aboutsummaryrefslogtreecommitdiff
path: root/src/cpswld.asm
blob: 8be6558ce159f80adf75008bf19d83b277654392 (plain)
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
; CPSWLD.ASM
;       KERMIT - (Celtic for "FREE")
;
;       This is the CP/M-80 implementation of the Columbia University
;       KERMIT file transfer protocol.
;
;       Version 4.0
;
;       Copyright June 1981,1982,1983,1984
;       Columbia University
;
; Originally written by Bill Catchings of the Columbia University Center for
; Computing Activities, 612 W. 115th St., New York, NY 10025.
;
; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
; others. 
;
;       Multi-file access subroutine.  Allows processing of multiple files
;       (i.e., *.ASM) from disk.  This routine builds the proper name in the
;       FCB each time it is called.  This command would be used in such pro-
;       grams such as modem transfer, tape save, etc. in which you want to
;       process single or multiple files.
;       Note that it will fail if more than 256 entries match the wildcard.
;
; revision history:
; edit 4: June 20, 1986, by OBSchou.  Added stuff at top and tail of routine
;       to support multiple FCBs.  If the routine get to mfn01 (Search for next)
;       then the next file found gets its fcb added to the buffer.  Once no 
;       more files have been found, the mfflg3 flag is set non-zero. 
;       The first thing to test on entry is whether a disk access
;       is needed.  Either way, the routine should return the next file name
;       in the fcb, or return with the carry flag set if there are no more
;       files to do.  Once there is a carry flag set for the return, all 
;       temporary flags are reset. Get all that?
;
; edit 3: July 27, 1984
;       support LASM: remove exclamation points, link to CP4CMD.
;
; edit 2: June 7, 1984 (CJC)
;       formatting and documentation; add module version string; redo movfcb,
;       in preparation for moving DMA buffer (later...).
;
; edit 1: May, 1984 (CJC)
;       extracted from CPMBASE.M80 version 3.9; modifications are described
;       in the accompanying .UPD file.
;
wldver:	db	'CPSWLD.ASM (4)  20-Jun-86$'

;       The FCB will be set up with the next name, ready to do normal 
;       processing (OPEN, READ, etc.) when routine is called.
;
;       Carry is set if no more names can be found
;
;       MFFLG1 is count/switch [0 for first time thru, pos for all others]
;       MFFLG2 is counted down for each successive GETNEXT file call
;       MFFLG3 is set to the last remaining FCBs buffered once Search for next
;               file fails with files in the buffer.
;
;       Technique used is to repeat SFIRST/SNEXT sequence N+1 times for each
;       successive call, till sequence fails. CP/M does NOT allow disk-handling
;       between SFIRST and SNEXT.
;       called by: send, seof, dir

mfname:	ora	a		; clear carry
	push	b		;Save registers
	push	d
	push	h
	jmp	mfnam0		; skip over the next bit (which is entered from elsewhere)

;[4] Get the FCB counter and see if we have any fcbs already.
mfnam1:	lxi	h,fcb0
	shld	xfcbptr		; reset the pointer if we are to return an FCB

mfnam0:	lda	fcbcnt
	ana	a		; if none, then we may have to get some from disk
	jz	mfn00		; see later on
	lhld	xfcbptr		; we have some, so give the next one to the user
	lxi	d,fcb		; move from (hl) to (de) for length bc
	lxi	b,12
	call	mover
	xra	a
	sta	fcbext		; clear fcb extents and such
	sta	fcbrno		; like record number
	lhld	xfcbptr		; point to next fcb
	lxi	d,fcblen
	dad	d		; yup
	shld	xfcbptr
	lda	fcbcnt
	dcr	a
	sta	fcbcnt		; decrease the number of fcbs we have
	xra	a		; clear carry
	jmp	mffix1		; and exit as if were all done

mfn00:	lda	mfflg3		; no more FCBs for the user, any more on disk?
	ana	a
	jnz	mffix2		; no, then set the carry flag to say so.
	lxi	h,fcb0		; now reset the fcb pointers and counter
	shld	xfcbptr
	xra	a
	sta	fcbcnt
