TITLE "MP4 by Douglas Jones" ; displays a fractal on the screen ; this version contains significant optimizations USE "hawk.h" USE "monitor.h" SUBTITLE "Plot routine" ; direction encodings ; 1 0 -- omit the indicated subsquare if the number matches ; 2 3 -- incrementing mod 4 turns it counterclockwise ; activation record ;RETAD = 0 R8SV = 4 ; save areas for R8 to R11 R9SV = 8 ; these allow R8 to 11 R10SV = 12 ; to be used for local R11SV = 16 ; variables ARSIZE = 20 PLOT: ; given R3: size (2 to the order) ; R4: x -- coordinates of center ; R5: y ; R6: direction STORES R1,R2 ADDI R2,R2,ARSIZE ; -- ar optimization CMPI R3,1 BGT PLOTBIG ; if size <= 1 { -- basis case ADDI R3,R4,-1 ; -- parameter x-1 MOVE R4,R5 ; -- parameter y LIL R1,PUTAT ; putat( x-1, y ) JSRS R1,R1 LIS R3,'[' LIL R1,PUTCHAR JSRS R1,R1 ; putchar( '[' ) LIS R3,']' LIL R1,PUTCHAR JSRS R1,R1 ; putchar( ']' ) BR PLOTDONE PLOTBIG: ; } else { -- recursive case STORE R8,R2,R8SV-ARSIZE STORE R9,R2,R9SV-ARSIZE STORE R10,R2,R10SV-ARSIZE STORE R11,R2,R11SV-ARSIZE MOVE R8,R3 ; -- R8 now holds size MOVE R9,R4 ; -- R9 now holds x MOVE R10,R5 ; -- R10 now holds y MOVE R11,R6 ; -- R11 now holds dir SR R8,1 ; size = size/2 CMPI R11,2 BEQ PLOTX2 ; if (dir != 2) { -- plot lower left MOVE R3,R8 ; -- parameter size SUB R4,R9,R8 ; -- parameter x-size MOVE R5,R8 ADDSI R5,1 SR R5,1 ADD R5,R10,R5 ; -- parameter y+(size+1)/2 LIS R6,0 ; -- parameter dir JSR R1,PLOT ; plot(size,x-size,y+(size+1)/2,0) PLOTX2: ; } CMPI R11,3 BEQ PLOTX3 ; if (dir != 3) { -- plot lower right MOVE R3,R8 ; -- parameter size ADD R4,R9,R8 ; -- parameter x+size MOVE R5,R8 ADDSI R5,1 SR R5,1 ADD R5,R10,R5 ; -- parameter y+(size+1)/2 LIS R6,1 ; -- parameter dir JSR R1,PLOT ; plot(size,x+size,y+size/2,1) PLOTX3: ; } TESTR R11 BEQ PLOTX0 ; if (dir != 0) { -- plot upper right MOVE R3,R8 ; -- parameter size ADD R4,R9,R8 ; -- parameter x+size MOVE R5,R8 SR R5,1 SUB R5,R10,R5 ; -- parameter y-size/2 LIS R6,2 ; -- parameter dir JSR R1,PLOT ; plot(size,x+size,y-size/2,2) PLOTX0: ; } CMPI R11,1 BEQ PLOTX1 ; if (dir != 1) { -- plot upper left MOVE R3,R8 ; -- parameter size SUB R4,R9,R8 ; -- parameter x-size MOVE R5,R8 SR R5,1 SUB R5,R10,R5 ; -- parameter y-size/2 LIS R6,3 ; -- parameter dir JSR R1,PLOT ; plot(size,x-size,y-size/2,3) PLOTX1: ; } LOAD R8,R2,R8SV-ARSIZE LOAD R9,R2,R9SV-ARSIZE LOAD R10,R2,R10SV-ARSIZE LOAD R11,R2,R11SV-ARSIZE PLOTDONE: ; } ADDI R2,R2,-ARSIZE ; -- ar optimization LOADS R1,R2 JUMPS R1 ; return SUBTITLE "Main program" INT MAIN S MAIN ; activation record structure ;RETAD = 0 ARSIZE = 4 MAIN: ; given R3: width of display area ; R4: height of display area STORES R1,R2 ADDI R2,R2,ARSIZE ; -- ar optimization MOVE R5,R4 ; -- move height to R5 (needed there later) MOVE R4,R3 ; -- move width to R4 (needed there later) MOVE R6,R4 SR R6,1 ; limit = width/2 CMP R6,R5 BLE MAIBIG ; if (limit > height) { MOVE R6,R5 ; limit = height MAIBIG: ; } LIS R3,1 ; size = 1 -- an initial guess MAILP: ; do { -- find largest power of 2 <= limit SR R6,1 ; limit = limit/2 BZS MAIDON ; if (limit == 0) break SL R3,1 ; size = size*2 BR MAILP MAIDON: ; } ; -- parameter size (computed in R3) SR R4,1 ; -- parameter width/2 SR R5,1 ADDSI R5,-1 ; -- parameter height/2-1 LIS R6,0 ; -- parameter JSR R1,PLOT ; plot( order, width/2, height/2-1, 0 ) ADDI R2,R2,-ARSIZE ; -- ar optimization LOADS R1,R2 JUMPS R1 ; return END