randomize.o \
readjoy.o \
rs232.o \
- tgi_mode_table.o\
- write.o
+ tgi_mode_table.o
all: $(OBJS)
+++ /dev/null
-;
-; 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
-
randomize.o \
readjoy.o \
rs232.o \
- tgi_mode_table.o \
- write.o
+ tgi_mode_table.o
TGIS = c64-320-200-2.tgi
clean:
@rm -f $(OBJS) $(TGIS:.tgi=.o)
-
+
+++ /dev/null
-;
-; 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
-
-
-
+++ /dev/null
-;
-; 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
-
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)
;
-; 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
IOBASE = $FFF3
+;-----------------------------------------------------------------------------
+; Device numbers
+;
+
+CBMDEV_KBD = 0
+CBMDEV_DATASETTE= 1
+CBMDEV_RS232 = 2
+CBMDEV_SCREEN = 3
--- /dev/null
+;
+; 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
+
+
+
+
--- /dev/null
+;
+; 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
+
+
+
--- /dev/null
+;
+; 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
+
--- /dev/null
+;
+; 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
+
+
+
--- /dev/null
+;
+; 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
+
+
+
--- /dev/null
+;
+; 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
+
--- /dev/null
+;
+; 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
+
+
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"
.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)
--- /dev/null
+;
+; 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
+
+
+
+
--- /dev/null
+;
+; 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
+
+
--- /dev/null
+;
+; 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
+
+
--- /dev/null
+;
+; 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
+
+
+
+
cputc.o \
kbhit.o \
randomize.o \
- readjoy.o \
- write.o
+ readjoy.o
all: $(OBJS)
+++ /dev/null
-;
-; 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
-
-
-
+++ /dev/null
-;
-; 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
-