1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 23:29:39 +00:00

Working on the CBM file functions

git-svn-id: svn://svn.cc65.org/cc65/trunk@1533 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2002-11-17 22:45:55 +00:00
parent 43d5800702
commit 544ff5b900
11 changed files with 377 additions and 229 deletions

View File

@ -44,7 +44,7 @@ S_OBJS = c_acptr.o \
close.o \ close.o \
ctype.o \ ctype.o \
cvline.o \ cvline.o \
diskerror.o \ diskcmd.o \
filedes.o \ filedes.o \
filename.o \ filename.o \
filevars.o \ filevars.o \
@ -57,6 +57,7 @@ S_OBJS = c_acptr.o \
oserror.o \ oserror.o \
read.o \ read.o \
revers.o \ revers.o \
rwcommon.o \
scratch.o \ scratch.o \
sysremove.o \ sysremove.o \
systime.o \ systime.o \

View File

@ -51,8 +51,17 @@ IOBASE = $FFF3
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
; Device numbers ; Device numbers
; ;
CBMDEV_KBD = 0 CBMDEV_KBD = 0
CBMDEV_DATASETTE= 1 CBMDEV_DATASETTE= 1
CBMDEV_RS232 = 2 CBMDEV_RS232 = 2
CBMDEV_SCREEN = 3 CBMDEV_SCREEN = 3
;-----------------------------------------------------------------------------
; Disk stuff
;
MAX_DRIVES = 24
FIRST_DRIVE = 8

View File

@ -6,8 +6,9 @@
.export _close .export _close
.import getdiskerror .import readdiskerror, closecmdchannel
.import __errno, __oserror .import __errno, __oserror
.importzp tmp2
.include "errno.inc" .include "errno.inc"
.include "cbm.inc" .include "cbm.inc"
@ -25,36 +26,40 @@
bne invalidfd bne invalidfd
cmp #MAX_FDS ; Is it valid? cmp #MAX_FDS ; Is it valid?
bcs invalidfd ; Jump if no bcs invalidfd ; Jump if no
sta tmp2 ; Save the handle
; Check if the LFN is valid and the file is open for writing ; Check if the file is actually open
adc #LFN_OFFS ; Carry is already clear
tax tax
lda fdtab-LFN_OFFS,x; Get flags for this handle lda fdtab,x ; Get flags for this handle
and #LFN_OPEN
beq notopen beq notopen
; Valid lfn, close it. The close call is always error free, at least as far ; Valid lfn, close it. The close call is always error free, at least as far
; as the kernal is involved ; as the kernal is involved
lda #LFN_CLOSED lda #LFN_CLOSED
sta fdtab-LFN_OFFS,x sta fdtab,x
lda unittab,x lda tmp2 ; Get the handle
pha ; Push unit for this file clc
txa adc #LFN_OFFS ; Make LFN from handle
jsr CLOSE jsr CLOSE
pla
; Read the drive error channel ; Read the drive error channel, then close it
lda unittab,x ldy tmp2 ; Get the handle
tax ldx unittab,y ; Get teh disk for this handle
jsr getdiskerror jsr readdiskerror ; Read the disk error code
cmp #$00 pha ; Save it on stack
bne error ldy tmp2
ldx unittab,y
jsr closecmdchannel ; Close the disk command channel
pla ; Get the error code from the disk
bne error ; Jump if error
; Successful ; Successful
tax tax ; Return zero in a/x
rts rts
; Error entry, file descriptor is invalid ; Error entry, file descriptor is invalid

212
libsrc/cbm/diskcmd.s Normal file
View File

