1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-11-22 01:31:33 +00:00

Added fileio and filesys modules for VIC-20 and C64

This commit is contained in:
Curtis F Kaylor 2019-03-29 19:06:12 -04:00
parent 1440c42c26
commit 0e149b7798
9 changed files with 1421 additions and 84 deletions

View File

@ -46,9 +46,8 @@ VICSCN EQU $0400 ;Video Screen Memory Area (Unexpanded)
CHRROM EQU $D000 ;Character Generator ROM
VICCLR EQU $D800 ;Color RAM (Unexpanded)
;Kernal Routines
chrin EQU $FFCF ;Input Character to Channel
chrout EQU $FFD2 ;Output Character to Channel
;ROM Routines
FSFLFA EQU $F314 ;Find Logical File A
;Machine Language Basic Stub
ORG $0801 ;Start of Basic Program

41
include/cbm/error.a02 Normal file
View File

@ -0,0 +1,41 @@
;error.a02 - Error Code Definitions for all Commodore 8-bit machines
;Generic System Errors
ENOSYS EQU 255 ;*Function not implemented
;Kernal Errors
ECNCLD EQU $01 ;Operation Canceled
ENFILE EQU $02 ;Too Many Open Files (in System)
EBADF EQU $03 ;File Not Open (Bad File Descriptor)
ENOENT EQU $04 ;File Not Found (No Such Entry)
ENODEV EQU $05 ;Device Does Not Exist (No Such Device)
EINVAL EQU $06 ;File Name Missing (Invalid Argument)
ENXIO EQU $07 ;Illegal Device Number (No Such Device or Address)
;Cassette/EIC Bus/RS-232 Errors
ETMOUT EQU $09 ;Read/Write Time Out (Connection timed out)
EMSIZE EQU $0A ;Short/Long Block/Record (Message too Long)
EBADM EQU $0B ;Checksum/Framing Error (Bad Message)
EFAULT EQU $0C ;End of Tape/Device Not Present (Bad Address)
ECOMM EQU $0D ;CTS Missing (Communication error on send)
EBUSY EQU $0E ;DTS Missing (Device or resource busy)
ECNRST EQU $0F ;BREAK Detected (Connection Reset)
;Commodore DOS Errors (Error Numbers)
;No Error $00 ;(00-19)
EREAD EQU $10 ;Read Error (20-24)
EWRITE EQU $11 ;Write Error (25)
EROFS EQU $12 ;Write-Protect On (26)
EIO EQU $13 ;Input/Output Error (27-29)
ENOSUP EQU $14 ;Command/Syntax Error (30-23)
ENOMSG EQU $15 ;Record Error (50-51)
EFBIG EQU $16 ;File too large (52)
EPERM EQU $17 ;File Open for Write (60)
EBADFD EQU $18 ;File Not Open/Not Found (61-62)
EEXIST EQU $19 ;File exists (63)
ETYPE EQU $1A ;File Type Mismatch (64)
ENOBLK EQU $1B ;Block Read/Write Error (65-67)
EMFILE EQU $1C ;No Channels Available (70)
ENODIR EQU $1D ;Directory Error (71)
ENOSPC EQU $1E ;Disk or Directory Full (72)
EAGAIN EQU $1F ;DOS Mismatch/Drive Not Ready (73-74)

694
include/cbm/fileio.a02 Normal file
View File

