Skip site navigation (1)Skip section navigation (2)
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>