1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-23 19:29:37 +00:00

Finally: Commodore file I/O

git-svn-id: svn://svn.cc65.org/cc65/trunk@1531 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2002-11-16 23:45:15 +00:00
parent 9e74c2b26f
commit 751aaee63d
23 changed files with 1023 additions and 273 deletions

View 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)

View File

@ -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

View 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)

View File

@ -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

View File

@ -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

View 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)

View 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

86
libsrc/cbm/close.s Normal file
View File

@ -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

87
libsrc/cbm/diskerror.s Normal file
View File

@ -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

21
libsrc/cbm/filedes.inc Normal file
View File

@ -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

37
libsrc/cbm/filedes.s Normal file
View File

@ -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

158
libsrc/cbm/filename.s Normal file
View File

@ -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

18
libsrc/cbm/filevars.s Normal file
View File

@ -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

168
libsrc/cbm/open.s Normal file
View File

@ -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

View 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"

View 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)

173
libsrc/cbm/read.s Normal file
View File

@ -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

49
libsrc/cbm/scratch.s Normal file
View File

@ -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

24
libsrc/cbm/sysremove.s Normal file
View File

@ -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

151
libsrc/cbm/write.s Normal file
View File

@ -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

View File

@ -21,8 +21,7 @@ OBJS = _scrsize.o \
cputc.o \
kbhit.o \
randomize.o \
readjoy.o \
write.o
readjoy.o
all: $(OBJS)

View File

@ -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

View File

@ -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