1 //-----------------------------------------------------------------------------
2 // Copyright (C) 1999-2012 Core Technologies.
3 //
4 // This file is part of tpasm.
5 //
6 // tpasm is free software; you can redistribute it and/or modify
7 // it under the terms of the tpasm LICENSE AGREEMENT.
8 //
9 // tpasm is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // tpasm LICENSE AGREEMENT for more details.
13 //
14 // You should have received a copy of the tpasm LICENSE AGREEMENT
15 // along with tpasm; see the file "LICENSE.TXT".
16 //
17 //-----------------------------------------------------------------------------
18 //
19 // Motorola MC68HC11 support Copyright (C) 1999 Cosmodog, Ltd.
20 //
21 //-----------------------------------------------------------------------------
22
23
24
25 // 68HC11 ADDRESSING MODE FORMS
26 //
27 // inherent: op
28 // immediate8: op #ii
29 // immediate16: op #jjkk
30 // direct: op dd
31 // extended: op hhll
32 // indexed_x: op ff,x
33 // indexed_y: op ff,y
34 // relative: op rr
35 // bit_direct: op dd,mm
36 // bit_indexed_x: op ff,x,mm
37 // bit_indexed_y: op ff,y,mm
38 // bit_direct_relative: op dd,mm,rr
39 // bit_indexed_x_relative: op ff,x,mm,rr
40 // bit_indexed_y_relative: op ff,y,mm,rr
41 //
42 // ii 8 bit immediate value
43 // jjkk 16 bit immediate value (jj is upper 8 bits, kk is lower 8 bits)
44 // dd 8 bit direct page address
45 // hhll 16 bit address (hh is upper 8 bits, ll is lower 8 bits)
46 // ff 8 bit unsigned offset
47 // rr 8 bit signed offset
48 // mm 8 bit mask
49 //
50 // ff is an implied 0 if it is not included in indexed addressing modes, i.e.,
51 // addd x
52 // addd ,x
53 // addd 0,x
54 // are all the same instruction (and are all valid)
55 //
56
57 #include "include.h"
58
59 static SYM_TABLE
60 *pseudoOpcodeSymbols,
61 *opcodeSymbols;
62
63 // enumerated addressing modes
64
65 enum
66 {
67 OT_INHERENT = 0, // no operands
68 OT_IMMEDIATE8, // one byte immediate operand
69 OT_IMMEDIATE16, // two byte immediate operand
70 OT_DIRECT, // one byte direct
71 OT_EXTENDED, // two byte absolute
72 OT_INDEXED_X,
73 OT_INDEXED_Y,
74 OT_RELATIVE, // one byte relative offset
75 OT_BIT_DIRECT, // one byte direct, one bit mask
76 OT_BIT_INDEXED_X,
77 OT_BIT_INDEXED_Y,
78 OT_BIT_DIRECT_RELATIVE, // one byte direct, one bit mask
79 OT_BIT_INDEXED_X_RELATIVE,
80 OT_BIT_INDEXED_Y_RELATIVE,
81 OT_NUM // number of addressing modes
82 };
83
84
85 // masks for the various addressing modes
86
87 #define M_INHERENT (1<<OT_INHERENT)
88 #define M_IMMEDIATE8 (1<<OT_IMMEDIATE8)
89 #define M_IMMEDIATE16 (1<<OT_IMMEDIATE16)
90 #define M_DIRECT (1<<OT_DIRECT)
91 #define M_EXTENDED (1<<OT_EXTENDED)
92 #define M_INDEXED_X (1<<OT_INDEXED_X)
93 #define M_INDEXED_Y (1<<OT_INDEXED_Y)
94 #define M_RELATIVE (1<<OT_RELATIVE)
95 #define M_BIT_DIRECT (1<<OT_BIT_DIRECT)
96 #define M_BIT_INDEXED_X (1<<OT_BIT_INDEXED_X)
97 #define M_BIT_INDEXED_Y (1<<OT_BIT_INDEXED_Y)
98 #define M_BIT_DIRECT_RELATIVE (1<<OT_BIT_DIRECT_RELATIVE)
99 #define M_BIT_INDEXED_X_RELATIVE (1<<OT_BIT_INDEXED_X_RELATIVE)
100 #define M_BIT_INDEXED_Y_RELATIVE (1<<OT_BIT_INDEXED_Y_RELATIVE)
101
102 typedef unsigned short opcode_t;
103
104 struct OPCODE
105 {
106 const char
107 *name;
108 unsigned int
109 typeMask;
110 opcode_t // opcodes are treated as two bytes to accomodate 'prebyte'. if high byte is zero the opcode is actually one byte
111 baseOpcode[OT_NUM];
112 };
113
114
115 static PSEUDO_OPCODE
116 pseudoOpcodes[]=
117 {
118 {"db", HandleDB},
119 {"dc.b", HandleDB},
120 {"dw", HandleBEDW}, // words are big endian
121 {"dc.w", HandleBEDW},
122 {"ds", HandleDS},
123 {"ds.b", HandleDS},
124 {"ds.w", HandleDSW},
125 {"incbin", HandleIncbin},
126 };
127
128 #define ______ 0 // unused opcode
129
130 static OPCODE
131 Opcodes[]=
132 {
133 // inh imm8 imm16 dir ext indx indy rel bdir binx biny bdr bix biy
134 {"aba", M_INHERENT, {0x001b,______,______,______,______,______,______,______,______,______,______,______,______,______}},
135 {"abx", M_INHERENT, {0x003a,______,______,______,______,______,______,______,______,______,______,______,______,______}},
136 {"aby", M_INHERENT, {0x183a,______,______,______,______,______,______,______,______,______,______,______,______,______}},
137 {"adca", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x0089,______,0x0099,0x00b9,0x00a9,0x18a9,______,______,______,______,______,______,______}},
138 {"adcb", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x00c9,______,0x00d9,0x00f9,0x00e9,0x18e9,______,______,______,______,______,______,______}},
139 {"adda", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x008b,______,0x009b,0x00bb,0x00ab,0x18ab,______,______,______,______,______,______,______}},
140 {"addb", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x00cb,______,0x00db,0x00fb,0x00eb,0x18eb,______,______,______,______,______,______,______}},
141 {"addd", M_IMMEDIATE16|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,0x00c3,0x00d3,0x00f3,0x00e3,0x18e3,______,______,______,______,______,______,______}},
142 {"anda", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x0084,______,0x0094,0x00b4,0x00a4,0x18a4,______,______,______,______,______,______,______}},
143 {"andb", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x00c4,______,0x00d4,0x00f4,0x00e4,0x18e4,______,______,______,______,______,______,______}},
144 {"asla", M_INHERENT, {0x0048,______,______,______,______,______,______,______,______,______,______,______,______,______}},
145 {"aslb", M_INHERENT, {0x0058,______,______,______,______,______,______,______,______,______,______,______,______,______}},
146 {"asl", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x0078,0x0068,0x1868,______,______,______,______,______,______,______}},
147 {"asld", M_INHERENT, {0x0005,______,______,______,______,______,______,______,______,______,______,______,______,______}},
148 {"asra", M_INHERENT, {0x0047,______,______,______,______,______,______,______,______,______,______,______,______,______}},
149 {"asrb", M_INHERENT, {0x0057,______,______,______,______,______,______,______,______,______,______,______,______,______}},
150 {"asr", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x0077,0x0067,0x1867,______,______,______,______,______,______,______}},
151 {"bcc", M_RELATIVE, {______,______,______,______,______,______,______,0x0024,______,______,______,______,______,______}}, // same as bhs
152 {"bclr", M_BIT_DIRECT|M_BIT_INDEXED_X|M_BIT_INDEXED_Y, {______,______,______,______,______,______,______,______,0x0015,0x001d,0x181d,______,______,______}},
153 {"bcs", M_RELATIVE, {______,______,______,______,______,______,______,0x0025,______,______,______,______,______,______}}, // same as blo
154 {"beq", M_RELATIVE, {______,______,______,______,______,______,______,0x0027,______,______,______,______,______,______}},
155 {"bge", M_RELATIVE, {______,______,______,______,______,______,______,0x002c,______,______,______,______,______,______}},
156 {"bgt", M_RELATIVE, {______,______,______,______,______,______,______,0x002e,______,______,______,______,______,______}},
157 {"bhi", M_RELATIVE, {______,______,______,______,______,______,______,0x0022,______,______,______,______,______,______}},
158 {"bhs", M_RELATIVE, {______,______,______,______,______,______,______,0x0024,______,______,______,______,______,______}}, // same as bcc
159 {"bita", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x0085,______,0x0095,0x00b5,0x00a5,0x18a5,______,______,______,______,______,______,______}},
160 {"bitb", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x00c5,______,0x00d5,0x00f5,0x00e5,0x18e5,______,______,______,______,______,______,______}},
161 {"ble", M_RELATIVE, {______,______,______,______,______,______,______,0x002f,______,______,______,______,______,______}},
162 {"blo", M_RELATIVE, {______,______,______,______,______,______,______,0x0025,______,______,______,______,______,______}}, // same as bcs
163 {"bls", M_RELATIVE, {______,______,______,______,______,______,______,0x0023,______,______,______,______,______,______}},
164 {"blt", M_RELATIVE, {______,______,______,______,______,______,______,0x002d,______,______,______,______,______,______}},
165 {"bmi", M_RELATIVE, {______,______,______,______,______,______,______,0x002b,______,______,______,______,______,______}},
166 {"bne", M_RELATIVE, {______,______,______,______,______,______,______,0x0026,______,______,______,______,______,______}},
167 {"bpl", M_RELATIVE, {______,______,______,______,______,______,______,0x002a,______,______,______,______,______,______}},
168 {"bra", M_RELATIVE, {______,______,______,______,______,______,______,0x0020,______,______,______,______,______,______}},
169 {"brclr", M_BIT_DIRECT_RELATIVE|M_BIT_INDEXED_X_RELATIVE|M_BIT_INDEXED_Y_RELATIVE, {______,______,______,______,______,______,______,______,______,______,______,0x0013,0x001f,0x181f}},
170 {"brn", M_RELATIVE, {______,______,______,______,______,______,______,0x0021,______,______,______,______,______,______}},
171 {"brset", M_BIT_DIRECT_RELATIVE|M_BIT_INDEXED_X_RELATIVE|M_BIT_INDEXED_Y_RELATIVE, {______,______,______,______,______,______,______,______,______,______,______,0x0012,0x001e,0x181e}},
172 {"bset", M_BIT_DIRECT|M_BIT_INDEXED_X|M_BIT_INDEXED_Y, {______,______,______,______,______,______,______,______,0x0014,0x001c,0x181c,______,______,______}},
173 {"bsr", M_RELATIVE, {______,______,______,______,______,______,______,0x008d,______,______,______,______,______,______}},
174 {"bvc", M_RELATIVE, {______,______,______,______,______,______,______,0x0028,______,______,______,______,______,______}},
175 {"bvs", M_RELATIVE, {______,______,______,______,______,______,______,0x0029,______,______,______,______,______,______}},
176 {"cba", M_INHERENT, {0x0011,______,______,______,______,______,______,______,______,______,______,______,______,______}},
177 {"clc", M_INHERENT, {0x000c,______,______,______,______,______,______,______,______,______,______,______,______,______}},
178 {"cli", M_INHERENT, {0x000e,______,______,______,______,______,______,______,______,______,______,______,______,______}},
179 {"clra", M_INHERENT, {0x004f,______,______,______,______,______,______,______,______,______,______,______,______,______}},
180 {"clrb", M_INHERENT, {0x005f,______,______,______,______,______,______,______,______,______,______,______,______,______}},
181 {"clr", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x007f,0x006f,0x186f,______,______,______,______,______,______,______}},
182 {"clv", M_INHERENT, {0x000a,______,______,______,______,______,______,______,______,______,______,______,______,______}},
183 {"cmpa", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x0081,______,0x0091,0x00b1,0x00a1,0x18a1,______,______,______,______,______,______,______}},
184 {"cmpb", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x00c1,______,0x00d1,0x00f1,0x00e1,0x18e1,______,______,______,______,______,______,______}},
185 {"coma", M_INHERENT, {0x0043,______,______,______,______,______,______,______,______,______,______,______,______,______}},
186 {"comb", M_INHERENT, {0x0053,______,______,______,______,______,______,______,______,______,______,______,______,______}},
187 {"com", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x0073,0x0063,0x1863,______,______,______,______,______,______,______}},
188 {"cpd", M_IMMEDIATE16|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,0x1a83,0x1a93,0x1ab3,0x1aa3,0xcda3,______,______,______,______,______,______,______}},
189 {"cpx", M_IMMEDIATE16|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,0x008c,0x009c,0x00bc,0x00ac,0xcdac,______,______,______,______,______,______,______}},
190 {"cpy", M_IMMEDIATE16|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,0x188c,0x189c,0x18bc,0x1aac,0x18ac,______,______,______,______,______,______,______}},
191 {"daa", M_INHERENT, {0x0019,______,______,______,______,______,______,______,______,______,______,______,______,______}},
192 {"deca", M_INHERENT, {0x004a,______,______,______,______,______,______,______,______,______,______,______,______,______}},
193 {"decb", M_INHERENT, {0x005a,______,______,______,______,______,______,______,______,______,______,______,______,______}},
194 {"dec", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x007a,0x006a,0x186a,______,______,______,______,______,______,______}},
195 {"des", M_INHERENT, {0x0034,______,______,______,______,______,______,______,______,______,______,______,______,______}},
196 {"dex", M_INHERENT, {0x0009,______,______,______,______,______,______,______,______,______,______,______,______,______}},
197 {"dey", M_INHERENT, {0x1809,______,______,______,______,______,______,______,______,______,______,______,______,______}},
198 {"eora", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x0088,______,0x0098,0x00b8,0x00a8,0x18a8,______,______,______,______,______,______,______}},
199 {"eorb", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x00c8,______,0x00d8,0x00f8,0x00e8,0x18e8,______,______,______,______,______,______,______}},
200 {"fdiv", M_INHERENT, {0x0003,______,______,______,______,______,______,______,______,______,______,______,______,______}},
201 {"idiv", M_INHERENT, {0x0002,______,______,______,______,______,______,______,______,______,______,______,______,______}},
202 {"inca", M_INHERENT, {0x004c,______,______,______,______,______,______,______,______,______,______,______,______,______}},
203 {"incb", M_INHERENT, {0x005c,______,______,______,______,______,______,______,______,______,______,______,______,______}},
204 {"inc", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x007c,0x006c,0x186c,______,______,______,______,______,______,______}},
205 {"ins", M_INHERENT, {0x0031,______,______,______,______,______,______,______,______,______,______,______,______,______}},
206 {"inx", M_INHERENT, {0x0008,______,______,______,______,______,______,______,______,______,______,______,______,______}},
207 {"iny", M_INHERENT, {0x1808,______,______,______,______,______,______,______,______,______,______,______,______,______}},
208 {"jmp", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x007e,0x006e,0x186e,______,______,______,______,______,______,______}},
209 {"jsr", M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,0x009d,0x00bd,0x00ad,0x18ad,______,______,______,______,______,______,______}},
210 {"ldaa", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x0086,______,0x0096,0x00b6,0x00a6,0x18a6,______,______,______,______,______,______,______}},
211 {"ldab", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x00c6,______,0x00d6,0x00f6,0x00e6,0x18e6,______,______,______,______,______,______,______}},
212 {"ldd", M_IMMEDIATE16|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,0x00cc,0x00dc,0x00fc,0x00ec,0x18ec,______,______,______,______,______,______,______}},
213 {"lds", M_IMMEDIATE16|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,0x008e,0x009e,0x00be,0x00ae,0x18ae,______,______,______,______,______,______,______}},
214 {"ldx", M_IMMEDIATE16|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,0x00ce,0x00de,0x00fe,0x00ee,0xcdee,______,______,______,______,______,______,______}},
215 {"ldy", M_IMMEDIATE16|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,0x18ce,0x18de,0x18fe,0x1aee,0x18ee,______,______,______,______,______,______,______}},
216 {"lsla", M_INHERENT, {0x0048,______,______,______,______,______,______,______,______,______,______,______,______,______}},
217 {"lslb", M_INHERENT, {0x0058,______,______,______,______,______,______,______,______,______,______,______,______,______}},
218 {"lsl", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x0078,0x0068,0x1868,______,______,______,______,______,______,______}},
219 {"lsld", M_INHERENT, {0x0005,______,______,______,______,______,______,______,______,______,______,______,______,______}},
220 {"lsra", M_INHERENT, {0x0044,______,______,______,______,______,______,______,______,______,______,______,______,______}},
221 {"lsrb", M_INHERENT, {0x0054,______,______,______,______,______,______,______,______,______,______,______,______,______}},
222 {"lsr", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x0074,0x0064,0x1864,______,______,______,______,______,______,______}},
223 {"lsrd", M_INHERENT, {0x0004,______,______,______,______,______,______,______,______,______,______,______,______,______}},
224 {"mul", M_INHERENT, {0x003d,______,______,______,______,______,______,______,______,______,______,______,______,______}},
225 {"nega", M_INHERENT, {0x0040,______,______,______,______,______,______,______,______,______,______,______,______,______}},
226 {"negb", M_INHERENT, {0x0050,______,______,______,______,______,______,______,______,______,______,______,______,______}},
227 {"neg", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x0070,0x0060,0x1860,______,______,______,______,______,______,______}},
228 {"nop", M_INHERENT, {0x0001,______,______,______,______,______,______,______,______,______,______,______,______,______}},
229 {"oraa", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x008a,______,0x009a,0x00ba,0x00aa,0x18aa,______,______,______,______,______,______,______}},
230 {"orab", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x00ca,______,0x00da,0x00fa,0x00ea,0x18ea,______,______,______,______,______,______,______}},
231 {"psha", M_INHERENT, {0x0036,______,______,______,______,______,______,______,______,______,______,______,______,______}},
232 {"pshb", M_INHERENT, {0x0037,______,______,______,______,______,______,______,______,______,______,______,______,______}},
233 {"pshx", M_INHERENT, {0x003c,______,______,______,______,______,______,______,______,______,______,______,______,______}},
234 {"pshy", M_INHERENT, {0x183c,______,______,______,______,______,______,______,______,______,______,______,______,______}},
235 {"pula", M_INHERENT, {0x0032,______,______,______,______,______,______,______,______,______,______,______,______,______}},
236 {"pulb", M_INHERENT, {0x0033,______,______,______,______,______,______,______,______,______,______,______,______,______}},
237 {"pulx", M_INHERENT, {0x0038,______,______,______,______,______,______,______,______,______,______,______,______,______}},
238 {"puly", M_INHERENT, {0x1838,______,______,______,______,______,______,______,______,______,______,______,______,______}},
239 {"rola", M_INHERENT, {0x0049,______,______,______,______,______,______,______,______,______,______,______,______,______}},
240 {"rolb", M_INHERENT, {0x0059,______,______,______,______,______,______,______,______,______,______,______,______,______}},
241 {"rol", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x0079,0x0069,0x1869,______,______,______,______,______,______,______}},
242 {"rora", M_INHERENT, {0x0046,______,______,______,______,______,______,______,______,______,______,______,______,______}},
243 {"rorb", M_INHERENT, {0x0056,______,______,______,______,______,______,______,______,______,______,______,______,______}},
244 {"ror", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x0076,0x0066,0x1866,______,______,______,______,______,______,______}},
245 {"rti", M_INHERENT, {0x003b,______,______,______,______,______,______,______,______,______,______,______,______,______}},
246 {"rts", M_INHERENT, {0x0039,______,______,______,______,______,______,______,______,______,______,______,______,______}},
247 {"sba", M_INHERENT, {0x0010,______,______,______,______,______,______,______,______,______,______,______,______,______}},
248 {"sbca", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x0082,______,0x0092,0x00b2,0x00a2,0x18a2,______,______,______,______,______,______,______}},
249 {"sbcb", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x00c2,______,0x00d2,0x00f2,0x00e2,0x18e2,______,______,______,______,______,______,______}},
250 {"sec", M_INHERENT, {0x000d,______,______,______,______,______,______,______,______,______,______,______,______,______}},
251 {"sei", M_INHERENT, {0x000f,______,______,______,______,______,______,______,______,______,______,______,______,______}},
252 {"sev", M_INHERENT, {0x000b,______,______,______,______,______,______,______,______,______,______,______,______,______}},
253 {"staa", M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,0x0097,0x00b7,0x00a7,0x18a7,______,______,______,______,______,______,______}},
254 {"stab", M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,0x00d7,0x00f7,0x00e7,0x18e7,______,______,______,______,______,______,______}},
255 {"std", M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,0x00dd,0x00fd,0x00ed,0x18ed,______,______,______,______,______,______,______}},
256 {"stop", M_INHERENT, {0x00cf,______,______,______,______,______,______,______,______,______,______,______,______,______}},
257 {"sts", M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,0x009f,0x00bf,0x00af,0x18af,______,______,______,______,______,______,______}},
258 {"stx", M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,0x00df,0x00ff,0x00ef,0xcdef,______,______,______,______,______,______,______}},
259 {"sty", M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,0x18df,0x18ff,0x1aef,0x18ef,______,______,______,______,______,______,______}},
260 {"suba", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x0080,______,0x0090,0x00b0,0x00a0,0x18a0,______,______,______,______,______,______,______}},
261 {"subb", M_IMMEDIATE8|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,0x00c0,______,0x00d0,0x00f0,0x00e0,0x18e0,______,______,______,______,______,______,______}},
262 {"subd", M_IMMEDIATE16|M_DIRECT|M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,0x0083,0x0093,0x00b3,0x00a3,0x18a3,______,______,______,______,______,______,______}},
263 {"swi", M_INHERENT, {0x003f,______,______,______,______,______,______,______,______,______,______,______,______,______}},
264 {"tab", M_INHERENT, {0x0016,______,______,______,______,______,______,______,______,______,______,______,______,______}},
265 {"tap", M_INHERENT, {0x0006,______,______,______,______,______,______,______,______,______,______,______,______,______}},
266 {"tba", M_INHERENT, {0x0017,______,______,______,______,______,______,______,______,______,______,______,______,______}},
267 {"test", M_INHERENT, {0x0000,______,______,______,______,______,______,______,______,______,______,______,______,______}},
268 {"tpa", M_INHERENT, {0x0007,______,______,______,______,______,______,______,______,______,______,______,______,______}},
269 {"tsta", M_INHERENT, {0x004d,______,______,______,______,______,______,______,______,______,______,______,______,______}},
270 {"tstb", M_INHERENT, {0x005d,______,______,______,______,______,______,______,______,______,______,______,______,______}},
271 {"tst", M_EXTENDED|M_INDEXED_X|M_INDEXED_Y, {______,______,______,______,0x007d,0x006d,0x186d,______,______,______,______,______,______,______}},
272 {"tsx", M_INHERENT, {0x0030,______,______,______,______,______,______,______,______,______,______,______,______,______}},
273 {"tsy", M_INHERENT, {0x1830,______,______,______,______,______,______,______,______,______,______,______,______,______}},
274 {"txs", M_INHERENT, {0x0035,______,______,______,______,______,______,______,______,______,______,______,______,______}},
275 {"tys", M_INHERENT, {0x1835,______,______,______,______,______,______,______,______,______,______,______,______,______}},
276 {"wai", M_INHERENT, {0x003e,______,______,______,______,______,______,______,______,______,______,______,______,______}},
277 {"xgdx", M_INHERENT, {0x008f,______,______,______,______,______,______,______,______,______,______,______,______,______}},
278 {"xgdy", M_INHERENT, {0x188f,______,______,______,______,______,______,______,______,______,______,______,______,______}},
279 };
280 // inh imm8 imm16 dir ext indx indy rel bdir binx biny bdr bix biy
281
ParseImmediatePreamble(const char * line,unsigned int * lineIndex)282 static bool ParseImmediatePreamble(const char *line,unsigned int *lineIndex)
283 // Expect a pound sign, step over one if found
284 {
285 if(line[*lineIndex]=='#') // does this look like a '#'?
286 {
287 (*lineIndex)++; // step over it
288 return(true);
289 }
290 return(false);
291 }
292
ParseIndexX(const char * line,unsigned int * lineIndex)293 static bool ParseIndexX(const char *line,unsigned int *lineIndex)
294 // see if next thing on the line is index register X
295 // return true if so, false otherwise
296 {
297 if(line[*lineIndex]=='X'||line[*lineIndex]=='x')
298 {
299 if(!IsLabelChar(line[(*lineIndex)+1]))
300 {
301 (*lineIndex)++; // step over the register
302 return(true);
303 }
304 }
305 return(false);
306 }
307
ParseIndexY(const char * line,unsigned int * lineIndex)308 static bool ParseIndexY(const char *line,unsigned int *lineIndex)
309 // see if next thing on the line is index register Y
310 // return true if so, false otherwise
311 {
312 if(line[*lineIndex]=='Y'||line[*lineIndex]=='y')
313 {
314 if(!IsLabelChar(line[(*lineIndex)+1]))
315 {
316 (*lineIndex)++; // step over the register
317 return(true);
318 }
319 }
320 return(false);
321 }
322
323 // opcode handling for 68HC11
324
325 enum
326 {
327 POT_INDEX_X,
328 POT_INDEX_Y,
329 POT_IMMEDIATE,
330 POT_VALUE,
331 };
332
ParseOperandElement(const char * line,unsigned int * lineIndex,unsigned int * type,int * value,bool * unresolved)333 static bool ParseOperandElement(const char *line,unsigned int *lineIndex,unsigned int *type,int *value,bool *unresolved)
334 // Try to parse an element of the operand and determine its type
335 // return true if the parsing succeeds
336 {
337 if(ParseImmediatePreamble(line,lineIndex)) // an immediate operand?
338 {
339 if(ParseExpression(line,lineIndex,value,unresolved))
340 {
341 *type=POT_IMMEDIATE;
342 return(true);
343 }
344 }
345 else if(ParseIndexX(line,lineIndex))
346 {
347 *type=POT_INDEX_X;
348 return(true);
349 }
350 else if(ParseIndexY(line,lineIndex))
351 {
352 *type=POT_INDEX_Y;
353 return(true);
354 }
355 else if(ParseExpression(line,lineIndex,value,unresolved))
356 {
357 *type=POT_VALUE;
358 return(true);
359 }
360 return(false);
361 }
362
WriteOpcode(opcode_t opcode,LISTING_RECORD * listingRecord)363 static bool WriteOpcode(opcode_t opcode, LISTING_RECORD *listingRecord)
364 {
365 bool
366 fail = false;
367
368 if(opcode & 0xff00) // if it has a pre-byte (opcode > 0xff) put out both bytes
369 {
370 fail = !GenerateByte((opcode>>8)&0xff,listingRecord);
371 }
372 if(!fail)
373 {
374 fail = !GenerateByte(opcode&0xff,listingRecord);
375 }
376 return(!fail);
377 }
378
HandleImmediate(OPCODE * opcode,int value,bool unresolved,LISTING_RECORD * listingRecord)379 static bool HandleImmediate(OPCODE *opcode,int value,bool unresolved,LISTING_RECORD *listingRecord)
380 // an immediate addressing mode was located
381 {
382 bool
383 fail=false;
384
385 if(opcode->typeMask&M_IMMEDIATE8) // 8-bit immediate value
386 {
387 CheckByteRange(value,true,true);
388 fail = !WriteOpcode(opcode->baseOpcode[OT_IMMEDIATE8],listingRecord);
389 if(!fail)
390 {
391 fail=!GenerateByte(value,listingRecord);
392 }
393 }
394 else if(opcode->typeMask&M_IMMEDIATE16) // 16-bit immediate value
395 {
396 CheckWordRange(value,true,true);
397 fail = !WriteOpcode(opcode->baseOpcode[OT_IMMEDIATE16],listingRecord);
398 if(!fail)
399 {
400 fail = !GenerateByte((value>>8)&0xff,listingRecord);
401 if(!fail)
402 {
403 fail = !GenerateByte(value&0xff,listingRecord);
404 }
405 }
406 }
407 else
408 {
409 ReportBadOperands();
410 }
411 return(!fail);
412 }
413
HandleRelative(OPCODE * opcode,int value,bool unresolved,LISTING_RECORD * listingRecord)414 static bool HandleRelative(OPCODE *opcode,int value,bool unresolved,LISTING_RECORD *listingRecord)
415 // a relative operand has been parsed
416 {
417 bool
418 fail;
419 int
420 offset;
421
422 fail = !WriteOpcode(opcode->baseOpcode[OT_RELATIVE],listingRecord);
423 if(!fail)
424 {
425 offset=0;
426 if(!unresolved&¤tSegment)
427 {
428 offset=value-(currentSegment->currentPC+currentSegment->codeGenOffset)-1;
429 Check8RelativeRange(offset,true,true);
430 }
431 fail=!GenerateByte(offset,listingRecord);
432 }
433 return(!fail);
434 }
435
HandleDirect(OPCODE * opcode,int value,bool unresolved,LISTING_RECORD * listingRecord)436 static bool HandleDirect(OPCODE *opcode,int value,bool unresolved,LISTING_RECORD *listingRecord)
437 // deal with direct mode output only
438 {
439 bool
440 fail;
441
442 fail=false;
443 if(opcode->typeMask&M_DIRECT)
444 {
445 CheckUnsignedByteRange(value,true,true);
446 fail = !WriteOpcode(opcode->baseOpcode[OT_DIRECT],listingRecord);
447 if(!fail)
448 {
449 fail=!GenerateByte(value,listingRecord);
450 }
451 }
452 else
453 {
454 ReportBadOperands();
455 }
456 return(!fail);
457 }
458
HandleExtended(OPCODE * opcode,int value,bool unresolved,LISTING_RECORD * listingRecord)459 static bool HandleExtended(OPCODE *opcode,int value,bool unresolved,LISTING_RECORD *listingRecord)
460 // deal with extended mode output only
461 {
462 bool
463 fail;
464
465 fail=false;
466 if(opcode->typeMask&M_EXTENDED)
467 {
468 CheckUnsignedWordRange(value,true,true);
469 fail = !WriteOpcode(opcode->baseOpcode[OT_EXTENDED],listingRecord);
470 if(!fail)
471 {
472 fail = !GenerateByte(value>>8,listingRecord);
473 if(!fail)
474 {
475 fail=!GenerateByte(value&0xFF,listingRecord);
476 }
477 }
478 }
479 else
480 {
481 ReportBadOperands();
482 }
483 return(!fail);
484 }
485
HandleDirectOrExtended(OPCODE * opcode,int value,bool unresolved,LISTING_RECORD * listingRecord)486 static bool HandleDirectOrExtended(OPCODE *opcode,int value,bool unresolved,LISTING_RECORD *listingRecord)
487 // a direct or extended address has been parsed
488 {
489 bool
490 fail;
491
492 fail=false;
493 if(opcode->typeMask&M_DIRECT)
494 {
495 if(((value>=0)&&(value<256))||!(opcode->typeMask&M_EXTENDED))
496 {
497 fail=!HandleDirect(opcode,value,unresolved,listingRecord);
498 }
499 else
500 {
501 fail=!HandleExtended(opcode,value,unresolved,listingRecord);
502 }
503 }
504 else
505 {
506 fail=!HandleExtended(opcode,value,unresolved,listingRecord);
507 }
508 return(!fail);
509 }
510
HandleSingleAddress(OPCODE * opcode,int value,bool unresolved,LISTING_RECORD * listingRecord)511 static bool HandleSingleAddress(OPCODE *opcode,int value,bool unresolved,LISTING_RECORD *listingRecord)
512 // a lone address has been parsed
513 // This means it is either a relative address (rr), direct (dd), or extended (hhll)
514 {
515 bool
516 fail;
517
518 fail=false;
519 if(opcode->typeMask&M_RELATIVE)
520 {
521 fail=!HandleRelative(opcode,value,unresolved,listingRecord);
522 }
523 else if(opcode->typeMask&(M_DIRECT|M_EXTENDED))
524 {
525 fail=!HandleDirectOrExtended(opcode,value,unresolved,listingRecord);
526 }
527 else
528 {
529 ReportBadOperands();
530 }
531 return(!fail);
532 }
533
HandleIndexedX(OPCODE * opcode,const char * line,unsigned int * lineIndex,int value1,bool unresolved,LISTING_RECORD * listingRecord)534 static bool HandleIndexedX(OPCODE *opcode,const char *line,unsigned int *lineIndex,int value1,bool unresolved,LISTING_RECORD *listingRecord)
535 // indexed x modes:
536 // indexed_x: op ff,x
537 // bit_indexed_x: op ff,x,mm
538 // bit_indexed_x_relative: op ff,x,mm,rr
539 {
540 bool fail = false;
541 int value2;
542 int value3;
543 int offset;
544 bool unresolved2;
545 bool unresolved3;
546 unsigned int elementType;
547
548 if(ParseCommaSeparator(line,lineIndex)) // look for a second separator
549 {
550 if(ParseOperandElement(line,lineIndex,&elementType,&value2,&unresolved2) && (elementType == POT_VALUE) )
551 {
552 if(ParseCommaSeparator(line,lineIndex)) // look for a third separator
553 {
554 if(ParseOperandElement(line,lineIndex,&elementType,&value3,&unresolved3) && (elementType == POT_VALUE) &&
555 ParseComment(line,lineIndex) && opcode->typeMask&M_BIT_INDEXED_X_RELATIVE )
556 {
557 fail = !WriteOpcode(opcode->baseOpcode[OT_BIT_INDEXED_X_RELATIVE],listingRecord);
558 if(!fail)
559 {
560 CheckUnsignedByteRange(value1,true,true); // bit indexed x relative
561 fail=!GenerateByte(value1,listingRecord);
562 if(!fail)
563 {
564 CheckUnsignedByteRange(value2,true,true);
565 fail=!GenerateByte(value2,listingRecord);
566 }
567 if(!fail)
568 {
569 offset=0;
570 if(currentSegment)
571 {
572 offset=value3-(currentSegment->currentPC+currentSegment->codeGenOffset)-1;
573 Check8RelativeRange(offset,true,true);
574 }
575 fail=!GenerateByte(offset,listingRecord);
576 }
577 }
578 }
579 else
580 {
581 ReportBadOperands();
582 }
583 }
584 else if(ParseComment(line,lineIndex) && opcode->typeMask&M_BIT_INDEXED_X) // bit indexed x
585 {
586 CheckUnsignedByteRange(value1,true,true);
587 CheckUnsignedByteRange(value2,true,true);
588 fail = !WriteOpcode(opcode->baseOpcode[OT_BIT_INDEXED_X],listingRecord);
589 if(!fail)
590 {
591 fail=!GenerateByte(value1,listingRecord);
592 if(!fail)
593 {
594 fail=!GenerateByte(value2,listingRecord);
595 }
596 }
597 }
598 else
599 {
600 ReportBadOperands();
601 }
602 }
603 else
604 {
605 ReportBadOperands();
606 }
607 }
608 else if(ParseComment(line,lineIndex))
609 {
610 if(opcode->typeMask&M_INDEXED_X)
611 {
612 CheckUnsignedByteRange(value1,true,true);
613 fail = !WriteOpcode(opcode->baseOpcode[OT_INDEXED_X],listingRecord);
614 if(!fail)
615 {
616 fail=!GenerateByte(value1,listingRecord);
617 }
618 }
619 else
620 {
621 ReportBadOperands();
622 }
623 }
624 else
625 {
626 ReportBadOperands();
627 }
628 return(!fail);
629 }
630
631
HandleIndexedY(OPCODE * opcode,const char * line,unsigned int * lineIndex,int value1,bool unresolved,LISTING_RECORD * listingRecord)632 static bool HandleIndexedY(OPCODE *opcode,const char *line,unsigned int *lineIndex,int value1,bool unresolved,LISTING_RECORD *listingRecord)
633 // indexed y modes:
634 // indexed_y: op ff,y
635 // bit_indexed_y: op ff,y,mm
636 // bit_indexed_y_relative: op ff,y,mm,rr
637 {
638 bool fail = false;
639 int value2;
640 int value3;
641 int offset;
642 bool unresolved2;
643 bool unresolved3;
644 unsigned int elementType;
645
646 if(ParseCommaSeparator(line,lineIndex)) // look for a second separator
647 {
648 if(ParseOperandElement(line,lineIndex,&elementType,&value2,&unresolved2) && (elementType == POT_VALUE) )
649 {
650 if(ParseCommaSeparator(line,lineIndex)) // look for a third separator
651 {
652 if(ParseOperandElement(line,lineIndex,&elementType,&value3,&unresolved3) && (elementType == POT_VALUE) &&
653 ParseComment(line,lineIndex) && opcode->typeMask&M_BIT_INDEXED_Y_RELATIVE )
654 {
655 fail = !WriteOpcode(opcode->baseOpcode[OT_BIT_INDEXED_Y_RELATIVE],listingRecord);
656 if(!fail)
657 {
658 CheckUnsignedByteRange(value1,true,true); // bit indexed y relative
659 fail=!GenerateByte(value1,listingRecord);
660 if(!fail)
661 {
662 CheckUnsignedByteRange(value2,true,true);
663 fail=!GenerateByte(value2,listingRecord);
664 }
665 if(!fail)
666 {
667 offset=0;
668 if(currentSegment)
669 {
670 offset=value3-(currentSegment->currentPC+currentSegment->codeGenOffset)-1;
671 Check8RelativeRange(offset,true,true);
672 }
673 fail=!GenerateByte(offset,listingRecord);
674 }
675 }
676 }
677 else
678 {
679 ReportBadOperands();
680 }
681 }
682 else if(ParseComment(line,lineIndex) && opcode->typeMask&M_BIT_INDEXED_Y) // bit indexed y
683 {
684 CheckUnsignedByteRange(value1,true,true);
685 CheckUnsignedByteRange(value2,true,true);
686 fail = !WriteOpcode(opcode->baseOpcode[OT_BIT_INDEXED_Y],listingRecord);
687 if(!fail)
688 {
689 fail=!GenerateByte(value1,listingRecord);
690 if(!fail)
691 {
692 fail=!GenerateByte(value2,listingRecord);
693 }
694 }
695 }
696 else
697 {
698 ReportBadOperands();
699 }
700 }
701 else
702 {
703 ReportBadOperands();
704 }
705 }
706 else if(ParseComment(line,lineIndex))
707 {
708 if(opcode->typeMask&M_INDEXED_Y)
709 {
710 fail = !WriteOpcode(opcode->baseOpcode[OT_INDEXED_Y],listingRecord);
711 if(!fail)
712 {
713 CheckUnsignedByteRange(value1,true,true);
714 fail=!GenerateByte(value1,listingRecord);
715 }
716 }
717 else
718 {
719 ReportBadOperands();
720 }
721 }
722 else
723 {
724 ReportBadOperands();
725 }
726 return(!fail);
727 }
728
729
HandleBitDirect(OPCODE * opcode,const char * line,unsigned int * lineIndex,int value1,int value2,LISTING_RECORD * listingRecord)730 static bool HandleBitDirect(OPCODE *opcode,const char *line,unsigned int *lineIndex,int value1, int value2,LISTING_RECORD *listingRecord)
731 {
732 bool fail = false;
733 int value3;
734 bool unresolved3;
735 unsigned int elementType;
736 int offset;
737
738 if(ParseCommaSeparator(line,lineIndex)) // separator indicates a third value
739 {
740 if(ParseOperandElement(line,lineIndex,&elementType,&value3,&unresolved3) && elementType==POT_VALUE)
741 {
742 if(ParseComment(line,lineIndex) && opcode->typeMask&M_BIT_DIRECT_RELATIVE)
743 {
744 fail = !WriteOpcode(opcode->baseOpcode[OT_BIT_DIRECT_RELATIVE],listingRecord);
745 if(!fail)
746 {
747 CheckUnsignedByteRange(value1,true,true);
748 fail=!GenerateByte(value1,listingRecord);
749 if(!fail)
750 {
751 CheckUnsignedByteRange(value2,true,true);
752 fail=!GenerateByte(value2,listingRecord);
753 if(!fail)
754 {
755 offset=0;
756 if(currentSegment)
757 {
758 offset=value3-(currentSegment->currentPC+currentSegment->codeGenOffset)-1;
759 Check8RelativeRange(offset,true,true);
760 }
761 fail=!GenerateByte(offset,listingRecord);
762 }
763 }
764 }
765 }
766 else
767 {
768 ReportBadOperands();
769 }
770 }
771 else
772 {
773 ReportBadOperands();
774 }
775 }
776 else if(ParseComment(line,lineIndex) && opcode->typeMask&M_BIT_DIRECT)
777 {
778 fail = !WriteOpcode(opcode->baseOpcode[OT_BIT_DIRECT],listingRecord);
779 if(!fail)
780 {
781 CheckUnsignedByteRange(value1,true,true);
782 fail=!GenerateByte(value1,listingRecord);
783 if(!fail)
784 {
785 CheckUnsignedByteRange(value2,true,true);
786 fail=!GenerateByte(value2,listingRecord);
787 }
788 }
789 }
790 else
791 {
792 ReportBadOperands();
793 }
794 return(!fail);
795
796 }
797
798
HandleFirstValue(OPCODE * opcode,const char * line,unsigned int * lineIndex,int value1,bool unresolved1,LISTING_RECORD * listingRecord)799 static bool HandleFirstValue(OPCODE *opcode,const char *line,unsigned int *lineIndex,int value1,bool unresolved1,LISTING_RECORD *listingRecord)
800 // a non-immediate value was parsed, so see what else we can find
801 {
802 bool
803 fail;
804 unsigned int
805 elementType;
806 int
807 value2;
808 bool
809 unresolved2;
810
811 fail=false;
812 if(ParseCommaSeparator(line,lineIndex)) // make sure the next thing separates operands
813 {
814 if(ParseOperandElement(line,lineIndex,&elementType,&value2,&unresolved2))
815 {
816 switch(elementType)
817 {
818 case POT_INDEX_X: // second operand was X
819 return(HandleIndexedX(opcode,line,lineIndex,value1,unresolved1,listingRecord));
820 break;
821
822 case POT_INDEX_Y: // second operand was Y
823 return(HandleIndexedY(opcode,line,lineIndex,value1,unresolved1,listingRecord));
824 break;
825
826 case POT_VALUE:
827 return(HandleBitDirect(opcode,line,lineIndex,value1,value2,listingRecord));
828 break;
829
830 default:
831 ReportBadOperands();
832 break;
833 }
834 }
835 else
836 {
837 ReportBadOperands();
838 }
839 }
840 else
841 {
842 ReportBadOperands();
843 }
844 return(!fail);
845 }
846
MatchOpcode(const char * string)847 static OPCODE *MatchOpcode(const char *string)
848 // match opcodes for this processor, return NULL if none matched
849 {
850 return((OPCODE *)STFindDataForNameNoCase(opcodeSymbols,string));
851 }
852
AttemptOpcode(const char * line,unsigned int * lineIndex,LISTING_RECORD * listingRecord,bool * success)853 static bool AttemptOpcode(const char *line,unsigned int *lineIndex,LISTING_RECORD *listingRecord,bool *success)
854 // look at the type of opcode available, parse operands as allowed
855 // return false only if there was a 'hard' error
856 //
857 {
858 bool
859 result;
860 unsigned int
861 tempIndex;
862 char
863 string[MAX_STRING];
864 OPCODE
865 *opcode;
866 unsigned int
867 elementType;
868 int
869 value;
870 bool
871 unresolved;
872 bool
873 indexedMode;
874
875 result=true; // no hard failure yet
876 *success=false; // no match yet
877 tempIndex=*lineIndex;
878 if(ParseName(line,&tempIndex,string)) // something that looks like an opcode?
879 {
880 if((opcode=MatchOpcode(string))) // found opcode?
881 {
882 *lineIndex=tempIndex; // actually push forward on the line
883 *success=true;
884 if(!ParseComment(line,lineIndex))
885 {
886 indexedMode=ParseCommaSeparator(line,lineIndex); // if true mode must be indexed
887 if(ParseOperandElement(line,lineIndex,&elementType,&value,&unresolved))
888 {
889 switch(elementType)
890 {
891 case POT_IMMEDIATE:
892 if(!indexedMode && ParseComment(line,lineIndex))
893 {
894 result=HandleImmediate(opcode,value,unresolved,listingRecord);
895 }
896 else
897 {
898 ReportBadOperands();
899 }
900 break;
901
902 case POT_INDEX_X:
903 value = 0;
904 result=HandleIndexedX(opcode,line,lineIndex,value,unresolved,listingRecord);
905 break;
906
907 case POT_INDEX_Y:
908 value = 0;
909 result=HandleIndexedY(opcode,line,lineIndex,value,unresolved,listingRecord);
910 break;
911
912 case POT_VALUE:
913 if(!indexedMode && ParseComment(line,lineIndex)) // if it's followed by comment/EOL, then its a single address
914 {
915 result=HandleSingleAddress(opcode,value,unresolved,listingRecord);
916 }
917 else
918 {
919 result=HandleFirstValue(opcode,line,lineIndex,value,unresolved,listingRecord);
920 }
921 break;
922 }
923 }
924 else
925 {
926 ReportBadOperands();
927 }
928 }
929 else
930 {
931 if(opcode->typeMask&M_INHERENT)
932 {
933 result=WriteOpcode(opcode->baseOpcode[OT_INHERENT],listingRecord);
934 }
935 else
936 {
937 ReportBadOperands();
938 }
939 }
940 }
941 }
942 return(result);
943 }
944
AttemptPseudoOpcode(const char * line,unsigned int * lineIndex,const PARSED_LABEL * lineLabel,LISTING_RECORD * listingRecord,bool * success)945 static bool AttemptPseudoOpcode(const char *line,unsigned int *lineIndex,const PARSED_LABEL *lineLabel,LISTING_RECORD *listingRecord,bool *success)
946 // See if the next thing on the line looks like a pseudo-op.
947 // If so, handle it here and return true.
948 {
949 bool
950 result;
951 unsigned int
952 tempIndex;
953 char
954 string[MAX_STRING];
955 PSEUDO_OPCODE
956 *opcode;
957
958 result=true; // no hard failure yet
959 *success=false; // no match yet
960 tempIndex=*lineIndex;
961 if(ParseName(line,&tempIndex,string)) // something that looks like an opcode?
962 {
963 if((opcode=(PSEUDO_OPCODE *)STFindDataForNameNoCase(pseudoOpcodeSymbols,string))) // matches global pseudo-op?
964 {
965 *lineIndex=tempIndex; // actually push forward on the line
966 *success=true;
967 result=opcode->function(string,line,lineIndex,lineLabel,listingRecord);
968 }
969 }
970 return(result);
971 }
972
SelectProcessor(PROCESSOR * processor)973 static bool SelectProcessor(PROCESSOR *processor)
974 // A processor in this family is being selected to assemble with
975 {
976 return(true);
977 }
978
DeselectProcessor(PROCESSOR * processor)979 static void DeselectProcessor(PROCESSOR *processor)
980 // A processor in this family is being deselected
981 {
982 }
983
UnInitFamily()984 static void UnInitFamily()
985 // undo what InitFamily did
986 {
987 STDisposeSymbolTable(opcodeSymbols);
988 STDisposeSymbolTable(pseudoOpcodeSymbols);
989 }
990
InitFamily()991 static bool InitFamily()
992 // initialize symbol table
993 {
994 unsigned int
995 i;
996 bool
997 fail;
998
999 fail=false;
1000 if((pseudoOpcodeSymbols=STNewSymbolTable(elementsof(pseudoOpcodes))))
1001 {
1002 for(i=0;!fail&&(i<elementsof(pseudoOpcodes));i++)
1003 {
1004 if(!STAddEntryAtEnd(pseudoOpcodeSymbols,pseudoOpcodes[i].name,&pseudoOpcodes[i]))
1005 {
1006 fail=true;
1007 }
1008 }
1009 if(!fail)
1010 {
1011 if((opcodeSymbols=STNewSymbolTable(elementsof(Opcodes))))
1012 {
1013 for(i=0;!fail&&(i<elementsof(Opcodes));i++)
1014 {
1015 if(!STAddEntryAtEnd(opcodeSymbols,Opcodes[i].name,&Opcodes[i]))
1016 {
1017 fail=true;
1018 }
1019 }
1020 if(!fail)
1021 {
1022 return(true);
1023 }
1024 STDisposeSymbolTable(opcodeSymbols);
1025 }
1026 }
1027 STDisposeSymbolTable(pseudoOpcodeSymbols);
1028 }
1029 return(false);
1030 }
1031
1032 // processors handled here (the constuctors for these variables link them to the global
1033 // list of processors that the assembler knows how to handle)
1034
1035 static PROCESSOR_FAMILY
1036 processorFamily("Motorola 68hc11",InitFamily,UnInitFamily,SelectProcessor,DeselectProcessor,AttemptPseudoOpcode,AttemptOpcode);
1037
1038 static PROCESSOR
1039 processors[]=
1040 {
1041 PROCESSOR(&processorFamily,"68hc11",NULL),
1042 };
1043