-
Notifications
You must be signed in to change notification settings - Fork 0
/
mixal.mix
1537 lines (1537 loc) · 41.8 KB
/
mixal.mix
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
*
* PETERSON: MIXAL ASSEMBLER
* HTTP://WWW.JKLP.ORG/PROFESSION/BOOKS/MIX/C08.HTML
*
*
TAPE EQU 0 TAPE UNIT NUMBER FOR LOADER
CR EQU 16 INPUT CARD READER
LP EQU 18 OUTPUT LINE PRINTER
*
MAXSYMBOL EQU 250 MAXIMUM NUMBER OF SYMBOLS
*
* TAPE BUFFER VARIABLES
*
BUF1 ORIG *+100 BUFFERS
BUF2 ORIG *+100
STOREBUF CON BUF1 POINTER TO BUFFER FOR STORING
TAPEBUF CON BUF2 POINTER TO BUFFER FOR OUTPUT
TAPEBUFPTR CON BUF1 CURRENT WORD POINTER
TAPECNTR CON 100 NUMBER OF WORDS LEFT
*
*
* SUBROUTINE FINISHBUF
*
* LOADER WORDS TO BE WRITTEN TO TAPE FOR
* LOADING ARE STORED IN A BUFFER UNTIL 100
* WORDS ARE ACCUMULATED. THEN THIS ROUTINE
* IS CALLED TO DUMP THE BUFFER TO TAPE. DOUBLE
* BUFFERING IS USED.
*
FINISHBUF STJ FIBEXIT
ST1 FIBSAVE1(0:2) SAVE REGISTERS
ST2 FIBSAVE2(0:2)
*
LD1 STOREBUF CURRENT BUFFER
OUT 0,1(TAPE) WRITE BUFFER TO TAPE
LD2 TAPEBUF SWITCH BUFFER POINTERS
ST2 STOREBUF
ST2 TAPEBUFPTR AND RESET POINTER
ST1 TAPEBUF
*
FIBSAVE1 ENT1 * RESTORE REGISTERS
FIBSAVE2 ENT2 *
FIBEXIT JMP *
*
*
* SUBROUTINE TAPEOUT
*
* THIS SUBROUTINE ACCEPTS ONE WORD TO BE
* WRITTEN TO THE TAPE FOR THE LOADER AND
* STORES IT IN THE BUFFER UNTIL THE BUFFER IS
* FULL. THEN IT CALLS FINISHBUF TO EMPTY
* THE BUFFER.
*
* INPUT WORD IS IN THE A REGISTER
*
TAPEOUT STJ TOEXIT SAVE REGISTERS
ST1 TOSAVE1(0:2)
*
LD1 TAPEBUFPTR NEXT WORD POINTER
STA 0,1 SAVE WORD
INC1 1
ST1 TAPEBUFPTR UPDATE POINTER
*
LD1 TAPECNTR CHECK FOR FULL BUFFER
DEC1 1
J1P STILLROOM
JMP FINISHBUF BUFFER FULL
ENT1 100 RESET COUNTER
*
STILLROOM ST1 TAPECNTR RESTORE COUNTER
*
TOSAVE1 ENT1 *
TOEXIT JMP *
*
*
* LOADER BLOCK VARIABLES
*
BLCKLENGTH CON 63 LENGTH OF LDRBLOCK
LDRBLOCK ORIG *+64 BLOCK FOR LOADER RECORDS
NXTLOADLOC CON 0 INDEX INTO LDRBLOCK
*
* GENERATE
*
* GENERATE A WORD OF LOADER OUTPUT.
* THE LOADER WORD IS IN VALUE. REGISTER I6 HAS
* THE ADDRESS OF THE LOCATION WHERE IT SHOULD
* BE LOADED. IF THIS WORD IS A CONTINUATION
* OF THE CURRENT BUFFER, IT IS SIMPLY STORED.
* IF THE WORD IS NONCONTIGUOUS OR FILLS THE
* BUFFER, THE BUFFER IS EMPTIED.
*
GNSAVEA ORIG *+1
*
GENERATE STJ GENEXIT
STA GNSAVEA
ST1 GNSAVE1(0:2)
*
CMP6 NXTLOADLOC CHECK IF CONTIGUOUS
JNE FINISHBLCK IF NOT, FINISH OLD BLOCK
*
LD1 LDRBLOCK(4:5) NUMBER OF WORDS
INC1 1
ST1 LDRBLOCK(4:5)
*
LDA VALUE
STA LDRBLOCK,1 STORE GENERATED WORD
*
INC6 1 INCREASE LOCATION COUNTER
ST6 NXTLOADLOC
*
CMP1 BLCKLENGTH CHECK FOR END OF BLOCK
JGE FINISHBLCK IF SO, FINISH BLOCK
LDA GNSAVEA
GNSAVE1 ENT1 * RESTORE REGISTERS
GENEXIT JMP *
*
*
* SUBROUTINE FINISHBLCK
*
* OUTPUT TO THE LOADER THE BLOCK IN LDRBLOCK.
* NUMBER OF WORDS IS IN BYTE 4:5 OF FIRST WORD.
* (MAY BE ZERO, IN WHICH CASE IGNORE CALL).
* COMPUTE CHECKSUM AND OUTPUT IT TOO
*
CHECKSUM ORIG *+1
FLBSAVEA ORIG *+1
FINISHBLCK STJ FLBEXIT
STA FLBSAVEA
ST1 FLBSAVE1(0:2)
*
LD1 LDRBLOCK(4:5)
J1Z FLBQUIT IF BLOCK IS EMPTY
*
STZ CHECKSUM INITIALIZE CHECKSUM
ENT1 0 INDEX AND COUNTER
*
BLOCKOUT LDA LDRBLOCK,1
JMP TAPEOUT OUTPUT EACH WORD
ADD CHECKSUM(1:5)
STA CHECKSUM(1:5) AND COMPUTE CHECKSUM
*
INC1 1
CMP1 LDRBLOCK(4:5) CHECK ALL WORD OUT
JLE BLOCKOUT
*
LDA CHECKSUM(1:5) OUTPUT CHECKSUM
JMP TAPEOUT
*
JOV *+1 TURN OVERFLOW OFF (IF ON)
*
FLBQUIT STZ LDRBLOCK NEW HEADER WORD
ST6 LDRBLOCK(0:2)
*
LDA FLBSAVEA RESTORE REGISTERS
FLBSAVE1 ENT1 *
FLBEXIT JMP *
*
*
INBUF ORIG *+16
CARD ORIG *+80
ORIG *+10 CARD NUMBER
CARDNUMBER CON 0 NUMBER OF CARDS READ
*
*
* SUBROUTINE CARDREAD
*
* READ THE NEXT CARD FROM THE CARD READER AND
* UNPACK IT INTO THE CHARACTER ARRAY CARD. THE
* CARD IS READ INTO THE BUFFER INBUF AND WE
* TRY TO KEEP THE CARD READER BUSY BY THIS
* DOUBLE BUFFERING.
*
RCSAVEA ORIG *+1
*
READCARD STJ RCEXIT
STA RCSAVEA SAVE REGISTERS
ST1 RCSAVE1(0:2)
ST2 RCSAVE2(0:2)
ST3 RCSAVE3(0:2)
*
JBUS *(CR) WAIT TILL CARD READ
ENT1 79 79..0 CHARACTER COUNTER
ENT2 15 15..0 WORD COUNTER
*
* UNPACK CARD FROM RIGHT TO LEFT
*
NEXTWORD LDA INBUF,2
DEC2 1
ENT3 4 4..0 NUMBER OF CHARACTERS
*
NEXTCHAR STA CARD,1(5:5)
DEC1 1
J1N CARDDONE IF ALL DONE
DEC3 1
J3N NEXTWORD OR NEW WORD NEEDED
SRA 1
JMP NEXTCHAR ELSE SHIFT AND CONTINUE
*
CARDDONE IN INBUF(CR) START NEXT READ
LDA CARDNUMBER
INCA 1 INCREMENT NUMBER OF CARDS
STA CARDNUMBER
*
LDA RCSAVEA RESTORE REGISTERS
RCSAVE1 ENT1 *
RCSAVE2 ENT2 *
RCSAVE3 ENT3 *
RCEXIT JMP *
*
*
SYM ORIG *+2 SYMBOL
LETTER ORIG *+1 NUMERIC=ZERO
*
*
* SUBROUTINE GETSYM
*
* GET THE NEXT SYMBOL FROM CARD(I5) AND PACK
* IT INTO SYM UNTIL A DELIMITER. I5 WILL BE
* MOVED TO POINT TO THE DELIMITER. LETTER IS
* ZERO IF NO LETTER FOUND.
*
GSSAVEA ORIG *+1
GSSAVEX ORIG *+1
*
GETSYM STJ GSEXIT SAVE REGISTERS
STA GSSAVEA
STX GSSAVEX
ST1 GSSAVE1(0:2)
ST2 GSSAVE2(0:2)
*
ENT1 10 MAXIMUM NUMBER OF CHARACTERS
STZ LETTER
ENTX 0
ENTA 0 BLANK AX
*
SCANSYM LD2 CARD,5
CMP2 CHARA(5:5) MUST BE AT LEAST A
JL ENDSYM
CMP2 CHAR9(5:5) AND NOT MORE THAN 9
JG ENDSYM
CMP2 CHAR0(5:5) ALSO CHECK IF 0..9
JGE *+2
STJ LETTER(4:5) LETTER FOUND
*
DEC1 1 DECREMENT NUMBER OF CHARACTERS
J1N *+3
SLAX 1
INCX 0,2 ADD NEW CHARACTER TO SYMBOL
INC5 1 NEXT COLUMN
JMP SCANSYM
*
SYMERROR JMP BADSYM BAD SYMBOL (TOO LONG)
JMP GSQUIT NO JUSTIFICATION NEEDED
*
ENDSYM J1N SYMERROR CHECK IF TOO LONG
LD2 LETTER CHECK IF NEED JUSTIFY.
J2Z *+2
SLAX 0,1 REGISTER 1 HAS COUNT
*
GSQUIT STA SYM SAVE SYMBOL
STX SYM+1
*
LDA GSSAVEA
LDX GSSAVEX
GSSAVE1 ENT1 *
GSSAVE2 ENT2 *
GSEXIT JMP *
*
LABEL ORIG *+2 SPACE FOR LABEL (IF ANY)
OP ORIG *+1 AND OPCODE
*
*
* SUBROUTINE GETFIELDS
*
* GET THE FIELDS FOR THE ASSEMBLY LANGUAGE.
* FIELDS ARE LABEL, OPCODE AND OPERAND. LABEL
* MAY BE MISSING. REGISTER I5 IS LEFT
* POINTING JUST BEFORE THE OPERAND.
* THE EXPRESSION ROUTINE WILL SKIP ONE COLUMN
* TO BEGIN EVALUATION, SO LEAVE I5 ONE BEFORE
* THE START OF THE OPERAND.
*
* FIXED FIELD
*
GFSAVEA ORIG *+1
*
GETFIELDS STJ GFEXIT SAVE REGISTERS
STA GFSAVEA
ST1 GFSAVE1(0:2)
*
STZ LABEL DEFAULT IS BLANK LABEL
LDA CARD CHECK COLUMN ONE
JAZ NOLABEL
ENT5 0 COLUMN OF LABEL
JMP GETSYM
*
LDA LETTER ERROR CHECKING
JANZ LEGALLABEL
JMP BADSYM NUMERIC SYMBOL
JMP NOLABEL
*
LEGALLABEL ENT1 LABEL MOVE LABEL FROM SYM
MOVE SYM(2)
*
NOLABEL ENT5 11 OPCODE
JMP GETSYM
LDA SYM(1:4) FOUR CHAR OPCODE
STA OP
*
ENT5 15 READY FOR OPERAND
* (COLUMN 17)
*
LDA GFSAVEA
GFSAVE1 ENT1 *
GFEXIT JMP *
*
* TYP
* A MACHINE INSTRUCTION
* B ORIG
* C CON OK
* D ALF OK
* E EQU OK
* F END OK
*
OPTAB EQU *
ALF ADD A
ADD
ALF ALF D
CON 0
ALF CHARA
CHAR
ALF CON C
CON 0
ALF CMPAA
CMPA
ALF CMPXA
CMPX
ALF CMP1A
CMP1
ALF CMP2A
CMP2
ALF CMP3A
CMP3
ALF CMP4A
CMP4
ALF CMP5A
CMP5
ALF CMP6A
CMP6
ALF DECAA
DECA
ALF DECXA
DECX
ALF DEC1A
DEC1
ALF DEC2A
DEC2
ALF DEC3A
DEC3
ALF DEC4A
DEC4
ALF DEC5A
DEC5
ALF DEC6A
DEC6
ALF DIV A
DIV
ALF END F
CON 0
ALF ENNAA
ENNA
ALF ENNXA
ENNX
ALF ENN1A
ENN1
ALF ENN2A
ENN2
ALF ENN3A
ENN3
ALF ENN4A
ENN4
ALF ENN5A
ENN5
ALF ENN6A
ENN6
ALF ENTAA
ENTA
ALF ENTXA
ENTX
ALF ENT1A
ENT1
ALF ENT2A
ENT2
ALF ENT3A
ENT3
ALF ENT4A
ENT4
ALF ENT5A
ENT5
ALF ENT6A
ENT6
ALF EQU E
CON 0
*
HLTINDEX EQU *-OPTAB/2 INDEX OF HLT
ALF HLT A
HLT
ALF IN A
IN
ALF INCAA
INCA
ALF INCXA
INCX
ALF INC1A
INC1
ALF INC2A
INC2
ALF INC3A
INC3
ALF INC4A
INC4
ALF INC5A
INC5
ALF INC6A
INC6
ALF IOC A
IOC
ALF JAN A
JAN
ALF JANNA
JANN
ALF JANPA
JANP
ALF JANZA
JANZ
ALF JAP A
JAP
ALF JAZ A
JAZ
ALF JBUSA
JBUS
ALF JE A
JE
ALF JG A
JG
ALF JGE A
JGE
ALF JL A
JL
ALF JLE A
JLE
ALF JMP A
JMP
ALF JNE A
JNE
ALF JNOVA
JNOV
ALF JOV A
JOV
ALF JREDA
JRED
ALF JSJ A
JSJ
ALF JXN A
JXN
ALF JXNNA
JXNN
ALF JXNPA
JXNP
ALF JXNZA
JXNZ
ALF JXP A
JXP
ALF JXZ A
JXZ
ALF J1N A
J1N
ALF J1NNA
J1NN
ALF J1NPA
J1NP
ALF J1NZA
J1NZ
ALF J1P A
J1P
ALF J1Z A
J1Z
ALF J2N A
J2N
ALF J2NNA
J2NN
ALF J2NPA
J2NP
ALF J2NZA
J2NZ
ALF J2P A
J2P
ALF J2Z A
J2Z
ALF J3N A
J3N
ALF J3NNA
J3NN
ALF J3NPA
J3NP
ALF J3NZA
J3NZ
ALF J3P A
J3P
ALF J3Z A
J3Z
ALF J4N A
J4N
ALF J4NNA
J4NN
ALF J4NPA
J4NP
ALF J4NZA
J4NZ
ALF J4P A
J4P
ALF J4Z A
J4Z
ALF J5N A
J5N
ALF J5NNA
J5NN
ALF J5NPA
J5NP
ALF J5NZA
J5NZ
ALF J5P A
J5P
ALF J5Z A
J5Z
ALF J6N A
J6N
ALF J6NNA
J6NN
ALF J6NPA
J6NP
ALF J6NZA
J6NZ
ALF J6P A
J6P
ALF J6Z A
J6Z
ALF LDA A
LDA
ALF LDANA
LDAN
ALF LDX A
LDX
ALF LDXNA
LDXN
ALF LD1 A
LD1
ALF LD1NA
LD1N
ALF LD2 A
LD2
ALF LD2NA
LD2N
ALF LD3 A
LD3
ALF LD3NA
LD3N
ALF LD4 A
LD4
ALF LD4NA
LD4N
ALF LD5 A
LD5
ALF LD5NA
LD5N
ALF LD6 A
LD6
ALF LD6NA
LD6N
ALF MOVEA
MOVE
ALF MUL A
MUL
ALF NOP A
NOP
ALF NUM A
NUM
ALF ORIGB
CON 0
ALF OUT A
OUT
ALF SLA A
SLA
ALF SLAXA
SLAX
ALF SLC A
SLC
ALF SRA A
SRA
ALF SRAXA
SRAX
ALF SRC A
SRC
ALF STA A
STA
ALF STJ A
STJ
ALF STX A
STX
ALF ST1 A
ST1
ALF ST2 A
ST2
ALF ST3 A
ST3
ALF ST4 A
ST4
ALF ST5 A
ST5
ALF ST6 A
ST6
ALF SUB A
SUB
*
NUMBEROPS EQU *-OPTAB/2 2 LOCATIONS PER ENTRY
*
OPTYPE CON 0
*
VALUE ORIG *+1
*
NSYMBOL CON 0 NUMBER OF SYMBOLS (TIMES 4)
SYMINDEX ORIG *+1
SYMTAB ORIG 4*MAXSYMBOL+* SYMBOL TABLE
*
* SUBROUTINE SEARCH OP
*
* SEARCH THE OPCODE TABLE (OPTAB) FOR THE
* OPCODE IN OP. A BINARY SEARCH IS USED. IF
* THE OPCODE IS NOT FOUND, AN UNOP ERROR
* OCCURS. A HLT IS USED FOR UNOP ERRORS. THE
* VALUE OF THE SECOND WORD IS
* STORED IN VALUE AND THE TYPE OF THE OPCODE
* IN OPTYPE.
*
SOPSAVEA ORIG *+1
SOPSAVEX ORIG *+1
OPHIGH ORIG *+1
OPLOW ORIG *+1
OPMID ORIG *+1
*
SEARCHOP STJ SOPEXIT SAVE REGISTERS
STA SOPSAVEA
STX SOPSAVEX
ST1 SOPSAVE1(0:2)
*
ENT1 NUMBEROPS-1
ST1 OPHIGH
STZ OPLOW INITIALIZE HIGH AND LOW
*
SOPLOOP LDA OPLOW
ADD OPHIGH
SRAX 5
DIV TWO COMPUTE OPMID = (HIGH+LOW)/2
STA OPMID
LD1 OPMID
INC1 0,1 2*OPMID (TWO WORDS PER ENTRY)
*
LDA OPTAB,1(1:4)
CMPA OP COMPARE OPCODES
JE SOPFOUND
*
JL UPLOW
DOWNHIGH LD1 OPMID OP < OPTAB[OPMID]
DEC1 1
ST1 OPHIGH SO HIGH = OPMID - 1
JMP SOPDONE
*
UPLOW LD1 OPMID OP > OPTAB[MID]
INC1 1
ST1 OPLOW SO LOW = OPMID + 1
* JMP SOPDONE
*
SOPDONE LDA OPHIGH CHECK FOR END
CMPA OPLOW
JGE SOPLOOP CHECK FROM LOW TO HIGH
*
JMP UNOP OPCODE NOT FOUND IN OPTAB
ENT1 2*HLTINDEX DEFAULT OPCODE
*
SOPFOUND LDA OPTAB+1,1 NUMERIC OPCODE
STA VALUE
LD1 OPTAB,1(5:5) OPCODE TYPE
ST1 OPTYPE
*
LDA SOPSAVEA RESTORE REGISTERS
LDX SOPSAVEX
SOPSAVE1 ENT1 *
SOPEXIT JMP *
*
*
* SUBROUTINE DEFINESYM
*
* DEFINE A SYMBOL. PUT IT IN THE SYMBOL
* TABLE. THE A REGISTER HAS ITS VALUE. THE
* FORWARD REFERENCE FIELD IS SET TO INDICATE
* NO FORWARD REFERENCES (YET) BY SETTING IT
* TO CHAINED.
*
DEFINESYM STJ DSEXIT SAVE REGISTERS
ST1 DSSAVE1(0:2)
*
LD1 NSYMBOL NEXT SYMBOL TABLE SPACE
STA SYMTAB+2,1 SYMBOL VALUE
LDA SYM
STA SYMTAB,1 FIRST FIVE CHARS
LDA SYM+1
STA SYMTAB+1,1
LDA CHAINEND
STA SYMTAB+3,1(4:5) FORWARD REFERENCE
*
ST1 SYMINDEX SYMBOL INDEX
INC1 4
ST1 NSYMBOL UPDATE NUMBER OF SYMBOLS
*
LDA SYMTAB-2,1 RESTORE A REGISTER
DSSAVE1 ENT1 *
DSEXIT JMP *
*
*
* SUBROUTINE SEARCHSYM
*
* SEARCH SYMBOL TABLE. SYMBOL TABLE
* IS SEARCHED FROM THE BACK TO THE FRONT.
* THE RESULT OF THE SEARCH IS RETURNED IN
* SYMINDEX. SYMINDEX IS AN INDEX INTO SYMTAB
* IF FOUND, OR NEGATIVE
*
SSSAVEA ORIG *+1
SSSAVEX ORIG *+1
*
SEARCHSYM STJ SSEXIT SAVE REGISTERS
STA SSSAVEA
STX SSSAVEX
ST1 SSSAVE1(0:2)
*
LDA SYM
LDX SYM+1 SYMBOL TO SEARCH FOR
LD1 NSYMBOL SYMTAB INDEX
*
SYMLOOP DEC1 4
J1N SYMDONE IF NEGATIVE, NOT FOUND
CMPA SYMTAB,1(1:5) COMPARE
JNE SYMLOOP
CMPX SYMTAB+1,1(1:5) AND COMPARE
JNE SYMLOOP
*
SYMDONE ST1 SYMINDEX EITHER FOUND OR NOT
*
SSSAVE1 ENT1 *
LDA SSSAVEA
LDX SSSAVEX
SSEXIT JMP *
*
*
UNDEFSYM ORIG *+1
NOFORWARD CON 1 NONZERO, NO FORWARDS
*
* UPPER AND LOWER BOUNDS FOR EXPRESSIONS
*
HLBYTE CON 0 INDEX, FIELD
CON 63
HLADDR CON 0 ADDRESSES (ORIG, END)
CON 3999
HL2BYTE CON -4095 ADDRESS FIELD
CON +4095
HLWORD CON -1073741823 MIN AND MAX WORD
CON +1073741823
*
*
OPERATOR ORIG *+44 FIRST 44 ZEROS
CON 1 ADD
CON 2 SUBTRACT
CON 3 MULTIPLY
CON 4 DIVIDE
ORIG *+6
CON 5 COLON OPERATOR
ORIG *+10
*
*
* SUBROUTINE EVALSYM
*
* EVALUATE THE NEXT SYMBOL. VALUE RETURNED
* IN A. UNDEFSYM IS NONZERO IF VALUE IS
* UNDEFINED. SYMBOLS MAY BE *, NUMBER
* OR SYMBOL. GETSYM IS USED TO GET NUMBERS
* OR SYMBOLS.
*
ESSAVEX ORIG *+1
*
EVALSYM STJ ESEXIT SAVE REGISTERS
ST1 ESSAVE1(0:2)
STX ESSAVEX
*
LDA CARD,5 CARD(COLUMN)
CMPA CHARSTAR(5:5) CHECK FOR *
JNE NOTSTAR
*
ISSTAR INC5 1 INCREASE COLUMN COUNTER
ENTA 0,6 VALUE
STZ UNDEFSYM DEFINED
JMP ESQUIT
*
NOTSTAR JMP GETSYM GET SYMBOL
LD1 LETTER
J1NZ ISSYMBOL LETTER NONZERO MEANS SYMBOL
*
ISNUMBER LDA SYM CONVERT SYMBOLIC TO NUMERIC
LDX SYM+1
NUM
JOV EXPOV IF OVERFLOW, ERROR
STZ UNDEFSYM
JMP ESQUIT
*
ISSYMBOL JMP SEARCHSYM SEARCH FOR SYMBOL
LD1 SYMINDEX
J1N ISNOTTHERE NOT IN SYMBOL TABLE
LDA SYMTAB,1
JAN ISNOTDEF IF IN TABLE, NOT DEFINED
*
ISDEFINED LDA SYMTAB+2,1
STZ UNDEFSYM DEFINED
JMP ESQUIT
*
ISNOTTHERE ENTA -1 NOT IN SYMBOL TABLE, ENTER
JMP DEFINESYM ARBITRARY VALUE
LD1 SYMINDEX
STA SYMTAB,1(0:0) MARK NEGATIVE: FORWARD REF
*
ISNOTDEF LDA SYMTAB+3,1 FORWARD REFERENCE
STJ UNDEFSYM(4:5) UNDEFINED VALUE
ST6 SYMTAB+3,1 UPDATE CHAIN ADDRESS
*
ESQUIT EQU *
LDX ESSAVEX
ESSAVE1 ENT1 *
ESEXIT JMP *
*
*
* SUBROUTINE EXPRESSION
*
* EVALUATE THE NEXT EXPRESSION. EXPRESSION
* STARTS AT COLUMN+1 (COLUMN IN I5). (THE
* PLUS ONE IS TO SKIP OVER THE LAST DELIMITER)
* OPERANDS ARE EVALUATED BY EVALSYM.
* OPERATORS ARE + - * / :
* AND ARE APPLIED LEFT TO RIGHT UNTIL A
* DELIMITER IS FOUND.
*
VALUE1 ORIG *+1
VALUE2 ORIG *+1
EXPSAVEX ORIG *+1
*
EXPRESSION STJ EXPEXIT SAVE REGISTERS
ST1 EXPSAVE1(0:2)
ST2 EXPSAVE2(0:2)
STX EXPSAVEX
*
INC5 1
JMP EVALSYM EVALUATE FIRST OPERAND
*
EXPLOOP LD2 CARD,5 CHECK NEXT COLUMN
LD2 OPERATOR,2 FOR OPERATOR
J2NP EXPOVER
*
LD1 UNDEFSYM NO UNDEFS AND OPERATORS
J1NZ FORERROR FORWARD REFERENCE ERROR
*
INC5 1 SKIP OPERATOR
STA VALUE1
JMP EVALSYM SECOND OPERATOR
STA VALUE2
LDA VALUE1
JMP *,2 APPROPRIATE OPERATOR
JMP OPADD
JMP OPSUB
JMP OPMUL
JMP OPDIV
JMP OP8ADD
*
OPADD ADD VALUE2 VALUE1 = VALUE1 + VALUE2
JMP NEXTOP
*
OPSUB SUB VALUE2 VALUE1 = VALUE1 - VALUE2
JMP NEXTOP
*
OPMUL MUL VALUE2 VALUE1 = VALUE1 * VALUE2
JANZ EXPOV IF A NONZERO, OVERFLOW
SLAX 5 PUT VALUE IN A
JMP NEXTOP
*
OPDIV SRAX 5 VALUE1 = VALUE1 / VALUE2
DIV VALUE2
JMP NEXTOP
*
OP8ADD MUL EIGHT VALUE1 = 8*VALUE1 + VALUE2
JANZ EXPOV
SLAX 5
ADD VALUE2
JMP NEXTOP
*
NEXTOP JOV EXPOV CHECK OVERFLOW
JMP EXPLOOP
*
EXPOVER LD1 UNDEFSYM
J1Z EXPQUIT CHECK IF UNDEFINED
LD1 NOFORWARD AND FORWARD REFERENCES
FORERROR J1NZ ILLFOR NOT ALLOWED => ERROR
*
EXPQUIT EQU *
EXPSAVE1 ENT1 * RESTORE INDEX 1
CMPA 0,1 CHECK LOWER BOUND
JGE *+3
JMP EXPOV LESS THAN LOWER
LDA 0,1 REPLACE WITH LOWER
CMPA 1,1 CHECK UPPER
JLE *+3
JMP EXPOV MORE THAN UPPER
LDA 1,1 REPLACE WITH UPPER
*
STJ NOFORWARD(4:5) FORWARDS NOT ALLOWED
*
LDX EXPSAVEX
EXPSAVE2 ENT2 *
EXPEXIT JMP *
*
*
* PRINTER SELECTION FORMAT VARIABLES
*
PRT CON 0 PRINT FORMAT HOLDING VARIABLE
ADR EQU 4:4 PRINT VALUE AS ADDRESS
VAL EQU 3:3 PRINT VALUE AS WORD
INST EQU 2:2 PRINT VALUE AS INSTRUCTION
LOC EQU 1:1 PRINT LOCATION COUNTER
*
PRTFMT CON 0 COMMENT PRINT
CON 1(LOC),1(INST) MACHINE: TYPE 1
CON 1(LOC),1(ADR) ORIG: TYPE 2
CON 1(LOC),1(VAL) CON: TYPE 3
CON 1(LOC),1(VAL) ALF: TYPE 4
CON 1(VAL) EQU: TYPE 5
CON 1(LOC),1(ADR) END: TYPE 6
*
PRTBUF ORIG *+24 PRINTER BUFFER
LINE ORIG *+30 FIRST 30 COLUMNS
* CARD ORIG *+80 CARD IMAGE MULTIPLE DEFINITION
* ORIG *+10 CARD NUMBER
*
PRINTLOC ORIG *+1 LOCATION COUNTER FOR PRT
*
*
* SUBROUTINE OCTCHAR
*
* CONVERTS A NUMBER FROM A NUMERIC FORMAT INTO
* AN OCTAL CHARACTER REPRESENTATION.
* CHARACTERS ARE STORED ONE PER WORD, SIGN FIRST,
* ZERO FILL. THE NUMBER IS IN THE A REGISTER,
* THE NUMBER OF CHARACTERS TO BE USED IN I2
* AND THE ADDRESS IN WHICH THEY SHOULD BE
* STORED IN REGISTER I1.
*
OCSAVEX ORIG *+1
OCTEMPA ORIG *+1
*
OCTCHAR STJ OCEXIT SAVE REGISTERS
STX OCSAVEX
*
STA OCTEMPA SAVE VALUE
STA *+1(0:0) SAVE SIGN FOR TESTING
ENTA 1 PLUS OR MINUS
ENTX 44 PLUS SIGN
JAP STORESIGN
ENTX 45 MINUS SIGN
STORESIGN STX 0,1 FIRST CHARACTER IS SIGN
LDA OCTEMPA(1:5) MAGNITUDE ONLY
*
INC1 0,2 LOW ORDER CHARACTERS FIRST
*
NXTDIGIT SRAX 5 SHIFT TO X FOR DIVIDE
DIV EIGHT OCTAL
INCX 30 X HAS DIGIT, CONVERT TO CHAR
STX 0,1 STORE CHARACTER
*
DEC1 1
DEC2 1 NUMBER OF CHARACTERS
J2P NXTDIGIT
*
LDX OCSAVEX RESTORE REGISTERS
OCEXIT JMP *
*
*