From owner-freebsd-ports Tue Oct 3 12:55:50 1995 Return-Path: owner-ports Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id MAA18639 for ports-outgoing; Tue, 3 Oct 1995 12:55:50 -0700 Received: from alf.zfn.uni-bremen.de (alf20.zfn.uni-bremen.de [134.102.20.22]) by freefall.freebsd.org (8.6.12/8.6.6) with SMTP id MAA18622 ; Tue, 3 Oct 1995 12:55:39 -0700 Received: from deceased.hb.north.de by alf.zfn.uni-bremen.de (AIX 3.2/UCB 5.64/4.940318) id AA05961; Tue, 3 Oct 1995 20:36:24 +0200 Received: from jelal.hb.north.de by deceased.hb.north.de with uucp (Smail3.1.29.1) id m0t0D8f-000ZB3C; Tue, 3 Oct 95 20:36 MET Received: by jelal.hb.north.de (SMail-ST 0.95gcc/2.5+) id AA00416; Tue, 3 Oct 1995 19:35:08 +0100 (CET) Received: (from nox@localhost) by saturn (8.6.11/8.6.9) id SAA03001; Tue, 3 Oct 1995 18:45:06 +0100 From: Juergen Lock Message-Id: <199510031745.SAA03001@saturn> Subject: pcemu, run a few more dos commands To: joerg@FreeBSD.org, ports@FreeBSD.org Date: Tue, 3 Oct 1995 18:45:05 +0100 (MET) X-Mailer: ELM [version 2.4 PL24] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Length: 12756 Sender: owner-ports@FreeBSD.org Precedence: bulk This should drop right into pcemu/patches, makes it emulate a few more instructions (mostly 80186). I still don't have a real intel CPU manual so some of this isn't perfect, (like does anyone know what the second arg to enter does exactly? i haven't yet seen it used...) but it does increase the number of working programs considerably i think. though i still couldn't get keyb gr working... :) greetings, Juergen Index: instr.h @@ -64,6 +64,7 @@ static INLINE2 void i_sub_ald8(void); static INLINE2 void i_sub_axd16(void); static INLINE2 void i_cs(void); +static INLINE2 void i_das(void); static INLINE2 void i_xor_br8(void); static INLINE2 void i_xor_r8b(void); static INLINE2 void i_xor_wr16(void); @@ -299,7 +300,7 @@ i_sub_ald8, /* 0x2c */ i_sub_axd16, /* 0x2d */ i_cs, /* 0x2e */ - i_notdone, + i_das, i_xor_br8, /* 0x30 */ i_xor_wr16, /* 0x31 */ i_xor_r8b, /* 0x32 */ Index: cpu.c @@ -1703,6 +1703,35 @@ PopWordReg(DI); } + +static INLINE2 void i_push_d16(void) +{ + /* Opcode 0x68 (80186) */ + + register unsigned tmp; + register unsigned tmp1 = (WORD)(ReadWord(&wregs[SP])-2); + + tmp = GetMemInc(c_cs,ip); + tmp += GetMemInc(c_cs,ip) << 8; + + PutMemW(c_stack,tmp1,tmp); + WriteWord(&wregs[SP],tmp1); +} + + +static INLINE2 void i_push_d8(void) +{ + /* Opcode 0x6a (80186) */ + + register unsigned tmp; + register unsigned tmp1 = (WORD)(ReadWord(&wregs[SP])-2); + + tmp = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip))); + + PutMemW(c_stack,tmp1,tmp); + WriteWord(&wregs[SP],tmp1); +} + /* Conditional jumps from 0x70 to 0x7f */ JumpCond(o, OF) /* 0x70 = Jump if overflow */ @@ -2835,6 +2864,170 @@ } +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?*/ + 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; + } + } +} + + static INLINE2 void i_ret_d16(void) { /* Opcode 0xc2 */ @@ -2916,6 +3109,40 @@ } +static INLINE2 void i_enter(void) +{ + /* Opcode 0xc8 (80186) */ + + register unsigned tmp; + register unsigned tmp1 = (WORD)(ReadWord(&wregs[SP])-2); + WORD tmp2; + /*WriteWord(&wregs[SP],tmp1);*/ + 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) { + 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); +} + + +static INLINE2 void i_leave(void) +{ + /* Opcode 0xc9 (80186) */ + + wregs[SP] = wregs[BP]; + PopWordReg(BP); +} + + static INLINE2 void i_retf_d16(void) { /* Opcode 0xca */ @@ -3715,6 +3942,17 @@ } +static INLINE2 void i_hlt(void) +{ + /* Opcode 0xf4 */ + + /*!!!should do something, maybe even give up cpu? */ +#ifdef DEBUGGER + call_debugger(D_INT); +#endif +} + + static INLINE2 void i_cmc(void) { /* Opcode 0xf5 */ @@ -4300,9 +4538,17 @@ case 0x65: i_notdone(); break; case 0x66: i_notdone(); break; case 0x67: i_notdone(); break; +#if 1 + case 0x68: i_push_d16(); break; +#else case 0x68: i_notdone(); break; +#endif case 0x69: i_notdone(); break; +#if 1 + case 0x6a: i_push_d8(); break; +#else case 0x6a: i_notdone(); break; +#endif case 0x6b: i_notdone(); break; case 0x6c: i_notdone(); break; case 0x6d: i_notdone(); break; @@ -4388,16 +4634,26 @@ case 0xbd: i_mov_bpd16(); break; case 0xbe: i_mov_sid16(); break; case 0xbf: i_mov_did16(); break; +#if 1 + case 0xc0: i_c0pre(); break; + case 0xc1: i_c1pre(); break; +#else case 0xc0: i_notdone(); break; case 0xc1: i_notdone(); break; +#endif 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; +#if 1 + case 0xc8: i_enter(); break; + case 0xc9: i_leave(); break; +#else case 0xc8: i_notdone(); break; case 0xc9: i_notdone(); break; +#endif case 0xca: i_retf_d16(); break; case 0xcb: i_retf(); break; case 0xcc: i_int3(); break; @@ -4440,7 +4696,11 @@ case 0xf1: i_gobios(); break; case 0xf2: i_repne(); break; case 0xf3: i_repe(); break; +#if 1 + case 0xf4: i_hlt(); break; +#else case 0xf4: i_notdone(); break; +#endif case 0xf5: i_cmc(); break; case 0xf6: i_f6pre(); break; case 0xf7: i_f7pre(); break; Index: instr.h @@ -111,6 +111,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_d16(void); +static INLINE2 void i_push_d8(void); static INLINE2 void i_jo(void); static INLINE2 void i_jno(void); static INLINE2 void i_jb(void); @@ -190,12 +192,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); @@ -229,6 +235,7 @@ static INLINE2 void i_lock(void); static INLINE2 void i_repne(void); static INLINE2 void i_repe(void); +static INLINE2 void i_hlt(void); static INLINE2 void i_cmc(void); static INLINE2 void i_f6pre(void); static INLINE2 void i_f7pre(void); @@ -350,9 +357,17 @@ i_notdone, i_notdone, i_notdone, +#if 1 + i_push_d16, +#else i_notdone, +#endif i_notdone, +#if 1 + i_push_d8, +#else i_notdone, +#endif i_notdone, i_notdone, i_notdone, @@ -438,16 +453,26 @@ i_mov_bpd16, /* 0xbd */ i_mov_sid16, /* 0xbe */ i_mov_did16, /* 0xbf */ +#if 1 + i_c0pre, + i_c1pre, +#else i_notdone, i_notdone, +#endif i_ret_d16, /* 0xc2 */ i_ret, /* 0xc3 */ i_les_dw, /* 0xc4 */ i_lds_dw, /* 0xc5 */ i_mov_bd8, /* 0xc6 */ i_mov_wd16, /* 0xc7 */ +#if 1 + i_enter, + i_leave, +#else i_notdone, i_notdone, +#endif i_retf_d16, /* 0xca */ i_retf, /* 0xcb */ i_int3, /* 0xcc */ @@ -490,7 +515,11 @@ i_gobios, /* 0xf1 */ i_repne, /* 0xf2 */ i_repe, /* 0xf3 */ +#if 1 + i_hlt, +#else i_notdone, +#endif i_cmc, /* 0xf5 */ i_f6pre, /* 0xf6 */ i_f7pre, /* 0xf7 */ Index: main.c @@ -42,10 +42,12 @@ 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"; + 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; Index: cpu.c @@ -4572,7 +4572,11 @@ case 0x7f: i_jnle(); break; case 0x80: i_80pre(); break; case 0x81: i_81pre(); break; +#if 1 + case 0x82: i_80pre(); break; +#else case 0x82: i_notdone(); break; +#endif case 0x83: i_83pre(); break; case 0x84: i_test_br8(); break; case 0x85: i_test_wr16(); break; Index: instr.h @@ -391,7 +391,11 @@ i_jnle, /* 0x7f */ i_80pre, /* 0x80 */ i_81pre, /* 0x81 */ +#if 1 + i_80pre, /* 0x82 */ +#else i_notdone, +#endif i_83pre, /* 0x83 */ i_test_br8, /* 0x84 */ i_test_wr16, /* 0x85 */