This repository has been archived by the owner on Dec 24, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathVT100.asm
4993 lines (4727 loc) · 56.2 KB
/
VT100.asm
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
;
; DZ80 V3.4.1 8080 Disassembly of archive/VT100.bin
; 2016/08/03 14:55
;
; Comments beginning with ";;" borrowed from Adam Mayer's (https://github.com/phooky)
; work at https://github.com/phooky/VT100-Hax/blob/master/ROMs/haxrom.d80 and http://vt100romhax.tumblr.com
;
; All other comments/annotations by Jeff Parsons (@jeffpar) <[email protected]>
;
;
; Data area definitions
;
stack_top equ 204eh
scratch_start equ 204eh
;
; The "Keys Flag Byte/Buffer" at 0x2068 contains the following bits:
;
; 0-1 Key counter
; 2 Key counter overflow bit
; 3 Setup
; 4 Control
; 5 Shift
; 6 Caps Lock
; 7 Last Key
;
key_flags equ 2068h ; "Keys Flag Buffer"
key_buffer equ 206ah ; start of the "three place New Key Address Buffer"
cursor_address equ 20f6h
cursor_countdn equ 212dh
cursor_visible equ 21bah
;
; Reset vector
;
org 0
di
lxi sp,stack_top ; SP = 0x204e
jmp reset
;
; Interrupt vector 0x1 for Keyboard
;
org 8
call X00fd
ei
ret
;
; Interrupt vector 0x2 for PUSART
;
org 10h
call X03cc
ei
ret
;
; Interrupt vector 0x3 for Keyboard and PUSART
;
org 18h
call X03cc
call X00fd
ei
ret
;
; Interrupt vector 0x4 for Video (vertical retrace)
;
org 20h
call X04cf
ret
;
; Interrupt vector 0x5 for Keyboard and Video
;
org 28h
call X04cf
ret
;
; Interrupt vector 0x6 for PUSART and Video
;
org 30h
X0030: call X03cc
call X04cf
ei
ret
;
; Interrupt vector 0x7 for Keyboard and PUSART and Video
;
org 38h
jmp X0030
;
; Beginning of power-up (reset) code at 0x003b
;
reset: mvi e,1
X003d: di
mvi a,0fh
out 62h ;; 0x0f to NVR latch
cma ;; invert A (0xf0)
out 42h ;; 0xf0 to brightness
;;
;; Run checksum on each 2K ROM, indicating with
;; the keyboard LEDs which is being scanned.
;; The # of the chip being scanned is stored in B.
;;
xra a ;; zero A
mov d,a ;; zero D, L, H
mov l,a
mov h,a
X0049: inr a ;; next 2K ROM
mov b,a ;; store the current ROM # in B
out 82h ;; show current ROM on LEDs
mvi c,8 ;; Checksum over 8 256B blocks
X004f: rlc ;; Rotate A left
xra m ;; A <- A ^ memory
inr l ;; next memory address
jnz X004f ;; ... repeat until end of block
inr h ;; next block
dcr c ;; decrement block count
jnz X004f ;; ... repeat until end of chip
ora a ;; Check the value of the accumulator
X005b: jnz X005b ;; If it's not zero, hang forever
mov a,b ;; Put the ROM # back in the accumulator
cpi 4 ;; If it's not 4...
jnz X0049 ;; repeat for the next ROM
inr a
out 82h ;; write 5 to LEDs (turns on L2 and L4)
mvi c,0aah ;; Test pattern: 0xaa
mvi b,2ch ;; 0x2c is the top of RAM on the basic board
in 42h ;;
ani 2 ;; flags buffer &= 0x02 : is AVO installed?
jnz X0074 ;; if bit 2 is not set, AVO is installed
mvi b,40h ;; 0x40 is the top of RAM on the AVO
X0074: mov h,b ;; load HL with top of RAM
dcx h ;; dec HL
X0076: mvi m,0 ;; M <- 0
dcx h ;; dec HL
mov a,h ;; a <- h
cpi 1fh ;; compare to 1f (top of ROM)
jnz X0076 ;; continue to zero if not at ROM
inx h
;;
;; Zero all RAM. C gets the high byte of the address of the top of
;; RAM, HL is loaded with it, and it zeros memory all the way down,
;; leaving the start of RAM in HL
;;
;; From start of RAM, test that it's all zero
;;
X0080: mov a,m ;; read a byte of memory
ora a
jz X0090 ;; if it's zero, skip ahead
ani 0fh
mov a,h
jnz X00a1 ;; err
cpi 30h
jc X00a1 ;; err
X0090: mov m,c ;; run test pattern through ram
mov a,m
xra c
jz X00a8 ;; jump to 00a8 if ok
ani 0fh
mov a,h
jnz X00a1 ;; err
cpi 30h
jnc X00a8 ;; ok
X00a1: mvi d,1
cpi 2ch
X00a5: jc X00a5 ;; Hang if non-AVO memory
X00a8: xra a
inx h
ora l
jnz X0080
ora h
cmp b
jnz X0080
mov a,c ;; Repeat mem test with pattern 0x55
rlc
mov c,a
jc X0074
;;
;; Memory test is done
;;
push d
call X02a4 ;; zero scratch and screen mem
call X02eb ;; Set a number of scratch values to fixed values
call X175b ;; .... more memory initialization
pop d
X00c4: jz X00cb
mov a,d
ori 2
mov d,a
X00cb: mvi a,2fh
sta X21c9
out 62h
;
; Prepare to enter the "beep" loop
;
X00d2: lxi b,X0fff
ei
X00d6: mvi a,8
ana e
mvi a,7fh
jnz X00e0
mvi a,0ffh
X00e0: out 82h
dcx b
mov a,b
ora c
jnz X00d6
;
; Done "beeping" now
;
X00e8: out 82h ; A = 0, so all LEDs off now
lda key_flags
ora a
jm X00f5
mov a,d
ori 4
mov d,a
X00f5: push d
;
; The next call issues the following:
;
; 03A2 CD8103 CALL 0381 ;stack=204A
; 0B67 CDAD10 CALL 10AD ;stack=2048
; chipset.outPort(0x00A2,DC012,0x00) at 10BD
; chipset.outPort(0x00A2,DC012,0x04) at 10C1
;
; and then:
;
; 03A2 CD8103 CALL 0381 ;stack=204A
; 0B67 CDAD10 CALL 10AD ;stack=2048
; 10C9 CDAA0F CALL 0FAA ;stack=2046
; 0FB6 CC8814 CALLZ 1488 ;stack=2040
; 1488 CD9314 CALL 1493 ;stack=203E
; chipset.inPort(0x0042,FLAGS.BUFFER): 0x60 at 1493
;
; Note that once we're inside 0FAA, that appears to be where we stay.
;
call X03a2
pop d
jmp X0875
;
; Keyboard interrupt handler
;
X00fd: push psw
in 82h ;; Read from keyboard port
push h
push b
mov b,a ;; copy b <- a
sui 7ch ;; subtract 0x7c from a
jm X011a ;; jump to 011a if a is a normal key
mov h,a ;; otherwise h <- a
inr h ;; h++
mvi a,10h ;; a <- 0x10
rrc
X010d: rlc
dcr h
jnz X010d
lxi h,key_flags ;; load keys flag addresss
ora m ;; or in control bit
mov m,a ;; store again
jmp X012d ;; jump to end to interrupt
X011a: lxi h,key_flags ;; load keys flag address
mvi a,7
ana m ;; load key counter
cpi 4 ;; if overflow.. (>3 keys)
jp X012d ;; discard keypress and end interrupt
inr m ;; otherwise increment key counter
lxi h,key_buffer ;; load key address buffer
call X13de ;; add key counter to address buffer
mov m,b ;; save key to address buffer
X012d: pop b
pop h
pop psw
ret
;;
;; End of keyboard interrupt handler
;;
X0131: ani 7fh
mov c,a
lda X207b
ora a
jnz X01ff
X013b: mov a,c
cpi 1
jz X01c3
lda X21a7
ani 20h
jnz X0175
lda X2178
ora a
jnz X015f
mov a,c
cpi 41h
jm X015b
mvi a,1bh
call X0f18
X015b: mov a,c
jmp X080d
X015f: mvi a,1bh
call X0f18
mov a,c
cpi 41h
jp X015b
mvi a,3fh
X016c: call X0f18
mov a,c
adi 40h
jmp X080d
X0175: lda X2178
ora a
jnz X019e
mov a,c
cpi 41h
jm X015b
cpi 50h
jm X019e
X0187: mvi a,1bh
call X0f18
mvi a,4fh
X018e: call X0f18
jmp X015b
X0194: mvi a,1bh
call X0f18
mvi a,5bh
jmp X018e
X019e: lda X21bc
ora a
jz X01b5
mov a,c
cpi 41h
jp X0187
X01ab: mvi a,1bh
call X0f18
mvi a,4fh
jmp X016c
X01b5: mov a,c
cpi 41h
jm X01ab
cpi 50h
jm X0194
jmp X0187
X01c3: lxi h,X0815
push h
lda X21a5
ora a
rnz
call X0853
lxi b,X020e
lxi h,key_flags
mov a,m
ani 10h
jnz X0900
mov a,m
ani 20h
jz X01e4
lxi b,X00d2
X01e4: mvi a,25h
ori 8
ora b
out 1
lda X207f
add c
mov c,a
X01f0: push b
call X1493
pop b
lda X207f
cmp c
jnz X01f0
jmp X0394
X01ff: lxi h,X0812
push h
xra a
sta X2130
sta X21b8
lxi h,X21a3
mov a,c
X020e: sui 41h
mov b,a
X0211: mov a,m
jz X0222
dcr b
jz X0226
dcr b
jz X1815
dcr b
jz X181e
ret
X0222: dcr a
rm
mov m,a
ret
X0226: inr a
cpi 20h
rz
mov m,a
ret
X022c: lda X21a7
cma
ani 10h
lxi h,X21a5
ora m
jnz X0841
lda X21bf
lxi b,X0211
ana b
jnz X0245
mvi c,13h
X0245: mov a,c
sui 11h
sta X21c4
call X0f7e
jmp X0812
X0251: di
lxi sp,stack_top ; SP = 0x204e
lxi h,2000h
push h
mov a,m
rar
jc X0265
in 42h
ani 2
jz X0269
X0265: inr a
sta X21c8
X0269: call X03a2
lda X2050
dcr a
sta X2153
pop h
mov a,m
mvi m,7fh
ora a
jz X0298
jp X0285
lxi h,X21cb
mvi m,0ah
ani 7fh
X0285: sta X21bd
adi 30h
lhld cursor_address
mov m,a
cpi 34h
jz X0298
mvi a,20h
sta X21a5
X0298: call X0bf2
lxi b,X0011
call X0f7e
jmp X03ae
;;
;; Zero all scratch and screen RAM above stack
;;
X02a4: lxi h,scratch_start ;; HL = 0x204e (just above stack)
lxi d,0fb2h ;; DE = 0x0fb2 (every byte from 0x204e up to 0x3000)
mvi b,0 ;; B = 0
call memset ;; memset(0x1083): set 0x0fb2 bytes to 0 starting at 0x204e
cma ;; invert A
sta X2104 ;; store A in 0x2104
lxi h,X2004 ;; HL <- 0x2004
shld X2052 ;; *(0x2052) = 0x2004
lxi h,X22d0 ;; HL <- 0x22d0
shld cursor_address ;; *(20f6) = 0x22d0
ret
;;
;; Initialize start of screen RAM and wipe attribute RAM to 0xff
;;
X02c0: call X0a15 ;; 0x2140 = 0xe605
lxi h,2000h ;; HL = 0x2000
lxi d,X02d9 ;; DE = 0x02d9
mvi b,12h ;; B = 18
call memmove ;; copy 18 bytes from 0x02d9 to 0x2000
lxi h,3000h ;; HL = 0x3000
lxi d,1000h ;; DE = 0x1000
mvi b,0ffh ;; B = 0xFF
jmp memset ;; invoke memset(0x1083) to set all of attribute RAM to 0xFF and return
;;
;; 0x02d9 through 0x02eb are the initial values for the screen RAM;
;; it's copied into low RAM at 0x2000 during init.
;;
X02d9:
db 07fh,070h,003h
db 07fh,0f2h,0d0h
db 07fh,070h,006h
db 07fh,070h,00ch
db 07fh,070h,00fh
db 07fh,070h,003h
;;
;; Initialize several scratch values. We don't know what all of these are for yet.
;;
X02eb: lxi h,212h ;; HL = 0x0212 (530.)
shld cursor_countdn ;; Store 0x0212 at cursor_countdn [0x212d]
mvi a,35h ;; A = 0x35
sta X212c ;; 0x212c = 0x35
mvi a,1 ;; A = 1
sta X205b ;; 0x205b = 1
sta X2176 ;; 0x2176 = 1
lxi h,X07ff ;; HL = 0x07ff
shld X2149 ;; store 0xff07 at 0x2149
mvi a,2 ;; A = 2
sta X2073 ;; 0x2073 = 2
mvi a,0f7h ;; A = 0xf7
sta X20fa ;; 0x20fa = 0xf7
in 42h ;; read flags buffer
ani 4 ;; And it with 0x04 (check graphics flag)
mvi a,1 ;; A=1
jnz X031a ;; if no graphics skip
sta X2079 ;; else store 1 in 0x2079
X031a: mvi a,0ffh ;; A = 0xff
sta X210e ;; 0x210e = 0xff
sta cursor_visible ;; set cursor_visible [0x21ba] to 0xff (initially visible)
mvi h,80h ;; H = 0x80
mov l,h ;; L = 0x80
shld X20c0 ;; Store 0x8080 at 0x20c0
ret
X0329: mvi a,40h
out 1
lda X2158
out 2
lda X21a4
out 1
call X0394
mvi a,10h
sta X21c9
out 62h
ret
X0342: lda X21a2
ora a
jz X034b
mvi a,10h
X034b: mov b,a
out 0c2h
lda X207c
out 0c2h
cpi 20h
lxi h,X0970
jnz X035e
lxi h,X0370
X035e: shld X2001
lda X21a8
ani 10h
rz
mov a,b
out 0c2h
ret
X036b: lda X21a6
ani 20h
X0370: jnz X0375
mvi a,1
X0375: ori 0ah
out 0a2h
lda X215b
ori 0ch
out 0a2h
ret
X0381: lda X21a2
ora a
jz X0b63
jmp X0b77
;;
;; memmove(0x038b): Move B bytes at DE to HL
;;
memmove:
ldax d ;; Load memory at DE into accumulator
mov m,a ;; Store it at HL
inx h ;; HL++
inx d ;; DE++
dcr b ;; B--
jnz memmove ;; until B is zero
ret
X0394: lda X21a5
ora a
mvi a,1
jnz X039f
mvi a,5
X039f: jmp X1f7b
X03a2: call X0381
call X1ddb
call X036b
jmp X0342
X03ae: call X1488
call X0587
lxi h,X2177
mov a,m
ora a
mvi m,0
cnz X1a20
lda X21a5
ora a
jz X03ae
xra a
sta X2144
jmp X03ae
;;
;; Receiver interrupt handler
;;
X03cc: push psw
push b
push h
in 0 ;; Read from PUSART data
ani 7fh
jz X043a
mov c,a
lda X21a5
ora a
jnz X043a
in 1 ;; Read from PUSART ctrl
ani 38h
jz X03ed
mvi c,1ah
mvi a,27h
ori 10h
out 1
X03ed: mov a,c
cpi 7fh
jz X0437
lda X21a7
ani 10h
mov a,c
jz X0409
lxi h,X21c2
cpi 11h
jz X043e
cpi 13h
jz X0444
X0409: lxi h,X20c0
mov c,m
mov b,h
stax b
mov a,c
inr a
ani 0bfh
mov m,a
mov b,a
lda X20c1
sub b
jnz X0427
mov m,c
mov a,b
inr a
ani 0bfh
mov l,a
mvi m,1ah
jmp X0431
X0427: jp X042c
adi 40h
X042c: cpi 20h
jnz X0437
X0431: lxi b,X0113
call X0f7e
X0437: call X0e47
X043a: pop h
pop b
pop psw
ret
;;
;; End of keyboard interrupt handler
;;
X043e: mvi a,0feh
ana m
jmp X0447
X0444: mvi a,1
ora m
X0447: mov m,a
jmp X0437
X044b: db 30h
dad h
lxi sp,X3221
mov b,b
inx sp
inx h
inr m
inr h
dcr m
dcr h
mvi m,5eh
stc
mvi h,38h
lhld X2839
dcr l
mov e,a
dcr a
dcx h
mov h,b
mov a,m
mov e,e
mov a,e
mov e,l
mov a,l
dcx sp
lda X3f2f
daa
shld X3c2c
mvi l,3eh
mov e,h
mov a,h
db 20h
X0476:
KBTab: db 20h, 7fh, 7fh, 7fh, 00h, 'p', 'o', 'y', 't', 'w', 'q'
db 0c3h, 00h, 00h, 00h, ']', '[', 'i', 'u', 'r', 'e', '1'
db 0c4h, 00h, 0c2h, 081h, '`', '-', '9', '7', '4', '3', 1bh
db 0c1h, 0d2h, 0d0h, 08h, '=', '0', '8', '6', '5', '2', 09h
db 0b7h, 0d3h, 0d1h, 0b0h, 0ah, '\', 'l', 'k', 'g', 'f', 'a'
db 0b8h, 8dh, 0b2h, 0b1h, 00h, 27h, 3bh, 'j', 'h', 'd', 's'
db 0aeh, 0ach, 0b5h, 0b4h, 0dh, '.', ',', 'n', 'b', 'x', 82h
db 0b9h, 0b3h, 0b6h, 0adh, 00h, '/', 'm', ' ', 'v', 'c', 'z'
rst 7
;;
;; Vertical interrupt handler
;;
X04cf: push psw
push h
push d
call X104e
push b
mvi a,9
out 0a2h
ei
lda X2065
ora a
jnz X050b
lxi h,X2051
ora m
jz X053e
mvi a,1
sta X2065
ora m
mvi m,0
mvi a,1
sta X205b
lda X2156
jp X0505
mvi a,99h
sta X205b
lda X2155
dcr a
X0505: call X122f
sta X207a
X050b: lxi b,X205b
ldax b
lxi h,X205a
add m
daa
ani 0fh
mov m,a
mov d,a
ani 3
out 0a2h
mov a,d
rar
ana a
rar
ori 4
out 0a2h
mov a,d
ora a
jnz X053e
sta X2065
ldax b
ora a
lda X2156
jm X0538
lda X2155
dcr a
X0538: call X11ce
sta X207a
X053e: lxi h,X2078
mov a,m
ora a
jz X054f
dcr m
ani 4
rrc
rrc
rrc
sta X2146
X054f: lxi h,X212c
mov a,m
dcr a
jnz X0569
mvi m,35h
mvi a,8
out 0a2h
lxi h,X21cb
mov a,m
ora a
jz X056a
out 0a2h
xri 1
X0569: mov m,a
X056a: mvi a,40h
sta X2148
lxi h,X207f
inr m
lda X21a3
out 42h
lda X2158
out 2
lda X21c9
out 62h
pop b
pop d
pop h
pop psw
ret
X0587: lda X21a5
lxi h,X207b
ora m
rnz
call X0675
rz
X0593: mov b,a
lda X207b
ora a
mov a,b
jnz X05a9
lda X2079
rlc
mov a,b
jc X05a9
cpi 20h
jc X08b2
X05a9: lhld X2140
pchl
X05ad: cpi 1bh
jnz X05cc
lxi h,X05b8
jmp X0a18
X05b8: cpi 32h
jnz X05c5
mvi a,1
sta X2079
jmp X0a15
X05c5: mov b,a
mvi a,1bh
call X05d2
mov a,b
X05cc: call X05d2
jmp X0c62
X05d2: mov c,a
X05d3: push b
call X1488
pop b
in 42h
ani 4
jnz X05d3
mov a,c
out 0e2h
ret
X05e3: call X0c46
X05e6: push psw
cpi 7fh
jz X0673
push h
push d
push b
mov c,a
lxi h,X20fc
mov d,m
inx h
mov a,d
add l
mov l,a
mov a,d
sui 2
jp X05ff
mov a,d
X05ff: sta X20fc
mov d,m
lda X20fa
ora d
mov b,a
mov a,d
rlc
mov a,c
jnc X0616
sui 5fh
cpi 20h
jnc X0616
mov c,a
X0616: mov a,d
ani 40h
mov a,c
jz X0624
cpi 23h
jnz X0624
mvi c,1eh
X0624: lda X20fb
ora c
mov c,a
lda X2142
ora a
jz X0641
lxi h,X20f8
lda X2153
cmp m
jnz X0641
mvi m,0
push b
call X0955
pop b
X0641: lhld cursor_address
mov m,c
mov a,h
adi 10h
mov h,a
mov m,b
mov a,b
sta X20f5
lxi h,X20f4
mov m,c
lxi h,X20f8
lda X2153
cmp m
jnz X0668
mov a,c
sta X20f4
lda X21a8
ani 40h
jmp X066d
X0668: inr m
call X1636
xra a
X066d: sta X2142
X0670: pop b
pop d
pop h
X0673: pop psw
ret
X0675: lda X21c4
ora a
jnz X0685
lxi h,X20c0
mov a,m
inx h
sub m
jnz X0687
X0685: xra a
ret
X0687: mov l,m
mvi h,20h
mov d,m
lxi h,X20c1
mov a,m
inr a
ani 0bfh
ori 80h
mov m,a
dcx h
sub m
jp X069c
adi 40h
X069c: cpi 30h
jnz X06a7
lxi b,X0111
call X0f7e
X06a7: mov a,d
ora a
ret
X06aa: lda key_flags ; A <- [Keys flag buffer]
mov e,a
ani 80h ; bit 7 set?
rz ; return if not