From: cuz Date: Sat, 16 Nov 2002 23:45:15 +0000 (+0000) Subject: Finally: Commodore file I/O X-Git-Tag: V2.12.0~2101 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=751aaee63dd64a751458c9798d4c808fa7689b64;p=cc65 Finally: Commodore file I/O git-svn-id: svn://svn.cc65.org/cc65/trunk@1531 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/c128/Makefile b/libsrc/c128/Makefile index bbf6e953a..555fe81eb 100644 --- a/libsrc/c128/Makefile +++ b/libsrc/c128/Makefile @@ -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 index 9a574f32c..000000000 --- a/libsrc/c128/write.s +++ /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 - diff --git a/libsrc/c64/Makefile b/libsrc/c64/Makefile index f35520ecf..5b67a4b1c 100644 --- a/libsrc/c64/Makefile +++ b/libsrc/c64/Makefile @@ -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 index 22d7b1d37..000000000 --- a/libsrc/c64/read.s +++ /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 index 9a574f32c..000000000 --- a/libsrc/c64/write.s +++ /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 - diff --git a/libsrc/cbm/Makefile b/libsrc/cbm/Makefile index a95d33219..1a67ed45c 100644 --- a/libsrc/cbm/Makefile +++ b/libsrc/cbm/Makefile @@ -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) diff --git a/libsrc/cbm/cbm.inc b/libsrc/cbm/cbm.inc index 26644c5ba..4a418e5e1 100644 --- a/libsrc/cbm/cbm.inc +++ b/libsrc/cbm/cbm.inc @@ -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 index 000000000..0bca167bb --- /dev/null +++ b/libsrc/cbm/close.s @@ -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 index 000000000..ec0489e9f --- /dev/null +++ b/libsrc/cbm/diskerror.s @@ -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 index 000000000..eb4d7050d --- /dev/null +++ b/libsrc/cbm/filedes.inc @@ -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 index 000000000..384313b94 --- /dev/null +++ b/libsrc/cbm/filedes.s @@ -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 index 000000000..360c6d796 --- /dev/null +++ b/libsrc/cbm/filename.s @@ -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 + 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 index 000000000..54f247d4c --- /dev/null +++ b/libsrc/cbm/filevars.s @@ -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 index 000000000..5d8cb269b --- /dev/null +++ b/libsrc/cbm/open.s @@ -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 + + diff --git a/libsrc/cbm/oserrlist.s b/libsrc/cbm/oserrlist.s index 2180a7be9..b48f90970 100644 --- a/libsrc/cbm/oserrlist.s +++ b/libsrc/cbm/oserrlist.s @@ -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" diff --git a/libsrc/cbm/oserror.s b/libsrc/cbm/oserror.s index 15db27f53..3fa7b3e1e 100644 --- a/libsrc/cbm/oserror.s +++ b/libsrc/cbm/oserror.s @@ -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 index 000000000..6c2046900 --- /dev/null +++ b/libsrc/cbm/read.s @@ -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 index 000000000..e8ffad9d5 --- /dev/null +++ b/libsrc/cbm/scratch.s @@ -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 + 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 index 000000000..ddd900097 --- /dev/null +++ b/libsrc/cbm/sysremove.s @@ -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 index 000000000..dc7bf348c --- /dev/null +++ b/libsrc/cbm/write.s @@ -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 + + + + diff --git a/libsrc/vic20/Makefile b/libsrc/vic20/Makefile index 49f975557..d3f42397d 100644 --- a/libsrc/vic20/Makefile +++ b/libsrc/vic20/Makefile @@ -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 index 22d7b1d37..000000000 --- a/libsrc/vic20/read.s +++ /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 index 9a574f32c..000000000 --- a/libsrc/vic20/write.s +++ /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 -