Applecorn/auxmem.oscli.s

528 lines
17 KiB
ArmAsm
Raw Normal View History

2021-08-15 03:42:06 +00:00
* AUXMEM.OSCLI.S
* (c) BOBBI 2021 GPLv3
*
2021-08-15 03:42:06 +00:00
* Handle OSCLI system calls
* 22-Aug-2021 Uses dispatch table
* Prepares parameters and hands on to API call
2021-08-25 02:01:41 +00:00
* 24-Aug-2021 Combined *LOAD and *SAVE, full address parsing.
* COMMAND TABLE
***************
* Table structure is: { string, byte OR $80, destword-1 } $00
* fsc commands
2021-08-25 02:01:41 +00:00
CMDTABLE ASC 'CAT' ; Must be first command so matches '*.'
DB $85
2021-08-25 02:01:41 +00:00
DW STARFSC-1 ; CAT -> FSC 5, XY=>params
ASC 'RUN'
DB $84
2021-08-25 02:01:41 +00:00
DW STARFSC-1 ; RUN -> FSC 4, XY=>params
ASC 'EX'
DB $89
2021-08-25 02:01:41 +00:00
DW STARFSC-1 ; EX -> FSC 9, XY=>params
ASC 'INFO'
DB $8A
2021-08-25 02:01:41 +00:00
DW STARFSC-1 ; INFO -> FSC 10, XY=>params
ASC 'RENAME'
DB $8C
2021-08-25 02:01:41 +00:00
DW STARFSC-1 ; RENAME -> FSC 12, XY=>params
* osfile commands
ASC 'LOAD'
DB $FF
2021-08-25 02:01:41 +00:00
DW STARLOAD-1 ; LOAD -> OSFILE FF, CBLK=>filename
ASC 'SAVE'
DB $FF
2021-08-25 02:01:41 +00:00
DW STARSAVE-1 ; SAVE -> OSFILE 00, CBLK=>filename
ASC 'DELETE'
DB $86
2021-08-25 02:01:41 +00:00
DW STARFILE-1 ; DELETE -> OSFILE 06, CBLK=>filename
ASC 'MKDIR'
DB $88
2021-08-25 02:01:41 +00:00
DW STARFILE-1 ; MKDIR -> OSFILE 08, CBLK=>filename
ASC 'CDIR'
DB $88
2021-08-25 02:01:41 +00:00
DW STARFILE-1 ; CDIR -> OSFILE 08, CBLK=>filename
* other filing commands
ASC 'CHDIR'
2021-08-25 02:01:41 +00:00
DB $C0
DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
ASC 'CD'
DB $C0
DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
ASC 'DIR'
2021-08-25 02:01:41 +00:00
DB $C0
DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
ASC 'DRIVE'
2021-08-25 02:01:41 +00:00
DB $C1
DW STARFSC-1 ; Should be a FSC 3 call, XY=>params
* FREE (<drive>)
* ACCESS <file> <access>
* TITLE (<drive>) <title>
* osbyte commands
ASC 'FX'
DB $80
2021-08-25 02:01:41 +00:00
DW STARFX-1 ; FX -> OSBYTE A,X,Y (LPTR)=>params
ASC 'OPT'
DB $8B
2021-08-25 02:01:41 +00:00
DW STARBYTE-1 ; OPT -> OSBYTE &8B,X,Y XY=>params
* others
ASC 'QUIT'
DB $80
2021-08-25 02:01:41 +00:00
DW STARQUIT-1 ; QUIT -> (LPTR)=>params
ASC 'HELP'
DB $80
2021-08-25 02:01:41 +00:00
DW STARHELP-1 ; HELP -> (LPTR)=>params
ASC 'BASIC'
DB $80
2021-08-25 02:01:41 +00:00
DW STARBASIC-1 ; BASIC -> (LPTR)=>params
ASC 'KEY'
DB $80
2021-08-25 02:01:41 +00:00
DW STARKEY-1 ; KEY -> (LPTR)=>params
* DUMP <file>
* TYPE <file>
* BUILD <file>
* terminator
DB $00
* OSCLI HANDLER
* On entry, XY=>command string
* On exit, AXY corrupted or error generated
*
2021-08-25 02:01:41 +00:00
CLIHND JSR XYtoLPTR ; LPTR=>command line
CLILP1 LDA (OSLPTR),Y
CMP #$0D
BEQ CLI2
INY
BNE CLILP1
2021-08-25 02:01:41 +00:00
CLIEXIT1 RTS ; No terminating <cr>
CLI2 LDY #0
CLILP2 LDA (OSLPTR),Y
INY
2021-08-25 02:01:41 +00:00
CMP #' ' ; Skip leading spaces
BEQ CLILP2
2021-08-25 02:01:41 +00:00
CMP #'*' ; Skip leading stars
BEQ CLILP2
CMP #$0D
2021-08-25 02:01:41 +00:00
BEQ CLIEXIT1 ; Null string
CMP #'|'
2021-08-25 02:01:41 +00:00
BEQ CLIEXIT1 ; Comment
CMP #'/'
BEQ CLISLASH
DEY
2021-08-25 02:01:41 +00:00
JSR LPTRtoXY ; Add Y to LPTR
JSR XYtoLPTR ; LPTR=>start of actual command
*
* Search command table
2021-08-25 02:01:41 +00:00
LDX #0 ; Start of command table
CLILP4 LDY #0 ; Start of command line
CLILP5 LDA CMDTABLE,X
2021-08-25 02:01:41 +00:00
BEQ CLIUNKNOWN ; End of command table
BMI CLIMATCH ; End of table string
EOR (OSLPTR),Y
2021-08-25 02:01:41 +00:00
AND #$DF ; Force upper case match
BNE CLINOMATCH
2021-08-25 02:01:41 +00:00
INX ; Step to next table char
INY ; Step to next command char
BNE CLILP5 ; Loop to check
CLINOMATCH LDA (OSLPTR),Y
2021-08-25 02:01:41 +00:00
CMP #'.' ; Abbreviation?
BEQ CLIDOT
2021-08-25 02:01:41 +00:00
CLINEXT INX ; No match, step to next entry
LDA CMDTABLE,X
BPL CLINEXT
2021-08-25 02:01:41 +00:00
CLINEXT2 INX ; Step past byte, address
INX
INX
2021-08-25 02:01:41 +00:00
BNE CLILP4 ; Loop to check next
CLIDOT LDA CMDTABLE,X
2021-08-25 02:01:41 +00:00
BMI CLINEXT2 ; Dot after full word, no match
CLIDOT2 INX ; Step to command address
LDA CMDTABLE,X
BPL CLIDOT2
2021-08-25 02:01:41 +00:00
INY ; Step past dot
BNE CLIMATCH2 ; Jump to this command
CLIMATCH LDA (OSLPTR),Y
CMP #'.'
2021-08-25 02:01:41 +00:00
BEQ CLINEXT ; Longer abbreviation, eg 'CAT.'
CMP #'A'
2021-08-25 02:01:41 +00:00
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
2021-08-25 02:01:41 +00:00
LDA CMDTABLE+0,X ; A=command parameter
PHA
2021-08-25 02:01:41 +00:00
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
2021-08-25 02:01:41 +00:00
BEQ CLIDONE ; */<cr>
LDA #$02
2021-08-25 02:01:41 +00:00
BNE STARFSC2 ; FSC 2 = */filename
CLIUNKNOWN LDA #$04
2021-08-25 02:01:41 +00:00
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
TAX
BEQ CLIDONE ; A=0, FSC call implemented
ERRBADCMD BRK
DB $FE
ASC 'Bad command'
ERRBADNUM BRK
DB $FC
ASC 'Bad number'
ERRBADADD BRK
DB $FC
ASC 'Bad address'
BRK
2021-08-25 02:01:41 +00:00
* *FX num(,num(,num))
*********************
STARFX JSR SCANDEC
BRA STARBYTE1
2021-08-25 02:01:41 +00:00
* Commands passed to OSBYTE
***************************
2021-08-25 02:01:41 +00:00
STARBYTE JSR XYtoLPTR
STARBYTE1 STA OSAREG ; Save OSBYTE number
LDA #$00 ; Default X and Y
STA OSXREG
STA OSYREG
2021-08-25 02:01:41 +00:00
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
2021-08-25 02:01:41 +00:00
BNE ERRBADCMD ; More params, error
STARBYTE2 LDY OSYREG
LDX OSXREG
LDA OSAREG
JSR OSBYTE
BVS ERRBADCMD
RTS
* Scan decimal number
SCANDEC JSR SKIPSPC
2021-08-25 02:01:41 +00:00
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
2021-08-25 02:01:41 +00:00
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
2021-08-25 02:01:41 +00:00
ADC OSTEMP ; num=num*10+digit
BCC SCANDECLP
2021-08-25 02:01:41 +00:00
BCS ERRBADNUM ; Overflowed
2021-08-25 02:01:41 +00:00
SCANDECOK LDA OSTEMP ; Return A=number
SCANDIG2 SEC
RTS
SCANDIGIT LDA (OSLPTR),Y
CMP #'0'
2021-08-25 02:01:41 +00:00
BCC SCANDIG2 ; <'0'
CMP #'9'+1
2021-08-25 02:01:41 +00:00
BCS SCANDIG2 ; >'9'
INY
AND #$0F
RTS
2021-08-25 02:01:41 +00:00
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
2021-08-25 02:01:41 +00:00
*
* Skip spaces
SKIPSPC1 INY ; Step past a character
SKIPSPC LDA (OSLPTR),Y
CMP #' '
BEQ SKIPSPC1
2021-08-25 02:01:41 +00:00
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
2021-08-25 02:01:41 +00:00
* Convert XY to (LPTR),Y
XYtoLPTR STX OSLPTR+0
STY OSLPTR+1
LDY #0
RTS
* Print *HELP text
2021-08-25 02:01:41 +00:00
* These needs tidying a bit
STARHELP PHY
JSR PRHELLO ; Unifiy version message
* LDA #<:MSG
* LDY #>:MSG
* JSR PRSTR
PLY
PHY
LDA (OSLPTR),Y
CMP #'.' ; *HELP .
2021-08-25 02:01:41 +00:00
BEQ STARHELP1
INY
EOR (OSLPTR),Y
INY
EOR (OSLPTR),Y
AND #$DF
CMP #$51 ; *HELP MOS
BNE STARHELP5
2021-08-25 02:01:41 +00:00
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
2021-08-25 02:01:41 +00:00
STARHELP5 LDA $8006
BMI STARHELP6 ; Use ROM's service entry
JSR OSNEWL
LDA #$09 ; Language name
LDY #$80 ; *TO DO* make this and BYTE8E
JSR PRSTR ; use same code
JSR OSNEWL
* LDA #<:MSG2
* LDY #>:MSG2
* JSR PRSTR
2021-08-25 02:01:41 +00:00
STARHELP6 PLY
LDA #9
2021-08-25 02:01:41 +00:00
JMP SERVICE ; Pass to sideways ROM(s)
*:MSG DB $0D
* ASC 'Applecorn MOS v0.01'
* DB $0D,$00
*:MSG2 DB $0D,$00
* Handle *QUIT command
STARQUIT >>> XF2MAIN,QUIT
2021-08-25 02:01:41 +00:00
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 SKIPSPC1 ; Skip following spaces
2021-08-25 02:01:41 +00:00
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 SKIPSPC1 ; Step past '+' and spaces
2021-08-25 02:01:41 +00:00
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
JSR OSFILE
TAX
BNE STARDONE
JMP ERRNOTFND
2021-08-25 02:01:41 +00:00
*STARCHDIR STX ZP1+0 ; TEMP
* STY ZP1+1 ; TEMP
* LDY #$00 ; TEMP
* JMP STARDIR ; TEMP
2021-08-25 02:01:41 +00:00
STARBASIC
STARKEY
STARDONE RTS
2021-08-25 02:01:41 +00:00
* 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
2021-08-25 02:01:41 +00:00
EATSPC LDA (ZP1),Y ; Check first char is ...
CMP #' ' ; ... space
BEQ :START
2021-08-25 02:01:41 +00:00
CMP #'"' ; Or quote mark
BEQ :START
BRA :NOTFND
:START INY
2021-08-25 02:01:41 +00:00
:L1 LDA (ZP1),Y ; Eat any additional ...
CMP #' ' ; ... spaces
BEQ :CONT
2021-08-25 02:01:41 +00:00
CMP #'"' ; Or quote marks
BNE :DONE
:CONT INY
BRA :L1
:DONE CLC
RTS
:NOTFND SEC
RTS