_start: # Print menu li a7,4 la a0,menumsg ecall # Read the user's input li a7,5 ecall li t0,1 beq a0,t0,retailkey li t0,2 beq a0,t0,oemkey li t0,3 beq a0,t0,upgradepassword j _start retailkey: # Clear the screen li a7,4 la a0,clearscreenmsg ecall # Section 1: any 3 numbers, with some exceptions # Generate 3 random numbers, 0-9 li a0,0 li a1,9 li a7,128 ecall mv s0,a0 li a0,0 li a1,9 li a7,128 ecall mv s1,a0 li a0,0 li a1,9 li a7,128 ecall mv s2,a0 # In the case of the first two being the same and NOT 0/1/2, the third must be different bne s0,s1,1f # digits 1/2 are not the same bne s1,s2,1f # digits 2/3 are not the same li t0,3 blt s2,t0,1f # all are less than 3 # Just decrement the 3rd digit so it's not the same, it's always at least 3 if we're # here, so this won't underflow addi s2,s2,-1 1: # Print the digits li a7,1 mv a0,s0 ecall li a7,1 mv a0,s1 ecall li a7,1 mv a0,s2 ecall # Print a dash li a7,11 li a0,'-' ecall # Section 2a: any 6 digits li s0,0 li t0,6 1: li a0,0 li a1,9 li a7,128 ecall add s0,s0,a0 li a7,1 ecall addi t0,t0,-1 bnez t0,1b # Section 2b: Check digit for section 2a li t0,7 rem s0,s0,t0 sub a0,t0,s0 li a7,1 ecall j anykey oemkey: # Clear the screen li a7,4 la a0,clearscreenmsg ecall # Section 1a: Any 3-digit number 001-366 li a0,1 li a1,366 li a7,128 ecall mv s0,a0 li t0,100 div a0,s0,t0 addi a0,a0,0x30 li a7,11 ecall li t0,10 div a0,s0,t0 li t0,10 rem a0,a0,t0 addi a0,a0,0x30 li a7,11 ecall li t0,10 rem a0,s0,t0 addi a0,a0,0x30 li a7,11 ecall # Section 1b: 2 digits, >=95 or <=03 li a0,0 li a1,8 li a7,128 ecall addi s0,a0,95 li t0,100 rem s0,s0,t0 li t0,10 div a0,s0,t0 addi a0,a0,0x30 li a7,11 ecall li t0,10 rem a0,s0,t0 addi a0,a0,0x30 li a7,11 ecall # Section 2 and 3a: '-OEM-0' la a0,oemmsg li a7,4 ecall # Section 3b: Any 5 digits li s0,0 li t0,5 1: li a0,0 li a1,9 li a7,128 ecall add s0,s0,a0 li a7,1 ecall addi t0,t0,-1 bnez t0,1b # Section 3c: Check digit for section 3b li t0,7 rem s0,s0,t0 sub a0,t0,s0 li a7,1 ecall # Another dash li a0,'-' li a7,11 ecall # Section 4: Any 5 digits li t0,5 1: li a0,0 li a1,9 li a7,128 ecall li a7,1 ecall addi t0,t0,-1 bnez t0,1b j anykey upgradepassword: # Clear the screen la a0,clearscreenmsg li a7,4 ecall # Clear the input buffer la t0,inputbuf sd x0,0(t0) sd x0,2(t0) sd x0,4(t0) sw x0,6(t0) # Print "Enter key: " message li a7,4 la a0,keypromptmsg ecall # Read the user's input li a7,8 la a0,inputbuf li a1,7 ecall # Print it back, followed by a line feed li a7,4 la a0,inputbuf ecall li a7,11 li a0,'\n' ecall # Check if all characters are digits la t0,inputbuf li t1,5 1: add t2,t0,t1 lb t3,0(t2) li t4,0x30 # 0 blt t3,t4,invalidinput # too low li t4,0x39 # 9 blt t4,t3,invalidinput # too high addi t1,t1,-1 bnez t1,1b # Convert the key into a decimal number, but backwards # Could I make this a loop? Probably. Does it matter? Not really. la t0,inputbuf lb s0,0(t0) # 1s place addi s0,s0,-0x30 lb t1,1(t0) # 10s place addi t1,t1,-0x30 li t2,10 mul t1,t1,t2 add s0,s0,t1 lb t1,2(t0) # 100s place addi t1,t1,-0x30 li t2,100 mul t1,t1,t2 add s0,s0,t1 lb t1,3(t0) # 1000s place addi t1,t1,-0x30 li t2,1000 mul t1,t1,t2 add s0,s0,t1 lb t1,4(t0) # 10000s place addi t1,t1,-0x30 li t2,10000 mul t1,t1,t2 add s0,s0,t1 lb t1,5(t0) # 100000s place addi t1,t1,-0x30 li t2,100000 mul t1,t1,t2 add s0,s0,t1 # Calculate the password li t0,0x414d57 xor s0,s0,t0 li t0,1000000 rem s0,s0,t0 # Print out the password one character at a time # Yes, RVController has a function to print integers, but I wanted to have some fun here li a7,4 la a0,passwordheadermsg ecall li t0,100000 div a0,s0,t0 addi a0,a0,0x30 li a7,11 ecall li t0,10000 div a0,s0,t0 li t0,10 rem a0,a0,t0 addi a0,a0,0x30 li a7,11 ecall li t0,1000 div a0,s0,t0 li t0,10 rem a0,a0,t0 addi a0,a0,0x30 li a7,11 ecall li t0,100 div a0,s0,t0 li t0,10 rem a0,a0,t0 addi a0,a0,0x30 li a7,11 ecall li t0,10 div a0,s0,t0 li t0,10 rem a0,a0,t0 addi a0,a0,0x30 li a7,11 ecall li t0,10 rem a0,s0,t0 addi a0,a0,0x30 li a7,11 ecall anykey: # Wait for user to press any key before clearing the screen and restarting li a7,4 la a0,anykeymsg ecall li a7,8 la a0,inputbuf li a1,7 ecall li a7,4 la a0,clearscreenmsg ecall j _start invalidinput: # Print error message and jump back to the start so the user can try again li a7,4 la a0,inputerrormsg ecall j _start menumsg: .asciz "1: Retail Key\n2: OEM Key\n3: Upgrade Password\n\nEnter your choice:\n" keypromptmsg: .asciz "Enter key: " passwordheadermsg: .asciz "Password: " inputerrormsg: .asciz "Invalid entry\n\n" anykeymsg: .asciz "\n\nPress any key..." oemmsg: .asciz "-OEM-\n0" clearscreenmsg: .asciz "\n\n\n\n\n\n" inputbuf: .skip 7 .globl _start