;
.include "atari.inc"
+ .include "fd.inc"
.importzp tmp1,tmp2,tmp3,ptr4,sp
- .import subysp,addysp
- .export fdtoiocb
+ .import fd_table,fd_index
+ .import fdt_to_fdi
+ .export clriocb
.export fdtoiocb_down
- .export fd_table
+ .export findfreeiocb
.export fddecusage
.export newfd
- .export getfd
-
- .export _fd_table,_fd_index ; for test purposes
-
- .data
-MAX_FD_INDEX = 12
-_fd_index:
-fd_index: ; fd number is index into this table, entry's value specifies the fd_table entry
- .res MAX_FD_INDEX,$ff
-
-_fd_table:
-fd_table: ; each entry represents an open iocb
- .byte 0,0,'E',0 ; system console, app starts with opened iocb #0 for E:
- .byte 0,$ff,0,0
- .byte 0,$ff,0,0
- .byte 0,$ff,0,0
- .byte 0,$ff,0,0
- .byte 0,$ff,0,0
- .byte 0,$ff,0,0
- .byte 0,$ff,0,0
-
-MAX_FD_VAL = (* - fd_table) / 4
-
-ft_entrylen = 4 ; length of table entry (it's not sufficient to change here!
- ; the code sometimes does two bit shifts to multiply/divide by
- ; this length)
-
-ft_usa = 0 ; usage counter
-ft_iocb = 1 ; iocb index (0,$10,$20,etc.), $ff for empty entry
-ft_dev = 2 ; device of open iocb (0 - device not remembered, eg. filename specified)
-ft_flag = 3 ; flags
- ; lower 3 bits: device number (for R: and D:)
.code
cmp fd_table+ft_iocb,x ; entry in use?
beq inval ; no, return error
lda fd_table+ft_usa,x ; get usage counter
- beq ok_notlast ; 0?
+ beq ok_notlast ; 0? (shouldn't happen)
sec
sbc #1 ; decr usage counter
sta fd_table+ft_usa,x
tax
plp
bne cont
- php
lda #$ff
sta fd_table+ft_iocb,y ; clear table entry
- plp
+ lda fd_table+ft_flag,y
+ and #16 ; opened by app?
+ eor #16 ; return set Z if yes
cont: rts
ok_notlast:
lda #1 ; clears Z
jmp retiocb
-.endproc
+.endproc ; fdtoiocb_down
inval: ldx #$ff ; sets N
rts
-; gets fd in ax
-; return iocb index in X
-; return N bit set for invalid fd
+; clear iocb except for ICHID field
+; expects X to be index to IOCB (0,$10,$20,etc.)
; all registers destroyed
-.proc fdtoiocb
- cpx #0
- bne inval
- cmp #MAX_FD_INDEX
- bcs inval
- tax
- lda fd_index,x
- asl a ; create index into fd table
- asl a
- tax
- lda #$ff
- cmp fd_table+ft_iocb,x ; entry in use?
- beq inval ; no, return error
- lda fd_table+ft_usa,x ; get usage counter
- beq inval ; 0? should not happen
- lda fd_table+ft_iocb,x ; get iocb
+.proc clriocb
+
+ inx ; don't clear ICHID
+ ldy #15
+ lda #0
+loop: sta ICHID,x
+ inx
+ dey
+ bne loop
rts
.endproc
+
+; find a free iocb
+; no entry parameters
+; return ZF = 0/1 for not found/found
+; index in X if found
+; all registers destroyed
+
+.proc findfreeiocb
+
+ ldx #0
+ ldy #$FF
+loop: tya
+ cmp ICHID,x
+ beq found
+ txa
+ clc
+ adc #$10
+ tax
+ cmp #$80
+ bcc loop
+ inx ; return ZF cleared
+found: rts
+
+.endproc ; findfreeiocb
+
+
; decrements usage counter for fd
; if 0 reached, it's marked as unused
; get fd index in tmp2
sta fd_table+ft_iocb,x ; clear table entry
ret: rts
-.endproc
+.endproc ; fddecusage
+
; newfd
;
; C - 0/1 for no open needed/open should be performed
; all registers preserved!
-; local variables:
-; AX - 0 (A-0,X-1)
-; Y - 2
-; ptr4 - 3,4 (backup)
-; devnum - 5
+ .bss
- .data
+; local variables:
loc_Y: .res 1
loc_ptr4_l: .res 1
loc_ptr4_h: .res 1
ldy #$ff
srchfree:
tya
- cmp fd_table,x
+ cmp fd_table,x ; check ft_iocb field for $ff
beq freefnd ; found a free slot
txa
clc
lda loc_Y
sta fd_table+ft_iocb,x ; set iocb index
lda loc_devnum
- and #7 ; only 3 bits
+ and #7 ; device number is 3 bits
+ ora #16 ; indicated a fd actively opened by the app
sta fd_table+ft_flag,x
lda tmp2
jsr fdt_to_fdi ; get new index
- bcs noslot ; no one available
+noslot1:bcs noslot ; no one available (noslot1: helper label for branch out of range)
;cmp #$ff ; no one available
;beq noslot ;@@@ cleanup needed
sta tmp2 ; return index
; not found, open new iocb
jmp do_open
-; helper for branch out of range
-noslot1:jmp noslot
-
; found device in table, check device number (e.g R0 - R3)
fnddev: lda fd_table+ft_flag,x
and #7
pla
rts
-.endproc
-
-; ftp_to_fdi
-; returns a fd_index entry pointing to the given ft_table entry
-; get fd_table entry in A
-; return C = 0/1 for OK/error
-; return fd_index entry in A if OK
-; registers destroyed
-.proc fdt_to_fdi
+.endproc ; newfd
- tay
- lda #$ff
- tax
- inx
-loop: cmp fd_index,x
- beq found
- inx
- cpx #MAX_FD_INDEX
- bcc loop
- rts
-
-found: tya
- sta fd_index,x
- txa
- clc
- rts
-
-.endproc
-
-; getfd
-; get a new fd pointing to a ft_table entry
-; usage counter of ft_table entry incremented
-; A - fd_table entry
-; return C = 0/1 for OK/error
-; returns fd in A if OK
-; registers destroyed, tmp1 destroyed
-.proc getfd
-
- sta tmp1 ; save fd_table entry
- jsr fdt_to_fdi
- bcs error
-
- pha
- lda tmp1
- asl a
- asl a ; also clears C
- tax
- inc fd_table+ft_usa,x ; increment usage counter
- pla
-error: rts
-
-.endproc