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
|