Big reorganization of MAINMEM.S - split into 5

This commit is contained in:
Bobbi Webber-Manners 2021-09-06 22:28:07 -04:00
parent eb457b70af
commit cf14641c6d
17 changed files with 562 additions and 636 deletions

Binary file not shown.

View File

@ -165,7 +165,12 @@ MAINZP MAC
* ... order matters!
PUT MAINMEM.LDR
PUT MAINMEM.MENU
PUT MAINMEM
PUT MAINMEM.FSEQU
PUT MAINMEM.INIT
PUT MAINMEM.SVC
PUT MAINMEM.PATH
PUT MAINMEM.LISTS
PUT MAINMEM.MISC
PUT AUXMEM.MOSEQU
PUT AUXMEM.INIT
PUT AUXMEM.VDU
@ -178,5 +183,3 @@ MAINZP MAC
* Automatically save the object file:
SAV APPLECORN

View File

@ -535,3 +535,7 @@ OSBM2 ASC ').'

View File

@ -439,3 +439,7 @@ KBDDONE RTS

View File

@ -895,3 +895,7 @@ ERROR2E DW $C800

View File

@ -152,3 +152,7 @@ HELLO ASC 'Applecorn MOS 2021-09-06 snapshot'

View File

@ -466,3 +466,7 @@ AUXBLK ASC '**ENDOFCODE**'

View File

@ -68,3 +68,7 @@ OSFILECB EQU $2EE ; OSFILE control block

View File

@ -568,3 +568,7 @@ ECHO3 PHP

View File

@ -497,3 +497,7 @@ BYTEA0 LDY #79 ; Read VDU variable $09,$0A

View File

@ -1,5 +1,5 @@
#!/bin/sh
for file in APPLECORN AUXMEM.BYTWRD AUXMEM.CHARIO AUXMEM.HOSTFS AUXMEM.INIT AUXMEM.MISC AUXMEM.MOSEQU AUXMEM.OSCLI AUXMEM.VDU LOADER MAINMEM MAIN.ROMMENU; do
for file in APPLECORN AUXMEM.BYTWRD AUXMEM.CHARIO AUXMEM.HOSTFS AUXMEM.INIT AUXMEM.MISC AUXMEM.MOSEQU AUXMEM.OSCLI AUXMEM.VDU MAINMEM.FSEQU MAINMEM.INIT MAINMEM.LDR MAINMEM.LISTS MAINMEM.MENU MAINMEM.MISC MAINMEM.PATH MAINMEM.SVC; do
cadius extractfile applecorn.po /APPLECORN/${file}.S .
rm _FileInformation.txt
cadius clearhighbit ${file}.S\#040000

96
mainmem.init.s Normal file
View File

@ -0,0 +1,96 @@
* MAINMEM.INIT.S
* (c) Bobbi 2021 GPLv3
*
* Initialization, interrupt handling and reset handling code
* that resides in main memory.
* Trampoline in main memory used by aux memory IRQ handler
* to invoke Apple II / ProDOS IRQs in main memory
A2IRQ >>> IENTMAIN ; IENTMAIN does not do CLI
JSR A2IRQ2
>>> XF2AUX,IRQBRKRET
A2IRQ2 PHP ; Fake things to look like IRQ
JMP (A2IRQV) ; Call Apple II ProDOS ISR
* BRK handler in main memory. Used on Apple IIgs only.
GSBRK >>> XF2AUX,GSBRKAUX
* Set prefix if not already set
SETPRFX LDA #GPFXCMD
STA :OPC7 ; Initialize cmd byte to $C7
:L1 JSR MLI
:OPC7 DB $00
DW GSPFXPL
LDX DRVBUF1 ; was $0300
BNE RTSINST
LDA $BF30
STA ONLNPL+1 ; Device number
JSR MLI
DB ONLNCMD
DW ONLNPL
LDA DRVBUF2 ; was $0301
AND #$0F
TAX
INX
STX DRVBUF1 ; was $0300
LDA #$2F
STA DRVBUF2 ; was $0301
DEC :OPC7
BNE :L1
RTSINST RTS
* Disconnect /RAM ramdrive to avoid aux corruption
* Stolen from Beagle Bros Extra K
DISCONN LDA $BF98
AND #$30
CMP #$30
BNE :S1
LDA $BF26
CMP $BF10
BNE :S2
LDA $BF27
CMP $BF11
BEQ :S1
:S2 LDY $BF31
:L1 LDA $BF32,Y
AND #$F3
CMP #$B3
BEQ :S3
DEY
BPL :L1
BMI :S1
:S3 LDA $BF32,Y
STA DRVBUF2+1 ; was $0302
:L2 LDA $BF33,Y
STA $BF32,Y
BEQ :S4
INY
BNE :L2
:S4 LDA $BF26
STA DRVBUF1 ; was $0300
LDA $BF27
STA DRVBUF2 ; was $0301
LDA $BF10
STA $BF26
LDA $BF11
STA $BF27
DEC $BF31
:S1 RTS
* Reset handler - invoked on Ctrl-Reset
* XFER to AUXMOS ($C000) in aux, AuxZP on, LC on
RESET TSX
STX $0100
LDA $C058 ; AN0 off
LDA $C05A ; AN1 off
LDA $C05D ; AN2 on
LDA $C05F ; AN3 on
LDA #$20 ; PAGE2 shadow on ROM3 GS
TRB $C035
>>> XF2AUX,AUXMOS
RTS

