root/src/struct.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hash_cmdtype
  2. create_cmdtable
  3. free_cmdtable
  4. getcmdcode
  5. hash_code
  6. getcmdptr
  7. getcmdtype
  8. getcmdname
  9. grstr
  10. reset
  11. shutdown

   1 #include "struct.h"
   2 #include "exec.h"
   3 
   4 /**
   5  * COMET IIの仮想実行マシンシステム
   6  */
   7 SYSTEM *sys = NULL;
   8 
   9 /**
  10  * プログラム実行時の開始と終了のアドレス
  11  */
  12 EXECPTR *execptr = NULL;
  13 
  14 /**
  15  * システムCOMET IIの命令表
  16  */
  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 
  58 /**
  59  * 命令表のサイズ
  60  */
  61 static int comet2cmdsize = ARRAYSIZE(comet2cmd);
  62 
  63 /**
  64  * ハッシュ表のサイズ
  65  */
  66 enum {
  67     CMDTABSIZE = 41,
  68 };
  69 
  70 /**
  71  * ハッシュ表
  72  */
  73 static CMDTAB *cmdtab[HASH_MAX][CMDTABSIZE] = {{NULL}};
  74 
  75 /**
  76  * 命令の名前とタイプからハッシュ値を生成する
  77  */
  78 unsigned hash_cmdtype(const char *cmd, CMDTYPE type);
  79 
  80 /**
  81  * 命令コードからハッシュ値を生成する
  82  */
  83 unsigned hash_code(WORD code);
  84 
  85 /**
  86  * 命令の名前とタイプからハッシュ値を生成する
  87  */
  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 
 110 /**
 111  * 命令ハッシュ表を作成する
 112  */
 113 bool create_cmdtable(CMDTAB_HASH hash)
 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 
 132 /**
 133  * 命令ハッシュ表を解放する
 134  */
 135 void free_cmdtable(CMDTAB_HASH hash)
 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 
 149 /**
 150  * 命令の名前とタイプから、命令コードを返す\n
 151  * 無効な場合は0xFFFFを返す
 152  */
 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 
 168 /**
 169  * 命令コードからハッシュ値を生成する
 170  */
 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 
 185 /**
 186  * 命令コードから命令の関数ポインタを返す
 187  */
 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 
 202 /**
 203  * 命令コードから命令のタイプを返す
 204  */
 205 CMDTYPE getcmdtype(WORD code)
 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 
 219 /**
 220  * 命令コードから命令の名前を返す
 221  */
 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 
 236 /**
 237  * 汎用レジスタの番号からレジスタを表す文字列を返す
 238  */
 239 
 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 
 250 /**
 251  * COMET II仮想マシンのリセット
 252  */
 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 
 275 /**
 276  * COMET II仮想マシンのシャットダウン
 277  */
 278 void shutdown()
 279 {
 280     FREE(execptr);
 281     FREE(sys->memory);
 282     FREE(sys->cpu);
 283     FREE(sys);
 284 }

/* [<][>][^][v][top][bottom][index][help] */