File: import.z

package info (click to toggle)
xtrs 4.9-5
  • links: PTS
  • area: contrib
  • in suites: sarge
  • size: 2,164 kB
  • ctags: 1,433
  • sloc: ansic: 19,840; makefile: 242; csh: 132; sh: 129
file content (379 lines) | stat: -rw-r--r-- 7,543 bytes parent folder | download | duplicates (2)
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