View File

@ -1,12 +1,13 @@
* LOADER.S
* MAINMEM.LDR.S
* (c) Bobbi 2021 GPLv3
*
* Applecorn loader code
* Applecorn loader code. Runs in main memory.
* Loads Acorn ROM file (16KB) from disk and writes it
* to aux memory starting at $08000. Copies Applecorn MOS
* to aux memory starting at AUXMOS1 and jumps to it.
* (Note that the MOS code will copy itself to $D000.)
START JSR ROMMENU
STZ :BLOCKS
@ -118,3 +119,7 @@ CANTOPEN ASC "Unable to open ROM file"

View File

@ -1,7 +1,7 @@
* MAIN.ROMMENU.S
* MAINMEM.MENU.S
* (c) Bobbi 2021 GPL3
*
* Applecorn ROM menu
* Applecorn ROM menu. Runs in main memory.
ROMMENU JSR HOME ; Clear screen
LDA #<TITLE1 ; Print title
@ -125,3 +125,7 @@ ROM8 STR "USERROM2.ROM"

132
mainmem.misc.s Normal file
View File

@ -0,0 +1,132 @@
* MAINMEM.MISC.S
* (c) Bobbi 2021 GPLv3
*
* Miscellaneous routines used by main memory code.
* 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
* Search FILEREFS for value in A
FINDBUF LDX #$00
:L1 CMP FILEREFS,X
BEQ :END
INX
CPX #$04
BNE :L1
LDX #$FF ; $FF for not found
:END RTS
* Check if file exists
* Return A=0 if doesn't exist, A=1 file, A=2 fir
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
* 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
* Get file info
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
* Create disk file
CRTFILE JSR MLI
DB CREATCMD
DW CREATEPL
RTS
* Open disk file
OPENFILE JSR MLI
DB OPENCMD
DW OPENPL
RTS
* Close disk file
CLSFILE JSR MLI
DB CLSCMD
DW CLSPL
RTS
* Read 512 bytes into BLKBUF
RDFILE JSR MLI
DB READCMD
DW READPL
RTS
* Write data in BLKBUF to disk
WRTFILE JSR MLI
DB WRITECMD
DW WRITEPL
RTS
* Put ProDOS prefix in PREFIX
GETPREF JSR MLI
DB GPFXCMD
DW GPFXPL
RTS
* Map of file reference numbers to IOBUF1..4
FILEREFS DB $00,$00,$00,$00

276
mainmem.path.s Normal file
View File

