261 lines
10 KiB
Plaintext
261 lines
10 KiB
Plaintext
[Hailstone (or Collatz) task for Rosetta Code.
|
|
EDSAC program, Initial Orders 2.]
|
|
|
|
[This program shows how subroutines can be called via the
|
|
phi, H, N, ..., V parameters, so that the code doesn't have
|
|
to be changed if the subroutines are moved about in store.
|
|
See Wilkes, Wheeler and Gill, 1951 edition, page 18.]
|
|
|
|
[Library subroutine P7, prints long strictly positive integer;
|
|
10 characters, right justified, padded left with spaces.
|
|
Input: 0D = integer to be printed.
|
|
Closed, even; 35 storage locations; working position 4D.]
|
|
T 55 K [call subroutine via V parameter]
|
|
P 56 F [address of subroutine]
|
|
E 25 K
|
|
T V
|
|
GKA3FT26@H28#@NDYFLDT4DS27@TFH8@S8@T1FV4DAFG31@SFLDUFOFFFSFL4F
|
|
T4DA1FA27@G11@XFT28#ZPFT27ZP1024FP610D@524D!FO30@SFL8FE22@
|
|
|
|
[Subroutine to print a string placed after the subroutine call.
|
|
One location per character, with character in top 5 bits.
|
|
Last character flagged by having bit 0 set.
|
|
17 locations, workspace 0F.]
|
|
T 54 K [call subroutine via C parameter]
|
|
P 91 F [address of subroutine]
|
|
E 25 K
|
|
T C
|
|
GKH16@A2FG4@A6@A2FT6@AFTFOFCFSFE3@A6@A3FT15@EFV2047F
|
|
|
|
[************ Rosetta Code task ************
|
|
Subroutine to generate and optionally store the hailstone
|
|
(Collatz) sequence for the passed-in initial term n.
|
|
Input: 4D = n, 35-bit positive integer
|
|
6F = start address of sequence if stored;
|
|
must be even; 0 = don't store
|
|
Output: 7F = number of terms in sequence, or -1 if error
|
|
Workspace: 0D (general), 8D (term of sequence)
|
|
Must be loaded at an even address.]
|
|
T 45 K [call subroutine via H parameter]
|
|
P 108 F [address of subroutine]
|
|
E 25 K
|
|
T H
|
|
G K
|
|
A 3 F
|
|
T 46 @
|
|
H 54#@ [mult reg := 1 to test odd/even]
|
|
A 4 D [load n passed in by caller]
|
|
T 8 D [term := n]
|
|
A 54 @ [load 1 (single)]
|
|
T 7 F [include initial term in count]
|
|
A 6 F [load address for store]
|
|
S 56 @ [test for 0; allow for pre-inc]
|
|
G 11 @ [skip next if storing not wanted]
|
|
A 12 @ [make 'T addr D' order]
|
|
[11] T 21 @ [plant T order, or -ve value if not storing
|
|
(note that a T order is +ve as an integer)]
|
|
[Loop: deal with current term in sequence
|
|
First store it, if user requested that]
|
|
[12] T D [clear acc; also serves to make 'T addr D' order]
|
|
A 21 @ [load T order to store term]
|
|
G 22 @ [jump if caller doesn't want store]
|
|
A 56 @ [pre-inc the address]
|
|
U 21 @ [update T order]
|
|
S 51 @ [check not gone beyond max EDSAC address]
|
|
E 47 @ [error exit if it has]
|
|
T F [clear acc]
|
|
A 8 D [load term]
|
|
[21] T D [store]
|
|
[22] T F [clear acc]
|
|
A 54#@ [load 1 (double)]
|
|
S 8 D [1 - term]
|
|
E 46 @ [if term = 1, jump out with acc = 0]
|
|
T F [clear acc]
|
|
C 8 D [acc := term AND 1]
|
|
S 54#@ [test whether 0 or 1]
|
|
G 38 @ [jump if term is even]
|
|
[Here if term is odd; acc = 0]
|
|
A 8 D [load term]
|
|
S 52#@ [guard against numeric overflow]
|
|
E 47 @ [jump if overflow]
|
|
A 52#@ [restore term after test]
|
|
L D [term*2]
|
|
A 8 D [term*3]
|
|
A 54#@ [plus 1]
|
|
E 41 @ [join common code]
|
|
[Here if term is even]
|
|
[38] T F [clear acc]
|
|
A 8 D [load term]
|
|
R D [term/2]
|
|
[Common code, acc = new term]
|
|
[41] T 8 D [store new term]
|
|
A 7 F [load count]
|
|
A 54 @ [add 1]
|
|
T 7 F [update count]
|
|
E 12 @ [loop back]
|
|
[Here when sequence has reached 1
|
|
Assume jump here with acc = 0]
|
|
[46] E F [return with acc = 0]
|
|
[47] T F [here on error]
|
|
S 54 F [acc := -1]
|
|
T 7 F [return that as count]
|
|
E 46 @
|
|
[Arrange the following to ensure even addresses for 35-bit values]
|
|
[51] T 1024 F [for checking valid address]
|
|
[52] H 682 DT 682 D [(2^34 - 1)/3]
|
|
[54] P DP F [1]
|
|
[56] P 2 F [to change addresses by 2]
|
|
|
|
[Program to demonstrate Rosetta Code subroutine]
|
|
T 180 K
|
|
G K
|
|
[Double constants]
|
|
[P 500 F P F] [maximum n = 1000"]
|
|
[0] & 848 F PF [maximum n = 100000]
|
|
[2] P 13 D PF [n = 27 as demo of sequence]
|
|
[4] P D PF [1]
|
|
[Double variables]
|
|
[6] P F P F [n, start of Collatz sequence]
|
|
[8] P F P F [n with maximum count]
|
|
[Single constants]
|
|
[10] P 400 F [where to store sequence]
|
|
[11] P 2 F [to change addresses by 2]
|
|
[12] @ F [carriage return]
|
|
[13] & F [line feed]
|
|
[14] K 4096 F [null char]
|
|
[15] A D [used for maiking 'A addr D' order]
|
|
[16] P 8 F [ used for adding 8 to address]
|
|
[Single variables]
|
|
[17] P F [maximum number of terms]
|
|
[18] P F [temporary store]
|
|
[19] P F [marks end of printing]
|
|
|
|
[Subroutine to print 4 numbers starting at address in 6F.
|
|
Prints new line (CR, LF) at end.]
|
|
[20] A 3 F [plant link for return]
|
|
T 40 @
|
|
A 6 F [load start address]
|
|
A 15 @ [make 'A addr D' order]
|
|
A 16 @ [inc address by 8 (4 double values)]
|
|
U 19 @ [store as test for end]
|
|
S 16 @ [restore 'A addr D' order for start]
|
|
[27] U 31 @ [plant 'A addr D' order in code]
|
|
S 19 @ [test for end]
|
|
E 38 @ [out if so]
|
|
T F [clear acc]
|
|
[31] A D [load number]
|
|
T D [to 0D for printing]
|
|
[33] A 33 @ [call print subroutine]
|
|
G V
|
|
A 31 @ [load 'A addr D' order]
|
|
A 11 @ [inc address to next double value]
|
|
G 27 @ [loop back]
|
|
[38] O 12 @ [here when done, print CR LF]
|
|
O 13 @
|
|
[40] E F [return]
|
|
|
|
[Enter with acc = 0]
|
|
[PART 1]
|
|
[41] A 2#@ [load demo value of n]
|
|
T 4 D [to 4D for subroutine]
|
|
A 10 @ [address to store sequence]
|
|
T 6 F [to 6F for subroutine]
|
|
[45] A 45 @ [call subroutine to generate sequence]
|
|
G H
|
|
A 7 F [load length of sequence]
|
|
G 198 @ [out if error]
|
|
T 18 @
|
|
[Print result]
|
|
[50] A 50 @ [print 'start' message]
|
|
G C
|
|
K2048F SF TF AF RF TF !F !F #D
|
|
A 2#@ [load demo value of n]
|
|
T D [to 0D for printing]
|
|
[63] A 63 @ [print demo n]
|
|
G V
|
|
[65] A 65 @ [print 'length' string]
|
|
G C
|
|
K2048F @F &F LF EF NF GF TF HF !F #D
|
|
T D [ensure 1F and sandwich bit are 0]
|
|
A 18 @ [load length]
|
|
T F [to 0F (effectively 0D) for printing]
|
|
[81] A 81 @
|
|
G V
|
|
[83] A 83 @ [print 'first and last four' string]
|
|
G C
|
|
K2048F @F &F FF IF RF SF TF !F AF NF DF !F LF AF SF TF !F FF OF UF RF @F &F #D
|
|
A 18 @ [load length of sequence]
|
|
L 1 F [times 4]
|
|
A 6 F [make address of last 4]
|
|
S 16 @
|
|
T 18 @ [store address of last 4]
|
|
[115] A 115 @ [print first 4 terms]
|
|
G 20 @
|
|
A 18 @ [retrieve address of last 4]
|
|
T 6 F [pass as parameter]
|
|
[119] A 119 @ [print last 4 terms]
|
|
G 20 @
|
|
|
|
[PART 2]
|
|
T F
|
|
T 17 @ [max count := 0]
|
|
T 6#@ [n := 0]
|
|
[Loop: update n, start new sequence]
|
|
[124] T F [clear acc]
|
|
A 6#@ [load n]
|
|
A 4#@ [add 1 (double)]
|
|
U 6#@ [update n]
|
|
T 4 D [n to 4D for subroutine]
|
|
T 6 F [say no store]
|
|
[130] A 130 @ [call subroutine to generate sequence]
|
|
G H
|
|
A 7 F [load count returned by subroutine]
|
|
G 198 @ [out if error]
|
|
S 17 @ [compare with max count so far]
|
|
G 140 @ [skip if less]
|
|
A 17 @ [restore count after test]
|
|
T 17 @ [update max count]
|
|
A 6#@ [load n]
|
|
T 8#@ [remember n that gave max count]
|
|
[140] T F [clear acc]
|
|
A 6#@ [load n just done]
|
|
S #@ [compare with max(n)]
|
|
G 124 @ [loop back if n < max(n)
|
|
else fall through with acc = 0]
|
|
[Here whan reached maximum n. Print result.]
|
|
[144] A 144 @ [print 'max n' message]
|
|
G C
|
|
K2048F MF AF XF !F NF !F !F #D
|
|
A #@ [load maximum n]
|
|
T D [to 0D for printing]
|
|
[157] A 157 @ [call print subroutine]
|
|
G V
|
|
[159] A 159 @ [print 'max len' message]
|
|
G C
|
|
K2048F @F &F MF AF XF !F LF EF NF #D
|
|
T D [clear 1F and sandwich bit]
|
|
A 17 @ [load max count (single)]
|
|
T F [to 0F, effectively to 0D]
|
|
[175] A 175 @ [call print subroutine]
|
|
G V
|
|
[177] A 177 @ [print 'at n =' message]
|
|
G C
|
|
K2048F @F &F AF TF !F NF !F #F VF !D
|
|
A 8#@ [load n for which max count occurred]
|
|
T D [to 0D for printing]
|
|
[192] A 192 @ [call print subroutine]
|
|
G V
|
|
[194] O 12 @ [print CR, LF]
|
|
O 13 @
|
|
O 14 @ [print null to flush teleprinter buffer]
|
|
Z F [stop]
|
|
[Here if term would overflow EDSAC 35-bit value.
|
|
With a maximum n of 100,000 this doesn't happen.]
|
|
[198] A 198 @ [print 'overflow' message]
|
|
G C
|
|
K2048F @F &F OF VF EF RF FF LF OF WD
|
|
E 194 @ [jump to exit]
|
|
|
|
E 41 Z [define entry point]
|
|
P F [acc = 0 on entry]
|