-
Notifications
You must be signed in to change notification settings - Fork 4
/
screen.dasm16
957 lines (907 loc) · 26.5 KB
/
screen.dasm16
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
; Screen output and screen editor input
;
; Uses PETSCII. In the future, I'll make an ASCII version of this that
; makes more sense on the DCPU.
;
:RAMC7 ; Reverse text? 0=no
:RVS DAT 0
:RAMC8 ; Pointer: end of logical line for input
:INDX DAT 0
:RAMC9 ; Cursor X,Y position at start of input
:LXSP DAT 0
:RAMCA DAT 0
:RAMCB ; Code of Current Key Pressed
:SFDX DAT 0
:RAMCC ; 0 = Flash Cursor
:BLNSW DAT 0
:RAMCD ; Countdown to blink cursor
:BLNCT DAT 0
:RAMCE ; Character under cursor
:GDBLN DAT 0
:RAMCF ; Was last cursor blink on or off?
:BLNON DAT 0
:RAMD0 ; Input from Keyboard (0) or Screen (3)
:CRSW DAT 0
:RAMD1 ;Pointer to the Address of the Current Line
:PNT DAT 0
:RAMD3 ;Cursor Column on Current Line
:PNTR DAT 0
:RAMD4 ; Quote Mode (0=No)
:QTSW DAT 0
:RAMD5 ; End of current line
:LNMX DAT HW_COLS-1
:RAMD6 ; Current physical line number
:TBLX DAT 0
; code of final character
:RAMD7 DAT 0
:INSRT
:RAMD8 DAT 0
; Screen line link table
.DEFINE DL_UNLINKED 0x80
:LDTB1
:RAMD9
.FILL HW_ROWS+1 DL_UNLINKED
:RAM0287
:GDCOL DAT 0xe620
:RAM0288
:HIBASE DAT SCREENMEM
;
:RAM0286
:COLOR DAT 0xE600
;
; AUTODN controls a subtle change in behavior between
; printing and typing.
:RAM0292
:AUTODN DAT 0
;
; Temporary index to the next line for screen scrolling
:RAM02A5 DAT 0
:SCREENMEM
.FILL HW_COLS*HW_ROWS BLANK
:SCREENMEMEND
; when HW_ROWS < 12, the bottom line displays
; various debugging information.
:DEBUGSPC
DAT 0xA004, 0xA002, 0xA03A, 0xA020 ; "DB: "
; debug keyboard I/O
DAT 0xA00B, 0xA03A ; "K:"
:DEBUGKEY
.FILL 10 BLANK
; debug line link tbl
DAT 0xA00C, 0xA03A ; "L:"
:DEBUGLNK
.FILL 14 BLANK
; debug vblank interrupt
DAT 0xA009, 0xA03A; "I:"
:DEBUGINT
.FILL 6 BLANK
.FILL HW_COLS-29 0xA02E
; get screen geometry
:DEF_SCREEN
:ROME505 SET X, HW_COLS
SET Y, HW_ROWS
RTS
; set cursor x/y
:DEF_PLOT
:ROME50A IFN C, 0
JMP ROME513
SET [TBLX], X ; Line number
SET [PNTR], Y ; Column
JSR ROME56C
:ROME513 SET X, [TBLX]
SET Y, [PNTR]
RTS
; initialize screen and keyboard
:ROME518
;JSR ROME5A0 ; initialize VIC chip - skip
SET [MODE], 0
SET [BLNON], 0
SET [RAM028F], ROMEB48
SET [BLNCT], 12
SET [BLNSW], 12
SET [XMAS], 10
SET [RAM028A], 10
SET [COLOR], 0xE600 ; lt blue on blue
SET [RAM028C], REPEAT_FRAMES_A ; key repeat speed
SET [RAM028B], REPEAT_FRAMES_B ; key repeat speed
:ROME544 ; Initialize screen link table
; and clear the screen. The 16-bit
; version doesn't need to attach
; the high byte of memory to this.
SET I, LDTB1
SET J, 0
:LINCLRLOOP STI [I], DL_UNLINKED
IFN J, HW_ROWS+1
JMP LINCLRLOOP
SET X, HW_ROWS-1
:ROME560 JSR ROME9FF ; clear one screen line
SUB X, 1
IFA X, -1 ; BPL
JMP ROME560
:ROME566 ; HOME cursor
SET [PNTR], 0 ; column 0
SET [TBLX], 0 ; row 0
; set address of current screen line
:ROME56C
SET X, [TBLX]
:ROME570 SET Y, [X+LDTB1]
IFB Y, DL_UNLINKED
JMP ROME57C
; this is 32 characters further
; in the previous line
ADD [PNTR], HW_COLS
SUB X, 1
IFA X, -1
JMP ROME570
:ROME57C JSR ROME9F0 ; set PNT line pointer
SET A, HW_COLS-1
ADD X, 1
:ROME582 SET Y, [X+LDTB1]
IFB Y, DL_UNLINKED
JMP ROME58C
ADD A, HW_COLS
ADD X, 1
JMP ROME582
:ROME58C SET [LNMX], A ; maximum line length
;JMP ROMEA24
RTS
:ROME591 IFN X, [LXSP]
RTS
JMP ROME6ED ; find beginning of logical line
; WAIT FOR RETURN FOR KEYBOARD
:ROME5CA JSR ROME716 ; output to the screen
:ROME5CD SET A, [NDX]
SET [BLNSW], A ; only blink if buffer is empty
SET [AUTODN], A ; Don't scroll until buffer is empty
IAQ 0 ; the c64 didn't have to manually enable ints here
IFE A, 0
JMP ROME5CD ; Loop until something changes?
:ROME5D6 IAQ 1 ; SEI
IFE [BLNON], 0
JMP ROME5E7
; restore haracter under cursor
SET [BLNON], 0
SET [BLNCT], 2
SET A, [PNT]
ADD A, [PNTR]
SET [A], [GDBLN]
:ROME5E7 JSR ROME5B4 ; get character from buffer
;IFN A, CBM_RUN ; RUN key
; JMP ROME5FE
; copy LOAD and RUN into buffer
;SET X, 9
;IAQ 1
;SET [NDX], X
:ROME5F3 ;DAT 0x5000
;JMP ROME5CD
:ROME5FE IFN A, CBM_RETURN
JMP ROME5CA
SET Y, [LNMX]
SET [CRSW], Y
ADD Y, [PNT]
:ROME606 SET A, [Y]
AND A, 0xFF
IFN A, 0x20 ; SPACE
JMP ROME60F
SUB Y, 1
IFN Y, [PNT] ; TODO: fix off-by-one
JMP ROME606
:ROME60F ADD Y, 1
SET [INDX], Y ; mark end of logical line
:ROME612 SET [AUTODN], 0 ; don't insert new lines when printing
SET [PNTR], 0 ; beginning of line
SET [QTSW], 0 ; turn off quote mode
SET A, [LXSP] ; get column at start of input
IFG [LXSP], 0x7F ; BMI
JMP ROME63A ; get chr from screen
SET X, [TBLX]
:ROME621 JSR ROME591
IFN X, [LXSP]
JMP ROME63A ; get chr from screen
SET A, [LXSP+1]
SET [PNTR], A
IFU A, [INDX]
JMP ROME63A ; get chr from screen
JMP ROME65D
:ROME632 ; get character from device 0 or 3
SET PUSH, Y
SET PUSH, X
IFE [CRSW], 0
JMP ROME5CD ; blink cursor, etc
; get character from current screen line
:ROME63A SET Y, [PNTR]
ADD Y, [PNT] ; Y <- current character location
SET A, [Y] ; A <- current character byte
; TODO: handle RVS text better
AND A, 0xFF
SET [RAMD7], A
AND A, 0x3F
; TODO: clean up for DCPU-16.
:ROME642 ; we don't need anyu shifting here
;SHL [RAMD7], 1
:ROME646 IFC [RAMD7], 0x40 ; original 0x40
JMP ROME64A
BOR A, 0x80
:ROME64A IFC [RAMD7], 0x80 ; original 0x80
JMP ROME650
IFN X, [QTSW]
JMP ROME654
:ROME650 IFB [RAMD7], 0x20 ; ASCII punctuation range
JMP ROME654 ; leave undisturbed
:ROME652 BOR A, 0x40 ;
:ROME654 ADD [PNTR], 1
IFE A, CBM_QUOTE
XOR [QTSW], 1
:ROME659 IFN Y, [INDX]
JMP ROME674
:ROME65D SET [CRSW], 0 ;
SET A, CBM_RETURN
IFE [DFLTN], 3
JMP ROME66F
IFE [DFLTO], 3
JMP ROME672
:ROME66F JSR ROME716 ; output to the screen
:ROME672 SET A, CBM_RETURN ; Register EOL
:ROME674 SET [RAMD7], A ; code of final character
SET X, POP
SET Y, POP
IFE A, 0xDE ; screen PI code
SET A, 0xFF ; petscii PI code
:ROME682 SET EX, 0 ; clc
SET C, 0
RTS
; create an XOR mask that swaps the background and
; foreground colors. The screen editor doesn't need to
; know about text printed in reverse -- just control
; characters, which still have the blink bit on.
:RVS_ON
SET A, [COLOR]
SET X, A
SHR A, 4
XOR A, X
SHR A, 4
XOR A, X
SHL A, 4
AND A, 0xFF00
SET [RVS], A
JMP ROME6A8
; fill screen at current position
:ROME691 BOR A, 0x40
:ROME693 SET X, [COLOR]
XOR X, [RVS] ; visual reverse only
JMP ROME699
; fill purposely with a control character
:ROME697 SET X, [COLOR]
SHL X, 4
SET B, EX
SHL X, 4
SET X, EX
SHL X, 4
BOR X, B
SHL X, 8
BOR A, 0x80 ; this means "blink" on LEM.
:ROME699 IFN [INSRT], 0
SUB [INSRT], 1
; TODO: proper RVS handling
JSR ROMEA13 ; place character on screen
JSR ROME6B6 ; advance cursor
; return from output to the screen
:ROME6A8
SET J, POP
SET I, POP
SET Y, POP
IFN [INSRT], 0
SHR [QTSW], 1
SET X, POP
SET A, POP
SET EX, 0
IAQ 0 ; RE-ENABLE INTERRUPTS
RTS
;advance the cursor, Get/insert new line
:ROME6B6 JSR ROME8B3 ; move cursor to next line if
; at end of line -- X will equal old line number
ADD [PNTR], 1
IFL [LNMX], [PNTR]
JMP ROME6C1
RTS
:ROME6C1 ; this branch is for when you type past the maximum logical line length
IFE [LNMX], (HW_COLS*ROWS_IN_LINE)-1
JMP ROME6F7 ; just move to next line
IFN [AUTODN], 0 ; if typing and not just printing
JMP ROME967 ; insert blank line underneath
:ROME6CD SET X, [TBLX] ; current row
IFL X, HW_ROWS
JMP ROME6DA ; skip scrolling
JSR ROME8EA ; scroll the screen first
SUB [TBLX], 1
SET X, [TBLX]
; link current line (X) with next line
:ROME6DA AND [LDTB1+X], 0xFFFF-DL_UNLINKED
BOR [LDTB1+1+X], DL_UNLINKED
:ROME6E6 ADD [LNMX], HW_COLS
:ROME6ED IFB [LDTB1+X], DL_UNLINKED
JMP ROME6F4
SUB X, 1
IFN X, 0
JMP ROME6ED
:ROME6F4 JMP ROME9F0 ; set PNT line pointer to X
:ROME6F7 SUB [TBLX], 1
JSR ROME87C ; Move cursor to next line
SET [PNTR], 0 ; beginning of
RTS
; move backwards over a line boundary
:ROME701 SET X, [TBLX]
IFN X, 0 ; at top of screen?
JMP ROME70B
SET [PNTR], 0 ; ? column 0
;SET A, POP ; not sure why we pop
;SET A, POP
;IFN A, 0
JMP ROME6A8
:ROME70B SUB X, 1
SET [TBLX], X
JSR ROME56C
SET [PNTR], [LNMX] ; end of line?
RTS
; SET NEXT LINE NUMBER
:ROME87C SHR [LXSP], 1 ; LSR $C9?
SET X, [TBLX]
:ROME880 ADD X, 1
IFE X, HW_ROWS
JSR ROME8EA ; scroll the screen
IFC [X+LDTB1], DL_UNLINKED ; if linked
JMP ROME880 ; repeat test with next line
SET [TBLX], X
:ROME88E JMP ROME56C ; Set PNT to current line
; action for RETURN
:ROME891 SET [INSRT], 0
SET [RVS], 0
SET [QTSW], 0
SET [PNTR], 0 ; column 0
JSR ROME87C ; Move cursor to next line
JMP ROME6A8 ; Return from outputting
; move cursor to previous line if at start of line
:ROME8A1 SET X, ROWS_IN_LINE ;2
SET A, 0
:ROME8A5 IFE [PNTR], A ;
JMP ROME8B0
ADD A, HW_COLS
SUB X, 1
IFN X, 0
JMP ROME8A5
RTS
:ROME8B0 SUB [TBLX], 1
RTS
; move cursor to next line if at end of line
:ROME8B3 SET X, ROWS_IN_LINE ;2
SET A, HW_COLS-1
:ROME8B7 IFE [PNTR], A ; at end of physical line #X
JMP ROME8C2 ; move to next line.
ADD A, HW_COLS
SUB X, 1
IFN X, 0
JMP ROME8B7
RTS
:ROME8C2 SET X, [TBLX]
IFN [TBLX], HW_ROWS
ADD [TBLX], 1
RTS
; check for color change codes
:ROME8CB
SET X, 0x0f
:ROME8CD IFE A, [ROME8DA+X]
JMP ROME8D6
SUB X, 1
IFA X, -1
JMP ROME8CD
RTS
:ROME8D6 AND [COLOR], 0x0F00
SHL X, 12
BOR [COLOR], X
RTS
:ROME8DA ; color codes
DAT 0x90, 0x05, 0x1c, 0x9f, 0x9c, 0x1E, 0x1F, 0x9E
DAT 0x81, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b
; scroll screen
:ROME8EA ; bypassed stack push of $AC-$AF.
:ROME8F6 SET X, -1
SUB [TBLX], 1
SUB [LXSP], 1
SUB [RAM02A5], 1 ; a temporary index
; Loop to the bottom of the screen and
; move each line upward, including its link
:ROME8FF ADD X, 1
JSR ROME9F0 ; set PNT line pointer to X
IFG X, HW_ROWS-2 ; CPX #$18
JMP ROME913 ; BCS $E913
SET A, X
ADD A, 1
MUL A, HW_COLS
ADD A, [HIBASE]
SET [SCPNT], A
JSR ROME9C8 ; move line up
JMP ROME8FF
:ROME913 JSR ROME9FF ; clear a screen line
SET X, 0
:ROME918 SET [LDTB1+X], [LDTB1+1+X]
ADD X, 1
IFl X, HW_ROWS-1
JMP ROME918
SET [LDTB1+HW_ROWS-1], DL_UNLINKED
:ROME92F IFC [LDTB1], DL_UNLINKED ; top line was linked
JMP ROME8F6 ; scroll another line
ADD [TBLX], 1
ADD [RAM02A5], 1
:ROME938 ; todo: Test for CTRL key
; ...
JMP ROME956
:ROME94B SET X, 10000 ; how long to pause
:ROME94D SET X, X; ; NOP
SUB X, 1;
IFN X, 0
JMP ROME94D
:ROME954 SET [NDX], 0 ; clear keyboard buffer
:ROME956 SET X, [TBLX]
:ROME958 RTS
; insert blank line in screen
:ROME965
SET X, [TBLX] ; current line
:ROME967 ADD X, 1
SET A, [LDTB1+X]
IFC A, DL_UNLINKED
JMP ROME967
SET [RAM02A5], X ; RAM02A5 is first unlinked line
; below initial X value.
IFE X, HW_ROWS-1
JMP ROME981
IFL X, HW_ROWS-1
JMP ROME981
JSR ROME8EA ; scroll the screen
SET X, [RAM02A5]
SUB X, 1
SUB [TBLX], 1
JMP ROME6DA ; Link line X with next line
:ROME981
SET X, HW_ROWS
:ROME98F SUB X, 1
JSR ROME9F0 ; set PNT line pointer to X
IFL X, [RAM02A5]
JMP ROME9A6
IFE X, [RAM02A5]
JMP ROME9A6
; get address of start of line
SET A, [PNT]
SUB A, HW_COLS
SET [SCPNT], A
JSR ROME9C8 ; Move line from SCPNT to PNT
JMP ROME98F ; repeat with previous line
:ROME9A6 JSR ROME9FF ; Clear a screen line
:ROME9A9 SET X, HW_ROWS-2
:ROME9AB IFL X, [RAM02A5]
JMP ROME9BF
:ROME9B0 SET A, 0 ; no longer need to preserve addr
IFB [LDTB1+X], DL_UNLINKED
BOR A, DL_UNLINKED
:ROME9BA SET [LDTB1+1+X], A
SUB X, 1
IFN X, 0
JMP ROME9AB
:ROME9BF SET X, [RAM02A5]
JSR ROME6DA ; link line X with next line
JMP ROME958 ; RTS
; move one screen line from [SCPNT] to [PNT]
; Instead of passing in a high byte in A,
; make sure the whole source address is in [SCPNT].
:ROME9C8
SET Y, HW_COLS-1
SET I, [SCPNT]
ADD I, Y
SET J, [PNT]
SET A, J
ADD J, Y
:ROME9D4
STD [J], [I]
STD [J], [I]
IFG J, A
JMP ROME9D4
RTS
; set color/screen addresses
:ROME9E0 ; Unnecessary
RTS
; fetch screen addresses
:ROME9F0 ;SET A, [ROMECF0+X]
;ADD A, [RAM0287]
SET A, X
MUL A, HW_COLS
ADD A, [HIBASE]
SET [PNT], A
RTS
; clear one screen line
:ROME9FF
JSR ROME9F0 ; set [PNT] line pointer to line X
SET I, [PNT]
SET J, HW_COLS-1
ADD I, J
SET A, 0x0020
BOR A, [COLOR]
:ROMEA07 STD [I], A
STD [I], A
IFA J, -1
JMP ROMEA07
RTS
; set cursor flash timing
; (and color memory addresses)
:ROMEA13
SET [BLNCT], 2
;JSR ROMEA24
; put a char on the screen
; color in X
; character in A
:ROMEA1C
AND A, 0xFF
AND X, 0xFF00
BOR A, X
SET Y, [PNTR]
ADD Y, [PNT]
SET [Y], A
:ROMEA23 RTS
:ROMEA24 ; Unnecessary because the LEM1802
; display doesn't have separate color memory
RTS
; input a character
; get a character
:CHRCOUNT DAT 0
:ROME716 SET PUSH, A
AND A, 0xFF ; PETSCII is 8-bit
SET [RAMD7], A
SET PUSH, X
SET PUSH, Y
SET PUSH, I
SET PUSH, J
SET [CRSW], 0
SET Y, [PNTR]
IFB A, 0x0080
JMP ROME7D4
; Handle unshifted characters
:ROME72A IFE A, CBM_RETURN
JMP ROME891 ; handle CR
IFL A, 0x20
JMP ROME745
IFL A, 0x60
JMP ROME73D
AND A, 0xDF
IFN A, 0
JMP ROME73F
:ROME73D AND A, 0x3F
:ROME73F IFE A, CBM_QUOTE
XOR [QTSW], 1
JMP ROME693 ; print character
:ROME745 SET X, [INSRT]
IFN X, 0
JMP ROME697 ; print reverse
IFN A, CBM_DELETE
JMP ROME77E
IFN Y, 0
JMP ROME759
JSR ROME701 ; move cursor bak does two POPs
SET I, [PNT]
ADD I, Y
JMP ROME773
:ROME759 JSR ROME8A1 ; move cursor to prev line if at start
; Move rest of line to the left with the cursor.
SUB Y, 1
;JSR ROMEA24
SET [PNTR], Y
SET I, [PNT]
SET J, [PNT] ; J = end of line
ADD J, [LNMX]
ADD I, Y
:ROME762 ADD I, 1
SET [I-1], [I]
IFN I, J ;END OF LINE
JMP ROME762
:ROME773 SET J, 0x0020 ; space
BOR J, [COLOR]
SET [I], J
JMP ROME6A8
:ROME77E IFN [QTSW], 0
JMP ROME697 ; print reverse
:ROME785 IFE A, 0x0E ; lowercase mode
JSR TOLOWER
IFE A, 0x12 ; RVS code
JMP RVS_ON
IFE A, CBM_HOME
JMP DOHOMEKEY
IFN A, CBM_RIGHT
JMP ROME7AD
:ROME796 ; do crsr-right
ADD Y, 1
JSR ROME8B3 ; handle end-of-line condition
SET [PNTR], Y
SUB Y, 1
IFL Y, [LNMX]
JMP ROME6A8 ; return from print
SUB [TBLX], 1
JSR ROME87C ; move cursor to next line
SET Y, 0
:ROME7A8 SET [PNTR], Y
JMP ROME6A8 ; return from print
:ROME7AD IFN A, CBM_DOWN
JMP ROME7CE
; perform cursor down
; first assume we're in a linked line
ADD Y, HW_COLS
ADD [TBLX], 1
IFL Y, [LNMX]
JMP ROME7A8
IFE Y, [LNMX]
JMP ROME7A8
SUB [TBLX], 1
:ROME7C0 SUB Y, HW_COLS
IFU Y, 0
JMP ROME7C8
SET [PNTR], Y
IFN Y, 0
JMP ROME7C0
:ROME7C8 JSR ROME87C ; move cursor to next line
JMP ROME6A8 ; return from print
:ROME7CE JSR ROME8CB
JMP ROMEC44
:DOHOMEKEY JSR ROME566
JMP ROME6A8
; Put shifted chars to screen
:ROME7D4 AND A, 0x7F ; remove shift bit
IFE A, 0x7F ; code for PI
SET A, 0x5E
IFG A, 0x1F ; printable
JMP ROME691 ; add 64 and print
:ROME7E3 IFE A, CBM_RETURN ; shift return
JMP ROME891 ; HANDLE CR
IFN [QTSW], 0
JMP ROME82D
IFN A, CBM_DELETE ; insert
JMP ROME829
SET Y, [LNMX]
SET A, [PNT]
ADD A, Y ; A contains end of space to be inserted
SET A, [A]
:ROME7F6 AND A, 0xFF
IFN A, CBM_SPACE
JMP ROME7FE
IFN Y, [PNTR]
JMP ROME805 ; No need to insert a line
:ROME7FE IFE Y, (HW_ROWS*ROWS_IN_LINE)-1
JMP ROME6A8 ; do nothing; can't expand further
:ROME802 JSR ROME965 ; Insert a line below the current line
:ROME805 SET PUSH, I
SET PUSH, J
SET I, [LNMX]
STD J, I ; decrement both
ADD J, [PNT]
;JSR ROMEA24
:ROME80A STD [J+1], [J]
IFN I, [PNTR]
JMP ROME80A
SET [J+1], [J] ; do one more
; fill in space
SET I, [COLOR]
AND I, 0xFF00
BOR I, 0x0020
SET [J], I ; TODO: Proper color
SET J, POP
SET I, POP
ADD [INSRT], 1
JMP ROME6A8
:ROME829 IFE [INSRT], 0
JMP ROME832
:ROME82D BOR A, 0x40 ; shift character
JMP ROME697 ; and print reverse
:ROME832 IFN A, CBM_DOWN ; cursor up
JMP ROME84C
SET X, [TBLX]
IFE X, 0
JMP ROME6A8 ; Do nothing, return.
SUB [TBLX], 1
SET A, [PNTR]
SUB A, HW_COLS
IFU A, 0
JMP ROME847
SET [PNTR], A
IFA A, -1 ; BPL
JMP ROME6A8
:ROME847 JSR ROME56C ; get address
JMP ROME6A8 ; retunr from print
:ROME84C IFE A, 0x0E ; Uppercase mode
JSR TOUPPER
IFE A, 0x12 ; reverse off
SET [RVS], 0
IFN A, CBM_RIGHT ; cursor left
JMP ROME86A
; do crsr left
IFE Y, 0
JMP ROME864
JSR ROME8A1 ; handle edge of screen?
SUB Y, 1
SET [PNTR], Y
JMP ROME6A8
:ROME864 JSR ROME701
JMP ROME6A8
:ROME86A IFN A, CBM_HOME ; clr code
JMP ROME874
JSR ROME544
JMP ROME6A8
:ROME874 BOR A, 0x80 ; restore high bit
JSR ROME8CB ; check for color change codes
JMP ROMEC4F
:MAKE_CBM_FONT
SET A, 4 ; DUMP FONT
SET B, VISFONT ; visible font area
HWI [MONITOR]
SET A, 3 ; border color
SET B, 14 ; light blue
HWI [MONITOR]
SET A, 2 ; MAKE VISIBLE CUSTOM PALETTE
SET B, CBM_PALETTE
HWI [MONITOR]
; Copy XOR map that changes uppercase to lowercase
SET I, VISFONT+130 ; Location of letter A
SET J, FONTXOR1
:FONTLOOP0
SET A, [I]
XOR A, [I+64]
STI [J], A
IFL J, FONTXOR1+52
SET PC, FONTLOOP0
; copy characters 64-95 to 0-31,
; and characters 96-127.
SET I, VISFONT
SET J, 0
:FONTLOOP1
SET [I], [I+128] ; Copy lowercase to top 32
SET [I+128], [J+UPCGFX] ; Copy lowercase to 64-range
STI [I+192], [J+COMGFX] ; Copy C= graphics into
IFL I, VISFONT+64
SET PC, FONTLOOP1
; Copy XOR map that changes uppercase to graphics
SET I, VISFONT+2 ; Location of letter A
SET J, FONTXOR2
:FONTLOOP2
SET A, [I]
XOR A, [I+128]
STI [J], A
IFL J, FONTXOR2+52
SET PC, FONTLOOP2
; make checkmark xor
XOR [CHECKMARK_XOR], [CHECKMARK_GFX]
XOR [CHECKMARK_XOR+1], [CHECKMARK_GFX+1]
; start in lowercase?
IFE STARTLOWER, 1
JSR TOGGLEFONT
; i hate the crossbar zero in a 4x8 font
; this looks much better
SET [VISFONT+96], 0x3E63
; c64-like uparrow and leftarrow
:FONTARROWLOOP
SET J, UPLEFT
SET I, VISFONT+60
STI [I], [J]
STI [I], [J]
STI [I], [J]
STI [I], [J]
; make font visible
SET A, 1 ; MAKE VISIBLE CUSTOM FONT
SET B, VISFONT ; visible font area
HWI [MONITOR]
RTS
:TOGGLEFONT
; toggle the character set onse
; there's probably an optimal way to do this
; to reduce risk of fire.
SET I, 0
:TOGGLELOOP
XOR [I+VISFONT+2], [I+FONTXOR1]
XOR [I+VISFONT+130], [I+FONTXOR2]
ADD I, 1
IFL I, 52
JMP TOGGLELOOP
; toggle box-drawing and checkmark in CBM area
XOR [VISFONT+244], [CHECKMARK_XOR]
XOR [VISFONT+245], [CHECKMARK_XOR+1]
RTS
:TOUPPER
SET I, 0
IFN [VISFONT+130], 0x587F
JMP TOGGLELOOP
RTS
:TOLOWER
SET I, 0
IFE [VISFONT+130], 0x587F
JMP TOGGLELOOP
RTS
:VISFONT
.FILL 256 BLANK
:COMGFX
DAT 0, 0 ; shift-space
DAT 0xFFFF, 0x00 ; left block
DAT 0xF0F0, 0xF0F0 ; bottom block
dat 0x0101, 0x0101 ; top pixel across
DAT 0x8080, 0x8080 ; bottom pixel across
DAT 0xFF00, 0x00 ; left 25%
DAT 0x33CC, 0x33CC ; checkerboard
DAT 0x0000, 0x00FF ; right 25%
DAT 0x30C0, 0x30C0 ; bottom checkerboard
DAT 0xFF3F, 0x0F03 ; top left half diagonal
DAT 0x0000, 0x00FF ; right 25%
DAT 0x00FF, 0x1818 ; box drawing: up down right
DAT 0x0000, 0xF0F0 ; bottom right quadrant
DAT 0x001F, 0x1818 ; box drawing: up right
DAT 0x1818, 0xF800 ; box drawing: down left
DAT 0xC0C0, 0xC0C0
DAT 0x00F8, 0x1818
DAT 0x181F, 0x1818
DAT 0x18F8, 0x1818
DAT 0x18FF, 0x0000
DAT 0xFF00, 0x00 ; left 25%
DAT 0xFF00, 0x00 ; left 25%
DAT 0x0000, 0x00FF ; right 25%
DAT 0x0303, 0x0303 ; top 25%
DAT 0x0707, 0x0707 ; top 3/8
DAT 0xE0E0, 0xE0E0 ; bottom 3/8
:CHECKMARK_GFX
DAT 0xC0C0, 0xC0FF ; box drawing/checkmark
DAT 0xF0F0, 0x0000
DAT 0x0000, 0x0F0F
DAT 0x181F, 0x0000
DAT 0x0F0F, 0x0000
DAT 0x0F0F, 0xF0F0
; Uppercase graphics
:UPCGFX
DAT 0x1818, 0x1818
DAT 0x587F, 0x5800
DAT 0x00FF, 0 ; Petscii vertical bar
DAT 0x1818, 0x1818 ; Petscii horiz bar
DAT 0x0C0C, 0x0C0C ;
DAT 0x0606, 0x0606 ; E
DAT 0x3030, 0x3030 ;F
DAT 0x00FF, 0x0000 ;G
DAT 0x0000, 0xFF00 ;H
DAT 0x18F0, 0x0000 ;I
DAT 0x000F, 0x1818 ;J
DAT 0x180F, 0x0000 ;K
DAT 0xFFC0, 0xC0C0 ;L
DAT 0x030C, 0x30C0 ;M
DAT 0xC030, 0x0C03 ;N
DAT 0xFF03, 0x0303 ;O
DAT 0x0303, 0x03FF ;P
DAT 0x3C7E, 0x3C00 ;Q
DAT 0x6060, 0x6060 ;R
DAT 0x1F7E, 0x1F00 ;S
DAT 0xFF00, 0 ;T
DAT 0x00F0, 0x1818 ;U
DAT 0xC33C, 0x3CC3 ;V
DAT 0x3C66, 0x3C00 ;Empty circle
DAT 0x4C73, 0x4C00 ;Clubs
DAT 0, 0xFF00 ;Verticle bar at 5/8
DAT 0x1C7F, 0x1C00 ;Diamond
DAT 0x18FF, 0x1818; cross
DAT 0x33CC, 0 ; Left 50%
DAT 0x00FF, 0 ; Petscii vertical bar
DAT 0x7C04, 0x7C00 ; pi
DAT 0x0003, 0x0F3F ; Upper right triangle
:UPLEFT ; arrow graphics
DAT 0x0CFE, 0x0C00
DAT 0x187E, 0x1818
; this will be converted to an XOR mask at runtime.
:CHECKMARK_XOR
DAT 0x7030, 0x0C03
; XOR masks to toggle uppercase-lowercase
:FONTXOR1
.FILL 52 BLANK
; XOR masks to toggle graphics-uppercase
:FONTXOR2
.FILL 52 BLANK
:CBM_PALETTE
DAT 0x000, 0xfff, 0xf00, 0x0ff
DAT 0xf0f, 0x0f0, 0x00f, 0xff0
DAT 0xf80, 0x840, 0xf99, 0x444
DAT 0x888, 0x9f9, 0x99f, 0xccc