mirror of
https://github.com/bobbimanners/Applecorn.git
synced 2024-11-05 17:04:40 +00:00
518 lines
16 KiB
ArmAsm
518 lines
16 KiB
ArmAsm
* AUXMEM.OSCLI.S
|
|
* (c) BOBBI 2021 GPLv3
|
|
*
|
|
* Handle OSCLI system calls
|
|
|
|
* 22-Aug-2021 Uses dispatch table
|
|
* Prepares parameters and hands on to API call
|
|
* 24-Aug-2021 Combined *LOAD and *SAVE, full address parsing.
|
|
|
|
|
|
* COMMAND TABLE
|
|
***************
|
|
* fsc commands
|
|
CMDTABLE ASC 'CAT' ; Must be first command so matches '*.'
|
|
DB $85
|
|
DW STARFSC-1 ; CAT -> FSC 5, XY=>params
|
|
ASC 'RUN'
|
|
DB $84
|
|
DW STARFSC-1 ; RUN -> FSC 4, XY=>params
|
|
ASC 'EX'
|
|
DB $89
|
|
DW STARFSC-1 ; EX -> FSC 9, XY=>params
|
|
ASC 'INFO'
|
|
DB $8A
|
|
DW STARFSC-1 ; INFO -> FSC 10, XY=>params
|
|
ASC 'RENAME'
|
|
DB $8C
|
|
DW STARFSC-1 ; RENAME -> FSC 12, XY=>params
|
|
* osfile commands
|
|
ASC 'LOAD'
|
|
DB $FF
|
|
DW STARLOAD-1 ; LOAD -> OSFILE FF, CBLK=>filename
|
|
ASC 'SAVE'
|
|
DB $FF
|
|
DW STARSAVE-1 ; SAVE -> OSFILE 00, CBLK=>filename
|
|
ASC 'DELETE'
|
|
DB $86
|
|
DW STARFILE-1 ; DELETE -> OSFILE 06, CBLK=>filename
|
|
ASC 'MKDIR'
|
|
DB $88
|
|
DW STARFILE-1 ; MKDIR -> OSFILE 08, CBLK=>filename
|
|
ASC 'CDIR'
|
|
DB $88
|
|
DW STARFILE-1 ; CDIR -> OSFILE 08, CBLK=>filename
|
|
* other filing commands
|
|
ASC 'CHDIR'
|
|
DB $C0
|
|
DW STARCHDIR-1 ; Should be a FSC call, XY=>params
|
|
ASC 'DIR'
|
|
DB $C0
|
|
DW STARCHDIR-1 ; Should be a FSC call, XY=>params
|
|
ASC 'DRIVE'
|
|
DB $C1
|
|
DW STARDRIVE-1 ; Should be a FSC call, XY=>params
|
|
* osbyte commands
|
|
ASC 'FX'
|
|
DB $80
|
|
DW STARFX-1 ; FX -> OSBYTE A,X,Y (LPTR)=>params
|
|
ASC 'OPT'
|
|
DB $8B
|
|
DW STARBYTE-1 ; OPT -> OSBYTE &8B,X,Y XY=>params
|
|
* others
|
|
ASC 'QUIT'
|
|
DB $80
|
|
DW STARQUIT-1 ; QUIT -> (LPTR)=>params
|
|
ASC 'HELP'
|
|
DB $80
|
|
DW STARHELP-1 ; HELP -> (LPTR)=>params
|
|
ASC 'BASIC'
|
|
DB $80
|
|
DW STARBASIC-1 ; BASIC -> (LPTR)=>params
|
|
ASC 'KEY'
|
|
DB $80
|
|
DW STARKEY-1 ; KEY -> (LPTR)=>params
|
|
* terminator
|
|
DB $00
|
|
|
|
|
|
* OSCLI HANDLER
|
|
* On entry, XY=>command string
|
|
* On exit, AXY corrupted or error generated
|
|
*
|
|
CLIHND JSR XYtoLPTR ; LPTR=>command line
|
|
CLILP1 LDA (OSLPTR),Y
|
|
CMP #$0D
|
|
BEQ CLI2
|
|
INY
|
|
BNE CLILP1
|
|
CLIEXIT1 RTS ; No terminating <cr>
|
|
CLI2 LDY #0
|
|
CLILP2 LDA (OSLPTR),Y
|
|
INY
|
|
CMP #' ' ; Skip leading spaces
|
|
BEQ CLILP2
|
|
CMP #'*' ; Skip leading stars
|
|
BEQ CLILP2
|
|
CMP #$0D
|
|
BEQ CLIEXIT1 ; Null string
|
|
CMP #'|'
|
|
BEQ CLIEXIT1 ; Comment
|
|
CMP #'/'
|
|
BEQ CLISLASH
|
|
DEY
|
|
JSR LPTRtoXY ; Add Y to LPTR
|
|
JSR XYtoLPTR ; LPTR=>start of actual command
|
|
*
|
|
* Search command table
|
|
LDX #0 ; Start of command table
|
|
CLILP4 LDY #0 ; Start of command line
|
|
CLILP5 LDA CMDTABLE,X
|
|
BEQ CLIUNKNOWN ; End of command table
|
|
BMI CLIMATCH ; End of table string
|
|
EOR (OSLPTR),Y
|
|
AND #$DF ; Force upper case match
|
|
BNE CLINOMATCH
|
|
INX ; Step to next table char
|
|
INY ; Step to next command char
|
|
BNE CLILP5 ; Loop to check
|
|
|
|
CLINOMATCH LDA (OSLPTR),Y
|
|
CMP #'.' ; Abbreviation?
|
|
BEQ CLIDOT
|
|
CLINEXT INX ; No match, step to next entry
|
|
LDA CMDTABLE,X
|
|
BPL CLINEXT
|
|
CLINEXT2 INX ; Step past byte, address
|
|
INX
|
|
INX
|
|
BNE CLILP4 ; Loop to check next
|
|
|
|
CLIDOT LDA CMDTABLE,X
|
|
BMI CLINEXT2 ; Dot after full word, no match
|
|
CLIDOT2 INX ; Step to command address
|
|
LDA CMDTABLE,X
|
|
BPL CLIDOT2
|
|
INY ; Step past dot
|
|
BNE CLIMATCH2 ; Jump to this command
|
|
|
|
CLIMATCH LDA (OSLPTR),Y
|
|
CMP #'.'
|
|
BEQ CLINEXT ; Longer abbreviation, eg 'CAT.'
|
|
CMP #'A'
|
|
BCS CLINEXT ; More letters, eg 'HELPER'
|
|
CLIMATCH2 JSR SKIPSPC ; (OSLPTR),Y=>parameters
|
|
LDA CMDTABLE+2,X ; Push destination address
|
|
PHA
|
|
LDA CMDTABLE+1,X
|
|
PHA
|
|
LDA CMDTABLE+0,X ; A=command parameter
|
|
PHA
|
|
ASL A ; Drop bit 7
|
|
BEQ CLICALL ; If $80 don't convert LPTR
|
|
JSR LPTRtoXY ; XY=>parameters
|
|
CLICALL PLA ; A=command parameter
|
|
CLIDONE RTS
|
|
|
|
CLISLASH JSR SKIPSPC
|
|
BEQ CLIDONE ; */<cr>
|
|
LDA #$02
|
|
BNE STARFSC2 ; FSC 2 = */filename
|
|
|
|
CLIUNKNOWN LDA #$04
|
|
JSR SERVICE ; Offer to sideways ROM(s)
|
|
BEQ CLIDONE ; Claimed
|
|
LDA #$03 ; FSC 3 = unknown command
|
|
STARFSC2 PHA
|
|
JSR LPTRtoXY ; XY=>command
|
|
PLA
|
|
STARFSC AND #$7F ; A=command, XY=>parameters
|
|
JSR CALLFSCV ; Hand on to filing system
|
|
* TO DO: hostfs.s needs to return A=0
|
|
TAX
|
|
BEQ CLIDONE
|
|
RTS ; *TEMP*
|
|
ERRBADCMD BRK
|
|
DB $FE
|
|
ASC 'Bad command'
|
|
ERRBADNUM BRK
|
|
DB $FC
|
|
ASC 'Bad number'
|
|
ERRBADADD BRK
|
|
DB $FC
|
|
ASC 'Bad address'
|
|
BRK
|
|
|
|
CALLFSCV JMP (FSCV) ; Hand on to filing system
|
|
|
|
|
|
* *FX num(,num(,num))
|
|
*********************
|
|
STARFX JSR SCANDEC
|
|
BRA STARBYTE1
|
|
|
|
* Commands passed to OSBYTE
|
|
***************************
|
|
STARBYTE JSR XYtoLPTR
|
|
STARBYTE1 STA OSAREG ; Save OSBYTE number
|
|
LDA #$00 ; Default X and Y
|
|
STA OSXREG
|
|
STA OSYREG
|
|
JSR SKIPCOMMA ; Step past any comma/spaces
|
|
BEQ STARBYTE2 ; End of line, do it
|
|
JSR SCANDEC ; Scan for X param
|
|
STA OSXREG ; Store it
|
|
JSR SKIPCOMMA ; Step past any comma/spaces
|
|
BEQ STARBYTE2 ; End of line, do it
|
|
JSR SCANDEC ; Scan for Y param
|
|
STA OSYREG ; Store it
|
|
JSR SKIPSPC
|
|
BNE ERRBADCMD ; More params, error
|
|
STARBYTE2 LDY OSYREG
|
|
LDX OSXREG
|
|
LDA OSAREG
|
|
JSR OSBYTE
|
|
BVS ERRBADCMD
|
|
RTS
|
|
|
|
* Scan decimal number
|
|
SCANDEC JSR SKIPSPC
|
|
JSR SCANDIGIT ; Check first digit
|
|
BCS ERRBADNUM ; Doesn't start with a digit
|
|
SCANDECLP STA OSTEMP ; Store as current number
|
|
JSR SCANDIGIT ; Check next digit
|
|
BCS SCANDECOK ; No more digits
|
|
PHA
|
|
LDA OSTEMP
|
|
CMP #26
|
|
BCS ERRBADNUM ; num>25, num*25>255
|
|
ASL A ; num*2
|
|
ASL A ; num*4
|
|
ADC OSTEMP ; num*4+num = num*5
|
|
ASL A ; num*10
|
|
STA OSTEMP
|
|
PLA
|
|
ADC OSTEMP ; num=num*10+digit
|
|
BCC SCANDECLP
|
|
BCS ERRBADNUM ; Overflowed
|
|
|
|
SCANDECOK LDA OSTEMP ; Return A=number
|
|
SCANDIG2 SEC
|
|
RTS
|
|
|
|
SCANDIGIT LDA (OSLPTR),Y
|
|
CMP #'0'
|
|
BCC SCANDIG2 ; <'0'
|
|
CMP #'9'+1
|
|
BCS SCANDIG2 ; >'9'
|
|
INY
|
|
AND #$0F
|
|
RTS
|
|
|
|
HEXDIGIT JSR SCANDIGIT
|
|
BCC HEXDIGIT2 ; Decimal digit
|
|
AND #$DF
|
|
CMP #'A'
|
|
BCC SCANDIG2 ; Bad hex character
|
|
CMP #'G'
|
|
BCS HEXDIGIT2 ; Bad hex character
|
|
SBC #$36 ; Convert 'A'-'F' to $0A-$0F
|
|
INY
|
|
CLC
|
|
HEXDIGIT2 RTS
|
|
|
|
* Scan hex address
|
|
* (OSLPTR),Y=>first character
|
|
* $200,X = 4-byte accumulator
|
|
SCANHEX JSR HEXDIGIT ; Get first digit
|
|
BCS ERRBADADD1 ; Not a hex character
|
|
STA $200,X ; Store first digit
|
|
LDA #0
|
|
STA $201,X ; Clear rest of accumulator
|
|
STA $202,X
|
|
STA $203,X
|
|
SCANHEXLP1 JSR HEXDIGIT ; Get next digit
|
|
BCS SKIPSPC ; Done, exit by skipping spaces
|
|
STY OSTEMP
|
|
LDY #4 ; Four bits to rotate
|
|
SCANHEXLP2 ASL $200,X ; Multiple accumulator by 16
|
|
ROL $201,X
|
|
ROL $202,X
|
|
ROL $203,X
|
|
BCS ERRBADADD1 ; Overflowed
|
|
DEY
|
|
BNE SCANHEXLP2 ; Loop for four bits
|
|
ORA $200,X ; Add in current digit
|
|
STA $200,X
|
|
LDY OSTEMP ; Get Y back
|
|
BNE SCANHEXLP1
|
|
ERRBADADD1 JMP ERRBADADD
|
|
|
|
SKIPCOMMA LDA (OSLPTR),Y
|
|
CMP #$2C
|
|
BNE SKIPSPC
|
|
*
|
|
* Skip spaces
|
|
SKIPSPCLP INY ; Step past space or comma
|
|
SKIPSPC LDA (OSLPTR),Y
|
|
CMP #' '
|
|
BEQ SKIPSPCLP
|
|
CMP #$0D ; Return EQ=<cr>
|
|
RTS
|
|
|
|
* Convert (LPTR),Y to XY
|
|
LPTRtoXY CLC
|
|
TYA
|
|
ADC OSLPTR+0
|
|
TAX
|
|
LDA #0
|
|
ADC OSLPTR+1
|
|
TAY
|
|
RTS
|
|
|
|
* Convert XY to (LPTR),Y
|
|
XYtoLPTR STX OSLPTR+0
|
|
STY OSLPTR+1
|
|
LDY #0
|
|
RTS
|
|
|
|
* Print *HELP text
|
|
* These needs tidying a bit
|
|
STARHELP PHY
|
|
LDA #<HELPMSG
|
|
LDY #>HELPMSG
|
|
JSR PRSTR
|
|
PLY
|
|
PHY
|
|
LDA (OSLPTR),Y
|
|
CMP #'.'
|
|
BEQ STARHELP1
|
|
INY
|
|
EOR (OSLPTR),Y
|
|
INY
|
|
EOR (OSLPTR),Y
|
|
AND #$DF
|
|
CMP #$51
|
|
BNE STARHELP5
|
|
STARHELP1 LDX #0
|
|
LDA #32
|
|
JSR OSWRCH
|
|
JSR OSWRCH
|
|
STARHELPLP1 LDY #10
|
|
LDA CMDTABLE,X
|
|
BEQ STARHELP4
|
|
STARHELPLP2 LDA CMDTABLE,X
|
|
BMI STARHELP3
|
|
JSR OSWRCH
|
|
DEY
|
|
INX
|
|
BNE STARHELPLP2
|
|
STARHELP3 LDA #32
|
|
JSR OSWRCH
|
|
DEY
|
|
BNE STARHELP3
|
|
INX
|
|
INX
|
|
INX
|
|
BNE STARHELPLP1
|
|
STARHELP4 JSR OSNEWL
|
|
STARHELP5 LDA $8006
|
|
BMI STARHELP6 ; Use ROM's service entry
|
|
JSR OSNEWL
|
|
LDA #$09 ; Language name
|
|
LDY #$80
|
|
JSR PRSTR
|
|
LDA #<HELPMSG2
|
|
LDY #>HELPMSG2
|
|
JSR PRSTR
|
|
STARHELP6 PLY
|
|
LDA #9
|
|
JMP SERVICE ; Pass to sideways ROM(s)
|
|
HELPMSG DB $0D
|
|
ASC 'Applecorn MOS v0.01'
|
|
DB $0D,$00
|
|
HELPMSG2 DB $0D,$00
|
|
|
|
* Handle *QUIT command
|
|
STARQUIT >>> XF2MAIN,QUIT
|
|
|
|
|
|
STARSAVE LDA #$00 ; Set A=0 - SAVE
|
|
STARLOAD PHA ; Entered with A=$FF - LOAD
|
|
JSR XYtoLPTR ; OSLPTR=>filename
|
|
* replace with with GSREAD
|
|
LDA (OSLPTR),Y
|
|
CMP #34
|
|
BEQ STARLDSVA
|
|
LDA #32
|
|
STARLDSVA STA OSTEMP
|
|
STARLDSV0
|
|
INY
|
|
LDA (OSLPTR),Y
|
|
CMP #13
|
|
BEQ STARLDSV1
|
|
CMP OSTEMP
|
|
BNE STARLDSV0 ; Step past filename
|
|
* ^^^^
|
|
JSR SKIPSPCLP ; Skip following spaces
|
|
BNE STARLDSV3 ; *load/save name addr
|
|
STARLDSV1 LDA #$FF ; $FF=load to file's address
|
|
STARLOAD2
|
|
STA OSFILECB+6
|
|
PLA
|
|
BEQ ERRBADADD2 ; *save name <no addr>
|
|
LDA #$7F ; Will become A=$FF
|
|
JMP STARLDSVGO ; Do the load
|
|
|
|
* load address exists
|
|
STARLDSV3
|
|
LDX #OSFILECB+2-$200 ; X=>load
|
|
JSR SCANHEX
|
|
BNE STARSAVE3 ; another address
|
|
LDA #$00 ; $00=load to supplied address
|
|
BEQ STARLOAD2 ; Do the load
|
|
|
|
* More than one address, must be *SAVE
|
|
STARSAVE3
|
|
PLA
|
|
BNE ERRBADADD2 ; Can't be *LOAD
|
|
LDX #3
|
|
STARSAVE4
|
|
LDA OSFILECB+2,X ; Get load
|
|
STA OSFILECB+6,X ; copy to exec
|
|
STA OSFILECB+10,X ; and to start
|
|
DEX
|
|
BPL STARSAVE4
|
|
LDA (OSLPTR),Y
|
|
CMP #'+'
|
|
PHP
|
|
BNE STARSAVE5 ; Not start+length
|
|
JSR SKIPSPCLP ; Step past '+' and spaces
|
|
STARSAVE5
|
|
LDX #OSFILECB+14-$200
|
|
JSR SCANHEX ; Get end or length
|
|
PLP
|
|
BNE STARSAVE7 ; Not +length
|
|
LDX #0
|
|
CLC
|
|
STARSAVE6
|
|
LDA OSFILECB+10,X ; end=start+length
|
|
ADC OSFILECB+14,X
|
|
STA OSFILECB+14,X
|
|
INX
|
|
TXA
|
|
AND #3
|
|
BNE STARSAVE6
|
|
STARSAVE7
|
|
* load =start
|
|
* exec =start
|
|
* start=start
|
|
* end =end or start+length
|
|
JSR SKIPSPC
|
|
BEQ STARSAVE10 ; No more, do it
|
|
LDX #OSFILECB+6-$200
|
|
JSR SCANHEX ; Get exec
|
|
BEQ STARSAVE10 ; No more, do it
|
|
LDX #OSFILECB+2-$200
|
|
JSR SCANHEX ; Get load
|
|
BEQ STARSAVE10 ; No more, do it
|
|
ERRBADADD2 JMP ERRBADADD ; Too many parameters
|
|
|
|
STARSAVE10
|
|
LDA #$80 ; Will become $00 - SAVE
|
|
STARLDSVGO
|
|
LDX OSLPTR+0
|
|
LDY OSLPTR+1
|
|
*
|
|
|
|
* Commands passed to OSFILE
|
|
***************************
|
|
STARFILE EOR #$80
|
|
STX OSFILECB+0
|
|
STY OSFILECB+1
|
|
LDX #<OSFILECB
|
|
LDY #>OSFILECB
|
|
JMP OSFILE
|
|
|
|
STARCHDIR STX ZP1+0 ; TEMP
|
|
STY ZP1+1 ; TEMP
|
|
LDY #$00 ; TEMP
|
|
JMP STARDIR ; TEMP
|
|
|
|
STARDRIVE
|
|
STARBASIC
|
|
STARKEY RTS
|
|
|
|
|
|
|
|
** Handle *CAT / *. command (list directory)
|
|
*STARCAT LDA #$05
|
|
* JMP JUMPFSCV ; Hand on to filing system
|
|
|
|
|
|
* Code that calls this will need to be replaced with calls
|
|
* to SKIPSPC and GSREAD
|
|
*
|
|
* Consume spaces in command line. Treat " as space!
|
|
* Return C set if no space found, C clear otherwise
|
|
* Command line pointer in (ZP1),Y
|
|
EATSPC LDA (ZP1),Y ; Check first char is ...
|
|
CMP #' ' ; ... space
|
|
BEQ :START
|
|
CMP #'"' ; Or quote mark
|
|
BEQ :START
|
|
BRA :NOTFND
|
|
:START INY
|
|
:L1 LDA (ZP1),Y ; Eat any additional ...
|
|
CMP #' ' ; ... spaces
|
|
BEQ :CONT
|
|
CMP #'"' ; Or quote marks
|
|
BNE :DONE
|
|
:CONT INY
|
|
BRA :L1
|
|
:DONE CLC
|
|
RTS
|
|
:NOTFND SEC
|
|
RTS
|
|
|