1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-11-26 13:49:21 +00:00
C02/vic20/include/file.a02
2018-01-28 13:45:16 -05:00

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