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&&currentSegment)
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