TITLE "mp5.a -- by Douglas Jones" ; plots a distorted version of the fractal from MP4 ; where each sub-fractal has a 1/5 probability of being ; shifted toward the center of its parent figure USE "hawk.h" USE "monitor.h" S MAIN ; the main program is at the end INT MAIN SUBTITLE "RANDOM subroutine" COMMON SEED,4 ; the seed for the random number generator LCSAVE = . . = SEED W 1 ; the initial seed value . = LCSAVE RANDOM: ; returns R3 = usually 0, but with probability 1/5 returns 1. ; uses R3 = lo, a temporary ; R4 = hi, a temporary ; R5 = very transient temporary ; R6 = pointer to global variable seed ; does not use an activation record LIL R6,SEED ; R6 = &seed LOADS R3,R6 MOVE R4,R3 ; R3 = R4 = seed TRUNC R3,16 ; R3 = (seed & FFFF) NEG R5,R3 ; -- note that 16807 is 7**5, so repeat 5 times ADDSL R3,R5,3 ; -- * 7 NEG R5,R3 ADDSL R3,R5,3 ; -- * 7 NEG R5,R3 ADDSL R3,R5,3 ; -- * 7 NEG R5,R3 ADDSL R3,R5,3 ; -- * 7 NEG R5,R3 ADDSL R3,R5,3 ; lo = 16807 * (seed & FFFF) SRU R4,16 ; R4 = (seed >> 16) NEG R5,R4 ; -- note that 16807 is 7**5, so repeat 5 times ADDSL R4,R5,3 ; -- * 7 NEG R5,R4 ADDSL R4,R5,3 ; -- * 7 NEG R5,R4 ADDSL R4,R5,3 ; -- * 7 NEG R5,R4 ADDSL R4,R5,3 ; -- * 7 NEG R5,R4 ADDSL R4,R5,3 ; hi = 16807 * (seed >> 16) MOVE R5,R4 TRUNC R5,15 ; R5 = (hi & 0x7FFF) ADDSL R5,R3,16 ; R5 = lo + ((hi & 0x7FFF) << 16) SRU R4,16 ; R4 = (hi >> 16) ADD R4,R5,R4 ; hi = lo + ((hi & 0x7FFF) << 16) + (hi >> 16) BNR RANPOS ; if (hi > 0x7FFFFFFF) { LIS R5,-1 SRU R5,1 ; R5 = 0x7FFFFFFF SUB R4,R4,R5 ; hi = hi - 0x7FFFFFFF RANPOS: ; } STORES R4,R6 ; seed = hi LIS R3,0 ; return-value = 0 ; -- now work out probability of 1/5 LIW R5,#19999999 ; R5 = (2**31 - 2)/5 CMP R4,R5 BGT RANZR ; if (seed <= (2**31 - 2)/5) { LIS R3,1 ; return-value = 1 RANZR: ; } JUMPS R1 ; return return-value SUBTITLE "PLOT subroutine" ; table giving dimensions of figure as a function of its order ALIGN 4 ; array of height ; order ROWS: W 0 ; 0 W 1 ; 1 W 2 ; 2 W 5 ; 3 W 12 ; 4 W 29 ; 5 W 70 ; 6 W 169 ; 7 W 408 ; 8 W 985 ; 9 ; activation record for PLOT ;retad = 0 R8SV = 4 R9SV = 8 R10SV = 12 R11SV = 16 R12SV = 20 ARSIZE = 24 PLOT: ; expects R3 = order of figure ; expects R4 = x coordinate of upper left of figure ; expects R5 = y " " " " " " STORES R1,R2 ADDSI R3,-1 ; order = order - 1; BLT PLOTQT ; if (order >= 0) { BGT PLOTEL ; if (order = 0) { -- basis case ADDI R2,R2,ARSIZE MOVE R3,R4 MOVE R4,R5 LIL R1,PUTAT JSRS R1,R1 ; putat(x,y) LIS R3,'[' LIL R1,PUTCHAR JSRS R1,R1 ; putchar('[') LIS R3,']' LIL R1,PUTCHAR JSRS R1,R1 ; putchar(']') ADDI R2,R2,-ARSIZE BR PLOTQT PLOTEL: ; } else { -- order > 0, fun case STORE R8,R2,R8SV STORE R9,R2,R9SV STORE R10,R2,R10SV STORE R11,R2,R11SV STORE R12,R2,R12SV ; -- all key variables moved to safety MOVE R8,R3 ; -- order in R8 MOVE R9,R4 ; -- X in R9 MOVE R10,R5 ; -- Y in R10 LEA R12,ROWS MOVESL R11,R8,2 ADD R12,R11,R12 LOADS R11,R12 ; big = ROWS[order] -- in R11 ADDSI R12,-4 LOADS R12,R12 ; lit = ROWS[order-1] -- in R12 ADDI R2,R2,ARSIZE ; -- upper left JSR R1,RANDOM ; p = random() -- mostly 0, could be 1 ADD R5,R3,R10 ; -- parameter y+p SL R3,1 ADD R4,R3,R9 ; -- parameter x+2p MOVE R3,R8 ; -- parameter order JSR R1,PLOT ; plot( order, x+2p, y+p ) ; -- lower left JSR R1,RANDOM ; p = random() -- mostly 0, could be 1 SUB R5,R10,R3 ADD R5,R5,R11 ADD R5,R5,R12 ; -- parameter (y-p)+big+lit SL R3,1 ADD R4,R3,R9 ; -- parameter x+2p MOVE R3,R8 ; -- parameter order JSR R1,PLOT ; plot( order, x+2p, (y-p)+big+lit ) ; -- upper right JSR R1,RANDOM ; p = random() -- mostly 0, could be 1 ADD R5,R3,R10 ; -- parameter y+p SUB R4,R11,R3 ADD R4,R4,R12 SL R4,1 ADD R4,R4,R9 ; -- parameter (big+lit-p)*2+x MOVE R3,R8 ; -- parameter order JSR R1,PLOT ; plot( order, (big+lit-p)*2+x, y+p ) ; -- lower right JSR R1,RANDOM ; p = random() -- mostly 0, could be 1 SUB R5,R10,R3 ADD R5,R5,R11 ADD R5,R5,R12 ; -- parameter (y-p)+big+lit SUB R4,R11,R3 ADD R4,R4,R12 SL R4,1 ADD R4,R4,R9 ; -- parameter (big+lit-p)*2+x MOVE R3,R8 ; -- parameter order JSR R1,PLOT ; plot(order,(big+lit-p)*2+x,(y-p)+big+lit) ; -- middle MOVE R3,R8 ADDSI R3,-1 MOVE R4,R11 ADDSL R4,R9,1 ADD R5,R11,R10 JSR R1,PLOT ; plot( order-1, (big)*2+x, big+y) ADDI R2,R2,-ARSIZE LOAD R8,R2,R8SV LOAD R9,R2,R9SV LOAD R10,R2,R10SV LOAD R11,R2,R11SV LOAD R12,R2,R12SV PLOTQT: ; } } LOADS R1,R2 JUMPS R1 ; return SUBTITLE "main program" ; activation record for MAIN ;retad = 0 ARSIZE = 4 MAIN: ; expects R3 = w -- screen width ; expects R4 = h -- screen height STORES R1,R2 ; -- find d, the limiting screen dimension MOVE R5,R3 SR R5,1 ; d = w/2 -- in R5 CMP R4,R5 BGE MAGOTD ; if (h < d) MOVE R5,R4 ; d = h; MAGOTD: ; } ; -- find order, limited by d LEA R6,ROWS LIS R7,0 ; order = 0 MAGETO: ; loop { LOADS R8,R6 CMP R8,R5 BGT MAGOTO ; if (ROWS[order] > d) break; ADDSI R7,1 ; order = order + 1 ADDSI R6,4 BR MAGETO ; } MAGOTO: ADDSI R7,-1 ; order = order - 1 ADDSI R6,-4 ; -- above loop overshoots by one LOADS R6,R6 ; r = ROWS[order] -- in R6 ; -- compute midpoint of screen SR R3,1 ; x = width/2 SR R4,1 ; y = height/2 ; -- compute upper left corner of figure SUB R3,R3,R6 ; x = x - rows SR R6,1 SUB R4,R4,R6 ; y = y - rows/2 ; -- plot the figure MOVE R5,R4 MOVE R4,R3 MOVE R3,R7 ADDI R2,R2,ARSIZE JSR R1,PLOT ; plot(order,x,y) ADDI R2,R2,-ARSIZE LOADS R1,R2 JUMPS R1 ; return