-
Notifications
You must be signed in to change notification settings - Fork 4
/
basic.dasm16
3370 lines (3155 loc) · 103 KB
/
basic.dasm16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
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
;
; Main BASIC interpreter
;
; requires math.dasm16
;
; TODO: add list of kernal dependencies.
;
;
:RAM03
:ADRAY1 DAT BLANK
:RAM05
:ADRAY2 DAT BLANK
:RAM07
:CHARAC DAT BLANK
:RAM08
:ENDCHR DAT BLANK
:RAM09 ; Column position of cursor before last TAB or SPC
:TRMPOS DAT BLANK
:RAM0B
:COUNT DAT BLANK
:RAM0C
:DIMFLG DAT BLANK
; todo: standardize the value stored here.
:RAM0D
:VALTYP DAT BLANK
:RAM0E
:INTFLG DAT BLANK
:RAM0F ; Flag for LIST, Garbage Collection, and Program Tokenization
:GARBFL DAT 0
:RAM10 ; Flag: Subscript Reference to an Array or User-Defined Function Call
:SUBFLG DAT 0
:RAM11 ; Flag: is data input to GET, READ, or INPUT?
:INPFLG DAT BLANK
.DEFINE INF_READ 0x98
.DEFINE INF_GET 0x40
.DEFINE INF_INPUT 0x0
:RAM12
:TANSGN DAT BLANK
:RAM13 ; Current logical file number
:CHANNL DAT 0
:RAM14 ; Line Number for LIST/GOTO, memory address for PEEK/POKE/SYS
:LINNUM DAT 0
:RAM16 ; Pointer to the next available space in the temporary string stack
:TEMPPT DAT TEMPST
:RAM17 ; Pointer to the address of the last string in the temporary string stack
:LASTPT DAT 0
:RAM19 ; Descriptor stack for temporary strings
:TEMPST
.FILL 10 BLANK
:TEMPSTEND
:RAM22
:INDEX DAT BLANK, BLANK
; Pointer to the start of BASIC program text
:RAM2B
:TXTTAB DAT BASICMEM+1
; Pointer to the variable storage area
:RAM2D
:VARTAB DAT 0
; Pointer to the start of the array storage area
:RAM2F
:ARYTAB DAT 0
; Pointer to the start of free RAM
:RAM31
:STREND DAT 0
:RAM33
:FREETOP DAT 0
; Temporary Pointer for Strings
:RAM35
:FRESPC DAT 0
:RAM37 ; Pointer to highest address used by basic
:MEMSIZ DAT 0
;Current basic line number (>0xF00 in immediate mode)
:RAM39
:CURLIN DAT 0
:RAM3B
:OLDLIN DAT 0
:RAM3D
:OLDTXT DAT 0
:RAM3F
:DATLIN DAT 0
:RAM41
:DATPTR DAT 0
:RAM43
:INPPTR DAT 0
:RAM45
:VARNAM DAT 0, 0
:RAM47
:VARPNT DAT 0
:RAM49
:FORPNT DAT 0
:RAM4B
:OPPTR DAT 0
:RAM4D
:OPMASK DAT 0
.DEFINE OPM_LT 1
.DEFINE OPM_EQ 2
.DEFINE OPM_GT 4
:RAM4E
:DEFPNT DAT 0
;temporary pointer to the current string descriptor
:RAM50
:DSCPNT DAT 0
:DSCLEN
:RAM53 DAT 0
:RAM55 DAT 0
; Parameters for memory copying and manipulation
:RAM58
:HIGHDS DAT 0
:RAM5F
:LOWTR DAT 0
:RAM5A
:HIGHTR DAT 0
:FBUFPT ; Series Evaluation Pointer
:RAM71 DAT 0
.INCLUDE "chrget.dasm16"
; debugging routine for garbage collector
.MACRO GARBDEBUG(F)
;SET C, [GARBDISPLAY]
;SET [C], 0x7000
;ADD [C], F
;ADD [GARBDISPLAY], 1
.ENDMACRO
:GARBDISPLAY DAT SCREENMEM+64
:USRPOK
:RAM0310 JMP 1234
.DEFINE RAM0311 USRPOK+1
.DEFINE USRADD USRPOK+1
; ************* BASIC ROM ************
; some special tokens
.DEFINE BASIC_FOR_TOKEN 0x81
.DEFINE BASIC_TO_TOKEN 0xA4
.DEFINE BASIC_STEP_TOKEN 0xA9
.DEFINE BASIC_DATA_TOKEN 0x83
.DEFINE BASIC_GOSUB_TOKEN 0x8D
.DEFINE BASIC_REM_TOKEN 0x8F
.DEFINE BASIC_PRINT_TOKEN 0x99
.DEFINE BASIC_GOTO_TOKEN 0x89
.DEFINE BASIC_THEN_TOKEN 0xA7
.DEFINE BASIC_TAB_TOKEN 0xA3
.DEFINE BASIC_SPC_TOKEN 0xA6
.DEFINE BASIC_FN_TOKEN 0xA5
.DEFINE BASIC_NOT_TOKEN 0xA8
.DEFINE BASIC_EQ_TOKEN 0xB2
.DEFINE BASIC_GT_TOKEN 0xB1
.DEFINE BASIC_LEFT_TOKEN 0xC8
.DEFINE BASIC_SGN_TOKEN 0xB4
.DEFINE BASIC_MINUS_TOKEN 0xAB
.DEFINE BASIC_PLUS_TOKEN 0xAA
; address table for commands
; (In original, address minus 1 used because
; the 6502 added 1 to the PC after an RTS)
:TOKEN_ROUTINES
:ROMA00C
DAT STMT_END
DAT STMT_FOR
DAT STMT_NEXT
DAT STMT_DATA
DAT STMT_INPUTN
DAT STMT_INPUT
DAT STMT_DIM
DAT STMT_READ
DAT STMT_LET
DAT STMT_GOTO
DAT STMT_RUN
DAT STMT_IF
DAT STMT_RESTORE
DAT STMT_GOSUB
DAT STMT_RETURN
DAT STMT_REM
DAT STMT_STOP
DAT STMT_ON
DAT STMT_WAIT
DAT STMT_LOAD
DAT STMT_SAVE
DAT STMT_VERIFY
DAT STMT_DEF
DAT STMT_POKE
DAT STMT_PRINTN
DAT STMT_PRINT
DAT STMT_CONT
DAT STMT_LIST
DAT STMT_CLR
DAT STMT_CMD
DAT 0xE129 ; sys
DAT 0xE1BD ; open
DAT 0xE1C6 ; close
DAT STMT_GET
DAT STMT_NEW
:FUNCTION_ROUTINES
DAT SGNFUNC ; sgn
DAT INT ; int
DAT ROMBC58 ; abs
DAT 0x0310 ; usr
DAT ROMB37D ; fre
DAT ROMB39E ; pos
DAT SQR
DAT RND
DAT LOG
DAT EXP
DAT COS
DAT SIN
DAT TAN
DAT ATN ; atn
DAT PEEKFUNC ; peek
DAT ROMB77C ; len
DAT STRD
DAT VAL
DAT ASCN
DAT CHRD
DAT LEFTD
DAT RIGHTD
DAT MIDD
; indexing offset
.DEFINE FUNCTION_VECTOR FUNCTION_ROUTINES-BASIC_SGN_TOKEN
; priority and address table
; for operators
:TBL_OP
DAT 0x79
DAT FADDT ; plus
DAT 0x79
DAT FSUBT ; minus
DAT 0x7B
DAT FMULTT ; multiply
DAT 0x7B
DAT FDIVT ; divide
DAT 0x7F
DAT FPWRT ; power
DAT 0x50
DAT ANDOP ; AND
DAT 0x46
DAT OROP ; OR
:TBL_OP_NEG
DAT 0x7D
DAT NEGOP ; negative
:TBL_OP_NOT
DAT 0x5A
DAT NOTOP ; NOT
:TBL_OP_COMPARE
DAT 0x64
DAT RELOPS ; greater / equal / less
; table of commands
; each ended with a +0x80
:TOKEN_NAMES
:ROMA09E
DAT 0x45,0x4E,0xC4 ; end
DAT 0x46,0x4F,0xD2 ; for
DAT 0x4E,0x45,0x58,0xD4 ; next
DAT 0x44,0x41,0x54,0xC1 ; data
DAT 0x49,0x4E,0x50,0x55,0x54,0xA3 ; input#
DAT 0x49,0x4E,0x50,0x55,0xD4 ; input
DAT 0x44,0x49,0xCD ; dim
DAT 0x52,0x45,0x41,0xC4 ; read
DAT 0x4C,0x45,0xD4 ; let
DAT 0x47,0x4F,0x54,0xCF ; goto
DAT 0x52,0x55,0xCE ; run
DAT 0x49,0xC6 ; if
DAT 0x52,0x45,0x53,0x54,0x4F,0x52,0xC5 ; restore
DAT 0x47,0x4F,0x53,0x55,0xC2 ; gosub
DAT 0x52,0x45,0x54,0x55,0x52,0xCE ; return
DAT 0x52,0x45,0xCD ; rem
DAT 0x53,0x54,0x4F,0xD0 ; stop
DAT 0x4F,0xCE ; on
DAT 0x57,0x41,0x49,0xD4 ; wait
DAT 0x4C,0x4F,0x41,0xC4 ; load
DAT 0x53,0x41,0x56,0xC5 ; save
DAT 0x56,0x45,0x52,0x49,0x46,0xD9 ; verify
DAT 0x44,0x45,0xC6 ; def
DAT 0x50,0x4F,0x4B,0xC5 ; poke
DAT 0x50,0x52,0x49,0x4E,0x54,0xA3 ; print#
DAT 0x50,0x52,0x49,0x4E,0xD4 ; print
DAT 0x43,0x4F,0x4E,0xD4 ; cont
DAT 0x4C,0x49,0x53,0xD4 ; list
DAT 0x43,0x4C,0xD2 ; clr
DAT 0x43,0x4D,0xC4 ; cmd
DAT 0x53,0x59,0xD3 ; sys
DAT 0x4F,0x50,0x45,0xCE ; open
DAT 0x43,0x4C,0x4F,0x53,0xC5 ; close
DAT 0x47,0x45,0xD4 ; get
DAT 0x4E,0x45,0xD7 ; new
DAT 0x54,0x41,0x42,0xA8 ; tab(
DAT 0x54,0xCF ; to
DAT 0x46,0xCE ; fn
DAT 0x53,0x50,0x43,0xA8 ; spc(
DAT 0x54,0x48,0x45,0xCE ; then
DAT 0x4E,0x4F,0xD4 ; not
DAT 0x53,0x54,0x45,0xD0 ; step
DAT 0xAB ; plus
DAT 0xAD ; minus
DAT 0xAA ; multiply
DAT 0xAF ; divide
DAT 0xDE ; power
DAT 0x41,0x4E,0xC4 ; and
DAT 0x4F,0xD2 ; or
DAT 0xBE ; greater
DAT 0xBD ; equal
DAT 0xBC ; less
DAT 0x53,0x47,0xCE ; sgn
DAT 0x49,0x4E,0xD4 ; int
DAT 0x41,0x42,0xD3 ; abs
DAT 0x55,0x53,0xD2 ; usr
DAT 0x46,0x52,0xC5 ; fre
DAT 0x50,0x4F,0xD3 ; pos
DAT 0x53,0x51,0xD2 ; sqr
DAT 0x52,0x4E,0xC4 ; rnd
DAT 0x4C,0x4F,0xC7 ; log
DAT 0x45,0x58,0xD0 ; exp
DAT 0x43,0x4F,0xD3 ; cos
DAT 0x53,0x49,0xCE ; sin
DAT 0x54,0x41,0xCE ; tan
DAT 0x41,0x54,0xCE ; atn
DAT 0x50,0x45,0x45,0xCB ; peek
DAT 0x4C,0x45,0xCE ; len
DAT 0x53,0x54,0x52,0xA4 ; str$
DAT 0x56,0x41,0xCC ; val
DAT 0x41,0x53,0xC3 ; asc
DAT 0x43,0x48,0x52,0xA4 ; chr$
DAT 0x4C,0x45,0x46,0x54,0xA4 ; left$
DAT 0x52,0x49,0x47,0x48,0x54,0xA4 ; right$
DAT 0x4D,0x49,0x44,0xA4 ; mid$
; other commands
DAT 0x47,0xCF ; go
DAT 0x00 ; end of list
; table of errors messages
; each ended with a +0x80
:ERR01 ;TOO MANY FILES
DAT 0x54,0x4F,0x4F
DAT 0x20,0x4D,0x41,0x4E,0x59
DAT 0x20,0x46,0x49,0x4C,0x45,0xD3
:ERR02 ;FILE OPEN
DAT 0x46,0x49,0x4C,0x45
DAT 0x20,0x4F,0x50,0x45,0xCE
:ERR03 ;FILE NOT OPEN
DAT 0x46,0x49,0x4C,0x45
DAT 0x20,0x4E,0x4F,0x54
DAT 0x20,0x4F,0x50,0x45,0xCE
:ERR04 ;FILE NOT FOUND
DAT 0x46,0x49,0x4C,0x45
DAT 0x20,0x4E,0x4F,0x54
DAT 0x20,0x46,0x4F,0x55,0x4E,0xC4
:ERR05 ;DEVICE NOT PRESENT
DAT 0x44,0x45,0x56,0x49,0x43,0x45
DAT 0x20,0x4E,0x4F,0x54
DAT 0x20,0x50,0x52,0x45,0x53,0x45,0x4E,0xD4
:ERR06 ;NOT INPUT FILE
DAT 0x4E,0x4F,0x54
DAT 0x20,0x49,0x4E,0x50,0x55,0x54
DAT 0x20,0x46,0x49,0x4C,0xC5
:ERR07 ;NOT OUTPUT FILE
DAT 0x4E,0x4F,0x54
DAT 0x20,0x4F,0x55,0x54,0x50,0x55,0x54
DAT 0x20,0x46,0x49,0x4C,0xC5
:ERR08 ;MISSING FILE NAME
DAT 0x4D,0x49,0x53,0x53,0x49,0x4E,0x47
DAT 0x20,0x46,0x49,0x4C,0x45
DAT 0x20,0x4E,0x41,0x4D,0xC5
:ERR09 ;ILLEGAL DEVICE NUMBER
DAT 0x49,0x4C,0x4C,0x45,0x47,0x41,0x4C
DAT 0x20,0x44,0x45,0x56,0x49,0x43,0x45
DAT 0x20,0x4E,0x55,0x4D,0x42,0x45,0xD2
:ERR0A ;NEXT WITHOUT FOR
DAT 0x4E,0x45,0x58,0x54
DAT 0x20,0x57,0x49,0x54,0x48,0x4F,0x55,0x54
DAT 0x20,0x46,0x4F,0xD2
:ERR0B ;SYNTAX
DAT 0x53,0x59,0x4E,0x54,0x41,0xD8
:ERR0C ;RETURN WITHOUT GOSUB
DAT 0x52,0x45,0x54,0x55,0x52,0x4E
DAT 0x20,0x57,0x49,0x54,0x48,0x4F,0x55,0x54
DAT 0x20,0x47,0x4F,0x53,0x55,0xC2
:ERR0D ;OUT OF DATA
DAT 0x4F,0x55,0x54
DAT 0x20,0x4F,0x46
DAT 0x20,0x44,0x41,0x54,0xC1
:ERR0E ;ILLEGAL QUANTITY
DAT 0x49,0x4C,0x4C,0x45,0x47,0x41,0x4C
DAT 0x20,0x51,0x55,0x41,0x4E,0x54,0x49,0x54,0xD9
:ERR0F ;OVERFLOW
DAT 0x4F,0x56,0x45,0x52,0x46,0x4C,0x4F,0xD7
:ERR10 ;OUT OF MEMORY
DAT 0x4F,0x55,0x54
DAT 0x20,0x4F,0x46
DAT 0x20,0x4D,0x45,0x4D,0x4F,0x52,0xD9
:ERR11 ;UNDEF'D STATEMENT
DAT 0x55,0x4E,0x44,0x45,0x46,0x27,0x44
DAT 0x20,0x53,0x54,0x41,0x54,0x45,0x4D,0x45,0x4E,0xD4
:ERR12 ;BAD SUBSCRIPT
DAT 0x42,0x41,0x44
DAT 0x20,0x53,0x55,0x42,0x53,0x43,0x52,0x49,0x50,0xD4
:ERR13 ;REDIM'D ARRAY
DAT 0x52,0x45,0x44,0x49,0x4D,0x27,0x44
DAT 0x20,0x41,0x52,0x52,0x41,0xD9
:ERR14 ;DIVIDION BY ZERO
DAT 0x44,0x49,0x56,0x49,0x53,0x49,0x4F,0x4E
DAT 0x20,0x42,0x59
DAT 0x20,0x5A,0x45,0x52,0xCF
:ERR15 ;ILLEGAL DIRECT
DAT 0x49,0x4C,0x4C,0x45,0x47,0x41,0x4C
DAT 0x20,0x44,0x49,0x52,0x45,0x43,0xD4
:ERR16 ;TYPE MISMATCH
DAT 0x54,0x59,0x50,0x45
DAT 0x20,0x4D,0x49,0x53,0x4D,0x41,0x54,0x43,0xC8
:ERR17 ;STRING TOO LONG
DAT 0x53,0x54,0x52,0x49,0x4E,0x47
DAT 0x20,0x54,0x4F,0x4F
DAT 0x20,0x4C,0x4F,0x4E,0xC7
:ERR18 ;FILE DATA
DAT 0x46,0x49,0x4C,0x45
DAT 0x20,0x44,0x41,0x54,0xC1
:ERR19 ;FORMULA TOO COMPLEX
DAT 0x46,0x4F,0x52,0x4D,0x55,0x4C,0x41
DAT 0x20,0x54,0x4F,0x4F
DAT 0x20,0x43,0x4F,0x4D,0x50,0x4C,0x45,0xD8
:ERR1A ;CAN'T CONTINUE
DAT 0x43,0x41,0x4E,0x27,0x54
DAT 0x20,0x43,0x4F,0x4E,0x54,0x49,0x4E,0x55,0xC5
:ERR1B ;UNDEF'D FUNCTION
DAT 0x55,0x4E,0x44,0x45,0x46,0x27,0x44
DAT 0x20,0x46,0x55,0x4E,0x43,0x54,0x49,0x4F,0xCE
:ERR1C ;VERIFY
DAT 0x56,0x45,0x52,0x49,0x46,0xD9
:ERR1D ;LOAD
DAT 0x4C,0x4F,0x41,0xC4
; error message address locations
:ROMA326 DAT 0 ; ???
DAT ERR01 ; 01 too many files
DAT ERR02 ; 02 file open
DAT ERR03 ; 03 file not open
DAT ERR04 ; 04 file not found
DAT ERR05 ; 05 device not present
DAT ERR06 ; 06 not input file
DAT ERR07 ; 07 not output file
DAT ERR08 ; 08 missing file name
DAT ERR09 ; 09 illegal device number
DAT ERR0A ; 0A next without for
DAT ERR0B ; 0B syntax
DAT ERR0C ; 0C return without gosub
DAT ERR0D ; 0D out of data
DAT ERR0E ; 0E illegal quantity
DAT ERR0F ; 0F overflow
DAT ERR10 ; 10 out of memory
DAT ERR11 ; 11 undef'd statment
DAT ERR12 ; 12 bad subscript
DAT ERR13 ; 13 redim'd array
DAT ERR14 ; 14 devision by zero
DAT ERR15 ; 15 illegal direct
DAT ERR16 ; 16 type mismatch
DAT ERR17 ; 17 string too long
DAT ERR18 ; 18 file data
DAT ERR19 ; 19 formula too complex
DAT ERR1A ; 1A can't continue
DAT ERR1B ; 1B undef'd function
DAT ERR1C ; 1C verify
DAT ERR1D ; 1D load
DAT ROMA381 ; 1E break
; other messages
; ok
:ROMA364 DAT CBM_RETURN, "OK", CBM_RETURN
:ROMA368 DAT 0
; error
:ROMA369 DAT " ERROR"
:ROMA370 DAT 0
; in
:ROMA371 DAT " IN "
:ROMA375 DAT 0
; ready.
:ROMA376 DAT CBM_RETURN, "READY.", CBM_RETURN
:ROMA380 DAT 0
; break
:ROMA381 DAT CBM_RETURN,0x0A
:ROMA383 DAT "BREAK"
:ROMA388 DAT 0x00
:ROMA389 DAT 0xA0
.include "loadsave.dasm16"
:FNDFOR
; Search for "FOR" blocks on stack containing
; the current variable. If found, returns the
; stack location as X, and Z=1. Otherwise, Z=0
:ROMA38A SET Z, 0
SET X, SP
ADD X, 2 ; make allowance for two JSRs
:ROMA38F IFN [X], BASIC_FOR_TOKEN ; FOR block
RTS ; not a FOR block.
:ROMA39A IFE [FORPNT], 0
SET [FORPNT], [X+1]
:ROMA3A4 SET A, [X+1]
IFE [FORPNT], A
JMP ROMA3B7
:ROMA3B0 ADD X, 11
JMP ROMA38F
:ROMA3B7 SET Z, 1 ; "found" result
RTS
:BLTU
; ----------------------------------------------------------------------------
; MOVE BLOCK OF MEMORY UP
;
; ON ENTRY:
; (Y,A) = (HIGHDS) = DESTINATION END+1 (58)
; (LOWTR) = LOWEST ADDRESS OF SOURCE (5F)
; (HIGHTR) = HIGHEST SOURCE ADDRESS+1 (5A)
; ----------------------------------------------------------------------------
; Parameters in [LOWTR], [HIGHTR], and [HIGHDS]
; and A should contain the value of [HIGHDS].
; RETURN: ?
:ROMA3B8 JSR REASON ; garbage collect?
SET [STREND], A ; returned start of free RAM
:BLTU2
:ROMA3BF SET B, [LOWTR] ; source start address
SET J, [HIGHTR] ; source end address
IFE J, B ; move no bytes
RTS
; pre-decrement
STD I, [HIGHDS] ; destimation end address
:ROMA3BG STD [I], [J]
IFN J, B
JMP ROMA3BG
SET [I], [J] ; last byte
RTS
; test for A bytes free on stack
:GETSTK
ADD A, STACK+52
IFG A, SP
JMP OMERR
RTS
; ----------------------------------------------------------------------------
; CHECK IF ENOUGH ROOM BETWEEN ARRAYS AND STRINGS
; (A) = ADDR ARRAYS NEED TO GROW TO
; ----------------------------------------------------------------------------
:REASON
:ROMA408 IFL A, [FREETOP]
RTS
SET PUSH, A
JSR GARBAG
SET A, POP
; garbage collection not enough?
IFG A, [FREETOP]
JMP OMERR
:ROMA434 RTS
; out of memory error
:OMERR
:ROMA435 SET X, 16 ; ?OUT OF MEMORY
; handle error messages
:ERROR
:ROMA437 JMP [IERROR] ; snall detour in the kernal
:BASIC_ERROR
:ROMA43A SET [INDEX], [ROMA326+X]
JSR CLRCHN
SET [CHANNL], 0
:ROMA44E JSR ROMAAD7 ; end line on CMD
:ROMA451 JSR OUTQUES
SET Z, [INDEX] ; LDY #$00
:ROMA456 SET A, [Z] ; LDA ($22),Y
SET PUSH, A ; PHA
AND A, 0x7F ; AND #$7F
SET PUSH, Z
JSR ROMAB47 ; CHROUT
SET Z, POP
ADD Z, 1 ; INY
SET A, POP
IFC A, 0x80 ; PLA
JMP ROMA456 ; BPL $A456
JSR ROMA67A ; clear some basic variables
SET A, ROMA369 ; " ERROR"
:ROMA469 JSR STROUT
IFL [CURLIN], 0xFF00 ;If not in immediate node
JSR ROMBDC2 ; display "IN <line>"
:READY
:ROMA474 SET A, ROMA376 ; "READY."
JSR STROUT
SET A, 0x80
:ROMA47D JSR SETMSG
; main loop
:MAIN
:ROMA480 JMP [IMAIN] ; normally ROMA483
:DEF_MAIN
:ROMA483
; debugging is useful
IFE DEBUGPROGMEM, 0
JMP SKIPBMEM
SET I, SCREENMEM
SET J, BASICMEM
:BMEMLOOP
STI [I], [J]
BOR [I-1], 0x0100
IFL I, SCREENMEM+32
JMP BMEMLOOP
:SKIPBMEM
JSR INLIN ; address of line input in X
SET [RAM7A], X
:ROMA48A JSR CHRGET
:ROMA48D SET X, A ; TAX
:ROMA48E IFE A, 0 ; BEQ $A480
JMP [IMAIN] ; which was this JMP
SET [CURLIN], -1 ; enter immediate mode
IFE C, 0 ; begins with a digit
JMP MAIN1 ; add line to program
; parse statement in immediate mode
JSR CRUNCH ; token cruncher
JMP ROMA7E1 ; execute a statement
; handle insert/delete basic lines
:MAIN1
:NUMBERED_LINE
:ROMA49C JSR LINGET ; get decimal number into [LINNUM]
JSR CRUNCH ; token cruncher
; why is this too short?
SET [COUNT], Y ; cache length of line
JSR FINDLN ; search for line A
IFE C, 0 ; line number not found
JMP ROMA4ED ; insert only
; Delete old line.
:ROMA4A9 SET I, [LOWTR] ; Pointer to matched line
SET J, [I] ; Pointer to following line
STD B, [VARTAB] ; End of program text
SUB B, J
ADD B, I ; End when line is removed.
SET [VARTAB], B ; reclaim memory for variables
; due to the fact that zero is always a 16-bit zero,
; and never the high byte of a small number,
; we might be able to relink the program within the
; loop instead of the old way.
:ROMA4A9L
STI [I], [J]
IFL I, B
JMP ROMA4A9L
SET [I], [J]
; insert new line.
:ROMA4ED JSR SETPTRS ; clear variable memory
JSR FIX_LINKS ; relink basic program
IFE [RAM0200], 0 ; No text entered
JMP MAIN ; delete only; return to prompt
; Make room for new line by moving the rest
; of the program up
:ROMA4F8 SET A, [VARTAB]
SET [HIGHTR], A ; source end address + 1
ADD A, [COUNT] ; add number of characters
SET [HIGHDS], A ; destination end address + 1
JSR BLTU ; Move memory
SET [RAM01FF], [LINNUM]
:ROMA517 SET [VARTAB], [STREND]
SET Y, [COUNT]
SUB Y, 1
; copy line into memory
SET I, [LOWTR] ; pointer to new spot in memory
ADD I, Y
STI J, RAM01FE
ADD J, Y
:ROMA522L
STD [I], [J]
IFN J, RAM01FE
JMP ROMA522L
:ROMA52A JSR SETPTRS ; clr?
JSR FIX_LINKS
JMP [IMAIN]
; ----------------------------------------------------------------------------
; CLEAR ALL VARIABLES
; RE-ESTABLISH ALL FORWARD LINKS
; ----------------------------------------------------------------------------
:FIX_LINKS
:ROMA533
SET I, [TXTTAB]
SET J, I ; note beginning of line
:ROMA53C IFE [I+1], 0 ; no link; must be end of program
RTS
ADD I, 1 ; skip over line number
:ROMA544 ADD I, 1 ; go to next character
IFN [I], 0
JMP ROMA544
ADD I, 1
:ROMA54A SET [J], I ; link from beginning of line to current location
:ROMA559 SET J, I ; use current location for next link
:ROMA55D JMP ROMA53C
; Get a line from the console.
; input stored in RAM0200, zero-terminated
:INLIN
:ROMA560 SET X, 0
:ROMA562 JSR ROME112 ; GETIN -> ROMF157
IFE A, CBM_RETURN
JMP ROMAACA ; mark end and return
SET [RAM0200+X], A
ADD X, 1
IFU X, HW_COLS*ROWS_IN_LINE
JMP ROMA562
IFE DEBUG_SNERR, 0
JMP LTLERR
; to help diagnose screen editor issues.
; how long did it think the line was?
SET A, X
JSR LINPRT
;SET A, 62
;JSR CHROUT
;SET A, HW_COLS*ROWS_IN_LINE
;JSR LINPRT
SET A, CBM_RETURN
JSR CHROUT
SET A, CBM_RETURN
JSR CHROUT
:LTLERR
SET X, 0x17 ; ?LINE TOO LONG
JMP ERROR
; Standard Token Cruncher
; Throughout this routine, X contains the address
; of the characters being evaluated.
; RAM0F is used to disable tokenization after a DATA statement.
; Y returns the length of the string plus 2, not including line number
; 2 is added so that when the crunched string is copied into program
; memory, it is copied along with an extra word for the line number,
; and an extra word into which the link to the next line will be stored.
; That is why everything indexed from [RAM01FE] instead of [RAM0200]
; directly, and why everything in the 6502 version indexed from $01FC.
:CRUNCH
:ROMA579 JMP [ICRNCH]
:DEF_CRUNCH
:ROMA57C SET X, [RAM7A]
SET Y, 2 ; first two characters are taken up by link &c
SET [RAM0F], Y
:ROMA582 SET A, [X]
IFC A, 0x80 ; BPL, unshifted character.
JMP ROMA58E
IFE A, 0xFF ; pi
JMP ROMA5C9
ADD X, 1
JMP ROMA582 ; ignore, go to next
:ROMA58E IFE A, CBM_SPACE
JMP ROMA5C9
SET [ENDCHR], A
IFE A, CBM_QUOTE
JMP ROMA5EE ; skip to next quote
IFB [RAM0F], 0x40 ; BVS
JMP ROMA5C9 ; Quote mode for DATA statement
IFN A, 0x3F ; question mark
JMP ROMA5A4
SET A, BASIC_PRINT_TOKEN
JMP ROMA5C9
; the REM test line should get at least this far
:ROMA5A4 IFL A, 0x30 ; Zero
JMP ROMA5AC ; not a digit
:ROMA5A8 IFL A, 0x3C ; Digit
JMP ROMA5C9
:ROMA5AC SET [RAM71], Y ; cache position in thing
SET [COUNT], 0 ; start at first token
SET Y, -1 ; start at first byte of token table
SET [RAM7A], X
SUB X, 1
; Loop through input buffer and token, see if they match.
:ROMA5B6 ADD Y, 1 ; does next character of token table...
ADD X, 1 ; match the next byte of the input?
; loop section 1
:ROMA5B8 SET A, [X]
:ROMA5BC XOR A, [TOKEN_NAMES+Y]
IFE A, 0
JMP ROMA5B6
:ROMA5C1 ; 0x80 matches both the final character of
; a full command, or the shifted final character
; of an abbreviated command.
IFN A, 0x80
JMP ROMA5F5
BOR A, [COUNT] ;A = Token = 0x80 + token's position in list
:ROMA5C7 SET Y, [RAM71]
:ROMA5C9 ADD X, 1 ; Move to next character in buffer
ADD Y, 1 ; Move to...?
SET [RAM01FD+Y], A
IFE A, 0 ; end of line
JMP ROMA609
:ROMA5D4 SUB A, CBM_COLON
IFE A, 0
JMP ROMA5DC
IFN A, (BASIC_DATA_TOKEN-CBM_COLON) ; DATA token
JMP ROMA5DE
:ROMA5DC SET [RAM0F], A ; Set quote mode ON for DATA
:ROMA5DE IFN A, (BASIC_REM_TOKEN-CBM_COLON)
JMP ROMA582 ; just move to next character
SET [ENDCHR], 0
; Copy characters literally until either
; end of line, or whatever's in [ENDCHR].
:ROMA5E5 SET A, [X]
IFC A, 0xFF
JMP ROMA5C9
:ROMA5EA IFE A, [ENDCHR]
JMP ROMA5C9
:ROMA5EE ADD Y, 1
SET [RAM01FD+Y], A
ADD X, 1
IFB X, 0xFF ; BNE in 8-bit
JMP ROMA5E5
; Jumped here from string matcher above,
; when a token didn't match. Return to beginning
; of token, and try the next one.
:ROMA5F5 SET X, [RAM7A] ; Restore original source pointer
ADD [COUNT], 1
; Skip past end of this token
:ROMA5F9 ADD Y, 1
IFC [TOKEN_NAMES-1+Y], 0x80
JMP ROMA5F9
IFN [TOKEN_NAMES+Y], 0
JMP ROMA5B8 ; Try next token
:ROMA604 SET A, [X]
IFC A, 0x80 ; unshifted
JMP ROMA5C7
; branches here if null character found
:ROMA609 SET [RAM01FE+Y], A ; ends with two NULLs in a row
SET [RAM7A], RAM0200-1
RTS
; SEARCH for a line in a program
; pass address of first line to check in A (originally A+X)
; returns C=1 and address in LOWTR if found
; returns C=0 if not found
:FINDLN
:ROMA613 SET A, [TXTTAB] ; $2B
:FINDLNA
:ROMA617 SET I, 1
SET [LOWTR], A
ADD I, [LOWTR] ; I = NEXT line in linked list
IFE [I], 0 ; if address of that line is 0
JMP ROMA640
SET A, [LINNUM]
IFL A, [I]
JMP ROMA640 ; return "not found"
SET C, 1 ;since last one was a BCC
IFE A, [I]
RTS ; return "found"
:ROMA637 SET A, [I-1]
JMP FINDLNA ; Check line after next.
:ROMA640 SET C, 0 ; return "not found"
RTS
; NEW command
:STMT_NEW
:ROMA642 IF_NOT_NEXT_STMT
RTS
:SCRTCH
:ROMA644 SET I, [TXTTAB]
STI [I], 0
STI [I], 0
SET [I], 0
SET [VARTAB], I
:SETPTRS
:ROMA659 JSR STXTPT ; set execution pointer to [TXTTAB]-1
:ROMA65C SET A, 0 ;LDA #$00
SET Z, 1
; CLR command
:STMT_CLR
:ROMA65E IF_NOT_NEXT_STMT
RTS ; BNE $A68D
:ROMA660 JSR CLALL
:ROMA663 SET [FREETOP], [MEMSIZ]
;SET EX, 0xA663
;IFE [VARTAB], 0
; JMP VARTABCRASH
SET [ARYTAB], [VARTAB]
SET [STREND], [VARTAB] ; set start of free RAM
:ROMA677 JSR STMT_RESTORE
; reset stack and program pointers
:ROMA67A SET [TEMPPT], TEMPST ;String pointer stack
SET A, POP ; Pull RTS location
SET SP, STACKBASEND ; LDX #$FA
SET PUSH, A
SET [OLDTXT], 0
SET [SUBFLG], 0
:ROMA68D RTS
; ----------------------------------------------------------------------------
; SET TXTPTR TO BEGINNING OF PROGRAM
; ----------------------------------------------------------------------------
:STXTPT
:ROMA68E SET A, [TXTTAB]
SUB A, 1
SET [RAM7A], A
RTS
:STMT_LIST
:ROMA69C IF_IS_DIGIT ; LIST line
JMP ROMA6A4
IF_NEXT_STMT ; LIST all
JMP ROMA6A4
IFN A, BASIC_MINUS_TOKEN ; LIST -end
RTS
:ROMA6A4 JSR LINGET
JSR FINDLN ;
JSR CHRGOT
IF_NEXT_STMT ; no end line specified
JMP ROMA6BB
IFN A, BASIC_MINUS_TOKEN ; range to end
RTS
JSR CHRGET
JSR LINGET
IFE Z, 0
RTS
; pop?
:ROMA6BB SET A, POP
SET A, POP
IFN [LINNUM], 0
JMP ROMA6C9
SET [LINNUM], -1
; LIST LINES from LOWTR to LINNUM
:ROMA6C9 SET [RAM0F], 1
SET Y, [LOWTR]
:ROMA6CD IFE [Y], 0 ; no link to next line
JMP ROMA714
JSR ROMA82C ; check STOP key
JSR ROMAAD7 ; end line on output file
ADD Y, 1
IFG [Y], [LINNUM] ; beyond end line
JMP ROMA714 ; break out of loop
SET [FORPNT], Y
:ROMA6EA SET A, [Y]
JSR LINPRT
SET A, CBM_SPACE ; space following line number
:ROMA6EF SET Y, [FORPNT]
:ROMA6F1 AND A, 0x7F ; filter high bit if coming from QPLOP
; loop to print a line
:ROMA6F3 JSR ROMAB47 ; print character
IFE A, CBM_QUOTE
XOR [RAM0F], -1 ; enter quote mode
ADD Y, 1
;IFE Y, 0 ; what, stop after 256 characters?
; JMP ROMA714
SET A, [Y]
IFN A, 0
JMP QPLOP ; Print with tokens expanded
SET Y, [LOWTR] ; follow link to nxt line
SET [LOWTR], [Y] ; cache link to line after that
IFN [Y], 0
JMP ROMA6C9
:ROMA714 JMP ROME386
; Standard Token Printer
:QPLOP
:ROMA717 JMP [IQPLOP]
:DEF_QPLOP
:ROMA71A IFL A, 0x80 ; Low ASCII
JMP ROMA6F3 ; print literal
IFE A, 0xFF ; PI
JMP ROMA6F3 ; print literal
IFB [RAM0F], 0x8000 ; BMI
JMP ROMA6F3 ; print literal
; token value detected
:ROMA724 SUB A, 0x7F
SET [FORPNT], Y
SET Y, TOKEN_NAMES-1