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. getcmdwordlen
  6. hash_code
  7. getcmdptr
  8. getcmdtype
  9. getcmdname
  10. grstr
  11. memsize_str2word
  12. comet2_init
  13. cpu_reset
  14. memory_reset
  15. comet2_reset
  16. comet2_resetall
  17. comet2_shutdown

   1 #include <errno.h>
   2 #include "struct.h"
   3 #include "exec.h"
   4 
   5 /**
   6  * COMET IIの仮想実行マシンシステム
   7  */
   8 SYSTEM *sys = NULL;
   9 
  10 /**
  11  * プログラム実行時の開始と終了のアドレス
  12  */
  13 EXECPTR *execptr = NULL;
  14 
  15 /**
  16  * システムCOMET IIの命令表
  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  * CPUのリセット
  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  * 命令の名前とタイプから、命令コードを返す\n
 162  * 無効な場合は0xFFFFを返す
 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  * 命令の名前とタイプから、命令語長を返す\n
 181  * 無効な場合は0を返す
 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  * COMET II仮想マシンの初期化
 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     /* CPU領域の確保 */
 297     sys->cpu = malloc_chk(sizeof(CPU), "comet2_init.cpu");
 298     /* CPUをリセット */
 299     cpu_reset();
 300     /* メモリ領域の確保 */
 301     sys->memory = calloc_chk(sys->memsize, sizeof(WORD), "comet2_init.memory");
 302     /* メモリをリセット */
 303     memory_reset();
 304     /* CASL2プログラムの開始と終了のアドレスを初期化 */
 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  * COMET II仮想マシンのCPUリセット
 329  */
 330 void comet2_reset()
 331 {
 332     /* CASL2プログラム終了のアドレスを初期化 */
 333     execptr->stop = false;
 334    /* CPUをリセット */
 335     cpu_reset();
 336     /* CPUとメモリを設定に応じて表示 */
 337     dsp_trace_dump();
 338 }
 339 
 340 /**
 341  * COMET II仮想マシンのCPUとメモリをリセット
 342  */
 343 void comet2_resetall()
 344 {
 345     /* CASL2プログラム終了のアドレスを初期化 */
 346     execptr->stop = false;
 347     /* CPUをリセット */
 348     cpu_reset();
 349     /* メモリをリセット */
 350     memory_reset();
 351     /* CPUとメモリを設定に応じて表示 */
 352     dsp_trace_dump();
 353 }
 354 
 355 /**
 356  * COMET II仮想マシンのシャットダウン
 357  */
 358 void comet2_shutdown()
 359 {
 360     FREE(execptr);
 361     FREE(sys->memory);
 362     FREE(sys->cpu);
 363     FREE(sys);
 364 }

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