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:
parent
1440c42c26
commit
0e149b7798
@ -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
41
include/cbm/error.a02
Normal 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
694
include/cbm/fileio.a02
Normal 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
186
include/cbm/fileio.h02
Normal 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
205
include/cbm/filesys.a02
Normal 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
56
include/cbm/filesys.h02
Normal 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
140
include/fileio.a02
Normal 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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user