Skip to content

Instantly share code, notes, and snippets.

@shirriff
Created September 2, 2019 16:21
Show Gist options
  • Save shirriff/4b3c50ec23715552cb511fb5512b7ca9 to your computer and use it in GitHub Desktop.
Save shirriff/4b3c50ec23715552cb511fb5512b7ca9 to your computer and use it in GitHub Desktop.
Disassembly of a vintage program to generate music on an IBM 1403 line printer.
87 00000 # X0
92 00000 # X1
97 000 # X2
100 ,001 set wordmark 1 # Start
104 /000 clear storage 0 # Wraps to top of memory?
108 H099 store B* 99 # Top of memory - 100? into X2
112 L/49089 load 1149 89 # X1 = 0
119 L/49094 load 1149 94 # X2 = 0
126 1 read # READNOTE: Read first card
127 C003/53 compare 3 1153 # Card has END?
134 B334S branch 334 S # Branch if equal to READNOTES:
139 M0996J5 move 99 615(X1) # line table[X1] = X2
146 B165D branch 165 D # if sense D set, branch to SENSED: numeric mode?
151 L/54354 load 1154 354 # Replace NOP with BRANCH
158 M0756J1 move 75 611(X1) # Store note name in table
165 A/56094 add 1156 94 # SENSED: X1 = X1 + 10 (10 is length of table entry)
172 M0660?0 move 66 0(X2) # *X2 = 66 character from card (i.e. half the print line)
179 H099 store B* 99 # X2 = left of line
183 1 read # Read second card
184 L0660?0 load 66 0(X2) # *X2 = 66 characters from card and word mark
191 H099 store B* 99 # X2 = left of line
195 A/57089 add 1157 89 # X0 = X0 + 1
202 C089/59 compare 89 1159 # if X0 < 21:
209 B126U branch 126 U # then branch to READNOTE:
214 .100 stop # else stop. Should have hit END card.
334 M585099 move 585 99 # READNOTES: END card read: X2 = /99 = 1199
341 /332 clear storage 332
345 / clear storage # Clear 200 to 332, i.e. print buffer. Note: previous code overlapped print buffer.
346 ,005201 set wordmark 5 201 # Set word marks at 5 and 201 (start of print buffer)
353 1 read # READTUNE: Read card
354 N372 no operation 372 # Modifed: if sense D not set, branch to READDONE
358 M002005 move 2 5 # card[5] = card[2] # Numeric format: move number to position 5
365 M/60002 move 1160 2 # card[2] = ' '
372 B564001X branch 564 1 X # READDONE: If first char 'X', branch to DOIT1:
380 B353001 branch 353 1 # If first char ' ', branch to READTUNE:
388 B503001R branch 503 1 R # If first char 'R' (rest), branch to LOOKUPREST:
396 L/49089 load 1149 89 # X0 = 0
# Find card[2:3] in the table of notes
403 C0036/1 compare 3 611(X0) # MATCHNOTE: Compare card[2:3] to table[X0] (entries for 1 to 20)
410 B438S branch 438 S # if equal, branch to LOOKUPNOTE:
415 A/56089 add 1156 89 # X0 += 10 (length of table entry)
422 C089094 compare 89 94
429 B403U branch 403 U # if X0 < X1, branch to MATCHNOTE:
434 .100 stop # Bad card? Stop.
438 L6/80?7 load 618(X0) 7(X2) # LOOKUPNOTE: *X2 = table[X0] (7-char load instruction for note line)
445 L/49089 load 1149 89 # X0 = 0
452 A005089 add 5 89 # X0 += card pos 5
459 A005089 add 5 89 # X0 += card pos 5
466 A005089 add 5 89 # X0 += card pos 5
473 A005089 add 5 89 # X0 += card pos 5, i.e. X0 = card[5] * 4
480 L8‡90A1 load 809(X0) 11(X2) # X2[11] = 809[card pos 5]. Jump table for note duration
487 A/62099 add 1162 99 # X2 += 11
494 B564A branch 564 A # MAYBEDOIT1: if sense switch A, branch to DOIT:
499 B353 branch 353 # else branch to READTUNE:
503 ,002 set wordmark 2 # LOOKUPREST: set wordmark on 2nd char in read buffer
507 L/49089 load 1149 89 # X0 = 0
514 A002089 add 2 89 # X0 += card pos 2
521 A002089 add 2 89 # X0 += card pos 2
528 A002089 add 2 89 # X0 += card pos 2
535 A002089 add 2 89 # X0 += card pos 2, i.e. X0 = card[2] * 4
542 ⌑002 clear wordmark 2
546 L‡/60?4 load 1016(X0) 4(X2) # X2[4] = 1016[X0]: Get branch instruction from rest jump table
553 A/63099 add 1163 99 # X2 += 4
560 B494 branch 494 # Branch to MAYBEDOIT1:
564 L5890?4 load 589 4(X2) # DOIT1: X2[4] = 'branch 590'
571 ,0?5 set wordmark 5(X2) # Set wordmark on X2[5]
575 L/64/99 load 1164 1199 # *1199 = 'N' (nop)
582 B/99 branch 1199 # DOIT2: branch to generated instruction sequence at 1199.
# For a note, code starting at 1199: N Lxxx332 Byyy B590. xxx is line pointer, loaded into print buffer at 201-332. yyy is note duration e.g. 846
# For a rest, code starting at 1199: N Bxxx B 590. xxx is e.g. 1053, rest code.
586 B590 branch 590 # Branch instruction to NOTEDONE: copied into X2 buffer
590 B599B branch 599 B # NOTEDONE: If not sense switch B,
595 .582 stop # then stop, continue at DOIT2:
599 B334C branch 334 C # F: if sense switch C, branch to READNOTES:
604 B582 branch 582 # Branch to DOIT2:
608 N no operation
609 1 # Note table: name can be overwritten with name from card e.g. G5
612 L000332 load 0 332 # Note table: addresses filled in to point to lines
619 2
622 L000332 load 0 332 # 332 is end of print buffer
629 3
632 L000332 load 0 332
639 4
642 L000332 load 0 332
649 5
652 L000332 load 0 332
659 6
662 L000332 load 0 332
669 7
672 L000332 load 0 332
679 8
682 L000332 load 0 332
689 9
692 L000332 load 0 332
699 010
702 L000332 load 0 332
709 011
712 L000332 load 0 332
719 012
722 L000332 load 0 332
729 013
732 L000332 load 0 332
739 014
742 L000332 load 0 332
749 015
752 L000332 load 0 332
759 016
762 L000332 load 0 332
769 017
772 L000332 load 0 332
779 018
782 L000332 load 0 332
789 019
792 L000332 load 0 332
799 020
802 L000332 load 0 332
809 N no operation
810 B846 branch 846 # Duration table entry 1. Branch to DURATION1:
814 B862 branch 862 # Branch to DURATION2:
818 B878 branch 878 # Branch to DURATION3:
822 B894 branch 894 # Branch to DURATION4:
826 B910 branch 910 # Branch to DURATION5:
830 B926 branch 926 # Branch to DURATION6:
834 B942 branch 942 # Branch to DURATION7:
838 B958 branch 958 # Branch to DURATION8:
842 B974 branch 974 # Branch to DURATION9:
# Entry points to play a note of particular duration
846 H099 store B* 99 # DURATION1: X2 = return addr, i.e. 1211 holding branch to 590 NOTEDONE:
850 B854 branch 854 # Branch to next instruction to set up B*
854 H‡07 store B* 1007 # Store 854 (i.e. this address) in LOOPPRINT:
858 B994 branch 994 # Branch to PRINT1
862 H099 store B* 99 # DURATION2: X2 = addr
866 B870 branch 870
870 H‡07 store B* 1007 # Store addr in LOOPPRINT:
874 B993 branch 993 # Branch to PRINT2
878 H099 store B* 99 # DURATION3: X2 = addr
882 B886 branch 886
886 H‡07 store B* 1007 # Store addr in LOOPPRINT:
890 B992 branch 992 # Branch to PRINT3
894 H099 store B* 99 # DURATION4: X2 = addr
898 B902 branch 902 # Branch to
902 H‡07 store B* 1007 # Store addr in LOOPPRINT:
906 B991 branch 991 # Branch to PRINT4
910 H099 store B* 99 # DURATION5: X2 = addr
914 B918 branch 918 # Branch to
918 H‡07 store B* 1007 # Store addr in LOOPPRINT:
922 B990 branch 990 # Branch to PRINT5
926 H099 store B* 99 # DURATION6: X2 = addr
930 B934 branch 934
934 H‡07 store B* 1007 # Store addr in LOOPPRINT:
938 B989 branch 988 # Branch to PRINT7
942 H099 store B* 99 # DURATION7: X2 = addr
946 B950 branch 950
950 H‡07 store B* 1007 # Store addr in LOOPPRINT:
954 B988 branch 988 # Branch to PRINT8
958 H099 store B* 99 # DURATION8: X2 = addr
962 B966 branch 966
966 H‡07 store B* 1007 # Store addr in LOOPPRINT:
970 B987 branch 987 # Branch to PRINT9
974 H099 store B* 99 # DURATION9: X2 = addr
978 B982 branch 982
982 H‡07 store B* 1007 # Store addr in LOOPPRINT:
986 2 print # PRINT9
987 2 print # PRINT8
988 2 print # PRINT7
989 2 print # PRINT6
990 2 print # PRINT5
991 2 print # PRINT4
992 2 print # PRINT3
993 2 print # PRINT2
994 2 print # PRINT1
995 B‡04G branch 1004 G # if sense switch G, goto LOOPPRINT:
1000 B‡08 branch 1008 # else goto CARRIAGE:
1004 B000 branch 0 # LOOPPRINT: loop address stored here
1008 FJ control carriage J # CARRIAGE: one line
1010 FJ control carriage J # one line
1012 B0?0 branch 0(X2) # Return (to X2) i.e. NOTEDONE:
1016 N no operation
1017 B‡53 branch 1053 # Rest jump table entry 1. Branch REST1:
1021 B‡68 branch 1068 # Branch REST2:
1025 B‡83 branch 1083 # Branch REST3:
1029 B‡98 branch 1098 # Branch REST4:
1033 B‡98 branch 1098 # Branch REST4:
1037 B/13 branch 1113 # Branch REST5:
1041 B/13 branch 1113 # Branch REST5:
1045 B/13 branch 1113 # Branch REST5:
1049 B/13 branch 1113 # Rest jump table entry 9. Branch REST5:
1053 H099 store B* 99 # REST11: X2 = B*, i.e. return address 1205 holding branch to 590 NOTEDONE:
1057 ?/67/71 zero and add 1167 1171 # *1171 = +250: rest loop for 250 counts
1064 B/24 branch 1124 # Branch RESTLOOP:
1068 H099 store B* 99 # REST2: X2 = B*
1072 ?/74/71 zero and add 1174 1171 # *1171 = +500
1079 B/24 branch 1124 # Branch RESTLOOP:
1083 H099 store B* 99 # REST3: X2 = B*
1087 ?/77/71 zero and add 1177 1171 # *1171 = +750
1094 B/24 branch 1124 # Branch RESTLOOP:
1098 H099 store B* 99 # REST4: X2 = B*
1102 ?/81/71 zero and add 1181 1171 # *1171 = +1000
1109 B/24 branch 1124 # Branch RESTLOOP:
1113 H099 store B* 99 # REST5: X2 = B*
1117 ?/85/71 zero and add 1185 1171 # *1171 = +2000
1124 S/86/71 subtract 1186 1171 # RESTLOOP: *1171 -= +1
1131 C/50/71 compare 1150 1171 # Compare +0001 to 1171
1138 B/24U branch 1124 U # Branch if B higher to RESTLOOP:
1143 B0?0 branch 0(X2) # Return to X2, i.e. NOTEDONE:
1147 000A # +0001
1151 END # 'END'
1154 B # Branch
1155 10 # 10 (table length inc)
1157 1 # 1 (increment)
1158 21 # 21 (loop limit)
1160 # ' '
1161 11 # 11
1163 4 # 4
1164 N # NOP
1165 25? # +250
1168 # Rest timing counter
1172 50? # +500
1175 75? # +750
1178 100? # +1000
1182 200? # +2000
1186 A # +1
1199 # Holds instruction.
1207 # Jump table branch here 1207-1210
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment