-
Notifications
You must be signed in to change notification settings - Fork 78
/
c64disasm_en.txt
9615 lines (9117 loc) · 532 KB
/
c64disasm_en.txt
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
- Fully Commented Commodore 64 ROM Disassembly (English)
-
- CBMBASIC and KERNAL
-
- The comments have been taken from
- The almost completely commented C64 ROM disassembly. V1.01 Lee Davison 2012
-
- The ROM is the 901227-03 version ($FF80 = 3).
-
- Converted and formatted by Michael Steil <mist64@mac.com>
-
- Corrections (typos, formatting, content) welcome at:
- https://github.com/mist64/c64ref
-
------------------------------------------------------------
-
# This plain text file is formatted so that it can be automatically
# parsed in order to create cross-references etc.
# * Lines starting with "-" is top-level information. The first line
# is the title. Lines starting with "--" are separators.
# * Lines starting with "#" are internal comments.
# * Lines starting with ".," indicate code to be disassembled.
# * Lines starting with ".:" indicate bytes to be dumped.
# * Comments start at the 33rd column.
# * 32 leading spaces and "***" indicate a heading. (Please leave one
# line blank above every heading.)
# * Otherwise, 32 leading spaces indicate an overflow comment.
# The encoding is UTF-8.
*** start of the BASIC ROM
.:A000 94 E3 BASIC cold start entry point
.:A002 7B E3 BASIC warm start entry point
.:A004 43 42 4D 42 41 53 49 43 'cbmbasic', ROM name, unreferenced
*** action addresses for primary commands
these are called by pushing the address onto the stack and doing an RTS so the
actual address -1 needs to be pushed
.:A00C 30 A8 perform END $80
.:A00E 41 A7 perform FOR $81
.:A010 1D AD perform NEXT $82
.:A012 F7 A8 perform DATA $83
.:A014 A4 AB perform INPUT# $84
.:A016 BE AB perform INPUT $85
.:A018 80 B0 perform DIM $86
.:A01A 05 AC perform READ $87
.:A01C A4 A9 perform LET $88
.:A01E 9F A8 perform GOTO $89
.:A020 70 A8 perform RUN $8A
.:A022 27 A9 perform IF $8B
.:A024 1C A8 perform RESTORE $8C
.:A026 82 A8 perform GOSUB $8D
.:A028 D1 A8 perform RETURN $8E
.:A02A 3A A9 perform REM $8F
.:A02C 2E A8 perform STOP $90
.:A02E 4A A9 perform ON $91
.:A030 2C B8 perform WAIT $92
.:A032 67 E1 perform LOAD $93
.:A034 55 E1 perform SAVE $94
.:A036 64 E1 perform VERIFY $95
.:A038 B2 B3 perform DEF $96
.:A03A 23 B8 perform POKE $97
.:A03C 7F AA perform PRINT# $98
.:A03E 9F AA perform PRINT $99
.:A040 56 A8 perform CONT $9A
.:A042 9B A6 perform LIST $9B
.:A044 5D A6 perform CLR $9C
.:A046 85 AA perform CMD $9D
.:A048 29 E1 perform SYS $9E
.:A04A BD E1 perform OPEN $9F
.:A04C C6 E1 perform CLOSE $A0
.:A04E 7A AB perform GET $A1
.:A050 41 A6 perform NEW $A2
*** action addresses for functions
.:A052 39 BC perform SGN $B4
.:A054 CC BC perform INT $B5
.:A056 58 BC perform ABS $B6
.:A058 10 03 perform USR $B7
.:A05A 7D B3 perform FRE $B8
.:A05C 9E B3 perform POS $B9
.:A05E 71 BF perform SQR $BA
.:A060 97 E0 perform RND $BB
.:A062 EA B9 perform LOG $BC
.:A064 ED BF perform EXP $BD
.:A066 64 E2 perform COS $BE
.:A068 6B E2 perform SIN $BF
.:A06A B4 E2 perform TAN $C0
.:A06C 0E E3 perform ATN $C1
.:A06E 0D B8 perform PEEK $C2
.:A070 7C B7 perform LEN $C3
.:A072 65 B4 perform STR$ $C4
.:A074 AD B7 perform VAL $C5
.:A076 8B B7 perform ASC $C6
.:A078 EC B6 perform CHR$ $C7
.:A07A 00 B7 perform LEFT$ $C8
.:A07C 2C B7 perform RIGHT$ $C9
.:A07E 37 B7 perform MID$ $CA
*** precedence byte and action addresses for operators
like the primary commands these are called by pushing the address onto the stack
and doing an RTS, so again the actual address -1 needs to be pushed
.:A080 79 69 B8 +
.:A083 79 52 B8 -
.:A086 7B 2A BA *
.:A089 7B 11 BB /
.:A08C 7F 7A BF ^
.:A08F 50 E8 AF AND
.:A092 46 E5 AF OR
.:A095 7D B3 BF >
.:A098 5A D3 AE =
.:A09B 64 15 B0 <
*** BASIC keywords
each word has b7 set in it's last character as an end marker, even
the one character keywords such as "<" or "="
first are the primary command keywords, only these can start a statement
.:A09E 45 4E end
.:A0A0 C4 46 4F D2 4E 45 58 D4 for next
.:A0A8 44 41 54 C1 49 4E 50 55 data input#
.:A0B0 54 A3 49 4E 50 55 D4 44 input dim
.:A0B8 49 CD 52 45 41 C4 4C 45 read let
.:A0C0 D4 47 4F 54 CF 52 55 CE goto run
.:A0C8 49 C6 52 45 53 54 4F 52 if restore
.:A0D0 C5 47 4F 53 55 C2 52 45 gosub return
.:A0D8 54 55 52 CE 52 45 CD 53 rem stop
.:A0E0 54 4F D0 4F CE 57 41 49 on wait
.:A0E8 D4 4C 4F 41 C4 53 41 56 load save
.:A0F0 C5 56 45 52 49 46 D9 44 verify def
.:A0F8 45 C6 50 4F 4B C5 50 52 poke print#
.:A100 49 4E 54 A3 50 52 49 4E print
.:A108 D4 43 4F 4E D4 4C 49 53 cont list
.:A110 D4 43 4C D2 43 4D C4 53 clr cmd sys
.:A118 59 D3 4F 50 45 CE 43 4C open close
.:A120 4F 53 C5 47 45 D4 4E 45 get new
next are the secondary command keywords, these can not start a statement
.:A128 D7 54 41 42 A8 54 CF 46 tab( to
.:A130 CE 53 50 43 A8 54 48 45 spc( then
.:A138 CE 4E 4F D4 53 54 45 D0 not step
next are the operators
.:A140 AB AD AA AF DE 41 4E C4 + - * / ' and
.:A148 4F D2 BE BD BC or <=>
.:A14D 53 47 CE sgn
and finally the functions
.:A150 49 4E D4 41 42 D3 55 53 int abs usr
.:A158 D2 46 52 C5 50 4F D3 53 fre pos sqr
.:A160 51 D2 52 4E C4 4C 4F C7 rnd log
.:A168 45 58 D0 43 4F D3 53 49 exp cos sin
.:A170 CE 54 41 CE 41 54 CE 50 tan atn peek
.:A178 45 45 CB 4C 45 CE 53 54 len str$
.:A180 52 A4 56 41 CC 41 53 C3 val asc
.:A188 43 48 52 A4 4C 45 46 54 chr$ left$
.:A190 A4 52 49 47 48 54 A4 4D right$ mid$
lastly is GO, this is an add on so that GO TO, as well as GOTO, will work
.:A198 49 44 A4 47 CF go
.:A19D 00 end marker
*** BASIC error messages
.:A19E 54 4F 1 too many files
.:A1A0 4F 20 4D 41 4E 59 20 46
.:A1A8 49 4C 45 D3 46 49 4C 45 2 file open
.:A1B0 20 4F 50 45 CE 46 49 4C 3 file not open
.:A1B8 45 20 4E 4F 54 20 4F 50
.:A1C0 45 CE 46 49 4C 45 20 4E 4 file not found
.:A1C8 4F 54 20 46 4F 55 4E C4 5 device not present
.:A1D0 44 45 56 49 43 45 20 4E
.:A1D8 4F 54 20 50 52 45 53 45
.:A1E0 4E D4 4E 4F 54 20 49 4E 6 not input file
.:A1E8 50 55 54 20 46 49 4C C5
.:A1F0 4E 4F 54 20 4F 55 54 50 7 not output file
.:A1F8 55 54 20 46 49 4C C5 4D
.:A200 49 53 53 49 4E 47 20 46 8 missing filename
.:A208 49 4C 45 20 4E 41 4D C5
.:A210 49 4C 4C 45 47 41 4C 20 9 illegal device number
.:A218 44 45 56 49 43 45 20 4E
.:A220 55 4D 42 45 D2 4E 45 58 10 next without for
.:A228 54 20 57 49 54 48 4F 55
.:A230 54 20 46 4F D2 53 59 4E 11 syntax
.:A238 54 41 D8 52 45 54 55 52 12 return without gosub
.:A240 4E 20 57 49 54 48 4F 55
.:A248 54 20 47 4F 53 55 C2 4F 13 out of data
.:A250 55 54 20 4F 46 20 44 41
.:A258 54 C1 49 4C 4C 45 47 41 14 illegal quantity
.:A260 4C 20 51 55 41 4E 54 49
.:A268 54 D9 4F 56 45 52 46 4C 15 overflow
.:A270 4F D7 4F 55 54 20 4F 46 16 out of memory
.:A278 20 4D 45 4D 4F 52 D9 55 17 undef'd statement
.:A280 4E 44 45 46 27 44 20 53
.:A288 54 41 54 45 4D 45 4E D4
.:A290 42 41 44 20 53 55 42 53 18 bad subscript
.:A298 43 52 49 50 D4 52 45 44 19 redim'd array
.:A2A0 49 4D 27 44 20 41 52 52
.:A2A8 41 D9 44 49 56 49 53 49 20 division by zero
.:A2B0 4F 4E 20 42 59 20 5A 45
.:A2B8 52 CF 49 4C 4C 45 47 41 21 illegal direct
.:A2C0 4C 20 44 49 52 45 43 D4
.:A2C8 54 59 50 45 20 4D 49 53 22 type mismatch
.:A2D0 4D 41 54 43 C8 53 54 52 23 string too long
.:A2D8 49 4E 47 20 54 4F 4F 20
.:A2E0 4C 4F 4E C7 46 49 4C 45 24 file data
.:A2E8 20 44 41 54 C1 46 4F 52 25 formula too complex
.:A2F0 4D 55 4C 41 20 54 4F 4F
.:A2F8 20 43 4F 4D 50 4C 45 D8
.:A300 43 41 4E 27 54 20 43 4F 26 can't continue
.:A308 4E 54 49 4E 55 C5 55 4E 27 undef'd function
.:A310 44 45 46 27 44 20 46 55
.:A318 4E 43 54 49 4F CE 56 45 28 verify
.:A320 52 49 46 D9 4C 4F 41 C4 29 load
*** error message pointer table
.:A328 9E A1 AC A1 B5 A1 C2 A1
.:A330 D0 A1 E2 A1 F0 A1 FF A1
.:A338 10 A2 25 A2 35 A2 3B A2
.:A340 4F A2 5A A2 6A A2 72 A2
.:A348 7F A2 90 A2 9D A2 AA A2
.:A350 BA A2 C8 A2 D5 A2 E4 A2
.:A358 ED A2 00 A3 0E A3 1E A3
.:A360 24 A3 83 A3
*** BASIC messages
.:A364 0D 4F 4B 0D OK
.:A368 00 20 20 45 52 52 4F 52 ERROR
.:A370 00 20 49 4E 20 00 0D 0A IN
.:A378 52 45 41 44 59 2E 0D 0A READY.
.:A380 00 0D 0A 42 52 45 41 4B BREAK
.:A388 00
*** spare byte, not referenced
.:A389 A0 unused
*** search the stack for FOR or GOSUB activity
return Zb=1 if FOR variable found
.,A38A BA TSX copy stack pointer
.,A38B E8 INX +1 pass return address
.,A38C E8 INX +2 pass return address
.,A38D E8 INX +3 pass calling routine return address
.,A38E E8 INX +4 pass calling routine return address
.,A38F BD 01 01 LDA $0101,X get the token byte from the stack
.,A392 C9 81 CMP #$81 is it the FOR token
.,A394 D0 21 BNE $A3B7 if not FOR token just exit
it was the FOR token
.,A396 A5 4A LDA $4A get FOR/NEXT variable pointer high byte
.,A398 D0 0A BNE $A3A4 branch if not null
.,A39A BD 02 01 LDA $0102,X get FOR variable pointer low byte
.,A39D 85 49 STA $49 save FOR/NEXT variable pointer low byte
.,A39F BD 03 01 LDA $0103,X get FOR variable pointer high byte
.,A3A2 85 4A STA $4A save FOR/NEXT variable pointer high byte
.,A3A4 DD 03 01 CMP $0103,X compare variable pointer with stacked variable pointer
high byte
.,A3A7 D0 07 BNE $A3B0 branch if no match
.,A3A9 A5 49 LDA $49 get FOR/NEXT variable pointer low byte
.,A3AB DD 02 01 CMP $0102,X compare variable pointer with stacked variable pointer
low byte
.,A3AE F0 07 BEQ $A3B7 exit if match found
.,A3B0 8A TXA copy index
.,A3B1 18 CLC clear carry for add
.,A3B2 69 12 ADC #$12 add FOR stack use size
.,A3B4 AA TAX copy back to index
.,A3B5 D0 D8 BNE $A38F loop if not at start of stack
.,A3B7 60 RTS
*** open up a space in the memory, set the end of arrays
.,A3B8 20 08 A4 JSR $A408 check available memory, do out of memory error if no room
.,A3BB 85 31 STA $31 set end of arrays low byte
.,A3BD 84 32 STY $32 set end of arrays high byte
open up a space in the memory, don't set the array end
.,A3BF 38 SEC set carry for subtract
.,A3C0 A5 5A LDA $5A get block end low byte
.,A3C2 E5 5F SBC $5F subtract block start low byte
.,A3C4 85 22 STA $22 save MOD(block length/$100) byte
.,A3C6 A8 TAY copy MOD(block length/$100) byte to Y
.,A3C7 A5 5B LDA $5B get block end high byte
.,A3C9 E5 60 SBC $60 subtract block start high byte
.,A3CB AA TAX copy block length high byte to X
.,A3CC E8 INX +1 to allow for count=0 exit
.,A3CD 98 TYA copy block length low byte to A
.,A3CE F0 23 BEQ $A3F3 branch if length low byte=0
block is (X-1)*256+Y bytes, do the Y bytes first
.,A3D0 A5 5A LDA $5A get block end low byte
.,A3D2 38 SEC set carry for subtract
.,A3D3 E5 22 SBC $22 subtract MOD(block length/$100) byte
.,A3D5 85 5A STA $5A save corrected old block end low byte
.,A3D7 B0 03 BCS $A3DC branch if no underflow
.,A3D9 C6 5B DEC $5B else decrement block end high byte
.,A3DB 38 SEC set carry for subtract
.,A3DC A5 58 LDA $58 get destination end low byte
.,A3DE E5 22 SBC $22 subtract MOD(block length/$100) byte
.,A3E0 85 58 STA $58 save modified new block end low byte
.,A3E2 B0 08 BCS $A3EC branch if no underflow
.,A3E4 C6 59 DEC $59 else decrement block end high byte
.,A3E6 90 04 BCC $A3EC branch always
.,A3E8 B1 5A LDA ($5A),Y get byte from source
.,A3EA 91 58 STA ($58),Y copy byte to destination
.,A3EC 88 DEY decrement index
.,A3ED D0 F9 BNE $A3E8 loop until Y=0
now do Y=0 indexed byte
.,A3EF B1 5A LDA ($5A),Y get byte from source
.,A3F1 91 58 STA ($58),Y save byte to destination
.,A3F3 C6 5B DEC $5B decrement source pointer high byte
.,A3F5 C6 59 DEC $59 decrement destination pointer high byte
.,A3F7 CA DEX decrement block count
.,A3F8 D0 F2 BNE $A3EC loop until count = $0
.,A3FA 60 RTS
*** check room on stack for A bytes
if stack too deep do out of memory error
.,A3FB 0A ASL *2
.,A3FC 69 3E ADC #$3E need at least $3E bytes free
.,A3FE B0 35 BCS $A435 if overflow go do out of memory error then warm start
.,A400 85 22 STA $22 save result in temp byte
.,A402 BA TSX copy stack
.,A403 E4 22 CPX $22 compare new limit with stack
.,A405 90 2E BCC $A435 if stack < limit do out of memory error then warm start
.,A407 60 RTS
*** check available memory, do out of memory error if no room
.,A408 C4 34 CPY $34 compare with bottom of string space high byte
.,A40A 90 28 BCC $A434 if less then exit (is ok)
.,A40C D0 04 BNE $A412 skip next test if greater (tested <)
high byte was =, now do low byte
.,A40E C5 33 CMP $33 compare with bottom of string space low byte
.,A410 90 22 BCC $A434 if less then exit (is ok)
address is > string storage ptr (oops!)
.,A412 48 PHA push address low byte
.,A413 A2 09 LDX #$09 set index to save $57 to $60 inclusive
.,A415 98 TYA copy address high byte (to push on stack)
save misc numeric work area
.,A416 48 PHA push byte
.,A417 B5 57 LDA $57,X get byte from $57 to $60
.,A419 CA DEX decrement index
.,A41A 10 FA BPL $A416 loop until all done
.,A41C 20 26 B5 JSR $B526 do garbage collection routine
restore misc numeric work area
.,A41F A2 F7 LDX #$F7 set index to restore bytes
.,A421 68 PLA pop byte
.,A422 95 61 STA $61,X save byte to $57 to $60
.,A424 E8 INX increment index
.,A425 30 FA BMI $A421 loop while -ve
.,A427 68 PLA pop address high byte
.,A428 A8 TAY copy back to Y
.,A429 68 PLA pop address low byte
.,A42A C4 34 CPY $34 compare with bottom of string space high byte
.,A42C 90 06 BCC $A434 if less then exit (is ok)
.,A42E D0 05 BNE $A435 if greater do out of memory error then warm start
high byte was =, now do low byte
.,A430 C5 33 CMP $33 compare with bottom of string space low byte
.,A432 B0 01 BCS $A435 if >= do out of memory error then warm start
ok exit, carry clear
.,A434 60 RTS
*** do out of memory error then warm start
.,A435 A2 10 LDX #$10 error code $10, out of memory error
do error #X then warm start
.,A437 6C 00 03 JMP ($0300) do error message
*** do error #X then warm start, the error message vector is initialised to point here
.,A43A 8A TXA copy error number
.,A43B 0A ASL *2
.,A43C AA TAX copy to index
.,A43D BD 26 A3 LDA $A326,X get error message pointer low byte
.,A440 85 22 STA $22 save it
.,A442 BD 27 A3 LDA $A327,X get error message pointer high byte
.,A445 85 23 STA $23 save it
.,A447 20 CC FF JSR $FFCC close input and output channels
.,A44A A9 00 LDA #$00 clear A
.,A44C 85 13 STA $13 clear current I/O channel, flag default
.,A44E 20 D7 AA JSR $AAD7 print CR/LF
.,A451 20 45 AB JSR $AB45 print "?"
.,A454 A0 00 LDY #$00 clear index
.,A456 B1 22 LDA ($22),Y get byte from message
.,A458 48 PHA save status
.,A459 29 7F AND #$7F mask 0xxx xxxx, clear b7
.,A45B 20 47 AB JSR $AB47 output character
.,A45E C8 INY increment index
.,A45F 68 PLA restore status
.,A460 10 F4 BPL $A456 loop if character was not end marker
.,A462 20 7A A6 JSR $A67A flush BASIC stack and clear continue pointer
.,A465 A9 69 LDA #$69 set " ERROR" pointer low byte
.,A467 A0 A3 LDY #$A3 set " ERROR" pointer high byte
*** print string and do warm start, break entry
.,A469 20 1E AB JSR $AB1E print null terminated string
.,A46C A4 3A LDY $3A get current line number high byte
.,A46E C8 INY increment it
.,A46F F0 03 BEQ $A474 branch if was in immediate mode
.,A471 20 C2 BD JSR $BDC2 do " IN " line number message
*** do warm start
.,A474 A9 76 LDA #$76 set "READY." pointer low byte
.,A476 A0 A3 LDY #$A3 set "READY." pointer high byte
.,A478 20 1E AB JSR $AB1E print null terminated string
.,A47B A9 80 LDA #$80 set for control messages only
.,A47D 20 90 FF JSR $FF90 control kernal messages
.,A480 6C 02 03 JMP ($0302) do BASIC warm start
*** BASIC warm start, the warm start vector is initialised to point here
.,A483 20 60 A5 JSR $A560 call for BASIC input
.,A486 86 7A STX $7A save BASIC execute pointer low byte
.,A488 84 7B STY $7B save BASIC execute pointer high byte
.,A48A 20 73 00 JSR $0073 increment and scan memory
.,A48D AA TAX copy byte to set flags
.,A48E F0 F0 BEQ $A480 loop if no input
got to interpret the input line now ....
.,A490 A2 FF LDX #$FF current line high byte to -1, indicates immediate mode
.,A492 86 3A STX $3A set current line number high byte
.,A494 90 06 BCC $A49C if numeric character go handle new BASIC line
no line number .. immediate mode
.,A496 20 79 A5 JSR $A579 crunch keywords into BASIC tokens
.,A499 4C E1 A7 JMP $A7E1 go scan and interpret code
*** handle new BASIC line
.,A49C 20 6B A9 JSR $A96B get fixed-point number into temporary integer
.,A49F 20 79 A5 JSR $A579 crunch keywords into BASIC tokens
.,A4A2 84 0B STY $0B save index pointer to end of crunched line
.,A4A4 20 13 A6 JSR $A613 search BASIC for temporary integer line number
.,A4A7 90 44 BCC $A4ED if not found skip the line delete
line # already exists so delete it
.,A4A9 A0 01 LDY #$01 set index to next line pointer high byte
.,A4AB B1 5F LDA ($5F),Y get next line pointer high byte
.,A4AD 85 23 STA $23 save it
.,A4AF A5 2D LDA $2D get start of variables low byte
.,A4B1 85 22 STA $22 save it
.,A4B3 A5 60 LDA $60 get found line pointer high byte
.,A4B5 85 25 STA $25 save it
.,A4B7 A5 5F LDA $5F get found line pointer low byte
.,A4B9 88 DEY decrement index
.,A4BA F1 5F SBC ($5F),Y subtract next line pointer low byte
.,A4BC 18 CLC clear carry for add
.,A4BD 65 2D ADC $2D add start of variables low byte
.,A4BF 85 2D STA $2D set start of variables low byte
.,A4C1 85 24 STA $24 save destination pointer low byte
.,A4C3 A5 2E LDA $2E get start of variables high byte
.,A4C5 69 FF ADC #$FF -1 + carry
.,A4C7 85 2E STA $2E set start of variables high byte
.,A4C9 E5 60 SBC $60 subtract found line pointer high byte
.,A4CB AA TAX copy to block count
.,A4CC 38 SEC set carry for subtract
.,A4CD A5 5F LDA $5F get found line pointer low byte
.,A4CF E5 2D SBC $2D subtract start of variables low byte
.,A4D1 A8 TAY copy to bytes in first block count
.,A4D2 B0 03 BCS $A4D7 branch if no underflow
.,A4D4 E8 INX increment block count, correct for = 0 loop exit
.,A4D5 C6 25 DEC $25 decrement destination high byte
.,A4D7 18 CLC clear carry for add
.,A4D8 65 22 ADC $22 add source pointer low byte
.,A4DA 90 03 BCC $A4DF branch if no overflow
.,A4DC C6 23 DEC $23 else decrement source pointer high byte
.,A4DE 18 CLC clear carry
close up memory to delete old line
.,A4DF B1 22 LDA ($22),Y get byte from source
.,A4E1 91 24 STA ($24),Y copy to destination
.,A4E3 C8 INY increment index
.,A4E4 D0 F9 BNE $A4DF while <> 0 do this block
.,A4E6 E6 23 INC $23 increment source pointer high byte
.,A4E8 E6 25 INC $25 increment destination pointer high byte
.,A4EA CA DEX decrement block count
.,A4EB D0 F2 BNE $A4DF loop until all done
got new line in buffer and no existing same #
.,A4ED 20 59 A6 JSR $A659 reset execution to start, clear variables, flush stack
and return
.,A4F0 20 33 A5 JSR $A533 rebuild BASIC line chaining
.,A4F3 AD 00 02 LDA $0200 get first byte from buffer
.,A4F6 F0 88 BEQ $A480 if no line go do BASIC warm start
else insert line into memory
.,A4F8 18 CLC clear carry for add
.,A4F9 A5 2D LDA $2D get start of variables low byte
.,A4FB 85 5A STA $5A save as source end pointer low byte
.,A4FD 65 0B ADC $0B add index pointer to end of crunched line
.,A4FF 85 58 STA $58 save as destination end pointer low byte
.,A501 A4 2E LDY $2E get start of variables high byte
.,A503 84 5B STY $5B save as source end pointer high byte
.,A505 90 01 BCC $A508 branch if no carry to high byte
.,A507 C8 INY else increment high byte
.,A508 84 59 STY $59 save as destination end pointer high byte
.,A50A 20 B8 A3 JSR $A3B8 open up space in memory
most of what remains to do is copy the crunched line into the space opened up in memory,
however, before the crunched line comes the next line pointer and the line number. the
line number is retrieved from the temporary integer and stored in memory, this
overwrites the bottom two bytes on the stack. next the line is copied and the next line
pointer is filled with whatever was in two bytes above the line number in the stack.
this is ok because the line pointer gets fixed in the line chain re-build.
.,A50D A5 14 LDA $14 get line number low byte
.,A50F A4 15 LDY $15 get line number high byte
.,A511 8D FE 01 STA $01FE save line number low byte before crunched line
.,A514 8C FF 01 STY $01FF save line number high byte before crunched line
.,A517 A5 31 LDA $31 get end of arrays low byte
.,A519 A4 32 LDY $32 get end of arrays high byte
.,A51B 85 2D STA $2D set start of variables low byte
.,A51D 84 2E STY $2E set start of variables high byte
.,A51F A4 0B LDY $0B get index to end of crunched line
.,A521 88 DEY -1
.,A522 B9 FC 01 LDA $01FC,Y get byte from crunched line
.,A525 91 5F STA ($5F),Y save byte to memory
.,A527 88 DEY decrement index
.,A528 10 F8 BPL $A522 loop while more to do
reset execution, clear variables, flush stack, rebuild BASIC chain and do warm start
.,A52A 20 59 A6 JSR $A659 reset execution to start, clear variables and flush stack
.,A52D 20 33 A5 JSR $A533 rebuild BASIC line chaining
.,A530 4C 80 A4 JMP $A480 go do BASIC warm start
*** rebuild BASIC line chaining
.,A533 A5 2B LDA $2B get start of memory low byte
.,A535 A4 2C LDY $2C get start of memory high byte
.,A537 85 22 STA $22 set line start pointer low byte
.,A539 84 23 STY $23 set line start pointer high byte
.,A53B 18 CLC clear carry for add
.,A53C A0 01 LDY #$01 set index to pointer to next line high byte
.,A53E B1 22 LDA ($22),Y get pointer to next line high byte
.,A540 F0 1D BEQ $A55F exit if null, [EOT]
.,A542 A0 04 LDY #$04 point to first code byte of line
there is always 1 byte + [EOL] as null entries are deleted
.,A544 C8 INY next code byte
.,A545 B1 22 LDA ($22),Y get byte
.,A547 D0 FB BNE $A544 loop if not [EOL]
.,A549 C8 INY point to byte past [EOL], start of next line
.,A54A 98 TYA copy it
.,A54B 65 22 ADC $22 add line start pointer low byte
.,A54D AA TAX copy to X
.,A54E A0 00 LDY #$00 clear index, point to this line's next line pointer
.,A550 91 22 STA ($22),Y set next line pointer low byte
.,A552 A5 23 LDA $23 get line start pointer high byte
.,A554 69 00 ADC #$00 add any overflow
.,A556 C8 INY increment index to high byte
.,A557 91 22 STA ($22),Y set next line pointer high byte
.,A559 86 22 STX $22 set line start pointer low byte
.,A55B 85 23 STA $23 set line start pointer high byte
.,A55D 90 DD BCC $A53C go do next line, branch always
.,A55F 60 RTS
call for BASIC input
.,A560 A2 00 LDX #$00 set channel $00, keyboard
.,A562 20 12 E1 JSR $E112 input character from channel with error check
.,A565 C9 0D CMP #$0D compare with [CR]
.,A567 F0 0D BEQ $A576 if [CR] set XY to $200 - 1, print [CR] and exit
character was not [CR]
.,A569 9D 00 02 STA $0200,X save character to buffer
.,A56C E8 INX increment buffer index
.,A56D E0 59 CPX #$59 compare with max+1
.,A56F 90 F1 BCC $A562 branch if < max+1
.,A571 A2 17 LDX #$17 error $17, string too long error
.,A573 4C 37 A4 JMP $A437 do error #X then warm start
.,A576 4C CA AA JMP $AACA set XY to $200 - 1 and print [CR]
*** crunch BASIC tokens vector
.,A579 6C 04 03 JMP ($0304) do crunch BASIC tokens
*** crunch BASIC tokens, the crunch BASIC tokens vector is initialised to point here
.,A57C A6 7A LDX $7A get BASIC execute pointer low byte
.,A57E A0 04 LDY #$04 set save index
.,A580 84 0F STY $0F clear open quote/DATA flag
.,A582 BD 00 02 LDA $0200,X get a byte from the input buffer
.,A585 10 07 BPL $A58E if b7 clear go do crunching
.,A587 C9 FF CMP #$FF compare with the token for PI, this toke is input
directly from the keyboard as the PI character
.,A589 F0 3E BEQ $A5C9 if PI save byte then continue crunching
this is the bit of code that stops you being able to enter
some keywords as just single shifted characters. If this
dropped through you would be able to enter GOTO as just
[SHIFT]G
.,A58B E8 INX increment read index
.,A58C D0 F4 BNE $A582 loop if more to do, branch always
.,A58E C9 20 CMP #$20 compare with [SPACE]
.,A590 F0 37 BEQ $A5C9 if [SPACE] save byte then continue crunching
.,A592 85 08 STA $08 save buffer byte as search character
.,A594 C9 22 CMP #$22 compare with quote character
.,A596 F0 56 BEQ $A5EE if quote go copy quoted string
.,A598 24 0F BIT $0F get open quote/DATA token flag
.,A59A 70 2D BVS $A5C9 branch if b6 of Oquote set, was DATA
go save byte then continue crunching
.,A59C C9 3F CMP #$3F compare with "?" character
.,A59E D0 04 BNE $A5A4 if not "?" continue crunching
.,A5A0 A9 99 LDA #$99 else the keyword token is $99, PRINT
.,A5A2 D0 25 BNE $A5C9 go save byte then continue crunching, branch always
.,A5A4 C9 30 CMP #$30 compare with "0"
.,A5A6 90 04 BCC $A5AC branch if <, continue crunching
.,A5A8 C9 3C CMP #$3C compare with "<"
.,A5AA 90 1D BCC $A5C9 if <, 0123456789:; go save byte then continue crunching
gets here with next character not numeric, ";" or ":"
.,A5AC 84 71 STY $71 copy save index
.,A5AE A0 00 LDY #$00 clear table pointer
.,A5B0 84 0B STY $0B clear word index
.,A5B2 88 DEY adjust for pre increment loop
.,A5B3 86 7A STX $7A save BASIC execute pointer low byte, buffer index
.,A5B5 CA DEX adjust for pre increment loop
.,A5B6 C8 INY next table byte
.,A5B7 E8 INX next buffer byte
.,A5B8 BD 00 02 LDA $0200,X get byte from input buffer
.,A5BB 38 SEC set carry for subtract
.,A5BC F9 9E A0 SBC $A09E,Y subtract table byte
.,A5BF F0 F5 BEQ $A5B6 go compare next if match
.,A5C1 C9 80 CMP #$80 was it end marker match ?
.,A5C3 D0 30 BNE $A5F5 branch if not, not found keyword
actually this works even if the input buffer byte is the
end marker, i.e. a shifted character. As you can't enter
any keywords as a single shifted character, see above,
you can enter keywords in shorthand by shifting any
character after the first. so RETURN can be entered as
R[SHIFT]E, RE[SHIFT]T, RET[SHIFT]U or RETU[SHIFT]R.
RETUR[SHIFT]N however will not work because the [SHIFT]N
will match the RETURN end marker so the routine will try
to match the next character.
else found keyword
.,A5C5 05 0B ORA $0B OR with word index, +$80 in A makes token
.,A5C7 A4 71 LDY $71 restore save index
save byte then continue crunching
.,A5C9 E8 INX increment buffer read index
.,A5CA C8 INY increment save index
.,A5CB 99 FB 01 STA $01FB,Y save byte to output
.,A5CE B9 FB 01 LDA $01FB,Y get byte from output, set flags
.,A5D1 F0 36 BEQ $A609 branch if was null [EOL]
A holds the token here
.,A5D3 38 SEC set carry for subtract
.,A5D4 E9 3A SBC #$3A subtract ":"
.,A5D6 F0 04 BEQ $A5DC branch if it was (is now $00)
A now holds token-':'
.,A5D8 C9 49 CMP #$49 compare with the token for DATA-':'
.,A5DA D0 02 BNE $A5DE if not DATA go try REM
token was : or DATA
.,A5DC 85 0F STA $0F save the token-$3A
.,A5DE 38 SEC set carry for subtract
.,A5DF E9 55 SBC #$55 subtract the token for REM-':'
.,A5E1 D0 9F BNE $A582 if wasn't REM crunch next bit of line
.,A5E3 85 08 STA $08 else was REM so set search for [EOL]
loop for "..." etc.
.,A5E5 BD 00 02 LDA $0200,X get byte from input buffer
.,A5E8 F0 DF BEQ $A5C9 if null [EOL] save byte then continue crunching
.,A5EA C5 08 CMP $08 compare with stored character
.,A5EC F0 DB BEQ $A5C9 if match save byte then continue crunching
.,A5EE C8 INY increment save index
.,A5EF 99 FB 01 STA $01FB,Y save byte to output
.,A5F2 E8 INX increment buffer index
.,A5F3 D0 F0 BNE $A5E5 loop while <> 0, should never reach 0
not found keyword this go
.,A5F5 A6 7A LDX $7A restore BASIC execute pointer low byte
.,A5F7 E6 0B INC $0B increment word index (next word)
now find end of this word in the table
.,A5F9 C8 INY increment table index
.,A5FA B9 9D A0 LDA $A09D,Y get table byte
.,A5FD 10 FA BPL $A5F9 loop if not end of word yet
.,A5FF B9 9E A0 LDA $A09E,Y get byte from keyword table
.,A602 D0 B4 BNE $A5B8 go test next word if not zero byte, end of table
reached end of table with no match
.,A604 BD 00 02 LDA $0200,X restore byte from input buffer
.,A607 10 BE BPL $A5C7 branch always, all unmatched bytes in the buffer are
$00 to $7F, go save byte in output and continue crunching
reached [EOL]
.,A609 99 FD 01 STA $01FD,Y save [EOL]
.,A60C C6 7B DEC $7B decrement BASIC execute pointer high byte
.,A60E A9 FF LDA #$FF point to start of buffer-1
.,A610 85 7A STA $7A set BASIC execute pointer low byte
.,A612 60 RTS
*** search BASIC for temporary integer line number
.,A613 A5 2B LDA $2B get start of memory low byte
.,A615 A6 2C LDX $2C get start of memory high byte
*** search Basic for temp integer line number from AX
returns carry set if found
.,A617 A0 01 LDY #$01 set index to next line pointer high byte
.,A619 85 5F STA $5F save low byte as current
.,A61B 86 60 STX $60 save high byte as current
.,A61D B1 5F LDA ($5F),Y get next line pointer high byte from address
.,A61F F0 1F BEQ $A640 pointer was zero so done, exit
.,A621 C8 INY increment index ...
.,A622 C8 INY ... to line # high byte
.,A623 A5 15 LDA $15 get temporary integer high byte
.,A625 D1 5F CMP ($5F),Y compare with line # high byte
.,A627 90 18 BCC $A641 exit if temp < this line, target line passed
.,A629 F0 03 BEQ $A62E go check low byte if =
.,A62B 88 DEY else decrement index
.,A62C D0 09 BNE $A637 branch always
.,A62E A5 14 LDA $14 get temporary integer low byte
.,A630 88 DEY decrement index to line # low byte
.,A631 D1 5F CMP ($5F),Y compare with line # low byte
.,A633 90 0C BCC $A641 exit if temp < this line, target line passed
.,A635 F0 0A BEQ $A641 exit if temp = (found line#)
not quite there yet
.,A637 88 DEY decrement index to next line pointer high byte
.,A638 B1 5F LDA ($5F),Y get next line pointer high byte
.,A63A AA TAX copy to X
.,A63B 88 DEY decrement index to next line pointer low byte
.,A63C B1 5F LDA ($5F),Y get next line pointer low byte
.,A63E B0 D7 BCS $A617 go search for line # in temporary integer
from AX, carry always set
.,A640 18 CLC clear found flag
.,A641 60 RTS
*** perform NEW
.,A642 D0 FD BNE $A641 exit if following byte to allow syntax error
.,A644 A9 00 LDA #$00 clear A
.,A646 A8 TAY clear index
.,A647 91 2B STA ($2B),Y clear pointer to next line low byte
.,A649 C8 INY increment index
.,A64A 91 2B STA ($2B),Y clear pointer to next line high byte, erase program
.,A64C A5 2B LDA $2B get start of memory low byte
.,A64E 18 CLC clear carry for add
.,A64F 69 02 ADC #$02 add null program length
.,A651 85 2D STA $2D set start of variables low byte
.,A653 A5 2C LDA $2C get start of memory high byte
.,A655 69 00 ADC #$00 add carry
.,A657 85 2E STA $2E set start of variables high byte
*** reset execute pointer and do CLR
.,A659 20 8E A6 JSR $A68E set BASIC execute pointer to start of memory - 1
.,A65C A9 00 LDA #$00 set Zb for CLR entry
*** perform CLR
.,A65E D0 2D BNE $A68D exit if following byte to allow syntax error
.,A660 20 E7 FF JSR $FFE7 close all channels and files
.,A663 A5 37 LDA $37 get end of memory low byte
.,A665 A4 38 LDY $38 get end of memory high byte
.,A667 85 33 STA $33 set bottom of string space low byte, clear strings
.,A669 84 34 STY $34 set bottom of string space high byte
.,A66B A5 2D LDA $2D get start of variables low byte
.,A66D A4 2E LDY $2E get start of variables high byte
.,A66F 85 2F STA $2F set end of variables low byte, clear variables
.,A671 84 30 STY $30 set end of variables high byte
.,A673 85 31 STA $31 set end of arrays low byte, clear arrays
.,A675 84 32 STY $32 set end of arrays high byte
*** do RESTORE and clear stack
.,A677 20 1D A8 JSR $A81D perform RESTORE
*** flush BASIC stack and clear the continue pointer
.,A67A A2 19 LDX #$19 get the descriptor stack start
.,A67C 86 16 STX $16 set the descriptor stack pointer
.,A67E 68 PLA pull the return address low byte
.,A67F A8 TAY copy it
.,A680 68 PLA pull the return address high byte
.,A681 A2 FA LDX #$FA set the cleared stack pointer
.,A683 9A TXS set the stack
.,A684 48 PHA push the return address high byte
.,A685 98 TYA restore the return address low byte
.,A686 48 PHA push the return address low byte
.,A687 A9 00 LDA #$00 clear A
.,A689 85 3E STA $3E clear the continue pointer high byte
.,A68B 85 10 STA $10 clear the subscript/FNX flag
.,A68D 60 RTS
*** set BASIC execute pointer to start of memory - 1
.,A68E 18 CLC clear carry for add
.,A68F A5 2B LDA $2B get start of memory low byte
.,A691 69 FF ADC #$FF add -1 low byte
.,A693 85 7A STA $7A set BASIC execute pointer low byte
.,A695 A5 2C LDA $2C get start of memory high byte
.,A697 69 FF ADC #$FF add -1 high byte
.,A699 85 7B STA $7B save BASIC execute pointer high byte
.,A69B 60 RTS
*** perform LIST
.,A69C 90 06 BCC $A6A4 branch if next character not token (LIST n...)
.,A69E F0 04 BEQ $A6A4 branch if next character [NULL] (LIST)
.,A6A0 C9 AB CMP #$AB compare with token for -
.,A6A2 D0 E9 BNE $A68D exit if not - (LIST -m)
LIST [[n][-m]]
this bit sets the n , if present, as the start and end
.,A6A4 20 6B A9 JSR $A96B get fixed-point number into temporary integer
.,A6A7 20 13 A6 JSR $A613 search BASIC for temporary integer line number
.,A6AA 20 79 00 JSR $0079 scan memory
.,A6AD F0 0C BEQ $A6BB branch if no more chrs
this bit checks the - is present
.,A6AF C9 AB CMP #$AB compare with token for -
.,A6B1 D0 8E BNE $A641 return if not "-" (will be SN error)
LIST [n]-m
the - was there so set m as the end value
.,A6B3 20 73 00 JSR $0073 increment and scan memory
.,A6B6 20 6B A9 JSR $A96B get fixed-point number into temporary integer
.,A6B9 D0 86 BNE $A641 exit if not ok
.,A6BB 68 PLA dump return address low byte, exit via warm start
.,A6BC 68 PLA dump return address high byte
.,A6BD A5 14 LDA $14 get temporary integer low byte
.,A6BF 05 15 ORA $15 OR temporary integer high byte
.,A6C1 D0 06 BNE $A6C9 branch if start set
.,A6C3 A9 FF LDA #$FF set for -1
.,A6C5 85 14 STA $14 set temporary integer low byte
.,A6C7 85 15 STA $15 set temporary integer high byte
.,A6C9 A0 01 LDY #$01 set index for line
.,A6CB 84 0F STY $0F clear open quote flag
.,A6CD B1 5F LDA ($5F),Y get next line pointer high byte
.,A6CF F0 43 BEQ $A714 if null all done so exit
.,A6D1 20 2C A8 JSR $A82C do CRTL-C check vector
.,A6D4 20 D7 AA JSR $AAD7 print CR/LF
.,A6D7 C8 INY increment index for line
.,A6D8 B1 5F LDA ($5F),Y get line number low byte
.,A6DA AA TAX copy to X
.,A6DB C8 INY increment index
.,A6DC B1 5F LDA ($5F),Y get line number high byte
.,A6DE C5 15 CMP $15 compare with temporary integer high byte
.,A6E0 D0 04 BNE $A6E6 branch if no high byte match
.,A6E2 E4 14 CPX $14 compare with temporary integer low byte
.,A6E4 F0 02 BEQ $A6E8 branch if = last line to do, < will pass next branch
else
.,A6E6 B0 2C BCS $A714 if greater all done so exit
.,A6E8 84 49 STY $49 save index for line
.,A6EA 20 CD BD JSR $BDCD print XA as unsigned integer
.,A6ED A9 20 LDA #$20 space is the next character
.,A6EF A4 49 LDY $49 get index for line
.,A6F1 29 7F AND #$7F mask top out bit of character
.,A6F3 20 47 AB JSR $AB47 go print the character
.,A6F6 C9 22 CMP #$22 was it " character
.,A6F8 D0 06 BNE $A700 if not skip the quote handle
we are either entering or leaving a pair of quotes
.,A6FA A5 0F LDA $0F get open quote flag
.,A6FC 49 FF EOR #$FF toggle it
.,A6FE 85 0F STA $0F save it back
.,A700 C8 INY increment index
.,A701 F0 11 BEQ $A714 line too long so just bail out and do a warm start
.,A703 B1 5F LDA ($5F),Y get next byte
.,A705 D0 10 BNE $A717 if not [EOL] (go print character)
was [EOL]
.,A707 A8 TAY else clear index
.,A708 B1 5F LDA ($5F),Y get next line pointer low byte
.,A70A AA TAX copy to X
.,A70B C8 INY increment index
.,A70C B1 5F LDA ($5F),Y get next line pointer high byte
.,A70E 86 5F STX $5F set pointer to line low byte
.,A710 85 60 STA $60 set pointer to line high byte
.,A712 D0 B5 BNE $A6C9 go do next line if not [EOT]
else ...
.,A714 4C 86 E3 JMP $E386 do warm start
.,A717 6C 06 03 JMP ($0306) do uncrunch BASIC tokens
*** uncrunch BASIC tokens, the uncrunch BASIC tokens vector is initialised to point here
.,A71A 10 D7 BPL $A6F3 just go print it if not token byte
else was token byte so uncrunch it
.,A71C C9 FF CMP #$FF compare with the token for PI. in this case the token
is the same as the PI character so it just needs printing
.,A71E F0 D3 BEQ $A6F3 just print it if so
.,A720 24 0F BIT $0F test the open quote flag
.,A722 30 CF BMI $A6F3 just go print character if open quote set
.,A724 38 SEC else set carry for subtract
.,A725 E9 7F SBC #$7F reduce token range to 1 to whatever
.,A727 AA TAX copy token # to X
.,A728 84 49 STY $49 save index for line
.,A72A A0 FF LDY #$FF start from -1, adjust for pre increment
.,A72C CA DEX decrement token #
.,A72D F0 08 BEQ $A737 if now found go do printing
.,A72F C8 INY else increment index
.,A730 B9 9E A0 LDA $A09E,Y get byte from keyword table
.,A733 10 FA BPL $A72F loop until keyword end marker
.,A735 30 F5 BMI $A72C go test if this is required keyword, branch always
found keyword, it's the next one
.,A737 C8 INY increment keyword table index
.,A738 B9 9E A0 LDA $A09E,Y get byte from table
.,A73B 30 B2 BMI $A6EF go restore index, mask byte and print if
byte was end marker
.,A73D 20 47 AB JSR $AB47 else go print the character
.,A740 D0 F5 BNE $A737 go get next character, branch always
*** perform FOR
.,A742 A9 80 LDA #$80 set FNX
.,A744 85 10 STA $10 set subscript/FNX flag
.,A746 20 A5 A9 JSR $A9A5 perform LET
.,A749 20 8A A3 JSR $A38A search the stack for FOR or GOSUB activity
.,A74C D0 05 BNE $A753 branch if FOR, this variable, not found
FOR, this variable, was found so first we dump the old one
.,A74E 8A TXA copy index
.,A74F 69 0F ADC #$0F add FOR structure size-2
.,A751 AA TAX copy to index
.,A752 9A TXS set stack (dump FOR structure (-2 bytes))
.,A753 68 PLA pull return address
.,A754 68 PLA pull return address
.,A755 A9 09 LDA #$09 we need 18d bytes !
.,A757 20 FB A3 JSR $A3FB check room on stack for 2*A bytes
.,A75A 20 06 A9 JSR $A906 scan for next BASIC statement ([:] or [EOL])
.,A75D 18 CLC clear carry for add
.,A75E 98 TYA copy index to A
.,A75F 65 7A ADC $7A add BASIC execute pointer low byte
.,A761 48 PHA push onto stack
.,A762 A5 7B LDA $7B get BASIC execute pointer high byte
.,A764 69 00 ADC #$00 add carry
.,A766 48 PHA push onto stack
.,A767 A5 3A LDA $3A get current line number high byte
.,A769 48 PHA push onto stack
.,A76A A5 39 LDA $39 get current line number low byte
.,A76C 48 PHA push onto stack
.,A76D A9 A4 LDA #$A4 set "TO" token
.,A76F 20 FF AE JSR $AEFF scan for CHR$(A), else do syntax error then warm start
.,A772 20 8D AD JSR $AD8D check if source is numeric, else do type mismatch
.,A775 20 8A AD JSR $AD8A evaluate expression and check is numeric, else do
type mismatch
.,A778 A5 66 LDA $66 get FAC1 sign (b7)
.,A77A 09 7F ORA #$7F set all non sign bits
.,A77C 25 62 AND $62 and FAC1 mantissa 1
.,A77E 85 62 STA $62 save FAC1 mantissa 1
.,A780 A9 8B LDA #$8B set return address low byte
.,A782 A0 A7 LDY #$A7 set return address high byte
.,A784 85 22 STA $22 save return address low byte
.,A786 84 23 STY $23 save return address high byte
.,A788 4C 43 AE JMP $AE43 round FAC1 and put on stack, returns to next instruction
.,A78B A9 BC LDA #$BC set 1 pointer low address, default step size
.,A78D A0 B9 LDY #$B9 set 1 pointer high address
.,A78F 20 A2 BB JSR $BBA2 unpack memory (AY) into FAC1
.,A792 20 79 00 JSR $0079 scan memory
.,A795 C9 A9 CMP #$A9 compare with STEP token
.,A797 D0 06 BNE $A79F if not "STEP" continue
was step so ....
.,A799 20 73 00 JSR $0073 increment and scan memory
.,A79C 20 8A AD JSR $AD8A evaluate expression and check is numeric, else do
type mismatch
.,A79F 20 2B BC JSR $BC2B get FAC1 sign, return A = $FF -ve, A = $01 +ve
.,A7A2 20 38 AE JSR $AE38 push sign, round FAC1 and put on stack
.,A7A5 A5 4A LDA $4A get FOR/NEXT variable pointer high byte
.,A7A7 48 PHA push on stack
.,A7A8 A5 49 LDA $49 get FOR/NEXT variable pointer low byte
.,A7AA 48 PHA push on stack
.,A7AB A9 81 LDA #$81 get FOR token
.,A7AD 48 PHA push on stack
*** interpreter inner loop
.,A7AE 20 2C A8 JSR $A82C do CRTL-C check vector
.,A7B1 A5 7A LDA $7A get the BASIC execute pointer low byte
.,A7B3 A4 7B LDY $7B get the BASIC execute pointer high byte
.,A7B5 C0 02 CPY #$02 compare the high byte with $02xx
.,A7B7 EA NOP unused byte
.,A7B8 F0 04 BEQ $A7BE if immediate mode skip the continue pointer save
.,A7BA 85 3D STA $3D save the continue pointer low byte
.,A7BC 84 3E STY $3E save the continue pointer high byte
.,A7BE A0 00 LDY #$00 clear the index
.,A7C0 B1 7A LDA ($7A),Y get a BASIC byte
.,A7C2 D0 43 BNE $A807 if not [EOL] go test for ":"
.,A7C4 A0 02 LDY #$02 else set the index
.,A7C6 B1 7A LDA ($7A),Y get next line pointer high byte
.,A7C8 18 CLC clear carry for no "BREAK" message
.,A7C9 D0 03 BNE $A7CE branch if not end of program
.,A7CB 4C 4B A8 JMP $A84B else go to immediate mode,was immediate or [EOT] marker
.,A7CE C8 INY increment index
.,A7CF B1 7A LDA ($7A),Y get line number low byte
.,A7D1 85 39 STA $39 save current line number low byte
.,A7D3 C8 INY increment index
.,A7D4 B1 7A LDA ($7A),Y get line # high byte
.,A7D6 85 3A STA $3A save current line number high byte
.,A7D8 98 TYA A now = 4
.,A7D9 65 7A ADC $7A add BASIC execute pointer low byte, now points to code
.,A7DB 85 7A STA $7A save BASIC execute pointer low byte
.,A7DD 90 02 BCC $A7E1 branch if no overflow
.,A7DF E6 7B INC $7B else increment BASIC execute pointer high byte
.,A7E1 6C 08 03 JMP ($0308) do start new BASIC code
*** start new BASIC code, the start new BASIC code vector is initialised to point here
.,A7E4 20 73 00 JSR $0073 increment and scan memory
.,A7E7 20 ED A7 JSR $A7ED go interpret BASIC code from BASIC execute pointer
.,A7EA 4C AE A7 JMP $A7AE loop
*** go interpret BASIC code from BASIC execute pointer
.,A7ED F0 3C BEQ $A82B if the first byte is null just exit
.,A7EF E9 80 SBC #$80 normalise the token
.,A7F1 90 11 BCC $A804 if wasn't token go do LET
.,A7F3 C9 23 CMP #$23 compare with token for TAB(-$80
.,A7F5 B0 17 BCS $A80E branch if >= TAB(
.,A7F7 0A ASL *2 bytes per vector
.,A7F8 A8 TAY copy to index
.,A7F9 B9 0D A0 LDA $A00D,Y get vector high byte
.,A7FC 48 PHA push on stack
.,A7FD B9 0C A0 LDA $A00C,Y get vector low byte
.,A800 48 PHA push on stack
.,A801 4C 73 00 JMP $0073 increment and scan memory and return. the return in
this case calls the command code, the return from
that will eventually return to the interpreter inner
loop above
.,A804 4C A5 A9 JMP $A9A5 perform LET
was not [EOL]
.,A807 C9 3A CMP #$3A comapre with ":"
.,A809 F0 D6 BEQ $A7E1 if ":" go execute new code
else ...
.,A80B 4C 08 AF JMP $AF08 do syntax error then warm start
token was >= TAB(
.,A80E C9 4B CMP #$4B compare with the token for GO
.,A810 D0 F9 BNE $A80B if not "GO" do syntax error then warm start
else was "GO"
.,A812 20 73 00 JSR $0073 increment and scan memory
.,A815 A9 A4 LDA #$A4 set "TO" token
.,A817 20 FF AE JSR $AEFF scan for CHR$(A), else do syntax error then warm start
.,A81A 4C A0 A8 JMP $A8A0 perform GOTO
*** perform RESTORE
.,A81D 38 SEC set carry for subtract
.,A81E A5 2B LDA $2B get start of memory low byte
.,A820 E9 01 SBC #$01 -1
.,A822 A4 2C LDY $2C get start of memory high byte
.,A824 B0 01 BCS $A827 branch if no rollunder
.,A826 88 DEY else decrement high byte
.,A827 85 41 STA $41 set DATA pointer low byte
.,A829 84 42 STY $42 set DATA pointer high byte
.,A82B 60 RTS
*** do CRTL-C check vector
.,A82C 20 E1 FF JSR $FFE1 scan stop key
*** perform STOP
.,A82F B0 01 BCS $A832 if carry set do BREAK instead of just END
*** perform END
.,A831 18 CLC clear carry
.,A832 D0 3C BNE $A870 return if wasn't CTRL-C
.,A834 A5 7A LDA $7A get BASIC execute pointer low byte
.,A836 A4 7B LDY $7B get BASIC execute pointer high byte
.,A838 A6 3A LDX $3A get current line number high byte