2 ; Christian Groessler, May-2000
4 ; fd indirection table & helper functions
9 .importzp tmp1,tmp2,tmp3,ptr4,sp
10 .import fd_table,fd_index
19 ; gets fd in ax, decrements usage counter
20 ; return iocb index in X
21 ; return N bit set for invalid fd
22 ; return Z bit set if last user
23 ; all registers destroyed
31 lda fd_index,x ; get index
34 sta fd_index,x ; clear entry
36 asl a ; create index into fd table
40 cmp fd_table+ft_iocb,x ; entry in use?
41 beq inval ; no, return error
42 lda fd_table+ft_usa,x ; get usage counter
45 sbc #1 ; decr usage counter
50 lda fd_table+ft_iocb,x ; get iocb
56 sta fd_table+ft_iocb,y ; clear table entry
66 inval: ldx #$ff ; sets N
71 ; return iocb index in X
72 ; return N bit set for invalid fd
73 ; all registers destroyed
82 asl a ; create index into fd table
86 cmp fd_table+ft_iocb,x ; entry in use?
87 beq inval ; no, return error
88 lda fd_table+ft_usa,x ; get usage counter
89 beq inval ; 0? should not happen
90 lda fd_table+ft_iocb,x ; get iocb
95 ; decrements usage counter for fd
96 ; if 0 reached, it's marked as unused
97 ; get fd index in tmp2
98 ; Y register preserved
103 bcs ret ; invalid index, do nothing
110 asl a ; create index into fd table
114 cmp fd_table+ft_iocb,x ; entry in use?
115 beq ret ; no, do nothing
116 lda fd_table+ft_usa,x ; get usage counter
117 beq ret ; 0? should not happen
119 sbc #1 ; decrement by one
120 sta fd_table+ft_usa,x
122 lda #$ff ; 0, table entry unused now
123 sta fd_table+ft_iocb,x ; clear table entry
130 ; called from open() function
131 ; finds a fd to use for an open request
132 ; checks whether it's a device or file (file: characters follow the ':')
133 ; files always get an exclusive slot
134 ; for devices it is checked whether the device is already open, and if yes,
135 ; a link to this open device is returned
137 ; Calling parameters:
138 ; tmp3 - length of filename + 1
139 ; AX - points to filename
140 ; Y - iocb to use (if we need a new open)
142 ; tmp2 - fd num ($ff and C=0 in case of error - no free slot)
143 ; C - 0/1 for no open needed/open should be performed
144 ; all registers preserved!
149 ; ptr4 - 3,4 (backup)
187 ; ptr4 points to filename
197 ; no colon there!? OK, then we use a fresh iocb....
198 ; return error here? no, the subsequent open call should fail
200 do_open_nd: ; do open and don't remember device
205 sta tmp1 ; set flag to return 'open needed' : C = 1
211 beq freefnd ; found a free slot
216 cmp #(MAX_FD_VAL*4)+ft_iocb ; end of table reached?
219 ; error: no free slot found
221 stx tmp1 ; return with C = 0
223 stx tmp2 ; iocb: $ff marks error
229 sbc #ft_iocb ; normalize
235 bit tmp1 ; remember device?
237 lda #0 ; no, put 0 in field
241 lda (sp),y ; get device
242 l2: sta fd_table+ft_dev,x ; set device
244 sta fd_table+ft_usa,x ; set usage counter
246 sta fd_table+ft_iocb,x ; set iocb index
249 sta fd_table+ft_flag,x
251 jsr fdt_to_fdi ; get new index
252 bcs noslot ; no one available
253 ;cmp #$ff ; no one available
254 ;beq noslot ;@@@ cleanup needed
255 sta tmp2 ; return index
258 ; string in "Xn:xxx" format
260 lda (ptr4),y ; get device number
265 sta tmp2 ; save it for speed later here also
266 lda #4 ; max. length if only device + number ("Xn:")
268 bcc do_open_nd ; string is longer -> contains filename
269 bcs check_dev ; handle device only string
271 ; string in "X:xxx" format
272 colon1: lda #3 ; max. length if device only ("X:")
274 bcc do_open_nd ; string is longer -> contains filename
276 ; get device and search it in fd table
279 lda (ptr4),y ; get device id
281 ldx #(MAX_FD_VAL*4) - ft_entrylen
283 cmp fd_table+ft_iocb,x ; is entry valid?
284 beq srch2 ; no, skip this entry
286 cmp fd_table+ft_dev,x
294 ; not found, open new iocb
297 ; helper for branch out of range
300 ; found device in table, check device number (e.g R0 - R3)
301 fnddev: lda fd_table+ft_flag,x
303 cmp tmp2 ; contains devnum
304 bne srch2 ; different device numbers
306 ; found existing open iocb with same device
311 inc fd_table+ft_usa,x ; increment usage counter
312 jsr fdt_to_fdi ; get new index
313 bcs noslot1 ; no one available
314 sta tmp2 ; return index
316 ; clean up and go home
328 lsr a ; set C as needed