@ -0,0 +1,212 @@
;
; Ullrich von Bassewitz, 17.11.2002
;
; Handle disk command channels
;
.export isdisk
.export opencmdchannel
.export closecmdchannel
.export readdiskerror
.export writediskcmd
.importzp tmp1, ptr1
.include "cbm.inc"
.include "filedes.inc"
;--------------------------------------------------------------------------
; isdisk: Return carry clear if the unit number in X is a disk, return
; carry set if not.
.proc isdisk
cpx #FIRST_DRIVE ; Disk unit?
bcc @L1 ; Branch if no disk
cpx #FIRST_DRIVE+MAX_DRIVES
rts
@L1: sec
rts
.endproc
;--------------------------------------------------------------------------
; Open the command channel for the disk unit in X. The function returns an
; error code in A and sets the flags according to the contents of A.
opencmdchannel:
jsr isdisk ; Disk unit?
bcs success
; Is this channel already open?
ldy opentab-FIRST_DRIVE,x
bne isopen
; Open the command channel, Carry is still clear
stx tmp1 ; Save the unit number
txa ; Get unit number
adc #(LFN_OFFS+MAX_FDS-FIRST_DRIVE)
ldy #15 ; Secondary address for cmd channel
jsr SETLFS
lda #0
jsr SETNAM ; No name supplied to OPEN
jsr OPEN
bcs done ; Error, code is in A
; Command channel is open now. Increment the count
ldx tmp1 ; Unit number
ldy opentab-FIRST_DRIVE,x
isopen: iny
tya
sta opentab-FIRST_DRIVE,x
; Done, return success
success:lda #$00
done: cmp #$00 ; Set flags for return code
rts
;--------------------------------------------------------------------------
; closecmdchannel: Decrement the counter for the disk command channel and
; close the channel if the counter drops to zero. The function expects the
; drive number in X and returns an error code in A. The flags for the return
; code are set when the function returns.
closecmdchannel:
jsr isdisk ; Disk unit?
bcs success
; Is this channel really open?
ldy opentab-FIRST_DRIVE,x
beq success ; OOPS! Channel is not open
; Decrement the count and stor it back
dey
tya
sta opentab-FIRST_DRIVE,x
; If the counter is now zero, close the channel. We still have carry clear
; when we come here.
bne success
txa ; Make LFN from drive number
adc #(LFN_OFFS+MAX_FDS-FIRST_DRIVE)
jsr CLOSE
bcs done
bcc success
;--------------------------------------------------------------------------
; readdiskerror: Read a disk error from an already open command channel.
; Returns an error code in A, which may either be the code read from the
; command channel, or another error when accessing the command channel failed.
readdiskerror:
jsr isdisk
bcs success
; Read the command channel. We won't check the status after the channel is
; open, because this seems to be unnecessary in most cases.
txa
clc ; Make LFN from drive number
adc #(LFN_OFFS+MAX_FDS-FIRST_DRIVE)
tax
jsr CHKIN ; Make the command channel input
bcs done ; Bail out with error code in A
jsr BASIN
and #$0F ; Make digit value from PETSCII
sta tmp1
asl a ; * 2
asl a ; * 4, carry clear
adc tmp1 ; * 5
asl a ; * 10
sta tmp1
jsr BASIN
and #$0F ; Make digit value from PETSCII
clc
adc tmp1
; Errors below 20 are not real errors. Fix that
cmp #20+1
bcs @L1
lda #$00
@L1: pha
; Read the remainder of the message and throw it away
@L2: jsr BASIN
cmp #$0D
bne @L2
; Close the input channel
jsr CLRCH
; Restore the error code (will also set the flags) and return
pla
rts
;--------------------------------------------------------------------------
; writediskcmd: Gets pointer to data in ptr1, length in A. Writes all data
; to the command channel of the given drive. Returns an error code in A,
; flags are set according to the contents of A.
writediskcmd:
jsr isdisk
bcs success
; Remember the length
sta tmp1
; Write to the command channel.
txa
clc ; Make LFN from drive number
adc #(LFN_OFFS+MAX_FDS-FIRST_DRIVE)
tax
jsr CKOUT ; Make the command channel output
bcs done ; Bail out with error code in A
ldy #$00
@L1: cpy tmp1
bcs @L3
lda (ptr1),y
iny
jsr BSOUT
bcc @L1
@L2: pha
jsr CLRCH
pla
rts
@L3: jsr CLRCH
lda #$00
rts
;--------------------------------------------------------------------------
; Data
.bss
opentab: .res MAX_DRIVES, 0

View File

