-
Notifications
You must be signed in to change notification settings - Fork 8
/
auxmem.shr.s
653 lines (602 loc) · 26 KB
/
auxmem.shr.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
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
* 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
* Pixel masks for colours in 640 mode
SHRCMASK640 DB %00000000
DB %01010101
DB %10101010
DB %11111111
* Pixel masks for colours in 320 mode
SHRCMASK320 DB $00
DB $11
DB $22
DB $33
DB $44
DB $55
DB $66
DB $77
DB $88
DB $99
DB $AA
DB $BB
DB $CC
DB $DD
DB $EE
DB $FF
* Addresses of start of text rows in SHR
* LS byte is always zero
* Add $A0 to get to next row of pixels
SHRTAB DB $20 ; Text row 0
DB $25 ; Text row 1
DB $2a ; Text row 2
DB $2f ; Text row 3
DB $34 ; Text row 4
DB $39 ; Text row 5
DB $3e ; Text row 6
DB $43 ; Text row 7
DB $48 ; Text row 8
DB $4d ; Text row 9
DB $52 ; Text row 10
DB $57 ; Text row 11
DB $5c ; Text row 12
DB $61 ; Text row 13
DB $66 ; Text row 14
DB $6b ; Text row 15
DB $70 ; Text row 16
DB $75 ; Text row 17
DB $7a ; Text row 18
DB $7f ; Text row 19
DB $84 ; Text row 20
DB $89 ; Text row 21
DB $8e ; Text row 22
DB $93 ; Text row 23
* Enable SHR mode
SHRVDU22 LDA #$18 ; Inhibit SHR & aux HGR shadowing
TSB SHADOW
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
STZ CLR80VID ; 40 column text mode
BRA :S1
:MODE0 LDA #SCB640 ; SCB for 640-mode
STZ SET80VID ; 80 column text mode
:S1 LDX #$00
:L1 STAL $E19D00,X ; SCBs begin at $9D00 in $E1
INX
CPX #200 ; 200 lines so 200 SCBs
BNE :L1
JSR SHRDEFPAL ; Default palette
>>> XF2MAIN,SHRXPLDFONT ; Explode font -> SHRFONTXPLD table
SHRV22RET >>> ENTAUX
JSR VDU12 ; Clear text and SHR screen
RTS
******************************************************************************
* Data in bank $E1
******************************************************************************
* Used for long writes
SHRCOLMASKL EQU $E1B000 ; Colour mask foreground (word)
SHRBGMASKL EQU $E1B002 ; Colour mask background (word)
* Used for reads via data bank reg
SHRCOLMASK EQU $B000 ; Colour mask foreground (word)
SHRBGMASK EQU $B002 ; Colour mask background (word)
******************************************************************************
SHRBGMASKA DW $0000 ; Keep a copy in aux mem too
* Write character to SHR screen
* On entry: A - character to write
SHRPRCHAR LDX VDUPIXELS ; Pixels per byte
CPX #$02 ; 2 is 320-mode (MODE 1)
BNE :S1
JMP SHRPRCH320
:S1 JMP SHRPRCH640
* Plot or unplot a cursor on SHR screen
* On entry: A - character to plot,
* CS show cursor / CC remove cursor
* VS read cursor / VC write cursor
* The read and write cursors have separate save-unders in :SAVEBYTES
SHRCURSOR PHP ; Preserve flags
PHA ; Preserve A
LDA VDUSTATUS ; If VDU5 mode, bail
AND #$20
BNE SHRCURSBAIL
JSR SHRCHARADDR ; Screen addr in VDUADDR
>>> WRTMAIN
LDA VDUADDR+0 ; Copy addr to SHRVDUQ
STA SHRVDUQ+0
LDA VDUADDR+1
STA SHRVDUQ+1
>>> WRTAUX
PLA ; Recover A
PLY ; Flags -> Y
>>> XF2MAIN,SHRCURSM
SHRCURSRET >>> ENTAUX
RTS
SHRCURSBAIL PLA
PLP
RTS
* Write character to SHR screen in 320 pixel mode
SHRPRCH320 SEC
SBC #32
TAX
LDA VDUSTATUS
AND #$20 ; Bit 5 text@gfx cursor
BEQ SHRPRCH320V4 ; VDU 4
TXA
>>> XF2MAIN,SHRVDU5CH ; VDU5
SHRPRCH320RET >>> ENTAUX
RTS
SHRPRCH320V4 TXA
CLC ; 65816 native mode
XCE
REP #$30 ; 16 bit M & X
MX %00 ; Tell Merlin
AND #$00FF
STA VDUADDR2 ; A*32 -> VDUADDR2
ASL VDUADDR2
ASL VDUADDR2
ASL VDUADDR2
ASL VDUADDR2
ASL VDUADDR2
CLC ; SHRFONTXPLD+A*32 -> VDUADDR2
LDA VDUADDR2
ADC #SHRFONTXPLD
STA VDUADDR2
SEP #$30 ; 8 bit M & X
MX %11 ; Tell Merlin
LDA #$E1
STA VDUBANK2
JSR SHRCHARADDR ; Screen addr in VDUADDR
* 65816 code contributed by John Brooks follows ...
PHB ; Save data bank
LDA VDUBANK2 ; Push font Bank onto stack
PHA
PLB ; Set data bank to font bank
REP #$30 ; 16 bit M & X
MX %00 ; Tell Merlin
LDY VDUADDR2 ; Font src ptr
LDX VDUADDR ; SHR dst ptr
LDA !$000000,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10000,X ; Write 2 bytes to screen
LDA !$000002,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10002,X ; Write 2 bytes to screen
LDA !$000004,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E100A0,X ; Write 2 bytes to screen
LDA !$000006,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E100A2,X ; Write 2 bytes to screen
LDA !$000008,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10140,X ; Write 2 bytes to screen
LDA !$00000A,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10142,X ; Write 2 bytes to screen
LDA !$00000C,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E101E0,X ; Write 2 bytes to screen
LDA !$00000E,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E101E2,X ; Write 2 bytes to screen
LDA !$000010,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10280,X ; Write 2 bytes to screen
LDA !$000012,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10282,X ; Write 2 bytes to screen
LDA !$000014,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10320,X ; Write 2 bytes to screen
LDA !$000016,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10322,X ; Write 2 bytes to screen
LDA !$000018,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E103C0,X ; Write 2 bytes to screen
LDA !$00001A,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E103C2,X ; Write 2 bytes to screen
LDA !$00001C,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10460,X ; Write 2 bytes to screen
LDA !$00001E,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10462,X ; Write 2 bytes to screen
PLB ; Recover data bank
SEC ; Back to emulation mode
XCE
MX %11 ; Tell Merlin
RTS
* Write character to SHR screen in 640 pixel mode
SHRPRCH640 SEC
SBC #32
TAX
LDA VDUSTATUS
AND #$20 ; Bit 5 text@gfx cursor
BEQ SHRPRCH640V4 ; VDU 4
TXA
>>> XF2MAIN,SHRVDU5CH ; VDU5
* (Returns via SHRPRCH320RET)
SHRPRCH640V4 TXA
CLC ; 65816 native mode
XCE
REP #$30 ; 16 bit M & X
MX %00 ; Tell Merlin
AND #$00FF
STA VDUADDR2 ; A*16 -> VDUADDR2
ASL VDUADDR2
ASL VDUADDR2
ASL VDUADDR2
ASL VDUADDR2
CLC ; SHRFONTXPLD+A*16 -> VDUADDR2
LDA VDUADDR2
ADC #SHRFONTXPLD
STA VDUADDR2
SEP #$30 ; 8 bit M & X
MX %11 ; Tell Merlin
LDA #$E1
STA VDUBANK2
JSR SHRCHARADDR ; Screen addr in VDUADDR
* 65816 code contributed by John Brooks follows ...
PHB ; Save data bank
LDA VDUBANK2 ; Push font Bank onto stack
PHA
PLB ; Set data bank to font bank
REP #$30 ; 16 bit M & X
MX %00 ; Tell Merlin
LDY VDUADDR2 ; Font src ptr
LDX VDUADDR ; SHR dst ptr
LDA !$000000,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10000,X ; Write 2 bytes to screen
LDA !$000002,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E100A0,X ; Write 2 bytes to screen
LDA !$000004,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10140,X ; Write 2 bytes to screen
LDA !$000006,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E101E0,X ; Write 2 bytes to screen
LDA !$000008,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10280,X ; Write 2 bytes to screen
LDA !$00000A,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10320,X ; Write 2 bytes to screen
LDA !$00000C,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E103C0,X ; Write 2 bytes to screen
LDA !$00000E,Y ; Read 2 bytes of exploded font
JSR SHRCOLWORD
STAL $E10460,X ; Write 2 bytes to screen
PLB ; Recover data bank
SEC ; Back to emulation mode
XCE
MX %11 ; Tell Merlin
RTS
* Apply colour masks to 16 bit word of character data
* Called in 65816 native mode, 16 bit
SHRCOLWORD MX %00 ; Tell Merlin 16 bit M & X
PHA ; Keep A
AND SHRCOLMASK ; Mask to set foreground colour
STA ZP1 ; Keep foreground
PLA ; Get original A back
EOR #$FFFF ; Invert bits
AND SHRBGMASK ; Apply background colour mask
EOR ZP1 ; Combine with foreground
RTS
MX %11
* 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 LDY VDUTEXTY
LDA SHRTAB,Y ; MSB
STA VDUADDR+1
LDA VDUTEXTX
ASL ; Mult x 2 (4 pixels/byte)
LDY VDUPIXELS ; Pixels per byte
CPY #$02 ; 2 pixels per byte in 320 mode
BNE :S1
ASL ; Mult x 2 (2 pixels/byte)
:S1 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
* Copy text line A+1 to line A
* Note: Code for this courtesy Kent Dickey
SHRSCR1LINE PHY
PHX
STA VDUADDR+1 ; Screen line -> MSB
STZ VDUADDR+0 ; Zero LSB
CLC ; Enter native mode
XCE
PHB ; Preserve data bank
REP #$31 ; M,X 16 bit, carry clear
MX %00 ; Tell Merlin
LDA VDUADDR ; Screen line to scroll
ASL ; Mult 4
ASL
ADC VDUADDR ; Mult 5
STA VDUADDR ; VDUADDR = line * $500
LDA TXTWINLFT ; Left margin
LDY VDUPIXELS ; Pixels per byte
CPY #$02 ; 2 pixels per byte in 320 mode
BNE :S1
ASL ; Double TXTWINLFT
:S1 ASL ; 2 bytes / char
AND #$00ff ; Mask to get 8 bit result
ADC VDUADDR ; Add to beginning of line addr
STA VDUADDR ; VDUADDR = start position
SEP #$21 ; M 8 bit, X 16 bit, carry set
MX %10 ; Tell Merlin
LDA TXTWINRGT ; Compute width ..
SBC TXTWINLFT ; .. right minus left
LDY VDUPIXELS ; Pixels per byte
CPY #$02 ; 2 pixels per byte in 320 mode
BNE :S2
ASL ; Double the width for 320
INC A ; Plus one
:S2 REP #$31 ; M,X 16 bit, carry clear
MX %00 ; Tell Merlin
ASL ; 2 bytes / char
AND #$00ff ; Mask to get 8 bit result
ADC VDUADDR ; Add to start position
TAX ; Will use as index
PEA #$E1E1 ; Set databank to $E1
PLB
PLB
:LOOP1 LDA $2500,X ; 2 bytes, row 0
STA $2000,X
LDA $25A0,X ; row 1
STA $20A0,X
LDA $2640,X ; row 2
STA $2140,X
LDA $26E0,X ; row 3
STA $21E0,X
LDA $2780,X ; row 4
STA $2280,X
LDA $2820,X ; row 5
STA $2320,X
LDA $28C0,X ; row 6
STA $23C0,X
LDA $2960,X ; row 7
STA $2460,X
DEX ; Update index
DEX
BMI :DONE ; Jump out if odd->-ve
CPX VDUADDR ; Compare with start addr
BCS :LOOP1 ; Bytes left? Go again
:DONE PLB ; Recover data bank
SEC ; Back to emulation mode
XCE
PLX
PLY
RTS
* Reverse scroll one line
* Copy text line A to line A+1
SHRRSCR1LINE PHY
PHX
STA VDUADDR+1 ; Screen line -> MSB
STZ VDUADDR+0 ; Zero LSB
CLC ; Enter native mode
XCE
PHB ; Preserve data bank
REP #$31 ; M,X 16 bit, carry clear
MX %00 ; Tell Merlin
LDA VDUADDR ; Screen line to scroll
ASL ; Mult 4
ASL
ADC VDUADDR ; Mult 5
STA VDUADDR ; VDUADDR = line * $500
LDA TXTWINLFT ; Left margin
LDY VDUPIXELS ; Pixels per byte
CPY #$02 ; 2 pixels per byte in 320 mode
BNE :S1
ASL ; Double TXTWINLFT
:S1 ASL ; 2 bytes / char
AND #$00ff ; Mask to get 8 bit result
ADC VDUADDR ; Add to beginning of line addr
STA VDUADDR ; VDUADDR = start position
SEP #$21 ; M 8 bit, X 16 bit, carry set
MX %10 ; Tell Merlin
LDA TXTWINRGT ; Compute width ..
SBC TXTWINLFT ; .. right minus left
LDY VDUPIXELS ; Pixels per byte
CPY #$02 ; 2 pixels per byte in 320 mode
BNE :S2
ASL ; Double the width for 320
INC A ; Plus one
:S2 REP #$31 ; M,X 16 bit, carry clear
MX %00 ; Tell Merlin
ASL ; 2 bytes / char
AND #$00ff ; Mask to get 8 bit result
ADC VDUADDR ; Add to start position
TAX ; Will use as index
PEA #$E1E1 ; Set databank to $E1
PLB
PLB
:LOOP1 LDA $2000,X ; 2 bytes, row 0
STA $2500,X
LDA $20A0,X ; row 1
STA $25A0,X
LDA $2140,X ; row 2
STA $2640,X
LDA $21E0,X ; row 3
STA $26E0,X
LDA $2280,X ; row 4
STA $2780,X
LDA $2320,X ; row 5
STA $2820,X
LDA $23C0,X ; row 6
STA $28C0,X
LDA $2460,X ; row 7
STA $2960,X
DEX ; Update index
DEX
BMI :DONE ; Jump out if odd->-ve
CPX VDUADDR ; Compare with start addr
BCS :LOOP1 ; Bytes left? Go again
:DONE PLB ; Recover data bank
SEC ; Back to emulation mode
XCE
PLX
PLY
RTS
* Clear from current location to EOL
SHRCLREOL JSR SHRCHARADDR
STZ VDUADDR+0 ; Addr of start of line
LDA #$08 ; Eight rows of pixels
STA :CTR
INC TXTWINRGT
:L0 LDA VDUTEXTX
TAX
ASL ; 2 bytes / char
LDY VDUPIXELS ; Pixels per byte
CPY #$02 ; 2 is 320-mode (MODE 1)
BNE :S0
ASL ; 4 bytes / char
:S0 TAY
:L1 CPX TXTWINRGT
BCS :S1
LDA SHRBGMASKA
STA [VDUADDR],Y
INY
STA [VDUADDR],Y
INY
LDA VDUPIXELS ; Pixels per byte
CMP #$02 ; 2 is 320-mode (MODE 1)
BNE :S2
LDA SHRBGMASKA
STA [VDUADDR],Y
INY
STA [VDUADDR],Y
INY
:S2 INX
BRA :L1
:S1 JSR SHRNEXTROW
DEC :CTR
BNE :L0
DEC TXTWINRGT
RTS
:CTR DB $00
* VDU16 (CLG) clears the graphics window
SHRCLEAR >>> XF2MAIN,SHRVDU16
SHRCLRRET >>> ENTAUX
RTS
* Set text colour
* A=text colour
SHRSETTCOL PHA
LDX VDUPIXELS ; Pixels per byte
CPX #$02 ; 2 is 320-mode (MODE 1)
BNE :MODE0
AND #$80
BEQ :FORE320
PLA
AND #$0F
TAX
LDA SHRCMASK320,X ; Lookup mask in table
STAL SHRBGMASKL ; Set colour mask (BG)
STAL SHRBGMASKL+1
STA SHRBGMASKA
RTS
:FORE320 PLA
AND #$0F
TAX
LDA SHRCMASK320,X ; Lookup mask in table
STAL SHRCOLMASKL ; Set colour mask (FG)
STAL SHRCOLMASKL+1
RTS
:MODE0 AND #$80
BEQ :FORE640
PLA
AND #$03
TAX
LDA SHRCMASK640,X ; Lookup mask in table
STAL SHRBGMASKL ; Set colour mask (BG)
STAL SHRBGMASKL+1
STA SHRBGMASKA
RTS
:FORE640 PLA
AND #$03
TAX
LDA SHRCMASK640,X ; Lookup mask in table
STAL SHRCOLMASKL ; Set colour mask (FG)
STAL SHRCOLMASKL+1
RTS
* Set graphics colour
* 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
SHRSETGCOL PHA
LDY VDUPIXELS ; Pixels per byte
CPY #$02 ; 2 is 320-mode (MODE 1)
BNE :MODE0
AND #$80
BEQ :FORE320
PLA
AND #$0F
TAY
LDA SHRCMASK320,Y ; Lookup mask in table
>>> WRTMAIN
STA SHRGFXBGMASK
>>> WRTAUX
RTS
:FORE320 PLA
AND #$0F
TAY
LDA SHRCMASK320,Y ; Lookup mask in table
>>> WRTMAIN
STA SHRGFXFGMASK
STX SHRGFXACTION
>>> WRTAUX
RTS
:MODE0 AND #$80
BEQ :FORE640
PLA
AND #$03
TAY
LDA SHRCMASK640,Y ; Lookup mask in table
>>> WRTMAIN
STA SHRGFXBGMASK
>>> WRTAUX
RTS
:FORE640 PLA
AND #$03
TAY
LDA SHRCMASK640,Y ; Lookup mask in table
>>> WRTMAIN
STA SHRGFXFGMASK
STX SHRGFXACTION
>>> WRTAUX
RTS
* Wrapper to call SHRDEFPALM (which sets up default palette)
SHRDEFPAL >>> XF2MAIN,SHRDEFPALM
SHRDEFPALRET >>> ENTAUX
RTS