1 /*****************************************************************************/
5 /* Opcode handler functions for the disassembler */
9 /* (C) 2000 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@musoftware.de */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
52 /*****************************************************************************/
53 /* Helper functions */
54 /*****************************************************************************/
58 static void Mnemonic (const char* M)
59 /* Indent and output a mnemonic */
67 static void OneLine (const OpcDesc* D, const char* Arg, ...) attribute ((format(printf, 2, 3)));
68 static void OneLine (const OpcDesc* D, const char* Arg, ...)
69 /* Output one line with the given mnemonic and argument */
79 xvsprintf (Buf, sizeof (Buf), Arg, ap);
84 /* Add the code stuff as comment */
85 LineComment (PC, D->Size);
93 static const char* GetAddrArg (unsigned Flags, unsigned Addr)
94 /* Return an address argument - a label if we have one, or the address itself */
96 const char* Label = 0;
97 if (Flags & flUseLabel) {
98 Label = GetLabel (Addr);
103 static char Buf [32];
105 xsprintf (Buf, sizeof (Buf), "$%02X", Addr);
107 xsprintf (Buf, sizeof (Buf), "$%04X", Addr);
115 static void GenerateLabel (unsigned Flags, unsigned Addr)
116 /* Generate a label in pass one if requested */
118 if (Pass == 1 && !HaveLabel (Addr)) {
119 if ((Flags & flGenLabel) != 0 ||
120 ((Flags & flUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd)) {
121 AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
128 /*****************************************************************************/
130 /*****************************************************************************/
134 void OH_Illegal (const OpcDesc* D attribute ((unused)))
141 void OH_Accumulator (const OpcDesc* D)
148 void OH_Implicit (const OpcDesc* D)
151 LineComment (PC, D->Size);
157 void OH_Immidiate (const OpcDesc* D)
159 OneLine (D, "#$%02X", GetCodeByte (PC+1));
164 void OH_Direct (const OpcDesc* D)
166 /* Get the operand */
167 unsigned Addr = GetCodeByte (PC+1);
169 /* Generate a label in pass 1 */
170 GenerateLabel (D->Flags, Addr);
172 /* Output the line */
173 OneLine (D, "%s", GetAddrArg (D->Flags, Addr));
178 void OH_DirectX (const OpcDesc* D)
180 /* Get the operand */
181 unsigned Addr = GetCodeByte (PC+1);
183 /* Generate a label in pass 1 */
184 GenerateLabel (D->Flags, Addr);
186 /* Output the line */
187 OneLine (D, "%s,x", GetAddrArg (D->Flags, Addr));
192 void OH_DirectY (const OpcDesc* D)
194 /* Get the operand */
195 unsigned Addr = GetCodeByte (PC+1);
197 /* Generate a label in pass 1 */
198 GenerateLabel (D->Flags, Addr);
200 /* Output the line */
201 OneLine (D, "%s,y", GetAddrArg (D->Flags, Addr));
206 void OH_Absolute (const OpcDesc* D)
208 /* Get the operand */
209 unsigned Addr = GetCodeWord (PC+1);
211 /* Generate a label in pass 1 */
212 GenerateLabel (D->Flags, Addr);
214 /* Output the line */
215 OneLine (D, "%s", GetAddrArg (D->Flags, Addr));
220 void OH_AbsoluteX (const OpcDesc* D)
222 /* Get the operand */
223 unsigned Addr = GetCodeWord (PC+1);
225 /* Generate a label in pass 1 */
226 GenerateLabel (D->Flags, Addr);
228 /* Output the line */
229 OneLine (D, "%s,x", GetAddrArg (D->Flags, Addr));
234 void OH_AbsoluteY (const OpcDesc* D)
236 /* Get the operand */
237 unsigned Addr = GetCodeWord (PC+1);
239 /* Generate a label in pass 1 */
240 GenerateLabel (D->Flags, Addr);
242 /* Output the line */
243 OneLine (D, "%s,y", GetAddrArg (D->Flags, Addr));
248 void OH_AbsoluteLong (const OpcDesc* D attribute ((unused)))
250 Error ("Not implemented");
255 void OH_AbsoluteLongX (const OpcDesc* D attribute ((unused)))
257 Error ("Not implemented");
262 void OH_Relative (const OpcDesc* D)
264 /* Get the operand */
265 signed char Offs = GetCodeByte (PC+1);
267 /* Calculate the target address */
268 unsigned Addr = (unsigned) (((int) PC+2) + Offs);
270 /* Generate a label in pass 1 */
271 GenerateLabel (D->Flags, Addr);
273 /* Output the line */
274 OneLine (D, "%s", GetAddrArg (D->Flags, Addr));
279 void OH_RelativeLong (const OpcDesc* D attribute ((unused)))
281 Error ("Not implemented");
286 void OH_DirectIndirect (const OpcDesc* D)
288 /* Get the operand */
289 unsigned Addr = GetCodeByte (PC+1);
291 /* Generate a label in pass 1 */
292 GenerateLabel (D->Flags, Addr);
294 /* Output the line */
295 OneLine (D, "(%s)", GetAddrArg (D->Flags, Addr));
300 void OH_DirectIndirectY (const OpcDesc* D)
302 /* Get the operand */
303 unsigned Addr = GetCodeByte (PC+1);
305 /* Generate a label in pass 1 */
306 GenerateLabel (D->Flags, Addr);
308 /* Output the line */
309 OneLine (D, "(%s),y", GetAddrArg (D->Flags, Addr));
314 void OH_DirectXIndirect (const OpcDesc* D)
316 /* Get the operand */
317 unsigned Addr = GetCodeByte (PC+1);
319 /* Generate a label in pass 1 */
320 GenerateLabel (D->Flags, Addr);
322 /* Output the line */
323 OneLine (D, "(%s,x)", GetAddrArg (D->Flags, Addr));
328 void OH_AbsoluteIndirect (const OpcDesc* D)
330 /* Get the operand */
331 unsigned Addr = GetCodeWord (PC+1);
333 /* Generate a label in pass 1 */
334 GenerateLabel (D->Flags, Addr);
336 /* Output the line */
337 OneLine (D, "(%s)", GetAddrArg (D->Flags, Addr));
342 void OH_BitBranch (const OpcDesc* D)
344 /* Get the operands */
345 unsigned char TestAddr = GetCodeByte (PC+1);
346 signed char BranchOffs = GetCodeByte (PC+2);
348 /* Calculate the target address for the branch */
349 unsigned BranchAddr = (unsigned) (((int) PC+3) + BranchOffs);
351 /* Generate labels in pass 1. The bit branch codes are special in that
352 * they don't really match the remainder of the 6502 instruction set (they
353 * are a Rockwell addon), so we must pass additional flags as direct
354 * value to the second GenerateLabel call.
356 GenerateLabel (D->Flags, TestAddr);
357 GenerateLabel (flLabel, BranchAddr);
359 /* Output the line */
360 OneLine (D, "%s,%s", GetAddrArg (D->Flags, TestAddr), GetAddrArg (flLabel, BranchAddr));
365 void OH_StackRelative (const OpcDesc* D attribute ((unused)))
367 Error ("Not implemented");
372 void OH_DirectIndirectLongX (const OpcDesc* D attribute ((unused)))
374 Error ("Not implemented");
379 void OH_StackRelativeIndirectY (const OpcDesc* D attribute ((unused)))
381 Error ("Not implemented");
386 void OH_DirectIndirectLong (const OpcDesc* D attribute ((unused)))
388 Error ("Not implemented");
393 void OH_DirectIndirectLongY (const OpcDesc* D attribute ((unused)))
395 Error ("Not implemented");
400 void OH_BlockMove (const OpcDesc* D attribute ((unused)))
402 Error ("Not implemented");
407 void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused)))
409 Error ("Not implemented");
414 void OH_Rts (const OpcDesc* D)
422 void OH_JmpAbsolute (const OpcDesc* D)
430 void OH_JmpAbsoluteIndirect (const OpcDesc* D)
432 OH_AbsoluteIndirect (D);