TITLE "MP3 solved by Douglas Jones" ; ---------------------------------- ; Sierpinski's Gasket ; Started, October 22, 2007 ; Note added, November 2: This is a variant solution ; It deliberately produces the wrong version of the gasket! ; ; Note: the main program is at the end, subroutines are ; listed in a define-before use order. ; ---------------------------------- USE "hawk.macs" USE "monitor.h" ; ---------------------------------- SUBTITLE "POWER2" ; return the largest power of two less than or ; equal to the given integer. ; ---------------------------------- ; receiving sequence assumptions POWER2: ; expects R3 = i, the given number (>= 1) ; returns R3 = p, the power of two ; uses R4 = i, copy of parameter MOVE R4,R3 ; set i aside LIS R3,1 ; p = 1 POWLP: CMP R3,R4 ; while (p <= i) { BGT POWQT SL R3,1 ; p = p * 2 BR POWLP ; } POWQT: ; -- note: loop overshoots goal SR R3,1 ; p = p / 2 JUMPS R1 ; return p ; ---------------------------------- SUBTITLE "GASKET" ; plot a gasket at the indicated location ; of the indicated height ; ---------------------------------- ; activation record structure ; RETAD = 0 ; return address X = 4 ; x coordinate of this gasket Y = 8 ; y coordinate of this gasket HEIGHT = 12 ; height of this gasket ARSIZE = 16 GASKET: ; expects R3 = x coordinate of lower left corner ; R4 = y coordinate of lower left corner ; R5 = h height of gasket ; returns nothing STORES R1,R2 ; save return address CMPI R5,1 ; if (height <= 1) { BGT GASELS ADDI R2,R2,ARSIZE LOAD R1,PDSPAT JSRS R1,R1 ; call dspat( x, y ) LEA R3,ELL LOAD R1,PDSPST JSRS R1,R1 ; call dspst( "L_" ) ADDI R2,R2,-ARSIZE BR GASQT GASELS: ; } else { STORE R3,R2,X ; save x to survive recursion STORE R4,R2,Y ; save y to survive recursion STORE R5,R2,HEIGHT ; save height to survive recursion SR R5,1 ADDI R2,R2,ARSIZE JSR R1,GASKET ; call gasket( x, y, height/2 ) ADDI R2,R2,-ARSIZE LOAD R3,R2,X ; recover x LOAD R4,R2,Y ; recover y LOAD R5,R2,HEIGHT ; recover height ADD R3,R3,R5 SR R5,1 ADDI R2,R2,ARSIZE JSR R1,GASKET ; call gasket( x + height, y, height/2 ) ADDI R2,R2,-ARSIZE LOAD R3,R2,X ; recover x LOAD R4,R2,Y ; recover y LOAD R5,R2,HEIGHT ; recover height SR R5,1 SUB R4,R4,R5 ADDI R2,R2,ARSIZE JSR R1,GASKET ; call gasket( x, y - height/2, height/2 ) ADDI R2,R2,-ARSIZE GASQT: ; } LOADS R1,R2 ; recover return address JUMPS R1 ; return ELL: ASCII "L_",0 ; ---------------------------------- SUBTITLE "Main Program" ALIGN 4 COMMON STACK,#1000 PSTACK: W STACK S MAIN MAIN: LOAD R2,PSTACK LOAD R1,PDSPINI JSRS R1,R1 ; initialize the display ; returns R3 = screenwidth ; returns R4 = screenheight ; first, find largest powers of two MOVE R8,R4 ; set aside screenheight JSR R1,POWER2 ; call power(screenwidth) MOVE R9,R3 ; set aside result MOVE R3,R8 JSR R1,POWER2 ; call power(height) ; now R3 = power(screenheight) ; R9 = power(screenwidth) ; then, find which limits the gasket height SR R9,1 ; height = power(screenwidth) / 2 CMP R9,R3 ; if (height > power(screenheight)) BLE MENDIF MOVE R9,R3 ; height = power(rows) MENDIF: ; now R9 = height ; now, display the gasket LIS R3,0 MOVE R4,R9 ADDSI R4,-1 MOVE R5,R9 JSR R1,GASKET ; call gasket(0,height-1,height) LOAD R1,PEXIT JSRS R1,R1 ; call exit() END