]> git.sur5r.net Git - cc65/commitdiff
Working on the CBM file functions
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 17 Nov 2002 22:45:55 +0000 (22:45 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 17 Nov 2002 22:45:55 +0000 (22:45 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1533 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/cbm/Makefile
libsrc/cbm/cbm.inc
libsrc/cbm/close.s
libsrc/cbm/diskcmd.s [new file with mode: 0644]
libsrc/cbm/diskerror.s [deleted file]
libsrc/cbm/filedes.inc
libsrc/cbm/open.s
libsrc/cbm/read.s
libsrc/cbm/rwcommon.s [new file with mode: 0644]
libsrc/cbm/scratch.s
libsrc/cbm/write.s

index 1a67ed45cfd19fcf5087a9505b6f9805f2aced0e..a77597bfa936cf4b7aeb260bbc2d68e40164802b 100644 (file)
@@ -44,7 +44,7 @@ S_OBJS =      c_acptr.o       \
                 close.o         \
                ctype.o         \
                cvline.o        \
-                diskerror.o     \
+                diskcmd.o       \
                 filedes.o       \
                 filename.o      \
                 filevars.o      \
@@ -57,6 +57,7 @@ S_OBJS =      c_acptr.o       \
                oserror.o       \
                 read.o          \
                revers.o        \
+                rwcommon.o      \
                 scratch.o       \
                 sysremove.o     \
                 systime.o       \
index 4a418e5e19a6309b0238bc65368dab54464c0545..d0f0aad3ca1739b5e02a8013f7444a880e09bc8e 100644 (file)
@@ -51,8 +51,17 @@ IOBASE               = $FFF3
 ;-----------------------------------------------------------------------------
 ; Device numbers
 ;
-                
+
 CBMDEV_KBD      = 0
 CBMDEV_DATASETTE= 1
 CBMDEV_RS232    = 2
 CBMDEV_SCREEN   = 3
+
+;-----------------------------------------------------------------------------
+; Disk stuff
+;
+            
+MAX_DRIVES      = 24
+FIRST_DRIVE     = 8
+
+
index 0bca167bbba75700089b2c581d474aebe48172ac..c521c0801cd255a13af15a7a5db6994644f5c2ad 100644 (file)
@@ -6,8 +6,9 @@
 
         .export         _close
 
-        .import         getdiskerror
+        .import         readdiskerror, closecmdchannel
         .import         __errno, __oserror
+        .importzp       tmp2
 
         .include        "errno.inc"
         .include        "cbm.inc"
         bne     invalidfd
         cmp     #MAX_FDS        ; Is it valid?
         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
-        lda     fdtab-LFN_OFFS,x; Get flags for this handle
+        lda     fdtab,x         ; Get flags for this handle
+        and     #LFN_OPEN
         beq     notopen
 
 ; Valid lfn, close it. The close call is always error free, at least as far
 ; as the kernal is involved
 
         lda     #LFN_CLOSED
-        sta     fdtab-LFN_OFFS,x
-        lda     unittab,x
-        pha                     ; Push unit for this file
-        txa
+        sta     fdtab,x
+        lda     tmp2            ; Get the handle
+        clc
+        adc     #LFN_OFFS       ; Make LFN from handle
         jsr     CLOSE
-        pla
 
-; Read the drive error channel
+; Read the drive error channel, then close it
 
-        lda     unittab,x
-        tax
-        jsr     getdiskerror
-        cmp     #$00
-        bne     error
+        ldy     tmp2            ; Get the handle
+        ldx     unittab,y       ; Get teh disk for this handle
+        jsr     readdiskerror   ; Read the disk error code
+        pha                     ; Save it on stack
+        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
 
-        tax
+        tax                     ; Return zero in a/x
         rts
 
 ; Error entry, file descriptor is invalid
diff --git a/libsrc/cbm/diskcmd.s b/libsrc/cbm/diskcmd.s
new file mode 100644 (file)
index 0000000..134622f
--- /dev/null
@@ -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
diff --git a/libsrc/cbm/diskerror.s b/libsrc/cbm/diskerror.s
deleted file mode 100644 (file)
index ec0489e..0000000
+++ /dev/null
@@ -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
-
-
-
index eb4d7050dd223c2be3996b0cad8736d45d0cd077..cccd067e9af9c9e6835eaba98901a42e62df686d 100644 (file)
@@ -14,6 +14,8 @@ LFN_OFFS        = 3     ; Start with logical file number 3
 LFN_CLOSED      = $00   ; LFN is closed
 LFN_READ        = $01   ; Open for reading
 LFN_WRITE       = $02   ; Open for writing
+LFN_OPEN        = (LFN_READ | LFN_WRITE)
+LFN_EOF         = $80   ; Read to EOF
 
 LFN_STDIN       = LFN_OFFS+0
 LFN_STDOUT      = LFN_OFFS+1
index 5d8cb269be11ae8680b448fdf7dd436a67eebd60..ad902237a4e13e8bdaa820385fe6fd8550479175 100644 (file)
@@ -8,7 +8,7 @@
 
         .import         addysp, popax
         .import         scratch, fnparse, fncomplete, fnset
-        .import         getdiskerror
+        .import         opencmdchannel, closecmdchannel, readdiskerror
         .import         __errno, __oserror
         .import         fnunit
         .importzp       sp, tmp2, tmp3
@@ -110,26 +110,18 @@ common: sta     tmp3
         jsr     OPEN
         bcs     error
 
-; Read the error channel
+; Open the the drive command channel and read it
 
         ldx     fnunit
-        jsr     getdiskerror
-        cmp     #0
-        beq     isopen          ; Branch if no error
-
-; We had an error, close the file
-
-        pha
-        lda     tmp2
-        clc
-        adc     #LFN_OFFS
-        jsr     CLOSE
-        pla
-        bne     error           ; Branch always
+        jsr     opencmdchannel
+        bne     closeandexit
+        ldx     fnunit
+        jsr     readdiskerror
+        bne     closeandexit    ; Branch on error
 
 ; File is open. Mark it as open in the table
 
-isopen: ldx     tmp2
+        ldx     tmp2
         lda     tmp3
         sta     fdtab,x
         lda     fnunit
@@ -161,7 +153,18 @@ invflags:
         sta     __errno+1
         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
 
index 6c2046900819eb52bf1714b4a08c0b6c575e4530..5a2157b998bb8e636fc82aef84509e53780bac1d 100644 (file)
@@ -6,10 +6,11 @@
 
         .export         _read
         .constructor    initstdin
-
+           
+        .import         rwcommon
         .import         popax
         .import         __errno, __oserror
-        .importzp       ptr1, ptr2, ptr3, tmp1, tmp2
+        .importzp       ptr1, ptr2, ptr3, tmp1, tmp2, tmp3
 
         .include        "errno.inc"
         .include        "fcntl.inc"
 
 .proc   _read
 
-; Retrieve count
-
-        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
+        jsr     rwcommon        ; Pop params, check handle
+        bcs     invalidfd       ; Branch if handle not ok
 
 ; Check if the LFN is valid and the file is open for writing
 
         and     #LFN_READ       ; File open for writing?
         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
 
         jsr     CHKIN
         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...
 
-        beq     deccount        ; Branch always
+        bcc     @L3             ; Branch always
 
 ; Read the next byte
 
-loop:   jsr     BASIN
+@L0:    jsr     BASIN
         sta     tmp1            ; Save the input byte
 
         jsr     READST          ; Read the IEEE status
-        sta     tmp2            ; Save it
+        sta     tmp3            ; Save it
         and     #%10111111      ; Check anything but the EOI bit
         bne     error5          ; Assume device not present
 
@@ -121,17 +92,24 @@ loop:   jsr     BASIN
 
 ; Get the status again and check the EOI bit
 
-@L2:    lda     tmp2
+@L2:    lda     tmp3
         and     #%01000000      ; Check for EOI
-        bne     done            ; Jump if end of file reached
+        bne     @L4             ; Jump if end of file reached
 
 ; Decrement the count
 
-deccount:
-        inc     ptr1
-        bne     loop
+@L3:    inc     ptr1
+        bne     @L0
         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
 
@@ -139,7 +117,7 @@ done:   jsr     CLRCH
 
 ; Return the number of chars read
 
-        lda     ptr3
+eof:    lda     ptr3
         ldx     ptr3+1
         rts
 
@@ -157,7 +135,7 @@ invalidfd:
 notopen:
         lda     #3              ; File not open
         bne     error
-
+                    
 ; Error entry, status not ok
 
 error5: lda     #5              ; Device not present
diff --git a/libsrc/cbm/rwcommon.s b/libsrc/cbm/rwcommon.s
new file mode 100644 (file)
index 0000000..2e124c7
--- /dev/null
@@ -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
+
+
index e8ffad9d564a37a384f87edb29c3f58841f5a9b3..6fd617308efaa0986bab789531fa094766e04b71 100644 (file)
@@ -5,8 +5,9 @@
 ;
 
         .export         scratch
-        .import         readdiskerror
+        .import         opencmdchannel, closecmdchannel, writediskcmd
         .import         fnunit, fnlen, fncmd
+        .importzp       ptr1
 
         .include        "cbm.inc"
 
 
 .proc   scratch
 
-        lda     #15             ; Command channel
-        ldx     fnunit          ; Unit
-        tay                     ; Secondary address
-        jsr     SETLFS
+        ldx     fnunit
+        jsr     opencmdchannel
+        bne     done
 
         lda     #'s'            ; Scratch command
         sta     fncmd
+
+        lda     #<fncmd
+        sta     ptr1
+        lda     #>fncmd
+        sta     ptr1+1
+
         ldx     fnlen
         inx                     ; Account for "S"
         txa                     ; Length of name into A
-        ldx     #<fncmd
-        ldy     #>fncmd
-        jsr     SETNAM
-
-        jsr     OPEN
-        bcs     done
-
-        jsr     readdiskerror   ; Read the command channel
+        ldx     fnunit          ; Unit
+        jsr     writediskcmd
 
         pha
-        lda     #15
-        jsr     CLOSE
+        ldx     fnunit
+        jsr     closecmdchannel
         pla
 
 done:   rts
index dc7bf348caf3cac63892feda9788fe65ee1033db..508deb6b8f2024475772df074ad320ece5fe726f 100644 (file)
@@ -7,9 +7,9 @@
         .export         _write
         .constructor    initstdout
 
-        .import         incsp6
+        .import         rwcommon
         .import         __errno, __oserror
-        .importzp       sp, ptr1, ptr2
+        .importzp       sp, ptr1, ptr2, ptr3
 
         .include        "errno.inc"
         .include        "fcntl.inc"
 
 .proc   _write
 
-        ldy     #4
-        lda     (sp),y          ; Get fd
-
-; Check if we have a valid handle
-
-        cmp     #MAX_FDS        ; Is it valid?
-        bcs     invalidfd       ; Jump if no
+        jsr     rwcommon        ; Pop params, check handle
+        bcs     invalidfd       ; Branch if handle not ok
 
 ; Check if the LFN is valid and the file is open for writing
 
 
         jsr     CKOUT
         bcs     error
-
-; 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
+        bcc     @L2
 
 ; Read the IEEE488 status
 
-loop:   jsr     READST
+@L0:    jsr     READST
         cmp     #0
         bne     error5
 
+; Output the next character from the buffer
+
         ldy     #0
         lda     (ptr2),y
         inc     ptr2
         bne     @L1
         inc     ptr2+1          ; A = *buf++;
-
 @L1:    jsr     BSOUT
 
+; Count characters written
+
+        inc     ptr3
+        bne     @L2
+        inc     ptr3+1
+
 ; Decrement count
 
-deccount:
-        inc     ptr1
-        bne     loop
+@L2:    inc     ptr1
+        bne     @L0
         inc     ptr1+1
-        bne     loop
+        bne     @L0
 
 ; Wrote all chars, close the output channel
 
@@ -114,12 +95,9 @@ deccount:
 
 ; Return the number of chars written
 
-        ldy     #1
-        lda     (sp),y
-        tax
-        dey
-        lda     (sp),y
-        jmp     incsp6
+        lda     ptr3
+        ldx     ptr3+1
+        rts
 
 ; Error entry, file descriptor is invalid
 
@@ -142,7 +120,7 @@ error5: lda     #5              ; Device not present
 error:  sta     __oserror
 errout: lda     #$FF
         tax                     ; Return -1
-        jmp     incsp6
+        rts
 
 .endproc