mirror of
https://github.com/bobbimanners/Applecorn.git
synced 2024-11-10 18:05:38 +00:00
337 lines
9.7 KiB
ArmAsm
337 lines
9.7 KiB
ArmAsm
* MAINMEM.PATH.S
|
|
* (c) Bobbi 2021 GPLv3
|
|
*
|
|
* Code for handling Applecorn paths and converting them to
|
|
* ProDOS paths. Runs in main memory.
|
|
* TO DO: check range in :sd
|
|
* TO DO: need separate reference to current root and drive by name
|
|
* TO DO: check for pathname too long
|
|
* ie /filename should be filename in root
|
|
|
|
|
|
* Preprocess path in MOSFILE, handles:
|
|
* 1) ':sd' type slot and drive prefix (s,d are digits)
|
|
* 2) '.' or '@' for current working directory
|
|
* 3) '..' or '^' for parent directory
|
|
* Carry set on error, clear otherwise
|
|
PREPATH LDX MOSFILE ; Length
|
|
BNE :S1
|
|
JMP :EXIT ; If zero length
|
|
:S1 LDA MOSFILE+1 ; 1st char of pathname
|
|
CMP #':'
|
|
BNE :NOTCOLN ; Not colon
|
|
CPX #$03 ; Length >= 3?
|
|
BCS :S2
|
|
JMP :ERR ; If not
|
|
:S2 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 #'/'
|
|
BNE :ERR
|
|
JSR DEL1CHAR ; Delete '/' from MOSFILE
|
|
BRA :APPEND
|
|
:NOTCOLN JSR GETPREF ; Current pfx -> PREFIX
|
|
:REENTER LDA MOSFILE+1 ; First char of dirname
|
|
CMP #'@' ; '@' means current working dir
|
|
BEQ :CWD
|
|
CMP #'^' ; '^' means parent dir
|
|
BEQ :CARET
|
|
CMP #'/' ; Absolute path
|
|
BEQ :EXIT ; Nothing to do
|
|
CMP #'.' ; ...
|
|
BEQ :UPDIR1
|
|
BRA :APPEND
|
|
:UPDIR1 LDA MOSFILE ; Length
|
|
CMP #$01
|
|
BEQ :CWD ; '.' on its own
|
|
LDA MOSFILE+2
|
|
CMP #'.' ; '..'
|
|
BEQ :DOTDOT
|
|
CMP #'/' ; './'
|
|
BEQ :CWD
|
|
BRA :ERR
|
|
:DOTDOT JSR DEL1CHAR ; Delete first char of MOSFILE
|
|
:CARET JSR PARENT ; Parent dir -> PREFIX
|
|
:CWD JSR DEL1CHAR ; Delete first char of MOSFILE
|
|
LDA MOSFILE ; Is there more?
|
|
BEQ :APPEND ; No more
|
|
CMP #$02 ; Len at least two?
|
|
BCC :ERR ; Too short!
|
|
LDA MOSFILE+1 ; What is next char?
|
|
CMP #'/' ; Is it slash?
|
|
BNE :ERR ; Nope!
|
|
JSR DEL1CHAR ; Delete '/' from MOSFILE
|
|
BRA :REENTER ; Go again!
|
|
:APPEND JSR APFXMF ; Append MOSFILE->PREFIX
|
|
JSR PFXtoMF ; Copy back to MOSFILE
|
|
:EXIT JSR DIGCONV ; Handle initial digits
|
|
JSR USCONV ; Handle any underscores
|
|
CLC
|
|
RTS
|
|
:ERR LDA #$40 ; $40=Bad filename
|
|
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 #'/'
|
|
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 #'/'
|
|
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 '_' to '.'
|
|
USCONV LDX MOSFILE ; Length
|
|
BEQ :EXIT ; Nothing to replace
|
|
:L1 LDA MOSFILE,X
|
|
CMP #'_'
|
|
BNE :S1
|
|
LDA #'.'
|
|
STA MOSFILE,X
|
|
:S1 DEX
|
|
BNE :L1
|
|
:EXIT 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 #'/' ; 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 MOSFILE
|
|
TMPtoMF LDA #<MFTEMP
|
|
STA A1L
|
|
LDA #>MFTEMP
|
|
STA A1H
|
|
LDA #<MOSFILE
|
|
STA A4L
|
|
LDA #>MOSFILE
|
|
STA A4H
|
|
JSR STRCPY
|
|
RTS
|
|
|
|
* Copy MFTEMP to MOSFILE2
|
|
TMPtoMF2 LDA #<MFTEMP
|
|
STA A1L
|
|
LDA #>MFTEMP
|
|
STA A1H
|
|
LDA #<MOSFILE2
|
|
STA A4L
|
|
LDA #>MOSFILE2
|
|
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
|
|
PFXtoMF 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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|