This source file includes following definitions.
- hash_cmdtype
- create_cmdtable
- free_cmdtable
- getcmdcode
- getcmdwordlen
- hash_code
- getcmdptr
- getcmdtype
- getcmdname
- grstr
- memsize_str2word
- comet2_init
- cpu_reset
- memory_reset
- comet2_reset
- comet2_resetall
- comet2_shutdown
1 #include <errno.h>
2 #include "struct.h"
3 #include "exec.h"
4
5
6
7
8 SYSTEM *sys = NULL;
9
10
11
12
13 EXECPTR *execptr = NULL;
14
15
16
17
18 static const COMET2CMD comet2cmd[] = {
19 { "NOP", NONE, 0x0, nop, 1 },
20 { "LD", R_ADR_X, 0x1000, ld_r_adr_x, 2 },
21 { "ST", R_ADR_X, 0x1100, st, 2 },
22 { "LAD", R_ADR_X, 0x1200, lad, 2 },
23 { "LD", R1_R2, 0x1400, ld_r1_r2, 1 },
24 { "ADDA", R_ADR_X, 0x2000, adda_r_adr_x, 2 },
25 { "SUBA", R_ADR_X, 0x2100, suba_r_adr_x, 2 },
26 { "ADDL", R_ADR_X, 0x2200, addl_r_adr_x, 2 },
27 { "SUBL", R_ADR_X, 0x2300, subl_r_adr_x, 2 },
28 { "ADDA", R1_R2, 0x2400, adda_r1_r2, 1 },
29 { "SUBA", R1_R2, 0x2500, suba_r1_r2, 1 },
30 { "ADDL", R1_R2, 0x2600, addl_r1_r2, 1 },
31 { "SUBL", R1_R2, 0x2700, subl_r1_r2, 1 },
32 { "AND", R_ADR_X, 0x3000, and_r_adr_x, 2 },
33 { "OR", R_ADR_X, 0x3100, or_r_adr_x, 2 },
34 { "XOR", R_ADR_X, 0x3200, xor_r_adr_x, 2 },
35 { "AND", R1_R2, 0x3400, and_r1_r2, 1 },
36 { "OR", R1_R2, 0x3500, or_r1_r2, 1 },
37 { "XOR", R1_R2, 0x3600, xor_r1_r2, 1 },
38 { "CPA", R_ADR_X, 0x4000, cpa_r_adr_x, 2 },
39 { "CPL", R_ADR_X, 0x4100, cpl_r_adr_x, 2 },
40 { "CPA", R1_R2, 0x4400, cpa_r1_r2, 1 },
41 { "CPL", R1_R2, 0x4500, cpl_r1_r2, 1 },
42 { "SLA", R_ADR_X, 0x5000, sla, 2 },
43 { "SRA", R_ADR_X, 0x5100, sra, 2 },
44 { "SLL", R_ADR_X, 0x5200, sll, 2 },
45 { "SRL", R_ADR_X, 0x5300, srl, 2 },
46 { "JMI", ADR_X, 0x6100, jmi, 2 },
47 { "JNZ", ADR_X, 0x6200, jnz, 2 },
48 { "JZE", ADR_X, 0x6300, jze, 2 },
49 { "JUMP", ADR_X, 0x6400, jump, 2 },
50 { "JPL", ADR_X, 0x6500, jpl, 2 },
51 { "JOV", ADR_X, 0x6600, jov, 2 },
52 { "PUSH", ADR_X, 0x7000, push, 2 },
53 { "POP", R_, 0x7100, pop, 1 },
54 { "CALL", ADR_X, 0x8000, call, 2 },
55 { "RET", NONE, 0x8100, ret, 1 },
56 { "SVC", ADR_X, 0xF000, svc, 2 },
57 };
58
59
60
61
62 static int comet2cmdsize = ARRAYSIZE(comet2cmd);
63
64
65
66
67 enum {
68 CMDTABSIZE = 41,
69 };
70
71
72
73
74 static CMDTAB *cmdtab[HASH_MAX][CMDTABSIZE] = {{NULL}};
75
76
77
78
79 unsigned hash_cmdtype(const char *cmd, CMDTYPE type);
80
81
82
83
84 unsigned hash_code(WORD code);
85
86
87
88
89 void cpu_reset();
90
91
92
93
94 void memory_reset();
95
96
97
98
99 unsigned hash_cmdtype(const char *cmd, CMDTYPE type)
100 {
101 HKEY *keys[2] = {NULL};
102 unsigned hashval = 0;
103
104
105 keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[0]");
106 keys[0]->type = CHARS;
107 keys[0]->val.s = strdup_chk(cmd, "keys[0].val.s");
108
109 keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[1]");
110 keys[1]->type = INT;
111 keys[1]->val.i = (int)(type & 070);
112
113 hashval = hash(2, keys, CMDTABSIZE);
114 FREE(keys[0]->val.s);
115 FREE(keys[0]);
116 FREE(keys[1]);
117
118 return hashval;
119 }
120
121
122
123
124 bool create_cmdtable(CMDTAB_HASH hash)
125 {
126 CMDTAB *p = NULL;
127 unsigned hashval;
128
129 for(int i = 0; i < comet2cmdsize; i++) {
130 p = malloc_chk(sizeof(CMDTAB), "create_cmdtable.p");
131 p->cmd = &comet2cmd[i];
132 if(hash == HASH_CMDTYPE) {
133 hashval = hash_cmdtype(comet2cmd[i].name, comet2cmd[i].type);
134 } else if(hash == HASH_CODE) {
135 hashval = hash_code(comet2cmd[i].code);
136 }
137 p->next = cmdtab[hash][hashval];
138 cmdtab[hash][hashval] = p;
139 }
140 return true;
141 }
142
143
144
145
146 void free_cmdtable(CMDTAB_HASH hash)
147 {
148 CMDTAB *p = NULL;
149 CMDTAB *q = NULL;
150
151 for(int i = 0; i < CMDTABSIZE; i++) {
152 for(p = cmdtab[hash][i]; p != NULL; p = q) {
153 q = p->next;
154 FREE(p);
155 }
156 cmdtab[hash][i] = NULL;
157 }
158 }
159
160
161
162
163
164 WORD getcmdcode(const char *cmd, CMDTYPE type)
165 {
166 CMDTAB *p = NULL;
167 WORD w = 0xFFFF;
168
169 assert(cmd != NULL);
170 for(p = cmdtab[HASH_CMDTYPE][hash_cmdtype(cmd, type)]; p != NULL; p = p->next) {
171 if(strcmp(cmd, p->cmd->name) == 0 && type == p->cmd->type) {
172 w = p->cmd->code;
173 break;
174 }
175 }
176 return w;
177 }
178
179
180
181
182
183 WORD getcmdwordlen(const char *cmd, CMDTYPE type)
184 {
185 CMDTAB *p = NULL;
186 int l = 0;
187
188 assert(cmd != NULL);
189 for(p = cmdtab[HASH_CMDTYPE][hash_cmdtype(cmd, type)]; p != NULL; p = p->next) {
190 if(strcmp(cmd, p->cmd->name) == 0 && type == p->cmd->type) {
191 l = p->cmd->wordlen;
192 break;
193 }
194 }
195 return l;
196 }
197
198
199
200
201 unsigned hash_code(WORD code)
202 {
203 HKEY *keys[1] = {NULL};
204 unsigned h = 0;
205
206
207 keys[0] = malloc_chk(sizeof(HKEY), "hash_code.key");
208 keys[0]->type = INT;
209 keys[0]->val.i = (int)(code >> 8);
210 h = hash(1, keys, CMDTABSIZE);
211 FREE(keys[0]);
212 return h;
213 }
214
215
216
217
218 void (*getcmdptr(WORD code))
219 {
220 CMDTAB *t = NULL;
221 void *ptr = NULL;
222
223 for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) {
224 if(code == t->cmd->code) {
225 ptr = t->cmd->ptr;
226 break;
227 }
228 }
229 return ptr;
230 }
231
232
233
234
235 CMDTYPE getcmdtype(WORD code)
236 {
237 CMDTAB *t = NULL;
238 CMDTYPE type = NONE;
239
240 for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) {
241 if(code == t->cmd->code) {
242 type = t->cmd->type;
243 break;
244 }
245 }
246 return type;
247 }
248
249
250
251
252 char *getcmdname(WORD code)
253 {
254 CMDTAB *t = NULL;
255 char *cmd = NULL;
256
257 for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) {
258 if(code == t->cmd->code) {
259 cmd = t->cmd->name;
260 break;
261 }
262 }
263 return cmd;
264 }
265
266
267
268
269
270 char *grstr(WORD word)
271 {
272 assert(word <= 7);
273 char *str = NULL;
274
275 str = malloc_chk(3 + 1, "grstr.str");
276 sprintf(str, "GR%d", word);
277 return str;
278 }
279
280 WORD memsize_str2word(const char *str) {
281 return (WORD)str2l_range(str, 1, MAX_MEMSIZE, "Memory Size");
282 }
283
284
285
286
287 void comet2_init(WORD memsize, CLOCK clocks)
288 {
289 sys = malloc_chk(sizeof(SYSTEM), "sys");
290
291 assert(0 < memsize && memsize <= MAX_MEMSIZE-1);
292 sys->memsize = memsize;
293
294 assert(0 < clocks && clocks <= MAX_CLOCKS);
295 sys->clocks = clocks;
296
297 sys->cpu = malloc_chk(sizeof(CPU), "comet2_init.cpu");
298
299 cpu_reset();
300
301 sys->memory = calloc_chk(sys->memsize, sizeof(WORD), "comet2_init.memory");
302
303 memory_reset();
304
305 execptr = malloc_chk(sizeof(EXECPTR), "execptr");
306 execptr->stop = false;
307 }
308
309
310 void cpu_reset() {
311
312 for(int i = 0; i < GRSIZE; i++) {
313 sys->cpu->gr[i] = 0x0;
314 }
315 sys->cpu->sp = sys->memsize;
316 sys->cpu->pr = 0x0;
317 sys->cpu->fr = 0x0;
318 }
319
320
321
322
323 void memory_reset() {
324 memset(sys->memory, 0, sys->memsize * sizeof(WORD));
325 }
326
327
328
329
330 void comet2_reset()
331 {
332
333 execptr->stop = false;
334
335 cpu_reset();
336
337 dsp_trace_dump();
338 }
339
340
341
342
343 void comet2_resetall()
344 {
345
346 execptr->stop = false;
347
348 cpu_reset();
349
350 memory_reset();
351
352 dsp_trace_dump();
353 }
354
355
356
357
358 void comet2_shutdown()
359 {
360 FREE(execptr);
361 FREE(sys->memory);
362 FREE(sys->cpu);
363 FREE(sys);
364 }