SMAL32 (rev 9/03) "MP4 solved by Douglas Jon 10:44:44 Page 1 Fri Nov 21 2003 7 SUBTITLE "32x32=64 unsigned multiply" 32 SUBTITLE "64/32=32 unsigned divide" 58 SUBTITLE "Minimal Standard Random Number Generator" 110 SUBTITLE MAIN SMAL32 (rev 9/03) "MP4 solved by Douglas Jon 10:44:44 Page 2 Fri Nov 21 2003 1 TITLE "MP4 solved by Douglas Jones" 2 3 S MAIN 4 USE "hawk.macs" 5 USE "monitor.h" +000000:+00000000 6 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 SMAL32 (rev 9/03) "MP4 solved by Douglas Jon 10:44:44 Page 3 "32x32=64 unsigned multipl Fri Nov 21 2003 7 SUBTITLE "32x32=64 unsigned multiply" 8 ; this code is based on the fast signed binary multiplication 9 ; routine from Chapter 9 of the notes, modified to make it 10 ; unsigned and extended precision. 11 12 MULU64: ; link through R1 13 ; on entry R3 = 32-bit multiplicand 14 ; R4 = 32-bit multiplier 15 ; on exit R3 = low 32 bits of product 16 ; R4 = high 32 bits of product 17 ; uses R5, R6, no other registers used 18 MOVE R5,R3 ; set aside multiplicand +000030: F5F3 19 CLR R3 ; product = 0 +000032: D300 20 LIS R6,32 ; loopcount = 32 +000034: D620 21 MULULP: ; do { 22 SL R3,1 ; double precision left shift +000036: A301 23 ADDC R4,R4 ; product and multiplier +000038: 1474 24 BCR MULSEIL ; if (top bit of multiplier was one) { +00003A: 0C02 25 ADD R3,R3,R5 ; double precision add +00003C: 3335 26 ADDC R4,R0 ; partial product to product +00003E: 1470 27 MULSEIL: ; } 28 ADDSI R6,-1 ; loopcount = loopcount - 1 +000040: 16CF 29 BGT MULULP ; } while (loopcount > 0) +000042: 0EF9 30 JUMPS R1 ; return +000044: F0B1 31 SMAL32 (rev 9/03) "MP4 solved by Douglas Jon 10:44:44 Page 4 "64/32=32 unsigned divide" Fri Nov 21 2003 32 SUBTITLE "64/32=32 unsigned divide" 33 ; this code is based on the binary division routine 34 ; from Chapter 9 of the notes, modified to make it 35 ; unsigned and extended precision. 36 37 DIVU64: ; link through R1 38 ; on entry R3 = low 32 bits of dividend 39 ; R4 = high 32 bits of dividend 40 ; R5 = divisor 41 ; on exit R3 = quotient 42 ; R4 = remainder 43 ; R5 = unchanged 44 ; uses R6, no other registers used 45 LIS R6,32 ; loopcount = 32 +000046: D620 46 DIVLP: ; do { 47 SL R3,1 +000048: A301 48 ADDC R4,R4 ; 64-bit shift quotient/remainder +00004A: 1474 49 CMP R4,R5 +00004C: 2045 50 BLTU DIVNO ; if (remainder >= divisor) { +00004E: 0C02 51 SUB R4,R4,R5 ; remainder = remainder - divisor +000050: 2445 52 ADDSI R3,1 ; quotient = quotient + 1 +000052: 13C1 53 DIVNO: ; } 54 ADDSI R6,-1 ; loopcount = loopcount - 1 +000054: 16CF 55 BGT DIVLP ; } while (loopcount > 0) +000056: 0EF8 56 JUMPS R1 ; return +000058: F0B1 57 SMAL32 (rev 9/03) "MP4 solved by Douglas Jon 10:44:44 Page 5 "Minimal Standard Random N Fri Nov 21 2003 58 SUBTITLE "Minimal Standard Random Number Generator" 59 ; this is the Park and Miller algorithm, 60 ; using a 64-bit intermediate result. 61 62 ; wierd constants required for pseudo random numbers 63 RANDA = 16807 64 RANDM = 2147483657 65 66 ; global variable needed by the random number generator 67 COMMON SEED,4 68 ALIGN 4 +00005C:+00000000 69 PSEED: W SEED 70 71 SETSEED: ; link through R1 72 ; on entry, R3 = proposed seed 73 ; uses: R4 all others unchanged 74 TESTR R3 +000060: F0E3 75 BZS SETSER ; error if proposed seed is zero +000062: 0205 76 LIL R4,RANDM >> 8 +000064: E480 0000 77 ORIS R4,RANDM & #FF ; R4 = funny constant M +000068: C409 78 CMP R3,R4 +00006A: 2034 79 BLTU SETSOK ; error if proposed seed >= M +00006C: 0C02 80 SETSER: 81 LIS R1,0 +00006E: D100 82 JUMPS R1 ; go bomb out if error +000070: F0B1 83 SETSOK: 84 LOAD R4,PSEED +000072: F450 FFE6 85 STORES R3,R4 ; accept seed +000076: F3A4 86 JUMPS R1 ; return +000078: F0B1 87 SMAL32 (rev 9/03) "MP4 solved by Douglas Jon 10:44:44 Page 6 "Minimal Standard Random N Fri Nov 21 2003 88 PAGE 89 RANDOM: ; link through R1 90 ; returns R3 = pseudo-random number 91 ; uses R3-7 92 MOVE R7,R1 ; save RA +00007A: F7F1 93 LOAD R4,PSEED +00007C: F450 FFDC 94 LOADS R3,R4 ; R3 = seed +000080: F3D4 95 96 LIL R4,RANDA ; R4 = funny constant A +000082: E400 41A7 97 JSR R1,MULU64 ; R3-R4 = seed * A +000086: F130 FFA6 98 99 LIL R5,RANDM >> 8 +00008A: E580 0000 100 ORIS R5,RANDM & #FF ; R4 = funny constant M +00008E: C509 101 JSR R1,DIVU64 ; R4 = (seed * A) mod M +000090: F130 FFB2 102 103 MOVE R3,R4 ; move to right place for return +000094: F3F4 104 LOAD R4,PSEED +000096: F450 FFC2 105 STORES R3,R4 ; seed = (seed * A) mod M +00009A: F3A4 106 107 MOVE R1,R7 ; restore RA +00009C: F1F7 108 JUMPS R1 ; return seed +00009E: F0B1 109 SMAL32 (rev 9/03) "MP4 solved by Douglas Jon 10:44:44 Page 7 MAIN Fri Nov 21 2003 110 SUBTITLE MAIN 111 112 ALIGN 4 ; this main program fills the 113 COMMON STACK,#1000 ; screen with randomly placed stars +0000A0:+00000000 114 PSTACK: W STACK ; as a test of the random number 115 ; generator 116 117 MAIN: LOAD R2,PSTACK ; set up the stack +0000A4: F250 FFF8 118 LOAD R1,PDSPINI +0000A8: F150 FF58 119 JSRS R1,R1 ; dspini() +0000AC: F1B1 120 MOVE R8,R3 ; R8 = columns (X size) +0000AE: F8F3 121 MOVE R9,R4 ; R9 = rows (Y size) +0000B0: F9F4 122 LIS R3,1 +0000B2: D301 123 JSR R1,SETSEED ; setseed(1) +0000B4: F130 FFA8 124 125 LOOP: ; while (TRUE) do { 126 JSR R1,RANDOM +0000B8: F130 FFBE 127 LIS R4,0 +0000BC: D400 128 MOVE R5,R8 +0000BE: F5F8 129 JSR R1,DIVU64 +0000C0: F130 FF82 130 MOVE R10,R4 ; column = random() mod columns +0000C4: FAF4 131 132 JSR R1,RANDOM +0000C6: F130 FFB0 133 LIS R4,0 +0000CA: D400 134 MOVE R5,R9 +0000CC: F5F9 135 JSR R1,DIVU64 +0000CE: F130 FF74 136 ; R4 row = random() mod rows 137 138 MOVE R3,R10 +0000D2: F3FA 139 LOAD R1,PDSPAT +0000D4: F150 FF30 140 JSRS R1,R1 ; dspat( column, row ) +0000D8: F1B1 141 142 LIS R3,'*' +0000DA: D32A 143 LOAD R1,PDSPCH +0000DC: F150 FF2C 144 JSRS R1,R1 ; dspch('*') +0000E0: F1B1 145 146 BR LOOP ; } while TRUE +0000E2: 00EA 147 148 END no errors