1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
|
;; import.z
;; Timothy Mann, 8/24/97
;; Last modified on Sat Mar 25 21:35:11 PST 2000 by mann
;;
;; Use xtrs 1.9 emulator traps to copy a file from Unix to TRS-80
;; Usage: IMPORT [-ln] unixfile [tofile]
;; Parameter -l will convert the Unix file to lower case.
;; (Needed for NEWDOS/80. They insist on uppercasing the
;; command line.)
;; If the -n parameter is given, each newline ('\n') in the Unix
;; file is converted to a carriage return ('\r'), the TRS-80 end of
;; line character.
;; If the tofile parameter is omitted, the last component of the
;; Unix pathname is used, with '.' changed to '/'. If this is
;; not a legal TRS-80 filename, you get an error message.
;; Model I/III addresses
@fspec equ 441ch
@init equ 4420h
@open equ 4424h
@close equ 4428h
@read equ 4436h
@write equ 4439h
@error equ 4409h
@exit equ 402dh
@abort equ 4030h
@put equ 001bh
dodcb$ equ 401dh
;; Model 4 SVCs
@svc equ 40 ; rst address for SVCs
;@svc equ 5 ; older zmac requires 8080-style "rst 5"
@fspec6 equ 78
@init6 equ 58
@open6 equ 59
@close6 equ 60
@read6 equ 67
@write6 equ 75
@error6 equ 26
@exit6 equ 22
@abort6 equ 21
@dsply6 equ 10
org 5200h
;; Jump tables for OS independence
startj:
fspec: call @fspec
ret
init: call @init
ret
open: call @open
ret
close: call @close
ret
reed: call @read
ret
write: call @write
ret
error: call @error
ret
exit: call @exit
ret
abort: call @abort
ret
dsply: call dsply5
ret
setern: call setern5
ret
endj:
; Model 4
startj6:
ld a, @fspec6
rst @svc
ret
ld a, @init6
rst @svc
ret
ld a, @open6
rst @svc
ret
ld a, @close6
rst @svc
ret
ld a, @read6
rst @svc
ret
ld a, @write6
rst @svc
ret
ld a, @error6
rst @svc
ret
ld a, @exit6
rst @svc
ret
ld a, @abort6
rst @svc
ret
ld a, @dsply6
rst @svc
ret
call setern6
ret
; Emulator trap instructions, byte-reversed for use in defw:
emt_open equ 30edh
emt_close equ 31edh
emt_read equ 32edh
emt_write equ 33edh
emt_lseek equ 34edh
emt_strerror equ 35edh
EO_ACCMODE equ 3q
EO_RDONLY equ 0q
EO_WRONLY equ 1q
EO_RDWR equ 2q
EO_CREAT equ 100q
EO_EXCL equ 200q
EO_TRUNC equ 1000q
EO_APPEND equ 2000q
iobsize equ 8192 ; must be divisible by 256
import:
ld a, (000ah) ; Model 4?
cp 40h
jr z, not4
push hl
ld de, startj
ld hl, startj6
ld bc, endj - startj
ldir
pop hl
not4:
flag0: ld a, (hl) ; look for flags
cp ' '
jp c, usage ; error if line ends here
jr nz, flag1
inc hl
jr flag0
flag1: cp '-'
jr nz, unix1
inc hl
ld a, (hl)
flag3: or 20h
cp 'l'
jr nz, flagn ; check for next flag
ld a, 1
ld (lflag), a
jr flag2
flagn: cp 'n'
jr nz, usage ; only -n or -N is accepted
ld a, 1
ld (nflag), a
flag2: inc hl
ld a, (hl)
cp ' '
jr nz, flag3 ; another flag follows
inc hl
jr flag0
unix1: ld de, iobuf ; copy Unix filename
ld a, ' '
unix2: cp (hl)
ldi
jr c, unix2
dec de ; NUL terminate Unix name
ld a, 0
ld (de), a
jr z, trs80 ; go if two names given
;; Translate last component of Unix name to TRS-80 name
dec hl ; back up to terminator
unix3: dec hl ; back up to last byte of name
ld a, (hl)
cp '.' ; change '.' to '/'
jr nz, notdot
ld (hl), '/'
notdot: cp '/'
jr z, unix4
cp ' '
jr nz, unix3
unix4: inc hl ; point to start of modified last component
trs80: ld de, dcb ; ready to get TRS-80 filename from (HL)
call fspec
jr nz, usage
ld hl, iobuf ; Unix path
ld a, (lflag)
or a
call nz, lcconv ; convert path to lower case
ld bc, EO_RDONLY
ld de, 0 ; mode (ignored)
defw emt_open
jr z, openok ; go if OK
ld hl, uopner ; error message and exit
jp uerror
openok: push de ; save fd
ld hl, iobuf
ld de, dcb
ld b, 0
call init ; open the file
pop de
jr z, opn2ok
ld c, a
call error
jp abort
usage: ld hl, usager ; error message and exit
call dsply
jp abort
;; Read
rloop:
opn2ok: ld hl, iobuf ; read a buffer
ld bc, iobsize
defw emt_read
jr z, readok
ld hl, urder ; read error (!!code in A)
jr uerror
readok: push de ; save fd
;; Translate
ld a, (nflag) ; check for NL feature
and a
jr z, nlfals
ld hl, iobuf
push bc ; save byte count
ld a, 0ah
ld d, 0dh
inc c ; deal with b=0 and/ c=0
inc b
jr tstrt
tloop: cp (hl)
jr nz, notcr
ld (hl), d
notcr: inc hl
tstrt: dec c
jr nz, tloop
djnz tloop
pop bc ; restore byte count
;; Write
nlfals: push bc ; save byte count
ld hl, iobuf
ld de, dcb
inc b ; deal with b=0 and/or c=0
ld a, c
and a
jr z, wstrt
wloop: ld (dcb+3), hl
call write ; write 256 bytes to file
jr z, wrok
ld c, a
call error ; oops, i/o error
jp abort
wrok: inc h
wstrt: djnz wloop
pop bc ; restore byte count
;; Done?
pop de ; restore fd
ld a, c
and a
jr nz, closit ; done for sure
cp b
jr nz, rloop ; maybe not done (sloppy)
closit: defw emt_close ; close Unix file
jr z, closok
ld hl, uclser ; close error (!!code in A)
jr uerror
closok: ld a, c
ld (dcb+8), a ; set EOF offset
call setern ; set ERN (in case shortening file)
ld de, dcb
call close ; close the TRS-80 file
jr z, cls2ok
ld c, a
call error ; oops, i/o error
jp abort
cls2ok: ld hl, 0 ; all is well
jp exit
;; Unix error, msg in hl, errno in a
uerror: push af
call dsply
pop af
ld hl, iobuf
ld bc, 256
defw emt_strerror
call dsply
jp abort
;; Display message in HL. 03h terminate, 0dh newline and terminate.
dsply5: ld de, dodcb$
push hl
dsply0: ld a, (hl)
cp 03h
jr z, dsply1
push af
call @put
pop af
inc hl
cp 0dh
jr nz, dsply0
dsply1: pop hl
ret
;; Convert (NUL terminated) string in HL to lower case.
lcconv: push hl
ld d, h
ld e, l
lcloop: ld a, (hl)
cp 5bh ; use '[' or uparrow as escape
jr nz, lconv1
inc hl
ld a, (hl)
jr lconv2 ; char after esc: don't convert
lconv1: sub 'A'
cp 26
ld a, (hl)
jr nc, lconv2
or 20h ; convert to lower case
lconv2: ld (de), a
inc hl
inc de
or a ; NUL terminator?
jr nz, lcloop
pop hl
ret
;; EOF handling is different for NEWDOS/80 and TRSDOS 1.3:
;; For TRSDOS 2.3 and LDOS, word (dcb+12) contains the number of
;; 256 byte records in the file, byte (dcb+8) contains the EOF
;; offset in the last record (0=256).
;; For NEWDOS/80 and TRSDOS 1.3, byte (dcb+8) and word (dcb+12)
;; form a 24 bit number containing the relative byte address of EOF.
;; Thus (dcb+12) differs by one if the file length is not a
;; multiple of 256 bytes.
; Set ending record number of file to current position
; EOF offset in C; destroys A, HL
setern5:
ld hl, (dcb+10) ; current record number
ld a, (4427h) ; system id for Newdos/80...
sub 82h ; ...should be 82h (v2.0)
jr z, adj
ld a, (441fh) ; system version number for most other DOSes
sub 13h ; TRSDOS 1.3?
jr nz, noadj
adj: or c ; length multiple of 256 bytes?
jr z, noadj
dec hl ; no, # of records - 1
noadj: ld (dcb+12), hl
ret
; All Model 4 mode operating systems should be TRSDOS/LS-DOS 6.x compatible
setern6:
ld hl, (dcb+10)
ld (dcb+12), hl
ret
lflag: defb 0
nflag: defb 0
usager: defb 'Usage: IMPORT [-ln] unixfile [tofile]', 0dh
uopner: defb 'Error in Unix open: ', 03h
urder: defb 'Error in Unix read: ', 03h
uclser: defb 'Error in Unix close: ', 03h
dcb: defs 48 ; 48 for Model III TRSDOS 1.3
iobuf: defs iobsize
end import
|