mirror of
https://github.com/bobbimanners/Applecorn.git
synced 2024-11-05 02:08:07 +00:00
954 lines
28 KiB
ArmAsm
954 lines
28 KiB
ArmAsm
* AUXMEM.HOSTFS.S
|
|
* (c) Bobbi 2021 GPL v3
|
|
*
|
|
* AppleMOS Host File System
|
|
* 29-Aug-2021 Generalised CHKERROR routone, checks for and
|
|
* translates ProDOS errors into Acorn errors
|
|
* Set &E0=&FF for testing to report ProDOS errors
|
|
* 30-Aug-2021 FSC commands moved to here
|
|
* Command line set by *RUN, and read by OSARGS
|
|
|
|
|
|
FSXREG EQU $B0
|
|
FSYREG EQU $B1
|
|
FSAREG EQU $B2
|
|
FSCTRL EQU FSXREG
|
|
FSPTR1 EQU $B4
|
|
FSPTR2 EQU $B6
|
|
FSCMDLINE EQU $CE
|
|
|
|
|
|
* OSFIND - open/close a file for byte access
|
|
FINDHND PHX
|
|
PHY
|
|
PHA
|
|
CMP #$00 ; A=$00 = close
|
|
BEQ :CLOSE
|
|
PHA
|
|
JSR PARSNAME ; Copy filename->MOSFILE
|
|
PLA ; Recover options
|
|
>>> XF2MAIN,OFILE
|
|
:CLOSE >>> WRTMAIN
|
|
STY MOSFILE ; Write file number
|
|
>>> WRTAUX
|
|
>>> XF2MAIN,CFILE
|
|
OSFINDRET
|
|
>>> ENTAUX
|
|
PLY ; Value of A on entry
|
|
CPY #$00 ; Was it close?
|
|
BNE :S1
|
|
TYA ; Preserve A for close
|
|
:S1 PLY
|
|
PLX
|
|
RTS
|
|
|
|
* OSGBPB - Get/Put a block of bytes to/from an open file
|
|
GBPBHND LDA #<OSGBPBM
|
|
LDY #>OSGBPBM
|
|
JMP PRSTR
|
|
OSGBPBM ASC 'OSGBPB.'
|
|
DB $00
|
|
|
|
* OSBPUT - write one byte to an open file
|
|
BPUTHND PHX
|
|
PHY
|
|
PHA ; Stash char to write
|
|
>>> WRTMAIN
|
|
STY MOSFILE ; File reference number
|
|
>>> WRTAUX
|
|
>>> XF2MAIN,FILEPUT
|
|
OSBPUTRET
|
|
>>> ENTAUX
|
|
CLC ; Means no error
|
|
PLA
|
|
PLY
|
|
PLX
|
|
RTS
|
|
|
|
* OSBGET - read one byte from an open file
|
|
BGETHND PHX
|
|
PHY
|
|
>>> WRTMAIN
|
|
STY MOSFILE ; File ref number
|
|
>>> WRTAUX
|
|
>>> XF2MAIN,FILEGET
|
|
OSBGETRET
|
|
>>> ENTAUX
|
|
CLC ; Means no error
|
|
CPY #$00 ; Check error status
|
|
BEQ :NOERR
|
|
SEC ; Set carry for error
|
|
BRA :EXIT
|
|
:NOERR CLC
|
|
:EXIT PLY
|
|
PLX
|
|
RTS
|
|
|
|
* OSARGS - adjust file arguments
|
|
* On entry, A=action
|
|
* Y<>0 A=FF Flush channel Y
|
|
* A=00 Read PTR#Y
|
|
* A=01 Write PTR#Y
|
|
* A=02 Read EXT#Y
|
|
* A=03 Write EXT#Y
|
|
* Y=0 A=FF Flush all channels
|
|
* A=00 Return filing system number in A
|
|
* A=01 Read command line address
|
|
* X=>4 byte ZP control block
|
|
* Y=file handle
|
|
* On exit, A=0 - implemented (except ARGS 0,0)
|
|
* A - preserved=unimplemented
|
|
* X,Y - preserved
|
|
* control block updated for 'read' calls
|
|
* control block preserved otherwise
|
|
*
|
|
ARGSHND PHX
|
|
PHY
|
|
PHA
|
|
CPY #$00
|
|
BNE :HASFILE
|
|
CMP #$00 ; Y=0,A=0 => current file sys
|
|
BNE :S1
|
|
PLA
|
|
LDA #105 ; 105=AppleFS filing system
|
|
PLY
|
|
PLX
|
|
RTS
|
|
|
|
:S1 CMP #$01 ; Y=0,A=1 => addr of CLI
|
|
BNE :S2
|
|
LDA FSCMDLINE+0
|
|
STA $00,X
|
|
LDA FSCMDLINE+1
|
|
STA $01,X
|
|
LDA #$FF
|
|
STA $02,X
|
|
STA $03,X
|
|
JMP OSARGSDONE ; Implemented
|
|
|
|
:S2 CMP #$FF ; Y=0,A=FF => flush all files
|
|
BNE :IEXIT
|
|
>>> WRTMAIN
|
|
STZ MOSFILE ; Zero means flush all
|
|
>>> WRTAUX
|
|
JMP :FLUSH
|
|
:IEXIT JMP :EXIT ; Exit preserved
|
|
|
|
:HASFILE >>> WRTMAIN
|
|
STY MOSFILE ; File ref num
|
|
STX MOSFILE+1 ; Pointer to ZP control block
|
|
>>> WRTAUX
|
|
CMP #$00 ; Y!=0,A=0 => read seq ptr
|
|
BNE :S3
|
|
>>> WRTMAIN
|
|
STZ MOSFILE+2 ; 0 means get pos
|
|
>>> WRTAUX
|
|
>>> XF2MAIN,TELL
|
|
|
|
:S3 CMP #$01 ; Y!=0,A=1 => write seq ptr
|
|
BNE :S4
|
|
>>> WRTMAIN
|
|
LDA $00,X
|
|
STA MOSFILE+2
|
|
LDA $01,X
|
|
STA MOSFILE+3
|
|
LDA $02,X
|
|
STA MOSFILE+4
|
|
>>> WRTAUX
|
|
>>> XF2MAIN,SEEK
|
|
|
|
:S4 CMP #$02 ; Y!=0,A=2 => read file len
|
|
BNE :S5
|
|
>>> WRTMAIN
|
|
STA MOSFILE+2 ; Non-zero means get len
|
|
>>> WRTAUX
|
|
>>> XF2MAIN,TELL
|
|
|
|
:S5 CMP #$FF ; Y!=0,A=FF => flush file
|
|
BNE :EXIT
|
|
:FLUSH >>> XF2MAIN,FLUSH
|
|
|
|
:EXIT PLA ; Unimplemented
|
|
PLY
|
|
PLX
|
|
RTS
|
|
|
|
OSARGSRET >>> ENTAUX
|
|
OSARGSDONE PLA
|
|
LDA #0 ; Implemented
|
|
PLY
|
|
PLX
|
|
RTS
|
|
|
|
|
|
* OSFILE - perform actions on entire files
|
|
* On entry, A=action
|
|
* XY=>control block
|
|
* On exit, A=preserved if unimplemented
|
|
* A=0 object not found (not load/save)
|
|
* A=1 file found
|
|
* A=2 directory found
|
|
* XY preserved
|
|
* control block updated
|
|
FILEHND PHX
|
|
PHY
|
|
PHA
|
|
|
|
STX CBPTR ; LSB of parameter block
|
|
STX ZP1
|
|
STY CBPTR+1 ; MSB of parameter block
|
|
STY ZP1+1
|
|
|
|
LDA (ZP1) ; Filename ptr->XY
|
|
TAX
|
|
LDY #$01
|
|
LDA (ZP1),Y
|
|
TAY
|
|
|
|
JSR PARSNAME ; Copy filename->MOSFILE
|
|
|
|
LDA #<FILEBLK
|
|
STA ZP2
|
|
LDA #>FILEBLK
|
|
STA ZP2+1
|
|
LDY #$00 ; Copy to FILEBLK in main mem
|
|
:L1 LDA (ZP1),Y
|
|
>>> WRTMAIN
|
|
STA (ZP2),Y
|
|
>>> WRTAUX
|
|
INY
|
|
CPY #$12
|
|
BNE :L1
|
|
|
|
PLA ; Get action back
|
|
PHA
|
|
BEQ :SAVE ; A=00 -> SAVE
|
|
CMP #$FF
|
|
BEQ :LOAD ; A=FF -> LOAD
|
|
CMP #$06
|
|
BEQ :DELETE ; A=06 -> DELETE
|
|
BCC :JMPINFO ; A=01-05 -> INFO
|
|
CMP #$08
|
|
BEQ :MKDIR ; A=08 -> MKDIR
|
|
|
|
PLA ; Not implemented, return unchanged
|
|
PLY
|
|
PLX
|
|
RTS
|
|
|
|
:JMPINFO JMP :INFO
|
|
:SAVE >>> XF2MAIN,SAVEFILE
|
|
:LOAD >>> XF2MAIN,LOADFILE
|
|
:DELETE >>> XF2MAIN,DELFILE
|
|
:MKDIR >>> XF2MAIN,MAKEDIR
|
|
:INFO >>> XF2MAIN,INFOFILE
|
|
|
|
* On return here, A<$20 return to caller, A>$1F ProDOS error
|
|
OSFILERET
|
|
>>> ENTAUX
|
|
PHA
|
|
LDA CBPTR ; Copy OSFILE CB to :CBPTR addr
|
|
STA ZP1
|
|
LDA CBPTR+1
|
|
STA ZP1+1
|
|
LDY #$02
|
|
:L3 LDA AUXBLK,Y ; Mainmem left it in AUXBLK
|
|
STA (ZP1),Y
|
|
INY
|
|
CPY #18 ; 18 bytes in control block
|
|
BNE :L3
|
|
PLA
|
|
PLY ; Original action
|
|
JSR CHKERROR ; Check if error returned
|
|
PLY ; No error, return to caller
|
|
PLX
|
|
RTS
|
|
|
|
ERRNOTFND BRK
|
|
DB $D6 ; $D6 = Object not found
|
|
ASC 'File not found'
|
|
BRK
|
|
|
|
ERREXISTS BRK
|
|
DB $C4 ; Can't create a dir if a file is
|
|
ASC 'File exists' ; already there
|
|
BRK
|
|
|
|
CBPTR DW $0000
|
|
OSFILEM ASC 'OSFILE($'
|
|
DB $00
|
|
OSFILEM2 ASC ')'
|
|
DB $00
|
|
OSFSCM ASC 'OSFSC.'
|
|
DB $00
|
|
|
|
|
|
* FSC Command Table
|
|
*******************
|
|
* These are commands specific to the filing system that can't be
|
|
* called via OSFILE, OSFSC, etc.
|
|
*
|
|
FSCCOMMAND ASC 'CHDIR'
|
|
DB $C0
|
|
DW FSCCHDIR-1 ; Change directory, XY=>params
|
|
ASC 'CD'
|
|
DB $C0
|
|
DW FSCCHDIR-1 ; Change directory, XY=>params
|
|
ASC 'DIR'
|
|
DB $C0
|
|
DW FSCCHDIR-1 ; Change directory, XY=>params
|
|
* TO DO, CHDIR should be $80 for LPTR=>params
|
|
ASC 'DRIVE'
|
|
DB $80
|
|
DW FSCDRIVE-1 ; Select drive, LPTR=>params
|
|
ASC 'FREE'
|
|
DB $80
|
|
DW FSCFREE-1 ; FREE <drive>, LPTR=>params
|
|
ASC 'ACCESS'
|
|
DB $80
|
|
DW FSCACCESS-1 ; ACCESS <objlist> <access>, LPTR=>params
|
|
ASC 'TITLE'
|
|
DB $80
|
|
DW FSCTITLE-1 ; TITLE (<drive>) <title>, LPTR=>params
|
|
ASC 'DESTROY'
|
|
DB $80
|
|
DW FSCDESTROY-1 ; DESTROY <objlist>, LPTR=>params
|
|
*
|
|
DB $FF ; Terminator
|
|
|
|
|
|
* OSFSC - miscellanous file system calls
|
|
*****************************************
|
|
* On entry, A=action, XY=>command line
|
|
* or A=action, X=param1, Y=param2
|
|
* On exit, A=preserved if unimplemented
|
|
* A=modified if implemented
|
|
* X,Y=any return values
|
|
*
|
|
FSCHND
|
|
CMP #$00
|
|
BEQ FSOPT ; A=0 - *OPT
|
|
CMP #$01
|
|
BEQ CHKEOF ; A=1 - Read EOF
|
|
CMP #$02
|
|
BEQ FSCRUN ; A=2 - */filename
|
|
CMP #$03
|
|
BEQ FSC03 ; A=3 - *command
|
|
CMP #$04
|
|
BEQ FSCRUN ; A=4 - *RUN
|
|
CMP #$05
|
|
BEQ JMPCAT ; A=5 - *CAT
|
|
CMP #$09
|
|
BEQ JMPCAT ; A=9 - *EX
|
|
CMP #$0A
|
|
BEQ JMPCAT ; A=10 - *INFO
|
|
CMP #$0C
|
|
BEQ FSCREN ; A=12 - *RENAME
|
|
|
|
* Performs OSFSC *OPT function
|
|
FSOPT RTS ; No FS options for now
|
|
|
|
FSCDRIVE JMP DRIVE
|
|
|
|
FSCFREE JMP FREE
|
|
|
|
FSCACCESS JMP ACCESS
|
|
|
|
FSCDESTROY JMP DESTROY
|
|
|
|
FSCTITLE
|
|
|
|
FSCUKN PHA
|
|
LDA #<OSFSCM
|
|
LDY #>OSFSCM
|
|
JSR PRSTR
|
|
PLA
|
|
FSCNULL RTS
|
|
|
|
JMPCAT JMP FSCCAT
|
|
|
|
FSC03 JSR XYtoLPTR
|
|
LDX #<FSCCOMMAND
|
|
LDY #>FSCCOMMAND
|
|
JSR CLILOOKUP
|
|
BEQ FSCNULL
|
|
JSR LPTRtoXY
|
|
*
|
|
FSCRUN STX OSFILECB ; Pointer to filename
|
|
STY OSFILECB+1
|
|
JSR XYtoLPTR
|
|
FSCRUNLP LDA (OSLPTR),Y ; Look for command line
|
|
INY
|
|
CMP #'!'
|
|
BCS FSCRUNLP
|
|
DEY
|
|
JSR SKIPSPC
|
|
JSR LPTRtoXY
|
|
STX FSCMDLINE+0 ; Set CMDLINE=>command line
|
|
STY FSCMDLINE+1 ; Collected by OSARGS 1,0
|
|
LDA #$FF ; OSFILE load flag
|
|
STA OSFILECB+6 ; Use file's address
|
|
LDX #<OSFILECB ; Pointer to control block
|
|
LDY #>OSFILECB
|
|
JSR OSFILE
|
|
JSR :CALL
|
|
LDA #$00 ; A=0 on return
|
|
RTS
|
|
:CALL LDA #$01 ; A=1 - entering code
|
|
SEC ; Not from RESET
|
|
JMP (OSFILECB+6) ; Jump to EXEC addr
|
|
|
|
FSCREN JMP RENAME
|
|
|
|
FSCCHDIR JMP CHDIR
|
|
|
|
* Performs OSFSC Read EOF function
|
|
* File ref number is in X
|
|
CHKEOF >>> WRTMAIN
|
|
STX MOSFILE ; File reference number
|
|
>>> WRTAUX
|
|
>>> XF2MAIN,FILEEOF
|
|
CHKEOFRET
|
|
>>> ENTAUX
|
|
TAX ; Return code -> X
|
|
RTS
|
|
|
|
* Perform CAT
|
|
* A=5 *CAT, A=9 *EX, A=10 *INFO
|
|
FSCCAT PHA
|
|
JSR PARSNAME ; Copy filename->MOSFILE
|
|
PLA
|
|
ASL A
|
|
ASL A
|
|
ASL A ; 0101xxxx=*CAT
|
|
ASL A ; 1001xxxx=*EX
|
|
STA FSAREG ; 1010xxxx=*INFO
|
|
>>> XF2MAIN,CATALOG
|
|
STARCATRET
|
|
>>> ENTAUX
|
|
PHA
|
|
JSR FORCENL
|
|
PLA
|
|
JSR CHKERROR ; See if error occurred
|
|
CATDONE LDA #0 ; 0=OK
|
|
RTS
|
|
|
|
* Print one block of a catalog. Called by CATALOG
|
|
* Block is in AUXBLK
|
|
PRONEBLK >>> ENTAUX
|
|
LDA AUXBLK+4 ; Get storage type
|
|
AND #$E0 ; Mask 3 MSBs
|
|
CMP #$E0
|
|
BNE :NOTKEY ; Not a key block
|
|
LDA #<:DIRM
|
|
LDY #>:DIRM
|
|
JSR PRSTR
|
|
SEC
|
|
:NOTKEY LDA #$00
|
|
:L1 PHA
|
|
PHP
|
|
JSR PRONEENT
|
|
PLP
|
|
BCC :L1X
|
|
JSR OSNEWL
|
|
:L1X PLA
|
|
INC
|
|
CMP #13 ; Number of dirents in block
|
|
CLC
|
|
BNE :L1
|
|
>>> XF2MAIN,CATALOGRET
|
|
:DIRM ASC 'Directory: '
|
|
DB $00
|
|
|
|
* Print a single directory entry
|
|
* On entry: A = dirent index in AUXBLK
|
|
PRONEENT PHP
|
|
TAX
|
|
LDA #<AUXBLK+4 ; Skip pointers
|
|
STA ZP3
|
|
LDA #>AUXBLK+4
|
|
STA ZP3+1
|
|
:L1 CPX #$00
|
|
BEQ :S1
|
|
CLC
|
|
LDA #$27 ; Size of dirent
|
|
ADC ZP3
|
|
STA ZP3
|
|
LDA #$00
|
|
ADC ZP3+1
|
|
STA ZP3+1
|
|
DEX
|
|
BRA :L1
|
|
:S1 LDY #$00
|
|
LDA (ZP3),Y
|
|
BEQ :EXIT1 ; Inactive entry
|
|
AND #$0F ; Len of filename
|
|
TAX
|
|
LDY #$01
|
|
:L2 CPX #$00
|
|
BEQ :S2
|
|
LDA (ZP3),Y
|
|
JSR OSWRCH
|
|
DEX
|
|
INY
|
|
BRA :L2
|
|
:S2 PLP
|
|
BCS :EXIT
|
|
LDA #$20
|
|
BIT FSAREG
|
|
BPL :S2LP
|
|
INY
|
|
INY
|
|
INY
|
|
INY
|
|
:S2LP JSR OSWRCH
|
|
INY
|
|
CPY #$15
|
|
BNE :S2LP
|
|
BIT FSAREG
|
|
BPL :EXIT
|
|
LDY #$21
|
|
LDX #3
|
|
LDA #0
|
|
JSR PRADDR0
|
|
LDA #'+'
|
|
JSR OSWRCH
|
|
LDY #$17
|
|
JSR PRADDR
|
|
JSR PRSPACE
|
|
LDY #$00
|
|
LDA (ZP3),Y
|
|
AND #$F0
|
|
CMP #$D0
|
|
BNE :NOTDIR
|
|
LDA #'D'
|
|
JSR OSWRCH
|
|
JSR PRLOCK
|
|
JMP OSNEWL
|
|
:NOTDIR JSR PRLOCK
|
|
LDA (ZP3),Y
|
|
LSR A
|
|
PHP
|
|
AND #1
|
|
BEQ :NOWR
|
|
LDA #'W'
|
|
JSR OSWRCH
|
|
:NOWR PLP
|
|
BCC :NOWR
|
|
LDA #'R'
|
|
JSR OSWRCH
|
|
:NORD
|
|
* JSR PRSPACE
|
|
* LDY #$22
|
|
* LDX #2
|
|
* JSR PRADDRLP
|
|
JMP OSNEWL
|
|
:EXIT1 PLP
|
|
:EXIT RTS
|
|
|
|
PRLOCK LDY #$1E
|
|
LDA (ZP3),Y
|
|
CMP #$40
|
|
BCS PRADDROK
|
|
LDA #'L'
|
|
JMP OSWRCH
|
|
|
|
PRADDR LDX #3
|
|
PRADDRLP LDA (ZP3),Y
|
|
PRADDR0 JSR OUTHEX
|
|
DEY
|
|
DEX
|
|
BNE PRADDRLP
|
|
PRADDROK RTS
|
|
PRSPACE LDA #' '
|
|
JMP OSWRCH
|
|
|
|
* Perform FSCV $0C RENAME function
|
|
* Parameter string in XY
|
|
RENAME JSR PARSNAME ; Copy Arg1->MOSFILE
|
|
CMP #$00 ; Length of arg1
|
|
BEQ :SYNTAX
|
|
JSR PARSLPTR2 ; Copy Arg2->MOSFILE2
|
|
CMP #$00 ; Length of arg2
|
|
BEQ :SYNTAX
|
|
>>> XF2MAIN,RENFILE
|
|
:SYNTAX BRK
|
|
DB $DC
|
|
ASC 'Syntax: RENAME <objspec> <objspec>'
|
|
BRK
|
|
RENRET
|
|
>>> ENTAUX
|
|
JSR CHKERROR
|
|
LDA #$00
|
|
RTS
|
|
|
|
* Perform *COPY function
|
|
* Parameter string in XY
|
|
COPY JSR PARSNAME ; Copy Arg1->MOSFILE
|
|
CMP #$00 ; Length of arg1
|
|
BEQ :SYNTAX
|
|
JSR PARSLPTR2 ; Copy Arg2->MOSFILE2
|
|
CMP #$00 ; Length of arg2
|
|
BEQ :SYNTAX
|
|
>>> XF2MAIN,COPYFILE
|
|
:SYNTAX BRK
|
|
DB $DC
|
|
ASC 'Syntax: COPY <listspec> <*objspec*>'
|
|
BRK
|
|
COPYRET
|
|
>>> ENTAUX
|
|
JSR CHKERROR
|
|
LDA #$00
|
|
RTS
|
|
|
|
* Handle *DIR (directory change) command
|
|
* On entry, XY points to command line
|
|
CHDIR JSR PARSNAME ; Copy filename->MOSFILE
|
|
CMP #$00 ; Filename length
|
|
BNE :HASPARM
|
|
BRK
|
|
DB $DC
|
|
ASC 'Syntax: DIR <*objspec*>'
|
|
BRK
|
|
:HASPARM >>> XF2MAIN,SETPFX
|
|
|
|
* Handle *DRIVE command, which is similar
|
|
* On entry, (OSLPTR),Y points to command line
|
|
DRIVE LDA (OSLPTR),Y ; First char
|
|
CMP #$3A ; Colon
|
|
BNE :ERR
|
|
JSR PARSLPTR ; Copy arg->MOSFILE
|
|
CMP #$03 ; Check 3 char arg
|
|
BEQ :HASPARM
|
|
:ERR BRK
|
|
DB $DC
|
|
ASC 'Syntax: DRIVE <dry> (eg: DRIVE :61)'
|
|
BRK
|
|
:HASPARM >>> XF2MAIN,SETPFX
|
|
|
|
CHDIRRET
|
|
>>> ENTAUX
|
|
JSR CHKERROR
|
|
CMP #$00
|
|
BEQ :EXIT
|
|
BRK
|
|
DB $CE ; Bad directory
|
|
ASC 'Bad dir'
|
|
BRK
|
|
:EXIT RTS
|
|
|
|
* Handle *FREE command
|
|
FREE LDA (OSLPTR),Y ; First char
|
|
CMP #$3A ; Colon
|
|
BNE :ERR
|
|
JSR PARSLPTR ; Copy arg->MOSFILE
|
|
CMP #$03 ; Check 3 char arg
|
|
BEQ :HASPARM
|
|
:ERR BRK
|
|
DB $DC
|
|
ASC 'Syntax: FREE <dry> (eg: DRIVE :61)'
|
|
BRK
|
|
:HASPARM >>> XF2MAIN,DRVINFO
|
|
|
|
FREERET
|
|
>>> ENTAUX
|
|
JSR CHKERROR
|
|
CMP #$00
|
|
BEQ :NOERR
|
|
BRK
|
|
DB $CE ; Bad directory
|
|
ASC 'Bad dir'
|
|
BRK
|
|
:NOERR SEC
|
|
LDA AUXBLK+2 ; LSB of total blks
|
|
SBC AUXBLK ; LSB of blocks used
|
|
TAX
|
|
LDA AUXBLK+3 ; MSB of total blks
|
|
SBC AUXBLK+1 ; MSB of blocks used
|
|
TAY
|
|
JSR PRDECXY ; Print in decimal
|
|
LDX #<:FREEM
|
|
LDY #>:FREEM
|
|
JSR OUTSTR
|
|
JSR FORCENL
|
|
LDX AUXBLK+0 ; Blocks used
|
|
LDY AUXBLK+1
|
|
JSR PRDECXY ; Print in decimal
|
|
LDX #<:USEDM
|
|
LDY #>:USEDM
|
|
JSR OUTSTR
|
|
JSR FORCENL
|
|
RTS
|
|
:FREEM ASC ' 512-byte Blocks Free'
|
|
DB $00
|
|
:USEDM ASC ' 512-byte Blocks Used'
|
|
DB $00
|
|
|
|
ACCESS JSR PARSLPTR ; Copy filename->MOSFILE
|
|
CMP #$00 ; Filename length
|
|
BEQ :SYNTAX
|
|
JSR PARSLPTR2 ; Copy Arg2->MOSFILE2
|
|
>>> XF2MAIN,SETPERM
|
|
:SYNTAX BRK
|
|
DB $DC
|
|
ASC 'Syntax: ACCESS <listspec> <L|R|W>'
|
|
BRK
|
|
|
|
ACCRET >>> ENTAUX
|
|
JSR CHKERROR
|
|
LDA #$00
|
|
RTS
|
|
|
|
DESTROY JSR PARSLPTR ; Copy filename->MOSFILE
|
|
CMP #$00 ; Filename length
|
|
BEQ :SYNTAX
|
|
>>> XF2MAIN,MULTIDEL
|
|
:SYNTAX BRK
|
|
DB $DC
|
|
ASC 'Syntax: DESTROY <listspec>'
|
|
BRK
|
|
|
|
DESTRET >>> ENTAUX
|
|
JSR CHKERROR
|
|
LDA #$00
|
|
RTS
|
|
|
|
* Parse filename pointed to by XY
|
|
* Write filename to MOSFILE in main memory
|
|
* Returns length in A
|
|
PARSNAME JSR XYtoLPTR
|
|
PARSLPTR CLC ; Means parsing a filename
|
|
JSR GSINIT ; Init gen string handling
|
|
PHP
|
|
SEI ; Disable IRQs
|
|
LDX #$00 ; Length
|
|
:L1 JSR GSREAD ; Handle next char
|
|
BCS :DONE
|
|
STA $C004 ; Write to main mem
|
|
STA MOSFILE+1,X
|
|
STA $C005 ; Write to aux mem
|
|
INX
|
|
BNE :L1
|
|
:DONE STA $C004 ; Write to main mem
|
|
STX MOSFILE ; Length byte (Pascal)
|
|
STA $C005 ; Back to aux
|
|
PLP ; IRQs back as they were
|
|
TXA ; Return len in A
|
|
RTS
|
|
|
|
* Parse filename pointed to by (OSLPTR),Y
|
|
* Write filename to MOSFILE2 in main memory
|
|
* Returns length in A
|
|
PARSNAME2 JSR XYtoLPTR
|
|
PARSLPTR2 CLC ; Means parsing a filename
|
|
JSR GSINIT ; Init gen string handling
|
|
PHP
|
|
SEI ; Disable IRQs
|
|
LDX #$00 ; Length
|
|
:L1 JSR GSREAD ; Handle next char
|
|
BCS :DONE
|
|
STA $C004 ; Write to main mem
|
|
STA MOSFILE2+1,X
|
|
STA $C005 ; Write to aux mem
|
|
INX
|
|
BNE :L1
|
|
:DONE STA $C004 ; Write to main mem
|
|
STX MOSFILE2 ; Length byte (Pascal)
|
|
STA $C005 ; Back to aux
|
|
PLP ; IRQs back as they were
|
|
TXA ; Return len in A
|
|
RTS
|
|
|
|
* Move this somewhere
|
|
CHKERROR CMP #$20
|
|
BCS MKERROR
|
|
RTS
|
|
|
|
*ERREXISTS LDA #$47 ; File exists
|
|
*ERRNOTFND LDA #$46 ; File not found
|
|
|
|
MKERROR
|
|
BIT $E0
|
|
BPL MKERROR1 ; *TEST*
|
|
PHA
|
|
LDX #15
|
|
MKERRLP
|
|
LDA ERRMSG,X
|
|
STA $100,X
|
|
DEX
|
|
BPL MKERRLP
|
|
PLA
|
|
PHA
|
|
LSR A
|
|
LSR A
|
|
LSR A
|
|
LSR A
|
|
JSR ERRHEX
|
|
STA $109
|
|
PLA
|
|
JSR ERRHEX
|
|
STA $10A
|
|
JMP $100
|
|
ERRHEX
|
|
AND #15
|
|
CMP #10
|
|
BCC ERRHEX1
|
|
ADC #6
|
|
ERRHEX1
|
|
ADC #48
|
|
RTS
|
|
ERRMSG
|
|
BRK
|
|
DB $FF
|
|
ASC 'TEST: $00'
|
|
BRK
|
|
MKERROR1
|
|
CMP #$40
|
|
BCS MKERROR2
|
|
ADC #$31
|
|
MKERROR2
|
|
SEC
|
|
SBC #$40
|
|
CMP #$20
|
|
BCC MKERROR3
|
|
LDA #$18 ; I/O error
|
|
MKERROR3
|
|
ASL A
|
|
TAX
|
|
LDA MKERROR4+1,X
|
|
PHA
|
|
LDA MKERROR4+0,X
|
|
PHA
|
|
PHP
|
|
RTI
|
|
MKERROR4
|
|
DW ERROR40,ERROR41,ERROR42,ERROR43,ERROR44,ERROR45,ERROR46,ERROR47
|
|
DW ERROR48,ERROR49,ERROR4A,ERROR4B,ERROR4C,ERROR4D,ERROR4E,ERROR4F
|
|
DW ERROR50,ERROR51,ERROR52,ERROR53,ERROR54,ERROR55,ERROR56,ERROR57
|
|
DW ERROR27,ERROR28,ERROR5A,ERROR5B,ERROR2B,ERROR5D,ERROR5E,ERROR2E
|
|
|
|
* $40 - Invalid pathname syntax. Bad filename
|
|
* $41 - Duplicate filename. (additional) Directory exists
|
|
* $42 - File Control Block table full. Too many open
|
|
* $43 - Invalid reference number. Channel not open
|
|
* $44 - Path not found. File not found
|
|
* $45 - Volume directory not found. Disk not found
|
|
* $46 - File not found. File not found
|
|
* $47 - Duplicate filename. (see also $41) File exists
|
|
* $48 - Overrun error. Disk full
|
|
* $49 - Volume directory full. Directory full
|
|
* $4A - Incompatible file format. Disk not recognised
|
|
* $4B - Unsupported storage_type. Disk not recognised
|
|
* $4C - End of file has been encountered. End of file
|
|
* $4D - Position out of range. Past end of file
|
|
* $4E - Access error. (see also $4F) RD/WR: Insufficient access
|
|
* $4F - Access error. (additional) REN/DEL: Locked
|
|
* $50 - File is open. Can't - file open
|
|
* $51 - Directory count error. Broken directory
|
|
* $52 - Not a ProDOS disk. Disk not recognised
|
|
* $53 - Invalid parameter. Invalid parameter
|
|
* $54 - (Dir not empty when deleting) Dir not empty
|
|
* $55 - Volume Control Block table full.
|
|
* $56 - Bad buffer address.
|
|
* $57 - Duplicate volume.
|
|
* ($58) $27 - I/O error (disk not formatted)
|
|
* ($59) $28 - No device connected (drive not present) Disk not present
|
|
* $5A ($29) - Bit map disk address is impossible. Sector not found
|
|
* $5B $2A -
|
|
* ($5C) $2B - Disk write protected. Disk write protected
|
|
* $5D ($2C) - (EOF during load or save) Data lost
|
|
* $5E ($2D) - (Couldn't open to save) Can't save
|
|
* ($5F) $2E - Disk switched Disk changed
|
|
* $2F - Device is offline (drive empty)
|
|
*
|
|
|
|
* AcornOS ProDOS
|
|
ERROR40 DW $CC00
|
|
ASC 'Bad filename' ; $40 - Invalid pathname syntax
|
|
ERROR41 DW $C400
|
|
ASC 'Directory exists' ; $41 - Duplicate filename (split from $47)
|
|
ERROR42 DW $C000
|
|
ASC 'Too many open' ; $42 - File Control Block table full
|
|
ERROR43 DW $DE00
|
|
ASC 'Channel not open' ; $43 - Invalid reference number
|
|
ERROR44 ; $44 - Path not found
|
|
ERROR46 DW $D600
|
|
ASC 'File not found' ; $46 - File not found
|
|
ERROR45 DW $D600
|
|
ASC 'Disk not found' ; $45 - Volume directory not found
|
|
ERROR47 DW $C400
|
|
ASC 'File exists' ; $47 - Duplicate filename (see also $41)
|
|
ERROR48 DW $C600
|
|
ASC 'Disk full' ; $48 - Overrun error
|
|
ERROR49 DW $B300
|
|
ASC 'Directory full' ; $49 - Volume directory full
|
|
ERROR4A ; $4A - Incompatible file format
|
|
ERROR4B ; $4B - Unsupported storage_type
|
|
ERROR52 DW $C800
|
|
ASC 'Disk not recognised' ; $52 - Not a ProDOS disk
|
|
ERROR4C DW $DF00
|
|
ASC 'End of file' ; $4C - End of file has been encountered
|
|
ERROR4D DW $C100
|
|
ASC 'Not open for update' ; $4D - Position out of range
|
|
ERROR4E DW $BD00
|
|
ASC 'Insufficient access' ; $4E - Access error (see also $4F)
|
|
ERROR4F DW $C300
|
|
ASC 'Locked' ; $4F - Access error (split from $4E)
|
|
ERROR50 DW $C200
|
|
ASC 'Can'
|
|
DB $27
|
|
ASC 't - file open' ; $50 - File is open
|
|
ERROR51 DW $A800
|
|
ASC 'Broken directory' ; $51 - Directory count error
|
|
ERROR53 DW $DC00
|
|
ASC 'Invalid parameter' ; $53 - Invalid parameter
|
|
ERROR54 DW $D400
|
|
ASC 'Directory not empty' ; $54 - Directory not empty
|
|
ERROR55 DW $FF00
|
|
ASC 'ProDOS: VCB full' ; $55 - Volume Control Block table full
|
|
ERROR56 DW $FF00
|
|
ASC 'ProDOS: Bad addr' ; $56 - Bad buffer address
|
|
ERROR57 DW $FF00
|
|
ASC 'ProDOS: Dup volm' ; $57 - Duplicate volume
|
|
ERROR5B ; spare
|
|
ERROR27 DW $FF00
|
|
ASC 'I/O error' ; $27 - I/O error
|
|
ERROR28 DW $D200
|
|
ASC 'Disk not present' ; $28 - No device detected/connected
|
|
ERROR5A DW $FF00
|
|
ASC 'Sector not found' ; $5A - Bit map disk address is impossible
|
|
ERROR2B DW $C900
|
|
ASC 'Disk write protected' ; $2B - Disk write protected
|
|
ERROR5D DW $CA00
|
|
ASC 'Data lost' ; $5D - EOF during LOAD or SAVE
|
|
ERROR5E DW $C000
|
|
ASC 'Can'
|
|
DB $27
|
|
ASC 't save' ; $5E - Couldn't open for save
|
|
ERROR2E DW $C800
|
|
ASC 'Disk changed' ; $2E - Disk switched
|
|
DB $00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|