]> git.sur5r.net Git - cc65/blob - src/da65/handler.c
Added SBC optimizations suggested by Piotr Fusik
[cc65] / src / da65 / handler.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 handler.c                                 */
4 /*                                                                           */
5 /*               Opcode handler functions for the disassembler               */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2000      Ullrich von Bassewitz                                       */
10 /*               Wacholderweg 14                                             */
11 /*               D-70597 Stuttgart                                           */
12 /* EMail:        uz@musoftware.de                                            */
13 /*                                                                           */
14 /*                                                                           */
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.                                    */
18 /*                                                                           */
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:                            */
22 /*                                                                           */
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              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <stdarg.h>
37
38 /* common */
39 #include "xsprintf.h"
40
41 /* da65 */
42 #include "attrtab.h"
43 #include "code.h"
44 #include "error.h"
45 #include "global.h"
46 #include "opctable.h"
47 #include "output.h"
48 #include "handler.h"
49
50
51
52 /*****************************************************************************/
53 /*                             Helper functions                              */
54 /*****************************************************************************/
55
56
57
58 static void Mnemonic (const char* M)
59 /* Indent and output a mnemonic */
60 {
61     Indent (MIndent);
62     Output ("%s", M);
63 }
64
65
66
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 */
70 {
71     char Buf [256];
72     va_list ap;
73
74     /* Mnemonic */
75     Mnemonic (D->Mnemo);
76
77     /* Argument */
78     va_start (ap, Arg);
79     xvsprintf (Buf, sizeof (Buf), Arg, ap);
80     va_end (ap);
81     Indent (AIndent);
82     Output (Buf);
83
84     /* Add the code stuff as comment */
85     LineComment (PC, D->Size);
86
87     /* End the line */
88     LineFeed ();
89 }
90
91
92
93 static const char* GetAddrArg (const OpcDesc* D, unsigned Addr)
94 /* Return an address argument - a label if we have one, or the address itself */
95 {
96     const char* Label = 0;
97     if (D->LabelFlag & lfUseLabel) {
98         Label = GetLabel (Addr);
99     }
100     if (Label) {
101         return Label;
102     } else {
103         static char Buf [32];
104         if (Addr < 0x100) {
105             xsprintf (Buf, sizeof (Buf), "$%02X", Addr);
106         } else {
107             xsprintf (Buf, sizeof (Buf), "$%04X", Addr);
108         }
109         return Buf;
110     }
111 }
112
113
114
115 static void GenerateLabel (const OpcDesc* D, unsigned Addr)
116 /* Generate a label in pass one if requested */
117 {
118     if (Pass == 1 && !HaveLabel (Addr)) {
119         if ((D->LabelFlag & lfGenLabel) != 0 ||
120             ((D->LabelFlag & lfUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd)) {
121             AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
122         }
123     }
124 }
125
126
127
128 /*****************************************************************************/
129 /*                                   Code                                    */
130 /*****************************************************************************/
131
132
133
134 void OH_Accumulator (const OpcDesc* D)
135 {
136     OneLine (D, "a");
137 }
138
139
140
141 void OH_Implicit (const OpcDesc* D)
142 {
143     Mnemonic (D->Mnemo);
144     LineComment (PC, D->Size);
145     LineFeed ();
146 }
147
148
149
150 void OH_Immidiate (const OpcDesc* D)
151 {
152     OneLine (D, "#$%02X", GetCodeByte (PC+1));
153 }
154
155
156
157 void OH_Direct (const OpcDesc* D)
158 {
159     /* Get the operand */
160     unsigned Addr = GetCodeByte (PC+1);
161
162     /* Generate a label in pass 1 */
163     GenerateLabel (D, Addr);
164
165     /* Output the line */
166     OneLine (D, "%s", GetAddrArg (D, Addr));
167 }
168
169
170
171 void OH_DirectX (const OpcDesc* D)
172 {
173     /* Get the operand */
174     unsigned Addr = GetCodeByte (PC+1);
175
176     /* Generate a label in pass 1 */
177     GenerateLabel (D, Addr);
178
179     /* Output the line */
180     OneLine (D, "%s,y", GetAddrArg (D, Addr));
181 }
182
183
184
185 void OH_DirectY (const OpcDesc* D)
186 {
187     /* Get the operand */
188     unsigned Addr = GetCodeByte (PC+1);
189
190     /* Generate a label in pass 1 */
191     GenerateLabel (D, Addr);
192
193     /* Output the line */
194     OneLine (D, "%s,y", GetAddrArg (D, Addr));
195 }
196
197
198
199 void OH_Absolute (const OpcDesc* D)
200 {
201     /* Get the operand */
202     unsigned Addr = GetCodeWord (PC+1);
203
204     /* Generate a label in pass 1 */
205     GenerateLabel (D, Addr);
206
207     /* Output the line */
208     OneLine (D, "%s", GetAddrArg (D, Addr));
209 }
210
211
212
213 void OH_AbsoluteX (const OpcDesc* D)
214 {
215     /* Get the operand */
216     unsigned Addr = GetCodeWord (PC+1);
217
218     /* Generate a label in pass 1 */
219     GenerateLabel (D, Addr);
220
221     /* Output the line */
222     OneLine (D, "%s,x", GetAddrArg (D, Addr));
223 }
224
225
226
227 void OH_AbsoluteY (const OpcDesc* D)
228 {
229     /* Get the operand */
230     unsigned Addr = GetCodeWord (PC+1);
231
232     /* Generate a label in pass 1 */
233     GenerateLabel (D, Addr);
234
235     /* Output the line */
236     OneLine (D, "%s,y", GetAddrArg (D, Addr));
237 }
238
239
240
241 void OH_AbsoluteLong (const OpcDesc* D attribute ((unused)))
242 {
243     Error ("Not implemented");
244 }
245
246
247
248 void OH_AbsoluteLongX (const OpcDesc* D attribute ((unused)))
249 {
250     Error ("Not implemented");
251 }
252
253
254
255 void OH_Relative (const OpcDesc* D)
256 {
257     /* Get the operand */
258     signed char Offs = GetCodeByte (PC+1);
259
260     /* Calculate the target address */
261     unsigned Addr = (unsigned) (((int) PC+2) + Offs);
262
263     /* Generate a label in pass 1 */
264     GenerateLabel (D, Addr);
265
266     /* Output the line */
267     OneLine (D, "%s", GetAddrArg (D, Addr));
268 }
269
270
271
272 void OH_RelativeLong (const OpcDesc* D attribute ((unused)))
273 {
274     Error ("Not implemented");
275 }
276
277
278
279 void OH_DirectIndirect (const OpcDesc* D)
280 {
281     /* Get the operand */
282     unsigned Addr = GetCodeByte (PC+1);
283
284     /* Generate a label in pass 1 */
285     GenerateLabel (D, Addr);
286
287     /* Output the line */
288     OneLine (D, "(%s)", GetAddrArg (D, Addr));
289 }
290
291
292
293 void OH_DirectIndirectY (const OpcDesc* D)
294 {
295     /* Get the operand */
296     unsigned Addr = GetCodeByte (PC+1);
297
298     /* Generate a label in pass 1 */
299     GenerateLabel (D, Addr);
300
301     /* Output the line */
302     OneLine (D, "(%s),y", GetAddrArg (D, Addr));
303 }
304
305
306
307 void OH_DirectXIndirect (const OpcDesc* D)
308 {
309     /* Get the operand */
310     unsigned Addr = GetCodeByte (PC+1);
311
312     /* Generate a label in pass 1 */
313     GenerateLabel (D, Addr);
314
315     /* Output the line */
316     OneLine (D, "(%s,x)", GetAddrArg (D, Addr));
317 }
318
319
320
321 void OH_AbsoluteIndirect (const OpcDesc* D)
322 {
323     /* Get the operand */
324     unsigned Addr = GetCodeWord (PC+1);
325
326     /* Generate a label in pass 1 */
327     GenerateLabel (D, Addr);
328
329     /* Output the line */
330     OneLine (D, "(%s)", GetAddrArg (D, Addr));
331 }
332
333
334
335 void OH_StackRelative (const OpcDesc* D attribute ((unused)))
336 {
337     Error ("Not implemented");
338 }
339
340
341
342 void OH_DirectIndirectLongX (const OpcDesc* D attribute ((unused)))
343 {
344     Error ("Not implemented");
345 }
346
347
348
349 void OH_StackRelativeIndirectY (const OpcDesc* D attribute ((unused)))
350 {
351     Error ("Not implemented");
352 }
353
354
355
356 void OH_DirectIndirectLong (const OpcDesc* D attribute ((unused)))
357 {
358     Error ("Not implemented");
359 }
360
361
362
363 void OH_DirectIndirectLongY (const OpcDesc* D attribute ((unused)))
364 {
365     Error ("Not implemented");
366 }
367
368
369
370 void OH_BlockMove (const OpcDesc* D attribute ((unused)))
371 {
372     Error ("Not implemented");
373 }
374
375
376
377 void OH_AbsoluteXIndirect (const OpcDesc* D attribute ((unused)))
378 {
379     Error ("Not implemented");
380 }
381
382
383
384 void OH_Rts (const OpcDesc* D)
385 {
386     OH_Implicit (D);
387     SeparatorLine();
388 }
389
390
391
392 void OH_JmpAbsolute (const OpcDesc* D)
393 {
394     OH_Absolute (D);
395     SeparatorLine ();
396 }
397
398
399
400 void OH_JmpAbsoluteIndirect (const OpcDesc* D)
401 {
402     OH_AbsoluteIndirect (D);
403     SeparatorLine ();
404 }
405
406
407