* MAINMEM.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.) * * This code is in main memory only to save space in aux LC. * ****************************************************************************** * Data in bank $E1 ****************************************************************************** SHRFONTXPLD EQU $A000 ; Explode SHR font to $E1:A000 ****************************************************************************** SHRPIXELS DB $00 ; Main memory copy of VDUPIXELS SHRVDUQ DS 16 ; Main memory copy of VDUQ * Explode font to generate SHRFONTXPLD table * This is 2 bytes x 8 rows for each character in 640 mode * or 4 bytes x 8 rows for each character in 320 mode SHRXPLDFONT >>> ENTMAIN LDA #SHRFONTXPLD STA A3H LDA #$E1 ; Memory bank $E1 STA A4L LDA #32 ; First char number :L1 JSR SHRXPLDCHAR ; Explode char A INC A CMP #128 ; 96 chars in FONT8 BNE :L1 >>> XF2AUX,SHRV22RET RTS * Explode one character to location pointed to by A3L * On entry: A - character to explode SHRXPLDCHAR PHA SEC SBC #32 STA A1L ; A*8 -> A1L/H STZ A1H ASL A1L ROL A1H ASL A1L ROL A1H ASL A1L ROL A1H CLC ; FONT8+A*8 -> A1L/H LDA A1L ADC #FONT8 STA A1H LDY #$00 ; First row of char :L1 LDA (A1L),Y ; Load row of font JSR SHRXPLDROW INY ; Next row of font CPY #$08 ; Last row? BNE :L1 PLA RTS * Explode one pixel row of user defined graphics char SHRUSERCHAR >>> ENTMAIN LDA #SHRFONTXPLD STA A3H LDA #$E1 STA A4L LDA SHRVDUQ+0 ; Character number CMP #32 ; < 32? Then bail out BCC :DONE SEC ; Otherwise, subtract 32 SBC #32 TAY LDA #16 ; Bytes/char in 640 mode LDX SHRPIXELS ; Pixels per byte CPX #$02 ; 2 is 320-mode (MODE 1) BNE :S0 LDA #32 ; Bytes/char in 320 mode :S0 STA :INCREMENT :L0 CPY #$00 BEQ :S1 CLC LDA A3L ADC :INCREMENT STA A3L LDA A3H ADC #$00 STA A3H DEY BRA :L0 :S1 LDY #$00 :L1 LDA SHRVDUQ+1,Y ; Row of pixels JSR SHRXPLDROW INY CPY #$08 ; Last row? BNE :L1 :DONE RTS >>> XF2AUX,VDU23RET :INCREMENT DB $00 * Explode one row of pixels. Used by SHRXPLDCHAR & SHRUSERCHAR * On entry: A contains row of font data SHRXPLDROW LDX SHRPIXELS ; Pixels per byte CPX #$02 ; 2 is 320-mode (MODE 1) BNE :S1 JSR SHRCHAR320 BRA :S2 :S1 JSR SHRCHAR640 :S2 LDX SHRPIXELS ; Pixels per byte CPX #$02 ; 2 is 320-mode (MODE 1) BNE :S3 CLC ; 320 mode: add 4 to A3L LDA A3L ADC #$04 STA A3L LDA A3H ADC #$00 STA A3H BRA :S4 :S3 CLC ; 640 mode: add 2 to A3L LDA A3L ADC #$02 STA A3L LDA A3H ADC #$00 STA A3H :S4 RTS * Explode one pixel row of font in 320 mode * 4 bytes per char, 4 bits per pixel * On entry: A contains row of font data SHRCHAR320 PHY ; Preserve Y LDY #$00 ; Dest byte index :L0 STZ A2L LDX #$00 ; Source bit index :L1 ASL ; MS bit -> C PHP ; Preserve C ROL A2L ; C -> LS bit PLP ; Recover C PHP ROL A2L ; C -> LS bit PLP ; Recover C PHP ROL A2L ; C -> LS bit PLP ; Recover C ROL A2L ; C -> LS bit INX CPX #$02 ; Processed two bits of font? BNE :L1 PHA ; Preserve partially shifted font LDA A2L STA [A3L],Y PLA ; Recover partially shifted font INY CPY #$04 ; Done 4 bytes? BNE :L0 PLY ; Recover Y RTS * Explode one pixel row of font in 640 mode * 2 bytes per char, 2 bits per pixel * On entry: A contains row of font data SHRCHAR640 PHY ; Preserve Y LDY #$00 ; Dest byte index :L0 STZ A2L LDX #$00 ; Source bit index :L1 ASL ; MS bit -> C PHP ; Preserve C ROL A2L ; C -> LS bit PLP ; Recover C ROL A2L ; C -> LS bit INX CPX #$04 BNE :L1 PHA ; Preserve partially shifted font LDA A2L STA [A3L],Y PLA ; Recover partially shifted font INY CPY #$02 ; Done 2 bytes? BNE :L0 PLY ; Recover Y RTS * Plot actions: PLOT k,x,y * k is in SHRVDUQ+4 * x is in SHRVDUQ+5,SHRVDUQ+6 * y is in SHRVDUQ+7,SHRVDUQ+8 * * Plot actions: * $00+x - move/draw lines * $40+x - plot point * $50+x - fill triangle * $60+x - fill rectangle * $90+x - draw circle * $98+x - fill circle * SHRPLOT >>> ENTMAIN JSR SHRCOORD ; Convert coordinates * ... >>> XF2AUX,GFXPLOTRET RTS * Convert high-resolution screen coordinates * from 1280x1024 to 620x200 or 320x200 * TODO: Totally untested ... SHRCOORD PHP ; Disable interrupts SEI CLC ; 65816 native mode XCE REP #$30 ; 16 bit M & X MX %00 ; Tell Merlin * X-coordinate in SHRVDUQ+5,+6 MODE0:1280/2=640 or MODE1:1280/4=320 LDA SHRPIXELS ; Pixels per byte AND #$00FF CMP #$02 ; 2 is 320-mode (MODE 1) BNE :MODE0 LDA SHRVDUQ+5 LSR ; /2 LSR ; /4 STA A1L ; TODO: Store somewhere sensible BRA :Y :MODE0 LDA SHRVDUQ+5 LSR ; /2 STA A1L ; TODO: Store somewhere sensible * Y-coordinate in SHRVDUQ+7,+8 1024*3/16=192, 1024/128=8, 192+8=200 :Y LDA SHRVDUQ+7 ASL ; *2 CLC ADC SHRVDUQ+7 ; *3 LSR ; *3/2 LSR ; *3/4 LSR ; *3/8 LSR ; *3/16 STA A1L ; (A1L and A1H) LDA SHRVDUQ+7 LSR ; /2 LSR ; /4 LSR ; /8 LSR ; /16 LSR ; /32 LSR ; /64 LSR ; /128 CLC ADC A1L ; Result STA A1L ; TODO: Store somewhere sensible SEC ; Back to emulation mode XCE MX %11 ; Tell Merlin PLP ; Normal service resumed RTS