TITLE MP1, Douglas Jones, the x3+1 problem USE "hawk.macs" . = #1000 S start disp: W DISPBASE+DISPTEXT-1 ; base of video-ram numb: W 100 ; starting number start: LOAD R5,disp ; the display base LOAD R3,numb ; the variable LIS R4,1 ; the constant 1 loop: ; when control reaches this point, ; R3 holds the number being modified ; R4 holds the constant 1 ; R5 points to the previous output location on the screen JSR R1,output ; (this wipes out R6-R10) CMP R3,R4 ; quit loop if R4 <= 1 BLEU quit ADDSRU 0,R3,1 ; check if variable is even or odd BCS odd ADDSRU R3,0,1 ; if even, divide by 2 BR loop odd: ADDSL R3,R3,1 ; if odd, multiply by 3 ADDSI R3,1 ; and add 1 BR loop quit: JUMP 0 ;------------------------ output: ; output the number in R3 ; uses R1 for linkage ; wipes out R6-10 ; uses R5 as display pointer ADDI R5,8 ; update display pointer MOVE R6,R5 ; prepare to work backward on display MOVE R7,R3 ; get copy of number to output nextdig: ; When control reaches this point ; R6 points to Video RAM where digit should be put ; R7 holds the remaining part of the number to output ; R8 = R7 / 10 ; reciprocal multiply ; 1/10 = .0001 1001 1001 1001 1001 1001 1001 1001 MOVE R8,R7 LIS R9,1 ADDSRU R8,R9,3 ; times .001+epsilon ADDSRU R8,R7,1 ; times .1001 ADDSRU R8,R7,3 ; times .0011001 ADDSRU R8,R7,1 ; times .10011001 ADDSRU R8,R7,3 ; times .00110011001 ADDSRU R8,R7,1 ; times .100110011001 ADDSRU R8,R7,3 ; times .001100110011001 ADDSRU R8,R7,1 ; times .1001100110011001 ADDSRU R8,R7,3 ; times .0011001100110011001 ADDSRU R8,R7,1 ; times .10011001100110011001 ADDSRU R8,R7,3 ; times .00110011001100110011001 ADDSRU R8,R7,1 ; times .100110011001100110011001 ADDSRU R8,R7,3 ; times .001100110011001100110011001 ADDSRU R8,R7,1 ; times .1001100110011001100110011001 ADDSRU R8,R7,4 ; times .00011001100110011001100110011001 ; \ /\ /\ /\ /\ /\ /\ /\ / MOVE R9,R8 ; R9 = R8 = R7/10 ADDSL R9,R9,2 SL R9,1 ; R9 = (R7/10)*10 SUB R9,R7,R9; R9 = R7-((R7/10)*10) = R7 mod 10 ; the following code fixes divide rounding problem CMPI R9,10 ; is it 10 or more BLT quook ADDSI R8,1 ADDI R9,-10 ; if too big, bump quotient, fix remainder quook: ; now, convert remainder in R9 to ASCII and output ADDI R9,'0' ; convert to ascii LOADS R10,R6 STUFFB R10,R9,R6 STORES R10,R6 ; output digit ADDSI R6,-1 ; backup for next one MOVECC R7,R8 BZR nextdig JUMPS R1 ; return