;[4] end of this addition.  See below as well.


	mvi	c,setdma	;Init DMA addr, FCB
	lxi	d,80H
	call	bdos
	xra	a		;A = 0
	sta	fcbext		;clear extension
	lda	mfflg1		;find out if "second" call in row
	ora	a
	jnz	mfn01		;Were here before
	sta	mfflg2
	lxi	h,fcb
	lxi	d,mfreq
	lxi	b,12
	call	mover		;.from FCB to MFREQ
	mvi	c,SFIRST	;Search first
	lxi	d,fcb
	call	bdos
	jmp	mfn02		;and check results

mfn01:	dcr	a
	sta	mfflg2		;store down-counter
	lxi	h,mfreq		;SFIRST REQ name
	lxi	d,fcb
	lxi	b,12
	call	mover		;.from MFREQ to FCB
	mvi	c,sfirst	;Search first old one,we got it before
	lxi	d,fcb
	call	bdos		;no error's expected -we got that before
mfn01a:
	mvi	c,snext		;Search next
	call	bdos
mfn02:	push	psw
	lda	mfflg2		;get "repeat file counter"
	ora	a
	jz	mfn02a		;if zero, check if SNEXT had ERROR
	dcr	a		;count down
	sta	mfflg2		;store back
	pop	psw		;no error-check, we got it before
	jmp	mfn01a		;next SNEXT

mfn02a:	pop	psw
	ora	a
	jm	mffi2a		;No (more) found
	call	movfcb		;move data to fcb
	lda	mfreq		;the original disk-designator
	sta	fcb		;back into fcb
	lda	mfflg1		;get file-flag
	inr	a		;increment
	sta	mfflg1		;and store for next go-around
	mvi	a,0		;Setup FCB
	sta	fcbext		;clean up FCB for OPEN etc
	sta	fcbrno
	lhld	xfcbptr		;[4] like here 
	xchg
	lxi	h,fcb		;[4] from fcb space
	lxi	b,12
	call	mover
	lhld	xfcbptr		;[4] now lets update the pointers
	lxi	d,fcblen
	dad	d
	shld	xfcbptr		;[4] new pointer
	lda	fcbcnt		;[4] now the fcb counter
	inr	a
	sta	fcbcnt
	cpi	maxfcb		;[4] any more spare space?
	jp	mfnam1		;[4] nope, so get first fcb and return
	lxi	d,fcb		; else restore the file to serach for
	lxi	h,mfreq
	lxi	b,12		; copy the original fcb to fcb
	call	mover
	jmp	mfn01a		; and look for next match.

mffix1:	pop	h		;restore registers
	pop	d
	pop	b
	ret			;and return

mffi2a:
	sta	mfflg3		;[4] no more FCBs from disks to be had, but
	lda	fcbcnt		;[4]we have some in the buffer, havet we?
	ana	a
	jnz	mfnam1		;[4] yes, so all's ok.  Get an fcb and return,

mffix2:	xra	a
	sta	mfflg3		;[4] clear the new flag (=no more fcbs at all)
	sta	mfflg2		;[4] may as well do the others, as we're not comming again
	sta	mfflg1		;[4]
	stc			;set carry
	jmp	mffix1		;return with CARRY set

;       copy directory entry to FCB
;       called with A/ entry number in directory (0-3)
;                   directory block in DMA buffer (buff)

movfcb:	add	a
	add	a
	add	a
	add	a
	add	a		;* 32
	mov	c,a		; copy offset to bc
	mvi	b,0		; (high byte is zero)
	lxi	h,buff		; get start of disk buffer
	dad	b		; calculate start of directory entry
	lxi	d,fcb
	lxi	b,12
	call	mover
	ret

;       Data storage for MFNAME (multi-file access)
mfreq:	DS	12		;Requested name
mfflg1:	DB	0		;First time thru flag for MFNAME
mfflg2:	DB	0		;Down counter for MFNAME
mfflg3:	DB	0		;[4] Non zero if no more FCBs from disk,
				;[4] but we still have some in buffer
;
IF lasm
	LINK	CPSCMD
ENDIF;lasm