PCem

view src/808x.c @ 164:9a88154e8608

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