-
Notifications
You must be signed in to change notification settings - Fork 17
/
export.z80
419 lines (387 loc) · 9.07 KB
/
export.z80
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
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
;; export.z80
;;
;; Copyright (c) 1997-2011, Timothy P. Mann
;;
;; Permission is hereby granted, free of charge, to any person
;; obtaining a copy of this software and associated documentation
;; files (the "Software"), to deal in the Software without
;; restriction, including without limitation the rights to use, copy,
;; modify, merge, publish, distribute, sublicense, and/or sell copies
;; of the Software, and to permit persons to whom the Software is
;; furnished to do so, subject to the following conditions:
;;
;; The above copyright notice and this permission notice shall be
;; included in all copies or substantial portions of the Software.
;;
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
;; SOFTWARE.
;;
;; Use xtrs emulator traps to copy a file from TRS-80 to Unix
;; Usage: EXPORT [-lne] fromfile [unixfile]
;; 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 carriage return ('\r')
;; in the TRS-80 file is converted to a newline ('\n') in the Unix file.
;; The program tries to determine what DOS it is running on and use
;; the correct FCB end of file convention, but this works only on
;; TRSDOS, LDOS, and NEWDOS/80. For other DOSes that use the
;; NEWDOS/80 convention (such as DOSPLUS), give the -e paramter.
;; If the unixfile parameter is omitted, the fromfile parameter is used,
;; with '/' changed to '.'.
;; 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
;; Model 4 only: file init or open with wrong LRL. Can be ignored.
lrlerr equ 42
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
getern: call getern5
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 getern6
ret
; Nonzero for LDOS ern convention
ernldos: db 1
; 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
export:
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:
ld a, (4427h) ; system id for Newdos/80...
sub 82h ; ...should be 82h (v2.0)
jr z, gotid
ld a, (441fh) ; system version number for most other DOSes
sub 13h ; TRSDOS 1.3?
gotid: ld (ernldos), a
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, fromf
inc hl
ld a, (hl)
flag3: or 20h
cp 'e'
jr nz, flagl
sub a
ld (ernldos), a
jr flag2
flagl: cp 'l'
jr nz, flagn ; check for next flag
ld a, 1
ld (lflag), a
jr flag2
flagn: cp 'n'
jp nz, usage ; unknown flag
ld a, 1
ld (nflag), a
flag2: inc hl
ld a, (hl)
cp ' '
jr nz, flag3 ; another flag follows
inc hl
jr flag0
fromf: ld de, dcb ; ready to get LDOS filename from (HL)
ld (lfname), hl ; save if needed to default Unix name
call fspec
jp nz, usage
unix0: ld a, (hl) ; scan over Unix filename
cp ' ' ; first skip spaces
jr c, usetrs ; if no Unix name, use translated TRS name
jr nz, unix1
inc hl
jr unix0
unix1: ld de, iobuf ; copy Unix filename
ld a, ' '
unix2: cp (hl)
ldi
jr c, unix2
dec de
sub a
ld (de), a ; NUL terminate Unix name
jr gotu
usetrs: ld hl, (lfname) ; translate TRS-80 name to Unix
ld de, iobuf
ut1: ld a, (hl)
cp ':' ; drivespec?
jr z, utdone ; done if so
cp ' '+1 ; end of line?
jr c, utdone ; done if so
cp '/' ; change '/' to '.' for extension
jr nz, notsl
ld a, '.'
notsl: ld (de), a
inc hl
inc de
jr ut1
utdone: sub a ; NUL-terminate Unix name
ld (de), a
gotu: ld hl, iobuf
ld de, dcb
ld b, 0
call open ; open the TRS-80 file
jr z, uname
cp lrlerr
jr z, uname
ld c, a
call error
jp abort
uname: ld hl, iobuf ; path
ld a, (lflag)
or a
call nz, lcconv ; convert filename to lower case
ld bc, EO_WRONLY|EO_CREAT|EO_TRUNC
ld de, 0666q ; mode
defw emt_open ; open the Unix file
jr z, opn2ok ; go if OK
ld hl, uopner ; error message and exit
jp uerror
;; Read
opn2ok: call getern ; count down records in bc
loop: push de ; save fd
ld de, dcb
call reed ; read 256 bytes from file
pop de
jr z, rdok ; got a full 256 bytes
cp 28 ; eof?
jr z, closit ; yes, OK
ld c, a
call error ; oops, i/o error
jp abort
rdok: dec bc
;; Translate
push bc ; save record count
ld a, (nflag) ; check for NL feature
and a
jr z, nlfals
ld hl, iobuf
ld a, 0dh
ld bc, 000ah ; b := 0, c := 0ah
tloop: cp (hl)
jr nz, notlf
ld (hl), c
notlf: inc hl
djnz tloop
nlfals: pop bc ; restore record count
;; Write
ld a, c
or b ; last record?
push bc ; save record count
ld bc, 0100h ; byte count
jr nz, notlst
ld b, a
ld a, (dcb+8)
ld c, a
dec c ; EOF offset 0: write 256 bytes
inc bc
notlst:
ld hl, iobuf
defw emt_write
pop bc
jr z, wrok
ld hl, uwrer ; write error
jr uerror
wrok: ld a, c
or b
jr nz, loop
;; Close
closit: defw emt_close ; close Unix file
jr z, closok
ld hl, uclser ; close error
jr uerror
closok: 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
;; Usage message
usage: ld hl, usager ; error message and exit
call dsply
jp abort
;; 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 differs between TRS-80 DOSes:
;; 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. DOSPLUS also uses this convention,
;; and NEWDOS 2.1 probably does too (not checked).
; Returns number of (partial or full) records in BC, destroys A
getern5:
ld bc, (dcb+12)
ld a, (ernldos) ; get ERN convention
and a
ret nz ; done if TRSDOS 2.3/LDOS convention
ld a, (dcb+8) ; length multiple of 256 bytes?
and a
ret z ; done if so
inc bc ; no, # of records = last full record + 1
ret
; All Model 4 mode operating systems should be TRSDOS/LS-DOS 6.x compatible
getern6:
ld bc, (dcb+12)
ret
lflag: defb 0
nflag: defb 0
lfname: defw 0
usager: defb 'Usage: EXPORT [-lne] fromfile [unixfile]', 0dh
uopner: defb 'Error in Unix open: ', 03h
uwrer: defb 'Error in Unix write: ', 03h
uclser: defb 'Error in Unix close: ', 03h
dcb: defs 48 ; 48 for Model III TRSDOS 1.3
iobuf: defs 256
end export