-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDisassembler_IO_Carbonell.X68
More file actions
329 lines (259 loc) · 8.45 KB
/
Disassembler_IO_Carbonell.X68
File metadata and controls
329 lines (259 loc) · 8.45 KB
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
*-----------------------------------------------------------
* Title : Dissassembler IO Subroutine
* Written by : Aaron Carbonell
* Date : 11/22/2020
* Description: This program scans memory from starting address
* to ending address inputted by user and displays
* mock contents to screen.
*-----------------------------------------------------------
CR EQU $0D
LF EQU $0A
*----- PRECONDITIONS ------*
* - Instruction addresses must be properly formatted hex values
* - Opcode must be properly formatted hex values ready to be read in memory
* - D6: good/bad opcode flag (0 = good, 1 = bad)(NOTE** OPCODE SUBROUTINE SETS THIS FLAG UPON OPCODE PROCESSING)
* - Operands must be be properly formatted hex values ready to be read in memory
* - D7: good/bad operand1 flag (0 = good, 1 = bad) (NOTE** EA SUBROUTINE SETS THESE FLAGS UPON OPCODE PROCESSING)
* - D5: good/bad operand2 flag(0 = good, 1 = bad), (set to 6 if operand2 is actually needed)
*---- POSTCONDITIONS -----*
* - Output memory words to console
ORG $1000
START: ; first instruction of program
* --Prompt user for starting address--
PROMPT_FOR_START
LEA PROMPT_START,A1
MOVE.B #14,D0
TRAP #15
MOVEA.L #0,A1
MOVE.W #2,D0
TRAP #15 Read a string from the keyboard into D1.L
BRA CONV_STRING
* --Prompt user for ending address--
PROMPT_FOR_END
LEA PROMPT_END,A1
MOVE.B #14,D0
TRAP #15
MOVEA.L #0,A1
MOVE.W #2,D0
TRAP #15 Read a string from the keyboard into D1.L
BRA CONV_STRING
*-- Converts ASCII string to Hex equivalent --
CONV_STRING
MOVE.B (A1)+,D0 Get individual char in input string
CMP.B #$46,D0 Check if char is more than F, the last valid hex value
BGT DISPLAY_INVALID_HEX
CMP.B #$41,D0 Check if char is a number or letter
BLT CONV_NUM
**--Convert ASCII char to hex equivalent --
SUB.B #$37, D0
ADD.L D0,D3
SUBI #1,D1
CMP.B #0,D1
BEQ DONE_START_CONV
LSL.L #4,D3
BRA CONV_STRING
* --Display invalid hex error upon invalid input--
DISPLAY_INVALID_HEX
LEA INVALID_HEX,A1
MOVE.B #14,D0
TRAP #15
LEA LINE_BREAK,A1
MOVE.B #14,D0
TRAP #15
CLR D3
CLR D4
BRA PROMPT_FOR_START
* --Converts ASCII num char into hex equivalent--
CONV_NUM
CMP.B #$30,D0
BLT DISPLAY_INVALID_HEX *check if char is less than 30, first valid hex num
CMP.B #$39,D0
BGT DISPLAY_INVALID_HEX *check if char is less than 30, last valid hex num
SUB.B #$30,D0
ADD.L D0,D3
SUBI #1,D1
CMP.B #0,D1
BEQ DONE_START_CONV
LSL.L #4,D3
BRA CONV_STRING
* --Move converted starting address into A3--
DONE_START_CONV
CMP #1,D4
BEQ DONE_END_CONV
ADDI #1,D4
MOVEA.L D3,A3
CLR D3
BRA PROMPT_FOR_END
* --Move converted ending address into A4 and prepare for opcodes--
DONE_END_CONV
CLR.W D4
MOVEA.L D3,A4
CLR D3
CLR D4
CMPA.L A3,A4 check if starting address is less than ending
BMI DISPLAY_INVALID_ORDER
BRA PREPARE_DISPLAY_BUFFER
*-- op code person takes over from here--
*-- derive opcodes starting from start address --*
DISPLAY_INVALID_ORDER
LEA INVALID_ORDER, A1
MOVE.B #14,D0
TRAP #15
LEA LINE_BREAK,A1
MOVE.B #14,D0
TRAP #15
CLR D3
ADDI #1,D4 force to jump straight to DONE_END_CONV when back in DONE_START_CONV
MOVE.W #$0000,A4 clear A4 for reprocessing
BRA PROMPT_FOR_END
* Prepare display buffer (these variables will be filled with real memory upon integration)
PREPARE_DISPLAY_BUFFER
MOVE.W INSTRUCTION_ADDR_MESSAGE, INSTRUCTION_ADDR *-- make placeholder for instruction address
MOVE.W OPCODE_MESSAGE, OPCODE *-- make placeholder for opcode
MOVE.W #OPERAND1_MESSAGE, OPERAND1 *-- make placeholder for first operand
MOVE.W #OPERAND2_MESSAGE, OPERAND2 *-- make placeholder for second operand
*-- Traverse through mock data in memory and print out until ending address
*-- NOTE** displays random YY's which is okay for now. Intent is to demonstrate
*-- the essence of I/O behavior for assembler.
PRINT_INSTRUCTIONS
JSR NEEDS_NEW_SCREEN
CMPA.L A3,A4 *-- check if at end address
BLE REACHED_END
MOVE.W (A3)+,INSTRUCTION_ADDR *get first word in mem
LEA INSTRUCTION_ADDR, A1
MOVE.B #14,D0
TRAP #15
LEA SPACE, A1
MOVE.B #14,D0
TRAP #15
CMP.B #1, D6 *-- check for valid opcode
BEQ DISPLAY_INVALID_INSTRUCTION
MOVE.W (A3)+,OPCODE *get next word in mem
LEA OPCODE, A1
MOVE.B #14,D0
TRAP #15
LEA SPACE, A1
MOVE.B #14,D0
TRAP #15
CMP.B #1, D7 *-- check for valid operand1
BEQ DISPLAY_INVALID_INSTRUCTION
MOVE.W (A3)+,OPERAND1 *get next word in mem
LEA OPERAND1, A1
MOVE.B #14,D0
TRAP #15
MOVE.B #6, D5
CMP.B #6,D5 *-- check if another operand is needed
BEQ PRINT_SECOND_OPERAND
LEA LINE_BREAK,A1
MOVE.B #14,D0
TRAP #15
BRA PRINT_INSTRUCTIONS
*-- Print second operand if needed
PRINT_SECOND_OPERAND
CMP.B #1, D5 *-- check for valid operand2
BEQ DISPLAY_INVALID_INSTRUCTION
LEA COMMA, A1
MOVE.B #14,D0
TRAP #15
MOVE.W (A3)+,OPERAND2 *get next word in mem
LEA OPERAND2, A1
MOVE.B #14,D0
TRAP #15
LEA LINE_BREAK,A1
MOVE.B #14,D0
TRAP #15
BRA PRINT_INSTRUCTIONS
*Display XXXXXXXX DATA YYYY if memory cannot be decoded to legitimate instruction
DISPLAY_INVALID_INSTRUCTION
MOVE.W (A3),INVALID_MEM_ADDR *get invalid word in mem
LEA INVALID_MEM_ADDR, A1
MOVE.B #14,D0
TRAP #15
LEA DATA, A1
MOVE.B #14,D0
TRAP #15
MOVE.W (A3),INVALID_HEX_VAL *get next word in mem
LEA INVALID_HEX_VAL, A1
MOVE.B #14,D0
TRAP #15
BRA PRINT_INSTRUCTIONS
*--Check if output reaches the end of screen
NEEDS_NEW_SCREEN
ADD #1,D4
CMP #26,D4 check if output reaches 25 lines
BEQ PROMPT_USER_FOR_ENTER
LEA SPACE,A1
MOVE #14,D0
TRAP #15
RTS
*--Prompt user to press enter when display reaches line limit
PROMPT_USER_FOR_ENTER
LEA SPACE,A1
MOVE.B #13,D0
TRAP #15
LEA ENTER_MESSAGE, A1 *Prompt user to press enter to display new screen
MOVE.B #14, D0
TRAP #15
CLR D4
MOVE.B #5,D0
TRAP #15
RTS
*--Ask if user wants to disassemble more memory--*
REACHED_END
LEA SPACE, A1
MOVE.B #14,D0
TRAP #15
LEA ASK_REPEAT,A1
MOVE.B #14,D0
TRAP #15
MOVE.B #4,D0
TRAP #15 Read num from the keyboard into D1.L
CMPI.B #0, D1 0 = yes
BEQ CLEAR_REG
CMPI.B #1,D1 1 = no
BEQ DONE
*--Clear all registers for reprocessing--*
CLEAR_REG
CLR D1
CLR D2
CLR D3
CLR D4
CLR D5
CLR D6
MOVE.L #00000000,A0
MOVE.L #00000000,A1
MOVE.L #00000000,A3
MOVE.L #00000000,A4
MOVE.L #00000000,A5
MOVE.L #00000000,A6
BRA PROMPT_FOR_START
* Put variables and constants here
PROMPT_START DC.B 'Please enter starting address in hexadecimal: ' ,0
PROMPT_END DC.B 'Please enter ending address in hexadecimal (must be after starting): ' ,0
INVALID_HEX DC.W 'Error: Address must be in valid hexadecimal' ,CR,LF,0
DONE_MESSAGE DC.B 'Done reading instructions' ,CR,LF,0
ENTER_MESSAGE DC.W 'Please press enter to display new screen ' ,CR,LF,0
INVALID_ORDER DC.W 'Error: ending address must come after starting',CR,LF,0
ASK_REPEAT DC.W 'Disassemble another mem range? (Yes = 0, No = 1) ' ,0
INVALID_MEM_ADDR DS.W 1
DATA DC.W ' DATA ',CR,LF,0
INVALID_HEX_VAL DS.W 1
LINE_BREAK DC.B ' ',CR,LF,0
SPACE DC.W ' ',0
COMMA DC.W ',',0
INSTRUCTION_ADDR DS.B 1
INSTRUCTION_ADDR_MESSAGE DC.W 'INSTRUCTION ADDR',0
OPCODE DS.W 1
OPCODE_MESSAGE DC.W 'OPCODE',0
OPERAND1 DS.W 1
OPERAND1_MESSAGE DC.W 'OPERAND1',0
OPERAND2 DS.W 1
OPERAND2_MESSAGE DC.W 'OPERAND2',0
GOOD_BAD_FLAG DS.B 1
START_ADDR DS.W 4
END_ADDR DS.W 4
DONE
LEA DONE_MESSAGE, A1
MOVE.B #14,D0
TRAP #15
END START ; last line of source