X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libsrc%2Fatari%2Ffdtable.s;h=7e3325055ff11048062f6124595f8c3c1828e6e6;hb=00fca46d2a0a16d463886d0de4d30bf428a0aba1;hp=5a8063c38f6a685d10fa0867b7913dd8fdaadf7d;hpb=8d6f5a2fca38aa7378180a26ca43fcfbcefafe45;p=cc65 diff --git a/libsrc/atari/fdtable.s b/libsrc/atari/fdtable.s index 5a8063c38..7e3325055 100644 --- a/libsrc/atari/fdtable.s +++ b/libsrc/atari/fdtable.s @@ -4,170 +4,147 @@ ; fd indirection table & helper functions ; - .include "atari.inc" - .include "fd.inc" - .importzp tmp1,tmp2,tmp3,ptr4,sp - .import fd_table,fd_index - .import fdt_to_fdi - .export clriocb - .export fdtoiocb - .export fdtoiocb_down - .export findfreeiocb - .export fddecusage - .export newfd - - .code + .include "atari.inc" + .include "fd.inc" + .importzp tmp1,tmp2,tmp3,ptr4,sp + .import fd_table,fd_index + .import fdt_to_fdi + .export clriocb + .export fdtoiocb_down + .export findfreeiocb + .export fddecusage + .export newfd + + .code ; gets fd in ax, decrements usage counter ; return iocb index in X ; return N bit set for invalid fd ; return Z bit set if last user ; all registers destroyed -.proc fdtoiocb_down - - cpx #0 - bne inval - cmp #MAX_FD_INDEX - bcs inval - tax - lda fd_index,x ; get index - tay - lda #$ff - sta fd_index,x ; clear entry - tya - 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 ok_notlast ; 0? - sec - sbc #1 ; decr usage counter - sta fd_table+ft_usa,x +.proc fdtoiocb_down + + cpx #0 + bne inval + cmp #MAX_FD_INDEX + bcs inval + tax + lda fd_index,x ; get index + tay + lda #$ff + sta fd_index,x ; clear entry + tya + 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 ok_notlast ; 0? (shouldn't happen) + sec + sbc #1 ; decr usage counter + sta fd_table+ft_usa,x retiocb:php - txa - tay - lda fd_table+ft_iocb,x ; get iocb - tax - plp - bne cont - php - lda #$ff - sta fd_table+ft_iocb,y ; clear table entry - plp -cont: rts + txa + tay + lda fd_table+ft_iocb,x ; get iocb + tax + plp + bne cont + lda #$ff + sta fd_table+ft_iocb,y ; clear table entry + 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 + lda #1 ; clears Z + jmp retiocb -.endproc ; fdtoiocb_down +.endproc ; fdtoiocb_down -inval: ldx #$ff ; sets N - rts +inval: ldx #$ff ; sets N + rts ; clear iocb except for ICHID field ; expects X to be index to IOCB (0,$10,$20,etc.) ; all registers destroyed -.proc clriocb +.proc clriocb - inx ; don't clear ICHID - ldy #15 - lda #0 -loop: sta ICHID,x - inx - dey - bne loop - rts + inx ; don't clear ICHID + ldy #15 + lda #0 +loop: sta ICHID,x + inx + dey + bne loop + rts .endproc -; gets fd in ax -; return iocb index in X -; return N bit set for invalid fd -; 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 - rts - -.endproc ; fdtoiocb - ; 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 +.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 + 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 -.endproc ; findfreeiocb ; decrements usage counter for fd ; if 0 reached, it's marked as unused ; get fd index in tmp2 ; Y register preserved -.proc fddecusage - - lda tmp2 ; get fd - cmp #MAX_FD_INDEX - bcs ret ; invalid index, do nothing - tax - lda fd_index,x - pha - lda #$ff - sta fd_index,x - pla - asl a ; create index into fd table - asl a - tax - lda #$ff - cmp fd_table+ft_iocb,x ; entry in use? - beq ret ; no, do nothing - lda fd_table+ft_usa,x ; get usage counter - beq ret ; 0? should not happen - sec - sbc #1 ; decrement by one - sta fd_table+ft_usa,x - bne ret ; not 0 - lda #$ff ; 0, table entry unused now - sta fd_table+ft_iocb,x ; clear table entry -ret: rts - -.endproc ; fddecusage +.proc fddecusage + + lda tmp2 ; get fd + cmp #MAX_FD_INDEX + bcs ret ; invalid index, do nothing + tax + lda fd_index,x + pha + lda #$ff + sta fd_index,x + pla + asl a ; create index into fd table + asl a + tax + lda #$ff + cmp fd_table+ft_iocb,x ; entry in use? + beq ret ; no, do nothing + lda fd_table+ft_usa,x ; get usage counter + beq ret ; 0? should not happen + sec + sbc #1 ; decrement by one + sta fd_table+ft_usa,x + bne ret ; not 0 + lda #$ff ; 0, table entry unused now + sta fd_table+ft_iocb,x ; clear table entry +ret: rts + +.endproc ; fddecusage + ; newfd ; @@ -179,204 +156,198 @@ ret: rts ; a link to this open device is returned ; ; Calling parameters: -; tmp3 - length of filename + 1 -; AX - points to filename -; Y - iocb to use (if we need a new open) +; tmp3 - length of filename + 1 +; AX - points to filename +; Y - iocb to use (if we need a new open) ; Return parameters: -; tmp2 - fd num ($ff and C=0 in case of error - no free slot) -; C - 0/1 for no open needed/open should be performed +; tmp2 - fd num ($ff and C=0 in case of error - no free slot) +; C - 0/1 for no open needed/open should be performed ; all registers preserved! + .bss + ; local variables: -; AX - 0 (A-0,X-1) -; Y - 2 -; ptr4 - 3,4 (backup) -; devnum - 5 - - .bss -loc_Y: .res 1 -loc_ptr4_l: .res 1 -loc_ptr4_h: .res 1 -loc_tmp1: .res 1 -loc_devnum: .res 1 -loc_size: .res 1 - - .code - -.proc newfd - - pha - txa - pha - tya - pha - - ldx #0 - stx loc_devnum - lda tmp1 - sta loc_tmp1 - stx tmp1 ; init tmp1 - stx tmp2 ; init tmp2 - lda ptr4+1 - sta loc_ptr4_h - lda ptr4 - sta loc_ptr4_l - pla - sta loc_Y - pla - sta ptr4+1 - pla - sta ptr4 - - ; ptr4 points to filename - - ldy #1 - lda #':' - cmp (ptr4),y ; "X:" - beq colon1 - iny - cmp (ptr4),y ; "Xn:" - beq colon2 - - ; no colon there!? OK, then we use a fresh iocb.... - ; return error here? no, the subsequent open call should fail - -do_open_nd: ; do open and don't remember device - lda #2 - sta tmp1 -do_open:lda tmp1 - ora #1 - sta tmp1 ; set flag to return 'open needed' : C = 1 - ldx #ft_iocb - ldy #$ff +loc_Y: .res 1 +loc_ptr4_l: .res 1 +loc_ptr4_h: .res 1 +loc_tmp1: .res 1 +loc_devnum: .res 1 +loc_size: .res 1 + + .code + +.proc newfd + + pha + txa + pha + tya + pha + + ldx #0 + stx loc_devnum + lda tmp1 + sta loc_tmp1 + stx tmp1 ; init tmp1 + stx tmp2 ; init tmp2 + lda ptr4+1 + sta loc_ptr4_h + lda ptr4 + sta loc_ptr4_l + pla + sta loc_Y + pla + sta ptr4+1 + pla + sta ptr4 + + ; ptr4 points to filename + + ldy #1 + lda #':' + cmp (ptr4),y ; "X:" + beq colon1 + iny + cmp (ptr4),y ; "Xn:" + beq colon2 + + ; no colon there!? OK, then we use a fresh iocb.... + ; return error here? no, the subsequent open call should fail + +do_open_nd: ; do open and don't remember device + lda #2 + sta tmp1 +do_open:lda tmp1 + ora #1 + sta tmp1 ; set flag to return 'open needed' : C = 1 + ldx #ft_iocb + ldy #$ff srchfree: - tya - cmp fd_table,x - beq freefnd ; found a free slot - txa - clc - adc #ft_entrylen - tax - cmp #(MAX_FD_VAL*4)+ft_iocb ; end of table reached? - bcc srchfree + tya + cmp fd_table,x ; check ft_iocb field for $ff + beq freefnd ; found a free slot + txa + clc + adc #ft_entrylen + tax + cmp #(MAX_FD_VAL*4)+ft_iocb ; end of table reached? + bcc srchfree ; error: no free slot found -noslot: ldx #0 - stx tmp1 ; return with C = 0 - dex - stx tmp2 ; iocb: $ff marks error - jmp finish +noslot: ldx #0 + stx tmp1 ; return with C = 0 + dex + stx tmp2 ; iocb: $ff marks error + jmp finish ; found a free slot freefnd:txa - sec - sbc #ft_iocb ; normalize - tax - lsr a - lsr a - sta tmp2 ; return fd - lda #2 - bit tmp1 ; remember device? - beq l1 ; yes - lda #0 ; no, put 0 in field - beq l2 - -l1: ldy #0 - lda (sp),y ; get device -l2: sta fd_table+ft_dev,x ; set device - lda #1 - sta fd_table+ft_usa,x ; set usage counter - lda loc_Y - sta fd_table+ft_iocb,x ; set iocb index - lda loc_devnum - and #7 ; only 3 bits - sta fd_table+ft_flag,x - lda tmp2 - jsr fdt_to_fdi ; get new index - bcs noslot ; no one available - ;cmp #$ff ; no one available - ;beq noslot ;@@@ cleanup needed - sta tmp2 ; return index - jmp finish + sec + sbc #ft_iocb ; normalize + tax + lsr a + lsr a + sta tmp2 ; return fd + lda #2 + bit tmp1 ; remember device? + beq l1 ; yes + lda #0 ; no, put 0 in field + beq l2 + +l1: ldy #0 + lda (sp),y ; get device +l2: sta fd_table+ft_dev,x ; set device + lda #1 + sta fd_table+ft_usa,x ; set usage counter + lda loc_Y + sta fd_table+ft_iocb,x ; set iocb index + lda loc_devnum + 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 +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 + jmp finish ; string in "Xn:xxx" format -colon2: dey - lda (ptr4),y ; get device number - sec - sbc #'0' - and #7 - sta loc_devnum - sta tmp2 ; save it for speed later here also - lda #4 ; max. length if only device + number ("Xn:") - cmp tmp3 - bcc do_open_nd ; string is longer -> contains filename - bcs check_dev ; handle device only string +colon2: dey + lda (ptr4),y ; get device number + sec + sbc #'0' + and #7 + sta loc_devnum + sta tmp2 ; save it for speed later here also + lda #4 ; max. length if only device + number ("Xn:") + cmp tmp3 + bcc do_open_nd ; string is longer -> contains filename + bcs check_dev ; handle device only string ; string in "X:xxx" format -colon1: lda #3 ; max. length if device only ("X:") - cmp tmp3 - bcc do_open_nd ; string is longer -> contains filename +colon1: lda #3 ; max. length if device only ("X:") + cmp tmp3 + bcc do_open_nd ; string is longer -> contains filename ; get device and search it in fd table check_dev: - ldy #0 - lda (ptr4),y ; get device id - tay - ldx #(MAX_FD_VAL*4) - ft_entrylen -srchdev:lda #$ff - cmp fd_table+ft_iocb,x ; is entry valid? - beq srch2 ; no, skip this entry - tya - cmp fd_table+ft_dev,x - beq fnddev -srch2: txa - sec - sbc #ft_entrylen+1 - tax - bpl srchdev + ldy #0 + lda (ptr4),y ; get device id + tay + ldx #(MAX_FD_VAL*4) - ft_entrylen +srchdev:lda #$ff + cmp fd_table+ft_iocb,x ; is entry valid? + beq srch2 ; no, skip this entry + tya + cmp fd_table+ft_dev,x + beq fnddev +srch2: txa + sec + sbc #ft_entrylen+1 + tax + bpl srchdev ; not found, open new iocb - jmp do_open - -; helper for branch out of range -noslot1:jmp noslot + jmp do_open ; found device in table, check device number (e.g R0 - R3) -fnddev: lda fd_table+ft_flag,x - and #7 - cmp tmp2 ; contains devnum - bne srch2 ; different device numbers +fnddev: lda fd_table+ft_flag,x + and #7 + cmp tmp2 ; contains devnum + bne srch2 ; different device numbers ; found existing open iocb with same device - txa - lsr a - lsr a - sta tmp2 - inc fd_table+ft_usa,x ; increment usage counter - jsr fdt_to_fdi ; get new index - bcs noslot1 ; no one available - sta tmp2 ; return index + txa + lsr a + lsr a + sta tmp2 + inc fd_table+ft_usa,x ; increment usage counter + jsr fdt_to_fdi ; get new index + bcs noslot1 ; no one available + sta tmp2 ; return index ; clean up and go home -finish: lda ptr4 - pha - lda ptr4+1 - pha - lda loc_Y - pha - lda tmp1 - pha - lda loc_tmp1 - sta tmp1 - pla - lsr a ; set C as needed - - pla - tay - pla - tax - pla - rts - -.endproc ; newfd +finish: lda ptr4 + pha + lda ptr4+1 + pha + lda loc_Y + pha + lda tmp1 + pha + lda loc_tmp1 + sta tmp1 + pla + lsr a ; set C as needed + + pla + tay + pla + tax + pla + rts + +.endproc ; newfd