YACASL2
struct.c
Go to the documentation of this file.
1 #include "struct.h"
2 #include "exec.h"
3 
7 SYSTEM *sys = NULL;
8 
12 EXECPTR *execptr = NULL;
13 
17 static const 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 },
56 };
57 
62 
66 enum {
67  CMDTABSIZE = 41,
68 };
69 
73 static CMDTAB *cmdtab[HASH_MAX][CMDTABSIZE] = {{NULL}};
74 
78 unsigned hash_cmdtype(const char *cmd, CMDTYPE type);
79 
83 unsigned hash_code(WORD code);
84 
88 unsigned hash_cmdtype(const char *cmd, CMDTYPE type)
89 {
90  HKEY *keys[2] = {NULL};
91  unsigned hashval = 0;
92 
93  /* 命令名を設定 */
94  keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[0]");
95  keys[0]->type = CHARS;
96  keys[0]->val.s = strdup_chk(cmd, "keys[0].val.s");
97  /* 命令タイプを設定 */
98  keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[1]");
99  keys[1]->type = INT;
100  keys[1]->val.i = (int)(type & 070);
101  /* ハッシュ値の計算 */
102  hashval = hash(2, keys, CMDTABSIZE);
103  FREE(keys[0]->val.s);
104  FREE(keys[0]);
105  FREE(keys[1]);
106  /* ハッシュ値を返す */
107  return hashval;
108 }
109 
114 {
115  CMDTAB *p = NULL;
116  unsigned hashval;
117 
118  for(int i = 0; i < comet2cmdsize; i++) {
119  p = malloc_chk(sizeof(CMDTAB), "create_cmdtable.p");
120  p->cmd = &comet2cmd[i];
121  if(hash == HASH_CMDTYPE) {
122  hashval = hash_cmdtype(comet2cmd[i].name, comet2cmd[i].type);
123  } else if(hash == HASH_CODE) {
124  hashval = hash_code(comet2cmd[i].code);
125  }
126  p->next = cmdtab[hash][hashval];
127  cmdtab[hash][hashval] = p;
128  }
129  return true;
130 }
131 
136 {
137  CMDTAB *p = NULL;
138  CMDTAB *q = NULL;
139 
140  for(int i = 0; i < CMDTABSIZE; i++) {
141  for(p = cmdtab[hash][i]; p != NULL; p = q) {
142  q = p->next;
143  FREE(p);
144  }
145  cmdtab[hash][i] = NULL;
146  }
147 }
148 
153 WORD getcmdcode(const char *cmd, CMDTYPE type)
154 {
155  CMDTAB *p = NULL;
156  WORD w = 0xFFFF;
157 
158  assert(cmd != NULL);
159  for(p = cmdtab[HASH_CMDTYPE][hash_cmdtype(cmd, type)]; p != NULL; p = p->next) {
160  if(strcmp(cmd, p->cmd->name) == 0 && type == p->cmd->type) {
161  w = p->cmd->code;
162  break;
163  }
164  }
165  return w;
166 }
167 
171 unsigned hash_code(WORD code)
172 {
173  HKEY *keys[1] = {NULL};
174  unsigned h = 0;
175 
176  /* 命令コードを設定 */
177  keys[0] = malloc_chk(sizeof(HKEY), "hash_code.key");
178  keys[0]->type = INT;
179  keys[0]->val.i = (int)(code >> 8);
180  h = hash(1, keys, CMDTABSIZE);
181  FREE(keys[0]);
182  return h;
183 }
184 
188 const void (*getcmdptr(WORD code))
189 {
190  CMDTAB *t = NULL;
191  const void *ptr = NULL;
192 
193  for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) {
194  if(code == t->cmd->code) {
195  ptr = t->cmd->ptr;
196  break;
197  }
198  }
199  return ptr;
200 }
201 
206 {
207  CMDTAB *t = NULL;
208  CMDTYPE type = NONE;
209 
210  for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) {
211  if(code == t->cmd->code) {
212  type = t->cmd->type;
213  break;
214  }
215  }
216  return type;
217 }
218 
222 char *getcmdname(WORD code)
223 {
224  CMDTAB *t = NULL;
225  char *cmd = NULL;
226 
227  for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) {
228  if(code == t->cmd->code) {
229  cmd = t->cmd->name;
230  break;
231  }
232  }
233  return cmd;
234 }
235 
240 char *grstr(WORD word)
241 {
242  assert(word <= 7);
243  char *str = NULL;
244 
245  str = malloc_chk(3 + 1, "grstr.str");
246  sprintf(str, "GR%d", word);
247  return str;
248 }
249 
253 void reset(int memsize, int clocks)
254 {
255  sys = malloc_chk(sizeof(SYSTEM), "sys");
256  /* メモリサイズを設定 */
257  sys->memsize = memsize;
258  /* クロック周波数を設定 */
259  sys->clocks = clocks;
260  /* メモリを初期化 */
261  sys->memory = calloc_chk(sys->memsize, sizeof(WORD), "memory");
262  /* CPUを初期化 */
263  sys->cpu = malloc_chk(sizeof(CPU), "cpu");
264  for(int i = 0; i < GRSIZE; i++) { /* 汎用レジスタ */
265  sys->cpu->gr[i] = 0x0;
266  }
267  sys->cpu->sp = sys->memsize; /* スタックポインタ */
268  sys->cpu->pr = 0x0; /* プログラムレジスタ */
269  sys->cpu->fr = 0x0; /* フラグレジスタ */
270  /* CASL2プログラムの開始と終了のアドレスを初期化 */
271  execptr = malloc_chk(sizeof(EXECPTR), "execptr");
272  execptr->stop = false;
273 }
274 
278 void shutdown()
279 {
280  FREE(execptr);
281  FREE(sys->memory);
282  FREE(sys->cpu);
283  FREE(sys);
284 }
void and_r_adr_x()
AND命令 - オペランドr,adr,x。語長2.
void st()
ST命令。語長2.
void jmi()
JMI命令。語長2.
void svc()
SVC命令。語長2.
void suba_r1_r2()
SUBA命令 - オペランドr1,r2。語長1.
void cpl_r_adr_x()
CPL命令 - オペランドr,adr,x。語長2.
void sra()
SRA命令 - オペランドr,adr,x。語長2.
void pop()
POP命令。語長1.
void adda_r1_r2()
ADDA命令 - オペランドr1,r2。語長1.
void xor_r1_r2()
XOR命令 - オペランドr1,r2。語長1.
void subl_r_adr_x()
SUBL命令 - オペランドr,adr,x。語長2.
void sla()
SLA命令 - オペランドr,adr,x。語長2.
void srl()
SRL命令 - オペランドr,adr,x。語長2.
void ld_r_adr_x()
LD命令 - オペランドr,adr,x。語長2.
void jnz()
JNZ命令。語長2.
void adda_r_adr_x()
ADDA命令 - オペランドr,adr,x。語長2.
void addl_r1_r2()
ADDL命令 - オペランドr1,r2。語長1.
void cpl_r1_r2()
CPL命令 - オペランドr1,r2。語長1.
void jump()
JUMP命令。語長2.
void subl_r1_r2()
SUBL命令 - オペランドr1,r2。語長1.
void cpa_r1_r2()
CPA命令 - オペランドr1,r2。語長1.
void push()
PUSH命令。語長2.
void nop()
NOP命令。語長1(OPのみ)
void cpa_r_adr_x()
CPA命令 - オペランドr,adr,x。語長2.
void and_r1_r2()
AND命令 - オペランドr1,r2。語長1.
void ret()
RET命令。語長1(OPのみ)
void or_r_adr_x()
OR命令 - オペランドr,adr,x。語長2.
void suba_r_adr_x()
SUBA命令 - オペランドr,adr,x。語長2.
void addl_r_adr_x()
ADDL命令 - オペランドr,adr,x。語長2.
void sll()
SLL命令 - オペランドr,adr,x。語長2.
void call()
CALL命令。語長2.
void jpl()
JPL命令。語長2.
void lad()
LAD命令。語長2.
void xor_r_adr_x()
XOR命令 - オペランドr,adr,x。語長2.
void jze()
JZE命令。語長2.
void or_r1_r2()
OR命令 - オペランドr1,r2。語長1.
void jov()
JOV命令。語長2.
void ld_r1_r2()
LD命令 - オペランドr1,r2。語長1.
#define FREE(ptr)
メモリを解放するマクロ
Definition: cmem.h:21
char * strdup_chk(const char *s, const char *tag)
malloc_chkを実行してメモリを確保し、コピーした文字列を返す
Definition: cmem.c:25
void * calloc_chk(size_t nmemb, size_t size, const char *tag)
領域の数とサイズを指定してメモリーを確保するcallocを実行する
Definition: cmem.c:14
#define ARRAYSIZE(array)
配列のサイズを返すマクロ
Definition: cmem.h:14
void * malloc_chk(size_t size, const char *tag)
mallocを実行し、0で初期化する
Definition: cmem.c:3
@ CHARS
Definition: hash.h:8
@ INT
Definition: hash.h:9
unsigned hash(int keyc, HKEY *keyv[], int tabsize)
ハッシュ値を取得する
Definition: hash.c:3
void reset(int memsize, int clocks)
Definition: struct.c:253
char * getcmdname(WORD code)
Definition: struct.c:222
CMDTYPE getcmdtype(WORD code)
Definition: struct.c:205
EXECPTR * execptr
Definition: struct.c:12
bool create_cmdtable(CMDTAB_HASH hash)
命令ハッシュ表を作成する
Definition: struct.c:113
static CMDTAB * cmdtab[HASH_MAX][CMDTABSIZE]
Definition: struct.c:73
unsigned hash_code(WORD code)
Definition: struct.c:171
void shutdown()
Definition: struct.c:278
void free_cmdtable(CMDTAB_HASH hash)
Definition: struct.c:135
SYSTEM * sys
COMET IIの仮想実行マシンシステム
Definition: struct.c:7
@ CMDTABSIZE
Definition: struct.c:67
const void * getcmdptr(WORD code)
Definition: struct.c:188
static const COMET2CMD comet2cmd[]
Definition: struct.c:17
char * grstr(WORD word)
汎用レジスタの番号からレジスタを表す文字列を返す
Definition: struct.c:240
static int comet2cmdsize
Definition: struct.c:61
WORD getcmdcode(const char *cmd, CMDTYPE type)
Definition: struct.c:153
unsigned hash_cmdtype(const char *cmd, CMDTYPE type)
Definition: struct.c:88
@ GRSIZE
Definition: struct.h:18
CMDTAB_HASH
Definition: struct.h:60
@ HASH_CMDTYPE
Definition: struct.h:61
@ HASH_MAX
Definition: struct.h:63
@ HASH_CODE
Definition: struct.h:62
CMDTYPE
Definition: struct.h:70
@ R_
Definition: struct.h:94
@ R_ADR_X
Definition: struct.h:77
@ ADR_X
Definition: struct.h:89
@ NONE
Definition: struct.h:98
@ R1_R2
Definition: struct.h:83
const COMET2CMD * cmd
Definition: struct.h:124
struct _CMDTAB * next
Definition: struct.h:123
const void * ptr
Definition: struct.h:116
CMDTYPE type
Definition: struct.h:114
char * name
Definition: struct.h:113
WORD code
Definition: struct.h:115
COMET IIのCPUを表すデータ型
Definition: struct.h:35
WORD gr[GRSIZE]
Definition: struct.h:36
WORD sp
Definition: struct.h:37
WORD fr
Definition: struct.h:39
WORD pr
Definition: struct.h:38
bool stop
Definition: struct.h:133
ハッシュ共用体のデータ型
Definition: hash.h:15
char * s
Definition: hash.h:18
UTYPE type
Definition: hash.h:16
int i
Definition: hash.h:19
union HKEY::@3 val
COMET IIの仮想実行マシンシステムを表すデータ型
Definition: struct.h:45
int memsize
Definition: struct.h:48
clock_t clocks
Definition: struct.h:49
WORD * memory
Definition: struct.h:47
CPU * cpu
Definition: struct.h:46
unsigned short WORD
16ビットの数値を表すデータ型
Definition: word.h:9