@ -1,87 +0,0 @@
;
; Ullrich von Bassewitz, 16.11.2002
;
; Read the disk error channel
;
.export readdiskerror, getdiskerror
.import fnunit
.importzp tmp1
.include "cbm.inc"
;--------------------------------------------------------------------------
; readdiskerror: Read a disk error from an already open command channel.
; Returns an error code in A, which may either be the code read from the
; command channel, or another error when accessing the command channel failed.
.proc readdiskerror
; Read the command channel. We won't check the status after the channel is
; open, because this seems to be unnecessary in most cases.
ldx #15
jsr CHKIN ; Read from LFN 15
bcs done ; Bail out with error code in A
jsr BASIN
and #$0F ; Make digit value from PETSCII
sta tmp1
asl a ; * 2
asl a ; * 4, carry clear
adc tmp1 ; * 5
asl a ; * 10
sta tmp1
jsr BASIN
and #$0F ; Make digit value from PETSCII
clc
adc tmp1
; Errors below 20 are not real errors. Fix that
cmp #20+1
bcs done
lda #0
done: rts
.endproc
;--------------------------------------------------------------------------
; getdiskerror: Open the command channel to a disk unit with id in X. Read
; the error and close it again. Returns an error code in A, which may either
; be the code read from the command channel, or another error when accessing
; the command channel failed.
.proc getdiskerror
cpx #8 ; Disk unit?
bcc nodisk
lda #15 ; Command channel
tay ; Secondary address
jsr SETLFS
lda #$00
jsr SETNAM ; No name supplied to OPEN
jsr OPEN
bcs err
jsr readdiskerror
pha ; Save error code
lda #15
jsr CLOSE
pla
err: rts
nodisk: lda #$00
rts
.endproc

View File

@ -14,6 +14,8 @@ LFN_OFFS = 3 ; Start with logical file number 3
LFN_CLOSED = $00 ; LFN is closed LFN_CLOSED = $00 ; LFN is closed
LFN_READ = $01 ; Open for reading LFN_READ = $01 ; Open for reading
LFN_WRITE = $02 ; Open for writing LFN_WRITE = $02 ; Open for writing
LFN_OPEN = (LFN_READ | LFN_WRITE)
LFN_EOF = $80 ; Read to EOF
LFN_STDIN = LFN_OFFS+0 LFN_STDIN = LFN_OFFS+0
LFN_STDOUT = LFN_OFFS+1 LFN_STDOUT = LFN_OFFS+1

View File

@ -8,7 +8,7 @@
.import addysp, popax .import addysp, popax
.import scratch, fnparse, fncomplete, fnset .import scratch, fnparse, fncomplete, fnset
.import getdiskerror .import opencmdchannel, closecmdchannel, readdiskerror
.import __errno, __oserror .import __errno, __oserror
.import fnunit .import fnunit
.importzp sp, tmp2, tmp3 .importzp sp, tmp2, tmp3
@ -110,26 +110,18 @@ common: sta tmp3
jsr OPEN jsr OPEN
bcs error bcs error
; Read the error channel ; Open the the drive command channel and read it
ldx fnunit ldx fnunit
jsr getdiskerror jsr opencmdchannel
cmp #0 bne closeandexit
beq isopen ; Branch if no error ldx fnunit
jsr readdiskerror
; We had an error, close the file bne closeandexit ; Branch on error
pha
lda tmp2
clc
adc #LFN_OFFS
jsr CLOSE
pla
bne error ; Branch always
; File is open. Mark it as open in the table ; File is open. Mark it as open in the table
isopen: ldx tmp2 ldx tmp2
lda tmp3 lda tmp3
sta fdtab,x sta fdtab,x
lda fnunit lda fnunit
@ -161,7 +153,18 @@ invflags:
sta __errno+1 sta __errno+1
beq errout beq errout
; Error entry: Close the file and exit
closeandexit:
pha
lda tmp2
clc
adc #LFN_OFFS
jsr CLOSE
ldx fnunit
jsr closecmdchannel
pla
bne error ; Branch always
.endproc .endproc

View File

