Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1186 | savelij | 1 | /* codetms1.c */ |
2 | /*****************************************************************************/ |
||
3 | /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */ |
||
4 | /* */ |
||
5 | /* AS-Portierung */ |
||
6 | /* */ |
||
7 | /* Codegenerator TMS1000-Familie */ |
||
8 | /* */ |
||
9 | /*****************************************************************************/ |
||
10 | |||
11 | #include "stdinc.h" |
||
12 | #include <ctype.h> |
||
13 | #include <string.h> |
||
14 | |||
15 | #include "bpemu.h" |
||
16 | #include "strutil.h" |
||
17 | #include "asmdef.h" |
||
18 | #include "asmsub.h" |
||
19 | #include "asmpars.h" |
||
20 | #include "asmitree.h" |
||
21 | #include "codevars.h" |
||
22 | #include "headids.h" |
||
23 | #include "codepseudo.h" |
||
24 | #include "intpseudo.h" |
||
25 | #include "errmsg.h" |
||
26 | |||
27 | #include "codetms1.h" |
||
28 | |||
29 | static CPUVar CPU1000, CPU1100, CPU1200, CPU1300; |
||
30 | static IntType CodeAdrIntType, DataAdrIntType; |
||
31 | |||
32 | /* 2/3/4-bit-operand in instruction is bit-mirrored */ |
||
33 | |||
34 | static const Byte BitMirr[16] = |
||
35 | { |
||
36 | 0, 8, 4, 12, 2, 10, 6, 14, |
||
37 | 1, 9, 5, 13, 3, 11, 7, 15 |
||
38 | }; |
||
39 | |||
40 | /*---------------------------------------------------------------------------*/ |
||
41 | /* Decoders */ |
||
42 | |||
43 | static void DecodeFixed(Word Code) |
||
44 | { |
||
45 | if (ChkArgCnt(0, 0)) |
||
46 | { |
||
47 | BAsmCode[0] = Lo(Code); |
||
48 | CodeLen = 1; |
||
49 | } |
||
50 | } |
||
51 | |||
52 | static void DecodeConst4(Word Code) |
||
53 | { |
||
54 | if (ChkArgCnt(1, 1)) |
||
55 | { |
||
56 | Boolean OK; |
||
57 | BAsmCode[0] = EvalStrIntExpression(&ArgStr[1], Int4, &OK); |
||
58 | if (OK) |
||
59 | { |
||
60 | BAsmCode[0] = BitMirr[BAsmCode[0] & 0x0f] | (Code & 0xf0); |
||
61 | CodeLen = 1; |
||
62 | } |
||
63 | } |
||
64 | } |
||
65 | |||
66 | static void DecodeConst3(Word Code) |
||
67 | { |
||
68 | if (ChkArgCnt(1, 1)) |
||
69 | { |
||
70 | Boolean OK; |
||
71 | BAsmCode[0] = EvalStrIntExpression(&ArgStr[1], UInt3, &OK); |
||
72 | if (OK) |
||
73 | { |
||
74 | BAsmCode[0] = (BitMirr[BAsmCode[0] & 0x07] >> 1) | (Code & 0xf8); |
||
75 | CodeLen = 1; |
||
76 | } |
||
77 | } |
||
78 | } |
||
79 | |||
80 | static void DecodeConst2(Word Code) |
||
81 | { |
||
82 | if (ChkArgCnt(1, 1)) |
||
83 | { |
||
84 | Boolean OK; |
||
85 | BAsmCode[0] = EvalStrIntExpression(&ArgStr[1], UInt2, &OK); |
||
86 | if (OK) |
||
87 | { |
||
88 | BAsmCode[0] = (BitMirr[BAsmCode[0] & 0x03] >> 2) | (Code & 0xfc); |
||
89 | CodeLen = 1; |
||
90 | } |
||
91 | } |
||
92 | } |
||
93 | |||
94 | static void DecodeJmp(Word Code) |
||
95 | { |
||
96 | if (ChkArgCnt(1, 1)) |
||
97 | { |
||
98 | tEvalResult EvalResult; |
||
99 | Word Addr = EvalStrIntExpressionWithResult(&ArgStr[1], CodeAdrIntType, &EvalResult); |
||
100 | if (EvalResult.OK) |
||
101 | { |
||
102 | ChkSpace(SegCode, EvalResult.AddrSpaceMask); |
||
103 | CodeLen = 1; |
||
104 | BAsmCode[0] = (Code & 0xc0) | (Addr & 0x3f); |
||
105 | } |
||
106 | } |
||
107 | } |
||
108 | |||
109 | static void DecodeJmpL(Word Code) |
||
110 | { |
||
111 | UNUSED(Code); |
||
112 | |||
113 | if (ChkArgCnt(1, 1)) |
||
114 | { |
||
115 | tEvalResult EvalResult; |
||
116 | Word Addr = EvalStrIntExpressionWithResult(&ArgStr[1], CodeAdrIntType, &EvalResult); |
||
117 | if (EvalResult.OK) |
||
118 | { |
||
119 | ChkSpace(SegCode, EvalResult.AddrSpaceMask); |
||
120 | BAsmCode[0] = 0x10 | ((Addr >> 6) & 15); /* LDP... */ |
||
121 | BAsmCode[1] = (Code & 0xc0) | (Addr & 0x3f); |
||
122 | CodeLen = 2; |
||
123 | } |
||
124 | } |
||
125 | } |
||
126 | |||
127 | /*---------------------------------------------------------------------------*/ |
||
128 | /* Dynamic Instruction Table Handling */ |
||
129 | |||
130 | static void InitFields(void) |
||
131 | { |
||
132 | Boolean Is1100 = (MomCPU == CPU1100) || (MomCPU == CPU1300); |
||
133 | |||
134 | InstTable = CreateInstTable(107); |
||
135 | |||
136 | add_null_pseudo(InstTable); |
||
137 | |||
138 | AddInstTable(InstTable, "TAY", Is1100 ? 0x20 : 0x24, DecodeFixed); |
||
139 | AddInstTable(InstTable, "TYA", 0x23, DecodeFixed); |
||
140 | AddInstTable(InstTable, "CLA", Is1100 ? 0x7f : 0x2f, DecodeFixed); |
||
141 | |||
142 | AddInstTable(InstTable, "TAM", Is1100 ? 0x27 : 0x03, DecodeFixed); |
||
143 | if (Is1100) |
||
144 | { |
||
145 | AddInstTable(InstTable, "TAMIYC", 0x25, DecodeFixed); |
||
146 | AddInstTable(InstTable, "TAMDYN", 0x24, DecodeFixed); |
||
147 | } |
||
148 | else |
||
149 | { |
||
150 | AddInstTable(InstTable, "TAMIY", 0x20, DecodeFixed); |
||
151 | } |
||
152 | AddInstTable(InstTable, "TAMZA", Is1100 ? 0x26 : 0x04, DecodeFixed); |
||
153 | AddInstTable(InstTable, "TMY", 0x22, DecodeFixed); |
||
154 | AddInstTable(InstTable, "TMA", 0x21, DecodeFixed); |
||
155 | AddInstTable(InstTable, "XMA", Is1100 ? 0x03 : 0x2e, DecodeFixed); |
||
156 | |||
157 | AddInstTable(InstTable, "AMAAC", Is1100 ? 0x06 : 0x25, DecodeFixed); |
||
158 | AddInstTable(InstTable, "SAMAN", Is1100 ? 0x3c : 0x27, DecodeFixed); |
||
159 | AddInstTable(InstTable, "IMAC", Is1100 ? 0x3e : 0x28, DecodeFixed); |
||
160 | AddInstTable(InstTable, "DMAN", Is1100 ? 0x07 : 0x2a, DecodeFixed); |
||
161 | if (Is1100) |
||
162 | AddInstTable(InstTable, "IAC", 0x70, DecodeFixed); |
||
163 | else |
||
164 | AddInstTable(InstTable, "IA", 0x0e, DecodeFixed); |
||
165 | AddInstTable(InstTable, "IYC", Is1100 ? 0x05 : 0x2b, DecodeFixed); |
||
166 | AddInstTable(InstTable, "DAN", Is1100 ? 0x77 : 0x07, DecodeFixed); |
||
167 | AddInstTable(InstTable, "DYN", Is1100 ? 0x04 : 0x2c, DecodeFixed); |
||
168 | AddInstTable(InstTable, "CPAIZ", Is1100 ? 0x3d : 0x2d, DecodeFixed); |
||
169 | AddInstTable(InstTable, "A6AAC", Is1100 ? 0x7a : 0x06, DecodeFixed); |
||
170 | AddInstTable(InstTable, "A8AAC", Is1100 ? 0x7e : 0x01, DecodeFixed); |
||
171 | AddInstTable(InstTable, "A10AAC", Is1100 ? 0x79 : 0x05, DecodeFixed); |
||
172 | if (Is1100) |
||
173 | { |
||
174 | AddInstTable(InstTable, "A2AAC", 0x78, DecodeFixed); |
||
175 | AddInstTable(InstTable, "A3AAC", 0x74, DecodeFixed); |
||
176 | AddInstTable(InstTable, "A4AAC", 0x7c, DecodeFixed); |
||
177 | AddInstTable(InstTable, "A5AAC", 0x72, DecodeFixed); |
||
178 | AddInstTable(InstTable, "A7AAC", 0x76, DecodeFixed); |
||
179 | AddInstTable(InstTable, "A9AAC", 0x71, DecodeFixed); |
||
180 | AddInstTable(InstTable, "A11AAC", 0x75, DecodeFixed); |
||
181 | AddInstTable(InstTable, "A12AAC", 0x7d, DecodeFixed); |
||
182 | AddInstTable(InstTable, "A13AAC", 0x73, DecodeFixed); |
||
183 | AddInstTable(InstTable, "A14AAC", 0x7b, DecodeFixed); |
||
184 | } |
||
185 | |||
186 | AddInstTable(InstTable, "ALEM", Is1100 ? 0x01: 0x29, DecodeFixed); |
||
187 | if (!Is1100) |
||
188 | { |
||
189 | AddInstTable(InstTable, "ALEC", 0x70, DecodeConst4); |
||
190 | } |
||
191 | |||
192 | if (Is1100) |
||
193 | { |
||
194 | AddInstTable(InstTable, "MNEA", 0x00, DecodeFixed); |
||
195 | } |
||
196 | AddInstTable(InstTable, "MNEZ", Is1100 ? 0x3f : 0x26, DecodeFixed); |
||
197 | AddInstTable(InstTable, "YNEA", Is1100 ? 0x02 : 0x02, DecodeFixed); |
||
198 | AddInstTable(InstTable, "YNEC", 0x50, DecodeConst4); |
||
199 | |||
200 | AddInstTable(InstTable, "SBIT", 0x30, DecodeConst2); |
||
201 | AddInstTable(InstTable, "RBIT", 0x34, DecodeConst2); |
||
202 | AddInstTable(InstTable, "TBIT1", 0x38, DecodeConst2); |
||
203 | |||
204 | AddInstTable(InstTable, "TCY", 0x40, DecodeConst4); |
||
205 | AddInstTable(InstTable, "TCMIY", 0x60, DecodeConst4); |
||
206 | |||
207 | AddInstTable(InstTable, "KNEZ", Is1100 ? 0x0e : 0x09, DecodeFixed); |
||
208 | AddInstTable(InstTable, "TKA", 0x08, DecodeFixed); |
||
209 | |||
210 | AddInstTable(InstTable, "SETR", 0x0d, DecodeFixed); |
||
211 | AddInstTable(InstTable, "RSTR", 0x0c, DecodeFixed); |
||
212 | AddInstTable(InstTable, "TDO", 0x0a, DecodeFixed); |
||
213 | if (!Is1100) |
||
214 | { |
||
215 | AddInstTable(InstTable, "CLO", 0x0b, DecodeFixed); |
||
216 | } |
||
217 | |||
218 | if (Is1100) |
||
219 | { |
||
220 | AddInstTable(InstTable, "LDX", 0x28, DecodeConst3); |
||
221 | } |
||
222 | else |
||
223 | { |
||
224 | AddInstTable(InstTable, "LDX", 0x3c, DecodeConst2); |
||
225 | } |
||
226 | AddInstTable(InstTable, "COMX", Is1100 ? 0x09 : 0x00, DecodeFixed); |
||
227 | |||
228 | AddInstTable(InstTable, "BR", 0x80, DecodeJmp); |
||
229 | AddInstTable(InstTable, "CALL", 0xc0, DecodeJmp); |
||
230 | AddInstTable(InstTable, "BL", 0x80, DecodeJmpL); |
||
231 | AddInstTable(InstTable, "CALLL", 0xc0, DecodeJmpL); |
||
232 | AddInstTable(InstTable, "RETN", 0x0f, DecodeFixed); |
||
233 | AddInstTable(InstTable, "LDP", 0x10, DecodeConst4); |
||
234 | if (Is1100) |
||
235 | { |
||
236 | AddInstTable(InstTable, "COMC", 0x0b, DecodeFixed); |
||
237 | } |
||
238 | AddIntelPseudo(InstTable, eIntPseudoFlag_BigEndian); |
||
239 | } |
||
240 | |||
241 | static void DeinitFields(void) |
||
242 | { |
||
243 | DestroyInstTable(InstTable); |
||
244 | } |
||
245 | |||
246 | /*---------------------------------------------------------------------------*/ |
||
247 | /* Interface */ |
||
248 | |||
249 | static void MakeCode_TMS1(void) |
||
250 | { |
||
251 | if (!LookupInstTable(InstTable, OpPart.str.p_str)) |
||
252 | WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart); |
||
253 | } |
||
254 | |||
255 | static Boolean IsDef_TMS1(void) |
||
256 | { |
||
257 | return False; |
||
258 | } |
||
259 | |||
260 | static void SwitchFrom_TMS1(void) |
||
261 | { |
||
262 | DeinitFields(); |
||
263 | } |
||
264 | |||
265 | static void SwitchTo_TMS1(void) |
||
266 | { |
||
267 | const TFamilyDescr *pFoundDescr = FindFamilyByName("TMS1000"); |
||
268 | |||
269 | TurnWords = False; |
||
270 | SetIntConstMode(eIntConstModeIntel); |
||
271 | |||
272 | PCSymbol = "$"; |
||
273 | HeaderID = pFoundDescr->Id; |
||
274 | NOPCode = 0x100; |
||
275 | DivideChars = ","; |
||
276 | HasAttrs = False; |
||
277 | |||
278 | ValidSegs = (1 << SegCode) | (1 << SegData); |
||
279 | Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0; |
||
280 | Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0; |
||
281 | if ((MomCPU == CPU1000) || (MomCPU == CPU1200)) |
||
282 | { |
||
283 | CodeAdrIntType = UInt10; |
||
284 | DataAdrIntType = UInt6; |
||
285 | } |
||
286 | else if ((MomCPU == CPU1100) || (MomCPU == CPU1300)) |
||
287 | { |
||
288 | CodeAdrIntType = UInt11; |
||
289 | DataAdrIntType = UInt7; |
||
290 | } |
||
291 | SegLimits[SegCode] = IntTypeDefs[CodeAdrIntType].Max; |
||
292 | SegLimits[SegData] = IntTypeDefs[DataAdrIntType].Max; |
||
293 | |||
294 | MakeCode = MakeCode_TMS1; |
||
295 | IsDef = IsDef_TMS1; |
||
296 | SwitchFrom = SwitchFrom_TMS1; |
||
297 | |||
298 | InitFields(); |
||
299 | } |
||
300 | |||
301 | void codetms1_init(void) |
||
302 | { |
||
303 | CPU1000 = AddCPU("TMS1000", SwitchTo_TMS1); |
||
304 | CPU1100 = AddCPU("TMS1100", SwitchTo_TMS1); |
||
305 | CPU1200 = AddCPU("TMS1200", SwitchTo_TMS1); |
||
306 | CPU1300 = AddCPU("TMS1300", SwitchTo_TMS1); |
||
307 | } |