mirror of
https://github.com/cc65/cc65.git
synced 2024-06-08 15:29:37 +00:00
first working version (with filenames at least, devices not tested yet)
git-svn-id: svn://svn.cc65.org/cc65/trunk@18 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
d1d9ebe9e7
commit
ca35829405
|
@ -5,22 +5,26 @@
|
||||||
;
|
;
|
||||||
|
|
||||||
.include "atari.inc"
|
.include "atari.inc"
|
||||||
.importzp tmp2,ptr4,sp
|
.importzp tmp1,tmp2,tmp3,ptr4,sp
|
||||||
.import subysp,addysp
|
.import subysp,addysp
|
||||||
.export fdtoiocb
|
.export fdtoiocb
|
||||||
.export fdtoiocb_down
|
.export fdtoiocb_down
|
||||||
.export fd_table
|
.export fd_table
|
||||||
.export fddecusage
|
.export fddecusage
|
||||||
.export newfd
|
.export newfd
|
||||||
|
.export getfd
|
||||||
|
|
||||||
|
.export _fd_table,_fd_index
|
||||||
|
|
||||||
.data
|
.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:
|
||||||
.byte 0,$ff,0,0
|
fd_table: ; each entry represents an open iocb
|
||||||
.byte 0,$ff,0,0
|
.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
|
||||||
.byte 0,$ff,0,0
|
.byte 0,$ff,0,0
|
||||||
|
@ -31,9 +35,13 @@ fd_table:
|
||||||
|
|
||||||
MAX_FD_VAL = (* - fd_table) / 4
|
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_usa = 0 ; usage counter
|
||||||
ft_iocb = 1 ; iocb index (0,$10,$20,etc.), $ff for empty entry
|
ft_iocb = 1 ; iocb index (0,$10,$20,etc.), $ff for empty entry
|
||||||
ft_dev = 2 ; device of open iocb
|
ft_dev = 2 ; device of open iocb (0 - device not remembered, eg. filename specified)
|
||||||
ft_flag = 3 ; flags
|
ft_flag = 3 ; flags
|
||||||
; lower 3 bits: device number (for R: and D:)
|
; lower 3 bits: device number (for R: and D:)
|
||||||
|
|
||||||
|
@ -48,8 +56,14 @@ ft_flag = 3 ; flags
|
||||||
|
|
||||||
cpx #0
|
cpx #0
|
||||||
bne inval
|
bne inval
|
||||||
cmp #MAX_FD_VAL
|
cmp #MAX_FD_INDEX
|
||||||
bcs inval
|
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 ; create index into fd table
|
||||||
asl a
|
asl a
|
||||||
tax
|
tax
|
||||||
|
@ -92,8 +106,10 @@ inval: ldx #$ff ; sets N
|
||||||
|
|
||||||
cpx #0
|
cpx #0
|
||||||
bne inval
|
bne inval
|
||||||
cmp #MAX_FD_VAL
|
cmp #MAX_FD_INDEX
|
||||||
bcs inval
|
bcs inval
|
||||||
|
tax
|
||||||
|
lda fd_index,x
|
||||||
asl a ; create index into fd table
|
asl a ; create index into fd table
|
||||||
asl a
|
asl a
|
||||||
tax
|
tax
|
||||||
|
@ -114,8 +130,14 @@ inval: ldx #$ff ; sets N
|
||||||
.proc fddecusage
|
.proc fddecusage
|
||||||
|
|
||||||
lda tmp2 ; get fd
|
lda tmp2 ; get fd
|
||||||
cmp #MAX_FD_VAL
|
cmp #MAX_FD_INDEX
|
||||||
bcs ret ; invalid index, do nothing
|
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 ; create index into fd table
|
||||||
asl a
|
asl a
|
||||||
tax
|
tax
|
||||||
|
@ -138,16 +160,17 @@ ret: rts
|
||||||
;
|
;
|
||||||
; called from open() function
|
; called from open() function
|
||||||
; finds a fd to use for an open request
|
; finds a fd to use for an open request
|
||||||
; checks whether it's a device or file (file: characters following the ':')
|
; checks whether it's a device or file (file: characters follow the ':')
|
||||||
; files always get an exclusive slot
|
; files always get an exclusive slot
|
||||||
; for devices it is checked whether the device is already open, and if yes,
|
; for devices it is checked whether the device is already open, and if yes,
|
||||||
; a link to this open device is returned
|
; a link to this open device is returned
|
||||||
;
|
;
|
||||||
; Calling paramteter:
|
; Calling parameters:
|
||||||
|
; tmp3 - length of filename + 1
|
||||||
; AX - points to filename
|
; AX - points to filename
|
||||||
; Y - iocb to use (if we need a new open)
|
; Y - iocb to use (if we need a new open)
|
||||||
; Return parameters:
|
; Return parameters:
|
||||||
; tmp2 - fd num
|
; 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
|
; C - 0/1 for no open needed/open should be performed
|
||||||
; all registers preserved!
|
; all registers preserved!
|
||||||
|
|
||||||
|
@ -157,13 +180,14 @@ ret: rts
|
||||||
; ptr4 - 3,4 (backup)
|
; ptr4 - 3,4 (backup)
|
||||||
; devnum - 5
|
; devnum - 5
|
||||||
|
|
||||||
loc_A = 0
|
;loc_A = 0
|
||||||
loc_X = 1
|
;loc_X = 1
|
||||||
loc_Y = 2
|
loc_Y = 0
|
||||||
loc_ptr4_l = 3
|
loc_ptr4_l = 1
|
||||||
loc_ptr4_h = 4
|
loc_ptr4_h = 2
|
||||||
loc_devnum = 5
|
loc_tmp1 = 3
|
||||||
loc_size = 6
|
loc_devnum = 4
|
||||||
|
loc_size = 5
|
||||||
|
|
||||||
.proc newfd
|
.proc newfd
|
||||||
|
|
||||||
|
@ -179,6 +203,12 @@ loc_size = 6
|
||||||
lda #0
|
lda #0
|
||||||
sta (sp),y ; loc_devnum
|
sta (sp),y ; loc_devnum
|
||||||
dey
|
dey
|
||||||
|
lda tmp1
|
||||||
|
sta (sp),y ; loc_tmp1
|
||||||
|
lda #0
|
||||||
|
sta tmp1 ; init tmp1
|
||||||
|
sta tmp2 ; init tmp2
|
||||||
|
dey
|
||||||
lda ptr4+1
|
lda ptr4+1
|
||||||
sta (sp),y ; loc_ptr4_h
|
sta (sp),y ; loc_ptr4_h
|
||||||
dey
|
dey
|
||||||
|
@ -187,13 +217,13 @@ loc_size = 6
|
||||||
dey
|
dey
|
||||||
pla
|
pla
|
||||||
sta (sp),y ; loc_Y
|
sta (sp),y ; loc_Y
|
||||||
dey
|
; dey
|
||||||
pla
|
pla
|
||||||
sta (sp),y ; loc_X
|
; sta (sp),y ; loc_X
|
||||||
sta ptr4+1
|
sta ptr4+1
|
||||||
dey
|
; dey
|
||||||
pla
|
pla
|
||||||
sta (sp),y ; loc_A
|
; sta (sp),y ; loc_A
|
||||||
sta ptr4
|
sta ptr4
|
||||||
|
|
||||||
; ptr4 points to filename
|
; ptr4 points to filename
|
||||||
|
@ -207,23 +237,201 @@ loc_size = 6
|
||||||
beq colon2
|
beq colon2
|
||||||
|
|
||||||
; no colon there!? OK, then we use a fresh iocb....
|
; no colon there!? OK, then we use a fresh iocb....
|
||||||
|
; return error here? no, the subsequent open call should fail
|
||||||
|
|
||||||
do_open:nop ; @@@TODO
|
do_open_nd: ; do open and don't remember device
|
||||||
ldy #loc_size
|
lda #2
|
||||||
jsr addysp
|
sta tmp1
|
||||||
rts
|
do_open:lda tmp1
|
||||||
|
ora #1
|
||||||
colon2: dey
|
sta tmp1 ; set flag to return 'open needed' : C = 1
|
||||||
|
ldx #ft_iocb
|
||||||
|
ldy #$ff
|
||||||
|
srchfree:
|
||||||
tya
|
tya
|
||||||
pha
|
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
|
||||||
|
|
||||||
|
; error: no free slot found
|
||||||
|
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
|
||||||
|
ldy #loc_Y
|
||||||
|
lda (sp),y
|
||||||
|
sta fd_table+ft_iocb,x ; set iocb index
|
||||||
|
ldy #loc_devnum
|
||||||
|
lda (sp),y ; get (optional) device number
|
||||||
|
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
|
||||||
|
|
||||||
|
; string in "Xn:xxx" format
|
||||||
|
colon2: dey
|
||||||
lda (ptr4),y ; get device number
|
lda (ptr4),y ; get device number
|
||||||
sec
|
sec
|
||||||
sbc #'0'
|
sbc #'0'
|
||||||
|
and #7
|
||||||
ldy #loc_devnum
|
ldy #loc_devnum
|
||||||
sta (sp),y ; save it
|
sta (sp),y ; save it
|
||||||
|
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
|
||||||
|
|
||||||
|
; 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
|
||||||
|
|
||||||
|
; 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
|
||||||
|
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
|
||||||
|
|
||||||
|
; clean up and go home
|
||||||
|
finish: lda ptr4
|
||||||
|
pha
|
||||||
|
lda ptr4+1
|
||||||
|
pha
|
||||||
|
ldy #loc_Y
|
||||||
|
lda (sp),y
|
||||||
|
pha
|
||||||
|
lda tmp1
|
||||||
|
pha
|
||||||
|
ldy #loc_tmp1
|
||||||
|
lda (sp),y
|
||||||
|
sta tmp1
|
||||||
|
ldy #loc_size
|
||||||
|
jsr addysp
|
||||||
|
pla
|
||||||
|
lsr a ; set C as needed
|
||||||
|
|
||||||
pla
|
pla
|
||||||
tay
|
tay
|
||||||
colon1:
|
pla
|
||||||
|
tax
|
||||||
|
pla
|
||||||
|
rts
|
||||||
|
|
||||||
.endproc
|
.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
|
||||||
|
|
||||||
|
pha
|
||||||
|
lda tmp1
|
||||||
|
asl a
|
||||||
|
asl a ; also clears C
|
||||||
|
tax
|
||||||
|
inc fd_table+ft_usa,x ; increment usage counter
|
||||||
|
pla
|
||||||
|
error: rts
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
Loading…
Reference in New Issue
Block a user