@ -0,0 +1,276 @@
* MAINMEM.PATH.S
* (c) Bobbi 2021 GPLv3
*
* Code for handling Applecorn paths and converting them to
* ProDOS paths. Runs in main memory.
* Preprocess path in MOSFILE, handling '..' sequence
* dir/file.ext filesystem, so '..' means parent dir (eg: '../SOMEDIR')
* Also allows '^' as '^' is illegal character in ProDOS
* Carry set on error, clear otherwise
PREPATH LDX MOSFILE ; Length
BEQ :EXIT ; If zero length
LDA MOSFILE+1 ; 1st char of pathname
CMP #$3A ; ':'
BNE :NOTCOLN ; Not colon
CPX #$03 ; Length >= 3?
BCC :ERR ; If not
LDA MOSFILE+3 ; Drive
SEC
SBC #'1'
TAX
LDA MOSFILE+2 ; Slot
SEC
SBC #'0'
JSR DRV2PFX ; Slot/drv->pfx in PREFIX
JSR DEL1CHAR ; Delete ':' from MOSFILE
JSR DEL1CHAR ; Delete slot from MOSFILE
JSR DEL1CHAR ; Delete drive from MOSFILE
LDA MOSFILE ; Is there more?
BEQ :APPEND ; Only ':sd'
CMP #$02 ; Length >= 2
BCC :ERR ; If not
LDA MOSFILE+1 ; 1st char of filename
CMP #$2F ; '/'
BNE :ERR
JSR DEL1CHAR ; Delete '/' from MOSFILE
BRA :APPEND
:NOTCOLN JSR GETPREF ; Current pfx -> PREFIX
:REENTER LDA MOSFILE+1 ; First char of dirname
CMP #'.'
BEQ :UPDIR1
CMP #$5E ; '^' char
BEQ :CARET ; If '^'
CMP #$2F ; '/' char - abs path
BEQ :EXIT ; Nothing to do
BRA :APPEND
:UPDIR1 LDA MOSFILE+2
CMP #'.' ; '..'
BNE :EXIT
JSR DEL1CHAR ; Delete two leading characters
:CARET JSR DEL1CHAR ; Delete '^' from MOSFILE
JSR PARENT ; Parent dir -> MOSFILE
LDA MOSFILE ; Is there more?
BEQ :APPEND ; Only '^'
CMP #$02 ; Len at least two?
BCC :ERR ; Nope!
LDA MOSFILE+1 ; What is next char?
CMP #$2F ; Is it slash?
BNE :ERR ; Nope!
JSR DEL1CHAR ; Delete '/' from MOSFILE
BRA :REENTER ; Go again!
:APPEND JSR APFXMF ; Append MOSFILE->PREFIX
JSR COPYPFXMF ; Copy back to MOSFILE
:EXIT JSR DIGCONV ; Handle initial digits
CLC
RTS
:ERR SEC
RTS
* Convert path in PREFIX by removing leaf dir to leave
* parent directory. If already at top, return unchanged.
PARENT LDX PREFIX ; Length of string
BEQ :EXIT ; Prefix len zero
DEX ; Ignore trailing '/'
:L1 LDA PREFIX,X
CMP #$2F ; Slash '/'
BEQ :FOUND
DEX
CPX #$01
BNE :L1
BRA :EXIT ; No slash found
:FOUND STX PREFIX ; Truncate string
:EXIT RTS
* Convert slot/drive to prefix
* Expect slot number (1..7) in A, drive (0..1) in X
* Puts prefix (or empty string) in PREFIX
DRV2PFX CLC ; Cy=0 A=00000sss
ROR A ; s 000000ss
ROR A ; s s000000s
ROR A ; s ss000000
ROR A ; 0 sss00000
CPX #1 ; d sss00000
ROR A ; 0 dsss0000
STA ONLNPL+1 ; Device number
JSR MLI ; Call ON_LINE
DB ONLNCMD
DW ONLNPL ; Buffer set to DRVBUF2 (was $301)
LDA DRVBUF2 ; Slot/Drive/Length
AND #$0F ; Mask to get length
TAX
INC ; Plus '/' at each end
INC
STA PREFIX ; Store length
LDA #$2F ; '/'
STA PREFIX+1
STA PREFIX+2,X
:L1 CPX #$00 ; Copy -> PREFIX
BEQ :EXIT
LDA DRVBUF2,X
STA PREFIX+1,X
DEX
BRA :L1
:EXIT RTS
* Delete first char of MOSFILE
DEL1CHAR LDX MOSFILE ; Length
BEQ :EXIT ; Nothing to delete
LDY #$02 ; Second char
:L1 CPY MOSFILE
BEQ :S2 ; If Y=MOSFILE okay
BCS :S1 ; If Y>MOSFILE done
:S2 LDA MOSFILE,Y
STA MOSFILE-1,Y
INY
BRA :L1
:S1 DEC MOSFILE
:EXIT RTS
* Append MOSFILE to PREFIX
APFXMF LDY PREFIX ; Length of PREFIX
LDX #$00 ; Index into MOSFILE
:L1 CPX MOSFILE ; Length of MOSFILE
BEQ :DONE
LDA MOSFILE+1,X
STA PREFIX+1,Y
INX
INY
BRA :L1
:DONE STY PREFIX ; Update length PREFIX
RTS
* Scan pathname in MOSFILE converting files/dirs
* starting with digit by adding 'N' before.
DIGCONV LDY #$01 ; First char
:L1 CPY MOSFILE ; String length
BEQ :KEEPON ; Last char
BCS :DONE ; Y>MOSFILE
:KEEPON LDA MOSFILE,Y ; Load char
JSR ISDIGIT ; Is it a digit?
BCC :NOINS ; No .. skip
CPY #$01 ; First char?
BEQ :INS ; First char is digit
LDA MOSFILE-1,Y ; Prev char
CMP #$2F ; Slash
BEQ :INS ; Slash followed by digit
BRA :NOINS ; Otherwise leave it alone
:INS LDA #'N' ; Char to insert
JSR INSMF ; Insert it
INY
:NOINS INY ; Next char
BRA :L1
:DONE RTS
* Is char in A a digit? Set carry if so
ISDIGIT CMP #'9'+1
BCS :NOTDIG
CMP #'0'
BCC :NOTDIG
SEC
RTS
:NOTDIG CLC
RTS
* Insert char in A into MOSFILE at posn Y
* Preserves regs
INSMF PHA ; Preserve char
STY :INSIDX ; Stash index for later
LDY MOSFILE ; String length
INY ; Start with Y=len+1
:L1 CPY :INSIDX ; Back to ins point?
BEQ :S1 ; Yes, done moving
LDA MOSFILE-1,Y ; Move one char
STA MOSFILE,Y
DEY
BRA :L1
:S1 PLA ; Char to insert
STA MOSFILE,Y ; Insert it
INC MOSFILE ; One char longer
RTS
:INSIDX DB $00
* Copy Pascal-style string
* Source in A1L/A1H, dest in A4L/A4H
STRCPY LDY #$00
LDA (A1L),Y ; Length of source
STA (A4L),Y ; Copy length byte
TAY
:L1 CPY #$00
BEQ :DONE
LDA (A1L),Y
STA (A4L),Y
DEY
BRA :L1
:DONE RTS
* Copy MOSFILE to MFTEMP
MFtoTMP LDA #<MOSFILE
STA A1L
LDA #>MOSFILE
STA A1H
LDA #<MFTEMP
STA A4L
LDA #>MFTEMP
STA A4H
JSR STRCPY
RTS
* Copy MFTEMP to MOSFILE1
TMPtoMF LDA #<MFTEMP
STA A1L
LDA #>MFTEMP
STA A1H
LDA #<MOSFILE
STA A4L
LDA #>MOSFILE
STA A4H
JSR STRCPY
RTS
* Copy MOSFILE to MOSFILE2
COPYMF12 LDA #<MOSFILE
STA A1L
LDA #>MOSFILE
STA A1H
LDA #<MOSFILE2
STA A4L
LDA #>MOSFILE2
STA A4H
JSR STRCPY
RTS
* Copy MOSFILE2 to MOSFILE
COPYMF21 LDA #<MOSFILE2
STA A1L
LDA #>MOSFILE2
STA A1H
LDA #<MOSFILE
STA A4L
LDA #>MOSFILE
STA A4H
JSR STRCPY
RTS
* Copy PREFIX to MOSFILE
COPYPFXMF
LDA #<PREFIX
STA A1L
LDA #>PREFIX
STA A1H
LDA #<MOSFILE
STA A4L
LDA #>MOSFILE
STA A4H
JSR STRCPY
RTS
MFTEMP DS 65 ; Temp copy of MOSFILE
PREFIX DS 65 ; Buffer for ProDOS prefix

