PCem
changeset 2:9c201151bb4b
Add missing files from last commit.
line diff
1.1 --- a/src/286.c Mon May 27 17:46:42 2013 +0100 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,3787 +0,0 @@ 1.4 -#include "ibm.h" 1.5 -#include "x86.h" 1.6 -#include "x86_flags.h" 1.7 -#include "cpu.h" 1.8 -#include "pit.h" 1.9 -#include "keyboard.h" 1.10 - 1.11 -#define getword getword286 1.12 - 1.13 -#define checkio_perm(port) if (!IOPLp) \ 1.14 - { \ 1.15 - x86gpf(NULL,0); \ 1.16 - break; \ 1.17 - } 1.18 - 1.19 -#undef readmemb 1.20 -#undef writememb 1.21 - 1.22 -#define readmemb(s,a) ((readlookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF)?readmemb386l(s,a):ram[readlookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]) 1.23 -#define writememb(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememb386l(s,a,v); else ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]=v 1.24 -#define writememw(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) writememwl(s,a,v); else *((uint16_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v 1.25 - 1.26 -extern int keywaiting; 1.27 - 1.28 -#define checklimit(a) 1.29 - 1.30 -/*#define checklimit(a) if (msw&1 && (a)) \ 1.31 - { \ 1.32 - pclog("Seg limit GPF at %04X:%04X\n",CS,pc); \ 1.33 - pclog("%04X %04X %04X %i %04X %04X\n", ealimitw, ealimit, eaaddr, mod, _ds.limit, _ss.limit); \ 1.34 - x86gpf(NULL,0); \ 1.35 - break; \ 1.36 - }*/ 1.37 - 1.38 -#define NOTRM if (!(msw & 1))\ 1.39 - { \ 1.40 - x86_int(6); \ 1.41 - break; \ 1.42 - } 1.43 - 1.44 - 1.45 -static inline uint8_t geteab() 1.46 -{ 1.47 - if (mod==3) 1.48 - return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l; 1.49 -// cycles-=3; 1.50 - return readmemb(easeg, eaaddr); 1.51 -} 1.52 - 1.53 -static inline uint16_t geteaw() 1.54 -{ 1.55 - if (mod==3) 1.56 - return regs[rm].w; 1.57 -// cycles-=3; 1.58 -// if (output==3) printf("GETEAW %04X:%08X\n",easeg,eaaddr); 1.59 - return readmemw(easeg, eaaddr); 1.60 -} 1.61 - 1.62 -static inline uint16_t geteaw2() 1.63 -{ 1.64 - if (mod==3) 1.65 - return regs[rm].w; 1.66 -// cycles-=2; 1.67 -// printf("Getting addr from %04X:%04X %05X\n",easeg,eaaddr+2,easeg+eaaddr+2); 1.68 - return readmemw(easeg,(eaaddr+2)&0xFFFF); 1.69 -} 1.70 - 1.71 -static inline void seteab(uint8_t val) 1.72 -{ 1.73 - if (mod==3) 1.74 - { 1.75 - if (rm&4) regs[rm&3].b.h=val; 1.76 - else regs[rm&3].b.l=val; 1.77 - } 1.78 - else 1.79 - { 1.80 -// cycles-=2; 1.81 - writememb(easeg, eaaddr, val); 1.82 - } 1.83 -} 1.84 - 1.85 -static inline void seteaw(uint16_t val) 1.86 -{ 1.87 - if (mod==3) 1.88 - regs[rm].w=val; 1.89 - else 1.90 - { 1.91 -// cycles-=2; 1.92 - writememw(easeg, eaaddr, val); 1.93 -// writememb(easeg+eaaddr+1,val>>8); 1.94 - } 1.95 -} 1.96 - 1.97 -#undef fetchea 1.98 - 1.99 -#define fetchea() { rmdat=readmemb(cs, pc); pc++; \ 1.100 - reg=(rmdat>>3)&7; \ 1.101 - mod=(rmdat>>6)&3; \ 1.102 - rm=rmdat&7; \ 1.103 - if (mod!=3) fetcheal286(); } 1.104 - 1.105 -void fetcheal286() 1.106 -{ 1.107 - if (!mod && rm==6) { eaaddr=getword(); easeg=ds; ealimit=_ds.limit; ealimitw=_ds.limitw; } 1.108 - else 1.109 - { 1.110 - switch (mod) 1.111 - { 1.112 - case 0: 1.113 - eaaddr=0; 1.114 - break; 1.115 - case 1: 1.116 - eaaddr=(uint16_t)(int8_t)readmemb(cs, pc); pc++; 1.117 - break; 1.118 - case 2: 1.119 - eaaddr=getword(); 1.120 - break; 1.121 - } 1.122 - eaaddr+=(*mod1add[0][rm])+(*mod1add[1][rm]); 1.123 - easeg=*mod1seg[rm]; 1.124 - if (mod1seg[rm] == &ss) { ealimit=_ss.limit; ealimitw=_ss.limitw; } 1.125 - else { ealimit=_ds.limit; ealimitw=_ds.limitw; } 1.126 -// if (output) pclog("Limit %08X %08X %08X %08X\n",ealimit,_ds.limit,mod1seg[rm],&ss); 1.127 - } 1.128 - eaaddr&=0xFFFF; 1.129 -} 1.130 - 1.131 -void rep286(int fv) 1.132 -{ 1.133 - uint8_t temp; 1.134 - uint32_t c;//=CX; 1.135 - uint8_t temp2; 1.136 - uint16_t tempw,tempw2,tempw3,of=flags; 1.137 - uint32_t ipc=oldpc;//pc-1; 1.138 - int changeds=0; 1.139 - uint32_t oldds; 1.140 - uint32_t templ,templ2; 1.141 - int tempz; 1.142 - int tempi; 1.143 -// if (output) pclog("REP32 %04X %04X ",use32,rep32); 1.144 - startrep: 1.145 - temp=opcode2=readmemb(cs,pc); pc++; 1.146 -// if (firstrepcycle && temp==0xA5) pclog("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI); 1.147 -// if (output) pclog("REP %02X %04X\n",temp,ipc); 1.148 - c = CX; 1.149 -/* if (rep32 && (msw&1)) 1.150 - { 1.151 - 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); 1.152 - }*/ 1.153 - switch (temp) 1.154 - { 1.155 - case 0x26: /*ES:*/ 1.156 - oldds=ds; 1.157 - ds=es; 1.158 - rds=ES; 1.159 - changeds=1; 1.160 - goto startrep; 1.161 - break; 1.162 - case 0x2E: /*CS:*/ 1.163 - oldds=ds; 1.164 - ds=cs; 1.165 - rds=CS; 1.166 - changeds=1; 1.167 - goto startrep; 1.168 - break; 1.169 - case 0x36: /*SS:*/ 1.170 - oldds=ds; 1.171 - ds=ss; 1.172 - rds=SS; 1.173 - changeds=1; 1.174 - goto startrep; 1.175 - break; 1.176 - case 0x3E: /*DS:*/ 1.177 - oldds=ds; 1.178 - ds=ds; 1.179 - changeds=1; 1.180 - goto startrep; 1.181 - break; 1.182 - case 0x6C: /*REP INSB*/ 1.183 - if (c>0) 1.184 - { 1.185 - checkio_perm(DX); 1.186 - temp2=inb(DX); 1.187 - writememb(es,DI,temp2); 1.188 - if (abrt) break; 1.189 - if (flags&D_FLAG) DI--; 1.190 - else DI++; 1.191 - c--; 1.192 - cycles-=15; 1.193 - } 1.194 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; } 1.195 - else firstrepcycle=1; 1.196 - break; 1.197 - case 0x6D: /*REP INSW*/ 1.198 - if (c>0) 1.199 - { 1.200 - tempw=inw(DX); 1.201 - writememw(es,DI,tempw); 1.202 - if (abrt) break; 1.203 - if (flags&D_FLAG) DI-=2; 1.204 - else DI+=2; 1.205 - c--; 1.206 - cycles-=15; 1.207 - } 1.208 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; } 1.209 - else firstrepcycle=1; 1.210 - break; 1.211 - case 0x6E: /*REP OUTSB*/ 1.212 - if (c>0) 1.213 - { 1.214 - temp2=readmemb(ds,SI); 1.215 - if (abrt) break; 1.216 - checkio_perm(DX); 1.217 - outb(DX,temp2); 1.218 - if (flags&D_FLAG) SI--; 1.219 - else SI++; 1.220 - c--; 1.221 - cycles-=14; 1.222 - } 1.223 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; } 1.224 - else firstrepcycle=1; 1.225 - break; 1.226 - case 0x6F: /*REP OUTSW*/ 1.227 - if (c>0) 1.228 - { 1.229 - tempw=readmemw(ds,SI); 1.230 - if (abrt) break; 1.231 -// pclog("OUTSW %04X -> %04X\n",SI,tempw); 1.232 - outw(DX,tempw); 1.233 - if (flags&D_FLAG) SI-=2; 1.234 - else SI+=2; 1.235 - c--; 1.236 - cycles-=14; 1.237 - } 1.238 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; } 1.239 - else firstrepcycle=1; 1.240 - break; 1.241 - case 0xA4: /*REP MOVSB*/ 1.242 - if (c>0) 1.243 - { 1.244 - temp2=readmemb(ds,SI); if (abrt) break; 1.245 - writememb(es,DI,temp2); if (abrt) break; 1.246 -// if (output==3) pclog("MOVSB %08X:%04X -> %08X:%04X %02X\n",ds,SI,es,DI,temp2); 1.247 - if (flags&D_FLAG) { DI--; SI--; } 1.248 - else { DI++; SI++; } 1.249 - c--; 1.250 - cycles-=(is486)?3:4; 1.251 - } 1.252 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; } 1.253 - else firstrepcycle=1; 1.254 - break; 1.255 - case 0xA5: /*REP MOVSW*/ 1.256 - if (c>0) 1.257 - { 1.258 - tempw=readmemw(ds,SI); if (abrt) break; 1.259 - writememw(es,DI,tempw); if (abrt) break; 1.260 - if (flags&D_FLAG) { DI-=2; SI-=2; } 1.261 - else { DI+=2; SI+=2; } 1.262 - c--; 1.263 - cycles-=(is486)?3:4; 1.264 - } 1.265 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; } 1.266 - else firstrepcycle=1; 1.267 - break; 1.268 - case 0xA6: /*REP CMPSB*/ 1.269 - if (fv) flags|=Z_FLAG; 1.270 - else flags&=~Z_FLAG; 1.271 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.272 - { 1.273 - temp=readmemb(ds,SI); 1.274 - temp2=readmemb(es,DI); 1.275 - if (abrt) { flags=of; break; } 1.276 - if (flags&D_FLAG) { DI--; SI--; } 1.277 - else { DI++; SI++; } 1.278 - c--; 1.279 - cycles-=(is486)?7:9; 1.280 - setsub8(temp,temp2); 1.281 - } 1.282 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.283 - else firstrepcycle=1; 1.284 - break; 1.285 - case 0xA7: /*REP CMPSW*/ 1.286 - if (fv) flags|=Z_FLAG; 1.287 - else flags&=~Z_FLAG; 1.288 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.289 - { 1.290 - tempw=readmemw(ds,SI); 1.291 - tempw2=readmemw(es,DI); 1.292 - if (abrt) { flags=of; break; } 1.293 - if (flags&D_FLAG) { DI-=2; SI-=2; } 1.294 - else { DI+=2; SI+=2; } 1.295 - c--; 1.296 - cycles-=(is486)?7:9; 1.297 - setsub16(tempw,tempw2); 1.298 - } 1.299 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.300 - else firstrepcycle=1; 1.301 - break; 1.302 - 1.303 - case 0xAA: /*REP STOSB*/ 1.304 - if (c>0) 1.305 - { 1.306 - writememb(es,DI,AL); 1.307 - if (abrt) break; 1.308 - if (flags&D_FLAG) DI--; 1.309 - else DI++; 1.310 - c--; 1.311 - cycles-=(is486)?4:5; 1.312 - } 1.313 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; } 1.314 - else firstrepcycle=1; 1.315 - break; 1.316 - case 0xAB: /*REP STOSW*/ 1.317 - if (c>0) 1.318 - { 1.319 - writememw(es,DI,AX); 1.320 - if (abrt) break; 1.321 - if (flags&D_FLAG) DI-=2; 1.322 - else DI+=2; 1.323 - c--; 1.324 - cycles-=(is486)?4:5; 1.325 - } 1.326 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; } 1.327 - else firstrepcycle=1; 1.328 - break; 1.329 - case 0xAC: /*REP LODSB*/ 1.330 -// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc); 1.331 - if (c>0) 1.332 - { 1.333 - AL=readmemb(ds,SI); 1.334 - if (abrt) break; 1.335 - if (flags&D_FLAG) SI--; 1.336 - else SI++; 1.337 - c--; 1.338 - cycles-=5; 1.339 - } 1.340 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; } 1.341 - else firstrepcycle=1; 1.342 - break; 1.343 - case 0xAD: /*REP LODSW*/ 1.344 -// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc); 1.345 - if (c>0) 1.346 - { 1.347 - AX=readmemw(ds,SI); 1.348 - if (abrt) break; 1.349 - if (flags&D_FLAG) SI-=2; 1.350 - else SI+=2; 1.351 - c--; 1.352 - cycles-=5; 1.353 - } 1.354 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; } 1.355 - else firstrepcycle=1; 1.356 - break; 1.357 - case 0xAE: /*REP SCASB*/ 1.358 -// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc); 1.359 -// tempz=(fv)?1:0; 1.360 - if (fv) flags|=Z_FLAG; 1.361 - else flags&=~Z_FLAG; 1.362 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.363 - { 1.364 - temp2=readmemb(es,DI); 1.365 - if (abrt) { flags=of; break; } 1.366 - setsub8(AL,temp2); 1.367 - if (flags&D_FLAG) DI--; 1.368 - else DI++; 1.369 - c--; 1.370 - cycles-=(is486)?5:8; 1.371 - } 1.372 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.373 - else firstrepcycle=1; 1.374 - break; 1.375 - case 0xAF: /*REP SCASW*/ 1.376 -// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc); 1.377 - if (fv) flags|=Z_FLAG; 1.378 - else flags&=~Z_FLAG; 1.379 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.380 - { 1.381 - tempw=readmemw(es,DI); 1.382 - if (abrt) { flags=of; break; } 1.383 - setsub16(AX,tempw); 1.384 - if (flags&D_FLAG) DI-=2; 1.385 - else DI+=2; 1.386 - c--; 1.387 - cycles-=(is486)?5:8; 1.388 - } 1.389 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.390 - else firstrepcycle=1; 1.391 - break; 1.392 - 1.393 - default: 1.394 - pc=ipc; 1.395 - cycles-=20; 1.396 - x86illegal(); 1.397 - pclog("Bad REP %02X\n", temp); 1.398 - //dumpregs(); 1.399 - //exit(-1); 1.400 - } 1.401 - CX=c; 1.402 - if (changeds) ds=oldds; 1.403 -// if (output) pclog("%03X %03X\n",rep32,use32); 1.404 -} 1.405 - 1.406 -void x86illegal() 1.407 -{ 1.408 - uint16_t addr; 1.409 - pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode); 1.410 -// if (output) 1.411 -// { 1.412 -// dumpregs(); 1.413 -// exit(-1); 1.414 -// } 1.415 - if (msw&1) 1.416 - { 1.417 - pmodeint(6,0); 1.418 - } 1.419 - else 1.420 - { 1.421 - if (ssegs) { ss=oldss; _ss.limit=oldsslimit; _ss.limitw=oldsslimitw; } 1.422 - writememw(ss,((SP-2)&0xFFFF),flags); 1.423 - writememw(ss,((SP-4)&0xFFFF),CS); 1.424 - writememw(ss,((SP-6)&0xFFFF),pc); 1.425 - SP-=6; 1.426 - flags&=~I_FLAG; 1.427 - flags&=~T_FLAG; 1.428 - addr=6<<2; 1.429 - pc=readmemw(0,addr); 1.430 - loadcs(readmemw(0,addr+2)); 1.431 - } 1.432 - cycles-=70; 1.433 -} 1.434 -//#endif 1.435 -//#if 0 1.436 - 1.437 -static inline uint8_t getbytef() 1.438 -{ 1.439 - uint8_t temp = readmemb(cs, pc); pc++; 1.440 - return temp; 1.441 -} 1.442 -static inline uint16_t getwordf() 1.443 -{ 1.444 - uint16_t tempw = readmemw(cs, pc); pc+=2; 1.445 - return tempw; 1.446 -} 1.447 - 1.448 -/*Conditional jump timing is WRONG*/ 1.449 -void exec286(int cycs) 1.450 -{ 1.451 - uint8_t temp,temp2; 1.452 - uint16_t addr,tempw,tempw2,tempw3,tempw4; 1.453 - int8_t offset; 1.454 - volatile int tempws, tempws2; 1.455 - uint32_t templ, templ2, templ3; 1.456 - int8_t temps; 1.457 - int16_t temps16; 1.458 - int c;//,cycdiff; 1.459 - int tempi; 1.460 - FILE *f; 1.461 - int trap; 1.462 - int cyclast; 1.463 -// printf("Run 286! %i %i\n",cycles,cycs); 1.464 - cycles+=cycs; 1.465 -// i86_Execute(cycs); 1.466 -// return; 1.467 - while (cycles>0) 1.468 - { 1.469 - cyclast = cycdiff; 1.470 - cycdiff=cycles; 1.471 - oldcs=CS; 1.472 - oldpc=pc; 1.473 - oldcpl=CPL; 1.474 - 1.475 - opcodestart: 1.476 - opcode = readmemb(cs, pc); 1.477 - if (abrt) goto opcodeend; 1.478 - tempc=flags&C_FLAG; 1.479 - trap=flags&T_FLAG; 1.480 - 1.481 - if (output && /*cs<0xF0000 && */!ssegs)//opcode!=0x26 && opcode!=0x36 && opcode!=0x2E && opcode!=0x3E) 1.482 - { 1.483 - if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle) 1.484 - { 1.485 - if (!skipnextprint) printf("%04X(%06X):%04X : %04X %04X %04X %04X %04X(%06X) %04X(%06X) %04X(%06X) %04X(%06X) %04X %04X %04X %04X %02X %04X %04X %04X %04X %04X %08X %i %i %i %08X %i %f %f\n",CS,cs,pc,AX,BX,CX,DX,CS,cs,DS,ds,ES,es,SS,ss,DI,SI,BP,SP,opcode,flags,msw,ram[0x7c3e],ram[(0x7c3e)+3],ram[0x7c40],_ds.limitw,keybsenddelay,keywaiting,ins, _ss.limit, cyclast, pit.c[1], PITCONST); 1.486 - skipnextprint=0; 1.487 -// ins++; 1.488 -/* if (ins==50000) 1.489 - { 1.490 - dumpregs(); 1.491 - exit(-1); 1.492 - }*/ 1.493 -/* if (ins==500000) 1.494 - { 1.495 - dumpregs(); 1.496 - exit(-1); 1.497 - }*/ 1.498 - } 1.499 - } 1.500 -//#endif 1.501 - pc++; 1.502 - inhlt=0; 1.503 -// if (ins==500000) { dumpregs(); exit(0); }*/ 1.504 - switch (opcode) 1.505 - { 1.506 - case 0x00: /*ADD 8,reg*/ 1.507 - fetchea(); 1.508 - //if (!rmdat && output) pc--; 1.509 -/* if (!rmdat && output) 1.510 - { 1.511 - pclog("Crashed\n"); 1.512 -// clear_keybuf(); 1.513 -// readkey(); 1.514 - dumpregs(); 1.515 - exit(-1); 1.516 - }*/ 1.517 - if (mod == 3) 1.518 - { 1.519 - temp = getr8(rm); 1.520 - temp2 = getr8(reg); 1.521 - setadd8(temp, temp2); 1.522 - setr8(rm, temp + temp2); 1.523 - cycles -= 2; 1.524 - } 1.525 - else 1.526 - { 1.527 - temp = geteab(); if (abrt) break; 1.528 - temp2 = getr8(reg); 1.529 - seteab(temp + temp2); if (abrt) break; 1.530 - setadd8(temp, temp2); 1.531 - cycles -= 7; 1.532 - } 1.533 - break; 1.534 - case 0x01: /*ADD 16,reg*/ 1.535 - fetchea(); 1.536 - if (mod == 3) 1.537 - { 1.538 - setadd16(regs[rm].w, regs[reg].w); 1.539 - regs[rm].w += regs[reg].w; 1.540 - cycles -= 2; 1.541 - } 1.542 - else 1.543 - { 1.544 - tempw = geteaw(); if (abrt) break; 1.545 - seteaw(tempw + regs[reg].w); if (abrt) break; 1.546 - setadd16(tempw, regs[reg].w); 1.547 - cycles -= 7; 1.548 - } 1.549 - break; 1.550 - case 0x02: /*ADD reg,8*/ 1.551 - fetchea(); 1.552 - temp=geteab(); if (abrt) break; 1.553 - setadd8(getr8(reg),temp); 1.554 - setr8(reg,getr8(reg)+temp); 1.555 - cycles -= (mod == 3) ? 2 : 7; 1.556 - break; 1.557 - case 0x03: /*ADD reg,16*/ 1.558 - fetchea(); 1.559 - tempw=geteaw(); if (abrt) break; 1.560 - setadd16(regs[reg].w,tempw); 1.561 - regs[reg].w+=tempw; 1.562 - cycles -= (mod == 3) ? 2 : 7; 1.563 - break; 1.564 - case 0x04: /*ADD AL,#8*/ 1.565 - temp=getbytef(); 1.566 - setadd8(AL,temp); 1.567 - AL+=temp; 1.568 - cycles -= 3; 1.569 - break; 1.570 - case 0x05: /*ADD AX,#16*/ 1.571 - tempw=getwordf(); 1.572 - setadd16(AX,tempw); 1.573 - AX+=tempw; 1.574 - cycles -= 3; 1.575 - break; 1.576 - 1.577 - case 0x06: /*PUSH ES*/ 1.578 - if (ssegs) ss=oldss; 1.579 - writememw(ss,((SP-2)&0xFFFF),ES); if (abrt) break; 1.580 - SP-=2; 1.581 - cycles-=3; 1.582 - break; 1.583 - case 0x07: 1.584 - if (ssegs) ss=oldss; 1.585 - tempw=readmemw(ss,SP); if (abrt) break; 1.586 - loadseg(tempw,&_es); if (abrt) break; 1.587 - SP+=2; 1.588 - cycles -= (msw & 1) ? 20 : 5; 1.589 - break; 1.590 - 1.591 - case 0x08: /*OR 8,reg*/ 1.592 - fetchea(); 1.593 - if (mod == 3) 1.594 - { 1.595 - temp = getr8(rm) | getr8(reg); 1.596 - setr8(rm, temp); 1.597 - setznp8(temp); 1.598 - cycles -= 2; 1.599 - } 1.600 - else 1.601 - { 1.602 - temp = geteab(); if (abrt) break; 1.603 - temp2 = getr8(reg); 1.604 - seteab(temp | temp2); if (abrt) break; 1.605 - setznp8(temp | temp2); 1.606 - cycles -= 7; 1.607 - } 1.608 - break; 1.609 - case 0x09: /*OR 16,reg*/ 1.610 - fetchea(); 1.611 - if (mod == 3) 1.612 - { 1.613 - regs[rm].w |= regs[reg].w; 1.614 - setznp16(regs[rm].w); 1.615 - cycles -= 2; 1.616 - } 1.617 - else 1.618 - { 1.619 - tempw = geteaw() | regs[reg].w; if (abrt) break; 1.620 - seteaw(tempw); if (abrt) break; 1.621 - setznp16(tempw); 1.622 - cycles -= 7; 1.623 - } 1.624 - break; 1.625 - case 0x0A: /*OR reg,8*/ 1.626 - fetchea(); 1.627 - temp=geteab(); if (abrt) break; 1.628 - temp|=getr8(reg); 1.629 - setznp8(temp); 1.630 - setr8(reg,temp); 1.631 - cycles -= (mod == 3) ? 2 : 7; 1.632 - break; 1.633 - case 0x0B: /*OR reg,16*/ 1.634 - fetchea(); 1.635 - tempw=geteaw(); if (abrt) break; 1.636 - tempw|=regs[reg].w; 1.637 - setznp16(tempw); 1.638 - regs[reg].w=tempw; 1.639 - cycles -= (mod == 3) ? 2 : 7; 1.640 - break; 1.641 - case 0x0C: /*OR AL,#8*/ 1.642 - AL|=getbytef(); 1.643 - setznp8(AL); 1.644 - cycles -= 2; 1.645 - break; 1.646 - case 0x0D: /*OR AX,#16*/ 1.647 - AX|=getwordf(); 1.648 - setznp16(AX); 1.649 - cycles -= 2; 1.650 - break; 1.651 - 1.652 - case 0x0E: /*PUSH CS*/ 1.653 - if (ssegs) ss=oldss; 1.654 - writememw(ss,((SP-2)&0xFFFF),CS); if (abrt) break; 1.655 - SP-=2; 1.656 - cycles-=3; 1.657 - break; 1.658 - 1.659 - case 0x0F: 1.660 - temp = readmemb(cs, pc); pc++; 1.661 - opcode2 = temp; 1.662 -// if (temp>5 && temp!=0x82 && temp!=0x85 && temp!=0x84 && temp!=0x87 && temp!=0x8D && temp!=0x8F && temp!=0x8C && temp!=0x20 && temp!=0x22) pclog("Using magic 386 0F instruction %02X!\n",temp); 1.663 - switch (temp) 1.664 - { 1.665 - case 0: 1.666 - fetchea(); if (abrt) break; 1.667 - switch (rmdat&0x38) 1.668 - { 1.669 - case 0x00: /*SLDT*/ 1.670 - NOTRM 1.671 - seteaw(ldt.seg); 1.672 - cycles -= (mod == 3) ? 3 : 2; 1.673 - break; 1.674 - case 0x08: /*STR*/ 1.675 - NOTRM 1.676 - seteaw(tr.seg); 1.677 - cycles -= (mod == 3) ? 3 : 2; 1.678 - break; 1.679 - case 0x10: /*LLDT*/ 1.680 - if (CPL && (msw & 1)) 1.681 - { 1.682 - pclog("Invalid LLDT!\n"); 1.683 - x86gpf(NULL,0); 1.684 - break; 1.685 - } 1.686 - NOTRM 1.687 - ldt.seg=geteaw(); 1.688 -// pclog("Load LDT %04X ",ldt.seg); 1.689 - templ=(ldt.seg&~7)+gdt.base; 1.690 -// pclog("%06X ",gdt.base); 1.691 - templ3=readmemw(0,templ)+((readmemb(0,templ+6)&0xF)<<16); 1.692 - templ2=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24); 1.693 - if (abrt) break; 1.694 - ldt.limit=templ3; 1.695 - ldt.access=readmemb(0,templ+6); 1.696 - if (readmemb(0,templ+6)&0x80) 1.697 - { 1.698 - ldt.limit<<=12; 1.699 - ldt.limit|=0xFFF; 1.700 - } 1.701 - ldt.base=templ2; 1.702 -// /*if (output==3) */pclog("LLDT %04X %08X %04X %08X %08X\n",ldt.seg,ldt.base,ldt.limit,readmeml(0,templ),readmeml(0,templ+4)); 1.703 - 1.704 - cycles -= (mod == 3) ? 17 : 19; 1.705 - break; 1.706 - case 0x18: /*LTR*/ 1.707 - if (CPL && (msw & 1)) 1.708 - { 1.709 - pclog("Invalid LTR!\n"); 1.710 - x86gpf(NULL,0); 1.711 - break; 1.712 - } 1.713 - NOTRM 1.714 - tr.seg=geteaw(); 1.715 - templ=(tr.seg&~7)+gdt.base; 1.716 - templ3=readmemw(0,templ)+((readmemb(0,templ+6)&0xF)<<16); 1.717 - templ2=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24); 1.718 - temp=readmemb(0,templ+5); 1.719 - if (abrt) break; 1.720 - tr.limit=templ3; 1.721 - tr.access=readmemb(0,templ+6); 1.722 - if (readmemb(0,templ+6)&0x80) 1.723 - { 1.724 - tr.limit<<=12; 1.725 - tr.limit|=0xFFF; 1.726 - } 1.727 - tr.base=templ2; 1.728 -// pclog("TR base = %08X\n",templ2); 1.729 - tr.access=temp; 1.730 - cycles -= (mod == 3) ? 17 : 19; 1.731 - break; 1.732 - case 0x20: /*VERR*/ 1.733 - NOTRM 1.734 - tempw=geteaw(); if (abrt) break; 1.735 - flags&=~Z_FLAG; 1.736 - if (!(tempw&0xFFFC)) break; /*Null selector*/ 1.737 - cpl_override=1; 1.738 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.739 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.740 - cpl_override=0; 1.741 - if (abrt) break; 1.742 - if (!(tempw2&0x1000)) tempi=0; 1.743 - if ((tempw2&0xC00)!=0xC00) /*Exclude conforming code segments*/ 1.744 - { 1.745 - tempw3=(tempw2>>13)&3; /*Check permissions*/ 1.746 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.747 - } 1.748 - if ((tempw2&0x0800) && !(tempw2&0x0200)) tempi=0; /*Non-readable code*/ 1.749 - if (tempi) flags|=Z_FLAG; 1.750 - cycles -= (mod == 3) ? 14 : 16; 1.751 - break; 1.752 - case 0x28: /*VERW*/ 1.753 - NOTRM 1.754 - tempw=geteaw(); if (abrt) break; 1.755 - flags&=~Z_FLAG; 1.756 - if (!(tempw&0xFFFC)) break; /*Null selector*/ 1.757 - cpl_override=1; 1.758 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.759 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.760 - cpl_override=0; 1.761 - if (abrt) break; 1.762 - if (!(tempw2&0x1000)) tempi=0; 1.763 - tempw3=(tempw2>>13)&3; /*Check permissions*/ 1.764 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.765 - if (tempw2&0x0800) tempi=0; /*Code*/ 1.766 - else if (!(tempw2&0x0200)) tempi=0; /*Read-only data*/ 1.767 - if (tempi) flags|=Z_FLAG; 1.768 - cycles -= (mod == 3) ? 14 : 16; 1.769 - break; 1.770 - 1.771 - 1.772 - default: 1.773 - pclog("Bad 0F 00 opcode %02X\n",rmdat&0x38); 1.774 - pc-=3; 1.775 - x86illegal(); 1.776 - break; 1.777 -// dumpregs(); 1.778 -// exit(-1); 1.779 - } 1.780 - break; 1.781 - case 1: 1.782 - fetchea(); if (abrt) break; 1.783 - switch (rmdat&0x38) 1.784 - { 1.785 - case 0x00: /*SGDT*/ 1.786 - seteaw(gdt.limit); 1.787 - writememw(easeg, eaaddr + 2, gdt.base); 1.788 - writememw(easeg, eaaddr + 4, (gdt.base >> 16) | 0xFF00); 1.789 - cycles -= 11; 1.790 - break; 1.791 - case 0x08: /*SIDT*/ 1.792 - seteaw(idt.limit); 1.793 - writememw(easeg, eaaddr + 2, idt.base); 1.794 - writememw(easeg, eaaddr + 4, (idt.base >> 16) | 0xFF00); 1.795 - cycles -= 12; 1.796 - break; 1.797 - case 0x10: /*LGDT*/ 1.798 - if (CPL && (msw & 1)) 1.799 - { 1.800 - pclog("Invalid LGDT!\n"); 1.801 - x86gpf(NULL,0); 1.802 - break; 1.803 - } 1.804 - tempw=geteaw(); 1.805 - templ=readmeml(0,easeg+eaaddr+2)&0xFFFFFF; 1.806 - if (abrt) break; 1.807 - gdt.limit=tempw; 1.808 - gdt.base=templ; 1.809 - cycles-=11; 1.810 - break; 1.811 - case 0x18: /*LIDT*/ 1.812 - if (CPL && (msw & 1)) 1.813 - { 1.814 - pclog("Invalid LIDT!\n"); 1.815 - x86gpf(NULL,0); 1.816 - break; 1.817 - } 1.818 - tempw=geteaw(); 1.819 - templ=readmeml(0,easeg+eaaddr+2)&0xFFFFFF; 1.820 - if (abrt) break; 1.821 - idt.limit=tempw; 1.822 - idt.base=templ; 1.823 - cycles-=12; 1.824 - break; 1.825 - 1.826 - case 0x20: /*SMSW*/ 1.827 - if (is486) seteaw(msw); 1.828 - else seteaw(msw|0xFF00); 1.829 -// pclog("SMSW %04X:%04X %04X %i\n",CS,pc,msw,is486); 1.830 - cycles -= (mod == 3) ? 2 : 3; 1.831 - break; 1.832 - case 0x30: /*LMSW*/ 1.833 - if (CPL && (msw&1)) 1.834 - { 1.835 - pclog("LMSW - ring not zero!\n"); 1.836 - x86gpf(NULL,0); 1.837 - break; 1.838 - } 1.839 - tempw=geteaw(); if (abrt) break; 1.840 - if (msw&1) tempw|=1; 1.841 - msw=tempw; 1.842 - cycles -= (mod == 3) ? 3 : 6; 1.843 - pclog("LMSW %04X %08X %04X:%04X\n", msw, cs, CS, pc); 1.844 - break; 1.845 - 1.846 - default: 1.847 - pclog("Bad 0F 01 opcode %02X\n",rmdat&0x38); 1.848 - pc-=3; 1.849 - x86illegal(); 1.850 - break; 1.851 -// dumpregs(); 1.852 -// exit(-1); 1.853 - } 1.854 - break; 1.855 - 1.856 - case 2: /*LAR*/ 1.857 - NOTRM 1.858 - fetchea(); 1.859 - tempw=geteaw(); if (abrt) break; 1.860 -// pclog("LAR seg %04X\n",tempw); 1.861 - 1.862 - if (!(tempw&0xFFFC)) { flags&=~Z_FLAG; break; } /*Null selector*/ 1.863 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.864 - if (tempi) 1.865 - { 1.866 - cpl_override=1; 1.867 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.868 - cpl_override=0; 1.869 - if (abrt) break; 1.870 - } 1.871 - flags&=~Z_FLAG; 1.872 -// pclog("tempw2 %04X %i %04X %04X\n",tempw2,tempi,ldt.limit,gdt.limit); 1.873 - if ((tempw2&0x1F00)==0x000) tempi=0; 1.874 - if ((tempw2&0x1F00)==0x800) tempi=0; 1.875 - if ((tempw2&0x1F00)==0xA00) tempi=0; 1.876 - if ((tempw2&0x1F00)==0xD00) tempi=0; 1.877 - if ((tempw2&0x1C00)<0x1C00) /*Exclude conforming code segments*/ 1.878 - { 1.879 - tempw3=(tempw2>>13)&3; 1.880 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.881 - } 1.882 - if (tempi) 1.883 - { 1.884 - flags|=Z_FLAG; 1.885 - cpl_override=1; 1.886 - regs[reg].w=readmemb(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+5)<<8; 1.887 - cpl_override=0; 1.888 - } 1.889 - cycles -= (mod == 3) ? 14 : 16; 1.890 - break; 1.891 - 1.892 - case 3: /*LSL*/ 1.893 - NOTRM 1.894 - fetchea(); 1.895 - tempw=geteaw(); if (abrt) break; 1.896 - flags&=~Z_FLAG; 1.897 - if (!(tempw&0xFFFC)) break; /*Null selector*/ 1.898 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.899 - cpl_override=1; 1.900 - if (tempi) 1.901 - { 1.902 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.903 - } 1.904 - cpl_override=0; 1.905 - if (abrt) break; 1.906 - if ((tempw2&0x1400)==0x400) tempi=0; /*Interrupt or trap or call gate*/ 1.907 - if ((tempw2&0x1F00)==0x000) tempi=0; /*Invalid*/ 1.908 - if ((tempw2&0x1F00)==0xA00) tempi=0; /*Invalid*/ 1.909 - if ((tempw2&0x1C00)!=0x1C00) /*Exclude conforming code segments*/ 1.910 - { 1.911 - tempw3=(tempw2>>13)&3; 1.912 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.913 - } 1.914 - if (tempi) 1.915 - { 1.916 - flags|=Z_FLAG; 1.917 - cpl_override=1; 1.918 - regs[reg].w=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)); 1.919 - cpl_override=0; 1.920 - } 1.921 - cycles -= (mod == 3) ? 14 : 16; 1.922 - break; 1.923 - 1.924 - case 5: /*LOADALL*/ 1.925 -// pclog("At %04X:%04X ",CS,pc); 1.926 - flags=(readmemw(0,0x818)&0xFFD5)|2; 1.927 - pc=readmemw(0,0x81A); 1.928 - DS=readmemw(0,0x81E); 1.929 - SS=readmemw(0,0x820); 1.930 - CS=readmemw(0,0x822); 1.931 - ES=readmemw(0,0x824); 1.932 - DI=readmemw(0,0x826); 1.933 - SI=readmemw(0,0x828); 1.934 - BP=readmemw(0,0x82A); 1.935 - SP=readmemw(0,0x82C); 1.936 - BX=readmemw(0,0x82E); 1.937 - DX=readmemw(0,0x830); 1.938 - CX=readmemw(0,0x832); 1.939 - AX=readmemw(0,0x834); 1.940 - /*if (readmemw(0,0x806)) 1.941 - { 1.942 - pclog("Something in LOADALL!\n"); 1.943 - dumpregs(); 1.944 - exit(-1); 1.945 - }*/ 1.946 - es=readmemw(0,0x836)|(readmemb(0,0x838)<<16); 1.947 - cs=readmemw(0,0x83C)|(readmemb(0,0x83E)<<16); 1.948 - ss=readmemw(0,0x842)|(readmemb(0,0x844)<<16); 1.949 - ds=readmemw(0,0x848)|(readmemb(0,0x84A)<<16); 1.950 - cycles-=195; 1.951 -// pclog("LOADALL - %06X:%04X %06X:%04X %04X\n",ds,SI,es,DI,DX); 1.952 - break; 1.953 - 1.954 - case 6: /*CLTS*/ 1.955 - if (CPL && (msw & 1)) 1.956 - { 1.957 - pclog("Can't CLTS\n"); 1.958 - x86gpf(NULL,0); 1.959 - break; 1.960 - } 1.961 - msw &= ~8; 1.962 - cycles-=2; 1.963 - break; 1.964 - 1.965 - case 0xFF: /*Invalid - Windows 3.1 syscall trap?*/ 1.966 - inv16: 1.967 - pc-=2; 1.968 - if (msw&1) 1.969 - { 1.970 - pmodeint(6,0); 1.971 - } 1.972 - else 1.973 - { 1.974 - if (ssegs) ss=oldss; 1.975 - writememw(ss,((SP-2)&0xFFFF),flags); 1.976 - writememw(ss,((SP-4)&0xFFFF),CS); 1.977 - writememw(ss,((SP-6)&0xFFFF),pc); 1.978 - SP-=6; 1.979 - addr=6<<2; 1.980 - flags&=~I_FLAG; 1.981 - flags&=~T_FLAG; 1.982 - oxpc=pc; 1.983 - pc=readmemw(0,addr); 1.984 - loadcs(readmemw(0,addr+2)); 1.985 -/* if (!pc && !cs) 1.986 - { 1.987 - pclog("Bad int %02X %04X:%04X\n",temp,oldcs,oldpc); 1.988 - dumpregs(); 1.989 - exit(-1); 1.990 - }*/ 1.991 - } 1.992 - cycles-=23; 1.993 - break; 1.994 - 1.995 - default: 1.996 - pclog("Bad 16-bit 0F opcode %02X 386 %i\n",temp,ins); 1.997 - pc=oldpc; 1.998 -// output=3; 1.999 -// timetolive=100000; 1.1000 -// dumpregs(); 1.1001 -// exit(-1); 1.1002 - x86illegal(); 1.1003 - break; 1.1004 - } 1.1005 - break; 1.1006 - 1.1007 - case 0x10: /*ADC 8,reg*/ 1.1008 - fetchea(); 1.1009 - if (mod == 3) 1.1010 - { 1.1011 - temp = getr8(rm); 1.1012 - temp2 = getr8(reg); 1.1013 - setadc8(temp, temp2); 1.1014 - setr8(rm, temp + temp2 + tempc); 1.1015 - cycles -= 2; 1.1016 - } 1.1017 - else 1.1018 - { 1.1019 - temp = geteab(); if (abrt) break; 1.1020 - temp2 = getr8(reg); 1.1021 - seteab(temp + temp2 + tempc); if (abrt) break; 1.1022 - setadc8(temp, temp2); 1.1023 - cycles -= 7; 1.1024 - } 1.1025 - break; 1.1026 - case 0x11: /*ADC 16,reg*/ 1.1027 - fetchea(); 1.1028 - if (mod == 3) 1.1029 - { 1.1030 - setadc16(regs[rm].w, regs[reg].w); 1.1031 - regs[rm].w += regs[reg].w + tempc; 1.1032 - cycles -= 2; 1.1033 - } 1.1034 - else 1.1035 - { 1.1036 - tempw = geteaw(); if (abrt) break; 1.1037 - tempw2 = regs[reg].w; 1.1038 - seteaw(tempw + tempw2 + tempc); if (abrt) break; 1.1039 - setadc16(tempw, tempw2); 1.1040 - cycles -= 7; 1.1041 - } 1.1042 - break; 1.1043 - case 0x12: /*ADC reg,8*/ 1.1044 - fetchea(); 1.1045 - temp=geteab(); if (abrt) break; 1.1046 - setadc8(getr8(reg),temp); 1.1047 - setr8(reg,getr8(reg)+temp+tempc); 1.1048 - cycles -= (mod == 3) ? 2 : 7; 1.1049 - break; 1.1050 - case 0x13: /*ADC reg,16*/ 1.1051 - fetchea(); 1.1052 - tempw=geteaw(); if (abrt) break; 1.1053 - setadc16(regs[reg].w,tempw); 1.1054 - regs[reg].w+=tempw+tempc; 1.1055 - cycles -= (mod == 3) ? 2 : 7; 1.1056 - break; 1.1057 - case 0x14: /*ADC AL,#8*/ 1.1058 - tempw=getbytef(); 1.1059 - setadc8(AL,tempw); 1.1060 - AL+=tempw+tempc; 1.1061 - cycles -= 3; 1.1062 - break; 1.1063 - case 0x15: /*ADC AX,#16*/ 1.1064 - tempw=getwordf(); 1.1065 - setadc16(AX,tempw); 1.1066 - AX+=tempw+tempc; 1.1067 - cycles -= 3; 1.1068 - break; 1.1069 - 1.1070 - case 0x16: /*PUSH SS*/ 1.1071 - if (ssegs) ss=oldss; 1.1072 - writememw(ss,((SP-2)&0xFFFF),SS); if (abrt) break; 1.1073 - SP-=2; 1.1074 - cycles-=3; 1.1075 - break; 1.1076 - case 0x17: /*POP SS*/ 1.1077 - if (ssegs) ss=oldss; 1.1078 - tempw=readmemw(ss,SP); if (abrt) break; 1.1079 - loadseg(tempw,&_ss); if (abrt) break; 1.1080 - SP += 2; 1.1081 - cycles -= (msw & 1) ? 20 : 5; 1.1082 - break; 1.1083 - 1.1084 - case 0x18: /*SBB 8,reg*/ 1.1085 - fetchea(); 1.1086 - if (mod == 3) 1.1087 - { 1.1088 - temp = getr8(rm); 1.1089 - temp2 = getr8(reg); 1.1090 - setsbc8(temp, temp2); 1.1091 - setr8(rm, temp - (temp2 + tempc)); 1.1092 - cycles -= 2; 1.1093 - } 1.1094 - else 1.1095 - { 1.1096 - temp = geteab(); if (abrt) break; 1.1097 - temp2 = getr8(reg); 1.1098 - seteab(temp - (temp2 + tempc)); if (abrt) break; 1.1099 - setsbc8(temp, temp2); 1.1100 - cycles -= 7; 1.1101 - } 1.1102 - break; 1.1103 - case 0x19: /*SBB 16,reg*/ 1.1104 - fetchea(); 1.1105 - if (mod == 3) 1.1106 - { 1.1107 - setsbc16(regs[rm].w, regs[reg].w); 1.1108 - regs[rm].w -= (regs[reg].w + tempc); 1.1109 - cycles -= 2; 1.1110 - } 1.1111 - else 1.1112 - { 1.1113 - tempw = geteaw(); if (abrt) break; 1.1114 - tempw2 = regs[reg].w; 1.1115 - seteaw(tempw - (tempw2 + tempc)); if (abrt) break; 1.1116 - setsbc16(tempw, tempw2); 1.1117 - cycles -= 7; 1.1118 - } 1.1119 - break; 1.1120 - case 0x1A: /*SBB reg,8*/ 1.1121 - fetchea(); 1.1122 - temp=geteab(); if (abrt) break; 1.1123 - setsbc8(getr8(reg),temp); 1.1124 - setr8(reg,getr8(reg)-(temp+tempc)); 1.1125 - cycles -= (mod == 3) ? 2 : 7; 1.1126 - break; 1.1127 - case 0x1B: /*SBB reg,16*/ 1.1128 - fetchea(); 1.1129 - tempw=geteaw(); if (abrt) break; 1.1130 - tempw2=regs[reg].w; 1.1131 - setsbc16(tempw2,tempw); 1.1132 - tempw2-=(tempw+tempc); 1.1133 - regs[reg].w=tempw2; 1.1134 - cycles -= (mod == 3) ? 2 : 7; 1.1135 - break; 1.1136 - case 0x1C: /*SBB AL,#8*/ 1.1137 - temp=getbytef(); 1.1138 - setsbc8(AL,temp); 1.1139 - AL-=(temp+tempc); 1.1140 - cycles -= 3; 1.1141 - break; 1.1142 - case 0x1D: /*SBB AX,#16*/ 1.1143 - tempw=getwordf(); 1.1144 - setsbc16(AX,tempw); 1.1145 - AX-=(tempw+tempc); 1.1146 - cycles -= 3; 1.1147 - break; 1.1148 - 1.1149 - case 0x1E: /*PUSH DS*/ 1.1150 - if (ssegs) ss=oldss; 1.1151 - writememw(ss,((SP-2)&0xFFFF),DS); if (abrt) break; 1.1152 - SP-=2; 1.1153 - cycles-=3; 1.1154 - break; 1.1155 - case 0x1F: case 0x21F: /*POP DS*/ 1.1156 - if (ssegs) ss=oldss; 1.1157 - tempw=readmemw(ss,SP); if (abrt) break; 1.1158 - loadseg(tempw,&_ds); if (abrt) break; 1.1159 - SP+=2; 1.1160 - cycles -= (msw & 1) ? 20 : 5; 1.1161 - break; 1.1162 - 1.1163 - case 0x20: /*AND 8,reg*/ 1.1164 - fetchea(); 1.1165 - if (mod == 3) 1.1166 - { 1.1167 - temp = getr8(rm) & getr8(reg); 1.1168 - setr8(rm, temp); 1.1169 - setznp8(temp); 1.1170 - cycles -= 2; 1.1171 - } 1.1172 - else 1.1173 - { 1.1174 - temp = geteab(); if (abrt) break; 1.1175 - temp &= getr8(reg); 1.1176 - seteab(temp); if (abrt) break; 1.1177 - setznp8(temp); 1.1178 - cycles -= 7; 1.1179 - } 1.1180 - break; 1.1181 - case 0x21: /*AND 16,reg*/ 1.1182 - fetchea(); 1.1183 - if (mod == 3) 1.1184 - { 1.1185 - regs[rm].w &= regs[reg].w; 1.1186 - setznp16(regs[rm].w); 1.1187 - cycles -= 2; 1.1188 - } 1.1189 - else 1.1190 - { 1.1191 - tempw = geteaw() & regs[reg].w; if (abrt) break; 1.1192 - seteaw(tempw); if (abrt) break; 1.1193 - setznp16(tempw); 1.1194 - cycles -= 7; 1.1195 - } 1.1196 - break; 1.1197 - case 0x22: /*AND reg,8*/ 1.1198 - fetchea(); 1.1199 - temp=geteab(); if (abrt) break; 1.1200 - temp&=getr8(reg); 1.1201 - setznp8(temp); 1.1202 - setr8(reg,temp); 1.1203 - cycles -= (mod == 3) ? 2 : 7; 1.1204 - break; 1.1205 - case 0x23: /*AND reg,16*/ 1.1206 - fetchea(); 1.1207 - tempw=geteaw(); if (abrt) break; 1.1208 - tempw&=regs[reg].w; 1.1209 - setznp16(tempw); 1.1210 - regs[reg].w=tempw; 1.1211 - cycles -= (mod == 3) ? 2 : 7; 1.1212 - break; 1.1213 - case 0x24: /*AND AL,#8*/ 1.1214 - AL&=getbytef(); 1.1215 - setznp8(AL); 1.1216 - cycles -= 3; 1.1217 - break; 1.1218 - case 0x25: /*AND AX,#16*/ 1.1219 - AX&=getwordf(); 1.1220 - setznp16(AX); 1.1221 - cycles -= 3; 1.1222 - break; 1.1223 - 1.1224 - case 0x26: /*ES:*/ 1.1225 - oldss=ss; 1.1226 - oldds=ds; 1.1227 - ds=ss=es; 1.1228 - rds=ES; 1.1229 - ssegs=2; 1.1230 - cycles-=2; 1.1231 - goto opcodestart; 1.1232 -// break; 1.1233 - 1.1234 - case 0x27: /*DAA*/ 1.1235 - if ((flags & A_FLAG) || ((AL & 0xF) > 9)) 1.1236 - { 1.1237 - tempi = ((uint16_t)AL) + 6; 1.1238 - AL += 6; 1.1239 - flags |= A_FLAG; 1.1240 - if (tempi & 0x100) flags |= C_FLAG; 1.1241 - } 1.1242 - if ((flags&C_FLAG) || (AL>0x9F)) 1.1243 - { 1.1244 - AL+=0x60; 1.1245 - flags|=C_FLAG; 1.1246 - } 1.1247 - tempw = flags & (C_FLAG | A_FLAG); 1.1248 - setznp8(AL); 1.1249 - flags |= tempw; 1.1250 - cycles -= 3; 1.1251 - break; 1.1252 - 1.1253 - case 0x28: /*SUB 8,reg*/ 1.1254 - fetchea(); 1.1255 - if (mod == 3) 1.1256 - { 1.1257 - temp = getr8(rm); 1.1258 - temp2 = getr8(reg); 1.1259 - setsub8(temp, temp2); 1.1260 - setr8(rm, temp - temp2); 1.1261 - cycles -= 2; 1.1262 - } 1.1263 - else 1.1264 - { 1.1265 - temp = geteab(); if (abrt) break; 1.1266 - temp2 = getr8(reg); 1.1267 - seteab(temp - temp2); if (abrt) break; 1.1268 - setsub8(temp, temp2); 1.1269 - cycles -= 7; 1.1270 - } 1.1271 - break; 1.1272 - case 0x29: /*SUB 16,reg*/ 1.1273 - fetchea(); 1.1274 - if (mod == 3) 1.1275 - { 1.1276 - setsub16(regs[rm].w, regs[reg].w); 1.1277 - regs[rm].w -= regs[reg].w; 1.1278 - cycles -= 2; 1.1279 - } 1.1280 - else 1.1281 - { 1.1282 - tempw = geteaw(); if (abrt) break; 1.1283 - seteaw(tempw - regs[reg].w); if (abrt) break; 1.1284 - setsub16(tempw, regs[reg].w); 1.1285 - cycles -= 7; 1.1286 - } 1.1287 - break; 1.1288 - case 0x2A: /*SUB reg,8*/ 1.1289 - fetchea(); 1.1290 - temp=geteab(); if (abrt) break; 1.1291 - setsub8(getr8(reg),temp); 1.1292 - setr8(reg,getr8(reg)-temp); 1.1293 - cycles -= (mod == 3) ? 2 : 7; 1.1294 - break; 1.1295 - case 0x2B: /*SUB reg,16*/ 1.1296 - fetchea(); 1.1297 - tempw=geteaw(); if (abrt) break; 1.1298 - setsub16(regs[reg].w,tempw); 1.1299 - regs[reg].w-=tempw; 1.1300 - cycles -= (mod == 3) ? 2 : 7; 1.1301 - break; 1.1302 - case 0x2C: /*SUB AL,#8*/ 1.1303 - temp=getbytef(); 1.1304 - setsub8(AL,temp); 1.1305 - AL-=temp; 1.1306 - cycles -= 3; 1.1307 - break; 1.1308 - case 0x2D: /*SUB AX,#16*/ 1.1309 - tempw=getwordf(); 1.1310 - setsub16(AX,tempw); 1.1311 - AX-=tempw; 1.1312 - cycles -= 3; 1.1313 - break; 1.1314 - 1.1315 - case 0x2E: /*CS:*/ 1.1316 - oldss=ss; 1.1317 - oldds=ds; 1.1318 - ds=ss=cs; 1.1319 - rds=CS; 1.1320 - ssegs=2; 1.1321 - cycles-=2; 1.1322 - goto opcodestart; 1.1323 - 1.1324 - case 0x2F: /*DAS*/ 1.1325 - if ((flags&A_FLAG)||((AL&0xF)>9)) 1.1326 - { 1.1327 - tempi=((uint16_t)AL)-6; 1.1328 - AL-=6; 1.1329 - flags|=A_FLAG; 1.1330 - if (tempi&0x100) flags|=C_FLAG; 1.1331 - } 1.1332 -// else 1.1333 -// flags&=~A_FLAG; 1.1334 - if ((flags&C_FLAG)||(AL>0x9F)) 1.1335 - { 1.1336 - AL-=0x60; 1.1337 - flags|=C_FLAG; 1.1338 - } 1.1339 -// else 1.1340 -// flags&=~C_FLAG; 1.1341 - tempw = flags & (C_FLAG | A_FLAG); 1.1342 - setznp8(AL); 1.1343 - flags |= tempw; 1.1344 - cycles -= 3; 1.1345 - break; 1.1346 - 1.1347 - case 0x30: /*XOR 8,reg*/ 1.1348 - fetchea(); 1.1349 - if (mod == 3) 1.1350 - { 1.1351 - temp = getr8(rm) ^ getr8(reg); 1.1352 - setr8(rm, temp); 1.1353 - setznp8(temp); 1.1354 - cycles -= 2; 1.1355 - } 1.1356 - else 1.1357 - { 1.1358 - temp = geteab(); if (abrt) break; 1.1359 - temp ^= getr8(reg); 1.1360 - seteab(temp); if (abrt) break; 1.1361 - setznp8(temp); 1.1362 - cycles -= 7; 1.1363 - } 1.1364 - break; 1.1365 - case 0x31: /*XOR 16,reg*/ 1.1366 - fetchea(); 1.1367 - if (mod == 3) 1.1368 - { 1.1369 - regs[rm].w ^= regs[reg].w; 1.1370 - setznp16(regs[rm].w); 1.1371 - cycles -= 2; 1.1372 - } 1.1373 - else 1.1374 - { 1.1375 - tempw = geteaw() ^ regs[reg].w; if (abrt) break; 1.1376 - seteaw(tempw); if (abrt) break; 1.1377 - setznp16(tempw); 1.1378 - cycles -= 7; 1.1379 - } 1.1380 - break; 1.1381 - case 0x32: /*XOR reg,8*/ 1.1382 - fetchea(); 1.1383 - temp=geteab(); if (abrt) break; 1.1384 - temp^=getr8(reg); 1.1385 - setznp8(temp); 1.1386 - setr8(reg,temp); 1.1387 - cycles -= (mod == 3) ? 2 : 7; 1.1388 - break; 1.1389 - case 0x33: /*XOR reg,16*/ 1.1390 - fetchea(); 1.1391 - tempw=geteaw(); if (abrt) break; 1.1392 - tempw^=regs[reg].w; 1.1393 - setznp16(tempw); 1.1394 - regs[reg].w=tempw; 1.1395 - cycles -= (mod == 3) ? 2 : 7; 1.1396 - break; 1.1397 - case 0x34: /*XOR AL,#8*/ 1.1398 - AL^=getbytef(); 1.1399 - setznp8(AL); 1.1400 - cycles -= 3; 1.1401 - break; 1.1402 - case 0x35: /*XOR AX,#16*/ 1.1403 - AX^=getwordf(); 1.1404 - setznp16(AX); 1.1405 - cycles -= 3; 1.1406 - break; 1.1407 - 1.1408 - case 0x36: /*SS:*/ 1.1409 - oldss=ss; 1.1410 - oldds=ds; 1.1411 - ds=ss=ss; 1.1412 - rds=SS; 1.1413 - ssegs=2; 1.1414 - cycles-=2; 1.1415 - goto opcodestart; 1.1416 -// break; 1.1417 - 1.1418 - case 0x37: /*AAA*/ 1.1419 - if ((flags&A_FLAG)||((AL&0xF)>9)) 1.1420 - { 1.1421 - AL+=6; 1.1422 - AH++; 1.1423 - flags|=(A_FLAG|C_FLAG); 1.1424 - } 1.1425 - else 1.1426 - flags&=~(A_FLAG|C_FLAG); 1.1427 - AL&=0xF; 1.1428 - cycles -= 3; 1.1429 - break; 1.1430 - 1.1431 - case 0x38: /*CMP 8,reg*/ 1.1432 - fetchea(); 1.1433 - temp=geteab(); if (abrt) break; 1.1434 - setsub8(temp,getr8(reg)); 1.1435 - cycles -= (mod == 3) ? 2 : 7; 1.1436 - break; 1.1437 - case 0x39: /*CMP 16,reg*/ 1.1438 - fetchea(); 1.1439 - tempw=geteaw(); if (abrt) break; 1.1440 -// if (output) pclog("CMP %04X %04X\n",tempw,regs[reg].w); 1.1441 - setsub16(tempw,regs[reg].w); 1.1442 - cycles -= (mod == 3) ? 2 : 7; 1.1443 - break; 1.1444 - case 0x3A: /*CMP reg,8*/ 1.1445 - fetchea(); 1.1446 - temp=geteab(); if (abrt) break; 1.1447 -// if (output) pclog("CMP %02X-%02X\n",getr8(reg),temp); 1.1448 - setsub8(getr8(reg),temp); 1.1449 - cycles -= (mod == 3) ? 2 : 6; 1.1450 - break; 1.1451 - case 0x3B: /*CMP reg,16*/ 1.1452 - fetchea(); 1.1453 - tempw=geteaw(); if (abrt) break; 1.1454 - setsub16(regs[reg].w,tempw); 1.1455 - cycles -= (mod == 3) ? 2 : 6; 1.1456 - break; 1.1457 - case 0x3C: /*CMP AL,#8*/ 1.1458 - temp=getbytef(); 1.1459 - setsub8(AL,temp); 1.1460 - cycles -= 3; 1.1461 - break; 1.1462 - case 0x3D: /*CMP AX,#16*/ 1.1463 - tempw=getwordf(); 1.1464 - setsub16(AX,tempw); 1.1465 - cycles -= 3; 1.1466 - break; 1.1467 - 1.1468 - case 0x3E: /*DS:*/ 1.1469 - oldss=ss; 1.1470 - oldds=ds; 1.1471 - ds=ss=ds; 1.1472 - ssegs=2; 1.1473 - cycles-=2; 1.1474 - goto opcodestart; 1.1475 -// break; 1.1476 - 1.1477 - case 0x3F: /*AAS*/ 1.1478 - if ((flags&A_FLAG)||((AL&0xF)>9)) 1.1479 - { 1.1480 - AL-=6; 1.1481 - AH--; 1.1482 - flags|=(A_FLAG|C_FLAG); 1.1483 - } 1.1484 - else 1.1485 - flags&=~(A_FLAG|C_FLAG); 1.1486 - AL&=0xF; 1.1487 - cycles -= 3; 1.1488 - break; 1.1489 - 1.1490 - case 0x40: case 0x41: case 0x42: case 0x43: /*INC r16*/ 1.1491 - case 0x44: case 0x45: case 0x46: case 0x47: 1.1492 - setadd16nc(regs[opcode&7].w,1); 1.1493 - regs[opcode&7].w++; 1.1494 - cycles -= 2; 1.1495 - break; 1.1496 - case 0x48: case 0x49: case 0x4A: case 0x4B: /*DEC r16*/ 1.1497 - case 0x4C: case 0x4D: case 0x4E: case 0x4F: 1.1498 - setsub16nc(regs[opcode&7].w,1); 1.1499 - regs[opcode&7].w--; 1.1500 - cycles -= 2; 1.1501 - break; 1.1502 - 1.1503 - case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/ 1.1504 - case 0x54: case 0x55: case 0x56: case 0x57: 1.1505 - if (ssegs) ss=oldss; 1.1506 - writememw(ss,(SP-2)&0xFFFF,regs[opcode&7].w); if (abrt) break; 1.1507 - SP-=2; 1.1508 - cycles -= 3; 1.1509 - break; 1.1510 - case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/ 1.1511 - case 0x5C: case 0x5D: case 0x5E: case 0x5F: 1.1512 - if (ssegs) ss=oldss; 1.1513 - SP+=2; 1.1514 - tempw=readmemw(ss,(SP-2)&0xFFFF); if (abrt) { SP-=2; break; } 1.1515 - regs[opcode&7].w=tempw; 1.1516 - cycles -= 5; 1.1517 - break; 1.1518 - 1.1519 - case 0x60: /*PUSHA*/ 1.1520 - writememw(ss,((SP-2)&0xFFFF),AX); 1.1521 - writememw(ss,((SP-4)&0xFFFF),CX); 1.1522 - writememw(ss,((SP-6)&0xFFFF),DX); 1.1523 - writememw(ss,((SP-8)&0xFFFF),BX); 1.1524 - writememw(ss,((SP-10)&0xFFFF),SP); 1.1525 - writememw(ss,((SP-12)&0xFFFF),BP); 1.1526 - writememw(ss,((SP-14)&0xFFFF),SI); 1.1527 - writememw(ss,((SP-16)&0xFFFF),DI); 1.1528 - if (!abrt) SP-=16; 1.1529 - cycles -= 17; 1.1530 - break; 1.1531 - case 0x61: /*POPA*/ 1.1532 - DI=readmemw(ss,((SP)&0xFFFF)); if (abrt) break; 1.1533 - SI=readmemw(ss,((SP+2)&0xFFFF)); if (abrt) break; 1.1534 - BP=readmemw(ss,((SP+4)&0xFFFF)); if (abrt) break; 1.1535 - BX=readmemw(ss,((SP+8)&0xFFFF)); if (abrt) break; 1.1536 - DX=readmemw(ss,((SP+10)&0xFFFF)); if (abrt) break; 1.1537 - CX=readmemw(ss,((SP+12)&0xFFFF)); if (abrt) break; 1.1538 - AX=readmemw(ss,((SP+14)&0xFFFF)); if (abrt) break; 1.1539 - SP+=16; 1.1540 - cycles -= 19; 1.1541 - break; 1.1542 - 1.1543 - case 0x62: /*BOUND*/ 1.1544 - fetchea(); 1.1545 - tempw=geteaw(); 1.1546 - tempw2=readmemw(easeg,eaaddr+2); if (abrt) break; 1.1547 - if (((int16_t)regs[reg].w<(int16_t)tempw) || ((int16_t)regs[reg].w>(int16_t)tempw2)) 1.1548 - { 1.1549 - x86_int(5); 1.1550 - } 1.1551 - cycles -= 13; 1.1552 - break; 1.1553 - 1.1554 - case 0x63: /*ARPL*/ 1.1555 - NOTRM 1.1556 - fetchea(); 1.1557 - tempw=geteaw(); if (abrt) break; 1.1558 - if ((tempw&3)<(regs[reg].w&3)) 1.1559 - { 1.1560 - tempw=(tempw&0xFFFC)|(regs[reg].w&3); 1.1561 - seteaw(tempw); if (abrt) break; 1.1562 - flags|=Z_FLAG; 1.1563 - } 1.1564 - else 1.1565 - flags&=~Z_FLAG; 1.1566 - cycles -= (mod == 3) ? 10 : 11; 1.1567 - break; 1.1568 - 1.1569 - case 0x68: /*PUSH #w*/ 1.1570 - tempw=getword(); 1.1571 - writememw(ss,((SP-2)&0xFFFF),tempw); if (abrt) break; 1.1572 - SP-=2; 1.1573 - cycles -= 3; 1.1574 - break; 1.1575 - case 0x69: /*IMUL r16*/ 1.1576 - fetchea(); 1.1577 - tempw=geteaw(); if (abrt) break; 1.1578 - tempw2=getword(); if (abrt) break; 1.1579 - templ=((int)(int16_t)tempw)*((int)(int16_t)tempw2); 1.1580 - if ((templ>>16)!=0 && (templ>>16)!=0xFFFF) flags|=C_FLAG|V_FLAG; 1.1581 - else flags&=~(C_FLAG|V_FLAG); 1.1582 - regs[reg].w=templ&0xFFFF; 1.1583 - cycles -= (mod == 3) ? 21 : 24; 1.1584 - break; 1.1585 - case 0x6A: /*PUSH #eb*/ 1.1586 - tempw=readmemb(cs,pc); pc++; 1.1587 - if (tempw&0x80) tempw|=0xFF00; 1.1588 - writememw(ss,((SP-2)&0xFFFF),tempw); if (abrt) break; 1.1589 - SP-=2; 1.1590 - cycles -= 3; 1.1591 - break; 1.1592 - case 0x6B: /*IMUL r8*/ 1.1593 - fetchea(); 1.1594 - tempw=geteaw(); if (abrt) break; 1.1595 - tempw2=readmemb(cs,pc); pc++; if (abrt) break; 1.1596 - if (tempw2&0x80) tempw2|=0xFF00; 1.1597 - templ=((int)(int16_t)tempw)*((int)(int16_t)tempw2); 1.1598 - if ((templ>>16)!=0 && ((templ>>16)&0xFFFF)!=0xFFFF) flags|=C_FLAG|V_FLAG; 1.1599 - else flags&=~(C_FLAG|V_FLAG); 1.1600 - regs[reg].w=templ&0xFFFF; 1.1601 - cycles -= (mod == 3) ? 21 : 24; 1.1602 - break; 1.1603 - 1.1604 - case 0x6C: /*INSB*/ 1.1605 - checkio_perm(DX); 1.1606 - temp=inb(DX); 1.1607 - writememb(es,DI,temp); if (abrt) break; 1.1608 - if (flags&D_FLAG) DI--; 1.1609 - else DI++; 1.1610 - cycles -= 5; 1.1611 - break; 1.1612 - case 0x6D: /*INSW*/ 1.1613 - checkio_perm(DX); 1.1614 - checkio_perm(DX+1); 1.1615 - tempw=inw(DX); 1.1616 - writememw(es,DI,tempw); if (abrt) break; 1.1617 - if (flags&D_FLAG) DI-=2; 1.1618 - else DI+=2; 1.1619 - cycles -= 5; 1.1620 - break; 1.1621 - case 0x6E: /*OUTSB*/ 1.1622 - temp=readmemb(ds,SI); if (abrt) break; 1.1623 - checkio_perm(DX); 1.1624 - if (flags&D_FLAG) SI--; 1.1625 - else SI++; 1.1626 - outb(DX,temp); 1.1627 - cycles -= 5; 1.1628 - break; 1.1629 - case 0x6F: /*OUTSW*/ 1.1630 - tempw=readmemw(ds,SI); if (abrt) break; 1.1631 - checkio_perm(DX); 1.1632 - checkio_perm(DX+1); 1.1633 - if (flags&D_FLAG) SI-=2; 1.1634 - else SI+=2; 1.1635 - outw(DX,tempw); 1.1636 -// outb(DX+1,tempw>>8); 1.1637 - cycles -= 5; 1.1638 - break; 1.1639 - 1.1640 - case 0x70: /*JO*/ 1.1641 - offset=(int8_t)getbytef(); 1.1642 - if (flags&V_FLAG) { pc += offset; cycles -= 4; cycles -= 2; } 1.1643 - cycles -= 3; 1.1644 - break; 1.1645 - case 0x71: /*JNO*/ 1.1646 - offset=(int8_t)getbytef(); 1.1647 - if (!(flags&V_FLAG)) { pc += offset; cycles -= 4; cycles -= 2; } 1.1648 - cycles -= 3; 1.1649 - break; 1.1650 - case 0x72: /*JB*/ 1.1651 - offset=(int8_t)getbytef(); 1.1652 - if (flags&C_FLAG) { pc += offset; cycles -= 4; cycles -= 2; } 1.1653 - cycles -= 3; 1.1654 - break; 1.1655 - case 0x73: /*JNB*/ 1.1656 - offset=(int8_t)getbytef(); 1.1657 - if (!(flags&C_FLAG)) { pc += offset; cycles -= 4; cycles -= 2; } 1.1658 - cycles -= 3; 1.1659 - break; 1.1660 - case 0x74: /*JZ*/ 1.1661 - offset=(int8_t)getbytef(); 1.1662 - if (flags&Z_FLAG) { pc += offset; cycles -= 4; cycles -= 2; } 1.1663 - cycles -= 3; 1.1664 - break; 1.1665 - case 0x75: /*JNZ*/ 1.1666 - offset=(int8_t)getbytef(); 1.1667 - if (!(flags&Z_FLAG)) { pc += offset; cycles -= 4; cycles -= 2; } 1.1668 - cycles -= 3; 1.1669 - break; 1.1670 - case 0x76: /*JBE*/ 1.1671 - offset=(int8_t)getbytef(); 1.1672 - if (flags&(C_FLAG|Z_FLAG)) { pc += offset; cycles -= 4; cycles -= 2; } 1.1673 - cycles -= 3; 1.1674 - break; 1.1675 - case 0x77: /*JNBE*/ 1.1676 - offset=(int8_t)getbytef(); 1.1677 - if (!(flags&(C_FLAG|Z_FLAG))) { pc += offset; cycles -= 4; cycles -= 2; } 1.1678 - cycles -= 3; 1.1679 - break; 1.1680 - case 0x78: /*JS*/ 1.1681 - offset=(int8_t)getbytef(); 1.1682 - if (flags&N_FLAG) { pc += offset; cycles -= 4; cycles -= 2; } 1.1683 - cycles -= 3; 1.1684 - break; 1.1685 - case 0x79: /*JNS*/ 1.1686 - offset=(int8_t)getbytef(); 1.1687 - if (!(flags&N_FLAG)) { pc += offset; cycles -= 4; cycles -= 2; } 1.1688 - cycles -= 3; 1.1689 - break; 1.1690 - case 0x7A: /*JP*/ 1.1691 - offset=(int8_t)getbytef(); 1.1692 - if (flags&P_FLAG) { pc += offset; cycles -= 4; cycles -= 2; } 1.1693 - cycles -= 3; 1.1694 - break; 1.1695 - case 0x7B: /*JNP*/ 1.1696 - offset=(int8_t)getbytef(); 1.1697 - if (!(flags&P_FLAG)) { pc += offset; cycles -= 4; cycles -= 2; } 1.1698 - cycles -= 3; 1.1699 - break; 1.1700 - case 0x7C: /*JL*/ 1.1701 - offset=(int8_t)getbytef(); 1.1702 - temp=(flags&N_FLAG)?1:0; 1.1703 - temp2=(flags&V_FLAG)?1:0; 1.1704 - if (temp!=temp2) { pc += offset; cycles -= 4; cycles -= 2; } 1.1705 - cycles -= 3; 1.1706 - break; 1.1707 - case 0x7D: /*JNL*/ 1.1708 - offset=(int8_t)getbytef(); 1.1709 - temp=(flags&N_FLAG)?1:0; 1.1710 - temp2=(flags&V_FLAG)?1:0; 1.1711 - if (temp==temp2) { pc += offset; cycles -= 4; cycles -= 2; } 1.1712 - cycles -= 3; 1.1713 - break; 1.1714 - case 0x7E: /*JLE*/ 1.1715 - offset=(int8_t)getbytef(); 1.1716 - temp=(flags&N_FLAG)?1:0; 1.1717 - temp2=(flags&V_FLAG)?1:0; 1.1718 - if ((flags&Z_FLAG) || (temp!=temp2)) { pc += offset; cycles -= 4; cycles -= 2; } 1.1719 - cycles -= 3; 1.1720 - break; 1.1721 - case 0x7F: /*JNLE*/ 1.1722 - offset=(int8_t)getbytef(); 1.1723 - temp=(flags&N_FLAG)?1:0; 1.1724 - temp2=(flags&V_FLAG)?1:0; 1.1725 - if (!((flags&Z_FLAG) || (temp!=temp2))) { pc += offset; cycles -= 4; cycles -= 2; } 1.1726 - cycles -= 3; 1.1727 - break; 1.1728 - 1.1729 - 1.1730 - case 0x80: 1.1731 - case 0x82: 1.1732 - fetchea(); 1.1733 - temp=geteab(); if (abrt) break; 1.1734 - temp2=readmemb(cs,pc); pc++; if (abrt) break; 1.1735 - switch (rmdat&0x38) 1.1736 - { 1.1737 - case 0x00: /*ADD b,#8*/ 1.1738 - seteab(temp+temp2); if (abrt) break; 1.1739 - setadd8(temp,temp2); 1.1740 - cycles -= (mod == 3) ? 3 : 7; 1.1741 - break; 1.1742 - case 0x08: /*OR b,#8*/ 1.1743 - temp|=temp2; 1.1744 - seteab(temp); if (abrt) break; 1.1745 - setznp8(temp); 1.1746 - cycles -= (mod == 3) ? 3 : 7; 1.1747 - break; 1.1748 - case 0x10: /*ADC b,#8*/ 1.1749 - seteab(temp+temp2+tempc); if (abrt) break; 1.1750 - setadc8(temp,temp2); 1.1751 - cycles -= (mod == 3) ? 3 : 7; 1.1752 - break; 1.1753 - case 0x18: /*SBB b,#8*/ 1.1754 - seteab(temp-(temp2+tempc)); if (abrt) break; 1.1755 - setsbc8(temp,temp2); 1.1756 - cycles -= (mod == 3) ? 3 : 7; 1.1757 - break; 1.1758 - case 0x20: /*AND b,#8*/ 1.1759 - temp&=temp2; 1.1760 - seteab(temp); if (abrt) break; 1.1761 - setznp8(temp); 1.1762 - cycles -= (mod == 3) ? 3 : 7; 1.1763 - break; 1.1764 - case 0x28: /*SUB b,#8*/ 1.1765 - seteab(temp-temp2); if (abrt) break; 1.1766 - setsub8(temp,temp2); 1.1767 - cycles -= (mod == 3) ? 3 : 7; 1.1768 - break; 1.1769 - case 0x30: /*XOR b,#8*/ 1.1770 - temp^=temp2; 1.1771 - seteab(temp); if (abrt) break; 1.1772 - setznp8(temp); 1.1773 - cycles -= (mod == 3) ? 3 : 7; 1.1774 - break; 1.1775 - case 0x38: /*CMP b,#8*/ 1.1776 - setsub8(temp,temp2); 1.1777 - cycles -= (mod == 3) ? 3 : 6; 1.1778 - break; 1.1779 - 1.1780 -// default: 1.1781 -// pclog("Bad 80 opcode %02X\n",rmdat&0x38); 1.1782 -// dumpregs(); 1.1783 -// exit(-1); 1.1784 - } 1.1785 - break; 1.1786 - 1.1787 - case 0x81: 1.1788 - fetchea(); 1.1789 - tempw=geteaw(); if (abrt) break; 1.1790 - tempw2=getword(); if (abrt) break; 1.1791 - switch (rmdat&0x38) 1.1792 - { 1.1793 - case 0x00: /*ADD w,#16*/ 1.1794 - seteaw(tempw+tempw2); if (abrt) break; 1.1795 - setadd16(tempw,tempw2); 1.1796 - cycles -= (mod == 3) ? 3 : 7; 1.1797 - break; 1.1798 - case 0x08: /*OR w,#16*/ 1.1799 - tempw|=tempw2; 1.1800 - seteaw(tempw); if (abrt) break; 1.1801 - setznp16(tempw); 1.1802 - cycles -= (mod == 3) ? 3 : 7; 1.1803 - break; 1.1804 - case 0x10: /*ADC w,#16*/ 1.1805 - seteaw(tempw+tempw2+tempc); if (abrt) break; 1.1806 - setadc16(tempw,tempw2); 1.1807 - cycles -= (mod == 3) ? 3 : 7; 1.1808 - break; 1.1809 - case 0x20: /*AND w,#16*/ 1.1810 - tempw&=tempw2; 1.1811 - seteaw(tempw); if (abrt) break; 1.1812 - setznp16(tempw); 1.1813 - cycles -= (mod == 3) ? 3 : 7; 1.1814 - break; 1.1815 - case 0x18: /*SBB w,#16*/ 1.1816 - seteaw(tempw-(tempw2+tempc)); if (abrt) break; 1.1817 - setsbc16(tempw,tempw2); 1.1818 - cycles -= (mod == 3) ? 3 : 7; 1.1819 - break; 1.1820 - case 0x28: /*SUB w,#16*/ 1.1821 - seteaw(tempw-tempw2); if (abrt) break; 1.1822 - setsub16(tempw,tempw2); 1.1823 - cycles -= (mod == 3) ? 3 : 7; 1.1824 - break; 1.1825 - case 0x30: /*XOR w,#16*/ 1.1826 - tempw^=tempw2; 1.1827 - seteaw(tempw); if (abrt) break; 1.1828 - setznp16(tempw); 1.1829 - cycles -= (mod == 3) ? 3 : 7; 1.1830 - break; 1.1831 - case 0x38: /*CMP w,#16*/ 1.1832 -// pclog("CMP %04X %04X\n", tempw, tempw2); 1.1833 - setsub16(tempw,tempw2); 1.1834 - cycles -= (mod == 3) ? 3 : 6; 1.1835 - break; 1.1836 - } 1.1837 - break; 1.1838 - 1.1839 - case 0x83: 1.1840 - fetchea(); 1.1841 - tempw=geteaw(); if (abrt) break; 1.1842 - tempw2=readmemb(cs,pc); pc++; if (abrt) break; 1.1843 - if (tempw2&0x80) tempw2|=0xFF00; 1.1844 - switch (rmdat&0x38) 1.1845 - { 1.1846 - case 0x00: /*ADD w,#8*/ 1.1847 - seteaw(tempw+tempw2); if (abrt) break; 1.1848 - setadd16(tempw,tempw2); 1.1849 - cycles -= (mod == 3) ? 3 : 7; 1.1850 - break; 1.1851 - case 0x08: /*OR w,#8*/ 1.1852 - tempw|=tempw2; 1.1853 - seteaw(tempw); if (abrt) break; 1.1854 - setznp16(tempw); 1.1855 - cycles -= (mod == 3) ? 3 : 7; 1.1856 - break; 1.1857 - case 0x10: /*ADC w,#8*/ 1.1858 - seteaw(tempw+tempw2+tempc); if (abrt) break; 1.1859 - setadc16(tempw,tempw2); 1.1860 - cycles -= (mod == 3) ? 3 : 7; 1.1861 - break; 1.1862 - case 0x18: /*SBB w,#8*/ 1.1863 - seteaw(tempw-(tempw2+tempc)); if (abrt) break; 1.1864 - setsbc16(tempw,tempw2); 1.1865 - cycles -= (mod == 3) ? 3 : 7; 1.1866 - break; 1.1867 - case 0x20: /*AND w,#8*/ 1.1868 - tempw&=tempw2; 1.1869 - seteaw(tempw); if (abrt) break; 1.1870 - setznp16(tempw); 1.1871 - cycles -= (mod == 3) ? 3 : 7; 1.1872 - break; 1.1873 - case 0x28: /*SUB w,#8*/ 1.1874 - seteaw(tempw-tempw2); if (abrt) break; 1.1875 - setsub16(tempw,tempw2); 1.1876 - cycles -= (mod == 3) ? 3 : 7; 1.1877 - break; 1.1878 - case 0x30: /*XOR w,#8*/ 1.1879 - tempw^=tempw2; 1.1880 - seteaw(tempw); if (abrt) break; 1.1881 - setznp16(tempw); 1.1882 - cycles -= (mod == 3) ? 3 : 7; 1.1883 - break; 1.1884 - case 0x38: /*CMP w,#8*/ 1.1885 - setsub16(tempw,tempw2); 1.1886 - cycles -= (mod == 3) ? 3 : 6; 1.1887 - break; 1.1888 - 1.1889 -// default: 1.1890 -// pclog("Bad 83 opcode %02X\n",rmdat&0x38); 1.1891 -// dumpregs(); 1.1892 -// exit(-1); 1.1893 - } 1.1894 - break; 1.1895 - 1.1896 - case 0x84: /*TEST b,reg*/ 1.1897 - fetchea(); 1.1898 - temp=geteab(); if (abrt) break; 1.1899 - temp2=getr8(reg); 1.1900 - setznp8(temp&temp2); 1.1901 - cycles -= (mod == 3) ? 2 : 6; 1.1902 - break; 1.1903 - case 0x85: /*TEST w,reg*/ 1.1904 - fetchea(); 1.1905 - tempw=geteaw(); if (abrt) break; 1.1906 - tempw2=regs[reg].w; 1.1907 - setznp16(tempw&tempw2); 1.1908 - cycles -= (mod == 3) ? 2 : 6; 1.1909 - break; 1.1910 - case 0x86: /*XCHG b,reg*/ 1.1911 - fetchea(); 1.1912 - temp=geteab(); if (abrt) break; 1.1913 - seteab(getr8(reg)); if (abrt) break; 1.1914 - setr8(reg,temp); 1.1915 - cycles -= (mod == 3) ? 3 : 5; 1.1916 - break; 1.1917 - case 0x87: /*XCHG w,reg*/ 1.1918 - fetchea(); 1.1919 - tempw=geteaw(); if (abrt) break; 1.1920 - seteaw(regs[reg].w); if (abrt) break; 1.1921 - regs[reg].w=tempw; 1.1922 - cycles -= (mod == 3) ? 3 : 5; 1.1923 - break; 1.1924 - 1.1925 - case 0x88: /*MOV b,reg*/ 1.1926 - fetchea(); 1.1927 - seteab(getr8(reg)); 1.1928 - cycles -= (mod == 3) ? 2 : 3; 1.1929 - break; 1.1930 - case 0x89: /*MOV w,reg*/ 1.1931 - fetchea(); 1.1932 - seteaw(regs[reg].w); 1.1933 - cycles -= (mod == 3) ? 2 : 3; 1.1934 - break; 1.1935 - case 0x8A: /*MOV reg,b*/ 1.1936 - fetchea(); 1.1937 - temp=geteab(); if (abrt) break; 1.1938 - setr8(reg,temp); 1.1939 - cycles -= (mod == 3) ? 5 : 3; 1.1940 - break; 1.1941 - case 0x8B: /*MOV reg,w*/ 1.1942 - fetchea(); 1.1943 - tempw=geteaw(); if (abrt) break; 1.1944 - regs[reg].w=tempw; 1.1945 - cycles -= (mod == 3) ? 5 : 3; 1.1946 - break; 1.1947 - 1.1948 - case 0x8C: /*MOV w,sreg*/ 1.1949 - fetchea(); 1.1950 - switch (rmdat&0x38) 1.1951 - { 1.1952 - case 0x00: /*ES*/ 1.1953 - seteaw(ES); 1.1954 - break; 1.1955 - case 0x08: /*CS*/ 1.1956 - seteaw(CS); 1.1957 - break; 1.1958 - case 0x18: /*DS*/ 1.1959 - if (ssegs) ds=oldds; 1.1960 - seteaw(DS); 1.1961 - break; 1.1962 - case 0x10: /*SS*/ 1.1963 - if (ssegs) ss=oldss; 1.1964 - seteaw(SS); 1.1965 - break; 1.1966 - } 1.1967 - cycles -= (mod == 3) ? 2 : 3; 1.1968 - break; 1.1969 - 1.1970 - case 0x8D: /*LEA*/ 1.1971 - fetchea(); 1.1972 - regs[reg].w=eaaddr; 1.1973 - cycles -= 3; 1.1974 - break; 1.1975 - 1.1976 - case 0x8E: /*MOV sreg,w*/ 1.1977 - fetchea(); 1.1978 - switch (rmdat&0x38) 1.1979 - { 1.1980 - case 0x00: /*ES*/ 1.1981 - tempw=geteaw(); if (abrt) break; 1.1982 - loadseg(tempw,&_es); 1.1983 - break; 1.1984 - case 0x18: /*DS*/ 1.1985 - tempw=geteaw(); if (abrt) break; 1.1986 - loadseg(tempw,&_ds); 1.1987 - if (ssegs) oldds=ds; 1.1988 - break; 1.1989 - case 0x10: /*SS*/ 1.1990 -// if (output==3) pclog("geteaw\n"); 1.1991 - tempw=geteaw(); if (abrt) break; 1.1992 -// if (output==3) pclog("loadseg\n"); 1.1993 - loadseg(tempw,&_ss); 1.1994 -// if (output==3) pclog("done\n"); 1.1995 - if (ssegs) oldss=ss; 1.1996 - skipnextprint=1; 1.1997 - noint=1; 1.1998 - break; 1.1999 - } 1.2000 - if (msw & 1) cycles -= (mod == 3) ? 17 : 19; 1.2001 - else cycles -= (mod == 3) ? 2 : 5; 1.2002 - break; 1.2003 - 1.2004 - case 0x8F: /*POPW*/ 1.2005 - if (ssegs) templ2=oldss; 1.2006 - else templ2=ss; 1.2007 - tempw=readmemw(templ2,SP); if (abrt) break; 1.2008 - SP+=2; 1.2009 - fetchea(); 1.2010 - if (ssegs) ss=oldss; 1.2011 - seteaw(tempw); 1.2012 - if (abrt) SP-=2; 1.2013 - cycles -= 5; 1.2014 - break; 1.2015 - 1.2016 - case 0x90: /*NOP*/ 1.2017 - cycles -= 3; 1.2018 - break; 1.2019 - 1.2020 - case 0x91: case 0x92: case 0x93: /*XCHG AX*/ 1.2021 - case 0x94: case 0x95: case 0x96: case 0x97: 1.2022 - tempw=AX; 1.2023 - AX=regs[opcode&7].w; 1.2024 - regs[opcode&7].w=tempw; 1.2025 - cycles -= 3; 1.2026 - break; 1.2027 - 1.2028 - case 0x98: /*CBW*/ 1.2029 - AH=(AL&0x80)?0xFF:0; 1.2030 - cycles -= 2; 1.2031 - break; 1.2032 - case 0x99: /*CWD*/ 1.2033 - DX=(AX&0x8000)?0xFFFF:0; 1.2034 - cycles -= 2; 1.2035 - break; 1.2036 - case 0x9A: /*CALL FAR*/ 1.2037 - tempw=getword(); 1.2038 - tempw2=getword(); if (abrt) break; 1.2039 - tempw3 = CS; 1.2040 - templ2 = pc; 1.2041 - if (ssegs) ss=oldss; 1.2042 - oxpc=pc; 1.2043 - pc=tempw; 1.2044 - optype=CALL; 1.2045 - if (msw&1) loadcscall(tempw2); 1.2046 - else loadcs(tempw2); 1.2047 - optype=0; 1.2048 - if (abrt) break; 1.2049 - oldss=ss; 1.2050 - writememw(ss,(SP-2)&0xFFFF,tempw3); 1.2051 - writememw(ss,(SP-4)&0xFFFF,templ2); if (abrt) break; 1.2052 - SP-=4; 1.2053 - cycles -= (msw & 1) ? 26 : 13; 1.2054 - break; 1.2055 - case 0x9B: /*WAIT*/ 1.2056 - cycles -= 3; 1.2057 - break; 1.2058 - case 0x9C: /*PUSHF*/ 1.2059 - if (ssegs) ss=oldss; 1.2060 - if (msw & 1) { writememw(ss, ((SP-2)&0xFFFF), flags & 0x7fff); } 1.2061 - else { writememw(ss, ((SP-2)&0xFFFF), flags & 0x0fff); } 1.2062 - if (abrt) break; 1.2063 - SP-=2; 1.2064 - cycles -= 3; 1.2065 - break; 1.2066 - case 0x9D: /*POPF*/ 1.2067 - if (ssegs) ss=oldss; 1.2068 - tempw=readmemw(ss,SP); if (abrt) break; 1.2069 - SP+=2; 1.2070 - if (!(CPL) || !(msw&1)) flags=(tempw&0xFFD5)|2; 1.2071 - else if (IOPLp) flags=(flags&0x3000)|(tempw&0x4FD5)|2; 1.2072 - else flags=(flags&0x7200)|(tempw&0x0DD5)|2; 1.2073 - pclog("POPF %04X %04X %04X:%04X\n", tempw, flags, CS, pc); 1.2074 - cycles -= 5; 1.2075 - break; 1.2076 - case 0x9E: /*SAHF*/ 1.2077 - flags=(flags&0xFF00)|(AH&0xD5)|2; 1.2078 - cycles -= 2; 1.2079 - break; 1.2080 - case 0x9F: /*LAHF*/ 1.2081 - AH=flags&0xFF; 1.2082 - cycles -= 2; 1.2083 - break; 1.2084 - 1.2085 - case 0xA0: /*MOV AL,(w)*/ 1.2086 - addr=getword(); if (abrt) break; 1.2087 - temp=readmemb(ds,addr); if (abrt) break; 1.2088 - AL=temp; 1.2089 - cycles -= 5; 1.2090 - break; 1.2091 - case 0xA1: /*MOV AX,(w)*/ 1.2092 - addr=getword(); if (abrt) break; 1.2093 - tempw=readmemw(ds,addr); if (abrt) break; 1.2094 - AX=tempw; 1.2095 - cycles -= 5; 1.2096 - break; 1.2097 - case 0xA2: /*MOV (w),AL*/ 1.2098 - addr=getword(); if (abrt) break; 1.2099 - writememb(ds,addr,AL); 1.2100 - cycles -= 3; 1.2101 - break; 1.2102 - case 0xA3: /*MOV (w),AX*/ 1.2103 - addr=getword(); if (abrt) break; 1.2104 - writememw(ds,addr,AX); 1.2105 - cycles -= 3; 1.2106 - break; 1.2107 - 1.2108 - case 0xA4: /*MOVSB*/ 1.2109 - temp=readmemb(ds,SI); if (abrt) break; 1.2110 - writememb(es,DI,temp); if (abrt) break; 1.2111 - if (flags&D_FLAG) { DI--; SI--; } 1.2112 - else { DI++; SI++; } 1.2113 - cycles -= 5; 1.2114 - break; 1.2115 - case 0xA5: /*MOVSW*/ 1.2116 - tempw=readmemw(ds,SI); if (abrt) break; 1.2117 - writememw(es,DI,tempw); if (abrt) break; 1.2118 - if (flags&D_FLAG) { DI-=2; SI-=2; } 1.2119 - else { DI+=2; SI+=2; } 1.2120 - cycles -= 5; 1.2121 - break; 1.2122 - case 0xA6: /*CMPSB*/ 1.2123 - temp =readmemb(ds,SI); 1.2124 - temp2=readmemb(es,DI); 1.2125 - if (abrt) break; 1.2126 - setsub8(temp,temp2); 1.2127 - if (flags&D_FLAG) { DI--; SI--; } 1.2128 - else { DI++; SI++; } 1.2129 - cycles -= 8; 1.2130 - break; 1.2131 - case 0xA7: /*CMPSW*/ 1.2132 - tempw =readmemw(ds,SI); 1.2133 - tempw2=readmemw(es,DI); 1.2134 - if (abrt) break; 1.2135 - setsub16(tempw,tempw2); 1.2136 - if (flags&D_FLAG) { DI-=2; SI-=2; } 1.2137 - else { DI+=2; SI+=2; } 1.2138 - cycles -= 8; 1.2139 - break; 1.2140 - case 0xA8: /*TEST AL,#8*/ 1.2141 - temp=getbytef(); 1.2142 - setznp8(AL&temp); 1.2143 - cycles -= 3; 1.2144 - break; 1.2145 - case 0xA9: /*TEST AX,#16*/ 1.2146 - tempw=getwordf(); 1.2147 - setznp16(AX&tempw); 1.2148 - cycles -= 3; 1.2149 - break; 1.2150 - case 0xAA: /*STOSB*/ 1.2151 - writememb(es,DI,AL); if (abrt) break; 1.2152 - if (flags&D_FLAG) DI--; 1.2153 - else DI++; 1.2154 - cycles -= 3; 1.2155 - break; 1.2156 - case 0xAB: /*STOSW*/ 1.2157 - writememw(es,DI,AX); if (abrt) break; 1.2158 - if (flags&D_FLAG) DI-=2; 1.2159 - else DI+=2; 1.2160 - cycles -= 3; 1.2161 - break; 1.2162 - case 0xAC: /*LODSB*/ 1.2163 - temp=readmemb(ds,SI); 1.2164 - if (abrt) break; 1.2165 - AL=temp; 1.2166 - if (flags&D_FLAG) SI--; 1.2167 - else SI++; 1.2168 - cycles -= 5; 1.2169 - break; 1.2170 - case 0xAD: /*LODSW*/ 1.2171 - tempw=readmemw(ds,SI); 1.2172 - if (abrt) break; 1.2173 - AX=tempw; 1.2174 -// if (output) pclog("Load from %05X:%04X\n",ds,SI); 1.2175 - if (flags&D_FLAG) SI-=2; 1.2176 - else SI+=2; 1.2177 - cycles -= 5; 1.2178 - break; 1.2179 - case 0xAE: /*SCASB*/ 1.2180 - temp=readmemb(es,DI); 1.2181 - if (abrt) break; 1.2182 - setsub8(AL,temp); 1.2183 - if (flags&D_FLAG) DI--; 1.2184 - else DI++; 1.2185 - cycles -= 7; 1.2186 - break; 1.2187 - case 0xAF: /*SCASW*/ 1.2188 - tempw=readmemw(es,DI); 1.2189 - if (abrt) break; 1.2190 - setsub16(AX,tempw); 1.2191 - if (flags&D_FLAG) DI-=2; 1.2192 - else DI+=2; 1.2193 - cycles -= 7; 1.2194 - break; 1.2195 - 1.2196 - case 0xB0: /*MOV AL,#8*/ 1.2197 - AL=getbytef(); 1.2198 - cycles -= 2; 1.2199 - break; 1.2200 - case 0xB1: /*MOV CL,#8*/ 1.2201 - CL=getbytef(); 1.2202 - cycles -= 2; 1.2203 - break; 1.2204 - case 0xB2: /*MOV DL,#8*/ 1.2205 - DL=getbytef(); 1.2206 - cycles -= 2; 1.2207 - break; 1.2208 - case 0xB3: /*MOV BL,#8*/ 1.2209 - BL=getbytef(); 1.2210 - cycles -= 2; 1.2211 - break; 1.2212 - case 0xB4: /*MOV AH,#8*/ 1.2213 - AH=getbytef(); 1.2214 - cycles -= 2; 1.2215 - break; 1.2216 - case 0xB5: /*MOV CH,#8*/ 1.2217 - CH=getbytef(); 1.2218 - cycles -= 2; 1.2219 - break; 1.2220 - case 0xB6: /*MOV DH,#8*/ 1.2221 - DH=getbytef(); 1.2222 - cycles -= 2; 1.2223 - break; 1.2224 - case 0xB7: /*MOV BH,#8*/ 1.2225 - BH=getbytef(); 1.2226 - cycles -= 2; 1.2227 - break; 1.2228 - case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV reg,#16*/ 1.2229 - case 0xBC: case 0xBD: case 0xBE: case 0xBF: 1.2230 - regs[opcode&7].w=getwordf(); 1.2231 - cycles -= 2; 1.2232 - break; 1.2233 - 1.2234 - case 0xC0: 1.2235 - fetchea(); 1.2236 - c=readmemb(cs,pc); pc++; 1.2237 - temp=geteab(); if (abrt) break; 1.2238 - c&=31; 1.2239 - if (!c) break; 1.2240 - cycles -= c; 1.2241 - switch (rmdat&0x38) 1.2242 - { 1.2243 - case 0x00: /*ROL b,CL*/ 1.2244 - while (c>0) 1.2245 - { 1.2246 - temp2=(temp&0x80)?1:0; 1.2247 - temp=(temp<<1)|temp2; 1.2248 - c--; 1.2249 - } 1.2250 - seteab(temp); if (abrt) break; 1.2251 - flags&=~(C_FLAG|V_FLAG); 1.2252 - if (temp2) flags|=C_FLAG; 1.2253 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.2254 - cycles -= (mod == 3) ? 5 : 8; 1.2255 - break; 1.2256 - case 0x08: /*ROR b,CL*/ 1.2257 - while (c>0) 1.2258 - { 1.2259 - temp2=temp&1; 1.2260 - temp>>=1; 1.2261 - if (temp2) temp|=0x80; 1.2262 - c--; 1.2263 - } 1.2264 - seteab(temp); if (abrt) break; 1.2265 - flags&=~(C_FLAG|V_FLAG); 1.2266 - if (temp2) flags|=C_FLAG; 1.2267 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.2268 - cycles -= (mod == 3) ? 5 : 8; 1.2269 - break; 1.2270 - case 0x10: /*RCL b,CL*/ 1.2271 - temp2=flags&C_FLAG; 1.2272 - while (c>0) 1.2273 - { 1.2274 - tempc=(temp2)?1:0; 1.2275 - temp2=temp&0x80; 1.2276 - temp=(temp<<1)|tempc; 1.2277 - c--; 1.2278 - if (is486) cycles--; 1.2279 - } 1.2280 - seteab(temp); if (abrt) break; 1.2281 - flags&=~(C_FLAG|V_FLAG); 1.2282 - if (temp2) flags|=C_FLAG; 1.2283 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.2284 - cycles -= (mod == 3) ? 5 : 8; 1.2285 - break; 1.2286 - case 0x18: /*RCR b,CL*/ 1.2287 - temp2=flags&C_FLAG; 1.2288 - while (c>0) 1.2289 - { 1.2290 - tempc=(temp2)?0x80:0; 1.2291 - temp2=temp&1; 1.2292 - temp=(temp>>1)|tempc; 1.2293 - c--; 1.2294 - if (is486) cycles--; 1.2295 - } 1.2296 - seteab(temp); if (abrt) break; 1.2297 - flags&=~(C_FLAG|V_FLAG); 1.2298 - if (temp2) flags|=C_FLAG; 1.2299 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.2300 - cycles -= (mod == 3) ? 5 : 8; 1.2301 - break; 1.2302 - case 0x20: case 0x30: /*SHL b,CL*/ 1.2303 - seteab(temp<<c); if (abrt) break; 1.2304 - setznp8(temp<<c); 1.2305 - if ((temp<<(c-1))&0x80) flags|=C_FLAG; 1.2306 - if (((temp<<c)^(temp<<(c-1)))&0x80) flags|=V_FLAG; 1.2307 - cycles -= (mod == 3) ? 5 : 8; 1.2308 - break; 1.2309 - case 0x28: /*SHR b,CL*/ 1.2310 - seteab(temp>>c); if (abrt) break; 1.2311 - setznp8(temp>>c); 1.2312 - if ((temp>>(c-1))&1) flags|=C_FLAG; 1.2313 - if (c==1 && temp&0x80) flags|=V_FLAG; 1.2314 - cycles -= (mod == 3) ? 5 : 8; 1.2315 - break; 1.2316 - case 0x38: /*SAR b,CL*/ 1.2317 - tempc=((temp>>(c-1))&1); 1.2318 - while (c>0) 1.2319 - { 1.2320 - temp>>=1; 1.2321 - if (temp&0x40) temp|=0x80; 1.2322 - c--; 1.2323 - } 1.2324 - seteab(temp); if (abrt) break; 1.2325 - setznp8(temp); 1.2326 - if (tempc) flags|=C_FLAG; 1.2327 - cycles -= (mod == 3) ? 5 : 8; 1.2328 - break; 1.2329 - 1.2330 -// default: 1.2331 -// pclog("Bad C0 opcode %02X\n",rmdat&0x38); 1.2332 -// dumpregs(); 1.2333 -// exit(-1); 1.2334 - } 1.2335 - break; 1.2336 - 1.2337 - case 0xC1: 1.2338 - fetchea(); 1.2339 - c=readmemb(cs,pc)&31; pc++; 1.2340 - tempw=geteaw(); if (abrt) break; 1.2341 - if (!c) break; 1.2342 - cycles -= c; 1.2343 - switch (rmdat&0x38) 1.2344 - { 1.2345 - case 0x00: /*ROL w,CL*/ 1.2346 - while (c>0) 1.2347 - { 1.2348 - temp=(tempw&0x8000)?1:0; 1.2349 - tempw=(tempw<<1)|temp; 1.2350 - c--; 1.2351 - } 1.2352 - seteaw(tempw); if (abrt) break; 1.2353 - flags&=~(C_FLAG|V_FLAG); 1.2354 - if (temp) flags|=C_FLAG; 1.2355 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.2356 - cycles -= (mod == 3) ? 5 : 8; 1.2357 - break; 1.2358 - case 0x08: /*ROR w,CL*/ 1.2359 - while (c>0) 1.2360 - { 1.2361 - tempw2=(tempw&1)?0x8000:0; 1.2362 - tempw=(tempw>>1)|tempw2; 1.2363 - c--; 1.2364 - } 1.2365 - seteaw(tempw); if (abrt) break; 1.2366 - flags&=~(C_FLAG|V_FLAG); 1.2367 - if (tempw2) flags|=C_FLAG; 1.2368 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.2369 - cycles -= (mod == 3) ? 5 : 8; 1.2370 - break; 1.2371 - case 0x10: /*RCL w,CL*/ 1.2372 - temp2=flags&C_FLAG; 1.2373 - while (c>0) 1.2374 - { 1.2375 - tempc=(temp2)?1:0; 1.2376 - temp2=(tempw>>15); 1.2377 - tempw=(tempw<<1)|tempc; 1.2378 - c--; 1.2379 - if (is486) cycles--; 1.2380 - } 1.2381 - seteaw(tempw); if (abrt) break; 1.2382 - flags&=~(C_FLAG|V_FLAG); 1.2383 - if (temp2) flags|=C_FLAG; 1.2384 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.2385 - cycles -= (mod == 3) ? 5 : 8; 1.2386 - break; 1.2387 - case 0x18: /*RCR w,CL*/ 1.2388 - temp2=flags&C_FLAG; 1.2389 - while (c>0) 1.2390 - { 1.2391 - tempc=(temp2)?0x8000:0; 1.2392 - temp2=tempw&1; 1.2393 - tempw=(tempw>>1)|tempc; 1.2394 - c--; 1.2395 - if (is486) cycles--; 1.2396 - } 1.2397 - seteaw(tempw); if (abrt) break; 1.2398 - flags&=~(C_FLAG|V_FLAG); 1.2399 - if (temp2) flags|=C_FLAG; 1.2400 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.2401 - cycles -= (mod == 3) ? 5 : 8; 1.2402 - break; 1.2403 - 1.2404 - case 0x20: case 0x30: /*SHL w,CL*/ 1.2405 - seteaw(tempw<<c); if (abrt) break; 1.2406 - setznp16(tempw<<c); 1.2407 - if ((tempw<<(c-1))&0x8000) flags|=C_FLAG; 1.2408 - if (((tempw<<c)^(tempw<<(c-1)))&0x8000) flags|=V_FLAG; 1.2409 - cycles -= (mod == 3) ? 5 : 8; 1.2410 - break; 1.2411 - 1.2412 - case 0x28: /*SHR w,CL*/ 1.2413 - seteaw(tempw>>c); if (abrt) break; 1.2414 - setznp16(tempw>>c); 1.2415 - if ((tempw>>(c-1))&1) flags|=C_FLAG; 1.2416 - if (c==1 && tempw&0x8000) flags|=V_FLAG; 1.2417 - cycles -= (mod == 3) ? 5 : 8; 1.2418 - break; 1.2419 - 1.2420 - case 0x38: /*SAR w,CL*/ 1.2421 - tempw2=tempw&0x8000; 1.2422 - tempc=(tempw>>(c-1))&1; 1.2423 - while (c>0) 1.2424 - { 1.2425 - tempw=(tempw>>1)|tempw2; 1.2426 - c--; 1.2427 - } 1.2428 - seteaw(tempw); if (abrt) break; 1.2429 - setznp16(tempw); 1.2430 - if (tempc) flags|=C_FLAG; 1.2431 - cycles -= (mod == 3) ? 5 : 8; 1.2432 - break; 1.2433 - 1.2434 -// default: 1.2435 -// pclog("Bad C1 opcode %02X\n",rmdat&0x38); 1.2436 -// dumpregs(); 1.2437 -// exit(-1); 1.2438 - } 1.2439 - break; 1.2440 - 1.2441 - case 0xC2: /*RET*/ 1.2442 - tempw=getword(); 1.2443 - if (ssegs) ss=oldss; 1.2444 - tempw2=readmemw(ss,SP); if (abrt) break; 1.2445 - SP+=2+tempw; 1.2446 - pc=tempw2; 1.2447 - cycles -= 11; 1.2448 - break; 1.2449 - case 0xC3: /*RET*/ 1.2450 - if (ssegs) ss=oldss; 1.2451 - tempw=readmemw(ss,SP); if (abrt) break; 1.2452 - SP+=2; 1.2453 - pc=tempw; 1.2454 - cycles -= 11; 1.2455 - break; 1.2456 - case 0xC4: /*LES*/ 1.2457 - fetchea(); 1.2458 - tempw2=readmemw(easeg,eaaddr); 1.2459 - tempw=readmemw(easeg,eaaddr+2); if (abrt) break; 1.2460 - loadseg(tempw,&_es); if (abrt) break; 1.2461 - regs[reg].w=tempw2; 1.2462 - cycles -= 7; 1.2463 - break; 1.2464 - case 0xC5: /*LDS*/ 1.2465 - fetchea(); 1.2466 - tempw2=readmemw(easeg,eaaddr); 1.2467 - tempw=readmemw(easeg,eaaddr+2); if (abrt) break; 1.2468 - loadseg(tempw,&_ds); if (abrt) break; 1.2469 - if (ssegs) oldds=ds; 1.2470 - regs[reg].w=tempw2; 1.2471 - cycles -= 7; 1.2472 - break; 1.2473 - case 0xC6: /*MOV b,#8*/ 1.2474 - fetchea(); 1.2475 - temp=readmemb(cs,pc); pc++; if (abrt) break; 1.2476 - seteab(temp); 1.2477 - cycles -= (mod == 3) ? 2 : 3; 1.2478 - break; 1.2479 - case 0xC7: /*MOV w,#16*/ 1.2480 - fetchea(); 1.2481 - tempw=getword(); if (abrt) break; 1.2482 - seteaw(tempw); 1.2483 - cycles -= (mod == 3) ? 2 : 3; 1.2484 - break; 1.2485 - case 0xC8: /*ENTER*/ 1.2486 - tempw2=getword(); 1.2487 - tempi=readmemb(cs,pc); pc++; 1.2488 - templ=BP; 1.2489 - writememw(ss,((SP-2)&0xFFFF),BP); if (abrt) break; 1.2490 - SP-=2; 1.2491 - templ2=SP; 1.2492 - if (tempi>0) 1.2493 - { 1.2494 - while (--tempi) 1.2495 - { 1.2496 - BP-=2; 1.2497 - tempw=readmemw(ss,BP); 1.2498 - if (abrt) { SP=templ2; BP=templ; break; } 1.2499 - writememw(ss,((SP-2)&0xFFFF),tempw); SP-=2; 1.2500 - if (abrt) { SP=templ2; BP=templ; break; } 1.2501 - cycles-=(is486)?3:4; 1.2502 - } 1.2503 - writememw(ss,((SP-2)&0xFFFF),templ2); SP-=2; 1.2504 - if (abrt) { SP=templ2; BP=templ; break; } 1.2505 - cycles -= 4; 1.2506 - } 1.2507 - BP = templ2; 1.2508 - SP-=tempw2; 1.2509 - cycles -= 12; 1.2510 - break; 1.2511 - case 0xC9: /*LEAVE*/ 1.2512 - templ=SP; 1.2513 - SP=BP; 1.2514 - tempw=readmemw(ss,SP); SP+=2; 1.2515 - if (abrt) { SP=templ; break; } 1.2516 - BP=tempw; 1.2517 - cycles -= 5; 1.2518 - break; 1.2519 - case 0xCA: /*RETF*/ 1.2520 - tempw=getword(); 1.2521 - if (msw&1) 1.2522 - { 1.2523 - pmoderetf(0,tempw); 1.2524 - break; 1.2525 - } 1.2526 - tempw2=CPL; 1.2527 - if (ssegs) ss=oldss; 1.2528 - oxpc=pc; 1.2529 - pc=readmemw(ss,SP); 1.2530 - loadcs(readmemw(ss,SP+2)); 1.2531 - if (abrt) break; 1.2532 - SP+=4+tempw; 1.2533 - cycles -= 15; 1.2534 - break; 1.2535 - case 0xCB: /*RETF*/ 1.2536 - if (msw&1) 1.2537 - { 1.2538 - pmoderetf(0,0); 1.2539 - break; 1.2540 - } 1.2541 - tempw2=CPL; 1.2542 - if (ssegs) ss=oldss; 1.2543 - oxpc=pc; 1.2544 - pc=readmemw(ss,SP); 1.2545 - loadcs(readmemw(ss,SP+2)); 1.2546 - if (abrt) break; 1.2547 - SP+=4; 1.2548 - cycles -= 15; 1.2549 - break; 1.2550 - case 0xCC: /*INT 3*/ 1.2551 - if (msw&1) 1.2552 - { 1.2553 - pmodeint(3,1); 1.2554 - cycles -= 40; 1.2555 - } 1.2556 - else 1.2557 - { 1.2558 - if (ssegs) ss=oldss; 1.2559 - writememw(ss,((SP-2)&0xFFFF),flags); 1.2560 - writememw(ss,((SP-4)&0xFFFF),CS); 1.2561 - writememw(ss,((SP-6)&0xFFFF),pc); 1.2562 - SP-=6; 1.2563 - addr=3<<2; 1.2564 -// flags&=~I_FLAG; 1.2565 - flags&=~T_FLAG; 1.2566 - oxpc=pc; 1.2567 - pc=readmemw(0,addr); 1.2568 - loadcs(readmemw(0,addr+2)); 1.2569 - cycles -= 23; 1.2570 - } 1.2571 - break; 1.2572 - case 0xCD: /*INT*/ 1.2573 - lastpc=pc; 1.2574 - lastcs=CS; 1.2575 - temp=readmemb(cs,pc); pc++; 1.2576 - intrt: 1.2577 - pclog("INT %02X %04X %04X %04X %04X %04X:%04X\n", temp, AX, BX, CX, DX, CS, pc); 1.2578 - if (1) 1.2579 - { 1.2580 - if (msw&1) 1.2581 - { 1.2582 -// pclog("PMODE int %02X %04X at %04X:%04X ",temp,AX,CS,pc); 1.2583 - pmodeint(temp,1); 1.2584 - cycles -= 40; 1.2585 -// pclog("to %04X:%04X\n",CS,pc); 1.2586 - } 1.2587 - else 1.2588 - { 1.2589 - if (ssegs) ss=oldss; 1.2590 - writememw(ss,((SP-2)&0xFFFF),flags); 1.2591 - writememw(ss,((SP-4)&0xFFFF),CS); 1.2592 - writememw(ss,((SP-6)&0xFFFF),pc); 1.2593 - SP-=6; 1.2594 - addr=temp<<2; 1.2595 -// flags&=~I_FLAG; 1.2596 - flags&=~T_FLAG; 1.2597 - oxpc=pc; 1.2598 -// pclog("%04X:%04X : ",CS,pc); 1.2599 - pc=readmemw(0,addr); 1.2600 - loadcs(readmemw(0,addr+2)); 1.2601 - cycles -= 23; 1.2602 -// pclog("INT %02X - %04X %04X:%04X\n",temp,addr,CS,pc); 1.2603 - } 1.2604 - } 1.2605 - break; 1.2606 - case 0xCE: /*INTO*/ 1.2607 - if (flags&V_FLAG) 1.2608 - { 1.2609 - temp=4; 1.2610 - goto intrt; 1.2611 -/* pclog("INTO interrupt!\n"); 1.2612 - dumpregs(); 1.2613 - exit(-1);*/ 1.2614 - } 1.2615 - cycles-=3; 1.2616 - break; 1.2617 - case 0xCF: /*IRET*/ 1.2618 - if (ssegs) ss=oldss; 1.2619 - if (msw&1) 1.2620 - { 1.2621 - optype=IRET; 1.2622 - pmodeiret(0); 1.2623 - optype=0; 1.2624 - } 1.2625 - else 1.2626 - { 1.2627 - tempw=CS; 1.2628 - tempw2=pc; 1.2629 - inint=0; 1.2630 - oxpc=pc; 1.2631 - pc=readmemw(ss,SP); 1.2632 - loadcs(readmemw(ss,((SP+2)&0xFFFF))); 1.2633 - flags=(readmemw(ss,((SP+4)&0xFFFF))&0x0FD5)|2; 1.2634 - SP+=6; 1.2635 - } 1.2636 - cycles -= 17; 1.2637 - break; 1.2638 - 1.2639 - case 0xD0: 1.2640 - fetchea(); 1.2641 - temp=geteab(); if (abrt) break; 1.2642 - switch (rmdat&0x38) 1.2643 - { 1.2644 - case 0x00: /*ROL b,1*/ 1.2645 - seteab((temp<<1)|((temp&0x80)?1:0)); if (abrt) break; 1.2646 - if (temp&0x80) flags|=C_FLAG; 1.2647 - else flags&=~C_FLAG; 1.2648 - temp<<=1; 1.2649 - if (flags&C_FLAG) temp|=1; 1.2650 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.2651 - else flags&=~V_FLAG; 1.2652 - cycles -= (mod == 3) ? 2 : 7; 1.2653 - break; 1.2654 - case 0x08: /*ROR b,1*/ 1.2655 - seteab((temp>>1)|((temp&1)?0x80:0)); if (abrt) break; 1.2656 - if (temp&1) flags|=C_FLAG; 1.2657 - else flags&=~C_FLAG; 1.2658 - temp>>=1; 1.2659 - if (flags&C_FLAG) temp|=0x80; 1.2660 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.2661 - else flags&=~V_FLAG; 1.2662 - cycles -= (mod == 3) ? 2 : 7; 1.2663 - break; 1.2664 - case 0x10: /*RCL b,1*/ 1.2665 - temp2=flags&C_FLAG; 1.2666 - seteab((temp<<1)|temp2); if (abrt) break; 1.2667 - if (temp&0x80) flags|=C_FLAG; 1.2668 - else flags&=~C_FLAG; 1.2669 - temp<<=1; 1.2670 - if (temp2) temp|=1; 1.2671 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.2672 - else flags&=~V_FLAG; 1.2673 - cycles -= (mod == 3) ? 2 : 7; 1.2674 - break; 1.2675 - case 0x18: /*RCR b,1*/ 1.2676 - temp2=flags&C_FLAG; 1.2677 - seteab((temp>>1)|(temp2?0x80:0)); if (abrt) break; 1.2678 - if (temp&1) flags|=C_FLAG; 1.2679 - else flags&=~C_FLAG; 1.2680 - temp>>=1; 1.2681 - if (temp2) temp|=0x80; 1.2682 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.2683 - else flags&=~V_FLAG; 1.2684 - cycles -= (mod == 3) ? 2 : 7; 1.2685 - break; 1.2686 - case 0x20: case 0x30: /*SHL b,1*/ 1.2687 - seteab(temp<<1); if (abrt) break; 1.2688 - setznp8(temp<<1); 1.2689 - if (temp&0x80) flags|=C_FLAG; 1.2690 - if ((temp^(temp<<1))&0x80) flags|=V_FLAG; 1.2691 - cycles -= (mod == 3) ? 2 : 7; 1.2692 - break; 1.2693 - case 0x28: /*SHR b,1*/ 1.2694 - seteab(temp>>1); if (abrt) break; 1.2695 - setznp8(temp>>1); 1.2696 - if (temp&1) flags|=C_FLAG; 1.2697 - if (temp&0x80) flags|=V_FLAG; 1.2698 - cycles -= (mod == 3) ? 2 : 7; 1.2699 - break; 1.2700 - case 0x38: /*SAR b,1*/ 1.2701 - seteab((temp>>1)|(temp&0x80)); if (abrt) break; 1.2702 - setznp8((temp>>1)|(temp&0x80)); 1.2703 - if (temp&1) flags|=C_FLAG; 1.2704 - cycles -= (mod == 3) ? 2 : 7; 1.2705 - break; 1.2706 - 1.2707 -// default: 1.2708 -// pclog("Bad D0 opcode %02X\n",rmdat&0x38); 1.2709 -// dumpregs(); 1.2710 -// exit(-1); 1.2711 - } 1.2712 - break; 1.2713 - case 0xD1: 1.2714 - fetchea(); 1.2715 - tempw=geteaw(); if (abrt) break; 1.2716 - switch (rmdat&0x38) 1.2717 - { 1.2718 - case 0x00: /*ROL w,1*/ 1.2719 - seteaw((tempw<<1)|(tempw>>15)); if (abrt) break; 1.2720 - if (tempw&0x8000) flags|=C_FLAG; 1.2721 - else flags&=~C_FLAG; 1.2722 - tempw<<=1; 1.2723 - if (flags&C_FLAG) tempw|=1; 1.2724 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.2725 - else flags&=~V_FLAG; 1.2726 - cycles -= (mod == 3) ? 2 : 7; 1.2727 - break; 1.2728 - case 0x08: /*ROR w,1*/ 1.2729 - seteaw((tempw>>1)|(tempw<<15)); if (abrt) break; 1.2730 - if (tempw&1) flags|=C_FLAG; 1.2731 - else flags&=~C_FLAG; 1.2732 - tempw>>=1; 1.2733 - if (flags&C_FLAG) tempw|=0x8000; 1.2734 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.2735 - else flags&=~V_FLAG; 1.2736 - cycles -= (mod == 3) ? 2 : 7; 1.2737 - break; 1.2738 - case 0x10: /*RCL w,1*/ 1.2739 - temp2=flags&C_FLAG; 1.2740 - seteaw((tempw<<1)|temp2); if (abrt) break; 1.2741 - if (tempw&0x8000) flags|=C_FLAG; 1.2742 - else flags&=~C_FLAG; 1.2743 - tempw<<=1; 1.2744 - if (temp2) tempw|=1; 1.2745 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.2746 - else flags&=~V_FLAG; 1.2747 - cycles -= (mod == 3) ? 2 : 7; 1.2748 - break; 1.2749 - case 0x18: /*RCR w,1*/ 1.2750 - temp2=flags&C_FLAG; 1.2751 - seteaw((tempw>>1)|(temp2?0x8000:0)); if (abrt) break; 1.2752 - if (tempw&1) flags|=C_FLAG; 1.2753 - else flags&=~C_FLAG; 1.2754 - tempw>>=1; 1.2755 - if (temp2) tempw|=0x8000; 1.2756 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.2757 - else flags&=~V_FLAG; 1.2758 - cycles -= (mod == 3) ? 2 : 7; 1.2759 - break; 1.2760 - case 0x20: case 0x30: /*SHL w,1*/ 1.2761 - seteaw(tempw<<1); if (abrt) break; 1.2762 - setznp16(tempw<<1); 1.2763 - if (tempw&0x8000) flags|=C_FLAG; 1.2764 - if ((tempw^(tempw<<1))&0x8000) flags|=V_FLAG; 1.2765 - cycles -= (mod == 3) ? 2 : 7; 1.2766 - break; 1.2767 - case 0x28: /*SHR w,1*/ 1.2768 - seteaw(tempw>>1); if (abrt) break; 1.2769 - setznp16(tempw>>1); 1.2770 - if (tempw&1) flags|=C_FLAG; 1.2771 - if (tempw&0x8000) flags|=V_FLAG; 1.2772 - cycles -= (mod == 3) ? 2 : 7; 1.2773 - break; 1.2774 - case 0x38: /*SAR w,1*/ 1.2775 - seteaw((tempw>>1)|(tempw&0x8000)); if (abrt) break; 1.2776 - setznp16((tempw>>1)|(tempw&0x8000)); 1.2777 - if (tempw&1) flags|=C_FLAG; 1.2778 - cycles -= (mod == 3) ? 2 : 7; 1.2779 - break; 1.2780 - 1.2781 - default: 1.2782 - pclog("Bad D1 opcode %02X\n",rmdat&0x38); 1.2783 - } 1.2784 - break; 1.2785 - 1.2786 - case 0xD2: 1.2787 - fetchea(); 1.2788 - temp=geteab(); if (abrt) break; 1.2789 - c=CL&31; 1.2790 -// cycles-=c; 1.2791 - if (!c) break; 1.2792 -// if (c>7) pclog("Shiftb %i %02X\n",rmdat&0x38,c); 1.2793 - cycles -= c; 1.2794 - switch (rmdat&0x38) 1.2795 - { 1.2796 - case 0x00: /*ROL b,CL*/ 1.2797 - while (c>0) 1.2798 - { 1.2799 - temp2=(temp&0x80)?1:0; 1.2800 - temp=(temp<<1)|temp2; 1.2801 - c--; 1.2802 - } 1.2803 - seteab(temp); if (abrt) break; 1.2804 - flags&=~(C_FLAG|V_FLAG); 1.2805 - if (temp2) flags|=C_FLAG; 1.2806 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.2807 - cycles -= (mod == 3) ? 5 : 8; 1.2808 - break; 1.2809 - case 0x08: /*ROR b,CL*/ 1.2810 - while (c>0) 1.2811 - { 1.2812 - temp2=temp&1; 1.2813 - temp>>=1; 1.2814 - if (temp2) temp|=0x80; 1.2815 - c--; 1.2816 - } 1.2817 - seteab(temp); if (abrt) break; 1.2818 - flags&=~(C_FLAG|V_FLAG); 1.2819 - if (temp2) flags|=C_FLAG; 1.2820 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.2821 - cycles -= (mod == 3) ? 5 : 8; 1.2822 - break; 1.2823 - case 0x10: /*RCL b,CL*/ 1.2824 - tempc=flags&C_FLAG; 1.2825 - while (c>0) 1.2826 - { 1.2827 - templ=tempc; 1.2828 - tempc=temp&0x80; 1.2829 - temp<<=1; 1.2830 - if (templ) temp|=1; 1.2831 - c--; 1.2832 - } 1.2833 - seteab(temp); if (abrt) break; 1.2834 - flags&=~(C_FLAG|V_FLAG); 1.2835 - if (tempc) flags|=C_FLAG; 1.2836 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.2837 - cycles -= (mod == 3) ? 5 : 8; 1.2838 - break; 1.2839 - case 0x18: /*RCR b,CL*/ 1.2840 - tempc=flags&C_FLAG; 1.2841 - while (c>0) 1.2842 - { 1.2843 - templ=tempc; 1.2844 - tempc=temp&1; 1.2845 - temp>>=1; 1.2846 - if (templ) temp|=0x80; 1.2847 - c--; 1.2848 - } 1.2849 - seteab(temp); if (abrt) break; 1.2850 - flags&=~(C_FLAG|V_FLAG); 1.2851 - if (tempc) flags|=C_FLAG; 1.2852 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.2853 - cycles -= (mod == 3) ? 5 : 8; 1.2854 - break; 1.2855 - case 0x20: case 0x30: /*SHL b,CL*/ 1.2856 - seteab(temp<<c); if (abrt) break; 1.2857 - setznp8(temp<<c); 1.2858 - if ((temp<<(c-1))&0x80) flags|=C_FLAG; 1.2859 - if (((temp<<c)^(temp<<(c-1)))&0x80) flags|=V_FLAG; 1.2860 - cycles -= (mod == 3) ? 5 : 8; 1.2861 - break; 1.2862 - case 0x28: /*SHR b,CL*/ 1.2863 - seteab(temp>>c); if (abrt) break; 1.2864 - setznp8(temp>>c); 1.2865 - if ((temp>>(c-1))&1) flags|=C_FLAG; 1.2866 - if (c==1 && temp&0x80) flags|=V_FLAG; 1.2867 - cycles -= (mod == 3) ? 5 : 8; 1.2868 - break; 1.2869 - case 0x38: /*SAR b,CL*/ 1.2870 - tempc=(temp>>(c-1))&1; 1.2871 - while (c>0) 1.2872 - { 1.2873 - temp>>=1; 1.2874 - if (temp&0x40) temp|=0x80; 1.2875 - c--; 1.2876 - } 1.2877 - seteab(temp); if (abrt) break; 1.2878 - setznp8(temp); 1.2879 - if (tempc) flags|=C_FLAG; 1.2880 - cycles -= (mod == 3) ? 5 : 8; 1.2881 - break; 1.2882 - 1.2883 -// default: 1.2884 -// pclog("Bad D2 opcode %02X\n",rmdat&0x38); 1.2885 -// dumpregs(); 1.2886 -// exit(-1); 1.2887 - } 1.2888 - break; 1.2889 - 1.2890 - case 0xD3: 1.2891 - fetchea(); 1.2892 - tempw=geteaw(); if (abrt) break; 1.2893 - c=CL&31; 1.2894 - if (!c) break; 1.2895 - cycles -= c; 1.2896 - switch (rmdat&0x38) 1.2897 - { 1.2898 - case 0x00: /*ROL w,CL*/ 1.2899 - while (c>0) 1.2900 - { 1.2901 - temp=(tempw&0x8000)?1:0; 1.2902 - tempw=(tempw<<1)|temp; 1.2903 - c--; 1.2904 - } 1.2905 - seteaw(tempw); if (abrt) break; 1.2906 - flags&=~(C_FLAG|V_FLAG); 1.2907 - if (temp) flags|=C_FLAG; 1.2908 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.2909 - cycles -= (mod == 3) ? 5 : 8; 1.2910 - break; 1.2911 - case 0x08: /*ROR w,CL*/ 1.2912 - while (c>0) 1.2913 - { 1.2914 - tempw2=(tempw&1)?0x8000:0; 1.2915 - tempw=(tempw>>1)|tempw2; 1.2916 - c--; 1.2917 - } 1.2918 - seteaw(tempw); if (abrt) break; 1.2919 - flags&=~(C_FLAG|V_FLAG); 1.2920 - if (tempw2) flags|=C_FLAG; 1.2921 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.2922 - cycles -= (mod == 3) ? 5 : 8; 1.2923 - break; 1.2924 - case 0x10: /*RCL w,CL*/ 1.2925 - tempc=flags&C_FLAG; 1.2926 - while (c>0) 1.2927 - { 1.2928 - templ=tempc; 1.2929 - tempc=tempw&0x8000; 1.2930 - tempw=(tempw<<1)|templ; 1.2931 - c--; 1.2932 - } 1.2933 - seteaw(tempw); if (abrt) break; 1.2934 - flags&=~(C_FLAG|V_FLAG); 1.2935 - if (tempc) flags|=C_FLAG; 1.2936 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.2937 - cycles -= (mod == 3) ? 5 : 8; 1.2938 - break; 1.2939 - case 0x18: /*RCR w,CL*/ 1.2940 - tempc=flags&C_FLAG; 1.2941 - while (c>0) 1.2942 - { 1.2943 - templ=tempc; 1.2944 - tempw2=(templ&1)?0x8000:0; 1.2945 - tempc=tempw&1; 1.2946 - tempw=(tempw>>1)|tempw2; 1.2947 - c--; 1.2948 - } 1.2949 - seteaw(tempw); if (abrt) break; 1.2950 - flags&=~(C_FLAG|V_FLAG); 1.2951 - if (tempc) flags|=C_FLAG; 1.2952 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.2953 - cycles -= (mod == 3) ? 5 : 8; 1.2954 - break; 1.2955 - 1.2956 - case 0x20: case 0x30: /*SHL w,CL*/ 1.2957 - seteaw(tempw<<c); if (abrt) break; 1.2958 - setznp16(tempw<<c); 1.2959 - if ((tempw<<(c-1))&0x8000) flags|=C_FLAG; 1.2960 - if (((tempw<<c)^(tempw<<(c-1)))&0x8000) flags|=V_FLAG; 1.2961 - cycles -= (mod == 3) ? 5 : 8; 1.2962 - break; 1.2963 - 1.2964 - case 0x28: /*SHR w,CL*/ 1.2965 - seteaw(tempw>>c); if (abrt) break; 1.2966 - setznp16(tempw>>c); 1.2967 - if ((tempw>>(c-1))&1) flags|=C_FLAG; 1.2968 - if (c==1 && tempw&0x8000) flags|=V_FLAG; 1.2969 - cycles -= (mod == 3) ? 5 : 8; 1.2970 - break; 1.2971 - 1.2972 - case 0x38: /*SAR w,CL*/ 1.2973 - tempw2=tempw&0x8000; 1.2974 - tempc=((int16_t)tempw>>(c-1))&1; 1.2975 - while (c>0) 1.2976 - { 1.2977 - tempw=(tempw>>1)|tempw2; 1.2978 - c--; 1.2979 - } 1.2980 - seteaw(tempw); if (abrt) break; 1.2981 - setznp16(tempw); 1.2982 - if (tempc) flags|=C_FLAG; 1.2983 - cycles -= (mod == 3) ? 5 : 8; 1.2984 - break; 1.2985 - 1.2986 -// default: 1.2987 -// pclog("Bad D3 opcode %02X\n",rmdat&0x38); 1.2988 -// dumpregs(); 1.2989 -// exit(-1); 1.2990 - } 1.2991 - break; 1.2992 - 1.2993 - case 0xD4: /*AAM*/ 1.2994 - tempws=readmemb(cs,pc); pc++; 1.2995 - AH=AL/tempws; 1.2996 - AL%=tempws; 1.2997 - setznp16(AX); 1.2998 - cycles -= 16; 1.2999 - break; 1.3000 - case 0xD5: /*AAD*/ 1.3001 - tempws=readmemb(cs,pc); pc++; 1.3002 - AL=(AH*tempws)+AL; 1.3003 - AH=0; 1.3004 - setznp16(AX); 1.3005 - cycles -= 14; 1.3006 - break; 1.3007 - case 0xD6: /*SETALC*/ 1.3008 - AL=(flags&C_FLAG)?0xFF:0; 1.3009 - cycles -= 3; 1.3010 - break; 1.3011 - case 0xD7: /*XLAT*/ 1.3012 - addr=(BX+AL)&0xFFFF; 1.3013 - temp=readmemb(ds,addr); if (abrt) break; 1.3014 - AL=temp; 1.3015 - cycles -= 5; 1.3016 - break; 1.3017 - case 0xD9: case 0xDA: case 0xDB: case 0xDD: /*ESCAPE*/ 1.3018 - case 0xD8: 1.3019 - case 0xDC: 1.3020 - case 0xDE: 1.3021 - case 0xDF: 1.3022 - if ((msw & 6) == 4) 1.3023 - { 1.3024 - pc=oldpc; 1.3025 - pmodeint(7,0); 1.3026 - cycles -= 40; 1.3027 - } 1.3028 - else 1.3029 - { 1.3030 - fetchea(); 1.3031 - } 1.3032 - break; 1.3033 - 1.3034 - case 0xE0: /*LOOPNE*/ 1.3035 - offset=(int8_t)readmemb(cs,pc); pc++; 1.3036 - CX--; 1.3037 - if (CX && !(flags&Z_FLAG)) { pc+=offset; cycles -= 4; cycles -= 2; } 1.3038 - cycles -= 4; 1.3039 - break; 1.3040 - case 0xE1: /*LOOPE*/ 1.3041 - offset=(int8_t)readmemb(cs,pc); pc++; 1.3042 - CX--; 1.3043 - if (CX && (flags&Z_FLAG)) { pc+=offset; cycles -= 4; cycles -= 2; } 1.3044 - cycles -= 4; 1.3045 - break; 1.3046 - case 0xE2: /*LOOP*/ 1.3047 - offset=(int8_t)readmemb(cs,pc); pc++; 1.3048 - CX--; 1.3049 - if (CX) { pc+=offset; cycles -= 4; cycles -= 2; } 1.3050 - cycles -= 4; 1.3051 - break; 1.3052 - case 0xE3: /*JCXZ*/ 1.3053 - offset=(int8_t)readmemb(cs,pc); pc++; 1.3054 - if (!CX) { pc+=offset; cycles -= 4; cycles -= 2; } 1.3055 - cycles-=4; 1.3056 - break; 1.3057 - 1.3058 - case 0xE4: /*IN AL*/ 1.3059 - temp=readmemb(cs,pc); 1.3060 - checkio_perm(temp); 1.3061 - pc++; 1.3062 - AL=inb(temp); 1.3063 - cycles -= 5; 1.3064 - break; 1.3065 - case 0xE5: /*IN AX*/ 1.3066 - temp=readmemb(cs,pc); 1.3067 - checkio_perm(temp); 1.3068 - checkio_perm(temp+1); 1.3069 - pc++; 1.3070 - AX=inw(temp); 1.3071 - cycles -= 5; 1.3072 - break; 1.3073 - case 0xE6: /*OUT AL*/ 1.3074 - temp=readmemb(cs,pc); 1.3075 - checkio_perm(temp); 1.3076 - pc++; 1.3077 - outb(temp,AL); 1.3078 - cycles -= 3; 1.3079 - break; 1.3080 - case 0xE7: /*OUT AX*/ 1.3081 - temp=readmemb(cs,pc); 1.3082 - checkio_perm(temp); 1.3083 - checkio_perm(temp+1); 1.3084 - pc++; 1.3085 - outw(temp,AX); 1.3086 - cycles -= 3; 1.3087 - break; 1.3088 - 1.3089 - case 0xE8: /*CALL rel 16*/ 1.3090 - tempw=getword(); if (abrt) break; 1.3091 - if (ssegs) ss=oldss; 1.3092 - writememw(ss,((SP-2)&0xFFFF),pc); if (abrt) break; 1.3093 - SP-=2; 1.3094 - pc+=(int16_t)tempw; 1.3095 - cycles -= 7; 1.3096 - break; 1.3097 - case 0xE9: /*JMP rel 16*/ 1.3098 - tempw=getword(); if (abrt) break; 1.3099 - pc+=(int16_t)tempw; 1.3100 - cycles -= 7; 1.3101 - break; 1.3102 - case 0xEA: /*JMP far*/ 1.3103 - addr=getword(); 1.3104 - tempw=getword(); if (abrt) { if (output==3) pclog("JMP ABRT\n"); break; } 1.3105 - oxpc=pc; 1.3106 - pc=addr; 1.3107 - loadcsjmp(tempw,oxpc); 1.3108 - cycles -= 11; 1.3109 - break; 1.3110 - case 0xEB: /*JMP rel*/ 1.3111 - offset=(int8_t)readmemb(cs,pc); pc++; 1.3112 - pc+=offset; 1.3113 - cycles -= 7; 1.3114 - break; 1.3115 - case 0xEC: /*IN AL,DX*/ 1.3116 - checkio_perm(DX); 1.3117 - AL=inb(DX); 1.3118 - cycles -= 5; 1.3119 - break; 1.3120 - case 0xED: /*IN AX,DX*/ 1.3121 - checkio_perm(DX); 1.3122 - checkio_perm(DX+1); 1.3123 - AX=inw(DX); 1.3124 - cycles -= 5; 1.3125 - break; 1.3126 - case 0xEE: /*OUT DX,AL*/ 1.3127 - checkio_perm(DX); 1.3128 - outb(DX,AL); 1.3129 - cycles -= 4; 1.3130 - break; 1.3131 - case 0xEF: /*OUT DX,AX*/ 1.3132 - checkio_perm(DX); 1.3133 - checkio_perm(DX+1); 1.3134 - outw(DX,AX); 1.3135 - cycles -= 4; 1.3136 - break; 1.3137 - 1.3138 - case 0xF0: /*LOCK*/ 1.3139 - break; 1.3140 - 1.3141 - case 0xF2: /*REPNE*/ 1.3142 - rep386(0); 1.3143 - break; 1.3144 - case 0xF3: /*REPE*/ 1.3145 - rep386(1); 1.3146 - break; 1.3147 - 1.3148 - case 0xF4: /*HLT*/ 1.3149 - inhlt=1; 1.3150 - pc--; 1.3151 - cycles -= 2; 1.3152 -/* if (!(flags & I_FLAG)) 1.3153 - { 1.3154 - pclog("Complete HLT\n"); 1.3155 - dumpregs(); 1.3156 - exit(-1); 1.3157 - }*/ 1.3158 - break; 1.3159 - case 0xF5: /*CMC*/ 1.3160 - flags^=C_FLAG; 1.3161 - cycles -= 2; 1.3162 - break; 1.3163 - 1.3164 - case 0xF6: 1.3165 - fetchea(); 1.3166 - temp=geteab(); if (abrt) break; 1.3167 - switch (rmdat&0x38) 1.3168 - { 1.3169 - case 0x00: /*TEST b,#8*/ 1.3170 - temp2=readmemb(cs,pc); pc++; if (abrt) break; 1.3171 -// pclog("TEST %02X,%02X\n",temp,temp2); 1.3172 -/* if (cs==0x700 && !temp && temp2==0x10) 1.3173 - { 1.3174 - dumpregs(); 1.3175 - exit(-1); 1.3176 - }*/ 1.3177 - temp&=temp2; 1.3178 - setznp8(temp); 1.3179 - cycles -= (mod == 3) ? 3 : 6; 1.3180 - break; 1.3181 - case 0x10: /*NOT b*/ 1.3182 - temp=~temp; 1.3183 - seteab(temp); 1.3184 - cycles -= (mod == 3) ? 2 : 7; 1.3185 - break; 1.3186 - case 0x18: /*NEG b*/ 1.3187 - setsub8(0,temp); 1.3188 - temp=0-temp; 1.3189 - seteab(temp); 1.3190 - cycles -= (mod == 3) ? 2 : 7; 1.3191 - break; 1.3192 - case 0x20: /*MUL AL,b*/ 1.3193 -// setznp8(AL); 1.3194 - AX=AL*temp; 1.3195 -// if (AX) flags&=~Z_FLAG; 1.3196 -// else flags|=Z_FLAG; 1.3197 - if (AH) flags|=(C_FLAG|V_FLAG); 1.3198 - else flags&=~(C_FLAG|V_FLAG); 1.3199 - cycles -= (mod == 3) ? 13 : 16; 1.3200 - break; 1.3201 - case 0x28: /*IMUL AL,b*/ 1.3202 -// setznp8(AL); 1.3203 - tempws=(int)((int8_t)AL)*(int)((int8_t)temp); 1.3204 - AX=tempws&0xFFFF; 1.3205 -// if (AX) flags&=~Z_FLAG; 1.3206 -// else flags|=Z_FLAG; 1.3207 - if (AH && AH!=0xFF) flags|=(C_FLAG|V_FLAG); 1.3208 - else flags&=~(C_FLAG|V_FLAG); 1.3209 - cycles -= (mod == 3) ? 13 : 16; 1.3210 - break; 1.3211 - case 0x30: /*DIV AL,b*/ 1.3212 - tempw=AX; 1.3213 - if (temp) tempw2=tempw/temp; 1.3214 -// pclog("DIV %04X/%02X %04X:%04X\n",tempw,temp,CS,pc); 1.3215 - if (temp && !(tempw2&0xFF00)) 1.3216 - { 1.3217 - tempw2=tempw%temp; 1.3218 - AH=tempw2; 1.3219 - tempw/=temp; 1.3220 - AL=tempw&0xFF; 1.3221 - flags|=0x8D5; /*Not a Cyrix*/ 1.3222 - } 1.3223 - else 1.3224 - { 1.3225 - pclog("DIVb BY 0 %04X:%04X\n",cs>>4,pc); 1.3226 - pc=oldpc; 1.3227 - if (msw&1) pmodeint(0,0); 1.3228 - else 1.3229 - { 1.3230 -// pclog("%04X:%04X\n",cs>>4,pc); 1.3231 - writememw(ss,(SP-2)&0xFFFF,flags); 1.3232 - writememw(ss,(SP-4)&0xFFFF,CS); 1.3233 - writememw(ss,(SP-6)&0xFFFF,pc); 1.3234 - SP-=6; 1.3235 - flags&=~I_FLAG; 1.3236 - oxpc=pc; 1.3237 - pc=readmemw(0,0); 1.3238 - loadcs(readmemw(0,2)); 1.3239 - } 1.3240 -// cs=loadcs(CS); 1.3241 -// cs=CS<<4; 1.3242 -// pclog("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x30); 1.3243 -// dumpregs(); 1.3244 -// exit(-1); 1.3245 - } 1.3246 - cycles -= (mod == 3) ? 14 : 17; 1.3247 - break; 1.3248 - case 0x38: /*IDIV AL,b*/ 1.3249 -// pclog("IDIV %04X/%02X\n",tempw,temp); 1.3250 - tempws=(int)(int16_t)AX; 1.3251 - if (temp!=0) tempws2=tempws/(int)((int8_t)temp); 1.3252 - temps=tempws2&0xFF; 1.3253 - if ((temp!=0) && ((int)temps==tempws2)) 1.3254 - { 1.3255 - tempw2=tempws%(int)((int8_t)temp); 1.3256 - AH=tempw2&0xFF; 1.3257 - AL=tempws2&0xFF; 1.3258 - if (!cpu_iscyrix) flags|=0x8D5; /*Not a Cyrix*/ 1.3259 - } 1.3260 - else 1.3261 - { 1.3262 - pclog("IDIVb exception - %X / %08X = %X\n",tempws,temp,tempws2); 1.3263 -// pclog("IDIVb BY 0 %04X:%04X\n",cs>>4,pc); 1.3264 - pc=oldpc; 1.3265 - if (msw&1) pmodeint(0,0); 1.3266 - else 1.3267 - { 1.3268 - writememw(ss,(SP-2)&0xFFFF,flags); 1.3269 - writememw(ss,(SP-4)&0xFFFF,CS); 1.3270 - writememw(ss,(SP-6)&0xFFFF,pc); 1.3271 - SP-=6; 1.3272 - flags&=~I_FLAG; 1.3273 - oxpc=pc; 1.3274 - pc=readmemw(0,0); 1.3275 - loadcs(readmemw(0,2)); 1.3276 - } 1.3277 -// cs=loadcs(CS); 1.3278 -// cs=CS<<4; 1.3279 -// pclog("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x38); 1.3280 - } 1.3281 - cycles -= (mod == 3) ? 17 : 20; 1.3282 - break; 1.3283 - 1.3284 - default: 1.3285 - pclog("Bad F6 opcode %02X\n",rmdat&0x38); 1.3286 - x86illegal(); 1.3287 -// dumpregs(); 1.3288 -// exit(-1); 1.3289 - } 1.3290 - break; 1.3291 - 1.3292 - case 0xF7: 1.3293 - fetchea(); 1.3294 - tempw=geteaw(); if (abrt) break; 1.3295 - switch (rmdat&0x38) 1.3296 - { 1.3297 - case 0x00: /*TEST w*/ 1.3298 - tempw2=getword(); if (abrt) break; 1.3299 -// if (output==3) pclog("TEST %04X %04X\n",tempw,tempw2); 1.3300 - setznp16(tempw&tempw2); 1.3301 - cycles -= (mod == 3) ? 3 : 6; 1.3302 - break; 1.3303 - case 0x10: /*NOT w*/ 1.3304 - seteaw(~tempw); 1.3305 - cycles -= (mod == 3) ? 2 : 7; 1.3306 - break; 1.3307 - case 0x18: /*NEG w*/ 1.3308 - setsub16(0,tempw); 1.3309 - tempw=0-tempw; 1.3310 - seteaw(tempw); 1.3311 - cycles -= (mod == 3) ? 2 : 7; 1.3312 - break; 1.3313 - case 0x20: /*MUL AX,w*/ 1.3314 -// setznp16(AX); 1.3315 - templ=AX*tempw; 1.3316 - AX=templ&0xFFFF; 1.3317 - DX=templ>>16; 1.3318 -// if (AX|DX) flags&=~Z_FLAG; 1.3319 -// else flags|=Z_FLAG; 1.3320 - if (DX) flags|=(C_FLAG|V_FLAG); 1.3321 - else flags&=~(C_FLAG|V_FLAG); 1.3322 - cycles -= (mod == 3) ? 21 : 24; 1.3323 - break; 1.3324 - case 0x28: /*IMUL AX,w*/ 1.3325 - templ=(int)((int16_t)AX)*(int)((int16_t)tempw); 1.3326 - AX=templ&0xFFFF; 1.3327 - DX=templ>>16; 1.3328 - if (DX && DX!=0xFFFF) flags|=(C_FLAG|V_FLAG); 1.3329 - else flags&=~(C_FLAG|V_FLAG); 1.3330 - cycles -= (mod == 3) ? 21 : 24; 1.3331 - break; 1.3332 - case 0x30: /*DIV AX,w*/ 1.3333 - templ=(DX<<16)|AX; 1.3334 - if (tempw) templ2=templ/tempw; 1.3335 - if (tempw && !(templ2&0xFFFF0000)) 1.3336 - { 1.3337 - tempw2=templ%tempw; 1.3338 - DX=tempw2; 1.3339 - templ/=tempw; 1.3340 - AX=templ&0xFFFF; 1.3341 - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ 1.3342 - } 1.3343 - else 1.3344 - { 1.3345 -// AX=DX=0; 1.3346 -// break; 1.3347 - pclog("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); 1.3348 -// dumpregs(); 1.3349 -// exit(-1); 1.3350 - pc=oldpc; 1.3351 - if (msw&1) pmodeint(0,0); 1.3352 - else 1.3353 - { 1.3354 -// pclog("%04X:%04X\n",cs>>4,pc); 1.3355 - writememw(ss,(SP-2)&0xFFFF,flags); 1.3356 - writememw(ss,(SP-4)&0xFFFF,CS); 1.3357 - writememw(ss,(SP-6)&0xFFFF,pc); 1.3358 - SP-=6; 1.3359 - flags&=~I_FLAG; 1.3360 - oxpc=pc; 1.3361 - pc=readmemw(0,0); 1.3362 - loadcs(readmemw(0,2)); 1.3363 - } 1.3364 -// cs=loadcs(CS); 1.3365 -// cs=CS<<4; 1.3366 -// pclog("Div by zero %04X:%04X %02X %02X 1\n",cs>>4,pc,0xf7,0x30); 1.3367 - } 1.3368 - cycles -= (mod == 3) ? 22 : 25; 1.3369 - break; 1.3370 - case 0x38: /*IDIV AX,w*/ 1.3371 - tempws=(int)((DX<<16)|AX); 1.3372 - if (tempw!=0) tempws2=tempws/(int)((int16_t)tempw); 1.3373 - temps16=tempws2&0xFFFF; 1.3374 -// pclog("IDIV %i %i ",tempws,tempw); 1.3375 - if ((tempw!=0) && ((int)temps16==tempws2)) 1.3376 - { 1.3377 - DX=tempws%(int)((int16_t)tempw); 1.3378 - AX=tempws2&0xFFFF; 1.3379 - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ 1.3380 - } 1.3381 - else 1.3382 - { 1.3383 - pclog("IDIVw exception - %X / %08X = %X\n",tempws,tempw,tempws2); 1.3384 -// pclog("IDIVw BY 0 %04X:%04X\n",cs>>4,pc); 1.3385 -// DX=0; 1.3386 -// AX=0xFFFF; 1.3387 - pc=oldpc; 1.3388 - if (msw&1) pmodeint(0,0); 1.3389 - else 1.3390 - { 1.3391 -// pclog("%04X:%04X\n",cs>>4,pc); 1.3392 - writememw(ss,(SP-2)&0xFFFF,flags); 1.3393 - writememw(ss,(SP-4)&0xFFFF,CS); 1.3394 - writememw(ss,(SP-6)&0xFFFF,pc); 1.3395 - SP-=6; 1.3396 - flags&=~I_FLAG; 1.3397 - oxpc=pc; 1.3398 - pc=readmemw(0,0); 1.3399 - loadcs(readmemw(0,2)); 1.3400 - } 1.3401 -// cs=loadcs(CS); 1.3402 -// cs=CS<<4; 1.3403 -// pclog("Div by zero %04X:%04X %02X %02X 1\n",cs>>4,pc,0xf7,0x38); 1.3404 - } 1.3405 - cycles -= (mod == 3) ? 25 : 28; 1.3406 - break; 1.3407 - 1.3408 - default: 1.3409 - pclog("Bad F7 opcode %02X\n",rmdat&0x38); 1.3410 - x86illegal(); 1.3411 -// dumpregs(); 1.3412 -// exit(-1); 1.3413 - } 1.3414 - break; 1.3415 - 1.3416 - case 0xF8: /*CLC*/ 1.3417 - flags&=~C_FLAG; 1.3418 - cycles -= 2; 1.3419 - break; 1.3420 - case 0xF9: /*STC*/ 1.3421 -// pclog("STC %04X\n",pc); 1.3422 - flags|=C_FLAG; 1.3423 - cycles -= 2; 1.3424 - break; 1.3425 - case 0xFA: /*CLI*/ 1.3426 - if (!IOPLp) 1.3427 - { 1.3428 - x86gpf(NULL,0); 1.3429 - } 1.3430 - else 1.3431 - flags&=~I_FLAG; 1.3432 - cycles -= 3; 1.3433 - break; 1.3434 - case 0xFB: /*STI*/ 1.3435 - if (!IOPLp) 1.3436 - { 1.3437 - x86gpf(NULL,0); 1.3438 - } 1.3439 - else 1.3440 - flags|=I_FLAG; 1.3441 - cycles -= 2; 1.3442 - break; 1.3443 - case 0xFC: /*CLD*/ 1.3444 - flags&=~D_FLAG; 1.3445 - cycles -= 2; 1.3446 - break; 1.3447 - case 0xFD: /*STD*/ 1.3448 - flags|=D_FLAG; 1.3449 - cycles -= 2; 1.3450 - break; 1.3451 - 1.3452 - case 0xFE: /*INC/DEC b*/ 1.3453 - fetchea(); 1.3454 - temp=geteab(); if (abrt) break; 1.3455 - if (rmdat&0x38) 1.3456 - { 1.3457 - seteab(temp-1); if (abrt) break; 1.3458 - flags&=~V_FLAG; 1.3459 - setsub8nc(temp,1); 1.3460 - temp2=temp-1; 1.3461 - if ((temp&0x80) && !(temp2&0x80)) flags|=V_FLAG; 1.3462 - } 1.3463 - else 1.3464 - { 1.3465 - seteab(temp+1); if (abrt) break; 1.3466 - flags&=~V_FLAG; 1.3467 - setadd8nc(temp,1); 1.3468 - temp2=temp+1; 1.3469 - if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG; 1.3470 - } 1.3471 - cycles -= (mod == 3) ? 2 : 7; 1.3472 - break; 1.3473 - 1.3474 - case 0xFF: 1.3475 - fetchea(); 1.3476 - switch (rmdat&0x38) 1.3477 - { 1.3478 - case 0x00: /*INC w*/ 1.3479 - tempw=geteaw(); if (abrt) break; 1.3480 - seteaw(tempw+1); if (abrt) break; 1.3481 - setadd16nc(tempw,1); 1.3482 - cycles -= (mod == 3) ? 2 : 7; 1.3483 - break; 1.3484 - case 0x08: /*DEC w*/ 1.3485 - tempw=geteaw(); if (abrt) break; 1.3486 - seteaw(tempw-1); if (abrt) break; 1.3487 - setsub16nc(tempw,1); 1.3488 - cycles -= (mod == 3) ? 2 : 7; 1.3489 - break; 1.3490 - case 0x10: /*CALL*/ 1.3491 - tempw=geteaw(); 1.3492 - if (abrt) break; 1.3493 - if (ssegs) ss=oldss; 1.3494 - writememw(ss,(SP-2)&0xFFFF,pc); if (abrt) break; 1.3495 - SP-=2; 1.3496 - pc=tempw; 1.3497 - cycles -= (mod == 3) ? 7 : 11; 1.3498 - break; 1.3499 - case 0x18: /*CALL far*/ 1.3500 - tempw=readmemw(easeg,eaaddr); 1.3501 - tempw2=readmemw(easeg,(eaaddr+2)); if (output==3) pclog("CALL FAR %04X:%04X\n",tempw,tempw2); if (abrt) break; 1.3502 - tempw3=CS; 1.3503 - templ2=pc; 1.3504 - if (ssegs) ss=oldss; 1.3505 - oxpc=pc; 1.3506 - pc=tempw; 1.3507 - optype=CALL; 1.3508 - if (msw&1) loadcscall(tempw2); 1.3509 - else loadcs(tempw2); 1.3510 - optype=0; 1.3511 - if (abrt) break; 1.3512 - oldss=ss; 1.3513 - writememw(ss,(SP-2)&0xFFFF,tempw3); 1.3514 - writememw(ss,((SP-4)&0xFFFF),templ2); 1.3515 - SP-=4; 1.3516 - cycles -= 16; 1.3517 - break; 1.3518 - case 0x20: /*JMP*/ 1.3519 - tempw=geteaw(); if (abrt) break; 1.3520 - pc=tempw; 1.3521 - cycles -= (mod == 3) ? 7 : 11; 1.3522 - break; 1.3523 - case 0x28: /*JMP far*/ 1.3524 - oxpc=pc; 1.3525 - tempw=readmemw(easeg,eaaddr); 1.3526 - tempw2=readmemw(easeg,eaaddr+2); if (abrt) break; 1.3527 - pc=tempw; 1.3528 - loadcsjmp(tempw2,oxpc); if (abrt) break; 1.3529 - cycles -= 15; 1.3530 - break; 1.3531 - case 0x30: /*PUSH w*/ 1.3532 - tempw=geteaw(); if (abrt) break; 1.3533 - if (ssegs) ss=oldss; 1.3534 - writememw(ss,((SP-2)&0xFFFF),tempw); if (abrt) break; 1.3535 - SP-=2; 1.3536 - cycles -= (mod==3) ? 3 : 5; 1.3537 - break; 1.3538 - 1.3539 - default: 1.3540 - pclog("Bad FF opcode %02X\n",rmdat&0x38); 1.3541 - x86illegal(); 1.3542 - //dumpregs(); 1.3543 - //exit(-1); 1.3544 - } 1.3545 - break; 1.3546 - 1.3547 - default: 1.3548 -// pc--; 1.3549 -// cycles-=8; 1.3550 -// break; 1.3551 - pclog("Bad opcode %02X at %04X:%04X from %04X:%04X %08X\n",opcode,cs>>4,pc,old8>>16,old8&0xFFFF,old82); 1.3552 - x86illegal(); 1.3553 -// dumpregs(); 1.3554 -// exit(-1); 1.3555 - } 1.3556 - opcodeend: 1.3557 - pc&=0xFFFF; 1.3558 - 1.3559 -// output = 3; 1.3560 -/* output = 3; 1.3561 - 1.3562 - if (pc == 0xcdd && CS == 0xf000) 1.3563 - { 1.3564 - dumpregs(); 1.3565 - exit(-1); 1.3566 - }*/ 1.3567 - //if (ins == 20768972) output = 3; 1.3568 - 1.3569 - if (ssegs) 1.3570 - { 1.3571 - ds=oldds; _ds.limit=olddslimit; _ds.limitw=olddslimitw; 1.3572 - ss=oldss; _ss.limit=oldsslimit; _ss.limitw=oldsslimitw; 1.3573 - ssegs=0; 1.3574 - } 1.3575 - if (abrt) 1.3576 - { 1.3577 - tempi = abrt; 1.3578 - abrt = 0; 1.3579 - x86_doabrt(tempi); 1.3580 - if (abrt) 1.3581 - { 1.3582 - abrt = 0; 1.3583 - CS = oldcs; 1.3584 - pc = oldpc; 1.3585 - pclog("Double fault\n"); 1.3586 -// dumpregs(); 1.3587 -// exit(-1); 1.3588 - pmodeint(8, 0); 1.3589 - if (abrt) 1.3590 - { 1.3591 - abrt = 0; 1.3592 - softresetx86(); 1.3593 - pclog("Triple fault - reset\n"); 1.3594 - } 1.3595 - } 1.3596 - } 1.3597 - cycdiff-=cycles; 1.3598 - 1.3599 - pit.c[0]-=cycdiff; 1.3600 - pit.c[1]-=cycdiff; 1.3601 - if (ppi.pb&1) pit.c[2]-=cycdiff; 1.3602 - 1.3603 - if ((pit.c[0]<1)||(pit.c[1]<1)||(pit.c[2]<1)) pit_poll(); 1.3604 - 1.3605 - spktime-=cycdiff; 1.3606 - if (spktime<=0.0) 1.3607 - { 1.3608 - spktime+=SPKCONST; 1.3609 -// pclog("1Poll spk\n"); 1.3610 - pollspk(); 1.3611 - pollgussamp(); 1.3612 - getsbsamp(); 1.3613 - polladlib(); 1.3614 - getdacsamp(); 1.3615 -// pclog("2Poll spk\n"); 1.3616 - } 1.3617 - soundtime-=cycdiff; 1.3618 - if (soundtime<=0.0) 1.3619 - { 1.3620 - soundtime+=SOUNDCONST; 1.3621 -// pclog("1Poll sound60hz\n"); 1.3622 - pollsound60hz(); 1.3623 -// pclog("2Poll sound60hz\n"); 1.3624 - } 1.3625 - gustime-=cycdiff; 1.3626 - while (gustime<=0.0) 1.3627 - { 1.3628 - gustime+=GUSCONST; 1.3629 - pollgus(); 1.3630 - } 1.3631 - gustime2-=cycdiff; 1.3632 - while (gustime2<=0.0) 1.3633 - { 1.3634 - gustime2+=GUSCONST2; 1.3635 - pollgus2(); 1.3636 - } 1.3637 - vidtime-=cycdiff; 1.3638 - if (vidtime<=0.0) 1.3639 - { 1.3640 -// pclog("1Poll video\n"); 1.3641 - pollvideo(); 1.3642 -// pclog("2Poll video\n"); 1.3643 - } 1.3644 - if (disctime) 1.3645 - { 1.3646 - disctime-=cycdiff/4; 1.3647 - if (disctime<=0) 1.3648 - { 1.3649 -// pclog("1Poll disc\n"); 1.3650 - disctime=0; 1.3651 - fdc_poll(); 1.3652 -// pclog("2Poll disc\n"); 1.3653 - } 1.3654 - } 1.3655 - if (mousedelay) 1.3656 - { 1.3657 - mousedelay-=20; 1.3658 - if (!mousedelay) 1.3659 - { 1.3660 -// pclog("1Poll mouse\n"); 1.3661 - mousecallback(); 1.3662 -// pclog("2Poll disc\n"); 1.3663 - } 1.3664 - } 1.3665 - if (sbenable) 1.3666 - { 1.3667 - sbcount-=cycdiff; 1.3668 - if (sbcount<0) 1.3669 - { 1.3670 - sbcount+=sblatcho; 1.3671 - pollsb(); 1.3672 - } 1.3673 - } 1.3674 - if (sb_enable_i) 1.3675 - { 1.3676 - sb_count_i-=cycdiff; 1.3677 - if (sb_count_i<0) 1.3678 - { 1.3679 - sb_count_i+=sblatchi; 1.3680 - sb_poll_i(); 1.3681 - } 1.3682 - } 1.3683 - rtctime-=cycdiff; 1.3684 - if (rtctime<0) 1.3685 - { 1.3686 - nvr_rtc(); 1.3687 - } 1.3688 - if (idecallback[0]) 1.3689 - { 1.3690 - idecallback[0]--; 1.3691 - if (idecallback[0]<=0) 1.3692 - { 1.3693 -// pclog("IDE time over\n"); 1.3694 - idecallback[0]=0; 1.3695 - callbackide(0); 1.3696 - } 1.3697 - } 1.3698 - if (idecallback[1]) 1.3699 - { 1.3700 - idecallback[1]--; 1.3701 - if (idecallback[1]<=0) 1.3702 - { 1.3703 -// pclog("IDE time over\n"); 1.3704 - idecallback[1]=0; 1.3705 - callbackide(1); 1.3706 - } 1.3707 - } 1.3708 - if (trap && (flags&T_FLAG) && !noint) 1.3709 - { 1.3710 - if (msw&1) 1.3711 - { 1.3712 - pmodeint(1,0); 1.3713 - cycles -= 40; 1.3714 - } 1.3715 - else 1.3716 - { 1.3717 - writememw(ss,(SP-2)&0xFFFF,flags); 1.3718 - writememw(ss,(SP-4)&0xFFFF,CS); 1.3719 - writememw(ss,(SP-6)&0xFFFF,pc); 1.3720 - SP-=6; 1.3721 - addr=1<<2; 1.3722 - flags&=~I_FLAG; 1.3723 - flags&=~T_FLAG; 1.3724 - pc=readmemw(0,addr); 1.3725 - loadcs(readmemw(0,addr+2)); 1.3726 - cycles -= 23; 1.3727 - } 1.3728 - } 1.3729 - else if ((flags&I_FLAG) && (((pic.pend&~pic.mask)&~pic.mask2) || ((pic2.pend&~pic2.mask)&~pic2.mask2)) && !ssegs && !noint) 1.3730 - { 1.3731 -// pclog("Test %02X %02X %02X\n", pic.pend, pic.mask, pic.mask2); 1.3732 - temp=picinterrupt(); 1.3733 - if (temp!=0xFF) 1.3734 - { 1.3735 -// pclog("286 int %02X %02X %02X %02X\n",temp, pic.pend, pic.mask, pic.mask2); 1.3736 - if (inhlt) pc++; 1.3737 -// intcount++; 1.3738 - if (msw&1) 1.3739 - { 1.3740 - pmodeint(temp,0); 1.3741 - cycles -= 40; 1.3742 - } 1.3743 - else 1.3744 - { 1.3745 - writememw(ss,(SP-2)&0xFFFF,flags); 1.3746 - writememw(ss,(SP-4)&0xFFFF,CS); 1.3747 - writememw(ss,(SP-6)&0xFFFF,pc); 1.3748 - SP-=6; 1.3749 - addr=temp<<2; 1.3750 - flags&=~I_FLAG; 1.3751 - flags&=~T_FLAG; 1.3752 - pc=readmemw(0,addr); 1.3753 - loadcs(readmemw(0,addr+2)); 1.3754 - cycles -= 23; 1.3755 - } 1.3756 - inint=1; 1.3757 - } 1.3758 - } 1.3759 - 1.3760 -/* if (pc==0xCC32 && es>0x180000) 1.3761 - { 1.3762 - pc=0xCBEB; 1.3763 -// output=1; 1.3764 -// timetolive=500000; 1.3765 - }*/ 1.3766 - 1.3767 - if (noint) noint=0; 1.3768 - ins++; 1.3769 - insc++; 1.3770 - 1.3771 -// if (ins == 25000000) output = 3; 1.3772 -/* if (timetolive) 1.3773 - { 1.3774 - timetolive--; 1.3775 - if (!timetolive) 1.3776 - { 1.3777 - dumpregs(); 1.3778 - exit(-1); 1.3779 - } //output=0; 1.3780 - }*/ 1.3781 - keybsenddelay--; 1.3782 - if (keybsenddelay<1) 1.3783 - { 1.3784 - keybsenddelay = 2500; 1.3785 - keyboard_poll(); 1.3786 - } 1.3787 - //output = 3; 1.3788 - } 1.3789 -} 1.3790 -//#endif
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/386.h Mon May 27 19:56:33 2013 +0100 2.3 @@ -0,0 +1,2 @@ 2.4 +extern void cpu_386_flags_extract(); 2.5 +extern void cpu_386_flags_rebuild();
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/386_ops.h Mon May 27 19:56:33 2013 +0100 3.3 @@ -0,0 +1,499 @@ 3.4 +#include "x86_ops.h" 3.5 + 3.6 +OpFn *x86_opcodes; 3.7 +OpFn *x86_opcodes_0f; 3.8 + 3.9 +static inline void PUSH_W(uint16_t val) 3.10 +{ 3.11 + if (stack32) 3.12 + { 3.13 + writememw(ss, ESP - 2, val); if (abrt) return; 3.14 + ESP -= 2; 3.15 + } 3.16 + else 3.17 + { 3.18 + writememw(ss, (SP - 2) & 0xFFFF, val); if (abrt) return; 3.19 + SP -= 2; 3.20 + } 3.21 +} 3.22 + 3.23 +static inline void PUSH_L(uint32_t val) 3.24 +{ 3.25 + if (stack32) 3.26 + { 3.27 + writememl(ss, ESP - 4, val); if (abrt) return; 3.28 + ESP -= 4; 3.29 + } 3.30 + else 3.31 + { 3.32 + writememl(ss, (SP - 4) & 0xFFFF, val); if (abrt) return; 3.33 + SP -= 4; 3.34 + } 3.35 +} 3.36 + 3.37 +static inline uint16_t POP_W() 3.38 +{ 3.39 + uint16_t ret; 3.40 + if (stack32) 3.41 + { 3.42 + ret = readmemw(ss, ESP); if (abrt) return 0; 3.43 + ESP += 2; 3.44 + } 3.45 + else 3.46 + { 3.47 + ret = readmemw(ss, SP); if (abrt) return 0; 3.48 + SP += 2; 3.49 + } 3.50 + return ret; 3.51 +} 3.52 + 3.53 +static inline uint32_t POP_L() 3.54 +{ 3.55 + uint32_t ret; 3.56 + if (stack32) 3.57 + { 3.58 + ret = readmeml(ss, ESP); if (abrt) return 0; 3.59 + ESP += 4; 3.60 + } 3.61 + else 3.62 + { 3.63 + ret = readmeml(ss, SP); if (abrt) return 0; 3.64 + SP += 4; 3.65 + } 3.66 + return ret; 3.67 +} 3.68 + 3.69 +#include "x86_ops_arith.h" 3.70 +#include "x86_ops_atomic.h" 3.71 +#include "x86_ops_bcd.h" 3.72 +#include "x86_ops_bit.h" 3.73 +#include "x86_ops_bitscan.h" 3.74 +#include "x86_ops_call.h" 3.75 +#include "x86_ops_flag.h" 3.76 +#include "x86_ops_fpu.h" 3.77 +#include "x86_ops_inc_dec.h" 3.78 +#include "x86_ops_int.h" 3.79 +#include "x86_ops_io.h" 3.80 +#include "x86_ops_jump.h" 3.81 +#include "x86_ops_misc.h" 3.82 +#include "x86_ops_mov.h" 3.83 +#include "x86_ops_mov_ctrl.h" 3.84 +#include "x86_ops_mov_seg.h" 3.85 +#include "x86_ops_movx.h" 3.86 +#include "x86_ops_msr.h" 3.87 +#include "x86_ops_mul.h" 3.88 +#include "x86_ops_pmode.h" 3.89 +#include "x86_ops_prefix.h" 3.90 +#include "x86_ops_rep.h" 3.91 +#include "x86_ops_ret.h" 3.92 +#include "x86_ops_set.h" 3.93 +#include "x86_ops_shift.h" 3.94 +#include "x86_ops_stack.h" 3.95 +#include "x86_ops_string.h" 3.96 +#include "x86_ops_xchg.h" 3.97 + 3.98 +static int ILLEGAL(uint32_t fetchdat) 3.99 +{ 3.100 + pc = oldpc; 3.101 + x86illegal(); 3.102 + return 0; 3.103 +} 3.104 + 3.105 +static int op0F_w_a16(uint32_t fetchdat) 3.106 +{ 3.107 + int opcode = fetchdat & 0xff; 3.108 + pc++; 3.109 + 3.110 + return x86_opcodes_0f[opcode](fetchdat >> 8); 3.111 +} 3.112 +static int op0F_l_a16(uint32_t fetchdat) 3.113 +{ 3.114 + int opcode = fetchdat & 0xff; 3.115 + pc++; 3.116 + 3.117 + return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); 3.118 +} 3.119 +static int op0F_w_a32(uint32_t fetchdat) 3.120 +{ 3.121 + int opcode = fetchdat & 0xff; 3.122 + pc++; 3.123 + 3.124 + return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); 3.125 +} 3.126 +static int op0F_l_a32(uint32_t fetchdat) 3.127 +{ 3.128 + int opcode = fetchdat & 0xff; 3.129 + pc++; 3.130 + 3.131 + return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); 3.132 +} 3.133 + 3.134 +void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f) 3.135 +{ 3.136 + x86_opcodes = opcodes; 3.137 + x86_opcodes_0f = opcodes_0f; 3.138 +} 3.139 + 3.140 +OpFn ops_286_0f[1024] = 3.141 +{ 3.142 + /*16-bit data, 16-bit addr*/ 3.143 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.144 +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.145 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.146 +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.147 +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.148 + 3.149 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.150 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.151 +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.152 +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.153 + 3.154 +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.155 +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.156 +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.157 +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.158 + 3.159 +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.160 +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.161 +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.162 +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.163 + 3.164 + /*32-bit data, 16-bit addr*/ 3.165 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.166 +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.167 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.168 +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.169 +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.170 + 3.171 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.172 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.173 +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.174 +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.175 + 3.176 +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.177 +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.178 +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.179 +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.180 + 3.181 +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.182 +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.183 +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.184 +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.185 + 3.186 + /*16-bit data, 32-bit addr*/ 3.187 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.188 +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.189 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.190 +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.191 +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.192 + 3.193 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.194 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.195 +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.196 +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.197 + 3.198 +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.199 +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.200 +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.201 +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.202 + 3.203 +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.204 +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.205 +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.206 +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.207 + 3.208 + /*32-bit data, 32-bit addr*/ 3.209 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.210 +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.211 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.212 +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.213 +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.214 + 3.215 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.216 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.217 +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.218 +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.219 + 3.220 +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.221 +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.222 +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.223 +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.224 + 3.225 +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.226 +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.227 +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.228 +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.229 +}; 3.230 + 3.231 +OpFn ops_386_0f[1024] = 3.232 +{ 3.233 + /*16-bit data, 16-bit addr*/ 3.234 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.235 +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.236 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.237 +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.238 +/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.239 + 3.240 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.241 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.242 +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.243 +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.244 + 3.245 +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, 3.246 +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, 3.247 +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, 3.248 +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,ILLEGAL, ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, 3.249 + 3.250 +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, 3.251 +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.252 +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.253 +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.254 + 3.255 + /*32-bit data, 16-bit addr*/ 3.256 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.257 +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.258 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.259 +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.260 +/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.261 + 3.262 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.263 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.264 +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.265 +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.266 + 3.267 +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, 3.268 +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, 3.269 +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, 3.270 +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, 3.271 + 3.272 +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, 3.273 +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.274 +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.275 +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.276 + 3.277 + /*16-bit data, 32-bit addr*/ 3.278 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.279 +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.280 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.281 +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.282 +/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.283 + 3.284 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.285 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.286 +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.287 +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.288 + 3.289 +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, 3.290 +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, 3.291 +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, 3.292 +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,ILLEGAL, ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, 3.293 + 3.294 +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, 3.295 +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.296 +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.297 +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.298 + 3.299 + /*32-bit data, 32-bit addr*/ 3.300 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.301 +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.302 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.303 +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.304 +/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.305 + 3.306 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.307 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.308 +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.309 +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.310 + 3.311 +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, 3.312 +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, 3.313 +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, 3.314 +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, 3.315 + 3.316 +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, 3.317 +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.318 +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.319 +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 3.320 +}; 3.321 + 3.322 +OpFn ops_286[1024] = 3.323 +{ 3.324 + /*16-bit data, 16-bit addr*/ 3.325 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.326 +/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, 3.327 +/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, 3.328 +/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, 3.329 +/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, 3.330 + 3.331 +/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, 3.332 +/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, 3.333 +/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, 3.334 +/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, 3.335 + 3.336 +/*80*/ op80_a16, op81_w_a16, ILLEGAL, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, 3.337 +/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF_286, opSAHF, opLAHF, 3.338 +/*a0*/ opMOV_AL_a16, opMOV_AX_a16, opMOV_a16_AL, opMOV_a16_AX, opMOVSB_a16, opMOVSW_a16, opCMPSB_a16, opCMPSW_a16, opTEST_AL, opTEST_AX, opSTOSB_a16, opSTOSW_a16, opLODSB_a16, opLODSW_a16, opSCASB_a16, opSCASW_a16, 3.339 +/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, 3.340 + 3.341 +/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET, 3.342 +/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, 3.343 +/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, 3.344 +/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, 3.345 + 3.346 + /*32-bit data, 16-bit addr*/ 3.347 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.348 +/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, 3.349 +/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, 3.350 +/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, 3.351 +/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, 3.352 + 3.353 +/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, 3.354 +/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, 3.355 +/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, 3.356 +/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, 3.357 + 3.358 +/*80*/ op80_a16, op81_w_a16, ILLEGAL, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, 3.359 +/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF_286, opSAHF, opLAHF, 3.360 +/*a0*/ opMOV_AL_a16, opMOV_AX_a16, opMOV_a16_AL, opMOV_a16_AX, opMOVSB_a16, opMOVSW_a16, opCMPSB_a16, opCMPSW_a16, opTEST_AL, opTEST_AX, opSTOSB_a16, opSTOSW_a16, opLODSB_a16, opLODSW_a16, opSCASB_a16, opSCASW_a16, 3.361 +/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, 3.362 + 3.363 +/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET, 3.364 +/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, 3.365 +/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, 3.366 +/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, 3.367 + 3.368 + /*16-bit data, 32-bit addr*/ 3.369 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.370 +/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, 3.371 +/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, 3.372 +/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, 3.373 +/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, 3.374 + 3.375 +/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, 3.376 +/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, 3.377 +/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, 3.378 +/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, 3.379 + 3.380 +/*80*/ op80_a16, op81_w_a16, ILLEGAL, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, 3.381 +/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF_286, opSAHF, opLAHF, 3.382 +/*a0*/ opMOV_AL_a16, opMOV_AX_a16, opMOV_a16_AL, opMOV_a16_AX, opMOVSB_a16, opMOVSW_a16, opCMPSB_a16, opCMPSW_a16, opTEST_AL, opTEST_AX, opSTOSB_a16, opSTOSW_a16, opLODSB_a16, opLODSW_a16, opSCASB_a16, opSCASW_a16, 3.383 +/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, 3.384 + 3.385 +/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET, 3.386 +/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, 3.387 +/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, 3.388 +/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, 3.389 + 3.390 + /*32-bit data, 32-bit addr*/ 3.391 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.392 +/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, 3.393 +/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, 3.394 +/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, 3.395 +/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, 3.396 + 3.397 +/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, 3.398 +/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, 3.399 +/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, 3.400 +/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, 3.401 + 3.402 +/*80*/ op80_a16, op81_w_a16, ILLEGAL, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, 3.403 +/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF_286, opSAHF, opLAHF, 3.404 +/*a0*/ opMOV_AL_a16, opMOV_AX_a16, opMOV_a16_AL, opMOV_a16_AX, opMOVSB_a16, opMOVSW_a16, opCMPSB_a16, opCMPSW_a16, opTEST_AL, opTEST_AX, opSTOSB_a16, opSTOSW_a16, opLODSB_a16, opLODSW_a16, opSCASB_a16, opSCASW_a16, 3.405 +/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, 3.406 + 3.407 +/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET, 3.408 +/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, 3.409 +/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, 3.410 +/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, 3.411 +}; 3.412 + 3.413 +OpFn ops_386[1024] = 3.414 +{ 3.415 + /*16-bit data, 16-bit addr*/ 3.416 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.417 +/*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, 3.418 +/*10*/ opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, 3.419 +/*20*/ opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, 3.420 +/*30*/ opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, 3.421 + 3.422 +/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, 3.423 +/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, 3.424 +/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a16, opARPL_a16, op_FS, op_GS, op_66, op_67, opPUSH_imm_w, opIMUL_w_iw_a16,opPUSH_imm_bw, opIMUL_w_ib_a16,opINSB_a16, opINSW_a16, opOUTSB_a16, opOUTSW_a16, 3.425 +/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, 3.426 + 3.427 +/*80*/ op80_a16, op81_w_a16, ILLEGAL, op83_w_a16, opTEST_b_a16, opTEST_w_a16, opXCHG_b_a16, opXCHG_w_a16, opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, opMOV_w_seg_a16,opLEA_w_a16, opMOV_seg_w_a16,opPOPW_a16, 3.428 +/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF, opSAHF, opLAHF, 3.429 +/*a0*/ opMOV_AL_a16, opMOV_AX_a16, opMOV_a16_AL, opMOV_a16_AX, opMOVSB_a16, opMOVSW_a16, opCMPSB_a16, opCMPSW_a16, opTEST_AL, opTEST_AX, opSTOSB_a16, opSTOSW_a16, opLODSB_a16, opLODSW_a16, opSCASB_a16, opSCASW_a16, 3.430 +/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, 3.431 + 3.432 +/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET, 3.433 +/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, 3.434 +/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, 3.435 +/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, 3.436 + 3.437 + /*32-bit data, 16-bit addr*/ 3.438 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.439 +/*00*/ opADD_b_rmw_a16,opADD_l_rmw_a16,opADD_b_rm_a16, opADD_l_rm_a16, opADD_AL_imm, opADD_EAX_imm, opPUSH_ES_l, opPOP_ES_l, opOR_b_rmw_a16, opOR_l_rmw_a16, opOR_b_rm_a16, opOR_l_rm_a16, opOR_AL_imm, opOR_EAX_imm, opPUSH_CS_l, op0F_l_a16, 3.440 +/*10*/ opADC_b_rmw_a16,opADC_l_rmw_a16,opADC_b_rm_a16, opADC_l_rm_a16, opADC_AL_imm, opADC_EAX_imm, opPUSH_SS_l, opPOP_SS_l, opSBB_b_rmw_a16,opSBB_l_rmw_a16,opSBB_b_rm_a16, opSBB_l_rm_a16, opSBB_AL_imm, opSBB_EAX_imm, opPUSH_DS_l, opPOP_DS_l, 3.441 +/*20*/ opAND_b_rmw_a16,opAND_l_rmw_a16,opAND_b_rm_a16, opAND_l_rm_a16, opAND_AL_imm, opAND_EAX_imm, op_ES, opDAA, opSUB_b_rmw_a16,opSUB_l_rmw_a16,opSUB_b_rm_a16, opSUB_l_rm_a16, opSUB_AL_imm, opSUB_EAX_imm, op_CS, opDAS, 3.442 +/*30*/ opXOR_b_rmw_a16,opXOR_l_rmw_a16,opXOR_b_rm_a16, opXOR_l_rm_a16, opXOR_AL_imm, opXOR_EAX_imm, op_SS, opAAA, opCMP_b_rmw_a16,opCMP_l_rmw_a16,opCMP_b_rm_a16, opCMP_l_rm_a16, opCMP_AL_imm, opCMP_EAX_imm, op_DS, opAAS, 3.443 + 3.444 +/*40*/ opINC_EAX, opINC_ECX, opINC_EDX, opINC_EBX, opINC_ESP, opINC_EBP, opINC_ESI, opINC_EDI, opDEC_EAX, opDEC_ECX, opDEC_EDX, opDEC_EBX, opDEC_ESP, opDEC_EBP, opDEC_ESI, opDEC_EDI, 3.445 +/*50*/ opPUSH_EAX, opPUSH_ECX, opPUSH_EDX, opPUSH_EBX, opPUSH_ESP, opPUSH_EBP, opPUSH_ESI, opPUSH_EDI, opPOP_EAX, opPOP_ECX, opPOP_EDX, opPOP_EBX, opPOP_ESP, opPOP_EBP, opPOP_ESI, opPOP_EDI, 3.446 +/*60*/ opPUSHA_l, opPOPA_l, opBOUND_l_a16, opARPL_a16, op_FS, op_GS, op_66, op_67, opPUSH_imm_l, opIMUL_l_il_a16,opPUSH_imm_bl, opIMUL_l_ib_a16,opINSB_a16, opINSL_a16, opOUTSB_a16, opOUTSL_a16, 3.447 +/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, 3.448 + 3.449 +/*80*/ op80_a16, op81_l_a16, ILLEGAL, op83_l_a16, opTEST_b_a16, opTEST_l_a16, opXCHG_b_a16, opXCHG_l_a16, opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, opMOV_l_seg_a16,opLEA_l_a16, opMOV_seg_w_a16,opPOPL_a16, 3.450 +/*90*/ opNOP, opXCHG_EAX_ECX, opXCHG_EAX_EDX, opXCHG_EAX_EBX, opXCHG_EAX_ESP, opXCHG_EAX_EBP, opXCHG_EAX_ESI, opXCHG_EAX_EDI, opCWDE, opCDQ, opCALL_far_l, opWAIT, opPUSHFD, opPOPFD, opSAHF, opLAHF, 3.451 +/*a0*/ opMOV_AL_a16, opMOV_EAX_a16, opMOV_a16_AL, opMOV_a16_EAX, opMOVSB_a16, opMOVSL_a16, opCMPSB_a16, opCMPSL_a16, opTEST_AL, opTEST_EAX, opSTOSB_a16, opSTOSL_a16, opLODSB_a16, opLODSL_a16, opSCASB_a16, opSCASL_a16, 3.452 +/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_EAX_imm, opMOV_ECX_imm, opMOV_EDX_imm, opMOV_EBX_imm, opMOV_ESP_imm, opMOV_EBP_imm, opMOV_ESI_imm, opMOV_EDI_imm, 3.453 + 3.454 +/*c0*/ opC0_a16, opC1_l_a16, opRET_l_imm, opRET_l, opLES_l_a16, opLDS_l_a16, opMOV_b_imm_a16,opMOV_l_imm_a16,opENTER_l, opLEAVE_l, opRETF_a32_imm, opRETF_a32, opINT3, opINT, opINTO, opIRETD, 3.455 +/*d0*/ opD0_a16, opD1_l_a16, opD2_a16, opD3_l_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, 3.456 +/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX, 3.457 +/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_l_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_l_a16, 3.458 + 3.459 + /*16-bit data, 32-bit addr*/ 3.460 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.461 +/*00*/ opADD_b_rmw_a32,opADD_w_rmw_a32,opADD_b_rm_a32, opADD_w_rm_a32, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a32, opOR_w_rmw_a32, opOR_b_rm_a32, opOR_w_rm_a32, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a32, 3.462 +/*10*/ opADC_b_rmw_a32,opADC_w_rmw_a32,opADC_b_rm_a32, opADC_w_rm_a32, opADC_AL_imm, opADC_AX_imm, opPUSH_SS_w, opPOP_SS_w, opSBB_b_rmw_a32,opSBB_w_rmw_a32,opSBB_b_rm_a32, opSBB_w_rm_a32, opSBB_AL_imm, opSBB_AX_imm, opPUSH_DS_w, opPOP_DS_w, 3.463 +/*20*/ opAND_b_rmw_a32,opAND_w_rmw_a32,opAND_b_rm_a32, opAND_w_rm_a32, opAND_AL_imm, opAND_AX_imm, op_ES, opDAA, opSUB_b_rmw_a32,opSUB_w_rmw_a32,opSUB_b_rm_a32, opSUB_w_rm_a32, opSUB_AL_imm, opSUB_AX_imm, op_CS, opDAS, 3.464 +/*30*/ opXOR_b_rmw_a32,opXOR_w_rmw_a32,opXOR_b_rm_a32, opXOR_w_rm_a32, opXOR_AL_imm, opXOR_AX_imm, op_SS, opAAA, opCMP_b_rmw_a32,opCMP_w_rmw_a32,opCMP_b_rm_a32, opCMP_w_rm_a32, opCMP_AL_imm, opCMP_AX_imm, op_DS, opAAS, 3.465 + 3.466 +/*40*/ opINC_AX, opINC_CX, opINC_DX, opINC_BX, opINC_SP, opINC_BP, opINC_SI, opINC_DI, opDEC_AX, opDEC_CX, opDEC_DX, opDEC_BX, opDEC_SP, opDEC_BP, opDEC_SI, opDEC_DI, 3.467 +/*50*/ opPUSH_AX, opPUSH_CX, opPUSH_DX, opPUSH_BX, opPUSH_SP, opPUSH_BP, opPUSH_SI, opPUSH_DI, opPOP_AX, opPOP_CX, opPOP_DX, opPOP_BX, opPOP_SP, opPOP_BP, opPOP_SI, opPOP_DI, 3.468 +/*60*/ opPUSHA_w, opPOPA_w, opBOUND_w_a32, opARPL_a32, op_FS, op_GS, op_66, op_67, opPUSH_imm_w, opIMUL_w_iw_a32,opPUSH_imm_bw, opIMUL_w_ib_a32,opINSB_a32, opINSW_a32, opOUTSB_a32, opOUTSW_a32, 3.469 +/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, 3.470 + 3.471 +/*80*/ op80_a32, op81_w_a32, ILLEGAL, op83_w_a32, opTEST_b_a32, opTEST_w_a32, opXCHG_b_a32, opXCHG_w_a32, opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, opMOV_w_seg_a32,opLEA_w_a32, opMOV_seg_w_a32,opPOPW_a32, 3.472 +/*90*/ opNOP, opXCHG_AX_CX, opXCHG_AX_DX, opXCHG_AX_BX, opXCHG_AX_SP, opXCHG_AX_BP, opXCHG_AX_SI, opXCHG_AX_DI, opCBW, opCWD, opCALL_far_w, opWAIT, opPUSHF, opPOPF, opSAHF, opLAHF, 3.473 +/*a0*/ opMOV_AL_a32, opMOV_AX_a32, opMOV_a32_AL, opMOV_a32_AX, opMOVSB_a32, opMOVSW_a32, opCMPSB_a32, opCMPSW_a32, opTEST_AL, opTEST_AX, opSTOSB_a32, opSTOSW_a32, opLODSB_a32, opLODSW_a32, opSCASB_a32, opSCASW_a32, 3.474 +/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_AX_imm, opMOV_CX_imm, opMOV_DX_imm, opMOV_BX_imm, opMOV_SP_imm, opMOV_BP_imm, opMOV_SI_imm, opMOV_DI_imm, 3.475 + 3.476 +/*c0*/ opC0_a32, opC1_w_a32, opRET_w_imm, opRET_w, opLES_w_a32, opLDS_w_a32, opMOV_b_imm_a32,opMOV_w_imm_a32,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET, 3.477 +/*d0*/ opD0_a32, opD1_w_a32, opD2_a32, opD3_w_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32, 3.478 +/*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, 3.479 +/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_w_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_w_a32, 3.480 + 3.481 + /*32-bit data, 32-bit addr*/ 3.482 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 3.483 +/*00*/ opADD_b_rmw_a32,opADD_l_rmw_a32,opADD_b_rm_a32, opADD_l_rm_a32, opADD_AL_imm, opADD_EAX_imm, opPUSH_ES_l, opPOP_ES_l, opOR_b_rmw_a32, opOR_l_rmw_a32, opOR_b_rm_a32, opOR_l_rm_a32, opOR_AL_imm, opOR_EAX_imm, opPUSH_CS_l, op0F_l_a32, 3.484 +/*10*/ opADC_b_rmw_a32,opADC_l_rmw_a32,opADC_b_rm_a32, opADC_l_rm_a32, opADC_AL_imm, opADC_EAX_imm, opPUSH_SS_l, opPOP_SS_l, opSBB_b_rmw_a32,opSBB_l_rmw_a32,opSBB_b_rm_a32, opSBB_l_rm_a32, opSBB_AL_imm, opSBB_EAX_imm, opPUSH_DS_l, opPOP_DS_l, 3.485 +/*20*/ opAND_b_rmw_a32,opAND_l_rmw_a32,opAND_b_rm_a32, opAND_l_rm_a32, opAND_AL_imm, opAND_EAX_imm, op_ES, opDAA, opSUB_b_rmw_a32,opSUB_l_rmw_a32,opSUB_b_rm_a32, opSUB_l_rm_a32, opSUB_AL_imm, opSUB_EAX_imm, op_CS, opDAS, 3.486 +/*30*/ opXOR_b_rmw_a32,opXOR_l_rmw_a32,opXOR_b_rm_a32, opXOR_l_rm_a32, opXOR_AL_imm, opXOR_EAX_imm, op_SS, opAAA, opCMP_b_rmw_a32,opCMP_l_rmw_a32,opCMP_b_rm_a32, opCMP_l_rm_a32, opCMP_AL_imm, opCMP_EAX_imm, op_DS, opAAS, 3.487 + 3.488 +/*40*/ opINC_EAX, opINC_ECX, opINC_EDX, opINC_EBX, opINC_ESP, opINC_EBP, opINC_ESI, opINC_EDI, opDEC_EAX, opDEC_ECX, opDEC_EDX, opDEC_EBX, opDEC_ESP, opDEC_EBP, opDEC_ESI, opDEC_EDI, 3.489 +/*50*/ opPUSH_EAX, opPUSH_ECX, opPUSH_EDX, opPUSH_EBX, opPUSH_ESP, opPUSH_EBP, opPUSH_ESI, opPUSH_EDI, opPOP_EAX, opPOP_ECX, opPOP_EDX, opPOP_EBX, opPOP_ESP, opPOP_EBP, opPOP_ESI, opPOP_EDI, 3.490 +/*60*/ opPUSHA_l, opPOPA_l, opBOUND_l_a32, opARPL_a32, op_FS, op_GS, op_66, op_67, opPUSH_imm_l, opIMUL_l_il_a32,opPUSH_imm_bl, opIMUL_l_ib_a32,opINSB_a32, opINSL_a32, opOUTSB_a32, opOUTSL_a32, 3.491 +/*70*/ opJO, opJNO, opJB, opJNB, opJE, opJNE, opJBE, opJNBE, opJS, opJNS, opJP, opJNP, opJL, opJNL, opJLE, opJNLE, 3.492 + 3.493 +/*80*/ op80_a32, op81_l_a32, ILLEGAL, op83_l_a32, opTEST_b_a32, opTEST_l_a32, opXCHG_b_a32, opXCHG_l_a32, opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, opMOV_l_seg_a32,opLEA_l_a32, opMOV_seg_w_a32,opPOPL_a32, 3.494 +/*90*/ opNOP, opXCHG_EAX_ECX, opXCHG_EAX_EDX, opXCHG_EAX_EBX, opXCHG_EAX_ESP, opXCHG_EAX_EBP, opXCHG_EAX_ESI, opXCHG_EAX_EDI, opCWDE, opCDQ, opCALL_far_l, opWAIT, opPUSHFD, opPOPFD, opSAHF, opLAHF, 3.495 +/*a0*/ opMOV_AL_a32, opMOV_EAX_a32, opMOV_a32_AL, opMOV_a32_EAX, opMOVSB_a32, opMOVSL_a32, opCMPSB_a32, opCMPSL_a32, opTEST_AL, opTEST_EAX, opSTOSB_a32, opSTOSL_a32, opLODSB_a32, opLODSL_a32, opSCASB_a32, opSCASL_a32, 3.496 +/*b0*/ opMOV_AL_imm, opMOV_CL_imm, opMOV_DL_imm, opMOV_BL_imm, opMOV_AH_imm, opMOV_CH_imm, opMOV_DH_imm, opMOV_BH_imm, opMOV_EAX_imm, opMOV_ECX_imm, opMOV_EDX_imm, opMOV_EBX_imm, opMOV_ESP_imm, opMOV_EBP_imm, opMOV_ESI_imm, opMOV_EDI_imm, 3.497 + 3.498 +/*c0*/ opC0_a32, opC1_l_a32, opRET_l_imm, opRET_l, opLES_l_a32, opLDS_l_a32, opMOV_b_imm_a32,opMOV_l_imm_a32,opENTER_l, opLEAVE_l, opRETF_a32_imm, opRETF_a32, opINT3, opINT, opINTO, opIRETD, 3.499 +/*d0*/ opD0_a32, opD1_l_a32, opD2_a32, opD3_l_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32, 3.500 +/*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX, 3.501 +/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32, 3.502 +};
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/808x.c Mon May 27 19:56:33 2013 +0100 4.3 @@ -0,0 +1,3474 @@ 4.4 +//1B64 - Vid_SetMode (Vid_Vesa.c) 4.5 +//6689c - CONS_Printf 4.6 +/*SHR AX,1 4.7 + 4.8 + 4 clocks - fetch opcode 4.9 + 4 clocks - fetch mod/rm 4.10 + 2 clocks - execute 2 clocks - fetch opcode 1 4.11 + 2 clocks - fetch opcode 2 4.12 + 4 clocks - fetch mod/rm 4.13 + 2 clocks - fetch opcode 1 2 clocks - execute 4.14 + 2 clocks - fetch opcode 2 etc*/ 4.15 +#include <stdio.h> 4.16 +#include "ibm.h" 4.17 + 4.18 +#include "cpu.h" 4.19 +#include "keyboard.h" 4.20 +#include "mem.h" 4.21 +#include "pic.h" 4.22 +#include "timer.h" 4.23 +#include "x86.h" 4.24 + 4.25 +int nextcyc=0; 4.26 +int cycdiff; 4.27 +int is8086=0; 4.28 + 4.29 +int memcycs; 4.30 +int nopageerrors=0; 4.31 + 4.32 +void FETCHCOMPLETE(); 4.33 + 4.34 +uint8_t readmembl(uint32_t addr); 4.35 +void writemembl(uint32_t addr, uint8_t val); 4.36 +uint16_t readmemwl(uint32_t seg, uint32_t addr); 4.37 +void writememwl(uint32_t seg, uint32_t addr, uint16_t val); 4.38 +uint32_t readmemll(uint32_t seg, uint32_t addr); 4.39 +void writememll(uint32_t seg, uint32_t addr, uint32_t val); 4.40 + 4.41 +#undef readmemb 4.42 +#undef readmemw 4.43 +uint8_t readmemb(uint32_t a) 4.44 +{ 4.45 + if (a!=(cs+pc)) memcycs+=4; 4.46 + if (readlookup2[(a)>>12]==0xFFFFFFFF) return readmembl(a); 4.47 + else return ram[readlookup2[(a)>>12]+((a)&0xFFF)]; 4.48 +} 4.49 + 4.50 +uint8_t readmembf(uint32_t a) 4.51 +{ 4.52 + if (readlookup2[(a)>>12]==0xFFFFFFFF) return readmembl(a); 4.53 + else return ram[readlookup2[(a)>>12]+((a)&0xFFF)]; 4.54 +} 4.55 + 4.56 +uint16_t readmemw(uint32_t s, uint16_t a) 4.57 +{ 4.58 + if (a!=(cs+pc)) memcycs+=(8>>is8086); 4.59 + if ((readlookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF)) return readmemwl(s,a); 4.60 + else return *((uint16_t *)(&ram[readlookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)])); 4.61 +} 4.62 + 4.63 +void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); memcycs+=4; } 4.64 + 4.65 +#undef fetchea 4.66 +#define fetchea() { rmdat=FETCH(); \ 4.67 + reg=(rmdat>>3)&7; \ 4.68 + mod=(rmdat>>6)&3; \ 4.69 + rm=rmdat&7; \ 4.70 + if (mod!=3) fetcheal(); } 4.71 + 4.72 +void writemembl(uint32_t addr, uint8_t val); 4.73 +void writememb(uint32_t a, uint8_t v) 4.74 +{ 4.75 + memcycs+=4; 4.76 + if (writelookup2[(a)>>12]==0xFFFFFFFF) writemembl(a,v); 4.77 + else ram[writelookup2[(a)>>12]+((a)&0xFFF)]=v; 4.78 +} 4.79 +void writememwl(uint32_t seg, uint32_t addr, uint16_t val); 4.80 +void writememw(uint32_t s, uint32_t a, uint16_t v) 4.81 +{ 4.82 + memcycs+=(8>>is8086); 4.83 + if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememwl(s,a,v); 4.84 + else *((uint16_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v; 4.85 +} 4.86 +void writememll(uint32_t seg, uint32_t addr, uint32_t val); 4.87 +void writememl(uint32_t s, uint32_t a, uint32_t v) 4.88 +{ 4.89 + if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememll(s,a,v); 4.90 + else *((uint32_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v; 4.91 +} 4.92 + 4.93 + 4.94 +void dumpregs(); 4.95 +uint16_t oldcs; 4.96 +int oldcpl; 4.97 + 4.98 +int tempc; 4.99 +uint8_t opcode; 4.100 +int times=0; 4.101 +uint16_t pc2,pc3; 4.102 +int noint=0; 4.103 + 4.104 +int output=0; 4.105 + 4.106 +int shadowbios=0; 4.107 + 4.108 +int ins=0; 4.109 +//#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a)) 4.110 + 4.111 +int ssegs; 4.112 + 4.113 +int fetchcycles=0,memcycs,fetchclocks; 4.114 + 4.115 +uint8_t prefetchqueue[6]; 4.116 +uint16_t prefetchpc; 4.117 +int prefetchw=0; 4.118 +inline uint8_t FETCH() 4.119 +{ 4.120 + uint8_t temp; 4.121 +/* temp=prefetchqueue[0]; 4.122 + prefetchqueue[0]=prefetchqueue[1]; 4.123 + prefetchqueue[1]=prefetchqueue[2]; 4.124 + prefetchqueue[2]=prefetchqueue[3]; 4.125 + prefetchqueue[3]=prefetchqueue[4]; 4.126 + prefetchqueue[4]=prefetchqueue[5]; 4.127 + if (prefetchw<=((is8086)?4:3)) 4.128 + { 4.129 + prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++; 4.130 + if (is8086 && (prefetchpc&1)) 4.131 + { 4.132 + prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++; 4.133 + } 4.134 + }*/ 4.135 + 4.136 +// uint8_t temp=readmemb(cs+pc); 4.137 +// if (output) printf("FETCH %04X %i\n",pc,fetchcycles); 4.138 + if (prefetchw==0) //(fetchcycles<4) 4.139 + { 4.140 + cycles-=(4-(fetchcycles&3)); 4.141 + fetchclocks+=(4-(fetchcycles&3)); 4.142 + fetchcycles=4; 4.143 + temp=readmembf(cs+pc); 4.144 + prefetchpc=pc=pc+1; 4.145 +// if (output) printf(" FETCH %04X:%04X %02X %04X %04X %i\n",CS,pc-1,temp,pc,prefetchpc,prefetchw); 4.146 + if (is8086 && (pc&1)) 4.147 + { 4.148 + prefetchqueue[0]=readmembf(cs+pc); 4.149 +// if (output) printf(" PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); 4.150 + prefetchpc++; 4.151 + prefetchw++; 4.152 + } 4.153 + } 4.154 + else 4.155 + { 4.156 + temp=prefetchqueue[0]; 4.157 + prefetchqueue[0]=prefetchqueue[1]; 4.158 + prefetchqueue[1]=prefetchqueue[2]; 4.159 + prefetchqueue[2]=prefetchqueue[3]; 4.160 + prefetchqueue[3]=prefetchqueue[4]; 4.161 + prefetchqueue[4]=prefetchqueue[5]; 4.162 + prefetchw--; 4.163 +// if (output) printf("PREFETCH %04X:%04X %02X %04X %04X %i\n",CS,pc,temp,pc,prefetchpc,prefetchw); 4.164 + fetchcycles-=4; 4.165 +// fetchclocks+=4; 4.166 + pc++; 4.167 + } 4.168 +// if (output) printf("%i\n",fetchcycles); 4.169 + return temp; 4.170 +} 4.171 + 4.172 +inline void FETCHADD(int c) 4.173 +{ 4.174 + int d; 4.175 +// if (output) printf("FETCHADD %i\n",c); 4.176 + if (c<0) return; 4.177 + if (prefetchw>((is8086)?4:3)) return; 4.178 + d=c+(fetchcycles&3); 4.179 + while (d>3 && prefetchw<((is8086)?6:4)) 4.180 + { 4.181 + d-=4; 4.182 + if (is8086 && !(prefetchpc&1)) 4.183 + { 4.184 + prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); 4.185 +// printf("PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); 4.186 + prefetchpc++; 4.187 + prefetchw++; 4.188 + } 4.189 + if (prefetchw<6) 4.190 + { 4.191 + prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); 4.192 +// printf("PREFETCHED from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]); 4.193 + prefetchpc++; 4.194 + prefetchw++; 4.195 + } 4.196 + } 4.197 + fetchcycles+=c; 4.198 + if (fetchcycles>16) fetchcycles=16; 4.199 +// if (fetchcycles>24) fetchcycles=24; 4.200 +} 4.201 + 4.202 +void FETCHCOMPLETE() 4.203 +{ 4.204 +// pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw); 4.205 + if (!(fetchcycles&3)) return; 4.206 + if (prefetchw>((is8086)?4:3)) return; 4.207 + if (!prefetchw) nextcyc=(4-(fetchcycles&3)); 4.208 + cycles-=(4-(fetchcycles&3)); 4.209 + fetchclocks+=(4-(fetchcycles&3)); 4.210 + if (is8086 && !(prefetchpc&1)) 4.211 + { 4.212 + prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); 4.213 +// printf("PREFETCHEDc from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); 4.214 + prefetchpc++; 4.215 + prefetchw++; 4.216 + } 4.217 + if (prefetchw<6) 4.218 + { 4.219 + prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); 4.220 +// printf("PREFETCHEDc from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]); 4.221 + prefetchpc++; 4.222 + prefetchw++; 4.223 + } 4.224 + fetchcycles+=(4-(fetchcycles&3)); 4.225 +} 4.226 + 4.227 +inline void FETCHCLEAR() 4.228 +{ 4.229 +/* int c; 4.230 + fetchcycles=0; 4.231 + prefetchpc=pc; 4.232 + if (is8086 && (prefetchpc&1)) cycles-=4; 4.233 + for (c=0;c<((is8086)?6:4);c++) 4.234 + { 4.235 + prefetchqueue[c]=readmembf(cs+prefetchpc); 4.236 + if (!is8086 || !(prefetchpc&1)) cycles-=4; 4.237 + prefetchpc++; 4.238 + } 4.239 + prefetchw=(is8086)?6:4;*/ 4.240 +// fetchcycles=0; 4.241 + prefetchpc=pc; 4.242 + prefetchw=0; 4.243 + memcycs=cycdiff-cycles; 4.244 + fetchclocks=0; 4.245 +// memcycs=cycles; 4.246 +/* prefetchqueue[0]=readmembf(cs+prefetchpc); 4.247 + prefetchpc++; 4.248 + prefetchw=1; 4.249 + if (is8086 && prefetchpc&1) 4.250 + { 4.251 + prefetchqueue[1]=readmembf(cs+prefetchpc); 4.252 + prefetchpc++; 4.253 + }*/ 4.254 +} 4.255 + 4.256 +static uint16_t getword() 4.257 +{ 4.258 + uint8_t temp=FETCH(); 4.259 + return temp|(FETCH()<<8); 4.260 +} 4.261 + 4.262 + 4.263 +/*EA calculation*/ 4.264 + 4.265 +/*R/M - bits 0-2 - R/M bits 3-5 - Reg bits 6-7 - mod 4.266 + From 386 programmers manual : 4.267 +r8(/r) AL CL DL BL AH CH DH BH 4.268 +r16(/r) AX CX DX BX SP BP SI DI 4.269 +r32(/r) EAX ECX EDX EBX ESP EBP ESI EDI 4.270 +/digit (Opcode) 0 1 2 3 4 5 6 7 4.271 +REG = 000 001 010 011 100 101 110 111 4.272 + ÚÄÄÄAddress 4.273 +disp8 denotes an 8-bit displacement following the ModR/M byte, to be 4.274 +sign-extended and added to the index. disp16 denotes a 16-bit displacement 4.275 +following the ModR/M byte, to be added to the index. Default segment 4.276 +register is SS for the effective addresses containing a BP index, DS for 4.277 +other effective addresses. 4.278 + ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄModR/M Values in HexadecimalÄÄÄÄÄÄÄÄ¿ 4.279 + 4.280 +[BX + SI] 000 00 08 10 18 20 28 30 38 4.281 +[BX + DI] 001 01 09 11 19 21 29 31 39 4.282 +[BP + SI] 010 02 0A 12 1A 22 2A 32 3A 4.283 +[BP + DI] 011 03 0B 13 1B 23 2B 33 3B 4.284 +[SI] 00 100 04 0C 14 1C 24 2C 34 3C 4.285 +[DI] 101 05 0D 15 1D 25 2D 35 3D 4.286 +disp16 110 06 0E 16 1E 26 2E 36 3E 4.287 +[BX] 111 07 0F 17 1F 27 2F 37 3F 4.288 + 4.289 +[BX+SI]+disp8 000 40 48 50 58 60 68 70 78 4.290 +[BX+DI]+disp8 001 41 49 51 59 61 69 71 79 4.291 +[BP+SI]+disp8 010 42 4A 52 5A 62 6A 72 7A 4.292 +[BP+DI]+disp8 011 43 4B 53 5B 63 6B 73 7B 4.293 +[SI]+disp8 01 100 44 4C 54 5C 64 6C 74 7C 4.294 +[DI]+disp8 101 45 4D 55 5D 65 6D 75 7D 4.295 +[BP]+disp8 110 46 4E 56 5E 66 6E 76 7E 4.296 +[BX]+disp8 111 47 4F 57 5F 67 6F 77 7F 4.297 + 4.298 +[BX+SI]+disp16 000 80 88 90 98 A0 A8 B0 B8 4.299 +[BX+DI]+disp16 001 81 89 91 99 A1 A9 B1 B9 4.300 +[BX+SI]+disp16 010 82 8A 92 9A A2 AA B2 BA 4.301 +[BX+DI]+disp16 011 83 8B 93 9B A3 AB B3 BB 4.302 +[SI]+disp16 10 100 84 8C 94 9C A4 AC B4 BC 4.303 +[DI]+disp16 101 85 8D 95 9D A5 AD B5 BD 4.304 +[BP]+disp16 110 86 8E 96 9E A6 AE B6 BE 4.305 +[BX]+disp16 111 87 8F 97 9F A7 AF B7 BF 4.306 + 4.307 +EAX/AX/AL 000 C0 C8 D0 D8 E0 E8 F0 F8 4.308 +ECX/CX/CL 001 C1 C9 D1 D9 E1 E9 F1 F9 4.309 +EDX/DX/DL 010 C2 CA D2 DA E2 EA F2 FA 4.310 +EBX/BX/BL 011 C3 CB D3 DB E3 EB F3 FB 4.311 +ESP/SP/AH 11 100 C4 CC D4 DC E4 EC F4 FC 4.312 +EBP/BP/CH 101 C5 CD D5 DD E5 ED F5 FD 4.313 +ESI/SI/DH 110 C6 CE D6 DE E6 EE F6 FE 4.314 +EDI/DI/BH 111 C7 CF D7 DF E7 EF F7 FF 4.315 + 4.316 +mod = 11 - register 4.317 + 10 - address + 16 bit displacement 4.318 + 01 - address + 8 bit displacement 4.319 + 00 - address 4.320 + 4.321 +reg = If mod=11, (depending on data size, 16 bits/8 bits, 32 bits=extend 16 bit registers) 4.322 + 0=AX/AL 1=CX/CL 2=DX/DL 3=BX/BL 4.323 + 4=SP/AH 5=BP/CH 6=SI/DH 7=DI/BH 4.324 + 4.325 + Otherwise, LSB selects SI/DI (0=SI), NMSB selects BX/BP (0=BX), and MSB 4.326 + selects whether BX/BP are used at all (0=used). 4.327 + 4.328 + mod=00 is an exception though 4.329 + 6=16 bit displacement only 4.330 + 7=[BX] 4.331 + 4.332 + Usage varies with instructions. 4.333 + 4.334 + MOV AL,BL has ModR/M as C3, for example. 4.335 + mod=11, reg=0, r/m=3 4.336 + MOV uses reg as dest, and r/m as src. 4.337 + reg 0 is AL, reg 3 is BL 4.338 + 4.339 + If BP or SP are in address calc, seg is SS, else DS 4.340 +*/ 4.341 + 4.342 +int cycles=0; 4.343 +uint32_t easeg,eaaddr; 4.344 +int rm,reg,mod,rmdat; 4.345 + 4.346 +uint16_t zero=0; 4.347 +uint16_t *mod1add[2][8]; 4.348 +uint32_t *mod1seg[8]; 4.349 + 4.350 +int slowrm[8]; 4.351 + 4.352 +void makemod1table() 4.353 +{ 4.354 + mod1add[0][0]=&BX; mod1add[0][1]=&BX; mod1add[0][2]=&BP; mod1add[0][3]=&BP; 4.355 + mod1add[0][4]=&SI; mod1add[0][5]=&DI; mod1add[0][6]=&BP; mod1add[0][7]=&BX; 4.356 + mod1add[1][0]=&SI; mod1add[1][1]=&DI; mod1add[1][2]=&SI; mod1add[1][3]=&DI; 4.357 + mod1add[1][4]=&zero; mod1add[1][5]=&zero; mod1add[1][6]=&zero; mod1add[1][7]=&zero; 4.358 + slowrm[0]=0; slowrm[1]=1; slowrm[2]=1; slowrm[3]=0; 4.359 + mod1seg[0]=&ds; mod1seg[1]=&ds; mod1seg[2]=&ss; mod1seg[3]=&ss; 4.360 + mod1seg[4]=&ds; mod1seg[5]=&ds; mod1seg[6]=&ss; mod1seg[7]=&ds; 4.361 +} 4.362 + 4.363 +static void fetcheal() 4.364 +{ 4.365 + if (!mod && rm==6) { eaaddr=getword(); easeg=ds; FETCHADD(6); } 4.366 + else 4.367 + { 4.368 + switch (mod) 4.369 + { 4.370 + case 0: 4.371 + eaaddr=0; 4.372 + if (rm&4) FETCHADD(5); 4.373 + else FETCHADD(7+slowrm[rm]); 4.374 + break; 4.375 + case 1: 4.376 + eaaddr=(uint16_t)(int8_t)FETCH(); 4.377 + if (rm&4) FETCHADD(9); 4.378 + else FETCHADD(11+slowrm[rm]); 4.379 + break; 4.380 + case 2: 4.381 + eaaddr=getword(); 4.382 + if (rm&4) FETCHADD(9); 4.383 + else FETCHADD(11+slowrm[rm]); 4.384 + break; 4.385 + } 4.386 + eaaddr+=(*mod1add[0][rm])+(*mod1add[1][rm]); 4.387 + easeg=*mod1seg[rm]; 4.388 + eaaddr&=0xFFFF; 4.389 + } 4.390 +} 4.391 + 4.392 +static inline uint8_t geteab() 4.393 +{ 4.394 + if (mod==3) 4.395 + return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l; 4.396 + return readmemb(easeg+eaaddr); 4.397 +} 4.398 + 4.399 +static inline uint16_t geteaw() 4.400 +{ 4.401 + if (mod==3) 4.402 + return regs[rm].w; 4.403 +// if (output==3) printf("GETEAW %04X:%08X\n",easeg,eaaddr); 4.404 + return readmemw(easeg,eaaddr); 4.405 +} 4.406 + 4.407 +static inline uint16_t geteaw2() 4.408 +{ 4.409 + if (mod==3) 4.410 + return regs[rm].w; 4.411 +// printf("Getting addr from %04X:%04X %05X\n",easeg,eaaddr+2,easeg+eaaddr+2); 4.412 + return readmemw(easeg,(eaaddr+2)&0xFFFF); 4.413 +} 4.414 + 4.415 +static inline void seteab(uint8_t val) 4.416 +{ 4.417 + if (mod==3) 4.418 + { 4.419 + if (rm&4) regs[rm&3].b.h=val; 4.420 + else regs[rm&3].b.l=val; 4.421 + } 4.422 + else 4.423 + { 4.424 + writememb(easeg+eaaddr,val); 4.425 + } 4.426 +} 4.427 + 4.428 +static inline void seteaw(uint16_t val) 4.429 +{ 4.430 + if (mod==3) 4.431 + regs[rm].w=val; 4.432 + else 4.433 + { 4.434 + writememw(easeg,eaaddr,val); 4.435 +// writememb(easeg+eaaddr+1,val>>8); 4.436 + } 4.437 +} 4.438 + 4.439 +#define getr8(r) ((r&4)?regs[r&3].b.h:regs[r&3].b.l) 4.440 + 4.441 +#define setr8(r,v) if (r&4) regs[r&3].b.h=v; \ 4.442 + else regs[r&3].b.l=v; 4.443 + 4.444 + 4.445 +/*Flags*/ 4.446 +uint8_t znptable8[256]; 4.447 +uint16_t znptable16[65536]; 4.448 + 4.449 +void makeznptable() 4.450 +{ 4.451 + int c,d; 4.452 + for (c=0;c<256;c++) 4.453 + { 4.454 + d=0; 4.455 + if (c&1) d++; 4.456 + if (c&2) d++; 4.457 + if (c&4) d++; 4.458 + if (c&8) d++; 4.459 + if (c&16) d++; 4.460 + if (c&32) d++; 4.461 + if (c&64) d++; 4.462 + if (c&128) d++; 4.463 + if (d&1) 4.464 + znptable8[c]=0; 4.465 + else 4.466 + znptable8[c]=P_FLAG; 4.467 + if (c == 0xb1) pclog("znp8 b1 = %i %02X\n", d, znptable8[c]); 4.468 + if (!c) znptable8[c]|=Z_FLAG; 4.469 + if (c&0x80) znptable8[c]|=N_FLAG; 4.470 + } 4.471 + for (c=0;c<65536;c++) 4.472 + { 4.473 + d=0; 4.474 + if (c&1) d++; 4.475 + if (c&2) d++; 4.476 + if (c&4) d++; 4.477 + if (c&8) d++; 4.478 + if (c&16) d++; 4.479 + if (c&32) d++; 4.480 + if (c&64) d++; 4.481 + if (c&128) d++; 4.482 + if (d&1) 4.483 + znptable16[c]=0; 4.484 + else 4.485 + znptable16[c]=P_FLAG; 4.486 + if (c == 0xb1) pclog("znp16 b1 = %i %02X\n", d, znptable16[c]); 4.487 + if (c == 0x65b1) pclog("znp16 65b1 = %i %02X\n", d, znptable16[c]); 4.488 + if (!c) znptable16[c]|=Z_FLAG; 4.489 + if (c&0x8000) znptable16[c]|=N_FLAG; 4.490 + } 4.491 +// isram[0xF]=1; 4.492 +// printf("isram 0 = %i\n",isram[0]); 4.493 + 4.494 +// makemod1table(); 4.495 +} 4.496 +int timetolive=0; 4.497 + 4.498 +extern uint32_t oldcs2; 4.499 +extern uint32_t oldpc2; 4.500 + 4.501 +int indump = 0; 4.502 + 4.503 +void dumpregs() 4.504 +{ 4.505 + FILE *f; 4.506 + int c,d=0,e=0,ff; 4.507 + if (indump) return; 4.508 + indump = 1; 4.509 +// return; 4.510 + output=0; 4.511 +// return; 4.512 +// savenvr(); 4.513 +// return; 4.514 +chdir(pcempath); 4.515 + nopageerrors=1; 4.516 +/* f=fopen("rram3.dmp","wb"); 4.517 + for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f); 4.518 + fclose(f);*/ 4.519 + f=fopen("ram.dmp","wb"); 4.520 + fwrite(ram,mem_size*1024*1024,1,f); 4.521 + fclose(f); 4.522 +/* pclog("Dumping rram5.dmp\n"); 4.523 + f=fopen("rram5.dmp","wb"); 4.524 + for (c=0;c<0x1000000;c++) putc(readmemb(c+0x10150000),f); 4.525 + fclose(f);*/ 4.526 + pclog("Dumping rram.dmp\n"); 4.527 + f=fopen("rram.dmp","wb"); 4.528 + for (c=0;c<0x1000000;c++) putc(readmemb(c),f); 4.529 + fclose(f); 4.530 +/* f=fopen("rram2.dmp","wb"); 4.531 + for (c=0;c<0x100000;c++) putc(readmemb(c+0xbff00000),f); 4.532 + fclose(f); 4.533 + f = fopen("stack.dmp","wb"); 4.534 + for (c = 0; c < 0x6000; c++) putc(readmemb(c+0xFFDFA000), f); 4.535 + fclose(f); 4.536 + f = fopen("tempx.dmp","wb"); 4.537 + for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFC816000), f); 4.538 + fclose(f); 4.539 + f = fopen("tempx2.dmp","wb"); 4.540 + for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFDEF5000), f); 4.541 + fclose(f);*/ 4.542 + pclog("Dumping rram4.dmp\n"); 4.543 + f=fopen("rram4.dmp","wb"); 4.544 + for (c=0;c<0x0050000;c++) 4.545 + { 4.546 + abrt = 0; 4.547 + putc(readmemb386l(0,c+0x80000000),f); 4.548 + } 4.549 + fclose(f); 4.550 + pclog("Dumping done\n"); 4.551 +/* f=fopen("rram6.dmp","wb"); 4.552 + for (c=0;c<0x1000000;c++) putc(readmemb(c+0xBF000000),f); 4.553 + fclose(f);*/ 4.554 +/* f=fopen("ram6.bin","wb"); 4.555 + fwrite(ram+0x10100,0xA000,1,f); 4.556 + fclose(f); 4.557 + f=fopen("boot.bin","wb"); 4.558 + fwrite(ram+0x7C00,0x200,1,f); 4.559 + fclose(f); 4.560 + f=fopen("ram7.bin","wb"); 4.561 + fwrite(ram+0x11100,0x2000,1,f); 4.562 + fclose(f); 4.563 + f=fopen("ram8.bin","wb"); 4.564 + fwrite(ram+0x3D210,0x200,1,f); 4.565 + fclose(f); */ 4.566 + f=fopen("vram.dmp","wb"); 4.567 + fwrite(vram,0x400000,1,f); 4.568 + fclose(f); 4.569 +/* f=fopen("bios.dmp","wb"); 4.570 + fwrite(rom,0x20000,1,f); 4.571 + fclose(f); 4.572 + f=fopen("vbios.dmp","wb"); 4.573 + fwrite(vrom,0x8000,1,f); 4.574 + fclose(f);*/ 4.575 +/* f=fopen("kernel.dmp","wb"); 4.576 + for (c=0;c<0x200000;c++) putc(readmemb(c+0xC0000000),f); 4.577 + fclose(f);*/ 4.578 +/* f=fopen("rram.dmp","wb"); 4.579 + for (c=0;c<0x1500000;c++) putc(readmemb(c),f); 4.580 + fclose(f); 4.581 + if (!times) 4.582 + { 4.583 + f=fopen("thing.dmp","wb"); 4.584 + fwrite(ram+0x11E50,0x1000,1,f); 4.585 + fclose(f); 4.586 + }*/ 4.587 + if (is386) 4.588 + 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); 4.589 + else 4.590 + 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); 4.591 + printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",pc,CS,DS,ES,SS,flags); 4.592 + printf("%04X:%04X %04X:%04X\n",oldcs,oldpc, oldcs2, oldpc2); 4.593 + printf("%i ins\n",ins); 4.594 + if (is386) 4.595 + printf("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real"); 4.596 + else 4.597 + printf("In %s mode\n",(msw&1)?"protected":"real"); 4.598 + printf("CS : base=%06X limit=%04X access=%02X\n",cs,_cs.limit,_cs.access); 4.599 + printf("DS : base=%06X limit=%04X access=%02X\n",ds,_ds.limit,_ds.access); 4.600 + printf("ES : base=%06X limit=%04X access=%02X\n",es,_es.limit,_es.access); 4.601 + if (is386) 4.602 + { 4.603 + printf("FS : base=%06X limit=%04X access=%02X\n",fs,_fs.limit,_fs.access); 4.604 + printf("GS : base=%06X limit=%04X access=%02X\n",gs,_gs.limit,_gs.access); 4.605 + } 4.606 + printf("SS : base=%06X limit=%04X access=%02X\n",ss,_ss.limit,_ss.access); 4.607 + printf("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit); 4.608 + printf("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit); 4.609 + printf("IDT : base=%06X limit=%04X\n",idt.base,idt.limit); 4.610 + printf("TR : base=%06X limit=%04X\n", tr.base, tr.limit); 4.611 + if (is386) 4.612 + { 4.613 + printf("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit"); 4.614 + printf("CR0=%08X CR2=%08X CR3=%08X\n",cr0,cr2,cr3); 4.615 + } 4.616 + printf("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum); 4.617 + for (c=0;c<1024*1024;c++) 4.618 + { 4.619 + if (readlookup2[c]!=0xFFFFFFFF) d++; 4.620 + if (writelookup2[c]!=0xFFFFFFFF) e++; 4.621 + } 4.622 + printf("Entries in readlookup : %i writelookup : %i\n",d,e); 4.623 + d=0; 4.624 + x87_dumpregs(); 4.625 + for (c = 0; c < 256; c++) 4.626 + { 4.627 + e = -1; 4.628 + for (d = 0; d < 256; d++) 4.629 + { 4.630 + if (inscounts[d] > e) 4.631 + { 4.632 + e = inscounts[d]; 4.633 + ff = d; 4.634 + } 4.635 + } 4.636 + inscounts[ff] = -1; 4.637 +// printf("Opcode %02x - %i\n", ff, e); 4.638 + } 4.639 +/* for (c=0;c<1024*1024;c++) 4.640 + { 4.641 + if (mmucache[c]!=0xFFFFFFFF) d++; 4.642 + } 4.643 + printf("Entries in MMU cache : %i\n",d);*/ 4.644 + indump = 0; 4.645 +} 4.646 + 4.647 +int resets = 0; 4.648 +void resetx86() 4.649 +{ 4.650 + pclog("x86 reset\n"); 4.651 + resets++; 4.652 + ins = 0; 4.653 + use32=0; 4.654 + stack32=0; 4.655 +// i86_Reset(); 4.656 +// cs=0xFFFF0; 4.657 + pc=0; 4.658 + msw=0; 4.659 + cr0=0; 4.660 + eflags=0; 4.661 + cgate32=0; 4.662 + loadcs(0xFFFF); 4.663 + rammask=0xFFFFFFFF; 4.664 + flags=2; 4.665 + initmmucache(); 4.666 + resetreadlookup(); 4.667 + makemod1table(); 4.668 + resetmcr(); 4.669 + FETCHCLEAR(); 4.670 + x87_reset(); 4.671 + cpu_set_edx(); 4.672 + ESP=0; 4.673 + mmu_perm=4; 4.674 + memset(inscounts, 0, sizeof(inscounts)); 4.675 +} 4.676 + 4.677 +void softresetx86() 4.678 +{ 4.679 +// dumpregs(); 4.680 +// exit(-1); 4.681 + use32=0; 4.682 + stack32=0; 4.683 +// i86_Reset(); 4.684 +// cs=0xFFFF0; 4.685 + pc=0; 4.686 + msw=0; 4.687 + cr0=0; 4.688 + eflags=0; 4.689 + cgate32=0; 4.690 + loadcs(0xFFFF); 4.691 + //rammask=0xFFFFFFFF; 4.692 + flags=2; 4.693 +} 4.694 + 4.695 +static void setznp8(uint8_t val) 4.696 +{ 4.697 + flags&=~0xC4; 4.698 + flags|=znptable8[val]; 4.699 +} 4.700 + 4.701 +static void setznp16(uint16_t val) 4.702 +{ 4.703 + flags&=~0xC4; 4.704 + flags|=znptable16[val]; 4.705 +} 4.706 + 4.707 +static void setadd8(uint8_t a, uint8_t b) 4.708 +{ 4.709 + uint16_t c=(uint16_t)a+(uint16_t)b; 4.710 + flags&=~0x8D5; 4.711 + flags|=znptable8[c&0xFF]; 4.712 + if (c&0x100) flags|=C_FLAG; 4.713 + if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; 4.714 + if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 4.715 +} 4.716 +static void setadd8nc(uint8_t a, uint8_t b) 4.717 +{ 4.718 + uint16_t c=(uint16_t)a+(uint16_t)b; 4.719 + flags&=~0x8D4; 4.720 + flags|=znptable8[c&0xFF]; 4.721 + if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; 4.722 + if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 4.723 +} 4.724 +static void setadc8(uint8_t a, uint8_t b) 4.725 +{ 4.726 + uint16_t c=(uint16_t)a+(uint16_t)b+tempc; 4.727 + flags&=~0x8D5; 4.728 + flags|=znptable8[c&0xFF]; 4.729 + if (c&0x100) flags|=C_FLAG; 4.730 + if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; 4.731 + if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 4.732 +} 4.733 +static void setadd16(uint16_t a, uint16_t b) 4.734 +{ 4.735 + uint32_t c=(uint32_t)a+(uint32_t)b; 4.736 + flags&=~0x8D5; 4.737 + flags|=znptable16[c&0xFFFF]; 4.738 + if (c&0x10000) flags|=C_FLAG; 4.739 + if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; 4.740 + if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 4.741 +} 4.742 +static void setadd16nc(uint16_t a, uint16_t b) 4.743 +{ 4.744 + uint32_t c=(uint32_t)a+(uint32_t)b; 4.745 + flags&=~0x8D4; 4.746 + flags|=znptable16[c&0xFFFF]; 4.747 + if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; 4.748 + if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 4.749 +} 4.750 +static void setadc16(uint16_t a, uint16_t b) 4.751 +{ 4.752 + uint32_t c=(uint32_t)a+(uint32_t)b+tempc; 4.753 + flags&=~0x8D5; 4.754 + flags|=znptable16[c&0xFFFF]; 4.755 + if (c&0x10000) flags|=C_FLAG; 4.756 + if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; 4.757 + if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 4.758 +} 4.759 + 4.760 +static void setsub8(uint8_t a, uint8_t b) 4.761 +{ 4.762 + uint16_t c=(uint16_t)a-(uint16_t)b; 4.763 + flags&=~0x8D5; 4.764 + flags|=znptable8[c&0xFF]; 4.765 + if (c&0x100) flags|=C_FLAG; 4.766 + if ((a^b)&(a^c)&0x80) flags|=V_FLAG; 4.767 + if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 4.768 +} 4.769 +static void setsub8nc(uint8_t a, uint8_t b) 4.770 +{ 4.771 + uint16_t c=(uint16_t)a-(uint16_t)b; 4.772 + flags&=~0x8D4; 4.773 + flags|=znptable8[c&0xFF]; 4.774 + if ((a^b)&(a^c)&0x80) flags|=V_FLAG; 4.775 + if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 4.776 +} 4.777 +static void setsbc8(uint8_t a, uint8_t b) 4.778 +{ 4.779 + uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc); 4.780 + flags&=~0x8D5; 4.781 + flags|=znptable8[c&0xFF]; 4.782 + if (c&0x100) flags|=C_FLAG; 4.783 + if ((a^b)&(a^c)&0x80) flags|=V_FLAG; 4.784 + if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 4.785 +} 4.786 +static void setsub16(uint16_t a, uint16_t b) 4.787 +{ 4.788 + uint32_t c=(uint32_t)a-(uint32_t)b; 4.789 + flags&=~0x8D5; 4.790 + flags|=znptable16[c&0xFFFF]; 4.791 + if (c&0x10000) flags|=C_FLAG; 4.792 + if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; 4.793 +// if (output) printf("%04X %04X %i\n",a^b,a^c,flags&V_FLAG); 4.794 + if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 4.795 +} 4.796 +static void setsub16nc(uint16_t a, uint16_t b) 4.797 +{ 4.798 + uint32_t c=(uint32_t)a-(uint32_t)b; 4.799 + flags&=~0x8D4; 4.800 + flags|=(znptable16[c&0xFFFF]&~4); 4.801 + flags|=(znptable8[c&0xFF]&4); 4.802 + if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; 4.803 + if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 4.804 +} 4.805 +static void setsbc16(uint16_t a, uint16_t b) 4.806 +{ 4.807 + uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); 4.808 + flags&=~0x8D5; 4.809 + flags|=(znptable16[c&0xFFFF]&~4); 4.810 + flags|=(znptable8[c&0xFF]&4); 4.811 + if (c&0x10000) flags|=C_FLAG; 4.812 + if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; 4.813 + if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 4.814 +} 4.815 + 4.816 +int totaldiff = 0; 4.817 +int current_diff = 0; 4.818 +void clockhardware() 4.819 +{ 4.820 + int diff = cycdiff - cycles - current_diff; 4.821 + 4.822 + current_diff += diff; 4.823 + totaldiff += diff; 4.824 + pit.c[0] -= diff; 4.825 + pit.c[1] -= diff; 4.826 + if (ppi.pb & 1) pit.c[2] -= diff; 4.827 + if ((pit.c[0] < 1) || (pit.c[1] < 1) || (pit.c[2] < 1)) pit_poll(); 4.828 + 4.829 + timer_clock(diff); 4.830 +} 4.831 + 4.832 + 4.833 +int firstrepcycle=1; 4.834 + 4.835 +void rep(int fv) 4.836 +{ 4.837 + uint8_t temp; 4.838 + int c=CX; 4.839 + uint8_t temp2; 4.840 + uint16_t tempw,tempw2; 4.841 + uint16_t ipc=oldpc;//pc-1; 4.842 + int changeds=0; 4.843 + uint32_t oldds; 4.844 + startrep: 4.845 + temp=FETCH(); 4.846 +// if (firstrepcycle && temp==0xA5) printf("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI); 4.847 +// if (output) printf("REP %02X %04X\n",temp,ipc); 4.848 + switch (temp) 4.849 + { 4.850 + case 0x08: 4.851 + pc=ipc+1; 4.852 + cycles-=2; 4.853 + FETCHCLEAR(); 4.854 + break; 4.855 + case 0x26: /*ES:*/ 4.856 + oldds=ds; 4.857 + ds=es; 4.858 + changeds=1; 4.859 + cycles-=2; 4.860 + goto startrep; 4.861 + break; 4.862 + case 0x2E: /*CS:*/ 4.863 + oldds=ds; 4.864 + ds=cs; 4.865 + changeds=1; 4.866 + cycles-=2; 4.867 + goto startrep; 4.868 + break; 4.869 + case 0x36: /*SS:*/ 4.870 + oldds=ds; 4.871 + ds=ss; 4.872 + changeds=1; 4.873 + cycles-=2; 4.874 + goto startrep; 4.875 + break; 4.876 + case 0x6E: /*REP OUTSB*/ 4.877 + if (c>0) 4.878 + { 4.879 + temp2=readmemb(ds+SI); 4.880 + outb(DX,temp2); 4.881 + if (flags&D_FLAG) SI--; 4.882 + else SI++; 4.883 + c--; 4.884 + cycles-=5; 4.885 + } 4.886 + if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 4.887 + else firstrepcycle=1; 4.888 + break; 4.889 + case 0xA4: /*REP MOVSB*/ 4.890 + while (c>0 && !IRQTEST) 4.891 + { 4.892 + temp2=readmemb(ds+SI); 4.893 + writememb(es+DI,temp2); 4.894 +// if (output) printf("Moved %02X from %04X:%04X to %04X:%04X\n",temp2,ds>>4,SI,es>>4,DI); 4.895 + if (flags&D_FLAG) { DI--; SI--; } 4.896 + else { DI++; SI++; } 4.897 + c--; 4.898 + cycles-=17; 4.899 + clockhardware(); 4.900 + FETCHADD(17-memcycs); 4.901 + } 4.902 + if (IRQTEST && c>0) pc=ipc; 4.903 +// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 4.904 +// else firstrepcycle=1; 4.905 +// } 4.906 + break; 4.907 + case 0xA5: /*REP MOVSW*/ 4.908 + while (c>0 && !IRQTEST) 4.909 + { 4.910 + memcycs=0; 4.911 + tempw=readmemw(ds,SI); 4.912 + writememw(es,DI,tempw); 4.913 + if (flags&D_FLAG) { DI-=2; SI-=2; } 4.914 + else { DI+=2; SI+=2; } 4.915 + c--; 4.916 + cycles-=17; 4.917 + clockhardware(); 4.918 + FETCHADD(17 - memcycs); 4.919 + } 4.920 + if (IRQTEST && c>0) pc=ipc; 4.921 +// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 4.922 +// else firstrepcycle=1; 4.923 +// } 4.924 + break; 4.925 + case 0xA6: /*REP CMPSB*/ 4.926 + if (fv) flags|=Z_FLAG; 4.927 + else flags&=~Z_FLAG; 4.928 + while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST) 4.929 + { 4.930 + memcycs=0; 4.931 + temp=readmemb(ds+SI); 4.932 + temp2=readmemb(es+DI); 4.933 +// printf("CMPSB %c %c %i %05X %05X %04X:%04X\n",temp,temp2,c,ds+SI,es+DI,cs>>4,pc); 4.934 + if (flags&D_FLAG) { DI--; SI--; } 4.935 + else { DI++; SI++; } 4.936 + c--; 4.937 + cycles -= 30; 4.938 + setsub8(temp,temp2); 4.939 + clockhardware(); 4.940 + FETCHADD(30 - memcycs); 4.941 + } 4.942 + if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) pc=ipc; 4.943 +// if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } 4.944 +// else firstrepcycle=1; 4.945 + break; 4.946 + case 0xA7: /*REP CMPSW*/ 4.947 + if (fv) flags|=Z_FLAG; 4.948 + else flags&=~Z_FLAG; 4.949 + while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST) 4.950 + { 4.951 + memcycs=0; 4.952 + tempw=readmemw(ds,SI); 4.953 + tempw2=readmemw(es,DI); 4.954 + if (flags&D_FLAG) { DI-=2; SI-=2; } 4.955 + else { DI+=2; SI+=2; } 4.956 + c--; 4.957 + cycles -= 30; 4.958 + setsub16(tempw,tempw2); 4.959 + clockhardware(); 4.960 + FETCHADD(30 - memcycs); 4.961 + } 4.962 + if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) pc=ipc; 4.963 +// if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } 4.964 +// else firstrepcycle=1; 4.965 +// if (firstrepcycle) printf("REP CMPSW %06X:%04X %06X:%04X %04X %04X\n",ds,SI,es,DI,tempw,tempw2); 4.966 + break; 4.967 + case 0xAA: /*REP STOSB*/ 4.968 + while (c>0 && !IRQTEST) 4.969 + { 4.970 + memcycs=0; 4.971 + writememb(es+DI,AL); 4.972 + if (flags&D_FLAG) DI--; 4.973 + else DI++; 4.974 + c--; 4.975 + cycles -= 10; 4.976 + clockhardware(); 4.977 + FETCHADD(10 - memcycs); 4.978 + } 4.979 + if (IRQTEST && c>0) pc=ipc; 4.980 +// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 4.981 +// else firstrepcycle=1; 4.982 + break; 4.983 + case 0xAB: /*REP STOSW*/ 4.984 + while (c>0 && !IRQTEST) 4.985 + { 4.986 + memcycs=0; 4.987 + writememw(es,DI,AX); 4.988 + if (flags&D_FLAG) DI-=2; 4.989 + else DI+=2; 4.990 + c--; 4.991 + cycles -= 10; 4.992 + clockhardware(); 4.993 + FETCHADD(10 - memcycs); 4.994 + } 4.995 + if (IRQTEST && c>0) pc=ipc; 4.996 +// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 4.997 +// else firstrepcycle=1; 4.998 + break; 4.999 + case 0xAC: /*REP LODSB*/ 4.1000 + if (c>0) 4.1001 + { 4.1002 + temp2=readmemb(ds+SI); 4.1003 + if (flags&D_FLAG) SI--; 4.1004 + else SI++; 4.1005 + c--; 4.1006 + cycles-=4; 4.1007 + } 4.1008 + if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 4.1009 + else firstrepcycle=1; 4.1010 + break; 4.1011 + case 0xAD: /*REP LODSW*/ 4.1012 + if (c>0) 4.1013 + { 4.1014 + tempw2=readmemw(ds,SI); 4.1015 + if (flags&D_FLAG) SI-=2; 4.1016 + else SI+=2; 4.1017 + c--; 4.1018 + cycles-=4; 4.1019 + } 4.1020 + if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 4.1021 + else firstrepcycle=1; 4.1022 + break; 4.1023 + case 0xAE: /*REP SCASB*/ 4.1024 + if (fv) flags|=Z_FLAG; 4.1025 + else flags&=~Z_FLAG; 4.1026 + if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 4.1027 + { 4.1028 + temp2=readmemb(es+DI); 4.1029 +// if (output) printf("SCASB %02X %c %02X %05X ",temp2,temp2,AL,es+DI); 4.1030 + setsub8(AL,temp2); 4.1031 +// if (output && flags&Z_FLAG) printf("Match %02X %02X\n",AL,temp2); 4.1032 + if (flags&D_FLAG) DI--; 4.1033 + else DI++; 4.1034 + c--; 4.1035 + cycles -= 15; 4.1036 + } 4.1037 +//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)))); 4.1038 + if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } 4.1039 + else firstrepcycle=1; 4.1040 +// cycles-=120; 4.1041 + break; 4.1042 + case 0xAF: /*REP SCASW*/ 4.1043 + if (fv) flags|=Z_FLAG; 4.1044 + else flags&=~Z_FLAG; 4.1045 + if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 4.1046 + { 4.1047 + tempw=readmemw(es,DI); 4.1048 + setsub16(AX,tempw); 4.1049 + if (flags&D_FLAG) DI-=2; 4.1050 + else DI+=2; 4.1051 + c--; 4.1052 + cycles -= 15; 4.1053 + } 4.1054 + if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } 4.1055 + else firstrepcycle=1; 4.1056 + break; 4.1057 + default: 4.1058 + pc=ipc; 4.1059 + cycles-=20; 4.1060 + FETCHCLEAR(); 4.1061 +// printf("Bad REP %02X\n",temp); 4.1062 +// dumpregs(); 4.1063 +// exit(-1); 4.1064 + } 4.1065 + CX=c; 4.1066 + if (changeds) ds=oldds; 4.1067 +// if (pc==ipc) FETCHCLEAR(); 4.1068 +} 4.1069 + 4.1070 + 4.1071 +int inhlt=0; 4.1072 +uint16_t lastpc,lastcs; 4.1073 +int firstrepcycle; 4.1074 +int skipnextprint=0; 4.1075 + 4.1076 + 4.1077 +int instime=0; 4.1078 +//#if 0 4.1079 +void execx86(int cycs) 4.1080 +{ 4.1081 + uint8_t temp,temp2; 4.1082 + uint16_t addr,tempw,tempw2,tempw3,tempw4; 4.1083 + int8_t offset; 4.1084 + int tempws; 4.1085 + uint32_t templ; 4.1086 + int c; 4.1087 + int tempi; 4.1088 + int trap; 4.1089 + 4.1090 +// printf("Run x86! %i %i\n",cycles,cycs); 4.1091 + cycles+=cycs; 4.1092 +// i86_Execute(cycs); 4.1093 +// return; 4.1094 + while (cycles>0) 4.1095 + { 4.1096 +// old83=old82; 4.1097 +// old82=old8; 4.1098 +// old8=oldpc|(oldcs<<16); 4.1099 +// if (pc==0x96B && cs==0x9E040) { printf("Hit it\n"); output=1; timetolive=150; } 4.1100 +// 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); 4.1101 + cycdiff=cycles; 4.1102 + current_diff = 0; 4.1103 + cycles-=nextcyc; 4.1104 +// if (instime) pclog("Cycles %i %i\n",cycles,cycdiff); 4.1105 + nextcyc=0; 4.1106 +// if (output) printf("CLOCK %i %i\n",cycdiff,cycles); 4.1107 + fetchclocks=0; 4.1108 + oldcs=CS; 4.1109 + oldpc=pc; 4.1110 + opcodestart: 4.1111 + opcode=FETCH(); 4.1112 + tempc=flags&C_FLAG; 4.1113 + trap=flags&T_FLAG; 4.1114 + pc--; 4.1115 +// output=1; 4.1116 +// 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); 4.1117 +//#if 0 4.1118 + if (output) 4.1119 + { 4.1120 +// if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle) 4.1121 +// { 4.1122 + if (!skipnextprint) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %02X %02X %02X %02X\n",cs,pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ram[0x413], ram[0x414], ram[0x415], ram[0x416]); 4.1123 + skipnextprint=0; 4.1124 +// ins++; 4.1125 +// } 4.1126 + } 4.1127 +//#endif 4.1128 + pc++; 4.1129 + inhlt=0; 4.1130 +// if (ins==500000) { dumpregs(); exit(0); }*/ 4.1131 + switch (opcode) 4.1132 + { 4.1133 + case 0x00: /*ADD 8,reg*/ 4.1134 + fetchea(); 4.1135 +/* if (!rmdat) pc--; 4.1136 + if (!rmdat) 4.1137 + { 4.1138 + fatal("Crashed\n"); 4.1139 +// clear_keybuf(); 4.1140 +// readkey(); 4.1141 + }*/ 4.1142 + temp=geteab(); 4.1143 + setadd8(temp,getr8(reg)); 4.1144 + temp+=getr8(reg); 4.1145 + seteab(temp); 4.1146 + cycles-=((mod==3)?3:24); 4.1147 + break; 4.1148 + case 0x01: /*ADD 16,reg*/ 4.1149 + fetchea(); 4.1150 + tempw=geteaw(); 4.1151 + setadd16(tempw,regs[reg].w); 4.1152 + tempw+=regs[reg].w; 4.1153 + seteaw(tempw); 4.1154 + cycles-=((mod==3)?3:24); 4.1155 + break; 4.1156 + case 0x02: /*ADD reg,8*/ 4.1157 + fetchea(); 4.1158 + temp=geteab(); 4.1159 + setadd8(getr8(reg),temp); 4.1160 + setr8(reg,getr8(reg)+temp); 4.1161 + cycles-=((mod==3)?3:13); 4.1162 + break; 4.1163 + case 0x03: /*ADD reg,16*/ 4.1164 + fetchea(); 4.1165 + tempw=geteaw(); 4.1166 + setadd16(regs[reg].w,tempw); 4.1167 + regs[reg].w+=tempw; 4.1168 + cycles-=((mod==3)?3:13); 4.1169 + break; 4.1170 + case 0x04: /*ADD AL,#8*/ 4.1171 + temp=FETCH(); 4.1172 + setadd8(AL,temp); 4.1173 + AL+=temp; 4.1174 + cycles-=4; 4.1175 + break; 4.1176 + case 0x05: /*ADD AX,#16*/ 4.1177 + tempw=getword(); 4.1178 + setadd16(AX,tempw); 4.1179 + AX+=tempw; 4.1180 + cycles-=4; 4.1181 + break; 4.1182 + 4.1183 + case 0x06: /*PUSH ES*/ 4.1184 + if (ssegs) ss=oldss; 4.1185 + writememw(ss,((SP-2)&0xFFFF),ES); 4.1186 + SP-=2; 4.1187 + cycles-=14; 4.1188 + break; 4.1189 + case 0x07: /*POP ES*/ 4.1190 + if (ssegs) ss=oldss; 4.1191 + tempw=readmemw(ss,SP); 4.1192 + loadseg(tempw,&_es); 4.1193 + SP+=2; 4.1194 + cycles-=12; 4.1195 + break; 4.1196 + 4.1197 + case 0x08: /*OR 8,reg*/ 4.1198 + fetchea(); 4.1199 + temp=geteab(); 4.1200 + temp|=getr8(reg); 4.1201 + setznp8(temp); 4.1202 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1203 + seteab(temp); 4.1204 + cycles-=((mod==3)?3:24); 4.1205 + break; 4.1206 + case 0x09: /*OR 16,reg*/ 4.1207 + fetchea(); 4.1208 + tempw=geteaw(); 4.1209 + tempw|=regs[reg].w; 4.1210 + setznp16(tempw); 4.1211 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1212 + seteaw(tempw); 4.1213 + cycles-=((mod==3)?3:24); 4.1214 + break; 4.1215 + case 0x0A: /*OR reg,8*/ 4.1216 + fetchea(); 4.1217 + temp=geteab(); 4.1218 + temp|=getr8(reg); 4.1219 + setznp8(temp); 4.1220 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1221 + setr8(reg,temp); 4.1222 + cycles-=((mod==3)?3:13); 4.1223 + break; 4.1224 + case 0x0B: /*OR reg,16*/ 4.1225 + fetchea(); 4.1226 + tempw=geteaw(); 4.1227 + tempw|=regs[reg].w; 4.1228 + setznp16(tempw); 4.1229 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1230 + regs[reg].w=tempw; 4.1231 + cycles-=((mod==3)?3:13); 4.1232 + break; 4.1233 + case 0x0C: /*OR AL,#8*/ 4.1234 + AL|=FETCH(); 4.1235 + setznp8(AL); 4.1236 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1237 + cycles-=4; 4.1238 + break; 4.1239 + case 0x0D: /*OR AX,#16*/ 4.1240 + AX|=getword(); 4.1241 + setznp16(AX); 4.1242 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1243 + cycles-=4; 4.1244 + break; 4.1245 + 4.1246 + case 0x0E: /*PUSH CS*/ 4.1247 + if (ssegs) ss=oldss; 4.1248 + writememw(ss,((SP-2)&0xFFFF),CS); 4.1249 + SP-=2; 4.1250 + cycles-=14; 4.1251 + break; 4.1252 + case 0x0F: /*POP CS - 8088/8086 only*/ 4.1253 + if (ssegs) ss=oldss; 4.1254 + tempw=readmemw(ss,SP); 4.1255 + loadseg(tempw,&_cs); 4.1256 + SP+=2; 4.1257 + cycles-=12; 4.1258 + break; 4.1259 + 4.1260 + case 0x10: /*ADC 8,reg*/ 4.1261 + fetchea(); 4.1262 + temp=geteab(); 4.1263 + temp2=getr8(reg); 4.1264 + setadc8(temp,temp2); 4.1265 + temp+=temp2+tempc; 4.1266 + seteab(temp); 4.1267 + cycles-=((mod==3)?3:24); 4.1268 + break; 4.1269 + case 0x11: /*ADC 16,reg*/ 4.1270 + fetchea(); 4.1271 + tempw=geteaw(); 4.1272 + tempw2=regs[reg].w; 4.1273 + setadc16(tempw,tempw2); 4.1274 + tempw+=tempw2+tempc; 4.1275 + seteaw(tempw); 4.1276 + cycles-=((mod==3)?3:24); 4.1277 + break; 4.1278 + case 0x12: /*ADC reg,8*/ 4.1279 + fetchea(); 4.1280 + temp=geteab(); 4.1281 + setadc8(getr8(reg),temp); 4.1282 + setr8(reg,getr8(reg)+temp+tempc); 4.1283 + cycles-=((mod==3)?3:13); 4.1284 + break; 4.1285 + case 0x13: /*ADC reg,16*/ 4.1286 + fetchea(); 4.1287 + tempw=geteaw(); 4.1288 + setadc16(regs[reg].w,tempw); 4.1289 + regs[reg].w+=tempw+tempc; 4.1290 + cycles-=((mod==3)?3:13); 4.1291 + break; 4.1292 + case 0x14: /*ADC AL,#8*/ 4.1293 + tempw=FETCH(); 4.1294 + setadc8(AL,tempw); 4.1295 + AL+=tempw+tempc; 4.1296 + cycles-=4; 4.1297 + break; 4.1298 + case 0x15: /*ADC AX,#16*/ 4.1299 + tempw=getword(); 4.1300 + setadc16(AX,tempw); 4.1301 + AX+=tempw+tempc; 4.1302 + cycles-=4; 4.1303 + break; 4.1304 + 4.1305 + case 0x16: /*PUSH SS*/ 4.1306 + if (ssegs) ss=oldss; 4.1307 + writememw(ss,((SP-2)&0xFFFF),SS); 4.1308 + SP-=2; 4.1309 + cycles-=14; 4.1310 + break; 4.1311 + case 0x17: /*POP SS*/ 4.1312 + if (ssegs) ss=oldss; 4.1313 + tempw=readmemw(ss,SP); 4.1314 + loadseg(tempw,&_ss); 4.1315 + SP+=2; 4.1316 + noint=1; 4.1317 + cycles-=12; 4.1318 +// output=1; 4.1319 + break; 4.1320 + 4.1321 + case 0x18: /*SBB 8,reg*/ 4.1322 + fetchea(); 4.1323 + temp=geteab(); 4.1324 + temp2=getr8(reg); 4.1325 + setsbc8(temp,temp2); 4.1326 + temp-=(temp2+tempc); 4.1327 + seteab(temp); 4.1328 + cycles-=((mod==3)?3:24); 4.1329 + break; 4.1330 + case 0x19: /*SBB 16,reg*/ 4.1331 + fetchea(); 4.1332 + tempw=geteaw(); 4.1333 + tempw2=regs[reg].w; 4.1334 +// printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc); 4.1335 + setsbc16(tempw,tempw2); 4.1336 + tempw-=(tempw2+tempc); 4.1337 + seteaw(tempw); 4.1338 + cycles-=((mod==3)?3:24); 4.1339 + break; 4.1340 + case 0x1A: /*SBB reg,8*/ 4.1341 + fetchea(); 4.1342 + temp=geteab(); 4.1343 + setsbc8(getr8(reg),temp); 4.1344 + setr8(reg,getr8(reg)-(temp+tempc)); 4.1345 + cycles-=((mod==3)?3:13); 4.1346 + break; 4.1347 + case 0x1B: /*SBB reg,16*/ 4.1348 + fetchea(); 4.1349 + tempw=geteaw(); 4.1350 + tempw2=regs[reg].w; 4.1351 +// printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc); 4.1352 + setsbc16(tempw2,tempw); 4.1353 + tempw2-=(tempw+tempc); 4.1354 + regs[reg].w=tempw2; 4.1355 + cycles-=((mod==3)?3:13); 4.1356 + break; 4.1357 + case 0x1C: /*SBB AL,#8*/ 4.1358 + temp=FETCH(); 4.1359 + setsbc8(AL,temp); 4.1360 + AL-=(temp+tempc); 4.1361 + cycles-=4; 4.1362 + break; 4.1363 + case 0x1D: /*SBB AX,#16*/ 4.1364 + tempw=getword(); 4.1365 + setsbc16(AX,tempw); 4.1366 + AX-=(tempw+tempc); 4.1367 + cycles-=4; 4.1368 + break; 4.1369 + 4.1370 + case 0x1E: /*PUSH DS*/ 4.1371 + if (ssegs) ss=oldss; 4.1372 + writememw(ss,((SP-2)&0xFFFF),DS); 4.1373 + SP-=2; 4.1374 + cycles-=14; 4.1375 + break; 4.1376 + case 0x1F: /*POP DS*/ 4.1377 + if (ssegs) ss=oldss; 4.1378 + tempw=readmemw(ss,SP); 4.1379 + loadseg(tempw,&_ds); 4.1380 + if (ssegs) oldds=ds; 4.1381 + SP+=2; 4.1382 + cycles-=12; 4.1383 + break; 4.1384 + 4.1385 + case 0x20: /*AND 8,reg*/ 4.1386 + fetchea(); 4.1387 + temp=geteab(); 4.1388 + temp&=getr8(reg); 4.1389 + setznp8(temp); 4.1390 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1391 + seteab(temp); 4.1392 + cycles-=((mod==3)?3:24); 4.1393 + break; 4.1394 + case 0x21: /*AND 16,reg*/ 4.1395 + fetchea(); 4.1396 + tempw=geteaw(); 4.1397 + tempw&=regs[reg].w; 4.1398 + setznp16(tempw); 4.1399 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1400 + seteaw(tempw); 4.1401 + cycles-=((mod==3)?3:24); 4.1402 + break; 4.1403 + case 0x22: /*AND reg,8*/ 4.1404 + fetchea(); 4.1405 + temp=geteab(); 4.1406 + temp&=getr8(reg); 4.1407 + setznp8(temp); 4.1408 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1409 + setr8(reg,temp); 4.1410 + cycles-=((mod==3)?3:13); 4.1411 + break; 4.1412 + case 0x23: /*AND reg,16*/ 4.1413 + fetchea(); 4.1414 + tempw=geteaw(); 4.1415 + tempw&=regs[reg].w; 4.1416 + setznp16(tempw); 4.1417 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1418 + regs[reg].w=tempw; 4.1419 + cycles-=((mod==3)?3:13); 4.1420 + break; 4.1421 + case 0x24: /*AND AL,#8*/ 4.1422 + AL&=FETCH(); 4.1423 + setznp8(AL); 4.1424 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1425 + cycles-=4; 4.1426 + break; 4.1427 + case 0x25: /*AND AX,#16*/ 4.1428 + AX&=getword(); 4.1429 + setznp16(AX); 4.1430 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1431 + cycles-=4; 4.1432 + break; 4.1433 + 4.1434 + case 0x26: /*ES:*/ 4.1435 + oldss=ss; 4.1436 + oldds=ds; 4.1437 + ds=ss=es; 4.1438 + ssegs=2; 4.1439 + cycles-=4; 4.1440 + goto opcodestart; 4.1441 +// break; 4.1442 + 4.1443 + case 0x27: /*DAA*/ 4.1444 + if ((flags&A_FLAG) || ((AL&0xF)>9)) 4.1445 + { 4.1446 + tempi=((uint16_t)AL)+6; 4.1447 + AL+=6; 4.1448 + flags|=A_FLAG; 4.1449 + if (tempi&0x100) flags|=C_FLAG; 4.1450 + } 4.1451 +// else 4.1452 +// flags&=~A_FLAG; 4.1453 + if ((flags&C_FLAG) || (AL>0x9F)) 4.1454 + { 4.1455 + AL+=0x60; 4.1456 + flags|=C_FLAG; 4.1457 + } 4.1458 +// else 4.1459 +// flags&=~C_FLAG; 4.1460 + setznp8(AL); 4.1461 + cycles-=4; 4.1462 + break; 4.1463 + 4.1464 + case 0x28: /*SUB 8,reg*/ 4.1465 + fetchea(); 4.1466 + temp=geteab(); 4.1467 + setsub8(temp,getr8(reg)); 4.1468 + temp-=getr8(reg); 4.1469 + seteab(temp); 4.1470 + cycles-=((mod==3)?3:24); 4.1471 + break; 4.1472 + case 0x29: /*SUB 16,reg*/ 4.1473 + fetchea(); 4.1474 + tempw=geteaw(); 4.1475 +// printf("%04X:%04X %04X-%04X\n",cs>>4,pc,tempw,regs[reg].w); 4.1476 + setsub16(tempw,regs[reg].w); 4.1477 + tempw-=regs[reg].w; 4.1478 + seteaw(tempw); 4.1479 + cycles-=((mod==3)?3:24); 4.1480 + break; 4.1481 + case 0x2A: /*SUB reg,8*/ 4.1482 + fetchea(); 4.1483 + temp=geteab(); 4.1484 + setsub8(getr8(reg),temp); 4.1485 + setr8(reg,getr8(reg)-temp); 4.1486 + cycles-=((mod==3)?3:13); 4.1487 + break; 4.1488 + case 0x2B: /*SUB reg,16*/ 4.1489 + fetchea(); 4.1490 + tempw=geteaw(); 4.1491 +// printf("%04X:%04X %04X-%04X\n",cs>>4,pc,regs[reg].w,tempw); 4.1492 + setsub16(regs[reg].w,tempw); 4.1493 + regs[reg].w-=tempw; 4.1494 + cycles-=((mod==3)?3:13); 4.1495 + break; 4.1496 + case 0x2C: /*SUB AL,#8*/ 4.1497 + temp=FETCH(); 4.1498 + setsub8(AL,temp); 4.1499 + AL-=temp; 4.1500 + cycles-=4; 4.1501 + break; 4.1502 + case 0x2D: /*SUB AX,#16*/ 4.1503 +// printf("INS %i\n",ins); 4.1504 +// output=1; 4.1505 + tempw=getword(); 4.1506 + setsub16(AX,tempw); 4.1507 + AX-=tempw; 4.1508 + cycles-=4; 4.1509 + break; 4.1510 + case 0x2E: /*CS:*/ 4.1511 + oldss=ss; 4.1512 + oldds=ds; 4.1513 + ds=ss=cs; 4.1514 + ssegs=2; 4.1515 + cycles-=4; 4.1516 + goto opcodestart; 4.1517 + case 0x2F: /*DAS*/ 4.1518 + if ((flags&A_FLAG)||((AL&0xF)>9)) 4.1519 + { 4.1520 + tempi=((uint16_t)AL)-6; 4.1521 + AL-=6; 4.1522 + flags|=A_FLAG; 4.1523 + if (tempi&0x100) flags|=C_FLAG; 4.1524 + } 4.1525 +// else 4.1526 +// flags&=~A_FLAG; 4.1527 + if ((flags&C_FLAG)||(AL>0x9F)) 4.1528 + { 4.1529 + AL-=0x60; 4.1530 + flags|=C_FLAG; 4.1531 + } 4.1532 +// else 4.1533 +// flags&=~C_FLAG; 4.1534 + setznp8(AL); 4.1535 + cycles-=4; 4.1536 + break; 4.1537 + case 0x30: /*XOR 8,reg*/ 4.1538 + fetchea(); 4.1539 + temp=geteab(); 4.1540 + temp^=getr8(reg); 4.1541 + setznp8(temp); 4.1542 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1543 + seteab(temp); 4.1544 + cycles-=((mod==3)?3:24); 4.1545 + break; 4.1546 + case 0x31: /*XOR 16,reg*/ 4.1547 + fetchea(); 4.1548 + tempw=geteaw(); 4.1549 + tempw^=regs[reg].w; 4.1550 + setznp16(tempw); 4.1551 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1552 + seteaw(tempw); 4.1553 + cycles-=((mod==3)?3:24); 4.1554 + break; 4.1555 + case 0x32: /*XOR reg,8*/ 4.1556 + fetchea(); 4.1557 + temp=geteab(); 4.1558 + temp^=getr8(reg); 4.1559 + setznp8(temp); 4.1560 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1561 + setr8(reg,temp); 4.1562 + cycles-=((mod==3)?3:13); 4.1563 + break; 4.1564 + case 0x33: /*XOR reg,16*/ 4.1565 + fetchea(); 4.1566 + tempw=geteaw(); 4.1567 + tempw^=regs[reg].w; 4.1568 + setznp16(tempw); 4.1569 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1570 + regs[reg].w=tempw; 4.1571 + cycles-=((mod==3)?3:13); 4.1572 + break; 4.1573 + case 0x34: /*XOR AL,#8*/ 4.1574 + AL^=FETCH(); 4.1575 + setznp8(AL); 4.1576 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1577 + cycles-=4; 4.1578 + break; 4.1579 + case 0x35: /*XOR AX,#16*/ 4.1580 + AX^=getword(); 4.1581 + setznp16(AX); 4.1582 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1583 + cycles-=4; 4.1584 + break; 4.1585 + 4.1586 + case 0x36: /*SS:*/ 4.1587 + oldss=ss; 4.1588 + oldds=ds; 4.1589 + ds=ss=ss; 4.1590 + ssegs=2; 4.1591 + cycles-=4; 4.1592 + goto opcodestart; 4.1593 +// break; 4.1594 + 4.1595 + case 0x37: /*AAA*/ 4.1596 + if ((flags&A_FLAG)||((AL&0xF)>9)) 4.1597 + { 4.1598 + AL+=6; 4.1599 + AH++; 4.1600 + flags|=(A_FLAG|C_FLAG); 4.1601 + } 4.1602 + else 4.1603 + flags&=~(A_FLAG|C_FLAG); 4.1604 + AL&=0xF; 4.1605 + cycles-=8; 4.1606 + break; 4.1607 + 4.1608 + case 0x38: /*CMP 8,reg*/ 4.1609 + fetchea(); 4.1610 + temp=geteab(); 4.1611 +// if (output) printf("CMP %02X-%02X\n",temp,getr8(reg)); 4.1612 + setsub8(temp,getr8(reg)); 4.1613 + cycles-=((mod==3)?3:13); 4.1614 + break; 4.1615 + case 0x39: /*CMP 16,reg*/ 4.1616 + fetchea(); 4.1617 + tempw=geteaw(); 4.1618 +// if (output) printf("CMP %04X-%04X\n",tempw,regs[reg].w); 4.1619 + setsub16(tempw,regs[reg].w); 4.1620 + cycles-=((mod==3)?3:13); 4.1621 + break; 4.1622 + case 0x3A: /*CMP reg,8*/ 4.1623 + fetchea(); 4.1624 + temp=geteab(); 4.1625 +// if (output) printf("CMP %02X-%02X\n",getr8(reg),temp); 4.1626 + setsub8(getr8(reg),temp); 4.1627 + cycles-=((mod==3)?3:13); 4.1628 + break; 4.1629 + case 0x3B: /*CMP reg,16*/ 4.1630 + fetchea(); 4.1631 + tempw=geteaw(); 4.1632 +// printf("CMP %04X-%04X\n",regs[reg].w,tempw); 4.1633 + setsub16(regs[reg].w,tempw); 4.1634 + cycles-=((mod==3)?3:13); 4.1635 + break; 4.1636 + case 0x3C: /*CMP AL,#8*/ 4.1637 + temp=FETCH(); 4.1638 + setsub8(AL,temp); 4.1639 + cycles-=4; 4.1640 + break; 4.1641 + case 0x3D: /*CMP AX,#16*/ 4.1642 + tempw=getword(); 4.1643 + setsub16(AX,tempw); 4.1644 + cycles-=4; 4.1645 + break; 4.1646 + 4.1647 + case 0x3E: /*DS:*/ 4.1648 + oldss=ss; 4.1649 + oldds=ds; 4.1650 + ds=ss=ds; 4.1651 + ssegs=2; 4.1652 + cycles-=4; 4.1653 + goto opcodestart; 4.1654 +// break; 4.1655 + 4.1656 + case 0x3F: /*AAS*/ 4.1657 + if ((flags&A_FLAG)||((AL&0xF)>9)) 4.1658 + { 4.1659 + AL-=6; 4.1660 + AH--; 4.1661 + flags|=(A_FLAG|C_FLAG); 4.1662 + } 4.1663 + else 4.1664 + flags&=~(A_FLAG|C_FLAG); 4.1665 + AL&=0xF; 4.1666 + cycles-=8; 4.1667 + break; 4.1668 + 4.1669 + case 0x40: case 0x41: case 0x42: case 0x43: /*INC r16*/ 4.1670 + case 0x44: case 0x45: case 0x46: case 0x47: 4.1671 + setadd16nc(regs[opcode&7].w,1); 4.1672 + regs[opcode&7].w++; 4.1673 + cycles-=3; 4.1674 + break; 4.1675 + case 0x48: case 0x49: case 0x4A: case 0x4B: /*DEC r16*/ 4.1676 + case 0x4C: case 0x4D: case 0x4E: case 0x4F: 4.1677 + setsub16nc(regs[opcode&7].w,1); 4.1678 + regs[opcode&7].w--; 4.1679 + cycles-=3; 4.1680 + break; 4.1681 + 4.1682 + case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/ 4.1683 + case 0x54: case 0x55: case 0x56: case 0x57: 4.1684 + if (ssegs) ss=oldss; 4.1685 + SP-=2; 4.1686 + writememw(ss,SP,regs[opcode&7].w); 4.1687 + cycles-=15; 4.1688 + break; 4.1689 + case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/ 4.1690 + case 0x5C: case 0x5D: case 0x5E: case 0x5F: 4.1691 + if (ssegs) ss=oldss; 4.1692 + SP+=2; 4.1693 + regs[opcode&7].w=readmemw(ss,(SP-2)&0xFFFF); 4.1694 + cycles-=12; 4.1695 + break; 4.1696 + 4.1697 + 4.1698 + case 0x70: /*JO*/ 4.1699 + offset=(int8_t)FETCH(); 4.1700 + if (flags&V_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1701 + cycles-=4; 4.1702 + break; 4.1703 + case 0x71: /*JNO*/ 4.1704 + offset=(int8_t)FETCH(); 4.1705 + if (!(flags&V_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1706 + cycles-=4; 4.1707 + break; 4.1708 + case 0x72: /*JB*/ 4.1709 + offset=(int8_t)FETCH(); 4.1710 + if (flags&C_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1711 + cycles-=4; 4.1712 + break; 4.1713 + case 0x73: /*JNB*/ 4.1714 + offset=(int8_t)FETCH(); 4.1715 + if (!(flags&C_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1716 + cycles-=4; 4.1717 + break; 4.1718 + case 0x74: /*JE*/ 4.1719 + offset=(int8_t)FETCH(); 4.1720 + if (flags&Z_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1721 + cycles-=4; 4.1722 + break; 4.1723 + case 0x75: /*JNE*/ 4.1724 + offset=(int8_t)FETCH(); 4.1725 + cycles-=4; 4.1726 + if (!(flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1727 + break; 4.1728 + case 0x76: /*JBE*/ 4.1729 + offset=(int8_t)FETCH(); 4.1730 + if (flags&(C_FLAG|Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1731 + cycles-=4; 4.1732 + break; 4.1733 + case 0x77: /*JNBE*/ 4.1734 + offset=(int8_t)FETCH(); 4.1735 + if (!(flags&(C_FLAG|Z_FLAG))) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1736 + cycles-=4; 4.1737 + break; 4.1738 + case 0x78: /*JS*/ 4.1739 + offset=(int8_t)FETCH(); 4.1740 + if (flags&N_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1741 + cycles-=4; 4.1742 + break; 4.1743 + case 0x79: /*JNS*/ 4.1744 + offset=(int8_t)FETCH(); 4.1745 + if (!(flags&N_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1746 + cycles-=4; 4.1747 + break; 4.1748 + case 0x7A: /*JP*/ 4.1749 + offset=(int8_t)FETCH(); 4.1750 + if (flags&P_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1751 + cycles-=4; 4.1752 + break; 4.1753 + case 0x7B: /*JNP*/ 4.1754 + offset=(int8_t)FETCH(); 4.1755 + if (!(flags&P_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1756 + cycles-=4; 4.1757 + break; 4.1758 + case 0x7C: /*JL*/ 4.1759 + offset=(int8_t)FETCH(); 4.1760 + temp=(flags&N_FLAG)?1:0; 4.1761 + temp2=(flags&V_FLAG)?1:0; 4.1762 + if (temp!=temp2) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1763 + cycles-=4; 4.1764 + break; 4.1765 + case 0x7D: /*JNL*/ 4.1766 + offset=(int8_t)FETCH(); 4.1767 + temp=(flags&N_FLAG)?1:0; 4.1768 + temp2=(flags&V_FLAG)?1:0; 4.1769 + if (temp==temp2) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1770 + cycles-=4; 4.1771 + break; 4.1772 + case 0x7E: /*JLE*/ 4.1773 + offset=(int8_t)FETCH(); 4.1774 + temp=(flags&N_FLAG)?1:0; 4.1775 + temp2=(flags&V_FLAG)?1:0; 4.1776 + if ((flags&Z_FLAG) || (temp!=temp2)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1777 + cycles-=4; 4.1778 + break; 4.1779 + case 0x7F: /*JNLE*/ 4.1780 + offset=(int8_t)FETCH(); 4.1781 + temp=(flags&N_FLAG)?1:0; 4.1782 + temp2=(flags&V_FLAG)?1:0; 4.1783 + if (!((flags&Z_FLAG) || (temp!=temp2))) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.1784 + cycles-=4; 4.1785 + break; 4.1786 + 4.1787 + case 0x80: case 0x82: 4.1788 + fetchea(); 4.1789 + temp=geteab(); 4.1790 + temp2=FETCH(); 4.1791 + switch (rmdat&0x38) 4.1792 + { 4.1793 + case 0x00: /*ADD b,#8*/ 4.1794 + setadd8(temp,temp2); 4.1795 + seteab(temp+temp2); 4.1796 + cycles-=((mod==3)?4:23); 4.1797 + break; 4.1798 + case 0x08: /*OR b,#8*/ 4.1799 + temp|=temp2; 4.1800 + setznp8(temp); 4.1801 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1802 + seteab(temp); 4.1803 + cycles-=((mod==3)?4:23); 4.1804 + break; 4.1805 + case 0x10: /*ADC b,#8*/ 4.1806 +// temp2+=(flags&C_FLAG); 4.1807 + setadc8(temp,temp2); 4.1808 + seteab(temp+temp2+tempc); 4.1809 + cycles-=((mod==3)?4:23); 4.1810 + break; 4.1811 + case 0x18: /*SBB b,#8*/ 4.1812 +// temp2+=(flags&C_FLAG); 4.1813 + setsbc8(temp,temp2); 4.1814 + seteab(temp-(temp2+tempc)); 4.1815 + cycles-=((mod==3)?4:23); 4.1816 + break; 4.1817 + case 0x20: /*AND b,#8*/ 4.1818 + temp&=temp2; 4.1819 + setznp8(temp); 4.1820 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1821 + seteab(temp); 4.1822 + cycles-=((mod==3)?4:23); 4.1823 + break; 4.1824 + case 0x28: /*SUB b,#8*/ 4.1825 + setsub8(temp,temp2); 4.1826 + seteab(temp-temp2); 4.1827 + cycles-=((mod==3)?4:23); 4.1828 + break; 4.1829 + case 0x30: /*XOR b,#8*/ 4.1830 + temp^=temp2; 4.1831 + setznp8(temp); 4.1832 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1833 + seteab(temp); 4.1834 + cycles-=((mod==3)?4:23); 4.1835 + break; 4.1836 + case 0x38: /*CMP b,#8*/ 4.1837 + setsub8(temp,temp2); 4.1838 + cycles-=((mod==3)?4:14); 4.1839 + break; 4.1840 + 4.1841 +// default: 4.1842 +// printf("Bad 80 opcode %02X\n",rmdat&0x38); 4.1843 +// dumpregs(); 4.1844 +// exit(-1); 4.1845 + } 4.1846 + break; 4.1847 + 4.1848 + case 0x81: 4.1849 + fetchea(); 4.1850 + tempw=geteaw(); 4.1851 + tempw2=getword(); 4.1852 + switch (rmdat&0x38) 4.1853 + { 4.1854 + case 0x00: /*ADD w,#16*/ 4.1855 + setadd16(tempw,tempw2); 4.1856 + tempw+=tempw2; 4.1857 + seteaw(tempw); 4.1858 + cycles-=((mod==3)?4:23); 4.1859 + break; 4.1860 + case 0x08: /*OR w,#16*/ 4.1861 + tempw|=tempw2; 4.1862 + setznp16(tempw); 4.1863 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1864 + seteaw(tempw); 4.1865 + cycles-=((mod==3)?4:23); 4.1866 + break; 4.1867 + case 0x10: /*ADC w,#16*/ 4.1868 +// tempw2+=(flags&C_FLAG); 4.1869 + setadc16(tempw,tempw2); 4.1870 + tempw+=tempw2+tempc; 4.1871 + seteaw(tempw); 4.1872 + cycles-=((mod==3)?4:23); 4.1873 + break; 4.1874 + case 0x20: /*AND w,#16*/ 4.1875 + tempw&=tempw2; 4.1876 + setznp16(tempw); 4.1877 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1878 + seteaw(tempw); 4.1879 + cycles-=((mod==3)?4:23); 4.1880 + break; 4.1881 + case 0x18: /*SBB w,#16*/ 4.1882 +// tempw2+=(flags&C_FLAG); 4.1883 + setsbc16(tempw,tempw2); 4.1884 + seteaw(tempw-(tempw2+tempc)); 4.1885 + cycles-=((mod==3)?4:23); 4.1886 + break; 4.1887 + case 0x28: /*SUB w,#16*/ 4.1888 + setsub16(tempw,tempw2); 4.1889 + tempw-=tempw2; 4.1890 + seteaw(tempw); 4.1891 + cycles-=((mod==3)?4:23); 4.1892 + break; 4.1893 + case 0x30: /*XOR w,#16*/ 4.1894 + tempw^=tempw2; 4.1895 + setznp16(tempw); 4.1896 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1897 + seteaw(tempw); 4.1898 + cycles-=((mod==3)?4:23); 4.1899 + break; 4.1900 + case 0x38: /*CMP w,#16*/ 4.1901 +// printf("CMP %04X %04X\n",tempw,tempw2); 4.1902 + setsub16(tempw,tempw2); 4.1903 + cycles-=((mod==3)?4:14); 4.1904 + break; 4.1905 + 4.1906 +// default: 4.1907 +// printf("Bad 81 opcode %02X\n",rmdat&0x38); 4.1908 +// dumpregs(); 4.1909 +// exit(-1); 4.1910 + } 4.1911 + break; 4.1912 + 4.1913 + case 0x83: 4.1914 + fetchea(); 4.1915 + tempw=geteaw(); 4.1916 + tempw2=FETCH(); 4.1917 + if (tempw2&0x80) tempw2|=0xFF00; 4.1918 + switch (rmdat&0x38) 4.1919 + { 4.1920 + case 0x00: /*ADD w,#8*/ 4.1921 + setadd16(tempw,tempw2); 4.1922 + tempw+=tempw2; 4.1923 + seteaw(tempw); 4.1924 + cycles-=((mod==3)?4:23); 4.1925 + break; 4.1926 + case 0x08: /*OR w,#8*/ 4.1927 + tempw|=tempw2; 4.1928 + setznp16(tempw); 4.1929 + seteaw(tempw); 4.1930 + flags&=~(C_FLAG|A_FLAG|V_FLAG); 4.1931 + cycles-=((mod==3)?4:23); 4.1932 + break; 4.1933 + case 0x10: /*ADC w,#8*/ 4.1934 +// tempw2+=(flags&C_FLAG); 4.1935 + setadc16(tempw,tempw2); 4.1936 + tempw+=tempw2+tempc; 4.1937 + seteaw(tempw); 4.1938 + cycles-=((mod==3)?4:23); 4.1939 + break; 4.1940 + case 0x18: /*SBB w,#8*/ 4.1941 +// tempw2+=(flags&C_FLAG); 4.1942 + setsbc16(tempw,tempw2); 4.1943 + tempw-=(tempw2+tempc); 4.1944 + seteaw(tempw); 4.1945 + cycles-=((mod==3)?4:23); 4.1946 + break; 4.1947 + case 0x20: /*AND w,#8*/ 4.1948 + tempw&=tempw2; 4.1949 + setznp16(tempw); 4.1950 + seteaw(tempw); 4.1951 + cycles-=((mod==3)?4:23); 4.1952 + flags&=~(C_FLAG|A_FLAG|V_FLAG); 4.1953 + break; 4.1954 + case 0x28: /*SUB w,#8*/ 4.1955 + setsub16(tempw,tempw2); 4.1956 + tempw-=tempw2; 4.1957 + seteaw(tempw); 4.1958 + cycles-=((mod==3)?4:23); 4.1959 + break; 4.1960 + case 0x30: /*XOR w,#8*/ 4.1961 + tempw^=tempw2; 4.1962 + setznp16(tempw); 4.1963 + seteaw(tempw); 4.1964 + cycles-=((mod==3)?4:23); 4.1965 + flags&=~(C_FLAG|A_FLAG|V_FLAG); 4.1966 + break; 4.1967 + case 0x38: /*CMP w,#8*/ 4.1968 + setsub16(tempw,tempw2); 4.1969 + cycles-=((mod==3)?4:14); 4.1970 + break; 4.1971 + 4.1972 +// default: 4.1973 +// printf("Bad 83 opcode %02X\n",rmdat&0x38); 4.1974 +// dumpregs(); 4.1975 +// exit(-1); 4.1976 + } 4.1977 + break; 4.1978 + 4.1979 + case 0x84: /*TEST b,reg*/ 4.1980 + fetchea(); 4.1981 + temp=geteab(); 4.1982 + temp2=getr8(reg); 4.1983 + setznp8(temp&temp2); 4.1984 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1985 + cycles-=((mod==3)?3:13); 4.1986 + break; 4.1987 + case 0x85: /*TEST w,reg*/ 4.1988 + fetchea(); 4.1989 + tempw=geteaw(); 4.1990 + tempw2=regs[reg].w; 4.1991 + setznp16(tempw&tempw2); 4.1992 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.1993 + cycles-=((mod==3)?3:13); 4.1994 + break; 4.1995 + case 0x86: /*XCHG b,reg*/ 4.1996 + fetchea(); 4.1997 + temp=geteab(); 4.1998 + seteab(getr8(reg)); 4.1999 + setr8(reg,temp); 4.2000 + cycles-=((mod==3)?4:25); 4.2001 + break; 4.2002 + case 0x87: /*XCHG w,reg*/ 4.2003 + fetchea(); 4.2004 + tempw=geteaw(); 4.2005 + seteaw(regs[reg].w); 4.2006 + regs[reg].w=tempw; 4.2007 + cycles-=((mod==3)?4:25); 4.2008 + break; 4.2009 + 4.2010 + case 0x88: /*MOV b,reg*/ 4.2011 + fetchea(); 4.2012 + seteab(getr8(reg)); 4.2013 + cycles-=((mod==3)?2:13); 4.2014 + break; 4.2015 + case 0x89: /*MOV w,reg*/ 4.2016 + fetchea(); 4.2017 + seteaw(regs[reg].w); 4.2018 + cycles-=((mod==3)?2:13); 4.2019 + break; 4.2020 + case 0x8A: /*MOV reg,b*/ 4.2021 + fetchea(); 4.2022 + temp=geteab(); 4.2023 + setr8(reg,temp); 4.2024 + cycles-=((mod==3)?2:12); 4.2025 + break; 4.2026 + case 0x8B: /*MOV reg,w*/ 4.2027 + fetchea(); 4.2028 + tempw=geteaw(); 4.2029 + regs[reg].w=tempw; 4.2030 + cycles-=((mod==3)?2:12); 4.2031 + break; 4.2032 + 4.2033 + case 0x8C: /*MOV w,sreg*/ 4.2034 + fetchea(); 4.2035 + switch (rmdat&0x38) 4.2036 + { 4.2037 + case 0x00: /*ES*/ 4.2038 + seteaw(ES); 4.2039 + break; 4.2040 + case 0x08: /*CS*/ 4.2041 + seteaw(CS); 4.2042 + break; 4.2043 + case 0x18: /*DS*/ 4.2044 + if (ssegs) ds=oldds; 4.2045 + seteaw(DS); 4.2046 + break; 4.2047 + case 0x10: /*SS*/ 4.2048 + if (ssegs) ss=oldss; 4.2049 + seteaw(SS); 4.2050 + break; 4.2051 + } 4.2052 + cycles-=((mod==3)?2:13); 4.2053 + break; 4.2054 + 4.2055 + case 0x8D: /*LEA*/ 4.2056 + fetchea(); 4.2057 + regs[reg].w=eaaddr; 4.2058 + cycles-=2; 4.2059 + break; 4.2060 + 4.2061 + case 0x8E: /*MOV sreg,w*/ 4.2062 +// if (output) printf("MOV %04X ",pc); 4.2063 + fetchea(); 4.2064 +// if (output) printf("%04X %02X\n",pc,rmdat); 4.2065 + switch (rmdat&0x38) 4.2066 + { 4.2067 + case 0x00: /*ES*/ 4.2068 + tempw=geteaw(); 4.2069 + loadseg(tempw,&_es); 4.2070 + break; 4.2071 + case 0x08: /*CS - 8088/8086 only*/ 4.2072 + tempw=geteaw(); 4.2073 + loadseg(tempw,&_cs); 4.2074 + break; 4.2075 + case 0x18: /*DS*/ 4.2076 + tempw=geteaw(); 4.2077 + loadseg(tempw,&_ds); 4.2078 + if (ssegs) oldds=ds; 4.2079 + break; 4.2080 + case 0x10: /*SS*/ 4.2081 + tempw=geteaw(); 4.2082 + loadseg(tempw,&_ss); 4.2083 + if (ssegs) oldss=ss; 4.2084 +// printf("LOAD SS %04X %04X\n",tempw,SS); 4.2085 +// printf("SS loaded with %04X %04X:%04X %04X %04X %04X\n",ss>>4,cs>>4,pc,CX,DX,es>>4); 4.2086 + break; 4.2087 + } 4.2088 + cycles-=((mod==3)?2:12); 4.2089 + skipnextprint=1; 4.2090 + noint=1; 4.2091 + break; 4.2092 + 4.2093 + case 0x8F: /*POPW*/ 4.2094 + fetchea(); 4.2095 + if (ssegs) ss=oldss; 4.2096 + tempw=readmemw(ss,SP); 4.2097 + SP+=2; 4.2098 + seteaw(tempw); 4.2099 + cycles-=25; 4.2100 + break; 4.2101 + 4.2102 + case 0x90: /*NOP*/ 4.2103 + cycles-=3; 4.2104 + break; 4.2105 + 4.2106 + case 0x91: case 0x92: case 0x93: /*XCHG AX*/ 4.2107 + case 0x94: case 0x95: case 0x96: case 0x97: 4.2108 + tempw=AX; 4.2109 + AX=regs[opcode&7].w; 4.2110 + regs[opcode&7].w=tempw; 4.2111 + cycles-=3; 4.2112 + break; 4.2113 + 4.2114 + case 0x98: /*CBW*/ 4.2115 + AH=(AL&0x80)?0xFF:0; 4.2116 + cycles-=2; 4.2117 + break; 4.2118 + case 0x99: /*CWD*/ 4.2119 + DX=(AX&0x8000)?0xFFFF:0; 4.2120 + cycles-=5; 4.2121 + break; 4.2122 + case 0x9A: /*CALL FAR*/ 4.2123 + tempw=getword(); 4.2124 + tempw2=getword(); 4.2125 + tempw3=CS; 4.2126 + tempw4=pc; 4.2127 + if (ssegs) ss=oldss; 4.2128 + pc=tempw; 4.2129 +// printf("0x9a"); 4.2130 + loadcs(tempw2); 4.2131 + writememw(ss,(SP-2)&0xFFFF,tempw3); 4.2132 + writememw(ss,(SP-4)&0xFFFF,tempw4); 4.2133 + SP-=4; 4.2134 + cycles-=36; 4.2135 + FETCHCLEAR(); 4.2136 + break; 4.2137 + case 0x9B: /*WAIT*/ 4.2138 + cycles-=4; 4.2139 + break; 4.2140 + case 0x9C: /*PUSHF*/ 4.2141 + if (ssegs) ss=oldss; 4.2142 + writememw(ss,((SP-2)&0xFFFF),flags|0xF000); 4.2143 + SP-=2; 4.2144 + cycles-=14; 4.2145 + break; 4.2146 + case 0x9D: /*POPF*/ 4.2147 + if (ssegs) ss=oldss; 4.2148 + flags=readmemw(ss,SP)&0xFFF; 4.2149 + SP+=2; 4.2150 + cycles-=12; 4.2151 + break; 4.2152 + case 0x9E: /*SAHF*/ 4.2153 + flags=(flags&0xFF00)|AH; 4.2154 + cycles-=4; 4.2155 + break; 4.2156 + case 0x9F: /*LAHF*/ 4.2157 + AH=flags&0xFF; 4.2158 + cycles-=4; 4.2159 + break; 4.2160 + 4.2161 + case 0xA0: /*MOV AL,(w)*/ 4.2162 + addr=getword(); 4.2163 + AL=readmemb(ds+addr); 4.2164 + cycles-=14; 4.2165 + break; 4.2166 + case 0xA1: /*MOV AX,(w)*/ 4.2167 + addr=getword(); 4.2168 +// printf("Reading AX from %05X %04X:%04X\n",ds+addr,ds>>4,addr); 4.2169 + AX=readmemw(ds,addr); 4.2170 + cycles-=!4; 4.2171 + break; 4.2172 + case 0xA2: /*MOV (w),AL*/ 4.2173 + addr=getword(); 4.2174 + writememb(ds+addr,AL); 4.2175 + cycles-=14; 4.2176 + break; 4.2177 + case 0xA3: /*MOV (w),AX*/ 4.2178 + addr=getword(); 4.2179 +// if (!addr) printf("Write !addr %04X:%04X\n",cs>>4,pc); 4.2180 + writememw(ds,addr,AX); 4.2181 + cycles-=14; 4.2182 + break; 4.2183 + 4.2184 + case 0xA4: /*MOVSB*/ 4.2185 + temp=readmemb(ds+SI); 4.2186 + writememb(es+DI,temp); 4.2187 + if (flags&D_FLAG) { DI--; SI--; } 4.2188 + else { DI++; SI++; } 4.2189 + cycles-=18; 4.2190 + break; 4.2191 + case 0xA5: /*MOVSW*/ 4.2192 + tempw=readmemw(ds,SI); 4.2193 + writememw(es,DI,tempw); 4.2194 + if (flags&D_FLAG) { DI-=2; SI-=2; } 4.2195 + else { DI+=2; SI+=2; } 4.2196 + cycles-=18; 4.2197 + break; 4.2198 + case 0xA6: /*CMPSB*/ 4.2199 + temp =readmemb(ds+SI); 4.2200 + temp2=readmemb(es+DI); 4.2201 + setsub8(temp,temp2); 4.2202 + if (flags&D_FLAG) { DI--; SI--; } 4.2203 + else { DI++; SI++; } 4.2204 + cycles-=30; 4.2205 + break; 4.2206 + case 0xA7: /*CMPSW*/ 4.2207 + tempw =readmemw(ds,SI); 4.2208 + tempw2=readmemw(es,DI); 4.2209 +// printf("CMPSW %04X %04X\n",tempw,tempw2); 4.2210 + setsub16(tempw,tempw2); 4.2211 + if (flags&D_FLAG) { DI-=2; SI-=2; } 4.2212 + else { DI+=2; SI+=2; } 4.2213 + cycles-=30; 4.2214 + break; 4.2215 + case 0xA8: /*TEST AL,#8*/ 4.2216 + temp=FETCH(); 4.2217 + setznp8(AL&temp); 4.2218 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.2219 + cycles-=5; 4.2220 + break; 4.2221 + case 0xA9: /*TEST AX,#16*/ 4.2222 + tempw=getword(); 4.2223 + setznp16(AX&tempw); 4.2224 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.2225 + cycles-=5; 4.2226 + break; 4.2227 + case 0xAA: /*STOSB*/ 4.2228 + writememb(es+DI,AL); 4.2229 + if (flags&D_FLAG) DI--; 4.2230 + else DI++; 4.2231 + cycles-=11; 4.2232 + break; 4.2233 + case 0xAB: /*STOSW*/ 4.2234 + writememw(es,DI,AX); 4.2235 + if (flags&D_FLAG) DI-=2; 4.2236 + else DI+=2; 4.2237 + cycles-=11; 4.2238 + break; 4.2239 + case 0xAC: /*LODSB*/ 4.2240 + AL=readmemb(ds+SI); 4.2241 +// printf("LODSB %04X:%04X %02X %04X:%04X\n",cs>>4,pc,AL,ds>>4,SI); 4.2242 + if (flags&D_FLAG) SI--; 4.2243 + else SI++; 4.2244 + cycles-=16; 4.2245 + break; 4.2246 + case 0xAD: /*LODSW*/ 4.2247 +// if (times) printf("LODSW %04X:%04X\n",cs>>4,pc); 4.2248 + AX=readmemw(ds,SI); 4.2249 + if (flags&D_FLAG) SI-=2; 4.2250 + else SI+=2; 4.2251 + cycles-=16; 4.2252 + break; 4.2253 + case 0xAE: /*SCASB*/ 4.2254 + temp=readmemb(es+DI); 4.2255 + setsub8(AL,temp); 4.2256 + if (flags&D_FLAG) DI--; 4.2257 + else DI++; 4.2258 + cycles-=19; 4.2259 + break; 4.2260 + case 0xAF: /*SCASW*/ 4.2261 + tempw=readmemw(es,DI); 4.2262 + setsub16(AX,tempw); 4.2263 + if (flags&D_FLAG) DI-=2; 4.2264 + else DI+=2; 4.2265 + cycles-=19; 4.2266 + break; 4.2267 + 4.2268 + case 0xB0: /*MOV AL,#8*/ 4.2269 + AL=FETCH(); 4.2270 + cycles-=4; 4.2271 + break; 4.2272 + case 0xB1: /*MOV CL,#8*/ 4.2273 + CL=FETCH(); 4.2274 + cycles-=4; 4.2275 + break; 4.2276 + case 0xB2: /*MOV DL,#8*/ 4.2277 + DL=FETCH(); 4.2278 + cycles-=4; 4.2279 + break; 4.2280 + case 0xB3: /*MOV BL,#8*/ 4.2281 + BL=FETCH(); 4.2282 + cycles-=4; 4.2283 + break; 4.2284 + case 0xB4: /*MOV AH,#8*/ 4.2285 + AH=FETCH(); 4.2286 + cycles-=4; 4.2287 + break; 4.2288 + case 0xB5: /*MOV CH,#8*/ 4.2289 + CH=FETCH(); 4.2290 + cycles-=4; 4.2291 + break; 4.2292 + case 0xB6: /*MOV DH,#8*/ 4.2293 + DH=FETCH(); 4.2294 + cycles-=4; 4.2295 + break; 4.2296 + case 0xB7: /*MOV BH,#8*/ 4.2297 + BH=FETCH(); 4.2298 + cycles-=4; 4.2299 + break; 4.2300 + case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV reg,#16*/ 4.2301 + case 0xBC: case 0xBD: case 0xBE: case 0xBF: 4.2302 + regs[opcode&7].w=getword(); 4.2303 + cycles-=4; 4.2304 + break; 4.2305 + 4.2306 + case 0xC2: /*RET*/ 4.2307 + tempw=getword(); 4.2308 + if (ssegs) ss=oldss; 4.2309 + pc=readmemw(ss,SP); 4.2310 +// printf("C2\n"); 4.2311 +// printf("RET to %04X\n",pc); 4.2312 + SP+=2+tempw; 4.2313 + cycles-=24; 4.2314 + FETCHCLEAR(); 4.2315 + break; 4.2316 + case 0xC3: /*RET*/ 4.2317 + if (ssegs) ss=oldss; 4.2318 + pc=readmemw(ss,SP); 4.2319 +// printf("C3\n"); 4.2320 +// if (output) printf("RET to %04X %05X\n",pc,ss+SP); 4.2321 + SP+=2; 4.2322 + cycles-=20; 4.2323 + FETCHCLEAR(); 4.2324 + break; 4.2325 + case 0xC4: /*LES*/ 4.2326 + fetchea(); 4.2327 + regs[reg].w=readmemw(easeg,eaaddr); //geteaw(); 4.2328 + tempw=readmemw(easeg,(eaaddr+2)&0xFFFF); //geteaw2(); 4.2329 + loadseg(tempw,&_es); 4.2330 + cycles-=24; 4.2331 + break; 4.2332 + case 0xC5: /*LDS*/ 4.2333 + fetchea(); 4.2334 + regs[reg].w=readmemw(easeg,eaaddr); 4.2335 + tempw=readmemw(easeg,(eaaddr+2)&0xFFFF); 4.2336 + loadseg(tempw,&_ds); 4.2337 + if (ssegs) oldds=ds; 4.2338 + cycles-=24; 4.2339 + break; 4.2340 + case 0xC6: /*MOV b,#8*/ 4.2341 + fetchea(); 4.2342 + temp=FETCH(); 4.2343 + seteab(temp); 4.2344 + cycles-=((mod==3)?4:14); 4.2345 + break; 4.2346 + case 0xC7: /*MOV w,#16*/ 4.2347 + fetchea(); 4.2348 + tempw=getword(); 4.2349 + seteaw(tempw); 4.2350 + cycles-=((mod==3)?4:14); 4.2351 + break; 4.2352 + 4.2353 + case 0xCA: /*RETF*/ 4.2354 + tempw=getword(); 4.2355 + if (ssegs) ss=oldss; 4.2356 + pc=readmemw(ss,SP); 4.2357 +// printf("CA\n"); 4.2358 + loadcs(readmemw(ss,SP+2)); 4.2359 + SP+=4; 4.2360 + SP+=tempw; 4.2361 + cycles-=33; 4.2362 + FETCHCLEAR(); 4.2363 + break; 4.2364 + case 0xCB: /*RETF*/ 4.2365 + if (ssegs) ss=oldss; 4.2366 + pc=readmemw(ss,SP); 4.2367 +// printf("CB\n"); 4.2368 + loadcs(readmemw(ss,SP+2)); 4.2369 + SP+=4; 4.2370 + cycles-=34; 4.2371 + FETCHCLEAR(); 4.2372 + break; 4.2373 + case 0xCC: /*INT 3*/ 4.2374 + if (ssegs) ss=oldss; 4.2375 + writememw(ss,((SP-2)&0xFFFF),flags|0xF000); 4.2376 + writememw(ss,((SP-4)&0xFFFF),CS); 4.2377 + writememw(ss,((SP-6)&0xFFFF),pc); 4.2378 + SP-=6; 4.2379 + addr=3<<2; 4.2380 + flags&=~I_FLAG; 4.2381 + flags&=~T_FLAG; 4.2382 +// printf("CC %04X:%04X ",CS,pc); 4.2383 + pc=readmemw(0,addr); 4.2384 + loadcs(readmemw(0,addr+2)); 4.2385 + FETCHCLEAR(); 4.2386 +// printf("%04X:%04X\n",CS,pc); 4.2387 + cycles-=72; 4.2388 + break; 4.2389 + case 0xCD: /*INT*/ 4.2390 + lastpc=pc; 4.2391 + lastcs=CS; 4.2392 + temp=FETCH(); 4.2393 + 4.2394 + if (ssegs) ss=oldss; 4.2395 + writememw(ss,((SP-2)&0xFFFF),flags|0xF000); 4.2396 + writememw(ss,((SP-4)&0xFFFF),CS); 4.2397 + writememw(ss,((SP-6)&0xFFFF),pc); 4.2398 + flags&=~T_FLAG; 4.2399 + SP-=6; 4.2400 + addr=temp<<2; 4.2401 + pc=readmemw(0,addr); 4.2402 + 4.2403 + loadcs(readmemw(0,addr+2)); 4.2404 + FETCHCLEAR(); 4.2405 + 4.2406 + cycles-=71; 4.2407 + break; 4.2408 + case 0xCF: /*IRET*/ 4.2409 + if (ssegs) ss=oldss; 4.2410 + tempw=CS; 4.2411 + tempw2=pc; 4.2412 + pc=readmemw(ss,SP); 4.2413 +// printf("CF\n"); 4.2414 + loadcs(readmemw(ss,((SP+2)&0xFFFF))); 4.2415 + flags=readmemw(ss,((SP+4)&0xFFFF))&0xFFF; 4.2416 + SP+=6; 4.2417 + cycles-=44; 4.2418 + FETCHCLEAR(); 4.2419 + break; 4.2420 + case 0xD0: 4.2421 + fetchea(); 4.2422 + temp=geteab(); 4.2423 + switch (rmdat&0x38) 4.2424 + { 4.2425 + case 0x00: /*ROL b,1*/ 4.2426 + if (temp&0x80) flags|=C_FLAG; 4.2427 + else flags&=~C_FLAG; 4.2428 + temp<<=1; 4.2429 + if (flags&C_FLAG) temp|=1; 4.2430 + seteab(temp); 4.2431 +// setznp8(temp); 4.2432 + if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 4.2433 + else flags&=~V_FLAG; 4.2434 + cycles-=((mod==3)?2:23); 4.2435 + break; 4.2436 + case 0x08: /*ROR b,1*/ 4.2437 + if (temp&1) flags|=C_FLAG; 4.2438 + else flags&=~C_FLAG; 4.2439 + temp>>=1; 4.2440 + if (flags&C_FLAG) temp|=0x80; 4.2441 + seteab(temp); 4.2442 +// setznp8(temp); 4.2443 + if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 4.2444 + else flags&=~V_FLAG; 4.2445 + cycles-=((mod==3)?2:23); 4.2446 + break; 4.2447 + case 0x10: /*RCL b,1*/ 4.2448 + temp2=flags&C_FLAG; 4.2449 + if (temp&0x80) flags|=C_FLAG; 4.2450 + else flags&=~C_FLAG; 4.2451 + temp<<=1; 4.2452 + if (temp2) temp|=1; 4.2453 + seteab(temp); 4.2454 +// setznp8(temp); 4.2455 + if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 4.2456 + else flags&=~V_FLAG; 4.2457 + cycles-=((mod==3)?2:23); 4.2458 + break; 4.2459 + case 0x18: /*RCR b,1*/ 4.2460 + temp2=flags&C_FLAG; 4.2461 + if (temp&1) flags|=C_FLAG; 4.2462 + else flags&=~C_FLAG; 4.2463 + temp>>=1; 4.2464 + if (temp2) temp|=0x80; 4.2465 + seteab(temp); 4.2466 +// setznp8(temp); 4.2467 + if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 4.2468 + else flags&=~V_FLAG; 4.2469 + cycles-=((mod==3)?2:23); 4.2470 + break; 4.2471 + case 0x20: case 0x30: /*SHL b,1*/ 4.2472 + if (temp&0x80) flags|=C_FLAG; 4.2473 + else flags&=~C_FLAG; 4.2474 + if ((temp^(temp<<1))&0x80) flags|=V_FLAG; 4.2475 + else flags&=~V_FLAG; 4.2476 + temp<<=1; 4.2477 + seteab(temp); 4.2478 + setznp8(temp); 4.2479 + cycles-=((mod==3)?2:23); 4.2480 + flags|=A_FLAG; 4.2481 + break; 4.2482 + case 0x28: /*SHR b,1*/ 4.2483 + if (temp&1) flags|=C_FLAG; 4.2484 + else flags&=~C_FLAG; 4.2485 + if (temp&0x80) flags|=V_FLAG; 4.2486 + else flags&=~V_FLAG; 4.2487 + temp>>=1; 4.2488 + seteab(temp); 4.2489 + setznp8(temp); 4.2490 + cycles-=((mod==3)?2:23); 4.2491 + flags|=A_FLAG; 4.2492 + break; 4.2493 + case 0x38: /*SAR b,1*/ 4.2494 + if (temp&1) flags|=C_FLAG; 4.2495 + else flags&=~C_FLAG; 4.2496 + temp>>=1; 4.2497 + if (temp&0x40) temp|=0x80; 4.2498 + seteab(temp); 4.2499 + setznp8(temp); 4.2500 + cycles-=((mod==3)?2:23); 4.2501 + flags|=A_FLAG; 4.2502 + flags&=~V_FLAG; 4.2503 + break; 4.2504 + 4.2505 +// default: 4.2506 +// printf("Bad D0 opcode %02X\n",rmdat&0x38); 4.2507 +// dumpregs(); 4.2508 +// exit(-1); 4.2509 + } 4.2510 + break; 4.2511 + 4.2512 + case 0xD1: 4.2513 + fetchea(); 4.2514 + tempw=geteaw(); 4.2515 + switch (rmdat&0x38) 4.2516 + { 4.2517 + case 0x00: /*ROL w,1*/ 4.2518 + if (tempw&0x8000) flags|=C_FLAG; 4.2519 + else flags&=~C_FLAG; 4.2520 + tempw<<=1; 4.2521 + if (flags&C_FLAG) tempw|=1; 4.2522 + seteaw(tempw); 4.2523 +// setznp16(tempw); 4.2524 + if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 4.2525 + else flags&=~V_FLAG; 4.2526 + cycles-=((mod==3)?2:23); 4.2527 + break; 4.2528 + case 0x08: /*ROR w,1*/ 4.2529 + if (tempw&1) flags|=C_FLAG; 4.2530 + else flags&=~C_FLAG; 4.2531 + tempw>>=1; 4.2532 + if (flags&C_FLAG) tempw|=0x8000; 4.2533 + seteaw(tempw); 4.2534 +// setznp16(tempw); 4.2535 + if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 4.2536 + else flags&=~V_FLAG; 4.2537 + cycles-=((mod==3)?2:23); 4.2538 + break; 4.2539 + case 0x10: /*RCL w,1*/ 4.2540 + temp2=flags&C_FLAG; 4.2541 + if (tempw&0x8000) flags|=C_FLAG; 4.2542 + else flags&=~C_FLAG; 4.2543 + tempw<<=1; 4.2544 + if (temp2) tempw|=1; 4.2545 + seteaw(tempw); 4.2546 + if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 4.2547 + else flags&=~V_FLAG; 4.2548 + cycles-=((mod==3)?2:23); 4.2549 + break; 4.2550 + case 0x18: /*RCR w,1*/ 4.2551 + temp2=flags&C_FLAG; 4.2552 + if (tempw&1) flags|=C_FLAG; 4.2553 + else flags&=~C_FLAG; 4.2554 + tempw>>=1; 4.2555 + if (temp2) tempw|=0x8000; 4.2556 + seteaw(tempw); 4.2557 +// setznp16(tempw); 4.2558 + if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 4.2559 + else flags&=~V_FLAG; 4.2560 + cycles-=((mod==3)?2:23); 4.2561 + break; 4.2562 + case 0x20: case 0x30: /*SHL w,1*/ 4.2563 + if (tempw&0x8000) flags|=C_FLAG; 4.2564 + else flags&=~C_FLAG; 4.2565 + if ((tempw^(tempw<<1))&0x8000) flags|=V_FLAG; 4.2566 + else flags&=~V_FLAG; 4.2567 + tempw<<=1; 4.2568 + seteaw(tempw); 4.2569 + setznp16(tempw); 4.2570 + cycles-=((mod==3)?2:23); 4.2571 + flags|=A_FLAG; 4.2572 + break; 4.2573 + case 0x28: /*SHR w,1*/ 4.2574 + if (tempw&1) flags|=C_FLAG; 4.2575 + else flags&=~C_FLAG; 4.2576 + if (tempw&0x8000) flags|=V_FLAG; 4.2577 + else flags&=~V_FLAG; 4.2578 + tempw>>=1; 4.2579 + seteaw(tempw); 4.2580 + setznp16(tempw); 4.2581 + cycles-=((mod==3)?2:23); 4.2582 + flags|=A_FLAG; 4.2583 + break; 4.2584 + 4.2585 + case 0x38: /*SAR w,1*/ 4.2586 + if (tempw&1) flags|=C_FLAG; 4.2587 + else flags&=~C_FLAG; 4.2588 + tempw>>=1; 4.2589 + if (tempw&0x4000) tempw|=0x8000; 4.2590 + seteaw(tempw); 4.2591 + setznp16(tempw); 4.2592 + cycles-=((mod==3)?2:23); 4.2593 + flags|=A_FLAG; 4.2594 + flags&=~V_FLAG; 4.2595 + break; 4.2596 + 4.2597 +// default: 4.2598 +// printf("Bad D1 opcode %02X\n",rmdat&0x38); 4.2599 +// dumpregs(); 4.2600 +// exit(-1); 4.2601 + } 4.2602 + break; 4.2603 + 4.2604 + case 0xD2: 4.2605 + fetchea(); 4.2606 + temp=geteab(); 4.2607 + c=CL; 4.2608 +// cycles-=c; 4.2609 + if (!c) break; 4.2610 +// if (c>7) printf("Shiftb %i %02X\n",rmdat&0x38,c); 4.2611 + switch (rmdat&0x38) 4.2612 + { 4.2613 + case 0x00: /*ROL b,CL*/ 4.2614 + while (c>0) 4.2615 + { 4.2616 + temp2=(temp&0x80)?1:0; 4.2617 + temp=(temp<<1)|temp2; 4.2618 + c--; 4.2619 + cycles-=4; 4.2620 + } 4.2621 + if (temp2) flags|=C_FLAG; 4.2622 + else flags&=~C_FLAG; 4.2623 + seteab(temp); 4.2624 +// setznp8(temp); 4.2625 + if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 4.2626 + else flags&=~V_FLAG; 4.2627 + cycles-=((mod==3)?8:28); 4.2628 + break; 4.2629 + case 0x08: /*ROR b,CL*/ 4.2630 + while (c>0) 4.2631 + { 4.2632 + temp2=temp&1; 4.2633 + temp>>=1; 4.2634 + if (temp2) temp|=0x80; 4.2635 + c--; 4.2636 + cycles-=4; 4.2637 + } 4.2638 + if (temp2) flags|=C_FLAG; 4.2639 + else flags&=~C_FLAG; 4.2640 + seteab(temp); 4.2641 + if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 4.2642 + else flags&=~V_FLAG; 4.2643 + cycles-=((mod==3)?8:28); 4.2644 + break; 4.2645 + case 0x10: /*RCL b,CL*/ 4.2646 +// printf("RCL %i %02X %02X\n",c,CL,temp); 4.2647 + while (c>0) 4.2648 + { 4.2649 + templ=flags&C_FLAG; 4.2650 + temp2=temp&0x80; 4.2651 + temp<<=1; 4.2652 + if (temp2) flags|=C_FLAG; 4.2653 + else flags&=~C_FLAG; 4.2654 + if (templ) temp|=1; 4.2655 + c--; 4.2656 + cycles-=4; 4.2657 + } 4.2658 +// printf("Now %02X\n",temp); 4.2659 + seteab(temp); 4.2660 + if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 4.2661 + else flags&=~V_FLAG; 4.2662 + cycles-=((mod==3)?8:28); 4.2663 + break; 4.2664 + case 0x18: /*RCR b,CL*/ 4.2665 + while (c>0) 4.2666 + { 4.2667 + templ=flags&C_FLAG; 4.2668 + temp2=temp&1; 4.2669 + temp>>=1; 4.2670 + if (temp2) flags|=C_FLAG; 4.2671 + else flags&=~C_FLAG; 4.2672 + if (templ) temp|=0x80; 4.2673 + c--; 4.2674 + cycles-=4; 4.2675 + } 4.2676 +// if (temp2) flags|=C_FLAG; 4.2677 +// else flags&=~C_FLAG; 4.2678 + seteab(temp); 4.2679 + if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 4.2680 + else flags&=~V_FLAG; 4.2681 + cycles-=((mod==3)?8:28); 4.2682 + break; 4.2683 + case 0x20: case 0x30: /*SHL b,CL*/ 4.2684 + if ((temp<<(c-1))&0x80) flags|=C_FLAG; 4.2685 + else flags&=~C_FLAG; 4.2686 + temp<<=c; 4.2687 + seteab(temp); 4.2688 + setznp8(temp); 4.2689 + cycles-=(c*4); 4.2690 + cycles-=((mod==3)?8:28); 4.2691 + flags|=A_FLAG; 4.2692 + break; 4.2693 + case 0x28: /*SHR b,CL*/ 4.2694 + if ((temp>>(c-1))&1) flags|=C_FLAG; 4.2695 + else flags&=~C_FLAG; 4.2696 + temp>>=c; 4.2697 + seteab(temp); 4.2698 + setznp8(temp); 4.2699 + cycles-=(c*4); 4.2700 + cycles-=((mod==3)?8:28); 4.2701 + flags|=A_FLAG; 4.2702 + break; 4.2703 + case 0x38: /*SAR b,CL*/ 4.2704 + if ((temp>>(c-1))&1) flags|=C_FLAG; 4.2705 + else flags&=~C_FLAG; 4.2706 + while (c>0) 4.2707 + { 4.2708 + temp>>=1; 4.2709 + if (temp&0x40) temp|=0x80; 4.2710 + c--; 4.2711 + cycles-=4; 4.2712 + } 4.2713 + seteab(temp); 4.2714 + setznp8(temp); 4.2715 + cycles-=((mod==3)?8:28); 4.2716 + flags|=A_FLAG; 4.2717 + break; 4.2718 + 4.2719 +// default: 4.2720 +// printf("Bad D2 opcode %02X\n",rmdat&0x38); 4.2721 +// dumpregs(); 4.2722 +// exit(-1); 4.2723 + } 4.2724 + break; 4.2725 + 4.2726 + case 0xD3: 4.2727 + fetchea(); 4.2728 + tempw=geteaw(); 4.2729 + c=CL; 4.2730 +// cycles-=c; 4.2731 + if (!c) break; 4.2732 +// if (c>15) printf("Shiftw %i %02X\n",rmdat&0x38,c); 4.2733 + switch (rmdat&0x38) 4.2734 + { 4.2735 + case 0x00: /*ROL w,CL*/ 4.2736 + while (c>0) 4.2737 + { 4.2738 + temp=(tempw&0x8000)?1:0; 4.2739 + tempw=(tempw<<1)|temp; 4.2740 + c--; 4.2741 + cycles-=4; 4.2742 + } 4.2743 + if (temp) flags|=C_FLAG; 4.2744 + else flags&=~C_FLAG; 4.2745 + seteaw(tempw); 4.2746 + if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 4.2747 + else flags&=~V_FLAG; 4.2748 + cycles-=((mod==3)?8:28); 4.2749 + break; 4.2750 + case 0x08: /*ROR w,CL*/ 4.2751 + while (c>0) 4.2752 + { 4.2753 + tempw2=(tempw&1)?0x8000:0; 4.2754 + tempw=(tempw>>1)|tempw2; 4.2755 + c--; 4.2756 + cycles-=4; 4.2757 + } 4.2758 + if (tempw2) flags|=C_FLAG; 4.2759 + else flags&=~C_FLAG; 4.2760 + seteaw(tempw); 4.2761 + if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 4.2762 + else flags&=~V_FLAG; 4.2763 + cycles-=((mod==3)?8:28); 4.2764 + break; 4.2765 + case 0x10: /*RCL w,CL*/ 4.2766 + while (c>0) 4.2767 + { 4.2768 + templ=flags&C_FLAG; 4.2769 + if (tempw&0x8000) flags|=C_FLAG; 4.2770 + else flags&=~C_FLAG; 4.2771 + tempw=(tempw<<1)|templ; 4.2772 + c--; 4.2773 + cycles-=4; 4.2774 + } 4.2775 + if (temp) flags|=C_FLAG; 4.2776 + else flags&=~C_FLAG; 4.2777 + seteaw(tempw); 4.2778 + if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 4.2779 + else flags&=~V_FLAG; 4.2780 + cycles-=((mod==3)?8:28); 4.2781 + break; 4.2782 + case 0x18: /*RCR w,CL*/ 4.2783 + while (c>0) 4.2784 + { 4.2785 + templ=flags&C_FLAG; 4.2786 + tempw2=(templ&1)?0x8000:0; 4.2787 + if (tempw&1) flags|=C_FLAG; 4.2788 + else flags&=~C_FLAG; 4.2789 + tempw=(tempw>>1)|tempw2; 4.2790 + c--; 4.2791 + cycles-=4; 4.2792 + } 4.2793 + if (tempw2) flags|=C_FLAG; 4.2794 + else flags&=~C_FLAG; 4.2795 + seteaw(tempw); 4.2796 + if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 4.2797 + else flags&=~V_FLAG; 4.2798 + cycles-=((mod==3)?8:28); 4.2799 + break; 4.2800 + 4.2801 + case 0x20: case 0x30: /*SHL w,CL*/ 4.2802 + if (c>16) 4.2803 + { 4.2804 + tempw=0; 4.2805 + flags&=~C_FLAG; 4.2806 + } 4.2807 + else 4.2808 + { 4.2809 + if ((tempw<<(c-1))&0x8000) flags|=C_FLAG; 4.2810 + else flags&=~C_FLAG; 4.2811 + tempw<<=c; 4.2812 + } 4.2813 + seteaw(tempw); 4.2814 + setznp16(tempw); 4.2815 + cycles-=(c*4); 4.2816 + cycles-=((mod==3)?8:28); 4.2817 + flags|=A_FLAG; 4.2818 + break; 4.2819 + 4.2820 + case 0x28: /*SHR w,CL*/ 4.2821 + if ((tempw>>(c-1))&1) flags|=C_FLAG; 4.2822 + else flags&=~C_FLAG; 4.2823 + tempw>>=c; 4.2824 + seteaw(tempw); 4.2825 + setznp16(tempw); 4.2826 + cycles-=(c*4); 4.2827 + cycles-=((mod==3)?8:28); 4.2828 + flags|=A_FLAG; 4.2829 + break; 4.2830 + 4.2831 + case 0x38: /*SAR w,CL*/ 4.2832 + tempw2=tempw&0x8000; 4.2833 + if ((tempw>>(c-1))&1) flags|=C_FLAG; 4.2834 + else flags&=~C_FLAG; 4.2835 + while (c>0) 4.2836 + { 4.2837 + tempw=(tempw>>1)|tempw2; 4.2838 + c--; 4.2839 + cycles-=4; 4.2840 + } 4.2841 + seteaw(tempw); 4.2842 + setznp16(tempw); 4.2843 + cycles-=((mod==3)?8:28); 4.2844 + flags|=A_FLAG; 4.2845 + break; 4.2846 + 4.2847 +// default: 4.2848 +// printf("Bad D3 opcode %02X\n",rmdat&0x38); 4.2849 +// dumpregs(); 4.2850 +// exit(-1); 4.2851 + } 4.2852 + break; 4.2853 + 4.2854 + case 0xD4: /*AAM*/ 4.2855 + tempws=FETCH(); 4.2856 + AH=AL/tempws; 4.2857 + AL%=tempws; 4.2858 + setznp16(AX); 4.2859 + cycles-=83; 4.2860 + break; 4.2861 + case 0xD5: /*AAD*/ 4.2862 + tempws=FETCH(); 4.2863 + AL=(AH*tempws)+AL; 4.2864 + AH=0; 4.2865 + setznp16(AX); 4.2866 + cycles-=60; 4.2867 + break; 4.2868 + case 0xD7: /*XLAT*/ 4.2869 + addr=BX+AL; 4.2870 + AL=readmemb(ds+addr); 4.2871 + cycles-=11; 4.2872 + break; 4.2873 + case 0xD9: case 0xDA: case 0xDB: case 0xDD: /*ESCAPE*/ 4.2874 + case 0xDC: case 0xDE: case 0xDF: case 0xD8: 4.2875 + fetchea(); 4.2876 + geteab(); 4.2877 + break; 4.2878 + 4.2879 + case 0xE0: /*LOOPNE*/ 4.2880 + offset=(int8_t)FETCH(); 4.2881 + CX--; 4.2882 + if (CX && !(flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.2883 + cycles-=6; 4.2884 + break; 4.2885 + case 0xE1: /*LOOPE*/ 4.2886 + offset=(int8_t)FETCH(); 4.2887 + CX--; 4.2888 + if (CX && (flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.2889 + cycles-=6; 4.2890 + break; 4.2891 + case 0xE2: /*LOOP*/ 4.2892 +// printf("LOOP start\n"); 4.2893 + offset=(int8_t)FETCH(); 4.2894 + CX--; 4.2895 + if (CX) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.2896 + cycles-=5; 4.2897 +// printf("LOOP end!\n"); 4.2898 + break; 4.2899 + case 0xE3: /*JCXZ*/ 4.2900 + offset=(int8_t)FETCH(); 4.2901 + if (!CX) { pc+=offset; cycles-=12; FETCHCLEAR(); } 4.2902 + cycles-=6; 4.2903 + break; 4.2904 + 4.2905 + case 0xE4: /*IN AL*/ 4.2906 + temp=FETCH(); 4.2907 + AL=inb(temp); 4.2908 + cycles-=14; 4.2909 + break; 4.2910 + case 0xE5: /*IN AX*/ 4.2911 + temp=FETCH(); 4.2912 + AL=inb(temp); 4.2913 + AH=inb(temp+1); 4.2914 + cycles-=14; 4.2915 + break; 4.2916 + case 0xE6: /*OUT AL*/ 4.2917 + temp=FETCH(); 4.2918 + outb(temp,AL); 4.2919 + cycles-=14; 4.2920 + break; 4.2921 + case 0xE7: /*OUT AX*/ 4.2922 + temp=FETCH(); 4.2923 + outb(temp,AL); 4.2924 + outb(temp+1,AH); 4.2925 + cycles-=14; 4.2926 + break; 4.2927 + 4.2928 + case 0xE8: /*CALL rel 16*/ 4.2929 + tempw=getword(); 4.2930 + if (ssegs) ss=oldss; 4.2931 +// writememb(ss+((SP-1)&0xFFFF),pc>>8); 4.2932 + writememw(ss,((SP-2)&0xFFFF),pc); 4.2933 + SP-=2; 4.2934 + pc+=tempw; 4.2935 + cycles-=23; 4.2936 + FETCHCLEAR(); 4.2937 + break; 4.2938 + case 0xE9: /*JMP rel 16*/ 4.2939 +// printf("PC was %04X\n",pc); 4.2940 + pc+=getword(); 4.2941 +// printf("PC now %04X\n",pc); 4.2942 + cycles-=15; 4.2943 + FETCHCLEAR(); 4.2944 + break; 4.2945 + case 0xEA: /*JMP far*/ 4.2946 + addr=getword(); 4.2947 + tempw=getword(); 4.2948 + pc=addr; 4.2949 +// printf("EA\n"); 4.2950 + loadcs(tempw); 4.2951 +// cs=loadcs(CS); 4.2952 +// cs=CS<<4; 4.2953 + cycles-=15; 4.2954 + FETCHCLEAR(); 4.2955 + break; 4.2956 + case 0xEB: /*JMP rel*/ 4.2957 + offset=(int8_t)FETCH(); 4.2958 + pc+=offset; 4.2959 + cycles-=15; 4.2960 + FETCHCLEAR(); 4.2961 + break; 4.2962 + case 0xEC: /*IN AL,DX*/ 4.2963 + AL=inb(DX); 4.2964 + cycles-=12; 4.2965 + break; 4.2966 + case 0xED: /*IN AX,DX*/ 4.2967 + AL=inb(DX); 4.2968 + AH=inb(DX+1); 4.2969 + cycles-=12; 4.2970 + break; 4.2971 + case 0xEE: /*OUT DX,AL*/ 4.2972 + outb(DX,AL); 4.2973 + cycles-=12; 4.2974 + break; 4.2975 + case 0xEF: /*OUT DX,AX*/ 4.2976 + outb(DX,AL); 4.2977 + outb(DX+1,AH); 4.2978 + cycles-=12; 4.2979 + break; 4.2980 + 4.2981 + case 0xF0: /*LOCK*/ 4.2982 + cycles-=4; 4.2983 + break; 4.2984 + 4.2985 + case 0xF2: /*REPNE*/ 4.2986 + rep(0); 4.2987 + break; 4.2988 + case 0xF3: /*REPE*/ 4.2989 + rep(1); 4.2990 + break; 4.2991 + 4.2992 + case 0xF4: /*HLT*/ 4.2993 +// printf("IN HLT!!!! %04X:%04X %08X %08X %08X\n",oldcs,oldpc,old8,old82,old83); 4.2994 +/* if (!(flags & I_FLAG)) 4.2995 + { 4.2996 + pclog("HLT\n"); 4.2997 + dumpregs(); 4.2998 + exit(-1); 4.2999 + }*/ 4.3000 + inhlt=1; 4.3001 + pc--; 4.3002 + FETCHCLEAR(); 4.3003 + cycles-=2; 4.3004 + break; 4.3005 + case 0xF5: /*CMC*/ 4.3006 + flags^=C_FLAG; 4.3007 + cycles-=2; 4.3008 + break; 4.3009 + 4.3010 + case 0xF6: 4.3011 + fetchea(); 4.3012 + temp=geteab(); 4.3013 + switch (rmdat&0x38) 4.3014 + { 4.3015 + case 0x00: /*TEST b,#8*/ 4.3016 + temp2=FETCH(); 4.3017 + temp&=temp2; 4.3018 + setznp8(temp); 4.3019 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.3020 + cycles-=((mod==3)?5:11); 4.3021 + break; 4.3022 + case 0x10: /*NOT b*/ 4.3023 + temp=~temp; 4.3024 + seteab(temp); 4.3025 + cycles-=((mod==3)?3:24); 4.3026 + break; 4.3027 + case 0x18: /*NEG b*/ 4.3028 + setsub8(0,temp); 4.3029 + temp=0-temp; 4.3030 + seteab(temp); 4.3031 + cycles-=((mod==3)?3:24); 4.3032 + break; 4.3033 + case 0x20: /*MUL AL,b*/ 4.3034 + setznp8(AL); 4.3035 + AX=AL*temp; 4.3036 + if (AX) flags&=~Z_FLAG; 4.3037 + else flags|=Z_FLAG; 4.3038 + if (AH) flags|=(C_FLAG|V_FLAG); 4.3039 + else flags&=~(C_FLAG|V_FLAG); 4.3040 + cycles-=70; 4.3041 + break; 4.3042 + case 0x28: /*IMUL AL,b*/ 4.3043 + setznp8(AL); 4.3044 + tempws=(int)((int8_t)AL)*(int)((int8_t)temp); 4.3045 + AX=tempws&0xFFFF; 4.3046 + if (AX) flags&=~Z_FLAG; 4.3047 + else flags|=Z_FLAG; 4.3048 + if (AH) flags|=(C_FLAG|V_FLAG); 4.3049 + else flags&=~(C_FLAG|V_FLAG); 4.3050 + cycles-=80; 4.3051 + break; 4.3052 + case 0x30: /*DIV AL,b*/ 4.3053 + tempw=AX; 4.3054 + if (temp) 4.3055 + { 4.3056 + tempw2=tempw%temp; 4.3057 +/* if (!tempw) 4.3058 + { 4.3059 + writememw((ss+SP)-2,flags|0xF000); 4.3060 + writememw((ss+SP)-4,cs>>4); 4.3061 + writememw((ss+SP)-6,pc); 4.3062 + SP-=6; 4.3063 + flags&=~I_FLAG; 4.3064 + pc=readmemw(0); 4.3065 + cs=readmemw(2)<<4; 4.3066 + printf("Div by zero %04X:%04X\n",cs>>4,pc); 4.3067 +// dumpregs(); 4.3068 +// exit(-1); 4.3069 + } 4.3070 + else 4.3071 + {*/ 4.3072 + AH=tempw2; 4.3073 + tempw/=temp; 4.3074 + AL=tempw&0xFF; 4.3075 +// } 4.3076 + } 4.3077 + else 4.3078 + { 4.3079 + printf("DIVb BY 0 %04X:%04X\n",cs>>4,pc); 4.3080 + writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 4.3081 + writememw(ss,(SP-4)&0xFFFF,CS); 4.3082 + writememw(ss,(SP-6)&0xFFFF,pc); 4.3083 + SP-=6; 4.3084 + flags&=~I_FLAG; 4.3085 + flags&=~T_FLAG; 4.3086 + pc=readmemw(0,0); 4.3087 +// printf("F6 30\n"); 4.3088 + loadcs(readmemw(0,2)); 4.3089 + FETCHCLEAR(); 4.3090 +// cs=loadcs(CS); 4.3091 +// cs=CS<<4; 4.3092 +// printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x30); 4.3093 +// dumpregs(); 4.3094 +// exit(-1); 4.3095 + } 4.3096 + cycles-=80; 4.3097 + break; 4.3098 + case 0x38: /*IDIV AL,b*/ 4.3099 + tempws=(int)AX; 4.3100 + if (temp) 4.3101 + { 4.3102 + tempw2=tempws%(int)((int8_t)temp); 4.3103 +/* if (!tempw) 4.3104 + { 4.3105 + writememw((ss+SP)-2,flags|0xF000); 4.3106 + writememw((ss+SP)-4,cs>>4); 4.3107 + writememw((ss+SP)-6,pc); 4.3108 + SP-=6; 4.3109 + flags&=~I_FLAG; 4.3110 + pc=readmemw(0); 4.3111 + cs=readmemw(2)<<4; 4.3112 + printf("Div by zero %04X:%04X\n",cs>>4,pc); 4.3113 + } 4.3114 + else 4.3115 + {*/ 4.3116 + AH=tempw2&0xFF; 4.3117 + tempws/=(int)((int8_t)temp); 4.3118 + AL=tempws&0xFF; 4.3119 +// } 4.3120 + } 4.3121 + else 4.3122 + { 4.3123 + printf("IDIVb BY 0 %04X:%04X\n",cs>>4,pc); 4.3124 + writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 4.3125 + writememw(ss,(SP-4)&0xFFFF,CS); 4.3126 + writememw(ss,(SP-6)&0xFFFF,pc); 4.3127 + SP-=6; 4.3128 + flags&=~I_FLAG; 4.3129 + flags&=~T_FLAG; 4.3130 + pc=readmemw(0,0); 4.3131 +// printf("F6 38\n"); 4.3132 + loadcs(readmemw(0,2)); 4.3133 + FETCHCLEAR(); 4.3134 +// cs=loadcs(CS); 4.3135 +// cs=CS<<4; 4.3136 +// printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x38); 4.3137 + } 4.3138 + cycles-=101; 4.3139 + break; 4.3140 + 4.3141 +// default: 4.3142 +// printf("Bad F6 opcode %02X\n",rmdat&0x38); 4.3143 +// dumpregs(); 4.3144 +// exit(-1); 4.3145 + } 4.3146 + break; 4.3147 + 4.3148 + case 0xF7: 4.3149 + fetchea(); 4.3150 + tempw=geteaw(); 4.3151 + switch (rmdat&0x38) 4.3152 + { 4.3153 + case 0x00: /*TEST w*/ 4.3154 + tempw2=getword(); 4.3155 + setznp16(tempw&tempw2); 4.3156 + flags&=~(C_FLAG|V_FLAG|A_FLAG); 4.3157 + cycles-=((mod==3)?5:11); 4.3158 + break; 4.3159 + case 0x10: /*NOT w*/ 4.3160 + seteaw(~tempw); 4.3161 + cycles-=((mod==3)?3:24); 4.3162 + break; 4.3163 + case 0x18: /*NEG w*/ 4.3164 + setsub16(0,tempw); 4.3165 + tempw=0-tempw; 4.3166 + seteaw(tempw); 4.3167 + cycles-=((mod==3)?3:24); 4.3168 + break; 4.3169 + case 0x20: /*MUL AX,w*/ 4.3170 + setznp16(AX); 4.3171 + templ=AX*tempw; 4.3172 +// if (output) printf("%04X*%04X=%08X\n",AX,tempw,templ); 4.3173 + AX=templ&0xFFFF; 4.3174 + DX=templ>>16; 4.3175 + if (AX|DX) flags&=~Z_FLAG; 4.3176 + else flags|=Z_FLAG; 4.3177 + if (DX) flags|=(C_FLAG|V_FLAG); 4.3178 + else flags&=~(C_FLAG|V_FLAG); 4.3179 + cycles-=118; 4.3180 + break; 4.3181 + case 0x28: /*IMUL AX,w*/ 4.3182 + setznp16(AX); 4.3183 +// printf("IMUL %i %i ",(int)((int16_t)AX),(int)((int16_t)tempw)); 4.3184 + tempws=(int)((int16_t)AX)*(int)((int16_t)tempw); 4.3185 + if ((tempws>>15) && ((tempws>>15)!=-1)) flags|=(C_FLAG|V_FLAG); 4.3186 + else flags&=~(C_FLAG|V_FLAG); 4.3187 +// printf("%i ",tempws); 4.3188 + AX=tempws&0xFFFF; 4.3189 + tempws=(uint16_t)(tempws>>16); 4.3190 + DX=tempws&0xFFFF; 4.3191 +// printf("%04X %04X\n",AX,DX); 4.3192 +// dumpregs(); 4.3193 +// exit(-1); 4.3194 + if (AX|DX) flags&=~Z_FLAG; 4.3195 + else flags|=Z_FLAG; 4.3196 + cycles-=128; 4.3197 + break; 4.3198 + case 0x30: /*DIV AX,w*/ 4.3199 + templ=(DX<<16)|AX; 4.3200 +// printf("DIV %08X/%04X\n",templ,tempw); 4.3201 + if (tempw) 4.3202 + { 4.3203 + tempw2=templ%tempw; 4.3204 + DX=tempw2; 4.3205 + templ/=tempw; 4.3206 + AX=templ&0xFFFF; 4.3207 + } 4.3208 + else 4.3209 + { 4.3210 + printf("DIVw BY 0 %04X:%04X\n",cs>>4,pc); 4.3211 + writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 4.3212 + writememw(ss,(SP-4)&0xFFFF,CS); 4.3213 + writememw(ss,(SP-6)&0xFFFF,pc); 4.3214 + SP-=6; 4.3215 + flags&=~I_FLAG; 4.3216 + flags&=~T_FLAG; 4.3217 + pc=readmemw(0,0); 4.3218 +// printf("F7 30\n"); 4.3219 + loadcs(readmemw(0,2)); 4.3220 + FETCHCLEAR(); 4.3221 + } 4.3222 + cycles-=144; 4.3223 + break; 4.3224 + case 0x38: /*IDIV AX,w*/ 4.3225 + tempws=(int)((DX<<16)|AX); 4.3226 +// printf("IDIV %i %i ",tempws,tempw); 4.3227 + if (tempw) 4.3228 + { 4.3229 + tempw2=tempws%(int)((int16_t)tempw); 4.3230 +// printf("%04X ",tempw2); 4.3231 + DX=tempw2; 4.3232 + tempws/=(int)((int16_t)tempw); 4.3233 + AX=tempws&0xFFFF; 4.3234 + } 4.3235 + else 4.3236 + { 4.3237 + printf("IDIVw BY 0 %04X:%04X\n",cs>>4,pc); 4.3238 + writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 4.3239 + writememw(ss,(SP-4)&0xFFFF,CS); 4.3240 + writememw(ss,(SP-6)&0xFFFF,pc); 4.3241 + SP-=6; 4.3242 + flags&=~I_FLAG; 4.3243 + flags&=~T_FLAG; 4.3244 + pc=readmemw(0,0); 4.3245 +// printf("F7 38\n"); 4.3246 + loadcs(readmemw(0,2)); 4.3247 + FETCHCLEAR(); 4.3248 + } 4.3249 + cycles-=165; 4.3250 + break; 4.3251 + 4.3252 +// default: 4.3253 +// printf("Bad F7 opcode %02X\n",rmdat&0x38); 4.3254 +// dumpregs(); 4.3255 +// exit(-1); 4.3256 + } 4.3257 + break; 4.3258 + 4.3259 + case 0xF8: /*CLC*/ 4.3260 + flags&=~C_FLAG; 4.3261 + cycles-=2; 4.3262 + break; 4.3263 + case 0xF9: /*STC*/ 4.3264 +// printf("STC %04X\n",pc); 4.3265 + flags|=C_FLAG; 4.3266 + cycles-=2; 4.3267 + break; 4.3268 + case 0xFA: /*CLI*/ 4.3269 + flags&=~I_FLAG; 4.3270 +// printf("CLI at %04X:%04X\n",cs>>4,pc); 4.3271 + cycles-=3; 4.3272 + break; 4.3273 + case 0xFB: /*STI*/ 4.3274 + flags|=I_FLAG; 4.3275 +// printf("STI at %04X:%04X\n",cs>>4,pc); 4.3276 + cycles-=2; 4.3277 + break; 4.3278 + case 0xFC: /*CLD*/ 4.3279 + flags&=~D_FLAG; 4.3280 + cycles-=2; 4.3281 + break; 4.3282 + case 0xFD: /*STD*/ 4.3283 + flags|=D_FLAG; 4.3284 + cycles-=2; 4.3285 + break; 4.3286 + 4.3287 + case 0xFE: /*INC/DEC b*/ 4.3288 + fetchea(); 4.3289 + temp=geteab(); 4.3290 + flags&=~V_FLAG; 4.3291 + if (rmdat&0x38) 4.3292 + { 4.3293 + setsub8nc(temp,1); 4.3294 + temp2=temp-1; 4.3295 + if ((temp&0x80) && !(temp2&0x80)) flags|=V_FLAG; 4.3296 + } 4.3297 + else 4.3298 + { 4.3299 + setadd8nc(temp,1); 4.3300 + temp2=temp+1; 4.3301 + if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG; 4.3302 + } 4.3303 +// setznp8(temp2); 4.3304 + seteab(temp2); 4.3305 + cycles-=((mod==3)?3:23); 4.3306 + break; 4.3307 + 4.3308 + case 0xFF: 4.3309 + fetchea(); 4.3310 + switch (rmdat&0x38) 4.3311 + { 4.3312 + case 0x00: /*INC w*/ 4.3313 + tempw=geteaw(); 4.3314 + setadd16nc(tempw,1); 4.3315 +// setznp16(tempw+1); 4.3316 + seteaw(tempw+1); 4.3317 + cycles-=((mod==3)?3:23); 4.3318 + break; 4.3319 + case 0x08: /*DEC w*/ 4.3320 + tempw=geteaw(); 4.3321 +// setsub16(tempw,1); 4.3322 + setsub16nc(tempw,1); 4.3323 +// setznp16(tempw-1); 4.3324 + seteaw(tempw-1); 4.3325 +// if (output) printf("DEC - %04X\n",tempw); 4.3326 + cycles-=((mod==3)?3:23); 4.3327 + break; 4.3328 + case 0x10: /*CALL*/ 4.3329 + tempw=geteaw(); 4.3330 + if (ssegs) ss=oldss; 4.3331 + writememw(ss,(SP-2)&0xFFFF,pc); 4.3332 + SP-=2; 4.3333 + pc=tempw; 4.3334 +// printf("FF 10\n"); 4.3335 + cycles-=((mod==3)?20:29); 4.3336 + FETCHCLEAR(); 4.3337 + break; 4.3338 + case 0x18: /*CALL far*/ 4.3339 + tempw=readmemw(easeg,eaaddr); 4.3340 + tempw2=readmemw(easeg,(eaaddr+2)&0xFFFF); //geteaw2(); 4.3341 + tempw3=CS; 4.3342 + tempw4=pc; 4.3343 + if (ssegs) ss=oldss; 4.3344 + pc=tempw; 4.3345 +// printf("FF 18\n"); 4.3346 + loadcs(tempw2); 4.3347 + writememw(ss,(SP-2)&0xFFFF,tempw3); 4.3348 + writememw(ss,((SP-4)&0xFFFF),tempw4); 4.3349 + SP-=4; 4.3350 + cycles-=53; 4.3351 + FETCHCLEAR(); 4.3352 + break; 4.3353 + case 0x20: /*JMP*/ 4.3354 + pc=geteaw(); 4.3355 +// printf("FF 20\n"); 4.3356 + cycles-=((mod==3)?11:18); 4.3357 + FETCHCLEAR(); 4.3358 + break; 4.3359 + case 0x28: /*JMP far*/ 4.3360 + pc=readmemw(easeg,eaaddr); //geteaw(); 4.3361 +// printf("FF 28\n"); 4.3362 + loadcs(readmemw(easeg,(eaaddr+2)&0xFFFF)); //geteaw2(); 4.3363 +// cs=loadcs(CS); 4.3364 +// cs=CS<<4; 4.3365 + cycles-=24; 4.3366 + FETCHCLEAR(); 4.3367 + break; 4.3368 + case 0x30: /*PUSH w*/ 4.3369 + tempw=geteaw(); 4.3370 +// if (output) printf("PUSH %04X %i %02X %04X %04X %02X %02X\n",tempw,rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]); 4.3371 + if (ssegs) ss=oldss; 4.3372 + writememw(ss,((SP-2)&0xFFFF),tempw); 4.3373 + SP-=2; 4.3374 + cycles-=((mod==3)?15:24); 4.3375 + break; 4.3376 + 4.3377 +// default: 4.3378 +// printf("Bad FF opcode %02X\n",rmdat&0x38); 4.3379 +// dumpregs(); 4.3380 +// exit(-1); 4.3381 + } 4.3382 + break; 4.3383 + 4.3384 + default: 4.3385 + FETCH(); 4.3386 + cycles-=8; 4.3387 + break; 4.3388 + 4.3389 +/* printf("Bad opcode %02X at %04X:%04X from %04X:%04X %08X\n",opcode,cs>>4,pc,old8>>16,old8&0xFFFF,old82); 4.3390 + dumpregs(); 4.3391 + exit(-1);*/ 4.3392 + } 4.3393 + pc&=0xFFFF; 4.3394 + 4.3395 +/* if ((CS & 0xf000) == 0xa000) 4.3396 + { 4.3397 + dumpregs(); 4.3398 + exit(-1); 4.3399 + }*/ 4.3400 +// output = 3; 4.3401 +/* if (CS == 0xf000) 4.3402 + { 4.3403 + dumpregs(); 4.3404 + exit(-1); 4.3405 + } 4.3406 + output = 3;*/ 4.3407 + if (ssegs) 4.3408 + { 4.3409 + ds=oldds; 4.3410 + ss=oldss; 4.3411 + ssegs=0; 4.3412 + } 4.3413 + 4.3414 +// output = 3; 4.3415 + // if (instime) printf("%i %i %i %i\n",cycdiff,cycles,memcycs,fetchclocks); 4.3416 + FETCHADD(((cycdiff-cycles)-memcycs)-fetchclocks); 4.3417 + if ((cycdiff-cycles)<memcycs) cycles-=(memcycs-(cycdiff-cycles)); 4.3418 + if (romset==ROM_IBMPC) 4.3419 + { 4.3420 + if ((cs+pc)==0xFE4A7) /*You didn't seriously think I was going to emulate the cassette, did you?*/ 4.3421 + { 4.3422 + CX=1; 4.3423 + BX=0x500; 4.3424 + } 4.3425 + } 4.3426 + memcycs=0; 4.3427 + 4.3428 + insc++; 4.3429 +// output=(CS==0xEB9); 4.3430 + clockhardware(); 4.3431 + 4.3432 + 4.3433 + if (trap && (flags&T_FLAG) && !noint) 4.3434 + { 4.3435 +// printf("TRAP!!! %04X:%04X\n",CS,pc); 4.3436 + writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 4.3437 + writememw(ss,(SP-4)&0xFFFF,CS); 4.3438 + writememw(ss,(SP-6)&0xFFFF,pc); 4.3439 + SP-=6; 4.3440 + addr=1<<2; 4.3441 + flags&=~I_FLAG; 4.3442 + flags&=~T_FLAG; 4.3443 + pc=readmemw(0,addr); 4.3444 + loadcs(readmemw(0,addr+2)); 4.3445 + FETCHCLEAR(); 4.3446 + } 4.3447 + else if ((flags&I_FLAG) && (pic.pend&~pic.mask) && !ssegs && !noint) 4.3448 + { 4.3449 + temp=picinterrupt(); 4.3450 + if (temp!=0xFF) 4.3451 + { 4.3452 + if (inhlt) pc++; 4.3453 + writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 4.3454 + writememw(ss,(SP-4)&0xFFFF,CS); 4.3455 + writememw(ss,(SP-6)&0xFFFF,pc); 4.3456 + SP-=6; 4.3457 + addr=temp<<2; 4.3458 + flags&=~I_FLAG; 4.3459 + flags&=~T_FLAG; 4.3460 + pc=readmemw(0,addr); 4.3461 +// printf("INT INT INT\n"); 4.3462 + loadcs(readmemw(0,addr+2)); 4.3463 + FETCHCLEAR(); 4.3464 +// printf("INTERRUPT\n"); 4.3465 + } 4.3466 + } 4.3467 + 4.3468 + if (noint) noint=0; 4.3469 + ins++; 4.3470 +/* if (timetolive) 4.3471 + { 4.3472 + timetolive--; 4.3473 + if (!timetolive) exit(-1); //output=0; 4.3474 + }*/ 4.3475 + } 4.3476 +} 4.3477 +
5.1 --- a/src/adlib.c Mon May 27 17:46:42 2013 +0100 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,187 +0,0 @@ 5.4 -#include <stdint.h> 5.5 -#include <stdlib.h> 5.6 -#include "ibm.h" 5.7 -#include "mame/fmopl.h" 5.8 -#include "mame/ymf262.h" 5.9 - 5.10 -/*Interfaces between PCem and the actual Adlib emulator*/ 5.11 - 5.12 -static int adlib_inited = 0; 5.13 -int adlibpos=0; 5.14 -void *YM3812[2]; 5.15 -void *YMF262; 5.16 -int fm_timers[2][2],fm_timers_enable[2][2]; 5.17 - 5.18 -void adlib_write(uint16_t a, uint8_t v) 5.19 -{ 5.20 -// printf("Adlib write %04X %02X %i\n",a,v,sbtype); 5.21 - if (!sbtype) return; 5.22 - if (sbtype<SBPRO && a<0x224) return; 5.23 - switch (a) 5.24 - { 5.25 - case 0x220: case 0x221: 5.26 - if (sbtype<SBPRO2) ym3812_write(YM3812[0],a,v); 5.27 - else ymf262_write(YMF262,a,v); 5.28 - break; 5.29 - case 0x222: case 0x223: 5.30 - if (sbtype<SBPRO2) ym3812_write(YM3812[1],a,v); 5.31 - else ymf262_write(YMF262,a,v); 5.32 - break; 5.33 - case 0x228: case 0x229: case 0x388: case 0x389: 5.34 - if (sbtype<SBPRO2) 5.35 - { 5.36 - ym3812_write(YM3812[0],a,v); 5.37 - ym3812_write(YM3812[1],a,v); 5.38 - } 5.39 - else 5.40 - ymf262_write(YMF262,a,v); 5.41 - break; 5.42 - } 5.43 -} 5.44 - 5.45 -uint8_t adlib_read(uint16_t a) 5.46 -{ 5.47 - uint8_t temp; 5.48 -// printf("Adlib read %04X\n",a); 5.49 - if (sbtype>=SBPRO2) 5.50 - { 5.51 - switch (a) 5.52 - { 5.53 - case 0x220: case 0x221: 5.54 - case 0x222: case 0x223: 5.55 - case 0x228: case 0x229: 5.56 - case 0x388: case 0x389: 5.57 - temp=ymf262_read(YMF262,a); 5.58 -// pclog("YMF262 read %03X %02X\n",a,temp); 5.59 - cycles-=(int)(isa_timing * 8); 5.60 - return temp; 5.61 - } 5.62 - } 5.63 - if (!sbtype) return 0xFF; 5.64 - switch (a) 5.65 - { 5.66 - case 0x220: case 0x221: 5.67 - if (sbtype<SBPRO) return 0xFF; 5.68 - case 0x228: case 0x229: 5.69 - case 0x388: case 0x389: 5.70 - cycles-=(int)(isa_timing * 8); 5.71 - return ym3812_read(YM3812[0],a); 5.72 - case 0x222: case 0x223: 5.73 - if (sbtype<SBPRO) return 0xFF; 5.74 - return ym3812_read(YM3812[1],a); 5.75 - } 5.76 -/* if (sbtype<SBPRO && a<0x224) return 0xFF; 5.77 - if (a==0x222) return adlibstat2; 5.78 - if (!(a&1)) return adlibstat; 5.79 - return 0;*/ 5.80 -} 5.81 - 5.82 -signed short *ad_bufs[4]; 5.83 -int16_t ad_filtbuf[2]={0,0}; 5.84 -void getadlib(signed short *bufl, signed short *bufr, int size) 5.85 -{ 5.86 - int c; 5.87 - if (sbtype>=SBPRO2) 5.88 - { 5.89 - ymf262_update_one(YMF262,ad_bufs,size); 5.90 - for (c=0;c<size;c++) 5.91 - { 5.92 - ad_filtbuf[0]=bufl[c]=(ad_bufs[0][c]/4)+((ad_filtbuf[0]*11)/16); 5.93 - ad_filtbuf[1]=bufr[c]=(ad_bufs[1][c]/4)+((ad_filtbuf[1]*11)/16); 5.94 - } 5.95 - if (fm_timers_enable[0][0]) 5.96 - { 5.97 - fm_timers[0][0]--; 5.98 - if (fm_timers[0][0]<0) ymf262_timer_over(YMF262,0); 5.99 - } 5.100 - if (fm_timers_enable[0][1]) 5.101 - { 5.102 - fm_timers[0][1]--; 5.103 - if (fm_timers[0][1]<0) ymf262_timer_over(YMF262,1); 5.104 - } 5.105 - } 5.106 - else 5.107 - { 5.108 - ym3812_update_one(YM3812[0],bufl,size); 5.109 - ym3812_update_one(YM3812[1],bufr,size); 5.110 - for (c=0;c<size;c++) 5.111 - { 5.112 - ad_filtbuf[0]=bufl[c]=(bufl[c]/4)+((ad_filtbuf[0]*11)/16); 5.113 - ad_filtbuf[1]=bufr[c]=(bufr[c]/4)+((ad_filtbuf[1]*11)/16); 5.114 - } 5.115 - if (fm_timers_enable[0][0]) 5.116 - { 5.117 - fm_timers[0][0]--; 5.118 - if (fm_timers[0][0]<0) ym3812_timer_over(YM3812[0],0); 5.119 - } 5.120 - if (fm_timers_enable[0][1]) 5.121 - { 5.122 - fm_timers[0][1]--; 5.123 - if (fm_timers[0][1]<0) ym3812_timer_over(YM3812[0],1); 5.124 - } 5.125 - if (fm_timers_enable[1][0]) 5.126 - { 5.127 - fm_timers[1][0]--; 5.128 - if (fm_timers[1][0]<0) ym3812_timer_over(YM3812[1],0); 5.129 - } 5.130 - if (fm_timers_enable[1][1]) 5.131 - { 5.132 - fm_timers[1][1]--; 5.133 - if (fm_timers[1][1]<0) ym3812_timer_over(YM3812[1],1); 5.134 - } 5.135 - } 5.136 -// for (c=0;c<size;c++) buf[c]/=2; 5.137 -} 5.138 - 5.139 -void ym3812_timer_set_0(void *param,int timer,attotime period) 5.140 -{ 5.141 - fm_timers[0][timer]=period/20833; 5.142 - if (!fm_timers[0][timer]) fm_timers[0][timer]=1; 5.143 - fm_timers_enable[0][timer]=(period)?1:0; 5.144 -} 5.145 -void ym3812_timer_set_1(void *param,int timer,attotime period) 5.146 -{ 5.147 - fm_timers[1][timer]=period/20833; 5.148 - if (!fm_timers[1][timer]) fm_timers[1][timer]=1; 5.149 - fm_timers_enable[1][timer]=(period)?1:0; 5.150 -} 5.151 - 5.152 -void ymf262_timer_set(void *param,int timer,attotime period) 5.153 -{ 5.154 - fm_timers[0][timer]=period/20833; 5.155 - if (!fm_timers[0][timer]) fm_timers[0][timer]=1; 5.156 - fm_timers_enable[0][timer]=(period)?1:0; 5.157 -} 5.158 - 5.159 -void adlib_init() 5.160 -{ 5.161 - if (!adlib_inited) 5.162 - { 5.163 - ad_bufs[0]=(signed short *)malloc(48000); 5.164 - ad_bufs[1]=(signed short *)malloc(48000); 5.165 - ad_bufs[2]=(signed short *)malloc(48000); 5.166 - ad_bufs[3]=(signed short *)malloc(48000); 5.167 - 5.168 - YM3812[0]=ym3812_init((void *)NULL,3579545,48000); 5.169 - ym3812_reset_chip(YM3812[0]); 5.170 - ym3812_set_timer_handler(YM3812[0],ym3812_timer_set_0,NULL); 5.171 - YM3812[1]=ym3812_init((void *)NULL,3579545,48000); 5.172 - ym3812_reset_chip(YM3812[1]); 5.173 - ym3812_set_timer_handler(YM3812[1],ym3812_timer_set_1,NULL); 5.174 - 5.175 - YMF262=ymf262_init((void *)NULL,3579545*4,48000); 5.176 - ymf262_reset_chip(YMF262); 5.177 - ymf262_set_timer_handler(YMF262,ymf262_timer_set,NULL); 5.178 - } 5.179 - 5.180 - adlib_inited = 1; 5.181 - 5.182 - io_sethandler(0x0388, 0x0002, adlib_read, NULL, NULL, adlib_write, NULL, NULL); 5.183 -} 5.184 - 5.185 -void adlib_reset() 5.186 -{ 5.187 - ym3812_reset_chip(YM3812[0]); 5.188 - ym3812_reset_chip(YM3812[1]); 5.189 - ymf262_reset_chip(YMF262); 5.190 -}
6.1 --- a/src/cms.c Mon May 27 17:46:42 2013 +0100 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,141 +0,0 @@ 6.4 -#include <stdio.h> 6.5 -#include "ibm.h" 6.6 - 6.7 -int cmsaddrs[2]; 6.8 -uint8_t cmsregs[2][32]; 6.9 -uint16_t cmslatch[12],cmsnoisefreq[12]; 6.10 -int cmsfreq[12]; 6.11 -float cmscount[12]; 6.12 -int cmsvol[12][2]; 6.13 -int cmsstat[12]; 6.14 -uint16_t cmsnoise[4]; 6.15 -int cmsnoisecount[4]; 6.16 -int cmsnoisetype[4]; 6.17 - 6.18 -#define CMSCONST (62500.0/44100.0) 6.19 - 6.20 -void getcms(signed short *p, int size) 6.21 -{ 6.22 - int c,d; 6.23 - int ena[12],noiseena[12]; 6.24 - for (c=0;c<6;c++) 6.25 - { 6.26 - ena[c]=(cmsregs[0][0x14]&(1<<c)); 6.27 - ena[c+6]=(cmsregs[1][0x14]&(1<<c)); 6.28 - } 6.29 - if (!(cmsregs[0][0x1C]&1)) 6.30 - { 6.31 - for (c=0;c<6;c++) ena[c]=0; 6.32 - } 6.33 - if (!(cmsregs[1][0x1C]&1)) 6.34 - { 6.35 - for (c=0;c<6;c++) ena[c+6]=0; 6.36 - } 6.37 - for (c=0;c<6;c++) 6.38 - { 6.39 - noiseena[c]=(cmsregs[0][0x15]&(1<<c)); 6.40 - noiseena[c+6]=(cmsregs[1][0x15]&(1<<c)); 6.41 - } 6.42 - if (!(cmsregs[0][0x1C]&1)) 6.43 - { 6.44 - for (c=0;c<6;c++) noiseena[c]=0; 6.45 - } 6.46 - if (!(cmsregs[1][0x1C]&1)) 6.47 - { 6.48 - for (c=0;c<6;c++) noiseena[c+6]=0; 6.49 - } 6.50 - for (c=0;c<4;c++) 6.51 - { 6.52 - switch (cmsnoisetype[c]) 6.53 - { 6.54 - case 0: cmsnoisefreq[c]=31250; break; 6.55 - case 1: cmsnoisefreq[c]=15625; break; 6.56 - case 2: cmsnoisefreq[c]=7812; break; 6.57 - case 3: cmsnoisefreq[c]=cmsfreq[c*3]; break; 6.58 - } 6.59 - } 6.60 - for (c=0;c<(size<<1);c+=2) 6.61 - { 6.62 - p[c]=0; 6.63 - p[c+1]=0; 6.64 - for (d=0;d<12;d++) 6.65 - { 6.66 - if (ena[d]) 6.67 - { 6.68 - if (cmsstat[d]) p[c] +=(cmsvol[d][0]*90); 6.69 - if (cmsstat[d]) p[c+1]+=(cmsvol[d][1]*90); 6.70 - cmscount[d]+=cmsfreq[d]; 6.71 - if (cmscount[d]>=(22050)) 6.72 - { 6.73 - cmscount[d]-=(22050); 6.74 - cmsstat[d]^=1; 6.75 - } 6.76 - } 6.77 - else if (noiseena[d]) 6.78 - { 6.79 - if (cmsnoise[d/3]&1) p[c] +=(cmsvol[d][0]*90); 6.80 - if (cmsnoise[d/3]&1) p[c+1]+=(cmsvol[d][0]*90); 6.81 - } 6.82 - } 6.83 - for (d=0;d<4;d++) 6.84 - { 6.85 - cmsnoisecount[d]+=cmsnoisefreq[d]; 6.86 - while (cmsnoisecount[d]>=22050) 6.87 - { 6.88 - cmsnoisecount[d]-=22050; 6.89 - cmsnoise[d]<<=1; 6.90 - if (!(((cmsnoise[d]&0x4000)>>8)^(cmsnoise[d]&0x40))) cmsnoise[d]|=1; 6.91 - } 6.92 - } 6.93 - } 6.94 -} 6.95 - 6.96 -void writecms(uint16_t addr, uint8_t val) 6.97 -{ 6.98 - int voice; 6.99 - int chip=(addr&2)>>1; 6.100 - if (addr&1) 6.101 - cmsaddrs[chip]=val&31; 6.102 - else 6.103 - { 6.104 - cmsregs[chip][cmsaddrs[chip]&31]=val; 6.105 - switch (cmsaddrs[chip]&31) 6.106 - { 6.107 - case 0x00: case 0x01: case 0x02: /*Volume*/ 6.108 - case 0x03: case 0x04: case 0x05: 6.109 - voice=cmsaddrs[chip]&7; 6.110 - if (chip) voice+=6; 6.111 - cmsvol[voice][0]=val&0xF;//((val&0xF)+(val>>4))>>1; 6.112 - cmsvol[voice][1]=val>>4; 6.113 - break; 6.114 - case 0x08: case 0x09: case 0x0A: /*Frequency*/ 6.115 - case 0x0B: case 0x0C: case 0x0D: 6.116 - voice=cmsaddrs[chip]&7; 6.117 - if (chip) voice+=6; 6.118 - cmslatch[voice]=(cmslatch[voice]&0x700)|val; 6.119 - cmsfreq[voice]=(15625<<(cmslatch[voice]>>8))/(511-(cmslatch[voice]&255)); 6.120 - break; 6.121 - case 0x10: case 0x11: case 0x12: /*Octave*/ 6.122 - voice=(cmsaddrs[chip]&3)<<1; 6.123 - if (chip) voice+=6; 6.124 - cmslatch[voice]=(cmslatch[voice]&0xFF)|((val&7)<<8); 6.125 - cmslatch[voice+1]=(cmslatch[voice+1]&0xFF)|((val&0x70)<<4); 6.126 - cmsfreq[voice]=(15625<<(cmslatch[voice]>>8))/(511-(cmslatch[voice]&255)); 6.127 - cmsfreq[voice+1]=(15625<<(cmslatch[voice+1]>>8))/(511-(cmslatch[voice+1]&255)); 6.128 - break; 6.129 - case 0x16: /*Noise*/ 6.130 - voice=chip*2; 6.131 - cmsnoisetype[voice]=val&3; 6.132 - cmsnoisetype[voice+1]=(val>>4)&3; 6.133 - break; 6.134 - } 6.135 - } 6.136 -} 6.137 - 6.138 -uint8_t readcms(uint16_t addr) 6.139 -{ 6.140 - int chip=(addr&2)>>1; 6.141 - if (addr&1) return cmsaddrs[chip]; 6.142 - return cmsregs[chip][cmsaddrs[chip]&31]; 6.143 -} 6.144 -
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/device.c Mon May 27 19:56:33 2013 +0100 7.3 @@ -0,0 +1,59 @@ 7.4 +#include "ibm.h" 7.5 +#include "device.h" 7.6 + 7.7 +static void *device_priv[256]; 7.8 +static device_t *devices[256]; 7.9 + 7.10 +void device_init() 7.11 +{ 7.12 + memset(devices, 0, sizeof(devices)); 7.13 +} 7.14 + 7.15 +void device_add(device_t *d) 7.16 +{ 7.17 + int c = 0; 7.18 + void *priv; 7.19 + 7.20 + while (devices[c] != NULL && c < 256) 7.21 + c++; 7.22 + 7.23 + if (c >= 256) 7.24 + fatal("device_add : too many devices\n"); 7.25 + 7.26 + priv = d->init(); 7.27 + if (priv == NULL) 7.28 + fatal("device_add : device init failed\n"); 7.29 + 7.30 + devices[c] = d; 7.31 + device_priv[c] = priv; 7.32 +} 7.33 + 7.34 +void device_close_all() 7.35 +{ 7.36 + int c; 7.37 + 7.38 + for (c = 0; c < 256; c++) 7.39 + { 7.40 + if (devices[c] != NULL) 7.41 + { 7.42 + devices[c]->close(device_priv[c]); 7.43 + devices[c] = device_priv[c] = NULL; 7.44 + } 7.45 + } 7.46 +} 7.47 + 7.48 +void device_speed_changed() 7.49 +{ 7.50 + int c; 7.51 + 7.52 + for (c = 0; c < 256; c++) 7.53 + { 7.54 + if (devices[c] != NULL) 7.55 + { 7.56 + if (devices[c]->speed_changed != NULL) 7.57 + { 7.58 + devices[c]->speed_changed(device_priv[c]); 7.59 + } 7.60 + } 7.61 + } 7.62 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/device.h Mon May 27 19:56:33 2013 +0100 8.3 @@ -0,0 +1,12 @@ 8.4 +typedef struct device_t 8.5 +{ 8.6 + char name[50]; 8.7 + void *(*init)(); 8.8 + void (*close)(void *priv); 8.9 + void (*speed_changed)(void *priv); 8.10 +} device_t; 8.11 + 8.12 +void device_init(); 8.13 +void device_add(device_t *d); 8.14 +void device_close_all(); 8.15 +void device_speed_changed();
9.1 --- a/src/gus.c Mon May 27 17:46:42 2013 +0100 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,625 +0,0 @@ 9.4 -#include <stdio.h> 9.5 -#include <stdlib.h> 9.6 -#include <string.h> 9.7 -#include "ibm.h" 9.8 - 9.9 -extern int ins; 9.10 -extern int timetolive; 9.11 -int output; 9.12 -//#define GUSRATECONST (44100.0/48000.0) 9.13 -uint8_t *gusram; 9.14 - 9.15 -struct 9.16 -{ 9.17 - int global; 9.18 - uint32_t addr,dmaaddr; 9.19 - int voice; 9.20 - uint32_t start[32],end[32],cur[32]; 9.21 - uint32_t startx[32],endx[32],curx[32]; 9.22 - uint32_t rstart[32],rend[32],rcur[32]; 9.23 - uint16_t freq[32]; 9.24 - uint16_t rfreq[32]; 9.25 - uint8_t ctrl[32]; 9.26 - uint8_t rctrl[32]; 9.27 - int curvol[32]; 9.28 - int t1on,t2on; 9.29 - uint8_t tctrl; 9.30 - uint16_t t1,t2,t1l,t2l; 9.31 - uint8_t irqstatus,irqstatus2; 9.32 - uint8_t adcommand; 9.33 - int waveirqs[32],rampirqs[32]; 9.34 - int voices; 9.35 - uint8_t dmactrl; 9.36 -} gus; 9.37 - 9.38 -double vol16bit[4096]; 9.39 - 9.40 -void initgus() 9.41 -{ 9.42 - int c; 9.43 - for (c=0;c<32;c++) 9.44 - { 9.45 - gus.ctrl[c]=1; 9.46 - gus.rctrl[c]=1; 9.47 - gus.rfreq[c]=63*512; 9.48 - } 9.49 - gusram=malloc(1024*1024); 9.50 - 9.51 - double out = 1.0; 9.52 - for (c=4095;c>=0;c--) { 9.53 - vol16bit[c]=out;//(float)c/4095.0;//out; 9.54 - out/=1.002709201; /* 0.0235 dB Steps */ 9.55 - } 9.56 - 9.57 - printf("Top volume %f %f %f %f\n",vol16bit[4095],vol16bit[3800],vol16bit[3000],vol16bit[2048]); 9.58 - gus.voices=14; 9.59 - 9.60 -} 9.61 - 9.62 -void dumpgus() 9.63 -{ 9.64 -/* FILE *f=fopen("gusram.dmp","wb"); 9.65 - fwrite(gusram,1024*1024,1,f); 9.66 - fclose(f);*/ 9.67 -} 9.68 - 9.69 -void pollgusirqs() 9.70 -{ 9.71 - int c; 9.72 - gus.irqstatus&=~0x60; 9.73 - for (c=0;c<32;c++) 9.74 - { 9.75 - if (gus.waveirqs[c]) 9.76 - { 9.77 -// gus.waveirqs[c]=0; 9.78 - gus.irqstatus2=0x60|c; 9.79 - gus.irqstatus|=0x20; 9.80 -// printf("Voice IRQ %i %02X %i\n",c,gus.irqstatus2,ins); 9.81 - picintlevel(0x20); 9.82 -// output=3; 9.83 -// timetolive=5000; 9.84 - return; 9.85 - } 9.86 - if (gus.rampirqs[c]) 9.87 - { 9.88 -// gus.rampirqs[c]=0; 9.89 - gus.irqstatus2=0xA0|c; 9.90 - gus.irqstatus|=0x40; 9.91 -// printf("Ramp IRQ %i %02X %i\n",c,gus.irqstatus2,ins); 9.92 - picintlevel(0x20); 9.93 - return; 9.94 - } 9.95 - } 9.96 - gus.irqstatus2=0xE0; 9.97 -// gus.irqstatus&=~0x20; 9.98 - if (!gus.irqstatus) picintc(0x20); 9.99 -} 9.100 - 9.101 -int gusirqnext=0; 9.102 - 9.103 -void writegus(uint16_t addr, uint8_t val) 9.104 -{ 9.105 - int c,d; 9.106 -// printf("Write GUS %04X %02X %04X:%04X\n",addr,val,CS,pc); 9.107 - switch (addr) 9.108 - { 9.109 - case 0x342: /*Voice select*/ 9.110 - gus.voice=val&31; 9.111 - break; 9.112 - case 0x343: /*Global select*/ 9.113 - gus.global=val; 9.114 - break; 9.115 - case 0x344: /*Global low*/ 9.116 -// if (gus.global!=0x43 && gus.global!=0x44) printf("Writing register %02X %02X %02X\n",gus.global,gus.voice,val); 9.117 - switch (gus.global) 9.118 - { 9.119 - case 0: /*Voice control*/ 9.120 -// if (val&1 && !(gus.ctrl[gus.voice]&1)) printf("Voice on %i\n",gus.voice); 9.121 - gus.ctrl[gus.voice]=val; 9.122 - break; 9.123 - case 1: /*Frequency control*/ 9.124 - gus.freq[gus.voice]=(gus.freq[gus.voice]&0xFF00)|val; 9.125 - break; 9.126 - case 2: /*Start addr high*/ 9.127 - gus.startx[gus.voice]=(gus.startx[gus.voice]&0xF807F)|(val<<7); 9.128 - gus.start[gus.voice]=(gus.start[gus.voice]&0x1F00FFFF)|(val<<16); 9.129 -// printf("Write %i start %08X %08X\n",gus.voice,gus.start[gus.voice],gus.startx[gus.voice]); 9.130 - break; 9.131 - case 3: /*Start addr low*/ 9.132 - gus.start[gus.voice]=(gus.start[gus.voice]&0x1FFFFF00)|val; 9.133 -// printf("Write %i start %08X %08X\n",gus.voice,gus.start[gus.voice],gus.startx[gus.voice]); 9.134 - break; 9.135 - case 4: /*End addr high*/ 9.136 - gus.endx[gus.voice]=(gus.endx[gus.voice]&0xF807F)|(val<<7); 9.137 - gus.end[gus.voice]=(gus.end[gus.voice]&0x1F00FFFF)|(val<<16); 9.138 -// printf("Write %i end %08X %08X\n",gus.voice,gus.end[gus.voice],gus.endx[gus.voice]); 9.139 - break; 9.140 - case 5: /*End addr low*/ 9.141 - gus.end[gus.voice]=(gus.end[gus.voice]&0x1FFFFF00)|val; 9.142 -// printf("Write %i end %08X %08X\n",gus.voice,gus.end[gus.voice],gus.endx[gus.voice]); 9.143 - break; 9.144 - 9.145 - case 0x6: /*Ramp frequency*/ 9.146 - gus.rfreq[gus.voice] = (int)( (double)((val & 63)*512)/(double)(1 << (3*(val >> 6)))); 9.147 -// printf("RFREQ %02X %i %i %f\n",val,gus.voice,gus.rfreq[gus.voice],(double)(val & 63)/(double)(1 << (3*(val >> 6)))); 9.148 - break; 9.149 - 9.150 - case 0x9: /*Current volume*/ 9.151 - gus.curvol[gus.voice]=gus.rcur[gus.voice]=(gus.rcur[gus.voice]&0x1FE0000)|(val<<9); 9.152 -// printf("Vol %i is %04X\n",gus.voice,gus.curvol[gus.voice]); 9.153 - break; 9.154 - 9.155 - case 0xA: /*Current addr high*/ 9.156 - gus.cur[gus.voice]=(gus.cur[gus.voice]&0x1F00FFFF)|(val<<16); 9.157 -gus.curx[gus.voice]=(gus.curx[gus.voice]&0xF807F00)|((val<<7)<<8); 9.158 -// gus.cur[gus.voice]=(gus.cur[gus.voice]&0x0F807F00)|((val<<7)<<8); 9.159 -// printf("Write %i cur %08X\n",gus.voice,gus.cur[gus.voice],gus.curx[gus.voice]); 9.160 - break; 9.161 - case 0xB: /*Current addr low*/ 9.162 - gus.cur[gus.voice]=(gus.cur[gus.voice]&0x1FFFFF00)|val; 9.163 -// printf("Write %i cur %08X\n",gus.voice,gus.cur[gus.voice],gus.curx[gus.voice]); 9.164 - break; 9.165 - 9.166 - case 0x42: /*DMA address low*/ 9.167 - gus.dmaaddr=(gus.dmaaddr&0xFF000)|(val<<4); 9.168 - break; 9.169 - 9.170 - case 0x43: /*Address low*/ 9.171 - gus.addr=(gus.addr&0xFFF00)|val; 9.172 - break; 9.173 - case 0x45: /*Timer control*/ 9.174 -// printf("Timer control %02X\n",val); 9.175 - gus.tctrl=val; 9.176 - break; 9.177 - } 9.178 - break; 9.179 - case 0x345: /*Global high*/ 9.180 -// if (gus.global!=0x43 && gus.global!=0x44) printf("HWriting register %02X %02X %02X %04X:%04X\n",gus.global,gus.voice,val,CS,pc); 9.181 - switch (gus.global) 9.182 - { 9.183 - case 0: /*Voice control*/ 9.184 - if (!(val&1) && gus.ctrl[gus.voice]&1) 9.185 - { 9.186 -// printf("Voice on %i - start %05X end %05X freq %04X\n",gus.voice,gus.start[gus.voice],gus.end[gus.voice],gus.freq[gus.voice]); 9.187 -// if (val&0x40) gus.cur[gus.voice]=gus.end[gus.voice]<<8; 9.188 -// else gus.cur[gus.voice]=gus.start[gus.voice]<<8; 9.189 - } 9.190 - if (val&2) val|=1; 9.191 - gus.waveirqs[gus.voice]=val&0x80; 9.192 - gus.ctrl[gus.voice]=val&0x7F; 9.193 - pollgusirqs(); 9.194 - break; 9.195 - case 1: /*Frequency control*/ 9.196 - gus.freq[gus.voice]=(gus.freq[gus.voice]&0xFF)|(val<<8); 9.197 - break; 9.198 - case 2: /*Start addr high*/ 9.199 - gus.startx[gus.voice]=(gus.startx[gus.voice]&0x07FFF)|(val<<15); 9.200 - gus.start[gus.voice]=(gus.start[gus.voice]&0x00FFFFFF)|((val&0x1F)<<24); 9.201 -// printf("Write %i start %08X %08X %02X\n",gus.voice,gus.start[gus.voice],gus.startx[gus.voice],val); 9.202 - break; 9.203 - case 3: /*Start addr low*/ 9.204 - gus.startx[gus.voice]=(gus.startx[gus.voice]&0xFFF80)|(val&0x7F); 9.205 - gus.start[gus.voice]=(gus.start[gus.voice]&0x1FFF00FF)|(val<<8); 9.206 -// printf("Write %i start %08X %08X\n",gus.voice,gus.start[gus.voice],gus.startx[gus.voice]); 9.207 - break; 9.208 - case 4: /*End addr high*/ 9.209 - gus.endx[gus.voice]=(gus.endx[gus.voice]&0x07FFF)|(val<<15); 9.210 - gus.end[gus.voice]=(gus.end[gus.voice]&0x00FFFFFF)|((val&0x1F)<<24); 9.211 -// printf("Write %i end %08X %08X %02X\n",gus.voice,gus.end[gus.voice],gus.endx[gus.voice],val); 9.212 - break; 9.213 - case 5: /*End addr low*/ 9.214 - gus.endx[gus.voice]=(gus.endx[gus.voice]&0xFFF80)|(val&0x7F); 9.215 - gus.end[gus.voice]=(gus.end[gus.voice]&0x1FFF00FF)|(val<<8); 9.216 -// printf("Write %i end %08X %08X\n",gus.voice,gus.end[gus.voice],gus.endx[gus.voice]); 9.217 - break; 9.218 - 9.219 - case 0x6: /*Ramp frequency*/ 9.220 - gus.rfreq[gus.voice] = (int)( (double)((val & 63)*512)/(double)(1 << (3*(val >> 6)))); 9.221 -// printf("RFREQ %02X %i %i %f %i\n",val,gus.voice,gus.rfreq[gus.voice],(double)(val & 63)/(double)(1 << (3*(val >> 6))),ins); 9.222 - break; 9.223 - case 0x7: /*Ramp start*/ 9.224 - gus.rstart[gus.voice]=val<<17; 9.225 - break; 9.226 - case 0x8: /*Ramp end*/ 9.227 - gus.rend[gus.voice]=val<<17; 9.228 - break; 9.229 - case 0x9: /*Current volume*/ 9.230 - gus.curvol[gus.voice]=gus.rcur[gus.voice]=(gus.rcur[gus.voice]&0x1FE00)|(val<<17); 9.231 -// printf("Vol %i is %04X\n",gus.voice,gus.curvol[gus.voice]); 9.232 - break; 9.233 - 9.234 - case 0xA: /*Current addr high*/ 9.235 - gus.cur[gus.voice]=(gus.cur[gus.voice]&0x00FFFFFF)|((val&0x1F)<<24); 9.236 -gus.curx[gus.voice]=(gus.curx[gus.voice]&0x07FFF00)|((val<<15)<<8); 9.237 -// printf("Write %i cur %08X %08X %02X\n",gus.voice,gus.cur[gus.voice],gus.curx[gus.voice],val); 9.238 -// gus.cur[gus.voice]=(gus.cur[gus.voice]&0x007FFF00)|((val<<15)<<8); 9.239 - break; 9.240 - case 0xB: /*Current addr low*/ 9.241 - gus.cur[gus.voice]=(gus.cur[gus.voice]&0x1FFF00FF)|(val<<8); 9.242 -gus.curx[gus.voice]=(gus.curx[gus.voice]&0xFFF8000)|((val&0x7F)<<8); 9.243 -// gus.cur[gus.voice]=(gus.cur[gus.voice]&0x0FFF8000)|((val&0x7F)<<8); 9.244 -// printf("Write %i cur %08X %08X\n",gus.voice,gus.cur[gus.voice],gus.curx[gus.voice]); 9.245 - break; 9.246 - case 0xD: /*Ramp control*/ 9.247 - if (val&2) val|=1; 9.248 - gus.rampirqs[gus.voice]=val&0x80; 9.249 - gus.rctrl[gus.voice]=val&0x7F; 9.250 - pollgusirqs(); 9.251 -// printf("Ramp control %02i %02X %02X %i\n",gus.voice,val,gus.rampirqs[gus.voice],ins); 9.252 - break; 9.253 - 9.254 - case 0xE: 9.255 - gus.voices=(val&63)+1; 9.256 - if (gus.voices>32) gus.voices=32; 9.257 - if (gus.voices<14) gus.voices=14; 9.258 - gus.global=val; 9.259 -// printf("GUS voices %i\n",val&31); 9.260 - break; 9.261 - 9.262 - case 0x41: /*DMA*/ 9.263 - if (val&1) 9.264 - { 9.265 -// printf("DMA start! %05X %02X\n",gus.dmaaddr,val); 9.266 - c=0; 9.267 - while (c<65536) 9.268 - { 9.269 - d=readdma3(); 9.270 - if (d==-1) break; 9.271 - if (val&0x80) d^=0x80; 9.272 - gusram[gus.dmaaddr]=d; 9.273 - gus.dmaaddr++; 9.274 - gus.dmaaddr&=0xFFFFF; 9.275 - c++; 9.276 - } 9.277 -// printf("Transferred %i bytes\n",c); 9.278 - gus.dmactrl=val&~0x40; 9.279 - if (val&0x20) gusirqnext=1; 9.280 -// exit(-1); 9.281 - } 9.282 - break; 9.283 - 9.284 - case 0x42: /*DMA address low*/ 9.285 - gus.dmaaddr=(gus.dmaaddr&0xFF0)|(val<<12); 9.286 - break; 9.287 - 9.288 - case 0x43: /*Address low*/ 9.289 - gus.addr=(gus.addr&0xF00FF)|(val<<8); 9.290 - break; 9.291 - case 0x44: /*Address high*/ 9.292 - gus.addr=(gus.addr&0xFFFF)|((val<<16)&0xF0000); 9.293 - break; 9.294 - case 0x45: /*Timer control*/ 9.295 - if (!(val&4)) gus.irqstatus&=~4; 9.296 - if (!(val&8)) gus.irqstatus&=~8; 9.297 -// printf("Timer control %02X\n",val); 9.298 -/* if ((val&4) && !(gus.tctrl&4)) 9.299 - { 9.300 - gus.t1=gus.t1l; 9.301 - gus.t1on=1; 9.302 - }*/ 9.303 - gus.tctrl=val; 9.304 - break; 9.305 - case 0x46: /*Timer 1*/ 9.306 - gus.t1=gus.t1l=val; 9.307 - gus.t1on=1; 9.308 -// printf("GUS timer 1 %i\n",val); 9.309 - break; 9.310 - case 0x47: /*Timer 2*/ 9.311 - gus.t2=gus.t2l=val<<2; 9.312 - gus.t2on=1; 9.313 -// printf("GUS timer 2 %i\n",val); 9.314 - break; 9.315 - } 9.316 - break; 9.317 - case 0x347: /*DRAM access*/ 9.318 - gusram[gus.addr]=val; 9.319 -// pclog("GUS RAM write %05X %02X\n",gus.addr,val); 9.320 - gus.addr&=0xFFFFF; 9.321 - break; 9.322 - case 0x248: case 0x388: gus.adcommand=val; break; 9.323 - } 9.324 -} 9.325 - 9.326 -uint8_t readgus(uint16_t addr) 9.327 -{ 9.328 - uint8_t val; 9.329 -// /*if (addr!=0x246) */printf("Read GUS %04X %04X(%06X):%04X %02X\n",addr,CS,cs,pc,gus.global); 9.330 -// output=3; 9.331 - switch (addr) 9.332 - { 9.333 - case 0x240: return 0; 9.334 - case 0x246: /*IRQ status*/ 9.335 - val=gus.irqstatus; 9.336 -// printf("246 status %02X\n",val); 9.337 -// gus.irqstatus=0; 9.338 -// if (gus.irqstatus2==0xE0) picintc(0x20); 9.339 - return val; 9.340 - case 0x24A: 9.341 - return gus.adcommand; 9.342 - case 0x24B: case 0x24F: return 0; 9.343 - case 0x340: /*MIDI status*/ 9.344 - case 0x341: /*MIDI data*/ 9.345 - return 0; 9.346 - case 0x342: return gus.voice; 9.347 - case 0x343: return gus.global; 9.348 - case 0x344: /*Global low*/ 9.349 -// /*if (gus.global!=0x43 && gus.global!=0x44) */printf("Reading register %02X %02X\n",gus.global,gus.voice); 9.350 - switch (gus.global) 9.351 - { 9.352 - case 0x82: /*Start addr high*/ 9.353 - return gus.start[gus.voice]>>16; 9.354 - case 0x83: /*Start addr low*/ 9.355 - return gus.start[gus.voice]&0xFF; 9.356 - 9.357 - case 0x89: /*Current volume*/ 9.358 - return gus.rcur[gus.voice]>>9; 9.359 - case 0x8A: /*Current addr high*/ 9.360 - return gus.cur[gus.voice]>>16; 9.361 - case 0x8B: /*Current addr low*/ 9.362 - return gus.cur[gus.voice]&0xFF; 9.363 - 9.364 - case 0x8F: /*IRQ status*/ 9.365 - val=gus.irqstatus2; 9.366 -// pclog("Read IRQ status - %02X\n",val); 9.367 - gus.rampirqs[gus.irqstatus2&0x1F]=0; 9.368 - gus.waveirqs[gus.irqstatus2&0x1F]=0; 9.369 - pollgusirqs(); 9.370 - return val; 9.371 - } 9.372 - //fatal("Bad GUS global low read %02X\n",gus.global); 9.373 - break; 9.374 - case 0x345: /*Global high*/ 9.375 -// /*if (gus.global!=0x43 && gus.global!=0x44) */printf("HReading register %02X %02X\n",gus.global,gus.voice); 9.376 - switch (gus.global) 9.377 - { 9.378 - case 0x80: /*Voice control*/ 9.379 - return gus.ctrl[gus.voice]|(gus.waveirqs[gus.voice]?0x80:0); 9.380 - 9.381 - case 0x82: /*Start addr high*/ 9.382 - return gus.start[gus.voice]>>24; 9.383 - case 0x83: /*Start addr low*/ 9.384 - return gus.start[gus.voice]>>8; 9.385 - 9.386 - case 0x89: /*Current volume*/ 9.387 - return gus.rcur[gus.voice]>>17; 9.388 - 9.389 - case 0x8A: /*Current addr high*/ 9.390 - return gus.cur[gus.voice]>>24; 9.391 - case 0x8B: /*Current addr low*/ 9.392 - return gus.cur[gus.voice]>>8; 9.393 - 9.394 - case 0x8D: 9.395 -// pclog("Read ramp control %02X %08X %08X %08X %08X\n",gus.rctrl[gus.voice]|(gus.rampirqs[gus.voice]?0x80:0),gus.rcur[gus.voice],gus.rfreq[gus.voice],gus.rstart[gus.voice],gus.rend[gus.voice]); 9.396 - return gus.rctrl[gus.voice]|(gus.rampirqs[gus.voice]?0x80:0); 9.397 - 9.398 - case 0x8F: /*IRQ status*/ 9.399 - val=gus.irqstatus2; 9.400 -// pclog("Read IRQ status - %02X\n",val); 9.401 - gus.rampirqs[gus.irqstatus2&0x1F]=0; 9.402 - gus.waveirqs[gus.irqstatus2&0x1F]=0; 9.403 - pollgusirqs(); 9.404 - return val; 9.405 - 9.406 - case 0x41: /*DMA control*/ 9.407 - val=gus.dmactrl|((gus.irqstatus&0x80)?0x40:0); 9.408 - gus.irqstatus&=~0x80; 9.409 - return val; 9.410 - case 0x45: /*Timer control*/ 9.411 - return gus.tctrl; 9.412 - case 0x49: /*Sampling control*/ 9.413 - return 0; 9.414 - } 9.415 - //fatal("Bad GUS global high read %02X\n",gus.global); 9.416 - break; 9.417 - case 0x346: return 0; 9.418 - case 0x347: /*DRAM access*/ 9.419 - val=gusram[gus.addr]; 9.420 -// pclog("GUS RAM read %05X %02X\n",gus.addr,val); 9.421 -// output=3; 9.422 - gus.addr&=0xFFFFF; 9.423 - return val; 9.424 - case 0x349: return 0; 9.425 - } 9.426 -// printf("Bad GUS read %04X! %02X\n",addr,gus.global); 9.427 -// exit(-1); 9.428 - return 0; 9.429 -} 9.430 - 9.431 -void pollgus() 9.432 -{ 9.433 - if (gus.t1on) 9.434 - { 9.435 - gus.t1++; 9.436 - if (gus.t1>=0xFF) 9.437 - { 9.438 -// gus.t1on=0; 9.439 - gus.t1=gus.t1l; 9.440 - if (gus.tctrl&4) 9.441 - { 9.442 - picintlevel(0x20); 9.443 - gus.irqstatus|=4; 9.444 -// printf("GUS T1 IRQ!\n"); 9.445 - } 9.446 - } 9.447 - } 9.448 - if (gusirqnext) 9.449 - { 9.450 - gusirqnext=0; 9.451 - gus.irqstatus|=0x80; 9.452 - picintlevel(0x20); 9.453 - } 9.454 -} 9.455 - 9.456 -void pollgus2() 9.457 -{ 9.458 - if (gus.t2on) 9.459 - { 9.460 - gus.t2++; 9.461 - if (gus.t2>=(0xFF<<2)) 9.462 - { 9.463 -// gus.t2on=0; 9.464 - gus.t2=gus.t2l; 9.465 - if (gus.tctrl&8) 9.466 - { 9.467 - picintlevel(0x20); 9.468 - gus.irqstatus|=8; 9.469 -// printf("GUS T2 IRQ!\n"); 9.470 - } 9.471 - } 9.472 - } 9.473 - if (gusirqnext) 9.474 - { 9.475 - gusirqnext=0; 9.476 - gus.irqstatus|=0x80; 9.477 - picintlevel(0x20); 9.478 - } 9.479 -} 9.480 - 9.481 -float gusfreqs[]= 9.482 -{ 9.483 - 44100,41160,38587,36317,34300,32494,30870,29400,28063,26843,25725,24696, 9.484 - 23746,22866,22050,21289,20580,19916,19293 9.485 -}; 9.486 - 9.487 -int16_t gusbufferx[65536]; 9.488 -int guspos=0; 9.489 -void getgus(int16_t *p, int count) 9.490 -{ 9.491 - memcpy(p,gusbufferx,count*4); 9.492 -// printf("Get %i samples %i\n",guspos,count); 9.493 - guspos=0; 9.494 - pollgusirqs(); 9.495 -} 9.496 - 9.497 -void pollgussamp() 9.498 -{ 9.499 - uint32_t addr; 9.500 - int c,d; 9.501 - int16_t v; 9.502 - int32_t vl; 9.503 - int16_t p[2]; 9.504 - float GUSRATECONST; 9.505 - if (guspos>65500) return; 9.506 -// return; 9.507 - if (gus.voices<14) GUSRATECONST=44100.0/48000.0; 9.508 - else GUSRATECONST=gusfreqs[gus.voices-14]/48000.0; 9.509 -// printf("Voices %i freq %f\n",gus.voices,GUSRATECONST*48000.0); 9.510 -// for (c=0;c<count;c++) 9.511 -// { 9.512 - p[0]=p[1]=0; 9.513 - for (d=0;d<32;d++) 9.514 - { 9.515 - if (!(gus.ctrl[d]&1)) 9.516 - { 9.517 - if (gus.ctrl[d]&4) 9.518 - { 9.519 - addr=gus.cur[d]>>9; 9.520 - addr=(addr&0xC0000)|((addr<<1)&0x3FFFE); 9.521 - if (!(gus.freq[d]>>10)) /*Interpolate*/ 9.522 - { 9.523 - vl=(int16_t)(int8_t)((gusram[(addr+1)&0xFFFFF]^0x80)-0x80)*(511-(gus.cur[d]&511)); 9.524 - vl+=(int16_t)(int8_t)((gusram[(addr+3)&0xFFFFF]^0x80)-0x80)*(gus.cur[d]&511); 9.525 - v=vl>>9; 9.526 - } 9.527 - else 9.528 - v=(int16_t)(int8_t)((gusram[(addr+1)&0xFFFFF]^0x80)-0x80); 9.529 - } 9.530 - else 9.531 - { 9.532 - if (!(gus.freq[d]>>10)) /*Interpolate*/ 9.533 - { 9.534 - vl=((int8_t)((gusram[(gus.cur[d]>>9)&0xFFFFF]^0x80)-0x80))*(511-(gus.cur[d]&511)); 9.535 - vl+=((int8_t)((gusram[((gus.cur[d]>>9)+1)&0xFFFFF]^0x80)-0x80))*(gus.cur[d]&511); 9.536 - v=vl>>9; 9.537 - } 9.538 - else 9.539 - v=(int16_t)(int8_t)((gusram[(gus.cur[d]>>9)&0xFFFFF]^0x80)-0x80); 9.540 - } 9.541 -// v=(int16_t)((float)((gusram[(gus.cur[d]>>9)&0xFFFFF]^0x80)-0x80)*32.0*vol16bit[(gus.rcur[d]>>13)&4095]); 9.542 - if ((gus.rcur[d]>>13)>4095) v=(int16_t)(float)(v)*24.0*vol16bit[4095]; 9.543 - else v=(int16_t)(float)(v)*24.0*vol16bit[(gus.rcur[d]>>13)&4095]; 9.544 -// if (!d) printf("%08X %08X %08X %05X %08X %08X %04X %f %04X %08X %i\n",gus.cur[d],gus.start[d],gus.end[d],gus.cur[d]>>9,gus.startx[d],gus.endx[d],gus.rcur[d],vol16bit[0],v,gus.freq[d],ins); 9.545 -// if (!d) 9.546 -// { 9.547 - p[0]+=v; 9.548 - p[1]+=v; 9.549 -// } 9.550 -// printf("Data from %08X\n",gus.cur[d]>>8); 9.551 - if (gus.ctrl[d]&0x40) 9.552 - { 9.553 - gus.cur[d]-=(gus.freq[d]>>1)*GUSRATECONST; 9.554 - if (gus.cur[d]<=gus.start[d]) 9.555 - { 9.556 - if (!(gus.rctrl[d]&4)) 9.557 - { 9.558 - if (!(gus.ctrl[d]&8)) gus.ctrl[d]|=1; 9.559 - else if (gus.ctrl[d]&0x10) gus.ctrl[d]^=0x40; 9.560 - gus.cur[d]=(gus.ctrl[d]&0x40)?gus.end[d]:gus.start[d]; 9.561 - } 9.562 - if (gus.ctrl[d]&0x20) gus.waveirqs[d]=1; 9.563 - } 9.564 - } 9.565 - else 9.566 - { 9.567 - gus.cur[d]+=(gus.freq[d]>>1)*GUSRATECONST; 9.568 -// pclog("GUS add %08X %f\n",gus.freq[d],GUSRATECONST); 9.569 - if (gus.cur[d]>=gus.end[d]) 9.570 - { 9.571 - if (!(gus.rctrl[d]&4)) 9.572 - { 9.573 -// gus.ctrl[d]|=1; 9.574 - if (!(gus.ctrl[d]&8)) gus.ctrl[d]|=1; 9.575 - else if (gus.ctrl[d]&0x10) gus.ctrl[d]^=0x40; 9.576 - gus.cur[d]=(gus.ctrl[d]&0x40)?gus.end[d]:gus.start[d]; 9.577 - } 9.578 - if (gus.ctrl[d]&0x20) gus.waveirqs[d]=1; 9.579 - } 9.580 - } 9.581 - } 9.582 - if (!(gus.rctrl[d]&1)) 9.583 - { 9.584 - if (gus.rctrl[d]&0x40) 9.585 - { 9.586 - gus.rcur[d]-=gus.rfreq[d]*GUSRATECONST*16; 9.587 -// printf("RCUR- %i %i %i %i %i\n",d,gus.rfreq[d],gus.rcur[d],gus.rstart[d],gus.rend[d]); 9.588 - if (gus.rcur[d]<=gus.rstart[d]) 9.589 - { 9.590 - if (gus.rctrl[d]&8) gus.rcur[d]=gus.rend[d]<<8; 9.591 - else gus.rctrl[d]|=1; 9.592 - if (gus.rctrl[d]&0x20) 9.593 - { 9.594 - gus.rampirqs[d]=1; 9.595 -// pclog("Causing ramp IRQ %02X\n",gus.rctrl[d]); 9.596 - } 9.597 - } 9.598 - } 9.599 - else 9.600 - { 9.601 - gus.rcur[d]+=gus.rfreq[d]*GUSRATECONST*16; 9.602 -// printf("RCUR+ %i %08X %08X %08X %08X\n",d,gus.rfreq[d],gus.rcur[d],gus.rstart[d],gus.rend[d]); 9.603 - if (gus.rcur[d]>=gus.rend[d]) 9.604 - { 9.605 - if (gus.rctrl[d]&8) gus.rcur[d]=gus.rstart[d]<<8; 9.606 - else gus.rctrl[d]|=1; 9.607 - if (gus.rctrl[d]&0x20) 9.608 - { 9.609 - gus.rampirqs[d]=1; 9.610 -// pclog("Causing ramp IRQ %02X\n",gus.rctrl[d]); 9.611 - } 9.612 - } 9.613 - } 9.614 - } 9.615 - } 9.616 - gusbufferx[guspos++]=p[0]; 9.617 - gusbufferx[guspos++]=p[1]; 9.618 - if (guspos==65536) guspos=0; 9.619 -// } 9.620 - pollgusirqs(); 9.621 -} 9.622 - 9.623 -void gus_init() 9.624 -{ 9.625 - io_sethandler(0x0240, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL); 9.626 - io_sethandler(0x0340, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL); 9.627 - io_sethandler(0x0388, 0x0001, NULL, NULL, NULL, writegus, NULL, NULL); 9.628 -}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/i430vx.c Mon May 27 19:56:33 2013 +0100 10.3 @@ -0,0 +1,96 @@ 10.4 +#include <string.h> 10.5 + 10.6 +#include "ibm.h" 10.7 +#include "io.h" 10.8 +#include "mem.h" 10.9 +#include "pci.h" 10.10 + 10.11 +#include "i430vx.h" 10.12 + 10.13 +static uint8_t card_i430vx[256]; 10.14 + 10.15 +static void i430vx_map(uint32_t addr, uint32_t size, int state) 10.16 +{ 10.17 + switch (state & 3) 10.18 + { 10.19 + case 0x0: mem_sethandler(addr, size, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL , NULL); break; /*DRAM disabled, accesses directed to PCI bus*/ 10.20 + case 0x1: mem_sethandler(addr, size, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL , NULL); break; /*Read only, DRAM write protected, non-cacheable*/ 10.21 + case 0x2: mem_sethandler(addr, size, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break; /*Write only*/ 10.22 + case 0x3: mem_sethandler(addr, size, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break; /*Read/write, non-cacheable*/ 10.23 + /*Below are redundant*/ 10.24 +// case 0x5: mem_sethandler(addr, size, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL ); break; /*Read only, DRAM write protected, cacheable*/ 10.25 +// case 0x7: mem_sethandler(addr, size, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); break; /*Read/write, non-cacheable*/ 10.26 + } 10.27 + flushmmucache_nopc(); 10.28 +} 10.29 +void i430vx_write(int func, int addr, uint8_t val, void *priv) 10.30 +{ 10.31 + if (func) 10.32 + return; 10.33 + 10.34 + switch (addr) 10.35 + { 10.36 + case 0x00: case 0x01: case 0x02: case 0x03: 10.37 + case 0x08: case 0x09: case 0x0a: case 0x0b: 10.38 + case 0x0e: 10.39 + return; 10.40 + 10.41 + case 0x59: /*PAM0*/ 10.42 + if ((card_i430vx[0x59] ^ val) & 0xf0) 10.43 + { 10.44 + i430vx_map(0xf0000, 0x10000, val >> 4); 10.45 + shadowbios = (val & 0x10); 10.46 + } 10.47 + pclog("i430vx_write : PAM0 write %02X\n", val); 10.48 + break; 10.49 + case 0x5e: /*PAM5*/ 10.50 + if ((card_i430vx[0x5e] ^ val) & 0x0f) 10.51 + i430vx_map(0xe0000, 0x04000, val & 0xf); 10.52 + if ((card_i430vx[0x5e] ^ val) & 0xf0) 10.53 + i430vx_map(0xe4000, 0x04000, val >> 4); 10.54 + pclog("i430vx_write : PAM5 write %02X\n", val); 10.55 + break; 10.56 + case 0x5f: /*PAM6*/ 10.57 + if ((card_i430vx[0x5f] ^ val) & 0x0f) 10.58 + i430vx_map(0xe8000, 0x04000, val & 0xf); 10.59 + if ((card_i430vx[0x5f] ^ val) & 0xf0) 10.60 + i430vx_map(0xec000, 0x04000, val >> 4); 10.61 + pclog("i430vx_write : PAM6 write %02X\n", val); 10.62 + break; 10.63 + } 10.64 + 10.65 + card_i430vx[addr] = val; 10.66 +} 10.67 + 10.68 +uint8_t i430vx_read(int func, int addr, void *priv) 10.69 +{ 10.70 + if (func) 10.71 + return 0xff; 10.72 + 10.73 + return card_i430vx[addr]; 10.74 +} 10.75 + 10.76 + 10.77 +void i430vx_init() 10.78 +{ 10.79 + pci_add_specific(0, i430vx_read, i430vx_write, NULL); 10.80 + 10.81 + memset(card_i430vx, 0, 256); 10.82 + card_i430vx[0x00] = 0x86; card_i430vx[0x01] = 0x80; /*Intel*/ 10.83 + card_i430vx[0x02] = 0x30; card_i430vx[0x03] = 0x70; /*82437VX*/ 10.84 + card_i430vx[0x04] = 0x06; card_i430vx[0x05] = 0x00; 10.85 + card_i430vx[0x06] = 0x00; card_i430vx[0x07] = 0x02; 10.86 + card_i430vx[0x08] = 0x00; /*A0 stepping*/ 10.87 + card_i430vx[0x09] = 0x00; card_i430vx[0x0a] = 0x00; card_i430vx[0x0b] = 0x06; 10.88 + card_i430vx[0x52] = 0x42; /*256kb PLB cache*/ 10.89 + card_i430vx[0x53] = 0x14; 10.90 + card_i430vx[0x56] = 0x52; /*DRAM control*/ 10.91 + card_i430vx[0x57] = 0x01; 10.92 + card_i430vx[0x60] = card_i430vx[0x61] = card_i430vx[0x62] = card_i430vx[0x63] = card_i430vx[0x64] = 0x02; 10.93 + card_i430vx[0x67] = 0x11; 10.94 + card_i430vx[0x69] = 0x03; 10.95 + card_i430vx[0x70] = 0x20; 10.96 + card_i430vx[0x72] = 0x02; 10.97 + card_i430vx[0x74] = 0x0e; 10.98 + card_i430vx[0x78] = 0x23; 10.99 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/i430vx.h Mon May 27 19:56:33 2013 +0100 11.3 @@ -0,0 +1,1 @@ 11.4 +void i430vx_init();
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/piix.c Mon May 27 19:56:33 2013 +0100 12.3 @@ -0,0 +1,303 @@ 12.4 +/*PRD format : 12.5 + 12.6 + word 0 - base address 12.7 + word 1 - bits 1 - 15 = byte count, bit 31 = end of transfer 12.8 +*/ 12.9 +#include <string.h> 12.10 + 12.11 +#include "ibm.h" 12.12 +#include "ide.h" 12.13 +#include "io.h" 12.14 +#include "pci.h" 12.15 + 12.16 +#include "piix.h" 12.17 + 12.18 +uint8_t piix_bus_master_read(uint16_t port, void *priv); 12.19 +void piix_bus_master_write(uint16_t port, uint8_t val, void *priv); 12.20 + 12.21 +static uint8_t card_piix[256], card_piix_ide[256]; 12.22 + 12.23 +void piix_write(int func, int addr, uint8_t val, void *priv) 12.24 +{ 12.25 + if (func > 1) 12.26 + return; 12.27 + 12.28 + if (func == 1) /*IDE*/ 12.29 + { 12.30 + switch (addr) 12.31 + { 12.32 + case 0x00: case 0x01: case 0x02: case 0x03: 12.33 + case 0x08: case 0x09: case 0x0a: case 0x0b: 12.34 + case 0x0e: 12.35 + return; 12.36 + case 0x20: 12.37 + val |= 1; 12.38 + break; 12.39 + case 0x41: 12.40 + if ((val ^ card_piix_ide[0x41]) & 0x80) 12.41 + { 12.42 + if (val & 0x80) 12.43 + ide_pri_enable(); 12.44 + else 12.45 + ide_pri_disable(); 12.46 + } 12.47 + break; 12.48 + case 0x43: 12.49 + if ((val ^ card_piix_ide[0x43]) & 0x80) 12.50 + { 12.51 + if (val & 0x80) 12.52 + ide_sec_enable(); 12.53 + else 12.54 + ide_sec_disable(); 12.55 + } 12.56 + break; 12.57 + } 12.58 + card_piix_ide[addr] = val; 12.59 + if ((addr & ~3) == 0x20) /*Bus master base address*/ 12.60 + { 12.61 + uint16_t base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); 12.62 + io_removehandler(0, 0x10000, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); 12.63 + io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); 12.64 + } 12.65 +// pclog("PIIX write %02X %02X\n", addr, val); 12.66 + } 12.67 + else 12.68 + { 12.69 + switch (addr) 12.70 + { 12.71 + case 0x00: case 0x01: case 0x02: case 0x03: 12.72 + case 0x08: case 0x09: case 0x0a: case 0x0b: 12.73 + case 0x0e: 12.74 + return; 12.75 + } 12.76 + card_piix[addr] = val; 12.77 + } 12.78 +} 12.79 + 12.80 +uint8_t piix_read(int func, int addr, void *priv) 12.81 +{ 12.82 + if (func > 1) 12.83 + return 0xff; 12.84 + 12.85 + if (func == 1) /*IDE*/ 12.86 + { 12.87 +// pclog("PIIX IDE read %02X %02X\n", addr, card_piix_ide[addr]); 12.88 + return card_piix_ide[addr]; 12.89 + } 12.90 + else 12.91 + return card_piix[addr]; 12.92 +} 12.93 + 12.94 +struct 12.95 +{ 12.96 + uint8_t command; 12.97 + uint8_t status; 12.98 + uint32_t ptr, ptr_cur; 12.99 + int count; 12.100 + uint32_t addr; 12.101 + int eot; 12.102 +} piix_busmaster[2]; 12.103 + 12.104 +static void piix_bus_master_next_addr(int channel) 12.105 +{ 12.106 + piix_busmaster[channel].addr = (*(unsigned long *)(&ram[piix_busmaster[channel].ptr_cur])) & ~1; 12.107 + piix_busmaster[channel].count = (*(unsigned long *)(&ram[piix_busmaster[channel].ptr_cur + 4])) & 0xfffe; 12.108 + piix_busmaster[channel].eot = (*(unsigned long *)(&ram[piix_busmaster[channel].ptr_cur + 4])) >> 31; 12.109 + piix_busmaster[channel].ptr_cur += 8; 12.110 +// pclog("New DMA settings on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); 12.111 +} 12.112 + 12.113 +void piix_bus_master_write(uint16_t port, uint8_t val, void *priv) 12.114 +{ 12.115 + int channel = (port & 8) ? 1 : 0; 12.116 +// pclog("PIIX Bus Master write %04X %02X\n", port, val); 12.117 + switch (port & 7) 12.118 + { 12.119 + case 0: 12.120 + if ((val & 1) && !(piix_busmaster[channel].command & 1)) /*Start*/ 12.121 + { 12.122 + piix_busmaster[channel].ptr_cur = piix_busmaster[channel].ptr; 12.123 + piix_bus_master_next_addr(channel); 12.124 + piix_busmaster[channel].status |= 1; 12.125 + } 12.126 + if (!(val & 1) && (piix_busmaster[channel].command & 1)) /*Stop*/ 12.127 + piix_busmaster[channel].status &= ~1; 12.128 + 12.129 + piix_busmaster[channel].command = val; 12.130 + break; 12.131 + case 2: 12.132 + piix_busmaster[channel].status = (val & 0x60) | ((piix_busmaster[channel].status & ~val) & 6) | (piix_busmaster[channel].status & 1); 12.133 + break; 12.134 + case 4: 12.135 + piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xffffff00) | val; 12.136 + break; 12.137 + case 5: 12.138 + piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xffff00ff) | (val << 8); 12.139 + break; 12.140 + case 6: 12.141 + piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xff00ffff) | (val << 16); 12.142 + break; 12.143 + case 7: 12.144 + piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0x00ffffff) | (val << 24); 12.145 + break; 12.146 + } 12.147 +} 12.148 + 12.149 +uint8_t piix_bus_master_read(uint16_t port, void *priv) 12.150 +{ 12.151 + int channel = (port & 8) ? 1 : 0; 12.152 + switch (port & 7) 12.153 + { 12.154 + case 0: 12.155 + return piix_busmaster[channel].command; 12.156 + case 2: 12.157 + return piix_busmaster[channel].status; 12.158 + case 4: 12.159 + return piix_busmaster[channel].ptr; 12.160 + case 5: 12.161 + return piix_busmaster[channel].ptr >> 8; 12.162 + case 6: 12.163 + return piix_busmaster[channel].ptr >> 16; 12.164 + case 7: 12.165 + return piix_busmaster[channel].ptr >> 24; 12.166 + } 12.167 + return 0xff; 12.168 +} 12.169 + 12.170 +int piix_bus_master_sector_read(int channel, uint8_t *data) 12.171 +{ 12.172 + int transferred = 0; 12.173 + 12.174 + if (!(piix_busmaster[channel].status & 1)) 12.175 + return 1; /*DMA disabled*/ 12.176 + 12.177 + while (transferred < 512) 12.178 + { 12.179 + if (piix_busmaster[channel].count < (512 - transferred) && piix_busmaster[channel].eot) 12.180 + fatal("DMA on channel %i - Read count less than 512! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); 12.181 + 12.182 + if (piix_busmaster[channel].count < (512 - transferred)) 12.183 + { 12.184 +// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); 12.185 + memcpy(&ram[piix_busmaster[channel].addr], data + transferred, piix_busmaster[channel].count); 12.186 + transferred += piix_busmaster[channel].count; 12.187 + piix_busmaster[channel].addr += piix_busmaster[channel].count; 12.188 + piix_busmaster[channel].count = 0; 12.189 + } 12.190 + else 12.191 + { 12.192 +// pclog("Transferring larger - %i bytes\n", 512 - transferred); 12.193 + memcpy(&ram[piix_busmaster[channel].addr], data + transferred, 512 - transferred); 12.194 + piix_busmaster[channel].addr += (512 - transferred); 12.195 + piix_busmaster[channel].count -= (512 - transferred); 12.196 + transferred += (512 - transferred); 12.197 + } 12.198 + 12.199 +// pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); 12.200 + 12.201 + if (!piix_busmaster[channel].count) 12.202 + { 12.203 +// pclog("DMA on channel %i - block over\n", channel); 12.204 + if (piix_busmaster[channel].eot) /*End of transfer?*/ 12.205 + { 12.206 +// pclog("DMA on channel %i - transfer over\n", channel); 12.207 + piix_busmaster[channel].status &= ~1; 12.208 + } 12.209 + else 12.210 + piix_bus_master_next_addr(channel); 12.211 + } 12.212 + } 12.213 + return 0; 12.214 +} 12.215 +int piix_bus_master_sector_write(int channel, uint8_t *data) 12.216 +{ 12.217 + int transferred = 0; 12.218 + 12.219 + if (!(piix_busmaster[channel].status & 1)) 12.220 + return 1; /*DMA disabled*/ 12.221 + 12.222 + while (transferred < 512) 12.223 + { 12.224 + if (piix_busmaster[channel].count < (512 - transferred) && piix_busmaster[channel].eot) 12.225 + fatal("DMA on channel %i - Write count less than 512! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); 12.226 + 12.227 + if (piix_busmaster[channel].count < (512 - transferred)) 12.228 + { 12.229 +// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); 12.230 + memcpy(data + transferred, &ram[piix_busmaster[channel].addr], piix_busmaster[channel].count); 12.231 + transferred += piix_busmaster[channel].count; 12.232 + piix_busmaster[channel].addr += piix_busmaster[channel].count; 12.233 + piix_busmaster[channel].count = 0; 12.234 + } 12.235 + else 12.236 + { 12.237 +// pclog("Transferring larger - %i bytes\n", 512 - transferred); 12.238 + memcpy(data + transferred, &ram[piix_busmaster[channel].addr], 512 - transferred); 12.239 + piix_busmaster[channel].addr += (512 - transferred); 12.240 + piix_busmaster[channel].count -= (512 - transferred); 12.241 + transferred += (512 - transferred); 12.242 + } 12.243 + 12.244 +// pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); 12.245 + 12.246 + if (!piix_busmaster[channel].count) 12.247 + { 12.248 +// pclog("DMA on channel %i - block over\n", channel); 12.249 + if (piix_busmaster[channel].eot) /*End of transfer?*/ 12.250 + { 12.251 +// pclog("DMA on channel %i - transfer over\n", channel); 12.252 + piix_busmaster[channel].status &= ~1; 12.253 + } 12.254 + else 12.255 + piix_bus_master_next_addr(channel); 12.256 + } 12.257 + } 12.258 + return 0; 12.259 +} 12.260 + 12.261 +void piix_bus_master_set_irq(int channel) 12.262 +{ 12.263 + piix_busmaster[channel].status |= 4; 12.264 +} 12.265 + 12.266 +void piix_init(int card) 12.267 +{ 12.268 + pci_add_specific(card, piix_read, piix_write, NULL); 12.269 + 12.270 + memset(card_piix, 0, 256); 12.271 + card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/ 12.272 + card_piix[0x02] = 0x2e; card_piix[0x03] = 0x12; /*82371FB (PIIX)*/ 12.273 + card_piix[0x04] = 0x07; card_piix[0x05] = 0x00; 12.274 + card_piix[0x06] = 0x00; card_piix[0x07] = 0x02; 12.275 + card_piix[0x08] = 0x00; /*A0 stepping*/ 12.276 + card_piix[0x09] = 0x00; card_piix[0x0a] = 0x01; card_piix[0x0b] = 0x06; 12.277 + card_piix[0x0e] = 0x80; /*Multi-function device*/ 12.278 + card_piix[0x4c] = 0x4d; 12.279 + card_piix[0x4e] = 0x03; 12.280 + card_piix[0x60] = card_piix[0x61] = card_piix[0x62] = card_piix[0x63] = 0x80; 12.281 + card_piix[0x69] = 0x02; 12.282 + card_piix[0x70] = card_piix[0x71] = 0x80; 12.283 + card_piix[0x76] = card_piix[0x77] = 0x0c; 12.284 + card_piix[0x78] = 0x02; card_piix[0x79] = 0x00; 12.285 + card_piix[0xa0] = 0x08; 12.286 + card_piix[0xa2] = card_piix[0xa3] = 0x00; 12.287 + card_piix[0xa4] = card_piix[0xa5] = card_piix[0xa6] = card_piix[0xa7] = 0x00; 12.288 + card_piix[0xa8] = 0x0f; 12.289 + card_piix[0xaa] = card_piix[0xab] = 0x00; 12.290 + card_piix[0xac] = 0x00; 12.291 + card_piix[0xae] = 0x00; 12.292 + 12.293 + card_piix_ide[0x00] = 0x86; card_piix_ide[0x01] = 0x80; /*Intel*/ 12.294 + card_piix_ide[0x02] = 0x30; card_piix_ide[0x03] = 0x12; /*82371FB (PIIX)*/ 12.295 + card_piix_ide[0x04] = 0x00; card_piix_ide[0x05] = 0x00; 12.296 + card_piix_ide[0x06] = 0x80; card_piix_ide[0x07] = 0x02; 12.297 + card_piix_ide[0x08] = 0x00; 12.298 + card_piix_ide[0x09] = 0x80; card_piix_ide[0x0a] = 0x01; card_piix_ide[0x0b] = 0x01; 12.299 + card_piix_ide[0x0d] = 0x00; 12.300 + card_piix_ide[0x0e] = 0x00; 12.301 + card_piix_ide[0x20] = 0x01; card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/ 12.302 + card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00; 12.303 + card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; 12.304 + 12.305 + ide_set_bus_master(piix_bus_master_sector_read, piix_bus_master_sector_write, piix_bus_master_set_irq); 12.306 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/src/piix.h Mon May 27 19:56:33 2013 +0100 13.3 @@ -0,0 +1,1 @@ 13.4 +void piix_init(int card);
14.1 --- a/src/ppi.h Mon May 27 17:46:42 2013 +0100 14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 14.3 @@ -1,1 +0,0 @@ 14.4 -extern int wasgated;
15.1 --- a/src/psg.c Mon May 27 17:46:42 2013 +0100 15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 15.3 @@ -1,206 +0,0 @@ 15.4 -#include "ibm.h" 15.5 - 15.6 -float volslog[16]= 15.7 -{ 15.8 - 0.00000f,0.59715f,0.75180f,0.94650f, 15.9 - 1.19145f,1.50000f,1.88835f,2.37735f, 15.10 - 2.99295f,3.76785f,4.74345f,5.97165f, 15.11 - 7.51785f,9.46440f,11.9194f,15.0000f 15.12 -}; 15.13 - 15.14 -float psgcount[4],psglatch[4]; 15.15 -int psgstat[4]; 15.16 -int snlatch[4],sncount[4]; 15.17 -int snfreqlo[4],snfreqhi[4]; 15.18 -int snvol[4]; 15.19 -int curfreq[4]; 15.20 -uint32_t snshift[2]={0x8000,0x8000}; 15.21 - 15.22 -#define SNCLOCK (2386360>>5) 15.23 -uint8_t snnoise; 15.24 - 15.25 -void initpsg() 15.26 -{ 15.27 - int c; 15.28 - for (c=0;c<4;c++) 15.29 - { 15.30 - psgcount[c]=psglatch[c]=100000; 15.31 - psgstat[c]=0; 15.32 - } 15.33 -} 15.34 - 15.35 -#define PSGCONST (32000.0/48000.0) 15.36 - 15.37 -void getpsg(signed short *p, int size) 15.38 -{ 15.39 -// printf("Getpsg %08X %i\n",p,size); 15.40 -// return; 15.41 - int c,d; 15.42 - for (c=0;c<size;c++) 15.43 - { 15.44 - p[c]=0; 15.45 - for (d=1;d<4;d++) 15.46 - { 15.47 - if (psgstat[d]) p[c]+=volslog[snvol[d]]*170; 15.48 - else p[c]-=volslog[snvol[d]]*170; 15.49 - psgcount[d]-=(512*PSGCONST); 15.50 - while (psgcount[d]<=0.0 && psglatch[d]>1.0) 15.51 - { 15.52 - psgcount[d]+=psglatch[d]; 15.53 - psgstat[d]^=1; 15.54 - } 15.55 - if (psgcount[d]<=0.0) psgcount[d]=1.0; 15.56 - } 15.57 - d=(snnoise&4)?0:1; 15.58 - if (snshift[d]&1) p[c]+=volslog[snvol[0]]*170; 15.59 - psgcount[0]-=(512*PSGCONST); 15.60 - while (psgcount[0]<=0.0 && psglatch[0]>1.0) 15.61 - { 15.62 - psgcount[0]+=psglatch[0]; 15.63 - snshift[1]>>=1; 15.64 - if (!snshift[1]) snshift[1]=0x4000; 15.65 - if ((snshift[0]&1)^((snshift[0]&4)?1:0)^((snshift[0]&0x8000)?1:0)) 15.66 - snshift[0]|=0x10000; 15.67 - snshift[0]>>=1; 15.68 - } 15.69 - if (psgcount[0]<=0.0) psgcount[0]=1.0; 15.70 - } 15.71 -} 15.72 - 15.73 -int lasttone; 15.74 -uint8_t firstdat; 15.75 -void writepsg(uint16_t addr, uint8_t data) 15.76 -{ 15.77 - int c; 15.78 - int freq; 15.79 - pclog("Write PSG %02X\n", data); 15.80 - if (data&0x80) 15.81 - { 15.82 - firstdat=data; 15.83 - switch (data&0x70) 15.84 - { 15.85 - case 0: 15.86 - snfreqlo[3]=data&0xF; 15.87 - lasttone=3; 15.88 - break; 15.89 - case 0x10: 15.90 - data&=0xF; 15.91 - snvol[3]=0xF-data; 15.92 - break; 15.93 - case 0x20: 15.94 - snfreqlo[2]=data&0xF; 15.95 - lasttone=2; 15.96 - break; 15.97 - case 0x30: 15.98 - data&=0xF; 15.99 - snvol[2]=0xF-data; 15.100 - break; 15.101 - case 0x40: 15.102 - snfreqlo[1]=data&0xF; 15.103 - lasttone=1; 15.104 - break; 15.105 - case 0x50: 15.106 - data&=0xF; 15.107 - snvol[1]=0xF-data; 15.108 - break; 15.109 - case 0x60: 15.110 - if ((data&3)!=(snnoise&3)) sncount[0]=0; 15.111 - snnoise=data&0xF; 15.112 - if ((data&3)==3) 15.113 - { 15.114 - curfreq[0]=curfreq[1]>>4; 15.115 - snlatch[0]=snlatch[1]; 15.116 - } 15.117 - else 15.118 - { 15.119 - switch (data&3) 15.120 - { 15.121 - case 0: 15.122 - snlatch[0]=128<<7; 15.123 - curfreq[0]=SNCLOCK/256; 15.124 - snlatch[0]=0x400; 15.125 - sncount[0]=0; 15.126 - break; 15.127 - case 1: 15.128 - snlatch[0]=256<<7; 15.129 - curfreq[0]=SNCLOCK/512; 15.130 - snlatch[0]=0x800; 15.131 - sncount[0]=0; 15.132 - break; 15.133 - case 2: 15.134 - snlatch[0]=512<<7; 15.135 - curfreq[0]=SNCLOCK/1024; 15.136 - snlatch[0]=0x1000; 15.137 - sncount[0]=0; 15.138 - break; 15.139 - case 3: 15.140 - snlatch[0]=snlatch[1]; 15.141 - sncount[0]=0; 15.142 - } 15.143 - if (snnoise&4) snlatch[0]<<=1; 15.144 - } 15.145 - break; 15.146 - case 0x70: 15.147 - data&=0xF; 15.148 - snvol[0]=0xF-data; 15.149 - break; 15.150 - } 15.151 - } 15.152 - else 15.153 - { 15.154 - if ((firstdat&0x70)==0x60) 15.155 - { 15.156 - if ((data&3)!=(snnoise&3)) sncount[0]=0; 15.157 - snnoise=data&0xF; 15.158 - if ((data&3)==3) 15.159 - { 15.160 - curfreq[0]=curfreq[1]>>4; 15.161 - snlatch[0]=snlatch[1]; 15.162 -// printf("SN 0 latch %04X\n",snlatch[0]); 15.163 - } 15.164 - else 15.165 - { 15.166 - switch (data&3) 15.167 - { 15.168 - case 0: 15.169 - snlatch[0]=128<<7; 15.170 - curfreq[0]=SNCLOCK/256; 15.171 - snlatch[0]=0x400; 15.172 - sncount[0]=0; 15.173 - break; 15.174 - case 1: 15.175 - snlatch[0]=256<<7; 15.176 - curfreq[0]=SNCLOCK/512; 15.177 - snlatch[0]=0x800; 15.178 - sncount[0]=0; 15.179 - break; 15.180 - case 2: 15.181 - snlatch[0]=512<<7; 15.182 - curfreq[0]=SNCLOCK/1024; 15.183 - snlatch[0]=0x1000; 15.184 - sncount[0]=0; 15.185 - break; 15.186 - case 3: 15.187 - snlatch[0]=snlatch[1]; 15.188 -// printf("SN 0 latch %04X\n",snlatch[0]); 15.189 - sncount[0]=0; 15.190 - } 15.191 - if (snnoise&4) snlatch[0]<<=1; 15.192 - } 15.193 - return; 15.194 - } 15.195 - else 15.196 - { 15.197 - snfreqhi[lasttone]=data&0x3F; 15.198 - freq=snfreqlo[lasttone]|(snfreqhi[lasttone]<<4); 15.199 - snlatch[lasttone]=freq<<6; 15.200 - } 15.201 - } 15.202 - for (c=0;c<4;c++) psglatch[c]=(float)snlatch[c]; 15.203 -} 15.204 - 15.205 -void psg_init() 15.206 -{ 15.207 - pclog("psg_init\n"); 15.208 - io_sethandler(0x00C0, 0x0001, NULL, NULL, NULL, writepsg, NULL, NULL); 15.209 -}
16.1 --- a/src/psg.h Mon May 27 17:46:42 2013 +0100 16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3 @@ -1,1 +0,0 @@ 16.4 -void psg_init();
17.1 --- a/src/sblaster.c Mon May 27 17:46:42 2013 +0100 17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 17.3 @@ -1,1104 +0,0 @@ 17.4 -/*Jazz sample rates : 17.5 - 386-33 - 12kHz 17.6 - 486-33 - 20kHz 17.7 - 486-50 - 32kHz 17.8 - Pentium - 45kHz*/ 17.9 - 17.10 -#include <stdint.h> 17.11 -#include <stdio.h> 17.12 -#include "ibm.h" 17.13 -#include "filters.h" 17.14 -#include "io.h" 17.15 - 17.16 -static int sb_8_length, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output; 17.17 -static int sb_16_length, sb_16_format, sb_16_autoinit, sb_16_pause, sb_16_enable, sb_16_autolen, sb_16_output; 17.18 -static int sb_pausetime = -1; 17.19 - 17.20 -static uint8_t sb_read_data[256]; 17.21 -static int sb_read_wp, sb_read_rp; 17.22 -static int sb_speaker; 17.23 - 17.24 -static int sb_data_stat=-1; 17.25 - 17.26 -static int sb_irqnum = 7; 17.27 - 17.28 -static uint8_t sbe2; 17.29 -static int sbe2count; 17.30 - 17.31 -static int sbe2dat[4][9] = { 17.32 - { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, 17.33 - { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, 17.34 - { -0x01, 0x02, 0x04, -0x08, 0x10, -0x20, -0x40, 0x80, -151 }, 17.35 - { 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 } 17.36 -}; 17.37 - 17.38 -static uint8_t sb_data[8]; 17.39 -static int sb_commands[256]= 17.40 -{ 17.41 - -1,-1,-1,-1, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1, 17.42 - 1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0, 17.43 - 0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1, 17.44 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 17.45 - 1, 2, 2,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 17.46 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 17.47 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 17.48 - -1,-1,-1,-1, 2, 2, 2, 2,-1,-1,-1,-1,-1, 0,-1, 0, 17.49 - 2, 2,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1, 17.50 - 0,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1, 17.51 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 17.52 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 17.53 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 17.54 - 0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1, 17.55 - 1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1, 17.56 - -1,-1, 0,-1,-1,-1,-1,-1,-1, 1, 2,-1,-1,-1,-1, 0 17.57 -}; 17.58 - 17.59 -char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; 17.60 -uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405}; 17.61 - 17.62 -/*These tables were 'borrowed' from DOSBox*/ 17.63 - int8_t scaleMap4[64] = { 17.64 - 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, 17.65 - 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, 17.66 - 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, 17.67 - 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 17.68 - }; 17.69 - uint8_t adjustMap4[64] = { 17.70 - 0, 0, 0, 0, 0, 16, 16, 16, 17.71 - 0, 0, 0, 0, 0, 16, 16, 16, 17.72 - 240, 0, 0, 0, 0, 16, 16, 16, 17.73 - 240, 0, 0, 0, 0, 16, 16, 16, 17.74 - 240, 0, 0, 0, 0, 16, 16, 16, 17.75 - 240, 0, 0, 0, 0, 16, 16, 16, 17.76 - 240, 0, 0, 0, 0, 0, 0, 0, 17.77 - 240, 0, 0, 0, 0, 0, 0, 0 17.78 - }; 17.79 - 17.80 - int8_t scaleMap26[40] = { 17.81 - 0, 1, 2, 3, 0, -1, -2, -3, 17.82 - 1, 3, 5, 7, -1, -3, -5, -7, 17.83 - 2, 6, 10, 14, -2, -6, -10, -14, 17.84 - 4, 12, 20, 28, -4, -12, -20, -28, 17.85 - 5, 15, 25, 35, -5, -15, -25, -35 17.86 - }; 17.87 - uint8_t adjustMap26[40] = { 17.88 - 0, 0, 0, 8, 0, 0, 0, 8, 17.89 - 248, 0, 0, 8, 248, 0, 0, 8, 17.90 - 248, 0, 0, 8, 248, 0, 0, 8, 17.91 - 248, 0, 0, 8, 248, 0, 0, 8, 17.92 - 248, 0, 0, 0, 248, 0, 0, 0 17.93 - }; 17.94 - 17.95 - int8_t scaleMap2[24] = { 17.96 - 0, 1, 0, -1, 1, 3, -1, -3, 17.97 - 2, 6, -2, -6, 4, 12, -4, -12, 17.98 - 8, 24, -8, -24, 6, 48, -16, -48 17.99 - }; 17.100 - uint8_t adjustMap2[24] = { 17.101 - 0, 4, 0, 4, 17.102 - 252, 4, 252, 4, 252, 4, 252, 4, 17.103 - 252, 4, 252, 4, 252, 4, 252, 4, 17.104 - 252, 0, 252, 0 17.105 - }; 17.106 - 17.107 - 17.108 -int sb_freq; 17.109 - 17.110 -int sbtype=0; 17.111 - 17.112 -int writebusy=0; /*Needed for Amnesia*/ 17.113 - 17.114 -int16_t sbdatl=0,sbdatr=0; 17.115 -int16_t sb16datl=0,sb16datr=0; 17.116 - 17.117 -int16_t sbdat; 17.118 -uint8_t sbref; 17.119 -int sbdacmode,sbdacpos,sbdat2; 17.120 -int8_t sbstep; 17.121 -int sbleftright=0; 17.122 -int sbinput=0; 17.123 -int sbreadstat,sbwritestat; 17.124 -int sbreset; 17.125 -uint8_t sbreaddat; 17.126 -uint8_t sb_command,sbdata; 17.127 -int sbcommandnext=1; 17.128 -uint8_t sb_test; 17.129 -int sb_timei,sb_timeo; 17.130 -int sbcommandstat; 17.131 -int sbhalted; 17.132 -int adpcmstat=0; 17.133 -int sbautolen; 17.134 -int sbautoinit=0; 17.135 -uint8_t sbcurcommand,sbdmacommand; 17.136 -float SBCONST; 17.137 -int sbstereo=0; 17.138 - 17.139 -int sbsamprate; 17.140 -uint8_t sb_transfertype; 17.141 -int sb_newtransfer; 17.142 -int sb_dma16; 17.143 -int sb_uart; 17.144 -int sb_irq8,sb_irq16; 17.145 -int sb_16_exit; 17.146 - 17.147 -uint8_t mixerindex; 17.148 -uint8_t sb_mixer[256]; 17.149 -uint8_t sb_asp_regs[256]; 17.150 - 17.151 - 17.152 -int sb_att[]= 17.153 -{ 17.154 - 310,368,437,520,618,735,873,1038,1234,1467,1743,2072,2463,2927,3479, 17.155 - 4134,4914,5840,6941,8250,9805,11653,13850,16461,19564,23252,27635,32845, 17.156 - 39036,46395,55140,65535 17.157 -}; 17.158 - 17.159 -void sb_irq(int irq8) 17.160 -{ 17.161 -// pclog("IRQ %i %02X\n",irq8,pic.mask); 17.162 - if (irq8) sb_irq8=1; 17.163 - else sb_irq16=1; 17.164 - picint(1 << sb_irqnum); 17.165 -} 17.166 -void sb_irqc(int irq8) 17.167 -{ 17.168 - if (irq8) sb_irq8=0; 17.169 - else sb_irq16=0; 17.170 - picintc(1 << sb_irqnum); 17.171 -} 17.172 - 17.173 -void sb_mixer_set() 17.174 -{ 17.175 - if (sbtype==SB16) 17.176 - { 17.177 - mixer.master_l=sb_att[sb_mixer[0x30]>>3]; 17.178 - mixer.master_r=sb_att[sb_mixer[0x31]>>3]; 17.179 - mixer.voice_l =sb_att[sb_mixer[0x32]>>3]; 17.180 - mixer.voice_r =sb_att[sb_mixer[0x33]>>3]; 17.181 - mixer.fm_l =sb_att[sb_mixer[0x34]>>3]; 17.182 - mixer.fm_r =sb_att[sb_mixer[0x35]>>3]; 17.183 - mixer.bass_l =sb_mixer[0x46]>>4; 17.184 - mixer.bass_r =sb_mixer[0x47]>>4; 17.185 - mixer.treble_l=sb_mixer[0x44]>>4; 17.186 - mixer.treble_r=sb_mixer[0x45]>>4; 17.187 - mixer.filter=0; 17.188 - pclog("%02X %02X %02X %02X %02X %02X\n",sb_mixer[0x30],sb_mixer[0x31],sb_mixer[0x32],sb_mixer[0x33],sb_mixer[0x34],sb_mixer[0x35]); 17.189 - pclog("Mixer - %04X %04X %04X %04X %04X %04X\n",mixer.master_l,mixer.master_r,mixer.voice_l,mixer.voice_r,mixer.fm_l,mixer.fm_r); 17.190 - } 17.191 - else if (sbtype==SBPRO || sbtype==SBPRO2) 17.192 - { 17.193 - mixer.master_l=sb_att[(sb_mixer[0x22]>>4)|0x11]; 17.194 - mixer.master_r=sb_att[(sb_mixer[0x22]&0xF)|0x11]; 17.195 - mixer.voice_l =sb_att[(sb_mixer[0x04]>>4)|0x11]; 17.196 - mixer.voice_r =sb_att[(sb_mixer[0x04]&0xF)|0x11]; 17.197 - mixer.fm_l =sb_att[(sb_mixer[0x26]>>4)|0x11]; 17.198 - mixer.fm_r =sb_att[(sb_mixer[0x26]&0xF)|0x11]; 17.199 - mixer.filter =!(sb_mixer[0xE]&0x20); 17.200 - mixer.bass_l =mixer.bass_r =8; 17.201 - mixer.treble_l=mixer.treble_r=8; 17.202 - pclog("%02X %02X %02X\n",sb_mixer[0x04],sb_mixer[0x22],sb_mixer[0x26]); 17.203 - pclog("Mixer - %04X %04X %04X %04X %04X %04X\n",mixer.master_l,mixer.master_r,mixer.voice_l,mixer.voice_r,mixer.fm_l,mixer.fm_r); 17.204 - } 17.205 - else 17.206 - { 17.207 - mixer.master_l=mixer.master_r=65535; 17.208 - mixer.voice_l =mixer.voice_r =65535; 17.209 - mixer.fm_l =mixer.fm_r =65535; 17.210 - mixer.bass_l =mixer.bass_r =8; 17.211 - mixer.treble_l=mixer.treble_r=8; 17.212 - mixer.filter=1; 17.213 - } 17.214 -} 17.215 - 17.216 -void sb_mixer_reset() 17.217 -{ 17.218 - pclog("Mixer reset\n"); 17.219 - if (sbtype==SB16) 17.220 - { 17.221 - sb_mixer[0x30]=31<<3; 17.222 - sb_mixer[0x31]=31<<3; 17.223 - sb_mixer[0x32]=31<<3; 17.224 - sb_mixer[0x33]=31<<3; 17.225 - sb_mixer[0x34]=31<<3; 17.226 - sb_mixer[0x35]=31<<3; 17.227 - sb_mixer[0x44]=8<<4; 17.228 - sb_mixer[0x45]=8<<4; 17.229 - sb_mixer[0x46]=8<<4; 17.230 - sb_mixer[0x47]=8<<4; 17.231 - sb_mixer[0x22]=(sb_mixer[0x30]&0xF0)|(sb_mixer[0x31]>>4); 17.232 - sb_mixer[0x04]=(sb_mixer[0x32]&0xF0)|(sb_mixer[0x33]>>4); 17.233 - sb_mixer[0x26]=(sb_mixer[0x34]&0xF0)|(sb_mixer[0x35]>>4); 17.234 - } 17.235 - if (sbtype==SBPRO || sbtype==SBPRO2) 17.236 - { 17.237 - sb_mixer[0x22]=0xFF; 17.238 - sb_mixer[0x04]=0xFF; 17.239 - sb_mixer[0x26]=0xFF; 17.240 - sb_mixer[0xE]=0; 17.241 - } 17.242 -} 17.243 - 17.244 -void sb_dsp_reset() 17.245 -{ 17.246 - sbenable = sb_enable_i = 0; 17.247 - sb_command = 0; 17.248 - 17.249 - sb_uart = 0; 17.250 - sb_8_length = sbautolen = 0xFFFF; 17.251 - 17.252 - sb_irqc(0); 17.253 - sb_irqc(1); 17.254 - sb_16_pause = 0; 17.255 - sb_read_wp = sb_read_rp = 0; 17.256 - sb_data_stat = -1; 17.257 - sb_speaker = 0; 17.258 - sb_pausetime = -1; 17.259 - sbe2 = 0xAA; 17.260 - sbe2count = 0; 17.261 - 17.262 - sbreset = 0; 17.263 - sbenable = sb_enable_i = sb_count_i = 0; 17.264 - sbhalted = 0; 17.265 - sbdmacommand = 0; 17.266 - sbstereo = 0; 17.267 - 17.268 - picintc(1 << sb_irqnum); 17.269 -} 17.270 - 17.271 -void sb_reset() 17.272 -{ 17.273 - int c; 17.274 - 17.275 - sb_dsp_reset(); 17.276 - sb_mixer_reset(); 17.277 - sb_mixer_set(); 17.278 - 17.279 - if (sbtype==SB16) sb_commands[8]=1; 17.280 - else sb_commands[8]=-1; 17.281 - 17.282 - for (c = 0; c < 256; c++) 17.283 - sb_asp_regs[c] = 0; 17.284 - sb_asp_regs[5] = 0x01; 17.285 - sb_asp_regs[9] = 0xf8; 17.286 -} 17.287 - 17.288 -void setsbclock(float clock) 17.289 -{ 17.290 - SBCONST=clock/1000000.0f; 17.291 - printf("SBCONST %f %f\n",SBCONST,clock); 17.292 - if (sb_timeo>255) sblatcho=(int)(SBCONST*(1000000.0f/(float)(sb_timeo-256))); 17.293 - else sblatcho=SBCONST*(256-sb_timeo); 17.294 - if (sb_timei>255) sblatchi=(int)(SBCONST*(1000000.0f/(float)(sb_timei-256))); 17.295 - else sblatchi=SBCONST*(256-sb_timei); 17.296 -} 17.297 - 17.298 -void outmidi(uint8_t v) 17.299 -{ 17.300 - printf("Write MIDI %02X\n",v); 17.301 -} 17.302 - 17.303 -void setsbtype(int type) 17.304 -{ 17.305 - sbtype=type; 17.306 - sbstereo=0; 17.307 - sb_mixer_set(); 17.308 - if (sbtype==SB16) sb_commands[8]=1; 17.309 - else sb_commands[8]=-1; 17.310 -} 17.311 - 17.312 - 17.313 - 17.314 - 17.315 - 17.316 - 17.317 - 17.318 -void sb_add_data(uint8_t v) 17.319 -{ 17.320 - sb_read_data[sb_read_wp++]=v; 17.321 - sb_read_wp&=0xFF; 17.322 -} 17.323 - 17.324 -#define ADPCM_4 1 17.325 -#define ADPCM_26 2 17.326 -#define ADPCM_2 3 17.327 - 17.328 -void sb_start_dma(int dma8, int autoinit, uint8_t format, int len) 17.329 -{ 17.330 - if (dma8) 17.331 - { 17.332 - sb_8_length=len; 17.333 - sb_8_format=format; 17.334 - sb_8_autoinit=autoinit; 17.335 - sb_8_pause=0; 17.336 - sb_8_enable=1; 17.337 - if (sb_16_enable && sb_16_output) sb_16_enable = 0; 17.338 - sb_8_output=1; 17.339 - sbenable=sb_8_enable; 17.340 - sbleftright=0; 17.341 - sbdacpos=0; 17.342 -// pclog("Start 8-bit DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); 17.343 - } 17.344 - else 17.345 - { 17.346 - sb_16_length=len; 17.347 - sb_16_format=format; 17.348 - sb_16_autoinit=autoinit; 17.349 - sb_16_pause=0; 17.350 - sb_16_enable=1; 17.351 - if (sb_8_enable && sb_8_output) sb_8_enable = 0; 17.352 - sb_16_output=1; 17.353 - sbenable=sb_16_enable; 17.354 -// pclog("Start 16-bit DMA addr %06X len %04X\n",dma16.ac[1]+(dma16.page[1]<<16),len); 17.355 - } 17.356 -} 17.357 - 17.358 -void sb_start_dma_i(int dma8, int autoinit, uint8_t format, int len) 17.359 -{ 17.360 - if (dma8) 17.361 - { 17.362 - sb_8_length=len; 17.363 - sb_8_format=format; 17.364 - sb_8_autoinit=autoinit; 17.365 - sb_8_pause=0; 17.366 - sb_8_enable=1; 17.367 - if (sb_16_enable && !sb_16_output) sb_16_enable = 0; 17.368 - sb_8_output=0; 17.369 - sb_enable_i=sb_8_enable; 17.370 -// pclog("Start 8-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); 17.371 - } 17.372 - else 17.373 - { 17.374 - sb_16_length=len; 17.375 - sb_16_format=format; 17.376 - sb_16_autoinit=autoinit; 17.377 - sb_16_pause=0; 17.378 - sb_16_enable=1; 17.379 - if (sb_8_enable && !sb_8_output) sb_8_enable = 0; 17.380 - sb_16_output=0; 17.381 - sb_enable_i=sb_16_enable; 17.382 -// pclog("Start 16-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); 17.383 - } 17.384 -} 17.385 - 17.386 -uint8_t sb_8_read_dma() 17.387 -{ 17.388 - return readdma1(); 17.389 -} 17.390 -void sb_8_write_dma(uint8_t val) 17.391 -{ 17.392 - writedma1(val); 17.393 -} 17.394 -uint16_t sb_16_read_dma() 17.395 -{ 17.396 - return readdma5(); 17.397 -} 17.398 -void sb_16_write_dma(uint16_t val) 17.399 -{ 17.400 - writedma5(val); 17.401 -} 17.402 - 17.403 -void sb_exec_command() 17.404 -{ 17.405 - int temp,c; 17.406 -// pclog("SB command %02X\n",sb_command); 17.407 - switch (sb_command) 17.408 - { 17.409 - case 0x10: /*8-bit direct mode*/ 17.410 - sbdat=sbdatl=sbdatr=(sb_data[0]^0x80)<<8; 17.411 - break; 17.412 - case 0x14: /*8-bit single cycle DMA output*/ 17.413 - sb_start_dma(1,0,0,sb_data[0]+(sb_data[1]<<8)); 17.414 - break; 17.415 - case 0x17: /*2-bit ADPCM output with reference*/ 17.416 - sbref=sb_8_read_dma(); 17.417 - sbstep=0; 17.418 -// pclog("Ref byte 2 %02X\n",sbref); 17.419 - case 0x16: /*2-bit ADPCM output*/ 17.420 - sb_start_dma(1,0,ADPCM_2,sb_data[0]+(sb_data[1]<<8)); 17.421 - sbdat2=sb_8_read_dma(); 17.422 - sb_8_length--; 17.423 - break; 17.424 - case 0x1C: /*8-bit autoinit DMA output*/ 17.425 - if (sbtype<SB15) break; 17.426 - sb_start_dma(1,1,0,sb_8_autolen); 17.427 - break; 17.428 - case 0x1F: /*2-bit ADPCM autoinit output*/ 17.429 - if (sbtype<SB15) break; 17.430 - sb_start_dma(1,1,ADPCM_2,sb_data[0]+(sb_data[1]<<8)); 17.431 - sbdat2=sb_8_read_dma(); 17.432 - sb_8_length--; 17.433 - break; 17.434 - case 0x20: /*8-bit direct input*/ 17.435 - sb_add_data(0); 17.436 - break; 17.437 - case 0x24: /*8-bit single cycle DMA input*/ 17.438 - sb_start_dma_i(1,0,0,sb_data[0]+(sb_data[1]<<8)); 17.439 - break; 17.440 - case 0x2C: /*8-bit autoinit DMA input*/ 17.441 - if (sbtype<SB15) break; 17.442 - sb_start_dma_i(1,1,0,sb_data[0]+(sb_data[1]<<8)); 17.443 - break; 17.444 - case 0x40: /*Set time constant*/ 17.445 - sb_timei=sb_timeo=sb_data[0]; 17.446 - sblatcho=sblatchi=SBCONST*(256-sb_data[0]); 17.447 - temp=256-sb_data[0]; 17.448 - temp=1000000/temp; 17.449 -// printf("Sample rate - %ihz (%i)\n",temp, sblatcho); 17.450 - sb_freq=temp; 17.451 - break; 17.452 - case 0x41: /*Set output sampling rate*/ 17.453 - if (sbtype<SB16) break; 17.454 - sblatcho=(int)(SBCONST*(1000000.0f/(float)(sb_data[1]+(sb_data[0]<<8)))); 17.455 -// printf("Sample rate - %ihz (%i)\n",sb_data[1]+(sb_data[0]<<8), sblatcho); 17.456 - sb_freq=sb_data[1]+(sb_data[0]<<8); 17.457 - sb_timeo=256+sb_freq; 17.458 - break; 17.459 - case 0x42: /*Set input sampling rate*/ 17.460 - if (sbtype<SB16) break; 17.461 - sblatchi=(int)(SBCONST*(1000000.0f/(float)(sb_data[1]+(sb_data[0]<<8)))); 17.462 -// printf("iample rate - %ihz\n",sb_data[1]+(sb_data[0]<<8)); 17.463 - sb_timei=256+sb_data[1]+(sb_data[0]<<8); 17.464 - break; 17.465 - case 0x48: /*Set DSP block transfer size*/ 17.466 - sb_8_autolen=sb_data[0]+(sb_data[1]<<8); 17.467 - break; 17.468 - case 0x75: /*4-bit ADPCM output with reference*/ 17.469 - sbref=sb_8_read_dma(); 17.470 - sbstep=0; 17.471 -// pclog("Ref byte 4 %02X\n",sbref); 17.472 - case 0x74: /*4-bit ADPCM output*/ 17.473 - sb_start_dma(1,0,ADPCM_4,sb_data[0]+(sb_data[1]<<8)); 17.474 - sbdat2=sb_8_read_dma(); 17.475 - sb_8_length--; 17.476 - break; 17.477 - case 0x77: /*2.6-bit ADPCM output with reference*/ 17.478 - sbref=sb_8_read_dma(); 17.479 - sbstep=0; 17.480 -// pclog("Ref byte 26 %02X\n",sbref); 17.481 - case 0x76: /*2.6-bit ADPCM output*/ 17.482 - sb_start_dma(1,0,ADPCM_26,sb_data[0]+(sb_data[1]<<8)); 17.483 - sbdat2=sb_8_read_dma(); 17.484 - sb_8_length--; 17.485 - break; 17.486 - case 0x7D: /*4-bit ADPCM autoinit output*/ 17.487 - if (sbtype<SB15) break; 17.488 - sb_start_dma(1,1,ADPCM_4,sb_data[0]+(sb_data[1]<<8)); 17.489 - sbdat2=sb_8_read_dma(); 17.490 - sb_8_length--; 17.491 - break; 17.492 - case 0x7F: /*2.6-bit ADPCM autoinit output*/ 17.493 - if (sbtype<SB15) break; 17.494 - sb_start_dma(1,1,ADPCM_26,sb_data[0]+(sb_data[1]<<8)); 17.495 - sbdat2=sb_8_read_dma(); 17.496 - sb_8_length--; 17.497 - break; 17.498 - case 0x80: /*Pause DAC*/ 17.499 - sb_pausetime=sb_data[0]+(sb_data[1]<<8); 17.500 -// pclog("SB pause %04X\n",sb_pausetime); 17.501 - sbenable=1; 17.502 - break; 17.503 - case 0x90: /*High speed 8-bit autoinit DMA output*/ 17.504 - if (sbtype<SB2) break; 17.505 - sb_start_dma(1,1,0,sb_8_autolen); 17.506 - break; 17.507 - case 0x91: /*High speed 8-bit single cycle DMA output*/ 17.508 - if (sbtype<SB2) break; 17.509 - sb_start_dma(1,0,0,sb_8_autolen); 17.510 - break; 17.511 - case 0x98: /*High speed 8-bit autoinit DMA input*/ 17.512 - if (sbtype<SB2) break; 17.513 - sb_start_dma_i(1,1,0,sb_8_autolen); 17.514 - break; 17.515 - case 0x99: /*High speed 8-bit single cycle DMA input*/ 17.516 - if (sbtype<SB2) break; 17.517 - sb_start_dma_i(1,0,0,sb_8_autolen); 17.518 - break; 17.519 - case 0xA0: /*Set input mode to mono*/ 17.520 - case 0xA8: /*Set input mode to stereo*/ 17.521 - break; 17.522 - case 0xB0: case 0xB1: case 0xB2: case 0xB3: 17.523 - case 0xB4: case 0xB5: case 0xB6: case 0xB7: /*16-bit DMA output*/ 17.524 - if (sbtype<SB16) break; 17.525 - sb_start_dma(0,sb_command&4,sb_data[0],sb_data[1]+(sb_data[2]<<8)); 17.526 - sb_16_autolen=sb_data[1]+(sb_data[2]<<8); 17.527 - break; 17.528 - case 0xB8: case 0xB9: case 0xBA: case 0xBB: 17.529 - case 0xBC: case 0xBD: case 0xBE: case 0xBF: /*16-bit DMA input*/ 17.530 - if (sbtype<SB16) break; 17.531 - sb_start_dma_i(0,sb_command&4,sb_data[0],sb_data[1]+(sb_data[2]<<8)); 17.532 - sb_16_autolen=sb_data[1]+(sb_data[2]<<8); 17.533 - break; 17.534 - case 0xC0: case 0xC1: case 0xC2: case 0xC3: 17.535 - case 0xC4: case 0xC5: case 0xC6: case 0xC7: /*8-bit DMA output*/ 17.536 - if (sbtype<SB16) break; 17.537 - sb_start_dma(1,sb_command&4,sb_data[0],sb_data[1]+(sb_data[2]<<8)); 17.538 - sb_8_autolen=sb_data[1]+(sb_data[2]<<8); 17.539 - break; 17.540 - case 0xC8: case 0xC9: case 0xCA: case 0xCB: 17.541 - case 0xCC: case 0xCD: case 0xCE: case 0xCF: /*8-bit DMA input*/ 17.542 - if (sbtype<SB16) break; 17.543 - sb_start_dma_i(1,sb_command&4,sb_data[0],sb_data[1]+(sb_data[2]<<8)); 17.544 - sb_8_autolen=sb_data[1]+(sb_data[2]<<8); 17.545 - break; 17.546 - case 0xD0: /*Pause 8-bit DMA*/ 17.547 - sb_8_pause=1; 17.548 - break; 17.549 - case 0xD1: /*Speaker on*/ 17.550 - sb_speaker=1; 17.551 - break; 17.552 - case 0xD3: /*Speaker off*/ 17.553 - sb_speaker=0; 17.554 - break; 17.555 - case 0xD4: /*Continue 8-bit DMA*/ 17.556 - sb_8_pause=0; 17.557 - break; 17.558 - case 0xD5: /*Pause 16-bit DMA*/ 17.559 - if (sbtype<SB16) break; 17.560 - sb_16_pause=1; 17.561 - break; 17.562 - case 0xD6: /*Continue 16-bit DMA*/ 17.563 - if (sbtype<SB16) break; 17.564 - sb_16_pause=0; 17.565 - break; 17.566 - case 0xD8: /*Get speaker status*/ 17.567 - sb_add_data(sb_speaker?0xFF:0); 17.568 - break; 17.569 - case 0xD9: /*Exit 16-bit auto-init mode*/ 17.570 - if (sbtype<SB16) break; 17.571 - sb_16_autoinit=0; 17.572 - break; 17.573 - case 0xDA: /*Exit 8-bit auto-init mode*/ 17.574 - sb_8_autoinit=0; 17.575 - break; 17.576 - case 0xE0: /*DSP identification*/ 17.577 - sb_add_data(~sb_data[0]); 17.578 - break; 17.579 - case 0xE1: /*Get DSP version*/ 17.580 - sb_add_data(sb_dsp_versions[sbtype]>>8); 17.581 - sb_add_data(sb_dsp_versions[sbtype]&0xFF); 17.582 - break; 17.583 - case 0xE2: /*Stupid ID/protection*/ 17.584 - for (c=0;c<8;c++) 17.585 - if (sb_data[0]&(1<<c)) sbe2+=sbe2dat[sbe2count&3][c]; 17.586 - sbe2+=sbe2dat[sbe2count&3][8]; 17.587 - sbe2count++; 17.588 - sb_8_write_dma(sbe2); 17.589 - break; 17.590 - case 0xE3: /*DSP copyright*/ 17.591 - if (sbtype<SB16) break; 17.592 - c=0; 17.593 - while (sb16_copyright[c]) 17.594 - sb_add_data(sb16_copyright[c++]); 17.595 - sb_add_data(0); 17.596 - break; 17.597 - case 0xE4: /*Write test register*/ 17.598 - sb_test=sb_data[0]; 17.599 - break; 17.600 - case 0xE8: /*Read test register*/ 17.601 - sb_add_data(sb_test); 17.602 - break; 17.603 - case 0xF2: /*Trigger 8-bit IRQ*/ 17.604 -// pclog("Trigger IRQ\n"); 17.605 - sb_irq(1); 17.606 - break; 17.607 - case 0xE7: /*???*/ 17.608 - case 0xFA: /*???*/ 17.609 - break; 17.610 - case 0x07: /*No, that's not how you program auto-init DMA*/ 17.611 - case 0xFF: 17.612 - break; 17.613 - case 0x08: /*ASP get version*/ 17.614 - if (sbtype<SB16) break; 17.615 - sb_add_data(0x18); 17.616 - break; 17.617 - case 0x0E: /*ASP set register*/ 17.618 - if (sbtype<SB16) break; 17.619 - sb_asp_regs[sb_data[0]] = sb_data[1]; 17.620 -// pclog("ASP write reg %02X %02X\n", sb_data[0], sb_data[1]); 17.621 - break; 17.622 - case 0x0F: /*ASP get register*/ 17.623 - if (sbtype<SB16) break; 17.624 -// sb_add_data(0); 17.625 - sb_add_data(sb_asp_regs[sb_data[0]]); 17.626 -// pclog("ASP read reg %02X %02X\n", sb_data[0], sb_asp_regs[sb_data[0]]); 17.627 - break; 17.628 - case 0xF9: 17.629 - if (sbtype<SB16) break; 17.630 - if (sb_data[0] == 0x0e) sb_add_data(0xff); 17.631 - else if (sb_data[0] == 0x0f) sb_add_data(0x07); 17.632 - else if (sb_data[0] == 0x37) sb_add_data(0x38); 17.633 - else sb_add_data(0x00); 17.634 - case 0x04: 17.635 - case 0x05: 17.636 - break; 17.637 -// default: 17.638 -// fatal("Exec bad SB command %02X\n",sb_command); 17.639 - } 17.640 -} 17.641 - 17.642 -void sb_write(uint16_t a, uint8_t v) 17.643 -{ 17.644 - int temp; 17.645 - int c; 17.646 -// printf("Write soundblaster %04X %02X %04X:%04X %02X\n",a,v,cs>>4,pc,sb_command); 17.647 - switch (a&0xF) 17.648 - { 17.649 - case 0: case 1: case 2: case 3: /*OPL or Gameblaster*/ 17.650 - if (GAMEBLASTER && sbtype < SBPRO) 17.651 - writecms(a, v); 17.652 - else if (sbtype >= SBPRO) 17.653 - adlib_write(a,v); 17.654 - return; 17.655 - case 4: mixerindex=v; return; 17.656 - case 5: 17.657 - sb_mixer[mixerindex]=v; 17.658 -// pclog("Write mixer data %02X %02X\n",mixerindex,sb_mixer[mixerindex]); 17.659 - if (sbtype==SB16) 17.660 - { 17.661 - switch (mixerindex) 17.662 - { 17.663 - case 0x22: 17.664 - sb_mixer[0x30]=((sb_mixer[0x22]>>4)|0x11)<<3; 17.665 - sb_mixer[0x31]=((sb_mixer[0x22]&0xF)|0x11)<<3; 17.666 - break; 17.667 - case 0x04: 17.668 - sb_mixer[0x32]=((sb_mixer[0x04]>>4)|0x11)<<3; 17.669 - sb_mixer[0x33]=((sb_mixer[0x04]&0xF)|0x11)<<3; 17.670 - break; 17.671 - case 0x26: 17.672 - sb_mixer[0x34]=((sb_mixer[0x26]>>4)|0x11)<<3; 17.673 - sb_mixer[0x35]=((sb_mixer[0x26]&0xF)|0x11)<<3; 17.674 - break; 17.675 - case 0x80: 17.676 - if (v & 1) sb_irqnum = 2; 17.677 - if (v & 2) sb_irqnum = 5; 17.678 - if (v & 4) sb_irqnum = 7; 17.679 - if (v & 8) sb_irqnum = 10; 17.680 - break; 17.681 - } 17.682 - } 17.683 -// if (!mixerindex) sb_mixer_reset(); 17.684 - sb_mixer_set(); 17.685 - return; 17.686 - case 6: /*Reset*/ 17.687 - if (!(v&1) && (sbreset&1)) 17.688 - { 17.689 - sb_dsp_reset(); 17.690 - sb_add_data(0xAA); 17.691 - } 17.692 - sbreset=v; 17.693 - return; 17.694 - case 8: case 9: adlib_write(a,v); return; /*OPL*/ 17.695 - case 0xC: /*Command/data write*/ 17.696 - if (sb_uart) return; 17.697 - if (sb_data_stat==-1) 17.698 - { 17.699 - sb_command=v; 17.700 -// if (sb_commands[v]==-1) 17.701 -// fatal("Bad SB command %02X\n",v); 17.702 - sb_data_stat++; 17.703 - } 17.704 - else 17.705 - sb_data[sb_data_stat++]=v; 17.706 - if (sb_data_stat==sb_commands[sb_command] || sb_commands[sb_command]==-1) 17.707 - { 17.708 - sb_exec_command(); 17.709 - sb_data_stat=-1; 17.710 - } 17.711 - break; 17.712 - } 17.713 -} 17.714 - 17.715 -uint8_t sb_read(uint16_t a) 17.716 -{ 17.717 - uint8_t temp; 17.718 -// if (a==0x224) output=1; 17.719 -// printf("Read soundblaster %04X %04X:%04X\n",a,cs,pc); 17.720 - switch (a&0xF) 17.721 - { 17.722 - case 0: case 1: case 2: case 3: /*OPL or GameBlaster*/ 17.723 - if (GAMEBLASTER && sbtype < SBPRO) 17.724 - return readcms(a); 17.725 - return adlib_read(a); 17.726 - break; 17.727 - case 5: 17.728 - if (sbtype<SBPRO) return 0; 17.729 -// pclog("Read mixer data %02X %02X\n",mixerindex,sb_mixer[mixerindex]); 17.730 - if (mixerindex==0x80 && sbtype>=SB16) 17.731 - { 17.732 - switch (sb_irqnum) 17.733 - { 17.734 - case 2: return 1; /*IRQ 7*/ 17.735 - case 5: return 2; /*IRQ 7*/ 17.736 - case 7: return 4; /*IRQ 7*/ 17.737 - case 10: return 8; /*IRQ 7*/ 17.738 - } 17.739 - } 17.740 - if (mixerindex==0x81 && sbtype>=SB16) return 0x22; /*DMA 1 and 5*/ 17.741 - if (mixerindex==0x82 && sbtype>=SB16) return ((sb_irq8)?1:0)|((sb_irq16)?2:0); 17.742 - return sb_mixer[mixerindex]; 17.743 - case 8: case 9: return adlib_read(a); /*OPL*/ 17.744 - case 0xA: /*Read data*/ 17.745 - if (sb_uart) return; 17.746 - sbreaddat=sb_read_data[sb_read_rp]; 17.747 - if (sb_read_rp!=sb_read_wp) 17.748 - { 17.749 - sb_read_rp++; 17.750 - sb_read_rp&=0xFF; 17.751 - } 17.752 -// pclog("SB read %02X\n",sbreaddat); 17.753 - return sbreaddat; 17.754 - case 0xC: /*Write data ready*/ 17.755 - cycles-=100; 17.756 - writebusy++; 17.757 - if (writebusy&8) return 0xFF; 17.758 - return 0x7F; 17.759 - case 0xE: /*Read data ready*/ 17.760 - picintc(1 << sb_irqnum); 17.761 - sb_irq8=sb_irq16=0; 17.762 - return (sb_read_rp==sb_read_wp)?0x7f:0xff; 17.763 - case 0xF: /*16-bit ack*/ 17.764 - sb_irq16=0; 17.765 - if (!sb_irq8) picintc(1 << sb_irqnum); 17.766 - return 0xff; 17.767 - } 17.768 - return 0; 17.769 -} 17.770 - 17.771 -void sb_init() 17.772 -{ 17.773 - int c; 17.774 - 17.775 - sb_reset(); 17.776 - 17.777 - io_sethandler(0x0220, 0x0010, sb_read, NULL, NULL, sb_write, NULL, NULL); 17.778 -} 17.779 - 17.780 - 17.781 -int sbshift4[8]={-2,-1,0,0,1,1,1,1}; 17.782 -void pollsb() 17.783 -{ 17.784 - int tempi,ref; 17.785 -// pclog("PollSB %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output); 17.786 - if (sb_8_enable && !sb_8_pause && sb_pausetime<0 && sb_8_output) 17.787 - { 17.788 -// pclog("Dopoll %i %02X %i\n", sb_8_length, sb_8_format, sblatcho); 17.789 - switch (sb_8_format) 17.790 - { 17.791 - case 0x00: /*Mono unsigned*/ 17.792 - sbdat=(sb_8_read_dma()^0x80)<<8; 17.793 - if (sbtype>=SBPRO && sbtype<SB16 && sb_mixer[0xE]&2) 17.794 - { 17.795 - if (sbleftright) sbdatl=sbdat; 17.796 - else sbdatr=sbdat; 17.797 - sbleftright=!sbleftright; 17.798 - } 17.799 - else 17.800 - sbdatl=sbdatr=sbdat; 17.801 - sb_8_length--; 17.802 - break; 17.803 - case 0x10: /*Mono signed*/ 17.804 - sbdat=sb_8_read_dma()<<8; 17.805 - if (sbtype>=SBPRO && sbtype<SB16 && sb_mixer[0xE]&2) 17.806 - { 17.807 - if (sbleftright) sbdatl=sbdat; 17.808 - else sbdatr=sbdat; 17.809 - sbleftright=!sbleftright; 17.810 - } 17.811 - else 17.812 - sbdatl=sbdatr=sbdat; 17.813 - sb_8_length--; 17.814 - break; 17.815 - case 0x20: /*Stereo unsigned*/ 17.816 - sbdatl=(sb_8_read_dma()^0x80)<<8; 17.817 - sbdatr=(sb_8_read_dma()^0x80)<<8; 17.818 - sb_8_length-=2; 17.819 - break; 17.820 - case 0x30: /*Stereo signed*/ 17.821 - sbdatl=sb_8_read_dma()<<8; 17.822 - sbdatr=sb_8_read_dma()<<8; 17.823 - sb_8_length-=2; 17.824 - break; 17.825 - 17.826 - case ADPCM_4: 17.827 - if (sbdacpos) tempi=(sbdat2&0xF)+sbstep; 17.828 - else tempi=(sbdat2>>4)+sbstep; 17.829 - if (tempi<0) tempi=0; 17.830 - if (tempi>63) tempi=63; 17.831 - 17.832 - ref = sbref + scaleMap4[tempi]; 17.833 - if (ref > 0xff) sbref = 0xff; 17.834 - else if (ref < 0x00) sbref = 0x00; 17.835 - else sbref = ref; 17.836 - 17.837 - sbstep = (sbstep + adjustMap4[tempi]) & 0xff; 17.838 - 17.839 - sbdat=(sbref^0x80)<<8; 17.840 - 17.841 - sbdacpos++; 17.842 - if (sbdacpos>=2) 17.843 - { 17.844 - sbdacpos=0; 17.845 - sbdat2=sb_8_read_dma(); 17.846 - sb_8_length--; 17.847 - } 17.848 - 17.849 - if (sbtype>=SBPRO && sbtype<SB16 && sb_mixer[0xE]&2) 17.850 - { 17.851 - if (sbleftright) sbdatl=sbdat; 17.852 - else sbdatr=sbdat; 17.853 - sbleftright=!sbleftright; 17.854 - } 17.855 - else 17.856 - sbdatl=sbdatr=sbdat; 17.857 - break; 17.858 - 17.859 - case ADPCM_26: 17.860 - if (!sbdacpos) tempi=(sbdat2>>5)+sbstep; 17.861 - else if (sbdacpos==1) tempi=((sbdat2>>2)&7)+sbstep; 17.862 - else tempi=((sbdat2<<1)&7)+sbstep; 17.863 - 17.864 - if (tempi<0) tempi=0; 17.865 - if (tempi>39) tempi=39; 17.866 - 17.867 - ref = sbref + scaleMap26[tempi]; 17.868 - if (ref > 0xff) sbref = 0xff; 17.869 - else if (ref < 0x00) sbref = 0x00; 17.870 - else sbref = ref; 17.871 - sbstep = (sbstep + adjustMap26[tempi]) & 0xff; 17.872 - 17.873 - sbdat=(sbref^0x80)<<8; 17.874 - 17.875 - sbdacpos++; 17.876 - if (sbdacpos>=3) 17.877 - { 17.878 - sbdacpos=0; 17.879 - sbdat2=readdma1(); 17.880 - sb_8_length--; 17.881 - } 17.882 - 17.883 - if (sbtype>=SBPRO && sbtype<SB16 && sb_mixer[0xE]&2) 17.884 - { 17.885 - if (sbleftright) sbdatl=sbdat; 17.886 - else sbdatr=sbdat; 17.887 - sbleftright=!sbleftright; 17.888 - } 17.889 - else 17.890 - sbdatl=sbdatr=sbdat; 17.891 - break; 17.892 - 17.893 - case ADPCM_2: 17.894 - tempi=((sbdat2>>((3-sbdacpos)*2))&3)+sbstep; 17.895 - if (tempi<0) tempi=0; 17.896 - if (tempi>23) tempi=23; 17.897 - 17.898 - ref = sbref + scaleMap2[tempi]; 17.899 - if (ref > 0xff) sbref = 0xff; 17.900 - else if (ref < 0x00) sbref = 0x00; 17.901 - else sbref = ref; 17.902 - sbstep = (sbstep + adjustMap2[tempi]) & 0xff; 17.903 - 17.904 - sbdat=(sbref^0x80)<<8; 17.905 - 17.906 - sbdacpos++; 17.907 - if (sbdacpos>=4) 17.908 - { 17.909 - sbdacpos=0; 17.910 - sbdat2=readdma1(); 17.911 - } 17.912 - 17.913 - if (sbtype>=SBPRO && sbtype<SB16 && sb_mixer[0xE]&2) 17.914 - { 17.915 - if (sbleftright) sbdatl=sbdat; 17.916 - else sbdatr=sbdat; 17.917 - sbleftright=!sbleftright; 17.918 - } 17.919 - else 17.920 - sbdatl=sbdatr=sbdat; 17.921 - break; 17.922 - 17.923 -// default: 17.924 - //fatal("Unrecognised SB 8-bit format %02X\n",sb_8_format); 17.925 - } 17.926 - 17.927 - if (sb_8_length<0) 17.928 - { 17.929 -// pclog("DMA over %i %i\n", sb_8_autoinit, sb_irqnum); 17.930 - if (sb_8_autoinit) sb_8_length=sb_8_autolen; 17.931 - else sb_8_enable=sbenable=0; 17.932 - sb_irq(1); 17.933 - } 17.934 - } 17.935 - if (sb_16_enable && !sb_16_pause && sb_pausetime<0 && sb_16_output) 17.936 - { 17.937 - switch (sb_16_format) 17.938 - { 17.939 - case 0x00: /*Mono unsigned*/ 17.940 - sbdatl=sbdatr=sb_16_read_dma()^0x8000; 17.941 - sb_16_length--; 17.942 - break; 17.943 - case 0x10: /*Mono signed*/ 17.944 - sbdatl=sbdatr=sb_16_read_dma(); 17.945 - sb_16_length--; 17.946 - break; 17.947 - case 0x20: /*Stereo unsigned*/ 17.948 - sbdatl=sb_16_read_dma()^0x8000; 17.949 - sbdatr=sb_16_read_dma()^0x8000; 17.950 - sb_16_length-=2; 17.951 - break; 17.952 - case 0x30: /*Stereo signed*/ 17.953 - sbdatl=sb_16_read_dma(); 17.954 - sbdatr=sb_16_read_dma(); 17.955 - sb_16_length-=2; 17.956 - break; 17.957 - 17.958 -// default: 17.959 -// fatal("Unrecognised SB 16-bit format %02X\n",sb_16_format); 17.960 - } 17.961 - 17.962 - if (sb_16_length<0) 17.963 - { 17.964 -// pclog("16DMA over %i\n",sb_16_autoinit); 17.965 - if (sb_16_autoinit) sb_16_length=sb_16_autolen; 17.966 - else sb_16_enable=sbenable=0; 17.967 - sb_irq(0); 17.968 - } 17.969 - } 17.970 - if (sb_pausetime>-1) 17.971 - { 17.972 - sb_pausetime--; 17.973 - if (sb_pausetime<0) 17.974 - { 17.975 - sb_irq(1); 17.976 - sbenable=sb_8_enable; 17.977 - pclog("SB pause over\n"); 17.978 - } 17.979 - } 17.980 -} 17.981 - 17.982 -void sb_poll_i() 17.983 -{ 17.984 -// pclog("PollSBi %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output); 17.985 - if (sb_8_enable && !sb_8_pause && sb_pausetime<0 && !sb_8_output) 17.986 - { 17.987 - switch (sb_8_format) 17.988 - { 17.989 - case 0x00: /*Mono unsigned*/ 17.990 - sb_8_write_dma(0x80); 17.991 - sb_8_length--; 17.992 - break; 17.993 - case 0x10: /*Mono signed*/ 17.994 - sb_8_write_dma(0x00); 17.995 - sb_8_length--; 17.996 - break; 17.997 - case 0x20: /*Stereo unsigned*/ 17.998 - sb_8_write_dma(0x80); 17.999 - sb_8_write_dma(0x80); 17.1000 - sb_8_length-=2; 17.1001 - break; 17.1002 - case 0x30: /*Stereo signed*/ 17.1003 - sb_8_write_dma(0x00); 17.1004 - sb_8_write_dma(0x00); 17.1005 - sb_8_length-=2; 17.1006 - break; 17.1007 - 17.1008 -// default: 17.1009 -// fatal("Unrecognised SB 8-bit input format %02X\n",sb_8_format); 17.1010 - } 17.1011 - 17.1012 - if (sb_8_length<0) 17.1013 - { 17.1014 -// pclog("Input DMA over %i\n",sb_8_autoinit); 17.1015 - if (sb_8_autoinit) sb_8_length=sb_8_autolen; 17.1016 - else sb_8_enable=sbenable=0; 17.1017 - sb_irq(1); 17.1018 - } 17.1019 - } 17.1020 - if (sb_16_enable && !sb_16_pause && sb_pausetime<0 && !sb_16_output) 17.1021 - { 17.1022 - switch (sb_16_format) 17.1023 - { 17.1024 - case 0x00: /*Unsigned mono*/ 17.1025 - sb_16_write_dma(0x8000); 17.1026 - sb_16_length--; 17.1027 - break; 17.1028 - case 0x10: /*Signed mono*/ 17.1029 - sb_16_write_dma(0); 17.1030 - sb_16_length--; 17.1031 - break; 17.1032 - case 0x20: /*Unsigned stereo*/ 17.1033 - sb_16_write_dma(0x8000); 17.1034 - sb_16_write_dma(0x8000); 17.1035 - sb_16_length-=2; 17.1036 - break; 17.1037 - case 0x30: /*Signed stereo*/ 17.1038 - sb_16_write_dma(0); 17.1039 - sb_16_write_dma(0); 17.1040 - sb_16_length-=2; 17.1041 - break; 17.1042 - 17.1043 -// default: 17.1044 -// fatal("Unrecognised SB 16-bit input format %02X\n",sb_16_format); 17.1045 - } 17.1046 - 17.1047 - if (sb_16_length<0) 17.1048 - { 17.1049 -// pclog("16iDMA over %i\n",sb_16_autoinit); 17.1050 - if (sb_16_autoinit) sb_16_length=sb_16_autolen; 17.1051 - else sb_16_enable=sbenable=0; 17.1052 - sb_irq(0); 17.1053 - } 17.1054 - } 17.1055 -} 17.1056 - 17.1057 -int16_t sbbuffer[2][SOUNDBUFLEN+20]; 17.1058 -int sbbufferpos=0; 17.1059 -int _sampcnt=0; 17.1060 -int16_t sb_filtbuf[4]={0,0,0,0}; 17.1061 -void getsbsamp() 17.1062 -{ 17.1063 - int vocl=sbpmixer.vocl*sbpmixer.masl; 17.1064 - int vocr=sbpmixer.vocr*sbpmixer.masr; 17.1065 - int16_t sbdat[2]; 17.1066 - double t; 17.1067 - 17.1068 - vocl=256-vocl; 17.1069 - vocr=256-vocr; 17.1070 - if (!vocl) vocl=1; 17.1071 - if (!vocr) vocr=1; 17.1072 - if (sbbufferpos>=(SOUNDBUFLEN+20)) return; 17.1073 - 17.1074 - sbdat[0]=sbdatl; 17.1075 - sbdat[1]=sbdatr; 17.1076 - 17.1077 - if (mixer.filter) 17.1078 - { 17.1079 - /*3.2kHz output filter*/ 17.1080 - sbdat[0]=(int16_t)(sb_iir(0,(float)sbdat[0])/1.3); 17.1081 - sbdat[1]=(int16_t)(sb_iir(1,(float)sbdat[1])/1.3); 17.1082 - } 17.1083 - 17.1084 - sbbuffer[0][sbbufferpos]=sbdat[0]; 17.1085 - sbbuffer[1][sbbufferpos]=sbdat[1]; 17.1086 - sbbufferpos++; 17.1087 -} 17.1088 - 17.1089 -void addsb(int16_t *p) 17.1090 -{ 17.1091 - int c; 17.1092 - if (sbbufferpos>SOUNDBUFLEN) sbbufferpos=SOUNDBUFLEN; 17.1093 -// printf("Addsb - %i %04X\n",sbbufferpos,p[0]); 17.1094 - for (c=0;c<sbbufferpos;c++) 17.1095 - { 17.1096 - p[c<<1]+=(((sbbuffer[0][c]/3)*mixer.voice_l)>>16); 17.1097 - p[(c<<1)+1]+=(((sbbuffer[1][c]/3)*mixer.voice_r)>>16); 17.1098 -// if (!c) pclog("V %04X %04X %04X\n",sbbuffer[0][c],p[c<<1],mixer.voice_l); 17.1099 - } 17.1100 - for (;c<SOUNDBUFLEN;c++) 17.1101 - { 17.1102 - p[c<<1]+=(((sbbuffer[0][sbbufferpos-1]/3)*mixer.voice_l)>>16); 17.1103 - p[(c<<1)+1]+=(((sbbuffer[0][sbbufferpos-1]/3)*mixer.voice_l)>>16); 17.1104 - } 17.1105 - sbbufferpos=0; 17.1106 -} 17.1107 -
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/src/sound_adlib.c Mon May 27 19:56:33 2013 +0100 18.3 @@ -0,0 +1,62 @@ 18.4 +#include <stdlib.h> 18.5 +#include "ibm.h" 18.6 +#include "device.h" 18.7 +#include "sound.h" 18.8 + 18.9 +#include "sound_adlib.h" 18.10 +#include "sound_opl.h" 18.11 + 18.12 +typedef struct adlib_t 18.13 +{ 18.14 + opl_t opl; 18.15 + int16_t buffer[SOUNDBUFLEN * 2]; 18.16 + int pos; 18.17 +} adlib_t; 18.18 + 18.19 +static void adlib_poll(void *p) 18.20 +{ 18.21 + adlib_t *adlib = (adlib_t *)p; 18.22 + 18.23 + if (adlib->pos >= SOUNDBUFLEN) return; 18.24 + 18.25 + opl2_poll(&adlib->opl, &adlib->buffer[adlib->pos * 2], &adlib->buffer[(adlib->pos * 2) + 1]); 18.26 + adlib->pos++; 18.27 +} 18.28 + 18.29 +static void adlib_get_buffer(int16_t *buffer, int len, void *p) 18.30 +{ 18.31 + adlib_t *adlib = (adlib_t *)p; 18.32 + int c; 18.33 + 18.34 + for (c = 0; c < len * 2; c++) 18.35 + buffer[c] += adlib->buffer[c]; 18.36 + 18.37 + adlib->pos = 0; 18.38 +} 18.39 + 18.40 +void *adlib_init() 18.41 +{ 18.42 + adlib_t *adlib = malloc(sizeof(adlib_t)); 18.43 + memset(adlib, 0, sizeof(adlib_t)); 18.44 + 18.45 + pclog("adlib_init\n"); 18.46 + opl2_init(&adlib->opl); 18.47 + io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); 18.48 + sound_add_handler(adlib_poll, adlib_get_buffer, adlib); 18.49 + return adlib; 18.50 +} 18.51 + 18.52 +void adlib_close(void *p) 18.53 +{ 18.54 + adlib_t *adlib = (adlib_t *)p; 18.55 + 18.56 + free(adlib); 18.57 +} 18.58 + 18.59 +device_t adlib_device = 18.60 +{ 18.61 + "AdLib", 18.62 + adlib_init, 18.63 + adlib_close, 18.64 + NULL 18.65 +};
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/src/sound_adlib.h Mon May 27 19:56:33 2013 +0100 19.3 @@ -0,0 +1,1 @@ 19.4 +extern device_t adlib_device;
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/src/sound_adlibgold.c Mon May 27 19:56:33 2013 +0100 20.3 @@ -0,0 +1,597 @@ 20.4 +#include <stdlib.h> 20.5 +#include <string.h> 20.6 +#include "ibm.h" 20.7 +#include "device.h" 20.8 + 20.9 +#include "sound_opl.h" 20.10 +#include "dma.h" 20.11 +#include "io.h" 20.12 +#include "pic.h" 20.13 +#include "pit.h" 20.14 +#include "timer.h" 20.15 + 20.16 +void adgold_timer_poll(); 20.17 + 20.18 +typedef struct adgold_t 20.19 +{ 20.20 + int adgold_irq_status; 20.21 + 20.22 + uint8_t adgold_eeprom[0x19]; 20.23 + 20.24 + uint8_t adgold_status; 20.25 + int adgold_38x_state, adgold_38x_addr; 20.26 + uint8_t adgold_38x_regs[0x19]; 20.27 + 20.28 + int adgold_mma_addr; 20.29 + uint8_t adgold_mma_regs[2][0xe]; 20.30 + 20.31 + int adgold_mma_enable[2]; 20.32 + uint8_t adgold_mma_fifo[2][256]; 20.33 + int adgold_mma_fifo_start[2], adgold_mma_fifo_end[2]; 20.34 + uint8_t adgold_mma_status; 20.35 + 20.36 + int16_t adgold_mma_out[2]; 20.37 + int adgold_mma_intpos[2]; 20.38 + 20.39 + int adgold_mma_timer_count; 20.40 + 20.41 + struct 20.42 + { 20.43 + int timer0_latch, timer0_count; 20.44 + int timerbase_latch, timerbase_count; 20.45 + int timer1_latch, timer1_count; 20.46 + int timer2_latch, timer2_count, timer2_read; 20.47 + 20.48 + int voice_count[2], voice_latch[2]; 20.49 + } adgold_mma; 20.50 + 20.51 + opl_t opl; 20.52 + 20.53 + int16_t opl_buffer[SOUNDBUFLEN * 2]; 20.54 + int16_t mma_buffer[2][SOUNDBUFLEN]; 20.55 + 20.56 + int pos; 20.57 +} adgold_t; 20.58 + 20.59 +void adgold_update_irq_status(adgold_t *adgold) 20.60 +{ 20.61 + uint8_t temp = 0xf; 20.62 + 20.63 + if (!(adgold->adgold_mma_regs[0][8] & 0x10) && (adgold->adgold_mma_status & 0x10)) /*Timer 0*/ 20.64 + temp &= ~2; 20.65 + if (!(adgold->adgold_mma_regs[0][8] & 0x20) && (adgold->adgold_mma_status & 0x20)) /*Timer 1*/ 20.66 + temp &= ~2; 20.67 + if (!(adgold->adgold_mma_regs[0][8] & 0x40) && (adgold->adgold_mma_status & 0x40)) /*Timer 2*/ 20.68 + temp &= ~2; 20.69 + 20.70 + if ((adgold->adgold_mma_status & 0x01) && !(adgold->adgold_mma_regs[0][0xc] & 2)) 20.71 + temp &= ~2; 20.72 + if ((adgold->adgold_mma_status & 0x02) && !(adgold->adgold_mma_regs[1][0xc] & 2)) 20.73 + temp &= ~2; 20.74 + adgold->adgold_status = temp; 20.75 + 20.76 + if ((adgold->adgold_status ^ 0xf) && !adgold->adgold_irq_status) 20.77 + { 20.78 + pclog("adgold irq %02X\n", adgold->adgold_status); 20.79 + picint(0x80); 20.80 + } 20.81 + 20.82 + adgold->adgold_irq_status = adgold->adgold_status ^ 0xf; 20.83 +} 20.84 + 20.85 +void adgold_getsamp_dma(adgold_t *adgold, int channel) 20.86 +{ 20.87 + int temp; 20.88 + 20.89 + if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127)) 20.90 + return; 20.91 + 20.92 + temp = readdma1(); 20.93 +// pclog("adgold DMA1 return %02X %i L\n", temp, channel); 20.94 + if (temp == -1) return; 20.95 + adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; 20.96 + adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; 20.97 + if (adgold->adgold_mma_regs[channel][0xc] & 0x60) 20.98 + { 20.99 + temp = readdma1(); 20.100 +// pclog("adgold DMA1 return %02X %i H\n", temp, channel); 20.101 + adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; 20.102 + adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; 20.103 + } 20.104 + if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= adgold->adgold_mma_intpos[channel]) 20.105 + { 20.106 + adgold->adgold_mma_status &= ~(0x01 << channel); 20.107 + adgold_update_irq_status(adgold); 20.108 + } 20.109 +} 20.110 + 20.111 +void adgold_write(uint16_t addr, uint8_t val, void *p) 20.112 +{ 20.113 + adgold_t *adgold = (adgold_t *)p; 20.114 + if (addr > 0x389) pclog("adgold_write : addr %04X val %02X %04X:%04X\n", addr, val, CS, pc); 20.115 + switch (addr & 7) 20.116 + { 20.117 + case 0: case 1: 20.118 + opl3_write(addr, val, &adgold->opl); 20.119 + break; 20.120 + 20.121 + case 2: 20.122 + if (val == 0xff) 20.123 + { 20.124 + adgold->adgold_38x_state = 1; 20.125 + return; 20.126 + } 20.127 + if (val == 0xfe) 20.128 + { 20.129 + adgold->adgold_38x_state = 0; 20.130 + return; 20.131 + } 20.132 + if (adgold->adgold_38x_state) /*Write to control chip*/ 20.133 + adgold->adgold_38x_addr = val; 20.134 + else 20.135 + opl3_write(addr, val, &adgold->opl); 20.136 + break; 20.137 + case 3: 20.138 + if (adgold->adgold_38x_state) 20.139 + { 20.140 + if (adgold->adgold_38x_addr >= 0x19) break; 20.141 + switch (adgold->adgold_38x_addr) 20.142 + { 20.143 + case 0x00: /*Control/ID*/ 20.144 + if (val & 1) 20.145 + memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19); 20.146 + if (val & 2) 20.147 + memcpy(adgold->adgold_eeprom, adgold->adgold_38x_regs, 0x19); 20.148 + break; 20.149 + 20.150 + default: 20.151 + adgold->adgold_38x_regs[adgold->adgold_38x_addr] = val; 20.152 + break; 20.153 + } 20.154 + } 20.155 + else 20.156 + opl3_write(addr, val, &adgold->opl); 20.157 + break; 20.158 + case 4: case 6: 20.159 + adgold->adgold_mma_addr = val; 20.160 + break; 20.161 + case 5: 20.162 + if (adgold->adgold_mma_addr >= 0xf) break; 20.163 + switch (adgold->adgold_mma_addr) 20.164 + { 20.165 + case 0x2: 20.166 + adgold->adgold_mma.timer0_latch = (adgold->adgold_mma.timer0_latch & 0xff00) | val; 20.167 + break; 20.168 + case 0x3: 20.169 + adgold->adgold_mma.timer0_latch = (adgold->adgold_mma.timer0_latch & 0xff) | (val << 8); 20.170 + break; 20.171 + case 0x4: 20.172 + adgold->adgold_mma.timerbase_latch = (adgold->adgold_mma.timerbase_latch & 0xf00) | val; 20.173 + break; 20.174 + case 0x5: 20.175 + adgold->adgold_mma.timerbase_latch = (adgold->adgold_mma.timerbase_latch & 0xff) | ((val & 0xf) << 8); 20.176 + adgold->adgold_mma.timer1_latch = val >> 4; 20.177 + break; 20.178 + case 0x6: 20.179 + adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff00) | val; 20.180 + break; 20.181 + case 0x7: 20.182 + adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff) | (val << 8); 20.183 + break; 20.184 + 20.185 + case 0x8: 20.186 + if ((val & 1) && !(adgold->adgold_mma_regs[0][8] & 1)) /*Reload timer 0*/ 20.187 + adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch; 20.188 + 20.189 + if ((val & 2) && !(adgold->adgold_mma_regs[0][8] & 2)) /*Reload timer 1*/ 20.190 + adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch; 20.191 + 20.192 + if ((val & 4) && !(adgold->adgold_mma_regs[0][8] & 4)) /*Reload timer 2*/ 20.193 + adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch; 20.194 + 20.195 + if ((val & 8) && !(adgold->adgold_mma_regs[0][8] & 8)) /*Reload base timer*/ 20.196 + adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch; 20.197 + break; 20.198 + 20.199 + case 0x9: 20.200 + switch (val & 0x18) 20.201 + { 20.202 + case 0x00: adgold->adgold_mma.voice_latch[0] = 12; break; /*44100 Hz*/ 20.203 + case 0x08: adgold->adgold_mma.voice_latch[0] = 24; break; /*22050 Hz*/ 20.204 + case 0x10: adgold->adgold_mma.voice_latch[0] = 48; break; /*11025 Hz*/ 20.205 + case 0x18: adgold->adgold_mma.voice_latch[0] = 72; break; /* 7350 Hz*/ 20.206 + } 20.207 + if (val & 0x80) 20.208 + { 20.209 + adgold->adgold_mma_enable[0] = 0; 20.210 + adgold->adgold_mma_fifo_end[0] = adgold->adgold_mma_fifo_start[0] = 0; 20.211 + adgold->adgold_mma_status &= ~0x01; 20.212 + adgold_update_irq_status(adgold); 20.213 + } 20.214 + if ((val & 0x01)) /*Start playback*/ 20.215 + { 20.216 + if (!(adgold->adgold_mma_regs[0][0x9] & 1)) 20.217 + adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0]; 20.218 + 20.219 + pclog("adgold start! FIFO fill %i %i %i %02X\n", (adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255, adgold->adgold_mma_fifo_end[0], adgold->adgold_mma_fifo_start[0], adgold->adgold_mma_regs[0][0xc]); 20.220 + if (adgold->adgold_mma_regs[0][0xc] & 1) 20.221 + { 20.222 + if (adgold->adgold_mma_regs[0][0xc] & 0x80) 20.223 + { 20.224 +// pclog("adgold start interleaved %i %i 20.225 + adgold->adgold_mma_enable[1] = 1; 20.226 + adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; 20.227 + 20.228 + while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) 20.229 + { 20.230 + adgold_getsamp_dma(adgold, 0); 20.231 + adgold_getsamp_dma(adgold, 1); 20.232 + } 20.233 + if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) 20.234 + { 20.235 + adgold->adgold_mma_status &= ~0x01; 20.236 + adgold_update_irq_status(adgold); 20.237 + } 20.238 + if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) 20.239 + { 20.240 + adgold->adgold_mma_status &= ~0x02; 20.241 + adgold_update_irq_status(adgold); 20.242 + } 20.243 + } 20.244 + else 20.245 + { 20.246 + while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) 20.247 + { 20.248 + adgold_getsamp_dma(adgold, 0); 20.249 + } 20.250 + if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) 20.251 + { 20.252 + adgold->adgold_mma_status &= ~0x01; 20.253 + adgold_update_irq_status(adgold); 20.254 + } 20.255 + } 20.256 + } 20.257 + pclog("adgold end\n"); 20.258 + } 20.259 + adgold->adgold_mma_enable[0] = val & 0x01; 20.260 + break; 20.261 + 20.262 + case 0xb: 20.263 + if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) 20.264 + { 20.265 + adgold->adgold_mma_fifo[0][adgold->adgold_mma_fifo_end[0]] = val; 20.266 + adgold->adgold_mma_fifo_end[0] = (adgold->adgold_mma_fifo_end[0] + 1) & 255; 20.267 + if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) 20.268 + { 20.269 + adgold->adgold_mma_status &= ~0x01; 20.270 + adgold_update_irq_status(adgold); 20.271 + } 20.272 + } 20.273 + break; 20.274 + 20.275 + case 0xc: 20.276 + adgold->adgold_mma_intpos[0] = (7 - ((val >> 2) & 7)) * 8; 20.277 + break; 20.278 + } 20.279 + adgold->adgold_mma_regs[0][adgold->adgold_mma_addr] = val; 20.280 + break; 20.281 + case 7: 20.282 + if (adgold->adgold_mma_addr >= 0xf) break; 20.283 + switch (adgold->adgold_mma_addr) 20.284 + { 20.285 + case 0x9: 20.286 + switch (val & 0x18) 20.287 + { 20.288 + case 0x00: adgold->adgold_mma.voice_latch[1] = 12; break; /*44100 Hz*/ 20.289 + case 0x08: adgold->adgold_mma.voice_latch[1] = 24; break; /*22050 Hz*/ 20.290 + case 0x10: adgold->adgold_mma.voice_latch[1] = 48; break; /*11025 Hz*/ 20.291 + case 0x18: adgold->adgold_mma.voice_latch[1] = 72; break; /* 7350 Hz*/ 20.292 + } 20.293 + if (val & 0x80) 20.294 + { 20.295 + adgold->adgold_mma_enable[1] = 0; 20.296 + adgold->adgold_mma_fifo_end[1] = adgold->adgold_mma_fifo_start[1] = 0; 20.297 + adgold->adgold_mma_status &= ~0x02; 20.298 + adgold_update_irq_status(adgold); 20.299 + } 20.300 + if ((val & 0x01)) /*Start playback*/ 20.301 + { 20.302 + if (!(adgold->adgold_mma_regs[1][0x9] & 1)) 20.303 + adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; 20.304 + 20.305 + pclog("adgold start! FIFO fill %i %i %i %02X\n", (adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255, adgold->adgold_mma_fifo_end[1], adgold->adgold_mma_fifo_start[1], adgold->adgold_mma_regs[1][0xc]); 20.306 + if (adgold->adgold_mma_regs[1][0xc] & 1) 20.307 + { 20.308 + while (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) 20.309 + { 20.310 + adgold_getsamp_dma(adgold, 1); 20.311 + } 20.312 + } 20.313 + pclog("adgold end\n"); 20.314 + } 20.315 + adgold->adgold_mma_enable[1] = val & 0x01; 20.316 + break; 20.317 + 20.318 + case 0xb: 20.319 + if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) 20.320 + { 20.321 + adgold->adgold_mma_fifo[1][adgold->adgold_mma_fifo_end[1]] = val; 20.322 + adgold->adgold_mma_fifo_end[1] = (adgold->adgold_mma_fifo_end[1] + 1) & 255; 20.323 + if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) 20.324 + { 20.325 + adgold->adgold_mma_status &= ~0x02; 20.326 + adgold_update_irq_status(adgold); 20.327 + } 20.328 + } 20.329 + break; 20.330 + 20.331 + case 0xc: 20.332 + adgold->adgold_mma_intpos[1] = (7 - ((val >> 2) & 7)) * 8; 20.333 + break; 20.334 + } 20.335 + adgold->adgold_mma_regs[1][adgold->adgold_mma_addr] = val; 20.336 + break; 20.337 + } 20.338 +} 20.339 + 20.340 +uint8_t adgold_read(uint16_t addr, void *p) 20.341 +{ 20.342 + adgold_t *adgold = (adgold_t *)p; 20.343 + uint8_t temp; 20.344 + 20.345 + switch (addr & 7) 20.346 + { 20.347 + case 0: case 1: 20.348 + temp = opl3_read(addr, &adgold->opl); 20.349 + break; 20.350 + 20.351 + case 2: 20.352 + if (adgold->adgold_38x_state) /*Read from control chip*/ 20.353 + temp = adgold->adgold_status; 20.354 + else 20.355 + temp = opl3_read(addr, &adgold->opl); 20.356 + break; 20.357 + 20.358 + case 3: 20.359 + if (adgold->adgold_38x_state) 20.360 + { 20.361 + if (adgold->adgold_38x_addr >= 0x19) temp = 0xff; 20.362 + switch (adgold->adgold_38x_addr) 20.363 + { 20.364 + case 0x00: /*Control/ID*/ 20.365 + temp = 0x70; /*16-bit ISA, no telephone/surround/CD-ROM*/ 20.366 + break; 20.367 + 20.368 + default: 20.369 + temp = adgold->adgold_38x_regs[adgold->adgold_38x_addr]; 20.370 + } 20.371 + } 20.372 + else 20.373 + temp = opl3_read(addr, &adgold->opl); 20.374 + break; 20.375 + 20.376 + case 4: case 6: 20.377 + temp = adgold->adgold_mma_status; 20.378 + adgold->adgold_mma_status = 0; /*JUKEGOLD expects timer status flags to auto-clear*/ 20.379 + adgold_update_irq_status(adgold); 20.380 + break; 20.381 + case 5: 20.382 + if (adgold->adgold_mma_addr >= 0xf) temp = 0xff; 20.383 + switch (adgold->adgold_mma_addr) 20.384 + { 20.385 + case 6: /*Timer 2 low*/ 20.386 + adgold->adgold_mma.timer2_read = adgold->adgold_mma.timer2_count; 20.387 + temp = adgold->adgold_mma.timer2_read & 0xff; 20.388 + break; 20.389 + case 7: /*Timer 2 high*/ 20.390 + temp = adgold->adgold_mma.timer2_read >> 8; 20.391 + break; 20.392 + 20.393 + default: 20.394 + temp = adgold->adgold_mma_regs[0][adgold->adgold_mma_addr]; 20.395 + break; 20.396 + } 20.397 + break; 20.398 + case 7: 20.399 + if (adgold->adgold_mma_addr >= 0xf) temp = 0xff; 20.400 + temp = adgold->adgold_mma_regs[1][adgold->adgold_mma_addr]; 20.401 + break; 20.402 + } 20.403 + if (addr > 0x389) pclog("adgold_read : addr %04X %02X\n", addr, temp); 20.404 + return temp; 20.405 +} 20.406 + 20.407 +void adgold_mma_poll(adgold_t *adgold, int channel) 20.408 +{ 20.409 + int16_t dat; 20.410 + 20.411 + if (adgold->adgold_mma_fifo_start[channel] != adgold->adgold_mma_fifo_end[channel]) 20.412 + { 20.413 + switch (adgold->adgold_mma_regs[channel][0xc] & 0x60) 20.414 + { 20.415 + case 0x00: /*8-bit*/ 20.416 + dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] * 256; 20.417 + adgold->adgold_mma_out[channel] = dat; 20.418 + adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; 20.419 + break; 20.420 + 20.421 + case 0x40: /*12-bit sensible format*/ 20.422 + if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < 2) 20.423 + return; 20.424 + 20.425 + dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] & 0xf0; 20.426 + adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; 20.427 + dat |= (adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] << 8); 20.428 + adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; 20.429 + adgold->adgold_mma_out[channel] = dat; 20.430 + break; 20.431 + } 20.432 + 20.433 + if (adgold->adgold_mma_regs[channel][0xc] & 1) 20.434 + { 20.435 + adgold_getsamp_dma(adgold, channel); 20.436 + } 20.437 + if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < adgold->adgold_mma_intpos[channel] && !(adgold->adgold_mma_status & 0x01)) 20.438 + { 20.439 +// pclog("adgold_mma_poll - IRQ! %i\n", channel); 20.440 + adgold->adgold_mma_status |= 1 << channel; 20.441 + adgold_update_irq_status(adgold); 20.442 + } 20.443 + } 20.444 + if (adgold->adgold_mma_fifo_start[channel] == adgold->adgold_mma_fifo_end[channel]) 20.445 + { 20.446 + adgold->adgold_mma_enable[channel] = 0; 20.447 + } 20.448 +} 20.449 + 20.450 +void adgold_timer_poll(void *p) 20.451 +{ 20.452 + adgold_t *adgold = (adgold_t *)p; 20.453 + 20.454 + while (adgold->adgold_mma_timer_count <= 0) 20.455 + { 20.456 + adgold->adgold_mma_timer_count += (int)((double)TIMER_USEC * 1.88964); 20.457 + if (adgold->adgold_mma_regs[0][8] & 0x01) /*Timer 0*/ 20.458 + { 20.459 + adgold->adgold_mma.timer0_count--; 20.460 + if (!adgold->adgold_mma.timer0_count) 20.461 + { 20.462 + adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch; 20.463 + pclog("Timer 0 interrupt\n"); 20.464 + adgold->adgold_mma_status |= 0x10; 20.465 + adgold_update_irq_status(adgold); 20.466 + } 20.467 + } 20.468 + if (adgold->adgold_mma_regs[0][8] & 0x08) /*Base timer*/ 20.469 + { 20.470 + adgold->adgold_mma.timerbase_count--; 20.471 + if (!adgold->adgold_mma.timerbase_count) 20.472 + { 20.473 + adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch; 20.474 + if (adgold->adgold_mma_regs[0][8] & 0x02) /*Timer 1*/ 20.475 + { 20.476 + adgold->adgold_mma.timer1_count--; 20.477 + if (!adgold->adgold_mma.timer1_count) 20.478 + { 20.479 + adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch; 20.480 + pclog("Timer 1 interrupt\n"); 20.481 + adgold->adgold_mma_status |= 0x20; 20.482 + adgold_update_irq_status(adgold); 20.483 + } 20.484 + } 20.485 + if (adgold->adgold_mma_regs[0][8] & 0x04) /*Timer 2*/ 20.486 + { 20.487 + adgold->adgold_mma.timer2_count--; 20.488 + if (!adgold->adgold_mma.timer2_count) 20.489 + { 20.490 + adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch; 20.491 + pclog("Timer 2 interrupt\n"); 20.492 + adgold->adgold_mma_status |= 0x40; 20.493 + adgold_update_irq_status(adgold); 20.494 + } 20.495 + } 20.496 + } 20.497 + } 20.498 + 20.499 + if (adgold->adgold_mma_enable[0]) 20.500 + { 20.501 + adgold->adgold_mma.voice_count[0]--; 20.502 + if (!adgold->adgold_mma.voice_count[0]) 20.503 + { 20.504 + adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0]; 20.505 + adgold_mma_poll(adgold, 0); 20.506 + } 20.507 + } 20.508 + if (adgold->adgold_mma_enable[1]) 20.509 + { 20.510 + adgold->adgold_mma.voice_count[1]--; 20.511 + if (!adgold->adgold_mma.voice_count[1]) 20.512 + { 20.513 + adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; 20.514 + adgold_mma_poll(adgold, 1); 20.515 + } 20.516 + } 20.517 + } 20.518 +} 20.519 + 20.520 +void adgold_poll(void *p) 20.521 +{ 20.522 + adgold_t *adgold = (adgold_t *)p; 20.523 + 20.524 + if (adgold->pos >= SOUNDBUFLEN) 20.525 + return; 20.526 + 20.527 + opl3_poll(&adgold->opl, &adgold->opl_buffer[adgold->pos * 2], &adgold->opl_buffer[(adgold->pos * 2) + 1]); 20.528 + adgold->mma_buffer[0][adgold->pos] = adgold->mma_buffer[1][adgold->pos] = 0; 20.529 + 20.530 + if (adgold->adgold_mma_regs[0][9] & 0x20) 20.531 + adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[0] / 2; 20.532 + if (adgold->adgold_mma_regs[0][9] & 0x40) 20.533 + adgold->mma_buffer[1][adgold->pos] += adgold->adgold_mma_out[0] / 2; 20.534 + 20.535 + if (adgold->adgold_mma_regs[1][9] & 0x20) 20.536 + adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[1] / 2; 20.537 + if (adgold->adgold_mma_regs[1][9] & 0x40) 20.538 + adgold->mma_buffer[1][adgold->pos] += adgold->adgold_mma_out[1] / 2; 20.539 + 20.540 + adgold->pos++; 20.541 +} 20.542 + 20.543 +static void adgold_get_buffer(int16_t *buffer, int len, void *p) 20.544 +{ 20.545 + adgold_t *adgold = (adgold_t *)p; 20.546 + 20.547 + int c; 20.548 + 20.549 + for (c = 0; c < len * 2; c++) 20.550 + { 20.551 + buffer[c] += adgold->opl_buffer[c]; 20.552 + buffer[c] += adgold->mma_buffer[c & 1][c >> 1] / 2; 20.553 + } 20.554 + 20.555 + adgold->pos = 0; 20.556 +} 20.557 + 20.558 + 20.559 +void *adgold_init() 20.560 +{ 20.561 + adgold_t *adgold = malloc(sizeof(adgold_t)); 20.562 + memset(adgold, 0, sizeof(adgold_t)); 20.563 + 20.564 + opl3_init(&adgold->opl); 20.565 + 20.566 + adgold->adgold_status = 0xf; 20.567 + adgold->adgold_38x_addr = 0; 20.568 + adgold->adgold_eeprom[0x09] = adgold->adgold_eeprom[0x0a] = 255; 20.569 + adgold->adgold_eeprom[0x13] = 3 | (1 << 4); /*IRQ 7, DMA 1*/ 20.570 + adgold->adgold_eeprom[0x14] = 3 << 4; /*DMA 3*/ 20.571 + adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/ 20.572 + memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19); 20.573 + 20.574 + adgold->adgold_mma_enable[0] = 0; 20.575 + adgold->adgold_mma_fifo_start[0] = adgold->adgold_mma_fifo_end[0] = 0; 20.576 + 20.577 + /*388/389 are handled by adlib_init*/ 20.578 + io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold); 20.579 + 20.580 + timer_add(adgold_timer_poll, &adgold->adgold_mma_timer_count, TIMER_ALWAYS_ENABLED, adgold); 20.581 + 20.582 + sound_add_handler(adgold_poll, adgold_get_buffer, adgold); 20.583 + 20.584 + return adgold; 20.585 +} 20.586 + 20.587 +void adgold_close(void *p) 20.588 +{ 20.589 + adgold_t *adgold = (adgold_t *)p; 20.590 + 20.591 + free(adgold); 20.592 +} 20.593 + 20.594 +device_t adgold_device = 20.595 +{ 20.596 + "AdLib Gold", 20.597 + adgold_init, 20.598 + adgold_close, 20.599 + NULL 20.600 +};
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/src/sound_adlibgold.h Mon May 27 19:56:33 2013 +0100 21.3 @@ -0,0 +1,1 @@ 21.4 +extern device_t adgold_device;
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/src/sound_cms.c Mon May 27 19:56:33 2013 +0100 22.3 @@ -0,0 +1,179 @@ 22.4 +#include <stdio.h> 22.5 +#include <stdlib.h> 22.6 +#include "ibm.h" 22.7 + 22.8 +#include "device.h" 22.9 +#include "io.h" 22.10 +#include "sound.h" 22.11 +#include "sound_cms.h" 22.12 + 22.13 +typedef struct cms_t 22.14 +{ 22.15 + int addrs[2]; 22.16 + uint8_t regs[2][32]; 22.17 + uint16_t latch[2][6]; 22.18 + int freq[2][6]; 22.19 + float count[2][6]; 22.20 + int vol[2][6][2]; 22.21 + int stat[2][6]; 22.22 + uint16_t noise[2][2]; 22.23 + uint16_t noisefreq[2][2]; 22.24 + int noisecount[2][2]; 22.25 + int noisetype[2][2]; 22.26 + 22.27 + int16_t buffer[SOUNDBUFLEN * 2]; 22.28 + 22.29 + int pos; 22.30 +} cms_t; 22.31 + 22.32 +void cms_poll(void *p) 22.33 +{ 22.34 + cms_t *cms = (cms_t *)p; 22.35 + int c, d; 22.36 + int16_t out_l = 0, out_r = 0; 22.37 + 22.38 + if (cms->pos >= SOUNDBUFLEN) 22.39 + return; 22.40 + 22.41 + for (c = 0; c < 4; c++) 22.42 + { 22.43 + switch (cms->noisetype[c >> 1][c & 1]) 22.44 + { 22.45 + case 0: cms->noisefreq[c >> 1][c & 1] = 31250; break; 22.46 + case 1: cms->noisefreq[c >> 1][c & 1] = 15625; break; 22.47 + case 2: cms->noisefreq[c >> 1][c & 1] = 7812; break; 22.48 + case 3: cms->noisefreq[c >> 1][c & 1] = cms->freq[c >> 1][(c & 1) * 3]; break; 22.49 + } 22.50 + } 22.51 + for (c = 0; c < 2; c ++) 22.52 + { 22.53 + if (cms->regs[c][0x1C] & 1) 22.54 + { 22.55 + for (d = 0; d < 6; d++) 22.56 + { 22.57 + if (cms->regs[c][0x14] & (1 << d)) 22.58 + { 22.59 + if (cms->stat[c][d]) out_l += (cms->vol[c][d][0] * 90); 22.60 + if (cms->stat[c][d]) out_r += (cms->vol[c][d][1] * 90); 22.61 + cms->count[c][d] += cms->freq[c][d]; 22.62 + if (cms->count[c][d] >= 24000) 22.63 + { 22.64 + cms->count[c][d] -= 24000; 22.65 + cms->stat[c][d] ^= 1; 22.66 + } 22.67 + } 22.68 + else if (cms->regs[c][0x15] & (1 << d)) 22.69 + { 22.70 + if (cms->noise[c][d / 3] & 1) out_l += (cms->vol[c][d][0] * 90); 22.71 + if (cms->noise[c][d / 3] & 1) out_r += (cms->vol[c][d][0] * 90); 22.72 + } 22.73 + } 22.74 + for (d = 0; d < 2; d++) 22.75 + { 22.76 + cms->noisecount[c][d] += cms->noisefreq[c][d]; 22.77 + while (cms->noisecount[c][d] >= 24000) 22.78 + { 22.79 + cms->noisecount[c][d] -= 24000; 22.80 + cms->noise[c][d] <<= 1; 22.81 + if (!(((cms->noise[c][d] & 0x4000) >> 8) ^ (cms->noise[c][d] & 0x40))) 22.82 + cms->noise[c][d] |= 1; 22.83 + } 22.84 + } 22.85 + } 22.86 + } 22.87 + cms->buffer[(cms->pos << 1)] = out_l; 22.88 + cms->buffer[(cms->pos << 1) + 1] = out_r; 22.89 + 22.90 + cms->pos++; 22.91 +} 22.92 + 22.93 +void cms_get_buffer(int16_t *buffer, int len, void *p) 22.94 +{ 22.95 + cms_t *cms = (cms_t *)p; 22.96 + 22.97 + int c; 22.98 + 22.99 + for (c = 0; c < len * 2; c++) 22.100 + buffer[c] += cms->buffer[c]; 22.101 + 22.102 + cms->pos = 0; 22.103 +} 22.104 + 22.105 +void cms_write(uint16_t addr, uint8_t val, void *p) 22.106 +{ 22.107 + cms_t *cms = (cms_t *)p; 22.108 + int voice; 22.109 + int chip = (addr & 2) >> 1; 22.110 + 22.111 + pclog("cms_write : addr %04X val %02X\n", addr, val); 22.112 + 22.113 + if (addr & 1) 22.114 + cms->addrs[chip] = val & 31; 22.115 + else 22.116 + { 22.117 + cms->regs[chip][cms->addrs[chip] & 31] = val; 22.118 + switch (cms->addrs[chip] & 31) 22.119 + { 22.120 + case 0x00: case 0x01: case 0x02: /*Volume*/ 22.121 + case 0x03: case 0x04: case 0x05: 22.122 + voice = cms->addrs[chip] & 7; 22.123 + cms->vol[chip][voice][0] = val & 0xf; 22.124 + cms->vol[chip][voice][1] = val >> 4; 22.125 + break; 22.126 + case 0x08: case 0x09: case 0x0A: /*Frequency*/ 22.127 + case 0x0B: case 0x0C: case 0x0D: 22.128 + voice = cms->addrs[chip] & 7; 22.129 + cms->latch[chip][voice] = (cms->latch[chip][voice] & 0x700) | val; 22.130 + cms->freq[chip][voice] = (15625 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); 22.131 + break; 22.132 + case 0x10: case 0x11: case 0x12: /*Octave*/ 22.133 + voice = (cms->addrs[chip] & 3) << 1; 22.134 + cms->latch[chip][voice] = (cms->latch[chip][voice] & 0xFF) | ((val & 7) << 8); 22.135 + cms->latch[chip][voice + 1] = (cms->latch[chip][voice + 1] & 0xFF) | ((val & 0x70) << 4); 22.136 + cms->freq[chip][voice] = (15625 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); 22.137 + cms->freq[chip][voice + 1] = (15625 << (cms->latch[chip][voice + 1] >> 8)) / (511 - (cms->latch[chip][voice + 1] & 255)); 22.138 + break; 22.139 + case 0x16: /*Noise*/ 22.140 + cms->noisetype[chip][0] = val & 3; 22.141 + cms->noisetype[chip][1] = (val >> 4) & 3; 22.142 + break; 22.143 + } 22.144 + } 22.145 +} 22.146 + 22.147 +uint8_t cms_read(uint16_t addr, void *p) 22.148 +{ 22.149 + cms_t *cms = (cms_t *)p; 22.150 + int chip = (addr & 2) >> 1; 22.151 + 22.152 + if (addr & 1) 22.153 + return cms->addrs[chip]; 22.154 + 22.155 + return cms->regs[chip][cms->addrs[chip] & 31]; 22.156 +} 22.157 + 22.158 +void *cms_init() 22.159 +{ 22.160 + cms_t *cms = malloc(sizeof(cms_t)); 22.161 + memset(cms, 0, sizeof(cms_t)); 22.162 + 22.163 + pclog("cms_init\n"); 22.164 + io_sethandler(0x0220, 0x0004, cms_read, NULL, NULL, cms_write, NULL, NULL, cms); 22.165 + sound_add_handler(cms_poll, cms_get_buffer, cms); 22.166 + return cms; 22.167 +} 22.168 + 22.169 +void cms_close(void *p) 22.170 +{ 22.171 + cms_t *cms = (cms_t *)p; 22.172 + 22.173 + free(cms); 22.174 +} 22.175 + 22.176 +device_t cms_device = 22.177 +{ 22.178 + "Creative Music System / Game Blaster", 22.179 + cms_init, 22.180 + cms_close, 22.181 + NULL 22.182 +};
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/src/sound_cms.h Mon May 27 19:56:33 2013 +0100 23.3 @@ -0,0 +1,1 @@ 23.4 +extern device_t cms_device;
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/src/sound_gus.c Mon May 27 19:56:33 2013 +0100 24.3 @@ -0,0 +1,1107 @@ 24.4 +#include <stdio.h> 24.5 +#include <stdlib.h> 24.6 +#include <string.h> 24.7 +#include "ibm.h" 24.8 + 24.9 +#include "device.h" 24.10 +#include "dma.h" 24.11 +#include "io.h" 24.12 +#include "pic.h" 24.13 +#include "sound.h" 24.14 +#include "sound_gus.h" 24.15 +#include "timer.h" 24.16 + 24.17 +typedef struct gus_t 24.18 +{ 24.19 + int reset; 24.20 + 24.21 + int global; 24.22 + uint32_t addr,dmaaddr; 24.23 + int voice; 24.24 + uint32_t start[32],end[32],cur[32]; 24.25 + uint32_t startx[32],endx[32],curx[32]; 24.26 + int rstart[32],rend[32]; 24.27 + int rcur[32]; 24.28 + uint16_t freq[32]; 24.29 + uint16_t rfreq[32]; 24.30 + uint8_t ctrl[32]; 24.31 + uint8_t rctrl[32]; 24.32 + int curvol[32]; 24.33 + int t1on,t2on; 24.34 + uint8_t tctrl; 24.35 + uint16_t t1,t2,t1l,t2l; 24.36 + uint8_t irqstatus,irqstatus2; 24.37 + uint8_t adcommand; 24.38 + int waveirqs[32],rampirqs[32]; 24.39 + int voices; 24.40 + uint8_t dmactrl; 24.41 + 24.42 + int16_t out_l, out_r; 24.43 + 24.44 + int16_t buffer[2][SOUNDBUFLEN]; 24.45 + int pos; 24.46 + 24.47 + int samp_timer, samp_latch; 24.48 + 24.49 + uint8_t *ram; 24.50 + 24.51 + int irqnext; 24.52 + 24.53 + int timer_1, timer_2; 24.54 + 24.55 + int irq, dma, irq_midi; 24.56 + int latch_enable; 24.57 + 24.58 + uint8_t sb_2xa, sb_2xc, sb_2xe; 24.59 + uint8_t sb_ctrl; 24.60 + int sb_nmi; 24.61 + 24.62 + uint8_t reg_ctrl; 24.63 + 24.64 + uint8_t ad_status, ad_data; 24.65 + uint8_t ad_timer_ctrl; 24.66 + 24.67 + uint8_t midi_ctrl, midi_status; 24.68 + uint8_t midi_data; 24.69 + int midi_loopback; 24.70 + 24.71 + uint8_t gp1, gp2; 24.72 + uint16_t gp1_addr, gp2_addr; 24.73 + 24.74 + uint8_t usrr; 24.75 +} gus_t; 24.76 + 24.77 +static int gus_irqs[8] = {-1, 2, 5, 3, 7, 11, 12, 15}; 24.78 +static int gus_irqs_midi[8] = {-1, 2, 5, 3, 7, 11, 12, 15}; 24.79 +static int gus_dmas[8] = {-1, 1, 3, 5, 6, 7, -1, -1}; 24.80 + 24.81 +int gusfreqs[]= 24.82 +{ 24.83 + 44100,41160,38587,36317,34300,32494,30870,29400,28063,26843,25725,24696, 24.84 + 23746,22866,22050,21289,20580,19916,19293 24.85 +}; 24.86 + 24.87 +double vol16bit[4096]; 24.88 + 24.89 +void pollgusirqs(gus_t *gus) 24.90 +{ 24.91 + int c; 24.92 + 24.93 + gus->irqstatus&=~0x60; 24.94 + for (c=0;c<32;c++) 24.95 + { 24.96 + if (gus->waveirqs[c]) 24.97 + { 24.98 +// gus->waveirqs[c]=0; 24.99 + gus->irqstatus2=0x60|c; 24.100 + if (gus->rampirqs[c]) gus->irqstatus2 |= 0x80; 24.101 + gus->irqstatus|=0x20; 24.102 +// printf("Voice IRQ %i %02X %i\n",c,gus->irqstatus2,ins); 24.103 + if (gus->irq != -1) 24.104 + picint(1 << gus->irq); 24.105 + return; 24.106 + } 24.107 + if (gus->rampirqs[c]) 24.108 + { 24.109 +// gus->rampirqs[c]=0; 24.110 + gus->irqstatus2=0xA0|c; 24.111 + gus->irqstatus|=0x40; 24.112 +// printf("Ramp IRQ %i %02X %i\n",c,gus->irqstatus2,ins); 24.113 + if (gus->irq != -1) 24.114 + picint(1 << gus->irq); 24.115 + return; 24.116 + } 24.117 + } 24.118 + gus->irqstatus2=0xE0; 24.119 +// gus->irqstatus&=~0x20; 24.120 + if (!gus->irqstatus && gus->irq != -1) picintc(1 << gus->irq); 24.121 +} 24.122 + 24.123 +enum 24.124 +{ 24.125 + MIDI_INT_RECEIVE = 0x01, 24.126 + MIDI_INT_TRANSMIT = 0x02, 24.127 + MIDI_INT_MASTER = 0x80 24.128 +}; 24.129 + 24.130 +enum 24.131 +{ 24.132 + MIDI_CTRL_TRANSMIT_MASK = 0x60, 24.133 + MIDI_CTRL_TRANSMIT = 0x20, 24.134 + MIDI_CTRL_RECEIVE = 0x80 24.135 +}; 24.136 + 24.137 +enum 24.138 +{ 24.139 + GUS_INT_MIDI_TRANSMIT = 0x01, 24.140 + GUS_INT_MIDI_RECEIVE = 0x02 24.141 +}; 24.142 + 24.143 +enum 24.144 +{ 24.145 + GUS_TIMER_CTRL_AUTO = 0x01 24.146 +}; 24.147 + 24.148 +void gus_midi_update_int_status(gus_t *gus) 24.149 +{ 24.150 + gus->midi_status &= ~MIDI_INT_MASTER; 24.151 + if ((gus->midi_ctrl & MIDI_CTRL_TRANSMIT_MASK) == MIDI_CTRL_TRANSMIT && (gus->midi_status & MIDI_INT_TRANSMIT)) 24.152 + { 24.153 + gus->midi_status |= MIDI_INT_MASTER; 24.154 + gus->irqstatus |= GUS_INT_MIDI_TRANSMIT; 24.155 + } 24.156 + else 24.157 + gus->irqstatus &= ~GUS_INT_MIDI_TRANSMIT; 24.158 + 24.159 + if ((gus->midi_ctrl & MIDI_CTRL_RECEIVE) && (gus->midi_status & MIDI_INT_RECEIVE)) 24.160 + { 24.161 + gus->midi_status |= MIDI_INT_MASTER; 24.162 + gus->irqstatus |= GUS_INT_MIDI_RECEIVE; 24.163 + } 24.164 + else 24.165 + gus->irqstatus &= ~GUS_INT_MIDI_RECEIVE; 24.166 + 24.167 + if ((gus->midi_status & MIDI_INT_MASTER) && (gus->irq_midi != -1)) 24.168 + { 24.169 +// pclog("Take MIDI IRQ\n"); 24.170 + picint(1 << gus->irq_midi); 24.171 + } 24.172 +} 24.173 + 24.174 +void writegus(uint16_t addr, uint8_t val, void *p) 24.175 +{ 24.176 + gus_t *gus = (gus_t *)p; 24.177 + int c, d; 24.178 + int old; 24.179 +// pclog("Write GUS %04X %02X %04X:%04X\n",addr,val,CS,pc); 24.180 + if (gus->latch_enable && addr != 0x24b) 24.181 + gus->latch_enable = 0; 24.182 + switch (addr) 24.183 + { 24.184 + case 0x340: /*MIDI control*/ 24.185 + old = gus->midi_ctrl; 24.186 + gus->midi_ctrl = val; 24.187 + 24.188 + if ((val & 3) == 3) 24.189 + gus->midi_status = 0; 24.190 + else if ((old & 3) == 3) 24.191 + { 24.192 + gus->midi_status |= MIDI_INT_TRANSMIT; 24.193 +// pclog("MIDI_INT_TRANSMIT\n"); 24.194 + } 24.195 + gus_midi_update_int_status(gus); 24.196 + break; 24.197 + 24.198 + case 0x341: /*MIDI data*/ 24.199 + if (gus->midi_loopback) 24.200 + { 24.201 + gus->midi_status |= MIDI_INT_RECEIVE; 24.202 + gus->midi_data = val; 24.203 + } 24.204 + else 24.205 + gus->midi_status |= MIDI_INT_TRANSMIT; 24.206 + break; 24.207 + 24.208 + case 0x342: /*Voice select*/ 24.209 + gus->voice=val&31; 24.210 + break; 24.211 + case 0x343: /*Global select*/ 24.212 + gus->global=val; 24.213 + break; 24.214 + case 0x344: /*Global low*/ 24.215 +// if (gus->global!=0x43 && gus->global!=0x44) printf("Writing register %02X %02X %02X %i\n",gus->global,gus->voice,val, ins); 24.216 + switch (gus->global) 24.217 + { 24.218 + case 0: /*Voice control*/ 24.219 +// if (val&1 && !(gus->ctrl[gus->voice]&1)) printf("Voice on %i\n",gus->voice); 24.220 + gus->ctrl[gus->voice]=val; 24.221 + break; 24.222 + case 1: /*Frequency control*/ 24.223 + gus->freq[gus->voice]=(gus->freq[gus->voice]&0xFF00)|val; 24.224 + break; 24.225 + case 2: /*Start addr high*/ 24.226 + gus->startx[gus->voice]=(gus->startx[gus->voice]&0xF807F)|(val<<7); 24.227 + gus->start[gus->voice]=(gus->start[gus->voice]&0x1F00FFFF)|(val<<16); 24.228 +// printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); 24.229 + break; 24.230 + case 3: /*Start addr low*/ 24.231 + gus->start[gus->voice]=(gus->start[gus->voice]&0x1FFFFF00)|val; 24.232 +// printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); 24.233 + break; 24.234 + case 4: /*End addr high*/ 24.235 + gus->endx[gus->voice]=(gus->endx[gus->voice]&0xF807F)|(val<<7); 24.236 + gus->end[gus->voice]=(gus->end[gus->voice]&0x1F00FFFF)|(val<<16); 24.237 +// printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); 24.238 + break; 24.239 + case 5: /*End addr low*/ 24.240 + gus->end[gus->voice]=(gus->end[gus->voice]&0x1FFFFF00)|val; 24.241 +// printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); 24.242 + break; 24.243 + 24.244 + case 0x6: /*Ramp frequency*/ 24.245 + gus->rfreq[gus->voice] = (int)( (double)((val & 63)*512)/(double)(1 << (3*(val >> 6)))); 24.246 +// printf("RFREQ %02X %i %i %f\n",val,gus->voice,gus->rfreq[gus->voice],(double)(val & 63)/(double)(1 << (3*(val >> 6)))); 24.247 + break; 24.248 + 24.249 + case 0x9: /*Current volume*/ 24.250 + gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 6)) | (val << 6); 24.251 +// printf("Vol %i is %04X\n",gus->voice,gus->curvol[gus->voice]); 24.252 + break; 24.253 + 24.254 + case 0xA: /*Current addr high*/ 24.255 + gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1F00FFFF)|(val<<16); 24.256 +gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); 24.257 +// gus->cur[gus->voice]=(gus->cur[gus->voice]&0x0F807F00)|((val<<7)<<8); 24.258 +// printf("Write %i cur %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); 24.259 + break; 24.260 + case 0xB: /*Current addr low*/ 24.261 + gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFFFF00)|val; 24.262 +// printf("Write %i cur %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); 24.263 + break; 24.264 + 24.265 + case 0x42: /*DMA address low*/ 24.266 + gus->dmaaddr=(gus->dmaaddr&0xFF000)|(val<<4); 24.267 + break; 24.268 + 24.269 + case 0x43: /*Address low*/ 24.270 + gus->addr=(gus->addr&0xFFF00)|val; 24.271 + break; 24.272 + case 0x45: /*Timer control*/ 24.273 +// printf("Timer control %02X\n",val); 24.274 + gus->tctrl=val; 24.275 + break; 24.276 + } 24.277 + break; 24.278 + case 0x345: /*Global high*/ 24.279 +// if (gus->global!=0x43 && gus->global!=0x44) printf("HWriting register %02X %02X %02X %04X:%04X %i %X\n",gus->global,gus->voice,val,CS,pc, ins, gus->rcur[1] >> 10); 24.280 + switch (gus->global) 24.281 + { 24.282 + case 0: /*Voice control*/ 24.283 + if (!(val&1) && gus->ctrl[gus->voice]&1) 24.284 + { 24.285 +// printf("Voice on %i - start %05X end %05X freq %04X\n",gus->voice,gus->start[gus->voice],gus->end[gus->voice],gus->freq[gus->voice]); 24.286 +// if (val&0x40) gus->cur[gus->voice]=gus->end[gus->voice]<<8; 24.287 +// else gus->cur[gus->voice]=gus->start[gus->voice]<<8; 24.288 + } 24.289 + 24.290 + gus->ctrl[gus->voice] = val & 0x7f; 24.291 + 24.292 + old = gus->waveirqs[gus->voice]; 24.293 + gus->waveirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; 24.294 + if (gus->waveirqs[gus->voice] != old) 24.295 + pollgusirqs(gus); 24.296 + break; 24.297 + case 1: /*Frequency control*/ 24.298 + gus->freq[gus->voice]=(gus->freq[gus->voice]&0xFF)|(val<<8); 24.299 + break; 24.300 + case 2: /*Start addr high*/ 24.301 + gus->startx[gus->voice]=(gus->startx[gus->voice]&0x07FFF)|(val<<15); 24.302 + gus->start[gus->voice]=(gus->start[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); 24.303 +// printf("Write %i start %08X %08X %02X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice],val); 24.304 + break; 24.305 + case 3: /*Start addr low*/ 24.306 + gus->startx[gus->voice]=(gus->startx[gus->voice]&0xFFF80)|(val&0x7F); 24.307 + gus->start[gus->voice]=(gus->start[gus->voice]&0x1FFF00FF)|(val<<8); 24.308 +// printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); 24.309 + break; 24.310 + case 4: /*End addr high*/ 24.311 + gus->endx[gus->voice]=(gus->endx[gus->voice]&0x07FFF)|(val<<15); 24.312 + gus->end[gus->voice]=(gus->end[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); 24.313 +// printf("Write %i end %08X %08X %02X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice],val); 24.314 + break; 24.315 + case 5: /*End addr low*/ 24.316 + gus->endx[gus->voice]=(gus->endx[gus->voice]&0xFFF80)|(val&0x7F); 24.317 + gus->end[gus->voice]=(gus->end[gus->voice]&0x1FFF00FF)|(val<<8); 24.318 +// printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); 24.319 + break; 24.320 + 24.321 + case 0x6: /*Ramp frequency*/ 24.322 + gus->rfreq[gus->voice] = (int)( (double)((val & 63) * (1 << 10))/(double)(1 << (3 * (val >> 6)))); 24.323 +// pclog("Ramp freq %02X %i %i %f %i\n", val, gus->voice, gus->rfreq[gus->voice], (double)(val & 63)/(double)(1 << (3*(val >> 6))), ins); 24.324 + break; 24.325 + case 0x7: /*Ramp start*/ 24.326 + gus->rstart[gus->voice] = val << 14; 24.327 +// pclog("Ramp start %04X\n", gus->rstart[gus->voice] >> 10); 24.328 + break; 24.329 + case 0x8: /*Ramp end*/ 24.330 + gus->rend[gus->voice] = val << 14; 24.331 +// pclog("Ramp end %04X\n", gus->rend[gus->voice] >> 10); 24.332 + break; 24.333 + case 0x9: /*Current volume*/ 24.334 + gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 14)) | (val << 14); 24.335 +// printf("Vol %i is %04X\n",gus->voice,gus->curvol[gus->voice]); 24.336 + break; 24.337 + 24.338 + case 0xA: /*Current addr high*/ 24.339 + gus->cur[gus->voice]=(gus->cur[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); 24.340 + gus->curx[gus->voice]=(gus->curx[gus->voice]&0x07FFF00)|((val<<15)<<8); 24.341 +// printf("Write %i cur %08X %08X %02X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice],val); 24.342 +// gus->cur[gus->voice]=(gus->cur[gus->voice]&0x007FFF00)|((val<<15)<<8); 24.343 + break; 24.344 + case 0xB: /*Current addr low*/ 24.345 + gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFF00FF)|(val<<8); 24.346 +gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); 24.347 +// gus->cur[gus->voice]=(gus->cur[gus->voice]&0x0FFF8000)|((val&0x7F)<<8); 24.348 +// printf("Write %i cur %08X %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); 24.349 + break; 24.350 + case 0xD: /*Ramp control*/ 24.351 + old = gus->rampirqs[gus->voice]; 24.352 + gus->rctrl[gus->voice] = val & 0x7F; 24.353 + gus->rampirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; 24.354 + if (gus->rampirqs[gus->voice] != old) 24.355 + pollgusirqs(gus); 24.356 +// printf("Ramp control %02i %02X %02X %i\n",gus->voice,val,gus->rampirqs[gus->voice],ins); 24.357 + break; 24.358 + 24.359 + case 0xE: 24.360 + gus->voices=(val&63)+1; 24.361 + if (gus->voices>32) gus->voices=32; 24.362 + if (gus->voices<14) gus->voices=14; 24.363 + gus->global=val; 24.364 +// printf("GUS voices %i\n",val&31); 24.365 + if (gus->voices < 14) 24.366 + gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); 24.367 + else 24.368 + gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); 24.369 + break; 24.370 + 24.371 + case 0x41: /*DMA*/ 24.372 + if (val&1 && gus->dma != -1) 24.373 + { 24.374 +// printf("DMA start! %05X %02X\n",gus->dmaaddr,val); 24.375 + if (val & 2) 24.376 + { 24.377 + c=0; 24.378 + while (c<65536) 24.379 + { 24.380 + d = gus->ram[gus->dmaaddr]; 24.381 + if (val & 0x80) d ^= 0x80; 24.382 + if (dma_channel_write(gus->dma, d) == DMA_NODATA) break; 24.383 + gus->dmaaddr++; 24.384 + gus->dmaaddr&=0xFFFFF; 24.385 + c++; 24.386 + } 24.387 +// printf("GUS->MEM Transferred %i bytes\n",c); 24.388 + gus->dmactrl=val&~0x40; 24.389 + if (val&0x20) gus->irqnext=1; 24.390 + } 24.391 + else 24.392 + { 24.393 + c=0; 24.394 + while (c<65536) 24.395 + { 24.396 + d = dma_channel_read(gus->dma); 24.397 + if (d == DMA_NODATA) break; 24.398 + if (val&0x80) d^=0x80; 24.399 + gus->ram[gus->dmaaddr]=d; 24.400 + gus->dmaaddr++; 24.401 + gus->dmaaddr&=0xFFFFF; 24.402 + c++; 24.403 + } 24.404 +// printf("MEM->GUS Transferred %i bytes\n",c); 24.405 + gus->dmactrl=val&~0x40; 24.406 + if (val&0x20) gus->irqnext=1; 24.407 + } 24.408 +// exit(-1); 24.409 + } 24.410 + break; 24.411 + 24.412 + case 0x42: /*DMA address low*/ 24.413 + gus->dmaaddr=(gus->dmaaddr&0xFF0)|(val<<12); 24.414 + break; 24.415 + 24.416 + case 0x43: /*Address low*/ 24.417 + gus->addr=(gus->addr&0xF00FF)|(val<<8); 24.418 + break; 24.419 + case 0x44: /*Address high*/ 24.420 + gus->addr=(gus->addr&0xFFFF)|((val<<16)&0xF0000); 24.421 + break; 24.422 + case 0x45: /*Timer control*/ 24.423 + if (!(val&4)) gus->irqstatus&=~4; 24.424 + if (!(val&8)) gus->irqstatus&=~8; 24.425 + if (!(val & 0x20)) 24.426 + { 24.427 + gus->ad_status &= ~0x18; 24.428 + nmi = 0; 24.429 + } 24.430 + if (!(val & 0x02)) 24.431 + { 24.432 + gus->ad_status &= ~0x01; 24.433 + nmi = 0; 24.434 + } 24.435 +// printf("Timer control %02X\n",val); 24.436 +/* if ((val&4) && !(gus->tctrl&4)) 24.437 + { 24.438 + gus->t1=gus->t1l; 24.439 + gus->t1on=1; 24.440 + }*/ 24.441 + gus->tctrl=val; 24.442 + gus->sb_ctrl = val; 24.443 + break; 24.444 + case 0x46: /*Timer 1*/ 24.445 + gus->t1 = gus->t1l = val; 24.446 + gus->t1on = 1; 24.447 +// printf("GUS timer 1 %i\n",val); 24.448 + break; 24.449 + case 0x47: /*Timer 2*/ 24.450 + gus->t2 = gus->t2l = val; 24.451 + gus->t2on = 1; 24.452 +// printf("GUS timer 2 %i\n",val); 24.453 + break; 24.454 + 24.455 + case 0x4c: /*Reset*/ 24.456 + gus->reset = val; 24.457 + break; 24.458 + } 24.459 + break; 24.460 + case 0x347: /*DRAM access*/ 24.461 + gus->ram[gus->addr]=val; 24.462 +// pclog("GUS RAM write %05X %02X\n",gus->addr,val); 24.463 + gus->addr&=0xFFFFF; 24.464 + break; 24.465 + case 0x248: case 0x388: 24.466 + gus->adcommand = val; 24.467 +// pclog("Setting ad command %02X %02X %p\n", val, gus->adcommand, &gus->adcommand); 24.468 + break; 24.469 + 24.470 + case 0x389: 24.471 + if ((gus->tctrl & GUS_TIMER_CTRL_AUTO) || gus->adcommand != 4) 24.472 + { 24.473 + gus->ad_data = val; 24.474 + gus->ad_status |= 0x01; 24.475 + if (gus->sb_ctrl & 0x02) 24.476 + { 24.477 + if (gus->sb_nmi) 24.478 + nmi = 1; 24.479 + else if (gus->irq != -1) 24.480 + picint(1 << gus->irq); 24.481 + } 24.482 + } 24.483 + else if (!(gus->tctrl & GUS_TIMER_CTRL_AUTO) && gus->adcommand == 4) 24.484 + { 24.485 + if (val & 0x80) 24.486 + { 24.487 + gus->ad_status &= ~0x60; 24.488 + } 24.489 + else 24.490 + { 24.491 + gus->ad_timer_ctrl = val; 24.492 + 24.493 + if (val & 0x01) 24.494 + gus->t1on = 1; 24.495 + else 24.496 + gus->t1 = gus->t1l; 24.497 + 24.498 + if (val & 0x02) 24.499 + gus->t2on = 1; 24.500 + else 24.501 + gus->t2 = gus->t2l; 24.502 + } 24.503 + } 24.504 + break; 24.505 + 24.506 + case 0x240: 24.507 + gus->midi_loopback = val & 0x20; 24.508 + gus->latch_enable = (val & 0x40) ? 2 : 1; 24.509 + break; 24.510 + 24.511 + case 0x24b: 24.512 + switch (gus->reg_ctrl & 0x07) 24.513 + { 24.514 + case 0: 24.515 + if (gus->latch_enable == 1) 24.516 + gus->dma = gus_dmas[val & 7]; 24.517 + if (gus->latch_enable == 2) 24.518 + { 24.519 + gus->irq = gus_irqs[val & 7]; 24.520 + if (val & 0x40) 24.521 + gus->irq_midi = gus->irq; 24.522 + else 24.523 + gus->irq_midi = gus_irqs_midi[(val >> 3) & 7]; 24.524 + 24.525 + gus->sb_nmi = val & 0x80; 24.526 + } 24.527 + gus->latch_enable = 0; 24.528 +// pclog("IRQ %i DMA %i\n", gus->irq, gus->dma); 24.529 + break; 24.530 + case 1: 24.531 + gus->gp1 = val; 24.532 + break; 24.533 + case 2: 24.534 + gus->gp2 = val; 24.535 + break; 24.536 + case 3: 24.537 + gus->gp1_addr = val; 24.538 + break; 24.539 + case 4: 24.540 + gus->gp2_addr = val; 24.541 + break; 24.542 + case 5: 24.543 + gus->usrr = 0; 24.544 + break; 24.545 + case 6: 24.546 + break; 24.547 + } 24.548 + break; 24.549 + 24.550 + case 0x246: 24.551 + gus->ad_status |= 0x08; 24.552 + if (gus->sb_ctrl & 0x20) 24.553 + { 24.554 + if (gus->sb_nmi) 24.555 + nmi = 1; 24.556 + else if (gus->irq != -1) 24.557 + picint(1 << gus->irq); 24.558 + } 24.559 + break; 24.560 + case 0x24a: 24.561 + gus->sb_2xa = val; 24.562 + break; 24.563 + case 0x24c: 24.564 + gus->ad_status |= 0x10; 24.565 + if (gus->sb_ctrl & 0x20) 24.566 + { 24.567 + if (gus->sb_nmi) 24.568 + nmi = 1; 24.569 + else if (gus->irq != -1) 24.570 + picint(1 << gus->irq); 24.571 + } 24.572 + case 0x24d: 24.573 + gus->sb_2xc = val; 24.574 + break; 24.575 + case 0x24e: 24.576 + gus->sb_2xe = val; 24.577 + break; 24.578 + case 0x24f: 24.579 + gus->reg_ctrl = val; 24.580 + break; 24.581 + } 24.582 +} 24.583 + 24.584 +uint8_t readgus(uint16_t addr, void *p) 24.585 +{ 24.586 + gus_t *gus = (gus_t *)p; 24.587 + uint8_t val; 24.588 +// /*if (addr!=0x246) */printf("Read GUS %04X %04X(%06X):%04X %02X\n",addr,CS,cs,pc,gus->global); 24.589 + switch (addr) 24.590 + { 24.591 + case 0x340: /*MIDI status*/ 24.592 + val = gus->midi_status; 24.593 +// pclog("Read MIDI status %02X\n", val); 24.594 + break; 24.595 + 24.596 + case 0x341: /*MIDI data*/ 24.597 + val = gus->midi_data; 24.598 + gus->midi_status &= ~MIDI_INT_RECEIVE; 24.599 + gus_midi_update_int_status(gus); 24.600 + break; 24.601 + 24.602 + case 0x240: return 0; 24.603 + case 0x246: /*IRQ status*/ 24.604 + val = gus->irqstatus & ~0x10; 24.605 + if (gus->ad_status & 0x19) 24.606 + val |= 0x10; 24.607 +// pclog("Read IRQ status %02X\n", val); 24.608 + return val; 24.609 + 24.610 + case 0x24F: return 0; 24.611 + case 0x342: return gus->voice; 24.612 + case 0x343: return gus->global; 24.613 + case 0x344: /*Global low*/ 24.614 +// /*if (gus->global!=0x43 && gus->global!=0x44) */printf("Reading register %02X %02X\n",gus->global,gus->voice); 24.615 + switch (gus->global) 24.616 + { 24.617 + case 0x82: /*Start addr high*/ 24.618 + return gus->start[gus->voice]>>16; 24.619 + case 0x83: /*Start addr low*/ 24.620 + return gus->start[gus->voice]&0xFF; 24.621 + 24.622 + case 0x89: /*Current volume*/ 24.623 + return gus->rcur[gus->voice]>>6; 24.624 + case 0x8A: /*Current addr high*/ 24.625 + return gus->cur[gus->voice]>>16; 24.626 + case 0x8B: /*Current addr low*/ 24.627 + return gus->cur[gus->voice]&0xFF; 24.628 + 24.629 + case 0x8F: /*IRQ status*/ 24.630 + val=gus->irqstatus2; 24.631 +// pclog("Read IRQ status - %02X\n",val); 24.632 + gus->rampirqs[gus->irqstatus2&0x1F]=0; 24.633 + gus->waveirqs[gus->irqstatus2&0x1F]=0; 24.634 + pollgusirqs(gus); 24.635 + return val; 24.636 + 24.637 + case 0x00: case 0x01: case 0x02: case 0x03: 24.638 + case 0x04: case 0x05: case 0x06: case 0x07: 24.639 + case 0x08: case 0x09: case 0x0a: case 0x0b: 24.640 + case 0x0c: case 0x0d: case 0x0e: case 0x0f: 24.641 + val = 0xff; 24.642 + break; 24.643 + 24.644 + default: 24.645 + fatal("Bad GUS global low read %02X\n",gus->global); 24.646 + } 24.647 + break; 24.648 + case 0x345: /*Global high*/ 24.649 +// /*if (gus->global!=0x43 && gus->global!=0x44) */printf("HReading register %02X %02X\n",gus->global,gus->voice); 24.650 + switch (gus->global) 24.651 + { 24.652 + case 0x80: /*Voice control*/ 24.653 +// pclog("Read voice control %02i %02X\n", gus->voice, gus->ctrl[gus->voice]|(gus->waveirqs[gus->voice]?0x80:0)); 24.654 + return gus->ctrl[gus->voice]|(gus->waveirqs[gus->voice]?0x80:0); 24.655 + 24.656 + case 0x82: /*Start addr high*/ 24.657 + return gus->start[gus->voice]>>24; 24.658 + case 0x83: /*Start addr low*/ 24.659 + return gus->start[gus->voice]>>8; 24.660 + 24.661 + case 0x89: /*Current volume*/ 24.662 +// pclog("Read current volume %i\n", gus->rcur[gus->voice] >> 14); 24.663 + return gus->rcur[gus->voice]>>14; 24.664 + 24.665 + case 0x8A: /*Current addr high*/ 24.666 + return gus->cur[gus->voice]>>24; 24.667 + case 0x8B: /*Current addr low*/ 24.668 + return gus->cur[gus->voice]>>8; 24.669 + 24.670 + case 0x8D: 24.671 +// pclog("Read ramp control %02X %04X %08X %08X %08X\n",gus->rctrl[gus->voice]|(gus->rampirqs[gus->voice]?0x80:0),gus->rcur[gus->voice] >> 14,gus->rfreq[gus->voice],gus->rstart[gus->voice],gus->rend[gus->voice]); 24.672 + return gus->rctrl[gus->voice]|(gus->rampirqs[gus->voice]?0x80:0); 24.673 + 24.674 + case 0x8F: /*IRQ status*/ 24.675 +// pclog("Read IRQ 1\n"); 24.676 + val=gus->irqstatus2; 24.677 + gus->rampirqs[gus->irqstatus2&0x1F]=0; 24.678 + gus->waveirqs[gus->irqstatus2&0x1F]=0; 24.679 + pollgusirqs(gus); 24.680 +// pclog("Read IRQ status - %02X %i %i\n",val, gus->waveirqs[gus->irqstatus2&0x1F], gus->rampirqs[gus->irqstatus2&0x1F]); 24.681 + return val; 24.682 + 24.683 + case 0x41: /*DMA control*/ 24.684 + val=gus->dmactrl|((gus->irqstatus&0x80)?0x40:0); 24.685 + gus->irqstatus&=~0x80; 24.686 + return val; 24.687 + case 0x45: /*Timer control*/ 24.688 + return gus->tctrl; 24.689 + case 0x49: /*Sampling control*/ 24.690 + return 0; 24.691 + 24.692 + case 0x00: case 0x01: case 0x02: case 0x03: 24.693 + case 0x04: case 0x05: case 0x06: case 0x07: 24.694 + case 0x08: case 0x09: case 0x0a: case 0x0b: 24.695 + case 0x0c: case 0x0d: case 0x0e: case 0x0f: 24.696 + val = 0xff; 24.697 + break; 24.698 + 24.699 + default: 24.700 + fatal("Bad GUS global high read %02X\n",gus->global); 24.701 + } 24.702 + break; 24.703 + case 0x346: return 0xff; 24.704 + case 0x347: /*DRAM access*/ 24.705 + val=gus->ram[gus->addr]; 24.706 +// pclog("GUS RAM read %05X %02X\n",gus->addr,val); 24.707 + gus->addr&=0xFFFFF; 24.708 + return val; 24.709 + case 0x349: return 0; 24.710 + case 0x746: /*Revision level*/ 24.711 + return 0xff; /*Pre 3.7 - no mixer*/ 24.712 + 24.713 + case 0x24b: 24.714 + switch (gus->reg_ctrl & 0x07) 24.715 + { 24.716 + case 1: 24.717 + val = gus->gp1; 24.718 + break; 24.719 + case 2: 24.720 + val = gus->gp2; 24.721 + break; 24.722 + case 3: 24.723 + val = gus->gp1_addr; 24.724 + break; 24.725 + case 4: 24.726 + val = gus->gp2_addr; 24.727 + break; 24.728 + } 24.729 + break; 24.730 + 24.731 + case 0x24c: 24.732 + val = gus->sb_2xc; 24.733 + if (gus->reg_ctrl & 0x20) 24.734 + gus->sb_2xc &= 0x80; 24.735 + break; 24.736 + case 0x24e: 24.737 +/* gus->ad_status |= 0x10; 24.738 + if (gus->reg_ctrl & 0x80) 24.739 + { 24.740 + gus->reg_ctrl_r |= 0x80; 24.741 + if (gus->sb_nmi) 24.742 + nmi = 1; 24.743 + else 24.744 + picint(1 << gus->irq); 24.745 + }*/ 24.746 + return gus->sb_2xe; 24.747 + 24.748 + case 0x248: case 0x388: 24.749 +// pclog("Read ad_status %02X\n", gus->ad_status); 24.750 + if (gus->tctrl & GUS_TIMER_CTRL_AUTO) 24.751 + val = gus->sb_2xa; 24.752 + else 24.753 + { 24.754 + val = gus->ad_status & ~(gus->ad_timer_ctrl & 0x60); 24.755 + if (val & 0x60) 24.756 + val |= 0x80; 24.757 + } 24.758 + break; 24.759 + 24.760 + case 0x249: 24.761 + gus->ad_status &= ~0x01; 24.762 + nmi = 0; 24.763 + case 0x389: 24.764 + val = gus->ad_data; 24.765 + break; 24.766 + 24.767 + case 0x24A: 24.768 + val = gus->adcommand; 24.769 +// pclog("Read ad command %02X %02X %p\n", gus->adcommand, val, &gus->adcommand); 24.770 + break; 24.771 + 24.772 + } 24.773 +// printf("Bad GUS read %04X! %02X\n",addr,gus->global); 24.774 +// exit(-1); 24.775 + return val; 24.776 +} 24.777 + 24.778 +void gus_poll_timer_1(void *p) 24.779 +{ 24.780 + gus_t *gus = (gus_t *)p; 24.781 + 24.782 + gus->timer_1 += (TIMER_USEC * 80); 24.783 +// pclog("gus_poll_timer_1 %i %i %i %i %02X\n", gustime, gus->t1on, gus->t1, gus->t1l, gus->tctrl); 24.784 + if (gus->t1on) 24.785 + { 24.786 + gus->t1++; 24.787 + if (gus->t1 > 0xFF) 24.788 + { 24.789 +// gus->t1on=0; 24.790 + gus->t1=gus->t1l; 24.791 + gus->ad_status |= 0x40; 24.792 + if (gus->tctrl&4) 24.793 + { 24.794 + if (gus->irq != -1) 24.795 + picint(1 << gus->irq); 24.796 + gus->ad_status |= 0x04; 24.797 + gus->irqstatus |= 0x04; 24.798 +// pclog("GUS T1 IRQ!\n"); 24.799 + } 24.800 + } 24.801 + } 24.802 + if (gus->irqnext) 24.803 + { 24.804 +// pclog("Take IRQ\n"); 24.805 + gus->irqnext=0; 24.806 + gus->irqstatus|=0x80; 24.807 + if (gus->irq != -1) 24.808 + picint(1 << gus->irq); 24.809 + } 24.810 + gus_midi_update_int_status(gus); 24.811 +} 24.812 + 24.813 +void gus_poll_timer_2(void *p) 24.814 +{ 24.815 + gus_t *gus = (gus_t *)p; 24.816 + 24.817 + gus->timer_2 += (TIMER_USEC * 320); 24.818 +// pclog("pollgus2 %i %i %i %i %02X\n", gustime, gus->t2on, gus->t2, gus->t2l, gus->tctrl); 24.819 + if (gus->t2on) 24.820 + { 24.821 + gus->t2++; 24.822 + if (gus->t2 > 0xFF) 24.823 + { 24.824 +// gus->t2on=0; 24.825 + gus->t2=gus->t2l; 24.826 + gus->ad_status |= 0x20; 24.827 + if (gus->tctrl&8) 24.828 + { 24.829 + if (gus->irq != -1) 24.830 + picint(1 << gus->irq); 24.831 + gus->ad_status |= 0x02; 24.832 + gus->irqstatus |= 0x08; 24.833 +// pclog("GUS T2 IRQ!\n"); 24.834 + } 24.835 + } 24.836 + } 24.837 + if (gus->irqnext) 24.838 + { 24.839 +// pclog("Take IRQ\n"); 24.840 + gus->irqnext=0; 24.841 + gus->irqstatus|=0x80; 24.842 + if (gus->irq != -1) 24.843 + picint(1 << gus->irq); 24.844 + } 24.845 +} 24.846 + 24.847 +void gus_poll_wave(void *p) 24.848 +{ 24.849 + gus_t *gus = (gus_t *)p; 24.850 + uint32_t addr; 24.851 + int d; 24.852 + int16_t v; 24.853 + int32_t vl; 24.854 + int update_irqs = 0; 24.855 + 24.856 + gus->samp_timer += gus->samp_latch; 24.857 + 24.858 + gus->out_l = gus->out_r = 0; 24.859 + 24.860 + if ((gus->reset & 3) != 3) 24.861 + return; 24.862 +//pclog("gus_poll_wave\n"); 24.863 + for (d=0;d<32;d++) 24.864 + { 24.865 + if (!(gus->ctrl[d] & 3)) 24.866 + { 24.867 + if (gus->ctrl[d] & 4) 24.868 + { 24.869 + addr = gus->cur[d] >> 9; 24.870 + addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE); 24.871 + if (!(gus->freq[d] >> 10)) /*Interpolate*/ 24.872 + { 24.873 + vl = (int16_t)(int8_t)((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (gus->cur[d] & 511)); 24.874 + vl += (int16_t)(int8_t)((gus->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (gus->cur[d] & 511); 24.875 + v = vl >> 9; 24.876 + } 24.877 + else 24.878 + v = (int16_t)(int8_t)((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80); 24.879 + } 24.880 + else 24.881 + { 24.882 + if (!(gus->freq[d] >> 10)) /*Interpolate*/ 24.883 + { 24.884 + vl = ((int8_t)((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (gus->cur[d] & 511)); 24.885 + vl += ((int8_t)((gus->ram[((gus->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (gus->cur[d] & 511); 24.886 + v = vl >> 9; 24.887 + } 24.888 + else 24.889 + v = (int16_t)(int8_t)((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80); 24.890 + } 24.891 + 24.892 +// pclog("Voice %i : %04X %05X %04X ", d, v, gus->cur[d] >> 9, gus->rcur[d] >> 10); 24.893 + if ((gus->rcur[d] >> 14) > 4095) v = (int16_t)(float)(v) * 24.0 * vol16bit[4095]; 24.894 + else v = (int16_t)(float)(v) * 24.0 * vol16bit[(gus->rcur[d]>>10) & 4095]; 24.895 +// pclog("%f %04X\n", vol16bit[(gus->rcur[d]>>10) & 4095], v); 24.896 + 24.897 + gus->out_l += v; 24.898 + gus->out_r += v; 24.899 + 24.900 + if (gus->ctrl[d]&0x40) 24.901 + { 24.902 + gus->cur[d] -= (gus->freq[d] >> 1); 24.903 + if (gus->cur[d] <= gus->start[d]) 24.904 + { 24.905 + int diff = gus->start[d] - gus->cur[d]; 24.906 + if (!(gus->rctrl[d]&4)) 24.907 + { 24.908 + if (!(gus->ctrl[d]&8)) 24.909 + { 24.910 + gus->ctrl[d] |= 1; 24.911 + gus->cur[d] = (gus->ctrl[d] & 0x40) ? gus->end[d] : gus->start[d]; 24.912 + } 24.913 + else 24.914 + { 24.915 + if (gus->ctrl[d]&0x10) gus->ctrl[d]^=0x40; 24.916 + gus->cur[d] = (gus->ctrl[d] & 0x40) ? (gus->end[d] - diff) : (gus->start[d] + diff); 24.917 + } 24.918 + } 24.919 + if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d]) 24.920 + { 24.921 + gus->waveirqs[d] = 1; 24.922 + update_irqs = 1; 24.923 +// pclog("Causing wave IRQ %02X %i\n", gus->ctrl[d], d); 24.924 + } 24.925 + } 24.926 + } 24.927 + else 24.928 + { 24.929 + gus->cur[d] += (gus->freq[d] >> 1); 24.930 + 24.931 + if (gus->cur[d] >= gus->end[d]) 24.932 + { 24.933 + int diff = gus->cur[d] - gus->end[d]; 24.934 + if (!(gus->rctrl[d]&4)) 24.935 + { 24.936 + if (!(gus->ctrl[d]&8)) 24.937 + { 24.938 + gus->ctrl[d] |= 1; 24.939 + gus->cur[d] = (gus->ctrl[d] & 0x40) ? gus->end[d] : gus->start[d]; 24.940 + } 24.941 + else 24.942 + { 24.943 + if (gus->ctrl[d]&0x10) gus->ctrl[d]^=0x40; 24.944 + gus->cur[d] = (gus->ctrl[d] & 0x40) ? (gus->end[d] - diff) : (gus->start[d] + diff); 24.945 + } 24.946 + } 24.947 + if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d]) 24.948 + { 24.949 + gus->waveirqs[d] = 1; 24.950 + update_irqs = 1; 24.951 +// pclog("Causing wave IRQ %02X %i\n", gus->ctrl[d], d); 24.952 + } 24.953 + } 24.954 + } 24.955 + } 24.956 + if (!(gus->rctrl[d] & 3)) 24.957 + { 24.958 + if (gus->rctrl[d] & 0x40) 24.959 + { 24.960 + gus->rcur[d] -= gus->rfreq[d]; 24.961 + if (gus->rcur[d] <= gus->rstart[d]) 24.962 + { 24.963 + int diff = gus->rstart[d] - gus->rcur[d]; 24.964 + if (!(gus->rctrl[d] & 8)) 24.965 + { 24.966 + gus->rctrl[d] |= 1; 24.967 + gus->rcur[d] = (gus->rctrl[d] & 0x40) ? gus->rstart[d] : gus->rend[d]; 24.968 + } 24.969 + else 24.970 + { 24.971 + if (gus->rctrl[d] & 0x10) gus->rctrl[d] ^= 0x40; 24.972 + gus->rcur[d] = (gus->rctrl[d] & 0x40) ? (gus->rend[d] - diff) : (gus->rstart[d] + diff); 24.973 + } 24.974 + 24.975 + if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d]) 24.976 + { 24.977 + gus->rampirqs[d] = 1; 24.978 + update_irqs = 1; 24.979 +// pclog("Causing ramp IRQ %02X %i\n",gus->rctrl[d], d); 24.980 + } 24.981 + } 24.982 + } 24.983 + else 24.984 + { 24.985 + gus->rcur[d] += gus->rfreq[d]; 24.986 +// if (d == 1) printf("RCUR+ %i %08X %08X %08X %08X\n",d,gus->rfreq[d],gus->rcur[d],gus->rstart[d],gus->rend[d]); 24.987 + if (gus->rcur[d] >= gus->rend[d]) 24.988 + { 24.989 + int diff = gus->rcur[d] - gus->rend[d]; 24.990 + if (!(gus->rctrl[d] & 8)) 24.991 + { 24.992 + gus->rctrl[d] |= 1; 24.993 + gus->rcur[d] = (gus->rctrl[d] & 0x40) ? gus->rstart[d] : gus->rend[d]; 24.994 + } 24.995 + else 24.996 + { 24.997 + if (gus->rctrl[d] & 0x10) gus->rctrl[d] ^= 0x40; 24.998 + gus->rcur[d] = (gus->rctrl[d] & 0x40) ? (gus->rend[d] - diff) : (gus->rstart[d] + diff); 24.999 + } 24.1000 + 24.1001 + if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d]) 24.1002 + { 24.1003 + gus->rampirqs[d] = 1; 24.1004 + update_irqs = 1; 24.1005 +// pclog("Causing ramp IRQ %02X %i\n",gus->rctrl[d], d); 24.1006 + } 24.1007 + } 24.1008 + } 24.1009 + } 24.1010 + } 24.1011 + 24.1012 + if (update_irqs) 24.1013 + pollgusirqs(gus); 24.1014 +} 24.1015 + 24.1016 +void gus_poll(void *p) 24.1017 +{ 24.1018 + gus_t *gus = (gus_t *)p; 24.1019 + 24.1020 + if (gus->pos >= SOUNDBUFLEN) 24.1021 + return; 24.1022 + 24.1023 + //pclog("gus_poll\n"); 24.1024 + gus->buffer[0][gus->pos] = gus->out_l; 24.1025 + gus->buffer[1][gus->pos] = gus->out_r; 24.1026 + 24.1027 + gus->pos++; 24.1028 +} 24.1029 + 24.1030 +static void gus_get_buffer(int16_t *buffer, int len, void *p) 24.1031 +{ 24.1032 + gus_t *gus = (gus_t *)p; 24.1033 + int c; 24.1034 + 24.1035 + for (c = 0; c < len * 2; c++) 24.1036 + { 24.1037 + buffer[c] += gus->buffer[c & 1][c >> 1]; 24.1038 + } 24.1039 + 24.1040 + gus->pos = 0; 24.1041 +} 24.1042 + 24.1043 + 24.1044 +void *gus_init() 24.1045 +{ 24.1046 + int c; 24.1047 + double out = 1.0; 24.1048 + gus_t *gus = malloc(sizeof(gus_t)); 24.1049 + memset(gus, 0, sizeof(gus_t)); 24.1050 + 24.1051 + gus->ram = malloc(1 << 20); 24.1052 + memset(gus->ram, 0, 1 << 20); 24.1053 + 24.1054 + pclog("gus_init\n"); 24.1055 + 24.1056 + for (c=0;c<32;c++) 24.1057 + { 24.1058 + gus->ctrl[c]=1; 24.1059 + gus->rctrl[c]=1; 24.1060 + gus->rfreq[c]=63*512; 24.1061 + } 24.1062 + 24.1063 + for (c=4095;c>=0;c--) { 24.1064 + vol16bit[c]=out;//(float)c/4095.0;//out; 24.1065 + out/=1.002709201; /* 0.0235 dB Steps */ 24.1066 + } 24.1067 + 24.1068 + printf("Top volume %f %f %f %f\n",vol16bit[4095],vol16bit[3800],vol16bit[3000],vol16bit[2048]); 24.1069 + gus->voices=14; 24.1070 + 24.1071 + gus->samp_timer = gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); 24.1072 + 24.1073 + io_sethandler(0x0240, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); 24.1074 + io_sethandler(0x0340, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); 24.1075 + io_sethandler(0x0746, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus); 24.1076 + io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus); 24.1077 + timer_add(gus_poll_wave, &gus->samp_timer, TIMER_ALWAYS_ENABLED, gus); 24.1078 + timer_add(gus_poll_timer_1, &gus->timer_1, TIMER_ALWAYS_ENABLED, gus); 24.1079 + timer_add(gus_poll_timer_2, &gus->timer_2, TIMER_ALWAYS_ENABLED, gus); 24.1080 + 24.1081 + sound_add_handler(gus_poll, gus_get_buffer, gus); 24.1082 + 24.1083 + return gus; 24.1084 +} 24.1085 + 24.1086 +void gus_close(void *p) 24.1087 +{ 24.1088 + gus_t *gus = (gus_t *)p; 24.1089 + 24.1090 + free(gus->ram); 24.1091 + free(gus); 24.1092 +} 24.1093 + 24.1094 +void gus_speed_changed(void *p) 24.1095 +{ 24.1096 + gus_t *gus = (gus_t *)p; 24.1097 + 24.1098 + if (gus->voices < 14) 24.1099 + gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); 24.1100 + else 24.1101 + gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); 24.1102 +} 24.1103 + 24.1104 +device_t gus_device = 24.1105 +{ 24.1106 + "Gravis UltraSound", 24.1107 + gus_init, 24.1108 + gus_close, 24.1109 + gus_speed_changed 24.1110 +};
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/src/sound_gus.h Mon May 27 19:56:33 2013 +0100 25.3 @@ -0,0 +1,1 @@ 25.4 +extern device_t gus_device;
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/src/sound_opl.c Mon May 27 19:56:33 2013 +0100 26.3 @@ -0,0 +1,195 @@ 26.4 +#include <stdint.h> 26.5 +#include <stdlib.h> 26.6 +#include "ibm.h" 26.7 +#include "io.h" 26.8 +#include "sound_opl.h" 26.9 + 26.10 +/*Interfaces between PCem and the actual OPL emulator*/ 26.11 + 26.12 + 26.13 +uint8_t opl2_read(uint16_t a, void *priv) 26.14 +{ 26.15 + opl_t *opl = (opl_t *)priv; 26.16 + 26.17 + cycles -= (int)(isa_timing * 8); 26.18 + return ym3812_read(opl->YM3812[0], a); 26.19 +} 26.20 +void opl2_write(uint16_t a, uint8_t v, void *priv) 26.21 +{ 26.22 + opl_t *opl = (opl_t *)priv; 26.23 + 26.24 + ym3812_write(opl->YM3812[0],a,v); 26.25 + ym3812_write(opl->YM3812[1],a,v); 26.26 +} 26.27 + 26.28 +uint8_t opl2_l_read(uint16_t a, void *priv) 26.29 +{ 26.30 + opl_t *opl = (opl_t *)priv; 26.31 + 26.32 + cycles -= (int)(isa_timing * 8); 26.33 + return ym3812_read(opl->YM3812[0], a); 26.34 +} 26.35 +void opl2_l_write(uint16_t a, uint8_t v, void *priv) 26.36 +{ 26.37 + opl_t *opl = (opl_t *)priv; 26.38 + 26.39 + ym3812_write(opl->YM3812[0],a,v); 26.40 +} 26.41 + 26.42 +uint8_t opl2_r_read(uint16_t a, void *priv) 26.43 +{ 26.44 + opl_t *opl = (opl_t *)priv; 26.45 + 26.46 + cycles -= (int)(isa_timing * 8); 26.47 + return ym3812_read(opl->YM3812[1], a); 26.48 +} 26.49 +void opl2_r_write(uint16_t a, uint8_t v, void *priv) 26.50 +{ 26.51 + opl_t *opl = (opl_t *)priv; 26.52 + 26.53 + ym3812_write(opl->YM3812[1],a,v); 26.54 +} 26.55 + 26.56 +uint8_t opl3_read(uint16_t a, void *priv) 26.57 +{ 26.58 + opl_t *opl = (opl_t *)priv; 26.59 + 26.60 + cycles -= (int)(isa_timing * 8); 26.61 + return ymf262_read(opl->YMF262, a); 26.62 +} 26.63 +void opl3_write(uint16_t a, uint8_t v, void *priv) 26.64 +{ 26.65 + opl_t *opl = (opl_t *)priv; 26.66 + 26.67 + ymf262_write(opl->YMF262, a, v); 26.68 +} 26.69 + 26.70 + 26.71 +void opl2_poll(opl_t *opl, int16_t *bufl, int16_t *bufr) 26.72 +{ 26.73 + ym3812_update_one(opl->YM3812[0], bufl, 1); 26.74 + ym3812_update_one(opl->YM3812[1], bufr, 1); 26.75 + 26.76 + opl->filtbuf[0] = *bufl = ((*bufl) / 4) + ((opl->filtbuf[0] * 11) / 16); 26.77 + opl->filtbuf[1] = *bufr = ((*bufr) / 4) + ((opl->filtbuf[1] * 11) / 16); 26.78 + 26.79 + if (opl->timers_enable[0][0]) 26.80 + { 26.81 + opl->timers[0][0]--; 26.82 + if (opl->timers[0][0] < 0) ym3812_timer_over(opl->YM3812[0], 0); 26.83 + } 26.84 + if (opl->timers_enable[0][1]) 26.85 + { 26.86 + opl->timers[0][1]--; 26.87 + if (opl->timers[0][1] < 0) ym3812_timer_over(opl->YM3812[0], 1); 26.88 + } 26.89 + if (opl->timers_enable[1][0]) 26.90 + { 26.91 + opl->timers[1][0]--; 26.92 + if (opl->timers[1][0] < 0) ym3812_timer_over(opl->YM3812[1], 0); 26.93 + } 26.94 + if (opl->timers_enable[1][1]) 26.95 + { 26.96 + opl->timers[1][1]--; 26.97 + if (opl->timers[1][1] < 0) ym3812_timer_over(opl->YM3812[1], 1); 26.98 + } 26.99 +} 26.100 + 26.101 +void opl3_poll(opl_t *opl, int16_t *bufl, int16_t *bufr) 26.102 +{ 26.103 + ymf262_update_one(opl->YMF262, opl->bufs, 1); 26.104 + 26.105 + opl->filtbuf[0] = *bufl = ((opl->bufs[0][0]) / 4) + ((opl->filtbuf[0] * 11) / 16); 26.106 + opl->filtbuf[1] = *bufr = ((opl->bufs[1][0]) / 4) + ((opl->filtbuf[1] * 11) / 16); 26.107 + 26.108 + if (opl->timers_enable[0][0]) 26.109 + { 26.110 + opl->timers[0][0]--; 26.111 + if (opl->timers[0][0] < 0) 26.112 + { 26.113 + opl->timers_enable[0][0] = 0; 26.114 + ymf262_timer_over(opl->YMF262, 0); 26.115 + } 26.116 + } 26.117 + if (opl->timers_enable[0][1]) 26.118 + { 26.119 + opl->timers[0][1]--; 26.120 + if (opl->timers[0][1] < 0) 26.121 + { 26.122 + opl->timers_enable[0][1] = 0; 26.123 + ymf262_timer_over(opl->YMF262, 1); 26.124 + } 26.125 + } 26.126 +} 26.127 + 26.128 +void ym3812_timer_set_0(void *param, int timer, attotime period) 26.129 +{ 26.130 + opl_t *opl = (opl_t *)param; 26.131 + 26.132 + opl->timers[0][timer] = period / 20833; 26.133 + if (!opl->timers[0][timer]) opl->timers[0][timer] = 1; 26.134 + opl->timers_enable[0][timer] = period ? 1 : 0; 26.135 +} 26.136 +void ym3812_timer_set_1(void *param, int timer, attotime period) 26.137 +{ 26.138 + opl_t *opl = (opl_t *)param; 26.139 + 26.140 + opl->timers[1][timer] = period / 20833; 26.141 + if (!opl->timers[1][timer]) opl->timers[1][timer] = 1; 26.142 + opl->timers_enable[1][timer] = period ? 1 : 0; 26.143 +} 26.144 + 26.145 +void ymf262_timer_set(void *param, int timer, attotime period) 26.146 +{ 26.147 + opl_t *opl = (opl_t *)param; 26.148 + 26.149 + opl->timers[0][timer] = period / 20833; 26.150 + if (!opl->timers[0][timer]) opl->timers[0][timer] = 1; 26.151 + opl->timers_enable[0][timer] = period ? 1 : 0; 26.152 +} 26.153 + 26.154 +void opl2_init(opl_t *opl) 26.155 +{ 26.156 + opl->bufs[0] = (int16_t *)malloc(4); 26.157 + opl->bufs[1] = (int16_t *)malloc(4); 26.158 + opl->bufs[2] = (int16_t *)malloc(4); 26.159 + opl->bufs[3] = (int16_t *)malloc(4); 26.160 + 26.161 + opl->YM3812[0] = ym3812_init(NULL, 3579545, 48000); 26.162 + ym3812_reset_chip(opl->YM3812[0]); 26.163 + ym3812_set_timer_handler(opl->YM3812[0], ym3812_timer_set_0, opl); 26.164 + 26.165 + opl->YM3812[1] = ym3812_init(NULL, 3579545, 48000); 26.166 + ym3812_reset_chip(opl->YM3812[1]); 26.167 + ym3812_set_timer_handler(opl->YM3812[1], ym3812_timer_set_1, opl); 26.168 +} 26.169 + 26.170 +void opl3_init(opl_t *opl) 26.171 +{ 26.172 + opl->bufs[0] = (int16_t *)malloc(4); 26.173 + opl->bufs[1] = (int16_t *)malloc(4); 26.174 + opl->bufs[2] = (int16_t *)malloc(4); 26.175 + opl->bufs[3] = (int16_t *)malloc(4); 26.176 + 26.177 + opl->YMF262 = ymf262_init(NULL, 3579545 * 4, 48000); 26.178 + ymf262_reset_chip(opl->YMF262); 26.179 + ymf262_set_timer_handler(opl->YMF262, ymf262_timer_set, opl); 26.180 +} 26.181 + 26.182 +void opl2_close(opl_t *opl) 26.183 +{ 26.184 + free(opl->bufs[0]); 26.185 + free(opl->bufs[1]); 26.186 + 26.187 + ym3812_shutdown(opl->YM3812[0]); 26.188 + ym3812_shutdown(opl->YM3812[1]); 26.189 +} 26.190 + 26.191 +void opl3_close(opl_t *opl) 26.192 +{ 26.193 + free(opl->bufs[0]); 26.194 + free(opl->bufs[1]); 26.195 + 26.196 + ym3812_shutdown(opl->YM3812[0]); 26.197 + ymf262_shutdown(opl->YMF262); 26.198 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/src/sound_opl.h Mon May 27 19:56:33 2013 +0100 27.3 @@ -0,0 +1,35 @@ 27.4 +#include "mame/fmopl.h" 27.5 +#include "mame/ymf262.h" 27.6 + 27.7 +typedef struct opl_t 27.8 +{ 27.9 + void *YM3812[2]; 27.10 + void *YMF262; 27.11 + 27.12 + int timers[2][2]; 27.13 + int timers_enable[2][2]; 27.14 + 27.15 + int16_t *bufs[4]; 27.16 + int16_t filtbuf[2]; 27.17 +} opl_t; 27.18 + 27.19 +uint8_t opl_read(uint16_t a, void *priv); 27.20 +void opl_write(uint16_t a, uint8_t v, void *priv); 27.21 + 27.22 +uint8_t opl2_read(uint16_t a, void *priv); 27.23 +void opl2_write(uint16_t a, uint8_t v, void *priv); 27.24 +uint8_t opl2_l_read(uint16_t a, void *priv); 27.25 +void opl2_l_write(uint16_t a, uint8_t v, void *priv); 27.26 +uint8_t opl2_r_read(uint16_t a, void *priv); 27.27 +void opl2_r_write(uint16_t a, uint8_t v, void *priv); 27.28 +uint8_t opl3_read(uint16_t a, void *priv); 27.29 +void opl3_write(uint16_t a, uint8_t v, void *priv); 27.30 + 27.31 +void opl2_poll(opl_t *opl, int16_t *bufl, int16_t *bufr); 27.32 +void opl3_poll(opl_t *opl, int16_t *bufl, int16_t *bufr); 27.33 + 27.34 +void opl2_init(opl_t *opl); 27.35 +void opl3_init(opl_t *opl); 27.36 + 27.37 +void opl2_close(opl_t *opl); 27.38 +void opl3_close(opl_t *opl);
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/src/sound_pas16.c Mon May 27 19:56:33 2013 +0100 28.3 @@ -0,0 +1,753 @@ 28.4 +#include <stdlib.h> 28.5 +#include "ibm.h" 28.6 + 28.7 +#include "device.h" 28.8 +#include "dma.h" 28.9 +#include "filters.h" 28.10 +#include "io.h" 28.11 +#include "pic.h" 28.12 +#include "pit.h" 28.13 +#include "sound_opl.h" 28.14 +#include "sound_pas16.h" 28.15 +#include "sound_sb_dsp.h" 28.16 +#include "timer.h" 28.17 + 28.18 +/* Original PAS uses 28.19 + 2 x OPL2 28.20 + PIT - sample rate/count 28.21 + LMC835N/LMC1982 - mixer 28.22 + YM3802 - MIDI Control System 28.23 + 28.24 + 28.25 + 9A01 - IO base 28.26 + base >> 2 28.27 + 28.28 + All below + IO base 28.29 + 28.30 + B89 - interrupt status / clear 28.31 + bit 2 - sample rate 28.32 + bit 3 - PCM 28.33 + bit 4 - MIDI 28.34 + 28.35 + B88 - Audio mixer control register 28.36 + 28.37 + B8A - Audio filter control 28.38 + bit 5 - mute? 28.39 + 28.40 + B8B - interrupt mask / board ID 28.41 + bits 5-7 - board ID (read only on PAS16) 28.42 + 28.43 + F88 - PCM data (low) 28.44 + 28.45 + F89 - PCM data (high) 28.46 + 28.47 + F8A - PCM control? 28.48 + bit 4 - input/output select (1 = output) 28.49 + bit 5 - mono/stereo select 28.50 + bit 6 - PCM enable 28.51 + 28.52 + 1388-138b - PIT clocked at 1193180 Hz 28.53 + 1388 - sample rate 28.54 + 1389 - sample count 28.55 + 28.56 + 178b - 28.57 + 2789 - board revision 28.58 + 28.59 + 8389 - 28.60 + bit 2 - 8/16 bit 28.61 + 28.62 + BF88 - wait states 28.63 + 28.64 + EF8B - 28.65 + bit 3 - 16 bits okay ? 28.66 + 28.67 + F388 - 28.68 + bit 6 - joystick enable 28.69 + 28.70 + F389 - 28.71 + bits 0-2 - DMA 28.72 + 28.73 + F38A - 28.74 + bits 0-3 - IRQ 28.75 + 28.76 + F788 - 28.77 + bit 1 - SB emulation 28.78 + bit 0 - MPU401 emulation 28.79 + 28.80 + F789 - SB base addr 28.81 + bits 0-3 - addr bits 4-7 28.82 + 28.83 + FB8A - SB IRQ/DMA 28.84 + bits 3-5 - IRQ 28.85 + bits 6-7 - DMA 28.86 + 28.87 + FF88 - board model 28.88 + 3 = PAS16 28.89 +*/ 28.90 + 28.91 +static uint8_t pas16_pit_in(uint16_t port, void *priv); 28.92 +static void pas16_pit_out(uint16_t port, uint8_t val, void *priv); 28.93 +//static void pas16_update_irqs(); 28.94 + 28.95 +typedef struct pas16_t 28.96 +{ 28.97 + uint16_t base; 28.98 + 28.99 + int irq, dma; 28.100 + 28.101 + uint8_t audiofilt; 28.102 + 28.103 + uint8_t audio_mixer; 28.104 + 28.105 + uint8_t compat, compat_base; 28.106 + 28.107 + uint8_t enhancedscsi; 28.108 + 28.109 + uint8_t io_conf_1, io_conf_2, io_conf_3, io_conf_4; 28.110 + 28.111 + uint8_t irq_stat, irq_ena; 28.112 + 28.113 + uint8_t pcm_ctrl; 28.114 + uint16_t pcm_dat; 28.115 + 28.116 + uint16_t pcm_dat_l, pcm_dat_r; 28.117 + 28.118 + uint8_t sb_irqdma; 28.119 + 28.120 + int stereo_lr; 28.121 + 28.122 + uint8_t sys_conf_1, sys_conf_2, sys_conf_3, sys_conf_4; 28.123 + 28.124 + struct 28.125 + { 28.126 + uint32_t l[3]; 28.127 + int c[3]; 28.128 + uint8_t m[3]; 28.129 + uint8_t ctrl, ctrls[2]; 28.130 + int wp, rm[3], wm[3]; 28.131 + uint16_t rl[3]; 28.132 + int thit[3]; 28.133 + int delay[3]; 28.134 + int rereadlatch[3]; 28.135 + int enable[3]; 28.136 + } pit; 28.137 + 28.138 + opl_t opl; 28.139 + sb_dsp_t dsp; 28.140 + 28.141 + int16_t opl_buffer[SOUNDBUFLEN * 2]; 28.142 + int16_t pcm_buffer[2][SOUNDBUFLEN]; 28.143 + int16_t dsp_buffer[SOUNDBUFLEN * 2]; 28.144 + 28.145 + int pos; 28.146 +} pas16_t; 28.147 + 28.148 +static int pas16_dmas[8] = {4, 1, 2, 3, 0, 5, 6, 7}; 28.149 +static int pas16_irqs[16] = {0, 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, 15, 0, 0, 0, 0}; 28.150 +static int pas16_sb_irqs[8] = {0, 2, 3, 5, 7, 10, 11, 12}; 28.151 +static int pas16_sb_dmas[8] = {0, 1, 2, 3}; 28.152 + 28.153 +enum 28.154 +{ 28.155 + PAS16_INT_SAMP = 0x04, 28.156 + PAS16_INT_PCM = 0x08, 28.157 +}; 28.158 + 28.159 +enum 28.160 +{ 28.161 + PAS16_PCM_MONO = 0x20, 28.162 + PAS16_PCM_ENA = 0x40 28.163 +}; 28.164 + 28.165 +enum 28.166 +{ 28.167 + PAS16_SC2_16BIT = 0x04, 28.168 + PAS16_SC2_MSBINV = 0x10 28.169 +}; 28.170 + 28.171 +enum 28.172 +{ 28.173 + PAS16_FILT_MUTE = 0x20 28.174 +}; 28.175 + 28.176 +static uint8_t pas16_in(uint16_t port, void *p) 28.177 +{ 28.178 + pas16_t *pas16 = (pas16_t *)p; 28.179 + uint8_t temp; 28.180 +/* if (CS == 0xCA53 && pc == 0x3AFC) 28.181 + fatal("here");*/ 28.182 + switch ((port - pas16->base) + 0x388) 28.183 + { 28.184 + case 0x388: case 0x389: case 0x38a: case 0x38b: 28.185 + temp = opl3_read((port - pas16->base) + 0x388, &pas16->opl); 28.186 + break; 28.187 + 28.188 + case 0xb88: 28.189 + temp = pas16->audio_mixer; 28.190 + break; 28.191 + 28.192 + case 0xb89: 28.193 + temp = pas16->irq_stat; 28.194 + break; 28.195 + 28.196 + case 0xb8a: 28.197 + temp = pas16->audiofilt; 28.198 + break; 28.199 + 28.200 + case 0xb8b: 28.201 + temp = (pas16->irq_ena & ~0xe0) | 0x20; 28.202 + break; 28.203 + 28.204 + case 0xf8a: 28.205 + temp = pas16->pcm_ctrl; 28.206 + break; 28.207 + 28.208 + case 0x1388: case 0x1389: case 0x138a: case 0x138b: 28.209 + temp = pas16_pit_in(port, pas16); 28.210 + break; 28.211 + 28.212 + case 0x2789: /*Board revision*/ 28.213 + temp = 0; 28.214 + break; 28.215 + 28.216 + case 0x7f89: 28.217 + temp = pas16->enhancedscsi & ~1; 28.218 + break; 28.219 + 28.220 + case 0x8388: 28.221 + temp = pas16->sys_conf_1; 28.222 + break; 28.223 + case 0x8389: 28.224 + temp = pas16->sys_conf_2; 28.225 + break; 28.226 + case 0x838b: 28.227 + temp = pas16->sys_conf_3; 28.228 + break; 28.229 + case 0x838c: 28.230 + temp = pas16->sys_conf_4; 28.231 + break; 28.232 + 28.233 + case 0xef8b: 28.234 + temp = 0x0c; 28.235 + break; 28.236 + 28.237 + case 0xf388: 28.238 + temp = pas16->io_conf_1; 28.239 + break; 28.240 + case 0xf389: 28.241 + temp = pas16->io_conf_2; 28.242 + break; 28.243 + case 0xf38b: 28.244 + temp = pas16->io_conf_3; 28.245 + break; 28.246 + case 0xf38c: 28.247 + temp = pas16->io_conf_4; 28.248 + break; 28.249 + 28.250 + case 0xf788: 28.251 + temp = pas16->compat; 28.252 + break; 28.253 + case 0xf789: 28.254 + temp = pas16->compat_base; 28.255 + break; 28.256 + 28.257 + case 0xfb8a: 28.258 + temp = pas16->sb_irqdma; 28.259 + break; 28.260 + 28.261 + case 0xff88: /*Board model*/ 28.262 + temp = 4; /*PAS16*/ 28.263 + break; 28.264 + case 0xff8b: /*Master mode read*/ 28.265 + temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ 28.266 + break; 28.267 + } 28.268 +/* if (port != 0x388 && port != 0x389 && port != 0xb8b) */pclog("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS,pc); 28.269 +/* if (CS == 0x1FF4 && pc == 0x0585) 28.270 + { 28.271 + if (output) 28.272 + fatal("here"); 28.273 + output = 3; 28.274 + }*/ 28.275 + return temp; 28.276 +} 28.277 + 28.278 +static void pas16_out(uint16_t port, uint8_t val, void *p) 28.279 +{ 28.280 + pas16_t *pas16 = (pas16_t *)p; 28.281 +/* if (port != 0x388 && port != 0x389) */pclog("pas16_out : port %04X val %02X %04X:%04X\n", port, val, CS,pc); 28.282 +/* if (CS == 0x369 && pc == 0x2AC5) 28.283 + fatal("here\n");*/ 28.284 + switch ((port - pas16->base) + 0x388) 28.285 + { 28.286 + case 0x388: case 0x389: case 0x38a: case 0x38b: 28.287 + opl3_write((port - pas16->base) + 0x388, val, &pas16->opl); 28.288 + break; 28.289 + 28.290 + case 0xb88: 28.291 + pas16->audio_mixer = val; 28.292 + break; 28.293 + 28.294 + case 0xb89: 28.295 + pas16->irq_stat &= ~val; 28.296 +// pas16_update_irqs(); 28.297 + break; 28.298 + 28.299 + case 0xb8a: 28.300 + pas16->audiofilt = val; 28.301 + break; 28.302 + 28.303 + case 0xb8b: 28.304 + pas16->irq_ena = val; 28.305 +// pas16_update_irqs(); 28.306 + break; 28.307 + 28.308 + case 0xf88: 28.309 + pas16->pcm_dat = (pas16->pcm_dat & 0xff00) | val; 28.310 + break; 28.311 + case 0xf89: 28.312 + pas16->pcm_dat = (pas16->pcm_dat & 0x00ff) | (val << 8); 28.313 + break; 28.314 + case 0xf8a: 28.315 + if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) /*Guess*/ 28.316 + pas16->stereo_lr = 0; 28.317 + pas16->pcm_ctrl = val; 28.318 + break; 28.319 + 28.320 + case 0x1388: case 0x1389: case 0x138a: case 0x138b: 28.321 + pas16_pit_out(port, val, pas16); 28.322 + break; 28.323 + 28.324 + case 0x7f89: 28.325 + pas16->enhancedscsi = val; 28.326 + break; 28.327 + 28.328 + case 0x8388: 28.329 + pas16->sys_conf_1 = val; 28.330 + break; 28.331 + case 0x8389: 28.332 + pas16->sys_conf_2 = val; 28.333 + break; 28.334 + case 0x838a: 28.335 + pas16->sys_conf_3 = val; 28.336 + break; 28.337 + case 0x838b: 28.338 + pas16->sys_conf_4 = val; 28.339 + break; 28.340 + 28.341 + case 0xf388: 28.342 + pas16->io_conf_1 = val; 28.343 + break; 28.344 + case 0xf389: 28.345 + pas16->io_conf_2 = val; 28.346 + pas16->dma = pas16_dmas[val & 0x7]; 28.347 + pclog("pas16_out : set PAS DMA %i\n", pas16->dma); 28.348 + break; 28.349 + case 0xf38a: 28.350 + pas16->io_conf_3 = val; 28.351 + pas16->irq = pas16_irqs[val & 0xf]; 28.352 + pclog("pas16_out : set PAS IRQ %i\n", pas16->irq); 28.353 + break; 28.354 + case 0xf38b: 28.355 + pas16->io_conf_4 = val; 28.356 + break; 28.357 + 28.358 + case 0xf788: 28.359 + pas16->compat = val; 28.360 + if (pas16->compat & 0x02) 28.361 + sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); 28.362 + else 28.363 + sb_dsp_setaddr(&pas16->dsp, 0); 28.364 + break; 28.365 + case 0xf789: 28.366 + pas16->compat_base = val; 28.367 + if (pas16->compat & 0x02) 28.368 + sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200); 28.369 + break; 28.370 + 28.371 + case 0xfb8a: 28.372 + pas16->sb_irqdma = val; 28.373 + sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]); 28.374 + sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]); 28.375 + pclog("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); 28.376 + break; 28.377 + 28.378 + default: 28.379 + pclog("pas16_out : unknown %04X\n", port); 28.380 + } 28.381 + if (pc == 0x80048CF3) 28.382 + { 28.383 + if (output) 28.384 + fatal("here\n"); 28.385 + output = 3; 28.386 + } 28.387 +/* if (CS == 0x1FF4 && pc == 0x0431) 28.388 + output = 3;*/ 28.389 +} 28.390 + 28.391 +static void pas16_pit_out(uint16_t port, uint8_t val, void *p) 28.392 +{ 28.393 + pas16_t *pas16 = (pas16_t *)p; 28.394 + int t; 28.395 + switch (port & 3) 28.396 + { 28.397 + case 3: /*CTRL*/ 28.398 + if ((val & 0xC0) == 0xC0) 28.399 + { 28.400 + if (!(val & 0x20)) 28.401 + { 28.402 + if (val & 2) pas16->pit.rl[0] = pas16->pit.c[0] / (PITCONST * (1 << TIMER_SHIFT)); 28.403 + if (val & 4) pas16->pit.rl[1] = pas16->pit.c[1]; 28.404 + if (val & 8) pas16->pit.rl[2] = pas16->pit.c[2]; 28.405 + } 28.406 + return; 28.407 + } 28.408 + t = val >> 6; 28.409 + pas16->pit.ctrls[t] = pas16->pit.ctrl = val; 28.410 + if (t == 3) 28.411 + { 28.412 + printf("Bad PIT reg select\n"); 28.413 + return; 28.414 + } 28.415 + if (!(pas16->pit.ctrl & 0x30)) 28.416 + { 28.417 + pas16->pit.rl[t] = pas16->pit.c[t]; 28.418 + if (!t) 28.419 + pas16->pit.rl[t] /= (PITCONST * (1 << TIMER_SHIFT)); 28.420 + if (pas16->pit.c[t] < 0) 28.421 + pas16->pit.rl[t] = 0; 28.422 + pas16->pit.ctrl |= 0x30; 28.423 + pas16->pit.rereadlatch[t] = 0; 28.424 + pas16->pit.rm[t] = 3; 28.425 + } 28.426 + else 28.427 + { 28.428 + pas16->pit.rm[t] = pas16->pit.wm[t] = (pas16->pit.ctrl >> 4) & 3; 28.429 + pas16->pit.m[t] = (val >> 1) & 7; 28.430 + if (pas16->pit.m[t] > 5) 28.431 + pas16->pit.m[t] &= 3; 28.432 + if (!pas16->pit.rm[t]) 28.433 + { 28.434 + pas16->pit.rm[t] = 3; 28.435 + pas16->pit.rl[t] = pit.c[t]; 28.436 + if (!t) 28.437 + pas16->pit.rl[t] /= (PITCONST * (1 << TIMER_SHIFT)); 28.438 + } 28.439 + pas16->pit.rereadlatch[t] = 1; 28.440 + } 28.441 + pas16->pit.wp = 0; 28.442 + pas16->pit.thit[t] = 0; 28.443 + break; 28.444 + case 0: case 1: case 2: /*Timers*/ 28.445 + t = port & 3; 28.446 + switch (pas16->pit.wm[t]) 28.447 + { 28.448 + case 1: 28.449 + pas16->pit.l[t] = val; 28.450 + pas16->pit.thit[t] = 0; 28.451 + pas16->pit.c[t] = pas16->pit.l[t]; 28.452 + if (!t) 28.453 + pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); 28.454 + pas16->pit.enable[t] = 1; 28.455 + break; 28.456 + case 2: 28.457 + pas16->pit.l[t] = val << 8; 28.458 + pas16->pit.thit[t] = 0; 28.459 + pas16->pit.c[t] = pas16->pit.l[t]; 28.460 + if (!t) 28.461 + pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); 28.462 + pas16->pit.enable[t] = 1; 28.463 + break; 28.464 + case 0: 28.465 + pas16->pit.l[t] &= 0xFF; 28.466 + pas16->pit.l[t] |= (val << 8); 28.467 + pas16->pit.c[t] = pas16->pit.l[t]; 28.468 + if (!t) 28.469 + pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); 28.470 + pas16->pit.thit[t] = 0; 28.471 + pas16->pit.wm[t] = 3; 28.472 + pas16->pit.enable[t] = 1; 28.473 + break; 28.474 + case 3: 28.475 + pas16->pit.l[t] &= 0xFF00; 28.476 + pas16->pit.l[t] |= val; 28.477 + pas16->pit.wm[t] = 0; 28.478 + break; 28.479 + } 28.480 + if (!pas16->pit.l[t]) 28.481 + { 28.482 + pas16->pit.l[t] |= 0x10000; 28.483 + pas16->pit.c[t] = pas16->pit.l[t]; 28.484 + if (!t) 28.485 + pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); 28.486 + } 28.487 + break; 28.488 + } 28.489 +} 28.490 + 28.491 +static uint8_t pas16_pit_in(uint16_t port, void *p) 28.492 +{ 28.493 + pas16_t *pas16 = (pas16_t *)p; 28.494 + uint8_t temp; 28.495 + int t = port & 3; 28.496 +// printf("Read PIT %04X ",addr); 28.497 + switch (port & 3) 28.498 + { 28.499 + case 0: case 1: case 2: /*Timers*/ 28.500 + if (pas16->pit.rereadlatch[t]) 28.501 + { 28.502 + pas16->pit.rereadlatch[t] = 0; 28.503 + if (!t) 28.504 + { 28.505 + pas16->pit.rl[t] = pas16->pit.c[t] / (PITCONST * (1 << TIMER_SHIFT)); 28.506 + if ((pas16->pit.c[t] / (PITCONST * (1 << TIMER_SHIFT))) > 65536) 28.507 + pas16->pit.rl[t] = 0xFFFF; 28.508 + } 28.509 + else 28.510 + { 28.511 + pas16->pit.rl[t] = pas16->pit.c[t]; 28.512 + if (pas16->pit.c[t] > 65536) 28.513 + pas16->pit.rl[t] = 0xFFFF; 28.514 + } 28.515 + } 28.516 + switch (pas16->pit.rm[t]) 28.517 + { 28.518 + case 0: 28.519 + temp = pas16->pit.rl[t] >> 8; 28.520 + pas16->pit.rm[t] = 3; 28.521 + pas16->pit.rereadlatch[t] = 1; 28.522 + break; 28.523 + case 1: 28.524 + temp = (pas16->pit.rl[t]) & 0xFF; 28.525 + pas16->pit.rereadlatch[t] = 1; 28.526 + break; 28.527 + case 2: 28.528 + temp = (pas16->pit.rl[t]) >> 8; 28.529 + pas16->pit.rereadlatch[t] = 1; 28.530 + break; 28.531 + case 3: 28.532 + temp = (pas16->pit.rl[t]) & 0xFF; 28.533 + if (pas16->pit.m[t] & 0x80) pas16->pit.m[t] &= 7; 28.534 + else pas16->pit.rm[t] = 0; 28.535 + break; 28.536 + } 28.537 + break; 28.538 + case 3: /*Control*/ 28.539 + temp = pas16->pit.ctrl; 28.540 + break; 28.541 + } 28.542 +// printf("%02X %i %i %04X:%04X\n",temp,pit.rm[addr&3],pit.wp,cs>>4,pc); 28.543 + return temp; 28.544 +} 28.545 + 28.546 +static uint8_t pas16_readdma(pas16_t *pas16) 28.547 +{ 28.548 + return dma_channel_read(pas16->dma); 28.549 +} 28.550 + 28.551 +static void pas16_pcm_poll(void *p) 28.552 +{ 28.553 + pas16_t *pas16 = (pas16_t *)p; 28.554 +// if (pas16->pcm_ctrl & PAS16_PCM_ENA) 28.555 +// pclog("pas16_pcm_poll : poll %i %i ", pas16->pit.c[0], pas16->pit.l[0]); 28.556 + if (pas16->pit.m[0] & 2) 28.557 + { 28.558 + if (pas16->pit.l[0]) 28.559 + pas16->pit.c[0] += (pas16->pit.l[0] * PITCONST * (1 << TIMER_SHIFT)); 28.560 + else 28.561 + pas16->pit.c[0] += (0x10000 * PITCONST * (1 << TIMER_SHIFT)); 28.562 + } 28.563 + else 28.564 + { 28.565 + pas16->pit.c[0] = -1; 28.566 + pas16->pit.enable[0] = 0; 28.567 + } 28.568 +// if (pas16->pcm_ctrl & PAS16_PCM_ENA) 28.569 +// pclog(" %i\n", pas16->pit.c[0]); 28.570 + 28.571 + pas16->irq_stat |= PAS16_INT_SAMP; 28.572 + if (pas16->irq_ena & PAS16_INT_SAMP) 28.573 + picint(1 << pas16->irq); 28.574 +// pas16_update_irqs(); 28.575 + 28.576 + /*Update sample rate counter*/ 28.577 + if (pas16->pit.enable[1]) 28.578 + { 28.579 + if (pas16->pcm_ctrl & PAS16_PCM_ENA) 28.580 + { 28.581 + uint16_t temp; 28.582 + 28.583 + if (pas16->sys_conf_2 & PAS16_SC2_16BIT) 28.584 + { 28.585 + temp = pas16_readdma(pas16) << 8; 28.586 + temp |= pas16_readdma(pas16); 28.587 + } 28.588 + else 28.589 + temp = (pas16_readdma(pas16) ^ 0x80) << 8; 28.590 + 28.591 + if (pas16->sys_conf_2 & PAS16_SC2_MSBINV) 28.592 + temp ^= 0x8000; 28.593 + if (pas16->pcm_ctrl & PAS16_PCM_MONO) 28.594 + pas16->pcm_dat_l = pas16->pcm_dat_r = temp; 28.595 + else 28.596 + { 28.597 + if (pas16->stereo_lr) 28.598 + pas16->pcm_dat_r = temp; 28.599 + else 28.600 + pas16->pcm_dat_l = temp; 28.601 + 28.602 + pas16->stereo_lr = !pas16->stereo_lr; 28.603 + } 28.604 +// pclog("pas16_pcm_poll : %04X %i\n", temp, pas16->stereo_lr); 28.605 +// pclog("pas16_pcm_poll : %i %02X %i\n", pas16->pit.c[1], temp, pas16->pit.c[0]); 28.606 +/* if (!pas16_pcm) 28.607 + pas16_pcm=fopen("pas16->pcm", "wb"); 28.608 + putc(temp, pas16_pcm);*/ 28.609 + } 28.610 + if (pas16->sys_conf_2 & PAS16_SC2_16BIT) 28.611 + pas16->pit.c[1] -= 2; 28.612 + else 28.613 + pas16->pit.c[1]--; 28.614 + if (pas16->pit.c[1] == 0) 28.615 + { 28.616 +// if (pas16->pcm_ctrl & PAS16_PCM_ENA) 28.617 +// pclog("pas16_pcm_poll : buffer over\n"); 28.618 + if (pas16->pit.m[1] & 2) 28.619 + { 28.620 + if (pas16->pit.l[1]) 28.621 + pas16->pit.c[1] += pas16->pit.l[1]; 28.622 + else 28.623 + pas16->pit.c[1] += 0x10000; 28.624 + } 28.625 + else 28.626 + { 28.627 + pas16->pit.c[1] = -1; 28.628 + pas16->pit.enable[1] = 0; 28.629 + } 28.630 + 28.631 + pas16->irq_stat |= PAS16_INT_PCM; 28.632 + if (pas16->irq_ena & PAS16_INT_PCM) 28.633 + { 28.634 + pclog("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); 28.635 + picint(1 << pas16->irq); 28.636 + } 28.637 + } 28.638 + } 28.639 +} 28.640 + 28.641 +static void pas16_out_base(uint16_t port, uint8_t val, void *p) 28.642 +{ 28.643 + pas16_t *pas16 = (pas16_t *)p; 28.644 + 28.645 + io_removehandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.646 + io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.647 + io_removehandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.648 + io_removehandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.649 + io_removehandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.650 + io_removehandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.651 + io_removehandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.652 + io_removehandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.653 + io_removehandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.654 + io_removehandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.655 + io_removehandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.656 + io_removehandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.657 + io_removehandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.658 + io_removehandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.659 + io_removehandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.660 + io_removehandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.661 + io_removehandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.662 + io_removehandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.663 + 28.664 + pas16->base = val << 2; 28.665 + pclog("pas16_write_base : PAS16 base now at %04X\n", pas16->base); 28.666 + 28.667 + io_sethandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.668 + io_sethandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.669 + io_sethandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.670 + io_sethandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.671 + io_sethandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.672 + io_sethandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.673 + io_sethandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.674 + io_sethandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.675 + io_sethandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.676 + io_sethandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.677 + io_sethandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.678 + io_sethandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.679 + io_sethandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.680 + io_sethandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.681 + io_sethandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.682 + io_sethandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.683 + io_sethandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.684 + io_sethandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL, pas16); 28.685 +} 28.686 + 28.687 + 28.688 +void pas16_poll(void *p) 28.689 +{ 28.690 + pas16_t *pas16 = (pas16_t *)p; 28.691 + 28.692 + if (pas16->pos >= SOUNDBUFLEN) 28.693 + return; 28.694 + 28.695 + opl3_poll(&pas16->opl, &pas16->opl_buffer[pas16->pos * 2], &pas16->opl_buffer[(pas16->pos * 2) + 1]); 28.696 + sb_dsp_poll(&pas16->dsp, &pas16->dsp_buffer[pas16->pos * 2], &pas16->dsp_buffer[(pas16->pos * 2) + 1]); 28.697 + 28.698 + if (!(pas16->audiofilt & PAS16_FILT_MUTE)) 28.699 + { 28.700 + pas16->pcm_buffer[0][pas16->pos] = 0; 28.701 + pas16->pcm_buffer[1][pas16->pos] = 0; 28.702 + } 28.703 + else 28.704 + { 28.705 + pas16->pcm_buffer[0][pas16->pos] = (int16_t)pas16->pcm_dat_l; 28.706 + pas16->pcm_buffer[1][pas16->pos] = (int16_t)pas16->pcm_dat_r; 28.707 + } 28.708 + pas16->pos++; 28.709 +} 28.710 + 28.711 +void pas16_get_buffer(int16_t *buffer, int len, void *p) 28.712 +{ 28.713 + pas16_t *pas16 = (pas16_t *)p; 28.714 + int c; 28.715 + 28.716 + for (c = 0; c < len * 2; c++) 28.717 + { 28.718 + buffer[c] += pas16->opl_buffer[c]; 28.719 + buffer[c] += (int16_t)(sb_iir(c & 1, (float)pas16->dsp_buffer[c]) / 1.3) / 2; 28.720 + buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2); 28.721 + } 28.722 + 28.723 + pas16->pos = 0; 28.724 +} 28.725 + 28.726 +void *pas16_init() 28.727 +{ 28.728 + pas16_t *pas16 = malloc(sizeof(pas16_t)); 28.729 + memset(pas16, 0, sizeof(pas16_t)); 28.730 + 28.731 + opl3_init(&pas16->opl); 28.732 + sb_dsp_init(&pas16->dsp, SB2); 28.733 + 28.734 + io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); 28.735 + 28.736 + timer_add(pas16_pcm_poll, &pas16->pit.c[0], &pas16->pit.enable[0], pas16); 28.737 + 28.738 + sound_add_handler(pas16_poll, pas16_get_buffer, pas16); 28.739 + 28.740 + return pas16; 28.741 +} 28.742 + 28.743 +void pas16_close(void *p) 28.744 +{ 28.745 + pas16_t *pas16 = (pas16_t *)p; 28.746 + 28.747 + free(pas16); 28.748 +} 28.749 + 28.750 +device_t pas16_device = 28.751 +{ 28.752 + "Pro Audio Spectrum 16", 28.753 + pas16_init, 28.754 + pas16_close, 28.755 + NULL 28.756 +};
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/src/sound_pas16.h Mon May 27 19:56:33 2013 +0100 29.3 @@ -0,0 +1,1 @@ 29.4 +extern device_t pas16_device;
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/src/sound_sb.c Mon May 27 19:56:33 2013 +0100 30.3 @@ -0,0 +1,412 @@ 30.4 +#include <stdlib.h> 30.5 +#include "ibm.h" 30.6 +#include "device.h" 30.7 +#include "sound_sb.h" 30.8 +#include "sound_sb_dsp.h" 30.9 +#include "sound_opl.h" 30.10 + 30.11 +#include "filters.h" 30.12 + 30.13 +typedef struct sb_mixer_t 30.14 +{ 30.15 + int master_l, master_r; 30.16 + int voice_l, voice_r; 30.17 + int fm_l, fm_r; 30.18 + int bass_l, bass_r; 30.19 + int treble_l, treble_r; 30.20 + int filter; 30.21 + 30.22 + int index; 30.23 + uint8_t regs[256]; 30.24 +} sb_mixer_t; 30.25 + 30.26 +typedef struct sb_t 30.27 +{ 30.28 + opl_t opl; 30.29 + sb_dsp_t dsp; 30.30 + sb_mixer_t mixer; 30.31 + 30.32 + int16_t opl_buffer[SOUNDBUFLEN * 2]; 30.33 + int16_t dsp_buffer[SOUNDBUFLEN * 2]; 30.34 + 30.35 + int pos; 30.36 +} sb_t; 30.37 + 30.38 +static int sb_att[]= 30.39 +{ 30.40 + 310,368,437,520,618,735,873,1038,1234,1467,1743,2072,2463,2927,3479, 30.41 + 4134,4914,5840,6941,8250,9805,11653,13850,16461,19564,23252,27635,32845, 30.42 + 39036,46395,55140,65535 30.43 +}; 30.44 + 30.45 + 30.46 + 30.47 +static void sb_opl2_poll(void *p) 30.48 +{ 30.49 + sb_t *sb = (sb_t *)p; 30.50 + 30.51 + if (sb->pos >= SOUNDBUFLEN) return; 30.52 + 30.53 + opl2_poll(&sb->opl, &sb->opl_buffer[sb->pos * 2], &sb->opl_buffer[(sb->pos * 2) + 1]); 30.54 + sb_dsp_poll(&sb->dsp, &sb->dsp_buffer[sb->pos * 2], &sb->dsp_buffer[(sb->pos * 2) + 1]); 30.55 + sb->pos++; 30.56 +} 30.57 + 30.58 +static void sb_opl3_poll(void *p) 30.59 +{ 30.60 + sb_t *sb = (sb_t *)p; 30.61 + 30.62 + if (sb->pos >= SOUNDBUFLEN) return; 30.63 + 30.64 + opl3_poll(&sb->opl, &sb->opl_buffer[sb->pos * 2], &sb->opl_buffer[(sb->pos * 2) + 1]); 30.65 + sb_dsp_poll(&sb->dsp, &sb->dsp_buffer[sb->pos * 2], &sb->dsp_buffer[(sb->pos * 2) + 1]); 30.66 + sb->pos++; 30.67 +} 30.68 + 30.69 +static void sb_get_buffer(int16_t *buffer, int len, void *p) 30.70 +{ 30.71 + sb_t *sb = (sb_t *)p; 30.72 + sb_mixer_t *mixer = &sb->mixer; 30.73 + 30.74 + int c; 30.75 + 30.76 + for (c = 0; c < len * 2; c += 2) 30.77 + { 30.78 + int16_t out_l, out_r; 30.79 + 30.80 + out_l = ((sb->opl_buffer[c] * mixer->fm_l) >> 16); 30.81 + out_r = ((sb->opl_buffer[c + 1] * mixer->fm_r) >> 16); 30.82 + if (sb->mixer.filter) 30.83 + { 30.84 + out_l += (int)(((sb_iir(0, (float)sb->dsp_buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 16; 30.85 + out_r += (int)(((sb_iir(1, (float)sb->dsp_buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 16; 30.86 + } 30.87 + else 30.88 + { 30.89 + out_l += ((sb->dsp_buffer[c] * mixer->voice_l) / 3) >> 16; 30.90 + out_r += ((sb->dsp_buffer[c + 1] * mixer->voice_r) / 3) >> 16; 30.91 + } 30.92 + 30.93 + out_l = (out_l * mixer->master_l) >> 16; 30.94 + out_r = (out_r * mixer->master_r) >> 16; 30.95 + 30.96 + if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) 30.97 + { 30.98 + if (mixer->bass_l>8) out_l = (out_l + (((int16_t) low_iir(0, (float)out_l) * (mixer->bass_l - 8)) >> 1)) * ((15 - mixer->bass_l) + 16) >> 5; 30.99 + if (mixer->bass_r>8) out_r = (out_r + (((int16_t) low_iir(1, (float)out_r) * (mixer->bass_r - 8)) >> 1)) * ((15 - mixer->bass_r) + 16) >> 5; 30.100 + if (mixer->treble_l>8) out_l = (out_l + (((int16_t) high_iir(0, (float)out_l) * (mixer->treble_l - 8)) >> 1)) * ((15 - mixer->treble_l) + 16) >> 5; 30.101 + if (mixer->treble_r>8) out_r = (out_r + (((int16_t) high_iir(1, (float)out_r) * (mixer->treble_r - 8)) >> 1)) * ((15 - mixer->treble_r) + 16) >> 5; 30.102 + if (mixer->bass_l<8) out_l = (out_l + (((int16_t) low_cut_iir(0, (float)out_l) * (8 - mixer->bass_l)) >> 1)) * (mixer->bass_l + 16) >> 5; 30.103 + if (mixer->bass_r<8) out_r = (out_r + (((int16_t) low_cut_iir(1, (float)out_r) * (8 - mixer->bass_r)) >> 1)) * (mixer->bass_r + 16) >> 5; 30.104 + if (mixer->treble_l<8) out_l = (out_l + (((int16_t)high_cut_iir(0, (float)out_l) * (8 - mixer->treble_l)) >> 1)) * (mixer->treble_l + 16) >> 5; 30.105 + if (mixer->treble_r<8) out_r = (out_r + (((int16_t)high_cut_iir(1, (float)out_r) * (8 - mixer->treble_r)) >> 1)) * (mixer->treble_r + 16) >> 5; 30.106 + } 30.107 + 30.108 + buffer[c] += out_l; 30.109 + buffer[c + 1] += out_r; 30.110 + } 30.111 + 30.112 + sb->pos = 0; 30.113 +} 30.114 + 30.115 + 30.116 +void sb_pro_mixer_write(uint16_t addr, uint8_t val, void *p) 30.117 +{ 30.118 + sb_t *sb = (sb_t *)p; 30.119 + sb_mixer_t *mixer = &sb->mixer; 30.120 + 30.121 + if (!(addr & 1)) 30.122 + mixer->index = val & 0xff; 30.123 + else 30.124 + { 30.125 + mixer->regs[mixer->index] = val; 30.126 + 30.127 + mixer->master_l = sb_att[(mixer->regs[0x22] >> 4) | 0x11]; 30.128 + mixer->master_r = sb_att[(mixer->regs[0x22] & 0xf) | 0x11]; 30.129 + mixer->voice_l = sb_att[(mixer->regs[0x04] >> 4) | 0x11]; 30.130 + mixer->voice_r = sb_att[(mixer->regs[0x04] & 0xf) | 0x11]; 30.131 + mixer->fm_l = sb_att[(mixer->regs[0x26] >> 4) | 0x11]; 30.132 + mixer->fm_r = sb_att[(mixer->regs[0x26] & 0xf) | 0x11]; 30.133 + mixer->filter = !(mixer->regs[0xe] & 0x20); 30.134 + mixer->bass_l = mixer->bass_r = 8; 30.135 + mixer->treble_l = mixer->treble_r = 8; 30.136 + pclog("%02X %02X %02X\n", mixer->regs[0x04], mixer->regs[0x22], mixer->regs[0x26]); 30.137 + pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r); 30.138 + if (mixer->index == 0xe) 30.139 + sb_dsp_set_stereo(&sb->dsp, val & 2); 30.140 + } 30.141 +} 30.142 + 30.143 +uint8_t sb_pro_mixer_read(uint16_t addr, void *p) 30.144 +{ 30.145 + sb_t *sb = (sb_t *)p; 30.146 + sb_mixer_t *mixer = &sb->mixer; 30.147 + 30.148 + if (!(addr & 1)) 30.149 + return mixer->index; 30.150 + 30.151 + return mixer->regs[mixer->index]; 30.152 +} 30.153 + 30.154 +void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p) 30.155 +{ 30.156 + sb_t *sb = (sb_t *)p; 30.157 + sb_mixer_t *mixer = &sb->mixer; 30.158 + 30.159 + if (!(addr & 1)) 30.160 + mixer->index = val; 30.161 + else 30.162 + { 30.163 + mixer->regs[mixer->index] = val; 30.164 + switch (mixer->index) 30.165 + { 30.166 + case 0x22: 30.167 + mixer->regs[0x30] = ((mixer->regs[0x22] >> 4) | 0x11) << 3; 30.168 + mixer->regs[0x31] = ((mixer->regs[0x22] & 0xf) | 0x11) << 3; 30.169 + break; 30.170 + case 0x04: 30.171 + mixer->regs[0x32] = ((mixer->regs[0x04] >> 4) | 0x11) << 3; 30.172 + mixer->regs[0x33] = ((mixer->regs[0x04] & 0xf) | 0x11) << 3; 30.173 + break; 30.174 + case 0x26: 30.175 + mixer->regs[0x34] = ((mixer->regs[0x26] >> 4) | 0x11) << 3; 30.176 + mixer->regs[0x35] = ((mixer->regs[0x26] & 0xf) | 0x11) << 3; 30.177 + break; 30.178 + case 0x80: 30.179 + if (val & 1) sb->dsp.sb_irqnum = 2; 30.180 + if (val & 2) sb->dsp.sb_irqnum = 5; 30.181 + if (val & 4) sb->dsp.sb_irqnum = 7; 30.182 + if (val & 8) sb->dsp.sb_irqnum = 10; 30.183 + break; 30.184 + } 30.185 + mixer->master_l = sb_att[mixer->regs[0x30] >> 3]; 30.186 + mixer->master_r = sb_att[mixer->regs[0x31] >> 3]; 30.187 + mixer->voice_l = sb_att[mixer->regs[0x32] >> 3]; 30.188 + mixer->voice_r = sb_att[mixer->regs[0x33] >> 3]; 30.189 + mixer->fm_l = sb_att[mixer->regs[0x34] >> 3]; 30.190 + mixer->fm_r = sb_att[mixer->regs[0x35] >> 3]; 30.191 + mixer->bass_l = mixer->regs[0x46] >> 4; 30.192 + mixer->bass_r = mixer->regs[0x47] >> 4; 30.193 + mixer->treble_l = mixer->regs[0x44] >> 4; 30.194 + mixer->treble_r = mixer->regs[0x45] >> 4; 30.195 + mixer->filter = 0; 30.196 + pclog("%02X %02X %02X %02X %02X %02X\n", mixer->regs[0x30], mixer->regs[0x31], mixer->regs[0x32], mixer->regs[0x33], mixer->regs[0x34], mixer->regs[0x35]); 30.197 + pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r); 30.198 + } 30.199 +} 30.200 + 30.201 +uint8_t sb_16_mixer_read(uint16_t addr, void *p) 30.202 +{ 30.203 + sb_t *sb = (sb_t *)p; 30.204 + sb_mixer_t *mixer = &sb->mixer; 30.205 + 30.206 + if (!(addr & 1)) 30.207 + return mixer->index; 30.208 + 30.209 + switch (mixer->index) 30.210 + { 30.211 + case 0x80: 30.212 + switch (sb->dsp.sb_irqnum) 30.213 + { 30.214 + case 2: return 1; /*IRQ 7*/ 30.215 + case 5: return 2; /*IRQ 7*/ 30.216 + case 7: return 4; /*IRQ 7*/ 30.217 + case 10: return 8; /*IRQ 7*/ 30.218 + } 30.219 + break; 30.220 + case 0x81: 30.221 + return 0x22; /*DMA 1 and 5*/ 30.222 + case 0x82: 30.223 + return ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0); 30.224 + } 30.225 + return mixer->regs[mixer->index]; 30.226 +} 30.227 + 30.228 +void sb_mixer_init(sb_mixer_t *mixer) 30.229 +{ 30.230 + mixer->master_l = mixer->master_r = 65535; 30.231 + mixer->voice_l = mixer->voice_r = 65535; 30.232 + mixer->fm_l = mixer->fm_r = 65535; 30.233 + mixer->bass_l = mixer->bass_r = 8; 30.234 + mixer->treble_l = mixer->treble_r = 8; 30.235 + mixer->filter = 1; 30.236 +} 30.237 + 30.238 +void *sb_1_init() 30.239 +{ 30.240 + sb_t *sb = malloc(sizeof(sb_t)); 30.241 + memset(sb, 0, sizeof(sb_t)); 30.242 + 30.243 + opl2_init(&sb->opl); 30.244 + sb_dsp_init(&sb->dsp, SB1); 30.245 + sb_dsp_setaddr(&sb->dsp, 0x0220); 30.246 + sb_mixer_init(&sb->mixer); 30.247 + io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 30.248 + io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 30.249 + sound_add_handler(sb_opl2_poll, sb_get_buffer, sb); 30.250 + return sb; 30.251 +} 30.252 +void *sb_15_init() 30.253 +{ 30.254 + sb_t *sb = malloc(sizeof(sb_t)); 30.255 + memset(sb, 0, sizeof(sb_t)); 30.256 + 30.257 + opl2_init(&sb->opl); 30.258 + sb_dsp_init(&sb->dsp, SB15); 30.259 + sb_dsp_setaddr(&sb->dsp, 0x0220); 30.260 + sb_mixer_init(&sb->mixer); 30.261 + io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 30.262 + io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 30.263 + sound_add_handler(sb_opl2_poll, sb_get_buffer, sb); 30.264 + return sb; 30.265 +} 30.266 +void *sb_2_init() 30.267 +{ 30.268 + sb_t *sb = malloc(sizeof(sb_t)); 30.269 + memset(sb, 0, sizeof(sb_t)); 30.270 + 30.271 + opl2_init(&sb->opl); 30.272 + sb_dsp_init(&sb->dsp, SB2); 30.273 + sb_dsp_setaddr(&sb->dsp, 0x0220); 30.274 + sb_mixer_init(&sb->mixer); 30.275 + io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 30.276 + io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 30.277 + sound_add_handler(sb_opl2_poll, sb_get_buffer, sb); 30.278 + return sb; 30.279 +} 30.280 + 30.281 +void *sb_pro_v1_init() 30.282 +{ 30.283 + sb_t *sb = malloc(sizeof(sb_t)); 30.284 + memset(sb, 0, sizeof(sb_t)); 30.285 + 30.286 + opl2_init(&sb->opl); 30.287 + sb_dsp_init(&sb->dsp, SBPRO); 30.288 + sb_dsp_setaddr(&sb->dsp, 0x0220); 30.289 + sb_mixer_init(&sb->mixer); 30.290 + io_sethandler(0x0220, 0x0002, opl2_l_read, NULL, NULL, opl2_l_write, NULL, NULL, &sb->opl); 30.291 + io_sethandler(0x0222, 0x0002, opl2_r_read, NULL, NULL, opl2_r_write, NULL, NULL, &sb->opl); 30.292 + io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 30.293 + io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 30.294 + io_sethandler(0x0224, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb); 30.295 + sound_add_handler(sb_opl2_poll, sb_get_buffer, sb); 30.296 + 30.297 + sb->mixer.regs[0x22] = 0xff; 30.298 + sb->mixer.regs[0x04] = 0xff; 30.299 + sb->mixer.regs[0x26] = 0xff; 30.300 + sb->mixer.regs[0xe] = 0; 30.301 + 30.302 + return sb; 30.303 +} 30.304 + 30.305 +void *sb_pro_v2_init() 30.306 +{ 30.307 + sb_t *sb = malloc(sizeof(sb_t)); 30.308 + memset(sb, 0, sizeof(sb_t)); 30.309 + 30.310 + opl3_init(&sb->opl); 30.311 + sb_dsp_init(&sb->dsp, SBPRO2); 30.312 + sb_dsp_setaddr(&sb->dsp, 0x0220); 30.313 + sb_mixer_init(&sb->mixer); 30.314 + io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 30.315 + io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 30.316 + io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 30.317 + io_sethandler(0x0224, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb); 30.318 + sound_add_handler(sb_opl3_poll, sb_get_buffer, sb); 30.319 + 30.320 + sb->mixer.regs[0x22] = 0xff; 30.321 + sb->mixer.regs[0x04] = 0xff; 30.322 + sb->mixer.regs[0x26] = 0xff; 30.323 + sb->mixer.regs[0xe] = 0; 30.324 + 30.325 + return sb; 30.326 +} 30.327 + 30.328 +void *sb_16_init() 30.329 +{ 30.330 + sb_t *sb = malloc(sizeof(sb_t)); 30.331 + memset(sb, 0, sizeof(sb_t)); 30.332 + 30.333 + opl3_init(&sb->opl); 30.334 + sb_dsp_init(&sb->dsp, SB16); 30.335 + sb_dsp_setaddr(&sb->dsp, 0x0220); 30.336 + sb_mixer_init(&sb->mixer); 30.337 + io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 30.338 + io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 30.339 + io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 30.340 + io_sethandler(0x0224, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); 30.341 + sound_add_handler(sb_opl3_poll, sb_get_buffer, sb); 30.342 + 30.343 + sb->mixer.regs[0x30] = 31 << 3; 30.344 + sb->mixer.regs[0x31] = 31 << 3; 30.345 + sb->mixer.regs[0x32] = 31 << 3; 30.346 + sb->mixer.regs[0x33] = 31 << 3; 30.347 + sb->mixer.regs[0x34] = 31 << 3; 30.348 + sb->mixer.regs[0x35] = 31 << 3; 30.349 + sb->mixer.regs[0x44] = 8 << 4; 30.350 + sb->mixer.regs[0x45] = 8 << 4; 30.351 + sb->mixer.regs[0x46] = 8 << 4; 30.352 + sb->mixer.regs[0x47] = 8 << 4; 30.353 + sb->mixer.regs[0x22] = (sb->mixer.regs[0x30] & 0xf0) | (sb->mixer.regs[0x31] >> 4); 30.354 + sb->mixer.regs[0x04] = (sb->mixer.regs[0x32] & 0xf0) | (sb->mixer.regs[0x33] >> 4); 30.355 + sb->mixer.regs[0x26] = (sb->mixer.regs[0x34] & 0xf0) | (sb->mixer.regs[0x35] >> 4); 30.356 + 30.357 + return sb; 30.358 +} 30.359 + 30.360 +void sb_close(void *p) 30.361 +{ 30.362 + sb_t *sb = (sb_t *)p; 30.363 + 30.364 + free(sb); 30.365 +} 30.366 + 30.367 +void sb_speed_changed(void *p) 30.368 +{ 30.369 + sb_t *sb = (sb_t *)p; 30.370 + 30.371 + sb_dsp_speed_changed(&sb->dsp); 30.372 +} 30.373 + 30.374 +device_t sb_1_device = 30.375 +{ 30.376 + "Sound Blaster v1.0", 30.377 + sb_1_init, 30.378 + sb_close, 30.379 + sb_speed_changed 30.380 +}; 30.381 +device_t sb_15_device = 30.382 +{ 30.383 + "Sound Blaster v1.5", 30.384 + sb_15_init, 30.385 + sb_close, 30.386 + sb_speed_changed 30.387 +}; 30.388 +device_t sb_2_device = 30.389 +{ 30.390 + "Sound Blaster v2.0", 30.391 + sb_2_init, 30.392 + sb_close, 30.393 + sb_speed_changed 30.394 +}; 30.395 +device_t sb_pro_v1_device = 30.396 +{ 30.397 + "Sound Blaster Pro v1", 30.398 + sb_pro_v1_init, 30.399 + sb_close, 30.400 + sb_speed_changed 30.401 +}; 30.402 +device_t sb_pro_v2_device = 30.403 +{ 30.404 + "Sound Blaster Pro v2", 30.405 + sb_pro_v2_init, 30.406 + sb_close, 30.407 + sb_speed_changed 30.408 +}; 30.409 +device_t sb_16_device = 30.410 +{ 30.411 + "Sound Blaster 16", 30.412 + sb_16_init, 30.413 + sb_close, 30.414 + sb_speed_changed 30.415 +};
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/src/sound_sb.h Mon May 27 19:56:33 2013 +0100 31.3 @@ -0,0 +1,6 @@ 31.4 +extern device_t sb_1_device; 31.5 +extern device_t sb_15_device; 31.6 +extern device_t sb_2_device; 31.7 +extern device_t sb_pro_v1_device; 31.8 +extern device_t sb_pro_v2_device; 31.9 +extern device_t sb_16_device;
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/src/sound_sb_dsp.c Mon May 27 19:56:33 2013 +0100 32.3 @@ -0,0 +1,908 @@ 32.4 +/*Jazz sample rates : 32.5 + 386-33 - 12kHz 32.6 + 486-33 - 20kHz 32.7 + 486-50 - 32kHz 32.8 + Pentium - 45kHz*/ 32.9 + 32.10 +#include <stdint.h> 32.11 +#include <stdio.h> 32.12 +#include "ibm.h" 32.13 + 32.14 + 32.15 +#include "dma.h" 32.16 +#include "io.h" 32.17 +#include "pic.h" 32.18 +#include "sound.h" 32.19 +#include "sound_sb_dsp.h" 32.20 +#include "timer.h" 32.21 + 32.22 +void pollsb(void *p); 32.23 +void sb_poll_i(void *p); 32.24 + 32.25 + 32.26 + 32.27 +static int sbe2dat[4][9] = { 32.28 + { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, 32.29 + { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, 32.30 + { -0x01, 0x02, 0x04, -0x08, 0x10, -0x20, -0x40, 0x80, -151 }, 32.31 + { 0x01, -0x02, 0x04, -0x08, -0x10, 0x20, -0x40, 0x80, 90 } 32.32 +}; 32.33 + 32.34 +static int sb_commands[256]= 32.35 +{ 32.36 + -1,-1,-1,-1, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1, 32.37 + 1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0, 32.38 + 0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1, 32.39 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 32.40 + 1, 2, 2,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 32.41 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 32.42 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 32.43 + -1,-1,-1,-1, 2, 2, 2, 2,-1,-1,-1,-1,-1, 0,-1, 0, 32.44 + 2, 2,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1, 32.45 + 0,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1, 32.46 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 32.47 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 32.48 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 32.49 + 0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1, 32.50 + 1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1, 32.51 + -1,-1, 0,-1,-1,-1,-1,-1,-1, 1, 2,-1,-1,-1,-1, 0 32.52 +}; 32.53 + 32.54 +char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; 32.55 +uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405}; 32.56 + 32.57 +/*These tables were 'borrowed' from DOSBox*/ 32.58 + int8_t scaleMap4[64] = { 32.59 + 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, 32.60 + 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, 32.61 + 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, 32.62 + 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 32.63 + }; 32.64 + uint8_t adjustMap4[64] = { 32.65 + 0, 0, 0, 0, 0, 16, 16, 16, 32.66 + 0, 0, 0, 0, 0, 16, 16, 16, 32.67 + 240, 0, 0, 0, 0, 16, 16, 16, 32.68 + 240, 0, 0, 0, 0, 16, 16, 16, 32.69 + 240, 0, 0, 0, 0, 16, 16, 16, 32.70 + 240, 0, 0, 0, 0, 16, 16, 16, 32.71 + 240, 0, 0, 0, 0, 0, 0, 0, 32.72 + 240, 0, 0, 0, 0, 0, 0, 0 32.73 + }; 32.74 + 32.75 + int8_t scaleMap26[40] = { 32.76 + 0, 1, 2, 3, 0, -1, -2, -3, 32.77 + 1, 3, 5, 7, -1, -3, -5, -7, 32.78 + 2, 6, 10, 14, -2, -6, -10, -14, 32.79 + 4, 12, 20, 28, -4, -12, -20, -28, 32.80 + 5, 15, 25, 35, -5, -15, -25, -35 32.81 + }; 32.82 + uint8_t adjustMap26[40] = { 32.83 + 0, 0, 0, 8, 0, 0, 0, 8, 32.84 + 248, 0, 0, 8, 248, 0, 0, 8, 32.85 + 248, 0, 0, 8, 248, 0, 0, 8, 32.86 + 248, 0, 0, 8, 248, 0, 0, 8, 32.87 + 248, 0, 0, 0, 248, 0, 0, 0 32.88 + }; 32.89 + 32.90 + int8_t scaleMap2[24] = { 32.91 + 0, 1, 0, -1, 1, 3, -1, -3, 32.92 + 2, 6, -2, -6, 4, 12, -4, -12, 32.93 + 8, 24, -8, -24, 6, 48, -16, -48 32.94 + }; 32.95 + uint8_t adjustMap2[24] = { 32.96 + 0, 4, 0, 4, 32.97 + 252, 4, 252, 4, 252, 4, 252, 4, 32.98 + 252, 4, 252, 4, 252, 4, 252, 4, 32.99 + 252, 0, 252, 0 32.100 + }; 32.101 + 32.102 + 32.103 + 32.104 +void sb_irq(sb_dsp_t *dsp, int irq8) 32.105 +{ 32.106 +// pclog("IRQ %i %02X\n",irq8,pic.mask); 32.107 + if (irq8) dsp->sb_irq8 = 1; 32.108 + else dsp->sb_irq16 = 1; 32.109 + picint(1 << dsp->sb_irqnum); 32.110 +} 32.111 +void sb_irqc(sb_dsp_t *dsp, int irq8) 32.112 +{ 32.113 + if (irq8) dsp->sb_irq8 = 0; 32.114 + else dsp->sb_irq16 = 0; 32.115 + picintc(1 << dsp->sb_irqnum); 32.116 +} 32.117 + 32.118 +void sb_dsp_reset(sb_dsp_t *dsp) 32.119 +{ 32.120 + dsp->sbenable = dsp->sb_enable_i = 0; 32.121 + dsp->sb_command = 0; 32.122 + 32.123 + dsp->sb_8_length = 0xffff; 32.124 + 32.125 + sb_irqc(dsp, 0); 32.126 + sb_irqc(dsp, 1); 32.127 + dsp->sb_16_pause = 0; 32.128 + dsp->sb_read_wp = dsp->sb_read_rp = 0; 32.129 + dsp->sb_data_stat = -1; 32.130 + dsp->sb_speaker = 0; 32.131 + dsp->sb_pausetime = -1; 32.132 + dsp->sbe2 = 0xAA; 32.133 + dsp->sbe2count = 0; 32.134 + 32.135 + dsp->sbreset = 0; 32.136 + dsp->sbenable = dsp->sb_enable_i = dsp->sb_count_i = 0; 32.137 + 32.138 + picintc(1 << dsp->sb_irqnum); 32.139 +} 32.140 + 32.141 +void sb_doreset(sb_dsp_t *dsp) 32.142 +{ 32.143 + int c; 32.144 + 32.145 + sb_dsp_reset(dsp); 32.146 + 32.147 + if (dsp->sb_type==SB16) sb_commands[8] = 1; 32.148 + else sb_commands[8] = -1; 32.149 + 32.150 + for (c = 0; c < 256; c++) 32.151 + dsp->sb_asp_regs[c] = 0; 32.152 + dsp->sb_asp_regs[5] = 0x01; 32.153 + dsp->sb_asp_regs[9] = 0xf8; 32.154 +} 32.155 + 32.156 +void sb_dsp_speed_changed(sb_dsp_t *dsp) 32.157 +{ 32.158 + if (dsp->sb_timeo < 256) 32.159 + dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo); 32.160 + else 32.161 + dsp->sblatcho = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256))); 32.162 + 32.163 + if (dsp->sb_timei < 256) 32.164 + dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei); 32.165 + else 32.166 + dsp->sblatchi = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256))); 32.167 +} 32.168 + 32.169 +void sb_add_data(sb_dsp_t *dsp, uint8_t v) 32.170 +{ 32.171 + dsp->sb_read_data[dsp->sb_read_wp++] = v; 32.172 + dsp->sb_read_wp &= 0xff; 32.173 +} 32.174 + 32.175 +#define ADPCM_4 1 32.176 +#define ADPCM_26 2 32.177 +#define ADPCM_2 3 32.178 + 32.179 +void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) 32.180 +{ 32.181 + if (dma8) 32.182 + { 32.183 + dsp->sb_8_length = len; 32.184 + dsp->sb_8_format = format; 32.185 + dsp->sb_8_autoinit = autoinit; 32.186 + dsp->sb_8_pause = 0; 32.187 + dsp->sb_8_enable = 1; 32.188 + if (dsp->sb_16_enable && dsp->sb_16_output) dsp->sb_16_enable = 0; 32.189 + dsp->sb_8_output = 1; 32.190 + timer_process(); 32.191 + dsp->sbenable = dsp->sb_8_enable; 32.192 + timer_update_outstanding(); 32.193 + dsp->sbleftright = 0; 32.194 + dsp->sbdacpos = 0; 32.195 +// pclog("Start 8-bit DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); 32.196 + } 32.197 + else 32.198 + { 32.199 + dsp->sb_16_length = len; 32.200 + dsp->sb_16_format = format; 32.201 + dsp->sb_16_autoinit = autoinit; 32.202 + dsp->sb_16_pause = 0; 32.203 + dsp->sb_16_enable = 1; 32.204 + if (dsp->sb_8_enable && dsp->sb_8_output) dsp->sb_8_enable = 0; 32.205 + dsp->sb_16_output = 1; 32.206 + timer_process(); 32.207 + dsp->sbenable = dsp->sb_16_enable; 32.208 + timer_update_outstanding(); 32.209 +// pclog("Start 16-bit DMA addr %06X len %04X\n",dma16.ac[1]+(dma16.page[1]<<16),len); 32.210 + } 32.211 +} 32.212 + 32.213 +void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) 32.214 +{ 32.215 + if (dma8) 32.216 + { 32.217 + dsp->sb_8_length = len; 32.218 + dsp->sb_8_format = format; 32.219 + dsp->sb_8_autoinit = autoinit; 32.220 + dsp->sb_8_pause = 0; 32.221 + dsp->sb_8_enable = 1; 32.222 + if (dsp->sb_16_enable && !dsp->sb_16_output) dsp->sb_16_enable = 0; 32.223 + dsp->sb_8_output = 0; 32.224 + timer_process(); 32.225 + dsp->sb_enable_i = dsp->sb_8_enable; 32.226 + timer_update_outstanding(); 32.227 +// pclog("Start 8-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); 32.228 + } 32.229 + else 32.230 + { 32.231 + dsp->sb_16_length = len; 32.232 + dsp->sb_16_format = format; 32.233 + dsp->sb_16_autoinit = autoinit; 32.234 + dsp->sb_16_pause = 0; 32.235 + dsp->sb_16_enable = 1; 32.236 + if (dsp->sb_8_enable && !dsp->sb_8_output) dsp->sb_8_enable = 0; 32.237 + dsp->sb_16_output = 0; 32.238 + timer_process(); 32.239 + dsp->sb_enable_i = dsp->sb_16_enable; 32.240 + timer_update_outstanding(); 32.241 +// pclog("Start 16-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); 32.242 + } 32.243 +} 32.244 + 32.245 +int sb_8_read_dma(sb_dsp_t *dsp) 32.246 +{ 32.247 + return dma_channel_read(dsp->sb_8_dmanum); 32.248 +} 32.249 +void sb_8_write_dma(sb_dsp_t *dsp, uint8_t val) 32.250 +{ 32.251 + dma_channel_write(dsp->sb_8_dmanum, val); 32.252 +} 32.253 +uint16_t sb_16_read_dma(sb_dsp_t *dsp) 32.254 +{ 32.255 + return dma_channel_read(5); 32.256 +} 32.257 +void sb_16_write_dma(sb_dsp_t *dsp, uint16_t val) 32.258 +{ 32.259 + dma_channel_write(5, val); 32.260 +} 32.261 + 32.262 +void sb_dsp_setirq(sb_dsp_t *dsp, int irq) 32.263 +{ 32.264 + dsp->sb_irqnum = irq; 32.265 +} 32.266 + 32.267 +void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) 32.268 +{ 32.269 + dsp->sb_8_dmanum = dma; 32.270 +} 32.271 + 32.272 +void sb_exec_command(sb_dsp_t *dsp) 32.273 +{ 32.274 + int temp,c; 32.275 + pclog("sb_exec_command : SB command %02X\n", dsp->sb_command); 32.276 + switch (dsp->sb_command) 32.277 + { 32.278 + case 0x10: /*8-bit direct mode*/ 32.279 + dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; 32.280 + break; 32.281 + case 0x14: /*8-bit single cycle DMA output*/ 32.282 + sb_start_dma(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); 32.283 + break; 32.284 + case 0x17: /*2-bit ADPCM output with reference*/ 32.285 + dsp->sbref = sb_8_read_dma(dsp); 32.286 + dsp->sbstep = 0; 32.287 +// pclog("Ref byte 2 %02X\n",sbref); 32.288 + case 0x16: /*2-bit ADPCM output*/ 32.289 + sb_start_dma(dsp, 1, 0, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); 32.290 + dsp->sbdat2 = sb_8_read_dma(dsp); 32.291 + dsp->sb_8_length--; 32.292 + break; 32.293 + case 0x1C: /*8-bit autoinit DMA output*/ 32.294 + if (dsp->sb_type < SB15) break; 32.295 + sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); 32.296 + break; 32.297 + case 0x1F: /*2-bit ADPCM autoinit output*/ 32.298 + if (dsp->sb_type < SB15) break; 32.299 + sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); 32.300 + dsp->sbdat2 = sb_8_read_dma(dsp); 32.301 + dsp->sb_8_length--; 32.302 + break; 32.303 + case 0x20: /*8-bit direct input*/ 32.304 + sb_add_data(dsp, 0); 32.305 + break; 32.306 + case 0x24: /*8-bit single cycle DMA input*/ 32.307 + sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); 32.308 + break; 32.309 + case 0x2C: /*8-bit autoinit DMA input*/ 32.310 + if (dsp->sb_type < SB15) break; 32.311 + sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); 32.312 + break; 32.313 + case 0x40: /*Set time constant*/ 32.314 + dsp->sb_timei = dsp->sb_timeo = dsp->sb_data[0]; 32.315 + dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]); 32.316 + temp = 256 - dsp->sb_data[0]; 32.317 + temp = 1000000 / temp; 32.318 +// printf("Sample rate - %ihz (%i)\n",temp, sblatcho); 32.319 + dsp->sb_freq = temp; 32.320 + break; 32.321 + case 0x41: /*Set output sampling rate*/ 32.322 + if (dsp->sb_type < SB16) break; 32.323 + dsp->sblatcho = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); 32.324 +// printf("Sample rate - %ihz (%i)\n",sb_data[1]+(sb_data[0]<<8), sblatcho); 32.325 + dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); 32.326 + dsp->sb_timeo = 256 + dsp->sb_freq; 32.327 + break; 32.328 + case 0x42: /*Set input sampling rate*/ 32.329 + if (dsp->sb_type < SB16) break; 32.330 + dsp->sblatchi = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); 32.331 +// printf("iample rate - %ihz\n",sb_data[1]+(sb_data[0]<<8)); 32.332 + dsp->sb_timei = 256 + dsp->sb_data[1] + (dsp->sb_data[0] << 8); 32.333 + break; 32.334 + case 0x48: /*Set DSP block transfer size*/ 32.335 + dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); 32.336 + break; 32.337 + case 0x75: /*4-bit ADPCM output with reference*/ 32.338 + dsp->sbref = sb_8_read_dma(dsp); 32.339 + dsp->sbstep = 0; 32.340 +// pclog("Ref byte 4 %02X\n",sbref); 32.341 + case 0x74: /*4-bit ADPCM output*/ 32.342 + sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); 32.343 + dsp->sbdat2 = sb_8_read_dma(dsp); 32.344 + dsp->sb_8_length--; 32.345 + break; 32.346 + case 0x77: /*2.6-bit ADPCM output with reference*/ 32.347 + dsp->sbref = sb_8_read_dma(dsp); 32.348 + dsp->sbstep = 0; 32.349 +// pclog("Ref byte 26 %02X\n",sbref); 32.350 + case 0x76: /*2.6-bit ADPCM output*/ 32.351 + sb_start_dma(dsp, 1, 0, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); 32.352 + dsp->sbdat2 = sb_8_read_dma(dsp); 32.353 + dsp->sb_8_length--; 32.354 + break; 32.355 + case 0x7D: /*4-bit ADPCM autoinit output*/ 32.356 + if (dsp->sb_type < SB15) break; 32.357 + sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); 32.358 + dsp->sbdat2 = sb_8_read_dma(dsp); 32.359 + dsp->sb_8_length--; 32.360 + break; 32.361 + case 0x7F: /*2.6-bit ADPCM autoinit output*/ 32.362 + if (dsp->sb_type < SB15) break; 32.363 + sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); 32.364 + dsp->sbdat2 = sb_8_read_dma(dsp); 32.365 + dsp->sb_8_length--; 32.366 + break; 32.367 + case 0x80: /*Pause DAC*/ 32.368 + dsp->sb_pausetime = dsp->sb_data[0] + (dsp->sb_data[1] << 8); 32.369 +// pclog("SB pause %04X\n",sb_pausetime); 32.370 + timer_process(); 32.371 + dsp->sbenable = 1; 32.372 + timer_update_outstanding(); 32.373 + break; 32.374 + case 0x90: /*High speed 8-bit autoinit DMA output*/ 32.375 + if (dsp->sb_type < SB2) break; 32.376 + sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); 32.377 + break; 32.378 + case 0x91: /*High speed 8-bit single cycle DMA output*/ 32.379 + if (dsp->sb_type < SB2) break; 32.380 + sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen); 32.381 + break; 32.382 + case 0x98: /*High speed 8-bit autoinit DMA input*/ 32.383 + if (dsp->sb_type < SB2) break; 32.384 + sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen); 32.385 + break; 32.386 + case 0x99: /*High speed 8-bit single cycle DMA input*/ 32.387 + if (dsp->sb_type < SB2) break; 32.388 + sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen); 32.389 + break; 32.390 + case 0xA0: /*Set input mode to mono*/ 32.391 + case 0xA8: /*Set input mode to stereo*/ 32.392 + break; 32.393 + case 0xB0: case 0xB1: case 0xB2: case 0xB3: 32.394 + case 0xB4: case 0xB5: case 0xB6: case 0xB7: /*16-bit DMA output*/ 32.395 + if (dsp->sb_type < SB16) break; 32.396 + sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); 32.397 + dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); 32.398 + break; 32.399 + case 0xB8: case 0xB9: case 0xBA: case 0xBB: 32.400 + case 0xBC: case 0xBD: case 0xBE: case 0xBF: /*16-bit DMA input*/ 32.401 + if (dsp->sb_type < SB16) break; 32.402 + sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); 32.403 + dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); 32.404 + break; 32.405 + case 0xC0: case 0xC1: case 0xC2: case 0xC3: 32.406 + case 0xC4: case 0xC5: case 0xC6: case 0xC7: /*8-bit DMA output*/ 32.407 + if (dsp->sb_type < SB16) break; 32.408 + sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); 32.409 + dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); 32.410 + break; 32.411 + case 0xC8: case 0xC9: case 0xCA: case 0xCB: 32.412 + case 0xCC: case 0xCD: case 0xCE: case 0xCF: /*8-bit DMA input*/ 32.413 + if (dsp->sb_type < SB16) break; 32.414 + sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); 32.415 + dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); 32.416 + break; 32.417 + case 0xD0: /*Pause 8-bit DMA*/ 32.418 + dsp->sb_8_pause = 1; 32.419 + break; 32.420 + case 0xD1: /*Speaker on*/ 32.421 + dsp->sb_speaker = 1; 32.422 + break; 32.423 + case 0xD3: /*Speaker off*/ 32.424 + dsp->sb_speaker = 0; 32.425 + break; 32.426 + case 0xD4: /*Continue 8-bit DMA*/ 32.427 + dsp->sb_8_pause = 0; 32.428 + break; 32.429 + case 0xD5: /*Pause 16-bit DMA*/ 32.430 + if (dsp->sb_type < SB16) break; 32.431 + dsp->sb_16_pause = 1; 32.432 + break; 32.433 + case 0xD6: /*Continue 16-bit DMA*/ 32.434 + if (dsp->sb_type < SB16) break; 32.435 + dsp->sb_16_pause = 0; 32.436 + break; 32.437 + case 0xD8: /*Get speaker status*/ 32.438 + sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0); 32.439 + break; 32.440 + case 0xD9: /*Exit 16-bit auto-init mode*/ 32.441 + if (dsp->sb_type < SB16) break; 32.442 + dsp->sb_16_autoinit = 0; 32.443 + break; 32.444 + case 0xDA: /*Exit 8-bit auto-init mode*/ 32.445 + dsp->sb_8_autoinit = 0; 32.446 + break; 32.447 + case 0xE0: /*DSP identification*/ 32.448 + sb_add_data(dsp, ~dsp->sb_data[0]); 32.449 + break; 32.450 + case 0xE1: /*Get DSP version*/ 32.451 + sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] >> 8); 32.452 + sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] & 0xff); 32.453 + break; 32.454 + case 0xE2: /*Stupid ID/protection*/ 32.455 + for (c = 0; c < 8; c++) 32.456 + if (dsp->sb_data[0] & (1 << c)) dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][c]; 32.457 + dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][8]; 32.458 + dsp->sbe2count++; 32.459 + sb_8_write_dma(dsp, dsp->sbe2); 32.460 + break; 32.461 + case 0xE3: /*DSP copyright*/ 32.462 + if (dsp->sb_type < SB16) break; 32.463 + c = 0; 32.464 + while (sb16_copyright[c]) 32.465 + sb_add_data(dsp, sb16_copyright[c++]); 32.466 + sb_add_data(dsp, 0); 32.467 + break; 32.468 + case 0xE4: /*Write test register*/ 32.469 + dsp->sb_test = dsp->sb_data[0]; 32.470 + break; 32.471 + case 0xE8: /*Read test register*/ 32.472 + sb_add_data(dsp, dsp->sb_test); 32.473 + break; 32.474 + case 0xF2: /*Trigger 8-bit IRQ*/ 32.475 +// pclog("Trigger IRQ\n"); 32.476 + sb_irq(dsp, 1); 32.477 + break; 32.478 + case 0xE7: /*???*/ 32.479 + case 0xFA: /*???*/ 32.480 + break; 32.481 + case 0x07: /*No, that's not how you program auto-init DMA*/ 32.482 + case 0xFF: 32.483 + break; 32.484 + case 0x08: /*ASP get version*/ 32.485 + if (dsp->sb_type < SB16) break; 32.486 + sb_add_data(dsp, 0x18); 32.487 + break; 32.488 + case 0x0E: /*ASP set register*/ 32.489 + if (dsp->sb_type < SB16) break; 32.490 + dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; 32.491 +// pclog("ASP write reg %02X %02X\n", sb_data[0], sb_data[1]); 32.492 + break; 32.493 + case 0x0F: /*ASP get register*/ 32.494 + if (dsp->sb_type < SB16) break; 32.495 +// sb_add_data(0); 32.496 + sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); 32.497 +// pclog("ASP read reg %02X %02X\n", sb_data[0], sb_asp_regs[sb_data[0]]); 32.498 + break; 32.499 + case 0xF9: 32.500 + if (dsp->sb_type < SB16) break; 32.501 + if (dsp->sb_data[0] == 0x0e) sb_add_data(dsp, 0xff); 32.502 + else if (dsp->sb_data[0] == 0x0f) sb_add_data(dsp, 0x07); 32.503 + else if (dsp->sb_data[0] == 0x37) sb_add_data(dsp, 0x38); 32.504 + else sb_add_data(dsp, 0x00); 32.505 + case 0x04: 32.506 + case 0x05: 32.507 + break; 32.508 +// default: 32.509 +// fatal("Exec bad SB command %02X\n",sb_command); 32.510 + } 32.511 +} 32.512 + 32.513 +void sb_write(uint16_t a, uint8_t v, void *priv) 32.514 +{ 32.515 + sb_dsp_t *dsp = (sb_dsp_t *)priv; 32.516 + printf("sb_write : Write soundblaster %04X %02X %04X:%04X %02X\n",a,v,CS,pc,dsp->sb_command); 32.517 + switch (a&0xF) 32.518 + { 32.519 + case 6: /*Reset*/ 32.520 + if (!(v & 1) && (dsp->sbreset & 1)) 32.521 + { 32.522 + sb_dsp_reset(dsp); 32.523 + sb_add_data(dsp, 0xAA); 32.524 + } 32.525 + dsp->sbreset = v; 32.526 + return; 32.527 + case 0xC: /*Command/data write*/ 32.528 + if (dsp->sb_data_stat == -1) 32.529 + { 32.530 + dsp->sb_command = v; 32.531 +// if (sb_commands[v]==-1) 32.532 +// fatal("Bad SB command %02X\n",v); 32.533 + dsp->sb_data_stat++; 32.534 + } 32.535 + else 32.536 + dsp->sb_data[dsp->sb_data_stat++] = v; 32.537 + if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) 32.538 + { 32.539 + sb_exec_command(dsp); 32.540 + dsp->sb_data_stat = -1; 32.541 + } 32.542 + break; 32.543 + } 32.544 +} 32.545 + 32.546 +uint8_t sb_read(uint16_t a, void *priv) 32.547 +{ 32.548 + sb_dsp_t *dsp = (sb_dsp_t *)priv; 32.549 +// if (a==0x224) output=1; 32.550 + pclog("sb_read : Read soundblaster %04X %04X:%04X\n",a,CS,pc); 32.551 + switch (a & 0xf) 32.552 + { 32.553 + case 0xA: /*Read data*/ 32.554 + dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; 32.555 + if (dsp->sb_read_rp != dsp->sb_read_wp) 32.556 + { 32.557 + dsp->sb_read_rp++; 32.558 + dsp->sb_read_rp &= 0xFF; 32.559 + } 32.560 +// pclog("SB read %02X\n",sbreaddat); 32.561 + return dsp->sbreaddat; 32.562 + case 0xC: /*Write data ready*/ 32.563 + cycles -= 100; 32.564 + dsp->writebusy++; 32.565 + if (dsp->writebusy & 8) return 0xff; 32.566 + return 0x7f; 32.567 + case 0xE: /*Read data ready*/ 32.568 + picintc(1 << dsp->sb_irqnum); 32.569 + dsp->sb_irq8 = dsp->sb_irq16 = 0; 32.570 + return (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; 32.571 + case 0xF: /*16-bit ack*/ 32.572 + dsp->sb_irq16 = 0; 32.573 + if (!dsp->sb_irq8) picintc(1 << dsp->sb_irqnum); 32.574 + return 0xff; 32.575 + } 32.576 + return 0; 32.577 +} 32.578 + 32.579 +void sb_dsp_init(sb_dsp_t *dsp, int type) 32.580 +{ 32.581 + dsp->sb_type = type; 32.582 + 32.583 + dsp->sb_irqnum = 7; 32.584 + dsp->sb_8_dmanum = 1; 32.585 + 32.586 + sb_doreset(dsp); 32.587 + 32.588 + timer_add(pollsb, &dsp->sbcount, &dsp->sbenable, dsp); 32.589 + timer_add(sb_poll_i, &dsp->sb_count_i, &dsp->sb_enable_i, dsp); 32.590 +} 32.591 + 32.592 +void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr) 32.593 +{ 32.594 + pclog("sb_dsp_setaddr : %04X\n", addr); 32.595 + io_removehandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); 32.596 + io_removehandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); 32.597 + dsp->sb_addr = addr; 32.598 + if (dsp->sb_addr != 0) 32.599 + { 32.600 + io_sethandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); 32.601 + io_sethandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); 32.602 + } 32.603 +} 32.604 + 32.605 +void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo) 32.606 +{ 32.607 + dsp->stereo = stereo; 32.608 +} 32.609 + 32.610 +void pollsb(void *p) 32.611 +{ 32.612 + sb_dsp_t *dsp = (sb_dsp_t *)p; 32.613 + int tempi,ref; 32.614 + 32.615 + dsp->sbcount += dsp->sblatcho; 32.616 +// pclog("PollSB %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output); 32.617 + if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) 32.618 + { 32.619 + int data[2]; 32.620 +// pclog("Dopoll %i %02X %i\n", sb_8_length, sb_8_format, sblatcho); 32.621 + switch (dsp->sb_8_format) 32.622 + { 32.623 + case 0x00: /*Mono unsigned*/ 32.624 + data[0] = sb_8_read_dma(dsp); 32.625 + /*Needed to prevent clicking in Worms, which programs the DSP to 32.626 + auto-init DMA but programs the DMA controller to single cycle*/ 32.627 + if (data[0] == DMA_NODATA) 32.628 + break; 32.629 + dsp->sbdat = (data[0] ^ 0x80) << 8; 32.630 + if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) 32.631 + { 32.632 + if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; 32.633 + else dsp->sbdatr = dsp->sbdat; 32.634 + dsp->sbleftright = !dsp->sbleftright; 32.635 + } 32.636 + else 32.637 + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; 32.638 + dsp->sb_8_length--; 32.639 + break; 32.640 + case 0x10: /*Mono signed*/ 32.641 + data[0] = sb_8_read_dma(dsp); 32.642 + if (data[0] == DMA_NODATA) 32.643 + break; 32.644 + dsp->sbdat = data[0] << 8; 32.645 + if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) 32.646 + { 32.647 + if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; 32.648 + else dsp->sbdatr = dsp->sbdat; 32.649 + dsp->sbleftright = !dsp->sbleftright; 32.650 + } 32.651 + else 32.652 + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; 32.653 + dsp->sb_8_length--; 32.654 + break; 32.655 + case 0x20: /*Stereo unsigned*/ 32.656 + data[0] = sb_8_read_dma(dsp); 32.657 + data[1] = sb_8_read_dma(dsp); 32.658 + if (data[0] == DMA_NODATA || data[1] == DMA_NODATA) 32.659 + break; 32.660 + dsp->sbdatl = (data[0] ^ 0x80) << 8; 32.661 + dsp->sbdatr = (data[1] ^ 0x80) << 8; 32.662 + dsp->sb_8_length -= 2; 32.663 + break; 32.664 + case 0x30: /*Stereo signed*/ 32.665 + data[0] = sb_8_read_dma(dsp); 32.666 + data[1] = sb_8_read_dma(dsp); 32.667 + if (data[0] == DMA_NODATA || data[1] == DMA_NODATA) 32.668 + break; 32.669 + dsp->sbdatl = data[0] << 8; 32.670 + dsp->sbdatr = data[1] << 8; 32.671 + dsp->sb_8_length -= 2; 32.672 + break; 32.673 + 32.674 + case ADPCM_4: 32.675 + if (dsp->sbdacpos) tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep; 32.676 + else tempi = (dsp->sbdat2 >> 4) + dsp->sbstep; 32.677 + if (tempi < 0) tempi = 0; 32.678 + if (tempi > 63) tempi = 63; 32.679 + 32.680 + ref = dsp->sbref + scaleMap4[tempi]; 32.681 + if (ref > 0xff) dsp->sbref = 0xff; 32.682 + else if (ref < 0x00) dsp->sbref = 0x00; 32.683 + else dsp->sbref = ref; 32.684 + 32.685 + dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; 32.686 + 32.687 + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; 32.688 + 32.689 + dsp->sbdacpos++; 32.690 + if (dsp->sbdacpos >= 2) 32.691 + { 32.692 + dsp->sbdacpos = 0; 32.693 + dsp->sbdat2 = sb_8_read_dma(dsp); 32.694 + dsp->sb_8_length--; 32.695 + } 32.696 + 32.697 + if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) 32.698 + { 32.699 + if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; 32.700 + else dsp->sbdatr = dsp->sbdat; 32.701 + dsp->sbleftright = !dsp->sbleftright; 32.702 + } 32.703 + else 32.704 + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; 32.705 + break; 32.706 + 32.707 + case ADPCM_26: 32.708 + if (!dsp->sbdacpos) tempi = (dsp->sbdat2 >> 5) + dsp->sbstep; 32.709 + else if (dsp->sbdacpos == 1) tempi = ((dsp->sbdat2 >> 2) & 7) + dsp->sbstep; 32.710 + else tempi = ((dsp->sbdat2 << 1) & 7) + dsp->sbstep; 32.711 + 32.712 + if (tempi < 0) tempi = 0; 32.713 + if (tempi > 39) tempi = 39; 32.714 + 32.715 + ref = dsp->sbref + scaleMap26[tempi]; 32.716 + if (ref > 0xff) dsp->sbref = 0xff; 32.717 + else if (ref < 0x00) dsp->sbref = 0x00; 32.718 + else dsp->sbref = ref; 32.719 + dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff; 32.720 + 32.721 + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; 32.722 + 32.723 + dsp->sbdacpos++; 32.724 + if (dsp->sbdacpos>=3) 32.725 + { 32.726 + dsp->sbdacpos = 0; 32.727 + dsp->sbdat2 = sb_8_read_dma(dsp); 32.728 + dsp->sb_8_length--; 32.729 + } 32.730 + 32.731 + if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) 32.732 + { 32.733 + if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; 32.734 + else dsp->sbdatr = dsp->sbdat; 32.735 + dsp->sbleftright = !dsp->sbleftright; 32.736 + } 32.737 + else 32.738 + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; 32.739 + break; 32.740 + 32.741 + case ADPCM_2: 32.742 + tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep; 32.743 + if (tempi < 0) tempi = 0; 32.744 + if (tempi > 23) tempi = 23; 32.745 + 32.746 + ref = dsp->sbref + scaleMap2[tempi]; 32.747 + if (ref > 0xff) dsp->sbref = 0xff; 32.748 + else if (ref < 0x00) dsp->sbref = 0x00; 32.749 + else dsp->sbref = ref; 32.750 + dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff; 32.751 + 32.752 + dsp->sbdat = (dsp->sbref ^ 0x80) << 8; 32.753 + 32.754 + dsp->sbdacpos++; 32.755 + if (dsp->sbdacpos >= 4) 32.756 + { 32.757 + dsp->sbdacpos = 0; 32.758 + dsp->sbdat2 = sb_8_read_dma(dsp); 32.759 + } 32.760 + 32.761 + if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) 32.762 + { 32.763 + if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat; 32.764 + else dsp->sbdatr = dsp->sbdat; 32.765 + dsp->sbleftright = !dsp->sbleftright; 32.766 + } 32.767 + else 32.768 + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; 32.769 + break; 32.770 + 32.771 +// default: 32.772 + //fatal("Unrecognised SB 8-bit format %02X\n",sb_8_format); 32.773 + } 32.774 + 32.775 + if (dsp->sb_8_length < 0) 32.776 + { 32.777 + if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_autolen; 32.778 + else dsp->sb_8_enable = dsp->sbenable=0; 32.779 + sb_irq(dsp, 1); 32.780 + } 32.781 + } 32.782 + if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0 && dsp->sb_16_output) 32.783 + { 32.784 + switch (dsp->sb_16_format) 32.785 + { 32.786 + case 0x00: /*Mono unsigned*/ 32.787 + dsp->sbdatl = dsp->sbdatr = sb_16_read_dma(dsp) ^ 0x8000; 32.788 + dsp->sb_16_length--; 32.789 + break; 32.790 + case 0x10: /*Mono signed*/ 32.791 + dsp->sbdatl = dsp->sbdatr = sb_16_read_dma(dsp); 32.792 + dsp->sb_16_length--; 32.793 + break; 32.794 + case 0x20: /*Stereo unsigned*/ 32.795 + dsp->sbdatl = sb_16_read_dma(dsp) ^ 0x8000; 32.796 + dsp->sbdatr = sb_16_read_dma(dsp) ^ 0x8000; 32.797 + dsp->sb_16_length -= 2; 32.798 + break; 32.799 + case 0x30: /*Stereo signed*/ 32.800 + dsp->sbdatl = sb_16_read_dma(dsp); 32.801 + dsp->sbdatr = sb_16_read_dma(dsp); 32.802 + dsp->sb_16_length -= 2; 32.803 + break; 32.804 + 32.805 +// default: 32.806 +// fatal("Unrecognised SB 16-bit format %02X\n",sb_16_format); 32.807 + } 32.808 + 32.809 + if (dsp->sb_16_length < 0) 32.810 + { 32.811 +// pclog("16DMA over %i\n",sb_16_autoinit); 32.812 + if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen; 32.813 + else dsp->sb_16_enable = dsp->sbenable = 0; 32.814 + sb_irq(dsp, 0); 32.815 + } 32.816 + } 32.817 + if (dsp->sb_pausetime > -1) 32.818 + { 32.819 + dsp->sb_pausetime--; 32.820 + if (dsp->sb_pausetime < 0) 32.821 + { 32.822 + sb_irq(dsp, 1); 32.823 + dsp->sbenable = dsp->sb_8_enable; 32.824 + pclog("SB pause over\n"); 32.825 + } 32.826 + } 32.827 +} 32.828 + 32.829 +void sb_poll_i(void *p) 32.830 +{ 32.831 + sb_dsp_t *dsp = (sb_dsp_t *)p; 32.832 + 32.833 + dsp->sb_count_i += dsp->sblatchi; 32.834 +// pclog("PollSBi %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output); 32.835 + if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) 32.836 + { 32.837 + switch (dsp->sb_8_format) 32.838 + { 32.839 + case 0x00: /*Mono unsigned*/ 32.840 + sb_8_write_dma(dsp, 0x80); 32.841 + dsp->sb_8_length--; 32.842 + break; 32.843 + case 0x10: /*Mono signed*/ 32.844 + sb_8_write_dma(dsp, 0x00); 32.845 + dsp->sb_8_length--; 32.846 + break; 32.847 + case 0x20: /*Stereo unsigned*/ 32.848 + sb_8_write_dma(dsp, 0x80); 32.849 + sb_8_write_dma(dsp, 0x80); 32.850 + dsp->sb_8_length -= 2; 32.851 + break; 32.852 + case 0x30: /*Stereo signed*/ 32.853 + sb_8_write_dma(dsp, 0x00); 32.854 + sb_8_write_dma(dsp, 0x00); 32.855 + dsp->sb_8_length -= 2; 32.856 + break; 32.857 + 32.858 +// default: 32.859 +// fatal("Unrecognised SB 8-bit input format %02X\n",sb_8_format); 32.860 + } 32.861 + 32.862 + if (dsp->sb_8_length < 0) 32.863 + { 32.864 +// pclog("Input DMA over %i\n",sb_8_autoinit); 32.865 + if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_autolen; 32.866 + else dsp->sb_8_enable = dsp->sbenable = 0; 32.867 + sb_irq(dsp, 1); 32.868 + } 32.869 + } 32.870 + if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0 && !dsp->sb_16_output) 32.871 + { 32.872 + switch (dsp->sb_16_format) 32.873 + { 32.874 + case 0x00: /*Unsigned mono*/ 32.875 + sb_16_write_dma(dsp, 0x8000); 32.876 + dsp->sb_16_length--; 32.877 + break; 32.878 + case 0x10: /*Signed mono*/ 32.879 + sb_16_write_dma(dsp, 0); 32.880 + dsp->sb_16_length--; 32.881 + break; 32.882 + case 0x20: /*Unsigned stereo*/ 32.883 + sb_16_write_dma(dsp, 0x8000); 32.884 + sb_16_write_dma(dsp, 0x8000); 32.885 + dsp->sb_16_length -= 2; 32.886 + break; 32.887 + case 0x30: /*Signed stereo*/ 32.888 + sb_16_write_dma(dsp, 0); 32.889 + sb_16_write_dma(dsp, 0); 32.890 + dsp->sb_16_length -= 2; 32.891 + break; 32.892 + 32.893 +// default: 32.894 +// fatal("Unrecognised SB 16-bit input format %02X\n",sb_16_format); 32.895 + } 32.896 + 32.897 + if (dsp->sb_16_length < 0) 32.898 + { 32.899 +// pclog("16iDMA over %i\n",sb_16_autoinit); 32.900 + if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen; 32.901 + else dsp->sb_16_enable = dsp->sbenable = 0; 32.902 + sb_irq(dsp, 0); 32.903 + } 32.904 + } 32.905 +} 32.906 + 32.907 +void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r) 32.908 +{ 32.909 + *l = dsp->sbdatl; 32.910 + *r = dsp->sbdatr; 32.911 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/src/sound_sb_dsp.h Mon May 27 19:56:33 2013 +0100 33.3 @@ -0,0 +1,69 @@ 33.4 +typedef struct sb_dsp_t 33.5 +{ 33.6 + int sb_type; 33.7 + 33.8 + int sb_8_length, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output; 33.9 + int sb_8_dmanum; 33.10 + int sb_16_length, sb_16_format, sb_16_autoinit, sb_16_pause, sb_16_enable, sb_16_autolen, sb_16_output; 33.11 + int sb_pausetime; 33.12 + 33.13 + uint8_t sb_read_data[256]; 33.14 + int sb_read_wp, sb_read_rp; 33.15 + int sb_speaker; 33.16 + 33.17 + int sb_data_stat; 33.18 + 33.19 + int sb_irqnum; 33.20 + 33.21 + uint8_t sbe2; 33.22 + int sbe2count; 33.23 + 33.24 + uint8_t sb_data[8]; 33.25 + 33.26 + int sb_freq; 33.27 + 33.28 + int writebusy; /*Needed for Amnesia*/ 33.29 + 33.30 + int16_t sbdat; 33.31 + int sbdat2; 33.32 + int16_t sbdatl, sbdatr; 33.33 + 33.34 + uint8_t sbref; 33.35 + int8_t sbstep; 33.36 + 33.37 + int sbdacpos; 33.38 + 33.39 + int sbleftright; 33.40 + 33.41 + int sbreset; 33.42 + uint8_t sbreaddat; 33.43 + uint8_t sb_command; 33.44 + uint8_t sb_test; 33.45 + int sb_timei, sb_timeo; 33.46 + 33.47 + int sb_irq8, sb_irq16; 33.48 + 33.49 + uint8_t sb_asp_regs[256]; 33.50 + 33.51 + int sbenable, sb_enable_i; 33.52 + 33.53 + int sbcount, sb_count_i; 33.54 + 33.55 + int sblatcho, sblatchi; 33.56 + 33.57 + uint16_t sb_addr; 33.58 + 33.59 + int stereo; 33.60 +} sb_dsp_t; 33.61 + 33.62 +void sb_dsp_init(sb_dsp_t *dsp, int type); 33.63 + 33.64 +void sb_dsp_setirq(sb_dsp_t *dsp, int irq); 33.65 +void sb_dsp_setdma8(sb_dsp_t *dsp, int dma); 33.66 +void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr); 33.67 + 33.68 +void sb_dsp_speed_changed(sb_dsp_t *dsp); 33.69 + 33.70 +void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r); 33.71 + 33.72 +void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo);
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/src/sound_sn76489.c Mon May 27 19:56:33 2013 +0100 34.3 @@ -0,0 +1,198 @@ 34.4 +#include <stdlib.h> 34.5 +#include "ibm.h" 34.6 +#include "device.h" 34.7 +#include "io.h" 34.8 +#include "sound.h" 34.9 +#include "sound_sn76489.h" 34.10 + 34.11 +static float volslog[16]= 34.12 +{ 34.13 + 0.00000f,0.59715f,0.75180f,0.94650f, 34.14 + 1.19145f,1.50000f,1.88835f,2.37735f, 34.15 + 2.99295f,3.76785f,4.74345f,5.97165f, 34.16 + 7.51785f,9.46440f,11.9194f,15.0000f 34.17 +}; 34.18 + 34.19 +typedef struct sn76489_t 34.20 +{ 34.21 + int stat[4]; 34.22 + int latch[4], count[4]; 34.23 + int freqlo[4], freqhi[4]; 34.24 + int vol[4]; 34.25 + uint32_t shift; 34.26 + uint8_t noise; 34.27 + int lasttone; 34.28 + uint8_t firstdat; 34.29 + 34.30 + int16_t buffer[SOUNDBUFLEN]; 34.31 + int pos; 34.32 +} sn76489_t; 34.33 + 34.34 +#define PSGCONST ((3579545.0 / 64.0) / 48000.0) 34.35 + 34.36 +void sn76489_poll(void *p) 34.37 +{ 34.38 + sn76489_t *sn76489 = (sn76489_t *)p; 34.39 + int c; 34.40 + int16_t result = 0; 34.41 + 34.42 + if (sn76489->pos >= SOUNDBUFLEN) 34.43 + return; 34.44 + 34.45 + for (c = 1; c < 4; c++) 34.46 + { 34.47 + if (sn76489->latch[c] > 256) result += (int16_t) (volslog[sn76489->vol[c]] * sn76489->stat[c]); 34.48 + else result += (int16_t) (volslog[sn76489->vol[c]] * 127); 34.49 + 34.50 + sn76489->count[c] -= (256 * PSGCONST); 34.51 + while ((int)sn76489->count[c] < 0 && sn76489->latch[c]) 34.52 + { 34.53 + sn76489->count[c] += sn76489->latch[c]; 34.54 + sn76489->stat[c] = -sn76489->stat[c]; 34.55 + } 34.56 + } 34.57 + result += (((sn76489->shift & 1) ^ 1) * 127 * volslog[sn76489->vol[0]] * 2); 34.58 + 34.59 + sn76489->count[0] -= (512 * PSGCONST); 34.60 + while ((int)sn76489->count[0] < 0 && sn76489->latch[0]) 34.61 + { 34.62 + sn76489->count[0] += (sn76489->latch[0] * 2); 34.63 + if (!(sn76489->noise & 4)) 34.64 + { 34.65 + if (sn76489->shift & 1) 34.66 + sn76489->shift |= 0x8000; 34.67 + sn76489->shift >>= 1; 34.68 + } 34.69 + else 34.70 + { 34.71 + if ((sn76489->shift & 1) ^ ((sn76489->shift >> 1) & 1)) 34.72 + sn76489->shift |= 0x8000; 34.73 + sn76489->shift >>= 1; 34.74 + } 34.75 + } 34.76 + 34.77 + sn76489->buffer[sn76489->pos++] = result; 34.78 +} 34.79 + 34.80 +void sn76489_get_buffer(int16_t *buffer, int len, void *p) 34.81 +{ 34.82 + sn76489_t *sn76489 = (sn76489_t *)p; 34.83 + 34.84 + int c; 34.85 + 34.86 + for (c = 0; c < len * 2; c++) 34.87 + buffer[c] += sn76489->buffer[c >> 1]; 34.88 + 34.89 + sn76489->pos = 0; 34.90 +} 34.91 + 34.92 +void sn76489_write(uint16_t addr, uint8_t data, void *p) 34.93 +{ 34.94 + sn76489_t *sn76489 = (sn76489_t *)p; 34.95 + int freq; 34.96 + 34.97 + if (data & 0x80) 34.98 + { 34.99 + sn76489->firstdat = data; 34.100 + switch (data & 0x70) 34.101 + { 34.102 + case 0: 34.103 + sn76489->freqlo[3] = data & 0xf; 34.104 + sn76489->latch[3] = (sn76489->freqlo[3] | (sn76489->freqhi[3] << 4)) << 6; 34.105 + sn76489->lasttone = 3; 34.106 + break; 34.107 + case 0x10: 34.108 + data &= 0xf; 34.109 + sn76489->vol[3] = 0xf - data; 34.110 + break; 34.111 + case 0x20: 34.112 + sn76489->freqlo[2] = data & 0xf; 34.113 + sn76489->latch[2] = (sn76489->freqlo[2] | (sn76489->freqhi[2] << 4)) << 6; 34.114 + sn76489->lasttone = 2; 34.115 + break; 34.116 + case 0x30: 34.117 + data &= 0xf; 34.118 + sn76489->vol[2] = 0xf - data; 34.119 + break; 34.120 + case 0x40: 34.121 + sn76489->freqlo[1] = data & 0xf; 34.122 + sn76489->latch[1] = (sn76489->freqlo[1] | (sn76489->freqhi[1] << 4)) << 6; 34.123 + sn76489->lasttone = 1; 34.124 + break; 34.125 + case 0x50: 34.126 + data &= 0xf; 34.127 + sn76489->vol[1] = 0xf - data; 34.128 + break; 34.129 + case 0x60: 34.130 + sn76489->shift = 0x4000; 34.131 + if ((data & 3) != (sn76489->noise & 3)) sn76489->count[0] = 0; 34.132 + sn76489->noise = data & 0xf; 34.133 + if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1]; 34.134 + else sn76489->latch[0] = 0x400 << (data & 3); 34.135 + break; 34.136 + case 0x70: 34.137 + data &= 0xf; 34.138 + sn76489->vol[0] = 0xf - data; 34.139 + break; 34.140 + } 34.141 + } 34.142 + else 34.143 + { 34.144 + if ((sn76489->firstdat & 0x70) == 0x60) 34.145 + { 34.146 + sn76489->shift = 0x4000; 34.147 + if ((data & 3) != (sn76489->noise & 3)) 34.148 + sn76489->count[0] = 0; 34.149 + sn76489->noise = data & 0xf; 34.150 + if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1]; 34.151 + else sn76489->latch[0] = 0x400 << (data & 3); 34.152 + } 34.153 + else 34.154 + { 34.155 + sn76489->freqhi[sn76489->lasttone] = data & 0x3F; 34.156 + freq = sn76489->freqlo[sn76489->lasttone] | (sn76489->freqhi[sn76489->lasttone] << 4); 34.157 + if ((sn76489->noise & 3) == 3 && sn76489->lasttone == 1) 34.158 + sn76489->latch[0] = freq << 6; 34.159 + sn76489->latch[sn76489->lasttone] = freq << 6; 34.160 + } 34.161 + } 34.162 +} 34.163 + 34.164 +void *sn76489_init() 34.165 +{ 34.166 + sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); 34.167 + memset(sn76489, 0, sizeof(sn76489_t)); 34.168 + 34.169 + io_sethandler(0x00C0, 0x0001, NULL, NULL, NULL, sn76489_write, NULL, NULL, sn76489); 34.170 + 34.171 + sound_add_handler(sn76489_poll, sn76489_get_buffer, sn76489); 34.172 + 34.173 + sn76489->latch[0] = sn76489->latch[1] = sn76489->latch[2] = sn76489->latch[3] = 0x3FF << 6; 34.174 + sn76489->vol[0] = 0; 34.175 + sn76489->vol[1] = sn76489->vol[2] = sn76489->vol[3] = 8; 34.176 + sn76489->stat[0] = sn76489->stat[1] = sn76489->stat[2] = sn76489->stat[3] = 127; 34.177 + srand(time(NULL)); 34.178 + sn76489->count[0] = 0; 34.179 + sn76489->count[1] = (rand()&0x3FF)<<6; 34.180 + sn76489->count[2] = (rand()&0x3FF)<<6; 34.181 + sn76489->count[3] = (rand()&0x3FF)<<6; 34.182 + sn76489->noise = 3; 34.183 + sn76489->shift = 0x4000; 34.184 + 34.185 + return sn76489; 34.186 +} 34.187 + 34.188 +void sn76489_close(void *p) 34.189 +{ 34.190 + sn76489_t *sn76489 = (sn76489_t *)p; 34.191 + 34.192 + free(sn76489); 34.193 +} 34.194 + 34.195 +device_t sn76489_device = 34.196 +{ 34.197 + "TI SN74689 PSG", 34.198 + sn76489_init, 34.199 + sn76489_close, 34.200 + NULL 34.201 +};
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/src/sound_sn76489.h Mon May 27 19:56:33 2013 +0100 35.3 @@ -0,0 +1,1 @@ 35.4 +extern device_t sn76489_device;
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/src/sound_speaker.c Mon May 27 19:56:33 2013 +0100 36.3 @@ -0,0 +1,42 @@ 36.4 +#include "ibm.h" 36.5 +#include "sound.h" 36.6 +#include "sound_speaker.h" 36.7 + 36.8 +static int16_t speaker_buffer[SOUNDBUFLEN]; 36.9 + 36.10 +static int speaker_pos = 0; 36.11 + 36.12 +int wasgated = 0; 36.13 + 36.14 +static void speaker_poll(void *p) 36.15 +{ 36.16 + if (speaker_pos >= SOUNDBUFLEN) return; 36.17 + 36.18 +// printf("SPeaker - %i %i %i %02X\n",speakval,gated,speakon,pit.m[2]); 36.19 + if (gated) 36.20 + { 36.21 + if (!pit.m[2] || pit.m[2]==4) 36.22 + speaker_buffer[speaker_pos] = speakval; 36.23 + else 36.24 + speaker_buffer[speaker_pos] = speakon ? 0x1400 : 0; 36.25 + } 36.26 + else 36.27 + speaker_buffer[speaker_pos] = wasgated ? 0x1400 : 0; 36.28 + speaker_pos++; 36.29 + wasgated = 0; 36.30 +} 36.31 + 36.32 +static void speaker_get_buffer(int16_t *buffer, int len, void *p) 36.33 +{ 36.34 + int c; 36.35 + 36.36 + for (c = 0; c < len * 2; c++) 36.37 + buffer[c] += speaker_buffer[c >> 1]; 36.38 + 36.39 + speaker_pos = 0; 36.40 +} 36.41 + 36.42 +void speaker_init() 36.43 +{ 36.44 + sound_add_handler(speaker_poll, speaker_get_buffer, NULL); 36.45 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/src/sound_speaker.h Mon May 27 19:56:33 2013 +0100 37.3 @@ -0,0 +1,1 @@ 37.4 +void speaker_init();
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/src/sound_wss.c Mon May 27 19:56:33 2013 +0100 38.3 @@ -0,0 +1,307 @@ 38.4 +/*PCem v0.8 by Tom Walker 38.5 + 38.6 + Windows Sound System compatible CODEC emulation (AD1848)*/ 38.7 + 38.8 +#include <math.h> 38.9 +#include <stdlib.h> 38.10 +#include "ibm.h" 38.11 + 38.12 +#include "device.h" 38.13 +#include "dma.h" 38.14 +#include "io.h" 38.15 +#include "pic.h" 38.16 +#include "sound_opl.h" 38.17 +#include "sound_wss.h" 38.18 + 38.19 +/*530, 11, 3 - 530=23*/ 38.20 +/*530, 11, 1 - 530=22*/ 38.21 +/*530, 11, 0 - 530=21*/ 38.22 +/*530, 10, 1 - 530=1a*/ 38.23 +/*530, 9, 1 - 530=12*/ 38.24 +/*530, 7, 1 - 530=0a*/ 38.25 +/*604, 11, 1 - 530=22*/ 38.26 +/*e80, 11, 1 - 530=22*/ 38.27 +/*f40, 11, 1 - 530=22*/ 38.28 + 38.29 + 38.30 +static int wss_dma[4] = {0, 0, 1, 3}; 38.31 +static int wss_irq[8] = {5, 7, 9, 10, 11, 12, 14, 15}; /*W95 only uses 7-9, others may be wrong*/ 38.32 +static uint16_t wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; 38.33 + 38.34 +typedef struct wss_t 38.35 +{ 38.36 + uint8_t config; 38.37 + 38.38 + int index; 38.39 + uint8_t regs[16]; 38.40 + uint8_t status; 38.41 + 38.42 + int trd; 38.43 + int mce; 38.44 + 38.45 + int count; 38.46 + 38.47 + int16_t out_l, out_r; 38.48 + 38.49 + int interp_count, inc; 38.50 + 38.51 + int enable; 38.52 + 38.53 + int irq, dma; 38.54 + 38.55 + opl_t opl; 38.56 + 38.57 + int16_t opl_buffer[SOUNDBUFLEN * 2]; 38.58 + int16_t pcm_buffer[2][SOUNDBUFLEN]; 38.59 + 38.60 + int pos; 38.61 +} wss_t; 38.62 + 38.63 +static int wss_vols[64]; 38.64 + 38.65 +uint8_t wss_read(uint16_t addr, void *p) 38.66 +{ 38.67 + wss_t *wss = (wss_t *)p; 38.68 + uint8_t temp = 0xff; 38.69 +// pclog("wss_read - addr %04X %04X(%08X):%08X ", addr, CS, cs, pc); 38.70 + switch (addr & 7) 38.71 + { 38.72 + case 0: case 1: case 2: case 3: /*Version*/ 38.73 + temp = 4 | (wss->config & 0x40); 38.74 + break; 38.75 + 38.76 + case 4: /*Index*/ 38.77 + temp = wss->index | wss->trd | wss->mce; 38.78 + break; 38.79 + case 5: 38.80 + temp = wss->regs[wss->index]; 38.81 + break; 38.82 + case 6: 38.83 + temp = wss->status; 38.84 + break; 38.85 + } 38.86 +// pclog("return %02X\n", temp); 38.87 + return temp; 38.88 +} 38.89 + 38.90 +void wss_write(uint16_t addr, uint8_t val, void *p) 38.91 +{ 38.92 + wss_t *wss = (wss_t *)p; 38.93 + double freq; 38.94 + pclog("wss_write - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, pc); 38.95 + switch (addr & 7) 38.96 + { 38.97 + case 0: case 1: case 2: case 3: /*Config*/ 38.98 + wss->config = val; 38.99 + wss->dma = wss_dma[val & 3]; 38.100 + wss->irq = wss_irq[(val >> 3) & 7]; 38.101 + break; 38.102 + 38.103 + case 4: /*Index*/ 38.104 + wss->index = val & 0xf; 38.105 + wss->trd = val & 0x20; 38.106 + wss->mce = val & 0x40; 38.107 + break; 38.108 + case 5: 38.109 + switch (wss->index) 38.110 + { 38.111 + case 8: 38.112 + freq = (val & 1) ? 16934400 : 24576000; 38.113 + switch ((val >> 1) & 7) 38.114 + { 38.115 + case 0: freq /= 3072; break; 38.116 + case 1: freq /= 1536; break; 38.117 + case 2: freq /= 896; break; 38.118 + case 3: freq /= 768; break; 38.119 + case 4: freq /= 448; break; 38.120 + case 5: freq /= 384; break; 38.121 + case 6: freq /= 512; break; 38.122 + case 7: freq /= 2560; break; 38.123 + } 38.124 + wss->inc = (int)((freq * 65536) / 48000); 38.125 + break; 38.126 + 38.127 + case 9: 38.128 + if (!wss->enable) 38.129 + wss->interp_count = 0; 38.130 + 38.131 + wss->enable = ((val & 0x41) == 0x01); 38.132 + break; 38.133 + 38.134 + case 12: 38.135 + return; 38.136 + 38.137 + case 14: 38.138 + wss->count = wss->regs[15] | (val << 8); 38.139 + break; 38.140 + } 38.141 + wss->regs[wss->index] = val; 38.142 + break; 38.143 + case 6: 38.144 + wss->status &= 0xfe; 38.145 + break; 38.146 + } 38.147 +} 38.148 + 38.149 +static void wss_poll(void *p) 38.150 +{ 38.151 + wss_t *wss = (wss_t *)p; 38.152 + 38.153 + if (wss->pos >= SOUNDBUFLEN) 38.154 + return; 38.155 + 38.156 + opl3_poll(&wss->opl, &wss->opl_buffer[wss->pos * 2], &wss->opl_buffer[(wss->pos * 2) + 1]); 38.157 + 38.158 + if (wss->enable) 38.159 + { 38.160 + int32_t temp; 38.161 + 38.162 + if (wss->regs[6] & 0x80) 38.163 + wss->pcm_buffer[1][wss->pos] = 0; 38.164 + else 38.165 + wss->pcm_buffer[1][wss->pos] = (wss->out_l * wss_vols[wss->regs[6] & 0x3f]) >> 16; 38.166 + 38.167 + if (wss->regs[7] & 0x80) 38.168 + wss->pcm_buffer[0][wss->pos] = 0; 38.169 + else 38.170 + wss->pcm_buffer[0][wss->pos] = (wss->out_r * wss_vols[wss->regs[7] & 0x3f]) >> 16; 38.171 + 38.172 + wss->interp_count += wss->inc; 38.173 + if (wss->interp_count >= 0x10000) 38.174 + { 38.175 + wss->interp_count -= 0x10000; 38.176 + 38.177 + if (wss->count < 0) 38.178 + { 38.179 + wss->count = wss->regs[15] | (wss->regs[14] << 8); 38.180 + if (!(wss->status & 0x01)) 38.181 + { 38.182 + wss->status |= 0x01; 38.183 + if (wss->regs[0xa] & 2) 38.184 + picint(1 << wss->irq); 38.185 + } 38.186 + } 38.187 + 38.188 + switch (wss->regs[8] & 0x70) 38.189 + { 38.190 + case 0x00: /*Mono, 8-bit PCM*/ 38.191 + wss->out_l = wss->out_r = (dma_channel_read(wss->dma) ^ 0x80) * 256; 38.192 + break; 38.193 + case 0x10: /*Stereo, 8-bit PCM*/ 38.194 + wss->out_l = (dma_channel_read(wss->dma) ^ 0x80) * 256; 38.195 + wss->out_r = (dma_channel_read(wss->dma) ^ 0x80) * 256; 38.196 + break; 38.197 + 38.198 + case 0x40: /*Mono, 16-bit PCM*/ 38.199 + temp = dma_channel_read(wss->dma); 38.200 + wss->out_l = wss->out_r = dma_channel_read(wss->dma) | (temp << 8); 38.201 + break; 38.202 + case 0x50: /*Stereo, 16-bit PCM*/ 38.203 + temp = dma_channel_read(wss->dma); 38.204 + wss->out_l = dma_channel_read(wss->dma) | (temp << 8); 38.205 + temp = dma_channel_read(wss->dma); 38.206 + wss->out_r = dma_channel_read(wss->dma) | (temp << 8); 38.207 + break; 38.208 + } 38.209 + 38.210 + wss->count--; 38.211 + } 38.212 +// pclog("wss_poll : enable %X %X %X %X %X %X\n", wss->pcm_buffer[0][wss->pos], wss->pcm_buffer[1][wss->pos], wss->out_l[0], wss->out_r[0], wss->out_l[1], wss->out_r[1]); 38.213 + } 38.214 + else 38.215 + { 38.216 + wss->pcm_buffer[0][wss->pos] = wss->pcm_buffer[1][wss->pos] = 0; 38.217 +// pclog("wss_poll : not enable\n"); 38.218 + } 38.219 + wss->pos++; 38.220 +} 38.221 + 38.222 +static void wss_get_buffer(int16_t *buffer, int len, void *p) 38.223 +{ 38.224 + wss_t *wss = (wss_t *)p; 38.225 + 38.226 + int c; 38.227 + 38.228 + for (c = 0; c < len * 2; c++) 38.229 + { 38.230 + buffer[c] += wss->opl_buffer[c]; 38.231 + buffer[c] += (wss->pcm_buffer[c & 1][c >> 1] / 2); 38.232 + } 38.233 + 38.234 + wss->pos = 0; 38.235 +} 38.236 + 38.237 +void *wss_init() 38.238 +{ 38.239 + wss_t *wss = malloc(sizeof(wss_t)); 38.240 + int c; 38.241 + double attenuation; 38.242 + 38.243 + memset(wss, 0, sizeof(wss_t)); 38.244 + 38.245 + opl3_init(&wss->opl); 38.246 + 38.247 + pclog("wss_init - %i %i\n", sbtype, SND_WSS); 38.248 + 38.249 + wss->enable = 0; 38.250 + 38.251 + wss->status = 0xcc; 38.252 + wss->index = wss->trd = 0; 38.253 + wss->mce = 0x40; 38.254 + 38.255 + wss->regs[0] = wss->regs[1] = 0; 38.256 + wss->regs[2] = wss->regs[3] = 0x80; 38.257 + wss->regs[4] = wss->regs[5] = 0x80; 38.258 + wss->regs[6] = wss->regs[7] = 0x80; 38.259 + wss->regs[8] = 0; 38.260 + wss->regs[9] = 0x08; 38.261 + wss->regs[10] = wss->regs[11] = 0; 38.262 + wss->regs[12] = 0xa; 38.263 + wss->regs[13] = 0; 38.264 + wss->regs[14] = wss->regs[15] = 0; 38.265 + 38.266 + wss->out_l = 0; 38.267 + wss->out_r = 0; 38.268 + wss->interp_count = 0; 38.269 + 38.270 + wss->irq = 7; 38.271 + wss->dma = 3; 38.272 + 38.273 + io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &wss->opl); 38.274 + io_sethandler(0x0530, 0x0008, wss_read, NULL, NULL, wss_write, NULL, NULL, wss); 38.275 + 38.276 + sound_add_handler(wss_poll, wss_get_buffer, wss); 38.277 + 38.278 + for (c = 0; c < 64; c++) 38.279 + { 38.280 + attenuation = 0.0; 38.281 + if (c & 0x01) attenuation -= 1.5; 38.282 + if (c & 0x02) attenuation -= 3.0; 38.283 + if (c & 0x04) attenuation -= 6.0; 38.284 + if (c & 0x08) attenuation -= 12.0; 38.285 + if (c & 0x10) attenuation -= 24.0; 38.286 + if (c & 0x20) attenuation -= 48.0; 38.287 + 38.288 + attenuation = pow(10, attenuation / 10); 38.289 + 38.290 + wss_vols[c] = (int)(attenuation * 65536); 38.291 + pclog("wss_vols %i = %f %i\n", c, attenuation, wss_vols[c]); 38.292 + } 38.293 + 38.294 + return wss; 38.295 +} 38.296 + 38.297 +void wss_close(void *p) 38.298 +{ 38.299 + wss_t *wss = (wss_t *)p; 38.300 + 38.301 + free(wss); 38.302 +} 38.303 + 38.304 +device_t wss_device = 38.305 +{ 38.306 + "Windows Sound System", 38.307 + wss_init, 38.308 + wss_close, 38.309 + NULL 38.310 +};
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/src/sound_wss.h Mon May 27 19:56:33 2013 +0100 39.3 @@ -0,0 +1,1 @@ 39.4 +extern device_t wss_device;
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/src/timer.c Mon May 27 19:56:33 2013 +0100 40.3 @@ -0,0 +1,94 @@ 40.4 +#include "ibm.h" 40.5 + 40.6 +/*#include "sound_opl.h" 40.7 +#include "adlibgold.h" 40.8 +#include "sound_pas16.h" 40.9 +#include "sound_sb.h" 40.10 +#include "sound_sb_dsp.h" 40.11 +#include "sound_wss.h"*/ 40.12 +#include "timer.h" 40.13 + 40.14 +#define TIMERS_MAX 32 40.15 + 40.16 +int TIMER_USEC; 40.17 + 40.18 +static struct 40.19 +{ 40.20 + int present; 40.21 + void (*callback)(void *priv); 40.22 + void *priv; 40.23 + int *enable; 40.24 + int *count; 40.25 +} timers[TIMERS_MAX]; 40.26 + 40.27 +int timers_present = 0; 40.28 +int timer_one = 1; 40.29 + 40.30 +int timer_count = 0, timer_latch = 0; 40.31 + 40.32 +void timer_process() 40.33 +{ 40.34 + int c; 40.35 + 40.36 + /*Get actual elapsed time*/ 40.37 + timer_latch -= timer_count; 40.38 + 40.39 + for (c = 0; c < timers_present; c++) 40.40 + { 40.41 +// pclog("timer_process : %i enable %i %X\n", c, timers[c].enable, *timers[c].enable); 40.42 + if (*timers[c].enable) 40.43 + { 40.44 + *timers[c].count = *timers[c].count - (timer_latch << TIMER_SHIFT); 40.45 + if (*timers[c].count <= 0) 40.46 + { 40.47 + timers[c].callback(timers[c].priv); 40.48 + } 40.49 + } 40.50 + } 40.51 +} 40.52 + 40.53 +void timer_update_outstanding() 40.54 +{ 40.55 + int c; 40.56 + timer_latch = 0x7fffffff; 40.57 + for (c = 0; c < timers_present; c++) 40.58 + { 40.59 + if (*timers[c].enable && *timers[c].count < timer_latch) 40.60 + timer_latch = *timers[c].count; 40.61 + } 40.62 + if (spktime < timer_latch) timer_latch = spktime; 40.63 + //if (soundtime < timer_latch) timer_latch = soundtime; 40.64 + //if (gustime < timer_latch) timer_latch = gustime; 40.65 + //if (gustime2 < timer_latch) timer_latch = gustime2; 40.66 + //if (vidtime < timer_latch) timer_latch = vidtime; 40.67 + timer_count = timer_latch = (timer_latch + ((1 << TIMER_SHIFT) - 1)) >> TIMER_SHIFT; 40.68 +} 40.69 + 40.70 +void timer_reset() 40.71 +{ 40.72 + pclog("timer_reset\n"); 40.73 + timers_present = 0; 40.74 + timer_latch = timer_count = 0; 40.75 +// timer_process(); 40.76 +} 40.77 + 40.78 +int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv) 40.79 +{ 40.80 + if (timers_present < TIMERS_MAX) 40.81 + { 40.82 + pclog("timer_add : adding timer %i\n", timers_present); 40.83 + timers[timers_present].present = 1; 40.84 + timers[timers_present].callback = callback; 40.85 + timers[timers_present].priv = priv; 40.86 + timers[timers_present].count = count; 40.87 + timers[timers_present].enable = enable; 40.88 + timers_present++; 40.89 + return timers_present - 1; 40.90 + } 40.91 + return -1; 40.92 +} 40.93 + 40.94 +void timer_set_callback(int timer, void (*callback)(void *priv)) 40.95 +{ 40.96 + timers[timer].callback = callback; 40.97 +}
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/src/timer.h Mon May 27 19:56:33 2013 +0100 41.3 @@ -0,0 +1,25 @@ 41.4 +#define timer_clock(cycles) \ 41.5 + do \ 41.6 + { \ 41.7 + timer_count -= cycles; \ 41.8 + if (timer_count <= 0) \ 41.9 + { \ 41.10 + timer_process(); \ 41.11 + timer_update_outstanding(); \ 41.12 + } \ 41.13 + } while (0) 41.14 + 41.15 +void timer_process(); 41.16 +void timer_update_outstanding(); 41.17 +void timer_reset(); 41.18 +int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv); 41.19 +void timer_set_callback(int timer, void (*callback)(void *priv)); 41.20 + 41.21 +#define TIMER_ALWAYS_ENABLED &timer_one 41.22 + 41.23 +extern int timer_count; 41.24 +extern int timer_one; 41.25 + 41.26 +#define TIMER_SHIFT 6 41.27 + 41.28 +extern int TIMER_USEC;
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/src/um8669f.c Mon May 27 19:56:33 2013 +0100 42.3 @@ -0,0 +1,138 @@ 42.4 +/*um8669f : 42.5 + 42.6 + aa to 108 unlocks 42.7 + next 108 write is register select (Cx?) 42.8 + data read/write to 109 42.9 + 55 to 108 locks 42.10 + 42.11 + 42.12 + 42.13 + 42.14 +C0 42.15 +bit 3 = LPT1 enable 42.16 +bit 2 = COM2 enable 42.17 +bit 1 = COM1 enable 42.18 +bit 0 = FDC enable 42.19 + 42.20 +C1 42.21 +bits 7-6 = LPT1 mode : 11 = ECP/EPP, 01 = EPP, 10 = SPP 42.22 +bit 3 = clear when LPT1 = 278 42.23 + 42.24 +C3 42.25 +bits 7-6 = LPT1 DMA mode : 11 = ECP/EPP DMA1, 10 = ECP/EPP DMA3, 01 = EPP/SPP, 00 = ECP 42.26 +bits 5-4 = LPT1 addr : 10 = 278/IRQ5, 01 = 3BC/IRQ7, 00 = 378/IRQ7 42.27 + 42.28 +COM1 : 42.29 +3f8, IRQ4 - C1 = BF, C3 = 00 42.30 +2f8, IRQ3 - C1 = BF, C3 = 03 42.31 +3e8, IRQ4 - C1 = BD, C3 = 00 42.32 +2e8, IRQ3 - B1 = BD, C3 = 03 42.33 + 42.34 +COM2 : 42.35 +3f8, IRQ4 - C1 = BF, C3 = 0C 42.36 +2f8, IRQ3 - C1 = BF, C3 = 00 42.37 +3e8, IRQ4 - C1 = BB, C3 = 0C 42.38 +2e8, IRQ3 - C1 = BB, C3 = 00 42.39 + 42.40 + */ 42.41 + 42.42 +#include "ibm.h" 42.43 + 42.44 +#include "fdc.h" 42.45 +#include "io.h" 42.46 +#include "lpt.h" 42.47 +#include "mouse_serial.h" 42.48 +#include "serial.h" 42.49 +#include "um8669f.h" 42.50 + 42.51 +static int um8669f_locked; 42.52 +static int um8669f_curreg; 42.53 +static uint8_t um8669f_regs[256]; 42.54 + 42.55 +void um8669f_write(uint16_t port, uint8_t val, void *priv) 42.56 +{ 42.57 + int temp; 42.58 + if (um8669f_locked) 42.59 + { 42.60 + if (port == 0x108 && val == 0xaa) 42.61 + um8669f_locked = 0; 42.62 + } 42.63 + else 42.64 + { 42.65 + if (port == 0x108) 42.66 + { 42.67 + if (val == 0x55) 42.68 + um8669f_locked = 1; 42.69 + else 42.70 + um8669f_curreg = val; 42.71 + } 42.72 + else 42.73 + { 42.74 + um8669f_regs[um8669f_curreg] = val; 42.75 + pclog("um8669f_write : reg %02X = %02X\n", um8669f_curreg, val); 42.76 + 42.77 + fdc_remove(); 42.78 + if (um8669f_regs[0xc0] & 1) 42.79 + fdc_add(); 42.80 + 42.81 + serial1_remove(); 42.82 + if (um8669f_regs[0xc0] & 2) 42.83 + { 42.84 + temp = um8669f_regs[0xc3] & 1; /*might be & 2*/ 42.85 + if (!(um8669f_regs[0xc1] & 2)) 42.86 + temp |= 2; 42.87 + switch (temp) 42.88 + { 42.89 + case 0: serial1_init(0x3f8); break; 42.90 + case 1: serial1_init(0x2f8); break; 42.91 + case 2: serial1_init(0x3e8); break; 42.92 + case 3: serial1_init(0x2e8); break; 42.93 + } 42.94 + } 42.95 + 42.96 + serial2_remove(); 42.97 + if (um8669f_regs[0xc0] & 4) 42.98 + { 42.99 + temp = (um8669f_regs[0xc3] & 4) ? 0 : 1; /*might be & 8*/ 42.100 + if (!(um8669f_regs[0xc1] & 4)) 42.101 + temp |= 2; 42.102 + switch (temp) 42.103 + { 42.104 + case 0: serial2_init(0x3f8); break; 42.105 + case 1: serial2_init(0x2f8); break; 42.106 + case 2: serial2_init(0x3e8); break; 42.107 + case 3: serial2_init(0x2e8); break; 42.108 + } 42.109 + } 42.110 + 42.111 + mouse_serial_init(); 42.112 + 42.113 + lpt1_remove(); 42.114 + lpt2_remove(); 42.115 + temp = (um8669f_regs[0xc3] >> 4) & 3; 42.116 + switch (temp) 42.117 + { 42.118 + case 0: lpt1_init(0x378); break; 42.119 + case 1: lpt1_init(0x3bc); break; 42.120 + case 2: lpt1_init(0x278); break; 42.121 + } 42.122 + } 42.123 + } 42.124 +} 42.125 + 42.126 +uint8_t um8669f_read(uint16_t port, void *priv) 42.127 +{ 42.128 + if (um8669f_locked) 42.129 + return 0xff; 42.130 + 42.131 + if (port == 0x108) 42.132 + return um8669f_curreg; /*???*/ 42.133 + else 42.134 + return um8669f_regs[um8669f_curreg]; 42.135 +} 42.136 + 42.137 +void um8669f_init() 42.138 +{ 42.139 + io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, NULL); 42.140 + um8669f_locked = 1; 42.141 +}
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/src/um8669f.h Mon May 27 19:56:33 2013 +0100 43.3 @@ -0,0 +1,1 @@ 43.4 +extern void um8669f_init();
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/src/vid_ati18800.c Mon May 27 19:56:33 2013 +0100 44.3 @@ -0,0 +1,142 @@ 44.4 +/*ATI 18800 emulation (VGA Edge-16)*/ 44.5 +#include "ibm.h" 44.6 +#include "io.h" 44.7 +#include "video.h" 44.8 +#include "vid_ati_eeprom.h" 44.9 +#include "vid_svga.h" 44.10 + 44.11 +static uint8_t ati_regs[256]; 44.12 +static int ati_index; 44.13 + 44.14 +void ati18800_out(uint16_t addr, uint8_t val, void *priv) 44.15 +{ 44.16 + uint8_t old; 44.17 + 44.18 + pclog("ati18800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc); 44.19 + 44.20 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 44.21 + 44.22 + switch (addr) 44.23 + { 44.24 + case 0x1ce: 44.25 + ati_index = val; 44.26 + break; 44.27 + case 0x1cf: 44.28 + ati_regs[ati_index] = val; 44.29 + switch (ati_index) 44.30 + { 44.31 + case 0xb2: 44.32 + case 0xbe: 44.33 + if (ati_regs[0xbe] & 8) /*Read/write bank mode*/ 44.34 + { 44.35 + svgarbank = ((ati_regs[0xb2] >> 5) & 7) * 0x10000; 44.36 + svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000; 44.37 + } 44.38 + else /*Single bank mode*/ 44.39 + svgarbank = svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000; 44.40 + break; 44.41 + case 0xb3: 44.42 + ati_eeprom_write(val & 8, val & 2, val & 1); 44.43 + break; 44.44 + } 44.45 + break; 44.46 + 44.47 + case 0x3D4: 44.48 + crtcreg = val & 0x3f; 44.49 + return; 44.50 + case 0x3D5: 44.51 + if (crtcreg <= 7 && crtc[0x11] & 0x80) return; 44.52 + old=crtc[crtcreg]; 44.53 + crtc[crtcreg]=val; 44.54 + if (old!=val) 44.55 + { 44.56 + if (crtcreg<0xE || crtcreg>0x10) 44.57 + { 44.58 + fullchange=changeframecount; 44.59 + svga_recalctimings(); 44.60 + } 44.61 + } 44.62 + break; 44.63 + } 44.64 + svga_out(addr, val, NULL); 44.65 +} 44.66 + 44.67 +uint8_t ati18800_in(uint16_t addr, void *priv) 44.68 +{ 44.69 + uint8_t temp; 44.70 + 44.71 + if (addr != 0x3da) pclog("ati18800_in : %04X ", addr); 44.72 + 44.73 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 44.74 + 44.75 + switch (addr) 44.76 + { 44.77 + case 0x1ce: 44.78 + temp = ati_index; 44.79 + break; 44.80 + case 0x1cf: 44.81 + switch (ati_index) 44.82 + { 44.83 + case 0xb7: 44.84 + temp = ati_regs[ati_index] & ~8; 44.85 + if (ati_eeprom_read()) 44.86 + temp |= 8; 44.87 + break; 44.88 + 44.89 + default: 44.90 + temp = ati_regs[ati_index]; 44.91 + break; 44.92 + } 44.93 + break; 44.94 + 44.95 + case 0x3D4: 44.96 + temp = crtcreg; 44.97 + break; 44.98 + case 0x3D5: 44.99 + temp = crtc[crtcreg]; 44.100 + break; 44.101 + default: 44.102 + temp = svga_in(addr, NULL); 44.103 + break; 44.104 + } 44.105 + if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); 44.106 + return temp; 44.107 +} 44.108 + 44.109 +int ati18800_init() 44.110 +{ 44.111 + svga_recalctimings_ex = NULL; 44.112 + svga_vram_limit = 1 << 19; /*512kb*/ 44.113 + vrammask = 0x7ffff; 44.114 + svgawbank = svgarbank = 0; 44.115 + bpp = 8; 44.116 + svga_miscout = 1; 44.117 + 44.118 + io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, NULL); 44.119 + 44.120 + ati_eeprom_load("ati18800.nvr", 0); 44.121 + 44.122 + return svga_init(); 44.123 +} 44.124 + 44.125 +GFXCARD vid_ati18800 = 44.126 +{ 44.127 + ati18800_init, 44.128 + /*IO at 3Cx/3Dx*/ 44.129 + ati18800_out, 44.130 + ati18800_in, 44.131 + /*IO at 3Ax/3Bx*/ 44.132 + video_out_null, 44.133 + video_in_null, 44.134 + 44.135 + svga_poll, 44.136 + svga_recalctimings, 44.137 + 44.138 + svga_write, 44.139 + video_write_null, 44.140 + video_write_null, 44.141 + 44.142 + svga_read, 44.143 + video_read_null, 44.144 + video_read_null 44.145 +};
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/src/vid_ati28800.c Mon May 27 19:56:33 2013 +0100 45.3 @@ -0,0 +1,161 @@ 45.4 +/*ATI 28800 emulation (VGA Charger)*/ 45.5 +#include "ibm.h" 45.6 +#include "io.h" 45.7 +#include "video.h" 45.8 +#include "vid_ati_eeprom.h" 45.9 +#include "vid_svga.h" 45.10 +#include "vid_svga_render.h" 45.11 + 45.12 +static uint8_t ati_regs[256]; 45.13 +static int ati_index; 45.14 + 45.15 +void ati28800_out(uint16_t addr, uint8_t val, void *priv) 45.16 +{ 45.17 + uint8_t old; 45.18 + 45.19 + pclog("ati28800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc); 45.20 + 45.21 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 45.22 + 45.23 + switch (addr) 45.24 + { 45.25 + case 0x1ce: 45.26 + ati_index = val; 45.27 + break; 45.28 + case 0x1cf: 45.29 + ati_regs[ati_index] = val; 45.30 + switch (ati_index) 45.31 + { 45.32 + case 0xb2: 45.33 + case 0xbe: 45.34 + if (ati_regs[0xbe] & 8) /*Read/write bank mode*/ 45.35 + { 45.36 + svgarbank = ((ati_regs[0xb2] >> 5) & 7) * 0x10000; 45.37 + svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000; 45.38 + } 45.39 + else /*Single bank mode*/ 45.40 + svgarbank = svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000; 45.41 + break; 45.42 + case 0xb3: 45.43 + ati_eeprom_write(val & 8, val & 2, val & 1); 45.44 + break; 45.45 + } 45.46 + break; 45.47 + 45.48 + case 0x3D4: 45.49 + crtcreg = val & 0x3f; 45.50 + return; 45.51 + case 0x3D5: 45.52 + if (crtcreg <= 7 && crtc[0x11] & 0x80) return; 45.53 + old=crtc[crtcreg]; 45.54 + crtc[crtcreg]=val; 45.55 + if (old!=val) 45.56 + { 45.57 + if (crtcreg<0xE || crtcreg>0x10) 45.58 + { 45.59 + fullchange=changeframecount; 45.60 + svga_recalctimings(); 45.61 + } 45.62 + } 45.63 + break; 45.64 + } 45.65 + svga_out(addr, val, NULL); 45.66 +} 45.67 + 45.68 +uint8_t ati28800_in(uint16_t addr, void *priv) 45.69 +{ 45.70 + uint8_t temp; 45.71 + 45.72 + if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); 45.73 + 45.74 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 45.75 + 45.76 + switch (addr) 45.77 + { 45.78 + case 0x1ce: 45.79 + temp = ati_index; 45.80 + break; 45.81 + case 0x1cf: 45.82 + switch (ati_index) 45.83 + { 45.84 + case 0xb7: 45.85 + temp = ati_regs[ati_index] & ~8; 45.86 + if (ati_eeprom_read()) 45.87 + temp |= 8; 45.88 + break; 45.89 + 45.90 + default: 45.91 + temp = ati_regs[ati_index]; 45.92 + break; 45.93 + } 45.94 + break; 45.95 + 45.96 + case 0x3c2: 45.97 + if ((vgapal[0].r + vgapal[0].g + vgapal[0].b) >= 0x50) 45.98 + temp = 0; 45.99 + else 45.100 + temp = 0x10; 45.101 + break; 45.102 + case 0x3D4: 45.103 + temp = crtcreg; 45.104 + break; 45.105 + case 0x3D5: 45.106 + temp = crtc[crtcreg]; 45.107 + break; 45.108 + default: 45.109 + temp = svga_in(addr, NULL); 45.110 + break; 45.111 + } 45.112 + if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); 45.113 + return temp; 45.114 +} 45.115 + 45.116 +void ati28800_recalctimings() 45.117 +{ 45.118 + pclog("ati28800_recalctimings\n"); 45.119 + if (!scrblank && (ati_regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ 45.120 + { 45.121 + pclog("8bpp_highres\n"); 45.122 + svga_render = svga_render_8bpp_highres; 45.123 + svga_rowoffset <<= 1; 45.124 + svga_ma <<= 1; 45.125 + } 45.126 +} 45.127 + 45.128 +int ati28800_init() 45.129 +{ 45.130 + svga_recalctimings_ex = ati28800_recalctimings; 45.131 + svga_vram_limit = 1 << 19; /*512kb*/ 45.132 + vrammask = 0x7ffff; 45.133 + svgawbank = svgarbank = 0; 45.134 + bpp = 8; 45.135 + svga_miscout = 1; 45.136 + 45.137 + io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, NULL); 45.138 + 45.139 + ati_eeprom_load("ati28800.nvr", 0); 45.140 + 45.141 + return svga_init(); 45.142 +} 45.143 + 45.144 +GFXCARD vid_ati28800 = 45.145 +{ 45.146 + ati28800_init, 45.147 + /*IO at 3Cx/3Dx*/ 45.148 + ati28800_out, 45.149 + ati28800_in, 45.150 + /*IO at 3Ax/3Bx*/ 45.151 + video_out_null, 45.152 + video_in_null, 45.153 + 45.154 + svga_poll, 45.155 + svga_recalctimings, 45.156 + 45.157 + svga_write, 45.158 + video_write_null, 45.159 + video_write_null, 45.160 + 45.161 + svga_read, 45.162 + video_read_null, 45.163 + video_read_null 45.164 +};
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/src/vid_ati68860_ramdac.c Mon May 27 19:56:33 2013 +0100 46.3 @@ -0,0 +1,83 @@ 46.4 +/*ATI 68860 RAMDAC emulation (for Mach64)*/ 46.5 +/* 46.6 +ATI 68860/68880 Truecolor DACs: 46.7 +REG08 (R/W): 46.8 +bit 0-? Always 2 ?? 46.9 + 46.10 +REG0A (R/W): 46.11 +bit 0-? Always 1Dh ?? 46.12 + 46.13 +REG0B (R/W): (GMR ?) 46.14 +bit 0-7 Mode. 82h: 4bpp, 83h: 8bpp, A0h: 15bpp, A1h: 16bpp, C0h: 24bpp, 46.15 + E3h: 32bpp (80h for VGA modes ?) 46.16 + 46.17 +REG0C (R/W): Device Setup Register A 46.18 +bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT 46.19 + 2-3 Depends on Video memory (= VRAM width ?) . 1: Less than 1Mb, 2: 1Mb, 46.20 + 3: > 1Mb 46.21 + 5-6 Always set ? 46.22 + 7 If set can remove "snow" in some cases (A860_Delay_L ?) ?? 46.23 +*/ 46.24 +#include "ibm.h" 46.25 +#include "video.h" 46.26 +#include "vid_svga.h" 46.27 +#include "vid_ati68860_ramdac.h" 46.28 + 46.29 +static uint8_t ramdac_regs[16]; 46.30 +void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv) 46.31 +{ 46.32 +// pclog("ati68860_out : addr %04X val %02X %04X:%04X\n", addr, val, CS,pc); 46.33 + switch (addr) 46.34 + { 46.35 + case 0: 46.36 + svga_out(0x3c8, val, NULL); 46.37 + break; 46.38 + case 1: 46.39 + svga_out(0x3c9, val, NULL); 46.40 + break; 46.41 + case 2: 46.42 + svga_out(0x3c6, val, NULL); 46.43 + break; 46.44 + case 3: 46.45 + svga_out(0x3c7, val, NULL); 46.46 + break; 46.47 + default: 46.48 + ramdac_regs[addr & 0xf] = val; 46.49 + break; 46.50 + } 46.51 +} 46.52 + 46.53 +uint8_t ati68860_ramdac_in(uint16_t addr, void *priv) 46.54 +{ 46.55 + uint8_t ret = 0; 46.56 + switch (addr) 46.57 + { 46.58 + case 0: 46.59 + ret = svga_in(0x3c8, NULL); 46.60 + break; 46.61 + case 1: 46.62 + ret = svga_in(0x3c9, NULL); 46.63 + break; 46.64 + case 2: 46.65 + ret = svga_in(0x3c6, NULL); 46.66 + break; 46.67 + case 3: 46.68 + ret = svga_in(0x3c7, NULL); 46.69 + break; 46.70 + case 4: case 8: 46.71 + ret = 2; 46.72 + break; 46.73 + case 6: case 0xa: 46.74 + ret = 0x1d; 46.75 + break; 46.76 + case 0xf: 46.77 + ret = 0xd0; 46.78 + break; 46.79 + 46.80 + default: 46.81 + ret = ramdac_regs[addr & 0xf]; 46.82 + break; 46.83 + } 46.84 +// pclog("ati68860_in : addr %04X ret %02X %04X:%04X\n", addr, ret, CS,pc); 46.85 + return ret; 46.86 +}
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/src/vid_ati68860_ramdac.h Mon May 27 19:56:33 2013 +0100 47.3 @@ -0,0 +1,2 @@ 47.4 +void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv); 47.5 +uint8_t ati68860_ramdac_in(uint16_t addr, void *priv);
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/src/vid_ati_eeprom.c Mon May 27 19:56:33 2013 +0100 48.3 @@ -0,0 +1,229 @@ 48.4 +#include "ibm.h" 48.5 +#include "vid_ati_eeprom.h" 48.6 + 48.7 +static uint16_t eeprom[256]; 48.8 +enum 48.9 +{ 48.10 + EEPROM_IDLE, 48.11 + EEPROM_WAIT, 48.12 + EEPROM_OPCODE, 48.13 + EEPROM_INPUT, 48.14 + EEPROM_OUTPUT 48.15 +}; 48.16 + 48.17 +enum 48.18 +{ 48.19 + EEPROM_OP_EW = 4, 48.20 + EEPROM_OP_WRITE = 5, 48.21 + EEPROM_OP_READ = 6, 48.22 + EEPROM_OP_ERASE = 7, 48.23 + 48.24 + EEPROM_OP_WRALMAIN = -1 48.25 +}; 48.26 + 48.27 +enum 48.28 +{ 48.29 + EEPROM_OP_EWDS = 0, 48.30 + EEPROM_OP_WRAL = 1, 48.31 + EEPROM_OP_ERAL = 2, 48.32 + EEPROM_OP_EWEN = 3 48.33 +}; 48.34 + 48.35 +static int oldclk, oldena; 48.36 +static int eeprom_opcode, eeprom_state, eeprom_count, eeprom_out; 48.37 +static int eeprom_wp; 48.38 +static uint32_t eeprom_dat; 48.39 +static int eeprom_type; 48.40 + 48.41 +static char eeprom_fn[256] = {0}; 48.42 + 48.43 +void ati_eeprom_load(char *fn, int type) 48.44 +{ 48.45 + FILE *f; 48.46 + eeprom_type = type; 48.47 + strcpy(eeprom_fn, fn); 48.48 + f = romfopen(eeprom_fn, "rb"); 48.49 + if (!f) 48.50 + { 48.51 + memset(eeprom, 0, type ? 512 : 128); 48.52 + return; 48.53 + } 48.54 + fread(eeprom, 1, type ? 512 : 128, f); 48.55 + fclose(f); 48.56 +} 48.57 + 48.58 +void ati_eeprom_save() 48.59 +{ 48.60 + FILE *f = romfopen(eeprom_fn, "wb"); 48.61 + if (!f) return; 48.62 + fwrite(eeprom, 1, eeprom_type ? 512 : 128, f); 48.63 + fclose(f); 48.64 +} 48.65 + 48.66 +void ati_eeprom_write(int ena, int clk, int dat) 48.67 +{ 48.68 + int c; 48.69 + pclog("EEPROM write %i %i %i\n", ena, clk, dat); 48.70 + if (!ena) 48.71 + { 48.72 + eeprom_out = 1; 48.73 + } 48.74 + if (clk && !oldclk) 48.75 + { 48.76 + if (ena && !oldena) 48.77 + { 48.78 + eeprom_state = EEPROM_WAIT; 48.79 + eeprom_opcode = 0; 48.80 + eeprom_count = 3; 48.81 + eeprom_out = 1; 48.82 + } 48.83 + else if (ena) 48.84 + { 48.85 + pclog("EEPROM receive %i %i %i\n", ena, clk, dat); 48.86 + switch (eeprom_state) 48.87 + { 48.88 + case EEPROM_WAIT: 48.89 + if (!dat) 48.90 + break; 48.91 + eeprom_state = EEPROM_OPCODE; 48.92 + /* fall through */ 48.93 + case EEPROM_OPCODE: 48.94 + eeprom_opcode = (eeprom_opcode << 1) | (dat ? 1 : 0); 48.95 + eeprom_count--; 48.96 + if (!eeprom_count) 48.97 + { 48.98 + pclog("EEPROM opcode - %i\n", eeprom_opcode); 48.99 + switch (eeprom_opcode) 48.100 + { 48.101 + case EEPROM_OP_WRITE: 48.102 + eeprom_count = eeprom_type ? 24 : 22; 48.103 + eeprom_state = EEPROM_INPUT; 48.104 + eeprom_dat = 0; 48.105 + break; 48.106 + case EEPROM_OP_READ: 48.107 + eeprom_count = eeprom_type ? 8 : 6; 48.108 + eeprom_state = EEPROM_INPUT; 48.109 + eeprom_dat = 0; 48.110 + break; 48.111 + case EEPROM_OP_EW: 48.112 + eeprom_count = 2; 48.113 + eeprom_state = EEPROM_INPUT; 48.114 + eeprom_dat = 0; 48.115 + break; 48.116 + case EEPROM_OP_ERASE: 48.117 + eeprom_count = eeprom_type ? 8 : 6; 48.118 + eeprom_state = EEPROM_INPUT; 48.119 + eeprom_dat = 0; 48.120 + break; 48.121 + } 48.122 + } 48.123 + break; 48.124 + 48.125 + case EEPROM_INPUT: 48.126 + eeprom_dat = (eeprom_dat << 1) | (dat ? 1 : 0); 48.127 + eeprom_count--; 48.128 + if (!eeprom_count) 48.129 + { 48.130 + pclog("EEPROM dat - %02X\n", eeprom_dat); 48.131 + switch (eeprom_opcode) 48.132 + { 48.133 + case EEPROM_OP_WRITE: 48.134 + pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom_dat >> 16) & (eeprom_type ? 255 : 63), eeprom_dat & 0xffff); 48.135 + if (!eeprom_wp) 48.136 + { 48.137 + eeprom[(eeprom_dat >> 16) & (eeprom_type ? 255 : 63)] = eeprom_dat & 0xffff; 48.138 + ati_eeprom_save(); 48.139 + } 48.140 + eeprom_state = EEPROM_IDLE; 48.141 + eeprom_out = 1; 48.142 + break; 48.143 + 48.144 + case EEPROM_OP_READ: 48.145 + eeprom_count = 17; 48.146 + eeprom_state = EEPROM_OUTPUT; 48.147 + eeprom_dat = eeprom[eeprom_dat]; 48.148 + pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom_dat); 48.149 + break; 48.150 + case EEPROM_OP_EW: 48.151 + pclog("EEPROM_OP_EW %i\n", eeprom_dat); 48.152 + switch (eeprom_dat) 48.153 + { 48.154 + case EEPROM_OP_EWDS: 48.155 + eeprom_wp = 1; 48.156 + break; 48.157 + case EEPROM_OP_WRAL: 48.158 + opcode = EEPROM_OP_WRALMAIN; 48.159 + eeprom_count = 20; 48.160 + break; 48.161 + case EEPROM_OP_ERAL: 48.162 + if (!eeprom_wp) 48.163 + { 48.164 + memset(eeprom, 0xff, 128); 48.165 + ati_eeprom_save(); 48.166 + } 48.167 + break; 48.168 + case EEPROM_OP_EWEN: 48.169 + eeprom_wp = 0; 48.170 + break; 48.171 + } 48.172 + eeprom_state = EEPROM_IDLE; 48.173 + eeprom_out = 1; 48.174 + break; 48.175 + 48.176 + case EEPROM_OP_ERASE: 48.177 + pclog("EEPROM_OP_ERASE %i\n", eeprom_dat); 48.178 + if (!eeprom_wp) 48.179 + { 48.180 + eeprom[eeprom_dat] = 0xffff; 48.181 + ati_eeprom_save(); 48.182 + } 48.183 + eeprom_state = EEPROM_IDLE; 48.184 + eeprom_out = 1; 48.185 + break; 48.186 + 48.187 + case EEPROM_OP_WRALMAIN: 48.188 + pclog("EEPROM_OP_WRAL %04X\n", eeprom_dat); 48.189 + if (!eeprom_wp) 48.190 + { 48.191 + for (c = 0; c < 256; c++) 48.192 + eeprom[c] = eeprom_dat; 48.193 + ati_eeprom_save(); 48.194 + } 48.195 + eeprom_state = EEPROM_IDLE; 48.196 + eeprom_out = 1; 48.197 + break; 48.198 + } 48.199 + } 48.200 + break; 48.201 + } 48.202 + } 48.203 + oldena = ena; 48.204 + } 48.205 + else if (!clk && oldclk) 48.206 + { 48.207 + if (ena) 48.208 + { 48.209 + switch (eeprom_state) 48.210 + { 48.211 + case EEPROM_OUTPUT: 48.212 + eeprom_out = (eeprom_dat & 0x10000) ? 1 : 0; 48.213 + eeprom_dat <<= 1; 48.214 + pclog("EEPROM_OUTPUT - data %i\n", eeprom_out); 48.215 + eeprom_count--; 48.216 + if (!eeprom_count) 48.217 + { 48.218 + pclog("EEPROM_OUTPUT complete\n"); 48.219 + eeprom_state = EEPROM_IDLE; 48.220 + } 48.221 + break; 48.222 + } 48.223 + } 48.224 + } 48.225 + oldclk = clk; 48.226 +} 48.227 + 48.228 +int ati_eeprom_read() 48.229 +{ 48.230 + return eeprom_out; 48.231 +} 48.232 +
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/src/vid_ati_eeprom.h Mon May 27 19:56:33 2013 +0100 49.3 @@ -0,0 +1,3 @@ 49.4 +void ati_eeprom_load(char *fn, int type); 49.5 +void ati_eeprom_write(int ena, int clk, int dat); 49.6 +int ati_eeprom_read();
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/src/vid_ati_mach64.c Mon May 27 19:56:33 2013 +0100 50.3 @@ -0,0 +1,1767 @@ 50.4 +/*ATI Mach64 emulation*/ 50.5 +#include "ibm.h" 50.6 +#include "io.h" 50.7 +#include "mem.h" 50.8 +#include "video.h" 50.9 +#include "vid_svga.h" 50.10 +#include "vid_ati68860_ramdac.h" 50.11 +#include "vid_ati_eeprom.h" 50.12 +#include "vid_ics2595.h" 50.13 +#include "vid_svga_render.h" 50.14 + 50.15 +//#define MACH64_DEBUG 50.16 +static int mach64_bank_r[2] = {0, 0}; 50.17 +static int mach64_bank_w[2] = {0, 0}; 50.18 +void mach64_write(uint32_t addr, uint8_t val, void *priv); 50.19 +uint8_t mach64_read(uint32_t addr, void *priv); 50.20 + 50.21 +static uint8_t ati_regs[256]; 50.22 +static int ati_index; 50.23 + 50.24 +struct 50.25 +{ 50.26 + uint32_t config_cntl; 50.27 + 50.28 + uint32_t context_load_cntl; 50.29 + uint32_t context_mask; 50.30 + 50.31 + uint32_t crtc_gen_cntl; 50.32 + uint8_t crtc_int_cntl; 50.33 + uint32_t crtc_h_total_disp; 50.34 + uint32_t crtc_v_sync_strt_wid; 50.35 + uint32_t crtc_v_total_disp; 50.36 + uint32_t crtc_off_pitch; 50.37 + 50.38 + uint32_t clock_cntl; 50.39 + 50.40 + uint32_t cur_horz_vert_off; 50.41 + uint32_t cur_horz_vert_posn; 50.42 + uint32_t cur_offset; 50.43 + 50.44 + uint32_t dac_cntl; 50.45 + 50.46 + uint32_t dp_bkgd_clr; 50.47 + uint32_t dp_frgd_clr; 50.48 + uint32_t dp_mix; 50.49 + uint32_t dp_pix_width; 50.50 + uint32_t dp_src; 50.51 + 50.52 + uint32_t dst_bres_lnth; 50.53 + uint32_t dst_bres_dec; 50.54 + uint32_t dst_bres_err; 50.55 + uint32_t dst_bres_inc; 50.56 + 50.57 + uint32_t dst_cntl; 50.58 + uint32_t dst_height_width; 50.59 + uint32_t dst_off_pitch; 50.60 + uint32_t dst_y_x; 50.61 + 50.62 + uint32_t gen_test_cntl; 50.63 + 50.64 + uint32_t gui_traj_cntl; 50.65 + 50.66 + uint32_t mem_cntl; 50.67 + 50.68 + uint32_t pat_cntl; 50.69 + uint32_t pat_reg0, pat_reg1; 50.70 + 50.71 + uint32_t sc_left_right, sc_top_bottom; 50.72 + 50.73 + uint32_t scratch_reg0, scratch_reg1; 50.74 + 50.75 + uint32_t src_cntl; 50.76 + uint32_t src_off_pitch; 50.77 + uint32_t src_y_x; 50.78 + 50.79 + struct 50.80 + { 50.81 + int op; 50.82 + 50.83 + int dst_x, dst_y; 50.84 + int dst_x_start; 50.85 + int src_x, src_y; 50.86 + int src_x_start; 50.87 + int xinc, yinc; 50.88 + int x_count, y_count; 50.89 + uint32_t src_offset, src_pitch; 50.90 + uint32_t dst_offset, dst_pitch; 50.91 + int mix_bg, mix_fg; 50.92 + int source_bg, source_fg, source_mix; 50.93 + int source_host; 50.94 + int dst_width, dst_height; 50.95 + int busy; 50.96 + int pattern[8][8]; 50.97 + int sc_left, sc_right, sc_top, sc_bottom; 50.98 + int dst_pix_width, src_pix_width, host_pix_width; 50.99 + int dst_size, src_size; 50.100 + 50.101 + uint32_t dp_bkgd_clr; 50.102 + uint32_t dp_frgd_clr; 50.103 + 50.104 + int err; 50.105 + } accel; 50.106 +} mach64; 50.107 + 50.108 +enum 50.109 +{ 50.110 + SRC_BG = 0, 50.111 + SRC_FG = 1, 50.112 + SRC_HOST = 2, 50.113 + SRC_BLITSRC = 3, 50.114 + SRC_PAT = 4 50.115 +}; 50.116 + 50.117 +enum 50.118 +{ 50.119 + MONO_SRC_1 = 0, 50.120 + MONO_SRC_PAT = 1, 50.121 + MONO_SRC_HOST = 2, 50.122 + MONO_SRC_BLITSRC = 3 50.123 +}; 50.124 + 50.125 +enum 50.126 +{ 50.127 + BPP_1 = 0, 50.128 + BPP_4 = 1, 50.129 + BPP_8 = 2, 50.130 + BPP_15 = 3, 50.131 + BPP_16 = 4, 50.132 + BPP_32 = 5 50.133 +}; 50.134 + 50.135 +enum 50.136 +{ 50.137 + OP_RECT, 50.138 + OP_LINE 50.139 +}; 50.140 + 50.141 +static int mach64_width[6] = {0, 0, 0, 1, 1, 2}; 50.142 + 50.143 +enum 50.144 +{ 50.145 + DST_24_ROT_EN = 0x80 50.146 +}; 50.147 + 50.148 +uint8_t mach64_ext_readb(uint32_t addr, void *priv); 50.149 +uint16_t mach64_ext_readw(uint32_t addr, void *priv); 50.150 +uint32_t mach64_ext_readl(uint32_t addr, void *priv); 50.151 +void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv); 50.152 +void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv); 50.153 +void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv); 50.154 + 50.155 +void mach64_out(uint16_t addr, uint8_t val, void *priv) 50.156 +{ 50.157 + uint8_t old; 50.158 + 50.159 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 50.160 + 50.161 +// pclog("mach64 out %04X %02X\n", addr, val); 50.162 + 50.163 + switch (addr) 50.164 + { 50.165 + case 0x1ce: 50.166 + ati_index = val; 50.167 + break; 50.168 + case 0x1cf: 50.169 + ati_regs[ati_index] = val; 50.170 + break; 50.171 + 50.172 + case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 50.173 + ati68860_ramdac_out((addr & 3) | ((mach64.dac_cntl & 3) << 2), val, NULL); 50.174 + return; 50.175 + 50.176 + case 0x3cf: 50.177 + if (gdcaddr == 6) 50.178 + { 50.179 + if ((gdcreg[6] & 0xc) != (val & 0xc)) 50.180 + { 50.181 + mem_removehandler(0xa0000, 0x20000, mach64_read, NULL, NULL, mach64_write, NULL, NULL, NULL); 50.182 + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 50.183 + mem_removehandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL); 50.184 + pclog("Write mapping %02X\n", val); 50.185 + switch (val&0xC) 50.186 + { 50.187 + case 0x0: /*128k at A0000*/ 50.188 + mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL, NULL); 50.189 + mem_sethandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL); 50.190 + break; 50.191 + case 0x4: /*64k at A0000*/ 50.192 + mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL, NULL); 50.193 + break; 50.194 + case 0x8: /*32k at B0000*/ 50.195 + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 50.196 + break; 50.197 + case 0xC: /*32k at B8000*/ 50.198 + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 50.199 + break; 50.200 + } 50.201 + } 50.202 + gdcreg[6] = val; 50.203 + return; 50.204 + } 50.205 + break; 50.206 + 50.207 + case 0x3D4: 50.208 + crtcreg = val & 0x3f; 50.209 + return; 50.210 + case 0x3D5: 50.211 + if (crtcreg <= 7 && crtc[0x11] & 0x80) return; 50.212 + old=crtc[crtcreg]; 50.213 + crtc[crtcreg]=val; 50.214 + 50.215 + if (old!=val) 50.216 + { 50.217 + if (crtcreg<0xE || crtcreg>0x10) 50.218 + { 50.219 + fullchange=changeframecount; 50.220 + svga_recalctimings(); 50.221 + } 50.222 + } 50.223 + break; 50.224 + } 50.225 + svga_out(addr, val, NULL); 50.226 +} 50.227 + 50.228 +uint8_t mach64_in(uint16_t addr, void *priv) 50.229 +{ 50.230 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 50.231 + 50.232 +// pclog("IN mach64 %04X\n", addr); 50.233 + 50.234 + switch (addr) 50.235 + { 50.236 + case 0x1ce: 50.237 + return ati_index; 50.238 + case 0x1cf: 50.239 + return ati_regs[ati_index]; 50.240 + 50.241 + case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 50.242 + return ati68860_ramdac_in((addr & 3) | ((mach64.dac_cntl & 3) << 2), NULL); 50.243 + 50.244 + case 0x3D4: 50.245 + return crtcreg; 50.246 + case 0x3D5: 50.247 + return crtc[crtcreg]; 50.248 + } 50.249 + return svga_in(addr, NULL); 50.250 +} 50.251 + 50.252 +void mach64_recalctimings() 50.253 +{ 50.254 + if (((mach64.crtc_gen_cntl >> 24) & 3) == 3) 50.255 + { 50.256 + svga_vtotal = (mach64.crtc_v_total_disp & 2047) + 1; 50.257 + svga_dispend = ((mach64.crtc_v_total_disp >> 16) & 2047) + 1; 50.258 + svga_htotal = (mach64.crtc_h_total_disp & 255) + 1; 50.259 + svga_hdisp_time = svga_hdisp = ((mach64.crtc_h_total_disp >> 16) & 255) + 1; 50.260 + svga_vsyncstart = (mach64.crtc_v_sync_strt_wid & 2047) + 1; 50.261 + svga_rowoffset = (mach64.crtc_off_pitch >> 22); 50.262 + svga_clock = cpuclock / ics2595_output_clock; 50.263 + svga_ma = (mach64.crtc_off_pitch & 0x1fffff) * 2; 50.264 + svga_linedbl = svga_rowcount = 0; 50.265 +// svga_htotal <<= 1; 50.266 +// svga_hdisp <<= 1; 50.267 + svga_rowoffset <<= 1; 50.268 + switch ((mach64.crtc_gen_cntl >> 8) & 7) 50.269 + { 50.270 + case 1: 50.271 + svga_render = svga_render_4bpp_highres; 50.272 + svga_hdisp *= 8; 50.273 + break; 50.274 + case 2: 50.275 + svga_render = svga_render_8bpp_highres; 50.276 + svga_hdisp *= 8; 50.277 + svga_rowoffset /= 2; 50.278 + break; 50.279 + case 3: 50.280 + svga_render = svga_render_15bpp_highres; 50.281 + svga_hdisp *= 8; 50.282 + //svga_rowoffset *= 2; 50.283 + break; 50.284 + case 4: 50.285 + svga_render = svga_render_16bpp_highres; 50.286 + svga_hdisp *= 8; 50.287 + //svga_rowoffset *= 2; 50.288 + break; 50.289 + case 5: 50.290 + svga_render = svga_render_24bpp_highres; 50.291 + svga_hdisp *= 8; 50.292 + svga_rowoffset = (svga_rowoffset * 3) / 2; 50.293 + break; 50.294 + case 6: 50.295 + svga_render = svga_render_32bpp_highres; 50.296 + svga_hdisp *= 8; 50.297 + break; 50.298 + } 50.299 + 50.300 + pclog("mach64_recalctimings : frame %i,%i disp %i,%i vsync at %i rowoffset %i pixel clock %f MA %08X\n", svga_htotal, svga_vtotal, svga_hdisp, svga_dispend, svga_vsyncstart, svga_rowoffset, svga_clock, svga_ma); 50.301 + } 50.302 +} 50.303 + 50.304 +#define READ8(addr, var) switch ((addr) & 3) \ 50.305 + { \ 50.306 + case 0: ret = (var) & 0xff; break; \ 50.307 + case 1: ret = ((var) >> 8) & 0xff; break; \ 50.308 + case 2: ret = ((var) >> 16) & 0xff; break; \ 50.309 + case 3: ret = ((var) >> 24) & 0xff; break; \ 50.310 + } 50.311 + 50.312 +#define WRITE8(addr, var, val) switch ((addr) & 3) \ 50.313 + { \ 50.314 + case 0: var = (var & 0xffffff00) | (val); break; \ 50.315 + case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ 50.316 + case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ 50.317 + case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ 50.318 + } 50.319 + 50.320 +void mach64_cursor_dump() 50.321 +{ 50.322 + pclog("Mach64 cursor :\n"); 50.323 + pclog("Ena = %i X = %i Y = %i Addr = %05X Xoff = %i Yoff = %i\n", svga_hwcursor.ena, svga_hwcursor.x, svga_hwcursor.y, svga_hwcursor.addr, svga_hwcursor.xoff, svga_hwcursor.yoff); 50.324 +} 50.325 + 50.326 +void mach64_start_fill() 50.327 +{ 50.328 + int x, y; 50.329 + 50.330 + mach64.accel.dst_x = (mach64.dst_y_x >> 16) & 0xfff; 50.331 + mach64.accel.dst_y = mach64.dst_y_x & 0xfff; 50.332 + 50.333 + mach64.accel.dst_width = (mach64.dst_height_width >> 16) & 0x1fff; 50.334 + mach64.accel.dst_height = mach64.dst_height_width & 0x1fff; 50.335 + mach64.accel.x_count = mach64.accel.dst_width; 50.336 + 50.337 + mach64.accel.src_x = (mach64.src_y_x >> 16) & 0xfff; 50.338 + mach64.accel.src_y = mach64.src_y_x & 0xfff; 50.339 + 50.340 + mach64.accel.src_pitch = (mach64.src_off_pitch >> 22) * 8; 50.341 + mach64.accel.src_offset = (mach64.src_off_pitch & 0xfffff) * 8; 50.342 + 50.343 + mach64.accel.dst_pitch = (mach64.dst_off_pitch >> 22) * 8; 50.344 + mach64.accel.dst_offset = (mach64.dst_off_pitch & 0xfffff) * 8; 50.345 + 50.346 + mach64.accel.mix_fg = (mach64.dp_mix >> 16) & 0x1f; 50.347 + mach64.accel.mix_bg = mach64.dp_mix & 0x1f; 50.348 + 50.349 + mach64.accel.source_bg = mach64.dp_src & 7; 50.350 + mach64.accel.source_fg = (mach64.dp_src >> 8) & 7; 50.351 + mach64.accel.source_mix = (mach64.dp_src >> 16) & 7; 50.352 + 50.353 + mach64.accel.dst_pix_width = mach64.dp_pix_width & 7; 50.354 + mach64.accel.src_pix_width = (mach64.dp_pix_width >> 8) & 7; 50.355 + mach64.accel.host_pix_width = (mach64.dp_pix_width >> 16) & 7; 50.356 + 50.357 + mach64.accel.dst_size = mach64_width[mach64.accel.dst_pix_width]; 50.358 + mach64.accel.src_size = mach64_width[mach64.accel.src_pix_width]; 50.359 + 50.360 +/* mach64.accel.src_x *= mach64_inc[mach64.accel.src_pix_width]; 50.361 + mach64.accel.src_pitch *= mach64_inc[mach64.accel.src_pix_width]; 50.362 + mach64.accel.dst_x *= mach64_inc[mach64.accel.dst_pix_width]; 50.363 + mach64.accel.dst_pitch *= mach64_inc[mach64.accel.dst_pix_width];*/ 50.364 + 50.365 + mach64.accel.src_offset >>= mach64.accel.src_size; 50.366 + mach64.accel.dst_offset >>= mach64.accel.dst_size; 50.367 + 50.368 + mach64.accel.src_x_start = mach64.accel.src_x; 50.369 + mach64.accel.dst_x_start = mach64.accel.dst_x; 50.370 + 50.371 +/* if (mach64.accel.source_fg == SRC_BLITSRC || mach64.accel.source_bg == SRC_BLITSRC) 50.372 + {*/ 50.373 + mach64.accel.xinc = (mach64.dst_cntl & 1) ? 1 : -1; 50.374 + mach64.accel.yinc = (mach64.dst_cntl & 2) ? 1 : -1; 50.375 +/* } 50.376 + else 50.377 + { 50.378 + mach64.accel.xinc = mach64_inc[mach64.accel.src_pix_width]; 50.379 + mach64.accel.yinc = 1; 50.380 + }*/ 50.381 + 50.382 + mach64.accel.source_host = ((mach64.dp_src & 7) == SRC_HOST) || (((mach64.dp_src >> 8) & 7) == SRC_HOST); 50.383 + 50.384 + 50.385 +// pclog("mach64_start_fill : pattern %08X %08X\n", mach64.pat_reg0, mach64.pat_reg1); 50.386 + for (y = 0; y < 8; y++) 50.387 + { 50.388 + for (x = 0; x < 8; x++) 50.389 + { 50.390 + uint32_t temp = (y & 4) ? mach64.pat_reg1 : mach64.pat_reg0; 50.391 + mach64.accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; 50.392 +// pclog("%i ", mach64.accel.pattern[y][x]); 50.393 + } 50.394 +// pclog("\n"); 50.395 + } 50.396 + 50.397 + mach64.accel.sc_left = mach64.sc_left_right & 0x1fff; 50.398 + mach64.accel.sc_right = (mach64.sc_left_right >> 16) & 0x1fff; 50.399 + mach64.accel.sc_top = mach64.sc_top_bottom & 0x7fff; 50.400 + mach64.accel.sc_bottom = (mach64.sc_top_bottom >> 16) & 0x7fff; 50.401 + 50.402 +/* mach64.accel.sc_left *= mach64_inc[mach64.accel.dst_pix_width]; 50.403 + mach64.accel.sc_right *= mach64_inc[mach64.accel.dst_pix_width];*/ 50.404 + 50.405 + mach64.accel.dp_frgd_clr = mach64.dp_frgd_clr; 50.406 + mach64.accel.dp_bkgd_clr = mach64.dp_bkgd_clr; 50.407 + 50.408 + mach64.accel.busy = 1; 50.409 +#ifdef MACH64_DEBUG 50.410 + pclog("mach64_start_fill : dst %i, %i src %i, %i size %i, %i src pitch %i offset %X dst pitch %i offset %X scissor %i %i %i %i src_fg %i\n", mach64.accel.dst_x, mach64.accel.dst_y, mach64.accel.src_x, mach64.accel.src_y, mach64.accel.dst_width, mach64.accel.dst_height, mach64.accel.src_pitch, mach64.accel.src_offset, mach64.accel.dst_pitch, mach64.accel.dst_offset, mach64.accel.sc_left, mach64.accel.sc_right, mach64.accel.sc_top, mach64.accel.sc_bottom, mach64.accel.source_fg); 50.411 +#endif 50.412 + mach64.accel.op = OP_RECT; 50.413 +} 50.414 + 50.415 +void mach64_start_line() 50.416 +{ 50.417 + int x, y; 50.418 + 50.419 + mach64.accel.dst_x = (mach64.dst_y_x >> 16) & 0xfff; 50.420 + mach64.accel.dst_y = mach64.dst_y_x & 0xfff; 50.421 + 50.422 + mach64.accel.src_x = (mach64.src_y_x >> 16) & 0xfff; 50.423 + mach64.accel.src_y = mach64.src_y_x & 0xfff; 50.424 + 50.425 + mach64.accel.src_pitch = (mach64.src_off_pitch >> 22) * 8; 50.426 + mach64.accel.src_offset = (mach64.src_off_pitch & 0xfffff) * 8; 50.427 + 50.428 + mach64.accel.dst_pitch = (mach64.dst_off_pitch >> 22) * 8; 50.429 + mach64.accel.dst_offset = (mach64.dst_off_pitch & 0xfffff) * 8; 50.430 + 50.431 + mach64.accel.mix_fg = (mach64.dp_mix >> 16) & 0x1f; 50.432 + mach64.accel.mix_bg = mach64.dp_mix & 0x1f; 50.433 + 50.434 + mach64.accel.source_bg = mach64.dp_src & 7; 50.435 + mach64.accel.source_fg = (mach64.dp_src >> 8) & 7; 50.436 + mach64.accel.source_mix = (mach64.dp_src >> 16) & 7; 50.437 + 50.438 + mach64.accel.dst_pix_width = mach64.dp_pix_width & 7; 50.439 + mach64.accel.src_pix_width = (mach64.dp_pix_width >> 8) & 7; 50.440 + mach64.accel.host_pix_width = (mach64.dp_pix_width >> 16) & 7; 50.441 + 50.442 + mach64.accel.dst_size = mach64_width[mach64.accel.dst_pix_width]; 50.443 + mach64.accel.src_size = mach64_width[mach64.accel.src_pix_width]; 50.444 + 50.445 + mach64.accel.src_offset >>= mach64.accel.src_size; 50.446 + mach64.accel.dst_offset >>= mach64.accel.dst_size; 50.447 + 50.448 +/* mach64.accel.src_pitch *= mach64_inc[mach64.accel.src_pix_width]; 50.449 + mach64.accel.dst_pitch *= mach64_inc[mach64.accel.dst_pix_width];*/ 50.450 + 50.451 + mach64.accel.source_host = ((mach64.dp_src & 7) == SRC_HOST) || (((mach64.dp_src >> 8) & 7) == SRC_HOST); 50.452 + 50.453 + for (y = 0; y < 8; y++) 50.454 + { 50.455 + for (x = 0; x < 8; x++) 50.456 + { 50.457 + uint32_t temp = (y & 4) ? mach64.pat_reg1 : mach64.pat_reg0; 50.458 + mach64.accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; 50.459 + } 50.460 + } 50.461 + 50.462 + mach64.accel.sc_left = mach64.sc_left_right & 0x1fff; 50.463 + mach64.accel.sc_right = (mach64.sc_left_right >> 16) & 0x1fff; 50.464 + mach64.accel.sc_top = mach64.sc_top_bottom & 0x7fff; 50.465 + mach64.accel.sc_bottom = (mach64.sc_top_bottom >> 16) & 0x7fff; 50.466 + 50.467 + mach64.accel.dp_frgd_clr = mach64.dp_frgd_clr; 50.468 + mach64.accel.dp_bkgd_clr = mach64.dp_bkgd_clr; 50.469 + 50.470 + mach64.accel.x_count = mach64.dst_bres_lnth & 0x7fff; 50.471 + mach64.accel.err = (mach64.dst_bres_err & 0x3ffff) | ((mach64.dst_bres_err & 0x40000) ? 0xfffc0000 : 0); 50.472 + 50.473 + mach64.accel.busy = 1; 50.474 +#ifdef MACH64_DEBUG 50.475 + pclog("mach64_start_line\n"); 50.476 +#endif 50.477 + mach64.accel.op = OP_LINE; 50.478 +} 50.479 + 50.480 +#define READ(addr, dat, width) if (width == 0) dat = vram[((addr)) & 0x7fffff]; \ 50.481 + else if (width == 1) dat = *(uint16_t *)&vram[((addr) << 1) & 0x7fffff]; \ 50.482 + else dat = *(uint32_t *)&vram[((addr) << 2) & 0x7fffff]; 50.483 + 50.484 +#define MIX switch (mix ? mach64.accel.mix_fg : mach64.accel.mix_bg) \ 50.485 + { \ 50.486 + case 0x0: dest_dat = ~dest_dat; break; \ 50.487 + case 0x1: dest_dat = 0; break; \ 50.488 + case 0x2: dest_dat = 0xffffffff; break; \ 50.489 + case 0x3: dest_dat = dest_dat; break; \ 50.490 + case 0x4: dest_dat = ~src_dat; break; \ 50.491 + case 0x5: dest_dat = src_dat ^ dest_dat; break; \ 50.492 + case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \ 50.493 + case 0x7: dest_dat = src_dat; break; \ 50.494 + case 0x8: dest_dat = ~(src_dat & dest_dat); break; \ 50.495 + case 0x9: dest_dat = ~src_dat | dest_dat; break; \ 50.496 + case 0xa: dest_dat = src_dat | ~dest_dat; break; \ 50.497 + case 0xb: dest_dat = src_dat | dest_dat; break; \ 50.498 + case 0xc: dest_dat = src_dat & dest_dat; break; \ 50.499 + case 0xd: dest_dat = src_dat & ~dest_dat; break; \ 50.500 + case 0xe: dest_dat = ~src_dat & dest_dat; break; \ 50.501 + case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ 50.502 + } 50.503 + 50.504 +#define WRITE(addr, width) if (width == 0) \ 50.505 + { \ 50.506 + vram[(addr) & 0x7fffff] = dest_dat; \ 50.507 + changedvram[((addr) & 0x7fffff) >> 10] = changeframecount; \ 50.508 + } \ 50.509 + else if (width == 1) \ 50.510 + { \ 50.511 + *(uint16_t *)&vram[((addr) << 1) & 0x7fffff] = dest_dat; \ 50.512 + changedvram[(((addr) << 1) & 0x7fffff) >> 10] = changeframecount; \ 50.513 + } \ 50.514 + else \ 50.515 + { \ 50.516 + *(uint32_t *)&vram[((addr) << 2) & 0x7fffff] = dest_dat; \ 50.517 + changedvram[(((addr) << 2) & 0x7fffff) >> 10] = changeframecount; \ 50.518 + } 50.519 + 50.520 +void mach64_blit(uint32_t cpu_dat, int count) 50.521 +{ 50.522 + if (!mach64.accel.busy) 50.523 + { 50.524 +#ifdef MACH64_DEBUG 50.525 + pclog("mach64_blit : return as not busy\n"); 50.526 +#endif 50.527 + return; 50.528 + } 50.529 + switch (mach64.accel.op) 50.530 + { 50.531 + case OP_RECT: 50.532 + while (count) 50.533 + { 50.534 + uint32_t src_dat, dest_dat; 50.535 + uint32_t host_dat; 50.536 + int mix; 50.537 + 50.538 + if (mach64.accel.source_host) 50.539 + { 50.540 + host_dat = cpu_dat; 50.541 + switch (mach64.accel.src_size) 50.542 + { 50.543 + case 0: 50.544 + cpu_dat >>= 8; 50.545 + count -= 8; 50.546 + break; 50.547 + case 1: 50.548 + cpu_dat >>= 16; 50.549 + count -= 16; 50.550 + break; 50.551 + case 2: 50.552 + count -= 32; 50.553 + break; 50.554 + } 50.555 + } 50.556 + else 50.557 + count--; 50.558 + 50.559 + switch (mach64.accel.source_mix) 50.560 + { 50.561 + case MONO_SRC_HOST: 50.562 + mix = cpu_dat >> 31; 50.563 + cpu_dat <<= 1; 50.564 + break; 50.565 + case MONO_SRC_PAT: 50.566 + mix = mach64.accel.pattern[mach64.accel.dst_y & 7][mach64.accel.dst_x & 7]; 50.567 + break; 50.568 + case MONO_SRC_1: 50.569 + default: 50.570 + mix = 1; 50.571 + break; 50.572 + } 50.573 + 50.574 + if (mach64.accel.dst_x >= mach64.accel.sc_left && mach64.accel.dst_x <= mach64.accel.sc_right && 50.575 + mach64.accel.dst_y >= mach64.accel.sc_top && mach64.accel.dst_y <= mach64.accel.sc_bottom) 50.576 + { 50.577 + switch (mix ? mach64.accel.source_fg : mach64.accel.source_bg) 50.578 + { 50.579 + case SRC_HOST: 50.580 + src_dat = host_dat; 50.581 + break; 50.582 + case SRC_BLITSRC: 50.583 + READ(mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x, src_dat, mach64.accel.src_size); 50.584 + break; 50.585 + case SRC_FG: 50.586 + src_dat = mach64.accel.dp_frgd_clr; 50.587 + break; 50.588 + case SRC_BG: 50.589 + src_dat = mach64.accel.dp_bkgd_clr; 50.590 + break; 50.591 + default: 50.592 + src_dat = 0; 50.593 + break; 50.594 + } 50.595 + 50.596 + READ(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, dest_dat, mach64.accel.dst_size); 50.597 + 50.598 +// pclog("Blit %i,%i %i,%i %X %X %i %02X %02X %i ", mach64.accel.src_x, mach64.accel.src_y, mach64.accel.dst_x, mach64.accel.dst_y, (mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x) & 0x7fffff, (mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix); 50.599 + 50.600 + MIX 50.601 + 50.602 +// pclog("%02X %i\n", dest_dat, mach64.accel.dst_height); 50.603 + 50.604 + WRITE(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, mach64.accel.dst_size); 50.605 + } 50.606 + 50.607 + if (mach64.dst_cntl & DST_24_ROT_EN) 50.608 + { 50.609 + mach64.accel.dp_frgd_clr = ((mach64.accel.dp_frgd_clr >> 8) & 0xffff) | (mach64.accel.dp_frgd_clr << 16); 50.610 + mach64.accel.dp_bkgd_clr = ((mach64.accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64.accel.dp_bkgd_clr << 16); 50.611 + } 50.612 + 50.613 + mach64.accel.src_x += mach64.accel.xinc; 50.614 + mach64.accel.dst_x += mach64.accel.xinc; 50.615 + mach64.accel.x_count--; 50.616 + 50.617 + if (mach64.accel.x_count <= 0) 50.618 + { 50.619 + mach64.accel.x_count = mach64.accel.dst_width; 50.620 + mach64.accel.src_x = mach64.accel.src_x_start; 50.621 + mach64.accel.dst_x = mach64.accel.dst_x_start; 50.622 + 50.623 + mach64.accel.src_y += mach64.accel.yinc; 50.624 + mach64.accel.dst_y += mach64.accel.yinc; 50.625 + mach64.accel.dst_height--; 50.626 + 50.627 + if (mach64.accel.dst_height <= 0) 50.628 + { 50.629 + /*Blit finished*/ 50.630 +#ifdef MACH64_DEBUG 50.631 + pclog("mach64 blit finished\n"); 50.632 +#endif 50.633 + mach64.accel.busy = 0; 50.634 + return; 50.635 + } 50.636 + if (mach64.accel.source_host) 50.637 + return; 50.638 + } 50.639 + } 50.640 + break; 50.641 + 50.642 + case OP_LINE: 50.643 + while (count) 50.644 + { 50.645 + uint32_t src_dat, dest_dat; 50.646 + uint32_t host_dat; 50.647 + int mix; 50.648 + 50.649 + if (mach64.accel.source_host) 50.650 + { 50.651 + host_dat = cpu_dat; 50.652 + switch (mach64.accel.src_size) 50.653 + { 50.654 + case 0: 50.655 + cpu_dat >>= 8; 50.656 + count -= 8; 50.657 + break; 50.658 + case 1: 50.659 + cpu_dat >>= 16; 50.660 + count -= 16; 50.661 + break; 50.662 + case 2: 50.663 + count -= 32; 50.664 + break; 50.665 + } 50.666 + } 50.667 + else 50.668 + count--; 50.669 + 50.670 + switch (mach64.accel.source_mix) 50.671 + { 50.672 + case MONO_SRC_HOST: 50.673 + mix = cpu_dat >> 31; 50.674 + cpu_dat <<= 1; 50.675 + break; 50.676 + case MONO_SRC_PAT: 50.677 + mix = mach64.accel.pattern[mach64.accel.dst_y & 7][mach64.accel.dst_x & 7]; 50.678 + break; 50.679 + case MONO_SRC_1: 50.680 + default: 50.681 + mix = 1; 50.682 + break; 50.683 + } 50.684 + 50.685 + if (mach64.accel.dst_x >= mach64.accel.sc_left && mach64.accel.dst_x <= mach64.accel.sc_right && 50.686 + mach64.accel.dst_y >= mach64.accel.sc_top && mach64.accel.dst_y <= mach64.accel.sc_bottom) 50.687 + { 50.688 + switch (mix ? mach64.accel.source_fg : mach64.accel.source_bg) 50.689 + { 50.690 + case SRC_HOST: 50.691 + src_dat = host_dat; 50.692 + break; 50.693 + case SRC_BLITSRC: 50.694 + READ(mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x, src_dat, mach64.accel.src_size); 50.695 + break; 50.696 + case SRC_FG: 50.697 + src_dat = mach64.accel.dp_frgd_clr; 50.698 + break; 50.699 + case SRC_BG: 50.700 + src_dat = mach64.accel.dp_bkgd_clr; 50.701 + break; 50.702 + default: 50.703 + src_dat = 0; 50.704 + break; 50.705 + } 50.706 + 50.707 + READ(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, dest_dat, mach64.accel.dst_size); 50.708 + 50.709 +// pclog("Blit %i,%i %i,%i %X %X %i %02X %02X %i ", mach64.accel.src_x, mach64.accel.src_y, mach64.accel.dst_x, mach64.accel.dst_y, (mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x) & 0x7fffff, (mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix); 50.710 + 50.711 + MIX 50.712 + 50.713 +// pclog("%02X %i\n", dest_dat, mach64.accel.dst_height); 50.714 + 50.715 + WRITE(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, mach64.accel.dst_size); 50.716 + } 50.717 + 50.718 + mach64.accel.x_count--; 50.719 + if (mach64.accel.x_count <= 0) 50.720 + { 50.721 + /*Blit finished*/ 50.722 +#ifdef MACH64_DEBUG 50.723 + pclog("mach64 blit finished\n"); 50.724 +#endif 50.725 + mach64.accel.busy = 0; 50.726 + return; 50.727 + } 50.728 + 50.729 + switch (mach64.dst_cntl & 7) 50.730 + { 50.731 + case 0: case 2: 50.732 + mach64.accel.src_x--; 50.733 + mach64.accel.dst_x--; 50.734 + break; 50.735 + case 1: case 3: 50.736 + mach64.accel.src_x++; 50.737 + mach64.accel.dst_x++; 50.738 + break; 50.739 + case 4: case 5: 50.740 + mach64.accel.src_y--; 50.741 + mach64.accel.dst_y--; 50.742 + break; 50.743 + case 6: case 7: 50.744 + mach64.accel.src_y++; 50.745 + mach64.accel.dst_y++; 50.746 + break; 50.747 + } 50.748 +#ifdef MACH64_DEBUG 50.749 + pclog("x %i y %i err %i inc %i dec %i\n", mach64.accel.dst_x, mach64.accel.dst_y, mach64.accel.err, mach64.dst_bres_inc, mach64.dst_bres_dec); 50.750 +#endif 50.751 + if (mach64.accel.err >= 0) 50.752 + { 50.753 + mach64.accel.err += mach64.dst_bres_dec; 50.754 + 50.755 + switch (mach64.dst_cntl & 7) 50.756 + { 50.757 + case 0: case 1: 50.758 + mach64.accel.src_y--; 50.759 + mach64.accel.dst_y--; 50.760 + break; 50.761 + case 2: case 3: 50.762 + mach64.accel.src_y++; 50.763 + mach64.accel.dst_y++; 50.764 + break; 50.765 + case 4: case 6: 50.766 + mach64.accel.src_x--; 50.767 + mach64.accel.dst_x--; 50.768 + break; 50.769 + case 5: case 7: 50.770 + mach64.accel.src_x++; 50.771 + mach64.accel.dst_x++; 50.772 + break; 50.773 + } 50.774 + } 50.775 + else 50.776 + mach64.accel.err += mach64.dst_bres_inc; 50.777 + } 50.778 + break; 50.779 + } 50.780 +} 50.781 + 50.782 +void mach64_load_context() 50.783 +{ 50.784 + uint32_t addr; 50.785 + 50.786 + while (mach64.context_load_cntl & 0x30000) 50.787 + { 50.788 + addr = (0x3fff - (mach64.context_load_cntl & 0x3fff)) * 256; 50.789 + mach64.context_mask = *(uint32_t *)&vram[addr]; 50.790 +#ifdef MACH64_DEBUG 50.791 + pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64.context_load_cntl, addr, mach64.context_mask); 50.792 +#endif 50.793 + 50.794 + if (mach64.context_mask & (1 << 2)) 50.795 + mach64_ext_writel(0x100, *(uint32_t *)&vram[addr + 0x08], NULL); 50.796 + if (mach64.context_mask & (1 << 3)) 50.797 + mach64_ext_writel(0x10c, *(uint32_t *)&vram[addr + 0x0c], NULL); 50.798 + if (mach64.context_mask & (1 << 4)) 50.799 + mach64_ext_writel(0x118, *(uint32_t *)&vram[addr + 0x10], NULL); 50.800 + if (mach64.context_mask & (1 << 5)) 50.801 + mach64_ext_writel(0x124, *(uint32_t *)&vram[addr + 0x14], NULL); 50.802 + if (mach64.context_mask & (1 << 6)) 50.803 + mach64_ext_writel(0x128, *(uint32_t *)&vram[addr + 0x18], NULL); 50.804 + if (mach64.context_mask & (1 << 7)) 50.805 + mach64_ext_writel(0x12c, *(uint32_t *)&vram[addr + 0x1c], NULL); 50.806 + if (mach64.context_mask & (1 << 8)) 50.807 + mach64_ext_writel(0x180, *(uint32_t *)&vram[addr + 0x20], NULL); 50.808 + if (mach64.context_mask & (1 << 9)) 50.809 + mach64_ext_writel(0x18c, *(uint32_t *)&vram[addr + 0x24], NULL); 50.810 + if (mach64.context_mask & (1 << 10)) 50.811 + mach64_ext_writel(0x198, *(uint32_t *)&vram[addr + 0x28], NULL); 50.812 + if (mach64.context_mask & (1 << 11)) 50.813 + mach64_ext_writel(0x1a4, *(uint32_t *)&vram[addr + 0x2c], NULL); 50.814 + if (mach64.context_mask & (1 << 12)) 50.815 + mach64_ext_writel(0x1b0, *(uint32_t *)&vram[addr + 0x30], NULL); 50.816 + if (mach64.context_mask & (1 << 13)) 50.817 + mach64_ext_writel(0x280, *(uint32_t *)&vram[addr + 0x34], NULL); 50.818 + if (mach64.context_mask & (1 << 14)) 50.819 + mach64_ext_writel(0x284, *(uint32_t *)&vram[addr + 0x38], NULL); 50.820 + if (mach64.context_mask & (1 << 15)) 50.821 + mach64_ext_writel(0x2a8, *(uint32_t *)&vram[addr + 0x3c], NULL); 50.822 + if (mach64.context_mask & (1 << 16)) 50.823 + mach64_ext_writel(0x2b4, *(uint32_t *)&vram[addr + 0x40], NULL); 50.824 + if (mach64.context_mask & (1 << 17)) 50.825 + mach64_ext_writel(0x2c0, *(uint32_t *)&vram[addr + 0x44], NULL); 50.826 + if (mach64.context_mask & (1 << 18)) 50.827 + mach64_ext_writel(0x2c4, *(uint32_t *)&vram[addr + 0x48], NULL); 50.828 + if (mach64.context_mask & (1 << 19)) 50.829 + mach64_ext_writel(0x2c8, *(uint32_t *)&vram[addr + 0x4c], NULL); 50.830 + if (mach64.context_mask & (1 << 20)) 50.831 + mach64_ext_writel(0x2cc, *(uint32_t *)&vram[addr + 0x50], NULL); 50.832 + if (mach64.context_mask & (1 << 21)) 50.833 + mach64_ext_writel(0x2d0, *(uint32_t *)&vram[addr + 0x54], NULL); 50.834 + if (mach64.context_mask & (1 << 22)) 50.835 + mach64_ext_writel(0x2d4, *(uint32_t *)&vram[addr + 0x58], NULL); 50.836 + if (mach64.context_mask & (1 << 23)) 50.837 + mach64_ext_writel(0x2d8, *(uint32_t *)&vram[addr + 0x5c], NULL); 50.838 + if (mach64.context_mask & (1 << 24)) 50.839 + mach64_ext_writel(0x300, *(uint32_t *)&vram[addr + 0x60], NULL); 50.840 + if (mach64.context_mask & (1 << 25)) 50.841 + mach64_ext_writel(0x304, *(uint32_t *)&vram[addr + 0x64], NULL); 50.842 + if (mach64.context_mask & (1 << 26)) 50.843 + mach64_ext_writel(0x308, *(uint32_t *)&vram[addr + 0x68], NULL); 50.844 + if (mach64.context_mask & (1 << 27)) 50.845 + mach64_ext_writel(0x330, *(uint32_t *)&vram[addr + 0x6c], NULL); 50.846 + 50.847 + mach64.context_load_cntl = *(uint32_t *)&vram[addr + 0x70]; 50.848 + } 50.849 +} 50.850 + 50.851 +uint8_t mach64_ext_readb(uint32_t addr, void *priv) 50.852 +{ 50.853 + uint8_t ret; 50.854 + switch (addr & 0x3ff) 50.855 + { 50.856 + case 0x00: case 0x01: case 0x02: case 0x03: 50.857 + READ8(addr, mach64.crtc_h_total_disp); 50.858 + break; 50.859 + case 0x08: case 0x09: case 0x0a: case 0x0b: 50.860 + READ8(addr, mach64.crtc_v_total_disp); 50.861 + break; 50.862 + case 0x0c: case 0x0d: case 0x0e: case 0x0f: 50.863 + READ8(addr, mach64.crtc_v_sync_strt_wid); 50.864 + break; 50.865 + 50.866 + case 0x14: case 0x15: case 0x16: case 0x17: 50.867 + READ8(addr, mach64.crtc_off_pitch); 50.868 + break; 50.869 + 50.870 + case 0x18: 50.871 + ret = mach64.crtc_int_cntl & ~1; 50.872 + if (cgastat & 8) 50.873 + ret |= 1; 50.874 + break; 50.875 + 50.876 + case 0x1c: case 0x1d: case 0x1e: case 0x1f: 50.877 + READ8(addr, mach64.crtc_gen_cntl); 50.878 + break; 50.879 + 50.880 + case 0x68: case 0x69: case 0x6a: case 0x6b: 50.881 + READ8(addr, mach64.cur_offset); 50.882 + break; 50.883 + case 0x6c: case 0x6d: case 0x6e: case 0x6f: 50.884 + READ8(addr, mach64.cur_horz_vert_posn); 50.885 + break; 50.886 + case 0x70: case 0x71: case 0x72: case 0x73: 50.887 + READ8(addr, mach64.cur_horz_vert_off); 50.888 + break; 50.889 + 50.890 + case 0x80: case 0x81: case 0x82: case 0x83: 50.891 + READ8(addr, mach64.scratch_reg0); 50.892 + break; 50.893 + case 0x84: case 0x85: case 0x86: case 0x87: 50.894 + READ8(addr, mach64.scratch_reg1); 50.895 + break; 50.896 + 50.897 + case 0x90: case 0x91: case 0x92: case 0x93: 50.898 + READ8(addr, mach64.clock_cntl); 50.899 + break; 50.900 + 50.901 + case 0xb0: case 0xb1: case 0xb2: case 0xb3: 50.902 + READ8(addr, mach64.mem_cntl); 50.903 + break; 50.904 + 50.905 + case 0xc4: case 0xc5: case 0xc6: case 0xc7: 50.906 + READ8(addr, mach64.dac_cntl); 50.907 + break; 50.908 + 50.909 + case 0xd0: case 0xd1: case 0xd2: case 0xd3: 50.910 + READ8(addr, mach64.gen_test_cntl); 50.911 + break; 50.912 + 50.913 + case 0xe0: case 0xe1: case 0xe2: case 0xe3: 50.914 + READ8(addr, 0xd7); /*88800GX*/ 50.915 + break; 50.916 + 50.917 + case 0x100: case 0x101: case 0x102: case 0x103: 50.918 + READ8(addr, mach64.dst_off_pitch); 50.919 + break; 50.920 + case 0x104: case 0x105: 50.921 + READ8(addr, mach64.dst_y_x); 50.922 + break; 50.923 + case 0x108: case 0x109: case 0x11c: case 0x11d: 50.924 + READ8(addr + 2, mach64.dst_y_x); 50.925 + break; 50.926 + case 0x10c: case 0x10d: case 0x10e: case 0x10f: 50.927 + READ8(addr, mach64.dst_y_x); 50.928 + break; 50.929 + case 0x110: case 0x111: 50.930 + addr += 2; 50.931 + case 0x114: case 0x115: 50.932 + case 0x118: case 0x119: case 0x11a: case 0x11b: 50.933 + case 0x11e: case 0x11f: 50.934 + READ8(addr, mach64.dst_height_width); 50.935 + break; 50.936 + 50.937 + case 0x120: case 0x121: case 0x122: case 0x123: 50.938 + READ8(addr, mach64.dst_bres_lnth); 50.939 + break; 50.940 + case 0x124: case 0x125: case 0x126: case 0x127: 50.941 + READ8(addr, mach64.dst_bres_err); 50.942 + break; 50.943 + case 0x128: case 0x129: case 0x12a: case 0x12b: 50.944 + READ8(addr, mach64.dst_bres_inc); 50.945 + break; 50.946 + case 0x12c: case 0x12d: case 0x12e: case 0x12f: 50.947 + READ8(addr, mach64.dst_bres_dec); 50.948 + break; 50.949 + 50.950 + case 0x130: case 0x131: case 0x132: case 0x133: 50.951 + READ8(addr, mach64.dst_cntl); 50.952 + break; 50.953 + 50.954 + case 0x180: case 0x181: case 0x182: case 0x183: 50.955 + READ8(addr, mach64.src_off_pitch); 50.956 + break; 50.957 + case 0x184: case 0x185: 50.958 + READ8(addr, mach64.src_y_x); 50.959 + break; 50.960 + case 0x188: case 0x189: 50.961 + READ8(addr + 2, mach64.src_y_x); 50.962 + break; 50.963 + case 0x18c: case 0x18d: case 0x18e: case 0x18f: 50.964 + READ8(addr, mach64.src_y_x); 50.965 + break; 50.966 + 50.967 + case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: 50.968 + READ8(addr, mach64.src_cntl); 50.969 + break; 50.970 + 50.971 + case 0x280: case 0x281: case 0x282: case 0x283: 50.972 + READ8(addr, mach64.pat_reg0); 50.973 + break; 50.974 + case 0x284: case 0x285: case 0x286: case 0x287: 50.975 + READ8(addr, mach64.pat_reg1); 50.976 + break; 50.977 + 50.978 + case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: 50.979 + READ8(addr, mach64.sc_left_right); 50.980 + break; 50.981 + case 0x2a4: case 0x2a5: 50.982 + addr += 2; 50.983 + case 0x2aa: case 0x2ab: 50.984 + READ8(addr, mach64.sc_left_right); 50.985 + break; 50.986 + 50.987 + case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: 50.988 + READ8(addr, mach64.sc_top_bottom); 50.989 + break; 50.990 + case 0x2b0: case 0x2b1: 50.991 + addr += 2; 50.992 + case 0x2b6: case 0x2b7: 50.993 + READ8(addr, mach64.sc_top_bottom); 50.994 + break; 50.995 + 50.996 + case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: 50.997 + READ8(addr, mach64.dp_bkgd_clr); 50.998 + break; 50.999 + case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: 50.1000 + READ8(addr, mach64.dp_frgd_clr); 50.1001 + break; 50.1002 + 50.1003 + case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: 50.1004 + READ8(addr, mach64.dp_pix_width); 50.1005 + break; 50.1006 + case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: 50.1007 + READ8(addr, mach64.dp_mix); 50.1008 + break; 50.1009 + case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: 50.1010 + READ8(addr, mach64.dp_src); 50.1011 + break; 50.1012 + 50.1013 + case 0x320: case 0x321: case 0x322: case 0x323: 50.1014 + READ8(addr, mach64.context_mask); 50.1015 + break; 50.1016 + 50.1017 + case 0x330: case 0x331: 50.1018 + READ8(addr, mach64.dst_cntl); 50.1019 + break; 50.1020 + case 0x332: 50.1021 + READ8(addr - 2, mach64.src_cntl); 50.1022 + break; 50.1023 + case 0x333: 50.1024 + READ8(addr - 3, mach64.pat_cntl); 50.1025 + break; 50.1026 + 50.1027 + default: 50.1028 + ret = 0; 50.1029 + break; 50.1030 + } 50.1031 +#ifdef MACH64_DEBUG 50.1032 + if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readb : addr %08X ret %02X\n", addr, ret); 50.1033 +#endif 50.1034 + return ret; 50.1035 +} 50.1036 +uint16_t mach64_ext_readw(uint32_t addr, void *priv) 50.1037 +{ 50.1038 + uint16_t ret; 50.1039 + switch (addr & 0x3ff) 50.1040 + { 50.1041 + default: 50.1042 +#ifdef MACH64_DEBUG 50.1043 + pclog(" "); 50.1044 +#endif 50.1045 + ret = mach64_ext_readb(addr, priv); 50.1046 +#ifdef MACH64_DEBUG 50.1047 + pclog(" "); 50.1048 +#endif 50.1049 + ret |= mach64_ext_readb(addr + 1, priv) << 8; 50.1050 + break; 50.1051 + } 50.1052 +#ifdef MACH64_DEBUG 50.1053 + if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readw : addr %08X ret %04X\n", addr, ret); 50.1054 +#endif 50.1055 + return ret; 50.1056 +} 50.1057 +uint32_t mach64_ext_readl(uint32_t addr, void *priv) 50.1058 +{ 50.1059 + uint32_t ret; 50.1060 + switch (addr & 0x3ff) 50.1061 + { 50.1062 + case 0x18: 50.1063 + ret = mach64.crtc_int_cntl & ~1; 50.1064 + if (cgastat & 8) 50.1065 + ret |= 1; 50.1066 + break; 50.1067 + 50.1068 + case 0xb4: 50.1069 + ret = (mach64_bank_w[0] >> 15) | ((mach64_bank_w[1] >> 15) << 16); 50.1070 + break; 50.1071 + case 0xb8: 50.1072 + ret = (mach64_bank_r[0] >> 15) | ((mach64_bank_r[1] >> 15) << 16); 50.1073 + break; 50.1074 + 50.1075 + default: 50.1076 +#ifdef MACH64_DEBUG 50.1077 + pclog(" "); 50.1078 +#endif 50.1079 + ret = mach64_ext_readw(addr, priv); 50.1080 +#ifdef MACH64_DEBUG 50.1081 + pclog(" "); 50.1082 +#endif 50.1083 + ret |= mach64_ext_readw(addr + 2, priv) << 16; 50.1084 + break; 50.1085 + } 50.1086 +#ifdef MACH64_DEBUG 50.1087 + if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readl : addr %08X ret %08X\n", addr, ret); 50.1088 +#endif 50.1089 + return ret; 50.1090 +} 50.1091 + 50.1092 +void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) 50.1093 +{ 50.1094 +#ifdef MACH64_DEBUG 50.1095 + pclog("mach64_ext_writeb : addr %08X val %02X\n", addr, val); 50.1096 +#endif 50.1097 + switch (addr & 0x3ff) 50.1098 + { 50.1099 + case 0x00: case 0x01: case 0x02: case 0x03: 50.1100 + WRITE8(addr, mach64.crtc_h_total_disp, val); 50.1101 + svga_recalctimings(); 50.1102 + break; 50.1103 + case 0x08: case 0x09: case 0x0a: case 0x0b: 50.1104 + WRITE8(addr, mach64.crtc_v_total_disp, val); 50.1105 + svga_recalctimings(); 50.1106 + break; 50.1107 + case 0x0c: case 0x0d: case 0x0e: case 0x0f: 50.1108 + WRITE8(addr, mach64.crtc_v_sync_strt_wid, val); 50.1109 + svga_recalctimings(); 50.1110 + break; 50.1111 + 50.1112 + case 0x14: case 0x15: case 0x16: case 0x17: 50.1113 + WRITE8(addr, mach64.crtc_off_pitch, val); 50.1114 + svga_recalctimings(); 50.1115 + fullchange = changeframecount; 50.1116 + break; 50.1117 + 50.1118 + case 0x18: 50.1119 + mach64.crtc_int_cntl = val; 50.1120 + break; 50.1121 + 50.1122 + case 0x1c: case 0x1d: case 0x1e: case 0x1f: 50.1123 + WRITE8(addr, mach64.crtc_gen_cntl, val); 50.1124 + svga_recalctimings(); 50.1125 + break; 50.1126 + 50.1127 + case 0x68: case 0x69: case 0x6a: case 0x6b: 50.1128 + WRITE8(addr, mach64.cur_offset, val); 50.1129 + svga_hwcursor.addr = (mach64.cur_offset & 0xfffff) * 8; 50.1130 + mach64_cursor_dump(); 50.1131 + break; 50.1132 + case 0x6c: case 0x6d: case 0x6e: case 0x6f: 50.1133 + WRITE8(addr, mach64.cur_horz_vert_posn, val); 50.1134 + svga_hwcursor.x = mach64.cur_horz_vert_posn & 0x7ff; 50.1135 + svga_hwcursor.y = (mach64.cur_horz_vert_posn >> 16) & 0x7ff; 50.1136 + mach64_cursor_dump(); 50.1137 + break; 50.1138 + case 0x70: case 0x71: case 0x72: case 0x73: 50.1139 + WRITE8(addr, mach64.cur_horz_vert_off, val); 50.1140 + svga_hwcursor.xoff = mach64.cur_horz_vert_off & 0x3f; 50.1141 + svga_hwcursor.yoff = (mach64.cur_horz_vert_off >> 16) & 0x3f; 50.1142 + mach64_cursor_dump(); 50.1143 + break; 50.1144 + 50.1145 + case 0x80: case 0x81: case 0x82: case 0x83: 50.1146 + WRITE8(addr, mach64.scratch_reg0, val); 50.1147 + break; 50.1148 + case 0x84: case 0x85: case 0x86: case 0x87: 50.1149 + WRITE8(addr, mach64.scratch_reg1, val); 50.1150 + break; 50.1151 + 50.1152 + case 0x90: case 0x91: case 0x92: case 0x93: 50.1153 + WRITE8(addr, mach64.clock_cntl, val); 50.1154 + ics2595_write(val & 0x40, val & 0xf); 50.1155 + break; 50.1156 + 50.1157 + case 0xb0: case 0xb1: case 0xb2: case 0xb3: 50.1158 + WRITE8(addr, mach64.mem_cntl, val); 50.1159 + break; 50.1160 + 50.1161 + case 0xb4: 50.1162 + mach64_bank_w[0] = val * 32768; 50.1163 +#ifdef MACH64_DEBUG 50.1164 + pclog("mach64 : write bank A0000-A7FFF set to %08X\n", mach64_bank_w[0]); 50.1165 +#endif 50.1166 + break; 50.1167 + case 0xb5: case 0xb6: 50.1168 + mach64_bank_w[1] = val * 32768; 50.1169 +#ifdef MACH64_DEBUG 50.1170 + pclog("mach64 : write bank A8000-AFFFF set to %08X\n", mach64_bank_w[1]); 50.1171 +#endif 50.1172 + break; 50.1173 + case 0xb8: 50.1174 + mach64_bank_r[0] = val * 32768; 50.1175 +#ifdef MACH64_DEBUG 50.1176 + pclog("mach64 : read bank A0000-A7FFF set to %08X\n", mach64_bank_r[0]); 50.1177 +#endif 50.1178 + break; 50.1179 + case 0xb9: case 0xba: 50.1180 + mach64_bank_r[1] = val * 32768; 50.1181 +#ifdef MACH64_DEBUG 50.1182 + pclog("mach64 : read bank A8000-AFFFF set to %08X\n", mach64_bank_r[1]); 50.1183 +#endif 50.1184 + break; 50.1185 + 50.1186 + case 0xc4: case 0xc5: case 0xc6: case 0xc7: 50.1187 + WRITE8(addr, mach64.dac_cntl, val); 50.1188 + break; 50.1189 + 50.1190 + case 0xd0: case 0xd1: case 0xd2: case 0xd3: 50.1191 + WRITE8(addr, mach64.gen_test_cntl, val); 50.1192 +// if (val == 2) output = 3; 50.1193 + ati_eeprom_write(mach64.gen_test_cntl & 0x10, mach64.gen_test_cntl & 2, mach64.gen_test_cntl & 1); 50.1194 + mach64.gen_test_cntl = (mach64.gen_test_cntl & ~8) | (ati_eeprom_read() ? 8 : 0); 50.1195 + svga_hwcursor.ena = mach64.gen_test_cntl & 0x80; 50.1196 + mach64_cursor_dump(); 50.1197 + break; 50.1198 + 50.1199 + case 0x100: case 0x101: case 0x102: case 0x103: 50.1200 + WRITE8(addr, mach64.dst_off_pitch, val); 50.1201 + break; 50.1202 + case 0x104: case 0x105: case 0x11c: case 0x11d: 50.1203 + WRITE8(addr + 2, mach64.dst_y_x, val); 50.1204 + break; 50.1205 + case 0x108: case 0x109: 50.1206 + WRITE8(addr, mach64.dst_y_x, val); 50.1207 + break; 50.1208 + case 0x10c: case 0x10d: case 0x10e: case 0x10f: 50.1209 + WRITE8(addr, mach64.dst_y_x, val); 50.1210 + break; 50.1211 + case 0x110: case 0x111: 50.1212 + addr += 2; 50.1213 + case 0x114: case 0x115: 50.1214 + case 0x118: case 0x119: case 0x11a: case 0x11b: 50.1215 + case 0x11e: case 0x11f: 50.1216 + WRITE8(addr, mach64.dst_height_width, val); 50.1217 + if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f) 50.1218 + { 50.1219 + mach64_start_fill(); 50.1220 +#ifdef MACH64_DEBUG 50.1221 + pclog("%i %i %i %i %i\n", (mach64.dst_height_width & 0x7ff), (mach64.dst_height_width & 0x7ff0000), 50.1222 + ((mach64.dp_src & 7) != SRC_HOST), (((mach64.dp_src >> 8) & 7) != SRC_HOST), 50.1223 + (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST)); 50.1224 +#endif 50.1225 + if ((mach64.dst_height_width & 0x7ff) && (mach64.dst_height_width & 0x7ff0000) && 50.1226 + ((mach64.dp_src & 7) != SRC_HOST) && (((mach64.dp_src >> 8) & 7) != SRC_HOST) && 50.1227 + (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST)) 50.1228 + mach64_blit(0, -1); 50.1229 + } 50.1230 + break; 50.1231 + 50.1232 + case 0x120: case 0x121: case 0x122: case 0x123: 50.1233 + WRITE8(addr, mach64.dst_bres_lnth, val); 50.1234 + if ((addr & 0x3ff) == 0x123 && !(val & 0x80)) 50.1235 + { 50.1236 + mach64_start_line(); 50.1237 + 50.1238 + if ((mach64.dst_bres_lnth & 0x7fff) && 50.1239 + ((mach64.dp_src & 7) != SRC_HOST) && (((mach64.dp_src >> 8) & 7) != SRC_HOST) && 50.1240 + (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST)) 50.1241 + mach64_blit(0, -1); 50.1242 + } 50.1243 + break; 50.1244 + case 0x124: case 0x125: case 0x126: case 0x127: 50.1245 + WRITE8(addr, mach64.dst_bres_err, val); 50.1246 + break; 50.1247 + case 0x128: case 0x129: case 0x12a: case 0x12b: 50.1248 + WRITE8(addr, mach64.dst_bres_inc, val); 50.1249 + break; 50.1250 + case 0x12c: case 0x12d: case 0x12e: case 0x12f: 50.1251 + WRITE8(addr, mach64.dst_bres_dec, val); 50.1252 + break; 50.1253 + 50.1254 + case 0x130: case 0x131: case 0x132: case 0x133: 50.1255 + WRITE8(addr, mach64.dst_cntl, val); 50.1256 + break; 50.1257 + 50.1258 + case 0x180: case 0x181: case 0x182: case 0x183: 50.1259 + WRITE8(addr, mach64.src_off_pitch, val); 50.1260 + break; 50.1261 + case 0x184: case 0x185: 50.1262 + WRITE8(addr, mach64.src_y_x, val); 50.1263 + break; 50.1264 + case 0x188: case 0x189: 50.1265 + WRITE8(addr + 2, mach64.src_y_x, val); 50.1266 + break; 50.1267 + case 0x18c: case 0x18d: case 0x18e: case 0x18f: 50.1268 + WRITE8(addr, mach64.src_y_x, val); 50.1269 + break; 50.1270 + 50.1271 + case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: 50.1272 + WRITE8(addr, mach64.src_cntl, val); 50.1273 + break; 50.1274 + 50.1275 + case 0x200: case 0x201: case 0x202: case 0x203: 50.1276 + case 0x204: case 0x205: case 0x206: case 0x207: 50.1277 + case 0x208: case 0x209: case 0x20a: case 0x20b: 50.1278 + case 0x20c: case 0x20d: case 0x20e: case 0x20f: 50.1279 + case 0x210: case 0x211: case 0x212: case 0x213: 50.1280 + case 0x214: case 0x215: case 0x216: case 0x217: 50.1281 + case 0x218: case 0x219: case 0x21a: case 0x21b: 50.1282 + case 0x21c: case 0x21d: case 0x21e: case 0x21f: 50.1283 + case 0x220: case 0x221: case 0x222: case 0x223: 50.1284 + case 0x224: case 0x225: case 0x226: case 0x227: 50.1285 + case 0x228: case 0x229: case 0x22a: case 0x22b: 50.1286 + case 0x22c: case 0x22d: case 0x22e: case 0x22f: 50.1287 + case 0x230: case 0x231: case 0x232: case 0x233: 50.1288 + case 0x234: case 0x235: case 0x236: case 0x237: 50.1289 + case 0x238: case 0x239: case 0x23a: case 0x23b: 50.1290 + case 0x23c: case 0x23d: case 0x23e: case 0x23f: 50.1291 + mach64_blit(val, 8); 50.1292 + break; 50.1293 + 50.1294 + case 0x280: case 0x281: case 0x282: case 0x283: 50.1295 + WRITE8(addr, mach64.pat_reg0, val); 50.1296 + break; 50.1297 + case 0x284: case 0x285: case 0x286: case 0x287: 50.1298 + WRITE8(addr, mach64.pat_reg1, val); 50.1299 + break; 50.1300 + 50.1301 + case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: 50.1302 + WRITE8(addr, mach64.sc_left_right, val); 50.1303 + break; 50.1304 + case 0x2a4: case 0x2a5: 50.1305 + addr += 2; 50.1306 + case 0x2aa: case 0x2ab: 50.1307 + WRITE8(addr, mach64.sc_left_right, val); 50.1308 + break; 50.1309 + 50.1310 + case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: 50.1311 + WRITE8(addr, mach64.sc_top_bottom, val); 50.1312 + break; 50.1313 + case 0x2b0: case 0x2b1: 50.1314 + addr += 2; 50.1315 + case 0x2b6: case 0x2b7: 50.1316 + WRITE8(addr, mach64.sc_top_bottom, val); 50.1317 + break; 50.1318 + 50.1319 + case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: 50.1320 + WRITE8(addr, mach64.dp_bkgd_clr, val); 50.1321 + break; 50.1322 + case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: 50.1323 + WRITE8(addr, mach64.dp_frgd_clr, val); 50.1324 + break; 50.1325 + 50.1326 + case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: 50.1327 + WRITE8(addr, mach64.dp_pix_width, val); 50.1328 + break; 50.1329 + case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: 50.1330 + WRITE8(addr, mach64.dp_mix, val); 50.1331 + break; 50.1332 + case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: 50.1333 + WRITE8(addr, mach64.dp_src, val); 50.1334 + break; 50.1335 + 50.1336 + case 0x320: case 0x321: case 0x322: case 0x323: 50.1337 + WRITE8(addr, mach64.context_mask, val); 50.1338 + break; 50.1339 + 50.1340 + case 0x330: case 0x331: 50.1341 + WRITE8(addr, mach64.dst_cntl, val); 50.1342 + break; 50.1343 + case 0x332: 50.1344 + WRITE8(addr - 2, mach64.src_cntl, val); 50.1345 + break; 50.1346 + case 0x333: 50.1347 + WRITE8(addr - 3, mach64.pat_cntl, val & 7); 50.1348 + break; 50.1349 + } 50.1350 +} 50.1351 +void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv) 50.1352 +{ 50.1353 +#ifdef MACH64_DEBUG 50.1354 + pclog("mach64_ext_writew : addr %08X val %04X\n", addr, val); 50.1355 +#endif 50.1356 + switch (addr & 0x3fe) 50.1357 + { 50.1358 + case 0x200: case 0x202: case 0x204: case 0x206: 50.1359 + case 0x208: case 0x20a: case 0x20c: case 0x20e: 50.1360 + case 0x210: case 0x212: case 0x214: case 0x216: 50.1361 + case 0x218: case 0x21a: case 0x21c: case 0x21e: 50.1362 + case 0x220: case 0x222: case 0x224: case 0x226: 50.1363 + case 0x228: case 0x22a: case 0x22c: case 0x22e: 50.1364 + case 0x230: case 0x232: case 0x234: case 0x236: 50.1365 + case 0x238: case 0x23a: case 0x23c: case 0x23e: 50.1366 + mach64_blit(val, 16); 50.1367 + break; 50.1368 + 50.1369 + default: 50.1370 +#ifdef MACH64_DEBUG 50.1371 + pclog(" "); 50.1372 +#endif 50.1373 + mach64_ext_writeb(addr, val, priv); 50.1374 +#ifdef MACH64_DEBUG 50.1375 + pclog(" "); 50.1376 +#endif 50.1377 + mach64_ext_writeb(addr + 1, val >> 8, priv); 50.1378 + break; 50.1379 + } 50.1380 +} 50.1381 +void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv) 50.1382 +{ 50.1383 +#ifdef MACH64_DEBUG 50.1384 + if ((addr & 0x3c0) != 0x200) 50.1385 + pclog("mach64_ext_writel : addr %08X val %08X\n", addr, val); 50.1386 +#endif 50.1387 + switch (addr & 0x3fc) 50.1388 + { 50.1389 + case 0x32c: 50.1390 + mach64.context_load_cntl = val; 50.1391 + if (val & 0x30000) 50.1392 + mach64_load_context(); 50.1393 + break; 50.1394 + 50.1395 + case 0x200: case 0x204: case 0x208: case 0x20c: 50.1396 + case 0x210: case 0x214: case 0x218: case 0x21c: 50.1397 + case 0x220: case 0x224: case 0x228: case 0x22c: 50.1398 + case 0x230: case 0x234: case 0x238: case 0x23c: 50.1399 + if (mach64.accel.source_host) 50.1400 + mach64_blit(val, 32); 50.1401 + else 50.1402 + mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32); 50.1403 + break; 50.1404 + 50.1405 + default: 50.1406 +#ifdef MACH64_DEBUG 50.1407 + pclog(" "); 50.1408 +#endif 50.1409 + mach64_ext_writew(addr, val, priv); 50.1410 +#ifdef MACH64_DEBUG 50.1411 + pclog(" "); 50.1412 +#endif 50.1413 + mach64_ext_writew(addr + 2, val >> 16, priv); 50.1414 + break; 50.1415 + } 50.1416 +} 50.1417 + 50.1418 +uint8_t mach64_ext_inb(uint16_t port, void *priv) 50.1419 +{ 50.1420 + uint8_t ret; 50.1421 +// if (CS == 0x2be7) output = 3; 50.1422 + switch (port) 50.1423 + { 50.1424 + case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: 50.1425 + ret = mach64_ext_readb(0x00 | (port & 3), NULL); 50.1426 + break; 50.1427 + case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: 50.1428 + ret = mach64_ext_readb(0x08 | (port & 3), NULL); 50.1429 + break; 50.1430 + case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: 50.1431 + ret = mach64_ext_readb(0x0c | (port & 3), NULL); 50.1432 + break; 50.1433 + 50.1434 + case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: 50.1435 + ret = mach64_ext_readb(0x14 | (port & 3), NULL); 50.1436 + break; 50.1437 + 50.1438 + case 0x1aec: 50.1439 + ret = mach64_ext_readb(0x18, NULL); 50.1440 + break; 50.1441 + 50.1442 + case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: 50.1443 + ret = mach64_ext_readb(0x1c | (port & 3), NULL); 50.1444 + break; 50.1445 + 50.1446 + case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: 50.1447 + ret = mach64_ext_readb(0x68 | (port & 3), NULL); 50.1448 + break; 50.1449 + case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: 50.1450 + ret = mach64_ext_readb(0x6c | (port & 3), NULL); 50.1451 + break; 50.1452 + case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: 50.1453 + ret = mach64_ext_readb(0x70 | (port & 3), NULL); 50.1454 + break; 50.1455 + 50.1456 + case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: 50.1457 + ret = mach64_ext_readb(0x80 | (port & 3), NULL); 50.1458 + break; 50.1459 + case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: 50.1460 + ret = mach64_ext_readb(0x84 | (port & 3), NULL); 50.1461 + break; 50.1462 + case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: 50.1463 + ret = mach64_ext_readb(0x90 | (port & 3), NULL); 50.1464 + break; 50.1465 + 50.1466 + case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: 50.1467 + ret = mach64_ext_readb(0xb0 | (port & 3), NULL); 50.1468 + break; 50.1469 + 50.1470 + case 0x56ec: 50.1471 + ret = mach64_ext_readb(0xb4, NULL); 50.1472 + break; 50.1473 + case 0x56ed: case 0x56ee: 50.1474 + ret = mach64_ext_readb(0xb5, NULL); 50.1475 + break; 50.1476 + case 0x5aec: 50.1477 + ret = mach64_ext_readb(0xb8, NULL); 50.1478 + break; 50.1479 + case 0x5aed: case 0x5aee: 50.1480 + ret = mach64_ext_readb(0xb9, NULL); 50.1481 + break; 50.1482 + 50.1483 + case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: 50.1484 + ret = ati68860_ramdac_in((port & 3) | ((mach64.dac_cntl & 3) << 2), NULL); 50.1485 + break; 50.1486 + 50.1487 + case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: 50.1488 + ret = mach64_ext_readb(0xc4 | (port & 3), NULL); 50.1489 + break; 50.1490 + 50.1491 + case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: 50.1492 + ret = mach64_ext_readb(0xd0 | (port & 3), NULL); 50.1493 + break; 50.1494 + 50.1495 + case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: 50.1496 + READ8(port, mach64.config_cntl); 50.1497 + break; 50.1498 + 50.1499 + case 0x6eec: case 0x6eed: case 0x6eee: case 0x6eef: 50.1500 + ret = mach64_ext_readb(0xe0 | (port & 3), NULL); 50.1501 + break; 50.1502 + 50.1503 + case 0x72ec: 50.1504 + ret = 6 | (3 << 3); /*VLB, 256Kx16 DRAM*/ 50.1505 + break; 50.1506 + 50.1507 + default: 50.1508 + ret = 0; 50.1509 + break; 50.1510 + } 50.1511 +#ifdef MACH64_DEBUG 50.1512 + pclog("mach64_ext_inb : port %04X ret %02X %04X:%04X\n", port, ret, CS,pc); 50.1513 +#endif 50.1514 + return ret; 50.1515 +} 50.1516 +uint16_t mach64_ext_inw(uint16_t port, void *priv) 50.1517 +{ 50.1518 + uint16_t ret; 50.1519 + switch (port) 50.1520 + { 50.1521 + default: 50.1522 + pclog(" "); 50.1523 + ret = mach64_ext_inb(port, priv); 50.1524 + pclog(" "); 50.1525 + ret |= (mach64_ext_inb(port + 1, priv) << 8); 50.1526 + break; 50.1527 + } 50.1528 +#ifdef MACH64_DEBUG 50.1529 + pclog("mach64_ext_inw : port %04X ret %04X\n", port, ret); 50.1530 +#endif 50.1531 + return ret; 50.1532 +} 50.1533 +uint32_t mach64_ext_inl(uint16_t port, void *priv) 50.1534 +{ 50.1535 + uint32_t ret; 50.1536 + switch (port) 50.1537 + { 50.1538 + case 0x56ec: 50.1539 + ret = mach64_ext_readl(0xb4, NULL); 50.1540 + break; 50.1541 + case 0x5aec: 50.1542 + ret = mach64_ext_readl(0xb8, NULL); 50.1543 + break; 50.1544 + 50.1545 + default: 50.1546 + pclog(" "); 50.1547 + ret = mach64_ext_inw(port, priv); 50.1548 + pclog(" "); 50.1549 + ret |= (mach64_ext_inw(port + 2, priv) << 16); 50.1550 + break; 50.1551 + } 50.1552 +#ifdef MACH64_DEBUG 50.1553 + pclog("mach64_ext_inl : port %04X ret %08X\n", port, ret); 50.1554 +#endif 50.1555 + return ret; 50.1556 +} 50.1557 + 50.1558 +void mach64_ext_outb(uint16_t port, uint8_t val, void *priv) 50.1559 +{ 50.1560 +#ifdef MACH64_DEBUG 50.1561 + pclog("mach64_ext_outb : port %04X val %02X %04X:%04X\n", port, val, CS,pc); 50.1562 +#endif 50.1563 + switch (port) 50.1564 + { 50.1565 + case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: 50.1566 + case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef: 50.1567 + mach64_ext_writeb(0x00 | (port & 3), val, NULL); 50.1568 + break; 50.1569 + case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: 50.1570 + mach64_ext_writeb(0x08 | (port & 3), val, NULL); 50.1571 + break; 50.1572 + case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: 50.1573 + mach64_ext_writeb(0x0c | (port & 3), val, NULL); 50.1574 + break; 50.1575 + 50.1576 + case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: 50.1577 + mach64_ext_writeb(0x14 | (port & 3), val, NULL); 50.1578 + break; 50.1579 + 50.1580 + case 0x1aec: 50.1581 + mach64_ext_writeb(0x18, val, NULL); 50.1582 + break; 50.1583 + 50.1584 + case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: 50.1585 + mach64_ext_writeb(0x1c | (port & 3), val, NULL); 50.1586 + break; 50.1587 + 50.1588 + case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: 50.1589 + mach64_ext_writeb(0x68 | (port & 3), val, NULL); 50.1590 + break; 50.1591 + case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: 50.1592 + mach64_ext_writeb(0x6c | (port & 3), val, NULL); 50.1593 + break; 50.1594 + case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: 50.1595 + mach64_ext_writeb(0x70 | (port & 3), val, NULL); 50.1596 + break; 50.1597 + 50.1598 + case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: 50.1599 + mach64_ext_writeb(0x80 | (port & 3), val, NULL); 50.1600 + break; 50.1601 + case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: 50.1602 + mach64_ext_writeb(0x84 | (port & 3), val, NULL); 50.1603 + break; 50.1604 + case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: 50.1605 + mach64_ext_writeb(0x90 | (port & 3), val, NULL); 50.1606 + break; 50.1607 + 50.1608 + case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: 50.1609 + mach64_ext_writeb(0xb0 | (port & 3), val, NULL); 50.1610 + break; 50.1611 + 50.1612 + case 0x56ec: 50.1613 + mach64_ext_writeb(0xb4, val, NULL); 50.1614 + break; 50.1615 + case 0x56ed: case 0x56ee: 50.1616 + mach64_ext_writeb(0xb5, val, NULL); 50.1617 + break; 50.1618 + case 0x5aec: 50.1619 + mach64_ext_writeb(0xb8, val, NULL); 50.1620 + break; 50.1621 + case 0x5aed: case 0x5aee: 50.1622 + mach64_ext_writeb(0xb9, val, NULL); 50.1623 + break; 50.1624 + 50.1625 + case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: 50.1626 + ati68860_ramdac_out((port & 3) | ((mach64.dac_cntl & 3) << 2), val, NULL); 50.1627 + break; 50.1628 + 50.1629 + case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: 50.1630 + mach64_ext_writeb(0xc4 | (port & 3), val, NULL); 50.1631 + break; 50.1632 + 50.1633 + case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: 50.1634 + mach64_ext_writeb(0xd0 | (port & 3), val, NULL); 50.1635 + break; 50.1636 + 50.1637 + case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: 50.1638 + WRITE8(port, mach64.config_cntl, val); 50.1639 + break; 50.1640 + } 50.1641 +} 50.1642 +void mach64_ext_outw(uint16_t port, uint16_t val, void *priv) 50.1643 +{ 50.1644 +#ifdef MACH64_DEBUG 50.1645 + pclog("mach64_ext_outw : port %04X val %04X\n", port, val); 50.1646 +#endif 50.1647 + switch (port) 50.1648 + { 50.1649 + default: 50.1650 +#ifdef MACH64_DEBUG 50.1651 + pclog(" "); 50.1652 +#endif 50.1653 + mach64_ext_outb(port, val, priv); 50.1654 +#ifdef MACH64_DEBUG 50.1655 + pclog(" "); 50.1656 +#endif 50.1657 + mach64_ext_outb(port + 1, val >> 8, priv); 50.1658 + break; 50.1659 + } 50.1660 +} 50.1661 +void mach64_ext_outl(uint16_t port, uint32_t val, void *priv) 50.1662 +{ 50.1663 + pclog("mach64_ext_outl : port %04X val %08X\n", port, val); 50.1664 + switch (port) 50.1665 + { 50.1666 + default: 50.1667 +#ifdef MACH64_DEBUG 50.1668 + pclog(" "); 50.1669 +#endif 50.1670 + mach64_ext_outw(port, val, priv); 50.1671 +#ifdef MACH64_DEBUG 50.1672 + pclog(" "); 50.1673 +#endif 50.1674 + mach64_ext_outw(port + 2, val >> 16, priv); 50.1675 + break; 50.1676 + } 50.1677 +} 50.1678 + 50.1679 +void mach64_write(uint32_t addr, uint8_t val, void *priv) 50.1680 +{ 50.1681 +// pclog("mach64_write : %05X %02X ", addr, val); 50.1682 + addr = (addr & 0x7fff) + mach64_bank_w[(addr >> 15) & 1]; 50.1683 +// pclog("%08X\n", addr); 50.1684 + svga_write_linear(addr, val, priv); 50.1685 +} 50.1686 + 50.1687 +uint8_t mach64_read(uint32_t addr, void *priv) 50.1688 +{ 50.1689 + uint8_t ret; 50.1690 +// pclog("mach64_read : %05X ", addr); 50.1691 + addr = (addr & 0x7fff) + mach64_bank_r[(addr >> 15) & 1]; 50.1692 + ret = svga_read_linear(addr, priv); 50.1693 +// pclog("%08X %02X\n", addr, ret); 50.1694 + return ret; 50.1695 +} 50.1696 + 50.1697 +void mach64_hwcursor_draw(int displine) 50.1698 +{ 50.1699 + int x, offset; 50.1700 + uint8_t dat; 50.1701 + offset = svga_hwcursor_latch.xoff; 50.1702 + for (x = 0; x < 64 - svga_hwcursor_latch.xoff; x += 4) 50.1703 + { 50.1704 + dat = vram[svga_hwcursor_latch.addr + (offset >> 2)]; 50.1705 + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0; 50.1706 + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32] ^= 0xFFFFFF; 50.1707 + dat >>= 2; 50.1708 + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0; 50.1709 + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33] ^= 0xFFFFFF; 50.1710 + dat >>= 2; 50.1711 + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0; 50.1712 + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34] ^= 0xFFFFFF; 50.1713 + dat >>= 2; 50.1714 + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0; 50.1715 + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35] ^= 0xFFFFFF; 50.1716 + dat >>= 2; 50.1717 + offset += 4; 50.1718 + } 50.1719 + svga_hwcursor_latch.addr += 16; 50.1720 +} 50.1721 + 50.1722 +int mach64_init() 50.1723 +{ 50.1724 + int c; 50.1725 + 50.1726 + svga_recalctimings_ex = mach64_recalctimings; 50.1727 + svga_hwcursor_draw = mach64_hwcursor_draw; 50.1728 + 50.1729 + svga_vram_limit = 1 << 22; /*4mb*/ 50.1730 + vrammask = 0x3fffff; 50.1731 + 50.1732 + for (c = 0; c < 8; c++) 50.1733 + { 50.1734 + io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL); 50.1735 + io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL); 50.1736 + io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL); 50.1737 + io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL); 50.1738 + } 50.1739 + 50.1740 + io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, NULL); 50.1741 + 50.1742 + ati_eeprom_load("mach64.nvr", 1); 50.1743 + 50.1744 + mach64.dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ 50.1745 + 50.1746 + mach64.dst_cntl = 3; 50.1747 + return svga_init(); 50.1748 +} 50.1749 + 50.1750 +GFXCARD vid_mach64 = 50.1751 +{ 50.1752 + mach64_init, 50.1753 + /*IO at 3Cx/3Dx*/ 50.1754 + mach64_out, 50.1755 + mach64_in, 50.1756 + /*IO at 3Ax/3Bx*/ 50.1757 + video_out_null, 50.1758 + video_in_null, 50.1759 + 50.1760 + svga_poll, 50.1761 + svga_recalctimings, 50.1762 + 50.1763 + svga_write, 50.1764 + video_write_null, 50.1765 + video_write_null, 50.1766 + 50.1767 + svga_read, 50.1768 + video_read_null, 50.1769 + video_read_null 50.1770 +};
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/src/vid_cl5429.c Mon May 27 19:56:33 2013 +0100 51.3 @@ -0,0 +1,850 @@ 51.4 +/*Cirrus Logic CL-GD5429 emulation*/ 51.5 +#include "ibm.h" 51.6 +#include "io.h" 51.7 +#include "mem.h" 51.8 +#include "video.h" 51.9 +#include "vid_svga.h" 51.10 +#include "vid_svga_render.h" 51.11 +#include "vid_unk_ramdac.h" 51.12 + 51.13 +struct 51.14 +{ 51.15 + uint32_t bank[2]; 51.16 + 51.17 + struct 51.18 + { 51.19 + uint16_t bg_col, fg_col; 51.20 + uint16_t width, height; 51.21 + uint16_t dst_pitch, src_pitch; 51.22 + uint32_t dst_addr, src_addr; 51.23 + uint8_t mask, mode, rop; 51.24 + 51.25 + uint32_t dst_addr_backup, src_addr_backup; 51.26 + uint16_t width_backup, height_internal; 51.27 + int x_count; 51.28 + } blt; 51.29 + 51.30 +} gd5429; 51.31 + 51.32 +void gd5429_write(uint32_t addr, uint8_t val, void *priv); 51.33 +uint8_t gd5429_read(uint32_t addr, void *priv); 51.34 + 51.35 +void gd5429_mmio_write(uint32_t addr, uint8_t val, void *priv); 51.36 +uint8_t gd5429_mmio_read(uint32_t addr, void *priv); 51.37 + 51.38 +void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *priv); 51.39 +void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *priv); 51.40 + 51.41 +void gd5429_recalc_banking(); 51.42 +void gd5429_recalc_mapping(); 51.43 + 51.44 +void gd5429_out(uint16_t addr, uint8_t val, void *priv) 51.45 +{ 51.46 + uint8_t old; 51.47 + 51.48 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 51.49 + 51.50 + pclog("gd5429 out %04X %02X\n", addr, val); 51.51 + 51.52 + switch (addr) 51.53 + { 51.54 + case 0x3c4: 51.55 + seqaddr = val; 51.56 + break; 51.57 + case 0x3c5: 51.58 + if (seqaddr > 5) 51.59 + { 51.60 + seqregs[seqaddr & 0x1f] = val; 51.61 + switch (seqaddr & 0x1f) 51.62 + { 51.63 + case 0x10: case 0x30: case 0x50: case 0x70: 51.64 + case 0x90: case 0xb0: case 0xd0: case 0xf0: 51.65 + svga_hwcursor.x = (val << 3) | ((seqaddr >> 5) & 7); 51.66 + pclog("svga_hwcursor.x = %i\n", svga_hwcursor.x); 51.67 + break; 51.68 + case 0x11: case 0x31: case 0x51: case 0x71: 51.69 + case 0x91: case 0xb1: case 0xd1: case 0xf1: 51.70 + svga_hwcursor.y = (val << 3) | ((seqaddr >> 5) & 7); 51.71 + pclog("svga_hwcursor.y = %i\n", svga_hwcursor.y); 51.72 + break; 51.73 + case 0x12: 51.74 + svga_hwcursor.ena = val & 1; 51.75 + pclog("svga_hwcursor.ena = %i\n", svga_hwcursor.ena); 51.76 + break; 51.77 + case 0x13: 51.78 + svga_hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256); 51.79 + pclog("svga_hwcursor.addr = %x\n", svga_hwcursor.addr); 51.80 + break; 51.81 + 51.82 + case 0x17: 51.83 + gd5429_recalc_mapping(); 51.84 + break; 51.85 + } 51.86 + return; 51.87 + } 51.88 + break; 51.89 + 51.90 + case 0x3cf: 51.91 + if (gdcaddr == 5) 51.92 + { 51.93 + gdcreg[5] = val; 51.94 + if (gdcreg[0xb] & 0x04) 51.95 + writemode = gdcreg[5] & 7; 51.96 + else 51.97 + writemode = gdcreg[5] & 3; 51.98 + readmode = val & 8; 51.99 + pclog("writemode = %i\n", writemode); 51.100 + return; 51.101 + } 51.102 + if (gdcaddr == 6) 51.103 + { 51.104 + if ((gdcreg[6] & 0xc) != (val & 0xc)) 51.105 + { 51.106 + gdcreg[6] = val; 51.107 + gd5429_recalc_mapping(); 51.108 + } 51.109 + gdcreg[6] = val; 51.110 + return; 51.111 + } 51.112 + if (gdcaddr > 8) 51.113 + { 51.114 + gdcreg[gdcaddr & 0x3f] = val; 51.115 + switch (gdcaddr) 51.116 + { 51.117 + case 0x09: case 0x0a: case 0x0b: 51.118 + gd5429_recalc_banking(); 51.119 + if (gdcreg[0xb] & 0x04) 51.120 + writemode = gdcreg[5] & 7; 51.121 + else 51.122 + writemode = gdcreg[5] & 3; 51.123 + break; 51.124 + } 51.125 + return; 51.126 + } 51.127 + break; 51.128 + 51.129 + case 0x3D4: 51.130 + crtcreg = val & 0x3f; 51.131 + return; 51.132 + case 0x3D5: 51.133 + if (crtcreg <= 7 && crtc[0x11] & 0x80) return; 51.134 + old=crtc[crtcreg]; 51.135 + crtc[crtcreg]=val; 51.136 + 51.137 + if (old!=val) 51.138 + { 51.139 + if (crtcreg<0xE || crtcreg>0x10) 51.140 + { 51.141 + fullchange=changeframecount; 51.142 + svga_recalctimings(); 51.143 + } 51.144 + } 51.145 + break; 51.146 + } 51.147 + svga_out(addr, val, NULL); 51.148 +} 51.149 + 51.150 +uint8_t gd5429_in(uint16_t addr, void *priv) 51.151 +{ 51.152 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 51.153 + 51.154 + if (addr != 0x3da) pclog("IN gd5429 %04X\n", addr); 51.155 + 51.156 + switch (addr) 51.157 + { 51.158 + case 0x3c5: 51.159 + if (seqaddr > 5) 51.160 + { 51.161 + switch (seqaddr) 51.162 + { 51.163 + case 6: 51.164 + return ((seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; 51.165 + } 51.166 + return seqregs[seqaddr & 0x3f]; 51.167 + } 51.168 + break; 51.169 + 51.170 + case 0x3cf: 51.171 + if (gdcaddr > 8) 51.172 + { 51.173 + return gdcreg[seqaddr & 0x3f]; 51.174 + } 51.175 + break; 51.176 + 51.177 + case 0x3D4: 51.178 + return crtcreg; 51.179 + case 0x3D5: 51.180 + switch (crtcreg) 51.181 + { 51.182 + case 0x27: /*ID*/ 51.183 + return 0x9c; /*GD5429*/ 51.184 + } 51.185 + return crtc[crtcreg]; 51.186 + } 51.187 + return svga_in(addr, NULL); 51.188 +} 51.189 + 51.190 +void gd5429_recalc_banking() 51.191 +{ 51.192 + if (gdcreg[0xb] & 0x20) 51.193 + gd5429.bank[0] = (gdcreg[0x09] & 0x7f) << 14; 51.194 + else 51.195 + gd5429.bank[0] = gdcreg[0x09] << 12; 51.196 + 51.197 + if (gdcreg[0xb] & 0x01) 51.198 + { 51.199 + if (gdcreg[0xb] & 0x20) 51.200 + gd5429.bank[1] = (gdcreg[0x0a] & 0x7f) << 14; 51.201 + else 51.202 + gd5429.bank[1] = gdcreg[0x0a] << 12; 51.203 + } 51.204 + else 51.205 + gd5429.bank[1] = gd5429.bank[0] + 0x8000; 51.206 +} 51.207 + 51.208 +void gd5429_recalc_mapping() 51.209 +{ 51.210 + mem_removehandler(0xa0000, 0x20000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, NULL); 51.211 + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 51.212 + mem_removehandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, NULL); 51.213 + pclog("Write mapping %02X %i\n", gdcreg[6], seqregs[0x17] & 0x04); 51.214 + switch (gdcreg[6] & 0x0C) 51.215 + { 51.216 + case 0x0: /*128k at A0000*/ 51.217 + mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, NULL); 51.218 + break; 51.219 + case 0x4: /*64k at A0000*/ 51.220 + mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, NULL); 51.221 + if (seqregs[0x17] & 0x04) 51.222 + mem_sethandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, NULL); 51.223 + break; 51.224 + case 0x8: /*32k at B0000*/ 51.225 + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 51.226 + break; 51.227 + case 0xC: /*32k at B8000*/ 51.228 + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 51.229 + break; 51.230 + } 51.231 +} 51.232 + 51.233 +void gd5429_recalctimings() 51.234 +{ 51.235 + if (seqregs[7] & 0x01) 51.236 + { 51.237 + svga_render = svga_render_8bpp_highres; 51.238 + } 51.239 + 51.240 + svga_ma |= ((crtc[0x1b] & 0x01) << 16) | ((crtc[0x1b] & 0xc) << 15); 51.241 + pclog("MA now %05X %02X\n", svga_ma, crtc[0x1b]); 51.242 +} 51.243 + 51.244 +void gd5429_hwcursor_draw(int displine) 51.245 +{ 51.246 + int x; 51.247 + uint8_t dat[2]; 51.248 + int xx; 51.249 + int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff; 51.250 + 51.251 + pclog("HWcursor %i %i %i %i %x %02X %02X\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y, offset, displine, svga_hwcursor_latch.addr, vram[svga_hwcursor_latch.addr], vram[svga_hwcursor_latch.addr + 0x80]); 51.252 + for (x = 0; x < 32; x += 8) 51.253 + { 51.254 + dat[0] = vram[svga_hwcursor_latch.addr]; 51.255 + dat[1] = vram[svga_hwcursor_latch.addr + 0x80]; 51.256 + for (xx = 0; xx < 8; xx++) 51.257 + { 51.258 + if (offset >= svga_hwcursor_latch.x) 51.259 + { 51.260 + if (dat[1] & 0x80) 51.261 + ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; 51.262 + if (dat[0] & 0x80) 51.263 + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; 51.264 + } 51.265 + 51.266 + offset++; 51.267 + dat[0] <<= 1; 51.268 + dat[1] <<= 1; 51.269 + } 51.270 + svga_hwcursor_latch.addr++; 51.271 + } 51.272 +} 51.273 + 51.274 +int gd5429_init() 51.275 +{ 51.276 + svga_recalctimings_ex = gd5429_recalctimings; 51.277 + svga_hwcursor_draw = gd5429_hwcursor_draw; 51.278 + svga_vram_limit = 2 << 20; /*2mb*/ 51.279 + vrammask = 0x1fffff; 51.280 + 51.281 + svga_hwcursor.yoff = 32; 51.282 + svga_hwcursor.xoff = 0; 51.283 + 51.284 + memset(&gd5429, 0, sizeof(gd5429)); 51.285 + 51.286 + gd5429.bank[1] = 0x8000; 51.287 + 51.288 + return svga_init(); 51.289 +} 51.290 + 51.291 +static uint8_t la, lb, lc, ld; 51.292 + 51.293 +uint8_t gd5429_read_linear(uint32_t addr, void *priv); 51.294 +void gd5429_write_linear(uint32_t addr, uint8_t val, void *priv); 51.295 + 51.296 +void gd5429_write(uint32_t addr, uint8_t val, void *priv) 51.297 +{ 51.298 +// pclog("gd5429_write : %05X %02X ", addr, val); 51.299 + addr = (addr & 0x7fff) + gd5429.bank[(addr >> 15) & 1]; 51.300 +// pclog("%08X\n", addr); 51.301 + gd5429_write_linear(addr, val, priv); 51.302 +} 51.303 + 51.304 +uint8_t gd5429_read(uint32_t addr, void *priv) 51.305 +{ 51.306 + uint8_t ret; 51.307 +// pclog("gd5429_read : %05X ", addr); 51.308 + addr = (addr & 0x7fff) + gd5429.bank[(addr >> 15) & 1]; 51.309 + ret = gd5429_read_linear(addr, priv); 51.310 +// pclog("%08X %02X\n", addr, ret); 51.311 + return ret; 51.312 +} 51.313 + 51.314 +void gd5429_write_linear(uint32_t addr, uint8_t val, void *priv) 51.315 +{ 51.316 + uint8_t vala,valb,valc,vald,wm=writemask; 51.317 + int writemask2 = writemask; 51.318 + 51.319 + cycles -= video_timing_b; 51.320 + cycles_lost += video_timing_b; 51.321 + 51.322 + egawrites++; 51.323 + 51.324 +// if (svga_output) pclog("Write LFB %08X %02X ", addr, val); 51.325 + if (!(gdcreg[6]&1)) fullchange=2; 51.326 + if (chain4 && (writemode < 4)) 51.327 + { 51.328 + writemask2=1<<(addr&3); 51.329 + addr&=~3; 51.330 + } 51.331 + else 51.332 + { 51.333 + addr<<=2; 51.334 + } 51.335 + addr &= 0x7fffff; 51.336 +// if (svga_output) pclog("%08X\n", addr); 51.337 + changedvram[addr>>10]=changeframecount; 51.338 + 51.339 + switch (writemode) 51.340 + { 51.341 + case 4: 51.342 + pclog("Writemode 4 : %X ", addr); 51.343 + addr <<= 1; 51.344 + changedvram[addr>>10]=changeframecount; 51.345 + pclog("%X %X\n", addr, val); 51.346 + if (val & 0x80) 51.347 + vram[addr + 0] = gdcreg[1]; 51.348 + if (val & 0x40) 51.349 + vram[addr + 1] = gdcreg[1]; 51.350 + if (val & 0x20) 51.351 + vram[addr + 2] = gdcreg[1]; 51.352 + if (val & 0x10) 51.353 + vram[addr + 3] = gdcreg[1]; 51.354 + if (val & 0x08) 51.355 + vram[addr + 4] = gdcreg[1]; 51.356 + if (val & 0x04) 51.357 + vram[addr + 5] = gdcreg[1]; 51.358 + if (val & 0x02) 51.359 + vram[addr + 6] = gdcreg[1]; 51.360 + if (val & 0x01) 51.361 + vram[addr + 7] = gdcreg[1]; 51.362 + break; 51.363 + 51.364 + case 5: 51.365 + pclog("Writemode 5 : %X ", addr); 51.366 + addr <<= 1; 51.367 + changedvram[addr>>10]=changeframecount; 51.368 + pclog("%X %X\n", addr, val); 51.369 + vram[addr + 0] = (val & 0x80) ? gdcreg[1] : gdcreg[0]; 51.370 + vram[addr + 1] = (val & 0x40) ? gdcreg[1] : gdcreg[0]; 51.371 + vram[addr + 2] = (val & 0x20) ? gdcreg[1] : gdcreg[0]; 51.372 + vram[addr + 3] = (val & 0x10) ? gdcreg[1] : gdcreg[0]; 51.373 + vram[addr + 4] = (val & 0x08) ? gdcreg[1] : gdcreg[0]; 51.374 + vram[addr + 5] = (val & 0x04) ? gdcreg[1] : gdcreg[0]; 51.375 + vram[addr + 6] = (val & 0x02) ? gdcreg[1] : gdcreg[0]; 51.376 + vram[addr + 7] = (val & 0x01) ? gdcreg[1] : gdcreg[0]; 51.377 + break; 51.378 + 51.379 + case 1: 51.380 + if (writemask2&1) vram[addr]=la; 51.381 + if (writemask2&2) vram[addr|0x1]=lb; 51.382 + if (writemask2&4) vram[addr|0x2]=lc; 51.383 + if (writemask2&8) vram[addr|0x3]=ld; 51.384 + break; 51.385 + case 0: 51.386 + if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val]; 51.387 + if (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) 51.388 + { 51.389 + if (writemask2&1) vram[addr]=val; 51.390 + if (writemask2&2) vram[addr|0x1]=val; 51.391 + if (writemask2&4) vram[addr|0x2]=val; 51.392 + if (writemask2&8) vram[addr|0x3]=val; 51.393 + } 51.394 + else 51.395 + { 51.396 + if (gdcreg[1]&1) vala=(gdcreg[0]&1)?0xFF:0; 51.397 + else vala=val; 51.398 + if (gdcreg[1]&2) valb=(gdcreg[0]&2)?0xFF:0; 51.399 + else valb=val; 51.400 + if (gdcreg[1]&4) valc=(gdcreg[0]&4)?0xFF:0; 51.401 + else valc=val; 51.402 + if (gdcreg[1]&8) vald=(gdcreg[0]&8)?0xFF:0; 51.403 + else vald=val; 51.404 + 51.405 + switch (gdcreg[3]&0x18) 51.406 + { 51.407 + case 0: /*Set*/ 51.408 + if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); 51.409 + if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); 51.410 + if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); 51.411 + if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); 51.412 + break; 51.413 + case 8: /*AND*/ 51.414 + if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; 51.415 + if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; 51.416 + if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; 51.417 + if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; 51.418 + break; 51.419 + case 0x10: /*OR*/ 51.420 + if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; 51.421 + if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; 51.422 + if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; 51.423 + if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; 51.424 + break; 51.425 + case 0x18: /*XOR*/ 51.426 + if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; 51.427 + if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; 51.428 + if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; 51.429 + if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; 51.430 + break; 51.431 + } 51.432 +// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); 51.433 + } 51.434 + break; 51.435 + case 2: 51.436 + if (!(gdcreg[3]&0x18) && !gdcreg[1]) 51.437 + { 51.438 + if (writemask2&1) vram[addr]=(((val&1)?0xFF:0)&gdcreg[8])|(la&~gdcreg[8]); 51.439 + if (writemask2&2) vram[addr|0x1]=(((val&2)?0xFF:0)&gdcreg[8])|(lb&~gdcreg[8]); 51.440 + if (writemask2&4) vram[addr|0x2]=(((val&4)?0xFF:0)&gdcreg[8])|(lc&~gdcreg[8]); 51.441 + if (writemask2&8) vram[addr|0x3]=(((val&8)?0xFF:0)&gdcreg[8])|(ld&~gdcreg[8]); 51.442 + } 51.443 + else 51.444 + { 51.445 + vala=((val&1)?0xFF:0); 51.446 + valb=((val&2)?0xFF:0); 51.447 + valc=((val&4)?0xFF:0); 51.448 + vald=((val&8)?0xFF:0); 51.449 + switch (gdcreg[3]&0x18) 51.450 + { 51.451 + case 0: /*Set*/ 51.452 + if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); 51.453 + if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); 51.454 + if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); 51.455 + if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); 51.456 + break; 51.457 + case 8: /*AND*/ 51.458 + if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; 51.459 + if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; 51.460 + if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; 51.461 + if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; 51.462 + break; 51.463 + case 0x10: /*OR*/ 51.464 + if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; 51.465 + if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; 51.466 + if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; 51.467 + if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; 51.468 + break; 51.469 + case 0x18: /*XOR*/ 51.470 + if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; 51.471 + if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; 51.472 + if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; 51.473 + if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; 51.474 + break; 51.475 + } 51.476 + } 51.477 + break; 51.478 + case 3: 51.479 + if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val]; 51.480 + wm=gdcreg[8]; 51.481 + gdcreg[8]&=val; 51.482 + 51.483 + vala=(gdcreg[0]&1)?0xFF:0; 51.484 + valb=(gdcreg[0]&2)?0xFF:0; 51.485 + valc=(gdcreg[0]&4)?0xFF:0; 51.486 + vald=(gdcreg[0]&8)?0xFF:0; 51.487 + switch (gdcreg[3]&0x18) 51.488 + { 51.489 + case 0: /*Set*/ 51.490 + if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]); 51.491 + if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]); 51.492 + if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]); 51.493 + if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]); 51.494 + break; 51.495 + case 8: /*AND*/ 51.496 + if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la; 51.497 + if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb; 51.498 + if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc; 51.499 + if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld; 51.500 + break; 51.501 + case 0x10: /*OR*/ 51.502 + if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la; 51.503 + if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb; 51.504 + if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc; 51.505 + if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld; 51.506 + break; 51.507 + case 0x18: /*XOR*/ 51.508 + if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la; 51.509 + if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb; 51.510 + if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc; 51.511 + if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld; 51.512 + break; 51.513 + } 51.514 + gdcreg[8]=wm; 51.515 + break; 51.516 + } 51.517 +} 51.518 + 51.519 +uint8_t gd5429_read_linear(uint32_t addr, void *priv) 51.520 +{ 51.521 + uint8_t temp,temp2,temp3,temp4; 51.522 + 51.523 + cycles -= video_timing_b; 51.524 + cycles_lost += video_timing_b; 51.525 + 51.526 + egareads++; 51.527 + 51.528 + if (chain4) 51.529 + { 51.530 + addr &= 0x7fffff; 51.531 + if (addr >= svga_vram_limit) 51.532 + return 0xff; 51.533 + return vram[addr & 0x7fffff]; 51.534 + } 51.535 + else addr<<=2; 51.536 + 51.537 + addr &= 0x7fffff; 51.538 + 51.539 + if (addr >= svga_vram_limit) 51.540 + return 0xff; 51.541 + 51.542 + la=vram[addr]; 51.543 + lb=vram[addr|0x1]; 51.544 + lc=vram[addr|0x2]; 51.545 + ld=vram[addr|0x3]; 51.546 + if (readmode) 51.547 + { 51.548 + temp= (colournocare&1) ?0xFF:0; 51.549 + temp&=la; 51.550 + temp^=(colourcompare&1)?0xFF:0; 51.551 + temp2= (colournocare&2) ?0xFF:0; 51.552 + temp2&=lb; 51.553 + temp2^=(colourcompare&2)?0xFF:0; 51.554 + temp3= (colournocare&4) ?0xFF:0; 51.555 + temp3&=lc; 51.556 + temp3^=(colourcompare&4)?0xFF:0; 51.557 + temp4= (colournocare&8) ?0xFF:0; 51.558 + temp4&=ld; 51.559 + temp4^=(colourcompare&8)?0xFF:0; 51.560 + return ~(temp|temp2|temp3|temp4); 51.561 + } 51.562 +//printf("Read %02X %04X %04X\n",vram[addr|readplane],addr,readplane); 51.563 + return vram[addr|readplane]; 51.564 +} 51.565 + 51.566 +void gd5429_start_blit(uint32_t cpu_dat, int count) 51.567 +{ 51.568 + pclog("gd5429_start_blit %i\n", count); 51.569 + if (count == -1) 51.570 + { 51.571 + gd5429.blt.dst_addr_backup = gd5429.blt.dst_addr; 51.572 + gd5429.blt.src_addr_backup = gd5429.blt.src_addr; 51.573 + gd5429.blt.width_backup = gd5429.blt.width; 51.574 + gd5429.blt.height_internal = gd5429.blt.height; 51.575 + gd5429.blt.x_count = gd5429.blt.mask & 7; 51.576 + pclog("gd5429_start_blit : size %i, %i\n", gd5429.blt.width, gd5429.blt.height); 51.577 + 51.578 + if (gd5429.blt.mode & 0x04) 51.579 + { 51.580 +// pclog("blt.mode & 0x04\n"); 51.581 + mem_removehandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL, NULL); 51.582 + mem_sethandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l, NULL); 51.583 + return; 51.584 + } 51.585 + else 51.586 + { 51.587 + mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l, NULL); 51.588 + gd5429_recalc_mapping(); 51.589 + } 51.590 + } 51.591 + 51.592 + while (count) 51.593 + { 51.594 + uint8_t src, dst; 51.595 + int mask; 51.596 + 51.597 + if (gd5429.blt.mode & 0x04) 51.598 + { 51.599 + if (gd5429.blt.mode & 0x80) 51.600 + { 51.601 + src = (cpu_dat & 0x80) ? gd5429.blt.fg_col : gd5429.blt.bg_col; 51.602 + mask = cpu_dat & 0x80; 51.603 + cpu_dat <<= 1; 51.604 + count--; 51.605 + } 51.606 + else 51.607 + { 51.608 + src = cpu_dat & 0xff; 51.609 + cpu_dat >>= 8; 51.610 + count -= 8; 51.611 + mask = 1; 51.612 + } 51.613 + } 51.614 + else 51.615 + { 51.616 + switch (gd5429.blt.mode & 0xc0) 51.617 + { 51.618 + case 0x00: 51.619 + src = vram[gd5429.blt.src_addr & vrammask]; 51.620 + gd5429.blt.src_addr += ((gd5429.blt.mode & 0x01) ? -1 : 1); 51.621 + mask = 1; 51.622 + break; 51.623 + case 0x40: 51.624 + src = vram[(gd5429.blt.src_addr & (vrammask & ~7)) | (gd5429.blt.dst_addr & 7)]; 51.625 + mask = 1; 51.626 + break; 51.627 + case 0x80: 51.628 + mask = vram[gd5429.blt.src_addr & vrammask] & (0x80 >> gd5429.blt.x_count); 51.629 + src = mask ? gd5429.blt.fg_col : gd5429.blt.bg_col; 51.630 + gd5429.blt.x_count++; 51.631 + if (gd5429.blt.x_count == 8) 51.632 + { 51.633 + gd5429.blt.x_count = 0; 51.634 + gd5429.blt.src_addr++; 51.635 + } 51.636 + break; 51.637 + case 0xc0: 51.638 + mask = vram[gd5429.blt.src_addr & vrammask] & (0x80 >> (gd5429.blt.dst_addr & 7)); 51.639 + src = mask ? gd5429.blt.fg_col : gd5429.blt.bg_col; 51.640 + break; 51.641 + } 51.642 + count--; 51.643 + } 51.644 + dst = vram[gd5429.blt.dst_addr & vrammask]; 51.645 + changedvram[(gd5429.blt.dst_addr & vrammask) >> 10] = changeframecount; 51.646 + 51.647 + pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429.blt.width, gd5429.blt.height_internal, gd5429.blt.src_addr, gd5429.blt.dst_addr, gd5429.blt.src_addr & vrammask, vram[gd5429.blt.src_addr & vrammask], 0x80 >> (gd5429.blt.dst_addr & 7), src, dst); 51.648 + switch (gd5429.blt.rop) 51.649 + { 51.650 + case 0x00: dst = 0; break; 51.651 + case 0x05: dst = src & dst; break; 51.652 + case 0x06: dst = dst; break; 51.653 + case 0x09: dst = src & ~dst; break; 51.654 + case 0x0b: dst = ~ dst; break; 51.655 + case 0x0d: dst = src; break; 51.656 + case 0x0e: dst = 0xff; break; 51.657 + case 0x50: dst = ~ src & dst; break; 51.658 + case 0x59: dst = src ^ dst; break; 51.659 + case 0x6d: dst = src | dst; break; 51.660 + case 0x90: dst = ~(src | dst); break; 51.661 + case 0x95: dst = ~(src ^ dst); break; 51.662 + case 0xad: dst = src | ~dst; break; 51.663 + case 0xd0: dst = ~src; break; 51.664 + case 0xd6: dst = ~src | dst; break; 51.665 + case 0xda: dst = ~(src & dst); break; 51.666 + } 51.667 + pclog("%02X %02X\n", dst, mask); 51.668 + 51.669 + if ((gd5429.blt.width_backup - gd5429.blt.width) >= (gd5429.blt.mask & 7) && 51.670 + !((gd5429.blt.mode & 0x08) && !mask)) 51.671 + vram[gd5429.blt.dst_addr & vrammask] = dst; 51.672 + 51.673 + gd5429.blt.dst_addr += ((gd5429.blt.mode & 0x01) ? -1 : 1); 51.674 + 51.675 + gd5429.blt.width--; 51.676 + 51.677 + if (gd5429.blt.width == 0xffff) 51.678 + { 51.679 + gd5429.blt.width = gd5429.blt.width_backup; 51.680 + 51.681 + gd5429.blt.dst_addr = gd5429.blt.dst_addr_backup = gd5429.blt.dst_addr_backup + ((gd5429.blt.mode & 0x01) ? -gd5429.blt.dst_pitch : gd5429.blt.dst_pitch); 51.682 + 51.683 + switch (gd5429.blt.mode & 0xc0) 51.684 + { 51.685 + case 0x00: 51.686 + gd5429.blt.src_addr = gd5429.blt.src_addr_backup = gd5429.blt.src_addr_backup + ((gd5429.blt.mode & 0x01) ? -gd5429.blt.src_pitch : gd5429.blt.src_pitch); 51.687 + break; 51.688 + case 0x40: 51.689 + gd5429.blt.src_addr = ((gd5429.blt.src_addr + ((gd5429.blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429.blt.src_addr & ~0x38); 51.690 + break; 51.691 + case 0x80: 51.692 + if (gd5429.blt.x_count != 0) 51.693 + { 51.694 + gd5429.blt.x_count = 0; 51.695 + gd5429.blt.src_addr++; 51.696 + } 51.697 + break; 51.698 + case 0xc0: 51.699 + gd5429.blt.src_addr = ((gd5429.blt.src_addr + ((gd5429.blt.mode & 0x01) ? -1 : 1)) & 7) | (gd5429.blt.src_addr & ~7); 51.700 + break; 51.701 + } 51.702 + 51.703 + gd5429.blt.height_internal--; 51.704 + if (gd5429.blt.height_internal == 0xffff) 51.705 + { 51.706 + if (gd5429.blt.mode & 0x04) 51.707 + { 51.708 + mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l, NULL); 51.709 + gd5429_recalc_mapping(); 51.710 + } 51.711 + return; 51.712 + } 51.713 + 51.714 + if (gd5429.blt.mode & 0x04) 51.715 + return; 51.716 + } 51.717 + } 51.718 +} 51.719 + 51.720 +void gd5429_mmio_write(uint32_t addr, uint8_t val, void *priv) 51.721 +{ 51.722 + pclog("MMIO write %08X %02X\n", addr, val); 51.723 + switch (addr & 0xff) 51.724 + { 51.725 + case 0x00: 51.726 + gd5429.blt.bg_col = (gd5429.blt.bg_col & 0xff00) | val; 51.727 + break; 51.728 + case 0x01: 51.729 + gd5429.blt.bg_col = (gd5429.blt.bg_col & 0x00ff) | (val << 8); 51.730 + break; 51.731 + 51.732 + case 0x04: 51.733 + gd5429.blt.fg_col = (gd5429.blt.fg_col & 0xff00) | val; 51.734 + break; 51.735 + case 0x05: 51.736 + gd5429.blt.fg_col = (gd5429.blt.fg_col & 0x00ff) | (val << 8); 51.737 + break; 51.738 + 51.739 + case 0x08: 51.740 + gd5429.blt.width = (gd5429.blt.width & 0xff00) | val; 51.741 + break; 51.742 + case 0x09: 51.743 + gd5429.blt.width = (gd5429.blt.width & 0x00ff) | (val << 8); 51.744 + break; 51.745 + case 0x0a: 51.746 + gd5429.blt.height = (gd5429.blt.height & 0xff00) | val; 51.747 + break; 51.748 + case 0x0b: 51.749 + gd5429.blt.height = (gd5429.blt.height & 0x00ff) | (val << 8); 51.750 + break; 51.751 + case 0x0c: 51.752 + gd5429.blt.dst_pitch = (gd5429.blt.dst_pitch & 0xff00) | val; 51.753 + break; 51.754 + case 0x0d: 51.755 + gd5429.blt.dst_pitch = (gd5429.blt.dst_pitch & 0x00ff) | (val << 8); 51.756 + break; 51.757 + case 0x0e: 51.758 + gd5429.blt.src_pitch = (gd5429.blt.src_pitch & 0xff00) | val; 51.759 + break; 51.760 + case 0x0f: 51.761 + gd5429.blt.src_pitch = (gd5429.blt.src_pitch & 0x00ff) | (val << 8); 51.762 + break; 51.763 + 51.764 + case 0x10: 51.765 + gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0xffff00) | val; 51.766 + break; 51.767 + case 0x11: 51.768 + gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0xff00ff) | (val << 8); 51.769 + break; 51.770 + case 0x12: 51.771 + gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0x00ffff) | (val << 16); 51.772 + break; 51.773 + 51.774 + case 0x14: 51.775 + gd5429.blt.src_addr = (gd5429.blt.src_addr & 0xffff00) | val; 51.776 + break; 51.777 + case 0x15: 51.778 + gd5429.blt.src_addr = (gd5429.blt.src_addr & 0xff00ff) | (val << 8); 51.779 + break; 51.780 + case 0x16: 51.781 + gd5429.blt.src_addr = (gd5429.blt.src_addr & 0x00ffff) | (val << 16); 51.782 + break; 51.783 + 51.784 + case 0x17: 51.785 + gd5429.blt.mask = val; 51.786 + break; 51.787 + case 0x18: 51.788 + gd5429.blt.mode = val; 51.789 + break; 51.790 + 51.791 + case 0x1a: 51.792 + gd5429.blt.rop = val; 51.793 + break; 51.794 + 51.795 + case 0x40: 51.796 + if (val & 0x02) 51.797 + gd5429_start_blit(0, -1); 51.798 + break; 51.799 + } 51.800 +} 51.801 + 51.802 +uint8_t gd5429_mmio_read(uint32_t addr, void *priv) 51.803 +{ 51.804 + pclog("MMIO read %08X\n", addr); 51.805 + switch (addr & 0xff) 51.806 + { 51.807 + case 0x40: /*BLT status*/ 51.808 + return 0; 51.809 + } 51.810 + return 0xff; /*All other registers read-only*/ 51.811 +} 51.812 + 51.813 +void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *priv) 51.814 +{ 51.815 + pclog("gd5429_blt_write_w %08X %08X\n", addr, val); 51.816 + gd5429_start_blit(val, 16); 51.817 +} 51.818 + 51.819 +void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *priv) 51.820 +{ 51.821 + pclog("gd5429_blt_write_l %08X %08X %04X %04X\n", addr, val, ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00)); 51.822 + if ((gd5429.blt.mode & 0x84) == 0x84) 51.823 + { 51.824 + gd5429_start_blit( val & 0xff, 8); 51.825 + gd5429_start_blit((val >> 8) & 0xff, 8); 51.826 + gd5429_start_blit((val >> 16) & 0xff, 8); 51.827 + gd5429_start_blit((val >> 24) & 0xff, 8); 51.828 + } 51.829 + else 51.830 + gd5429_start_blit(val, 32); 51.831 +} 51.832 + 51.833 +GFXCARD vid_gd5429 = 51.834 +{ 51.835 + gd5429_init, 51.836 + /*IO at 3Cx/3Dx*/ 51.837 + gd5429_out, 51.838 + gd5429_in, 51.839 + /*IO at 3Ax/3Bx*/ 51.840 + video_out_null, 51.841 + video_in_null, 51.842 + 51.843 + svga_poll, 51.844 + svga_recalctimings, 51.845 + 51.846 + svga_write, 51.847 + video_write_null, 51.848 + video_write_null, 51.849 + 51.850 + svga_read, 51.851 + video_read_null, 51.852 + video_read_null 51.853 +};
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2 +++ b/src/vid_ics2595.c Mon May 27 19:56:33 2013 +0100 52.3 @@ -0,0 +1,63 @@ 52.4 +/*ICS2595 clock chip emulation 52.5 + Used by ATI Mach64*/ 52.6 + 52.7 +#include "ibm.h" 52.8 +#include "vid_ics2595.h" 52.9 + 52.10 +enum 52.11 +{ 52.12 + ICS2595_IDLE, 52.13 + ICS2595_WRITE, 52.14 + ICS2595_READ 52.15 +}; 52.16 + 52.17 +static int ics2595_oldfs3, ics2595_oldfs2; 52.18 +static int ics2595_dat; 52.19 +static int ics2595_pos; 52.20 +static int ics2595_state = ICS2595_IDLE; 52.21 + 52.22 +static int ics2595_div[4] = {8, 4, 2, 1}; 52.23 + 52.24 +static double ics2595_clocks[16]; 52.25 +double ics2595_output_clock; 52.26 + 52.27 +void ics2595_write(int strobe, int dat) 52.28 +{ 52.29 + pclog("ics2595_write : %i %i\n", strobe, dat); 52.30 + if (strobe) 52.31 + { 52.32 + if ((dat & 8) && !ics2595_oldfs3) /*Data clock*/ 52.33 + { 52.34 + pclog(" - new dat %i\n", dat & 4); 52.35 + switch (ics2595_state) 52.36 + { 52.37 + case ICS2595_IDLE: 52.38 + ics2595_state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE; 52.39 + ics2595_pos = 0; 52.40 + break; 52.41 + case ICS2595_WRITE: 52.42 + ics2595_dat = (ics2595_dat >> 1); 52.43 + if (dat & 4) 52.44 + ics2595_dat |= (1 << 19); 52.45 + ics2595_pos++; 52.46 + if (ics2595_pos == 20) 52.47 + { 52.48 + int d, n, l; 52.49 + pclog("ICS2595_WRITE : dat %08X\n", ics2595_dat); 52.50 + l = (ics2595_dat >> 2) & 31; 52.51 + n = ((ics2595_dat >> 7) & 255) + 257; 52.52 + d = ics2595_div[(ics2595_dat >> 16) & 3]; 52.53 + 52.54 + ics2595_clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d; 52.55 + pclog("ICS2595 clock set - L %i N %i D %i freq = %f\n", l, n, d, (14318181.8 * ((double)n / 46.0)) / (double)d); 52.56 + ics2595_state = ICS2595_IDLE; 52.57 + } 52.58 + break; 52.59 + } 52.60 + } 52.61 + 52.62 + ics2595_oldfs2 = dat & 4; 52.63 + ics2595_oldfs3 = dat & 8; 52.64 + } 52.65 + ics2595_output_clock = ics2595_clocks[dat]; 52.66 +}
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/src/vid_ics2595.h Mon May 27 19:56:33 2013 +0100 53.3 @@ -0,0 +1,2 @@ 53.4 +void ics2595_write(int strobe, int dat); 53.5 +extern double ics2595_output_clock;
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/src/vid_s3_virge.c Mon May 27 19:56:33 2013 +0100 54.3 @@ -0,0 +1,467 @@ 54.4 +/*S3 ViRGE emulation 54.5 + 54.6 + The SVGA core is largely the same as older S3 chips, but the blitter is totally different*/ 54.7 +#include "ibm.h" 54.8 +#include "io.h" 54.9 +#include "mem.h" 54.10 +#include "pci.h" 54.11 +#include "video.h" 54.12 +#include "vid_svga.h" 54.13 +#include "vid_svga_render.h" 54.14 +//#include "vid_sdac_ramdac.h" 54.15 + 54.16 +void s3_virge_updatemapping(); 54.17 + 54.18 +static uint8_t s3_bank; 54.19 +static uint8_t s3_ma_ext; 54.20 +static int s3_width = 1024; 54.21 +static int s3_bpp = 0; 54.22 + 54.23 +static uint8_t s3_virge_id, s3_virge_id_high, s3_virge_id_low, s3_virge_rev; 54.24 + 54.25 +uint8_t s3_virge_mmio_read(uint32_t addr, void *priv); 54.26 +uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv); 54.27 +uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv); 54.28 +void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv); 54.29 +void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv); 54.30 +void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv); 54.31 + 54.32 +void s3_virge_out(uint16_t addr, uint8_t val, void *priv) 54.33 +{ 54.34 + uint8_t old; 54.35 + 54.36 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 54.37 + 54.38 + pclog("S3 out %04X %02X %04X:%08X %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins); 54.39 + 54.40 + switch (addr) 54.41 + { 54.42 + case 0x3c5: 54.43 + if (seqaddr >= 0x10) 54.44 + { 54.45 + seqregs[seqaddr&0x1F]=val; 54.46 + return; 54.47 + } 54.48 + if (seqaddr == 4) /*Chain-4 - update banking*/ 54.49 + { 54.50 + if (val & 8) svgawbank = svgarbank = s3_bank << 16; 54.51 + else svgawbank = svgarbank = s3_bank << 14; 54.52 + } 54.53 + break; 54.54 + 54.55 + //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 54.56 +// pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); 54.57 + //sdac_ramdac_out(addr,val); 54.58 + //return; 54.59 + 54.60 + case 0x3D4: 54.61 + crtcreg=val&0x7f; 54.62 + return; 54.63 + case 0x3D5: 54.64 +// if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val); 54.65 + if (crtcreg <= 7 && crtc[0x11] & 0x80) return; 54.66 + if (crtcreg >= 0x20 && crtcreg != 0x38 && (crtc[0x38] & 0xcc) != 0x48) return; 54.67 + old=crtc[crtcreg]; 54.68 + crtc[crtcreg]=val; 54.69 + switch (crtcreg) 54.70 + { 54.71 + case 0x31: 54.72 + s3_ma_ext = (s3_ma_ext & 0x1c) | ((val & 0x30) >> 4); 54.73 + vrammask = (val & 8) ? 0x3fffff : 0x3ffff; 54.74 + break; 54.75 + 54.76 + case 0x50: 54.77 + switch (crtc[0x50] & 0xc1) 54.78 + { 54.79 + case 0x00: s3_width = (crtc[0x31] & 2) ? 2048 : 1024; break; 54.80 + case 0x01: s3_width = 1152; break; 54.81 + case 0x40: s3_width = 640; break; 54.82 + case 0x80: s3_width = 800; break; 54.83 + case 0x81: s3_width = 1600; break; 54.84 + case 0xc0: s3_width = 1280; break; 54.85 + } 54.86 + s3_bpp = (crtc[0x50] >> 4) & 3; 54.87 + break; 54.88 + case 0x69: 54.89 + s3_ma_ext = val & 0x1f; 54.90 + break; 54.91 + 54.92 + case 0x35: 54.93 + s3_bank = (s3_bank & 0x70) | (val & 0xf); 54.94 +// pclog("CRTC write R35 %02X\n", val); 54.95 + if (chain4) svgawbank = svgarbank = s3_bank << 16; 54.96 + else svgawbank = svgarbank = s3_bank << 14; 54.97 + break; 54.98 + case 0x51: 54.99 + s3_bank = (s3_bank & 0x4f) | ((val & 0xc) << 2); 54.100 + if (chain4) svgawbank = svgarbank = s3_bank << 16; 54.101 + else svgawbank = svgarbank = s3_bank << 14; 54.102 + s3_ma_ext = (s3_ma_ext & ~0xc) | ((val & 3) << 2); 54.103 + break; 54.104 + case 0x6a: 54.105 + s3_bank = val; 54.106 +// pclog("CRTC write R6a %02X\n", val); 54.107 + if (chain4) svgawbank = svgarbank = s3_bank << 16; 54.108 + else svgawbank = svgarbank = s3_bank << 14; 54.109 + break; 54.110 + 54.111 + case 0x3a: 54.112 + if (val & 0x10) gdcreg[5] |= 0x40; /*Horrible cheat*/ 54.113 + break; 54.114 + 54.115 + case 0x45: 54.116 + svga_hwcursor.ena = val & 1; 54.117 + break; 54.118 + case 0x48: 54.119 + svga_hwcursor.x = ((crtc[0x46] << 8) | crtc[0x47]) & 0x7ff; 54.120 + if (bpp == 32) svga_hwcursor.x >>= 1; 54.121 + svga_hwcursor.y = ((crtc[0x48] << 8) | crtc[0x49]) & 0x7ff; 54.122 + svga_hwcursor.xoff = crtc[0x4e] & 63; 54.123 + svga_hwcursor.yoff = crtc[0x4f] & 63; 54.124 + svga_hwcursor.addr = ((((crtc[0x4c] << 8) | crtc[0x4d]) & 0xfff) * 1024) + (svga_hwcursor.yoff * 16); 54.125 + break; 54.126 + 54.127 + case 0x53: 54.128 + case 0x58: case 0x59: case 0x5a: 54.129 + s3_virge_updatemapping(); 54.130 + break; 54.131 + 54.132 + case 0x67: 54.133 + switch (val >> 4) 54.134 + { 54.135 + case 3: bpp = 15; break; 54.136 + case 5: bpp = 16; break; 54.137 + case 7: bpp = 24; break; 54.138 + case 13: bpp = 32; break; 54.139 + default: bpp = 8; break; 54.140 + } 54.141 + break; 54.142 + //case 0x55: case 0x43: 54.143 +// pclog("Write CRTC R%02X %02X\n", crtcreg, val); 54.144 + } 54.145 + if (old!=val) 54.146 + { 54.147 + if (crtcreg<0xE || crtcreg>0x10) 54.148 + { 54.149 + fullchange=changeframecount; 54.150 + svga_recalctimings(); 54.151 + } 54.152 + } 54.153 + break; 54.154 + } 54.155 + svga_out(addr, val, NULL); 54.156 +} 54.157 + 54.158 +uint8_t s3_virge_in(uint16_t addr, void *priv) 54.159 +{ 54.160 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 54.161 + 54.162 + if (addr != 0x3da) pclog("S3 in %04X %04X:%08X\n", addr, CS, pc); 54.163 + switch (addr) 54.164 + { 54.165 + //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 54.166 +// pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); 54.167 + //return sdac_ramdac_in(addr); 54.168 + 54.169 + case 0x3c5: 54.170 + if (seqaddr >= 0x10) 54.171 + return seqregs[seqaddr&0x1F]; 54.172 + break; 54.173 + 54.174 + case 0x3D4: 54.175 + return crtcreg; 54.176 + case 0x3D5: 54.177 +// pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc); 54.178 + switch (crtcreg) 54.179 + { 54.180 + case 0x2d: return s3_virge_id_high; /*Extended chip ID*/ 54.181 + case 0x2e: return s3_virge_id_low; /*New chip ID*/ 54.182 + case 0x2f: return s3_virge_rev; 54.183 + case 0x30: return s3_virge_id; /*Chip ID*/ 54.184 + case 0x31: return (crtc[0x31] & 0xcf) | ((s3_ma_ext & 3) << 4); 54.185 + case 0x35: return (crtc[0x35] & 0xf0) | (s3_bank & 0xf); 54.186 + case 0x51: return (crtc[0x51] & 0xf0) | ((s3_bank >> 2) & 0xc) | ((s3_ma_ext >> 2) & 3); 54.187 + case 0x69: return s3_ma_ext; 54.188 + case 0x6a: return s3_bank; 54.189 + } 54.190 + return crtc[crtcreg]; 54.191 + } 54.192 + return svga_in(addr, NULL); 54.193 +} 54.194 + 54.195 +void s3_virge_recalctimings() 54.196 +{ 54.197 +// pclog("recalctimings\n"); 54.198 + svga_ma |= (s3_ma_ext << 16); 54.199 +// pclog("SVGA_MA %08X\n", svga_ma); 54.200 +// if (gdcreg[5] & 0x40) svga_lowres = !(crtc[0x3a] & 0x10); 54.201 + if ((gdcreg[5] & 0x40) && (crtc[0x3a] & 0x10)) 54.202 + { 54.203 + switch (bpp) 54.204 + { 54.205 + case 8: 54.206 + svga_render = svga_render_8bpp_highres; 54.207 + break; 54.208 + case 15: 54.209 + svga_render = svga_render_15bpp_highres; 54.210 + break; 54.211 + case 16: 54.212 + svga_render = svga_render_16bpp_highres; 54.213 + break; 54.214 + case 24: 54.215 + svga_render = svga_render_24bpp_highres; 54.216 + break; 54.217 + case 32: 54.218 + svga_render = svga_render_32bpp_highres; 54.219 + break; 54.220 + } 54.221 + } 54.222 + 54.223 + if (crtc[0x5d] & 0x01) svga_htotal += 0x100; 54.224 + if (crtc[0x5d] & 0x02) svga_hdisp += 0x100; 54.225 + if (crtc[0x5e] & 0x01) svga_vtotal += 0x400; 54.226 + if (crtc[0x5e] & 0x02) svga_dispend += 0x400; 54.227 + if (crtc[0x5e] & 0x10) svga_vsyncstart += 0x400; 54.228 + if (crtc[0x5e] & 0x40) svga_split += 0x400; 54.229 + if (crtc[0x51] & 0x30) svga_rowoffset += (crtc[0x51] & 0x30) << 4; 54.230 + else if (crtc[0x43] & 0x04) svga_rowoffset += 0x100; 54.231 + if (!svga_rowoffset) svga_rowoffset = 256; 54.232 + svga_interlace = crtc[0x42] & 0x20; 54.233 + if (bpp == 32) 54.234 + { 54.235 + svga_htotal <<= 2; 54.236 + svga_hdisp <<= 2; 54.237 + } 54.238 + //svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3); 54.239 +// pclog("SVGA_CLOCK = %f %02X %f\n", svga_clock, svga_miscout, cpuclock); 54.240 + //if (bpp > 8) svga_clock /= 2; 54.241 +} 54.242 + 54.243 +static uint32_t s3_linear_base = 0, s3_linear_size = 0; 54.244 +void s3_virge_updatemapping() 54.245 +{ 54.246 + mem_removehandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); 54.247 + 54.248 +// video_write_a000_w = video_write_a000_l = NULL; 54.249 + 54.250 + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 54.251 + mem_removehandler(0xa0000, 0x20000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL); 54.252 + pclog("Update mapping - bank %02X ", gdcreg[6] & 0xc); 54.253 + switch (gdcreg[6] & 0xc) /*Banked framebuffer*/ 54.254 + { 54.255 + case 0x0: /*128k at A0000*/ 54.256 + mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 54.257 + break; 54.258 + case 0x4: /*64k at A0000*/ 54.259 + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 54.260 + break; 54.261 + case 0x8: /*32k at B0000*/ 54.262 + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 54.263 + break; 54.264 + case 0xC: /*32k at B8000*/ 54.265 + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 54.266 + break; 54.267 + } 54.268 + 54.269 + pclog("Linear framebuffer %02X ", crtc[0x58] & 0x10); 54.270 + if (crtc[0x58] & 0x10) /*Linear framebuffer*/ 54.271 + { 54.272 + s3_linear_base = (crtc[0x5a] << 16) | (crtc[0x59] << 24); 54.273 + switch (crtc[0x58] & 3) 54.274 + { 54.275 + case 0: /*64k*/ 54.276 + s3_linear_size = 0x10000; 54.277 + break; 54.278 + case 1: /*1mb*/ 54.279 + s3_linear_size = 0x100000; 54.280 + break; 54.281 + case 2: /*2mb*/ 54.282 + s3_linear_size = 0x200000; 54.283 + break; 54.284 + case 3: /*8mb*/ 54.285 + s3_linear_size = 0x400000; 54.286 + break; 54.287 + } 54.288 + s3_linear_base &= ~(s3_linear_size - 1); 54.289 +// pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]); 54.290 + pclog("Linear framebuffer at %08X size %08X\n", s3_linear_base, s3_linear_size); 54.291 + if (s3_linear_base == 0xa0000) 54.292 + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 54.293 + else 54.294 + mem_sethandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); 54.295 + } 54.296 + 54.297 + pclog("Memory mapped IO %02X\n", crtc[0x53] & 0x18); 54.298 + output = 0; 54.299 + if ((crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/ 54.300 + { 54.301 + output = 3; 54.302 + if (crtc[0x53] & 0x20) 54.303 + mem_sethandler(0xb8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL); 54.304 + else 54.305 + mem_sethandler(0xa8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL); 54.306 + } 54.307 + 54.308 +} 54.309 + 54.310 + 54.311 +uint8_t s3_virge_mmio_read(uint32_t addr, void *priv) 54.312 +{ 54.313 + pclog("MMIO readb %08X\n", addr); 54.314 + return 0xff; 54.315 +} 54.316 +uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv) 54.317 +{ 54.318 + pclog("MMIO readw %08X\n", addr); 54.319 + return 0xffff; 54.320 +} 54.321 +uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv) 54.322 +{ 54.323 + pclog("MMIO readl %08X\n", addr); 54.324 + return 0xffffffff; 54.325 +} 54.326 +void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv) 54.327 +{ 54.328 + pclog("MMIO writeb %08X %02X\n", addr, val); 54.329 +} 54.330 +void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv) 54.331 +{ 54.332 + pclog("MMIO writew %08X %04X\n", addr, val); 54.333 +} 54.334 +void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) 54.335 +{ 54.336 + pclog("MMIO writel %08X %08X\n", addr, val); 54.337 +} 54.338 + 54.339 + 54.340 + 54.341 +void s3_virge_hwcursor_draw(int displine) 54.342 +{ 54.343 + int x; 54.344 + uint16_t dat[2]; 54.345 + int xx; 54.346 + int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff; 54.347 + 54.348 + pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y); 54.349 + for (x = 0; x < 64; x += 16) 54.350 + { 54.351 + dat[0] = (vram[svga_hwcursor_latch.addr] << 8) | vram[svga_hwcursor_latch.addr + 1]; 54.352 + dat[1] = (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3]; 54.353 + for (xx = 0; xx < 16; xx++) 54.354 + { 54.355 + if (offset >= svga_hwcursor_latch.x) 54.356 + { 54.357 + if (!(dat[0] & 0x8000)) 54.358 + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? 0xffffff : 0; 54.359 + else if (dat[1] & 0x8000) 54.360 + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; 54.361 +// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]); 54.362 + } 54.363 + 54.364 + offset++; 54.365 + dat[0] <<= 1; 54.366 + dat[1] <<= 1; 54.367 + } 54.368 + svga_hwcursor_latch.addr += 4; 54.369 + } 54.370 +} 54.371 + 54.372 + 54.373 +static uint8_t s3_virge_pci_regs[256]; 54.374 + 54.375 +uint8_t s3_virge_pci_read(int func, int addr, void *priv) 54.376 +{ 54.377 +// pclog("S3 PCI read %08X\n", addr); 54.378 + switch (addr) 54.379 + { 54.380 + case 0x00: return 0x33; /*'S3'*/ 54.381 + case 0x01: return 0x53; 54.382 + 54.383 + case 0x02: return s3_virge_id_low; 54.384 + case 0x03: return s3_virge_id_high; 54.385 + 54.386 + case 0x08: return 0; /*Revision ID*/ 54.387 + case 0x09: return 0; /*Programming interface*/ 54.388 + 54.389 + case 0x0a: return 0x00; /*Supports VGA interface*/ 54.390 + case 0x0b: return 0x03; 54.391 + 54.392 + case 0x10: return 0x00; /*Linear frame buffer address*/ 54.393 + case 0x11: return 0x00; 54.394 + case 0x12: return 0x00; 54.395 + case 0x13: return crtc[0x59] & 0xfc; 54.396 + 54.397 + case 0x30: return 0x01; /*BIOS ROM address*/ 54.398 + case 0x31: return 0x00; 54.399 + case 0x32: return 0x0C; 54.400 + case 0x33: return 0x00; 54.401 + 54.402 + } 54.403 + return s3_virge_pci_regs[addr]; 54.404 +} 54.405 + 54.406 +void s3_virge_pci_write(int func, int addr, uint8_t val, void *priv) 54.407 +{ 54.408 + switch (addr) 54.409 + { 54.410 + case 0x00: case 0x01: case 0x02: case 0x03: 54.411 + case 0x08: case 0x09: case 0x0a: case 0x0b: 54.412 + case 0x3d: case 0x3e: case 0x3f: 54.413 + break; 54.414 + 54.415 + case 0x13: crtc[0x59] = val & 0xfc; s3_virge_updatemapping(); break; 54.416 + } 54.417 + s3_virge_pci_regs[addr] = val; 54.418 +} 54.419 + 54.420 +int s3_virge_init() 54.421 +{ 54.422 + s3_virge_pci_regs[4] = 3; 54.423 + s3_virge_pci_regs[5] = 0; 54.424 + s3_virge_pci_regs[6] = 0; 54.425 + s3_virge_pci_regs[7] = 2; 54.426 + s3_virge_pci_regs[0x3d] = 1; 54.427 + s3_virge_pci_regs[0x3e] = 4; 54.428 + s3_virge_pci_regs[0x3f] = 0xff; 54.429 + 54.430 + s3_virge_id_high = 0x56; 54.431 + s3_virge_id_low = 0x31; 54.432 + s3_virge_rev = 0; 54.433 + s3_virge_id = 0xe1; 54.434 + 54.435 + svga_recalctimings_ex = s3_virge_recalctimings; 54.436 + svga_hwcursor_draw = s3_virge_hwcursor_draw; 54.437 + 54.438 + crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5); 54.439 + crtc[0x37] = 1 | (7 << 5); 54.440 + 54.441 + vrammask = 0x3fffff; 54.442 + 54.443 + pci_add(s3_virge_pci_read, s3_virge_pci_write, NULL); 54.444 + 54.445 + svga_vram_limit = 4 << 20; /*4mb*/ 54.446 + return svga_init(); 54.447 +} 54.448 + 54.449 +GFXCARD vid_s3_virge = 54.450 +{ 54.451 + s3_virge_init, 54.452 + /*IO at 3Cx/3Dx*/ 54.453 + s3_virge_out, 54.454 + s3_virge_in, 54.455 + /*IO at 3Ax/3Bx*/ 54.456 + video_out_null, 54.457 + video_in_null, 54.458 + 54.459 + svga_poll, 54.460 + svga_recalctimings, 54.461 + 54.462 + svga_write, 54.463 + video_write_null, 54.464 + video_write_null, 54.465 + 54.466 + svga_read, 54.467 + video_read_null, 54.468 + video_read_null 54.469 +}; 54.470 +
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/src/vid_svga_render.c Mon May 27 19:56:33 2013 +0100 55.3 @@ -0,0 +1,487 @@ 55.4 +#include "ibm.h" 55.5 +#include "video.h" 55.6 +#include "vid_svga.h" 55.7 +#include "vid_svga_render.h" 55.8 + 55.9 +void svga_render_blank() 55.10 +{ 55.11 + int x, xx; 55.12 + 55.13 + if (firstline_draw == 2000) firstline_draw = displine; 55.14 + lastline_draw = displine; 55.15 + for (x=0;x<svga_hdisp;x++) 55.16 + { 55.17 + switch (seqregs[1]&9) 55.18 + { 55.19 + case 0: 55.20 + for (xx=0;xx<9;xx++) ((uint32_t *)buffer32->line[displine])[(x*9)+xx+32]=0; 55.21 + break; 55.22 + case 1: 55.23 + for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[(x*8)+xx+32]=0; 55.24 + break; 55.25 + case 8: 55.26 + for (xx=0;xx<18;xx++) ((uint32_t *)buffer32->line[displine])[(x*18)+xx+32]=0; 55.27 + break; 55.28 + case 9: 55.29 + for (xx=0;xx<16;xx++) ((uint32_t *)buffer32->line[displine])[(x*16)+xx+32]=0; 55.30 + break; 55.31 + } 55.32 + } 55.33 +} 55.34 + 55.35 +void svga_render_text_40() 55.36 +{ 55.37 + if (firstline_draw == 2000) firstline_draw = displine; 55.38 + lastline_draw = displine; 55.39 + 55.40 + if (fullchange) 55.41 + { 55.42 + int x, xx; 55.43 + int drawcursor; 55.44 + uint8_t chr, attr, dat; 55.45 + uint32_t charaddr; 55.46 + int fg, bg; 55.47 + int xinc = (seqregs[1] & 1) ? 16 : 18; 55.48 + 55.49 + for (x=0;x<svga_hdisp;x+=xinc) 55.50 + { 55.51 + drawcursor=((ma==ca) && con && cursoron); 55.52 + chr=vram[(ma<<1)]; 55.53 + attr=vram[(ma<<1)+4]; 55.54 + if (attr&8) charaddr=charsetb+(chr*128); 55.55 + else charaddr=charseta+(chr*128); 55.56 + 55.57 + if (drawcursor) 55.58 + { 55.59 + bg=pallook[egapal[attr&15]]; 55.60 + fg=pallook[egapal[attr>>4]]; 55.61 + } 55.62 + else 55.63 + { 55.64 + fg=pallook[egapal[attr&15]]; 55.65 + bg=pallook[egapal[attr>>4]]; 55.66 + if (attr&0x80 && attrregs[0x10]&8) 55.67 + { 55.68 + bg=pallook[egapal[(attr>>4)&7]]; 55.69 + if (cgablink&16) fg=bg; 55.70 + } 55.71 + } 55.72 + 55.73 + dat=vram[charaddr+(sc<<2)]; 55.74 + if (seqregs[1]&1) 55.75 + { 55.76 + for (xx=0;xx<8;xx++) 55.77 + ((uint32_t *)buffer32->line[displine])[(x+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[(x+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; 55.78 + } 55.79 + else 55.80 + { 55.81 + for (xx=0;xx<8;xx++) 55.82 + ((uint32_t *)buffer32->line[displine])[(x+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[(x+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; 55.83 + if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) 55.84 + ((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=bg; 55.85 + else 55.86 + ((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=(dat&1)?fg:bg; 55.87 + } 55.88 + ma+=4; ma&=vrammask; 55.89 + } 55.90 + } 55.91 +} 55.92 + 55.93 +void svga_render_text_80() 55.94 +{ 55.95 + if (firstline_draw == 2000) firstline_draw = displine; 55.96 + lastline_draw = displine; 55.97 + 55.98 + if (fullchange) 55.99 + { 55.100 + int x, xx; 55.101 + int drawcursor; 55.102 + uint8_t chr, attr, dat; 55.103 + uint32_t charaddr; 55.104 + int fg, bg; 55.105 + int xinc = (seqregs[1] & 1) ? 8 : 9; 55.106 + 55.107 + for (x=0;x<svga_hdisp;x+=xinc) 55.108 + { 55.109 + drawcursor=((ma==ca) && con && cursoron); 55.110 + chr=vram[(ma<<1)]; 55.111 + attr=vram[(ma<<1)+4]; 55.112 + if (attr&8) charaddr=charsetb+(chr*128); 55.113 + else charaddr=charseta+(chr*128); 55.114 + 55.115 + if (drawcursor) 55.116 + { 55.117 + bg=pallook[egapal[attr&15]]; 55.118 + fg=pallook[egapal[attr>>4]]; 55.119 + } 55.120 + else 55.121 + { 55.122 + fg=pallook[egapal[attr&15]]; 55.123 + bg=pallook[egapal[attr>>4]]; 55.124 + if (attr&0x80 && attrregs[0x10]&8) 55.125 + { 55.126 + bg=pallook[egapal[(attr>>4)&7]]; 55.127 + if (cgablink&16) fg=bg; 55.128 + } 55.129 + } 55.130 + 55.131 + dat=vram[charaddr+(sc<<2)]; 55.132 + if (seqregs[1]&1) 55.133 + { 55.134 + for (xx=0;xx<8;xx++) 55.135 + ((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; 55.136 + } 55.137 + else 55.138 + { 55.139 + for (xx=0;xx<8;xx++) 55.140 + ((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; 55.141 + if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) 55.142 + ((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=bg; 55.143 + else 55.144 + ((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=(dat&1)?fg:bg; 55.145 + } 55.146 + ma+=4; ma&=vrammask; 55.147 + } 55.148 + } 55.149 +} 55.150 + 55.151 +void svga_render_4bpp_lowres() 55.152 +{ 55.153 + int x, offset; 55.154 + uint8_t edat[4], dat; 55.155 + 55.156 + if (firstline_draw == 2000) firstline_draw = displine; 55.157 + lastline_draw = displine; 55.158 + 55.159 + offset=((8-scrollcache)<<1)+16; 55.160 + for (x = 0; x <= svga_hdisp; x += 16) 55.161 + { 55.162 + edat[0]=vram[ma]; 55.163 + edat[1]=vram[ma|0x1]; 55.164 + edat[2]=vram[ma|0x2]; 55.165 + edat[3]=vram[ma|0x3]; 55.166 + ma+=4; ma&=vrammask; 55.167 + 55.168 + dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2); 55.169 + ((uint32_t *)buffer32->line[displine])[x+14+offset]=((uint32_t *)buffer32->line[displine])[x+15+offset]=pallook[egapal[dat&0xF]]; 55.170 + ((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[dat>>4]]; 55.171 + dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2); 55.172 + ((uint32_t *)buffer32->line[displine])[x+10+offset]=((uint32_t *)buffer32->line[displine])[x+11+offset]=pallook[egapal[dat&0xF]]; 55.173 + ((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[dat>>4]]; 55.174 + dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2); 55.175 + ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[dat&0xF]]; 55.176 + ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat>>4]]; 55.177 + dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); 55.178 + ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[dat&0xF]]; 55.179 + ((uint32_t *)buffer32->line[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat>>4]]; 55.180 + } 55.181 +} 55.182 + 55.183 +void svga_render_4bpp_highres() 55.184 +{ 55.185 + int x, offset; 55.186 + uint8_t edat[4], dat; 55.187 + 55.188 + if (firstline_draw == 2000) firstline_draw = displine; 55.189 + lastline_draw = displine; 55.190 + 55.191 + offset=(8-scrollcache)+24; 55.192 + for (x = 0; x <= svga_hdisp; x += 8) 55.193 + { 55.194 + edat[0]=vram[ma]; 55.195 + edat[1]=vram[ma|0x1]; 55.196 + edat[2]=vram[ma|0x2]; 55.197 + edat[3]=vram[ma|0x3]; 55.198 + ma+=4; ma&=vrammask; 55.199 + 55.200 + dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2); 55.201 + ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[dat&0xF]]; 55.202 + ((uint32_t *)buffer32->line[displine])[x+6+offset]=pallook[egapal[dat>>4]]; 55.203 + dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2); 55.204 + ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat&0xF]]; 55.205 + ((uint32_t *)buffer32->line[displine])[x+4+offset]=pallook[egapal[dat>>4]]; 55.206 + dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2); 55.207 + ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[dat&0xF]]; 55.208 + ((uint32_t *)buffer32->line[displine])[x+2+offset]=pallook[egapal[dat>>4]]; 55.209 + dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); 55.210 + ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat&0xF]]; 55.211 + ((uint32_t *)buffer32->line[displine])[x+offset]= pallook[egapal[dat>>4]]; 55.212 + } 55.213 +} 55.214 + 55.215 +void svga_render_2bpp_lowres() 55.216 +{ 55.217 + int x, offset; 55.218 + uint8_t edat[4], dat; 55.219 + 55.220 + if (firstline_draw == 2000) firstline_draw = displine; 55.221 + lastline_draw = displine; 55.222 + offset=((8-scrollcache)<<1)+16; 55.223 + /*Low res (320) only, though high res (640) should be possible*/ 55.224 + for (x = 0; x <= svga_hdisp; x += 16) 55.225 + { 55.226 + if (sc&1 && !(crtc[0x17]&1)) 55.227 + { 55.228 + edat[0]=vram[(ma<<1)+0x8000]; 55.229 + edat[1]=vram[(ma<<1)+0x8004]; 55.230 + } 55.231 + else 55.232 + { 55.233 + edat[0]=vram[(ma<<1)]; 55.234 + edat[1]=vram[(ma<<1)+4]; 55.235 + } 55.236 + ma+=4; ma&=vrammask; 55.237 + 55.238 + ((uint32_t *)buffer32->line[displine])[x+14+offset]=((uint32_t *)buffer32->line[displine])[x+15+offset]=pallook[egapal[edat[1]&3]]; 55.239 + ((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[(edat[1]>>2)&3]]; 55.240 + dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2); 55.241 + ((uint32_t *)buffer32->line[displine])[x+10+offset]=((uint32_t *)buffer32->line[displine])[x+11+offset]=pallook[egapal[(edat[1]>>4)&3]]; 55.242 + ((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[(edat[1]>>6)&3]]; 55.243 + dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2); 55.244 + ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[(edat[0]>>0)&3]]; 55.245 + ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[(edat[0]>>2)&3]]; 55.246 + dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); 55.247 + ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[(edat[0]>>4)&3]]; 55.248 + ((uint32_t *)buffer32->line[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[(edat[0]>>6)&3]]; 55.249 + } 55.250 +} 55.251 + 55.252 +void svga_render_8bpp_lowres() 55.253 +{ 55.254 + int x, offset; 55.255 + uint8_t edat[4]; 55.256 + 55.257 + if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 55.258 + { 55.259 + if (firstline_draw == 2000) firstline_draw = displine; 55.260 + lastline_draw = displine; 55.261 + 55.262 + offset=(8-(scrollcache&6))+24; 55.263 + 55.264 + for (x = 0; x <= svga_hdisp; x += 8) 55.265 + { 55.266 + edat[0]=vram[ma]; 55.267 + edat[1]=vram[ma|0x1]; 55.268 + edat[2]=vram[ma|0x2]; 55.269 + edat[3]=vram[ma|0x3]; 55.270 + ma+=4; ma&=vrammask; 55.271 + ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[edat[3]]; 55.272 + ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[edat[2]]; 55.273 + ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[edat[1]]; 55.274 + ((uint32_t *)buffer32->line[displine])[x+offset]= ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[edat[0]]; 55.275 + } 55.276 + } 55.277 +} 55.278 + 55.279 +void svga_render_8bpp_highres() 55.280 +{ 55.281 + int x, offset; 55.282 + uint8_t edat[4]; 55.283 + 55.284 + if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 55.285 + { 55.286 + if (firstline_draw == 2000) firstline_draw = displine; 55.287 + lastline_draw = displine; 55.288 + 55.289 + offset = (8 - ((scrollcache & 6) >> 1)) + 24; 55.290 + 55.291 + for (x = 0; x <= svga_hdisp; x += 8) 55.292 + { 55.293 + edat[0]=vram[ma]; 55.294 + edat[1]=vram[ma|0x1]; 55.295 + edat[2]=vram[ma|0x2]; 55.296 + edat[3]=vram[ma|0x3]; 55.297 + ma+=4; ma&=vrammask; 55.298 + ((uint32_t *)buffer32->line[displine])[x+3+offset] = pallook[edat[3]]; 55.299 + ((uint32_t *)buffer32->line[displine])[x+2+offset] = pallook[edat[2]]; 55.300 + ((uint32_t *)buffer32->line[displine])[x+1+offset] = pallook[edat[1]]; 55.301 + ((uint32_t *)buffer32->line[displine])[x+offset] = pallook[edat[0]]; 55.302 + edat[0]=vram[ma]; 55.303 + edat[1]=vram[ma|0x1]; 55.304 + edat[2]=vram[ma|0x2]; 55.305 + edat[3]=vram[ma|0x3]; 55.306 + ma+=4; ma&=vrammask; 55.307 + ((uint32_t *)buffer32->line[displine])[x+7+offset] = pallook[edat[3]]; 55.308 + ((uint32_t *)buffer32->line[displine])[x+6+offset] = pallook[edat[2]]; 55.309 + ((uint32_t *)buffer32->line[displine])[x+5+offset] = pallook[edat[1]]; 55.310 + ((uint32_t *)buffer32->line[displine])[x+4+offset] = pallook[edat[0]]; 55.311 + } 55.312 + } 55.313 +} 55.314 + 55.315 +void svga_render_15bpp_lowres() 55.316 +{ 55.317 + int x, offset; 55.318 + uint16_t fg, bg; 55.319 + 55.320 + if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 55.321 + { 55.322 + if (firstline_draw == 2000) firstline_draw = displine; 55.323 + lastline_draw = displine; 55.324 + 55.325 + offset=(8-(scrollcache&6))+24; 55.326 + 55.327 + for (x = 0; x <= svga_hdisp; x += 4) 55.328 + { 55.329 + fg=vram[ma]|(vram[ma|0x1]<<8); 55.330 + bg=vram[ma|0x2]|(vram[ma|0x3]<<8); 55.331 + ma+=4; ma&=vrammask; 55.332 + ((uint32_t *)buffer32->line[displine])[x+2+offset]=((uint32_t *)buffer32->line[displine])[x+3+offset]=((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19); 55.333 + ((uint32_t *)buffer32->line[displine])[x+0+offset]=((uint32_t *)buffer32->line[displine])[x+1+offset]=((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19); 55.334 + } 55.335 + } 55.336 +} 55.337 + 55.338 +void svga_render_15bpp_highres() 55.339 +{ 55.340 + int x, offset; 55.341 + uint16_t fg, bg; 55.342 + 55.343 + if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 55.344 + { 55.345 + if (firstline_draw == 2000) firstline_draw = displine; 55.346 + lastline_draw = displine; 55.347 + 55.348 + offset = (8 - ((scrollcache & 6) >> 1)) + 24; 55.349 + 55.350 + for (x = 0; x <= svga_hdisp; x += 2) 55.351 + { 55.352 + fg=vram[ma]|(vram[ma|0x1]<<8); 55.353 + bg=vram[ma|0x2]|(vram[ma|0x3]<<8); 55.354 + ma+=4; ma&=vrammask; 55.355 + ((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19); 55.356 + ((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19); 55.357 + } 55.358 + } 55.359 +} 55.360 + 55.361 +void svga_render_16bpp_lowres() 55.362 +{ 55.363 + int x, offset; 55.364 + uint16_t fg, bg; 55.365 + 55.366 + if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 55.367 + { 55.368 + if (firstline_draw == 2000) firstline_draw = displine; 55.369 + lastline_draw = displine; 55.370 + 55.371 + offset=(8-(scrollcache&6))+24; 55.372 + 55.373 + for (x = 0; x <= svga_hdisp; x += 4) 55.374 + { 55.375 + fg=vram[ma]|(vram[ma|0x1]<<8); 55.376 + bg=vram[ma|0x2]|(vram[ma|0x3]<<8); 55.377 + ma+=4; ma&=vrammask; 55.378 + ((uint32_t *)buffer32->line[displine])[x+2+offset]=((uint32_t *)buffer32->line[displine])[x+3+offset]=((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19); 55.379 + ((uint32_t *)buffer32->line[displine])[x+0+offset]=((uint32_t *)buffer32->line[displine])[x+1+offset]=((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19); 55.380 + } 55.381 + } 55.382 +} 55.383 + 55.384 +void svga_render_16bpp_highres() 55.385 +{ 55.386 + int x, offset; 55.387 + uint16_t fg, bg; 55.388 + 55.389 + if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 55.390 + { 55.391 + if (firstline_draw == 2000) firstline_draw = displine; 55.392 + lastline_draw = displine; 55.393 + 55.394 + offset = (8 - ((scrollcache & 6) >> 1)) + 24; 55.395 + 55.396 + for (x = 0; x <= svga_hdisp; x += 2) 55.397 + { 55.398 + fg=vram[ma]|(vram[ma|0x1]<<8); 55.399 + bg=vram[ma|0x2]|(vram[ma|0x3]<<8); 55.400 + ma+=4; ma&=vrammask; 55.401 + ((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19); 55.402 + ((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19); 55.403 + } 55.404 + } 55.405 +} 55.406 + 55.407 +void svga_render_24bpp_lowres() 55.408 +{ 55.409 + int x, offset; 55.410 + uint32_t fg; 55.411 + 55.412 + if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 55.413 + { 55.414 + if (firstline_draw == 2000) firstline_draw = displine; 55.415 + lastline_draw = displine; 55.416 + 55.417 + offset=(8-(scrollcache&6))+24; 55.418 + 55.419 + for (x = 0; x <= svga_hdisp; x++) 55.420 + { 55.421 + fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16); 55.422 + ma+=3; ma&=vrammask; 55.423 + ((uint32_t *)buffer32->line[displine])[(x<<1)+offset]=((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=fg; 55.424 + } 55.425 + } 55.426 +} 55.427 + 55.428 +void svga_render_24bpp_highres() 55.429 +{ 55.430 + int x, offset; 55.431 + uint32_t fg; 55.432 + 55.433 + if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 55.434 + { 55.435 + if (firstline_draw == 2000) firstline_draw = displine; 55.436 + lastline_draw = displine; 55.437 + 55.438 + offset = (8 - ((scrollcache & 6) >> 1)) + 24; 55.439 + 55.440 + for (x = 0; x <= svga_hdisp; x++) 55.441 + { 55.442 + fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16); 55.443 + ma+=3; ma&=vrammask; 55.444 + ((uint32_t *)buffer32->line[displine])[x + offset] = fg; 55.445 + } 55.446 + } 55.447 +} 55.448 + 55.449 +void svga_render_32bpp_lowres() 55.450 +{ 55.451 + int x, offset; 55.452 + uint32_t fg; 55.453 + 55.454 + if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 55.455 + { 55.456 + if (firstline_draw == 2000) firstline_draw = displine; 55.457 + lastline_draw = displine; 55.458 + 55.459 + offset=(8-(scrollcache&6))+24; 55.460 + 55.461 + for (x = 0; x <= svga_hdisp; x++) 55.462 + { 55.463 + fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16); 55.464 + ma += 4; ma &= vrammask; 55.465 + ((uint32_t *)buffer32->line[displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[displine])[(x << 1) + 1 + offset] = fg; 55.466 + } 55.467 + } 55.468 +} 55.469 + 55.470 +void svga_render_32bpp_highres() 55.471 +{ 55.472 + int x, offset; 55.473 + uint32_t fg; 55.474 + 55.475 + if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 55.476 + { 55.477 + if (firstline_draw == 2000) firstline_draw = displine; 55.478 + lastline_draw = displine; 55.479 + 55.480 + offset = (8 - ((scrollcache & 6) >> 1)) + 24; 55.481 + 55.482 + for (x = 0; x <= svga_hdisp; x++) 55.483 + { 55.484 + fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16); 55.485 + ma+=4; ma&=vrammask; 55.486 + ((uint32_t *)buffer32->line[displine])[x + offset] = fg; 55.487 + } 55.488 + } 55.489 +} 55.490 +
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/src/vid_svga_render.h Mon May 27 19:56:33 2013 +0100 56.3 @@ -0,0 +1,30 @@ 56.4 +extern int firstline_draw, lastline_draw; 56.5 +extern int displine; 56.6 +extern int sc; 56.7 + 56.8 +extern uint32_t ma, ca; 56.9 +extern int con, cursoron, cgablink; 56.10 + 56.11 +extern int scrollcache; 56.12 + 56.13 +extern uint8_t edatlookup[4][4]; 56.14 + 56.15 +void svga_render_blank(); 56.16 +void svga_render_text_40(); 56.17 +void svga_render_text_80(); 56.18 + 56.19 +void svga_render_2bpp_lowres(); 56.20 +void svga_render_4bpp_lowres(); 56.21 +void svga_render_4bpp_highres(); 56.22 +void svga_render_8bpp_lowres(); 56.23 +void svga_render_8bpp_highres(); 56.24 +void svga_render_15bpp_lowres(); 56.25 +void svga_render_15bpp_highres(); 56.26 +void svga_render_16bpp_lowres(); 56.27 +void svga_render_16bpp_highres(); 56.28 +void svga_render_24bpp_lowres(); 56.29 +void svga_render_24bpp_highres(); 56.30 +void svga_render_32bpp_lowres(); 56.31 +void svga_render_32bpp_highres(); 56.32 + 56.33 +extern void (*svga_render)();
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/src/vid_vga.c Mon May 27 19:56:33 2013 +0100 57.3 @@ -0,0 +1,92 @@ 57.4 +/*IBM VGA emulation*/ 57.5 +#include "ibm.h" 57.6 +#include "io.h" 57.7 +#include "video.h" 57.8 +#include "vid_svga.h" 57.9 + 57.10 +void vga_out(uint16_t addr, uint8_t val, void *priv) 57.11 +{ 57.12 + uint8_t old; 57.13 + 57.14 + pclog("vga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,pc, ram[0x489], ins); 57.15 + 57.16 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 57.17 + 57.18 + switch (addr) 57.19 + { 57.20 + case 0x3D4: 57.21 + crtcreg = val & 0x1f; 57.22 + return; 57.23 + case 0x3D5: 57.24 + if (crtcreg <= 7 && crtc[0x11] & 0x80) return; 57.25 + old=crtc[crtcreg]; 57.26 + crtc[crtcreg]=val; 57.27 + if (old!=val) 57.28 + { 57.29 + if (crtcreg<0xE || crtcreg>0x10) 57.30 + { 57.31 + fullchange=changeframecount; 57.32 + svga_recalctimings(); 57.33 + } 57.34 + } 57.35 + break; 57.36 + } 57.37 + svga_out(addr, val, NULL); 57.38 +} 57.39 + 57.40 +uint8_t vga_in(uint16_t addr, void *priv) 57.41 +{ 57.42 + uint8_t temp; 57.43 + 57.44 + if (addr != 0x3da) pclog("vga_in : %04X ", addr); 57.45 + 57.46 + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 57.47 + 57.48 + switch (addr) 57.49 + { 57.50 + case 0x3D4: 57.51 + temp = crtcreg; 57.52 + break; 57.53 + case 0x3D5: 57.54 + temp = crtc[crtcreg]; 57.55 + break; 57.56 + default: 57.57 + temp = svga_in(addr, NULL); 57.58 + break; 57.59 + } 57.60 + if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); 57.61 + return temp; 57.62 +} 57.63 + 57.64 +int vga_init() 57.65 +{ 57.66 + svga_recalctimings_ex = NULL; 57.67 + svga_vram_limit = 1 << 18; /*256kb*/ 57.68 + vrammask = 0x3ffff; 57.69 + svgawbank = svgarbank = 0; 57.70 + bpp = 8; 57.71 + svga_miscout = 1; 57.72 + return svga_init(); 57.73 +} 57.74 + 57.75 +GFXCARD vid_vga = 57.76 +{ 57.77 + vga_init, 57.78 + /*IO at 3Cx/3Dx*/ 57.79 + vga_out, 57.80 + vga_in, 57.81 + /*IO at 3Ax/3Bx*/ 57.82 + video_out_null, 57.83 + video_in_null, 57.84 + 57.85 + svga_poll, 57.86 + svga_recalctimings, 57.87 + 57.88 + svga_write, 57.89 + video_write_null, 57.90 + video_write_null, 57.91 + 57.92 + svga_read, 57.93 + video_read_null, 57.94 + video_read_null 57.95 +};
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/src/vid_voodoo.c Mon May 27 19:56:33 2013 +0100 58.3 @@ -0,0 +1,732 @@ 58.4 +#include <stdlib.h> 58.5 +#include "ibm.h" 58.6 +#include "mem.h" 58.7 +#include "pci.h" 58.8 +#include "vid_voodoo.h" 58.9 + 58.10 +static int tris = 0; 58.11 + 58.12 +static struct voodoo 58.13 +{ 58.14 + int pci_enable; 58.15 + 58.16 + uint32_t color0, color1; 58.17 + 58.18 + uint8_t dac_data[8]; 58.19 + int dac_reg; 58.20 + uint8_t dac_readdata; 58.21 + 58.22 + uint32_t dRdX, dGdX, dBdX, dZdX, dAdX, dSdX, dTdX, dWdX; 58.23 + 58.24 + uint32_t dRdY, dGdY, dBdY, dZdY, dAdY, dSdY, dTdY, dWdY; 58.25 + 58.26 + uint32_t fbiInit0, fbiInit1, fbiInit2, fbiInit3, fbiInit4; 58.27 + 58.28 + uint32_t fbzMode; 58.29 + 58.30 + uint8_t initEnable; 58.31 + 58.32 + uint32_t lfbMode; 58.33 + 58.34 + uint32_t memBaseAddr; 58.35 + 58.36 + uint32_t startR, startG, startB, startZ, startA, startS, startT, startW; 58.37 + 58.38 + uint32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; 58.39 + 58.40 + uint32_t front_offset, back_offset, aux_offset; 58.41 + 58.42 + uint32_t fb_read_offset, fb_write_offset; 58.43 + 58.44 + uint32_t draw_offset; 58.45 + 58.46 + int row_width; 58.47 + 58.48 + uint8_t *fb_mem, *tex_mem; 58.49 +} voodoo; 58.50 + 58.51 +enum 58.52 +{ 58.53 + SST_status = 0x000, 58.54 + 58.55 + SST_vertexAx = 0x008, 58.56 + SST_vertexAy = 0x00c, 58.57 + SST_vertexBx = 0x010, 58.58 + SST_vertexBy = 0x014, 58.59 + SST_vertexCx = 0x018, 58.60 + SST_vertexCy = 0x01c, 58.61 + 58.62 + SST_startR = 0x0020, 58.63 + SST_startG = 0x0024, 58.64 + SST_startB = 0x0028, 58.65 + SST_startZ = 0x002c, 58.66 + SST_startA = 0x0030, 58.67 + SST_startS = 0x0034, 58.68 + SST_startT = 0x0038, 58.69 + SST_startW = 0x003c, 58.70 + 58.71 + SST_dRdX = 0x0040, 58.72 + SST_dGdX = 0x0044, 58.73 + SST_dBdX = 0x0048, 58.74 + SST_dZdX = 0x004c, 58.75 + SST_dAdX = 0x0050, 58.76 + SST_dSdX = 0x0054, 58.77 + SST_dTdX = 0x0058, 58.78 + SST_dWdX = 0x005c, 58.79 + 58.80 + SST_dRdY = 0x0060, 58.81 + SST_dGdY = 0x0064, 58.82 + SST_dBdY = 0x0068, 58.83 + SST_dZdY = 0x006c, 58.84 + SST_dAdY = 0x0070, 58.85 + SST_dSdY = 0x0074, 58.86 + SST_dTdY = 0x0078, 58.87 + SST_dWdY = 0x007c, 58.88 + 58.89 + SST_triangleCMD = 0x0080, 58.90 + 58.91 + SST_fbzMode = 0x110, 58.92 + SST_lfbMode = 0x114, 58.93 + SST_swapbufferCMD = 0x128, 58.94 + 58.95 + SST_color0 = 0x144, 58.96 + SST_color1 = 0x148, 58.97 + 58.98 + SST_fbiInit4 = 0x200, 58.99 + SST_fbiInit0 = 0x210, 58.100 + SST_fbiInit1 = 0x214, 58.101 + SST_fbiInit2 = 0x218, 58.102 + SST_fbiInit3 = 0x21c, 58.103 + SST_dacData = 0x22c 58.104 +}; 58.105 + 58.106 +enum 58.107 +{ 58.108 + LFB_WRITE_FRONT = 0x0000, 58.109 + LFB_WRITE_BACK = 0x0010, 58.110 + LFB_WRITE_MASK = 0x0030 58.111 +}; 58.112 + 58.113 +enum 58.114 +{ 58.115 + LFB_READ_FRONT = 0x0000, 58.116 + LFB_READ_BACK = 0x0040, 58.117 + LFB_READ_AUX = 0x0080, 58.118 + LFB_READ_MASK = 0x00c0 58.119 +}; 58.120 + 58.121 +enum 58.122 +{ 58.123 + LFB_FORMAT_RGB565 = 0, 58.124 + LFB_FORMAT_DEPTH = 15, 58.125 + LFB_FORMAT_MASK = 15 58.126 +}; 58.127 + 58.128 +enum 58.129 +{ 58.130 + LFB_WRITE_COLOUR = 1, 58.131 + LFB_WRITE_DEPTH = 2 58.132 +}; 58.133 + 58.134 +enum 58.135 +{ 58.136 + FBZ_DITHER = 0x100, 58.137 + FBZ_DRAWRGB = 0x200, 58.138 + 58.139 + FBZ_DRAW_FRONT = 0x0000, 58.140 + FBZ_DRAW_BACK = 0x4000, 58.141 + FBZ_DRAW_MASK = 0xc000 58.142 +}; 58.143 + 58.144 +static int voodoo_reads = 0; 58.145 + 58.146 +static void voodoo_recalc() 58.147 +{ 58.148 + uint32_t buffer_offset = ((voodoo.fbiInit2 >> 11) & 511) * 4096; 58.149 + 58.150 + voodoo.front_offset = 0; 58.151 + voodoo.back_offset = buffer_offset; 58.152 + voodoo.aux_offset = buffer_offset * 2; 58.153 + 58.154 + switch (voodoo.lfbMode & LFB_WRITE_MASK) 58.155 + { 58.156 + case LFB_WRITE_FRONT: 58.157 + voodoo.fb_write_offset = voodoo.front_offset; 58.158 + break; 58.159 + case LFB_WRITE_BACK: 58.160 + voodoo.fb_write_offset = voodoo.back_offset; 58.161 + break; 58.162 + 58.163 + default: 58.164 + fatal("voodoo_recalc : unknown lfb destination\n"); 58.165 + } 58.166 + 58.167 + switch (voodoo.lfbMode & LFB_READ_MASK) 58.168 + { 58.169 + case LFB_READ_FRONT: 58.170 + voodoo.fb_read_offset = voodoo.front_offset; 58.171 + break; 58.172 + case LFB_READ_BACK: 58.173 + voodoo.fb_read_offset = voodoo.back_offset; 58.174 + break; 58.175 + case LFB_READ_AUX: 58.176 + voodoo.fb_read_offset = voodoo.aux_offset; 58.177 + break; 58.178 + 58.179 + default: 58.180 + fatal("voodoo_recalc : unknown lfb source\n"); 58.181 + } 58.182 + 58.183 + switch (voodoo.fbzMode & FBZ_DRAW_MASK) 58.184 + { 58.185 + case FBZ_DRAW_FRONT: 58.186 + voodoo.draw_offset = voodoo.front_offset; 58.187 + break; 58.188 + case FBZ_DRAW_BACK: 58.189 + voodoo.draw_offset = voodoo.back_offset; 58.190 + break; 58.191 + 58.192 + default: 58.193 + fatal("voodoo_recalc : unknown draw buffer\n"); 58.194 + } 58.195 + 58.196 + voodoo.row_width = ((voodoo.fbiInit1 >> 4) & 15) * 64 * 2; 58.197 + pclog("voodoo_recalc : front_offset %08X back_offset %08X aux_offset %08X\n", voodoo.front_offset, voodoo.back_offset, voodoo.aux_offset); 58.198 + pclog(" fb_read_offset %08X fb_write_offset %08X row_width %i\n", voodoo.fb_read_offset, voodoo.fb_write_offset, voodoo.row_width); 58.199 +} 58.200 + 58.201 +static int dither_matrix_4x4[16] = 58.202 +{ 58.203 + 0, 8, 2, 10, 58.204 + 12, 4, 14, 6, 58.205 + 3, 11, 1, 9, 58.206 + 15, 7, 13, 5 58.207 +}; 58.208 + 58.209 +static int dither_rb[256][4][4]; 58.210 +static int dither_g[256][4][4]; 58.211 + 58.212 +static void voodoo_make_dither() 58.213 +{ 58.214 + int c, x, y; 58.215 + int seen_rb[1024]; 58.216 + int seen_g[1024]; 58.217 + 58.218 + for (c = 0; c < 256; c++) 58.219 + { 58.220 + int rb = (int)(((double)c * 496.0) / 256.0); 58.221 + int g = (int)(((double)c * 1008.0) / 256.0); 58.222 + pclog("rb %i %i\n", rb, c); 58.223 + for (y = 0; y < 4; y++) 58.224 + { 58.225 + for (x = 0; x < 4; x++) 58.226 + { 58.227 + int val; 58.228 + 58.229 + val = rb + dither_matrix_4x4[x + (y << 2)]; 58.230 + dither_rb[c][y][x] = val >> 4; 58.231 + pclog("RB %i %i, %i %i %i %i\n", c, x, y, val, val >> 4, dither_rb[c][y][x]); 58.232 + 58.233 + if (dither_rb[c][y][x] > 31) 58.234 + fatal("RB overflow %i %i %i %i\n", c, x, y, dither_rb[c][y][x]); 58.235 + 58.236 + val = g + dither_matrix_4x4[x + (y << 2)]; 58.237 + dither_g[c][y][x] = val >> 4; 58.238 + 58.239 + if (dither_g[c][y][x] > 63) 58.240 + fatal("G overflow %i %i %i %i\n", c, x, y, dither_g[c][y][x]); 58.241 + } 58.242 + } 58.243 + } 58.244 + 58.245 + memset(seen_rb, 0, sizeof(seen_rb)); 58.246 + memset(seen_g, 0, sizeof(seen_g)); 58.247 + 58.248 + for (c = 0; c < 256; c++) 58.249 + { 58.250 + int total_rb = 0; 58.251 + int total_g = 0; 58.252 + for (y = 0; y < 4; y++) 58.253 + { 58.254 + for (x = 0; x < 4; x++) 58.255 + { 58.256 + total_rb += dither_rb[c][y][x]; 58.257 + pclog("total_rb %i %i, %i %i %i\n", c, x, y, total_rb, dither_rb[c][y][x]); 58.258 + total_g += dither_g[c][y][x]; 58.259 + } 58.260 + } 58.261 + 58.262 + if (seen_rb[total_rb]) 58.263 + fatal("Duplicate rb %i %i\n", c, total_rb); 58.264 + seen_rb[total_rb] = 1; 58.265 + 58.266 + if (seen_g[total_g]) 58.267 + fatal("Duplicate g %i %i\n", c, total_g); 58.268 + seen_g[total_g] = 1; 58.269 + } 58.270 +} 58.271 + 58.272 +static void voodoo_triangle(struct voodoo *voodoo) 58.273 +{ 58.274 + int y, yend, ydir; 58.275 + int xstart, xend, xdir; 58.276 + int dx1, dx2; 58.277 + 58.278 + pclog("voodoo_triangle %i : vA %f, %f vB %f, %f vC %f, %f\n", tris, (float)voodoo->vertexAx / 16.0, (float)voodoo->vertexAy / 16.0, 58.279 + (float)voodoo->vertexBx / 16.0, (float)voodoo->vertexBy / 16.0, 58.280 + (float)voodoo->vertexCx / 16.0, (float)voodoo->vertexCy / 16.0); 58.281 +// output = 3; 58.282 + tris++; 58.283 +// if (tris == 3) 58.284 +// fatal("tris 2\n"); 58.285 + 58.286 + y = voodoo->vertexAy >> 4; 58.287 + ydir = (voodoo->vertexAy >= voodoo->vertexCy) ? -1 : 1; 58.288 + 58.289 + if (voodoo->vertexAy == voodoo->vertexBy) 58.290 + { 58.291 + xstart = voodoo->vertexAx << 8; 58.292 + xend = voodoo->vertexBx << 8; 58.293 + } 58.294 + else 58.295 + xstart = xend = voodoo->vertexAx << 8; 58.296 + xdir = (xstart >= xend) ? -1 : 1; 58.297 + 58.298 + if (voodoo->vertexAy != voodoo->vertexBy) 58.299 + { 58.300 + /*Draw top half*/ 58.301 + dx1 = (int)(((voodoo->vertexBx << 8) - xstart) << 4) / (int)((voodoo->vertexBy - voodoo->vertexAy) * ydir); 58.302 + dx2 = (int)(((voodoo->vertexCx << 8) - xend) << 4) / (int)((voodoo->vertexCy - voodoo->vertexAy) * ydir); 58.303 + yend = voodoo->vertexBy >> 4; 58.304 + 58.305 + pclog("voodoo_triangle : top-half %X %X %X %X %i %i %i %i\n", xstart, xend, dx1, dx2, xdir, y, yend, ydir); 58.306 + 58.307 + for (; y != yend; y += ydir) 58.308 + { 58.309 + pclog(" %i : %i - %i\n", xstart >> 12, xend >> 12); 58.310 + xstart += dx1; 58.311 + xend += dx2; 58.312 + } 58.313 + } 58.314 + 58.315 + 58.316 + if (voodoo->vertexBy != voodoo->vertexCy) 58.317 + { 58.318 + /*Draw bottom half*/ 58.319 + dx1 = (int)(((voodoo->vertexCx << 8) - xstart) << 4) / (int)((voodoo->vertexCy - voodoo->vertexAy) * ydir); 58.320 + dx2 = (int)(((voodoo->vertexCx << 8) - xend) << 4) / (int)((voodoo->vertexCy - voodoo->vertexAy) * ydir); 58.321 + yend = voodoo->vertexCy >> 4; 58.322 + 58.323 + pclog("voodoo_triangle : bottom-half %X %X %X %X %X %i %i %i %i\n", xstart, xend, dx1, dx2, dx2 * 36, xdir, y, yend, ydir); 58.324 + 58.325 + for (; y != yend; y += ydir) 58.326 + { 58.327 + int x = xstart >> 12, x2 = xend >> 12; 58.328 + pclog(" %i : %i - %i\n", y, x, x2); 58.329 + 58.330 + for (; x != x2; x += xdir) 58.331 + { 58.332 + if (voodoo->fbzMode & FBZ_DRAWRGB) 58.333 + { 58.334 + int r = (voodoo->color1 >> 16) & 0xff; 58.335 + int g = (voodoo->color1 >> 8) & 0xff; 58.336 + int b = voodoo->color1 & 0xff; 58.337 + if (voodoo->fbzMode & FBZ_DITHER) 58.338 + { 58.339 + r = dither_rb[r][y & 3][x & 3]; 58.340 + g = dither_g[g][y & 3][x & 3]; 58.341 + b = dither_rb[b][y & 3][x & 3]; 58.342 +/* r = ((r << 1) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 4; 58.343 + g = ((g << 2) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 4; 58.344 + b = ((b << 1) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 4; 58.345 + if (r > 31) r = 31; 58.346 + if (g > 63) g = 63; 58.347 + if (b > 31) b = 31;*/ 58.348 +/* r = (((r << 1) - (r >> 4) + (r >> 7) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 1) >> 3; 58.349 + g = (((g << 2) - (g >> 4) + (g >> 6) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 2) >> 2; 58.350 + b = (((b << 1) - (b >> 4) + (b >> 7) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 1) >> 3;*/ 58.351 + } 58.352 + else 58.353 + { 58.354 + r >>= 3; 58.355 + g >>= 2; 58.356 + b >>= 3; 58.357 + } 58.358 + *(uint16_t *)(&voodoo->fb_mem[voodoo->draw_offset + (y * voodoo->row_width) + (x << 1)]) = b | (g << 5) | (r << 11); 58.359 + pclog(" %i = %i %i %i %04X %08X %08X\n", x, r, g, b, b | (g << 5) | (r << 11), voodoo->draw_offset + (y * voodoo->row_width) + (x << 1), *(uint32_t *)(&voodoo->fb_mem[4])); 58.360 + } 58.361 + } 58.362 + xstart += dx1; 58.363 + xend += dx2; 58.364 + } 58.365 + } 58.366 + 58.367 +/* for (y = ystart, y != yend; y += ydir) 58.368 + { 58.369 + if (voodoo.fbzMode & FBZ_DITHER 58.370 + }*/ 58.371 +} 58.372 + 58.373 +static uint32_t voodoo_readl(uint32_t addr, void *priv) 58.374 +{ 58.375 + uint32_t temp; 58.376 + switch (addr & 0x3fc) 58.377 + { 58.378 + case SST_status: 58.379 + temp = 0x0ffff03f; /*FIFOs empty*/ 58.380 + break; 58.381 + 58.382 + case SST_lfbMode: 58.383 + return voodoo.lfbMode; 58.384 + 58.385 + case SST_fbiInit4: 58.386 + temp = voodoo.fbiInit4; 58.387 + break; 58.388 + case SST_fbiInit0: 58.389 + temp = voodoo.fbiInit0; 58.390 + break; 58.391 + case SST_fbiInit1: 58.392 + temp = voodoo.fbiInit1 & ~5; /*Pass-thru board with one SST-1*/ 58.393 + break; 58.394 + case SST_fbiInit2: 58.395 + if (voodoo.initEnable & 0x04) 58.396 + temp = voodoo.dac_readdata; 58.397 + else 58.398 + temp = voodoo.fbiInit2; 58.399 + break; 58.400 + case SST_fbiInit3: 58.401 + temp = voodoo.fbiInit3; 58.402 + break; 58.403 + 58.404 + default: 58.405 + fatal("voodoo_readl : bad addr %08X\n", addr); 58.406 + temp = 0xffffffff; 58.407 + } 58.408 + pclog("voodoo_readl : addr %08X val %08X %04X(%08X):%08X %i\n", addr, temp, CS, cs, pc, voodoo_reads++); 58.409 +// if (voodoo_reads == 200494) 58.410 +// output = 3; 58.411 + return temp; 58.412 +} 58.413 + 58.414 +static void voodoo_writel(uint32_t addr, uint32_t val, void *priv) 58.415 +{ 58.416 + pclog("voodoo_writel : addr %08X val %08X %04X(%08X):%08X\n", addr, val, CS, cs, pc); 58.417 + switch (addr & 0x3fc) 58.418 + { 58.419 + case SST_swapbufferCMD: 58.420 + pclog(" start swap buffer command\n"); 58.421 +// output = 3; 58.422 + break; 58.423 + 58.424 + case SST_vertexAx: 58.425 + voodoo.vertexAx = val & 0xffff; 58.426 + break; 58.427 + case SST_vertexAy: 58.428 + voodoo.vertexAy = val & 0xffff; 58.429 + break; 58.430 + case SST_vertexBx: 58.431 + voodoo.vertexBx = val & 0xffff; 58.432 + break; 58.433 + case SST_vertexBy: 58.434 + voodoo.vertexBy = val & 0xffff; 58.435 + break; 58.436 + case SST_vertexCx: 58.437 + voodoo.vertexCx = val & 0xffff; 58.438 + break; 58.439 + case SST_vertexCy: 58.440 + voodoo.vertexCy = val & 0xffff; 58.441 + break; 58.442 + 58.443 + case SST_startR: 58.444 + voodoo.startR = val & 0xffffff; 58.445 + break; 58.446 + case SST_startG: 58.447 + voodoo.startG = val & 0xffffff; 58.448 + break; 58.449 + case SST_startB: 58.450 + voodoo.startB = val & 0xffffff; 58.451 + break; 58.452 + case SST_startZ: 58.453 + voodoo.startZ = val; 58.454 + break; 58.455 + case SST_startA: 58.456 + voodoo.startA = val & 0xffffff; 58.457 + break; 58.458 + case SST_startS: 58.459 + voodoo.startS = val; 58.460 + break; 58.461 + case SST_startT: 58.462 + voodoo.startT = val; 58.463 + break; 58.464 + case SST_startW: 58.465 + voodoo.startW = val; 58.466 + break; 58.467 + 58.468 + case SST_dRdX: 58.469 + voodoo.dRdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); 58.470 + break; 58.471 + case SST_dGdX: 58.472 + voodoo.dGdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); 58.473 + break; 58.474 + case SST_dBdX: 58.475 + voodoo.dBdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); 58.476 + break; 58.477 + case SST_dZdX: 58.478 + voodoo.dZdX = val; 58.479 + break; 58.480 + case SST_dAdX: 58.481 + voodoo.dAdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); 58.482 + break; 58.483 + case SST_dSdX: 58.484 + voodoo.dSdX = val; 58.485 + break; 58.486 + case SST_dTdX: 58.487 + voodoo.dTdX = val; 58.488 + break; 58.489 + case SST_dWdX: 58.490 + voodoo.dWdX = val; 58.491 + break; 58.492 + 58.493 + case SST_dRdY: 58.494 + voodoo.dRdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); 58.495 + break; 58.496 + case SST_dGdY: 58.497 + voodoo.dGdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); 58.498 + break; 58.499 + case SST_dBdY: 58.500 + voodoo.dBdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); 58.501 + break; 58.502 + case SST_dZdY: 58.503 + voodoo.dZdY = val; 58.504 + break; 58.505 + case SST_dAdY: 58.506 + voodoo.dAdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); 58.507 + break; 58.508 + case SST_dSdY: 58.509 + voodoo.dSdY = val; 58.510 + break; 58.511 + case SST_dTdY: 58.512 + voodoo.dTdY = val; 58.513 + break; 58.514 + case SST_dWdY: 58.515 + voodoo.dWdY = val; 58.516 + break; 58.517 + 58.518 + case SST_triangleCMD: 58.519 + voodoo_triangle(&voodoo); 58.520 + break; 58.521 + 58.522 + 58.523 + case SST_fbzMode: 58.524 + voodoo.fbzMode = val; 58.525 + break; 58.526 + case SST_lfbMode: 58.527 + voodoo.lfbMode = val; 58.528 + voodoo_recalc(); 58.529 + break; 58.530 + 58.531 + case SST_color0: 58.532 + voodoo.color0 = val; 58.533 + break; 58.534 + case SST_color1: 58.535 + voodoo.color1 = val; 58.536 + break; 58.537 + 58.538 + case SST_fbiInit4: 58.539 + if (voodoo.initEnable & 0x01) 58.540 + voodoo.fbiInit4 = val; 58.541 + break; 58.542 + case SST_fbiInit0: 58.543 + if (voodoo.initEnable & 0x01) 58.544 + voodoo.fbiInit0 = val; 58.545 + break; 58.546 + case SST_fbiInit1: 58.547 + if (voodoo.initEnable & 0x01) 58.548 + voodoo.fbiInit1 = val; 58.549 + break; 58.550 + case SST_fbiInit2: 58.551 + if (voodoo.initEnable & 0x01) 58.552 + { 58.553 + voodoo.fbiInit2 = val; 58.554 + voodoo_recalc(); 58.555 + } 58.556 + break; 58.557 + case SST_fbiInit3: 58.558 + if (voodoo.initEnable & 0x01) 58.559 + voodoo.fbiInit3 = val; 58.560 + break; 58.561 + 58.562 + case SST_dacData: 58.563 + voodoo.dac_reg = (val >> 8) & 7; 58.564 + voodoo.dac_readdata = 0xff; 58.565 + if (val & 0x800) 58.566 + { 58.567 + pclog(" dacData read %i %02X\n", voodoo.dac_reg, voodoo.dac_data[7]); 58.568 + if (voodoo.dac_reg == 5) 58.569 + { 58.570 + switch (voodoo.dac_data[7]) 58.571 + { 58.572 + case 0x01: voodoo.dac_readdata = 0x55; break; 58.573 + case 0x07: voodoo.dac_readdata = 0x71; break; 58.574 + case 0x0b: voodoo.dac_readdata = 0x79; break; 58.575 + } 58.576 + } 58.577 + else 58.578 + voodoo.dac_readdata = voodoo.dac_data[voodoo.dac_readdata]; 58.579 + } 58.580 + else 58.581 + voodoo.dac_data[voodoo.dac_reg] = val & 0xff; 58.582 + break; 58.583 + } 58.584 +} 58.585 + 58.586 +static uint16_t voodoo_fb_readw(uint32_t addr, void *priv) 58.587 +{ 58.588 + pclog("voodoo_fb_readw : %08X %04X\n", addr, *(uint16_t *)(&voodoo.fb_mem[addr & 0x1fffff])); 58.589 + return *(uint16_t *)(&voodoo.fb_mem[addr & 0x1fffff]); 58.590 +} 58.591 +static uint32_t voodoo_fb_readl(uint32_t addr, void *priv) 58.592 +{ 58.593 + int x, y; 58.594 + uint32_t read_addr; 58.595 + uint32_t temp; 58.596 + 58.597 + x = (addr >> 1) & 0x3ff; 58.598 + y = (addr >> 11) & 0x3ff; 58.599 + read_addr = voodoo.fb_read_offset + (x << 1) + (y * voodoo.row_width); 58.600 + 58.601 + temp = *(uint32_t *)(&voodoo.fb_mem[read_addr & 0x1fffff]); 58.602 + 58.603 + pclog("voodoo_fb_readl : %08X %08X %i %i %08X %08X\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo.fb_mem[4])); 58.604 + return temp; 58.605 +} 58.606 +static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv) 58.607 +{ 58.608 + pclog("voodoo_fb_writew : %08X %04X\n", addr, val); 58.609 + *(uint16_t *)(&voodoo.fb_mem[addr & 0x1fffff]) = val; 58.610 +} 58.611 +static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv) 58.612 +{ 58.613 + int x, y; 58.614 + uint32_t write_addr, write_addr_aux; 58.615 + uint32_t colour_data, depth_data; 58.616 + int write_mask, count = 1; 58.617 + 58.618 + pclog("voodoo_fb_writel : %08X %08X\n", addr, val); 58.619 + 58.620 + if (voodoo.lfbMode & 0x100) 58.621 + fatal("voodoo_fb_writel : using pixel processing\n"); 58.622 + 58.623 + switch (voodoo.lfbMode & LFB_FORMAT_MASK) 58.624 + { 58.625 + case LFB_FORMAT_RGB565: 58.626 + colour_data = val; 58.627 + write_mask = LFB_WRITE_COLOUR; 58.628 + break; 58.629 + 58.630 + case LFB_FORMAT_DEPTH: 58.631 + depth_data = val; 58.632 + write_mask = LFB_WRITE_DEPTH; 58.633 + addr <<= 1; 58.634 + count = 2; 58.635 + break; 58.636 + 58.637 + default: 58.638 + fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo.lfbMode); 58.639 + } 58.640 + 58.641 + x = addr & 0x3fe; 58.642 + y = (addr >> 10) & 0x3ff; 58.643 + 58.644 + write_addr = voodoo.fb_read_offset + x + (y * voodoo.row_width); 58.645 + write_addr_aux = voodoo.aux_offset + x + (y * voodoo.row_width); 58.646 + 58.647 + while (count--) 58.648 + { 58.649 + if (write_mask & LFB_WRITE_COLOUR) 58.650 + *(uint16_t *)(&voodoo.fb_mem[write_addr & 0x1ffffe]) = colour_data; 58.651 + if (write_mask & LFB_WRITE_DEPTH) 58.652 + *(uint16_t *)(&voodoo.fb_mem[write_addr_aux & 0x1ffffe]) = depth_data; 58.653 + 58.654 + colour_data >>= 16; 58.655 + depth_data >>= 16; 58.656 + 58.657 + write_addr += 2; 58.658 + write_addr_aux += 2; 58.659 + } 58.660 +} 58.661 + 58.662 +static void voodoo_tex_writew(uint32_t addr, uint16_t val, void *priv) 58.663 +{ 58.664 + pclog("voodoo_tex_write : %08X %04X\n", addr, val); 58.665 + *(uint16_t *)(&voodoo.tex_mem[addr & 0x1fffff]) = val; 58.666 +} 58.667 +static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *priv) 58.668 +{ 58.669 + pclog("voodoo_tex_write : %08X %08X\n", addr, val); 58.670 + *(uint32_t *)(&voodoo.tex_mem[addr & 0x1fffff]) = val; 58.671 +} 58.672 + 58.673 +static void voodoo_recalcmapping() 58.674 +{ 58.675 + mem_removehandler(0x00000000, 0xffffffff, NULL, NULL, voodoo_readl, NULL, NULL, voodoo_writel, NULL); 58.676 + mem_removehandler(0x00000000, 0xffffffff, NULL, voodoo_fb_readw, voodoo_fb_readl, NULL, voodoo_fb_writew, voodoo_fb_writel, NULL); 58.677 + mem_removehandler(0x00000000, 0xffffffff, NULL, NULL, NULL, NULL, voodoo_tex_writew, voodoo_tex_writel, NULL); 58.678 + if (voodoo.pci_enable) 58.679 + { 58.680 + pclog("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo.memBaseAddr); 58.681 + mem_sethandler(voodoo.memBaseAddr, 0x003fffff, NULL, NULL, voodoo_readl, NULL, NULL, voodoo_writel, NULL); 58.682 + mem_sethandler(voodoo.memBaseAddr + 0x00400000, 0x003fffff, NULL, voodoo_fb_readw, voodoo_fb_readl, NULL, voodoo_fb_writew, voodoo_fb_writel, NULL); 58.683 + mem_sethandler(voodoo.memBaseAddr + 0x00800000, 0x007fffff, NULL, NULL, NULL, NULL, voodoo_tex_writew, voodoo_tex_writel, NULL); 58.684 + } 58.685 + else 58.686 + pclog("voodoo_recalcmapping : disabled\n"); 58.687 +} 58.688 + 58.689 +uint8_t voodoo_pci_read(int func, int addr, void *priv) 58.690 +{ 58.691 + pclog("Voodoo PCI read %08X\n", addr); 58.692 + switch (addr) 58.693 + { 58.694 + case 0x00: return 0x1a; /*3dfx*/ 58.695 + case 0x01: return 0x12; 58.696 + 58.697 + case 0x02: return 0x01; /*SST-1 (Voodoo Graphics)*/ 58.698 + case 0x03: return 0x00; 58.699 + 58.700 + case 0x04: return voodoo.pci_enable ? 0x02 : 0x00; /*Respond to memory accesses*/ 58.701 + 58.702 + case 0x08: return 0; /*Revision ID*/ 58.703 + case 0x09: return 0; /*Programming interface*/ 58.704 + 58.705 + case 0x10: return 0x00; /*memBaseAddr*/ 58.706 + case 0x11: return 0x00; 58.707 + case 0x12: return 0x00; 58.708 + case 0x13: return voodoo.memBaseAddr >> 24; 58.709 + 58.710 + case 0x40: return voodoo.initEnable; 58.711 + } 58.712 + return 0; 58.713 +} 58.714 + 58.715 +void voodoo_pci_write(int func, int addr, uint8_t val, void *priv) 58.716 +{ 58.717 + pclog("Voodoo PCI write %04X %02X\n", addr, val); 58.718 + switch (addr) 58.719 + { 58.720 + case 0x04: voodoo.pci_enable = val & 2; voodoo_recalcmapping(); break; 58.721 + 58.722 + case 0x13: voodoo.memBaseAddr = val << 24; voodoo_recalcmapping(); break; 58.723 + 58.724 + case 0x40: voodoo.initEnable = val; break; 58.725 + } 58.726 +} 58.727 + 58.728 +void voodoo_init() 58.729 +{ 58.730 + return; 58.731 + voodoo_make_dither(); 58.732 + pci_add(voodoo_pci_read, voodoo_pci_write, NULL); 58.733 + voodoo.fb_mem = malloc(2 * 1024 * 1024); 58.734 + voodoo.tex_mem = malloc(2 * 1024 * 1024); 58.735 +}
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2 +++ b/src/vid_voodoo.h Mon May 27 19:56:33 2013 +0100 59.3 @@ -0,0 +1,1 @@ 59.4 +void voodoo_init();
60.1 --- a/src/x86.c Mon May 27 17:46:42 2013 +0100 60.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 60.3 @@ -1,3686 +0,0 @@ 60.4 -//1B64 - Vid_SetMode (Vid_Vesa.c) 60.5 -//6689c - CONS_Printf 60.6 -/*SHR AX,1 60.7 - 60.8 - 4 clocks - fetch opcode 60.9 - 4 clocks - fetch mod/rm 60.10 - 2 clocks - execute 2 clocks - fetch opcode 1 60.11 - 2 clocks - fetch opcode 2 60.12 - 4 clocks - fetch mod/rm 60.13 - 2 clocks - fetch opcode 1 2 clocks - execute 60.14 - 2 clocks - fetch opcode 2 etc*/ 60.15 -#include <stdio.h> 60.16 -#include "ibm.h" 60.17 -#include "x86.h" 60.18 -#include "mem.h" 60.19 -#include "keyboard.h" 60.20 - 60.21 -int nextcyc=0; 60.22 -int cycdiff; 60.23 -int is8086=0; 60.24 - 60.25 -int memcycs; 60.26 -int nopageerrors=0; 60.27 -float cassettetime; 60.28 - 60.29 -void FETCHCOMPLETE(); 60.30 - 60.31 -uint8_t readmembl(uint32_t addr); 60.32 -void writemembl(uint32_t addr, uint8_t val); 60.33 -uint16_t readmemwl(uint32_t seg, uint32_t addr); 60.34 -void writememwl(uint32_t seg, uint32_t addr, uint16_t val); 60.35 -uint32_t readmemll(uint32_t seg, uint32_t addr); 60.36 -void writememll(uint32_t seg, uint32_t addr, uint32_t val); 60.37 - 60.38 -#undef readmemb 60.39 -#undef readmemw 60.40 -uint8_t readmemb(uint32_t a) 60.41 -{ 60.42 - if (a!=(cs+pc)) memcycs+=4; 60.43 - if (readlookup2[(a)>>12]==0xFFFFFFFF) return readmembl(a); 60.44 - else return ram[readlookup2[(a)>>12]+((a)&0xFFF)]; 60.45 -} 60.46 - 60.47 -uint8_t readmembf(uint32_t a) 60.48 -{ 60.49 - if (readlookup2[(a)>>12]==0xFFFFFFFF) return readmembl(a); 60.50 - else return ram[readlookup2[(a)>>12]+((a)&0xFFF)]; 60.51 -} 60.52 - 60.53 -uint16_t readmemw(uint32_t s, uint16_t a) 60.54 -{ 60.55 - if (a!=(cs+pc)) memcycs+=(8>>is8086); 60.56 - if ((readlookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF)) return readmemwl(s,a); 60.57 - else return *((uint16_t *)(&ram[readlookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)])); 60.58 -} 60.59 - 60.60 -void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); memcycs+=4; } 60.61 - 60.62 -#undef fetchea 60.63 -#define fetchea() { rmdat=FETCH(); \ 60.64 - reg=(rmdat>>3)&7; \ 60.65 - mod=(rmdat>>6)&3; \ 60.66 - rm=rmdat&7; \ 60.67 - if (mod!=3) fetcheal(); } 60.68 - 60.69 -void writemembl(uint32_t addr, uint8_t val); 60.70 -void writememb(uint32_t a, uint8_t v) 60.71 -{ 60.72 - memcycs+=4; 60.73 - if (writelookup2[(a)>>12]==0xFFFFFFFF) writemembl(a,v); 60.74 - else ram[writelookup2[(a)>>12]+((a)&0xFFF)]=v; 60.75 -} 60.76 -void writememwl(uint32_t seg, uint32_t addr, uint16_t val); 60.77 -void writememw(uint32_t s, uint32_t a, uint16_t v) 60.78 -{ 60.79 - memcycs+=(8>>is8086); 60.80 - if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememwl(s,a,v); 60.81 - else *((uint16_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v; 60.82 -} 60.83 -void writememll(uint32_t seg, uint32_t addr, uint32_t val); 60.84 -void writememl(uint32_t s, uint32_t a, uint32_t v) 60.85 -{ 60.86 - if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememll(s,a,v); 60.87 - else *((uint32_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v; 60.88 -} 60.89 - 60.90 -int lldt=0; 60.91 -int notpresent; 60.92 -uint16_t oldflags; 60.93 -void dumpregs(); 60.94 -int incga; 60.95 -uint32_t old8,old82,old83; 60.96 -uint16_t oldcs; 60.97 -int oldcpl; 60.98 - 60.99 -int dlE=0; 60.100 -/*#define CS (cs>>4) 60.101 -#define DS (ds>>4) 60.102 -#define ES (es>>4) 60.103 -#define SS (ss>>4)*/ 60.104 - 60.105 -//#define loadseg(a) ((a)<<4) 60.106 - 60.107 -int keyboardtimer; 60.108 -int tempc; 60.109 -int bxcheck=0,spcheck=0; 60.110 -uint16_t getword(); 60.111 -int count40=0; 60.112 -int dosfunc; 60.113 -uint8_t opcode; 60.114 -int times=0; 60.115 -uint16_t pc2,pc3; 60.116 -int pit0=1; 60.117 -int noint=0; 60.118 - 60.119 -int output=0; 60.120 - 60.121 -int shadowbios=0; 60.122 - 60.123 -int inint=0; 60.124 -int ins=0; 60.125 -//#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a)) 60.126 - 60.127 -int ssegs; 60.128 - 60.129 -int fetchcycles=0,memcycs,fetchclocks; 60.130 - 60.131 -uint8_t prefetchqueue[6]; 60.132 -uint16_t prefetchpc; 60.133 -int prefetchw=0; 60.134 -inline uint8_t FETCH() 60.135 -{ 60.136 - uint8_t temp; 60.137 -/* temp=prefetchqueue[0]; 60.138 - prefetchqueue[0]=prefetchqueue[1]; 60.139 - prefetchqueue[1]=prefetchqueue[2]; 60.140 - prefetchqueue[2]=prefetchqueue[3]; 60.141 - prefetchqueue[3]=prefetchqueue[4]; 60.142 - prefetchqueue[4]=prefetchqueue[5]; 60.143 - if (prefetchw<=((is8086)?4:3)) 60.144 - { 60.145 - prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++; 60.146 - if (is8086 && (prefetchpc&1)) 60.147 - { 60.148 - prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++; 60.149 - } 60.150 - }*/ 60.151 - 60.152 -// uint8_t temp=readmemb(cs+pc); 60.153 -// if (output) printf("FETCH %04X %i\n",pc,fetchcycles); 60.154 - if (prefetchw==0) //(fetchcycles<4) 60.155 - { 60.156 - cycles-=(4-(fetchcycles&3)); 60.157 - fetchclocks+=(4-(fetchcycles&3)); 60.158 - fetchcycles=4; 60.159 - temp=readmembf(cs+pc); 60.160 - prefetchpc=pc=pc+1; 60.161 -// if (output) printf(" FETCH %04X:%04X %02X %04X %04X %i\n",CS,pc-1,temp,pc,prefetchpc,prefetchw); 60.162 - if (is8086 && (pc&1)) 60.163 - { 60.164 - prefetchqueue[0]=readmembf(cs+pc); 60.165 -// if (output) printf(" PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); 60.166 - prefetchpc++; 60.167 - prefetchw++; 60.168 - } 60.169 - } 60.170 - else 60.171 - { 60.172 - temp=prefetchqueue[0]; 60.173 - prefetchqueue[0]=prefetchqueue[1]; 60.174 - prefetchqueue[1]=prefetchqueue[2]; 60.175 - prefetchqueue[2]=prefetchqueue[3]; 60.176 - prefetchqueue[3]=prefetchqueue[4]; 60.177 - prefetchqueue[4]=prefetchqueue[5]; 60.178 - prefetchw--; 60.179 -// if (output) printf("PREFETCH %04X:%04X %02X %04X %04X %i\n",CS,pc,temp,pc,prefetchpc,prefetchw); 60.180 - fetchcycles-=4; 60.181 -// fetchclocks+=4; 60.182 - pc++; 60.183 - } 60.184 -// if (output) printf("%i\n",fetchcycles); 60.185 - return temp; 60.186 -} 60.187 - 60.188 -inline void FETCHADD(int c) 60.189 -{ 60.190 - int d; 60.191 -// if (output) printf("FETCHADD %i\n",c); 60.192 - if (c<0) return; 60.193 - if (prefetchw>((is8086)?4:3)) return; 60.194 - d=c+(fetchcycles&3); 60.195 - while (d>3 && prefetchw<((is8086)?6:4)) 60.196 - { 60.197 - d-=4; 60.198 - if (is8086 && !(prefetchpc&1)) 60.199 - { 60.200 - prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); 60.201 -// printf("PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); 60.202 - prefetchpc++; 60.203 - prefetchw++; 60.204 - } 60.205 - if (prefetchw<6) 60.206 - { 60.207 - prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); 60.208 -// printf("PREFETCHED from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]); 60.209 - prefetchpc++; 60.210 - prefetchw++; 60.211 - } 60.212 - } 60.213 - fetchcycles+=c; 60.214 - if (fetchcycles>16) fetchcycles=16; 60.215 -// if (fetchcycles>24) fetchcycles=24; 60.216 -} 60.217 - 60.218 -void FETCHCOMPLETE() 60.219 -{ 60.220 -// pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw); 60.221 - if (!(fetchcycles&3)) return; 60.222 - if (prefetchw>((is8086)?4:3)) return; 60.223 - if (!prefetchw) nextcyc=(4-(fetchcycles&3)); 60.224 - cycles-=(4-(fetchcycles&3)); 60.225 - fetchclocks+=(4-(fetchcycles&3)); 60.226 - if (is8086 && !(prefetchpc&1)) 60.227 - { 60.228 - prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); 60.229 -// printf("PREFETCHEDc from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); 60.230 - prefetchpc++; 60.231 - prefetchw++; 60.232 - } 60.233 - if (prefetchw<6) 60.234 - { 60.235 - prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); 60.236 -// printf("PREFETCHEDc from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]); 60.237 - prefetchpc++; 60.238 - prefetchw++; 60.239 - } 60.240 - fetchcycles+=(4-(fetchcycles&3)); 60.241 -} 60.242 - 60.243 -inline void FETCHCLEAR() 60.244 -{ 60.245 -/* int c; 60.246 - fetchcycles=0; 60.247 - prefetchpc=pc; 60.248 - if (is8086 && (prefetchpc&1)) cycles-=4; 60.249 - for (c=0;c<((is8086)?6:4);c++) 60.250 - { 60.251 - prefetchqueue[c]=readmembf(cs+prefetchpc); 60.252 - if (!is8086 || !(prefetchpc&1)) cycles-=4; 60.253 - prefetchpc++; 60.254 - } 60.255 - prefetchw=(is8086)?6:4;*/ 60.256 -// fetchcycles=0; 60.257 - prefetchpc=pc; 60.258 - prefetchw=0; 60.259 - memcycs=cycdiff-cycles; 60.260 - fetchclocks=0; 60.261 -// memcycs=cycles; 60.262 -/* prefetchqueue[0]=readmembf(cs+prefetchpc); 60.263 - prefetchpc++; 60.264 - prefetchw=1; 60.265 - if (is8086 && prefetchpc&1) 60.266 - { 60.267 - prefetchqueue[1]=readmembf(cs+prefetchpc); 60.268 - prefetchpc++; 60.269 - }*/ 60.270 -} 60.271 - 60.272 -/*EA calculation*/ 60.273 - 60.274 -/*R/M - bits 0-2 - R/M bits 3-5 - Reg bits 6-7 - mod 60.275 - From 386 programmers manual : 60.276 -r8(/r) AL CL DL BL AH CH DH BH 60.277 -r16(/r) AX CX DX BX SP BP SI DI 60.278 -r32(/r) EAX ECX EDX EBX ESP EBP ESI EDI 60.279 -/digit (Opcode) 0 1 2 3 4 5 6 7 60.280 -REG = 000 001 010 011 100 101 110 111 60.281 - ÚÄÄÄAddress 60.282 -disp8 denotes an 8-bit displacement following the ModR/M byte, to be 60.283 -sign-extended and added to the index. disp16 denotes a 16-bit displacement 60.284 -following the ModR/M byte, to be added to the index. Default segment 60.285 -register is SS for the effective addresses containing a BP index, DS for 60.286 -other effective addresses. 60.287 - ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄModR/M Values in HexadecimalÄÄÄÄÄÄÄÄ¿ 60.288 - 60.289 -[BX + SI] 000 00 08 10 18 20 28 30 38 60.290 -[BX + DI] 001 01 09 11 19 21 29 31 39 60.291 -[BP + SI] 010 02 0A 12 1A 22 2A 32 3A 60.292 -[BP + DI] 011 03 0B 13 1B 23 2B 33 3B 60.293 -[SI] 00 100 04 0C 14 1C 24 2C 34 3C 60.294 -[DI] 101 05 0D 15 1D 25 2D 35 3D 60.295 -disp16 110 06 0E 16 1E 26 2E 36 3E 60.296 -[BX] 111 07 0F 17 1F 27 2F 37 3F 60.297 - 60.298 -[BX+SI]+disp8 000 40 48 50 58 60 68 70 78 60.299 -[BX+DI]+disp8 001 41 49 51 59 61 69 71 79 60.300 -[BP+SI]+disp8 010 42 4A 52 5A 62 6A 72 7A 60.301 -[BP+DI]+disp8 011 43 4B 53 5B 63 6B 73 7B 60.302 -[SI]+disp8 01 100 44 4C 54 5C 64 6C 74 7C 60.303 -[DI]+disp8 101 45 4D 55 5D 65 6D 75 7D 60.304 -[BP]+disp8 110 46 4E 56 5E 66 6E 76 7E 60.305 -[BX]+disp8 111 47 4F 57 5F 67 6F 77 7F 60.306 - 60.307 -[BX+SI]+disp16 000 80 88 90 98 A0 A8 B0 B8 60.308 -[BX+DI]+disp16 001 81 89 91 99 A1 A9 B1 B9 60.309 -[BX+SI]+disp16 010 82 8A 92 9A A2 AA B2 BA 60.310 -[BX+DI]+disp16 011 83 8B 93 9B A3 AB B3 BB 60.311 -[SI]+disp16 10 100 84 8C 94 9C A4 AC B4 BC 60.312 -[DI]+disp16 101 85 8D 95 9D A5 AD B5 BD 60.313 -[BP]+disp16 110 86 8E 96 9E A6 AE B6 BE 60.314 -[BX]+disp16 111 87 8F 97 9F A7 AF B7 BF 60.315 - 60.316 -EAX/AX/AL 000 C0 C8 D0 D8 E0 E8 F0 F8 60.317 -ECX/CX/CL 001 C1 C9 D1 D9 E1 E9 F1 F9 60.318 -EDX/DX/DL 010 C2 CA D2 DA E2 EA F2 FA 60.319 -EBX/BX/BL 011 C3 CB D3 DB E3 EB F3 FB 60.320 -ESP/SP/AH 11 100 C4 CC D4 DC E4 EC F4 FC 60.321 -EBP/BP/CH 101 C5 CD D5 DD E5 ED F5 FD 60.322 -ESI/SI/DH 110 C6 CE D6 DE E6 EE F6 FE 60.323 -EDI/DI/BH 111 C7 CF D7 DF E7 EF F7 FF 60.324 - 60.325 -mod = 11 - register 60.326 - 10 - address + 16 bit displacement 60.327 - 01 - address + 8 bit displacement 60.328 - 00 - address 60.329 - 60.330 -reg = If mod=11, (depending on data size, 16 bits/8 bits, 32 bits=extend 16 bit registers) 60.331 - 0=AX/AL 1=CX/CL 2=DX/DL 3=BX/BL 60.332 - 4=SP/AH 5=BP/CH 6=SI/DH 7=DI/BH 60.333 - 60.334 - Otherwise, LSB selects SI/DI (0=SI), NMSB selects BX/BP (0=BX), and MSB 60.335 - selects whether BX/BP are used at all (0=used). 60.336 - 60.337 - mod=00 is an exception though 60.338 - 6=16 bit displacement only 60.339 - 7=[BX] 60.340 - 60.341 - Usage varies with instructions. 60.342 - 60.343 - MOV AL,BL has ModR/M as C3, for example. 60.344 - mod=11, reg=0, r/m=3 60.345 - MOV uses reg as dest, and r/m as src. 60.346 - reg 0 is AL, reg 3 is BL 60.347 - 60.348 - If BP or SP are in address calc, seg is SS, else DS 60.349 -*/ 60.350 - 60.351 -int cycles=0; 60.352 -uint32_t easeg,eaaddr; 60.353 -int rm,reg,mod,rmdat; 60.354 - 60.355 -uint16_t zero=0; 60.356 -uint16_t *mod1add[2][8]; 60.357 -uint32_t *mod1seg[8]; 60.358 - 60.359 -int slowrm[8]; 60.360 - 60.361 -void makemod1table() 60.362 -{ 60.363 - mod1add[0][0]=&BX; mod1add[0][1]=&BX; mod1add[0][2]=&BP; mod1add[0][3]=&BP; 60.364 - mod1add[0][4]=&SI; mod1add[0][5]=&DI; mod1add[0][6]=&BP; mod1add[0][7]=&BX; 60.365 - mod1add[1][0]=&SI; mod1add[1][1]=&DI; mod1add[1][2]=&SI; mod1add[1][3]=&DI; 60.366 - mod1add[1][4]=&zero; mod1add[1][5]=&zero; mod1add[1][6]=&zero; mod1add[1][7]=&zero; 60.367 - slowrm[0]=0; slowrm[1]=1; slowrm[2]=1; slowrm[3]=0; 60.368 - mod1seg[0]=&ds; mod1seg[1]=&ds; mod1seg[2]=&ss; mod1seg[3]=&ss; 60.369 - mod1seg[4]=&ds; mod1seg[5]=&ds; mod1seg[6]=&ss; mod1seg[7]=&ds; 60.370 -} 60.371 - 60.372 -void fetcheal() 60.373 -{ 60.374 - if (!mod && rm==6) { eaaddr=getword(); easeg=ds; FETCHADD(6); } 60.375 - else 60.376 - { 60.377 - switch (mod) 60.378 - { 60.379 - case 0: 60.380 - eaaddr=0; 60.381 - if (rm&4) FETCHADD(5); 60.382 - else FETCHADD(7+slowrm[rm]); 60.383 - break; 60.384 - case 1: 60.385 - eaaddr=(uint16_t)(int8_t)FETCH(); 60.386 - if (rm&4) FETCHADD(9); 60.387 - else FETCHADD(11+slowrm[rm]); 60.388 - break; 60.389 - case 2: 60.390 - eaaddr=getword(); 60.391 - if (rm&4) FETCHADD(9); 60.392 - else FETCHADD(11+slowrm[rm]); 60.393 - break; 60.394 - } 60.395 - eaaddr+=(*mod1add[0][rm])+(*mod1add[1][rm]); 60.396 - easeg=*mod1seg[rm]; 60.397 - eaaddr&=0xFFFF; 60.398 - } 60.399 -} 60.400 - 60.401 -/*void fetchea() 60.402 -{ 60.403 - rmdat=readmemb(cs+pc); pc++; 60.404 - reg=(rmdat>>3)&7; 60.405 - mod=rmdat>>6; 60.406 - rm=rmdat&7; 60.407 - switch (mod) 60.408 - { 60.409 - case 0: 60.410 - switch (rm) 60.411 - { 60.412 - case 0: eaaddr=BX+SI; easeg=ds; if (!AT) cycles-=7; break; 60.413 - case 1: eaaddr=BX+DI; easeg=ds; if (!AT) cycles-=8; break; 60.414 - case 2: eaaddr=BP+SI; easeg=ss; if (!AT) cycles-=8; break; 60.415 - case 3: eaaddr=BP+DI; easeg=ss; if (!AT) cycles-=7; break; 60.416 - case 4: eaaddr=SI; easeg=ds; if (!AT) cycles-=5; break; 60.417 - case 5: eaaddr=DI; easeg=ds; if (!AT) cycles-=5; break; 60.418 - case 6: eaaddr=getword(); easeg=ds; if (!AT) cycles-=6; break; 60.419 - case 7: eaaddr=BX; easeg=ds; if (!AT) cycles-=5; break; 60.420 - } 60.421 - if (AT && !(rm&4)) cycles--; 60.422 - break; 60.423 - 60.424 - case 1: 60.425 - eaaddr=readmemb(cs+pc); pc++; 60.426 - if (eaaddr&0x80) eaaddr|=0xFF00; 60.427 -// if (output) printf("EAADDR %04X ",eaaddr); 60.428 - switch (rm) 60.429 - { 60.430 - case 0: eaaddr+=BX+SI; easeg=ds; if (!AT) cycles-=11; break; 60.431 - case 1: eaaddr+=BX+DI; easeg=ds; if (!AT) cycles-=12; break; 60.432 - case 2: eaaddr+=BP+SI; easeg=ss; if (!AT) cycles-=12; break; 60.433 - case 3: eaaddr+=BP+DI; easeg=ss; if (!AT) cycles-=11; break; 60.434 - case 4: eaaddr+=SI; easeg=ds; if (!AT) cycles-=9; break; 60.435 - case 5: eaaddr+=DI; easeg=ds; if (!AT) cycles-=9; break; 60.436 - case 6: eaaddr+=BP; easeg=ss; if (!AT) cycles-=9; break; 60.437 - case 7: eaaddr+=BX; easeg=ds; if (!AT) cycles-=9; break; 60.438 - } 60.439 - if (AT && !(rm&4)) cycles--; 60.440 -// if (output) printf("%04X %04X",eaaddr,BX); 60.441 - break; 60.442 - 60.443 - case 2: 60.444 - eaaddr=getword(); 60.445 - switch (rm) 60.446 - { 60.447 - case 0: eaaddr+=BX+SI; easeg=ds; if (!AT) cycles-=11; break; 60.448 - case 1: eaaddr+=BX+DI; easeg=ds; if (!AT) cycles-=12; break; 60.449 - case 2: eaaddr+=BP+SI; easeg=ss; if (!AT) cycles-=12; break; 60.450 - case 3: eaaddr+=BP+DI; easeg=ss; if (!AT) cycles-=11; break; 60.451 - case 4: eaaddr+=SI; easeg=ds; if (!AT) cycles-=9; break; 60.452 - case 5: eaaddr+=DI; easeg=ds; if (!AT) cycles-=9; break; 60.453 - case 6: eaaddr+=BP; easeg=ss; if (!AT) cycles-=9; break; 60.454 - case 7: eaaddr+=BX; easeg=ds; if (!AT) cycles-=9; break; 60.455 - } 60.456 - if (AT && !(rm&4)) cycles--; 60.457 - break; 60.458 - } 60.459 - eaaddr&=0xFFFF; 60.460 -}*/ 60.461 - 60.462 -static inline uint8_t geteab() 60.463 -{ 60.464 - if (mod==3) 60.465 - return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l; 60.466 - return readmemb(easeg+eaaddr); 60.467 -} 60.468 - 60.469 -static inline uint16_t geteaw() 60.470 -{ 60.471 - if (mod==3) 60.472 - return regs[rm].w; 60.473 -// if (output==3) printf("GETEAW %04X:%08X\n",easeg,eaaddr); 60.474 - return readmemw(easeg,eaaddr); 60.475 -} 60.476 - 60.477 -static inline uint16_t geteaw2() 60.478 -{ 60.479 - if (mod==3) 60.480 - return regs[rm].w; 60.481 -// printf("Getting addr from %04X:%04X %05X\n",easeg,eaaddr+2,easeg+eaaddr+2); 60.482 - return readmemw(easeg,(eaaddr+2)&0xFFFF); 60.483 -} 60.484 - 60.485 -static inline void seteab(uint8_t val) 60.486 -{ 60.487 - if (mod==3) 60.488 - { 60.489 - if (rm&4) regs[rm&3].b.h=val; 60.490 - else regs[rm&3].b.l=val; 60.491 - } 60.492 - else 60.493 - { 60.494 - writememb(easeg+eaaddr,val); 60.495 - } 60.496 -} 60.497 - 60.498 -static inline void seteaw(uint16_t val) 60.499 -{ 60.500 - if (mod==3) 60.501 - regs[rm].w=val; 60.502 - else 60.503 - { 60.504 - writememw(easeg,eaaddr,val); 60.505 -// writememb(easeg+eaaddr+1,val>>8); 60.506 - } 60.507 -} 60.508 - 60.509 -#define getr8(r) ((r&4)?regs[r&3].b.h:regs[r&3].b.l) 60.510 - 60.511 -#define setr8(r,v) if (r&4) regs[r&3].b.h=v; \ 60.512 - else regs[r&3].b.l=v; 60.513 - 60.514 - 60.515 -/*Flags*/ 60.516 -uint8_t znptable8[256]; 60.517 -uint16_t znptable16[65536]; 60.518 - 60.519 -void makeznptable() 60.520 -{ 60.521 - int c,d; 60.522 - for (c=0;c<256;c++) 60.523 - { 60.524 - d=0; 60.525 - if (c&1) d++; 60.526 - if (c&2) d++; 60.527 - if (c&4) d++; 60.528 - if (c&8) d++; 60.529 - if (c&16) d++; 60.530 - if (c&32) d++; 60.531 - if (c&64) d++; 60.532 - if (c&128) d++; 60.533 - if (d&1) 60.534 - znptable8[c]=0; 60.535 - else 60.536 - znptable8[c]=P_FLAG; 60.537 - if (c == 0xb1) pclog("znp8 b1 = %i %02X\n", d, znptable8[c]); 60.538 - if (!c) znptable8[c]|=Z_FLAG; 60.539 - if (c&0x80) znptable8[c]|=N_FLAG; 60.540 - } 60.541 - for (c=0;c<65536;c++) 60.542 - { 60.543 - d=0; 60.544 - if (c&1) d++; 60.545 - if (c&2) d++; 60.546 - if (c&4) d++; 60.547 - if (c&8) d++; 60.548 - if (c&16) d++; 60.549 - if (c&32) d++; 60.550 - if (c&64) d++; 60.551 - if (c&128) d++; 60.552 - if (d&1) 60.553 - znptable16[c]=0; 60.554 - else 60.555 - znptable16[c]=P_FLAG; 60.556 - if (c == 0xb1) pclog("znp16 b1 = %i %02X\n", d, znptable16[c]); 60.557 - if (c == 0x65b1) pclog("znp16 65b1 = %i %02X\n", d, znptable16[c]); 60.558 - if (!c) znptable16[c]|=Z_FLAG; 60.559 - if (c&0x8000) znptable16[c]|=N_FLAG; 60.560 - } 60.561 -// isram[0xF]=1; 60.562 -// printf("isram 0 = %i\n",isram[0]); 60.563 - 60.564 -// makemod1table(); 60.565 -} 60.566 -int timetolive=0; 60.567 - 60.568 -uint8_t cpu_readop(uint32_t addr) { return readmemb(addr); } 60.569 -uint8_t cpu_readmem20(uint32_t addr) { return readmemb(addr); } 60.570 - 60.571 -void cpu_writemem20(uint32_t addr, uint8_t val) { writememb(addr,val); } 60.572 - 60.573 -uint16_t getword() 60.574 -{ 60.575 - uint8_t temp=FETCH(); 60.576 - return temp|(FETCH()<<8); 60.577 -// pc+=2; 60.578 -// return readmemw(cs,(pc-2)); 60.579 -} 60.580 - 60.581 -uint16_t getword286() 60.582 -{ 60.583 - uint16_t temp=readmemw(cs,pc); pc+=2; 60.584 - return temp; 60.585 -} 60.586 - 60.587 -int ratio1=0,ratio2=0; 60.588 - 60.589 -extern uint32_t oldcs2; 60.590 -extern uint32_t oldpc2; 60.591 - 60.592 -void dumpregs() 60.593 -{ 60.594 - FILE *f; 60.595 - int c,d=0,e=0; 60.596 -// return; 60.597 - output=0; 60.598 -// return; 60.599 -// savenvr(); 60.600 -/* printf("The ratio is %i %i\n",ratio1,ratio2); 60.601 - for (c=0;c<256;c++) 60.602 - { 60.603 - printf("ISRAM : %06X %i\n",c<<16,isram[c]); 60.604 - }*/ 60.605 -// return; 60.606 -chdir(pcempath); 60.607 - nopageerrors=1; 60.608 -/* f=fopen("rram3.dmp","wb"); 60.609 - for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f); 60.610 - fclose(f);*/ 60.611 -/* f=fopen("ram.dmp","wb"); 60.612 - fwrite(ram,mem_size*1024*1024,1,f); 60.613 - fclose(f);*/ 60.614 -/* f=fopen("rram.dmp","wb"); 60.615 - for (c=0;c<0x1000000;c++) putc(readmemb(c),f); 60.616 - fclose(f); 60.617 - f=fopen("rram2.dmp","wb"); 60.618 - for (c=0;c<0x100000;c++) putc(readmemb(c+0xbff00000),f); 60.619 - fclose(f); 60.620 - f = fopen("stack.dmp","wb"); 60.621 - for (c = 0; c < 0x6000; c++) putc(readmemb(c+0xFFDFA000), f); 60.622 - fclose(f); 60.623 - f = fopen("tempx.dmp","wb"); 60.624 - for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFC816000), f); 60.625 - fclose(f); 60.626 - f = fopen("tempx2.dmp","wb"); 60.627 - for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFDEF5000), f); 60.628 - fclose(f);*/ 60.629 -/* f=fopen("rram4.dmp","wb"); 60.630 - for (c=0;c<0x3000000;c++) putc(readmemb(c+0x80000000),f); 60.631 - fclose(f);*/ 60.632 -/* f=fopen("rram5.dmp","wb"); 60.633 - for (c=0;c<0x1000000;c++) putc(readmemb(c+0x10000000),f); 60.634 - fclose(f);*/ 60.635 -/* f=fopen("rram6.dmp","wb"); 60.636 - for (c=0;c<0x1000000;c++) putc(readmemb(c+0xBF000000),f); 60.637 - fclose(f);*/ 60.638 -/* f=fopen("ram6.bin","wb"); 60.639 - fwrite(ram+0x10100,0xA000,1,f); 60.640 - fclose(f); 60.641 - f=fopen("boot.bin","wb"); 60.642 - fwrite(ram+0x7C00,0x200,1,f); 60.643 - fclose(f); 60.644 - f=fopen("ram7.bin","wb"); 60.645 - fwrite(ram+0x11100,0x2000,1,f); 60.646 - fclose(f); 60.647 - f=fopen("ram8.bin","wb"); 60.648 - fwrite(ram+0x3D210,0x200,1,f); 60.649 - fclose(f); */ 60.650 -/* f=fopen("vram.dmp","wb"); 60.651 - fwrite(vram,0x400000,1,f); 60.652 - fclose(f); 60.653 - f=fopen("bios.dmp","wb"); 60.654 - fwrite(rom,0x20000,1,f); 60.655 - fclose(f); 60.656 - f=fopen("vbios.dmp","wb"); 60.657 - fwrite(vrom,0x8000,1,f); 60.658 - fclose(f);*/ 60.659 -/* f=fopen("kernel.dmp","wb"); 60.660 - for (c=0;c<0x200000;c++) putc(readmemb(c+0xC0000000),f); 60.661 - fclose(f);*/ 60.662 -/* f=fopen("rram.dmp","wb"); 60.663 - for (c=0;c<0x1500000;c++) putc(readmemb(c),f); 60.664 - fclose(f); 60.665 - if (!times) 60.666 - { 60.667 - f=fopen("thing.dmp","wb"); 60.668 - fwrite(ram+0x11E50,0x1000,1,f); 60.669 - fclose(f); 60.670 - }*/ 60.671 - if (is386) 60.672 - 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); 60.673 - else 60.674 - 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); 60.675 - printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",pc,CS,DS,ES,SS,flags); 60.676 - printf("%04X:%04X %04X:%04X %08X %08X %08X\n",oldcs,oldpc, oldcs2, oldpc2, old8,old82,old83); 60.677 - printf("%i ins\n",ins); 60.678 - if (is386) 60.679 - printf("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real"); 60.680 - else 60.681 - printf("In %s mode\n",(msw&1)?"protected":"real"); 60.682 - printf("CS : base=%06X limit=%04X access=%02X\n",cs,_cs.limit,_cs.access); 60.683 - printf("DS : base=%06X limit=%04X access=%02X\n",ds,_ds.limit,_ds.access); 60.684 - printf("ES : base=%06X limit=%04X access=%02X\n",es,_es.limit,_es.access); 60.685 - if (is386) 60.686 - { 60.687 - printf("FS : base=%06X limit=%04X access=%02X\n",fs,_fs.limit,_fs.access); 60.688 - printf("GS : base=%06X limit=%04X access=%02X\n",gs,_gs.limit,_gs.access); 60.689 - } 60.690 - printf("SS : base=%06X limit=%04X access=%02X\n",ss,_ss.limit,_ss.access); 60.691 - printf("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit); 60.692 - printf("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit); 60.693 - printf("IDT : base=%06X limit=%04X\n",idt.base,idt.limit); 60.694 - printf("TR : base=%06X limit=%04X\n", tr.base, tr.limit); 60.695 - if (is386) 60.696 - { 60.697 - printf("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit"); 60.698 - printf("CR0=%08X CR2=%08X CR3=%08X\n",cr0,cr2,cr3); 60.699 - } 60.700 - printf("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum); 60.701 - for (c=0;c<1024*1024;c++) 60.702 - { 60.703 - if (readlookup2[c]!=0xFFFFFFFF) d++; 60.704 - if (writelookup2[c]!=0xFFFFFFFF) e++; 60.705 - } 60.706 - printf("Entries in readlookup : %i writelookup : %i\n",d,e); 60.707 - d=0; 60.708 - x87_dumpregs(); 60.709 -/* for (c=0;c<1024*1024;c++) 60.710 - { 60.711 - if (mmucache[c]!=0xFFFFFFFF) d++; 60.712 - } 60.713 - printf("Entries in MMU cache : %i\n",d);*/ 60.714 -} 60.715 - 60.716 -int isAT; 60.717 -int resets = 0; 60.718 -void resetx86() 60.719 -{ 60.720 - pclog("x86 reset\n"); 60.721 - resets++; 60.722 - ins = 0; 60.723 - use32=0; 60.724 - stack32=0; 60.725 -// i86_Reset(); 60.726 -// cs=0xFFFF0; 60.727 - pc=0; 60.728 - msw=0; 60.729 - cr0=0; 60.730 - eflags=0; 60.731 - cgate32=0; 60.732 - loadcs(0xFFFF); 60.733 - rammask=0xFFFFFFFF; 60.734 - flags=2; 60.735 - initmmucache(); 60.736 - resetreadlookup(); 60.737 - makemod1table(); 60.738 - resetmcr(); 60.739 - isAT=AT; 60.740 - FETCHCLEAR(); 60.741 - x87_reset(); 60.742 - cpu_set_edx(); 60.743 - ESP=0; 60.744 - mmu_perm=4; 60.745 -} 60.746 - 60.747 -void softresetx86() 60.748 -{ 60.749 -// dumpregs(); 60.750 -// exit(-1); 60.751 - use32=0; 60.752 - stack32=0; 60.753 -// i86_Reset(); 60.754 -// cs=0xFFFF0; 60.755 - pc=0; 60.756 - msw=0; 60.757 - cr0=0; 60.758 - eflags=0; 60.759 - cgate32=0; 60.760 - loadcs(0xFFFF); 60.761 - //rammask=0xFFFFFFFF; 60.762 - flags=2; 60.763 -} 60.764 - 60.765 -#undef AT 60.766 -#define AT isAT 60.767 - 60.768 -extern int is486; 60.769 -void setznp8(uint8_t val) 60.770 -{ 60.771 - flags&=~0xC4; 60.772 - flags|=znptable8[val]; 60.773 -} 60.774 - 60.775 -#define setznp168 setznp16 60.776 -void setznp16(uint16_t val) 60.777 -{ 60.778 - flags&=~0xC4; 60.779 -// flags|=((val&0x8000)?N_FLAG:((!val)?Z_FLAG:0)); 60.780 -// flags|=(((znptable8[val&0xFF]&P_FLAG)==(znptable8[val>>8]&P_FLAG))?P_FLAG:0); 60.781 - flags|=znptable16[val]; 60.782 -} 60.783 - 60.784 -/*void setznp168(uint16_t val) 60.785 -{ 60.786 - flags&=~0xC4; 60.787 - flags|=(znptable16[val]&0xC0)|(znptable8[val&0xFF]&4); 60.788 -}*/ 60.789 - 60.790 -void setadd8(uint8_t a, uint8_t b) 60.791 -{ 60.792 - uint16_t c=(uint16_t)a+(uint16_t)b; 60.793 - flags&=~0x8D5; 60.794 - flags|=znptable8[c&0xFF]; 60.795 - if (c&0x100) flags|=C_FLAG; 60.796 - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; 60.797 - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 60.798 -} 60.799 -void setadd8nc(uint8_t a, uint8_t b) 60.800 -{ 60.801 - uint16_t c=(uint16_t)a+(uint16_t)b; 60.802 - flags&=~0x8D4; 60.803 - flags|=znptable8[c&0xFF]; 60.804 - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; 60.805 - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 60.806 -} 60.807 -void setadc8(uint8_t a, uint8_t b) 60.808 -{ 60.809 - uint16_t c=(uint16_t)a+(uint16_t)b+tempc; 60.810 - flags&=~0x8D5; 60.811 - flags|=znptable8[c&0xFF]; 60.812 - if (c&0x100) flags|=C_FLAG; 60.813 - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; 60.814 - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 60.815 -} 60.816 -void setadd16(uint16_t a, uint16_t b) 60.817 -{ 60.818 - uint32_t c=(uint32_t)a+(uint32_t)b; 60.819 - flags&=~0x8D5; 60.820 - flags|=znptable16[c&0xFFFF]; 60.821 - if (c&0x10000) flags|=C_FLAG; 60.822 - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; 60.823 - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 60.824 -} 60.825 -void setadd16nc(uint16_t a, uint16_t b) 60.826 -{ 60.827 - uint32_t c=(uint32_t)a+(uint32_t)b; 60.828 - flags&=~0x8D4; 60.829 - flags|=znptable16[c&0xFFFF]; 60.830 - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; 60.831 - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 60.832 -} 60.833 -void setadc16(uint16_t a, uint16_t b) 60.834 -{ 60.835 - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; 60.836 - flags&=~0x8D5; 60.837 - flags|=znptable16[c&0xFFFF]; 60.838 - if (c&0x10000) flags|=C_FLAG; 60.839 - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; 60.840 - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 60.841 -} 60.842 - 60.843 -void setsub8(uint8_t a, uint8_t b) 60.844 -{ 60.845 - uint16_t c=(uint16_t)a-(uint16_t)b; 60.846 - flags&=~0x8D5; 60.847 - flags|=znptable8[c&0xFF]; 60.848 - if (c&0x100) flags|=C_FLAG; 60.849 - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; 60.850 - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 60.851 -} 60.852 -void setsub8nc(uint8_t a, uint8_t b) 60.853 -{ 60.854 - uint16_t c=(uint16_t)a-(uint16_t)b; 60.855 - flags&=~0x8D4; 60.856 - flags|=znptable8[c&0xFF]; 60.857 - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; 60.858 - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 60.859 -} 60.860 -void setsbc8(uint8_t a, uint8_t b) 60.861 -{ 60.862 - uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc); 60.863 - flags&=~0x8D5; 60.864 - flags|=znptable8[c&0xFF]; 60.865 - if (c&0x100) flags|=C_FLAG; 60.866 - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; 60.867 - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 60.868 -} 60.869 -void setsub16(uint16_t a, uint16_t b) 60.870 -{ 60.871 - uint32_t c=(uint32_t)a-(uint32_t)b; 60.872 - flags&=~0x8D5; 60.873 - flags|=znptable16[c&0xFFFF]; 60.874 - if (c&0x10000) flags|=C_FLAG; 60.875 - if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; 60.876 -// if (output) printf("%04X %04X %i\n",a^b,a^c,flags&V_FLAG); 60.877 - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 60.878 -} 60.879 -void setsub16nc(uint16_t a, uint16_t b) 60.880 -{ 60.881 - uint32_t c=(uint32_t)a-(uint32_t)b; 60.882 - flags&=~0x8D4; 60.883 - flags|=(znptable16[c&0xFFFF]&~4); 60.884 - flags|=(znptable8[c&0xFF]&4); 60.885 - if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; 60.886 - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 60.887 -} 60.888 -void setsbc16(uint16_t a, uint16_t b) 60.889 -{ 60.890 - uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); 60.891 - flags&=~0x8D5; 60.892 - flags|=(znptable16[c&0xFFFF]&~4); 60.893 - flags|=(znptable8[c&0xFF]&4); 60.894 - if (c&0x10000) flags|=C_FLAG; 60.895 - if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; 60.896 - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 60.897 -} 60.898 - 60.899 - 60.900 -void clockhardware() 60.901 -{ 60.902 - cycdiff-=cycles; 60.903 - 60.904 - keybsenddelay--; 60.905 - if (keybsenddelay<1) 60.906 - { 60.907 - keybsenddelay = 1000;//2500; 60.908 - keyboard_poll(); 60.909 - } 60.910 - 60.911 - pit.c[0]-=cycdiff; 60.912 - pit.c[1]-=cycdiff; 60.913 - if (ppi.pb&1) pit.c[2]-=cycdiff; 60.914 - 60.915 - if ((pit.c[0]<1)||(pit.c[1]<1)||(pit.c[2]<1)) pit_poll(); 60.916 - 60.917 - spktime-=cycdiff; 60.918 - if (spktime<=0.0) 60.919 - { 60.920 - spktime+=SPKCONST; 60.921 - pollspk(); 60.922 - pollgussamp(); 60.923 - getsbsamp(); 60.924 - getdacsamp(); 60.925 - polladlib(); 60.926 - } 60.927 - soundtime-=cycdiff; 60.928 - if (soundtime<=0.0) 60.929 - { 60.930 - soundtime+=SOUNDCONST; 60.931 - pollsound60hz(); 60.932 - } 60.933 - gustime-=cycdiff; 60.934 - while (gustime<=0.0) 60.935 - { 60.936 - gustime+=GUSCONST; 60.937 -// printf("1Poll GUS %f %f\n",gustime,GUSCONST); 60.938 - pollgus(); 60.939 -// printf("2Poll GUS\n"); 60.940 - } 60.941 - vidtime-=cycdiff; 60.942 - if (vidtime<=0.0) 60.943 - { 60.944 - pollvideo(); 60.945 -// polltandy(); 60.946 -// pollmda(); 60.947 -// pollcga(); 60.948 - } 60.949 - if (disctime) 60.950 - { 60.951 - disctime-=(cycdiff/2); 60.952 - if (disctime<=0) 60.953 - { 60.954 - disctime=0; 60.955 - fdc_poll(); 60.956 - } 60.957 - } 60.958 - if (mousedelay) 60.959 - { 60.960 - mousedelay--; 60.961 - if (!mousedelay) 60.962 - mousecallback(); 60.963 - } 60.964 - if (sbenable) 60.965 - { 60.966 - sbcount-=cycdiff; 60.967 - if (sbcount<0) 60.968 - { 60.969 - sbcount+=sblatcho; 60.970 - pollsb(); 60.971 - } 60.972 - } 60.973 - rtctime-=cycdiff; 60.974 - if (rtctime<0) 60.975 - { 60.976 - nvr_rtc(); 60.977 - } 60.978 - cycdiff=cycles; 60.979 - if (idecallback[0]) 60.980 - { 60.981 - idecallback[0]--; 60.982 - if (idecallback[0]<=0) 60.983 - { 60.984 -// pclog("IDE time over\n"); 60.985 - idecallback[0]=0; 60.986 - callbackide(0); 60.987 - } 60.988 - } 60.989 -} 60.990 - 60.991 - 60.992 - int firstrepcycle=1; 60.993 -void cpu_writeport(uint32_t port, uint8_t val) { outb(port,val); } 60.994 -void rep(int fv) 60.995 -{ 60.996 - uint8_t temp; 60.997 - int c=CX; 60.998 - uint8_t temp2; 60.999 - uint16_t tempw,tempw2,tempw3; 60.1000 - uint16_t ipc=oldpc;//pc-1; 60.1001 - int changeds=0; 60.1002 - uint32_t oldds; 60.1003 - startrep: 60.1004 - temp=FETCH(); 60.1005 -// if (firstrepcycle && temp==0xA5) printf("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI); 60.1006 -// if (output) printf("REP %02X %04X\n",temp,ipc); 60.1007 - switch (temp) 60.1008 - { 60.1009 - case 0x08: 60.1010 - pc=ipc+1; 60.1011 - cycles-=2; 60.1012 - FETCHCLEAR(); 60.1013 - break; 60.1014 - case 0x26: /*ES:*/ 60.1015 - oldds=ds; 60.1016 - ds=es; 60.1017 - changeds=1; 60.1018 - cycles-=2; 60.1019 - goto startrep; 60.1020 - break; 60.1021 - case 0x2E: /*CS:*/ 60.1022 - oldds=ds; 60.1023 - ds=cs; 60.1024 - changeds=1; 60.1025 - cycles-=2; 60.1026 - goto startrep; 60.1027 - break; 60.1028 - case 0x36: /*SS:*/ 60.1029 - oldds=ds; 60.1030 - ds=ss; 60.1031 - changeds=1; 60.1032 - cycles-=2; 60.1033 - goto startrep; 60.1034 - break; 60.1035 - case 0x6E: /*REP OUTSB*/ 60.1036 - if (c>0) 60.1037 - { 60.1038 - temp2=readmemb(ds+SI); 60.1039 - outb(DX,temp2); 60.1040 - if (flags&D_FLAG) SI--; 60.1041 - else SI++; 60.1042 - c--; 60.1043 - cycles-=5; 60.1044 - } 60.1045 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1046 - else firstrepcycle=1; 60.1047 - break; 60.1048 - case 0xA4: /*REP MOVSB*/ 60.1049 - while (c>0 && !IRQTEST) 60.1050 - { 60.1051 - temp2=readmemb(ds+SI); 60.1052 - writememb(es+DI,temp2); 60.1053 -// if (output) printf("Moved %02X from %04X:%04X to %04X:%04X\n",temp2,ds>>4,SI,es>>4,DI); 60.1054 - if (flags&D_FLAG) { DI--; SI--; } 60.1055 - else { DI++; SI++; } 60.1056 - c--; 60.1057 - cycles-=((AT)?4:17); 60.1058 - clockhardware(); 60.1059 - FETCHADD(((AT)?4:17)-memcycs); 60.1060 - } 60.1061 - if (IRQTEST && c>0) pc=ipc; 60.1062 -// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1063 -// else firstrepcycle=1; 60.1064 -// } 60.1065 - break; 60.1066 - case 0xA5: /*REP MOVSW*/ 60.1067 - while (c>0 && !IRQTEST) 60.1068 - { 60.1069 - memcycs=0; 60.1070 - tempw=readmemw(ds,SI); 60.1071 - writememw(es,DI,tempw); 60.1072 - if (flags&D_FLAG) { DI-=2; SI-=2; } 60.1073 - else { DI+=2; SI+=2; } 60.1074 - c--; 60.1075 - cycles-=((AT)?4:17); 60.1076 - clockhardware(); 60.1077 - FETCHADD(((AT)?4:17)-memcycs); 60.1078 - } 60.1079 - if (IRQTEST && c>0) pc=ipc; 60.1080 -// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1081 -// else firstrepcycle=1; 60.1082 -// } 60.1083 - break; 60.1084 - case 0xA6: /*REP CMPSB*/ 60.1085 - if (fv) flags|=Z_FLAG; 60.1086 - else flags&=~Z_FLAG; 60.1087 - while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST) 60.1088 - { 60.1089 - memcycs=0; 60.1090 - temp=readmemb(ds+SI); 60.1091 - temp2=readmemb(es+DI); 60.1092 -// printf("CMPSB %c %c %i %05X %05X %04X:%04X\n",temp,temp2,c,ds+SI,es+DI,cs>>4,pc); 60.1093 - if (flags&D_FLAG) { DI--; SI--; } 60.1094 - else { DI++; SI++; } 60.1095 - c--; 60.1096 - if (!AT) cycles-=30; 60.1097 - else cycles-=9; 60.1098 - setsub8(temp,temp2); 60.1099 - clockhardware(); 60.1100 - FETCHADD(((AT)?9:30)-memcycs); 60.1101 - } 60.1102 - if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) pc=ipc; 60.1103 -// if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1104 -// else firstrepcycle=1; 60.1105 - break; 60.1106 - case 0xA7: /*REP CMPSW*/ 60.1107 - if (fv) flags|=Z_FLAG; 60.1108 - else flags&=~Z_FLAG; 60.1109 - while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST) 60.1110 - { 60.1111 - memcycs=0; 60.1112 - tempw=readmemw(ds,SI); 60.1113 - tempw2=readmemw(es,DI); 60.1114 - if (flags&D_FLAG) { DI-=2; SI-=2; } 60.1115 - else { DI+=2; SI+=2; } 60.1116 - c--; 60.1117 - if (!AT) cycles-=30; 60.1118 - else cycles-=9; 60.1119 - setsub16(tempw,tempw2); 60.1120 - clockhardware(); 60.1121 - FETCHADD(((AT)?9:30)-memcycs); 60.1122 - } 60.1123 - if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) pc=ipc; 60.1124 -// if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1125 -// else firstrepcycle=1; 60.1126 -// if (firstrepcycle) printf("REP CMPSW %06X:%04X %06X:%04X %04X %04X\n",ds,SI,es,DI,tempw,tempw2); 60.1127 - break; 60.1128 - case 0xAA: /*REP STOSB*/ 60.1129 - while (c>0 && !IRQTEST) 60.1130 - { 60.1131 - memcycs=0; 60.1132 - writememb(es+DI,AL); 60.1133 - if (flags&D_FLAG) DI--; 60.1134 - else DI++; 60.1135 - c--; 60.1136 - cycles-=((AT)?3:10); 60.1137 - clockhardware(); 60.1138 - FETCHADD(((AT)?3:10)-memcycs); 60.1139 - } 60.1140 - if (IRQTEST && c>0) pc=ipc; 60.1141 -// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1142 -// else firstrepcycle=1; 60.1143 - break; 60.1144 - case 0xAB: /*REP STOSW*/ 60.1145 - while (c>0 && !IRQTEST) 60.1146 - { 60.1147 - memcycs=0; 60.1148 - writememw(es,DI,AX); 60.1149 - if (flags&D_FLAG) DI-=2; 60.1150 - else DI+=2; 60.1151 - c--; 60.1152 - cycles-=((AT)?3:10); 60.1153 - clockhardware(); 60.1154 - FETCHADD(((AT)?3:10)-memcycs); 60.1155 - } 60.1156 - if (IRQTEST && c>0) pc=ipc; 60.1157 -// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1158 -// else firstrepcycle=1; 60.1159 -// printf("REP STOSW %04X:%04X %04X:%04X %04X %04X\n",CS,pc,ES,DI,AX,CX); } 60.1160 - break; 60.1161 - case 0xAC: /*REP LODSB*/ 60.1162 - if (c>0) 60.1163 - { 60.1164 - temp2=readmemb(ds+SI); 60.1165 - if (flags&D_FLAG) SI--; 60.1166 - else SI++; 60.1167 - c--; 60.1168 - cycles-=4; 60.1169 - } 60.1170 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1171 - else firstrepcycle=1; 60.1172 - break; 60.1173 - case 0xAD: /*REP LODSW*/ 60.1174 - if (c>0) 60.1175 - { 60.1176 - tempw2=readmemw(ds,SI); 60.1177 - if (flags&D_FLAG) SI-=2; 60.1178 - else SI+=2; 60.1179 - c--; 60.1180 - cycles-=4; 60.1181 - } 60.1182 - if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1183 - else firstrepcycle=1; 60.1184 - break; 60.1185 - case 0xAE: /*REP SCASB*/ 60.1186 - if (fv) flags|=Z_FLAG; 60.1187 - else flags&=~Z_FLAG; 60.1188 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 60.1189 - { 60.1190 - temp2=readmemb(es+DI); 60.1191 -// if (output) printf("SCASB %02X %c %02X %05X ",temp2,temp2,AL,es+DI); 60.1192 - setsub8(AL,temp2); 60.1193 -// if (output && flags&Z_FLAG) printf("Match %02X %02X\n",AL,temp2); 60.1194 - if (flags&D_FLAG) DI--; 60.1195 - else DI++; 60.1196 - c--; 60.1197 - cycles-=((AT)?8:15); 60.1198 - } 60.1199 -//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)))); 60.1200 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1201 - else firstrepcycle=1; 60.1202 -// cycles-=120; 60.1203 - break; 60.1204 - case 0xAF: /*REP SCASW*/ 60.1205 - if (fv) flags|=Z_FLAG; 60.1206 - else flags&=~Z_FLAG; 60.1207 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 60.1208 - { 60.1209 - tempw=readmemw(es,DI); 60.1210 - setsub16(AX,tempw); 60.1211 - if (flags&D_FLAG) DI-=2; 60.1212 - else DI+=2; 60.1213 - c--; 60.1214 - cycles-=((AT)?8:15); 60.1215 - } 60.1216 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } 60.1217 - else firstrepcycle=1; 60.1218 - break; 60.1219 - default: 60.1220 - pc=ipc; 60.1221 - cycles-=20; 60.1222 - FETCHCLEAR(); 60.1223 -// printf("Bad REP %02X\n",temp); 60.1224 -// dumpregs(); 60.1225 -// exit(-1); 60.1226 - } 60.1227 - CX=c; 60.1228 - if (changeds) ds=oldds; 60.1229 -// if (pc==ipc) FETCHCLEAR(); 60.1230 -} 60.1231 - 60.1232 - 60.1233 -int inhlt=0; 60.1234 -uint16_t lastpc,lastcs; 60.1235 -int firstrepcycle; 60.1236 -int skipnextprint=0; 60.1237 - 60.1238 - 60.1239 -int instime=0,instimer=0; 60.1240 -//#if 0 60.1241 -void execx86(int cycs) 60.1242 -{ 60.1243 - uint8_t temp,temp2; 60.1244 - uint16_t addr,tempw,tempw2,tempw3,tempw4; 60.1245 - int8_t offset; 60.1246 - int tempws; 60.1247 - uint32_t templ; 60.1248 - int c; 60.1249 - int tempi; 60.1250 - int trap; 60.1251 - FILE *f; 60.1252 -// printf("Run x86! %i %i\n",cycles,cycs); 60.1253 - cycles+=cycs; 60.1254 -// i86_Execute(cycs); 60.1255 -// return; 60.1256 - while (cycles>0) 60.1257 - { 60.1258 -// old83=old82; 60.1259 -// old82=old8; 60.1260 -// old8=oldpc|(oldcs<<16); 60.1261 -// if (pc==0x96B && cs==0x9E040) { printf("Hit it\n"); output=1; timetolive=150; } 60.1262 -// 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); 60.1263 - cycdiff=cycles; 60.1264 - cycles-=nextcyc; 60.1265 -// if (instime) pclog("Cycles %i %i\n",cycles,cycdiff); 60.1266 - nextcyc=0; 60.1267 -// if (output) printf("CLOCK %i %i\n",cycdiff,cycles); 60.1268 - fetchclocks=0; 60.1269 - oldcs=CS; 60.1270 - oldpc=pc; 60.1271 - opcodestart: 60.1272 - opcode=FETCH(); 60.1273 - tempc=flags&C_FLAG; 60.1274 - trap=flags&T_FLAG; 60.1275 - pc--; 60.1276 -// output=1; 60.1277 -// 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); 60.1278 -//#if 0 60.1279 - if (output && /*cs<0xF0000 && */!ssegs && (pc<0x43A || pc>0x44A))//opcode!=0x26 && opcode!=0x36 && opcode!=0x2E && opcode!=0x3E) 60.1280 - { 60.1281 - if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle) 60.1282 - { 60.1283 - if (!skipnextprint) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %02X %02X %02X %02X\n",cs,pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ram[0x413], ram[0x414], ram[0x415], ram[0x416]); 60.1284 - skipnextprint=0; 60.1285 -// ins++; 60.1286 - } 60.1287 - } 60.1288 -//#endif 60.1289 - pc++; 60.1290 - inhlt=0; 60.1291 -// if (ins==500000) { dumpregs(); exit(0); }*/ 60.1292 - switch (opcode) 60.1293 - { 60.1294 - case 0x00: /*ADD 8,reg*/ 60.1295 - fetchea(); 60.1296 -/* if (!rmdat) pc--; 60.1297 - if (!rmdat) 60.1298 - { 60.1299 - fatal("Crashed\n"); 60.1300 -// clear_keybuf(); 60.1301 -// readkey(); 60.1302 - }*/ 60.1303 - temp=geteab(); 60.1304 - setadd8(temp,getr8(reg)); 60.1305 - temp+=getr8(reg); 60.1306 - seteab(temp); 60.1307 - cycles-=((mod==3)?3:24); 60.1308 - break; 60.1309 - case 0x01: /*ADD 16,reg*/ 60.1310 - fetchea(); 60.1311 - tempw=geteaw(); 60.1312 - setadd16(tempw,regs[reg].w); 60.1313 - tempw+=regs[reg].w; 60.1314 - seteaw(tempw); 60.1315 - cycles-=((mod==3)?3:24); 60.1316 - break; 60.1317 - case 0x02: /*ADD reg,8*/ 60.1318 - fetchea(); 60.1319 - temp=geteab(); 60.1320 - setadd8(getr8(reg),temp); 60.1321 - setr8(reg,getr8(reg)+temp); 60.1322 - cycles-=((mod==3)?3:13); 60.1323 - break; 60.1324 - case 0x03: /*ADD reg,16*/ 60.1325 - fetchea(); 60.1326 - tempw=geteaw(); 60.1327 - setadd16(regs[reg].w,tempw); 60.1328 - regs[reg].w+=tempw; 60.1329 - cycles-=((mod==3)?3:13); 60.1330 - break; 60.1331 - case 0x04: /*ADD AL,#8*/ 60.1332 - temp=FETCH(); 60.1333 - setadd8(AL,temp); 60.1334 - AL+=temp; 60.1335 - cycles-=4; 60.1336 - break; 60.1337 - case 0x05: /*ADD AX,#16*/ 60.1338 - tempw=getword(); 60.1339 - setadd16(AX,tempw); 60.1340 - AX+=tempw; 60.1341 - cycles-=4; 60.1342 - break; 60.1343 - 60.1344 - case 0x06: /*PUSH ES*/ 60.1345 - if (ssegs) ss=oldss; 60.1346 - writememw(ss,((SP-2)&0xFFFF),ES); 60.1347 - SP-=2; 60.1348 - cycles-=14; 60.1349 - break; 60.1350 - case 0x07: /*POP ES*/ 60.1351 - if (ssegs) ss=oldss; 60.1352 - tempw=readmemw(ss,SP); 60.1353 - loadseg(tempw,&_es); 60.1354 - SP+=2; 60.1355 - cycles-=12; 60.1356 - break; 60.1357 - 60.1358 - case 0x08: /*OR 8,reg*/ 60.1359 - fetchea(); 60.1360 - temp=geteab(); 60.1361 - temp|=getr8(reg); 60.1362 - setznp8(temp); 60.1363 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1364 - seteab(temp); 60.1365 - cycles-=((mod==3)?3:24); 60.1366 - break; 60.1367 - case 0x09: /*OR 16,reg*/ 60.1368 - fetchea(); 60.1369 - tempw=geteaw(); 60.1370 - tempw|=regs[reg].w; 60.1371 - setznp16(tempw); 60.1372 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1373 - seteaw(tempw); 60.1374 - cycles-=((mod==3)?3:24); 60.1375 - break; 60.1376 - case 0x0A: /*OR reg,8*/ 60.1377 - fetchea(); 60.1378 - temp=geteab(); 60.1379 - temp|=getr8(reg); 60.1380 - setznp8(temp); 60.1381 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1382 - setr8(reg,temp); 60.1383 - cycles-=((mod==3)?3:13); 60.1384 - break; 60.1385 - case 0x0B: /*OR reg,16*/ 60.1386 - fetchea(); 60.1387 - tempw=geteaw(); 60.1388 - tempw|=regs[reg].w; 60.1389 - setznp16(tempw); 60.1390 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1391 - regs[reg].w=tempw; 60.1392 - cycles-=((mod==3)?3:13); 60.1393 - break; 60.1394 - case 0x0C: /*OR AL,#8*/ 60.1395 - AL|=FETCH(); 60.1396 - setznp8(AL); 60.1397 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1398 - cycles-=4; 60.1399 - break; 60.1400 - case 0x0D: /*OR AX,#16*/ 60.1401 - AX|=getword(); 60.1402 - setznp16(AX); 60.1403 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1404 - cycles-=4; 60.1405 - break; 60.1406 - 60.1407 - case 0x0E: /*PUSH CS*/ 60.1408 - if (ssegs) ss=oldss; 60.1409 - writememw(ss,((SP-2)&0xFFFF),CS); 60.1410 - SP-=2; 60.1411 - cycles-=14; 60.1412 - break; 60.1413 - case 0x0F: /*POP CS - 8088/8086 only*/ 60.1414 - if (ssegs) ss=oldss; 60.1415 - tempw=readmemw(ss,SP); 60.1416 - loadseg(tempw,&_cs); 60.1417 - SP+=2; 60.1418 - cycles-=12; 60.1419 - break; 60.1420 - 60.1421 - case 0x10: /*ADC 8,reg*/ 60.1422 - fetchea(); 60.1423 - temp=geteab(); 60.1424 - temp2=getr8(reg); 60.1425 - setadc8(temp,temp2); 60.1426 - temp+=temp2+tempc; 60.1427 - seteab(temp); 60.1428 - cycles-=((mod==3)?3:24); 60.1429 - break; 60.1430 - case 0x11: /*ADC 16,reg*/ 60.1431 - fetchea(); 60.1432 - tempw=geteaw(); 60.1433 - tempw2=regs[reg].w; 60.1434 - setadc16(tempw,tempw2); 60.1435 - tempw+=tempw2+tempc; 60.1436 - seteaw(tempw); 60.1437 - cycles-=((mod==3)?3:24); 60.1438 - break; 60.1439 - case 0x12: /*ADC reg,8*/ 60.1440 - fetchea(); 60.1441 - temp=geteab(); 60.1442 - setadc8(getr8(reg),temp); 60.1443 - setr8(reg,getr8(reg)+temp+tempc); 60.1444 - cycles-=((mod==3)?3:13); 60.1445 - break; 60.1446 - case 0x13: /*ADC reg,16*/ 60.1447 - fetchea(); 60.1448 - tempw=geteaw(); 60.1449 - setadc16(regs[reg].w,tempw); 60.1450 - regs[reg].w+=tempw+tempc; 60.1451 - cycles-=((mod==3)?3:13); 60.1452 - break; 60.1453 - case 0x14: /*ADC AL,#8*/ 60.1454 - tempw=FETCH(); 60.1455 - setadc8(AL,tempw); 60.1456 - AL+=tempw+tempc; 60.1457 - cycles-=4; 60.1458 - break; 60.1459 - case 0x15: /*ADC AX,#16*/ 60.1460 - tempw=getword(); 60.1461 - setadc16(AX,tempw); 60.1462 - AX+=tempw+tempc; 60.1463 - cycles-=4; 60.1464 - break; 60.1465 - 60.1466 - case 0x16: /*PUSH SS*/ 60.1467 - if (ssegs) ss=oldss; 60.1468 - writememw(ss,((SP-2)&0xFFFF),SS); 60.1469 - SP-=2; 60.1470 - cycles-=14; 60.1471 - break; 60.1472 - case 0x17: /*POP SS*/ 60.1473 - if (ssegs) ss=oldss; 60.1474 - tempw=readmemw(ss,SP); 60.1475 - loadseg(tempw,&_ss); 60.1476 - SP+=2; 60.1477 - noint=1; 60.1478 - cycles-=12; 60.1479 -// output=1; 60.1480 - break; 60.1481 - 60.1482 - case 0x18: /*SBB 8,reg*/ 60.1483 - fetchea(); 60.1484 - temp=geteab(); 60.1485 - temp2=getr8(reg); 60.1486 - setsbc8(temp,temp2); 60.1487 - temp-=(temp2+tempc); 60.1488 - seteab(temp); 60.1489 - cycles-=((mod==3)?3:24); 60.1490 - break; 60.1491 - case 0x19: /*SBB 16,reg*/ 60.1492 - fetchea(); 60.1493 - tempw=geteaw(); 60.1494 - tempw2=regs[reg].w; 60.1495 -// printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc); 60.1496 - setsbc16(tempw,tempw2); 60.1497 - tempw-=(tempw2+tempc); 60.1498 - seteaw(tempw); 60.1499 - cycles-=((mod==3)?3:24); 60.1500 - break; 60.1501 - case 0x1A: /*SBB reg,8*/ 60.1502 - fetchea(); 60.1503 - temp=geteab(); 60.1504 - setsbc8(getr8(reg),temp); 60.1505 - setr8(reg,getr8(reg)-(temp+tempc)); 60.1506 - cycles-=((mod==3)?3:13); 60.1507 - break; 60.1508 - case 0x1B: /*SBB reg,16*/ 60.1509 - fetchea(); 60.1510 - tempw=geteaw(); 60.1511 - tempw2=regs[reg].w; 60.1512 -// printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc); 60.1513 - setsbc16(tempw2,tempw); 60.1514 - tempw2-=(tempw+tempc); 60.1515 - regs[reg].w=tempw2; 60.1516 - cycles-=((mod==3)?3:13); 60.1517 - break; 60.1518 - case 0x1C: /*SBB AL,#8*/ 60.1519 - temp=FETCH(); 60.1520 - setsbc8(AL,temp); 60.1521 - AL-=(temp+tempc); 60.1522 - cycles-=4; 60.1523 - break; 60.1524 - case 0x1D: /*SBB AX,#16*/ 60.1525 - tempw=getword(); 60.1526 - setsbc16(AX,tempw); 60.1527 - AX-=(tempw+tempc); 60.1528 - cycles-=4; 60.1529 - break; 60.1530 - 60.1531 - case 0x1E: /*PUSH DS*/ 60.1532 - if (ssegs) ss=oldss; 60.1533 - writememw(ss,((SP-2)&0xFFFF),DS); 60.1534 - SP-=2; 60.1535 - cycles-=14; 60.1536 - break; 60.1537 - case 0x1F: /*POP DS*/ 60.1538 - if (ssegs) ss=oldss; 60.1539 - tempw=readmemw(ss,SP); 60.1540 - loadseg(tempw,&_ds); 60.1541 - if (ssegs) oldds=ds; 60.1542 - SP+=2; 60.1543 - cycles-=12; 60.1544 - break; 60.1545 - 60.1546 - case 0x20: /*AND 8,reg*/ 60.1547 - fetchea(); 60.1548 - temp=geteab(); 60.1549 - temp&=getr8(reg); 60.1550 - setznp8(temp); 60.1551 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1552 - seteab(temp); 60.1553 - cycles-=((mod==3)?3:24); 60.1554 - break; 60.1555 - case 0x21: /*AND 16,reg*/ 60.1556 - fetchea(); 60.1557 - tempw=geteaw(); 60.1558 - tempw&=regs[reg].w; 60.1559 - setznp16(tempw); 60.1560 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1561 - seteaw(tempw); 60.1562 - cycles-=((mod==3)?3:24); 60.1563 - break; 60.1564 - case 0x22: /*AND reg,8*/ 60.1565 - fetchea(); 60.1566 - temp=geteab(); 60.1567 - temp&=getr8(reg); 60.1568 - setznp8(temp); 60.1569 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1570 - setr8(reg,temp); 60.1571 - cycles-=((mod==3)?3:13); 60.1572 - break; 60.1573 - case 0x23: /*AND reg,16*/ 60.1574 - fetchea(); 60.1575 - tempw=geteaw(); 60.1576 - tempw&=regs[reg].w; 60.1577 - setznp16(tempw); 60.1578 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1579 - regs[reg].w=tempw; 60.1580 - cycles-=((mod==3)?3:13); 60.1581 - break; 60.1582 - case 0x24: /*AND AL,#8*/ 60.1583 - AL&=FETCH(); 60.1584 - setznp8(AL); 60.1585 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1586 - cycles-=4; 60.1587 - break; 60.1588 - case 0x25: /*AND AX,#16*/ 60.1589 - AX&=getword(); 60.1590 - setznp16(AX); 60.1591 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1592 - cycles-=4; 60.1593 - break; 60.1594 - 60.1595 - case 0x26: /*ES:*/ 60.1596 - oldss=ss; 60.1597 - oldds=ds; 60.1598 - ds=ss=es; 60.1599 - ssegs=2; 60.1600 - cycles-=4; 60.1601 - goto opcodestart; 60.1602 -// break; 60.1603 - 60.1604 - case 0x27: /*DAA*/ 60.1605 - if ((flags&A_FLAG) || ((AL&0xF)>9)) 60.1606 - { 60.1607 - tempi=((uint16_t)AL)+6; 60.1608 - AL+=6; 60.1609 - flags|=A_FLAG; 60.1610 - if (tempi&0x100) flags|=C_FLAG; 60.1611 - } 60.1612 -// else 60.1613 -// flags&=~A_FLAG; 60.1614 - if ((flags&C_FLAG) || (AL>0x9F)) 60.1615 - { 60.1616 - AL+=0x60; 60.1617 - flags|=C_FLAG; 60.1618 - } 60.1619 -// else 60.1620 -// flags&=~C_FLAG; 60.1621 - setznp8(AL); 60.1622 - cycles-=4; 60.1623 - break; 60.1624 - 60.1625 - case 0x28: /*SUB 8,reg*/ 60.1626 - fetchea(); 60.1627 - temp=geteab(); 60.1628 - setsub8(temp,getr8(reg)); 60.1629 - temp-=getr8(reg); 60.1630 - seteab(temp); 60.1631 - cycles-=((mod==3)?3:24); 60.1632 - break; 60.1633 - case 0x29: /*SUB 16,reg*/ 60.1634 - fetchea(); 60.1635 - tempw=geteaw(); 60.1636 -// printf("%04X:%04X %04X-%04X\n",cs>>4,pc,tempw,regs[reg].w); 60.1637 - setsub16(tempw,regs[reg].w); 60.1638 - tempw-=regs[reg].w; 60.1639 - seteaw(tempw); 60.1640 - cycles-=((mod==3)?3:24); 60.1641 - break; 60.1642 - case 0x2A: /*SUB reg,8*/ 60.1643 - fetchea(); 60.1644 - temp=geteab(); 60.1645 - setsub8(getr8(reg),temp); 60.1646 - setr8(reg,getr8(reg)-temp); 60.1647 - cycles-=((mod==3)?3:13); 60.1648 - break; 60.1649 - case 0x2B: /*SUB reg,16*/ 60.1650 - fetchea(); 60.1651 - tempw=geteaw(); 60.1652 -// printf("%04X:%04X %04X-%04X\n",cs>>4,pc,regs[reg].w,tempw); 60.1653 - setsub16(regs[reg].w,tempw); 60.1654 - regs[reg].w-=tempw; 60.1655 - cycles-=((mod==3)?3:13); 60.1656 - break; 60.1657 - case 0x2C: /*SUB AL,#8*/ 60.1658 - temp=FETCH(); 60.1659 - setsub8(AL,temp); 60.1660 - AL-=temp; 60.1661 - cycles-=4; 60.1662 - break; 60.1663 - case 0x2D: /*SUB AX,#16*/ 60.1664 -// printf("INS %i\n",ins); 60.1665 -// output=1; 60.1666 - tempw=getword(); 60.1667 - setsub16(AX,tempw); 60.1668 - AX-=tempw; 60.1669 - cycles-=4; 60.1670 - break; 60.1671 - case 0x2E: /*CS:*/ 60.1672 - oldss=ss; 60.1673 - oldds=ds; 60.1674 - ds=ss=cs; 60.1675 - ssegs=2; 60.1676 - cycles-=4; 60.1677 - goto opcodestart; 60.1678 - case 0x2F: /*DAS*/ 60.1679 - if ((flags&A_FLAG)||((AL&0xF)>9)) 60.1680 - { 60.1681 - tempi=((uint16_t)AL)-6; 60.1682 - AL-=6; 60.1683 - flags|=A_FLAG; 60.1684 - if (tempi&0x100) flags|=C_FLAG; 60.1685 - } 60.1686 -// else 60.1687 -// flags&=~A_FLAG; 60.1688 - if ((flags&C_FLAG)||(AL>0x9F)) 60.1689 - { 60.1690 - AL-=0x60; 60.1691 - flags|=C_FLAG; 60.1692 - } 60.1693 -// else 60.1694 -// flags&=~C_FLAG; 60.1695 - setznp8(AL); 60.1696 - cycles-=4; 60.1697 - break; 60.1698 - case 0x30: /*XOR 8,reg*/ 60.1699 - fetchea(); 60.1700 - temp=geteab(); 60.1701 - temp^=getr8(reg); 60.1702 - setznp8(temp); 60.1703 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1704 - seteab(temp); 60.1705 - cycles-=((mod==3)?3:24); 60.1706 - break; 60.1707 - case 0x31: /*XOR 16,reg*/ 60.1708 - fetchea(); 60.1709 - tempw=geteaw(); 60.1710 - tempw^=regs[reg].w; 60.1711 - setznp16(tempw); 60.1712 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1713 - seteaw(tempw); 60.1714 - cycles-=((mod==3)?3:24); 60.1715 - break; 60.1716 - case 0x32: /*XOR reg,8*/ 60.1717 - fetchea(); 60.1718 - temp=geteab(); 60.1719 - temp^=getr8(reg); 60.1720 - setznp8(temp); 60.1721 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1722 - setr8(reg,temp); 60.1723 - cycles-=((mod==3)?3:13); 60.1724 - break; 60.1725 - case 0x33: /*XOR reg,16*/ 60.1726 - fetchea(); 60.1727 - tempw=geteaw(); 60.1728 - tempw^=regs[reg].w; 60.1729 - setznp16(tempw); 60.1730 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1731 - regs[reg].w=tempw; 60.1732 - cycles-=((mod==3)?3:13); 60.1733 - break; 60.1734 - case 0x34: /*XOR AL,#8*/ 60.1735 - AL^=FETCH(); 60.1736 - setznp8(AL); 60.1737 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1738 - cycles-=4; 60.1739 - break; 60.1740 - case 0x35: /*XOR AX,#16*/ 60.1741 - AX^=getword(); 60.1742 - setznp16(AX); 60.1743 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1744 - cycles-=4; 60.1745 - break; 60.1746 - 60.1747 - case 0x36: /*SS:*/ 60.1748 - oldss=ss; 60.1749 - oldds=ds; 60.1750 - ds=ss=ss; 60.1751 - ssegs=2; 60.1752 - cycles-=4; 60.1753 - goto opcodestart; 60.1754 -// break; 60.1755 - 60.1756 - case 0x37: /*AAA*/ 60.1757 - if ((flags&A_FLAG)||((AL&0xF)>9)) 60.1758 - { 60.1759 - AL+=6; 60.1760 - AH++; 60.1761 - flags|=(A_FLAG|C_FLAG); 60.1762 - } 60.1763 - else 60.1764 - flags&=~(A_FLAG|C_FLAG); 60.1765 - AL&=0xF; 60.1766 - cycles-=8; 60.1767 - break; 60.1768 - 60.1769 - case 0x38: /*CMP 8,reg*/ 60.1770 - fetchea(); 60.1771 - temp=geteab(); 60.1772 -// if (output) printf("CMP %02X-%02X\n",temp,getr8(reg)); 60.1773 - setsub8(temp,getr8(reg)); 60.1774 - cycles-=((mod==3)?3:13); 60.1775 - break; 60.1776 - case 0x39: /*CMP 16,reg*/ 60.1777 - fetchea(); 60.1778 - tempw=geteaw(); 60.1779 -// if (output) printf("CMP %04X-%04X\n",tempw,regs[reg].w); 60.1780 - setsub16(tempw,regs[reg].w); 60.1781 - cycles-=((mod==3)?3:13); 60.1782 - break; 60.1783 - case 0x3A: /*CMP reg,8*/ 60.1784 - fetchea(); 60.1785 - temp=geteab(); 60.1786 -// if (output) printf("CMP %02X-%02X\n",getr8(reg),temp); 60.1787 - setsub8(getr8(reg),temp); 60.1788 - cycles-=((mod==3)?3:13); 60.1789 - break; 60.1790 - case 0x3B: /*CMP reg,16*/ 60.1791 - fetchea(); 60.1792 - tempw=geteaw(); 60.1793 -// printf("CMP %04X-%04X\n",regs[reg].w,tempw); 60.1794 - setsub16(regs[reg].w,tempw); 60.1795 - cycles-=((mod==3)?3:13); 60.1796 - break; 60.1797 - case 0x3C: /*CMP AL,#8*/ 60.1798 - temp=FETCH(); 60.1799 - setsub8(AL,temp); 60.1800 - cycles-=4; 60.1801 - break; 60.1802 - case 0x3D: /*CMP AX,#16*/ 60.1803 - tempw=getword(); 60.1804 - setsub16(AX,tempw); 60.1805 - cycles-=4; 60.1806 - break; 60.1807 - 60.1808 - case 0x3E: /*DS:*/ 60.1809 - oldss=ss; 60.1810 - oldds=ds; 60.1811 - ds=ss=ds; 60.1812 - ssegs=2; 60.1813 - cycles-=4; 60.1814 - goto opcodestart; 60.1815 -// break; 60.1816 - 60.1817 - case 0x3F: /*AAS*/ 60.1818 - if ((flags&A_FLAG)||((AL&0xF)>9)) 60.1819 - { 60.1820 - AL-=6; 60.1821 - AH--; 60.1822 - flags|=(A_FLAG|C_FLAG); 60.1823 - } 60.1824 - else 60.1825 - flags&=~(A_FLAG|C_FLAG); 60.1826 - AL&=0xF; 60.1827 - cycles-=8; 60.1828 - break; 60.1829 - 60.1830 - case 0x40: case 0x41: case 0x42: case 0x43: /*INC r16*/ 60.1831 - case 0x44: case 0x45: case 0x46: case 0x47: 60.1832 - setadd16nc(regs[opcode&7].w,1); 60.1833 - regs[opcode&7].w++; 60.1834 - cycles-=3; 60.1835 - break; 60.1836 - case 0x48: case 0x49: case 0x4A: case 0x4B: /*DEC r16*/ 60.1837 - case 0x4C: case 0x4D: case 0x4E: case 0x4F: 60.1838 - setsub16nc(regs[opcode&7].w,1); 60.1839 - regs[opcode&7].w--; 60.1840 - cycles-=3; 60.1841 - break; 60.1842 - 60.1843 - case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/ 60.1844 - case 0x54: case 0x55: case 0x56: case 0x57: 60.1845 - if (ssegs) ss=oldss; 60.1846 - SP-=2; 60.1847 - writememw(ss,SP,regs[opcode&7].w); 60.1848 - cycles-=15; 60.1849 - break; 60.1850 - case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/ 60.1851 - case 0x5C: case 0x5D: case 0x5E: case 0x5F: 60.1852 - if (ssegs) ss=oldss; 60.1853 - SP+=2; 60.1854 - regs[opcode&7].w=readmemw(ss,(SP-2)&0xFFFF); 60.1855 - cycles-=12; 60.1856 - break; 60.1857 - 60.1858 - 60.1859 - case 0x70: /*JO*/ 60.1860 - offset=(int8_t)FETCH(); 60.1861 - if (flags&V_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1862 - cycles-=4; 60.1863 - break; 60.1864 - case 0x71: /*JNO*/ 60.1865 - offset=(int8_t)FETCH(); 60.1866 - if (!(flags&V_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1867 - cycles-=4; 60.1868 - break; 60.1869 - case 0x72: /*JB*/ 60.1870 - offset=(int8_t)FETCH(); 60.1871 - if (flags&C_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1872 - cycles-=4; 60.1873 - break; 60.1874 - case 0x73: /*JNB*/ 60.1875 - offset=(int8_t)FETCH(); 60.1876 - if (!(flags&C_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1877 - cycles-=4; 60.1878 - break; 60.1879 - case 0x74: /*JE*/ 60.1880 - offset=(int8_t)FETCH(); 60.1881 - if (flags&Z_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1882 - cycles-=4; 60.1883 - break; 60.1884 - case 0x75: /*JNE*/ 60.1885 - offset=(int8_t)FETCH(); 60.1886 - cycles-=4; 60.1887 - if (!(flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1888 - break; 60.1889 - case 0x76: /*JBE*/ 60.1890 - offset=(int8_t)FETCH(); 60.1891 - if (flags&(C_FLAG|Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1892 - cycles-=4; 60.1893 - break; 60.1894 - case 0x77: /*JNBE*/ 60.1895 - offset=(int8_t)FETCH(); 60.1896 - if (!(flags&(C_FLAG|Z_FLAG))) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1897 - cycles-=4; 60.1898 - break; 60.1899 - case 0x78: /*JS*/ 60.1900 - offset=(int8_t)FETCH(); 60.1901 - if (flags&N_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1902 - cycles-=4; 60.1903 - break; 60.1904 - case 0x79: /*JNS*/ 60.1905 - offset=(int8_t)FETCH(); 60.1906 - if (!(flags&N_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1907 - cycles-=4; 60.1908 - break; 60.1909 - case 0x7A: /*JP*/ 60.1910 - offset=(int8_t)FETCH(); 60.1911 - if (flags&P_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1912 - cycles-=4; 60.1913 - break; 60.1914 - case 0x7B: /*JNP*/ 60.1915 - offset=(int8_t)FETCH(); 60.1916 - if (!(flags&P_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1917 - cycles-=4; 60.1918 - break; 60.1919 - case 0x7C: /*JL*/ 60.1920 - offset=(int8_t)FETCH(); 60.1921 - temp=(flags&N_FLAG)?1:0; 60.1922 - temp2=(flags&V_FLAG)?1:0; 60.1923 - if (temp!=temp2) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1924 - cycles-=4; 60.1925 - break; 60.1926 - case 0x7D: /*JNL*/ 60.1927 - offset=(int8_t)FETCH(); 60.1928 - temp=(flags&N_FLAG)?1:0; 60.1929 - temp2=(flags&V_FLAG)?1:0; 60.1930 - if (temp==temp2) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1931 - cycles-=4; 60.1932 - break; 60.1933 - case 0x7E: /*JLE*/ 60.1934 - offset=(int8_t)FETCH(); 60.1935 - temp=(flags&N_FLAG)?1:0; 60.1936 - temp2=(flags&V_FLAG)?1:0; 60.1937 - if ((flags&Z_FLAG) || (temp!=temp2)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1938 - cycles-=4; 60.1939 - break; 60.1940 - case 0x7F: /*JNLE*/ 60.1941 - offset=(int8_t)FETCH(); 60.1942 - temp=(flags&N_FLAG)?1:0; 60.1943 - temp2=(flags&V_FLAG)?1:0; 60.1944 - if (!((flags&Z_FLAG) || (temp!=temp2))) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.1945 - cycles-=4; 60.1946 - break; 60.1947 - 60.1948 - case 0x80: case 0x82: 60.1949 - fetchea(); 60.1950 - temp=geteab(); 60.1951 - temp2=FETCH(); 60.1952 - switch (rmdat&0x38) 60.1953 - { 60.1954 - case 0x00: /*ADD b,#8*/ 60.1955 - setadd8(temp,temp2); 60.1956 - seteab(temp+temp2); 60.1957 - cycles-=((mod==3)?4:23); 60.1958 - break; 60.1959 - case 0x08: /*OR b,#8*/ 60.1960 - temp|=temp2; 60.1961 - setznp8(temp); 60.1962 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1963 - seteab(temp); 60.1964 - cycles-=((mod==3)?4:23); 60.1965 - break; 60.1966 - case 0x10: /*ADC b,#8*/ 60.1967 -// temp2+=(flags&C_FLAG); 60.1968 - setadc8(temp,temp2); 60.1969 - seteab(temp+temp2+tempc); 60.1970 - cycles-=((mod==3)?4:23); 60.1971 - break; 60.1972 - case 0x18: /*SBB b,#8*/ 60.1973 -// temp2+=(flags&C_FLAG); 60.1974 - setsbc8(temp,temp2); 60.1975 - seteab(temp-(temp2+tempc)); 60.1976 - cycles-=((mod==3)?4:23); 60.1977 - break; 60.1978 - case 0x20: /*AND b,#8*/ 60.1979 - temp&=temp2; 60.1980 - setznp8(temp); 60.1981 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1982 - seteab(temp); 60.1983 - cycles-=((mod==3)?4:23); 60.1984 - break; 60.1985 - case 0x28: /*SUB b,#8*/ 60.1986 - setsub8(temp,temp2); 60.1987 - seteab(temp-temp2); 60.1988 - cycles-=((mod==3)?4:23); 60.1989 - break; 60.1990 - case 0x30: /*XOR b,#8*/ 60.1991 - temp^=temp2; 60.1992 - setznp8(temp); 60.1993 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.1994 - seteab(temp); 60.1995 - cycles-=((mod==3)?4:23); 60.1996 - break; 60.1997 - case 0x38: /*CMP b,#8*/ 60.1998 - setsub8(temp,temp2); 60.1999 - cycles-=((mod==3)?4:14); 60.2000 - break; 60.2001 - 60.2002 -// default: 60.2003 -// printf("Bad 80 opcode %02X\n",rmdat&0x38); 60.2004 -// dumpregs(); 60.2005 -// exit(-1); 60.2006 - } 60.2007 - break; 60.2008 - 60.2009 - case 0x81: 60.2010 - fetchea(); 60.2011 - tempw=geteaw(); 60.2012 - tempw2=getword(); 60.2013 - switch (rmdat&0x38) 60.2014 - { 60.2015 - case 0x00: /*ADD w,#16*/ 60.2016 - setadd16(tempw,tempw2); 60.2017 - tempw+=tempw2; 60.2018 - seteaw(tempw); 60.2019 - cycles-=((mod==3)?4:23); 60.2020 - break; 60.2021 - case 0x08: /*OR w,#16*/ 60.2022 - tempw|=tempw2; 60.2023 - setznp16(tempw); 60.2024 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.2025 - seteaw(tempw); 60.2026 - cycles-=((mod==3)?4:23); 60.2027 - break; 60.2028 - case 0x10: /*ADC w,#16*/ 60.2029 -// tempw2+=(flags&C_FLAG); 60.2030 - setadc16(tempw,tempw2); 60.2031 - tempw+=tempw2+tempc; 60.2032 - seteaw(tempw); 60.2033 - cycles-=((mod==3)?4:23); 60.2034 - break; 60.2035 - case 0x20: /*AND w,#16*/ 60.2036 - tempw&=tempw2; 60.2037 - setznp16(tempw); 60.2038 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.2039 - seteaw(tempw); 60.2040 - cycles-=((mod==3)?4:23); 60.2041 - break; 60.2042 - case 0x18: /*SBB w,#16*/ 60.2043 -// tempw2+=(flags&C_FLAG); 60.2044 - setsbc16(tempw,tempw2); 60.2045 - seteaw(tempw-(tempw2+tempc)); 60.2046 - cycles-=((mod==3)?4:23); 60.2047 - break; 60.2048 - case 0x28: /*SUB w,#16*/ 60.2049 - setsub16(tempw,tempw2); 60.2050 - tempw-=tempw2; 60.2051 - seteaw(tempw); 60.2052 - cycles-=((mod==3)?4:23); 60.2053 - break; 60.2054 - case 0x30: /*XOR w,#16*/ 60.2055 - tempw^=tempw2; 60.2056 - setznp16(tempw); 60.2057 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.2058 - seteaw(tempw); 60.2059 - cycles-=((mod==3)?4:23); 60.2060 - break; 60.2061 - case 0x38: /*CMP w,#16*/ 60.2062 -// printf("CMP %04X %04X\n",tempw,tempw2); 60.2063 - setsub16(tempw,tempw2); 60.2064 - cycles-=((mod==3)?4:14); 60.2065 - break; 60.2066 - 60.2067 -// default: 60.2068 -// printf("Bad 81 opcode %02X\n",rmdat&0x38); 60.2069 -// dumpregs(); 60.2070 -// exit(-1); 60.2071 - } 60.2072 - break; 60.2073 - 60.2074 - case 0x83: 60.2075 - fetchea(); 60.2076 - tempw=geteaw(); 60.2077 - tempw2=FETCH(); 60.2078 - if (tempw2&0x80) tempw2|=0xFF00; 60.2079 - switch (rmdat&0x38) 60.2080 - { 60.2081 - case 0x00: /*ADD w,#8*/ 60.2082 - setadd16(tempw,tempw2); 60.2083 - tempw+=tempw2; 60.2084 - seteaw(tempw); 60.2085 - cycles-=((mod==3)?4:23); 60.2086 - break; 60.2087 - case 0x08: /*OR w,#8*/ 60.2088 - tempw|=tempw2; 60.2089 - setznp16(tempw); 60.2090 - seteaw(tempw); 60.2091 - flags&=~(C_FLAG|A_FLAG|V_FLAG); 60.2092 - cycles-=((mod==3)?4:23); 60.2093 - break; 60.2094 - case 0x10: /*ADC w,#8*/ 60.2095 -// tempw2+=(flags&C_FLAG); 60.2096 - setadc16(tempw,tempw2); 60.2097 - tempw+=tempw2+tempc; 60.2098 - seteaw(tempw); 60.2099 - cycles-=((mod==3)?4:23); 60.2100 - break; 60.2101 - case 0x18: /*SBB w,#8*/ 60.2102 -// tempw2+=(flags&C_FLAG); 60.2103 - setsbc16(tempw,tempw2); 60.2104 - tempw-=(tempw2+tempc); 60.2105 - seteaw(tempw); 60.2106 - cycles-=((mod==3)?4:23); 60.2107 - break; 60.2108 - case 0x20: /*AND w,#8*/ 60.2109 - tempw&=tempw2; 60.2110 - setznp16(tempw); 60.2111 - seteaw(tempw); 60.2112 - cycles-=((mod==3)?4:23); 60.2113 - flags&=~(C_FLAG|A_FLAG|V_FLAG); 60.2114 - break; 60.2115 - case 0x28: /*SUB w,#8*/ 60.2116 - setsub16(tempw,tempw2); 60.2117 - tempw-=tempw2; 60.2118 - seteaw(tempw); 60.2119 - cycles-=((mod==3)?4:23); 60.2120 - break; 60.2121 - case 0x30: /*XOR w,#8*/ 60.2122 - tempw^=tempw2; 60.2123 - setznp16(tempw); 60.2124 - seteaw(tempw); 60.2125 - cycles-=((mod==3)?4:23); 60.2126 - flags&=~(C_FLAG|A_FLAG|V_FLAG); 60.2127 - break; 60.2128 - case 0x38: /*CMP w,#8*/ 60.2129 - setsub16(tempw,tempw2); 60.2130 - cycles-=((mod==3)?4:14); 60.2131 - break; 60.2132 - 60.2133 -// default: 60.2134 -// printf("Bad 83 opcode %02X\n",rmdat&0x38); 60.2135 -// dumpregs(); 60.2136 -// exit(-1); 60.2137 - } 60.2138 - break; 60.2139 - 60.2140 - case 0x84: /*TEST b,reg*/ 60.2141 - fetchea(); 60.2142 - temp=geteab(); 60.2143 - temp2=getr8(reg); 60.2144 - setznp8(temp&temp2); 60.2145 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.2146 - cycles-=((mod==3)?3:13); 60.2147 - break; 60.2148 - case 0x85: /*TEST w,reg*/ 60.2149 - fetchea(); 60.2150 - tempw=geteaw(); 60.2151 - tempw2=regs[reg].w; 60.2152 - setznp16(tempw&tempw2); 60.2153 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.2154 - cycles-=((mod==3)?3:13); 60.2155 - break; 60.2156 - case 0x86: /*XCHG b,reg*/ 60.2157 - fetchea(); 60.2158 - temp=geteab(); 60.2159 - seteab(getr8(reg)); 60.2160 - setr8(reg,temp); 60.2161 - cycles-=((mod==3)?4:25); 60.2162 - break; 60.2163 - case 0x87: /*XCHG w,reg*/ 60.2164 - fetchea(); 60.2165 - tempw=geteaw(); 60.2166 - seteaw(regs[reg].w); 60.2167 - regs[reg].w=tempw; 60.2168 - cycles-=((mod==3)?4:25); 60.2169 - break; 60.2170 - 60.2171 - case 0x88: /*MOV b,reg*/ 60.2172 - fetchea(); 60.2173 - seteab(getr8(reg)); 60.2174 - cycles-=((mod==3)?2:13); 60.2175 - break; 60.2176 - case 0x89: /*MOV w,reg*/ 60.2177 - fetchea(); 60.2178 - seteaw(regs[reg].w); 60.2179 - cycles-=((mod==3)?2:13); 60.2180 - break; 60.2181 - case 0x8A: /*MOV reg,b*/ 60.2182 - fetchea(); 60.2183 - temp=geteab(); 60.2184 - setr8(reg,temp); 60.2185 - cycles-=((mod==3)?2:12); 60.2186 - break; 60.2187 - case 0x8B: /*MOV reg,w*/ 60.2188 - fetchea(); 60.2189 - tempw=geteaw(); 60.2190 - regs[reg].w=tempw; 60.2191 - cycles-=((mod==3)?2:12); 60.2192 - break; 60.2193 - 60.2194 - case 0x8C: /*MOV w,sreg*/ 60.2195 - fetchea(); 60.2196 - switch (rmdat&0x38) 60.2197 - { 60.2198 - case 0x00: /*ES*/ 60.2199 - seteaw(ES); 60.2200 - break; 60.2201 - case 0x08: /*CS*/ 60.2202 - seteaw(CS); 60.2203 - break; 60.2204 - case 0x18: /*DS*/ 60.2205 - if (ssegs) ds=oldds; 60.2206 - seteaw(DS); 60.2207 - break; 60.2208 - case 0x10: /*SS*/ 60.2209 - if (ssegs) ss=oldss; 60.2210 - seteaw(SS); 60.2211 - break; 60.2212 - } 60.2213 - cycles-=((mod==3)?2:13); 60.2214 - break; 60.2215 - 60.2216 - case 0x8D: /*LEA*/ 60.2217 - fetchea(); 60.2218 - regs[reg].w=eaaddr; 60.2219 - cycles-=2; 60.2220 - break; 60.2221 - 60.2222 - case 0x8E: /*MOV sreg,w*/ 60.2223 -// if (output) printf("MOV %04X ",pc); 60.2224 - fetchea(); 60.2225 -// if (output) printf("%04X %02X\n",pc,rmdat); 60.2226 - switch (rmdat&0x38) 60.2227 - { 60.2228 - case 0x00: /*ES*/ 60.2229 - tempw=geteaw(); 60.2230 - loadseg(tempw,&_es); 60.2231 - break; 60.2232 - case 0x08: /*CS - 8088/8086 only*/ 60.2233 - tempw=geteaw(); 60.2234 - loadseg(tempw,&_cs); 60.2235 - break; 60.2236 - case 0x18: /*DS*/ 60.2237 - tempw=geteaw(); 60.2238 - loadseg(tempw,&_ds); 60.2239 - if (ssegs) oldds=ds; 60.2240 - break; 60.2241 - case 0x10: /*SS*/ 60.2242 - tempw=geteaw(); 60.2243 - loadseg(tempw,&_ss); 60.2244 - if (ssegs) oldss=ss; 60.2245 -// printf("LOAD SS %04X %04X\n",tempw,SS); 60.2246 -// printf("SS loaded with %04X %04X:%04X %04X %04X %04X\n",ss>>4,cs>>4,pc,CX,DX,es>>4); 60.2247 - break; 60.2248 - } 60.2249 - cycles-=((mod==3)?2:12); 60.2250 - skipnextprint=1; 60.2251 - noint=1; 60.2252 - break; 60.2253 - 60.2254 - case 0x8F: /*POPW*/ 60.2255 - fetchea(); 60.2256 - if (ssegs) ss=oldss; 60.2257 - tempw=readmemw(ss,SP); 60.2258 - SP+=2; 60.2259 - seteaw(tempw); 60.2260 - cycles-=25; 60.2261 - break; 60.2262 - 60.2263 - case 0x90: /*NOP*/ 60.2264 - cycles-=3; 60.2265 - break; 60.2266 - 60.2267 - case 0x91: case 0x92: case 0x93: /*XCHG AX*/ 60.2268 - case 0x94: case 0x95: case 0x96: case 0x97: 60.2269 - tempw=AX; 60.2270 - AX=regs[opcode&7].w; 60.2271 - regs[opcode&7].w=tempw; 60.2272 - cycles-=3; 60.2273 - break; 60.2274 - 60.2275 - case 0x98: /*CBW*/ 60.2276 - AH=(AL&0x80)?0xFF:0; 60.2277 - cycles-=2; 60.2278 - break; 60.2279 - case 0x99: /*CWD*/ 60.2280 - DX=(AX&0x8000)?0xFFFF:0; 60.2281 - cycles-=5; 60.2282 - break; 60.2283 - case 0x9A: /*CALL FAR*/ 60.2284 - tempw=getword(); 60.2285 - tempw2=getword(); 60.2286 - tempw3=CS; 60.2287 - tempw4=pc; 60.2288 - if (ssegs) ss=oldss; 60.2289 - pc=tempw; 60.2290 -// printf("0x9a"); 60.2291 - loadcs(tempw2); 60.2292 - writememw(ss,(SP-2)&0xFFFF,tempw3); 60.2293 - writememw(ss,(SP-4)&0xFFFF,tempw4); 60.2294 - SP-=4; 60.2295 - cycles-=36; 60.2296 - FETCHCLEAR(); 60.2297 - break; 60.2298 - case 0x9B: /*WAIT*/ 60.2299 - cycles-=4; 60.2300 - break; 60.2301 - case 0x9C: /*PUSHF*/ 60.2302 - if (ssegs) ss=oldss; 60.2303 - writememw(ss,((SP-2)&0xFFFF),flags|0xF000); 60.2304 - SP-=2; 60.2305 - cycles-=14; 60.2306 - break; 60.2307 - case 0x9D: /*POPF*/ 60.2308 - if (ssegs) ss=oldss; 60.2309 - flags=readmemw(ss,SP)&0xFFF; 60.2310 - SP+=2; 60.2311 - cycles-=12; 60.2312 - break; 60.2313 - case 0x9E: /*SAHF*/ 60.2314 - flags=(flags&0xFF00)|AH; 60.2315 - cycles-=4; 60.2316 - break; 60.2317 - case 0x9F: /*LAHF*/ 60.2318 - AH=flags&0xFF; 60.2319 - cycles-=4; 60.2320 - break; 60.2321 - 60.2322 - case 0xA0: /*MOV AL,(w)*/ 60.2323 - addr=getword(); 60.2324 - AL=readmemb(ds+addr); 60.2325 - cycles-=14; 60.2326 - break; 60.2327 - case 0xA1: /*MOV AX,(w)*/ 60.2328 - addr=getword(); 60.2329 -// printf("Reading AX from %05X %04X:%04X\n",ds+addr,ds>>4,addr); 60.2330 - AX=readmemw(ds,addr); 60.2331 - cycles-=!4; 60.2332 - break; 60.2333 - case 0xA2: /*MOV (w),AL*/ 60.2334 - addr=getword(); 60.2335 - writememb(ds+addr,AL); 60.2336 - cycles-=14; 60.2337 - break; 60.2338 - case 0xA3: /*MOV (w),AX*/ 60.2339 - addr=getword(); 60.2340 -// if (!addr) printf("Write !addr %04X:%04X\n",cs>>4,pc); 60.2341 - writememw(ds,addr,AX); 60.2342 - cycles-=14; 60.2343 - break; 60.2344 - 60.2345 - case 0xA4: /*MOVSB*/ 60.2346 - temp=readmemb(ds+SI); 60.2347 - writememb(es+DI,temp); 60.2348 - if (flags&D_FLAG) { DI--; SI--; } 60.2349 - else { DI++; SI++; } 60.2350 - cycles-=18; 60.2351 - break; 60.2352 - case 0xA5: /*MOVSW*/ 60.2353 - tempw=readmemw(ds,SI); 60.2354 - writememw(es,DI,tempw); 60.2355 - if (flags&D_FLAG) { DI-=2; SI-=2; } 60.2356 - else { DI+=2; SI+=2; } 60.2357 - cycles-=18; 60.2358 - break; 60.2359 - case 0xA6: /*CMPSB*/ 60.2360 - temp =readmemb(ds+SI); 60.2361 - temp2=readmemb(es+DI); 60.2362 - setsub8(temp,temp2); 60.2363 - if (flags&D_FLAG) { DI--; SI--; } 60.2364 - else { DI++; SI++; } 60.2365 - cycles-=30; 60.2366 - break; 60.2367 - case 0xA7: /*CMPSW*/ 60.2368 - tempw =readmemw(ds,SI); 60.2369 - tempw2=readmemw(es,DI); 60.2370 -// printf("CMPSW %04X %04X\n",tempw,tempw2); 60.2371 - setsub16(tempw,tempw2); 60.2372 - if (flags&D_FLAG) { DI-=2; SI-=2; } 60.2373 - else { DI+=2; SI+=2; } 60.2374 - cycles-=30; 60.2375 - break; 60.2376 - case 0xA8: /*TEST AL,#8*/ 60.2377 - temp=FETCH(); 60.2378 - setznp8(AL&temp); 60.2379 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.2380 - cycles-=5; 60.2381 - break; 60.2382 - case 0xA9: /*TEST AX,#16*/ 60.2383 - tempw=getword(); 60.2384 - setznp16(AX&tempw); 60.2385 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.2386 - cycles-=5; 60.2387 - break; 60.2388 - case 0xAA: /*STOSB*/ 60.2389 - writememb(es+DI,AL); 60.2390 - if (flags&D_FLAG) DI--; 60.2391 - else DI++; 60.2392 - cycles-=11; 60.2393 - break; 60.2394 - case 0xAB: /*STOSW*/ 60.2395 - writememw(es,DI,AX); 60.2396 - if (flags&D_FLAG) DI-=2; 60.2397 - else DI+=2; 60.2398 - cycles-=11; 60.2399 - break; 60.2400 - case 0xAC: /*LODSB*/ 60.2401 - AL=readmemb(ds+SI); 60.2402 -// printf("LODSB %04X:%04X %02X %04X:%04X\n",cs>>4,pc,AL,ds>>4,SI); 60.2403 - if (flags&D_FLAG) SI--; 60.2404 - else SI++; 60.2405 - cycles-=16; 60.2406 - break; 60.2407 - case 0xAD: /*LODSW*/ 60.2408 -// if (times) printf("LODSW %04X:%04X\n",cs>>4,pc); 60.2409 - AX=readmemw(ds,SI); 60.2410 - if (flags&D_FLAG) SI-=2; 60.2411 - else SI+=2; 60.2412 - cycles-=16; 60.2413 - break; 60.2414 - case 0xAE: /*SCASB*/ 60.2415 - temp=readmemb(es+DI); 60.2416 - setsub8(AL,temp); 60.2417 - if (flags&D_FLAG) DI--; 60.2418 - else DI++; 60.2419 - cycles-=19; 60.2420 - break; 60.2421 - case 0xAF: /*SCASW*/ 60.2422 - tempw=readmemw(es,DI); 60.2423 - setsub16(AX,tempw); 60.2424 - if (flags&D_FLAG) DI-=2; 60.2425 - else DI+=2; 60.2426 - cycles-=19; 60.2427 - break; 60.2428 - 60.2429 - case 0xB0: /*MOV AL,#8*/ 60.2430 - AL=FETCH(); 60.2431 - cycles-=4; 60.2432 - break; 60.2433 - case 0xB1: /*MOV CL,#8*/ 60.2434 - CL=FETCH(); 60.2435 - cycles-=4; 60.2436 - break; 60.2437 - case 0xB2: /*MOV DL,#8*/ 60.2438 - DL=FETCH(); 60.2439 - cycles-=4; 60.2440 - break; 60.2441 - case 0xB3: /*MOV BL,#8*/ 60.2442 - BL=FETCH(); 60.2443 - cycles-=4; 60.2444 - break; 60.2445 - case 0xB4: /*MOV AH,#8*/ 60.2446 - AH=FETCH(); 60.2447 - cycles-=4; 60.2448 - break; 60.2449 - case 0xB5: /*MOV CH,#8*/ 60.2450 - CH=FETCH(); 60.2451 - cycles-=4; 60.2452 - break; 60.2453 - case 0xB6: /*MOV DH,#8*/ 60.2454 - DH=FETCH(); 60.2455 - cycles-=4; 60.2456 - break; 60.2457 - case 0xB7: /*MOV BH,#8*/ 60.2458 - BH=FETCH(); 60.2459 - cycles-=4; 60.2460 - break; 60.2461 - case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV reg,#16*/ 60.2462 - case 0xBC: case 0xBD: case 0xBE: case 0xBF: 60.2463 - regs[opcode&7].w=getword(); 60.2464 - cycles-=4; 60.2465 - break; 60.2466 - 60.2467 - case 0xC2: /*RET*/ 60.2468 - tempw=getword(); 60.2469 - if (ssegs) ss=oldss; 60.2470 - pc=readmemw(ss,SP); 60.2471 -// printf("C2\n"); 60.2472 -// printf("RET to %04X\n",pc); 60.2473 - SP+=2+tempw; 60.2474 - cycles-=24; 60.2475 - FETCHCLEAR(); 60.2476 - break; 60.2477 - case 0xC3: /*RET*/ 60.2478 - if (ssegs) ss=oldss; 60.2479 - pc=readmemw(ss,SP); 60.2480 -// printf("C3\n"); 60.2481 -// if (output) printf("RET to %04X %05X\n",pc,ss+SP); 60.2482 - SP+=2; 60.2483 - cycles-=20; 60.2484 - FETCHCLEAR(); 60.2485 - break; 60.2486 - case 0xC4: /*LES*/ 60.2487 - fetchea(); 60.2488 - regs[reg].w=readmemw(easeg,eaaddr); //geteaw(); 60.2489 - tempw=readmemw(easeg,(eaaddr+2)&0xFFFF); //geteaw2(); 60.2490 - loadseg(tempw,&_es); 60.2491 - cycles-=24; 60.2492 - break; 60.2493 - case 0xC5: /*LDS*/ 60.2494 - fetchea(); 60.2495 - regs[reg].w=readmemw(easeg,eaaddr); 60.2496 - tempw=readmemw(easeg,(eaaddr+2)&0xFFFF); 60.2497 - loadseg(tempw,&_ds); 60.2498 - if (ssegs) oldds=ds; 60.2499 - cycles-=24; 60.2500 - break; 60.2501 - case 0xC6: /*MOV b,#8*/ 60.2502 - fetchea(); 60.2503 - temp=FETCH(); 60.2504 - seteab(temp); 60.2505 - cycles-=((mod==3)?4:14); 60.2506 - break; 60.2507 - case 0xC7: /*MOV w,#16*/ 60.2508 - fetchea(); 60.2509 - tempw=getword(); 60.2510 - seteaw(tempw); 60.2511 - cycles-=((mod==3)?4:14); 60.2512 - break; 60.2513 - 60.2514 - case 0xCA: /*RETF*/ 60.2515 - tempw=getword(); 60.2516 - if (ssegs) ss=oldss; 60.2517 - pc=readmemw(ss,SP); 60.2518 -// printf("CA\n"); 60.2519 - loadcs(readmemw(ss,SP+2)); 60.2520 - SP+=4; 60.2521 - SP+=tempw; 60.2522 - cycles-=33; 60.2523 - FETCHCLEAR(); 60.2524 - break; 60.2525 - case 0xCB: /*RETF*/ 60.2526 - if (ssegs) ss=oldss; 60.2527 - pc=readmemw(ss,SP); 60.2528 -// printf("CB\n"); 60.2529 - loadcs(readmemw(ss,SP+2)); 60.2530 - SP+=4; 60.2531 - cycles-=34; 60.2532 - FETCHCLEAR(); 60.2533 - break; 60.2534 - case 0xCC: /*INT 3*/ 60.2535 - if (ssegs) ss=oldss; 60.2536 - writememw(ss,((SP-2)&0xFFFF),flags|0xF000); 60.2537 - writememw(ss,((SP-4)&0xFFFF),CS); 60.2538 - writememw(ss,((SP-6)&0xFFFF),pc); 60.2539 - SP-=6; 60.2540 - addr=3<<2; 60.2541 - flags&=~I_FLAG; 60.2542 - flags&=~T_FLAG; 60.2543 -// printf("CC %04X:%04X ",CS,pc); 60.2544 - pc=readmemw(0,addr); 60.2545 - loadcs(readmemw(0,addr+2)); 60.2546 - FETCHCLEAR(); 60.2547 -// printf("%04X:%04X\n",CS,pc); 60.2548 - cycles-=72; 60.2549 - break; 60.2550 - case 0xCD: /*INT*/ 60.2551 - lastpc=pc; 60.2552 - lastcs=CS; 60.2553 - temp=FETCH(); 60.2554 - 60.2555 -// if (temp == 0x13 && AX == 0x0201 && ES == 0x0BF5 && CX == 0x1D06) output = 3; 60.2556 -// if (temp==0x10 && !AH) printf("Entering mode %02X\n",AL); 60.2557 -// if (temp==0x18 || temp==0x19) { printf("INT %02X\n",temp); output=1; } 60.2558 -// /*if (temp==0x13) */printf("INT %02X %04X %04X:%04X %04X %04X:%04X %04X:%04X\n",temp,AX,ES,BX,CX,DS,DX,CS,pc); 60.2559 - //if (temp == 0x13 && AH == 2) output = 3; 60.2560 -/* if (CS==0xC800 && temp==0x13) 60.2561 - { 60.2562 - output=3; 60.2563 - timetolive=100000; 60.2564 - }*/ 60.2565 -/* if (temp==0x10) printf("INT 10 %04X %04X %04X %04X %04X:%04X %06X %06X %c\n",AX,BX,CX,DX,cs>>4,pc,ds,ds+DX, (AL > 31) ? AL : '.'); 60.2566 - if (temp == 0x10 && AX == 0xe35) 60.2567 - { 60.2568 - dumpregs(); 60.2569 - 60.2570 - }*/ 60.2571 -/* if (temp==0x21 && AH==9) 60.2572 - { 60.2573 - addr=0; 60.2574 - while (ram[ds+DX+addr]!='$') 60.2575 - { 60.2576 - printf("%c",ram[ds+DX+addr]); 60.2577 - addr++; 60.2578 - } 60.2579 - printf("\n"); 60.2580 - printf("Called from %04X\n",readmemw(ss,SP)); 60.2581 - }*/ 60.2582 -// output=0; 60.2583 -// if (temp==0x13 && AH==3) printf("Write sector %04X:%04X %05X\n",es>>4,BX,es+BX); 60.2584 -/* if (temp==0x13 && (DL==0x80 || DL==0x81) && AH>0) 60.2585 - { 60.2586 - int13hdc(); 60.2587 - } 60.2588 - else *//*if (temp==0x13 && AH==2 && DL<2)// && FASTDISC) 60.2589 - { 60.2590 - int13read(); 60.2591 - //output=1; 60.2592 - } 60.2593 - else if (temp==0x13 && AH==3 && DL<2)// && FASTDISC) 60.2594 - { 60.2595 - int13write(); 60.2596 - } 60.2597 - else if (temp==0x13 && AH==4 && DL<2)// && FASTDISC) 60.2598 - { 60.2599 - AH=0; 60.2600 - flags&=~C_FLAG; 60.2601 - } 60.2602 - else 60.2603 - {*/ 60.2604 - if (ssegs) ss=oldss; 60.2605 - writememw(ss,((SP-2)&0xFFFF),flags|0xF000); 60.2606 - writememw(ss,((SP-4)&0xFFFF),CS); 60.2607 - writememw(ss,((SP-6)&0xFFFF),pc); 60.2608 - flags&=~T_FLAG; 60.2609 - SP-=6; 60.2610 - addr=temp<<2; 60.2611 - pc=readmemw(0,addr); 60.2612 -// printf("CD\n"); 60.2613 - loadcs(readmemw(0,addr+2)); 60.2614 - FETCHCLEAR(); 60.2615 -// } 60.2616 - cycles-=71; 60.2617 - break; 60.2618 - case 0xCF: /*IRET*/ 60.2619 - if (ssegs) ss=oldss; 60.2620 - tempw=CS; 60.2621 - tempw2=pc; 60.2622 - inint=0; 60.2623 - pc=readmemw(ss,SP); 60.2624 -// printf("CF\n"); 60.2625 - loadcs(readmemw(ss,((SP+2)&0xFFFF))); 60.2626 - flags=readmemw(ss,((SP+4)&0xFFFF))&0xFFF; 60.2627 - SP+=6; 60.2628 - cycles-=44; 60.2629 - FETCHCLEAR(); 60.2630 - break; 60.2631 - case 0xD0: 60.2632 - fetchea(); 60.2633 - temp=geteab(); 60.2634 - switch (rmdat&0x38) 60.2635 - { 60.2636 - case 0x00: /*ROL b,1*/ 60.2637 - if (temp&0x80) flags|=C_FLAG; 60.2638 - else flags&=~C_FLAG; 60.2639 - temp<<=1; 60.2640 - if (flags&C_FLAG) temp|=1; 60.2641 - seteab(temp); 60.2642 -// setznp8(temp); 60.2643 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 60.2644 - else flags&=~V_FLAG; 60.2645 - cycles-=((mod==3)?2:23); 60.2646 - break; 60.2647 - case 0x08: /*ROR b,1*/ 60.2648 - if (temp&1) flags|=C_FLAG; 60.2649 - else flags&=~C_FLAG; 60.2650 - temp>>=1; 60.2651 - if (flags&C_FLAG) temp|=0x80; 60.2652 - seteab(temp); 60.2653 -// setznp8(temp); 60.2654 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 60.2655 - else flags&=~V_FLAG; 60.2656 - cycles-=((mod==3)?2:23); 60.2657 - break; 60.2658 - case 0x10: /*RCL b,1*/ 60.2659 - temp2=flags&C_FLAG; 60.2660 - if (temp&0x80) flags|=C_FLAG; 60.2661 - else flags&=~C_FLAG; 60.2662 - temp<<=1; 60.2663 - if (temp2) temp|=1; 60.2664 - seteab(temp); 60.2665 -// setznp8(temp); 60.2666 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 60.2667 - else flags&=~V_FLAG; 60.2668 - cycles-=((mod==3)?2:23); 60.2669 - break; 60.2670 - case 0x18: /*RCR b,1*/ 60.2671 - temp2=flags&C_FLAG; 60.2672 - if (temp&1) flags|=C_FLAG; 60.2673 - else flags&=~C_FLAG; 60.2674 - temp>>=1; 60.2675 - if (temp2) temp|=0x80; 60.2676 - seteab(temp); 60.2677 -// setznp8(temp); 60.2678 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 60.2679 - else flags&=~V_FLAG; 60.2680 - cycles-=((mod==3)?2:23); 60.2681 - break; 60.2682 - case 0x20: case 0x30: /*SHL b,1*/ 60.2683 - if (temp&0x80) flags|=C_FLAG; 60.2684 - else flags&=~C_FLAG; 60.2685 - if ((temp^(temp<<1))&0x80) flags|=V_FLAG; 60.2686 - else flags&=~V_FLAG; 60.2687 - temp<<=1; 60.2688 - seteab(temp); 60.2689 - setznp8(temp); 60.2690 - cycles-=((mod==3)?2:23); 60.2691 - flags|=A_FLAG; 60.2692 - break; 60.2693 - case 0x28: /*SHR b,1*/ 60.2694 - if (temp&1) flags|=C_FLAG; 60.2695 - else flags&=~C_FLAG; 60.2696 - if (temp&0x80) flags|=V_FLAG; 60.2697 - else flags&=~V_FLAG; 60.2698 - temp>>=1; 60.2699 - seteab(temp); 60.2700 - setznp8(temp); 60.2701 - cycles-=((mod==3)?2:23); 60.2702 - flags|=A_FLAG; 60.2703 - break; 60.2704 - case 0x38: /*SAR b,1*/ 60.2705 - if (temp&1) flags|=C_FLAG; 60.2706 - else flags&=~C_FLAG; 60.2707 - temp>>=1; 60.2708 - if (temp&0x40) temp|=0x80; 60.2709 - seteab(temp); 60.2710 - setznp8(temp); 60.2711 - cycles-=((mod==3)?2:23); 60.2712 - flags|=A_FLAG; 60.2713 - flags&=~V_FLAG; 60.2714 - break; 60.2715 - 60.2716 -// default: 60.2717 -// printf("Bad D0 opcode %02X\n",rmdat&0x38); 60.2718 -// dumpregs(); 60.2719 -// exit(-1); 60.2720 - } 60.2721 - break; 60.2722 - 60.2723 - case 0xD1: 60.2724 - fetchea(); 60.2725 - tempw=geteaw(); 60.2726 - switch (rmdat&0x38) 60.2727 - { 60.2728 - case 0x00: /*ROL w,1*/ 60.2729 - if (tempw&0x8000) flags|=C_FLAG; 60.2730 - else flags&=~C_FLAG; 60.2731 - tempw<<=1; 60.2732 - if (flags&C_FLAG) tempw|=1; 60.2733 - seteaw(tempw); 60.2734 -// setznp16(tempw); 60.2735 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 60.2736 - else flags&=~V_FLAG; 60.2737 - cycles-=((mod==3)?2:23); 60.2738 - break; 60.2739 - case 0x08: /*ROR w,1*/ 60.2740 - if (tempw&1) flags|=C_FLAG; 60.2741 - else flags&=~C_FLAG; 60.2742 - tempw>>=1; 60.2743 - if (flags&C_FLAG) tempw|=0x8000; 60.2744 - seteaw(tempw); 60.2745 -// setznp16(tempw); 60.2746 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 60.2747 - else flags&=~V_FLAG; 60.2748 - cycles-=((mod==3)?2:23); 60.2749 - break; 60.2750 - case 0x10: /*RCL w,1*/ 60.2751 - temp2=flags&C_FLAG; 60.2752 - if (tempw&0x8000) flags|=C_FLAG; 60.2753 - else flags&=~C_FLAG; 60.2754 - tempw<<=1; 60.2755 - if (temp2) tempw|=1; 60.2756 - seteaw(tempw); 60.2757 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 60.2758 - else flags&=~V_FLAG; 60.2759 - cycles-=((mod==3)?2:23); 60.2760 - break; 60.2761 - case 0x18: /*RCR w,1*/ 60.2762 - temp2=flags&C_FLAG; 60.2763 - if (tempw&1) flags|=C_FLAG; 60.2764 - else flags&=~C_FLAG; 60.2765 - tempw>>=1; 60.2766 - if (temp2) tempw|=0x8000; 60.2767 - seteaw(tempw); 60.2768 -// setznp16(tempw); 60.2769 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 60.2770 - else flags&=~V_FLAG; 60.2771 - cycles-=((mod==3)?2:23); 60.2772 - break; 60.2773 - case 0x20: case 0x30: /*SHL w,1*/ 60.2774 - if (tempw&0x8000) flags|=C_FLAG; 60.2775 - else flags&=~C_FLAG; 60.2776 - if ((tempw^(tempw<<1))&0x8000) flags|=V_FLAG; 60.2777 - else flags&=~V_FLAG; 60.2778 - tempw<<=1; 60.2779 - seteaw(tempw); 60.2780 - setznp16(tempw); 60.2781 - cycles-=((mod==3)?2:23); 60.2782 - flags|=A_FLAG; 60.2783 - break; 60.2784 - case 0x28: /*SHR w,1*/ 60.2785 - if (tempw&1) flags|=C_FLAG; 60.2786 - else flags&=~C_FLAG; 60.2787 - if (tempw&0x8000) flags|=V_FLAG; 60.2788 - else flags&=~V_FLAG; 60.2789 - tempw>>=1; 60.2790 - seteaw(tempw); 60.2791 - setznp16(tempw); 60.2792 - cycles-=((mod==3)?2:23); 60.2793 - flags|=A_FLAG; 60.2794 - break; 60.2795 - 60.2796 - case 0x38: /*SAR w,1*/ 60.2797 - if (tempw&1) flags|=C_FLAG; 60.2798 - else flags&=~C_FLAG; 60.2799 - tempw>>=1; 60.2800 - if (tempw&0x4000) tempw|=0x8000; 60.2801 - seteaw(tempw); 60.2802 - setznp16(tempw); 60.2803 - cycles-=((mod==3)?2:23); 60.2804 - flags|=A_FLAG; 60.2805 - flags&=~V_FLAG; 60.2806 - break; 60.2807 - 60.2808 -// default: 60.2809 -// printf("Bad D1 opcode %02X\n",rmdat&0x38); 60.2810 -// dumpregs(); 60.2811 -// exit(-1); 60.2812 - } 60.2813 - break; 60.2814 - 60.2815 - case 0xD2: 60.2816 - fetchea(); 60.2817 - temp=geteab(); 60.2818 - c=CL; 60.2819 -// cycles-=c; 60.2820 - if (!c) break; 60.2821 -// if (c>7) printf("Shiftb %i %02X\n",rmdat&0x38,c); 60.2822 - switch (rmdat&0x38) 60.2823 - { 60.2824 - case 0x00: /*ROL b,CL*/ 60.2825 - while (c>0) 60.2826 - { 60.2827 - temp2=(temp&0x80)?1:0; 60.2828 - temp=(temp<<1)|temp2; 60.2829 - c--; 60.2830 - cycles-=4; 60.2831 - } 60.2832 - if (temp2) flags|=C_FLAG; 60.2833 - else flags&=~C_FLAG; 60.2834 - seteab(temp); 60.2835 -// setznp8(temp); 60.2836 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 60.2837 - else flags&=~V_FLAG; 60.2838 - cycles-=((mod==3)?8:28); 60.2839 - break; 60.2840 - case 0x08: /*ROR b,CL*/ 60.2841 - while (c>0) 60.2842 - { 60.2843 - temp2=temp&1; 60.2844 - temp>>=1; 60.2845 - if (temp2) temp|=0x80; 60.2846 - c--; 60.2847 - cycles-=4; 60.2848 - } 60.2849 - if (temp2) flags|=C_FLAG; 60.2850 - else flags&=~C_FLAG; 60.2851 - seteab(temp); 60.2852 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 60.2853 - else flags&=~V_FLAG; 60.2854 - cycles-=((mod==3)?8:28); 60.2855 - break; 60.2856 - case 0x10: /*RCL b,CL*/ 60.2857 -// printf("RCL %i %02X %02X\n",c,CL,temp); 60.2858 - while (c>0) 60.2859 - { 60.2860 - templ=flags&C_FLAG; 60.2861 - temp2=temp&0x80; 60.2862 - temp<<=1; 60.2863 - if (temp2) flags|=C_FLAG; 60.2864 - else flags&=~C_FLAG; 60.2865 - if (templ) temp|=1; 60.2866 - c--; 60.2867 - cycles-=4; 60.2868 - } 60.2869 -// printf("Now %02X\n",temp); 60.2870 - seteab(temp); 60.2871 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 60.2872 - else flags&=~V_FLAG; 60.2873 - cycles-=((mod==3)?8:28); 60.2874 - break; 60.2875 - case 0x18: /*RCR b,CL*/ 60.2876 - while (c>0) 60.2877 - { 60.2878 - templ=flags&C_FLAG; 60.2879 - temp2=temp&1; 60.2880 - temp>>=1; 60.2881 - if (temp2) flags|=C_FLAG; 60.2882 - else flags&=~C_FLAG; 60.2883 - if (templ) temp|=0x80; 60.2884 - c--; 60.2885 - cycles-=4; 60.2886 - } 60.2887 -// if (temp2) flags|=C_FLAG; 60.2888 -// else flags&=~C_FLAG; 60.2889 - seteab(temp); 60.2890 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 60.2891 - else flags&=~V_FLAG; 60.2892 - cycles-=((mod==3)?8:28); 60.2893 - break; 60.2894 - case 0x20: case 0x30: /*SHL b,CL*/ 60.2895 - if ((temp<<(c-1))&0x80) flags|=C_FLAG; 60.2896 - else flags&=~C_FLAG; 60.2897 - temp<<=c; 60.2898 - seteab(temp); 60.2899 - setznp8(temp); 60.2900 - cycles-=(c*4); 60.2901 - cycles-=((mod==3)?8:28); 60.2902 - flags|=A_FLAG; 60.2903 - break; 60.2904 - case 0x28: /*SHR b,CL*/ 60.2905 - if ((temp>>(c-1))&1) flags|=C_FLAG; 60.2906 - else flags&=~C_FLAG; 60.2907 - temp>>=c; 60.2908 - seteab(temp); 60.2909 - setznp8(temp); 60.2910 - cycles-=(c*4); 60.2911 - cycles-=((mod==3)?8:28); 60.2912 - flags|=A_FLAG; 60.2913 - break; 60.2914 - case 0x38: /*SAR b,CL*/ 60.2915 - if ((temp>>(c-1))&1) flags|=C_FLAG; 60.2916 - else flags&=~C_FLAG; 60.2917 - while (c>0) 60.2918 - { 60.2919 - temp>>=1; 60.2920 - if (temp&0x40) temp|=0x80; 60.2921 - c--; 60.2922 - cycles-=4; 60.2923 - } 60.2924 - seteab(temp); 60.2925 - setznp8(temp); 60.2926 - cycles-=((mod==3)?8:28); 60.2927 - flags|=A_FLAG; 60.2928 - break; 60.2929 - 60.2930 -// default: 60.2931 -// printf("Bad D2 opcode %02X\n",rmdat&0x38); 60.2932 -// dumpregs(); 60.2933 -// exit(-1); 60.2934 - } 60.2935 - break; 60.2936 - 60.2937 - case 0xD3: 60.2938 - fetchea(); 60.2939 - tempw=geteaw(); 60.2940 - c=CL; 60.2941 -// cycles-=c; 60.2942 - if (!c) break; 60.2943 -// if (c>15) printf("Shiftw %i %02X\n",rmdat&0x38,c); 60.2944 - switch (rmdat&0x38) 60.2945 - { 60.2946 - case 0x00: /*ROL w,CL*/ 60.2947 - while (c>0) 60.2948 - { 60.2949 - temp=(tempw&0x8000)?1:0; 60.2950 - tempw=(tempw<<1)|temp; 60.2951 - c--; 60.2952 - cycles-=4; 60.2953 - } 60.2954 - if (temp) flags|=C_FLAG; 60.2955 - else flags&=~C_FLAG; 60.2956 - seteaw(tempw); 60.2957 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 60.2958 - else flags&=~V_FLAG; 60.2959 - cycles-=((mod==3)?8:28); 60.2960 - break; 60.2961 - case 0x08: /*ROR w,CL*/ 60.2962 - while (c>0) 60.2963 - { 60.2964 - tempw2=(tempw&1)?0x8000:0; 60.2965 - tempw=(tempw>>1)|tempw2; 60.2966 - c--; 60.2967 - cycles-=4; 60.2968 - } 60.2969 - if (tempw2) flags|=C_FLAG; 60.2970 - else flags&=~C_FLAG; 60.2971 - seteaw(tempw); 60.2972 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 60.2973 - else flags&=~V_FLAG; 60.2974 - cycles-=((mod==3)?8:28); 60.2975 - break; 60.2976 - case 0x10: /*RCL w,CL*/ 60.2977 - while (c>0) 60.2978 - { 60.2979 - templ=flags&C_FLAG; 60.2980 - if (tempw&0x8000) flags|=C_FLAG; 60.2981 - else flags&=~C_FLAG; 60.2982 - tempw=(tempw<<1)|templ; 60.2983 - c--; 60.2984 - cycles-=4; 60.2985 - } 60.2986 - if (temp) flags|=C_FLAG; 60.2987 - else flags&=~C_FLAG; 60.2988 - seteaw(tempw); 60.2989 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 60.2990 - else flags&=~V_FLAG; 60.2991 - cycles-=((mod==3)?8:28); 60.2992 - break; 60.2993 - case 0x18: /*RCR w,CL*/ 60.2994 - while (c>0) 60.2995 - { 60.2996 - templ=flags&C_FLAG; 60.2997 - tempw2=(templ&1)?0x8000:0; 60.2998 - if (tempw&1) flags|=C_FLAG; 60.2999 - else flags&=~C_FLAG; 60.3000 - tempw=(tempw>>1)|tempw2; 60.3001 - c--; 60.3002 - cycles-=4; 60.3003 - } 60.3004 - if (tempw2) flags|=C_FLAG; 60.3005 - else flags&=~C_FLAG; 60.3006 - seteaw(tempw); 60.3007 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 60.3008 - else flags&=~V_FLAG; 60.3009 - cycles-=((mod==3)?8:28); 60.3010 - break; 60.3011 - 60.3012 - case 0x20: case 0x30: /*SHL w,CL*/ 60.3013 - if (c>16) 60.3014 - { 60.3015 - tempw=0; 60.3016 - flags&=~C_FLAG; 60.3017 - } 60.3018 - else 60.3019 - { 60.3020 - if ((tempw<<(c-1))&0x8000) flags|=C_FLAG; 60.3021 - else flags&=~C_FLAG; 60.3022 - tempw<<=c; 60.3023 - } 60.3024 - seteaw(tempw); 60.3025 - setznp16(tempw); 60.3026 - cycles-=(c*4); 60.3027 - cycles-=((mod==3)?8:28); 60.3028 - flags|=A_FLAG; 60.3029 - break; 60.3030 - 60.3031 - case 0x28: /*SHR w,CL*/ 60.3032 - if ((tempw>>(c-1))&1) flags|=C_FLAG; 60.3033 - else flags&=~C_FLAG; 60.3034 - tempw>>=c; 60.3035 - seteaw(tempw); 60.3036 - setznp16(tempw); 60.3037 - cycles-=(c*4); 60.3038 - cycles-=((mod==3)?8:28); 60.3039 - flags|=A_FLAG; 60.3040 - break; 60.3041 - 60.3042 - case 0x38: /*SAR w,CL*/ 60.3043 - tempw2=tempw&0x8000; 60.3044 - if ((tempw>>(c-1))&1) flags|=C_FLAG; 60.3045 - else flags&=~C_FLAG; 60.3046 - while (c>0) 60.3047 - { 60.3048 - tempw=(tempw>>1)|tempw2; 60.3049 - c--; 60.3050 - cycles-=4; 60.3051 - } 60.3052 - seteaw(tempw); 60.3053 - setznp16(tempw); 60.3054 - cycles-=((mod==3)?8:28); 60.3055 - flags|=A_FLAG; 60.3056 - break; 60.3057 - 60.3058 -// default: 60.3059 -// printf("Bad D3 opcode %02X\n",rmdat&0x38); 60.3060 -// dumpregs(); 60.3061 -// exit(-1); 60.3062 - } 60.3063 - break; 60.3064 - 60.3065 - case 0xD4: /*AAM*/ 60.3066 - tempws=FETCH(); 60.3067 - AH=AL/tempws; 60.3068 - AL%=tempws; 60.3069 - setznp168(AX); 60.3070 - cycles-=83; 60.3071 - break; 60.3072 - case 0xD5: /*AAD*/ 60.3073 - tempws=FETCH(); 60.3074 - AL=(AH*tempws)+AL; 60.3075 - AH=0; 60.3076 - setznp168(AX); 60.3077 - cycles-=60; 60.3078 - break; 60.3079 - case 0xD7: /*XLAT*/ 60.3080 - addr=BX+AL; 60.3081 - AL=readmemb(ds+addr); 60.3082 - cycles-=11; 60.3083 - break; 60.3084 - case 0xD9: case 0xDA: case 0xDB: case 0xDD: /*ESCAPE*/ 60.3085 - case 0xDC: case 0xDE: case 0xDF: case 0xD8: 60.3086 - fetchea(); 60.3087 - geteab(); 60.3088 - break; 60.3089 - 60.3090 - case 0xE0: /*LOOPNE*/ 60.3091 - offset=(int8_t)FETCH(); 60.3092 - CX--; 60.3093 - if (CX && !(flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.3094 - cycles-=6; 60.3095 - break; 60.3096 - case 0xE1: /*LOOPE*/ 60.3097 - offset=(int8_t)FETCH(); 60.3098 - CX--; 60.3099 - if (CX && (flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.3100 - cycles-=6; 60.3101 - break; 60.3102 - case 0xE2: /*LOOP*/ 60.3103 -// printf("LOOP start\n"); 60.3104 - offset=(int8_t)FETCH(); 60.3105 - CX--; 60.3106 - if (CX) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.3107 - cycles-=5; 60.3108 -// printf("LOOP end!\n"); 60.3109 - break; 60.3110 - case 0xE3: /*JCXZ*/ 60.3111 - offset=(int8_t)FETCH(); 60.3112 - if (!CX) { pc+=offset; cycles-=12; FETCHCLEAR(); } 60.3113 - cycles-=6; 60.3114 - break; 60.3115 - 60.3116 - case 0xE4: /*IN AL*/ 60.3117 - temp=FETCH(); 60.3118 - AL=inb(temp); 60.3119 - cycles-=14; 60.3120 - break; 60.3121 - case 0xE5: /*IN AX*/ 60.3122 - temp=FETCH(); 60.3123 - AL=inb(temp); 60.3124 - AH=inb(temp+1); 60.3125 - cycles-=14; 60.3126 - break; 60.3127 - case 0xE6: /*OUT AL*/ 60.3128 - temp=FETCH(); 60.3129 - outb(temp,AL); 60.3130 - cycles-=14; 60.3131 - break; 60.3132 - case 0xE7: /*OUT AX*/ 60.3133 - temp=FETCH(); 60.3134 - outb(temp,AL); 60.3135 - outb(temp+1,AH); 60.3136 - cycles-=14; 60.3137 - break; 60.3138 - 60.3139 - case 0xE8: /*CALL rel 16*/ 60.3140 - tempw=getword(); 60.3141 - if (ssegs) ss=oldss; 60.3142 -// writememb(ss+((SP-1)&0xFFFF),pc>>8); 60.3143 - writememw(ss,((SP-2)&0xFFFF),pc); 60.3144 - SP-=2; 60.3145 - pc+=tempw; 60.3146 - cycles-=23; 60.3147 - FETCHCLEAR(); 60.3148 - break; 60.3149 - case 0xE9: /*JMP rel 16*/ 60.3150 -// printf("PC was %04X\n",pc); 60.3151 - pc+=getword(); 60.3152 -// printf("PC now %04X\n",pc); 60.3153 - cycles-=15; 60.3154 - FETCHCLEAR(); 60.3155 - break; 60.3156 - case 0xEA: /*JMP far*/ 60.3157 - addr=getword(); 60.3158 - tempw=getword(); 60.3159 - pc=addr; 60.3160 -// printf("EA\n"); 60.3161 - loadcs(tempw); 60.3162 -// cs=loadcs(CS); 60.3163 -// cs=CS<<4; 60.3164 - cycles-=15; 60.3165 - FETCHCLEAR(); 60.3166 - break; 60.3167 - case 0xEB: /*JMP rel*/ 60.3168 - offset=(int8_t)FETCH(); 60.3169 - pc+=offset; 60.3170 - cycles-=15; 60.3171 - FETCHCLEAR(); 60.3172 - break; 60.3173 - case 0xEC: /*IN AL,DX*/ 60.3174 - AL=inb(DX); 60.3175 - cycles-=12; 60.3176 - break; 60.3177 - case 0xED: /*IN AX,DX*/ 60.3178 - AL=inb(DX); 60.3179 - AH=inb(DX+1); 60.3180 - cycles-=12; 60.3181 - break; 60.3182 - case 0xEE: /*OUT DX,AL*/ 60.3183 - outb(DX,AL); 60.3184 - cycles-=12; 60.3185 - break; 60.3186 - case 0xEF: /*OUT DX,AX*/ 60.3187 - outb(DX,AL); 60.3188 - outb(DX+1,AH); 60.3189 - cycles-=12; 60.3190 - break; 60.3191 - 60.3192 - case 0xF0: /*LOCK*/ 60.3193 - cycles-=4; 60.3194 - break; 60.3195 - 60.3196 - case 0xF2: /*REPNE*/ 60.3197 - rep(0); 60.3198 - break; 60.3199 - case 0xF3: /*REPE*/ 60.3200 - rep(1); 60.3201 - break; 60.3202 - 60.3203 - case 0xF4: /*HLT*/ 60.3204 -// printf("IN HLT!!!! %04X:%04X %08X %08X %08X\n",oldcs,oldpc,old8,old82,old83); 60.3205 -/* if (!(flags & I_FLAG)) 60.3206 - { 60.3207 - pclog("HLT\n"); 60.3208 - dumpregs(); 60.3209 - exit(-1); 60.3210 - }*/ 60.3211 - inhlt=1; 60.3212 - pc--; 60.3213 - FETCHCLEAR(); 60.3214 - cycles-=2; 60.3215 - break; 60.3216 - case 0xF5: /*CMC*/ 60.3217 - flags^=C_FLAG; 60.3218 - cycles-=2; 60.3219 - break; 60.3220 - 60.3221 - case 0xF6: 60.3222 - fetchea(); 60.3223 - temp=geteab(); 60.3224 - switch (rmdat&0x38) 60.3225 - { 60.3226 - case 0x00: /*TEST b,#8*/ 60.3227 - temp2=FETCH(); 60.3228 - temp&=temp2; 60.3229 - setznp8(temp); 60.3230 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.3231 - cycles-=((mod==3)?5:11); 60.3232 - break; 60.3233 - case 0x10: /*NOT b*/ 60.3234 - temp=~temp; 60.3235 - seteab(temp); 60.3236 - cycles-=((mod==3)?3:24); 60.3237 - break; 60.3238 - case 0x18: /*NEG b*/ 60.3239 - setsub8(0,temp); 60.3240 - temp=0-temp; 60.3241 - seteab(temp); 60.3242 - cycles-=((mod==3)?3:24); 60.3243 - break; 60.3244 - case 0x20: /*MUL AL,b*/ 60.3245 - setznp8(AL); 60.3246 - AX=AL*temp; 60.3247 - if (AX) flags&=~Z_FLAG; 60.3248 - else flags|=Z_FLAG; 60.3249 - if (AH) flags|=(C_FLAG|V_FLAG); 60.3250 - else flags&=~(C_FLAG|V_FLAG); 60.3251 - cycles-=70; 60.3252 - break; 60.3253 - case 0x28: /*IMUL AL,b*/ 60.3254 - setznp8(AL); 60.3255 - tempws=(int)((int8_t)AL)*(int)((int8_t)temp); 60.3256 - AX=tempws&0xFFFF; 60.3257 - if (AX) flags&=~Z_FLAG; 60.3258 - else flags|=Z_FLAG; 60.3259 - if (AH) flags|=(C_FLAG|V_FLAG); 60.3260 - else flags&=~(C_FLAG|V_FLAG); 60.3261 - cycles-=80; 60.3262 - break; 60.3263 - case 0x30: /*DIV AL,b*/ 60.3264 - tempw=AX; 60.3265 - if (temp) 60.3266 - { 60.3267 - tempw2=tempw%temp; 60.3268 -/* if (!tempw) 60.3269 - { 60.3270 - writememw((ss+SP)-2,flags|0xF000); 60.3271 - writememw((ss+SP)-4,cs>>4); 60.3272 - writememw((ss+SP)-6,pc); 60.3273 - SP-=6; 60.3274 - flags&=~I_FLAG; 60.3275 - pc=readmemw(0); 60.3276 - cs=readmemw(2)<<4; 60.3277 - printf("Div by zero %04X:%04X\n",cs>>4,pc); 60.3278 -// dumpregs(); 60.3279 -// exit(-1); 60.3280 - } 60.3281 - else 60.3282 - {*/ 60.3283 - AH=tempw2; 60.3284 - tempw/=temp; 60.3285 - AL=tempw&0xFF; 60.3286 -// } 60.3287 - } 60.3288 - else 60.3289 - { 60.3290 - printf("DIVb BY 0 %04X:%04X\n",cs>>4,pc); 60.3291 - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 60.3292 - writememw(ss,(SP-4)&0xFFFF,CS); 60.3293 - writememw(ss,(SP-6)&0xFFFF,pc); 60.3294 - SP-=6; 60.3295 - flags&=~I_FLAG; 60.3296 - flags&=~T_FLAG; 60.3297 - pc=readmemw(0,0); 60.3298 -// printf("F6 30\n"); 60.3299 - loadcs(readmemw(0,2)); 60.3300 - FETCHCLEAR(); 60.3301 -// cs=loadcs(CS); 60.3302 -// cs=CS<<4; 60.3303 -// printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x30); 60.3304 -// dumpregs(); 60.3305 -// exit(-1); 60.3306 - } 60.3307 - cycles-=80; 60.3308 - break; 60.3309 - case 0x38: /*IDIV AL,b*/ 60.3310 - tempws=(int)AX; 60.3311 - if (temp) 60.3312 - { 60.3313 - tempw2=tempws%(int)((int8_t)temp); 60.3314 -/* if (!tempw) 60.3315 - { 60.3316 - writememw((ss+SP)-2,flags|0xF000); 60.3317 - writememw((ss+SP)-4,cs>>4); 60.3318 - writememw((ss+SP)-6,pc); 60.3319 - SP-=6; 60.3320 - flags&=~I_FLAG; 60.3321 - pc=readmemw(0); 60.3322 - cs=readmemw(2)<<4; 60.3323 - printf("Div by zero %04X:%04X\n",cs>>4,pc); 60.3324 - } 60.3325 - else 60.3326 - {*/ 60.3327 - AH=tempw2&0xFF; 60.3328 - tempws/=(int)((int8_t)temp); 60.3329 - AL=tempws&0xFF; 60.3330 -// } 60.3331 - } 60.3332 - else 60.3333 - { 60.3334 - printf("IDIVb BY 0 %04X:%04X\n",cs>>4,pc); 60.3335 - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 60.3336 - writememw(ss,(SP-4)&0xFFFF,CS); 60.3337 - writememw(ss,(SP-6)&0xFFFF,pc); 60.3338 - SP-=6; 60.3339 - flags&=~I_FLAG; 60.3340 - flags&=~T_FLAG; 60.3341 - pc=readmemw(0,0); 60.3342 -// printf("F6 38\n"); 60.3343 - loadcs(readmemw(0,2)); 60.3344 - FETCHCLEAR(); 60.3345 -// cs=loadcs(CS); 60.3346 -// cs=CS<<4; 60.3347 -// printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x38); 60.3348 - } 60.3349 - cycles-=101; 60.3350 - break; 60.3351 - 60.3352 -// default: 60.3353 -// printf("Bad F6 opcode %02X\n",rmdat&0x38); 60.3354 -// dumpregs(); 60.3355 -// exit(-1); 60.3356 - } 60.3357 - break; 60.3358 - 60.3359 - case 0xF7: 60.3360 - fetchea(); 60.3361 - tempw=geteaw(); 60.3362 - switch (rmdat&0x38) 60.3363 - { 60.3364 - case 0x00: /*TEST w*/ 60.3365 - tempw2=getword(); 60.3366 - setznp16(tempw&tempw2); 60.3367 - flags&=~(C_FLAG|V_FLAG|A_FLAG); 60.3368 - cycles-=((mod==3)?5:11); 60.3369 - break; 60.3370 - case 0x10: /*NOT w*/ 60.3371 - seteaw(~tempw); 60.3372 - cycles-=((mod==3)?3:24); 60.3373 - break; 60.3374 - case 0x18: /*NEG w*/ 60.3375 - setsub16(0,tempw); 60.3376 - tempw=0-tempw; 60.3377 - seteaw(tempw); 60.3378 - cycles-=((mod==3)?3:24); 60.3379 - break; 60.3380 - case 0x20: /*MUL AX,w*/ 60.3381 - setznp16(AX); 60.3382 - templ=AX*tempw; 60.3383 -// if (output) printf("%04X*%04X=%08X\n",AX,tempw,templ); 60.3384 - AX=templ&0xFFFF; 60.3385 - DX=templ>>16; 60.3386 - if (AX|DX) flags&=~Z_FLAG; 60.3387 - else flags|=Z_FLAG; 60.3388 - if (DX) flags|=(C_FLAG|V_FLAG); 60.3389 - else flags&=~(C_FLAG|V_FLAG); 60.3390 - cycles-=118; 60.3391 - break; 60.3392 - case 0x28: /*IMUL AX,w*/ 60.3393 - setznp16(AX); 60.3394 -// printf("IMUL %i %i ",(int)((int16_t)AX),(int)((int16_t)tempw)); 60.3395 - tempws=(int)((int16_t)AX)*(int)((int16_t)tempw); 60.3396 - if ((tempws>>15) && ((tempws>>15)!=-1)) flags|=(C_FLAG|V_FLAG); 60.3397 - else flags&=~(C_FLAG|V_FLAG); 60.3398 -// printf("%i ",tempws); 60.3399 - AX=tempws&0xFFFF; 60.3400 - tempws=(uint16_t)(tempws>>16); 60.3401 - DX=tempws&0xFFFF; 60.3402 -// printf("%04X %04X\n",AX,DX); 60.3403 -// dumpregs(); 60.3404 -// exit(-1); 60.3405 - if (AX|DX) flags&=~Z_FLAG; 60.3406 - else flags|=Z_FLAG; 60.3407 - cycles-=128; 60.3408 - break; 60.3409 - case 0x30: /*DIV AX,w*/ 60.3410 - templ=(DX<<16)|AX; 60.3411 -// printf("DIV %08X/%04X\n",templ,tempw); 60.3412 - if (tempw) 60.3413 - { 60.3414 - tempw2=templ%tempw; 60.3415 - DX=tempw2; 60.3416 - templ/=tempw; 60.3417 - AX=templ&0xFFFF; 60.3418 - } 60.3419 - else 60.3420 - { 60.3421 - printf("DIVw BY 0 %04X:%04X\n",cs>>4,pc); 60.3422 - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 60.3423 - writememw(ss,(SP-4)&0xFFFF,CS); 60.3424 - writememw(ss,(SP-6)&0xFFFF,pc); 60.3425 - SP-=6; 60.3426 - flags&=~I_FLAG; 60.3427 - flags&=~T_FLAG; 60.3428 - pc=readmemw(0,0); 60.3429 -// printf("F7 30\n"); 60.3430 - loadcs(readmemw(0,2)); 60.3431 - FETCHCLEAR(); 60.3432 - } 60.3433 - cycles-=144; 60.3434 - break; 60.3435 - case 0x38: /*IDIV AX,w*/ 60.3436 - tempws=(int)((DX<<16)|AX); 60.3437 -// printf("IDIV %i %i ",tempws,tempw); 60.3438 - if (tempw) 60.3439 - { 60.3440 - tempw2=tempws%(int)((int16_t)tempw); 60.3441 -// printf("%04X ",tempw2); 60.3442 - DX=tempw2; 60.3443 - tempws/=(int)((int16_t)tempw); 60.3444 - AX=tempws&0xFFFF; 60.3445 - } 60.3446 - else 60.3447 - { 60.3448 - printf("IDIVw BY 0 %04X:%04X\n",cs>>4,pc); 60.3449 - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 60.3450 - writememw(ss,(SP-4)&0xFFFF,CS); 60.3451 - writememw(ss,(SP-6)&0xFFFF,pc); 60.3452 - SP-=6; 60.3453 - flags&=~I_FLAG; 60.3454 - flags&=~T_FLAG; 60.3455 - pc=readmemw(0,0); 60.3456 -// printf("F7 38\n"); 60.3457 - loadcs(readmemw(0,2)); 60.3458 - FETCHCLEAR(); 60.3459 - } 60.3460 - cycles-=165; 60.3461 - break; 60.3462 - 60.3463 -// default: 60.3464 -// printf("Bad F7 opcode %02X\n",rmdat&0x38); 60.3465 -// dumpregs(); 60.3466 -// exit(-1); 60.3467 - } 60.3468 - break; 60.3469 - 60.3470 - case 0xF8: /*CLC*/ 60.3471 - flags&=~C_FLAG; 60.3472 - cycles-=2; 60.3473 - break; 60.3474 - case 0xF9: /*STC*/ 60.3475 -// printf("STC %04X\n",pc); 60.3476 - flags|=C_FLAG; 60.3477 - cycles-=2; 60.3478 - break; 60.3479 - case 0xFA: /*CLI*/ 60.3480 - flags&=~I_FLAG; 60.3481 -// printf("CLI at %04X:%04X\n",cs>>4,pc); 60.3482 - cycles-=3; 60.3483 - break; 60.3484 - case 0xFB: /*STI*/ 60.3485 - flags|=I_FLAG; 60.3486 -// printf("STI at %04X:%04X\n",cs>>4,pc); 60.3487 - cycles-=2; 60.3488 - break; 60.3489 - case 0xFC: /*CLD*/ 60.3490 - flags&=~D_FLAG; 60.3491 - cycles-=2; 60.3492 - break; 60.3493 - case 0xFD: /*STD*/ 60.3494 - flags|=D_FLAG; 60.3495 - cycles-=2; 60.3496 - break; 60.3497 - 60.3498 - case 0xFE: /*INC/DEC b*/ 60.3499 - fetchea(); 60.3500 - temp=geteab(); 60.3501 - flags&=~V_FLAG; 60.3502 - if (rmdat&0x38) 60.3503 - { 60.3504 - setsub8nc(temp,1); 60.3505 - temp2=temp-1; 60.3506 - if ((temp&0x80) && !(temp2&0x80)) flags|=V_FLAG; 60.3507 - } 60.3508 - else 60.3509 - { 60.3510 - setadd8nc(temp,1); 60.3511 - temp2=temp+1; 60.3512 - if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG; 60.3513 - } 60.3514 -// setznp8(temp2); 60.3515 - seteab(temp2); 60.3516 - cycles-=((mod==3)?3:23); 60.3517 - break; 60.3518 - 60.3519 - case 0xFF: 60.3520 - fetchea(); 60.3521 - switch (rmdat&0x38) 60.3522 - { 60.3523 - case 0x00: /*INC w*/ 60.3524 - tempw=geteaw(); 60.3525 - setadd16nc(tempw,1); 60.3526 -// setznp16(tempw+1); 60.3527 - seteaw(tempw+1); 60.3528 - cycles-=((mod==3)?3:23); 60.3529 - break; 60.3530 - case 0x08: /*DEC w*/ 60.3531 - tempw=geteaw(); 60.3532 -// setsub16(tempw,1); 60.3533 - setsub16nc(tempw,1); 60.3534 -// setznp16(tempw-1); 60.3535 - seteaw(tempw-1); 60.3536 -// if (output) printf("DEC - %04X\n",tempw); 60.3537 - cycles-=((mod==3)?3:23); 60.3538 - break; 60.3539 - case 0x10: /*CALL*/ 60.3540 - tempw=geteaw(); 60.3541 - if (ssegs) ss=oldss; 60.3542 - writememw(ss,(SP-2)&0xFFFF,pc); 60.3543 - SP-=2; 60.3544 - pc=tempw; 60.3545 -// printf("FF 10\n"); 60.3546 - cycles-=((mod==3)?20:29); 60.3547 - FETCHCLEAR(); 60.3548 - break; 60.3549 - case 0x18: /*CALL far*/ 60.3550 - tempw=readmemw(easeg,eaaddr); 60.3551 - tempw2=readmemw(easeg,(eaaddr+2)&0xFFFF); //geteaw2(); 60.3552 - tempw3=CS; 60.3553 - tempw4=pc; 60.3554 - if (ssegs) ss=oldss; 60.3555 - pc=tempw; 60.3556 -// printf("FF 18\n"); 60.3557 - loadcs(tempw2); 60.3558 - writememw(ss,(SP-2)&0xFFFF,tempw3); 60.3559 - writememw(ss,((SP-4)&0xFFFF),tempw4); 60.3560 - SP-=4; 60.3561 - cycles-=53; 60.3562 - FETCHCLEAR(); 60.3563 - break; 60.3564 - case 0x20: /*JMP*/ 60.3565 - pc=geteaw(); 60.3566 -// printf("FF 20\n"); 60.3567 - cycles-=((mod==3)?11:18); 60.3568 - FETCHCLEAR(); 60.3569 - break; 60.3570 - case 0x28: /*JMP far*/ 60.3571 - pc=readmemw(easeg,eaaddr); //geteaw(); 60.3572 -// printf("FF 28\n"); 60.3573 - loadcs(readmemw(easeg,(eaaddr+2)&0xFFFF)); //geteaw2(); 60.3574 -// cs=loadcs(CS); 60.3575 -// cs=CS<<4; 60.3576 - cycles-=24; 60.3577 - FETCHCLEAR(); 60.3578 - break; 60.3579 - case 0x30: /*PUSH w*/ 60.3580 - tempw=geteaw(); 60.3581 -// if (output) printf("PUSH %04X %i %02X %04X %04X %02X %02X\n",tempw,rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]); 60.3582 - if (ssegs) ss=oldss; 60.3583 - writememw(ss,((SP-2)&0xFFFF),tempw); 60.3584 - SP-=2; 60.3585 - cycles-=((mod==3)?15:24); 60.3586 - break; 60.3587 - 60.3588 -// default: 60.3589 -// printf("Bad FF opcode %02X\n",rmdat&0x38); 60.3590 -// dumpregs(); 60.3591 -// exit(-1); 60.3592 - } 60.3593 - break; 60.3594 - 60.3595 - default: 60.3596 - FETCH(); 60.3597 - cycles-=8; 60.3598 - break; 60.3599 - 60.3600 -/* printf("Bad opcode %02X at %04X:%04X from %04X:%04X %08X\n",opcode,cs>>4,pc,old8>>16,old8&0xFFFF,old82); 60.3601 - dumpregs(); 60.3602 - exit(-1);*/ 60.3603 - } 60.3604 - pc&=0xFFFF; 60.3605 - 60.3606 -/* if ((CS & 0xf000) == 0xa000) 60.3607 - { 60.3608 - dumpregs(); 60.3609 - exit(-1); 60.3610 - }*/ 60.3611 -// output = 3; 60.3612 -/* if (CS == 0xf000) 60.3613 - { 60.3614 - dumpregs(); 60.3615 - exit(-1); 60.3616 - } 60.3617 - output = 3;*/ 60.3618 - if (ssegs) 60.3619 - { 60.3620 - ds=oldds; 60.3621 - ss=oldss; 60.3622 - ssegs=0; 60.3623 - } 60.3624 - 60.3625 -// output = 3; 60.3626 - // if (instime) printf("%i %i %i %i\n",cycdiff,cycles,memcycs,fetchclocks); 60.3627 - FETCHADD(((cycdiff-cycles)-memcycs)-fetchclocks); 60.3628 - if ((cycdiff-cycles)<memcycs) cycles-=(memcycs-(cycdiff-cycles)); 60.3629 - if (romset==ROM_IBMPC) 60.3630 - { 60.3631 - if ((cs+pc)==0xFE4A7) /*You didn't seriously think I was going to emulate the cassette, did you?*/ 60.3632 - { 60.3633 - CX=1; 60.3634 - BX=0x500; 60.3635 - } 60.3636 - } 60.3637 - memcycs=0; 60.3638 - 60.3639 - insc++; 60.3640 -// output=(CS==0xEB9); 60.3641 - clockhardware(); 60.3642 - 60.3643 - 60.3644 - if (trap && (flags&T_FLAG) && !noint) 60.3645 - { 60.3646 -// printf("TRAP!!! %04X:%04X\n",CS,pc); 60.3647 - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 60.3648 - writememw(ss,(SP-4)&0xFFFF,CS); 60.3649 - writememw(ss,(SP-6)&0xFFFF,pc); 60.3650 - SP-=6; 60.3651 - addr=1<<2; 60.3652 - flags&=~I_FLAG; 60.3653 - flags&=~T_FLAG; 60.3654 - pc=readmemw(0,addr); 60.3655 - loadcs(readmemw(0,addr+2)); 60.3656 - FETCHCLEAR(); 60.3657 - } 60.3658 - else if ((flags&I_FLAG) && (pic.pend&~pic.mask) && !ssegs && !noint) 60.3659 - { 60.3660 - temp=picinterrupt(); 60.3661 - if (temp!=0xFF) 60.3662 - { 60.3663 - if (inhlt) pc++; 60.3664 - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); 60.3665 - writememw(ss,(SP-4)&0xFFFF,CS); 60.3666 - writememw(ss,(SP-6)&0xFFFF,pc); 60.3667 - SP-=6; 60.3668 - addr=temp<<2; 60.3669 - flags&=~I_FLAG; 60.3670 - flags&=~T_FLAG; 60.3671 - pc=readmemw(0,addr); 60.3672 -// printf("INT INT INT\n"); 60.3673 - loadcs(readmemw(0,addr+2)); 60.3674 - FETCHCLEAR(); 60.3675 - inint=1; 60.3676 -// printf("INTERRUPT\n"); 60.3677 - } 60.3678 - } 60.3679 - 60.3680 - if (noint) noint=0; 60.3681 - ins++; 60.3682 -/* if (timetolive) 60.3683 - { 60.3684 - timetolive--; 60.3685 - if (!timetolive) exit(-1); //output=0; 60.3686 - }*/ 60.3687 - } 60.3688 -} 60.3689 -
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/src/x86_ops.h Mon May 27 19:56:33 2013 +0100 61.3 @@ -0,0 +1,12 @@ 61.4 +typedef int (*OpFn)(uint32_t fetchdat); 61.5 + 61.6 +void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f); 61.7 + 61.8 +extern OpFn *x86_opcodes; 61.9 +extern OpFn *x86_opcodes_0f; 61.10 + 61.11 +extern OpFn ops_286[1024]; 61.12 +extern OpFn ops_286_0f[1024]; 61.13 + 61.14 +extern OpFn ops_386[1024]; 61.15 +extern OpFn ops_386_0f[1024];
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/src/x86_ops_arith.h Mon May 27 19:56:33 2013 +0100 62.3 @@ -0,0 +1,645 @@ 62.4 +#define OP_ARITH(name, operation, setflags, flagops) \ 62.5 + static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \ 62.6 + { \ 62.7 + int tempc = CF_SET(); \ 62.8 + fetch_ea_16(fetchdat); \ 62.9 + if (mod == 3) \ 62.10 + { \ 62.11 + uint8_t dst = getr8(rm); \ 62.12 + uint8_t src = getr8(reg); \ 62.13 + setflags ## 8 flagops; \ 62.14 + setr8(rm, operation); \ 62.15 + cycles -= timing_rr; \ 62.16 + } \ 62.17 + else \ 62.18 + { \ 62.19 + uint8_t dst = geteab(); if (abrt) return 0; \ 62.20 + uint8_t src = getr8(reg); \ 62.21 + seteab(operation); if (abrt) return 0; \ 62.22 + setflags ## 8 flagops; \ 62.23 + cycles -= timing_mr; \ 62.24 + } \ 62.25 + return 0; \ 62.26 + } \ 62.27 + static int op ## name ## _b_rmw_a32(uint32_t fetchdat) \ 62.28 + { \ 62.29 + int tempc = CF_SET(); \ 62.30 + fetch_ea_32(fetchdat); \ 62.31 + if (mod == 3) \ 62.32 + { \ 62.33 + uint8_t dst = getr8(rm); \ 62.34 + uint8_t src = getr8(reg); \ 62.35 + setflags ## 8 flagops; \ 62.36 + setr8(rm, operation); \ 62.37 + cycles -= timing_rr; \ 62.38 + } \ 62.39 + else \ 62.40 + { \ 62.41 + uint8_t dst = geteab(); if (abrt) return 0; \ 62.42 + uint8_t src = getr8(reg); \ 62.43 + seteab(operation); if (abrt) return 0; \ 62.44 + setflags ## 8 flagops; \ 62.45 + cycles -= timing_mr; \ 62.46 + } \ 62.47 + return 0; \ 62.48 + } \ 62.49 + \ 62.50 + static int op ## name ## _w_rmw_a16(uint32_t fetchdat) \ 62.51 + { \ 62.52 + int tempc = CF_SET(); \ 62.53 + fetch_ea_16(fetchdat); \ 62.54 + if (mod == 3) \ 62.55 + { \ 62.56 + uint16_t dst = regs[rm].w; \ 62.57 + uint16_t src = regs[reg].w; \ 62.58 + setflags ## 16 flagops; \ 62.59 + regs[rm].w = operation; \ 62.60 + cycles -= timing_rr; \ 62.61 + } \ 62.62 + else \ 62.63 + { \ 62.64 + uint16_t dst = geteaw(); if (abrt) return 0; \ 62.65 + uint16_t src = regs[reg].w; \ 62.66 + seteaw(operation); if (abrt) return 0; \ 62.67 + setflags ## 16 flagops; \ 62.68 + cycles -= timing_mr; \ 62.69 + } \ 62.70 + return 0; \ 62.71 + } \ 62.72 + static int op ## name ## _w_rmw_a32(uint32_t fetchdat) \ 62.73 + { \ 62.74 + int tempc = CF_SET(); \ 62.75 + fetch_ea_32(fetchdat); \ 62.76 + if (mod == 3) \ 62.77 + { \ 62.78 + uint16_t dst = regs[rm].w; \ 62.79 + uint16_t src = regs[reg].w; \ 62.80 + setflags ## 16 flagops; \ 62.81 + regs[rm].w = operation; \ 62.82 + cycles -= timing_rr; \ 62.83 + } \ 62.84 + else \ 62.85 + { \ 62.86 + uint16_t dst = geteaw(); if (abrt) return 0; \ 62.87 + uint16_t src = regs[reg].w; \ 62.88 + seteaw(operation); if (abrt) return 0; \ 62.89 + setflags ## 16 flagops; \ 62.90 + cycles -= timing_mr; \ 62.91 + } \ 62.92 + return 0; \ 62.93 + } \ 62.94 + \ 62.95 + static int op ## name ## _l_rmw_a16(uint32_t fetchdat) \ 62.96 + { \ 62.97 + int tempc = CF_SET(); \ 62.98 + fetch_ea_16(fetchdat); \ 62.99 + if (mod == 3) \ 62.100 + { \ 62.101 + uint32_t dst = regs[rm].l; \ 62.102 + uint32_t src = regs[reg].l; \ 62.103 + setflags ## 32 flagops; \ 62.104 + regs[rm].l = operation; \ 62.105 + cycles -= timing_rr; \ 62.106 + } \ 62.107 + else \ 62.108 + { \ 62.109 + uint32_t dst = geteal(); if (abrt) return 0; \ 62.110 + uint32_t src = regs[reg].l; \ 62.111 + seteal(operation); if (abrt) return 0; \ 62.112 + setflags ## 32 flagops; \ 62.113 + cycles -= timing_mrl; \ 62.114 + } \ 62.115 + return 0; \ 62.116 + } \ 62.117 + static int op ## name ## _l_rmw_a32(uint32_t fetchdat) \ 62.118 + { \ 62.119 + int tempc = CF_SET(); \ 62.120 + fetch_ea_32(fetchdat); \ 62.121 + if (mod == 3) \ 62.122 + { \ 62.123 + uint32_t dst = regs[rm].l; \ 62.124 + uint32_t src = regs[reg].l; \ 62.125 + setflags ## 32 flagops; \ 62.126 + regs[rm].l = operation; \ 62.127 + cycles -= timing_rr; \ 62.128 + } \ 62.129 + else \ 62.130 + { \ 62.131 + uint32_t dst = geteal(); if (abrt) return 0; \ 62.132 + uint32_t src = regs[reg].l; \ 62.133 + seteal(operation); if (abrt) return 0; \ 62.134 + setflags ## 32 flagops; \ 62.135 + cycles -= timing_mrl; \ 62.136 + } \ 62.137 + return 0; \ 62.138 + } \ 62.139 + \ 62.140 + static int op ## name ## _b_rm_a16(uint32_t fetchdat) \ 62.141 + { \ 62.142 + int tempc = CF_SET(); \ 62.143 + uint8_t dst, src; \ 62.144 + fetch_ea_16(fetchdat); \ 62.145 + dst = getr8(reg); \ 62.146 + src = geteab(); if (abrt) return 0; \ 62.147 + setflags ## 8 flagops; \ 62.148 + setr8(reg, operation); \ 62.149 + cycles -= (mod == 3) ? timing_rr : timing_rm; \ 62.150 + return 0; \ 62.151 + } \ 62.152 + static int op ## name ## _b_rm_a32(uint32_t fetchdat) \ 62.153 + { \ 62.154 + int tempc = CF_SET(); \ 62.155 + uint8_t dst, src; \ 62.156 + fetch_ea_32(fetchdat); \ 62.157 + dst = getr8(reg); \ 62.158 + src = geteab(); if (abrt) return 0; \ 62.159 + setflags ## 8 flagops; \ 62.160 + setr8(reg, operation); \ 62.161 + cycles -= (mod == 3) ? timing_rr : timing_rm; \ 62.162 + return 0; \ 62.163 + } \ 62.164 + \ 62.165 + static int op ## name ## _w_rm_a16(uint32_t fetchdat) \ 62.166 + { \ 62.167 + int tempc = CF_SET(); \ 62.168 + uint16_t dst, src; \ 62.169 + fetch_ea_16(fetchdat); \ 62.170 + dst = regs[reg].w; \ 62.171 + src = geteaw(); if (abrt) return 0; \ 62.172 + setflags ## 16 flagops; \ 62.173 + regs[reg].w = operation; \ 62.174 + cycles -= (mod == 3) ? timing_rr : timing_rm; \ 62.175 + return 0; \ 62.176 + } \ 62.177 + static int op ## name ## _w_rm_a32(uint32_t fetchdat) \ 62.178 + { \ 62.179 + int tempc = CF_SET(); \ 62.180 + uint16_t dst, src; \ 62.181 + fetch_ea_32(fetchdat); \ 62.182 + dst = regs[reg].w; \ 62.183 + src = geteaw(); if (abrt) return 0; \ 62.184 + setflags ## 16 flagops; \ 62.185 + regs[reg].w = operation; \ 62.186 + cycles -= (mod == 3) ? timing_rr : timing_rm; \ 62.187 + return 0; \ 62.188 + } \ 62.189 + \ 62.190 + static int op ## name ## _l_rm_a16(uint32_t fetchdat) \ 62.191 + { \ 62.192 + int tempc = CF_SET(); \ 62.193 + uint32_t dst, src; \ 62.194 + fetch_ea_16(fetchdat); \ 62.195 + dst = regs[reg].l; \ 62.196 + src = geteal(); if (abrt) return 0; \ 62.197 + setflags ## 32 flagops; \ 62.198 + regs[reg].l = operation; \ 62.199 + cycles -= (mod == 3) ? timing_rr : timing_rml; \ 62.200 + return 0; \ 62.201 + } \ 62.202 + static int op ## name ## _l_rm_a32(uint32_t fetchdat) \ 62.203 + { \ 62.204 + int tempc = CF_SET(); \ 62.205 + uint32_t dst, src; \ 62.206 + fetch_ea_32(fetchdat); \ 62.207 + dst = regs[reg].l; \ 62.208 + src = geteal(); if (abrt) return 0; \ 62.209 + setflags ## 32 flagops; \ 62.210 + regs[reg].l = operation; \ 62.211 + cycles -= (mod == 3) ? timing_rr : timing_rml; \ 62.212 + return 0; \ 62.213 + } \ 62.214 + \ 62.215 + static int op ## name ## _AL_imm(uint32_t fetchdat) \ 62.216 + { \ 62.217 + int tempc = CF_SET(); \ 62.218 + uint8_t dst = AL; \ 62.219 + uint8_t src = getbytef(); \ 62.220 + setflags ## 8 flagops; \ 62.221 + AL = operation; \ 62.222 + cycles -= timing_rr; \ 62.223 + return 0; \ 62.224 + } \ 62.225 + \ 62.226 + static int op ## name ## _AX_imm(uint32_t fetchdat) \ 62.227 + { \ 62.228 + int tempc = CF_SET(); \ 62.229 + uint16_t dst = AX; \ 62.230 + uint16_t src = getwordf(); \ 62.231 + setflags ## 16 flagops; \ 62.232 + AX = operation; \ 62.233 + cycles -= timing_rr; \ 62.234 + return 0; \ 62.235 + } \ 62.236 + \ 62.237 + static int op ## name ## _EAX_imm(uint32_t fetchdat) \ 62.238 + { \ 62.239 + int tempc = CF_SET(); \ 62.240 + uint32_t dst = EAX; \ 62.241 + uint32_t src = getlong(); \ 62.242 + setflags ## 32 flagops; \ 62.243 + EAX = operation; \ 62.244 + cycles -= timing_rr; \ 62.245 + return 0; \ 62.246 + } 62.247 + 62.248 +OP_ARITH(ADD, dst + src, setadd, (dst, src)) 62.249 +OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src)) 62.250 +OP_ARITH(SUB, dst - src, setsub, (dst, src)) 62.251 +OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src)) 62.252 +OP_ARITH(OR, dst | src, setznp, (dst | src)) 62.253 +OP_ARITH(AND, dst & src, setznp, (dst & src)) 62.254 +OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src)) 62.255 + 62.256 +static int opCMP_b_rmw_a16(uint32_t fetchdat) 62.257 +{ 62.258 + uint8_t dst; 62.259 + fetch_ea_16(fetchdat); 62.260 + dst = geteab(); if (abrt) return 0; 62.261 + setsub8(dst, getr8(reg)); 62.262 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.263 + else cycles -= ((mod == 3) ? 2 : 5); 62.264 + return 0; 62.265 +} 62.266 +static int opCMP_b_rmw_a32(uint32_t fetchdat) 62.267 +{ 62.268 + uint8_t dst; 62.269 + fetch_ea_32(fetchdat); 62.270 + dst = geteab(); if (abrt) return 0; 62.271 + setsub8(dst, getr8(reg)); 62.272 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.273 + else cycles -= ((mod == 3) ? 2 : 5); 62.274 + return 0; 62.275 +} 62.276 + 62.277 +static int opCMP_w_rmw_a16(uint32_t fetchdat) 62.278 +{ 62.279 + uint16_t dst; 62.280 + fetch_ea_16(fetchdat); 62.281 + dst = geteaw(); if (abrt) return 0; 62.282 + setsub16(dst, regs[reg].w); 62.283 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.284 + else cycles -= ((mod == 3) ? 2 : 5); 62.285 + return 0; 62.286 +} 62.287 +static int opCMP_w_rmw_a32(uint32_t fetchdat) 62.288 +{ 62.289 + uint16_t dst; 62.290 + fetch_ea_32(fetchdat); 62.291 + dst = geteaw(); if (abrt) return 0; 62.292 + setsub16(dst, regs[reg].w); 62.293 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.294 + else cycles -= ((mod == 3) ? 2 : 5); 62.295 + return 0; 62.296 +} 62.297 + 62.298 +static int opCMP_l_rmw_a16(uint32_t fetchdat) 62.299 +{ 62.300 + uint32_t dst; 62.301 + fetch_ea_16(fetchdat); 62.302 + dst = geteal(); if (abrt) return 0; 62.303 + setsub32(dst, regs[reg].l); 62.304 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.305 + else cycles -= ((mod == 3) ? 2 : 5); 62.306 + return 0; 62.307 +} 62.308 +static int opCMP_l_rmw_a32(uint32_t fetchdat) 62.309 +{ 62.310 + uint32_t dst; 62.311 + fetch_ea_32(fetchdat); 62.312 + dst = geteal(); if (abrt) return 0; 62.313 + setsub32(dst, regs[reg].l); 62.314 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.315 + else cycles -= ((mod == 3) ? 2 : 5); 62.316 + return 0; 62.317 +} 62.318 + 62.319 +static int opCMP_b_rm_a16(uint32_t fetchdat) 62.320 +{ 62.321 + uint8_t src; 62.322 + fetch_ea_16(fetchdat); 62.323 + src = geteab(); if (abrt) return 0; 62.324 + setsub8(getr8(reg), src); 62.325 + cycles -= (mod == 3) ? timing_rr : timing_rm; 62.326 + return 0; 62.327 +} 62.328 +static int opCMP_b_rm_a32(uint32_t fetchdat) 62.329 +{ 62.330 + uint8_t src; 62.331 + fetch_ea_32(fetchdat); 62.332 + src = geteab(); if (abrt) return 0; 62.333 + setsub8(getr8(reg), src); 62.334 + cycles -= (mod == 3) ? timing_rr : timing_rm; 62.335 + return 0; 62.336 +} 62.337 + 62.338 +static int opCMP_w_rm_a16(uint32_t fetchdat) 62.339 +{ 62.340 + uint16_t src; 62.341 + fetch_ea_16(fetchdat); 62.342 + src = geteaw(); if (abrt) return 0; 62.343 + setsub16(regs[reg].w, src); 62.344 + cycles -= (mod == 3) ? timing_rr : timing_rm; 62.345 + return 0; 62.346 +} 62.347 +static int opCMP_w_rm_a32(uint32_t fetchdat) 62.348 +{ 62.349 + uint16_t src; 62.350 + fetch_ea_32(fetchdat); 62.351 + src = geteaw(); if (abrt) return 0; 62.352 + setsub16(regs[reg].w, src); 62.353 + cycles -= (mod == 3) ? timing_rr : timing_rm; 62.354 + return 0; 62.355 +} 62.356 + 62.357 +static int opCMP_l_rm_a16(uint32_t fetchdat) 62.358 +{ 62.359 + uint32_t src; 62.360 + fetch_ea_16(fetchdat); 62.361 + src = geteal(); if (abrt) return 0; 62.362 + setsub32(regs[reg].l, src); 62.363 + cycles -= (mod == 3) ? timing_rr : timing_rml; 62.364 + return 0; 62.365 +} 62.366 +static int opCMP_l_rm_a32(uint32_t fetchdat) 62.367 +{ 62.368 + uint32_t src; 62.369 + fetch_ea_32(fetchdat); 62.370 + src = geteal(); if (abrt) return 0; 62.371 + setsub32(regs[reg].l, src); 62.372 + cycles -= (mod == 3) ? timing_rr : timing_rml; 62.373 + return 0; 62.374 +} 62.375 + 62.376 +static int opCMP_AL_imm(uint32_t fetchdat) 62.377 +{ 62.378 + uint8_t src = getbytef(); 62.379 + setsub8(AL, src); 62.380 + cycles -= timing_rr; 62.381 + return 0; 62.382 +} 62.383 + 62.384 +static int opCMP_AX_imm(uint32_t fetchdat) 62.385 +{ 62.386 + uint16_t src = getwordf(); 62.387 + setsub16(AX, src); 62.388 + cycles -= timing_rr; 62.389 + return 0; 62.390 +} 62.391 + 62.392 +static int opCMP_EAX_imm(uint32_t fetchdat) 62.393 +{ 62.394 + uint32_t src = getlong(); 62.395 + setsub32(EAX, src); 62.396 + cycles -= timing_rr; 62.397 + return 0; 62.398 +} 62.399 + 62.400 +static int opTEST_b_a16(uint32_t fetchdat) 62.401 +{ 62.402 + uint8_t temp, temp2; 62.403 + fetch_ea_16(fetchdat); 62.404 + temp = geteab(); if (abrt) return 0; 62.405 + temp2 = getr8(reg); 62.406 + setznp8(temp & temp2); 62.407 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.408 + else cycles -= ((mod == 3) ? 2 : 5); 62.409 + return 0; 62.410 +} 62.411 +static int opTEST_b_a32(uint32_t fetchdat) 62.412 +{ 62.413 + uint8_t temp, temp2; 62.414 + fetch_ea_32(fetchdat); 62.415 + temp = geteab(); if (abrt) return 0; 62.416 + temp2 = getr8(reg); 62.417 + setznp8(temp & temp2); 62.418 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.419 + else cycles -= ((mod == 3) ? 2 : 5); 62.420 + return 0; 62.421 +} 62.422 + 62.423 +static int opTEST_w_a16(uint32_t fetchdat) 62.424 +{ 62.425 + uint16_t temp, temp2; 62.426 + fetch_ea_16(fetchdat); 62.427 + temp = geteaw(); if (abrt) return 0; 62.428 + temp2 = regs[reg].w; 62.429 + setznp16(temp & temp2); 62.430 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.431 + else cycles -= ((mod == 3) ? 2 : 5); 62.432 + return 0; 62.433 +} 62.434 +static int opTEST_w_a32(uint32_t fetchdat) 62.435 +{ 62.436 + uint16_t temp, temp2; 62.437 + fetch_ea_32(fetchdat); 62.438 + temp = geteaw(); if (abrt) return 0; 62.439 + temp2 = regs[reg].w; 62.440 + setznp16(temp & temp2); 62.441 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.442 + else cycles -= ((mod == 3) ? 2 : 5); 62.443 + return 0; 62.444 +} 62.445 + 62.446 +static int opTEST_l_a16(uint32_t fetchdat) 62.447 +{ 62.448 + uint32_t temp, temp2; 62.449 + fetch_ea_16(fetchdat); 62.450 + temp = geteal(); if (abrt) return 0; 62.451 + temp2 = regs[reg].l; 62.452 + setznp32(temp & temp2); 62.453 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.454 + else cycles -= ((mod == 3) ? 2 : 5); 62.455 + return 0; 62.456 +} 62.457 +static int opTEST_l_a32(uint32_t fetchdat) 62.458 +{ 62.459 + uint32_t temp, temp2; 62.460 + fetch_ea_32(fetchdat); 62.461 + temp = geteal(); if (abrt) return 0; 62.462 + temp2 = regs[reg].l; 62.463 + setznp32(temp & temp2); 62.464 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 62.465 + else cycles -= ((mod == 3) ? 2 : 5); 62.466 + return 0; 62.467 +} 62.468 + 62.469 +static int opTEST_AL(uint32_t fetchdat) 62.470 +{ 62.471 + uint8_t temp = getbytef(); 62.472 + setznp8(AL & temp); 62.473 + cycles -= timing_rr; 62.474 + return 0; 62.475 +} 62.476 +static int opTEST_AX(uint32_t fetchdat) 62.477 +{ 62.478 + uint16_t temp = getwordf(); 62.479 + setznp16(AX & temp); 62.480 + cycles -= timing_rr; 62.481 + return 0; 62.482 +} 62.483 +static int opTEST_EAX(uint32_t fetchdat) 62.484 +{ 62.485 + uint32_t temp = getlong(); if (abrt) return 0; 62.486 + setznp32(EAX & temp); 62.487 + cycles -= timing_rr; 62.488 + return 0; 62.489 +} 62.490 + 62.491 + 62.492 +#define ARITH_MULTI(ea_width, flag_width) \ 62.493 + dst = getea ## ea_width(); if (abrt) return 0; \ 62.494 + switch (rmdat&0x38) \ 62.495 + { \ 62.496 + case 0x00: /*ADD ea, #*/ \ 62.497 + setea ## ea_width(dst + src); if (abrt) return 0; \ 62.498 + setadd ## flag_width(dst, src); \ 62.499 + cycles -= (mod == 3) ? timing_rr : timing_mr; \ 62.500 + break; \ 62.501 + case 0x08: /*OR ea, #*/ \ 62.502 + dst |= src; \ 62.503 + setea ## ea_width(dst); if (abrt) return 0; \ 62.504 + setznp ## flag_width(dst); \ 62.505 + cycles -= (mod == 3) ? timing_rr : timing_mr; \ 62.506 + break; \ 62.507 + case 0x10: /*ADC ea, #*/ \ 62.508 + setea ## ea_width(dst + src + tempc); if (abrt) return 0; \ 62.509 + setadc ## flag_width(dst, src); \ 62.510 + cycles -= (mod == 3) ? timing_rr : timing_mr; \ 62.511 + break; \ 62.512 + case 0x18: /*SBB ea, #*/ \ 62.513 + setea ## ea_width(dst - (src + tempc)); if (abrt) return 0; \ 62.514 + setsbc ## flag_width(dst, src); \ 62.515 + cycles -= (mod == 3) ? timing_rr : timing_mr; \ 62.516 + break; \ 62.517 + case 0x20: /*AND ea, #*/ \ 62.518 + dst &= src; \ 62.519 + setea ## ea_width(dst); if (abrt) return 0; \ 62.520 + setznp ## flag_width(dst); \ 62.521 + cycles -= (mod == 3) ? timing_rr : timing_mr; \ 62.522 + break; \ 62.523 + case 0x28: /*SUB ea, #*/ \ 62.524 + setea ## ea_width(dst - src); if (abrt) return 0; \ 62.525 + setsub ## flag_width(dst, src); \ 62.526 + cycles -= (mod == 3) ? timing_rr : timing_mr; \ 62.527 + break; \ 62.528 + case 0x30: /*XOR ea, #*/ \ 62.529 + dst ^= src; \ 62.530 + setea ## ea_width(dst); if (abrt) return 0; \ 62.531 + setznp ## flag_width(dst); \ 62.532 + cycles -= (mod == 3) ? timing_rr : timing_mr; \ 62.533 + break; \ 62.534 + case 0x38: /*CMP ea, #*/ \ 62.535 + setsub ## flag_width(dst, src); \ 62.536 + if (is486) cycles -= ((mod == 3) ? 1 : 2); \ 62.537 + else cycles -= ((mod == 3) ? 2 : 7); \ 62.538 + break; \ 62.539 + } 62.540 + 62.541 + 62.542 +static int op80_a16(uint32_t fetchdat) 62.543 +{ 62.544 + uint8_t src, dst; 62.545 + 62.546 + fetch_ea_16(fetchdat); 62.547 + src = getbyte(); if (abrt) return 0; 62.548 + ARITH_MULTI(b, 8); 62.549 + 62.550 + return 0; 62.551 +} 62.552 +static int op80_a32(uint32_t fetchdat) 62.553 +{ 62.554 + uint8_t src, dst; 62.555 + 62.556 + fetch_ea_32(fetchdat); 62.557 + src = getbyte(); if (abrt) return 0; 62.558 + ARITH_MULTI(b, 8); 62.559 + 62.560 + return 0; 62.561 +} 62.562 +static int op81_w_a16(uint32_t fetchdat) 62.563 +{ 62.564 + uint16_t src, dst; 62.565 + 62.566 + fetch_ea_16(fetchdat); 62.567 + src = getword(); if (abrt) return 0; 62.568 + ARITH_MULTI(w, 16); 62.569 + 62.570 + return 0; 62.571 +} 62.572 +static int op81_w_a32(uint32_t fetchdat) 62.573 +{ 62.574 + uint16_t src, dst; 62.575 + 62.576 + fetch_ea_32(fetchdat); 62.577 + src = getword(); if (abrt) return 0; 62.578 + ARITH_MULTI(w, 16); 62.579 + 62.580 + return 0; 62.581 +} 62.582 +static int op81_l_a16(uint32_t fetchdat) 62.583 +{ 62.584 + uint32_t src, dst; 62.585 + 62.586 + fetch_ea_16(fetchdat); 62.587 + src = getlong(); if (abrt) return 0; 62.588 + ARITH_MULTI(l, 32); 62.589 + 62.590 + return 0; 62.591 +} 62.592 +static int op81_l_a32(uint32_t fetchdat) 62.593 +{ 62.594 + uint32_t src, dst; 62.595 + 62.596 + fetch_ea_32(fetchdat); 62.597 + src = getlong(); if (abrt) return 0; 62.598 + ARITH_MULTI(l, 32); 62.599 + 62.600 + return 0; 62.601 +} 62.602 + 62.603 +static int op83_w_a16(uint32_t fetchdat) 62.604 +{ 62.605 + uint16_t src, dst; 62.606 + 62.607 + fetch_ea_16(fetchdat); 62.608 + src = getbyte(); if (abrt) return 0; 62.609 + if (src & 0x80) src |= 0xff00; 62.610 + ARITH_MULTI(w, 16); 62.611 + 62.612 + return 0; 62.613 +} 62.614 +static int op83_w_a32(uint32_t fetchdat) 62.615 +{ 62.616 + uint16_t src, dst; 62.617 + 62.618 + fetch_ea_32(fetchdat); 62.619 + src = getbyte(); if (abrt) return 0; 62.620 + if (src & 0x80) src |= 0xff00; 62.621 + ARITH_MULTI(w, 16); 62.622 + 62.623 + return 0; 62.624 +} 62.625 + 62.626 +static int op83_l_a16(uint32_t fetchdat) 62.627 +{ 62.628 + uint32_t src, dst; 62.629 + 62.630 + fetch_ea_16(fetchdat); 62.631 + src = getbyte(); if (abrt) return 0; 62.632 + if (src & 0x80) src |= 0xffffff00; 62.633 + ARITH_MULTI(l, 32); 62.634 + 62.635 + return 0; 62.636 +} 62.637 +static int op83_l_a32(uint32_t fetchdat) 62.638 +{ 62.639 + uint32_t src, dst; 62.640 + 62.641 + fetch_ea_32(fetchdat); 62.642 + src = getbyte(); if (abrt) return 0; 62.643 + if (src & 0x80) src |= 0xffffff00; 62.644 + ARITH_MULTI(l, 32); 62.645 + 62.646 + return 0; 62.647 +} 62.648 +
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/src/x86_ops_atomic.h Mon May 27 19:56:33 2013 +0100 63.3 @@ -0,0 +1,209 @@ 63.4 +static int opCMPXCHG_b_a16(uint32_t fetchdat) 63.5 +{ 63.6 + uint8_t temp, temp2 = AL; 63.7 + if (!is486) 63.8 + { 63.9 + pc = oldpc; 63.10 + x86illegal(); 63.11 + return 0; 63.12 + } 63.13 + fetch_ea_16(fetchdat); 63.14 + temp = geteab(); if (abrt) return 0; 63.15 + if (AL == temp) seteab(getr8(reg)); 63.16 + else AL = temp; 63.17 + if (abrt) return 0; 63.18 + setsub8(temp2, temp); 63.19 + cycles -= (mod == 3) ? 6 : 10; 63.20 + return 0; 63.21 +} 63.22 +static int opCMPXCHG_b_a32(uint32_t fetchdat) 63.23 +{ 63.24 + uint8_t temp, temp2 = AL; 63.25 + if (!is486) 63.26 + { 63.27 + pc = oldpc; 63.28 + x86illegal(); 63.29 + return 0; 63.30 + } 63.31 + fetch_ea_32(fetchdat); 63.32 + temp = geteab(); if (abrt) return 0; 63.33 + if (AL == temp) seteab(getr8(reg)); 63.34 + else AL = temp; 63.35 + if (abrt) return 0; 63.36 + setsub8(temp2, temp); 63.37 + cycles -= (mod == 3) ? 6 : 10; 63.38 + return 0; 63.39 +} 63.40 + 63.41 +static int opCMPXCHG_w_a16(uint32_t fetchdat) 63.42 +{ 63.43 + uint16_t temp, temp2 = AX; 63.44 + if (!is486) 63.45 + { 63.46 + pc = oldpc; 63.47 + x86illegal(); 63.48 + return 0; 63.49 + } 63.50 + fetch_ea_16(fetchdat); 63.51 + temp = geteaw(); if (abrt) return 0; 63.52 + if (AX == temp) seteaw(regs[reg].w); 63.53 + else AX = temp; 63.54 + if (abrt) return 0; 63.55 + setsub16(temp2, temp); 63.56 + cycles -= (mod == 3) ? 6 : 10; 63.57 + return 0; 63.58 +} 63.59 +static int opCMPXCHG_w_a32(uint32_t fetchdat) 63.60 +{ 63.61 + uint16_t temp, temp2 = AX; 63.62 + if (!is486) 63.63 + { 63.64 + pc = oldpc; 63.65 + x86illegal(); 63.66 + return 0; 63.67 + } 63.68 + fetch_ea_32(fetchdat); 63.69 + temp = geteaw(); if (abrt) return 0; 63.70 + if (AX == temp) seteaw(regs[reg].w); 63.71 + else AX = temp; 63.72 + if (abrt) return 0; 63.73 + setsub16(temp2, temp); 63.74 + cycles -= (mod == 3) ? 6 : 10; 63.75 + return 0; 63.76 +} 63.77 + 63.78 +static int opCMPXCHG_l_a16(uint32_t fetchdat) 63.79 +{ 63.80 + uint32_t temp, temp2 = EAX; 63.81 + if (!is486) 63.82 + { 63.83 + pc = oldpc; 63.84 + x86illegal(); 63.85 + return 0; 63.86 + } 63.87 + fetch_ea_16(fetchdat); 63.88 + temp = geteal(); if (abrt) return 0; 63.89 + if (EAX == temp) seteal(regs[reg].l); 63.90 + else EAX = temp; 63.91 + if (abrt) return 0; 63.92 + setsub32(temp2, temp); 63.93 + cycles -= (mod == 3) ? 6 : 10; 63.94 + return 0; 63.95 +} 63.96 +static int opCMPXCHG_l_a32(uint32_t fetchdat) 63.97 +{ 63.98 + uint32_t temp, temp2 = EAX; 63.99 + if (!is486) 63.100 + { 63.101 + pc = oldpc; 63.102 + x86illegal(); 63.103 + return 0; 63.104 + } 63.105 + fetch_ea_32(fetchdat); 63.106 + temp = geteal(); if (abrt) return 0; 63.107 + if (EAX == temp) seteal(regs[reg].l); 63.108 + else EAX = temp; 63.109 + if (abrt) return 0; 63.110 + setsub32(temp2, temp); 63.111 + cycles -= (mod == 3) ? 6 : 10; 63.112 + return 0; 63.113 +} 63.114 + 63.115 +static int opXADD_b_a16(uint32_t fetchdat) 63.116 +{ 63.117 + uint8_t temp; 63.118 + if (!is486) 63.119 + { 63.120 + pc = oldpc; 63.121 + x86illegal(); 63.122 + return 0; 63.123 + } 63.124 + fetch_ea_16(fetchdat); 63.125 + temp = geteab(); if (abrt) return 0; 63.126 + seteab(temp + getr8(reg)); if (abrt) return 0; 63.127 + setadd8(temp, getr8(reg)); 63.128 + setr8(reg, temp); 63.129 + return 0; 63.130 +} 63.131 +static int opXADD_b_a32(uint32_t fetchdat) 63.132 +{ 63.133 + uint8_t temp; 63.134 + if (!is486) 63.135 + { 63.136 + pc = oldpc; 63.137 + x86illegal(); 63.138 + return 0; 63.139 + } 63.140 + fetch_ea_32(fetchdat); 63.141 + temp = geteab(); if (abrt) return 0; 63.142 + seteab(temp + getr8(reg)); if (abrt) return 0; 63.143 + setadd8(temp, getr8(reg)); 63.144 + setr8(reg, temp); 63.145 + return 0; 63.146 +} 63.147 + 63.148 +static int opXADD_w_a16(uint32_t fetchdat) 63.149 +{ 63.150 + uint16_t temp; 63.151 + if (!is486) 63.152 + { 63.153 + pc = oldpc; 63.154 + x86illegal(); 63.155 + return 0; 63.156 + } 63.157 + fetch_ea_16(fetchdat); 63.158 + temp = geteaw(); if (abrt) return 0; 63.159 + seteaw(temp + regs[reg].w); if (abrt) return 0; 63.160 + setadd16(temp, regs[reg].w); 63.161 + regs[reg].w = temp; 63.162 + return 0; 63.163 +} 63.164 +static int opXADD_w_a32(uint32_t fetchdat) 63.165 +{ 63.166 + uint16_t temp; 63.167 + if (!is486) 63.168 + { 63.169 + pc = oldpc; 63.170 + x86illegal(); 63.171 + return 0; 63.172 + } 63.173 + fetch_ea_32(fetchdat); 63.174 + temp = geteaw(); if (abrt) return 0; 63.175 + seteaw(temp + regs[reg].w); if (abrt) return 0; 63.176 + setadd16(temp, regs[reg].w); 63.177 + regs[reg].w = temp; 63.178 + return 0; 63.179 +} 63.180 + 63.181 +static int opXADD_l_a16(uint32_t fetchdat) 63.182 +{ 63.183 + uint32_t temp; 63.184 + if (!is486) 63.185 + { 63.186 + pc = oldpc; 63.187 + x86illegal(); 63.188 + return 0; 63.189 + } 63.190 + fetch_ea_16(fetchdat); 63.191 + temp = geteal(); if (abrt) return 0; 63.192 + seteal(temp + regs[reg].l); if (abrt) return 0; 63.193 + setadd32(temp, regs[reg].l); 63.194 + regs[reg].l = temp; 63.195 + return 0; 63.196 +} 63.197 +static int opXADD_l_a32(uint32_t fetchdat) 63.198 +{ 63.199 + uint32_t temp; 63.200 + if (!is486) 63.201 + { 63.202 + pc = oldpc; 63.203 + x86illegal(); 63.204 + return 0; 63.205 + } 63.206 + fetch_ea_32(fetchdat); 63.207 + temp = geteal(); if (abrt) return 0; 63.208 + seteal(temp + regs[reg].l); if (abrt) return 0; 63.209 + setadd32(temp, regs[reg].l); 63.210 + regs[reg].l = temp; 63.211 + return 0; 63.212 +}
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 64.2 +++ b/src/x86_ops_bcd.h Mon May 27 19:56:33 2013 +0100 64.3 @@ -0,0 +1,105 @@ 64.4 +static int opAAA(uint32_t fetchdat) 64.5 +{ 64.6 + flags_rebuild(); 64.7 + if ((flags & A_FLAG) || ((AL & 0xF) > 9)) 64.8 + { 64.9 + AL += 6; 64.10 + AH++; 64.11 + flags |= (A_FLAG | C_FLAG); 64.12 + } 64.13 + else 64.14 + flags &= ~(A_FLAG | C_FLAG); 64.15 + AL &= 0xF; 64.16 + cycles -= is486 ? 3 : 4; 64.17 + return 0; 64.18 +} 64.19 + 64.20 +static int opAAD(uint32_t fetchdat) 64.21 +{ 64.22 + int base = getbytef(); 64.23 + if (cpu_manufacturer != MANU_INTEL) base = 10; 64.24 + AL = (AH * base) + AL; 64.25 + AH = 0; 64.26 + setznp16(AX); 64.27 + cycles -= (is486) ? 14 : 19; 64.28 + return 0; 64.29 +} 64.30 + 64.31 +static int opAAM(uint32_t fetchdat) 64.32 +{ 64.33 + int base = getbytef(); 64.34 + if (!base || cpu_manufacturer != MANU_INTEL) base = 10; 64.35 + AH = AL / base; 64.36 + AL %= base; 64.37 + setznp16(AX); 64.38 + cycles -= (is486) ? 15 : 17; 64.39 + return 0; 64.40 +} 64.41 + 64.42 +static int opAAS(uint32_t fetchdat) 64.43 +{ 64.44 + flags_rebuild(); 64.45 + if ((flags & A_FLAG) || ((AL & 0xF) > 9)) 64.46 + { 64.47 + AL -= 6; 64.48 + AH--; 64.49 + flags |= (A_FLAG | C_FLAG); 64.50 + } 64.51 + else 64.52 + flags &= ~(A_FLAG | C_FLAG); 64.53 + AL &= 0xF; 64.54 + cycles -= is486 ? 3 : 4; 64.55 + return 0; 64.56 +} 64.57 + 64.58 +static int opDAA(uint32_t fetchdat) 64.59 +{ 64.60 + uint16_t tempw; 64.61 + 64.62 + flags_rebuild(); 64.63 + if ((flags & A_FLAG) || ((AL & 0xf) > 9)) 64.64 + { 64.65 + int tempi = ((uint16_t)AL) + 6; 64.66 + AL += 6; 64.67 + flags |= A_FLAG; 64.68 + if (tempi & 0x100) flags |= C_FLAG; 64.69 + } 64.70 + if ((flags & C_FLAG) || (AL > 0x9f)) 64.71 + { 64.72 + AL += 0x60; 64.73 + flags |= C_FLAG; 64.74 + } 64.75 + 64.76 + tempw = flags & (C_FLAG | A_FLAG); 64.77 + setznp8(AL); 64.78 + flags |= tempw; 64.79 + cycles -= 4; 64.80 + 64.81 + return 0; 64.82 +} 64.83 + 64.84 +static int opDAS(uint32_t fetchdat) 64.85 +{ 64.86 + uint16_t tempw; 64.87 + 64.88 + flags_rebuild(); 64.89 + if ((flags & A_FLAG) || ((AL & 0xf) > 9)) 64.90 + { 64.91 + int tempi = ((uint16_t)AL) - 6; 64.92 + AL -= 6; 64.93 + flags |= A_FLAG; 64.94 + if (tempi & 0x100) flags |= C_FLAG; 64.95 + } 64.96 + if ((flags & C_FLAG) || (AL > 0x9f)) 64.97 + { 64.98 + AL -= 0x60; 64.99 + flags |= C_FLAG; 64.100 + } 64.101 + 64.102 + tempw = flags & (C_FLAG | A_FLAG); 64.103 + setznp8(AL); 64.104 + flags |= tempw; 64.105 + cycles -= 4; 64.106 + 64.107 + return 0; 64.108 +}
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 65.2 +++ b/src/x86_ops_bit.h Mon May 27 19:56:33 2013 +0100 65.3 @@ -0,0 +1,297 @@ 65.4 +static int opBT_w_r_a16(uint32_t fetchdat) 65.5 +{ 65.6 + int tempc; 65.7 + uint16_t temp; 65.8 + 65.9 + fetch_ea_16(fetchdat); 65.10 + eaaddr += ((regs[reg].w / 16) * 2); eal_r = 0; 65.11 + temp = geteaw(); if (abrt) return 0; 65.12 + flags_rebuild(); 65.13 + if (temp & (1 << (regs[reg].w & 15))) flags |= C_FLAG; 65.14 + else flags &= ~C_FLAG; 65.15 + 65.16 + cycles -= 3; 65.17 + return 0; 65.18 +} 65.19 +static int opBT_w_r_a32(uint32_t fetchdat) 65.20 +{ 65.21 + uint16_t temp; 65.22 + 65.23 + fetch_ea_32(fetchdat); 65.24 + eaaddr += ((regs[reg].w / 16) * 2); eal_r = 0; 65.25 + temp = geteaw(); if (abrt) return 0; 65.26 + flags_rebuild(); 65.27 + if (temp & (1 << (regs[reg].w & 15))) flags |= C_FLAG; 65.28 + else flags &= ~C_FLAG; 65.29 + 65.30 + cycles -= 3; 65.31 + return 0; 65.32 +} 65.33 +static int opBT_l_r_a16(uint32_t fetchdat) 65.34 +{ 65.35 + uint32_t temp; 65.36 + 65.37 + fetch_ea_16(fetchdat); 65.38 + eaaddr += ((regs[reg].l / 32) * 4); eal_r = 0; 65.39 + temp = geteal(); if (abrt) return 0; 65.40 + flags_rebuild(); 65.41 + if (temp & (1 << (regs[reg].l & 31))) flags |= C_FLAG; 65.42 + else flags &= ~C_FLAG; 65.43 + 65.44 + cycles -= 3; 65.45 + return 0; 65.46 +} 65.47 +static int opBT_l_r_a32(uint32_t fetchdat) 65.48 +{ 65.49 + uint32_t temp; 65.50 + 65.51 + fetch_ea_32(fetchdat); 65.52 + eaaddr += ((regs[reg].l / 32) * 4); eal_r = 0; 65.53 + temp = geteal(); if (abrt) return 0; 65.54 + flags_rebuild(); 65.55 + if (temp & (1 << (regs[reg].l & 31))) flags |= C_FLAG; 65.56 + else flags &= ~C_FLAG; 65.57 + 65.58 + cycles -= 3; 65.59 + return 0; 65.60 +} 65.61 + 65.62 +#define opBT(name, operation) \ 65.63 + static int opBT ## name ## _w_r_a16(uint32_t fetchdat) \ 65.64 + { \ 65.65 + int tempc; \ 65.66 + uint16_t temp; \ 65.67 + \ 65.68 + fetch_ea_16(fetchdat); \ 65.69 + eaaddr += ((regs[reg].w / 16) * 2); eal_r = eal_w = 0; \ 65.70 + temp = geteaw(); if (abrt) return 0; \ 65.71 + tempc = (temp & (1 << (regs[reg].w & 15))) ? 1 : 0; \ 65.72 + temp operation (1 << (regs[reg].w & 15)); \ 65.73 + seteaw(temp); if (abrt) return 0; \ 65.74 + flags_rebuild(); \ 65.75 + if (tempc) flags |= C_FLAG; \ 65.76 + else flags &= ~C_FLAG; \ 65.77 + \ 65.78 + cycles -= 6; \ 65.79 + return 0; \ 65.80 + } \ 65.81 + static int opBT ## name ## _w_r_a32(uint32_t fetchdat) \ 65.82 + { \ 65.83 + int tempc; \ 65.84 + uint16_t temp; \ 65.85 + \ 65.86 + fetch_ea_32(fetchdat); \ 65.87 + eaaddr += ((regs[reg].w / 16) * 2); eal_r = eal_w = 0; \ 65.88 + temp = geteaw(); if (abrt) return 0; \ 65.89 + tempc = (temp & (1 << (regs[reg].w & 15))) ? 1 : 0; \ 65.90 + temp operation (1 << (regs[reg].w & 15)); \ 65.91 + seteaw(temp); if (abrt) return 0; \ 65.92 + flags_rebuild(); \ 65.93 + if (tempc) flags |= C_FLAG; \ 65.94 + else flags &= ~C_FLAG; \ 65.95 + \ 65.96 + cycles -= 6; \ 65.97 + return 0; \ 65.98 + } \ 65.99 + static int opBT ## name ## _l_r_a16(uint32_t fetchdat) \ 65.100 + { \ 65.101 + int tempc; \ 65.102 + uint32_t temp; \ 65.103 + \ 65.104 + fetch_ea_16(fetchdat); \ 65.105 + eaaddr += ((regs[reg].l / 32) * 4); eal_r = eal_w = 0; \ 65.106 + temp = geteal(); if (abrt) return 0; \ 65.107 + tempc = (temp & (1 << (regs[reg].l & 31))) ? 1 : 0; \ 65.108 + temp operation (1 << (regs[reg].l & 31)); \ 65.109 + seteal(temp); if (abrt) return 0; \ 65.110 + flags_rebuild(); \ 65.111 + if (tempc) flags |= C_FLAG; \ 65.112 + else flags &= ~C_FLAG; \ 65.113 + \ 65.114 + cycles -= 6; \ 65.115 + return 0; \ 65.116 + } \ 65.117 + static int opBT ## name ## _l_r_a32(uint32_t fetchdat) \ 65.118 + { \ 65.119 + int tempc; \ 65.120 + uint32_t temp; \ 65.121 + \ 65.122 + fetch_ea_32(fetchdat); \ 65.123 + eaaddr += ((regs[reg].l / 32) * 4); eal_r = eal_w = 0; \ 65.124 + temp = geteal(); if (abrt) return 0; \ 65.125 + tempc = (temp & (1 << (regs[reg].l & 31))) ? 1 : 0; \ 65.126 + temp operation (1 << (regs[reg].l & 31)); \ 65.127 + seteal(temp); if (abrt) return 0; \ 65.128 + flags_rebuild(); \ 65.129 + if (tempc) flags |= C_FLAG; \ 65.130 + else flags &= ~C_FLAG; \ 65.131 + \ 65.132 + cycles -= 6; \ 65.133 + return 0; \ 65.134 + } 65.135 + 65.136 +opBT(C, ^=) 65.137 +opBT(R, &=~) 65.138 +opBT(S, |=) 65.139 + 65.140 +static int opBA_w_a16(uint32_t fetchdat) 65.141 +{ 65.142 + int tempc, count; 65.143 + uint16_t temp; 65.144 + 65.145 + fetch_ea_16(fetchdat); 65.146 + 65.147 + temp = geteaw(); 65.148 + count = getbyte(); if (abrt) return 0; 65.149 + tempc = temp & (1 << count); 65.150 + flags_rebuild(); 65.151 + switch (rmdat & 0x38) 65.152 + { 65.153 + case 0x20: /*BT w,imm*/ 65.154 + if (tempc) flags |= C_FLAG; 65.155 + else flags &= ~C_FLAG; 65.156 + cycles -= 3; 65.157 + return 0; 65.158 + case 0x28: /*BTS w,imm*/ 65.159 + temp |= (1 << count); 65.160 + break; 65.161 + case 0x30: /*BTR w,imm*/ 65.162 + temp &= ~(1 << count); 65.163 + break; 65.164 + case 0x38: /*BTC w,imm*/ 65.165 + temp ^= (1 << count); 65.166 + break; 65.167 + 65.168 + default: 65.169 + pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38); 65.170 + pc = oldpc; 65.171 + x86illegal(); 65.172 + break; 65.173 + } 65.174 + seteaw(temp); if (abrt) return 0; 65.175 + if (tempc) flags |= C_FLAG; 65.176 + else flags &= ~C_FLAG; 65.177 + cycles -= 6; 65.178 + return 0; 65.179 +} 65.180 +static int opBA_w_a32(uint32_t fetchdat) 65.181 +{ 65.182 + int tempc, count; 65.183 + uint16_t temp; 65.184 + 65.185 + fetch_ea_32(fetchdat); 65.186 + 65.187 + temp = geteaw(); 65.188 + count = getbyte(); if (abrt) return 0; 65.189 + tempc = temp & (1 << count); 65.190 + flags_rebuild(); 65.191 + switch (rmdat & 0x38) 65.192 + { 65.193 + case 0x20: /*BT w,imm*/ 65.194 + if (tempc) flags |= C_FLAG; 65.195 + else flags &= ~C_FLAG; 65.196 + cycles -= 3; 65.197 + return 0; 65.198 + case 0x28: /*BTS w,imm*/ 65.199 + temp |= (1 << count); 65.200 + break; 65.201 + case 0x30: /*BTR w,imm*/ 65.202 + temp &= ~(1 << count); 65.203 + break; 65.204 + case 0x38: /*BTC w,imm*/ 65.205 + temp ^= (1 << count); 65.206 + break; 65.207 + 65.208 + default: 65.209 + pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38); 65.210 + pc = oldpc; 65.211 + x86illegal(); 65.212 + break; 65.213 + } 65.214 + seteaw(temp); if (abrt) return 0; 65.215 + if (tempc) flags |= C_FLAG; 65.216 + else flags &= ~C_FLAG; 65.217 + cycles -= 6; 65.218 + return 0; 65.219 +} 65.220 + 65.221 +static int opBA_l_a16(uint32_t fetchdat) 65.222 +{ 65.223 + int tempc, count; 65.224 + uint32_t temp; 65.225 + 65.226 + fetch_ea_16(fetchdat); 65.227 + 65.228 + temp = geteal(); 65.229 + count = getbyte(); if (abrt) return 0; 65.230 + tempc = temp & (1 << count); 65.231 + flags_rebuild(); 65.232 + switch (rmdat & 0x38) 65.233 + { 65.234 + case 0x20: /*BT w,imm*/ 65.235 + if (tempc) flags |= C_FLAG; 65.236 + else flags &= ~C_FLAG; 65.237 + cycles -= 3; 65.238 + return 0; 65.239 + case 0x28: /*BTS w,imm*/ 65.240 + temp |= (1 << count); 65.241 + break; 65.242 + case 0x30: /*BTR w,imm*/ 65.243 + temp &= ~(1 << count); 65.244 + break; 65.245 + case 0x38: /*BTC w,imm*/ 65.246 + temp ^= (1 << count); 65.247 + break; 65.248 + 65.249 + default: 65.250 + pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38); 65.251 + pc = oldpc; 65.252 + x86illegal(); 65.253 + break; 65.254 + } 65.255 + seteal(temp); if (abrt) return 0; 65.256 + if (tempc) flags |= C_FLAG; 65.257 + else flags &= ~C_FLAG; 65.258 + cycles -= 6; 65.259 + return 0; 65.260 +} 65.261 +static int opBA_l_a32(uint32_t fetchdat) 65.262 +{ 65.263 + int tempc, count; 65.264 + uint32_t temp; 65.265 + 65.266 + fetch_ea_32(fetchdat); 65.267 + 65.268 + temp = geteal(); 65.269 + count = getbyte(); if (abrt) return 0; 65.270 + tempc = temp & (1 << count); 65.271 + flags_rebuild(); 65.272 + switch (rmdat & 0x38) 65.273 + { 65.274 + case 0x20: /*BT w,imm*/ 65.275 + if (tempc) flags |= C_FLAG; 65.276 + else flags &= ~C_FLAG; 65.277 + cycles -= 3; 65.278 + return 0; 65.279 + case 0x28: /*BTS w,imm*/ 65.280 + temp |= (1 << count); 65.281 + break; 65.282 + case 0x30: /*BTR w,imm*/ 65.283 + temp &= ~(1 << count); 65.284 + break; 65.285 + case 0x38: /*BTC w,imm*/ 65.286 + temp ^= (1 << count); 65.287 + break; 65.288 + 65.289 + default: 65.290 + pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38); 65.291 + pc = oldpc; 65.292 + x86illegal(); 65.293 + break; 65.294 + } 65.295 + seteal(temp); if (abrt) return 0; 65.296 + if (tempc) flags |= C_FLAG; 65.297 + else flags &= ~C_FLAG; 65.298 + cycles -= 6; 65.299 + return 0; 65.300 +}
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 66.2 +++ b/src/x86_ops_bitscan.h Mon May 27 19:56:33 2013 +0100 66.3 @@ -0,0 +1,117 @@ 66.4 +#define BS_common(start, end, dir, dest, time) \ 66.5 + flags_rebuild(); \ 66.6 + if (temp) \ 66.7 + { \ 66.8 + int c; \ 66.9 + flags &= ~Z_FLAG; \ 66.10 + for (c = start; c != end; c += dir) \ 66.11 + { \ 66.12 + cycles -= time; \ 66.13 + if (temp & (1 << c)) \ 66.14 + { \ 66.15 + dest = c; \ 66.16 + break; \ 66.17 + } \ 66.18 + } \ 66.19 + } \ 66.20 + else \ 66.21 + flags |= Z_FLAG; 66.22 + 66.23 +static int opBSF_w_a16(uint32_t fetchdat) 66.24 +{ 66.25 + uint16_t temp; 66.26 + 66.27 + fetch_ea_16(fetchdat); 66.28 + temp = geteaw(); if (abrt) return 0; 66.29 + 66.30 + BS_common(0, 16, 1, regs[reg].w, (is486) ? 1 : 3); 66.31 + 66.32 + cycles -= (is486) ? 6 : 10; 66.33 + return 0; 66.34 +} 66.35 +static int opBSF_w_a32(uint32_t fetchdat) 66.36 +{ 66.37 + uint16_t temp; 66.38 + 66.39 + fetch_ea_32(fetchdat); 66.40 + temp = geteaw(); if (abrt) return 0; 66.41 + 66.42 + BS_common(0, 16, 1, regs[reg].w, (is486) ? 1 : 3); 66.43 + 66.44 + cycles -= (is486) ? 6 : 10; 66.45 + return 0; 66.46 +} 66.47 +static int opBSF_l_a16(uint32_t fetchdat) 66.48 +{ 66.49 + uint32_t temp; 66.50 + 66.51 + fetch_ea_16(fetchdat); 66.52 + temp = geteal(); if (abrt) return 0; 66.53 + 66.54 + BS_common(0, 32, 1, regs[reg].l, (is486) ? 1 : 3); 66.55 + 66.56 + cycles -= (is486) ? 6 : 10; 66.57 + return 0; 66.58 +} 66.59 +static int opBSF_l_a32(uint32_t fetchdat) 66.60 +{ 66.61 + uint32_t temp; 66.62 + 66.63 + fetch_ea_32(fetchdat); 66.64 + temp = geteal(); if (abrt) return 0; 66.65 + 66.66 + BS_common(0, 32, 1, regs[reg].l, (is486) ? 1 : 3); 66.67 + 66.68 + cycles -= (is486) ? 6 : 10; 66.69 + return 0; 66.70 +} 66.71 + 66.72 +static int opBSR_w_a16(uint32_t fetchdat) 66.73 +{ 66.74 + uint16_t temp; 66.75 + 66.76 + fetch_ea_16(fetchdat); 66.77 + temp = geteaw(); if (abrt) return 0; 66.78 + 66.79 + BS_common(15, -1, -1, regs[reg].w, 3); 66.80 + 66.81 + cycles -= (is486) ? 6 : 10; 66.82 + return 0; 66.83 +} 66.84 +static int opBSR_w_a32(uint32_t fetchdat) 66.85 +{ 66.86 + uint16_t temp; 66.87 + 66.88 + fetch_ea_32(fetchdat); 66.89 + temp = geteaw(); if (abrt) return 0; 66.90 + 66.91 + BS_common(15, -1, -1, regs[reg].w, 3); 66.92 + 66.93 + cycles -= (is486) ? 6 : 10; 66.94 + return 0; 66.95 +} 66.96 +static int opBSR_l_a16(uint32_t fetchdat) 66.97 +{ 66.98 + uint32_t temp; 66.99 + 66.100 + fetch_ea_16(fetchdat); 66.101 + temp = geteal(); if (abrt) return 0; 66.102 + 66.103 + BS_common(31, -1, -1, regs[reg].l, 3); 66.104 + 66.105 + cycles -= (is486) ? 6 : 10; 66.106 + return 0; 66.107 +} 66.108 +static int opBSR_l_a32(uint32_t fetchdat) 66.109 +{ 66.110 + uint32_t temp; 66.111 + 66.112 + fetch_ea_32(fetchdat); 66.113 + temp = geteal(); if (abrt) return 0; 66.114 + 66.115 + BS_common(31, -1, -1, regs[reg].l, 3); 66.116 + 66.117 + cycles -= (is486) ? 6 : 10; 66.118 + return 0; 66.119 +} 66.120 +
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/src/x86_ops_call.h Mon May 27 19:56:33 2013 +0100 67.3 @@ -0,0 +1,366 @@ 67.4 +#define CALL_FAR_w(new_seg, new_pc) \ 67.5 + old_cs = CS; \ 67.6 + old_pc = pc; \ 67.7 + if (ssegs) ss = oldss; \ 67.8 + oxpc = pc; \ 67.9 + pc = new_pc; \ 67.10 + optype = CALL; \ 67.11 + cgate16 = cgate32 = 0; \ 67.12 + if (msw & 1) loadcscall(new_seg); \ 67.13 + else loadcs(new_seg); \ 67.14 + optype = 0; \ 67.15 + if (abrt) { cgate16 = cgate32 = 0; return 0; } \ 67.16 + oldss = ss; \ 67.17 + if (cgate32) \ 67.18 + { \ 67.19 + PUSH_L(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 0; } \ 67.20 + PUSH_L(old_pc); \ 67.21 + } \ 67.22 + else \ 67.23 + { \ 67.24 + PUSH_W(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 0; } \ 67.25 + PUSH_W(old_pc); \ 67.26 + } 67.27 + 67.28 +#define CALL_FAR_l(new_seg, new_pc) \ 67.29 + old_cs = CS; \ 67.30 + old_pc = pc; \ 67.31 + if (ssegs) ss = oldss; \ 67.32 + oxpc = pc; \ 67.33 + pc = new_pc; \ 67.34 + optype = CALL; \ 67.35 + cgate16 = cgate32 = 0; \ 67.36 + if (msw & 1) loadcscall(new_seg); \ 67.37 + else loadcs(new_seg); \ 67.38 + optype = 0; \ 67.39 + if (abrt) { cgate16 = cgate32 = 0; return 0; } \ 67.40 + oldss = ss; \ 67.41 + if (cgate16) \ 67.42 + { \ 67.43 + PUSH_W(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 0; } \ 67.44 + PUSH_W(old_pc); \ 67.45 + } \ 67.46 + else \ 67.47 + { \ 67.48 + PUSH_L(old_cs); if (abrt) { cgate16 = cgate32 = 0; return 0; } \ 67.49 + PUSH_L(old_pc); \ 67.50 + } 67.51 + 67.52 + 67.53 +#define CALL_FAR_nr(new_seg, new_pc) \ 67.54 + old_cs = CS; \ 67.55 + old_pc = pc; \ 67.56 + if (ssegs) ss = oldss; \ 67.57 + oxpc = pc; \ 67.58 + pc = new_pc; \ 67.59 + optype = CALL; \ 67.60 + cgate16 = cgate32 = 0; \ 67.61 + if (msw & 1) loadcscall(new_seg); \ 67.62 + else loadcs(new_seg); \ 67.63 + optype = 0; \ 67.64 + if (abrt) { cgate16 = cgate32 = 0; break; } \ 67.65 + oldss = ss; \ 67.66 + if (cgate32) \ 67.67 + { \ 67.68 + PUSH_L(old_cs); if (abrt) { cgate16 = cgate32 = 0; break; } \ 67.69 + PUSH_L(old_pc); \ 67.70 + } \ 67.71 + else \ 67.72 + { \ 67.73 + PUSH_W(old_cs); if (abrt) { cgate16 = cgate32 = 0; break; } \ 67.74 + PUSH_W(old_pc); \ 67.75 + } \ 67.76 + 67.77 +static int opCALL_far_w(uint32_t fetchdat) 67.78 +{ 67.79 + uint32_t old_cs, old_pc; 67.80 + uint16_t new_cs, new_pc; 67.81 + 67.82 + new_pc = getwordf(); 67.83 + new_cs = getword(); if (abrt) return 0; 67.84 + 67.85 + CALL_FAR_w(new_cs, new_pc); 67.86 + 67.87 + cycles -= is486 ? 18 : 17; 67.88 + return 0; 67.89 +} 67.90 +static int opCALL_far_l(uint32_t fetchdat) 67.91 +{ 67.92 + uint32_t old_cs, old_pc; 67.93 + uint32_t new_cs, new_pc; 67.94 + 67.95 + new_pc = getlong(); 67.96 + new_cs = getword(); if (abrt) return 0; 67.97 + 67.98 + CALL_FAR_l(new_cs, new_pc); 67.99 + 67.100 + cycles -= is486 ? 18 : 17; 67.101 + return 0; 67.102 +} 67.103 + 67.104 + 67.105 +static int opFF_w_a16(uint32_t fetchdat) 67.106 +{ 67.107 + uint16_t old_cs, new_cs; 67.108 + uint32_t old_pc, new_pc; 67.109 + 67.110 + uint16_t temp; 67.111 + 67.112 + fetch_ea_16(fetchdat); 67.113 + 67.114 + switch (rmdat & 0x38) 67.115 + { 67.116 + case 0x00: /*INC w*/ 67.117 + temp = geteaw(); if (abrt) return 0; 67.118 + seteaw(temp + 1); if (abrt) return 0; 67.119 + setadd16nc(temp, 1); 67.120 + cycles -= (mod == 3) ? timing_rr : timing_mm; 67.121 + break; 67.122 + case 0x08: /*DEC w*/ 67.123 + temp = geteaw(); if (abrt) return 0; 67.124 + seteaw(temp - 1); if (abrt) return 0; 67.125 + setsub16nc(temp, 1); 67.126 + cycles -= (mod == 3) ? timing_rr : timing_mm; 67.127 + break; 67.128 + case 0x10: /*CALL*/ 67.129 + new_pc = geteaw(); if (abrt) return 0; 67.130 + if (ssegs) ss = oldss; 67.131 + PUSH_W(pc); 67.132 + pc = new_pc; 67.133 + if (is486) cycles -= 5; 67.134 + else cycles -= ((mod == 3) ? 7 : 10); 67.135 + break; 67.136 + case 0x18: /*CALL far*/ 67.137 + new_pc = readmemw(easeg, eaaddr); 67.138 + new_cs = readmemw(easeg, (eaaddr + 2)); if (abrt) return 0; 67.139 + 67.140 + CALL_FAR_w(new_cs, new_pc); 67.141 + 67.142 + cycles -= is486 ? 17 : 22; 67.143 + break; 67.144 + case 0x20: /*JMP*/ 67.145 + new_pc = geteaw(); if (abrt) return 0; 67.146 + pc = new_pc; 67.147 + if (is486) cycles -= 5; 67.148 + else cycles -= ((mod == 3) ? 7 : 10); 67.149 + break; 67.150 + case 0x28: /*JMP far*/ 67.151 + oxpc = pc; 67.152 + new_pc = readmemw(easeg, eaaddr); 67.153 + new_cs = readmemw(easeg, eaaddr + 2); if (abrt) return 0; 67.154 + pc = new_pc; 67.155 + loadcsjmp(new_cs, oxpc); if (abrt) return 0; 67.156 + cycles -= is486 ? 13 : 12; 67.157 + break; 67.158 + case 0x30: /*PUSH w*/ 67.159 + temp = geteaw(); if (abrt) return 0; 67.160 + if (ssegs) ss = oldss; 67.161 + PUSH_W(temp); 67.162 + cycles -= ((mod == 3) ? 2 : 5); 67.163 + break; 67.164 + 67.165 + default: 67.166 + fatal("Bad FF opcode %02X\n",rmdat&0x38); 67.167 + x86illegal(); 67.168 + } 67.169 + return 0; 67.170 +} 67.171 +static int opFF_w_a32(uint32_t fetchdat) 67.172 +{ 67.173 + uint16_t old_cs, new_cs; 67.174 + uint32_t old_pc, new_pc; 67.175 + 67.176 + uint16_t temp; 67.177 + 67.178 + fetch_ea_32(fetchdat); 67.179 + 67.180 + switch (rmdat & 0x38) 67.181 + { 67.182 + case 0x00: /*INC w*/ 67.183 + temp = geteaw(); if (abrt) return 0; 67.184 + seteaw(temp + 1); if (abrt) return 0; 67.185 + setadd16nc(temp, 1); 67.186 + cycles -= (mod == 3) ? timing_rr : timing_mm; 67.187 + break; 67.188 + case 0x08: /*DEC w*/ 67.189 + temp = geteaw(); if (abrt) return 0; 67.190 + seteaw(temp - 1); if (abrt) return 0; 67.191 + setsub16nc(temp, 1); 67.192 + cycles -= (mod == 3) ? timing_rr : timing_mm; 67.193 + break; 67.194 + case 0x10: /*CALL*/ 67.195 + new_pc = geteaw(); if (abrt) return 0; 67.196 + if (ssegs) ss = oldss; 67.197 + PUSH_W(pc); 67.198 + pc = new_pc; 67.199 + if (is486) cycles -= 5; 67.200 + else cycles -= ((mod == 3) ? 7 : 10); 67.201 + break; 67.202 + case 0x18: /*CALL far*/ 67.203 + new_pc = readmemw(easeg, eaaddr); 67.204 + new_cs = readmemw(easeg, (eaaddr + 2)); if (abrt) return 0; 67.205 + 67.206 + CALL_FAR_w(new_cs, new_pc); 67.207 + 67.208 + cycles -= is486 ? 17 : 22; 67.209 + break; 67.210 + case 0x20: /*JMP*/ 67.211 + new_pc = geteaw(); if (abrt) return 0; 67.212 + pc = new_pc; 67.213 + if (is486) cycles -= 5; 67.214 + else cycles -= ((mod == 3) ? 7 : 10); 67.215 + break; 67.216 + case 0x28: /*JMP far*/ 67.217 + oxpc = pc; 67.218 + new_pc = readmemw(easeg, eaaddr); 67.219 + new_cs = readmemw(easeg, eaaddr + 2); if (abrt) return 0; 67.220 + pc = new_pc; 67.221 + loadcsjmp(new_cs, oxpc); if (abrt) return 0; 67.222 + cycles -= is486 ? 13 : 12; 67.223 + break; 67.224 + case 0x30: /*PUSH w*/ 67.225 + temp = geteaw(); if (abrt) return 0; 67.226 + if (ssegs) ss = oldss; 67.227 + PUSH_W(temp); 67.228 + cycles -= ((mod == 3) ? 2 : 5); 67.229 + break; 67.230 + 67.231 + default: 67.232 + fatal("Bad FF opcode %02X\n",rmdat&0x38); 67.233 + x86illegal(); 67.234 + } 67.235 + return 0; 67.236 +} 67.237 + 67.238 +static int opFF_l_a16(uint32_t fetchdat) 67.239 +{ 67.240 + uint16_t old_cs, new_cs; 67.241 + uint32_t old_pc, new_pc; 67.242 + 67.243 + uint32_t temp; 67.244 + 67.245 + fetch_ea_16(fetchdat); 67.246 + 67.247 + switch (rmdat & 0x38) 67.248 + { 67.249 + case 0x00: /*INC l*/ 67.250 + temp = geteal(); if (abrt) return 0; 67.251 + seteal(temp + 1); if (abrt) return 0; 67.252 + setadd32nc(temp, 1); 67.253 + cycles -= (mod == 3) ? timing_rr : timing_mm; 67.254 + break; 67.255 + case 0x08: /*DEC l*/ 67.256 + temp = geteal(); if (abrt) return 0; 67.257 + seteal(temp - 1); if (abrt) return 0; 67.258 + setsub32nc(temp, 1); 67.259 + cycles -= (mod == 3) ? timing_rr : timing_mm; 67.260 + break; 67.261 + case 0x10: /*CALL*/ 67.262 + new_pc = geteal(); if (abrt) return 0; 67.263 + if (ssegs) ss = oldss; 67.264 + PUSH_L(pc); 67.265 + pc = new_pc; 67.266 + if (is486) cycles -= 5; 67.267 + else cycles -= ((mod == 3) ? 7 : 10); 67.268 + break; 67.269 + case 0x18: /*CALL far*/ 67.270 + new_pc = readmeml(easeg, eaaddr); 67.271 + new_cs = readmemw(easeg, (eaaddr + 4)); if (abrt) return 0; 67.272 + 67.273 + CALL_FAR_l(new_cs, new_pc); 67.274 + 67.275 + cycles -= is486 ? 17 : 22; 67.276 + break; 67.277 + case 0x20: /*JMP*/ 67.278 + new_pc = geteal(); if (abrt) return 0; 67.279 + pc = new_pc; 67.280 + if (is486) cycles -= 5; 67.281 + else cycles -= ((mod == 3) ? 7 : 10); 67.282 + break; 67.283 + case 0x28: /*JMP far*/ 67.284 + oxpc = pc; 67.285 + new_pc = readmeml(easeg, eaaddr); 67.286 + new_cs = readmemw(easeg, eaaddr + 4); if (abrt) return 0; 67.287 + pc = new_pc; 67.288 + loadcsjmp(new_cs, oxpc); if (abrt) return 0; 67.289 + cycles -= is486 ? 13 : 12; 67.290 + break; 67.291 + case 0x30: /*PUSH l*/ 67.292 + temp = geteal(); if (abrt) return 0; 67.293 + if (ssegs) ss = oldss; 67.294 + PUSH_L(temp); 67.295 + cycles -= ((mod == 3) ? 2 : 5); 67.296 + break; 67.297 + 67.298 + default: 67.299 + fatal("Bad FF opcode %02X\n",rmdat&0x38); 67.300 + x86illegal(); 67.301 + } 67.302 + return 0; 67.303 +} 67.304 +static int opFF_l_a32(uint32_t fetchdat) 67.305 +{ 67.306 + uint16_t old_cs, new_cs; 67.307 + uint32_t old_pc, new_pc; 67.308 + 67.309 + uint32_t temp; 67.310 + 67.311 + fetch_ea_32(fetchdat); 67.312 + 67.313 + switch (rmdat & 0x38) 67.314 + { 67.315 + case 0x00: /*INC l*/ 67.316 + temp = geteal(); if (abrt) return 0; 67.317 + seteal(temp + 1); if (abrt) return 0; 67.318 + setadd32nc(temp, 1); 67.319 + cycles -= (mod == 3) ? timing_rr : timing_mm; 67.320 + break; 67.321 + case 0x08: /*DEC l*/ 67.322 + temp = geteal(); if (abrt) return 0; 67.323 + seteal(temp - 1); if (abrt) return 0; 67.324 + setsub32nc(temp, 1); 67.325 + cycles -= (mod == 3) ? timing_rr : timing_mm; 67.326 + break; 67.327 + case 0x10: /*CALL*/ 67.328 + new_pc = geteal(); if (abrt) return 0; 67.329 + if (ssegs) ss = oldss; 67.330 + PUSH_L(pc); if (abrt) return 0; 67.331 + pc = new_pc; 67.332 + if (is486) cycles -= 5; 67.333 + else cycles -= ((mod == 3) ? 7 : 10); 67.334 + break; 67.335 + case 0x18: /*CALL far*/ 67.336 + new_pc = readmeml(easeg, eaaddr); 67.337 + new_cs = readmemw(easeg, (eaaddr + 4)); if (abrt) return 0; 67.338 + 67.339 + CALL_FAR_l(new_cs, new_pc); 67.340 + 67.341 + cycles -= is486 ? 17 : 22; 67.342 + break; 67.343 + case 0x20: /*JMP*/ 67.344 + new_pc = geteal(); if (abrt) return 0; 67.345 + pc = new_pc; 67.346 + if (is486) cycles -= 5; 67.347 + else cycles -= ((mod == 3) ? 7 : 10); 67.348 + break; 67.349 + case 0x28: /*JMP far*/ 67.350 + oxpc = pc; 67.351 + new_pc = readmeml(easeg, eaaddr); 67.352 + new_cs = readmemw(easeg, eaaddr + 4); if (abrt) return 0; 67.353 + pc = new_pc; 67.354 + loadcsjmp(new_cs, oxpc); if (abrt) return 0; 67.355 + cycles -= is486 ? 13 : 12; 67.356 + break; 67.357 + case 0x30: /*PUSH l*/ 67.358 + temp = geteal(); if (abrt) return 0; 67.359 + if (ssegs) ss = oldss; 67.360 + PUSH_L(temp); 67.361 + cycles -= ((mod == 3) ? 2 : 5); 67.362 + break; 67.363 + 67.364 + default: 67.365 + fatal("Bad FF opcode %02X\n",rmdat&0x38); 67.366 + x86illegal(); 67.367 + } 67.368 + return 0; 67.369 +}
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2 +++ b/src/x86_ops_flag.h Mon May 27 19:56:33 2013 +0100 68.3 @@ -0,0 +1,178 @@ 68.4 +static int opCMC(uint32_t fetchdat) 68.5 +{ 68.6 + flags_rebuild(); 68.7 + flags ^= C_FLAG; 68.8 + cycles -= 2; 68.9 + return 0; 68.10 +} 68.11 + 68.12 + 68.13 +static int opCLC(uint32_t fetchdat) 68.14 +{ 68.15 + flags_rebuild(); 68.16 + flags &= ~C_FLAG; 68.17 + cycles -= 2; 68.18 + return 0; 68.19 +} 68.20 +static int opCLD(uint32_t fetchdat) 68.21 +{ 68.22 + flags &= ~D_FLAG; 68.23 + cycles -= 2; 68.24 + return 0; 68.25 +} 68.26 +static int opCLI(uint32_t fetchdat) 68.27 +{ 68.28 + if (!IOPLp) 68.29 + { 68.30 + x86gpf(NULL,0); 68.31 + } 68.32 + else 68.33 + flags &= ~I_FLAG; 68.34 + 68.35 + cycles -= 3; 68.36 + return 0; 68.37 +} 68.38 + 68.39 +static int opSTC(uint32_t fetchdat) 68.40 +{ 68.41 + flags_rebuild(); 68.42 + flags |= C_FLAG; 68.43 + cycles -= 2; 68.44 + return 0; 68.45 +} 68.46 +static int opSTD(uint32_t fetchdat) 68.47 +{ 68.48 + flags |= D_FLAG; 68.49 + cycles -= 2; 68.50 + return 0; 68.51 +} 68.52 +static int opSTI(uint32_t fetchdat) 68.53 +{ 68.54 + if (!IOPLp) 68.55 + { 68.56 + x86gpf(NULL,0); 68.57 + } 68.58 + else 68.59 + flags |= I_FLAG; 68.60 + 68.61 + cycles -= 2; 68.62 + return 0; 68.63 +} 68.64 + 68.65 +static int opSAHF(uint32_t fetchdat) 68.66 +{ 68.67 + flags_rebuild(); 68.68 + flags = (flags & 0xff00) | (AH & 0xd5) | 2; 68.69 + cycles -= 3; 68.70 + return 0; 68.71 +} 68.72 +static int opLAHF(uint32_t fetchdat) 68.73 +{ 68.74 + flags_rebuild(); 68.75 + AH = flags & 0xff; 68.76 + cycles -= 3; 68.77 + return 0; 68.78 +} 68.79 + 68.80 +static int opPUSHF(uint32_t fetchdat) 68.81 +{ 68.82 + if (ssegs) ss = oldss; 68.83 + if ((eflags & VM_FLAG) && (IOPL < 3)) 68.84 + { 68.85 + x86gpf(NULL,0); 68.86 + return 0; 68.87 + } 68.88 + flags_rebuild(); 68.89 + PUSH_W(flags); 68.90 + cycles -= 4; 68.91 + return 0; 68.92 +} 68.93 +static int opPUSHFD(uint32_t fetchdat) 68.94 +{ 68.95 + uint16_t tempw; 68.96 + if (ssegs) ss=oldss; 68.97 + if ((eflags & VM_FLAG) && (IOPL < 3)) 68.98 + { 68.99 + x86gpf(NULL, 0); 68.100 + return 0; 68.101 + } 68.102 + if (CPUID) tempw = eflags & 0x24; 68.103 + else tempw = eflags & 4; 68.104 + flags_rebuild(); 68.105 + PUSH_L(flags | (tempw << 16)); 68.106 + cycles -= 4; 68.107 + return 0; 68.108 +} 68.109 + 68.110 +static int opPOPF_286(uint32_t fetchdat) 68.111 +{ 68.112 + uint16_t tempw; 68.113 + if (ssegs) ss = oldss; 68.114 + 68.115 + if ((eflags & VM_FLAG) && (IOPL < 3)) 68.116 + { 68.117 + x86gpf(NULL, 0); 68.118 + return 0; 68.119 + } 68.120 + 68.121 + tempw = POP_W(); if (abrt) return 0; 68.122 + 68.123 + pclog("POPF_286 %04X:%04X %04X\n", CS, pc, tempw); 68.124 + if (!(msw & 1)) flags = (flags & 0x7000) | (tempw & 0x0fd5) | 2; 68.125 + else if (!(CPL)) flags = (tempw & 0x7fd5) | 2; 68.126 + else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2; 68.127 + else flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2; 68.128 + flags_extract(); 68.129 + 68.130 + cycles -= 5; 68.131 + return 0; 68.132 +} 68.133 +static int opPOPF(uint32_t fetchdat) 68.134 +{ 68.135 + uint16_t tempw; 68.136 + if (ssegs) ss = oldss; 68.137 + 68.138 + if ((eflags & VM_FLAG) && (IOPL < 3)) 68.139 + { 68.140 + x86gpf(NULL, 0); 68.141 + return 0; 68.142 + } 68.143 + 68.144 + tempw = POP_W(); if (abrt) return 0; 68.145 + 68.146 + if (!(CPL) || !(msw & 1)) flags = (tempw & 0xffd5) | 2; 68.147 + else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0xcfd5) | 2; 68.148 + else flags = (flags & 0x3200) | (tempw & 0xcdd5) | 2; 68.149 + flags_extract(); 68.150 + 68.151 + cycles -= 5; 68.152 + return 0; 68.153 +} 68.154 +static int opPOPFD(uint32_t fetchdat) 68.155 +{ 68.156 + uint32_t templ; 68.157 + if (ssegs) ss = oldss; 68.158 + 68.159 + if ((eflags & VM_FLAG) && (IOPL < 3)) 68.160 + { 68.161 + x86gpf(NULL, 0); 68.162 + return 0; 68.163 + } 68.164 + 68.165 + templ = POP_L(); if (abrt) return 0; 68.166 + 68.167 + if (!(CPL) || !(msw & 1)) flags = (templ & 0xffd5) | 2; 68.168 + else if (IOPLp) flags = (flags & 0x3000) | (templ & 0xcfd5) | 2; 68.169 + else flags = (flags & 0x3200) | (templ & 0xcdd5) | 2; 68.170 + 68.171 + templ &= is486 ? 0x240000 : 0; 68.172 + templ |= ((eflags&3) << 16); 68.173 + if (CPUID) eflags = (templ >> 16) & 0x27; 68.174 + else if (is486) eflags = (templ >> 16) & 7; 68.175 + else eflags = (templ >> 16) & 3; 68.176 + 68.177 + flags_extract(); 68.178 + 68.179 + cycles -= 5; 68.180 + return 0; 68.181 +}
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/src/x86_ops_fpu.h Mon May 27 19:56:33 2013 +0100 69.3 @@ -0,0 +1,60 @@ 69.4 +#define opESCAPE(num) \ 69.5 + static int opESCAPE_ ## num ##_a16(uint32_t fetchdat) \ 69.6 + { \ 69.7 + flags_rebuild(); \ 69.8 + if ((cr0 & 6) == 4) \ 69.9 + { \ 69.10 + x86_int(7); \ 69.11 + } \ 69.12 + else \ 69.13 + { \ 69.14 + fpucount++; \ 69.15 + fetch_ea_16(fetchdat); \ 69.16 + if (hasfpu) \ 69.17 + { \ 69.18 + x87_pc_off = oldpc; \ 69.19 + x87_pc_seg = CS; \ 69.20 + x87_op_off = eaaddr; \ 69.21 + x87_op_seg = ea_rseg; \ 69.22 + x87_ ## num(); \ 69.23 + } \ 69.24 + } \ 69.25 + return 0; \ 69.26 + } \ 69.27 + static int opESCAPE_ ## num ## _a32(uint32_t fetchdat) \ 69.28 + { \ 69.29 + flags_rebuild(); \ 69.30 + if ((cr0 & 6) == 4) \ 69.31 + { \ 69.32 + x86_int(7); \ 69.33 + } \ 69.34 + else \ 69.35 + { \ 69.36 + fpucount++; \ 69.37 + fetch_ea_32(fetchdat); \ 69.38 + if (hasfpu) \ 69.39 + { \ 69.40 + x87_pc_off = oldpc; \ 69.41 + x87_pc_seg = CS; \ 69.42 + x87_op_off = eaaddr; \ 69.43 + x87_op_seg = ea_rseg; \ 69.44 + x87_ ## num(); \ 69.45 + } \ 69.46 + } \ 69.47 + return 0; \ 69.48 + } 69.49 + 69.50 +opESCAPE(d8); 69.51 +opESCAPE(d9); 69.52 +opESCAPE(da); 69.53 +opESCAPE(db); 69.54 +opESCAPE(dc); 69.55 +opESCAPE(dd); 69.56 +opESCAPE(de); 69.57 +opESCAPE(df); 69.58 + 69.59 +static int opWAIT(uint32_t fetchdat) 69.60 +{ 69.61 + cycles -= 4; 69.62 + return 0; 69.63 +}
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 70.2 +++ b/src/x86_ops_inc_dec.h Mon May 27 19:56:33 2013 +0100 70.3 @@ -0,0 +1,86 @@ 70.4 +#define INC_DEC_OP(name, reg, inc, setflags) \ 70.5 + static int op ## name (uint32_t fetchdat) \ 70.6 + { \ 70.7 + setflags(reg, 1); \ 70.8 + reg += inc; \ 70.9 + cycles -= timing_rr; \ 70.10 + return 0; \ 70.11 + } 70.12 + 70.13 +INC_DEC_OP(INC_AX, AX, 1, setadd16nc) 70.14 +INC_DEC_OP(INC_BX, BX, 1, setadd16nc) 70.15 +INC_DEC_OP(INC_CX, CX, 1, setadd16nc) 70.16 +INC_DEC_OP(INC_DX, DX, 1, setadd16nc) 70.17 +INC_DEC_OP(INC_SI, SI, 1, setadd16nc) 70.18 +INC_DEC_OP(INC_DI, DI, 1, setadd16nc) 70.19 +INC_DEC_OP(INC_BP, BP, 1, setadd16nc) 70.20 +INC_DEC_OP(INC_SP, SP, 1, setadd16nc) 70.21 + 70.22 +INC_DEC_OP(INC_EAX, EAX, 1, setadd32nc) 70.23 +INC_DEC_OP(INC_EBX, EBX, 1, setadd32nc) 70.24 +INC_DEC_OP(INC_ECX, ECX, 1, setadd32nc) 70.25 +INC_DEC_OP(INC_EDX, EDX, 1, setadd32nc) 70.26 +INC_DEC_OP(INC_ESI, ESI, 1, setadd32nc) 70.27 +INC_DEC_OP(INC_EDI, EDI, 1, setadd32nc) 70.28 +INC_DEC_OP(INC_EBP, EBP, 1, setadd32nc) 70.29 +INC_DEC_OP(INC_ESP, ESP, 1, setadd32nc) 70.30 + 70.31 +INC_DEC_OP(DEC_AX, AX, -1, setsub16nc) 70.32 +INC_DEC_OP(DEC_BX, BX, -1, setsub16nc) 70.33 +INC_DEC_OP(DEC_CX, CX, -1, setsub16nc) 70.34 +INC_DEC_OP(DEC_DX, DX, -1, setsub16nc) 70.35 +INC_DEC_OP(DEC_SI, SI, -1, setsub16nc) 70.36 +INC_DEC_OP(DEC_DI, DI, -1, setsub16nc) 70.37 +INC_DEC_OP(DEC_BP, BP, -1, setsub16nc) 70.38 +INC_DEC_OP(DEC_SP, SP, -1, setsub16nc) 70.39 + 70.40 +INC_DEC_OP(DEC_EAX, EAX, -1, setsub32nc) 70.41 +INC_DEC_OP(DEC_EBX, EBX, -1, setsub32nc) 70.42 +INC_DEC_OP(DEC_ECX, ECX, -1, setsub32nc) 70.43 +INC_DEC_OP(DEC_EDX, EDX, -1, setsub32nc) 70.44 +INC_DEC_OP(DEC_ESI, ESI, -1, setsub32nc) 70.45 +INC_DEC_OP(DEC_EDI, EDI, -1, setsub32nc) 70.46 +INC_DEC_OP(DEC_EBP, EBP, -1, setsub32nc) 70.47 +INC_DEC_OP(DEC_ESP, ESP, -1, setsub32nc) 70.48 + 70.49 + 70.50 +static int opINCDEC_b_a16(uint32_t fetchdat) 70.51 +{ 70.52 + uint8_t temp; 70.53 + 70.54 + fetch_ea_16(fetchdat); 70.55 + temp=geteab(); if (abrt) return 0; 70.56 + 70.57 + if (rmdat&0x38) 70.58 + { 70.59 + seteab(temp - 1); if (abrt) return 0; 70.60 + setsub8nc(temp, 1); 70.61 + } 70.62 + else 70.63 + { 70.64 + seteab(temp + 1); if (abrt) return 0; 70.65 + setadd8nc(temp, 1); 70.66 + } 70.67 + cycles -= (mod == 3) ? timing_rr : timing_mm; 70.68 + return 0; 70.69 +} 70.70 +static int opINCDEC_b_a32(uint32_t fetchdat) 70.71 +{ 70.72 + uint8_t temp; 70.73 + 70.74 + fetch_ea_32(fetchdat); 70.75 + temp=geteab(); if (abrt) return 0; 70.76 + 70.77 + if (rmdat&0x38) 70.78 + { 70.79 + seteab(temp - 1); if (abrt) return 0; 70.80 + setsub8nc(temp, 1); 70.81 + } 70.82 + else 70.83 + { 70.84 + seteab(temp + 1); if (abrt) return 0; 70.85 + setadd8nc(temp, 1); 70.86 + } 70.87 + cycles -= (mod == 3) ? timing_rr : timing_mm; 70.88 + return 0; 70.89 +}
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 71.2 +++ b/src/x86_ops_int.h Mon May 27 19:56:33 2013 +0100 71.3 @@ -0,0 +1,46 @@ 71.4 +static int opINT3(uint32_t fetchdat) 71.5 +{ 71.6 + oldpc = pc; 71.7 + //fatal("INT3\n"); 71.8 + if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) 71.9 + { 71.10 + x86gpf(NULL,0); 71.11 + return 0; 71.12 + } 71.13 + x86_int_sw(3); 71.14 + cycles -= (is486) ? 44 : 59; 71.15 + return 0; 71.16 +} 71.17 + 71.18 +static int opINT(uint32_t fetchdat) 71.19 +{ 71.20 + uint8_t temp; 71.21 + 71.22 + /*if (msw&1) pclog("INT %i %i %i\n",cr0&1,eflags&VM_FLAG,IOPL);*/ 71.23 + if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) 71.24 + { 71.25 + x86gpf(NULL,0); 71.26 + return 0; 71.27 + } 71.28 + temp = getbytef(); 71.29 + if (temp == 0x10 && AH == 0xe) pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc); 71.30 + x86_int_sw(temp); 71.31 + return 0; 71.32 +} 71.33 + 71.34 +static int opINTO(uint32_t fetchdat) 71.35 +{ 71.36 + if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) 71.37 + { 71.38 + x86gpf(NULL,0); 71.39 + return 0; 71.40 + } 71.41 + if (VF_SET()) 71.42 + { 71.43 + oldpc = pc; 71.44 + x86_int_sw(4); 71.45 + } 71.46 + cycles -= 3; 71.47 + return 0; 71.48 +} 71.49 +
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 72.2 +++ b/src/x86_ops_io.h Mon May 27 19:56:33 2013 +0100 72.3 @@ -0,0 +1,110 @@ 72.4 +int opIN_AL_imm(uint32_t fetchdat) 72.5 +{ 72.6 + uint16_t port = (uint16_t)getbytef(); 72.7 + check_io_perm(port); 72.8 + AL = inb(port); 72.9 + cycles -= 12; 72.10 + return 0; 72.11 +} 72.12 +int opIN_AX_imm(uint32_t fetchdat) 72.13 +{ 72.14 + uint16_t port = (uint16_t)getbytef(); 72.15 + check_io_perm(port); 72.16 + check_io_perm(port + 1); 72.17 + AX = inw(port); 72.18 + cycles -= 12; 72.19 + return 0; 72.20 +} 72.21 +int opIN_EAX_imm(uint32_t fetchdat) 72.22 +{ 72.23 + uint16_t port = (uint16_t)getbytef(); 72.24 + check_io_perm(port); 72.25 + check_io_perm(port + 1); 72.26 + check_io_perm(port + 2); 72.27 + check_io_perm(port + 3); 72.28 + EAX = inl(port); 72.29 + cycles -= 12; 72.30 + return 0; 72.31 +} 72.32 + 72.33 +int opOUT_AL_imm(uint32_t fetchdat) 72.34 +{ 72.35 + uint16_t port = (uint16_t)getbytef(); 72.36 + check_io_perm(port); 72.37 + outb(port, AL); 72.38 + cycles -= 10; 72.39 + return 0; 72.40 +} 72.41 +int opOUT_AX_imm(uint32_t fetchdat) 72.42 +{ 72.43 + uint16_t port = (uint16_t)getbytef(); 72.44 + check_io_perm(port); 72.45 + check_io_perm(port + 1); 72.46 + outw(port, AX); 72.47 + cycles -= 10; 72.48 + return 0; 72.49 +} 72.50 +int opOUT_EAX_imm(uint32_t fetchdat) 72.51 +{ 72.52 + uint16_t port = (uint16_t)getbytef(); 72.53 + check_io_perm(port); 72.54 + check_io_perm(port + 1); 72.55 + check_io_perm(port + 2); 72.56 + check_io_perm(port + 3); 72.57 + outl(port, EAX); 72.58 + cycles -= 10; 72.59 + return 0; 72.60 +} 72.61 + 72.62 +int opIN_AL_DX(uint32_t fetchdat) 72.63 +{ 72.64 + check_io_perm(DX); 72.65 + AL = inb(DX); 72.66 + cycles -= 12; 72.67 + return 0; 72.68 +} 72.69 +int opIN_AX_DX(uint32_t fetchdat) 72.70 +{ 72.71 + check_io_perm(DX); 72.72 + check_io_perm(DX + 1); 72.73 + AX = inw(DX); 72.74 + cycles -= 12; 72.75 + return 0; 72.76 +} 72.77 +int opIN_EAX_DX(uint32_t fetchdat) 72.78 +{ 72.79 + check_io_perm(DX); 72.80 + check_io_perm(DX + 1); 72.81 + check_io_perm(DX + 2); 72.82 + check_io_perm(DX + 3); 72.83 + EAX = inl(DX); 72.84 + cycles -= 12; 72.85 + return 0; 72.86 +} 72.87 + 72.88 +int opOUT_AL_DX(uint32_t fetchdat) 72.89 +{ 72.90 + check_io_perm(DX); 72.91 + outb(DX, AL); 72.92 + cycles -= 11; 72.93 + return 0; 72.94 +} 72.95 +int opOUT_AX_DX(uint32_t fetchdat) 72.96 +{ 72.97 + //pclog("OUT_AX_DX %04X %04X\n", DX, AX); 72.98 + check_io_perm(DX); 72.99 + check_io_perm(DX + 1); 72.100 + outw(DX, AX); 72.101 + cycles -= 11; 72.102 + return 0; 72.103 +} 72.104 +int opOUT_EAX_DX(uint32_t fetchdat) 72.105 +{ 72.106 + check_io_perm(DX); 72.107 + check_io_perm(DX + 1); 72.108 + check_io_perm(DX + 2); 72.109 + check_io_perm(DX + 3); 72.110 + outl(DX, EAX); 72.111 + cycles -= 11; 72.112 + return 0; 72.113 +}
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2 +++ b/src/x86_ops_jump.h Mon May 27 19:56:33 2013 +0100 73.3 @@ -0,0 +1,268 @@ 73.4 +#define cond_O ( VF_SET()) 73.5 +#define cond_NO (!VF_SET()) 73.6 +#define cond_B ( CF_SET()) 73.7 +#define cond_NB (!CF_SET()) 73.8 +#define cond_E ( ZF_SET()) 73.9 +#define cond_NE (!ZF_SET()) 73.10 +#define cond_BE ( CF_SET() || ZF_SET()) 73.11 +#define cond_NBE (!CF_SET() && !ZF_SET()) 73.12 +#define cond_S ( NF_SET()) 73.13 +#define cond_NS (!NF_SET()) 73.14 +#define cond_P ( PF_SET()) 73.15 +#define cond_NP (!PF_SET()) 73.16 +#define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0)) 73.17 +#define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0)) 73.18 +#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET())) 73.19 +#define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET())) 73.20 + 73.21 +#define opJ(condition) \ 73.22 + static int opJ ## condition(uint32_t fetchdat) \ 73.23 + { \ 73.24 + int8_t offset = (int8_t)getbytef(); \ 73.25 + if (cond_ ## condition) \ 73.26 + { \ 73.27 + pc += offset; \ 73.28 + cycles -= timing_bt; \ 73.29 + } \ 73.30 + cycles -= timing_bnt; \ 73.31 + return 0; \ 73.32 + } \ 73.33 + \ 73.34 + static int opJ ## condition ## _w(uint32_t fetchdat) \ 73.35 + { \ 73.36 + int16_t offset = (int16_t)getwordf(); \ 73.37 + if (cond_ ## condition) \ 73.38 + { \ 73.39 + pc += offset; \ 73.40 + cycles -= timing_bt; \ 73.41 + } \ 73.42 + cycles -= timing_bnt; \ 73.43 + return 0; \ 73.44 + } \ 73.45 + \ 73.46 + static int opJ ## condition ## _l(uint32_t fetchdat) \ 73.47 + { \ 73.48 + uint32_t offset = getlong(); \ 73.49 + if (cond_ ## condition) \ 73.50 + { \ 73.51 + pc += offset; \ 73.52 + cycles -= timing_bt; \ 73.53 + } \ 73.54 + cycles -= timing_bnt; \ 73.55 + return 0; \ 73.56 + } \ 73.57 + 73.58 +opJ(O) 73.59 +opJ(NO) 73.60 +opJ(B) 73.61 +opJ(NB) 73.62 +opJ(E) 73.63 +opJ(NE) 73.64 +opJ(BE) 73.65 +opJ(NBE) 73.66 +opJ(S) 73.67 +opJ(NS) 73.68 +opJ(P) 73.69 +opJ(NP) 73.70 +opJ(L) 73.71 +opJ(NL) 73.72 +opJ(LE) 73.73 +opJ(NLE) 73.74 + 73.75 + 73.76 + 73.77 +static int opLOOPNE_w(uint32_t fetchdat) 73.78 +{ 73.79 + int8_t offset = (int8_t)getbytef(); 73.80 + CX--; 73.81 + if (CX && !ZF_SET()) 73.82 + pc += offset; 73.83 + cycles -= (is486) ? 7 : 11; 73.84 + return 0; 73.85 +} 73.86 +static int opLOOPNE_l(uint32_t fetchdat) 73.87 +{ 73.88 + int8_t offset = (int8_t)getbytef(); 73.89 + ECX--; 73.90 + if (ECX && !ZF_SET()) 73.91 + pc += offset; 73.92 + cycles -= (is486) ? 7 : 11; 73.93 + return 0; 73.94 +} 73.95 + 73.96 +static int opLOOPE_w(uint32_t fetchdat) 73.97 +{ 73.98 + int8_t offset = (int8_t)getbytef(); 73.99 + CX--; 73.100 + if (CX && ZF_SET()) 73.101 + pc += offset; 73.102 + cycles -= (is486) ? 7 : 11; 73.103 + return 0; 73.104 +} 73.105 +static int opLOOPE_l(uint32_t fetchdat) 73.106 +{ 73.107 + int8_t offset = (int8_t)getbytef(); 73.108 + ECX--; 73.109 + if (ECX && ZF_SET()) 73.110 + pc += offset; 73.111 + cycles -= (is486) ? 7 : 11; 73.112 + return 0; 73.113 +} 73.114 + 73.115 +static int opLOOP_w(uint32_t fetchdat) 73.116 +{ 73.117 + int8_t offset = (int8_t)getbytef(); 73.118 + CX--; 73.119 + if (CX) 73.120 + pc += offset; 73.121 + cycles -= (is486) ? 7 : 11; 73.122 + return 0; 73.123 +} 73.124 +static int opLOOP_l(uint32_t fetchdat) 73.125 +{ 73.126 + int8_t offset = (int8_t)getbytef(); 73.127 + ECX--; 73.128 + if (ECX) 73.129 + pc += offset; 73.130 + cycles -= (is486) ? 7 : 11; 73.131 + return 0; 73.132 +} 73.133 + 73.134 +static int opJCXZ(uint32_t fetchdat) 73.135 +{ 73.136 + int8_t offset = (int8_t)getbytef(); 73.137 + if (!CX) 73.138 + { 73.139 + pc += offset; 73.140 + cycles -= 4; 73.141 + } 73.142 + cycles -= 5; 73.143 + return 0; 73.144 +} 73.145 +static int opJECXZ(uint32_t fetchdat) 73.146 +{ 73.147 + int8_t offset = (int8_t)getbytef(); 73.148 + if (!ECX) 73.149 + { 73.150 + pc += offset; 73.151 + cycles -= 4; 73.152 + } 73.153 + cycles -= 5; 73.154 + return 0; 73.155 +} 73.156 + 73.157 + 73.158 +static int opJMP_r8(uint32_t fetchdat) 73.159 +{ 73.160 + int8_t offset = (int8_t)getbytef(); 73.161 + pc += offset; 73.162 + cycles -= (is486) ? 3 : 7; 73.163 + return 0; 73.164 +} 73.165 +static int opJMP_r16(uint32_t fetchdat) 73.166 +{ 73.167 + int16_t offset = (int16_t)getwordf(); 73.168 + pc += offset; 73.169 + cycles -= (is486) ? 3 : 7; 73.170 + return 0; 73.171 +} 73.172 +static int opJMP_r32(uint32_t fetchdat) 73.173 +{ 73.174 + int32_t offset = (int32_t)getlong(); if (abrt) return 0; 73.175 + pc += offset; 73.176 + cycles -= (is486) ? 3 : 7; 73.177 + return 0; 73.178 +} 73.179 + 73.180 +static int opJMP_far_a16(uint32_t fetchdat) 73.181 +{ 73.182 + uint16_t addr = getwordf(); 73.183 + uint16_t seg = getword(); if (abrt) return 0; 73.184 + uint32_t oxpc = pc; 73.185 + pc = addr; 73.186 + loadcsjmp(seg, oxpc); 73.187 + cycles -= (is486) ? 17 : 12; 73.188 + return 0; 73.189 +} 73.190 +static int opJMP_far_a32(uint32_t fetchdat) 73.191 +{ 73.192 + uint32_t addr = getlong(); 73.193 + uint16_t seg = getword(); if (abrt) return 0; 73.194 + uint32_t oxpc = pc; 73.195 + pc = addr; 73.196 + loadcsjmp(seg, oxpc); 73.197 + cycles -= (is486) ? 17 : 12; 73.198 + return 0; 73.199 +} 73.200 + 73.201 +int opCALL_r16(uint32_t fetchdat) 73.202 +{ 73.203 + int16_t addr = (int16_t)getwordf(); 73.204 + if (ssegs) ss=oldss; 73.205 + PUSH_W(pc); 73.206 + pc += addr; 73.207 + cycles -= (is486) ? 3 : 7; 73.208 + return 0; 73.209 +} 73.210 +int opCALL_r32(uint32_t fetchdat) 73.211 +{ 73.212 + int32_t addr = getlong(); if (abrt) return 0; 73.213 + if (ssegs) ss=oldss; 73.214 + PUSH_L(pc); 73.215 + pc += addr; 73.216 + cycles -= (is486) ? 3 : 7; 73.217 + return 0; 73.218 +} 73.219 + 73.220 +int opRET_w(uint32_t fetchdat) 73.221 +{ 73.222 + uint16_t ret; 73.223 + 73.224 + if (ssegs) ss=oldss; 73.225 + ret = POP_W(); if (abrt) return 0; 73.226 + pc = ret; 73.227 + 73.228 + cycles -= (is486) ? 5 : 10; 73.229 + return 0; 73.230 +} 73.231 +int opRET_l(uint32_t fetchdat) 73.232 +{ 73.233 + uint32_t ret; 73.234 + 73.235 + if (ssegs) ss=oldss; 73.236 + ret = POP_L(); if (abrt) return 0; 73.237 + pc = ret; 73.238 + 73.239 + cycles -= (is486) ? 5 : 10; 73.240 + return 0; 73.241 +} 73.242 + 73.243 +int opRET_w_imm(uint32_t fetchdat) 73.244 +{ 73.245 + uint16_t offset = getwordf(); 73.246 + uint16_t ret; 73.247 + 73.248 + if (ssegs) ss=oldss; 73.249 + ret = POP_W(); if (abrt) return 0; 73.250 + if (stack32) ESP += offset; 73.251 + else SP += offset; 73.252 + pc = ret; 73.253 + 73.254 + cycles -= (is486) ? 5 : 10; 73.255 + return 0; 73.256 +} 73.257 +int opRET_l_imm(uint32_t fetchdat) 73.258 +{ 73.259 + uint16_t offset = getwordf(); 73.260 + uint32_t ret; 73.261 + 73.262 + if (ssegs) ss=oldss; 73.263 + ret = POP_L(); if (abrt) return 0; 73.264 + if (stack32) ESP += offset; 73.265 + else SP += offset; 73.266 + pc = ret; 73.267 + 73.268 + cycles -= (is486) ? 5 : 10; 73.269 + return 0; 73.270 +} 73.271 +
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 74.2 +++ b/src/x86_ops_misc.h Mon May 27 19:56:33 2013 +0100 74.3 @@ -0,0 +1,678 @@ 74.4 +static int opCBW(uint32_t fetchdat) 74.5 +{ 74.6 + AH = (AL & 0x80) ? 0xff : 0; 74.7 + cycles -= 3; 74.8 + return 0; 74.9 +} 74.10 +static int opCWDE(uint32_t fetchdat) 74.11 +{ 74.12 + EAX = (AX & 0x8000) ? (0xffff0000 | AX) : AX; 74.13 + cycles -= 3; 74.14 + return 0; 74.15 +} 74.16 +static int opCWD(uint32_t fetchdat) 74.17 +{ 74.18 + DX = (AX & 0x8000) ? 0xFFFF : 0; 74.19 + cycles -= 2; 74.20 + return 0; 74.21 +} 74.22 +static int opCDQ(uint32_t fetchdat) 74.23 +{ 74.24 + EDX = (EAX & 0x80000000) ? 0xffffffff : 0; 74.25 + cycles -= 2; 74.26 + return 0; 74.27 +} 74.28 + 74.29 +static int opNOP(uint32_t fetchdat) 74.30 +{ 74.31 + cycles -= (is486) ? 1 : 3; 74.32 + return 0; 74.33 +} 74.34 + 74.35 +static int opSETALC(uint32_t fetchdat) 74.36 +{ 74.37 + AL = (CF_SET()) ? 0xff : 0; 74.38 + cycles -= timing_rr; 74.39 + return 0; 74.40 +} 74.41 + 74.42 + 74.43 + 74.44 +static int opF6_a16(uint32_t fetchdat) 74.45 +{ 74.46 + int tempws, tempws2; 74.47 + uint16_t tempw, src16; 74.48 + uint8_t src, dst; 74.49 + int8_t temps; 74.50 + 74.51 + fetch_ea_16(fetchdat); 74.52 + dst = geteab(); if (abrt) return 0; 74.53 + switch (rmdat & 0x38) 74.54 + { 74.55 + case 0x00: /*TEST b,#8*/ 74.56 + src = readmemb(cs, pc); pc++; if (abrt) return 0; 74.57 + setznp8(src & dst); 74.58 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 74.59 + else cycles -= ((mod == 3) ? 2 : 5); 74.60 + break; 74.61 + case 0x10: /*NOT b*/ 74.62 + seteab(~dst); 74.63 + cycles -= (mod == 3) ? timing_rr : timing_mm; 74.64 + break; 74.65 + case 0x18: /*NEG b*/ 74.66 + setsub8(0, dst); 74.67 + seteab(0 - dst); 74.68 + cycles -= (mod == 3) ? timing_rr : timing_mm; 74.69 + break; 74.70 + case 0x20: /*MUL AL,b*/ 74.71 + AX = AL * dst; 74.72 + flags_rebuild(); 74.73 + if (AH) flags |= (C_FLAG | V_FLAG); 74.74 + else flags &= ~(C_FLAG | V_FLAG); 74.75 + cycles -= 13; 74.76 + break; 74.77 + case 0x28: /*IMUL AL,b*/ 74.78 + tempws = (int)((int8_t)AL) * (int)((int8_t)dst); 74.79 + AX = tempws & 0xffff; 74.80 + flags_rebuild(); 74.81 + if (AH && AH != 0xff) flags |= (C_FLAG | V_FLAG); 74.82 + else flags &= ~(C_FLAG | V_FLAG); 74.83 + cycles -= 14; 74.84 + break; 74.85 + case 0x30: /*DIV AL,b*/ 74.86 + src16 = AX; 74.87 + if (dst) tempw = src16 / dst; 74.88 + if (dst && !(tempw & 0xff00)) 74.89 + { 74.90 + AH = src16 % dst; 74.91 + AL = (src16 / dst) &0xff; 74.92 + if (!cpu_iscyrix) 74.93 + { 74.94 + flags_rebuild(); 74.95 + flags |= 0x8D5; /*Not a Cyrix*/ 74.96 + } 74.97 + } 74.98 + else 74.99 + { 74.100 + x86_int(0); 74.101 + } 74.102 + cycles -= is486 ? 16 : 14; 74.103 + break; 74.104 + case 0x38: /*IDIV AL,b*/ 74.105 + tempws = (int)(int16_t)AX; 74.106 + if (dst != 0) tempws2 = tempws / (int)((int8_t)dst); 74.107 + temps = tempws2 & 0xff; 74.108 + if (dst && ((int)temps == tempws2)) 74.109 + { 74.110 + AH = (tempws % (int)((int8_t)dst)) & 0xff; 74.111 + AL = tempws2 & 0xff; 74.112 + if (!cpu_iscyrix) 74.113 + { 74.114 + flags_rebuild(); 74.115 + flags|=0x8D5; /*Not a Cyrix*/ 74.116 + } 74.117 + } 74.118 + else 74.119 + { 74.120 +// pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2); 74.121 + x86_int(0); 74.122 + } 74.123 + cycles -= 19; 74.124 + break; 74.125 + 74.126 + default: 74.127 + pclog("Bad F6 opcode %02X\n", rmdat & 0x38); 74.128 + x86illegal(); 74.129 + } 74.130 + return 0; 74.131 +} 74.132 +static int opF6_a32(uint32_t fetchdat) 74.133 +{ 74.134 + int tempws, tempws2; 74.135 + uint16_t tempw, src16; 74.136 + uint8_t src, dst; 74.137 + int8_t temps; 74.138 + 74.139 + fetch_ea_32(fetchdat); 74.140 + dst = geteab(); if (abrt) return 0; 74.141 + switch (rmdat & 0x38) 74.142 + { 74.143 + case 0x00: /*TEST b,#8*/ 74.144 + src = readmemb(cs, pc); pc++; if (abrt) return 0; 74.145 + setznp8(src & dst); 74.146 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 74.147 + else cycles -= ((mod == 3) ? 2 : 5); 74.148 + break; 74.149 + case 0x10: /*NOT b*/ 74.150 + seteab(~dst); 74.151 + cycles -= (mod == 3) ? timing_rr : timing_mm; 74.152 + break; 74.153 + case 0x18: /*NEG b*/ 74.154 + setsub8(0, dst); 74.155 + seteab(0 - dst); 74.156 + cycles -= (mod == 3) ? timing_rr : timing_mm; 74.157 + break; 74.158 + case 0x20: /*MUL AL,b*/ 74.159 + AX = AL * dst; 74.160 + flags_rebuild(); 74.161 + if (AH) flags |= (C_FLAG | V_FLAG); 74.162 + else flags &= ~(C_FLAG | V_FLAG); 74.163 + cycles -= 13; 74.164 + break; 74.165 + case 0x28: /*IMUL AL,b*/ 74.166 + tempws = (int)((int8_t)AL) * (int)((int8_t)dst); 74.167 + AX = tempws & 0xffff; 74.168 + flags_rebuild(); 74.169 + if (AH && AH != 0xff) flags |= (C_FLAG | V_FLAG); 74.170 + else flags &= ~(C_FLAG | V_FLAG); 74.171 + cycles -= 14; 74.172 + break; 74.173 + case 0x30: /*DIV AL,b*/ 74.174 + src16 = AX; 74.175 + if (dst) tempw = src16 / dst; 74.176 + if (dst && !(tempw & 0xff00)) 74.177 + { 74.178 + AH = src16 % dst; 74.179 + AL = (src16 / dst) &0xff; 74.180 + if (!cpu_iscyrix) 74.181 + { 74.182 + flags_rebuild(); 74.183 + flags |= 0x8D5; /*Not a Cyrix*/ 74.184 + } 74.185 + } 74.186 + else 74.187 + { 74.188 + x86_int(0); 74.189 + } 74.190 + cycles -= is486 ? 16 : 14; 74.191 + break; 74.192 + case 0x38: /*IDIV AL,b*/ 74.193 + tempws = (int)(int16_t)AX; 74.194 + if (dst != 0) tempws2 = tempws / (int)((int8_t)dst); 74.195 + temps = tempws2 & 0xff; 74.196 + if (dst && ((int)temps == tempws2)) 74.197 + { 74.198 + AH = (tempws % (int)((int8_t)dst)) & 0xff; 74.199 + AL = tempws2 & 0xff; 74.200 + if (!cpu_iscyrix) 74.201 + { 74.202 + flags_rebuild(); 74.203 + flags|=0x8D5; /*Not a Cyrix*/ 74.204 + } 74.205 + } 74.206 + else 74.207 + { 74.208 +// pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2); 74.209 + x86_int(0); 74.210 + } 74.211 + cycles -= 19; 74.212 + break; 74.213 + 74.214 + default: 74.215 + pclog("Bad F6 opcode %02X\n", rmdat & 0x38); 74.216 + x86illegal(); 74.217 + } 74.218 + return 0; 74.219 +} 74.220 + 74.221 + 74.222 + 74.223 +static int opF7_w_a16(uint32_t fetchdat) 74.224 +{ 74.225 + uint32_t templ, templ2; 74.226 + int tempws, tempws2; 74.227 + int16_t temps16; 74.228 + uint16_t src, dst; 74.229 + 74.230 + fetch_ea_16(fetchdat); 74.231 + dst = geteaw(); if (abrt) return 0; 74.232 + switch (rmdat & 0x38) 74.233 + { 74.234 + case 0x00: /*TEST w*/ 74.235 + src = getword(); if (abrt) return 0; 74.236 + setznp16(src & dst); 74.237 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 74.238 + else cycles -= ((mod == 3) ? 2 : 5); 74.239 + break; 74.240 + case 0x10: /*NOT w*/ 74.241 + seteaw(~dst); 74.242 + cycles -= (mod == 3) ? timing_rr : timing_mm; 74.243 + break; 74.244 + case 0x18: /*NEG w*/ 74.245 + setsub16(0, dst); 74.246 + seteaw(0 - dst); 74.247 + cycles -= (mod == 3) ? timing_rr : timing_mm; 74.248 + break; 74.249 + case 0x20: /*MUL AX,w*/ 74.250 + templ = AX * dst; 74.251 + AX = templ & 0xFFFF; 74.252 + DX = templ >> 16; 74.253 + flags_rebuild(); 74.254 + if (DX) flags |= (C_FLAG | V_FLAG); 74.255 + else flags &= ~(C_FLAG | V_FLAG); 74.256 + cycles -= 21; 74.257 + break; 74.258 + case 0x28: /*IMUL AX,w*/ 74.259 + templ = (int)((int16_t)AX) * (int)((int16_t)dst); 74.260 + AX = templ & 0xFFFF; 74.261 + DX = templ >> 16; 74.262 + flags_rebuild(); 74.263 + if (DX && DX != 0xFFFF) flags |= (C_FLAG | V_FLAG); 74.264 + else flags &= ~(C_FLAG | V_FLAG); 74.265 + cycles -= 22; 74.266 + break; 74.267 + case 0x30: /*DIV AX,w*/ 74.268 + templ = (DX << 16) | AX; 74.269 + if (dst) templ2 = templ / dst; 74.270 + if (dst && !(templ2 & 0xffff0000)) 74.271 + { 74.272 + DX = templ % dst; 74.273 + AX = (templ / dst) & 0xffff; 74.274 + if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ 74.275 + } 74.276 + else 74.277 + { 74.278 +// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); 74.279 + x86_int(0); 74.280 + } 74.281 + cycles -= is486 ? 24 : 22; 74.282 + break; 74.283 + case 0x38: /*IDIV AX,w*/ 74.284 + tempws = (int)((DX << 16)|AX); 74.285 + if (dst) tempws2 = tempws / (int)((int16_t)dst); 74.286 + temps16 = tempws2 & 0xffff; 74.287 + if ((dst != 0) && ((int)temps16 == tempws2)) 74.288 + { 74.289 + DX = tempws % (int)((int16_t)dst); 74.290 + AX = tempws2 & 0xffff; 74.291 + if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ 74.292 + } 74.293 + else 74.294 + { 74.295 +// pclog("IDIVw exception - %X / %08X = %X\n",tempws, dst, tempws2); 74.296 + x86_int(0); 74.297 + } 74.298 + cycles -= 27; 74.299 + break; 74.300 + 74.301 + default: 74.302 + pclog("Bad F7 opcode %02X\n", rmdat & 0x38); 74.303 + x86illegal(); 74.304 + } 74.305 + return 0; 74.306 +} 74.307 +static int opF7_w_a32(uint32_t fetchdat) 74.308 +{ 74.309 + uint32_t templ, templ2; 74.310 + int tempws, tempws2; 74.311 + int16_t temps16; 74.312 + uint16_t src, dst; 74.313 + 74.314 + fetch_ea_32(fetchdat); 74.315 + dst = geteaw(); if (abrt) return 0; 74.316 + switch (rmdat & 0x38) 74.317 + { 74.318 + case 0x00: /*TEST w*/ 74.319 + src = getword(); if (abrt) return 0; 74.320 + setznp16(src & dst); 74.321 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 74.322 + else cycles -= ((mod == 3) ? 2 : 5); 74.323 + break; 74.324 + case 0x10: /*NOT w*/ 74.325 + seteaw(~dst); 74.326 + cycles -= (mod == 3) ? timing_rr : timing_mm; 74.327 + break; 74.328 + case 0x18: /*NEG w*/ 74.329 + setsub16(0, dst); 74.330 + seteaw(0 - dst); 74.331 + cycles -= (mod == 3) ? timing_rr : timing_mm; 74.332 + break; 74.333 + case 0x20: /*MUL AX,w*/ 74.334 + templ = AX * dst; 74.335 + AX = templ & 0xFFFF; 74.336 + DX = templ >> 16; 74.337 + flags_rebuild(); 74.338 + if (DX) flags |= (C_FLAG | V_FLAG); 74.339 + else flags &= ~(C_FLAG | V_FLAG); 74.340 + cycles -= 21; 74.341 + break; 74.342 + case 0x28: /*IMUL AX,w*/ 74.343 + templ = (int)((int16_t)AX) * (int)((int16_t)dst); 74.344 + AX = templ & 0xFFFF; 74.345 + DX = templ >> 16; 74.346 + flags_rebuild(); 74.347 + if (DX && DX != 0xFFFF) flags |= (C_FLAG | V_FLAG); 74.348 + else flags &= ~(C_FLAG | V_FLAG); 74.349 + cycles -= 22; 74.350 + break; 74.351 + case 0x30: /*DIV AX,w*/ 74.352 + templ = (DX << 16) | AX; 74.353 + if (dst) templ2 = templ / dst; 74.354 + if (dst && !(templ2 & 0xffff0000)) 74.355 + { 74.356 + DX = templ % dst; 74.357 + AX = (templ / dst) & 0xffff; 74.358 + if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ 74.359 + } 74.360 + else 74.361 + { 74.362 +// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); 74.363 + x86_int(0); 74.364 + } 74.365 + cycles -= is486 ? 24 : 22; 74.366 + break; 74.367 + case 0x38: /*IDIV AX,w*/ 74.368 + tempws = (int)((DX << 16)|AX); 74.369 + if (dst) tempws2 = tempws / (int)((int16_t)dst); 74.370 + temps16 = tempws2 & 0xffff; 74.371 + if ((dst != 0) && ((int)temps16 == tempws2)) 74.372 + { 74.373 + DX = tempws % (int)((int16_t)dst); 74.374 + AX = tempws2 & 0xffff; 74.375 + if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ 74.376 + } 74.377 + else 74.378 + { 74.379 +// pclog("IDIVw exception - %X / %08X = %X\n", tempws, dst, tempws2); 74.380 + x86_int(0); 74.381 + } 74.382 + cycles -= 27; 74.383 + break; 74.384 + 74.385 + default: 74.386 + pclog("Bad F7 opcode %02X\n", rmdat & 0x38); 74.387 + x86illegal(); 74.388 + } 74.389 + return 0; 74.390 +} 74.391 + 74.392 +static int opF7_l_a16(uint32_t fetchdat) 74.393 +{ 74.394 + uint64_t temp64; 74.395 + uint32_t src, dst; 74.396 + 74.397 + fetch_ea_16(fetchdat); 74.398 + dst = geteal(); if (abrt) return 0; 74.399 + 74.400 + switch (rmdat & 0x38) 74.401 + { 74.402 + case 0x00: /*TEST l*/ 74.403 + src = getlong(); if (abrt) return 0; 74.404 + setznp32(src & dst); 74.405 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 74.406 + else cycles -= ((mod == 3) ? 2 : 5); 74.407 + break; 74.408 + case 0x10: /*NOT l*/ 74.409 + seteal(~dst); 74.410 + cycles -= (mod == 3) ? timing_rr : timing_mml; 74.411 + break; 74.412 + case 0x18: /*NEG l*/ 74.413 + setsub32(0, dst); 74.414 + seteal(0 - dst); 74.415 + cycles -= (mod == 3) ? timing_rr : timing_mml; 74.416 + break; 74.417 + case 0x20: /*MUL EAX,l*/ 74.418 + temp64 = (uint64_t)EAX * (uint64_t)dst; 74.419 + EAX = temp64 & 0xffffffff; 74.420 + EDX = temp64 >> 32; 74.421 + flags_rebuild(); 74.422 + if (EDX) flags |= (C_FLAG|V_FLAG); 74.423 + else flags &= ~(C_FLAG|V_FLAG); 74.424 + cycles -= 21; 74.425 + break; 74.426 + case 0x28: /*IMUL EAX,l*/ 74.427 + temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst; 74.428 + EAX = temp64 & 0xffffffff; 74.429 + EDX = temp64 >> 32; 74.430 + flags_rebuild(); 74.431 + if (EDX && EDX != 0xffffffff) flags |= (C_FLAG|V_FLAG); 74.432 + else flags &= ~(C_FLAG|V_FLAG); 74.433 + cycles -= 38; 74.434 + break; 74.435 + case 0x30: /*DIV EAX,l*/ 74.436 + divl(dst); 74.437 + if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ 74.438 + cycles -= (is486) ? 40 : 38; 74.439 + break; 74.440 + case 0x38: /*IDIV EAX,l*/ 74.441 + idivl((int32_t)dst); 74.442 + if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ 74.443 + cycles -= 43; 74.444 + break; 74.445 + 74.446 + default: 74.447 + pclog("Bad F7 opcode %02X\n", rmdat & 0x38); 74.448 + x86illegal(); 74.449 + } 74.450 + return 0; 74.451 +} 74.452 +static int opF7_l_a32(uint32_t fetchdat) 74.453 +{ 74.454 + uint64_t temp64; 74.455 + uint32_t src, dst; 74.456 + 74.457 + fetch_ea_32(fetchdat); 74.458 + dst = geteal(); if (abrt) return 0; 74.459 + 74.460 + switch (rmdat & 0x38) 74.461 + { 74.462 + case 0x00: /*TEST l*/ 74.463 + src = getlong(); if (abrt) return 0; 74.464 + setznp32(src & dst); 74.465 + if (is486) cycles -= ((mod == 3) ? 1 : 2); 74.466 + else cycles -= ((mod == 3) ? 2 : 5); 74.467 + break; 74.468 + case 0x10: /*NOT l*/ 74.469 + seteal(~dst); 74.470 + cycles -= (mod == 3) ? timing_rr : timing_mml; 74.471 + break; 74.472 + case 0x18: /*NEG l*/ 74.473 + setsub32(0, dst); 74.474 + seteal(0 - dst); 74.475 + cycles -= (mod == 3) ? timing_rr : timing_mml; 74.476 + break; 74.477 + case 0x20: /*MUL EAX,l*/ 74.478 + temp64 = (uint64_t)EAX * (uint64_t)dst; 74.479 + EAX = temp64 & 0xffffffff; 74.480 + EDX = temp64 >> 32; 74.481 + flags_rebuild(); 74.482 + if (EDX) flags |= (C_FLAG|V_FLAG); 74.483 + else flags &= ~(C_FLAG|V_FLAG); 74.484 + cycles -= 21; 74.485 + break; 74.486 + case 0x28: /*IMUL EAX,l*/ 74.487 + temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst; 74.488 + EAX = temp64 & 0xffffffff; 74.489 + EDX = temp64 >> 32; 74.490 + flags_rebuild(); 74.491 + if (EDX && EDX != 0xffffffff) flags |= (C_FLAG|V_FLAG); 74.492 + else flags &= ~(C_FLAG|V_FLAG); 74.493 + cycles -= 38; 74.494 + break; 74.495 + case 0x30: /*DIV EAX,l*/ 74.496 + divl(dst); 74.497 + if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ 74.498 + cycles -= (is486) ? 40 : 38; 74.499 + break; 74.500 + case 0x38: /*IDIV EAX,l*/ 74.501 + idivl((int32_t)dst); 74.502 + if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ 74.503 + cycles -= 43; 74.504 + break; 74.505 + 74.506 + default: 74.507 + pclog("Bad F7 opcode %02X\n", rmdat & 0x38); 74.508 + x86illegal(); 74.509 + } 74.510 + return 0; 74.511 +} 74.512 + 74.513 + 74.514 +static int opHLT(uint32_t fetchdat) 74.515 +{ 74.516 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 74.517 + { 74.518 + x86gpf(NULL,0); 74.519 + return 0; 74.520 + } 74.521 + if (!((flags&I_FLAG) && pic_intpending && !ssegs)) 74.522 + { 74.523 + cycles -= 100; 74.524 + pc--; 74.525 + } 74.526 + else 74.527 + cycles -= 5; 74.528 + return 0; 74.529 +} 74.530 + 74.531 + 74.532 +static int opLOCK(uint32_t fetchdat) 74.533 +{ 74.534 + cycles -= 4; 74.535 + return 0; 74.536 +} 74.537 + 74.538 + 74.539 + 74.540 +static int opBOUND_w_a16(uint32_t fetchdat) 74.541 +{ 74.542 + int16_t low, high; 74.543 + 74.544 + fetch_ea_16(fetchdat); 74.545 + low = geteaw(); 74.546 + high = readmemw(easeg, eaaddr + 2); if (abrt) return 0; 74.547 + 74.548 + if (((int16_t)regs[reg].w < low) || ((int16_t)regs[reg].w > high)) 74.549 + { 74.550 + x86_int(5); 74.551 + } 74.552 + 74.553 + cycles -= is486 ? 7 : 10; 74.554 + return 0; 74.555 +} 74.556 +static int opBOUND_w_a32(uint32_t fetchdat) 74.557 +{ 74.558 + int16_t low, high; 74.559 + 74.560 + fetch_ea_32(fetchdat); 74.561 + low = geteaw(); 74.562 + high = readmemw(easeg, eaaddr + 2); if (abrt) return 0; 74.563 + 74.564 + if (((int16_t)regs[reg].w < low) || ((int16_t)regs[reg].w > high)) 74.565 + { 74.566 + x86_int(5); 74.567 + } 74.568 + 74.569 + cycles -= is486 ? 7 : 10; 74.570 + return 0; 74.571 +} 74.572 + 74.573 +static int opBOUND_l_a16(uint32_t fetchdat) 74.574 +{ 74.575 + int32_t low, high; 74.576 + 74.577 + fetch_ea_16(fetchdat); 74.578 + low = geteal(); 74.579 + high = readmeml(easeg, eaaddr + 4); if (abrt) return 0; 74.580 + 74.581 + if (((int32_t)regs[reg].l < low) || ((int32_t)regs[reg].l > high)) 74.582 + { 74.583 + x86_int(5); 74.584 + } 74.585 + 74.586 + cycles -= is486 ? 7 : 10; 74.587 + return 0; 74.588 +} 74.589 +static int opBOUND_l_a32(uint32_t fetchdat) 74.590 +{ 74.591 + int32_t low, high; 74.592 + 74.593 + fetch_ea_32(fetchdat); 74.594 + low = geteal(); 74.595 + high = readmeml(easeg, eaaddr + 4); if (abrt) return 0; 74.596 + 74.597 + if (((int32_t)regs[reg].l < low) || ((int32_t)regs[reg].l > high)) 74.598 + { 74.599 + x86_int(5); 74.600 + } 74.601 + 74.602 + cycles -= is486 ? 7 : 10; 74.603 + return 0; 74.604 +} 74.605 + 74.606 + 74.607 +static int opCLTS(uint32_t fetchdat) 74.608 +{ 74.609 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 74.610 + { 74.611 + pclog("Can't CLTS\n"); 74.612 + x86gpf(NULL,0); 74.613 + return 0; 74.614 + } 74.615 + cr0 &= ~8; 74.616 + cycles -= 5; 74.617 + return 0; 74.618 +} 74.619 + 74.620 +static int opINVD(uint32_t fetchdat) 74.621 +{ 74.622 + if (!is486) 74.623 + { 74.624 + x86illegal(); 74.625 + return 0; 74.626 + } 74.627 + cycles -= 1000; 74.628 + return 0; 74.629 +} 74.630 +static int opWBINVD(uint32_t fetchdat) 74.631 +{ 74.632 + if (!is486) 74.633 + { 74.634 + x86illegal(); 74.635 + return 0; 74.636 + } 74.637 + cycles -= 10000; 74.638 + return 0; 74.639 +} 74.640 + 74.641 + 74.642 + 74.643 +static int opLOADALL(uint32_t fetchdat) 74.644 +{ 74.645 + flags = (readmemw(0, 0x818) & 0xffd5) | 2; 74.646 + flags_extract(); 74.647 + pc = readmemw(0, 0x81A); 74.648 + DS = readmemw(0, 0x81E); 74.649 + SS = readmemw(0, 0x820); 74.650 + CS = readmemw(0, 0x822); 74.651 + ES = readmemw(0, 0x824); 74.652 + DI = readmemw(0, 0x826); 74.653 + SI = readmemw(0, 0x828); 74.654 + BP = readmemw(0, 0x82A); 74.655 + SP = readmemw(0, 0x82C); 74.656 + BX = readmemw(0, 0x82E); 74.657 + DX = readmemw(0, 0x830); 74.658 + CX = readmemw(0, 0x832); 74.659 + AX = readmemw(0, 0x834); 74.660 + es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16); 74.661 + cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); 74.662 + ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); 74.663 + ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); 74.664 + cycles-=195; 74.665 + return 0; 74.666 +} 74.667 + 74.668 +static int opCPUID(uint32_t fetchdat) 74.669 +{ 74.670 + if (CPUID) 74.671 + { 74.672 + cpu_CPUID(); 74.673 + cycles -= 9; 74.674 + return 0; 74.675 + } 74.676 + pc = oldpc; 74.677 + x86illegal(); 74.678 + return 0; 74.679 +} 74.680 + 74.681 +
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/src/x86_ops_mov.h Mon May 27 19:56:33 2013 +0100 75.3 @@ -0,0 +1,559 @@ 75.4 +static int opMOV_AL_imm(uint32_t fetchdat) 75.5 +{ 75.6 + AL = getbytef(); 75.7 + cycles -= timing_rr; 75.8 + return 0; 75.9 +} 75.10 +static int opMOV_AH_imm(uint32_t fetchdat) 75.11 +{ 75.12 + AH = getbytef(); 75.13 + cycles -= timing_rr; 75.14 + return 0; 75.15 +} 75.16 +static int opMOV_BL_imm(uint32_t fetchdat) 75.17 +{ 75.18 + BL = getbytef(); 75.19 + cycles -= timing_rr; 75.20 + return 0; 75.21 +} 75.22 +static int opMOV_BH_imm(uint32_t fetchdat) 75.23 +{ 75.24 + BH = getbytef(); 75.25 + cycles -= timing_rr; 75.26 + return 0; 75.27 +} 75.28 +static int opMOV_CL_imm(uint32_t fetchdat) 75.29 +{ 75.30 + CL = getbytef(); 75.31 + cycles -= timing_rr; 75.32 + return 0; 75.33 +} 75.34 +static int opMOV_CH_imm(uint32_t fetchdat) 75.35 +{ 75.36 + CH = getbytef(); 75.37 + cycles -= timing_rr; 75.38 + return 0; 75.39 +} 75.40 +static int opMOV_DL_imm(uint32_t fetchdat) 75.41 +{ 75.42 + DL = getbytef(); 75.43 + cycles -= timing_rr; 75.44 + return 0; 75.45 +} 75.46 +static int opMOV_DH_imm(uint32_t fetchdat) 75.47 +{ 75.48 + DH = getbytef(); 75.49 + cycles -= timing_rr; 75.50 + return 0; 75.51 +} 75.52 + 75.53 +static int opMOV_AX_imm(uint32_t fetchdat) 75.54 +{ 75.55 + AX = getwordf(); 75.56 + cycles -= timing_rr; 75.57 + return 0; 75.58 +} 75.59 +static int opMOV_BX_imm(uint32_t fetchdat) 75.60 +{ 75.61 + BX = getwordf(); 75.62 + cycles -= timing_rr; 75.63 + return 0; 75.64 +} 75.65 +static int opMOV_CX_imm(uint32_t fetchdat) 75.66 +{ 75.67 + CX = getwordf(); 75.68 + cycles -= timing_rr; 75.69 + return 0; 75.70 +} 75.71 +static int opMOV_DX_imm(uint32_t fetchdat) 75.72 +{ 75.73 + DX = getwordf(); 75.74 + cycles -= timing_rr; 75.75 + return 0; 75.76 +} 75.77 +static int opMOV_SI_imm(uint32_t fetchdat) 75.78 +{ 75.79 + SI = getwordf(); 75.80 + cycles -= timing_rr; 75.81 + return 0; 75.82 +} 75.83 +static int opMOV_DI_imm(uint32_t fetchdat) 75.84 +{ 75.85 + DI = getwordf(); 75.86 + cycles -= timing_rr; 75.87 + return 0; 75.88 +} 75.89 +static int opMOV_BP_imm(uint32_t fetchdat) 75.90 +{ 75.91 + BP = getwordf(); 75.92 + cycles -= timing_rr; 75.93 + return 0; 75.94 +} 75.95 +static int opMOV_SP_imm(uint32_t fetchdat) 75.96 +{ 75.97 + SP = getwordf(); 75.98 + cycles -= timing_rr; 75.99 + return 0; 75.100 +} 75.101 + 75.102 +static int opMOV_EAX_imm(uint32_t fetchdat) 75.103 +{ 75.104 + uint32_t templ = getlong(); if (abrt) return 0; 75.105 + EAX = templ; 75.106 + cycles -= timing_rr; 75.107 + return 0; 75.108 +} 75.109 +static int opMOV_EBX_imm(uint32_t fetchdat) 75.110 +{ 75.111 + uint32_t templ = getlong(); if (abrt) return 0; 75.112 + EBX = templ; 75.113 + cycles -= timing_rr; 75.114 + return 0; 75.115 +} 75.116 +static int opMOV_ECX_imm(uint32_t fetchdat) 75.117 +{ 75.118 + uint32_t templ = getlong(); if (abrt) return 0; 75.119 + ECX = templ; 75.120 + cycles -= timing_rr; 75.121 + return 0; 75.122 +} 75.123 +static int opMOV_EDX_imm(uint32_t fetchdat) 75.124 +{ 75.125 + uint32_t templ = getlong(); if (abrt) return 0; 75.126 + EDX = templ; 75.127 + cycles -= timing_rr; 75.128 + return 0; 75.129 +} 75.130 +static int opMOV_ESI_imm(uint32_t fetchdat) 75.131 +{ 75.132 + uint32_t templ = getlong(); if (abrt) return 0; 75.133 + ESI = templ; 75.134 + cycles -= timing_rr; 75.135 + return 0; 75.136 +} 75.137 +static int opMOV_EDI_imm(uint32_t fetchdat) 75.138 +{ 75.139 + uint32_t templ = getlong(); if (abrt) return 0; 75.140 + EDI = templ; 75.141 + cycles -= timing_rr; 75.142 + return 0; 75.143 +} 75.144 +static int opMOV_EBP_imm(uint32_t fetchdat) 75.145 +{ 75.146 + uint32_t templ = getlong(); if (abrt) return 0; 75.147 + EBP = templ; 75.148 + cycles -= timing_rr; 75.149 + return 0; 75.150 +} 75.151 +static int opMOV_ESP_imm(uint32_t fetchdat) 75.152 +{ 75.153 + uint32_t templ = getlong(); if (abrt) return 0; 75.154 + ESP = templ; 75.155 + cycles -= timing_rr; 75.156 + return 0; 75.157 +} 75.158 + 75.159 +static int opMOV_b_imm_a16(uint32_t fetchdat) 75.160 +{ 75.161 + uint8_t temp; 75.162 + fetch_ea_16(fetchdat); 75.163 + temp = readmemb(cs,pc); pc++; if (abrt) return 0; 75.164 + seteab(temp); 75.165 + cycles -= timing_rr; 75.166 + return 0; 75.167 +} 75.168 +static int opMOV_b_imm_a32(uint32_t fetchdat) 75.169 +{ 75.170 + uint8_t temp; 75.171 + fetch_ea_32(fetchdat); 75.172 + temp = getbyte(); if (abrt) return 0; 75.173 + seteab(temp); 75.174 + cycles -= timing_rr; 75.175 + return 0; 75.176 +} 75.177 + 75.178 +static int opMOV_w_imm_a16(uint32_t fetchdat) 75.179 +{ 75.180 + uint16_t temp; 75.181 + fetch_ea_16(fetchdat); 75.182 + temp = getword(); if (abrt) return 0; 75.183 + seteaw(temp); 75.184 + cycles -= timing_rr; 75.185 + return 0; 75.186 +} 75.187 +static int opMOV_w_imm_a32(uint32_t fetchdat) 75.188 +{ 75.189 + uint16_t temp; 75.190 + fetch_ea_32(fetchdat); 75.191 + temp = getword(); if (abrt) return 0; 75.192 + seteaw(temp); 75.193 + cycles -= timing_rr; 75.194 + return 0; 75.195 +} 75.196 +static int opMOV_l_imm_a16(uint32_t fetchdat) 75.197 +{ 75.198 + uint32_t temp; 75.199 + fetch_ea_16(fetchdat); 75.200 + temp = getlong(); if (abrt) return 0; 75.201 + seteal(temp); 75.202 + cycles -= timing_rr; 75.203 + return 0; 75.204 +} 75.205 +static int opMOV_l_imm_a32(uint32_t fetchdat) 75.206 +{ 75.207 + uint32_t temp; 75.208 + fetch_ea_32(fetchdat); 75.209 + temp = getlong(); if (abrt) return 0; 75.210 + seteal(temp); 75.211 + cycles -= timing_rr; 75.212 + return 0; 75.213 +} 75.214 + 75.215 + 75.216 +static int opMOV_AL_a16(uint32_t fetchdat) 75.217 +{ 75.218 + uint16_t addr = getwordf(); 75.219 + uint8_t temp = readmemb(ds, addr); if (abrt) return 0; 75.220 + AL = temp; 75.221 + cycles -= (is486) ? 1 : 4; 75.222 + return 0; 75.223 +} 75.224 +static int opMOV_AL_a32(uint32_t fetchdat) 75.225 +{ 75.226 + uint32_t addr = getlong(); 75.227 + uint8_t temp = readmemb(ds, addr); if (abrt) return 0; 75.228 + AL = temp; 75.229 + cycles -= (is486) ? 1 : 4; 75.230 + return 0; 75.231 +} 75.232 +static int opMOV_AX_a16(uint32_t fetchdat) 75.233 +{ 75.234 + uint16_t addr = getwordf(); 75.235 + uint16_t temp = readmemw(ds, addr); if (abrt) return 0; 75.236 + AX = temp; 75.237 + cycles -= (is486) ? 1 : 4; 75.238 + return 0; 75.239 +} 75.240 +static int opMOV_AX_a32(uint32_t fetchdat) 75.241 +{ 75.242 + uint32_t addr = getlong(); 75.243 + uint16_t temp = readmemw(ds, addr); if (abrt) return 0; 75.244 + AX = temp; 75.245 + cycles -= (is486) ? 1 : 4; 75.246 + return 0; 75.247 +} 75.248 +static int opMOV_EAX_a16(uint32_t fetchdat) 75.249 +{ 75.250 + uint16_t addr = getwordf(); if (abrt) return 0; 75.251 + uint32_t temp = readmeml(ds, addr); if (abrt) return 0; 75.252 + EAX = temp; 75.253 + cycles -= (is486) ? 1 : 4; 75.254 + return 0; 75.255 +} 75.256 +static int opMOV_EAX_a32(uint32_t fetchdat) 75.257 +{ 75.258 + uint32_t addr = getlong(); if (abrt) return 0; 75.259 + uint32_t temp = readmeml(ds, addr); if (abrt) return 0; 75.260 + EAX = temp; 75.261 + cycles -= (is486) ? 1 : 4; 75.262 + return 0; 75.263 +} 75.264 + 75.265 +static int opMOV_a16_AL(uint32_t fetchdat) 75.266 +{ 75.267 + uint16_t addr = getwordf(); 75.268 + writememb(ds, addr, AL); 75.269 + cycles -= (is486) ? 1 : 2; 75.270 + return 0; 75.271 +} 75.272 +static int opMOV_a32_AL(uint32_t fetchdat) 75.273 +{ 75.274 + uint32_t addr = getlong(); 75.275 + writememb(ds, addr, AL); 75.276 + cycles -= (is486) ? 1 : 2; 75.277 + return 0; 75.278 +} 75.279 +static int opMOV_a16_AX(uint32_t fetchdat) 75.280 +{ 75.281 + uint16_t addr = getwordf(); 75.282 + writememw(ds, addr, AX); 75.283 + cycles -= (is486) ? 1 : 2; 75.284 + return 0; 75.285 +} 75.286 +static int opMOV_a32_AX(uint32_t fetchdat) 75.287 +{ 75.288 + uint32_t addr = getlong(); 75.289 + writememw(ds, addr, AX); 75.290 + cycles -= (is486) ? 1 : 2; 75.291 + return 0; 75.292 +} 75.293 +static int opMOV_a16_EAX(uint32_t fetchdat) 75.294 +{ 75.295 + uint16_t addr = getwordf(); 75.296 + writememl(ds, addr, EAX); 75.297 + cycles -= (is486) ? 1 : 2; 75.298 + return 0; 75.299 +} 75.300 +static int opMOV_a32_EAX(uint32_t fetchdat) 75.301 +{ 75.302 + uint32_t addr = getlong(); 75.303 + writememl(ds, addr, EAX); 75.304 + cycles -= (is486) ? 1 : 2; 75.305 + return 0; 75.306 +} 75.307 + 75.308 + 75.309 +static int opLEA_w_a16(uint32_t fetchdat) 75.310 +{ 75.311 + fetch_ea_16(fetchdat); 75.312 + regs[reg].w = eaaddr; 75.313 + cycles -= timing_rr; 75.314 + return 0; 75.315 +} 75.316 +static int opLEA_w_a32(uint32_t fetchdat) 75.317 +{ 75.318 + fetch_ea_32(fetchdat); 75.319 + regs[reg].w = eaaddr; 75.320 + cycles -= timing_rr; 75.321 + return 0; 75.322 +} 75.323 + 75.324 +static int opLEA_l_a16(uint32_t fetchdat) 75.325 +{ 75.326 + fetch_ea_16(fetchdat); 75.327 + regs[reg].l = eaaddr & 0xffff; 75.328 + cycles -= timing_rr; 75.329 + return 0; 75.330 +} 75.331 +static int opLEA_l_a32(uint32_t fetchdat) 75.332 +{ 75.333 + fetch_ea_32(fetchdat); 75.334 + regs[reg].l = eaaddr; 75.335 + cycles -= timing_rr; 75.336 + return 0; 75.337 +} 75.338 + 75.339 + 75.340 + 75.341 +int opXLAT_a16(uint32_t fetchdat) 75.342 +{ 75.343 + uint32_t addr = (BX + AL)&0xFFFF; 75.344 + uint8_t temp = readmemb(ds, addr); if (abrt) return 0; 75.345 + AL = temp; 75.346 + cycles -= 5; 75.347 + return 0; 75.348 +} 75.349 +int opXLAT_a32(uint32_t fetchdat) 75.350 +{ 75.351 + uint32_t addr = EBX + AL; 75.352 + uint8_t temp = readmemb(ds, addr); if (abrt) return 0; 75.353 + AL = temp; 75.354 + cycles -= 5; 75.355 + return 0; 75.356 +} 75.357 + 75.358 +static int opMOV_b_r_a16(uint32_t fetchdat) 75.359 +{ 75.360 + if ((uint8_t)fetchdat >= 0xc0) 75.361 + { 75.362 + pc++; 75.363 + setr8(fetchdat & 7, getr8((fetchdat >> 3) & 7)); 75.364 + cycles -= timing_rr; 75.365 + } 75.366 + else 75.367 + { 75.368 + fetch_ea_16(fetchdat); 75.369 + seteab(getr8(reg)); 75.370 + cycles -= is486 ? 1 : 2; 75.371 + } 75.372 + return 0; 75.373 +} 75.374 +static int opMOV_b_r_a32(uint32_t fetchdat) 75.375 +{ 75.376 + if ((uint8_t)fetchdat >= 0xc0) 75.377 + { 75.378 + pc++; 75.379 + setr8(fetchdat & 7, getr8((fetchdat >> 3) & 7)); 75.380 + cycles -= timing_rr; 75.381 + } 75.382 + else 75.383 + { 75.384 + fetch_ea_32(fetchdat); 75.385 + seteab(getr8(reg)); 75.386 + cycles -= is486 ? 1 : 2; 75.387 + } 75.388 + return 0; 75.389 +} 75.390 +static int opMOV_w_r_a16(uint32_t fetchdat) 75.391 +{ 75.392 + if ((uint8_t)fetchdat >= 0xc0) 75.393 + { 75.394 + pc++; 75.395 + regs[fetchdat & 7].w = regs[(fetchdat >> 3) & 7].w; 75.396 + cycles -= timing_rr; 75.397 + } 75.398 + else 75.399 + { 75.400 + fetch_ea_16(fetchdat); 75.401 + seteaw(regs[reg].w); 75.402 + cycles -= is486 ? 1 : 2; 75.403 + } 75.404 + return 0; 75.405 +} 75.406 +static int opMOV_w_r_a32(uint32_t fetchdat) 75.407 +{ 75.408 + if ((uint8_t)fetchdat >= 0xc0) 75.409 + { 75.410 + pc++; 75.411 + regs[fetchdat & 7].w = regs[(fetchdat >> 3) & 7].w; 75.412 + cycles -= timing_rr; 75.413 + } 75.414 + else 75.415 + { 75.416 + fetch_ea_32(fetchdat); 75.417 + seteaw(regs[reg].w); 75.418 + cycles -= is486 ? 1 : 2; 75.419 + } 75.420 + return 0; 75.421 +} 75.422 +static int opMOV_l_r_a16(uint32_t fetchdat) 75.423 +{ 75.424 + if ((uint8_t)fetchdat >= 0xc0) 75.425 + { 75.426 + pc++; 75.427 + regs[fetchdat & 7].l = regs[(fetchdat >> 3) & 7].l; 75.428 + cycles -= timing_rr; 75.429 + } 75.430 + else 75.431 + { 75.432 + fetch_ea_16(fetchdat); 75.433 + seteal(regs[reg].l); 75.434 + cycles -= is486 ? 1 : 2; 75.435 + } 75.436 + return 0; 75.437 +} 75.438 +static int opMOV_l_r_a32(uint32_t fetchdat) 75.439 +{ 75.440 + if ((uint8_t)fetchdat >= 0xc0) 75.441 + { 75.442 + pc++; 75.443 + regs[fetchdat & 7].l = regs[(fetchdat >> 3) & 7].l; 75.444 + cycles -= timing_rr; 75.445 + } 75.446 + else 75.447 + { 75.448 + fetch_ea_32(fetchdat); 75.449 + seteal(regs[reg].l); 75.450 + cycles -= is486 ? 1 : 2; 75.451 + } 75.452 + return 0; 75.453 +} 75.454 + 75.455 +static int opMOV_r_b_a16(uint32_t fetchdat) 75.456 +{ 75.457 + if ((uint8_t)fetchdat >= 0xc0) 75.458 + { 75.459 + pc++; 75.460 + setr8((fetchdat >> 3) & 7, getr8(fetchdat & 7)); 75.461 + cycles -= timing_rr; 75.462 + } 75.463 + else 75.464 + { 75.465 + uint8_t temp; 75.466 + fetch_ea_16(fetchdat); 75.467 + temp = geteab(); if (abrt) return 0; 75.468 + setr8(reg, temp); 75.469 + cycles -= is486 ? 1 : 4; 75.470 + } 75.471 + return 0; 75.472 +} 75.473 +static int opMOV_r_b_a32(uint32_t fetchdat) 75.474 +{ 75.475 + if ((uint8_t)fetchdat >= 0xc0) 75.476 + { 75.477 + pc++; 75.478 + setr8((fetchdat >> 3) & 7, getr8(fetchdat & 7)); 75.479 + cycles -= timing_rr; 75.480 + } 75.481 + else 75.482 + { 75.483 + uint8_t temp; 75.484 + fetch_ea_32(fetchdat); 75.485 + temp = geteab(); if (abrt) return 0; 75.486 + setr8(reg, temp); 75.487 + cycles -= is486 ? 1 : 4; 75.488 + } 75.489 + return 0; 75.490 +} 75.491 +static int opMOV_r_w_a16(uint32_t fetchdat) 75.492 +{ 75.493 + if ((uint8_t)fetchdat >= 0xc0) 75.494 + { 75.495 + pc++; 75.496 + regs[(fetchdat >> 3) & 7].w = regs[fetchdat & 7].w; 75.497 + cycles -= timing_rr; 75.498 + } 75.499 + else 75.500 + { 75.501 + uint16_t temp; 75.502 + fetch_ea_16(fetchdat); 75.503 + temp = geteaw(); if (abrt) return 0; 75.504 + regs[reg].w = temp; 75.505 + cycles -= (is486) ? 1 : 4; 75.506 + } 75.507 + return 0; 75.508 +} 75.509 +static int opMOV_r_w_a32(uint32_t fetchdat) 75.510 +{ 75.511 + if ((uint8_t)fetchdat >= 0xc0) 75.512 + { 75.513 + pc++; 75.514 + regs[(fetchdat >> 3) & 7].w = regs[fetchdat & 7].w; 75.515 + cycles -= timing_rr; 75.516 + } 75.517 + else 75.518 + { 75.519 + uint16_t temp; 75.520 + fetch_ea_32(fetchdat); 75.521 + temp = geteaw(); if (abrt) return 0; 75.522 + regs[reg].w = temp; 75.523 + cycles -= (is486) ? 1 : 4; 75.524 + } 75.525 + return 0; 75.526 +} 75.527 +static int opMOV_r_l_a16(uint32_t fetchdat) 75.528 +{ 75.529 + if ((uint8_t)fetchdat >= 0xc0) 75.530 + { 75.531 + pc++; 75.532 + regs[(fetchdat >> 3) & 7].l = regs[fetchdat & 7].l; 75.533 + cycles -= timing_rr; 75.534 + } 75.535 + else 75.536 + { 75.537 + uint32_t temp; 75.538 + fetch_ea_16(fetchdat); 75.539 + temp = geteal(); if (abrt) return 0; 75.540 + regs[reg].l = temp; 75.541 + cycles -= is486 ? 1 : 4; 75.542 + } 75.543 + return 0; 75.544 +} 75.545 +static int opMOV_r_l_a32(uint32_t fetchdat) 75.546 +{ 75.547 + if ((uint8_t)fetchdat >= 0xc0) 75.548 + { 75.549 + pc++; 75.550 + regs[(fetchdat >> 3) & 7].l = regs[fetchdat & 7].l; 75.551 + cycles -= timing_rr; 75.552 + } 75.553 + else 75.554 + { 75.555 + uint32_t temp; 75.556 + fetch_ea_32(fetchdat); 75.557 + temp = geteal(); if (abrt) return 0; 75.558 + regs[reg].l = temp; 75.559 + cycles -= is486 ? 1 : 4; 75.560 + } 75.561 + return 0; 75.562 +}
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 76.2 +++ b/src/x86_ops_mov_ctrl.h Mon May 27 19:56:33 2013 +0100 76.3 @@ -0,0 +1,232 @@ 76.4 +static int opMOV_r_CRx_a16(uint32_t fetchdat) 76.5 +{ 76.6 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.7 + { 76.8 + pclog("Can't load from CRx\n"); 76.9 + x86gpf(NULL, 0); 76.10 + return 0; 76.11 + } 76.12 + fetch_ea_16(fetchdat); 76.13 + switch (reg) 76.14 + { 76.15 + case 0: 76.16 + regs[rm].l = cr0; 76.17 + if (is486) regs[rm].l |= 0x10; /*ET hardwired on 486*/ 76.18 + break; 76.19 + case 2: 76.20 + regs[rm].l = cr2; 76.21 + break; 76.22 + case 3: 76.23 + regs[rm].l = cr3; 76.24 + break; 76.25 + default: 76.26 + pclog("Bad read of CR%i %i\n",rmdat&7,reg); 76.27 + pc = oldpc; 76.28 + x86illegal(); 76.29 + break; 76.30 + } 76.31 + cycles -= 6; 76.32 + return 0; 76.33 +} 76.34 +static int opMOV_r_CRx_a32(uint32_t fetchdat) 76.35 +{ 76.36 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.37 + { 76.38 + pclog("Can't load from CRx\n"); 76.39 + x86gpf(NULL, 0); 76.40 + return 0; 76.41 + } 76.42 + fetch_ea_32(fetchdat); 76.43 + switch (reg) 76.44 + { 76.45 + case 0: 76.46 + regs[rm].l = cr0; 76.47 + if (is486) regs[rm].l |= 0x10; /*ET hardwired on 486*/ 76.48 + break; 76.49 + case 2: 76.50 + regs[rm].l = cr2; 76.51 + break; 76.52 + case 3: 76.53 + regs[rm].l = cr3; 76.54 + break; 76.55 + default: 76.56 + pclog("Bad read of CR%i %i\n",rmdat&7,reg); 76.57 + pc = oldpc; 76.58 + x86illegal(); 76.59 + break; 76.60 + } 76.61 + cycles -= 6; 76.62 + return 0; 76.63 +} 76.64 + 76.65 +static int opMOV_r_DRx_a16(uint32_t fetchdat) 76.66 +{ 76.67 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.68 + { 76.69 + pclog("Can't load from DRx\n"); 76.70 + x86gpf(NULL, 0); 76.71 + return 0; 76.72 + } 76.73 + fetch_ea_16(fetchdat); 76.74 + regs[rm].l = 0; 76.75 + cycles -= 6; 76.76 + return 0; 76.77 +} 76.78 +static int opMOV_r_DRx_a32(uint32_t fetchdat) 76.79 +{ 76.80 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.81 + { 76.82 + pclog("Can't load from DRx\n"); 76.83 + x86gpf(NULL, 0); 76.84 + return 0; 76.85 + } 76.86 + fetch_ea_32(fetchdat); 76.87 + regs[rm].l = 0; 76.88 + cycles -= 6; 76.89 + return 0; 76.90 +} 76.91 + 76.92 +static int opMOV_CRx_r_a16(uint32_t fetchdat) 76.93 +{ 76.94 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.95 + { 76.96 + pclog("Can't load CRx\n"); 76.97 + x86gpf(NULL,0); 76.98 + return 0; 76.99 + } 76.100 + fetch_ea_16(fetchdat); 76.101 + switch (reg) 76.102 + { 76.103 + case 0: 76.104 + if ((regs[rm].l ^ cr0) & 0x80000001) flushmmucache(); 76.105 + cr0 = regs[rm].l; 76.106 + if (cpu_16bitbus) cr0 |= 0x10; 76.107 + if (!(cr0 & 0x80000000)) mmu_perm=4; 76.108 + break; 76.109 + case 2: 76.110 + cr2 = regs[rm].l; 76.111 + break; 76.112 + case 3: 76.113 + cr3 = regs[rm].l & ~0xfff; 76.114 + flushmmucache(); 76.115 + break; 76.116 + default: 76.117 + pclog("Bad load CR%i\n", reg); 76.118 + pc = oldpc; 76.119 + x86illegal(); 76.120 + break; 76.121 + } 76.122 + cycles -= 10; 76.123 + return 0; 76.124 +} 76.125 +static int opMOV_CRx_r_a32(uint32_t fetchdat) 76.126 +{ 76.127 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.128 + { 76.129 + pclog("Can't load CRx\n"); 76.130 + x86gpf(NULL,0); 76.131 + return 0; 76.132 + } 76.133 + fetch_ea_32(fetchdat); 76.134 + switch (reg) 76.135 + { 76.136 + case 0: 76.137 + if ((regs[rm].l ^ cr0) & 0x80000001) flushmmucache(); 76.138 + cr0 = regs[rm].l; 76.139 + if (cpu_16bitbus) cr0 |= 0x10; 76.140 + if (!(cr0 & 0x80000000)) mmu_perm=4; 76.141 + break; 76.142 + case 2: 76.143 + cr2 = regs[rm].l; 76.144 + break; 76.145 + case 3: 76.146 + cr3 = regs[rm].l & ~0xfff; 76.147 + flushmmucache(); 76.148 + break; 76.149 + default: 76.150 + pclog("Bad load CR%i\n", reg); 76.151 + pc = oldpc; 76.152 + x86illegal(); 76.153 + break; 76.154 + } 76.155 + cycles -= 10; 76.156 + return 0; 76.157 +} 76.158 + 76.159 +static int opMOV_DRx_r_a16(uint32_t fetchdat) 76.160 +{ 76.161 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.162 + { 76.163 + pclog("Can't load DRx\n"); 76.164 + x86gpf(NULL, 0); 76.165 + return 0; 76.166 + } 76.167 + fetch_ea_16(fetchdat); 76.168 + cycles -= 6; 76.169 + return 0; 76.170 +} 76.171 +static int opMOV_DRx_r_a32(uint32_t fetchdat) 76.172 +{ 76.173 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.174 + { 76.175 + pclog("Can't load DRx\n"); 76.176 + x86gpf(NULL, 0); 76.177 + return 0; 76.178 + } 76.179 + fetch_ea_16(fetchdat); 76.180 + cycles -= 6; 76.181 + return 0; 76.182 +} 76.183 + 76.184 +static int opMOV_r_TRx_a16(uint32_t fetchdat) 76.185 +{ 76.186 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.187 + { 76.188 + pclog("Can't load from TRx\n"); 76.189 + x86gpf(NULL, 0); 76.190 + return 0; 76.191 + } 76.192 + fetch_ea_16(fetchdat); 76.193 + regs[rm].l = 0; 76.194 + cycles -= 6; 76.195 + return 0; 76.196 +} 76.197 +static int opMOV_r_TRx_a32(uint32_t fetchdat) 76.198 +{ 76.199 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.200 + { 76.201 + pclog("Can't load from TRx\n"); 76.202 + x86gpf(NULL, 0); 76.203 + return 0; 76.204 + } 76.205 + fetch_ea_32(fetchdat); 76.206 + regs[rm].l = 0; 76.207 + cycles -= 6; 76.208 + return 0; 76.209 +} 76.210 + 76.211 +static int opMOV_TRx_r_a16(uint32_t fetchdat) 76.212 +{ 76.213 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.214 + { 76.215 + pclog("Can't load TRx\n"); 76.216 + x86gpf(NULL, 0); 76.217 + return 0; 76.218 + } 76.219 + fetch_ea_16(fetchdat); 76.220 + cycles -= 6; 76.221 + return 0; 76.222 +} 76.223 +static int opMOV_TRx_r_a32(uint32_t fetchdat) 76.224 +{ 76.225 + if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 76.226 + { 76.227 + pclog("Can't load TRx\n"); 76.228 + x86gpf(NULL, 0); 76.229 + return 0; 76.230 + } 76.231 + fetch_ea_16(fetchdat); 76.232 + cycles -= 6; 76.233 + return 0; 76.234 +} 76.235 +
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/src/x86_ops_mov_seg.h Mon May 27 19:56:33 2013 +0100 77.3 @@ -0,0 +1,396 @@ 77.4 +static int opMOV_w_seg_a16(uint32_t fetchdat) 77.5 +{ 77.6 + fetch_ea_16(fetchdat); 77.7 + 77.8 + switch (rmdat & 0x38) 77.9 + { 77.10 + case 0x00: /*ES*/ 77.11 + seteaw(ES); 77.12 + break; 77.13 + case 0x08: /*CS*/ 77.14 + seteaw(CS); 77.15 + break; 77.16 + case 0x18: /*DS*/ 77.17 + if (ssegs) ds = oldds; 77.18 + seteaw(DS); 77.19 + break; 77.20 + case 0x10: /*SS*/ 77.21 + if (ssegs) ss = oldss; 77.22 + seteaw(SS); 77.23 + break; 77.24 + case 0x20: /*FS*/ 77.25 + seteaw(FS); 77.26 + break; 77.27 + case 0x28: /*GS*/ 77.28 + seteaw(GS); 77.29 + break; 77.30 + } 77.31 + 77.32 + cycles -= ((mod == 3) ? 2 : 3); 77.33 + return 0; 77.34 +} 77.35 +static int opMOV_w_seg_a32(uint32_t fetchdat) 77.36 +{ 77.37 + fetch_ea_32(fetchdat); 77.38 + 77.39 + switch (rmdat & 0x38) 77.40 + { 77.41 + case 0x00: /*ES*/ 77.42 + seteaw(ES); 77.43 + break; 77.44 + case 0x08: /*CS*/ 77.45 + seteaw(CS); 77.46 + break; 77.47 + case 0x18: /*DS*/ 77.48 + if (ssegs) ds = oldds; 77.49 + seteaw(DS); 77.50 + break; 77.51 + case 0x10: /*SS*/ 77.52 + if (ssegs) ss = oldss; 77.53 + seteaw(SS); 77.54 + break; 77.55 + case 0x20: /*FS*/ 77.56 + seteaw(FS); 77.57 + break; 77.58 + case 0x28: /*GS*/ 77.59 + seteaw(GS); 77.60 + break; 77.61 + } 77.62 + 77.63 + cycles -= ((mod == 3) ? 2 : 3); 77.64 + return 0; 77.65 +} 77.66 + 77.67 +static int opMOV_l_seg_a16(uint32_t fetchdat) 77.68 +{ 77.69 + fetch_ea_16(fetchdat); 77.70 + 77.71 + switch (rmdat & 0x38) 77.72 + { 77.73 + case 0x00: /*ES*/ 77.74 + if (mod == 3) regs[rm].l = ES; 77.75 + else seteaw(ES); 77.76 + break; 77.77 + case 0x08: /*CS*/ 77.78 + if (mod == 3) regs[rm].l = CS; 77.79 + else seteaw(CS); 77.80 + break; 77.81 + case 0x18: /*DS*/ 77.82 + if (ssegs) ds = oldds; 77.83 + if (mod == 3) regs[rm].l = DS; 77.84 + else seteaw(DS); 77.85 + break; 77.86 + case 0x10: /*SS*/ 77.87 + if (ssegs) ss = oldss; 77.88 + if (mod == 3) regs[rm].l = SS; 77.89 + else seteaw(SS); 77.90 + break; 77.91 + case 0x20: /*FS*/ 77.92 + if (mod == 3) regs[rm].l = FS; 77.93 + else seteaw(FS); 77.94 + break; 77.95 + case 0x28: /*GS*/ 77.96 + if (mod == 3) regs[rm].l = GS; 77.97 + else seteaw(GS); 77.98 + break; 77.99 + } 77.100 + 77.101 + cycles -= ((mod == 3) ? 2 : 3); 77.102 + return 0; 77.103 +} 77.104 +static int opMOV_l_seg_a32(uint32_t fetchdat) 77.105 +{ 77.106 + fetch_ea_32(fetchdat); 77.107 + 77.108 + switch (rmdat & 0x38) 77.109 + { 77.110 + case 0x00: /*ES*/ 77.111 + if (mod == 3) regs[rm].l = ES; 77.112 + else seteaw(ES); 77.113 + break; 77.114 + case 0x08: /*CS*/ 77.115 + if (mod == 3) regs[rm].l = CS; 77.116 + else seteaw(CS); 77.117 + break; 77.118 + case 0x18: /*DS*/ 77.119 + if (ssegs) ds = oldds; 77.120 + if (mod == 3) regs[rm].l = DS; 77.121 + else seteaw(DS); 77.122 + break; 77.123 + case 0x10: /*SS*/ 77.124 + if (ssegs) ss = oldss; 77.125 + if (mod == 3) regs[rm].l = SS; 77.126 + else seteaw(SS); 77.127 + break; 77.128 + case 0x20: /*FS*/ 77.129 + if (mod == 3) regs[rm].l = FS; 77.130 + else seteaw(FS); 77.131 + break; 77.132 + case 0x28: /*GS*/ 77.133 + if (mod == 3) regs[rm].l = GS; 77.134 + else seteaw(GS); 77.135 + break; 77.136 + } 77.137 + 77.138 + cycles -= ((mod == 3) ? 2 : 3); 77.139 + return 0; 77.140 +} 77.141 + 77.142 +static int opMOV_seg_w_a16(uint32_t fetchdat) 77.143 +{ 77.144 + uint16_t new_seg; 77.145 + 77.146 + fetch_ea_16(fetchdat); 77.147 + 77.148 + new_seg=geteaw(); if (abrt) return 0; 77.149 + 77.150 + switch (rmdat & 0x38) 77.151 + { 77.152 + case 0x00: /*ES*/ 77.153 + loadseg(new_seg, &_es); 77.154 + break; 77.155 + case 0x18: /*DS*/ 77.156 + loadseg(new_seg, &_ds); 77.157 + if (ssegs) oldds = ds; 77.158 + break; 77.159 + case 0x10: /*SS*/ 77.160 + loadseg(new_seg, &_ss); 77.161 + if (ssegs) 77.162 + { 77.163 + ds = oldds; 77.164 + rds = DS; 77.165 + ssegs = 0; 77.166 + } 77.167 + op32 = use32; 77.168 + return 1; 77.169 + case 0x20: /*FS*/ 77.170 + loadseg(new_seg, &_fs); 77.171 + break; 77.172 + case 0x28: /*GS*/ 77.173 + loadseg(new_seg, &_gs); 77.174 + break; 77.175 + } 77.176 + 77.177 + cycles -= ((mod == 3) ? 2 : 5); 77.178 + return 0; 77.179 +} 77.180 +static int opMOV_seg_w_a32(uint32_t fetchdat) 77.181 +{ 77.182 + uint16_t new_seg; 77.183 + 77.184 + fetch_ea_32(fetchdat); 77.185 + 77.186 + new_seg=geteaw(); if (abrt) return 0; 77.187 + 77.188 + switch (rmdat & 0x38) 77.189 + { 77.190 + case 0x00: /*ES*/ 77.191 + loadseg(new_seg, &_es); 77.192 + break; 77.193 + case 0x18: /*DS*/ 77.194 + loadseg(new_seg, &_ds); 77.195 + if (ssegs) oldds = ds; 77.196 + break; 77.197 + case 0x10: /*SS*/ 77.198 + loadseg(new_seg, &_ss); 77.199 + if (ssegs) 77.200 + { 77.201 + ds = oldds; 77.202 + rds = DS; 77.203 + ssegs = 0; 77.204 + } 77.205 + op32 = use32; 77.206 + return 1; 77.207 + case 0x20: /*FS*/ 77.208 + loadseg(new_seg, &_fs); 77.209 + break; 77.210 + case 0x28: /*GS*/ 77.211 + loadseg(new_seg, &_gs); 77.212 + break; 77.213 + } 77.214 + 77.215 + cycles -= ((mod == 3) ? 2 : 5); 77.216 + return 0; 77.217 +} 77.218 + 77.219 + 77.220 +static int opLDS_w_a16(uint32_t fetchdat) 77.221 +{ 77.222 + uint16_t addr, seg; 77.223 + 77.224 + fetch_ea_16(fetchdat); 77.225 + addr = readmemw(easeg, eaaddr); 77.226 + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; 77.227 + loadseg(seg, &_ds); if (abrt) return 0; 77.228 + regs[reg].w = addr; 77.229 + if (ssegs) oldds = ds; 77.230 + 77.231 + cycles -= 7; 77.232 + return 0; 77.233 +} 77.234 +static int opLDS_w_a32(uint32_t fetchdat) 77.235 +{ 77.236 + uint16_t addr, seg; 77.237 + 77.238 + fetch_ea_32(fetchdat); 77.239 + addr = readmemw(easeg, eaaddr); 77.240 + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; 77.241 + loadseg(seg, &_ds); if (abrt) return 0; 77.242 + regs[reg].w = addr; 77.243 + if (ssegs) oldds = ds; 77.244 + 77.245 + cycles -= 7; 77.246 + return 0; 77.247 +} 77.248 +static int opLDS_l_a16(uint32_t fetchdat) 77.249 +{ 77.250 + uint32_t addr; 77.251 + uint16_t seg; 77.252 + 77.253 + fetch_ea_16(fetchdat); 77.254 + addr = readmeml(easeg, eaaddr); 77.255 + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; 77.256 + loadseg(seg, &_ds); if (abrt) return 0; 77.257 + regs[reg].l = addr; 77.258 + if (ssegs) oldds = ds; 77.259 + 77.260 + cycles -= 7; 77.261 + return 0; 77.262 +} 77.263 +static int opLDS_l_a32(uint32_t fetchdat) 77.264 +{ 77.265 + uint32_t addr; 77.266 + uint16_t seg; 77.267 + 77.268 + fetch_ea_32(fetchdat); 77.269 + addr = readmeml(easeg, eaaddr); 77.270 + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; 77.271 + loadseg(seg, &_ds); if (abrt) return 0; 77.272 + regs[reg].l = addr; 77.273 + if (ssegs) oldds = ds; 77.274 + 77.275 + cycles -= 7; 77.276 + return 0; 77.277 +} 77.278 + 77.279 +static int opLSS_w_a16(uint32_t fetchdat) 77.280 +{ 77.281 + uint16_t addr, seg; 77.282 + 77.283 + fetch_ea_16(fetchdat); 77.284 + addr = readmemw(easeg, eaaddr); 77.285 + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; 77.286 + loadseg(seg, &_ss); if (abrt) return 0; 77.287 + regs[reg].w = addr; 77.288 + oldss = ss; 77.289 + 77.290 + cycles -= 7; 77.291 + return 0; 77.292 +} 77.293 +static int opLSS_w_a32(uint32_t fetchdat) 77.294 +{ 77.295 + uint16_t addr, seg; 77.296 + 77.297 + fetch_ea_32(fetchdat); 77.298 + addr = readmemw(easeg, eaaddr); 77.299 + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; 77.300 + loadseg(seg, &_ss); if (abrt) return 0; 77.301 + regs[reg].w = addr; 77.302 + oldss = ss; 77.303 + 77.304 + cycles -= 7; 77.305 + return 0; 77.306 +} 77.307 +static int opLSS_l_a16(uint32_t fetchdat) 77.308 +{ 77.309 + uint32_t addr; 77.310 + uint16_t seg; 77.311 + 77.312 + fetch_ea_16(fetchdat); 77.313 + addr = readmeml(easeg, eaaddr); 77.314 + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; 77.315 + loadseg(seg, &_ss); if (abrt) return 0; 77.316 + regs[reg].l = addr; 77.317 + oldss = ss; 77.318 + 77.319 + cycles -= 7; 77.320 + return 0; 77.321 +} 77.322 +static int opLSS_l_a32(uint32_t fetchdat) 77.323 +{ 77.324 + uint32_t addr; 77.325 + uint16_t seg; 77.326 + 77.327 + fetch_ea_32(fetchdat); 77.328 + addr = readmeml(easeg, eaaddr); 77.329 + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; 77.330 + loadseg(seg, &_ss); if (abrt) return 0; 77.331 + regs[reg].l = addr; 77.332 + oldss = ss; 77.333 + 77.334 + cycles -= 7; 77.335 + return 0; 77.336 +} 77.337 + 77.338 +#define opLsel(name, sel) \ 77.339 + static int opL ## name ## _w_a16(uint32_t fetchdat) \ 77.340 + { \ 77.341 + uint16_t addr, seg; \ 77.342 + \ 77.343 + fetch_ea_16(fetchdat); \ 77.344 + addr = readmemw(easeg, eaaddr); \ 77.345 + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; \ 77.346 + loadseg(seg, &sel); if (abrt) return 0; \ 77.347 + regs[reg].w = addr; \ 77.348 + \ 77.349 + cycles -= 7; \ 77.350 + return 0; \ 77.351 + } \ 77.352 + \ 77.353 + static int opL ## name ## _w_a32(uint32_t fetchdat) \ 77.354 + { \ 77.355 + uint16_t addr, seg; \ 77.356 + \ 77.357 + fetch_ea_32(fetchdat); \ 77.358 + addr = readmemw(easeg, eaaddr); \ 77.359 + seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; \ 77.360 + loadseg(seg, &sel); if (abrt) return 0; \ 77.361 + regs[reg].w = addr; \ 77.362 + \ 77.363 + cycles -= 7; \ 77.364 + return 0; \ 77.365 + } \ 77.366 + \ 77.367 + static int opL ## name ## _l_a16(uint32_t fetchdat) \ 77.368 + { \ 77.369 + uint32_t addr; \ 77.370 + uint16_t seg; \ 77.371 + \ 77.372 + fetch_ea_16(fetchdat); \ 77.373 + addr = readmeml(easeg, eaaddr); \ 77.374 + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; \ 77.375 + loadseg(seg, &sel); if (abrt) return 0; \ 77.376 + regs[reg].l = addr; \ 77.377 + \ 77.378 + cycles -= 7; \ 77.379 + return 0; \ 77.380 + } \ 77.381 + \ 77.382 + static int opL ## name ## _l_a32(uint32_t fetchdat) \ 77.383 + { \ 77.384 + uint32_t addr; \ 77.385 + uint16_t seg; \ 77.386 + \ 77.387 + fetch_ea_32(fetchdat); \ 77.388 + addr = readmeml(easeg, eaaddr); \ 77.389 + seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; \ 77.390 + loadseg(seg, &sel); if (abrt) return 0; \ 77.391 + regs[reg].l = addr; \ 77.392 + \ 77.393 + cycles -= 7; \ 77.394 + return 0; \ 77.395 + } 77.396 + 77.397 +opLsel(ES, _es) 77.398 +opLsel(FS, _fs) 77.399 +opLsel(GS, _gs)
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 78.2 +++ b/src/x86_ops_movx.h Mon May 27 19:56:33 2013 +0100 78.3 @@ -0,0 +1,145 @@ 78.4 +static int opMOVZX_w_b_a16(uint32_t fetchdat) 78.5 +{ 78.6 + uint8_t temp; 78.7 + 78.8 + fetch_ea_16(fetchdat); 78.9 + temp = geteab(); if (abrt) return 0; 78.10 + regs[reg].w = (uint16_t)temp; 78.11 + 78.12 + cycles -= 3; 78.13 + return 0; 78.14 +} 78.15 +static int opMOVZX_w_b_a32(uint32_t fetchdat) 78.16 +{ 78.17 + uint8_t temp; 78.18 + 78.19 + fetch_ea_32(fetchdat); 78.20 + temp = geteab(); if (abrt) return 0; 78.21 + regs[reg].w = (uint16_t)temp; 78.22 + 78.23 + cycles -= 3; 78.24 + return 0; 78.25 +} 78.26 +static int opMOVZX_l_b_a16(uint32_t fetchdat) 78.27 +{ 78.28 + uint8_t temp; 78.29 + 78.30 + fetch_ea_16(fetchdat); 78.31 + temp = geteab(); if (abrt) return 0; 78.32 + regs[reg].l = (uint32_t)temp; 78.33 + 78.34 + cycles -= 3; 78.35 + return 0; 78.36 +} 78.37 +static int opMOVZX_l_b_a32(uint32_t fetchdat) 78.38 +{ 78.39 + uint8_t temp; 78.40 + 78.41 + fetch_ea_32(fetchdat); 78.42 + temp = geteab(); if (abrt) return 0; 78.43 + regs[reg].l = (uint32_t)temp; 78.44 + 78.45 + cycles -= 3; 78.46 + return 0; 78.47 +} 78.48 +static int opMOVZX_l_w_a16(uint32_t fetchdat) 78.49 +{ 78.50 + uint16_t temp; 78.51 + 78.52 + fetch_ea_16(fetchdat); 78.53 + temp = geteaw(); if (abrt) return 0; 78.54 + regs[reg].l = (uint32_t)temp; 78.55 + 78.56 + cycles -= 3; 78.57 + return 0; 78.58 +} 78.59 +static int opMOVZX_l_w_a32(uint32_t fetchdat) 78.60 +{ 78.61 + uint16_t temp; 78.62 + 78.63 + fetch_ea_32(fetchdat); 78.64 + temp = geteaw(); if (abrt) return 0; 78.65 + regs[reg].l = (uint32_t)temp; 78.66 + 78.67 + cycles -= 3; 78.68 + return 0; 78.69 +} 78.70 + 78.71 +static int opMOVSX_w_b_a16(uint32_t fetchdat) 78.72 +{ 78.73 + uint8_t temp; 78.74 + 78.75 + fetch_ea_16(fetchdat); 78.76 + temp = geteab(); if (abrt) return 0; 78.77 + regs[reg].w = (uint16_t)temp; 78.78 + if (temp & 0x80) 78.79 + regs[reg].w |= 0xff00; 78.80 + 78.81 + cycles -= 3; 78.82 + return 0; 78.83 +} 78.84 +static int opMOVSX_w_b_a32(uint32_t fetchdat) 78.85 +{ 78.86 + uint8_t temp; 78.87 + 78.88 + fetch_ea_32(fetchdat); 78.89 + temp = geteab(); if (abrt) return 0; 78.90 + regs[reg].w = (uint16_t)temp; 78.91 + if (temp & 0x80) 78.92 + regs[reg].w |= 0xff00; 78.93 + 78.94 + cycles -= 3; 78.95 + return 0; 78.96 +} 78.97 +static int opMOVSX_l_b_a16(uint32_t fetchdat) 78.98 +{ 78.99 + uint8_t temp; 78.100 + 78.101 + fetch_ea_16(fetchdat); 78.102 + temp = geteab(); if (abrt) return 0; 78.103 + regs[reg].l = (uint32_t)temp; 78.104 + if (temp & 0x80) 78.105 + regs[reg].l |= 0xffffff00; 78.106 + 78.107 + cycles -= 3; 78.108 + return 0; 78.109 +} 78.110 +static int opMOVSX_l_b_a32(uint32_t fetchdat) 78.111 +{ 78.112 + uint8_t temp; 78.113 + 78.114 + fetch_ea_32(fetchdat); 78.115 + temp = geteab(); if (abrt) return 0; 78.116 + regs[reg].l = (uint32_t)temp; 78.117 + if (temp & 0x80) 78.118 + regs[reg].l |= 0xffffff00; 78.119 + 78.120 + cycles -= 3; 78.121 + return 0; 78.122 +} 78.123 +static int opMOVSX_l_w_a16(uint32_t fetchdat) 78.124 +{ 78.125 + uint16_t temp; 78.126 + 78.127 + fetch_ea_16(fetchdat); 78.128 + temp = geteaw(); if (abrt) return 0; 78.129 + regs[reg].l = (uint32_t)temp; 78.130 + if (temp & 0x8000) 78.131 + regs[reg].l |= 0xffff0000; 78.132 + 78.133 + cycles -= 3; 78.134 + return 0; 78.135 +} 78.136 +static int opMOVSX_l_w_a32(uint32_t fetchdat) 78.137 +{ 78.138 + uint16_t temp; 78.139 + 78.140 + fetch_ea_32(fetchdat); 78.141 + temp = geteaw(); if (abrt) return 0; 78.142 + regs[reg].l = (uint32_t)temp; 78.143 + if (temp & 0x8000) 78.144 + regs[reg].l |= 0xffff0000; 78.145 + 78.146 + cycles -= 3; 78.147 + return 0; 78.148 +}
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 79.2 +++ b/src/x86_ops_msr.h Mon May 27 19:56:33 2013 +0100 79.3 @@ -0,0 +1,13 @@ 79.4 +static int opRDTSC(uint32_t fetchdat) 79.5 +{ 79.6 + if (!cpu_hasrdtsc) 79.7 + { 79.8 + pc = oldpc; 79.9 + x86illegal(); 79.10 + return 0; 79.11 + } 79.12 + EAX = tsc & 0xffffffff; 79.13 + EDX = tsc >> 32; 79.14 + cycles--; 79.15 + return 0; 79.16 +}
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 80.2 +++ b/src/x86_ops_mul.h Mon May 27 19:56:33 2013 +0100 80.3 @@ -0,0 +1,222 @@ 80.4 +static int opIMUL_w_iw_a16(uint32_t fetchdat) 80.5 +{ 80.6 + uint32_t templ; 80.7 + int16_t tempw, tempw2; 80.8 + 80.9 + fetch_ea_16(fetchdat); 80.10 + 80.11 + tempw = geteaw(); if (abrt) return 0; 80.12 + tempw2 = getword(); if (abrt) return 0; 80.13 + 80.14 + templ = ((int)tempw) * ((int)tempw2); 80.15 + flags_rebuild(); 80.16 + if ((templ >> 16) != 0 && (templ >> 16) != 0xffff) flags |= C_FLAG | V_FLAG; 80.17 + else flags &= ~(C_FLAG | V_FLAG); 80.18 + regs[reg].w = templ & 0xffff; 80.19 + 80.20 + cycles -= (mod == 3) ? 14 : 17; 80.21 + return 0; 80.22 +} 80.23 +static int opIMUL_w_iw_a32(uint32_t fetchdat) 80.24 +{ 80.25 + uint32_t templ; 80.26 + int16_t tempw, tempw2; 80.27 + 80.28 + fetch_ea_32(fetchdat); 80.29 + 80.30 + tempw = geteaw(); if (abrt) return 0; 80.31 + tempw2 = getword(); if (abrt) return 0; 80.32 + 80.33 + templ = ((int)tempw) * ((int)tempw2); 80.34 + flags_rebuild(); 80.35 + if ((templ >> 16) != 0 && (templ >> 16) != 0xffff) flags |= C_FLAG | V_FLAG; 80.36 + else flags &= ~(C_FLAG | V_FLAG); 80.37 + regs[reg].w = templ & 0xffff; 80.38 + 80.39 + cycles -= (mod == 3) ? 14 : 17; 80.40 + return 0; 80.41 +} 80.42 + 80.43 +static int opIMUL_l_il_a16(uint32_t fetchdat) 80.44 +{ 80.45 + int64_t temp64; 80.46 + int32_t templ, templ2; 80.47 + 80.48 + fetch_ea_16(fetchdat); 80.49 + 80.50 + templ = geteal(); if (abrt) return 0; 80.51 + templ2 = getlong(); if (abrt) return 0; 80.52 + 80.53 + temp64 = ((int64_t)templ) * ((int64_t)templ2); 80.54 + flags_rebuild(); 80.55 + if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |= C_FLAG | V_FLAG; 80.56 + else flags &= ~(C_FLAG | V_FLAG); 80.57 + regs[reg].l = temp64 & 0xffffffff; 80.58 + 80.59 + cycles-=25; 80.60 + return 0; 80.61 +} 80.62 +static int opIMUL_l_il_a32(uint32_t fetchdat) 80.63 +{ 80.64 + int64_t temp64; 80.65 + int32_t templ, templ2; 80.66 + 80.67 + fetch_ea_32(fetchdat); 80.68 + 80.69 + templ = geteal(); if (abrt) return 0; 80.70 + templ2 = getlong(); if (abrt) return 0; 80.71 + 80.72 + temp64 = ((int64_t)templ) * ((int64_t)templ2); 80.73 + flags_rebuild(); 80.74 + if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |= C_FLAG | V_FLAG; 80.75 + else flags &= ~(C_FLAG | V_FLAG); 80.76 + regs[reg].l = temp64 & 0xffffffff; 80.77 + 80.78 + cycles-=25; 80.79 + return 0; 80.80 +} 80.81 + 80.82 +static int opIMUL_w_ib_a16(uint32_t fetchdat) 80.83 +{ 80.84 + uint32_t templ; 80.85 + int16_t tempw, tempw2; 80.86 + 80.87 + fetch_ea_16(fetchdat); 80.88 + 80.89 + tempw = geteaw(); if (abrt) return 0; 80.90 + tempw2 = getbyte(); if (abrt) return 0; 80.91 + if (tempw2 & 0x80) tempw2 |= 0xff00; 80.92 + 80.93 + templ = ((int)tempw) * ((int)tempw2); 80.94 + flags_rebuild(); 80.95 + if ((templ >> 16) != 0 && ((templ >> 16) & 0xffff) != 0xffff) flags |= C_FLAG | V_FLAG; 80.96 + else flags &= ~(C_FLAG | V_FLAG); 80.97 + regs[reg].w = templ & 0xffff; 80.98 + 80.99 + cycles -= (mod == 3) ? 14 : 17; 80.100 + return 0; 80.101 +} 80.102 +static int opIMUL_w_ib_a32(uint32_t fetchdat) 80.103 +{ 80.104 + uint32_t templ; 80.105 + int16_t tempw, tempw2; 80.106 + 80.107 + fetch_ea_32(fetchdat); 80.108 + 80.109 + tempw = geteaw(); if (abrt) return 0; 80.110 + tempw2 = getbyte(); if (abrt) return 0; 80.111 + if (tempw2 & 0x80) tempw2 |= 0xff00; 80.112 + 80.113 + templ = ((int)tempw) * ((int)tempw2); 80.114 + flags_rebuild(); 80.115 + if ((templ >> 16) != 0 && ((templ >> 16) & 0xffff) != 0xffff) flags |= C_FLAG | V_FLAG; 80.116 + else flags &= ~(C_FLAG | V_FLAG); 80.117 + regs[reg].w = templ & 0xffff; 80.118 + 80.119 + cycles -= (mod == 3) ? 14 : 17; 80.120 + return 0; 80.121 +} 80.122 + 80.123 +static int opIMUL_l_ib_a16(uint32_t fetchdat) 80.124 +{ 80.125 + uint64_t temp64; 80.126 + int32_t templ, templ2; 80.127 + 80.128 + fetch_ea_16(fetchdat); 80.129 + templ = geteal(); if (abrt) return 0; 80.130 + templ2 = getbyte(); if (abrt) return 0; 80.131 + if (templ2 & 0x80) templ2 |= 0xffffff00; 80.132 + 80.133 + temp64 = ((int64_t)templ)*((int64_t)templ2); 80.134 + flags_rebuild(); 80.135 + if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |= C_FLAG | V_FLAG; 80.136 + else flags &= ~(C_FLAG | V_FLAG); 80.137 + regs[reg].l = temp64 & 0xffffffff; 80.138 + 80.139 + cycles -= 20; 80.140 + return 0; 80.141 +} 80.142 +static int opIMUL_l_ib_a32(uint32_t fetchdat) 80.143 +{ 80.144 + uint64_t temp64; 80.145 + int32_t templ, templ2; 80.146 + 80.147 + fetch_ea_32(fetchdat); 80.148 + templ = geteal(); if (abrt) return 0; 80.149 + templ2 = getbyte(); if (abrt) return 0; 80.150 + if (templ2 & 0x80) templ2 |= 0xffffff00; 80.151 + 80.152 + temp64 = ((int64_t)templ)*((int64_t)templ2); 80.153 + flags_rebuild(); 80.154 + if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |= C_FLAG | V_FLAG; 80.155 + else flags &= ~(C_FLAG | V_FLAG); 80.156 + regs[reg].l = temp64 & 0xffffffff; 80.157 + 80.158 + cycles -= 20; 80.159 + return 0; 80.160 +} 80.161 + 80.162 + 80.163 + 80.164 +static int opIMUL_w_w_a16(uint32_t fetchdat) 80.165 +{ 80.166 + int32_t templ; 80.167 + 80.168 + fetch_ea_16(fetchdat); 80.169 + templ = (int32_t)(int16_t)regs[reg].w * (int32_t)(int16_t)geteaw(); 80.170 + if (abrt) return 0; 80.171 + regs[reg].w = templ & 0xFFFF; 80.172 + flags_rebuild(); 80.173 + if ((templ >> 16) && (templ >> 16) != 0xFFFF) flags |= C_FLAG | V_FLAG; 80.174 + else flags &= ~(C_FLAG | V_FLAG); 80.175 + 80.176 + cycles -= 18; 80.177 + return 0; 80.178 +} 80.179 +static int opIMUL_w_w_a32(uint32_t fetchdat) 80.180 +{ 80.181 + int32_t templ; 80.182 + 80.183 + fetch_ea_32(fetchdat); 80.184 + templ = (int32_t)(int16_t)regs[reg].w * (int32_t)(int16_t)geteaw(); 80.185 + if (abrt) return 0; 80.186 + regs[reg].w = templ & 0xFFFF; 80.187 + flags_rebuild(); 80.188 + if ((templ >> 16) && (templ >> 16) != 0xFFFF) flags |= C_FLAG | V_FLAG; 80.189 + else flags &= ~(C_FLAG | V_FLAG); 80.190 + 80.191 + cycles -= 18; 80.192 + return 0; 80.193 +} 80.194 + 80.195 +static int opIMUL_l_l_a16(uint32_t fetchdat) 80.196 +{ 80.197 + int64_t temp64; 80.198 + 80.199 + fetch_ea_16(fetchdat); 80.200 + temp64 = (int64_t)(int32_t)regs[reg].l * (int64_t)(int32_t)geteal(); 80.201 + if (abrt) return 0; 80.202 + regs[reg].l = temp64 & 0xFFFFFFFF; 80.203 + flags_rebuild(); 80.204 + if ((temp64 >> 32) && (temp64 >> 32) != 0xFFFFFFFF) flags |= C_FLAG | V_FLAG; 80.205 + else flags &= ~(C_FLAG | V_FLAG); 80.206 + 80.207 + cycles -= 30; 80.208 + return 0; 80.209 +} 80.210 +static int opIMUL_l_l_a32(uint32_t fetchdat) 80.211 +{ 80.212 + int64_t temp64; 80.213 + 80.214 + fetch_ea_32(fetchdat); 80.215 + temp64 = (int64_t)(int32_t)regs[reg].l * (int64_t)(int32_t)geteal(); 80.216 + if (abrt) return 0; 80.217 + regs[reg].l = temp64 & 0xFFFFFFFF; 80.218 + flags_rebuild(); 80.219 + if ((temp64 >> 32) && (temp64 >> 32) != 0xFFFFFFFF) flags |= C_FLAG | V_FLAG; 80.220 + else flags &= ~(C_FLAG | V_FLAG); 80.221 + 80.222 + cycles -= 30; 80.223 + return 0; 80.224 +} 80.225 +
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 81.2 +++ b/src/x86_ops_pmode.h Mon May 27 19:56:33 2013 +0100 81.3 @@ -0,0 +1,404 @@ 81.4 +static int opARPL_a16(uint32_t fetchdat) 81.5 +{ 81.6 + uint16_t temp_seg; 81.7 + 81.8 + NOTRM 81.9 + fetch_ea_16(fetchdat); 81.10 + 81.11 + temp_seg = geteaw(); if (abrt) return 0; 81.12 + 81.13 + flags_rebuild(); 81.14 + if ((temp_seg & 3) < (regs[reg].w & 3)) 81.15 + { 81.16 + temp_seg = (temp_seg & 0xfffc) | (regs[reg].w & 3); 81.17 + seteaw(temp_seg); if (abrt) return 0; 81.18 + flags |= Z_FLAG; 81.19 + } 81.20 + else 81.21 + flags &= ~Z_FLAG; 81.22 + 81.23 + cycles -= is486 ? 9 : 20; 81.24 + return 0; 81.25 +} 81.26 +static int opARPL_a32(uint32_t fetchdat) 81.27 +{ 81.28 + uint16_t temp_seg; 81.29 + 81.30 + NOTRM 81.31 + fetch_ea_32(fetchdat); 81.32 + 81.33 + temp_seg = geteaw(); if (abrt) return 0; 81.34 + 81.35 + flags_rebuild(); 81.36 + if ((temp_seg & 3) < (regs[reg].w & 3)) 81.37 + { 81.38 + temp_seg = (temp_seg & 0xfffc) | (regs[reg].w & 3); 81.39 + seteaw(temp_seg); if (abrt) return 0; 81.40 + flags |= Z_FLAG; 81.41 + } 81.42 + else 81.43 + flags &= ~Z_FLAG; 81.44 + 81.45 + cycles -= is486 ? 9 : 20; 81.46 + return 0; 81.47 +} 81.48 + 81.49 +#define opLAR(name, fetch_ea, is32) \ 81.50 + static int opLAR_ ## name(uint32_t fetchdat) \ 81.51 + { \ 81.52 + int valid; \ 81.53 + uint16_t sel, desc; \ 81.54 + \ 81.55 + NOTRM \ 81.56 + fetch_ea(fetchdat); \ 81.57 + \ 81.58 + sel = geteaw(); if (abrt) return 0; \ 81.59 + \ 81.60 + flags_rebuild(); \ 81.61 + if (!(sel & 0xfffc)) { flags &= ~Z_FLAG; return 0; } /*Null selector*/ \ 81.62 + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ 81.63 + if (valid) \ 81.64 + { \ 81.65 + cpl_override = 1; \ 81.66 + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ 81.67 + cpl_override = 0; if (abrt) return 0; \ 81.68 + } \ 81.69 + flags &= ~Z_FLAG; \ 81.70 + if ((desc & 0x1f00) == 0x000) valid = 0; \ 81.71 + if ((desc & 0x1f00) == 0x800) valid = 0; \ 81.72 + if ((desc & 0x1f00) == 0xa00) valid = 0; \ 81.73 + if ((desc & 0x1f00) == 0xd00) valid = 0; \ 81.74 + if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \ 81.75 + { \ 81.76 + int dpl = (desc >> 13) & 3; \ 81.77 + if (dpl < CPL || dpl < (sel & 3)) valid = 0; \ 81.78 + } \ 81.79 + if (valid) \ 81.80 + { \ 81.81 + flags |= Z_FLAG; \ 81.82 + cpl_override = 1; \ 81.83 + if (is32) \ 81.84 + regs[reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \ 81.85 + else \ 81.86 + regs[reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \ 81.87 + cpl_override = 0; \ 81.88 + } \ 81.89 + cycles -= 11; \ 81.90 + return 0; \ 81.91 + } 81.92 + 81.93 +opLAR(w_a16, fetch_ea_16, 0) 81.94 +opLAR(w_a32, fetch_ea_32, 0) 81.95 +opLAR(l_a16, fetch_ea_16, 1) 81.96 +opLAR(l_a32, fetch_ea_32, 1) 81.97 + 81.98 +#define opLSL(name, fetch_ea, is32) \ 81.99 + static int opLSL_ ## name(uint32_t fetchdat) \ 81.100 + { \ 81.101 + int valid; \ 81.102 + uint16_t sel, desc; \ 81.103 + \ 81.104 + NOTRM \ 81.105 + fetch_ea(fetchdat); \ 81.106 + \ 81.107 + sel = geteaw(); if (abrt) return 0; \ 81.108 + flags_rebuild(); \ 81.109 + flags &= ~Z_FLAG; \ 81.110 + if (!(sel & 0xfffc)) return 0; /*Null selector*/ \ 81.111 + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ 81.112 + if (valid) \ 81.113 + { \ 81.114 + cpl_override = 1; \ 81.115 + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ 81.116 + cpl_override = 0; if (abrt) return 0; \ 81.117 + } \ 81.118 + if ((desc & 0x1400) == 0x400) valid = 0; /*Interrupt or trap or call gate*/ \ 81.119 + if ((desc & 0x1f00) == 0x000) valid = 0; /*Invalid*/ \ 81.120 + if ((desc & 0x1f00) == 0xa00) valid = 0; /*Invalid*/ \ 81.121 + if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \ 81.122 + { \ 81.123 + int rpl = (desc >> 13) & 3; \ 81.124 + if (rpl < CPL || rpl < (sel & 3)) valid = 0; \ 81.125 + } \ 81.126 + if (valid) \ 81.127 + { \ 81.128 + flags |= Z_FLAG; \ 81.129 + cpl_override = 1; \ 81.130 + if (is32) \ 81.131 + { \ 81.132 + regs[reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ 81.133 + regs[reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \ 81.134 + if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) \ 81.135 + { \ 81.136 + regs[reg].l <<= 12; \ 81.137 + regs[reg].l |= 0xFFF; \ 81.138 + } \ 81.139 + } \ 81.140 + else \ 81.141 + regs[reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ 81.142 + cpl_override = 0; \ 81.143 + } \ 81.144 + cycles -= 10; \ 81.145 + return 0; \ 81.146 + } 81.147 + 81.148 +opLSL(w_a16, fetch_ea_16, 0) 81.149 +opLSL(w_a32, fetch_ea_32, 0) 81.150 +opLSL(l_a16, fetch_ea_16, 1) 81.151 +opLSL(l_a32, fetch_ea_32, 1) 81.152 + 81.153 + 81.154 +static inline int op0F00_common(uint32_t fetchdat) 81.155 +{ 81.156 + int dpl, valid, granularity; 81.157 + uint32_t addr, base, limit; 81.158 + uint16_t desc, sel; 81.159 + uint8_t access; 81.160 + 81.161 +// pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); 81.162 + switch (rmdat & 0x38) 81.163 + { 81.164 + case 0x00: /*SLDT*/ 81.165 + seteaw(ldt.seg); 81.166 + cycles -= 4; 81.167 + break; 81.168 + case 0x08: /*STR*/ 81.169 + seteaw(tr.seg); 81.170 + cycles -= 4; 81.171 + break; 81.172 + case 0x10: /*LLDT*/ 81.173 + if ((CPL || eflags&VM_FLAG) && (cr0&1)) 81.174 + { 81.175 + pclog("Invalid LLDT!\n"); 81.176 + x86gpf(NULL,0); 81.177 + return 0; 81.178 + } 81.179 + sel = geteaw(); if (abrt) return 0; 81.180 + addr = (sel & ~7) + gdt.base; 81.181 + limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); 81.182 + base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); 81.183 + access = readmemb(0, addr + 5); 81.184 + granularity = readmemb(0, addr + 6) & 0x80; 81.185 + if (abrt) return 0; 81.186 + ldt.limit = limit; 81.187 + ldt.access = access; 81.188 + if (granularity) 81.189 + { 81.190 + ldt.limit <<= 12; 81.191 + ldt.limit |= 0xfff; 81.192 + } 81.193 + ldt.base = base; 81.194 + ldt.seg = sel; 81.195 + cycles -= 20; 81.196 + break; 81.197 + case 0x18: /*LTR*/ 81.198 + if ((CPL || eflags&VM_FLAG) && (cr0&1)) 81.199 + { 81.200 + pclog("Invalid LTR!\n"); 81.201 + x86gpf(NULL,0); 81.202 + break; 81.203 + } 81.204 + sel = geteaw(); if (abrt) return 0; 81.205 + addr = (sel & ~7) + gdt.base; 81.206 + limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); 81.207 + base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); 81.208 + access = readmemb(0, addr + 5); 81.209 + granularity = readmemb(0, addr + 6) & 0x80; 81.210 + if (abrt) return 0; 81.211 + tr.seg = sel; 81.212 + tr.limit = limit; 81.213 + tr.access = access; 81.214 + if (granularity) 81.215 + { 81.216 + tr.limit <<= 12; 81.217 + tr.limit |= 0xFFF; 81.218 + } 81.219 + tr.base = base; 81.220 + cycles -= 20; 81.221 + break; 81.222 + case 0x20: /*VERR*/ 81.223 + sel = geteaw(); if (abrt) return 0; 81.224 + flags_rebuild(); 81.225 + flags &= ~Z_FLAG; 81.226 + if (!(sel & 0xfffc)) return 0; /*Null selector*/ 81.227 + cpl_override = 1; 81.228 + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); 81.229 + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); 81.230 + cpl_override = 0; if (abrt) return 0; 81.231 + if (!(desc & 0x1000)) valid = 0; 81.232 + if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/ 81.233 + { 81.234 + dpl = (desc >> 13) & 3; /*Check permissions*/ 81.235 + if (dpl < CPL || dpl < (sel & 3)) valid = 0; 81.236 + } 81.237 + if ((desc & 0x0800) && !(desc & 0x0200)) valid = 0; /*Non-readable code*/ 81.238 + if (valid) flags |= Z_FLAG; 81.239 + cycles -= 20; 81.240 + break; 81.241 + case 0x28: /*VERW*/ 81.242 + sel = geteaw(); if (abrt) return 0; 81.243 + flags_rebuild(); 81.244 + flags &= ~Z_FLAG; 81.245 + if (!(sel & 0xfffc)) return 0; /*Null selector*/ 81.246 + cpl_override = 1; 81.247 + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); 81.248 + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); 81.249 + cpl_override = 0; if (abrt) return 0; 81.250 + if (!(desc & 0x1000)) valid = 0; 81.251 + dpl = (desc >> 13) & 3; /*Check permissions*/ 81.252 + if (dpl < CPL || dpl < (sel & 3)) valid = 0; 81.253 + if (desc & 0x0800) valid = 0; /*Code*/ 81.254 + if (!(desc & 0x0200)) valid = 0; /*Read-only data*/ 81.255 + if (valid) flags |= Z_FLAG; 81.256 + cycles -= 20; 81.257 + break; 81.258 + 81.259 + default: 81.260 + pclog("Bad 0F 00 opcode %02X\n", rmdat & 0x38); 81.261 + pc -= 3; 81.262 + x86illegal(); 81.263 + break; 81.264 + } 81.265 + return 0; 81.266 +} 81.267 + 81.268 +static inline op0F00_a16(uint32_t fetchdat) 81.269 +{ 81.270 + NOTRM 81.271 + 81.272 + fetch_ea_16(fetchdat); 81.273 + 81.274 + op0F00_common(fetchdat); 81.275 + return 0; 81.276 +} 81.277 +static inline op0F00_a32(uint32_t fetchdat) 81.278 +{ 81.279 + NOTRM 81.280 + 81.281 + fetch_ea_32(fetchdat); 81.282 + 81.283 + op0F00_common(fetchdat); 81.284 + return 0; 81.285 +} 81.286 + 81.287 +static inline op0F01_common(uint32_t fetchdat, int is32) 81.288 +{ 81.289 + uint32_t base; 81.290 + uint16_t limit, tempw; 81.291 +// pclog("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); 81.292 + switch (rmdat & 0x38) 81.293 + { 81.294 + case 0x00: /*SGDT*/ 81.295 + seteaw(gdt.limit); 81.296 + base = is32 ? gdt.base : (gdt.base & 0xffffff); 81.297 + writememl(easeg, eaaddr + 2, base); 81.298 + cycles -= 7; 81.299 + break; 81.300 + case 0x08: /*SIDT*/ 81.301 + seteaw(idt.limit); 81.302 + base = is32 ? idt.base : (idt.base & 0xffffff); 81.303 + writememl(easeg, eaaddr + 2, base); 81.304 + cycles -= 7; 81.305 + break; 81.306 + case 0x10: /*LGDT*/ 81.307 + if ((CPL || eflags&VM_FLAG) && (cr0&1)) 81.308 + { 81.309 + pclog("Invalid LGDT!\n"); 81.310 + x86gpf(NULL,0); 81.311 + break; 81.312 + } 81.313 +// pclog("LGDT %08X:%08X\n", easeg, eaaddr); 81.314 + limit = geteaw(); 81.315 + base = readmeml(0, easeg + eaaddr + 2); if (abrt) return 0; 81.316 +// pclog(" %08X %04X\n", base, limit); 81.317 + gdt.limit = limit; 81.318 + gdt.base = base; 81.319 + if (!is32) gdt.base &= 0xffffff; 81.320 + cycles -= 11; 81.321 + break; 81.322 + case 0x18: /*LIDT*/ 81.323 + if ((CPL || eflags&VM_FLAG) && (cr0&1)) 81.324 + { 81.325 + pclog("Invalid LIDT!\n"); 81.326 + x86gpf(NULL,0); 81.327 + break; 81.328 + } 81.329 +// pclog("LIDT %08X:%08X\n", easeg, eaaddr); 81.330 + limit = geteaw(); 81.331 + base = readmeml(0, easeg + eaaddr + 2); if (abrt) return 0; 81.332 +// pclog(" %08X %04X\n", base, limit); 81.333 + idt.limit = limit; 81.334 + idt.base = base; 81.335 + if (!is32) idt.base &= 0xffffff; 81.336 + cycles -= 11; 81.337 + break; 81.338 + 81.339 + case 0x20: /*SMSW*/ 81.340 + if (is486) seteaw(msw); 81.341 + else seteaw(msw | 0xFF00); 81.342 + cycles -= 2; 81.343 + break; 81.344 + case 0x30: /*LMSW*/ 81.345 + if ((CPL || eflags&VM_FLAG) && (msw&1)) 81.346 + { 81.347 + pclog("LMSW - ring not zero!\n"); 81.348 + x86gpf(NULL, 0); 81.349 + break; 81.350 + } 81.351 + tempw = geteaw(); if (abrt) return 0; 81.352 + if (msw & 1) tempw |= 1; 81.353 + msw = tempw; 81.354 + break; 81.355 + 81.356 + case 0x38: /*INVLPG*/ 81.357 + if (is486) 81.358 + { 81.359 + if ((CPL || eflags&VM_FLAG) && (cr0&1)) 81.360 + { 81.361 + pclog("Invalid INVLPG!\n"); 81.362 + x86gpf(NULL, 0); 81.363 + break; 81.364 + } 81.365 + mmu_invalidate(ds + eaaddr); 81.366 + cycles -= 12; 81.367 + break; 81.368 + } 81.369 + 81.370 + default: 81.371 + pclog("Bad 0F 01 opcode %02X\n", rmdat & 0x38); 81.372 + pc -= 3; 81.373 + x86illegal(); 81.374 + break; 81.375 + } 81.376 + return 0; 81.377 +} 81.378 + 81.379 +static inline op0F01_w_a16(uint32_t fetchdat) 81.380 +{ 81.381 + fetch_ea_16(fetchdat); 81.382 + 81.383 + op0F01_common(fetchdat, 0); 81.384 + return 0; 81.385 +} 81.386 +static inline op0F01_w_a32(uint32_t fetchdat) 81.387 +{ 81.388 + fetch_ea_32(fetchdat); 81.389 + 81.390 + op0F01_common(fetchdat, 0); 81.391 + return 0; 81.392 +} 81.393 +static inline op0F01_l_a16(uint32_t fetchdat) 81.394 +{ 81.395 + fetch_ea_16(fetchdat); 81.396 + 81.397 + op0F01_common(fetchdat, 1); 81.398 + return 0; 81.399 +} 81.400 +static inline op0F01_l_a32(uint32_t fetchdat) 81.401 +{ 81.402 + fetch_ea_32(fetchdat); 81.403 + 81.404 + op0F01_common(fetchdat, 1); 81.405 + return 0; 81.406 +} 81.407 +
82.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 82.2 +++ b/src/x86_ops_prefix.h Mon May 27 19:56:33 2013 +0100 82.3 @@ -0,0 +1,73 @@ 82.4 +static int op_CS(uint32_t fetchdat) 82.5 +{ 82.6 + oldss = ss; 82.7 + oldds = ds; 82.8 + ds = ss = cs; 82.9 + rds = CS; 82.10 + ssegs = 2; 82.11 + cycles -= 4; 82.12 + return 1; 82.13 +} 82.14 +static int op_DS(uint32_t fetchdat) 82.15 +{ 82.16 + oldss = ss; 82.17 + oldds = ds; 82.18 + ds = ss = ds; 82.19 + ssegs = 2; 82.20 + cycles -= 4; 82.21 + return 1; 82.22 +} 82.23 +static int op_ES(uint32_t fetchdat) 82.24 +{ 82.25 + oldss = ss; 82.26 + oldds = ds; 82.27 + ds = ss = es; 82.28 + rds = ES; 82.29 + ssegs = 2; 82.30 + cycles -= 4; 82.31 + return 1; 82.32 +} 82.33 +static int op_FS(uint32_t fetchdat) 82.34 +{ 82.35 + oldss = ss; 82.36 + oldds = ds; 82.37 + rds = FS; 82.38 + ds = ss = fs; 82.39 + ssegs = 2; 82.40 + cycles -= 4; 82.41 + return 1; 82.42 +} 82.43 +static int op_GS(uint32_t fetchdat) 82.44 +{ 82.45 + oldss = ss; 82.46 + oldds = ds; 82.47 + rds = GS; 82.48 + ds = ss = gs; 82.49 + ssegs = 2; 82.50 + cycles -= 4; 82.51 + return 1; 82.52 +} 82.53 +static int op_SS(uint32_t fetchdat) 82.54 +{ 82.55 + oldss = ss; 82.56 + oldds = ds; 82.57 + ds = ss = ss; 82.58 + rds = SS; 82.59 + ssegs = 2; 82.60 + cycles -= 4; 82.61 + return 1; 82.62 +} 82.63 + 82.64 + 82.65 +static int op_66(uint32_t fetchdat) /*Data size select*/ 82.66 +{ 82.67 + op32 = ((use32 & 0x100) ^ 0x100) | (op32 & 0x200); 82.68 + cycles -= 2; 82.69 + return 1; 82.70 +} 82.71 +static int op_67(uint32_t fetchdat) /*Address size select*/ 82.72 +{ 82.73 + op32 = ((use32 & 0x200) ^ 0x200) | (op32 & 0x100); 82.74 + cycles -= 2; 82.75 + return 1; 82.76 +}
83.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 83.2 +++ b/src/x86_ops_rep.h Mon May 27 19:56:33 2013 +0100 83.3 @@ -0,0 +1,11 @@ 83.4 +static int opREPNE(uint32_t fetchdat) 83.5 +{ 83.6 + rep386(0); 83.7 + return 0; 83.8 +} 83.9 +static int opREPE(uint32_t fetchdat) 83.10 +{ 83.11 + rep386(1); 83.12 + return 0; 83.13 +} 83.14 +
84.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 84.2 +++ b/src/x86_ops_ret.h Mon May 27 19:56:33 2013 +0100 84.3 @@ -0,0 +1,152 @@ 84.4 +#define RETF_a16(stack_offset) \ 84.5 + if ((msw&1) && !(eflags&VM_FLAG)) \ 84.6 + { \ 84.7 + pmoderetf(0, stack_offset); \ 84.8 + return 0; \ 84.9 + } \ 84.10 + if (ssegs) ss = oldss; \ 84.11 + oxpc = pc; \ 84.12 + if (stack32) \ 84.13 + { \ 84.14 + pc = readmemw(ss, ESP); \ 84.15 + loadcs(readmemw(ss, ESP + 2)); \ 84.16 + } \ 84.17 + else \ 84.18 + { \ 84.19 + pc = readmemw(ss, SP); \ 84.20 + loadcs(readmemw(ss, SP + 2)); \ 84.21 + } \ 84.22 + if (abrt) return 0; \ 84.23 + if (stack32) ESP += 4 + stack_offset; \ 84.24 + else SP += 4 + stack_offset; \ 84.25 + cycles -= is486 ? 13 : 18; 84.26 + 84.27 +#define RETF_a32(stack_offset) \ 84.28 + if ((msw&1) && !(eflags&VM_FLAG)) \ 84.29 + { \ 84.30 + pmoderetf(1, stack_offset); \ 84.31 + return 0; \ 84.32 + } \ 84.33 + if (ssegs) ss = oldss; \ 84.34 + oxpc = pc; \ 84.35 + if (stack32) \ 84.36 + { \ 84.37 + pc = readmeml(ss, ESP); \ 84.38 + loadcs(readmeml(ss, ESP + 4) & 0xffff); \ 84.39 + } \ 84.40 + else \ 84.41 + { \ 84.42 + pc = readmeml(ss, SP); \ 84.43 + loadcs(readmeml(ss, SP + 4) & 0xffff); \ 84.44 + } \ 84.45 + if (abrt) return 0; \ 84.46 + if (stack32) ESP += 8 + stack_offset; \ 84.47 + else SP += 8 + stack_offset; \ 84.48 + cycles -= is486 ? 13 : 18; 84.49 + 84.50 +static int opRETF_a16(uint32_t fetchdat) 84.51 +{ 84.52 + RETF_a16(0); 84.53 + return 0; 84.54 +} 84.55 +static int opRETF_a32(uint32_t fetchdat) 84.56 +{ 84.57 + RETF_a32(0); 84.58 + return 0; 84.59 +} 84.60 + 84.61 +static int opRETF_a16_imm(uint32_t fetchdat) 84.62 +{ 84.63 + uint16_t offset = getwordf(); 84.64 + RETF_a16(offset); 84.65 + return 0; 84.66 +} 84.67 +static int opRETF_a32_imm(uint32_t fetchdat) 84.68 +{ 84.69 + uint16_t offset = getwordf(); 84.70 + RETF_a32(offset); 84.71 + return 0; 84.72 +} 84.73 + 84.74 +static int opIRET(uint32_t fetchdat) 84.75 +{ 84.76 + if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) 84.77 + { 84.78 + x86gpf(NULL,0); 84.79 + return 0; 84.80 + } 84.81 + if (ssegs) ss = oldss; 84.82 + if (msw&1) 84.83 + { 84.84 + optype = IRET; 84.85 + pmodeiret(0); 84.86 + optype = 0; 84.87 + } 84.88 + else 84.89 + { 84.90 + uint16_t new_cs; 84.91 + oxpc = pc; 84.92 + if (stack32) 84.93 + { 84.94 + pc = readmemw(ss, ESP); 84.95 + new_cs = readmemw(ss, ESP + 2); 84.96 + flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; 84.97 + ESP += 6; 84.98 + } 84.99 + else 84.100 + { 84.101 + pc = readmemw(ss, SP); 84.102 + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); 84.103 + flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; 84.104 + SP += 6; 84.105 + } 84.106 + loadcs(new_cs); 84.107 + } 84.108 + flags_extract(); 84.109 + cycles -= is486 ? 15 : 22; 84.110 + nmi_enable = 1; 84.111 + return 0; 84.112 +} 84.113 + 84.114 +static int opIRETD(uint32_t fetchdat) 84.115 +{ 84.116 + if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) 84.117 + { 84.118 + x86gpf(NULL,0); 84.119 + return 0; 84.120 + } 84.121 + if (ssegs) ss = oldss; 84.122 + if (msw & 1) 84.123 + { 84.124 + optype = IRET; 84.125 + pmodeiret(1); 84.126 + optype = 0; 84.127 + } 84.128 + else 84.129 + { 84.130 + uint16_t new_cs; 84.131 + oxpc = pc; 84.132 + if (stack32) 84.133 + { 84.134 + pc = readmeml(ss, ESP); 84.135 + new_cs = readmemw(ss, ESP + 4); 84.136 + flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; 84.137 + eflags = readmemw(ss, ESP + 10); 84.138 + ESP += 12; 84.139 + } 84.140 + else 84.141 + { 84.142 + pc = readmeml(ss, SP); 84.143 + new_cs = readmemw(ss, ((SP + 4) & 0xffff)); 84.144 + flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2; 84.145 + eflags = readmemw(ss, (SP + 10) & 0xffff); 84.146 + SP += 12; 84.147 + } 84.148 + loadcs(new_cs); 84.149 + } 84.150 + flags_extract(); 84.151 + cycles -= is486 ? 15 : 22; 84.152 + nmi_enable = 1; 84.153 + return 0; 84.154 +} 84.155 +
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 85.2 +++ b/src/x86_ops_set.h Mon May 27 19:56:33 2013 +0100 85.3 @@ -0,0 +1,33 @@ 85.4 +#define opSET(condition) \ 85.5 + static int opSET ## condition ## _a16(uint32_t fetchdat) \ 85.6 + { \ 85.7 + fetch_ea_16(fetchdat); \ 85.8 + seteab((cond_ ## condition) ? 1 : 0); \ 85.9 + cycles -= 4; \ 85.10 + return 0; \ 85.11 + } \ 85.12 + \ 85.13 + static int opSET ## condition ## _a32(uint32_t fetchdat) \ 85.14 + { \ 85.15 + fetch_ea_32(fetchdat); \ 85.16 + seteab((cond_ ## condition) ? 1 : 0); \ 85.17 + cycles -= 4; \ 85.18 + return 0; \ 85.19 + } 85.20 + 85.21 +opSET(O) 85.22 +opSET(NO) 85.23 +opSET(B) 85.24 +opSET(NB) 85.25 +opSET(E) 85.26 +opSET(NE) 85.27 +opSET(BE) 85.28 +opSET(NBE) 85.29 +opSET(S) 85.30 +opSET(NS) 85.31 +opSET(P) 85.32 +opSET(NP) 85.33 +opSET(L) 85.34 +opSET(NL) 85.35 +opSET(LE) 85.36 +opSET(NLE)
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 86.2 +++ b/src/x86_ops_shift.h Mon May 27 19:56:33 2013 +0100 86.3 @@ -0,0 +1,595 @@ 86.4 +#define OP_SHIFT_b(c) \ 86.5 + if (!c) return 0; \ 86.6 + flags_rebuild(); \ 86.7 + switch (rmdat & 0x38) \ 86.8 + { \ 86.9 + case 0x00: /*ROL b, c*/ \ 86.10 + while (c > 0) \ 86.11 + { \ 86.12 + temp2 = (temp & 0x80) ? 1 : 0; \ 86.13 + temp = (temp << 1) | temp2; \ 86.14 + c--; \ 86.15 + } \ 86.16 + seteab(temp); if (abrt) return 0; \ 86.17 + flags &= ~(C_FLAG | V_FLAG); \ 86.18 + if (temp2) flags |= C_FLAG; \ 86.19 + if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ 86.20 + cycles -= ((mod == 3) ? 3 : 7); \ 86.21 + break; \ 86.22 + case 0x08: /*ROR b,CL*/ \ 86.23 + while (c > 0) \ 86.24 + { \ 86.25 + temp2 = temp & 1; \ 86.26 + temp >>= 1; \ 86.27 + if (temp2) temp |= 0x80; \ 86.28 + c--; \ 86.29 + } \ 86.30 + seteab(temp); if (abrt) return 0; \ 86.31 + flags &= ~(C_FLAG | V_FLAG); \ 86.32 + if (temp2) flags |= C_FLAG; \ 86.33 + if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ 86.34 + cycles -= ((mod == 3) ? 3 : 7); \ 86.35 + break; \ 86.36 + case 0x10: /*RCL b,CL*/ \ 86.37 + temp2 = flags & C_FLAG; \ 86.38 + while (c > 0) \ 86.39 + { \ 86.40 + tempc = temp2 ? 1 : 0; \ 86.41 + temp2 = temp & 0x80; \ 86.42 + temp = (temp << 1) | tempc; \ 86.43 + c--; \ 86.44 + if (is486) cycles--; \ 86.45 + } \ 86.46 + seteab(temp); if (abrt) return 0; \ 86.47 + flags &= ~(C_FLAG | V_FLAG); \ 86.48 + if (temp2) flags |= C_FLAG; \ 86.49 + if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ 86.50 + cycles -= ((mod == 3) ? 9 : 10); \ 86.51 + break; \ 86.52 + case 0x18: /*RCR b,CL*/ \ 86.53 + temp2 = flags & C_FLAG; \ 86.54 + while (c > 0) \ 86.55 + { \ 86.56 + tempc = temp2 ? 0x80 : 0; \ 86.57 + temp2 = temp & 1; \ 86.58 + temp = (temp >> 1) | tempc; \ 86.59 + c--; \ 86.60 + if (is486) cycles--; \ 86.61 + } \ 86.62 + seteab(temp); if (abrt) return 0; \ 86.63 + flags &= ~(C_FLAG | V_FLAG); \ 86.64 + if (temp2) flags |= C_FLAG; \ 86.65 + if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ 86.66 + cycles -= ((mod == 3) ? 9 : 10); \ 86.67 + break; \ 86.68 + case 0x20: case 0x30: /*SHL b,CL*/ \ 86.69 + seteab(temp << c); if (abrt) return 0; \ 86.70 + setznp8(temp << c); \ 86.71 + if ((temp << (c - 1)) & 0x80) flags |= C_FLAG; \ 86.72 + if (((temp << c) ^ (temp << (c - 1))) & 0x80) flags |= V_FLAG; \ 86.73 + cycles -= ((mod == 3) ? 3 : 7); \ 86.74 + break; \ 86.75 + case 0x28: /*SHR b,CL*/ \ 86.76 + seteab(temp >> c); if (abrt) return 0; \ 86.77 + setznp8(temp >> c); \ 86.78 + if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ 86.79 + if (c == 1 && temp & 0x80) flags |= V_FLAG; \ 86.80 + cycles -= ((mod == 3) ? 3 : 7); \ 86.81 + break; \ 86.82 + case 0x38: /*SAR b,CL*/ \ 86.83 + tempc = ((temp >> (c - 1)) & 1); \ 86.84 + while (c > 0) \ 86.85 + { \ 86.86 + temp >>= 1; \ 86.87 + if (temp & 0x40) temp |= 0x80; \ 86.88 + c--; \ 86.89 + } \ 86.90 + seteab(temp); if (abrt) return 0; \ 86.91 + setznp8(temp); \ 86.92 + if (tempc) flags |= C_FLAG; \ 86.93 + cycles -= ((mod == 3) ? 3 : 7); \ 86.94 + break; \ 86.95 + } 86.96 + 86.97 +#define OP_SHIFT_w(c) \ 86.98 + if (!c) return 0; \ 86.99 + flags_rebuild(); \ 86.100 + switch (rmdat & 0x38) \ 86.101 + { \ 86.102 + case 0x00: /*ROL w, c*/ \ 86.103 + while (c > 0) \ 86.104 + { \ 86.105 + temp2 = (temp & 0x8000) ? 1 : 0; \ 86.106 + temp = (temp << 1) | temp2; \ 86.107 + c--; \ 86.108 + } \ 86.109 + seteaw(temp); if (abrt) return 0; \ 86.110 + flags &= ~(C_FLAG | V_FLAG); \ 86.111 + if (temp2) flags |= C_FLAG; \ 86.112 + if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ 86.113 + cycles -= ((mod == 3) ? 3 : 7); \ 86.114 + break; \ 86.115 + case 0x08: /*ROR w, c*/ \ 86.116 + while (c > 0) \ 86.117 + { \ 86.118 + temp2 = temp & 1; \ 86.119 + temp >>= 1; \ 86.120 + if (temp2) temp |= 0x8000; \ 86.121 + c--; \ 86.122 + } \ 86.123 + seteaw(temp); if (abrt) return 0; \ 86.124 + flags &= ~(C_FLAG | V_FLAG); \ 86.125 + if (temp2) flags |= C_FLAG; \ 86.126 + if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ 86.127 + cycles -= ((mod == 3) ? 3 : 7); \ 86.128 + break; \ 86.129 + case 0x10: /*RCL w, c*/ \ 86.130 + temp2 = flags & C_FLAG; \ 86.131 + while (c > 0) \ 86.132 + { \ 86.133 + tempc = temp2 ? 1 : 0; \ 86.134 + temp2 = temp & 0x8000; \ 86.135 + temp = (temp << 1) | tempc; \ 86.136 + c--; \ 86.137 + if (is486) cycles--; \ 86.138 + } \ 86.139 + seteaw(temp); if (abrt) return 0; \ 86.140 + flags &= ~(C_FLAG | V_FLAG); \ 86.141 + if (temp2) flags |= C_FLAG; \ 86.142 + if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ 86.143 + cycles -= ((mod == 3) ? 9 : 10); \ 86.144 + break; \ 86.145 + case 0x18: /*RCR w, c*/ \ 86.146 + temp2 = flags & C_FLAG; \ 86.147 + while (c > 0) \ 86.148 + { \ 86.149 + tempc = temp2 ? 0x8000 : 0; \ 86.150 + temp2 = temp & 1; \ 86.151 + temp = (temp >> 1) | tempc; \ 86.152 + c--; \ 86.153 + if (is486) cycles--; \ 86.154 + } \ 86.155 + seteaw(temp); if (abrt) return 0; \ 86.156 + flags &= ~(C_FLAG | V_FLAG); \ 86.157 + if (temp2) flags |= C_FLAG; \ 86.158 + if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ 86.159 + cycles -= ((mod == 3) ? 9 : 10); \ 86.160 + break; \ 86.161 + case 0x20: case 0x30: /*SHL w, c*/ \ 86.162 + seteaw(temp << c); if (abrt) return 0; \ 86.163 + setznp16(temp << c); \ 86.164 + if ((temp << (c - 1)) & 0x8000) flags |= C_FLAG; \ 86.165 + if (((temp << c) ^ (temp << (c - 1))) & 0x8000) flags |= V_FLAG;\ 86.166 + cycles -= ((mod == 3) ? 3 : 7); \ 86.167 + break; \ 86.168 + case 0x28: /*SHR w, c*/ \ 86.169 + seteaw(temp >> c); if (abrt) return 0; \ 86.170 + setznp16(temp >> c); \ 86.171 + if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ 86.172 + if (c == 1 && temp & 0x8000) flags |= V_FLAG; \ 86.173 + cycles -= ((mod == 3) ? 3 : 7); \ 86.174 + break; \ 86.175 + case 0x38: /*SAR w, c*/ \ 86.176 + tempc = ((temp >> (c - 1)) & 1); \ 86.177 + while (c > 0) \ 86.178 + { \ 86.179 + temp >>= 1; \ 86.180 + if (temp & 0x4000) temp |= 0x8000; \ 86.181 + c--; \ 86.182 + } \ 86.183 + seteaw(temp); if (abrt) return 0; \ 86.184 + setznp16(temp); \ 86.185 + if (tempc) flags |= C_FLAG; \ 86.186 + cycles -= ((mod == 3) ? 3 : 7); \ 86.187 + break; \ 86.188 + } 86.189 + 86.190 +#define OP_SHIFT_l(c) \ 86.191 + if (!c) return 0; \ 86.192 + flags_rebuild(); \ 86.193 + switch (rmdat & 0x38) \ 86.194 + { \ 86.195 + case 0x00: /*ROL l, c*/ \ 86.196 + while (c > 0) \ 86.197 + { \ 86.198 + temp2 = (temp & 0x80000000) ? 1 : 0; \ 86.199 + temp = (temp << 1) | temp2; \ 86.200 + c--; \ 86.201 + } \ 86.202 + seteal(temp); if (abrt) return 0; \ 86.203 + flags &= ~(C_FLAG | V_FLAG); \ 86.204 + if (temp2) flags |= C_FLAG; \ 86.205 + if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ 86.206 + cycles -= ((mod == 3) ? 3 : 7); \ 86.207 + break; \ 86.208 + case 0x08: /*ROR l, c*/ \ 86.209 + while (c > 0) \ 86.210 + { \ 86.211 + temp2 = temp & 1; \ 86.212 + temp >>= 1; \ 86.213 + if (temp2) temp |= 0x80000000; \ 86.214 + c--; \ 86.215 + } \ 86.216 + seteal(temp); if (abrt) return 0; \ 86.217 + flags &= ~(C_FLAG | V_FLAG); \ 86.218 + if (temp2) flags |= C_FLAG; \ 86.219 + if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ 86.220 + cycles -= ((mod == 3) ? 3 : 7); \ 86.221 + break; \ 86.222 + case 0x10: /*RCL l, c*/ \ 86.223 + temp2 = flags & C_FLAG; \ 86.224 + while (c > 0) \ 86.225 + { \ 86.226 + tempc = temp2 ? 1 : 0; \ 86.227 + temp2 = temp & 0x80000000; \ 86.228 + temp = (temp << 1) | tempc; \ 86.229 + c--; \ 86.230 + if (is486) cycles--; \ 86.231 + } \ 86.232 + seteal(temp); if (abrt) return 0; \ 86.233 + flags &= ~(C_FLAG | V_FLAG); \ 86.234 + if (temp2) flags |= C_FLAG; \ 86.235 + if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ 86.236 + cycles -= ((mod == 3) ? 9 : 10); \ 86.237 + break; \ 86.238 + case 0x18: /*RCR l, c*/ \ 86.239 + temp2 = flags & C_FLAG; \ 86.240 + while (c > 0) \ 86.241 + { \ 86.242 + tempc = temp2 ? 0x80000000 : 0; \ 86.243 + temp2 = temp & 1; \ 86.244 + temp = (temp >> 1) | tempc; \ 86.245 + c--; \ 86.246 + if (is486) cycles--; \ 86.247 + } \ 86.248 + seteal(temp); if (abrt) return 0; \ 86.249 + flags &= ~(C_FLAG | V_FLAG); \ 86.250 + if (temp2) flags |= C_FLAG; \ 86.251 + if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ 86.252 + cycles -= ((mod == 3) ? 9 : 10); \ 86.253 + break; \ 86.254 + case 0x20: case 0x30: /*SHL l, c*/ \ 86.255 + seteal(temp << c); if (abrt) return 0; \ 86.256 + setznp32(temp << c); \ 86.257 + if ((temp << (c - 1)) & 0x80000000) flags |= C_FLAG; \ 86.258 + if (((temp << c) ^ (temp << (c - 1))) & 0x80000000) flags |= V_FLAG;\ 86.259 + cycles -= ((mod == 3) ? 3 : 7); \ 86.260 + break; \ 86.261 + case 0x28: /*SHR l, c*/ \ 86.262 + seteal(temp >> c); if (abrt) return 0; \ 86.263 + setznp32(temp >> c); \ 86.264 + if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ 86.265 + if (c == 1 && temp & 0x80000000) flags |= V_FLAG; \ 86.266 + cycles -= ((mod == 3) ? 3 : 7); \ 86.267 + break; \ 86.268 + case 0x38: /*SAR l, c*/ \ 86.269 + tempc = ((temp >> (c - 1)) & 1); \ 86.270 + while (c > 0) \ 86.271 + { \ 86.272 + temp >>= 1; \ 86.273 + if (temp & 0x40000000) temp |= 0x80000000; \ 86.274 + c--; \ 86.275 + } \ 86.276 + seteal(temp); if (abrt) return 0; \ 86.277 + setznp32(temp); \ 86.278 + if (tempc) flags |= C_FLAG; \ 86.279 + cycles -= ((mod == 3) ? 3 : 7); \ 86.280 + break; \ 86.281 + } 86.282 + 86.283 +static int opC0_a16(uint32_t fetchdat) 86.284 +{ 86.285 + int c; 86.286 + int tempc; 86.287 + uint8_t temp, temp2; 86.288 + 86.289 + fetch_ea_16(fetchdat); 86.290 + c = readmemb(cs, pc) & 31; pc++; 86.291 + temp = geteab(); if (abrt) return 0; 86.292 + OP_SHIFT_b(c); 86.293 + return 0; 86.294 +} 86.295 +static int opC0_a32(uint32_t fetchdat) 86.296 +{ 86.297 + int c; 86.298 + int tempc; 86.299 + uint8_t temp, temp2; 86.300 + 86.301 + fetch_ea_32(fetchdat); 86.302 + c = readmemb(cs, pc) & 31; pc++; 86.303 + temp = geteab(); if (abrt) return 0; 86.304 + OP_SHIFT_b(c); 86.305 + return 0; 86.306 +} 86.307 +static int opC1_w_a16(uint32_t fetchdat) 86.308 +{ 86.309 + int c; 86.310 + int tempc; 86.311 + uint16_t temp, temp2; 86.312 + 86.313 + fetch_ea_16(fetchdat); 86.314 + c = readmemb(cs, pc) & 31; pc++; 86.315 + temp = geteaw(); if (abrt) return 0; 86.316 + OP_SHIFT_w(c); 86.317 + return 0; 86.318 +} 86.319 +static int opC1_w_a32(uint32_t fetchdat) 86.320 +{ 86.321 + int c; 86.322 + int tempc; 86.323 + uint16_t temp, temp2; 86.324 + 86.325 + fetch_ea_32(fetchdat); 86.326 + c = readmemb(cs, pc) & 31; pc++; 86.327 + temp = geteaw(); if (abrt) return 0; 86.328 + OP_SHIFT_w(c); 86.329 + return 0; 86.330 +} 86.331 +static int opC1_l_a16(uint32_t fetchdat) 86.332 +{ 86.333 + int c; 86.334 + int tempc; 86.335 + uint32_t temp, temp2; 86.336 + 86.337 + fetch_ea_16(fetchdat); 86.338 + c = readmemb(cs, pc) & 31; pc++; 86.339 + temp = geteal(); if (abrt) return 0; 86.340 + OP_SHIFT_l(c); 86.341 + return 0; 86.342 +} 86.343 +static int opC1_l_a32(uint32_t fetchdat) 86.344 +{ 86.345 + int c; 86.346 + int tempc; 86.347 + uint32_t temp, temp2; 86.348 + 86.349 + fetch_ea_32(fetchdat); 86.350 + c = readmemb(cs, pc) & 31; pc++; 86.351 + temp = geteal(); if (abrt) return 0; 86.352 + OP_SHIFT_l(c); 86.353 + return 0; 86.354 +} 86.355 + 86.356 +static int opD0_a16(uint32_t fetchdat) 86.357 +{ 86.358 + int c = 1; 86.359 + int tempc; 86.360 + uint8_t temp, temp2; 86.361 + 86.362 + fetch_ea_16(fetchdat); 86.363 + temp = geteab(); if (abrt) return 0; 86.364 + OP_SHIFT_b(c); 86.365 + return 0; 86.366 +} 86.367 +static int opD0_a32(uint32_t fetchdat) 86.368 +{ 86.369 + int c = 1; 86.370 + int tempc; 86.371 + uint8_t temp, temp2; 86.372 + 86.373 + fetch_ea_32(fetchdat); 86.374 + temp = geteab(); if (abrt) return 0; 86.375 + OP_SHIFT_b(c); 86.376 + return 0; 86.377 +} 86.378 +static int opD1_w_a16(uint32_t fetchdat) 86.379 +{ 86.380 + int c = 1; 86.381 + int tempc; 86.382 + uint16_t temp, temp2; 86.383 + 86.384 + fetch_ea_16(fetchdat); 86.385 + temp = geteaw(); if (abrt) return 0; 86.386 + OP_SHIFT_w(c); 86.387 + return 0; 86.388 +} 86.389 +static int opD1_w_a32(uint32_t fetchdat) 86.390 +{ 86.391 + int c = 1; 86.392 + int tempc; 86.393 + uint16_t temp, temp2; 86.394 + 86.395 + fetch_ea_32(fetchdat); 86.396 + temp = geteaw(); if (abrt) return 0; 86.397 + OP_SHIFT_w(c); 86.398 + return 0; 86.399 +} 86.400 +static int opD1_l_a16(uint32_t fetchdat) 86.401 +{ 86.402 + int c = 1; 86.403 + int tempc; 86.404 + uint32_t temp, temp2; 86.405 + 86.406 + fetch_ea_16(fetchdat); 86.407 + temp = geteal(); if (abrt) return 0; 86.408 + OP_SHIFT_l(c); 86.409 + return 0; 86.410 +} 86.411 +static int opD1_l_a32(uint32_t fetchdat) 86.412 +{ 86.413 + int c = 1; 86.414 + int tempc; 86.415 + uint32_t temp, temp2; 86.416 + 86.417 + fetch_ea_32(fetchdat); 86.418 + temp = geteal(); if (abrt) return 0; 86.419 + OP_SHIFT_l(c); 86.420 + return 0; 86.421 +} 86.422 + 86.423 +static int opD2_a16(uint32_t fetchdat) 86.424 +{ 86.425 + int c; 86.426 + int tempc; 86.427 + uint8_t temp, temp2; 86.428 + 86.429 + fetch_ea_16(fetchdat); 86.430 + c = CL & 31; 86.431 + temp = geteab(); if (abrt) return 0; 86.432 + OP_SHIFT_b(c); 86.433 + return 0; 86.434 +} 86.435 +static int opD2_a32(uint32_t fetchdat) 86.436 +{ 86.437 + int c; 86.438 + int tempc; 86.439 + uint8_t temp, temp2; 86.440 + 86.441 + fetch_ea_32(fetchdat); 86.442 + c = CL & 31; 86.443 + temp = geteab(); if (abrt) return 0; 86.444 + OP_SHIFT_b(c); 86.445 + return 0; 86.446 +} 86.447 +static int opD3_w_a16(uint32_t fetchdat) 86.448 +{ 86.449 + int c; 86.450 + int tempc; 86.451 + uint16_t temp, temp2; 86.452 + 86.453 + fetch_ea_16(fetchdat); 86.454 + c = CL & 31; 86.455 + temp = geteaw(); if (abrt) return 0; 86.456 + OP_SHIFT_w(c); 86.457 + return 0; 86.458 +} 86.459 +static int opD3_w_a32(uint32_t fetchdat) 86.460 +{ 86.461 + int c; 86.462 + int tempc; 86.463 + uint16_t temp, temp2; 86.464 + 86.465 + fetch_ea_32(fetchdat); 86.466 + c = CL & 31; 86.467 + temp = geteaw(); if (abrt) return 0; 86.468 + OP_SHIFT_w(c); 86.469 + return 0; 86.470 +} 86.471 +static int opD3_l_a16(uint32_t fetchdat) 86.472 +{ 86.473 + int c; 86.474 + int tempc; 86.475 + uint32_t temp, temp2; 86.476 + 86.477 + fetch_ea_16(fetchdat); 86.478 + c = CL & 31; 86.479 + temp = geteal(); if (abrt) return 0; 86.480 + OP_SHIFT_l(c); 86.481 + return 0; 86.482 +} 86.483 +static int opD3_l_a32(uint32_t fetchdat) 86.484 +{ 86.485 + int c; 86.486 + int tempc; 86.487 + uint32_t temp, temp2; 86.488 + 86.489 + fetch_ea_32(fetchdat); 86.490 + c = CL & 31; 86.491 + temp = geteal(); if (abrt) return 0; 86.492 + OP_SHIFT_l(c); 86.493 + return 0; 86.494 +} 86.495 + 86.496 + 86.497 +#define SHLD_w() \ 86.498 + if (count) \ 86.499 + { \ 86.500 + uint16_t tempw = geteaw(); if (abrt) return 0; \ 86.501 + int tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ 86.502 + uint32_t templ = (tempw << 16) | regs[reg].w; \ 86.503 + if (count <= 16) tempw = templ >> (16 - count); \ 86.504 + else tempw = (templ << count) >> 16; \ 86.505 + seteaw(tempw); if (abrt) return 0; \ 86.506 + setznp16(tempw); \ 86.507 + flags_rebuild(); \ 86.508 + if (tempc) flags |= C_FLAG; \ 86.509 + } 86.510 + 86.511 +#define SHLD_l() \ 86.512 + if (count) \ 86.513 + { \ 86.514 + uint32_t templ = geteal(); if (abrt) return 0; \ 86.515 + int tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ 86.516 + templ = (templ << count) | (regs[reg].l >> (32 - count)); \ 86.517 + seteal(templ); if (abrt) return 0; \ 86.518 + setznp32(templ); \ 86.519 + flags_rebuild(); \ 86.520 + if (tempc) flags |= C_FLAG; \ 86.521 + } 86.522 + 86.523 + 86.524 +#define SHRD_w() \ 86.525 + if (count) \ 86.526 + { \ 86.527 + uint16_t tempw = geteaw(); if (abrt) return 0; \ 86.528 + int tempc = (tempw >> (count - 1)) & 1; \ 86.529 + uint32_t templ = tempw | (regs[reg].w << 16); \ 86.530 + tempw = templ >> count; \ 86.531 + seteaw(tempw); if (abrt) return 0; \ 86.532 + setznp16(tempw); \ 86.533 + flags_rebuild(); \ 86.534 + if (tempc) flags |= C_FLAG; \ 86.535 + } 86.536 + 86.537 +#define SHRD_l() \ 86.538 + if (count) \ 86.539 + { \ 86.540 + uint32_t templ = geteal(); if (abrt) return 0; \ 86.541 + int tempc = (templ >> (count - 1)) & 1; \ 86.542 + templ = (templ >> count) | (regs[reg].l << (32 - count)); \ 86.543 + seteal(templ); if (abrt) return 0; \ 86.544 + setznp32(templ); \ 86.545 + flags_rebuild(); \ 86.546 + if (tempc) flags |= C_FLAG; \ 86.547 + } 86.548 + 86.549 +#define opSHxD(operation) \ 86.550 + static int op ## operation ## _i_a16(uint32_t fetchdat) \ 86.551 + { \ 86.552 + int count; \ 86.553 + \ 86.554 + fetch_ea_16(fetchdat); \ 86.555 + count = getbyte() & 31; \ 86.556 + operation(); \ 86.557 + \ 86.558 + cycles -= 3; \ 86.559 + return 0; \ 86.560 + } \ 86.561 + static int op ## operation ## _CL_a16(uint32_t fetchdat) \ 86.562 + { \ 86.563 + int count; \ 86.564 + \ 86.565 + fetch_ea_16(fetchdat); \ 86.566 + count = CL & 31; \ 86.567 + operation(); \ 86.568 + \ 86.569 + cycles -= 3; \ 86.570 + return 0; \ 86.571 + } \ 86.572 + static int op ## operation ## _i_a32(uint32_t fetchdat) \ 86.573 + { \ 86.574 + int count; \ 86.575 + \ 86.576 + fetch_ea_32(fetchdat); \ 86.577 + count = getbyte() & 31; \ 86.578 + operation(); \ 86.579 + \ 86.580 + cycles -= 3; \ 86.581 + return 0; \ 86.582 + } \ 86.583 + static int op ## operation ## _CL_a32(uint32_t fetchdat) \ 86.584 + { \ 86.585 + int count; \ 86.586 + \ 86.587 + fetch_ea_32(fetchdat); \ 86.588 + count = CL & 31; \ 86.589 + operation(); \ 86.590 + \ 86.591 + cycles -= 3; \ 86.592 + return 0; \ 86.593 + } 86.594 + 86.595 +opSHxD(SHLD_w) 86.596 +opSHxD(SHLD_l) 86.597 +opSHxD(SHRD_w) 86.598 +opSHxD(SHRD_l)
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 87.2 +++ b/src/x86_ops_stack.h Mon May 27 19:56:33 2013 +0100 87.3 @@ -0,0 +1,447 @@ 87.4 +#define PUSH_W_OP(reg) \ 87.5 + static int opPUSH_ ## reg (uint32_t fetchdat) \ 87.6 + { \ 87.7 + if (ssegs) ss=oldss; \ 87.8 + PUSH_W(reg); \ 87.9 + cycles -= (is486) ? 1 : 2; \ 87.10 + return 0; \ 87.11 + } 87.12 + 87.13 +#define PUSH_L_OP(reg) \ 87.14 + static int opPUSH_ ## reg (uint32_t fetchdat) \ 87.15 + { \ 87.16 + if (ssegs) ss=oldss; \ 87.17 + PUSH_L(reg); \ 87.18 + cycles -= (is486) ? 1 : 2; \ 87.19 + return 0; \ 87.20 + } 87.21 + 87.22 +#define POP_W_OP(reg) \ 87.23 + static int opPOP_ ## reg (uint32_t fetchdat) \ 87.24 + { \ 87.25 + if (ssegs) ss=oldss; \ 87.26 + reg = POP_W(); \ 87.27 + cycles -= (is486) ? 1 : 4; \ 87.28 + return 0; \ 87.29 + } 87.30 + 87.31 +#define POP_L_OP(reg) \ 87.32 + static int opPOP_ ## reg (uint32_t fetchdat) \ 87.33 + { \ 87.34 + if (ssegs) ss=oldss; \ 87.35 + reg = POP_L(); \ 87.36 + cycles -= (is486) ? 1 : 4; \ 87.37 + return 0; \ 87.38 + } 87.39 + 87.40 +PUSH_W_OP(AX) 87.41 +PUSH_W_OP(BX) 87.42 +PUSH_W_OP(CX) 87.43 +PUSH_W_OP(DX) 87.44 +PUSH_W_OP(SI) 87.45 +PUSH_W_OP(DI) 87.46 +PUSH_W_OP(BP) 87.47 +PUSH_W_OP(SP) 87.48 + 87.49 +PUSH_L_OP(EAX) 87.50 +PUSH_L_OP(EBX) 87.51 +PUSH_L_OP(ECX) 87.52 +PUSH_L_OP(EDX) 87.53 +PUSH_L_OP(ESI) 87.54 +PUSH_L_OP(EDI) 87.55 +PUSH_L_OP(EBP) 87.56 +PUSH_L_OP(ESP) 87.57 + 87.58 +POP_W_OP(AX) 87.59 +POP_W_OP(BX) 87.60 +POP_W_OP(CX) 87.61 +POP_W_OP(DX) 87.62 +POP_W_OP(SI) 87.63 +POP_W_OP(DI) 87.64 +POP_W_OP(BP) 87.65 +POP_W_OP(SP) 87.66 + 87.67 +POP_L_OP(EAX) 87.68 +POP_L_OP(EBX) 87.69 +POP_L_OP(ECX) 87.70 +POP_L_OP(EDX) 87.71 +POP_L_OP(ESI) 87.72 +POP_L_OP(EDI) 87.73 +POP_L_OP(EBP) 87.74 +POP_L_OP(ESP) 87.75 + 87.76 + 87.77 +static int opPUSHA_w(uint32_t fetchdat) 87.78 +{ 87.79 + if (stack32) 87.80 + { 87.81 + writememw(ss, ESP - 2, AX); 87.82 + writememw(ss, ESP - 4, CX); 87.83 + writememw(ss, ESP - 6, DX); 87.84 + writememw(ss, ESP - 8, BX); 87.85 + writememw(ss, ESP - 10, SP); 87.86 + writememw(ss, ESP - 12, BP); 87.87 + writememw(ss, ESP - 14, SI); 87.88 + writememw(ss, ESP - 16, DI); 87.89 + if (!abrt) ESP -= 16; 87.90 + } 87.91 + else 87.92 + { 87.93 + writememw(ss, ((SP - 2) & 0xFFFF), AX); 87.94 + writememw(ss, ((SP - 4) & 0xFFFF), CX); 87.95 + writememw(ss, ((SP - 6) & 0xFFFF), DX); 87.96 + writememw(ss, ((SP - 8) & 0xFFFF), BX); 87.97 + writememw(ss, ((SP - 10) & 0xFFFF), SP); 87.98 + writememw(ss, ((SP - 12) & 0xFFFF), BP); 87.99 + writememw(ss, ((SP - 14) & 0xFFFF), SI); 87.100 + writememw(ss, ((SP - 16) & 0xFFFF), DI); 87.101 + if (!abrt) SP -= 16; 87.102 + } 87.103 + cycles -= (is486) ? 11 : 18; 87.104 + return 0; 87.105 +} 87.106 +static int opPUSHA_l(uint32_t fetchdat) 87.107 +{ 87.108 + if (stack32) 87.109 + { 87.110 + writememl(ss, ESP - 4, EAX); 87.111 + writememl(ss, ESP - 8, ECX); 87.112 + writememl(ss, ESP - 12, EDX); 87.113 + writememl(ss, ESP - 16, EBX); 87.114 + writememl(ss, ESP - 20, ESP); 87.115 + writememl(ss, ESP - 24, EBP); 87.116 + writememl(ss, ESP - 28, ESI); 87.117 + writememl(ss, ESP - 32, EDI); 87.118 + if (!abrt) ESP -= 32; 87.119 + } 87.120 + else 87.121 + { 87.122 + writememl(ss, ((SP - 4) & 0xFFFF), EAX); 87.123 + writememl(ss, ((SP - 8) & 0xFFFF), ECX); 87.124 + writememl(ss, ((SP - 12) & 0xFFFF), EDX); 87.125 + writememl(ss, ((SP - 16) & 0xFFFF), EBX); 87.126 + writememl(ss, ((SP - 20) & 0xFFFF), ESP); 87.127 + writememl(ss, ((SP - 24) & 0xFFFF), EBP); 87.128 + writememl(ss, ((SP - 28) & 0xFFFF), ESI); 87.129 + writememl(ss, ((SP - 32) & 0xFFFF), EDI); 87.130 + if (!abrt) SP -= 32; 87.131 + } 87.132 + cycles -= (is486) ? 11 : 18; 87.133 + return 0; 87.134 +} 87.135 + 87.136 +static int opPOPA_w(uint32_t fetchdat) 87.137 +{ 87.138 + if (stack32) 87.139 + { 87.140 + DI = readmemw(ss, ESP); if (abrt) return 0; 87.141 + SI = readmemw(ss, ESP + 2); if (abrt) return 0; 87.142 + BP = readmemw(ss, ESP + 4); if (abrt) return 0; 87.143 + BX = readmemw(ss, ESP + 8); if (abrt) return 0; 87.144 + DX = readmemw(ss, ESP + 10); if (abrt) return 0; 87.145 + CX = readmemw(ss, ESP + 12); if (abrt) return 0; 87.146 + AX = readmemw(ss, ESP + 14); if (abrt) return 0; 87.147 + ESP += 16; 87.148 + } 87.149 + else 87.150 + { 87.151 + DI = readmemw(ss, ((SP) & 0xFFFF)); if (abrt) return 0; 87.152 + SI = readmemw(ss, ((SP + 2) & 0xFFFF)); if (abrt) return 0; 87.153 + BP = readmemw(ss, ((SP + 4) & 0xFFFF)); if (abrt) return 0; 87.154 + BX = readmemw(ss, ((SP + 8) & 0xFFFF)); if (abrt) return 0; 87.155 + DX = readmemw(ss, ((SP + 10) & 0xFFFF)); if (abrt) return 0; 87.156 + CX = readmemw(ss, ((SP + 12) & 0xFFFF)); if (abrt) return 0; 87.157 + AX = readmemw(ss, ((SP + 14) & 0xFFFF)); if (abrt) return 0; 87.158 + SP += 16; 87.159 + } 87.160 + cycles -= (is486) ? 9 : 24; 87.161 + return 0; 87.162 +} 87.163 +static int opPOPA_l(uint32_t fetchdat) 87.164 +{ 87.165 + if (stack32) 87.166 + { 87.167 + EDI = readmeml(ss, ESP); if (abrt) return 0; 87.168 + ESI = readmeml(ss, ESP + 4); if (abrt) return 0; 87.169 + EBP = readmeml(ss, ESP + 8); if (abrt) return 0; 87.170 + EBX = readmeml(ss, ESP + 16); if (abrt) return 0; 87.171 + EDX = readmeml(ss, ESP + 20); if (abrt) return 0; 87.172 + ECX = readmeml(ss, ESP + 24); if (abrt) return 0; 87.173 + EAX = readmeml(ss, ESP + 28); if (abrt) return 0; 87.174 + ESP += 32; 87.175 + } 87.176 + else 87.177 + { 87.178 + EDI = readmeml(ss, ((SP) & 0xFFFF)); if (abrt) return 0; 87.179 + ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (abrt) return 0; 87.180 + EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (abrt) return 0; 87.181 + EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (abrt) return 0; 87.182 + EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (abrt) return 0; 87.183 + ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (abrt) return 0; 87.184 + EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (abrt) return 0; 87.185 + SP += 32; 87.186 + } 87.187 + cycles -= (is486) ? 9 : 24; 87.188 + return 0; 87.189 +} 87.190 + 87.191 +static int opPUSH_imm_w(uint32_t fetchdat) 87.192 +{ 87.193 + uint16_t val = getwordf(); 87.194 + if (ssegs) ss=oldss; 87.195 + PUSH_W(val); 87.196 + cycles -= 2; 87.197 + return 0; 87.198 +} 87.199 +static int opPUSH_imm_l(uint32_t fetchdat) 87.200 +{ 87.201 + uint32_t val = getlong(); 87.202 + if (ssegs) ss=oldss; 87.203 + PUSH_L(val); 87.204 + cycles -= 2; 87.205 + return 0; 87.206 +} 87.207 + 87.208 +static int opPUSH_imm_bw(uint32_t fetchdat) 87.209 +{ 87.210 + uint16_t tempw = getbytef(); 87.211 + 87.212 + if (tempw & 0x80) tempw |= 0xFF00; 87.213 + PUSH_W(tempw); 87.214 + 87.215 + cycles -= 2; 87.216 + return 0; 87.217 +} 87.218 +static int opPUSH_imm_bl(uint32_t fetchdat) 87.219 +{ 87.220 + uint32_t templ = getbytef(); 87.221 + 87.222 + if (templ & 0x80) templ |= 0xFFFFFF00; 87.223 + PUSH_L(templ); 87.224 + 87.225 + cycles -= 2; 87.226 + return 0; 87.227 +} 87.228 + 87.229 +static int opPOPW_a16(uint32_t fetchdat) 87.230 +{ 87.231 + uint16_t temp; 87.232 + 87.233 + if (ssegs) ss=oldss; 87.234 + temp = POP_W(); if (abrt) return 0; 87.235 + fetch_ea_16(fetchdat); 87.236 + seteaw(temp); 87.237 + if (abrt) 87.238 + { 87.239 + if (stack32) ESP -= 2; 87.240 + else SP -= 2; 87.241 + } 87.242 + 87.243 + if (is486) cycles -= ((mod == 3) ? 1 : 6); 87.244 + else cycles -= ((mod == 3) ? 4 : 5); 87.245 + return 0; 87.246 +} 87.247 +static int opPOPW_a32(uint32_t fetchdat) 87.248 +{ 87.249 + uint16_t temp; 87.250 + 87.251 + if (ssegs) ss=oldss; 87.252 + temp = POP_W(); if (abrt) return 0; 87.253 + fetch_ea_32(fetchdat); 87.254 + seteaw(temp); 87.255 + if (abrt) 87.256 + { 87.257 + if (stack32) ESP -= 2; 87.258 + else SP -= 2; 87.259 + } 87.260 + 87.261 + if (is486) cycles -= ((mod == 3) ? 1 : 6); 87.262 + else cycles -= ((mod == 3) ? 4 : 5); 87.263 + return 0; 87.264 +} 87.265 + 87.266 +static int opPOPL_a16(uint32_t fetchdat) 87.267 +{ 87.268 + uint32_t temp; 87.269 + 87.270 + if (ssegs) ss=oldss; 87.271 + temp = POP_L(); if (abrt) return 0; 87.272 + fetch_ea_16(fetchdat); 87.273 + seteal(temp); 87.274 + if (abrt) 87.275 + { 87.276 + if (stack32) ESP -= 4; 87.277 + else SP -= 4; 87.278 + } 87.279 + 87.280 + if (is486) cycles -= ((mod == 3) ? 1 : 6); 87.281 + else cycles -= ((mod == 3) ? 4 : 5); 87.282 + return 0; 87.283 +} 87.284 +static int opPOPL_a32(uint32_t fetchdat) 87.285 +{ 87.286 + uint32_t temp; 87.287 + 87.288 + if (ssegs) ss=oldss; 87.289 + temp = POP_L(); if (abrt) return 0; 87.290 + fetch_ea_32(fetchdat); 87.291 + seteal(temp); 87.292 + if (abrt) 87.293 + { 87.294 + if (stack32) ESP -= 4; 87.295 + else SP -= 4; 87.296 + } 87.297 + 87.298 + if (is486) cycles -= ((mod == 3) ? 1 : 6); 87.299 + else cycles -= ((mod == 3) ? 4 : 5); 87.300 + return 0; 87.301 +} 87.302 + 87.303 + 87.304 +static int opENTER_w(uint32_t fetchdat) 87.305 +{ 87.306 + uint16_t offset = getwordf(); 87.307 + int count = (fetchdat >> 16) & 0xff; pc++; 87.308 + uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr; 87.309 + 87.310 + PUSH_W(BP); 87.311 + frame_ptr = ESP; 87.312 + 87.313 + if (count > 0) 87.314 + { 87.315 + while (--count) 87.316 + { 87.317 + uint16_t tempw; 87.318 + 87.319 + BP -= 2; 87.320 + tempw = readmemw(ss, BP); 87.321 + if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } 87.322 + PUSH_W(tempw); 87.323 + if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } 87.324 + cycles -= (is486) ? 3 : 4; 87.325 + } 87.326 + PUSH_W(frame_ptr); 87.327 + if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } 87.328 + cycles -= (is486) ? 3 : 5; 87.329 + } 87.330 + BP = frame_ptr; 87.331 + 87.332 + if (stack32) ESP -= offset; 87.333 + else SP -= offset; 87.334 + cycles -= (is486) ? 14 : 10; 87.335 + return 0; 87.336 +} 87.337 +static int opENTER_l(uint32_t fetchdat) 87.338 +{ 87.339 + uint16_t offset = getwordf(); 87.340 + int count = (fetchdat >> 16) & 0xff; pc++; 87.341 + uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr; 87.342 + 87.343 + PUSH_L(EBP); 87.344 + frame_ptr = ESP; 87.345 + 87.346 + if (count > 0) 87.347 + { 87.348 + while (--count) 87.349 + { 87.350 + uint32_t templ; 87.351 + 87.352 + EBP -= 4; 87.353 + templ = readmeml(ss, EBP); 87.354 + if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } 87.355 + PUSH_L(templ); 87.356 + if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } 87.357 + cycles -= (is486) ? 3 : 4; 87.358 + } 87.359 + PUSH_L(frame_ptr); 87.360 + if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; } 87.361 + cycles -= (is486) ? 3 : 5; 87.362 + } 87.363 + EBP = frame_ptr; 87.364 + 87.365 + if (stack32) ESP -= offset; 87.366 + else SP -= offset; 87.367 + cycles -= (is486) ? 14 : 10; 87.368 + return 0; 87.369 +} 87.370 + 87.371 + 87.372 +static int opLEAVE_w(uint32_t fetchdat) 87.373 +{ 87.374 + uint32_t tempESP = ESP; 87.375 + uint16_t temp; 87.376 + 87.377 + SP = BP; 87.378 + temp = POP_W(); 87.379 + if (abrt) { ESP = tempESP; return 0; } 87.380 + BP = temp; 87.381 + 87.382 + cycles -= 4; 87.383 + return 0; 87.384 +} 87.385 +static int opLEAVE_l(uint32_t fetchdat) 87.386 +{ 87.387 + uint32_t tempESP = ESP; 87.388 + uint32_t temp; 87.389 + 87.390 + ESP = EBP; 87.391 + temp = POP_L(); 87.392 + if (abrt) { ESP = tempESP; return 0; } 87.393 + EBP = temp; 87.394 + 87.395 + cycles -= 4; 87.396 + return 0; 87.397 +} 87.398 + 87.399 + 87.400 +#define PUSH_SEG_OPS(seg) \ 87.401 + static int opPUSH_ ## seg ## _w(uint32_t fetchdat) \ 87.402 + { \ 87.403 + if (ssegs) ss=oldss; \ 87.404 + PUSH_W(seg); \ 87.405 + cycles -= 2; \ 87.406 + return 0; \ 87.407 + } \ 87.408 + static int opPUSH_ ## seg ## _l(uint32_t fetchdat) \ 87.409 + { \ 87.410 + if (ssegs) ss=oldss; \ 87.411 + PUSH_L(seg); \ 87.412 + cycles -= 2; \ 87.413 + return 0; \ 87.414 + } 87.415 + 87.416 +#define POP_SEG_OPS(seg, realseg) \ 87.417 + static int opPOP_ ## seg ## _w(uint32_t fetchdat) \ 87.418 + { \ 87.419 + uint16_t temp_seg; \ 87.420 + uint32_t temp_esp = ESP; \ 87.421 + if (ssegs) ss=oldss; \ 87.422 + temp_seg = POP_W(); if (abrt) return 0; \ 87.423 + loadseg(temp_seg, realseg); if (abrt) ESP = temp_esp; \ 87.424 + cycles -= is486 ? 3 : 7; \ 87.425 + return 0; \ 87.426 + } \ 87.427 + static int opPOP_ ## seg ## _l(uint32_t fetchdat) \ 87.428 + { \ 87.429 + uint32_t temp_seg; \ 87.430 + uint32_t temp_esp = ESP; \ 87.431 + if (ssegs) ss=oldss; \ 87.432 + temp_seg = POP_L(); if (abrt) return 0; \ 87.433 + loadseg(temp_seg & 0xffff, realseg); if (abrt) ESP = temp_esp; \ 87.434 + cycles -= is486 ? 3 : 7; \ 87.435 + return 0; \ 87.436 + } 87.437 + 87.438 + 87.439 +PUSH_SEG_OPS(CS); 87.440 +PUSH_SEG_OPS(DS); 87.441 +PUSH_SEG_OPS(ES); 87.442 +PUSH_SEG_OPS(FS); 87.443 +PUSH_SEG_OPS(GS); 87.444 +PUSH_SEG_OPS(SS); 87.445 + 87.446 +POP_SEG_OPS(DS, &_ds); 87.447 +POP_SEG_OPS(ES, &_es); 87.448 +POP_SEG_OPS(FS, &_fs); 87.449 +POP_SEG_OPS(GS, &_gs); 87.450 +POP_SEG_OPS(SS, &_ss);
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 88.2 +++ b/src/x86_ops_string.h Mon May 27 19:56:33 2013 +0100 88.3 @@ -0,0 +1,435 @@ 88.4 +static int opMOVSB_a16(uint32_t fetchdat) 88.5 +{ 88.6 + uint8_t temp = readmemb(ds,SI); if (abrt) return 0; 88.7 + writememb(es, DI, temp); if (abrt) return 0; 88.8 + if (flags & D_FLAG) { DI--; SI--; } 88.9 + else { DI++; SI++; } 88.10 + cycles -= 7; 88.11 + return 0; 88.12 +} 88.13 +static int opMOVSB_a32(uint32_t fetchdat) 88.14 +{ 88.15 + uint8_t temp = readmemb(ds,ESI); if (abrt) return 0; 88.16 + writememb(es, EDI, temp); if (abrt) return 0; 88.17 + if (flags & D_FLAG) { EDI--; ESI--; } 88.18 + else { EDI++; ESI++; } 88.19 + cycles -= 7; 88.20 + return 0; 88.21 +} 88.22 + 88.23 +static int opMOVSW_a16(uint32_t fetchdat) 88.24 +{ 88.25 + uint16_t temp = readmemw(ds,SI); if (abrt) return 0; 88.26 + writememw(es, DI, temp); if (abrt) return 0; 88.27 + if (flags & D_FLAG) { DI -= 2; SI -= 2; } 88.28 + else { DI += 2; SI += 2; } 88.29 + cycles -= 7; 88.30 + return 0; 88.31 +} 88.32 +static int opMOVSW_a32(uint32_t fetchdat) 88.33 +{ 88.34 + uint16_t temp = readmemw(ds,ESI); if (abrt) return 0; 88.35 + writememw(es, EDI, temp); if (abrt) return 0; 88.36 + if (flags & D_FLAG) { EDI -= 2; ESI -= 2; } 88.37 + else { EDI += 2; ESI += 2; } 88.38 + cycles -= 7; 88.39 + return 0; 88.40 +} 88.41 + 88.42 +static int opMOVSL_a16(uint32_t fetchdat) 88.43 +{ 88.44 + uint32_t temp = readmeml(ds,SI); if (abrt) return 0; 88.45 + writememl(es, DI, temp); if (abrt) return 0; 88.46 + if (flags & D_FLAG) { DI -= 4; SI -= 4; } 88.47 + else { DI += 4; SI += 4; } 88.48 + cycles -= 7; 88.49 + return 0; 88.50 +} 88.51 +static int opMOVSL_a32(uint32_t fetchdat) 88.52 +{ 88.53 + uint32_t temp = readmeml(ds,ESI); if (abrt) return 0; 88.54 + writememl(es, EDI, temp); if (abrt) return 0; 88.55 + if (flags & D_FLAG) { EDI -= 4; ESI -= 4; } 88.56 + else { EDI += 4; ESI += 4; } 88.57 + cycles -= 7; 88.58 + return 0; 88.59 +} 88.60 + 88.61 + 88.62 +static int opCMPSB_a16(uint32_t fetchdat) 88.63 +{ 88.64 + uint8_t src = readmemb(ds, SI); 88.65 + uint8_t dst = readmemb(es, DI); if (abrt) return 0; 88.66 + setsub8(src, dst); 88.67 + if (flags & D_FLAG) { DI--; SI--; } 88.68 + else { DI++; SI++; } 88.69 + cycles -= (is486) ? 8 : 10; 88.70 + return 0; 88.71 +} 88.72 +static int opCMPSB_a32(uint32_t fetchdat) 88.73 +{ 88.74 + uint8_t src = readmemb(ds, ESI); 88.75 + uint8_t dst = readmemb(es, EDI); if (abrt) return 0; 88.76 + setsub8(src, dst); 88.77 + if (flags & D_FLAG) { EDI--; ESI--; } 88.78 + else { EDI++; ESI++; } 88.79 + cycles -= (is486) ? 8 : 10; 88.80 + return 0; 88.81 +} 88.82 + 88.83 +static int opCMPSW_a16(uint32_t fetchdat) 88.84 +{ 88.85 + uint16_t src = readmemw(ds, SI); 88.86 + uint16_t dst = readmemw(es, DI); if (abrt) return 0; 88.87 + setsub16(src, dst); 88.88 + if (flags & D_FLAG) { DI -= 2; SI -= 2; } 88.89 + else { DI += 2; SI += 2; } 88.90 + cycles -= (is486) ? 8 : 10; 88.91 + return 0; 88.92 +} 88.93 +static int opCMPSW_a32(uint32_t fetchdat) 88.94 +{ 88.95 + uint16_t src = readmemw(ds, ESI); 88.96 + uint16_t dst = readmemw(es, EDI); if (abrt) return 0; 88.97 + setsub16(src, dst); 88.98 + if (flags & D_FLAG) { EDI -= 2; ESI -= 2; } 88.99 + else { EDI += 2; ESI += 2; } 88.100 + cycles -= (is486) ? 8 : 10; 88.101 + return 0; 88.102 +} 88.103 + 88.104 +static int opCMPSL_a16(uint32_t fetchdat) 88.105 +{ 88.106 + uint32_t src = readmeml(ds, SI); 88.107 + uint32_t dst = readmeml(es, DI); if (abrt) return 0; 88.108 + setsub32(src, dst); 88.109 + if (flags & D_FLAG) { DI -= 4; SI -= 4; } 88.110 + else { DI += 4; SI += 4; } 88.111 + cycles -= (is486) ? 8 : 10; 88.112 + return 0; 88.113 +} 88.114 +static int opCMPSL_a32(uint32_t fetchdat) 88.115 +{ 88.116 + uint32_t src = readmeml(ds, ESI); 88.117 + uint32_t dst = readmeml(es, EDI); if (abrt) return 0; 88.118 + setsub32(src, dst); 88.119 + if (flags & D_FLAG) { EDI -= 4; ESI -= 4; } 88.120 + else { EDI += 4; ESI += 4; } 88.121 + cycles -= (is486) ? 8 : 10; 88.122 + return 0; 88.123 +} 88.124 + 88.125 +static int opSTOSB_a16(uint32_t fetchdat) 88.126 +{ 88.127 + writememb(es, DI, AL); if (abrt) return 0; 88.128 + if (flags & D_FLAG) DI--; 88.129 + else DI++; 88.130 + cycles -= 4; 88.131 + return 0; 88.132 +} 88.133 +static int opSTOSB_a32(uint32_t fetchdat) 88.134 +{ 88.135 + writememb(es, EDI, AL); if (abrt) return 0; 88.136 + if (flags & D_FLAG) EDI--; 88.137 + else EDI++; 88.138 + cycles -= 4; 88.139 + return 0; 88.140 +} 88.141 + 88.142 +static int opSTOSW_a16(uint32_t fetchdat) 88.143 +{ 88.144 + writememw(es, DI, AX); if (abrt) return 0; 88.145 + if (flags & D_FLAG) DI -= 2; 88.146 + else DI += 2; 88.147 + cycles -= 4; 88.148 + return 0; 88.149 +} 88.150 +static int opSTOSW_a32(uint32_t fetchdat) 88.151 +{ 88.152 + writememw(es, EDI, AX); if (abrt) return 0; 88.153 + if (flags & D_FLAG) EDI -= 2; 88.154 + else EDI += 2; 88.155 + cycles -= 4; 88.156 + return 0; 88.157 +} 88.158 + 88.159 +static int opSTOSL_a16(uint32_t fetchdat) 88.160 +{ 88.161 + writememl(es, DI, EAX); if (abrt) return 0; 88.162 + if (flags & D_FLAG) DI -= 4; 88.163 + else DI += 4; 88.164 + cycles -= 4; 88.165 + return 0; 88.166 +} 88.167 +static int opSTOSL_a32(uint32_t fetchdat) 88.168 +{ 88.169 + writememl(es, EDI, EAX); if (abrt) return 0; 88.170 + if (flags & D_FLAG) EDI -= 4; 88.171 + else EDI += 4; 88.172 + cycles -= 4; 88.173 + return 0; 88.174 +} 88.175 + 88.176 + 88.177 +static int opLODSB_a16(uint32_t fetchdat) 88.178 +{ 88.179 + uint8_t temp = readmemb(ds, SI); if (abrt) return 0; 88.180 + AL = temp; 88.181 + if (flags & D_FLAG) SI--; 88.182 + else SI++; 88.183 + cycles -= 5; 88.184 + return 0; 88.185 +} 88.186 +static int opLODSB_a32(uint32_t fetchdat) 88.187 +{ 88.188 + uint8_t temp = readmemb(ds, ESI); if (abrt) return 0; 88.189 + AL = temp; 88.190 + if (flags & D_FLAG) ESI--; 88.191 + else ESI++; 88.192 + cycles -= 5; 88.193 + return 0; 88.194 +} 88.195 + 88.196 +static int opLODSW_a16(uint32_t fetchdat) 88.197 +{ 88.198 + uint16_t temp = readmemw(ds, SI); if (abrt) return 0; 88.199 + AX = temp; 88.200 + if (flags & D_FLAG) SI -= 2; 88.201 + else SI += 2; 88.202 + cycles -= 5; 88.203 + return 0; 88.204 +} 88.205 +static int opLODSW_a32(uint32_t fetchdat) 88.206 +{ 88.207 + uint16_t temp = readmemw(ds, ESI); if (abrt) return 0; 88.208 + AX = temp; 88.209 + if (flags & D_FLAG) ESI -= 2; 88.210 + else ESI += 2; 88.211 + cycles -= 5; 88.212 + return 0; 88.213 +} 88.214 + 88.215 +static int opLODSL_a16(uint32_t fetchdat) 88.216 +{ 88.217 + uint32_t temp = readmeml(ds, SI); if (abrt) return 0; 88.218 + EAX = temp; 88.219 + if (flags & D_FLAG) SI -= 4; 88.220 + else SI += 4; 88.221 + cycles -= 5; 88.222 + return 0; 88.223 +} 88.224 +static int opLODSL_a32(uint32_t fetchdat) 88.225 +{ 88.226 + uint32_t temp = readmeml(ds, ESI); if (abrt) return 0; 88.227 + EAX = temp; 88.228 + if (flags & D_FLAG) ESI -= 4; 88.229 + else ESI += 4; 88.230 + cycles -= 5; 88.231 + return 0; 88.232 +} 88.233 + 88.234 + 88.235 +static int opSCASB_a16(uint32_t fetchdat) 88.236 +{ 88.237 + uint8_t temp = readmemb(es, DI); if (abrt) return 0; 88.238 + setsub8(AL, temp); 88.239 + if (flags & D_FLAG) DI--; 88.240 + else DI++; 88.241 + cycles -= 7; 88.242 + return 0; 88.243 +} 88.244 +static int opSCASB_a32(uint32_t fetchdat) 88.245 +{ 88.246 + uint8_t temp = readmemb(es, EDI); if (abrt) return 0; 88.247 + setsub8(AL, temp); 88.248 + if (flags & D_FLAG) EDI--; 88.249 + else EDI++; 88.250 + cycles -= 7; 88.251 + return 0; 88.252 +} 88.253 + 88.254 +static int opSCASW_a16(uint32_t fetchdat) 88.255 +{ 88.256 + uint16_t temp = readmemw(es, DI); if (abrt) return 0; 88.257 + setsub16(AX, temp); 88.258 + if (flags & D_FLAG) DI -= 2; 88.259 + else DI += 2; 88.260 + cycles -= 7; 88.261 + return 0; 88.262 +} 88.263 +static int opSCASW_a32(uint32_t fetchdat) 88.264 +{ 88.265 + uint16_t temp = readmemw(es, EDI); if (abrt) return 0; 88.266 + setsub16(AX, temp); 88.267 + if (flags & D_FLAG) EDI -= 2; 88.268 + else EDI += 2; 88.269 + cycles -= 7; 88.270 + return 0; 88.271 +} 88.272 + 88.273 +static int opSCASL_a16(uint32_t fetchdat) 88.274 +{ 88.275 + uint32_t temp = readmeml(es, DI); if (abrt) return 0; 88.276 + setsub32(EAX, temp); 88.277 + if (flags & D_FLAG) DI -= 4; 88.278 + else DI += 4; 88.279 + cycles -= 7; 88.280 + return 0; 88.281 +} 88.282 +static int opSCASL_a32(uint32_t fetchdat) 88.283 +{ 88.284 + uint32_t temp = readmeml(es, EDI); if (abrt) return 0; 88.285 + setsub32(EAX, temp); 88.286 + if (flags & D_FLAG) EDI -= 4; 88.287 + else EDI += 4; 88.288 + cycles -= 7; 88.289 + return 0; 88.290 +} 88.291 + 88.292 +static int opINSB_a16(uint32_t fetchdat) 88.293 +{ 88.294 + uint8_t temp; 88.295 + check_io_perm(DX); 88.296 + temp = inb(DX); 88.297 + writememb(es, DI, temp); if (abrt) return 0; 88.298 + if (flags & D_FLAG) DI--; 88.299 + else DI++; 88.300 + cycles -= 15; 88.301 + return 0; 88.302 +} 88.303 +static int opINSB_a32(uint32_t fetchdat) 88.304 +{ 88.305 + uint8_t temp; 88.306 + check_io_perm(DX); 88.307 + temp = inb(DX); 88.308 + writememb(es, EDI, temp); if (abrt) return 0; 88.309 + if (flags & D_FLAG) EDI--; 88.310 + else EDI++; 88.311 + cycles -= 15; 88.312 + return 0; 88.313 +} 88.314 + 88.315 +static int opINSW_a16(uint32_t fetchdat) 88.316 +{ 88.317 + uint16_t temp; 88.318 + check_io_perm(DX); 88.319 + check_io_perm(DX + 1); 88.320 + temp = inw(DX); 88.321 + writememw(es, DI, temp); if (abrt) return 0; 88.322 + if (flags & D_FLAG) DI -= 2; 88.323 + else DI += 2; 88.324 + cycles -= 15; 88.325 + return 0; 88.326 +} 88.327 +static int opINSW_a32(uint32_t fetchdat) 88.328 +{ 88.329 + uint16_t temp; 88.330 + check_io_perm(DX); 88.331 + check_io_perm(DX + 1); 88.332 + temp = inw(DX); 88.333 + writememw(es, EDI, temp); if (abrt) return 0; 88.334 + if (flags & D_FLAG) EDI -= 2; 88.335 + else EDI += 2; 88.336 + cycles -= 15; 88.337 + return 0; 88.338 +} 88.339 + 88.340 +static int opINSL_a16(uint32_t fetchdat) 88.341 +{ 88.342 + uint32_t temp; 88.343 + check_io_perm(DX); 88.344 + check_io_perm(DX + 1); 88.345 + check_io_perm(DX + 2); 88.346 + check_io_perm(DX + 3); 88.347 + temp = inl(DX); 88.348 + writememl(es, DI, temp); if (abrt) return 0; 88.349 + if (flags & D_FLAG) DI -= 4; 88.350 + else DI += 4; 88.351 + cycles -= 15; 88.352 + return 0; 88.353 +} 88.354 +static int opINSL_a32(uint32_t fetchdat) 88.355 +{ 88.356 + uint32_t temp; 88.357 + check_io_perm(DX); 88.358 + check_io_perm(DX + 1); 88.359 + check_io_perm(DX + 2); 88.360 + check_io_perm(DX + 3); 88.361 + temp = inl(DX); 88.362 + writememl(es, EDI, temp); if (abrt) return 0; 88.363 + if (flags & D_FLAG) EDI -= 4; 88.364 + else EDI += 4; 88.365 + cycles -= 15; 88.366 + return 0; 88.367 +} 88.368 + 88.369 +static int opOUTSB_a16(uint32_t fetchdat) 88.370 +{ 88.371 + uint8_t temp = readmemb(ds, SI); if (abrt) return 0; 88.372 + check_io_perm(DX); 88.373 + if (flags & D_FLAG) SI--; 88.374 + else SI++; 88.375 + outb(DX, temp); 88.376 + cycles -= 14; 88.377 + return 0; 88.378 +} 88.379 +static int opOUTSB_a32(uint32_t fetchdat) 88.380 +{ 88.381 + uint8_t temp = readmemb(ds, ESI); if (abrt) return 0; 88.382 + check_io_perm(DX); 88.383 + if (flags & D_FLAG) ESI--; 88.384 + else ESI++; 88.385 + outb(DX, temp); 88.386 + cycles -= 14; 88.387 + return 0; 88.388 +} 88.389 + 88.390 +static int opOUTSW_a16(uint32_t fetchdat) 88.391 +{ 88.392 + uint16_t temp = readmemw(ds, SI); if (abrt) return 0; 88.393 + check_io_perm(DX); 88.394 + check_io_perm(DX + 1); 88.395 + if (flags & D_FLAG) SI -= 2; 88.396 + else SI += 2; 88.397 + outw(DX, temp); 88.398 + cycles -= 14; 88.399 + return 0; 88.400 +} 88.401 +static int opOUTSW_a32(uint32_t fetchdat) 88.402 +{ 88.403 + uint16_t temp = readmemw(ds, ESI); if (abrt) return 0; 88.404 + check_io_perm(DX); 88.405 + check_io_perm(DX + 1); 88.406 + if (flags & D_FLAG) ESI -= 2; 88.407 + else ESI += 2; 88.408 + outw(DX, temp); 88.409 + cycles -= 14; 88.410 + return 0; 88.411 +} 88.412 + 88.413 +static int opOUTSL_a16(uint32_t fetchdat) 88.414 +{ 88.415 + uint32_t temp = readmeml(ds, SI); if (abrt) return 0; 88.416 + check_io_perm(DX); 88.417 + check_io_perm(DX + 1); 88.418 + check_io_perm(DX + 2); 88.419 + check_io_perm(DX + 3); 88.420 + if (flags & D_FLAG) SI -= 4; 88.421 + else SI += 4; 88.422 + outl(EDX, temp); 88.423 + cycles -= 14; 88.424 + return 0; 88.425 +} 88.426 +static int opOUTSL_a32(uint32_t fetchdat) 88.427 +{ 88.428 + uint32_t temp = readmeml(ds, ESI); if (abrt) return 0; 88.429 + check_io_perm(DX); 88.430 + check_io_perm(DX + 1); 88.431 + check_io_perm(DX + 2); 88.432 + check_io_perm(DX + 3); 88.433 + if (flags & D_FLAG) ESI -= 4; 88.434 + else ESI += 4; 88.435 + outl(EDX, temp); 88.436 + cycles -= 14; 88.437 + return 0; 88.438 +}
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 89.2 +++ b/src/x86_ops_xchg.h Mon May 27 19:56:33 2013 +0100 89.3 @@ -0,0 +1,195 @@ 89.4 +static int opXCHG_b_a16(uint32_t fetchdat) 89.5 +{ 89.6 + uint8_t temp; 89.7 + fetch_ea_16(fetchdat); 89.8 + temp = geteab(); if (abrt) return 0; 89.9 + seteab(getr8(reg)); if (abrt) return 0; 89.10 + setr8(reg, temp); 89.11 + cycles -= ((mod == 3) ? 3 : 5); 89.12 + return 0; 89.13 +} 89.14 +static int opXCHG_b_a32(uint32_t fetchdat) 89.15 +{ 89.16 + uint8_t temp; 89.17 + fetch_ea_32(fetchdat); 89.18 + temp = geteab(); if (abrt) return 0; 89.19 + seteab(getr8(reg)); if (abrt) return 0; 89.20 + setr8(reg, temp); 89.21 + cycles -= ((mod == 3) ? 3 : 5); 89.22 + return 0; 89.23 +} 89.24 + 89.25 +static int opXCHG_w_a16(uint32_t fetchdat) 89.26 +{ 89.27 + uint16_t temp; 89.28 + fetch_ea_16(fetchdat); 89.29 + temp = geteaw(); if (abrt) return 0; 89.30 + seteaw(regs[reg].w); if (abrt) return 0; 89.31 + regs[reg].w = temp; 89.32 + cycles -= ((mod == 3) ? 3 : 5); 89.33 + return 0; 89.34 +} 89.35 +static int opXCHG_w_a32(uint32_t fetchdat) 89.36 +{ 89.37 + uint16_t temp; 89.38 + fetch_ea_32(fetchdat); 89.39 + temp = geteaw(); if (abrt) return 0; 89.40 + seteaw(regs[reg].w); if (abrt) return 0; 89.41 + regs[reg].w = temp; 89.42 + cycles -= ((mod == 3) ? 3 : 5); 89.43 + return 0; 89.44 +} 89.45 + 89.46 +static int opXCHG_l_a16(uint32_t fetchdat) 89.47 +{ 89.48 + uint32_t temp; 89.49 + fetch_ea_16(fetchdat); 89.50 + temp = geteal(); if (abrt) return 0; 89.51 + seteal(regs[reg].l); if (abrt) return 0; 89.52 + regs[reg].l = temp; 89.53 + cycles -= ((mod == 3) ? 3 : 5); 89.54 + return 0; 89.55 +} 89.56 +static int opXCHG_l_a32(uint32_t fetchdat) 89.57 +{ 89.58 + uint32_t temp; 89.59 + fetch_ea_32(fetchdat); 89.60 + temp = geteal(); if (abrt) return 0; 89.61 + seteal(regs[reg].l); if (abrt) return 0; 89.62 + regs[reg].l = temp; 89.63 + cycles -= ((mod == 3) ? 3 : 5); 89.64 + return 0; 89.65 +} 89.66 + 89.67 + 89.68 +static int opXCHG_AX_BX(uint32_t fetchdat) 89.69 +{ 89.70 + uint16_t temp = AX; 89.71 + AX = BX; 89.72 + BX = temp; 89.73 + cycles -= 3; 89.74 + return 0; 89.75 +} 89.76 +static int opXCHG_AX_CX(uint32_t fetchdat) 89.77 +{ 89.78 + uint16_t temp = AX; 89.79 + AX = CX; 89.80 + CX = temp; 89.81 + cycles -= 3; 89.82 + return 0; 89.83 +} 89.84 +static int opXCHG_AX_DX(uint32_t fetchdat) 89.85 +{ 89.86 + uint16_t temp = AX; 89.87 + AX = DX; 89.88 + DX = temp; 89.89 + cycles -= 3; 89.90 + return 0; 89.91 +} 89.92 +static int opXCHG_AX_SI(uint32_t fetchdat) 89.93 +{ 89.94 + uint16_t temp = AX; 89.95 + AX = SI; 89.96 + SI = temp; 89.97 + cycles -= 3; 89.98 + return 0; 89.99 +} 89.100 +static int opXCHG_AX_DI(uint32_t fetchdat) 89.101 +{ 89.102 + uint16_t temp = AX; 89.103 + AX = DI; 89.104 + DI = temp; 89.105 + cycles -= 3; 89.106 + return 0; 89.107 +} 89.108 +static int opXCHG_AX_BP(uint32_t fetchdat) 89.109 +{ 89.110 + uint16_t temp = AX; 89.111 + AX = BP; 89.112 + BP = temp; 89.113 + cycles -= 3; 89.114 + return 0; 89.115 +} 89.116 +static int opXCHG_AX_SP(uint32_t fetchdat) 89.117 +{ 89.118 + uint16_t temp = AX; 89.119 + AX = SP; 89.120 + SP = temp; 89.121 + cycles -= 3; 89.122 + return 0; 89.123 +} 89.124 + 89.125 +static int opXCHG_EAX_EBX(uint32_t fetchdat) 89.126 +{ 89.127 + uint32_t temp = EAX; 89.128 + EAX = EBX; 89.129 + EBX = temp; 89.130 + cycles -= 3; 89.131 + return 0; 89.132 +} 89.133 +static int opXCHG_EAX_ECX(uint32_t fetchdat) 89.134 +{ 89.135 + uint32_t temp = EAX; 89.136 + EAX = ECX; 89.137 + ECX = temp; 89.138 + cycles -= 3; 89.139 + return 0; 89.140 +} 89.141 +static int opXCHG_EAX_EDX(uint32_t fetchdat) 89.142 +{ 89.143 + uint32_t temp = EAX; 89.144 + EAX = EDX; 89.145 + EDX = temp; 89.146 + cycles -= 3; 89.147 + return 0; 89.148 +} 89.149 +static int opXCHG_EAX_ESI(uint32_t fetchdat) 89.150 +{ 89.151 + uint32_t temp = EAX; 89.152 + EAX = ESI; 89.153 + ESI = temp; 89.154 + cycles -= 3; 89.155 + return 0; 89.156 +} 89.157 +static int opXCHG_EAX_EDI(uint32_t fetchdat) 89.158 +{ 89.159 + uint32_t temp = EAX; 89.160 + EAX = EDI; 89.161 + EDI = temp; 89.162 + cycles -= 3; 89.163 + return 0; 89.164 +} 89.165 +static int opXCHG_EAX_EBP(uint32_t fetchdat) 89.166 +{ 89.167 + uint32_t temp = EAX; 89.168 + EAX = EBP; 89.169 + EBP = temp; 89.170 + cycles -= 3; 89.171 + return 0; 89.172 +} 89.173 +static int opXCHG_EAX_ESP(uint32_t fetchdat) 89.174 +{ 89.175 + uint32_t temp = EAX; 89.176 + EAX = ESP; 89.177 + ESP = temp; 89.178 + cycles -= 3; 89.179 + return 0; 89.180 +} 89.181 + 89.182 + 89.183 +#define opBSWAP(reg) \ 89.184 + static int opBSWAP_ ## reg(uint32_t fetchdat) \ 89.185 + { \ 89.186 + reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \ 89.187 + cycles--; \ 89.188 + return 0; \ 89.189 + } 89.190 + 89.191 +opBSWAP(EAX) 89.192 +opBSWAP(EBX) 89.193 +opBSWAP(ECX) 89.194 +opBSWAP(EDX) 89.195 +opBSWAP(ESI) 89.196 +opBSWAP(EDI) 89.197 +opBSWAP(EBP) 89.198 +opBSWAP(ESP)
