-
Notifications
You must be signed in to change notification settings - Fork 0
/
jupiter_ace_ROM_1.lst
10956 lines (10953 loc) · 594 KB
/
jupiter_ace_ROM_1.lst
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
0001 0000 ; Disassembly of the file "C:\ACE\JupiterAce.rom"
0002 0000 ;
0003 0000 ; CPU Type: Z80
0004 0000 ;
0005 0000 ; Created with dZ80 1.50
0006 0000 ;
0007 0000 ; on Monday, 21 of January 2002 at 07:11 PM
0008 0000 ;
0009 0000 ; last updated 02-NOV-2002
0010 0000 ;
0011 0000 ; Cross-assembles to an 8K ROM file.
0012 0000 ;
0013 0000 ; Note. A Low-level Assembly Listing only.
0014 0000
0015 0000 #define DEFB .BYTE
0016 0000 #define DEFW .WORD
0017 0000 #define DEFM .TEXT
0018 0000 #define EQU .EQU
0019 0000 #define ORG .ORG
0020 0000
0021 0000 ORG $0000
0022 0000
0023 0000 ; -------------------
0024 0000 ; THE 'START' RESTART
0025 0000 ; -------------------
0026 0000
0027 0000 F3 L0000: DI ; disable interrupts.
0028 0001 21 00 3C LD HL,$3C00 ; start of 'User' RAM
0029 0004 3E FC LD A,$FC ; a test byte and 1K masking byte.
0030 0006 18 20 JR L0028 ; forward to continue at Part 2.
0031 0008
0032 0008 ; -------------------
0033 0008 ; THE 'PRINT' RESTART
0034 0008 ; -------------------
0035 0008
0036 0008 D9 L0008: EXX ; preserve main registers.
0037 0009 DD CB 3E 5E BIT 3,(IX+$3E) ; test FLAGS for print destination.
0038 000D C3 EE 03 JP L03EE ; forward to
0039 0010
0040 0010 ; ---------------------------
0041 0010 ; THE 'STACK WORD DE' RESTART
0042 0010 ; ---------------------------
0043 0010
0044 0010 2A 3B 3C L0010: LD HL,($3C3B) ; SPARE
0045 0013 73 LD (HL),E
0046 0014 23 INC HL
0047 0015 C3 5F 08 JP L085F ;
0048 0018
0049 0018 ; -------------------------
0050 0018 ; THE 'POP WORD DE' RESTART
0051 0018 ; -------------------------
0052 0018
0053 0018
0054 0018 2A 3B 3C L0018: LD HL,($3C3B) ; SPARE
0055 001B 2B DEC HL
0056 001C 56 LD D,(HL)
0057 001D C3 59 08 JP L0859 ;
0058 0020
0059 0020 ; -------------------
0060 0020 ; THE 'ERROR' RESTART
0061 0020 ; -------------------
0062 0020
0063 0020 E1 L0020: POP HL
0064 0021 7E LD A,(HL)
0065 0022 32 3D 3C LD ($3C3D),A ; ERR_NO
0066 0025 C3 AD 00 JP L00AD ;
0067 0028
0068 0028 ; ------------------------------------
0069 0028 ; THE 'INITIALIZATION ROUTINE' Part 2.
0070 0028 ; ------------------------------------
0071 0028
0072 0028 24 L0028: INC H ; increase high byte
0073 0029 77 LD (HL),A ; insert A value
0074 002A BE CP (HL) ; compare to expected
0075 002B 28 FB JR Z,L0028 ; loop back while RAM is populated.
0076 002D
0077 002D A4 AND H ; limit to nearest 1K segment.
0078 002E 67 LD H,A ; place back in H.
0079 002F 22 18 3C LD ($3C18),HL ; set system variable RAMTOP.
0080 0032 F9 LD SP,HL ; initialize the stack pointer.
0081 0033
0082 0033 ; the Z80 instructions CALL, PUSH and POP can now be used.
0083 0033
0084 0033 21 0D 01 LD HL,L010D ; prepare to copy the system variables
0085 0036 ; initial state from ROM.
0086 0036 18 03 JR L003B ; skip past the fixed-position restart.
0087 0038
0088 0038 ; -----------------------
0089 0038 ; THE 'INTERRUPT' RESTART
0090 0038 ; -----------------------
0091 0038
0092 0038 C3 3A 01 L0038: JP L013A ; jump to somewhere more convenient.
0093 003B
0094 003B ;------------------------------------------------------------------------------
0095 003B ;
0096 003B ; MEMORY MAP
0097 003B ;
0098 003B ; $0000 +======================================================+
0099 003B ; | |
0100 003B ; | ROM 8K |
0101 003B ; | v $2300 |
0102 003B ; $2000 +======================================================+ - - - - - -
0103 003B ; | copy of $2400 |0|< cassette >|
0104 003B ; $2400 +-------------------------------------+-+--------------+
0105 003B ; | VIDEO MEMORY 768 bytes |0| PAD 254 bytes| 1K RAM
0106 003B ; $2800 +-------------------------------------+-+--------------+
0107 003B ; | copy of $2c00 ^ $2700 |
0108 003B ; $2C00 +------------------------------------------------------+
0109 003B ; | CHARACTER SET - Write-Only | 1K RAM
0110 003B ; $3000 +------------------------------------------------------+
0111 003B ; | copy of $3c00 |
0112 003B ; $3400 +------------------------------------------------------+
0113 003B ; | copy of $3c00 |
0114 003B ; $3800 +------------------------------------------------------+
0115 003B ; | copy of $3c00 |
0116 003B ; $3C00 +-------+----------------------------------------------+
0117 003B ; |SYSVARS| DICT {12} DATA STACK -> <- RET STACK | 1K RAM
0118 003B ; $4000 +=======+==============================================+ - - - - - -
0119 003B ; | |
0120 003B ; 48K AVAILABLE FOR EXPANSION.
0121 003B ; | |
0122 003B ; $FFFF +======================================================+
0123 003B ;
0124 003B ; The Ace had an 8K ROM and was sold with 3K of RAM each byte of which had
0125 003B ; at least two addresses and sometimes four addresses so the mapping of the
0126 003B ; 3K of RAM was as above.
0127 003B ; The 768 bytes of video memory is accessed by the ROM using addresses
0128 003B ; $2400 - $26FF. This gives priority to the video circuitry which also needs
0129 003B ; this information to build the TV picture. The byte at $2700 is set to zero
0130 003B ; so that it is easy for the ROM to detect when it is at the end of the screen.
0131 003B ; The 254 bytes remaining are the PAD - the workspace used by FORTH.
0132 003B ; This same area is used by the tape recorder routines to assemble the tape
0133 003B ; header information but since, for accurate tape timing, the FORTH ROM needs
0134 003B ; priority over the video circuitry, then the ROM uses addresses $2301 - $23FF.
0135 003B ;
0136 003B ; Similarly the Character Set is written to by the ROM (and User) at the 1K
0137 003B ; section starting at $2C00. The video circuitry accesses this using addresses
0138 003B ; $2800 - $2BFF to build the TV picture. It is not possible for the ROM or User
0139 003B ; to read back the information from either address so this precludes the saving
0140 003B ; of character sets and writing a driver for a device like the ZX Printer.
0141 003B ;
0142 003B ; The final 1K or RAM has four addresses although it is normal to use addresses
0143 003B ; $3C00 - $3FFF. The first sixty three bytes are the System Variables which
0144 003B ; hold information like the number BASE and CONTEXT, and even the plotting
0145 003B ; coordinates should the user wish to develop a word like DRAW to draw lines.
0146 003B ;
0147 003B ; Then comes the User Dictionary, the first word of which is "FORTH" which links
0148 003B ; to the Dictionary in ROM. Next a gap of 12 bytes to allow for Data Stack
0149 003B ; underflow and then the Data Stack itself which grows upwards.
0150 003B ; At the opposite end of free memory is the Return Stack (machine stack) which
0151 003B ; grows downwards.
0152 003B
0153 003B ; ------------------------------------
0154 003B ; THE 'INITIALIZATION ROUTINE' Part 3.
0155 003B ; ------------------------------------
0156 003B
0157 003B 11 24 3C L003B: LD DE,$3C24 ; destination system variable L_HALF
0158 003E 01 2D 00 LD BC,$002D ; number of bytes.
0159 0041 ED B0 LDIR ; copy initial state from ROM to RAM.
0160 0043
0161 0043 DD 21 00 3C LD IX,$3C00 ; set IX to index the system variables.
0162 0047 FD 21 C8 04 LD IY,L04C8 ; set IY to the SLOW return address.
0163 004B
0164 004B CD 24 0A L004B: CALL L0A24 ; routine CLS.
0165 004E
0166 004E AF XOR A ; clear accumulator.
0167 004F
0168 004F 32 00 27 LD ($2700),A ; make location after screen zero.
0169 0052
0170 0052 ; There are 128 bit-mapped 8x8 characters.
0171 0052 ; Define the 8 Battenberg graphics ($10 to $17) from low byte of address.
0172 0052 ; This routine also sets the other characters $00 to $0F and $18 to $1F
0173 0052 ; to copies of this range. The inverse form of character $17 is used as the
0174 0052 ; normal cursor - character $97.
0175 0052
0176 0052 21 00 2C L0052: LD HL,$2C00 ; point to the start of the 1K write-
0177 0055 ; only Character Set RAM.
0178 0055
0179 0055 7D L0055: LD A,L ; set A to low byte of address
0180 0056 E6 BF AND $BF ; AND %10111111
0181 0058 0F RRCA ; rotate
0182 0059 0F RRCA ; three times
0183 005A 0F RRCA ; to test bit 2
0184 005B 30 02 JR NC,L005F ; forward if not set.
0185 005D
0186 005D 0F RRCA ; else rotate
0187 005E 0F RRCA ; twice more.
0188 005F
0189 005F 0F L005F: RRCA ; set carry from bit (3) or (6)
0190 0060
0191 0060 47 LD B,A
0192 0061
0193 0061 9F SBC A,A ; $00 or $FF
0194 0062 CB 18 RR B
0195 0064 47 LD B,A
0196 0065 9F SBC A,A
0197 0066 A8 XOR B
0198 0067 E6 F0 AND $F0
0199 0069 A8 XOR B
0200 006A 77 LD (HL),A ; insert the byte.
0201 006B 2C INC L ; increment low byte of address
0202 006C 20 E7 JR NZ,L0055 ; loop back until the first 256 bytes
0203 006E ; have been filled with 32 repeating
0204 006E ; characters.
0205 006E
0206 006E ; Now copy the bit patterns at the end of this ROM to the last 768 bytes of
0207 006E ; the Character RAM, filling in some blank bytes omitted to save ROM space.
0208 006E ; This process starts at high memory and works downwards.
0209 006E
0210 006E 11 FF 2F L006E: LD DE,$2FFF ; top of destination.
0211 0071 21 FB 1F LD HL,L1FFB ; end of copyright character.
0212 0074 01 08 00 LD BC,$0008 ; 8 characters
0213 0077
0214 0077 ED B8 LDDR ; copy the © character
0215 0079
0216 0079 EB EX DE,HL ; switch pointers.
0217 007A
0218 007A 3E 5F LD A,$5F ; set character counter to ninety five.
0219 007C ; i.e. %0101 1111
0220 007C ; bit 5 shows which 32-character sector
0221 007C ; we are in.
0222 007C
0223 007C ; enter a loop for the remaining characters supplying zero bytes as required.
0224 007C
0225 007C 0E 07 L007C: LD C,$07 ; set byte counter to seven.
0226 007E
0227 007E CB 6F BIT 5,A ; test bit 5 of the counter.
0228 0080 28 03 JR Z,L0085 ; forward if not in middle section
0229 0082 ; which includes "[A-Z]"
0230 0082
0231 0082 70 LD (HL),B ; else insert a zero byte.
0232 0083 2B DEC HL ; decrement the destination address.
0233 0084 0D DEC C ; and the byte counter.
0234 0085
0235 0085 EB L0085: EX DE,HL ; switch pointers.
0236 0086
0237 0086 ED B8 LDDR ; copy the 5 or 6 characters.
0238 0088
0239 0088 EB EX DE,HL ; switch pointers.
0240 0089
0241 0089 70 LD (HL),B ; always insert the blank top byte.
0242 008A 2B DEC HL ; decrement the address.
0243 008B
0244 008B 3D DEC A ; decrement the character counter.
0245 008C
0246 008C 20 EE JR NZ,L007C ; back for all 95 characters.
0247 008E
0248 008E ED 56 IM 1 ; Select Interrupt Mode 1
0249 0090
0250 0090 18 09 JR L009B ; and then jump into the code for the
0251 0092 ; QUIT word.
0252 0092
0253 0092
0254 0092 ; ---------------
0255 0092 ; THE 'QUIT' WORD
0256 0092 ; ---------------
0257 0092 ; ( -- )
0258 0092 ; Clears return stack, empties input buffer and returns control to the
0259 0092 ; keyboard.
0260 0092
0261 0092 51 55 49 L0092: DEFM "QUI" ; 'name field'
0262 0095 D4 DEFB 'T' + $80
0263 0096
0264 0096 00 00 L0096: DEFW $0000 ; 'link field' - end of linked list.
0265 0098
0266 0098 04 L0098: DEFB $04 ; 'name length field'
0267 0099
0268 0099 9B 00 L0099: DEFW L009B ; 'code field'
0269 009B ; address of machine code for routine.
0270 009B
0271 009B ; ---
0272 009B
0273 009B ED 7B 18 3C L009B: LD SP,($3C18) ; set stack-pointer to RAMTOP.
0274 009F
0275 009F FB EI ; Enable Interrupts.
0276 00A0
0277 00A0 C3 F2 04 JP L04F2 ; jump forward to the main execution
0278 00A3 ; loop.
0279 00A3
0280 00A3 ; ----------------
0281 00A3 ; THE 'ABORT' WORD
0282 00A3 ; ----------------
0283 00A3 ; Clears the data and return stacks, deletes any incomplete definition
0284 00A3 ; left in the dictionary, prints 'ERROR' and the byte from address $3C3D
0285 00A3 ; if the byte is non-negative, empties the input buffer, and returns
0286 00A3 ; control to the keyboard.
0287 00A3
0288 00A3
0289 00A3 41 42 4F 52 L00A3: DEFM "ABOR" ; 'name field'
0290 00A7 D4 DEFB 'T' + $80
0291 00A8
0292 00A8 98 00 DEFW L0098 ; 'link field' to previous word QUIT.
0293 00AA
0294 00AA 05 L00AA: DEFB $05 ; 'name length field'
0295 00AB
0296 00AB AD 00 L00AB: DEFW L00AD ; 'code field'
0297 00AD
0298 00AD ; ---
0299 00AD
0300 00AD ; -> also continuation of the error restart.
0301 00AD
0302 00AD FD E5 L00AD: PUSH IY ; preserve current IY value slow/fast.
0303 00AF
0304 00AF FD 21 B9 04 LD IY,L04B9 ; set IY to FAST
0305 00B3 ; now empty the data stack
0306 00B3 2A 37 3C LD HL,($3C37) ; STKBOT
0307 00B6 22 3B 3C LD ($3C3B),HL ; SPARE
0308 00B9 21 3E 3C LD HL,$3C3E ; address FLAGS
0309 00BC 7E LD A,(HL) ; fetch status from FLAGS.
0310 00BD E6 B3 AND $B3 ; AND %10110011
0311 00BF ; reset bit 2 - show definition complete
0312 00BF ; reset bit 3 - output to screen.
0313 00BF ; reset bit 6 - show in interpreter mode
0314 00BF CB 56 BIT 2,(HL) ; was there an incomplete definition ?
0315 00C1 77 LD (HL),A ; update FLAGS
0316 00C2 28 1A JR Z,L00DE ; forward if no incomplete word.
0317 00C4
0318 00C4 CD B9 04 L00C4: CALL L04B9 ; do forth
0319 00C7
0320 00C7 90 04 DEFW L0490 ; dict address of sv DICT
0321 00C9 B3 08 DEFW L08B3 ; @ value of sv DICT (d).
0322 00CB 4B 10 DEFW L104B ; stk_data d. length field
0323 00CD 05 DEFB $05 ; five d, 5.
0324 00CE D2 0D DEFW L0DD2 ; + d+5. code field
0325 00D0 6B 08 DEFW L086B ; dup d+5, d+5.
0326 00D2 10 16 DEFW L1610 ; prvcur d+5.
0327 00D4 B5 15 DEFW L15B5 ; namefield n.
0328 00D6 11 10 DEFW L1011 ; stackwrd n.
0329 00D8 37 3C DEFW $3C37 ; (stkbot) n, stkbot.
0330 00DA C1 08 DEFW L08C1 ; ! .
0331 00DC 0E 1A DEFW L1A0E ; end-forth. .
0332 00DE
0333 00DE ; at this stage the system variable STKBOT holds the address of the
0334 00DE ; obsolete name field and the system variable CURRENT points to the
0335 00DE ; address of the previous complete word - obtained from the old link field.
0336 00DE
0337 00DE DD CB 3D 7E L00DE: BIT 7,(IX+$3D) ; test ERR_NO for normal value 255.
0338 00E2 20 1B JR NZ,L00FF ; set-min then main-loop if OK.
0339 00E4
0340 00E4 CD 08 18 CALL L1808 ; else pr-inline
0341 00E7
0342 00E7 ; ---
0343 00E7
0344 00E7 45 52 52 4F L00E7: DEFM "ERRO" ; the message "ERROR" with the last
0345 00EB D2 DEFB 'R' + $80 ; character inverted.
0346 00EC
0347 00EC ; ---
0348 00EC
0349 00EC CD B9 04 L00EC: CALL L04B9 ; forth
0350 00EF
0351 00EF 11 10 DEFW L1011 ; stack next word
0352 00F1 3D 3C DEFW $3C3D ; -> system variable ERR_NO
0353 00F3 96 08 DEFW L0896 ; C@ - fetch content byte
0354 00F5 B3 09 DEFW L09B3 ; . - print it
0355 00F7 95 0A DEFW L0A95 ; CR
0356 00F9 0E 1A DEFW L1A0E ; end-forth.
0357 00FB
0358 00FB DD 36 3D FF LD (IX+$3D),$FF ; set ERR_NO to 'No Error'
0359 00FF
0360 00FF 2A 37 3C L00FF: LD HL,($3C37) ; fetch STKBOT
0361 0102 01 0C 00 LD BC,$000C ; allow twelve bytes for stack underflow
0362 0105 09 ADD HL,BC ; add the extra
0363 0106 22 3B 3C LD ($3C3B),HL ; set SPARE
0364 0109 FD E1 POP IY ; restore previous state of IY
0365 010B
0366 010B 18 8E JR L009B ; rejoin main loop
0367 010D
0368 010D ; -------------------------
0369 010D ; THE 'DEFAULT ENVIRONMENT'
0370 010D ; -------------------------
0371 010D ; This is the default environment that is copied from ROM to RAM as part of
0372 010D ; the initialization process. This also contains the FORTH word FORTH definition
0373 010D
0374 010D E0 26 L010D: DEFW $26E0 ; L_HALF
0375 010F
0376 010F 00 DEFB $00 ; KEYCOD
0377 0110 00 DEFB $00 ; KEYCNT copy the 32 bytes.
0378 0111 00 DEFB $00 ; STATIN
0379 0112 00 00 DEFW $0000 ; EXWRCH
0380 0114 00 DEFB $00 ; FRAMES
0381 0115 00 DEFB $00 ; FRAMES
0382 0116 00 DEFB $00 ; FRAMES
0383 0117 00 DEFB $00 ; FRAMES
0384 0118 00 DEFB $00 ; XCOORD
0385 0119 00 DEFB $00 ; YCOORD
0386 011A 4C 3C DEFW $3C4C ; CURRENT
0387 011C 4C 3C DEFW $3C4C ; CONTEXT
0388 011E 4F 3C DEFW $3C4F ; VOCLNK
0389 0120 51 3C DEFW $3C51 ; STKBOT
0390 0122 45 3C DEFW $3C45 ; DICT
0391 0124 5D 3C DEFW $3C5D ; SPARE
0392 0126 FF DEFB $FF ; ERR_NO
0393 0127 00 DEFB $00 ; FLAGS
0394 0128 0A DEFB $0A ; BASE
0395 0129
0396 0129 ; FORTH
0397 0129
0398 0129 46 4F 52 54 DEFM "FORT" ; The 'name field'
0399 012D C8 DEFB 'H' + $80 ; FORTH
0400 012E
0401 012E
0402 012E 00 00 DEFW $0000 ; length field - filled when next word
0403 0130 ; is defined.
0404 0130 FF 1F DEFW L1FFF ; link field copied to $3C49.
0405 0132 05 DEFB $05 ; name length field
0406 0133 B5 11 DEFW L11B5 ; code field
0407 0135 49 3C DEFW $3C49 ; address of parameters
0408 0137 00 DEFB $00 ; VOCLNK [$3C4F]
0409 0138 00 DEFB $00 ; - link to next vocabulary.
0410 0139 00 DEFB $00 ; last byte to be copied. to [$3C51]
0411 013A
0412 013A ; -----------------------------------------------
0413 013A ; THE 'CONTINUATION OF THE Z80 INTERRUPT' ROUTINE
0414 013A ; -----------------------------------------------
0415 013A ; The destination of the jump at $0038.
0416 013A ; Begin by saving both accumulators and the 3 main registers.
0417 013A
0418 013A F5 L013A: PUSH AF ; preserve both accumulators
0419 013B 08 EX AF,AF' ;
0420 013C F5 PUSH AF ;
0421 013D
0422 013D C5 PUSH BC ; and main registers.
0423 013E D5 PUSH DE ;
0424 013F E5 PUSH HL ;
0425 0140
0426 0140 ; Now wait for 62 * 12 clock cycles. ( To avoid flicker perhaps? ).
0427 0140
0428 0140 06 3E LD B,$3E ; delay counter.
0429 0142
0430 0142 10 FE L0142: DJNZ L0142 ; self loop for delay
0431 0144
0432 0144 ; Increment the 4-byte frames counter for use as a system clock.
0433 0144
0434 0144 21 2B 3C LD HL,$3C2B ; FRAMES1
0435 0147
0436 0147 34 L0147: INC (HL) ; increment timer.
0437 0148 23 INC HL ; next significant byte of four.
0438 0149 28 FC JR Z,L0147 ; loop back if the value wrapped back
0439 014B ; to zero.
0440 014B
0441 014B ; Note. as manual points out, there is no actual check on this and if
0442 014B ; you leave your Ace switched on for 2.75 years it will advance to the
0443 014B ; following system variables although it takes several millennia to advance
0444 014B ; through the screen coordinates.
0445 014B
0446 014B ; Now read the keyboard and if no new key then exit after restoring the
0447 014B ; preserved registers.
0448 014B
0449 014B CD 10 03 CALL L0310 ; routine KEYBOARD.
0450 014E
0451 014E 21 28 3C LD HL,$3C28 ; address system variable STATIN
0452 0151
0453 0151 CB 46 BIT 0,(HL) ; new key?
0454 0153 28 21 JR Z,L0176 ; forward if not to RESTORE/EXIT
0455 0155
0456 0155 A7 AND A ; zero key code ?
0457 0156 28 1E JR Z,L0176 ; forward if so to EXIT.
0458 0158
0459 0158 FE 20 CP $20 ; compare to SPACE
0460 015A 38 14 JR C,L0170 ; forward if less as an Editing Key.
0461 015C
0462 015C CB 4E BIT 1,(HL) ; CAPS shift?
0463 015E C4 07 08 CALL NZ,L0807 ; routine TO_UPPER
0464 0161
0465 0161 CB 56 BIT 2,(HL) ; GRAPHICS mode?
0466 0163 28 02 JR Z,L0167 ; skip forward if not
0467 0165
0468 0165 E6 9F AND $9F ; convert to one of 8 mosaic characters
0469 0167
0470 0167 CB 5E L0167: BIT 3,(HL) ; INVERSE mode?
0471 0169 28 02 JR Z,L016D ; forward if not.
0472 016B
0473 016B F6 80 OR $80 ; set bit 7 to make character inverse.
0474 016D
0475 016D CD 96 01 L016D: CALL L0196 ; routine pr_buffer
0476 0170
0477 0170 CD E6 01 L0170: CALL L01E6 ; routine EDIT_KEY
0478 0173 CD 82 02 CALL L0282 ; routine pr_cursor
0479 0176
0480 0176 ; Before exiting restore the preserved registers.
0481 0176
0482 0176 E1 L0176: POP HL ;
0483 0177 D1 POP DE ;
0484 0178 C1 POP BC ;
0485 0179 F1 POP AF ;
0486 017A 08 EX AF,AF' ;
0487 017B F1 POP AF ;
0488 017C
0489 017C FB EI ; Enable Interrupts
0490 017D
0491 017D C9 RET ; return.
0492 017E
0493 017E ; -----------------------------------
0494 017E ; THE 'PRINT to LOWER SCREEN' ROUTINE
0495 017E ; -----------------------------------
0496 017E
0497 017E FE 0D L017E: CP $0D ; carriage return?
0498 0180 20 14 JR NZ,L0196 ; forward if not
0499 0182
0500 0182 ; a carriage return to input buffer i.e. lower screen memory.
0501 0182
0502 0182 21 00 27 LD HL,$2700 ; set pointer to location after the
0503 0185 ; input buffer.
0504 0185
0505 0185 22 22 3C LD ($3C22),HL ; set ENDBUF - end of logical line
0506 0188 22 20 3C LD ($3C20),HL ; set the CURSOR
0507 018B
0508 018B AF XOR A ; clear A
0509 018C
0510 018C CD 98 01 CALL L0198 ; print character zero.
0511 018F
0512 018F 21 E0 26 LD HL,$26E0 ; left hand position of bottom line.
0513 0192 22 1E 3C LD ($3C1E),HL ; set INSCRN to this position.
0514 0195 C9 RET ; return.
0515 0196
0516 0196 ; ---------------------------------------
0517 0196 ; THE 'PRINT CHARACTER TO BUFFER' ROUTINE
0518 0196 ; ---------------------------------------
0519 0196
0520 0196 A7 L0196: AND A ; check for zero character
0521 0197 C8 RET Z ; return if so.
0522 0198
0523 0198 ; => also called from previous routine only to print a zero skipping above test.
0524 0198
0525 0198 08 L0198: EX AF,AF' ; preserve the output character.
0526 0199
0527 0199 2A 22 3C LD HL,($3C22) ; fetch ENDBUF end of logical line
0528 019C 7E LD A,(HL) ; fetch character from position
0529 019D A7 AND A ; is it zero ?
0530 019E 28 06 JR Z,L01A6 ; skip forward if so.
0531 01A0
0532 01A0 ; else lower screen scrolling is required.
0533 01A0
0534 01A0 11 00 D9 LD DE,$D900 ; $0000 - $2700
0535 01A3 19 ADD HL,DE ; test if position is within video RAM
0536 01A4 30 28 JR NC,L01CE ; forward if < $26FF
0537 01A6
0538 01A6 ; now check that the limit of 22 lines in lower screen is not exceeded.
0539 01A6
0540 01A6 ED 5B 24 3C L01A6: LD DE,($3C24) ; fetch start of buffer from L_HALF
0541 01AA 21 A0 DB LD HL,$DBA0 ; $0000 - $2460
0542 01AD 19 ADD HL,DE ;
0543 01AE 30 34 JR NC,L01E4 ; forward to exit if buffer full.
0544 01B0
0545 01B0
0546 01B0 2A 1C 3C LD HL,($3C1C) ; fetch position SCRPOS for upper screen
0547 01B3 01 20 00 LD BC,$0020 ; allow an extra 32 characters - 1 line.
0548 01B6 09 ADD HL,BC ;
0549 01B7 ED 52 SBC HL,DE ; subtract the start of input buffer
0550 01B9 D5 PUSH DE ; and save the L_HALF value
0551 01BA
0552 01BA D4 21 04 CALL NC,L0421 ; routine to scroll upper display.
0553 01BD
0554 01BD CD B0 02 CALL L02B0 ; find zerobyte loc in HL
0555 01C0
0556 01C0 D1 POP DE ; retrieve the L_HALF value
0557 01C1
0558 01C1 CD 2F 04 CALL L042F ; routine scroll and blank
0559 01C4
0560 01C4 ; The four system variables INSCRN, CURSOR, ENDBUF and L_HALF are each
0561 01C4 ; reduced by 32 bytes a screen line.
0562 01C4
0563 01C4 21 1E 3C LD HL,$3C1E ; address INSCRN the left-hand location
0564 01C7 ; of the current input line.
0565 01C7
0566 01C7 06 04 LD B,$04 ; four system variables to update
0567 01C9
0568 01C9 CD 43 04 L01C9: CALL L0443 ; routine SCR-PTRS
0569 01CC
0570 01CC 10 FB DJNZ L01C9 ; repeat for all four pointers.
0571 01CE
0572 01CE ; ok to print
0573 01CE
0574 01CE CD 02 03 L01CE: CALL L0302 ; routine find characters to EOL.
0575 01D1
0576 01D1 54 LD D,H ; HL is end of line
0577 01D2 5D LD E,L ; transfer to DE register.
0578 01D3 23 INC HL ; increment
0579 01D4 22 22 3C LD ($3C22),HL ; update ENDBUF
0580 01D7 2B DEC HL ; decrement
0581 01D8 2B DEC HL ; so HL = DE -1
0582 01D9
0583 01D9 28 02 JR Z,L01DD ; skip if BC zero.
0584 01DB
0585 01DB ED B8 LDDR ; else move the characters.
0586 01DD
0587 01DD 08 L01DD: EX AF,AF' ; restore the output character.
0588 01DE 12 LD (DE),A ; insert at screen position.
0589 01DF ; (a zero if CR lower)
0590 01DF 13 INC DE ; next character position
0591 01E0 ED 53 20 3C LD ($3C20),DE ; update CURSOR
0592 01E4
0593 01E4 AF L01E4: XOR A ; ?
0594 01E5 C9 RET ; return.
0595 01E6
0596 01E6 ; -------------------------
0597 01E6 ; THE 'EDIT KEY' SUBROUTINE
0598 01E6 ; -------------------------
0599 01E6
0600 01E6 21 F0 01 L01E6: LD HL,L01F0 ; address the EDIT KEYS table.
0601 01E9
0602 01E9 16 00 LD D,$00 ; prepare to index by one byte.
0603 01EB 5F LD E,A ; character code to E.
0604 01EC 19 ADD HL,DE ; index into the table.
0605 01ED
0606 01ED 5E LD E,(HL) ; pick up required offset to the
0607 01EE ; handling routine.
0608 01EE
0609 01EE 19 ADD HL,DE ; add to the current address.
0610 01EF E9 JP (HL) ; exit via the routine.
0611 01F0
0612 01F0 ; ---------------------
0613 01F0 ; THE 'EDIT KEYS' TABLE
0614 01F0 ; ---------------------
0615 01F0
0616 01F0 20 L01F0: DEFB $20 ; L0210 $00 - RET
0617 01F1 13 L01F1: DEFB $13 ; L0204 $01 - LEFT
0618 01F2 0C L01F2: DEFB $0C ; L01FE $02 - CAPS
0619 01F3 1E L01F3: DEFB $1E ; L0211 $03 - RIGHT
0620 01F4 0A L01F4: DEFB $0A ; L01FE $04 - GRAPH
0621 01F5 37 L01F5: DEFB $37 ; L022C $05 - DEL
0622 01F6 1A L01F6: DEFB $1A ; L0210 $06 - RET
0623 01F7 50 L01F7: DEFB $50 ; L0247 $07 - UP
0624 01F8 06 L01F8: DEFB $06 ; L01FE $08 - INV
0625 01F9 9C L01F9: DEFB $9C ; L0295 $09 - DOWN
0626 01FA C9 L01FA: DEFB $C9 ; L02C3 $0A - DEL LINE
0627 01FB 15 L01FB: DEFB $15 ; L0210 $0B - RET
0628 01FC 14 L01FC: DEFB $14 ; L0210 $0C - RET
0629 01FD D3 L01FD: DEFB $D3 ; L02D0 $0D - KEY-ENTER
0630 01FE
0631 01FE ; -------------------------------
0632 01FE ; THE 'TOGGLE STATUS BIT' ROUTINE
0633 01FE ; -------------------------------
0634 01FE ; The keycodes have been cleverly mapped to individual bits of the STATIN
0635 01FE ; system variable so this simple routine maintains all three status bits.
0636 01FE ; KEY '2' - CAPS SHIFT, '4' - GRAPHICS, '8' - INVERSE VIDEO.
0637 01FE
0638 01FE 21 28 3C L01FE: LD HL,$3C28 ; system variable STATIN
0639 0201 AE XOR (HL) ; toggle the single relevant bit.
0640 0202 77 LD (HL),A ; put back.
0641 0203 C9 RET ; return.
0642 0204
0643 0204 ; ----------------------------
0644 0204 ; THE 'CURSOR LEFT' SUBROUTINE
0645 0204 ; ----------------------------
0646 0204 ; this subroutine moves the cursor to the left unless the character at that
0647 0204 ; position is zero.
0648 0204
0649 0204 2A 20 3C L0204: LD HL,($3C20) ; fetch CURSOR.
0650 0207 2B DEC HL ; decrement value.
0651 0208 7E LD A,(HL) ; fetch character at new position.
0652 0209 A7 AND A ; test for zero. (cr)
0653 020A C8 RET Z ; return if so. >>
0654 020B
0655 020B 22 20 3C LD ($3C20),HL ; else update CURSOR
0656 020E 23 INC HL ; step back
0657 020F 77 LD (HL),A ; and put character that was at new
0658 0210 ; cursor position where cursor is now.
0659 0210
0660 0210 C9 L0210: RET ; return.
0661 0211
0662 0211 ; Note. various unallocated keys in the EDIT KEYS table point to the
0663 0211 ; above RET instruction.
0664 0211
0665 0211 ; -----------------------------
0666 0211 ; THE 'CURSOR RIGHT' SUBROUTINE
0667 0211 ; -----------------------------
0668 0211
0669 0211 2A 20 3C L0211: LD HL,($3C20) ; fetch CURSOR position
0670 0214 23 INC HL ; and increment it.
0671 0215
0672 0215 ED 5B 22 3C LD DE,($3C22) ; fetch ENDBUF - end of current line.
0673 0219 A7 AND A ; prepare to subtract.
0674 021A ED 52 SBC HL,DE ; test
0675 021C C8 RET Z ; return if zero - CURSOR is at ENDBUF
0676 021D
0677 021D 19 ADD HL,DE ; else reform the pointers.
0678 021E 22 20 3C LD ($3C20),HL ; update CURSOR
0679 0221 7E LD A,(HL) ; fetch character at new position.
0680 0222 2B DEC HL ; decrement
0681 0223 77 LD (HL),A ; and insert where cursor was.
0682 0224 C9 RET ; ret.
0683 0225
0684 0225 ; ---------------------------
0685 0225 ; THE 'DELETE CURSOR' ROUTINE
0686 0225 ; ---------------------------
0687 0225 ; Moves cursor position to right and then continues into DEL-CHAR
0688 0225
0689 0225 2A 20 3C L0225: LD HL,($3C20) ; fetch CURSOR
0690 0228 23 INC HL ; increment position.
0691 0229 22 20 3C LD ($3C20),HL ; update CURSOR
0692 022C
0693 022C
0694 022C ; ------------------------------
0695 022C ; THE 'DELETE CHARACTER' ROUTINE
0696 022C ; ------------------------------
0697 022C
0698 022C CD 02 03 L022C: CALL L0302 ; routine finds characters to EOL.
0699 022F
0700 022F 62 LD H,D ; transfer CURSOR position DE to HL.
0701 0230 6B LD L,E ;
0702 0231 1B DEC DE ; decrement DE
0703 0232 1A LD A,(DE) ; fetch character to left of original
0704 0233 ; cursor.
0705 0233 A7 AND A ; test for zero.
0706 0234 C8 RET Z ; return if so. >>
0707 0235
0708 0235 ED 53 20 3C LD ($3C20),DE ; else update CURSOR
0709 0239 78 LD A,B ; check for count of characters
0710 023A B1 OR C ; being zero
0711 023B 28 02 JR Z,L023F ; skip if so.
0712 023D
0713 023D ED B0 L023D: LDIR ; else shift characters to left.
0714 023F
0715 023F 2B L023F: DEC HL ; decrement HL so that points to end -
0716 0240 ; last position on the logical line.
0717 0240 36 20 LD (HL),$20 ; insert a space.
0718 0242 22 22 3C LD ($3C22),HL ; set ENDBUF
0719 0245 0C INC C ; reset zero flag??
0720 0246 C9 RET ; return.
0721 0247
0722 0247 ; -----------------------
0723 0247 ; THE 'CURSOR UP' ROUTINE
0724 0247 ; -----------------------
0725 0247 ; When the cursor is moved up while editing a multi-line word definition,
0726 0247 ; then the cursor is first moved to the left of the screen abutting the
0727 0247 ; character zeros at the leftmost position.
0728 0247 ; These zero characters appear as spaces but mark the beginning of each logical
0729 0247 ; line. A logical line may, for instance if it contains a text item, extend over
0730 0247 ; several physical screen lines.
0731 0247
0732 0247 CD 04 02 L0247: CALL L0204 ; routine CURSOR-LEFT
0733 024A 28 08 JR Z,L0254 ; skip forward if not possible.
0734 024C
0735 024C ; else move left by thirty two positions. This may achieve a vertical move if
0736 024C ; attempted when a word is first being entered. Alternatively if one of the
0737 024C ; calls to cursor left fails having encountered a zero, then all subsequent
0738 024C ; calls will fail. The routine will return with the cursor adjacent to the zero.
0739 024C
0740 024C 06 1F LD B,$1F ; count 31 decimal
0741 024E CD 04 02 L024E: CALL L0204 ; move cursor left thirty one times.
0742 0251 10 FB DJNZ L024E ; makes thirty two moves counting first
0743 0253
0744 0253 C9 RET ; return.
0745 0254
0746 0254 ; ---
0747 0254
0748 0254 2A 1E 3C L0254: LD HL,($3C1E) ; fetch INSCRN start of current line.
0749 0257 ED 5B 24 3C LD DE,($3C24) ; fetch L_HALF start of buffer.
0750 025B A7 AND A ; reset carry for
0751 025C ED 52 SBC HL,DE ; true subtraction.
0752 025E C8 RET Z ; return if at beginning of input buffer
0753 025F
0754 025F CD 25 02 CALL L0225 ; routine DEL-CURSOR
0755 0262
0756 0262 2A 1E 3C LD HL,($3C1E) ; fetch INSCRN leftmost location of
0757 0265 ; current line.
0758 0265 11 E0 FF LD DE,$FFE0 ; make DE minus thirty two.
0759 0268 AF XOR A ; clear accumulator to zero.
0760 0269
0761 0269 19 L0269: ADD HL,DE ; subtract 32
0762 026A BE CP (HL) ; compare contents to zero
0763 026B ; ( i.e. prev (cr) or buffer start?)
0764 026B 20 FC JR NZ,L0269 ; loop back until HL holds zero.
0765 026D
0766 026D 22 1E 3C LD ($3C1E),HL ; update INSCRN
0767 0270
0768 0270 CD F4 02 CALL L02F4 ; find endbuf
0769 0273
0770 0273 22 20 3C LD ($3C20),HL ; set CURSOR
0771 0276
0772 0276 ; ----------
0773 0276 ; PR_CURSOR
0774 0276 ; ----------
0775 0276
0776 0276 3E A0 L0276: LD A,$A0 ; inverse space - so solid square
0777 0278
0778 0278 CD 7E 01 CALL L017E ; routine PR_LOWER
0779 027B
0780 027B 2A 20 3C LD HL,($3C20) ; CURSOR
0781 027E 2B DEC HL
0782 027F 22 20 3C LD ($3C20),HL ; CURSOR
0783 0282
0784 0282 ; -> from interrupt
0785 0282 2A 20 3C L0282: LD HL,($3C20) ; CURSOR
0786 0285
0787 0285 3A 28 3C LD A,($3C28) ; STATIN
0788 0288 1F RRA ; ignore bit 0
0789 0289 36 97 LD (HL),$97 ; pixel cursor.
0790 028B 1F RRA ; test bit 1 - CAPS
0791 028C 30 02 JR NC,L0290 ; forward if no CAPS SHIFT
0792 028E
0793 028E 36 C3 LD (HL),$C3 ; inverse [C] cursor.
0794 0290
0795 0290 1F L0290: RRA ; test bit 2 - GRAPHICS.
0796 0291 D0 RET NC ; return if not
0797 0292
0798 0292 36 C7 L0292: LD (HL),$C7 ; inverse [G] cursor.
0799 0294 C9 RET ; return
0800 0295
0801 0295 ; -------------------------
0802 0295 ; THE 'CURSOR DOWN' ROUTINE
0803 0295 ; -------------------------
0804 0295
0805 0295
0806 0295 CD 11 02 L0295: CALL L0211 ; routine CURSOR RIGHT
0807 0298 28 08 JR Z,L02A2 ; forward if not possible.
0808 029A
0809 029A 06 1F LD B,$1F ; set counter to thirty one.
0810 029C
0811 029C CD 11 02 L029C: CALL L0211 ; routine CURSOR RIGHT
0812 029F 10 FB DJNZ L029C ; thirty two moves altogether.
0813 02A1 C9 RET ; return.
0814 02A2
0815 02A2 ; ---
0816 02A2
0817 02A2 CD B0 02 L02A2: CALL L02B0 ; find zerobyte
0818 02A5 E0 RET PO ; return if found
0819 02A6
0820 02A6 E5 PUSH HL ; save position
0821 02A7 CD 25 02 CALL L0225 ; routine DEL-CURSOR
0822 02AA E1 POP HL ; retrieve position.
0823 02AB CD ED 02 CALL L02ED ; set logical line
0824 02AE 18 C6 JR L0276 ; back to exit via pr_cursor.
0825 02B0
0826 02B0 ; ---
0827 02B0 ; find zerobyte
0828 02B0 ; ---
0829 02B0 ; -> called 5 times
0830 02B0
0831 02B0 21 00 27 L02B0: LD HL,$2700 ; this location is always zero.
0832 02B3 ; the byte following video RAM.
0833 02B3 ED 5B 1E 3C LD DE,($3C1E) ; INSCRN e.g. $26E0
0834 02B7
0835 02B7 A7 AND A ; prepare for true subtraction
0836 02B8
0837 02B8 ED 52 SBC HL,DE ; subtract to give number of chars
0838 02BA
0839 02BA 44 LD B,H ; transfer count to
0840 02BB 4D LD C,L ; the BC register pair.
0841 02BC
0842 02BC EB EX DE,HL ; transfer INSCR value to HL.
0843 02BD
0844 02BD 23 INC HL ; start next location
0845 02BE AF XOR A ; search for a zero character.
0846 02BF
0847 02BF ED B1 CPIR ; at most BC locations.
0848 02C1 ; sets P/O flag if BC!=0
0849 02C1
0850 02C1 2B DEC HL ; step back to last non-zero
0851 02C2 C9 RET ; return.
0852 02C3
0853 02C3 ; -------------------------
0854 02C3 ; THE 'DELETE LINE' ROUTINE
0855 02C3 ; -------------------------
0856 02C3 ; CHR$ 10
0857 02C3
0858 02C3 2A 22 3C L02C3: LD HL,($3C22) ; ENDBUF
0859 02C6 2B DEC HL ;
0860 02C7 22 20 3C LD ($3C20),HL ; CURSOR
0861 02CA
0862 02CA CD 2C 02 L02CA: CALL L022C ; KEY-DEL
0863 02CD 20 FB JR NZ,L02CA ; repeat
0864 02CF
0865 02CF C9 RET ; return.
0866 02D0
0867 02D0 ; --------------------------
0868 02D0 ; THE 'KEY-ENTER' SUBROUTINE
0869 02D0 ; --------------------------
0870 02D0
0871 02D0 21 28 3C L02D0: LD HL,$3C28 ; STATIN
0872 02D3 CB EE SET 5,(HL) ; signal new key.
0873 02D5 CB 86 RES 0,(HL) ; reset new key flag
0874 02D7 C9 RET ; return.
0875 02D8
0876 02D8
0877 02D8 ; ------------------------
0878 02D8 ; THE 'SET BUFFER' ROUTINE
0879 02D8 ; ------------------------
0880 02D8 ; called by LIST, QUERY
0881 02D8
0882 02D8 21 00 27 L02D8: LD HL,$2700 ; one past end of screen.
0883 02DB ED 5B 24 3C LD DE,($3C24) ; fetch start of buffer from L_HALF
0884 02DF
0885 02DF CD FA 07 CALL L07FA ; routine SPACE_FILL
0886 02E2
0887 02E2 21 E0 26 LD HL,$26E0 ; first location of bottom line.
0888 02E5 22 24 3C LD ($3C24),HL ; set L_HALF
0889 02E8
0890 02E8 36 00 LD (HL),$00 ; insert a ZERO.
0891 02EA
0892 02EA ; -> called by retype
0893 02EA 2A 24 3C L02EA: LD HL,($3C24) ; fetch L_HALF
0894 02ED
0895 02ED ; -> from cursor down
0896 02ED 22 1E 3C L02ED: LD ($3C1E),HL ; set INSCRN
0897 02F0 23 INC HL ; step past the zero
0898 02F1 22 20 3C LD ($3C20),HL ; set CURSOR
0899 02F4
0900 02F4 ; => from cursor up.
0901 02F4 CD B0 02 L02F4: CALL L02B0 ; find zerobyte
0902 02F7
0903 02F7 3E 20 LD A,$20 ; prepare a space
0904 02F9
0905 02F9 2B L02F9: DEC HL ; move to the left.
0906 02FA BE CP (HL) ; compare to space.
0907 02FB 28 FC JR Z,L02F9 ; back while spaces exist.
0908 02FD
0909 02FD 23 INC HL ; point to last space encountered.
0910 02FE 22 22 3C LD ($3C22),HL ; set ENDBUF - end of logical line.
0911 0301 C9 RET ; return.
0912 0302
0913 0302 ; ----------------------------------
0914 0302 ; THE 'COUNT TO END OF LINE' ROUTINE
0915 0302 ; ----------------------------------
0916 0302 ; Find the number of characters to the end of the logical line.
0917 0302
0918 0302 2A 22 3C L0302: LD HL,($3C22) ; system variable ENDBUF
0919 0305 ED 5B 20 3C LD DE,($3C20) ; system variable CURSOR
0920 0309 A7 AND A ; prepare to subtract.
0921 030A ED 52 SBC HL,DE ; subtract to give character places
0922 030C 44 LD B,H ; transfer result
0923 030D 4D LD C,L ; to the BC register pair.
0924 030E 19 ADD HL,DE ; reform the pointers.
0925 030F
0926 030F C9 RET ; return with zero flag set if cursor
0927 0310 ; at EOL.
0928 0310
0929 0310 ; ----------------------
0930 0310 ; THE 'KEYBOARD' ROUTINE
0931 0310 ; ----------------------
0932 0310
0933 0310 CD 36 03 L0310: CALL L0336 ; routine KEY_SCAN
0934 0313
0935 0313 47 LD B,A ; save key in B
0936 0314
0937 0314 2A 26 3C LD HL,($3C26) ; load L with KEYCOD - last key pressed
0938 0317 ; load H with KEYCNT - debounce counter
0939 0317
0940 0317 AD XOR L ; compare to previous key.
0941 0318 28 0B JR Z,L0325 ; forward if a match.
0942 031A
0943 031A AD XOR L ; reform original
0944 031B 28 03 JR Z,L0320 ; forward if zero - no key.
0945 031D
0946 031D AF XOR A ; else clear accumulator.
0947 031E
0948 031E BD CP L ; compare with last.
0949 031F C0 RET NZ ; return if not zero.
0950 0320
0951 0320 68 L0320: LD L,B ; set L to original keycode
0952 0321 26 20 LD H,$20 ; set counter to thirty two.
0953 0323 18 0D JR L0332 ; forward to store values and exit
0954 0325 ; returning zero.
0955 0325
0956 0325 ; ---
0957 0325
0958 0325 ; Key is same as previously accepted key.
0959 0325 ; It repeats after two interrupts
0960 0325
0961 0325 25 L0325: DEC H ; decrement the counter.
0962 0326 7C LD A,H ; fetch counter to A.
0963 0327 FE 1E CP $1E ; compare to thirty.
0964 0329 28 06 JR Z,L0331 ; forward if so to return key in A.
0965 032B
0966 032B AF XOR A ; clear accumulator.
0967 032C BC CP H ; is counter zero?
0968 032D 20 03 JR NZ,L0332 ; forward if not to keep counting.
0969 032F
0970 032F 26 04 LD H,$04 ; else set counter to four.
0971 0331
0972 0331 7D L0331: LD A,L ; pick up previous key.
0973 0332
0974 0332 22 26 3C L0332: LD ($3C26),HL ; update KEYCOD/KEYCNT
0975 0335
0976 0335 C9 RET ; return.
0977 0336
0978 0336 ;----------------------------------------------------------------------------
0979 0336 ; LOGICAL VIEW OF KEYBOARD
0980 0336 ;
0981 0336 ; 0 1 2 3 4 -Bits- 4 3 2 1 0
0982 0336 ; PORT PORT
0983 0336 ;
0984 0336 ; F7FE [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] | [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 0 ] EFFE
0985 0336 ; ^ | v
0986 0336 ; FBFE [ Q ] [ W ] [ E ] [ R ] [ T ] | [ Y ] [ U ] [ I ] [ O ] [ P ] DFFE
0987 0336 ; ^ | v
0988 0336 ; FDFE [ A ] [ S ] [ D ] [ F ] [ G ] | [ H ] [ J ] [ K ] [ L ] [ ENT ] BFFE
0989 0336 ; ^ | v
0990 0336 ; FEFE [SHI] [SYM] [ Z ] [ X ] [ C ] | [ V ] [ B ] [ N ] [ M ] [ SPC ] 7FFE
0991 0336 ; ^ v ^ v
0992 0336 ; Start +------------>--------------------->-------------+ End
0993 0336 ;
0994 0336 ;
0995 0336 ;----------------------------------------------------------------------------
0996 0336
0997 0336
0998 0336 ; ----------------------------------
0999 0336 ; THE 'KEYBOARD SCANNING' SUBROUTINE
1000 0336 ; ----------------------------------