@ -0,0 +1,694 @@
;C02 Module file.h02 Assembly Language Routines
;for all Commodore 8 bit machines
; Requires error code definitions from error.a02,
; External routines FSFLFA, RESRXY, STRLEN
; and the following RAM locations definitions
; external zero page byte pairs SRCLO,SRCHI and DSTLO,DSTHI
; and external bytes TEMP1, TEMP2
; NOTE: Reading from CASSETTE will not produce an EOF
;Kernal Device Numbers
KEYBRD EQU 0
CASST1 EQU 1
MODEM1 EQU 2
SCREEN EQU 3
PRNTR1 EQU 4
PRNTR2 EQU 5
PRNTR3 EQU 6
PRNTR4 EQU 7
DRIVE1 EQU 8
DRIVE2 EQU 9
DRIVE3 EQU 10
DRIVE4 EQU 11
DRIVE5 EQU 12
DRIVE6 EQU 13
DRIVE7 EQU 14
DRIVE8 EQU 15
;Disk Numbers (Within Drive)
DISK0 EQU $00
DISK1 EQU $40
;File Open Modes
MWRITE EQU $80
MREAD EQU $00
;File Load Modes
MABSLT EQU $80 ;Absolute (Use File Header Address)
MRELCT EQU $00 ;Relocate (Use Specified Address)
;File Types
FTASC EQU $00 ;ASCII Text (SEQ)
FTBAS EQU $10 ;Basic Program (PRG)
FTBIN EQU $20 ;Binary File (PRG)
FTUSR EQU $30 ;User-Defined (USR)
;Zero Page System Variables (Names Subject to Change)
FSIOST EQU $90 ;Kernal I/O Status Word
FSNOFL EQU $98 ;Number of Open I/O Files
FSRCVB EQU $A4 ;Serial Bus Received Byte
FSSVLO EQU $AC ;Save Address (Low Byte)
FSSVHI EQU $AD ;Save Address (High Byte)
FSFNLN EQU $B7 ;Length of Current Filename
FSLFNO EQU $B8 ;Current Logical File Number
FSSADR EQU $B9 ;Current Secondary Address
FSDVNO EQU $BA ;Current Device Number
FSFNLO EQU $BB ;Pointer: Current Filename (LSB)
FSFNHI EQU $BC ;Pointer: Current Filename (MSB)
;IEC STATUS Bit Masks
FSSTTO EQU $03 ;Disk - Read/Write Timeout $21 //Error - Operation Timed Out
FSSTSB EQU $04 ;Tape - Short Block
FSSTLB EQU $08 ;Tape - Long Block
FSSTRE EQU $10 ;Tape - Read Error
FSSTCE EQU $20 ;Both - Checksum Error
FSSTEF EQU $40 ;Both - End of File
FSSTNP EQU $80 ;Disk - Device Not Present
FSSTET EQU $80 ;Tape - End of Tape
;RS-232 Status Bit Masks
;$01 - Parity Error
;$02 - Framing Error
;$04 - Receive Overrun
;$10 - CTS Missing
;$40 - DSR Missing
;$80 - BREAK Detected
;fsioet[15] - I/O Error Table by Channel Number
FSIOET EQU $0140 ;Bottom of BASIC Stack Area
;fscntr - File Counter
FSCNTR EQU $0150 ;Byte Following Error Table
;fsbufr - Buffer for String Concatenation
FSBUFR EQU $0200 ;BASIC Line Editor Input Buffer
;Error Code Conversion Tables
;FSCSST DC FSSSPE,FSSSFE,FSSSRO,FSSSCM,FSSSDM,FSSSBD
FSCSTT DC FSSTTO,FSSTSB,FSSTLB,FSSTRE,FSSTCE ;STATUS to Error Code
;String Constants
FSCMDI DC "I",0 ;Command - Initialize Drive
FSWSFX DC ",S,W",0 ;Filename Suffix for Write
;fsbcmd(command) - Build Disk Command String
;Args: A = Disk Command (Single Letter Abbreviation)
;Uses: FSBUFR = Command String
; TEMP2 = Mode/Option Byte
FSBCMD: STA FSBUFR ;Store Command in FSBUFR[0]
JSR FSDSKN ;Get Disk Number
STA FSBUFR+1 ;and Store in FSBUFR[1]
LDA #58 ;Load ':'
STA FSBUFR+2 ;and Store in FSBUFR[2]
LDA #0 ;Load String Terminator
STA FSBUFR+3 ;and Store in FSBUFR[3]
RTS
;fsdskn() - Get Disk Number
;Uses: TEMP2 = Mode/Option Byte
;Returns: A = Disk Number "0" or "1"
FSDSKN: LDA TEMP2 ;Get Option Byte
AND #$01 ;Isolate Drive Number
ORA #$30 ;Convert to ASCII
RTS
;fschan(chan) - Find Channel Info
;Args: A = Logical File Number
;Uses: $0259 = LAT File number table
; $0263 = FAT Device number table
; $026D = SAT Secondary address table
;Returns: A = Device Number
; Y = Secondary Address
; X = Index into File Tables
; $FF if Channel Not Open
FSCHAN: JSR FSFLFA ;Find File Table Index
BMI FSCHAX ;If Found
LDA $026D,X ;Load Secondary Address into Y
TAY
LDA $0263,X ;Load Device Number into X
FSCHAX: RTS
;fsinit(device) - Initialize Disk Drive
;Args: A = Device Number
; Y,X = Pointer to Command String
;Uses: FSBUFR - String Concatenation Buffer
;Sets: TEMP2 = Number of Bytes Read from Drive
;Returns: A = Drive Status Code
; Y = Kernal or I/O Error
FSINIT: LDX #<FSCMDI ;Load Pointer to Command String
LDY #>FSCMDI ;and Fall Trhough to FSDCMD
;fsdcmd(device) - Send Command to Drive
;Args: A = Device Number
; Y,X = Pointer to Command String
;Uses: FSBUFR - String Concatenation Buffer
;Sets: TEMP2 = Number of Bytes Read from Drive
;Returns: A = Drive Status Code
; Y = Kernal or I/O Error
FSDCMD: JSR SETSRC ;Save Command String Pointer
JSR FSOCMD ;Open Command Channel
BEQ FSCHAX ;If Not Open, Return
ORA #$80 ;Set flag to Emit C/R
JSR FPUTSA ;Call fputs() - Alternate Entry Point
BCC FSDSTR ;If No Error, Get Disk Status
RTS ;Else Return
;fscste(status) - Convert STATUS byte into Error Code
FSCSTE: LDY #5 ;Set Index to Table Size
FSCSTL: AND FSCSTT-1,Y ;Mask Bits Against Table Entry
BNE FSCSTS ;If Bits Not Set
DEY ; Decrement Index
BNE FSCSTL ; and Loop if Not Zero
FSCSTS: TYA ;Copy Index to Accumulator
BEQ FSCSTX ;If Not Zero
ORA #$10 ; Convert from $0x to $1x
FSCSTX: RTS
;fscdst(status) - Convert Drive Status
;Args: A = Drive Status Code
;Returns: Y = Converted Error Code
;fsdsts(device) - Get Drive Status
;Args: A = Device Number
;Uses: FSBUFR - String Concatenation Buffer
;Returns: A = Drive Status Code
; Y = Kernal or I/O Error
FSDSTS: JSR FSOCMD ;Open Command Channel
BCS FSCHAX ;If Error, Return
FSDSTR: JSR FSRCMD ;Read Command Channel
BEQ FSDSTX ;If Bytes Read
JSR FSGBFR ; Get Buffer Address
JSR ATOC ; Convert Error# to Byte
LDY #0 ; Set Error to 0
FSDSTX: RTS ;and Return
;fscbfr() - Copy Source String to String Buffer
;Args: C = Mode
;Uses: SRCLO,SRCHI = Pointer to Source String
FSCBFR: JSR FSGBFR ;Get String Buffer Address
JSR SETDST ;Set Buffer as Destination
LDY #0 ;Initialize Index
BCS FSCBFS ;If Carry Clear
JMP STRCPL ; Copy String
FSCBFS: JMP STRCAL ;Else Concatenate String
;fsgbfr() - Get String Buffer Address
FSGBFR: LDX #<FSBUFR ;Load LSB into X
LDY #>FSBUFR ;Load MSB into Y
RTS
;fsocmd(device) - Open Command Channel
;Args: A = Device Number
;Returns: A = Logical File Number
FSOCMD: ORA #$10 ;Set LFN to Device# + 16
JSR FSFLFA ;Find File Table Index
BPL FSCHAX ;If Already Open, Return
TAX ;Copy Device Number to X
FSOCMX: LDA #0 ;Set Filename to None
JSR $FFBD ;Call Kernal SETNAM Routine
FSET15: LDA #15 ;Set LFN to 15
BNE FSOPEY ;Copy to SA and Open Channel
;fsname(&s) - Set Filename for Load, Save
;Args: Y,X = Pointer to string containing filename
FSNAME: JSR STRLEN ;Get Length of String
JSR GETSRC ;Retrieve String Address
JMP $FFBD ;Execute Kernal SETNAM Routine
;fsonam(&s) - Set Filename for Open
;Args: Y,X = Pointer to string containing filename
FSONAM: LDA TEMP1 ;Get Device Number
AND TEMP2 ;AND with Mode/Option
AND #$08 ;Check Disk + Write Bit
BEQ FSNAME ;Execute FSNAME/FSWNAM
;fswnam(&s) - Set Filename for Write to Disk
;Args: Y,X = Pointer to string containing filename
FSWNAM: JSR SETSRC ;Set Filename as Source
CLC ;Set Flag to Copy
JSR FSCBFR ;and Copy to String Buffer
LDX #<FSWSFX
LDY #>FSWSFX
JSR STRCAT ;Append Write Suffix
JSR FSGBFR ;Get String Buffer Address
JMP $FFBD ;Execute Kernal SETNAM Routine
;fsldsv() - Setup for Load and Save
;Args: A = Logical File Number
; Y = Mode
; X = Device Number
;Returns: Y,X = Destination Address (DSTHI,DSTLO)
FSLDSV: PHA ;Save LFN
TYA ;Copy Mode to Accumulator
LSR ;Rotate Bit 3 to Bit 1
LSR
LSR
TAY ;Use as Secondary Address
PLA ;Restore LFN
JSR $FFBA ;Call Kernal SETLFS Routine
JMP GETDST ;Get Load/End Address into X,Y
;fsopts() - Parse Load/Save/Open Options Byte
;Args: A = Combined Options Byte
; Bits 0-3 = Device Number
; Bits 4-7 = Mode/Option
;Sets: TEMP0 = Combined Option
; TEMP1 = Device
; TEMP2 = Mode/Option
; Bit 1 = Disk Number
; Bits 1-2 = File Type
; Bit 3 = Mode (0=Read/1=Write)
;Returns: A = Mode/Option
FSOPTS: STA TEMP0 ;Save Argument
AND #$0F ;Isolate Device Number
STA TEMP1 ;and Save it
LDA TEMP0 ;Restore Argument
LSR ;Shift to Low Nybble
LSR
LSR
LSR
STA TEMP2 ;and Save it
RTS
;fsopen(chan, mode, device) - Open Channel to Device
;Requires prior call to FSNAME
;Args: A = Logical File Number
; Y = Mode: 0=Read, !0= Write
; X = Device 0=Keyboard, 1=Cassette, 2=RS232, 3=Screen
; 4-7=Printers, 8-15=Disks, 31=All Devices
;Returns: A,X = Channel Number (0=Error)
; Y = Error Number (0=None)
FSOPEN: CPX #1
BNE FSOPEY ;If Device is Cassette
CPY #0
BEQ FSOPEZ ; If Mode is Not Zero
LDY #2 ; Set Secondary Address to 2
BNE FSOPEZ ;Else
FSOPEY: TAY ; Copy LFN to Secondary Address
FSOPEZ: JSR $FFBA ;Call Kernal SETLFS Routine
JSR $FFC0 ;Call Kernal OPEN Routine
BCS FSERRV ;If Error Return A=0, Y=Error#
BCC FSOPED ;** Skip Drive Check for now; **
LDA FSDVNO ;Get Current Device Number
CMP #8 ;Check Device Number
BCC FSOPED ;If Disk Drive
JSR FSDSTS ; Get Drive Status
BCS FSERRV ; If Error Return A=0, Y=Error#
FSOPED: LDA #0 ;Set Error Code to 0
STA FSIOET ;Clear General Error Entry
LDX FSLFNO ;Get LFN
STA FSIOET,X ;Clear Error Table Entry
TAY ;Clear Error Code
TXA ;Return LFN
RTS
;fsload(chan, mode, device) - Load File from Device
;Requires: DSTLO,DSTHI = Load Address
; Prior call to FSNAME
;Args: A = Logical File Number
; Y = Mode: 0=Read, !0= Write
; X = Device 1=Cassette, 8-15=Disks
;Returns: A = Error Number (0=None)
; Y,X = Address at Last Byte Loaded
FSLOAD: JSR FSLDSV ;Set up for Load/Save
LDA TEMP3 ;Get Load/Verify Flag
FSLOAK: JSR $FFD5 ;Call Kernal LOAD Routine
BCC FSZERO ;If No Error, Return 0
RTS
;fssave(chan, mode, device) - Save File to Device
;Requires: DSTLO,DSTHI = Load Address
; Prior call to FSNAME
;Args: A = Logical File Number
; Y = Mode: 0=Read, !0= Write
; X = Device 1=Cassette, 8-15=Disks
;Returns: A = Error Number (0=None)
; Y,X = Address at Last Byte Loaded
FSSAVE: JSR FSLDSV ;Set up for Load/Save
LDA #FSSVLO ;Load Start Address Pointer
JSR $FFD8 ;Call Kernal SAVE Routine
BCC FSZERO ;If No Error, Return 0
RTS
;fsrdst() - Read I/O Status Byte
;Replaces Kernal READST Routine, fixing RS-232 bug,
;bypassing Kernal messages, and preserving Accumulator
;Affects: X
;Returns: Carry Set if Error
; Overflow Set if EOF
; Y = I/O Status
; Bit Cassette Read Serial Bus I/O Tape Load/Verify
; $01 Write Timeout
; $02 Read Timeout
; $04 Short Block Short Block
; $08 Long Block Long Block
; $10 Read Error Any Mismatch
; $20 Checksum Err Checksum Err
; $40 End of File EOI Line
; $80 End of Tape Device Not Present End of Tape
FSRDST: TAX ;Save Accumulator
CLV ;Clear Overflow Flag
LDY $BA ;Get Current Device Number
CPY #$02 ;Check Device Number
BNE FSRDSS ;If Serial Port
LDA $0297 ; Read RS-232 Status Word
LDY #0 ; then
STY $0297 ; Clear It
BEQ FSRDSX ;Else
FSRDSS: LDA FSIOST ; Load I/O Status Byte
BIT FSIOST ; EOF Bit into Overflow Flag
BEQ FSRDSX ; If Error
BVS FSRDSX ; And Not EOF
JSR FSCSTE ; Convert ST into Error
FSRDSX: LDY FSLFNO ;Get Logical File Number
STA FSIOET,Y ;Save Error in Table
BVC FSRDSY ;If EOF
AND #$BF ; Clear EOF Flag
FSRDSY: CMP #1 ;Set Carry if Error
TAY ;Copy Error Code to Y
TXA ;Restore Accumulator
RTS
;fsunch() - Find Unused Channel Number
;Affects: X,Y
;Returns: A = Channel Number
; 0=No Channel Available
FSUNCH: LDY #2 ;Start with Channel 2
FSUNCL: TYA ;Copy Channel to Accumulator`
JSR FSFLFA ;Find File Table Index
BMI FSUNCX ;If Channel Allocated
INY ; Increment Channel
CPY #15 ; If less than 15
BCC FSUNCL ; Loop
LDY #0 ; Else Return 0
FSUNCX: TYA ;Copy Channel to Set Flags
RTS
;fscdrv() - Check if Device is Disk Drive
;Uses: TEMP1 = Device Number
;Returns: A = Device Number
; 0 if Not a Disk Drive
; Y = Error Code
; 0 = None
FSCDRV: LDA TEMP1 ;Get Device Number
FSCDRA: CMP #8 ;If >=8
BCS FSRTS ; Return
;fserr7() - Return General Error 7
FSERR7: LDA #7 ;Set Error to Illegal Device Number
DC $2C ;BIT - Skip Next Instruction
;fserr2() - Return General Error 2
FSERR2: LDA #2 ;Set Error to 2
;fserrv(error) - Write General Error Entry
FSERRV: LDX #0 ;Set No Logical File Number
DC $2C ;BIT - Skip Next Instruction
;fserrw() - Write Error To Table and Return in Y
FSERRW: LDX FSLFNO ;Get Logical File Number
FSERRX: STA FSIOET,X ;Save Error To Table
FSERRY: TAY ;Move Error Code to Y
FSZERO: LDA #0 ;Return 0
FSRTS: RTS
;fload(args, &name) - Load File
;Args: A = Mode + Device #
; Y,X = Pointer to File Name
;Returns: A = Error Number (0=None)
; Y,X = Address at Last Byte Loaded
FLOAD: JSR FSOPTS ;Parse Options Argument
LDA #0 ;Set Flag to LOAD
FLOADA: STA TEMP3 ;and Save It
JSR FSNAME ;Set Filename for Open
JSR FSUNCH ;Find Unused Channel Number
BEQ FSERR2 ;If None Available, Return Error
JSR RESRXY ;Load Device, Mode into X, Y
JMP FSLOAD ;and Load File
;fsave(args, &name) - Save File
;Requires: SRCLO,SRCHI = Start Address
; DSTLO,DSTHI = End Address
;Args: A = Mode + Device #
; Y,X = Pointer to File Name
;Returns: A = Error Number (0=None)
; Y,X = Address at Last Byte Loaded
FSAVE: JSR SAVREG ;Save Arguments
JSR GETSRC ;Get Start Address
STX FSSVLO ;and Store It
STY FSSVHI
JSR RESREG ;Restore Arguments
JSR FSOPTS ;Parse Options Argument
JSR FSNAME ;Set Filename for Open
JSR FSUNCH ;Find Unused Channel Number
BEQ FSERR2 ;If None Available, Return 0
JSR RESRXY ;Load Device, Mode into X, Y
JMP FSSAVE ;and Load File
;fvrfy(args, &name) - Verify File
;Args: A = Mode + Device #
; Y,X = Pointer to File Name
;Returns: A = Error Number (0=None)
; Y,X = Address at Last Byte Loaded
FVRFY: JSR FSOPTS ;Parse Options Argument
LDA #1 ;Set Flag to VERIFY
BNE FLOADA ;Execute FLOAD Alternate Entry Point
;fopen(args, &name) - Open File
;Args: A = Mode + Device #
; Y,X = Pointer to File Name
;Returns: A = File Channel (0=File Not Opened)
; Y = File Error (0=None)
FOPEN: JSR FSOPTS ;Parse Options Argument
FOPENA: JSR FSONAM ;Set Filename for Open
JSR FSUNCH ;Find Unused Channel Number
BEQ FSERR2 ;If None Available, Return Error 2
JSR RESRXY ;Load Device, Mode into X, Y
JMP FSOPEN ;and Open File
;fsccmd() - Close Command Channel
;Args: A = Device Number
;Returns: A = Logical File Number
FSCCMD: ORA #$10 ;Set LFN to Device# + 16
;fclose(chan) - Close File
;Args: A = Channel Number (0=Close All)
FCLOSE: ORA #0 ;Check File Number
BEQ FCLOSS ;If Not 0
JMP $FFC3 ; Execute Kernal Routine CLOSE
FCLOSS: JMP $FFE7 ;Else Execute Kernal Routine CLALL
;feof(lfn) - Check for End of File
;Args: A = Logical file number
;Affects: A,X
;Returns: A = $FF If End of File
; $00 Otherwise
FEOF: JSR FERROR ;Get Error Code
AND #$40 ;Mask off EOF Bit
BEQ FEOFX ;If Not 0
FSTRUE: LDA #$FF ; Return TRUE
FEOFX: RTS ;Return from Subroutine
;ferror(lfn) - Get Error on Channel`
;Args: A = Channel Number (0=None)
;Returns: A = Error Code
; 1 = Terminated by the STOP key
; 2 = Too many open files
; 3 = File Not Open
; 4 = File not found
; 5 = Device not present
; 6 = Not an input file
; 7 = Not an output file
; 8 = File name is missing
; 9 = Illegal device number
FERROR: TAX ;Copy LFN to X
LDA FSIOET,X ;Load I/O Status for LFN
RTS
;fflush() - Flush file buffer
;Args: A = Logical File Number
FFLUSH: RTS ;No Logic Needed
;fgetc(lfn) - Read character from file
;Args: A = Logical file number
;Affects: X
;Returns: A = Character
; Y = Error Code (0=None)
FGETC: TAX ;Move logical file number to X register
JSR $FFC6 ;Call Kernal Routine CHKIN
FGETCW: BCS FSERRW ;If Error, Write to Table and Return in Y
JSR $FFCF ;Call Kernal Routine CHRIN
TAY ;Save Character
FGETCC: JSR $FFCC ;Call Kernal Routine CLRCHN
TYA ;Restore Character
JSR FSRDST ;Read Status Byte
BVS FSORA0 ;If Not EOF
BCS FSZERO ;and Error, Return NUL
FSORA0: ORA #0 ;Else Set Flags Based on Character
RTS
;fsrcmd() - Read Command Channel
FSRCMD: LDA #15 ;Set LFN to 15
JSR FSGBFR ;Get Buffer Address
;fgets(lfn, &s) - Read string from file
;Args: A = Logical file number
; Y,X = Pointer to String
;Affects: X
;Returns: A = Number of bytes read
; Y = Error Code
FGETS: JSR SETDST ;Save string address
TAX ;Move logical file number to X register
JSR $FFC6 ;Call Kernal Routine CHKIN
BCS FGETCW ;If Error, Write to Table and Return in Y
LDY #0 ;Initialize Index
FGETSL: STY TEMP3 ;and Save It
JSR $FFCF ;Call Kernal Routine CHRIN
LDY TEMP3 ;Restore Index
CMP #$0D ;If Not C/R (Real or from Error)
BEQ FGETSX
STA (DSTLO),Y ;Store Character in String
INY ;Increment Pointer
BPL FGETSL ;and Loop if Less Than 128
FGETSX: LDA #0 ;Store NUL Terminator
STA (DSTLO),Y ;at End of String
JSR $FFCC ;Call Kernal Routine CLRCHN
TYA ;Copy Length of String to Acuumulator
JSR FSRDST ;Get I/O Status in Y Register
ORA #0 ;Set Flags based on Accumulator
FGETSR: RTS
;fread(lfn, count) - Read bytes from file
;Requires: DSTLO, DSTHI - Pointer to destination string
;Args: A = Logical file number
; Y = Number of Bytes to Read
;Sets: TEMP1 = Number of Bytes to Read
; TEMP2 = 0 (Read Mode)
; TEMP3 = Number of Bytes Read
;Affects: X
;Returns: A = Number of bytes read
; Y = Error Code (0=None)
; Carry Set if Error, Clear if None
FREAD: LDX #0 ;Mode = READ
FREADA: STX TEMP2 ;Save Mode
STY TEMP1 ;Save Number of Bytes
TAX ;Move logical file number to X register
JSR $FFC6 ;Call Kernal Routine CHKIN
FREADE: BCS FGETCW ;If Error, Write to Table and Return in Y
LDY #0 ;Initialize Index
STY TEMP3 ;and Save It
FREADL: JSR $FFCF ;Call Kernal Routine CHRIN
JSR FSRDST ;Get I/O Status in Y Register
BCS FREADX ;If No Error
LDY TEMP3 ; Retrieve Index
LDX TEMP2 ; Get Mode
BNE FREADN ; If READ
STA (DSTLO),Y ; Store Character in String
FREADN: INY ; Increment Pointer
STY TEMP3 ; and Save It
BVS FREADS ; If Not EOF
CPY TEMP1 ; Compare against Count
BNE FREADL ; and Loop if Less
FREADS: LDY #0 ; Set Error to None
FREADX: JSR $FFCC ;Call Kernal Routine CLRCHN
CLC ;Clear Carry
TYA ;Copy Error Code to Accumulator
ADC #$FF ;Set Carry if Error
LDA TEMP3 ;Return Length of String
RTS
;fputc(lfn, chr) - Write character from file
;Args: A = Logical file number
; Y = Character to Write
;Returns: A = Character (0 if Error)
; Y = Error Code (0=None)
FPUTC: TAX ;Move LFN to X register
JSR $FFC9 ;Call Kernal Routine CHKOUT
BCS FREADE ;If Error, Write to Table and Return in Y
TYA ;Copy Character to Accumulator
FPUTCO: JSR $FFD2 ;Call Kernal Routine CHROUT
JMP FGETCC ;Clear Channel and Check STATUS
;fputln(lfn, &s) - Write Line to File
;Args: A = Logical file number
; Y,X = Pointer to String
;Sets: SRCLO,SRCHI = Pointer to String
;Affects: X,Y
;Returns: A = Number of bytes written
; Y = Error Code (0=None)
FPUTLN: ORA #$80 ;Set High Bit and Fall Through
;fputs(lfn, &s) - Write String to File
;Args: A = Logical file number
; Y,X = Pointer to String
;Sets: SRCLO,SRCHI = Pointer to String
;Affects: X,Y
;Returns: A = Number of bytes written
; Y = Error Code (0=None)
FPUTS: JSR SETSRC ;Save string address & initialize pointer
FPUTSA: STA TEMP2 ;Save LFN Argument
AND #$7F ;Strip High Bit
TAX ;Copy LFN to X Register
JSR $FFC9 ;Call Kernal Routine CHKOUT
BCS FREADE ;If Error, Write to Table and Return in Y
LDY #0 ;Initialize Index
STY TEMP3 ;and Save It
FPUTSL: LDA (SRCLO),Y ;Load next character
BEQ FPUTSX ;If NUL, Finish Up
JSR $FFD2 ;Call Kernal Routine CHROUT
STY TEMP3 ;Save Index
JSR FSRDST ;Read I/O Status
BCS FREADX ;If Error, Return in Y
LDY TEMP3 ;Restore Index
INY ;Increment Index
BPL FPUTSL ;Loop if Less than 128
BMI FREADS ;Else Finish Up
FPUTSX: LDA TEMP2 ;Retrieve LFN Argument
BPL FREADS ;Finish Up if High Bit Not Set
INY ;Else Increment Count
LDA #$0D ;Load Carriage Return
BNE FPUTCO ;and Write It
FSKIP: LDX #$FF ;Set Mode to Skip
BNE FREADA ;and Execute FREAD
;fwrite(lfn, count) - Write bytes from file
;Requires: SRCLO, SRCHI - Pointer to destination string
;Args: A = Logical File Number
; Y = Number of Bytes to Write
;Affects: X
;Returns: A = Number of bytes read
; Y = Error Code (0=None)
FWRITE: STY TEMP1 ;Save Number of Bytes
TAX ;Move logical file number to X register
JSR $FFC9 ;Call Kernal Routine CHKOUT
BCS FREADE ;If Error, Return in Y (FSERRY)
LDY #0 ;Initialize Index
STY TEMP3 ;and Save It
FWRITL: LDA (SRCLO),Y ;Load next character
JSR $FFD2 ;Call Kernal Routine CHROUT
JSR FSRDST ;Read I/O Status
BCS FREADX ;If Error, Return In Y
INC TEMP3 ;Increment Index
LDY TEMP3 ;and Load it Index
CPY TEMP1 ;Compare against Count
BNE FWRITL ;and Loop if Less
BEQ FREADS ;Else Return No Error
;fgetw(lfn) - Read Word from File
;Args: A = Logical file number
;Sets: TEMP0 = Logical File Number
; TEMP1 = LSB
; TEMP2 = MSB
;Returns: A = Error Code (0=None)
; Y,X = Word (MSB, LSB)
FGETW: STA TEMP0 ;Save LFN
FGETWA: LDA TEMP0 ;Load LFN (Alternate Entry Point)
JSR FGETC ;Read LSB
BCS FGETWX ;If No Error
STA TEMP1 ; Save in TEMP1
LDA TEMP1 ; Restore LFN
JSR FGETC ; Read MSB
STA TEMP2 ; Save in TEMP2
FGETWX: TYA ;Copy Error to A
JSR RESRXY ;Load Word into Y,X
ORA #0 ;Set Flags
RTS

186
include/cbm/fileio.h02 Normal file
View File

@ -0,0 +1,186 @@
/***************************************
* file - Standard File Functions for *
* all Commodore 8 bit machines *
***************************************/
/* Device IDs */
enum {KEYBRD, CASST1, MODEM1, SCREEN,
PRNTR1, PRNTR2, PRNTR3, PRNTR4,
DRIVE1, DRIVE2, DRIVE3, DRIVE4,
DRIVE5, DRIVE6, DRIVE7, DRIVE8};
#define MWRITE $80 //Open File for Write
#define MREAD $00 //Open File for Read
#define MRELCT $00 //Relocate (Load at Specified Address)
#define MABSLT $80 //Absolute (Load at Address in File Header)
/* RS-232 Errors */
/* Other Errors */
#define ERRFNA $FF //Error - Function Not Available
/* Zero Page System Variables *
* for diagnostic purposes *
* Names subject to change */
char fsiost; //Kernal I/O Status Word
char fsnofl; //Number of Open I/O Files
char fslfno; //Current Logical File Number
char fsdvno; //Current Device Number
char fssadr; //Current Secondary Address
char fsfnlo,fsfnhi; //Pointer: Current Filename
char fsfnln; //Length of Current Filename
char fsrcvb; //Serial Bus Received Byte
/* System Variables */
char fsbufr[]; //String Concatenation Buffer
char fscntr; //Directory Entry Count
/* File Load *
* Loads File into Memory *
* Args: md - Mode | DriveID *
^ &n - Filename *
* Returns: Error Code (0=None) *
* Load Address */
char fload();
/* File Save *
* Save File from Memory *
* Args: md - Mode | driveid *
^ &n - Filename *
* Returns: Error Code (0=None) */
char fsave();
/* File Open *
* Opens File Specified by Name *
* Args: m - mode | driveid *
* &f - string containing filename *
* Returns: file pointer if successful *
0 if an error occurs */
char fopen();
/* File Close *
* Closes File Opened to File Pointer *
* Args: fp - file pointer */
char fclose();
/* End of File *
* Check for End of File Condition *
* Args: fp - file pointer *
* Returns: EOF Indicator *
* (0 if not at end of file *
* 255 if not implemented *
or non-zero EOF value) */
char feof();
/* File Error *
* Check File Error Indicator *
* Args: fp - file pointer *
* &s - string for error text *
* Returns: platform specific error number *
* (0 if no error *
* 255 if not implemented) */
char ferror();
/* Flush File Buffer *
* Flush File Output Buffer *
* Args: fp - file pointer *
* Returns: platform specific error number *
* (0 if no error) */
char fflush();
/* Read Character from File *
* Args: fp - file pointer *
* Returns: ASCII value of character, *
* platform specific error number *
* (0 if no error *
* 255 if not implemented) */
char fgetc();
/* Load to Memory from File *
* Args: md - mode + device# *
* &f - string containing filename *
* Requires: setdst(); *
* Returns: platform specific error *
* (0 if no error *
* 255 if not implemented) *
* end address of load */
char fload();
/* Write Character to File *
* Args: fp - file pointer *
* c - ASCII character to write *
* Returns: platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fputc();
/* Read String from File *
* Buffers up to 128 characters *
* until C/R is pressed *
* Args: fp - file pointer *
* &s - string read from file *
* Returns: number of characters read, *
* platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fgets();
/* Write String to File *
* Writes up to 128 characters of a *
* null terminated string *
* Args: fp - file pointer *
* &s - string to print from *
* Returns: platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fputs();
/* Write Line to File *
* Write String to File followed by C/R *
* Args: fp - file pointer *
* &s - string to print from *
* Returns: ending position in string *
* 255 if error during write */
char fputln();
/* Read Bytes from File *
* Reads until EOF is reached *
* Args: fp - file pointer *
* n - number of bytes to read *
* Requires: setdst(); *
* Returns: number of bytes read, *
* platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fread();
/* Save Memory to File *
* Args: d - device# *
* &f - string containing filename *
* Requires: setsrc(); setdst(); *
* Returns: platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fload();
/* Verify File against Memory *
* Args: md - mode + device# *
* &f - string containing filename *
* Requires: setdst(); *
* Returns: platform specific error *
* (0 if no error *
* 255 if not implemented) *
* end address of verify */
char fload();
/* Write Bytes to File *
* Args: fp - file pointer *
* n - number of bytes to write *
* Requires: setdst(); *
* Returns: number of bytes written, *
* platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fwrite();

205
include/cbm/filesys.a02 Normal file
View File

@ -0,0 +1,205 @@
; C02 filesys.h02 assembly language subroutines
; for all Commodore 8 bit machines
; Requires external functions ADDDST, FOPENA, FREAD, FSKIP,
; FSBCMD, FSCBFR, FSCDRA, FSGBFR, FSOPTS, and SETSRC
; external zero page locations BFRHI, BFRLO, DSTHI, DSTLO,
; SRCHI, and SRCLO
; and external locations FSCNTR, FSDVNO, FSLFNO, and TEMP0
;String Constants
FSDIRP DC "$0:",0 ;Disk Directory Prefix
;opndir() - Open Directory for Reading
;Args: A = Drive/Options
; Y,X = Pointer to Directory Name
;Uses: BFRHI,BFRLO = Pointer to Work Buffer
;Sets: SRCHI,SRCLO = Pointer to Directory Name
;Returns: A = File Pointer
; 0 - Error
OPNDIR: JSR SETSRC ;Save Directory Pointer
STY FSCNTR ;Set File Count to 0
JSR FSOPTS ;Parse Options Byte
JSR FSCDRV ;If Device is Not Disk Drive
BEQ CLSDIX ; Return Error
LDA #36 ;Set Command to "$"
JSR FSBCMD ;and Build Command String
SEC ;Set Flag to Concatenate
JSR FSCBFR ;Concatenate Directory Name to Buffer
JSR FSGBFR ;Get String Buffer Address
JMP FOPENA ;Execute File Open (Alternate Entry Point)
;clsdir() - Close Directory File
;Args: A = Directory File Pointer
;Returns: A = Error Code
; 0 - Success
CLSDIR: ORA #0 ;Check File Pointer
BEQ CLSDIX ;If Not Zero
JMP FCLOSE ;Close File Channel
CLSDIX: RTS
;rdhdr() - Read Directory Header
;Note: Call once before first rddir()
;Args: A = Directory File Pointer
; Y,X = Pointer to HDRENT buffer
;Sets: DSTHI,DSTLO = Pointer to HDRENT buffer
;Returns: A = Disk Type
; Y = Error Code (0=None)
RDHDR: JSR SETDST ;Set Destination Address
LDY #2 ;Set Record Length
JSR FREAD ;and Read Record
BCS RDHDRZ ;If Error, Exit
STY TEMP0 ;Set Skipped Bytes to 0
LDA (DSTLO),Y ;Get Disk Version
PHA ;and Save It
CMP #$43 ;If 8050/8250
LDY #2 ;Skip Unused bytes
BNE RDHDRC
CMP #$41 ;If 4040/1541/1571
BNE RDHDRD ; Skip BAM
LDA FSLFNO ; Get Channel
LDY #140 ; Set Record Length
RDHDRC: STY TEMP0 ; Save Number of Skipped Bytes
JSR FSKIP ; and Skip Bytes
BCS RDHDRX ; If Error, Exit
RDHDRD: LDA #2 ;Add 2 Bytes
JSR ADDDST ;to Destination Address
LDA FSLFNO ;Get Channel
LDY #24 ;Set Record Length
JSR FREAD ;and Read Record
BCS RDHDRX ;If Error, Exit
LDA #228 ;Set Padding Bytes
SEC
SBC TEMP0 ;Subtract Bytes Skipped
TAY ;Set as Record Length
LDA FSLFNO ;Get Channel
JSR FSKIP ;and Skip Bytes
LDY #23 ;Set Index to 24
RDHDRN: LDA (DSTLO),Y ;Load Byte
CMP #$A0 ;If Shifted Space
BNE RDHDRS
LDA #0 ;Change to 0
STA (DSTLO),Y
RDHDRS: DEY ;Decrement Index
BPL RDHDRN ;and Loop if Not Negative
INY ;Set Error Code to 0
RDHDRX: PLA ;Retrieve Disk Type
RDHDRZ: RTS
;rddir() - Read Directory Entry
;Args: A = Directory File Pointer
; Y,X = Pointer to DIRENT buffer
;Uses: BFRHI,BFRLO = Pointer to Work Buffer
;Sets: DSTHI,DSTLO = Pointer to DIRENT buffer
;Returns: A = File Type (0=Null Entry)
; Y = Error Code (0=None)
RDDIR: JSR SETDST ;Set Destination Address
TAX ;Save LFN
LDY #32 ;Set Record Length
INC FSCNTR ;Increment File Count
LDA FSCNTR ;Load It
AND #$07 ;Modulo 8
BNE RDDIRB ;If 0
LDY #30 ; Change Record Length
RDDIRB: TXA ;Restore LFN
JSR FREAD ;and Read Record
RDDIRC: LDA #0 ;Initialize Return Value
BCS RDDIRX ;If Error, Exit
LDA (DSTLO),Y ;Get File Type
PHA ;and Save it
LDA #3 ;Add 3 Bytes
JSR ADDDST ;to Destination Address
LDY #15 ;Set Index to 15
RDDIRN: LDA (DSTLO),Y ;Load Byte
CMP #$A0 ;If Shifted Space
BNE RDDIRS
LDA #0 ;Change to 0
STA (DSTLO),Y
RDDIRS: DEY ;Decrement Index
BPL RDDIRN ;and Loop if Not Negative
INY ;Set Error Code to 0
PLA ;Restore File Type
RDDIRX: RTS
;setdrv() - Set Current Drive
;Args: A = Drive Identifier
;Returns: A = Drive Identifier
; 0 - None/Error
SETDRV: JSR FSCDRA ;Check Device Number
BCS SETDRX ;If Disk Drive
STA FSDVNO ; Write to Device#
SETDRX: RTS
;getdrv() - Get Current Drive
;Returns: A = Drive Identifier
; 0 - None/Error
GETDRV: LDA FSDVNO ;Load Current Device#
JMP FSCDRA ;Check if Disk Drive
;setdir() - Set Current Directory
;Args: A = Drive Identifier
; Y,X = Pointer to Directory Name
;Uses: BFRHI,BFRLO = Pointer to Work Buffer
;Sets: SRCHI,SRCLO = Pointer to Directory Name
;Returns: A = Error Code
; $00 - Successful
; $FF - Inapplicable
SETDIR: JSR SETSRC ;Save Pointer
JSR FSOPTS ;Parse Drive Argument
JSR FSGBFR ;Get String Buffer Address
;command is "/0:Directory"
;assuming 0 is disk number
;of course this is switched from normal command syntax
RTS
;getdir() - Get Current Directory
;Args: A = Drive Identifier
; Y,X = Pointer to String
;Uses: BFRHI,BFRLO = Pointer to Work Buffer
;Sets: DSTHI,DSTLO = Pointer to String
;Returns: A - Length of Directory Name
; $00 - Root
; $FF - Inapplicable
GETDIR: ;Return Inapplicable (fall through)
;mkdir() - Create Directory
;Args: A = Drive Identifier
; Y,X = Pointer to Directory Name
;Uses: BFRHI,BFRLO = Pointer to Work Buffer
;Sets: SRCHI,SRCLO = Pointer to Directory Name
;Returns: A = Error Code
; $00 - Successful
; $FF - Inapplicable
MKDIR: ;Return Inapplicable (fall through)
;rmdir() - Remove Directory
;Args: A = Drive Identifier
; Y,X = Pointer to Directory Name
;Uses: BFRHI,BFRLO = Pointer to Work Buffer
;Sets: SRCHI,SRCLO = Pointer to Directory Name
;Returns: A = Error Code
; $00 - Successful
; $FF - Inapplicable
RMDIR: ;Return Inapplicable (fall through)
;remove() - Delete File
;Args: A = Drive Identifier
; Y,X = Pointer to File Name
;Uses: BFRHI,BFRLO = Pointer to Work Buffer
;Sets: SRCHI,SRCLO = Pointer to File Name
;Returns: A = Error Code
; $00 - Successful
; $FF - Inapplicable
REMOVE: ;Return Inapplicable (fall through)
;rename() - Rename File
;Args: A = Drive Identifier
; Y,X = Pointer to Destination File Name
;Uses: SRCHI,SRCLO = Pointer to Source File Name
; BFRHI,BFRLO = Pointer to Work Buffer
;Sets: DSTHI,DSTLO = Pointer to Destination File Name
;Returns: A = Error Code
; $00 - Successful
; $FF - Inapplicable
RENAME: LDA #$FF ;Return Inapplicable
RTS

56
include/cbm/filesys.h02 Normal file
View File

@ -0,0 +1,56 @@
/***************************************
* filesys - File System functions for *
* all Commodore 8 bit machines *
**************************************/
struct dirblk {char track; char sector;};
struct dirdts {char year; char month; char day; char hour; char minute; };
struct dirent {
char filtyp;
struct dirblk datblk;
char filnam[15];
struct dirblk relblk;
char recsiz;
char exttyp;
struct dirdts tstamp;
char sizelo;
char sizehi;
char unused[1];
};
struct dirhdr {
char dskver;
char dblsid;
char dsknam[17];
char diskid[2];
char dosver[2];
};
/* Open Directory for Reading *
* Args: drv - Drive Identifier *
* &dir - Directory Name *
* Returns: Directory Channel *
* (0 if Error) */
char opndir();
/* Read Disk/Directory Header *
* Args: dc - Directory Channel *
* &de - dirhdr Struct *
* Returns: Length of Header *
* (0 if N/A or Error) */
char rdhdr();
/* Read Directory Entry *
* Args: dc - Directory Channel *
* &de - dirent Struct *
* Returns: Length of Entry *
* (0 at End or Error) */
char rddir();
/* Close Directory Channel *
* Args: dc - Directory Channel *
* Returns: Error Code *
* $00 = Successful) */
char clsdir();