@ -6,10 +6,11 @@
.export _read .export _read
.constructor initstdin .constructor initstdin
.import rwcommon
.import popax .import popax
.import __errno, __oserror .import __errno, __oserror
.importzp ptr1, ptr2, ptr3, tmp1, tmp2 .importzp ptr1, ptr2, ptr3, tmp1, tmp2, tmp3
.include "errno.inc" .include "errno.inc"
.include "fcntl.inc" .include "fcntl.inc"
@ -39,31 +40,8 @@
.proc _read .proc _read
; Retrieve count jsr rwcommon ; Pop params, check handle
bcs invalidfd ; Branch if handle not ok
jsr popax ; Get count
eor #$FF
sta ptr1
txa
eor #$FF
sta ptr1+1 ; Remember -count-1
; Retrieve buf
jsr popax
sta ptr2
stx ptr2+1
; Retrieve the handle
jsr popax
; Check if we have a valid handle
cpx #$00
bne invalidfd
cmp #MAX_FDS ; Is it valid?
bcs invalidfd ; Jump if no
; Check if the LFN is valid and the file is open for writing ; Check if the LFN is valid and the file is open for writing
@ -73,34 +51,27 @@
and #LFN_READ ; File open for writing? and #LFN_READ ; File open for writing?
beq notopen beq notopen
; Check the EOF flag. If it is set, don't read anything
lda fdtab-LFN_OFFS,x; Get flags for this handle
bmi eof
; Valid lfn. Make it the input file ; Valid lfn. Make it the input file
jsr CHKIN jsr CHKIN
bcs error bcs error
; Clear the byte counter
lda #$00
sta ptr3
sta ptr3+1
; Read the status to check if we are already at the end of the file
jsr READST
and #%01000000
bne done
; Go looping... ; Go looping...
beq deccount ; Branch always bcc @L3 ; Branch always
; Read the next byte ; Read the next byte
loop: jsr BASIN @L0: jsr BASIN
sta tmp1 ; Save the input byte sta tmp1 ; Save the input byte
jsr READST ; Read the IEEE status jsr READST ; Read the IEEE status
sta tmp2 ; Save it sta tmp3 ; Save it
and #%10111111 ; Check anything but the EOI bit and #%10111111 ; Check anything but the EOI bit
bne error5 ; Assume device not present bne error5 ; Assume device not present
@ -121,17 +92,24 @@ loop: jsr BASIN
; Get the status again and check the EOI bit ; Get the status again and check the EOI bit
@L2: lda tmp2 @L2: lda tmp3
and #%01000000 ; Check for EOI and #%01000000 ; Check for EOI
bne done ; Jump if end of file reached bne @L4 ; Jump if end of file reached
; Decrement the count ; Decrement the count
deccount: @L3: inc ptr1
inc ptr1 bne @L0
bne loop
inc ptr1+1 inc ptr1+1
bne loop bne @L0
beq done ; Branch always
; Set the EOI flag and bail out
@L4: ldx tmp2 ; Get the handle
lda #LFN_EOF
ora fdtab,x
sta fdtab,x
; Read done, close the input channel ; Read done, close the input channel
@ -139,7 +117,7 @@ done: jsr CLRCH
; Return the number of chars read ; Return the number of chars read
lda ptr3 eof: lda ptr3
ldx ptr3+1 ldx ptr3+1
rts rts
@ -157,7 +135,7 @@ invalidfd:
notopen: notopen:
lda #3 ; File not open lda #3 ; File not open
bne error bne error
; Error entry, status not ok ; Error entry, status not ok
error5: lda #5 ; Device not present error5: lda #5 ; Device not present

47
libsrc/cbm/rwcommon.s Normal file
View File

@ -0,0 +1,47 @@
;
; Ullrich von Bassewitz, 17.11.2002
;
; Common stuff for the read/write routines
;
.export rwcommon
.import popax
.importzp ptr1, ptr2, ptr3, tmp2
.include "filedes.inc"
;--------------------------------------------------------------------------
; rwcommon: Pop the parameters from stack, preprocess them and place them
; into zero page locations. Return carry set if the handle is invalid,
; return carry clear if it is ok. If the carry is clear, the handle is
; returned in A.
.proc rwcommon
jsr popax ; Get count
eor #$FF
sta ptr1
txa
eor #$FF
sta ptr1+1 ; Remember -count-1
jsr popax ; Get buf
sta ptr2
stx ptr2+1
lda #$00
sta ptr3
sta ptr3+1 ; Clear ptr3
jsr popax ; Get the handle
sta tmp2
cpx #$01
bcs inv
cmp #MAX_FDS
inv: rts
.endproc

