[Conway's game of Life, by Michael Behrend]
[EDSAC program, initial orders 2.]
[vn 042, 2021-10-20]

[EDSAC library subroutine M3 - prints header and is then overwritten.]
            PFGKIFAFRDLFUFOFE@A6FG@E8FEZPF
 @&*GAME!OF!LIFE#N!2021*@&
 VIEW!IN!LONG!TANK!#0*@&
 LOADING!PROGRAM#N!*PLEASE!WAIT@&..
            PZ      [mark end of header]

            T52K    [A parameter: view area, must coincide with a long tank.]
            PF      [0 to view in long tank 0.]

            T53K    [B parameter: buffer for view area.]
            P32F    [32 locations, even address.]

            T50K    [X parameter: once-only code. Can be overwritten after]
            P56F    [execution; at present only 56..63 are overwritten.]

            T46K    [N parameter: constants. Even address.]
            P180F

            T47K    [M parameter: main routine.]
            P250F

            T51K    [G parameter: general-purpose subroutines.]
            P850F

            T54K    [C parameter: cell work area.]
            P950F   [38 locations, even address.]

            T55K    [V parameter: program-wide variables]
            P990F   [4 locations, even address.]

            T48K    [& (delta) parameter: temporary store. Even address.]
            P1000F  [Since long tank 0 is used for the display, we need]
                    [an area to replace the usual workspace in low memory.]

[============================= V parameter ===============================]

[Variables. These may re-use space in initial orders (though they don't]
  [at the moment), so so don't let initial orders write to them.]
      [0]           [35-bit pseudo-random number generated by LCG]
      [2]           [number of live cells]
      [3]           [generation number]

[============================= X parameter ===============================]
            E25KTX
            GK
[Enter here with acc = 0]
[Since display is in long tank 0, we need to write the customary]
[values of 2F and 3F to the area that replaces the lowest addresses.]
      [0]   A33@    [to change address of an order by 1]
            T2&
            A34@    [for subroutine return]
            T3&

[Initialize linear congruential generator (used to create random pattern).]
[Uses old contents of view buffer, so do it before clearing buffer.]
[vn 036 Formerly a s/r in M block, now done inline.]
            T4#&    [clear temp store]
            S21N
      [6]   A36N    [makes order 'A m #B']
            T8@     [plant order]
      [8]   A#B     [load word from buffer]
            A4#&    [add to sum]
            T4#&    [store updated sum]
            A8@     [on to next word in buffer]
            A18N
            S36N    [test for end]
            G6@     [loop back if not]
[Here acc = 0]
            A4#&    [get sum]
            A#V     [add to lcg_x left over from last run]
            T#V     [store as random seed for mew run]
[Clear view buffer (this is necessary)]
            A18@
            G223M
[vn 030 Try clearing view area as well]
            A20@
            GM
[Clear generation number and number of live cells.]
            T&
            T3V
            T2V
[2021-10-05 Now printing menu here, not via M3]
            A101@
            T&
            A27@
            GG
[Call subroutine to get response from user (via phone dial)]
[2021-09-20 S/r to read tape is now called from phone subroutine, not here.]
            A29@
            G237M
            T&
            E41M
     [33]   P1F
     [34]   U2F
[Menu in packed format]
     [35]
            *43DO1415D!1233DA1641DM237DU765D@1539DL961D
            U1123DE297DT313DI1449D#179DW1311DS57DC217D
            H513DS1303DE1607DA971DI1479DS761DE1201DR1609D
            !1015DL551DE281D!1321D!715DL377D*1907DA1437D
            #1803D!1321D!435D*849DG889DG1303DY1201DU1631D
            H193DT623DI1427D!1321D!721DL185D*337DM217D
            #1809D!1321D!627D*313DN1235DM741D&51D*263D
            A1257DF275DM1315DI1607D@1549DO457D!1963DO573D
            E763D!D
    [101]   P35@

[============================= N parameter ===============================]
            E25KTN
            GK

[35-bit constants set up by library subroutine R2]
      [0]   PFPF    [35-bit 1]
[2021-09-24 Parameters for LCG, to generate a random initial pattern]
      [2]   PFPF    [15,319,397 good multiplier for 2^35 (L'Ecuyer)]
      [4]   PFPF    [19,461,217 add-on constant, arbitrary odd value]
[lcg_x has been moved to variables block (V parameter)]
[v_019 2021-10-01 35-bit increments when updating the pattern;]
[trying to speed things up.]
      [6]   PFPF
      [8]   PFPF
     [10]   PFPF
     [12]   PFPF
     [14]   PFPF
     [16]   PFPF

[EDSAC library subroutine R2 (temporary). Fills in the 35-bit constants]
  [above, and is then overwritten by the 17-bit constants below.]
            GKT20FVDL8FA40DUDTFI40FA40FS39FG@S2FG23FA5@T5@E4@E13Z
            T#N
 1F15319397F19461217F554172416F554174498F545785922F2114F1099958338F554176612#
            TZ
[17-bit constants]
     [18]   P2F
     [19]   P8F
     [20]   P16F
     [21]   P32F
     [22]   CF      [add to C order to make A order with same addess]
     [23]   OF      [add to A order to make T order with same addess]
     [24]   &F      [line feed]
     [25]   @F      [carriage return]
     [26]   !F      [space]
     [27]   K4096F  [null char]
     [28]   P35F
     [29]   P36F
     [30]   P37F
     [31]   P38F
     [32]   A36#C
     [33]   T#B
     [34]   A#B
     [35]   A32#B
     [36]   A32#B
     [37]   T32#B
     [38]   A38C    [inc'd from 37 to 38]
     [39]   T38#C   [working with double words]
     [40]   C35C
[For running in simulator with no phone dial]
     [41]   P5F
     [42]   P6F
     [43]   P9F

[============================= M parameter ===============================]
            E25KTM
            GK
[vn 030 Subroutine (formerly inline) to copy view buffer to view area.]
[For greater speed, does not use a loop.]
      [0]   A3&
            T34@
            A#BT#AA2#BT2#AA4#BT4#AA6#BT6#A
            A8#BT8#AA10#BT10#AA12#BT12#AA14#BT14#A
            A16#BT16#AA18#BT18#AA20#BT20#AA22#BT22#A
            A24#BT24#AA26#BT26#AA28#BT28#AA30#BT30#A
     [34]   EF

[Header message '  GEN LIVE', also sets teleprinter to figures.]
[2021-10-05 vn 029 Now a packed message.]
     [35]
            !1311DG237D!1617DV229D&705F
     [40]   P35@

[Main routine]
     [41]   A41@    [copy view buffer to view area]
            G@
[Print generation number and count of live cells.]
[First time here (generation number = 0) print a header.]
            S3V     [test generation number]
            G49@    [skip if > 0]
            A40@
            T&
            A47@    [call s/r to print column headers]
            GG
     [49]   T&      [clear acc]
            A26N    [replace leading zeros by spaces]
            T1&     [pass to print subroutine]
            A3V     [print generation number]
            T&
            A54@
            G30G
[2021-10-08 Use number of live cells to modify LCG.]
[Assume LCG subroutine does not change 0& or 1&.]
            A2V     [load number of live cells]
            T&      [pass to LCG subroutine on 0&]
            A58@
            G217@   [call LCG subroutine]
            A60@
            G30G    [call s/r to print number oflive cells]
            O25NO24N
            A3V     [increment generation number]
            AN
            T3V

[Fall through to update the Life pattern]

[vn_018 2021-09-30 C parameter block inc'd from 37 to 38 words.]
[Want to speed things up a bit by using double words.]
[First clear the work area (C parameter)]
[vn_018 Now done as double words.]
            S31N
     [68]   A39N    [first time makes order 'T #C']
            T70@    [plant in code]
     [70]   T#C     [manufactured order]
            A70@
            A18N    [inc address]
            S39N    [reached (exclusive) end?]
            G68@    [back if not]
[Here with acc = 0]
            T2V     [also reset number of live cells]
[Outer loop: work through the rows y = 0..15]
[followed by build phase for y = 16]
            A34N
            U81@
            A23N
            T188@
[The scan phase, omitted if y = 16]
     [80]   T&
[The following order doubles up as a counter for the outer loop.]
[Exclusive end is 'A 34 B'; the preceding 'A 32 B' is not executed.]
     [81]   A#B     [load word from view buffer: x bits for this y]
            T4#&    [to temp store, will be shifted left to test bits]
            S29N    [vn_020]
[Inner loop. Back here after subtracting addr36 from 'A x #C' order]
     [84]   A32N    [restore 'A x #C'; first time round loop, A 0 #C]
            T102@   [plant in code]
[Dispatch on next 2 bits of dword from view buffer]
            A4#&    [load dword]
            G109@   [jump if top bit is 1]
            LD      [shift next bit into sign bit]
            G93@    [jump if 1]
[Top 2 bits 00 - no action]
            LD
            T4#&    [ready for next time]
            E144@
[Top 2 bits 01]
     [93]   LD
            T4#&    [ready for next time]
            A102@
            A23N
            U104@
            A18N
            U107@
            S23N
            T105@
[The following order doubles up as a counter for the inner loop.]
[Exclusive end is 'A 36 #C'.]
    [102]   A#C
            A6#N
    [104]   T#C
    [105]   A#C
            A8#N
    [107]   T#C
            E144@
[Here if sign bit was 1]
    [109]   LD      [shift next bit into sign bit]
            G128@
[Top 2 bits 10]
    [111]   LD
            T4#&    [ready for next time]
            A102@   [load counter A order (above)]
            U121@   [plant below]
            A23N    [convert to T order, same address]
            U123@   [plant in code]
            A18N    [inc address by 2]
            U126@   [plant in code]
            S23N    [convert to A order]
            T124@   [plant in code]
    [121]   A#C     [load 35-bit cell counts]
            A10#N   [add constant]
    [123]   T#C     [store back]
    [124]   A#C     [repeat for next 35-bit]
            A12#N
    [126]   T#C
            E144@
[Top 2 bits 11]
    [128]   LD
            T4#&    [ready for next time]
            A102@   [update counts, similar to previous case]
            U138@
            A23N
            U140@
            A18N
            U143@
            S23N
            T141@
    [138]   A#C
            A14#N
    [140]   T#C
    [141]   A#C
            A16#N
    [143]   T#C     [fall through to common code]
    [144]   A102@   [load counter order]
            A18N    [inc by 2 now (vn_019)]
            S32N    [test for done]
            G84@    [loop if not done]

[The build phase, omitted if y = 0. Code for build includes shift,]
 [so for y = 0 the shift must be done separately.]
[Building row for next generation in 4#&, no need to initialize it.]
            A34N    [test for y = 0 by looking at counter order]
            S81@
            E193@   [if so, jump to special case]
[vn_023 2021-10-02 New way with moving mask, which also]
[serves as a counter. Mask must move from bit 0 to bit 34;]
[hence we must work backwards in EDSAC memory.]
    [151]   T&      [clear acc]
            T4#&    [initialize word to go into the view buffer]
            A#N     [initialize mask to 00...001]
            T6#&    [use 6#& for mask]
            H214@   [11111 binary, to select lowest count field]
            A40N    [initialize C (collate) order]
    [157]   U162@   [plant C order in code]
            A22N    [A order, same address]
            U176@   [plant in code]
            A23N    [T order, same address]
            T178@   [plant in code]
    [162]   CC      [acc := low count field]
            S216@   [if count < 5 then cell dies]
            G167@
            S215@   [if 5 <= count < 8 then cell lives]
            G169@
[Cell is dead in next generation]
    [167]   T&      [clear acc]
            E176@   [join common code]
[Cell is alive in next generation]
    [169]   T&      [clear acc]
            A4#&    [load partial new row]
            A6#&    [add in mask bit]
            T4#&    [store back]
            A2V     [inc program-wide variable 'nrlive']
            AN
            T2V
[Common code for alive or dead]
    [176]   AC      [do shift here, to avoid overhead of a separate loop]
            R8F     [5 right]
    [178]   TC
            A6#&    [load mask just used]
            G186@   [done if it was bit 34]
            LD      [shift mask 1 left]
            T6#&
            A162@   [on to next location in C block]
            S2&     [working backwards]
            G157@   [always loop back, since C < 0]
[Store the word just built.]
    [186]   T&      [clear acc]
            A4#&
    [188]   T#B
            A188@   [inc address]
            A18N
            T188@
            E205@

[y = 0. Do the shift only.]
    [193]   S30N
    [194]   A38N    [makes 'A C' order first time]
            U198@   [plant in code]
            A23N    [make T order, same address]
            T200@   [plant in code]
    [198]   AC      [load word from C block]
            R8F     [shift 5 right and store back]
    [200]   TC
            A198@   [increment address]
            A2&
            S38N    [test for end]
            G194@   [loop back if not]
[Here with acc = 0]
    [205]   A81@    [inc counter order for y]
            A18N
            U81@
            S35N    [if y < 16, do scan and build]
            G80@
            S18N    [if y = 16, do the build phase only]
            G151@
[Update finished, jump to display result]
            T&      [*** not needed? ***]
            E41@
[Mask for low 5 bits]
    [214]   P15D
    [215]   P1D     [constant 3]
    [216]   P2D     [constant 5]

[-------------------------------------------------------------------]
[Subroutine to use 17-bit value in 0& to modify 35-bit lcg_x.]
[Put in to reduce possibility of repeating the same random values]
  [when the program is run again.]
[*** Contents of 0& and 1& must be preserved. ***]
    [217]   A3&
            T222@
            A&
            A#V
            T#V
    [222]   EF

[-------------------------------------------------------------------]
[Subroutine to clear view buffer (B parameter)]
    [223]   A3&     [plant return link]
            T236@
            A33N    [initialize T order]
            T229@
            S20N    [count := -16]
    [228]   T&      [to temp store]
    [229]   T#B     [clear dword in buffer]
            A229@   [inc address]
            A18N
            T229@
            A&      [inc count]
            A2&
            G228@   [loop till count = 0]
    [236]   EF

[-------------------------------------------------------------------]
[Once-only subroutine to set up initial pattern from phone dial.]
[Dial 0 => get pattern from a separate input tape.]

    [237]   A3&
            T273@
[Halt the program, with acc = 0.]
[When user dials, program restarts with number of pulses in acc (address field)]
            ZF
     ["|A addr5 N|" <------- TEMP for simulator without phone dial]
     ["|A addr5 N|"  twice, for 10 pulses]
[2021-10-08 vn 033 User's choice modifies randomizer]
            T&      [pass number of pulses in 0&]
            A241@   [call s/r to modify randomizer]
            G217@   [(s/r does not change 0&)]
            A&      [get number of pulses again]
            S274@   [if 10 pulses, replace by 0 (the number dialled)]
[2021-09-23 Printing the user's choice]
            E247@   [skip with acc = 0 if so]
            A274@   [restore nr of pulses]
    [247]   U4&     [store number dialled]
            L512F   [shift into top 5 bits]
            T&      [to 0& for printing]
            O&      [print, plus CRLF]
            O25NO24N
            A4&     [acc := number dialled (in address field)]
            S2&     [test for 0, also compensates for table starting at 1]
            G265@   [read from tape if user dialled 0]
            S19N    [test for 9]
            E269@   [random pattern if user dialled 9]
            A275@   [make order to load address from table]
            T260@   [plant in code]
    [260]   AF      [load address]
            T&      [pass to subroutine in 0&]
            A262@   [for s/r return]
            G284@   [call s/r to read hard-coded pattern]
            E272@   [exit]
[Here if user dialled 0.]
[Read initial pattern from 'tape' (i.e. a file, in the simulator).]
    [265]   T&      [acc := 0]
            A266@   [read initial position from tape file]
            G332@
            E273@
[Here if user dialled 9: set up a random initial pattern]
    [269]   T&
            A270@
            G367@
    [272]   T&      [clear acc on exit]
    [273]   EF
    [274]   P10F
[Table of orders to load first word of an initial pattern]
[2021-10-04 vn 027 Addresses only, not A orders]
    [275]   A284@
            P401@
            P432@
            P469@
            P488@
            P521@
            P526@
            P535@
            P544@
    [284]

[-----------------------------------------------------------------------------]
[2021-10-04 vn 027 New way to read hard-coded initial pattern.]
[Imitates reading from a file of 0's and 1's.]
[Caller passes address of a list containing:]
  [number of 0's, number of 1's, number of 0's number of 1's, etc.]
[Number of 0's or 1's is in address field, e.g. P50F for 50 bits.]
[No need to mark end of list; subroutine exits after reading 16 x 35 bits.]
[Memory usage: 0&  = address of list, then dump to clear acc]
                    [1&  = negative count of input bits]
                    [4#& = 35-bit 0 or 1 from input list]
                    [6&  = negative count of output bits]
    [284]   A3&     [plant return link as usual]
            T330@
    [286]   A&      [load address of list]
            A331@   [make S order for that address]
            T303@   [plant in code]
            A#N     [input bit := 1 (gets reversed before first use)]
            T4#&
            T1&     [input count := 0]
            A35N    [A order for exclusive end of view buffer]
            T314@   [plant in code (gets pre-dec'd)]

[Outer loop: here to fill next 35-bit word in view buffer]
    [294]   T&      [clear acc]
            A314@   [decrement buffer addresses in A and T orders]
            S18N
            U314@
            A23N
            T317@
            S28N    [init negative output bit count to -35]
    [301]   T6&     [store negative output bit count]
            E311@   [jump to middle of loop]
[Get new input count from hard-coded list]
    [303]   SF      [manufactured order, loads negative input count]
            T1&     [store count]
            A#N     [load 35-bit 1]
            S4#&    [invert output bit]
            T4#&
            A303@   [advance place in list for next time]
            A2&
            T303@
    [311]   A1&     [load -ve input count]
            E303@   [if no more, back for the next count.]
[(A bit spaghetti, to allow for possibility of a zero count in the list).]
            T&      [clear acc]
    [314]   A#B     [manufactured order, load 35-bit word from view buffer]
            LD      [shift 1 left]
            A4#&    [add input bit]
    [317]   T#B     [manufactured, store back]
            A2V     [update number of live cells]
            A4&     [17-bit add here]
            T2V
            A1&     [update negative input bit count]
            A2&
            T1&
            A6&     [update negative output bit count]
            A2&
            G301@   [inner loop if 35-bit output not complete]
[Here acc = 0, 35-bit word in view buffer is complete]
            A33N    [test for whole view buffer complete]
            S317@
            G294@   [outer loop if not]
    [330]   EF      [manufactured link for return from s/r]
    [331]   SF      [to manufacture S order from address]

[-----------------------------------------------------------------------------]
[2021-09-28 Read a "tape" (text file) in Andrew Clover's format, i.e. a series]
[of 560 chars making the same pattern that will be seen on the oscilloscope.]
  [(assuming 16 rows each of 35 characters).]
[Allow any characters; live or dead determined by bit 0 (1 = live, 0 = dead).]
[This allows e.g. '*' for live and '-' for dead, which is clearer than 1/0.]
[The result is placed in the view buffer (B parameter).]
    [332]   A3&     [plant return link as usual]
            T366@
            T2V     [clear count of live cells]
            H#N     [set mult reg to 35-bit 00...001]
            T4#&    [clear whole of 4#& (including sandwich bit)]
            A35N    [A order for exclusive end of view buffer]
            T353@   [plant in code]
[Outer loop: here to fill next 35-bit word in view buffer.]
[NB We work backwards, since top row of buffer is first to be read.]
    [339]   T&      [clear acc]
            A353@   [dec addresses in A and T orders below]
            S18N
            U353@
            A23N
            T356@
    [345]   S28N    [set negative counter for 35 bits]
[Inner loop: here to get next bit of 35-bit word]
    [346]   T6&     [store updated counter]
    [347]   I4&     [input char to low 5 bits of 4&]
            T&      [clear acc]
            A4&     [load char]
[Formerly had a test here for '0' or '1', ignored character if neither of these.]
[Now allow any chacacter: cell is live (resp. dead) if low bit of 5-bit]
  [character code is 1 (resp. 0). Allows e.g. '*' for live and '-' for dead.]
            T&      [clear acc]
            C4#&    [acc := 35-bit 1 if live]
            T#&     [save 35-bit 0 or 1]
    [353]   A#B     [load current dword from view buffer]
            LD      [shift 1 left, bit 0 := 0]
            A#&     [bit 0 := 1 if live]
    [356]   T#B     [store back]
            A2V     [update number of live cells]
            A&      [add 17-bit 1 if cell is live]
            T2V
            A6&     [inc negative count]
            A2&
            G346@   [if count not yet 0, loop for next bit]
[Here acc = 0. 35-bit word completed]
            A33N    [T order for start of view buffer]
            S356@   [compare with row just done]
            G339@   [back if not last]
    [366]   EF      [exit with acc = 0]

[-----------------------------------------------------------------------------]
[Write a random initial pattern]
[2021-10-08 vn 033 Stop worrying about accumulator overflow.]
[From WWG, 2nd edition (1957),]
['It is sometimes convenient intentionally to program a calculation]
[so that the machine may, at some stage, carry out operations of which]
[the correct result would exceed the capacity of the accumulator.']
    [367]   A3&     [plant returrn link as usual]
            T400@
            T6#&    [reset count of live cells]
[Outer loop to fill view buffer with 16 random 35-bit words.]
[Works backwards.]
            S21N
    [371]   A37N
            T381@
            H2#N
            V#V     [acc := 2^(-34) * a * x)]
            LFLFL64F [13 + 13 + 8 left to give a * x]
            A4#N    [add c, don't worry about overflow]
            U#V     [update LCG x]
            U4#&    [also to temp store for counting 1's]
    [381]   T#B     [also store in view buffer]
[Inner loop to count the number of live cells]
            H#N     [mult reg to test bit 0]
            S28N    [set count to -35]
    [384]   T&      [count in temp store]
            A6#&    [count of live cells]
            C4#&    [collate with word]
            T6#&    [store back]
            A4#&    [shift word right]
            RD
            T4#&
            A&      [inc negative count]
            A2&
            G384@   [loop till done 35 bits]
[Update buffer address (working forwards)]
            A381@
            A18N
            S37N
            G371@   [loop till buffer is filled]
[Here with acc = 0]
            A6&     [number of live cells, low word only]
            T2V
    [400]   EF

[-----------------------------------------------------------------------------]
[Initial patterns.]
[Format imitates reading from a file.]
[Number of 0's, number of 1's, number of 0's, number of 1's, ...,]
  [ending when total count is 560.]
[Counts are in the address field, e.g P50F for a count of 50.]

[Initial pattern 1: Andrew Clover's starting pattern: moves to the left.]
[This is a 'puffer train', see Gardner, 'Wheels, Life, ...' page 248.]
    [401]   P127FP4FP31FP1FP3FP1FP30FP1FP35FP1F
            P2FP1FP2FP2FP32FP3FP27FP1FP2FP1F
            P2FP2FP26FP1FP34FP1FP3FP1FP30FP4F
            P149F
[Initial pattern 2: 2 spaceships]
    [432]   P194FP2FP31FP1FP4FP1FP28FP1F
            P34FP1FP5FP1FP22FP3FP3FP6F
            P23FP1FP2FP1FP31FP1FP34FP1F
            P3FP1FP30FP1FP3FP1FP30FP1F
            P35FP1FP1FP1FP21F
[Initial pattern 3: 3 times 3]
    [469]   P123FP1FP34FP1FP34FP1FP33FP1F
            P34FP1FP34FP1FP33FP1FP34FP1F
            P34FP1FP158F
[Initial pattern 4: 4 gliders]
    [488]   P22FP1FP22FP1FP1FP1FP9FP1F
            P1FP1FP21FP2FP9FP2FP22FP1F
            P326FP1FP22FP2FP9FP2FP21FP1F
            P1FP1FP9FP1FP1FP1FP22FP1F
            P22F
[Initial pattern 5: row of 5, blank, row of 5]
    [521]   P257FP5FP1FP5FP292F
[Initial pattern 6: zigzag 6 (hexonimo)]
    [526]   P226FP1FP34FP2FP34FP2FP34FP1F
            P226F
[Initial pattern 7: heptomino (overflows on generation 73)]
    [535]   P290FP1FP33FP3FP32FP1FP33FP2F
            P165F
[Initial pattern 8: 2 rows of 8]
    [544]   P226FP8FP91FP8FP227F
["---]
[Initial pattern 8: r-pentomino]
[~ipat8 |P307F| |P  2F| |P 32F| |P  2F| |P 34F| |P  1F| |P182F|]
[Initial pattern 8: row of 10]
[~ipat8  |P292F| |P 10F| |P258F|]
[---"]

[============================= G parameter ===============================]
            E25KTG
            GK
[Subroutine to print a packed string.]
[Each 17-bit word holds up to three 5-bit characters in bits 2..16,]
  [the character at the high end being the first to be printed.]
[Bits 0..1 determine how many of the chars are required.]
[This is 3 in each packed word except the last, which has 0, 1, or 2.]
[Caller passes address of packed string in 0& (not preserved).]
[Designed for Life program, vith view in long tank 0.]
[Uses delta parameter to replace low memory.]
      [0]   A3&     [plant return link as usual]
            T26@
            H28@    [set mult reg to select bits 0..1]
      [3]   A&      [load address of caller's message]
            A29@    [make A order for first word]
      [5]   T6@     [plant in code]
      [6]   AF      [load packed chars]
            T4&     [to low word of 4#&]
            A2&     [set marker bit in high word of 4D]
            T5&
            C4&     [acc := character count 0..3]
     [11]   S27@    [test count]
            G25@    [end of string if count has reached 0]
            T1&     [save modded count in 1&]
            O4&     [output packed character]
            A4#&    [shift 4#& 5 left for next character]
            L8F
            G21@    [if marker bit has reached sign bit, go for next word]
            T4#&    [else update 4D]
            A1&     [pick up count]
            E11@    [always loop back, since count >= 0]
[Here for next packed word]
     [21]   T&      [clear acc]
            A6@     [inc address in A order above]
            A2&
            G5@     [always loop back, since A < 0]
[Here when whole string is finished]
     [25]   T&      [clear acc]
     [26]   EF      [return to caller]
[17-bit constants]
     [27]   PD
     [28]   P1D
     [29]   AF

[--------------------------------------------------------------------]
[2021-09-25 Subroutine for printing integers 0..65535.]
[Always prints 5 characters; caller specifies character for leading 0.]
[This version uses a 17-bit multiplier; no need for 35-bit constant.]
[Designed for Life program, vith view in long tank 0.]
[Uses delta parameter to replace low memory.]
[Parameters: 0& = integer to be printed (not preserved)]
                    [1& = character for leading zero]
                    [(preserved; typically null, space or zero)]
[Workspace: 4&..7&]
[38 locations]
[Checked output from this subroutine against output from Delphi program.]
[OK for all numbers 0..65535]
     [30]   A3&
            T64@
            A1&     [char for leading zero]
            T7&     [make local copy]
            S65@    [initialize count to -4]
            T6&
            T4#&    [clear 4&, 5&, sandwich bit]
            A&      [load 17-bit integer to be printed]
            T4&     [make integer double in 4#&]
            H66@    [times 53687]
            V4&     [product in acc]
            RD      [shift 1 right]
            A4#&    [now times 53687.5]
            R1024F  [shift 12 more right]
            H67@    [multiplier := 5/16 for later]
            E53@    [jump into middle of loop]
     [46]   O7&
[Here with negative count in accum address field]
     [47]
            A2&     [inc count]
            T6&
            T5&     [clear digit]
            V4#&
            YF      [this is needed (empiricsl)]
            L8F     [shift 5 left]
     [53]   T4#&
            A5&     [should be top digit]
            L1024F  [shift 12 left to top end]
[Now want to suppress leading 0 (unless input is 0)]
            U&      [store digit in 0&]
            A6&
            G46@    [jump if digit = 0 and count < 0]
            O&
            T&
            T7&
            A6&
            G47@
     [64]   ZF
     [65]   P4F     [initial digit count]
     [66]   Z219D   [53687, where 2^29/10000 = 53687.0912]
     [67]   TF      [5/16]

[========================== X parameter again ============================]
            E25KTX
            GK
            EZ      [define entry point]
            PF      [enter with acc = 0]
[end]

