Applecorn/auxmem.misc.s

549 lines
19 KiB
ArmAsm
Raw Normal View History

2021-08-24 18:04:37 +00:00
* AUXMEM.MISC.S
* (c) Bobbi 2021 GPLv3
*
2021-08-24 18:04:37 +00:00
* Misc functions and API entry block
2021-09-02 19:47:03 +00:00
* 02-Sep-2021 Written GSINIT/GSREAD
* 11-Sep-2021 PR16DEC uses OS workspace, added rest of default vectors/etc.
2021-09-20 21:02:31 +00:00
* 20-Sep-2021 Updated PRDECIMAL routine, prints up to 32 bits.
2021-10-27 14:40:25 +00:00
* 25-Oct-2021 Initial pseudo-sideways ROM selection code.
* 26-Oct-2021 Corrected entry parameters to OSRDRM.
2021-11-04 02:55:05 +00:00
* 03-Nov-2021 Temp'y fix, if can't find SROM, ignores it.
2021-11-13 18:58:20 +00:00
* 13-Nov-2021 ROMSELECT calls mainmem to load ROM.
* 08-Oct-2022 ROMSEL doesn't call loader if already paged in.
* OSBYTE $80 - ADVAL
************************************
* Read input device or buffer status
2022-10-08 22:58:17 +00:00
BYTE80 LDY #$00 ; Prepare return=&00xx
TXA ; X<0 - info about buffers
BMI ADVALBUF ; X>=0 - read input devices
CPX #$7F
BNE ADVALNONE
ADVALWAIT JSR KBDREAD
2021-08-12 20:58:13 +00:00
BCS ADVALWAIT
TAX
2022-10-08 22:58:17 +00:00
BPL ADVALOK1 ; &00xx for normal keys
INY ; &01xx for function/edit keys
2021-09-02 19:47:03 +00:00
ADVALOK1 RTS
2022-10-08 22:58:17 +00:00
ADVALNONE LDX #$00 ; Input, just return 0
RTS
ADVALBUF INX
2022-10-08 22:58:17 +00:00
BEQ :ADVALKBD ; Fake keyboard buffer
INX
2022-10-08 22:58:17 +00:00
BEQ :ADVALOK ; Serial input, return 0
LDX #$01 ; For outputs, return 1 char free
RTS
:ADVALKBD BIT KBDDATA ; Test keyboard data/strobe
2022-10-08 22:58:17 +00:00
BPL :ADVALOK ; No Strobe, return 0
INX ; Strobe, return 1
:ADVALOK RTS
* Beep
******
2021-08-12 20:58:13 +00:00
* Sound measurement shows the tone formula is:
* 1.230 MHz
* ------------- = cycles
* 8 * frequency
*
2021-08-12 20:58:13 +00:00
* cycles = BEEPX*5+10
*
2021-08-12 20:58:13 +00:00
* So:
* BEEPX = (cycles-10)/5
* So:
* BEEPX = ( 1.230 MHz )
* (------------- - 10 ) / 5
* (8 * frequency )
* BEEPX EQU #57 ; note=C5
2022-10-08 22:58:17 +00:00
BEEPX EQU #116 ; note=C4
2021-08-12 20:58:13 +00:00
BEEP PHA
PHX
PHY
2022-10-08 22:58:17 +00:00
LDY #$00 ; duration
:L1 LDX #BEEPX ; 2cy pitch 2cy
*------------------------------------------------------
2022-10-08 22:58:17 +00:00
:L2 DEX ; 2cy BEEPX * 2cy
BNE :L2 ; 3cy/2cy (BEEPX-1) * 3cy + 1 * 2cy
*------------------------------------------------------
2021-09-02 19:47:03 +00:00
* BEEPX*5-1cy
LDA SPKR ; 4cy BEEPX*5+5
2022-10-08 22:58:17 +00:00
DEY ; 2cy BEEPX*5+7
BNE :L1 ; 3cy/2cy BEEPX*5+10
PLY ;
PLX
PLA
PRSTROK RTS
2021-10-23 18:41:47 +00:00
* OSPRSTR - Print string at XY
******************************
* On exit, X,Y preserved, A=$00
OUTSTR TXA
* Print string pointed to by A,Y to the screen
2022-10-08 22:58:17 +00:00
PRSTR STA OSTEXT+0 ; String in A,Y
STY OSTEXT+1
2022-10-08 22:58:17 +00:00
:L1 LDA (OSTEXT) ; Ptr to string in OSTEXT
PHP ; Save EQ
INC OSTEXT
BNE :L2
INC OSTEXT+1
:L2 PLP ; Get EQ back
BEQ PRSTROK ; End of string
JSR OSASCI
BRA :L1
2021-08-31 22:47:35 +00:00
* Print NL if not already at column 0
FORCENL LDA #$86
JSR OSBYTE
TXA
BEQ PRSTROK
JMP OSNEWL
* OSPR2HEX - Print XY in hex
****************************
OUT2HEX TYA
JSR OUTHEX
2022-10-08 22:58:17 +00:00
TXA ; Continue into OUTHEX
* OSPR1HEX - Print hex byte in A
********************************
OUTHEX PHA
LSR
LSR
LSR
LSR
AND #$0F
JSR PRNIB
PLA
2022-10-08 22:58:17 +00:00
AND #$0F ; Continue into PRNIB
* Print hex nibble in A
PRNIB CMP #$0A
BCC :S1
2022-10-08 22:58:17 +00:00
CLC ; >= $0A
ADC #'A'-$0A
JSR OSWRCH
RTS
2022-10-08 22:58:17 +00:00
:S1 ADC #'0' ; < $0A
JMP OSWRCH
* OSPRDEC - Print up to 32-bit decimal number
*********************************************
2021-09-20 21:02:31 +00:00
* See forum.6502.org/viewtopic.php?f=2&t=4894
2021-10-23 18:41:47 +00:00
* and groups.google.com/g/comp.sys.apple2/c/_y27d_TxDHA
*
2021-09-20 21:02:31 +00:00
* X=>four byte zero page locations
2021-10-23 18:41:47 +00:00
* Y= number of digits to pad to, 0 for no padding
2021-09-20 21:02:31 +00:00
*
2022-10-08 22:58:17 +00:00
PRINTDEC sty OSPAD ; Number of padding+digits
ldy #0 ; Digit counter
PRDECDIGIT lda #32 ; 32-bit divide
2021-09-20 21:02:31 +00:00
sta OSTEMP
2022-10-08 22:58:17 +00:00
lda #0 ; Remainder=0
clv ; V=0 means div result = 0
PRDECDIV10 cmp #10/2 ; Calculate OSNUM/10
2021-09-20 21:02:31 +00:00
bcc PRDEC10
2022-10-08 22:58:17 +00:00
sbc #10/2+$80 ; Remove digit & set V=1 to show div result > 0
sec ; Shift 1 into div result
PRDEC10 rol 0,x ; Shift /10 result into OSNUM
2021-09-20 21:02:31 +00:00
rol 1,x
rol 2,x
rol 3,x
2022-10-08 22:58:17 +00:00
rol a ; Shift bits of input into acc (input mod 10)
2021-09-20 21:02:31 +00:00
dec OSTEMP
2022-10-08 22:58:17 +00:00
bne PRDECDIV10 ; Continue 32-bit divide
2021-09-20 21:02:31 +00:00
ora #48
2022-10-08 22:58:17 +00:00
pha ; Push low digit 0-9 to print
2021-09-20 21:02:31 +00:00
iny
2022-10-08 22:58:17 +00:00
bvs PRDECDIGIT ; If V=1, result of /10 was > 0 & do next digit
2021-09-20 21:02:31 +00:00
lda #32
PRDECLP1 cpy OSPAD
2022-10-08 22:58:17 +00:00
bcs PRDECLP2 ; Enough padding pushed
pha ; Push leading space characters
2021-09-20 21:02:31 +00:00
iny
bne PRDECLP1
2022-10-08 22:58:17 +00:00
PRDECLP2 pla ; Pop character left to right
jsr OSWRCH ; Print it
2021-09-20 21:02:31 +00:00
dey
bne PRDECLP2
rts
2021-09-02 19:47:03 +00:00
* GSINIT - Initialise for GSTRANS string parsing
************************************************
* On entry,
* (OSLPTR),Y=>start of string (spaces will be skipped)
* CLC = filename style parsing
* SEC = *KEY style parsing
* On exit,
* X = preserved
* Y = prepared for future calls to GSREAD
* EQ = end of line (nb: not "" null string)
* NE = not end of line
*
* Very difficult to write this without it being a direct clone
* from the BBC MOS. ;)
*
2022-10-08 22:58:17 +00:00
GSINTGO ROR GSFLAG ; CY initially into bit 7
JSR SKIPSPC ; Skip any spaces
INY ; Step past in case it's a quote
CMP #$22 ; Is it a quote?
2021-09-02 19:47:03 +00:00
BEQ GSINTGO1
2022-10-08 22:58:17 +00:00
DEY ; Wasn't a quote, step back
CLC ; Prepare CC=no leading quote
GSINTGO1 ROR GSFLAG ; Rotate 'leading-quote' into flags
2021-09-02 19:47:03 +00:00
CMP #$0D
2022-10-08 22:58:17 +00:00
RTS ; Return EQ if end of line
2021-09-02 19:47:03 +00:00
* GSFLAG set to:
* bit7: leading quote found
* bit6: CC=filename CS=*KEY
* GSREAD - Read a character from a GSTRANS parsed string
********************************************************
* On entry,
* (OSLPTR),Y=>current string pointer
* On exit,
* A = parsed character
* X = preserved
* CS = end of string (space or <cr> or ")
* Y =updated to start of next word or end of line
* EQ=end of line after this string
* NE=not end of line, more words follow
* CC = not end of string
* Y =updated for future calls to GSREAD
* VS=7-bit control character, (char AND $7F)<$20
* VC=not 7-bit control character (char AND $7F)>$1F
* EQ= char=$00, NE= char>$00
* PL= char<$80, MI= char>$7F
2021-09-02 19:47:03 +00:00
*
* No string present is checked for with:
* JSR GSINIT:BEQ missingstring
*
* A null string is checked for with:
* JSR GSINIT:JSR GSREAD:BCS nullstring
*
* A string is skipped with:
* JSR GSINIT
* loop
* JSR GSREAD:BCC loop
*
* A string is copied with:
* JSR GSINIT
* LDX #0
* loop
* JSR GSREAD:BCS done
* STA data,X
* INX:BNE loop
* done
*
2022-10-08 22:58:17 +00:00
GSRDGO LDA #$00 ; Prepare to clear accumulator
GSREADLP STA GSCHAR ; Update accumulator
LDA (OSLPTR),Y ; Get current character
CMP #$0D ; End of line?
BNE GSREAD2 ; No, check character
2021-09-02 19:47:03 +00:00
BIT GSFLAG
2022-10-08 22:58:17 +00:00
BPL GSREADEND ; We aren't waiting for a closing quote
* ; End of line before closing quote
2021-09-02 19:47:03 +00:00
ERRBADSTR BRK
DB $FD
ASC 'Bad string'
BRK
GSREAD2 CMP #' '
2022-10-08 22:58:17 +00:00
BCC ERRBADSTR ; Embedded control char
BNE GSREAD3 ; Not a space, process it
BIT GSFLAG ; Can space terminate string?
BMI GSREADCHAR ; We're waiting for a terminating quote
* ; so return the space character
2022-10-08 22:58:17 +00:00
BVC GSREADEND ; Space is a terminator, finish
GSREAD3 CMP #$22 ; Is it a quote?
BNE GSREADESC ; Not quote, check for escapes
BIT GSFLAG ; Was there an opening quote?
BPL GSREADCHAR ; Not waiting for a closing quote
INY ; Waiting for quote, check next character
2021-09-02 19:47:03 +00:00
LDA (OSLPTR),Y
2022-10-08 22:58:17 +00:00
CMP #$22 ; Is it another quote?
BEQ GSREADCHAR ; Quote-Quote, expand to single quote
2021-09-02 19:47:03 +00:00
* End of string
* Either closing quote, or a space seperator, or end of line
2022-10-08 22:58:17 +00:00
GSREADEND JSR SKIPSPC ; Skip any spaces to next word
SEC ; SEC=end of string
RTS ; and (OSLPTR),Y=>next word or end of line
2021-09-02 19:47:03 +00:00
* CS=end of string
* EQ=end of line
* NE=not end of line, more words follow
2022-10-08 22:58:17 +00:00
GSREADESC CMP #$7C ; Is it '|' escape character
BNE GSREADCHAR ; No, return as character
INY ; Step to next character
2021-09-02 19:47:03 +00:00
LDA (OSLPTR),Y
CMP #$7C
2022-10-08 22:58:17 +00:00
BEQ GSREADCHAR ; bar-bar expands to bar
2021-09-02 19:47:03 +00:00
CMP #$22
2022-10-08 22:58:17 +00:00
BEQ GSREADCHAR ; bar-quote expands to quote
CMP #'!' ; Is it bar-pling?
BNE GSREAD5 ; No, check for bar-letter
INY ; Step past it
LDA #$80 ; Set bit 7 in accumulator
BNE GSREADLP ; Loop back to check next character(s)
GSREAD5 CMP #'?' ; Check for '?'
BCC ERRBADSTR ; <'?', bad character
BEQ GSREADDEL ; bar-query -> DEL
AND #$1F ; Convert bar-letter to control code
BIT SETV ; SEV=control character
2021-09-02 19:47:03 +00:00
BVS GSREADOK
GSREADDEL LDA #$7F
2022-10-08 22:58:17 +00:00
GSREADCHAR CLV ; CLV=not control character
GSREADOK INY ; Step to next character
ORA GSCHAR ; Add in any bit 7 from |! prefix
CLC ; CLC=not end of string
2021-09-02 19:47:03 +00:00
RTS
* CC=not end of string
* VS=control character
* VC=not control character
* OSRDROM - Read a byte from sideways ROM
*****************************************
2021-10-27 14:40:25 +00:00
* On entry, Y=ROM to read from
* (ROMPTR)=>byte to read
2021-10-23 18:41:47 +00:00
* On exit, A=byte read, X=current ROM, Y=$00
2022-10-08 22:58:17 +00:00
RDROM LDA ROMID
PHA ; Save current ROM
2021-10-27 14:40:25 +00:00
TYA
2022-10-08 22:58:17 +00:00
TAX ; X=ROM to read from
JSR ROMSELECT ; Page in the required ROM
LDY #$00 ; NOTE BBC sets Y=0, Master preserves
2022-10-08 22:58:17 +00:00
LDA (ROMPTR),Y ; Read the byte
2021-10-23 18:41:47 +00:00
PLX
* ROMSELECT - Select a sideways ROM
***********************************
* On entry, X=ROM to select
* On exit, All registers must be preserved
*
2021-11-13 18:58:20 +00:00
ROMSELECT
2021-10-23 18:41:47 +00:00
* Insert code here for faking sideways ROMs by loading or otherwise
* fetching code to $8000. All registers must be preserved.
2022-10-08 22:58:17 +00:00
PHP
CPX ROMID ; Speed up by checking if
BEQ ROMSELOK ; already paged in
2022-10-08 22:58:17 +00:00
* BUG: This needs ROMID an invalid value on startup so first access works
2021-11-13 18:58:20 +00:00
PHA
PHX
PHY
2022-10-08 22:58:17 +00:00
SEI
TXA ; A=ROM to select
2021-11-13 18:58:20 +00:00
>>> XF2MAIN,SELECTROM
ROMSELDONE >>> ENTAUX
PLY
PLX
PLA
2022-10-08 22:58:17 +00:00
STX ROMID ; Set Current ROM number
ROMSELOK PLP
2021-11-13 18:58:20 +00:00
RTS
2021-11-13 19:57:05 +00:00
* Initialize ROMTAB according to user selection in menu
2022-10-08 22:58:17 +00:00
ROMINIT STZ MAXROM ; One sideways ROM only
STA RDMAINRAM ; Read main mem
2022-10-08 22:58:17 +00:00
LDA USERSEL ; *TO DO* Should be actual number of ROMs
STA RDCARDRAM ; Read aux mem
2021-11-13 18:58:20 +00:00
CMP #6
BNE :X1
INC MAXROM
:X1 CMP #7
BNE :X2
STA MAXROM
:X2 LDA #$FF
STA ROMID ; Ensure set to invalid value
RTS
2021-11-13 18:58:20 +00:00
2021-09-02 19:47:03 +00:00
EVENT RTS
**********************************************************
* Interrupt Handlers, MOS redirection vectors etc.
**********************************************************
* Invoked from GSBRK in main memory. On IIgs only.
2022-10-08 22:58:17 +00:00
GSBRKAUX >>> IENTAUX ; IENTAUX does not do CLI
* Continue into IRQBRKHDLR
* TO DO: Check, IENTAUX modifies X
* IRQ/BRK handler
*****************
IRQBRKHDLR PHA
* Mustn't enable IRQs within the IRQ handler
2021-08-14 05:18:35 +00:00
* Do not use WRTMAIN/WRTAUX macros
STA WRMAINRAM ; Write to main memory
2022-10-08 22:58:17 +00:00
STA $45 ; $45=A for ProDOS IRQ handlers
STA WRCARDRAM ; Write to aux memory
2022-10-08 22:58:17 +00:00
TXA
PHA
CLD
TSX
2022-10-08 22:58:17 +00:00
LDA $103,X ; Get PSW from stack
AND #$10
2022-10-08 22:58:17 +00:00
BEQ :IRQ ; IRQ
SEC
2022-10-08 22:58:17 +00:00
LDA $0104,X
SBC #$01
2022-10-08 22:58:17 +00:00
STA FAULT+0 ; FAULT=>error block after BRK
LDA $0105,X
SBC #$00
STA FAULT+1
2021-10-23 18:41:47 +00:00
2022-10-08 22:58:17 +00:00
LDA $F4 ; Get current ROM
STA BYTEVARBASE+$BA ; Set ROM at last BRK
STX OSXREG ; Pass stack pointer
LDA #$06 ; Service Call 6 = BRK occured
2021-10-23 18:41:47 +00:00
JSR SERVICE
2022-10-08 22:58:17 +00:00
LDX BYTEVARBASE+$FC ; Get current language
JSR ROMSELECT ; Bring it into memory
2021-10-23 18:41:47 +00:00
PLA
TAX
PLA
2022-10-08 22:58:17 +00:00
CLI
JMP (BRKV) ; Pass on to BRK handler
2022-10-08 22:58:17 +00:00
:IRQ >>> XF2MAIN,A2IRQ ; Bounce to Apple IRQ handler
IRQBRKRET
2022-10-08 22:58:17 +00:00
>>> IENTAUX ; IENTAUX does not do CLI
PLA ; TODO: Pass on to IRQ1V
TAX
PLA
NULLRTI RTI
* Default BRK handler
*********************
MOSBRKHDLR LDX #<MSGBRK
LDY #>MSGBRK
JSR OSPRSTR
JSR PRERR
* JSR OSNEWL
* JSR OSNEWL
STOP JMP STOP ; Cannot return from a BRK
MSGBRK DB $0D
ASC 'ERROR: '
DB $00
PRERR LDY #$01
PRERRLP LDA (FAULT),Y
BEQ PRERR1
JSR OSWRCH
INY
BNE PRERRLP
NULLRTS
PRERR1 RTS
* Default page 2 contents
*************************
2022-10-08 22:58:17 +00:00
DEFVEC DW NULLRTS ; $200 USERV
DW MOSBRKHDLR ; $202 BRKV
DW NULLRTI ; $204 IRQ1V
DW NULLRTI ; $206 IRQ2V
DW CLIHND ; $208 CLIV
DW BYTEHND ; $20A BYTEV
DW WORDHND ; $20C WORDV
DW WRCHHND ; $20E WRCHV
DW RDCHHND ; $210 RDCHV
DW FILEHND ; $212 FILEV
DW ARGSHND ; $214 ARGSV
DW BGETHND ; $216 BGETV
DW BPUTHND ; $218 BPUTV
DW GBPBHND ; $21A GBPBV
DW FINDHND ; $21C FINDV
DW FSCHND ; $21E FSCV
DW NULLRTS ; $220 EVENTV
DW NULLRTS ; $222
DW NULLRTS ; $224
DW NULLRTS ; $226
DW NULLRTS ; $228
DW NULLRTS ; $22A
DW NULLRTS ; $22C
DW NULLRTS ; $22E
DW NULLRTS ; $230 SPARE1V
DW NULLRTS ; $232 SPARE2V
DW NULLRTS ; $234 SPARE3V
ENDVEC
*
* Acorn MOS entry points at the top of RAM
* Copied from loaded code to high memory
*
* Base of API entries here in loaded code
MOSVEC
* Real base of API entries in real memory
MOSAPI EQU $FF95
ORG MOSAPI
* OPTIONAL ENTRIES
* ----------------
2022-10-08 22:58:17 +00:00
OSSERV JMP SERVICE ; FF95 OSSERV
OSCOLD JMP NULLRTS ; FF98 OSCOLD
OSPRSTR JMP OUTSTR ; FF9B OSPRSTR
OSSCANDEC JMP SCANDEC ; FF9E SCANDEC
OSSCANHEX JMP SCANHEX ; FFA1 SCANHEX
OSFFA4 JMP NULLRTS ; FFA4 (DISKACC)
OSFFA7 JMP NULLRTS ; FFA7 (DISKCCP)
PRHEX
PR1HEX JMP OUTHEX ; FFAA PRHEX
2022-10-08 22:58:17 +00:00
PR2HEX JMP OUT2HEX ; FFAD PR2HEX
OSFFB0 JMP PRINTDEC ; FFB0 (USERINT)
OSWRRM JMP NULLRTS ; FFB3 OSWRRM
* COMPULSARY ENTRIES
* ------------------
2022-10-08 22:58:17 +00:00
VECSIZE DB ENDVEC-DEFVEC ; FFB6 VECSIZE Size of vectors
VECBASE DW DEFVEC ; FFB7 VECBASE Base of default vectors
OSRDRM JMP RDROM ; FFB9 OSRDRM Read byte from paged ROM
OSCHROUT JMP OUTCHAR ; FFBC CHROUT Send char to VDU driver
OSEVEN JMP EVENT ; FFBF OSEVEN Signal an event
GSINIT JMP GSINTGO ; FFC2 GSINIT Init string reading
GSREAD JMP GSRDGO ; FFC5 GSREAD Parse general string
NVWRCH JMP WRCHHND ; FFC8 NVWRCH Nonvectored WRCH
NVRDCH JMP RDCHHND ; FFCB NVRDCH Nonvectored RDCH
OSFIND JMP (FINDV) ; FFCE OSFIND
OSGBPB JMP (GBPBV) ; FFD1 OSGBPB
OSBPUT JMP (BPUTV) ; FFD4 OSBPUT
OSBGET JMP (BGETV) ; FFD7 OSBGET
OSARGS JMP (ARGSV) ; FFDA OSARGS
OSFILE JMP (FILEV) ; FFDD OSFILE
OSRDCH JMP (RDCHV) ; FFE0 OSRDCH
OSASCI CMP #$0D ; FFE3 OSASCI
BNE OSWRCH
2022-10-08 22:58:17 +00:00
OSNEWL LDA #$0A ; FFE7 OSNEWL
JSR OSWRCH
2022-10-08 22:58:17 +00:00
OSWRCR LDA #$0D ; FFEC OSWRCR
OSWRCH JMP (WRCHV) ; FFEE OSWRCH
OSWORD JMP (WORDV) ; FFF1 OSWORD
OSBYTE JMP (BYTEV) ; FFF4 OSBYTE
OSCLI JMP (CLIV) ; FFF7 OSCLI
NMIVEC DW NULLRTI ; FFFA NMIVEC
RSTVEC DW STOP ; FFFC RSTVEC
IRQVEC
* Assembler doesn't like running up to $FFFF, so we bodge a bit
MOSEND
ORG MOSEND-MOSAPI+MOSVEC
2022-10-08 22:58:17 +00:00
DW IRQBRKHDLR ; FFFE IRQVEC
MOSVEND
* Buffer for one 512 byte disk block in aux mem
AUXBLK
; ASC '**ENDOFCODE**'
; DS $200-13
2022-10-08 21:37:45 +00:00