]> git.sur5r.net Git - cc65/blobdiff - libsrc/atari/fdtable.s
move fdtoiocb function into its own file -- idea by Daniel Serpell
[cc65] / libsrc / atari / fdtable.s
index 1a428764afb28ba01a4217c6b3312f62f667b975..111f340d0e064e6011ef4f21ee92fae92345eea0 100644 (file)
@@ -5,45 +5,15 @@
 ;
 
        .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
 
@@ -71,7 +41,7 @@ ft_flag = 3   ; flags
        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
@@ -82,47 +52,66 @@ retiocb:php
        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
@@ -154,7 +143,8 @@ inval:      ldx     #$ff                    ; sets N
        sta     fd_table+ft_iocb,x      ; clear table entry
 ret:   rts
 
-.endproc
+.endproc       ; fddecusage
+
 
 ; newfd
 ;
@@ -174,13 +164,9 @@ ret:       rts
 ;      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
+
+; local variables:
 loc_Y:         .res    1
 loc_ptr4_l:    .res    1
 loc_ptr4_h:    .res    1
@@ -238,7 +224,7 @@ do_open:lda tmp1
        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
@@ -276,11 +262,12 @@ l2:       sta     fd_table+ft_dev,x       ; set device
        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
@@ -325,9 +312,6 @@ srch2:      txa
 ; 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
@@ -365,55 +349,5 @@ finish:    lda     ptr4
        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
-
-       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
+.endproc       ; newfd
 
-       pha
-       lda     tmp1
-       asl     a
-       asl     a                       ; also clears C
-       tax
-       inc     fd_table+ft_usa,x       ; increment usage counter
-       pla
-error: rts
-
-.endproc