Applecorn/auxmem.shr.s

277 lines
9.3 KiB
ArmAsm

* AUXMEM.SHR.S
* (c) Bobbi 2022 GPLv3
*
* Routines for drawing bitmapped text and graphics in SHR mode
* on Apple IIGS (640x200 4 colour, or 320x200 16 colour.)
*
SCB320 EQU $00 ; SCB for 320 mode
SCB640 EQU $80 ; SCB for 640 mode
* Colours in the following order.
* For 16 colour modes ...
* BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, ...
* For 4 colour modes ...
* BLACK, RED, YELLOW, WHITE
PALETTE320 DB $00, $00 ; BLACK
DB $00, $08 ; RED
DB $80, $00 ; GREEN
DB $80, $08 ; YELLOW
DB $08, $00 ; BLUE
DB $08, $08 ; MAGENTA
DB $88, $00 ; CYAN
DB $88, $08 ; WHITE
DB $00, $00 ; BLACK
DB $00, $08 ; RED
DB $80, $00 ; GREEN
DB $80, $08 ; YELLOW
DB $08, $00 ; BLUE
DB $08, $08 ; MAGENTA
DB $88, $00 ; CYAN
DB $88, $08 ; WHITE
PALETTE640 DB $00, $00 ; BLACK
DB $00, $08 ; RED
DB $80, $08 ; YELLOW
DB $88, $08 ; WHITE
DB $00, $00 ; BLACK
DB $00, $08 ; RED
DB $80, $08 ; YELLOW
DB $88, $08 ; WHITE
DB $00, $00 ; BLACK
DB $00, $08 ; RED
DB $80, $08 ; YELLOW
DB $88, $08 ; WHITE
DB $00, $00 ; BLACK
DB $00, $08 ; RED
DB $80, $08 ; YELLOW
DB $88, $08 ; WHITE
SHRCOLMASK DB $00 ; Colour mask
* Enable SHR mode
SHRVDU22 JSR VDU12 ; Clear text and SHR screen
LDA #$80 ; Most significant bit
TSB NEWVIDEO ; Enable SHR mode
LDA VDUPIXELS ; Pixels per byte
CMP #$02 ; 2 is 320-mode (MODE 1)
BNE :MODE0
LDA #SCB320 ; SCB for 320-mode
LDY #00 ; Palette offset
BRA :S1
:MODE0 LDA #SCB640 ; SCB for 640-mode
LDY #32 ; Palette offset
:S1 LDX #$00
:L1 STAL $E19D00,X ; SCBs begin at $9D00 in $E1
INX
CPX #200 ; 200 lines so 200 SCBs
BNE :L1
LDX #$00
:L2 LDA PALETTE320,Y ; Offset in Y computed above
STAL $E19E00,X ; Palettes begin at $9E00 in $E1
INX
INY
CPX #32 ; 32 bytes in palette
BNE :L2
RTS
* Write character to SHR screen
* On entry: A - character to write
SHRPRCHAR SEC
SBC #32
STA ZP1+0 ; A*8 -> ZP1
STZ ZP1+1
ASL ZP1+0
ROL ZP1+1
ASL ZP1+0
ROL ZP1+1
ASL ZP1+0
ROL ZP1+1
CLC ; FONT8+A*8 -> ZP1
LDA ZP1+0
ADC #<FONT8
STA ZP1+0
LDA ZP1+1
ADC #>FONT8
STA ZP1+1
JSR SHRCHARADDR ; Addr in VDUADDR
LDY #$00 ; First row of char
:L1 >>> RDMAIN
LDA (ZP1),Y ; Load row of font
>>> RDAUX
LDX VDUPIXELS ; Pixels per byte
CPX #$02 ; 2 is 320-mode (MODE 1)
BNE :S1
JSR SHRCHAR320
BRA :S2
:S1 JSR SHRCHAR640
:S2 JSR SHRNEXTROW ; Add 160 to VDUADDR
INY ; Next row of font
CPY #$08 ; Last row?
BNE :L1
RTS
* Draw one pixel row of font in 320 mode
* 4 bytes per char, 4 bits per pixel
SHRCHAR320 PHY
LDA #$FF
LDY #$00
STA [VDUADDR],Y
INY
STA [VDUADDR],Y
INY
STA [VDUADDR],Y
INY
STA [VDUADDR],Y
PLY
RTS
* Draw one pixel row of font in 640 mode
* 2 bytes per char, 2 bits per pixel
SHRCHAR640 PHY
STZ :TEMP
LDX #$00 ; Source bit index
:L1 ASL ; MS bit -> C
PHP ; Preserve C
ROL :TEMP ; C -> LS bit
PLP ; Recover C
ROL :TEMP ; C -> LS bit
INX
CPX #$04
BNE :L1
PHA
LDA :TEMP
AND SHRCOLMASK ; Mask to set colour
STA [VDUADDR]
PLA
STZ :TEMP
LDX #$00
:L2 ASL ; MS bit -> C
PHP ; Preserve C
ROL :TEMP ; C -> LS bit
PLP ; Recover C
ROL :TEMP ; C -> LS bit
INX
CPX #$04
BNE :L2
LDA :TEMP
LDY #$01
AND SHRCOLMASK ; Mask to set colour
STA [VDUADDR],Y
PLY
RTS
:TEMP DB $00
* Calculate character address in SHR screen memory
* This is the address of the first pixel row of the char
* Add $00A0 for each subsequent row
SHRCHARADDR LDA #$20 ; MSB starts at $20
LDY VDUTEXTY
:L1 CPY #$00
BEQ :S1
CLC
ADC #05 ; Each char row is $500
DEY
BRA :L1
:S1 STA VDUADDR+1 ; MSB of address
LDA VDUTEXTX
ASL ; Mult x 2 (4 pixels/byte)
LDY VDUPIXELS ; Pixels per byte
CPY #$02 ; 2 pixels per byte in 320 mode
BNE :S2
ASL ; Mult x 2 (2 pixels/byte)
:S2 STA VDUADDR+0 ; LSB of address
LDA #$E1 ; Bank $E1
STA VDUBANK
RTS
* (VDUADDR)=>character address, X=preserved
* Advance VDUADDR to the next row of pixels
SHRNEXTROW LDA VDUADDR+0 ; Add 160 to VDUADDR
CLC
ADC #160
STA VDUADDR+0
LDA VDUADDR+1
ADC #$00
STA VDUADDR+1
RTS
* Forwards scroll one line
SHRSCR1LINE
RTS
* Reverse scroll one line
SHRRSCR1LINE
RTS
* Clear from current location to EOL
* TODO: This is only for 640 mode at present
SHRCLREOL JSR SHRCHARADDR
STZ VDUADDR+0 ; Addr of start of line
LDA #$08 ; Eight rows
STA :CTR
:L0 LDA VDUTEXTX
TAX
ASL ; 2 bytes / char
TAY
LDA #$00
:L1 CPX TXTWINRGT
BCS :S1
STA [VDUADDR],Y
INY
STA [VDUADDR],Y
INY
INX
BRA :L1
:S1 JSR SHRNEXTROW
DEC :CTR
BNE :L0
RTS
:CTR DB $00
* VDU16 (CLG) clears the whole SHR screen right now
SHRCLEAR PHP ; Disable interrupts
SEI
CLC ; 816 native mode
XCE
REP #$10 ; 16 bit index
MX %10 ; Tell Merlin
LDX #$0000
LDA #$00
:L1 STAL $E12000,X ; SHR screen @ E1:2000
INX
CPX #$7D00
BNE :L1
SEP #$10 ; Back to 8 bit index
MX %11 ; Tell Merlin
SEC ; Back to 6502 emu mode
XCE
PLP ; Normal service resumed
RTS
* Set text colour
* A=txt colour
SHRSETTCOL TAX
LDA :MASKS640,X ; Lookup mask in table
STA SHRCOLMASK ; Set colour mask
RTS
:MASKS640 DB %00000000
DB %01010101
DB %10101010
DB %11111111