diff --git a/applecorn.po b/applecorn.po index 936eb35..22c6b88 100644 Binary files a/applecorn.po and b/applecorn.po differ diff --git a/auxmem.hostfs.s b/auxmem.hostfs.s index b5a2f53..07b1b06 100644 --- a/auxmem.hostfs.s +++ b/auxmem.hostfs.s @@ -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+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' - LDX AUXBLK+0 ; Blocks used + JSR OUTSTR ; Print 'free' + 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' + JMP OUTSTR ; Print 'used' * 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 - diff --git a/auxmem.init.s b/auxmem.init.s index 41ff2e2..1c7c2cb 100644 --- a/auxmem.init.s +++ b/auxmem.init.s @@ -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 diff --git a/auxmem.mosequ.s b/auxmem.mosequ.s index 6adc7fc..8532a5e 100644 --- a/auxmem.mosequ.s +++ b/auxmem.mosequ.s @@ -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 diff --git a/mainmem.misc.s b/mainmem.misc.s index e961385..f64423b 100644 --- a/mainmem.misc.s +++ b/mainmem.misc.s @@ -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 - BRA :EXIT -:S1 CPX #$01 - BNE :S2 - LDA #IOBUF2 - BRA :EXIT -:S2 CPX #$02 - BNE :S3 - LDA #IOBUF3 - BRA :EXIT -:S3 CPX #$03 - BNE :NOBUFS - LDA #IOBUF4 -:EXIT CLC - RTS -:NOBUFS SEC - RTS +BUFADDR CPX #$00 + BNE :S1 + LDA #IOBUF1 + BRA :EXIT +:S1 CPX #$01 + BNE :S2 + LDA #IOBUF2 + BRA :EXIT +:S2 CPX #$02 + BNE :S3 + LDA #IOBUF3 + BRA :EXIT +:S3 CPX #$03 + BNE :NOBUFS + LDA #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+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+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+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+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 - STA OPENPL+2 -OPENFILE JSR MLI - DB OPENCMD - DW OPENPL - RTS +OPENMOSFILE 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 diff --git a/mainmem.svc.s b/mainmem.svc.s index cc6ed4d..0589fa9 100644 --- a/mainmem.svc.s +++ b/mainmem.svc.s @@ -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 - 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 + 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+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 #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+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+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