Applecorn/auxmem.hgr.s

349 lines
10 KiB
ArmAsm

* AUXMEM.HGR.S
* (c) Bobbi 2021-2022 GPLv3
*
* Routines for drawing bitmapped text and graphics in HGR mode (280x192)
* Most of these routines call into MAINMEM.HGR.S to actually do the
* drawing.
*
* 26-Sep-2021 All graphics screen code moved to here.
* 02-Oct-2021 Added temp'y wrapper to HGRPLOT.
* Addresses of start of pixel rows in PAGE1
HGRTAB DW $2000,$2080,$2100,$2180,$2200,$2280,$2300,$2380
DW $2028,$20A8,$2128,$21A8,$2228,$22A8,$2328,$23A8
DW $2050,$20D0,$2150,$21D0,$2250,$22D0,$2350,$23D0
* Enable HGR mode
HGRVDU22 JSR VDU12 ; Clear text and HGR screen
STA HIRES ; Hi-Res
STA GRON ; Enable Graphics
STA PAGE1 ; PAGE1
STA CLR80VID ; Select 40col text
LDA #$80 ; Most significant bit
TRB NEWVIDEO ; Turn off SHR
RTS
* Write character to HGR screen
HGRPRCHAR CMP #$A0 ; Convert to screen code
BCS :B0
CMP #$80
BCC :B0
EOR #$80
:B0 TAX
AND #$20
BNE :B1
TXA
EOR #$40
TAX
:B1 PHX
JSR HGRCHARADDR ; Addr in VDUADDR
>>> WRTMAIN
LDA VDUADDR+0
STA HGRADDR+0
LDA VDUADDR+1
STA HGRADDR+1
>>> WRTAUX
PLA ; Recover character
>>> XF2MAIN,DRAWCHAR ; Plot char on HGR screen
PUTCHRET >>> ENTAUX
RTS
* Calculate character address in HGR screen memory
* This is the address of the first pixel row of the char
* Add $0400 for each subsequent row of the char
HGRCHARADDR LDA VDUTEXTY
ASL
TAY
CLC
LDA HGRTAB+0,Y ; LSB of row address
ADC VDUTEXTX
STA VDUADDR+0
LDA HGRTAB+1,Y ; MSB of row address
ADC #$00
STA VDUADDR+1
RTS
* (VDUADDR)=>character address, X=preserved
* Forwards scroll one line
HGRSCR1LINE >>> WRTMAIN
LDX TXTWINLFT
STX MTXTWINLFT
LDX TXTWINRGT
STX MTXTWINRGT
>>> WRTAUX
>>> XF2MAIN,HGRSCR1L
HSCR1RET >>> ENTAUX
RTS
* Reverse scroll one line
HGRRSCR1LINE >>> WRTMAIN
LDX TXTWINLFT
STX MTXTWINLFT
LDX TXTWINRGT
STX MTXTWINRGT
>>> WRTAUX
>>> XF2MAIN,HGRRSCR1L
* Clear from current location to EOL
HGRCLREOL LDA VDUTEXTY
ASL
TAX
>>> WRTMAIN
LDA HGRTAB+0,X
STA HGRADDR+0
LDA HGRTAB+1,X
STA HGRADDR+1
LDA VDUTEXTX
STA MVDUTEXTX
LDA TXTWINRGT
STA MTXTWINRGT
>>> WRTAUX
>>> XF2MAIN,HCLREOL
* VDU16 (CLG) clears the whole HGR screen right now
HGRCLEAR >>> XF2MAIN,CLRHGR
VDU16RET >>> ENTAUX
STZ XPIXEL+0
STZ XPIXEL+1
LDA #191
STA YPIXEL
RTS
CLRLNRET >>> ENTAUX
RTS
* A=txt colour
HGRSETTCOL RTS
* A=gfx colour, X=gcol action
* GCOL actions:
* 0 = SET pixel
* 1 = ORA with pixel
* 2 = AND with pixel
* 3 = XOR with pixel
* 4 = NOT pixel
* 5 = NUL no change to pixel
* 6 = CLR clear pixel to background
* 7 = UND undefined
HGRSETGCOL PHA
LDA #$00 ; Normal drawing mode
CPX #$04 ; k=4 means toggle
BNE :NORM
LDA #$01 ; Change to toggle mode
:NORM >>> WRTMAIN
STA LINETYPE
STA FDRAWADDR+5
>>> WRTAUX
>>> XF2MAIN,SETLINE
VDU18RET1 >>> ENTAUX
:NORM PLA ; Colour
BPL :FOREGND ; <128 is foreground
>>> WRTMAIN
AND #$7F
STA BGCOLOR ; Stored in main memory
>>> WRTAUX
RTS
:FOREGND >>> WRTMAIN
STA FGCOLOR ; Stored in main memory
>>> WRTAUX
RTS
* Plot actions, PLOT k,x,y
* k is in VDUQ+4
* x is in VDUQ+5,VDUQ+6
* y is in VDUQ+7,VDUQ+8
*
* Plot actions capable with FastDraw:
* $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
*
HGRPLOT JSR HGRCOORD ; Convert coordinate system
HGRPLOT2 LDA VDUQ+4
AND #$03
CMP #$0 ; Bits 0,1 clear -> just move
BNE HGRPLOTACT
HGRPLOTPOS JMP HGRPOS ; Just update pos
HGRPLOTACT LDA VDUQ+4
AND #$F0
CMP #$00
BEQ :LINE
CMP #$40
BEQ :POINT
CMP #$60
BNE :S1
JMP :RECT
:S1 CMP #$90
BNE :UNDEF
JMP :CIRC
:UNDEF RTS
:POINT >>> WRTMAIN
LDA VDUQ+4
STA PLOTMODE
LDA VDUQ+5
STA FDRAWADDR+6 ; LSB of X1
LDA VDUQ+6
STA FDRAWADDR+7 ; MSB of X1
LDA VDUQ+7
STA FDRAWADDR+8 ; Y1
>>> WRTAUX
>>> XF2MAIN,DRAWPNT
:LINE >>> WRTMAIN
LDA VDUQ+4
STA PLOTMODE
LDA XPIXEL+0
STA FDRAWADDR+6 ; LSB of X1
LDA XPIXEL+1
STA FDRAWADDR+7 ; MSB of X1
LDA YPIXEL
STA FDRAWADDR+8 ; Y1
LDA VDUQ+5
STA FDRAWADDR+9 ; LSB of X2
LDA VDUQ+6
STA FDRAWADDR+10 ; MSB of X2
LDA VDUQ+7
STA FDRAWADDR+11 ; Y2
>>> WRTAUX
>>> XF2MAIN,DRAWLINE
:RECT >>> WRTMAIN
LDA VDUQ+4
STA PLOTMODE
LDA XPIXEL+0
STA FDRAWADDR+6 ; LSB of X1
LDA XPIXEL+1
STA FDRAWADDR+7 ; MSB of X1
LDA YPIXEL
STA FDRAWADDR+8 ; Y1
LDA VDUQ+5
STA FDRAWADDR+9 ; LSB of X2
LDA VDUQ+6
STA FDRAWADDR+10 ; MSB of X2
LDA VDUQ+7
STA FDRAWADDR+11 ; Y2
>>> WRTAUX
>>> XF2MAIN,FILLRECT
:CIRC >>> WRTMAIN
LDA XPIXEL+0
STA FDRAWADDR+6
LDA XPIXEL+1
STA FDRAWADDR+7
LDA YPIXEL
STA FDRAWADDR+8
LDA VDUQ+5
STA FDRAWADDR+12 ; Radius
LDA VDUQ+4
STA PLOTMODE
>>> WRTAUX
AND #$F8
CMP #$98
BEQ :FILLCIRC
>>> XF2MAIN,DRAWCIRC
:FILLCIRC >>> XF2MAIN,FILLCIRC
VDU25RET >>> ENTAUX
* Fall through into HGRPOS
* Save pixel X,Y position
HGRPOS LDA VDUQ+5
STA XPIXEL+0
LDA VDUQ+6
STA XPIXEL+1
LDA VDUQ+7
STA YPIXEL
RTS
XPIXEL DW $0000 ; Previous plot x-coord
YPIXEL DW $0000 ; Previous plot y-coord
* Convert high-resolution screen coordinates
* from 1280x1024 to 280x192
HGRCOORD
* X-coordinate in VDUQ+5,+6 1280*7/32=280
LDA VDUQ+6 ; MSB of X-coord
CMP #$05 ; $500 is 1280
BCS :BIGX ; Value >=1280
STA ZP1+1 ; X-coord -> ZP1 and ZP2
STA ZP2+1
LDA VDUQ+5
STA ZP1+0
ASL A ; ZP2 *= 8
ROL ZP2+1
ASL A
ROL ZP2+1
ASL A
ROL ZP2+1
SEC ; ZP2-ZP1->ZP2
SBC ZP1+0
STA ZP2+0
LDA ZP2+1
SBC ZP1+1
LSR A ; ZP2 /= 32
ROR ZP2+0
LSR A
ROR ZP2+0
LSR A
ROR ZP2+0
LSR A
ROR ZP2+0
LSR A
ROR ZP2+0
STA VDUQ+6 ; ZP2 -> X-coord
LDA ZP2+0
STA VDUQ+5
* Y-coordinate in VDUQ+7,+8 1024*3/16=192
:YCOORD LDA VDUQ+8 ; MSB of Y-coord
AND #$FC
BNE :BIGY ; Y>1023
LDA VDUQ+8 ; Y-coord -> ZP1
STA ZP1+1
STA ZP2+1
LDA VDUQ+7
STA ZP1+0
* STA ZP2+0
* LDA VDUQ+8
* JMP :YCOORD4
ASL A ; ZP2 *= 2
ROL ZP2+1
CLC ; ZP2+ZP1->ZP2
ADC ZP1+0
STA ZP2+0
LDA ZP2+1
ADC ZP1+1
LSR A ; ZP2 /= 16
ROR ZP2+0
LSR A
ROR ZP2+0
:YCOORD4 LSR A
ROR ZP2+0
LSR A
ROR ZP2+0
STZ VDUQ+8 ; MSB always zero
SEC
LDA #191 ; 191 - ZP2 -> Y-coord
SBC ZP2+0
STA VDUQ+7
CMP #192
BCS :BIGY
RTS
:BIGY STZ VDUQ+7 ; Y too large, row zero
STZ VDUQ+8
RTS
:BIGX LDA #$17 ; X too large, use 279
STA VDUQ+5
LDA #$01
STA VDUQ+6
BRA :YCOORD