-
Notifications
You must be signed in to change notification settings - Fork 8
/
auxmem.hgr.s
348 lines (322 loc) · 9.98 KB
/
auxmem.hgr.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
* 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