File: export.z80

package info (click to toggle)
xtrs 4.9c-4
  • links: PTS
  • area: contrib
  • in suites: stretch
  • size: 2,240 kB
  • ctags: 1,430
  • sloc: ansic: 19,941; makefile: 243; csh: 132; sh: 129
file content (408 lines) | stat: -rw-r--r-- 8,536 bytes parent folder | download | duplicates (5)
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
;; export.z
;; Timothy Mann, 8/24/97
;; $Date: 2006/05/15 00:48:57 $
;;
;;	Copyright (c) 1997, Timothy Mann
;;
;;	This software may be copied, modified, and used for any
;;	purpose without fee, provided that (1) the above copyright
;;	notice is retained, and (2) modified versions are clearly
;;	marked as having been modified, with the modifier's name and
;;	the date included.  
;;
;; 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
        pop hl
        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