📄 compile.c
字号:
goto fail; } } else { p->type = X (OP_DISP, OP_SIZE (q->how)); p->literal = cst[opnum]; /* DISP2 is special. */ if ((x & SIZE) == L_2) switch (OP_SIZE (q->how)) { case SB: break; case SW: p->literal *= 2; break; case SL: p->literal *= 4; break; } } p->reg = rdisp[opnum]; } else if (x & CTRL) { switch (reg[opnum]) { case C_CCR: p->type = X (OP_CCR, SB); break; case C_EXR: p->type = X (OP_EXR, SB); break; case C_MACH: p->type = X (OP_MACH, SL); break; case C_MACL: p->type = X (OP_MACL, SL); break; case C_VBR: p->type = X (OP_VBR, SL); break; case C_SBR: p->type = X (OP_SBR, SL); break; } } else if ((x & MODE) == CCR) { p->type = OP_CCR; } else if ((x & MODE) == EXR) { p->type = OP_EXR; } else printf ("Hmmmm 0x%x...\n", x); args++; } } /* Unary operators: treat src and dst as equivalent. */ if (dst->dst.type == -1) dst->dst = dst->src; if (dst->src.type == -1) dst->src = dst->dst; dst->opcode = q->how; dst->cycles = q->time; /* And jsr's to these locations are turned into magic traps. */ if (OP_KIND (dst->opcode) == O_JSR) { switch (dst->src.literal) { case 0xc5: dst->opcode = O (O_SYS_OPEN, SB); break; case 0xc6: dst->opcode = O (O_SYS_READ, SB); break; case 0xc7: dst->opcode = O (O_SYS_WRITE, SB); break; case 0xc8: dst->opcode = O (O_SYS_LSEEK, SB); break; case 0xc9: dst->opcode = O (O_SYS_CLOSE, SB); break; case 0xca: dst->opcode = O (O_SYS_STAT, SB); break; case 0xcb: dst->opcode = O (O_SYS_FSTAT, SB); break; case 0xcc: dst->opcode = O (O_SYS_CMDLINE, SB); break; } /* End of Processing for system calls. */ } dst->next_pc = addr + len / 2; return; } else printf ("Don't understand 0x%x \n", looking_for); } len++; nib++; } fail: ; } end: /* Fell off the end. */ dst->opcode = O (O_ILL, SB);}static voidcompile (SIM_DESC sd, int pc){ int idx; /* Find the next cache entry to use. */ idx = h8_get_cache_top (sd) + 1; h8_increment_compiles (sd); if (idx >= sd->sim_cache_size) { idx = 1; } h8_set_cache_top (sd, idx); /* Throw away its old meaning. */ h8_set_cache_idx (sd, sd->sim_cache[idx].oldpc, 0); /* Set to new address. */ sd->sim_cache[idx].oldpc = pc; /* Fill in instruction info. */ decode (sd, pc, h8_get_memory_buf (sd) + pc, sd->sim_cache + idx); /* Point to new cache entry. */ h8_set_cache_idx (sd, pc, idx);}static unsigned char *breg[32];static unsigned short *wreg[16];static unsigned int *lreg[18];#define GET_B_REG(X) *(breg[X])#define SET_B_REG(X, Y) (*(breg[X])) = (Y)#define GET_W_REG(X) *(wreg[X])#define SET_W_REG(X, Y) (*(wreg[X])) = (Y)#define GET_L_REG(X) h8_get_reg (sd, X)#define SET_L_REG(X, Y) h8_set_reg (sd, X, Y)#define GET_MEMORY_L(X) \ ((X) < memory_size \ ? ((h8_get_memory (sd, (X)+0) << 24) | (h8_get_memory (sd, (X)+1) << 16) \ | (h8_get_memory (sd, (X)+2) << 8) | (h8_get_memory (sd, (X)+3) << 0)) \ : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 24) \ | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 16) \ | (h8_get_eightbit (sd, ((X)+2) & 0xff) << 8) \ | (h8_get_eightbit (sd, ((X)+3) & 0xff) << 0)))#define GET_MEMORY_W(X) \ ((X) < memory_size \ ? ((h8_get_memory (sd, (X)+0) << 8) \ | (h8_get_memory (sd, (X)+1) << 0)) \ : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 8) \ | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 0)))#define GET_MEMORY_B(X) \ ((X) < memory_size ? (h8_get_memory (sd, (X))) \ : (h8_get_eightbit (sd, (X) & 0xff)))#define SET_MEMORY_L(X, Y) \{ register unsigned char *_p; register int __y = (Y); \ _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : \ h8_get_eightbit_buf (sd) + ((X) & 0xff)); \ _p[0] = __y >> 24; _p[1] = __y >> 16; \ _p[2] = __y >> 8; _p[3] = __y >> 0; \}#define SET_MEMORY_W(X, Y) \{ register unsigned char *_p; register int __y = (Y); \ _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : \ h8_get_eightbit_buf (sd) + ((X) & 0xff)); \ _p[0] = __y >> 8; _p[1] = __y; \}#define SET_MEMORY_B(X, Y) \ ((X) < memory_size ? (h8_set_memory (sd, (X), (Y))) \ : (h8_set_eightbit (sd, (X) & 0xff, (Y))))/* Simulate a memory fetch. Return 0 for success, -1 for failure.*/static intfetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice){ int rn = arg->reg; int abs = arg->literal; int r; int t; if (val == NULL) return -1; /* Paranoia. */ switch (arg->type) { /* Indexed register plus displacement mode: This new family of addressing modes are similar to OP_DISP (register plus displacement), with two differences: 1) INDEXB uses only the least significant byte of the register, INDEXW uses only the least significant word, and INDEXL uses the entire register (just like OP_DISP). and 2) The displacement value in abs is multiplied by two for SW-sized operations, and by four for SL-size. This gives nine possible variations. */ case X (OP_INDEXB, SB): case X (OP_INDEXB, SW): case X (OP_INDEXB, SL): case X (OP_INDEXW, SB): case X (OP_INDEXW, SW): case X (OP_INDEXW, SL): case X (OP_INDEXL, SB): case X (OP_INDEXL, SW): case X (OP_INDEXL, SL): t = GET_L_REG (rn); switch (OP_KIND (arg->type)) { case OP_INDEXB: t &= 0xff; break; case OP_INDEXW: t &= 0xffff; break; case OP_INDEXL: default: break; } switch (OP_SIZE (arg->type)) { case SB: *val = GET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd)); break; case SW: *val = GET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd)); break; case SL: *val = GET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd)); break; } break; case X (OP_LOWREG, SB): *val = GET_L_REG (rn) & 0xff; break; case X (OP_LOWREG, SW): *val = GET_L_REG (rn) & 0xffff; break; case X (OP_REG, SB): /* Register direct, byte. */ *val = GET_B_REG (rn); break; case X (OP_REG, SW): /* Register direct, word. */ *val = GET_W_REG (rn); break; case X (OP_REG, SL): /* Register direct, long. */ *val = GET_L_REG (rn); break; case X (OP_IMM, SB): /* Immediate, byte. */ case X (OP_IMM, SW): /* Immediate, word. */ case X (OP_IMM, SL): /* Immediate, long. */ *val = abs; break; case X (OP_POSTINC, SB): /* Register indirect w/post-incr: byte. */ t = GET_L_REG (rn); t &= h8_get_mask (sd); r = GET_MEMORY_B (t); if (!twice) t += 1; t = t & h8_get_mask (sd); SET_L_REG (rn, t); *val = r; break; case X (OP_POSTINC, SW): /* Register indirect w/post-incr: word. */ t = GET_L_REG (rn); t &= h8_get_mask (sd); r = GET_MEMORY_W (t); if (!twice) t += 2; t = t & h8_get_mask (sd); SET_L_REG (rn, t); *val = r; break; case X (OP_POSTINC, SL): /* Register indirect w/post-incr: long. */ t = GET_L_REG (rn); t &= h8_get_mask (sd); r = GET_MEMORY_L (t); if (!twice) t += 4; t = t & h8_get_mask (sd); SET_L_REG (rn, t); *val = r; break; case X (OP_POSTDEC, SB): /* Register indirect w/post-decr: byte. */ t = GET_L_REG (rn); t &= h8_get_mask (sd); r = GET_MEMORY_B (t); if (!twice) t -= 1; t = t & h8_get_mask (sd); SET_L_REG (rn, t); *val = r; break; case X (OP_POSTDEC, SW): /* Register indirect w/post-decr: word. */ t = GET_L_REG (rn); t &= h8_get_mask (sd); r = GET_MEMORY_W (t); if (!twice) t -= 2; t = t & h8_get_mask (sd); SET_L_REG (rn, t); *val = r; break; case X (OP_POSTDEC, SL): /* Register indirect w/post-decr: long. */ t = GET_L_REG (rn); t &= h8_get_mask (sd); r = GET_MEMORY_L (t); if (!twice) t -= 4; t = t & h8_get_mask (sd); SET_L_REG (rn, t); *val = r; break; case X (OP_PREDEC, SB): /* Register indirect w/pre-decr: byte. */ t = GET_L_REG (rn) - 1; t &= h8_get_mask (sd); SET_L_REG (rn, t); *val = GET_MEMORY_B (t); break; case X (OP_PREDEC, SW): /* Register indirect w/pre-decr: word. */ t = GET_L_REG (rn) - 2; t &= h8_get_mask (sd); SET_L_REG (rn, t); *val = GET_MEMORY_W (t); break; case X (OP_PREDEC, SL): /* Register indirect w/pre-decr: long. */ t = GET_L_REG (rn) - 4; t &= h8_get_mask (sd); SET_L_REG (rn, t); *val = GET_MEMORY_L (t); break; case X (OP_PREINC, SB): /* Register indirect w/pre-incr: byte. */ t = GET_L_REG (rn) + 1; t &= h8_get_mask (sd); SET_L_REG (rn, t); *val = GET_MEMORY_B (t); break; case X (OP_PREINC, SW): /* Register indirect w/pre-incr: long. */ t = GET_L_REG (rn) + 2; t &= h8_get_mask (sd); SET_L_REG (rn, t); *val = GET_MEMORY_W (t); break; case X (OP_PREINC, SL): /* Register indirect w/pre-incr: long. */ t = GET_L_REG (rn) + 4; t &= h8_get_mask (sd); SET_L_REG (rn, t); *val = GET_MEMORY_L (t); break; case X (OP_DISP, SB): /* Register indirect w/displacement: byte. */ t = GET_L_REG (rn) + abs; t &= h8_get_mask (sd); *val = GET_MEMORY_B (t); break; case X (OP_DISP, SW): /* Register indirect w/displacement: word. */ t = GET_L_REG (rn) + abs; t &= h8_get_mask (sd); *val = GET_MEMORY_W (t); break; case X (OP_DISP, SL): /* Register indirect w/displacement: long. */ t = GET_L_REG (rn) + abs; t &= h8_get_mask (sd); *val =GET_MEMORY_L (t); break; case X (OP_MEM, SL): /* Absolute memory address, long. */ t = GET_MEMORY_L (abs); t &= h8_get_mask (sd); *val = t; break; case X (OP_MEM, SW): /* Absolute memory address, word. */ t = GET_MEMORY_W (abs); t &= h8_get_mask (sd); *val = t; break; case X (OP_PCREL, SB): /* PC relative (for jump, branch etc). */ case X (OP_PCREL, SW): case X (OP_PCREL, SL): case X (OP_PCREL, SN): *val = abs; break; case X (OP_MEM, SB): /* Why isn't this implemented? */ default: sim_engine_set_run_state (sd, sim_stopped, SIGSEGV); return -1; } return 0; /* Success. */}/* Normal fetch. */static intfetch (SIM_DESC sd, ea_type *arg, int *val){ return fetch_1 (sd, arg, val, 0);}/* Fetch which will be followed by a store to the same location. The difference being that we don't want to do a post-increment or post-decrement at this time: we'll do it when we store. */static intfetch2 (SIM_DESC sd, ea_type *arg, int *val){ return fetch_1 (sd, arg, val, 1);}/* Simulate a memory store. Return 0 for success, -1 for failure.*/static intstore_1 (SIM_DESC sd, ea_type *arg, int n, int twice){ int rn = arg->reg; int abs = arg->literal; int t; switch (arg->type) { /* Indexed register plus displacement mode: This new family of addressing modes are similar to OP_DISP (register plus displacement), with two differences: 1) INDEXB uses only the least significant byte of the register, INDEXW uses only the least significant word, and INDEXL uses the entire register (just like OP_DISP). and 2) The displacement value in abs is multiplied by two for SW-sized operations, and by four for SL-size. This gives nine possible variations. */ case X (OP_INDEXB, SB): case X (OP_INDEXB, SW): case X (OP_INDEXB, SL): case X (OP_INDEXW, SB): case X (OP_INDEXW, SW): case X (OP_INDEXW, SL): case X (OP_INDEXL, SB): case X (OP_INDEXL, SW): case X (OP_INDEXL, SL): t = GET_L_REG (rn); switch (OP_KIND (arg->type)) { case OP_INDEXB: t &= 0xff; break; case OP_INDEXW: t &= 0xffff; break; case OP_INDEXL: default: break; } switch (OP_SIZE (arg->type)) { case SB: SET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd), n); break; case SW: SET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd), n); break; case SL: SET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd), n); break; } break; case X (OP_REG, SB): /* Register direct, byte. */ SET_B_REG (rn, n); break; case X (OP_REG, SW): /* Register direct, word. */ SET_W_REG (rn, n); break; case X (OP_REG, SL): /* Register direct, long. */ SET_L_REG (rn, n); break; case X (OP_PREDEC, SB): /* Register indirect w/pre-decr, byte. */ t = GET_L_REG (rn); if (!twice) t -= 1; t &= h8_get_mask (sd); SET_L_REG (rn, t); SET_MEMORY_B (t, n); break; case X (OP_PREDEC, SW): /* Register indirect w/pre-decr, word. */ t = GET_L_REG (rn); if (!twice) t -= 2; t &= h8_get_mask (sd); SET_L_REG (rn, t); SET_MEMORY_W (t, n); break; case X (OP_PREDEC, SL): /* Register indirect w/pre-decr, long. */ t = GET_L_REG (rn); if (!twice) t -= 4; t &= h8_get_mask (sd); SET_L_REG (rn, t); SET_MEMORY_L (t, n); break; case X (OP_PREINC, SB): /* Register indirect w/pre-incr, byte. */ t = GET_L_REG (rn); if (!twice) t += 1; t &= h8_get_mask (sd); SET_L_REG (rn, t); SET_MEMORY_B (t, n); break; case X (OP_PREINC, SW): /* Register indirect w/pre-incr, word. */ t = GET_L_REG (rn); if (!twice) t += 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -