summaryrefslogtreecommitdiff
path: root/assembly/win95/win95.S
blob: ace9008edf8f4d048fbcf5b3ecf6df8c0b60c446 (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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
_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