PCem
view src/808x.c @ 150:871b132c6158
Implemented CR4 register for Winchip. Currently only Time Stamp Disable (TSD) has an effect.
Fixed stupid bug in WRMSR - MSRs can now be written with values other than zero.
| author | TomW |
|---|---|
| date | Sat Aug 23 16:28:16 2014 +0100 |
| parents | bd46c39a78e8 |
| children | d0d530adce12 |
line source
1 //1B64 - Vid_SetMode (Vid_Vesa.c)
2 //6689c - CONS_Printf
3 /*SHR AX,1
5 4 clocks - fetch opcode
6 4 clocks - fetch mod/rm
7 2 clocks - execute 2 clocks - fetch opcode 1
8 2 clocks - fetch opcode 2
9 4 clocks - fetch mod/rm
10 2 clocks - fetch opcode 1 2 clocks - execute
11 2 clocks - fetch opcode 2 etc*/
12 #include <stdio.h>
13 #include "ibm.h"
15 #include "cpu.h"
16 #include "keyboard.h"
17 #include "mem.h"
18 #include "pic.h"
19 #include "timer.h"
20 #include "x86.h"
22 int nmi = 0;
24 int nextcyc=0;
25 int cycdiff;
26 int is8086=0;
28 int memcycs;
29 int nopageerrors=0;
31 void FETCHCOMPLETE();
33 uint8_t readmembl(uint32_t addr);
34 void writemembl(uint32_t addr, uint8_t val);
35 uint16_t readmemwl(uint32_t seg, uint32_t addr);
36 void writememwl(uint32_t seg, uint32_t addr, uint16_t val);
37 uint32_t readmemll(uint32_t seg, uint32_t addr);
38 void writememll(uint32_t seg, uint32_t addr, uint32_t val);
40 #undef readmemb
41 #undef readmemw
42 uint8_t readmemb(uint32_t a)
43 {
44 if (a!=(cs+pc)) memcycs+=4;
45 if (readlookup2[(a)>>12]==0xFFFFFFFF) return readmembl(a);
46 else return *(uint8_t *)(readlookup2[(a) >> 12] + (a));
47 }
49 uint8_t readmembf(uint32_t a)
50 {
51 if (readlookup2[(a)>>12]==0xFFFFFFFF) return readmembl(a);
52 else return *(uint8_t *)(readlookup2[(a) >> 12] + (a));
53 }
55 uint16_t readmemw(uint32_t s, uint16_t a)
56 {
57 if (a!=(cs+pc)) memcycs+=(8>>is8086);
58 if ((readlookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF)) return readmemwl(s,a);
59 else return *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a);
60 }
62 void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); memcycs+=4; }
64 #undef fetchea
65 #define fetchea() { rmdat=FETCH(); \
66 reg=(rmdat>>3)&7; \
67 mod=(rmdat>>6)&3; \
68 rm=rmdat&7; \
69 if (mod!=3) fetcheal(); }
71 void writemembl(uint32_t addr, uint8_t val);
72 void writememb(uint32_t a, uint8_t v)
73 {
74 memcycs+=4;
75 if (writelookup2[(a)>>12]==0xFFFFFFFF) writemembl(a,v);
76 else *(uint8_t *)(writelookup2[a >> 12] + a) = v;
77 }
78 void writememwl(uint32_t seg, uint32_t addr, uint16_t val);
79 void writememw(uint32_t s, uint32_t a, uint16_t v)
80 {
81 memcycs+=(8>>is8086);
82 if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememwl(s,a,v);
83 else *(uint16_t *)(writelookup2[(s + a) >> 12] + s + a) = v;
84 }
85 void writememll(uint32_t seg, uint32_t addr, uint32_t val);
86 void writememl(uint32_t s, uint32_t a, uint32_t v)
87 {
88 if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememll(s,a,v);
89 else *(uint32_t *)(writelookup2[(s + a) >> 12] + s + a) = v;
90 }
93 void dumpregs();
94 uint16_t oldcs;
95 int oldcpl;
97 int tempc;
98 uint8_t opcode;
99 int times=0;
100 uint16_t pc2,pc3;
101 int noint=0;
103 int output=0;
105 int shadowbios=0;
107 int ins=0;
108 //#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a))
110 int ssegs;
112 int fetchcycles=0,memcycs,fetchclocks;
114 uint8_t prefetchqueue[6];
115 uint16_t prefetchpc;
116 int prefetchw=0;
117 inline uint8_t FETCH()
118 {
119 uint8_t temp;
120 /* temp=prefetchqueue[0];
121 prefetchqueue[0]=prefetchqueue[1];
122 prefetchqueue[1]=prefetchqueue[2];
123 prefetchqueue[2]=prefetchqueue[3];
124 prefetchqueue[3]=prefetchqueue[4];
125 prefetchqueue[4]=prefetchqueue[5];
126 if (prefetchw<=((is8086)?4:3))
127 {
128 prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++;
129 if (is8086 && (prefetchpc&1))
130 {
131 prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++;
132 }
133 }*/
135 // uint8_t temp=readmemb(cs+pc);
136 // if (output) printf("FETCH %04X %i\n",pc,fetchcycles);
137 if (prefetchw==0) //(fetchcycles<4)
138 {
139 cycles-=(4-(fetchcycles&3));
140 fetchclocks+=(4-(fetchcycles&3));
141 fetchcycles=4;
142 temp=readmembf(cs+pc);
143 prefetchpc=pc=pc+1;
144 // if (output) printf(" FETCH %04X:%04X %02X %04X %04X %i\n",CS,pc-1,temp,pc,prefetchpc,prefetchw);
145 if (is8086 && (pc&1))
146 {
147 prefetchqueue[0]=readmembf(cs+pc);
148 // if (output) printf(" PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]);
149 prefetchpc++;
150 prefetchw++;
151 }
152 }
153 else
154 {
155 temp=prefetchqueue[0];
156 prefetchqueue[0]=prefetchqueue[1];
157 prefetchqueue[1]=prefetchqueue[2];
158 prefetchqueue[2]=prefetchqueue[3];
159 prefetchqueue[3]=prefetchqueue[4];
160 prefetchqueue[4]=prefetchqueue[5];
161 prefetchw--;
162 // if (output) printf("PREFETCH %04X:%04X %02X %04X %04X %i\n",CS,pc,temp,pc,prefetchpc,prefetchw);
163 fetchcycles-=4;
164 // fetchclocks+=4;
165 pc++;
166 }
167 // if (output) printf("%i\n",fetchcycles);
168 return temp;
169 }
171 inline void FETCHADD(int c)
172 {
173 int d;
174 // if (output) printf("FETCHADD %i\n",c);
175 if (c<0) return;
176 if (prefetchw>((is8086)?4:3)) return;
177 d=c+(fetchcycles&3);
178 while (d>3 && prefetchw<((is8086)?6:4))
179 {
180 d-=4;
181 if (is8086 && !(prefetchpc&1))
182 {
183 prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
184 // printf("PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]);
185 prefetchpc++;
186 prefetchw++;
187 }
188 if (prefetchw<6)
189 {
190 prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
191 // printf("PREFETCHED from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]);
192 prefetchpc++;
193 prefetchw++;
194 }
195 }
196 fetchcycles+=c;
197 if (fetchcycles>16) fetchcycles=16;
198 // if (fetchcycles>24) fetchcycles=24;
199 }
201 void FETCHCOMPLETE()
202 {
203 // pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw);
204 if (!(fetchcycles&3)) return;
205 if (prefetchw>((is8086)?4:3)) return;
206 if (!prefetchw) nextcyc=(4-(fetchcycles&3));
207 cycles-=(4-(fetchcycles&3));
208 fetchclocks+=(4-(fetchcycles&3));
209 if (is8086 && !(prefetchpc&1))
210 {
211 prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
212 // printf("PREFETCHEDc from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]);
213 prefetchpc++;
214 prefetchw++;
215 }
216 if (prefetchw<6)
217 {
218 prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
219 // printf("PREFETCHEDc from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]);
220 prefetchpc++;
221 prefetchw++;
222 }
223 fetchcycles+=(4-(fetchcycles&3));
224 }
226 inline void FETCHCLEAR()
227 {
228 /* int c;
229 fetchcycles=0;
230 prefetchpc=pc;
231 if (is8086 && (prefetchpc&1)) cycles-=4;
232 for (c=0;c<((is8086)?6:4);c++)
233 {
234 prefetchqueue[c]=readmembf(cs+prefetchpc);
235 if (!is8086 || !(prefetchpc&1)) cycles-=4;
236 prefetchpc++;
237 }
238 prefetchw=(is8086)?6:4;*/
239 // fetchcycles=0;
240 prefetchpc=pc;
241 prefetchw=0;
242 memcycs=cycdiff-cycles;
243 fetchclocks=0;
244 // memcycs=cycles;
245 /* prefetchqueue[0]=readmembf(cs+prefetchpc);
246 prefetchpc++;
247 prefetchw=1;
248 if (is8086 && prefetchpc&1)
249 {
250 prefetchqueue[1]=readmembf(cs+prefetchpc);
251 prefetchpc++;
252 }*/
253 }
255 static uint16_t getword()
256 {
257 uint8_t temp=FETCH();
258 return temp|(FETCH()<<8);
259 }
262 /*EA calculation*/
264 /*R/M - bits 0-2 - R/M bits 3-5 - Reg bits 6-7 - mod
265 From 386 programmers manual :
266 r8(/r) AL CL DL BL AH CH DH BH
267 r16(/r) AX CX DX BX SP BP SI DI
268 r32(/r) EAX ECX EDX EBX ESP EBP ESI EDI
269 /digit (Opcode) 0 1 2 3 4 5 6 7
270 REG = 000 001 010 011 100 101 110 111
271 ÚÄÄÄAddress
272 disp8 denotes an 8-bit displacement following the ModR/M byte, to be
273 sign-extended and added to the index. disp16 denotes a 16-bit displacement
274 following the ModR/M byte, to be added to the index. Default segment
275 register is SS for the effective addresses containing a BP index, DS for
276 other effective addresses.
277 ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄModR/M Values in HexadecimalÄÄÄÄÄÄÄÄ¿
279 [BX + SI] 000 00 08 10 18 20 28 30 38
280 [BX + DI] 001 01 09 11 19 21 29 31 39
281 [BP + SI] 010 02 0A 12 1A 22 2A 32 3A
282 [BP + DI] 011 03 0B 13 1B 23 2B 33 3B
283 [SI] 00 100 04 0C 14 1C 24 2C 34 3C
284 [DI] 101 05 0D 15 1D 25 2D 35 3D
285 disp16 110 06 0E 16 1E 26 2E 36 3E
286 [BX] 111 07 0F 17 1F 27 2F 37 3F
288 [BX+SI]+disp8 000 40 48 50 58 60 68 70 78
289 [BX+DI]+disp8 001 41 49 51 59 61 69 71 79
290 [BP+SI]+disp8 010 42 4A 52 5A 62 6A 72 7A
291 [BP+DI]+disp8 011 43 4B 53 5B 63 6B 73 7B
292 [SI]+disp8 01 100 44 4C 54 5C 64 6C 74 7C
293 [DI]+disp8 101 45 4D 55 5D 65 6D 75 7D
294 [BP]+disp8 110 46 4E 56 5E 66 6E 76 7E
295 [BX]+disp8 111 47 4F 57 5F 67 6F 77 7F
297 [BX+SI]+disp16 000 80 88 90 98 A0 A8 B0 B8
298 [BX+DI]+disp16 001 81 89 91 99 A1 A9 B1 B9
299 [BX+SI]+disp16 010 82 8A 92 9A A2 AA B2 BA
300 [BX+DI]+disp16 011 83 8B 93 9B A3 AB B3 BB
301 [SI]+disp16 10 100 84 8C 94 9C A4 AC B4 BC
302 [DI]+disp16 101 85 8D 95 9D A5 AD B5 BD
303 [BP]+disp16 110 86 8E 96 9E A6 AE B6 BE
304 [BX]+disp16 111 87 8F 97 9F A7 AF B7 BF
306 EAX/AX/AL 000 C0 C8 D0 D8 E0 E8 F0 F8
307 ECX/CX/CL 001 C1 C9 D1 D9 E1 E9 F1 F9
308 EDX/DX/DL 010 C2 CA D2 DA E2 EA F2 FA
309 EBX/BX/BL 011 C3 CB D3 DB E3 EB F3 FB
310 ESP/SP/AH 11 100 C4 CC D4 DC E4 EC F4 FC
311 EBP/BP/CH 101 C5 CD D5 DD E5 ED F5 FD
312 ESI/SI/DH 110 C6 CE D6 DE E6 EE F6 FE
313 EDI/DI/BH 111 C7 CF D7 DF E7 EF F7 FF
315 mod = 11 - register
316 10 - address + 16 bit displacement
317 01 - address + 8 bit displacement
318 00 - address
320 reg = If mod=11, (depending on data size, 16 bits/8 bits, 32 bits=extend 16 bit registers)
321 0=AX/AL 1=CX/CL 2=DX/DL 3=BX/BL
322 4=SP/AH 5=BP/CH 6=SI/DH 7=DI/BH
324 Otherwise, LSB selects SI/DI (0=SI), NMSB selects BX/BP (0=BX), and MSB
325 selects whether BX/BP are used at all (0=used).
327 mod=00 is an exception though
328 6=16 bit displacement only
329 7=[BX]
331 Usage varies with instructions.
333 MOV AL,BL has ModR/M as C3, for example.
334 mod=11, reg=0, r/m=3
335 MOV uses reg as dest, and r/m as src.
336 reg 0 is AL, reg 3 is BL
338 If BP or SP are in address calc, seg is SS, else DS
339 */
341 int cycles=0;
342 uint32_t easeg,eaaddr;
343 int rm,reg,mod,rmdat;
345 uint16_t zero=0;
346 uint16_t *mod1add[2][8];
347 uint32_t *mod1seg[8];
349 int slowrm[8];
351 void makemod1table()
352 {
353 mod1add[0][0]=&BX; mod1add[0][1]=&BX; mod1add[0][2]=&BP; mod1add[0][3]=&BP;
354 mod1add[0][4]=&SI; mod1add[0][5]=&DI; mod1add[0][6]=&BP; mod1add[0][7]=&BX;
355 mod1add[1][0]=&SI; mod1add[1][1]=&DI; mod1add[1][2]=&SI; mod1add[1][3]=&DI;
356 mod1add[1][4]=&zero; mod1add[1][5]=&zero; mod1add[1][6]=&zero; mod1add[1][7]=&zero;
357 slowrm[0]=0; slowrm[1]=1; slowrm[2]=1; slowrm[3]=0;
358 mod1seg[0]=&ds; mod1seg[1]=&ds; mod1seg[2]=&ss; mod1seg[3]=&ss;
359 mod1seg[4]=&ds; mod1seg[5]=&ds; mod1seg[6]=&ss; mod1seg[7]=&ds;
360 }
362 static void fetcheal()
363 {
364 if (!mod && rm==6) { eaaddr=getword(); easeg=ds; FETCHADD(6); }
365 else
366 {
367 switch (mod)
368 {
369 case 0:
370 eaaddr=0;
371 if (rm&4) FETCHADD(5);
372 else FETCHADD(7+slowrm[rm]);
373 break;
374 case 1:
375 eaaddr=(uint16_t)(int8_t)FETCH();
376 if (rm&4) FETCHADD(9);
377 else FETCHADD(11+slowrm[rm]);
378 break;
379 case 2:
380 eaaddr=getword();
381 if (rm&4) FETCHADD(9);
382 else FETCHADD(11+slowrm[rm]);
383 break;
384 }
385 eaaddr+=(*mod1add[0][rm])+(*mod1add[1][rm]);
386 easeg=*mod1seg[rm];
387 eaaddr&=0xFFFF;
388 }
389 }
391 static inline uint8_t geteab()
392 {
393 if (mod==3)
394 return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l;
395 return readmemb(easeg+eaaddr);
396 }
398 static inline uint16_t geteaw()
399 {
400 if (mod==3)
401 return regs[rm].w;
402 // if (output==3) printf("GETEAW %04X:%08X\n",easeg,eaaddr);
403 return readmemw(easeg,eaaddr);
404 }
406 static inline uint16_t geteaw2()
407 {
408 if (mod==3)
409 return regs[rm].w;
410 // printf("Getting addr from %04X:%04X %05X\n",easeg,eaaddr+2,easeg+eaaddr+2);
411 return readmemw(easeg,(eaaddr+2)&0xFFFF);
412 }
414 static inline void seteab(uint8_t val)
415 {
416 if (mod==3)
417 {
418 if (rm&4) regs[rm&3].b.h=val;
419 else regs[rm&3].b.l=val;
420 }
421 else
422 {
423 writememb(easeg+eaaddr,val);
424 }
425 }
427 static inline void seteaw(uint16_t val)
428 {
429 if (mod==3)
430 regs[rm].w=val;
431 else
432 {
433 writememw(easeg,eaaddr,val);
434 // writememb(easeg+eaaddr+1,val>>8);
435 }
436 }
438 #define getr8(r) ((r&4)?regs[r&3].b.h:regs[r&3].b.l)
440 #define setr8(r,v) if (r&4) regs[r&3].b.h=v; \
441 else regs[r&3].b.l=v;
444 /*Flags*/
445 uint8_t znptable8[256];
446 uint16_t znptable16[65536];
448 void makeznptable()
449 {
450 int c,d;
451 for (c=0;c<256;c++)
452 {
453 d=0;
454 if (c&1) d++;
455 if (c&2) d++;
456 if (c&4) d++;
457 if (c&8) d++;
458 if (c&16) d++;
459 if (c&32) d++;
460 if (c&64) d++;
461 if (c&128) d++;
462 if (d&1)
463 znptable8[c]=0;
464 else
465 znptable8[c]=P_FLAG;
466 if (c == 0xb1) pclog("znp8 b1 = %i %02X\n", d, znptable8[c]);
467 if (!c) znptable8[c]|=Z_FLAG;
468 if (c&0x80) znptable8[c]|=N_FLAG;
469 }
470 for (c=0;c<65536;c++)
471 {
472 d=0;
473 if (c&1) d++;
474 if (c&2) d++;
475 if (c&4) d++;
476 if (c&8) d++;
477 if (c&16) d++;
478 if (c&32) d++;
479 if (c&64) d++;
480 if (c&128) d++;
481 if (d&1)
482 znptable16[c]=0;
483 else
484 znptable16[c]=P_FLAG;
485 if (c == 0xb1) pclog("znp16 b1 = %i %02X\n", d, znptable16[c]);
486 if (c == 0x65b1) pclog("znp16 65b1 = %i %02X\n", d, znptable16[c]);
487 if (!c) znptable16[c]|=Z_FLAG;
488 if (c&0x8000) znptable16[c]|=N_FLAG;
489 }
491 // makemod1table();
492 }
493 int timetolive=0;
495 extern uint32_t oldcs2;
496 extern uint32_t oldpc2;
498 int indump = 0;
500 void dumpregs()
501 {
502 int c,d=0,e=0,ff;
503 #ifndef RELEASE_BUILD
504 FILE *f;
505 if (indump) return;
506 indump = 1;
507 // return;
508 output=0;
509 // return;
510 // savenvr();
511 // return;
512 chdir(pcempath);
513 nopageerrors=1;
514 /* f=fopen("rram3.dmp","wb");
515 for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f);
516 fclose(f);*/
517 f=fopen("ram.dmp","wb");
518 fwrite(ram,mem_size*1024*1024,1,f);
519 fclose(f);
520 /* pclog("Dumping rram5.dmp\n");
521 f=fopen("rram5.dmp","wb");
522 for (c=0;c<0x1000000;c++) putc(readmemb(c+0x10150000),f);
523 fclose(f);*/
524 pclog("Dumping rram.dmp\n");
525 f=fopen("rram.dmp","wb");
526 for (c=0;c<0x1000000;c++) putc(readmemb(c),f);
527 fclose(f);
528 /* f=fopen("rram2.dmp","wb");
529 for (c=0;c<0x100000;c++) putc(readmemb(c+0xbff00000),f);
530 fclose(f);
531 f = fopen("stack.dmp","wb");
532 for (c = 0; c < 0x6000; c++) putc(readmemb(c+0xFFDFA000), f);
533 fclose(f);
534 f = fopen("tempx.dmp","wb");
535 for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFC816000), f);
536 fclose(f);
537 f = fopen("tempx2.dmp","wb");
538 for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFDEF5000), f);
539 fclose(f);*/
540 pclog("Dumping rram4.dmp\n");
541 f=fopen("rram4.dmp","wb");
542 for (c=0;c<0x0050000;c++)
543 {
544 abrt = 0;
545 putc(readmemb386l(0,c+0x80000000),f);
546 }
547 fclose(f);
548 pclog("Dumping done\n");
549 /* f=fopen("rram6.dmp","wb");
550 for (c=0;c<0x1000000;c++) putc(readmemb(c+0xBF000000),f);
551 fclose(f);*/
552 /* f=fopen("ram6.bin","wb");
553 fwrite(ram+0x10100,0xA000,1,f);
554 fclose(f);
555 f=fopen("boot.bin","wb");
556 fwrite(ram+0x7C00,0x200,1,f);
557 fclose(f);
558 f=fopen("ram7.bin","wb");
559 fwrite(ram+0x11100,0x2000,1,f);
560 fclose(f);
561 f=fopen("ram8.bin","wb");
562 fwrite(ram+0x3D210,0x200,1,f);
563 fclose(f); */
564 /* f=fopen("bios.dmp","wb");
565 fwrite(rom,0x20000,1,f);
566 fclose(f);*/
567 /* f=fopen("kernel.dmp","wb");
568 for (c=0;c<0x200000;c++) putc(readmemb(c+0xC0000000),f);
569 fclose(f);*/
570 /* f=fopen("rram.dmp","wb");
571 for (c=0;c<0x1500000;c++) putc(readmemb(c),f);
572 fclose(f);
573 if (!times)
574 {
575 f=fopen("thing.dmp","wb");
576 fwrite(ram+0x11E50,0x1000,1,f);
577 fclose(f);
578 }*/
579 #endif
580 if (is386)
581 printf("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",EAX,EBX,ECX,EDX,EDI,ESI,EBP,ESP);
582 else
583 printf("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP);
584 printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",pc,CS,DS,ES,SS,flags);
585 printf("%04X:%04X %04X:%04X\n",oldcs,oldpc, oldcs2, oldpc2);
586 printf("%i ins\n",ins);
587 if (is386)
588 printf("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real");
589 else
590 printf("In %s mode\n",(msw&1)?"protected":"real");
591 printf("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",cs,_cs.limit,_cs.access, _cs.limit_low, _cs.limit_high);
592 printf("DS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ds,_ds.limit,_ds.access, _ds.limit_low, _ds.limit_high);
593 printf("ES : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",es,_es.limit,_es.access, _es.limit_low, _es.limit_high);
594 if (is386)
595 {
596 printf("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",fs,_fs.limit,_fs.access, _fs.limit_low, _fs.limit_high);
597 printf("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",gs,_gs.limit,_gs.access, _gs.limit_low, _gs.limit_high);
598 }
599 printf("SS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ss,_ss.limit,_ss.access, _ss.limit_low, _ss.limit_high);
600 printf("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit);
601 printf("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit);
602 printf("IDT : base=%06X limit=%04X\n",idt.base,idt.limit);
603 printf("TR : base=%06X limit=%04X\n", tr.base, tr.limit);
604 if (is386)
605 {
606 printf("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit");
607 printf("CR0=%08X CR2=%08X CR3=%08X\n",cr0,cr2,cr3);
608 }
609 printf("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum);
610 for (c=0;c<1024*1024;c++)
611 {
612 if (readlookup2[c]!=0xFFFFFFFF) d++;
613 if (writelookup2[c]!=0xFFFFFFFF) e++;
614 }
615 printf("Entries in readlookup : %i writelookup : %i\n",d,e);
616 x87_dumpregs();
617 indump = 0;
618 }
620 int resets = 0;
621 void resetx86()
622 {
623 pclog("x86 reset\n");
624 resets++;
625 ins = 0;
626 use32=0;
627 stack32=0;
628 // i86_Reset();
629 // cs=0xFFFF0;
630 pc=0;
631 msw=0;
632 cr0=0;
633 cr4 = 0;
634 eflags=0;
635 cgate32=0;
636 loadcs(0xFFFF);
637 rammask=0xFFFFFFFF;
638 idt.base = 0;
639 flags=2;
640 makeznptable();
641 resetreadlookup();
642 makemod1table();
643 resetmcr();
644 FETCHCLEAR();
645 x87_reset();
646 cpu_set_edx();
647 ESP=0;
648 mmu_perm=4;
649 memset(inscounts, 0, sizeof(inscounts));
650 x86seg_reset();
651 }
653 void softresetx86()
654 {
655 // dumpregs();
656 // exit(-1);
657 use32=0;
658 stack32=0;
659 // i86_Reset();
660 // cs=0xFFFF0;
661 pc=0;
662 msw=0;
663 cr0=0;
664 cr4 = 0;
665 eflags=0;
666 cgate32=0;
667 loadcs(0xFFFF);
668 //rammask=0xFFFFFFFF;
669 flags=2;
670 idt.base = 0;
671 x86seg_reset();
672 }
674 static void setznp8(uint8_t val)
675 {
676 flags&=~0xC4;
677 flags|=znptable8[val];
678 }
680 static void setznp16(uint16_t val)
681 {
682 flags&=~0xC4;
683 flags|=znptable16[val];
684 }
686 static void setadd8(uint8_t a, uint8_t b)
687 {
688 uint16_t c=(uint16_t)a+(uint16_t)b;
689 flags&=~0x8D5;
690 flags|=znptable8[c&0xFF];
691 if (c&0x100) flags|=C_FLAG;
692 if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
693 if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
694 }
695 static void setadd8nc(uint8_t a, uint8_t b)
696 {
697 uint16_t c=(uint16_t)a+(uint16_t)b;
698 flags&=~0x8D4;
699 flags|=znptable8[c&0xFF];
700 if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
701 if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
702 }
703 static void setadc8(uint8_t a, uint8_t b)
704 {
705 uint16_t c=(uint16_t)a+(uint16_t)b+tempc;
706 flags&=~0x8D5;
707 flags|=znptable8[c&0xFF];
708 if (c&0x100) flags|=C_FLAG;
709 if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
710 if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
711 }
712 static void setadd16(uint16_t a, uint16_t b)
713 {
714 uint32_t c=(uint32_t)a+(uint32_t)b;
715 flags&=~0x8D5;
716 flags|=znptable16[c&0xFFFF];
717 if (c&0x10000) flags|=C_FLAG;
718 if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
719 if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
720 }
721 static void setadd16nc(uint16_t a, uint16_t b)
722 {
723 uint32_t c=(uint32_t)a+(uint32_t)b;
724 flags&=~0x8D4;
725 flags|=znptable16[c&0xFFFF];
726 if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
727 if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
728 }
729 static void setadc16(uint16_t a, uint16_t b)
730 {
731 uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
732 flags&=~0x8D5;
733 flags|=znptable16[c&0xFFFF];
734 if (c&0x10000) flags|=C_FLAG;
735 if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
736 if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
737 }
739 static void setsub8(uint8_t a, uint8_t b)
740 {
741 uint16_t c=(uint16_t)a-(uint16_t)b;
742 flags&=~0x8D5;
743 flags|=znptable8[c&0xFF];
744 if (c&0x100) flags|=C_FLAG;
745 if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
746 if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
747 }
748 static void setsub8nc(uint8_t a, uint8_t b)
749 {
750 uint16_t c=(uint16_t)a-(uint16_t)b;
751 flags&=~0x8D4;
752 flags|=znptable8[c&0xFF];
753 if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
754 if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
755 }
756 static void setsbc8(uint8_t a, uint8_t b)
757 {
758 uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc);
759 flags&=~0x8D5;
760 flags|=znptable8[c&0xFF];
761 if (c&0x100) flags|=C_FLAG;
762 if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
763 if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
764 }
765 static void setsub16(uint16_t a, uint16_t b)
766 {
767 uint32_t c=(uint32_t)a-(uint32_t)b;
768 flags&=~0x8D5;
769 flags|=znptable16[c&0xFFFF];
770 if (c&0x10000) flags|=C_FLAG;
771 if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
772 // if (output) printf("%04X %04X %i\n",a^b,a^c,flags&V_FLAG);
773 if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
774 }
775 static void setsub16nc(uint16_t a, uint16_t b)
776 {
777 uint32_t c=(uint32_t)a-(uint32_t)b;
778 flags&=~0x8D4;
779 flags|=(znptable16[c&0xFFFF]&~4);
780 flags|=(znptable8[c&0xFF]&4);
781 if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
782 if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
783 }
784 static void setsbc16(uint16_t a, uint16_t b)
785 {
786 uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
787 flags&=~0x8D5;
788 flags|=(znptable16[c&0xFFFF]&~4);
789 flags|=(znptable8[c&0xFF]&4);
790 if (c&0x10000) flags|=C_FLAG;
791 if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
792 if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
793 }
795 int current_diff = 0;
796 void clockhardware()
797 {
798 int diff = cycdiff - cycles - current_diff;
800 current_diff += diff;
801 if (pit.running[0]) pit.c[0] -= diff;
802 if (pit.running[1]) pit.c[1] -= diff;
803 if (pit.running[2]) pit.c[2] -= diff;
804 if ((pit.c[0] < 1) || (pit.c[1] < 1) || (pit.c[2] < 1)) pit_poll();
806 timer_end_period(cycles);
807 }
809 static int takeint = 0;
812 int firstrepcycle=1;
814 void rep(int fv)
815 {
816 uint8_t temp;
817 int c=CX;
818 uint8_t temp2;
819 uint16_t tempw,tempw2;
820 uint16_t ipc=oldpc;//pc-1;
821 int changeds=0;
822 uint32_t oldds;
823 startrep:
824 temp=FETCH();
826 // if (firstrepcycle && temp==0xA5) printf("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI);
827 // if (output) printf("REP %02X %04X\n",temp,ipc);
828 switch (temp)
829 {
830 case 0x08:
831 pc=ipc+1;
832 cycles-=2;
833 FETCHCLEAR();
834 break;
835 case 0x26: /*ES:*/
836 oldds=ds;
837 ds=es;
838 changeds=1;
839 cycles-=2;
840 goto startrep;
841 break;
842 case 0x2E: /*CS:*/
843 oldds=ds;
844 ds=cs;
845 changeds=1;
846 cycles-=2;
847 goto startrep;
848 break;
849 case 0x36: /*SS:*/
850 oldds=ds;
851 ds=ss;
852 changeds=1;
853 cycles-=2;
854 goto startrep;
855 break;
856 case 0x6E: /*REP OUTSB*/
857 if (c>0)
858 {
859 temp2=readmemb(ds+SI);
860 outb(DX,temp2);
861 if (flags&D_FLAG) SI--;
862 else SI++;
863 c--;
864 cycles-=5;
865 }
866 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
867 else firstrepcycle=1;
868 break;
869 case 0xA4: /*REP MOVSB*/
870 while (c>0 && !IRQTEST)
871 {
872 temp2=readmemb(ds+SI);
873 writememb(es+DI,temp2);
874 // if (output) printf("Moved %02X from %04X:%04X to %04X:%04X\n",temp2,ds>>4,SI,es>>4,DI);
875 if (flags&D_FLAG) { DI--; SI--; }
876 else { DI++; SI++; }
877 c--;
878 cycles-=17;
879 clockhardware();
880 FETCHADD(17-memcycs);
881 }
882 if (IRQTEST && c>0) pc=ipc;
883 // if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
884 // else firstrepcycle=1;
885 // }
886 break;
887 case 0xA5: /*REP MOVSW*/
888 while (c>0 && !IRQTEST)
889 {
890 memcycs=0;
891 tempw=readmemw(ds,SI);
892 writememw(es,DI,tempw);
893 if (flags&D_FLAG) { DI-=2; SI-=2; }
894 else { DI+=2; SI+=2; }
895 c--;
896 cycles-=17;
897 clockhardware();
898 FETCHADD(17 - memcycs);
899 }
900 if (IRQTEST && c>0) pc=ipc;
901 // if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
902 // else firstrepcycle=1;
903 // }
904 break;
905 case 0xA6: /*REP CMPSB*/
906 if (fv) flags|=Z_FLAG;
907 else flags&=~Z_FLAG;
908 while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST)
909 {
910 memcycs=0;
911 temp=readmemb(ds+SI);
912 temp2=readmemb(es+DI);
913 // printf("CMPSB %c %c %i %05X %05X %04X:%04X\n",temp,temp2,c,ds+SI,es+DI,cs>>4,pc);
914 if (flags&D_FLAG) { DI--; SI--; }
915 else { DI++; SI++; }
916 c--;
917 cycles -= 30;
918 setsub8(temp,temp2);
919 clockhardware();
920 FETCHADD(30 - memcycs);
921 }
922 if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) pc=ipc;
923 // if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
924 // else firstrepcycle=1;
925 break;
926 case 0xA7: /*REP CMPSW*/
927 if (fv) flags|=Z_FLAG;
928 else flags&=~Z_FLAG;
929 while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST)
930 {
931 memcycs=0;
932 tempw=readmemw(ds,SI);
933 tempw2=readmemw(es,DI);
934 if (flags&D_FLAG) { DI-=2; SI-=2; }
935 else { DI+=2; SI+=2; }
936 c--;
937 cycles -= 30;
938 setsub16(tempw,tempw2);
939 clockhardware();
940 FETCHADD(30 - memcycs);
941 }
942 if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) pc=ipc;
943 // if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
944 // else firstrepcycle=1;
945 // if (firstrepcycle) printf("REP CMPSW %06X:%04X %06X:%04X %04X %04X\n",ds,SI,es,DI,tempw,tempw2);
946 break;
947 case 0xAA: /*REP STOSB*/
948 while (c>0 && !IRQTEST)
949 {
950 memcycs=0;
951 writememb(es+DI,AL);
952 if (flags&D_FLAG) DI--;
953 else DI++;
954 c--;
955 cycles -= 10;
956 clockhardware();
957 FETCHADD(10 - memcycs);
958 }
959 if (IRQTEST && c>0) pc=ipc;
960 // if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
961 // else firstrepcycle=1;
962 break;
963 case 0xAB: /*REP STOSW*/
964 while (c>0 && !IRQTEST)
965 {
966 memcycs=0;
967 writememw(es,DI,AX);
968 if (flags&D_FLAG) DI-=2;
969 else DI+=2;
970 c--;
971 cycles -= 10;
972 clockhardware();
973 FETCHADD(10 - memcycs);
974 }
975 if (IRQTEST && c>0) pc=ipc;
976 // if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
977 // else firstrepcycle=1;
978 break;
979 case 0xAC: /*REP LODSB*/
980 if (c>0)
981 {
982 temp2=readmemb(ds+SI);
983 if (flags&D_FLAG) SI--;
984 else SI++;
985 c--;
986 cycles-=4;
987 }
988 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
989 else firstrepcycle=1;
990 break;
991 case 0xAD: /*REP LODSW*/
992 if (c>0)
993 {
994 tempw2=readmemw(ds,SI);
995 if (flags&D_FLAG) SI-=2;
996 else SI+=2;
997 c--;
998 cycles-=4;
999 }
1000 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
1001 else firstrepcycle=1;
1002 break;
1003 case 0xAE: /*REP SCASB*/
1004 if (fv) flags|=Z_FLAG;
1005 else flags&=~Z_FLAG;
1006 if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))
1007 {
1008 temp2=readmemb(es+DI);
1009 // if (output) printf("SCASB %02X %c %02X %05X ",temp2,temp2,AL,es+DI);
1010 setsub8(AL,temp2);
1011 // if (output && flags&Z_FLAG) printf("Match %02X %02X\n",AL,temp2);
1012 if (flags&D_FLAG) DI--;
1013 else DI++;
1014 c--;
1015 cycles -= 15;
1016 }
1017 //if (output) printf("%i %i %i %i\n",c,(c>0),(fv==((flags&Z_FLAG)?1:0)),((c>0) && (fv==((flags&Z_FLAG)?1:0))));
1018 if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
1019 else firstrepcycle=1;
1020 // cycles-=120;
1021 break;
1022 case 0xAF: /*REP SCASW*/
1023 if (fv) flags|=Z_FLAG;
1024 else flags&=~Z_FLAG;
1025 if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))
1026 {
1027 tempw=readmemw(es,DI);
1028 setsub16(AX,tempw);
1029 if (flags&D_FLAG) DI-=2;
1030 else DI+=2;
1031 c--;
1032 cycles -= 15;
1033 }
1034 if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
1035 else firstrepcycle=1;
1036 break;
1037 default:
1038 pc=ipc;
1039 cycles-=20;
1040 FETCHCLEAR();
1041 // printf("Bad REP %02X\n",temp);
1042 // dumpregs();
1043 // exit(-1);
1044 }
1045 CX=c;
1046 if (changeds) ds=oldds;
1047 if (IRQTEST)
1048 takeint = 1;
1049 // if (pc==ipc) FETCHCLEAR();
1050 }
1053 int inhlt=0;
1054 uint16_t lastpc,lastcs;
1055 int firstrepcycle;
1056 int skipnextprint=0;
1058 int instime=0;
1059 //#if 0
1060 void execx86(int cycs)
1061 {
1062 uint8_t temp,temp2;
1063 uint16_t addr,tempw,tempw2,tempw3,tempw4;
1064 int8_t offset;
1065 int tempws;
1066 uint32_t templ;
1067 int c;
1068 int tempi;
1069 int trap;
1071 // printf("Run x86! %i %i\n",cycles,cycs);
1072 cycles+=cycs;
1073 // i86_Execute(cycs);
1074 // return;
1075 while (cycles>0)
1076 {
1077 // old83=old82;
1078 // old82=old8;
1079 // old8=oldpc|(oldcs<<16);
1080 // if (pc==0x96B && cs==0x9E040) { printf("Hit it\n"); output=1; timetolive=150; }
1081 // if (pc<0x8000) printf("%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i\n",pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags,disctime);
1082 cycdiff=cycles;
1083 timer_start_period(cycles);
1084 current_diff = 0;
1085 cycles-=nextcyc;
1086 // if (instime) pclog("Cycles %i %i\n",cycles,cycdiff);
1087 nextcyc=0;
1088 // if (output) printf("CLOCK %i %i\n",cycdiff,cycles);
1089 fetchclocks=0;
1090 oldcs=CS;
1091 oldpc=pc;
1092 opcodestart:
1093 opcode=FETCH();
1094 tempc=flags&C_FLAG;
1095 trap=flags&T_FLAG;
1096 pc--;
1097 // output=1;
1098 // if (output) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X\n",cs>>4,pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags&~0x200,rmdat);
1099 //#if 0
1100 if (output)
1101 {
1102 // if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle)
1103 // {
1104 if (!skipnextprint) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i %p %02X\n",cs,pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ins, ram, ram[0x1a925]);
1105 skipnextprint=0;
1106 // ins++;
1107 // }
1108 }
1109 //#endif
1110 pc++;
1111 inhlt=0;
1112 // if (ins==500000) { dumpregs(); exit(0); }*/
1113 switch (opcode)
1114 {
1115 case 0x00: /*ADD 8,reg*/
1116 fetchea();
1117 /* if (!rmdat) pc--;
1118 if (!rmdat)
1119 {
1120 fatal("Crashed\n");
1121 // clear_keybuf();
1122 // readkey();
1123 }*/
1124 temp=geteab();
1125 setadd8(temp,getr8(reg));
1126 temp+=getr8(reg);
1127 seteab(temp);
1128 cycles-=((mod==3)?3:24);
1129 break;
1130 case 0x01: /*ADD 16,reg*/
1131 fetchea();
1132 tempw=geteaw();
1133 setadd16(tempw,regs[reg].w);
1134 tempw+=regs[reg].w;
1135 seteaw(tempw);
1136 cycles-=((mod==3)?3:24);
1137 break;
1138 case 0x02: /*ADD reg,8*/
1139 fetchea();
1140 temp=geteab();
1141 setadd8(getr8(reg),temp);
1142 setr8(reg,getr8(reg)+temp);
1143 cycles-=((mod==3)?3:13);
1144 break;
1145 case 0x03: /*ADD reg,16*/
1146 fetchea();
1147 tempw=geteaw();
1148 setadd16(regs[reg].w,tempw);
1149 regs[reg].w+=tempw;
1150 cycles-=((mod==3)?3:13);
1151 break;
1152 case 0x04: /*ADD AL,#8*/
1153 temp=FETCH();
1154 setadd8(AL,temp);
1155 AL+=temp;
1156 cycles-=4;
1157 break;
1158 case 0x05: /*ADD AX,#16*/
1159 tempw=getword();
1160 setadd16(AX,tempw);
1161 AX+=tempw;
1162 cycles-=4;
1163 break;
1165 case 0x06: /*PUSH ES*/
1166 if (ssegs) ss=oldss;
1167 writememw(ss,((SP-2)&0xFFFF),ES);
1168 SP-=2;
1169 cycles-=14;
1170 break;
1171 case 0x07: /*POP ES*/
1172 if (ssegs) ss=oldss;
1173 tempw=readmemw(ss,SP);
1174 loadseg(tempw,&_es);
1175 SP+=2;
1176 cycles-=12;
1177 break;
1179 case 0x08: /*OR 8,reg*/
1180 fetchea();
1181 temp=geteab();
1182 temp|=getr8(reg);
1183 setznp8(temp);
1184 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1185 seteab(temp);
1186 cycles-=((mod==3)?3:24);
1187 break;
1188 case 0x09: /*OR 16,reg*/
1189 fetchea();
1190 tempw=geteaw();
1191 tempw|=regs[reg].w;
1192 setznp16(tempw);
1193 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1194 seteaw(tempw);
1195 cycles-=((mod==3)?3:24);
1196 break;
1197 case 0x0A: /*OR reg,8*/
1198 fetchea();
1199 temp=geteab();
1200 temp|=getr8(reg);
1201 setznp8(temp);
1202 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1203 setr8(reg,temp);
1204 cycles-=((mod==3)?3:13);
1205 break;
1206 case 0x0B: /*OR reg,16*/
1207 fetchea();
1208 tempw=geteaw();
1209 tempw|=regs[reg].w;
1210 setznp16(tempw);
1211 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1212 regs[reg].w=tempw;
1213 cycles-=((mod==3)?3:13);
1214 break;
1215 case 0x0C: /*OR AL,#8*/
1216 AL|=FETCH();
1217 setznp8(AL);
1218 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1219 cycles-=4;
1220 break;
1221 case 0x0D: /*OR AX,#16*/
1222 AX|=getword();
1223 setznp16(AX);
1224 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1225 cycles-=4;
1226 break;
1228 case 0x0E: /*PUSH CS*/
1229 if (ssegs) ss=oldss;
1230 writememw(ss,((SP-2)&0xFFFF),CS);
1231 SP-=2;
1232 cycles-=14;
1233 break;
1234 case 0x0F: /*POP CS - 8088/8086 only*/
1235 if (ssegs) ss=oldss;
1236 tempw=readmemw(ss,SP);
1237 loadseg(tempw,&_cs);
1238 SP+=2;
1239 cycles-=12;
1240 break;
1242 case 0x10: /*ADC 8,reg*/
1243 fetchea();
1244 temp=geteab();
1245 temp2=getr8(reg);
1246 setadc8(temp,temp2);
1247 temp+=temp2+tempc;
1248 seteab(temp);
1249 cycles-=((mod==3)?3:24);
1250 break;
1251 case 0x11: /*ADC 16,reg*/
1252 fetchea();
1253 tempw=geteaw();
1254 tempw2=regs[reg].w;
1255 setadc16(tempw,tempw2);
1256 tempw+=tempw2+tempc;
1257 seteaw(tempw);
1258 cycles-=((mod==3)?3:24);
1259 break;
1260 case 0x12: /*ADC reg,8*/
1261 fetchea();
1262 temp=geteab();
1263 setadc8(getr8(reg),temp);
1264 setr8(reg,getr8(reg)+temp+tempc);
1265 cycles-=((mod==3)?3:13);
1266 break;
1267 case 0x13: /*ADC reg,16*/
1268 fetchea();
1269 tempw=geteaw();
1270 setadc16(regs[reg].w,tempw);
1271 regs[reg].w+=tempw+tempc;
1272 cycles-=((mod==3)?3:13);
1273 break;
1274 case 0x14: /*ADC AL,#8*/
1275 tempw=FETCH();
1276 setadc8(AL,tempw);
1277 AL+=tempw+tempc;
1278 cycles-=4;
1279 break;
1280 case 0x15: /*ADC AX,#16*/
1281 tempw=getword();
1282 setadc16(AX,tempw);
1283 AX+=tempw+tempc;
1284 cycles-=4;
1285 break;
1287 case 0x16: /*PUSH SS*/
1288 if (ssegs) ss=oldss;
1289 writememw(ss,((SP-2)&0xFFFF),SS);
1290 SP-=2;
1291 cycles-=14;
1292 break;
1293 case 0x17: /*POP SS*/
1294 if (ssegs) ss=oldss;
1295 tempw=readmemw(ss,SP);
1296 loadseg(tempw,&_ss);
1297 SP+=2;
1298 noint=1;
1299 cycles-=12;
1300 // output=1;
1301 break;
1303 case 0x18: /*SBB 8,reg*/
1304 fetchea();
1305 temp=geteab();
1306 temp2=getr8(reg);
1307 setsbc8(temp,temp2);
1308 temp-=(temp2+tempc);
1309 seteab(temp);
1310 cycles-=((mod==3)?3:24);
1311 break;
1312 case 0x19: /*SBB 16,reg*/
1313 fetchea();
1314 tempw=geteaw();
1315 tempw2=regs[reg].w;
1316 // printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc);
1317 setsbc16(tempw,tempw2);
1318 tempw-=(tempw2+tempc);
1319 seteaw(tempw);
1320 cycles-=((mod==3)?3:24);
1321 break;
1322 case 0x1A: /*SBB reg,8*/
1323 fetchea();
1324 temp=geteab();
1325 setsbc8(getr8(reg),temp);
1326 setr8(reg,getr8(reg)-(temp+tempc));
1327 cycles-=((mod==3)?3:13);
1328 break;
1329 case 0x1B: /*SBB reg,16*/
1330 fetchea();
1331 tempw=geteaw();
1332 tempw2=regs[reg].w;
1333 // printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc);
1334 setsbc16(tempw2,tempw);
1335 tempw2-=(tempw+tempc);
1336 regs[reg].w=tempw2;
1337 cycles-=((mod==3)?3:13);
1338 break;
1339 case 0x1C: /*SBB AL,#8*/
1340 temp=FETCH();
1341 setsbc8(AL,temp);
1342 AL-=(temp+tempc);
1343 cycles-=4;
1344 break;
1345 case 0x1D: /*SBB AX,#16*/
1346 tempw=getword();
1347 setsbc16(AX,tempw);
1348 AX-=(tempw+tempc);
1349 cycles-=4;
1350 break;
1352 case 0x1E: /*PUSH DS*/
1353 if (ssegs) ss=oldss;
1354 writememw(ss,((SP-2)&0xFFFF),DS);
1355 SP-=2;
1356 cycles-=14;
1357 break;
1358 case 0x1F: /*POP DS*/
1359 if (ssegs) ss=oldss;
1360 tempw=readmemw(ss,SP);
1361 loadseg(tempw,&_ds);
1362 if (ssegs) oldds=ds;
1363 SP+=2;
1364 cycles-=12;
1365 break;
1367 case 0x20: /*AND 8,reg*/
1368 fetchea();
1369 temp=geteab();
1370 temp&=getr8(reg);
1371 setznp8(temp);
1372 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1373 seteab(temp);
1374 cycles-=((mod==3)?3:24);
1375 break;
1376 case 0x21: /*AND 16,reg*/
1377 fetchea();
1378 tempw=geteaw();
1379 tempw&=regs[reg].w;
1380 setznp16(tempw);
1381 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1382 seteaw(tempw);
1383 cycles-=((mod==3)?3:24);
1384 break;
1385 case 0x22: /*AND reg,8*/
1386 fetchea();
1387 temp=geteab();
1388 temp&=getr8(reg);
1389 setznp8(temp);
1390 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1391 setr8(reg,temp);
1392 cycles-=((mod==3)?3:13);
1393 break;
1394 case 0x23: /*AND reg,16*/
1395 fetchea();
1396 tempw=geteaw();
1397 tempw&=regs[reg].w;
1398 setznp16(tempw);
1399 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1400 regs[reg].w=tempw;
1401 cycles-=((mod==3)?3:13);
1402 break;
1403 case 0x24: /*AND AL,#8*/
1404 AL&=FETCH();
1405 setznp8(AL);
1406 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1407 cycles-=4;
1408 break;
1409 case 0x25: /*AND AX,#16*/
1410 AX&=getword();
1411 setznp16(AX);
1412 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1413 cycles-=4;
1414 break;
1416 case 0x26: /*ES:*/
1417 oldss=ss;
1418 oldds=ds;
1419 ds=ss=es;
1420 ssegs=2;
1421 cycles-=4;
1422 goto opcodestart;
1423 // break;
1425 case 0x27: /*DAA*/
1426 if ((flags&A_FLAG) || ((AL&0xF)>9))
1427 {
1428 tempi=((uint16_t)AL)+6;
1429 AL+=6;
1430 flags|=A_FLAG;
1431 if (tempi&0x100) flags|=C_FLAG;
1432 }
1433 // else
1434 // flags&=~A_FLAG;
1435 if ((flags&C_FLAG) || (AL>0x9F))
1436 {
1437 AL+=0x60;
1438 flags|=C_FLAG;
1439 }
1440 // else
1441 // flags&=~C_FLAG;
1442 setznp8(AL);
1443 cycles-=4;
1444 break;
1446 case 0x28: /*SUB 8,reg*/
1447 fetchea();
1448 temp=geteab();
1449 setsub8(temp,getr8(reg));
1450 temp-=getr8(reg);
1451 seteab(temp);
1452 cycles-=((mod==3)?3:24);
1453 break;
1454 case 0x29: /*SUB 16,reg*/
1455 fetchea();
1456 tempw=geteaw();
1457 // printf("%04X:%04X %04X-%04X\n",cs>>4,pc,tempw,regs[reg].w);
1458 setsub16(tempw,regs[reg].w);
1459 tempw-=regs[reg].w;
1460 seteaw(tempw);
1461 cycles-=((mod==3)?3:24);
1462 break;
1463 case 0x2A: /*SUB reg,8*/
1464 fetchea();
1465 temp=geteab();
1466 setsub8(getr8(reg),temp);
1467 setr8(reg,getr8(reg)-temp);
1468 cycles-=((mod==3)?3:13);
1469 break;
1470 case 0x2B: /*SUB reg,16*/
1471 fetchea();
1472 tempw=geteaw();
1473 // printf("%04X:%04X %04X-%04X\n",cs>>4,pc,regs[reg].w,tempw);
1474 setsub16(regs[reg].w,tempw);
1475 regs[reg].w-=tempw;
1476 cycles-=((mod==3)?3:13);
1477 break;
1478 case 0x2C: /*SUB AL,#8*/
1479 temp=FETCH();
1480 setsub8(AL,temp);
1481 AL-=temp;
1482 cycles-=4;
1483 break;
1484 case 0x2D: /*SUB AX,#16*/
1485 // printf("INS %i\n",ins);
1486 // output=1;
1487 tempw=getword();
1488 setsub16(AX,tempw);
1489 AX-=tempw;
1490 cycles-=4;
1491 break;
1492 case 0x2E: /*CS:*/
1493 oldss=ss;
1494 oldds=ds;
1495 ds=ss=cs;
1496 ssegs=2;
1497 cycles-=4;
1498 goto opcodestart;
1499 case 0x2F: /*DAS*/
1500 if ((flags&A_FLAG)||((AL&0xF)>9))
1501 {
1502 tempi=((uint16_t)AL)-6;
1503 AL-=6;
1504 flags|=A_FLAG;
1505 if (tempi&0x100) flags|=C_FLAG;
1506 }
1507 // else
1508 // flags&=~A_FLAG;
1509 if ((flags&C_FLAG)||(AL>0x9F))
1510 {
1511 AL-=0x60;
1512 flags|=C_FLAG;
1513 }
1514 // else
1515 // flags&=~C_FLAG;
1516 setznp8(AL);
1517 cycles-=4;
1518 break;
1519 case 0x30: /*XOR 8,reg*/
1520 fetchea();
1521 temp=geteab();
1522 temp^=getr8(reg);
1523 setznp8(temp);
1524 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1525 seteab(temp);
1526 cycles-=((mod==3)?3:24);
1527 break;
1528 case 0x31: /*XOR 16,reg*/
1529 fetchea();
1530 tempw=geteaw();
1531 tempw^=regs[reg].w;
1532 setznp16(tempw);
1533 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1534 seteaw(tempw);
1535 cycles-=((mod==3)?3:24);
1536 break;
1537 case 0x32: /*XOR reg,8*/
1538 fetchea();
1539 temp=geteab();
1540 temp^=getr8(reg);
1541 setznp8(temp);
1542 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1543 setr8(reg,temp);
1544 cycles-=((mod==3)?3:13);
1545 break;
1546 case 0x33: /*XOR reg,16*/
1547 fetchea();
1548 tempw=geteaw();
1549 tempw^=regs[reg].w;
1550 setznp16(tempw);
1551 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1552 regs[reg].w=tempw;
1553 cycles-=((mod==3)?3:13);
1554 break;
1555 case 0x34: /*XOR AL,#8*/
1556 AL^=FETCH();
1557 setznp8(AL);
1558 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1559 cycles-=4;
1560 break;
1561 case 0x35: /*XOR AX,#16*/
1562 AX^=getword();
1563 setznp16(AX);
1564 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1565 cycles-=4;
1566 break;
1568 case 0x36: /*SS:*/
1569 oldss=ss;
1570 oldds=ds;
1571 ds=ss=ss;
1572 ssegs=2;
1573 cycles-=4;
1574 goto opcodestart;
1575 // break;
1577 case 0x37: /*AAA*/
1578 if ((flags&A_FLAG)||((AL&0xF)>9))
1579 {
1580 AL+=6;
1581 AH++;
1582 flags|=(A_FLAG|C_FLAG);
1583 }
1584 else
1585 flags&=~(A_FLAG|C_FLAG);
1586 AL&=0xF;
1587 cycles-=8;
1588 break;
1590 case 0x38: /*CMP 8,reg*/
1591 fetchea();
1592 temp=geteab();
1593 // if (output) printf("CMP %02X-%02X\n",temp,getr8(reg));
1594 setsub8(temp,getr8(reg));
1595 cycles-=((mod==3)?3:13);
1596 break;
1597 case 0x39: /*CMP 16,reg*/
1598 fetchea();
1599 tempw=geteaw();
1600 // if (output) printf("CMP %04X-%04X\n",tempw,regs[reg].w);
1601 setsub16(tempw,regs[reg].w);
1602 cycles-=((mod==3)?3:13);
1603 break;
1604 case 0x3A: /*CMP reg,8*/
1605 fetchea();
1606 temp=geteab();
1607 // if (output) printf("CMP %02X-%02X\n",getr8(reg),temp);
1608 setsub8(getr8(reg),temp);
1609 cycles-=((mod==3)?3:13);
1610 break;
1611 case 0x3B: /*CMP reg,16*/
1612 fetchea();
1613 tempw=geteaw();
1614 // printf("CMP %04X-%04X\n",regs[reg].w,tempw);
1615 setsub16(regs[reg].w,tempw);
1616 cycles-=((mod==3)?3:13);
1617 break;
1618 case 0x3C: /*CMP AL,#8*/
1619 temp=FETCH();
1620 setsub8(AL,temp);
1621 cycles-=4;
1622 break;
1623 case 0x3D: /*CMP AX,#16*/
1624 tempw=getword();
1625 setsub16(AX,tempw);
1626 cycles-=4;
1627 break;
1629 case 0x3E: /*DS:*/
1630 oldss=ss;
1631 oldds=ds;
1632 ds=ss=ds;
1633 ssegs=2;
1634 cycles-=4;
1635 goto opcodestart;
1636 // break;
1638 case 0x3F: /*AAS*/
1639 if ((flags&A_FLAG)||((AL&0xF)>9))
1640 {
1641 AL-=6;
1642 AH--;
1643 flags|=(A_FLAG|C_FLAG);
1644 }
1645 else
1646 flags&=~(A_FLAG|C_FLAG);
1647 AL&=0xF;
1648 cycles-=8;
1649 break;
1651 case 0x40: case 0x41: case 0x42: case 0x43: /*INC r16*/
1652 case 0x44: case 0x45: case 0x46: case 0x47:
1653 setadd16nc(regs[opcode&7].w,1);
1654 regs[opcode&7].w++;
1655 cycles-=3;
1656 break;
1657 case 0x48: case 0x49: case 0x4A: case 0x4B: /*DEC r16*/
1658 case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1659 setsub16nc(regs[opcode&7].w,1);
1660 regs[opcode&7].w--;
1661 cycles-=3;
1662 break;
1664 case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/
1665 case 0x54: case 0x55: case 0x56: case 0x57:
1666 if (ssegs) ss=oldss;
1667 SP-=2;
1668 writememw(ss,SP,regs[opcode&7].w);
1669 cycles-=15;
1670 break;
1671 case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/
1672 case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1673 if (ssegs) ss=oldss;
1674 SP+=2;
1675 regs[opcode&7].w=readmemw(ss,(SP-2)&0xFFFF);
1676 cycles-=12;
1677 break;
1680 case 0x70: /*JO*/
1681 offset=(int8_t)FETCH();
1682 if (flags&V_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1683 cycles-=4;
1684 break;
1685 case 0x71: /*JNO*/
1686 offset=(int8_t)FETCH();
1687 if (!(flags&V_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1688 cycles-=4;
1689 break;
1690 case 0x72: /*JB*/
1691 offset=(int8_t)FETCH();
1692 if (flags&C_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1693 cycles-=4;
1694 break;
1695 case 0x73: /*JNB*/
1696 offset=(int8_t)FETCH();
1697 if (!(flags&C_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1698 cycles-=4;
1699 break;
1700 case 0x74: /*JE*/
1701 offset=(int8_t)FETCH();
1702 if (flags&Z_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1703 cycles-=4;
1704 break;
1705 case 0x75: /*JNE*/
1706 offset=(int8_t)FETCH();
1707 cycles-=4;
1708 if (!(flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1709 break;
1710 case 0x76: /*JBE*/
1711 offset=(int8_t)FETCH();
1712 if (flags&(C_FLAG|Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1713 cycles-=4;
1714 break;
1715 case 0x77: /*JNBE*/
1716 offset=(int8_t)FETCH();
1717 if (!(flags&(C_FLAG|Z_FLAG))) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1718 cycles-=4;
1719 break;
1720 case 0x78: /*JS*/
1721 offset=(int8_t)FETCH();
1722 if (flags&N_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1723 cycles-=4;
1724 break;
1725 case 0x79: /*JNS*/
1726 offset=(int8_t)FETCH();
1727 if (!(flags&N_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1728 cycles-=4;
1729 break;
1730 case 0x7A: /*JP*/
1731 offset=(int8_t)FETCH();
1732 if (flags&P_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1733 cycles-=4;
1734 break;
1735 case 0x7B: /*JNP*/
1736 offset=(int8_t)FETCH();
1737 if (!(flags&P_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1738 cycles-=4;
1739 break;
1740 case 0x7C: /*JL*/
1741 offset=(int8_t)FETCH();
1742 temp=(flags&N_FLAG)?1:0;
1743 temp2=(flags&V_FLAG)?1:0;
1744 if (temp!=temp2) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1745 cycles-=4;
1746 break;
1747 case 0x7D: /*JNL*/
1748 offset=(int8_t)FETCH();
1749 temp=(flags&N_FLAG)?1:0;
1750 temp2=(flags&V_FLAG)?1:0;
1751 if (temp==temp2) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1752 cycles-=4;
1753 break;
1754 case 0x7E: /*JLE*/
1755 offset=(int8_t)FETCH();
1756 temp=(flags&N_FLAG)?1:0;
1757 temp2=(flags&V_FLAG)?1:0;
1758 if ((flags&Z_FLAG) || (temp!=temp2)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1759 cycles-=4;
1760 break;
1761 case 0x7F: /*JNLE*/
1762 offset=(int8_t)FETCH();
1763 temp=(flags&N_FLAG)?1:0;
1764 temp2=(flags&V_FLAG)?1:0;
1765 if (!((flags&Z_FLAG) || (temp!=temp2))) { pc+=offset; cycles-=12; FETCHCLEAR(); }
1766 cycles-=4;
1767 break;
1769 case 0x80: case 0x82:
1770 fetchea();
1771 temp=geteab();
1772 temp2=FETCH();
1773 switch (rmdat&0x38)
1774 {
1775 case 0x00: /*ADD b,#8*/
1776 setadd8(temp,temp2);
1777 seteab(temp+temp2);
1778 cycles-=((mod==3)?4:23);
1779 break;
1780 case 0x08: /*OR b,#8*/
1781 temp|=temp2;
1782 setznp8(temp);
1783 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1784 seteab(temp);
1785 cycles-=((mod==3)?4:23);
1786 break;
1787 case 0x10: /*ADC b,#8*/
1788 // temp2+=(flags&C_FLAG);
1789 setadc8(temp,temp2);
1790 seteab(temp+temp2+tempc);
1791 cycles-=((mod==3)?4:23);
1792 break;
1793 case 0x18: /*SBB b,#8*/
1794 // temp2+=(flags&C_FLAG);
1795 setsbc8(temp,temp2);
1796 seteab(temp-(temp2+tempc));
1797 cycles-=((mod==3)?4:23);
1798 break;
1799 case 0x20: /*AND b,#8*/
1800 temp&=temp2;
1801 setznp8(temp);
1802 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1803 seteab(temp);
1804 cycles-=((mod==3)?4:23);
1805 break;
1806 case 0x28: /*SUB b,#8*/
1807 setsub8(temp,temp2);
1808 seteab(temp-temp2);
1809 cycles-=((mod==3)?4:23);
1810 break;
1811 case 0x30: /*XOR b,#8*/
1812 temp^=temp2;
1813 setznp8(temp);
1814 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1815 seteab(temp);
1816 cycles-=((mod==3)?4:23);
1817 break;
1818 case 0x38: /*CMP b,#8*/
1819 setsub8(temp,temp2);
1820 cycles-=((mod==3)?4:14);
1821 break;
1823 // default:
1824 // printf("Bad 80 opcode %02X\n",rmdat&0x38);
1825 // dumpregs();
1826 // exit(-1);
1827 }
1828 break;
1830 case 0x81:
1831 fetchea();
1832 tempw=geteaw();
1833 tempw2=getword();
1834 switch (rmdat&0x38)
1835 {
1836 case 0x00: /*ADD w,#16*/
1837 setadd16(tempw,tempw2);
1838 tempw+=tempw2;
1839 seteaw(tempw);
1840 cycles-=((mod==3)?4:23);
1841 break;
1842 case 0x08: /*OR w,#16*/
1843 tempw|=tempw2;
1844 setznp16(tempw);
1845 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1846 seteaw(tempw);
1847 cycles-=((mod==3)?4:23);
1848 break;
1849 case 0x10: /*ADC w,#16*/
1850 // tempw2+=(flags&C_FLAG);
1851 setadc16(tempw,tempw2);
1852 tempw+=tempw2+tempc;
1853 seteaw(tempw);
1854 cycles-=((mod==3)?4:23);
1855 break;
1856 case 0x20: /*AND w,#16*/
1857 tempw&=tempw2;
1858 setznp16(tempw);
1859 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1860 seteaw(tempw);
1861 cycles-=((mod==3)?4:23);
1862 break;
1863 case 0x18: /*SBB w,#16*/
1864 // tempw2+=(flags&C_FLAG);
1865 setsbc16(tempw,tempw2);
1866 seteaw(tempw-(tempw2+tempc));
1867 cycles-=((mod==3)?4:23);
1868 break;
1869 case 0x28: /*SUB w,#16*/
1870 setsub16(tempw,tempw2);
1871 tempw-=tempw2;
1872 seteaw(tempw);
1873 cycles-=((mod==3)?4:23);
1874 break;
1875 case 0x30: /*XOR w,#16*/
1876 tempw^=tempw2;
1877 setznp16(tempw);
1878 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1879 seteaw(tempw);
1880 cycles-=((mod==3)?4:23);
1881 break;
1882 case 0x38: /*CMP w,#16*/
1883 // printf("CMP %04X %04X\n",tempw,tempw2);
1884 setsub16(tempw,tempw2);
1885 cycles-=((mod==3)?4:14);
1886 break;
1888 // default:
1889 // printf("Bad 81 opcode %02X\n",rmdat&0x38);
1890 // dumpregs();
1891 // exit(-1);
1892 }
1893 break;
1895 case 0x83:
1896 fetchea();
1897 tempw=geteaw();
1898 tempw2=FETCH();
1899 if (tempw2&0x80) tempw2|=0xFF00;
1900 switch (rmdat&0x38)
1901 {
1902 case 0x00: /*ADD w,#8*/
1903 setadd16(tempw,tempw2);
1904 tempw+=tempw2;
1905 seteaw(tempw);
1906 cycles-=((mod==3)?4:23);
1907 break;
1908 case 0x08: /*OR w,#8*/
1909 tempw|=tempw2;
1910 setznp16(tempw);
1911 seteaw(tempw);
1912 flags&=~(C_FLAG|A_FLAG|V_FLAG);
1913 cycles-=((mod==3)?4:23);
1914 break;
1915 case 0x10: /*ADC w,#8*/
1916 // tempw2+=(flags&C_FLAG);
1917 setadc16(tempw,tempw2);
1918 tempw+=tempw2+tempc;
1919 seteaw(tempw);
1920 cycles-=((mod==3)?4:23);
1921 break;
1922 case 0x18: /*SBB w,#8*/
1923 // tempw2+=(flags&C_FLAG);
1924 setsbc16(tempw,tempw2);
1925 tempw-=(tempw2+tempc);
1926 seteaw(tempw);
1927 cycles-=((mod==3)?4:23);
1928 break;
1929 case 0x20: /*AND w,#8*/
1930 tempw&=tempw2;
1931 setznp16(tempw);
1932 seteaw(tempw);
1933 cycles-=((mod==3)?4:23);
1934 flags&=~(C_FLAG|A_FLAG|V_FLAG);
1935 break;
1936 case 0x28: /*SUB w,#8*/
1937 setsub16(tempw,tempw2);
1938 tempw-=tempw2;
1939 seteaw(tempw);
1940 cycles-=((mod==3)?4:23);
1941 break;
1942 case 0x30: /*XOR w,#8*/
1943 tempw^=tempw2;
1944 setznp16(tempw);
1945 seteaw(tempw);
1946 cycles-=((mod==3)?4:23);
1947 flags&=~(C_FLAG|A_FLAG|V_FLAG);
1948 break;
1949 case 0x38: /*CMP w,#8*/
1950 setsub16(tempw,tempw2);
1951 cycles-=((mod==3)?4:14);
1952 break;
1954 // default:
1955 // printf("Bad 83 opcode %02X\n",rmdat&0x38);
1956 // dumpregs();
1957 // exit(-1);
1958 }
1959 break;
1961 case 0x84: /*TEST b,reg*/
1962 fetchea();
1963 temp=geteab();
1964 temp2=getr8(reg);
1965 setznp8(temp&temp2);
1966 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1967 cycles-=((mod==3)?3:13);
1968 break;
1969 case 0x85: /*TEST w,reg*/
1970 fetchea();
1971 tempw=geteaw();
1972 tempw2=regs[reg].w;
1973 setznp16(tempw&tempw2);
1974 flags&=~(C_FLAG|V_FLAG|A_FLAG);
1975 cycles-=((mod==3)?3:13);
1976 break;
1977 case 0x86: /*XCHG b,reg*/
1978 fetchea();
1979 temp=geteab();
1980 seteab(getr8(reg));
1981 setr8(reg,temp);
1982 cycles-=((mod==3)?4:25);
1983 break;
1984 case 0x87: /*XCHG w,reg*/
1985 fetchea();
1986 tempw=geteaw();
1987 seteaw(regs[reg].w);
1988 regs[reg].w=tempw;
1989 cycles-=((mod==3)?4:25);
1990 break;
1992 case 0x88: /*MOV b,reg*/
1993 fetchea();
1994 seteab(getr8(reg));
1995 cycles-=((mod==3)?2:13);
1996 break;
1997 case 0x89: /*MOV w,reg*/
1998 fetchea();
1999 seteaw(regs[reg].w);
2000 cycles-=((mod==3)?2:13);
2001 break;
2002 case 0x8A: /*MOV reg,b*/
2003 fetchea();
2004 temp=geteab();
2005 setr8(reg,temp);
2006 cycles-=((mod==3)?2:12);
2007 break;
2008 case 0x8B: /*MOV reg,w*/
2009 fetchea();
2010 tempw=geteaw();
2011 regs[reg].w=tempw;
2012 cycles-=((mod==3)?2:12);
2013 break;
2015 case 0x8C: /*MOV w,sreg*/
2016 fetchea();
2017 switch (rmdat&0x38)
2018 {
2019 case 0x00: /*ES*/
2020 seteaw(ES);
2021 break;
2022 case 0x08: /*CS*/
2023 seteaw(CS);
2024 break;
2025 case 0x18: /*DS*/
2026 if (ssegs) ds=oldds;
2027 seteaw(DS);
2028 break;
2029 case 0x10: /*SS*/
2030 if (ssegs) ss=oldss;
2031 seteaw(SS);
2032 break;
2033 }
2034 cycles-=((mod==3)?2:13);
2035 break;
2037 case 0x8D: /*LEA*/
2038 fetchea();
2039 regs[reg].w=eaaddr;
2040 cycles-=2;
2041 break;
2043 case 0x8E: /*MOV sreg,w*/
2044 // if (output) printf("MOV %04X ",pc);
2045 fetchea();
2046 // if (output) printf("%04X %02X\n",pc,rmdat);
2047 switch (rmdat&0x38)
2048 {
2049 case 0x00: /*ES*/
2050 tempw=geteaw();
2051 loadseg(tempw,&_es);
2052 break;
2053 case 0x08: /*CS - 8088/8086 only*/
2054 tempw=geteaw();
2055 loadseg(tempw,&_cs);
2056 break;
2057 case 0x18: /*DS*/
2058 tempw=geteaw();
2059 loadseg(tempw,&_ds);
2060 if (ssegs) oldds=ds;
2061 break;
2062 case 0x10: /*SS*/
2063 tempw=geteaw();
2064 loadseg(tempw,&_ss);
2065 if (ssegs) oldss=ss;
2066 // printf("LOAD SS %04X %04X\n",tempw,SS);
2067 // printf("SS loaded with %04X %04X:%04X %04X %04X %04X\n",ss>>4,cs>>4,pc,CX,DX,es>>4);
2068 break;
2069 }
2070 cycles-=((mod==3)?2:12);
2071 skipnextprint=1;
2072 noint=1;
2073 break;
2075 case 0x8F: /*POPW*/
2076 fetchea();
2077 if (ssegs) ss=oldss;
2078 tempw=readmemw(ss,SP);
2079 SP+=2;
2080 seteaw(tempw);
2081 cycles-=25;
2082 break;
2084 case 0x90: /*NOP*/
2085 cycles-=3;
2086 break;
2088 case 0x91: case 0x92: case 0x93: /*XCHG AX*/
2089 case 0x94: case 0x95: case 0x96: case 0x97:
2090 tempw=AX;
2091 AX=regs[opcode&7].w;
2092 regs[opcode&7].w=tempw;
2093 cycles-=3;
2094 break;
2096 case 0x98: /*CBW*/
2097 AH=(AL&0x80)?0xFF:0;
2098 cycles-=2;
2099 break;
2100 case 0x99: /*CWD*/
2101 DX=(AX&0x8000)?0xFFFF:0;
2102 cycles-=5;
2103 break;
2104 case 0x9A: /*CALL FAR*/
2105 tempw=getword();
2106 tempw2=getword();
2107 tempw3=CS;
2108 tempw4=pc;
2109 if (ssegs) ss=oldss;
2110 pc=tempw;
2111 // printf("0x9a");
2112 loadcs(tempw2);
2113 writememw(ss,(SP-2)&0xFFFF,tempw3);
2114 writememw(ss,(SP-4)&0xFFFF,tempw4);
2115 SP-=4;
2116 cycles-=36;
2117 FETCHCLEAR();
2118 break;
2119 case 0x9B: /*WAIT*/
2120 cycles-=4;
2121 break;
2122 case 0x9C: /*PUSHF*/
2123 if (ssegs) ss=oldss;
2124 writememw(ss,((SP-2)&0xFFFF),flags|0xF000);
2125 SP-=2;
2126 cycles-=14;
2127 break;
2128 case 0x9D: /*POPF*/
2129 if (ssegs) ss=oldss;
2130 flags=readmemw(ss,SP)&0xFFF;
2131 SP+=2;
2132 cycles-=12;
2133 break;
2134 case 0x9E: /*SAHF*/
2135 flags=(flags&0xFF00)|AH;
2136 cycles-=4;
2137 break;
2138 case 0x9F: /*LAHF*/
2139 AH=flags&0xFF;
2140 cycles-=4;
2141 break;
2143 case 0xA0: /*MOV AL,(w)*/
2144 addr=getword();
2145 AL=readmemb(ds+addr);
2146 cycles-=14;
2147 break;
2148 case 0xA1: /*MOV AX,(w)*/
2149 addr=getword();
2150 // printf("Reading AX from %05X %04X:%04X\n",ds+addr,ds>>4,addr);
2151 AX=readmemw(ds,addr);
2152 cycles-=!4;
2153 break;
2154 case 0xA2: /*MOV (w),AL*/
2155 addr=getword();
2156 writememb(ds+addr,AL);
2157 cycles-=14;
2158 break;
2159 case 0xA3: /*MOV (w),AX*/
2160 addr=getword();
2161 // if (!addr) printf("Write !addr %04X:%04X\n",cs>>4,pc);
2162 writememw(ds,addr,AX);
2163 cycles-=14;
2164 break;
2166 case 0xA4: /*MOVSB*/
2167 temp=readmemb(ds+SI);
2168 writememb(es+DI,temp);
2169 if (flags&D_FLAG) { DI--; SI--; }
2170 else { DI++; SI++; }
2171 cycles-=18;
2172 break;
2173 case 0xA5: /*MOVSW*/
2174 tempw=readmemw(ds,SI);
2175 writememw(es,DI,tempw);
2176 if (flags&D_FLAG) { DI-=2; SI-=2; }
2177 else { DI+=2; SI+=2; }
2178 cycles-=18;
2179 break;
2180 case 0xA6: /*CMPSB*/
2181 temp =readmemb(ds+SI);
2182 temp2=readmemb(es+DI);
2183 setsub8(temp,temp2);
2184 if (flags&D_FLAG) { DI--; SI--; }
2185 else { DI++; SI++; }
2186 cycles-=30;
2187 break;
2188 case 0xA7: /*CMPSW*/
2189 tempw =readmemw(ds,SI);
2190 tempw2=readmemw(es,DI);
2191 // printf("CMPSW %04X %04X\n",tempw,tempw2);
2192 setsub16(tempw,tempw2);
2193 if (flags&D_FLAG) { DI-=2; SI-=2; }
2194 else { DI+=2; SI+=2; }
2195 cycles-=30;
2196 break;
2197 case 0xA8: /*TEST AL,#8*/
2198 temp=FETCH();
2199 setznp8(AL&temp);
2200 flags&=~(C_FLAG|V_FLAG|A_FLAG);
2201 cycles-=5;
2202 break;
2203 case 0xA9: /*TEST AX,#16*/
2204 tempw=getword();
2205 setznp16(AX&tempw);
2206 flags&=~(C_FLAG|V_FLAG|A_FLAG);
2207 cycles-=5;
2208 break;
2209 case 0xAA: /*STOSB*/
2210 writememb(es+DI,AL);
2211 if (flags&D_FLAG) DI--;
2212 else DI++;
2213 cycles-=11;
2214 break;
2215 case 0xAB: /*STOSW*/
2216 writememw(es,DI,AX);
2217 if (flags&D_FLAG) DI-=2;
2218 else DI+=2;
2219 cycles-=11;
2220 break;
2221 case 0xAC: /*LODSB*/
2222 AL=readmemb(ds+SI);
2223 // printf("LODSB %04X:%04X %02X %04X:%04X\n",cs>>4,pc,AL,ds>>4,SI);
2224 if (flags&D_FLAG) SI--;
2225 else SI++;
2226 cycles-=16;
2227 break;
2228 case 0xAD: /*LODSW*/
2229 // if (times) printf("LODSW %04X:%04X\n",cs>>4,pc);
2230 AX=readmemw(ds,SI);
2231 if (flags&D_FLAG) SI-=2;
2232 else SI+=2;
2233 cycles-=16;
2234 break;
2235 case 0xAE: /*SCASB*/
2236 temp=readmemb(es+DI);
2237 setsub8(AL,temp);
2238 if (flags&D_FLAG) DI--;
2239 else DI++;
2240 cycles-=19;
2241 break;
2242 case 0xAF: /*SCASW*/
2243 tempw=readmemw(es,DI);
2244 setsub16(AX,tempw);
2245 if (flags&D_FLAG) DI-=2;
2246 else DI+=2;
2247 cycles-=19;
2248 break;
2250 case 0xB0: /*MOV AL,#8*/
2251 AL=FETCH();
2252 cycles-=4;
2253 break;
2254 case 0xB1: /*MOV CL,#8*/
2255 CL=FETCH();
2256 cycles-=4;
2257 break;
2258 case 0xB2: /*MOV DL,#8*/
2259 DL=FETCH();
2260 cycles-=4;
2261 break;
2262 case 0xB3: /*MOV BL,#8*/
2263 BL=FETCH();
2264 cycles-=4;
2265 break;
2266 case 0xB4: /*MOV AH,#8*/
2267 AH=FETCH();
2268 cycles-=4;
2269 break;
2270 case 0xB5: /*MOV CH,#8*/
2271 CH=FETCH();
2272 cycles-=4;
2273 break;
2274 case 0xB6: /*MOV DH,#8*/
2275 DH=FETCH();
2276 cycles-=4;
2277 break;
2278 case 0xB7: /*MOV BH,#8*/
2279 BH=FETCH();
2280 cycles-=4;
2281 break;
2282 case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV reg,#16*/
2283 case 0xBC: case 0xBD: case 0xBE: case 0xBF:
2284 regs[opcode&7].w=getword();
2285 cycles-=4;
2286 break;
2288 case 0xC2: /*RET*/
2289 tempw=getword();
2290 if (ssegs) ss=oldss;
2291 pc=readmemw(ss,SP);
2292 // printf("C2\n");
2293 // printf("RET to %04X\n",pc);
2294 SP+=2+tempw;
2295 cycles-=24;
2296 FETCHCLEAR();
2297 break;
2298 case 0xC3: /*RET*/
2299 if (ssegs) ss=oldss;
2300 pc=readmemw(ss,SP);
2301 // printf("C3\n");
2302 // if (output) printf("RET to %04X %05X\n",pc,ss+SP);
2303 SP+=2;
2304 cycles-=20;
2305 FETCHCLEAR();
2306 break;
2307 case 0xC4: /*LES*/
2308 fetchea();
2309 regs[reg].w=readmemw(easeg,eaaddr); //geteaw();
2310 tempw=readmemw(easeg,(eaaddr+2)&0xFFFF); //geteaw2();
2311 loadseg(tempw,&_es);
2312 cycles-=24;
2313 break;
2314 case 0xC5: /*LDS*/
2315 fetchea();
2316 regs[reg].w=readmemw(easeg,eaaddr);
2317 tempw=readmemw(easeg,(eaaddr+2)&0xFFFF);
2318 loadseg(tempw,&_ds);
2319 if (ssegs) oldds=ds;
2320 cycles-=24;
2321 break;
2322 case 0xC6: /*MOV b,#8*/
2323 fetchea();
2324 temp=FETCH();
2325 seteab(temp);
2326 cycles-=((mod==3)?4:14);
2327 break;
2328 case 0xC7: /*MOV w,#16*/
2329 fetchea();
2330 tempw=getword();
2331 seteaw(tempw);
2332 cycles-=((mod==3)?4:14);
2333 break;
2335 case 0xCA: /*RETF*/
2336 tempw=getword();
2337 if (ssegs) ss=oldss;
2338 pc=readmemw(ss,SP);
2339 // printf("CA\n");
2340 loadcs(readmemw(ss,SP+2));
2341 SP+=4;
2342 SP+=tempw;
2343 cycles-=33;
2344 FETCHCLEAR();
2345 break;
2346 case 0xCB: /*RETF*/
2347 if (ssegs) ss=oldss;
2348 pc=readmemw(ss,SP);
2349 // printf("CB\n");
2350 loadcs(readmemw(ss,SP+2));
2351 SP+=4;
2352 cycles-=34;
2353 FETCHCLEAR();
2354 break;
2355 case 0xCC: /*INT 3*/
2356 if (ssegs) ss=oldss;
2357 writememw(ss,((SP-2)&0xFFFF),flags|0xF000);
2358 writememw(ss,((SP-4)&0xFFFF),CS);
2359 writememw(ss,((SP-6)&0xFFFF),pc);
2360 SP-=6;
2361 addr=3<<2;
2362 flags&=~I_FLAG;
2363 flags&=~T_FLAG;
2364 // printf("CC %04X:%04X ",CS,pc);
2365 pc=readmemw(0,addr);
2366 loadcs(readmemw(0,addr+2));
2367 FETCHCLEAR();
2368 // printf("%04X:%04X\n",CS,pc);
2369 cycles-=72;
2370 break;
2371 case 0xCD: /*INT*/
2372 lastpc=pc;
2373 lastcs=CS;
2374 temp=FETCH();
2376 if (ssegs) ss=oldss;
2377 writememw(ss,((SP-2)&0xFFFF),flags|0xF000);
2378 writememw(ss,((SP-4)&0xFFFF),CS);
2379 writememw(ss,((SP-6)&0xFFFF),pc);
2380 flags&=~T_FLAG;
2381 SP-=6;
2382 addr=temp<<2;
2383 pc=readmemw(0,addr);
2385 loadcs(readmemw(0,addr+2));
2386 FETCHCLEAR();
2388 cycles-=71;
2389 break;
2390 case 0xCF: /*IRET*/
2391 if (ssegs) ss=oldss;
2392 tempw=CS;
2393 tempw2=pc;
2394 pc=readmemw(ss,SP);
2395 // printf("CF\n");
2396 loadcs(readmemw(ss,((SP+2)&0xFFFF)));
2397 flags=readmemw(ss,((SP+4)&0xFFFF))&0xFFF;
2398 SP+=6;
2399 cycles-=44;
2400 FETCHCLEAR();
2401 nmi_enable = 1;
2402 break;
2403 case 0xD0:
2404 fetchea();
2405 temp=geteab();
2406 switch (rmdat&0x38)
2407 {
2408 case 0x00: /*ROL b,1*/
2409 if (temp&0x80) flags|=C_FLAG;
2410 else flags&=~C_FLAG;
2411 temp<<=1;
2412 if (flags&C_FLAG) temp|=1;
2413 seteab(temp);
2414 // setznp8(temp);
2415 if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
2416 else flags&=~V_FLAG;
2417 cycles-=((mod==3)?2:23);
2418 break;
2419 case 0x08: /*ROR b,1*/
2420 if (temp&1) flags|=C_FLAG;
2421 else flags&=~C_FLAG;
2422 temp>>=1;
2423 if (flags&C_FLAG) temp|=0x80;
2424 seteab(temp);
2425 // setznp8(temp);
2426 if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
2427 else flags&=~V_FLAG;
2428 cycles-=((mod==3)?2:23);
2429 break;
2430 case 0x10: /*RCL b,1*/
2431 temp2=flags&C_FLAG;
2432 if (temp&0x80) flags|=C_FLAG;
2433 else flags&=~C_FLAG;
2434 temp<<=1;
2435 if (temp2) temp|=1;
2436 seteab(temp);
2437 // setznp8(temp);
2438 if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
2439 else flags&=~V_FLAG;
2440 cycles-=((mod==3)?2:23);
2441 break;
2442 case 0x18: /*RCR b,1*/
2443 temp2=flags&C_FLAG;
2444 if (temp&1) flags|=C_FLAG;
2445 else flags&=~C_FLAG;
2446 temp>>=1;
2447 if (temp2) temp|=0x80;
2448 seteab(temp);
2449 // setznp8(temp);
2450 if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
2451 else flags&=~V_FLAG;
2452 cycles-=((mod==3)?2:23);
2453 break;
2454 case 0x20: case 0x30: /*SHL b,1*/
2455 if (temp&0x80) flags|=C_FLAG;
2456 else flags&=~C_FLAG;
2457 if ((temp^(temp<<1))&0x80) flags|=V_FLAG;
2458 else flags&=~V_FLAG;
2459 temp<<=1;
2460 seteab(temp);
2461 setznp8(temp);
2462 cycles-=((mod==3)?2:23);
2463 flags|=A_FLAG;
2464 break;
2465 case 0x28: /*SHR b,1*/
2466 if (temp&1) flags|=C_FLAG;
2467 else flags&=~C_FLAG;
2468 if (temp&0x80) flags|=V_FLAG;
2469 else flags&=~V_FLAG;
2470 temp>>=1;
2471 seteab(temp);
2472 setznp8(temp);
2473 cycles-=((mod==3)?2:23);
2474 flags|=A_FLAG;
2475 break;
2476 case 0x38: /*SAR b,1*/
2477 if (temp&1) flags|=C_FLAG;
2478 else flags&=~C_FLAG;
2479 temp>>=1;
2480 if (temp&0x40) temp|=0x80;
2481 seteab(temp);
2482 setznp8(temp);
2483 cycles-=((mod==3)?2:23);
2484 flags|=A_FLAG;
2485 flags&=~V_FLAG;
2486 break;
2488 // default:
2489 // printf("Bad D0 opcode %02X\n",rmdat&0x38);
2490 // dumpregs();
2491 // exit(-1);
2492 }
2493 break;
2495 case 0xD1:
2496 fetchea();
2497 tempw=geteaw();
2498 switch (rmdat&0x38)
2499 {
2500 case 0x00: /*ROL w,1*/
2501 if (tempw&0x8000) flags|=C_FLAG;
2502 else flags&=~C_FLAG;
2503 tempw<<=1;
2504 if (flags&C_FLAG) tempw|=1;
2505 seteaw(tempw);
2506 // setznp16(tempw);
2507 if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
2508 else flags&=~V_FLAG;
2509 cycles-=((mod==3)?2:23);
2510 break;
2511 case 0x08: /*ROR w,1*/
2512 if (tempw&1) flags|=C_FLAG;
2513 else flags&=~C_FLAG;
2514 tempw>>=1;
2515 if (flags&C_FLAG) tempw|=0x8000;
2516 seteaw(tempw);
2517 // setznp16(tempw);
2518 if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
2519 else flags&=~V_FLAG;
2520 cycles-=((mod==3)?2:23);
2521 break;
2522 case 0x10: /*RCL w,1*/
2523 temp2=flags&C_FLAG;
2524 if (tempw&0x8000) flags|=C_FLAG;
2525 else flags&=~C_FLAG;
2526 tempw<<=1;
2527 if (temp2) tempw|=1;
2528 seteaw(tempw);
2529 if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
2530 else flags&=~V_FLAG;
2531 cycles-=((mod==3)?2:23);
2532 break;
2533 case 0x18: /*RCR w,1*/
2534 temp2=flags&C_FLAG;
2535 if (tempw&1) flags|=C_FLAG;
2536 else flags&=~C_FLAG;
2537 tempw>>=1;
2538 if (temp2) tempw|=0x8000;
2539 seteaw(tempw);
2540 // setznp16(tempw);
2541 if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
2542 else flags&=~V_FLAG;
2543 cycles-=((mod==3)?2:23);
2544 break;
2545 case 0x20: case 0x30: /*SHL w,1*/
2546 if (tempw&0x8000) flags|=C_FLAG;
2547 else flags&=~C_FLAG;
2548 if ((tempw^(tempw<<1))&0x8000) flags|=V_FLAG;
2549 else flags&=~V_FLAG;
2550 tempw<<=1;
2551 seteaw(tempw);
2552 setznp16(tempw);
2553 cycles-=((mod==3)?2:23);
2554 flags|=A_FLAG;
2555 break;
2556 case 0x28: /*SHR w,1*/
2557 if (tempw&1) flags|=C_FLAG;
2558 else flags&=~C_FLAG;
2559 if (tempw&0x8000) flags|=V_FLAG;
2560 else flags&=~V_FLAG;
2561 tempw>>=1;
2562 seteaw(tempw);
2563 setznp16(tempw);
2564 cycles-=((mod==3)?2:23);
2565 flags|=A_FLAG;
2566 break;
2568 case 0x38: /*SAR w,1*/
2569 if (tempw&1) flags|=C_FLAG;
2570 else flags&=~C_FLAG;
2571 tempw>>=1;
2572 if (tempw&0x4000) tempw|=0x8000;
2573 seteaw(tempw);
2574 setznp16(tempw);
2575 cycles-=((mod==3)?2:23);
2576 flags|=A_FLAG;
2577 flags&=~V_FLAG;
2578 break;
2580 // default:
2581 // printf("Bad D1 opcode %02X\n",rmdat&0x38);
2582 // dumpregs();
2583 // exit(-1);
2584 }
2585 break;
2587 case 0xD2:
2588 fetchea();
2589 temp=geteab();
2590 c=CL;
2591 // cycles-=c;
2592 if (!c) break;
2593 // if (c>7) printf("Shiftb %i %02X\n",rmdat&0x38,c);
2594 switch (rmdat&0x38)
2595 {
2596 case 0x00: /*ROL b,CL*/
2597 while (c>0)
2598 {
2599 temp2=(temp&0x80)?1:0;
2600 temp=(temp<<1)|temp2;
2601 c--;
2602 cycles-=4;
2603 }
2604 if (temp2) flags|=C_FLAG;
2605 else flags&=~C_FLAG;
2606 seteab(temp);
2607 // setznp8(temp);
2608 if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
2609 else flags&=~V_FLAG;
2610 cycles-=((mod==3)?8:28);
2611 break;
2612 case 0x08: /*ROR b,CL*/
2613 while (c>0)
2614 {
2615 temp2=temp&1;
2616 temp>>=1;
2617 if (temp2) temp|=0x80;
2618 c--;
2619 cycles-=4;
2620 }
2621 if (temp2) flags|=C_FLAG;
2622 else flags&=~C_FLAG;
2623 seteab(temp);
2624 if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
2625 else flags&=~V_FLAG;
2626 cycles-=((mod==3)?8:28);
2627 break;
2628 case 0x10: /*RCL b,CL*/
2629 // printf("RCL %i %02X %02X\n",c,CL,temp);
2630 while (c>0)
2631 {
2632 templ=flags&C_FLAG;
2633 temp2=temp&0x80;
2634 temp<<=1;
2635 if (temp2) flags|=C_FLAG;
2636 else flags&=~C_FLAG;
2637 if (templ) temp|=1;
2638 c--;
2639 cycles-=4;
2640 }
2641 // printf("Now %02X\n",temp);
2642 seteab(temp);
2643 if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
2644 else flags&=~V_FLAG;
2645 cycles-=((mod==3)?8:28);
2646 break;
2647 case 0x18: /*RCR b,CL*/
2648 while (c>0)
2649 {
2650 templ=flags&C_FLAG;
2651 temp2=temp&1;
2652 temp>>=1;
2653 if (temp2) flags|=C_FLAG;
2654 else flags&=~C_FLAG;
2655 if (templ) temp|=0x80;
2656 c--;
2657 cycles-=4;
2658 }
2659 // if (temp2) flags|=C_FLAG;
2660 // else flags&=~C_FLAG;
2661 seteab(temp);
2662 if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
2663 else flags&=~V_FLAG;
2664 cycles-=((mod==3)?8:28);
2665 break;
2666 case 0x20: case 0x30: /*SHL b,CL*/
2667 if ((temp<<(c-1))&0x80) flags|=C_FLAG;
2668 else flags&=~C_FLAG;
2669 temp<<=c;
2670 seteab(temp);
2671 setznp8(temp);
2672 cycles-=(c*4);
2673 cycles-=((mod==3)?8:28);
2674 flags|=A_FLAG;
2675 break;
2676 case 0x28: /*SHR b,CL*/
2677 if ((temp>>(c-1))&1) flags|=C_FLAG;
2678 else flags&=~C_FLAG;
2679 temp>>=c;
2680 seteab(temp);
2681 setznp8(temp);
2682 cycles-=(c*4);
2683 cycles-=((mod==3)?8:28);
2684 flags|=A_FLAG;
2685 break;
2686 case 0x38: /*SAR b,CL*/
2687 if ((temp>>(c-1))&1) flags|=C_FLAG;
2688 else flags&=~C_FLAG;
2689 while (c>0)
2690 {
2691 temp>>=1;
2692 if (temp&0x40) temp|=0x80;
2693 c--;
2694 cycles-=4;
2695 }
2696 seteab(temp);
2697 setznp8(temp);
2698 cycles-=((mod==3)?8:28);
2699 flags|=A_FLAG;
2700 break;
2702 // default:
2703 // printf("Bad D2 opcode %02X\n",rmdat&0x38);
2704 // dumpregs();
2705 // exit(-1);
2706 }
2707 break;
2709 case 0xD3:
2710 fetchea();
2711 tempw=geteaw();
2712 c=CL;
2713 // cycles-=c;
2714 if (!c) break;
2715 // if (c>15) printf("Shiftw %i %02X\n",rmdat&0x38,c);
2716 switch (rmdat&0x38)
2717 {
2718 case 0x00: /*ROL w,CL*/
2719 while (c>0)
2720 {
2721 temp=(tempw&0x8000)?1:0;
2722 tempw=(tempw<<1)|temp;
2723 c--;
2724 cycles-=4;
2725 }
2726 if (temp) flags|=C_FLAG;
2727 else flags&=~C_FLAG;
2728 seteaw(tempw);
2729 if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
2730 else flags&=~V_FLAG;
2731 cycles-=((mod==3)?8:28);
2732 break;
2733 case 0x08: /*ROR w,CL*/
2734 while (c>0)
2735 {
2736 tempw2=(tempw&1)?0x8000:0;
2737 tempw=(tempw>>1)|tempw2;
2738 c--;
2739 cycles-=4;
2740 }
2741 if (tempw2) flags|=C_FLAG;
2742 else flags&=~C_FLAG;
2743 seteaw(tempw);
2744 if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
2745 else flags&=~V_FLAG;
2746 cycles-=((mod==3)?8:28);
2747 break;
2748 case 0x10: /*RCL w,CL*/
2749 while (c>0)
2750 {
2751 templ=flags&C_FLAG;
2752 if (tempw&0x8000) flags|=C_FLAG;
2753 else flags&=~C_FLAG;
2754 tempw=(tempw<<1)|templ;
2755 c--;
2756 cycles-=4;
2757 }
2758 if (temp) flags|=C_FLAG;
2759 else flags&=~C_FLAG;
2760 seteaw(tempw);
2761 if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
2762 else flags&=~V_FLAG;
2763 cycles-=((mod==3)?8:28);
2764 break;
2765 case 0x18: /*RCR w,CL*/
2766 while (c>0)
2767 {
2768 templ=flags&C_FLAG;
2769 tempw2=(templ&1)?0x8000:0;
2770 if (tempw&1) flags|=C_FLAG;
2771 else flags&=~C_FLAG;
2772 tempw=(tempw>>1)|tempw2;
2773 c--;
2774 cycles-=4;
2775 }
2776 if (tempw2) flags|=C_FLAG;
2777 else flags&=~C_FLAG;
2778 seteaw(tempw);
2779 if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
2780 else flags&=~V_FLAG;
2781 cycles-=((mod==3)?8:28);
2782 break;
2784 case 0x20: case 0x30: /*SHL w,CL*/
2785 if (c>16)
2786 {
2787 tempw=0;
2788 flags&=~C_FLAG;
2789 }
2790 else
2791 {
2792 if ((tempw<<(c-1))&0x8000) flags|=C_FLAG;
2793 else flags&=~C_FLAG;
2794 tempw<<=c;
2795 }
2796 seteaw(tempw);
2797 setznp16(tempw);
2798 cycles-=(c*4);
2799 cycles-=((mod==3)?8:28);
2800 flags|=A_FLAG;
2801 break;
2803 case 0x28: /*SHR w,CL*/
2804 if ((tempw>>(c-1))&1) flags|=C_FLAG;
2805 else flags&=~C_FLAG;
2806 tempw>>=c;
2807 seteaw(tempw);
2808 setznp16(tempw);
2809 cycles-=(c*4);
2810 cycles-=((mod==3)?8:28);
2811 flags|=A_FLAG;
2812 break;
2814 case 0x38: /*SAR w,CL*/
2815 tempw2=tempw&0x8000;
2816 if ((tempw>>(c-1))&1) flags|=C_FLAG;
2817 else flags&=~C_FLAG;
2818 while (c>0)
2819 {
2820 tempw=(tempw>>1)|tempw2;
2821 c--;
2822 cycles-=4;
2823 }
2824 seteaw(tempw);
2825 setznp16(tempw);
2826 cycles-=((mod==3)?8:28);
2827 flags|=A_FLAG;
2828 break;
2830 // default:
2831 // printf("Bad D3 opcode %02X\n",rmdat&0x38);
2832 // dumpregs();
2833 // exit(-1);
2834 }
2835 break;
2837 case 0xD4: /*AAM*/
2838 tempws=FETCH();
2839 AH=AL/tempws;
2840 AL%=tempws;
2841 setznp16(AX);
2842 cycles-=83;
2843 break;
2844 case 0xD5: /*AAD*/
2845 tempws=FETCH();
2846 AL=(AH*tempws)+AL;
2847 AH=0;
2848 setznp16(AX);
2849 cycles-=60;
2850 break;
2851 case 0xD7: /*XLAT*/
2852 addr=BX+AL;
2853 AL=readmemb(ds+addr);
2854 cycles-=11;
2855 break;
2856 case 0xD9: case 0xDA: case 0xDB: case 0xDD: /*ESCAPE*/
2857 case 0xDC: case 0xDE: case 0xDF: case 0xD8:
2858 fetchea();
2859 geteab();
2860 break;
2862 case 0xE0: /*LOOPNE*/
2863 offset=(int8_t)FETCH();
2864 CX--;
2865 if (CX && !(flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
2866 cycles-=6;
2867 break;
2868 case 0xE1: /*LOOPE*/
2869 offset=(int8_t)FETCH();
2870 CX--;
2871 if (CX && (flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
2872 cycles-=6;
2873 break;
2874 case 0xE2: /*LOOP*/
2875 // printf("LOOP start\n");
2876 offset=(int8_t)FETCH();
2877 CX--;
2878 if (CX) { pc+=offset; cycles-=12; FETCHCLEAR(); }
2879 cycles-=5;
2880 // printf("LOOP end!\n");
2881 break;
2882 case 0xE3: /*JCXZ*/
2883 offset=(int8_t)FETCH();
2884 if (!CX) { pc+=offset; cycles-=12; FETCHCLEAR(); }
2885 cycles-=6;
2886 break;
2888 case 0xE4: /*IN AL*/
2889 temp=FETCH();
2890 AL=inb(temp);
2891 cycles-=14;
2892 break;
2893 case 0xE5: /*IN AX*/
2894 temp=FETCH();
2895 AL=inb(temp);
2896 AH=inb(temp+1);
2897 cycles-=14;
2898 break;
2899 case 0xE6: /*OUT AL*/
2900 temp=FETCH();
2901 outb(temp,AL);
2902 cycles-=14;
2903 break;
2904 case 0xE7: /*OUT AX*/
2905 temp=FETCH();
2906 outb(temp,AL);
2907 outb(temp+1,AH);
2908 cycles-=14;
2909 break;
2911 case 0xE8: /*CALL rel 16*/
2912 tempw=getword();
2913 if (ssegs) ss=oldss;
2914 // writememb(ss+((SP-1)&0xFFFF),pc>>8);
2915 writememw(ss,((SP-2)&0xFFFF),pc);
2916 SP-=2;
2917 pc+=tempw;
2918 cycles-=23;
2919 FETCHCLEAR();
2920 break;
2921 case 0xE9: /*JMP rel 16*/
2922 // printf("PC was %04X\n",pc);
2923 pc+=getword();
2924 // printf("PC now %04X\n",pc);
2925 cycles-=15;
2926 FETCHCLEAR();
2927 break;
2928 case 0xEA: /*JMP far*/
2929 addr=getword();
2930 tempw=getword();
2931 pc=addr;
2932 // printf("EA\n");
2933 loadcs(tempw);
2934 // cs=loadcs(CS);
2935 // cs=CS<<4;
2936 cycles-=15;
2937 FETCHCLEAR();
2938 break;
2939 case 0xEB: /*JMP rel*/
2940 offset=(int8_t)FETCH();
2941 pc+=offset;
2942 cycles-=15;
2943 FETCHCLEAR();
2944 break;
2945 case 0xEC: /*IN AL,DX*/
2946 AL=inb(DX);
2947 cycles-=12;
2948 break;
2949 case 0xED: /*IN AX,DX*/
2950 AL=inb(DX);
2951 AH=inb(DX+1);
2952 cycles-=12;
2953 break;
2954 case 0xEE: /*OUT DX,AL*/
2955 outb(DX,AL);
2956 cycles-=12;
2957 break;
2958 case 0xEF: /*OUT DX,AX*/
2959 outb(DX,AL);
2960 outb(DX+1,AH);
2961 cycles-=12;
2962 break;
2964 case 0xF0: /*LOCK*/
2965 cycles-=4;
2966 break;
2968 case 0xF2: /*REPNE*/
2969 rep(0);
2970 break;
2971 case 0xF3: /*REPE*/
2972 rep(1);
2973 break;
2975 case 0xF4: /*HLT*/
2976 // printf("IN HLT!!!! %04X:%04X %08X %08X %08X\n",oldcs,oldpc,old8,old82,old83);
2977 /* if (!(flags & I_FLAG))
2978 {
2979 pclog("HLT\n");
2980 dumpregs();
2981 exit(-1);
2982 }*/
2983 inhlt=1;
2984 pc--;
2985 FETCHCLEAR();
2986 cycles-=2;
2987 break;
2988 case 0xF5: /*CMC*/
2989 flags^=C_FLAG;
2990 cycles-=2;
2991 break;
2993 case 0xF6:
2994 fetchea();
2995 temp=geteab();
2996 switch (rmdat&0x38)
2997 {
2998 case 0x00: /*TEST b,#8*/
2999 temp2=FETCH();
3000 temp&=temp2;
3001 setznp8(temp);
3002 flags&=~(C_FLAG|V_FLAG|A_FLAG);
3003 cycles-=((mod==3)?5:11);
3004 break;
3005 case 0x10: /*NOT b*/
3006 temp=~temp;
3007 seteab(temp);
3008 cycles-=((mod==3)?3:24);
3009 break;
3010 case 0x18: /*NEG b*/
3011 setsub8(0,temp);
3012 temp=0-temp;
3013 seteab(temp);
3014 cycles-=((mod==3)?3:24);
3015 break;
3016 case 0x20: /*MUL AL,b*/
3017 setznp8(AL);
3018 AX=AL*temp;
3019 if (AX) flags&=~Z_FLAG;
3020 else flags|=Z_FLAG;
3021 if (AH) flags|=(C_FLAG|V_FLAG);
3022 else flags&=~(C_FLAG|V_FLAG);
3023 cycles-=70;
3024 break;
3025 case 0x28: /*IMUL AL,b*/
3026 setznp8(AL);
3027 tempws=(int)((int8_t)AL)*(int)((int8_t)temp);
3028 AX=tempws&0xFFFF;
3029 if (AX) flags&=~Z_FLAG;
3030 else flags|=Z_FLAG;
3031 if (AH) flags|=(C_FLAG|V_FLAG);
3032 else flags&=~(C_FLAG|V_FLAG);
3033 cycles-=80;
3034 break;
3035 case 0x30: /*DIV AL,b*/
3036 tempw=AX;
3037 if (temp)
3038 {
3039 tempw2=tempw%temp;
3040 /* if (!tempw)
3041 {
3042 writememw((ss+SP)-2,flags|0xF000);
3043 writememw((ss+SP)-4,cs>>4);
3044 writememw((ss+SP)-6,pc);
3045 SP-=6;
3046 flags&=~I_FLAG;
3047 pc=readmemw(0);
3048 cs=readmemw(2)<<4;
3049 printf("Div by zero %04X:%04X\n",cs>>4,pc);
3050 // dumpregs();
3051 // exit(-1);
3052 }
3053 else
3054 {*/
3055 AH=tempw2;
3056 tempw/=temp;
3057 AL=tempw&0xFF;
3058 // }
3059 }
3060 else
3061 {
3062 printf("DIVb BY 0 %04X:%04X\n",cs>>4,pc);
3063 writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
3064 writememw(ss,(SP-4)&0xFFFF,CS);
3065 writememw(ss,(SP-6)&0xFFFF,pc);
3066 SP-=6;
3067 flags&=~I_FLAG;
3068 flags&=~T_FLAG;
3069 pc=readmemw(0,0);
3070 // printf("F6 30\n");
3071 loadcs(readmemw(0,2));
3072 FETCHCLEAR();
3073 // cs=loadcs(CS);
3074 // cs=CS<<4;
3075 // printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x30);
3076 // dumpregs();
3077 // exit(-1);
3078 }
3079 cycles-=80;
3080 break;
3081 case 0x38: /*IDIV AL,b*/
3082 tempws=(int)AX;
3083 if (temp)
3084 {
3085 tempw2=tempws%(int)((int8_t)temp);
3086 /* if (!tempw)
3087 {
3088 writememw((ss+SP)-2,flags|0xF000);
3089 writememw((ss+SP)-4,cs>>4);
3090 writememw((ss+SP)-6,pc);
3091 SP-=6;
3092 flags&=~I_FLAG;
3093 pc=readmemw(0);
3094 cs=readmemw(2)<<4;
3095 printf("Div by zero %04X:%04X\n",cs>>4,pc);
3096 }
3097 else
3098 {*/
3099 AH=tempw2&0xFF;
3100 tempws/=(int)((int8_t)temp);
3101 AL=tempws&0xFF;
3102 // }
3103 }
3104 else
3105 {
3106 printf("IDIVb BY 0 %04X:%04X\n",cs>>4,pc);
3107 writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
3108 writememw(ss,(SP-4)&0xFFFF,CS);
3109 writememw(ss,(SP-6)&0xFFFF,pc);
3110 SP-=6;
3111 flags&=~I_FLAG;
3112 flags&=~T_FLAG;
3113 pc=readmemw(0,0);
3114 // printf("F6 38\n");
3115 loadcs(readmemw(0,2));
3116 FETCHCLEAR();
3117 // cs=loadcs(CS);
3118 // cs=CS<<4;
3119 // printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x38);
3120 }
3121 cycles-=101;
3122 break;
3124 // default:
3125 // printf("Bad F6 opcode %02X\n",rmdat&0x38);
3126 // dumpregs();
3127 // exit(-1);
3128 }
3129 break;
3131 case 0xF7:
3132 fetchea();
3133 tempw=geteaw();
3134 switch (rmdat&0x38)
3135 {
3136 case 0x00: /*TEST w*/
3137 tempw2=getword();
3138 setznp16(tempw&tempw2);
3139 flags&=~(C_FLAG|V_FLAG|A_FLAG);
3140 cycles-=((mod==3)?5:11);
3141 break;
3142 case 0x10: /*NOT w*/
3143 seteaw(~tempw);
3144 cycles-=((mod==3)?3:24);
3145 break;
3146 case 0x18: /*NEG w*/
3147 setsub16(0,tempw);
3148 tempw=0-tempw;
3149 seteaw(tempw);
3150 cycles-=((mod==3)?3:24);
3151 break;
3152 case 0x20: /*MUL AX,w*/
3153 setznp16(AX);
3154 templ=AX*tempw;
3155 // if (output) printf("%04X*%04X=%08X\n",AX,tempw,templ);
3156 AX=templ&0xFFFF;
3157 DX=templ>>16;
3158 if (AX|DX) flags&=~Z_FLAG;
3159 else flags|=Z_FLAG;
3160 if (DX) flags|=(C_FLAG|V_FLAG);
3161 else flags&=~(C_FLAG|V_FLAG);
3162 cycles-=118;
3163 break;
3164 case 0x28: /*IMUL AX,w*/
3165 setznp16(AX);
3166 // printf("IMUL %i %i ",(int)((int16_t)AX),(int)((int16_t)tempw));
3167 tempws=(int)((int16_t)AX)*(int)((int16_t)tempw);
3168 if ((tempws>>15) && ((tempws>>15)!=-1)) flags|=(C_FLAG|V_FLAG);
3169 else flags&=~(C_FLAG|V_FLAG);
3170 // printf("%i ",tempws);
3171 AX=tempws&0xFFFF;
3172 tempws=(uint16_t)(tempws>>16);
3173 DX=tempws&0xFFFF;
3174 // printf("%04X %04X\n",AX,DX);
3175 // dumpregs();
3176 // exit(-1);
3177 if (AX|DX) flags&=~Z_FLAG;
3178 else flags|=Z_FLAG;
3179 cycles-=128;
3180 break;
3181 case 0x30: /*DIV AX,w*/
3182 templ=(DX<<16)|AX;
3183 // printf("DIV %08X/%04X\n",templ,tempw);
3184 if (tempw)
3185 {
3186 tempw2=templ%tempw;
3187 DX=tempw2;
3188 templ/=tempw;
3189 AX=templ&0xFFFF;
3190 }
3191 else
3192 {
3193 printf("DIVw BY 0 %04X:%04X\n",cs>>4,pc);
3194 writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
3195 writememw(ss,(SP-4)&0xFFFF,CS);
3196 writememw(ss,(SP-6)&0xFFFF,pc);
3197 SP-=6;
3198 flags&=~I_FLAG;
3199 flags&=~T_FLAG;
3200 pc=readmemw(0,0);
3201 // printf("F7 30\n");
3202 loadcs(readmemw(0,2));
3203 FETCHCLEAR();
3204 }
3205 cycles-=144;
3206 break;
3207 case 0x38: /*IDIV AX,w*/
3208 tempws=(int)((DX<<16)|AX);
3209 // printf("IDIV %i %i ",tempws,tempw);
3210 if (tempw)
3211 {
3212 tempw2=tempws%(int)((int16_t)tempw);
3213 // printf("%04X ",tempw2);
3214 DX=tempw2;
3215 tempws/=(int)((int16_t)tempw);
3216 AX=tempws&0xFFFF;
3217 }
3218 else
3219 {
3220 printf("IDIVw BY 0 %04X:%04X\n",cs>>4,pc);
3221 writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
3222 writememw(ss,(SP-4)&0xFFFF,CS);
3223 writememw(ss,(SP-6)&0xFFFF,pc);
3224 SP-=6;
3225 flags&=~I_FLAG;
3226 flags&=~T_FLAG;
3227 pc=readmemw(0,0);
3228 // printf("F7 38\n");
3229 loadcs(readmemw(0,2));
3230 FETCHCLEAR();
3231 }
3232 cycles-=165;
3233 break;
3235 // default:
3236 // printf("Bad F7 opcode %02X\n",rmdat&0x38);
3237 // dumpregs();
3238 // exit(-1);
3239 }
3240 break;
3242 case 0xF8: /*CLC*/
3243 flags&=~C_FLAG;
3244 cycles-=2;
3245 break;
3246 case 0xF9: /*STC*/
3247 // printf("STC %04X\n",pc);
3248 flags|=C_FLAG;
3249 cycles-=2;
3250 break;
3251 case 0xFA: /*CLI*/
3252 flags&=~I_FLAG;
3253 // printf("CLI at %04X:%04X\n",cs>>4,pc);
3254 cycles-=3;
3255 break;
3256 case 0xFB: /*STI*/
3257 flags|=I_FLAG;
3258 // printf("STI at %04X:%04X\n",cs>>4,pc);
3259 cycles-=2;
3260 break;
3261 case 0xFC: /*CLD*/
3262 flags&=~D_FLAG;
3263 cycles-=2;
3264 break;
3265 case 0xFD: /*STD*/
3266 flags|=D_FLAG;
3267 cycles-=2;
3268 break;
3270 case 0xFE: /*INC/DEC b*/
3271 fetchea();
3272 temp=geteab();
3273 flags&=~V_FLAG;
3274 if (rmdat&0x38)
3275 {
3276 setsub8nc(temp,1);
3277 temp2=temp-1;
3278 if ((temp&0x80) && !(temp2&0x80)) flags|=V_FLAG;
3279 }
3280 else
3281 {
3282 setadd8nc(temp,1);
3283 temp2=temp+1;
3284 if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG;
3285 }
3286 // setznp8(temp2);
3287 seteab(temp2);
3288 cycles-=((mod==3)?3:23);
3289 break;
3291 case 0xFF:
3292 fetchea();
3293 switch (rmdat&0x38)
3294 {
3295 case 0x00: /*INC w*/
3296 tempw=geteaw();
3297 setadd16nc(tempw,1);
3298 // setznp16(tempw+1);
3299 seteaw(tempw+1);
3300 cycles-=((mod==3)?3:23);
3301 break;
3302 case 0x08: /*DEC w*/
3303 tempw=geteaw();
3304 // setsub16(tempw,1);
3305 setsub16nc(tempw,1);
3306 // setznp16(tempw-1);
3307 seteaw(tempw-1);
3308 // if (output) printf("DEC - %04X\n",tempw);
3309 cycles-=((mod==3)?3:23);
3310 break;
3311 case 0x10: /*CALL*/
3312 tempw=geteaw();
3313 if (ssegs) ss=oldss;
3314 writememw(ss,(SP-2)&0xFFFF,pc);
3315 SP-=2;
3316 pc=tempw;
3317 // printf("FF 10\n");
3318 cycles-=((mod==3)?20:29);
3319 FETCHCLEAR();
3320 break;
3321 case 0x18: /*CALL far*/
3322 tempw=readmemw(easeg,eaaddr);
3323 tempw2=readmemw(easeg,(eaaddr+2)&0xFFFF); //geteaw2();
3324 tempw3=CS;
3325 tempw4=pc;
3326 if (ssegs) ss=oldss;
3327 pc=tempw;
3328 // printf("FF 18\n");
3329 loadcs(tempw2);
3330 writememw(ss,(SP-2)&0xFFFF,tempw3);
3331 writememw(ss,((SP-4)&0xFFFF),tempw4);
3332 SP-=4;
3333 cycles-=53;
3334 FETCHCLEAR();
3335 break;
3336 case 0x20: /*JMP*/
3337 pc=geteaw();
3338 // printf("FF 20\n");
3339 cycles-=((mod==3)?11:18);
3340 FETCHCLEAR();
3341 break;
3342 case 0x28: /*JMP far*/
3343 pc=readmemw(easeg,eaaddr); //geteaw();
3344 // printf("FF 28\n");
3345 loadcs(readmemw(easeg,(eaaddr+2)&0xFFFF)); //geteaw2();
3346 // cs=loadcs(CS);
3347 // cs=CS<<4;
3348 cycles-=24;
3349 FETCHCLEAR();
3350 break;
3351 case 0x30: /*PUSH w*/
3352 tempw=geteaw();
3353 // if (output) printf("PUSH %04X %i %02X %04X %04X %02X %02X\n",tempw,rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]);
3354 if (ssegs) ss=oldss;
3355 writememw(ss,((SP-2)&0xFFFF),tempw);
3356 SP-=2;
3357 cycles-=((mod==3)?15:24);
3358 break;
3360 // default:
3361 // printf("Bad FF opcode %02X\n",rmdat&0x38);
3362 // dumpregs();
3363 // exit(-1);
3364 }
3365 break;
3367 default:
3368 FETCH();
3369 cycles-=8;
3370 break;
3372 /* printf("Bad opcode %02X at %04X:%04X from %04X:%04X %08X\n",opcode,cs>>4,pc,old8>>16,old8&0xFFFF,old82);
3373 dumpregs();
3374 exit(-1);*/
3375 }
3376 pc&=0xFFFF;
3378 /* if ((CS & 0xf000) == 0xa000)
3379 {
3380 dumpregs();
3381 exit(-1);
3382 }*/
3383 // output = 3;
3384 /* if (CS == 0xf000)
3385 {
3386 dumpregs();
3387 exit(-1);
3388 }
3389 output = 3;*/
3390 if (ssegs)
3391 {
3392 ds=oldds;
3393 ss=oldss;
3394 ssegs=0;
3395 }
3397 // output = 3;
3398 // if (instime) printf("%i %i %i %i\n",cycdiff,cycles,memcycs,fetchclocks);
3399 FETCHADD(((cycdiff-cycles)-memcycs)-fetchclocks);
3400 if ((cycdiff-cycles)<memcycs) cycles-=(memcycs-(cycdiff-cycles));
3401 if (romset==ROM_IBMPC)
3402 {
3403 if ((cs+pc)==0xFE4A7) /*You didn't seriously think I was going to emulate the cassette, did you?*/
3404 {
3405 CX=1;
3406 BX=0x500;
3407 }
3408 }
3409 memcycs=0;
3411 insc++;
3412 // output=(CS==0xEB9);
3413 clockhardware();
3416 if (trap && (flags&T_FLAG) && !noint)
3417 {
3418 // printf("TRAP!!! %04X:%04X\n",CS,pc);
3419 writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
3420 writememw(ss,(SP-4)&0xFFFF,CS);
3421 writememw(ss,(SP-6)&0xFFFF,pc);
3422 SP-=6;
3423 addr=1<<2;
3424 flags&=~I_FLAG;
3425 flags&=~T_FLAG;
3426 pc=readmemw(0,addr);
3427 loadcs(readmemw(0,addr+2));
3428 FETCHCLEAR();
3429 }
3430 else if (nmi && nmi_enable)
3431 {
3432 // output = 3;
3433 writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
3434 writememw(ss,(SP-4)&0xFFFF,CS);
3435 writememw(ss,(SP-6)&0xFFFF,pc);
3436 SP-=6;
3437 addr=2<<2;
3438 flags&=~I_FLAG;
3439 flags&=~T_FLAG;
3440 pc=readmemw(0,addr);
3441 loadcs(readmemw(0,addr+2));
3442 FETCHCLEAR();
3443 nmi_enable = 0;
3444 }
3445 else if (takeint && !ssegs && !noint)
3446 {
3447 temp=picinterrupt();
3448 if (temp!=0xFF)
3449 {
3450 if (inhlt) pc++;
3451 writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
3452 writememw(ss,(SP-4)&0xFFFF,CS);
3453 writememw(ss,(SP-6)&0xFFFF,pc);
3454 SP-=6;
3455 addr=temp<<2;
3456 flags&=~I_FLAG;
3457 flags&=~T_FLAG;
3458 pc=readmemw(0,addr);
3459 // printf("INT INT INT\n");
3460 loadcs(readmemw(0,addr+2));
3461 FETCHCLEAR();
3462 // printf("INTERRUPT\n");
3463 }
3464 }
3465 takeint = (flags&I_FLAG) && (pic.pend&~pic.mask);
3467 if (noint) noint=0;
3468 ins++;
3469 /* if (timetolive)
3470 {
3471 timetolive--;
3472 if (!timetolive) exit(-1); //output=0;
3473 }*/
3474 }
3475 }