View File

@ -1,172 +1,9 @@
* MAINMEM.S
* (c) Bobbi 2021 GPL v3
* MAINMEM.SVC.S
* (c) Bobbi 2021 GPLv3
*
* Code that runs on the Apple //e in main memory.
* This code is mostly glue between the BBC Micro code
* which runs in aux mem and Apple II ProDOS.
* 24-Aug-2021 AUXTYPE set from load address
* 27-Aug-2021 Delete and MkDir return ProDOS result to caller
* 29-Aug-2021 All calls (seem to) return ProDOS result to caller
* Set ?&E0=255 for testing to report ProDOS result
* 30-Aug-2021 INFOFILE semi-implemented, UPDFB returns moddate
* Lots of tidying up possible once confirmed code working
* ProDOS string buffers
RTCBUF EQU $0200 ; Use by RTC calls, 40 bytes
* ; $0228-$023D
DRVBUF1 EQU $023E
DRVBUF2 EQU $023F ; Prefix on current drive, len+64
CMDPATH EQU $0280 ; Path used to start Applecorn
* Filename string buffers
MOSFILE1 EQU $0300 ; length + 64 bytes
MOSFILE2 EQU $0341 ; length + 64 bytes
MOSFILE EQU MOSFILE1
* $0382 ; $3C bytes here
*
FILEBLK EQU $03BE
FBPTR EQU FILEBLK+0 ; Pointer to name (in aux)
FBLOAD EQU FILEBLK+2 ; Load address
FBEXEC EQU FILEBLK+6 ; Exec address
FBSIZE EQU FILEBLK+10 ; Size
FBSTRT EQU FILEBLK+10 ; Start address for SAVE
FBATTR EQU FILEBLK+14 ; Attributes
FBEND EQU FILEBLK+14 ; End address for SAVE
* ProDOS MLI command numbers
QUITCMD EQU $65
GTIMECMD EQU $82
CREATCMD EQU $C0
DESTCMD EQU $C1
RENCMD EQU $C2
SINFOCMD EQU $C3
GINFOCMD EQU $C4
ONLNCMD EQU $C5
SPFXCMD EQU $C6
GPFXCMD EQU $C7
OPENCMD EQU $C8
READCMD EQU $CA
WRITECMD EQU $CB
CLSCMD EQU $CC
FLSHCMD EQU $CD
SMARKCMD EQU $CE
GMARKCMD EQU $CF
GEOFCMD EQU $D1
* Trampoline in main memory used by aux memory IRQ handler
* to invoke Apple II / ProDOS IRQs in main memory
A2IRQ >>> IENTMAIN ; IENTMAIN does not do CLI
JSR A2IRQ2
>>> XF2AUX,IRQBRKRET
A2IRQ2 PHP ; Fake things to look like IRQ
JMP (A2IRQV) ; Call Apple II ProDOS ISR
* BRK handler in main memory. Used on Apple IIgs only.
GSBRK >>> XF2AUX,GSBRKAUX
* Set prefix if not already set
SETPRFX LDA #GPFXCMD
STA :OPC7 ; Initialize cmd byte to $C7
:L1 JSR MLI
:OPC7 DB $00
DW GSPFXPL
LDX DRVBUF1 ; was $0300
BNE RTSINST
LDA $BF30
STA ONLNPL+1 ; Device number
JSR MLI
DB ONLNCMD
DW ONLNPL
LDA DRVBUF2 ; was $0301
AND #$0F
TAX
INX
STX DRVBUF1 ; was $0300
LDA #$2F
STA DRVBUF2 ; was $0301
DEC :OPC7
BNE :L1
RTSINST RTS
* Disconnect /RAM ramdrive to avoid aux corruption
* Stolen from Beagle Bros Extra K
DISCONN LDA $BF98
AND #$30
CMP #$30
BNE :S1
LDA $BF26
CMP $BF10
BNE :S2
LDA $BF27
CMP $BF11
BEQ :S1
:S2 LDY $BF31
:L1 LDA $BF32,Y
AND #$F3
CMP #$B3
BEQ :S3
DEY
BPL :L1
BMI :S1
:S3 LDA $BF32,Y
STA DRVBUF2+1 ; was $0302
:L2 LDA $BF33,Y
STA $BF32,Y
BEQ :S4
INY
BNE :L2
:S4 LDA $BF26
STA DRVBUF1 ; was $0300
LDA $BF27
STA DRVBUF2 ; was $0301
LDA $BF10
STA $BF26
LDA $BF11
STA $BF27
DEC $BF31
:S1 RTS
* Reset handler - invoked on Ctrl-Reset
* XFER to AUXMOS ($C000) in aux, AuxZP on, LC on
RESET TSX
STX $0100
LDA $C058 ; AN0 off
LDA $C05A ; AN1 off
LDA $C05D ; AN2 on
LDA $C05F ; AN3 on
LDA #$20 ; PAGE2 shadow on ROM3 GS
TRB $C035
>>> XF2AUX,AUXMOS
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
* Main memory entry points called by Applecorn MOS running in
* aux memory. Each entry point performs some ProDOS service,
* then returns to aux memory.
* TO DO: All OSFILE calls combined and dispatch in here
* All start with PREPATH, UPDFB, COPYFB then branch
@ -365,19 +202,6 @@ CFILE >>> ENTMAIN
STA FILEREFS,X
:S1 JMP FINDEXIT
* Map of file reference numbers to IOBUF1..4
FILEREFS DB $00,$00,$00,$00
* Search FILEREFS for value in A
FINDBUF LDX #$00
:L1 CMP FILEREFS,X
BEQ :END
INX
CPX #$04
BNE :L1
LDX #$FF ; $FF for not found
:END RTS
* ProDOS file handling for MOS OSBGET call
* Returns with char read in A and error num in Y (or 0)
FILEGET >>> ENTMAIN
@ -591,40 +415,6 @@ LOADFILE >>> ENTMAIN
>>> XF2AUX,OSFILERET
:BLOCKS DB $00
* Check if file exists
* Return A=0 if doesn't exist, A=1 file, A=2 fir
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
* 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
* ProDOS file handling for MOS OSFILE SAVE call
* Invoked by AppleMOS OSFILE
* Return A=01 if successful (ie: 'file')
@ -938,70 +728,6 @@ CATALOGRET
>>> ENTMAIN
BRA CATREENTRY
* Preprocess path in MOSFILE, handling '..' sequence
* dir/file.ext filesystem, so '..' means parent dir (eg: '../SOMEDIR')
* Also allows '^' as '^' is illegal character in ProDOS
* Carry set on error, clear otherwise
PREPATH LDX MOSFILE ; Length
BEQ :EXIT ; If zero length
LDA MOSFILE+1 ; 1st char of pathname
CMP #$3A ; ':'
BNE :NOTCOLN ; Not colon
CPX #$03 ; Length >= 3?
BCC :ERR ; If not
LDA MOSFILE+3 ; Drive
SEC
SBC #'1'
TAX
LDA MOSFILE+2 ; Slot
SEC
SBC #'0'
JSR DRV2PFX ; Slot/drv->pfx in PREFIX
JSR DEL1CHAR ; Delete ':' from MOSFILE
JSR DEL1CHAR ; Delete slot from MOSFILE
JSR DEL1CHAR ; Delete drive from MOSFILE
LDA MOSFILE ; Is there more?
BEQ :APPEND ; Only ':sd'
CMP #$02 ; Length >= 2
BCC :ERR ; If not
LDA MOSFILE+1 ; 1st char of filename
CMP #$2F ; '/'
BNE :ERR
JSR DEL1CHAR ; Delete '/' from MOSFILE
BRA :APPEND
:NOTCOLN JSR GETPREF ; Current pfx -> PREFIX
:REENTER LDA MOSFILE+1 ; First char of dirname
CMP #'.'
BEQ :UPDIR1
CMP #$5E ; '^' char
BEQ :CARET ; If '^'
CMP #$2F ; '/' char - abs path
BEQ :EXIT ; Nothing to do
BRA :APPEND
:UPDIR1 LDA MOSFILE+2
CMP #'.' ; '..'
BNE :EXIT
JSR DEL1CHAR ; Delete two leading characters
:CARET JSR DEL1CHAR ; Delete '^' from MOSFILE
JSR PARENT ; Parent dir -> MOSFILE
LDA MOSFILE ; Is there more?
BEQ :APPEND ; Only '^'
CMP #$02 ; Len at least two?
BCC :ERR ; Nope!
LDA MOSFILE+1 ; What is next char?
CMP #$2F ; Is it slash?
BNE :ERR ; Nope!
JSR DEL1CHAR ; Delete '/' from MOSFILE
BRA :REENTER ; Go again!
:APPEND JSR APFXMF ; Append MOSFILE->PREFIX
JSR COPYPFXMF ; Copy back to MOSFILE
:EXIT JSR DIGCONV ; Handle initial digits
CLC
RTS
:ERR SEC
RTS
* Set prefix. Used by *CHDIR to change directory
SETPFX >>> ENTMAIN
JSR PREPATH ; Preprocess pathname
@ -1098,257 +824,6 @@ SETPERM >>> ENTMAIN
:WFLAG DB $00 ; 'W' attribute
:RFLAG DB $00 ; 'R' attribute
* Get file info
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
* Create disk file
CRTFILE JSR MLI
DB CREATCMD
DW CREATEPL
RTS
* Open disk file
OPENFILE JSR MLI
DB OPENCMD
DW OPENPL
RTS
* Close disk file
CLSFILE JSR MLI
DB CLSCMD
DW CLSPL
RTS
* Read 512 bytes into BLKBUF
RDFILE JSR MLI
DB READCMD
DW READPL
RTS
* Write data in BLKBUF to disk
WRTFILE JSR MLI
DB WRITECMD
DW WRITEPL
RTS
* Put ProDOS prefix in PREFIX
GETPREF JSR MLI
DB GPFXCMD
DW GPFXPL
RTS
* Convert path in PREFIX by removing leaf dir to leave
* parent directory. If already at top, return unchanged.
PARENT LDX PREFIX ; Length of string
BEQ :EXIT ; Prefix len zero
DEX ; Ignore trailing '/'
:L1 LDA PREFIX,X
CMP #$2F ; Slash '/'
BEQ :FOUND
DEX
CPX #$01
BNE :L1
BRA :EXIT ; No slash found
:FOUND STX PREFIX ; Truncate string
:EXIT RTS
* Convert slot/drive to prefix
* Expect slot number (1..7) in A, drive (0..1) in X
* Puts prefix (or empty string) in PREFIX
DRV2PFX CLC ; Cy=0 A=00000sss
ROR A ; s 000000ss
ROR A ; s s000000s
ROR A ; s ss000000
ROR A ; 0 sss00000
CPX #1 ; d sss00000
ROR A ; 0 dsss0000
STA ONLNPL+1 ; Device number
JSR MLI ; Call ON_LINE
DB ONLNCMD
DW ONLNPL ; Buffer set to DRVBUF2 (was $301)
LDA DRVBUF2 ; Slot/Drive/Length
AND #$0F ; Mask to get length
TAX
INC ; Plus '/' at each end
INC
STA PREFIX ; Store length
LDA #$2F ; '/'
STA PREFIX+1
STA PREFIX+2,X
:L1 CPX #$00 ; Copy -> PREFIX
BEQ :EXIT
LDA DRVBUF2,X
STA PREFIX+1,X
DEX
BRA :L1
:EXIT RTS
* Delete first char of MOSFILE
DEL1CHAR LDX MOSFILE ; Length
BEQ :EXIT ; Nothing to delete
LDY #$02 ; Second char
:L1 CPY MOSFILE
BEQ :S2 ; If Y=MOSFILE okay
BCS :S1 ; If Y>MOSFILE done
:S2 LDA MOSFILE,Y
STA MOSFILE-1,Y
INY
BRA :L1
:S1 DEC MOSFILE
:EXIT RTS
* Append MOSFILE to PREFIX
APFXMF LDY PREFIX ; Length of PREFIX
LDX #$00 ; Index into MOSFILE
:L1 CPX MOSFILE ; Length of MOSFILE
BEQ :DONE
LDA MOSFILE+1,X
STA PREFIX+1,Y
INX
INY
BRA :L1
:DONE STY PREFIX ; Update length PREFIX
RTS
* Scan pathname in MOSFILE converting files/dirs
* starting with digit by adding 'N' before.
DIGCONV LDY #$01 ; First char
:L1 CPY MOSFILE ; String length
BEQ :KEEPON ; Last char
BCS :DONE ; Y>MOSFILE
:KEEPON LDA MOSFILE,Y ; Load char
JSR ISDIGIT ; Is it a digit?
BCC :NOINS ; No .. skip
CPY #$01 ; First char?
BEQ :INS ; First char is digit
LDA MOSFILE-1,Y ; Prev char
CMP #$2F ; Slash
BEQ :INS ; Slash followed by digit
BRA :NOINS ; Otherwise leave it alone
:INS LDA #'N' ; Char to insert
JSR INSMF ; Insert it
INY
:NOINS INY ; Next char
BRA :L1
:DONE RTS
* Is char in A a digit? Set carry if so
ISDIGIT CMP #'9'+1
BCS :NOTDIG
CMP #'0'
BCC :NOTDIG
SEC
RTS
:NOTDIG CLC
RTS
* Insert char in A into MOSFILE at posn Y
* Preserves regs
INSMF PHA ; Preserve char
STY :INSIDX ; Stash index for later
LDY MOSFILE ; String length
INY ; Start with Y=len+1
:L1 CPY :INSIDX ; Back to ins point?
BEQ :S1 ; Yes, done moving
LDA MOSFILE-1,Y ; Move one char
STA MOSFILE,Y
DEY
BRA :L1
:S1 PLA ; Char to insert
STA MOSFILE,Y ; Insert it
INC MOSFILE ; One char longer
RTS
:INSIDX DB $00
* Copy Pascal-style string
* Source in A1L/A1H, dest in A4L/A4H
STRCPY LDY #$00
LDA (A1L),Y ; Length of source
STA (A4L),Y ; Copy length byte
TAY
:L1 CPY #$00
BEQ :DONE
LDA (A1L),Y
STA (A4L),Y
DEY
BRA :L1
:DONE RTS
* Copy MOSFILE to MFTEMP
MFtoTMP LDA #<MOSFILE
STA A1L
LDA #>MOSFILE
STA A1H
LDA #<MFTEMP
STA A4L
LDA #>MFTEMP
STA A4H
JSR STRCPY
RTS
* Copy MFTEMP to MOSFILE1
TMPtoMF LDA #<MFTEMP
STA A1L
LDA #>MFTEMP
STA A1H
LDA #<MOSFILE
STA A4L
LDA #>MOSFILE
STA A4H
JSR STRCPY
RTS
* Copy MOSFILE to MOSFILE2
COPYMF12 LDA #<MOSFILE
STA A1L
LDA #>MOSFILE
STA A1H
LDA #<MOSFILE2
STA A4L
LDA #>MOSFILE2
STA A4H
JSR STRCPY
RTS
* Copy MOSFILE2 to MOSFILE
COPYMF21 LDA #<MOSFILE2
STA A1L
LDA #>MOSFILE2
STA A1H
LDA #<MOSFILE
STA A4L
LDA #>MOSFILE
STA A4H
JSR STRCPY
RTS
* Copy PREFIX to MOSFILE
COPYPFXMF
LDA #<PREFIX
STA A1L
LDA #>PREFIX
STA A1H
LDA #<MOSFILE
STA A4L
LDA #>MOSFILE
STA A4H
JSR STRCPY
RTS
* Read mainmem from auxmem
MACHRD LDA $C081
LDA $C081
@ -1366,104 +841,7 @@ MAINRDMEM STA A1L
MAINRDEXIT >>> XF2AUX,NULLRTS ; Back to an RTS
******************************************************
* ProDOS Parameter lists for MLI calls
******************************************************
OPENPL HEX 03 ; Number of parameters
DW $0000 ; Pointer to filename
DW IOBUF0 ; Pointer to IO buffer
DB $00 ; Reference number returned
OPENPL2 HEX 03 ; Number of parameters
DW $0000 ; Pointer to filename
DW $0000 ; Pointer to IO buffer
DB $00 ; Reference number returned
CREATEPL HEX 07 ; Number of parameters
DW $0000 ; Pointer to filename
DB $00 ; Access
DB $00 ; File type
DW $0000 ; Aux type
DB $00 ; Storage type
DW $0000 ; Create date
DW $0000 ; Create time
DESTPL HEX 01 ; Number of parameters
DW $0000 ; Pointer to filename
RENPL HEX 02 ; Number of parameters
DW $0000 ; Pointer to existing name
DW $0000 ; Pointer to new filename
READPL HEX 04 ; Number of parameters
DB $00 ; Reference number
DW BLKBUF ; Pointer to data buffer
DW 512 ; Request count
DW $0000 ; Trans count
READPL2 HEX 04 ; Number of parameters
DB #00 ; Reference number
DW BLKBUF ; Pointer to data buffer
DW 1 ; Request count
DW $0000 ; Trans count
WRITEPL HEX 04 ; Number of parameters
DB $01 ; Reference number
DW BLKBUF ; Pointer to data buffer
DW $00 ; Request count
DW $0000 ; Trans count
CLSPL HEX 01 ; Number of parameters
DB $00 ; Reference number
FLSHPL HEX 01 ; Number of parameters
DB $00 ; Reference number
ONLNPL HEX 02 ; Number of parameters
DB $00 ; Unit num
DW DRVBUF2 ; Buffer
GSPFXPL HEX 01 ; Number of parameters
DW DRVBUF1 ; Buffer
GPFXPL HEX 01 ; Number of parameters
DW PREFIX ; Buffer
SPFXPL HEX 01 ; Number of parameters
DW MOSFILE ; Buffer
GMARKPL HEX 02 ; Number of parameters
DB $00 ; File reference number
DB $00 ; Mark (24 bit)
DB $00
DB $00
GEOFPL HEX 02 ; Number of parameters
DB $00 ; File reference number
DB $00 ; EOF (24 bit)
DB $00
DB $00
GINFOPL HEX 0A ; Number of parameters
DW $0000 ; Pointer to filename
DB $00 ; Access
DB $00 ; File type
DW $0000 ; Aux type
DB $00 ; Storage type
DW $0000 ; Blocks used
DW $0000 ; Mod date
DW $0000 ; Mod time
DW $0000 ; Create date
DW $0000 ; Create time
QUITPL HEX 04 ; Number of parameters
DB $00
DW $0000
DB $00
DW $0000
MFTEMP DS 65 ; Temp copy of MOSFILE
PREFIX DS 65 ; Buffer for ProDOS prefix