-
Notifications
You must be signed in to change notification settings - Fork 1
/
nibl3.lst
2371 lines (2284 loc) · 168 KB
/
nibl3.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
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 1 - 2024年05月30日 15時32分15秒
1/ 0 : ; This listing was reverse engineered and commented from a dump of the 8073N ROM
2/ 0 : ; It may look like valid SC/MP-III assembler, but probably isn't. This is purely for
3/ 0 : ; reference - not for feeding into an assembler program.
4/ 0 : ; Analysed and commented by Holger Veit (20140315)
5/ 0 : cpu 8070
6/ 0 : ; locations in on-chip RAM
7/ 0 : =0xFFC0 MULOV = 0xffc0 ; DW high 16 bit from MPY
8/ 0 : =0xFFC2 INPMOD = 0xffc2 ; DB input mode: 0x00 interactive, <>0 in INPUT, 01: running
9/ 0 : =0xFFC3 CURRNT = 0xffc3 ; DW current line number executed
10/ 0 : =0xFFC5 RUNMOD = 0xffc5 ; DB runmode 'R', 0x00
11/ 0 : =0xFFC6 EXTRAM = 0xffc6 ; DW start of variables (26 words)
12/ 0 : =0xFFC8 AESTK = 0xffc8 ; DW start of arithmetic stack (13 words)
13/ 0 : =0xFFCA SBRSTK = 0xffca ; DW start of GOSUB stack (10 words)
14/ 0 : =0xFFCC DOSTK = 0xffcc ; DW start of DO stack (10 words)
15/ 0 : =0xFFCE FORSTK = 0xffce ; DW start of FOR stack (28 words)
16/ 0 :
17/ 0 : =0xFFD0 BUFAD = 0xffd0 ; DW
18/ 0 : =0xFFD2 STACK = 0xffd2 ; DW top of stack
19/ 0 : =0xFFD4 TXTBGN = 0xffd4 ; DW start of program area
20/ 0 : =0xFFD6 TXTUNF = 0xffd6 ; DW
21/ 0 : =0xFFD8 TXTEND = 0xffd8 ; DW end of program area
22/ 0 : =0xFFDA DOPTR = 0xffda ; DW ptr to DO level?
23/ 0 : =0xFFDC FORPTR = 0xffdc ; DW ptr to FOR level?
24/ 0 : =0xFFDE SBRPTR = 0xffde ; DW ptr to GOSUB level?
25/ 0 :
26/ 0 : =0xFFE0 INTVEC = 0xffe0 ; DW current interrupt vector
27/ 0 : =0xFFE2 INTAVC = 0xffe2 ; DW Interrupt A vector
28/ 0 : =0xFFE4 INTBVC = 0xffe4 ; DW Interrupt B vector
29/ 0 : =0xFFE6 BRKFLG = 0xffe6 ; DB if 0 check for BREAK from serial
30/ 0 : =0xFFE7 NOINT = 0xffe7 ; DB flag to suppress INT after having set STAT
31/ 0 :
32/ 0 : =0xFFE8 ONE = 0xffe8 ; DW constant 1
33/ 0 : =0xFFEA ZERO = 0xffea ; DW constant 0
34/ 0 : =0xFFEC DLYTIM = 0xffec ; DW delay value for serial I/O
35/ 0 : =0xFFEE CONTP = 0xffee ; DW buffer pointer for CONT
36/ 0 :
37/ 0 : =0xFFF0 TMPF0 = 0xfff0 ; DW temporary for moving program code for insertion
38/ 0 : =0xFFF2 TMPF2 = 0xfff2 ; DW temp store for current program pointer
39/ 0 :
40/ 0 : =0xFFF4 RNDNUM = 0xfff4 ; DW rnd number
41/ 0 :
42/ 0 : =0xFFF6 TMPF6 = 0xfff6 ; DB,DW temporary
43/ 0 : =0xFFF8 UNUSE1 = 0xfff8 ; DW unused
44/ 0 : =0xFFFB TMPFB = 0xfffb ; DB,DW temporary
45/ 0 : =0xFFFC TMPFC = 0xfffc ; DB,DW temporary (overlaps TMPFB)
46/ 0 : =0xFFFE TMPFE = 0xfffe ; DW temporary, alias
47/ 0 :
48/ 0 : ; more constants
49/ 0 : =0x1000 RAMBASE = 0x1000 ; start of RAM
50/ 0 : =0x1400 ROMBASE = 0x1400 ; potential start of a ROM (BASIC AREA)
51/ 0 : =0xFD00 BAUDFLG = 0xFD00 ; address of baudrate selection bits
52/ 0 :
53/ 0 : =0x8 BS = 0x08 ; back space
54/ 0 : =0xD CR = 0x0d ; carriage return
55/ 0 : =0xA LF = 0x0a ; line feed
56/ 0 : =0x15 NAK = 0x15 ; CTRL-U, NAK
57/ 0 : =' ' SPACE = ' ' ; space character
58/ 0 : ='>' GTR = '>' ; prompt for interactive mode
59/ 0 : ='?' QUEST = '?' ; prompt for input mode
60/ 0 : ='^' CARET = '^' ; prefix for CTRL output
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 2 - 2024年05月30日 15時32分15秒
61/ 0 :
62/ 0 :
63/ 0 : ; interpreter starts here
64/ 0 : ; assumptions "should be" refer to 1K RAM at 0x1000-0x13ff)
65/ 0 : ORG 0
66/ 0 : 00 NOP ; lost byte because of PC preincrement
67/ 1 : 24 09 00 JMP COLD ; Jump to cold start
68/ 4 : 24 C2 08 JMP INTA ; Jump to interrupt a handler
69/ 7 : 24 C7 08 JMP INTB ; Jump to interrupt b handler
70/ A : 84 00 14 COLD: LD EA, =ROMBASE ; bottom address of ROM
71/ D : 8D D4 COLD1: ST EA, TXTBGN ; set begin of text to ROM
72/ F : 84 00 10 LD EA, =RAMBASE ; set P2 to point to base of RAM
73/ 12 : 46 LD P2, EA ;
74/ 13 : 20 75 00 COLD2: JSR TSTRAM1 ; test for RAM at loc P2
75/ 16 : 7C FB BNZ COLD2 ; not zero: no RAM, loop
76/ 18 : 32 LD EA, P2 ; found RAM, get address
77/ 19 : BC 01 00 SUB EA, =1 ; subtract 1 to get the current position
78/ 1C : 7C F5 BNZ COLD2 ; is not at xx00, search next
79/ 1E : 74 20 BRA COLD3 ; found a page skip over call tbl, continue below
80/ 20 :
81/ 20 : ; short CALL table
82/ 20 : 44 06 DW RELEXP-1 ; call 0 (RELEXP)
83/ 22 : F7 06 DW FACTOR-1 ; call 1 (FACTOR)
84/ 24 : 4F 08 DW SAVOP-1 ; call 2 (SAVOP)
85/ 26 : 82 06 DW COMPAR-1 ; call 3 (COMPAR)
86/ 28 : 42 08 DW APUSH-1 ; call 4 (APUSH)
87/ 2A : 52 08 DW APULL-1 ; call 5 (APULL)
88/ 2C : 0B 02 DW ENDCMD-1 ; call 6 (ENDCMD)
89/ 2E : 90 09 DW PUTC-1 ; call 7 (PUTC)
90/ 30 : 8B 09 DW CRLF-1 ; call 8 (CRLF)
91/ 32 : 55 05 DW GETCHR-1 ; call 9 (GETCHR)
92/ 34 : 0A 08 DW NEGATE-1 ; call 10 (NEGATE)
93/ 36 : 1C 06 DW CMPTOK-1 ; call 11 (CMPTOK)
94/ 38 : 66 05 DW EXPECT-1 ; call 12 (EXPECT c, offset)
95/ 3A : 9D 05 DW NUMBER-1 ; call 13 (NUMBER, offset)
96/ 3C : 47 05 DW PRTLN-1 ; call 14 (PRTLN)
97/ 3E : D5 08 DW ERROR-1 ; call 15 (ERROR)
98/ 40 :
99/ 40 : ; continues here from cold start
100/ 40 : 8D C6 COLD3: ST EA, EXTRAM ; arrive here with xx00, store it (should be 0x1000)
101/ 42 : B4 00 01 ADD EA, =0x0100 ; add 256
102/ 45 : 8D D2 ST EA, STACK ; store as STACK address (should be 0x1100)
103/ 47 : 45 LD SP, EA ; initialize stack pointer
104/ 48 : 20 75 00 COLD4: JSR TSTRAM1 ; check RAM at current pos P2 (should be 0x1000)
105/ 4B : 6C FB BZ COLD4 ; advance until no longer RAM
106/ 4D : ; P2 points to last RAM+2
107/ 4D : C6 FE LD A, @-2, P2 ; subtract 2 from P2
108/ 4F : 32 LD EA, P2 ; get last RAM address
109/ 50 : 8D D8 ST EA, TXTEND ; store at end of text (should be 0x13ff)
110/ 52 : 85 D4 LD EA, TXTBGN ; load begin of ROM text (0x8000)
111/ 54 : 46 LD P2, EA ; put into P2
112/ 55 : 20 75 00 JSR TSTRAM1 ; is there RAM?
113/ 58 : 6C 03 BZ COLD5 ; yes, skip
114/ 5A : 24 E2 01 JMP RUN ; no, this could be a ROM program, run it
115/ 5D : 85 D2 COLD5: LD EA, STACK ; get stack top
116/ 5F : BD D4 SUB EA, TXTBGN ; subtract begin of program
117/ 61 : 06 LD A, S ; get carry bit
118/ 62 : 64 04 BP COLD6 ; not set, skip
119/ 64 : 85 D2 LD EA, STACK ; get stack top
120/ 66 : 8D D4 ST EA, TXTBGN ; make it new TXTBGN
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 3 - 2024年05月30日 15時32分15秒
121/ 68 : C5 C5 COLD6: LD A, RUNMOD ; get mode
122/ 6A : E4 52 XOR A, ='R' ; is it 'R'?
123/ 6C : 6C 35 BZ MAINLP ; yes, skip
124/ 6E : 20 C9 05 JSR INITAL ; intialize all interpreter variables
125/ 71 : 74 27 BRA MAIN ; continue
126/ 73 :
127/ 73 : ENDRAM1:
128/ 73 : C4 FF LD A, =0xff ; if P2>=0x8000 then return NonZero(RAM END)
129/ 75 : 5C RET
130/ 76 : TSTRAM1:
131/ 76 : 32 LD EA,P2
132/ 77 : 40 LD A,E
133/ 78 : FC 80 SUB A, =0x80
134/ 7A : 64 F7 BP ENDRAM1
135/ 7C :
136/ 7C : ; check RAM at loc P2; return 0 if found, nonzero if no RAM
137/ 7C : C6 01 TSTRAM: LD A, @1, P2 ; get value from RAM, autoincrement
138/ 7E : 48 LD E, A ; save old value into E (e.g. 0x55)
139/ 7F : E4 FF XOR A, =0xff ; complement value (e.g. 0xAA)
140/ 81 : CA FF ST A, -1, P2 ; store it back (0xAA)
141/ 83 : E2 FF XOR A, -1, P2 ; read back and compare (should be 0x00)
142/ 85 : 01 XCH A, E ; A=old value, E=0x00 (if RAM)
143/ 86 : CA FF ST A, -1, P2 ; store back old value
144/ 88 : E2 FF XOR A, -1, P2 ; read back and compare (should be 0x00)
145/ 8A : 58 OR A, E ; or both tests, should be 0x00 if RAM)
146/ 8B : 5C RET ; return zero, if RAM, nonzero if none
147/ 8C :
148/ 8C : ; NEW command
149/ 8C : 20 C9 05 NEW: JSR INITAL ; initialize interpreter variables
150/ 8F : C2 00 LD A, 0, P2 ; get a char from current program position (initially ROMBASE)
151/ 91 : E4 0D XOR A, =CR ; is char a CR?
152/ 93 : 6C 05 BZ MAIN ; yes, skip to program
153/ 95 : 10 CALL 0
154/ 96 : 15 CALL 5 ; APULL
155/ 97 : 24 0C 00 JMP COLD1 ; back to cold start
156/ 9A :
157/ 9A : 85 D4 MAIN: LD EA, TXTBGN ; get start of program area
158/ 9C : 8D D6 ST EA, TXTUNF ; store as end of program
159/ 9E : 46 LD P2, EA ; point P2 to it
160/ 9F : C4 7F LD A, =0x7f ; set end of program flag
161/ A1 : CA 00 ST A, 0, P2 ; at that position
162/ A3 :
163/ A3 : ; main interpreter loop
164/ A3 : 85 D2 MAINLP: LD EA, STACK ; reinitialize stack
165/ A5 : 45 LD SP, EA
166/ A6 : 85 C6 LD EA, EXTRAM ; start of RAM
167/ A8 : B4 34 00 ADD EA, =52 ; offset to AESTK
168/ AB : 8D C8 ST EA, AESTK ; set position of arithmetic stack
169/ AD : 47 LD P3, EA ; P3 is arith stack pointer
170/ AE : 20 F6 09 JSR INITBD ; initialize baud rate
171/ B1 : 18 CALL 8 ; CRLF
172/ B2 : C5 C2 LD A, INPMOD ; mode flag?
173/ B4 : 6C 0C BZ MAINL2 ; zero, skip
174/ B6 : ; no, this is a break CTRL-C
175/ B6 : 32 LD EA, P2 ; current pointion of buffer
176/ B7 : 8D EE ST EA, CONTP ; save position (for CONT)
177/ B9 : 22 1A 09 PLI P2, =STOPMSG ; STOP message
178/ BC : 1E CALL 14 ; PRTLN
179/ BD : 5E POP P2 ; restore P2
180/ BE : 20 0A 09 JSR PRTAT ; print AT line#
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 4 - 2024年05月30日 15時32分15秒
181/ C1 : 18 MAINL1: CALL 8 ; CRLF
182/ C2 : 85 C8 MAINL2: LD EA, AESTK ; initialize P3 with AESTK
183/ C4 : 47 LD P3, EA
184/ C5 : 84 00 00 LD EA, =0 ; initialize constant ZERO
185/ C8 : 8D EA ST EA, ZERO
186/ CA : CD C2 ST A, INPMOD ; set cmd mode=0
187/ CC : C4 01 LD A, =1 ; initialize constant ONE
188/ CE : 8D E8 ST EA, ONE
189/ D0 : 20 55 08 JSR GETLN ; read a line into buffer
190/ D3 : 19 CALL 9 ; GETCHR
191/ D4 : 1D CALL 13 ; NUMBER
192/ D5 : 85 DB 0x85 ; not a number, skip to DIRECT
193/ D6 : 85 D4 LD EA, TXTBGN ; start of program
194/ D8 : BD E8 SUB EA, ONE ; minus 1
195/ DA : BD D6 SUB EA, TXTUNF ; subtract end of program
196/ DC : 06 LD A, S ; get status
197/ DD : 64 02 BP MAINL3 ; overflow? no, skip
198/ DF : 1F CALL 15 ; ERROR
199/ E0 : 01 DB 1 ; 1 (out of mem)
200/ E1 : 32 MAINL3: LD EA, P2 ; get buffer pointer
201/ E2 : 8D F0 ST EA, TMPF0 ; save it
202/ E4 : 20 76 01 JSR FINDLN ; find line in program
203/ E7 : 7C 1B BNZ MAINL4 ; no match, skip
204/ E9 : 56 PUSH P2 ; save p2 (line begin)
205/ EA : 20 9A 01 JSR TOEOLN ; advance to end of line
206/ ED : 81 00 LD EA, 0, SP ; get line begin (P2)
207/ EF : 47 LD P3, EA ; into P3
208/ F0 : 32 LD EA, P2 ; get end of line from TOEOLN
209/ F1 : 1A CALL 10 ; NEGATE
210/ F2 : 08 PUSH EA ; save -endline
211/ F3 : B5 E8 ADD EA, ONE ; add one (for CR)
212/ F5 : B5 D6 ADD EA, TXTUNF ; add end of program area
213/ F7 : 8D FE ST EA, TMPFE ; store number of bytes to move
214/ F9 : 3A POP EA ; restore -endline
215/ FA : B1 00 ADD EA, 0, SP ; subtract from start to get number of bytes to move
216/ FC : B5 D6 ADD EA, TXTUNF ; add end of program area
217/ FE : 8D D6 ST EA, TXTUNF ; set a new end of program
218/ 100 : 20 65 01 JSR BMOVE ; move area
219/ 103 : 5E POP P2 ; restore start of line
220/ 104 : ; replace or add line
221/ 104 : 32 MAINL4: LD EA, P2 ; copy into P3
222/ 105 : 47 LD P3, EA
223/ 106 : 85 F0 LD EA, TMPF0 ; buffer pointer
224/ 108 : 46 LD P2, EA ; into P2
225/ 109 : 19 CALL 9 ; GETCHR
226/ 10A : E4 0D XOR A, =CR ; is it a single line number?
227/ 10C : 6C B4 BZ MAINL2 ; yes, ignore that
228/ 10E : 85 D0 LD EA, BUFAD ; address of buffer
229/ 110 : 46 LD P2, EA ; into P2
230/ 111 : 19 CALL 9 ; GETCHR
231/ 112 : 32 LD EA, P2 ; save buffer pointer
232/ 113 : 8D F6 ST EA, TMPF6
233/ 115 : 20 9A 01 JSR TOEOLN ; advance to end of line
234/ 118 : 32 LD EA, P2 ; get end of line
235/ 119 : BD F6 SUB EA, TMPF6 ; subtract to get length of buffer
236/ 11B : 8D FE ST EA, TMPFE ; store number of bytes to move
237/ 11D : B5 D6 ADD EA, TXTUNF ; add temporary end of buffer
238/ 11F : BD D8 SUB EA, TXTEND ; store as new end of program
239/ 121 : BD E8 SUB EA, ONE ; subtract one
240/ 123 : 01 XCH A, E ; is result negative?
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 5 - 2024年05月30日 15時32分15秒
241/ 124 : 64 3E BP OMERR ; out of memory error
242/ 126 : 57 PUSH P3 ; save P3
243/ 127 : 85 D6 LD EA, TXTUNF ; get tmp area
244/ 129 : 46 LD P2, EA ; into P2
245/ 12A : 33 LD EA, P3 ; line to insert
246/ 12B : BD D6 SUB EA, TXTUNF ; subtract tmp buf
247/ 12D : 1A CALL 10 ; NEGATE
248/ 12E : 8D FB ST EA, TMPFB ; number of bytes to expand
249/ 130 : 58 OR A, E ; is result zero?
250/ 131 : 0A PUSH A ; save it for later check
251/ 132 : 85 D6 LD EA, TXTUNF ; tmp buf
252/ 134 : B5 FE ADD EA, TMPFE ; add length of line
253/ 136 : 8D D6 ST EA, TXTUNF ; store
254/ 138 : 47 LD P3, EA ; into P3
255/ 139 : C2 00 LD A, 0, P2 ; copy a byte
256/ 13B : CB 00 ST A, 0, P3
257/ 13D : 38 POP A ; restore result from above (sets Z flag)
258/ 13E : 6C 10 BZ MAINL6 ; was zero, skip
259/ 140 : C6 FF MAINL5: LD A, @-1, P2 ; otherwise copy backwards TMPFB bytes
260/ 142 : CF FF ST A, @-1, P3
261/ 144 : 9D FB DLD A, TMPFB ; decrement byte counter
262/ 146 : 7C F8 BNZ MAINL5
263/ 148 : C5 FC LD A, TMPFB+1
264/ 14A : 6C 04 BZ MAINL6 ; exit loop if zero
265/ 14C : 9D FC DLD A, TMPFB+1
266/ 14E : 74 F0 BRA MAINL5 ; loop
267/ 150 : 5F MAINL6: POP P3 ; restore target location
268/ 151 : 85 F6 LD EA, TMPF6
269/ 153 : 46 LD P2, EA ; restore source location
270/ 154 : 20 65 01 JSR BMOVE ; move new line into program
271/ 157 : 24 C1 00 MAINL7: JMP MAINL2 ; done, continue in main loop
272/ 15A :
273/ 15A : ; parse a direct command
274/ 15A : C2 00 DIRECT: LD A, 0, P2 ; get char from buffer
275/ 15C : E4 0D XOR A, =CR ; is it a CR?
276/ 15E : 6C F7 BZ MAINL7 ; yes, continue in main loop
277/ 160 : 23 A1 01 PLI P3, =CMDTB1 ; load first CMD table
278/ 163 : 1B CALL 11 ; CMPTOK
279/ 164 :
280/ 164 : ; out of memory error
281/ 164 : 1F OMERR: CALL 15 ; ERROR
282/ 165 : 01 DB 1 ; 1 (out of memory)
283/ 166 : ;--------------------------------------------------------------------------------------------------
284/ 166 :
285/ 166 : ; move TMPFE bytes ascending from @P2 to @P3
286/ 166 : C6 01 BMOVE: LD A, @1, P2 ; get char from first pos
287/ 168 : CF 01 ST A, @1, P3 ; store into second
288/ 16A : 9D FE DLD A, TMPFE ; decrement byte counter 16 bit
289/ 16C : 7C F8 BNZ BMOVE
290/ 16E : C5 FF LD A, TMPFE+1
291/ 170 : 6C 04 BZ BMOVE1 ; exit if zero
292/ 172 : 9D FF DLD A, TMPFE+1
293/ 174 : 74 F0 BRA BMOVE ; loop
294/ 176 : 5C BMOVE1: RET
295/ 177 : ;--------------------------------------------------------------------------------------------------
296/ 177 : ; find line in program, 0 = found, 1 = insert before, -1 = not found, line in P2
297/ 177 : ; line number to find is on AESTK
298/ 177 : 85 D4 FINDLN: LD EA, TXTBGN ; get start of program
299/ 179 : 46 LD P2, EA ; into P2
300/ 17A : 32 FINDL1: LD EA, P2 ; get P2
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 6 - 2024年05月30日 15時32分15秒
301/ 17B : 8D FB ST EA, TMPFB ; save temporary
302/ 17D : 19 CALL 9 ; GETCHR
303/ 17E : 1D CALL 13 ; NUMBER
304/ 17F : 18 DB 0x18 ; skip if not number to FINDL4
305/ 180 : 15 CALL 5 ; APULL
306/ 181 : BB FE SUB EA, -2, P3 ; subtract number from the one on stack (the line number found)
307/ 183 : 01 XCH A, E ; is larger?
308/ 184 : 64 05 BP FINDL2 ; yes skip
309/ 186 : 20 9A 01 JSR TOEOLN ; advance to end of line
310/ 189 : 74 EF BRA FINDL1 ; loop
311/ 18B : 58 FINDL2: OR A, E
312/ 18C : 6C 02 BZ FINDL3 ; is exactly the same?
313/ 18E : C4 01 LD A, =01 ; no, return 1
314/ 190 : 0A FINDL3: PUSH A
315/ 191 : 15 CALL 5 ; APULL
316/ 192 : 85 FB LD EA, TMPFB ; get start of this line
317/ 194 : 46 LD P2, EA ; into P2
318/ 195 : 38 POP A ; restore result
319/ 196 : 5C RET ; return with 0, if exact match, 1 if insert
320/ 197 : C4 FF FINDL4: LD A, =0xff ; return with -1: end of program
321/ 199 : 74 F5 BRA FINDL3
322/ 19B :
323/ 19B : ;--------------------------------------------------------------------------------------------------
324/ 19B : ; advance to end of line
325/ 19B : C4 0D TOEOLN: LD A, =CR ; search for end of line
326/ 19D : 2E SSM P2 ; should be within next 256 bytes
327/ 19E : 74 17 BRA UCERR ; didn't find one, error 3
328/ 1A0 : 5C RET ; found one, return with P2 pointing to char after CR
329/ 1A1 :
330/ 1A1 : ;--------------------------------------------------------------------------------------------------
331/ 1A1 : ; set of DIRECT commands
332/ 1A1 : 4C 49 53 54 CMDTB1: DB 'LIST'
333/ 1A5 : 93 DB 0x93 ; to LIST
334/ 1A6 : 4E 45 57 DB 'NEW'
335/ 1A9 : 8A DB 0x8a ; to NEW2
336/ 1AA : 52 55 4E DB 'RUN'
337/ 1AD : B5 DB 0xb5 ; to RUN
338/ 1AE : 43 4F 4E 54 DB 'CONT'
339/ 1B2 : A7 DB 0xa7 ; to CONT
340/ 1B3 : D2 DB 0xd2 ; default case to EXEC1
341/ 1B4 :
342/ 1B4 : ;--------------------------------------------------------------------------------------------------
343/ 1B4 : ; NEW command
344/ 1B4 : 24 8B 00 NEW2: JMP NEW ; do new command
345/ 1B7 :
346/ 1B7 : ;--------------------------------------------------------------------------------------------------
347/ 1B7 : 1F UCERR: CALL 15 ; ERROR
348/ 1B8 : 03 DB 3 ; 3 (unexpected char)
349/ 1B9 :
350/ 1B9 : ;--------------------------------------------------------------------------------------------------
351/ 1B9 : ; LIST command
352/ 1B9 : 1D LIST: CALL 13 ; NUMBER
353/ 1BA : 03 DB 3 ; if no number, skip to LIST0
354/ 1BB : 74 03 BRA LIST1
355/ 1BD : 85 EA LIST0: LD EA, ZERO ; no number given, start with line 0
356/ 1BF : 14 CALL 4 ; APUSH put on stack
357/ 1C0 : 20 76 01 LIST1: JSR FINDLN ; find line in program, or next one
358/ 1C3 : 19 LIST2: CALL 9 ; GETCHR from location found
359/ 1C4 : 56 PUSH P2
360/ 1C5 : 1D CALL 13 ; NUMBER
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 7 - 2024年05月30日 15時32分15秒
361/ 1C6 : 0A DB 0x0a ; if error, goto LIST3
362/ 1C7 : 15 CALL 5 ; APULL
363/ 1C8 : 5E POP P2
364/ 1C9 : 1E CALL 14 ; PRTLN
365/ 1CA : 18 CALL 8 ; CRLF
366/ 1CB : 20 26 09 JSR CHKBRK ; test break
367/ 1CE : 74 F3 BRA LIST2
368/ 1D0 : 5E LIST3: POP P2
369/ 1D1 : 24 A2 00 MAIN1: JMP MAINLP
370/ 1D4 :
371/ 1D4 : ;--------------------------------------------------------------------------------------------------
372/ 1D4 : 54 48 45 4E CMDTB6: DB 'THEN' ; then table
373/ 1D8 : AD DB 0xad ; to EXEC1
374/ 1D9 : AC DB 0xac ; default case to EXEC1
375/ 1DA :
376/ 1DA : ;--------------------------------------------------------------------------------------------------
377/ 1DA : ; CONT command
378/ 1DA : 85 EE CONT: LD EA, CONTP ; restore program pointer from CONT
379/ 1DC : 46 LD P2, EA
380/ 1DD : C4 01 LD A, =01 ; set program mode
381/ 1DF : CD C2 ST A, INPMOD
382/ 1E1 : 74 37 BRA ENDCM1
383/ 1E3 :
384/ 1E3 : ;--------------------------------------------------------------------------------------------------
385/ 1E3 : ; RUN command
386/ 1E3 : 20 C9 05 RUN: JSR INITAL ; initialize interpreter variables
387/ 1E6 : C4 01 LD A, =01 ; set "running mode"
388/ 1E8 : CD C2 ST A, INPMOD
389/ 1EA : 85 D4 LD EA, TXTBGN ; start at first line
390/ 1EC : 46 LD P2, EA ; in buffer
391/ 1ED : 74 04 BRA RUN2 ; skip
392/ 1EF : C5 C2 RUN1: LD A, INPMOD
393/ 1F1 : 6C DE BZ MAIN1
394/ 1F3 : 85 EA RUN2: LD EA, ZERO ; load 0
395/ 1F5 : 14 CALL 4 ; APUSH
396/ 1F6 :
397/ 1F6 : 20 79 01 RUN3: JSR FINDL1 ; find line from current position
398/ 1F9 : 64 06 BP RUN4 ; found one
399/ 1FB : C4 00 LD A, =00 ; set 'not running'
400/ 1FD : CD C2 ST A, INPMOD
401/ 1FF : 74 D0 BRA MAIN1 ; back to mainloop
402/ 201 : 1D RUN4: CALL 13 ; parse line NUMBER
403/ 202 : 08 DB 8 ; not found: syntax error, goto SNERR1
404/ 203 : 15 CALL 5 ; APULL line number
405/ 204 : 8D C3 ST EA, CURRNT ; set as current line
406/ 206 :
407/ 206 :
408/ 206 : 23 37 02 EXEC1: PLI P3, =CMDTB2 ; run loop
409/ 209 : 1B CALL 11 ; process commands
410/ 20A :
411/ 20A : 1F SNERR1: CALL 15 ; ERROR
412/ 20B : 04 DB 4 ; 4 (syntax error)
413/ 20C :
414/ 20C : ;--------------------------------------------------------------------------------------------------
415/ 20C : ; handle end of CMD, check for break or interrupts... (call 6)
416/ 20C : 3A ENDCMD: POP EA ; drop return address
417/ 20D : C5 E7 LD A, 0xffe7 ; flag set?
418/ 20F : 7C 09 BNZ ENDCM1 ; yes, skip
419/ 211 : C5 C2 LD A, INPMOD ; interactive mode?
420/ 213 : 6C 05 BZ ENDCM1 ; yes skip
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 8 - 2024年05月30日 15時32分15秒
421/ 215 : 85 E0 LD EA, INTVEC ; interrupt pending?
422/ 217 : 58 OR A, E
423/ 218 : 7C 14 BNZ ENDCM3 ; yes, skip
424/ 21A :
425/ 21A : C4 00 ENDCM1: LD A, =0
426/ 21C : CD E7 ST A, NOINT
427/ 21E : 20 26 09 JSR CHKBRK ; check for break
428/ 221 : 1C CALL 12 ; EXPECT
429/ 222 : 3A DB ':' ; colon?
430/ 223 : 03 DB 0x03 ; no, to ENDCM2
431/ 224 : 74 E0 BRA EXEC1 ; continue run loop
432/ 226 : C6 01 ENDCM2: LD A, @1, P2 ; advance to next char
433/ 228 : E4 0D XOR A, =CR ; is it end of line?
434/ 22A : 7C 8B BNZ UCERR ; error unexpected char
435/ 22C : 74 C1 BRA RUN1 ; continue
436/ 22E :
437/ 22E : 85 E0 ENDCM3: LD EA, INTVEC ; get pending int vector
438/ 230 : 14 CALL 4 ; APUSH
439/ 231 : 85 EA LD EA, ZERO ;
440/ 233 : 8D E0 ST EA, INTVEC ; clear pending int
441/ 235 : 74 49 BRA GOSUB1 ; jump into GOSUB (process interrupt)
442/ 237 :
443/ 237 : 4C 45 54 CMDTB2: DB 'LET'
444/ 23A : A6 DB 0xa6 ; to LET
445/ 23B : 49 46 DB 'IF'
446/ 23D : F3 DB 0xf3 ; to IFCMD
447/ 23E : 4C 49 4E 4B DB 'LINK'
448/ 242 : F7 DB 0xf7 ; to LINK
449/ 243 : 4E 45 58 54 DB 'NEXT'
450/ 247 : 9C DB 0x9c ; to NEXT
451/ 248 : 55 4E 54 49 4C DB 'UNTIL'
452/ 24D : DB DB 0xdb ; to UNTIL
453/ 24E : 47 4F DB 'GO'
454/ 250 : 96 DB 0x96 ; to GOCMD
455/ 251 : 52 45 54 55 52 4E DB 'RETURN'
456/ 257 : BD DB 0xbd ; to RETURN
457/ 258 : 52 45 4D DB 'REM'
458/ 25B : CF DB 0xcf ; to REMCMD
459/ 25C : 80 DB 0x80 ; default case to EXEC2
460/ 25D :
461/ 25D : 23 C8 02 EXEC2: PLI P3, =CMDTB7 ; load table 7
462/ 260 : 1B CALL 11 ; CMPTOK
463/ 261 :
464/ 261 : ;------------------------------------------------------------------------------
465/ 261 : ; forward to assignment
466/ 261 : 24 63 04 LET: JMP ASSIGN ; ignore LET and continue with general assigment
467/ 264 :
468/ 264 : ;------------------------------------------------------------------------------
469/ 264 : ; forward to NEXT cmd
470/ 264 : 24 71 03 NEXT: JMP NEXT0 ; handle NEXT
471/ 267 :
472/ 267 : ;------------------------------------------------------------------------------
473/ 267 : ; handle GOTO or GOSUB
474/ 267 : 23 6B 02 GOCMD: PLI P3, =CMDTB5 ; check for TO or SUB
475/ 26A : 1B CALL 11
476/ 26B :
477/ 26B : 54 4F CMDTB5: DB 'TO'
478/ 26D : 85 DB 0x85 ; to GOTO
479/ 26E : 53 55 42 DB 'SUB'
480/ 271 : 8D DB 0x8d
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 9 - 2024年05月30日 15時32分15秒
481/ 272 : 80 DB 0x80 ; default case to GOTO
482/ 273 :
483/ 273 : ;------------------------------------------------------------------------------
484/ 273 : ; GOTO command
485/ 273 : 10 GOTO: CALL 0 ; RELEXP
486/ 274 : C4 01 GOTO1: LD A, =1 ;
487/ 276 : CD C2 ST A, INPMOD ; set 'running mode'
488/ 278 : 20 76 01 JSR FINDLN ; find line in buffer
489/ 27B : 6C 84 BZ RUN4 ; skip to line number check
490/ 27D : 1F CALL 15 ; error
491/ 27E : 07 DB 7 ; 7 (goto target does not exist)
492/ 27F :
493/ 27F : ;------------------------------------------------------------------------------
494/ 27F : ; GOSUB command
495/ 27F : 10 GOSUB: CALL 0 ; RELEXP
496/ 280 : 85 DE GOSUB1: LD EA, SBRPTR ; get SBR stack pointer
497/ 282 : 57 PUSH P3 ; save P3
498/ 283 : 47 LD P3, EA ; SBR stack in P3
499/ 284 : 85 CC LD EA, DOSTK ; mark do stack pointer
500/ 286 : CD F6 ST A, TMPF6 ; in temporary
501/ 288 : 33 LD EA, P3 ; get SBR stack ptr
502/ 289 : 20 C9 03 JSR CHKSBR ; check for overflow
503/ 28C : 32 LD EA, P2 ; get buffer pointer
504/ 28D : 8F 02 ST EA, @2, P3 ;
505/ 28F : 33 LD EA, P3 ; save new SBR pointer
506/ 290 : 8D DE ST EA, SBRPTR
507/ 292 : 5F POP P3 ; restore P3
508/ 293 : 74 DF BRA GOTO1 ; do GOTO
509/ 295 :
510/ 295 : ;------------------------------------------------------------------------------
511/ 295 : ; RETURN command
512/ 295 : 85 DE RETURN: LD EA, SBRPTR ; get SBR ptr
513/ 297 : BD CA SUB EA, SBRSTK ; is stack empty?
514/ 299 : 6C 0C BZ RETERR ; yes error 8
515/ 29B : 85 DE LD EA, SBRPTR ; decrement SBR ptr
516/ 29D : BC 02 00 SUB EA, =2
517/ 2A0 : 8D DE ST EA, SBRPTR ; store it back
518/ 2A2 : 46 LD P2, EA ; into P2
519/ 2A3 : 82 00 LD EA, 0, P2 ; restore buffer pointer
520/ 2A5 : 46 LD P2, EA
521/ 2A6 : 16 CALL 6 ; ENDCMD
522/ 2A7 :
523/ 2A7 : ;------------------------------------------------------------------------------
524/ 2A7 : 1F RETERR: CALL 15 ; ERROR
525/ 2A8 : 08 DB 8 ; 8 (return without gosub)
526/ 2A9 :
527/ 2A9 : ;------------------------------------------------------------------------------
528/ 2A9 : ; forward to UNTIL
529/ 2A9 : 74 5F UNTIL: BRA UNTIL0 ; redirect to real code
530/ 2AB :
531/ 2AB : ;------------------------------------------------------------------------------
532/ 2AB : ; REM
533/ 2AB : 20 9A 01 REMCMD: JSR TOEOLN ; advance to end of line
534/ 2AE : C6 FF LD A, @-1, P2 ; back one char
535/ 2B0 : 16 CALL 6 ; ENDCMD
536/ 2B1 :
537/ 2B1 : ;------------------------------------------------------------------------------
538/ 2B1 : ; IF
539/ 2B1 : 10 IFCMD: CALL 0 ; RELEXP get condition
540/ 2B2 : 15 CALL 5 ; APULL pop it into EA
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 10 - 2024年05月30日 15時32分15秒
541/ 2B3 : 58 OR A, E ; check for zero
542/ 2B4 : 6C F5 BZ REMCMD ; false: advance to end of line
543/ 2B6 : 23 D4 01 PLI P3, =CMDTB6 ; process THEN (may be missing)
544/ 2B9 : 1B CALL 11 ; CMPTOK
545/ 2BA :
546/ 2BA : ;------------------------------------------------------------------------------
547/ 2BA : ; LINK
548/ 2BA : 10 LINK: CALL 0 ; RELEXP get link address
549/ 2BB : 22 CB 04 PLI P2, =DOLAL6-1 ; save P2, put return vector into P2
550/ 2BE : 15 CALL 5 ; APULL pop link address
551/ 2BF : 57 PUSH P3 ; push P3 on stack
552/ 2C0 : 56 PUSH P2 ; put return vector on stack
553/ 2C1 : BD E8 SUB EA, ONE ; adjust link address
554/ 2C3 : 08 PUSH EA ; push on stack
555/ 2C4 : 85 C6 LD EA, EXTRAM ; load P2 with base of variables
556/ 2C6 : 46 LD P2, EA
557/ 2C7 : 5C RET ; return to link address
558/ 2C8 : ; note: the stack frame is (before RET):
559/ 2C8 : ; P2 = variables
560/ 2C8 : ; Top: linkaddress-1 (pulled by RET here)
561/ 2C8 : ; returnvector-1 (pulled by RET in called program)
562/ 2C8 : ; saved P3 (restored in returnvector stub)
563/ 2C8 : ; saved P2 (restored in returnvector stub)
564/ 2C8 :
565/ 2C8 : ;------------------------------------------------------------------------------
566/ 2C8 : 46 4F 52 CMDTB7: DB 'FOR'
567/ 2CB : E4 DB 0xe4 ; to FOR
568/ 2CC : 44 4F DB 'DO'
569/ 2CE : A7 DB 0xa7 ; to DO
570/ 2CF : 4F 4E DB 'ON'
571/ 2D1 : 8F DB 0x8f ; to ON
572/ 2D2 : 43 4C 45 41 52 DB 'CLEAR'
573/ 2D7 : 85 DB 0x85 ; to CLEAR
574/ 2D8 : 80 DB 0x80 ; to EXEC3
575/ 2D9 :
576/ 2D9 : ;------------------------------------------------------------------------------
577/ 2D9 : ; handle several commands for direct/program mode
578/ 2D9 : 23 2C 04 EXEC3: PLI P3, =CMDTB8
579/ 2DC : 1B CALL 11 ; CMPTOK
580/ 2DD :
581/ 2DD : ;------------------------------------------------------------------------------
582/ 2DD : ; CLEAR cmd
583/ 2DD : 20 CE 05 CLEAR: JSR INITA1 ; do warm initialization
584/ 2E0 : 16 CALL 6 ; ENDCMD
585/ 2E1 :
586/ 2E1 : ;------------------------------------------------------------------------------
587/ 2E1 : ; ON cmd
588/ 2E1 : 10 ON: CALL 0 ; RELEXP get expression
589/ 2E2 : 1C CALL 12 ; EXPECT check if comma follows
590/ 2E3 : 2C DB ','
591/ 2E4 : 01 DB 1 ; if not, continue next instruction
592/ 2E5 : 15 ON1: CALL 5 ; APULL get expression
593/ 2E6 : D4 01 AND A, =1 ; has it bit 0 set?
594/ 2E8 : 6C 07 BZ ON2 ; no, skip
595/ 2EA : CD E6 ST A, BRKFLG ; store nonzero in BRKFLG
596/ 2EC : 10 CALL 0 ; RELEXP get INTA vector expression
597/ 2ED : 15 CALL 5 ; APULL into EA
598/ 2EE : 8D E2 ST EA, INTAVC ; set as INTA call vector
599/ 2F0 : 16 CALL 6 ; ENDCMD done
600/ 2F1 :
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 11 - 2024年05月30日 15時32分15秒
601/ 2F1 : ; assume here another bit set
602/ 2F1 : 10 ON2: CALL 0 ; RELEXP get INTB vector expression
603/ 2F2 : 15 CALL 5 ; APULL into EA
604/ 2F3 : 8D E4 ST EA, INTBVC ; set as INTB call vector
605/ 2F5 : 16 CALL 6 ; ENDCMD done
606/ 2F6 :
607/ 2F6 : ;------------------------------------------------------------------------------
608/ 2F6 : ; DO cmd
609/ 2F6 : 85 DA DO: LD EA, DOPTR ; get DO stack ptr
610/ 2F8 : 57 PUSH P3 ; save P3
611/ 2F9 : 47 LD P3, EA ; into P3
612/ 2FA : 85 CE LD EA, FORSTK ; put end of stack (FORSTK is adjacent)
613/ 2FC : CD F6 ST A, TMPF6 ; into temporary
614/ 2FE : 33 LD EA, P3 ; DO stack pointer
615/ 2FF : 20 C9 03 JSR CHKSBR ; check stack overflow
616/ 302 : 32 LD EA, P2 ; get current program pointer
617/ 303 : 8F 02 ST EA, @02, P3 ; push on DO stack
618/ 305 : 33 LD EA, P3 ; and save new DO stack ptr
619/ 306 : 5F POP P3 ; restore P3
620/ 307 : 8D DA DO1: ST EA, DOPTR
621/ 309 : 16 CALL 6 ; ENDCMD done
622/ 30A : ;; RET ; done
623/ 30A :
624/ 30A : ;------------------------------------------------------------------------------
625/ 30A : ;UNTIL command
626/ 30A : 10 UNTIL0: CALL 0 ; RELEXP get condition
627/ 30B : 85 DA LD EA, DOPTR ; get DO stack ptr
628/ 30D : BD CC SUB EA, DOSTK ; subtrack stack base
629/ 30F : 58 OR A,E ; is empty?
630/ 310 : 7C 02 BNZ UNTIL1 ; no, continue
631/ 312 : ; otherwise throw error 11
632/ 312 : 1F CALL 15 ; ERROR
633/ 313 : 0B DB 0x0b ; 11 (UNTIL without DO)
634/ 314 : 15 UNTIL1: CALL 5 ; APULL condition into EA
635/ 315 : 58 OR A,E ; is false?
636/ 316 : 6C 07 BZ UNTIL2 ; yes, skip
637/ 318 : 85 DA LD EA, DOPTR ; no, discard DO loop from stack
638/ 31A : BC 02 00 SUB EA, =0002 ; 1 level
639/ 31D : 74 E8 BRA DO1 ; store back DO stack ptr and exit
640/ 31F : 85 DA UNTIL2: LD EA, DOPTR ; do loop again
641/ 321 : 46 LD P2, EA ; get DO stack ptr
642/ 322 : 82 FE LD EA, -2, P2 ; get last level stored
643/ 324 : 46 LD P2, EA ; as new program pointer -> redo loop
644/ 325 : 16 CALL 6 ; ENDCMD
645/ 326 : ;; RET ; done
646/ 326 :
647/ 326 : ;------------------------------------------------------------------------------
648/ 326 : ; for comparison of FOR keyword STEP
649/ 326 : 53 54 45 50 CMDTB9: DB 'STEP'
650/ 32A : 96 DB 0x96 ; to FOR2
651/ 32B : 98 DB 0x98 ; to FOR3
652/ 32C :
653/ 32C : ; for comparison of FOR keyword TO
654/ 32C : 54 4F CMDT10: DB 'TO'
655/ 32E : 8D DB 0x8d ; to FOR1
656/ 32F : FD DB 0xfd ; to SNERR2 (syntax error)
657/ 330 :
658/ 330 : 20 75 05 FOR: JSR GETVAR ; get a variable address on stack
659/ 333 : 7A DB 0x7a ; none found: goto SNERR2 (syntax error)
660/ 334 : 1C CALL 12 ; EXPECT a '='
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 12 - 2024年05月30日 15時32分15秒
661/ 335 : 3D DB '='
662/ 336 : 77 DB 0x77 ; none found: goto SNERR2 (syntax error)
663/ 337 : 10 CALL 0 ; RELEXP get initial expression
664/ 338 : 23 2C 03 PLI P3, =CMDT10 ; expect TO keyword (SNERR if not)
665/ 33B : 1B CALL 11 ; CMPTOK
666/ 33C :
667/ 33C : 10 FOR1: CALL 0 ; RELEXP get end expression
668/ 33D : 23 26 03 PLI P3, =CMDTB9 ; check for STEP keyword, to FOR2 if found, to FOR3 if not
669/ 340 : 1B CALL 11 ; CMPTOK
670/ 341 :
671/ 341 : 10 FOR2: CALL 0 ; RELEXP get step expression
672/ 342 : 74 04 BRA FOR4 ; skip
673/ 344 : 85 E8 FOR3: LD EA, ONE ; push 1 as STEP on stack
674/ 346 : 8F 02 ST EA, @2, P3
675/ 348 : 85 DC FOR4: LD EA, FORPTR ; get the FOR stack ptr
676/ 34A : 56 PUSH P2 ; save current program ptr
677/ 34B : 46 LD P2, EA ; into P2
678/ 34C : 85 D0 LD EA, BUFAD ; put end of stack (BUFAD is adjacent)
679/ 34E : CD F6 ST A, TMPF6 ; into temporary
680/ 350 : 32 LD EA, P2 ; FOR stack ptr
681/ 351 : 20 C9 03 JSR CHKSBR ; check stack overflow
682/ 354 : 15 CALL 5 ; APULL restore step value
683/ 355 : 8E 02 ST EA, @2, P2 ; save at forstack+0
684/ 357 : 15 CALL 5 ; APULL restore end value
685/ 358 : 8E 02 ST EA, @2, P2 ; save at forstack+2
686/ 35A : 15 CALL 5 ; APULL restore initial value
687/ 35B : 09 LD T, EA ; save in T
688/ 35C : 15 CALL 5 ; APULL restore variable address
689/ 35D : 8D F6 ST EA, TMPF6 ; store address in temporary
690/ 35F : CE 01 ST A, @1, P2 ; save low offset of var at forstack+4
691/ 361 : 81 00 LD EA, 0, SP ; get current program ptr
692/ 363 : 8E 02 ST EA, @2, P2 ; save at forstack+5
693/ 365 : 32 LD EA, P2 ; save new FOR stack ptr
694/ 366 : 8D DC ST EA, FORPTR
695/ 368 : 85 F6 LD EA, TMPF6 ; get variable address
696/ 36A : 46 LD P2, EA ; into P2
697/ 36B : 0B LD EA, T ; initial value
698/ 36C : 8A 00 ST EA, 0, P2 ; save in variable
699/ 36E : 5E FOR5: POP P2 ; restore program pointer
700/ 36F : 16 CALL 6 ; ENDCMD
701/ 370 : ; note the FOR stack frame looks like the following:
702/ 370 : ; offset 0: DW step value
703/ 370 : ; offset 2: DW end value
704/ 370 : ; offset 4: DB variable low offset
705/ 370 : ; offset 5: DW program pointer of first statement of loop
706/ 370 :
707/ 370 : 1F NXERR: CALL 15 ; ERROR
708/ 371 : 0A DB 10 ; 10 (NEXT without FOR)
709/ 372 :
710/ 372 : ; NEXT command
711/ 372 : 20 75 05 NEXT0: JSR GETVAR ; get variable address on stack
712/ 375 : 38 DB 0x38 ; no var found, goto SNERR2 (syntax error)
713/ 376 : 15 CALL 5 ; APULL restore address
714/ 377 : 09 LD T, EA ; put into T
715/ 378 : 85 DC NEXT1: LD EA, FORPTR ; get FOR stack ptr
716/ 37A : BD CE SUB EA, FORSTK ; subtract base
717/ 37C : 6C F2 BZ NXERR ; is empty? yes, NEXT without FOR error
718/ 37E : 85 DC LD EA, FORPTR ; get FOR stack ptr again
719/ 380 : BC 07 00 SUB EA, =0007 ; discard current frame
720/ 383 : 8D DC ST EA, FORPTR ; save it for the case loop ends
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 13 - 2024年05月30日 15時32分15秒
721/ 385 : 56 PUSH P2 ; save program pointer
722/ 386 : 46 LD P2, EA ; point to base of current FOR frame
723/ 387 : 0B LD EA, T ; get var address
724/ 388 : FA 04 SUB A, 4, P2 ; subtract var addr of this frame
725/ 38A : 6C 03 BZ NEXT2 ; is the same?, yes skip (found)
726/ 38C : 5E POP P2 ; restore P2
727/ 38D : 74 E9 BRA NEXT1 ; try another loop - assume jump out of loop
728/ 38F : C2 01 NEXT2: LD A, 1, P2 ; step value (high byte)
729/ 391 : 64 09 BP NEXT3 ; is step positive? yes, skip
730/ 393 : 20 AE 03 JSR NXADD ; add step and compare with end value
731/ 396 : E4 FF XOR A, =0xff ; compare with -1
732/ 398 : 6C 07 BZ NEXT5 ; zero? yes, end of loop not yet reached
733/ 39A : 74 03 BRA NEXT4 ; skip
734/ 39C : 20 AE 03 NEXT3: JSR NXADD ; add step and compare with end value
735/ 39F : 64 CD NEXT4: BP FOR5 ; end of loop done, continue after NEXT
736/ 3A1 : 82 05 NEXT5: LD EA, 5, P2 ; get start of loop program pointer
737/ 3A3 : 5E POP P2 ; drop P2
738/ 3A4 : 46 LD P2, EA ; set start of loop again
739/ 3A5 : 85 DC LD EA, FORPTR ; get FOR stack ptr
740/ 3A7 : B4 07 00 ADD EA, =0007 ; push loop frame again
741/ 3AA : 8D DC ST EA, FORPTR ; save new FOR ptr
742/ 3AC : 16 CALL 6 ; ENDCMD
743/ 3AD : ;; RET ; done
744/ 3AD :
745/ 3AD : 1F SNERR2: CALL 15 ; ERROR
746/ 3AE : 04 DB 4 ; 4 (syntax error)
747/ 3AF :
748/ 3AF : ;------------------------------------------------------------------------------
749/ 3AF : ; add step and compare with end value
750/ 3AF : 85 C6 NXADD: LD EA, EXTRAM ; variable base
751/ 3B1 : C2 04 LD A, 4, P2 ; get variable offset
752/ 3B3 : 57 PUSH P3 ; save P3
753/ 3B4 : 47 LD P3, EA ; into EA
754/ 3B5 : 83 00 LD EA, 0, P3 ; get variable value
755/ 3B7 : B2 00 ADD EA, 0, P2 ; add step value
756/ 3B9 : 8B 00 ST EA, 0, P3 ; store new variable
757/ 3BB : 5F POP P3 ; restore P3
758/ 3BC : BA 02 SUB EA, 2, P2 ; compare with end value
759/ 3BE : 6C 04 BZ NXADD2 ; same?
760/ 3C0 : 01 XCH A, E ; no, swap: A = high byte
761/ 3C1 : D4 80 NXADD1: AND A, =0x80 ; mask out sign bit
762/ 3C3 : 5C RET ; return
763/ 3C4 : 01 NXADD2: XCH A, E ; swap: A = high byte
764/ 3C5 : 7C FA BNZ NXADD1 ; not same? get high byte
765/ 3C7 : C4 FF LD A, =0xff ; set A = -1
766/ 3C9 : 5C RET ; return
767/ 3CA :
768/ 3CA : ;------------------------------------------------------------------------------
769/ 3CA : ; check for SBR stack overflow
770/ 3CA : ; EA contains current stack pointer, TMPF6 contains limit
771/ 3CA : FD F6 CHKSBR: SUB A, TMPF6 ; subrack limit
772/ 3CC : 64 01 BP NSERR ; beyond limit?
773/ 3CE : 5C RET ; no, exit
774/ 3CF : ; otherwise nesting too deep error
775/ 3CF : 1F NSERR: CALL 15 ; ERROR
776/ 3D0 : 09 DB 9 ; 9 (nesting too deep)
777/ 3D1 :
778/ 3D1 : ;------------------------------------------------------------------------------
779/ 3D1 : 1F SUERR: CALL 15 ; ERROR
780/ 3D2 : 02 DB 2 ; 2 (stmt used improperly)
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 14 - 2024年05月30日 15時32分15秒
781/ 3D3 :
782/ 3D3 : ;------------------------------------------------------------------------------
783/ 3D3 : ; INPUT handler
784/ 3D3 : C5 C2 INPUT0: LD A, INPMOD ; is in direct mode?
785/ 3D5 : 6C FA BZ SUERR ; yes, this is an error!
786/ 3D7 : 32 LD EA, P2 ; save current program ptr temporarily
787/ 3D8 : 8D F2 ST EA, TMPF2
788/ 3DA : 20 75 05 INPUT1: JSR GETVAR ; get variable address on stack
789/ 3DD : 29 DB 0x29 ; no variable, goto INPUT3 (could be $)
790/ 3DE : C4 03 LD A, =03 ; set mode 3, swap buffers (P2 is input buffer)
791/ 3E0 : 20 23 04 JSR SWPBUF
792/ 3E3 : 20 55 08 JSR GETLN ; get line into input buffer
793/ 3E6 : 10 INPUT2: CALL 0 ; RELEXP get expression from input buffer
794/ 3E7 : 15 CALL 5 ; APULL into EA
795/ 3E8 : 09 LD T, EA ; save into T
796/ 3E9 : 15 CALL 5 ; APULL get variable address
797/ 3EA : 57 PUSH P3 ; save P3
798/ 3EB : 47 LD P3, EA ; into P3
799/ 3EC : 0B LD EA, T ; obtain expression
800/ 3ED : 8B 00 ST EA, 0, P3 ; save into variable
801/ 3EF : 5F POP P3 ; restore P3
802/ 3F0 : C4 01 LD A, =01 ; set mode 1, swap buffers (P2 is program ptr)
803/ 3F2 : 20 23 04 JSR SWPBUF
804/ 3F5 : 1C CALL 12 ; EXPECT a comma
805/ 3F6 : 2C DB ','
806/ 3F7 : 2C DB 0x2c ; if not found, exit via INPUT5
807/ 3F8 : 20 75 05 JSR GETVAR ; get another variable
808/ 3FB : D6 DB 0xd6 ; if none found, goto SUERR (error 2)
809/ 3FC : ; does not accept $ any more here
810/ 3FC : C4 03 LD A, =03 ; set mode 3, swap buffers (P2 is input buffer)
811/ 3FE : 20 23 04 JSR SWPBUF
812/ 401 : 1C CALL 12 ; EXPECT an optional comma in input buffer
813/ 402 : 2C DB ','
814/ 403 : 01 DB 1 ; none found, ignore
815/ 404 : 74 E0 BRA INPUT2 ; process the next variable
816/ 406 :
817/ 406 : ; process $expr for string input
818/ 406 : 1C INPUT3: CALL 12 ; EXPECT a $ here
819/ 407 : 24 DB '$'
820/ 408 : C9 DB 0xc9 ; none found, goto SUERR
821/ 409 : 11 CALL 1 ; FACTOR get string buffer address
822/ 40A : C4 03 LD A, =03 ; set mode 3, swap buffers (P2 is input buffer)
823/ 40C : 20 23 04 JSR SWPBUF
824/ 40F : 20 55 08 JSR GETLN ; get line of input
825/ 412 : 15 CALL 5 ; APULL get buffer address
826/ 413 : 57 PUSH P3 ; save P3
827/ 414 : 47 LD P3, EA ; into P3
828/ 415 : C6 01 INPUT4: LD A, @1, P2 ; copy input from buffer into string
829/ 417 : CF 01 ST A, @1, P3
830/ 419 : E4 0D XOR A, =CR ; until CR seen
831/ 41B : 7C F8 BNZ INPUT4
832/ 41D : 5F POP P3 ; restore P3
833/ 41E : C4 01 LD A, =01 ; set mode 1 again, swap buffers (P2 is program ptr)
834/ 420 : 20 23 04 JSR SWPBUF
835/ 423 : 16 INPUT5: CALL 6 ; ENDCMD done
836/ 424 :
837/ 424 : ;------------------------------------------------------------------------------
838/ 424 : ; save input mode and swap buffers
839/ 424 : CD C2 SWPBUF: ST A, INPMOD ; store new input mode
840/ 426 : 85 F0 LD EA, TMPF0 ; swap buffer addresses
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 15 - 2024年05月30日 15時32分15秒
841/ 428 : 4E XCH P2, EA ; TMPF0 normally contains input buffer address
842/ 429 : 8D F0 ST EA, TMPF0
843/ 42B : 5C RET
844/ 42C :
845/ 42C : ;------------------------------------------------------------------------------
846/ 42C : ; several more commands
847/ 42C : 44 45 4C 41 59 CMDTB8: DB 'DELAY'
848/ 431 : 9A DB 0x9a ; to DELAY
849/ 432 : 49 4E 50 55 54 DB 'INPUT'
850/ 437 : 8F DB 0x8f ; to INPUT
851/ 438 : 50 52 49 4E 54 DB 'PRINT'
852/ 43D : 8B DB 0x8b ; to PRINT
853/ 43E : 50 52 DB 'PR'
854/ 440 : 88 DB 0x88 ; to PRINT
855/ 441 : 53 54 4F 50 DB 'STOP'
856/ 445 : 91 DB 0x91 ; to STOP
857/ 446 : 9D DB 0x9d ; default to ASSIGN
858/ 447 :
859/ 447 : ;------------------------------------------------------------------------------
860/ 447 : ; INPUT cmd
861/ 447 : 74 8A INPUT: BRA INPUT0 ; INPUT handler
862/ 449 :
863/ 449 : ;------------------------------------------------------------------------------
864/ 449 : ; PRINT cmd
865/ 449 : 24 D2 04 PRINT: JMP PRINT0 ; PRINT handler
866/ 44C :
867/ 44C : ;------------------------------------------------------------------------------
868/ 44C : ; DELAY cmd
869/ 44C : 10 DELAY: CALL 0 ; RELEXP get delay expression
870/ 44D : 15 CALL 5 ; APULL into EA
871/ 44E : A4 3F 00 LD T, =0x003f ; multiply with 63
872/ 451 : 2C MPY EA, T
873/ 452 : 0B LD EA, T ; into EA
874/ 453 : 20 DC 09 JSR DELAYC ; do delay
875/ 456 : 16 CALL 6 ; ENDCMD
876/ 457 : ;;; RET ; done
877/ 457 :
878/ 457 : ;------------------------------------------------------------------------------
879/ 457 : ; STOP cmd
880/ 457 : 24 A2 00 STOP: JMP MAINLP ; directly enter main loop
881/ 45A :
882/ 45A : ;------------------------------------------------------------------------------
883/ 45A : ; left hand side (LHS) operators for assigment
884/ 45A : 53 54 41 54 CMDTB4: DB 'STAT'
885/ 45E : 89 DB 0x89 ; to STATLH
886/ 45F : 40 DB '@'
887/ 460 : 92 DB 0x92 ; to ATLH
888/ 461 : 24 DB '$'
889/ 462 : B1 DB 0xb1 ; to DOLALH
890/ 463 : 9E DB 0x9e ; default case to ASSIG1
891/ 464 :
892/ 464 : ;------------------------------------------------------------------------------
893/ 464 : ; handle assignments
894/ 464 : 23 5A 04 ASSIGN: PLI P3, =CMDTB4
895/ 467 : 1B CALL 11 ; CMPTOK
896/ 468 :
897/ 468 : ;------------------------------------------------------------------------------
898/ 468 : ; STAT on left hand side
899/ 468 : 1C STATLH: CALL 12 ; EXPECT an equal symbol
900/ 469 : 3D DB '=' ;
AS V1.42 Beta [Bld 269] - Source File nibl3.asm - Page 16 - 2024年05月30日 15時32分15秒
901/ 46A : 67 DB 0x67 ; not found, goto SNERR
902/ 46B : 10 CALL 0 ; RELEXP get the right hand side
903/ 46C : 15 CALL 5 ; APULL into EA
904/ 46D : 07 LD S, A ; put into SR (only low byte)
905/ 46E : C4 01 LD A, =1 ; suppress potential INT that could
906/ 470 : CD E7 ST A, NOINT ; result from changing SA/SB
907/ 472 : 16 CALL 6 ; ENDCMD
908/ 473 :
909/ 473 : ;------------------------------------------------------------------------------
910/ 473 : ; @ on left hand side (POKE)
911/ 473 : 11 ATLH: CALL 1 ; FACTOR get non-boolean expression
912/ 474 : 1C CALL 12 ; EXPECT an equal symbol
913/ 475 : 3D DB '='
914/ 476 : 5B DB 0x5b ; not found, goto SNERR (syntax error)
915/ 477 : 10 CALL 0 ; RELEXP get right hand side
916/ 478 : 15 CALL 5 ; APULL into EA
917/ 479 : 09 LD T, EA ; into T
918/ 47A : 15 CALL 5 ; APULL get target address
919/ 47B : 57 PUSH P3 ; save P3
920/ 47C : 47 LD P3, EA ; into P3
921/ 47D : 0B LD EA, T ; RHS into EA
922/ 47E : CB 00 ST A, 0, P3 ; store low byte at address
923/ 480 : 5F POP P3
924/ 481 : 16 CALL 6 ; ENDCMD
925/ 482 : ;;; RET
926/ 482 :
927/ 482 : ;------------------------------------------------------------------------------
928/ 482 : ; default case for assign (VAR = expr)
929/ 482 : 20 75 05 ASSIG1: JSR GETVAR ; get a variable
930/ 485 : 4C DB 0x4c ; if not var, goto DOLAL4 (assume $xxxx)
931/ 486 : 1C CALL 12 ; EXPECT an equal symbol
932/ 487 : 3D DB '='
933/ 488 : 49 DB 0x49 ; not found, go to SNERR
934/ 489 : 10 CALL 0 ; RELEXP get right hand side
935/ 48A : 15 CALL 5 ; APULL into EA
936/ 48B : 09 LD T, EA ; into T
937/ 48C : 15 CALL 5 ; APULL get variable address
938/ 48D : 57 PUSH P3 ; save P3
939/ 48E : 47 LD P3, EA ; into P3
940/ 48F : 0B LD EA, T ; get RHS
941/ 490 : 8B 00 ST EA, 0, P3 ; store result into variable
942/ 492 : 5F POP P3 ; restore P3
943/ 493 : 16 CALL 6 ; ENDCMD done
944/ 494 :
945/ 494 : ;------------------------------------------------------------------------------
946/ 494 : ; $ on left hand side
947/ 494 : 11 DOLALH: CALL 1 ; FACTOR get target address
948/ 495 : 1C CALL 12 ; EXPECT an equal symbol
949/ 496 : 3D DB '='
950/ 497 : 3A DB 0x3a ; if not found, goto SNERR
951/ 498 : C2 00 LD A, 0, P2 ; get next char from program
952/ 49A : E4 22 XOR A, =0x22 ; is double quote?