summaryrefslogtreecommitdiff
path: root/assembly/win95/win95.S
blob: 0ecd394dc2a2c4a2b1662473b288a8f5284cccec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
_start:

# 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

# 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

keypromptmsg: .asciz "Enter key: "
passwordheadermsg: .asciz "Password: "
inputerrormsg: .asciz "Invalid entry\n\n"
anykeymsg: .asciz "\n\nPress any key..."
clearscreenmsg: .asciz "\n\n\n\n\n\n"
inputbuf: .skip 7
.globl _start