* 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+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