Merge PR#128 'Updated OSFILE main code'.

This commit is contained in:
Bobbi Webber-Manners 2021-10-24 13:34:06 -04:00
parent 725fc3b76e
commit 0ca2cb0689
6 changed files with 454 additions and 518 deletions

Binary file not shown.

View File

@ -13,6 +13,7 @@
* 13-Oct-2021 FIND, BGET, BPUT optimised passing registers to main.
* 13-Oct-2021 ARGS, EOF returns errors, optimised passing registers.
* 14-Oct-2021 Tidied FILE handler.
* 23-Oct-2021 Uses single dispatch to mainmem FILE handler.
* $B0-$BF Temporary filing system workspace
@ -207,14 +208,16 @@ OSARGSDONE PLA
* A=2 directory found
* XY preserved
* control block updated
OSFILEMIN EQU $FF ; $FF=LOAD
OSFILEMAX EQU $08 ; $08=MKDIR
FILEHND PHX
PHY
PHA
* STX CBPTR ; LSB of parameter block
* STX ZP1
* STY CBPTR+1 ; MSB of parameter block
* STY ZP1+1
CLC
ADC #256-OSFILEMIN
CMP #OSFILEMAX+257-OSFILEMIN ; NB: LTR evaluation
BCS FILEIGNORE
STX FSCTRL+0 ; FSCTRL=>control block
STY FSCTRL+1
@ -225,26 +228,6 @@ FILEHND PHX
TAY
JSR PARSNAME ; Copy filename->MOSFILE
* 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
LDY #$11
>>> WRTMAIN
:L1 LDA (FSCTRL),Y ; Copy control block to auxmem
@ -252,78 +235,50 @@ FILEHND PHX
DEY
BPL :L1
>>> WRTAUX
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 :INFO ; A=01-05 -> INFO
BCC :JMPINFO ; A=01-05 -> INFO
CMP #$08
BEQ :MKDIR ; A=08 -> MKDIR
>>> XF2MAIN,CALLFILE
* PLA
PLY ; Not implemented, return unchanged
PLX
RTS
:JMPINFO JMP :INFO
:SAVE >>> XF2MAIN,SAVEFILE
:LOAD >>> XF2MAIN,LOADFILE
:DELETE >>> XF2MAIN,DELFILE
:INFO >>> XF2MAIN,INFOFILE
:MKDIR >>> XF2MAIN,MAKEDIR
* 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
*
* PLY ; Not implemented, return unchanged
* PLX
* RTS
*
*:JMPINFO JMP :INFO
*:SAVE >>> XF2MAIN,SAVEFILE
*:LOAD >>> XF2MAIN,LOADFILE
*:DELETE >>> XF2MAIN,DELFILE
*:INFO >>> XF2MAIN,INFOFILE
*:MKDIR >>> XF2MAIN,MAKEDIR
* On return here, A<$20 return to caller, A>$1F ProDOS error
OSFILERET >>> ENTAUX
JSR CHKERROR ; Check if error returned
PHA
LDY #$11 ; Copy updated control block back
:L3 LDA AUXBLK,Y ; Mainmem left it in AUXBLK
:L3
* LDA AUXBLK,Y ; Mainmem left it in AUXBLK
LDA OSFILECB,Y ; Mainmem left it in OSFILECB
STA (FSCTRL),Y
DEY
BPL :L3
* 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 ; Returned object type
* PLY ; Original action
* JSR CHKERROR ; Check if error returned
FILEIGNORE PLA ; Returned object type
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
@ -460,24 +415,23 @@ CHKEOFRET >>> ENTAUX
JMP CHKERROR
* Perform CAT
* Display catalog entries and info
* A=5 *CAT, A=9 *EX, A=10 *INFO
FSCCAT PHA
FSCCAT EOR #$06
CLC
ROR A ; 01100000=*CAT
ROR A ; 11100000=*EX
ROR A ; 10000000=*INFO
ROR A ; b7=long info
STA FSAREG ; b6=multiple items
JSR PARSNAME ; Copy filename->MOSFILE
PLA
ASL A
ASL A
ASL A ; 0101xxxx=*CAT
ASL A ; 1001xxxx=*EX
STA FSAREG ; 1010xxxx=*INFO
LDA FSAREG ; Get ARG back
>>> XF2MAIN,CATALOG
STARCATRET
>>> ENTAUX
PHA
JSR FORCENL
PLA
STARCATRET >>> ENTAUX
JSR CHKERROR ; See if error occurred
CATDONE LDA #0 ; 0=OK
JSR FORCENL
* CATDONE
LDA #0 ; 0=OK
RTS
* Print one block of a catalog. Called by CATALOG
@ -713,19 +667,19 @@ FREERET
LDA AUXBLK+3 ; MSB of total blks
SBC AUXBLK+1 ; MSB of blocks used
TAY
LDA #$00 ; *TO DO* b16-b23 of free
LDA #$00 ; *TO DO* b16-b23 of free
* NEW
JSR :FREEDEC ; Print 'AAYYXX blocks aaayyyxxx bytes '
JSR :FREEDEC ; Print 'AAYYXX blocks aaayyyxxx bytes '
LDX #<:FREE
LDY #>:FREE
JSR OUTSTR ; Print 'free'<nl>
LDX AUXBLK+0 ; Blocks used
JSR OUTSTR ; Print 'free'<nl>
LDX AUXBLK+0 ; Blocks used
LDY AUXBLK+1
LDA #$00 ; *TO DO* b16-b23 of used
JSR :FREEDEC ; Print 'AAYYXX blocks aaayyyxxx bytes '
LDA #$00 ; *TO DO* b16-b23 of used
JSR :FREEDEC ; Print 'AAYYXX blocks aaayyyxxx bytes '
LDX #<:USED
LDY #>:USED
JMP OUTSTR ; Print 'used'<nl>
JMP OUTSTR ; Print 'used'<nl>
* OLD
* JSR PRDECXY ; Print in decimal
@ -748,20 +702,20 @@ FREERET
STA FSNUM+3
* What's the maximum number of blocks?
* JSR PRHEX ; Blocks b16-b23 in hex
JSR PR2HEX ; Blocks b0-b15 in hex
JSR PR2HEX ; Blocks b0-b15 in hex
LDX #<:BLOCKS
LDY #>:BLOCKS
JSR OUTSTR ; ' blocks '
STZ FSNUM+0 ; FSNUM=blocks*512
JSR OUTSTR ; ' blocks '
STZ FSNUM+0 ; FSNUM=blocks*512
ASL FSNUM+1
ROL FSNUM+2
ROL FSNUM+3
LDX #FSNUM ; X=>number to print
LDY #8 ; Y=pad up to 8 digits
JSR PRINTDEC ; Print it in decimal
LDX #FSNUM ; X=>number to print
LDY #8 ; Y=pad up to 8 digits
JSR PRINTDEC ; Print it in decimal
LDX #<:BYTES
LDY #>:BYTES
JMP OUTSTR ; ' bytes '
JMP OUTSTR ; ' bytes '
:BLOCKS ASC ' blocks '
DB 0
:BYTES ASC ' bytes '
@ -898,13 +852,13 @@ ERRMSG
MKERROR1
CMP #$40
BCS MKERROR2
ORA #$30 ; <$40 -> $30-$3F
ORA #$30 ; <$40 -> $30-$3F
MKERROR2
SEC
SBC #$37
CMP #$28
BCC MKERROR3
LDA #$00 ; I/O error
LDA #$00 ; I/O error
MKERROR3
ASL A
TAX
@ -945,14 +899,13 @@ MKERROR4 DW ERROR27
* $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: Insuff access ..
* .. also, dir not empty
* $4E - Access error. (see also $4F) RD/WR: Insufficient access
* $4F -(Access error. split from $4E) REN/DEL/SAV: Locked
* $50 - File already 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 - (GSOS Out of memory) (Dir not empty when deleting)
* $54 -(Dir not empty when deleting, cf $4E) DEL: Dir not empty
* $55 - Volume Control Block table full.
* $56 - Bad buffer address.
* $57 - Duplicate volume.
@ -961,7 +914,7 @@ MKERROR4 DW ERROR27
* $5A - Bit map disk address is impossible. Sector not found
* $5B -(GSOS Bad ChangePath pathname)
* $5C -(GSOS Not executable file)
* $5D -(GSOS OS/FS not found) (EOF during load or save) Data lost
* $5D -(GSOS OS/FS not found) (EOF during load or save) Data lost
* $5E -(Couldn't open to save) Can't save
* $5F -(GSOS Too many applications)
* $60+ - (GSOS)
@ -969,68 +922,67 @@ MKERROR4 DW ERROR27
* AcornOS ProDOS
ERROR40 DW $CC00
ASC 'Bad filename' ; $40 - Invalid pathname syntax
ASC 'Bad filename' ; $40 - Invalid pathname syntax
ERROR41 DW $C400
ASC 'Is a directory' ; $41 - Duplicate filename (split from $47)
ASC 'Is a directory' ; $41 - Duplicate filename (split from $47)
ERROR42 DW $C000
ASC 'Too many open' ; $42 - File Control Block table full
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
ASC 'Channel not open' ; $43 - Invalid reference number
ERROR44 ; $44 - Path not found
ERROR46 DW $D600
ASC 'File not found' ; $46 - File not found
ASC 'File not found' ; $46 - File not found
ERROR45 DW $D600
ASC 'Disk not found' ; $45 - Volume directory not found
ASC 'Disk not found' ; $45 - Volume directory not found
ERROR47 DW $C400
ASC 'File exists' ; $47 - Duplicate filename (see also $41)
ASC 'File exists' ; $47 - Duplicate filename (see also $41)
ERROR48 DW $C600
ASC 'Disk full' ; $48 - Overrun error
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
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
ASC 'Disk not recognised' ; $52 - Not a ProDOS disk
ERROR4C DW $DF00
ASC 'End of file' ; $4C - End of file has been encountered
ASC 'End of file' ; $4C - End of file has been encountered
ERROR4D DW $C100
ASC 'Not open for update' ; $4D - Position out of range
ASC 'Not open for update' ; $4D - Position out of range
ERROR4E DW $BD00
ASC 'Insufficient access' ; $4E - Access error (see also $4F)
ASC 'Insufficient access' ; $4E - Access error (see also $4F)
ERROR4F DW $C300
ASC 'Entry locked' ; $4F - Access error (split from $4E)
ASC 'Entry locked' ; $4F - Access error (split from $4E)
ERROR50 DW $C200
ASC 'Can'
DB $27
ASC 't - file open' ; $50 - File is open
ASC 't - file open' ; $50 - File is open
ERROR51 DW $A800
ASC 'Broken directory' ; $51 - Directory count error
ASC 'Broken directory' ; $51 - Directory count error
ERROR53 DW $DC00
ASC 'Invalid parameter' ; $53 - Invalid parameter
ASC 'Invalid parameter' ; $53 - Invalid parameter
ERROR54 DW $D400
ASC 'Directory not empty' ; $54 - Directory not empty
ASC 'Directory not empty' ; $54 - Directory not empty
ERROR55 DW $FF00
ASC 'ProDOS: VCB full' ; $55 - Volume Control Block table full
ASC 'ProDOS: VCB full' ; $55 - Volume Control Block table full
ERROR56 DW $FF00
ASC 'ProDOS: Bad addr' ; $56 - Bad buffer address
ASC 'ProDOS: Bad addr' ; $56 - Bad buffer address
ERROR57 DW $FF00
ASC 'ProDOS: Dup volm' ; $57 - Duplicate volume
ERROR5B ; spare
ASC 'ProDOS: Dup volm' ; $57 - Duplicate volume
ERROR5B ; spare
ERROR27 DW $FF00
ASC 'I/O error' ; $27 - I/O error
ASC 'I/O error' ; $27 - I/O error
ERROR28 DW $D200
ASC 'Disk not present' ; $28 - No device detected/connected
ASC 'Disk not present' ; $28 - No device detected/connected
ERROR5A DW $FF00
ASC 'Sector not found' ; $5A - Bit map disk address is impossible
ASC 'Sector not found' ; $5A - Bit map disk address is impossible
ERROR2B DW $C900
ASC 'Disk write protected' ; $2B - Disk write protected
ASC 'Disk write protected'; $2B - Disk write protected
ERROR5D DW $CA00
ASC 'Data lost' ; $5D - EOF during LOAD or SAVE
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
ASC 't save' ; $5E - Couldn't open for save
ERROR2E DW $C800
ASC 'Disk changed' ; $2E - Disk switched
ASC 'Disk changed' ; $2E - Disk switched
DB $00

View File

@ -191,7 +191,7 @@ BYTE00 BEQ BYTE00A ; OSBYTE 0,0 - generate error
RTS ; %000x1xxx host type, 'A'pple
BYTE00A BRK
DB $F7
HELLO ASC 'Applecorn MOS 2021-10-23'
HELLO ASC 'Applecorn MOS 2021-10-24'
DB $00 ; Unify MOS messages

View File

@ -1,97 +1,70 @@
* AUXMEM.MOSEQU.S
* (c) Bobbi 2021 GPLv3
*
*******************************
* BBC MOS WORKSPACE LOCATIONS *
*******************************
* $00-$8F Language workspace
* $90-$9F Network workspace
* $A0-$A7 NMI workspace
* $A8-$AF Non-MOS *command workspace
* $B0-$BF Temporary filing system workspace
* $C0-$CF Persistant filing system workspace
* $D0-$DF VDU driver workspace
* $E0-$EE Internal MOS workspace
* $EF-$FF MOS API workspace
FSFLAG1 EQU $E2
FSFLAG2 EQU $E3
GSFLAG EQU $E4 ; $E4 GSREAD processing flags
GSCHAR EQU $E5 ; $E5 GSREAD accumulator
OSTEXT EQU $E6 ; $E6 => text string $E6 OSNUM+0
MAXLEN EQU OSTEXT+2 ; $E8 $E8 OSNUM+2
MINCHAR EQU OSTEXT+3 ; $E9 $E9 OSNUM+3
MAXCHAR EQU OSTEXT+4 ; $EA $EA OSPAD
OSTEMP EQU $EB ; $EB
OSKBD1 EQU $EC ; $EC kbd ws
OSKBD2 EQU OSKBD1+1 ; $ED kbd ws
OSKBD3 EQU OSKBD1+2 ; $EE kbd ws
OSAREG EQU $EF ; $EF A register
OSXREG EQU OSAREG+1 ; $F0 X register
OSYREG EQU OSXREG+1 ; $F1 Y register
OSCTRL EQU OSXREG ; $F0 (XY)=>control block
OSLPTR EQU $F2 ; $F2 => command line
*
OSINTWS EQU $FA ; $FA IRQ ZP pointer, use when IRQs off
OSINTA EQU $FC ; $FC IRQ register A store
FAULT EQU $FD ; $FD Error message pointer
ESCFLAG EQU $FF ; $FF Escape status
* $0200-$0235 Vectors
* $0236-$028F OSBYTE variables ($190+BYTENUM)
* $0290-$02ED
* $02EE-$02FF MOS control block
USERV EQU $200 ; USER vector
BRKV EQU $202 ; BRK vector
CLIV EQU $208 ; OSCLI vector
BYTEV EQU $20A ; OSBYTE vector
WORDV EQU $20C ; OSWORD vector
WRCHV EQU $20E ; OSWRCH vector
RDCHV EQU $210 ; OSRDCH vector
FILEV EQU $212 ; OSFILE vector
ARGSV EQU $214 ; OSARGS vector
BGETV EQU $216 ; OSBGET vector
BPUTV EQU $218 ; OSBPUT vector
GBPBV EQU $21A ; OSGBPB vector
FINDV EQU $21C ; OSFIND vector
FSCV EQU $21E ; FSCV misc file ops
BYTEVARBASE EQU $190 ; Base of OSBYTE variables
OSFILECB EQU $2EE ; OSFILE control block
* Moved to VDU
* COPYCHAR EQU OSKBD2 ; ** TEMP **
* $0300-$03DF
* $03E0-$03FF Used for interfacing with ProDOS XFER
* AUXMEM.MOSEQU.S
* (c) Bobbi 2021 GPLv3
*
*******************************
* BBC MOS WORKSPACE LOCATIONS *
*******************************
* $00-$8F Language workspace
* $90-$9F Network workspace
* $A0-$A7 NMI workspace
* $A8-$AF Non-MOS *command workspace
* $B0-$BF Temporary filing system workspace
* $C0-$CF Persistant filing system workspace
* $D0-$DF VDU driver workspace
* $E0-$EE Internal MOS workspace
* $EF-$FF MOS API workspace
FSFLAG1 EQU $E2
FSFLAG2 EQU $E3
GSFLAG EQU $E4 ; $E4 GSREAD processing flags
GSCHAR EQU $E5 ; $E5 GSREAD accumulator
OSTEXT EQU $E6 ; $E6 => text string $E6 OSNUM+0
MAXLEN EQU OSTEXT+2 ; $E8 $E8 OSNUM+2
MINCHAR EQU OSTEXT+3 ; $E9 $E9 OSNUM+3
MAXCHAR EQU OSTEXT+4 ; $EA $EA OSPAD
OSTEMP EQU $EB ; $EB $EB OSTEMP
OSKBD1 EQU $EC ; $EC kbd ws
OSKBD2 EQU OSKBD1+1 ; $ED kbd ws
OSKBD3 EQU OSKBD1+2 ; $EE kbd ws
OSAREG EQU $EF ; $EF A register
OSXREG EQU OSAREG+1 ; $F0 X register
OSYREG EQU OSXREG+1 ; $F1 Y register
OSCTRL EQU OSXREG ; $F0 (XY)=>control block
OSLPTR EQU $F2 ; $F2 => command line
OSROMNUM EQU $F4 ; $F4 current ROM
*
OSINTWS EQU $FA ; $FA IRQ ZP pointer, use when IRQs off
OSINTA EQU $FC ; $FC IRQ register A store
FAULT EQU $FD ; $FD Error message pointer
ESCFLAG EQU $FF ; $FF Escape status
* $0200-$0235 Vectors
* $0236-$028F OSBYTE variables ($190+BYTENUM)
* $0290-$02ED
* $02EE-$02FF MOS control block
USERV EQU $200 ; USER vector
BRKV EQU $202 ; BRK vector
CLIV EQU $208 ; OSCLI vector
BYTEV EQU $20A ; OSBYTE vector
WORDV EQU $20C ; OSWORD vector
WRCHV EQU $20E ; OSWRCH vector
RDCHV EQU $210 ; OSRDCH vector
FILEV EQU $212 ; OSFILE vector
ARGSV EQU $214 ; OSARGS vector
BGETV EQU $216 ; OSBGET vector
BPUTV EQU $218 ; OSBPUT vector
GBPBV EQU $21A ; OSGBPB vector
FINDV EQU $21C ; OSFIND vector
FSCV EQU $21E ; FSCV misc file ops
BYTEVARBASE EQU $190 ; Base of OSBYTE variables
OSFILECB EQU $2EE ; OSFILE control block
OSGBPBCB EQU OSFILECB+1 ; OSGBPB control block
* $0300-$03DF
* $03E0-$03FF Used for interfacing with ProDOS XFER

View File

@ -7,195 +7,194 @@
* A1L/A1H: Start address
* A2L/A2H: End address
* A4L/A4H: Destination start address
MEMCPY LDA (A1L)
STA (A4L)
LDA A1H
CMP A2H
BNE :S1
LDA A1L
CMP A2L
BNE :S1
BRA :DONE
:S1 INC A1L
BNE :S2
INC A1H
:S2 INC A4L
BNE :S3
INC A4H
:S3 BRA MEMCPY
:DONE RTS
MEMCPY LDA (A1L)
STA (A4L)
LDA A1H
CMP A2H
BNE :S1
LDA A1L
CMP A2L
BNE :S1
BRA :DONE
:S1 INC A1L
BNE :S2
INC A1H
:S2 INC A4L
BNE :S3
INC A4H
:S3 BRA MEMCPY
:DONE RTS
* Copy 512 bytes from BLKBUF to AUXBLK in aux LC
COPYAUXBLK >>> ALTZP ; Alt ZP & Alt LC on
LDY #$00
:L1 LDA BLKBUF,Y
STA $C005 ; Write aux mem
STA AUXBLK,Y
STA $C004 ; Write main mem
CPY #$FF
BEQ :S1
INY
BRA :L1
:S1 LDY #$00
:L2 LDA BLKBUF+$100,Y
STA $C005 ; Write aux mem
STA AUXBLK+$100,Y
STA $C004 ; Write main mem
CPY #$FF
BEQ :S2
INY
BRA :L2
:S2 >>> MAINZP ; Alt ZP off, ROM back in
RTS
COPYAUXBLK >>> ALTZP ; Alt ZP & Alt LC on
LDY #$00
:L1 LDA BLKBUF,Y
STA $C005 ; Write aux mem
STA AUXBLK,Y
STA $C004 ; Write main mem
CPY #$FF
BEQ :S1
INY
BRA :L1
:S1 LDY #$00
:L2 LDA BLKBUF+$100,Y
STA $C005 ; Write aux mem
STA AUXBLK+$100,Y
STA $C004 ; Write main mem
CPY #$FF
BEQ :S2
INY
BRA :L2
:S2 >>> MAINZP ; Alt ZP off, ROM back in
RTS
* Search FILEREFS for value in A
* On return, buffer number is in X (or $FF if no bufs)
FINDBUF LDX #$00
:L1 CMP FILEREFS,X
BEQ :END
INX
CPX #$04
BNE :L1
LDX #$FF ; $FF for not found
:END RTS
FINDBUF LDX #$00
:L1 CMP FILEREFS,X
BEQ :END
INX
CPX #$04
BNE :L1
LDX #$FF ; $FF for not found
:END RTS
* Obtain I/O buffer address
* On entry: buffer number in X
* On exit: buffer address in AY
* Carry set if no bufs, clear otherwise
BUFADDR CPX #$00
BNE :S1
LDA #<IOBUF1
LDY #>IOBUF1
BRA :EXIT
:S1 CPX #$01
BNE :S2
LDA #<IOBUF2
LDY #>IOBUF2
BRA :EXIT
:S2 CPX #$02
BNE :S3
LDA #<IOBUF3
LDY #>IOBUF3
BRA :EXIT
:S3 CPX #$03
BNE :NOBUFS
LDA #<IOBUF4
LDY #>IOBUF4
:EXIT CLC
RTS
:NOBUFS SEC
RTS
BUFADDR CPX #$00
BNE :S1
LDA #<IOBUF1
LDY #>IOBUF1
BRA :EXIT
:S1 CPX #$01
BNE :S2
LDA #<IOBUF2
LDY #>IOBUF2
BRA :EXIT
:S2 CPX #$02
BNE :S3
LDA #<IOBUF3
LDY #>IOBUF3
BRA :EXIT
:S3 CPX #$03
BNE :NOBUFS
LDA #<IOBUF4
LDY #>IOBUF4
:EXIT CLC
RTS
:NOBUFS SEC
RTS
* Check if file exists
* Return A=0 if doesn't exist, A=1 file, A=2 dir
EXISTS LDA #<MOSFILE
STA GINFOPL+1
LDA #>MOSFILE
STA GINFOPL+2
JSR GETINFO ; GET_FILE_INFO
BCS :NOEXIST
LDA GINFOPL+7 ; Storage type
CMP #$0D
BCS :DIR ; >= $0D
LDA #$01 ; File
RTS
:DIR LDA #$02
RTS
:NOEXIST LDA #$00
RTS
EXISTS LDA #<MOSFILE
STA GINFOPL+1
LDA #>MOSFILE
STA GINFOPL+2
JSR GETINFO ; GET_FILE_INFO
BCS :NOEXIST
LDA GINFOPL+7 ; Storage type
CMP #$0D
BCS :DIR ; >= $0D
LDA #$01 ; File
RTS
:DIR LDA #$02
RTS
:NOEXIST LDA #$00
RTS
* Copy FILEBLK to AUXBLK in aux memory
* Copy FILEBLK to OSFILECB in aux memory
* Preserves A
COPYFB PHA
LDX #$00
:L1 LDA FILEBLK,X
TAY
>>> ALTZP ; Alt ZP and LC
TYA
STA AUXBLK,X
>>> MAINZP ; Back to normal
INX
CPX #18 ; 18 bytes in FILEBLK
BNE :L1
PLA
RTS
COPYFB PHA
LDX #$11 ; 18 bytes in FILEBLK
* >>> WRTAUX ; Alt ZP and LC
>>> WRTAUX ; Write to Aux mem
:L1 LDA FILEBLK,X
* STA AUXBLK,X
STA OSFILECB,X
DEX
BPL :L1
* >>> MAINZP ; Back to normal
>>> WRTMAIN ; Back to Main mem
PLA
RTS
* Get file info
GETINFO JSR MLI
DB GINFOCMD
DW GINFOPL
RTS
GETINFO JSR MLI
DB GINFOCMD
DW GINFOPL
RTS
* Set file info
SETINFO LDA #$07 ; SET_FILE_INFO 7 parms
STA GINFOPL
JSR MLI
DB SINFOCMD
DW GINFOPL ; Re-use PL from GFI
LDA #$0A ; GET_FILE_INFO 10 parms
STA GINFOPL
RTS
SETINFO LDA #$07 ; SET_FILE_INFO 7 parms
STA GINFOPL
JSR MLI
DB SINFOCMD
DW GINFOPL ; Re-use PL from GFI
LDA #$0A ; GET_FILE_INFO 10 parms
STA GINFOPL
RTS
* Create disk file
* Uses filename in MOSFILE
CRTFILE JSR MLI ; GET_TIME
DB GTIMECMD
LDA #<MOSFILE
STA CREATEPL+1
LDA #>MOSFILE
STA CREATEPL+2
LDA #$C3 ; Open permissions
STA CREATEPL+3
LDA $BF90 ; Current date
STA CREATEPL+8
LDA $BF91
STA CREATEPL+9
LDA $BF92 ; Current time
STA CREATEPL+10
LDA $BF93
STA CREATEPL+11
JSR MLI
DB CREATCMD
DW CREATEPL
RTS
CRTFILE JSR MLI ; GET_TIME
DB GTIMECMD
LDA #<MOSFILE
STA CREATEPL+1
LDA #>MOSFILE
STA CREATEPL+2
LDA #$C3 ; Open permissions
STA CREATEPL+3
LDA $BF90 ; Current date
STA CREATEPL+8
LDA $BF91
STA CREATEPL+9
LDA $BF92 ; Current time
STA CREATEPL+10
LDA $BF93
STA CREATEPL+11
JSR MLI
DB CREATCMD
DW CREATEPL
RTS
* Open disk file
OPENMOSFILE LDA #<MOSFILE ; Open filename in MOSFILE
STA OPENPL+1
LDA #>MOSFILE
STA OPENPL+2
OPENFILE JSR MLI
DB OPENCMD
DW OPENPL
RTS
OPENMOSFILE LDA #<MOSFILE ; Open filename in MOSFILE
STA OPENPL+1
LDA #>MOSFILE
STA OPENPL+2
OPENFILE JSR MLI
DB OPENCMD
DW OPENPL
RTS
* Close disk file
CLSFILE JSR MLI
DB CLSCMD
DW CLSPL
RTS
CLSFILE JSR MLI
DB CLSCMD
DW CLSPL
RTS
* Read 512 bytes into BLKBUF
RDFILE JSR MLI
DB READCMD
DW READPL
RTS
RDFILE JSR MLI
DB READCMD
DW READPL
RTS
* Write data in BLKBUF to disk
WRTFILE JSR MLI
DB WRITECMD
DW WRITEPL
RTS
WRTFILE JSR MLI
DB WRITECMD
DW WRITEPL
RTS
* Put ProDOS prefix in PREFIX
GETPREF JSR MLI
DB GPFXCMD
DW GPFXPL
RTS
GETPREF JSR MLI
DB GPFXCMD
DW GPFXPL
RTS
* Map of file reference numbers to IOBUF1..4
FILEREFS DB $00,$00,$00,$00
FILEREFS DB $00,$00,$00,$00

View File

@ -15,64 +15,9 @@
* 16-Oct-2021 LOADFILE only reads object info once.
* 17-Oct-2021 SAVEFILE updated.
* 18-Oct-2021 Optimised CREATE, removed dead code, RDDATA and WRDATA.
INFOFILE >>> ENTMAIN
JSR PREPATH ; Preprocess path
JSR UPDFB ; Update FILEBLK
JSR COPYFB ; Copy back to aux mem
>>> XF2AUX,OSFILERET
* ProDOS file handling to delete a file
* Called by AppleMOS OSFILE
* Return A=0 no object, A=1 file deleted, A=2 dir deleted
* A>$1F ProDOS error
DELFILE >>> ENTMAIN
JSR PREPATH ; Preprocess pathname
JSR UPDFB ; Update FILEBLK
JSR COPYFB ; Copy back to aux mem
PHA ; Save object type
JSR DODELETE
BCC :DELETED
PLX ; Drop object
JSR CHKNOTFND
PHA
:DELETED PLA ; Get object back
:EXIT >>> XF2AUX,OSFILERET
DODELETE LDA #<MOSFILE ; Attempt to destroy file
STA DESTPL+1
LDA #>MOSFILE
STA DESTPL+2
JSR MLI
DB DESTCMD
DW DESTPL
RTS
* Returns $4E for 'Dir is not empty'
* Need to separate from 'Dir is locked'
* ProDOS file handling to create a directory
* Invoked by AppleMOS OSFILE
* Return A=$02 on success (ie: 'directory')
* A>$1F ProDOS error, translated by OSFILE handler
MAKEDIR >>> ENTMAIN
JSR PREPATH ; Preprocess pathname
JSR UPDFB ; Update FILEBLK
CMP #$02
BEQ :EXIT1 ; Dir already exists
LDA #$0D ; OBJT='Directory'
STA CREATEPL+7 ; ->Storage type
LDA #$0F ; TYPE='Directory'
LDX #$00 ; LOAD=$0000
LDY #$00
JSR CREATEOBJ
BCS :EXIT ; Failed, exit with ProDOS result
JSR UPDFB ; Update FILEBLK, returns A=$02
:EXIT1 JSR COPYFB ; Copy FILEBLK to aux mem
:EXIT >>> XF2AUX,OSFILERET
* 23-Oct-2021 Moved all the OSFILE routines together.
* Optimised entry and return from OSFILE routines.
* DELETE returns 'Dir not empty' when appropriate.
* ProDOS file handling to rename a file
@ -492,11 +437,107 @@ TELLEXIT >>> XF2AUX,OSARGSRET
ZPMOS EQU $30
* ProDOS file MOS OSFILE calls
CALLFILE >>> ENTMAIN
JSR FILEDISPATCH
>>> XF2AUX,OSFILERET
FILEDISPATCH CMP #$00
BEQ SVCSAVE ; A=00 -> SAVE
CMP #$FF
BEQ SVCLOAD ; A=FF -> LOAD
CMP #$06
BEQ DELFILE ; A=06 -> DELETE
BCC INFOFILE ; A=01-05 -> INFO
CMP #$08
BEQ MAKEDIR ; A=08 -> MKDIR
RTS
SVCSAVE JMP SAVEFILE
SVCLOAD JMP LOADFILE
INFOFILE
* >>> ENTMAIN
* JSR PREPATH ; Preprocess path
* JSR UPDFB ; Update FILEBLK
JSR UPDPATH ; Process path and get info
JMP COPYFB ; Copy back to aux mem
* >>> XF2AUX,OSFILERET
* ProDOS file handling to delete a file
* Called by AppleMOS OSFILE
* Return A=0 no object, A=1 file deleted, A=2 dir deleted
* A>$1F ProDOS error
DELFILE
* >>> ENTMAIN
* JSR PREPATH ; Preprocess path
* JSR UPDFB ; Update FILEBLK
JSR UPDPATH ; Process path and get info
JSR COPYFB ; Copy back to aux mem
PHA ; Save object type
JSR DODELETE
BCC :DELETED ; Success
TAX ; X=error code
PLA ; Get object back
CPX #$4E
BNE :DELERROR ; Not 'Insuff. access', return it
LDX #$4F ; Change to 'Locked'
CMP #$02
BNE :DELERROR ; Wasn't a directory, return 'Locked'
LDA FBATTR+0
AND #$08
BNE :DELERROR ; Dir locked, return 'Locked'
LDX #$54 ; Change to 'Dir not empty'
:DELERROR TXA
JSR CHKNOTFND
PHA
:DELETED PLA ; Get object back
:EXIT RTS
* >>> XF2AUX,OSFILERET
DODELETE LDA #<MOSFILE ; Attempt to destroy file
STA DESTPL+1
LDA #>MOSFILE
STA DESTPL+2
JSR MLI
DB DESTCMD
DW DESTPL
RTS
* ProDOS file handling to create a directory
* Invoked by AppleMOS OSFILE
* Return A=$02 on success (ie: 'directory')
* A>$1F ProDOS error, translated by OSFILE handler
MAKEDIR
* >>> ENTMAIN
* JSR PREPATH ; Preprocess path
* JSR UPDFB ; Update FILEBLK
JSR UPDPATH ; Process path and get info
CMP #$02
BEQ :EXIT1 ; Dir already exists
LDA #$0D ; OBJT='Directory'
STA CREATEPL+7 ; ->Storage type
LDA #$0F ; TYPE='Directory'
LDX #$00 ; LOAD=$0000
LDY #$00
JSR CREATEOBJ
BCS :EXIT ; Failed, exit with ProDOS result
JSR UPDFB ; Update FILEBLK, returns A=$02
:EXIT1 JSR COPYFB ; Copy FILEBLK to aux mem
:EXIT RTS
* >>> XF2AUX,OSFILERET
* ProDOS file handling for MOS OSFILE LOAD call
* Invoked by AppleMOS OSFILE
* Return A=01 if successful (meaning 'file')
* A>$1F ProDOS error, translated by FILERET
LOADFILE >>> ENTMAIN
LOADFILE
* >>> ENTMAIN
LDX #4
:LP LDA FBLOAD,X ; Get address to load to
STA ZPMOS,X
@ -514,7 +555,6 @@ LOADFILE >>> ENTMAIN
ADC #$41 ; 0->$46, 2->$41
:JMPEXIT JMP :EXIT2 ; Return error
* EXISTS has done GETINFO, so file info already loaded
:ISFILE LDA ZPMOS+4 ; If FBEXEC is zero, use addr
BEQ :CBADDR ; in the control block
LDA FBLOAD+0 ; Otherwise, use file's address
@ -522,47 +562,12 @@ LOADFILE >>> ENTMAIN
LDA FBLOAD+1
STA ZPMOS+1
:CBADDR
* LDA #<MOSFILE
* STA OPENPL+1
* LDA #>MOSFILE
* STA OPENPL+2
JSR OPENMOSFILE
:CBADDR JSR OPENMOSFILE
BCS :EXIT2 ; File not opened
:L1 LDA OPENPL+5 ; File ref number
JSR READDATA ; Read data from open file
* STA READPL+1
* JSR RDFILE
* BCS :READERR ; Close file and return any error
*
*:S1
** CLC
* LDA #<BLKBUF ; LSB of start of data buffer
* STA A1L ; A1=>start of data buffer
* ADC READPL+6 ; LSB of trans count
* STA A2L ; A2=>end of data buffer
* LDA #>BLKBUF
* STA A1H
* ADC READPL+7 ; MSB of trans count
* STA A2H
* LDA ZPMOS+0 ; A4=>address to load to
* STA A4L
* LDA ZPMOS+1
* STA A4H
* INC ZPMOS+1 ; Step to next block
* INC ZPMOS+1
*
* SEC ; Main -> AUX
* JSR AUXMOVE ; A4 updated to next address
* JMP :L1
*
*:READERR CMP #$4C
* BNE :EXITERR
*:EXITOK LDA #$00 ; $00=Success
*:EXITERR
PHA ; Save result
LDA OPENPL+5 ; File ref num
STA CLSPL+1
@ -571,7 +576,8 @@ LOADFILE >>> ENTMAIN
BNE :EXIT2
JSR COPYFB ; Copy FILEBLK to auxmem
LDA #$01 ; $01=File
:EXIT2 >>> XF2AUX,OSFILERET
:EXIT2 RTS
* >>> XF2AUX,OSFILERET
* A=channel, MOSZP+0/1=address to load to, TO DO: MOS+4/5=length to read
@ -612,18 +618,20 @@ READDATA STA READPL+1
:EXITOK LDA #$00 ; $00=Success
:EXITERR RTS
* ProDOS file handling for MOS OSFILE SAVE call
* Invoked by AppleMOS OSFILE
* Return A=01 if successful (ie: 'file')
* A>$1F ProDOS error translated by FILERET
SAVEFILE >>> ENTMAIN
SAVEFILE
* >>> ENTMAIN
SEC ; Compute file length
LDA FBEND+0
SBC FBSTRT+0
STA LENREM+0
STA :LENREM+0
LDA FBEND+1
SBC FBSTRT+1
STA LENREM+1
STA :LENREM+1
LDA FBEND+2
SBC FBSTRT+2
BNE :TOOBIG ; >64K
@ -655,10 +663,6 @@ SAVEFILE >>> ENTMAIN
LDY FBLOAD+1
JSR CREATEFILE
BCS :JMPEXIT2 ; Error trying to create
* LDA #<MOSFILE
* STA OPENPL+1
* LDA #>MOSFILE
* STA OPENPL+2
JSR OPENMOSFILE
BCS :JMPEXIT2 ; Error trying to open
LDA OPENPL+5 ; File ref number
@ -676,35 +680,36 @@ SAVEFILE >>> ENTMAIN
:EXIT2 CMP #$4E
BNE :EXIT3 ; Change 'Insuff. access'
LDA #$4F ; to 'Locked'
:EXIT3 >>> XF2AUX,OSFILERET
:EXIT3 RTS
* >>> XF2AUX,OSFILERET
:CANTSAVE LDA #$5E ; Can't open/create
BRA :EXIT3 ; TO DO: Error=File too long
* A=channel, FBSTRT+0/1=address to save from
* LENREM+0/1=length to write
* :LENREM+0/1=length to write
WRITEDATA STA WRITEPL+1
:L1 LDA #$00 ; 512 bytes request count
STA WRITEPL+4
LDA #$02
STA WRITEPL+5
LDA LENREM+1
LDA :LENREM+1
CMP #$02
BCS :L15 ; More than 511 bytes remaining
STA WRITEPL+5
LDA LENREM+0
LDA :LENREM+0
STA WRITEPL+4
ORA WRITEPL+5
BEQ :SAVEOK ; Zero bytes remaining
:L15 SEC
LDA LENREM+0 ; LENREM=LENREM-count
LDA :LENREM+0 ; LENREM=LENREM-count
SBC WRITEPL+4
STA LENREM+0
LDA LENREM+1
STA :LENREM+0
LDA :LENREM+1
SBC WRITEPL+5
STA LENREM+1
STA :LENREM+1
CLC
LDA FBSTRT+0
@ -738,7 +743,8 @@ WRITEDATA STA WRITEPL+1
JMP :L1 ; Loop back for next block
:SAVEOK ; Enter here with A=$00
:WRITEERR RTS
LENREM DW $0000 ; Remaining length
:LENREM DW $0000 ; Remaining length
CREATEFILE LDA #$01 ; Storage type - file
STA CREATEPL+7
@ -750,13 +756,16 @@ CREATEOBJ STA CREATEPL+4 ; Type = BIN or DIR
JMP CRTFILE
* Process pathname and read object info
UPDPATH JSR PREPATH ; Process pathname
BCC UPDFB ; If no error, update control block
RTS
* Update FILEBLK before returning to aux memory
* Returns A=object type or ProDOS error
UPDFB LDA #<MOSFILE
* STA OPENPL+1
STA GINFOPL+1
LDA #>MOSFILE
* STA OPENPL+2
STA GINFOPL+2
JSR GETINFO ; Call GET_FILE_INFO
BCC :UPDFB1
@ -864,11 +873,14 @@ QUIT INC $3F4 ; Invalidate powerup byte
RTS
* Used for *CAT, *EX and *INFO
* On entry: A=$5x *CAT, A=$9x *EX, A=$Ax *INFO
* On entry: b7=0 - short info (*CAT)
* b7=1 - long info (*INFO, *EX)
* b6=0 - single entry, parameter is object (*INFO)
* b6=1 - multiple items, parameter is dir (*CAT, *EX)
*
CATALOG >>> ENTMAIN
AND #$F0
STA CATARG ; Stash argument
CMP #$A0 ; Is it *INFO?
CMP #$80 ; Is it *INFO?
BNE :NOTINFO
JMP INFO ; Handle entry for *INFO
:NOTINFO LDA MOSFILE ; Length of pathname
@ -913,7 +925,7 @@ CATEXIT >>> XF2AUX,STARCATRET
CATALOGRET
>>> ENTMAIN
LDA CATARG
CMP #$A0 ; Is this an *INFO call?
CMP #$80 ; Is this an *INFO call?
BEQ INFOREENTRY
BRA CATREENTRY