Text File

[Life by Andrew Clover]

[ Print program heading using library routine M3 ]

PFGKIFAFRDLFUFOFE@A6FG@E8FEZPF

*@&GAME!OF!LIFE@&OUTPUT!ON!LONG!TANK!#31*@&PRESS!RESET!FOR!NEXT!GENERATION@&@& GEN!#0*@&..

[ ] P Z [ ] [ ] T 56 K [ ] [ ] G K [ Load at 56 upwards ] [ ] T 44 K [ Write to initial orders' parameters ] [ ] P @ [ Set ! parameter (subroutines) ] [ ] P 168 ! [ Set H parameter (main program) ] [ ] P 100 H [ Set N parameter (constants) ] [ ] P 22 N [ Set M parameter (variables) ] [ ] T Z [ Restore load point ]

[ Subroutines -------------------------------------------------------------- ! ]

[ Library routine P6 (print short integer) ] [ on entry: | 0 D | integer to print ]

[ 0 ] A 3 F [ ] [ 1 ] T 25 @ [ Plant link ] [ 2 ] H 29 @ [ ] [ 3 ] V F [ Multiply by 2^16/10 ] [ 4 ] T 4 D [ ] [ 5 ] A 3 @ [ V F = -1/16 to S(0) ] [ 6 ] T F [ ] [ 7 ] H 30 @ [ Set multiplier ] [ 8 ] S 6 @ [ Set digit count ] [ 24 -> 9 ] T 1 F [ Digit count ] [ 10 ] V 4 D [ Multiply ] [ 11 ] U 4 D [ ] [ 12 ] A F [ Test for first ] [ 13 ] G 26 @ [ non-zero digit ] [ 14 ] T F [ Clear Acc. and S(0)* ] [ 15 ] T F [ ] [ 16 ] O 5 F [ Print ] [ 17 ] A 4 D [ ] [ 18 ] F 4 F [ Check and remove ] [ 19 ] S 4 F [ ] [ 28 -> 20 ] L 4 F [ Shift ] [ 21 ] T 4 D [ ] [ 22 ] A 1 F [ ] [ 23 ] S 3 @ [ Count digits ] [ 24 ] G 9 @ [ ] [ 25 | ]E F[ | Link ] [ |------------| ] [ 13 -> 26 ] S F [ Add 1/16 ] [ 27 ] O 31 @ [ Space ] [ 28 ] E 20 @ [ ] [ |------------| ] [ 29 |] J 995 F [ = 2^16/10^5 ] [ 30 |] J F [ = 10/16 ] [ 31 |] ! F [ Space ]

[ Calculate cell position subroutine ] [ on entry: | 1 M | X co-ordinate ] [ | 2 M | Y co-ordinate ] [ | 3 M | X co-ordinate offset (added to 1 M before use) ] [ | 4 M | Y co-ordinate offset ] [ on exit: | 6#M | Bit position of cell in word ] [ | 12 M | Order offset to use to access word containing cell ]

[ 32 ] A 3 F [ ] [ 33 ] T 61 @ [ Plant return link ] [ 34 ] A 1 M [ ] [ 35 ] A 3 M [ Get X co-ordinate ] [ 36 ] E 39 @ [ ] [ 37 ] A 5 N [ ] [ 38 ] E 42 @ [ Wraparound if X<0 ] [ 36 -> 39 ] S 5 N [ ] [ 40 ] E 42 @ [ ] [ 38, 41 ] A 5 N [ Wraparound if X>34 ] [ 40 -> 42 ] T 13 M [ ] [ 43 ] A 5 N [ ] [ 44 ] S N [ ] [ 45 ] S 13 M [ Get bit position = 34-X ] [ 46 ] L 1 F [ Multiply by four to get order offset ] [ 47 ] A 17 N [ ] [ 48 ] T 49 @ [ Plant load-word-from-shift-lookup-table order ] [ 49 | ]A #M[ | Load long word from M+14+2*(34-X) ] [ 50 ] T 6#M [ Store as bit position of cell ] [ 51 ] A 2 M [ ] [ 52 ] A 4 M [ Get Y co-ordinate ] [ 53 ] E 56 @ [ ] [ 54 ] A 6 N [ ] [ 55 ] E 59 @ [ Wraparound if Y<0 ] [ 53 -> 56 ] S 6 N [ ] [ 57 ] E 59 @ [ ] [ 55, 58 ] A 6 N [ Wraparound if Y>15 ] [ 57 -> 59 ] L 1 F [ Multiply Y by four ] [ 60 ] T 12 M [ Store as order offset from start of tank ] [ 61 | ]E F[ | Link ] [ |------------| ]

[ Check cell subroutine ] [ on entry: | 1-4 M | Co-ordinates as in calculate cell position ] [ on exit: | 5 M | Incremented if cell is 'alive' ]

[ 62 ] A 3 F [ ] [ 63 ] T 80 @ [ Plant return link ] [ 64 ] A 64 @ [ ] [ 65 ] G 32 ! [ Find address/bit for cell ] [ 66 ] A 16 N [ ] [ 67 ] A 12 M [ ] [ 68 ] T 69 @ [ Plant load-word order ] [ 69 | ]H D[ | Load word from tank 31 ] [ 70 ] C 6#M [ Isolate the bit for the cell concerned ] [ 71 ] S 6#M [ Subtract bit - accumulator now zero if bit set ] [ 72 ] G 79 @ [ If accumulator negative non-zero, return ] [ 73 ] S N [ Decrement accumulator ] [ 74 ] E 79 @ [ If accumulator is still +ve, then it was non-zero ] [ 75 ] T F [ ] [ 76 ] A 5 M [ ] [ 77 ] A N [ ] [ 72, 78 ] T 5 M [ Increment living-neighbours counter ] [ 74 -> 79 ] T F [ Make sure accumulator is clear ] [ 80 | ]E F[ | Link ] [ |------------| ]

[ Set cell subroutine ] [ on entry: | 1-4 M | Co-ordinates ] [ | 10#M | 0 to set cell to 'dead', -1 to set cell 'alive' ]

[ 81 ] A 3 F [ ] [ 82 ] T 99 @ [ Plant return link ] [ 83 ] A 83 @ [ ] [ 84 ] G 32 ! [ Find address/bit for cell ] [ 85 ] A 15 N [ ] [ 86 ] A 12 M [ ] [ 87 ] T 94 @ [ Plant load-word order ] [ 88 ] A 11 N [ ] [ 89 ] A 12 M [ ] [ 90 ] T 98 @ [ Plant store-word order ] [ 91 ] S 6#M [ ] [ 92 ] S #N [ ] [ 93 ] T 8#M [ Form one's complement of cell bit ] [ 94 | ]H D[ | Load word from tank 30 to multiplier ] [ 95 ] C 8#M [ Clear bit in word using AND one's complement ] [ 96 ] H 6#M [ ] [ 97 ] C 10#M [ OR in the new value of the bit ] [ 98 | ]T D[ | Store new word back to tank 31 ] [ 99 | ]E F[ | Link ] [ |------------| ]

[ Make shift lookup table subroutine ] [ on exit: | 14-44#M | Filled with bit positions ]

[ 100 ] A 3 F [ ] [ 101 ] T 122 @ [ Plant return link ] [ 102 ] A #N [ ] [ 103 ] T 14#M [ Store bit 0 set in first word of shift lookup table ] [ 104 ] A 17 N [ ] [ 105 ] T 110 @ [ ] [ 106 ] A 103 @ [ ] [ 107 ] A 4 N [ ] [ 108 ] T 112 @ [ Initialise loop orders ] [ 120-> 109 ] T F [ ] [ 110 | ]A #M[ | Load previous bit pattern ] [ 111 ] L D [ 1<<n for next n ] [ 112 | ]T #M[ | Store in next table entry ] [ 113 ] A 110 @ [ ] [ 114 ] A 4 N [ ] [ 115 ] T 110 @ [ Add 2 to loop load order address ] [ 116 ] A 112 @ [ ] [ 117 ] A 4 N [ ] [ 118 ] U 112 @ [ Add 2 to loop store order address ] [ 119 ] S 18 N [ ] [ 120 ] G 109 @ [ Loop until end of table reached ] [ 121 ] T F [ ] [ 122 | ]E F[ | Link ] [ |------------| ]

[ Read initial data subroutine ] [ on exit: |992-1022#M | Filled with bit patterns read from punched tape ]

[ 123 ] A 3 F [ ] [ 124 ] T 165 @ [ Plant return link ] [ 125 ] A 20 N [ ] [ 126 ] T 158 @ [ Plant initial word store order in Y loop ] [ 163-> 127 ] T F [ ] [ 128 ] T 1 M [ Initialise X loop variable ] [ 139, 129 ] T 6#M [ Start each X loop with zero sum word ] [ 155-> 130 ] T F [ ] [ 131 ] A 6#M [ ] [ 132 ] L D [ ] [ 133 ] T 6#M [ Double sum word each time around loop ] [ 134 ] I 3 M [ ] [ 135 ] A 3 M [ Get character from tape ] [ 136 ] S 6 N [ ] [ 137 ] G 140 @ [ ] [ 138 ] S N [ ] [ 139 ] G 130 @ [ If blank character, go back and read another ] [ 137-> 140 ] T F [ ] [ 141 ] A 3 M [ ] [ 142 ] S 2 N [ ] [ 143 ] E 166 @ [ Else check for validity - must be 0 or 1 ] [ 144 ] A N [ ] [ 145 ] G 150 @ [ Check for it being '1' ] [ 146 ] T F [ ] [ 147 ] A 6#M [ ] [ 148 ] A #N [ ] [ 149 ] T 6#M [ If it is, add 1 to sum word ] [ 145-> 150 ] T F [ ] [ 151 ] A 1 M [ ] [ 152 ] A N [ ] [ 153 ] U 1 M [ Increment X ] [ 154 ] S 5 N [ ] [ 155 ] G 130 @ [ Loop if X<35 ] [ 156 ] T F [ ] [ 157 ] A 6#M [ ] [ 158 | ]T D[ | Copy word to screen ] [ 159 ] A 158 @ [ ] [ 160 ] S 4 N [ ] [ 161 ] U 158 @ [ Subtract 2 from address in word store order ] [ 162 ] S 21 N [ ] [ 163 ] E 127 @ [ And loop if we haven't filled the screen yet ] [ 164 ] T F [ ] [ 165 | ]E F[ | Link ] [ |------------| ] [ 166 ] Z F [ Error condition ] [ 167 ] Z F [ Padding to long-word boundary ]

[ Main program ------------------------------------------------------------- H ]

[ enter ] G K [ ] [ -> 0 ] O 7 N [ Figure shift - all output is numerical ] [ 1 ] A 1 @ [ ] [ 2 ] G 100 ! [ Create shift lookup table ] [ 3 ] A 3 @ [ ] [ 4 ] G 123 ! [ Read in the data for the zeroth generation ] [ 99 -> 5 ] T F [ Clear accumulator ] [ 6 ] Z F [ Ring and wait between each generation ]

[ Process cells from screen (tank 31) to tank 30 ]

[ 7 ] T 1 M [ ] [ 67, 8 ] T 2 M [ Initialise X and Y loop variables ] [ 74 -> 9 ] T F [ ] [ 10 ] T 5 M [ Initialise count of alive neighbour cells ] [ 11 ] S N [ ] [ 12 ] U 3 M [ ] [ 13 ] T 4 M [ ] [ 14 ] A 14 @ [ ] [ 15 ] G 62 ! [ Check cell (X-1, Y-1) ] [ 16 ] T 3 M [ ] [ 17 ] A 17 @ [ ] [ 18 ] G 62 ! [ Check cell (X, Y-1) ] [ 19 ] A N [ ] [ 20 ] T 3 M [ ] [ 21 ] A 21 @ [ ] [ 22 ] G 62 ! [ Check cell (X+1, Y-1) ] [ 23 ] A N [ ] [ 24 ] T 4 M [ ] [ 25 ] A 25 @ [ ] [ 26 ] G 62 ! [ Check cell (X+1, Y+1) ] [ 27 ] T 3 M [ ] [ 28 ] A 28 @ [ ] [ 29 ] G 62 ! [ Check cell (X, Y+1) ] [ 30 ] S N [ ] [ 31 ] T 3 M [ ] [ 32 ] A 32 @ [ ] [ 33 ] G 62 ! [ Check cell (X-1, Y+1) ] [ 34 ] T 4 M [ ] [ 35 ] A 35 @ [ ] [ 36 ] G 62 ! [ Check cell (X-1, Y) ] [ 37 ] A N [ ] [ 38 ] T 3 M [ ] [ 39 ] A 39 @ [ ] [ 40 ] G 62 ! [ Check cell (X+1, Y) ] [ 41 ] T 3 M [ Reset cell offset to (0,0) ] [ 42 ] A 5 M [ ] [ 43 ] S 4 N [ ] [ 44 ] E 55 @ [ If more than 3 neighbour cells, cell dies ] [ 45 ] A 2 N [ ] [ 46 ] G 55 @ [ If fewer than 2 neighbour cells, cell dies ] [ 47 ] S N [ ] [ 48 ] E 58 @ [ If exactly 3 neighbour cells, cell lives ] [ 49 ] T F [ ] [ 50 ] A 50 @ [ ] [ 51 ] G 62 ! [ 2 neighbour cells -> must check cell (X, Y) ] [ 52 ] A 5 M [ ] [ 53 ] S 3 N [ If there are now 3 cells, then current cell alive ] [ 44, 54 ] E 58 @ [ If cell is alive it stays alive else stays dead ] [ 46 -> 55 ] T F [ ] [ 56 ] T 10#M [ ] [ 57 ] E 61 @ [ Set cell value parameter to 0 (clear) ] [ 48, |------------| ] [ 54 -> 58 ] T F [ ] [ 59 ] S #N [ ] [ 60 ] T 10#M [ Set cell value parameter to long -1 (set) ] [ 57 -> 61 ] A 61 @ [ ] [ 62 ] G 81 ! [ Set cell value ] [ 63 ] A 1 M [ ] [ 64 ] A N [ ] [ 65 ] U 1 M [ Increment X variable ] [ 66 ] S 5 N [ ] [ 67 ] G 9 @ [ If X<35 loop ] [ 68 ] T F [ ] [ 69 ] T 1 M [ Else reset X to 0 ] [ 70 ] A 2 M [ ] [ 71 ] A N [ ] [ 72 ] U 2 M [ And increment Y variable ] [ 73 ] S 6 N [ ] [ 74 ] G 9 @ [ If Y<16 loop ]

[ Copy new life pattern to screen (tank 31) ]

[ 75 ] A 10 N [ ] [ 76 ] T 80 @ [ ] [ 77 ] A 13 N [ ] [ 78 ] T 81 @ [ Initialise loop orders ] [ 89 -> 79 ] T F [ ] [ 80 | ]A F[ | ] [ 81 | ]T F[ | Copy 35-bit word from tank 30 to tank 31 ] [ 82 ] A 80 @ [ ] [ 83 ] A 4 N [ ] [ 84 ] T 80 @ [ Add 2 to loop load order address ] [ 85 ] A 81 @ [ ] [ 86 ] A 4 N [ ] [ 87 ] U 81 @ [ Add 2 to loop store order address ] [ 88 ] S 14 N [ Compare store order to overflow condition ] [ 89 ] G 79 @ [ If less than this, loop ]

[ Print generation number ]

[ 90 ] T F [ ] [ 91 ] A M [ Get generation number ] [ 92 ] U F [ Store as parameter ] [ 93 ] A N [ ] [ 94 ] T M [ Increment generation number ] [ 95 ] A 95 @ [ ] [ 96 ] G ! [ Output old generation number ] [ 97 ] O 8 N [ ] [ 98 ] O 9 N [ Output newline ] [ 99 ] E 5 @ [ Next iteration ] [ |------------| ]

[ Constants ---------------------------------------------------------------- N ]

[ 0 |] P D [ 1 short/long ] [ 1 |] P F [ ] [ 2 |] P 1 F [ 2 ] [ 3 |] P 1 D [ 3 ] [ 4 |] P 2 F [ 4 ] [ 5 |] P 17 D [ 35 ] [ 6 |] P 8 F [ 16 ] [ 7 |] # F [ FS ] [ 8 |] @ F [ CR ] [ 9 |] & F [ LF ] [ 10 |] A 960 D [ Base order for tank 30 load ] [ 11 |] T 960 D [ Base order for tank 30 store ] [ 12 |] A 992 D [ Base order for tank 31 load ] [ 13 |] T 992 D [ Base order for tank 31 store ] [ 14 |] T 1024 D [ Final order for tank-copy loop ] [ 15 |] H 960 D [ Base order for tank 30 load-to-multiplier ] [ 16 |] H 992 D [ Base order for tank 31 load-to-multiplier ] [ 17 |] A 14#M [ Base order for load-word-from-shift-lookup-table ] [ 18 |] T 84#M [ Final order for make-shift-lookup-table loop ] [ 19 |] P F [ Padding ] [ 20 |] T 1022 D [ Initial order for data input loop ] [ 21 |] T 994 D [ Final order for data input loop ]

[ Variables ---------------------------------------------------------------- M ]

[ 0 |] P D [ Generation number, initially 1 ] [ 1 |] [ X loop variable ] [ 2 |] [ Y loop variable ] [ 3 |] [ X offset parameter ] [ 4 |] [ Y offset parameter ] [ 5 |] [ Neighbour cell count ] [ 6 |] [ ] [ 7 |] [ Bit position of cell in word ] [ 8 |] [ ] [ 9 |] [ One's complement of bit position (set cell) ] [ 10 |] [ ] [ 11 |] [ Long value to set cell to (all 0 or all 1) ] [ 12 |] [ Transfer order offset for cell position ] [ 13 |] [ Temporary variable in shift lookup ] [ 14 |] [ Shift lookup table ] [ 46 ] [ End of program ]

[ ] E Z [ Run program at @ (=H) ] [ ] P F [ ]

[ Generation zero bitmap ----------------------------------------------------- ]

00000000000000000000000000000000000 00000000000000000000000000000000000 00000000000000000000000000000000000 00000000000000111100000000000000000 00000000000000100010000000000000000 00000000000000100000000000000000000 00000000000000010010011000000000000 00000000000000000000111000000000000 00000000000000010010011000000000000 00000000000000100000000000000000000 00000000000000100010000000000000000 00000000000000111100000000000000000 00000000000000000000000000000000000 00000000000000000000000000000000000 00000000000000000000000000000000000 00000000000000000000000000000000000