📄 star.c
字号:
emit("push edx\n"); emit("add edx,[__vbr]\n"); } emit("call readmemorydword\n"); if(cputype >= 68010) { emit("pop edx\n"); } emit("push ecx\n");/* dest. PC */ sr2cx(); emit("push ecx\n");/* old SR */ supervisor(); /* ** Exception handlers do not like being traced, so clear the SR trace ** flag as well as the trace tricky bit. ** ** Leave the cycle leftover count alone, in case we still need to ** call attention to other unrelated tricky bits. */ emit("and byte[__sr+1],27h\n"); emit("mov byte[__trace_trickybit],0\n"); emit("mov ecx,esi\n"); emit("sub ecx,ebp\n"); if(cputype >= 68010) { emit("push ecx\n");/* old PC */ emit("mov ecx,edx\n"); } emit("mov edx,[__a7]\n"); if(cputype >= 68010) { emit("and ecx,0FFCh\n");/* Format code */ emit("sub edx,byte 2\n"); emit("call writememoryword\n"); emit("pop ecx\n"); } emit("sub edx,byte 4\n"); emit("call writememorydword\n"); emit("pop ecx\n");/* old SR */ emit("sub edx,byte 2\n"); emit("call writememoryword\n"); emit("mov [__a7],edx\n"); emit("pop esi\n");/* dest. PC */ emit("ret\n");}/***************************************************************************//* Privilege violation */static void gen_privilege_violation(void){ align(16); emit("privilege_violation:\n"); emit("sub esi,byte 2\n"); emit("mov edx,20h\n"); emit("call group_1_exception\n"); perform_cached_rebase(); ret_timing((cputype==68010)?38:34);}/***************************************************************************/static void usereg(void) { emit("and ebx,byte 7\n");}/* usereg only where applicable */static void selective_usereg(void) { switch(main_eamode) { case dreg: case areg: case aind: case ainc: case adec: case adsp: case axdp: usereg(); default: break; }}static void selftest(int size) { emit("test %s,%s\n", x86cx[size], x86cx[size]);}/***************************************************************************//* Get condition: Less Than (N^V)** If true, the x86 sign flag will be set */static void getcondition_l_s_ns(void) { emit("push eax\n"); emit("neg al\n"); emit("xor al,ah\n"); emit("pop eax\n");}/* Get condition: Less Than or Equal ((N^V)|Z)** If true, the x86 sign flag will be set */static void getcondition_le_s_ns(void) { emit("push eax\n"); emit("neg al\n"); emit("xor al,ah\n"); emit("add ah,ah\n"); emit("or al,ah\n"); emit("pop eax\n");}static char optcc[5];static char optrc[5];static void getcondition(int cc) { switch(cc) { case 0x0: case 0x1: break; case 0x2:/* a */ emit("test ah,41h\n"); sprintf(optcc, "z"); sprintf(optrc, "nz"); break; case 0x3:/* be */ emit("test ah,41h\n"); sprintf(optcc, "nz"); sprintf(optrc, "z"); break; case 0x4:/* nc */ emit("test ah,1\n"); sprintf(optcc, "z"); sprintf(optrc, "nz"); break; case 0x5:/* c */ emit("test ah,1\n"); sprintf(optcc, "nz"); sprintf(optrc, "z"); break; case 0x6:/* ne */ emit("test ah,40h\n"); sprintf(optcc, "z"); sprintf(optrc, "nz"); break; case 0x7:/* e */ emit("test ah,40h\n"); sprintf(optcc, "nz"); sprintf(optrc, "z"); break; case 0x8:/* no */ emit("test al,1\n"); sprintf(optcc, "z"); sprintf(optrc, "nz"); break; case 0x9:/* o */ emit("test al,1\n"); sprintf(optcc, "nz"); sprintf(optrc, "z"); break; case 0xA:/* ns */ emit("or ah,ah\n"); sprintf(optcc, "ns"); sprintf(optrc, "s"); break; case 0xB:/* s */ emit("or ah,ah\n"); sprintf(optcc, "s"); sprintf(optrc, "ns"); break; case 0xC:/* ge */ getcondition_l_s_ns(); sprintf(optcc, "ns"); sprintf(optrc, "s"); break; case 0xD:/* l */ getcondition_l_s_ns(); sprintf(optcc, "s"); sprintf(optrc, "ns"); break; case 0xE:/* g */ getcondition_le_s_ns(); sprintf(optcc, "ns"); sprintf(optrc, "s"); break; case 0xF:/* le */ getcondition_le_s_ns(); sprintf(optcc, "s"); sprintf(optrc, "ns"); break; default:break; }}static void flags(void) { emit("lahf\n"); emit("seto al\n");}static void flags_v0(void) { emit("lahf\n"); emit("mov al,0\n");}/* Put one of the x86 flags into the 68K zero flag. */static void flag_to_z(char *f) { int myline = linenum; linenum += 2; emit("j%s short ln%d\n", f, myline); emit("and ah,0BFh\n"); emit("jmp short ln%d\n", myline + 1); emit("ln%d:\n", myline); emit("or ah,40h\n"); emit("ln%d:\n", myline + 1);}/* carry to X flag */static void c2x(void) { emit("setc [__xflag]\n");}/* with previous flags in another register, adjust for non-changing zero */static void adjzero(char *reg) { int myline = linenum; linenum++; emit("jnz short ln%d\n", myline); emit("or %s,0BFh\n", reg); emit("and ah,%s\n", reg); emit("ln%d:\n", myline);}/* Check for privilege violation */static void privilegecheck(void) { emit("test byte[__sr+1],20h\n"); emit("jz near privilege_violation\n");}/****************************************************************************** EFFECTIVE ADDRESS GENERATION****************************************************************************//*** There are five types of EA activity:**** 1. Read: precalc -> read -> postcalc** 2. Write: precalc -> write -> postcalc** 3. R-M-W: precalc -> read -> (modify) -> write -> postcalc** 4. Move: Read followed by Write** 5. Control: precalc*//* Calculate address */static void ea_step_precalc(int size, enum eamode mode, int reg) { char regs[100]; if(reg == -1) sprintf(regs, "ebx*4"); else sprintf(regs, "%d", reg * 4); switch(mode) { case dreg: case areg: break; case aind: case ainc: case adec: emit("mov edx,[__areg+%s]\n",regs); if(mode == adec) { /* Compensate for byte-sized stack ops */ if(size == 1) { if(reg == -1) { emit("cmp bl,7\n"); emit("adc edx,byte -2\n"); } else if(reg == 7) { emit("sub edx,byte 2\n"); } else { emit("dec edx\n"); } } else { emit("sub edx,byte %d\n", size); } } break; case adsp: emit("movsx edx,word[esi]\n"); emit("add esi,byte 2\n"); emit("add edx,[__areg+%s]\n", regs); break; case axdp: emit("call decode_ext\n"); emit("add edx,[__areg+%s]\n", regs); break; case absw: emit("movsx edx,word[esi]\n"); emit("add esi,byte 2\n"); break; case absl: emit("mov edx,dword[esi]\n"); emit("add esi,byte 4\n"); emit("rol edx,16\n"); break; case pcdp: emit("movsx edx,word[esi]\n"); emit("add edx,esi\n"); emit("sub edx,ebp\n"); emit("add esi,byte 2\n"); break; case pcxd: emit("call decode_ext\n"); emit("add edx,esi\n"); emit("sub edx,ebp\n"); emit("sub edx,byte 2\n"); break; case immd: break; default: emit("#error ea_step_precalc\n"); break; }}static void ea_step_read(int size, enum eamode mode, int reg) { char regs[100]; if(reg == -1) sprintf(regs, "ebx*4"); else sprintf(regs, "%d", reg * 4); switch(mode) { case dreg: emit("mov ecx,[__dreg+%s]\n", regs); break; case areg: emit("mov ecx,[__areg+%s]\n", regs); break; case aind: case ainc: case adec: case adsp: case axdp: case absw: case absl: case pcdp: case pcxd: emit("call readmemory%s\n", sizename[size]); break; case immd: switch(size) { case 1: case 2: emit("mov cx,[esi]\n"); emit("add esi,byte 2\n"); break; case 4: emit("mov ecx,[esi]\n"); emit("add esi,byte 4\n"); emit("rol ecx,16\n"); break; default: emit("#error ea_step_read\n"); break; } break; default: emit("#error ea_step_read\n"); break; }}/*** Special case for when you need to load a word and sign-extend it.** This cuts some fat out of a few instructions (i.e. MOVEA).*/static void ea_step_read_signword(enum eamode mode, int reg) { char regs[100]; if(reg == -1) sprintf(regs, "ebx*4"); else sprintf(regs, "%d", reg * 4); switch(mode) { case dreg: emit("movsx ecx,word[__dreg+%s]\n", regs); break; case areg: emit("movsx ecx,word[__areg+%s]\n", regs); break; case aind: case ainc: case adec: case adsp: case axdp: case absw: case absl: case pcdp: case pcxd: emit("call readmemory%s\n", sizename[2]); emit("movsx ecx,cx\n"); break; case immd: emit("movsx ecx,word[esi]\n"); emit("add esi,byte 2\n"); break; default: emit("#error ea_step_read_signword\n"); break; }}static void ea_step_write(int size, enum eamode mode, int reg) { char regs[100]; if(reg == -1) sprintf(regs, "ebx*4"); else sprintf(regs, "%d", reg * 4); switch(mode) { case dreg: emit("mov [__dreg+%s],%s\n", regs, x86cx[size]); break; case aind: case ainc: case adec: case adsp: case axdp: case absw: case absl: emit("call writememory%s\n", sizename[size]); break; default: emit("#error ea_step_write\n"); break; }}static void ea_step_postcalc(int size, enum eamode mode, int reg) { char regs[100]; if(reg == -1) sprintf(regs, "ebx*4"); else sprintf(regs, "%d", reg * 4); switch(mode) { case ainc: /* Compensate for byte-sized stack ops */ if(size == 1) { if(reg == -1) { emit("cmp bl,7\n"); emit("sbb edx,byte -2\n"); } else if(reg == 7) { emit("add edx,byte 2\n"); } else { emit("inc edx\n"); } } else { emit("add edx,byte %d\n", size); } /* Fall through */ case adec: /* Store already-predecremented address */ emit("mov [__areg+%s],edx\n", regs); break; case dreg: case areg: case aind: case adsp: case axdp: case absw: case absl: case pcdp: case pcxd: case immd: break; default: emit("#error ea_step_postcalc\n"); break; }}/* Combined EA routines */static void ea_load(int size, enum eamode mode, int reg) { ea_step_precalc (size, mode, reg); ea_step_read (size, mode, reg); ea_step_postcalc(size, mode, reg);}static void ea_load_signword(enum eamode mode, int reg) { ea_step_precalc (2, mode, reg); ea_step_read_signword( mode, reg); ea_step_postcalc (2, mode, reg);}static void ea_store(int size, enum eamode mode, int reg) { ea_step_precalc (size, mode, reg); ea_step_write (size, mode, reg); ea_step_postcalc(size, mode, reg);}static void ea_rmw_load(int size, enum eamode mode, int reg) { ea_step_precalc (size, mode, reg); ea_step_read (size, mode, reg);}static void ea_rmw_store(int size, enum eamode mode, int reg) { ea_step_write (size, mode, reg); ea_step_postcalc(size, mode, reg);}static void ea_control(enum eamode mode, int reg) { ea_step_precalc (0, mode, reg);}static void main_ea_load(void) { ea_load(main_size, main_eamode, -1);}static void main_ea_load_signed(void) { if(main_size < 4) { ea_load_signword(main_eamode, -1); } else { ea_load(main_size, main_eamode, -1); }}static void main_ea_store(void) { ea_store(main_size, main_eamode, -1);}static void main_ea_rmw_load(void) { ea_rmw_load(main_size, main_eamode, -1);}stati
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -