mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-10-31 10:14:09 +00:00
290 lines
11 KiB
Plaintext
290 lines
11 KiB
Plaintext
|
; Requires external routines SETSRC and SETDST
|
||
|
; Requires the following RAM locations be defined
|
||
|
; external zero page byte pairs SRCLO,SRCHI and DSTLO,DSTHI
|
||
|
; and external bytes TEMP0, TEMP1, TEMP2, and TEMP3
|
||
|
; as well as constant FOMAX and a table of FOMAX+1
|
||
|
; consecutive bytes named FTBL
|
||
|
|
||
|
;finit() - Initialize File System
|
||
|
FSINIT: LDA #$40 ;Control Messages Only
|
||
|
JSR SETMSG ;Kernal - Set System Messages
|
||
|
JMP FSHUT ;Close All Files
|
||
|
|
||
|
LDA #15 ;OPEN 15,8,15,"I"
|
||
|
LDX #8
|
||
|
TAY
|
||
|
JMP SETLFS
|
||
|
LDA 1
|
||
|
LDY #>FSINII
|
||
|
LDX #<FSINII
|
||
|
JMP OPEN
|
||
|
FSINII: DC "I"
|
||
|
|
||
|
;fshut() - Shut Down File System
|
||
|
FSHUT: LDA #0 ;Clear File Table
|
||
|
LDX #FOMAX
|
||
|
FSHUTL: STA FTBL,X
|
||
|
DEX
|
||
|
BPL FSHUTL
|
||
|
JMP CLALL ;Kernal - Close All Files
|
||
|
|
||
|
;fsptr(fn) - Generate File Pointer
|
||
|
;Returns: A,X = An Unused File Pointer (Logical File Number)
|
||
|
; 0 if None Available
|
||
|
FSPTR: LDX #FOMAX ;Start at Top of Table
|
||
|
FSPTRL: LDA FTBL,X ;Check File Table Entry
|
||
|
BEQ FSPTRX ;If Not 0
|
||
|
DEX ; Decrement Index and
|
||
|
BNE FSPTRL ; Loop if Greater Than 0
|
||
|
FSPTRX: TXA ;Move Channel# to Accumulator
|
||
|
RTS ;and Return
|
||
|
|
||
|
;fschk(fn) - Check File Pointer
|
||
|
;Args: A = File Pointer (Logical File Number)
|
||
|
;Sets: TEMP0 = Logical File Number
|
||
|
;Returns: A = 0 if File Pointer is Valid
|
||
|
; 255 if File Pointer is Invalid
|
||
|
; X = Logical file number
|
||
|
FSCHK: STA TEMP0 ;Save Logical File Number
|
||
|
TAX ;Transfer LFN to X register
|
||
|
BEQ FERR ;If LFN is 0, Return ERROR
|
||
|
JSR FSTCK ;Get File Table Entry
|
||
|
BNE FZERO ;If Populated, Return 0
|
||
|
BEQ FERR ;Else Return ERROR
|
||
|
|
||
|
;fstat(fn) - Get Status of Channel
|
||
|
;Args: A = File Pointer (Logical File Number)
|
||
|
;Returns: A = Result of Last READST if Argument is 0
|
||
|
; Contents of File Table Entry
|
||
|
; 255 if File Pointer is Greater Than FOMAX
|
||
|
; X = Logical file number
|
||
|
FSTAT: TAX ;Transfer Logical File Number to X Register
|
||
|
FSTCK: CLC ;If LFN
|
||
|
SBC #FOMAX ; is Greater Than FOMAX
|
||
|
BCS FERR ; Return ERROR
|
||
|
LDA FTBL,X ;Load File Table Entry
|
||
|
RTS ;And Return It
|
||
|
|
||
|
;fopen(dn, &s) - Open File with Specified Name
|
||
|
;Args: A = Device Number
|
||
|
; Y,X = Pointer to File Name
|
||
|
;Sets: TEMP0 = Logical File Number
|
||
|
; TEMP1 = Device Number
|
||
|
; TEMP4 = Length of File Name
|
||
|
;Returns: A = Logical file number
|
||
|
FOPEN: STA TEMP1 ;Save Device Number
|
||
|
JSR STRLEN ;Get File Name Length
|
||
|
STA TEMP3 ;and Save It
|
||
|
JSR FSPTR ;Find Unused Channel
|
||
|
BEQ FRTS ;If None Found - Return 0
|
||
|
STA TEMP0 ;Save Logical File Number
|
||
|
LDX TEMP1 ;Load Device Number
|
||
|
LDY TEMP0 ;Set Secondary Address tp
|
||
|
INY ; Logical File Number+1
|
||
|
JSR SETLFS ;Set Up Logical File
|
||
|
LDA TEMP3 ;Load File Name Length
|
||
|
JSR GETSRC ;Kernal - Load File Name Pointer
|
||
|
JSR SETNAM ;Kernal - Set File Name
|
||
|
JSR OPEN ;Open File
|
||
|
JSR READST ;Kernal - Read Status Word
|
||
|
STA FTBL ;Save in File Table Entry 0
|
||
|
BNE FZERO ;If No Errors
|
||
|
LDX TEMP0 ; Load Logical File Number
|
||
|
LDA TEMP1 ; Load Device Number
|
||
|
STA FTBL,X ; Store in Table Entry
|
||
|
TXA ; Return Logical File Number
|
||
|
RTS
|
||
|
FZERO: LDA #0 ;Return 0
|
||
|
RTS
|
||
|
|
||
|
;fclose(fn) - Close File
|
||
|
;Args: A = File Pointer (Logical File Number)
|
||
|
;Returns: A = 0,240 (see FSTAT)
|
||
|
FCLOSE: JSR FSCHK ;Save and Check Logical File Number
|
||
|
BNE FRTS ;If Invalid, then Return
|
||
|
JSR CLOSE ;Execute Kernal Close and Return
|
||
|
BCC FCLOSX ;If Error On Close
|
||
|
JSR FSERR ; If File System Error
|
||
|
BNE FERR ; Return 255
|
||
|
FCLOSX: LDX TEMP0 ;Retrieve Logical File Number
|
||
|
LDA #0 ;Ensure that Z Flag is Set
|
||
|
STA FTBL,X ;Clear File Table Entry
|
||
|
RTS ;and Return 0
|
||
|
|
||
|
;feof(fn) - Check for End of File
|
||
|
;Args: A = Logical file number
|
||
|
;Affects: A,X
|
||
|
FEOF: TAX ;Move Channel# to X
|
||
|
LDA FTBL,X ;Test File Table Entry
|
||
|
BPL FZERO ;If High Bit Clear, Return 0
|
||
|
FERR: LDA #$FF ;Set Generic Error Condition
|
||
|
FRTS: RTS ;Return from Subroutine
|
||
|
|
||
|
;ferror(fn) - Check for Error
|
||
|
;Args: A = Logical file number
|
||
|
;Affects: A,X
|
||
|
;Returns: A = Error Bit Mask
|
||
|
; 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
|
||
|
FERROR LDA FTBL ;File Table Entry 0 Contains Last Error
|
||
|
RTS
|
||
|
|
||
|
;fgetc(fn) - Read character from file
|
||
|
;Args: A = Logical file number
|
||
|
;Stack: 9
|
||
|
;Affects: A,X
|
||
|
;Returns: A = 0,240 (see FERROR)
|
||
|
FGETC: JSR FSCHK ;Save and Validate Logical File Number
|
||
|
BNE FRTS ;If Error, Return 255
|
||
|
JSR CHKIN ;Open channel for input
|
||
|
JSR CHRIN ;Get character from input channel
|
||
|
PHA ;Save read character
|
||
|
JSR FSERR ;Check for Error
|
||
|
JSR CLRCHN ;Clear I/O channels
|
||
|
PLA ;Retrieve read Character
|
||
|
RTS
|
||
|
|
||
|
;fputc(fn) - Write character to file
|
||
|
;Args: A = Logical file number
|
||
|
; Y = Character to Write
|
||
|
;Stack: 9
|
||
|
;Affects: A,X
|
||
|
;Returns: A = 0,240 (see FERROR)
|
||
|
FPUTC: JSR FSCHK ;Save and Validate Logical File Number
|
||
|
BNE FRTS ;If Error, Return 255
|
||
|
JSR CHKOUT ;Open channel for input
|
||
|
TYA ;Move character to accumulator
|
||
|
FPUTCH: JSR CHROUT ;Output a character
|
||
|
JSR FSERR ;Check for Error
|
||
|
JMP CLRCHN ;Clear I/O channels and return
|
||
|
|
||
|
;fgets(fn, &s) - Read string from file
|
||
|
;Requires: DSTLO, DSTHI - Pointer to destination string
|
||
|
;Args: A = Logical file number
|
||
|
; Y,X = Pointer to String
|
||
|
;Stack: 9
|
||
|
;Affects: X,Y
|
||
|
;Returns: A = Number of bytes read
|
||
|
FGETS: JSR SETSRC ;Save string address and initialize pointer
|
||
|
JSR FSCHK ;Save and Validate Logical File Number
|
||
|
BNE FRTS ;If Error, Return 255
|
||
|
JSR CHKIN ;Open Channel for Input (X set in FSCHK)
|
||
|
FGETSL: JSR CHRIN ;Get character from input channel
|
||
|
STA TEMP3
|
||
|
JSR FSERR ;Check for Error
|
||
|
BNE FGETSX ;If Not 0, Exit
|
||
|
LDA TEMP3 ;Retrieve read character
|
||
|
STA (SRCLO),Y ;Store character in string
|
||
|
CMP #$0D ;If Carriage Return
|
||
|
BEQ FGETSX ; Then Exit
|
||
|
INY ;Increment pointer
|
||
|
BPL FGETSL ;and loop if less than 128
|
||
|
FGETSX: LDA #$00 ;Terminate String
|
||
|
STA (SRCLO),Y ;
|
||
|
FGETSY: JSR CLRCHN ;Clear I/O channels
|
||
|
TYA ;Return string length
|
||
|
RTS
|
||
|
|
||
|
;fputs(fn, &s) - Write String to File
|
||
|
;Requires: DSTLO, DSTHI - Pointer to source string
|
||
|
;Args: A = Logical file number
|
||
|
; Y,X = Pointer to String
|
||
|
;Affects: X,Y
|
||
|
;Returns: A = Number of bytes written
|
||
|
FPUTS: JSR SETSRC ;Save string address & initialize pointer
|
||
|
BNE FRTS ;If Error, Return 255
|
||
|
JSR FSCHK ;Save and Validate Logical File Number
|
||
|
JSR CHKOUT ;Open channel for Output
|
||
|
FPUTSL: LDA (SRCLO),Y ;Load next character
|
||
|
CMP #$00 ;If Null Terminator
|
||
|
BEQ FGETSY ; Then Exit
|
||
|
JSR CHROUT ;Write character to output channel
|
||
|
JSR FSERR ;Check for Error
|
||
|
BNE FGETSY ;If Not 0, Exit
|
||
|
INY ;Increment pointer
|
||
|
BPL FPUTSL ;If less than 128 then loop
|
||
|
BMI FGETSY ;Else exit
|
||
|
|
||
|
;fserr() - Check for File Read/Write Error
|
||
|
;Requires: TEMP0 - Logical File Number of Last Read/Write
|
||
|
;Sets: High Bit of File Table Entry to 1 if Error
|
||
|
;Returns: A = 0 if No Error, Otherwise LFN | $80
|
||
|
; N = 1 if Error, 0 if None
|
||
|
; X = Logical File Number
|
||
|
;Check for End of File and Set Flag
|
||
|
FSERR: JSR READST ;Read status word
|
||
|
STA FTBL ;and Save It
|
||
|
BEQ FSERRX ;If Not 0
|
||
|
LDX TEMP0 ; Get Channel#
|
||
|
LDA FTBL,X ; Load Table Entry
|
||
|
ORA #$80 ; Set High Bit
|
||
|
STA FTBL,X ; and Save
|
||
|
FSERRX: RTS
|
||
|
|
||
|
;fsdst(&s) - Set Destination String
|
||
|
; Called before fread()
|
||
|
;Args: X,Y = Pointer to destination string
|
||
|
;Sets: DSTLO,DSTHI = Pointer to destination string
|
||
|
;Affects: N,Z
|
||
|
FSDST EQU SETDST ;Aliased to System Header function
|
||
|
|
||
|
;fread(fn, n) - Read bytes from file
|
||
|
;Requires: DSTLO, DSTHI - Pointer to destination string
|
||
|
;Args: A = Logical file number
|
||
|
; Y = Maximum number of bytes to read
|
||
|
;Affects: X,Y
|
||
|
;Returns: A = Number of bytes read
|
||
|
FREAD: STY TEMP1 ;Save Number of Bytes to Read
|
||
|
LDY #0 ;Initialize pointer
|
||
|
JSR FSCHK ;Save and Validate Logical File Number
|
||
|
BNE FREADR ;If Error, Return 255
|
||
|
JSR CHKIN ;Open Channel for Input (X set in FSCHK)
|
||
|
FREADL: JSR CHRIN ;Get character from input channel
|
||
|
STA TEMP3
|
||
|
JSR FSERR ;Check for Error
|
||
|
BNE FREADX ;If Not 0, Exit
|
||
|
LDA TEMP3 ;Retrieve read character
|
||
|
STA (DSTLO),Y ;Store character in string
|
||
|
INY ;Increment pointer
|
||
|
CPY TEMP1 ;If Less Than Maximum
|
||
|
BNE FREADL ; Then Loop
|
||
|
FREADX: JSR CLRCHN ;Clear I/O channels
|
||
|
TYA ;Return string length
|
||
|
FREADR: RTS
|
||
|
|
||
|
;fssrc(&s) - Set Destination String
|
||
|
; Called before fwrite()
|
||
|
;Args: X,Y = Pointer to destination string
|
||
|
;Sets: SRCLO,SRCHI = Pointer to destination string
|
||
|
;Affects: N,Z
|
||
|
FSSRC EQU SETSRC ;Aliased to System Header function
|
||
|
|
||
|
;fwrite(fn, n) - Write bytes from file
|
||
|
;Requires: SRCLO, SRCHI - Pointer to destination string
|
||
|
;Args: A = Logical file number
|
||
|
; Y = Maximum number of bytes to read
|
||
|
;Affects: X,Y
|
||
|
;Returns: A = Number of bytes written
|
||
|
FWRITE: STY TEMP1 ;Save Number of Bytes to Writre
|
||
|
LDY #0 ;Initialize pointer
|
||
|
JSR FSCHK ;Save and Validate Logical File Number
|
||
|
BNE FWRITR ;If Error, Return 255
|
||
|
JSR CHKOUT ;Open Channel for Input (X set in FSCHK)
|
||
|
FWRITL: LDA (SRCLO),Y ;Get Byte to Write
|
||
|
JSR CHROUT ;Get character from input channel
|
||
|
JSR FSERR ;Check for Error
|
||
|
BNE FWRITX ;If Not 0, Exit
|
||
|
INY ;Increment pointer
|
||
|
CPY TEMP1 ;If Less Than Maximum
|
||
|
BNE FWRITL ; Then Loop
|
||
|
FWRITX: JSR CLRCHN ;Clear I/O channels
|
||
|
TYA ;Return string length
|
||
|
FWRITR: RTS
|