View File

@ -5,8 +5,9 @@
; ;
.export scratch .export scratch
.import readdiskerror .import opencmdchannel, closecmdchannel, writediskcmd
.import fnunit, fnlen, fncmd .import fnunit, fnlen, fncmd
.importzp ptr1
.include "cbm.inc" .include "cbm.inc"
@ -18,28 +19,27 @@
.proc scratch .proc scratch
lda #15 ; Command channel ldx fnunit
ldx fnunit ; Unit jsr opencmdchannel
tay ; Secondary address bne done
jsr SETLFS
lda #'s' ; Scratch command lda #'s' ; Scratch command
sta fncmd sta fncmd
lda #<fncmd
sta ptr1
lda #>fncmd
sta ptr1+1
ldx fnlen ldx fnlen
inx ; Account for "S" inx ; Account for "S"
txa ; Length of name into A txa ; Length of name into A
ldx #<fncmd ldx fnunit ; Unit
ldy #>fncmd jsr writediskcmd
jsr SETNAM
jsr OPEN
bcs done
jsr readdiskerror ; Read the command channel
pha pha
lda #15 ldx fnunit
jsr CLOSE jsr closecmdchannel
pla pla
done: rts done: rts

View File

@ -7,9 +7,9 @@
.export _write .export _write
.constructor initstdout .constructor initstdout
.import incsp6 .import rwcommon
.import __errno, __oserror .import __errno, __oserror
.importzp sp, ptr1, ptr2 .importzp sp, ptr1, ptr2, ptr3
.include "errno.inc" .include "errno.inc"
.include "fcntl.inc" .include "fcntl.inc"
@ -44,13 +44,8 @@
.proc _write .proc _write
ldy #4 jsr rwcommon ; Pop params, check handle
lda (sp),y ; Get fd bcs invalidfd ; Branch if handle not ok
; Check if we have a valid handle
cmp #MAX_FDS ; Is it valid?
bcs invalidfd ; Jump if no
; Check if the LFN is valid and the file is open for writing ; Check if the LFN is valid and the file is open for writing
@ -64,49 +59,35 @@
jsr CKOUT jsr CKOUT
bcs error bcs error
bcc @L2
; Calculate -count-1 for easier looping
ldy #0
lda (sp),y
eor #$FF
sta ptr1
iny
lda (sp),y
eor #$FF
sta ptr1+1
; Get the pointer to the data buffer
iny
lda (sp),y
sta ptr2
iny
lda (sp),y
sta ptr2+1
jmp deccount
; Read the IEEE488 status ; Read the IEEE488 status
loop: jsr READST @L0: jsr READST
cmp #0 cmp #0
bne error5 bne error5
; Output the next character from the buffer
ldy #0 ldy #0
lda (ptr2),y lda (ptr2),y
inc ptr2 inc ptr2
bne @L1 bne @L1
inc ptr2+1 ; A = *buf++; inc ptr2+1 ; A = *buf++;
@L1: jsr BSOUT @L1: jsr BSOUT
; Count characters written
inc ptr3
bne @L2
inc ptr3+1
; Decrement count ; Decrement count
deccount: @L2: inc ptr1
inc ptr1 bne @L0
bne loop
inc ptr1+1 inc ptr1+1
bne loop bne @L0
; Wrote all chars, close the output channel ; Wrote all chars, close the output channel
@ -114,12 +95,9 @@ deccount:
; Return the number of chars written ; Return the number of chars written
ldy #1 lda ptr3
lda (sp),y ldx ptr3+1
tax rts
dey
lda (sp),y
jmp incsp6
; Error entry, file descriptor is invalid ; Error entry, file descriptor is invalid
@ -142,7 +120,7 @@ error5: lda #5 ; Device not present
error: sta __oserror error: sta __oserror
errout: lda #$FF errout: lda #$FF
tax ; Return -1 tax ; Return -1
jmp incsp6 rts
.endproc .endproc