Date: Sun, 3 Nov 1996 12:39:34 +0100 (MET) From: Juergen Lock <nox@jelal.hb.north.de> To: msmith@atrad.adelaide.edu.au (Michael Smith) Cc: luigi@iet.unipi.it, emulation@freebsd.org, babkin@hq.icb.chel.su Subject: Re: New PC-Emu (fwd) Message-ID: <199611031139.MAA04001@saturn.hb.north.de> In-Reply-To: <199611010553.QAA03882@genesis.atrad.adelaide.edu.au> from "Michael Smith" at Nov 1, 96 04:23:04 pm
next in thread | previous in thread | raw e-mail | index | archive | help
Michael Smith writes: > > I have something that vaguely approximates a cut at this here (very > ragged still though 8( ), and what I'm looking for is a small set of > testers (perferably ones that are using PC-Emu already) to check that > I've correctly merged things and that the result is mildly cohesive. > > If/when this proves the case, I'll release the result in > comp.emulators.misc and make a 'real' port out of it. > > If you're interested, have a look at > ftp://gsoft.com.au/pub/pcemu1.9pre.tar.gz > > and let me know how you go. OK i just tried to sync this with my own old hacked copy of the port, and here is what i have now: - turn on some of the added instructions (actually i see now at least bound is still left turned off), working versions of enter/leave (enter second arg 0 only), added back(?) c0pre/c1pre - #ifdef'd the exit(1) in i_notdone (-DEXIT_NOTDONE) - handle keymap code=0xff (hex) a quick test looks like its now running everything my old version did, i haven't checked out the new features yet... Index: cpu.c @@ -4223,16 +4223,21 @@ /********************************************************************** * lr 941008 - these are new codes (non 8086) *********************************************************************/ -static INLINE2 i_push_imm8(void) +static INLINE2 void i_push_imm8(void) { register unsigned tmp1=(WORD)(ReadWord(&wregs[SP])-2); +#if 1 + /* direct sign extend, more efficient(?) */ + register unsigned imm=(WORD)((INT16)((INT8)GetMemInc(c_cs,ip))); +#else register unsigned imm=GetMemInc(c_cs,ip); if (imm>127) imm |= 0xff00; +#endif WriteWord(&wregs[SP],tmp1); PutMemW(c_stack, tmp1, imm); } -static INLINE2 i_push_imm16(void) +static INLINE2 void i_push_imm16(void) { register unsigned tmp1=(WORD)(ReadWord(&wregs[SP])-2); register unsigned imm=GetMemInc(c_cs,ip); @@ -4240,7 +4245,41 @@ WriteWord(&wregs[SP],tmp1); PutMemW(c_stack, tmp1, imm); } + +#if 1 +/* these seem to work a little better :) */ +static INLINE2 void i_leave(void) +{ + /* Opcode 0xc9 (80186) */ + + wregs[SP] = wregs[BP]; + PopWordReg(BP); +} +static INLINE2 void i_enter(void) +{ + /* Opcode 0xc8 (80186) */ + + register unsigned tmp; + register unsigned tmp1 = (WORD)(ReadWord(&wregs[SP])-2); + WORD tmp2; + tmp2 = ReadWord(&wregs[BP]); + PutMemW(c_stack,tmp1,tmp2); + WriteWord(&wregs[BP],tmp1); + + tmp = GetMemInc(c_cs,ip); + tmp += GetMemInc(c_cs,ip) << 8; + tmp2 = GetMemInc(c_cs,ip); + if (tmp2) { + /* XXX handle non-0 second arg... */ + fprintf(stderr,"Error: Unimplemented opcode c8 xxxx %02X at cs:ip = %04X:%04X\n", + tmp2,sregs[CS],ip-3); +/* exit(1); */ + } + + WriteWord(&wregs[SP],tmp1-tmp); +} +#else static INLINE2 i_leave(void) { /* MOV BP, SP; POP BP */ @@ -4269,6 +4308,7 @@ WriteWord(&wregs[BP], fp ); WriteWord(&wregs[SP], ReadWord(&wregs[SP]) - disp ); } +#endif static void i_bound(void) { @@ -4283,13 +4323,177 @@ if (op< low || op >high) interrupt(5); } + +static INLINE2 void i_c0pre(void) +{ + /* Opcode 0xc0 (80186) */ + + unsigned ModRM = GetMemInc(c_cs,ip); + unsigned count = GetMemInc(c_cs,ip); + register BYTE *dest = GetModRMRMB(ModRM); + register unsigned tmp = *dest; + + for (; count; --count) { /*!!!fix OF? not on intel it seems... */ + register unsigned tmp2 = tmp; + + switch (ModRM & 0x38) + { + case 0x00: /* ROL eb,count */ + CF = (tmp & 0x80) != 0; + *dest = (tmp << 1) + CF; + OF = !(!(tmp & 0x40)) != CF; + break; + case 0x08: /* ROR eb,count */ + CF = (tmp & 0x01) != 0; + *dest = (tmp >> 1) + (CF << 7); + OF = !(!(tmp & 0x80)) != CF; + break; + case 0x10: /* RCL eb,count */ + OF = (tmp ^ (tmp << 1)) & 0x80; + *dest = (tmp << 1) + CF; + CF = (tmp & 0x80) != 0; + break; + case 0x18: /* RCR eb,count */ + *dest = (tmp >> 1) + (CF << 7); + OF = !(!(tmp & 0x80)) != CF; + CF = (tmp & 0x01) != 0; + break; + case 0x20: /* SHL eb,count */ + case 0x30: + tmp += tmp; + + SetCFB_Add(tmp,tmp2); + SetOFB_Add(tmp,tmp2,tmp2); + AF = 1; + SetZFB(tmp); + SetSFB(tmp); + SetPF(tmp); + + *dest = (BYTE)tmp; + break; + case 0x28: /* SHR eb,count */ + CF = (tmp & 0x01) != 0; + OF = tmp & 0x80; + + tmp2 = tmp >> 1; + + SetSFB(tmp2); + SetPF(tmp2); + SetZFB(tmp2); + AF = 1; + *dest = (BYTE)tmp2; + tmp = tmp2; + break; + case 0x38: /* SAR eb,count */ + CF = (tmp & 0x01) != 0; + OF = 0; + + tmp2 = (tmp >> 1) | (tmp & 0x80); + + SetSFB(tmp2); + SetPF(tmp2); + SetZFB(tmp2); + AF = 1; + *dest = (BYTE)tmp2; + tmp = tmp2; + break; + } + } +} + +static INLINE2 void i_c1pre(void) +{ + /* Opcode 0xc1 (80186) */ + + unsigned ModRM = GetMemInc(c_cs,ip); + unsigned count = GetMemInc(c_cs,ip); + register WORD *dest = GetModRMRMW(ModRM); + register unsigned tmp = ReadWord(dest); + + for (; count; --count) { /*!!!fix OF?*/ + register unsigned tmp2 = tmp; + + switch (ModRM & 0x38) + { + case 0x00: /* ROL ew,count */ + CF = (tmp & 0x8000) != 0; + tmp2 = (tmp << 1) + CF; + OF = !(!(tmp & 0x4000)) != CF; + WriteWord(dest,tmp2); + tmp = tmp2; + break; + case 0x08: /* ROR ew,count */ + CF = (tmp & 0x01) != 0; + tmp2 = (tmp >> 1) + ((unsigned)CF << 15); + OF = !(!(tmp & 0x8000)) != CF; + WriteWord(dest,tmp2); + tmp = tmp2; + break; + case 0x10: /* RCL ew,count */ + tmp2 = (tmp << 1) + CF; + OF = (tmp ^ (tmp << 1)) & 0x8000; + CF = (tmp & 0x8000) != 0; + WriteWord(dest,tmp2); + tmp = tmp2; + break; + case 0x18: /* RCR ew,count */ + tmp2 = (tmp >> 1) + ((unsigned)CF << 15); + OF = !(!(tmp & 0x8000)) != CF; + CF = (tmp & 0x01) != 0; + WriteWord(dest,tmp2); + tmp = tmp2; + break; + case 0x20: /* SHL ew,count */ + case 0x30: + tmp += tmp; + + SetCFW_Add(tmp,tmp2); + SetOFW_Add(tmp,tmp2,tmp2); + AF = 1; + SetZFW(tmp); + SetSFW(tmp); + SetPF(tmp); + + WriteWord(dest,tmp); + break; + case 0x28: /* SHR ew,count */ + CF = (tmp & 0x01) != 0; + OF = tmp & 0x8000; + + tmp2 = tmp >> 1; + + SetSFW(tmp2); + SetPF(tmp2); + SetZFW(tmp2); + AF = 1; + WriteWord(dest,tmp2); + tmp = tmp2; + break; + case 0x38: /* SAR ew,count */ + CF = (tmp & 0x01) != 0; + OF = 0; + + tmp2 = (tmp >> 1) | (tmp & 0x8000); + + SetSFW(tmp2); + SetPF(tmp2); + SetZFW(tmp2); + AF = 1; + WriteWord(dest,tmp2); + tmp = tmp2; + break; + } + } +} /* lr 941008 - no reason to make this inlined! */ static void i_notdone(void) { fprintf(stderr,"Warning: non-8086 opcode %02X at cs:ip = %04X:%04X\n", c_cs[ip-1],sregs[CS],ip-1); +#ifdef EXIT_NOTDONE exit(1); +#endif } @@ -4424,9 +4628,9 @@ case 0x65: i_notdone(); break; case 0x66: i_notdone(); break; case 0x67: i_notdone(); break; - case 0x68: i_notdone(); break; + case 0x68: i_push_imm16(); break; case 0x69: i_notdone(); break; - case 0x6a: i_notdone(); break; + case 0x6a: i_push_imm8(); break; case 0x6b: i_notdone(); break; case 0x6c: i_notdone(); break; case 0x6d: i_notdone(); break; /* XXX */ @@ -4512,16 +4716,16 @@ case 0xbd: i_mov_bpd16(); break; case 0xbe: i_mov_sid16(); break; case 0xbf: i_mov_did16(); break; - case 0xc0: i_notdone(); break; - case 0xc1: i_notdone(); break; + case 0xc0: i_c0pre(); break; + case 0xc1: i_c1pre(); break; case 0xc2: i_ret_d16(); break; case 0xc3: i_ret(); break; case 0xc4: i_les_dw(); break; case 0xc5: i_lds_dw(); break; case 0xc6: i_mov_bd8(); break; case 0xc7: i_mov_wd16(); break; - case 0xc8: i_notdone(); break; - case 0xc9: i_notdone(); break; + case 0xc8: i_enter(); break; + case 0xc9: i_leave(); break; case 0xca: i_retf_d16(); break; case 0xcb: i_retf(); break; case 0xcc: i_int3(); break; Index: instr.h @@ -112,6 +112,8 @@ static INLINE2 void i_pop_bp(void); static INLINE2 void i_pop_si(void); static INLINE2 void i_pop_di(void); +static INLINE2 void i_push_imm16(void); +static INLINE2 void i_push_imm8(void); static INLINE2 void i_jo(void); static INLINE2 void i_jno(void); static INLINE2 void i_jb(void); @@ -191,12 +193,16 @@ static INLINE2 void i_mov_bpd16(void); static INLINE2 void i_mov_sid16(void); static INLINE2 void i_mov_did16(void); +static INLINE2 void i_c0pre(); +static INLINE2 void i_c1pre(); static INLINE2 void i_ret_d16(void); static INLINE2 void i_ret(void); static INLINE2 void i_les_dw(void); static INLINE2 void i_lds_dw(void); static INLINE2 void i_mov_bd8(void); static INLINE2 void i_mov_wd16(void); +static INLINE2 void i_enter(void); +static INLINE2 void i_leave(void); static INLINE2 void i_retf_d16(void); static INLINE2 void i_retf(void); static INLINE2 void i_int3(void); @@ -352,9 +358,9 @@ i_notdone, /* 0x65 XXX */ i_notdone, /* 0x66 XXX */ i_notdone, /* 0x67 XXX */ - i_notdone, /* 0x68 XXX */ + i_push_imm16, /* 0x68 */ i_notdone, /* 0x69 XXX */ - i_notdone, /* 0x6a XXX */ + i_push_imm8, /* 0x6a */ i_notdone, /* 0x6b XXX */ i_notdone, /* 0x6c XXX -- insb (286) */ i_notdone, /* 0x6d XXX -- insw (286) */ @@ -440,16 +446,16 @@ i_mov_bpd16, /* 0xbd */ i_mov_sid16, /* 0xbe */ i_mov_did16, /* 0xbf */ - i_notdone, - i_notdone, + i_c0pre, /* 0xc0 */ + i_c1pre, /* 0xc1 */ i_ret_d16, /* 0xc2 */ i_ret, /* 0xc3 */ i_les_dw, /* 0xc4 */ i_lds_dw, /* 0xc5 */ i_mov_bd8, /* 0xc6 */ i_mov_wd16, /* 0xc7 */ - i_notdone, - i_notdone, + i_enter, /* 0xc8 */ + i_leave, /* 0xc9 */ i_retf_d16, /* 0xca */ i_retf, /* 0xcb */ i_int3, /* 0xcc */ Index: main.c @@ -50,10 +50,13 @@ static char *set_keymap(char *buf) { char c; - int code; + int code, chx; if(sscanf(buf, " %*s %i=%c", &code, &c) != 2) return "usage: keymap code=char"; + /* handle 0x... (== hex) */ + if(c == '0' && sscanf(buf, " %*s %*i=%i", &chx) == 1) + c = chx; if(put_scan_table(code, (unsigned char)c)) return "bad value for keymap"; return 0;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611031139.MAA04001>