Updated CLOSE, EXEC

*CLOSE is a MOS command
Fixed *EXEC, needs optimising
Added buffer handler
This commit is contained in:
jgharston 2022-10-07 12:35:38 +01:00 committed by GitHub
parent def729bc9b
commit 835e2327de
3 changed files with 238 additions and 52 deletions

View File

@ -310,9 +310,6 @@ FSCCOMMAND ASC 'CHDIR'
ASC 'COPY'
DB $80
DW FSCCOPY-1 ; COPY <listspec> <*objspec*>, LPTR=>params
ASC 'CLOSE'
DB $80
DW FSCCLOSE-1 ; CLOSE
*
DB $FF ; Terminator
@ -841,20 +838,6 @@ DESTROY JSR PARSLPTR ; Copy filename->MOSFILE
FSCTITLE RTS
* Handle *CLOSE command
*
FSCCLOSE JSR PARSLPTR
BNE :SYNTAX ; Trailing junk
LDA #$00 ; Close all open files
LDY #$00
JSR FINDHND
STZ FXSPOOL ; Also, stop spooling
RTS
:SYNTAX BRK
DB $DC
ASC 'Syntax: CLOSE'
BRK
* Parse filename pointed to by XY
* Write filename to MOSFILE in main memory
* Returns length in A with EQ/NE set

View File

@ -9,6 +9,7 @@
* 02-Sep-2021 *LOAD/*SAVE now uses GSTRANS.
* 12-Sep-2021 *HELP uses subject lookup, *HELP MOS, *HELP HOSTFS.
* 25-Oct-2021 Implemented *BASIC.
* 07-Oct-2022 *CLOSE is a host command, fixed *EXEC.
* COMMAND TABLE
@ -69,6 +70,13 @@ CMDTABLE ASC 'CAT' ; Must be first command so matches '*.'
ASC 'ECHO'
DB $80
DW ECHO-1 ; ECHO -> (LPTR)=>params
ASC 'FAST'
DB $80
DW FAST-1 ; FAST -> (LPTR)=>params
ASC 'SLOW'
DB $80
DW SLOW-1 ; SLOW -> (LPTR)=>params
* filing utilities
ASC 'TYPE'
DB $80
DW TYPE-1 ; TYPE -> (LPTR)=>params
@ -77,16 +85,13 @@ CMDTABLE ASC 'CAT' ; Must be first command so matches '*.'
DW DUMP-1 ; DUMP -> (LPTR)=>params
ASC 'SPOOL'
DB $80
DW SPOOL-1 ; EXEC -> (LPTR)=>params
DW SPOOL-1 ; SPOOL -> (LPTR)=>params
ASC 'EXEC'
DB $80
DW EXEC-1 ; EXEC -> (LPTR)=>params
ASC 'FAST'
ASC 'CLOSE'
DB $80
DW FAST-1 ; FAST -> (LPTR)=>params
ASC 'SLOW'
DB $80
DW SLOW-1 ; SLOW -> (LPTR)=>params
DW STARCLOSE-1 ; CLOSE -> (LPTR)=>params
* BUILD <file>
* terminator
DB $FF
@ -527,6 +532,17 @@ ECHOLP1 JSR GSREAD
JSR OSWRCH
JMP ECHOLP1
* FILING UTILITIES
******************
* *CLOSE
********
STARCLOSE LDA #$00
TAY
JSR OSFIND ; Close all files
STA FXEXEC ; Clear Spool/Exec handles
STA FXSPOOL
RTS
* Handle *TYPE command
* LPTR=>parameters string
@ -540,7 +556,7 @@ TYPE JSR LPTRtoXY
PLY
PLX
LDA #$40 ; Open for input
JSR FINDHND ; Try to open file
JSR OSFIND ; Try to open file
CMP #$00 ; Was file opened?
BEQ :NOTFOUND
TAY ; File handle in Y
@ -553,7 +569,7 @@ TYPE JSR LPTRtoXY
BMI :ESC
BRA :L1
:CLOSE LDA #$00
JSR FINDHND ; Close file
JSR OSFIND ; Close file
:DONE RTS
:SYNTAX BRK
DB $DC
@ -564,7 +580,7 @@ TYPE JSR LPTRtoXY
ASC 'Not found'
BRK
:ESC LDA #$00 ; Close file
JSR FINDHND
JSR OSFIND
BRK
DB $11
ASC 'Escape'
@ -583,7 +599,7 @@ DUMP JSR LPTRtoXY
PLY
PLX
LDA #$40 ; Open for input
JSR FINDHND ; Try to open file
JSR OSFIND ; Try to open file
CMP #$00 ; Was file opened?
BEQ :NOTFOUND
TAY ; File handle in Y
@ -623,7 +639,7 @@ DUMP JSR LPTRtoXY
BRA :L1
:CLOSE JSR PRCHARS ; Print ASCII representation
LDA #$00
JSR FINDHND ; Close file
JSR OSFIND ; Close file
:DONE RTS
:SYNTAX BRK
DB $DC
@ -634,7 +650,7 @@ DUMP JSR LPTRtoXY
ASC 'Not found'
BRK
:ESC LDA #$00 ; Close file
JSR FINDHND
JSR OSFIND
BRK
DB $11
ASC 'Escape'
@ -706,11 +722,11 @@ SPOOL JSR LPTRtoXY
LDY FXSPOOL ; Already spooling?
BEQ :OPEN
LDA #$00 ; If so, close file
JSR FINDHND
JSR OSFIND
:OPEN PLY
PLX
LDA #$80 ; Open for writing
JSR FINDHND ; Try to open file
JSR OSFIND ; Try to open file
STA FXSPOOL ; Store SPOOL file handle
RTS
:CLOSE PLY ; Clean up stack
@ -718,7 +734,7 @@ SPOOL JSR LPTRtoXY
LDY FXSPOOL
BEQ :DONE
LDA #$00
JSR FINDHND ; Close file
JSR OSFIND ; Close file
STZ FXSPOOL
:DONE RTS
@ -726,29 +742,24 @@ SPOOL JSR LPTRtoXY
* Handle *EXEC command
* LPTR=>parameters string
*
EXEC JSR LPTRtoXY
PHX
PHY
JSR XYtoLPTR
JSR PARSLPTR ; Just for error handling
BEQ :SYNTAX ; No filename
PLY
PLX
EXEC PHY
LDY FXEXEC
BEQ :EXEC1
LDA #$00
STA FXEXEC
JSR OSFIND ; If Exec open, close it
:EXEC1 PLY
LDA (OSLPTR),Y
CMP #$0D
BEQ :DONE ; No filename, all done
JSR LPTRtoXY ; XY=>filename
LDA #$40 ; Open for input
JSR FINDHND ; Try to open file
CMP #$00 ; Was file opened?
JSR OSFIND ; Try to open file
TAY ; Was file opened?
BEQ :NOTFOUND
STA FXEXEC ; Store EXEC file handle
RTS
RTS
:SYNTAX PLY ; Fix the stack
PLX
BRK
DB $DC
ASC 'Syntax: EXEC <*objspec*>'
BRK
:NOTFOUND STZ FXEXEC
BRK
:DONE RTS
:NOTFOUND BRK
DB $D6
ASC 'Not found'
BRK

192
buffer.s Normal file
View File

@ -0,0 +1,192 @@
* BUFFER.S
* Buffer handling code, called by INSV, REMV, CNPV
* Location and sizes of buffers
* -----------------------------
BUF4 EQU $0340
BUF4SZ EQU 16
BUF5 EQU $0350
BUF5SZ EQU 16
BUF6 EQU $0360
BUF6SZ EQU 16
BUF7 EQU $0370
BUF7SZ EQU 16
BUF3 EQU $0380
BUF3SZ EQU 64
BUFBASE EQU $03C0 ; Base of buffer workspace
BUF0 EQU $03E0
BUF0SZ EQU 32
BUF2 EQU $0C00
BUF2SZ EQU 192
BUF8 EQU $0CC0
BUF8SZ EQU 64
BUF1 EQU $0D00
BUF1SZ EQU 256
* The buffers are arranged so that an offset of &FF is the last entry, and
* incrementing to &00 passes the end of the buffer. A buffer is empty when
* BUFINP=BUFOUT, and is full when BUFINP+1=BUFOUT.
* BUFFER ADDRESS LOW BYTE LOOKUP TABLE
* ------------------------------------
* start+len
BUFLO DB (BUF0 + BUF0SZ - 256) AND 255 ; keyboard
DB (BUF1 + BUF1SZ - 256) AND 255 ; serial input
DB (BUF2 + BUF2SZ - 256) AND 255 ; serial output
DB (BUF3 + BUF3SZ - 256) AND 255 ; printer
DB (BUF4 + BUF4SZ - 256) AND 255 ; sound 0
DB (BUF5 + BUF5SZ - 256) AND 255 ; sound 1
DB (BUF6 + BUF6SZ - 256) AND 255 ; sound 2
DB (BUF7 + BUF7SZ - 256) AND 255 ; sound 3
DB (BUF8 + BUF8SZ - 256) AND 255 ; speech
* BUFFER ADDRESS HIGH BYTE LOOKUP TABLE
* -------------------------------------
* start+len
BUFHI DB (BUF0 + BUF0SZ - 256) DIV 256 ; keyboard
DB (BUF1 + BUF1SZ - 256) DIV 256 ; serial input
DB (BUF2 + BUF2SZ - 256) DIV 256 ; serial output
DB (BUF3 + BUF3SZ - 256) DIV 256 ; printer
DB (BUF4 + BUF4SZ - 256) DIV 256 ; sound 0
DB (BUF5 + BUF5SZ - 256) DIV 256 ; sound 1
DB (BUF6 + BUF6SZ - 256) DIV 256 ; sound 2
DB (BUF7 + BUF7SZ - 256) DIV 256 ; sound 3
DB (BUF8 + BUF8SZ - 256) DIV 256 ; speech
* BUFFER START ADDRESS OFFSET
* ---------------------------
* len
BUFOFF DB 256-BUF0SZ
DB 256-BUF1SZ
DB 256-BUF2SZ
DB 256-BUF3SZ
DB 256-BUF4SZ
DB 256-BUF5SZ
DB 256-BUF6SZ
DB 256-BUF7SZ
DB 256-BUF8SZ
BUFNUM EQU BUFHI-BUFLO ; Number of buffers
BUFFLG EQU BUFBASE+0*BUFNUM ; Buffer flags
BUFINP EQU BUFBASE+1*BUFNUM ; Input pointers
BUFOUT EQU BUFBASE+2*BUFNUM ; Output pointers
* Get buffer base address
* -----------------------
* On entry, X=buffer number (not checked)
* On exit, (OSINTWS)=>buffer base
BUFADDR LDA BUFLO,X
STA OSINTWS+0 ; Get buffer base address low
LDA BUFHI,X
STA OSINTWS+1 ; Get buffer base address high
RTS
* REMV buffer remove
* ==================
* On entry, X =buffer number
* VS=examine buffer
* VC=remove from buffer
* On exit, X =preserved
* CS=buffer empty
* A,Y corrupted
* CC=buffer not empty
* A=Y=byte from buffer
* If called to remove from buffer, pointers updated
*
BUFREM PHP ; Save flags
SEI ; Disable IRQs
CPX #BUFNUM ; Valid buffer number?
BCS BUFFAIL ; No, return 'empty'
LDA BUFOUT,X ; Get output pointer for buffer X
CMP BUFINP,X ; Compare it to input pointer
BEQ BUFFAIL ; Equal, so buffer is empty
TAY ; Y=output pointer
JSR BUFADDR ; Get buffer base address
LDA (OSINTWS),Y ; Get byte from buffer
BVS BUFREM2 ; If VS, just examine buffer, return
INY ; Otherwise, update buffer pointer
BNE BUFREM1 ; Not zero, not reached end of buffer
LDY BUFOFF,X ; Get offset to start of buffer
BUFREM1 STY BUFOUT,X ; Update the buffer output pointer
BUFREM2 TAY ; Return A=Y=byte from buffer
PLP ; Restore IRQs
CLC ; CLC=success
RTS
* INSV buffer insert
* ==================
* On entry, X =buffer number
* A =byte to be inserted
* On exit, X =preserved
* A =preserved
* Y =corrupted
* CS=buffer full, couldn't insert
* CC=buffer wasn't full, insertion successful
*
BUFINS PHP ; Save flags
SEI ; Disable IRQs
CPX #BUFNUM ; Valid buffer number?
BCS BUFINS2 ; No, sink it and return 'ok'
PHA ; Save A
LDY BUFINP,X ; Get buffer input pointer
INY ; Otherwise, update buffer pointer
BNE BUFINS1 ; Not zero, not reached end of buffer
LDY BUFOFF,X ; Get offset to start of buffer
BUFINS1 TYA ; A=updated input pointer
CMP BUFOUT,X ; Compare with output pointer
BEQ BUFINS4 ; Same, buffer is full, exit with 'failed'
LDY BUFINP,X ; Get unupdated input pointer back
STA BUFINP,X ; Store updated input pointer
JSR BUFADDR ; Get buffer base address
PLA ; Get the byte back
STA (OSINTWS),Y ; And store it in buffer
BUFINS2 PLP ; Restore IRQs
CLC ; CLC=success
RTS
BUFINS4 PLA ; Restore A
BUFFAIL PLP ; Restore IRQs
SEC ; SEC=failed
RTS
* CNPV count/purge buffer
* =======================
* On entry, X =buffer number
* VC=purge (clear) buffer
* VS=count buffer
* CC=count used space
* CS=count free space
* On exit, XY=size counted
* A =corrupted
*
BUFCNP CPX #BUFNUM ; Valid buffer number?
BCS BUFCNP1 ; No, ignore it
BVC BUFCNT1 ; VS, count buffer
LDA BUFOUT,X ; Set input=output, empty buffer
STA BUFINP,X
BUFCNP1 BVS BUFCNT5 ; Purged, exit
LDX #$00
BEQ BUFCNT4 ; Count, return zero
BUFCNT1 PHP ; Save flags
SEI ; Disable IRQs
SEC ; Prepare for SBC
LDA BUFOUT,X ; Get output pointer
SBC BUFINP,X ; Subtract input pointer
BCS BUFCNT2 ; No overflow, use it
SEC ; Prepare for SBC
SBC BUFOFF,X ; Subtract buffer start offset
BUFCNT2 PLP ; Get flags back, also restore IRQs
BCC BUFCNT3 ; CLC, exit with size counted
CLC ; Prepare for ADC
ADC BUFOFF,X ; Add buffer offset to get NEG(bytes free)
EOR #&FF ; Invert it to get free space
BUFCNT3 TAX ; YX=count
BUFCNT4 LDY #&00 ; All our buffers are <256 bytes
BUFCNT5 RTS