PCem

view src/386.c @ 111:912e602b3406

Moved PIT to common timer API.
author TomW
date Thu Jun 19 21:02:59 2014 +0100
parents eb624a751863
children 07168c9bdd22
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 0xA4: case 0x1A4: /*REP MOVSB*/
667 if (c>0)
668 {
669 temp2=readmemb(ds,SI); if (abrt) break;
670 writememb(es,DI,temp2); if (abrt) break;
671 // if (output==3) pclog("MOVSB %08X:%04X -> %08X:%04X %02X\n",ds,SI,es,DI,temp2);
672 if (flags&D_FLAG) { DI--; SI--; }
673 else { DI++; SI++; }
674 c--;
675 cycles-=(is486)?3:4;
676 }
677 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
678 else firstrepcycle=1;
679 break;
680 case 0x2A4: case 0x3A4: /*REP MOVSB*/
681 if (c>0)
682 {
683 temp2=readmemb(ds,ESI); if (abrt) break;
684 writememb(es,EDI,temp2); if (abrt) break;
685 if (flags&D_FLAG) { EDI--; ESI--; }
686 else { EDI++; ESI++; }
687 c--;
688 cycles-=(is486)?3:4;
689 }
690 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
691 else firstrepcycle=1;
692 break;
693 case 0xA5: /*REP MOVSW*/
694 if (c>0)
695 {
696 tempw=readmemw(ds,SI); if (abrt) break;
697 writememw(es,DI,tempw); if (abrt) break;
698 if (flags&D_FLAG) { DI-=2; SI-=2; }
699 else { DI+=2; SI+=2; }
700 c--;
701 cycles-=(is486)?3:4;
702 }
703 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
704 else firstrepcycle=1;
705 break;
706 case 0x1A5: /*REP MOVSL*/
707 if (c>0)
708 {
709 templ=readmeml(ds,SI); if (abrt) break;
710 // pclog("MOVSD %08X from %08X to %08X (%04X:%08X)\n", templ, ds+SI, es+DI, CS, pc);
711 writememl(es,DI,templ); if (abrt) break;
712 if (flags&D_FLAG) { DI-=4; SI-=4; }
713 else { DI+=4; SI+=4; }
714 c--;
715 cycles-=(is486)?3:4;
716 }
717 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
718 else firstrepcycle=1;
719 break;
720 case 0x2A5: /*REP MOVSW*/
721 if (c>0)
722 {
723 tempw=readmemw(ds,ESI); if (abrt) break;
724 writememw(es,EDI,tempw); if (abrt) break;
725 // 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);
726 if (flags&D_FLAG) { EDI-=2; ESI-=2; }
727 else { EDI+=2; ESI+=2; }
728 c--;
729 cycles-=(is486)?3:4;
730 }
731 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
732 else firstrepcycle=1;
733 break;
734 case 0x3A5: /*REP MOVSL*/
735 if (c>0)
736 {
737 templ=readmeml(ds,ESI); if (abrt) break;
738 // if ((EDI&0xFFFF0000)==0xA0000) cycles-=12;
739 writememl(es,EDI,templ); if (abrt) break;
740 // if (output) pclog("Load %08X from %08X to %08X %04X %08X %04X %08X\n",templ,ESI,EDI,DS,ds,ES,es);
741 if (flags&D_FLAG) { EDI-=4; ESI-=4; }
742 else { EDI+=4; ESI+=4; }
743 c--;
744 cycles-=(is486)?3:4;
745 }
746 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
747 else firstrepcycle=1;
748 break;
749 case 0xA6: case 0x1A6: /*REP CMPSB*/
750 tempz = (fv) ? 1 : 0;
751 if ((c>0) && (fv==tempz))
752 {
753 temp=readmemb(ds,SI);
754 temp2=readmemb(es,DI);
755 if (abrt) { flags=of; break; }
756 if (flags&D_FLAG) { DI--; SI--; }
757 else { DI++; SI++; }
758 c--;
759 cycles-=(is486)?7:9;
760 setsub8(temp,temp2);
761 tempz = (ZF_SET()) ? 1 : 0;
762 }
763 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
764 else firstrepcycle=1;
765 break;
766 case 0x2A6: case 0x3A6: /*REP CMPSB*/
767 tempz = (fv) ? 1 : 0;
768 if ((c>0) && (fv==tempz))
769 {
770 temp=readmemb(ds,ESI);
771 temp2=readmemb(es,EDI);
772 if (abrt) { flags=of; break; }
773 if (flags&D_FLAG) { EDI--; ESI--; }
774 else { EDI++; ESI++; }
775 c--;
776 cycles-=(is486)?7:9;
777 setsub8(temp,temp2);
778 tempz = (ZF_SET()) ? 1 : 0;
779 }
780 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
781 else firstrepcycle=1;
782 break;
783 case 0xA7: /*REP CMPSW*/
784 tempz = (fv) ? 1 : 0;
785 if ((c>0) && (fv==tempz))
786 {
787 // pclog("CMPSW %05X %05X %08X %08X ", ds+SI, es+DI, readlookup2[(ds+SI)>>12], readlookup2[(es+DI)>>12]);
788 tempw=readmemw(ds,SI);
789 tempw2=readmemw(es,DI);
790 // pclog("%04X %04X %02X\n", tempw, tempw2, ram[8]);
792 if (abrt) { flags=of; break; }
793 if (flags&D_FLAG) { DI-=2; SI-=2; }
794 else { DI+=2; SI+=2; }
795 c--;
796 cycles-=(is486)?7:9;
797 setsub16(tempw,tempw2);
798 tempz = (ZF_SET()) ? 1 : 0;
799 }
800 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
801 else firstrepcycle=1;
802 break;
803 case 0x1A7: /*REP CMPSL*/
804 tempz = (fv) ? 1 : 0;
805 if ((c>0) && (fv==tempz))
806 {
807 templ=readmeml(ds,SI);
808 templ2=readmeml(es,DI);
809 if (abrt) { flags=of; break; }
810 if (flags&D_FLAG) { DI-=4; SI-=4; }
811 else { DI+=4; SI+=4; }
812 c--;
813 cycles-=(is486)?7:9;
814 setsub32(templ,templ2);
815 tempz = (ZF_SET()) ? 1 : 0;
816 }
817 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
818 else firstrepcycle=1;
819 break;
820 case 0x2A7: /*REP CMPSW*/
821 tempz = (fv) ? 1 : 0;
822 if ((c>0) && (fv==tempz))
823 {
824 tempw=readmemw(ds,ESI);
825 tempw2=readmemw(es,EDI);
826 if (abrt) { flags=of; break; }
827 if (flags&D_FLAG) { EDI-=2; ESI-=2; }
828 else { EDI+=2; ESI+=2; }
829 c--;
830 cycles-=(is486)?7:9;
831 setsub16(tempw,tempw2);
832 tempz = (ZF_SET()) ? 1 : 0;
833 }
834 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
835 else firstrepcycle=1;
836 break;
837 case 0x3A7: /*REP CMPSL*/
838 tempz = (fv) ? 1 : 0;
839 if ((c>0) && (fv==tempz))
840 {
841 templ=readmeml(ds,ESI);
842 templ2=readmeml(es,EDI);
843 if (abrt) { flags=of; break; }
844 if (flags&D_FLAG) { EDI-=4; ESI-=4; }
845 else { EDI+=4; ESI+=4; }
846 c--;
847 cycles-=(is486)?7:9;
848 setsub32(templ,templ2);
849 tempz = (ZF_SET()) ? 1 : 0;
850 }
851 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
852 else firstrepcycle=1;
853 break;
855 case 0xAA: case 0x1AA: /*REP STOSB*/
856 if (c>0)
857 {
858 writememb(es,DI,AL);
859 if (abrt) break;
860 if (flags&D_FLAG) DI--;
861 else DI++;
862 c--;
863 cycles-=(is486)?4:5;
864 }
865 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
866 else firstrepcycle=1;
867 break;
868 case 0x2AA: case 0x3AA: /*REP STOSB*/
869 if (c>0)
870 {
871 writememb(es,EDI,AL);
872 if (abrt) break;
873 if (flags&D_FLAG) EDI--;
874 else EDI++;
875 c--;
876 cycles-=(is486)?4:5;
877 }
878 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
879 else firstrepcycle=1;
880 break;
881 case 0xAB: /*REP STOSW*/
882 if (c>0)
883 {
884 writememw(es,DI,AX);
885 if (abrt) break;
886 if (flags&D_FLAG) DI-=2;
887 else DI+=2;
888 c--;
889 cycles-=(is486)?4:5;
890 }
891 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
892 else firstrepcycle=1;
893 break;
894 case 0x2AB: /*REP STOSW*/
895 if (c>0)
896 {
897 writememw(es,EDI,AX);
898 if (abrt) break;
899 if (flags&D_FLAG) EDI-=2;
900 else EDI+=2;
901 c--;
902 cycles-=(is486)?4:5;
903 }
904 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
905 else firstrepcycle=1;
906 break;
907 case 0x1AB: /*REP STOSL*/
908 if (c>0)
909 {
910 writememl(es,DI,EAX);
911 if (abrt) break;
912 if (flags&D_FLAG) DI-=4;
913 else DI+=4;
914 c--;
915 cycles-=(is486)?4:5;
916 }
917 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
918 else firstrepcycle=1;
919 break;
920 case 0x3AB: /*REP STOSL*/
921 if (c>0)
922 {
923 writememl(es,EDI,EAX);
924 if (abrt) break;
925 if (flags&D_FLAG) EDI-=4;
926 else EDI+=4;
927 c--;
928 cycles-=(is486)?4:5;
929 }
930 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
931 else firstrepcycle=1;
932 break;
933 case 0xAC: case 0x1AC: /*REP LODSB*/
934 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
935 if (c>0)
936 {
937 AL=readmemb(ds,SI);
938 if (abrt) break;
939 if (flags&D_FLAG) SI--;
940 else SI++;
941 c--;
942 cycles-=5;
943 }
944 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
945 else firstrepcycle=1;
946 break;
947 case 0x2AC: case 0x3AC: /*REP LODSB*/
948 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
949 if (c>0)
950 {
951 AL=readmemb(ds,ESI);
952 if (abrt) break;
953 if (flags&D_FLAG) ESI--;
954 else ESI++;
955 c--;
956 cycles-=5;
957 }
958 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
959 else firstrepcycle=1;
960 break;
961 case 0xAD: /*REP LODSW*/
962 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
963 if (c>0)
964 {
965 AX=readmemw(ds,SI);
966 if (abrt) break;
967 if (flags&D_FLAG) SI-=2;
968 else SI+=2;
969 c--;
970 cycles-=5;
971 }
972 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
973 else firstrepcycle=1;
974 break;
975 case 0x1AD: /*REP LODSL*/
976 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
977 if (c>0)
978 {
979 EAX=readmeml(ds,SI);
980 if (abrt) break;
981 if (flags&D_FLAG) SI-=4;
982 else SI+=4;
983 c--;
984 cycles-=5;
985 }
986 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
987 else firstrepcycle=1;
988 break;
989 case 0x2AD: /*REP LODSW*/
990 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
991 if (c>0)
992 {
993 AX=readmemw(ds,ESI);
994 if (abrt) break;
995 if (flags&D_FLAG) ESI-=2;
996 else ESI+=2;
997 c--;
998 cycles-=5;
999 }
1000 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
1001 else firstrepcycle=1;
1002 break;
1003 case 0x3AD: /*REP LODSL*/
1004 // if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
1005 if (c>0)
1007 EAX=readmeml(ds,ESI);
1008 if (abrt) break;
1009 if (flags&D_FLAG) ESI-=4;
1010 else ESI+=4;
1011 c--;
1012 cycles-=5;
1014 if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
1015 else firstrepcycle=1;
1016 break;
1017 case 0xAE: case 0x1AE: /*REP SCASB*/
1018 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
1019 // tempz=(fv)?1:0;
1020 tempz = (fv) ? 1 : 0;
1021 if ((c>0) && (fv==tempz))
1023 temp2=readmemb(es,DI);
1024 if (abrt) { flags=of; break; }
1025 setsub8(AL,temp2);
1026 tempz = (ZF_SET()) ? 1 : 0;
1027 if (flags&D_FLAG) DI--;
1028 else DI++;
1029 c--;
1030 cycles-=(is486)?5:8;
1032 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1033 else firstrepcycle=1;
1034 break;
1035 case 0x2AE: case 0x3AE: /*REP SCASB*/
1036 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
1037 // tempz=(fv)?1:0;
1038 tempz = (fv) ? 1 : 0;
1039 if ((c>0) && (fv==tempz))
1041 temp2=readmemb(es,EDI);
1042 if (abrt) { flags=of; break; }
1043 // if (output) pclog("Compare %02X,%02X\n",temp2,AL);
1044 setsub8(AL,temp2);
1045 tempz = (ZF_SET()) ? 1 : 0;
1046 if (flags&D_FLAG) EDI--;
1047 else EDI++;
1048 c--;
1049 cycles-=(is486)?5:8;
1051 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1052 else firstrepcycle=1;
1053 break;
1054 case 0xAF: /*REP SCASW*/
1055 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
1056 tempz = (fv) ? 1 : 0;
1057 if ((c>0) && (fv==tempz))
1059 tempw=readmemw(es,DI);
1060 if (abrt) { flags=of; break; }
1061 setsub16(AX,tempw);
1062 tempz = (ZF_SET()) ? 1 : 0;
1063 if (flags&D_FLAG) DI-=2;
1064 else DI+=2;
1065 c--;
1066 cycles-=(is486)?5:8;
1068 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1069 else firstrepcycle=1;
1070 break;
1071 case 0x1AF: /*REP SCASL*/
1072 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc);
1073 tempz = (fv) ? 1 : 0;
1074 if ((c>0) && (fv==tempz))
1076 templ=readmeml(es,DI);
1077 if (abrt) { flags=of; break; }
1078 setsub32(EAX,templ);
1079 tempz = (ZF_SET()) ? 1 : 0;
1080 if (flags&D_FLAG) DI-=4;
1081 else DI+=4;
1082 c--;
1083 cycles-=(is486)?5:8;
1085 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1086 else firstrepcycle=1;
1087 break;
1088 case 0x2AF: /*REP SCASW*/
1089 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
1090 tempz = (fv) ? 1 : 0;
1091 if ((c>0) && (fv==tempz))
1093 tempw=readmemw(es,EDI);
1094 if (abrt) { flags=of; break; }
1095 setsub16(AX,tempw);
1096 tempz = (ZF_SET()) ? 1 : 0;
1097 if (flags&D_FLAG) EDI-=2;
1098 else EDI+=2;
1099 c--;
1100 cycles-=(is486)?5:8;
1102 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1103 else firstrepcycle=1;
1104 break;
1105 case 0x3AF: /*REP SCASL*/
1106 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc);
1107 tempz = (fv) ? 1 : 0;
1108 if ((c>0) && (fv==tempz))
1110 templ=readmeml(es,EDI);
1111 if (abrt) { flags=of; break; }
1112 setsub32(EAX,templ);
1113 tempz = (ZF_SET()) ? 1 : 0;
1114 if (flags&D_FLAG) EDI-=4;
1115 else EDI+=4;
1116 c--;
1117 cycles-=(is486)?5:8;
1119 if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
1120 else firstrepcycle=1;
1121 break;
1124 default:
1125 pc=ipc;
1126 cycles-=20;
1127 pclog("Bad REP %02X %i\n", temp, rep32 >> 8);
1128 x86illegal();
1130 if (rep32&0x200) ECX=c;
1131 else CX=c;
1132 if (changeds) ds=oldds;
1133 // if (output) pclog("%03X %03X\n",rep32,use32);
1136 int checkio(int port)
1138 uint16_t t;
1139 uint8_t d;
1140 cpl_override = 1;
1141 t = readmemw(tr.base, 0x66);
1142 cpl_override = 0;
1143 // pclog("CheckIO 1 %08X\n",tr.base);
1144 if (abrt) return 0;
1145 // pclog("CheckIO %04X %01X %01X %02X %04X %04X %08X ",CS,CPL,IOPL,port,t,t+(port>>3),tr.base+t+(port>>3));
1146 if ((t+(port>>3))>tr.limit) return 1;
1147 cpl_override = 1;
1148 d = readmemb386l(0, tr.base + t + (port >> 3));
1149 // d=readmemb(tr.base,t+(port>>3));
1150 cpl_override = 0;
1151 // pclog("%02X %02X\n",d,d&(1<<(port&7)));
1152 return d&(1<<(port&7));
1155 #define getbytef() ((uint8_t)(fetchdat)); pc++
1156 #define getwordf() ((uint16_t)(fetchdat)); pc+=2
1157 #define getbyte2f() ((uint8_t)(fetchdat>>8)); pc++
1158 #define getword2f() ((uint16_t)(fetchdat>>8)); pc+=2
1159 int xout=0;
1162 #define divexcp() { \
1163 pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,pc); \
1164 x86_int(0); \
1167 void divl(uint32_t val)
1169 if (val==0)
1171 divexcp();
1172 return;
1174 uint64_t num=(((uint64_t)EDX)<<32)|EAX;
1175 uint64_t quo=num/val;
1176 uint32_t rem=num%val;
1177 uint32_t quo32=(uint32_t)(quo&0xFFFFFFFF);
1178 if (quo!=(uint64_t)quo32)
1180 divexcp();
1181 return;
1183 EDX=rem;
1184 EAX=quo32;
1186 void idivl(int32_t val)
1188 if (val==0)
1190 divexcp();
1191 return;
1193 int64_t num=(((uint64_t)EDX)<<32)|EAX;
1194 int64_t quo=num/val;
1195 int32_t rem=num%val;
1196 int32_t quo32=(int32_t)(quo&0xFFFFFFFF);
1197 if (quo!=(int64_t)quo32)
1199 divexcp();
1200 return;
1202 EDX=rem;
1203 EAX=quo32;
1207 void cpu_386_flags_extract()
1209 flags_extract();
1211 void cpu_386_flags_rebuild()
1213 flags_rebuild();
1216 int oldi;
1218 uint32_t testr[9];
1219 int dontprint=0;
1221 #undef NOTRM
1222 #define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
1223 { \
1224 x86_int(6); \
1225 return 0; \
1228 #include "386_ops.h"
1230 #undef NOTRM
1231 #define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
1232 { \
1233 x86_int(6); \
1234 break; \
1237 void exec386(int cycs)
1239 uint8_t temp;
1240 uint32_t addr;
1241 int tempi;
1242 int cycdiff;
1243 int oldcyc;
1245 cycles+=cycs;
1246 // output=3;
1247 while (cycles>0)
1249 cycdiff=0;
1250 oldcyc=cycles;
1251 timer_start_period(cycles);
1252 // pclog("%i %02X\n", ins, ram[8]);
1253 while (cycdiff<100)
1255 /* testr[0]=EAX; testr[1]=EBX; testr[2]=ECX; testr[3]=EDX;
1256 testr[4]=ESI; testr[5]=EDI; testr[6]=EBP; testr[7]=ESP;*/
1257 /* testr[8]=flags;*/
1258 // oldcs2=oldcs;
1259 // oldpc2=oldpc;
1260 opcode_realstart:
1261 oldcs=CS;
1262 oldpc=pc;
1263 oldcpl=CPL;
1264 op32=use32;
1266 dontprint=0;
1268 opcodestart:
1269 fetchdat = fastreadl(cs + pc);
1270 if (!abrt)
1272 tempc = CF_SET();
1273 trap = flags & T_FLAG;
1274 opcode = fetchdat & 0xFF;
1275 fetchdat >>= 8;
1277 if (output == 3)
1279 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]);
1281 pc++;
1282 if (x86_opcodes[(opcode | op32) & 0x3ff](fetchdat))
1283 goto opcodestart;
1286 if (!use32) pc &= 0xffff;
1287 /* if (ins == 74400000)
1289 pclog("Output on\n");
1290 output = 3;
1291 }*/
1292 if ((cs + pc) == 0xc)
1293 fatal("Dead\n");
1294 if (ssegs)
1296 ds=oldds;
1297 ss=oldss;
1298 rds=DS;
1299 ssegs=0;
1301 if (abrt)
1303 flags_rebuild();
1304 // pclog("Abort\n");
1305 // if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,abrt);
1306 /* if (testr[0]!=EAX) pclog("EAX corrupted %08X\n",pc);
1307 if (testr[1]!=EBX) pclog("EBX corrupted %08X\n",pc);
1308 if (testr[2]!=ECX) pclog("ECX corrupted %08X\n",pc);
1309 if (testr[3]!=EDX) pclog("EDX corrupted %08X\n",pc);
1310 if (testr[4]!=ESI) pclog("ESI corrupted %08X\n",pc);
1311 if (testr[5]!=EDI) pclog("EDI corrupted %08X\n",pc);
1312 if (testr[6]!=EBP) pclog("EBP corrupted %08X\n",pc);
1313 if (testr[7]!=ESP) pclog("ESP corrupted %08X\n",pc);*/
1314 /* if (testr[8]!=flags) pclog("FLAGS corrupted %08X\n",pc);*/
1315 tempi = abrt;
1316 abrt = 0;
1317 x86_doabrt(tempi);
1318 if (abrt)
1320 abrt = 0;
1321 CS = oldcs;
1322 pc = oldpc;
1323 pclog("Double fault %i\n", ins);
1324 pmodeint(8, 0);
1325 if (abrt)
1327 abrt = 0;
1328 softresetx86();
1329 pclog("Triple fault - reset\n");
1333 cycdiff=oldcyc-cycles;
1335 if (trap)
1337 flags_rebuild();
1338 // oldpc=pc;
1339 // oldcs=CS;
1340 if (msw&1)
1342 pmodeint(1,0);
1344 else
1346 writememw(ss,(SP-2)&0xFFFF,flags);
1347 writememw(ss,(SP-4)&0xFFFF,CS);
1348 writememw(ss,(SP-6)&0xFFFF,pc);
1349 SP-=6;
1350 addr = (1 << 2) + idt.base;
1351 flags&=~I_FLAG;
1352 flags&=~T_FLAG;
1353 pc=readmemw(0,addr);
1354 loadcs(readmemw(0,addr+2));
1357 else if (nmi && nmi_enable)
1359 oldpc = pc;
1360 oldcs = CS;
1361 // pclog("NMI\n");
1362 x86_int(2);
1363 nmi_enable = 0;
1365 else if ((flags&I_FLAG) && pic_intpending)
1367 temp=picinterrupt();
1368 if (temp!=0xFF)
1370 // if (temp == 0x54) pclog("Take int 54\n");
1371 // if (output) output=3;
1372 // if (temp == 0xd) pclog("Hardware int %02X %i %04X(%08X):%08X\n",temp,ins, CS,cs,pc);
1373 // if (temp==0x54) output=3;
1374 flags_rebuild();
1375 if (msw&1)
1377 pmodeint(temp,0);
1379 else
1381 writememw(ss,(SP-2)&0xFFFF,flags);
1382 writememw(ss,(SP-4)&0xFFFF,CS);
1383 writememw(ss,(SP-6)&0xFFFF,pc);
1384 SP-=6;
1385 addr = (temp << 2) + idt.base;
1386 flags&=~I_FLAG;
1387 flags&=~T_FLAG;
1388 oxpc=pc;
1389 pc=readmemw(0,addr);
1390 loadcs(readmemw(0,addr+2));
1391 // if (temp==0x76) pclog("INT to %04X:%04X\n",CS,pc);
1393 // pclog("Now at %04X(%08X):%08X\n", CS, cs, pc);
1397 // tempi = ZF_SET() ? Z_FLAG : 0;
1398 // if (tempi != (flags & Z_FLAG))
1399 // fatal("Z flag mismatch %02X %08X\n", opcode, fetchdat);
1400 ins++;
1401 insc++;
1402 /*output = 3;
1403 if (ins == 1372108)
1404 fatal("here2\n");
1405 if (ins == 50966339)
1406 fatal("here\n");*/
1407 if (timetolive)
1409 timetolive--;
1410 if (!timetolive)
1411 fatal("Life expired\n");
1413 // if (ins == 97300000) output = 3;
1416 tsc += cycdiff;
1418 timer_end_period(cycles);