140
include/fileio.a02 Normal file
View File

@ -0,0 +1,140 @@
;C02 Module file.h02 Assembly Lamnguage
;Template Code
;Sample Device Numbers
CASST1 EQU 0
MODEM1 EQU 2
PRNTR1 EQU 3
PRNTR2 EQU 4
DRIVE1 EQU 5
DRIVE2 EQU 6
DRIVE3 EQU 7
DRIVE4 EQU 8
;Disk Numbers (Within Drive)
DISK0 EQU $00
DISK1 EQU $40
;File Open Modes
MWRITE EQU $80
MREAD EQU $00
;fflush(chan) - Flush Write Buffer to File
;Args: A = Mode + Drive ID
;Returns: A = File Channel (0=File Not Opened)
FFLUSH: ;Return Success (fall through)
;fopen(args, &name) - Open File
;Args: A = Mode + Drive ID
; Y,X = Pointer to File Name
;Returns: A = File Channel (0=File Not Opened)
FOPEN: LDA $00 ;Return File Not Opened (fall through)
;fclose(chan) - Close File
;Args: A = Channel Number
FCLOSE: RTS ;No Action
;fgetc(chan) - Read Character from File
;Args: A = Channel Number
;Returns: A = Character
; Y = Error Code
; $00 - Success
; $FF - Not Implemented
FGETC: ;Return Error - Not Implemented (fall through)
;fgets(chan, &s) - Read String from File
;Args: A = Channel Number
; Y,X = Pointer to String Array
;Returns: A = Number of Bytes Read
; Y = Error Code
; $00 - Success
; $FF - Not Implemented
FGETS: ;Return Error - Not Implemented (fall through)
;fread(chan, count) - Read Bytes from File
;Args: A = Channel Number
; Y = Number of Bytes to Read
;Uses: DSTLO,DSTHI - Pointer Destination Array
;Returns: A = Number of Bytes Read
; Y = Error Code
; $00 - Success
; $FF - Not Implemented
FREAD: ;Return Error - Not Implemented (fall through)
;fwrite(chan, count) - Write Bytes to File
;Args: A = Channel Number
; Y = Number of Bytes to Write
;Uses: DSTLO,DSTHI - Pointer to Source Array
;Returns: A = Number of Bytes Written
; Y = Error Code
; $00 - Success
; $FF - Not Implemented
FWRITE: LDA $00 ;Return 0 Bytes Read/Written
LDY $FF ;and Error - Not Implemented
RTS
;feof(chan) - Check for End of File
;Args: A = Channel Number
;Returns: A = Platform Specific EOF Value
; $00 - Not End of File
; $FF - Not Implemented
FEOF: ;Return Error - Not Implemented (fall through)
;ferror(chan) - Check for Error
;Args: A = Channel Number
;Returns: A = Error Code
; $00 - Success
; $FF - Not Implemented
FERROR: ;Return Error - Not Implemented (fall through)
;fputc(chan, char) - Write Character to File
;Args: A = Channel Number
; Y = Character to Write
;Returns: A = Error Code
; $00 - Success
; $FF - Not Implemented
FPUTC: ;Return Error - Not Implemented (fall through)
;fputs(chan, &s) - Write String from File
;Args: A = Channel Number
; Y,X = Pointer to String Array
;Returns: A = Error Code
; $00 - Success
; $FF - Not Implemented
FPUTS: ;Return Error - Not Implemented (fall through)
;fload(name) - Load File into Memory
;Args: A = Option + DriveID
; Y,X = Pointer to File Name
;Uses: SRCLO,SRCHI = Start Address
; DSTLO,DSTHI = End Address
;Returns: A = Error Code
; $00 - Success
; $FF - Not Implemented
; X,Y = Load Address
FLOAD: ;Return Error - Not Implemented (fall through)
;fsave(name) - Save File from Memory
;Args: A = Option + DriveID
;Args: Y,X = Pointer to File Name
;Uses: SRCLO,SRCHI = Start Address
; DSTLO,DSTHI = End Address
;Returns: A = Error Code
; $00 - Success
; $FF - Not Implemented
FSAVE: LDA $FF ;Return Error - Not Implemented
RTS
;Internal routines are all prefixed with FS
;fsetup() - Set Parameters for File Open
;Platform Specific
;fsinit() - Initialize Control Block
;For platforms that use File or Parameter Control Blocks
;fname(&name) - Set File Name
;If a seperate OS Call to set the File Name
;or a terminator other than NUL is required

