forked from bhristov96/p68k
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser.X68
430 lines (348 loc) · 13.7 KB
/
user.X68
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
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
*
* Subroutines to handle user input and display printing.
*
* ==== user subroutines ====
*-----------------------------------------------------------
* //// get start and end addresses from user
* parameters:
* none
* return:
* a0 - start address
* a6 - end address
*
rl_user_input reg a1-a5/d0-d7
user_input move.w sr, -(sp)
movem.l rl_user_input, -(sp)
* ---- subroutine code:
bsr font_blue
in_loop1 move.b #14, d0
lea msg_start_in, a1
trap #15
bsr read_hex_l
tst.b d6 * if $FF, success
beq in_loop1_bad
bsr check_even
tst.b d4 * if $FF, even
beq in_loop1_odd
bra in_loop1_end
* given string was an invalid start address
in_loop1_bad bsr font_red
move.b #13, d0
lea msg_input_bad, a1
trap #15
bsr font_blue
bra in_loop1
* start address was not even
in_loop1_odd bsr font_red
move.b #13, d0
lea msg_input_odd, a1
trap #15
bsr font_blue
bra in_loop1
in_loop1_end move.l d7, a0
in_loop2 move.b #14, d0
lea msg_end_in, a1
trap #15
bsr read_hex_l
tst.b d6 * if $FF, success
beq bad_end_addr
bsr check_even
tst.b d4 * if $FF, even
beq in_loop2_odd
cmpa.l d7, a0 * if end < start, it's invalid
bls in_loop2_end
* end was lower than start
bsr font_red
move.b #13, d0
lea msg_end_low, a1
trap #15
bsr font_blue
bra in_loop2
* given string was an invalid end address
bad_end_addr bsr font_red
move.b #13, d0
lea msg_input_bad, a1
trap #15
bsr font_blue
bra in_loop2
* end address was not even
in_loop2_odd bsr font_red
move.b #13, d0
lea msg_input_odd, a1
trap #15
bsr font_blue
bra in_loop2
in_loop2_end movea.l d7, a6
bsr font_white
* ---- exit
user_input_x movem.l (sp)+, rl_user_input
rtr
*-----------------------------------------------------------
* //// read hex long value from user, only even values $0 to $FFFFFE
* parameters:
* none
* return:
* d6 - $FF for success, $00 for failure
* d7 - long from user
*
rl_read_hl reg a0-a6/d0-d5
read_hex_l move.w sr, -(sp)
movem.l rl_read_hl, -(sp)
* ---- subroutine code:
sf d6 * set result to $00, failure
clr.l d7 * set return long to 0
move.b #2, d0 * read null-term string from user
lea str_buf, a1
trap #15
cmpi.w #6, d1 * if more than 6 chars, fail
bgt read_hex_l_x
move.b (a1), d5 * get first char
cmpi.b #0, d5 * if it's null, fail - empty string
beq read_hex_l_x
rhl_loop cmpi.b #0, d5 * if char is null, end loop
beq rhl_loop_end
bsr char_to_nib
tst.b d6 * if $00, fail
beq read_hex_l_x
lsl.l #4, d7 * scoot result over by a nibble
add.b d5, d7 * hex value inserted into last 4 bits
addq.l #1, a1 * move to next char in string
move.b (a1), d5 * fetch char from string
bra rhl_loop
rhl_loop_end st d6 * set result to $FF, success
* ---- exit
read_hex_l_x movem.l (sp)+, rl_read_hl
rtr
*-----------------------------------------------------------
* //// convert ascii hex char to nibble
* parameters:
* d5 - ascii char representing a hex digit
* return:
* d5 - byte value of hex digit, $0 to $F
* d6 - $FF for valid hex char, $00 for invalid
*
rl_char_to_nib reg a0-a6/d0-d4/d7
char_to_nib move.w sr, -(sp)
movem.l rl_char_to_nib, -(sp)
* ---- subroutine code:
sf d6 * set result to $00, invalid
cmpi.b #$30, d5 * if ascii < $30, fail
blt char_to_nib_x
cmpi.b #$46, d5 * if ascii > $46, fail
bgt char_to_nib_x
* if $39 < ascii < $41, fail
cmpi.b #$39, d5
sgt d0 * if ascii > $39, d0 = true
cmpi.b #$41, d5
slt d1 * if ascii < $41, d1 = true
and.b d0, d1 * if d0 && d1 == true, fail
bne char_to_nib_x
* at this point, it should be a valid hex char
st d6 * set result to $FF, valid
subi.b #$30, d5 * ascii offset for 0 is $30
tst.b d0 * if d0 == $00, we have char A-F
beq char_to_nib_x
subi.b #$7, d5 * need 7 extra offset for A-F
* ---- exit
char_to_nib_x movem.l (sp)+, rl_char_to_nib
rtr
*-----------------------------------------------------------
* //// check if long is even or odd
* parameters:
* d7 - long to check
* return:
* d4 - $FF for even, $00 for odd
*
rl_check_even reg a0-a6/d0-d3/d5-d7
check_even move.w sr, -(sp)
movem.l rl_check_even, -(sp)
* ---- subroutine code:
divu #2, d7
swap d7
cmpi.w #0, d7
seq d4
* ---- exit
check_even_x movem.l (sp)+, rl_check_even
rtr
*-----------------------------------------------------------
* //// wait for user to press enter to continue
* parameters:
* none
* return:
* none
*
rl_wait_cont reg a0-a6/d0-d7
wait_continue move.w sr, -(sp)
movem.l rl_wait_cont, -(sp)
* ---- subroutine code:
bsr font_orange
move.b #14, d0 * print null-term string without CR, LF
lea msg_continue, a1
trap #15
bsr font_white
move.b #12, d0 * change keyboard echo
sf d1 * disable echo
trap #15
move.b #5, d0 * read char from keyboard
continue_loop trap #15
cmpi.b #CR, d1 * check if char was [Enter]
bne continue_loop
move.b #12, d0 * change keyboard echo
st d1 * enable echo
trap #15
bsr print_nl
* ---- exit
wait_continue_x movem.l (sp)+, rl_wait_cont
rtr
*-----------------------------------------------------------
* //// wait for user to answer yes/no to go again
* parameters:
* none
* return:
* d3 - byte $FF for yes, $00 for no
*
rl_wait_again reg a0-a6/d0-d2/d4-d7
wait_again move.w sr, -(sp)
movem.l rl_wait_again, -(sp)
* ---- subroutine code:
bsr font_blue
move.b #14, d0 * print null-term string without CR, LF
lea msg_again, a1
trap #15
bsr font_white
move.b #12, d0 * change keyboard echo
sf d1 * disable echo
trap #15
move.b #5, d0 * read char from keyboard
again_loop trap #15
cmpi.b #'n', d1
sne d3 * if 'n', set result to no
beq again_loop_end
cmpi.b #'y', d1
bne again_loop
seq d3 * if 'y', set result to yes
again_loop_end move.b #12, d0 * change keyboard echo
st d1 * enable echo
trap #15
bsr print_nl
* ---- exit
wait_again_x movem.l (sp)+, rl_wait_again
rtr
*-----------------------------------------------------------
* //// print test address bounds (as debugging hints)
* parameters:
* none
* return:
* none
*
rl_b_hint reg a0-a6/d0-d7
bound_hint move.w sr, -(sp)
movem.l rl_b_hint, -(sp)
* ---- subroutine code:
* REMOVE THIS SUBROUTINE if test.x68 is removed
bsr font_orange
move.b #14, d0
lea msg_hint1, a1
trap #15
move.l #test_start, d1
bsr print_hex_l
move.b #14, d0
lea msg_hint2, a1
trap #15
move.l #test_end, d1
bsr print_hex_l
bsr print_nl
bsr font_white
* ---- exit
bound_hint_x movem.l (sp)+, rl_b_hint
rtr
*-----------------------------------------------------------
* //// print Team 68++ logo
* parameters:
* none
* return:
* none
*
rl_print_logo reg a0-a6/d0-d7
print_logo move.w sr, -(sp)
movem.l rl_print_logo, -(sp)
* ---- subroutine code:
clr.b d2
bsr font_red * red
move.b #13, d0
lea logo_1, a1
trap #15
move.b #21, d0
move.l #$0000A5FF, d1 * orange
trap #15
move.b #13, d0
lea logo_2, a1
trap #15
move.b #21, d0
move.l #$0000FFFF, d1 * yellow
trap #15
move.b #13, d0
lea logo_3, a1
trap #15
move.b #21, d0
move.l #$0000FF00, d1 * green
trap #15
move.b #13, d0
lea logo_4, a1
trap #15
move.b #21, d0
move.l #$00FFFF00, d1 * light blue
trap #15
move.b #13, d0
lea logo_5, a1
trap #15
move.b #21, d0
move.l #$00D99CB1, d1 * light purple
trap #15
move.b #13, d0
lea logo_6, a1
trap #15
bsr font_white * back to white
* ---- exit
print_logo_x movem.l (sp)+, rl_print_logo
rtr
*-----------------------------------------------------------
* //// print finish message
* parameters:
* none
* return:
* none
*
rl_pr_finish reg a0-a6/d0-d7
print_finish move.w sr, -(sp)
movem.l rl_pr_finish, -(sp)
* ---- subroutine code:
bsr font_blue
move.b #13, d0
lea msg_finish, a1
trap #15
bsr font_white
* ---- exit
print_finish_x movem.l (sp)+, rl_pr_finish
rtr
* ==== constants and variables ====
msg_start_in dc.w 'Start address (even hex, $0-$FFFFFE): $',0
msg_end_in dc.w 'End address (even hex, $0-$FFFFFE): $',0
msg_input_bad dc.w 'Invalid input, try again.',0
msg_end_low dc.w 'End address cannot be less than start address, try again.',0
msg_input_odd dc.w 'Address must be even, try again.',0
msg_continue dc.w '>>> Press [Enter] to continue... ',0
msg_again dc.w '>>> Disassemble again? [y/n]',0
msg_finish dc.w 'Program finished.',0
msg_hint1 dc.w '>>> HINT: test bounds are $',0
msg_hint2 dc.w ' to $',0
logo_1 dc.w ' _______ __ ___ _____ _____',0
logo_2 dc.w ' |__ __| / / / _ \| __ \| __ \',0
logo_3 dc.w ' | | ___ __ _ _ __ ___ / /_ | (_) | |__) | |__) |',0
logo_4 dc.w ' | |/ _ \/ _` | `_ ` _ \ | `_ \ > _ <| ___/| ___/',0
logo_5 dc.w ' | | __/ (_| | | | | | | | (_) | (_) | | | |',0
logo_6 dc.w ' |_|\___|\__,_|_| |_| |_| \___/ \___/|_| |_|',0
*~Font name~Courier New~
*~Font size~10~
*~Tab type~1~
*~Tab size~4~