-
Notifications
You must be signed in to change notification settings - Fork 8
/
auxmem.vdu.s
1461 lines (1350 loc) · 51.9 KB
/
auxmem.vdu.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
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
* AUXMEM.VDU.S
* (c) Bobbi 2021-2022 GPLv3
*
* Apple //e, //c & IIGS VDU Driver for 40/80 column mode (PAGE2)
*
* 15-Aug-2021 Optimised address calculations and PRCHRC.
* Entry point to move copy cursor.
* Start to consolidate VDU workspace.
* 16-Aug-2021 Added COPY cursor handling.
* 21-Aug-2021 CHR$(&80+n) is inverse of CHR$(&00+n)
* 21-Aug-2021 If screen scrolls, copy cursor adjusted.
* 05-Sep-2021 Starting to prepare VDU workspace.
* 09-Sep-2021 New dispatch routine.
* 22-Sep-2021 More VDU workspace, started MODE definitions.
* 23-Sep-2021 More or less sorted VDU workspace.
* 26-Sep-2021 Merged together JGH VDU updates and Bobbi GFX updates.
* Moved all graphics screen access code to gfx.s
* All 65816-specific code disabled.
* 29-Sep-2021 Windows VDU 26, VDU 28, VDU 29, colours VDU 20.
* 01-Oct-2021 VDU 18 (GCOL), start on updating VDU 25 (PLOT).
**********************************
* VDU DRIVER WORKSPACE LOCATIONS *
**********************************
* # marks variables that can't be moved
*
* VDU DRIVER ZERO PAGE
**********************
* $00D0-$00DF VDU driver zero page workspace
VDUSTATUS EQU $D0 ; $D0 # VDU status
* bit 7 = VDU 21 VDU disabled
* bit 6 = COPY cursor active
* bit 5 = VDU 5 Text at graphics cursor
* bit 4 = (Master shadow display)
* bit 3 = VDU 28 Text window defined
* bit 2 = VDU 14 Paged scrolling active
* bit 1 = Don't scroll (COPY cursor or VDU 5 mode)
* bit 0 = VDU 2 printer echo active
*
VDUCHAR EQU VDUSTATUS+1 ; $D1 current control character
VDUTEMP EQU VDUCHAR ; &D1
VDUADDR EQU VDUSTATUS+2 ; $D2 address of current char cell
VDUBANK EQU VDUADDR+2 ; $D4 screen bank
VDUADDR2 EQU VDUADDR+3 ; $D5 address being scrolled
VDUBANK2 EQU VDUBANK+3 ; $D7 screen bank being scrolled
PLOTACTION EQU VDUSTATUS+8 ; &D8
OLDCHAR EQU OSKBD1 ; &EC character under cursor
COPYCHAR EQU OSKBD2 ; &ED character under copy cursor
* VDU DRIVER MAIN WORKSPACE
***************************
FXLINES EQU BYTEVARBASE+217 ; Paged scrolling line counter
FXVDUQLEN EQU BYTEVARBASE+218 ; Length of pending VDU queue
VDUVARS EQU $290
VDUVAREND EQU $2ED
GFXWINLFT EQU VDUVARS+$00 ; # graphics window left
GFXWINBOT EQU VDUVARS+$02 ; # graphics window bottom \ window
GFXWINRGT EQU VDUVARS+$04 ; # graphics window right / size
GFXWINTOP EQU VDUVARS+$06 ; # graphics window top
TXTWINLFT EQU VDUVARS+$08 ; # text window left
TXTWINBOT EQU VDUVARS+$09 ; # text window bottom \ window
TXTWINRGT EQU VDUVARS+$0A ; # text window right / size
TXTWINTOP EQU VDUVARS+$0B ; # text window top
GFXORIGX EQU VDUVARS+$0C ; graphics X origin
GFXORIGY EQU VDUVARS+$0E ; graphics Y origin
*
GFXPOSNX EQU VDUVARS+$10 ; current graphics X posn
GFXPOSNY EQU VDUVARS+$12 ; current graphics Y posn
GFXLASTX EQU VDUVARS+$14 ; last graphics X posn
GFXLASTY EQU VDUVARS+$16 ; last graphics Y posn
VDUTEXTX EQU VDUVARS+$18 ; # absolute text X posn = POS+WINLFT
VDUTEXTY EQU VDUVARS+$19 ; # absolute text Y posn = VPOS+WINTOP
VDUCOPYX EQU VDUVARS+$1A ; absolute COPY text X posn
VDUCOPYY EQU VDUVARS+$1B ; absolute COPY text Y posn
*
PIXELPLOTX EQU VDUVARS+$1C ; PLOT graphics X in pixels
PIXELPLOTY EQU VDUVARS+$1E ; PLOT graphics Y in pixels
PIXELPOSNX EQU VDUVARS+$20 ; current graphics X in pixels
PIXELPOSNY EQU VDUVARS+$22 ; current graphics Y in pixels
PIXELLASTX EQU VDUVARS+$24 ; last graphics X in pixels
PIXELLASTY EQU VDUVARS+$26 ; last graphics Y in pixels
VDUWINEND EQU PIXELLASTY+1 ; VDU 26 clears up to here
*
CURSOR EQU VDUVARS+$28 ; character used for cursor
CURSORCP EQU VDUVARS+$29 ; character used for copy cursor
CURSORED EQU VDUVARS+$2A ; character used for edit cursor
*
VDUQ EQU VDUVARS+$2B ; $2B..$33
VDUQGFXWIND EQU VDUQ+1 ; Neatly becomes VDUVARS+$2C
VDUQPLOT EQU VDUQ+5 ; Neatly becomes VDUVARS+$30
VDUQCOORD EQU VDUQ+5
*
VDUVAR34 EQU VDUVARS+$34
VDUMODE EQU VDUVARS+$35 ; # current MODE
VDUSCREEN EQU VDUVARS+$36 ; # MODE type
TXTFGD EQU VDUVARS+$37 ; # Text foreground
TXTBGD EQU VDUVARS+$38 ; # Text background
GFXFGD EQU VDUVARS+$39 ; # Graphics foreground
GFXBGD EQU VDUVARS+$3A ; # Graphics background
GFXPLOTFGD EQU VDUVARS+$3B ; # Foreground GCOL action
GFXPLOTBGD EQU VDUVARS+$3C ; # Background GCOL action
VDUBORDER EQU VDUVARS+$3D ; Border colour
VDUCOLEND EQU VDUBORDER ; VDU 20 clears up to here
*
VDUVAR3E EQU VDUVARS+$3E
VDUBYTES EQU VDUVARS+$3F ; bytes per char, 1=text only
VDUCOLOURS EQU VDUVARS+$40 ; # colours-1
VDUPIXELS EQU VDUVARS+$41 ; # pixels per byte
VDUWORKSP EQU VDUVARS+$42 ; 28 bytes of general workspace
VDUWORKSZ EQU VDUVAREND-VDUWORKSP+1
*
* Screen definitions
* 0 1 3 4 6 7 ; MODEs sort-of completed
SCNTXTMAXX DB 79, 39, 39, 79, 39, 39, 39, 39 ; Max text column
SCNTXTMAXY DB 23, 23, 23, 23, 23, 23, 23, 23 ; Max text row
SCNBYTES DB 08, 08, 08, 01, 08, 01, 01, 01 ; Bytes per character
SCNCOLOURS DB 03, 15, 15, 01, 07, 01, 01, 01 ; Colours-1
SCNPIXELS DB 04, 02, 02, 00, 07, 00, 00, 00 ; Pixels per byte
SCNFALLBACK DB 03, 04, 05, 03, 04, 05, 06, 07 ; Fall back if unsupported
SCNTYPE DB 65, 64, 66, 01,128, 02, 00, 32 ; Screen type
* b7=FastDraw -> HGR mode
* b6=SHR mode on Apple IIgs
* b5=Teletext
* b1=40COL/20COL
* b0=40COL/80COL
* Colour table
CLRTRANS16 DB 00,01,04,08,02,14,11,10
DB 05,09,12,13,06,03,07,15
CLRTRANS8 DB 00,05,01,01,06,02,02,07
********************************************************************
* Note that we use PAGE2 80 column mode ($800-$BFF in main and aux)
* and PAGE1 HGR mode ($2000-$23ff in main only)
********************************************************************
* Addresses of start of text rows in PAGE2
SCNTAB DW $800,$880,$900,$980,$A00,$A80,$B00,$B80
DW $828,$8A8,$928,$9A8,$A28,$AA8,$B28,$BA8
DW $850,$8D0,$950,$9D0,$A50,$AD0,$B50,$BD0
* Output character to VDU driver
********************************
* On entry: A=character
* On exit: All registers trashable
* CS if printer echo enabled for this character
*
OUTCHAR LDX FXVDUQLEN
BNE ADDTOQ ; Waiting for chars
CMP #$7F
BEQ CTRLDEL ; =$7F - control char
CMP #$20
BCC CTRLCHAR ; <$20 - control char
BIT VDUSTATUS
BMI OUTCHEXIT ; VDU disabled
OUTCHARCP JSR PRCHRC ; Store char, checking keypress
OUTCHARCP2 JSR VDU09 ; Move cursor right
* OSBYTE &75 - Read VDUSTATUS
*****************************
BYTE75
OUTCHEXIT LDA VDUSTATUS
TAX
LSR A ; Return Cy=Printer Echo Enabled
RTS
CTRLDEL LDA #$20 ; $7F becomes $20
CTRLCHAR CMP #$01
BEQ ADDQ ; One param
CMP #$11
BCC CTRLCHARGO ; Zero params
ADDQ STA VDUCHAR ; Save initial character
AND #$0F
TAX
LDA QLEN,X
STA FXVDUQLEN ; Number of params to queue
BEQ CTRLCHARGO1 ; Zero, do it now
QDONE CLC ; CLC=Don't echo VDU queue to printer
RTS
ADDTOQ STA VDUQ-256+9,X
INC FXVDUQLEN
BNE QDONE
CTRLCHARGO1 LDA VDUCHAR
CTRLCHARGO ASL A
TAY
CMP #$10 ; 8*2
BCC CTRLCHARGO2 ; ctrl<$08, don't echo to printer
EOR #$FF ; ctrl>$0D, don't echo to printer
CMP #$E5 ; (13*2) EOR 255
CTRLCHARGO2 PHP ; Save CS=(ctrl>=8 && ctrl<=13)
JSR CTRLCHARJMP ; Call routine
PLP
BCS OUTCHEXIT ; If echoable, test if printer enabled
RTS ; Return, CC=Don't echo to printer
OUTCHARGO ASL A ; Entry point to move COPY cursor
TAY
CTRLCHARJMP CPY #6*2
BEQ CTRLCHAR6 ; Always allow VDU 6 through
BIT VDUSTATUS
BMI VDU00 ; VDU disabled
CTRLCHAR6 LDA CTRLADDRS+1,Y
PHA
LDA CTRLADDRS+0,Y
PHA
VDU27
VDU00 RTS
QLEN DB -0,-1,-2,-5,-0,-0,-1,-9 ; 32,1 or 17,18,19,20,21,22,23
DB -8,-5,-0,-0,-4,-4,-0,-2 ; 24,25,26,27,28,29,30,31
CTRLADDRS DW VDU00-1,VDU01-1,VDU02-1,VDU03-1
DW VDU04-1,VDU05-1,VDU06-1,BEEP-1
DW VDU08-1,VDU09-1,VDU10-1,VDU11-1
DW VDU12-1,VDU13-1,VDU14-1,VDU15-1
DW VDU16-1,VDU17-1,VDU18-1,VDU19-1
DW VDU20-1,VDU21-1,VDU22-1,VDU23-1
DW VDU24-1,VDU25-1,VDU26-1,VDU27-1
DW VDU28-1,VDU29-1,VDU30-1,VDU31-1
DW VDU127-1
* Turn things on and off
************************
* VDU 2 - Start print job
VDU02
* JSR select printer
LDA #$01 ; Set PrinterEcho On
BNE SETSTATUS
* VDU 5 - Text at graphics cursor
VDU05 LDX VDUPIXELS
BEQ SETEXIT ; 0 pixels per char, text only
CPX #$07 ; 7 pixels per char, HGR
BEQ SETEXIT
LDA #$20 ; Set VDU 5 mode
BNE SETSTATUS
* VDU 14 - Select paged scrolling
VDU14 STZ FXLINES ; Reset line counter
LDA #$04 ; Set Paged Mode
BNE SETSTATUS
* VDU 21 - Disable VDU
VDU21 LDA #$80 ; Set VDU disabled
SETSTATUS ORA VDUSTATUS ; Set bits in VDU STATUS
STA VDUSTATUS
SETEXIT RTS
* VDU 3 - End print job
VDU03
* JSR flush printer
LDA #$FE ; Clear Printer Echo
BNE CLRSTATUS
* VDU 4 - Text at text cursor
VDU04 LDA #$DF ; Clear VDU 5 mode
BNE CLRSTATUS
* VDU 15 - Disable paged scrolling
VDU15 LDA #$FB ; Clear paged scrolling
BRA CLRSTATUS
* VDU 6 - Enable VDU
VDU06 LDA #$7F ; Clear VDU disabled
CLRSTATUS AND VDUSTATUS
STA VDUSTATUS
RTS
* Editing cursor
****************
* Move editing cursor
* A=cursor key, CS from caller
COPYMOVE PHA
BIT VDUSTATUS
BVS COPYMOVE2 ; Edit cursor already on
JSR GETCHRC
STA COPYCHAR
LDA CURSORED
JSR SHOWWTCURSOR ; Show write cursor
SEC
JSR COPYSWAP2 ; Initialise copy cursor
ROR FLASHER
ASL FLASHER ; Ensure b0=0
LDA #$42
ORA VDUSTATUS
STA VDUSTATUS ; Turn cursor editing on
COPYMOVE2 PLA
AND #3 ; Convert to 8/9/10/11
ORA #8
COPYMOVE3 JMP OUTCHARGO ; Move edit cursor
* Swap between edit and copy cursors
COPYSWAP1 CLC ; CC=Swap TEXT and COPY
COPYSWAP2 LDX #1
COPYSWAPLP LDY VDUCOPYX,X
LDA VDUTEXTX,X
STA VDUCOPYX,X
BCS COPYSWAP3 ; CS=Copy TEXT to COPY
TYA
STA VDUTEXTX,X
COPYSWAP3 DEX
BPL COPYSWAPLP
COPYSWAP4 RTS
* Write character to screen
***************************
* Perform backspace & delete operation
VDU127 JSR VDU08 ; Move cursor back
LDA VDUSTATUS
AND #$20 ; Bit 5 VDU5 mode
BEQ :NOTVDU5
>>> XF2MAIN,SHRVDU127
RTS
:NOTVDU5 LDA #' ' ; Overwrite with a space
BRA PUTCHRC
* Display character at current (TEXTX,TEXTY)
PRCHRC PHA ; Save character
LDA VDUSTATUS
AND #$20 ; Bit 5 VDU5 mode
BEQ :S1
JMP PRCHR7 ; Jump over text mode stuff
:S1 BIT ESCFLAG
BMI :RESUME
JSR ESCPOLL
BCS :RESUME
BMI :RESUME
CMP #$13
BNE :RESUME
:PAUSE0 JSR ESCPOLL
BMI :RESUME
BCS :PAUSE0
CMP #$11
BNE :PAUSE0
BRA :RESUME
LDA KEYBOARD
BPL :RESUME ; No key pressed
EOR #$80
:PAUSE1 JSR KBDCHKESC ; Ask KBD to test if Escape
BIT ESCFLAG
BMI :RESUMEACK ; Escape, skip pausing
CMP #$13
BNE :RESUME ; Not Ctrl-S
STA KBDSTRB ; Ack. keypress
:PAUSE2 LDA KEYBOARD
BPL :PAUSE2 ; Loop until keypress
EOR #$80
CMP #$11 ; Ctrl-Q
BEQ :RESUMEACK ; Stop pausing
JSR KBDCHKESC ; Ask KBD to test if Escape
BIT ESCFLAG
BPL :PAUSE2 ; No Escape, keep pausing
:RESUMEACK STA KBDSTRB ; Ack. keypress
:RESUME PLA
* Put character to screen
* Puts character to text screen buffer, then in graphics mode,
* writes bitmap to graphics screen
PUTCHRC PHA
EOR #$80 ; Convert character to screen code
TAX
AND #$A0
BNE PRCHR4
CPX #$20
BCS PRCHR3 ; Not $80-$9F
LDA #$20
BIT VDUSCREEN
BEQ PRCHR3 ; Not teletext
LDX #$E0 ; Convert $80-$9F to space
PRCHR3 TXA
EOR #$40
TAX
PRCHR4 JSR CHARADDR ; Find character address
TXA ; Get character back
BIT VDUBANK
BPL PRCHR5 ; Not AppleGS, use short write
>>> WRTMAIN
STA [VDUADDR],Y
>>> WRTAUX
BRA PRCHR7
PRCHR5 BCC PRCHR6 ; Aux memory
>>> WRTMAIN
STA (VDUADDR),Y ; Store in main
>>> WRTAUX
BRA PRCHR7
PRCHR6 STA (VDUADDR),Y ; Store in aux
PRCHR7 PLA
BIT VDUSCREEN
BPL :NOTHGR
JMP HGRPRCHAR ; Write character to HGR
:NOTHGR BVC :NOTSHR
JMP SHRPRCHAR ; Write character to SHR
:NOTSHR RTS
* Wrapper around PUTCHRC used when showing the read cursor
* On entry: A - character used for cursor
SHOWRDCURSOR TAX ; Preserve character
BIT VDUSCREEN
BVS :SHR
TXA
JMP PUTCHRC
:SHR TXA ; Recover character
SEC ; CS: Show cursor
CLV ; VC: Read cursor
JMP SHRCURSOR
* Wrapper around PUTCHRC used when showing the write cursor
* On entry: A - character used for cursor
SHOWWTCURSOR TAX ; Preserve character
BIT VDUSCREEN
BVS :SHR
TXA
JMP PUTCHRC
:SHR TXA ; Recover character
SEC ; CS: Show cursor
BIT SETV ; VS: Write cursor
JMP SHRCURSOR
* Wrapper around PUTCHRC used when removing the read cursor
* On entry: A - character which was obscured by cursor
REMRDCURSOR TAX ; Preserve character
BIT VDUSCREEN
BVS :SHR
TXA
JMP PUTCHRC
:SHR TXA ; Recover character
CLC ; CC: Remove cursor
CLV ; VC: Read cursor
JMP SHRCURSOR
* Wrapper around PUTCHRC used when removing the write cursor
* On entry: A - character which was obscured by cursor
REMWTCURSOR TAX ; Preserve character
BIT VDUSCREEN
BVS :SHR
TXA
JMP PUTCHRC
:SHR TXA ; Recover character
CLC ; CC: Remove cursor
BIT SETV ; VS: Write cursor
JMP SHRCURSOR
* Wrapper around OUTCHARCP used when drawing the read cursor
* On entry: A - character which was obscured by cursor
PUTCOPYCURS TAX ; Preserve character
BIT VDUSCREEN
BVS :SHR
TXA
JMP OUTCHARCP
:SHR TXA ; Recover character
CLC ; CC: Remove cursor
CLV ; VC: Read cursor
JSR SHRCURSOR
JMP OUTCHARCP2
* OSBYTE &87 - Read character at cursor
***************************************
* Fetch character from screen at (TEXTX,TEXTY) and return MODE in Y
* Always read from text screen (which we maintain even in graphics mode)
BYTE87
GETCHRC JSR CHARADDR ; Find character address
BIT VDUBANK
BMI GETCHRGS
BCC GETCHR6 ; Aux memory
STZ RDMAINRAM ; Read main memory (IRQs off)
GETCHR6 LDA (VDUADDR),Y ; Get character
STZ RDCARDRAM ; Read aux memory
TAY ; Convert character
AND #$A0
BNE GETCHR7
TYA
EOR #$40
TAY
GETCHR7 TYA
EOR #$80
LDY VDUMODE ; Y=MODE
TAX ; X=char
GETCHROK RTS
GETCHRGS BCC GETCHR8 ; Aux memory
STZ RDMAINRAM ; Read main memory (IRQs off)
GETCHR8 LDA [VDUADDR],Y ; Get character
STZ RDCARDRAM ; Read aux memory
TAY ; Convert character
AND #$A0
BNE GETCHR9
TYA
EOR #$40
TAY
GETCHR9 TYA
EOR #$80
LDY VDUMODE ; Y=MODE
TAX ; X=char, set EQ/NE
RTS
* OSBYTE &86 - Get text cursor position
***************************************
BYTE86 LDY VDUTEXTY
LDX VDUTEXTX
RTS
* Calculate character address
*****************************
* NB: VDUBANK at VDUADDR+2 is set by VDU22
CHARADDR LDA VDUTEXTY
CHARADDRY ASL
TAY
LDA SCNTAB+0,Y ; LSB of row address
STA VDUADDR+0
LDA SCNTAB+1,Y ; MSB of row address
STA VDUADDR+1
LDA VDUTEXTX
BIT RD80VID
SEC
BPL CHARADDR40 ; 40-col
LSR A
CHARADDR40 TAY ; Y=offset into this row
LDA VDUBANK
AND #$FE
BCS CHARADDROK
ORA #$01
CHARADDROK STA VDUBANK
RTS
* (VDUADDR),Y=>character address
* VDUBANK = AppleGS screen bank
* CC=auxmem, CS=mainmem, X=preserved
* Handle paged mode when moving up the screen
VDUUP DEC FXLINES
BPL :DONE
STZ FXLINES
:DONE RTS
* Handle paged mode when moving down the screen
VDUDOWN LDA VDUSTATUS
AND #$04 ; Bit 2 -> paged mode
BEQ :DONE
LDA TXTWINBOT
SEC
SBC TXTWINTOP
STA :HEIGHT
INC FXLINES
LDA FXLINES
CMP :HEIGHT
BCC :DONE ; FXLINES <= limit
:L1 JSR BYTE76 ; Check keyboard
LDA FXKBDSTATE
AND #$01 ; See if Open Apple depressed
BEQ :L1 ; If not, spin
STZ FXLINES
:DONE RTS
:HEIGHT DB $00
* Generic return for all SHRVDUxx returns to aux mem
VDUXXRET >>> ENTAUX ; SHRVDU08 returns here
RTS
* Move text cursor position
***************************
* Move cursor left
VDU08 LDA VDUSTATUS
AND #$20 ; Bit 5 -> VDU5 mode
BEQ VDU08VDU4 ; VDU5 not in effect
BIT VDUSCREEN
BVC VDU08DONE ; VDU5 but not SHR
>>> XF2MAIN,SHRVDU08
VDU08VDU4 LDA VDUTEXTX ; COL
CMP TXTWINLFT
BEQ :S1
DEC VDUTEXTX ; COL
BRA VDU08DONE
:S1 LDA VDUTEXTY ; ROW
CMP TXTWINTOP
BEQ VDU08DONE
DEC VDUTEXTY ; ROW
LDA TXTWINRGT
STA VDUTEXTX ; COL
JSR VDUUP ; Handle paged mode
VDU08DONE RTS
* Move cursor right
VDU09 LDA VDUSTATUS
AND #$20 ; Bit 5 VDU 5 mode
BEQ VDU09VDU4 ; VDU5 not in effect
BIT VDUSCREEN
BVC VDU09DONE ; VDU5 but not SHR
>>> XF2MAIN,SHRVDU09
VDU09VDU4 LDA VDUTEXTX ; COL
CMP TXTWINRGT
BCC VDU09RGHT
LDA TXTWINLFT
STA VDUTEXTX ; COL
JSR VDUDOWN ; Handle paged mode
LDA VDUTEXTY ; ROW
CMP TXTWINBOT
BEQ SCROLL
INC VDUTEXTY ; ROW
VDU09DONE RTS
VDU09RGHT INC VDUTEXTX ; COL
BRA VDU09DONE
SCROLL JSR SCROLLER
LDA TXTWINLFT
STA VDUTEXTX
JSR CLREOL
RTS
* Move cursor down
VDU10 LDA VDUSTATUS
AND #$20 ; Bit 5 -> VDU5 mode
BEQ VDU10VDU4 ; VDU5 not in effect
BIT VDUSCREEN
BVC VDU10DONE ; VDU5 but not SHR
>>> XF2MAIN,SHRVDU10
VDU10VDU4 JSR VDUDOWN ; Handle paged mode
LDA VDUTEXTY ; ROW
CMP TXTWINBOT
BEQ VDU10SCRL
INC VDUTEXTY ; ROW
VDU10DONE RTS
VDU10SCRL JMP SCROLL
* Move cursor up
VDU11 LDA VDUSTATUS
AND #$20 ; Bit 5 -> VDU5 mode
BEQ VDU11VDU4 ; VDU5 not in effect
BIT VDUSCREEN
BVC VDU11DONE ; VDU5 but not SHR
>>> XF2MAIN,SHRVDU11
VDU11VDU4 LDA VDUTEXTY ; ROW
CMP TXTWINTOP
BNE VDU11UP
LDA VDUTEXTX ; COL
CMP TXTWINLFT
BNE VDU11DONE
JSR RSCROLLER
LDA TXTWINLFT
STA VDUTEXTX
JSR CLREOL
RTS
VDU11UP DEC VDUTEXTY ; ROW
JSR VDUUP ; Handle paged mode
VDU11DONE RTS
* Move to start of line
VDU13 LDA VDUSTATUS
AND #$20 ; Bit 5 -> VDU5 mode
BEQ VDU13VDU4 ; VDU5 not in effect
BIT VDUSCREEN
BVC VDU13DONE ; VDU5 but not SHR
>>> XF2MAIN,SHRVDU13
VDU13VDU4 LDA #$BF
JSR CLRSTATUS ; Turn copy cursor off
LDA TXTWINLFT
STA VDUTEXTX ; COL
VDU13DONE RTS
* Move to (0,0)
VDU30 LDA TXTWINTOP
STA VDUTEXTY ; ROW
LDA TXTWINLFT
STA VDUTEXTX ; COL
RTS
* Move to (X,Y)
VDU31 LDY VDUQ+8
CPY #24
BCS :DONE
LDX VDUQ+7
CPX #80
BCS :DONE
BIT RD80VID
BMI :T9A
CPX #40
BCS :DONE
:T9A STX VDUTEXTX ; COL
STY VDUTEXTY ; ROW
:DONE RTS
* Initialise VDU driver
***********************
* On entry, A=MODE to start in
*
VDUINIT STA VDUQ+8
* JSR FONTIMPLODE ; Reset VDU 23 font
* VDU 22 - MODE n
*****************
* MODEs available:
* MODE 0 - 640x200 SHR graphics, 80x24 bitmap text (GS only)
* MODE 1 - 320x200 SHR graphics, 40x24 bitmap text (GS only)
* MODE 2 --> MODE 1
* MODE 3 - 80x24 text
* MODE 4 - 280x192 HGR graphics, 40x24 bitmap text
* MODE 5 --> MODE 6
* MODE 6 - 40x24 text
* MODE 7 - 40x24 with $80-$9F converted to spaces
*
* On //e, MODE 0 -> MODE 3
* MODE 1 -> MODE 4
* MODE 2 -> MODE 5
*
VDU22 JSR NEGCALL ; Find machine type
AND #$0F
BEQ :NOTGS ; MCHID=$x0 -> Not AppleGS, bank=0
LDA #$E0 ; Not $x0 -> AppleGS, point to screen bank
:NOTGS STA VDUBANK
LDA VDUQ+8
AND #$07
; jgh
BIT VDUBANK
BMI :INIT ; All MODEs supported
CMP #$03
BCS :INIT
ADC #$03 ; Fall back to replacement MODE
; BIT VDUBANK
; BMI :INIT ; Skip if GS
; CMP #$00 ; Mode 0?
; BNE :S1
; LDA #$03 ; --> Mode 3 instead
; BRA :INIT
;:S1 CMP #$01 ; Mode 1?
; BNE :INIT
; LDA #$06 ; --> Mode 6 instead
:INIT TAX ; Set up MODE
STX VDUMODE ; Screen MODE
LDA SCNCOLOURS,X
STA VDUCOLOURS ; Colours-1
LDA SCNBYTES,X
STA VDUBYTES ; Bytes per char
LDA SCNPIXELS,X
STA VDUPIXELS ; Pixels per byte
>>> WRTMAIN
STA SHRPIXELS
>>> WRTAUX
LDA SCNTYPE,X
STA VDUSCREEN ; Screen type
LDA #$01
JSR CLRSTATUS ; Clear everything except PrinterEcho
LDA #'_' ; Set up default cursors
STA CURSOR ; Normal cursor
STA CURSORCP ; Copy cursor when editing
LDA #$A0
STA CURSORED ; Edit cursor when editing
JSR VDU20 ; Default colours
JSR VDU26 ; Default windows
STA FULLGR ; Clear MIXED mode
BIT VDUSCREEN
BPL :NOTHGR
JMP HGRVDU22 ; b7=1, HGR mode
:NOTHGR BVC :NOTSHR
JMP SHRVDU22 ; b6=1, SHR mode
:NOTSHR LDA VDUSCREEN
AND #$01 ; 40col/80col bit
TAX
STA CLR80VID,X ; Select 40col/80col
STA TEXTON ; Enable Text
STA PAGE2 ; PAGE2
STA SETALTCHAR ; Enable alt charset
LDA #$80 ; Most significant bit
TRB NEWVIDEO ; Turn off SHR
* Fall through into CLS
* Clear areas of the screen
***************************
VDU12 STZ FXLINES
LDA TXTWINTOP
STA VDUTEXTY
LDA TXTWINLFT
STA VDUTEXTX
* Clear the text screen buffer
:L1 JSR CLREOL
BIT VDUSCREEN
BPL :NOTHGR
JSR HGRCLREOL
BRA :NOTSHR
:NOTHGR BVC :NOTSHR
JSR SHRCLREOL
:NOTSHR LDA VDUTEXTY ; ROW
CMP TXTWINBOT
BEQ :S1
INC VDUTEXTY ; ROW
BRA :L1
:S1 LDA TXTWINTOP
STA VDUTEXTY ; ROW
LDA TXTWINLFT
STA VDUTEXTX ; COL
RTS
* Clear the graphics screen buffer
VDU12SOFT JMP VDU16 ; *TEMP*
* Clear to EOL, respecting text window boundaries
CLREOL JSR CHARADDR ; Set VDUADDR=>start of line
INC TXTWINRGT
BIT VDUBANK
BMI CLREOLGS ; AppleGS
BIT RD80VID
BPL :FORTY ; 40-col mode
:EIGHTY LDX VDUTEXTX ; Addr offset for column
:L1 TXA ; Column/2 into Y
LSR
TAY
LDA #$A0
BCS :MAIN ; Odd cols in main mem
STA (VDUADDR),Y ; Even cols in aux
BRA :SKIPMAIN
:MAIN >>> WRTMAIN
STA (VDUADDR),Y
>>> WRTAUX
:SKIPMAIN INX
CPX TXTWINRGT
BMI :L1
BRA CLREOLDONE
:FORTY LDA #$A0
:L2 >>> WRTMAIN
STA (VDUADDR),Y
>>> WRTAUX
INY
CPY TXTWINRGT
BMI :L2
CLREOLDONE DEC TXTWINRGT
BIT VDUSCREEN
BPL :NOHGR
JMP HGRCLREOL ; Clear an HGR line
:NOHGR BVC :NOSHR
JMP SHRCLREOL ; Clear an SHR line
:NOSHR RTS
CLREOLGS BIT RD80VID
BPL :FORTY ; 40-col mode
:EIGHTY LDX VDUTEXTX ; Addr offset for column
:L1 TXA ; Column/2 into Y
LSR
TAY
BCS :E0 ; Odd cols
LDA #$E1
STA VDUBANK
LDA #$A0
>>> WRTMAIN
STA [VDUADDR],Y ; Even cols in bank $E1
>>> WRTAUX
BRA :SKIPE0
:E0 LDA #$E0
STA VDUBANK
LDA #$A0
>>> WRTMAIN
STA [VDUADDR],Y ; Odd cols in bank $E0
>>> WRTAUX
:SKIPE0 INX
CPX TXTWINRGT
BMI :L1
BRA CLREOLDONE
:FORTY LDA #$E0
STA VDUBANK
LDA #$A0
:L2 >>> WRTMAIN
STA [VDUADDR],Y
>>> WRTAUX
INY
CPY TXTWINRGT
BMI :L2
BRA CLREOLDONE
* Scroll areas of the screen
****************************
* Scroll text window up one line
SCROLLER LDA TXTWINTOP
:L1 PHA
JSR SCR1LINE
BIT VDUSCREEN
BPL :NOTHGR
JSR HGRSCR1LINE ; Scroll HGR screen
BRA :NOTSHR
:NOTHGR BVC :NOTSHR
JSR SHRSCR1LINE ; Scroll SHR screen
:NOTSHR PLA
INC
CMP TXTWINBOT
BNE :L1
BIT VDUSTATUS
BVC :S1 ; Copy cursor not active
JSR COPYSWAP1
LDA #11
JSR OUTCHARGO
JSR COPYSWAP1
:S1 RTS
* Scroll text window down one line
RSCROLLER DEC TXTWINTOP
LDA TXTWINBOT
DEC A
:L1 PHA
JSR RSCR1LINE
BIT VDUSCREEN
BPL :NOTHGR
JSR HGRRSCR1LINE ; Reverse scroll HGR screen
BRA :NOTSHR
:NOTHGR BVC :NOTSHR
JSR SHRRSCR1LINE ; Reverse scroll SHR screen
:NOTSHR PLA
DEC A
CMP TXTWINTOP
BNE :L1
BIT VDUSTATUS
BVC :S1 ; Copy cursor not active
JSR COPYSWAP1
LDA #11
JSR OUTCHARGO
JSR COPYSWAP1
:S1 INC TXTWINTOP
RTS
* Copy line A to line A+1, respecting text window boundaries
RSCR1LINE PHA
INC A
JSR CHARADDRY ; VDUADDR=>line A+1
LDX #2
:L0 LDA VDUADDR,X ; Copy VDUADDR->VDUADDR2
STA VDUADDR2,X
DEX
BPL :L0
PLA
PHA
JSR CHARADDRY ; VDUADDR=>line A+1
BRA DOSCR1LINE
* Copy line A+1 to line A, respecting text window boundaries
SCR1LINE PHA
JSR CHARADDRY ; VDUADDR=>line A
LDX #2
:L0 LDA VDUADDR,X ; Copy VDUADDR->VDUADDR2
STA VDUADDR2,X
DEX
BPL :L0
PLA
PHA
INC A
JSR CHARADDRY ; VDUADDR=>line A+1
DOSCR1LINE INC TXTWINRGT
BIT VDUBANK
BMI SCR1LINEGS ; AppleGS
LDX TXTWINLFT ; Addr offset for column
BIT RD80VID
BPL :FORTY ; 40-col mode
:EIGHTY
:L1 TXA ; Column/2 into Y
LSR
TAY
BCS :MAIN ; Odd cols in main mem
LDA (VDUADDR),Y ; Even cols in aux
STA (VDUADDR2),Y
BRA :SKIPMAIN
:MAIN >>> WRTMAIN
STZ RDMAINRAM ; Read main memory (IRQs off)
LDA (VDUADDR),Y
STA (VDUADDR2),Y
STZ RDCARDRAM ; Read aux memory
>>> WRTAUX
:SKIPMAIN INX
CPX TXTWINRGT
BMI :L1
BRA SCR1LNDONE
:FORTY TXA
TAY
:L2 >>> WRTMAIN
STZ RDMAINRAM ; Read main memory (IRQs off)
LDA (VDUADDR),Y
STA (VDUADDR2),Y
STZ RDCARDRAM ; Read aux memory
>>> WRTAUX
INY
CPY TXTWINRGT
BMI :L2
SCR1LNDONE DEC TXTWINRGT
PLA
RTS