View File

@ -2,96 +2,107 @@
* file - Standard File Functions for C02 *
******************************************/
/* File Setup - System Specific *
* Args: system dependent *
* Returns: system dependent */
char fsetup();
/* Device List */
enum {CASST1, MODEM1, PRNTR1, PRNTR2,
DRIVE1, DRIVE2, DRIVE3, DRIVE4};
/* Set File Name - System Specific *
* Args: system dependent *
* Returns: system dependent */
char fsname();
/* File Open Modes */
#define MWRITE $80 //Open File for Write
#define MREAD $00 //Open File for Read
/* Load File - System Specific *
* Args: system dependent *
* Returns: system dependent */
char fsload();
/* File Load Modes */
#define MRELCT $00 //Relocate (Load at Specified Address)
#define MABSLT $80 //Absolute (Load at Address in File Header)
/* Save File - System Specific *
* Args: system dependent *
* Returns: system dependent */
char fssave();
/* Open File - System Specific *
* Args: system dependent *
* Returns: system dependent */
char fsopen();
/* File Load *
* Loads File into Memory *
* Args: d - Options | DeviceID *
^ &n - Filename *
* Returns: Error Code (0=None) *
* Load Address */
char fload();
/* Open File *
* Opens File Specified by Name *
* Args: m - mode *
* &f - string containing filename *
* Returns: file pointer if successful *
0 if an error occurs */
/* File Save *
* Save File from Memory *
* Args: d - Options | DeviceID *
^ &n - Filename *
* Returns: Error Code (0=None) */
char fsave();
/* File Open *
* Opens File Specified by Name *
* Args: d - Options | DeviceID *
^ &n - Filename *
* Returns: File Pointer (0=Error) *
Error Code (0=None) */
char fopen();
/* Close File *
/* File Close *
* Closes File Opened to File Pointer *
* Args: fp - file pointer *
* Returns: 0 if successful *
255 if an error occurred */
* Args: fp - file pointer */
char fclose();
/* End of File *
* Check for End of File Condition *
* Args: fp - file pointer *
* Returns: 0 if not at end of file *
255 if end of file reached */
/* End of File *
* Check for End of File Condition *
* Args: fp - file pointer *
* Returns: EOF Indicator *
* (0 if not at end of file *
* 255 if not implemented *
* or non-zero EOF value) */
char feof();
/* File Error *
* Check File Error Indicator *
* Args: fp - file pointer *
* Returns: system dependent error number *
0 if no error */
/* File Error *
* Check File Error Indicator *
* Args: fp - file pointer *
* &s - string for error text *
* Returns: platform specific error number *
* (0 if no error *
* 255 if not implemented) */
char ferror();
/* Flush File Buffer *
* Flush File Output Buffer *
* Args: fp - file pointer *
* Returns: system dependent error number *
0 if no error */
/* Flush File Buffer *
* Flush File Output Buffer *
* Args: fp - file pointer *
* Returns: platform specific error number *
* (0 if no error) */
char fflush();
/* Read Character from File *
* Args: fp - file pointer *
* Returns: ASCII value of character *
* system dependent garbage *
character if past end of file */
/* Read Character from File *
* Args: fp - file pointer *
* Returns: ASCII value of character, *
* platform specific error number *
* (0 if no error *
* 255 if not implemented) */
char fgetc();
/* Write Character to File *
* Args: fp - file pointer *
* c - ASCII character to write *
* Returns: ASCII value of character */
/* Write Character to File *
* Args: fp - file pointer *
* c - ASCII character to write *
* Returns: platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fputc();
/* Read String from File *
* Buffers up to 128 characters *
* until C/R is pressed *
* Args: fp - file pointer *
* &s - string read from file *
* Returns: length of string *
* 255 if error during write */
/* Read String from File *
* Buffers up to 128 characters *
* until C/R is pressed *
* Args: fp - file pointer *
* &s - string read from file *
* Returns: number of characters read, *
* platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fgets();
/* Write String to File *
* Writes up to 128 characters of a *
* null terminated string *
* Args: fp - file pointer *
* &s - string to print from *
* Returns: ending position in string *
* 255 if error during write */
/* Write String to File *
* Writes up to 128 characters of a *
* null terminated string *
* Args: fp - file pointer *
* &s - string to print from *
* Returns: platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fputs();
/* Write Line to File *
@ -102,19 +113,21 @@ char fputs();
* 255 if error during write */
char fputln();
/* Sets Array for fread() and fwrite() *
* Args: &s - Destination string */
void fsdst();
/* Read Bytes from File *
* Reads until EOF is reached *
* Args: fp - file pointer *
* n - number of bytes to read *
* Returns: number of bytes read */
/* Read Bytes from File *
* Reads until EOF is reached *
* Args: fp - file pointer *
* n - number of bytes to read *
* Returns: number of bytes read, *
* platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fread();
/* Write Bytes to File *
* Args: fp - file pointer *
* n - number of bytes to write *
* Returns: number of bytes written */
/* Write Bytes to File *
* Args: fp - file pointer *
* n - number of bytes to write *
* Returns: number of bytes written, *
* platform specific error *
* (0 if no error *
* 255 if not implemented) */
char fwrite();

View File

@ -44,6 +44,9 @@ STKSHI EQU $03FD ;Stack Start MSB [Unused Byte]
STKELO EQU $03FE ;Stack End LSB [Unused Byte]
STKEHI EQU $03FF ;Stack End MSB [Unused Byte]
;ROM Routines
FSFLFA EQU $F3D4 ;Find Logical File A
START: TSX ;Get Stack Pointer
STX STKSAV ;and Save for Exit
JMP MAIN ;Execute Program