TITLE "MP5 by Douglas Jones" ; displays a fractal on the screen ; this version contains significant optimizations ; this was originally the second posted solution to MP4 ; -- http://homepage.cs.uiowa.edu/~dwjones/assem/hw/mp4sol2.txt ; -- (changes to make it work on the Sparrowhawk are marked like this) STRICTSPARROW = 1 ; -- (use only strict Sparrowhawk instructions) USE "sparrowhawk.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 structure ; -- (these fields are never directly referenced) ; -- (instead, the record is built by pushing and popping the stack) ;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 ADDSI R2,4 ; -- (push RETAD) LIS R1,1 ; -- (LIS/CMP was CMPI) CMP R3,R1 BGT PLOTBIG ; if size <= 1 { -- basis case MOVE R3,R4 ; -- (MOVE/ADDSI was ADDI) ADDSI R3,-1 ; -- parameter x-1 MOVE R4,R5 ; -- parameter y LIS R1,PPUTAT-(.+4) ; -- (LIS/PLUS/LOADS was LOAD) PLUS R1,R0 LOADS R1,R1 JSRS R1,R1 ; putat( x-1, y ) LIS R3,'[' LIS R1,PPUTCH-(.+4) ; -- (LIS/PLUS/LOADS was LOAD) PLUS R1,R0 LOADS R1,R1 JSRS R1,R1 ; putchar( '[' ) LIS R3,']' LIS R1,PPUTCH-(.+4) ; -- (LIS/PLUS/LOADS was LOAD) PLUS R1,R0 LOADS R1,R1 JSRS R1,R1 ; putchar( ']' ) BR PLOTDONE ALIGN 4 ; -- (pointers to external routines here) PPUTAT: W PUTAT PPUTCH: W PUTCHAR PLOTBIG: ; } else { -- recursive case STORES R8,R2 ADDSI R2,4 ; -- (push R8SV) STORES R9,R2 ADDSI R2,4 ; -- (push R9SV) STORES R10,R2 ADDSI R2,4 ; -- (push R10SV) STORES R11,R2 ADDSI R2,4 ; -- (push R11SV) 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 LIS R1,2 ; -- (LIS/CMP was CMPI) CMP R11,R1 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 LIS R1,PLOT-(.+4) ; -- (LIS/PLUS/JSRS was JSR) PLUS R1,R0 JSRS R1,R1 ; plot(size,x-size,y+(size+1)/2,0) PLOTX2: ; } LIS R1,3 ; -- (LIS/CMP was CMPI) CMP R11,R1 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 ADDR = PLOT-(.+6) LIS R1,ADDR >> 8 ; -- (LIS/ORIS/PLUS/JSRS was JSR) ORIS R1,ADDR & #FF PLUS R1,R0 JSRS R1,R1 ; 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 ADDR = PLOT-(.+6) LIS R1,ADDR >> 8 ; -- (LIS/ORIS/PLUS/JSRS was JSR) ORIS R1,ADDR & #FF PLUS R1,R0 JSRS R1,R1 ; plot(size,x+size,y-size/2,2) PLOTX0: ; } LIS R1,1 ; -- (LIS/CMP was CMPI) CMP R11,R1 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 ADDR = PLOT-(.+6) LIS R1,ADDR >> 8 ; -- (LIS/ORIS/PLUS/JSRS was JSR) ORIS R1,ADDR & #FF PLUS R1,R0 JSRS R1,R1 ; plot(size,x-size,y-size/2,3) PLOTX1: ; } ADDSI R2,-4 ; -- (pop R11SV) LOADS R11,R2 ADDSI R2,-4 ; -- (pop R10SV) LOADS R10,R2 ADDSI R2,-4 ; -- (pop R9SV) LOADS R9,R2 ADDSI R2,-4 ; -- (pop R8SV) LOADS R8,R2 PLOTDONE: ; } ADDSI R2,-4 ; -- (pop RETAD) LOADS R1,R2 JUMPS R1 ; return SUBTITLE "Main program" INT MAIN S MAIN ; activation record structure ; -- (these fields are never directly referenced) ; -- (instead, the record is built by pushing and popping the stack) ;RETAD = 0 ;ARSIZE = 4 MAIN: ; given R3: width of display area ; R4: height of display area STORES R1,R2 ADDSI R2,4 ; -- (push RETAD) 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 ADDR = PLOT-(.+6) LIS R1,ADDR >> 8 ; -- (LIS/ORIS/PLUS/JSRS was JSR) ORIS R1,ADDR & #FF PLUS R1,R0 JSRS R1,R1 ; plot( order, width/2, height/2-1, 0 ) ADDSI R2,-4 ; -- (pop RETAD) LOADS R1,R2 JUMPS R1 ; return END