]> git.sur5r.net Git - cc65/commitdiff
Finally: Commodore file I/O
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 16 Nov 2002 23:45:15 +0000 (23:45 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 16 Nov 2002 23:45:15 +0000 (23:45 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1531 b7a2c559-68d2-44c3-8de9-860c34a00d81

23 files changed:
libsrc/c128/Makefile
libsrc/c128/write.s [deleted file]
libsrc/c64/Makefile
libsrc/c64/read.s [deleted file]
libsrc/c64/write.s [deleted file]
libsrc/cbm/Makefile
libsrc/cbm/cbm.inc
libsrc/cbm/close.s [new file with mode: 0644]
libsrc/cbm/diskerror.s [new file with mode: 0644]
libsrc/cbm/filedes.inc [new file with mode: 0644]
libsrc/cbm/filedes.s [new file with mode: 0644]
libsrc/cbm/filename.s [new file with mode: 0644]
libsrc/cbm/filevars.s [new file with mode: 0644]
libsrc/cbm/open.s [new file with mode: 0644]
libsrc/cbm/oserrlist.s
libsrc/cbm/oserror.s
libsrc/cbm/read.s [new file with mode: 0644]
libsrc/cbm/scratch.s [new file with mode: 0644]
libsrc/cbm/sysremove.s [new file with mode: 0644]
libsrc/cbm/write.s [new file with mode: 0644]
libsrc/vic20/Makefile
libsrc/vic20/read.s [deleted file]
libsrc/vic20/write.s [deleted file]

index bbf6e953ada330ec960051250517047281ed9921..555fe81ebe323519af063552d9fb5b5dd507d60c 100644 (file)
@@ -24,8 +24,7 @@ OBJS =        _scrsize.o      \
         randomize.o     \
        readjoy.o       \
        rs232.o         \
-       tgi_mode_table.o\
-       write.o
+       tgi_mode_table.o
 
 all:           $(OBJS)
 
diff --git a/libsrc/c128/write.s b/libsrc/c128/write.s
deleted file mode 100644 (file)
index 9a574f3..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-;
-; Ullrich von Bassewitz, 30.05.1998
-;
-; int write (int fd, const void* buf, int count);
-;
-; THIS IS A HACK!
-;
-
-       .export         _write
-       .import         popax
-       .importzp       ptr1, ptr2, ptr3
-
-       .include        "../cbm/cbm.inc"
-
-_write:        jsr     popax           ; get count
-               sta     ptr2
-       stx     ptr2+1          ; save it for later
-       sta     ptr3
-       stx     ptr3+1          ; save for function result
-       jsr     popax           ; get buf
-       sta     ptr1
-       stx     ptr1+1
-       jsr     popax           ; get fd and discard it
-
-L1:    lda     ptr2
-       ora     ptr2+1          ; count zero?
-       beq     L9
-       ldy     #0
-       lda     (ptr1),y
-       jsr     BSOUT
-       inc     ptr1
-       bne     L2
-       inc     ptr1+1
-L2:    lda     ptr2
-       bne     L3
-       dec     ptr2
-       dec     ptr2+1
-       jmp     L1
-L3:    dec     ptr2
-       jmp     L1
-
-; No error, return count
-
-L9:    lda     ptr3
-       ldx     ptr3+1
-       rts
-
index f35520ecfb2ff29a7828d5d5d45d080560ec9d79..5b67a4b1cefe06f2407ece7c22443f18c81ad4ed 100644 (file)
@@ -27,8 +27,7 @@ OBJS =        _scrsize.o              \
         randomize.o             \
                readjoy.o               \
                rs232.o                 \
-        tgi_mode_table.o       \
-       write.o
+        tgi_mode_table.o
 
 TGIS = c64-320-200-2.tgi
 
@@ -44,4 +43,4 @@ all:  $(OBJS) $(TGIS)
 
 clean:
        @rm -f $(OBJS) $(TGIS:.tgi=.o)
-                                 
+
diff --git a/libsrc/c64/read.s b/libsrc/c64/read.s
deleted file mode 100644 (file)
index 22d7b1d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-;
-; Ullrich von Bassewitz, 30.05.1998
-;
-; int read (int fd, void* buf, int count);
-;
-; THIS IS A HACK!
-;
-
-       .export         _read
-       .import         popax
-       .importzp       ptr1, ptr2, ptr3
-
-       .include        "../cbm/cbm.inc"
-
-_read: jsr     popax           ; get count
-       sta     ptr2
-       stx     ptr2+1          ; save it for later
-       jsr     popax           ; get buf
-       sta     ptr1
-       stx     ptr1+1
-       jsr     popax           ; get fd and discard it
-       lda     #0
-       sta     ptr3
-       sta     ptr3+1          ; set count
-
-L1:            lda     ptr2
-       ora     ptr2+1          ; count zero?
-       beq     L9
-       dec     ptr2
-       bne     L1a
-       dec     ptr2+1
-L1a:           jsr     BASIN
-       ldy     #0
-       sta     (ptr1),y        ; save char
-       inc     ptr1
-       bne     L2
-       inc     ptr1+1
-L2:            inc     ptr3            ; increment count
-       bne     L3
-       inc     ptr3+1
-L3:    cmp     #$0D            ; CR?
-       bne     L1
-
-; Done, return the count
-
-L9:     lda    ptr3
-       ldx     ptr3+1
-       rts
-
-
-
diff --git a/libsrc/c64/write.s b/libsrc/c64/write.s
deleted file mode 100644 (file)
index 9a574f3..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-;
-; Ullrich von Bassewitz, 30.05.1998
-;
-; int write (int fd, const void* buf, int count);
-;
-; THIS IS A HACK!
-;
-
-       .export         _write
-       .import         popax
-       .importzp       ptr1, ptr2, ptr3
-
-       .include        "../cbm/cbm.inc"
-
-_write:        jsr     popax           ; get count
-               sta     ptr2
-       stx     ptr2+1          ; save it for later
-       sta     ptr3
-       stx     ptr3+1          ; save for function result
-       jsr     popax           ; get buf
-       sta     ptr1
-       stx     ptr1+1
-       jsr     popax           ; get fd and discard it
-
-L1:    lda     ptr2
-       ora     ptr2+1          ; count zero?
-       beq     L9
-       ldy     #0
-       lda     (ptr1),y
-       jsr     BSOUT
-       inc     ptr1
-       bne     L2
-       inc     ptr1+1
-L2:    lda     ptr2
-       bne     L3
-       dec     ptr2
-       dec     ptr2+1
-       jmp     L1
-L3:    dec     ptr2
-       jmp     L1
-
-; No error, return count
-
-L9:    lda     ptr3
-       ldx     ptr3+1
-       rts
-
index a95d33219fb7bd406248def0dabce9e4a9084e70..1a67ed45cfd19fcf5087a9505b6f9805f2aced0e 100644 (file)
@@ -41,17 +41,27 @@ S_OBJS =    c_acptr.o       \
                cclear.o        \
                chline.o        \
                clock.o         \
+                close.o         \
                ctype.o         \
                cvline.o        \
+                diskerror.o     \
+                filedes.o       \
+                filename.o      \
+                filevars.o      \
                getenv.o        \
                gotox.o         \
                gotoxy.o        \
                gotoy.o         \
+                open.o          \
                 oserrlist.o     \
                oserror.o       \
+                read.o          \
                revers.o        \
+                scratch.o       \
+                sysremove.o     \
                 systime.o       \
-               where.o
+               where.o         \
+                write.o
 
 all:   $(C_OBJS) $(S_OBJS)
 
index 26644c5baa6d7878ce31df771b79d9b0fa90bd69..4a418e5e19a6309b0238bc65368dab54464c0545 100644 (file)
@@ -1,8 +1,12 @@
 ;
-; Subroutines available in the CBM jump table
+; Include file for the Commdore 6502 machines
 ;
 
 
+;-----------------------------------------------------------------------------
+; Subroutines available in the CBM jump table
+;
+
 CINT           = $FF81
 IOINIT         = $FF84
 RAMTAS         = $FF87
@@ -44,3 +48,11 @@ PLOT         = $FFF0
 IOBASE         = $FFF3
 
 
+;-----------------------------------------------------------------------------
+; Device numbers
+;
+                
+CBMDEV_KBD      = 0
+CBMDEV_DATASETTE= 1
+CBMDEV_RS232    = 2
+CBMDEV_SCREEN   = 3
diff --git a/libsrc/cbm/close.s b/libsrc/cbm/close.s
new file mode 100644 (file)
index 0000000..0bca167
--- /dev/null
@@ -0,0 +1,86 @@
+;
+; Ullrich von Bassewitz, 16.11.2002
+;
+; int __fastcall__ close (int fd);
+;
+
+        .export         _close
+
+        .import         getdiskerror
+        .import         __errno, __oserror
+
+        .include        "errno.inc"
+        .include        "cbm.inc"
+        .include        "filedes.inc"
+
+
+;--------------------------------------------------------------------------
+; _close
+
+.proc   _close
+
+; 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
+
+        adc     #LFN_OFFS       ; Carry is already clear
+        tax
+        lda     fdtab-LFN_OFFS,x; Get flags for this handle
+        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
+        jsr     CLOSE
+        pla
+
+; Read the drive error channel
+
+        lda     unittab,x
+        tax
+        jsr     getdiskerror
+        cmp     #$00
+        bne     error
+
+; Successful
+
+        tax
+        rts
+
+; Error entry, file descriptor is invalid
+
+invalidfd:
+        lda     #EINVAL
+        sta     __errno
+        lda     #0
+        sta     __errno+1
+        beq     errout
+
+; Error entry, file is not open
+
+notopen:
+        lda     #3              ; File not open
+        bne     error
+
+; Error entry, status not ok
+
+error:  sta     __oserror
+errout: lda     #$FF
+        tax                     ; Return -1
+        rts
+
+.endproc
+
+
+
+
diff --git a/libsrc/cbm/diskerror.s b/libsrc/cbm/diskerror.s
new file mode 100644 (file)
index 0000000..ec0489e
--- /dev/null
@@ -0,0 +1,87 @@
+;
+; 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
+
+
+
diff --git a/libsrc/cbm/filedes.inc b/libsrc/cbm/filedes.inc
new file mode 100644 (file)
index 0000000..eb4d705
--- /dev/null
@@ -0,0 +1,21 @@
+;
+; Ullrich von Bassewitz, 16.11.2002
+;
+; File descriptor management for the POSIX I/O routines
+;
+
+.global         fdtab   ; Handle table
+.global         unittab ; Unit table
+.global         freefd  ; Return a table entry
+
+MAX_FDS         = 8     ; Maximum number of file descriptors
+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_STDIN       = LFN_OFFS+0
+LFN_STDOUT      = LFN_OFFS+1
+LFN_STDERR      = LFN_OFFS+2
+
diff --git a/libsrc/cbm/filedes.s b/libsrc/cbm/filedes.s
new file mode 100644 (file)
index 0000000..384313b
--- /dev/null
@@ -0,0 +1,37 @@
+;
+; Ullrich von Bassewitz, 16.11.2002
+;
+; File descriptor management for the POSIX I/O routines
+;
+
+
+        .include        "filedes.inc"
+
+.code
+
+;--------------------------------------------------------------------------
+; freefd: Find a free file handle and return it in X. Return carry clear if we
+; found one, return a carry if no free lfns are left.
+
+.proc   freefd
+
+        ldx     #0
+        clc
+loop:   lda     fdtab,x
+        beq     found
+        inx
+        cpx     #MAX_FDS
+        bcc     loop
+found:  rts
+
+.endproc
+
+;--------------------------------------------------------------------------
+; Data
+
+.bss
+fdtab:  .res    MAX_FDS
+unittab:.res    MAX_FDS
+
+
+
diff --git a/libsrc/cbm/filename.s b/libsrc/cbm/filename.s
new file mode 100644 (file)
index 0000000..360c6d7
--- /dev/null
@@ -0,0 +1,158 @@
+;
+; Ullrich von Bassewitz, 16.11.2002
+;
+; File name handling for CBM file I/O
+;
+
+        .export         fnparse, fnset, fncomplete
+        .export         fnunit, fnlen, fncmd, fnbuf
+
+        .import         __curunit, __filetype
+        .importzp       ptr1
+
+        .include        "ctype.inc"
+        .include        "cbm.inc"
+
+
+;--------------------------------------------------------------------------
+; fnparse: Parse a filename passed in in a/x. Will set the following
+; variables:
+;
+;       fnlen   -> length of filename
+;       fnbuf   -> filename including drive spec
+;       fnunit  -> unit from spec or default unit
+
+
+.proc   fnparse
+
+        sta     ptr1
+        stx     ptr1+1          ; Save pointer to name
+
+; For now we're always using the default unit
+
+        lda     __curunit
+        sta     fnunit
+
+; Check the name for a drive spec
+
+        ldy     #0
+        lda     (ptr1),y
+        sta     fnbuf+0
+        cmp     #'0'
+        beq     digit
+        cmp     #'1'
+        bne     nodrive
+
+digit:  iny
+        lda     (ptr1),y
+        cmp     #':'
+        bne     nodrive
+
+; We found a drive spec, copy it to the buffer
+
+        sta     fnbuf+1
+        iny                     ; Skip colon
+        bne     drivedone       ; Branch always
+
+; We did not find a drive spec, always use drive zero
+
+nodrive:
+        lda     #'0'
+        sta     fnbuf+0
+        lda     #':'
+        sta     fnbuf+1
+        ldy     #$00            ; Reposition to start of name
+
+; Drive spec done. Copy the name into the file name buffer. Check that all
+; file name characters are valid and that the maximum length is not exceeded.
+
+drivedone:
+        lda     #2              ; Length of drive spec
+        sta     fnlen
+
+nameloop:
+        lda     (ptr1),y        ; Get next char from filename
+        beq     namedone        ; Jump if end of name reached
+
+; Check for valid chars in the file name
+
+        tax
+        lda     __ctype,x
+        and     #CT_ALNUM       ; Letters and digits are allowed
+        beq     invalidname
+
+; Check the maximum length, store the character
+
+        ldx     fnlen
+        cpx     #14             ; Maximum length reached?
+        bcs     invalidname
+        lda     (ptr1),y        ; Reload char
+        sta     fnbuf,x         ; Store into buffer
+        inc     fnlen           ; Count characters
+        iny                     ; Next char from name
+        bne     nameloop        ; Branch always
+
+; Invalid file name
+
+invalidname:
+        lda     #33             ; Invalid file name
+
+; Done, we've successfully parsed the name.
+
+namedone:
+        rts
+
+.endproc
+
+
+;--------------------------------------------------------------------------
+; fnset: Tell the kernal about the file name
+
+.proc   fnset
+
+        lda     fnlen
+        ldx     #<fnbuf
+        ldy     #>fnbuf
+        jmp     SETNAM
+
+.endproc
+
+;--------------------------------------------------------------------------
+; fncomplete: Complete a filename by adding ",t,m" where t is the file type
+; and m is the access mode passed in in the A register
+
+.proc  fncomplete
+
+       pha                     ; Save mode
+       ldx     fnlen
+       lda     #','
+       sta     fnbuf,x
+       inx
+       lda     __filetype
+       sta     fnbuf,x
+       inx
+       lda     #','
+       sta     fnbuf,x
+       inx
+       pla
+       sta     fnbuf,x
+       inx
+       stx     fnlen
+       rts
+
+.endproc
+
+;--------------------------------------------------------------------------
+; Data
+
+.bss
+
+fnunit: .res    1
+fnlen:  .res    1
+
+.data
+fncmd:  .byte   's'             ; Use as scratch command
+fnbuf:  .res    20
+
+
+
diff --git a/libsrc/cbm/filevars.s b/libsrc/cbm/filevars.s
new file mode 100644 (file)
index 0000000..54f247d
--- /dev/null
@@ -0,0 +1,18 @@
+;
+; Ullrich von Bassewitz, 15.11.2002
+;
+; Variables used for CBM file I/O
+;
+
+        .export         __curunit
+        .export         __filetype
+
+
+.data
+
+__curunit:
+        .byte   8               ; Default is disk
+
+__filetype:
+        .byte   'u'             ; Create user files by default
+
diff --git a/libsrc/cbm/open.s b/libsrc/cbm/open.s
new file mode 100644 (file)
index 0000000..5d8cb26
--- /dev/null
@@ -0,0 +1,168 @@
+;
+; Ullrich von Bassewitz, 16.11.2002
+;
+; int open (const char* name, int flags, ...); /* May take a mode argument */
+;
+
+        .export         _open
+
+        .import         addysp, popax
+        .import         scratch, fnparse, fncomplete, fnset
+        .import         getdiskerror
+        .import         __errno, __oserror
+        .import         fnunit
+        .importzp       sp, tmp2, tmp3
+
+        .include        "errno.inc"
+        .include        "fcntl.inc"
+        .include        "cbm.inc"
+        .include        "filedes.inc"
+
+
+;--------------------------------------------------------------------------
+; initstdout: Open the stdout and stderr file descriptors for the screen.
+
+.proc   _open
+
+       cpy     #4              ; correct # of arguments (bytes)?
+       beq     parmok          ; parameter count ok
+       tya                     ; parm count < 4 shouldn't be needed to be...
+               sec                     ; ...checked (it generates a c compiler warning)
+       sbc     #4
+       tay
+       jsr     addysp          ; fix stack, throw away unused parameters
+
+; Parameters ok. Pop the flags and save them into tmp3
+
+parmok: jsr     popax           ; Get flags
+        sta     tmp3
+
+; Get the filename from stack and parse it. Bail out if is not ok
+
+        jsr     popax           ; Get name
+        jsr     fnparse         ; Parse it
+        cmp     #0
+        bne     error           ; Bail out if problem with name
+
+; Get a free file handle and remember it in tmp2
+
+        jsr     freefd
+        bcs     nofile
+        stx     tmp2
+
+; Check the flags. We cannot have:
+;
+;  - both, read and write flags set
+;  - the append flag set
+;
+
+        lda     tmp3
+        and     #O_RDWR
+        beq     invflags        ; Neither read nor write
+        cmp     #O_RDWR
+        beq     invflags        ; Jump if both set
+        cmp     #O_RDONLY
+        beq     doread
+
+; Write bit is set. We cannot open a file for writing without creating it,
+; so check for the O_CREAT bit.
+
+        lda     tmp3
+        and     #O_CREAT
+        beq     invflags
+
+; If O_TRUNC is set, scratch the file, but ignore any errors
+
+        lda     tmp3
+        and     #O_TRUNC
+        beq     notrunc
+        jsr     scratch
+
+; Complete the the file name
+
+notrunc:
+        lda     #'w'
+        jsr     fncomplete
+
+; Setup the real open flags
+
+        lda     #LFN_WRITE
+        bne     common
+
+; Read bit is set. Add an 'r' to the name
+
+doread: lda     #'r'
+        jsr     fncomplete
+        lda     #LFN_READ
+
+; Common read/write code. Flags in A, handle in tmp2
+
+common: sta     tmp3
+        jsr     fnset           ; Set the file name
+
+        lda     tmp2
+        clc
+        adc     #LFN_OFFS
+        ldx     fnunit
+        tay                     ; Use the LFN also as SA
+        jsr     SETLFS          ; Set the file params
+
+        jsr     OPEN
+        bcs     error
+
+; Read the error channel
+
+        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
+
+; File is open. Mark it as open in the table
+
+isopen: ldx     tmp2
+        lda     tmp3
+        sta     fdtab,x
+        lda     fnunit
+        sta     unittab,x       ; Remember
+
+; Done. Return the handle in a/x
+
+        txa                     ; Handle
+        ldx     #0
+        rts
+
+; Error entry: No more file handles
+
+nofile: lda     #1              ; Too many open files
+
+; Error entry. Error code is in A.
+
+error:  sta     __oserror
+errout: lda     #$FF
+        tax                     ; Return -1
+        rts
+
+; Error entry: Invalid flag parameter
+
+invflags:
+        lda     #EINVAL
+        sta     __errno
+        lda     #0
+        sta     __errno+1
+        beq     errout
+
+
+
+.endproc
+
+
index 2180a7be9f8f420007957df7e600623441dd3623..b48f90970569aa4de767f50ae8e4d9d6da47fe08 100644 (file)
@@ -80,6 +80,7 @@ __sys_oserrlist:
                sys_oserr_entry         71, "Directory error"
                sys_oserr_entry         72, "Disk full"
                sys_oserr_entry         73, "DOS version mismatch"
+        sys_oserr_entry         74, "Drive not ready"
         sys_oserr_sentinel      "Unknown error"
 
 
index 15db27f532e1c090ade3968a586ce600bf7241b4..3fa7b3e1ebbcb2946503ee98a578dec4f3c00a97 100644 (file)
@@ -42,36 +42,37 @@ ErrTab:
        .byte   7, EINVAL       ; File not output
        .byte   8, EINVAL       ; Filename missing
        .byte   9, ENODEV       ; Ilegal device
-;      .byte  20,              ; Read error
-;              .byte  21,              ; Read error
-;      .byte  22,              ; Read error
-;              .byte  23,              ; Read error
-;              .byte  24,              ; Read error
-;              .byte  25,              ; Write error
+;      .byte  20,              ; Read error
+;              .byte  21,              ; Read error
+;      .byte  22,              ; Read error
+;              .byte  23,              ; Read error
+;              .byte  24,              ; Read error
+;              .byte  25,              ; Write error
        .byte  26, EACCES       ; Write protect on
-;              .byte  27,              ; Read error
-;              .byte  28,              ; Write error
-;              .byte  29,              ; Disk ID mismatch
-;              .byte  30,              ; Syntax error
-;              .byte  31,              ; Syntax error
-;              .byte  32,              ; Syntax error
+;              .byte  27,              ; Read error
+;              .byte  28,              ; Write error
+;              .byte  29,              ; Disk ID mismatch
+;              .byte  30,              ; Syntax error
+;              .byte  31,              ; Syntax error
+;              .byte  32,              ; Syntax error
                .byte  33, EINVAL       ; Syntax error (invalid file name)
                .byte  34, EINVAL       ; Syntax error (no file given)
-;              .byte  39,              ; Syntax error
-;              .byte  50,              ; Record not present
-;              .byte  51,              ; Overflow in record
-;      .byte  52,              ; File too large
+;              .byte  39,              ; Syntax error
+;              .byte  50,              ; Record not present
+;              .byte  51,              ; Overflow in record
+;      .byte  52,              ; File too large
        .byte  60, EINVAL       ; Write file open
        .byte  61, EINVAL       ; File not open
        .byte  62, ENOENT       ; File not found
        .byte  63, EEXIST       ; File exists
        .byte  64, EINVAL       ; File type mismatch
-;      .byte  65,              ; No block
-;      .byte  66,              ; Illegal track or sector
-;              .byte  67,              ; Illegal system track or sector
+;      .byte  65,              ; No block
+;      .byte  66,              ; Illegal track or sector
+;              .byte  67,              ; Illegal system track or sector
        .byte  70, EBUSY        ; No channel
-;              .byte  71,              ; Directory error
+;              .byte  71,              ; Directory error
 ;      .byte  72,              ; Disk full
-;              .byte  73,              ; DOS version mismatch
+;              .byte  73,              ; DOS version mismatch
+        .byte  74, ENODEV       ; Drive not ready
 
 ErrTabSize = (* - ErrTab)
diff --git a/libsrc/cbm/read.s b/libsrc/cbm/read.s
new file mode 100644 (file)
index 0000000..6c20469
--- /dev/null
@@ -0,0 +1,173 @@
+;
+; Ullrich von Bassewitz, 16.11.2002
+;
+; int read (int fd, void* buf, unsigned count);
+;
+
+        .export         _read
+        .constructor    initstdin
+
+        .import         popax
+        .import         __errno, __oserror
+        .importzp       ptr1, ptr2, ptr3, tmp1, tmp2
+
+        .include        "errno.inc"
+        .include        "fcntl.inc"
+        .include        "cbm.inc"
+        .include        "filedes.inc"
+
+
+;--------------------------------------------------------------------------
+; initstdin: Open the stdin file descriptors for the keyboard
+
+.proc   initstdin
+
+        lda     #LFN_READ
+        sta     fdtab+STDIN_FILENO
+        lda     #STDIN_FILENO + LFN_OFFS
+        ldx     #CBMDEV_KBD
+        stx     unittab+STDIN_FILENO
+        ldy     #$FF
+        jsr     SETLFS
+        jmp     OPEN            ; Will always succeed
+
+.endproc
+
+;--------------------------------------------------------------------------
+; _read
+
+
+.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
+
+; Check if the LFN is valid and the file is open for writing
+
+        adc     #LFN_OFFS       ; Carry is already clear
+        tax
+        lda     fdtab-LFN_OFFS,x; Get flags for this handle
+        and     #LFN_READ       ; File open for writing?
+        beq     notopen
+
+; 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
+
+; Read the next byte
+
+loop:   jsr     BASIN
+        sta     tmp1            ; Save the input byte
+
+        jsr     READST          ; Read the IEEE status
+        sta     tmp2            ; Save it
+        and     #%10111111      ; Check anything but the EOI bit
+        bne     error5          ; Assume device not present
+
+; Store the byte just read
+
+        ldy     #0
+        lda     tmp1
+        sta     (ptr2),y
+        inc     ptr2
+        bne     @L1
+        inc     ptr2+1          ; *buf++ = A;
+
+; Increment the byte count
+
+@L1:    inc     ptr3
+        bne     @L2
+        inc     ptr3+1
+
+; Get the status again and check the EOI bit
+
+@L2:    lda     tmp2
+        and     #%01000000      ; Check for EOI
+        bne     done            ; Jump if end of file reached
+
+; Decrement the count
+
+deccount:
+        inc     ptr1
+        bne     loop
+        inc     ptr1+1
+        bne     loop
+
+; Read done, close the input channel
+
+done:   jsr     CLRCH
+
+; Return the number of chars read
+
+        lda     ptr3
+        ldx     ptr3+1
+        rts
+
+; Error entry, file descriptor is invalid
+
+invalidfd:
+        lda     #EINVAL
+        sta     __errno
+        lda     #0
+        sta     __errno+1
+        beq     errout
+
+; Error entry, file is not open
+
+notopen:
+        lda     #3              ; File not open
+        bne     error
+
+; Error entry, status not ok
+
+error5: lda     #5              ; Device not present
+error:  sta     __oserror
+errout: lda     #$FF
+        tax                     ; Return -1
+        rts
+
+.endproc
+
+
+
+
diff --git a/libsrc/cbm/scratch.s b/libsrc/cbm/scratch.s
new file mode 100644 (file)
index 0000000..e8ffad9
--- /dev/null
@@ -0,0 +1,49 @@
+;
+; Ullrich von Bassewitz, 16.11.2002
+;
+; Scratch a file on disk
+;
+
+        .export         scratch
+        .import         readdiskerror
+        .import         fnunit, fnlen, fncmd
+
+        .include        "cbm.inc"
+
+;--------------------------------------------------------------------------
+; scratch: Scratch a file on disk. Expects the name of the file to be already
+; parsed. 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   scratch
+
+        lda     #15             ; Command channel
+        ldx     fnunit          ; Unit
+        tay                     ; Secondary address
+        jsr     SETLFS
+
+        lda     #'s'            ; Scratch command
+        sta     fncmd
+        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
+
+        pha
+        lda     #15
+        jsr     CLOSE
+        pla
+
+done:   rts
+
+.endproc
+
+
diff --git a/libsrc/cbm/sysremove.s b/libsrc/cbm/sysremove.s
new file mode 100644 (file)
index 0000000..ddd9000
--- /dev/null
@@ -0,0 +1,24 @@
+;
+; Ullrich von Bassewitz, 16.11.2002
+;
+; unsigned char __fastcall__ _sysremove (const char* name);
+;
+
+        .export         __sysremove
+        .import         fnparse, scratch
+
+
+;--------------------------------------------------------------------------
+; __sysremove:
+
+.proc   __sysremove
+
+        jsr     fnparse         ; Parse the given file name
+        cmp     #0              ; Do we have an error?
+        bne     err             ; Jump if yes
+        jmp     scratch         ; Scratch the file, return an error code
+err:    rts
+
+.endproc
+
+
diff --git a/libsrc/cbm/write.s b/libsrc/cbm/write.s
new file mode 100644 (file)
index 0000000..dc7bf34
--- /dev/null
@@ -0,0 +1,151 @@
+;
+; Ullrich von Bassewitz, 16.11.2002
+;
+; int write (int fd, const void* buf, unsigned count);
+;
+
+        .export         _write
+        .constructor    initstdout
+
+        .import         incsp6
+        .import         __errno, __oserror
+        .importzp       sp, ptr1, ptr2
+
+        .include        "errno.inc"
+        .include        "fcntl.inc"
+        .include        "cbm.inc"
+        .include        "filedes.inc"
+
+
+;--------------------------------------------------------------------------
+; initstdout: Open the stdout and stderr file descriptors for the screen.
+
+.proc   initstdout
+
+        lda     #LFN_WRITE
+        sta     fdtab+STDOUT_FILENO
+        sta     fdtab+STDERR_FILENO
+        lda     #CBMDEV_SCREEN
+        sta     unittab+STDOUT_FILENO
+        sta     unittab+STDERR_FILENO
+        lda     #STDOUT_FILENO + LFN_OFFS
+        jsr     @L1
+        lda     #STDERR_FILENO + LFN_OFFS
+@L1:    ldx     #CBMDEV_SCREEN
+        ldy     #$FF
+        jsr     SETLFS
+        jmp     OPEN            ; Will always succeed
+
+.endproc
+
+;--------------------------------------------------------------------------
+; _write
+
+
+.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
+
+; Check if the LFN is valid and the file is open for writing
+
+        adc     #LFN_OFFS       ; Carry is already clear
+        tax
+        lda     fdtab-LFN_OFFS,x; Get flags for this handle
+        and     #LFN_WRITE      ; File open for writing?
+        beq     notopen
+
+; Valid lfn. Make it the output file
+
+        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
+
+; Read the IEEE488 status
+
+loop:   jsr     READST
+        cmp     #0
+        bne     error5
+
+        ldy     #0
+        lda     (ptr2),y
+        inc     ptr2
+        bne     @L1
+        inc     ptr2+1          ; A = *buf++;
+
+@L1:    jsr     BSOUT
+
+; Decrement count
+
+deccount:
+        inc     ptr1
+        bne     loop
+        inc     ptr1+1
+        bne     loop
+
+; Wrote all chars, close the output channel
+
+        jsr     CLRCH
+
+; Return the number of chars written
+
+        ldy     #1
+        lda     (sp),y
+        tax
+        dey
+        lda     (sp),y
+        jmp     incsp6
+
+; Error entry, file descriptor is invalid
+
+invalidfd:
+        lda     #EINVAL
+        sta     __errno
+        lda     #0
+        sta     __errno+1
+        beq     errout
+
+; Error entry, file is not open
+
+notopen:
+        lda     #3              ; File not open
+        bne     error
+
+; Error entry, status not ok
+
+error5: lda     #5              ; Device not present
+error:  sta     __oserror
+errout: lda     #$FF
+        tax                     ; Return -1
+        jmp     incsp6
+
+.endproc
+
+
+
+
index 49f9755572ca2f4eb9d22bdb3076f48e4f950986..d3f42397d8596a313ec40993370bd958011a98f2 100644 (file)
@@ -21,8 +21,7 @@ OBJS =        _scrsize.o      \
        cputc.o         \
        kbhit.o         \
         randomize.o     \
-       readjoy.o       \
-       write.o
+       readjoy.o       
 
 all:   $(OBJS)
 
diff --git a/libsrc/vic20/read.s b/libsrc/vic20/read.s
deleted file mode 100644 (file)
index 22d7b1d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-;
-; Ullrich von Bassewitz, 30.05.1998
-;
-; int read (int fd, void* buf, int count);
-;
-; THIS IS A HACK!
-;
-
-       .export         _read
-       .import         popax
-       .importzp       ptr1, ptr2, ptr3
-
-       .include        "../cbm/cbm.inc"
-
-_read: jsr     popax           ; get count
-       sta     ptr2
-       stx     ptr2+1          ; save it for later
-       jsr     popax           ; get buf
-       sta     ptr1
-       stx     ptr1+1
-       jsr     popax           ; get fd and discard it
-       lda     #0
-       sta     ptr3
-       sta     ptr3+1          ; set count
-
-L1:            lda     ptr2
-       ora     ptr2+1          ; count zero?
-       beq     L9
-       dec     ptr2
-       bne     L1a
-       dec     ptr2+1
-L1a:           jsr     BASIN
-       ldy     #0
-       sta     (ptr1),y        ; save char
-       inc     ptr1
-       bne     L2
-       inc     ptr1+1
-L2:            inc     ptr3            ; increment count
-       bne     L3
-       inc     ptr3+1
-L3:    cmp     #$0D            ; CR?
-       bne     L1
-
-; Done, return the count
-
-L9:     lda    ptr3
-       ldx     ptr3+1
-       rts
-
-
-
diff --git a/libsrc/vic20/write.s b/libsrc/vic20/write.s
deleted file mode 100644 (file)
index 9a574f3..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-;
-; Ullrich von Bassewitz, 30.05.1998
-;
-; int write (int fd, const void* buf, int count);
-;
-; THIS IS A HACK!
-;
-
-       .export         _write
-       .import         popax
-       .importzp       ptr1, ptr2, ptr3
-
-       .include        "../cbm/cbm.inc"
-
-_write:        jsr     popax           ; get count
-               sta     ptr2
-       stx     ptr2+1          ; save it for later
-       sta     ptr3
-       stx     ptr3+1          ; save for function result
-       jsr     popax           ; get buf
-       sta     ptr1
-       stx     ptr1+1
-       jsr     popax           ; get fd and discard it
-
-L1:    lda     ptr2
-       ora     ptr2+1          ; count zero?
-       beq     L9
-       ldy     #0
-       lda     (ptr1),y
-       jsr     BSOUT
-       inc     ptr1
-       bne     L2
-       inc     ptr1+1
-L2:    lda     ptr2
-       bne     L3
-       dec     ptr2
-       dec     ptr2+1
-       jmp     L1
-L3:    dec     ptr2
-       jmp     L1
-
-; No error, return count
-
-L9:    lda     ptr3
-       ldx     ptr3+1
-       rts
-