17 static COMET2CMD comet2cmd[] = {
18 { "NOP", NONE, 0x0, nop },
19 { "LD", R_ADR_X, 0x1000, ld_r_adr_x },
20 { "ST", R_ADR_X, 0x1100, st },
21 { "LAD", R_ADR_X, 0x1200, lad },
22 { "LD", R1_R2, 0x1400, ld_r1_r2 },
23 { "ADDA", R_ADR_X, 0x2000, adda_r_adr_x },
24 { "SUBA", R_ADR_X, 0x2100, suba_r_adr_x },
25 { "ADDL", R_ADR_X, 0x2200, addl_r_adr_x },
26 { "SUBL", R_ADR_X, 0x2300, subl_r_adr_x },
27 { "ADDA", R1_R2, 0x2400, adda_r1_r2 },
28 { "SUBA", R1_R2, 0x2500, suba_r1_r2 },
29 { "ADDL", R1_R2, 0x2600, addl_r1_r2 },
30 { "SUBL", R1_R2, 0x2700, subl_r1_r2 },
31 { "AND", R_ADR_X, 0x3000, and_r_adr_x },
32 { "OR", R_ADR_X, 0x3100, or_r_adr_x },
33 { "XOR", R_ADR_X, 0x3200, xor_r_adr_x },
34 { "AND", R1_R2, 0x3400, and_r1_r2 },
35 { "OR", R1_R2, 0x3500, or_r1_r2 },
36 { "XOR", R1_R2, 0x3600, xor_r1_r2 },
37 { "CPA", R_ADR_X, 0x4000, cpa_r_adr_x },
38 { "CPL", R_ADR_X, 0x4100, cpl_r_adr_x },
39 { "CPA", R1_R2, 0x4400, cpa_r1_r2 },
40 { "CPL", R1_R2, 0x4500, cpl_r1_r2 },
41 { "SLA", R_ADR_X, 0x5000, sla },
42 { "SRA", R_ADR_X, 0x5100, sra },
43 { "SLL", R_ADR_X, 0x5200, sll },
44 { "SRL", R_ADR_X, 0x5300, srl },
45 { "JMI", ADR_X, 0x6100, jmi },
46 { "JNZ", ADR_X, 0x6200, jnz },
47 { "JZE", ADR_X, 0x6300, jze },
48 { "JUMP", ADR_X, 0x6400, jump },
49 { "JPL", ADR_X, 0x6500, jpl },
50 { "JOV", ADR_X, 0x6600, jov },
51 { "PUSH", ADR_X, 0x7000, push },
52 { "POP", R_, 0x7100, pop },
53 { "CALL", ADR_X, 0x8000, call },
54 { "SVC", ADR_X, 0xF000, svc },
55 { "RET", NONE, 0x8100, ret },
61 static int comet2cmdsize = ARRAYSIZE(comet2cmd);
73 static CMDTAB *cmdtype_code[CMDTABSIZE], *code_cmdtype[CMDTABSIZE];
76 * 命令の名前とタイプからハッシュ値を生成する
78 unsigned hash_cmdtype(const char *cmd, CMDTYPE type)
84 keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[0]");
85 keys[0]->type = CHARS;
86 keys[0]->val.s = strdup_chk(cmd, "keys[0].val.s");
88 keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[1]");
90 keys[1]->val.i = (int)(type & 070);
92 hashval = hash(2, keys, CMDTABSIZE);
101 * 名前とタイプがキーの命令ハッシュ表を作成する
103 bool create_cmdtype_code()
109 for(i = 0; i < comet2cmdsize; i++) {
110 hashval = hash_cmdtype(comet2cmd[i].name, comet2cmd[i].type); /* ハッシュ値の生成 */
111 p = malloc_chk(sizeof(CMDTAB), "cmdtype_code");
112 p->cmd = &comet2cmd[i];
113 p->next = cmdtype_code[hashval]; /* ハッシュ表に値を追加 */
114 cmdtype_code[hashval] = p;
120 * 命令の名前とタイプから、命令コードを返す\n
123 WORD getcmdcode(const char *cmd, CMDTYPE type)
129 for(p = cmdtype_code[hash_cmdtype(cmd, type)]; p != NULL; p = p->next) {
130 if(strcmp(cmd, p->cmd->name) == 0 && type == p->cmd->type) {
139 * 名前とタイプがキーの命令ハッシュ表を解放する
141 void free_cmdtype_code()
146 for(i = 0; i < CMDTABSIZE; i++) {
147 for(p = cmdtype_code[i]; p != NULL; p = q) {
157 unsigned hash_code(WORD code)
163 keys[0] = malloc_chk(sizeof(HKEY), "hash_code.key");
165 keys[0]->val.i = (int)(code >> 8);
166 h = hash(1, keys, CMDTABSIZE);
172 * コードがキーの命令ハッシュ表を作成する
174 bool create_code_cmdtype()
180 for(i = 0; i < comet2cmdsize; i++) {
181 hashval = hash_code((&comet2cmd[i])->code); /* ハッシュ値の生成 */
182 p = malloc_chk(sizeof(CMDTAB), "code_cmdtype");
183 p->cmd = &comet2cmd[i];
184 p->next = code_cmdtype[hashval]; /* ハッシュ表に値を追加 */
185 code_cmdtype[hashval] = p;
191 * 命令コードから命令の関数ポインタを返す
193 const void (*getcmdptr(WORD code))
196 const void *ptr = NULL;
198 for(t = code_cmdtype[hash_code(code)]; t != NULL; t = t->next) {
199 if(code == t->cmd->code) {
210 CMDTYPE getcmdtype(WORD code)
215 for(t = code_cmdtype[hash_code(code)]; t != NULL; t = t->next) {
216 if(code == t->cmd->code) {
227 char *getcmdname(WORD code)
232 for(t = code_cmdtype[hash_code(code)]; t != NULL; t = t->next) {
233 if(code == t->cmd->code) {
242 * 汎用レジスタの番号からレジスタを表す文字列を返す
245 char *grstr(WORD word)
248 char *str = malloc_chk(3 + 1, "grstr.str");
249 sprintf(str, "GR%d", word);
254 * コードがキーの命令ハッシュ表を解放する
256 void free_code_cmdtype()
260 for(i = 0; i < CMDTABSIZE; i++) {
261 for(p = code_cmdtype[i]; p != NULL; p = q) {
271 void reset(int memsize, int clocks)
275 sys = malloc_chk(sizeof(SYSTEM), "sys");
277 sys->memsize = memsize;
279 sys->clocks = clocks;
281 sys->memory = calloc_chk(sys->memsize, sizeof(WORD), "memory");
283 sys->cpu = malloc_chk(sizeof(CPU), "cpu");
284 for(i = 0; i < GRSIZE; i++) { /* 汎用レジスタ */
285 sys->cpu->gr[i] = 0x0;
287 sys->cpu->sp = sys->memsize; /* スタックポインタ */
288 sys->cpu->pr = 0x0; /* プログラムレジスタ */
289 sys->cpu->fr = 0x0; /* フラグレジスタ */
290 /* CASL2プログラムの開始と終了のアドレスを初期化 */
291 execptr = malloc_chk(sizeof(EXECPTR), "execptr");
292 execptr->stop = false;
296 * COMET II仮想マシンのシャットダウン