1 // Copyright (C) 1999-2012 Core Technologies.
2 //
3 // This file is part of tpasm.
4 //
5 // tpasm is free software; you can redistribute it and/or modify
6 // it under the terms of the tpasm LICENSE AGREEMENT.
7 //
8 // tpasm is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // tpasm LICENSE AGREEMENT for more details.
12 //
13 // You should have received a copy of the tpasm LICENSE AGREEMENT
14 // along with tpasm; see the file "LICENSE.TXT".
15
16 // Generate code for Motorola 6805, or the newer hc08's
17
18 #include "include.h"
19
20 #define SP_PREAMBLE 0x9E // all opcodes which reference SP require this preamble
21
22 static SYM_TABLE
23 *pseudoOpcodeSymbols,
24 *opcodeSymbols6805,
25 *opcodeSymbols68hc08;
26
27 static PROCESSOR
28 *currentProcessor;
29
30 // enumerated addressing modes
31
32 enum
33 {
34 OT_INHERENT, // no operands
35 OT_IMM8, // 8-bit immediate operand
36 OT_IMM16, // 16-bit immediate operand
37 OT_DIRECT, // one byte direct
38 OT_EXTENDED, // two byte absolute
39 OT_INDEXED, // indexed with no offset
40 OT_OFF8_INDEXED, // indexed with 8-bit offset
41 OT_OFF16_INDEXED, // indexed with 16-bit offset
42 OT_OFF8_SP, // stack pointer with 8-bit offset
43 OT_OFF16_SP, // stack pointer with 16-bit offset
44 OT_BIT_DIRECT, // one bit index, one byte of direct
45 OT_IMM8_DIRECT, // 8-bit immediate operand, one byte direct address
46 OT_DIRECT_DIRECT, // one byte direct address, one byte direct address
47 OT_INDEXED_PI_DIRECT, // indexed to direct with post-increment
48 OT_DIRECT_INDEXED_PI, // direct to indexed with post-increment
49 OT_INDEXED_PI, // indexed post-increment
50 OT_OFF8_INDEXED_PI, // indexed with 8 bit offset and post-increment
51 OT_NUM // number of addressing modes
52 };
53
54 // masks for the various addressing modes (all opcodes which use relative offsets are
55 // handled with a separate flag that tells us to expect a relative offset as the last
56 // parameter)
57
58 #define M_INHERENT (1<<OT_INHERENT)
59 #define M_IMM8 (1<<OT_IMM8)
60 #define M_IMM16 (1<<OT_IMM16)
61 #define M_DIRECT (1<<OT_DIRECT)
62 #define M_EXTENDED (1<<OT_EXTENDED)
63 #define M_INDEXED (1<<OT_INDEXED)
64 #define M_OFF8_INDEXED (1<<OT_OFF8_INDEXED)
65 #define M_OFF16_INDEXED (1<<OT_OFF16_INDEXED)
66 #define M_OFF8_SP (1<<OT_OFF8_SP)
67 #define M_OFF16_SP (1<<OT_OFF16_SP)
68 #define M_BIT_DIRECT (1<<OT_BIT_DIRECT)
69 #define M_IMM8_DIRECT (1<<OT_IMM8_DIRECT)
70 #define M_DIRECT_DIRECT (1<<OT_DIRECT_DIRECT)
71 #define M_INDEXED_PI_DIRECT (1<<OT_INDEXED_PI_DIRECT)
72 #define M_DIRECT_INDEXED_PI (1<<OT_DIRECT_INDEXED_PI)
73 #define M_INDEXED_PI (1<<OT_INDEXED_PI)
74 #define M_OFF8_INDEXED_PI (1<<OT_OFF8_INDEXED_PI)
75
76
77 // types of operands which we can discover while parsing
78 enum
79 {
80 POT_INDEX,
81 POT_INDEX_PI, // index with post-increment (X+)
82 POT_SP,
83 POT_IMMEDIATE,
84 POT_VALUE,
85 };
86
87 struct OPCODE
88 {
89 const char
90 *name; // opcode name
91 bool
92 relativeMode; // tells if this opcode requires a relative address as its last operand (in addition to any others that may be specified)
93 unsigned int
94 typeMask; // mask of bits that tells which type of operands are allowed for this opcode
95 unsigned char
96 baseOpcode[OT_NUM]; // list of opcode values -- one for each possible operand type
97 };
98
99 struct OPERAND
100 {
101 unsigned int
102 type; // type of operand located
103 int
104 value; // first immediate value, or non immediate value
105 bool
106 unresolved; // if value was an expression, this tells if it was unresolved
107 };
108
109
110 static PSEUDO_OPCODE
111 pseudoOpcodes[]=
112 {
113 {"db", HandleDB},
114 {"dc.b", HandleDB},
115 {"dw", HandleBEDW}, // words are big endian
116 {"dc.w", HandleBEDW},
117 {"ds", HandleDS},
118 {"ds.b", HandleDS},
119 {"ds.w", HandleDSW},
120 {"incbin", HandleIncbin},
121 };
122
123 // These macros are used to make the opcode table creation simpler and less error prone
124 // Entries which are passed as whitespace are not encoded into typeMask
125 // Entries which are non-whitespace have a bit set in typeMask
126
127 #define OP_FLAG(a,mask) ((sizeof(#a)>1)?mask:0)
128 #define OP_VAL(a) (a+0)
129
130 // This macro creates the typeFlags and baseOpcode list. For each non-white entry in the baseOpcode
131 // list, a bit is set in typeFlags.
132 #define OP_ENTRY(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) OP_FLAG(a,M_INHERENT)|OP_FLAG(b,M_IMM8)|OP_FLAG(c,M_IMM16)|OP_FLAG(d,M_DIRECT)|OP_FLAG(e,M_EXTENDED)|OP_FLAG(f,M_INDEXED)|OP_FLAG(g,M_OFF8_INDEXED)|OP_FLAG(h,M_OFF16_INDEXED)|OP_FLAG(i,M_OFF8_SP)|OP_FLAG(j,M_OFF16_SP)|OP_FLAG(k,M_BIT_DIRECT)|OP_FLAG(l,M_IMM8_DIRECT)|OP_FLAG(m,M_DIRECT_DIRECT)|OP_FLAG(n,M_INDEXED_PI_DIRECT)|OP_FLAG(o,M_DIRECT_INDEXED_PI)|OP_FLAG(p,M_INDEXED_PI)|OP_FLAG(q,M_OFF8_INDEXED_PI),{OP_VAL(a),OP_VAL(b),OP_VAL(c),OP_VAL(d),OP_VAL(e),OP_VAL(f),OP_VAL(g),OP_VAL(h),OP_VAL(i),OP_VAL(j),OP_VAL(k),OP_VAL(l),OP_VAL(m),OP_VAL(n),OP_VAL(o),OP_VAL(p),OP_VAL(q)}
133
134 static OPCODE
135 Opcodes6805[]=
136 {
137 // inh im8 im16 dir ext hx 8hx 16hx 8sp 16sp bd im8d dd hx+d dhx+ hx+ 8hx+
138 {"adc", false,OP_ENTRY( 0,0xA9, 0,0xB9,0xC9,0xF9,0xE9,0xD9, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
139 {"add", false,OP_ENTRY( 0,0xAB, 0,0xBB,0xCB,0xFB,0xEB,0xDB, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
140 {"and", false,OP_ENTRY( 0,0xA4, 0,0xB4,0xC4,0xF4,0xE4,0xD4, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
141 {"asl", false,OP_ENTRY( 0, 0, 0,0x38, 0,0x78,0x68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
142 {"asla", false,OP_ENTRY(0x48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
143 {"aslx", false,OP_ENTRY(0x58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
144 {"asr", false,OP_ENTRY( 0, 0, 0,0x37, 0,0x77,0x67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
145 {"asra", false,OP_ENTRY(0x47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
146 {"asrx", false,OP_ENTRY(0x57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
147 {"bcc", true ,OP_ENTRY(0x24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
148 {"bclr", false,OP_ENTRY( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x11, 0, 0, 0, 0, 0, 0)},
149 {"bclr0", false,OP_ENTRY( 0, 0, 0,0x11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
150 {"bclr1", false,OP_ENTRY( 0, 0, 0,0x13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
151 {"bclr2", false,OP_ENTRY( 0, 0, 0,0x15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
152 {"bclr3", false,OP_ENTRY( 0, 0, 0,0x17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
153 {"bclr4", false,OP_ENTRY( 0, 0, 0,0x19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
154 {"bclr5", false,OP_ENTRY( 0, 0, 0,0x1B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
155 {"bclr6", false,OP_ENTRY( 0, 0, 0,0x1D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
156 {"bclr7", false,OP_ENTRY( 0, 0, 0,0x1F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
157 {"bcs", true ,OP_ENTRY(0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
158 {"beq", true ,OP_ENTRY(0x27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
159 {"bhcc", true ,OP_ENTRY(0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
160 {"bhcs", true ,OP_ENTRY(0x29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
161 {"bhi", true ,OP_ENTRY(0x22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
162 {"bhs", true ,OP_ENTRY(0x24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
163 {"bih", true ,OP_ENTRY(0x2F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
164 {"bil", true ,OP_ENTRY(0x2E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
165 {"bit", false,OP_ENTRY( 0,0xA5, 0,0xB5,0xC5,0xF5,0xE5,0xD5, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
166 {"blo", true ,OP_ENTRY(0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
167 {"bls", true ,OP_ENTRY(0x23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
168 {"bmc", true ,OP_ENTRY(0x2C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
169 {"bmi", true ,OP_ENTRY(0x2B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
170 {"bms", true ,OP_ENTRY(0x2D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
171 {"bne", true ,OP_ENTRY(0x26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
172 {"bpl", true ,OP_ENTRY(0x2A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
173 {"bra", true ,OP_ENTRY(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
174 {"brclr", true ,OP_ENTRY( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x01, 0, 0, 0, 0, 0, 0)},
175 {"brclr0", true ,OP_ENTRY( 0, 0, 0,0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
176 {"brclr1", true ,OP_ENTRY( 0, 0, 0,0x03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
177 {"brclr2", true ,OP_ENTRY( 0, 0, 0,0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
178 {"brclr3", true ,OP_ENTRY( 0, 0, 0,0x07, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
179 {"brclr4", true ,OP_ENTRY( 0, 0, 0,0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
180 {"brclr5", true ,OP_ENTRY( 0, 0, 0,0x0B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
181 {"brclr6", true ,OP_ENTRY( 0, 0, 0,0x0D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
182 {"brclr7", true ,OP_ENTRY( 0, 0, 0,0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
183 {"brn", true ,OP_ENTRY(0x21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
184 {"brset", true ,OP_ENTRY( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x00, 0, 0, 0, 0, 0, 0)},
185 {"brset0", true ,OP_ENTRY( 0, 0, 0,0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
186 {"brset1", true ,OP_ENTRY( 0, 0, 0,0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
187 {"brset2", true ,OP_ENTRY( 0, 0, 0,0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
188 {"brset3", true ,OP_ENTRY( 0, 0, 0,0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
189 {"brset4", true ,OP_ENTRY( 0, 0, 0,0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
190 {"brset5", true ,OP_ENTRY( 0, 0, 0,0x0A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
191 {"brset6", true ,OP_ENTRY( 0, 0, 0,0x0C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
192 {"brset7", true ,OP_ENTRY( 0, 0, 0,0x0E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
193 {"bset", false,OP_ENTRY( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x10, 0, 0, 0, 0, 0, 0)},
194 {"bset0", false,OP_ENTRY( 0, 0, 0,0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
195 {"bset1", false,OP_ENTRY( 0, 0, 0,0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
196 {"bset2", false,OP_ENTRY( 0, 0, 0,0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
197 {"bset3", false,OP_ENTRY( 0, 0, 0,0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
198 {"bset4", false,OP_ENTRY( 0, 0, 0,0x18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
199 {"bset5", false,OP_ENTRY( 0, 0, 0,0x1A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
200 {"bset6", false,OP_ENTRY( 0, 0, 0,0x1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
201 {"bset7", false,OP_ENTRY( 0, 0, 0,0x1E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
202 {"bsr", true ,OP_ENTRY(0xAD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
203 {"clc", false,OP_ENTRY(0x98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
204 {"cli", false,OP_ENTRY(0x9A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
205 {"clr", false,OP_ENTRY( 0, 0, 0,0x3F, 0,0x7F,0x6F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
206 {"clra", false,OP_ENTRY(0x4F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
207 {"clrx", false,OP_ENTRY(0x5F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
208 {"cmp", false,OP_ENTRY( 0,0xA1, 0,0xB1,0xC1,0xF1,0xE1,0xD1, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
209 {"com", false,OP_ENTRY( 0, 0, 0,0x33, 0,0x73,0x63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
210 {"coma", false,OP_ENTRY(0x43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
211 {"comx", false,OP_ENTRY(0x53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
212 {"cpx", false,OP_ENTRY( 0,0xA3, 0,0xB3,0xC3,0xF3,0xE3,0xD3, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
213 {"dec", false,OP_ENTRY( 0, 0, 0,0x3A, 0,0x7A,0x6A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
214 {"deca", false,OP_ENTRY(0x4A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
215 {"decx", false,OP_ENTRY(0x5A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
216 {"dex", false,OP_ENTRY(0x5A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
217 {"eor", false,OP_ENTRY( 0,0xA8, 0,0xB8,0xC8,0xF8,0xE8,0xD8, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
218 {"inc", false,OP_ENTRY( 0, 0, 0,0x3C, 0,0x7C,0x6C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
219 {"inca", false,OP_ENTRY(0x4C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
220 {"incx", false,OP_ENTRY(0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
221 {"inx", false,OP_ENTRY(0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
222 {"jmp", false,OP_ENTRY( 0, 0, 0,0xBC,0xCC,0xFC,0xEC,0xDC, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
223 {"jsr", false,OP_ENTRY( 0, 0, 0,0xBD,0xCD,0xFD,0xED,0xDD, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
224 {"lda", false,OP_ENTRY( 0,0xA6, 0,0xB6,0xC6,0xF6,0xE6,0xD6, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
225 {"ldx", false,OP_ENTRY( 0,0xAE, 0,0xBE,0xCE,0xFE,0xEE,0xDE, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
226 {"lsl", false,OP_ENTRY( 0, 0, 0,0x38, 0,0x78,0x68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
227 {"lsla", false,OP_ENTRY(0x48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
228 {"lslx", false,OP_ENTRY(0x58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
229 {"lsr", false,OP_ENTRY( 0, 0, 0,0x34, 0,0x74,0x64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
230 {"lsra", false,OP_ENTRY(0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
231 {"lsrx", false,OP_ENTRY(0x54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
232 {"mul", false,OP_ENTRY(0x42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
233 {"neg", false,OP_ENTRY( 0, 0, 0,0x30, 0,0x70,0x60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
234 {"nega", false,OP_ENTRY(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
235 {"negx", false,OP_ENTRY(0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
236 {"nop", false,OP_ENTRY(0x9D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
237 {"ora", false,OP_ENTRY( 0,0xAA, 0,0xBA,0xCA,0xFA,0xEA,0xDA, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
238 {"rol", false,OP_ENTRY( 0, 0, 0,0x39, 0,0x79,0x69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
239 {"rola", false,OP_ENTRY(0x49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
240 {"rolx", false,OP_ENTRY(0x59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
241 {"ror", false,OP_ENTRY( 0, 0, 0,0x36, 0,0x76,0x66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
242 {"rora", false,OP_ENTRY(0x46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
243 {"rorx", false,OP_ENTRY(0x56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
244 {"rsp", false,OP_ENTRY(0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
245 {"rti", false,OP_ENTRY(0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
246 {"rts", false,OP_ENTRY(0x81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
247 {"sbc", false,OP_ENTRY( 0,0xA2, 0,0xB2,0xC2,0xF2,0xE2,0xD2, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
248 {"sec", false,OP_ENTRY(0x99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
249 {"sei", false,OP_ENTRY(0x9B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
250 {"sta", false,OP_ENTRY( 0, 0, 0,0xB7,0xC7,0xF7,0xE7,0xD7, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
251 {"stop", false,OP_ENTRY(0x8E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
252 {"stx", false,OP_ENTRY( 0, 0, 0,0xBF,0xCF,0xFF,0xEF,0xDF, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
253 {"sub", false,OP_ENTRY( 0,0xA0, 0,0xB0,0xC0,0xF0,0xE0,0xD0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
254 {"swi", false,OP_ENTRY(0x83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
255 {"tax", false,OP_ENTRY(0x97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
256 {"tst", false,OP_ENTRY( 0, 0, 0,0x3D, 0,0x7D,0x6D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
257 {"tsta", false,OP_ENTRY(0x4D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
258 {"tstx", false,OP_ENTRY(0x5D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
259 {"txa", false,OP_ENTRY(0x9F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
260 {"wait", false,OP_ENTRY(0x8F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
261 };
262
263 static OPCODE
264 Opcodes68hc08[]=
265 {
266 // inh im8 im16 dir ext hx 8hx 16hx 8sp 16sp bd im8d dd hx+d dhx+ hx+ 8hx+
267 {"adc", false,OP_ENTRY( 0,0xA9, 0,0xB9,0xC9,0xF9,0xE9,0xD9,0xE9,0xD9, 0, 0, 0, 0, 0, 0, 0)},
268 {"add", false,OP_ENTRY( 0,0xAB, 0,0xBB,0xCB,0xFB,0xEB,0xDB,0xEB,0xDB, 0, 0, 0, 0, 0, 0, 0)},
269 {"ais", false,OP_ENTRY( 0,0xA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
270 {"aix", false,OP_ENTRY( 0,0xAF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
271 {"and", false,OP_ENTRY( 0,0xA4, 0,0xB4,0xC4,0xF4,0xE4,0xD4,0xE4,0xD4, 0, 0, 0, 0, 0, 0, 0)},
272 {"asl", false,OP_ENTRY( 0, 0, 0,0x38, 0,0x78,0x68, 0,0x68, 0, 0, 0, 0, 0, 0, 0, 0)},
273 {"asla", false,OP_ENTRY(0x48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
274 {"aslx", false,OP_ENTRY(0x58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
275 {"asr", false,OP_ENTRY( 0, 0, 0,0x37, 0,0x77,0x67, 0,0x67, 0, 0, 0, 0, 0, 0, 0, 0)},
276 {"asra", false,OP_ENTRY(0x47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
277 {"asrx", false,OP_ENTRY(0x57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
278 {"bcc", true ,OP_ENTRY(0x24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
279 {"bclr", false,OP_ENTRY( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x11, 0, 0, 0, 0, 0, 0)},
280 {"bclr0", false,OP_ENTRY( 0, 0, 0,0x11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
281 {"bclr1", false,OP_ENTRY( 0, 0, 0,0x13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
282 {"bclr2", false,OP_ENTRY( 0, 0, 0,0x15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
283 {"bclr3", false,OP_ENTRY( 0, 0, 0,0x17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
284 {"bclr4", false,OP_ENTRY( 0, 0, 0,0x19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
285 {"bclr5", false,OP_ENTRY( 0, 0, 0,0x1B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
286 {"bclr6", false,OP_ENTRY( 0, 0, 0,0x1D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
287 {"bclr7", false,OP_ENTRY( 0, 0, 0,0x1F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
288 {"bcs", true ,OP_ENTRY(0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
289 {"beq", true ,OP_ENTRY(0x27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
290 {"bge", true ,OP_ENTRY(0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
291 {"bgt", true ,OP_ENTRY(0x92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
292 {"bhcc", true ,OP_ENTRY(0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
293 {"bhcs", true ,OP_ENTRY(0x29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
294 {"bhi", true ,OP_ENTRY(0x22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
295 {"bhs", true ,OP_ENTRY(0x24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
296 {"bih", true ,OP_ENTRY(0x2F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
297 {"bil", true ,OP_ENTRY(0x2E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
298 {"bit", false,OP_ENTRY( 0,0xA5, 0,0xB5,0xC5,0xF5,0xE5,0xD5,0xE5,0xD5, 0, 0, 0, 0, 0, 0, 0)},
299 {"ble", true ,OP_ENTRY(0x93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
300 {"blo", true ,OP_ENTRY(0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
301 {"bls", true ,OP_ENTRY(0x23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
302 {"blt", true ,OP_ENTRY(0x91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
303 {"bmc", true ,OP_ENTRY(0x2C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
304 {"bmi", true ,OP_ENTRY(0x2B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
305 {"bms", true ,OP_ENTRY(0x2D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
306 {"bne", true ,OP_ENTRY(0x26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
307 {"bpl", true ,OP_ENTRY(0x2A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
308 {"bra", true ,OP_ENTRY(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
309 {"brclr", true ,OP_ENTRY( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x01, 0, 0, 0, 0, 0, 0)},
310 {"brclr0", true ,OP_ENTRY( 0, 0, 0,0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
311 {"brclr1", true ,OP_ENTRY( 0, 0, 0,0x03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
312 {"brclr2", true ,OP_ENTRY( 0, 0, 0,0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
313 {"brclr3", true ,OP_ENTRY( 0, 0, 0,0x07, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
314 {"brclr4", true ,OP_ENTRY( 0, 0, 0,0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
315 {"brclr5", true ,OP_ENTRY( 0, 0, 0,0x0B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
316 {"brclr6", true ,OP_ENTRY( 0, 0, 0,0x0D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
317 {"brclr7", true ,OP_ENTRY( 0, 0, 0,0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
318 {"brn", true ,OP_ENTRY(0x21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
319 {"brset", true ,OP_ENTRY( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x00, 0, 0, 0, 0, 0, 0)},
320 {"brset0", true ,OP_ENTRY( 0, 0, 0,0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
321 {"brset1", true ,OP_ENTRY( 0, 0, 0,0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
322 {"brset2", true ,OP_ENTRY( 0, 0, 0,0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
323 {"brset3", true ,OP_ENTRY( 0, 0, 0,0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
324 {"brset4", true ,OP_ENTRY( 0, 0, 0,0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
325 {"brset5", true ,OP_ENTRY( 0, 0, 0,0x0A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
326 {"brset6", true ,OP_ENTRY( 0, 0, 0,0x0C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
327 {"brset7", true ,OP_ENTRY( 0, 0, 0,0x0E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
328 {"bset", false,OP_ENTRY( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x10, 0, 0, 0, 0, 0, 0)},
329 {"bset0", false,OP_ENTRY( 0, 0, 0,0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
330 {"bset1", false,OP_ENTRY( 0, 0, 0,0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
331 {"bset2", false,OP_ENTRY( 0, 0, 0,0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
332 {"bset3", false,OP_ENTRY( 0, 0, 0,0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
333 {"bset4", false,OP_ENTRY( 0, 0, 0,0x18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
334 {"bset5", false,OP_ENTRY( 0, 0, 0,0x1A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
335 {"bset6", false,OP_ENTRY( 0, 0, 0,0x1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
336 {"bset7", false,OP_ENTRY( 0, 0, 0,0x1E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
337 {"bsr", true ,OP_ENTRY(0xAD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
338 {"cbeq", true ,OP_ENTRY( 0, 0, 0,0x31, 0, 0, 0, 0,0x61, 0, 0, 0, 0, 0, 0,0x71,0x61)},
339 {"cbeqa", true ,OP_ENTRY( 0,0x41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
340 {"cbeqx", true ,OP_ENTRY( 0,0x51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
341 {"clc", false,OP_ENTRY(0x98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
342 {"cli", false,OP_ENTRY(0x9A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
343 {"clr", false,OP_ENTRY( 0, 0, 0,0x3F, 0,0x7F,0x6F, 0,0x6F, 0, 0, 0, 0, 0, 0, 0, 0)},
344 {"clra", false,OP_ENTRY(0x4F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
345 {"clrx", false,OP_ENTRY(0x5F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
346 {"clrh", false,OP_ENTRY(0x8C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
347 {"cmp", false,OP_ENTRY( 0,0xA1, 0,0xB1,0xC1,0xF1,0xE1,0xD1,0xE1,0xD1, 0, 0, 0, 0, 0, 0, 0)},
348 {"com", false,OP_ENTRY( 0, 0, 0,0x33, 0,0x73,0x63, 0,0x63, 0, 0, 0, 0, 0, 0, 0, 0)},
349 {"coma", false,OP_ENTRY(0x43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
350 {"comx", false,OP_ENTRY(0x53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
351 {"cphx", false,OP_ENTRY( 0, 0,0x65,0x75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
352 {"cpx", false,OP_ENTRY( 0,0xA3, 0,0xB3,0xC3,0xF3,0xE3,0xD3,0xE3,0xD3, 0, 0, 0, 0, 0, 0, 0)},
353 {"daa", false,OP_ENTRY(0x72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
354 {"dbnz", true ,OP_ENTRY( 0, 0, 0,0x3B, 0,0x7B,0x6B, 0,0x6B, 0, 0, 0, 0, 0, 0, 0, 0)},
355 {"dbnza", true ,OP_ENTRY(0x4B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
356 {"dbnzx", true ,OP_ENTRY(0x5B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
357 {"dec", false,OP_ENTRY( 0, 0, 0,0x3A, 0,0x7A,0x6A, 0,0x6A, 0, 0, 0, 0, 0, 0, 0, 0)},
358 {"deca", false,OP_ENTRY(0x4A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
359 {"decx", false,OP_ENTRY(0x5A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
360 {"dex", false,OP_ENTRY(0x5A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
361 {"div", false,OP_ENTRY(0x52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
362 {"eor", false,OP_ENTRY( 0,0xA8, 0,0xB8,0xC8,0xF8,0xE8,0xD8,0xE8,0xD8, 0, 0, 0, 0, 0, 0, 0)},
363 {"inc", false,OP_ENTRY( 0, 0, 0,0x3C, 0,0x7C,0x6C, 0,0x6C, 0, 0, 0, 0, 0, 0, 0, 0)},
364 {"inca", false,OP_ENTRY(0x4C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
365 {"incx", false,OP_ENTRY(0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
366 {"inx", false,OP_ENTRY(0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
367 {"jmp", false,OP_ENTRY( 0, 0, 0,0xBC,0xCC,0xFC,0xEC,0xDC, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
368 {"jsr", false,OP_ENTRY( 0, 0, 0,0xBD,0xCD,0xFD,0xED,0xDD, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
369 {"lda", false,OP_ENTRY( 0,0xA6, 0,0xB6,0xC6,0xF6,0xE6,0xD6,0xE6,0xD6, 0, 0, 0, 0, 0, 0, 0)},
370 {"ldhx", false,OP_ENTRY( 0, 0,0x45,0x55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
371 {"ldx", false,OP_ENTRY( 0,0xAE, 0,0xBE,0xCE,0xFE,0xEE,0xDE,0xEE,0xDE, 0, 0, 0, 0, 0, 0, 0)},
372 {"lsl", false,OP_ENTRY( 0, 0, 0,0x38, 0,0x78,0x68, 0,0x68, 0, 0, 0, 0, 0, 0, 0, 0)},
373 {"lsla", false,OP_ENTRY(0x48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
374 {"lslx", false,OP_ENTRY(0x58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
375 {"lsr", false,OP_ENTRY( 0, 0, 0,0x34, 0,0x74,0x64, 0,0x64, 0, 0, 0, 0, 0, 0, 0, 0)},
376 {"lsra", false,OP_ENTRY(0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
377 {"lsrx", false,OP_ENTRY(0x54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
378 {"mov", false,OP_ENTRY( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x6E,0x4E,0x7E,0x5E, 0, 0)},
379 {"mul", false,OP_ENTRY(0x42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
380 {"neg", false,OP_ENTRY( 0, 0, 0,0x30, 0,0x70,0x60, 0,0x60, 0, 0, 0, 0, 0, 0, 0, 0)},
381 {"nega", false,OP_ENTRY(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
382 {"negx", false,OP_ENTRY(0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
383 {"nop", false,OP_ENTRY(0x9D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
384 {"nsa", false,OP_ENTRY(0x62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
385 {"ora", false,OP_ENTRY( 0,0xAA, 0,0xBA,0xCA,0xFA,0xEA,0xDA,0xEA,0xDA, 0, 0, 0, 0, 0, 0, 0)},
386 {"psha", false,OP_ENTRY(0x87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
387 {"pshh", false,OP_ENTRY(0x8B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
388 {"pshx", false,OP_ENTRY(0x89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
389 {"pula", false,OP_ENTRY(0x86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
390 {"pulh", false,OP_ENTRY(0x8A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
391 {"pulx", false,OP_ENTRY(0x88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
392 {"rol", false,OP_ENTRY( 0, 0, 0,0x39, 0,0x79,0x69, 0,0x69, 0, 0, 0, 0, 0, 0, 0, 0)},
393 {"rola", false,OP_ENTRY(0x49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
394 {"rolx", false,OP_ENTRY(0x59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
395 {"ror", false,OP_ENTRY( 0, 0, 0,0x36, 0,0x76,0x66, 0,0x66, 0, 0, 0, 0, 0, 0, 0, 0)},
396 {"rora", false,OP_ENTRY(0x46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
397 {"rorx", false,OP_ENTRY(0x56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
398 {"rsp", false,OP_ENTRY(0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
399 {"rti", false,OP_ENTRY(0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
400 {"rts", false,OP_ENTRY(0x81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
401 {"sbc", false,OP_ENTRY( 0,0xA2, 0,0xB2,0xC2,0xF2,0xE2,0xD2,0xE2,0xD2, 0, 0, 0, 0, 0, 0, 0)},
402 {"sec", false,OP_ENTRY(0x99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
403 {"sei", false,OP_ENTRY(0x9B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
404 {"sta", false,OP_ENTRY( 0, 0, 0,0xB7,0xC7,0xF7,0xE7,0xD7,0xE7,0xD7, 0, 0, 0, 0, 0, 0, 0)},
405 {"sthx", false,OP_ENTRY( 0, 0, 0,0x35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
406 {"stop", false,OP_ENTRY(0x8E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
407 {"stx", false,OP_ENTRY( 0, 0, 0,0xBF,0xCF,0xFF,0xEF,0xDF,0xEF,0xDF, 0, 0, 0, 0, 0, 0, 0)},
408 {"sub", false,OP_ENTRY( 0,0xA0, 0,0xB0,0xC0,0xF0,0xE0,0xD0,0xE0,0xD0, 0, 0, 0, 0, 0, 0, 0)},
409 {"swi", false,OP_ENTRY(0x83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
410 {"tap", false,OP_ENTRY(0x84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
411 {"tax", false,OP_ENTRY(0x97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
412 {"tpa", false,OP_ENTRY(0x85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
413 {"tst", false,OP_ENTRY( 0, 0, 0,0x3D, 0,0x7D,0x6D, 0,0x6D, 0, 0, 0, 0, 0, 0, 0, 0)},
414 {"tsta", false,OP_ENTRY(0x4D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
415 {"tstx", false,OP_ENTRY(0x5D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
416 {"tsx", false,OP_ENTRY(0x95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
417 {"txa", false,OP_ENTRY(0x9F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
418 {"txs", false,OP_ENTRY(0x94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
419 {"wait", false,OP_ENTRY(0x8F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
420 };
421
ParseImmediatePreamble(const char * line,unsigned int * lineIndex)422 static bool ParseImmediatePreamble(const char *line,unsigned int *lineIndex)
423 // Expect a pound sign, step over one if found
424 {
425 if(line[*lineIndex]=='#') // does this look like a '#'?
426 {
427 (*lineIndex)++; // step over it
428 return(true);
429 }
430 return(false);
431 }
432
ParseIndex(const char * line,unsigned int * lineIndex)433 static bool ParseIndex(const char *line,unsigned int *lineIndex)
434 // see if next thing on the line is the index register
435 // return true if so, false otherwise
436 {
437 if(line[*lineIndex]=='X'||line[*lineIndex]=='x')
438 {
439 if(!IsLabelChar(line[(*lineIndex)+1]))
440 {
441 (*lineIndex)++; // step over the register
442 return(true);
443 }
444 }
445 return(false);
446 }
447
ParseSp(const char * line,unsigned int * lineIndex)448 static bool ParseSp(const char *line,unsigned int *lineIndex)
449 // see if next thing on the line is the stack register
450 // return true if so, false otherwise
451 {
452 if(line[*lineIndex]=='S'||line[*lineIndex]=='s')
453 {
454 if(line[(*lineIndex)+1]=='P'||line[(*lineIndex)+1]=='p')
455 {
456 if(!IsLabelChar(line[(*lineIndex)+2]))
457 {
458 (*lineIndex)+=2; // step over the register
459 return(true);
460 }
461 }
462 }
463 return(false);
464 }
465
ParseOperand(const char * line,unsigned int * lineIndex,OPERAND * operand)466 static bool ParseOperand(const char *line,unsigned int *lineIndex,OPERAND *operand)
467 // Try to parse an operand and determine its type
468 // return true if the parsing succeeds
469 {
470 if(ParseImmediatePreamble(line,lineIndex)) // an immediate operand?
471 {
472 if(ParseExpression(line,lineIndex,&operand->value,&operand->unresolved))
473 {
474 operand->type=POT_IMMEDIATE;
475 return(true);
476 }
477 }
478 else if(ParseIndex(line,lineIndex))
479 {
480 if(line[*lineIndex]=='+') // post increment being specified?
481 {
482 (*lineIndex)++;
483 operand->type=POT_INDEX_PI;
484 }
485 else
486 {
487 operand->type=POT_INDEX;
488 }
489 return(true);
490 }
491 else if(ParseSp(line,lineIndex))
492 {
493 operand->type=POT_SP;
494 return(true);
495 }
496 else if(ParseExpression(line,lineIndex,&operand->value,&operand->unresolved))
497 {
498 operand->type=POT_VALUE;
499 return(true);
500 }
501 return(false);
502 }
503
GenerateImmediate8(int value,bool unresolved,LISTING_RECORD * listingRecord)504 static bool GenerateImmediate8(int value,bool unresolved,LISTING_RECORD *listingRecord)
505 // Generate an 8 bit immediate on the output byte stream
506 // if there is a hard failure, return false
507 {
508 CheckByteRange(value,true,true);
509 return(GenerateByte(value,listingRecord));
510 }
511
GenerateImmediate16(int value,bool unresolved,LISTING_RECORD * listingRecord)512 static bool GenerateImmediate16(int value,bool unresolved,LISTING_RECORD *listingRecord)
513 // Generate a 16 bit immediate on the output byte stream
514 // if there is a hard failure, return false
515 {
516 CheckWordRange(value,true,true);
517 if(GenerateByte(value>>8,listingRecord))
518 {
519 return(GenerateByte(value&0xFF,listingRecord));
520 }
521 return(false);
522 }
523
GenerateDirectAddress(int value,bool unresolved,LISTING_RECORD * listingRecord)524 static bool GenerateDirectAddress(int value,bool unresolved,LISTING_RECORD *listingRecord)
525 // Generate a direct address on the output byte stream
526 // if there is a hard failure, return false
527 {
528 CheckUnsignedByteRange(value,true,true);
529 return(GenerateByte(value,listingRecord));
530 }
531
GenerateExtendedAddress(int value,bool unresolved,LISTING_RECORD * listingRecord)532 static bool GenerateExtendedAddress(int value,bool unresolved,LISTING_RECORD *listingRecord)
533 // Generate an extended address on the output byte stream
534 // if there is a hard failure, return false
535 {
536 CheckUnsignedWordRange(value,true,true);
537 if(GenerateByte(value>>8,listingRecord))
538 {
539 return(GenerateByte(value&0xFF,listingRecord));
540 }
541 return(false);
542 }
543
GenerateRelativeOffset(int value,bool unresolved,LISTING_RECORD * listingRecord)544 static bool GenerateRelativeOffset(int value,bool unresolved,LISTING_RECORD *listingRecord)
545 // Generate an relative offset on the output byte stream
546 // if there is a hard failure, return false
547 {
548 unsigned int
549 offset;
550
551 offset=0;
552 if(!unresolved&¤tSegment)
553 {
554 offset=value-(currentSegment->currentPC+currentSegment->codeGenOffset)-1;
555 Check8RelativeRange(offset,true,true);
556 }
557 return(GenerateByte(offset,listingRecord));
558 }
559
GenerateOffset8(int value,bool unresolved,LISTING_RECORD * listingRecord)560 static bool GenerateOffset8(int value,bool unresolved,LISTING_RECORD *listingRecord)
561 // Generate a 8-bit offset on the output byte stream
562 // if there is a hard failure, return false
563 {
564 CheckUnsignedByteRange(value,true,true);
565 return(GenerateByte(value,listingRecord));
566 }
567
GenerateOffset16(int value,bool unresolved,LISTING_RECORD * listingRecord)568 static bool GenerateOffset16(int value,bool unresolved,LISTING_RECORD *listingRecord)
569 // Generate a 16-bit offset on the output byte stream
570 // if there is a hard failure, return false
571 {
572 CheckWordRange(value,true,true); // can be signed too, since address space is 16 bits
573 if(GenerateByte(value>>8,listingRecord))
574 {
575 return(GenerateByte(value&0xFF,listingRecord));
576 }
577 return(false);
578 }
579
580 // ----------------------------------------------------------------------------------------
581
HandleInherent(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)582 static bool HandleInherent(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
583 // Handle an inherent opcode. Return false on hard error
584 {
585 bool
586 fail;
587
588 fail=!GenerateByte(opcode->baseOpcode[OT_INHERENT],listingRecord);
589 if(!fail&&opcode->relativeMode)
590 {
591 fail=!GenerateRelativeOffset(operands[0].value,operands[0].unresolved,listingRecord);
592 }
593 return(!fail);
594 }
595
HandleIndexed(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)596 static bool HandleIndexed(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
597 // Handle X. Return false on hard error
598 {
599 bool
600 fail;
601
602 fail=!GenerateByte(opcode->baseOpcode[OT_INDEXED],listingRecord);
603 if(!fail&&opcode->relativeMode)
604 {
605 fail=!GenerateRelativeOffset(operands[1].value,operands[1].unresolved,listingRecord);
606 }
607 return(!fail);
608 }
609
HandleIndexedPi(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)610 static bool HandleIndexedPi(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
611 // Handle X+. Return false on hard error
612 {
613 bool
614 fail;
615
616 fail=!GenerateByte(opcode->baseOpcode[OT_INDEXED_PI],listingRecord);
617 if(!fail&&opcode->relativeMode)
618 {
619 fail=!GenerateRelativeOffset(operands[1].value,operands[1].unresolved,listingRecord);
620 }
621 return(!fail);
622 }
623
HandleImmediate(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)624 static bool HandleImmediate(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
625 // Handle immediate (8 or 16 bit) values. Return false on hard error
626 {
627 bool
628 fail;
629
630 fail=false;
631 if(opcode->typeMask&M_IMM8)
632 {
633 if(GenerateByte(opcode->baseOpcode[OT_IMM8],listingRecord))
634 {
635 fail=!GenerateImmediate8(operands[0].value,operands[0].unresolved,listingRecord);
636 }
637 else
638 {
639 fail=true;
640 }
641 }
642 else // must be 16 or we would not be here
643 {
644 if(GenerateByte(opcode->baseOpcode[OT_IMM16],listingRecord))
645 {
646 fail=!GenerateImmediate16(operands[0].value,operands[0].unresolved,listingRecord);
647 }
648 else
649 {
650 fail=true;
651 }
652 }
653 if(!fail&&opcode->relativeMode)
654 {
655 fail=!GenerateRelativeOffset(operands[1].value,operands[1].unresolved,listingRecord);
656 }
657 return(!fail);
658 }
659
HandleDirectExtended(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)660 static bool HandleDirectExtended(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
661 // Handle direct/extended address. Return false on hard error
662 {
663 bool
664 fail;
665
666 fail=false;
667 if((opcode->typeMask&M_DIRECT)&&(((operands[0].value>=0)&&(operands[0].value<256))||!(opcode->typeMask&M_EXTENDED)))
668 {
669 if(GenerateByte(opcode->baseOpcode[OT_DIRECT],listingRecord))
670 {
671 fail=!GenerateDirectAddress(operands[0].value,operands[0].unresolved,listingRecord);
672 }
673 else
674 {
675 fail=true;
676 }
677 }
678 else
679 {
680 if(GenerateByte(opcode->baseOpcode[OT_EXTENDED],listingRecord))
681 {
682 fail=!GenerateExtendedAddress(operands[0].value,operands[0].unresolved,listingRecord);
683 }
684 else
685 {
686 fail=true;
687 }
688 }
689 if(!fail&&opcode->relativeMode)
690 {
691 fail=!GenerateRelativeOffset(operands[1].value,operands[1].unresolved,listingRecord);
692 }
693 return(!fail);
694 }
695
HandleIndexedPiDirect(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)696 static bool HandleIndexedPiDirect(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
697 // Handle X+,direct. Return false on hard error
698 {
699 bool
700 fail;
701
702 fail=false;
703 if(GenerateByte(opcode->baseOpcode[OT_INDEXED_PI_DIRECT],listingRecord))
704 {
705 fail=!GenerateDirectAddress(operands[1].value,operands[1].unresolved,listingRecord);
706 }
707 else
708 {
709 fail=true;
710 }
711 if(!fail&&opcode->relativeMode)
712 {
713 fail=!GenerateRelativeOffset(operands[2].value,operands[2].unresolved,listingRecord);
714 }
715 return(!fail);
716 }
717
HandleImmediate8Direct(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)718 static bool HandleImmediate8Direct(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
719 // Handle #immediate,direct. Return false on hard error
720 {
721 bool
722 fail;
723
724 fail=false;
725 if(GenerateByte(opcode->baseOpcode[OT_IMM8_DIRECT],listingRecord))
726 {
727 if(GenerateImmediate8(operands[0].value,operands[0].unresolved,listingRecord))
728 {
729 fail=!GenerateDirectAddress(operands[1].value,operands[1].unresolved,listingRecord);
730 }
731 else
732 {
733 fail=true;
734 }
735 }
736 else
737 {
738 fail=true;
739 }
740 if(!fail&&opcode->relativeMode)
741 {
742 fail=!GenerateRelativeOffset(operands[2].value,operands[2].unresolved,listingRecord);
743 }
744 return(!fail);
745 }
746
HandleOffsetIndexed(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)747 static bool HandleOffsetIndexed(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
748 // Handle offset,X. Return false on hard error
749 {
750 bool
751 fail;
752
753 fail=false;
754 if((opcode->typeMask&M_OFF8_INDEXED)&&(((operands[0].value>=0)&&(operands[0].value<256))||!(opcode->typeMask&M_OFF16_INDEXED)))
755 {
756 if(GenerateByte(opcode->baseOpcode[OT_OFF8_INDEXED],listingRecord))
757 {
758 fail=!GenerateOffset8(operands[0].value,operands[0].unresolved,listingRecord);
759 }
760 else
761 {
762 fail=true;
763 }
764 }
765 else
766 {
767 if(GenerateByte(opcode->baseOpcode[OT_OFF16_INDEXED],listingRecord))
768 {
769 fail=!GenerateOffset16(operands[0].value,operands[0].unresolved,listingRecord);
770 }
771 else
772 {
773 fail=true;
774 }
775 }
776 if(!fail&&opcode->relativeMode)
777 {
778 fail=!GenerateRelativeOffset(operands[2].value,operands[2].unresolved,listingRecord);
779 }
780 return(!fail);
781 }
782
HandleDirectIndexedPi(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)783 static bool HandleDirectIndexedPi(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
784 // Handle direct,X+. Return false on hard error
785 {
786 bool
787 fail;
788
789 fail=false;
790 if(GenerateByte(opcode->baseOpcode[OT_DIRECT_INDEXED_PI],listingRecord))
791 {
792 fail=!GenerateDirectAddress(operands[0].value,operands[0].unresolved,listingRecord);
793 }
794 else
795 {
796 fail=true;
797 }
798 if(!fail&&opcode->relativeMode)
799 {
800 fail=!GenerateRelativeOffset(operands[2].value,operands[2].unresolved,listingRecord);
801 }
802 return(!fail);
803 }
804
HandleOffsetIndexedPi(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)805 static bool HandleOffsetIndexedPi(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
806 // Handle offset,X+. Return false on hard error
807 {
808 bool
809 fail;
810
811 fail=false;
812 if(GenerateByte(opcode->baseOpcode[OT_OFF8_INDEXED_PI],listingRecord))
813 {
814 fail=!GenerateOffset8(operands[0].value,operands[0].unresolved,listingRecord);
815 }
816 else
817 {
818 fail=true;
819 }
820 if(!fail&&opcode->relativeMode)
821 {
822 fail=!GenerateRelativeOffset(operands[2].value,operands[2].unresolved,listingRecord);
823 }
824 return(!fail);
825 }
826
HandleOffsetSp(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)827 static bool HandleOffsetSp(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
828 // Handle offset,SP. Return false on hard error
829 {
830 bool
831 fail;
832
833 fail=false;
834 if(GenerateByte(SP_PREAMBLE,listingRecord)) // output preamble that tells the '08 this is a SP referencing instruction
835 {
836 if((opcode->typeMask&M_OFF8_SP)&&(((operands[0].value>=0)&&(operands[0].value<256))||!(opcode->typeMask&M_OFF16_SP)))
837 {
838 if(GenerateByte(opcode->baseOpcode[OT_OFF8_SP],listingRecord))
839 {
840 fail=!GenerateOffset8(operands[0].value,operands[0].unresolved,listingRecord);
841 }
842 else
843 {
844 fail=true;
845 }
846 }
847 else
848 {
849 if(GenerateByte(opcode->baseOpcode[OT_OFF16_SP],listingRecord))
850 {
851 fail=!GenerateOffset16(operands[0].value,operands[0].unresolved,listingRecord);
852 }
853 else
854 {
855 fail=true;
856 }
857 }
858 }
859 if(!fail&&opcode->relativeMode)
860 {
861 fail=!GenerateRelativeOffset(operands[2].value,operands[2].unresolved,listingRecord);
862 }
863 return(!fail);
864 }
865
HandleBitDirect(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)866 static bool HandleBitDirect(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
867 // Handle bit,direct. Return false on hard error
868 {
869 bool
870 fail;
871
872 fail=false;
873 Check8BitIndexRange(operands[0].value,true,true);
874 operands[0].value&=0x07;
875 if(GenerateByte(opcode->baseOpcode[OT_BIT_DIRECT]|(operands[0].value<<1),listingRecord))
876 {
877 fail=!GenerateDirectAddress(operands[1].value,operands[1].unresolved,listingRecord);
878 }
879 else
880 {
881 fail=true;
882 }
883 if(!fail&&opcode->relativeMode)
884 {
885 fail=!GenerateRelativeOffset(operands[2].value,operands[2].unresolved,listingRecord);
886 }
887 return(!fail);
888 }
889
HandleDirectDirect(OPCODE * opcode,OPERAND * operands,LISTING_RECORD * listingRecord)890 static bool HandleDirectDirect(OPCODE *opcode,OPERAND *operands,LISTING_RECORD *listingRecord)
891 // Handle direct,direct. Return false on hard error
892 {
893 bool
894 fail;
895
896 fail=false;
897 if(GenerateByte(opcode->baseOpcode[OT_DIRECT_DIRECT],listingRecord))
898 {
899 if(GenerateDirectAddress(operands[0].value,operands[0].unresolved,listingRecord))
900 {
901 fail=!GenerateDirectAddress(operands[1].value,operands[1].unresolved,listingRecord);
902 }
903 else
904 {
905 fail=true;
906 }
907 }
908 else
909 {
910 fail=true;
911 }
912 if(!fail&&opcode->relativeMode)
913 {
914 fail=!GenerateRelativeOffset(operands[2].value,operands[2].unresolved,listingRecord);
915 }
916 return(!fail);
917 }
918
ParseOperands(const char * line,unsigned int * lineIndex,unsigned int * numOperands,OPERAND * operands)919 static bool ParseOperands(const char *line,unsigned int *lineIndex,unsigned int *numOperands,OPERAND *operands)
920 // parse from 0 to 3 operands from the line
921 // return the operands parsed
922 // If something does not look right, return false
923 {
924 bool
925 fail;
926 bool
927 initialComma; // only allowed if first parameter is index reg
928
929 fail=false;
930 *numOperands=0;
931 if(!ParseComment(line,lineIndex)) // make sure not at end of line
932 {
933 initialComma=ParseCommaSeparator(line,lineIndex);
934 if(!ParseComment(line,lineIndex)) // make sure not at end of line
935 {
936 if(ParseOperand(line,lineIndex,&operands[0]))
937 {
938 if(!initialComma||(operands[0].type==POT_INDEX)||(operands[0].type==POT_INDEX_PI))
939 {
940 *numOperands=1;
941 if(!ParseComment(line,lineIndex)) // make sure not at end of line
942 {
943 if(ParseCommaSeparator(line,lineIndex))
944 {
945 if(!ParseComment(line,lineIndex)) // make sure not at end of line
946 {
947 if(ParseOperand(line,lineIndex,&operands[1]))
948 {
949 *numOperands=2;
950 if(!ParseComment(line,lineIndex)) // make sure not at end of line
951 {
952 if(ParseCommaSeparator(line,lineIndex))
953 {
954 if(!ParseComment(line,lineIndex)) // make sure not at end of line
955 {
956 if(ParseOperand(line,lineIndex,&operands[2]))
957 {
958 *numOperands=3;
959 if(!ParseComment(line,lineIndex)) // make sure were at end of line
960 {
961 fail=true;
962 }
963 }
964 else
965 {
966 fail=true;
967 }
968 }
969 else
970 {
971 fail=true;
972 }
973 }
974 else
975 {
976 fail=true;
977 }
978 }
979 }
980 else
981 {
982 fail=true;
983 }
984 }
985 else
986 {
987 fail=true;
988 }
989 }
990 else
991 {
992 fail=true;
993 }
994 }
995 }
996 else
997 {
998 fail=true;
999 }
1000 }
1001 }
1002 else
1003 {
1004 fail=true;
1005 }
1006 }
1007 return(!fail);
1008 }
1009
MatchOpcode(const char * string)1010 static OPCODE *MatchOpcode(const char *string)
1011 // match opcodes for this processor, return NULL if none matched
1012 {
1013 return((OPCODE *)STFindDataForNameNoCase(*((SYM_TABLE **)(currentProcessor->processorData)),string));
1014 }
1015
AttemptOpcode(const char * line,unsigned int * lineIndex,LISTING_RECORD * listingRecord,bool * success)1016 static bool AttemptOpcode(const char *line,unsigned int *lineIndex,LISTING_RECORD *listingRecord,bool *success)
1017 // look at the type of opcode available, parse operands as allowed
1018 // If this matches anything, it will set success true.
1019 // If there's some sort of hard failure, this will return false
1020 {
1021 bool
1022 result;
1023 unsigned int
1024 tempIndex;
1025 char
1026 string[MAX_STRING];
1027 OPCODE
1028 *opcode;
1029 unsigned int
1030 numOperands;
1031 OPERAND
1032 operands[3];
1033
1034 result=true; // no hard failure yet
1035 *success=false; // no match yet
1036 tempIndex=*lineIndex;
1037 if(ParseName(line,&tempIndex,string)) // something that looks like an opcode?
1038 {
1039 if((opcode=MatchOpcode(string))) // found opcode?
1040 {
1041 *lineIndex=tempIndex; // actually push forward on the line
1042 *success=true;
1043 if(ParseOperands(line,lineIndex,&numOperands,&operands[0])) // fetch operands for opcode
1044 {
1045 if(!opcode->relativeMode||(numOperands&&(operands[numOperands-1].type==POT_VALUE))) // if relative, make sure last operand is a value
1046 {
1047 switch(opcode->relativeMode?(numOperands-1):numOperands)
1048 {
1049 case 0:
1050 if(opcode->typeMask&M_INHERENT)
1051 {
1052 result=HandleInherent(opcode,operands,listingRecord);
1053 }
1054 else
1055 {
1056 ReportBadOperands();
1057 }
1058 break;
1059 case 1:
1060 switch(operands[0].type)
1061 {
1062 case POT_INDEX:
1063 if(opcode->typeMask&M_INDEXED)
1064 {
1065 result=HandleIndexed(opcode,operands,listingRecord);
1066 }
1067 else
1068 {
1069 ReportBadOperands();
1070 }
1071 break;
1072 case POT_INDEX_PI:
1073 if(opcode->typeMask&M_INDEXED_PI)
1074 {
1075 result=HandleIndexedPi(opcode,operands,listingRecord);
1076 }
1077 else
1078 {
1079 ReportBadOperands();
1080 }
1081 break;
1082 case POT_IMMEDIATE:
1083 if(opcode->typeMask&(M_IMM8|M_IMM16))
1084 {
1085 result=HandleImmediate(opcode,operands,listingRecord);
1086 }
1087 else
1088 {
1089 ReportBadOperands();
1090 }
1091 break;
1092 case POT_VALUE:
1093 if(opcode->typeMask&(M_DIRECT|M_EXTENDED))
1094 {
1095 result=HandleDirectExtended(opcode,operands,listingRecord);
1096 }
1097 else
1098 {
1099 ReportBadOperands();
1100 }
1101 break;
1102 default:
1103 ReportBadOperands();
1104 break;
1105 }
1106 break;
1107 case 2:
1108 switch(operands[0].type)
1109 {
1110 case POT_INDEX_PI:
1111 if((opcode->typeMask&M_INDEXED_PI_DIRECT)&&(operands[1].type==POT_VALUE))
1112 {
1113 result=HandleIndexedPiDirect(opcode,operands,listingRecord);
1114 }
1115 else
1116 {
1117 ReportBadOperands();
1118 }
1119 break;
1120 case POT_IMMEDIATE:
1121 if((opcode->typeMask&M_IMM8_DIRECT)&&(operands[1].type==POT_VALUE))
1122 {
1123 result=HandleImmediate8Direct(opcode,operands,listingRecord);
1124 }
1125 else
1126 {
1127 ReportBadOperands();
1128 }
1129 break;
1130 case POT_VALUE:
1131 switch(operands[1].type)
1132 {
1133 case POT_INDEX:
1134 if(opcode->typeMask&(M_OFF8_INDEXED|M_OFF16_INDEXED))
1135 {
1136 result=HandleOffsetIndexed(opcode,operands,listingRecord);
1137 }
1138 else
1139 {
1140 ReportBadOperands();
1141 }
1142 break;
1143 case POT_INDEX_PI:
1144 if(opcode->typeMask&M_DIRECT_INDEXED_PI)
1145 {
1146 result=HandleDirectIndexedPi(opcode,operands,listingRecord);
1147 }
1148 else if(opcode->typeMask&M_OFF8_INDEXED_PI)
1149 {
1150 result=HandleOffsetIndexedPi(opcode,operands,listingRecord);
1151 }
1152 else
1153 {
1154 ReportBadOperands();
1155 }
1156 break;
1157 case POT_SP:
1158 if(opcode->typeMask&(M_OFF8_SP|M_OFF16_SP))
1159 {
1160 result=HandleOffsetSp(opcode,operands,listingRecord);
1161 }
1162 else
1163 {
1164 ReportBadOperands();
1165 }
1166 break;
1167 case POT_VALUE:
1168 if(opcode->typeMask&M_BIT_DIRECT)
1169 {
1170 result=HandleBitDirect(opcode,operands,listingRecord);
1171 }
1172 else if(opcode->typeMask&M_DIRECT_DIRECT)
1173 {
1174 result=HandleDirectDirect(opcode,operands,listingRecord);
1175 }
1176 else
1177 {
1178 ReportBadOperands();
1179 }
1180 break;
1181 default:
1182 ReportBadOperands();
1183 break;
1184 }
1185 break;
1186 default:
1187 ReportBadOperands();
1188 break;
1189 }
1190 break;
1191 default:
1192 ReportBadOperands();
1193 break;
1194 }
1195 }
1196 else
1197 {
1198 ReportBadOperands();
1199 }
1200 }
1201 else
1202 {
1203 ReportBadOperands();
1204 }
1205 }
1206 }
1207 return(result);
1208 }
1209
AttemptPseudoOpcode(const char * line,unsigned int * lineIndex,const PARSED_LABEL * lineLabel,LISTING_RECORD * listingRecord,bool * success)1210 static bool AttemptPseudoOpcode(const char *line,unsigned int *lineIndex,const PARSED_LABEL *lineLabel,LISTING_RECORD *listingRecord,bool *success)
1211 // See if the next thing on the line looks like a pseudo-op.
1212 // If this matches anything, it will set success true.
1213 // If there's some sort of hard failure, this will return false
1214 {
1215 bool
1216 result;
1217 unsigned int
1218 tempIndex;
1219 char
1220 string[MAX_STRING];
1221 PSEUDO_OPCODE
1222 *opcode;
1223
1224 result=true; // no hard failure yet
1225 *success=false; // no match yet
1226 tempIndex=*lineIndex;
1227 if(ParseName(line,&tempIndex,string)) // something that looks like an opcode?
1228 {
1229 if((opcode=(PSEUDO_OPCODE *)STFindDataForNameNoCase(pseudoOpcodeSymbols,string))) // matches global pseudo-op?
1230 {
1231 *lineIndex=tempIndex; // actually push forward on the line
1232 *success=true;
1233 result=opcode->function(string,line,lineIndex,lineLabel,listingRecord);
1234 }
1235 }
1236 return(result);
1237 }
1238
SelectProcessor(PROCESSOR * processor)1239 static bool SelectProcessor(PROCESSOR *processor)
1240 // A processor in this family is being selected to assemble with
1241 {
1242 currentProcessor=processor;
1243 return(true);
1244 }
1245
DeselectProcessor(PROCESSOR * processor)1246 static void DeselectProcessor(PROCESSOR *processor)
1247 // A processor in this family is being deselected
1248 {
1249 }
1250
UnInitFamily()1251 static void UnInitFamily()
1252 // undo what InitFamily did
1253 {
1254 STDisposeSymbolTable(opcodeSymbols68hc08);
1255 STDisposeSymbolTable(opcodeSymbols6805);
1256 STDisposeSymbolTable(pseudoOpcodeSymbols);
1257 }
1258
InitFamily()1259 static bool InitFamily()
1260 // initialize symbol table
1261 {
1262 unsigned int
1263 i;
1264 bool
1265 fail;
1266
1267 fail=false;
1268 if((pseudoOpcodeSymbols=STNewSymbolTable(elementsof(pseudoOpcodes))))
1269 {
1270 for(i=0;!fail&&(i<elementsof(pseudoOpcodes));i++)
1271 {
1272 if(!STAddEntryAtEnd(pseudoOpcodeSymbols,pseudoOpcodes[i].name,&pseudoOpcodes[i]))
1273 {
1274 fail=true;
1275 }
1276 }
1277 if(!fail)
1278 {
1279 if((opcodeSymbols6805=STNewSymbolTable(elementsof(Opcodes6805))))
1280 {
1281 for(i=0;!fail&&(i<elementsof(Opcodes6805));i++)
1282 {
1283 if(!STAddEntryAtEnd(opcodeSymbols6805,Opcodes6805[i].name,&Opcodes6805[i]))
1284 {
1285 fail=true;
1286 }
1287 }
1288 if(!fail)
1289 {
1290 if((opcodeSymbols68hc08=STNewSymbolTable(elementsof(Opcodes68hc08))))
1291 {
1292 for(i=0;!fail&&(i<elementsof(Opcodes68hc08));i++)
1293 {
1294 if(!STAddEntryAtEnd(opcodeSymbols68hc08,Opcodes68hc08[i].name,&Opcodes68hc08[i]))
1295 {
1296 fail=true;
1297 }
1298 }
1299 if(!fail)
1300 {
1301 return(true);
1302 }
1303 STDisposeSymbolTable(opcodeSymbols68hc08);
1304 }
1305 }
1306 STDisposeSymbolTable(opcodeSymbols6805);
1307 }
1308 }
1309 STDisposeSymbolTable(pseudoOpcodeSymbols);
1310 }
1311 return(false);
1312 }
1313
1314 // processors handled here (the constuctors for these variables link them to the global
1315 // list of processors that the assembler knows how to handle)
1316
1317 static PROCESSOR_FAMILY
1318 processorFamily("Motorola 6805",InitFamily,UnInitFamily,SelectProcessor,DeselectProcessor,AttemptPseudoOpcode,AttemptOpcode);
1319
1320 static PROCESSOR
1321 processors[]=
1322 {
1323 PROCESSOR(&processorFamily,"6805",&opcodeSymbols6805),
1324 PROCESSOR(&processorFamily,"68hc05",&opcodeSymbols6805),
1325 PROCESSOR(&processorFamily,"68705",&opcodeSymbols6805),
1326 PROCESSOR(&processorFamily,"68hc08",&opcodeSymbols68hc08),
1327 };
1328