Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Oct 1995 18:45:05 +0100 (MET)
From:      Juergen Lock <nox@jelal.hb.north.de>
To:        joerg@FreeBSD.org, ports@FreeBSD.org
Subject:   pcemu, run a few more dos commands
Message-ID:  <199510031745.SAA03001@saturn>

next in thread | raw e-mail | index | archive | help
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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199510031745.SAA03001>