PCem

view src/386.c @ 118:07168c9bdd22

Added REP NOP / PAUSE instruction, needed for Windows 2000 installer. Patch from SA1988.
author TomW
date Tue Jul 08 22:06:48 2014 +0100
parents 912e602b3406
children bd46c39a78e8
line source
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include "ibm.h"
5 #include "x86.h"
6 #include "x87.h"
7 #include "mem.h"
8 #include "cpu.h"
9 #include "fdc.h"
10 #include "timer.h"
11 #include "video.h"
13 int nmi_enable = 1;
15 int inscounts[256];
16 uint32_t oldpc2;
18 int trap;
20 #define check_io_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \
21 { \
22 int tempi = checkio(port); \
23 if (abrt) return 0; \
24 if (tempi) \
25 { \
26 x86gpf(NULL,0); \
27 return 0; \
28 } \
29 }
31 #define checkio_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \
32 { \
33 tempi = checkio(port); \
34 if (abrt) break; \
35 if (tempi) \
36 { \
37 x86gpf(NULL,0); \
38 break; \
39 } \
40 }
43 int cpl_override=0;
45 int has_fpu;
46 int fpucount=0;
47 int times;
48 uint16_t rds;
49 uint16_t ea_rseg;
51 int is486;
52 int cgate32;
54 #undef readmemb
55 #undef writememb
58 #define readmemb(s,a) ((readlookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[((s)+(a))>>12] + (s) + (a)) )
60 #define writememb(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememb386l(s,a,v); else *(uint8_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v
62 #define writememw(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) writememwl(s,a,v); else *(uint16_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v
63 #define writememl(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC) writememll(s,a,v); else *(uint32_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v
66 uint8_t romext[32768];
67 uint8_t *ram,*rom;
68 uint16_t biosmask;
70 uint32_t rmdat32;
71 #define rmdat rmdat32
72 #define fetchdat rmdat32
73 uint32_t backupregs[16];
74 int oddeven=0;
75 int inttype,abrt;
78 uint32_t oldcs2;
79 uint32_t oldecx;
80 uint32_t op32;
82 static inline uint8_t fastreadb(uint32_t a)
83 {
84 if ((a >> 12) == pccache)
85 return *((uint8_t *)&pccache2[a]);
86 pccache2 = getpccache(a);
87 if (abrt)
88 return;
89 pccache = a >> 12;
90 return *((uint8_t *)&pccache2[a]);
91 }
93 static inline uint16_t fastreadw(uint32_t a)
94 {
95 uint32_t t;
96 if ((a&0xFFF)>0xFFE)
97 {
98 t=readmemb(0,a);
99 t|=(readmemb(0,a+1)<<8);
100 return t;
101 }
102 if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]);
103 pccache2=getpccache(a);
104 if (abrt)
105 return;
106 pccache=a>>12;
107 return *((uint16_t *)&pccache2[a]);
108 }
110 static inline uint32_t fastreadl(uint32_t a)
111 {
112 uint8_t *t;
113 uint32_t val;
114 if ((a&0xFFF)<0xFFD)
115 {
116 if ((a>>12)!=pccache)
117 {
118 t = getpccache(a);
119 if (abrt) return 0;
120 pccache2 = t;
121 pccache=a>>12;
122 //return *((uint32_t *)&pccache2[a]);
123 }
124 return *((uint32_t *)&pccache2[a]);
125 }
126 val =readmemb(0,a);
127 val |=(readmemb(0,a+1)<<8);
128 val |=(readmemb(0,a+2)<<16);
129 val |=(readmemb(0,a+3)<<24);
130 return val;
131 }
134 static inline uint8_t getbyte()
135 {
136 pc++;
137 return fastreadb(cs + (pc - 1));
138 }
140 static inline uint16_t getword()
141 {
142 pc+=2;
143 return fastreadw(cs+(pc-2));
144 }
146 static inline uint32_t getlong()
147 {
148 pc+=4;
149 return fastreadl(cs+(pc-4));
150 }
152 uint32_t *eal_r, *eal_w;
153 static inline uint8_t geteab()
154 {
155 if (mod==3)
156 return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l;
157 if (eal_r) return *(uint8_t *)eal_r;
158 return readmemb(easeg,eaaddr);
159 }
161 static inline uint16_t geteaw()
162 {
163 if (mod==3)
164 return regs[rm].w;
165 // cycles-=3;
166 if (eal_r) return *(uint16_t *)eal_r;
167 return readmemw(easeg,eaaddr);
168 }
170 static inline uint32_t geteal()
171 {
172 if (mod==3)
173 return regs[rm].l;
174 // cycles-=3;
175 if (eal_r) return *eal_r;
176 return readmeml(easeg,eaaddr);
177 }
179 static inline uint8_t geteab_mem()
180 {
181 if (eal_r) return *(uint8_t *)eal_r;
182 return readmemb(easeg,eaaddr);
183 }
184 static inline uint16_t geteaw_mem()
185 {
186 if (eal_r) return *(uint16_t *)eal_r;
187 return readmemw(easeg,eaaddr);
188 }
189 static inline uint32_t geteal_mem()
190 {
191 if (eal_r) return *eal_r;
192 return readmeml(easeg,eaaddr);
193 }
195 #define seteab(v) if (mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v); } else if (rm&4) regs[rm&3].b.h=v; else regs[rm].b.l=v
196 #define seteaw(v) if (mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v); } else regs[rm].w=v
197 #define seteal(v) if (mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v); } else regs[rm].l=v
199 #define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v);
200 #define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v);
201 #define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v);
203 uint16_t *mod1add[2][8];
204 uint32_t *mod1seg[8];
206 static inline void fetch_ea_32_long(uint32_t rmdat)
207 {
208 eal_r = eal_w = NULL;
209 easeg = ds;
210 ea_rseg = DS;
211 if (rm == 4)
212 {
213 uint8_t sib = rmdat >> 8;
215 switch (mod)
216 {
217 case 0:
218 eaaddr = regs[sib & 7].l;
219 pc++;
220 break;
221 case 1:
222 pc++;
223 eaaddr = ((uint32_t)(int8_t)getbyte()) + regs[sib & 7].l;
224 // pc++;
225 break;
226 case 2:
227 eaaddr = (fastreadl(cs + pc + 1)) + regs[sib & 7].l;
228 pc += 5;
229 break;
230 }
231 /*SIB byte present*/
232 if ((sib & 7) == 5 && !mod)
233 eaaddr = getlong();
234 else if ((sib & 6) == 4)
235 {
236 easeg = ss;
237 ea_rseg = SS;
238 }
239 if (((sib >> 3) & 7) != 4)
240 eaaddr += regs[(sib >> 3) & 7].l << (sib >> 6);
241 }
242 else
243 {
244 eaaddr = regs[rm].l;
245 if (mod)
246 {
247 if (rm == 5)
248 {
249 easeg = ss;
250 ea_rseg = SS;
251 }
252 if (mod == 1)
253 {
254 eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
255 pc++;
256 }
257 else
258 {
259 eaaddr += getlong();
260 }
261 }
262 else if (rm == 5)
263 {
264 eaaddr = getlong();
265 }
266 }
267 if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC)
268 {
269 if ( readlookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF)
270 eal_r = (uint32_t *)(readlookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr);
271 if (writelookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF)
272 eal_w = (uint32_t *)(writelookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr);
273 }
274 }
276 static inline void fetch_ea_16_long(uint32_t rmdat)
277 {
278 eal_r = eal_w = NULL;
279 if (!mod && rm == 6)
280 {
281 eaaddr = getword();
282 easeg = ds;
283 ea_rseg = DS;
284 }
285 else
286 {
287 switch (mod)
288 {
289 case 0:
290 eaaddr = 0;
291 break;
292 case 1:
293 eaaddr = (uint16_t)(int8_t)(rmdat >> 8); pc++;
294 break;
295 case 2:
296 eaaddr = getword();
297 break;
298 }
299 eaaddr += (*mod1add[0][rm]) + (*mod1add[1][rm]);
300 easeg = *mod1seg[rm];
301 if (mod1seg[rm] == &ss) ea_rseg = SS;
302 else ea_rseg = DS;
303 eaaddr &= 0xFFFF;
304 }
305 if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC)
306 {
307 if ( readlookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF)
308 eal_r = (uint32_t *)(readlookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr);
309 if (writelookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF)
310 eal_w = (uint32_t *)(writelookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr);
311 }
312 }
314 #define fetch_ea_16(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_16_long(rmdat); if (abrt) return 0; }
315 #define fetch_ea_32(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_32_long(rmdat); } if (abrt) return 0
317 #include "x86_flags.h"
319 void x86_int(int num)
320 {
321 uint32_t addr;
322 // pclog("x86_int\n");
323 flags_rebuild();
324 pc=oldpc;
325 if (msw&1)
326 {
327 pmodeint(num,0);
328 }
329 else
330 {
331 if (ssegs) ss=oldss;
332 if (stack32)
333 {
334 writememw(ss,ESP-2,flags);
335 writememw(ss,ESP-4,CS);
336 writememw(ss,ESP-6,pc);
337 ESP-=6;
338 }
339 else
340 {
341 writememw(ss,((SP-2)&0xFFFF),flags);
342 writememw(ss,((SP-4)&0xFFFF),CS);
343 writememw(ss,((SP-6)&0xFFFF),pc);
344 SP-=6;
345 }
346 addr = (num << 2) + idt.base;
348 flags&=~I_FLAG;
349 flags&=~T_FLAG;
350 oxpc=pc;
351 pc=readmemw(0,addr);
352 loadcs(readmemw(0,addr+2));
353 }
354 cycles-=70;
355 }
357 void x86_int_sw(int num)
358 {
359 uint32_t addr;
360 // pclog("x86_int\n");
361 flags_rebuild();
362 if (msw&1)
363 {
364 pmodeint(num,1);
365 }
366 else
367 {
368 if (ssegs) ss=oldss;
369 if (stack32)
370 {
371 writememw(ss,ESP-2,flags);
372 writememw(ss,ESP-4,CS);
373 writememw(ss,ESP-6,pc);
374 ESP-=6;
375 }
376 else
377 {
378 writememw(ss,((SP-2)&0xFFFF),flags);
379 writememw(ss,((SP-4)&0xFFFF),CS);
380 writememw(ss,((SP-6)&0xFFFF),pc);
381 SP-=6;
382 }
383 addr = (num << 2) + idt.base;
385 flags&=~I_FLAG;
386 flags&=~T_FLAG;
387 oxpc=pc;
388 pc=readmemw(0,addr);
389 loadcs(readmemw(0,addr+2));
390 }
391 cycles-=70;
392 trap = 0;
393 }
395 void x86illegal()
396 {
397 uint16_t addr;
398 pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode);
399 // if (output)
400 // {
401 // dumpregs();
402 // exit(-1);
403 // }
404 x86_int(6);
405 }
408 #define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
409 { \
410 x86_int(6); \
411 break; \
412 }
414 void rep386(int fv)
415 {
416 uint8_t temp;
417 uint32_t c;//=CX;
418 uint8_t temp2;
419 uint16_t tempw,tempw2,of;
420 uint32_t ipc=oldpc;//pc-1;
421 int changeds=0;
422 uint32_t oldds;
423 uint32_t rep32=op32;
424 uint32_t templ,templ2;
425 int tempz;
426 int tempi;
428 flags_rebuild();
429 of = flags;
430 // if (output) pclog("REP32 %04X %04X ",use32,rep32);
431 startrep:
432 temp=opcode2=readmemb(cs,pc); pc++;
433 // if (firstrepcycle && temp==0xA5) pclog("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI);
434 // if (output) pclog("REP %02X %04X\n",temp,ipc);
435 c=(rep32&0x200)?ECX:CX;
436 /* if (rep32 && (msw&1))
437 {
438 if (temp!=0x67 && temp!=0x66 && (rep32|temp)!=0x1AB && (rep32|temp)!=0x3AB) pclog("32-bit REP %03X %08X %04X:%06X\n",temp|rep32,c,CS,pc);
439 }*/
440 switch (temp|rep32)
441 {
442 case 0xC3: case 0x1C3: case 0x2C3: case 0x3C3:
443 pc--;
444 break;
445 case 0x08:
446 pc=ipc+1;
447 break;
448 case 0x26: case 0x126: case 0x226: case 0x326: /*ES:*/
449 oldds=ds;
450 ds=es;
451 rds=ES;
452 changeds=1;
453 goto startrep;
454 break;
455 case 0x2E: case 0x12E: case 0x22E: case 0x32E: /*CS:*/
456 oldds=ds;
457 ds=cs;
458 rds=CS;
459 changeds=1;
460 goto startrep;
461 break;
462 case 0x36: case 0x136: case 0x236: case 0x336: /*SS:*/
463 oldds=ds;
464 ds=ss;
465 rds=SS;
466 changeds=1;
467 goto startrep;
468 break;
469 case 0x3E: case 0x13E: case 0x23E: case 0x33E: /*DS:*/
470 oldds=ds;
471 ds=ds;
472 changeds=1;
473 goto startrep;
474 break;
475 case 0x64: case 0x164: case 0x264: case 0x364: /*FS:*/
476 oldds=ds;
477 ds=fs;
478 rds=FS;
479 changeds=1;
480 goto startrep;
481 case 0x65: case 0x165: case 0x265: case 0x365: /*GS:*/
482 oldds=ds;
483 ds=gs;
484 rds=GS;
485 changeds=1;
486 goto startrep;
487 case 0x66: case 0x166: case 0x266: case 0x366: /*Data size prefix*/
488 rep32^=0x100;
489 goto startrep;
490 case 0x67: case 0x167: case 0x267: case 0x367: /*Address size prefix*/
491 rep32^=0x200;
492 goto startrep;
493 case 0x6C: case 0x16C: /*REP INSB*/
494 if (c>0)
495 {
496 checkio_perm(DX);
497 temp2=inb(DX);
498 writememb(es,DI,temp2);
499 if (abrt) break;
500 if (flags&D_FLAG) DI--;
501 else DI++;
502 c--;
503 cycles-=15;
504 }
505 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
506 else firstrepcycle=1;
507 break;
508 case 0x26C: case 0x36C: /*REP INSB*/
509 if (c>0)
510 {
511 checkio_perm(DX);
512 temp2=inb(DX);
513 writememb(es,EDI,temp2);
514 if (abrt) break;
515 if (flags&D_FLAG) EDI--;
516 else EDI++;
517 c--;
518 cycles-=15;
519 }
520 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
521 else firstrepcycle=1;
522 break;
523 case 0x6D: /*REP INSW*/
524 if (c>0)
525 {
526 tempw=inw(DX);
527 writememw(es,DI,tempw);
528 if (abrt) break;
529 if (flags&D_FLAG) DI-=2;
530 else DI+=2;
531 c--;
532 cycles-=15;
533 }
534 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
535 else firstrepcycle=1;
536 break;
537 case 0x16D: /*REP INSL*/
538 if (c>0)
539 {
540 templ=inl(DX);
541 writememl(es,DI,templ);
542 if (abrt) break;
543 if (flags&D_FLAG) DI-=4;
544 else DI+=4;
545 c--;
546 cycles-=15;
547 }
548 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
549 else firstrepcycle=1;
550 break;
551 case 0x26D: /*REP INSW*/
552 if (c>0)
553 {
554 tempw=inw(DX);
555 writememw(es,EDI,tempw);
556 if (abrt) break;
557 if (flags&D_FLAG) EDI-=2;
558 else EDI+=2;
559 c--;
560 cycles-=15;
561 }
562 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
563 else firstrepcycle=1;
564 break;
565 case 0x36D: /*REP INSL*/
566 if (c>0)
567 {
568 templ=inl(DX);
569 writememl(es,EDI,templ);
570 if (abrt) break;
571 if (flags&D_FLAG) EDI-=4;
572 else EDI+=4;
573 c--;
574 cycles-=15;
575 }
576 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
577 else firstrepcycle=1;
578 break;
579 case 0x6E: case 0x16E: /*REP OUTSB*/
580 if (c>0)
581 {
582 temp2=readmemb(ds,SI);
583 if (abrt) break;
584 checkio_perm(DX);
585 outb(DX,temp2);
586 if (flags&D_FLAG) SI--;
587 else SI++;
588 c--;
589 cycles-=14;
590 }
591 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
592 else firstrepcycle=1;
593 break;
594 case 0x26E: case 0x36E: /*REP OUTSB*/
595 if (c>0)
596 {
597 temp2=readmemb(ds,ESI);
598 if (abrt) break;
599 checkio_perm(DX);
600 outb(DX,temp2);
601 if (flags&D_FLAG) ESI--;
602 else ESI++;
603 c--;
604 cycles-=14;
605 }
606 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
607 else firstrepcycle=1;
608 break;
609 case 0x6F: /*REP OUTSW*/
610 if (c>0)
611 {
612 tempw=readmemw(ds,SI);
613 if (abrt) break;
614 // pclog("OUTSW %04X -> %04X\n",SI,tempw);
615 outw(DX,tempw);
616 if (flags&D_FLAG) SI-=2;
617 else SI+=2;
618 c--;
619 cycles-=14;
620 }
621 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
622 else firstrepcycle=1;
623 break;
624 case 0x16F: /*REP OUTSL*/
625 if (c > 0)
626 {
627 templ = readmeml(ds, SI);
628 if (abrt) break;
629 outl(DX, templ);
630 if (flags & D_FLAG) SI -= 4;
631 else SI += 4;
632 c--;
633 cycles -= 14;
634 }
635 if (c > 0) { firstrepcycle = 0; pc = ipc; if (ssegs) ssegs++; }
636 else firstrepcycle = 1;
637 break;
638 case 0x26F: /*REP OUTSW*/
639 if (c>0)
640 {
641 tempw=readmemw(ds,ESI);
642 if (abrt) break;
643 outw(DX,tempw);
644 if (flags&D_FLAG) ESI-=2;
645 else ESI+=2;
646 c--;
647 cycles-=14;
648 }
649 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
650 else firstrepcycle=1;
651 break;
652 case 0x36F: /*REP OUTSL*/
653 if (c > 0)
654 {
655 templ = readmeml(ds, ESI);
656 if (abrt) break;
657 outl(DX, templ);
658 if (flags & D_FLAG) ESI -= 4;
659 else ESI += 4;
660 c--;
661 cycles -= 14;
662 }
663 if (c > 0) { firstrepcycle = 0; pc = ipc; if (ssegs) ssegs++; }
664 else firstrepcycle = 1;
665 break;
666 case 0x90: case 0x190: /*REP NOP*/
667 case 0x290: case 0x390:
668 break;
669 case 0xA4: case 0x1A4: /*REP MOVSB*/
670 if (c>0)
671 {
672 temp2=readmemb(ds,SI); if (abrt) break;
673 writememb(es,DI,temp2); if (abrt) break;
674 // if (output==3) pclog("MOVSB %08X:%04X -> %08X:%04X %02X\n",ds,SI,es,DI,temp2);
675 if (flags&D_FLAG) { DI--; SI--; }
676 else { DI++; SI++; }
677 c--;
678 cycles-=(is486)?3:4;
679 }
680 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
681 else firstrepcycle=1;
682 break;
683 case 0x2A4: case 0x3A4: /*REP MOVSB*/
684 if (c>0)
685 {
686 temp2=readmemb(ds,ESI); if (abrt) break;
687 writememb(es,EDI,temp2); if (abrt) break;
688 if (flags&D_FLAG) { EDI--; ESI--; }
689 else { EDI++; ESI++; }
690 c--;
691 cycles-=(is486)?3:4;
692 }
693 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
694 else firstrepcycle=1;
695 break;
696 case 0xA5: /*REP MOVSW*/
697 if (c>0)
698 {
699 tempw=readmemw(ds,SI); if (abrt) break;
700 writememw(es,DI,tempw); if (abrt) break;
701 if (flags&D_FLAG) { DI-=2; SI-=2; }
702 else { DI+=2; SI+=2; }
703 c--;
704 cycles-=(is486)?3:4;
705 }
706 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
707 else firstrepcycle=1;
708 break;
709 case 0x1A5: /*REP MOVSL*/
710 if (c>0)
711 {
712 templ=readmeml(ds,SI); if (abrt) break;
713 // pclog("MOVSD %08X from %08X to %08X (%04X:%08X)\n", templ, ds+SI, es+DI, CS, pc);
714 writememl(es,DI,templ); if (abrt) break;
715 if (flags&D_FLAG) { DI-=4; SI-=4; }
716 else { DI+=4; SI+=4; }
717 c--;
718 cycles-=(is486)?3:4;
719 }
720 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
721 else firstrepcycle=1;
722 break;
723 case 0x2A5: /*REP MOVSW*/
724 if (c>0)
725 {
726 tempw=readmemw(ds,ESI); if (abrt) break;
727 writememw(es,EDI,tempw); if (abrt) break;
728 // if (output) pclog("Written %04X from %08X to %08X %i %08X %04X %08X %04X\n",tempw,ds+ESI,es+EDI,c,ds,ES,es,ES);
729 if (flags&D_FLAG) { EDI-=2; ESI-=2; }
730 else { EDI+=2; ESI+=2; }
731 c--;
732 cycles-=(is486)?3:4;
733 }
734 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
735 else firstrepcycle=1;
736 break;
737 case 0x3A5: /*REP MOVSL*/
738 if (c>0)
739 {
740 templ=readmeml(ds,ESI); if (abrt) break;
741 // if ((EDI&0xFFFF0000)==0xA0000) cycles-=12;
742 writememl(es,EDI,templ); if (abrt) break;
743 // if (output) pclog("Load %08X from %08X to %08X %04X %08X %04X %08X\n",templ,ESI,EDI,DS,ds,ES,es);
744 if (flags&D_FLAG) { EDI-=4; ESI-=4; }
745 else { EDI+=4; ESI+=4; }
746 c--;
747 cycles-=(is486)?3:4;
748 }
749 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
750 else firstrepcycle=1;
751 break;
752 case 0xA6: case 0x1A6: /*REP CMPSB*/
753 tempz = (fv) ? 1 : 0;
754 if ((c>0) && (fv==tempz))
755 {
756 temp=readmemb(ds,SI);
757 temp2=readmemb(es,DI);
758 if (abrt) { flags=of; break; }
759 if (flags&D_FLAG) { DI--; SI--; }
760 else { DI++; SI++; }
761 c--;
762 cycles-=(is486)?7:9;
763 setsub8(temp,temp2);
764 tempz = (ZF_SET()) ? 1 : 0;
765 }
766 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
767 else firstrepcycle=1;
768 break;
769 case 0x2A6: case 0x3A6: /*REP CMPSB*/
770 tempz = (fv) ? 1 : 0;
771 if ((c>0) && (fv==tempz))
772 {
773 temp=readmemb(ds,ESI);
774 temp2=readmemb(es,EDI);
775 if (abrt) { flags=of; break; }
776 if (flags&D_FLAG) { EDI--; ESI--; }
777 else { EDI++; ESI++; }
778 c--;
779 cycles-=(is486)?7:9;
780 setsub8(temp,temp2);
781 tempz = (ZF_SET()) ? 1 : 0;
782 }
783 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
784 else firstrepcycle=1;
785 break;
786 case 0xA7: /*REP CMPSW*/
787 tempz = (fv) ? 1 : 0;
788 if ((c>0) && (fv==tempz))
789 {
790 // pclog("CMPSW %05X %05X %08X %08X ", ds+SI, es+DI, readlookup2[(ds+SI)>>12], readlookup2[(es+DI)>>12]);
791 tempw=readmemw(ds,SI);
792 tempw2=readmemw(es,DI);
793 // pclog("%04X %04X %02X\n", tempw, tempw2, ram[8]);
795 if (abrt) { flags=of; break; }
796 if (flags&D_FLAG) { DI-=2; SI-=2; }
797 else { DI+=2; SI+=2; }
798 c--;
799 cycles-=(is486)?7:9;
800 setsub16(tempw,tempw2);
801 tempz = (ZF_SET()) ? 1 : 0;
802 }
803 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
804 else firstrepcycle=1;
805 break;
806 case 0x1A7: /*REP CMPSL*/
807 tempz = (fv) ? 1 : 0;
808 if ((c>0) && (fv==tempz))
809 {
810 templ=readmeml(ds,SI);
811 templ2=readmeml(es,DI);
812 if (abrt) { flags=of; break; }
813 if (flags&D_FLAG) { DI-=4; SI-=4; }
814 else { DI+=4; SI+=4; }
815 c--;
816 cycles-=(is486)?7:9;
817 setsub32(templ,templ2);
818 tempz = (ZF_SET()) ? 1 : 0;
819 }
820 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
821 else firstrepcycle=1;
822 break;
823 case 0x2A7: /*REP CMPSW*/
824 tempz = (fv) ? 1 : 0;
825 if ((c>0) && (fv==tempz))
826 {
827 tempw=readmemw(ds,ESI);
828 tempw2=readmemw(es,EDI);
829 if (abrt) { flags=of; break; }
830 if (flags&D_FLAG) { EDI-=2; ESI-=2; }
831 else { EDI+=2; ESI+=2; }
832 c--;
833 cycles-=(is486)?7:9;
834 setsub16(tempw,tempw2);
835 tempz = (ZF_SET()) ? 1 : 0;
836 }
837 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
838 else firstrepcycle=1;
839 break;
840 case 0x3A7: /*REP CMPSL*/
841 tempz = (fv) ? 1 : 0;
842 if ((c>0) && (fv==tempz))
843 {
844 templ=readmeml(ds,ESI);
845 templ2=readmeml(es,EDI);
846 if (abrt) { flags=of; break; }
847 if (flags&D_FLAG) { EDI-=4; ESI-=4; }
848 else { EDI+=4; ESI+=4; }
849 c--;
850 cycles-=(is486)?7:9;
851 setsub32(templ,templ2);
852 tempz = (ZF_SET()) ? 1 : 0;
853 }
854 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
855 else firstrepcycle=1;
856 break;
858 case 0xAA: case 0x1AA: /*REP STOSB*/
859 if (c>0)
860 {
861 writememb(es,DI,AL);
862 if (abrt) break;
863 if (flags&D_FLAG) DI--;
864 else DI++;
865 c--;
866 cycles-=(is486)?4:5;
867 }
868 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
869 else firstrepcycle=1;
870 break;
871 case 0x2AA: case 0x3AA: /*REP STOSB*/
872 if (c>0)
873 {
874 writememb(es,EDI,AL);
875 if (abrt) break;
876 if (flags&D_FLAG) EDI--;
877 else EDI++;
878 c--;
879 cycles-=(is486)?4:5;
880 }
881 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
882 else firstrepcycle=1;
883 break;
884 case 0xAB: /*REP STOSW*/
885 if (c>0)
886 {
887 writememw(es,DI,AX);
888 if (abrt) break;
889 if (flags&D_FLAG) DI-=2;
890 else DI+=2;
891 c--;
892 cycles-=(is486)?4:5;
893 }
894 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
895 else firstrepcycle=1;
896 break;
897 case 0x2AB: /*REP STOSW*/
898 if (c>0)
899 {
900 writememw(es,EDI,AX);
901 if (abrt) break;
902 if (flags&D_FLAG) EDI-=2;
903 else EDI+=2;
904 c--;
905 cycles-=(is486)?4:5;
906 }
907 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
908 else firstrepcycle=1;
909 break;
910 case 0x1AB: /*REP STOSL*/
911 if (c>0)
912 {
913 writememl(es,DI,EAX);
914 if (abrt) break;
915 if (flags&D_FLAG) DI-=4;
916 else DI+=4;
917 c--;
918 cycles-=(is486)?4:5;
919 }
920 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
921 else firstrepcycle=1;
922 break;
923 case 0x3AB: /*REP STOSL*/
924 if (c>0)
925 {
926 writememl(es,EDI,EAX);
927 if (abrt) break;
928 if (flags&D_FLAG) EDI-=4;
929 else EDI+=4;
930 c--;
931 cycles-=(is486)?4:5;
932 }
933 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
934 else firstrepcycle=1;
935 break;
936 case 0xAC: case 0x1AC: /*REP LODSB*/
937 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
938 if (c>0)
939 {
940 AL=readmemb(ds,SI);
941 if (abrt) break;
942 if (flags&D_FLAG) SI--;
943 else SI++;
944 c--;
945 cycles-=5;
946 }
947 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
948 else firstrepcycle=1;
949 break;
950 case 0x2AC: case 0x3AC: /*REP LODSB*/
951 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
952 if (c>0)
953 {
954 AL=readmemb(ds,ESI);
955 if (abrt) break;
956 if (flags&D_FLAG) ESI--;
957 else ESI++;
958 c--;
959 cycles-=5;
960 }
961 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
962 else firstrepcycle=1;
963 break;
964 case 0xAD: /*REP LODSW*/
965 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
966 if (c>0)
967 {
968 AX=readmemw(ds,SI);
969 if (abrt) break;
970 if (flags&D_FLAG) SI-=2;
971 else SI+=2;
972 c--;
973 cycles-=5;
974 }
975 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
976 else firstrepcycle=1;
977 break;
978 case 0x1AD: /*REP LODSL*/
979 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
980 if (c>0)
981 {
982 EAX=readmeml(ds,SI);
983 if (abrt) break;
984 if (flags&D_FLAG) SI-=4;
985 else SI+=4;
986 c--;
987 cycles-=5;
988 }
989 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
990 else firstrepcycle=1;
991 break;
992 case 0x2AD: /*REP LODSW*/
993 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
994 if (c>0)
995 {
996 AX=readmemw(ds,ESI);
997 if (abrt) break;
998 if (flags&D_FLAG) ESI-=2;
999 else ESI+=2;
1000 c--;
1001 cycles-=5;
1003 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
1004 else firstrepcycle=1;
1005 break;
1006 case 0x3AD: /*REP LODSL*/
1007 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
1008 if (c>0)
1010 EAX=readmeml(ds,ESI);
1011 if (abrt) break;
1012 if (flags&D_FLAG) ESI-=4;
1013 else ESI+=4;
1014 c--;
1015 cycles-=5;
1017 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
1018 else firstrepcycle=1;
1019 break;
1020 case 0xAE: case 0x1AE: /*REP SCASB*/
1021 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
1022 // tempz=(fv)?1:0;
1023 tempz = (fv) ? 1 : 0;
1024 if ((c>0) && (fv==tempz))
1026 temp2=readmemb(es,DI);
1027 if (abrt) { flags=of; break; }
1028 setsub8(AL,temp2);
1029 tempz = (ZF_SET()) ? 1 : 0;
1030 if (flags&D_FLAG) DI--;
1031 else DI++;
1032 c--;
1033 cycles-=(is486)?5:8;
1035 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1036 else firstrepcycle=1;
1037 break;
1038 case 0x2AE: case 0x3AE: /*REP SCASB*/
1039 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
1040 // tempz=(fv)?1:0;
1041 tempz = (fv) ? 1 : 0;
1042 if ((c>0) && (fv==tempz))
1044 temp2=readmemb(es,EDI);
1045 if (abrt) { flags=of; break; }
1046 // if (output) pclog("Compare %02X,%02X\n",temp2,AL);
1047 setsub8(AL,temp2);
1048 tempz = (ZF_SET()) ? 1 : 0;
1049 if (flags&D_FLAG) EDI--;
1050 else EDI++;
1051 c--;
1052 cycles-=(is486)?5:8;
1054 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1055 else firstrepcycle=1;
1056 break;
1057 case 0xAF: /*REP SCASW*/
1058 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
1059 tempz = (fv) ? 1 : 0;
1060 if ((c>0) && (fv==tempz))
1062 tempw=readmemw(es,DI);
1063 if (abrt) { flags=of; break; }
1064 setsub16(AX,tempw);
1065 tempz = (ZF_SET()) ? 1 : 0;
1066 if (flags&D_FLAG) DI-=2;
1067 else DI+=2;
1068 c--;
1069 cycles-=(is486)?5:8;
1071 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1072 else firstrepcycle=1;
1073 break;
1074 case 0x1AF: /*REP SCASL*/
1075 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc);
1076 tempz = (fv) ? 1 : 0;
1077 if ((c>0) && (fv==tempz))
1079 templ=readmeml(es,DI);
1080 if (abrt) { flags=of; break; }
1081 setsub32(EAX,templ);
1082 tempz = (ZF_SET()) ? 1 : 0;
1083 if (flags&D_FLAG) DI-=4;
1084 else DI+=4;
1085 c--;
1086 cycles-=(is486)?5:8;
1088 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1089 else firstrepcycle=1;
1090 break;
1091 case 0x2AF: /*REP SCASW*/
1092 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
1093 tempz = (fv) ? 1 : 0;
1094 if ((c>0) && (fv==tempz))
1096 tempw=readmemw(es,EDI);
1097 if (abrt) { flags=of; break; }
1098 setsub16(AX,tempw);
1099 tempz = (ZF_SET()) ? 1 : 0;
1100 if (flags&D_FLAG) EDI-=2;
1101 else EDI+=2;
1102 c--;
1103 cycles-=(is486)?5:8;
1105 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1106 else firstrepcycle=1;
1107 break;
1108 case 0x3AF: /*REP SCASL*/
1109 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc);
1110 tempz = (fv) ? 1 : 0;
1111 if ((c>0) && (fv==tempz))
1113 templ=readmeml(es,EDI);
1114 if (abrt) { flags=of; break; }
1115 setsub32(EAX,templ);
1116 tempz = (ZF_SET()) ? 1 : 0;
1117 if (flags&D_FLAG) EDI-=4;
1118 else EDI+=4;
1119 c--;
1120 cycles-=(is486)?5:8;
1122 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1123 else firstrepcycle=1;
1124 break;
1127 default:
1128 pc=ipc;
1129 cycles-=20;
1130 pclog("Bad REP %02X %i\n", temp, rep32 >> 8);
1131 x86illegal();
1133 if (rep32&0x200) ECX=c;
1134 else CX=c;
1135 if (changeds) ds=oldds;
1136 // if (output) pclog("%03X %03X\n",rep32,use32);
1139 int checkio(int port)
1141 uint16_t t;
1142 uint8_t d;
1143 cpl_override = 1;
1144 t = readmemw(tr.base, 0x66);
1145 cpl_override = 0;
1146 // pclog("CheckIO 1 %08X\n",tr.base);
1147 if (abrt) return 0;
1148 // pclog("CheckIO %04X %01X %01X %02X %04X %04X %08X ",CS,CPL,IOPL,port,t,t+(port>>3),tr.base+t+(port>>3));
1149 if ((t+(port>>3))>tr.limit) return 1;
1150 cpl_override = 1;
1151 d = readmemb386l(0, tr.base + t + (port >> 3));
1152 // d=readmemb(tr.base,t+(port>>3));
1153 cpl_override = 0;
1154 // pclog("%02X %02X\n",d,d&(1<<(port&7)));
1155 return d&(1<<(port&7));
1158 #define getbytef() ((uint8_t)(fetchdat)); pc++
1159 #define getwordf() ((uint16_t)(fetchdat)); pc+=2
1160 #define getbyte2f() ((uint8_t)(fetchdat>>8)); pc++
1161 #define getword2f() ((uint16_t)(fetchdat>>8)); pc+=2
1162 int xout=0;
1165 #define divexcp() { \
1166 pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,pc); \
1167 x86_int(0); \
1170 void divl(uint32_t val)
1172 if (val==0)
1174 divexcp();
1175 return;
1177 uint64_t num=(((uint64_t)EDX)<<32)|EAX;
1178 uint64_t quo=num/val;
1179 uint32_t rem=num%val;
1180 uint32_t quo32=(uint32_t)(quo&0xFFFFFFFF);
1181 if (quo!=(uint64_t)quo32)
1183 divexcp();
1184 return;
1186 EDX=rem;
1187 EAX=quo32;
1189 void idivl(int32_t val)
1191 if (val==0)
1193 divexcp();
1194 return;
1196 int64_t num=(((uint64_t)EDX)<<32)|EAX;
1197 int64_t quo=num/val;
1198 int32_t rem=num%val;
1199 int32_t quo32=(int32_t)(quo&0xFFFFFFFF);
1200 if (quo!=(int64_t)quo32)
1202 divexcp();
1203 return;
1205 EDX=rem;
1206 EAX=quo32;
1210 void cpu_386_flags_extract()
1212 flags_extract();
1214 void cpu_386_flags_rebuild()
1216 flags_rebuild();
1219 int oldi;
1221 uint32_t testr[9];
1222 int dontprint=0;
1224 #undef NOTRM
1225 #define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
1226 { \
1227 x86_int(6); \
1228 return 0; \
1231 #include "386_ops.h"
1233 #undef NOTRM
1234 #define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
1235 { \
1236 x86_int(6); \
1237 break; \
1240 void exec386(int cycs)
1242 uint8_t temp;
1243 uint32_t addr;
1244 int tempi;
1245 int cycdiff;
1246 int oldcyc;
1248 cycles+=cycs;
1249 // output=3;
1250 while (cycles>0)
1252 cycdiff=0;
1253 oldcyc=cycles;
1254 timer_start_period(cycles);
1255 // pclog("%i %02X\n", ins, ram[8]);
1256 while (cycdiff<100)
1258 /* testr[0]=EAX; testr[1]=EBX; testr[2]=ECX; testr[3]=EDX;
1259 testr[4]=ESI; testr[5]=EDI; testr[6]=EBP; testr[7]=ESP;*/
1260 /* testr[8]=flags;*/
1261 // oldcs2=oldcs;
1262 // oldpc2=oldpc;
1263 opcode_realstart:
1264 oldcs=CS;
1265 oldpc=pc;
1266 oldcpl=CPL;
1267 op32=use32;
1269 dontprint=0;
1271 opcodestart:
1272 fetchdat = fastreadl(cs + pc);
1273 if (!abrt)
1275 tempc = CF_SET();
1276 trap = flags & T_FLAG;
1277 opcode = fetchdat & 0xFF;
1278 fetchdat >>= 8;
1280 if (output == 3)
1282 pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X %02X%02X %02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0xB270+0x3F5], ram[0xB270+0x3F4], ram[0xB270+0x3F7], ram[0xB270+0x3F6], ram[0xB270+0x3F9], ram[0xB270+0x3F8], ram[0x4430+0x0D49]);
1284 pc++;
1285 if (x86_opcodes[(opcode | op32) & 0x3ff](fetchdat))
1286 goto opcodestart;
1289 if (!use32) pc &= 0xffff;
1290 /* if (ins == 74400000)
1292 pclog("Output on\n");
1293 output = 3;
1294 }*/
1295 if ((cs + pc) == 0xc)
1296 fatal("Dead\n");
1297 if (ssegs)
1299 ds=oldds;
1300 ss=oldss;
1301 rds=DS;
1302 ssegs=0;
1304 if (abrt)
1306 flags_rebuild();
1307 // pclog("Abort\n");
1308 // if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,abrt);
1309 /* if (testr[0]!=EAX) pclog("EAX corrupted %08X\n",pc);
1310 if (testr[1]!=EBX) pclog("EBX corrupted %08X\n",pc);
1311 if (testr[2]!=ECX) pclog("ECX corrupted %08X\n",pc);
1312 if (testr[3]!=EDX) pclog("EDX corrupted %08X\n",pc);
1313 if (testr[4]!=ESI) pclog("ESI corrupted %08X\n",pc);
1314 if (testr[5]!=EDI) pclog("EDI corrupted %08X\n",pc);
1315 if (testr[6]!=EBP) pclog("EBP corrupted %08X\n",pc);
1316 if (testr[7]!=ESP) pclog("ESP corrupted %08X\n",pc);*/
1317 /* if (testr[8]!=flags) pclog("FLAGS corrupted %08X\n",pc);*/
1318 tempi = abrt;
1319 abrt = 0;
1320 x86_doabrt(tempi);
1321 if (abrt)
1323 abrt = 0;
1324 CS = oldcs;
1325 pc = oldpc;
1326 pclog("Double fault %i\n", ins);
1327 pmodeint(8, 0);
1328 if (abrt)
1330 abrt = 0;
1331 softresetx86();
1332 pclog("Triple fault - reset\n");
1336 cycdiff=oldcyc-cycles;
1338 if (trap)
1340 flags_rebuild();
1341 // oldpc=pc;
1342 // oldcs=CS;
1343 if (msw&1)
1345 pmodeint(1,0);
1347 else
1349 writememw(ss,(SP-2)&0xFFFF,flags);
1350 writememw(ss,(SP-4)&0xFFFF,CS);
1351 writememw(ss,(SP-6)&0xFFFF,pc);
1352 SP-=6;
1353 addr = (1 << 2) + idt.base;
1354 flags&=~I_FLAG;
1355 flags&=~T_FLAG;
1356 pc=readmemw(0,addr);
1357 loadcs(readmemw(0,addr+2));
1360 else if (nmi && nmi_enable)
1362 oldpc = pc;
1363 oldcs = CS;
1364 // pclog("NMI\n");
1365 x86_int(2);
1366 nmi_enable = 0;
1368 else if ((flags&I_FLAG) && pic_intpending)
1370 temp=picinterrupt();
1371 if (temp!=0xFF)
1373 // if (temp == 0x54) pclog("Take int 54\n");
1374 // if (output) output=3;
1375 // if (temp == 0xd) pclog("Hardware int %02X %i %04X(%08X):%08X\n",temp,ins, CS,cs,pc);
1376 // if (temp==0x54) output=3;
1377 flags_rebuild();
1378 if (msw&1)
1380 pmodeint(temp,0);
1382 else
1384 writememw(ss,(SP-2)&0xFFFF,flags);
1385 writememw(ss,(SP-4)&0xFFFF,CS);
1386 writememw(ss,(SP-6)&0xFFFF,pc);
1387 SP-=6;
1388 addr = (temp << 2) + idt.base;
1389 flags&=~I_FLAG;
1390 flags&=~T_FLAG;
1391 oxpc=pc;
1392 pc=readmemw(0,addr);
1393 loadcs(readmemw(0,addr+2));
1394 // if (temp==0x76) pclog("INT to %04X:%04X\n",CS,pc);
1396 // pclog("Now at %04X(%08X):%08X\n", CS, cs, pc);
1400 // tempi = ZF_SET() ? Z_FLAG : 0;
1401 // if (tempi != (flags & Z_FLAG))
1402 // fatal("Z flag mismatch %02X %08X\n", opcode, fetchdat);
1403 ins++;
1404 insc++;
1405 /*output = 3;
1406 if (ins == 1372108)
1407 fatal("here2\n");
1408 if (ins == 50966339)
1409 fatal("here\n");*/
1410 if (timetolive)
1412 timetolive--;
1413 if (!timetolive)
1414 fatal("Life expired\n");
1416 // if (ins == 97300000) output = 3;
1419 tsc += cycdiff;
1421 timer_end_period(cycles);