PCem
changeset 1:fb4a67daaa1b
Now up to date with current dev version.
Changes since v0.7 :
- Major CPU reorganisation. This has possibly broken some stuff, though I fixed all the regressions I could find
- Lazy flags. This brought 10% speed improvement at one point, but that's probably been lost now
- 430 VX chipset emulation
- IDT Winchip emulation (currently sans MMX). Timing is probably wrong
- Fixed a few FPU bugs
- Timer reorganisation
- Sound reorganisation
- Other general reorganisation
- AdLib Gold emulation
- Windows Sound System emulation
- Pro Audio Spectrum 16 emulation. This currently works with most DOS stuff, but not in Windows
- Major improvements to GUS emulation. Has the downside that it now conflicts with SB emulation, so probably best to not enable both simultaneously
- New graphics cards :
- ATI-18800 (VGA Edge-16)
- ATI-28800 (VGA Charger)
- ATI Mach64GX (Graphics Pro Turbo). Quite a few features missing, but Windows doesn't seem to use half the features of this card
- Cirrus Logic CL-GD5429. Blitter is a bit broken
- Oak OTI-067
- S3 Trio64 (Number Nine 9FX)
- S3 Virge. Only framebuffer stuff at the minute, Windows won't recognise the card
- Trident TGUI-9440
- VGA. Doesn't work yet
- Beginnings of 3DFX emulation, however this is in extremely early stages and doesn't do anything useful
- Fixed DMA bug stopping floppy drives working in Windows 3.x
- Fixed some other stuff probably
- Broke some other stuff probably as well
line diff
1.1 --- a/src/386.c Sun Apr 21 14:54:35 2013 +0100 1.2 +++ b/src/386.c Mon May 27 17:46:42 2013 +0100 1.3 @@ -1,9 +1,3 @@ 1.4 -//61% 1.5 -//Win 3.1 - Timer (vtdapi.386) IRQ handler 80020E04 stores to 800200F8 1.6 - 1.7 -//11A2D 1.8 -//3EF08 - SYS_FloatTime() 1.9 - 1.10 #include <stdio.h> 1.11 #include <stdint.h> 1.12 #include <stdlib.h> 1.13 @@ -13,14 +7,24 @@ 1.14 #include "mem.h" 1.15 #include "cpu.h" 1.16 #include "fdc.h" 1.17 +#include "timer.h" 1.18 #include "video.h" 1.19 1.20 -extern int resets; 1.21 -int gpf = 0; 1.22 -int ins2 = 0; 1.23 +int nmi_enable = 1; 1.24 1.25 -// pclog("IO perm fail on %04X\n",port); \ 1.26 +int inscounts[256]; 1.27 +uint32_t oldpc2; 1.28 1.29 +#define check_io_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ 1.30 + { \ 1.31 + int tempi = checkio(port); \ 1.32 + if (abrt) return 0; \ 1.33 + if (tempi) \ 1.34 + { \ 1.35 + x86gpf(NULL,0); \ 1.36 + return 0; \ 1.37 + } \ 1.38 + } 1.39 1.40 #define checkio_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ 1.41 { \ 1.42 @@ -42,26 +46,12 @@ 1.43 uint16_t rds; 1.44 uint16_t ea_rseg; 1.45 1.46 -int hitits=0; 1.47 - 1.48 -uint32_t oldpc2; 1.49 int is486; 1.50 int cgate32; 1.51 -uint8_t opcode2; 1.52 -int incga; 1.53 -int enters=0; 1.54 -int ec; 1.55 1.56 -uint32_t ten3688; 1.57 -int oldv86=0,oldpmode=0,itson=0; 1.58 -uint8_t old22; 1.59 #undef readmemb 1.60 #undef writememb 1.61 1.62 -//#define readmemb(s,a) readmemb386l(s,a) 1.63 -//#define writememb(s,a,v) writememb386l(s,a,v) 1.64 - 1.65 -//#define is486 1 1.66 1.67 #define readmemb(s,a) ((readlookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF)?readmemb386l(s,a):ram[readlookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]) 1.68 1.69 @@ -71,37 +61,12 @@ 1.70 #define writememl(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC) writememll(s,a,v); else *((uint32_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v 1.71 1.72 1.73 -/*#undef readmemw 1.74 -#undef readmeml 1.75 - 1.76 -#define readmemb(s, a) readmemb386l(s, a) 1.77 -#define readmemw(s, a) readmemwl(s, a) 1.78 -#define readmeml(s, a) readmemll(s, a)*/ 1.79 - 1.80 -/*#define writememb(s,a,v) writememb386l(s, a, v) 1.81 -#define writememw(s,a,v) writememwl(s, a, v) 1.82 -#define writememl(s,a,v) writememll(s, a, v)*/ 1.83 -//#define readmemb(s,a) readmemb((s)+(a)) 1.84 -//#define writememb(s,a,v) writememb((s)+(a),v) 1.85 uint32_t mmucache[0x100000]; 1.86 1.87 uint8_t romext[32768]; 1.88 uint8_t *ram,*rom,*vram,*vrom; 1.89 uint16_t biosmask; 1.90 1.91 -/*uint16_t getwordx() 1.92 -{ 1.93 - pc+=2; 1.94 - return readmemw(cs,(pc-2)); 1.95 -}*/ 1.96 - 1.97 -#define getword() getwordx() 1.98 - 1.99 - 1.100 -//#define readmemb(s,a) readmemb386(s,a) 1.101 -//#define writememb(s,a,v) writememb386(s,a,v) 1.102 - 1.103 -//uint32_t fetchdat; 1.104 uint32_t rmdat32; 1.105 #define rmdat rmdat32 1.106 #define fetchdat rmdat32 1.107 @@ -114,6 +79,15 @@ 1.108 uint32_t oldecx; 1.109 uint32_t op32; 1.110 1.111 +static inline uint8_t fastreadb(uint32_t a) 1.112 +{ 1.113 + if ((a >> 12) == pccache) 1.114 + return *((uint8_t *)&pccache2[a]); 1.115 + pccache2 = getpccache(a); 1.116 + pccache = a >> 12; 1.117 + return *((uint8_t *)&pccache2[a]); 1.118 +} 1.119 + 1.120 static inline uint16_t fastreadw(uint32_t a) 1.121 { 1.122 uint32_t t; 1.123 @@ -152,6 +126,13 @@ 1.124 return val; 1.125 } 1.126 1.127 + 1.128 +static inline uint8_t getbyte() 1.129 +{ 1.130 + pc++; 1.131 + return fastreadb(cs + (pc - 1)); 1.132 +} 1.133 + 1.134 static inline uint16_t getword() 1.135 { 1.136 pc+=2; 1.137 @@ -191,219 +172,234 @@ 1.138 return readmeml(easeg,eaaddr); 1.139 } 1.140 1.141 -#define seteab(v) if (mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v); } else if (rm&4) regs[rm&3].b.h=v; else regs[rm].b.l=v 1.142 +static inline uint8_t geteab_mem() 1.143 +{ 1.144 + if (eal_r) return *(uint8_t *)eal_r; 1.145 + return readmemb(easeg,eaaddr); 1.146 +} 1.147 +static inline uint16_t geteaw_mem() 1.148 +{ 1.149 + if (eal_r) return *(uint16_t *)eal_r; 1.150 + return readmemw(easeg,eaaddr); 1.151 +} 1.152 +static inline uint32_t geteal_mem() 1.153 +{ 1.154 + if (eal_r) return *eal_r; 1.155 + return readmeml(easeg,eaaddr); 1.156 +} 1.157 + 1.158 +#define seteab(v) if (mod!=3) { /*if (eal_w) *(uint8_t *)eal_w=v; else */writememb386l(easeg,eaaddr,v); } else if (rm&4) regs[rm&3].b.h=v; else regs[rm].b.l=v 1.159 #define seteaw(v) if (mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v); } else regs[rm].w=v 1.160 #define seteal(v) if (mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v); } else regs[rm].l=v 1.161 1.162 -static inline void fetcheal32sib() 1.163 -{ 1.164 - uint8_t sib; 1.165 - sib=rmdat>>8;// pc++; 1.166 - switch (mod) 1.167 - { 1.168 - case 0: eaaddr=regs[sib&7].l; pc++; break; 1.169 - case 1: eaaddr=((uint32_t)(int8_t)(rmdat>>16))+regs[sib&7].l; pc+=2; break; 1.170 - case 2: eaaddr=(fastreadl(cs+pc+1))+regs[sib&7].l; pc+=5; break; 1.171 - } 1.172 - /*SIB byte present*/ 1.173 - if ((sib&7)==5 && !mod) eaaddr=getlong(); 1.174 - else if ((sib&6)==4) 1.175 - { 1.176 - easeg=ss; 1.177 - ea_rseg=SS; 1.178 - } 1.179 - if (((sib>>3)&7)!=4) eaaddr+=regs[(sib>>3)&7].l<<(sib>>6); 1.180 -} 1.181 - 1.182 -static inline void fetcheal32nosib() 1.183 -{ 1.184 - if (rm==5) 1.185 - { 1.186 - easeg=ss; 1.187 - ea_rseg=SS; 1.188 - } 1.189 - if (mod==1) { eaaddr+=((uint32_t)(int8_t)(rmdat>>8)); pc++; } 1.190 - else { eaaddr+=getlong(); } 1.191 -} 1.192 +#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v); 1.193 +#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v); 1.194 +#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v); 1.195 1.196 uint16_t *mod1add[2][8]; 1.197 uint32_t *mod1seg[8]; 1.198 1.199 -void fetchea32() 1.200 +static inline void fetch_ea_32_long(uint32_t rmdat) 1.201 { 1.202 eal_r = eal_w = NULL; 1.203 - if (op32&0x200) 1.204 + easeg = ds; 1.205 + ea_rseg = DS; 1.206 + if (rm == 4) 1.207 { 1.208 - /*rmdat=readmemw(cs,pc); */pc++; 1.209 - reg=(rmdat>>3)&7; 1.210 - mod=(rmdat>>6)&3; 1.211 - rm=rmdat&7; 1.212 + uint8_t sib = rmdat >> 8; 1.213 1.214 - if (mod!=3) 1.215 + switch (mod) 1.216 { 1.217 - easeg=ds; 1.218 - ea_rseg=DS; 1.219 - if (rm==4) fetcheal32sib(); 1.220 - else 1.221 - { 1.222 - eaaddr=regs[rm].l; 1.223 - if (mod) fetcheal32nosib(); 1.224 - else if (rm==5) eaaddr=getlong(); 1.225 - } 1.226 - if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC) 1.227 - { 1.228 - if ( readlookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF) 1.229 - eal_r = (uint32_t *)&ram[ readlookup2[(easeg + eaaddr) >> 12] + ((easeg + eaaddr) & 0xFFF)]; 1.230 - if (writelookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF) 1.231 - eal_w = (uint32_t *)&ram[writelookup2[(easeg + eaaddr) >> 12] + ((easeg + eaaddr) & 0xFFF)]; 1.232 - } 1.233 + case 0: 1.234 + eaaddr = regs[sib & 7].l; 1.235 + pc++; 1.236 + break; 1.237 + case 1: 1.238 + pc++; 1.239 + eaaddr = ((uint32_t)(int8_t)getbyte()) + regs[sib & 7].l; 1.240 +// pc++; 1.241 + break; 1.242 + case 2: 1.243 + eaaddr = (fastreadl(cs + pc + 1)) + regs[sib & 7].l; 1.244 + pc += 5; 1.245 + break; 1.246 } 1.247 + /*SIB byte present*/ 1.248 + if ((sib & 7) == 5 && !mod) 1.249 + eaaddr = getlong(); 1.250 + else if ((sib & 6) == 4) 1.251 + { 1.252 + easeg = ss; 1.253 + ea_rseg = SS; 1.254 + } 1.255 + if (((sib >> 3) & 7) != 4) 1.256 + eaaddr += regs[(sib >> 3) & 7].l << (sib >> 6); 1.257 } 1.258 else 1.259 { 1.260 - /*rmdat=readmemb(cs,pc); */pc++; 1.261 - reg=(rmdat>>3)&7; 1.262 - mod=(rmdat>>6)&3; 1.263 - rm=rmdat&7; 1.264 - if (mod!=3) 1.265 + eaaddr = regs[rm].l; 1.266 + if (mod) 1.267 { 1.268 - if (!mod && rm==6) { eaaddr=(rmdat>>8)&0xFFFF; pc+=2; easeg=ds; ea_rseg=DS; } 1.269 - else 1.270 + if (rm == 5) 1.271 { 1.272 - switch (mod) 1.273 - { 1.274 - case 0: 1.275 - eaaddr=0; 1.276 - break; 1.277 - case 1: 1.278 - eaaddr=(uint16_t)(int8_t)(rmdat>>8); pc++; 1.279 - break; 1.280 - case 2: 1.281 - eaaddr=getword(); 1.282 - break; 1.283 - } 1.284 - eaaddr+=(*mod1add[0][rm])+(*mod1add[1][rm]); 1.285 - easeg=*mod1seg[rm]; 1.286 - if (mod1seg[rm]==&ss) ea_rseg=SS; 1.287 - else ea_rseg=DS; 1.288 - eaaddr&=0xFFFF; 1.289 + easeg = ss; 1.290 + ea_rseg = SS; 1.291 } 1.292 - if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC) 1.293 + if (mod == 1) 1.294 + { 1.295 + eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); 1.296 + pc++; 1.297 + } 1.298 + else 1.299 { 1.300 - if ( readlookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF) 1.301 - eal_r = (uint32_t *)&ram[ readlookup2[(easeg + eaaddr) >> 12] + ((easeg + eaaddr) & 0xFFF)]; 1.302 - if (writelookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF) 1.303 - eal_w = (uint32_t *)&ram[writelookup2[(easeg + eaaddr) >> 12] + ((easeg + eaaddr) & 0xFFF)]; 1.304 + eaaddr += getlong(); 1.305 } 1.306 -/* if (readlookup2[(easeg+eaaddr)>>12]!=0xFFFFFFFF && easeg!=0xFFFFFFFF && ((easeg+eaaddr)&0xFFF)<=0xFFC) 1.307 - eal=(uint32_t *)&ram[readlookup2[(easeg+eaaddr)>>12]+((easeg+eaaddr)&0xFFF)];*/ 1.308 } 1.309 + else if (rm == 5) 1.310 + { 1.311 + eaaddr = getlong(); 1.312 + } 1.313 + } 1.314 + if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC) 1.315 + { 1.316 + if ( readlookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF) 1.317 + eal_r = (uint32_t *)&ram[ readlookup2[(easeg + eaaddr) >> 12] + ((easeg + eaaddr) & 0xFFF)]; 1.318 + if (writelookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF) 1.319 + eal_w = (uint32_t *)&ram[writelookup2[(easeg + eaaddr) >> 12] + ((easeg + eaaddr) & 0xFFF)]; 1.320 } 1.321 } 1.322 1.323 -#undef fetchea 1.324 -#define fetchea() fetchea32(); if (abrt) break 1.325 -#define fetchea2() rmdat=fastreadl(cs+pc); fetchea32(); if (abrt) break 1.326 +static inline void fetch_ea_16_long(uint32_t rmdat) 1.327 +{ 1.328 + eal_r = eal_w = NULL; 1.329 + if (!mod && rm == 6) 1.330 + { 1.331 + eaaddr = getword(); 1.332 + easeg = ds; 1.333 + ea_rseg = DS; 1.334 + } 1.335 + else 1.336 + { 1.337 + switch (mod) 1.338 + { 1.339 + case 0: 1.340 + eaaddr = 0; 1.341 + break; 1.342 + case 1: 1.343 + eaaddr = (uint16_t)(int8_t)(rmdat >> 8); pc++; 1.344 + break; 1.345 + case 2: 1.346 + eaaddr = getword(); 1.347 + break; 1.348 + } 1.349 + eaaddr += (*mod1add[0][rm]) + (*mod1add[1][rm]); 1.350 + easeg = *mod1seg[rm]; 1.351 + if (mod1seg[rm] == &ss) ea_rseg = SS; 1.352 + else ea_rseg = DS; 1.353 + eaaddr &= 0xFFFF; 1.354 + } 1.355 + if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC) 1.356 + { 1.357 + if ( readlookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF) 1.358 + eal_r = (uint32_t *)&ram[ readlookup2[(easeg + eaaddr) >> 12] + ((easeg + eaaddr) & 0xFFF)]; 1.359 + if (writelookup2[(easeg + eaaddr) >> 12] != 0xFFFFFFFF) 1.360 + eal_w = (uint32_t *)&ram[writelookup2[(easeg + eaaddr) >> 12] + ((easeg + eaaddr) & 0xFFF)]; 1.361 + } 1.362 +} 1.363 + 1.364 +#define fetch_ea_16(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_16_long(rmdat); if (abrt) return 0; } 1.365 +#define fetch_ea_32(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_32_long(rmdat); } if (abrt) return 0 1.366 1.367 #include "x86_flags.h" 1.368 1.369 -void setadd32(uint32_t a, uint32_t b) 1.370 -{ 1.371 - uint32_t c=(uint32_t)a+(uint32_t)b; 1.372 - flags&=~0x8D5; 1.373 - flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); 1.374 - flags|=(znptable8[c&0xFF]&P_FLAG); 1.375 - if (c<a) flags|=C_FLAG; 1.376 - if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) flags|=V_FLAG; 1.377 - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 1.378 -} 1.379 -void setadd32nc(uint32_t a, uint32_t b) 1.380 -{ 1.381 - uint32_t c=(uint32_t)a+(uint32_t)b; 1.382 - flags&=~0x8D4; 1.383 - flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); 1.384 - flags|=(znptable8[c&0xFF]&P_FLAG); 1.385 - if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) flags|=V_FLAG; 1.386 - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 1.387 -} 1.388 -void setadc32(uint32_t a, uint32_t b) 1.389 -{ 1.390 - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; 1.391 - flags&=~0x8D5; 1.392 - flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); 1.393 - flags|=(znptable8[c&0xFF]&P_FLAG); 1.394 - if ((c<a) || (c==a && tempc)) flags|=C_FLAG; 1.395 - if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) flags|=V_FLAG; 1.396 - if (((a&0xF)+(b&0xF)+tempc)&0x10) flags|=A_FLAG; 1.397 -} 1.398 -void setsub32(uint32_t a, uint32_t b) 1.399 -{ 1.400 - uint32_t c=(uint32_t)a-(uint32_t)b; 1.401 - flags&=~0x8D5; 1.402 - flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); 1.403 - flags|=(znptable8[c&0xFF]&P_FLAG); 1.404 - if (c>a) flags|=C_FLAG; 1.405 - if ((a^b)&(a^c)&0x80000000) flags|=V_FLAG; 1.406 - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 1.407 -} 1.408 -void setsub32nc(uint32_t a, uint32_t b) 1.409 -{ 1.410 - uint32_t c=(uint32_t)a-(uint32_t)b; 1.411 - flags&=~0x8D4; 1.412 - flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); 1.413 - flags|=(znptable8[c&0xFF]&P_FLAG); 1.414 - if ((a^b)&(a^c)&0x80000000) flags|=V_FLAG; 1.415 - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 1.416 -} 1.417 -void setsbc32(uint32_t a, uint32_t b) 1.418 -{ 1.419 - uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); 1.420 - flags&=~0x8D5; 1.421 - flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); 1.422 - flags|=(znptable8[c&0xFF]&P_FLAG); 1.423 - if ((c>a) || (c==a && tempc)) flags|=C_FLAG; 1.424 - if ((a^b)&(a^c)&0x80000000) flags|=V_FLAG; 1.425 - if (((a&0xF)-((b&0xF)+tempc))&0x10) flags|=A_FLAG; 1.426 -} 1.427 - 1.428 - 1.429 - 1.430 void x86_int(int num) 1.431 { 1.432 uint32_t addr; 1.433 - pc=oldpc; 1.434 - if (msw&1) 1.435 - { 1.436 - pmodeint(num,0); 1.437 - } 1.438 - else 1.439 - { 1.440 - if (ssegs) ss=oldss; 1.441 - if (stack32) 1.442 - { 1.443 - writememw(ss,ESP-2,flags); 1.444 - writememw(ss,ESP-4,CS); 1.445 - writememw(ss,ESP-6,pc); 1.446 - ESP-=6; 1.447 - } 1.448 - else 1.449 - { 1.450 - writememw(ss,((SP-2)&0xFFFF),flags); 1.451 - writememw(ss,((SP-4)&0xFFFF),CS); 1.452 - writememw(ss,((SP-6)&0xFFFF),pc); 1.453 - SP-=6; 1.454 - } 1.455 - addr=num<<2; 1.456 +// pclog("x86_int\n"); 1.457 + flags_rebuild(); 1.458 + pc=oldpc; 1.459 + if (msw&1) 1.460 + { 1.461 + pmodeint(num,0); 1.462 + } 1.463 + else 1.464 + { 1.465 + if (ssegs) ss=oldss; 1.466 + if (stack32) 1.467 + { 1.468 + writememw(ss,ESP-2,flags); 1.469 + writememw(ss,ESP-4,CS); 1.470 + writememw(ss,ESP-6,pc); 1.471 + ESP-=6; 1.472 + } 1.473 + else 1.474 + { 1.475 + writememw(ss,((SP-2)&0xFFFF),flags); 1.476 + writememw(ss,((SP-4)&0xFFFF),CS); 1.477 + writememw(ss,((SP-6)&0xFFFF),pc); 1.478 + SP-=6; 1.479 + } 1.480 + addr=num<<2; 1.481 1.482 - flags&=~I_FLAG; 1.483 - flags&=~T_FLAG; 1.484 - oxpc=pc; 1.485 - pc=readmemw(0,addr); 1.486 - loadcs(readmemw(0,addr+2)); 1.487 - } 1.488 - cycles-=70; 1.489 + flags&=~I_FLAG; 1.490 + flags&=~T_FLAG; 1.491 + oxpc=pc; 1.492 + pc=readmemw(0,addr); 1.493 + loadcs(readmemw(0,addr+2)); 1.494 + } 1.495 + cycles-=70; 1.496 } 1.497 1.498 +void x86_int_sw(int num) 1.499 +{ 1.500 + uint32_t addr; 1.501 +// pclog("x86_int\n"); 1.502 + flags_rebuild(); 1.503 + if (msw&1) 1.504 + { 1.505 + pmodeint(num,1); 1.506 + } 1.507 + else 1.508 + { 1.509 + if (ssegs) ss=oldss; 1.510 + if (stack32) 1.511 + { 1.512 + writememw(ss,ESP-2,flags); 1.513 + writememw(ss,ESP-4,CS); 1.514 + writememw(ss,ESP-6,pc); 1.515 + ESP-=6; 1.516 + } 1.517 + else 1.518 + { 1.519 + writememw(ss,((SP-2)&0xFFFF),flags); 1.520 + writememw(ss,((SP-4)&0xFFFF),CS); 1.521 + writememw(ss,((SP-6)&0xFFFF),pc); 1.522 + SP-=6; 1.523 + } 1.524 + addr=num<<2; 1.525 + 1.526 + flags&=~I_FLAG; 1.527 + flags&=~T_FLAG; 1.528 + oxpc=pc; 1.529 + pc=readmemw(0,addr); 1.530 + loadcs(readmemw(0,addr+2)); 1.531 + } 1.532 + cycles-=70; 1.533 +} 1.534 + 1.535 +void x86illegal() 1.536 +{ 1.537 + uint16_t addr; 1.538 + pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode); 1.539 +// if (output) 1.540 +// { 1.541 +// dumpregs(); 1.542 +// exit(-1); 1.543 +// } 1.544 + x86_int(6); 1.545 +} 1.546 + 1.547 + 1.548 #define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\ 1.549 { \ 1.550 x86_int(6); \ 1.551 @@ -415,7 +411,7 @@ 1.552 uint8_t temp; 1.553 uint32_t c;//=CX; 1.554 uint8_t temp2; 1.555 - uint16_t tempw,tempw2,tempw3,of=flags; 1.556 + uint16_t tempw,tempw2,of; 1.557 uint32_t ipc=oldpc;//pc-1; 1.558 int changeds=0; 1.559 uint32_t oldds; 1.560 @@ -423,6 +419,9 @@ 1.561 uint32_t templ,templ2; 1.562 int tempz; 1.563 int tempi; 1.564 + 1.565 + flags_rebuild(); 1.566 + of = flags; 1.567 // if (output) pclog("REP32 %04X %04X ",use32,rep32); 1.568 startrep: 1.569 temp=opcode2=readmemb(cs,pc); pc++; 1.570 @@ -743,9 +742,8 @@ 1.571 else firstrepcycle=1; 1.572 break; 1.573 case 0xA6: case 0x1A6: /*REP CMPSB*/ 1.574 - if (fv) flags|=Z_FLAG; 1.575 - else flags&=~Z_FLAG; 1.576 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.577 + tempz = (fv) ? 1 : 0; 1.578 + if ((c>0) && (fv==tempz)) 1.579 { 1.580 temp=readmemb(ds,SI); 1.581 temp2=readmemb(es,DI); 1.582 @@ -755,14 +753,14 @@ 1.583 c--; 1.584 cycles-=(is486)?7:9; 1.585 setsub8(temp,temp2); 1.586 + tempz = (ZF_SET()) ? 1 : 0; 1.587 } 1.588 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.589 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.590 else firstrepcycle=1; 1.591 break; 1.592 case 0x2A6: case 0x3A6: /*REP CMPSB*/ 1.593 - if (fv) flags|=Z_FLAG; 1.594 - else flags&=~Z_FLAG; 1.595 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.596 + tempz = (fv) ? 1 : 0; 1.597 + if ((c>0) && (fv==tempz)) 1.598 { 1.599 temp=readmemb(ds,ESI); 1.600 temp2=readmemb(es,EDI); 1.601 @@ -772,14 +770,14 @@ 1.602 c--; 1.603 cycles-=(is486)?7:9; 1.604 setsub8(temp,temp2); 1.605 + tempz = (ZF_SET()) ? 1 : 0; 1.606 } 1.607 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.608 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.609 else firstrepcycle=1; 1.610 break; 1.611 case 0xA7: /*REP CMPSW*/ 1.612 - if (fv) flags|=Z_FLAG; 1.613 - else flags&=~Z_FLAG; 1.614 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.615 + tempz = (fv) ? 1 : 0; 1.616 + if ((c>0) && (fv==tempz)) 1.617 { 1.618 // pclog("CMPSW %05X %05X %08X %08X ", ds+SI, es+DI, readlookup2[(ds+SI)>>12], readlookup2[(es+DI)>>12]); 1.619 tempw=readmemw(ds,SI); 1.620 @@ -792,14 +790,14 @@ 1.621 c--; 1.622 cycles-=(is486)?7:9; 1.623 setsub16(tempw,tempw2); 1.624 + tempz = (ZF_SET()) ? 1 : 0; 1.625 } 1.626 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.627 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.628 else firstrepcycle=1; 1.629 break; 1.630 case 0x1A7: /*REP CMPSL*/ 1.631 - if (fv) flags|=Z_FLAG; 1.632 - else flags&=~Z_FLAG; 1.633 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.634 + tempz = (fv) ? 1 : 0; 1.635 + if ((c>0) && (fv==tempz)) 1.636 { 1.637 templ=readmeml(ds,SI); 1.638 templ2=readmeml(es,DI); 1.639 @@ -809,14 +807,14 @@ 1.640 c--; 1.641 cycles-=(is486)?7:9; 1.642 setsub32(templ,templ2); 1.643 + tempz = (ZF_SET()) ? 1 : 0; 1.644 } 1.645 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.646 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.647 else firstrepcycle=1; 1.648 break; 1.649 case 0x2A7: /*REP CMPSW*/ 1.650 - if (fv) flags|=Z_FLAG; 1.651 - else flags&=~Z_FLAG; 1.652 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.653 + tempz = (fv) ? 1 : 0; 1.654 + if ((c>0) && (fv==tempz)) 1.655 { 1.656 tempw=readmemw(ds,ESI); 1.657 tempw2=readmemw(es,EDI); 1.658 @@ -826,14 +824,14 @@ 1.659 c--; 1.660 cycles-=(is486)?7:9; 1.661 setsub16(tempw,tempw2); 1.662 + tempz = (ZF_SET()) ? 1 : 0; 1.663 } 1.664 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.665 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.666 else firstrepcycle=1; 1.667 break; 1.668 case 0x3A7: /*REP CMPSL*/ 1.669 - if (fv) flags|=Z_FLAG; 1.670 - else flags&=~Z_FLAG; 1.671 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.672 + tempz = (fv) ? 1 : 0; 1.673 + if ((c>0) && (fv==tempz)) 1.674 { 1.675 templ=readmeml(ds,ESI); 1.676 templ2=readmeml(es,EDI); 1.677 @@ -843,8 +841,9 @@ 1.678 c--; 1.679 cycles-=(is486)?7:9; 1.680 setsub32(templ,templ2); 1.681 + tempz = (ZF_SET()) ? 1 : 0; 1.682 } 1.683 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.684 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.685 else firstrepcycle=1; 1.686 break; 1.687 1.688 @@ -1013,107 +1012,106 @@ 1.689 case 0xAE: case 0x1AE: /*REP SCASB*/ 1.690 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc); 1.691 // tempz=(fv)?1:0; 1.692 - if (fv) flags|=Z_FLAG; 1.693 - else flags&=~Z_FLAG; 1.694 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.695 + tempz = (fv) ? 1 : 0; 1.696 + if ((c>0) && (fv==tempz)) 1.697 { 1.698 temp2=readmemb(es,DI); 1.699 if (abrt) { flags=of; break; } 1.700 setsub8(AL,temp2); 1.701 + tempz = (ZF_SET()) ? 1 : 0; 1.702 if (flags&D_FLAG) DI--; 1.703 else DI++; 1.704 c--; 1.705 cycles-=(is486)?5:8; 1.706 } 1.707 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.708 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.709 else firstrepcycle=1; 1.710 break; 1.711 case 0x2AE: case 0x3AE: /*REP SCASB*/ 1.712 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc); 1.713 // tempz=(fv)?1:0; 1.714 - if (fv) flags|=Z_FLAG; 1.715 - else flags&=~Z_FLAG; 1.716 -// if (output) pclog("REP SCASB - %i %04X %i\n",fv,flags&Z_FLAG,c); 1.717 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.718 + tempz = (fv) ? 1 : 0; 1.719 + if ((c>0) && (fv==tempz)) 1.720 { 1.721 temp2=readmemb(es,EDI); 1.722 if (abrt) { flags=of; break; } 1.723 // if (output) pclog("Compare %02X,%02X\n",temp2,AL); 1.724 setsub8(AL,temp2); 1.725 + tempz = (ZF_SET()) ? 1 : 0; 1.726 if (flags&D_FLAG) EDI--; 1.727 else EDI++; 1.728 c--; 1.729 cycles-=(is486)?5:8; 1.730 } 1.731 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.732 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.733 else firstrepcycle=1; 1.734 break; 1.735 case 0xAF: /*REP SCASW*/ 1.736 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc); 1.737 - if (fv) flags|=Z_FLAG; 1.738 - else flags&=~Z_FLAG; 1.739 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.740 + tempz = (fv) ? 1 : 0; 1.741 + if ((c>0) && (fv==tempz)) 1.742 { 1.743 tempw=readmemw(es,DI); 1.744 if (abrt) { flags=of; break; } 1.745 setsub16(AX,tempw); 1.746 + tempz = (ZF_SET()) ? 1 : 0; 1.747 if (flags&D_FLAG) DI-=2; 1.748 else DI+=2; 1.749 c--; 1.750 cycles-=(is486)?5:8; 1.751 } 1.752 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.753 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.754 else firstrepcycle=1; 1.755 break; 1.756 case 0x1AF: /*REP SCASL*/ 1.757 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc); 1.758 - if (fv) flags|=Z_FLAG; 1.759 - else flags&=~Z_FLAG; 1.760 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.761 + tempz = (fv) ? 1 : 0; 1.762 + if ((c>0) && (fv==tempz)) 1.763 { 1.764 templ=readmeml(es,DI); 1.765 if (abrt) { flags=of; break; } 1.766 setsub32(EAX,templ); 1.767 + tempz = (ZF_SET()) ? 1 : 0; 1.768 if (flags&D_FLAG) DI-=4; 1.769 else DI+=4; 1.770 c--; 1.771 cycles-=(is486)?5:8; 1.772 } 1.773 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.774 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.775 else firstrepcycle=1; 1.776 break; 1.777 case 0x2AF: /*REP SCASW*/ 1.778 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc); 1.779 - if (fv) flags|=Z_FLAG; 1.780 - else flags&=~Z_FLAG; 1.781 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.782 + tempz = (fv) ? 1 : 0; 1.783 + if ((c>0) && (fv==tempz)) 1.784 { 1.785 tempw=readmemw(es,EDI); 1.786 if (abrt) { flags=of; break; } 1.787 setsub16(AX,tempw); 1.788 + tempz = (ZF_SET()) ? 1 : 0; 1.789 if (flags&D_FLAG) EDI-=2; 1.790 else EDI+=2; 1.791 c--; 1.792 cycles-=(is486)?5:8; 1.793 } 1.794 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.795 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.796 else firstrepcycle=1; 1.797 break; 1.798 case 0x3AF: /*REP SCASL*/ 1.799 // if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc); 1.800 - if (fv) flags|=Z_FLAG; 1.801 - else flags&=~Z_FLAG; 1.802 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) 1.803 + tempz = (fv) ? 1 : 0; 1.804 + if ((c>0) && (fv==tempz)) 1.805 { 1.806 templ=readmeml(es,EDI); 1.807 if (abrt) { flags=of; break; } 1.808 setsub32(EAX,templ); 1.809 + tempz = (ZF_SET()) ? 1 : 0; 1.810 if (flags&D_FLAG) EDI-=4; 1.811 else EDI+=4; 1.812 c--; 1.813 cycles-=(is486)?5:8; 1.814 } 1.815 - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.816 + if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; } 1.817 else firstrepcycle=1; 1.818 break; 1.819 1.820 @@ -1121,8 +1119,8 @@ 1.821 default: 1.822 pc=ipc; 1.823 cycles-=20; 1.824 + fatal("Bad REP %02X %i\n",temp,rep32>>8); 1.825 x86illegal(); 1.826 - pclog("Bad REP %02X %i\n",temp,rep32>>8); 1.827 } 1.828 if (rep32&0x200) ECX=c; 1.829 else CX=c; 1.830 @@ -1142,7 +1140,8 @@ 1.831 // pclog("CheckIO %04X %01X %01X %02X %04X %04X %08X ",CS,CPL,IOPL,port,t,t+(port>>3),tr.base+t+(port>>3)); 1.832 if ((t+(port>>3))>tr.limit) return 1; 1.833 cpl_override = 1; 1.834 - d=readmemb(tr.base,t+(port>>3)); 1.835 + d = readmemb386l(0, tr.base + t + (port >> 3)); 1.836 +// d=readmemb(tr.base,t+(port>>3)); 1.837 cpl_override = 0; 1.838 // pclog("%02X %02X\n",d,d&(1<<(port&7))); 1.839 return d&(1<<(port&7)); 1.840 @@ -1157,68 +1156,90 @@ 1.841 1.842 #define divexcp() { \ 1.843 pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,pc); \ 1.844 - pc=oldpc; \ 1.845 - if (msw&1) pmodeint(0,0); \ 1.846 - else \ 1.847 - { \ 1.848 - writememw(ss,(SP-2)&0xFFFF,flags); \ 1.849 - writememw(ss,(SP-4)&0xFFFF,CS); \ 1.850 - writememw(ss,(SP-6)&0xFFFF,pc); \ 1.851 - SP-=6; \ 1.852 - flags&=~I_FLAG; \ 1.853 - oxpc=pc; \ 1.854 - pc=readmemw(0,0); \ 1.855 - loadcs(readmemw(0,2)); \ 1.856 - } \ 1.857 - return; \ 1.858 + x86_int(0); \ 1.859 } 1.860 1.861 void divl(uint32_t val) 1.862 { 1.863 - if (val==0) divexcp(); 1.864 + if (val==0) 1.865 + { 1.866 + divexcp(); 1.867 + return; 1.868 + } 1.869 uint64_t num=(((uint64_t)EDX)<<32)|EAX; 1.870 uint64_t quo=num/val; 1.871 uint32_t rem=num%val; 1.872 uint32_t quo32=(uint32_t)(quo&0xFFFFFFFF); 1.873 - if (quo!=(uint64_t)quo32) divexcp(); 1.874 + if (quo!=(uint64_t)quo32) 1.875 + { 1.876 + divexcp(); 1.877 + return; 1.878 + } 1.879 EDX=rem; 1.880 EAX=quo32; 1.881 } 1.882 void idivl(int32_t val) 1.883 { 1.884 - if (val==0) divexcp(); 1.885 + if (val==0) 1.886 + { 1.887 + divexcp(); 1.888 + return; 1.889 + } 1.890 int64_t num=(((uint64_t)EDX)<<32)|EAX; 1.891 int64_t quo=num/val; 1.892 int32_t rem=num%val; 1.893 int32_t quo32=(int32_t)(quo&0xFFFFFFFF); 1.894 - if (quo!=(int64_t)quo32) divexcp(); 1.895 + if (quo!=(int64_t)quo32) 1.896 + { 1.897 + divexcp(); 1.898 + return; 1.899 + } 1.900 EDX=rem; 1.901 EAX=quo32; 1.902 } 1.903 1.904 + 1.905 +void cpu_386_flags_extract() 1.906 +{ 1.907 + flags_extract(); 1.908 +} 1.909 +void cpu_386_flags_rebuild() 1.910 +{ 1.911 + flags_rebuild(); 1.912 +} 1.913 + 1.914 int oldi; 1.915 1.916 +static uint64_t tsc = 0; 1.917 + 1.918 uint32_t testr[9]; 1.919 int dontprint=0; 1.920 + 1.921 +#undef NOTRM 1.922 +#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\ 1.923 + { \ 1.924 + x86_int(6); \ 1.925 + return 0; \ 1.926 + } 1.927 + 1.928 +#include "386_ops.h" 1.929 + 1.930 +#undef NOTRM 1.931 +#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\ 1.932 + { \ 1.933 + x86_int(6); \ 1.934 + break; \ 1.935 + } 1.936 + 1.937 void exec386(int cycs) 1.938 { 1.939 - uint64_t temp64; 1.940 - int64_t temp64i; 1.941 - uint8_t temp,temp2; 1.942 - uint16_t tempw,tempw2,tempw3,tempw4; 1.943 - int8_t offset; 1.944 - int8_t temps; 1.945 - int16_t temps16; 1.946 - volatile int tempws,tempws2; 1.947 - uint32_t templ,templ2,templ3,addr; 1.948 - int c,cycdiff; 1.949 + uint8_t temp; 1.950 + uint32_t addr; 1.951 + int tempi; 1.952 + int cycdiff; 1.953 int oldcyc; 1.954 - int tempi; 1.955 - int cyctot=0; 1.956 - int trap; 1.957 + int trap = flags & T_FLAG; 1.958 1.959 - FILE *f; 1.960 - 1.961 cycles+=cycs; 1.962 // output=3; 1.963 while (cycles>0) 1.964 @@ -1228,11 +1249,12 @@ 1.965 // pclog("%i %02X\n", ins, ram[8]); 1.966 while (cycdiff<100) 1.967 { 1.968 -/* testr[0]=EAX; testr[1]=EBX; testr[2]=ECX; testr[3]=EDX; 1.969 - testr[4]=ESI; testr[5]=EDI; testr[6]=EBP; testr[7]=ESP; 1.970 - testr[8]=flags;*/ 1.971 + /* testr[0]=EAX; testr[1]=EBX; testr[2]=ECX; testr[3]=EDX; 1.972 + testr[4]=ESI; testr[5]=EDI; testr[6]=EBP; testr[7]=ESP;*/ 1.973 +/* testr[8]=flags;*/ 1.974 // oldcs2=oldcs; 1.975 // oldpc2=oldpc; 1.976 +opcode_realstart: 1.977 oldcs=CS; 1.978 oldpc=pc; 1.979 oldcpl=CPL; 1.980 @@ -1240,6921 +1262,32 @@ 1.981 1.982 dontprint=0; 1.983 1.984 - opcodestart: 1.985 - fetchdat=fastreadl(cs+pc); 1.986 - if (abrt) goto opcodeend; 1.987 - 1.988 - tempc=flags&C_FLAG; 1.989 - trap=flags&T_FLAG; 1.990 - opcode=fetchdat&0xFF; 1.991 - fetchdat>>=8; 1.992 +opcodestart: 1.993 + fetchdat = fastreadl(cs + pc); 1.994 + if (!abrt) 1.995 + { 1.996 + tempc = CF_SET(); 1.997 + trap = flags & T_FLAG; 1.998 + opcode = fetchdat & 0xFF; 1.999 + fetchdat >>= 8; 1.1000 1.1001 - if (output==3 && !dontprint) 1.1002 + if (output == 3) 1.1003 + { 1.1004 + pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X %02X%02X %02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0xB270+0x3F5], ram[0xB270+0x3F4], ram[0xB270+0x3F7], ram[0xB270+0x3F6], ram[0xB270+0x3F9], ram[0xB270+0x3F8], ram[0x4430+0x0D49]); 1.1005 + } 1.1006 + pc++; 1.1007 + if (x86_opcodes[(opcode | op32) & 0x3ff](fetchdat)) 1.1008 + goto opcodestart; 1.1009 + } 1.1010 + 1.1011 + if (!use32) pc &= 0xffff; 1.1012 +/* if (ins == 74400000) 1.1013 { 1.1014 - if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle) 1.1015 - { 1.1016 - if (!skipnextprint) 1.1017 - { 1.1018 - pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,writelookup2, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, readmode); 1.1019 - //x87_print(); 1.1020 - } 1.1021 - skipnextprint=0; 1.1022 - } 1.1023 - } 1.1024 - dontprint=1; 1.1025 -//#endif 1.1026 - pc++; 1.1027 - inhlt=0; 1.1028 - switch ((opcode|op32)&0x3FF) 1.1029 - { 1.1030 - case 0x00: case 0x100: case 0x200: case 0x300: /*ADD 8,reg*/ 1.1031 - fetchea(); 1.1032 - //if (!rmdat && output) pc--; 1.1033 -/* if (!rmdat && output) 1.1034 - { 1.1035 - fatal("Crashed\n"); 1.1036 -// clear_keybuf(); 1.1037 -// readkey(); 1.1038 - 1.1039 - 1.1040 - }*/ 1.1041 - if (mod == 3) 1.1042 - { 1.1043 - temp = getr8(rm); 1.1044 - temp2 = getr8(reg); 1.1045 - setadd8(temp, temp2); 1.1046 - setr8(rm, temp + temp2); 1.1047 - cycles -= timing_rr; 1.1048 - } 1.1049 - else 1.1050 - { 1.1051 - temp = geteab(); if (abrt) break; 1.1052 - temp2 = getr8(reg); 1.1053 - seteab(temp + temp2); if (abrt) break; 1.1054 - setadd8(temp, temp2); 1.1055 - cycles -= timing_mr; 1.1056 - } 1.1057 - break; 1.1058 - case 0x01: case 0x201: /*ADD 16,reg*/ 1.1059 - fetchea(); 1.1060 - if (mod == 3) 1.1061 - { 1.1062 - setadd16(regs[rm].w, regs[reg].w); 1.1063 - regs[rm].w += regs[reg].w; 1.1064 - cycles -= timing_rr; 1.1065 - } 1.1066 - else 1.1067 - { 1.1068 - tempw = geteaw(); if (abrt) break; 1.1069 - seteaw(tempw + regs[reg].w); if (abrt) break; 1.1070 - setadd16(tempw, regs[reg].w); 1.1071 - cycles -= timing_mr; 1.1072 - } 1.1073 - break; 1.1074 - case 0x101: case 0x301: /*ADD 32,reg*/ 1.1075 - fetchea(); 1.1076 - if (mod == 3) 1.1077 - { 1.1078 - setadd32(regs[rm].l, regs[reg].l); 1.1079 - regs[rm].l += regs[reg].l; 1.1080 - cycles -= timing_rr; 1.1081 - } 1.1082 - else 1.1083 - { 1.1084 - templ = geteal(); if (abrt) break; 1.1085 - seteal(templ + regs[reg].l); if (abrt) break; 1.1086 - setadd32(templ, regs[reg].l); 1.1087 - cycles -= timing_mrl; 1.1088 - } 1.1089 - break; 1.1090 - case 0x02: case 0x102: case 0x202: case 0x302: /*ADD reg,8*/ 1.1091 - fetchea(); 1.1092 - temp=geteab(); if (abrt) break; 1.1093 - setadd8(getr8(reg),temp); 1.1094 - setr8(reg,getr8(reg)+temp); 1.1095 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.1096 - break; 1.1097 - case 0x03: case 0x203: /*ADD reg,16*/ 1.1098 - fetchea(); 1.1099 - tempw=geteaw(); if (abrt) break; 1.1100 - setadd16(regs[reg].w,tempw); 1.1101 - regs[reg].w+=tempw; 1.1102 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.1103 - break; 1.1104 - case 0x103: case 0x303: /*ADD reg,32*/ 1.1105 - fetchea(); 1.1106 - templ=geteal(); if (abrt) break; 1.1107 - setadd32(regs[reg].l,templ); 1.1108 - regs[reg].l+=templ; 1.1109 - cycles -= (mod == 3) ? timing_rr : timing_rml; 1.1110 - break; 1.1111 - case 0x04: case 0x104: case 0x204: case 0x304: /*ADD AL,#8*/ 1.1112 - temp=getbytef(); 1.1113 - setadd8(AL,temp); 1.1114 - AL+=temp; 1.1115 - cycles -= timing_rr; 1.1116 - break; 1.1117 - case 0x05: case 0x205: /*ADD AX,#16*/ 1.1118 - tempw=getwordf(); 1.1119 - setadd16(AX,tempw); 1.1120 - AX+=tempw; 1.1121 - cycles -= timing_rr; 1.1122 - break; 1.1123 - case 0x105: case 0x305: /*ADD EAX,#32*/ 1.1124 - templ=getlong(); if (abrt) break; 1.1125 - setadd32(EAX,templ); 1.1126 - EAX+=templ; 1.1127 - cycles -= timing_rr; 1.1128 - break; 1.1129 - 1.1130 - case 0x06: case 0x206: /*PUSH ES*/ 1.1131 - if (ssegs) ss=oldss; 1.1132 - if (stack32) 1.1133 - { 1.1134 - writememw(ss,ESP-2,ES); if (abrt) break; 1.1135 - ESP-=2; 1.1136 - } 1.1137 - else 1.1138 - { 1.1139 - writememw(ss,((SP-2)&0xFFFF),ES); if (abrt) break; 1.1140 - SP-=2; 1.1141 - } 1.1142 - cycles-=2; 1.1143 - break; 1.1144 - case 0x106: case 0x306: /*PUSH ES*/ 1.1145 - if (ssegs) ss=oldss; 1.1146 - if (stack32) 1.1147 - { 1.1148 - writememl(ss,ESP-4,ES); if (abrt) break; 1.1149 - ESP-=4; 1.1150 - } 1.1151 - else 1.1152 - { 1.1153 - writememl(ss,((SP-4)&0xFFFF),ES); if (abrt) break; 1.1154 - SP-=4; 1.1155 - } 1.1156 - cycles-=2; 1.1157 - break; 1.1158 - case 0x07: case 0x207: /*POP ES*/ 1.1159 - if (ssegs) ss=oldss; 1.1160 - if (stack32) 1.1161 - { 1.1162 - tempw=readmemw(ss,ESP); if (abrt) break; 1.1163 - loadseg(tempw,&_es); if (abrt) break; 1.1164 - ESP+=2; 1.1165 - } 1.1166 - else 1.1167 - { 1.1168 - tempw=readmemw(ss,SP); if (abrt) break; 1.1169 - loadseg(tempw,&_es); if (abrt) break; 1.1170 - SP+=2; 1.1171 - } 1.1172 - cycles-=(is486)?3:7; 1.1173 - break; 1.1174 - case 0x107: case 0x307: /*POP ES*/ 1.1175 - if (ssegs) ss=oldss; 1.1176 - if (stack32) 1.1177 - { 1.1178 - tempw=readmeml(ss,ESP)&0xFFFF; if (abrt) break; 1.1179 - loadseg(tempw,&_es); if (abrt) break; 1.1180 - ESP+=4; 1.1181 - } 1.1182 - else 1.1183 - { 1.1184 - tempw=readmemw(ss,SP); if (abrt) break; 1.1185 - loadseg(tempw,&_es); if (abrt) break; 1.1186 - SP+=4; 1.1187 - } 1.1188 - cycles-=(is486)?3:7; 1.1189 - break; 1.1190 - 1.1191 - 1.1192 - case 0x08: case 0x108: case 0x208: case 0x308: /*OR 8,reg*/ 1.1193 - fetchea(); 1.1194 - if (mod == 3) 1.1195 - { 1.1196 - temp = getr8(rm) | getr8(reg); 1.1197 - setr8(rm, temp); 1.1198 - setznp8(temp); 1.1199 - cycles -= timing_rr; 1.1200 - } 1.1201 - else 1.1202 - { 1.1203 - temp = geteab(); if (abrt) break; 1.1204 - temp2 = getr8(reg); 1.1205 - seteab(temp | temp2); if (abrt) break; 1.1206 - setznp8(temp | temp2); 1.1207 - cycles -= timing_mr; 1.1208 - } 1.1209 - break; 1.1210 - case 0x09: case 0x209: /*OR 16,reg*/ 1.1211 - fetchea(); 1.1212 - if (mod == 3) 1.1213 - { 1.1214 - regs[rm].w |= regs[reg].w; 1.1215 - setznp16(regs[rm].w); 1.1216 - cycles -= timing_rr; 1.1217 - } 1.1218 - else 1.1219 - { 1.1220 - tempw = geteaw() | regs[reg].w; if (abrt) break; 1.1221 - seteaw(tempw); if (abrt) break; 1.1222 - setznp16(tempw); 1.1223 - cycles -= timing_mr; 1.1224 - } 1.1225 - break; 1.1226 - case 0x109: case 0x309: /*OR 32,reg*/ 1.1227 - fetchea(); 1.1228 - if (mod == 3) 1.1229 - { 1.1230 - regs[rm].l |= regs[reg].l; 1.1231 - setznp32(regs[rm].l); 1.1232 - cycles -= timing_rr; 1.1233 - } 1.1234 - else 1.1235 - { 1.1236 - templ = geteal() | regs[reg].l; if (abrt) break; 1.1237 - seteal(templ); if (abrt) break; 1.1238 - setznp32(templ); 1.1239 - cycles -= timing_mrl; 1.1240 - } 1.1241 - break; 1.1242 - case 0x0A: case 0x10A: case 0x20A: case 0x30A: /*OR reg,8*/ 1.1243 - fetchea(); 1.1244 - temp=geteab(); if (abrt) break; 1.1245 - temp|=getr8(reg); 1.1246 - setznp8(temp); 1.1247 - setr8(reg,temp); 1.1248 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.1249 - break; 1.1250 - case 0x0B: case 0x20B: /*OR reg,16*/ 1.1251 - fetchea(); 1.1252 - tempw=geteaw(); if (abrt) break; 1.1253 - tempw|=regs[reg].w; 1.1254 - setznp16(tempw); 1.1255 - regs[reg].w=tempw; 1.1256 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.1257 - break; 1.1258 - case 0x10B: case 0x30B: /*OR reg,32*/ 1.1259 - fetchea(); 1.1260 - templ=geteal(); if (abrt) break; 1.1261 - templ|=regs[reg].l; 1.1262 - setznp32(templ); 1.1263 - regs[reg].l=templ; 1.1264 - cycles -= (mod == 3) ? timing_rr : timing_rml; 1.1265 - break; 1.1266 - case 0x0C: case 0x10C: case 0x20C: case 0x30C: /*OR AL,#8*/ 1.1267 - AL|=getbytef(); 1.1268 - setznp8(AL); 1.1269 - cycles -= timing_rr; 1.1270 - break; 1.1271 - case 0x0D: case 0x20D: /*OR AX,#16*/ 1.1272 - AX|=getwordf(); 1.1273 - setznp16(AX); 1.1274 - cycles -= timing_rr; 1.1275 - break; 1.1276 - case 0x10D: case 0x30D: /*OR AX,#32*/ 1.1277 - templ=getlong(); if (abrt) break; 1.1278 - EAX|=templ; 1.1279 - setznp32(EAX); 1.1280 - cycles -= timing_rr; 1.1281 - break; 1.1282 - 1.1283 - case 0x0E: case 0x20E: /*PUSH CS*/ 1.1284 - if (ssegs) ss=oldss; 1.1285 - if (stack32) 1.1286 - { 1.1287 - writememw(ss,ESP-2,CS); if (abrt) break; 1.1288 - ESP-=2; 1.1289 - } 1.1290 - else 1.1291 - { 1.1292 - writememw(ss,((SP-2)&0xFFFF),CS); if (abrt) break; 1.1293 - SP-=2; 1.1294 - } 1.1295 - cycles-=2; 1.1296 - break; 1.1297 - case 0x10E: case 0x30E: /*PUSH CS*/ 1.1298 - if (ssegs) ss=oldss; 1.1299 - if (stack32) 1.1300 - { 1.1301 - writememl(ss,ESP-4,CS); if (abrt) break; 1.1302 - ESP-=4; 1.1303 - } 1.1304 - else 1.1305 - { 1.1306 - writememl(ss,((SP-4)&0xFFFF),CS); if (abrt) break; 1.1307 - SP-=4; 1.1308 - } 1.1309 - cycles-=2; 1.1310 - break; 1.1311 - 1.1312 - case 0x0F: case 0x20F: 1.1313 - temp=fetchdat&0xFF/*readmemb(cs+pc)*/; pc++; 1.1314 - opcode2=temp; 1.1315 -// 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.1316 - switch (temp) 1.1317 - { 1.1318 - case 0: 1.1319 - if (!(cr0&1) || (eflags&VM_FLAG)) goto inv16; 1.1320 - fetchea2(); if (abrt) break; 1.1321 - switch (rmdat&0x38) 1.1322 - { 1.1323 - case 0x00: /*SLDT*/ 1.1324 - NOTRM 1.1325 - seteaw(ldt.seg); 1.1326 - cycles-=4; 1.1327 - break; 1.1328 - case 0x08: /*STR*/ 1.1329 - NOTRM 1.1330 - seteaw(tr.seg); 1.1331 - cycles-=4; 1.1332 - break; 1.1333 - case 0x10: /*LLDT*/ 1.1334 - if ((CPL || eflags&VM_FLAG) && (cr0&1)) 1.1335 - { 1.1336 - pclog("Invalid LLDT!\n"); 1.1337 - x86gpf(NULL,0); 1.1338 - break; 1.1339 - } 1.1340 - NOTRM 1.1341 - ldt.seg=geteaw(); 1.1342 -// pclog("Load LDT %04X ",ldt.seg); 1.1343 - templ=(ldt.seg&~7)+gdt.base; 1.1344 -// pclog("%06X ",gdt.base); 1.1345 - templ3=readmemw(0,templ)+((readmemb(0,templ+6)&0xF)<<16); 1.1346 - templ2=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24); 1.1347 - if (abrt) break; 1.1348 - ldt.limit=templ3; 1.1349 - ldt.access=readmemb(0,templ+6); 1.1350 - if (readmemb(0,templ+6)&0x80) 1.1351 - { 1.1352 - ldt.limit<<=12; 1.1353 - ldt.limit|=0xFFF; 1.1354 - } 1.1355 - ldt.base=templ2; 1.1356 -// /*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.1357 - 1.1358 - cycles-=20; 1.1359 - break; 1.1360 - case 0x18: /*LTR*/ 1.1361 - if ((CPL || eflags&VM_FLAG) && (cr0&1)) 1.1362 - { 1.1363 - pclog("Invalid LTR!\n"); 1.1364 - x86gpf(NULL,0); 1.1365 - break; 1.1366 - } 1.1367 - NOTRM 1.1368 - tr.seg=geteaw(); 1.1369 - templ=(tr.seg&~7)+gdt.base; 1.1370 - templ3=readmemw(0,templ)+((readmemb(0,templ+6)&0xF)<<16); 1.1371 - templ2=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24); 1.1372 - temp=readmemb(0,templ+5); 1.1373 - if (abrt) break; 1.1374 - tr.limit=templ3; 1.1375 - tr.access=readmemb(0,templ+6); 1.1376 - if (readmemb(0,templ+6)&0x80) 1.1377 - { 1.1378 - tr.limit<<=12; 1.1379 - tr.limit|=0xFFF; 1.1380 - } 1.1381 - tr.base=templ2; 1.1382 -// pclog("TR base = %08X\n",templ2); 1.1383 - tr.access=temp; 1.1384 - cycles-=20; 1.1385 - break; 1.1386 - case 0x20: /*VERR*/ 1.1387 - NOTRM 1.1388 - tempw=geteaw(); if (abrt) break; 1.1389 - flags&=~Z_FLAG; 1.1390 - if (!(tempw&0xFFFC)) break; /*Null selector*/ 1.1391 - cpl_override=1; 1.1392 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.1393 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.1394 - cpl_override=0; 1.1395 - if (abrt) break; 1.1396 - if (!(tempw2&0x1000)) tempi=0; 1.1397 - if ((tempw2&0xC00)!=0xC00) /*Exclude conforming code segments*/ 1.1398 - { 1.1399 - tempw3=(tempw2>>13)&3; /*Check permissions*/ 1.1400 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.1401 - } 1.1402 - if ((tempw2&0x0800) && !(tempw2&0x0200)) tempi=0; /*Non-readable code*/ 1.1403 - if (tempi) flags|=Z_FLAG; 1.1404 - cycles-=20; 1.1405 - break; 1.1406 - case 0x28: /*VERW*/ 1.1407 - NOTRM 1.1408 - tempw=geteaw(); if (abrt) break; 1.1409 - flags&=~Z_FLAG; 1.1410 - if (!(tempw&0xFFFC)) break; /*Null selector*/ 1.1411 - cpl_override=1; 1.1412 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.1413 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.1414 - cpl_override=0; 1.1415 - if (abrt) break; 1.1416 - if (!(tempw2&0x1000)) tempi=0; 1.1417 - tempw3=(tempw2>>13)&3; /*Check permissions*/ 1.1418 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.1419 - if (tempw2&0x0800) tempi=0; /*Code*/ 1.1420 - else if (!(tempw2&0x0200)) tempi=0; /*Read-only data*/ 1.1421 - if (tempi) flags|=Z_FLAG; 1.1422 - cycles-=20; 1.1423 - break; 1.1424 - 1.1425 - 1.1426 - default: 1.1427 - pclog("Bad 0F 00 opcode %02X\n",rmdat&0x38); 1.1428 - pc-=3; 1.1429 - x86illegal(); 1.1430 - break; 1.1431 - } 1.1432 - break; 1.1433 - case 1: 1.1434 - fetchea2(); if (abrt) break; 1.1435 - switch (rmdat&0x38) 1.1436 - { 1.1437 - case 0x00: /*SGDT*/ 1.1438 - seteaw(gdt.limit); 1.1439 - writememw(easeg,eaaddr+2,gdt.base); 1.1440 - writememw(easeg,eaaddr+4,(gdt.base>>16)&0xFF); 1.1441 - cycles-=7; //less seteaw time 1.1442 - break; 1.1443 - case 0x08: /*SIDT*/ 1.1444 - seteaw(idt.limit); 1.1445 - writememw(easeg,eaaddr+2,idt.base); 1.1446 - writememw(easeg,eaaddr+4,(idt.base>>16)&0xFF); 1.1447 - cycles-=7; 1.1448 - break; 1.1449 - case 0x10: /*LGDT*/ 1.1450 - if ((CPL || eflags&VM_FLAG) && (cr0&1)) 1.1451 - { 1.1452 - pclog("Invalid LGDT!\n"); 1.1453 - x86gpf(NULL,0); 1.1454 - break; 1.1455 - } 1.1456 - tempw=geteaw(); 1.1457 - templ=readmeml(0,easeg+eaaddr+2)&0xFFFFFF; 1.1458 - if (abrt) break; 1.1459 - gdt.limit=tempw; 1.1460 - gdt.base=templ; 1.1461 - cycles-=11; 1.1462 - break; 1.1463 - case 0x18: /*LIDT*/ 1.1464 - if ((CPL || eflags&VM_FLAG) && (cr0&1)) 1.1465 - { 1.1466 - pclog("Invalid LIDT!\n"); 1.1467 - x86gpf(NULL,0); 1.1468 - break; 1.1469 - } 1.1470 - tempw=geteaw(); 1.1471 - templ=readmeml(0,easeg+eaaddr+2)&0xFFFFFF; 1.1472 - if (abrt) break; 1.1473 - idt.limit=tempw; 1.1474 - idt.base=templ; 1.1475 - cycles-=11; 1.1476 - break; 1.1477 - 1.1478 - case 0x20: /*SMSW*/ 1.1479 - if (is486) seteaw(msw); 1.1480 - else seteaw(msw|0xFF00); 1.1481 -// pclog("SMSW %04X:%04X %04X %i\n",CS,pc,msw,is486); 1.1482 - cycles-=2; 1.1483 - break; 1.1484 - case 0x30: /*LMSW*/ 1.1485 - if ((CPL || eflags&VM_FLAG) && (msw&1)) 1.1486 - { 1.1487 - pclog("LMSW - ring not zero!\n"); 1.1488 - x86gpf(NULL,0); 1.1489 - break; 1.1490 - } 1.1491 - tempw=geteaw(); if (abrt) break; 1.1492 - if (msw&1) tempw|=1; 1.1493 - msw=tempw; 1.1494 - break; 1.1495 - 1.1496 - default: 1.1497 - pclog("Bad 0F 01 opcode %02X\n",rmdat&0x38); 1.1498 - pc-=3; 1.1499 - x86illegal(); 1.1500 - break; 1.1501 - } 1.1502 - break; 1.1503 - 1.1504 - case 2: /*LAR*/ 1.1505 - NOTRM 1.1506 - fetchea2(); 1.1507 - tempw=geteaw(); if (abrt) break; 1.1508 -// pclog("LAR seg %04X\n",tempw); 1.1509 - 1.1510 - if (!(tempw&0xFFFC)) { flags&=~Z_FLAG; break; } /*Null selector*/ 1.1511 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.1512 - if (tempi) 1.1513 - { 1.1514 - cpl_override=1; 1.1515 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.1516 - cpl_override=0; 1.1517 - if (abrt) break; 1.1518 - } 1.1519 - flags&=~Z_FLAG; 1.1520 -// pclog("tempw2 %04X %i %04X %04X\n",tempw2,tempi,ldt.limit,gdt.limit); 1.1521 - if ((tempw2&0x1F00)==0x000) tempi=0; 1.1522 - if ((tempw2&0x1F00)==0x800) tempi=0; 1.1523 - if ((tempw2&0x1F00)==0xA00) tempi=0; 1.1524 - if ((tempw2&0x1F00)==0xD00) tempi=0; 1.1525 - if ((tempw2&0x1C00)<0x1C00) /*Exclude conforming code segments*/ 1.1526 - { 1.1527 - tempw3=(tempw2>>13)&3; 1.1528 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.1529 - } 1.1530 - if (tempi) 1.1531 - { 1.1532 - flags|=Z_FLAG; 1.1533 - cpl_override=1; 1.1534 - regs[reg].w=readmemb(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+5)<<8; 1.1535 - cpl_override=0; 1.1536 - } 1.1537 - cycles-=11; 1.1538 - break; 1.1539 - 1.1540 - case 3: /*LSL*/ 1.1541 - NOTRM 1.1542 - fetchea2(); 1.1543 - tempw=geteaw(); if (abrt) break; 1.1544 - flags&=~Z_FLAG; 1.1545 - if (!(tempw&0xFFFC)) break; /*Null selector*/ 1.1546 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.1547 - cpl_override=1; 1.1548 - if (tempi) 1.1549 - { 1.1550 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.1551 - } 1.1552 - cpl_override=0; 1.1553 - if (abrt) break; 1.1554 - if ((tempw2&0x1400)==0x400) tempi=0; /*Interrupt or trap or call gate*/ 1.1555 - if ((tempw2&0x1F00)==0x000) tempi=0; /*Invalid*/ 1.1556 - if ((tempw2&0x1F00)==0xA00) tempi=0; /*Invalid*/ 1.1557 - if ((tempw2&0x1C00)!=0x1C00) /*Exclude conforming code segments*/ 1.1558 - { 1.1559 - tempw3=(tempw2>>13)&3; 1.1560 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.1561 - } 1.1562 - if (tempi) 1.1563 - { 1.1564 - flags|=Z_FLAG; 1.1565 - cpl_override=1; 1.1566 - regs[reg].w=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)); 1.1567 - cpl_override=0; 1.1568 - } 1.1569 - cycles-=10; 1.1570 - break; 1.1571 - 1.1572 - case 5: /*LOADALL*/ 1.1573 -// pclog("At %04X:%04X ",CS,pc); 1.1574 - flags=(readmemw(0,0x818)&0xFFD5)|2; 1.1575 - pc=readmemw(0,0x81A); 1.1576 - DS=readmemw(0,0x81E); 1.1577 - SS=readmemw(0,0x820); 1.1578 - CS=readmemw(0,0x822); 1.1579 - ES=readmemw(0,0x824); 1.1580 - DI=readmemw(0,0x826); 1.1581 - SI=readmemw(0,0x828); 1.1582 - BP=readmemw(0,0x82A); 1.1583 - SP=readmemw(0,0x82C); 1.1584 - BX=readmemw(0,0x82E); 1.1585 - DX=readmemw(0,0x830); 1.1586 - CX=readmemw(0,0x832); 1.1587 - AX=readmemw(0,0x834); 1.1588 - es=readmemw(0,0x836)|(readmemb(0,0x838)<<16); 1.1589 - cs=readmemw(0,0x83C)|(readmemb(0,0x83E)<<16); 1.1590 - ss=readmemw(0,0x842)|(readmemb(0,0x844)<<16); 1.1591 - ds=readmemw(0,0x848)|(readmemb(0,0x84A)<<16); 1.1592 - cycles-=195; 1.1593 -// pclog("LOADALL - %06X:%04X %06X:%04X %04X\n",ds,SI,es,DI,DX); 1.1594 - break; 1.1595 - 1.1596 - case 6: /*CLTS*/ 1.1597 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.1598 - { 1.1599 - pclog("Can't CLTS\n"); 1.1600 - x86gpf(NULL,0); 1.1601 - break; 1.1602 - } 1.1603 - cr0&=~8; 1.1604 - cycles-=5; 1.1605 - break; 1.1606 - 1.1607 - case 8: /*INVD*/ 1.1608 - if (!is486) goto inv16; 1.1609 - cycles-=1000; 1.1610 - break; 1.1611 - case 9: /*WBINVD*/ 1.1612 - if (!is486) goto inv16; 1.1613 - cycles-=10000; 1.1614 - break; 1.1615 - 1.1616 - case 0x20: /*MOV reg32,CRx*/ 1.1617 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.1618 - { 1.1619 - pclog("Can't load from CRx\n"); 1.1620 - x86gpf(NULL,0); 1.1621 - break; 1.1622 - } 1.1623 - fetchea2(); 1.1624 - switch (reg) 1.1625 - { 1.1626 - case 0: 1.1627 - regs[rm].l=cr0;//&~2; 1.1628 - if (is486) regs[rm].l|=0x10; /*ET hardwired on 486*/ 1.1629 - break; 1.1630 - case 2: 1.1631 - regs[rm].l=cr2; 1.1632 - break; 1.1633 - case 3: 1.1634 - regs[rm].l=cr3; 1.1635 - break; 1.1636 - default: 1.1637 - pclog("Bad read of CR%i %i\n",rmdat&7,reg); 1.1638 - pc=oldpc; 1.1639 - x86illegal(); 1.1640 - break; 1.1641 - } 1.1642 - cycles-=6; 1.1643 - break; 1.1644 - case 0x21: /*MOV reg32,DRx*/ 1.1645 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.1646 - { 1.1647 - pclog("Can't load from DRx\n"); 1.1648 - x86gpf(NULL,0); 1.1649 - break; 1.1650 - } 1.1651 - fetchea2(); 1.1652 - regs[rm].l=0; 1.1653 - cycles-=6; 1.1654 - break; 1.1655 - case 0x22: /*MOV CRx,reg32*/ 1.1656 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.1657 - { 1.1658 - pclog("Can't load CRx\n"); 1.1659 - x86gpf(NULL,0); 1.1660 - break; 1.1661 - } 1.1662 - fetchea2(); 1.1663 - switch (reg) 1.1664 - { 1.1665 - case 0: 1.1666 - //if ((cr0^regs[rm].l)>>31) flushmmucache(); 1.1667 - if ((regs[rm].l^cr0) & 0x80000001) flushmmucache(); 1.1668 - cr0=regs[rm].l;//&~2; 1.1669 - if (cpu_16bitbus) cr0 |= 0x10; 1.1670 -// if (cs<0xF0000 && cr0&1) output=3; 1.1671 - if (cr0&0x80000000) 1.1672 - { 1.1673 - } 1.1674 - else mmu_perm=4; 1.1675 - break; 1.1676 - case 2: 1.1677 - cr2=regs[rm].l; 1.1678 - break; 1.1679 - case 3: 1.1680 - cr3=regs[rm].l&~0xFFF; 1.1681 -// pclog("Loading CR3 with %08X at %08X:%08X\n",cr3,cs,pc); 1.1682 -// if (pc==0x204) output=3; 1.1683 - flushmmucache(); 1.1684 - break; 1.1685 - default: 1.1686 - pclog("Bad load CR%i\n",reg); 1.1687 - pc=oldpc; 1.1688 - x86illegal(); 1.1689 - break; 1.1690 - } 1.1691 - cycles-=10; 1.1692 - break; 1.1693 - case 0x23: /*MOV DRx,reg32*/ 1.1694 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.1695 - { 1.1696 - pclog("Can't load DRx\n"); 1.1697 - x86gpf(NULL,0); 1.1698 - break; 1.1699 - } 1.1700 - fetchea2(); 1.1701 - cycles-=6; 1.1702 - break; 1.1703 - case 0x24: /*MOV reg32,TRx*/ 1.1704 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.1705 - { 1.1706 - pclog("Can't load from TRx\n"); 1.1707 - x86gpf(NULL,0); 1.1708 - break; 1.1709 - } 1.1710 - fetchea2(); 1.1711 - regs[rm].l=0; 1.1712 - cycles-=6; 1.1713 - break; 1.1714 - case 0x26: /*MOV TRx,reg32*/ 1.1715 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.1716 - { 1.1717 - pclog("Can't load TRx\n"); 1.1718 - x86gpf(NULL,0); 1.1719 - break; 1.1720 - } 1.1721 - fetchea2(); 1.1722 - cycles-=6; 1.1723 - break; 1.1724 - 1.1725 - case 0x32: x86illegal(); break; 1.1726 - 1.1727 - case 0x80: /*JO*/ 1.1728 - tempw=getword2f(); 1.1729 - if (flags&V_FLAG) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1730 - cycles -= timing_bnt; 1.1731 - break; 1.1732 - case 0x81: /*JNO*/ 1.1733 - tempw=getword2f(); 1.1734 - if (!(flags&V_FLAG)) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1735 - cycles -= timing_bnt; 1.1736 - break; 1.1737 - case 0x82: /*JB*/ 1.1738 - tempw=getword2f(); 1.1739 - if (flags&C_FLAG) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1740 - cycles -= timing_bnt; 1.1741 - break; 1.1742 - case 0x83: /*JNB*/ 1.1743 - tempw=getword2f(); 1.1744 - if (!(flags&C_FLAG)) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1745 - cycles -= timing_bnt; 1.1746 - break; 1.1747 - case 0x84: /*JE*/ 1.1748 - tempw=getword2f(); 1.1749 - if (flags&Z_FLAG) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1750 - cycles -= timing_bnt; 1.1751 - break; 1.1752 - case 0x85: /*JNE*/ 1.1753 - tempw=getword2f(); 1.1754 - if (!(flags&Z_FLAG)) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1755 - cycles -= timing_bnt; 1.1756 - break; 1.1757 - case 0x86: /*JBE*/ 1.1758 - tempw=getword2f(); 1.1759 - if (flags&(C_FLAG|Z_FLAG)) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1760 - cycles -= timing_bnt; 1.1761 - break; 1.1762 - case 0x87: /*JNBE*/ 1.1763 - tempw=getword2f(); 1.1764 - if (!(flags&(C_FLAG|Z_FLAG))) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1765 - cycles -= timing_bnt; 1.1766 - break; 1.1767 - case 0x88: /*JS*/ 1.1768 - tempw=getword2f(); 1.1769 - if (flags&N_FLAG) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1770 - cycles -= timing_bnt; 1.1771 - break; 1.1772 - case 0x89: /*JNS*/ 1.1773 - tempw=getword2f(); 1.1774 - if (!(flags&N_FLAG)) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1775 - cycles -= timing_bnt; 1.1776 - break; 1.1777 - case 0x8A: /*JP*/ 1.1778 - tempw=getword2f(); 1.1779 - if (flags&P_FLAG) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1780 - cycles -= timing_bnt; 1.1781 - break; 1.1782 - case 0x8B: /*JNP*/ 1.1783 - tempw=getword2f(); 1.1784 - if (!(flags&P_FLAG)) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1785 - cycles -= timing_bnt; 1.1786 - break; 1.1787 - case 0x8C: /*JL*/ 1.1788 - tempw=getword2f(); 1.1789 - temp=(flags&N_FLAG)?1:0; 1.1790 - temp2=(flags&V_FLAG)?1:0; 1.1791 - if (temp!=temp2) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1792 - cycles -= timing_bnt; 1.1793 - break; 1.1794 - case 0x8D: /*JNL*/ 1.1795 - tempw=getword2f(); 1.1796 - temp=(flags&N_FLAG)?1:0; 1.1797 - temp2=(flags&V_FLAG)?1:0; 1.1798 - if (temp==temp2) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1799 - cycles -= timing_bnt; 1.1800 - break; 1.1801 - case 0x8E: /*JLE*/ 1.1802 - tempw=getword2f(); 1.1803 - temp=(flags&N_FLAG)?1:0; 1.1804 - temp2=(flags&V_FLAG)?1:0; 1.1805 - if ((flags&Z_FLAG) || (temp!=temp2)) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1806 - cycles -= timing_bnt; 1.1807 - break; 1.1808 - case 0x8F: /*JNLE*/ 1.1809 - tempw=getword2f(); 1.1810 - temp=(flags&N_FLAG)?1:0; 1.1811 - temp2=(flags&V_FLAG)?1:0; 1.1812 - if (!((flags&Z_FLAG) || (temp!=temp2))) { pc+=(int16_t)tempw; cycles-=timing_bt; } 1.1813 - cycles -= timing_bnt; 1.1814 - break; 1.1815 - 1.1816 - case 0x90: /*SETO*/ 1.1817 - fetchea2(); 1.1818 - seteab((flags&V_FLAG)?1:0); 1.1819 - cycles-=4; 1.1820 - break; 1.1821 - case 0x91: /*SETNO*/ 1.1822 - fetchea2(); 1.1823 - seteab((flags&V_FLAG)?0:1); 1.1824 - cycles-=4; 1.1825 - break; 1.1826 - case 0x92: /*SETC*/ 1.1827 - fetchea2(); 1.1828 - seteab((flags&C_FLAG)?1:0); 1.1829 - cycles-=4; 1.1830 - break; 1.1831 - case 0x93: /*SETAE*/ 1.1832 - fetchea2(); 1.1833 - seteab((flags&C_FLAG)?0:1); 1.1834 - cycles-=4; 1.1835 - break; 1.1836 - case 0x94: /*SETZ*/ 1.1837 - fetchea2(); 1.1838 - seteab((flags&Z_FLAG)?1:0); 1.1839 - cycles-=4; 1.1840 - break; 1.1841 - case 0x95: /*SETNZ*/ 1.1842 - fetchea2(); 1.1843 - seteab((flags&Z_FLAG)?0:1); 1.1844 - cycles-=4; 1.1845 - break; 1.1846 - case 0x96: /*SETBE*/ 1.1847 - fetchea2(); 1.1848 - seteab((flags&(C_FLAG|Z_FLAG))?1:0); 1.1849 - cycles-=4; 1.1850 - break; 1.1851 - case 0x97: /*SETNBE*/ 1.1852 - fetchea2(); 1.1853 - seteab((flags&(C_FLAG|Z_FLAG))?0:1); 1.1854 - cycles-=4; 1.1855 - break; 1.1856 - case 0x98: /*SETS*/ 1.1857 - fetchea2(); 1.1858 - seteab((flags&N_FLAG)?1:0); 1.1859 - cycles-=4; 1.1860 - break; 1.1861 - case 0x99: /*SETNS*/ 1.1862 - fetchea2(); 1.1863 - seteab((flags&N_FLAG)?0:1); 1.1864 - cycles-=4; 1.1865 - break; 1.1866 - case 0x9A: /*SETP*/ 1.1867 - fetchea2(); 1.1868 - seteab((flags&P_FLAG)?1:0); 1.1869 - cycles-=4; 1.1870 - break; 1.1871 - case 0x9B: /*SETNP*/ 1.1872 - fetchea2(); 1.1873 - seteab((flags&P_FLAG)?0:1); 1.1874 - cycles-=4; 1.1875 - break; 1.1876 - case 0x9C: /*SETL*/ 1.1877 - fetchea2(); 1.1878 - temp=(flags&N_FLAG)?1:0; 1.1879 - temp2=(flags&V_FLAG)?1:0; 1.1880 - seteab(temp^temp2); 1.1881 - cycles-=4; 1.1882 - break; 1.1883 - case 0x9D: /*SETGE*/ 1.1884 - fetchea2(); 1.1885 - temp=(flags&N_FLAG)?1:0; 1.1886 - temp2=(flags&V_FLAG)?1:0; 1.1887 - seteab((temp^temp2)?0:1); 1.1888 - cycles-=4; 1.1889 - break; 1.1890 - case 0x9E: /*SETLE*/ 1.1891 - fetchea2(); 1.1892 - temp=(flags&N_FLAG)?1:0; 1.1893 - temp2=(flags&V_FLAG)?1:0; 1.1894 - seteab(((temp^temp2) || (flags&Z_FLAG))?1:0); 1.1895 - cycles-=4; 1.1896 - break; 1.1897 - case 0x9F: /*SETNLE*/ 1.1898 - fetchea2(); 1.1899 - temp=(flags&N_FLAG)?1:0; 1.1900 - temp2=(flags&V_FLAG)?1:0; 1.1901 - seteab(((temp^temp2) || (flags&Z_FLAG))?0:1); 1.1902 - cycles-=4; 1.1903 - break; 1.1904 - 1.1905 - case 0xA0: /*PUSH FS*/ 1.1906 - if (ssegs) ss=oldss; 1.1907 - if (stack32) 1.1908 - { 1.1909 - writememw(ss,ESP-2,FS); if (abrt) break; 1.1910 - ESP-=2; 1.1911 - } 1.1912 - else 1.1913 - { 1.1914 - writememw(ss,((SP-2)&0xFFFF),FS); if (abrt) break; 1.1915 - SP-=2; 1.1916 - } 1.1917 - cycles-=2; 1.1918 - break; 1.1919 - case 0xA1: /*POP FS*/ 1.1920 - if (ssegs) ss=oldss; 1.1921 - if (stack32) 1.1922 - { 1.1923 - tempw=readmemw(ss,ESP); if (abrt) break; 1.1924 - loadseg(tempw,&_fs); if (abrt) break; 1.1925 - ESP+=2; 1.1926 - } 1.1927 - else 1.1928 - { 1.1929 - tempw=readmemw(ss,SP); if (abrt) break; 1.1930 - loadseg(tempw,&_fs); if (abrt) break; 1.1931 - SP+=2; 1.1932 - } 1.1933 - cycles-=(is486)?3:7; 1.1934 - break; 1.1935 - case 0xA3: /*BT r16*/ 1.1936 - fetchea2(); 1.1937 - eaaddr+=((regs[reg].w/16)*2); eal_r = 0; 1.1938 - tempw=geteaw(); if (abrt) break; 1.1939 - if (tempw&(1<<(regs[reg].w&15))) flags|=C_FLAG; 1.1940 - else flags&=~C_FLAG; 1.1941 - cycles-=3; 1.1942 - break; 1.1943 - case 0xA4: /*SHLD imm*/ 1.1944 - fetchea2(); 1.1945 - temp=readmemb(cs,pc)&31; pc++; 1.1946 - if (temp) 1.1947 - { 1.1948 - tempw=geteaw(); if (abrt) break; 1.1949 - tempc=((tempw<<(temp-1))&0x8000)?1:0; 1.1950 - templ=(tempw<<16)|regs[reg].w; 1.1951 - if (temp<=16) tempw=templ>>(16-temp); 1.1952 - else tempw=(templ<<temp)>>16; 1.1953 - seteaw(tempw); if (abrt) break; 1.1954 - setznp16(tempw); 1.1955 - if (tempc) flags|=C_FLAG; 1.1956 - } 1.1957 - cycles-=3; 1.1958 - break; 1.1959 - case 0xA5: /*SHLD CL*/ 1.1960 - fetchea2(); 1.1961 - temp=CL&31; 1.1962 - if (temp) 1.1963 - { 1.1964 - tempw=geteaw(); if (abrt) break; 1.1965 - tempc=((tempw<<(temp-1))&0x8000)?1:0; 1.1966 - templ=(tempw<<16)|regs[reg].w; 1.1967 - if (temp<=16) tempw=templ>>(16-temp); 1.1968 - else tempw=(templ<<temp)>>16; 1.1969 - seteaw(tempw); if (abrt) break; 1.1970 - setznp16(tempw); 1.1971 - if (tempc) flags|=C_FLAG; 1.1972 - } 1.1973 - cycles-=3; 1.1974 - break; 1.1975 - case 0xA8: /*PUSH GS*/ 1.1976 - if (ssegs) ss=oldss; 1.1977 - if (stack32) 1.1978 - { 1.1979 - writememw(ss,ESP-2,GS); if (abrt) break; 1.1980 - ESP-=2; 1.1981 - } 1.1982 - else 1.1983 - { 1.1984 - writememw(ss,((SP-2)&0xFFFF),GS); if (abrt) break; 1.1985 - SP-=2; 1.1986 - } 1.1987 - cycles-=2; 1.1988 - break; 1.1989 - case 0xA9: /*POP GS*/ 1.1990 - if (ssegs) ss=oldss; 1.1991 - if (stack32) 1.1992 - { 1.1993 - tempw=readmemw(ss,ESP); if (abrt) break; 1.1994 - loadseg(tempw,&_gs); if (abrt) break; 1.1995 - ESP+=2; 1.1996 - } 1.1997 - else 1.1998 - { 1.1999 - tempw=readmemw(ss,SP); if (abrt) break; 1.2000 - loadseg(tempw,&_gs); if (abrt) break; 1.2001 - SP+=2; 1.2002 - } 1.2003 - cycles-=(is486)?3:7; 1.2004 - break; 1.2005 - case 0xAB: /*BTS r16*/ 1.2006 - fetchea2(); 1.2007 - eaaddr+=((regs[reg].w/16)*2); eal_r = eal_w = 0; 1.2008 - tempw=geteaw(); if (abrt) break; 1.2009 - tempc=(tempw&(1<<(regs[reg].w&15)))?1:0; 1.2010 - tempw|=(1<<(regs[reg].w&15)); 1.2011 - seteaw(tempw); if (abrt) break; 1.2012 - if (tempc) flags|=C_FLAG; 1.2013 - else flags&=~C_FLAG; 1.2014 - cycles-=6; 1.2015 - break; 1.2016 - case 0xAC: /*SHRD imm*/ 1.2017 - fetchea2(); 1.2018 - temp=readmemb(cs,pc)&31; pc++; 1.2019 - if (temp) 1.2020 - { 1.2021 - tempw=geteaw(); if (abrt) break; 1.2022 - tempc=(tempw>>(temp-1))&1; 1.2023 - templ=tempw|(regs[reg].w<<16); 1.2024 - tempw=templ>>temp; 1.2025 - seteaw(tempw); if (abrt) break; 1.2026 - setznp16(tempw); 1.2027 - if (tempc) flags|=C_FLAG; 1.2028 - } 1.2029 - cycles-=3; 1.2030 - break; 1.2031 - case 0xAD: /*SHRD CL*/ 1.2032 - fetchea2(); 1.2033 - temp=CL&31; 1.2034 - if (temp) 1.2035 - { 1.2036 - tempw=geteaw(); if (abrt) break; 1.2037 - tempc=(tempw>>(temp-1))&1; 1.2038 - templ=tempw|(regs[reg].w<<16); 1.2039 - tempw=templ>>temp; 1.2040 - seteaw(tempw); if (abrt) break; 1.2041 - setznp16(tempw); 1.2042 - if (tempc) flags|=C_FLAG; 1.2043 - } 1.2044 - cycles-=3; 1.2045 - break; 1.2046 - 1.2047 - case 0xAF: /*IMUL reg16,rm16*/ 1.2048 - fetchea2(); 1.2049 - templ=(int32_t)(int16_t)regs[reg].w*(int32_t)(int16_t)geteaw(); 1.2050 - if (abrt) break; 1.2051 - regs[reg].w=templ&0xFFFF; 1.2052 - if ((templ>>16) && (templ>>16)!=0xFFFF) flags|=C_FLAG|V_FLAG; 1.2053 - else flags&=~(C_FLAG|V_FLAG); 1.2054 - cycles-=18; 1.2055 - break; 1.2056 - 1.2057 - case 0xB0: /*CMPXCHG rm8, reg8*/ 1.2058 - if (!is486) goto inv16; 1.2059 - fetchea2(); 1.2060 - temp = geteab(); 1.2061 - setsub8(AL, temp); 1.2062 - if (AL == temp) seteab(getr8(reg)); 1.2063 - else AL = temp; 1.2064 - cycles -= (mod == 3) ? 6 : 10; 1.2065 - break; 1.2066 - case 0xB1: /*CMPXCHG rm16, reg16*/ 1.2067 - if (!is486) goto inv16; 1.2068 - fetchea2(); 1.2069 - tempw = geteaw(); 1.2070 - setsub16(AX, tempw); 1.2071 - if (AX == tempw) seteaw(regs[reg].w); 1.2072 - else AX = tempw; 1.2073 - cycles -= (mod == 3) ? 6 : 10; 1.2074 - break; 1.2075 - 1.2076 - case 0xB3: /*BTR r16*/ 1.2077 - fetchea2(); 1.2078 - eaaddr+=((regs[reg].w/16)*2); eal_r = eal_w = 0; 1.2079 - tempw=geteaw(); if (abrt) break; 1.2080 - tempc=tempw&(1<<(regs[reg].w&15)); 1.2081 - tempw&=~(1<<(regs[reg].w&15)); 1.2082 - seteaw(tempw); if (abrt) break; 1.2083 - if (tempc) flags|=C_FLAG; 1.2084 - else flags&=~C_FLAG; 1.2085 - cycles-=6; 1.2086 - break; 1.2087 - 1.2088 - case 0xB2: /*LSS*/ 1.2089 - fetchea2(); 1.2090 - tempw2=readmemw(easeg,eaaddr); 1.2091 - tempw=readmemw(easeg,(eaaddr+2)); if (abrt) break; 1.2092 - loadseg(tempw,&_ss); if (abrt) break; 1.2093 - regs[reg].w=tempw2; 1.2094 - oldss=ss; 1.2095 - cycles-=7; 1.2096 - break; 1.2097 - case 0xB4: /*LFS*/ 1.2098 - fetchea2(); 1.2099 - tempw2=readmemw(easeg,eaaddr); 1.2100 - tempw=readmemw(easeg,(eaaddr+2)); if (abrt) break; 1.2101 - loadseg(tempw,&_fs); if (abrt) break; 1.2102 - regs[reg].w=tempw2; 1.2103 - cycles-=7; 1.2104 - break; 1.2105 - case 0xB5: /*LGS*/ 1.2106 - fetchea2(); 1.2107 - tempw2=readmemw(easeg,eaaddr); 1.2108 - tempw=readmemw(easeg,(eaaddr+2)); if (abrt) break; 1.2109 - loadseg(tempw,&_gs); if (abrt) break; 1.2110 - regs[reg].w=tempw2; 1.2111 - cycles-=7; 1.2112 - break; 1.2113 - 1.2114 - case 0xB6: /*MOVZX b*/ 1.2115 - fetchea2(); 1.2116 - tempw=geteab(); if (abrt) break; 1.2117 - regs[reg].w=tempw; 1.2118 - cycles-=3; 1.2119 - break; 1.2120 - case 0xB7: /*MOVZX w*/ 1.2121 - fetchea2(); /*Slightly pointless?*/ 1.2122 - tempw=geteaw(); if (abrt) break; 1.2123 - regs[reg].w=tempw; 1.2124 - cycles-=3; 1.2125 - break; 1.2126 - case 0xBE: /*MOVSX b*/ 1.2127 - fetchea2(); 1.2128 - tempw=geteab(); if (abrt) break; 1.2129 - if (tempw&0x80) tempw|=0xFF00; 1.2130 - regs[reg].w=tempw; 1.2131 - cycles-=3; 1.2132 - break; 1.2133 - 1.2134 - case 0xBA: /*MORE?!?!?!*/ 1.2135 - fetchea2(); 1.2136 - switch (rmdat&0x38) 1.2137 - { 1.2138 - case 0x20: /*BT w,imm*/ 1.2139 - tempw=geteaw(); 1.2140 - temp=readmemb(cs,pc); pc++; if (abrt) break; 1.2141 - if (tempw&(1<<temp)) flags|=C_FLAG; 1.2142 - else flags&=~C_FLAG; 1.2143 - cycles-=6; 1.2144 - break; 1.2145 - case 0x28: /*BTS w,imm*/ 1.2146 - tempw=geteaw(); 1.2147 - temp=readmemb(cs,pc); pc++; if (abrt) break; 1.2148 - tempc=(tempw&(1<<temp))?1:0; 1.2149 - tempw|=(1<<temp); 1.2150 - seteaw(tempw); if (abrt) break; 1.2151 - if (tempc) flags|=C_FLAG; 1.2152 - else flags&=~C_FLAG; 1.2153 - cycles-=6; 1.2154 - break; 1.2155 - case 0x30: /*BTR w,imm*/ 1.2156 - tempw=geteaw(); 1.2157 - temp=readmemb(cs,pc); pc++; if (abrt) break; 1.2158 - tempc=(tempw&(1<<temp))?1:0; 1.2159 - tempw&=~(1<<temp); 1.2160 - seteaw(tempw); if (abrt) break; 1.2161 - if (tempc) flags|=C_FLAG; 1.2162 - else flags&=~C_FLAG; 1.2163 - cycles-=6; 1.2164 - break; 1.2165 - case 0x38: /*BTC w,imm*/ 1.2166 - tempw=geteaw(); 1.2167 - temp=readmemb(cs,pc); pc++; if (abrt) break; 1.2168 - tempc=(tempw&(1<<temp))?1:0; 1.2169 - tempw^=(1<<temp); 1.2170 - seteaw(tempw); if (abrt) break; 1.2171 - if (tempc) flags|=C_FLAG; 1.2172 - else flags&=~C_FLAG; 1.2173 - cycles-=6; 1.2174 - break; 1.2175 - 1.2176 - default: 1.2177 - pclog("Bad 0F BA opcode %02X\n",rmdat&0x38); 1.2178 - pc=oldpc; 1.2179 - x86illegal(); 1.2180 - break; 1.2181 - } 1.2182 - break; 1.2183 - 1.2184 - case 0xBC: /*BSF w*/ 1.2185 - fetchea2(); 1.2186 - tempw = geteaw(); if (abrt) break; 1.2187 - if (!tempw) 1.2188 - { 1.2189 -// regs[reg].w=0; 1.2190 - flags |= Z_FLAG; 1.2191 - } 1.2192 - else 1.2193 - { 1.2194 - for (tempi = 0; tempi < 16; tempi++) 1.2195 - { 1.2196 - cycles -= (is486) ? 1 : 3; 1.2197 - if (tempw & (1 << tempi)) 1.2198 - { 1.2199 - flags &= ~Z_FLAG; 1.2200 - regs[reg].w = tempi; 1.2201 - break; 1.2202 - } 1.2203 - } 1.2204 - } 1.2205 - cycles -= (is486) ? 6 : 10; 1.2206 - break; 1.2207 - case 0xBD: /*BSR w*/ 1.2208 - fetchea2(); 1.2209 - tempw = geteaw(); if (abrt) break; 1.2210 - if (!tempw) 1.2211 - { 1.2212 -// regs[reg].w=0; 1.2213 - flags |= Z_FLAG; 1.2214 - } 1.2215 - else 1.2216 - { 1.2217 - for (tempi = 15; tempi >= 0; tempi--) 1.2218 - { 1.2219 - cycles -= 3; 1.2220 - if (tempw & (1 << tempi)) 1.2221 - { 1.2222 - flags &= ~Z_FLAG; 1.2223 - regs[reg].w = tempi; 1.2224 - break; 1.2225 - } 1.2226 - } 1.2227 - } 1.2228 - cycles -= (is486) ? 6 : 10; 1.2229 - break; 1.2230 - 1.2231 - case 0xA2: /*CPUID*/ 1.2232 - if (CPUID) 1.2233 - { 1.2234 - cpu_CPUID(); 1.2235 - cycles-=9; 1.2236 - break; 1.2237 - } 1.2238 - goto inv16; 1.2239 - 1.2240 - case 0xC0: /*XADD b*/ 1.2241 - pclog("XADDb 16\n"); 1.2242 - fetchea2(); 1.2243 - temp=geteab(); if (abrt) break; 1.2244 - seteab(temp+getr8(reg)); if (abrt) break; 1.2245 - setadd8(temp,getr8(reg)); 1.2246 - setr8(reg,temp); 1.2247 - break; 1.2248 - case 0xC1: /*XADD w*/ 1.2249 - pclog("XADDw 16\n"); 1.2250 - fetchea2(); 1.2251 - tempw=geteaw(); if (abrt) break; 1.2252 - seteaw(tempw+regs[reg].w); if (abrt) break; 1.2253 - setadd16(tempw,regs[reg].w); 1.2254 - regs[reg].w=tempw; 1.2255 - break; 1.2256 - 1.2257 - case 0xA6: /*XBTS/CMPXCHG486*/ 1.2258 - pclog("CMPXCHG486\n"); 1.2259 -// output=1; 1.2260 - case 0xFF: /*Invalid - Windows 3.1 syscall trap?*/ 1.2261 - inv16: 1.2262 - pc-=2; 1.2263 - if (msw&1) 1.2264 - { 1.2265 - pmodeint(6,0); 1.2266 - } 1.2267 - else 1.2268 - { 1.2269 - if (ssegs) ss=oldss; 1.2270 - if (stack32) 1.2271 - { 1.2272 - writememw(ss,ESP-2,flags); 1.2273 - writememw(ss,ESP-4,CS); 1.2274 - writememw(ss,ESP-6,pc); 1.2275 - ESP-=6; 1.2276 - } 1.2277 - else 1.2278 - { 1.2279 - writememw(ss,((SP-2)&0xFFFF),flags); 1.2280 - writememw(ss,((SP-4)&0xFFFF),CS); 1.2281 - writememw(ss,((SP-6)&0xFFFF),pc); 1.2282 - SP-=6; 1.2283 - } 1.2284 - addr=6<<2; 1.2285 - flags&=~I_FLAG; 1.2286 - flags&=~T_FLAG; 1.2287 - oxpc=pc; 1.2288 - pc=readmemw(0,addr); 1.2289 - loadcs(readmemw(0,addr+2)); 1.2290 - } 1.2291 - cycles-=70; 1.2292 - break; 1.2293 - 1.2294 - default: 1.2295 - pclog("Bad 16-bit 0F opcode %02X 386 %i\n",temp,ins); 1.2296 - pc=oldpc; 1.2297 - x86illegal(); 1.2298 - break; 1.2299 - } 1.2300 - break; 1.2301 - 1.2302 - case 0x10F: case 0x30F: 1.2303 - temp=fetchdat&0xFF/*readmemb(cs+pc)*/; pc++; 1.2304 - opcode2=temp; 1.2305 - switch (temp) 1.2306 - { 1.2307 - case 0: 1.2308 - if (!(cr0&1) || (eflags&VM_FLAG)) goto inv32; 1.2309 - fetchea2(); 1.2310 -// pclog("32-bit op %02X\n",rmdat&0x38); 1.2311 - switch (rmdat&0x38) 1.2312 - { 1.2313 - case 0x00: /*SLDT*/ 1.2314 - NOTRM 1.2315 - seteaw(ldt.seg); 1.2316 - cycles-=4; 1.2317 - break; 1.2318 - case 0x08: /*STR*/ 1.2319 - NOTRM 1.2320 - seteaw(tr.seg); 1.2321 - cycles-=4; 1.2322 - break; 1.2323 - case 0x10: /*LLDT*/ 1.2324 - if ((CPL || eflags&VM_FLAG) && (cr0&1)) 1.2325 - { 1.2326 - pclog("Invalid LLDT32!\n"); 1.2327 - x86gpf(NULL,0); 1.2328 - break; 1.2329 - } 1.2330 - NOTRM 1.2331 - ldt.seg=geteaw(); if (abrt) break; 1.2332 - templ=(ldt.seg&~7)+gdt.base; 1.2333 - templ3=readmemw(0,templ)+((readmemb(0,templ+6)&0xF)<<16); 1.2334 - templ2=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24); 1.2335 - if (abrt) break; 1.2336 - ldt.limit=templ3; 1.2337 - ldt.base=templ2; 1.2338 - ldt.access=readmemb(0,templ+6); 1.2339 - if (readmemb(0,templ+6)&0x80) 1.2340 - { 1.2341 - ldt.limit<<=12; 1.2342 - ldt.limit|=0xFFF; 1.2343 - } 1.2344 -// /*if (output==3) */pclog("LLDT32 %04X %08X %04X\n",ldt.seg,ldt.base,ldt.limit,readmeml(0,templ),readmeml(0,templ+4)); 1.2345 - cycles-=20; 1.2346 - break; 1.2347 - case 0x18: /*LTR*/ 1.2348 - if ((CPL || eflags&VM_FLAG) && (cr0&1)) 1.2349 - { 1.2350 - pclog("Invalid LTR32!\n"); 1.2351 - x86gpf(NULL,0); 1.2352 - break; 1.2353 - } 1.2354 - NOTRM 1.2355 - tempw=geteaw(); if (abrt) break; 1.2356 - tr.seg=tempw; 1.2357 - templ=(tempw&~7)+gdt.base; 1.2358 - templ3=readmemw(0,templ)+((readmemb(0,templ+6)&0xF)<<16); 1.2359 - templ2=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24); 1.2360 - temp=readmemb(0,templ+5); 1.2361 - if (abrt) break; 1.2362 - tr.seg=tempw; 1.2363 - tr.limit=templ3; 1.2364 - tr.access=readmemb(0,templ+6); 1.2365 - if (readmemb(0,templ+6)&0x80) 1.2366 - { 1.2367 - tr.limit<<=12; 1.2368 - tr.limit|=0xFFF; 1.2369 - } 1.2370 - tr.base=templ2; 1.2371 -// pclog("TR base = %08X\n",templ2); 1.2372 - tr.access=temp; 1.2373 - cycles-=20; 1.2374 - break; 1.2375 - 1.2376 - case 0x20: /*VERR*/ 1.2377 - NOTRM 1.2378 - tempw=geteaw(); if (abrt) break; 1.2379 - flags&=~Z_FLAG; 1.2380 - if (!(tempw&0xFFFC)) break; /*Null selector*/ 1.2381 - cpl_override=1; 1.2382 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.2383 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.2384 - cpl_override=0; 1.2385 - if (abrt) break; 1.2386 - if (!(tempw2&0x1000)) tempi=0; 1.2387 - if ((tempw2&0xC00)!=0xC00) /*Exclude conforming code segments*/ 1.2388 - { 1.2389 - tempw3=(tempw2>>13)&3; /*Check permissions*/ 1.2390 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.2391 - } 1.2392 - if ((tempw2&0x0800) && !(tempw2&0x0200)) tempi=0; /*Non-readable code*/ 1.2393 - if (tempi) flags|=Z_FLAG; 1.2394 - cycles-=20; 1.2395 - break; 1.2396 - case 0x28: /*VERW*/ 1.2397 - NOTRM 1.2398 - tempw=geteaw(); if (abrt) break; 1.2399 - flags&=~Z_FLAG; 1.2400 - if (!(tempw&0xFFFC)) break; /*Null selector*/ 1.2401 - cpl_override=1; 1.2402 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.2403 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.2404 - cpl_override=0; 1.2405 - if (abrt) break; 1.2406 - if (!(tempw2&0x1000)) tempi=0; 1.2407 - tempw3=(tempw2>>13)&3; /*Check permissions*/ 1.2408 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.2409 - if (tempw2&0x0800) tempi=0; /*Code*/ 1.2410 - else if (!(tempw2&0x0200)) tempi=0; /*Read-only data*/ 1.2411 - if (tempi) flags|=Z_FLAG; 1.2412 - cycles-=20; 1.2413 - break; 1.2414 - 1.2415 - default: 1.2416 - pclog("Bad 0F 00 opcode %02X\n",rmdat&0x38); 1.2417 - pc=oldpc; 1.2418 - x86illegal(); 1.2419 - break; 1.2420 - } 1.2421 - break; 1.2422 - case 1: 1.2423 - fetchea2(); 1.2424 - switch (rmdat&0x38) 1.2425 - { 1.2426 - case 0x00: /*SGDT*/ 1.2427 - seteaw(gdt.limit); 1.2428 - writememl(easeg,eaaddr+2,gdt.base); 1.2429 - cycles-=7; 1.2430 - break; 1.2431 - case 0x08: /*SIDT*/ 1.2432 - seteaw(idt.limit); 1.2433 - writememl(easeg,eaaddr+2,idt.base); 1.2434 - cycles-=7; 1.2435 - break; 1.2436 - case 0x10: /*LGDT*/ 1.2437 - if ((CPL || eflags&VM_FLAG) && (cr0&1)) 1.2438 - { 1.2439 - pclog("Invalid LGDT32!\n"); 1.2440 - x86gpf(NULL,0); 1.2441 - break; 1.2442 - } 1.2443 - tempw=geteaw(); 1.2444 - templ=readmeml(easeg,eaaddr+2); 1.2445 - if (abrt) break; 1.2446 - gdt.limit=tempw; 1.2447 - gdt.base=templ; 1.2448 -// pclog("LGDT32 %08X %04X\n",gdt.base,gdt.limit); 1.2449 - cycles-=11; 1.2450 - break; 1.2451 - case 0x18: /*LIDT*/ 1.2452 - if ((CPL || eflags&VM_FLAG) && (cr0&1)) 1.2453 - { 1.2454 - pclog("Invalid LIDT32!\n"); 1.2455 - x86gpf(NULL,0); 1.2456 - break; 1.2457 - } 1.2458 - tempw=geteaw(); 1.2459 - templ=readmeml(easeg,eaaddr+2); 1.2460 - idt.limit=tempw; 1.2461 - idt.base=templ; 1.2462 -// pclog("LIDT32 %08X %08X\n",idt.base,readmeml(0,easeg+eaaddr+2)); 1.2463 - cycles-=11; 1.2464 - break; 1.2465 - case 0x20: /*SMSW*/ 1.2466 - if (mod<3) seteaw(cr0); 1.2467 - else seteal(cr0); /*Apparently this is the case!*/ 1.2468 -// pclog("SMSW32 %04X(%06X):%04X\n",CS,cs,pc); 1.2469 - cycles-=2; 1.2470 - break; 1.2471 - 1.2472 - case 0x30: /*LMSW*/ 1.2473 - if ((CPL || eflags&VM_FLAG) && (msw&1)) 1.2474 - { 1.2475 - pclog("LMSW - ring not zero!\n"); 1.2476 - x86gpf(NULL,0); 1.2477 - break; 1.2478 - } 1.2479 - tempw=geteaw(); if (abrt) break; 1.2480 - if (msw&1) tempw|=1; 1.2481 - msw=tempw; 1.2482 - break; 1.2483 - 1.2484 - case 0x38: /*INVLPG*/ 1.2485 - if (is486) 1.2486 - { 1.2487 - if ((CPL || eflags&VM_FLAG) && (cr0&1)) 1.2488 - { 1.2489 - pclog("Invalid INVLPG!\n"); 1.2490 - x86gpf(NULL,0); 1.2491 - break; 1.2492 - } 1.2493 - if (output) pclog("INVLPG %08X + %08X\n", eaaddr, ds); 1.2494 - mmu_invalidate(ds + eaaddr); 1.2495 - cycles-=12; 1.2496 - break; 1.2497 - } 1.2498 - 1.2499 - 1.2500 - default: 1.2501 - pclog("Bad 0F 01 opcode %02X\n",rmdat&0x38); 1.2502 - pc=oldpc; 1.2503 - x86illegal(); 1.2504 - break; 1.2505 - } 1.2506 - break; 1.2507 - 1.2508 - case 2: /*LAR*/ 1.2509 - NOTRM 1.2510 - fetchea2(); 1.2511 - tempw=geteaw(); if (abrt) break; 1.2512 -// pclog("LAR seg %04X\n",tempw); 1.2513 - if (!(tempw&0xFFFC)) { flags&=~Z_FLAG; break; } /*Null selector*/ 1.2514 - cpl_override=1; 1.2515 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.2516 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.2517 - cpl_override=0; 1.2518 - if (abrt) break; 1.2519 - flags&=~Z_FLAG; 1.2520 -// pclog("tempw2 %04X %i %04X %04X\n",tempw2,tempi,ldt.limit,gdt.limit); 1.2521 - if ((tempw2&0x1F00)==0x000) tempi=0; 1.2522 - if ((tempw2&0x1F00)==0x800) tempi=0; 1.2523 - if ((tempw2&0x1F00)==0xA00) tempi=0; 1.2524 - if ((tempw2&0x1F00)==0xD00) tempi=0; 1.2525 - if ((tempw2&0x1C00)<0x1C00) /*Exclude conforming code segments*/ 1.2526 - { 1.2527 - tempw3=(tempw2>>13)&3; 1.2528 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.2529 - } 1.2530 - if (tempi) 1.2531 - { 1.2532 - flags|=Z_FLAG; 1.2533 - cpl_override=1; 1.2534 - regs[reg].l=readmeml(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4)&0xFFFF00; 1.2535 - cpl_override=0; 1.2536 - } 1.2537 - cycles-=11; 1.2538 - break; 1.2539 - 1.2540 - case 3: /*LSL*/ 1.2541 - NOTRM 1.2542 - fetchea2(); 1.2543 - tempw=geteaw(); if (abrt) break; 1.2544 - if (output) pclog("LSL %04X\n",tempw); 1.2545 - if (!(tempw&0xFFFC)) { flags&=~Z_FLAG; break; } /*Null selector*/ 1.2546 - cpl_override=1; 1.2547 - tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit); 1.2548 - if (output) pclog("In range? %i\n",tempi); 1.2549 - if (tempi) 1.2550 - { 1.2551 - tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4); 1.2552 - if (output) pclog("segdat[2] = %04X\n",tempw2); 1.2553 - } 1.2554 - cpl_override=0; 1.2555 - if (abrt) break; 1.2556 - flags&=~Z_FLAG; 1.2557 - if ((tempw2&0x1400)==0x400) tempi=0; /*Interrupt or trap or call gate*/ 1.2558 - if ((tempw2&0x1F00)==0x000) tempi=0; /*Invalid*/ 1.2559 - if ((tempw2&0x1F00)==0xA00) tempi=0; /*Invalid*/ 1.2560 - if ((tempw2&0x1C00)!=0x1C00) /*Exclude conforming code segments*/ 1.2561 - { 1.2562 - tempw3=(tempw2>>13)&3; 1.2563 - if (tempw3<CPL || tempw3<(tempw&3)) tempi=0; 1.2564 - } 1.2565 - if (output) pclog("Final tempi %i\n",tempi); 1.2566 - if (tempi) 1.2567 - { 1.2568 - flags|=Z_FLAG; 1.2569 - cpl_override=1; 1.2570 - regs[reg].l=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)); 1.2571 - regs[reg].l|=(readmemb(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+6)&0xF)<<16; 1.2572 - if (readmemb(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+6)&0x80) 1.2573 - { 1.2574 - regs[reg].l<<=12; 1.2575 - regs[reg].l|=0xFFF; 1.2576 - } 1.2577 - cpl_override=0; 1.2578 - } 1.2579 - cycles-=10; 1.2580 - break; 1.2581 - 1.2582 - case 6: /*CLTS*/ 1.2583 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.2584 - { 1.2585 - pclog("Can't CLTS\n"); 1.2586 - x86gpf(NULL,0); 1.2587 - break; 1.2588 - } 1.2589 - cr0&=~8; 1.2590 - cycles-=5; 1.2591 - break; 1.2592 - 1.2593 - case 8: /*INVD*/ 1.2594 - if (!is486) goto inv32; 1.2595 - cycles-=1000; 1.2596 - break; 1.2597 - case 9: /*WBINVD*/ 1.2598 - if (!is486) goto inv32; 1.2599 - cycles-=10000; 1.2600 - break; 1.2601 - 1.2602 - case 0x20: /*MOV reg32,CRx*/ 1.2603 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.2604 - { 1.2605 - pclog("Can't load from CRx\n"); 1.2606 - x86gpf(NULL,0); 1.2607 - break; 1.2608 - } 1.2609 - fetchea2(); 1.2610 - switch (reg) 1.2611 - { 1.2612 - case 0: 1.2613 - regs[rm].l=cr0;//&~2; 1.2614 - if (is486) regs[rm].l|=0x10; /*ET hardwired on 486*/ 1.2615 - break; 1.2616 - case 2: 1.2617 - regs[rm].l=cr2; 1.2618 - break; 1.2619 - case 3: 1.2620 - regs[rm].l=cr3; 1.2621 - break; 1.2622 - default: 1.2623 - pclog("Bad read of CR%i %i\n",rmdat&7,reg); 1.2624 - pc=oldpc; 1.2625 - x86illegal(); 1.2626 - break; 1.2627 - } 1.2628 - cycles-=6; 1.2629 - break; 1.2630 - case 0x21: /*MOV reg32,DRx*/ 1.2631 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.2632 - { 1.2633 - pclog("Can't load from DRx\n"); 1.2634 - x86gpf(NULL,0); 1.2635 - break; 1.2636 - } 1.2637 - fetchea2(); 1.2638 - regs[rm].l=0; 1.2639 - cycles-=6; 1.2640 - break; 1.2641 - case 0x22: /*MOV CRx,reg32*/ 1.2642 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.2643 - { 1.2644 - pclog("Can't load CRx\n"); 1.2645 - x86gpf(NULL,0); 1.2646 - break; 1.2647 - } 1.2648 - fetchea2(); 1.2649 - switch (reg) 1.2650 - { 1.2651 - case 0: 1.2652 - //if ((cr0^regs[rm].l)>>31) flushmmucache(); 1.2653 - if ((regs[rm].l^cr0) & 0x80000001) flushmmucache(); 1.2654 - cr0=regs[rm].l;//&~2; 1.2655 - if (cpu_16bitbus) cr0 |= 0x10; 1.2656 -// if (cs<0xF0000 && cr0&1) output=3; 1.2657 - if (cr0&0x80000000) 1.2658 - { 1.2659 - } 1.2660 - else mmu_perm=4; 1.2661 - break; 1.2662 - case 2: 1.2663 - cr2=regs[rm].l; 1.2664 - break; 1.2665 - case 3: 1.2666 - cr3=regs[rm].l&~0xFFF; 1.2667 -// pclog("Loading CR3 with %08X at %08X:%08X\n",cr3,cs,pc); 1.2668 - flushmmucache(); 1.2669 - break; 1.2670 - default: 1.2671 - pclog("Bad load CR%i\n",reg); 1.2672 - pc=oldpc; 1.2673 - x86illegal(); 1.2674 - break; 1.2675 - } 1.2676 - cycles-=10; 1.2677 - break; 1.2678 - case 0x23: /*MOV DRx,reg32*/ 1.2679 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.2680 - { 1.2681 - pclog("Can't load DRx\n"); 1.2682 - x86gpf(NULL,0); 1.2683 - break; 1.2684 - } 1.2685 - fetchea2(); 1.2686 - cycles-=6; 1.2687 - break; 1.2688 - case 0x24: /*MOV reg32,TRx*/ 1.2689 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.2690 - { 1.2691 - pclog("Can't load from TRx\n"); 1.2692 - x86gpf(NULL,0); 1.2693 - break; 1.2694 - } 1.2695 - fetchea2(); 1.2696 - regs[rm].l=0; 1.2697 - cycles-=6; 1.2698 - break; 1.2699 - case 0x26: /*MOV TRx,reg32*/ 1.2700 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.2701 - { 1.2702 - pclog("Can't load TRx\n"); 1.2703 - x86gpf(NULL,0); 1.2704 - break; 1.2705 - } 1.2706 - fetchea2(); 1.2707 - cycles-=6; 1.2708 - break; 1.2709 - 1.2710 - case 0x80: /*JO*/ 1.2711 - templ=getlong(); if (abrt) break; 1.2712 - if (flags&V_FLAG) { pc+=templ; cycles-=((is486)?2:4); } 1.2713 - cycles-=((is486)?1:3); 1.2714 - break; 1.2715 - case 0x81: /*JNO*/ 1.2716 - templ=getlong(); if (abrt) break; 1.2717 - if (!(flags&V_FLAG)) { pc+=templ; cycles-=((is486)?2:4); } 1.2718 - cycles-=((is486)?1:3); 1.2719 - break; 1.2720 - case 0x82: /*JB*/ 1.2721 - templ=getlong(); if (abrt) break; 1.2722 - if (flags&C_FLAG) { pc+=templ; cycles-=((is486)?2:4); } 1.2723 - cycles-=((is486)?1:3); 1.2724 - break; 1.2725 - case 0x83: /*JNB*/ 1.2726 - templ=getlong(); if (abrt) break; 1.2727 - if (!(flags&C_FLAG)) { pc+=templ; cycles-=((is486)?2:4); } 1.2728 - cycles-=((is486)?1:3); 1.2729 - break; 1.2730 - case 0x84: /*JE*/ 1.2731 - templ=getlong(); if (abrt) break; 1.2732 - if (flags&Z_FLAG) pc+=templ; 1.2733 - cycles-=4; 1.2734 - break; 1.2735 - case 0x85: /*JNE*/ 1.2736 - templ=getlong(); if (abrt) break; 1.2737 - if (!(flags&Z_FLAG)) pc+=templ; 1.2738 - cycles-=4; 1.2739 - break; 1.2740 - case 0x86: /*JBE*/ 1.2741 - templ=getlong(); if (abrt) break; 1.2742 - if (flags&(C_FLAG|Z_FLAG)) { pc+=templ; cycles-=((is486)?2:4); } 1.2743 - cycles-=((is486)?1:3); 1.2744 - break; 1.2745 - case 0x87: /*JNBE*/ 1.2746 - templ=getlong(); if (abrt) break; 1.2747 - if (!(flags&(C_FLAG|Z_FLAG))) { pc+=templ; cycles-=((is486)?2:4); } 1.2748 - cycles-=((is486)?1:3); 1.2749 - break; 1.2750 - case 0x88: /*JS*/ 1.2751 - templ=getlong(); if (abrt) break; 1.2752 - if (flags&N_FLAG) pc+=templ; 1.2753 - cycles-=4; 1.2754 - break; 1.2755 - case 0x89: /*JNS*/ 1.2756 - templ=getlong(); if (abrt) break; 1.2757 - if (!(flags&N_FLAG)) pc+=templ; 1.2758 - cycles-=4; 1.2759 - break; 1.2760 - case 0x8A: /*JP*/ 1.2761 - templ=getlong(); if (abrt) break; 1.2762 - if (flags&P_FLAG) pc+=templ; 1.2763 - cycles-=4; 1.2764 - break; 1.2765 - case 0x8B: /*JNP*/ 1.2766 - templ=getlong(); if (abrt) break; 1.2767 - if (!(flags&P_FLAG)) pc+=templ; 1.2768 - cycles-=4; 1.2769 - break; 1.2770 - case 0x8C: /*JL*/ 1.2771 - templ=getlong(); if (abrt) break; 1.2772 - temp=(flags&N_FLAG)?1:0; 1.2773 - temp2=(flags&V_FLAG)?1:0; 1.2774 - if (temp!=temp2) { pc+=templ; cycles-=((is486)?2:4); } 1.2775 - cycles-=((is486)?1:3); 1.2776 - break; 1.2777 - case 0x8D: /*JNL*/ 1.2778 - templ=getlong(); if (abrt) break; 1.2779 - temp=(flags&N_FLAG)?1:0; 1.2780 - temp2=(flags&V_FLAG)?1:0; 1.2781 - if (temp==temp2) { pc+=templ; cycles-=((is486)?2:4); } 1.2782 - cycles-=((is486)?1:3); 1.2783 - break; 1.2784 - case 0x8E: /*JLE*/ 1.2785 - templ=getlong(); if (abrt) break; 1.2786 - temp=(flags&N_FLAG)?1:0; 1.2787 - temp2=(flags&V_FLAG)?1:0; 1.2788 - if ((flags&Z_FLAG) || (temp!=temp2)) { pc+=templ; cycles-=((is486)?2:4); } 1.2789 - cycles-=((is486)?1:3); 1.2790 - break; 1.2791 - case 0x8F: /*JNLE*/ 1.2792 - templ=getlong(); if (abrt) break; 1.2793 - temp=(flags&N_FLAG)?1:0; 1.2794 - temp2=(flags&V_FLAG)?1:0; 1.2795 - if (!((flags&Z_FLAG) || (temp!=temp2))) { pc+=templ; cycles-=((is486)?2:4); } 1.2796 - cycles-=((is486)?1:3); 1.2797 - break; 1.2798 - 1.2799 - case 0x90: /*SETO*/ 1.2800 - fetchea2(); 1.2801 - seteab((flags&V_FLAG)?1:0); 1.2802 - cycles-=4; 1.2803 - break; 1.2804 - case 0x91: /*SETNO*/ 1.2805 - fetchea2(); 1.2806 - seteab((flags&V_FLAG)?0:1); 1.2807 - cycles-=4; 1.2808 - break; 1.2809 - case 0x92: /*SETC*/ 1.2810 - fetchea2(); 1.2811 - seteab((flags&C_FLAG)?1:0); 1.2812 - cycles-=4; 1.2813 - break; 1.2814 - case 0x93: /*SETAE*/ 1.2815 - fetchea2(); 1.2816 - seteab((flags&C_FLAG)?0:1); 1.2817 - cycles-=4; 1.2818 - break; 1.2819 - case 0x94: /*SETZ*/ 1.2820 - fetchea2(); 1.2821 - seteab((flags&Z_FLAG)?1:0); 1.2822 - cycles-=4; 1.2823 - break; 1.2824 - case 0x95: /*SETNZ*/ 1.2825 - fetchea2(); 1.2826 - seteab((flags&Z_FLAG)?0:1); 1.2827 - cycles-=4; 1.2828 - break; 1.2829 - case 0x96: /*SETBE*/ 1.2830 - fetchea2(); 1.2831 - seteab((flags&(C_FLAG|Z_FLAG))?1:0); 1.2832 - cycles-=4; 1.2833 - break; 1.2834 - case 0x97: /*SETNBE*/ 1.2835 - fetchea2(); 1.2836 - seteab((flags&(C_FLAG|Z_FLAG))?0:1); 1.2837 - cycles-=4; 1.2838 - break; 1.2839 - case 0x98: /*SETS*/ 1.2840 - fetchea2(); 1.2841 - seteab((flags&N_FLAG)?1:0); 1.2842 - cycles-=4; 1.2843 - break; 1.2844 - case 0x99: /*SETNS*/ 1.2845 - fetchea2(); 1.2846 - seteab((flags&N_FLAG)?0:1); 1.2847 - cycles-=4; 1.2848 - break; 1.2849 - case 0x9A: /*SETP*/ 1.2850 - fetchea2(); 1.2851 - seteab((flags&P_FLAG)?1:0); 1.2852 - cycles-=4; 1.2853 - break; 1.2854 - case 0x9B: /*SETNP*/ 1.2855 - fetchea2(); 1.2856 - seteab((flags&P_FLAG)?0:1); 1.2857 - cycles-=4; 1.2858 - break; 1.2859 - case 0x9C: /*SETL*/ 1.2860 - fetchea2(); 1.2861 - temp=(flags&N_FLAG)?1:0; 1.2862 - temp2=(flags&V_FLAG)?1:0; 1.2863 - seteab(temp^temp2); 1.2864 - cycles-=4; 1.2865 - break; 1.2866 - case 0x9D: /*SETGE*/ 1.2867 - fetchea2(); 1.2868 - temp=(flags&N_FLAG)?1:0; 1.2869 - temp2=(flags&V_FLAG)?1:0; 1.2870 - seteab((temp^temp2)?0:1); 1.2871 - cycles-=4; 1.2872 - break; 1.2873 - case 0x9E: /*SETLE*/ 1.2874 - fetchea2(); 1.2875 - temp=(flags&N_FLAG)?1:0; 1.2876 - temp2=(flags&V_FLAG)?1:0; 1.2877 - seteab(((temp^temp2) || (flags&Z_FLAG))?1:0); 1.2878 - cycles-=4; 1.2879 - break; 1.2880 - case 0x9F: /*SETNLE*/ 1.2881 - fetchea2(); 1.2882 - temp=(flags&N_FLAG)?1:0; 1.2883 - temp2=(flags&V_FLAG)?1:0; 1.2884 - seteab(((temp^temp2) || (flags&Z_FLAG))?0:1); 1.2885 - cycles-=4; 1.2886 - break; 1.2887 - 1.2888 - case 0xA0: /*PUSH FS*/ 1.2889 - if (ssegs) ss=oldss; 1.2890 - if (stack32) 1.2891 - { 1.2892 - writememl(ss,ESP-4,FS); if (abrt) break; 1.2893 - ESP-=4; 1.2894 - } 1.2895 - else 1.2896 - { 1.2897 - writememl(ss,((SP-4)&0xFFFF),FS); if (abrt) break; 1.2898 - SP-=4; 1.2899 - } 1.2900 - cycles-=2; 1.2901 - break; 1.2902 - case 0xA1: /*POP FS*/ 1.2903 - if (ssegs) ss=oldss; 1.2904 - if (stack32) 1.2905 - { 1.2906 - tempw=readmemw(ss,ESP); if (abrt) break; 1.2907 - loadseg(tempw,&_fs); if (abrt) break; 1.2908 - ESP+=4; 1.2909 - } 1.2910 - else 1.2911 - { 1.2912 - tempw=readmemw(ss,SP); if (abrt) break; 1.2913 - loadseg(tempw,&_fs); if (abrt) break; 1.2914 - SP+=4; 1.2915 - } 1.2916 - cycles-=(is486)?3:7; 1.2917 - break; 1.2918 - case 0xA8: /*PUSH GS*/ 1.2919 - if (ssegs) ss=oldss; 1.2920 - if (stack32) 1.2921 - { 1.2922 - writememl(ss,ESP-4,GS); if (abrt) break; 1.2923 - ESP-=4; 1.2924 - } 1.2925 - else 1.2926 - { 1.2927 - writememl(ss,((SP-4)&0xFFFF),GS); if (abrt) break; 1.2928 - SP-=4; 1.2929 - } 1.2930 - cycles-=2; 1.2931 - break; 1.2932 - case 0xA9: /*POP GS*/ 1.2933 - if (ssegs) ss=oldss; 1.2934 - if (stack32) 1.2935 - { 1.2936 - tempw=readmemw(ss,ESP); if (abrt) break; 1.2937 - loadseg(tempw,&_gs); if (abrt) break; 1.2938 - ESP+=4; 1.2939 - } 1.2940 - else 1.2941 - { 1.2942 - tempw=readmemw(ss,SP); if (abrt) break; 1.2943 - loadseg(tempw,&_gs); if (abrt) break; 1.2944 - SP+=4; 1.2945 - } 1.2946 - cycles-=(is486)?3:7; 1.2947 - break; 1.2948 - 1.2949 - case 0xA3: /*BT r32*/ 1.2950 - fetchea2(); 1.2951 - eaaddr+=((regs[reg].l/32)*4); eal_r = 0; 1.2952 - templ=geteal(); if (abrt) break; 1.2953 - if (templ&(1<<(regs[reg].l&31))) flags|=C_FLAG; 1.2954 - else flags&=~C_FLAG; 1.2955 - cycles-=3; 1.2956 - break; 1.2957 - case 0xA4: /*SHLD imm*/ 1.2958 - fetchea2(); 1.2959 - temp=readmemb(cs,pc)&31; pc++; 1.2960 - if (temp) 1.2961 - { 1.2962 - templ=geteal(); if (abrt) break; 1.2963 - tempc=((templ<<(temp-1))&0x80000000)?1:0; 1.2964 - templ=(templ<<temp)|(regs[reg].l>>(32-temp)); 1.2965 - seteal(templ); if (abrt) break; 1.2966 - setznp32(templ); 1.2967 - if (tempc) flags|=C_FLAG; 1.2968 - } 1.2969 - cycles-=3; 1.2970 - break; 1.2971 - case 0xA5: /*SHLD CL*/ 1.2972 - fetchea2(); 1.2973 - temp=CL&31; 1.2974 - if (temp) 1.2975 - { 1.2976 - templ=geteal(); if (abrt) break; 1.2977 - tempc=((templ<<(temp-1))&0x80000000)?1:0; 1.2978 - templ=(templ<<temp)|(regs[reg].l>>(32-temp)); 1.2979 - seteal(templ); if (abrt) break; 1.2980 - setznp32(templ); 1.2981 - if (tempc) flags|=C_FLAG; 1.2982 - } 1.2983 - cycles-=3; 1.2984 - break; 1.2985 - case 0xAB: /*BTS r32*/ 1.2986 - fetchea2(); 1.2987 - eaaddr+=((regs[reg].l/32)*4); eal_r = eal_w = 0; 1.2988 - templ=geteal(); if (abrt) break; 1.2989 - tempc=(templ&(1<<(regs[reg].l&31)))?1:0; 1.2990 - templ|=(1<<(regs[reg].l&31)); 1.2991 - seteal(templ); if (abrt) break; 1.2992 - if (tempc) flags|=C_FLAG; 1.2993 - else flags&=~C_FLAG; 1.2994 - cycles-=6; 1.2995 - break; 1.2996 - case 0xAC: /*SHRD imm*/ 1.2997 - fetchea2(); 1.2998 - temp=readmemb(cs,pc)&31; pc++; 1.2999 - if (temp) 1.3000 - { 1.3001 - templ=geteal(); if (abrt) break; 1.3002 - tempc=(templ>>(temp-1))&1; 1.3003 - templ=(templ>>temp)|(regs[reg].l<<(32-temp)); 1.3004 - seteal(templ); if (abrt) break; 1.3005 - setznp32(templ); 1.3006 - if (tempc) flags|=C_FLAG; 1.3007 - } 1.3008 - cycles-=3; 1.3009 - break; 1.3010 - case 0xAD: /*SHRD CL*/ 1.3011 - fetchea2(); 1.3012 - temp=CL&31; 1.3013 - if (temp) 1.3014 - { 1.3015 - templ=geteal(); if (abrt) break; 1.3016 - tempc=(templ>>(temp-1))&1; 1.3017 - templ=(templ>>temp)|(regs[reg].l<<(32-temp)); 1.3018 - seteal(templ); if (abrt) break; 1.3019 - setznp32(templ); 1.3020 - if (tempc) flags|=C_FLAG; 1.3021 - } 1.3022 - cycles-=3; 1.3023 - break; 1.3024 - 1.3025 - case 0xAF: /*IMUL reg32,rm32*/ 1.3026 - fetchea2(); 1.3027 - temp64=(int64_t)(int32_t)regs[reg].l*(int64_t)(int32_t)geteal(); 1.3028 - if (abrt) break; 1.3029 - regs[reg].l=temp64&0xFFFFFFFF; 1.3030 - if ((temp64>>32) && (temp64>>32)!=0xFFFFFFFF) flags|=C_FLAG|V_FLAG; 1.3031 - else flags&=~(C_FLAG|V_FLAG); 1.3032 - cycles-=30; 1.3033 - break; 1.3034 - 1.3035 - case 0xB0: /*CMPXCHG rm8, reg8*/ 1.3036 - if (!is486) goto inv32; 1.3037 - fetchea2(); 1.3038 - temp = geteab(); 1.3039 - setsub8(AL, temp); 1.3040 - if (AL == temp) seteab(getr8(reg)); 1.3041 - else AL = temp; 1.3042 - cycles -= (mod == 3) ? 6 : 10; 1.3043 - break; 1.3044 - case 0xB1: /*CMPXCHG rm32, reg32*/ 1.3045 - if (!is486) goto inv32; 1.3046 - fetchea2(); 1.3047 - templ = geteal(); 1.3048 - setsub32(EAX, templ); 1.3049 - if (EAX == templ) seteal(regs[reg].l); 1.3050 - else EAX = templ; 1.3051 - cycles -= (mod == 3) ? 6 : 10; 1.3052 - break; 1.3053 - 1.3054 - case 0xB3: /*BTR r32*/ 1.3055 - fetchea2(); 1.3056 - eaaddr+=((regs[reg].l/32)*4); eal_r = eal_w = 0; 1.3057 - templ=geteal(); if (abrt) break; 1.3058 - tempc=(templ&(1<<(regs[reg].l&31)))?1:0; 1.3059 - templ&=~(1<<(regs[reg].l&31)); 1.3060 - seteal(templ); if (abrt) break; 1.3061 - if (tempc) flags|=C_FLAG; 1.3062 - else flags&=~C_FLAG; 1.3063 - cycles-=6; 1.3064 - break; 1.3065 - 1.3066 - case 0xB2: /*LSS*/ 1.3067 - fetchea2(); 1.3068 - templ=readmeml(easeg,eaaddr); 1.3069 - tempw=readmemw(easeg,(eaaddr+4)); if (abrt) break; 1.3070 - loadseg(tempw,&_ss); if (abrt) break; 1.3071 - regs[reg].l=templ; 1.3072 - oldss=ss; 1.3073 - cycles-=7; 1.3074 - break; 1.3075 - case 0xB4: /*LFS*/ 1.3076 - fetchea2(); 1.3077 - templ=readmeml(easeg,eaaddr); 1.3078 - tempw=readmemw(easeg,(eaaddr+4)); if (abrt) break; 1.3079 - loadseg(tempw,&_fs); if (abrt) break; 1.3080 - regs[reg].l=templ; 1.3081 - cycles-=7; 1.3082 - break; 1.3083 - case 0xB5: /*LGS*/ 1.3084 - fetchea2(); 1.3085 - templ=readmeml(easeg,eaaddr); 1.3086 - tempw=readmemw(easeg,(eaaddr+4)); if (abrt) break; 1.3087 - loadseg(tempw,&_gs); if (abrt) break; 1.3088 - regs[reg].l=templ; 1.3089 - cycles-=7; 1.3090 - break; 1.3091 - 1.3092 - case 0xB6: /*MOVZX b*/ 1.3093 - fetchea2(); 1.3094 - templ=geteab(); if (abrt) break; 1.3095 - regs[reg].l=templ; 1.3096 - cycles-=3; 1.3097 - break; 1.3098 - case 0xB7: /*MOVZX w*/ 1.3099 - fetchea2(); 1.3100 - templ=geteaw(); if (abrt) break; 1.3101 - regs[reg].l=templ; 1.3102 - cycles-=3; 1.3103 -// if (pc==0x30B) output=1; 1.3104 - break; 1.3105 - 1.3106 - case 0xBA: /*MORE?!?!?!*/ 1.3107 - fetchea2(); 1.3108 - switch (rmdat&0x38) 1.3109 - { 1.3110 - case 0x20: /*BT l,imm*/ 1.3111 - templ=geteal(); 1.3112 - temp=readmemb(cs,pc); pc++; 1.3113 - if (abrt) break; 1.3114 - if (templ&(1<<temp)) flags|=C_FLAG; 1.3115 - else flags&=~C_FLAG; 1.3116 - cycles-=6; 1.3117 - break; 1.3118 - case 0x28: /*BTS l,imm*/ 1.3119 - templ=geteal(); 1.3120 - temp=readmemb(cs,pc); pc++; 1.3121 - if (abrt) break; 1.3122 - tempc=(templ&(1<<temp))?1:0; 1.3123 - templ|=(1<<temp); 1.3124 - seteal(templ); if (abrt) break; 1.3125 - if (tempc) flags|=C_FLAG; 1.3126 - else flags&=~C_FLAG; 1.3127 - cycles-=6; 1.3128 - break; 1.3129 - case 0x30: /*BTR l,imm*/ 1.3130 - templ=geteal(); 1.3131 - temp=readmemb(cs,pc); pc++; 1.3132 - if (abrt) break; 1.3133 - tempc=(templ&(1<<temp))?1:0; 1.3134 - templ&=~(1<<temp); 1.3135 - seteal(templ); if (abrt) break; 1.3136 - if (tempc) flags|=C_FLAG; 1.3137 - else flags&=~C_FLAG; 1.3138 - cycles-=6; 1.3139 - break; 1.3140 - case 0x38: /*BTC l,imm*/ 1.3141 - templ=geteal(); 1.3142 - temp=readmemb(cs,pc); pc++; 1.3143 - if (abrt) break; 1.3144 - tempc=(templ&(1<<temp))?1:0; 1.3145 - templ^=(1<<temp); 1.3146 - seteal(templ); if (abrt) break; 1.3147 - if (tempc) flags|=C_FLAG; 1.3148 - else flags&=~C_FLAG; 1.3149 - cycles-=6; 1.3150 - break; 1.3151 - 1.3152 - default: 1.3153 - pclog("Bad 32-bit 0F BA opcode %02X\n",rmdat&0x38); 1.3154 - pc=oldpc; 1.3155 - x86illegal(); 1.3156 - break; 1.3157 - } 1.3158 - break; 1.3159 - 1.3160 - case 0xBB: /*BTC r32*/ 1.3161 - fetchea2(); 1.3162 - eaaddr+=((regs[reg].l/32)*4); eal_r = eal_w = 0; 1.3163 - templ=geteal(); if (abrt) break; 1.3164 - tempc=(templ&(1<<(regs[reg].l&31)))?1:0; 1.3165 - templ^=(1<<(regs[reg].l&31)); 1.3166 - seteal(templ); if (abrt) break; 1.3167 - if (tempc) flags|=C_FLAG; 1.3168 - else flags&=~C_FLAG; 1.3169 - cycles-=6; 1.3170 - break; 1.3171 - 1.3172 - case 0xBC: /*BSF l*/ 1.3173 - fetchea2(); 1.3174 - templ=geteal(); if (abrt) break; 1.3175 - if (!templ) 1.3176 - { 1.3177 -// regs[reg].l=0; 1.3178 - flags|=Z_FLAG; 1.3179 - } 1.3180 - else 1.3181 - { 1.3182 - for (tempi=0;tempi<32;tempi++) 1.3183 - { 1.3184 - cycles -= (is486) ? 1 : 3; 1.3185 - if (templ&(1<<tempi)) 1.3186 - { 1.3187 - flags&=~Z_FLAG; 1.3188 - regs[reg].l=tempi; 1.3189 - break; 1.3190 - } 1.3191 - } 1.3192 - } 1.3193 - cycles-=(is486)?6:10; 1.3194 - break; 1.3195 - case 0xBD: /*BSR l*/ 1.3196 - fetchea2(); 1.3197 - templ=geteal(); if (abrt) break; 1.3198 - if (!templ) 1.3199 - { 1.3200 -// regs[reg].l=0; 1.3201 - flags|=Z_FLAG; 1.3202 - } 1.3203 - else 1.3204 - { 1.3205 - for (tempi=31;tempi>=0;tempi--) 1.3206 - { 1.3207 - cycles -= 3; 1.3208 - if (templ&(1<<tempi)) 1.3209 - { 1.3210 - flags&=~Z_FLAG; 1.3211 - regs[reg].l=tempi; 1.3212 - break; 1.3213 - } 1.3214 - } 1.3215 - } 1.3216 - cycles-=(is486)?6:10; 1.3217 - break; 1.3218 - 1.3219 - case 0xBE: /*MOVSX b*/ 1.3220 - fetchea2(); 1.3221 - templ=geteab(); if (abrt) break; 1.3222 - if (templ&0x80) templ|=0xFFFFFF00; 1.3223 - regs[reg].l=templ; 1.3224 - cycles-=3; 1.3225 - break; 1.3226 - case 0xBF: /*MOVSX w*/ 1.3227 - fetchea2(); 1.3228 - templ=geteaw(); if (abrt) break; 1.3229 - if (templ&0x8000) templ|=0xFFFF0000; 1.3230 - regs[reg].l=templ; 1.3231 - cycles-=3; 1.3232 - break; 1.3233 - 1.3234 - case 0xC0: /*XADD b*/ 1.3235 - pclog("XADDb 32\n"); 1.3236 - fetchea2(); 1.3237 - temp=geteab(); if (abrt) break; 1.3238 - seteab(temp+getr8(reg)); if (abrt) break; 1.3239 - setadd8(temp,getr8(reg)); 1.3240 - setr8(reg,temp); 1.3241 - break; 1.3242 - case 0xC1: /*XADD l*/ 1.3243 -// pclog("XADDl 32\n"); 1.3244 - fetchea2(); 1.3245 - templ=geteal(); if (abrt) break; 1.3246 - templ2=regs[reg].l; 1.3247 -// pclog("EAL %08X REG %08X\n",templ,templ2); 1.3248 - seteal(templ+templ2); if (abrt) break; 1.3249 - setadd32(templ,templ2); 1.3250 - regs[reg].l=templ; 1.3251 -// pclog("EAL %08X REG %08X\n",templ+templ2,regs[reg].l); 1.3252 - break; 1.3253 - 1.3254 - case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*BSWAP*/ 1.3255 - case 0xCC: case 0xCD: case 0xCE: case 0xCF: /*486!!!*/ 1.3256 - regs[temp&7].l = (regs[temp&7].l>>24)|((regs[temp&7].l>>8)&0xFF00)|((regs[temp&7].l<<8)&0xFF0000)|((regs[temp&7].l<<24)&0xFF000000); 1.3257 - cycles--; 1.3258 - break; 1.3259 - 1.3260 - case 0xA2: /*CPUID*/ 1.3261 - if (CPUID) 1.3262 - { 1.3263 - cpu_CPUID(); 1.3264 - cycles-=9; 1.3265 - break; 1.3266 - } 1.3267 - goto inv32; 1.3268 - 1.3269 - case 0xFF: 1.3270 - inv32: 1.3271 - pclog("INV32!\n"); 1.3272 - default: 1.3273 - pclog("Bad 32-bit 0F opcode %02X 386\n",temp); 1.3274 - pc=oldpc; 1.3275 - x86illegal(); 1.3276 - break; 1.3277 - } 1.3278 - break; 1.3279 - 1.3280 - case 0x10: case 0x110: case 0x210: case 0x310: /*ADC 8,reg*/ 1.3281 - fetchea(); 1.3282 - if (mod == 3) 1.3283 - { 1.3284 - temp = getr8(rm); 1.3285 - temp2 = getr8(reg); 1.3286 - setadc8(temp, temp2); 1.3287 - setr8(rm, temp + temp2 + tempc); 1.3288 - cycles -= timing_rr; 1.3289 - } 1.3290 - else 1.3291 - { 1.3292 - temp = geteab(); if (abrt) break; 1.3293 - temp2 = getr8(reg); 1.3294 - seteab(temp + temp2 + tempc); if (abrt) break; 1.3295 - setadc8(temp, temp2); 1.3296 - cycles -= timing_mr; 1.3297 - } 1.3298 - break; 1.3299 - case 0x11: case 0x211: /*ADC 16,reg*/ 1.3300 - fetchea(); 1.3301 - if (mod == 3) 1.3302 - { 1.3303 - setadc16(regs[rm].w, regs[reg].w); 1.3304 - regs[rm].w += regs[reg].w + tempc; 1.3305 - cycles -= timing_rr; 1.3306 - } 1.3307 - else 1.3308 - { 1.3309 - tempw = geteaw(); if (abrt) break; 1.3310 - tempw2 = regs[reg].w; 1.3311 - seteaw(tempw + tempw2 + tempc); if (abrt) break; 1.3312 - setadc16(tempw, tempw2); 1.3313 - cycles -= timing_mr; 1.3314 - } 1.3315 - break; 1.3316 - case 0x111: case 0x311: /*ADC 32,reg*/ 1.3317 - fetchea(); 1.3318 - if (mod == 3) 1.3319 - { 1.3320 - setadc32(regs[rm].l, regs[reg].l); 1.3321 - regs[rm].l += regs[reg].l + tempc; 1.3322 - cycles -= timing_rr; 1.3323 - } 1.3324 - else 1.3325 - { 1.3326 - templ = geteal(); if (abrt) break; 1.3327 - templ2 = regs[reg].l; 1.3328 - seteal(templ + templ2 + tempc); if (abrt) break; 1.3329 - setadc32(templ, templ2); 1.3330 - cycles -= timing_mrl; 1.3331 - } 1.3332 - break; 1.3333 - case 0x12: case 0x112: case 0x212: case 0x312: /*ADC reg,8*/ 1.3334 - fetchea(); 1.3335 - temp=geteab(); if (abrt) break; 1.3336 - setadc8(getr8(reg),temp); 1.3337 - setr8(reg,getr8(reg)+temp+tempc); 1.3338 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3339 - break; 1.3340 - case 0x13: case 0x213: /*ADC reg,16*/ 1.3341 - fetchea(); 1.3342 - tempw=geteaw(); if (abrt) break; 1.3343 - setadc16(regs[reg].w,tempw); 1.3344 - regs[reg].w+=tempw+tempc; 1.3345 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3346 - break; 1.3347 - case 0x113: case 0x313: /*ADC reg,32*/ 1.3348 - fetchea(); 1.3349 - templ=geteal(); if (abrt) break; 1.3350 - setadc32(regs[reg].l,templ); 1.3351 - regs[reg].l+=templ+tempc; 1.3352 - cycles -= (mod == 3) ? timing_rr : timing_rml; 1.3353 - break; 1.3354 - case 0x14: case 0x114: case 0x214: case 0x314: /*ADC AL,#8*/ 1.3355 - tempw=getbytef(); 1.3356 - setadc8(AL,tempw); 1.3357 - AL+=tempw+tempc; 1.3358 - cycles -= timing_rr; 1.3359 - break; 1.3360 - case 0x15: case 0x215: /*ADC AX,#16*/ 1.3361 - tempw=getwordf(); 1.3362 - setadc16(AX,tempw); 1.3363 - AX+=tempw+tempc; 1.3364 - cycles -= timing_rr; 1.3365 - break; 1.3366 - case 0x115: case 0x315: /*ADC EAX,#32*/ 1.3367 - templ=getlong(); if (abrt) break; 1.3368 - setadc32(EAX,templ); 1.3369 - EAX+=templ+tempc; 1.3370 - cycles -= timing_rr; 1.3371 - break; 1.3372 - 1.3373 - case 0x16: case 0x216: /*PUSH SS*/ 1.3374 - if (ssegs) ss=oldss; 1.3375 - if (stack32) 1.3376 - { 1.3377 - writememw(ss,ESP-2,SS); if (abrt) break; 1.3378 - ESP-=2; 1.3379 - } 1.3380 - else 1.3381 - { 1.3382 - writememw(ss,((SP-2)&0xFFFF),SS); if (abrt) break; 1.3383 - SP-=2; 1.3384 - } 1.3385 - cycles-=2; 1.3386 - break; 1.3387 - case 0x116: case 0x316: /*PUSH SS*/ 1.3388 - if (ssegs) ss=oldss; 1.3389 - if (stack32) 1.3390 - { 1.3391 - writememl(ss,ESP-4,SS); if (abrt) break; 1.3392 - ESP-=4; 1.3393 - } 1.3394 - else 1.3395 - { 1.3396 - writememl(ss,((SP-4)&0xFFFF),SS); if (abrt) break; 1.3397 - SP-=4; 1.3398 - } 1.3399 - cycles-=2; 1.3400 - break; 1.3401 - case 0x17: case 0x217: /*POP SS*/ 1.3402 - if (ssegs) ss=oldss; 1.3403 - if (stack32) 1.3404 - { 1.3405 - tempw=readmemw(ss,ESP); if (abrt) break; 1.3406 - loadseg(tempw,&_ss); if (abrt) break; 1.3407 - ESP+=2; 1.3408 - } 1.3409 - else 1.3410 - { 1.3411 - tempw=readmemw(ss,SP); if (abrt) break; 1.3412 - loadseg(tempw,&_ss); if (abrt) break; 1.3413 - SP+=2; 1.3414 - } 1.3415 - cycles-=(is486)?3:7; 1.3416 - break; 1.3417 - case 0x117: case 0x317: /*POP SS*/ 1.3418 - if (ssegs) ss=oldss; 1.3419 - if (stack32) 1.3420 - { 1.3421 - tempw=readmemw(ss,ESP); if (abrt) break; 1.3422 - loadseg(tempw,&_ss); if (abrt) break; 1.3423 - ESP+=4; 1.3424 - } 1.3425 - else 1.3426 - { 1.3427 - tempw=readmemw(ss,SP); if (abrt) break; 1.3428 - loadseg(tempw,&_ss); if (abrt) break; 1.3429 - SP+=4; 1.3430 - } 1.3431 - cycles-=(is486)?3:7; 1.3432 - break; 1.3433 - 1.3434 - case 0x18: case 0x118: case 0x218: case 0x318: /*SBB 8,reg*/ 1.3435 - fetchea(); 1.3436 - if (mod == 3) 1.3437 - { 1.3438 - temp = getr8(rm); 1.3439 - temp2 = getr8(reg); 1.3440 - setsbc8(temp, temp2); 1.3441 - setr8(rm, temp - (temp2 + tempc)); 1.3442 - cycles -= timing_rr; 1.3443 - } 1.3444 - else 1.3445 - { 1.3446 - temp = geteab(); if (abrt) break; 1.3447 - temp2 = getr8(reg); 1.3448 - seteab(temp - (temp2 + tempc)); if (abrt) break; 1.3449 - setsbc8(temp, temp2); 1.3450 - cycles -= timing_mr; 1.3451 - } 1.3452 - break; 1.3453 - case 0x19: case 0x219: /*SBB 16,reg*/ 1.3454 - fetchea(); 1.3455 - if (mod == 3) 1.3456 - { 1.3457 - setsbc16(regs[rm].w, regs[reg].w); 1.3458 - regs[rm].w -= (regs[reg].w + tempc); 1.3459 - cycles -= timing_rr; 1.3460 - } 1.3461 - else 1.3462 - { 1.3463 - tempw = geteaw(); if (abrt) break; 1.3464 - tempw2 = regs[reg].w; 1.3465 - seteaw(tempw - (tempw2 + tempc)); if (abrt) break; 1.3466 - setsbc16(tempw, tempw2); 1.3467 - cycles -= timing_mr; 1.3468 - } 1.3469 - break; 1.3470 - case 0x119: case 0x319: /*SBB 32,reg*/ 1.3471 - fetchea(); 1.3472 - if (mod == 3) 1.3473 - { 1.3474 - setsbc32(regs[rm].l, regs[reg].l); 1.3475 - regs[rm].l -= (regs[reg].l + tempc); 1.3476 - cycles -= timing_rr; 1.3477 - } 1.3478 - else 1.3479 - { 1.3480 - templ = geteal(); if (abrt) break; 1.3481 - templ2 = regs[reg].l; 1.3482 - seteal(templ - (templ2 + tempc)); if (abrt) break; 1.3483 - setsbc32(templ, templ2); 1.3484 - cycles -= timing_mrl; 1.3485 - } 1.3486 - break; 1.3487 - case 0x1A: case 0x11A: case 0x21A: case 0x31A: /*SBB reg,8*/ 1.3488 - fetchea(); 1.3489 - temp=geteab(); if (abrt) break; 1.3490 - setsbc8(getr8(reg),temp); 1.3491 - setr8(reg,getr8(reg)-(temp+tempc)); 1.3492 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3493 - break; 1.3494 - case 0x1B: case 0x21B: /*SBB reg,16*/ 1.3495 - fetchea(); 1.3496 - tempw=geteaw(); if (abrt) break; 1.3497 - tempw2=regs[reg].w; 1.3498 - setsbc16(tempw2,tempw); 1.3499 - tempw2-=(tempw+tempc); 1.3500 - regs[reg].w=tempw2; 1.3501 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3502 - break; 1.3503 - case 0x11B: case 0x31B: /*SBB reg,32*/ 1.3504 - fetchea(); 1.3505 - templ=geteal(); if (abrt) break; 1.3506 - templ2=regs[reg].l; 1.3507 - setsbc32(templ2,templ); 1.3508 - templ2-=(templ+tempc); 1.3509 - regs[reg].l=templ2; 1.3510 - cycles -= (mod == 3) ? timing_rr : timing_rml; 1.3511 - break; 1.3512 - case 0x1C: case 0x11C: case 0x21C: case 0x31C: /*SBB AL,#8*/ 1.3513 - temp=getbytef(); 1.3514 - setsbc8(AL,temp); 1.3515 - AL-=(temp+tempc); 1.3516 - cycles-=(is486)?1:2; 1.3517 - break; 1.3518 - case 0x1D: case 0x21D: /*SBB AX,#16*/ 1.3519 - tempw=getwordf(); 1.3520 - setsbc16(AX,tempw); 1.3521 - AX-=(tempw+tempc); 1.3522 - cycles-=(is486)?1:2; 1.3523 - break; 1.3524 - case 0x11D: case 0x31D: /*SBB AX,#32*/ 1.3525 - templ=getlong(); if (abrt) break; 1.3526 - setsbc32(EAX,templ); 1.3527 - EAX-=(templ+tempc); 1.3528 - cycles-=(is486)?1:2; 1.3529 - break; 1.3530 - 1.3531 - case 0x1E: case 0x21E: /*PUSH DS*/ 1.3532 - if (ssegs) ss=oldss; 1.3533 - if (stack32) 1.3534 - { 1.3535 - writememw(ss,ESP-2,DS); if (abrt) break; 1.3536 - ESP-=2; 1.3537 - } 1.3538 - else 1.3539 - { 1.3540 - writememw(ss,((SP-2)&0xFFFF),DS); if (abrt) break; 1.3541 - SP-=2; 1.3542 - } 1.3543 - cycles-=2; 1.3544 - break; 1.3545 - case 0x11E: case 0x31E: /*PUSH DS*/ 1.3546 - if (ssegs) ss=oldss; 1.3547 - if (stack32) 1.3548 - { 1.3549 - writememl(ss,ESP-4,DS); if (abrt) break; 1.3550 - ESP-=4; 1.3551 - } 1.3552 - else 1.3553 - { 1.3554 - writememl(ss,((SP-4)&0xFFFF),DS); if (abrt) break; 1.3555 - SP-=4; 1.3556 - } 1.3557 - cycles-=2; 1.3558 - break; 1.3559 - case 0x1F: case 0x21F: /*POP DS*/ 1.3560 - if (ssegs) ss=oldss; 1.3561 - if (stack32) 1.3562 - { 1.3563 - tempw=readmemw(ss,ESP); if (abrt) break; 1.3564 - loadseg(tempw,&_ds); if (abrt) break; 1.3565 - ESP+=2; 1.3566 - } 1.3567 - else 1.3568 - { 1.3569 - tempw=readmemw(ss,SP); if (abrt) break; 1.3570 - loadseg(tempw,&_ds); if (abrt) break; 1.3571 - SP+=2; 1.3572 - } 1.3573 - cycles-=(is486)?3:7; 1.3574 - break; 1.3575 - case 0x11F: case 0x31F: /*POP DS*/ 1.3576 - if (ssegs) ss=oldss; 1.3577 - if (stack32) 1.3578 - { 1.3579 - tempw=readmemw(ss,ESP); if (abrt) break; 1.3580 - loadseg(tempw,&_ds); if (abrt) break; 1.3581 - ESP+=4; 1.3582 - } 1.3583 - else 1.3584 - { 1.3585 - tempw=readmemw(ss,SP); if (abrt) break; 1.3586 - loadseg(tempw,&_ds); if (abrt) break; 1.3587 - SP+=4; 1.3588 - } 1.3589 - cycles-=(is486)?3:7; 1.3590 - break; 1.3591 - 1.3592 - case 0x20: case 0x120: case 0x220: case 0x320: /*AND 8,reg*/ 1.3593 - fetchea(); 1.3594 - if (mod == 3) 1.3595 - { 1.3596 - temp = getr8(rm) & getr8(reg); 1.3597 - setr8(rm, temp); 1.3598 - setznp8(temp); 1.3599 - cycles -= timing_rr; 1.3600 - } 1.3601 - else 1.3602 - { 1.3603 - temp = geteab(); if (abrt) break; 1.3604 - temp &= getr8(reg); 1.3605 - seteab(temp); if (abrt) break; 1.3606 - setznp8(temp); 1.3607 - cycles -= timing_mr; 1.3608 - } 1.3609 - break; 1.3610 - case 0x21: case 0x221: /*AND 16,reg*/ 1.3611 - fetchea(); 1.3612 - if (mod == 3) 1.3613 - { 1.3614 - regs[rm].w &= regs[reg].w; 1.3615 - setznp16(regs[rm].w); 1.3616 - cycles -= timing_rr; 1.3617 - } 1.3618 - else 1.3619 - { 1.3620 - tempw = geteaw() & regs[reg].w; if (abrt) break; 1.3621 - seteaw(tempw); if (abrt) break; 1.3622 - setznp16(tempw); 1.3623 - cycles -= timing_mr; 1.3624 - } 1.3625 - break; 1.3626 - case 0x121: case 0x321: /*AND 32,reg*/ 1.3627 - fetchea(); 1.3628 - if (mod == 3) 1.3629 - { 1.3630 - regs[rm].l &= regs[reg].l; 1.3631 - setznp32(regs[rm].l); 1.3632 - cycles -= timing_rr; 1.3633 - } 1.3634 - else 1.3635 - { 1.3636 - templ = geteal() & regs[reg].l; if (abrt) break; 1.3637 - seteal(templ); if (abrt) break; 1.3638 - setznp32(templ); 1.3639 - cycles -= timing_mrl; 1.3640 - } 1.3641 - break; 1.3642 - case 0x22: case 0x122: case 0x222: case 0x322: /*AND reg,8*/ 1.3643 - fetchea(); 1.3644 - temp=geteab(); if (abrt) break; 1.3645 - temp&=getr8(reg); 1.3646 - setznp8(temp); 1.3647 - setr8(reg,temp); 1.3648 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3649 - break; 1.3650 - case 0x23: case 0x223: /*AND reg,16*/ 1.3651 - fetchea(); 1.3652 - tempw=geteaw(); if (abrt) break; 1.3653 - tempw&=regs[reg].w; 1.3654 - setznp16(tempw); 1.3655 - regs[reg].w=tempw; 1.3656 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3657 - break; 1.3658 - case 0x123: case 0x323: /*AND reg,32*/ 1.3659 - fetchea(); 1.3660 - templ=geteal(); if (abrt) break; 1.3661 - templ&=regs[reg].l; 1.3662 - setznp32(templ); 1.3663 - regs[reg].l=templ; 1.3664 - cycles -= (mod == 3) ? timing_rr : timing_rml; 1.3665 - break; 1.3666 - case 0x24: case 0x124: case 0x224: case 0x324: /*AND AL,#8*/ 1.3667 - AL&=getbytef(); 1.3668 - setznp8(AL); 1.3669 - cycles -= timing_rr; 1.3670 - break; 1.3671 - case 0x25: case 0x225: /*AND AX,#16*/ 1.3672 - AX&=getwordf(); 1.3673 - setznp16(AX); 1.3674 - cycles -= timing_rr; 1.3675 - break; 1.3676 - case 0x125: case 0x325: /*AND EAX,#32*/ 1.3677 - templ=getlong(); if (abrt) break; 1.3678 - EAX&=templ; 1.3679 - setznp32(EAX); 1.3680 - cycles -= timing_rr; 1.3681 - break; 1.3682 - 1.3683 - case 0x26: case 0x126: case 0x226: case 0x326: /*ES:*/ 1.3684 - oldss=ss; 1.3685 - oldds=ds; 1.3686 - ds=ss=es; 1.3687 - rds=ES; 1.3688 - ssegs=2; 1.3689 - cycles-=4; 1.3690 - goto opcodestart; 1.3691 -// break; 1.3692 - 1.3693 - case 0x27: case 0x127: case 0x227: case 0x327: /*DAA*/ 1.3694 - if ((flags & A_FLAG) || ((AL & 0xF) > 9)) 1.3695 - { 1.3696 - tempi = ((uint16_t)AL) + 6; 1.3697 - AL += 6; 1.3698 - flags |= A_FLAG; 1.3699 - if (tempi & 0x100) flags |= C_FLAG; 1.3700 - } 1.3701 -// else 1.3702 -// flags&=~A_FLAG; 1.3703 - if ((flags&C_FLAG) || (AL>0x9F)) 1.3704 - { 1.3705 - AL+=0x60; 1.3706 - flags|=C_FLAG; 1.3707 - } 1.3708 -// else 1.3709 -// flags&=~C_FLAG; 1.3710 - tempw = flags & (C_FLAG | A_FLAG); 1.3711 - setznp8(AL); 1.3712 - flags |= tempw; 1.3713 - cycles-=4; 1.3714 - break; 1.3715 - 1.3716 - case 0x28: case 0x128: case 0x228: case 0x328: /*SUB 8,reg*/ 1.3717 - fetchea(); 1.3718 - if (mod == 3) 1.3719 - { 1.3720 - temp = getr8(rm); 1.3721 - temp2 = getr8(reg); 1.3722 - setsub8(temp, temp2); 1.3723 - setr8(rm, temp - temp2); 1.3724 - cycles -= timing_rr; 1.3725 - } 1.3726 - else 1.3727 - { 1.3728 - temp = geteab(); if (abrt) break; 1.3729 - temp2 = getr8(reg); 1.3730 - seteab(temp - temp2); if (abrt) break; 1.3731 - setsub8(temp, temp2); 1.3732 - cycles -= timing_mr; 1.3733 - } 1.3734 - break; 1.3735 - case 0x29: case 0x229: /*SUB 16,reg*/ 1.3736 - fetchea(); 1.3737 - if (mod == 3) 1.3738 - { 1.3739 - setsub16(regs[rm].w, regs[reg].w); 1.3740 - regs[rm].w -= regs[reg].w; 1.3741 - cycles -= timing_rr; 1.3742 - } 1.3743 - else 1.3744 - { 1.3745 - tempw = geteaw(); if (abrt) break; 1.3746 - seteaw(tempw - regs[reg].w); if (abrt) break; 1.3747 - setsub16(tempw, regs[reg].w); 1.3748 - cycles -= timing_mr; 1.3749 - } 1.3750 - break; 1.3751 - case 0x129: case 0x329: /*SUB 32,reg*/ 1.3752 - fetchea(); 1.3753 - if (mod == 3) 1.3754 - { 1.3755 - setsub32(regs[rm].l, regs[reg].l); 1.3756 - regs[rm].l -= regs[reg].l; 1.3757 - cycles -= timing_rr; 1.3758 - } 1.3759 - else 1.3760 - { 1.3761 - templ = geteal(); if (abrt) break; 1.3762 - seteal(templ - regs[reg].l); if (abrt) break; 1.3763 - setsub32(templ, regs[reg].l); 1.3764 - cycles -= timing_mrl; 1.3765 - } 1.3766 - break; 1.3767 - case 0x2A: case 0x12A: case 0x22A: case 0x32A: /*SUB reg,8*/ 1.3768 - fetchea(); 1.3769 - temp=geteab(); if (abrt) break; 1.3770 - setsub8(getr8(reg),temp); 1.3771 - setr8(reg,getr8(reg)-temp); 1.3772 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3773 - break; 1.3774 - case 0x2B: case 0x22B: /*SUB reg,16*/ 1.3775 - fetchea(); 1.3776 - tempw=geteaw(); if (abrt) break; 1.3777 - setsub16(regs[reg].w,tempw); 1.3778 - regs[reg].w-=tempw; 1.3779 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3780 - break; 1.3781 - case 0x12B: case 0x32B: /*SUB reg,32*/ 1.3782 - fetchea(); 1.3783 - templ=geteal(); if (abrt) break; 1.3784 - setsub32(regs[reg].l,templ); 1.3785 - regs[reg].l-=templ; 1.3786 - cycles -= (mod == 3) ? timing_rr : timing_rml; 1.3787 - break; 1.3788 - case 0x2C: case 0x12C: case 0x22C: case 0x32C: /*SUB AL,#8*/ 1.3789 - temp=getbytef(); 1.3790 - setsub8(AL,temp); 1.3791 - AL-=temp; 1.3792 - cycles -= timing_rr; 1.3793 - break; 1.3794 - case 0x2D: case 0x22D: /*SUB AX,#16*/ 1.3795 - tempw=getwordf(); 1.3796 - setsub16(AX,tempw); 1.3797 - AX-=tempw; 1.3798 - cycles -= timing_rr; 1.3799 - break; 1.3800 - case 0x12D: case 0x32D: /*SUB EAX,#32*/ 1.3801 - templ=getlong(); if (abrt) break; 1.3802 - setsub32(EAX,templ); 1.3803 - EAX-=templ; 1.3804 - cycles -= timing_rr; 1.3805 - break; 1.3806 - 1.3807 - case 0x2E: case 0x12E: case 0x22E: case 0x32E: /*CS:*/ 1.3808 - oldss=ss; 1.3809 - oldds=ds; 1.3810 - ds=ss=cs; 1.3811 - rds=CS; 1.3812 - ssegs=2; 1.3813 - cycles-=4; 1.3814 - goto opcodestart; 1.3815 - case 0x2F: case 0x12F: case 0x22F: case 0x32F: /*DAS*/ 1.3816 - if ((flags&A_FLAG)||((AL&0xF)>9)) 1.3817 - { 1.3818 - tempi=((uint16_t)AL)-6; 1.3819 - AL-=6; 1.3820 - flags|=A_FLAG; 1.3821 - if (tempi&0x100) flags|=C_FLAG; 1.3822 - } 1.3823 -// else 1.3824 -// flags&=~A_FLAG; 1.3825 - if ((flags&C_FLAG)||(AL>0x9F)) 1.3826 - { 1.3827 - AL-=0x60; 1.3828 - flags|=C_FLAG; 1.3829 - } 1.3830 -// else 1.3831 -// flags&=~C_FLAG; 1.3832 - tempw = flags & (C_FLAG | A_FLAG); 1.3833 - setznp8(AL); 1.3834 - flags |= tempw; 1.3835 - cycles-=4; 1.3836 - break; 1.3837 - 1.3838 - case 0x30: case 0x130: case 0x230: case 0x330: /*XOR 8,reg*/ 1.3839 - fetchea(); 1.3840 - if (mod == 3) 1.3841 - { 1.3842 - temp = getr8(rm) ^ getr8(reg); 1.3843 - setr8(rm, temp); 1.3844 - setznp8(temp); 1.3845 - cycles -= timing_rr; 1.3846 - } 1.3847 - else 1.3848 - { 1.3849 - temp = geteab(); if (abrt) break; 1.3850 - temp ^= getr8(reg); 1.3851 - seteab(temp); if (abrt) break; 1.3852 - setznp8(temp); 1.3853 - cycles -= timing_mr; 1.3854 - } 1.3855 - break; 1.3856 - case 0x31: case 0x231: /*XOR 16,reg*/ 1.3857 - fetchea(); 1.3858 - if (mod == 3) 1.3859 - { 1.3860 - regs[rm].w ^= regs[reg].w; 1.3861 - setznp16(regs[rm].w); 1.3862 - cycles -= timing_rr; 1.3863 - } 1.3864 - else 1.3865 - { 1.3866 - tempw = geteaw() ^ regs[reg].w; if (abrt) break; 1.3867 - seteaw(tempw); if (abrt) break; 1.3868 - setznp16(tempw); 1.3869 - cycles -= timing_mr; 1.3870 - } 1.3871 - break; 1.3872 - case 0x131: case 0x331: /*XOR 32,reg*/ 1.3873 - fetchea(); 1.3874 - if (mod == 3) 1.3875 - { 1.3876 - regs[rm].l ^= regs[reg].l; 1.3877 - setznp32(regs[rm].l); 1.3878 - cycles -= timing_rr; 1.3879 - } 1.3880 - else 1.3881 - { 1.3882 - templ = geteal() ^ regs[reg].l; if (abrt) break; 1.3883 - seteal(templ); if (abrt) break; 1.3884 - setznp32(templ); 1.3885 - cycles -= timing_mrl; 1.3886 - } 1.3887 - break; 1.3888 - case 0x32: case 0x132: case 0x232: case 0x332: /*XOR reg,8*/ 1.3889 - fetchea(); 1.3890 - temp=geteab(); if (abrt) break; 1.3891 - temp^=getr8(reg); 1.3892 - setznp8(temp); 1.3893 - setr8(reg,temp); 1.3894 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3895 - break; 1.3896 - case 0x33: case 0x233: /*XOR reg,16*/ 1.3897 - fetchea(); 1.3898 - tempw=geteaw(); if (abrt) break; 1.3899 - tempw^=regs[reg].w; 1.3900 - setznp16(tempw); 1.3901 - regs[reg].w=tempw; 1.3902 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3903 - break; 1.3904 - case 0x133: case 0x333: /*XOR reg,32*/ 1.3905 - fetchea(); 1.3906 - templ=geteal(); if (abrt) break; 1.3907 - templ^=regs[reg].l; 1.3908 - setznp32(templ); 1.3909 - regs[reg].l=templ; 1.3910 - cycles -= (mod == 3) ? timing_rr : timing_rml; 1.3911 - break; 1.3912 - case 0x34: case 0x134: case 0x234: case 0x334: /*XOR AL,#8*/ 1.3913 - AL^=getbytef(); 1.3914 - setznp8(AL); 1.3915 - cycles -= timing_rr; 1.3916 - break; 1.3917 - case 0x35: case 0x235: /*XOR AX,#16*/ 1.3918 - AX^=getwordf(); 1.3919 - setznp16(AX); 1.3920 - cycles -= timing_rr; 1.3921 - break; 1.3922 - case 0x135: case 0x335: /*XOR EAX,#32*/ 1.3923 - templ=getlong(); if (abrt) break; 1.3924 - EAX^=templ; 1.3925 - setznp32(EAX); 1.3926 - cycles -= timing_rr; 1.3927 - break; 1.3928 - 1.3929 - case 0x36: case 0x136: case 0x236: case 0x336: /*SS:*/ 1.3930 - oldss=ss; 1.3931 - oldds=ds; 1.3932 - ds=ss=ss; 1.3933 - rds=SS; 1.3934 - ssegs=2; 1.3935 - cycles-=4; 1.3936 - goto opcodestart; 1.3937 -// break; 1.3938 - 1.3939 - case 0x37: case 0x137: case 0x237: case 0x337: /*AAA*/ 1.3940 - if ((flags&A_FLAG)||((AL&0xF)>9)) 1.3941 - { 1.3942 - AL+=6; 1.3943 - AH++; 1.3944 - flags|=(A_FLAG|C_FLAG); 1.3945 - } 1.3946 - else 1.3947 - flags&=~(A_FLAG|C_FLAG); 1.3948 - AL&=0xF; 1.3949 - cycles-=(is486)?3:4; 1.3950 - break; 1.3951 - 1.3952 - case 0x38: case 0x138: case 0x238: case 0x338: /*CMP 8,reg*/ 1.3953 - fetchea(); 1.3954 - temp=geteab(); if (abrt) break; 1.3955 - setsub8(temp,getr8(reg)); 1.3956 - if (is486) cycles-=((mod==3)?1:2); 1.3957 - else cycles-=((mod==3)?2:5); 1.3958 - break; 1.3959 - case 0x39: case 0x239: /*CMP 16,reg*/ 1.3960 - fetchea(); 1.3961 - tempw=geteaw(); if (abrt) break; 1.3962 -// if (output) pclog("CMP %04X %04X\n",tempw,regs[reg].w); 1.3963 - setsub16(tempw,regs[reg].w); 1.3964 - if (is486) cycles-=((mod==3)?1:2); 1.3965 - else cycles-=((mod==3)?2:5); 1.3966 - break; 1.3967 - case 0x139: case 0x339: /*CMP 32,reg*/ 1.3968 - fetchea(); 1.3969 - templ=geteal(); if (abrt) break; 1.3970 - setsub32(templ,regs[reg].l); 1.3971 - if (is486) cycles-=((mod==3)?1:2); 1.3972 - else cycles-=((mod==3)?2:5); 1.3973 - break; 1.3974 - case 0x3A: case 0x13A: case 0x23A: case 0x33A: /*CMP reg,8*/ 1.3975 - fetchea(); 1.3976 - temp=geteab(); if (abrt) break; 1.3977 -// if (output) pclog("CMP %02X-%02X\n",getr8(reg),temp); 1.3978 - setsub8(getr8(reg),temp); 1.3979 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3980 - break; 1.3981 - case 0x3B: case 0x23B: /*CMP reg,16*/ 1.3982 - fetchea(); 1.3983 - tempw=geteaw(); if (abrt) break; 1.3984 - setsub16(regs[reg].w,tempw); 1.3985 - cycles -= (mod == 3) ? timing_rr : timing_rm; 1.3986 - break; 1.3987 - case 0x13B: case 0x33B: /*CMP reg,32*/ 1.3988 - fetchea(); 1.3989 - templ=geteal(); if (abrt) break; 1.3990 - setsub32(regs[reg].l,templ); 1.3991 - cycles -= (mod == 3) ? timing_rr : timing_rml; 1.3992 - break; 1.3993 - case 0x3C: case 0x13C: case 0x23C: case 0x33C: /*CMP AL,#8*/ 1.3994 - temp=getbytef(); 1.3995 - setsub8(AL,temp); 1.3996 - cycles -= timing_rr; 1.3997 - break; 1.3998 - case 0x3D: case 0x23D: /*CMP AX,#16*/ 1.3999 - tempw=getwordf(); 1.4000 - setsub16(AX,tempw); 1.4001 - cycles -= timing_rr; 1.4002 - break; 1.4003 - case 0x13D: case 0x33D: /*CMP EAX,#32*/ 1.4004 - templ=getlong(); if (abrt) break; 1.4005 - setsub32(EAX,templ); 1.4006 - cycles -= timing_rr; 1.4007 - break; 1.4008 - 1.4009 - case 0x3E: case 0x13E: case 0x23E: case 0x33E: /*DS:*/ 1.4010 - oldss=ss; 1.4011 - oldds=ds; 1.4012 - ds=ss=ds; 1.4013 - ssegs=2; 1.4014 - cycles-=4; 1.4015 - goto opcodestart; 1.4016 -// break; 1.4017 - 1.4018 - case 0x3F: case 0x13F: case 0x23F: case 0x33F: /*AAS*/ 1.4019 - if ((flags&A_FLAG)||((AL&0xF)>9)) 1.4020 - { 1.4021 - AL-=6; 1.4022 - AH--; 1.4023 - flags|=(A_FLAG|C_FLAG); 1.4024 - } 1.4025 - else 1.4026 - flags&=~(A_FLAG|C_FLAG); 1.4027 - AL&=0xF; 1.4028 - cycles-=(is486)?3:4; 1.4029 - break; 1.4030 - 1.4031 - case 0x40: case 0x41: case 0x42: case 0x43: /*INC r16*/ 1.4032 - case 0x44: case 0x45: case 0x46: case 0x47: 1.4033 - case 0x240: case 0x241: case 0x242: case 0x243: 1.4034 - case 0x244: case 0x245: case 0x246: case 0x247: 1.4035 - setadd16nc(regs[opcode&7].w,1); 1.4036 - regs[opcode&7].w++; 1.4037 - cycles -= timing_rr; 1.4038 - break; 1.4039 - case 0x140: case 0x141: case 0x142: case 0x143: /*INC r32*/ 1.4040 - case 0x144: case 0x145: case 0x146: case 0x147: 1.4041 - case 0x340: case 0x341: case 0x342: case 0x343: 1.4042 - case 0x344: case 0x345: case 0x346: case 0x347: 1.4043 - setadd32nc(regs[opcode&7].l,1); 1.4044 - regs[opcode&7].l++; 1.4045 - cycles -= timing_rr; 1.4046 - break; 1.4047 - case 0x48: case 0x49: case 0x4A: case 0x4B: /*DEC r16*/ 1.4048 - case 0x4C: case 0x4D: case 0x4E: case 0x4F: 1.4049 - case 0x248: case 0x249: case 0x24A: case 0x24B: 1.4050 - case 0x24C: case 0x24D: case 0x24E: case 0x24F: 1.4051 - setsub16nc(regs[opcode&7].w,1); 1.4052 - regs[opcode&7].w--; 1.4053 - cycles -= timing_rr; 1.4054 - break; 1.4055 - case 0x148: case 0x149: case 0x14A: case 0x14B: /*DEC r32*/ 1.4056 - case 0x14C: case 0x14D: case 0x14E: case 0x14F: 1.4057 - case 0x348: case 0x349: case 0x34A: case 0x34B: 1.4058 - case 0x34C: case 0x34D: case 0x34E: case 0x34F: 1.4059 - setsub32nc(regs[opcode&7].l,1); 1.4060 - regs[opcode&7].l--; 1.4061 - cycles -= timing_rr; 1.4062 - break; 1.4063 - 1.4064 - case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/ 1.4065 - case 0x54: case 0x55: case 0x56: case 0x57: 1.4066 - case 0x250: case 0x251: case 0x252: case 0x253: 1.4067 - case 0x254: case 0x255: case 0x256: case 0x257: 1.4068 - if (ssegs) ss=oldss; 1.4069 - if (stack32) 1.4070 - { 1.4071 - writememw(ss,ESP-2,regs[opcode&7].w); if (abrt) break; 1.4072 - ESP-=2; 1.4073 - } 1.4074 - else 1.4075 - { 1.4076 - writememw(ss,(SP-2)&0xFFFF,regs[opcode&7].w); if (abrt) break; 1.4077 - SP-=2; 1.4078 - } 1.4079 -// if (pc>=0x1A1BED && pc<0x1A1C00) pclog("PUSH %02X! %08X\n",opcode,ESP); 1.4080 - cycles-=(is486)?1:2; 1.4081 - break; 1.4082 - case 0x150: case 0x151: case 0x152: case 0x153: /*PUSH r32*/ 1.4083 - case 0x154: case 0x155: case 0x156: case 0x157: 1.4084 - case 0x350: case 0x351: case 0x352: case 0x353: 1.4085 - case 0x354: case 0x355: case 0x356: case 0x357: 1.4086 - if (ssegs) ss=oldss; 1.4087 - if (stack32) 1.4088 - { 1.4089 - writememl(ss,ESP-4,regs[opcode&7].l); if (abrt) break; 1.4090 - ESP-=4; 1.4091 - } 1.4092 - else 1.4093 - { 1.4094 - writememl(ss,(SP-4)&0xFFFF,regs[opcode&7].l); if (abrt) break; 1.4095 - SP-=4; 1.4096 - } 1.4097 - cycles-=(is486)?1:2; 1.4098 - break; 1.4099 - case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/ 1.4100 - case 0x5C: case 0x5D: case 0x5E: case 0x5F: 1.4101 - case 0x258: case 0x259: case 0x25A: case 0x25B: 1.4102 - case 0x25C: case 0x25D: case 0x25E: case 0x25F: 1.4103 - if (ssegs) ss=oldss; 1.4104 - if (stack32) 1.4105 - { 1.4106 - ESP+=2; 1.4107 - tempw=readmemw(ss,ESP-2); if (abrt) { ESP-=2; break; } 1.4108 - } 1.4109 - else 1.4110 - { 1.4111 - SP+=2; 1.4112 - tempw=readmemw(ss,(SP-2)&0xFFFF); if (abrt) { SP-=2; break; } 1.4113 - } 1.4114 - regs[opcode&7].w=tempw; 1.4115 - cycles-=(is486)?1:4; 1.4116 - break; 1.4117 - case 0x158: case 0x159: case 0x15A: case 0x15B: /*POP r32*/ 1.4118 - case 0x15C: case 0x15D: case 0x15E: case 0x15F: 1.4119 - case 0x358: case 0x359: case 0x35A: case 0x35B: 1.4120 - case 0x35C: case 0x35D: case 0x35E: case 0x35F: 1.4121 - if (ssegs) ss=oldss; 1.4122 - if (stack32) 1.4123 - { 1.4124 - ESP+=4; 1.4125 - templ=readmeml(ss,ESP-4); if (abrt) { ESP-=4; break; } 1.4126 - } 1.4127 - else 1.4128 - { 1.4129 - SP+=4; 1.4130 - templ=readmeml(ss,(SP-4)&0xFFFF); if (abrt) { SP-=4; break; } 1.4131 - } 1.4132 - regs[opcode&7].l=templ; 1.4133 - cycles-=(is486)?1:4; 1.4134 - break; 1.4135 - 1.4136 - case 0x60: case 0x260: /*PUSHA*/ 1.4137 - if (stack32) 1.4138 - { 1.4139 - writememw(ss,ESP-2,AX); 1.4140 - writememw(ss,ESP-4,CX); 1.4141 - writememw(ss,ESP-6,DX); 1.4142 - writememw(ss,ESP-8,BX); 1.4143 - writememw(ss,ESP-10,SP); 1.4144 - writememw(ss,ESP-12,BP); 1.4145 - writememw(ss,ESP-14,SI); 1.4146 - writememw(ss,ESP-16,DI); 1.4147 - if (!abrt) ESP-=16; 1.4148 - } 1.4149 - else 1.4150 - { 1.4151 - writememw(ss,((SP-2)&0xFFFF),AX); 1.4152 - writememw(ss,((SP-4)&0xFFFF),CX); 1.4153 - writememw(ss,((SP-6)&0xFFFF),DX); 1.4154 - writememw(ss,((SP-8)&0xFFFF),BX); 1.4155 - writememw(ss,((SP-10)&0xFFFF),SP); 1.4156 - writememw(ss,((SP-12)&0xFFFF),BP); 1.4157 - writememw(ss,((SP-14)&0xFFFF),SI); 1.4158 - writememw(ss,((SP-16)&0xFFFF),DI); 1.4159 - if (!abrt) SP-=16; 1.4160 - } 1.4161 - cycles-=(is486)?11:18; 1.4162 - break; 1.4163 - case 0x61: case 0x261: /*POPA*/ 1.4164 - if (stack32) 1.4165 - { 1.4166 - DI=readmemw(ss,ESP); if (abrt) break; 1.4167 - SI=readmemw(ss,ESP+2); if (abrt) break; 1.4168 - BP=readmemw(ss,ESP+4); if (abrt) break; 1.4169 - BX=readmemw(ss,ESP+8); if (abrt) break; 1.4170 - DX=readmemw(ss,ESP+10); if (abrt) break; 1.4171 - CX=readmemw(ss,ESP+12); if (abrt) break; 1.4172 - AX=readmemw(ss,ESP+14); if (abrt) break; 1.4173 - ESP+=16; 1.4174 - } 1.4175 - else 1.4176 - { 1.4177 - DI=readmemw(ss,((SP)&0xFFFF)); if (abrt) break; 1.4178 - SI=readmemw(ss,((SP+2)&0xFFFF)); if (abrt) break; 1.4179 - BP=readmemw(ss,((SP+4)&0xFFFF)); if (abrt) break; 1.4180 - BX=readmemw(ss,((SP+8)&0xFFFF)); if (abrt) break; 1.4181 - DX=readmemw(ss,((SP+10)&0xFFFF)); if (abrt) break; 1.4182 - CX=readmemw(ss,((SP+12)&0xFFFF)); if (abrt) break; 1.4183 - AX=readmemw(ss,((SP+14)&0xFFFF)); if (abrt) break; 1.4184 - SP+=16; 1.4185 - } 1.4186 - cycles-=(is486)?9:24; 1.4187 - break; 1.4188 - case 0x160: case 0x360: /*PUSHA*/ 1.4189 - if (stack32) 1.4190 - { 1.4191 - writememl(ss,ESP-4,EAX); 1.4192 - writememl(ss,ESP-8,ECX); 1.4193 - writememl(ss,ESP-12,EDX); 1.4194 - writememl(ss,ESP-16,EBX); 1.4195 - writememl(ss,ESP-20,ESP); 1.4196 - writememl(ss,ESP-24,EBP); 1.4197 - writememl(ss,ESP-28,ESI); 1.4198 - writememl(ss,ESP-32,EDI); 1.4199 - if (!abrt) ESP-=32; 1.4200 - } 1.4201 - else 1.4202 - { 1.4203 - writememl(ss,((SP-4)&0xFFFF),EAX); 1.4204 - writememl(ss,((SP-8)&0xFFFF),ECX); 1.4205 - writememl(ss,((SP-12)&0xFFFF),EDX); 1.4206 - writememl(ss,((SP-16)&0xFFFF),EBX); 1.4207 - writememl(ss,((SP-20)&0xFFFF),ESP); 1.4208 - writememl(ss,((SP-24)&0xFFFF),EBP); 1.4209 - writememl(ss,((SP-28)&0xFFFF),ESI); 1.4210 - writememl(ss,((SP-32)&0xFFFF),EDI); 1.4211 - if (!abrt) SP-=32; 1.4212 - } 1.4213 - cycles-=(is486)?11:18; 1.4214 - break; 1.4215 - case 0x161: case 0x361: /*POPA*/ 1.4216 - if (stack32) 1.4217 - { 1.4218 - EDI=readmeml(ss,ESP); if (abrt) break; 1.4219 - ESI=readmeml(ss,ESP+4); if (abrt) break; 1.4220 - EBP=readmeml(ss,ESP+8); if (abrt) break; 1.4221 - EBX=readmeml(ss,ESP+16); if (abrt) break; 1.4222 - EDX=readmeml(ss,ESP+20); if (abrt) break; 1.4223 - ECX=readmeml(ss,ESP+24); if (abrt) break; 1.4224 - EAX=readmeml(ss,ESP+28); if (abrt) break; 1.4225 - ESP+=32; 1.4226 - } 1.4227 - else 1.4228 - { 1.4229 - EDI=readmeml(ss,((SP)&0xFFFF)); if (abrt) break; 1.4230 - ESI=readmeml(ss,((SP+4)&0xFFFF)); if (abrt) break; 1.4231 - EBP=readmeml(ss,((SP+8)&0xFFFF)); if (abrt) break; 1.4232 - EBX=readmeml(ss,((SP+16)&0xFFFF)); if (abrt) break; 1.4233 - EDX=readmeml(ss,((SP+20)&0xFFFF)); if (abrt) break; 1.4234 - ECX=readmeml(ss,((SP+24)&0xFFFF)); if (abrt) break; 1.4235 - EAX=readmeml(ss,((SP+28)&0xFFFF)); if (abrt) break; 1.4236 - SP+=32; 1.4237 - } 1.4238 - cycles-=(is486)?9:24; 1.4239 - break; 1.4240 - 1.4241 - case 0x62: case 0x262: /*BOUND*/ 1.4242 - fetchea(); 1.4243 - tempw=geteaw(); 1.4244 - tempw2=readmemw(easeg,eaaddr+2); if (abrt) break; 1.4245 - if (((int16_t)regs[reg].w<(int16_t)tempw) || ((int16_t)regs[reg].w>(int16_t)tempw2)) 1.4246 - { 1.4247 - x86_int(5); 1.4248 - } 1.4249 - cycles-=(is486)?7:10; 1.4250 - break; 1.4251 - case 0x162: case 0x362: /*BOUND*/ 1.4252 - fetchea(); 1.4253 - templ=geteal(); 1.4254 - templ2=readmeml(easeg,eaaddr+4); if (abrt) break; 1.4255 - if (((int32_t)regs[reg].l<(int32_t)templ) || ((int32_t)regs[reg].l>(int32_t)templ2)) 1.4256 - { 1.4257 - x86_int(5); 1.4258 - } 1.4259 - cycles-=(is486)?7:10; 1.4260 - break; 1.4261 - 1.4262 - 1.4263 - case 0x63: case 0x163: case 0x263: case 0x363: /*ARPL*/ 1.4264 - NOTRM 1.4265 - fetchea(); 1.4266 - tempw=geteaw(); if (abrt) break; 1.4267 - if ((tempw&3)<(regs[reg].w&3)) 1.4268 - { 1.4269 - tempw=(tempw&0xFFFC)|(regs[reg].w&3); 1.4270 - seteaw(tempw); if (abrt) break; 1.4271 - flags|=Z_FLAG; 1.4272 - } 1.4273 - else 1.4274 - flags&=~Z_FLAG; 1.4275 - cycles-=(is486)?9:20; 1.4276 - break; 1.4277 - case 0x64: case 0x164: case 0x264: case 0x364: /*FS:*/ 1.4278 - oldss=ss; 1.4279 - oldds=ds; 1.4280 - rds=FS; 1.4281 - ds=ss=fs; 1.4282 - ssegs=2; 1.4283 - cycles-=4; 1.4284 - goto opcodestart; 1.4285 - case 0x65: case 0x165: case 0x265: case 0x365: /*GS:*/ 1.4286 - oldss=ss; 1.4287 - oldds=ds; 1.4288 - rds=GS; 1.4289 - ds=ss=gs; 1.4290 - ssegs=2; 1.4291 - cycles-=4; 1.4292 - goto opcodestart; 1.4293 - 1.4294 - case 0x66: case 0x166: case 0x266: case 0x366: /*Data size select*/ 1.4295 - op32=((use32&0x100)^0x100)|(op32&0x200); 1.4296 -// op32^=0x100; 1.4297 - cycles-=2; 1.4298 - goto opcodestart; 1.4299 - case 0x67: case 0x167: case 0x267: case 0x367: /*Address size select*/ 1.4300 - op32=((use32&0x200)^0x200)|(op32&0x100); 1.4301 -// op32^=0x200; 1.4302 - cycles-=2; 1.4303 - goto opcodestart; 1.4304 - 1.4305 - case 0x68: case 0x268: /*PUSH #w*/ 1.4306 - tempw=getword(); 1.4307 - if (stack32) 1.4308 - { 1.4309 - writememw(ss,ESP-2,tempw); if (abrt) break; 1.4310 - ESP-=2; 1.4311 - } 1.4312 - else 1.4313 - { 1.4314 - writememw(ss,((SP-2)&0xFFFF),tempw); if (abrt) break; 1.4315 - SP-=2; 1.4316 - } 1.4317 - cycles-=2; 1.4318 - break; 1.4319 - case 0x168: case 0x368: /*PUSH #l*/ 1.4320 - templ=getlong(); 1.4321 - if (stack32) 1.4322 - { 1.4323 - writememl(ss,ESP-4,templ); if (abrt) break; 1.4324 - ESP-=4; 1.4325 - } 1.4326 - else 1.4327 - { 1.4328 - writememl(ss,((SP-4)&0xFFFF),templ); if (abrt) break; 1.4329 - SP-=4; 1.4330 - } 1.4331 - cycles-=2; 1.4332 - break; 1.4333 - case 0x69: case 0x269: /*IMUL r16*/ 1.4334 - fetchea(); 1.4335 - tempw=geteaw(); if (abrt) break; 1.4336 - tempw2=getword(); if (abrt) break; 1.4337 - templ=((int)(int16_t)tempw)*((int)(int16_t)tempw2); 1.4338 - if ((templ>>16)!=0 && (templ>>16)!=0xFFFF) flags|=C_FLAG|V_FLAG; 1.4339 - else flags&=~(C_FLAG|V_FLAG); 1.4340 - regs[reg].w=templ&0xFFFF; 1.4341 - cycles-=((mod==3)?14:17); 1.4342 - break; 1.4343 - case 0x169: case 0x369: /*IMUL r32*/ 1.4344 - fetchea(); 1.4345 - templ=geteal(); if (abrt) break; 1.4346 - templ2=getlong(); if (abrt) break; 1.4347 - temp64=((int64_t)(int32_t)templ)*((int64_t)(int32_t)templ2); 1.4348 - if ((temp64>>32)!=0 && (temp64>>32)!=0xFFFFFFFF) flags|=C_FLAG|V_FLAG; 1.4349 - else flags&=~(C_FLAG|V_FLAG); 1.4350 - regs[reg].l=temp64&0xFFFFFFFF; 1.4351 - cycles-=25; 1.4352 - break; 1.4353 - case 0x6A: case 0x26A:/*PUSH #eb*/ 1.4354 - tempw=readmemb(cs,pc); pc++; 1.4355 - if (tempw&0x80) tempw|=0xFF00; 1.4356 - if (output) pclog("PUSH %04X %i\n",tempw,stack32); 1.4357 - if (stack32) 1.4358 - { 1.4359 - writememw(ss,ESP-2,tempw); if (abrt) break; 1.4360 - ESP-=2; 1.4361 - } 1.4362 - else 1.4363 - { 1.4364 - writememw(ss,((SP-2)&0xFFFF),tempw); if (abrt) break; 1.4365 - SP-=2; 1.4366 - } 1.4367 - cycles-=2; 1.4368 - break; 1.4369 - case 0x16A: case 0x36A:/*PUSH #eb*/ 1.4370 - templ=readmemb(cs,pc); pc++; 1.4371 - if (templ&0x80) templ|=0xFFFFFF00; 1.4372 - if (output) pclog("PUSH %08X %i\n",templ,stack32); 1.4373 - if (stack32) 1.4374 - { 1.4375 - writememl(ss,ESP-4,templ); if (abrt) break; 1.4376 - ESP-=4; 1.4377 - } 1.4378 - else 1.4379 - { 1.4380 - writememl(ss,((SP-4)&0xFFFF),templ); if (abrt) break; 1.4381 - SP-=4; 1.4382 - } 1.4383 - cycles-=2; 1.4384 - break; 1.4385 -// #if 0 1.4386 - case 0x6B: case 0x26B: /*IMUL r8*/ 1.4387 - fetchea(); 1.4388 - tempw=geteaw(); if (abrt) break; 1.4389 - tempw2=readmemb(cs,pc); pc++; if (abrt) break; 1.4390 - if (tempw2&0x80) tempw2|=0xFF00; 1.4391 - templ=((int)(int16_t)tempw)*((int)(int16_t)tempw2); 1.4392 -// pclog("IMULr8 %08X %08X %08X\n",tempw,tempw2,templ); 1.4393 - if ((templ>>16)!=0 && ((templ>>16)&0xFFFF)!=0xFFFF) flags|=C_FLAG|V_FLAG; 1.4394 - else flags&=~(C_FLAG|V_FLAG); 1.4395 - regs[reg].w=templ&0xFFFF; 1.4396 - cycles-=((mod==3)?14:17); 1.4397 - break; 1.4398 - case 0x16B: case 0x36B: /*IMUL r8*/ 1.4399 - fetchea(); 1.4400 - templ=geteal(); if (abrt) break; 1.4401 - templ2=readmemb(cs,pc); pc++; if (abrt) break; 1.4402 - if (templ2&0x80) templ2|=0xFFFFFF00; 1.4403 - temp64=((int64_t)(int32_t)templ)*((int64_t)(int32_t)templ2); 1.4404 -// pclog("IMULr8 %08X %08X %i\n",templ,templ2,temp64i>>32); 1.4405 - if ((temp64>>32)!=0 && (temp64>>32)!=0xFFFFFFFF) flags|=C_FLAG|V_FLAG; 1.4406 - else flags&=~(C_FLAG|V_FLAG); 1.4407 - regs[reg].l=temp64&0xFFFFFFFF; 1.4408 - cycles-=20; 1.4409 - break; 1.4410 -//#endif 1.4411 - case 0x6C: case 0x16C: /*INSB*/ 1.4412 - checkio_perm(DX); 1.4413 - temp=inb(DX); 1.4414 - writememb(es,DI,temp); if (abrt) break; 1.4415 - if (flags&D_FLAG) DI--; 1.4416 - else DI++; 1.4417 - cycles-=15; 1.4418 - break; 1.4419 - case 0x26C: case 0x36C: /*INSB*/ 1.4420 - checkio_perm(DX); 1.4421 - temp=inb(DX); 1.4422 - writememb(es,EDI,temp); if (abrt) break; 1.4423 - if (flags&D_FLAG) EDI--; 1.4424 - else EDI++; 1.4425 - cycles-=15; 1.4426 - break; 1.4427 - case 0x6D: /*INSW*/ 1.4428 - checkio_perm(DX); 1.4429 - checkio_perm(DX+1); 1.4430 - tempw=inw(DX); 1.4431 - writememw(es,DI,tempw); if (abrt) break; 1.4432 - if (flags&D_FLAG) DI-=2; 1.4433 - else DI+=2; 1.4434 - cycles-=15; 1.4435 - break; 1.4436 - case 0x16D: /*INSL*/ 1.4437 - checkio_perm(DX); 1.4438 - checkio_perm(DX+1); 1.4439 - checkio_perm(DX+2); 1.4440 - checkio_perm(DX+3); 1.4441 - templ=inl(DX); 1.4442 - writememl(es,DI,templ); if (abrt) break; 1.4443 - if (flags&D_FLAG) DI-=4; 1.4444 - else DI+=4; 1.4445 - cycles-=15; 1.4446 - break; 1.4447 - case 0x26D: /*INSW*/ 1.4448 - checkio_perm(DX); 1.4449 - checkio_perm(DX+1); 1.4450 - tempw=inw(DX); 1.4451 - writememw(es,EDI,tempw); if (abrt) break; 1.4452 - if (flags&D_FLAG) EDI-=2; 1.4453 - else EDI+=2; 1.4454 - cycles-=15; 1.4455 - break; 1.4456 - case 0x36D: /*INSL*/ 1.4457 - checkio_perm(DX); 1.4458 - checkio_perm(DX+1); 1.4459 - checkio_perm(DX+2); 1.4460 - checkio_perm(DX+3); 1.4461 - templ=inl(DX); 1.4462 - writememl(es,EDI,templ); if (abrt) break; 1.4463 - if (flags&D_FLAG) EDI-=4; 1.4464 - else EDI+=4; 1.4465 - cycles-=15; 1.4466 - break; 1.4467 - case 0x6E: case 0x16E: /*OUTSB*/ 1.4468 - temp=readmemb(ds,SI); if (abrt) break; 1.4469 - checkio_perm(DX); 1.4470 - if (flags&D_FLAG) SI--; 1.4471 - else SI++; 1.4472 - outb(DX,temp); 1.4473 - cycles-=14; 1.4474 - break; 1.4475 - case 0x26E: case 0x36E: /*OUTSB*/ 1.4476 - checkio_perm(DX); 1.4477 - temp=readmemb(ds,ESI); if (abrt) break; 1.4478 - if (flags&D_FLAG) ESI--; 1.4479 - else ESI++; 1.4480 - outb(DX,temp); 1.4481 - cycles-=14; 1.4482 - break; 1.4483 - case 0x6F: /*OUTSW*/ 1.4484 - tempw=readmemw(ds,SI); if (abrt) break; 1.4485 - checkio_perm(DX); 1.4486 - checkio_perm(DX+1); 1.4487 - if (flags&D_FLAG) SI-=2; 1.4488 - else SI+=2; 1.4489 - outw(DX,tempw); 1.4490 -// outb(DX+1,tempw>>8); 1.4491 - cycles-=14; 1.4492 - break; 1.4493 - case 0x16F: /*OUTSL*/ 1.4494 - tempw=readmemw(ds,SI); if (abrt) break; 1.4495 - checkio_perm(DX); 1.4496 - checkio_perm(DX+1); 1.4497 - checkio_perm(DX+2); 1.4498 - checkio_perm(DX+3); 1.4499 - if (flags&D_FLAG) SI-=4; 1.4500 - else SI+=4; 1.4501 - outl(EDX,templ); 1.4502 - cycles-=14; 1.4503 - break; 1.4504 - case 0x26F: /*OUTSW*/ 1.4505 - tempw=readmemw(ds,ESI); if (abrt) break; 1.4506 - checkio_perm(DX); 1.4507 - checkio_perm(DX+1); 1.4508 - if (flags&D_FLAG) ESI-=2; 1.4509 - else ESI+=2; 1.4510 - outw(DX,tempw); 1.4511 - cycles-=14; 1.4512 - break; 1.4513 - case 0x36F: /*OUTSL*/ 1.4514 - tempw=readmemw(ds,ESI); if (abrt) break; 1.4515 - checkio_perm(DX); 1.4516 - checkio_perm(DX+1); 1.4517 - checkio_perm(DX+2); 1.4518 - checkio_perm(DX+3); 1.4519 - if (flags&D_FLAG) ESI-=4; 1.4520 - else ESI+=4; 1.4521 - outl(EDX,templ); 1.4522 - cycles-=14; 1.4523 - break; 1.4524 - 1.4525 - case 0x70: case 0x170: case 0x270: case 0x370: /*JO*/ 1.4526 - offset=(int8_t)getbytef(); 1.4527 - if (flags&V_FLAG) { pc += offset; cycles -= timing_bt; } 1.4528 - cycles -= timing_bnt; 1.4529 - break; 1.4530 - case 0x71: case 0x171: case 0x271: case 0x371: /*JNO*/ 1.4531 - offset=(int8_t)getbytef(); 1.4532 - if (!(flags&V_FLAG)) { pc += offset; cycles -= timing_bt; } 1.4533 - cycles -= timing_bnt; 1.4534 - break; 1.4535 - case 0x72: case 0x172: case 0x272: case 0x372: /*JB*/ 1.4536 - offset=(int8_t)getbytef(); 1.4537 - if (flags&C_FLAG) { pc += offset; cycles -= timing_bt; } 1.4538 - cycles -= timing_bnt; 1.4539 - break; 1.4540 - case 0x73: case 0x173: case 0x273: case 0x373: /*JNB*/ 1.4541 - offset=(int8_t)getbytef(); 1.4542 - if (!(flags&C_FLAG)) { pc += offset; cycles -= timing_bt; } 1.4543 - cycles -= timing_bnt; 1.4544 - break; 1.4545 - case 0x74: case 0x174: case 0x274: case 0x374: /*JZ*/ 1.4546 - offset=(int8_t)getbytef(); 1.4547 - if (flags&Z_FLAG) { pc += offset; cycles -= timing_bt; } 1.4548 - cycles -= timing_bnt; 1.4549 - break; 1.4550 - case 0x75: case 0x175: case 0x275: case 0x375: /*JNZ*/ 1.4551 - offset=(int8_t)getbytef(); 1.4552 - if (!(flags&Z_FLAG)) { pc += offset; cycles -= timing_bt; } 1.4553 - cycles -= timing_bnt; 1.4554 - break; 1.4555 - case 0x76: case 0x176: case 0x276: case 0x376: /*JBE*/ 1.4556 - offset=(int8_t)getbytef(); 1.4557 - if (flags&(C_FLAG|Z_FLAG)) { pc += offset; cycles -= timing_bt; } 1.4558 - cycles -= timing_bnt; 1.4559 - break; 1.4560 - case 0x77: case 0x177: case 0x277: case 0x377: /*JNBE*/ 1.4561 - offset=(int8_t)getbytef(); 1.4562 - if (!(flags&(C_FLAG|Z_FLAG))) { pc += offset; cycles -= timing_bt; } 1.4563 - cycles -= timing_bnt; 1.4564 - break; 1.4565 - case 0x78: case 0x178: case 0x278: case 0x378: /*JS*/ 1.4566 - offset=(int8_t)getbytef(); 1.4567 - if (flags&N_FLAG) { pc += offset; cycles -= timing_bt; } 1.4568 - cycles -= timing_bnt; 1.4569 - break; 1.4570 - case 0x79: case 0x179: case 0x279: case 0x379: /*JNS*/ 1.4571 - offset=(int8_t)getbytef(); 1.4572 - if (!(flags&N_FLAG)) { pc += offset; cycles -= timing_bt; } 1.4573 - cycles -= timing_bnt; 1.4574 - break; 1.4575 - case 0x7A: case 0x17A: case 0x27A: case 0x37A: /*JP*/ 1.4576 - offset=(int8_t)getbytef(); 1.4577 - if (flags&P_FLAG) { pc += offset; cycles -= timing_bt; } 1.4578 - cycles -= timing_bnt; 1.4579 - break; 1.4580 - case 0x7B: case 0x17B: case 0x27B: case 0x37B: /*JNP*/ 1.4581 - offset=(int8_t)getbytef(); 1.4582 - if (!(flags&P_FLAG)) { pc += offset; cycles -= timing_bt; } 1.4583 - cycles -= timing_bnt; 1.4584 - break; 1.4585 - case 0x7C: case 0x17C: case 0x27C: case 0x37C: /*JL*/ 1.4586 - offset=(int8_t)getbytef(); 1.4587 - temp=(flags&N_FLAG)?1:0; 1.4588 - temp2=(flags&V_FLAG)?1:0; 1.4589 - if (temp!=temp2) { pc += offset; cycles -= timing_bt; } 1.4590 - cycles -= timing_bnt; 1.4591 - break; 1.4592 - case 0x7D: case 0x17D: case 0x27D: case 0x37D: /*JNL*/ 1.4593 - offset=(int8_t)getbytef(); 1.4594 - temp=(flags&N_FLAG)?1:0; 1.4595 - temp2=(flags&V_FLAG)?1:0; 1.4596 - if (temp==temp2) { pc += offset; cycles -= timing_bt; } 1.4597 - cycles -= timing_bnt; 1.4598 - break; 1.4599 - case 0x7E: case 0x17E: case 0x27E: case 0x37E: /*JLE*/ 1.4600 - offset=(int8_t)getbytef(); 1.4601 - temp=(flags&N_FLAG)?1:0; 1.4602 - temp2=(flags&V_FLAG)?1:0; 1.4603 - if ((flags&Z_FLAG) || (temp!=temp2)) { pc += offset; cycles -= timing_bt; } 1.4604 - cycles -= timing_bnt; 1.4605 - break; 1.4606 - case 0x7F: case 0x17F: case 0x27F: case 0x37F: /*JNLE*/ 1.4607 - offset=(int8_t)getbytef(); 1.4608 - temp=(flags&N_FLAG)?1:0; 1.4609 - temp2=(flags&V_FLAG)?1:0; 1.4610 - if (!((flags&Z_FLAG) || (temp!=temp2))) { pc += offset; cycles -= timing_bt; } 1.4611 - cycles -= timing_bnt; 1.4612 - break; 1.4613 - 1.4614 - 1.4615 - case 0x80: case 0x180: case 0x280: case 0x380: 1.4616 - case 0x82: case 0x182: case 0x282: case 0x382: 1.4617 - fetchea(); 1.4618 - temp=geteab(); if (abrt) break; 1.4619 - temp2=readmemb(cs,pc); pc++; if (abrt) break; 1.4620 - switch (rmdat&0x38) 1.4621 - { 1.4622 - case 0x00: /*ADD b,#8*/ 1.4623 - seteab(temp+temp2); if (abrt) break; 1.4624 - setadd8(temp,temp2); 1.4625 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4626 - break; 1.4627 - case 0x08: /*OR b,#8*/ 1.4628 - temp|=temp2; 1.4629 - seteab(temp); if (abrt) break; 1.4630 - setznp8(temp); 1.4631 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4632 - break; 1.4633 - case 0x10: /*ADC b,#8*/ 1.4634 - seteab(temp+temp2+tempc); if (abrt) break; 1.4635 - setadc8(temp,temp2); 1.4636 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4637 - break; 1.4638 - case 0x18: /*SBB b,#8*/ 1.4639 - seteab(temp-(temp2+tempc)); if (abrt) break; 1.4640 - setsbc8(temp,temp2); 1.4641 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4642 - break; 1.4643 - case 0x20: /*AND b,#8*/ 1.4644 - temp&=temp2; 1.4645 - seteab(temp); if (abrt) break; 1.4646 - setznp8(temp); 1.4647 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4648 - break; 1.4649 - case 0x28: /*SUB b,#8*/ 1.4650 - seteab(temp-temp2); if (abrt) break; 1.4651 - setsub8(temp,temp2); 1.4652 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4653 - break; 1.4654 - case 0x30: /*XOR b,#8*/ 1.4655 - temp^=temp2; 1.4656 - seteab(temp); if (abrt) break; 1.4657 - setznp8(temp); 1.4658 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4659 - break; 1.4660 - case 0x38: /*CMP b,#8*/ 1.4661 - setsub8(temp,temp2); 1.4662 - if (is486) cycles-=((mod==3)?1:2); 1.4663 - else cycles-=((mod==3)?2:7); 1.4664 - break; 1.4665 - } 1.4666 - break; 1.4667 - 1.4668 - case 0x81: case 0x281: 1.4669 - fetchea(); 1.4670 - tempw=geteaw(); if (abrt) break; 1.4671 - tempw2=getword(); if (abrt) break; 1.4672 - switch (rmdat&0x38) 1.4673 - { 1.4674 - case 0x00: /*ADD w,#16*/ 1.4675 - seteaw(tempw+tempw2); if (abrt) break; 1.4676 - setadd16(tempw,tempw2); 1.4677 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4678 - break; 1.4679 - case 0x08: /*OR w,#16*/ 1.4680 - tempw|=tempw2; 1.4681 - seteaw(tempw); if (abrt) break; 1.4682 - setznp16(tempw); 1.4683 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4684 - break; 1.4685 - case 0x10: /*ADC w,#16*/ 1.4686 - seteaw(tempw+tempw2+tempc); if (abrt) break; 1.4687 - setadc16(tempw,tempw2); 1.4688 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4689 - break; 1.4690 - case 0x20: /*AND w,#16*/ 1.4691 - tempw&=tempw2; 1.4692 - seteaw(tempw); if (abrt) break; 1.4693 - setznp16(tempw); 1.4694 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4695 - break; 1.4696 - case 0x18: /*SBB w,#16*/ 1.4697 - seteaw(tempw-(tempw2+tempc)); if (abrt) break; 1.4698 - setsbc16(tempw,tempw2); 1.4699 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4700 - break; 1.4701 - case 0x28: /*SUB w,#16*/ 1.4702 - seteaw(tempw-tempw2); if (abrt) break; 1.4703 - setsub16(tempw,tempw2); 1.4704 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4705 - break; 1.4706 - case 0x30: /*XOR w,#16*/ 1.4707 - tempw^=tempw2; 1.4708 - seteaw(tempw); if (abrt) break; 1.4709 - setznp16(tempw); 1.4710 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4711 - break; 1.4712 - case 0x38: /*CMP w,#16*/ 1.4713 - setsub16(tempw,tempw2); 1.4714 - if (is486) cycles-=((mod==3)?1:2); 1.4715 - else cycles-=((mod==3)?2:7); 1.4716 - break; 1.4717 - } 1.4718 - break; 1.4719 - case 0x181: case 0x381: 1.4720 - fetchea(); 1.4721 - templ=geteal(); if (abrt) break; 1.4722 - templ2=getlong(); if (abrt) break; 1.4723 - switch (rmdat&0x38) 1.4724 - { 1.4725 - case 0x00: /*ADD l,#32*/ 1.4726 - seteal(templ+templ2); if (abrt) break; 1.4727 - setadd32(templ,templ2); 1.4728 - cycles -= (mod == 3) ? timing_rr : timing_mrl; 1.4729 - break; 1.4730 - case 0x08: /*OR l,#32*/ 1.4731 - templ|=templ2; 1.4732 - seteal(templ); if (abrt) break; 1.4733 - setznp32(templ); 1.4734 - cycles -= (mod == 3) ? timing_rr : timing_mrl; 1.4735 - break; 1.4736 - case 0x10: /*ADC l,#32*/ 1.4737 - seteal(templ+templ2+tempc); if (abrt) break; 1.4738 - setadc32(templ,templ2); 1.4739 - cycles -= (mod == 3) ? timing_rr : timing_mrl; 1.4740 - break; 1.4741 - case 0x20: /*AND l,#32*/ 1.4742 - templ&=templ2; 1.4743 - seteal(templ); if (abrt) break; 1.4744 - setznp32(templ); 1.4745 - cycles -= (mod == 3) ? timing_rr : timing_mrl; 1.4746 - break; 1.4747 - case 0x18: /*SBB l,#32*/ 1.4748 - seteal(templ-(templ2+tempc)); if (abrt) break; 1.4749 - setsbc32(templ,templ2); 1.4750 - cycles -= (mod == 3) ? timing_rr : timing_mrl; 1.4751 - break; 1.4752 - case 0x28: /*SUB l,#32*/ 1.4753 - seteal(templ-templ2); if (abrt) break; 1.4754 - setsub32(templ,templ2); 1.4755 - cycles -= (mod == 3) ? timing_rr : timing_mrl; 1.4756 - break; 1.4757 - case 0x30: /*XOR l,#32*/ 1.4758 - templ^=templ2; 1.4759 - seteal(templ); if (abrt) break; 1.4760 - setznp32(templ); 1.4761 - cycles -= (mod == 3) ? timing_rr : timing_mrl; 1.4762 - break; 1.4763 - case 0x38: /*CMP l,#32*/ 1.4764 - setsub32(templ,templ2); 1.4765 - if (is486) cycles-=((mod==3)?1:2); 1.4766 - else cycles-=((mod==3)?2:7); 1.4767 - break; 1.4768 - } 1.4769 - break; 1.4770 - 1.4771 - case 0x83: case 0x283: 1.4772 - fetchea(); 1.4773 - tempw=geteaw(); if (abrt) break; 1.4774 - tempw2=readmemb(cs,pc); pc++; if (abrt) break; 1.4775 - if (tempw2&0x80) tempw2|=0xFF00; 1.4776 - switch (rmdat&0x38) 1.4777 - { 1.4778 - case 0x00: /*ADD w,#8*/ 1.4779 - seteaw(tempw+tempw2); if (abrt) break; 1.4780 - setadd16(tempw,tempw2); 1.4781 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4782 - break; 1.4783 - case 0x08: /*OR w,#8*/ 1.4784 - tempw|=tempw2; 1.4785 - seteaw(tempw); if (abrt) break; 1.4786 - setznp16(tempw); 1.4787 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4788 - break; 1.4789 - case 0x10: /*ADC w,#8*/ 1.4790 - seteaw(tempw+tempw2+tempc); if (abrt) break; 1.4791 - setadc16(tempw,tempw2); 1.4792 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4793 - break; 1.4794 - case 0x18: /*SBB w,#8*/ 1.4795 - seteaw(tempw-(tempw2+tempc)); if (abrt) break; 1.4796 - setsbc16(tempw,tempw2); 1.4797 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4798 - break; 1.4799 - case 0x20: /*AND w,#8*/ 1.4800 - tempw&=tempw2; 1.4801 - seteaw(tempw); if (abrt) break; 1.4802 - setznp16(tempw); 1.4803 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4804 - break; 1.4805 - case 0x28: /*SUB w,#8*/ 1.4806 - seteaw(tempw-tempw2); if (abrt) break; 1.4807 - setsub16(tempw,tempw2); 1.4808 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4809 - break; 1.4810 - case 0x30: /*XOR w,#8*/ 1.4811 - tempw^=tempw2; 1.4812 - seteaw(tempw); if (abrt) break; 1.4813 - setznp16(tempw); 1.4814 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4815 - break; 1.4816 - case 0x38: /*CMP w,#8*/ 1.4817 - setsub16(tempw,tempw2); 1.4818 - if (is486) cycles-=((mod==3)?1:2); 1.4819 - else cycles-=((mod==3)?2:7); 1.4820 - break; 1.4821 - } 1.4822 - break; 1.4823 - case 0x183: case 0x383: 1.4824 - fetchea(); 1.4825 - templ=geteal(); if (abrt) break; 1.4826 - templ2=readmemb(cs,pc); pc++; if (abrt) break; 1.4827 - if (templ2&0x80) templ2|=0xFFFFFF00; 1.4828 - switch (rmdat&0x38) 1.4829 - { 1.4830 - case 0x00: /*ADD l,#32*/ 1.4831 - seteal(templ+templ2); if (abrt) break; 1.4832 - setadd32(templ,templ2); 1.4833 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4834 - break; 1.4835 - case 0x08: /*OR l,#32*/ 1.4836 - templ|=templ2; 1.4837 - seteal(templ); if (abrt) break; 1.4838 - setznp32(templ); 1.4839 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4840 - break; 1.4841 - case 0x10: /*ADC l,#32*/ 1.4842 - seteal(templ+templ2+tempc); if (abrt) break; 1.4843 - setadc32(templ,templ2); 1.4844 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4845 - break; 1.4846 - case 0x20: /*AND l,#32*/ 1.4847 - templ&=templ2; 1.4848 - seteal(templ); if (abrt) break; 1.4849 - setznp32(templ); 1.4850 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4851 - break; 1.4852 - case 0x18: /*SBB l,#32*/ 1.4853 - seteal(templ-(templ2+tempc)); if (abrt) break; 1.4854 - setsbc32(templ,templ2); 1.4855 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4856 - break; 1.4857 - case 0x28: /*SUB l,#32*/ 1.4858 - seteal(templ-templ2); if (abrt) break; 1.4859 - setsub32(templ,templ2); 1.4860 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4861 - break; 1.4862 - case 0x30: /*XOR l,#32*/ 1.4863 - templ^=templ2; 1.4864 - seteal(templ); if (abrt) break; 1.4865 - setznp32(templ); 1.4866 - cycles -= (mod == 3) ? timing_rr : timing_mr; 1.4867 - break; 1.4868 - case 0x38: /*CMP l,#32*/ 1.4869 - setsub32(templ,templ2); 1.4870 - if (is486) cycles-=((mod==3)?1:2); 1.4871 - else cycles-=((mod==3)?2:7); 1.4872 - break; 1.4873 - } 1.4874 - break; 1.4875 - 1.4876 - case 0x84: case 0x184: case 0x284: case 0x384: /*TEST b,reg*/ 1.4877 - fetchea(); 1.4878 - temp=geteab(); if (abrt) break; 1.4879 - temp2=getr8(reg); 1.4880 - setznp8(temp&temp2); 1.4881 - if (is486) cycles-=((mod==3)?1:2); 1.4882 - else cycles-=((mod==3)?2:5); 1.4883 - break; 1.4884 - case 0x85: case 0x285: /*TEST w,reg*/ 1.4885 - fetchea(); 1.4886 - tempw=geteaw(); if (abrt) break; 1.4887 - tempw2=regs[reg].w; 1.4888 - setznp16(tempw&tempw2); 1.4889 - if (is486) cycles-=((mod==3)?1:2); 1.4890 - else cycles-=((mod==3)?2:5); 1.4891 - break; 1.4892 - case 0x185: case 0x385: /*TEST l,reg*/ 1.4893 - fetchea(); 1.4894 - templ=geteal(); if (abrt) break; 1.4895 - templ2=regs[reg].l; 1.4896 - setznp32(templ&templ2); 1.4897 - if (is486) cycles-=((mod==3)?1:2); 1.4898 - else cycles-=((mod==3)?2:5); 1.4899 - break; 1.4900 - case 0x86: case 0x186: case 0x286: case 0x386: /*XCHG b,reg*/ 1.4901 - fetchea(); 1.4902 - temp=geteab(); if (abrt) break; 1.4903 - seteab(getr8(reg)); if (abrt) break; 1.4904 - setr8(reg,temp); 1.4905 - cycles-=((mod==3)?3:5); 1.4906 - break; 1.4907 - case 0x87: case 0x287: /*XCHG w,reg*/ 1.4908 - fetchea(); 1.4909 - tempw=geteaw(); if (abrt) break; 1.4910 - seteaw(regs[reg].w); if (abrt) break; 1.4911 - regs[reg].w=tempw; 1.4912 - cycles-=((mod==3)?3:5); 1.4913 - break; 1.4914 - case 0x187: case 0x387: /*XCHG l,reg*/ 1.4915 - fetchea(); 1.4916 - templ=geteal(); if (abrt) break; 1.4917 - seteal(regs[reg].l); if (abrt) break; 1.4918 - regs[reg].l=templ; 1.4919 - cycles-=((mod==3)?3:5); 1.4920 - break; 1.4921 - 1.4922 - case 0x88: case 0x188: case 0x288: case 0x388: /*MOV b,reg*/ 1.4923 - fetchea(); 1.4924 - seteab(getr8(reg)); 1.4925 - cycles-=(is486)?1:2; 1.4926 - break; 1.4927 - case 0x89: case 0x289: /*MOV w,reg*/ 1.4928 - fetchea(); 1.4929 - seteaw(regs[reg].w); 1.4930 - cycles-=(is486)?1:2; 1.4931 - break; 1.4932 - case 0x189: case 0x389: /*MOV l,reg*/ 1.4933 - fetchea(); 1.4934 - //if (output==3) pclog("Write %08X to %08X:%08X %08X %08X %08X\n",regs[reg].l,easeg,eaaddr,); 1.4935 - seteal(regs[reg].l); 1.4936 - cycles-=(is486)?1:2; 1.4937 - break; 1.4938 - case 0x8A: case 0x18A: case 0x28A: case 0x38A: /*MOV reg,b*/ 1.4939 - fetchea(); 1.4940 - temp=geteab(); if (abrt) break; 1.4941 - setr8(reg,temp); 1.4942 - if (is486) cycles--; 1.4943 - else cycles-=((mod==3)?2:4); 1.4944 - break; 1.4945 - case 0x8B: case 0x28B: /*MOV reg,w*/ 1.4946 - fetchea(); 1.4947 - tempw=geteaw(); if (abrt) break; 1.4948 - regs[reg].w=tempw; 1.4949 - if (is486) cycles--; 1.4950 - else cycles-=((mod==3)?2:4); 1.4951 - break; 1.4952 - case 0x18B: case 0x38B: /*MOV reg,l*/ 1.4953 - fetchea(); 1.4954 - templ=geteal(); if (abrt) break; 1.4955 - regs[reg].l=templ; 1.4956 - if (is486) cycles--; 1.4957 - else cycles-=((mod==3)?2:4); 1.4958 - break; 1.4959 - 1.4960 - case 0x8C: case 0x28C: /*MOV w,sreg*/ 1.4961 - fetchea(); 1.4962 -// if (output==3) pclog("MOV sreg %02X %08X\n",rmdat,fetchdat); 1.4963 - switch (rmdat&0x38) 1.4964 - { 1.4965 - case 0x00: /*ES*/ 1.4966 - seteaw(ES); 1.4967 - break; 1.4968 - case 0x08: /*CS*/ 1.4969 - seteaw(CS); 1.4970 - break; 1.4971 - case 0x18: /*DS*/ 1.4972 - if (ssegs) ds=oldds; 1.4973 - seteaw(DS); 1.4974 - break; 1.4975 - case 0x10: /*SS*/ 1.4976 - if (ssegs) ss=oldss; 1.4977 - seteaw(SS); 1.4978 - break; 1.4979 - case 0x20: /*FS*/ 1.4980 - seteaw(FS); 1.4981 - break; 1.4982 - case 0x28: /*GS*/ 1.4983 - seteaw(GS); 1.4984 - break; 1.4985 - } 1.4986 - cycles-=((mod==3)?2:3); 1.4987 - break; 1.4988 - case 0x18C: case 0x38C: /*MOV l,sreg*/ 1.4989 - fetchea(); 1.4990 - switch (rmdat&0x38) 1.4991 - { 1.4992 - case 0x00: /*ES*/ 1.4993 - if (mod==3) regs[rm].l=ES; 1.4994 - else seteaw(ES); 1.4995 - break; 1.4996 - case 0x08: /*CS*/ 1.4997 - if (mod==3) regs[rm].l=CS; 1.4998 - else seteaw(CS); 1.4999 - break; 1.5000 - case 0x18: /*DS*/ 1.5001 - if (ssegs) ds=oldds; 1.5002 - if (mod==3) regs[rm].l=DS; 1.5003 - else seteaw(DS); 1.5004 - break; 1.5005 - case 0x10: /*SS*/ 1.5006 - if (ssegs) ss=oldss; 1.5007 - if (mod==3) regs[rm].l=SS; 1.5008 - else seteaw(SS); 1.5009 - break; 1.5010 - case 0x20: /*FS*/ 1.5011 - if (mod==3) regs[rm].l=FS; 1.5012 - else seteaw(FS); 1.5013 - break; 1.5014 - case 0x28: /*GS*/ 1.5015 - if (mod==3) regs[rm].l=GS; 1.5016 - else seteaw(GS); 1.5017 - break; 1.5018 - } 1.5019 - cycles-=((mod==3)?2:3); 1.5020 - break; 1.5021 - 1.5022 - case 0x8D: case 0x28D: /*LEA*/ 1.5023 - fetchea(); 1.5024 - regs[reg].w=eaaddr; 1.5025 - cycles -= timing_rr; 1.5026 - break; 1.5027 - case 0x18D: /*LEA*/ 1.5028 - fetchea(); 1.5029 - regs[reg].l=eaaddr&0xFFFF; 1.5030 - cycles -= timing_rr; 1.5031 - break; 1.5032 - case 0x38D: /*LEA*/ 1.5033 - fetchea(); 1.5034 - regs[reg].l=eaaddr; 1.5035 - cycles -= timing_rr; 1.5036 - break; 1.5037 - 1.5038 - case 0x8E: case 0x18E: case 0x28E: case 0x38E: /*MOV sreg,w*/ 1.5039 - fetchea(); 1.5040 - switch (rmdat&0x38) 1.5041 - { 1.5042 - case 0x00: /*ES*/ 1.5043 - tempw=geteaw(); if (abrt) break; 1.5044 - loadseg(tempw,&_es); 1.5045 - break; 1.5046 - case 0x18: /*DS*/ 1.5047 - tempw=geteaw(); if (abrt) break; 1.5048 - loadseg(tempw,&_ds); 1.5049 - if (ssegs) oldds=ds; 1.5050 - break; 1.5051 - case 0x10: /*SS*/ 1.5052 -// if (output==3) pclog("geteaw\n"); 1.5053 - tempw=geteaw(); if (abrt) break; 1.5054 -// if (output==3) pclog("loadseg\n"); 1.5055 - loadseg(tempw,&_ss); 1.5056 -// if (output==3) pclog("done\n"); 1.5057 - if (ssegs) oldss=ss; 1.5058 - skipnextprint=1; 1.5059 - noint=1; 1.5060 - break; 1.5061 - case 0x20: /*FS*/ 1.5062 - tempw=geteaw(); if (abrt) break; 1.5063 - loadseg(tempw,&_fs); 1.5064 - break; 1.5065 - case 0x28: /*GS*/ 1.5066 - tempw=geteaw(); if (abrt) break; 1.5067 - loadseg(tempw,&_gs); 1.5068 - break; 1.5069 - } 1.5070 - cycles-=((mod==3)?2:5); 1.5071 - break; 1.5072 - 1.5073 - case 0x8F: case 0x28F: /*POPW*/ 1.5074 - if (ssegs) templ2=oldss; 1.5075 - else templ2=ss; 1.5076 - if (stack32) 1.5077 - { 1.5078 - tempw=readmemw(templ2,ESP); if (abrt) break; 1.5079 - ESP+=2; 1.5080 - } 1.5081 - else 1.5082 - { 1.5083 - tempw=readmemw(templ2,SP); if (abrt) break; 1.5084 - SP+=2; 1.5085 - } 1.5086 - fetchea(); 1.5087 - if (ssegs) ss=oldss; 1.5088 - seteaw(tempw); 1.5089 - if (abrt) 1.5090 - { 1.5091 - if (stack32) ESP-=2; 1.5092 - else SP-=2; 1.5093 - } 1.5094 - if (is486) cycles-=((mod==3)?1:6); 1.5095 - else cycles-=((mod==3)?4:5); 1.5096 - break; 1.5097 - case 0x18F: case 0x38F: /*POPL*/ 1.5098 - if (ssegs) templ2=oldss; 1.5099 - else templ2=ss; 1.5100 - if (stack32) 1.5101 - { 1.5102 - templ=readmeml(templ2,ESP); if (abrt) break; 1.5103 - ESP+=4; 1.5104 - } 1.5105 - else 1.5106 - { 1.5107 - templ=readmeml(templ2,SP); if (abrt) break; 1.5108 - SP+=4; 1.5109 - } 1.5110 - fetchea(); 1.5111 - if (ssegs) ss=oldss; 1.5112 - seteal(templ); 1.5113 - if (abrt) 1.5114 - { 1.5115 - if (stack32) ESP-=4; 1.5116 - else SP-=4; 1.5117 - } 1.5118 - if (is486) cycles-=((mod==3)?1:6); 1.5119 - else cycles-=((mod==3)?4:5); 1.5120 - break; 1.5121 - 1.5122 - case 0x90: case 0x190: case 0x290: case 0x390: /*NOP*/ 1.5123 - cycles-=(is486)?1:3; 1.5124 - break; 1.5125 - 1.5126 - case 0x91: case 0x92: case 0x93: /*XCHG AX*/ 1.5127 - case 0x94: case 0x95: case 0x96: case 0x97: 1.5128 - case 0x291: case 0x292: case 0x293: 1.5129 - case 0x294: case 0x295: case 0x296: case 0x297: 1.5130 - tempw=AX; 1.5131 - AX=regs[opcode&7].w; 1.5132 - regs[opcode&7].w=tempw; 1.5133 - cycles-=3; 1.5134 - break; 1.5135 - case 0x191: case 0x192: case 0x193: /*XCHG EAX*/ 1.5136 - case 0x194: case 0x195: case 0x196: case 0x197: 1.5137 - case 0x391: case 0x392: case 0x393: /*XCHG EAX*/ 1.5138 - case 0x394: case 0x395: case 0x396: case 0x397: 1.5139 - templ=EAX; 1.5140 - EAX=regs[opcode&7].l; 1.5141 - regs[opcode&7].l=templ; 1.5142 - cycles-=3; 1.5143 - break; 1.5144 - 1.5145 - case 0x98: case 0x298: /*CBW*/ 1.5146 - AH=(AL&0x80)?0xFF:0; 1.5147 - cycles-=3; 1.5148 - break; 1.5149 - case 0x198: case 0x398: /*CWDE*/ 1.5150 - EAX=(AX&0x8000)?(0xFFFF0000|AX):AX; 1.5151 - cycles-=3; 1.5152 - break; 1.5153 - case 0x99: case 0x299: /*CWD*/ 1.5154 - DX=(AX&0x8000)?0xFFFF:0; 1.5155 - cycles-=2; 1.5156 - break; 1.5157 - case 0x199: case 0x399: /*CDQ*/ 1.5158 - EDX=(EAX&0x80000000)?0xFFFFFFFF:0; 1.5159 - cycles-=2; 1.5160 - break; 1.5161 - case 0x9A: case 0x29A: /*CALL FAR*/ 1.5162 - tempw=getword(); 1.5163 - tempw2=getword(); if (abrt) break; 1.5164 - if (output == 3) pclog("Call far %04X:%04X\n",tempw2,tempw); 1.5165 - tempw3=CS; 1.5166 - templ2 = pc; 1.5167 - if (output) pclog("Call far %08X\n",templ2); 1.5168 - if (ssegs) ss=oldss; 1.5169 - oxpc=pc; 1.5170 - pc=tempw; 1.5171 - optype=CALL; 1.5172 - cgate32=0; 1.5173 - if (output == 3) pclog("Load CS\n"); 1.5174 - if (msw&1) loadcscall(tempw2); 1.5175 - else loadcs(tempw2); 1.5176 - if (output == 3) pclog("%i %i\n", abrt, cgate32); 1.5177 - optype=0; 1.5178 -// if (output==3) pclog("CALL FAR 16 complete\n"); 1.5179 - if (abrt) break; 1.5180 - oldss=ss; 1.5181 - if (cgate32) goto writecall32; 1.5182 - writecall16: 1.5183 - cgate16=0; 1.5184 - if (stack32) 1.5185 - { 1.5186 - writememw(ss,ESP-2,tempw3); 1.5187 - writememw(ss,ESP-4,templ2); if (abrt) break; 1.5188 - ESP-=4; 1.5189 - } 1.5190 - else 1.5191 - { 1.5192 - writememw(ss,(SP-2)&0xFFFF,tempw3); 1.5193 - if (output) pclog("Write CS to %04X:%04X\n",SS,SP-2); 1.5194 - writememw(ss,(SP-4)&0xFFFF,templ2); if (abrt) break; 1.5195 - if (output) pclog("Write PC %08X to %04X:%04X\n", templ2, SS,SP-4); 1.5196 - SP-=4; 1.5197 - } 1.5198 - cycles-=(is486)?18:17; 1.5199 - break; 1.5200 - case 0x19A: case 0x39A: /*CALL FAR*/ 1.5201 -// if (output==3) pclog("CF 1 %08X\n",pc); 1.5202 - templ=getword(); templ|=(getword()<<16); 1.5203 -// if (output==3) pclog("CF 2\n"); 1.5204 - tempw2=getword(); if (abrt) break; 1.5205 -// if (output==3) pclog("CF 3 %04X:%08X\n",tempw2,templ); 1.5206 - tempw3=CS; 1.5207 - templ2 = pc; 1.5208 - if (ssegs) ss=oldss; 1.5209 - oxpc=pc; 1.5210 - pc=templ; 1.5211 - optype=CALL; 1.5212 - cgate16=0; 1.5213 -// if (output==3) pclog("Load CS\n"); 1.5214 - if (msw&1) loadcscall(tempw2); 1.5215 - else loadcs(tempw2); 1.5216 -// if (output==3) pclog("%i %i\n",notpresent,abrt); 1.5217 - optype=0; 1.5218 -// if (output==3) pclog("CALL FAR 32 complete\n"); 1.5219 - if (abrt) break; 1.5220 - oldss=ss; 1.5221 - if (cgate16) goto writecall16; 1.5222 - writecall32: 1.5223 - cgate32=0; 1.5224 - if (stack32) 1.5225 - { 1.5226 - writememl(ss,ESP-4,tempw3); 1.5227 - writememl(ss,ESP-8,templ2); if (abrt) break; 1.5228 - if (output) pclog("Write PC %08X to %04X:%04X\n", templ2, SS,ESP-8); 1.5229 - ESP-=8; 1.5230 - } 1.5231 - else 1.5232 - { 1.5233 - writememl(ss,(SP-4)&0xFFFF,tempw3); 1.5234 - writememl(ss,(SP-8)&0xFFFF,templ2); if (abrt) break; 1.5235 - if (output) pclog("Write PC %08X to %04X:%04X\n", templ2, SS,SP-8); 1.5236 - SP-=8; 1.5237 - } 1.5238 - cycles-=(is486)?18:17; 1.5239 - break; 1.5240 - case 0x9B: case 0x19B: case 0x29B: case 0x39B: /*WAIT*/ 1.5241 - cycles-=4; 1.5242 - break; 1.5243 - case 0x9C: case 0x29C: /*PUSHF*/ 1.5244 - if (ssegs) ss=oldss; 1.5245 - if ((eflags&VM_FLAG) && (IOPL<3)) 1.5246 - { 1.5247 - x86gpf(NULL,0); 1.5248 - break; 1.5249 - } 1.5250 - if (stack32) 1.5251 - { 1.5252 - writememw(ss,ESP-2,flags); if (abrt) break; 1.5253 - ESP-=2; 1.5254 - } 1.5255 - else 1.5256 - { 1.5257 - writememw(ss,((SP-2)&0xFFFF),flags); if (abrt) break; 1.5258 - SP-=2; 1.5259 - } 1.5260 - cycles-=4; 1.5261 - break; 1.5262 - case 0x19C: case 0x39C: /*PUSHFD*/ 1.5263 -// pclog("PUSHFD %04X(%08X):%08X\n",CS,cs,pc); 1.5264 - if (ssegs) ss=oldss; 1.5265 - if ((eflags&VM_FLAG) && (IOPL<3)) 1.5266 - { 1.5267 - x86gpf(NULL,0); 1.5268 - break; 1.5269 - } 1.5270 - if (CPUID) tempw=eflags&0x24; 1.5271 - else tempw=eflags&4; 1.5272 - if (stack32) 1.5273 - { 1.5274 - writememw(ss,ESP-2,tempw); 1.5275 - writememw(ss,ESP-4,flags); if (abrt) break; 1.5276 - ESP-=4; 1.5277 -// if (output==3) pclog("Pushing %04X %04X\n",eflags,flags); 1.5278 - } 1.5279 - else 1.5280 - { 1.5281 - writememw(ss,((SP-2)&0xFFFF),tempw); 1.5282 - writememw(ss,((SP-4)&0xFFFF),flags); if (abrt) break; 1.5283 - SP-=4; 1.5284 - } 1.5285 - cycles-=4; 1.5286 - break; 1.5287 - case 0x9D: case 0x29D: /*POPF*/ 1.5288 -// if (CS!=0x21 && CS!=0xF000) pclog("POPF %04X:%04X\n",CS,pc); 1.5289 - if (ssegs) ss=oldss; 1.5290 - if ((eflags&VM_FLAG) && (IOPL<3)) 1.5291 - { 1.5292 - x86gpf(NULL,0); 1.5293 - break; 1.5294 - } 1.5295 - if (stack32) 1.5296 - { 1.5297 - tempw=readmemw(ss,ESP); if (abrt) break; 1.5298 - ESP+=2; 1.5299 - } 1.5300 - else 1.5301 - { 1.5302 - tempw=readmemw(ss,SP); if (abrt) break; 1.5303 - SP+=2; 1.5304 - } 1.5305 -// pclog("POPF! %i %i %i\n",CPL,msw&1,IOPLp); 1.5306 - if (!(CPL) || !(msw&1)) flags=(tempw&0xFFD5)|2; 1.5307 - else if (IOPLp) flags=(flags&0x3000)|(tempw&0xCFD5)|2; 1.5308 - else flags=(flags&0xF200)|(tempw&0x0DD5)|2; 1.5309 -// if (flags==0xF000) pclog("POPF - flags now F000 %04X(%06X):%04X %08X %08X %08X\n",CS,cs,pc,old8,old82,old83); 1.5310 - cycles-=5; 1.5311 - break; 1.5312 - case 0x19D: case 0x39D: /*POPFD*/ 1.5313 - if (ssegs) ss=oldss; 1.5314 - if ((eflags&VM_FLAG) && (IOPL<3)) 1.5315 - { 1.5316 - x86gpf(NULL,0); 1.5317 - break; 1.5318 - } 1.5319 - if (stack32) 1.5320 - { 1.5321 - tempw=readmemw(ss,ESP); 1.5322 - tempw2=readmemw(ss,ESP+2); if (abrt) break; 1.5323 - ESP+=4; 1.5324 - } 1.5325 - else 1.5326 - { 1.5327 - tempw=readmemw(ss,SP); 1.5328 - tempw2=readmemw(ss,SP+2); if (abrt) break; 1.5329 - SP+=4; 1.5330 - } 1.5331 -// eflags|=0x200000; 1.5332 - if (!(CPL) || !(msw&1)) flags=(tempw&0xFFD5)|2; 1.5333 - else if (IOPLp) flags=(flags&0x3000)|(tempw&0xCFD5)|2; 1.5334 - else flags=(flags&0xF200)|(tempw&0x0DD5)|2; 1.5335 - tempw2&=(is486)?0x24:0; 1.5336 - tempw2|=(eflags&3); 1.5337 - if (CPUID) eflags=tempw2&0x27; 1.5338 - else if (is486) eflags=tempw2&7; 1.5339 - else eflags=tempw2&3; 1.5340 -// if (flags==0xF000) pclog("POPF - flags now F000 %04X(%06X):%04X %08X %08X %08X\n",CS,cs,pc,old8,old82,old83); 1.5341 - cycles-=5; 1.5342 - break; 1.5343 - case 0x9E: case 0x19E: case 0x29E: case 0x39E: /*SAHF*/ 1.5344 - flags=(flags&0xFF00)|(AH&0xD5)|2; 1.5345 - cycles-=3; 1.5346 - break; 1.5347 - case 0x9F: case 0x19F: case 0x29F: case 0x39F: /*LAHF*/ 1.5348 - AH=flags&0xFF; 1.5349 - cycles-=3; 1.5350 - break; 1.5351 - 1.5352 - case 0xA0: case 0x1A0: /*MOV AL,(w)*/ 1.5353 - addr=getword(); if (abrt) break; 1.5354 - temp=readmemb(ds,addr); if (abrt) break; 1.5355 - AL=temp; 1.5356 - cycles-=(is486)?1:4; 1.5357 - break; 1.5358 - case 0x2A0: case 0x3A0: /*MOV AL,(l)*/ 1.5359 - addr=getlong(); if (abrt) break; 1.5360 - temp=readmemb(ds,addr); if (abrt) break; 1.5361 - AL=temp; 1.5362 - cycles-=(is486)?1:4; 1.5363 - break; 1.5364 - case 0xA1: /*MOV AX,(w)*/ 1.5365 - addr=getword(); if (abrt) break; 1.5366 - tempw=readmemw(ds,addr); if (abrt) break; 1.5367 - AX=tempw; 1.5368 - cycles-=(is486)?1:4; 1.5369 - break; 1.5370 - case 0x1A1: /*MOV EAX,(w)*/ 1.5371 - addr=getword(); if (abrt) break; 1.5372 - templ=readmeml(ds,addr); if (abrt) break; 1.5373 - EAX=templ; 1.5374 - cycles-=(is486)?1:4; 1.5375 - break; 1.5376 - case 0x2A1: /*MOV AX,(l)*/ 1.5377 - addr=getlong(); if (abrt) break; 1.5378 - tempw=readmemw(ds,addr); if (abrt) break; 1.5379 - AX=tempw; 1.5380 - cycles-=(is486)?1:4; 1.5381 - break; 1.5382 - case 0x3A1: /*MOV EAX,(l)*/ 1.5383 - addr=getlong(); if (abrt) break; 1.5384 - templ=readmeml(ds,addr); if (abrt) break; 1.5385 - EAX=templ; 1.5386 - cycles-=(is486)?1:4; 1.5387 - break; 1.5388 - case 0xA2: case 0x1A2: /*MOV (w),AL*/ 1.5389 - addr=getword(); if (abrt) break; 1.5390 - writememb(ds,addr,AL); 1.5391 - cycles-=(is486)?1:2; 1.5392 - break; 1.5393 - case 0x2A2: case 0x3A2: /*MOV (l),AL*/ 1.5394 - addr=getlong(); if (abrt) break; 1.5395 - writememb(ds,addr,AL); 1.5396 - cycles-=(is486)?1:2; 1.5397 - break; 1.5398 - case 0xA3: /*MOV (w),AX*/ 1.5399 - addr=getword(); if (abrt) break; 1.5400 - writememw(ds,addr,AX); 1.5401 - cycles-=(is486)?1:2; 1.5402 - break; 1.5403 - case 0x1A3: /*MOV (w),EAX*/ 1.5404 - addr=getword(); if (abrt) break; 1.5405 - writememl(ds,addr,EAX); 1.5406 - cycles-=(is486)?1:2; 1.5407 - break; 1.5408 - case 0x2A3: /*MOV (l),AX*/ 1.5409 - addr=getlong(); if (abrt) break; 1.5410 - writememw(ds,addr,AX); 1.5411 - cycles-=(is486)?1:2; 1.5412 - break; 1.5413 - case 0x3A3: /*MOV (l),EAX*/ 1.5414 - addr=getlong(); if (abrt) break; 1.5415 - writememl(ds,addr,EAX); 1.5416 - cycles-=(is486)?1:2; 1.5417 - break; 1.5418 - 1.5419 - case 0xA4: case 0x1A4: /*MOVSB*/ 1.5420 - temp=readmemb(ds,SI); if (abrt) break; 1.5421 - writememb(es,DI,temp); if (abrt) break; 1.5422 - if (flags&D_FLAG) { DI--; SI--; } 1.5423 - else { DI++; SI++; } 1.5424 - cycles-=7; 1.5425 - break; 1.5426 - case 0x2A4: case 0x3A4: /*MOVSB*/ 1.5427 - temp=readmemb(ds,ESI); if (abrt) break; 1.5428 - writememb(es,EDI,temp); if (abrt) break; 1.5429 - if (flags&D_FLAG) { EDI--; ESI--; } 1.5430 - else { EDI++; ESI++; } 1.5431 - cycles-=7; 1.5432 - break; 1.5433 - case 0xA5: /*MOVSW*/ 1.5434 - tempw=readmemw(ds,SI); if (abrt) break; 1.5435 - writememw(es,DI,tempw); if (abrt) break; 1.5436 - if (flags&D_FLAG) { DI-=2; SI-=2; } 1.5437 - else { DI+=2; SI+=2; } 1.5438 - cycles-=7; 1.5439 - break; 1.5440 - case 0x2A5: /*MOVSW*/ 1.5441 - tempw=readmemw(ds,ESI); if (abrt) break; 1.5442 - writememw(es,EDI,tempw); if (abrt) break; 1.5443 - if (flags&D_FLAG) { EDI-=2; ESI-=2; } 1.5444 - else { EDI+=2; ESI+=2; } 1.5445 - cycles-=7; 1.5446 - break; 1.5447 - case 0x1A5: /*MOVSL*/ 1.5448 - templ=readmeml(ds,SI); if (abrt) break; 1.5449 - writememl(es,DI,templ); if (abrt) break; 1.5450 - if (flags&D_FLAG) { DI-=4; SI-=4; } 1.5451 - else { DI+=4; SI+=4; } 1.5452 - cycles-=7; 1.5453 - break; 1.5454 - case 0x3A5: /*MOVSL*/ 1.5455 - templ=readmeml(ds,ESI); if (abrt) break; 1.5456 - writememl(es,EDI,templ); if (abrt) break; 1.5457 - if (flags&D_FLAG) { EDI-=4; ESI-=4; } 1.5458 - else { EDI+=4; ESI+=4; } 1.5459 - cycles-=7; 1.5460 - break; 1.5461 - case 0xA6: case 0x1A6: /*CMPSB*/ 1.5462 - temp =readmemb(ds,SI); 1.5463 - temp2=readmemb(es,DI); 1.5464 - if (abrt) break; 1.5465 - setsub8(temp,temp2); 1.5466 - if (flags&D_FLAG) { DI--; SI--; } 1.5467 - else { DI++; SI++; } 1.5468 - cycles-=(is486)?8:10; 1.5469 - break; 1.5470 - case 0x2A6: case 0x3A6: /*CMPSB*/ 1.5471 - temp =readmemb(ds,ESI); 1.5472 - temp2=readmemb(es,EDI); 1.5473 - if (abrt) break; 1.5474 - setsub8(temp,temp2); 1.5475 - if (flags&D_FLAG) { EDI--; ESI--; } 1.5476 - else { EDI++; ESI++; } 1.5477 - cycles-=(is486)?8:10; 1.5478 - break; 1.5479 - case 0xA7: /*CMPSW*/ 1.5480 - tempw =readmemw(ds,SI); 1.5481 - tempw2=readmemw(es,DI); 1.5482 - if (abrt) break; 1.5483 - setsub16(tempw,tempw2); 1.5484 - if (flags&D_FLAG) { DI-=2; SI-=2; } 1.5485 - else { DI+=2; SI+=2; } 1.5486 - cycles-=(is486)?8:10; 1.5487 - break; 1.5488 - case 0x1A7: /*CMPSL*/ 1.5489 - templ =readmeml(ds,SI); 1.5490 - templ2=readmeml(es,DI); 1.5491 - if (abrt) break; 1.5492 - setsub32(templ,templ2); 1.5493 - if (flags&D_FLAG) { DI-=4; SI-=4; } 1.5494 - else { DI+=4; SI+=4; } 1.5495 - cycles-=(is486)?8:10; 1.5496 - break; 1.5497 - case 0x2A7: /*CMPSW*/ 1.5498 - tempw =readmemw(ds,ESI); 1.5499 - tempw2=readmemw(es,EDI); 1.5500 - if (abrt) break; 1.5501 - setsub16(tempw,tempw2); 1.5502 - if (flags&D_FLAG) { EDI-=2; ESI-=2; } 1.5503 - else { EDI+=2; ESI+=2; } 1.5504 - cycles-=(is486)?8:10; 1.5505 - break; 1.5506 - case 0x3A7: /*CMPSL*/ 1.5507 - templ =readmeml(ds,ESI); 1.5508 - templ2=readmeml(es,EDI); 1.5509 - if (abrt) break; 1.5510 - setsub32(templ,templ2); 1.5511 - if (flags&D_FLAG) { EDI-=4; ESI-=4; } 1.5512 - else { EDI+=4; ESI+=4; } 1.5513 - cycles-=(is486)?8:10; 1.5514 - break; 1.5515 - case 0xA8: case 0x1A8: case 0x2A8: case 0x3A8: /*TEST AL,#8*/ 1.5516 - temp=getbytef(); 1.5517 - setznp8(AL&temp); 1.5518 - cycles -= timing_rr; 1.5519 - break; 1.5520 - case 0xA9: case 0x2A9: /*TEST AX,#16*/ 1.5521 - tempw=getwordf(); 1.5522 - setznp16(AX&tempw); 1.5523 - cycles -= timing_rr; 1.5524 - break; 1.5525 - case 0x1A9: case 0x3A9: /*TEST EAX,#32*/ 1.5526 - templ=getlong(); if (abrt) break; 1.5527 - setznp32(EAX&templ); 1.5528 - cycles -= timing_rr; 1.5529 - break; 1.5530 - case 0xAA: case 0x1AA: /*STOSB*/ 1.5531 - writememb(es,DI,AL); if (abrt) break; 1.5532 - if (flags&D_FLAG) DI--; 1.5533 - else DI++; 1.5534 - cycles-=4; 1.5535 - break; 1.5536 - case 0x2AA: case 0x3AA: /*STOSB*/ 1.5537 - writememb(es,EDI,AL); if (abrt) break; 1.5538 - if (flags&D_FLAG) EDI--; 1.5539 - else EDI++; 1.5540 - cycles-=4; 1.5541 - break; 1.5542 - case 0xAB: /*STOSW*/ 1.5543 - writememw(es,DI,AX); if (abrt) break; 1.5544 - if (flags&D_FLAG) DI-=2; 1.5545 - else DI+=2; 1.5546 - cycles-=4; 1.5547 - break; 1.5548 - case 0x1AB: /*STOSL*/ 1.5549 - writememl(es,DI,EAX); if (abrt) break; 1.5550 - if (flags&D_FLAG) DI-=4; 1.5551 - else DI+=4; 1.5552 - cycles-=4; 1.5553 - break; 1.5554 - case 0x2AB: /*STOSW*/ 1.5555 - writememw(es,EDI,AX); if (abrt) break; 1.5556 - if (flags&D_FLAG) EDI-=2; 1.5557 - else EDI+=2; 1.5558 - cycles-=4; 1.5559 - break; 1.5560 - case 0x3AB: /*STOSL*/ 1.5561 - writememl(es,EDI,EAX); if (abrt) break; 1.5562 - if (flags&D_FLAG) EDI-=4; 1.5563 - else EDI+=4; 1.5564 - cycles-=4; 1.5565 - break; 1.5566 - case 0xAC: case 0x1AC: /*LODSB*/ 1.5567 - temp=readmemb(ds,SI); 1.5568 - if (abrt) break; 1.5569 - AL=temp; 1.5570 -// if (output==3) pclog("LODSB %02X from %05X:%04X\n",AL,ds,SI); 1.5571 - if (flags&D_FLAG) SI--; 1.5572 - else SI++; 1.5573 - cycles-=5; 1.5574 - break; 1.5575 - case 0x2AC: case 0x3AC: /*LODSB*/ 1.5576 - temp=readmemb(ds,ESI); 1.5577 - if (abrt) break; 1.5578 - AL=temp; 1.5579 - if (flags&D_FLAG) ESI--; 1.5580 - else ESI++; 1.5581 - cycles-=5; 1.5582 - break; 1.5583 - case 0xAD: /*LODSW*/ 1.5584 - tempw=readmemw(ds,SI); 1.5585 - if (abrt) break; 1.5586 - AX=tempw; 1.5587 -// if (output) pclog("Load from %05X:%04X\n",ds,SI); 1.5588 - if (flags&D_FLAG) SI-=2; 1.5589 - else SI+=2; 1.5590 - cycles-=5; 1.5591 - break; 1.5592 - case 0x1AD: /*LODSL*/ 1.5593 - templ=readmeml(ds,SI); 1.5594 - if (abrt) break; 1.5595 - EAX=templ; 1.5596 - if (flags&D_FLAG) SI-=4; 1.5597 - else SI+=4; 1.5598 - cycles-=5; 1.5599 - break; 1.5600 - case 0x2AD: /*LODSW*/ 1.5601 - tempw=readmemw(ds,ESI); 1.5602 - if (abrt) break; 1.5603 - AX=tempw; 1.5604 - if (flags&D_FLAG) ESI-=2; 1.5605 - else ESI+=2; 1.5606 - cycles-=5; 1.5607 - break; 1.5608 - case 0x3AD: /*LODSL*/ 1.5609 - templ=readmeml(ds,ESI); 1.5610 - if (abrt) break; 1.5611 - EAX=templ; 1.5612 - if (flags&D_FLAG) ESI-=4; 1.5613 - else ESI+=4; 1.5614 - cycles-=5; 1.5615 - break; 1.5616 - case 0xAE: case 0x1AE: /*SCASB*/ 1.5617 - temp=readmemb(es,DI); 1.5618 - if (abrt) break; 1.5619 - setsub8(AL,temp); 1.5620 - if (flags&D_FLAG) DI--; 1.5621 - else DI++; 1.5622 - cycles-=7; 1.5623 - break; 1.5624 - case 0x2AE: case 0x3AE: /*SCASB*/ 1.5625 - temp=readmemb(es,EDI); 1.5626 - if (abrt) break; 1.5627 - setsub8(AL,temp); 1.5628 - if (flags&D_FLAG) EDI--; 1.5629 - else EDI++; 1.5630 - cycles-=7; 1.5631 - break; 1.5632 - case 0xAF: /*SCASW*/ 1.5633 - tempw=readmemw(es,DI); 1.5634 - if (abrt) break; 1.5635 - setsub16(AX,tempw); 1.5636 - if (flags&D_FLAG) DI-=2; 1.5637 - else DI+=2; 1.5638 - cycles-=7; 1.5639 - break; 1.5640 - case 0x1AF: /*SCASL*/ 1.5641 - templ=readmeml(es,DI); 1.5642 - if (abrt) break; 1.5643 - setsub32(EAX,templ); 1.5644 - if (flags&D_FLAG) DI-=4; 1.5645 - else DI+=4; 1.5646 - cycles-=7; 1.5647 - break; 1.5648 - case 0x2AF: /*SCASW*/ 1.5649 - tempw=readmemw(es,EDI); 1.5650 - if (abrt) break; 1.5651 - setsub16(AX,tempw); 1.5652 - if (flags&D_FLAG) EDI-=2; 1.5653 - else EDI+=2; 1.5654 - cycles-=7; 1.5655 - break; 1.5656 - case 0x3AF: /*SCASL*/ 1.5657 - templ=readmeml(es,EDI); 1.5658 - if (abrt) break; 1.5659 - setsub32(EAX,templ); 1.5660 - if (flags&D_FLAG) EDI-=4; 1.5661 - else EDI+=4; 1.5662 - cycles-=7; 1.5663 - break; 1.5664 - 1.5665 - case 0xB0: case 0x1B0: case 0x2B0: case 0x3B0: /*MOV AL,#8*/ 1.5666 - AL=getbytef(); 1.5667 - cycles -= timing_rr; 1.5668 - break; 1.5669 - case 0xB1: case 0x1B1: case 0x2B1: case 0x3B1: /*MOV CL,#8*/ 1.5670 - CL=getbytef(); 1.5671 - cycles -= timing_rr; 1.5672 - break; 1.5673 - case 0xB2: case 0x1B2: case 0x2B2: case 0x3B2: /*MOV DL,#8*/ 1.5674 - DL=getbytef(); 1.5675 - cycles -= timing_rr; 1.5676 - break; 1.5677 - case 0xB3: case 0x1B3: case 0x2B3: case 0x3B3: /*MOV BL,#8*/ 1.5678 - BL=getbytef(); 1.5679 - cycles -= timing_rr; 1.5680 - break; 1.5681 - case 0xB4: case 0x1B4: case 0x2B4: case 0x3B4: /*MOV AH,#8*/ 1.5682 - AH=getbytef(); 1.5683 - cycles -= timing_rr; 1.5684 - break; 1.5685 - case 0xB5: case 0x1B5: case 0x2B5: case 0x3B5: /*MOV CH,#8*/ 1.5686 - CH=getbytef(); 1.5687 - cycles -= timing_rr; 1.5688 - break; 1.5689 - case 0xB6: case 0x1B6: case 0x2B6: case 0x3B6: /*MOV DH,#8*/ 1.5690 - DH=getbytef(); 1.5691 - cycles -= timing_rr; 1.5692 - break; 1.5693 - case 0xB7: case 0x1B7: case 0x2B7: case 0x3B7: /*MOV BH,#8*/ 1.5694 - BH=getbytef(); 1.5695 - cycles -= timing_rr; 1.5696 - break; 1.5697 - case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV reg,#16*/ 1.5698 - case 0xBC: case 0xBD: case 0xBE: case 0xBF: 1.5699 - case 0x2B8: case 0x2B9: case 0x2BA: case 0x2BB: 1.5700 - case 0x2BC: case 0x2BD: case 0x2BE: case 0x2BF: 1.5701 - regs[opcode&7].w=getwordf(); 1.5702 - cycles -= timing_rr; 1.5703 - break; 1.5704 - case 0x1B8: case 0x1B9: case 0x1BA: case 0x1BB: /*MOV reg,#32*/ 1.5705 - case 0x1BC: case 0x1BD: case 0x1BE: case 0x1BF: 1.5706 - case 0x3B8: case 0x3B9: case 0x3BA: case 0x3BB: 1.5707 - case 0x3BC: case 0x3BD: case 0x3BE: case 0x3BF: 1.5708 - templ=getlong(); if (abrt) break; 1.5709 - regs[opcode&7].l=templ; 1.5710 - cycles -= timing_rr; 1.5711 - break; 1.5712 - 1.5713 - case 0xC0: case 0x1C0: case 0x2C0: case 0x3C0: 1.5714 - fetchea(); 1.5715 - c=readmemb(cs,pc); pc++; 1.5716 - temp=geteab(); if (abrt) break; 1.5717 - c&=31; 1.5718 - if (!c) break; 1.5719 - switch (rmdat&0x38) 1.5720 - { 1.5721 - case 0x00: /*ROL b,CL*/ 1.5722 - while (c>0) 1.5723 - { 1.5724 - temp2=(temp&0x80)?1:0; 1.5725 - temp=(temp<<1)|temp2; 1.5726 - c--; 1.5727 - } 1.5728 - seteab(temp); if (abrt) break; 1.5729 - flags&=~(C_FLAG|V_FLAG); 1.5730 - if (temp2) flags|=C_FLAG; 1.5731 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.5732 - cycles-=((mod==3)?3:7); 1.5733 - break; 1.5734 - case 0x08: /*ROR b,CL*/ 1.5735 - while (c>0) 1.5736 - { 1.5737 - temp2=temp&1; 1.5738 - temp>>=1; 1.5739 - if (temp2) temp|=0x80; 1.5740 - c--; 1.5741 - } 1.5742 - seteab(temp); if (abrt) break; 1.5743 - flags&=~(C_FLAG|V_FLAG); 1.5744 - if (temp2) flags|=C_FLAG; 1.5745 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.5746 - cycles-=((mod==3)?3:7); 1.5747 - break; 1.5748 - case 0x10: /*RCL b,CL*/ 1.5749 - temp2=flags&C_FLAG; 1.5750 - while (c>0) 1.5751 - { 1.5752 - tempc=(temp2)?1:0; 1.5753 - temp2=temp&0x80; 1.5754 - temp=(temp<<1)|tempc; 1.5755 - c--; 1.5756 - if (is486) cycles--; 1.5757 - } 1.5758 - seteab(temp); if (abrt) break; 1.5759 - flags&=~(C_FLAG|V_FLAG); 1.5760 - if (temp2) flags|=C_FLAG; 1.5761 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.5762 - cycles-=((mod==3)?9:10); 1.5763 - break; 1.5764 - case 0x18: /*RCR b,CL*/ 1.5765 - temp2=flags&C_FLAG; 1.5766 - while (c>0) 1.5767 - { 1.5768 - tempc=(temp2)?0x80:0; 1.5769 - temp2=temp&1; 1.5770 - temp=(temp>>1)|tempc; 1.5771 - c--; 1.5772 - if (is486) cycles--; 1.5773 - } 1.5774 - seteab(temp); if (abrt) break; 1.5775 - flags&=~(C_FLAG|V_FLAG); 1.5776 - if (temp2) flags|=C_FLAG; 1.5777 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.5778 - cycles-=((mod==3)?9:10); 1.5779 - break; 1.5780 - case 0x20: case 0x30: /*SHL b,CL*/ 1.5781 - seteab(temp<<c); if (abrt) break; 1.5782 - setznp8(temp<<c); 1.5783 - if ((temp<<(c-1))&0x80) flags|=C_FLAG; 1.5784 - if (((temp<<c)^(temp<<(c-1)))&0x80) flags|=V_FLAG; 1.5785 - cycles-=((mod==3)?3:7); 1.5786 - break; 1.5787 - case 0x28: /*SHR b,CL*/ 1.5788 - seteab(temp>>c); if (abrt) break; 1.5789 - setznp8(temp>>c); 1.5790 - if ((temp>>(c-1))&1) flags|=C_FLAG; 1.5791 - if (c==1 && temp&0x80) flags|=V_FLAG; 1.5792 - cycles-=((mod==3)?3:7); 1.5793 - break; 1.5794 - case 0x38: /*SAR b,CL*/ 1.5795 - tempc=((temp>>(c-1))&1); 1.5796 - while (c>0) 1.5797 - { 1.5798 - temp>>=1; 1.5799 - if (temp&0x40) temp|=0x80; 1.5800 - c--; 1.5801 - } 1.5802 - seteab(temp); if (abrt) break; 1.5803 - setznp8(temp); 1.5804 - if (tempc) flags|=C_FLAG; 1.5805 - cycles-=((mod==3)?3:7); 1.5806 - break; 1.5807 - } 1.5808 - break; 1.5809 - 1.5810 - case 0xC1: case 0x2C1: 1.5811 - fetchea(); 1.5812 - c=readmemb(cs,pc)&31; pc++; 1.5813 - tempw=geteaw(); if (abrt) break; 1.5814 - if (!c) break; 1.5815 - switch (rmdat&0x38) 1.5816 - { 1.5817 - case 0x00: /*ROL w,CL*/ 1.5818 - while (c>0) 1.5819 - { 1.5820 - temp=(tempw&0x8000)?1:0; 1.5821 - tempw=(tempw<<1)|temp; 1.5822 - c--; 1.5823 - } 1.5824 - seteaw(tempw); if (abrt) break; 1.5825 - flags&=~(C_FLAG|V_FLAG); 1.5826 - if (temp) flags|=C_FLAG; 1.5827 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.5828 - cycles-=((mod==3)?3:7); 1.5829 - break; 1.5830 - case 0x08: /*ROR w,CL*/ 1.5831 - while (c>0) 1.5832 - { 1.5833 - tempw2=(tempw&1)?0x8000:0; 1.5834 - tempw=(tempw>>1)|tempw2; 1.5835 - c--; 1.5836 - } 1.5837 - seteaw(tempw); if (abrt) break; 1.5838 - flags&=~(C_FLAG|V_FLAG); 1.5839 - if (tempw2) flags|=C_FLAG; 1.5840 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.5841 - cycles-=((mod==3)?3:7); 1.5842 - break; 1.5843 - case 0x10: /*RCL w,CL*/ 1.5844 - temp2=flags&C_FLAG; 1.5845 - while (c>0) 1.5846 - { 1.5847 - tempc=(temp2)?1:0; 1.5848 - temp2=(tempw>>15); 1.5849 - tempw=(tempw<<1)|tempc; 1.5850 - c--; 1.5851 - if (is486) cycles--; 1.5852 - } 1.5853 - seteaw(tempw); if (abrt) break; 1.5854 - flags&=~(C_FLAG|V_FLAG); 1.5855 - if (temp2) flags|=C_FLAG; 1.5856 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.5857 - cycles-=((mod==3)?9:10); 1.5858 - break; 1.5859 - case 0x18: /*RCR w,CL*/ 1.5860 - temp2=flags&C_FLAG; 1.5861 - while (c>0) 1.5862 - { 1.5863 - tempc=(temp2)?0x8000:0; 1.5864 - temp2=tempw&1; 1.5865 - tempw=(tempw>>1)|tempc; 1.5866 - c--; 1.5867 - if (is486) cycles--; 1.5868 - } 1.5869 - seteaw(tempw); if (abrt) break; 1.5870 - flags&=~(C_FLAG|V_FLAG); 1.5871 - if (temp2) flags|=C_FLAG; 1.5872 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.5873 - cycles-=((mod==3)?9:10); 1.5874 - break; 1.5875 - 1.5876 - case 0x20: case 0x30: /*SHL w,CL*/ 1.5877 - seteaw(tempw<<c); if (abrt) break; 1.5878 - setznp16(tempw<<c); 1.5879 - if ((tempw<<(c-1))&0x8000) flags|=C_FLAG; 1.5880 - if (((tempw<<c)^(tempw<<(c-1)))&0x8000) flags|=V_FLAG; 1.5881 - cycles-=((mod==3)?3:7); 1.5882 - break; 1.5883 - 1.5884 - case 0x28: /*SHR w,CL*/ 1.5885 - seteaw(tempw>>c); if (abrt) break; 1.5886 - setznp16(tempw>>c); 1.5887 - if ((tempw>>(c-1))&1) flags|=C_FLAG; 1.5888 - if (c==1 && tempw&0x8000) flags|=V_FLAG; 1.5889 - cycles-=((mod==3)?3:7); 1.5890 - break; 1.5891 - 1.5892 - case 0x38: /*SAR w,CL*/ 1.5893 - tempw2=tempw&0x8000; 1.5894 - tempc=(tempw>>(c-1))&1; 1.5895 - while (c>0) 1.5896 - { 1.5897 - tempw=(tempw>>1)|tempw2; 1.5898 - c--; 1.5899 - } 1.5900 - seteaw(tempw); if (abrt) break; 1.5901 - setznp16(tempw); 1.5902 - if (tempc) flags|=C_FLAG; 1.5903 - cycles-=((mod==3)?3:7); 1.5904 - break; 1.5905 - } 1.5906 - break; 1.5907 - case 0x1C1: case 0x3C1: 1.5908 - fetchea(); 1.5909 - c=readmemb(cs,pc); pc++; 1.5910 - c&=31; 1.5911 - templ=geteal(); if (abrt) break; 1.5912 - if (!c) break; 1.5913 - switch (rmdat&0x38) 1.5914 - { 1.5915 - case 0x00: /*ROL l,CL*/ 1.5916 - while (c>0) 1.5917 - { 1.5918 - temp=(templ&0x80000000)?1:0; 1.5919 - templ=(templ<<1)|temp; 1.5920 - c--; 1.5921 - } 1.5922 - seteal(templ); if (abrt) break; 1.5923 - flags&=~(C_FLAG|V_FLAG); 1.5924 - if (temp) flags|=C_FLAG; 1.5925 - if ((flags&C_FLAG)^(templ>>31)) flags|=V_FLAG; 1.5926 - cycles-=((mod==3)?9:10); 1.5927 - break; 1.5928 - case 0x08: /*ROR l,CL*/ 1.5929 - while (c>0) 1.5930 - { 1.5931 - templ2=(templ&1)?0x80000000:0; 1.5932 - templ=(templ>>1)|templ2; 1.5933 - c--; 1.5934 - } 1.5935 - seteal(templ); if (abrt) break; 1.5936 - flags&=~(C_FLAG|V_FLAG); 1.5937 - if (templ2) flags|=C_FLAG; 1.5938 - if ((templ^(templ>>1))&0x40000000) flags|=V_FLAG; 1.5939 - cycles-=((mod==3)?9:10); 1.5940 - break; 1.5941 - case 0x10: /*RCL l,CL*/ 1.5942 - temp2=flags&C_FLAG; 1.5943 - while (c>0) 1.5944 - { 1.5945 - tempc=(flags&C_FLAG)?1:0; 1.5946 - temp2=templ>>31; 1.5947 - templ=(templ<<1)|tempc; 1.5948 - c--; 1.5949 - if (is486) cycles--; 1.5950 - } 1.5951 - seteal(templ); if (abrt) break; 1.5952 - flags&=~(C_FLAG|V_FLAG); 1.5953 - if (temp2) flags|=C_FLAG; 1.5954 - if ((flags&C_FLAG)^(templ>>31)) flags|=V_FLAG; 1.5955 - cycles-=((mod==3)?9:10); 1.5956 - break; 1.5957 - case 0x18: /*RCR l,CL*/ 1.5958 - temp2=flags&C_FLAG; 1.5959 - while (c>0) 1.5960 - { 1.5961 - tempc=(temp2)?0x80000000:0; 1.5962 - temp2=templ&1; 1.5963 - templ=(templ>>1)|tempc; 1.5964 - c--; 1.5965 - if (is486) cycles--; 1.5966 - } 1.5967 - seteal(templ); if (abrt) break; 1.5968 - flags&=~(C_FLAG|V_FLAG); 1.5969 - if (temp2) flags|=C_FLAG; 1.5970 - if ((templ^(templ>>1))&0x40000000) flags|=V_FLAG; 1.5971 - cycles-=((mod==3)?9:10); 1.5972 - break; 1.5973 - 1.5974 - case 0x20: case 0x30: /*SHL l,CL*/ 1.5975 - seteal(templ<<c); if (abrt) break; 1.5976 - setznp32(templ<<c); 1.5977 - if ((templ<<(c-1))&0x80000000) flags|=C_FLAG; 1.5978 - if (((templ<<c)^(templ<<(c-1)))&0x80000000) flags|=V_FLAG; 1.5979 - cycles-=((mod==3)?3:7); 1.5980 - break; 1.5981 - 1.5982 - case 0x28: /*SHR l,CL*/ 1.5983 - seteal(templ>>c); if (abrt) break; 1.5984 - setznp32(templ>>c); 1.5985 - if ((templ>>(c-1))&1) flags|=C_FLAG; 1.5986 - if (c==1 && templ&0x80000000) flags|=V_FLAG; 1.5987 - cycles-=((mod==3)?3:7); 1.5988 - break; 1.5989 - 1.5990 - case 0x38: /*SAR l,CL*/ 1.5991 - templ2=templ&0x80000000; 1.5992 - tempc=(templ>>(c-1))&1; 1.5993 - while (c>0) 1.5994 - { 1.5995 - templ=(templ>>1)|templ2; 1.5996 - c--; 1.5997 - } 1.5998 - seteal(templ); if (abrt) break; 1.5999 - setznp32(templ); 1.6000 - if (tempc) flags|=C_FLAG; 1.6001 - cycles-=((mod==3)?3:7); 1.6002 - break; 1.6003 - } 1.6004 - break; 1.6005 - 1.6006 - 1.6007 - case 0xC2: case 0x2C2: /*RET*/ 1.6008 - tempw=getword(); 1.6009 - if (ssegs) ss=oldss; 1.6010 - if (stack32) 1.6011 - { 1.6012 - tempw2=readmemw(ss,ESP); if (abrt) break; 1.6013 - ESP+=2+tempw; 1.6014 - } 1.6015 - else 1.6016 - { 1.6017 - tempw2=readmemw(ss,SP); if (abrt) break; 1.6018 - SP+=2+tempw; 1.6019 - } 1.6020 - pc=tempw2; 1.6021 - cycles-=(is486)?5:10; 1.6022 - break; 1.6023 - case 0x1C2: case 0x3C2: /*RET*/ 1.6024 - tempw=getword(); 1.6025 - if (ssegs) ss=oldss; 1.6026 - if (stack32) 1.6027 - { 1.6028 - templ=readmeml(ss,ESP); if (abrt) break; 1.6029 - ESP+=4+tempw; 1.6030 - } 1.6031 - else 1.6032 - { 1.6033 - templ=readmeml(ss,SP); if (abrt) break; 1.6034 - SP+=4+tempw; 1.6035 - } 1.6036 - pc=templ; 1.6037 - cycles-=(is486)?5:10; 1.6038 - break; 1.6039 - case 0xC3: case 0x2C3: /*RET*/ 1.6040 - if (ssegs) ss=oldss; 1.6041 - if (stack32) 1.6042 - { 1.6043 - tempw=readmemw(ss,ESP); if (abrt) break; 1.6044 - ESP+=2; 1.6045 - } 1.6046 - else 1.6047 - { 1.6048 - tempw=readmemw(ss,SP); if (abrt) break; 1.6049 - SP+=2; 1.6050 - } 1.6051 - pc=tempw; 1.6052 - cycles-=(is486)?5:10; 1.6053 - break; 1.6054 - case 0x1C3: case 0x3C3: /*RET*/ 1.6055 - if (ssegs) ss=oldss; 1.6056 - if (stack32) 1.6057 - { 1.6058 - templ=readmeml(ss,ESP); if (abrt) break; 1.6059 - ESP+=4; 1.6060 - } 1.6061 - else 1.6062 - { 1.6063 - templ=readmeml(ss,SP); if (abrt) break; 1.6064 - SP+=4; 1.6065 - } 1.6066 - pc=templ; 1.6067 - cycles-=(is486)?5:10; 1.6068 - break; 1.6069 - case 0xC4: case 0x2C4: /*LES*/ 1.6070 - fetchea(); 1.6071 - tempw2=readmemw(easeg,eaaddr); 1.6072 - tempw=readmemw(easeg,eaaddr+2); 1.6073 -// if (output==3) pclog("LES %04X:%08X %04X:%08X\n",easeg,eaaddr,tempw,tempw2); 1.6074 - if (abrt) break; 1.6075 - loadseg(tempw,&_es); 1.6076 - if (abrt) break; 1.6077 - regs[reg].w=tempw2; 1.6078 -// if (output==3) pclog("LES complete\n"); 1.6079 -// if (!ES) pclog("LES=0 %04X(%06X):%04X\n",CS,cs,pc); 1.6080 -// if (cr0&1) pclog("ES loaded with %04X %04X(%08X):%08X\n",tempw,CS,cs,pc); 1.6081 - cycles-=7; 1.6082 - break; 1.6083 - case 0x1C4: case 0x3C4: /*LES*/ 1.6084 - fetchea(); 1.6085 - templ=readmeml(easeg,eaaddr); 1.6086 - tempw=readmemw(easeg,eaaddr+4); 1.6087 - if (abrt) break; 1.6088 - loadseg(tempw,&_es); 1.6089 - if (abrt) break; 1.6090 - regs[reg].l=templ; 1.6091 - cycles-=7; 1.6092 - break; 1.6093 - case 0xC5: case 0x2C5: /*LDS*/ 1.6094 - fetchea(); 1.6095 - tempw2=readmemw(easeg,eaaddr); 1.6096 - tempw=readmemw(easeg,eaaddr+2); 1.6097 - if (abrt) break; 1.6098 - loadseg(tempw,&_ds); 1.6099 - if (abrt) break; 1.6100 - if (ssegs) oldds=ds; 1.6101 - regs[reg].w=tempw2; 1.6102 - cycles-=7; 1.6103 - break; 1.6104 - case 0x1C5: case 0x3C5: /*LDS*/ 1.6105 - fetchea(); 1.6106 - templ=readmeml(easeg,eaaddr); 1.6107 - tempw=readmemw(easeg,eaaddr+4); 1.6108 - if (abrt) break; 1.6109 - loadseg(tempw,&_ds); 1.6110 - if (abrt) break; 1.6111 - if (ssegs) oldds=ds; 1.6112 - regs[reg].l=templ; 1.6113 - cycles-=7; 1.6114 - break; 1.6115 - case 0xC6: case 0x1C6: case 0x2C6: case 0x3C6: /*MOV b,#8*/ 1.6116 - fetchea(); 1.6117 - temp=readmemb(cs,pc); pc++; if (abrt) break; 1.6118 - seteab(temp); 1.6119 - cycles -= timing_rr; 1.6120 - break; 1.6121 - case 0xC7: case 0x2C7: /*MOV w,#16*/ 1.6122 - fetchea(); 1.6123 - tempw=getword(); if (abrt) break; 1.6124 - seteaw(tempw); 1.6125 - cycles -= timing_rr; 1.6126 - break; 1.6127 - case 0x1C7: case 0x3C7: /*MOV l,#32*/ 1.6128 - fetchea(); 1.6129 - templ=getlong(); if (abrt) break; 1.6130 - seteal(templ); 1.6131 - cycles -= timing_rr; 1.6132 - break; 1.6133 - case 0xC8: case 0x2C8: /*ENTER*/ 1.6134 - tempw2=getword(); 1.6135 - tempi=readmemb(cs,pc); pc++; 1.6136 - templ=EBP; 1.6137 - if (stack32) { writememw(ss,(ESP-2),BP); if (abrt) break; ESP-=2; } 1.6138 - else { writememw(ss,((SP-2)&0xFFFF),BP); if (abrt) break; SP-=2; } 1.6139 - templ2=ESP; 1.6140 - if (tempi>0) 1.6141 - { 1.6142 - while (--tempi) 1.6143 - { 1.6144 - EBP-=2; 1.6145 - if (stack32) tempw=readmemw(ss,EBP); 1.6146 - else tempw=readmemw(ss,BP); 1.6147 - if (abrt) { ESP=templ2; EBP=templ; break; } 1.6148 - if (stack32) { writememw(ss,(ESP-2),tempw); ESP-=2; } 1.6149 - else { writememw(ss,((SP-2)&0xFFFF),tempw); SP-=2; } 1.6150 - if (abrt) { ESP=templ2; EBP=templ; break; } 1.6151 - cycles-=(is486)?3:4; 1.6152 - } 1.6153 - if (stack32) { writememw(ss,(ESP-2),templ2); ESP-=2; } 1.6154 - else { writememw(ss,((SP-2)&0xFFFF),templ2); SP-=2; } 1.6155 - if (abrt) { ESP=templ2; EBP=templ; break; } 1.6156 - cycles-=(is486)?3:5; 1.6157 - } 1.6158 - BP = templ2; 1.6159 - if (stack32) ESP-=tempw2; 1.6160 - else SP-=tempw2; 1.6161 - cycles-=(is486)?14:10; 1.6162 -// if (cr0&1) pclog("BP %04X\n",BP); 1.6163 -// if (output==3) pclog("\n"); 1.6164 - break; 1.6165 - case 0x1C8: case 0x3C8: /*ENTER*/ 1.6166 -// if (output==1 && SS==0xA0) 1.6167 -// { 1.6168 -// enters++; 1.6169 -// for (ec=0;ec<enters;ec++) pclog(" "); 1.6170 -// pclog("ENTER %02X %04X %04X %i\n",SS,BP,SP,eflags&VM_FLAG); 1.6171 -// } 1.6172 - tempw=getword(); 1.6173 - tempi=readmemb(cs,pc); pc++; 1.6174 - if (stack32) { writememl(ss,(ESP-4),EBP); if (abrt) break; ESP-=4; } 1.6175 - else { writememl(ss,((SP-4)&0xFFFF),EBP); if (abrt) break; SP-=4; } 1.6176 - templ2=ESP; templ3=EBP; 1.6177 - if (tempi>0) 1.6178 - { 1.6179 - while (--tempi) 1.6180 - { 1.6181 - EBP-=4; 1.6182 - if (stack32) templ=readmeml(ss,EBP); 1.6183 - else templ=readmeml(ss,BP); 1.6184 - if (abrt) { ESP=templ2; EBP=templ3; break; } 1.6185 - if (stack32) { writememl(ss,(ESP-4),templ); ESP-=4; } 1.6186 - else { writememl(ss,((SP-4)&0xFFFF),templ); SP-=4; } 1.6187 - if (abrt) { ESP=templ2; EBP=templ3; break; } 1.6188 - cycles-=(is486)?3:4; 1.6189 - } 1.6190 - if (stack32) { writememl(ss,(ESP-4),templ2); ESP-=4; } 1.6191 - else { writememl(ss,((SP-4)&0xFFFF),templ2); SP-=4; } 1.6192 - if (abrt) { ESP=templ2; EBP=templ3; break; } 1.6193 - cycles-=(is486)?3:5; 1.6194 - } 1.6195 - EBP=templ2; 1.6196 - if (stack32) ESP-=tempw; 1.6197 - else SP-=tempw; 1.6198 - cycles-=(is486)?14:10; 1.6199 -// if (output==3) pclog("\n"); 1.6200 - break; 1.6201 - case 0xC9: case 0x2C9: /*LEAVE*/ 1.6202 - templ=ESP; 1.6203 - SP=BP; 1.6204 - if (stack32) { tempw=readmemw(ss,ESP); ESP+=2; } 1.6205 - else { tempw=readmemw(ss,SP); SP+=2; } 1.6206 - if (abrt) { ESP=templ; break; } 1.6207 - BP=tempw; 1.6208 - cycles-=4; 1.6209 -// if (output==1 && SS==0xA0) 1.6210 -// { 1.6211 -// for (ec=0;ec<enters;ec++) pclog(" "); 1.6212 -// pclog("LEAVE %02X %04X %04X %i\n",SS,BP,SP,eflags&VM_FLAG); 1.6213 -// enters--; 1.6214 -// } 1.6215 -// if (output==3) pclog("\n"); 1.6216 - break; 1.6217 - case 0x3C9: case 0x1C9: /*LEAVE*/ 1.6218 - templ=ESP; 1.6219 - ESP=EBP; 1.6220 - if (stack32) { templ2=readmeml(ss,ESP); ESP+=4; } 1.6221 - else { templ2=readmeml(ss,SP); SP+=4; } 1.6222 - if (abrt) { ESP=templ; break; } 1.6223 - EBP=templ2; 1.6224 - cycles-=4; 1.6225 -// if (output==1 && SS==0xA0) 1.6226 -// { 1.6227 -// for (ec=0;ec<enters;ec++) pclog(" "); 1.6228 -// pclog("LEAVE %02X %04X %04X %i\n",SS,BP,SP,eflags&VM_FLAG); 1.6229 -// enters--; 1.6230 -// } 1.6231 -// if (output==3) pclog("\n"); 1.6232 - break; 1.6233 - case 0xCA: case 0x2CA: /*RETF*/ 1.6234 - tempw=getword(); 1.6235 - if ((msw&1) && !(eflags&VM_FLAG)) 1.6236 - { 1.6237 - pmoderetf(0,tempw); 1.6238 - break; 1.6239 - } 1.6240 - tempw2=CPL; 1.6241 - if (ssegs) ss=oldss; 1.6242 - oxpc=pc; 1.6243 - if (stack32) 1.6244 - { 1.6245 - pc=readmemw(ss,ESP); 1.6246 - loadcs(readmemw(ss,ESP+2)); 1.6247 - } 1.6248 - else 1.6249 - { 1.6250 - pc=readmemw(ss,SP); 1.6251 - loadcs(readmemw(ss,SP+2)); 1.6252 - } 1.6253 - if (abrt) break; 1.6254 - if (stack32) ESP+=4+tempw; 1.6255 - else SP+=4+tempw; 1.6256 - cycles-=(is486)?13:18; 1.6257 - break; 1.6258 - case 0x1CA: case 0x3CA: /*RETF*/ 1.6259 - tempw=getword(); 1.6260 - if ((msw&1) && !(eflags&VM_FLAG)) 1.6261 - { 1.6262 - pmoderetf(1,tempw); 1.6263 - break; 1.6264 - } 1.6265 - tempw2=CPL; 1.6266 - if (ssegs) ss=oldss; 1.6267 - oxpc=pc; 1.6268 - if (stack32) 1.6269 - { 1.6270 - pc=readmeml(ss,ESP); 1.6271 - loadcs(readmeml(ss,ESP+4)&0xFFFF); 1.6272 - } 1.6273 - else 1.6274 - { 1.6275 - pc=readmeml(ss,SP); 1.6276 - loadcs(readmeml(ss,SP+4)&0xFFFF); 1.6277 - } 1.6278 - if (abrt) break; 1.6279 - if (stack32) ESP+=8+tempw; 1.6280 - else SP+=8+tempw; 1.6281 - cycles-=(is486)?13:18; 1.6282 - break; 1.6283 - case 0xCB: case 0x2CB: /*RETF*/ 1.6284 - if ((msw&1) && !(eflags&VM_FLAG)) 1.6285 - { 1.6286 - pmoderetf(0,0); 1.6287 - break; 1.6288 - } 1.6289 - tempw2=CPL; 1.6290 - if (ssegs) ss=oldss; 1.6291 - oxpc=pc; 1.6292 - if (stack32) 1.6293 - { 1.6294 - pc=readmemw(ss,ESP); 1.6295 - loadcs(readmemw(ss,ESP+2)); 1.6296 - } 1.6297 - else 1.6298 - { 1.6299 - pc=readmemw(ss,SP); 1.6300 - loadcs(readmemw(ss,SP+2)); 1.6301 - } 1.6302 - if (abrt) break; 1.6303 - if (stack32) ESP+=4; 1.6304 - else SP+=4; 1.6305 - cycles-=(is486)?13:18; 1.6306 - break; 1.6307 - case 0x1CB: case 0x3CB: /*RETF*/ 1.6308 - if ((msw&1) && !(eflags&VM_FLAG)) 1.6309 - { 1.6310 - pmoderetf(1,0); 1.6311 - break; 1.6312 - } 1.6313 - tempw2=CPL; 1.6314 - if (ssegs) ss=oldss; 1.6315 - oxpc=pc; 1.6316 - if (stack32) 1.6317 - { 1.6318 - pc=readmeml(ss,ESP); 1.6319 - loadcs(readmemw(ss,ESP+4)); 1.6320 - } 1.6321 - else 1.6322 - { 1.6323 - pc=readmeml(ss,SP); 1.6324 - loadcs(readmemw(ss,SP+4)); 1.6325 - } 1.6326 - if (abrt) break; 1.6327 - if (stack32) ESP+=8; 1.6328 - else SP+=8; 1.6329 - if ((msw&1) && CPL>tempw2) 1.6330 - { 1.6331 - if (stack32) 1.6332 - { 1.6333 - templ=readmeml(ss,ESP); 1.6334 - loadseg(readmeml(ss,ESP+4),&_ss); 1.6335 - ESP=templ; 1.6336 - } 1.6337 - else 1.6338 - { 1.6339 - templ=readmeml(ss,SP); 1.6340 - loadseg(readmeml(ss,SP+4),&_ss); 1.6341 - ESP=templ; 1.6342 - } 1.6343 - } 1.6344 - cycles-=(is486)?13:18; 1.6345 - break; 1.6346 - case 0xCC: case 0x1CC: case 0x2CC: case 0x3CC: /*INT 3*/ 1.6347 - if (msw&1) 1.6348 - { 1.6349 - pmodeint(3,1); 1.6350 - cycles-=(is486)?44:59; 1.6351 - } 1.6352 - else 1.6353 - { 1.6354 - if (ssegs) ss=oldss; 1.6355 - if (stack32) 1.6356 - { 1.6357 - writememw(ss,ESP-2,flags); 1.6358 - writememw(ss,ESP-4,CS); 1.6359 - writememw(ss,ESP-6,pc); 1.6360 - ESP-=6; 1.6361 - } 1.6362 - else 1.6363 - { 1.6364 - writememw(ss,((SP-2)&0xFFFF),flags); 1.6365 - writememw(ss,((SP-4)&0xFFFF),CS); 1.6366 - writememw(ss,((SP-6)&0xFFFF),pc); 1.6367 - SP-=6; 1.6368 - } 1.6369 - addr=3<<2; 1.6370 -// flags&=~I_FLAG; 1.6371 - flags&=~T_FLAG; 1.6372 - oxpc=pc; 1.6373 - pc=readmemw(0,addr); 1.6374 - loadcs(readmemw(0,addr+2)); 1.6375 - cycles-=(is486)?26:33; 1.6376 - } 1.6377 - cycles-=23; 1.6378 - break; 1.6379 - case 0xCD: case 0x1CD: case 0x2CD: case 0x3CD: /*INT*/ 1.6380 - /*if (msw&1) pclog("INT %i %i %i\n",cr0&1,eflags&VM_FLAG,IOPL);*/ 1.6381 - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) 1.6382 - { 1.6383 - x86gpf(NULL,0); 1.6384 - break; 1.6385 - } 1.6386 - lastpc=pc; 1.6387 - lastcs=CS; 1.6388 - temp=readmemb(cs,pc); pc++; 1.6389 - intrt: 1.6390 - 1.6391 -// if (temp == 0x15 && AX == 0xc203) output = 3; 1.6392 -// /*if (temp == 0x13) */pclog("INT %02X %04X %04X %04X %04X:%04X %04X:%04X %c %i %i\n",temp,AX,BX,CX,DS,DX,CS,pc,(AL>31)?AL:' ', ins, ins2); 1.6393 - if (1) 1.6394 - { 1.6395 - if (msw&1) 1.6396 - { 1.6397 -// pclog("PMODE int %02X %04X at %04X:%04X ",temp,AX,CS,pc); 1.6398 - pmodeint(temp,1); 1.6399 - cycles-=(is486)?44:59; 1.6400 -// pclog("to %04X:%04X\n",CS,pc); 1.6401 - } 1.6402 - else 1.6403 - { 1.6404 - if (ssegs) ss=oldss; 1.6405 - if (stack32) 1.6406 - { 1.6407 - writememw(ss,ESP-2,flags); 1.6408 - writememw(ss,ESP-4,CS); 1.6409 - writememw(ss,ESP-6,pc); 1.6410 - ESP-=6; 1.6411 - } 1.6412 - else 1.6413 - { 1.6414 - writememw(ss,((SP-2)&0xFFFF),flags); 1.6415 - writememw(ss,((SP-4)&0xFFFF),CS); 1.6416 - writememw(ss,((SP-6)&0xFFFF),pc); 1.6417 - SP-=6; 1.6418 - } 1.6419 - addr=temp<<2; 1.6420 -// flags&=~I_FLAG; 1.6421 - flags&=~T_FLAG; 1.6422 - oxpc=pc; 1.6423 -// pclog("%04X:%04X : ",CS,pc); 1.6424 - pc=readmemw(0,addr); 1.6425 - loadcs(readmemw(0,addr+2)); 1.6426 - cycles-=(is486)?30:37; 1.6427 -// pclog("INT %02X - %04X %04X:%04X\n",temp,addr,CS,pc); 1.6428 - } 1.6429 - } 1.6430 - break; 1.6431 - case 0xCE: /*INTO*/ 1.6432 - if (flags&V_FLAG) 1.6433 - { 1.6434 - temp=4; 1.6435 - goto intrt; 1.6436 - } 1.6437 - cycles-=3; 1.6438 - break; 1.6439 - case 0xCF: case 0x2CF: /*IRET*/ 1.6440 -// if (CS == 0xc000) output = 0; 1.6441 -// pclog("IRET\n"); 1.6442 - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) 1.6443 - { 1.6444 - x86gpf(NULL,0); 1.6445 - break; 1.6446 - } 1.6447 -// output=0; 1.6448 - if (ssegs) ss=oldss; 1.6449 - if (msw&1) 1.6450 - { 1.6451 - optype=IRET; 1.6452 - pmodeiret(0); 1.6453 - optype=0; 1.6454 - } 1.6455 - else 1.6456 - { 1.6457 - tempw=CS; 1.6458 - tempw2=pc; 1.6459 - inint=0; 1.6460 - oxpc=pc; 1.6461 - if (stack32) 1.6462 - { 1.6463 - pc=readmemw(ss,ESP); 1.6464 - loadcs(readmemw(ss,ESP+2)); 1.6465 - } 1.6466 - else 1.6467 - { 1.6468 - pc=readmemw(ss,SP); 1.6469 - loadcs(readmemw(ss,((SP+2)&0xFFFF))); 1.6470 - } 1.6471 - if (stack32) 1.6472 - { 1.6473 - flags=(readmemw(ss,ESP+4)&0xFFD5)|2; 1.6474 - ESP+=6; 1.6475 - } 1.6476 - else 1.6477 - { 1.6478 - flags=(readmemw(ss,((SP+4)&0xFFFF))&0xFFD5)|2; 1.6479 - SP+=6; 1.6480 - } 1.6481 - } 1.6482 - cycles-=(is486)?15:22; 1.6483 - break; 1.6484 - case 0x1CF: case 0x3CF: /*IRETD*/ 1.6485 -// if (output==3) output=1; 1.6486 -// pclog("IRET\n"); 1.6487 - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) 1.6488 - { 1.6489 - x86gpf(NULL,0); 1.6490 - break; 1.6491 - } 1.6492 -// output=0; 1.6493 - if (ssegs) ss=oldss; 1.6494 - if (msw&1) 1.6495 - { 1.6496 - optype=IRET; 1.6497 - pmodeiret(1); 1.6498 - optype=0; 1.6499 - } 1.6500 - else 1.6501 - { 1.6502 - tempw=CS; 1.6503 - tempw2=pc; 1.6504 - inint=0; 1.6505 - oxpc=pc; 1.6506 - if (stack32) 1.6507 - { 1.6508 - pc=readmeml(ss,ESP); 1.6509 - templ=readmeml(ss,ESP+4); 1.6510 - } 1.6511 - else 1.6512 - { 1.6513 - pc=readmeml(ss,SP); 1.6514 - templ=readmeml(ss,((SP+4)&0xFFFF)); 1.6515 - } 1.6516 - if (stack32) 1.6517 - { 1.6518 - flags=(readmemw(ss,ESP+8)&0xFFD5)|2; 1.6519 - eflags=readmemw(ss,ESP+10); 1.6520 - ESP+=12; 1.6521 - } 1.6522 - else 1.6523 - { 1.6524 - flags=(readmemw(ss,(SP+8)&0xFFFF)&0xFFD5)|2; 1.6525 - eflags=readmemw(ss,(SP+10)&0xFFFF); 1.6526 - SP+=12; 1.6527 - } 1.6528 - loadcs(templ); 1.6529 - } 1.6530 - cycles-=(is486)?15:22; 1.6531 - break; 1.6532 - 1.6533 - case 0xD0: case 0x1D0: case 0x2D0: case 0x3D0: 1.6534 - fetchea(); 1.6535 - temp=geteab(); if (abrt) break; 1.6536 - switch (rmdat&0x38) 1.6537 - { 1.6538 - case 0x00: /*ROL b,1*/ 1.6539 - seteab((temp<<1)|((temp&0x80)?1:0)); if (abrt) break; 1.6540 - if (temp&0x80) flags|=C_FLAG; 1.6541 - else flags&=~C_FLAG; 1.6542 - temp<<=1; 1.6543 - if (flags&C_FLAG) temp|=1; 1.6544 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.6545 - else flags&=~V_FLAG; 1.6546 - cycles-=((mod==3)?3:7); 1.6547 - break; 1.6548 - case 0x08: /*ROR b,1*/ 1.6549 - seteab((temp>>1)|((temp&1)?0x80:0)); if (abrt) break; 1.6550 - if (temp&1) flags|=C_FLAG; 1.6551 - else flags&=~C_FLAG; 1.6552 - temp>>=1; 1.6553 - if (flags&C_FLAG) temp|=0x80; 1.6554 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.6555 - else flags&=~V_FLAG; 1.6556 - cycles-=((mod==3)?3:7); 1.6557 - break; 1.6558 - case 0x10: /*RCL b,1*/ 1.6559 - temp2=flags&C_FLAG; 1.6560 - seteab((temp<<1)|temp2); if (abrt) break; 1.6561 - if (temp&0x80) flags|=C_FLAG; 1.6562 - else flags&=~C_FLAG; 1.6563 - temp<<=1; 1.6564 - if (temp2) temp|=1; 1.6565 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.6566 - else flags&=~V_FLAG; 1.6567 - cycles-=((mod==3)?3:7); 1.6568 - break; 1.6569 - case 0x18: /*RCR b,1*/ 1.6570 - temp2=flags&C_FLAG; 1.6571 - seteab((temp>>1)|(temp2?0x80:0)); if (abrt) break; 1.6572 - if (temp&1) flags|=C_FLAG; 1.6573 - else flags&=~C_FLAG; 1.6574 - temp>>=1; 1.6575 - if (temp2) temp|=0x80; 1.6576 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.6577 - else flags&=~V_FLAG; 1.6578 - cycles-=((mod==3)?3:7); 1.6579 - break; 1.6580 - case 0x20: case 0x30: /*SHL b,1*/ 1.6581 - seteab(temp<<1); if (abrt) break; 1.6582 - setznp8(temp<<1); 1.6583 - if (temp&0x80) flags|=C_FLAG; 1.6584 - if ((temp^(temp<<1))&0x80) flags|=V_FLAG; 1.6585 - cycles-=((mod==3)?3:7); 1.6586 - break; 1.6587 - case 0x28: /*SHR b,1*/ 1.6588 - seteab(temp>>1); if (abrt) break; 1.6589 - setznp8(temp>>1); 1.6590 - if (temp&1) flags|=C_FLAG; 1.6591 - if (temp&0x80) flags|=V_FLAG; 1.6592 - cycles-=((mod==3)?3:7); 1.6593 - break; 1.6594 - case 0x38: /*SAR b,1*/ 1.6595 - seteab((temp>>1)|(temp&0x80)); if (abrt) break; 1.6596 - setznp8((temp>>1)|(temp&0x80)); 1.6597 - if (temp&1) flags|=C_FLAG; 1.6598 - cycles-=((mod==3)?3:7); 1.6599 - break; 1.6600 - } 1.6601 - break; 1.6602 - case 0xD1: case 0x2D1: 1.6603 - fetchea(); 1.6604 - tempw=geteaw(); if (abrt) break; 1.6605 - switch (rmdat&0x38) 1.6606 - { 1.6607 - case 0x00: /*ROL w,1*/ 1.6608 - seteaw((tempw<<1)|(tempw>>15)); if (abrt) break; 1.6609 - if (tempw&0x8000) flags|=C_FLAG; 1.6610 - else flags&=~C_FLAG; 1.6611 - tempw<<=1; 1.6612 - if (flags&C_FLAG) tempw|=1; 1.6613 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.6614 - else flags&=~V_FLAG; 1.6615 - cycles-=((mod==3)?3:7); 1.6616 - break; 1.6617 - case 0x08: /*ROR w,1*/ 1.6618 - seteaw((tempw>>1)|(tempw<<15)); if (abrt) break; 1.6619 - if (tempw&1) flags|=C_FLAG; 1.6620 - else flags&=~C_FLAG; 1.6621 - tempw>>=1; 1.6622 - if (flags&C_FLAG) tempw|=0x8000; 1.6623 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.6624 - else flags&=~V_FLAG; 1.6625 - cycles-=((mod==3)?3:7); 1.6626 - break; 1.6627 - case 0x10: /*RCL w,1*/ 1.6628 - temp2=flags&C_FLAG; 1.6629 - seteaw((tempw<<1)|temp2); if (abrt) break; 1.6630 - if (tempw&0x8000) flags|=C_FLAG; 1.6631 - else flags&=~C_FLAG; 1.6632 - tempw<<=1; 1.6633 - if (temp2) tempw|=1; 1.6634 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.6635 - else flags&=~V_FLAG; 1.6636 - cycles-=((mod==3)?3:7); 1.6637 - break; 1.6638 - case 0x18: /*RCR w,1*/ 1.6639 - temp2=flags&C_FLAG; 1.6640 - seteaw((tempw>>1)|(temp2?0x8000:0)); if (abrt) break; 1.6641 - if (tempw&1) flags|=C_FLAG; 1.6642 - else flags&=~C_FLAG; 1.6643 - tempw>>=1; 1.6644 - if (temp2) tempw|=0x8000; 1.6645 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.6646 - else flags&=~V_FLAG; 1.6647 - cycles-=((mod==3)?3:7); 1.6648 - break; 1.6649 - case 0x20: case 0x30: /*SHL w,1*/ 1.6650 - seteaw(tempw<<1); if (abrt) break; 1.6651 - setznp16(tempw<<1); 1.6652 - if (tempw&0x8000) flags|=C_FLAG; 1.6653 - if ((tempw^(tempw<<1))&0x8000) flags|=V_FLAG; 1.6654 - cycles-=((mod==3)?3:7); 1.6655 - break; 1.6656 - case 0x28: /*SHR w,1*/ 1.6657 - seteaw(tempw>>1); if (abrt) break; 1.6658 - setznp16(tempw>>1); 1.6659 - if (tempw&1) flags|=C_FLAG; 1.6660 - if (tempw&0x8000) flags|=V_FLAG; 1.6661 - cycles-=((mod==3)?3:7); 1.6662 - break; 1.6663 - case 0x38: /*SAR w,1*/ 1.6664 - seteaw((tempw>>1)|(tempw&0x8000)); if (abrt) break; 1.6665 - setznp16((tempw>>1)|(tempw&0x8000)); 1.6666 - if (tempw&1) flags|=C_FLAG; 1.6667 - cycles-=((mod==3)?3:7); 1.6668 - break; 1.6669 - 1.6670 - default: 1.6671 - pclog("Bad D1 opcode %02X\n",rmdat&0x38); 1.6672 - } 1.6673 - break; 1.6674 - case 0x1D1: case 0x3D1: 1.6675 - fetchea(); 1.6676 - templ=geteal(); if (abrt) break; 1.6677 - switch (rmdat&0x38) 1.6678 - { 1.6679 - case 0x00: /*ROL l,1*/ 1.6680 - seteal((templ<<1)|(templ>>31)); if (abrt) break; 1.6681 - if (templ&0x80000000) flags|=C_FLAG; 1.6682 - else flags&=~C_FLAG; 1.6683 - templ<<=1; 1.6684 - if (flags&C_FLAG) templ|=1; 1.6685 - if ((flags&C_FLAG)^(templ>>31)) flags|=V_FLAG; 1.6686 - else flags&=~V_FLAG; 1.6687 - cycles-=((mod==3)?3:7); 1.6688 - break; 1.6689 - case 0x08: /*ROR l,1*/ 1.6690 - seteal((templ>>1)|(templ<<31)); if (abrt) break; 1.6691 - if (templ&1) flags|=C_FLAG; 1.6692 - else flags&=~C_FLAG; 1.6693 - templ>>=1; 1.6694 - if (flags&C_FLAG) templ|=0x80000000; 1.6695 - if ((templ^(templ>>1))&0x40000000) flags|=V_FLAG; 1.6696 - else flags&=~V_FLAG; 1.6697 - cycles-=((mod==3)?3:7); 1.6698 - break; 1.6699 - case 0x10: /*RCL l,1*/ 1.6700 - temp2=flags&C_FLAG; 1.6701 - seteal((templ<<1)|temp2); if (abrt) break; 1.6702 - if (templ&0x80000000) flags|=C_FLAG; 1.6703 - else flags&=~C_FLAG; 1.6704 - templ<<=1; 1.6705 - if (temp2) templ|=1; 1.6706 - if ((flags&C_FLAG)^(templ>>31)) flags|=V_FLAG; 1.6707 - else flags&=~V_FLAG; 1.6708 - cycles-=((mod==3)?3:7); 1.6709 - break; 1.6710 - case 0x18: /*RCR l,1*/ 1.6711 - temp2=flags&C_FLAG; 1.6712 - seteal((templ>>1)|(temp2?0x80000000:0)); if (abrt) break; 1.6713 - temp2=flags&C_FLAG; 1.6714 - if (templ&1) flags|=C_FLAG; 1.6715 - else flags&=~C_FLAG; 1.6716 - templ>>=1; 1.6717 - if (temp2) templ|=0x80000000; 1.6718 - if ((templ^(templ>>1))&0x40000000) flags|=V_FLAG; 1.6719 - else flags&=~V_FLAG; 1.6720 - cycles-=((mod==3)?3:7); 1.6721 - break; 1.6722 - case 0x20: case 0x30: /*SHL l,1*/ 1.6723 - seteal(templ<<1); if (abrt) break; 1.6724 - setznp32(templ<<1); 1.6725 - if (templ&0x80000000) flags|=C_FLAG; 1.6726 - if ((templ^(templ<<1))&0x80000000) flags|=V_FLAG; 1.6727 - cycles-=((mod==3)?3:7); 1.6728 - break; 1.6729 - case 0x28: /*SHR l,1*/ 1.6730 - seteal(templ>>1); if (abrt) break; 1.6731 - setznp32(templ>>1); 1.6732 - if (templ&1) flags|=C_FLAG; 1.6733 - if (templ&0x80000000) flags|=V_FLAG; 1.6734 - cycles-=((mod==3)?3:7); 1.6735 - break; 1.6736 - case 0x38: /*SAR l,1*/ 1.6737 - seteal((templ>>1)|(templ&0x80000000)); if (abrt) break; 1.6738 - setznp32((templ>>1)|(templ&0x80000000)); 1.6739 - if (templ&1) flags|=C_FLAG; 1.6740 - cycles-=((mod==3)?3:7); 1.6741 - break; 1.6742 - 1.6743 - default: 1.6744 - pclog("Bad D1 opcode %02X\n",rmdat&0x38); 1.6745 - } 1.6746 - break; 1.6747 - 1.6748 - case 0xD2: case 0x1D2: case 0x2D2: case 0x3D2: 1.6749 - fetchea(); 1.6750 - temp=geteab(); if (abrt) break; 1.6751 - c=CL&31; 1.6752 -// cycles-=c; 1.6753 - if (!c) break; 1.6754 -// if (c>7) pclog("Shiftb %i %02X\n",rmdat&0x38,c); 1.6755 - switch (rmdat&0x38) 1.6756 - { 1.6757 - case 0x00: /*ROL b,CL*/ 1.6758 - while (c>0) 1.6759 - { 1.6760 - temp2=(temp&0x80)?1:0; 1.6761 - temp=(temp<<1)|temp2; 1.6762 - c--; 1.6763 - } 1.6764 - seteab(temp); if (abrt) break; 1.6765 - flags&=~(C_FLAG|V_FLAG); 1.6766 - if (temp2) flags|=C_FLAG; 1.6767 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.6768 - cycles-=((mod==3)?3:7); 1.6769 - break; 1.6770 - case 0x08: /*ROR b,CL*/ 1.6771 - while (c>0) 1.6772 - { 1.6773 - temp2=temp&1; 1.6774 - temp>>=1; 1.6775 - if (temp2) temp|=0x80; 1.6776 - c--; 1.6777 - } 1.6778 - seteab(temp); if (abrt) break; 1.6779 - flags&=~(C_FLAG|V_FLAG); 1.6780 - if (temp2) flags|=C_FLAG; 1.6781 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.6782 - cycles-=((mod==3)?3:7); 1.6783 - break; 1.6784 - case 0x10: /*RCL b,CL*/ 1.6785 - tempc=flags&C_FLAG; 1.6786 - while (c>0) 1.6787 - { 1.6788 - templ=tempc; 1.6789 - tempc=temp&0x80; 1.6790 - temp<<=1; 1.6791 - if (templ) temp|=1; 1.6792 - c--; 1.6793 - } 1.6794 - seteab(temp); if (abrt) break; 1.6795 - flags&=~(C_FLAG|V_FLAG); 1.6796 - if (tempc) flags|=C_FLAG; 1.6797 - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; 1.6798 - cycles-=((mod==3)?3:7); 1.6799 - break; 1.6800 - case 0x18: /*RCR b,CL*/ 1.6801 - tempc=flags&C_FLAG; 1.6802 - while (c>0) 1.6803 - { 1.6804 - templ=tempc; 1.6805 - tempc=temp&1; 1.6806 - temp>>=1; 1.6807 - if (templ) temp|=0x80; 1.6808 - c--; 1.6809 - } 1.6810 - seteab(temp); if (abrt) break; 1.6811 - flags&=~(C_FLAG|V_FLAG); 1.6812 - if (tempc) flags|=C_FLAG; 1.6813 - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; 1.6814 - cycles-=((mod==3)?3:7); 1.6815 - break; 1.6816 - case 0x20: case 0x30: /*SHL b,CL*/ 1.6817 - seteab(temp<<c); if (abrt) break; 1.6818 - setznp8(temp<<c); 1.6819 - if ((temp<<(c-1))&0x80) flags|=C_FLAG; 1.6820 - if (((temp<<c)^(temp<<(c-1)))&0x80) flags|=V_FLAG; 1.6821 - cycles-=((mod==3)?3:7); 1.6822 - break; 1.6823 - case 0x28: /*SHR b,CL*/ 1.6824 - seteab(temp>>c); if (abrt) break; 1.6825 - setznp8(temp>>c); 1.6826 - if ((temp>>(c-1))&1) flags|=C_FLAG; 1.6827 - if (c==1 && temp&0x80) flags|=V_FLAG; 1.6828 - cycles-=((mod==3)?3:7); 1.6829 - break; 1.6830 - case 0x38: /*SAR b,CL*/ 1.6831 - tempc=(temp>>(c-1))&1; 1.6832 - while (c>0) 1.6833 - { 1.6834 - temp>>=1; 1.6835 - if (temp&0x40) temp|=0x80; 1.6836 - c--; 1.6837 - } 1.6838 - seteab(temp); if (abrt) break; 1.6839 - setznp8(temp); 1.6840 - if (tempc) flags|=C_FLAG; 1.6841 - cycles-=((mod==3)?3:7); 1.6842 - break; 1.6843 - } 1.6844 - break; 1.6845 - 1.6846 - case 0xD3: case 0x2D3: 1.6847 - fetchea(); 1.6848 - tempw=geteaw(); if (abrt) break; 1.6849 - c=CL&31; 1.6850 - if (!c) break; 1.6851 - switch (rmdat&0x38) 1.6852 - { 1.6853 - case 0x00: /*ROL w,CL*/ 1.6854 - while (c>0) 1.6855 - { 1.6856 - temp=(tempw&0x8000)?1:0; 1.6857 - tempw=(tempw<<1)|temp; 1.6858 - c--; 1.6859 - } 1.6860 - seteaw(tempw); if (abrt) break; 1.6861 - flags&=~(C_FLAG|V_FLAG); 1.6862 - if (temp) flags|=C_FLAG; 1.6863 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.6864 - cycles-=((mod==3)?3:7); 1.6865 - break; 1.6866 - case 0x08: /*ROR w,CL*/ 1.6867 - while (c>0) 1.6868 - { 1.6869 - tempw2=(tempw&1)?0x8000:0; 1.6870 - tempw=(tempw>>1)|tempw2; 1.6871 - c--; 1.6872 - } 1.6873 - seteaw(tempw); if (abrt) break; 1.6874 - flags&=~(C_FLAG|V_FLAG); 1.6875 - if (tempw2) flags|=C_FLAG; 1.6876 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.6877 - cycles-=((mod==3)?3:7); 1.6878 - break; 1.6879 - case 0x10: /*RCL w,CL*/ 1.6880 - tempc=flags&C_FLAG; 1.6881 - while (c>0) 1.6882 - { 1.6883 - templ=tempc; 1.6884 - tempc=tempw&0x8000; 1.6885 - tempw=(tempw<<1)|templ; 1.6886 - c--; 1.6887 - } 1.6888 - seteaw(tempw); if (abrt) break; 1.6889 - flags&=~(C_FLAG|V_FLAG); 1.6890 - if (tempc) flags|=C_FLAG; 1.6891 - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; 1.6892 - cycles-=((mod==3)?3:7); 1.6893 - break; 1.6894 - case 0x18: /*RCR w,CL*/ 1.6895 - tempc=flags&C_FLAG; 1.6896 - while (c>0) 1.6897 - { 1.6898 - templ=tempc; 1.6899 - tempw2=(templ&1)?0x8000:0; 1.6900 - tempc=tempw&1; 1.6901 - tempw=(tempw>>1)|tempw2; 1.6902 - c--; 1.6903 - } 1.6904 - seteaw(tempw); if (abrt) break; 1.6905 - flags&=~(C_FLAG|V_FLAG); 1.6906 - if (tempc) flags|=C_FLAG; 1.6907 - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; 1.6908 - cycles-=((mod==3)?3:7); 1.6909 - break; 1.6910 - 1.6911 - case 0x20: case 0x30: /*SHL w,CL*/ 1.6912 - seteaw(tempw<<c); if (abrt) break; 1.6913 - setznp16(tempw<<c); 1.6914 - if ((tempw<<(c-1))&0x8000) flags|=C_FLAG; 1.6915 - if (((tempw<<c)^(tempw<<(c-1)))&0x8000) flags|=V_FLAG; 1.6916 - cycles-=((mod==3)?3:7); 1.6917 - break; 1.6918 - 1.6919 - case 0x28: /*SHR w,CL*/ 1.6920 - seteaw(tempw>>c); if (abrt) break; 1.6921 - setznp16(tempw>>c); 1.6922 - if ((tempw>>(c-1))&1) flags|=C_FLAG; 1.6923 - if (c==1 && tempw&0x8000) flags|=V_FLAG; 1.6924 - cycles-=((mod==3)?3:7); 1.6925 - break; 1.6926 - 1.6927 - case 0x38: /*SAR w,CL*/ 1.6928 - tempw2=tempw&0x8000; 1.6929 - tempc=((int16_t)tempw>>(c-1))&1; 1.6930 - while (c>0) 1.6931 - { 1.6932 - tempw=(tempw>>1)|tempw2; 1.6933 - c--; 1.6934 - } 1.6935 - seteaw(tempw); if (abrt) break; 1.6936 - setznp16(tempw); 1.6937 - if (tempc) flags|=C_FLAG; 1.6938 - cycles-=((mod==3)?3:7); 1.6939 - break; 1.6940 - } 1.6941 - break; 1.6942 - case 0x1D3: case 0x3D3: 1.6943 - fetchea(); 1.6944 - templ=geteal(); if (abrt) break; 1.6945 - c=CL&31; 1.6946 - if (!c) break; 1.6947 - switch (rmdat&0x38) 1.6948 - { 1.6949 - case 0x00: /*ROL l,CL*/ 1.6950 - while (c>0) 1.6951 - { 1.6952 - temp=(templ&0x80000000)?1:0; 1.6953 - templ=(templ<<1)|temp; 1.6954 - c--; 1.6955 - } 1.6956 - seteal(templ); if (abrt) break; 1.6957 - flags&=~(C_FLAG|V_FLAG); 1.6958 - if (temp) flags|=C_FLAG; 1.6959 - if ((flags&C_FLAG)^(templ>>31)) flags|=V_FLAG; 1.6960 - cycles-=((mod==3)?3:7); 1.6961 - break; 1.6962 - case 0x08: /*ROR l,CL*/ 1.6963 - while (c>0) 1.6964 - { 1.6965 - templ2=(templ&1)?0x80000000:0; 1.6966 - templ=(templ>>1)|templ2; 1.6967 - c--; 1.6968 - } 1.6969 - seteal(templ); if (abrt) break; 1.6970 - flags&=~(C_FLAG|V_FLAG); 1.6971 - if (templ2) flags|=C_FLAG; 1.6972 - if ((templ^(templ>>1))&0x40000000) flags|=V_FLAG; 1.6973 - cycles-=((mod==3)?3:7); 1.6974 - break; 1.6975 - case 0x10: /*RCL l,CL*/ 1.6976 - tempc=flags&C_FLAG; 1.6977 - while (c>0) 1.6978 - { 1.6979 - templ2=tempc; 1.6980 - tempc=(templ>>31); 1.6981 - templ=(templ<<1)|templ2; 1.6982 - c--; 1.6983 - } 1.6984 - seteal(templ); if (abrt) break; 1.6985 - flags&=~(C_FLAG|V_FLAG); 1.6986 - if (templ2) flags|=C_FLAG; 1.6987 - if ((flags&C_FLAG)^(templ>>31)) flags|=V_FLAG; 1.6988 - cycles-=((mod==3)?3:7); 1.6989 - break; 1.6990 - case 0x18: /*RCR l,CL*/ 1.6991 - tempc=flags&C_FLAG; 1.6992 - while (c>0) 1.6993 - { 1.6994 - templ2=(tempc)?0x80000000:0; 1.6995 - tempc=templ&1; 1.6996 - templ=(templ>>1)|templ2; 1.6997 - c--; 1.6998 - } 1.6999 - seteal(templ); if (abrt) break; 1.7000 - flags&=~(C_FLAG|V_FLAG); 1.7001 - if (templ2) flags|=C_FLAG; 1.7002 - if ((templ^(templ>>1))&0x40000000) flags|=V_FLAG; 1.7003 - cycles-=((mod==3)?3:7); 1.7004 - break; 1.7005 - 1.7006 - case 0x20: case 0x30: /*SHL l,CL*/ 1.7007 - seteal(templ<<c); if (abrt) break; 1.7008 - setznp32(templ<<c); 1.7009 - if ((templ<<(c-1))&0x80000000) flags|=C_FLAG; 1.7010 - if (((templ<<c)^(templ<<(c-1)))&0x80000000) flags|=V_FLAG; 1.7011 - cycles-=((mod==3)?3:7); 1.7012 - break; 1.7013 - 1.7014 - case 0x28: /*SHR l,CL*/ 1.7015 - seteal(templ>>c); if (abrt) break; 1.7016 - setznp32(templ>>c); 1.7017 - if ((templ>>(c-1))&1) flags|=C_FLAG; 1.7018 - if (c==1 && templ&0x80000000) flags|=V_FLAG; 1.7019 - cycles-=((mod==3)?3:7); 1.7020 - break; 1.7021 - 1.7022 - case 0x38: /*SAR w,CL*/ 1.7023 - templ2=templ&0x80000000; 1.7024 - tempc=(templ>>(c-1))&1; 1.7025 - while (c>0) 1.7026 - { 1.7027 - templ=(templ>>1)|templ2; 1.7028 - c--; 1.7029 - } 1.7030 - seteal(templ); if (abrt) break; 1.7031 - setznp32(templ); 1.7032 - if (tempc) flags|=C_FLAG; 1.7033 - cycles-=((mod==3)?3:7); 1.7034 - break; 1.7035 - } 1.7036 - break; 1.7037 - 1.7038 - 1.7039 - case 0xD4: case 0x1D4: case 0x2D4: case 0x3D4: /*AAM*/ 1.7040 - tempws=readmemb(cs,pc); pc++; 1.7041 - if (!tempws || cpu_manufacturer != MANU_INTEL) tempws = 10; 1.7042 - AH=AL/tempws; 1.7043 - AL%=tempws; 1.7044 - setznp16(AX); 1.7045 - cycles-=(is486)?15:17; 1.7046 - break; 1.7047 - case 0xD5: case 0x1D5: case 0x2D5: case 0x3D5: /*AAD*/ 1.7048 - tempws=readmemb(cs,pc); pc++; 1.7049 - if (cpu_manufacturer != MANU_INTEL) tempws = 10; 1.7050 - AL=(AH*tempws)+AL; 1.7051 - AH=0; 1.7052 - setznp16(AX); 1.7053 - cycles-=(is486)?14:19; 1.7054 - break; 1.7055 - case 0xD6: case 0x1D6: case 0x2D6: case 0x3D6: /*SETALC*/ 1.7056 - AL=(flags&C_FLAG)?0xFF:0; 1.7057 - cycles -= timing_rr; 1.7058 - break; 1.7059 - case 0xD7: case 0x1D7: /*XLAT*/ 1.7060 - addr=(BX+AL)&0xFFFF; 1.7061 - temp=readmemb(ds,addr); if (abrt) break; 1.7062 - AL=temp; 1.7063 - cycles-=5; 1.7064 - break; 1.7065 - case 0x2D7: case 0x3D7: /*XLAT*/ 1.7066 - addr=EBX+AL; 1.7067 - temp=readmemb(ds,addr); if (abrt) break; 1.7068 - AL=temp; 1.7069 - cycles-=5; 1.7070 - break; 1.7071 - case 0xD9: case 0xDA: case 0xDB: case 0xDD: /*ESCAPE*/ 1.7072 - case 0x1D9: case 0x1DA: case 0x1DB: case 0x1DD: /*ESCAPE*/ 1.7073 - case 0x2D9: case 0x2DA: case 0x2DB: case 0x2DD: /*ESCAPE*/ 1.7074 - case 0x3D9: case 0x3DA: case 0x3DB: case 0x3DD: /*ESCAPE*/ 1.7075 - case 0xD8: case 0x1D8: case 0x2D8: case 0x3D8: 1.7076 - case 0xDC: case 0x1DC: case 0x2DC: case 0x3DC: 1.7077 - case 0xDE: case 0x1DE: case 0x2DE: case 0x3DE: 1.7078 - case 0xDF: case 0x1DF: case 0x2DF: case 0x3DF: 1.7079 - if ((cr0&6)==4) 1.7080 - { 1.7081 - pc=oldpc; 1.7082 - pmodeint(7,0); 1.7083 - cycles-=59; 1.7084 - } 1.7085 - else 1.7086 - { 1.7087 - fpucount++; 1.7088 - fetchea(); 1.7089 - if (hasfpu) 1.7090 - { 1.7091 - x87_pc_off=oldpc; 1.7092 - x87_pc_seg=CS; 1.7093 - x87_op_off=eaaddr; 1.7094 - x87_op_seg=ea_rseg; 1.7095 - switch (opcode) 1.7096 - { 1.7097 - case 0xD8: x87_d8(); break; 1.7098 - case 0xD9: x87_d9(); break; 1.7099 - case 0xDA: x87_da(); break; 1.7100 - case 0xDB: x87_db(); break; 1.7101 - case 0xDC: x87_dc(); break; 1.7102 - case 0xDD: x87_dd(); break; 1.7103 - case 0xDE: x87_de(); break; 1.7104 - case 0xDF: x87_df(); break; 1.7105 - } 1.7106 - } 1.7107 - //cycles-=8; 1.7108 - } 1.7109 - break; 1.7110 - 1.7111 - case 0xE0: case 0x1E0: /*LOOPNE*/ 1.7112 - offset=(int8_t)readmemb(cs,pc); pc++; 1.7113 - CX--; 1.7114 - if (CX && !(flags&Z_FLAG)) { pc+=offset; } 1.7115 - cycles-=(is486)?7:11; 1.7116 - break; 1.7117 - case 0x2E0: case 0x3E0: /*LOOPNE*/ 1.7118 - offset=(int8_t)readmemb(cs,pc); pc++; 1.7119 - ECX--; 1.7120 - if (ECX && !(flags&Z_FLAG)) { pc+=offset; } 1.7121 - cycles-=(is486)?7:11; 1.7122 - break; 1.7123 - case 0xE1: case 0x1E1: /*LOOPE*/ 1.7124 - offset=(int8_t)readmemb(cs,pc); pc++; 1.7125 - CX--; 1.7126 - if (CX && (flags&Z_FLAG)) { pc+=offset; } 1.7127 - cycles-=(is486)?7:11; 1.7128 - break; 1.7129 - case 0x2E1: case 0x3E1: /*LOOPE*/ 1.7130 - offset=(int8_t)readmemb(cs,pc); pc++; 1.7131 - ECX--; 1.7132 - if (ECX && (flags&Z_FLAG)) { pc+=offset; } 1.7133 - cycles-=(is486)?7:11; 1.7134 - break; 1.7135 - case 0xE2: case 0x1E2: /*LOOP*/ 1.7136 - offset=(int8_t)readmemb(cs,pc); pc++; 1.7137 - CX--; 1.7138 - if (CX) { pc+=offset; } 1.7139 - cycles-=(is486)?7:11; 1.7140 - break; 1.7141 - case 0x2E2: case 0x3E2: /*LOOP*/ 1.7142 - offset=(int8_t)readmemb(cs,pc); pc++; 1.7143 - ECX--; 1.7144 - if (ECX) { pc+=offset; } 1.7145 - cycles-=(is486)?7:11; 1.7146 - break; 1.7147 - case 0xE3: case 0x1E3: /*JCXZ*/ 1.7148 - offset=(int8_t)readmemb(cs,pc); pc++; 1.7149 - if (!CX) { pc+=offset; cycles-=4; } 1.7150 - cycles-=5; 1.7151 - break; 1.7152 - case 0x2E3: case 0x3E3: /*JECXZ*/ 1.7153 - offset=(int8_t)readmemb(cs,pc); pc++; 1.7154 - if (!ECX) { pc+=offset; cycles-=4; } 1.7155 - cycles-=5; 1.7156 - break; 1.7157 - 1.7158 - case 0xE4: case 0x1E4: case 0x2E4: case 0x3E4: /*IN AL*/ 1.7159 - temp=readmemb(cs,pc); 1.7160 - checkio_perm(temp); 1.7161 - pc++; 1.7162 - AL=inb(temp); 1.7163 - cycles-=12; 1.7164 - break; 1.7165 - case 0xE5: case 0x2E5: /*IN AX*/ 1.7166 - temp=readmemb(cs,pc); 1.7167 - checkio_perm(temp); 1.7168 - checkio_perm(temp+1); 1.7169 - pc++; 1.7170 - AX=inw(temp); 1.7171 - cycles-=12; 1.7172 - break; 1.7173 - case 0x1E5: case 0x3E5: /*IN EAX*/ 1.7174 - temp=readmemb(cs,pc); 1.7175 - checkio_perm(temp); 1.7176 - checkio_perm(temp+1); 1.7177 - checkio_perm(temp+2); 1.7178 - checkio_perm(temp+3); 1.7179 - pc++; 1.7180 - EAX=inl(temp); 1.7181 - cycles-=12; 1.7182 - break; 1.7183 - case 0xE6: case 0x1E6: case 0x2E6: case 0x3E6: /*OUT AL*/ 1.7184 - temp=readmemb(cs,pc); 1.7185 -// if (output) pclog("OUT %02X,%02X - %08X\n",temp,AL,writelookup2); 1.7186 - checkio_perm(temp); 1.7187 - // if (output) pclog(" - %08X\n",writelookup2); 1.7188 - pc++; 1.7189 - outb(temp,AL); 1.7190 -// if (output) pclog(" - %08X\n",writelookup2); 1.7191 - cycles-=10; 1.7192 - break; 1.7193 - case 0xE7: case 0x2E7: /*OUT AX*/ 1.7194 - temp=readmemb(cs,pc); 1.7195 - checkio_perm(temp); 1.7196 - checkio_perm(temp+1); 1.7197 - pc++; 1.7198 - outw(temp,AX); 1.7199 - cycles-=10; 1.7200 - break; 1.7201 - case 0x1E7: case 0x3E7: /*OUT EAX*/ 1.7202 - temp=readmemb(cs,pc); 1.7203 - checkio_perm(temp); 1.7204 - checkio_perm(temp+1); 1.7205 - checkio_perm(temp+2); 1.7206 - checkio_perm(temp+3); 1.7207 - pc++; 1.7208 - outl(temp,EAX); 1.7209 - cycles-=10; 1.7210 - break; 1.7211 - 1.7212 - case 0xE8: /*CALL rel 16*/ 1.7213 - tempw=getword(); if (abrt) break; 1.7214 - if (ssegs) ss=oldss; 1.7215 - if (stack32) 1.7216 - { 1.7217 - writememw(ss,ESP-2,pc); if (abrt) break; 1.7218 - ESP-=2; 1.7219 - } 1.7220 - else 1.7221 - { 1.7222 - writememw(ss,((SP-2)&0xFFFF),pc); if (abrt) break; 1.7223 - SP-=2; 1.7224 - } 1.7225 - pc+=(int16_t)tempw; 1.7226 - cycles-=(is486)?3:7; 1.7227 - break; 1.7228 - case 0x3E8: /*CALL rel 16*/ 1.7229 - templ=getlong(); if (abrt) break; 1.7230 - if (ssegs) ss=oldss; 1.7231 - if (stack32) 1.7232 - { 1.7233 - writememl(ss,ESP-4,pc); if (abrt) break; 1.7234 - ESP-=4; 1.7235 - } 1.7236 - else 1.7237 - { 1.7238 - writememl(ss,((SP-4)&0xFFFF),pc); if (abrt) break; 1.7239 - SP-=4; 1.7240 - } 1.7241 - pc+=templ; 1.7242 - cycles-=(is486)?3:7; 1.7243 - break; 1.7244 - case 0xE9: case 0x2E9: /*JMP rel 16*/ 1.7245 - tempw=getword(); if (abrt) break; 1.7246 - pc+=(int16_t)tempw; 1.7247 - cycles-=(is486)?3:7; 1.7248 - break; 1.7249 - case 0x1E9: case 0x3E9: /*JMP rel 32*/ 1.7250 - templ=getlong(); if (abrt) break; 1.7251 - pc+=templ; 1.7252 - cycles-=(is486)?3:7; 1.7253 - break; 1.7254 - case 0xEA: case 0x2EA: /*JMP far*/ 1.7255 - addr=getword(); 1.7256 - tempw=getword(); if (abrt) { if (output==3) pclog("JMP ABRT\n"); break; } 1.7257 - oxpc=pc; 1.7258 - pc=addr; 1.7259 - loadcsjmp(tempw,oxpc); 1.7260 - cycles-=(is486)?17:12; 1.7261 - break; 1.7262 - case 0x1EA: case 0x3EA: /*JMP far*/ 1.7263 - templ=getlong(); 1.7264 - tempw=getword(); if (abrt) break; 1.7265 - oxpc=pc; 1.7266 - pc=templ; 1.7267 - loadcsjmp(tempw,oxpc); 1.7268 - cycles-=(is486)?17:12; 1.7269 - break; 1.7270 - case 0xEB: case 0x1EB: case 0x2EB: case 0x3EB: /*JMP rel*/ 1.7271 - offset=(int8_t)readmemb(cs,pc); pc++; 1.7272 - pc+=offset; 1.7273 - cycles-=(is486)?3:7; 1.7274 - break; 1.7275 - case 0xEC: case 0x1EC: case 0x2EC: case 0x3EC: /*IN AL,DX*/ 1.7276 - checkio_perm(DX); 1.7277 - AL=inb(DX); 1.7278 - cycles-=13; 1.7279 - break; 1.7280 - case 0xED: case 0x2ED: /*IN AX,DX*/ 1.7281 - checkio_perm(DX); 1.7282 - checkio_perm(DX+1); 1.7283 - AX=inw(DX); 1.7284 - cycles-=13; 1.7285 - break; 1.7286 - case 0x1ED: case 0x3ED: /*IN EAX,DX*/ 1.7287 - checkio_perm(DX); 1.7288 - checkio_perm(DX+1); 1.7289 - checkio_perm(DX+2); 1.7290 - checkio_perm(DX+3); 1.7291 - EAX=inl(DX); 1.7292 - cycles-=13; 1.7293 - break; 1.7294 - case 0xEE: case 0x1EE: case 0x2EE: case 0x3EE: /*OUT DX,AL*/ 1.7295 - checkio_perm(DX); 1.7296 - outb(DX,AL); 1.7297 - cycles-=11; 1.7298 - break; 1.7299 - case 0xEF: case 0x2EF: /*OUT DX,AX*/ 1.7300 - checkio_perm(DX); 1.7301 - checkio_perm(DX+1); 1.7302 - outw(DX,AX); 1.7303 - cycles-=11; 1.7304 - break; 1.7305 - case 0x1EF: case 0x3EF: /*OUT DX,EAX*/ 1.7306 - checkio_perm(DX); 1.7307 - checkio_perm(DX+1); 1.7308 - checkio_perm(DX+2); 1.7309 - checkio_perm(DX+3); 1.7310 - outl(DX,EAX); 1.7311 - cycles-=11; 1.7312 - break; 1.7313 - 1.7314 - case 0xF0: case 0x1F0: case 0x2F0: case 0x3F0: /*LOCK*/ 1.7315 - cycles-=4; 1.7316 - break; 1.7317 - 1.7318 - case 0xF2: case 0x1F2: case 0x2F2: case 0x3F2: /*REPNE*/ 1.7319 - rep386(0); 1.7320 - break; 1.7321 - case 0xF3: case 0x1F3: case 0x2F3: case 0x3F3: /*REPE*/ 1.7322 - rep386(1); 1.7323 - break; 1.7324 - 1.7325 - case 0xF4: case 0x1F4: case 0x2F4: case 0x3F4: /*HLT*/ 1.7326 - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) 1.7327 - { 1.7328 -// pclog("Can't HLT\n"); 1.7329 - x86gpf(NULL,0); 1.7330 - //output=3; 1.7331 - break; 1.7332 - } 1.7333 - inhlt=1; 1.7334 - pc--; 1.7335 - if (!((flags&I_FLAG) && (((pic.pend&~pic.mask)&~pic.mask2) || ((pic2.pend&~pic2.mask)&~pic2.mask2)) && !ssegs && !noint)) cycles = oldcyc - 100; 1.7336 - else cycles-=5; 1.7337 - break; 1.7338 - case 0xF5: case 0x1F5: case 0x2F5: case 0x3F5: /*CMC*/ 1.7339 - flags^=C_FLAG; 1.7340 - cycles-=2; 1.7341 - break; 1.7342 - 1.7343 - case 0xF6: case 0x1F6: case 0x2F6: case 0x3F6: 1.7344 - fetchea(); 1.7345 - temp=geteab(); if (abrt) break; 1.7346 - switch (rmdat&0x38) 1.7347 - { 1.7348 - case 0x00: /*TEST b,#8*/ 1.7349 - temp2=readmemb(cs,pc); pc++; if (abrt) break; 1.7350 -// pclog("TEST %02X,%02X\n",temp,temp2); 1.7351 - temp&=temp2; 1.7352 - setznp8(temp); 1.7353 - if (is486) cycles-=((mod==3)?1:2); 1.7354 - else cycles-=((mod==3)?2:5); 1.7355 - break; 1.7356 - case 0x10: /*NOT b*/ 1.7357 - temp=~temp; 1.7358 - seteab(temp); 1.7359 - cycles -= (mod == 3) ? timing_rr : timing_mm; 1.7360 - break; 1.7361 - case 0x18: /*NEG b*/ 1.7362 - setsub8(0,temp); 1.7363 - temp=0-temp; 1.7364 - seteab(temp); 1.7365 - cycles -= (mod == 3) ? timing_rr : timing_mm; 1.7366 - break; 1.7367 - case 0x20: /*MUL AL,b*/ 1.7368 -// setznp8(AL); 1.7369 - AX=AL*temp; 1.7370 -// if (AX) flags&=~Z_FLAG; 1.7371 -// else flags|=Z_FLAG; 1.7372 - if (AH) flags|=(C_FLAG|V_FLAG); 1.7373 - else flags&=~(C_FLAG|V_FLAG); 1.7374 - cycles-=13; 1.7375 - break; 1.7376 - case 0x28: /*IMUL AL,b*/ 1.7377 -// setznp8(AL); 1.7378 - tempws=(int)((int8_t)AL)*(int)((int8_t)temp); 1.7379 - AX=tempws&0xFFFF; 1.7380 -// if (AX) flags&=~Z_FLAG; 1.7381 -// else flags|=Z_FLAG; 1.7382 - if (AH && AH!=0xFF) flags|=(C_FLAG|V_FLAG); 1.7383 - else flags&=~(C_FLAG|V_FLAG); 1.7384 - cycles-=14; 1.7385 - break; 1.7386 - case 0x30: /*DIV AL,b*/ 1.7387 - tempw=AX; 1.7388 - if (temp) tempw2=tempw/temp; 1.7389 -// pclog("DIV %04X/%02X %04X:%04X\n",tempw,temp,CS,pc); 1.7390 - if (temp && !(tempw2&0xFF00)) 1.7391 - { 1.7392 - tempw2=tempw%temp; 1.7393 - AH=tempw2; 1.7394 - tempw/=temp; 1.7395 - AL=tempw&0xFF; 1.7396 - if (!cpu_iscyrix) flags|=0x8D5; /*Not a Cyrix*/ 1.7397 - } 1.7398 - else 1.7399 - { 1.7400 -// fatal("DIVb BY 0\n"); 1.7401 - pc=oldpc; 1.7402 - if (msw&1) pmodeint(0,0); 1.7403 - else 1.7404 - { 1.7405 -// pclog("%04X:%04X\n",cs>>4,pc); 1.7406 - writememw(ss,(SP-2)&0xFFFF,flags); 1.7407 - writememw(ss,(SP-4)&0xFFFF,CS); 1.7408 - writememw(ss,(SP-6)&0xFFFF,pc); 1.7409 - SP-=6; 1.7410 - flags&=~I_FLAG; 1.7411 - oxpc=pc; 1.7412 - pc=readmemw(0,0); 1.7413 - loadcs(readmemw(0,2)); 1.7414 - } 1.7415 -// cs=loadcs(CS); 1.7416 -// cs=CS<<4; 1.7417 - } 1.7418 - cycles-=(is486)?16:14; 1.7419 - break; 1.7420 - case 0x38: /*IDIV AL,b*/ 1.7421 -// pclog("IDIV %04X/%02X\n",tempw,temp); 1.7422 - tempws=(int)(int16_t)AX; 1.7423 - if (temp!=0) tempws2=tempws/(int)((int8_t)temp); 1.7424 - temps=tempws2&0xFF; 1.7425 - if ((temp!=0) && ((int)temps==tempws2)) 1.7426 - { 1.7427 - tempw2=tempws%(int)((int8_t)temp); 1.7428 - AH=tempw2&0xFF; 1.7429 - AL=tempws2&0xFF; 1.7430 - if (!cpu_iscyrix) flags|=0x8D5; /*Not a Cyrix*/ 1.7431 - } 1.7432 - else 1.7433 - { 1.7434 - pclog("IDIVb exception - %X / %08X = %X\n",tempws,temp,tempws2); 1.7435 -// pclog("IDIVb BY 0 %04X:%04X\n",cs>>4,pc); 1.7436 - pc=oldpc; 1.7437 - if (msw&1) pmodeint(0,0); 1.7438 - else 1.7439 - { 1.7440 - writememw(ss,(SP-2)&0xFFFF,flags); 1.7441 - writememw(ss,(SP-4)&0xFFFF,CS); 1.7442 - writememw(ss,(SP-6)&0xFFFF,pc); 1.7443 - SP-=6; 1.7444 - flags&=~I_FLAG; 1.7445 - oxpc=pc; 1.7446 - pc=readmemw(0,0); 1.7447 - loadcs(readmemw(0,2)); 1.7448 - } 1.7449 -// cs=loadcs(CS); 1.7450 -// cs=CS<<4; 1.7451 -// pclog("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x38); 1.7452 - } 1.7453 - cycles-=19; 1.7454 - break; 1.7455 - 1.7456 - default: 1.7457 - pclog("Bad F6 opcode %02X\n",rmdat&0x38); 1.7458 - x86illegal(); 1.7459 - } 1.7460 - break; 1.7461 - 1.7462 - case 0xF7: case 0x2F7: 1.7463 - fetchea(); 1.7464 - tempw=geteaw(); if (abrt) break; 1.7465 - switch (rmdat&0x38) 1.7466 - { 1.7467 - case 0x00: /*TEST w*/ 1.7468 - tempw2=getword(); if (abrt) break; 1.7469 -// if (output==3) pclog("TEST %04X %04X\n",tempw,tempw2); 1.7470 - setznp16(tempw&tempw2); 1.7471 - if (is486) cycles-=((mod==3)?1:2); 1.7472 - else cycles-=((mod==3)?2:5); 1.7473 - break; 1.7474 - case 0x10: /*NOT w*/ 1.7475 - seteaw(~tempw); 1.7476 - cycles -= (mod == 3) ? timing_rr : timing_mm; 1.7477 - break; 1.7478 - case 0x18: /*NEG w*/ 1.7479 - setsub16(0,tempw); 1.7480 - tempw=0-tempw; 1.7481 - seteaw(tempw); 1.7482 - cycles -= (mod == 3) ? timing_rr : timing_mm; 1.7483 - break; 1.7484 - case 0x20: /*MUL AX,w*/ 1.7485 -// setznp16(AX); 1.7486 - templ=AX*tempw; 1.7487 - AX=templ&0xFFFF; 1.7488 - DX=templ>>16; 1.7489 -// if (AX|DX) flags&=~Z_FLAG; 1.7490 -// else flags|=Z_FLAG; 1.7491 - if (DX) flags|=(C_FLAG|V_FLAG); 1.7492 - else flags&=~(C_FLAG|V_FLAG); 1.7493 - cycles-=21; 1.7494 - break; 1.7495 - case 0x28: /*IMUL AX,w*/ 1.7496 -// setznp16(AX); 1.7497 -// pclog("IMUL %i %i ",(int)((int16_t)AX),(int)((int16_t)tempw)); 1.7498 - templ=(int)((int16_t)AX)*(int)((int16_t)tempw); 1.7499 -// pclog("%i ",tempws); 1.7500 - AX=templ&0xFFFF; 1.7501 - DX=templ>>16; 1.7502 - if (DX && DX!=0xFFFF) flags|=(C_FLAG|V_FLAG); 1.7503 - else flags&=~(C_FLAG|V_FLAG); 1.7504 - cycles-=22; 1.7505 - break; 1.7506 - case 0x30: /*DIV AX,w*/ 1.7507 - templ=(DX<<16)|AX; 1.7508 - if (tempw) templ2=templ/tempw; 1.7509 - if (tempw && !(templ2&0xFFFF0000)) 1.7510 - { 1.7511 - tempw2=templ%tempw; 1.7512 - DX=tempw2; 1.7513 - templ/=tempw; 1.7514 - AX=templ&0xFFFF; 1.7515 - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ 1.7516 - } 1.7517 - else 1.7518 - { 1.7519 -// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); 1.7520 - pc=oldpc; 1.7521 - if (msw&1) pmodeint(0,0); 1.7522 - else 1.7523 - { 1.7524 -// pclog("%04X:%04X\n",cs>>4,pc); 1.7525 - writememw(ss,(SP-2)&0xFFFF,flags); 1.7526 - writememw(ss,(SP-4)&0xFFFF,CS); 1.7527 - writememw(ss,(SP-6)&0xFFFF,pc); 1.7528 - SP-=6; 1.7529 - flags&=~I_FLAG; 1.7530 - oxpc=pc; 1.7531 - pc=readmemw(0,0); 1.7532 - loadcs(readmemw(0,2)); 1.7533 - } 1.7534 -// cs=loadcs(CS); 1.7535 -// cs=CS<<4; 1.7536 -// pclog("Div by zero %04X:%04X %02X %02X 1\n",cs>>4,pc,0xf7,0x30); 1.7537 - } 1.7538 - cycles-=(is486)?24:22; 1.7539 - break; 1.7540 - case 0x38: /*IDIV AX,w*/ 1.7541 - tempws=(int)((DX<<16)|AX); 1.7542 - if (tempw!=0) tempws2=tempws/(int)((int16_t)tempw); 1.7543 - temps16=tempws2&0xFFFF; 1.7544 -// pclog("IDIV %i %i ",tempws,tempw); 1.7545 - if ((tempw!=0) && ((int)temps16==tempws2)) 1.7546 - { 1.7547 - DX=tempws%(int)((int16_t)tempw); 1.7548 - AX=tempws2&0xFFFF; 1.7549 - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ 1.7550 - } 1.7551 - else 1.7552 - { 1.7553 - pclog("IDIVw exception - %X / %08X = %X\n",tempws,tempw,tempws2); 1.7554 -// pclog("IDIVw BY 0 %04X:%04X\n",cs>>4,pc); 1.7555 -// DX=0; 1.7556 -// AX=0xFFFF; 1.7557 - pc=oldpc; 1.7558 - if (msw&1) pmodeint(0,0); 1.7559 - else 1.7560 - { 1.7561 -// pclog("%04X:%04X\n",cs>>4,pc); 1.7562 - writememw(ss,(SP-2)&0xFFFF,flags); 1.7563 - writememw(ss,(SP-4)&0xFFFF,CS); 1.7564 - writememw(ss,(SP-6)&0xFFFF,pc); 1.7565 - SP-=6; 1.7566 - flags&=~I_FLAG; 1.7567 - oxpc=pc; 1.7568 - pc=readmemw(0,0); 1.7569 - loadcs(readmemw(0,2)); 1.7570 - } 1.7571 -// cs=loadcs(CS); 1.7572 -// cs=CS<<4; 1.7573 -// pclog("Div by zero %04X:%04X %02X %02X 1\n",cs>>4,pc,0xf7,0x38); 1.7574 - } 1.7575 - cycles-=27; 1.7576 - break; 1.7577 - 1.7578 - default: 1.7579 - pclog("Bad F7 opcode %02X\n",rmdat&0x38); 1.7580 - x86illegal(); 1.7581 - } 1.7582 - break; 1.7583 - case 0x1F7: case 0x3F7: 1.7584 - fetchea(); 1.7585 - templ=geteal(); if (abrt) break; 1.7586 - switch (rmdat&0x38) 1.7587 - { 1.7588 - case 0x00: /*TEST l*/ 1.7589 - templ2=getlong(); if (abrt) break; 1.7590 - setznp32(templ&templ2); 1.7591 - if (is486) cycles-=((mod==3)?1:2); 1.7592 - else cycles-=((mod==3)?2:5); 1.7593 - break; 1.7594 - case 0x10: /*NOT l*/ 1.7595 - seteal(~templ); 1.7596 - cycles -= (mod == 3) ? timing_rr : timing_mml; 1.7597 - break; 1.7598 - case 0x18: /*NEG l*/ 1.7599 - setsub32(0,templ); 1.7600 - templ=0-templ; 1.7601 - seteal(templ); 1.7602 - cycles -= (mod == 3) ? timing_rr : timing_mml; 1.7603 - break; 1.7604 - case 0x20: /*MUL EAX,l*/ 1.7605 - temp64=(uint64_t)EAX*(uint64_t)templ; 1.7606 - EAX=temp64&0xFFFFFFFF; 1.7607 - EDX=temp64>>32; 1.7608 - if (EDX) flags|= (C_FLAG|V_FLAG); 1.7609 - else flags&=~(C_FLAG|V_FLAG); 1.7610 - cycles-=21; 1.7611 - break; 1.7612 - case 0x28: /*IMUL EAX,l*/ 1.7613 - temp64=(int64_t)(int32_t)EAX*(int64_t)(int32_t)templ; 1.7614 - EAX=temp64&0xFFFFFFFF; 1.7615 - EDX=temp64>>32; 1.7616 - if (EDX && EDX!=0xFFFFFFFF) flags|=(C_FLAG|V_FLAG); 1.7617 - else flags&=~(C_FLAG|V_FLAG); 1.7618 - cycles-=38; 1.7619 - break; 1.7620 - case 0x30: /*DIV EAX,l*/ 1.7621 - divl(templ); 1.7622 - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ 1.7623 - cycles-=(is486)?40:38; 1.7624 - break; 1.7625 - case 0x38: /*IDIV EAX,l*/ 1.7626 - idivl((int32_t)templ); 1.7627 - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ 1.7628 - cycles-=43; 1.7629 - break; 1.7630 - 1.7631 - default: 1.7632 - pclog("Bad F7 opcode %02X\n",rmdat&0x38); 1.7633 - x86illegal(); 1.7634 - } 1.7635 - break; 1.7636 - 1.7637 - case 0xF8: case 0x1F8: case 0x2F8: case 0x3F8: /*CLC*/ 1.7638 - flags&=~C_FLAG; 1.7639 - cycles-=2; 1.7640 - break; 1.7641 - case 0xF9: case 0x1F9: case 0x2F9: case 0x3F9: /*STC*/ 1.7642 -// pclog("STC %04X\n",pc); 1.7643 - flags|=C_FLAG; 1.7644 - cycles-=2; 1.7645 - break; 1.7646 - case 0xFA: case 0x1FA: case 0x2FA: case 0x3FA: /*CLI*/ 1.7647 - if (!IOPLp) 1.7648 - { 1.7649 -// output=3; 1.7650 -// pclog("Can't CLI %i %i %04X:%08X\n",IOPL,CPL,CS,pc); 1.7651 -// if (CS==0x1C7 && pc==0x5BE) output=3; 1.7652 - x86gpf(NULL,0); 1.7653 - } 1.7654 - else 1.7655 - flags&=~I_FLAG; 1.7656 -// pclog("CLI at %04X:%04X\n",cs>>4,pc); 1.7657 - cycles-=3; 1.7658 - break; 1.7659 - case 0xFB: case 0x1FB: case 0x2FB: case 0x3FB: /*STI*/ 1.7660 - if (!IOPLp) 1.7661 - { 1.7662 -// pclog("Can't STI %04X:%08X\n",CS,pc); 1.7663 -// output=3; 1.7664 - x86gpf(NULL,0); 1.7665 - } 1.7666 - else 1.7667 - flags|=I_FLAG; 1.7668 -// pclog("STI at %04X:%04X\n",cs>>4,pc); 1.7669 - cycles-=2; 1.7670 - break; 1.7671 - case 0xFC: case 0x1FC: case 0x2FC: case 0x3FC: /*CLD*/ 1.7672 - flags&=~D_FLAG; 1.7673 - cycles-=2; 1.7674 - break; 1.7675 - case 0xFD: case 0x1FD: case 0x2FD: case 0x3FD: /*STD*/ 1.7676 - flags|=D_FLAG; 1.7677 - cycles-=2; 1.7678 - break; 1.7679 - 1.7680 - case 0xFE: case 0x1FE: case 0x2FE: case 0x3FE: /*INC/DEC b*/ 1.7681 - fetchea(); 1.7682 - temp=geteab(); if (abrt) break; 1.7683 - if (rmdat&0x38) 1.7684 - { 1.7685 - seteab(temp-1); if (abrt) break; 1.7686 - flags&=~V_FLAG; 1.7687 - setsub8nc(temp,1); 1.7688 - temp2=temp-1; 1.7689 - if ((temp&0x80) && !(temp2&0x80)) flags|=V_FLAG; 1.7690 - } 1.7691 - else 1.7692 - { 1.7693 - seteab(temp+1); if (abrt) break; 1.7694 - flags&=~V_FLAG; 1.7695 - setadd8nc(temp,1); 1.7696 - temp2=temp+1; 1.7697 - if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG; 1.7698 - } 1.7699 - cycles -= (mod == 3) ? timing_rr : timing_mm; 1.7700 - break; 1.7701 - 1.7702 - case 0xFF: case 0x2FF: 1.7703 - fetchea(); 1.7704 - switch (rmdat&0x38) 1.7705 - { 1.7706 - case 0x00: /*INC w*/ 1.7707 - tempw=geteaw(); if (abrt) break; 1.7708 - seteaw(tempw+1); if (abrt) break; 1.7709 - setadd16nc(tempw,1); 1.7710 - cycles -= (mod == 3) ? timing_rr : timing_mm; 1.7711 - break; 1.7712 - case 0x08: /*DEC w*/ 1.7713 - tempw=geteaw(); if (abrt) break; 1.7714 - seteaw(tempw-1); if (abrt) break; 1.7715 - setsub16nc(tempw,1); 1.7716 - cycles -= (mod == 3) ? timing_rr : timing_mm; 1.7717 - break; 1.7718 - case 0x10: /*CALL*/ 1.7719 - tempw=geteaw(); 1.7720 - if (output) pclog("CALL %04X %08X:%08X\n", tempw, easeg, eaaddr); 1.7721 - if (abrt) break; 1.7722 - if (ssegs) ss=oldss; 1.7723 - if (stack32) 1.7724 - { 1.7725 - writememw(ss,ESP-2,pc); if (abrt) break; 1.7726 - ESP-=2; 1.7727 - } 1.7728 - else 1.7729 - { 1.7730 - writememw(ss,(SP-2)&0xFFFF,pc); if (abrt) break; 1.7731 - SP-=2; 1.7732 - } 1.7733 - pc=tempw; 1.7734 - if (is486) cycles-=5; 1.7735 - else cycles-=((mod==3)?7:10); 1.7736 - break; 1.7737 - case 0x18: /*CALL far*/ 1.7738 - tempw=readmemw(easeg,eaaddr); 1.7739 - tempw2=readmemw(easeg,(eaaddr+2)); if (output==3) pclog("CALL FAR %04X:%04X\n",tempw,tempw2); if (abrt) break; 1.7740 - tempw3=CS; 1.7741 - templ2=pc; 1.7742 - if (ssegs) ss=oldss; 1.7743 - oxpc=pc; 1.7744 - pc=tempw; 1.7745 - optype=CALL; 1.7746 - cgate32=0; 1.7747 - if (msw&1) loadcscall(tempw2); 1.7748 - else loadcs(tempw2); 1.7749 - optype=0; 1.7750 - if (abrt) break; 1.7751 - oldss=ss; 1.7752 - if (cgate32) goto writecall32_2; 1.7753 - writecall16_2: 1.7754 - if (stack32) 1.7755 - { 1.7756 - writememw(ss,ESP-2,tempw3); 1.7757 - writememw(ss,ESP-4,templ2); 1.7758 - ESP-=4; 1.7759 - } 1.7760 - else 1.7761 - { 1.7762 - writememw(ss,(SP-2)&0xFFFF,tempw3); 1.7763 - writememw(ss,((SP-4)&0xFFFF),templ2); 1.7764 - SP-=4; 1.7765 - } 1.7766 - cycles-=(is486)?17:22; 1.7767 - break; 1.7768 - case 0x20: /*JMP*/ 1.7769 - tempw=geteaw(); if (abrt) break; 1.7770 - pc=tempw; 1.7771 - if (is486) cycles-=5; 1.7772 - else cycles-=((mod==3)?7:10); 1.7773 - break; 1.7774 - case 0x28: /*JMP far*/ 1.7775 - oxpc=pc; 1.7776 - tempw=readmemw(easeg,eaaddr); 1.7777 - tempw2=readmemw(easeg,eaaddr+2); if (abrt) break; 1.7778 - pc=tempw; 1.7779 - loadcsjmp(tempw2,oxpc); if (abrt) break; 1.7780 - cycles-=(is486)?13:12; 1.7781 - break; 1.7782 - case 0x30: /*PUSH w*/ 1.7783 - tempw=geteaw(); if (abrt) break; 1.7784 - if (ssegs) ss=oldss; 1.7785 - if (stack32) 1.7786 - { 1.7787 - writememw(ss,ESP-2,tempw); if (abrt) break; 1.7788 - ESP-=2; 1.7789 - } 1.7790 - else 1.7791 - { 1.7792 -// if (output) pclog("PUSH %04X to %04X\n",tempw,SP-2); 1.7793 - writememw(ss,((SP-2)&0xFFFF),tempw); if (abrt) break; 1.7794 - SP-=2; 1.7795 - } 1.7796 - cycles-=((mod==3)?2:5); 1.7797 - break; 1.7798 - 1.7799 - default: 1.7800 - pclog("Bad FF opcode %02X\n",rmdat&0x38); 1.7801 - x86illegal(); 1.7802 - } 1.7803 - break; 1.7804 - case 0x1FF: case 0x3FF: 1.7805 - fetchea(); 1.7806 - switch (rmdat&0x38) 1.7807 - { 1.7808 - case 0x00: /*INC l*/ 1.7809 - templ=geteal(); if (abrt) break; 1.7810 - seteal(templ+1); if (abrt) break; 1.7811 - setadd32nc(templ,1); 1.7812 - cycles -= (mod == 3) ? timing_rr : timing_mml; 1.7813 - break; 1.7814 - case 0x08: /*DEC l*/ 1.7815 - templ=geteal(); if (abrt) break; 1.7816 - seteal(templ-1); if (abrt) break; 1.7817 - setsub32nc(templ,1); 1.7818 - cycles -= (mod == 3) ? timing_rr : timing_mml; 1.7819 - break; 1.7820 - case 0x10: /*CALL*/ 1.7821 - templ=geteal(); if (abrt) break; 1.7822 - if (ssegs) ss=oldss; 1.7823 - if (stack32) 1.7824 - { 1.7825 - writememl(ss,ESP-4,pc); if (abrt) break; 1.7826 - ESP-=4; 1.7827 - } 1.7828 - else 1.7829 - { 1.7830 - writememl(ss,(SP-4)&0xFFFF,pc); if (abrt) break; 1.7831 - SP-=4; 1.7832 - } 1.7833 - pc=templ; 1.7834 - if (pc==0xFFFFFFFF) pclog("Failed CALL!\n"); 1.7835 - if (is486) cycles-=5; 1.7836 - else cycles-=((mod==3)?7:10); 1.7837 - break; 1.7838 - case 0x18: /*CALL far*/ 1.7839 - templ=readmeml(easeg,eaaddr); 1.7840 - tempw2=readmemw(easeg,(eaaddr+4)); if (abrt) break; 1.7841 - tempw3=CS; 1.7842 - templ2=pc; 1.7843 - if (ssegs) ss=oldss; 1.7844 - oxpc=pc; 1.7845 - pc=templ; 1.7846 - optype=CALL; 1.7847 - cgate16=0; 1.7848 - if (msw&1) loadcscall(tempw2); 1.7849 - else loadcs(tempw2); 1.7850 - optype=0; 1.7851 - if (abrt) break; 1.7852 - oldss=ss; 1.7853 - if (cgate16) goto writecall16_2; 1.7854 - writecall32_2: 1.7855 - if (stack32) 1.7856 - { 1.7857 - writememl(ss,ESP-4,tempw3); 1.7858 - writememl(ss,ESP-8,templ2); 1.7859 - ESP-=8; 1.7860 - } 1.7861 - else 1.7862 - { 1.7863 - writememl(ss,(SP-4)&0xFFFF,tempw3); 1.7864 - writememl(ss,(SP-8)&0xFFFF,templ2); 1.7865 - SP-=8; 1.7866 - } 1.7867 - if (pc==0xFFFFFFFF) pclog("Failed CALL far!\n"); 1.7868 - cycles-=(is486)?17:22; 1.7869 - break; 1.7870 - case 0x20: /*JMP*/ 1.7871 - templ=geteal(); if (abrt) break; 1.7872 - pc=templ; 1.7873 - if (is486) cycles-=5; 1.7874 - else cycles-=((mod==3)?7:12); 1.7875 - if (pc==0xFFFFFFFF) pclog("Failed JMP!\n"); 1.7876 - break; 1.7877 - case 0x28: /*JMP far*/ 1.7878 - oxpc=pc; 1.7879 - templ=readmeml(easeg,eaaddr); 1.7880 - templ2=readmeml(easeg,eaaddr+4); if (abrt) break; 1.7881 - pc=templ; 1.7882 - loadcsjmp(templ2,oxpc); 1.7883 - if (pc==0xFFFFFFFF) pclog("Failed JMP far!\n"); 1.7884 - cycles-=(is486)?13:12; 1.7885 - break; 1.7886 - case 0x30: /*PUSH l*/ 1.7887 - templ=geteal(); if (abrt) break; 1.7888 - if (ssegs) ss=oldss; 1.7889 - if (stack32) 1.7890 - { 1.7891 - writememl(ss,ESP-4,templ); if (abrt) break; 1.7892 - ESP-=4; 1.7893 - } 1.7894 - else 1.7895 - { 1.7896 - writememl(ss,((SP-4)&0xFFFF),templ); if (abrt) break; 1.7897 - SP-=4; 1.7898 - } 1.7899 - cycles-=((mod==3)?2:5); 1.7900 - break; 1.7901 - 1.7902 - default: 1.7903 - pclog("Bad 32-bit FF opcode %02X\n",rmdat&0x38); 1.7904 - x86illegal(); 1.7905 - } 1.7906 - break; 1.7907 - 1.7908 - default: 1.7909 -// pc--; 1.7910 -// cycles-=8; 1.7911 -// break; 1.7912 - pclog("Bad opcode %02X %i %03X at %04X:%04X from %04X:%04X %08X\n",opcode,op32>>8,opcode|op32,cs>>4,pc,old8>>16,old8&0xFFFF,old82); 1.7913 - x86illegal(); 1.7914 - } 1.7915 - opcodeend: 1.7916 - if (!use32) pc&=0xFFFF; 1.7917 - 1.7918 + pclog("Output on\n"); 1.7919 + output = 3; 1.7920 + }*/ 1.7921 + if ((cs + pc) == 0xc) 1.7922 + fatal("Dead\n"); 1.7923 if (ssegs) 1.7924 { 1.7925 ds=oldds; 1.7926 @@ -8164,7 +1297,8 @@ 1.7927 } 1.7928 if (abrt) 1.7929 { 1.7930 - 1.7931 + flags_rebuild(); 1.7932 +// pclog("Abort\n"); 1.7933 // if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,abrt); 1.7934 /* if (testr[0]!=EAX) pclog("EAX corrupted %08X\n",pc); 1.7935 if (testr[1]!=EBX) pclog("EBX corrupted %08X\n",pc); 1.7936 @@ -8173,8 +1307,8 @@ 1.7937 if (testr[4]!=ESI) pclog("ESI corrupted %08X\n",pc); 1.7938 if (testr[5]!=EDI) pclog("EDI corrupted %08X\n",pc); 1.7939 if (testr[6]!=EBP) pclog("EBP corrupted %08X\n",pc); 1.7940 - if (testr[7]!=ESP) pclog("ESP corrupted %08X\n",pc); 1.7941 - if (testr[8]!=flags) pclog("FLAGS corrupted %08X\n",pc);*/ 1.7942 + if (testr[7]!=ESP) pclog("ESP corrupted %08X\n",pc);*/ 1.7943 +/* if (testr[8]!=flags) pclog("FLAGS corrupted %08X\n",pc);*/ 1.7944 tempi = abrt; 1.7945 abrt = 0; 1.7946 x86_doabrt(tempi); 1.7947 @@ -8183,7 +1317,7 @@ 1.7948 abrt = 0; 1.7949 CS = oldcs; 1.7950 pc = oldpc; 1.7951 - pclog("Double fault %i %i\n", ins, resets); 1.7952 + pclog("Double fault %i\n", ins); 1.7953 pmodeint(8, 0); 1.7954 if (abrt) 1.7955 { 1.7956 @@ -8195,11 +1329,12 @@ 1.7957 } 1.7958 cycdiff=oldcyc-cycles; 1.7959 1.7960 - if (trap && (flags&T_FLAG) && !noint) 1.7961 + if (trap && (flags&T_FLAG)) 1.7962 { 1.7963 + flags_rebuild(); 1.7964 // oldpc=pc; 1.7965 // oldcs=CS; 1.7966 -// printf("TRAP!!! %04X:%04X\n",CS,pc); 1.7967 +// pclog("TRAP!!! %04X:%04X\n",CS,pc); 1.7968 if (msw&1) 1.7969 { 1.7970 pmodeint(1,0); 1.7971 @@ -8217,16 +1352,24 @@ 1.7972 loadcs(readmemw(0,addr+2)); 1.7973 } 1.7974 } 1.7975 - else if ((flags&I_FLAG) && (((pic.pend&~pic.mask)&~pic.mask2) || ((pic2.pend&~pic2.mask)&~pic2.mask2)) && !noint) 1.7976 + else if (nmi && nmi_enable) 1.7977 + { 1.7978 + oldpc = pc; 1.7979 + oldcs = CS; 1.7980 +// pclog("NMI\n"); 1.7981 + x86_int(2); 1.7982 + nmi_enable = 0; 1.7983 + } 1.7984 + else if ((flags&I_FLAG) && pic_intpending) 1.7985 { 1.7986 temp=picinterrupt(); 1.7987 if (temp!=0xFF) 1.7988 { 1.7989 // if (temp == 0x54) pclog("Take int 54\n"); 1.7990 // if (output) output=3; 1.7991 -// pclog("Hardware int %02X %i %i %04X(%08X):%08X\n",temp,ins, ins2, CS,cs,pc); 1.7992 +// if (temp == 0xd) pclog("Hardware int %02X %i %04X(%08X):%08X\n",temp,ins, CS,cs,pc); 1.7993 // if (temp==0x54) output=3; 1.7994 - if (inhlt) pc++; 1.7995 + flags_rebuild(); 1.7996 if (msw&1) 1.7997 { 1.7998 pmodeint(temp,0); 1.7999 @@ -8245,133 +1388,42 @@ 1.8000 loadcs(readmemw(0,addr+2)); 1.8001 // if (temp==0x76) pclog("INT to %04X:%04X\n",CS,pc); 1.8002 } 1.8003 - inint=1; 1.8004 +// pclog("Now at %04X(%08X):%08X\n", CS, cs, pc); 1.8005 } 1.8006 } 1.8007 - if (noint) noint=0; 1.8008 + 1.8009 +// tempi = ZF_SET() ? Z_FLAG : 0; 1.8010 +// if (tempi != (flags & Z_FLAG)) 1.8011 +// fatal("Z flag mismatch %02X %08X\n", opcode, fetchdat); 1.8012 ins++; 1.8013 insc++; 1.8014 - 1.8015 -/* if (times && ins == 9000000) output = 3; 1.8016 - if (CS == 0x1000 && pc == 0x1200) 1.8017 - fatal("Hit it\n");*/ 1.8018 -// if (!ins) ins2++; 1.8019 - 1.8020 +/*output = 3; 1.8021 + if (ins == 1372108) 1.8022 + fatal("here2\n"); 1.8023 + if (ins == 50966339) 1.8024 + fatal("here\n");*/ 1.8025 + if (timetolive) 1.8026 + { 1.8027 + timetolive--; 1.8028 + if (!timetolive) 1.8029 + fatal("Life expired\n"); 1.8030 + } 1.8031 +// if (ins == 97300000) output = 3; 1.8032 } 1.8033 1.8034 - keybsenddelay -= cycdiff; 1.8035 + tsc += cycdiff; 1.8036 + 1.8037 +/* keybsenddelay -= cycdiff; 1.8038 if (keybsenddelay<1) 1.8039 { 1.8040 keybsenddelay = 1000; 1.8041 keyboard_at_poll(); 1.8042 - } 1.8043 + }*/ 1.8044 1.8045 pit.c[0]-=cycdiff; 1.8046 pit.c[1]-=cycdiff; 1.8047 if (ppi.pb&1) pit.c[2]-=cycdiff; 1.8048 if ((pit.c[0]<1)||(pit.c[1]<1)||(pit.c[2]<1)) pit_poll(); 1.8049 - spktime-=cycdiff; 1.8050 - if (spktime<=0.0) 1.8051 - { 1.8052 - spktime+=SPKCONST; 1.8053 -// pclog("1Poll spk\n"); 1.8054 - pollspk(); 1.8055 - pollgussamp(); 1.8056 - getsbsamp(); 1.8057 - polladlib(); 1.8058 - getdacsamp(); 1.8059 -// pclog("2Poll spk\n"); 1.8060 - } 1.8061 - soundtime-=cycdiff; 1.8062 - if (soundtime<=0.0) 1.8063 - { 1.8064 - soundtime+=SOUNDCONST; 1.8065 -// pclog("1Poll sound60hz\n"); 1.8066 - pollsound60hz(); 1.8067 -// pclog("2Poll sound60hz\n"); 1.8068 - } 1.8069 - gustime-=cycdiff; 1.8070 - while (gustime<=0.0) 1.8071 - { 1.8072 - gustime+=GUSCONST; 1.8073 - pollgus(); 1.8074 - } 1.8075 - gustime2-=cycdiff; 1.8076 - while (gustime2<=0.0) 1.8077 - { 1.8078 - gustime2+=GUSCONST2; 1.8079 - pollgus2(); 1.8080 - } 1.8081 - vidtime-=cycdiff; 1.8082 - if (vidtime<=0.0) 1.8083 - { 1.8084 -// pclog("1Poll video\n"); 1.8085 - pollvideo(); 1.8086 -// pclog("2Poll video\n"); 1.8087 - } 1.8088 - if (disctime) 1.8089 - { 1.8090 - disctime-=(cycdiff); 1.8091 - if (disctime<=0) 1.8092 - { 1.8093 -// pclog("1Poll disc\n"); 1.8094 - disctime=0; 1.8095 - fdc_poll(); 1.8096 -// pclog("2Poll disc\n"); 1.8097 - } 1.8098 - } 1.8099 - if (mousedelay) 1.8100 - { 1.8101 - mousedelay-=20; 1.8102 - if (!mousedelay) 1.8103 - { 1.8104 -// pclog("1Poll mouse\n"); 1.8105 - mousecallback(); 1.8106 -// pclog("2Poll disc\n"); 1.8107 - } 1.8108 - } 1.8109 - if (sbenable) 1.8110 - { 1.8111 - sbcount-=cycdiff; 1.8112 - if (sbcount<0) 1.8113 - { 1.8114 - sbcount+=sblatcho; 1.8115 - pollsb(); 1.8116 - } 1.8117 - } 1.8118 - if (sb_enable_i) 1.8119 - { 1.8120 - sb_count_i-=cycdiff; 1.8121 - if (sb_count_i<0) 1.8122 - { 1.8123 - sb_count_i+=sblatchi; 1.8124 - sb_poll_i(); 1.8125 - } 1.8126 - } 1.8127 - if (idecallback[0]) 1.8128 - { 1.8129 - idecallback[0]--; 1.8130 - if (idecallback[0]<=0) 1.8131 - { 1.8132 -// pclog("IDE time over\n"); 1.8133 - idecallback[0]=0; 1.8134 - callbackide(0); 1.8135 - } 1.8136 - } 1.8137 - if (idecallback[1]) 1.8138 - { 1.8139 - idecallback[1]--; 1.8140 - if (idecallback[1]<=0) 1.8141 - { 1.8142 -// pclog("IDE time over\n"); 1.8143 - idecallback[1]=0; 1.8144 - callbackide(1); 1.8145 - } 1.8146 - } 1.8147 - rtctime-=cycdiff; 1.8148 - if (rtctime<0) 1.8149 - { 1.8150 - nvr_rtc(); 1.8151 - } 1.8152 + timer_clock(cycdiff); 1.8153 } 1.8154 }
2.1 --- a/src/Makefile.mingw Sun Apr 21 14:54:35 2013 +0100 2.2 +++ b/src/Makefile.mingw Mon May 27 17:46:42 2013 +0100 2.3 @@ -3,20 +3,22 @@ 2.4 CC = gcc.exe 2.5 WINDRES = windres.exe 2.6 CFLAGS = -O3 -march=i686 -fomit-frame-pointer 2.7 -OBJ = 286.o 386.o acer386sx.o adlib.o ali1429.o amstrad.o cdrom-ioctl.o cms.o \ 2.8 - config.o cpu.o dac.o dma.o ega.o fdc.o gus.o harddisk.o \ 2.9 - headland.o ide.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \ 2.10 +OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \ 2.11 + config.o cpu.o dac.o device.o dma.o ega.o fdc.o harddisk.o \ 2.12 + headland.o i430vx.o ide.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \ 2.13 keyboard_olim24.o keyboard_xt.o lpt.o mcr.o mem.o model.o \ 2.14 mouse.o mouse_ps2.o mouse_serial.o neat.o nvr.o olivetti_m24.o \ 2.15 - opti.o pc.o pci.o pic.o pit.o \ 2.16 - ppi.o psg.o sblaster.o serial.o sound.o soundopenal.o um8881f.o \ 2.17 - vid_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \ 2.18 - vid_et4000w32i.o vid_hercules.o vid_icd2061.o vid_mda.o vid_olivetti_m24.o \ 2.19 - vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o \ 2.20 - vid_pc200.o vid_s3.o vid_sdac_ramdac.o vid_stg_ramdac.o \ 2.21 - vid_svga.o vid_tandy.o vid_tkd8001_ramdac.o vid_tvga.o \ 2.22 - vid_unk_ramdac.o video.o wd76c10.o win.o win-ddraw.o \ 2.23 - win-keyboard.o win-mouse.o win-timer.o win-video.o x86.o \ 2.24 + opti.o pc.o pci.o pic.o piix.o pit.o ppi.o serial.o sound.o sound_adlib.o \ 2.25 + sound_adlibgold.o sound_cms.o sound_gus.o sound_opl.o sound_pas16.o sound_sb.o \ 2.26 + sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_wss.o soundopenal.o timer.o \ 2.27 + um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ 2.28 + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_ega.o \ 2.29 + vid_et4000.o vid_et4000w32.o vid_et4000w32i.o vid_hercules.o vid_icd2061.o \ 2.30 + vid_ics2595.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o \ 2.31 + vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \ 2.32 + vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tkd8001_ramdac.o \ 2.33 + vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o video.o wd76c10.o \ 2.34 + win.o win-ddraw.o win-keyboard.o win-mouse.o win-timer.o win-video.o \ 2.35 x86seg.o x87.o xtide.o pc.res 2.36 FMOBJ = fmopl.o ymf262.o 2.37
3.1 --- a/src/acer386sx.c Sun Apr 21 14:54:35 2013 +0100 3.2 +++ b/src/acer386sx.c Mon May 27 17:46:42 2013 +0100 3.3 @@ -7,7 +7,7 @@ 3.4 static int acer_index = 0; 3.5 static uint8_t acer_regs[256]; 3.6 3.7 -void acer386sx_write(uint16_t addr, uint8_t val) 3.8 +void acer386sx_write(uint16_t addr, uint8_t val, void *priv) 3.9 { 3.10 if (addr & 1) 3.11 acer_regs[acer_index] = val; 3.12 @@ -15,7 +15,7 @@ 3.13 acer_index = val; 3.14 } 3.15 3.16 -uint8_t acer386sx_read(uint16_t addr) 3.17 +uint8_t acer386sx_read(uint16_t addr, void *priv) 3.18 { 3.19 if (addr & 1) 3.20 { 3.21 @@ -29,5 +29,5 @@ 3.22 3.23 void acer386sx_init() 3.24 { 3.25 - io_sethandler(0x0022, 0x0002, acer386sx_read, NULL, NULL, acer386sx_write, NULL, NULL); 3.26 + io_sethandler(0x0022, 0x0002, acer386sx_read, NULL, NULL, acer386sx_write, NULL, NULL, NULL); 3.27 }
4.1 --- a/src/ali1429.c Sun Apr 21 14:54:35 2013 +0100 4.2 +++ b/src/ali1429.c Mon May 27 17:46:42 2013 +0100 4.3 @@ -9,7 +9,7 @@ 4.4 static int ali1429_index; 4.5 static uint8_t ali1429_regs[256]; 4.6 4.7 -void ali1429_write(uint16_t port, uint8_t val) 4.8 +void ali1429_write(uint16_t port, uint8_t val, void *priv) 4.9 { 4.10 // return; 4.11 if (!(port&1)) ali1429_index=val; 4.12 @@ -31,9 +31,9 @@ 4.13 { 4.14 shadowbios=0; 4.15 if (!shadowbios_write) 4.16 - mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL ); 4.17 + mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL, NULL); 4.18 else 4.19 - mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml); 4.20 + mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); 4.21 flushmmucache(); 4.22 } 4.23 break; 4.24 @@ -42,10 +42,10 @@ 4.25 shadowbios_write=val&2; 4.26 switch (val & 3) 4.27 { 4.28 - case 0: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL ); break; 4.29 - case 1: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL ); break; 4.30 - case 2: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml); break; 4.31 - case 3: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); break; 4.32 + case 0: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL, NULL); break; 4.33 + case 1: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL, NULL); break; 4.34 + case 2: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break; 4.35 + case 3: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break; 4.36 } 4.37 4.38 // if (val==0x43) shadowbios=1; 4.39 @@ -56,7 +56,7 @@ 4.40 } 4.41 } 4.42 4.43 -uint8_t ali1429_read(uint16_t port) 4.44 +uint8_t ali1429_read(uint16_t port, void *priv) 4.45 { 4.46 if (!(port&1)) return ali1429_index; 4.47 if ((ali1429_index >= 0xc0 || ali1429_index == 0x20) && cpu_iscyrix) 4.48 @@ -72,5 +72,5 @@ 4.49 4.50 void ali1429_init() 4.51 { 4.52 - io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL); 4.53 + io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, NULL); 4.54 }
5.1 --- a/src/amstrad.c Sun Apr 21 14:54:35 2013 +0100 5.2 +++ b/src/amstrad.c Mon May 27 17:46:42 2013 +0100 5.3 @@ -8,7 +8,7 @@ 5.4 5.5 static uint8_t amstrad_dead; 5.6 5.7 -uint8_t amstrad_read(uint16_t port) 5.8 +uint8_t amstrad_read(uint16_t port, void *priv) 5.9 { 5.10 pclog("amstrad_read : %04X\n",port); 5.11 switch (port) 5.12 @@ -25,7 +25,7 @@ 5.13 return 0xff; 5.14 } 5.15 5.16 -void amstrad_write(uint16_t port, uint8_t val) 5.17 +void amstrad_write(uint16_t port, uint8_t val, void *priv) 5.18 { 5.19 switch (port) 5.20 { 5.21 @@ -37,16 +37,15 @@ 5.22 5.23 static uint8_t mousex,mousey; 5.24 5.25 -void amstrad_mouse_write(uint16_t addr, uint8_t val) 5.26 +void amstrad_mouse_write(uint16_t addr, uint8_t val, void *priv) 5.27 { 5.28 // pclog("Write mouse %04X %02X %04X:%04X\n", addr, val, CS, pc); 5.29 if (addr==0x78) mousex=0; 5.30 else mousey=0; 5.31 } 5.32 5.33 -uint8_t amstrad_mouse_read(uint16_t addr) 5.34 +uint8_t amstrad_mouse_read(uint16_t addr, void *priv) 5.35 { 5.36 - uint8_t temp; 5.37 // printf("Read mouse %04X %04X:%04X %02X\n", addr, CS, pc, (addr == 0x78) ? mousex : mousey); 5.38 if (addr==0x78) return mousex; 5.39 return mousey; 5.40 @@ -73,12 +72,12 @@ 5.41 5.42 void amstrad_init() 5.43 { 5.44 - lpt2_remove(); 5.45 + lpt2_remove_ams(); 5.46 5.47 - io_sethandler(0x0078, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL); 5.48 - io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL); 5.49 - io_sethandler(0x0379, 0x0002, amstrad_read, NULL, NULL, NULL, NULL, NULL); 5.50 - io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL); 5.51 + io_sethandler(0x0078, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); 5.52 + io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); 5.53 + io_sethandler(0x0379, 0x0002, amstrad_read, NULL, NULL, NULL, NULL, NULL, NULL); 5.54 + io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); 5.55 5.56 mouse_poll = amstrad_mouse_poll; 5.57 }
6.1 --- a/src/cdrom-ioctl.c Sun Apr 21 14:54:35 2013 +0100 6.2 +++ b/src/cdrom-ioctl.c Mon May 27 17:46:42 2013 +0100 6.3 @@ -44,7 +44,7 @@ 6.4 { 6.5 RAW_READ_INFO in; 6.6 DWORD count; 6.7 - int c; 6.8 + 6.9 // return; 6.10 // pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); 6.11 if (ioctl_cd_state != CD_PLAYING) 6.12 @@ -143,7 +143,6 @@ 6.13 6.14 static void ioctl_pause(void) 6.15 { 6.16 - long size; 6.17 if (!cdrom_drive) return; 6.18 if (ioctl_cd_state == CD_PLAYING) 6.19 ioctl_cd_state = CD_PAUSED; 6.20 @@ -154,7 +153,6 @@ 6.21 6.22 static void ioctl_resume(void) 6.23 { 6.24 - long size; 6.25 if (!cdrom_drive) return; 6.26 if (ioctl_cd_state == CD_PAUSED) 6.27 ioctl_cd_state = CD_PLAYING; 6.28 @@ -165,7 +163,6 @@ 6.29 6.30 static void ioctl_stop(void) 6.31 { 6.32 - long size; 6.33 if (!cdrom_drive) return; 6.34 ioctl_cd_state = CD_STOPPED; 6.35 // ioctl_open(0); 6.36 @@ -175,7 +172,6 @@ 6.37 6.38 static void ioctl_seek(uint32_t pos) 6.39 { 6.40 - long size; 6.41 if (!cdrom_drive) return; 6.42 // ioctl_cd_state = CD_STOPPED; 6.43 pclog("Seek %08X\n", pos); 6.44 @@ -229,8 +225,7 @@ 6.45 SUB_Q_CHANNEL_DATA sub; 6.46 long size; 6.47 int pos=0; 6.48 - int c; 6.49 - uint32_t temp, cdpos; 6.50 + uint32_t cdpos; 6.51 if (!cdrom_drive) return 0; 6.52 insub.Format = IOCTL_CDROM_CURRENT_POSITION; 6.53 ioctl_open(0);
7.1 --- a/src/config.c Sun Apr 21 14:54:35 2013 +0100 7.2 +++ b/src/config.c Mon May 27 17:46:42 2013 +0100 7.3 @@ -26,7 +26,7 @@ 7.4 if (!f) 7.5 return def; 7.6 7.7 - pclog("Searching for %s\n", name); 7.8 +// pclog("Searching for %s\n", name); 7.9 7.10 while (1) 7.11 { 7.12 @@ -46,9 +46,9 @@ 7.13 if (!buffer[c]) continue; 7.14 name2[d] = 0; 7.15 7.16 - pclog("Comparing %s and %s\n", name, name2); 7.17 +// pclog("Comparing %s and %s\n", name, name2); 7.18 if (strcmp(name, name2)) continue; 7.19 - pclog("Found!\n"); 7.20 +// pclog("Found!\n"); 7.21 7.22 while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c]) 7.23 c++; 7.24 @@ -56,7 +56,7 @@ 7.25 if (!buffer[c]) continue; 7.26 7.27 sscanf(&buffer[c], "%i", &res); 7.28 - pclog("Reading value - %i\n", res); 7.29 +// pclog("Reading value - %i\n", res); 7.30 break; 7.31 } 7.32 7.33 @@ -78,7 +78,7 @@ 7.34 if (!f) 7.35 return config_return_string; 7.36 7.37 - pclog("Searching for %s\n", name); 7.38 +// pclog("Searching for %s\n", name); 7.39 7.40 while (1) 7.41 { 7.42 @@ -98,9 +98,9 @@ 7.43 if (!buffer[c]) continue; 7.44 name2[d] = 0; 7.45 7.46 - pclog("Comparing %s and %s\n", name, name2); 7.47 +// pclog("Comparing %s and %s\n", name, name2); 7.48 if (strcmp(name, name2)) continue; 7.49 - pclog("Found!\n"); 7.50 +// pclog("Found!\n"); 7.51 7.52 while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c]) 7.53 c++; 7.54 @@ -110,11 +110,11 @@ 7.55 strcpy(config_return_string, &buffer[c]); 7.56 7.57 c = strlen(config_return_string) - 1; 7.58 - pclog("string len %i\n", c); 7.59 +// pclog("string len %i\n", c); 7.60 while (config_return_string[c] <= 32 && config_return_string[c]) 7.61 config_return_string[c--] = 0; 7.62 7.63 - pclog("Reading value - %s\n", config_return_string); 7.64 +// pclog("Reading value - %s\n", config_return_string); 7.65 break; 7.66 } 7.67 7.68 @@ -125,19 +125,19 @@ 7.69 void set_config_int(char *head, char *name, int val) 7.70 { 7.71 FILE *f = fopen(config_file, "at"); 7.72 - if (!f) pclog("set_config_int - !f\n"); 7.73 +// if (!f) pclog("set_config_int - !f\n"); 7.74 fprintf(f, "%s = %i\n", name, val); 7.75 - pclog("Write %s = %i\n", name, val); 7.76 +// pclog("Write %s = %i\n", name, val); 7.77 fclose(f); 7.78 - pclog("fclose\n"); 7.79 +// pclog("fclose\n"); 7.80 } 7.81 7.82 void set_config_string(char *head, char *name, char *val) 7.83 { 7.84 FILE *f = fopen(config_file, "at"); 7.85 - if (!f) pclog("set_config_string - !f\n"); 7.86 +// if (!f) pclog("set_config_string - !f\n"); 7.87 fprintf(f, "%s = %s\n", name, val); 7.88 - pclog("Write %s = %s\n", name, val); 7.89 +// pclog("Write %s = %s\n", name, val); 7.90 fclose(f); 7.91 } 7.92
8.1 --- a/src/config.h Sun Apr 21 14:54:35 2013 +0100 8.2 +++ b/src/config.h Mon May 27 17:46:42 2013 +0100 8.3 @@ -3,3 +3,7 @@ 8.4 char *get_config_string(char *head, char *name, char *def); 8.5 void set_config_int(char *head, char *name, int val); 8.6 void set_config_string(char *head, char *name, char *val); 8.7 + 8.8 +char *get_filename(char *s); 8.9 +void append_filename(char *dest, char *s1, char *s2, int size); 8.10 +void put_backslash(char *s);
9.1 --- a/src/cpu.c Sun Apr 21 14:54:35 2013 +0100 9.2 +++ b/src/cpu.c Mon May 27 17:46:42 2013 +0100 9.3 @@ -2,6 +2,7 @@ 9.4 #include "cpu.h" 9.5 #include "model.h" 9.6 #include "io.h" 9.7 +#include "x86_ops.h" 9.8 9.9 int cpu = 3, cpu_manufacturer = 0; 9.10 CPU *cpu_s; 9.11 @@ -9,6 +10,7 @@ 9.12 int cpu_iscyrix; 9.13 int cpu_16bitbus; 9.14 int cpu_busspeed; 9.15 +int cpu_hasrdtsc; 9.16 9.17 int timing_rr; 9.18 int timing_mr, timing_mrl; 9.19 @@ -32,6 +34,9 @@ 9.20 12 = 133 MHz 9.21 13 = 150 MHz 9.22 14 = 160 MHz 9.23 + 15 = 166 MHz 9.24 + 16 = 180 MHz 9.25 + 17 = 200 MHz 9.26 */ 9.27 9.28 CPU cpus_8088[] = 9.29 @@ -197,6 +202,23 @@ 9.30 {"", -1, 0, 0, 0} 9.31 }; 9.32 9.33 +CPU cpus_WinChip[] = 9.34 +{ 9.35 + /*IDT WinChip*/ 9.36 + {"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 0x540, 0x540, 0}, 9.37 + {"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 0x540, 0x540, 0}, 9.38 + {"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 0x540, 0x540, 0}, 9.39 + {"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 0x540, 0x540, 0}, 9.40 + {"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 0x540, 0x540, 0}, 9.41 + {"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 0x540, 0x540, 0}, 9.42 + {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 0x540, 0x540, 0}, 9.43 + {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 0x540, 0x540, 0}, 9.44 + {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 0x540, 0x540, 0}, 9.45 + {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 0x540, 0x540, 0}, 9.46 + {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 0x540, 0x540, 0}, 9.47 + {"", -1, 0, 0, 0} 9.48 +}; 9.49 + 9.50 void cpu_set_edx() 9.51 { 9.52 EDX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset; 9.53 @@ -216,17 +238,37 @@ 9.54 if (cpu_s->multi) 9.55 cpu_busspeed = cpu_s->rspeed / cpu_s->multi; 9.56 cpu_multi = cpu_s->multi; 9.57 + cpu_hasrdtsc = 0; 9.58 9.59 if (cpu_iscyrix) 9.60 - io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL); 9.61 + io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL); 9.62 else 9.63 - io_removehandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL); 9.64 + io_removehandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL); 9.65 9.66 pclog("hasfpu - %i\n",hasfpu); 9.67 pclog("is486 - %i %i\n",is486,cpu_s->cpu_type); 9.68 - 9.69 + 9.70 + x86_setopcodes(ops_386, ops_386_0f); 9.71 + 9.72 switch (cpu_s->cpu_type) 9.73 { 9.74 + case CPU_8088: 9.75 + case CPU_8086: 9.76 + break; 9.77 + 9.78 + case CPU_286: 9.79 + x86_setopcodes(ops_286, ops_286_0f); 9.80 + timing_rr = 2; /*register dest - register src*/ 9.81 + timing_rm = 7; /*register dest - memory src*/ 9.82 + timing_mr = 7; /*memory dest - register src*/ 9.83 + timing_mm = 7; /*memory dest - memory src*/ 9.84 + timing_rml = 9; /*register dest - memory src long*/ 9.85 + timing_mrl = 11; /*memory dest - register src long*/ 9.86 + timing_mml = 11; /*memory dest - memory src*/ 9.87 + timing_bt = 7-3; /*branch taken*/ 9.88 + timing_bnt = 3; /*branch not taken*/ 9.89 + break; 9.90 + 9.91 case CPU_386SX: 9.92 timing_rr = 2; /*register dest - register src*/ 9.93 timing_rm = 6; /*register dest - memory src*/ 9.94 @@ -326,6 +368,22 @@ 9.95 timing_bt = 5-1; /*branch taken*/ 9.96 timing_bnt = 1; /*branch not taken*/ 9.97 break; 9.98 + 9.99 + case CPU_WINCHIP: 9.100 + timing_rr = 1; /*register dest - register src*/ 9.101 + timing_rm = 2; /*register dest - memory src*/ 9.102 + timing_mr = 3; /*memory dest - register src*/ 9.103 + timing_mm = 3; 9.104 + timing_rml = 2; /*register dest - memory src long*/ 9.105 + timing_mrl = 3; /*memory dest - register src long*/ 9.106 + timing_mml = 3; 9.107 + timing_bt = 3-1; /*branch taken*/ 9.108 + timing_bnt = 1; /*branch not taken*/ 9.109 + cpu_hasrdtsc = 1; 9.110 + break; 9.111 + 9.112 + default: 9.113 + fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); 9.114 } 9.115 } 9.116 9.117 @@ -354,6 +412,7 @@ 9.118 case CPU_Am486SX: 9.119 if (!EAX) 9.120 { 9.121 + EAX = 1; 9.122 EBX = 0x68747541; 9.123 ECX = 0x444D4163; 9.124 EDX = 0x69746E65; 9.125 @@ -370,6 +429,7 @@ 9.126 case CPU_Am486DX: 9.127 if (!EAX) 9.128 { 9.129 + EAX = 1; 9.130 EBX = 0x68747541; 9.131 ECX = 0x444D4163; 9.132 EDX = 0x69746E65; 9.133 @@ -383,19 +443,37 @@ 9.134 else 9.135 EAX = 0; 9.136 break; 9.137 + 9.138 + case CPU_WINCHIP: 9.139 + if (!EAX) 9.140 + { 9.141 + EAX = 1; 9.142 + EBX = 0x746e6543; /*CentaurHauls*/ 9.143 + ECX = 0x736c7561; 9.144 + EDX = 0x48727561; 9.145 + } 9.146 + else if (EAX == 1) 9.147 + { 9.148 + EAX = CPUID; 9.149 + EBX = ECX = 0; 9.150 + EDX = 1; /*FPU*/ 9.151 + } 9.152 + else 9.153 + EAX = 0; 9.154 + break; 9.155 } 9.156 } 9.157 9.158 9.159 static int cyrix_addr; 9.160 9.161 -void cyrix_write(uint16_t addr, uint8_t val) 9.162 +void cyrix_write(uint16_t addr, uint8_t val, void *priv) 9.163 { 9.164 if (!(addr & 1)) cyrix_addr = val; 9.165 // else pclog("Write Cyrix %02X %02X\n",cyrix_addr,val); 9.166 } 9.167 9.168 -uint8_t cyrix_read(uint16_t addr) 9.169 +uint8_t cyrix_read(uint16_t addr, void *priv) 9.170 { 9.171 if (addr & 1) 9.172 {
10.1 --- a/src/cpu.h Sun Apr 21 14:54:35 2013 +0100 10.2 +++ b/src/cpu.h Mon May 27 17:46:42 2013 +0100 10.3 @@ -22,9 +22,13 @@ 10.4 #define CPU_Cx486DX 12 10.5 #define CPU_Cx5x86 13 10.6 10.7 +/*586 class CPUs*/ 10.8 +#define CPU_WINCHIP 14 10.9 + 10.10 #define MANU_INTEL 0 10.11 #define MANU_AMD 1 10.12 #define MANU_CYRIX 2 10.13 +#define MANU_IDT 3 10.14 10.15 extern int timing_rr; 10.16 extern int timing_mr, timing_mrl; 10.17 @@ -55,6 +59,7 @@ 10.18 extern CPU cpus_i486[]; 10.19 extern CPU cpus_Am486[]; 10.20 extern CPU cpus_Cx486[]; 10.21 +extern CPU cpus_WinChip[]; 10.22 10.23 extern CPU cpus_pc1512[]; 10.24 extern CPU cpus_ibmat[]; 10.25 @@ -65,7 +70,9 @@ 10.26 extern int cpu_busspeed; 10.27 extern int cpu_multi; 10.28 10.29 -void cyrix_write(uint16_t addr, uint8_t val); 10.30 -uint8_t cyrix_read(uint16_t addr); 10.31 +extern int cpu_hasrdtsc; 10.32 + 10.33 +void cyrix_write(uint16_t addr, uint8_t val, void *priv); 10.34 +uint8_t cyrix_read(uint16_t addr, void *priv); 10.35 10.36 extern int is8086;
11.1 --- a/src/dma.c Sun Apr 21 14:54:35 2013 +0100 11.2 +++ b/src/dma.c Mon May 27 17:46:42 2013 +0100 11.3 @@ -1,7 +1,9 @@ 11.4 #include "ibm.h" 11.5 + 11.6 +#include "dma.h" 11.7 +#include "fdc.h" 11.8 +#include "io.h" 11.9 #include "video.h" 11.10 -#include "io.h" 11.11 -#include "dma.h" 11.12 11.13 extern int ins; 11.14 int output; 11.15 @@ -38,10 +40,10 @@ 11.16 dma16.m=0; 11.17 } 11.18 11.19 -uint8_t dma_read(uint16_t addr) 11.20 +uint8_t dma_read(uint16_t addr, void *priv) 11.21 { 11.22 uint8_t temp; 11.23 -// printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc); 11.24 +// printf("Read DMA %04X %04X:%04X %i %02X\n",addr,CS,pc, pic_intpending, pic.pend); 11.25 switch (addr&0xF) 11.26 { 11.27 case 0: 11.28 @@ -69,7 +71,8 @@ 11.29 case 8: /*Status register*/ 11.30 temp=dma.stat; 11.31 dma.stat=0; 11.32 - return temp|1; 11.33 +// pclog("Read DMA status %02X\n", temp); 11.34 + return temp; 11.35 case 0xD: 11.36 return 0; 11.37 } 11.38 @@ -77,9 +80,9 @@ 11.39 return dmaregs[addr&0xF]; 11.40 } 11.41 11.42 -void dma_write(uint16_t addr, uint8_t val) 11.43 +void dma_write(uint16_t addr, uint8_t val, void *priv) 11.44 { 11.45 -// printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc); 11.46 + printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc); 11.47 dmaregs[addr&0xF]=val; 11.48 switch (addr&0xF) 11.49 { 11.50 @@ -122,7 +125,7 @@ 11.51 } 11.52 } 11.53 11.54 -uint8_t dma16_read(uint16_t addr) 11.55 +uint8_t dma16_read(uint16_t addr, void *priv) 11.56 { 11.57 uint8_t temp; 11.58 // printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc); 11.59 @@ -154,12 +157,12 @@ 11.60 case 8: /*Status register*/ 11.61 temp=dma16.stat; 11.62 dma16.stat=0; 11.63 - return temp|1; 11.64 + return temp; 11.65 } 11.66 return dma16regs[addr&0xF]; 11.67 } 11.68 11.69 -void dma16_write(uint16_t addr, uint8_t val) 11.70 +void dma16_write(uint16_t addr, uint8_t val, void *priv) 11.71 { 11.72 // printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc); 11.73 addr>>=1; 11.74 @@ -205,14 +208,14 @@ 11.75 } 11.76 11.77 uint8_t dmapages[16]; 11.78 -static int primed = 0; 11.79 -void dma_page_write(uint16_t addr, uint8_t val) 11.80 + 11.81 +void dma_page_write(uint16_t addr, uint8_t val, void *priv) 11.82 { 11.83 - if (!(addr&0xF)) 11.84 - { 11.85 -// printf("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc); 11.86 +/* if (!(addr&0xF)) 11.87 + {*/ 11.88 + pclog("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc); 11.89 // if (val==0x29 && pc==0xD25) output=1; 11.90 - } 11.91 +// } 11.92 dmapages[addr&0xF]=val; 11.93 switch (addr&0xF) 11.94 { 11.95 @@ -233,21 +236,21 @@ 11.96 // printf("Page write %04X %02X\n",addr,val); 11.97 } 11.98 11.99 -uint8_t dma_page_read(uint16_t addr) 11.100 +uint8_t dma_page_read(uint16_t addr, void *priv) 11.101 { 11.102 return dmapages[addr&0xF]; 11.103 } 11.104 11.105 void dma_init() 11.106 { 11.107 - io_sethandler(0x0000, 0x0010, dma_read, NULL, NULL, dma_write, NULL, NULL); 11.108 - io_sethandler(0x0080, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL); 11.109 + io_sethandler(0x0000, 0x0010, dma_read, NULL, NULL, dma_write, NULL, NULL, NULL); 11.110 + io_sethandler(0x0080, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); 11.111 } 11.112 11.113 void dma16_init() 11.114 { 11.115 - io_sethandler(0x00C0, 0x0020, dma16_read, NULL, NULL, dma16_write, NULL, NULL); 11.116 - io_sethandler(0x0088, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL); 11.117 + io_sethandler(0x00C0, 0x0020, dma16_read, NULL, NULL, dma16_write, NULL, NULL, NULL); 11.118 + io_sethandler(0x0088, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); 11.119 } 11.120 11.121 11.122 @@ -256,11 +259,11 @@ 11.123 switch (addr&0xFFFF8000) 11.124 { 11.125 case 0xA0000: case 0xA8000: 11.126 - return video_read_a000(addr); 11.127 + return video_read_a000(addr, NULL); 11.128 case 0xB0000: 11.129 - return video_read_b000(addr); 11.130 + return video_read_b000(addr, NULL); 11.131 case 0xB8000: 11.132 - return video_read_b800(addr); 11.133 + return video_read_b800(addr, NULL); 11.134 } 11.135 if (isram[addr>>16]) return ram[addr]; 11.136 return 0xff; 11.137 @@ -271,19 +274,20 @@ 11.138 switch (addr&0xFFFF8000) 11.139 { 11.140 case 0xA0000: case 0xA8000: 11.141 - video_write_a000(addr,val); 11.142 + video_write_a000(addr,val, NULL); 11.143 return; 11.144 case 0xB0000: 11.145 - video_write_b000(addr,val); 11.146 + video_write_b000(addr,val, NULL); 11.147 return; 11.148 case 0xB8000: 11.149 - video_write_b800(addr,val); 11.150 + video_write_b800(addr,val, NULL); 11.151 return; 11.152 case 0xC0000: case 0xC8000: case 0xD0000: case 0xD8000: 11.153 case 0xE0000: case 0xE8000: case 0xF0000: case 0xF8000: 11.154 return; 11.155 } 11.156 - if (isram[addr>>16]) ram[addr]=val; 11.157 + if (isram[addr >> 16]) 11.158 + ram[addr] = val; 11.159 } 11.160 /*void writedma2(uint8_t val) 11.161 { 11.162 @@ -301,10 +305,144 @@ 11.163 } 11.164 }*/ 11.165 11.166 +int dma_channel_read(int channel) 11.167 +{ 11.168 + uint16_t temp; 11.169 + 11.170 + if (channel < 4) 11.171 + { 11.172 +// pclog("Read DMA channel %i\n", channel); 11.173 + if (dma.m & (1 << channel)) 11.174 + return DMA_NODATA; 11.175 + if ((dma.mode[channel] & 0xC) != 8) 11.176 + return DMA_NODATA; 11.177 + temp = _dma_read(dma.ac[channel] + (dma.page[channel] << 16)); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]; 11.178 +// pclog(" - %02X %05X\n", temp, dma.ac[channel] + (dma.page[channel] << 16)); 11.179 + if (dma.mode[channel] & 0x20) dma.ac[channel]--; 11.180 + else dma.ac[channel]++; 11.181 + dma.cc[channel]--; 11.182 + if (!dma.cc[channel] && (dma.mode[channel] & 0x10)) 11.183 + { 11.184 + dma.cc[channel] = dma.cb[channel] + 1; 11.185 + dma.ac[channel] = dma.ab[channel]; 11.186 + dma.stat |= (1 << channel); 11.187 + } 11.188 + else if (dma.cc[channel]<=-1) 11.189 + { 11.190 + dma.m |= (1 << channel); 11.191 + dma.stat |= (1 << channel); 11.192 + } 11.193 + return temp; 11.194 + } 11.195 + else 11.196 + { 11.197 + channel &= 3; 11.198 + if (dma16.m & (1 << channel)) 11.199 + return DMA_NODATA; 11.200 + if ((dma16.mode[channel] & 0xC) != 8) 11.201 + return DMA_NODATA; 11.202 + temp = _dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16)) | 11.203 + (_dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1) << 8); 11.204 + if (dma16.mode[channel] & 0x20) dma16.ac[channel]--; 11.205 + else dma16.ac[channel]++; 11.206 + dma16.cc[channel]--; 11.207 + if (!dma16.cc[channel] && (dma16.mode[channel] & 0x10)) 11.208 + { 11.209 + dma16.cc[channel] = dma16.cb[channel] + 1; 11.210 + dma16.ac[channel] = dma16.ab[channel]; 11.211 + dma16.stat |= (1 << channel); 11.212 + } 11.213 + else if (dma16.cc[channel]<=-1) 11.214 + { 11.215 + dma16.m |= (1 << channel); 11.216 + dma16.stat |= (1 << channel); 11.217 + } 11.218 + return temp; 11.219 + } 11.220 +} 11.221 + 11.222 +int dma_channel_write(int channel, uint16_t val) 11.223 +{ 11.224 + if (channel < 4) 11.225 + { 11.226 + if (dma.m & (1 << channel)) 11.227 + return DMA_NODATA; 11.228 + if ((dma.mode[channel] & 0xC) != 4) 11.229 + return DMA_NODATA; 11.230 + _dma_write(dma.ac[channel] + (dma.page[channel] << 16), val); 11.231 + if (dma.mode[channel]&0x20) dma.ac[channel]--; 11.232 + else dma.ac[channel]++; 11.233 + dma.cc[channel]--; 11.234 + if (!dma.cc[channel] && (dma.mode[channel] & 0x10)) 11.235 + { 11.236 + dma.cc[channel] = dma.cb[channel] + 1; 11.237 + dma.ac[channel] = dma.ab[channel]; 11.238 + dma.stat |= (1 << channel); 11.239 + } 11.240 + else if (dma.cc[channel]<=-1) 11.241 + { 11.242 + dma.m |= (1 << channel); 11.243 + dma.stat |= (1 << channel); 11.244 + } 11.245 + } 11.246 + else 11.247 + { 11.248 + channel &= 3; 11.249 + if (dma16.m & (1 << channel)) 11.250 + return DMA_NODATA; 11.251 + if ((dma16.mode[channel] & 0xC) != 4) 11.252 + return DMA_NODATA; 11.253 + _dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16), val); 11.254 + _dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1, val >> 8); 11.255 + if (dma16.mode[channel]&0x20) dma16.ac[channel]--; 11.256 + else dma16.ac[channel]++; 11.257 + dma16.cc[channel]--; 11.258 + if (!dma16.cc[channel] && (dma16.mode[channel] & 0x10)) 11.259 + { 11.260 + dma16.cc[channel] = dma16.cb[channel] + 1; 11.261 + dma16.ac[channel] = dma16.ab[channel]; 11.262 + dma16.stat |= (1 << channel); 11.263 + } 11.264 + else if (dma16.cc[channel] <= -1) 11.265 + { 11.266 + dma16.m |= (1 << channel); 11.267 + dma16.stat |= (1 << channel); 11.268 + } 11.269 + } 11.270 + return 0; 11.271 +} 11.272 + 11.273 +extern int sbbufferpos; 11.274 +int readdma1() 11.275 +{ 11.276 + uint8_t temp; 11.277 + pclog("readdma1 : Read DMA1 %02X %02X %i\n",dma.m,dma.mode[1], dma.cc[1]); 11.278 + if (dma.m & (1 << 1)) 11.279 + return DMA_NODATA; 11.280 + if ((dma.mode[1]&0xC)!=8) 11.281 + return DMA_NODATA; 11.282 + temp=_dma_read((dma.ac[1]+(dma.page[1]<<16))&rammask); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]; 11.283 + pclog("readdma1 : DMA1 %02X %05X\n",temp,(dma.ac[1]+(dma.page[1]<<16))&rammask); 11.284 + if (dma.mode[1]&0x20) dma.ac[1]--; 11.285 + else dma.ac[1]++; 11.286 + dma.cc[1]--; 11.287 + if (!dma.cc[1] && (dma.mode[1]&0x10)) 11.288 + { 11.289 + dma.cc[1]=dma.cb[1]+1; 11.290 + dma.ac[1]=dma.ab[1]; 11.291 + dma.stat |= (1 << 1); 11.292 + } 11.293 + else if (dma.cc[1]<=-1) 11.294 + { 11.295 + dma.m |= (1 << 1); 11.296 + dma.stat |= (1 << 1); 11.297 + } 11.298 + return temp; 11.299 +} 11.300 uint8_t readdma2() 11.301 { 11.302 uint8_t temp; 11.303 -// pclog("Read DMA2 %02X %02X\n",dma.m,dma.mode[2]); 11.304 +// pclog("Read DMA2 %02X %02X %i\n",dma.m,dma.mode[2], dma.cc[2]); 11.305 if (dma.m&4) 11.306 { 11.307 fdc_abort(); 11.308 @@ -324,12 +462,68 @@ 11.309 { 11.310 dma.cc[2]=dma.cb[2]+1; 11.311 dma.ac[2]=dma.ab[2]; 11.312 + dma.stat |= (1 << 2); 11.313 } 11.314 else if (dma.cc[2]<=-1) 11.315 - dma.m|=4; 11.316 + { 11.317 + dma.m|=4; 11.318 + dma.stat |= (1 << 2); 11.319 + } 11.320 + return temp; 11.321 +} 11.322 +int readdma3() 11.323 +{ 11.324 + uint8_t temp; 11.325 +// pclog("Read DMA1 %02X %02X %i\n",dma.m,dma.mode[1], dma.cc[1]); 11.326 + if (dma.m & (1 << 3)) 11.327 + return DMA_NODATA; 11.328 + if ((dma.mode[3]&0xC)!=8) 11.329 + return DMA_NODATA; 11.330 + temp=_dma_read((dma.ac[3]+(dma.page[3]<<16))&rammask); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]; 11.331 + //pclog("DMA3 %02X %05X\n",temp,(dma.ac[3]+(dma.page[3]<<16))&rammask); 11.332 + if (dma.mode[3]&0x20) dma.ac[3]--; 11.333 + else dma.ac[3]++; 11.334 + dma.cc[3]--; 11.335 + if (!dma.cc[3] && (dma.mode[3]&0x10)) 11.336 + { 11.337 + dma.cc[3]=dma.cb[3]+1; 11.338 + dma.ac[3]=dma.ab[3]; 11.339 + dma.stat |= (1 << 3); 11.340 + } 11.341 + else if (dma.cc[3]<=-1) 11.342 + { 11.343 + dma.m |= (1 << 3); 11.344 + dma.stat |= (1 << 3); 11.345 + } 11.346 return temp; 11.347 } 11.348 11.349 +void writedma1(uint8_t temp) 11.350 +{ 11.351 +// pclog("Write DMA1 %02X %02X %04X\n",dma.m,dma.mode[1],dma.cc[1]); 11.352 + if (dma.m & (1 << 1)) 11.353 + return; 11.354 + if ((dma.mode[1] & 0xC) != 4) 11.355 + return; 11.356 +// pclog("Write %05X %05X %02X\n",(dma.ac[2]+(dma.page[2]<<16)),rammask,temp); 11.357 +// ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]=temp; 11.358 + _dma_write((dma.ac[1]+(dma.page[1]<<16))&rammask,temp); 11.359 + if (dma.mode[1]&0x20) dma.ac[1]--; 11.360 + else dma.ac[1]++; 11.361 + dma.cc[1]--; 11.362 + if (!dma.cc[1] && (dma.mode[1]&0x10)) 11.363 + { 11.364 + dma.cc[1]=dma.cb[1]+1; 11.365 + dma.ac[1]=dma.ab[1]; 11.366 + dma.stat |= (1 << 1); 11.367 + } 11.368 + else if (dma.cc[1]<=-1) 11.369 + { 11.370 +// pclog("Reached TC\n"); 11.371 + dma.m |= (1 << 1); 11.372 + dma.stat |= (1 << 1); 11.373 + } 11.374 +} 11.375 void writedma2(uint8_t temp) 11.376 { 11.377 // pclog("Write DMA2 %02X %02X %04X\n",dma.m,dma.mode[2],dma.cc[2]); 11.378 @@ -353,35 +547,41 @@ 11.379 { 11.380 dma.cc[2]=dma.cb[2]+1; 11.381 dma.ac[2]=dma.ab[2]; 11.382 + dma.stat |= (1 << 2); 11.383 } 11.384 else if (dma.cc[2]<=-1) 11.385 { 11.386 // pclog("Reached TC\n"); 11.387 fdc_abort(); 11.388 dma.m|=4; 11.389 + dma.stat |= (1 << 2); 11.390 } 11.391 } 11.392 - 11.393 -uint8_t readdma1() 11.394 +void writedma3(uint8_t temp) 11.395 { 11.396 - uint8_t temp=0; 11.397 - /*if ((dma.ac[1]+(dma.page[1]<<16))<0x800000) */temp=ram[(dma.ac[1]+(dma.page[1]<<16))&rammask]; 11.398 -// printf("Read DMA1 from %05X %02X %04X %02X %i\n",dma.ac[1]+(dma.page[1]<<16),dma.mode[1],dma.cc[1],temp,dmaon[1]); 11.399 - if (!dmaon[1]) 11.400 +// pclog("Write DMA3 %02X %02X %04X\n",dma.m,dma.mode[3],dma.cc[3]); 11.401 + if (dma.m & (1 << 3)) 11.402 + return; 11.403 + if ((dma.mode[3] & 0xC) != 4) 11.404 + return; 11.405 +// pclog("Write %05X %05X %02X\n",(dma.ac[2]+(dma.page[2]<<16)),rammask,temp); 11.406 +// ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]=temp; 11.407 + _dma_write((dma.ac[3]+(dma.page[3]<<16))&rammask,temp); 11.408 + if (dma.mode[3]&0x20) dma.ac[3]--; 11.409 + else dma.ac[3]++; 11.410 + dma.cc[3]--; 11.411 + if (!dma.cc[3] && (dma.mode[3]&0x10)) 11.412 { 11.413 -// printf("DMA off!\n"); 11.414 - return temp; 11.415 + dma.cc[3]=dma.cb[3]+1; 11.416 + dma.ac[3]=dma.ab[3]; 11.417 + dma.stat |= (1 << 3); 11.418 } 11.419 - dma.ac[1]++; 11.420 - dma.cc[1]--; 11.421 - if (dma.cc[1]<=-1 && (dma.mode[1]&0x10)) 11.422 + else if (dma.cc[3]<=-1) 11.423 { 11.424 - dma.cc[1]=dma.cb[1]; 11.425 - dma.ac[1]=dma.ab[1]; 11.426 +// pclog("Reached TC\n"); 11.427 + dma.m |= (1 << 3); 11.428 + dma.stat |= (1 << 3); 11.429 } 11.430 - else if (dma.cc[1]<=-1) 11.431 - dmaon[1]=0; 11.432 - return temp; 11.433 } 11.434 11.435 uint16_t readdma5() 11.436 @@ -402,26 +602,16 @@ 11.437 { 11.438 dma16.cc[1]=dma16.cb[1]; 11.439 dma16.ac[1]=dma16.ab[1]; 11.440 + dma16.stat |= (1 << 1); 11.441 } 11.442 else if (dma16.cc[1]<=-1) 11.443 - dma16on[1]=0; 11.444 + { 11.445 + dma16on[1]=0; 11.446 + dma16.stat |= (1 << 1); 11.447 + } 11.448 return temp; 11.449 } 11.450 11.451 -void writedma1(uint8_t temp) 11.452 -{ 11.453 - if (!dmaon[1]) return; 11.454 - ram[(dma.ac[1]+(dma.page[1]<<16))&rammask]=temp; 11.455 - dma.ac[1]++; 11.456 - dma.cc[1]--; 11.457 - if (!dma.cc[1] && (dma.mode[1]&0x10)) 11.458 - { 11.459 - dma.cc[1]=dma.cb[1]+1; 11.460 - dma.ac[1]=dma.ab[1]; 11.461 - } 11.462 - else if (dma.cc[1]<=-1) 11.463 - dmaon[1]=0; 11.464 -} 11.465 void writedma5(uint16_t temp) 11.466 { 11.467 if (!dma16on[1]) return; 11.468 @@ -434,31 +624,15 @@ 11.469 { 11.470 dma16.cc[1]=dma16.cb[1]; 11.471 dma16.ac[1]=dma16.ab[1]; 11.472 + dma16.stat |= (1 << 1); 11.473 } 11.474 else if (dma16.cc[1]<=-1) 11.475 - dma16on[1]=0; 11.476 + { 11.477 + dma16on[1]=0; 11.478 + dma16.stat |= (1 << 1); 11.479 + } 11.480 } 11.481 11.482 -int readdma3() 11.483 -{ 11.484 - uint8_t temp=ram[((dma.page[3]<<16)+dma.ac[3])&rammask]; 11.485 - if (dma.m&8) 11.486 - { 11.487 - return -1; 11.488 - } 11.489 -// printf("Read DMA 3 - %02X %05X %i\n",temp,(dma.page[3]<<16)+dma.ac[3],dma.cc[3]); 11.490 - if (!(dma.m&8)) 11.491 - { 11.492 - dma.ac[3]++; 11.493 - dma.cc[3]--; 11.494 - if (dma.cc[3]==-1) 11.495 - { 11.496 - dma.m|=8; 11.497 - dma.stat|=8; 11.498 - } 11.499 - } 11.500 - return temp; 11.501 -} 11.502 void readdma0() 11.503 { 11.504 if (AT) ppi.pb^=0x10; 11.505 @@ -474,9 +648,9 @@ 11.506 dma.cc[0]--; 11.507 if (dma.cc[0]==-1) 11.508 { 11.509 - dma.stat|=1; 11.510 dma.ac[0]=dma.ab[0]; 11.511 dma.cc[0]=dma.cb[0]; 11.512 + dma.stat |= 1; 11.513 } 11.514 // } 11.515 // ppi.pb^=0x10;
12.1 --- a/src/dma.h Sun Apr 21 14:54:35 2013 +0100 12.2 +++ b/src/dma.h Mon May 27 17:46:42 2013 +0100 12.3 @@ -1,3 +1,15 @@ 12.4 void dma_init(); 12.5 void dma16_init(); 12.6 void dma_reset(); 12.7 + 12.8 +#define DMA_NODATA -1 12.9 + 12.10 +void readdma0(); 12.11 +int readdma1(); 12.12 +uint8_t readdma2(); 12.13 +int readdma3(); 12.14 + 12.15 +void writedma2(uint8_t temp); 12.16 + 12.17 +int dma_channel_read(int channel); 12.18 +int dma_channel_write(int channel, uint16_t val);
13.1 --- a/src/ega.c Sun Apr 21 14:54:35 2013 +0100 13.2 +++ b/src/ega.c Mon May 27 17:46:42 2013 +0100 13.3 @@ -16,7 +16,6 @@ 13.4 13.5 uint8_t oldvram=0; 13.6 int frames; 13.7 -int incga=1; 13.8 int hsync; 13.9 uint8_t cgastat; 13.10 13.11 @@ -36,7 +35,7 @@ 13.12 13.13 int egares; 13.14 13.15 -uint8_t seqregs[32]; 13.16 +uint8_t seqregs[64]; 13.17 int seqaddr; 13.18 13.19 uint8_t oak_regs[32]; 13.20 @@ -54,7 +53,8 @@ 13.21 13.22 int fullchange; 13.23 13.24 -float dispontime,dispofftime,disptime; 13.25 +int dispontime,dispofftime; 13.26 +double disptime; 13.27 13.28 int ega_vtotal,ega_dispend,ega_vsyncstart,ega_split,ega_hdisp,ega_rowoffset; 13.29 int vidclock; 13.30 @@ -135,8 +135,6 @@ 13.31 } 13.32 } 13.33 crtc[0xC]=crtc[0xD]=0; 13.34 - if (romset==ROM_PC1640 || romset==ROM_PC1512) incga=1; 13.35 - else incga=0; 13.36 for (c=0;c<4;c++) 13.37 { 13.38 for (d=0;d<4;d++) 13.39 @@ -277,6 +275,7 @@ 13.40 if (TRIDENT || ET4000W32) return bpp; 13.41 return 8; 13.42 } 13.43 + return 0; 13.44 } 13.45 13.46 int ega_getx()
14.1 --- a/src/fdc.c Sun Apr 21 14:54:35 2013 +0100 14.2 +++ b/src/fdc.c Mon May 27 17:46:42 2013 +0100 14.3 @@ -2,6 +2,11 @@ 14.4 #include <string.h> 14.5 #include "ibm.h" 14.6 14.7 +#include "dma.h" 14.8 +#include "io.h" 14.9 +#include "pic.h" 14.10 +#include "timer.h" 14.11 + 14.12 void fdc_poll(); 14.13 int timetolive; 14.14 int TRACKS[2] = {80, 80}; 14.15 @@ -105,9 +110,8 @@ 14.16 } 14.17 int ins; 14.18 14.19 -void fdc_write(uint16_t addr, uint8_t val) 14.20 +void fdc_write(uint16_t addr, uint8_t val, void *priv) 14.21 { 14.22 - int c; 14.23 // printf("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate); 14.24 switch (addr&7) 14.25 { 14.26 @@ -122,7 +126,9 @@ 14.27 } 14.28 if ((val&4) && !(fdc.dor&4)) 14.29 { 14.30 - disctime=128; 14.31 + timer_process(); 14.32 + disctime = 128 * (1 << TIMER_SHIFT); 14.33 + timer_update_outstanding(); 14.34 discint=-1; 14.35 fdc_reset(); 14.36 } 14.37 @@ -132,7 +138,9 @@ 14.38 case 4: 14.39 if (val & 0x80) 14.40 { 14.41 - disctime=128; 14.42 + timer_process(); 14.43 + disctime = 128 * (1 << TIMER_SHIFT); 14.44 + timer_update_outstanding(); 14.45 discint=-1; 14.46 fdc_reset(); 14.47 } 14.48 @@ -247,7 +255,9 @@ 14.49 // exit(-1); 14.50 fdc.stat=0x10; 14.51 discint=0xfc; 14.52 - disctime=200; 14.53 + timer_process(); 14.54 + disctime = 200 * (1 << TIMER_SHIFT); 14.55 + timer_update_outstanding(); 14.56 break; 14.57 } 14.58 } 14.59 @@ -259,7 +269,8 @@ 14.60 // pclog("Got all params\n"); 14.61 fdc.stat=0x30; 14.62 discint=fdc.command&0x1F; 14.63 - disctime=1024; 14.64 + timer_process(); 14.65 + disctime = 1024 * (1 << TIMER_SHIFT); 14.66 fdc.drive=fdc.params[0]&1; 14.67 if (discint==2 || discint==5 || discint==6) 14.68 { 14.69 @@ -285,13 +296,13 @@ 14.70 { 14.71 // pclog("Wrong rate %i %i\n",fdc.rate,discrate[fdc.drive]); 14.72 discint=0xFF; 14.73 - disctime=1024; 14.74 + disctime = 1024 * (1 << TIMER_SHIFT); 14.75 } 14.76 if (driveempty[fdc.drive]) 14.77 { 14.78 // pclog("Drive empty\n"); 14.79 discint=0xFE; 14.80 - disctime=1024; 14.81 + disctime = 1024 * (1 << TIMER_SHIFT); 14.82 } 14.83 } 14.84 if (discint == 7 || discint == 0xf) 14.85 @@ -303,6 +314,7 @@ 14.86 { 14.87 fdc.head = (fdc.params[0] & 4) ? 1 : 0; 14.88 } 14.89 + timer_update_outstanding(); 14.90 // if (discint==5) fdc.pos=512; 14.91 } 14.92 } 14.93 @@ -320,7 +332,7 @@ 14.94 } 14.95 14.96 int paramstogo=0; 14.97 -uint8_t fdc_read(uint16_t addr) 14.98 +uint8_t fdc_read(uint16_t addr, void *priv) 14.99 { 14.100 uint8_t temp; 14.101 // /*if (addr!=0x3f4) */printf("Read FDC %04X %04X:%04X %04X %i %02X %i ",addr,cs>>4,pc,BX,fdc.pos,fdc.st0,ins); 14.102 @@ -360,7 +372,12 @@ 14.103 lastbyte=0; 14.104 temp=fdc.dat; 14.105 } 14.106 - if (discint==0xA) disctime=1024; 14.107 + if (discint==0xA) 14.108 + { 14.109 + timer_process(); 14.110 + disctime = 1024 * (1 << TIMER_SHIFT); 14.111 + timer_update_outstanding(); 14.112 + } 14.113 fdc.stat &= 0xf0; 14.114 break; 14.115 case 7: /*Disk change*/ 14.116 @@ -395,6 +412,7 @@ 14.117 void fdc_poll() 14.118 { 14.119 int temp; 14.120 + disctime = 0; 14.121 // pclog("fdc_poll %08X %i %02X\n", discint, fdc.drive, fdc.st0); 14.122 switch (discint) 14.123 { 14.124 @@ -420,7 +438,9 @@ 14.125 fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos]; 14.126 // pclog("Read %i %i %i %i %02X\n",fdc.head,fdc.track,fdc.sector,fdc.pos,fdc.dat); 14.127 writedma2(fdc.dat); 14.128 - disctime=60; 14.129 + timer_process(); 14.130 + disctime = 60 * (1 << TIMER_SHIFT); 14.131 + timer_update_outstanding(); 14.132 } 14.133 else 14.134 { 14.135 @@ -437,17 +457,6 @@ 14.136 fdc.res[9]=fdc.params[4]; 14.137 paramstogo=7; 14.138 return; 14.139 - disctime=1024; 14.140 - picint(0x40); 14.141 - fdc.stat=0xD0; 14.142 - switch (fdc.pos-512) 14.143 - { 14.144 - case 0: case 1: case 2: fdc.dat=0; break; 14.145 - case 3: fdc.dat=fdc.track[fdc.drive]; break; 14.146 - case 4: fdc.dat=fdc.head; break; 14.147 - case 5: fdc.dat=fdc.sector; break; 14.148 - case 6: fdc.dat=fdc.params[4]; discint=-2; lastbyte=1; break; 14.149 - } 14.150 } 14.151 fdc.pos++; 14.152 if (fdc.pos==512 && fdc.params[5]!=1) 14.153 @@ -491,14 +500,18 @@ 14.154 { 14.155 fdc_abort_f=0; 14.156 discint=0xFD; 14.157 - disctime=50; 14.158 + timer_process(); 14.159 + disctime = 50 * (1 << TIMER_SHIFT); 14.160 + timer_update_outstanding(); 14.161 return; 14.162 } 14.163 else 14.164 { 14.165 fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos]=temp; 14.166 // printf("Write data %i %i %02X %i:%i:%i:%i\n",fdc.sector-1,fdc.pos,fdc.dat,fdc.head,fdc.track[fdc.drive],fdc.sector-1,fdc.pos); 14.167 - disctime=60; 14.168 + timer_process(); 14.169 + disctime = 60 * (1 << TIMER_SHIFT); 14.170 + timer_update_outstanding(); 14.171 } 14.172 } 14.173 else 14.174 @@ -517,19 +530,6 @@ 14.175 fdc.res[10]=fdc.params[4]; 14.176 paramstogo=7; 14.177 return; 14.178 - disctime=1024; 14.179 - picint(0x40); 14.180 - fdc.stat=0xD0; 14.181 - switch (fdc.pos-512) 14.182 - { 14.183 - case 0: fdc.dat=0x40; break; 14.184 - case 1: fdc.dat=2; break; 14.185 - case 2: fdc.dat=0; break; 14.186 - case 3: fdc.dat=fdc.track[fdc.drive]; break; 14.187 - case 4: fdc.dat=fdc.head; break; 14.188 - case 5: fdc.dat=fdc.sector; break; 14.189 - case 6: fdc.dat=fdc.params[4]; discint=-2; break; 14.190 - } 14.191 } 14.192 fdc.pos++; 14.193 if (fdc.pos==512 && fdc.sector!=fdc.params[5]) 14.194 @@ -548,7 +548,9 @@ 14.195 fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos]; 14.196 // printf("Read disc %i %i %i %i %02X\n",fdc.head,fdc.track,fdc.sector,fdc.pos,fdc.dat); 14.197 writedma2(fdc.dat); 14.198 - disctime=60; 14.199 + timer_process(); 14.200 + disctime = 60 * (1 << TIMER_SHIFT); 14.201 + timer_update_outstanding(); 14.202 } 14.203 else 14.204 { 14.205 @@ -579,12 +581,12 @@ 14.206 fdc.pos++; 14.207 if (fdc.pos==512)// && fdc.sector!=fdc.params[5]) 14.208 { 14.209 -// printf("Sector complete! %02X\n",fdc.params[5]); 14.210 +// pclog("Sector complete! %02X\n",fdc.params[5]); 14.211 fdc.pos=0; 14.212 fdc.sector++; 14.213 if (fdc.sector > fdc.params[5]) 14.214 { 14.215 -// printf("Overrunnit!\n"); 14.216 +// pclog("Overrunnit! %02X\n", fdc.command & 0x80); 14.217 // dumpregs(); 14.218 // exit(-1); 14.219 fdc.sector=1; 14.220 @@ -617,7 +619,9 @@ 14.221 if (!driveempty[fdc.dor & 1]) discchanged[fdc.dor & 1] = 0; 14.222 fdc.st0=0x20|fdc.drive|(fdc.head?4:0); 14.223 discint=-3; 14.224 - disctime=2048; 14.225 + timer_process(); 14.226 + disctime = 2048 * (1 << TIMER_SHIFT); 14.227 + timer_update_outstanding(); 14.228 // printf("Recalibrate complete!\n"); 14.229 fdc.stat = 0x80 | (1 << fdc.drive); 14.230 return; 14.231 @@ -663,7 +667,9 @@ 14.232 // printf("Seeked to track %i %i\n",fdc.track[fdc.drive], fdc.drive); 14.233 fdc.st0=0x20|fdc.drive|(fdc.head?4:0); 14.234 discint=-3; 14.235 - disctime=2048; 14.236 + timer_process(); 14.237 + disctime = 2048 * (1 << TIMER_SHIFT); 14.238 + timer_update_outstanding(); 14.239 fdc.stat = 0x80 | (1 << fdc.drive); 14.240 // pclog("Stat %02X ST0 %02X\n", fdc.stat, fdc.st0); 14.241 return; 14.242 @@ -792,15 +798,19 @@ 14.243 // exit(-1); 14.244 } 14.245 14.246 - 14.247 void fdc_init() 14.248 { 14.249 - io_sethandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL); 14.250 - io_sethandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL); 14.251 + timer_add(fdc_poll, &disctime, &disctime, NULL); 14.252 +} 14.253 + 14.254 +void fdc_add() 14.255 +{ 14.256 + io_sethandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); 14.257 + io_sethandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); 14.258 } 14.259 14.260 void fdc_remove() 14.261 { 14.262 - io_removehandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL); 14.263 - io_removehandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL); 14.264 + io_removehandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); 14.265 + io_removehandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); 14.266 }
15.1 --- a/src/fdc.h Sun Apr 21 14:54:35 2013 +0100 15.2 +++ b/src/fdc.h Mon May 27 17:46:42 2013 +0100 15.3 @@ -1,4 +1,6 @@ 15.4 void fdc_init(); 15.5 +void fdc_add(); 15.6 void fdc_remove(); 15.7 void fdc_reset(); 15.8 void fdc_poll(); 15.9 +void fdc_abort();
16.1 --- a/src/headland.c Sun Apr 21 14:54:35 2013 +0100 16.2 +++ b/src/headland.c Mon May 27 17:46:42 2013 +0100 16.3 @@ -8,7 +8,7 @@ 16.4 static int headland_index; 16.5 static uint8_t headland_regs[256]; 16.6 16.7 -void headland_write(uint16_t addr, uint8_t val) 16.8 +void headland_write(uint16_t addr, uint8_t val, void *priv) 16.9 { 16.10 if (addr & 1) 16.11 { 16.12 @@ -20,15 +20,15 @@ 16.13 shadowbios = val & 0x10; 16.14 shadowbios_write = !(val & 0x10); 16.15 if (shadowbios) 16.16 - mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL ); 16.17 + mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL , NULL); 16.18 else 16.19 - mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml); 16.20 + mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); 16.21 } 16.22 } 16.23 else headland_index = val; 16.24 } 16.25 16.26 -uint8_t headland_read(uint16_t addr) 16.27 +uint8_t headland_read(uint16_t addr, void *priv) 16.28 { 16.29 if (addr & 1) 16.30 { 16.31 @@ -41,5 +41,5 @@ 16.32 16.33 void headland_init() 16.34 { 16.35 - io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL); 16.36 + io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); 16.37 }
17.1 --- a/src/ibm.h Sun Apr 21 14:54:35 2013 +0100 17.2 +++ b/src/ibm.h Mon May 27 17:46:42 2013 +0100 17.3 @@ -1,5 +1,6 @@ 17.4 #include <stdio.h> 17.5 #include <stdint.h> 17.6 +#include <string.h> 17.7 #define printf pclog 17.8 17.9 /*Memory*/ 17.10 @@ -291,9 +292,8 @@ 17.11 #define PCI (romset == ROM_PCI486) 17.12 17.13 #define AMIBIOS (romset==ROM_AMI386 || romset==ROM_AMI486 || romset == ROM_WIN486) 17.14 -int FASTDISC; 17.15 -int ADLIB; 17.16 -int GAMEBLASTER; 17.17 + 17.18 +int GAMEBLASTER, GUS; 17.19 17.20 enum 17.21 { 17.22 @@ -320,7 +320,8 @@ 17.23 ROM_AMI386, 17.24 ROM_AMI486, 17.25 ROM_WIN486, 17.26 - ROM_PCI486 17.27 + ROM_PCI486, 17.28 + ROM_430VX 17.29 }; 17.30 17.31 //#define ROM_IBMPCJR 5 /*Not working! ROMs are corrupt*/ 17.32 @@ -337,10 +338,18 @@ 17.33 //#define GFX_OTI067 3 /*Using BIOS from Acer 386SX/25N - edit - only works with Acer BIOS! Stupid integrated systems*/ 17.34 #define GFX_TVGA 4 /*Using Trident 8900D BIOS*/ 17.35 #define GFX_ET4000 5 /*Tseng ET4000*/ 17.36 -#define GFX_ET4000W32 6 /*Tseng ET4000/W32p (Diamond Stealth 32)*/ 17.37 -#define GFX_BAHAMAS64 7 /*S3 Vision864 (Paradise Bahamas 64)*/ 17.38 -#define GFX_N9_9FX 8 /*S3 764/Trio64 (Number Nine 9FX)*/ 17.39 -#define GFX_STEALTH64 9 /*S3 Vision964 (Diamond Stealth 64 VRAM PCI)*/ 17.40 +#define GFX_ET4000W32 6 /*Tseng ET4000/W32p (Diamond Stealth 32)*/ 17.41 +#define GFX_BAHAMAS64 7 /*S3 Vision864 (Paradise Bahamas 64)*/ 17.42 +#define GFX_N9_9FX 8 /*S3 764/Trio64 (Number Nine 9FX)*/ 17.43 +#define GFX_STEALTH64 9 /*S3 Vision964 (Diamond Stealth 64 VRAM PCI)*/ 17.44 +#define GFX_VIRGE 10 /*S3 Virge*/ 17.45 +#define GFX_TGUI9440 11 /*Trident TGUI9440*/ 17.46 +#define GFX_VGA 12 /*IBM VGA*/ 17.47 +#define GFX_VGAEDGE16 13 /*ATI VGA Edge-16 (18800-1)*/ 17.48 +#define GFX_VGACHARGER 14 /*ATI VGA Charger (28800-5)*/ 17.49 +#define GFX_OTI067 15 /*Oak OTI-067*/ 17.50 +#define GFX_MACH64GX 16 /*ATI Graphics Pro Turbo (Mach64)*/ 17.51 +#define GFX_CL_GD5429 17 /*Cirrus Logic CL-GD5429*/ 17.52 17.53 int gfxcard; 17.54 17.55 @@ -354,7 +363,6 @@ 17.56 uint8_t hercctrl; 17.57 int slowega,egacycles,egacycles2; 17.58 extern uint8_t gdcreg[16]; 17.59 -extern int incga; 17.60 extern int egareads,egawrites; 17.61 extern int cga_comp; 17.62 extern int vid_resize; 17.63 @@ -383,13 +391,10 @@ 17.64 /*Sound*/ 17.65 uint8_t spkstat; 17.66 17.67 -float spktime,soundtime,gustime,gustime2,vidtime,rtctime; 17.68 +float spktime; 17.69 +int rtctime; 17.70 +int soundtime,gustime,gustime2,vidtime; 17.71 int ppispeakon; 17.72 -//#define SPKCONST (8000000.0/44100.0) 17.73 -float SPKCONST; 17.74 -float SOUNDCONST; 17.75 -float CASCONST; 17.76 -float GUSCONST,GUSCONST2; 17.77 float CGACONST; 17.78 float MDACONST; 17.79 float VGACONST1,VGACONST2; 17.80 @@ -400,38 +405,23 @@ 17.81 17.82 17.83 /*Sound Blaster*/ 17.84 -int sbenable,sblatchi,sblatcho,sbcount,sb_enable_i,sb_count_i; 17.85 -int16_t sbdat; 17.86 +/*int sbenable,sblatchi,sblatcho,sbcount,sb_enable_i,sb_count_i; 17.87 +int16_t sbdat;*/ 17.88 void setsbclock(float clock); 17.89 17.90 -#define SADLIB 1 /*No DSP*/ 17.91 -#define SB1 2 /*DSP v1.05*/ 17.92 -#define SB15 3 /*DSP v2.00*/ 17.93 -#define SB2 4 /*DSP v2.01 - needed for high-speed DMA*/ 17.94 -#define SBPRO 5 /*DSP v3.00*/ 17.95 -#define SBPRO2 6 /*DSP v3.02 + OPL3*/ 17.96 -#define SB16 7 /*DSP v4.05 + OPL3*/ 17.97 +#define SADLIB 1 /*No DSP*/ 17.98 +#define SB1 2 /*DSP v1.05*/ 17.99 +#define SB15 3 /*DSP v2.00*/ 17.100 +#define SB2 4 /*DSP v2.01 - needed for high-speed DMA*/ 17.101 +#define SBPRO 5 /*DSP v3.00*/ 17.102 +#define SBPRO2 6 /*DSP v3.02 + OPL3*/ 17.103 +#define SB16 7 /*DSP v4.05 + OPL3*/ 17.104 +#define SADGOLD 8 /*AdLib Gold*/ 17.105 +#define SND_WSS 9 /*Windows Sound System*/ 17.106 +#define SND_PAS16 10 /*Pro Audio Spectrum 16*/ 17.107 + 17.108 int sbtype; 17.109 17.110 -struct 17.111 -{ 17.112 - int vocl,vocr,voc; 17.113 - int midl,midr,mid; 17.114 - int masl,masr,mas; 17.115 -} sbpmixer; 17.116 -extern int sb_freq; 17.117 - 17.118 -struct 17.119 -{ 17.120 - int master_l,master_r; 17.121 - int voice_l,voice_r; 17.122 - int fm_l,fm_r; 17.123 - int bass_l,bass_r; 17.124 - int treble_l,treble_r; 17.125 - int filter; 17.126 -} mixer; 17.127 - 17.128 - 17.129 int clocks[3][12][4]; 17.130 int at70hz; 17.131 17.132 @@ -466,3 +456,5 @@ 17.133 17.134 17.135 extern float isa_timing, bus_timing; 17.136 + 17.137 +extern int frame;
18.1 --- a/src/ide.c Sun Apr 21 14:54:35 2013 +0100 18.2 +++ b/src/ide.c Mon May 27 17:46:42 2013 +0100 18.3 @@ -2,7 +2,7 @@ 18.4 IDE emulation*/ 18.5 //#define RPCEMU_IDE 18.6 18.7 -#define IDE_TIME 5 18.8 +#define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) 18.9 18.10 #define _LARGEFILE_SOURCE 18.11 #define _LARGEFILE64_SOURCE 18.12 @@ -20,6 +20,9 @@ 18.13 #include "arm.h" 18.14 #else 18.15 #include "ibm.h" 18.16 + #include "io.h" 18.17 + #include "pic.h" 18.18 + #include "timer.h" 18.19 #endif 18.20 #include "ide.h" 18.21 18.22 @@ -50,6 +53,11 @@ 18.23 #define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */ 18.24 #define WIN_PACKETCMD 0xA0 /* Send a packet command. */ 18.25 #define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */ 18.26 +#define WIN_READ_MULTIPLE 0xC4 18.27 +#define WIN_WRITE_MULTIPLE 0xC5 18.28 +#define WIN_SET_MULTIPLE_MODE 0xC6 18.29 +#define WIN_READ_DMA 0xC8 18.30 +#define WIN_WRITE_DMA 0xCA 18.31 #define WIN_SETIDLE1 0xE3 18.32 #define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ 18.33 18.34 @@ -134,6 +142,7 @@ 18.35 int lba; 18.36 uint32_t lba_addr; 18.37 int skip512; 18.38 + int blocksize, blockcount; 18.39 } IDE; 18.40 18.41 IDE ide_drives[4]; 18.42 @@ -142,6 +151,10 @@ 18.43 18.44 char ide_fn[2][512]; 18.45 18.46 +int (*ide_bus_master_read_sector)(int channel, uint8_t *data); 18.47 +int (*ide_bus_master_write_sector)(int channel, uint8_t *data); 18.48 +void (*ide_bus_master_set_irq)(int channel); 18.49 + 18.50 static void callreadcd(IDE *ide); 18.51 static void atapicommand(int ide_board); 18.52 18.53 @@ -272,8 +285,15 @@ 18.54 #else 18.55 ide_padstr((char *) (ide->buffer + 27), "PCemHD", 40); /* Model */ 18.56 #endif 18.57 - ide->buffer[49] = (1<<9); /* LBA supported */ 18.58 + ide->buffer[20] = 3; /*Buffer type*/ 18.59 + ide->buffer[21] = 512; /*Buffer size*/ 18.60 + ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ 18.61 + ide->buffer[48] = 1; /*Dword transfers supported*/ 18.62 + ide->buffer[49] = (1 << 9) | (1 << 8); /* LBA and DMA supported */ 18.63 ide->buffer[50] = 0x4000; /* Capabilities */ 18.64 + ide->buffer[51] = 2 << 8; /*PIO timing mode*/ 18.65 + ide->buffer[52] = 2 << 8; /*DMA timing mode*/ 18.66 + ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; 18.67 #ifdef RPCEMU_IDE 18.68 ide->buffer[60] = (65535 * 16 * 63) & 0xFFFF; /* Total addressable sectors (LBA) */ 18.69 ide->buffer[61] = (65535 * 16 * 63) >> 16; 18.70 @@ -281,6 +301,8 @@ 18.71 ide->buffer[60] = (hdc[cur_ide[0]].tracks * hdc[cur_ide[0]].hpc * hdc[cur_ide[0]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ 18.72 ide->buffer[61] = (hdc[cur_ide[0]].tracks * hdc[cur_ide[0]].hpc * hdc[cur_ide[0]].spt) >> 16; 18.73 #endif 18.74 + ide->buffer[63] = 7; /*Multiword DMA*/ 18.75 + ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ 18.76 } 18.77 18.78 /** 18.79 @@ -571,7 +593,9 @@ 18.80 if (ide->pos>=(ide->packlen+2)) 18.81 { 18.82 ide->packetstatus=5; 18.83 + timer_process(); 18.84 idecallback[ide_board]=6*IDE_TIME; 18.85 + timer_update_outstanding(); 18.86 // pclog("Packet over!\n"); 18.87 ide_irq_lower(ide); 18.88 } 18.89 @@ -583,8 +607,10 @@ 18.90 ide->pos=0; 18.91 ide->atastat = BUSY_STAT; 18.92 ide->packetstatus=1; 18.93 - idecallback[ide_board]=6*IDE_TIME; 18.94 +/* idecallback[ide_board]=6*IDE_TIME;*/ 18.95 + timer_process(); 18.96 callbackide(ide_board); 18.97 + timer_update_outstanding(); 18.98 // idecallback[ide_board]=60*IDE_TIME; 18.99 // if ((ide->buffer[0]&0xFF)==0x43) idecallback[ide_board]=1*IDE_TIME; 18.100 // pclog("Packet now waiting!\n"); 18.101 @@ -598,15 +624,25 @@ 18.102 { 18.103 ide->pos=0; 18.104 ide->atastat = BUSY_STAT; 18.105 - idecallback[ide_board]=6*IDE_TIME; 18.106 -// callbackide(ide_board); 18.107 + timer_process(); 18.108 + if (ide->command == WIN_WRITE_MULTIPLE) 18.109 + callbackide(ide_board); 18.110 + else 18.111 + idecallback[ide_board]=6*IDE_TIME; 18.112 + timer_update_outstanding(); 18.113 } 18.114 } 18.115 18.116 +void writeidel(int ide_board, uint32_t val) 18.117 +{ 18.118 +// pclog("WriteIDEl %08X\n", val); 18.119 + writeidew(ide_board, val); 18.120 + writeidew(ide_board, val >> 16); 18.121 +} 18.122 + 18.123 void writeide(int ide_board, uint16_t addr, uint8_t val) 18.124 { 18.125 IDE *ide = &ide_drives[cur_ide[ide_board]]; 18.126 - uint8_t *idebufferb = (uint8_t *) ide->buffer; 18.127 #ifndef RPCEMU_IDE 18.128 /* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) 18.129 { 18.130 @@ -614,6 +650,8 @@ 18.131 return; 18.132 }*/ 18.133 #endif 18.134 +// if ((cr0&1) && !(eflags&VM_FLAG)) 18.135 +// pclog("WriteIDE %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, pc); 18.136 // return; 18.137 addr|=0x80; 18.138 // if (ide_board) pclog("Write IDEb %04X %02X %04X(%08X):%04X %i %02X %02X\n",addr,val,CS,cs,pc,ins,ide->atastat,ide_drives[0].atastat); 18.139 @@ -660,9 +698,26 @@ 18.140 dumpregs(); 18.141 exit(-1); 18.142 }*/ 18.143 - cur_ide[ide_board]=((val>>4)&1)+(ide_board<<1); 18.144 - ide = &ide_drives[cur_ide[ide_board]]; 18.145 - 18.146 + 18.147 + if (cur_ide[ide_board] != ((val>>4)&1)+(ide_board<<1)) 18.148 + { 18.149 + cur_ide[ide_board]=((val>>4)&1)+(ide_board<<1); 18.150 + 18.151 + if (ide->reset) 18.152 + { 18.153 + ide->atastat = READY_STAT | DSC_STAT; 18.154 + ide->error=1; 18.155 + ide->secount=1; 18.156 + ide->sector=1; 18.157 + ide->head=0; 18.158 + ide->cylinder=0; 18.159 + ide->reset = 0; 18.160 + return; 18.161 + } 18.162 + 18.163 + ide = &ide_drives[cur_ide[ide_board]]; 18.164 + } 18.165 + 18.166 ide->head=val&0xF; 18.167 ide->lba=val&0x40; 18.168 18.169 @@ -684,17 +739,32 @@ 18.170 case WIN_SRST: /* ATAPI Device Reset */ 18.171 if (IDE_DRIVE_IS_CDROM(ide)) ide->atastat = BUSY_STAT; 18.172 else ide->atastat = READY_STAT; 18.173 + timer_process(); 18.174 idecallback[ide_board]=100*IDE_TIME; 18.175 + timer_update_outstanding(); 18.176 return; 18.177 18.178 case WIN_RESTORE: 18.179 case WIN_SEEK: 18.180 +// pclog("WIN_RESTORE start\n"); 18.181 ide->atastat = READY_STAT; 18.182 + timer_process(); 18.183 idecallback[ide_board]=100*IDE_TIME; 18.184 + timer_update_outstanding(); 18.185 return; 18.186 18.187 + case WIN_READ_MULTIPLE: 18.188 + if (!ide->blocksize) 18.189 + fatal("READ_MULTIPLE - blocksize = 0\n"); 18.190 +#if 0 18.191 + if (ide->lba) pclog("Read Multiple %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr); 18.192 + else pclog("Read Multiple %i sectors from sector %i cylinder %i head %i %i\n",ide->secount,ide->sector,ide->cylinder,ide->head,ins); 18.193 +#endif 18.194 + ide->blockcount = 0; 18.195 + 18.196 case WIN_READ: 18.197 case WIN_READ_NORETRY: 18.198 + case WIN_READ_DMA: 18.199 /* if (ide.secount>1) 18.200 { 18.201 fatal("Read %i sectors from sector %i cylinder %i head %i\n",ide.secount,ide.sector,ide.cylinder,ide.head); 18.202 @@ -704,12 +774,23 @@ 18.203 else pclog("Read %i sectors from sector %i cylinder %i head %i %i\n",ide->secount,ide->sector,ide->cylinder,ide->head,ins); 18.204 #endif 18.205 ide->atastat = BUSY_STAT; 18.206 + timer_process(); 18.207 idecallback[ide_board]=200*IDE_TIME; 18.208 + timer_update_outstanding(); 18.209 return; 18.210 - 18.211 + 18.212 + case WIN_WRITE_MULTIPLE: 18.213 + if (!ide->blocksize) 18.214 + fatal("Write_MULTIPLE - blocksize = 0\n"); 18.215 +#if 0 18.216 + if (ide->lba) pclog("Write Multiple %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr); 18.217 + else pclog("Write Multiple %i sectors to sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head); 18.218 +#endif 18.219 + ide->blockcount = 0; 18.220 + 18.221 case WIN_WRITE: 18.222 - case WIN_WRITE_NORETRY: 18.223 -/* if (ide.secount>1) 18.224 + case WIN_WRITE_NORETRY: 18.225 + /* if (ide.secount>1) 18.226 { 18.227 fatal("Write %i sectors to sector %i cylinder %i head %i\n",ide.secount,ide.sector,ide.cylinder,ide.head); 18.228 }*/ 18.229 @@ -721,13 +802,26 @@ 18.230 ide->pos=0; 18.231 return; 18.232 18.233 + case WIN_WRITE_DMA: 18.234 +#if 0 18.235 + if (ide->lba) pclog("Write %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr); 18.236 + else pclog("Write %i sectors to sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head); 18.237 +#endif 18.238 + ide->atastat = BUSY_STAT; 18.239 + timer_process(); 18.240 + idecallback[ide_board]=200*IDE_TIME; 18.241 + timer_update_outstanding(); 18.242 + return; 18.243 + 18.244 case WIN_VERIFY: 18.245 #if 0 18.246 if (ide->lba) pclog("Read verify %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr); 18.247 else pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head); 18.248 #endif 18.249 ide->atastat = BUSY_STAT; 18.250 + timer_process(); 18.251 idecallback[ide_board]=200*IDE_TIME; 18.252 + timer_update_outstanding(); 18.253 return; 18.254 18.255 case WIN_FORMAT: 18.256 @@ -739,17 +833,22 @@ 18.257 18.258 case WIN_SPECIFY: /* Initialize Drive Parameters */ 18.259 ide->atastat = BUSY_STAT; 18.260 + timer_process(); 18.261 idecallback[ide_board]=200*IDE_TIME; 18.262 + timer_update_outstanding(); 18.263 // pclog("SPECIFY\n"); 18.264 // output=1; 18.265 return; 18.266 18.267 case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ 18.268 case WIN_PIDENTIFY: /* Identify Packet Device */ 18.269 + case WIN_SET_MULTIPLE_MODE: /*Set Multiple Mode*/ 18.270 // output=1; 18.271 case WIN_SETIDLE1: /* Idle */ 18.272 ide->atastat = BUSY_STAT; 18.273 + timer_process(); 18.274 idecallback[ide_board]=200*IDE_TIME; 18.275 + timer_update_outstanding(); 18.276 return; 18.277 18.278 case WIN_IDENTIFY: /* Identify Device */ 18.279 @@ -757,13 +856,17 @@ 18.280 // output=3; 18.281 // timetolive=500; 18.282 ide->atastat = BUSY_STAT; 18.283 + timer_process(); 18.284 idecallback[ide_board]=200*IDE_TIME; 18.285 + timer_update_outstanding(); 18.286 return; 18.287 18.288 case WIN_PACKETCMD: /* ATAPI Packet */ 18.289 ide->packetstatus=0; 18.290 ide->atastat = BUSY_STAT; 18.291 + timer_process(); 18.292 idecallback[ide_board]=1;//30*IDE_TIME; 18.293 + timer_update_outstanding(); 18.294 ide->pos=0; 18.295 return; 18.296 18.297 @@ -772,15 +875,18 @@ 18.298 ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; 18.299 ide->error = ABRT_ERR; 18.300 ide_irq_raise(ide); 18.301 +/* fatal("Bad IDE command %02X\n", val);*/ 18.302 return; 18.303 } 18.304 -// fatal("Bad IDE command %02X\n", val); 18.305 + 18.306 return; 18.307 18.308 case 0x3F6: /* Device control */ 18.309 if ((ide->fdisk&4) && !(val&4) && (ide->type != IDE_NONE)) 18.310 { 18.311 + timer_process(); 18.312 idecallback[ide_board]=500*IDE_TIME; 18.313 + timer_update_outstanding(); 18.314 ide->reset = 1; 18.315 ide->atastat = BUSY_STAT; 18.316 // pclog("IDE Reset\n"); 18.317 @@ -795,7 +901,6 @@ 18.318 uint8_t readide(int ide_board, uint16_t addr) 18.319 { 18.320 IDE *ide = &ide_drives[cur_ide[ide_board]]; 18.321 - const uint8_t *idebufferb = (const uint8_t *) ide->buffer; 18.322 uint8_t temp; 18.323 uint16_t tempw; 18.324 18.325 @@ -807,6 +912,8 @@ 18.326 return 0xFF; 18.327 }*/ 18.328 #endif 18.329 +// if ((cr0&1) && !(eflags&VM_FLAG)) 18.330 +// pclog("ReadIDE %04X from %04X(%08X):%08X\n", addr, CS, cs, pc); 18.331 // return 0xFF; 18.332 18.333 if (ide->type == IDE_NONE && addr != 0x1f6) return 0xff; 18.334 @@ -866,7 +973,7 @@ 18.335 else 18.336 { 18.337 // && ide->service) return ide.atastat[ide.board]|SERVICE_STAT; 18.338 -// pclog("Return status %02X\n",ide->atastat); 18.339 +// pclog("Return status %02X %04X:%04X %02X %02X\n",ide->atastat, CS ,pc, AH, BH); 18.340 temp = ide->atastat; 18.341 } 18.342 break; 18.343 @@ -910,7 +1017,7 @@ 18.344 }*/ 18.345 #endif 18.346 // return 0xFFFF; 18.347 -// pclog("Read IDEw %04X %04X:%04X %02X %i\n",ide->buffer[ide->pos >> 1],CS,pc,opcode,ins); 18.348 +// pclog("Read IDEw %04X %04X:%04X %02X %i %i\n",ide->buffer[ide->pos >> 1],CS,pc,opcode,ins, ide->pos); 18.349 18.350 //if (idedebug) pclog("Read IDEW %08X\n",PC); 18.351 18.352 @@ -921,7 +1028,7 @@ 18.353 ide->pos+=2; 18.354 if ((ide->pos>=512 && ide->command != WIN_PACKETCMD) || (ide->command == WIN_PACKETCMD && ide->pos>=ide->packlen)) 18.355 { 18.356 -// pclog("Over! packlen %i %i\n",ide.packlen,ide.pos); 18.357 +// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); 18.358 ide->pos=0; 18.359 if (ide->command == WIN_PACKETCMD)// && ide.packetstatus==6) 18.360 { 18.361 @@ -932,16 +1039,24 @@ 18.362 { 18.363 ide->atastat = READY_STAT | DSC_STAT; 18.364 ide->packetstatus=0; 18.365 - if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY) 18.366 + if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE) 18.367 { 18.368 ide->secount--; 18.369 if (ide->secount) 18.370 { 18.371 ide_next_sector(ide); 18.372 ide->atastat = BUSY_STAT; 18.373 - idecallback[ide_board]=6*IDE_TIME; 18.374 + timer_process(); 18.375 + if (ide->command == WIN_READ_MULTIPLE) 18.376 + callbackide(ide_board); 18.377 + else 18.378 + idecallback[ide_board]=6*IDE_TIME; 18.379 + timer_update_outstanding(); 18.380 +// pclog("set idecallback\n"); 18.381 // callbackide(ide_board); 18.382 } 18.383 +// else 18.384 +// pclog("readidew done %02X\n", ide->atastat); 18.385 } 18.386 } 18.387 } 18.388 @@ -949,6 +1064,12 @@ 18.389 return temp; 18.390 } 18.391 18.392 +uint32_t readidel(int ide_board) 18.393 +{ 18.394 + uint16_t temp = readidew(ide_board); 18.395 + return temp | (readidew(ide_board) << 16); 18.396 +} 18.397 + 18.398 int times30=0; 18.399 void callbackide(int ide_board) 18.400 { 18.401 @@ -972,6 +1093,7 @@ 18.402 ide->head=0; 18.403 ide->cylinder=0; 18.404 ide->reset = 0; 18.405 + ide->blocksize = 0; 18.406 // pclog("Reset callback\n"); 18.407 return; 18.408 } 18.409 @@ -996,9 +1118,10 @@ 18.410 case WIN_RESTORE: 18.411 case WIN_SEEK: 18.412 if (IDE_DRIVE_IS_CDROM(ide)) { 18.413 + pclog("WIN_RESTORE callback on CD-ROM\n"); 18.414 goto abort_cmd; 18.415 } 18.416 -// pclog("Restore callback\n"); 18.417 +// pclog("WIN_RESTORE callback\n"); 18.418 ide->atastat = READY_STAT | DSC_STAT; 18.419 ide_irq_raise(ide); 18.420 return; 18.421 @@ -1026,6 +1149,66 @@ 18.422 #endif 18.423 return; 18.424 18.425 + case WIN_READ_DMA: 18.426 + if (IDE_DRIVE_IS_CDROM(ide)) { 18.427 + goto abort_cmd; 18.428 + } 18.429 + addr = ide_get_sector(ide) * 512; 18.430 + fseeko64(ide->hdfile, addr, SEEK_SET); 18.431 + fread(ide->buffer, 512, 1, ide->hdfile); 18.432 + ide->pos=0; 18.433 + 18.434 + if (ide_bus_master_read_sector) 18.435 + { 18.436 + if (ide_bus_master_read_sector(ide_board, (uint8_t *)ide->buffer)) 18.437 + idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/ 18.438 + else 18.439 + { 18.440 + /*DMA successful*/ 18.441 + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; 18.442 + 18.443 + ide->secount--; 18.444 + if (ide->secount) 18.445 + { 18.446 + ide_next_sector(ide); 18.447 + ide->atastat = BUSY_STAT; 18.448 + idecallback[ide_board]=6*IDE_TIME; 18.449 + } 18.450 + else 18.451 + { 18.452 + ide_irq_raise(ide); 18.453 + ide_bus_master_set_irq(ide_board); 18.454 + } 18.455 + } 18.456 + } 18.457 +#ifndef RPCEMU_IDE 18.458 + readflash=1; 18.459 +#endif 18.460 + return; 18.461 + 18.462 + case WIN_READ_MULTIPLE: 18.463 + if (IDE_DRIVE_IS_CDROM(ide)) { 18.464 + goto abort_cmd; 18.465 + } 18.466 + addr = ide_get_sector(ide) * 512; 18.467 +// pclog("Read multiple from %08X %i (%i) %i\n", addr, ide->blockcount, ide->blocksize, ide->secount); 18.468 + fseeko64(ide->hdfile, addr, SEEK_SET); 18.469 + fread(ide->buffer, 512, 1, ide->hdfile); 18.470 + ide->pos=0; 18.471 + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; 18.472 + if (!ide->blockcount)// || ide->secount == 1) 18.473 + { 18.474 +// pclog("Read multiple int\n"); 18.475 + ide_irq_raise(ide); 18.476 + } 18.477 + ide->blockcount++; 18.478 + if (ide->blockcount >= ide->blocksize) 18.479 + ide->blockcount = 0; 18.480 +#ifndef RPCEMU_IDE 18.481 + readflash=1; 18.482 +#endif 18.483 + return; 18.484 + 18.485 case WIN_WRITE: 18.486 case WIN_WRITE_NORETRY: 18.487 if (IDE_DRIVE_IS_CDROM(ide)) { 18.488 @@ -1049,6 +1232,71 @@ 18.489 readflash=1; 18.490 #endif 18.491 return; 18.492 + 18.493 + case WIN_WRITE_DMA: 18.494 + if (IDE_DRIVE_IS_CDROM(ide)) { 18.495 + goto abort_cmd; 18.496 + } 18.497 + 18.498 + if (ide_bus_master_write_sector) 18.499 + { 18.500 + if (ide_bus_master_write_sector(ide_board, (uint8_t *)ide->buffer)) 18.501 + idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/ 18.502 + else 18.503 + { 18.504 + /*DMA successful*/ 18.505 + addr = ide_get_sector(ide) * 512; 18.506 + fseeko64(ide->hdfile, addr, SEEK_SET); 18.507 + fwrite(ide->buffer, 512, 1, ide->hdfile); 18.508 + 18.509 + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; 18.510 + 18.511 + ide->secount--; 18.512 + if (ide->secount) 18.513 + { 18.514 + ide_next_sector(ide); 18.515 + ide->atastat = BUSY_STAT; 18.516 + idecallback[ide_board]=6*IDE_TIME; 18.517 + } 18.518 + else 18.519 + { 18.520 + ide_irq_raise(ide); 18.521 + ide_bus_master_set_irq(ide_board); 18.522 + } 18.523 + } 18.524 + } 18.525 +#ifndef RPCEMU_IDE 18.526 + readflash=1; 18.527 +#endif 18.528 + return; 18.529 + 18.530 + case WIN_WRITE_MULTIPLE: 18.531 + if (IDE_DRIVE_IS_CDROM(ide)) { 18.532 + goto abort_cmd; 18.533 + } 18.534 + addr = ide_get_sector(ide) * 512; 18.535 +// pclog("Write sector callback %i %i %i offset %08X %i left %i\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt); 18.536 + fseeko64(ide->hdfile, addr, SEEK_SET); 18.537 + fwrite(ide->buffer, 512, 1, ide->hdfile); 18.538 + ide->blockcount++; 18.539 + if (ide->blockcount >= ide->blocksize || ide->secount == 1) 18.540 + { 18.541 + ide->blockcount = 0; 18.542 + ide_irq_raise(ide); 18.543 + } 18.544 + ide->secount--; 18.545 + if (ide->secount) 18.546 + { 18.547 + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; 18.548 + ide->pos=0; 18.549 + ide_next_sector(ide); 18.550 + } 18.551 + else 18.552 + ide->atastat = READY_STAT | DSC_STAT; 18.553 +#ifndef RPCEMU_IDE 18.554 + readflash=1; 18.555 +#endif 18.556 + return; 18.557 18.558 case WIN_VERIFY: 18.559 if (IDE_DRIVE_IS_CDROM(ide)) { 18.560 @@ -1117,6 +1365,21 @@ 18.561 // pclog("Not ATAPI\n"); 18.562 goto abort_cmd; 18.563 18.564 + case WIN_SET_MULTIPLE_MODE: 18.565 + if (IDE_DRIVE_IS_CDROM(ide)) { 18.566 +#ifndef RPCEMU_IDE 18.567 + pclog("IS CDROM - ABORT\n"); 18.568 +#endif 18.569 + goto abort_cmd; 18.570 + } 18.571 + ide->blocksize = ide->secount; 18.572 + ide->atastat = READY_STAT | DSC_STAT; 18.573 +#ifndef RPCEMU_IDE 18.574 + pclog("Set multiple mode - %i\n", ide->blocksize); 18.575 +#endif 18.576 + ide_irq_raise(ide); 18.577 + return; 18.578 + 18.579 case WIN_SETIDLE1: /* Idle */ 18.580 case 0xEF: 18.581 goto abort_cmd; 18.582 @@ -1207,6 +1470,18 @@ 18.583 ide_irq_raise(ide); 18.584 } 18.585 18.586 +void ide_callback_pri() 18.587 +{ 18.588 + idecallback[0] = 0; 18.589 + callbackide(0); 18.590 +} 18.591 + 18.592 +void ide_callback_sec() 18.593 +{ 18.594 + idecallback[1] = 0; 18.595 + callbackide(1); 18.596 +} 18.597 + 18.598 /*ATAPI CD-ROM emulation 18.599 This mostly seems to work. It is implemented only on Windows at the moment as 18.600 I haven't had time to implement any interfaces for it in the generic gui. 18.601 @@ -1714,44 +1989,93 @@ 18.602 18.603 18.604 18.605 -void ide_write_pri(uint16_t addr, uint8_t val) 18.606 +void ide_write_pri(uint16_t addr, uint8_t val, void *priv) 18.607 { 18.608 writeide(0, addr, val); 18.609 } 18.610 -void ide_write_pri_w(uint16_t addr, uint16_t val) 18.611 +void ide_write_pri_w(uint16_t addr, uint16_t val, void *priv) 18.612 { 18.613 writeidew(0, val); 18.614 } 18.615 -uint8_t ide_read_pri(uint16_t addr) 18.616 +void ide_write_pri_l(uint16_t addr, uint32_t val, void *priv) 18.617 +{ 18.618 + writeidel(0, val); 18.619 +} 18.620 +uint8_t ide_read_pri(uint16_t addr, void *priv) 18.621 { 18.622 return readide(0, addr); 18.623 } 18.624 -uint16_t ide_read_pri_w(uint16_t addr) 18.625 +uint16_t ide_read_pri_w(uint16_t addr, void *priv) 18.626 { 18.627 return readidew(0); 18.628 } 18.629 +uint32_t ide_read_pri_l(uint16_t addr, void *priv) 18.630 +{ 18.631 + return readidel(0); 18.632 +} 18.633 18.634 -void ide_write_sec(uint16_t addr, uint8_t val) 18.635 +void ide_write_sec(uint16_t addr, uint8_t val, void *priv) 18.636 { 18.637 writeide(1, addr, val); 18.638 } 18.639 -void ide_write_sec_w(uint16_t addr, uint16_t val) 18.640 +void ide_write_sec_w(uint16_t addr, uint16_t val, void *priv) 18.641 { 18.642 writeidew(1, val); 18.643 } 18.644 -uint8_t ide_read_sec(uint16_t addr) 18.645 +void ide_write_sec_l(uint16_t addr, uint32_t val, void *priv) 18.646 +{ 18.647 + writeidel(1, val); 18.648 +} 18.649 +uint8_t ide_read_sec(uint16_t addr, void *priv) 18.650 { 18.651 return readide(1, addr); 18.652 } 18.653 -uint16_t ide_read_sec_w(uint16_t addr) 18.654 +uint16_t ide_read_sec_w(uint16_t addr, void *priv) 18.655 { 18.656 return readidew(1); 18.657 } 18.658 +uint32_t ide_read_sec_l(uint16_t addr, void *priv) 18.659 +{ 18.660 + return readidel(1); 18.661 +} 18.662 + 18.663 +void ide_pri_enable() 18.664 +{ 18.665 + io_sethandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); 18.666 + io_sethandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); 18.667 +} 18.668 + 18.669 +void ide_pri_disable() 18.670 +{ 18.671 + io_removehandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); 18.672 + io_removehandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); 18.673 +} 18.674 + 18.675 +void ide_sec_enable() 18.676 +{ 18.677 + io_sethandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); 18.678 + io_sethandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); 18.679 +} 18.680 + 18.681 +void ide_sec_disable() 18.682 +{ 18.683 + io_removehandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); 18.684 + io_removehandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); 18.685 +} 18.686 18.687 void ide_init() 18.688 { 18.689 - io_sethandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, NULL, ide_write_pri, ide_write_pri_w, NULL); 18.690 - io_sethandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL); 18.691 - io_sethandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, NULL, ide_write_sec, ide_write_sec_w, NULL); 18.692 - io_sethandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL); 18.693 + ide_pri_enable(); 18.694 + ide_sec_enable(); 18.695 + ide_bus_master_read_sector = ide_bus_master_write_sector = NULL; 18.696 + 18.697 + timer_add(ide_callback_pri, &idecallback[0], &idecallback[0], NULL); 18.698 + timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL); 18.699 } 18.700 + 18.701 +void ide_set_bus_master(int (*read_sector)(int channel, uint8_t *data), int (*write_sector)(int channel, uint8_t *data), void (*set_irq)(int channel)) 18.702 +{ 18.703 + ide_bus_master_read_sector = read_sector; 18.704 + ide_bus_master_write_sector = write_sector; 18.705 + ide_bus_master_set_irq = set_irq; 18.706 +}
19.1 --- a/src/ide.h Sun Apr 21 14:54:35 2013 +0100 19.2 +++ b/src/ide.h Mon May 27 17:46:42 2013 +0100 19.3 @@ -10,6 +10,11 @@ 19.4 extern void callbackide(int ide_board); 19.5 extern void resetide(void); 19.6 extern void ide_init(); 19.7 +extern void ide_pri_enable(); 19.8 +extern void ide_sec_enable(); 19.9 +extern void ide_pri_disable(); 19.10 +extern void ide_sec_disable(); 19.11 +extern void ide_set_bus_master(int (*read_sector)(int channel, uint8_t *data), int (*write_sector)(int channel, uint8_t *data), void (*set_irq)(int channel)); 19.12 19.13 /*ATAPI stuff*/ 19.14 typedef struct ATAPI
20.1 --- a/src/io.c Sun Apr 21 14:54:35 2013 +0100 20.2 +++ b/src/io.c Mon May 27 17:46:42 2013 +0100 20.3 @@ -1,89 +1,112 @@ 20.4 #include "ibm.h" 20.5 #include "ide.h" 20.6 +#include "io.h" 20.7 #include "video.h" 20.8 #include "cpu.h" 20.9 20.10 -uint8_t (*port_inb[0x10000][2])(uint16_t addr); 20.11 -uint16_t (*port_inw[0x10000][2])(uint16_t addr); 20.12 -uint32_t (*port_inl[0x10000][2])(uint16_t addr); 20.13 +uint8_t (*port_inb[0x10000][2])(uint16_t addr, void *priv); 20.14 +uint16_t (*port_inw[0x10000][2])(uint16_t addr, void *priv); 20.15 +uint32_t (*port_inl[0x10000][2])(uint16_t addr, void *priv); 20.16 20.17 -void (*port_outb[0x10000][2])(uint16_t addr, uint8_t val); 20.18 -void (*port_outw[0x10000][2])(uint16_t addr, uint16_t val); 20.19 -void (*port_outl[0x10000][2])(uint16_t addr, uint32_t val); 20.20 +void (*port_outb[0x10000][2])(uint16_t addr, uint8_t val, void *priv); 20.21 +void (*port_outw[0x10000][2])(uint16_t addr, uint16_t val, void *priv); 20.22 +void (*port_outl[0x10000][2])(uint16_t addr, uint32_t val, void *priv); 20.23 + 20.24 +void *port_priv[0x10000][2]; 20.25 20.26 void io_init() 20.27 { 20.28 int c; 20.29 + pclog("io_init\n"); 20.30 for (c = 0; c < 0x10000; c++) 20.31 { 20.32 port_inb[c][0] = port_inw[c][0] = port_inl[c][0] = NULL; 20.33 port_outb[c][0] = port_outw[c][0] = port_outl[c][0] = NULL; 20.34 port_inb[c][1] = port_inw[c][1] = port_inl[c][1] = NULL; 20.35 port_outb[c][1] = port_outw[c][1] = port_outl[c][1] = NULL; 20.36 + port_priv[c][0] = port_priv[c][1] = NULL; 20.37 } 20.38 } 20.39 20.40 void io_sethandler(uint16_t base, int size, 20.41 - uint8_t (*inb)(uint16_t addr), 20.42 - uint16_t (*inw)(uint16_t addr), 20.43 - uint32_t (*inl)(uint16_t addr), 20.44 - void (*outb)(uint16_t addr, uint8_t val), 20.45 - void (*outw)(uint16_t addr, uint16_t val), 20.46 - void (*outl)(uint16_t addr, uint32_t val)) 20.47 + uint8_t (*inb)(uint16_t addr, void *priv), 20.48 + uint16_t (*inw)(uint16_t addr, void *priv), 20.49 + uint32_t (*inl)(uint16_t addr, void *priv), 20.50 + void (*outb)(uint16_t addr, uint8_t val, void *priv), 20.51 + void (*outw)(uint16_t addr, uint16_t val, void *priv), 20.52 + void (*outl)(uint16_t addr, uint32_t val, void *priv), 20.53 + void *priv) 20.54 { 20.55 int c; 20.56 for (c = 0; c < size; c++) 20.57 { 20.58 - if (!port_inb[ base + c][0]) port_inb[ base + c][0] = inb; 20.59 - else if (!port_inb[ base + c][1]) port_inb[ base + c][1] = inb; 20.60 - if (!port_inw[ base + c][0]) port_inw[ base + c][0] = inw; 20.61 - else if (!port_inw[ base + c][1]) port_inw[ base + c][1] = inw; 20.62 - if (!port_inl[ base + c][0]) port_inl[ base + c][0] = inl; 20.63 - else if (!port_inl[ base + c][1]) port_inl[ base + c][1] = inl; 20.64 - if (!port_outb[base + c][0]) port_outb[base + c][0] = outb; 20.65 - else if (!port_outb[base + c][1]) port_outb[base + c][1] = outb; 20.66 - if (!port_outw[base + c][0]) port_outw[base + c][0] = outw; 20.67 - else if (!port_outw[base + c][1]) port_outw[base + c][1] = outw; 20.68 - if (!port_outl[base + c][0]) port_outl[base + c][0] = outl; 20.69 - else if (!port_outl[base + c][1]) port_outl[base + c][1] = outl; 20.70 + if (!port_inb[ base + c][0] && !port_inw[ base + c][0] && !port_inl[ base + c][0] && 20.71 + !port_outb[base + c][0] && !port_outw[base + c][0] && !port_outl[base + c][0]) 20.72 + { 20.73 + port_inb[ base + c][0] = inb; 20.74 + port_inw[ base + c][0] = inw; 20.75 + port_inl[ base + c][0] = inl; 20.76 + port_outb[base + c][0] = outb; 20.77 + port_outw[base + c][0] = outw; 20.78 + port_outl[base + c][0] = outl; 20.79 + port_priv[base + c][0] = priv; 20.80 + } 20.81 + else if (!port_inb[ base + c][1] && !port_inw[ base + c][1] && !port_inl[ base + c][1] && 20.82 + !port_outb[base + c][1] && !port_outw[base + c][1] && !port_outl[base + c][1]) 20.83 + { 20.84 + port_inb[ base + c][1] = inb; 20.85 + port_inw[ base + c][1] = inw; 20.86 + port_inl[ base + c][1] = inl; 20.87 + port_outb[base + c][1] = outb; 20.88 + port_outw[base + c][1] = outw; 20.89 + port_outl[base + c][1] = outl; 20.90 + port_priv[base + c][1] = priv; 20.91 + } 20.92 } 20.93 } 20.94 20.95 void io_removehandler(uint16_t base, int size, 20.96 - uint8_t (*inb)(uint16_t addr), 20.97 - uint16_t (*inw)(uint16_t addr), 20.98 - uint32_t (*inl)(uint16_t addr), 20.99 - void (*outb)(uint16_t addr, uint8_t val), 20.100 - void (*outw)(uint16_t addr, uint16_t val), 20.101 - void (*outl)(uint16_t addr, uint32_t val)) 20.102 + uint8_t (*inb)(uint16_t addr, void *priv), 20.103 + uint16_t (*inw)(uint16_t addr, void *priv), 20.104 + uint32_t (*inl)(uint16_t addr, void *priv), 20.105 + void (*outb)(uint16_t addr, uint8_t val, void *priv), 20.106 + void (*outw)(uint16_t addr, uint16_t val, void *priv), 20.107 + void (*outl)(uint16_t addr, uint32_t val, void *priv), 20.108 + void *priv) 20.109 { 20.110 int c; 20.111 for (c = 0; c < size; c++) 20.112 { 20.113 - if (port_inb[ base + c][0] == inb) 20.114 - port_inb[ base + c][0] = NULL; 20.115 - if (port_inb[ base + c][1] == inb) 20.116 - port_inb[ base + c][1] = NULL; 20.117 - if (port_inw[ base + c][0] == inw) 20.118 - port_inw[ base + c][0] = NULL; 20.119 - if (port_inw[ base + c][1] == inw) 20.120 - port_inw[ base + c][1] = NULL; 20.121 - if (port_inl[ base + c][0] == inl) 20.122 - port_inl[ base + c][0] = NULL; 20.123 - if (port_inl[ base + c][1] == inl) 20.124 - port_inl[ base + c][1] = NULL; 20.125 - if (port_outb[ base + c][0] == outb) 20.126 - port_outb[ base + c][0] = NULL; 20.127 - if (port_outb[ base + c][1] == outb) 20.128 - port_outb[ base + c][1] = NULL; 20.129 - if (port_outw[ base + c][0] == outw) 20.130 - port_outw[ base + c][0] = NULL; 20.131 - if (port_outw[ base + c][1] == outw) 20.132 - port_outw[ base + c][1] = NULL; 20.133 - if (port_outl[ base + c][0] == outl) 20.134 - port_outl[ base + c][0] = NULL; 20.135 - if (port_outl[ base + c][1] == outl) 20.136 - port_outl[ base + c][1] = NULL; 20.137 + if (port_priv[base + c][0] == priv) 20.138 + { 20.139 + if (port_inb[ base + c][0] == inb) 20.140 + port_inb[ base + c][0] = NULL; 20.141 + if (port_inw[ base + c][0] == inw) 20.142 + port_inw[ base + c][0] = NULL; 20.143 + if (port_inl[ base + c][0] == inl) 20.144 + port_inl[ base + c][0] = NULL; 20.145 + if (port_outb[ base + c][0] == outb) 20.146 + port_outb[ base + c][0] = NULL; 20.147 + if (port_outw[ base + c][0] == outw) 20.148 + port_outw[ base + c][0] = NULL; 20.149 + if (port_outl[ base + c][0] == outl) 20.150 + port_outl[ base + c][0] = NULL; 20.151 + } 20.152 + if (port_priv[base + c][1] == priv) 20.153 + { 20.154 + if (port_inb[ base + c][1] == inb) 20.155 + port_inb[ base + c][1] = NULL; 20.156 + if (port_inw[ base + c][1] == inw) 20.157 + port_inw[ base + c][1] = NULL; 20.158 + if (port_inl[ base + c][1] == inl) 20.159 + port_inl[ base + c][1] = NULL; 20.160 + if (port_outb[ base + c][1] == outb) 20.161 + port_outb[ base + c][1] = NULL; 20.162 + if (port_outw[ base + c][1] == outw) 20.163 + port_outw[ base + c][1] = NULL; 20.164 + if (port_outl[ base + c][1] == outl) 20.165 + port_outl[ base + c][1] = NULL; 20.166 + } 20.167 } 20.168 } 20.169 20.170 @@ -95,63 +118,39 @@ 20.171 uint8_t inb(uint16_t port) 20.172 { 20.173 uint8_t temp = 0xff; 20.174 - int tempi; 20.175 + 20.176 if (port_inb[port][0]) 20.177 - temp &= port_inb[port][0](port); 20.178 + temp &= port_inb[port][0](port, port_priv[port][0]); 20.179 if (port_inb[port][1]) 20.180 - temp &= port_inb[port][1](port); 20.181 + temp &= port_inb[port][1](port, port_priv[port][1]); 20.182 + 20.183 +/* if (!port_inb[port][0] && !port_inb[port][1]) 20.184 + pclog("Bad INB %04X %04X:%04X\n", port, CS, pc);*/ 20.185 + 20.186 return temp; 20.187 - 20.188 - if (port&0x80) sw9=2; 20.189 -// if ((port&0x3F0)==0x3D0) printf("Video access read %03X %04X:%04X\n",port,cs>>4,pc); 20.190 -// if (cs<0xF0000 || cs>0x100000) printf("IN %04X %04X(%06X):%08X\n",port,CS,cs,pc); 20.191 -// /*if (output==3) */printf("IN %04X %04X:%04X\n",port,CS,pc); 20.192 -// if (port == 0x23) pclog("IN %04X %04X:%08X\n", port, CS, pc); 20.193 - switch (port) 20.194 - { 20.195 - case 0x220: case 0x221: case 0x222: case 0x223: /*Gameblaster*/ 20.196 - if (sbtype>=SBPRO) return readsb(port); 20.197 - if (GAMEBLASTER) return readcms(port); 20.198 - return 0xFF; 20.199 - } 20.200 -// printf("Bad IN port %04X %04X:%04X\n",port,cs>>4,pc); 20.201 - return 0xff; 20.202 - /*dumpregs(); 20.203 - exit(-1);*/ 20.204 } 20.205 20.206 -/*uint8_t inb(uint16_t port) 20.207 -{ 20.208 - uint8_t temp = _inb(port); 20.209 -// if (port != 0x61) pclog("IN %04X %02X %04X(%08X):%08X %f %04X %i %i\n", port, temp, CS, cs, pc, pit.c[1], CX, keybsenddelay, GetTickCount()); 20.210 - return temp; 20.211 -}*/ 20.212 - 20.213 uint8_t cpu_readport(uint32_t port) { return inb(port); } 20.214 20.215 void outb(uint16_t port, uint8_t val) 20.216 { 20.217 -// /*if (output==3) */printf("OUT %04X %02X %04X(%08X):%08X %i %i\n", port, val, CS, cs, pc, ins, GetTickCount()); 20.218 if (port_outb[port][0]) 20.219 - port_outb[port][0](port, val); 20.220 + port_outb[port][0](port, val, port_priv[port][0]); 20.221 if (port_outb[port][1]) 20.222 - port_outb[port][1](port, val); 20.223 + port_outb[port][1](port, val, port_priv[port][1]); 20.224 + 20.225 +/* if (!port_outb[port][0] && !port_outb[port][1]) 20.226 + pclog("Bad OUTB %04X %02X %04X:%08X\n", port, val, CS, pc);*/ 20.227 return; 20.228 - switch (port) 20.229 - { 20.230 - case 0x220: case 0x221: case 0x222: case 0x223: /*Gameblaster*/ 20.231 - if (GAMEBLASTER) writecms(port,val); 20.232 - return; 20.233 - } 20.234 - pclog("OUT %04X %02X %04X:%08X\n",port,val,CS,pc); 20.235 } 20.236 20.237 uint16_t inw(uint16_t port) 20.238 { 20.239 +// pclog("INW %04X\n", port); 20.240 if (port_inw[port][0]) 20.241 - return port_inw[port][0](port); 20.242 + return port_inw[port][0](port, port_priv[port][0]); 20.243 if (port_inw[port][1]) 20.244 - return port_inw[port][1](port); 20.245 + return port_inw[port][1](port, port_priv[port][1]); 20.246 20.247 return inb(port) | (inb(port + 1) << 8); 20.248 } 20.249 @@ -159,10 +158,13 @@ 20.250 void outw(uint16_t port, uint16_t val) 20.251 { 20.252 // printf("OUTW %04X %04X %04X:%08X\n",port,val, CS, pc); 20.253 +/* if ((port & ~0xf) == 0xf000) 20.254 + pclog("OUTW %04X %04X\n", port, val);*/ 20.255 + 20.256 if (port_outw[port][0]) 20.257 - port_outw[port][0](port, val); 20.258 + port_outw[port][0](port, val, port_priv[port][0]); 20.259 if (port_outw[port][1]) 20.260 - port_outw[port][1](port, val); 20.261 + port_outw[port][1](port, val, port_priv[port][1]); 20.262 20.263 if (port_outw[port][0] || port_outw[port][1]) 20.264 return; 20.265 @@ -173,20 +175,24 @@ 20.266 20.267 uint32_t inl(uint16_t port) 20.268 { 20.269 +// pclog("INL %04X\n", port); 20.270 if (port_inl[port][0]) 20.271 - return port_inl[port][0](port); 20.272 + return port_inl[port][0](port, port_priv[port][0]); 20.273 if (port_inl[port][1]) 20.274 - return port_inl[port][1](port); 20.275 + return port_inl[port][1](port, port_priv[port][1]); 20.276 20.277 return inw(port) | (inw(port + 2) << 16); 20.278 } 20.279 20.280 void outl(uint16_t port, uint32_t val) 20.281 { 20.282 +/* if ((port & ~0xf) == 0xf000) 20.283 + pclog("OUTL %04X %08X\n", port, val);*/ 20.284 + 20.285 if (port_outl[port][0]) 20.286 - port_outl[port][0](port, val); 20.287 + port_outl[port][0](port, val, port_priv[port][0]); 20.288 if (port_outl[port][1]) 20.289 - port_outl[port][1](port, val); 20.290 + port_outl[port][1](port, val, port_priv[port][1]); 20.291 20.292 if (port_outl[port][0] || port_outl[port][1]) 20.293 return;
21.1 --- a/src/io.h Sun Apr 21 14:54:35 2013 +0100 21.2 +++ b/src/io.h Mon May 27 17:46:42 2013 +0100 21.3 @@ -1,17 +1,19 @@ 21.4 void io_init(); 21.5 21.6 void io_sethandler(uint16_t base, int size, 21.7 - uint8_t (*inb)(uint16_t addr), 21.8 - uint16_t (*inw)(uint16_t addr), 21.9 - uint32_t (*inl)(uint16_t addr), 21.10 - void (*outb)(uint16_t addr, uint8_t val), 21.11 - void (*outw)(uint16_t addr, uint16_t val), 21.12 - void (*outl)(uint16_t addr, uint32_t val)); 21.13 + uint8_t (*inb)(uint16_t addr, void *priv), 21.14 + uint16_t (*inw)(uint16_t addr, void *priv), 21.15 + uint32_t (*inl)(uint16_t addr, void *priv), 21.16 + void (*outb)(uint16_t addr, uint8_t val, void *priv), 21.17 + void (*outw)(uint16_t addr, uint16_t val, void *priv), 21.18 + void (*outl)(uint16_t addr, uint32_t val, void *priv), 21.19 + void *priv); 21.20 21.21 void io_removehandler(uint16_t base, int size, 21.22 - uint8_t (*inb)(uint16_t addr), 21.23 - uint16_t (*inw)(uint16_t addr), 21.24 - uint32_t (*inl)(uint16_t addr), 21.25 - void (*outb)(uint16_t addr, uint8_t val), 21.26 - void (*outw)(uint16_t addr, uint16_t val), 21.27 - void (*outl)(uint16_t addr, uint32_t val)); 21.28 + uint8_t (*inb)(uint16_t addr, void *priv), 21.29 + uint16_t (*inw)(uint16_t addr, void *priv), 21.30 + uint32_t (*inl)(uint16_t addr, void *priv), 21.31 + void (*outb)(uint16_t addr, uint8_t val, void *priv), 21.32 + void (*outw)(uint16_t addr, uint16_t val, void *priv), 21.33 + void (*outl)(uint16_t addr, uint32_t val, void *priv), 21.34 + void *priv);
22.1 --- a/src/jim.c Sun Apr 21 14:54:35 2013 +0100 22.2 +++ b/src/jim.c Mon May 27 17:46:42 2013 +0100 22.3 @@ -1,6 +1,7 @@ 22.4 #include <stdio.h> 22.5 #include <string.h> 22.6 #include "ibm.h" 22.7 +#include "io.h" 22.8 22.9 uint8_t europcdat[16]; 22.10 struct 22.11 @@ -10,7 +11,7 @@ 22.12 int addr; 22.13 } europc_rtc; 22.14 22.15 -void writejim(uint16_t addr, uint8_t val) 22.16 +void writejim(uint16_t addr, uint8_t val, void *p) 22.17 { 22.18 if ((addr&0xFF0)==0x250) europcdat[addr&0xF]=val; 22.19 switch (addr) 22.20 @@ -38,7 +39,7 @@ 22.21 // printf("Write JIM %04X %02X\n",addr,val); 22.22 } 22.23 22.24 -uint8_t readjim(uint16_t addr) 22.25 +uint8_t readjim(uint16_t addr, void *p) 22.26 { 22.27 // printf("Read JIM %04X\n",addr); 22.28 switch (addr) 22.29 @@ -74,5 +75,5 @@ 22.30 else viddat=0x10; 22.31 europc_rtc.dat[0xB]=viddat; 22.32 europc_rtc.dat[0xD]=viddat; /*Checksum*/ 22.33 - io_sethandler(0x250, 0x10, readjim, NULL, NULL, writejim, NULL, NULL); 22.34 + io_sethandler(0x250, 0x10, readjim, NULL, NULL, writejim, NULL, NULL, NULL); 22.35 }
23.1 --- a/src/keyboard.c Sun Apr 21 14:54:35 2013 +0100 23.2 +++ b/src/keyboard.c Mon May 27 17:46:42 2013 +0100 23.3 @@ -248,7 +248,7 @@ 23.4 continue; 23.5 if (!key[c] && scancodes[c].scancodes_break[0] == -1) 23.6 continue; 23.7 - pclog("Key %02X start\n", c); 23.8 +// pclog("Key %02X start\n", c); 23.9 d = 0; 23.10 if (key[c]) 23.11 {
24.1 --- a/src/keyboard_amstrad.c Sun Apr 21 14:54:35 2013 +0100 24.2 +++ b/src/keyboard_amstrad.c Mon May 27 17:46:42 2013 +0100 24.3 @@ -1,6 +1,7 @@ 24.4 #include "ibm.h" 24.5 #include "io.h" 24.6 #include "mem.h" 24.7 +#include "pic.h" 24.8 #include "sound.h" 24.9 24.10 #include "keyboard.h" 24.11 @@ -53,7 +54,7 @@ 24.12 return; 24.13 } 24.14 24.15 -void keyboard_amstrad_write(uint16_t port, uint8_t val) 24.16 +void keyboard_amstrad_write(uint16_t port, uint8_t val, void *priv) 24.17 { 24.18 pclog("keyboard_amstrad : write %04X %02X %02X\n", port, val, keyboard_amstrad.pb); 24.19 /* if (ram[8] == 0xc3) 24.20 @@ -102,7 +103,7 @@ 24.21 } 24.22 } 24.23 24.24 -uint8_t keyboard_amstrad_read(uint16_t port) 24.25 +uint8_t keyboard_amstrad_read(uint16_t port, void *priv) 24.26 { 24.27 uint8_t temp; 24.28 // pclog("keyboard_amstrad : read %04X ", port); 24.29 @@ -161,7 +162,7 @@ 24.30 { 24.31 //return; 24.32 pclog("keyboard_amstrad_init\n"); 24.33 - io_sethandler(0x0060, 0x0006, keyboard_amstrad_read, NULL, NULL, keyboard_amstrad_write, NULL, NULL); 24.34 + io_sethandler(0x0060, 0x0006, keyboard_amstrad_read, NULL, NULL, keyboard_amstrad_write, NULL, NULL, NULL); 24.35 keyboard_amstrad_reset(); 24.36 keyboard_send = keyboard_amstrad_adddata; 24.37 keyboard_poll = keyboard_amstrad_poll;
25.1 --- a/src/keyboard_at.c Sun Apr 21 14:54:35 2013 +0100 25.2 +++ b/src/keyboard_at.c Mon May 27 17:46:42 2013 +0100 25.3 @@ -1,7 +1,9 @@ 25.4 #include "ibm.h" 25.5 #include "io.h" 25.6 #include "mem.h" 25.7 +#include "pic.h" 25.8 #include "sound.h" 25.9 +#include "timer.h" 25.10 25.11 #include "keyboard.h" 25.12 #include "keyboard_at.h" 25.13 @@ -44,22 +46,23 @@ 25.14 25.15 void keyboard_at_poll() 25.16 { 25.17 + keybsenddelay += (1000 * TIMER_USEC); 25.18 if (keyboard_at.wantirq) 25.19 { 25.20 keyboard_at.wantirq = 0; 25.21 picint(2); 25.22 - pclog("keyboard_at : take IRQ\n"); 25.23 +// pclog("keyboard_at : take IRQ\n"); 25.24 } 25.25 else if (keyboard_at.wantirq12) 25.26 { 25.27 keyboard_at.wantirq12 = 0; 25.28 picint(0x1000); 25.29 - pclog("keyboard_at : take IRQ 12\n"); 25.30 +// pclog("keyboard_at : take IRQ 12\n"); 25.31 } 25.32 if (!(keyboard_at.status & STAT_OFULL) && !(keyboard_at.mem[0] & 0x10) && 25.33 mouse_queue_start != mouse_queue_end) 25.34 { 25.35 - pclog("Reading %02X from the mouse queue at %i\n", keyboard_at.out, key_queue_start); 25.36 +// pclog("Reading %02X from the mouse queue at %i\n", keyboard_at.out, key_queue_start); 25.37 keyboard_at.out = mouse_queue[mouse_queue_start]; 25.38 mouse_queue_start = (mouse_queue_start + 1) & 0xf; 25.39 keyboard_at.status |= STAT_OFULL | STAT_MFULL; 25.40 @@ -70,7 +73,7 @@ 25.41 else if (!(keyboard_at.status & STAT_OFULL) && !(keyboard_at.mem[0] & 0x10) && 25.42 key_queue_start != key_queue_end) 25.43 { 25.44 - pclog("Reading %02X from the key queue at %i\n", keyboard_at.out, key_queue_start); 25.45 +// pclog("Reading %02X from the key queue at %i\n", keyboard_at.out, key_queue_start); 25.46 keyboard_at.out = key_queue[key_queue_start]; 25.47 key_queue_start = (key_queue_start + 1) & 0xf; 25.48 keyboard_at.status |= STAT_OFULL; 25.49 @@ -81,7 +84,7 @@ 25.50 else if (!(keyboard_at.status & STAT_OFULL) && 25.51 key_ctrl_queue_start != key_ctrl_queue_end) 25.52 { 25.53 - pclog("Reading %02X from the key ctrl_queue at %i\n", keyboard_at.out, key_ctrl_queue_start); 25.54 +// pclog("Reading %02X from the key ctrl_queue at %i\n", keyboard_at.out, key_ctrl_queue_start); 25.55 keyboard_at.out = key_ctrl_queue[key_ctrl_queue_start]; 25.56 key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; 25.57 keyboard_at.status |= STAT_OFULL; 25.58 @@ -97,7 +100,7 @@ 25.59 // { 25.60 key_ctrl_queue[key_ctrl_queue_end] = val; 25.61 key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf; 25.62 - pclog("keyboard_at : %02X added to queue\n", val); 25.63 +// pclog("keyboard_at : %02X added to queue\n", val); 25.64 /* return; 25.65 } 25.66 keyboard_at.out = val; 25.67 @@ -110,9 +113,15 @@ 25.68 25.69 void keyboard_at_adddata_keyboard(uint8_t val) 25.70 { 25.71 +/* if (val == 0x1c) 25.72 + { 25.73 + key_1c++; 25.74 + if (key_1c == 4) 25.75 + output = 3; 25.76 + }*/ 25.77 key_queue[key_queue_end] = val; 25.78 key_queue_end = (key_queue_end + 1) & 0xf; 25.79 - pclog("keyboard_at : %02X added to key queue\n", val); 25.80 +// pclog("keyboard_at : %02X added to key queue\n", val); 25.81 return; 25.82 } 25.83 25.84 @@ -120,13 +129,13 @@ 25.85 { 25.86 mouse_queue[mouse_queue_end] = val; 25.87 mouse_queue_end = (mouse_queue_end + 1) & 0xf; 25.88 - pclog("keyboard_at : %02X added to mouse queue\n", val); 25.89 +// pclog("keyboard_at : %02X added to mouse queue\n", val); 25.90 return; 25.91 } 25.92 25.93 -void keyboard_at_write(uint16_t port, uint8_t val) 25.94 +void keyboard_at_write(uint16_t port, uint8_t val, void *priv) 25.95 { 25.96 - pclog("keyboard_at : write %04X %02X %i %02X\n", port, val, keyboard_at.key_wantdata, ram[8]); 25.97 +// pclog("keyboard_at : write %04X %02X %i %02X\n", port, val, keyboard_at.key_wantdata, ram[8]); 25.98 /* if (ram[8] == 0xc3) 25.99 { 25.100 output = 3; 25.101 @@ -165,7 +174,7 @@ 25.102 break; 25.103 25.104 case 0xd1: /*Write output port*/ 25.105 - pclog("Write output port - %02X %02X %04X:%04X\n", keyboard_at.output_port, val, CS, pc); 25.106 +// pclog("Write output port - %02X %02X %04X:%04X\n", keyboard_at.output_port, val, CS, pc); 25.107 if ((keyboard_at.output_port ^ val) & 0x02) /*A20 enable change*/ 25.108 { 25.109 mem_a20_key = val & 0x02; 25.110 @@ -384,7 +393,7 @@ 25.111 } 25.112 } 25.113 25.114 -uint8_t keyboard_at_read(uint16_t port) 25.115 +uint8_t keyboard_at_read(uint16_t port, void *priv) 25.116 { 25.117 uint8_t temp = 0xff; 25.118 cycles -= 4; 25.119 @@ -428,9 +437,11 @@ 25.120 void keyboard_at_init() 25.121 { 25.122 //return; 25.123 - io_sethandler(0x0060, 0x0005, keyboard_at_read, NULL, NULL, keyboard_at_write, NULL, NULL); 25.124 + io_sethandler(0x0060, 0x0005, keyboard_at_read, NULL, NULL, keyboard_at_write, NULL, NULL, NULL); 25.125 keyboard_at_reset(); 25.126 keyboard_send = keyboard_at_adddata_keyboard; 25.127 keyboard_poll = keyboard_at_poll; 25.128 mouse_write = NULL; 25.129 + 25.130 + timer_add(keyboard_at_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); 25.131 }
26.1 --- a/src/keyboard_olim24.c Sun Apr 21 14:54:35 2013 +0100 26.2 +++ b/src/keyboard_olim24.c Mon May 27 17:46:42 2013 +0100 26.3 @@ -2,6 +2,7 @@ 26.4 #include "io.h" 26.5 #include "mem.h" 26.6 #include "mouse.h" 26.7 +#include "pic.h" 26.8 26.9 #include "keyboard.h" 26.10 #include "keyboard_olim24.h" 26.11 @@ -63,7 +64,7 @@ 26.12 return; 26.13 } 26.14 26.15 -void keyboard_olim24_write(uint16_t port, uint8_t val) 26.16 +void keyboard_olim24_write(uint16_t port, uint8_t val, void *priv) 26.17 { 26.18 pclog("keyboard_olim24 : write %04X %02X\n", port, val); 26.19 /* if (ram[8] == 0xc3) 26.20 @@ -138,7 +139,7 @@ 26.21 } 26.22 } 26.23 26.24 -uint8_t keyboard_olim24_read(uint16_t port) 26.25 +uint8_t keyboard_olim24_read(uint16_t port, void *priv) 26.26 { 26.27 uint8_t temp; 26.28 // pclog("keyboard_olim24 : read %04X ", port); 26.29 @@ -276,8 +277,8 @@ 26.30 void keyboard_olim24_init() 26.31 { 26.32 //return; 26.33 - io_sethandler(0x0060, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL); 26.34 - io_sethandler(0x0064, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL); 26.35 + io_sethandler(0x0060, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL, NULL); 26.36 + io_sethandler(0x0064, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL, NULL); 26.37 keyboard_olim24_reset(); 26.38 keyboard_send = keyboard_olim24_adddata; 26.39 keyboard_poll = keyboard_olim24_poll;
27.1 --- a/src/keyboard_xt.c Sun Apr 21 14:54:35 2013 +0100 27.2 +++ b/src/keyboard_xt.c Mon May 27 17:46:42 2013 +0100 27.3 @@ -1,7 +1,9 @@ 27.4 #include "ibm.h" 27.5 #include "io.h" 27.6 #include "mem.h" 27.7 +#include "pic.h" 27.8 #include "sound.h" 27.9 +#include "timer.h" 27.10 27.11 #include "keyboard.h" 27.12 #include "keyboard_xt.h" 27.13 @@ -28,6 +30,7 @@ 27.14 27.15 void keyboard_xt_poll() 27.16 { 27.17 + keybsenddelay += (1000 * TIMER_USEC); 27.18 if (keyboard_xt.wantirq) 27.19 { 27.20 keyboard_xt.wantirq = 0; 27.21 @@ -51,7 +54,7 @@ 27.22 return; 27.23 } 27.24 27.25 -void keyboard_xt_write(uint16_t port, uint8_t val) 27.26 +void keyboard_xt_write(uint16_t port, uint8_t val, void *priv) 27.27 { 27.28 pclog("keyboard_xt : write %04X %02X %02X\n", port, val, keyboard_xt.pb); 27.29 /* if (ram[8] == 0xc3) 27.30 @@ -86,10 +89,10 @@ 27.31 } 27.32 } 27.33 27.34 -uint8_t keyboard_xt_read(uint16_t port) 27.35 +uint8_t keyboard_xt_read(uint16_t port, void *priv) 27.36 { 27.37 uint8_t temp; 27.38 -// pclog("keyboard_xt : read %04X ", port); 27.39 + pclog("keyboard_xt : read %04X ", port); 27.40 switch (port) 27.41 { 27.42 case 0x60: 27.43 @@ -142,7 +145,7 @@ 27.44 //dumpregs(); 27.45 //exit(-1); 27.46 } 27.47 -// pclog("%02X\n", temp); 27.48 + pclog("%02X\n", temp); 27.49 return temp; 27.50 } 27.51 27.52 @@ -156,8 +159,10 @@ 27.53 void keyboard_xt_init() 27.54 { 27.55 //return; 27.56 - io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL); 27.57 + io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL, NULL); 27.58 keyboard_xt_reset(); 27.59 keyboard_send = keyboard_xt_adddata; 27.60 keyboard_poll = keyboard_xt_poll; 27.61 + 27.62 + timer_add(keyboard_xt_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); 27.63 }
28.1 --- a/src/lpt.c Sun Apr 21 14:54:35 2013 +0100 28.2 +++ b/src/lpt.c Mon May 27 17:46:42 2013 +0100 28.3 @@ -4,7 +4,7 @@ 28.4 #include "lpt.h" 28.5 28.6 static uint8_t lpt1_dat, lpt2_dat; 28.7 -void lpt1_write(uint16_t port, uint8_t val) 28.8 +void lpt1_write(uint16_t port, uint8_t val, void *priv) 28.9 { 28.10 switch (port & 3) 28.11 { 28.12 @@ -17,7 +17,7 @@ 28.13 break; 28.14 } 28.15 } 28.16 -uint8_t lpt1_read(uint16_t port) 28.17 +uint8_t lpt1_read(uint16_t port, void *priv) 28.18 { 28.19 switch (port & 3) 28.20 { 28.21 @@ -29,7 +29,7 @@ 28.22 return 0xff; 28.23 } 28.24 28.25 -void lpt2_write(uint16_t port, uint8_t val) 28.26 +void lpt2_write(uint16_t port, uint8_t val, void *priv) 28.27 { 28.28 switch (port & 3) 28.29 { 28.30 @@ -42,7 +42,7 @@ 28.31 break; 28.32 } 28.33 } 28.34 -uint8_t lpt2_read(uint16_t port) 28.35 +uint8_t lpt2_read(uint16_t port, void *priv) 28.36 { 28.37 switch (port & 3) 28.38 { 28.39 @@ -56,11 +56,32 @@ 28.40 28.41 void lpt_init() 28.42 { 28.43 - io_sethandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL); 28.44 - io_sethandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL); 28.45 + io_sethandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); 28.46 + io_sethandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); 28.47 } 28.48 28.49 +void lpt1_init(uint16_t port) 28.50 +{ 28.51 + io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); 28.52 +} 28.53 +void lpt1_remove() 28.54 +{ 28.55 + io_removehandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); 28.56 + io_removehandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); 28.57 + io_removehandler(0x03bc, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); 28.58 +} 28.59 +void lpt2_init(uint16_t port) 28.60 +{ 28.61 + io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); 28.62 +} 28.63 void lpt2_remove() 28.64 { 28.65 - io_removehandler(0x0379, 0x0002, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL); 28.66 + io_removehandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); 28.67 + io_removehandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); 28.68 + io_removehandler(0x03bc, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); 28.69 } 28.70 + 28.71 +void lpt2_remove_ams() 28.72 +{ 28.73 + io_removehandler(0x0379, 0x0002, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); 28.74 +}
29.1 --- a/src/lpt.h Sun Apr 21 14:54:35 2013 +0100 29.2 +++ b/src/lpt.h Mon May 27 17:46:42 2013 +0100 29.3 @@ -1,2 +1,6 @@ 29.4 -void lpt_init(); 29.5 -void lpt2_remove(); 29.6 +extern void lpt_init(); 29.7 +extern void lpt1_init(uint16_t port); 29.8 +extern void lpt1_remove(); 29.9 +extern void lpt2_init(uint16_t port); 29.10 +extern void lpt2_remove(); 29.11 +extern void lpt2_remove_ams();
30.1 --- a/src/mem.c Sun Apr 21 14:54:35 2013 +0100 30.2 +++ b/src/mem.c Mon May 27 17:46:42 2013 +0100 30.3 @@ -8,17 +8,20 @@ 30.4 #include <stdlib.h> 30.5 #include <string.h> 30.6 #include "ibm.h" 30.7 + 30.8 +#include "config.h" 30.9 #include "mem.h" 30.10 #include "video.h" 30.11 #include "x86.h" 30.12 #include "cpu.h" 30.13 30.14 -static uint8_t (*_mem_read_b[0x20000])(uint32_t addr); 30.15 -static uint16_t (*_mem_read_w[0x20000])(uint32_t addr); 30.16 -static uint32_t (*_mem_read_l[0x20000])(uint32_t addr); 30.17 -static void (*_mem_write_b[0x20000])(uint32_t addr, uint8_t val); 30.18 -static void (*_mem_write_w[0x20000])(uint32_t addr, uint16_t val); 30.19 -static void (*_mem_write_l[0x20000])(uint32_t addr, uint32_t val); 30.20 +static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv); 30.21 +static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv); 30.22 +static uint32_t (*_mem_read_l[0x40000])(uint32_t addr, void *priv); 30.23 +static void (*_mem_write_b[0x40000])(uint32_t addr, uint8_t val, void *priv); 30.24 +static void (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv); 30.25 +static void (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv); 30.26 +static void *_mem_priv[0x40000]; 30.27 30.28 int shadowbios,shadowbios_write; 30.29 30.30 @@ -40,14 +43,14 @@ 30.31 FILE *romfopen(char *fn, char *mode) 30.32 { 30.33 char s[512]; 30.34 - pclog("romfopen %s\n", fn); 30.35 +// pclog("romfopen %s\n", fn); 30.36 strcpy(s,pcempath); 30.37 - pclog("s = %s\n", s); 30.38 +// pclog("s = %s\n", s); 30.39 put_backslash(s); 30.40 - pclog("s = %s\n", s); 30.41 - pclog("strcat %s %s\n", s, fn); 30.42 +// pclog("s = %s\n", s); 30.43 +// pclog("strcat %s %s\n", s, fn); 30.44 strcat(s,fn); 30.45 - pclog("s = %s\n", s); 30.46 +// pclog("s = %s\n", s); 30.47 return fopen(s,mode); 30.48 } 30.49 30.50 @@ -76,18 +79,14 @@ 30.51 fclose(f); 30.52 } 30.53 } 30.54 - 30.55 -int loadbios() 30.56 + 30.57 +int mem_load_video_bios() 30.58 { 30.59 - FILE *f=NULL,*ff=NULL; 30.60 + FILE *f = NULL; 30.61 int c; 30.62 - 30.63 - loadfont("mda.rom", 0); 30.64 - 30.65 - memset(vrom,0x63,0x8000); 30.66 -// printf("Loadrom - VGA %i\n",VGA); 30.67 - if (VID_EGA) 30.68 + switch (gfxcard) 30.69 { 30.70 + case GFX_EGA: 30.71 f=romfopen("roms/ibm_6277356_ega_card_u44_27128.bin","rb"); 30.72 if (f) 30.73 { 30.74 @@ -101,67 +100,170 @@ 30.75 vrom[c]=getc(f); 30.76 } 30.77 fclose(f); 30.78 + return 1; 30.79 } 30.80 - } 30.81 - if (VGA) 30.82 - { 30.83 + break; 30.84 + 30.85 + case GFX_TVGA: 30.86 f=romfopen("roms/trident.bin","rb"); 30.87 if (f) 30.88 { 30.89 fread(vrom,32768,1,f); 30.90 fclose(f); 30.91 + return 1; 30.92 } 30.93 - } 30.94 - if (ET4000) 30.95 - { 30.96 + break; 30.97 + 30.98 + case GFX_ET4000: 30.99 f=romfopen("roms/et4000.bin","rb"); 30.100 if (f) 30.101 { 30.102 fread(vrom,32768,1,f); 30.103 fclose(f); 30.104 + return 1; 30.105 } 30.106 - } 30.107 - if (ET4000W32) 30.108 - { 30.109 + break; 30.110 + 30.111 + case GFX_ET4000W32: 30.112 f=romfopen("roms/et4000w32.bin","rb"); 30.113 if (f) 30.114 { 30.115 fread(vrom,32768,1,f); 30.116 fclose(f); 30.117 + return 1; 30.118 } 30.119 - } 30.120 - if (gfxcard == GFX_BAHAMAS64) 30.121 - { 30.122 + break; 30.123 + 30.124 + case GFX_BAHAMAS64: 30.125 f=romfopen("roms/bahamas64.bin","rb"); 30.126 if (f) 30.127 { 30.128 fread(vrom,32768,1,f); 30.129 fclose(f); 30.130 + return 1; 30.131 } 30.132 - } 30.133 - if (gfxcard == GFX_N9_9FX) 30.134 - { 30.135 + break; 30.136 + 30.137 + case GFX_N9_9FX: 30.138 f=romfopen("roms/s3_764.bin","rb"); 30.139 if (f) 30.140 { 30.141 fread(vrom,32768,1,f); 30.142 fclose(f); 30.143 + return 1; 30.144 } 30.145 - } 30.146 - if (gfxcard == GFX_STEALTH64) 30.147 - { 30.148 + break; 30.149 + 30.150 + case GFX_STEALTH64: 30.151 f=romfopen("roms/TRIO64 (Ver. 1.5-07) [VGA] (S3 Incorporated).bin","rb"); 30.152 if (f) 30.153 { 30.154 fread(vrom,32768,1,f); 30.155 fclose(f); 30.156 + return 1; 30.157 } 30.158 + break; 30.159 + 30.160 + case GFX_VIRGE: 30.161 + f=romfopen("roms/s3virge.bin","rb"); 30.162 + if (f) 30.163 + { 30.164 + fread(vrom,32768,1,f); 30.165 + fclose(f); 30.166 + return 1; 30.167 + } 30.168 + break; 30.169 + 30.170 + case GFX_TGUI9440: 30.171 + f=romfopen("roms/9440.vbi","rb"); 30.172 + if (f) 30.173 + { 30.174 + fread(vrom,32768,1,f); 30.175 + fclose(f); 30.176 + return 1; 30.177 + } 30.178 + break; 30.179 + 30.180 + case GFX_VGA: 30.181 + f=romfopen("roms/ibm_vga.bin","rb"); 30.182 + if (f) 30.183 + { 30.184 + fread(vrom,32768,1,f); 30.185 + fclose(f); 30.186 + return 1; 30.187 + } 30.188 + break; 30.189 + 30.190 + case GFX_VGAEDGE16: 30.191 + f=romfopen("roms/vgaedge16.vbi","rb"); 30.192 + if (f) 30.193 + { 30.194 + fread(vrom,32768,1,f); 30.195 + fclose(f); 30.196 + return 1; 30.197 + } 30.198 + break; 30.199 + 30.200 + case GFX_VGACHARGER: 30.201 + f=romfopen("roms/bios.bin","rb"); 30.202 + if (f) 30.203 + { 30.204 + fread(vrom,32768,1,f); 30.205 + fclose(f); 30.206 + return 1; 30.207 + } 30.208 + break; 30.209 + 30.210 + case GFX_OTI067: 30.211 + f=romfopen("roms/oti067/bios.bin","rb"); 30.212 + if (f) 30.213 + { 30.214 + fread(vrom,32768,1,f); 30.215 + fclose(f); 30.216 + return 1; 30.217 + } 30.218 + break; 30.219 + 30.220 + case GFX_MACH64GX: 30.221 + f=romfopen("roms/mach64gx/bios.bin","rb"); 30.222 + if (f) 30.223 + { 30.224 + fread(vrom,32768,1,f); 30.225 + fclose(f); 30.226 + return 1; 30.227 + } 30.228 + break; 30.229 + 30.230 + case GFX_CL_GD5429: 30.231 + f=romfopen("roms/5429.vbi","rb"); 30.232 + if (f) 30.233 + { 30.234 + fread(vrom,32768,1,f); 30.235 + fclose(f); 30.236 + return 1; 30.237 + } 30.238 + break; 30.239 + 30.240 + default: 30.241 + memset(vrom,0x63,0x8000); 30.242 + return 1; 30.243 } 30.244 - 30.245 - memset(romext,0x63,0x8000); 30.246 + pclog("mem_load_video_bios : failed to load video BIOS for gfxcard %i\n", gfxcard); 30.247 + memset(vrom,0x63,0x8000); 30.248 + return 0; 30.249 +} 30.250 + 30.251 +int loadbios() 30.252 +{ 30.253 + FILE *f=NULL,*ff=NULL; 30.254 + int c; 30.255 + 30.256 + loadfont("mda.rom", 0); 30.257 30.258 biosmask = 0xffff; 30.259 30.260 + memset(romext,0x63,0x4000); 30.261 + 30.262 pclog("Starting with romset %i\n", romset); 30.263 30.264 switch (romset) 30.265 @@ -484,6 +586,17 @@ 30.266 //is486=1; 30.267 return 1; 30.268 30.269 + case ROM_430VX: 30.270 +// f = romfopen("roms/430vx/Ga586atv.bin", "rb"); 30.271 +// f = fopen("roms/430vx/vx29.BIN", "rb"); 30.272 + f = romfopen("roms/430vx/55XWUQ0E.BIN", "rb"); 30.273 +// f=romfopen("roms/430vx/430vx","rb"); 30.274 + if (!f) break; 30.275 + fread(rom, 0x20000, 1, f); 30.276 + fclose(f); 30.277 + biosmask = 0x1ffff; 30.278 + //is486=1; 30.279 + return 1; 30.280 } 30.281 printf("Failed to load ROM!\n"); 30.282 if (f) fclose(f); 30.283 @@ -663,20 +776,23 @@ 30.284 30.285 uint32_t mmutranslatereal(uint32_t addr, int rw) 30.286 { 30.287 - int mmuout=0; 30.288 uint32_t addr2; 30.289 uint32_t temp,temp2,temp3; 30.290 - if (abrt) return -1; 30.291 + if (abrt) 30.292 + { 30.293 +// pclog("Translate recursive abort\n"); 30.294 + return -1; 30.295 + } 30.296 /* if ((addr&~0xFFFFF)==0x77f00000) pclog("Do translate %08X %i %08X %08X\n",addr,rw,EAX,pc); 30.297 if (addr==0x77f61000) output = 3; 30.298 if (addr==0x77f62000) { dumpregs(); exit(-1); } 30.299 if (addr==0x77f9a000) { dumpregs(); exit(-1); }*/ 30.300 addr2=(cr3+((addr>>20)&0xFFC)); 30.301 temp=temp2=((uint32_t *)ram)[addr2>>2]; 30.302 -// pclog("Do translate %08X %i %08X\n", addr, rw, temp); 30.303 +// if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, temp); 30.304 if (!(temp&1))// || (CPL==3 && !(temp&4) && !cpl_override) || (rw && !(temp&2) && (CPL==3 || cr0&WP_FLAG))) 30.305 { 30.306 -// if (/*output==3 && */!nopageerrors) pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,pc,CPL,rw); 30.307 +// /*if (!nopageerrors && opcode != 0xf3 && opcode != 0x89) */pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,pc,CPL,rw); 30.308 30.309 cr2=addr; 30.310 temp&=1; 30.311 @@ -693,13 +809,16 @@ 30.312 } 30.313 temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2]; 30.314 temp3=temp&temp2; 30.315 -// pclog("Do translate %08X %08X\n", temp, temp3); 30.316 +// if (output == 3) pclog("Do translate %08X %08X\n", temp, temp3); 30.317 if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG))) 30.318 { 30.319 -// if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %04X:%08X %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,CS,pc,SS,ESP,ins,CPL,rw); 30.320 +// /*if (!nopageerrors && opcode != 0xf3 && opcode != 0x89) */pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,frame,rmdat32, CS,pc,SS,ESP,ins,CPL,rw); 30.321 + 30.322 +// dumpregs(); 30.323 +// exit(-1); 30.324 // if (addr == 0x815F6E90) output = 3; 30.325 -/* if (addr == 0x10ADE020) output = 3; 30.326 - if (addr == 0x10000008) 30.327 +/* if (addr == 0x10ADE020) output = 3;*/ 30.328 +/* if (addr == 0x10150010 && !nopageerrors) 30.329 { 30.330 dumpregs(); 30.331 exit(-1); 30.332 @@ -816,7 +935,7 @@ 30.333 { 30.334 // int logit=(a>0xFFFFF); 30.335 uint32_t a2=a; 30.336 - if (readlookup2[a>>12]!=0xFFFFFFFF) return &ram[(uint8_t *)readlookup2[a>>12] - (uint8_t *)(a&~0xFFF)]; 30.337 + //if (readlookup2[a>>12]!=0xFFFFFFFF) return &ram[(uint8_t *)readlookup2[a>>12] - (uint8_t *)(a&~0xFFF)]; 30.338 if (cr0>>31) 30.339 { 30.340 // if (output==3) pclog("Translate GetPCCache %08X\n",a); 30.341 @@ -870,12 +989,8 @@ 30.342 } 30.343 addr &= rammask; 30.344 30.345 - switch (addr>>16) 30.346 - { 30.347 - case 13: if (romset==ROM_AMI286) return neat_readems(addr); return 0xFF; 30.348 -// case 14: pclog("Read %06X\n", addr); if (shadowbios) { /*printf("Read shadow RAM %08X %02X\n",addr,ram[addr]);*/ return ram[addr]; } 30.349 - } 30.350 - if (_mem_read_b[addr >> 15]) return _mem_read_b[addr >> 15](addr); 30.351 + if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv[addr >> 14]); 30.352 +// pclog("Bad readmembl %08X %04X:%08X\n", addr, CS, pc); 30.353 return 0xFF; 30.354 } 30.355 30.356 @@ -890,15 +1005,8 @@ 30.357 } 30.358 addr &= rammask; 30.359 30.360 - switch (addr>>16) 30.361 - { 30.362 - case 13: if (romset==ROM_AMI286) neat_writeems(addr,val); return; 30.363 -// case 14: printf("Write %08X %02X\n",addr,val); //ram[addr]=val; 30.364 -// if (isram[(addr>>16)&0xFF]) ram[addr]=val; 30.365 -// return; 30.366 - } 30.367 - if (_mem_write_b[addr >> 15]) _mem_write_b[addr >> 15](addr, val); 30.368 -// else pclog("Bad write %08X %02X\n", addr, val); 30.369 + if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv[addr >> 14]); 30.370 +// else pclog("Bad write %08X %02X %04X:%08X\n", addr, val, CS, pc); 30.371 } 30.372 30.373 uint8_t readmemb386l(uint32_t seg, uint32_t addr) 30.374 @@ -910,10 +1018,10 @@ 30.375 return -1; 30.376 } 30.377 mem_logical_addr = addr = addr + seg; 30.378 - if (readlookup2[mem_logical_addr >> 12] != 0xFFFFFFFF) 30.379 +/* if (readlookup2[mem_logical_addr >> 12] != 0xFFFFFFFF) 30.380 { 30.381 return ram[readlookup2[mem_logical_addr >> 12] + (mem_logical_addr & 0xFFF)]; 30.382 - } 30.383 + }*/ 30.384 30.385 if (cr0 >> 31) 30.386 { 30.387 @@ -923,7 +1031,8 @@ 30.388 30.389 addr &= rammask; 30.390 30.391 - if (_mem_read_b[addr >> 15]) return _mem_read_b[addr >> 15](addr); 30.392 + if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv[addr >> 14]); 30.393 +// pclog("Bad readmemb386l %08X %04X:%08X\n", addr, CS, pc); 30.394 return 0xFF; 30.395 } 30.396 30.397 @@ -945,8 +1054,11 @@ 30.398 30.399 addr &= rammask; 30.400 30.401 - if (_mem_write_b[addr >> 15]) _mem_write_b[addr >> 15](addr, val); 30.402 -// else pclog("Bad write %08X %02X\n", addr, val); 30.403 +/* if (addr >= 0xa0000 && addr < 0xc0000) 30.404 + pclog("writemembl %08X %02X\n", addr, val);*/ 30.405 + 30.406 + if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv[addr >> 14]); 30.407 +// else pclog("Bad write %08X %02X %04X:%08X\n", addr, val, CS, pc); 30.408 } 30.409 30.410 uint16_t readmemwl(uint32_t seg, uint32_t addr) 30.411 @@ -956,8 +1068,8 @@ 30.412 { 30.413 if (cr0>>31) 30.414 { 30.415 - if (mmutranslate(addr2, 0) == 0xffffffff) return; 30.416 - if (mmutranslate(addr2+1, 0) == 0xffffffff) return; 30.417 + if (mmutranslate(addr2, 0) == 0xffffffff) return 0xffff; 30.418 + if (mmutranslate(addr2+1, 0) == 0xffffffff) return 0xffff; 30.419 } 30.420 if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8); 30.421 else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8); 30.422 @@ -976,12 +1088,12 @@ 30.423 30.424 addr2 &= rammask; 30.425 30.426 - if (_mem_read_w[addr2 >> 15]) return _mem_read_w[addr2 >> 15](addr2); 30.427 + if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]); 30.428 30.429 - if (_mem_read_b[addr2 >> 15]) 30.430 + if (_mem_read_b[addr2 >> 14]) 30.431 { 30.432 - if (AT) return _mem_read_b[addr2 >> 15](addr2) | (_mem_read_b[(addr2 + 1) >> 15](addr2 + 1) << 8); 30.433 - else return _mem_read_b[addr2 >> 15](addr2) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 15](seg + ((addr + 1) & 0xffff)) << 8); 30.434 + if (AT) return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv[addr2 >> 14]) << 8); 30.435 + else return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv[addr2 >> 14]) << 8); 30.436 } 30.437 return 0xffff; 30.438 } 30.439 @@ -1022,19 +1134,20 @@ 30.440 } 30.441 30.442 addr2 &= rammask; 30.443 + 30.444 +/* if (addr2 >= 0xa0000 && addr2 < 0xc0000) 30.445 + pclog("writememwl %08X %02X\n", addr2, val);*/ 30.446 30.447 - if (_mem_write_w[addr2 >> 15]) 30.448 + if (_mem_write_w[addr2 >> 14]) 30.449 { 30.450 - _mem_write_w[addr2 >> 15](addr2, val); 30.451 + _mem_write_w[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]); 30.452 return; 30.453 } 30.454 30.455 - if (_mem_write_b[addr2 >> 15]) 30.456 + if (_mem_write_b[addr2 >> 14]) 30.457 { 30.458 - _mem_write_b[addr2 >> 15](addr2, val); 30.459 - _mem_write_b[(addr2 + 1) >> 15](addr2 + 1, val >> 8); 30.460 -// if (AT) _ 30.461 -// else _mem_write_b[(seg + ((addr + 1) & 0xffff)) >> 15](seg + ((addr + 1) & 0xffff), val >> 8); 30.462 + _mem_write_b[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]); 30.463 + _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv[addr2 >> 14]); 30.464 return; 30.465 } 30.466 // pclog("Bad write %08X %04X\n", addr, val); 30.467 @@ -1047,8 +1160,8 @@ 30.468 { 30.469 if (cr0>>31) 30.470 { 30.471 - if (mmutranslate(addr2, 0) == 0xffffffff) return; 30.472 - if (mmutranslate(addr2+3, 0) == 0xffffffff) return; 30.473 + if (mmutranslate(addr2, 0) == 0xffffffff) return 0xffffffff; 30.474 + if (mmutranslate(addr2+3, 0) == 0xffffffff) return 0xffffffff; 30.475 } 30.476 return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); 30.477 } 30.478 @@ -1068,11 +1181,11 @@ 30.479 30.480 addr2&=rammask; 30.481 30.482 - if (_mem_read_l[addr2 >> 15]) return _mem_read_l[addr2 >> 15](addr2); 30.483 + if (_mem_read_l[addr2 >> 14]) return _mem_read_l[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]); 30.484 30.485 - if (_mem_read_w[addr2 >> 15]) return _mem_read_w[addr2 >> 15](addr2) | (_mem_read_w[addr2 >> 15](addr2 + 2) << 16); 30.486 + if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv[addr2 >> 14]) << 16); 30.487 30.488 - if (_mem_read_b[addr2 >> 15]) return _mem_read_b[addr2 >> 15](addr2) | (_mem_read_b[addr2 >> 15](addr2 + 1) << 8) | (_mem_read_b[addr2 >> 15](addr2 + 2) << 16) | (_mem_read_b[addr2 >> 15](addr2 + 3) << 24); 30.489 + if (_mem_read_b[addr2 >> 14]) return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv[addr2 >> 14]) << 24); 30.490 30.491 return 0xffffffff; 30.492 } 30.493 @@ -1106,67 +1219,70 @@ 30.494 30.495 addr2&=rammask; 30.496 30.497 - if (_mem_write_l[addr2 >> 15]) 30.498 +/* if (addr >= 0xa0000 && addr < 0xc0000) 30.499 + pclog("writememll %08X %08X\n", addr, val);*/ 30.500 + 30.501 + if (_mem_write_l[addr2 >> 14]) 30.502 { 30.503 - _mem_write_l[addr2 >> 15](addr2, val); 30.504 + _mem_write_l[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]); 30.505 return; 30.506 } 30.507 - if (_mem_write_w[addr2 >> 15]) 30.508 + if (_mem_write_w[addr2 >> 14]) 30.509 { 30.510 - _mem_write_w[addr2 >> 15](addr2, val); 30.511 - _mem_write_w[addr2 >> 15](addr2 + 2, val >> 16); 30.512 + _mem_write_w[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]); 30.513 + _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv[addr2 >> 14]); 30.514 return; 30.515 } 30.516 - if (_mem_write_b[addr2 >> 15]) 30.517 + if (_mem_write_b[addr2 >> 14]) 30.518 { 30.519 - _mem_write_b[addr2 >> 15](addr2, val); 30.520 - _mem_write_b[addr2 >> 15](addr2 + 1, val >> 8); 30.521 - _mem_write_b[addr2 >> 15](addr2 + 2, val >> 16); 30.522 - _mem_write_b[addr2 >> 15](addr2 + 3, val >> 24); 30.523 + _mem_write_b[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]); 30.524 + _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv[addr2 >> 14]); 30.525 + _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv[addr2 >> 14]); 30.526 + _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv[addr2 >> 14]); 30.527 return; 30.528 } 30.529 // pclog("Bad write %08X %08X\n", addr, val); 30.530 } 30.531 30.532 -uint8_t mem_read_ram(uint32_t addr) 30.533 +uint8_t mem_read_ram(uint32_t addr, void *priv) 30.534 { 30.535 -// if (addr < 0xa0000) pclog("Read RAMb %08X\n", addr); 30.536 +// if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMb %08X\n", addr); 30.537 addreadlookup(mem_logical_addr, addr); 30.538 return ram[addr]; 30.539 } 30.540 -uint16_t mem_read_ramw(uint32_t addr) 30.541 +uint16_t mem_read_ramw(uint32_t addr, void *priv) 30.542 { 30.543 -// if (addr < 0xa0000) pclog("Read RAMw %08X\n", addr); 30.544 +// if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMw %08X\n", addr); 30.545 addreadlookup(mem_logical_addr, addr); 30.546 return *(uint16_t *)&ram[addr]; 30.547 } 30.548 -uint32_t mem_read_raml(uint32_t addr) 30.549 +uint32_t mem_read_raml(uint32_t addr, void *priv) 30.550 { 30.551 -// if (addr < 0xa0000) pclog("Read RAMl %08X\n", addr); 30.552 +// if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMl %08X\n", addr); 30.553 addreadlookup(mem_logical_addr, addr); 30.554 return *(uint32_t *)&ram[addr]; 30.555 } 30.556 30.557 -void mem_write_ram(uint32_t addr, uint8_t val) 30.558 +void mem_write_ram(uint32_t addr, uint8_t val, void *priv) 30.559 { 30.560 addwritelookup(mem_logical_addr, addr); 30.561 ram[addr] = val; 30.562 // if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMb %08X\n", addr); 30.563 } 30.564 -void mem_write_ramw(uint32_t addr, uint16_t val) 30.565 +void mem_write_ramw(uint32_t addr, uint16_t val, void *priv) 30.566 { 30.567 addwritelookup(mem_logical_addr, addr); 30.568 *(uint16_t *)&ram[addr] = val; 30.569 -// if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMw %08X %04X:%04X\n", addr, CS, pc); 30.570 +// if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMw %08X %04X:%04X %i %04X %04X:%04X %04X:%04X\n", addr, CS, pc, ins, val, DS,SI, ES,DI); 30.571 } 30.572 -void mem_write_raml(uint32_t addr, uint32_t val) 30.573 +void mem_write_raml(uint32_t addr, uint32_t val, void *priv) 30.574 { 30.575 addwritelookup(mem_logical_addr, addr); 30.576 *(uint32_t *)&ram[addr] = val; 30.577 // if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMl %08X %04X:%04X %04X:%04X %04X:%04X\n", addr, CS, pc, DS,SI, ES,DI); 30.578 } 30.579 30.580 -uint8_t mem_read_bios(uint32_t addr) 30.581 +uint8_t mem_read_bios(uint32_t addr, void *priv) 30.582 { 30.583 if (AMIBIOS && (addr&0xFFFFF)==0xF8281) /*This is read constantly during AMIBIOS POST, but is never written to. It's clearly a status register of some kind, but for what?*/ 30.584 { 30.585 @@ -1177,39 +1293,39 @@ 30.586 // if (output) pclog("Read BIOS %08X %02X %04X:%04X\n", addr, rom[addr & biosmask], CS, pc); 30.587 return rom[addr & biosmask]; 30.588 } 30.589 -uint16_t mem_read_biosw(uint32_t addr) 30.590 +uint16_t mem_read_biosw(uint32_t addr, void *priv) 30.591 { 30.592 -// if (output) pclog("Read BIOS %08X %04X %04X:%04X\n", addr, *(uint16_t *)&rom[addr & biosmask], CS, pc); 30.593 +// /*if (output) */pclog("Read BIOS %08X %04X %04X:%04X\n", addr, *(uint16_t *)&rom[addr & biosmask], CS, pc); 30.594 return *(uint16_t *)&rom[addr & biosmask]; 30.595 } 30.596 -uint32_t mem_read_biosl(uint32_t addr) 30.597 +uint32_t mem_read_biosl(uint32_t addr, void *priv) 30.598 { 30.599 -// if (output) pclog("Read BIOS %08X %02X %04X:%04X\n", addr, *(uint32_t *)&rom[addr & biosmask], CS, pc); 30.600 +// pclog("Read BIOS %08X %02X %04X:%04X\n", addr, *(uint32_t *)&rom[addr & biosmask], CS, pc); 30.601 return *(uint32_t *)&rom[addr & biosmask]; 30.602 } 30.603 30.604 -uint8_t mem_read_vrom(uint32_t addr) 30.605 +uint8_t mem_read_vrom(uint32_t addr, void *priv) 30.606 { 30.607 return vrom[addr & 0x7fff]; 30.608 } 30.609 -uint16_t mem_read_vromw(uint32_t addr) 30.610 +uint16_t mem_read_vromw(uint32_t addr, void *priv) 30.611 { 30.612 return *(uint16_t *)&vrom[addr & 0x7fff]; 30.613 } 30.614 -uint32_t mem_read_vroml(uint32_t addr) 30.615 +uint32_t mem_read_vroml(uint32_t addr, void *priv) 30.616 { 30.617 return *(uint32_t *)&vrom[addr & 0x7fff]; 30.618 } 30.619 30.620 -uint8_t mem_read_romext(uint32_t addr) 30.621 +uint8_t mem_read_romext(uint32_t addr, void *priv) 30.622 { 30.623 return romext[addr & 0x7fff]; 30.624 } 30.625 -uint16_t mem_read_romextw(uint32_t addr) 30.626 +uint16_t mem_read_romextw(uint32_t addr, void *priv) 30.627 { 30.628 return *(uint16_t *)&romext[addr & 0x7fff]; 30.629 } 30.630 -uint32_t mem_read_romextl(uint32_t addr) 30.631 +uint32_t mem_read_romextl(uint32_t addr, void *priv) 30.632 { 30.633 return *(uint32_t *)&romext[addr & 0x7fff]; 30.634 } 30.635 @@ -1233,16 +1349,16 @@ 30.636 isram[c]=1; 30.637 if (c >= 0xa && c<=0xF) isram[c]=0; 30.638 } 30.639 - for (c = 0; c < 0x20000; c++) 30.640 - _mem_read_b[c] = _mem_read_w[c] = _mem_read_l[c] = _mem_write_b[c] = _mem_write_w[c] = _mem_write_l[c] = NULL; 30.641 + for (c = 0; c < 0x40000; c++) 30.642 + _mem_read_b[c] = _mem_read_w[c] = _mem_read_l[c] = _mem_write_b[c] = _mem_write_w[c] = _mem_write_l[c] = _mem_priv[c] = NULL; 30.643 30.644 - mem_sethandler(0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); 30.645 + mem_sethandler(0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); 30.646 if (mem_size > 1) 30.647 - mem_sethandler(0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); 30.648 + mem_sethandler(0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); 30.649 30.650 - mem_sethandler(0xc0000, 0x08000, mem_read_vrom, mem_read_vromw, mem_read_vroml, NULL, NULL, NULL); 30.651 - mem_sethandler(0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL); 30.652 - mem_sethandler(0xe0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml); 30.653 + mem_sethandler(0xc0000, 0x08000, mem_read_vrom, mem_read_vromw, mem_read_vroml, NULL, NULL, NULL, NULL); 30.654 + mem_sethandler(0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, NULL); 30.655 + mem_sethandler(0xe0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); 30.656 // pclog("Mem resize %i %i\n",mem_size,c); 30.657 } 30.658 30.659 @@ -1258,16 +1374,16 @@ 30.660 isram[c]=1; 30.661 if (c >= 0xa && c<=0xF) isram[c]=0; 30.662 } 30.663 - for (c = 0; c < 0x20000; c++) 30.664 - _mem_read_b[c] = _mem_read_w[c] = _mem_read_l[c] = _mem_write_b[c] = _mem_write_w[c] = _mem_write_l[c] = NULL; 30.665 + for (c = 0; c < 0x40000; c++) 30.666 + _mem_read_b[c] = _mem_read_w[c] = _mem_read_l[c] = _mem_write_b[c] = _mem_write_w[c] = _mem_write_l[c] = _mem_priv[c] = NULL; 30.667 30.668 - mem_sethandler(0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); 30.669 + mem_sethandler(0x00000, 0xa0000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); 30.670 if (mem_size > 1) 30.671 - mem_sethandler(0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); 30.672 + mem_sethandler(0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); 30.673 30.674 - mem_sethandler(0xc0000, 0x8000, mem_read_vrom, mem_read_vromw, mem_read_vroml, NULL, NULL, NULL); 30.675 - mem_sethandler(0xc8000, 0x8000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL); 30.676 - mem_sethandler(0xe0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml); 30.677 + mem_sethandler(0xc0000, 0x8000, mem_read_vrom, mem_read_vromw, mem_read_vroml, NULL, NULL, NULL, NULL); 30.678 + mem_sethandler(0xc8000, 0x8000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, NULL); 30.679 + mem_sethandler(0xe0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); 30.680 // pclog("Mem resize %i %i\n",mem_size,c); 30.681 } 30.682 30.683 @@ -1295,44 +1411,62 @@ 30.684 } 30.685 30.686 void mem_sethandler(uint32_t base, uint32_t size, 30.687 - uint8_t (*read_b)(uint32_t addr), 30.688 - uint16_t (*read_w)(uint32_t addr), 30.689 - uint32_t (*read_l)(uint32_t addr), 30.690 - void (*write_b)(uint32_t addr, uint8_t val), 30.691 - void (*write_w)(uint32_t addr, uint16_t val), 30.692 - void (*write_l)(uint32_t addr, uint32_t val)) 30.693 + uint8_t (*read_b)(uint32_t addr, void *priv), 30.694 + uint16_t (*read_w)(uint32_t addr, void *priv), 30.695 + uint32_t (*read_l)(uint32_t addr, void *priv), 30.696 + void (*write_b)(uint32_t addr, uint8_t val, void *priv), 30.697 + void (*write_w)(uint32_t addr, uint16_t val, void *priv), 30.698 + void (*write_l)(uint32_t addr, uint32_t val, void *priv), 30.699 + void *priv) 30.700 { 30.701 uint32_t c; 30.702 - for (c = base; c < base + size; c += 0x8000) 30.703 +// printf("mem_sethandler : %05X %04X %08X %08X %08X %08X %08X\n", base, size, read_w, write_w, mem_read_biosw, mem_read_ramw, mem_write_ramw); 30.704 + for (c = base; c < base + size; c += 0x4000) 30.705 { 30.706 - _mem_read_b[ c >> 15] = read_b; 30.707 - _mem_read_w[ c >> 15] = read_w; 30.708 - _mem_read_l[ c >> 15] = read_l; 30.709 - _mem_write_b[c >> 15] = write_b; 30.710 - _mem_write_w[c >> 15] = write_w; 30.711 - _mem_write_l[c >> 15] = write_l; 30.712 + _mem_read_b[ c >> 14] = read_b; 30.713 + _mem_read_w[ c >> 14] = read_w; 30.714 + _mem_read_l[ c >> 14] = read_l; 30.715 + _mem_write_b[c >> 14] = write_b; 30.716 + _mem_write_w[c >> 14] = write_w; 30.717 + _mem_write_l[c >> 14] = write_l; 30.718 + _mem_priv[c >> 14] = priv; 30.719 + } 30.720 + for (c = base; c < base + size; c += 0x1000) 30.721 + { 30.722 + readlookup2[c >> 12] = 0xFFFFFFFF; 30.723 + writelookup2[c >> 12] = 0xFFFFFFFF; 30.724 } 30.725 } 30.726 30.727 void mem_removehandler(uint32_t base, uint32_t size, 30.728 - uint8_t (*read_b)(uint32_t addr), 30.729 - uint16_t (*read_w)(uint32_t addr), 30.730 - uint32_t (*read_l)(uint32_t addr), 30.731 - void (*write_b)(uint32_t addr, uint8_t val), 30.732 - void (*write_w)(uint32_t addr, uint16_t val), 30.733 - void (*write_l)(uint32_t addr, uint32_t val)) 30.734 + uint8_t (*read_b)(uint32_t addr, void *priv), 30.735 + uint16_t (*read_w)(uint32_t addr, void *priv), 30.736 + uint32_t (*read_l)(uint32_t addr, void *priv), 30.737 + void (*write_b)(uint32_t addr, uint8_t val, void *priv), 30.738 + void (*write_w)(uint32_t addr, uint16_t val, void *priv), 30.739 + void (*write_l)(uint32_t addr, uint32_t val, void *priv), 30.740 + void *priv) 30.741 { 30.742 uint32_t c; 30.743 if ((base + size) > 0xffff8000) 30.744 size = 0xffff0000 - base; 30.745 - for (c = base; c < base + size; c += 0x8000) 30.746 + for (c = base; c < base + size; c += 0x4000) 30.747 { 30.748 - if ( _mem_read_b[c >> 15] == read_b) _mem_read_b[c >> 15] = NULL; 30.749 - if ( _mem_read_w[c >> 15] == read_w) _mem_read_w[c >> 15] = NULL; 30.750 - if ( _mem_read_l[c >> 15] == read_l) _mem_read_l[c >> 15] = NULL; 30.751 - if (_mem_write_b[c >> 15] == write_b) _mem_write_b[c >> 15] = NULL; 30.752 - if (_mem_write_w[c >> 15] == write_w) _mem_write_w[c >> 15] = NULL; 30.753 - if (_mem_write_l[c >> 15] == write_l) _mem_write_l[c >> 15] = NULL; 30.754 + if (_mem_priv[c >> 14] == priv) 30.755 + { 30.756 + if ( _mem_read_b[c >> 14] == read_b) _mem_read_b[c >> 14] = NULL; 30.757 + if ( _mem_read_w[c >> 14] == read_w) _mem_read_w[c >> 14] = NULL; 30.758 + if ( _mem_read_l[c >> 14] == read_l) _mem_read_l[c >> 14] = NULL; 30.759 + if (_mem_write_b[c >> 14] == write_b) _mem_write_b[c >> 14] = NULL; 30.760 + if (_mem_write_w[c >> 14] == write_w) _mem_write_w[c >> 14] = NULL; 30.761 + if (_mem_write_l[c >> 14] == write_l) _mem_write_l[c >> 14] = NULL; 30.762 + _mem_priv[c >> 14] = NULL; 30.763 + } 30.764 + } 30.765 + for (c = base; c < base + size; c += 0x1000) 30.766 + { 30.767 + readlookup2[c >> 12] = 0xFFFFFFFF; 30.768 + writelookup2[c >> 12] = 0xFFFFFFFF; 30.769 } 30.770 } 30.771 30.772 @@ -1342,7 +1476,7 @@ 30.773 void mem_a20_recalc() 30.774 { 30.775 int state = mem_a20_key | mem_a20_alt; 30.776 - pclog("A20 recalc %i %i\n", state, mem_a20_state); 30.777 +// pclog("A20 recalc %i %i\n", state, mem_a20_state); 30.778 if (state && !mem_a20_state) 30.779 { 30.780 rammask = 0xffffffff; 30.781 @@ -1353,6 +1487,6 @@ 30.782 rammask = 0xffefffff; 30.783 flushmmucache(); 30.784 } 30.785 - pclog("rammask now %08X\n", rammask); 30.786 +// pclog("rammask now %08X\n", rammask); 30.787 mem_a20_state = state; 30.788 }
31.1 --- a/src/mem.h Sun Apr 21 14:54:35 2013 +0100 31.2 +++ b/src/mem.h Mon May 27 17:46:42 2013 +0100 31.3 @@ -7,34 +7,38 @@ 31.4 extern int memwaitstate; 31.5 31.6 void mem_sethandler(uint32_t base, uint32_t size, 31.7 - uint8_t (*read_b)(uint32_t addr), 31.8 - uint16_t (*read_w)(uint32_t addr), 31.9 - uint32_t (*read_l)(uint32_t addr), 31.10 - void (*write_b)(uint32_t addr, uint8_t val), 31.11 - void (*write_w)(uint32_t addr, uint16_t val), 31.12 - void (*write_l)(uint32_t addr, uint32_t val)); 31.13 + uint8_t (*read_b)(uint32_t addr, void *priv), 31.14 + uint16_t (*read_w)(uint32_t addr, void *priv), 31.15 + uint32_t (*read_l)(uint32_t addr, void *priv), 31.16 + void (*write_b)(uint32_t addr, uint8_t val, void *priv), 31.17 + void (*write_w)(uint32_t addr, uint16_t val, void *priv), 31.18 + void (*write_l)(uint32_t addr, uint32_t val, void *priv), 31.19 + void *priv); 31.20 31.21 void mem_removehandler(uint32_t base, uint32_t size, 31.22 - uint8_t (*read_b)(uint32_t addr), 31.23 - uint16_t (*read_w)(uint32_t addr), 31.24 - uint32_t (*read_l)(uint32_t addr), 31.25 - void (*write_b)(uint32_t addr, uint8_t val), 31.26 - void (*write_w)(uint32_t addr, uint16_t val), 31.27 - void (*write_l)(uint32_t addr, uint32_t val)); 31.28 + uint8_t (*read_b)(uint32_t addr, void *priv), 31.29 + uint16_t (*read_w)(uint32_t addr, void *priv), 31.30 + uint32_t (*read_l)(uint32_t addr, void *priv), 31.31 + void (*write_b)(uint32_t addr, uint8_t val, void *priv), 31.32 + void (*write_w)(uint32_t addr, uint16_t val, void *priv), 31.33 + void (*write_l)(uint32_t addr, uint32_t val, void *priv), 31.34 + void *priv); 31.35 extern int mem_a20_alt; 31.36 extern int mem_a20_key; 31.37 void mem_a20_recalc(); 31.38 31.39 -uint8_t mem_read_ram(uint32_t addr); 31.40 -uint16_t mem_read_ramw(uint32_t addr); 31.41 -uint32_t mem_read_raml(uint32_t addr); 31.42 +uint8_t mem_read_ram(uint32_t addr, void *priv); 31.43 +uint16_t mem_read_ramw(uint32_t addr, void *priv); 31.44 +uint32_t mem_read_raml(uint32_t addr, void *priv); 31.45 31.46 -void mem_write_ram(uint32_t addr, uint8_t val); 31.47 -void mem_write_ramw(uint32_t addr, uint16_t val); 31.48 -void mem_write_raml(uint32_t addr, uint32_t val); 31.49 +void mem_write_ram(uint32_t addr, uint8_t val, void *priv); 31.50 +void mem_write_ramw(uint32_t addr, uint16_t val, void *priv); 31.51 +void mem_write_raml(uint32_t addr, uint32_t val, void *priv); 31.52 31.53 -uint8_t mem_read_bios(uint32_t addr); 31.54 -uint16_t mem_read_biosw(uint32_t addr); 31.55 -uint32_t mem_read_biosl(uint32_t addr); 31.56 +uint8_t mem_read_bios(uint32_t addr, void *priv); 31.57 +uint16_t mem_read_biosw(uint32_t addr, void *priv); 31.58 +uint32_t mem_read_biosl(uint32_t addr, void *priv); 31.59 31.60 FILE *romfopen(char *fn, char *mode); 31.61 + 31.62 +int mem_load_video_bios();
32.1 --- a/src/model.c Sun Apr 21 14:54:35 2013 +0100 32.2 +++ b/src/model.c Mon May 27 17:46:42 2013 +0100 32.3 @@ -6,14 +6,17 @@ 32.4 #include "acer386sx.h" 32.5 #include "ali1429.h" 32.6 #include "amstrad.h" 32.7 +#include "device.h" 32.8 #include "dma.h" 32.9 #include "fdc.h" 32.10 #include "headland.h" 32.11 +#include "i430vx.h" 32.12 #include "ide.h" 32.13 #include "jim.h" 32.14 -#include "keyboard_xt.h" 32.15 +#include "keyboard_amstrad.h" 32.16 #include "keyboard_at.h" 32.17 #include "keyboard_olim24.h" 32.18 +#include "keyboard_xt.h" 32.19 #include "lpt.h" 32.20 #include "mouse_ps2.h" 32.21 #include "mouse_serial.h" 32.22 @@ -22,9 +25,11 @@ 32.23 #include "olivetti_m24.h" 32.24 #include "pci.h" 32.25 #include "pic.h" 32.26 +#include "piix.h" 32.27 #include "pit.h" 32.28 -#include "psg.h" 32.29 #include "serial.h" 32.30 +#include "sound_sn76489.h" 32.31 +#include "um8669f.h" 32.32 #include "um8881f.h" 32.33 #include "wd76c10.h" 32.34 #include "xtide.h" 32.35 @@ -41,33 +46,35 @@ 32.36 void at_ali1429_init(); 32.37 void at_headland_init(); 32.38 void at_um8881f_init(); 32.39 +void at_i430vx_init(); 32.40 32.41 int model; 32.42 32.43 MODEL models[] = 32.44 { 32.45 - {"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init}, 32.46 - {"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init}, 32.47 - {"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init}, 32.48 - {"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init}, 32.49 - {"Tandy 1000", ROM_TANDY, { "", cpus_8088, "", NULL, "", NULL}, 1, tandy1k_init}, 32.50 - {"Amstrad PC1512", ROM_PC1512, { "", cpus_pc1512,"", NULL, "", NULL}, 1, ams_init}, 32.51 - {"Sinclair PC200", ROM_PC200, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init}, 32.52 - {"Euro PC", ROM_EUROPC, { "", cpus_8086, "", NULL, "", NULL}, 0, europc_init}, 32.53 - {"Olivetti M24", ROM_OLIM24, { "", cpus_8086, "", NULL, "", NULL}, 1, olim24_init}, 32.54 - {"Amstrad PC1640", ROM_PC1640, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init}, 32.55 - {"Amstrad PC2086", ROM_PC2086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init}, 32.56 - {"Amstrad PC3086", ROM_PC3086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init}, 32.57 - {"IBM AT", ROM_IBMAT, { "", cpus_ibmat, "", NULL, "", NULL}, 0, at_init}, 32.58 - {"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, at_init}, 32.59 - {"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, at_neat_init}, 32.60 - {"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, at_init}, 32.61 - {"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, at_acer386sx_init}, 32.62 - {"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, at_wd76c10_init}, 32.63 - {"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, at_headland_init}, 32.64 - {"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init}, 32.65 - {"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init}, 32.66 - {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_um8881f_init}, 32.67 + {"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init}, 32.68 + {"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init}, 32.69 + {"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init}, 32.70 + {"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, xt_init}, 32.71 + {"Tandy 1000", ROM_TANDY, { "", cpus_8088, "", NULL, "", NULL}, 1, tandy1k_init}, 32.72 + {"Amstrad PC1512", ROM_PC1512, { "", cpus_pc1512, "", NULL, "", NULL}, 1, ams_init}, 32.73 + {"Sinclair PC200", ROM_PC200, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init}, 32.74 + {"Euro PC", ROM_EUROPC, { "", cpus_8086, "", NULL, "", NULL}, 0, europc_init}, 32.75 + {"Olivetti M24", ROM_OLIM24, { "", cpus_8086, "", NULL, "", NULL}, 1, olim24_init}, 32.76 + {"Amstrad PC1640", ROM_PC1640, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init}, 32.77 + {"Amstrad PC2086", ROM_PC2086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init}, 32.78 + {"Amstrad PC3086", ROM_PC3086, { "", cpus_8086, "", NULL, "", NULL}, 1, ams_init}, 32.79 + {"IBM AT", ROM_IBMAT, { "", cpus_ibmat, "", NULL, "", NULL}, 0, at_init}, 32.80 + {"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, at_init}, 32.81 + {"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, at_neat_init}, 32.82 + {"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, at_init}, 32.83 + {"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, at_acer386sx_init}, 32.84 + {"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, at_wd76c10_init}, 32.85 + {"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, at_headland_init}, 32.86 + {"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init}, 32.87 + {"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_ali1429_init}, 32.88 + {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, at_um8881f_init}, 32.89 + {"Award 430VX PCI", ROM_430VX, { "IDT", cpus_WinChip, "", NULL, "", NULL}, 0, at_i430vx_init}, 32.90 {"", -1, {"", 0, "", 0, "", 0}, 0} 32.91 }; 32.92 32.93 @@ -84,7 +91,7 @@ 32.94 void common_init() 32.95 { 32.96 dma_init(); 32.97 - fdc_init(); 32.98 + fdc_add(); 32.99 lpt_init(); 32.100 pic_init(); 32.101 pit_init(); 32.102 @@ -105,7 +112,7 @@ 32.103 common_init(); 32.104 keyboard_xt_init(); 32.105 mouse_serial_init(); 32.106 - psg_init(); 32.107 + device_add(&sn76489_device); 32.108 xtide_init(); 32.109 } 32.110 32.111 @@ -191,6 +198,16 @@ 32.112 um8881f_init(); 32.113 } 32.114 32.115 +void at_i430vx_init() 32.116 +{ 32.117 + at_init(); 32.118 + mouse_serial_init(); 32.119 + pci_init(); 32.120 + i430vx_init(); 32.121 + piix_init(7); 32.122 + um8669f_init(); 32.123 +} 32.124 + 32.125 void model_init() 32.126 { 32.127 pclog("Initting as %s\n", model_getname());
33.1 --- a/src/model.h Sun Apr 21 14:54:35 2013 +0100 33.2 +++ b/src/model.h Mon May 27 17:46:42 2013 +0100 33.3 @@ -14,3 +14,7 @@ 33.4 extern MODEL models[]; 33.5 33.6 extern int model; 33.7 + 33.8 +int model_getromset(); 33.9 +char *model_getname(); 33.10 +void model_init();
34.1 --- a/src/mouse_serial.c Sun Apr 21 14:54:35 2013 +0100 34.2 +++ b/src/mouse_serial.c Mon May 27 17:46:42 2013 +0100 34.3 @@ -1,6 +1,8 @@ 34.4 #include "ibm.h" 34.5 #include "mouse.h" 34.6 +#include "pic.h" 34.7 #include "serial.h" 34.8 +#include "timer.h" 34.9 34.10 static int oldb=0; 34.11 34.12 @@ -37,11 +39,12 @@ 34.13 void mouse_serial_rcr() 34.14 { 34.15 mousepos=-1; 34.16 - mousedelay=1000; 34.17 + mousedelay=5000 * (1 << TIMER_SHIFT); 34.18 } 34.19 34.20 void mousecallback() 34.21 { 34.22 + mousedelay = 0; 34.23 if (mousepos == -1) 34.24 { 34.25 mousepos = 0; 34.26 @@ -62,5 +65,6 @@ 34.27 { 34.28 mouse_poll = mouse_serial_poll; 34.29 serial_rcr = mouse_serial_rcr; 34.30 + timer_add(mousecallback, &mousedelay, &mousedelay, NULL); 34.31 } 34.32
35.1 --- a/src/neat.c Sun Apr 21 14:54:35 2013 +0100 35.2 +++ b/src/neat.c Mon May 27 17:46:42 2013 +0100 35.3 @@ -7,7 +7,7 @@ 35.4 static int neat_index; 35.5 static int neat_emspage[4]; 35.6 35.7 -void neat_write(uint16_t port, uint8_t val) 35.8 +void neat_write(uint16_t port, uint8_t val, void *priv) 35.9 { 35.10 switch (port) 35.11 { 35.12 @@ -35,7 +35,7 @@ 35.13 } 35.14 } 35.15 35.16 -uint8_t neat_read(uint16_t port) 35.17 +uint8_t neat_read(uint16_t port, void *priv) 35.18 { 35.19 switch (port) 35.20 { 35.21 @@ -60,9 +60,9 @@ 35.22 35.23 void neat_init() 35.24 { 35.25 - io_sethandler(0x0022, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL); 35.26 - io_sethandler(0x0208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL); 35.27 - io_sethandler(0x4208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL); 35.28 - io_sethandler(0x8208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL); 35.29 - io_sethandler(0xc208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL); 35.30 + io_sethandler(0x0022, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); 35.31 + io_sethandler(0x0208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); 35.32 + io_sethandler(0x4208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); 35.33 + io_sethandler(0x8208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); 35.34 + io_sethandler(0xc208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); 35.35 }
36.1 --- a/src/nvr.c Sun Apr 21 14:54:35 2013 +0100 36.2 +++ b/src/nvr.c Mon May 27 17:46:42 2013 +0100 36.3 @@ -1,7 +1,10 @@ 36.4 #include <stdio.h> 36.5 #include <windows.h> 36.6 #include "ibm.h" 36.7 +#include "io.h" 36.8 #include "nvr.h" 36.9 +#include "pic.h" 36.10 +#include "timer.h" 36.11 36.12 int oldromset; 36.13 int nvrmask=63; 36.14 @@ -10,6 +13,8 @@ 36.15 36.16 SYSTEMTIME systemtime; 36.17 36.18 +int nvr_dosave = 0; 36.19 + 36.20 void getnvrtime() 36.21 { 36.22 int c,d; 36.23 @@ -51,9 +56,9 @@ 36.24 void nvr_recalc() 36.25 { 36.26 int c; 36.27 - float newrtctime; 36.28 + int newrtctime; 36.29 c=1<<((nvrram[0xA]&0xF)-1); 36.30 - newrtctime=RTCCONST*(float)c; 36.31 + newrtctime=(int)(RTCCONST * c * (1 << TIMER_SHIFT)); 36.32 if (rtctime>newrtctime) rtctime=newrtctime; 36.33 } 36.34 36.35 @@ -62,11 +67,11 @@ 36.36 int c; 36.37 if (!(nvrram[0xA]&0xF)) 36.38 { 36.39 - rtctime=99999999; 36.40 + rtctime=0x7fffffff; 36.41 return; 36.42 } 36.43 c=1<<((nvrram[0xA]&0xF)-1); 36.44 - rtctime+=RTCCONST*(float)c; 36.45 + rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); 36.46 // pclog("RTCtime now %f\n",rtctime); 36.47 nvrram[0xC]=0x40; 36.48 if (nvrram[0xB]&0x40) 36.49 @@ -78,7 +83,7 @@ 36.50 } 36.51 } 36.52 36.53 -void writenvr(uint16_t addr, uint8_t val) 36.54 +void writenvr(uint16_t addr, uint8_t val, void *priv) 36.55 { 36.56 int c; 36.57 // printf("Write NVR %03X %02X %02X %04X:%04X %i\n",addr,nvraddr,val,cs>>4,pc,ins); 36.58 @@ -86,7 +91,7 @@ 36.59 { 36.60 // if (nvraddr == 0x33) pclog("NVRWRITE33 %02X %04X:%04X %i\n",val,CS,pc,ins); 36.61 if (nvraddr >= 0xe && nvrram[nvraddr] != val) 36.62 - savenvr(); 36.63 + nvr_dosave = 1; 36.64 if (nvraddr!=0xC && nvraddr!=0xD) nvrram[nvraddr]=val; 36.65 36.66 if (nvraddr==0xA) 36.67 @@ -95,16 +100,16 @@ 36.68 if (val&0xF) 36.69 { 36.70 c=1<<((val&0xF)-1); 36.71 - rtctime+=RTCCONST*(float)c; 36.72 + rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); 36.73 } 36.74 else 36.75 - rtctime=99999999; 36.76 + rtctime = 0x7fffffff; 36.77 } 36.78 } 36.79 else nvraddr=val&nvrmask; 36.80 } 36.81 36.82 -uint8_t readnvr(uint16_t addr) 36.83 +uint8_t readnvr(uint16_t addr, void *priv) 36.84 { 36.85 uint8_t temp; 36.86 // printf("Read NVR %03X %02X %02X %04X:%04X\n",addr,nvraddr,nvrram[nvraddr],cs>>4,pc); 36.87 @@ -157,6 +162,7 @@ 36.88 case ROM_AMI486: f = romfopen("ami486.nvr", "rb"); nvrmask = 127; break; 36.89 case ROM_WIN486: f = romfopen("win486.nvr", "rb"); nvrmask = 127; break; 36.90 case ROM_PCI486: f = romfopen("hot-433.nvr", "rb"); nvrmask = 127; break; 36.91 + case ROM_430VX: f = romfopen("hot-433.nvr", "rb"); nvrmask = 127; break; 36.92 default: return; 36.93 } 36.94 if (!f) 36.95 @@ -169,7 +175,7 @@ 36.96 nvrram[0xA]=6; 36.97 nvrram[0xB]=0; 36.98 c=1<<((6&0xF)-1); 36.99 - rtctime+=RTCCONST*(float)c; 36.100 + rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); 36.101 } 36.102 void savenvr() 36.103 { 36.104 @@ -178,7 +184,7 @@ 36.105 { 36.106 case ROM_PC1512: f = romfopen("pc1512.nvr" , "wb"); break; 36.107 case ROM_PC1640: f = romfopen("pc1640.nvr" , "wb"); break; 36.108 - case ROM_PC200: f = romfopen("pc200.nvr" , "wb"); break; 36.109 + case ROM_PC200: f = romfopen("pc200.nvr" , "wb"); break; 36.110 case ROM_PC2086: f = romfopen("pc2086.nvr" , "wb"); break; 36.111 case ROM_PC3086: f = romfopen("pc3086.nvr" , "wb"); break; 36.112 case ROM_IBMAT: f = romfopen("at.nvr" , "wb"); break; 36.113 @@ -192,6 +198,7 @@ 36.114 case ROM_AMI486: f = romfopen("ami486.nvr" , "wb"); break; 36.115 case ROM_WIN486: f = romfopen("win486.nvr" , "wb"); break; 36.116 case ROM_PCI486: f = romfopen("hot-433.nvr", "wb"); break; 36.117 + case ROM_430VX: f = romfopen("hot-433.nvr", "wb"); break; 36.118 default: return; 36.119 } 36.120 fwrite(nvrram,128,1,f); 36.121 @@ -200,5 +207,6 @@ 36.122 36.123 void nvr_init() 36.124 { 36.125 - io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL); 36.126 + io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, NULL); 36.127 + timer_add(nvr_rtc, &rtctime, TIMER_ALWAYS_ENABLED, NULL); 36.128 }
37.1 --- a/src/nvr.h Sun Apr 21 14:54:35 2013 +0100 37.2 +++ b/src/nvr.h Mon May 27 17:46:42 2013 +0100 37.3 @@ -1,1 +1,3 @@ 37.4 void nvr_init(); 37.5 + 37.6 +extern int nvr_dosave;
38.1 --- a/src/olivetti_m24.c Sun Apr 21 14:54:35 2013 +0100 38.2 +++ b/src/olivetti_m24.c Mon May 27 17:46:42 2013 +0100 38.3 @@ -2,7 +2,7 @@ 38.4 #include "io.h" 38.5 #include "olivetti_m24.h" 38.6 38.7 -uint8_t olivetti_m24_read(uint16_t port) 38.8 +uint8_t olivetti_m24_read(uint16_t port, void *priv) 38.9 { 38.10 switch (port) 38.11 { 38.12 @@ -16,5 +16,5 @@ 38.13 38.14 void olivetti_m24_init() 38.15 { 38.16 - io_sethandler(0x0066, 0x0002, olivetti_m24_read, NULL, NULL, NULL, NULL, NULL); 38.17 + io_sethandler(0x0066, 0x0002, olivetti_m24_read, NULL, NULL, NULL, NULL, NULL, NULL); 38.18 }
39.1 --- a/src/pc.c Sun Apr 21 14:54:35 2013 +0100 39.2 +++ b/src/pc.c Mon May 27 17:46:42 2013 +0100 39.3 @@ -1,19 +1,36 @@ 39.4 #include <stdio.h> 39.5 +#include <stdlib.h> 39.6 #include <stdarg.h> 39.7 #include "ibm.h" 39.8 -#include "video.h" 39.9 +#include "device.h" 39.10 + 39.11 +#include "ali1429.h" 39.12 #include "amstrad.h" 39.13 +#include "cdrom-ioctl.h" 39.14 +#include "config.h" 39.15 +#include "cpu.h" 39.16 #include "dma.h" 39.17 +#include "fdc.h" 39.18 +#include "sound_gus.h" 39.19 +#include "ide.h" 39.20 +#include "keyboard.h" 39.21 #include "mem.h" 39.22 -#include "ide.h" 39.23 +#include "model.h" 39.24 #include "mouse.h" 39.25 +#include "nvr.h" 39.26 #include "pic.h" 39.27 #include "pit.h" 39.28 +#include "plat-mouse.h" 39.29 #include "serial.h" 39.30 -#include "cdrom-ioctl.h" 39.31 -#include "cpu.h" 39.32 -#include "model.h" 39.33 -#include "plat-mouse.h" 39.34 +#include "sound.h" 39.35 +#include "sound_cms.h" 39.36 +#include "sound_opl.h" 39.37 +#include "sound_sb.h" 39.38 +#include "timer.h" 39.39 +#include "vid_voodoo.h" 39.40 +#include "video.h" 39.41 + 39.42 +int frame = 0; 39.43 39.44 int cdrom_enabled; 39.45 int CPUID; 39.46 @@ -42,8 +59,8 @@ 39.47 FILE *pclogf; 39.48 void pclog(const char *format, ...) 39.49 { 39.50 - char buf[256]; 39.51 - return; 39.52 + char buf[1024]; 39.53 + //return; 39.54 if (!pclogf) 39.55 pclogf=fopen("pclog.txt","wt"); 39.56 //return; 39.57 @@ -79,6 +96,7 @@ 39.58 void pollmouse() 39.59 { 39.60 int x,y; 39.61 +// return; 39.62 pollmouse_delay--; 39.63 if (pollmouse_delay) return; 39.64 pollmouse_delay = 2; 39.65 @@ -149,6 +167,7 @@ 39.66 { 39.67 resetx86(); 39.68 cpu_set(); 39.69 + //timer_reset(); 39.70 dma_reset(); 39.71 fdc_reset(); 39.72 pic_reset(); 39.73 @@ -157,8 +176,7 @@ 39.74 39.75 setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); 39.76 39.77 - adlib_reset(); 39.78 - sb_reset(); 39.79 +// sb_reset(); 39.80 39.81 ali1429_reset(); 39.82 et4000w32_reset(); 39.83 @@ -185,31 +203,39 @@ 39.84 cpuspeed2=(AT)?2:1; 39.85 // cpuspeed2=cpuspeed; 39.86 atfullspeed=0; 39.87 - 39.88 + 39.89 + device_init(); 39.90 pclog("Initvideo\n"); 39.91 39.92 initvideo(); 39.93 mem_init(); 39.94 loadbios(); 39.95 + mem_load_video_bios(); 39.96 39.97 loaddisc(0,discfns[0]); 39.98 loaddisc(1,discfns[1]); 39.99 + 39.100 + timer_reset(); 39.101 + sound_reset(); 39.102 + fdc_init(); 39.103 + 39.104 //loadfont(); 39.105 loadnvr(); 39.106 resetvideo(); 39.107 - initsound(); 39.108 - initpsg(); 39.109 + sound_init(); 39.110 inithdc(); 39.111 initega(); 39.112 - initgus(); 39.113 resetide(); 39.114 ioctl_open(cdrom_drive); 39.115 model_init(); 39.116 video_init(); 39.117 - adlib_init(); 39.118 - sb_init(); 39.119 - gus_init(); 39.120 - 39.121 + speaker_init(); 39.122 + sound_card_init(sound_card_current); 39.123 + if (GUS) 39.124 + device_add(&gus_device); 39.125 + if (GAMEBLASTER) 39.126 + device_add(&cms_device); 39.127 + 39.128 pc_reset(); 39.129 39.130 pit_reset(); 39.131 @@ -222,7 +248,7 @@ 39.132 // CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9)); 39.133 // pclog("Init - CPUID %i %i\n",CPUID,cpuspeed); 39.134 shadowbios=0; 39.135 - 39.136 + voodoo_init(); 39.137 } 39.138 39.139 void resetpc() 39.140 @@ -236,13 +262,22 @@ 39.141 39.142 void resetpchard() 39.143 { 39.144 + device_close_all(); 39.145 + device_init(); 39.146 + 39.147 + timer_reset(); 39.148 + sound_reset(); 39.149 mem_resize(); 39.150 + fdc_init(); 39.151 model_init(); 39.152 pclog("Video_init\n"); 39.153 video_init(); 39.154 - adlib_init(); 39.155 - sb_init(); 39.156 - gus_init(); 39.157 + speaker_init(); 39.158 + sound_card_init(sound_card_current); 39.159 + if (GUS) 39.160 + device_add(&gus_device); 39.161 + if (GAMEBLASTER) 39.162 + device_add(&cms_device); 39.163 39.164 pc_reset(); 39.165 39.166 @@ -278,14 +313,14 @@ 39.167 int serial_fifo_read, serial_fifo_write; 39.168 39.169 int emu_fps = 0; 39.170 - 39.171 +extern int totaldiff; 39.172 void runpc() 39.173 { 39.174 char s[200]; 39.175 int done=0; 39.176 clockrate = models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed; 39.177 if (is386) exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); 39.178 - else if (AT) exec286(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); 39.179 + else if (AT) exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); 39.180 else execx86(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); 39.181 keyboard_poll_host(); 39.182 keyboard_process(); 39.183 @@ -320,10 +355,12 @@ 39.184 if (win_title_update) 39.185 { 39.186 win_title_update=0; 39.187 - sprintf(s, "PCem v0.7 - %s - %s - %s - %i%% %i %04X %i", model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : "Press CTRL-END to release mouse", fps, et4000w32p_getclock(), ECX, ins); 39.188 + sprintf(s, "PCem v0.7 - %s - %s - %s - %i%% - %i", model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : "Press CTRL-END to release mouse", fps, totaldiff); 39.189 + totaldiff = 0; 39.190 set_window_title(s); 39.191 } 39.192 done++; 39.193 + frame++; 39.194 /* if ((at70hz && VGA)!=oldat70hz) 39.195 { 39.196 oldat70hz=(at70hz && VGA); 39.197 @@ -369,7 +406,6 @@ 39.198 // ioctl_close(); 39.199 dumpegaregs(); 39.200 dumppic(); 39.201 - dumpgus(); 39.202 // output=7; 39.203 // setpitclock(clocks[0][0][0]); 39.204 // while (1) runpc(); 39.205 @@ -377,6 +413,7 @@ 39.206 savedisc(1); 39.207 dumpregs(); 39.208 closevideo(); 39.209 + device_close_all(); 39.210 } 39.211 39.212 /*int main() 39.213 @@ -398,94 +435,86 @@ 39.214 { 39.215 char s[512]; 39.216 char *p; 39.217 - append_filename(s,pcempath,"pcem.cfg",511); 39.218 + append_filename(s, pcempath, "pcem.cfg", 511); 39.219 set_config_file(s); 39.220 - ADLIB=get_config_int(NULL,"adlib",1); 39.221 - GAMEBLASTER=get_config_int(NULL,"gameblaster",0); 39.222 - FASTDISC=get_config_int(NULL,"fast_disc",1); 39.223 + GAMEBLASTER = get_config_int(NULL, "gameblaster", 0); 39.224 + GUS = get_config_int(NULL, "gus", 0); 39.225 39.226 model = get_config_int(NULL, "model", 14); 39.227 - pclog("Model %i\n", model); 39.228 + 39.229 romset = model_getromset(); 39.230 cpu_manufacturer = get_config_int(NULL, "cpu_manufacturer", 0); 39.231 cpu = get_config_int(NULL, "cpu", 0); 39.232 39.233 - gfxcard=get_config_int(NULL,"gfxcard",0); 39.234 + gfxcard = get_config_int(NULL, "gfxcard", 0); 39.235 video_speed = get_config_int(NULL, "video_speed", 3); 39.236 - sbtype=get_config_int(NULL,"sndcard",SB2); 39.237 - pclog("Model1 %i\n", model); 39.238 - p=(char *)get_config_string(NULL,"disc_a",""); 39.239 - if (p) strcpy(discfns[0],p); 39.240 - else strcpy(discfns[0],""); 39.241 - pclog("Model2 %i\n", model); 39.242 - p=(char *)get_config_string(NULL,"disc_b",""); 39.243 - if (p) strcpy(discfns[1],p); 39.244 - else strcpy(discfns[1],""); 39.245 - pclog("Model3 %i\n", model); 39.246 - mem_size=get_config_int(NULL,"mem_size",4); 39.247 - cdrom_drive=get_config_int(NULL,"cdrom_drive",0); 39.248 - cdrom_enabled=get_config_int(NULL,"cdrom_enabled",0); 39.249 + sound_card_current = get_config_int(NULL, "sndcard", SB2); 39.250 + 39.251 + p = (char *)get_config_string(NULL, "disc_a", ""); 39.252 + if (p) strcpy(discfns[0], p); 39.253 + else strcpy(discfns[0], ""); 39.254 + 39.255 + p = (char *)get_config_string(NULL, "disc_b", ""); 39.256 + if (p) strcpy(discfns[1], p); 39.257 + else strcpy(discfns[1], ""); 39.258 + 39.259 + mem_size = get_config_int(NULL, "mem_size", 4); 39.260 + cdrom_drive = get_config_int(NULL, "cdrom_drive", 0); 39.261 + cdrom_enabled = get_config_int(NULL, "cdrom_enabled", 0); 39.262 39.263 - slowega=get_config_int(NULL,"slow_video",1); 39.264 - cache=get_config_int(NULL,"cache",3); 39.265 - cga_comp=get_config_int(NULL,"cga_composite",0); 39.266 + slowega = get_config_int(NULL, "slow_video", 1); 39.267 + cache = get_config_int(NULL, "cache", 3); 39.268 + cga_comp = get_config_int(NULL, "cga_composite", 0); 39.269 39.270 - kb_win=get_config_int(NULL,"kb_win",0); 39.271 - vid_resize=get_config_int(NULL,"vid_resize",0); 39.272 -// cpuspeed=2; 39.273 + kb_win = get_config_int(NULL, "kb_win", 0); 39.274 + vid_resize = get_config_int(NULL, "vid_resize", 0); 39.275 39.276 - hdc[0].spt=get_config_int(NULL,"hdc_sectors",0); 39.277 - hdc[0].hpc=get_config_int(NULL,"hdc_heads",0); 39.278 - hdc[0].tracks=get_config_int(NULL,"hdc_cylinders",0); 39.279 + hdc[0].spt = get_config_int(NULL, "hdc_sectors", 0); 39.280 + hdc[0].hpc = get_config_int(NULL, "hdc_heads", 0); 39.281 + hdc[0].tracks = get_config_int(NULL, "hdc_cylinders", 0); 39.282 p = (char *)get_config_string(NULL, "hdc_fn", ""); 39.283 if (p) strcpy(ide_fn[0], p); 39.284 else strcpy(ide_fn[0], ""); 39.285 - hdc[1].spt=get_config_int(NULL,"hdd_sectors",0); 39.286 - hdc[1].hpc=get_config_int(NULL,"hdd_heads",0); 39.287 - hdc[1].tracks=get_config_int(NULL,"hdd_cylinders",0); 39.288 + hdc[1].spt = get_config_int(NULL, "hdd_sectors", 0); 39.289 + hdc[1].hpc = get_config_int(NULL, "hdd_heads", 0); 39.290 + hdc[1].tracks = get_config_int(NULL, "hdd_cylinders", 0); 39.291 p = (char *)get_config_string(NULL, "hdd_fn", ""); 39.292 if (p) strcpy(ide_fn[1], p); 39.293 else strcpy(ide_fn[1], ""); 39.294 - pclog("Model4 %i\n", model); 39.295 } 39.296 39.297 void saveconfig() 39.298 { 39.299 - pclog("saveconfig\n"); 39.300 config_new(); 39.301 - pclog("config_new\n"); 39.302 - set_config_int(NULL,"adlib",ADLIB); 39.303 - pclog("sci 1\n"); 39.304 - set_config_int(NULL,"gameblaster",GAMEBLASTER); 39.305 - set_config_int(NULL,"fast_disc",FASTDISC); 39.306 + set_config_int(NULL, "gameblaster", GAMEBLASTER); 39.307 + set_config_int(NULL, "gus", GUS); 39.308 39.309 set_config_int(NULL, "model", model); 39.310 set_config_int(NULL, "cpu_manufacturer", cpu_manufacturer); 39.311 set_config_int(NULL, "cpu", cpu); 39.312 39.313 - set_config_int(NULL,"gfxcard",gfxcard); 39.314 - set_config_int(NULL,"video_speed", video_speed); 39.315 - set_config_int(NULL,"sndcard",sbtype); 39.316 - set_config_int(NULL,"cpu_speed",cpuspeed); 39.317 - set_config_int(NULL,"has_fpu",hasfpu); 39.318 - set_config_int(NULL,"slow_video",slowega); 39.319 - set_config_int(NULL,"cache",cache); 39.320 - set_config_int(NULL,"cga_composite",cga_comp); 39.321 - set_config_string(NULL,"disc_a",discfns[0]); 39.322 - set_config_string(NULL,"disc_b",discfns[1]); 39.323 - set_config_int(NULL,"mem_size",mem_size); 39.324 - set_config_int(NULL,"cdrom_drive",cdrom_drive); 39.325 - set_config_int(NULL,"cdrom_enabled",cdrom_enabled); 39.326 - set_config_int(NULL,"kb_win",kb_win); 39.327 - set_config_int(NULL,"vid_resize",vid_resize); 39.328 + set_config_int(NULL, "gfxcard", gfxcard); 39.329 + set_config_int(NULL, "video_speed", video_speed); 39.330 + set_config_int(NULL, "sndcard", sound_card_current); 39.331 + set_config_int(NULL, "cpu_speed", cpuspeed); 39.332 + set_config_int(NULL, "has_fpu", hasfpu); 39.333 + set_config_int(NULL, "slow_video", slowega); 39.334 + set_config_int(NULL, "cache", cache); 39.335 + set_config_int(NULL, "cga_composite", cga_comp); 39.336 + set_config_string(NULL, "disc_a", discfns[0]); 39.337 + set_config_string(NULL, "disc_b", discfns[1]); 39.338 + set_config_int(NULL, "mem_size", mem_size); 39.339 + set_config_int(NULL, "cdrom_drive", cdrom_drive); 39.340 + set_config_int(NULL, "cdrom_enabled", cdrom_enabled); 39.341 + set_config_int(NULL, "kb_win", kb_win); 39.342 + set_config_int(NULL, "vid_resize", vid_resize); 39.343 39.344 - set_config_int(NULL,"hdc_sectors",hdc[0].spt); 39.345 - set_config_int(NULL,"hdc_heads",hdc[0].hpc); 39.346 - set_config_int(NULL,"hdc_cylinders",hdc[0].tracks); 39.347 + set_config_int(NULL, "hdc_sectors", hdc[0].spt); 39.348 + set_config_int(NULL, "hdc_heads", hdc[0].hpc); 39.349 + set_config_int(NULL, "hdc_cylinders", hdc[0].tracks); 39.350 set_config_string(NULL, "hdc_fn", ide_fn[0]); 39.351 - set_config_int(NULL,"hdd_sectors",hdc[1].spt); 39.352 - set_config_int(NULL,"hdd_heads",hdc[1].hpc); 39.353 - set_config_int(NULL,"hdd_cylinders",hdc[1].tracks); 39.354 + set_config_int(NULL, "hdd_sectors", hdc[1].spt); 39.355 + set_config_int(NULL, "hdd_heads", hdc[1].hpc); 39.356 + set_config_int(NULL, "hdd_cylinders", hdc[1].tracks); 39.357 set_config_string(NULL, "hdd_fn", ide_fn[1]); 39.358 - pclog("saveconfig done\n"); 39.359 }
40.1 --- a/src/pci.c Sun Apr 21 14:54:35 2013 +0100 40.2 +++ b/src/pci.c Mon May 27 17:46:42 2013 +0100 40.3 @@ -4,13 +4,12 @@ 40.4 40.5 #include "pci.h" 40.6 40.7 -void (*pci_card_write[32])(int func, int addr, uint8_t val); 40.8 -uint8_t (*pci_card_read[32])(int func, int addr); 40.9 +void (*pci_card_write[32])(int func, int addr, uint8_t val, void *priv); 40.10 +uint8_t (*pci_card_read[32])(int func, int addr, void *priv); 40.11 +void *pci_priv[32]; 40.12 static int pci_index, pci_func, pci_card, pci_bus, pci_enable; 40.13 -static uint8_t card_16[256]; 40.14 -static uint8_t card_18[256]; 40.15 40.16 -void pci_write(uint16_t port, uint8_t val) 40.17 +void pci_write(uint16_t port, uint8_t val, void *priv) 40.18 { 40.19 switch (port) 40.20 { 40.21 @@ -32,16 +31,16 @@ 40.22 if (!pci_enable) 40.23 return; 40.24 40.25 - pclog("PCI write bus %i card %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_index | (port & 3), val, CS, pc); 40.26 +// pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, pc); 40.27 40.28 if (!pci_bus && pci_card_write[pci_card]) 40.29 - pci_card_write[pci_card](pci_func, pci_index | (port & 3), val); 40.30 + pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); 40.31 40.32 break; 40.33 } 40.34 } 40.35 40.36 -uint8_t pci_read(uint16_t port) 40.37 +uint8_t pci_read(uint16_t port, void *priv) 40.38 { 40.39 switch (port) 40.40 { 40.41 @@ -58,10 +57,10 @@ 40.42 if (!pci_enable) 40.43 return 0xff; 40.44 40.45 - pclog("PCI read bus %i card %i index %02X\n", pci_bus, pci_card, pci_index | (port & 3)); 40.46 +// pclog("PCI read bus %i card %i func %i index %02X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3)); 40.47 40.48 if (!pci_bus && pci_card_read[pci_card]) 40.49 - return pci_card_read[pci_card](pci_func, pci_index | (port & 3)); 40.50 + return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); 40.51 40.52 return 0xff; 40.53 } 40.54 @@ -71,19 +70,20 @@ 40.55 { 40.56 int c; 40.57 40.58 - io_sethandler(0x0cf8, 0x0008, pci_read, NULL, NULL, pci_write, NULL, NULL); 40.59 + io_sethandler(0x0cf8, 0x0008, pci_read, NULL, NULL, pci_write, NULL, NULL, NULL); 40.60 40.61 for (c = 0; c < 32; c++) 40.62 - pci_card_read[c] = pci_card_write[c] = NULL; 40.63 + pci_card_read[c] = pci_card_write[c] = pci_priv[c] = NULL; 40.64 } 40.65 40.66 -void pci_add_specific(int card, uint8_t (*read)(int func, int addr), void (*write)(int func, int addr, uint8_t val)) 40.67 +void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) 40.68 { 40.69 pci_card_read[card] = read; 40.70 pci_card_write[card] = write; 40.71 + pci_priv[card] = priv; 40.72 } 40.73 40.74 -void pci_add(uint8_t (*read)(int func, int addr), void (*write)(int func, int addr, uint8_t val)) 40.75 +void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) 40.76 { 40.77 int c; 40.78 40.79 @@ -93,6 +93,7 @@ 40.80 { 40.81 pci_card_read[c] = read; 40.82 pci_card_write[c] = write; 40.83 + pci_priv[c] = priv; 40.84 return; 40.85 } 40.86 }
41.1 --- a/src/pci.h Sun Apr 21 14:54:35 2013 +0100 41.2 +++ b/src/pci.h Mon May 27 17:46:42 2013 +0100 41.3 @@ -1,3 +1,3 @@ 41.4 void pci_init(); 41.5 -void pci_add_specific(int card, uint8_t (*read)(int func, int addr), void (*write)(int func, int addr, uint8_t val)); 41.6 -void pci_add(uint8_t (*read)(int func, int addr), void (*write)(int func, int addr, uint8_t val)); 41.7 +void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); 41.8 +void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
42.1 --- a/src/pic.c Sun Apr 21 14:54:35 2013 +0100 42.2 +++ b/src/pic.c Mon May 27 17:46:42 2013 +0100 42.3 @@ -1,14 +1,16 @@ 42.4 #include "ibm.h" 42.5 +#include "io.h" 42.6 +#include "pic.h" 42.7 42.8 int output; 42.9 int intclear; 42.10 int keywaiting=0; 42.11 -int pit0; 42.12 int pic_intpending; 42.13 42.14 void pic_updatepending() 42.15 { 42.16 pic_intpending = (((pic.pend&~pic.mask)&~pic.mask2) || ((pic2.pend&~pic2.mask)&~pic2.mask2)); 42.17 +// pclog("pic_intpending = %i %02X %02X %02X\n", pic_intpending, pic.pend, pic.mask, pic.mask2); 42.18 } 42.19 42.20 42.21 @@ -27,7 +29,7 @@ 42.22 pic_intpending = 0; 42.23 } 42.24 42.25 -void pic_write(uint16_t addr, uint8_t val) 42.26 +void pic_write(uint16_t addr, uint8_t val, void *priv) 42.27 { 42.28 int c; 42.29 // pclog("Write PIC %04X %02X %04X(%06X):%04X\n",addr,val,CS,cs,pc); 42.30 @@ -87,7 +89,6 @@ 42.31 pic.ins&=~(1<<c); 42.32 pic.mask2&=~(1<<c); 42.33 // pic.pend&=~(1<<c); 42.34 - if (c==0) pit0=1; 42.35 if (c==1 && keywaiting) 42.36 { 42.37 intclear&=~1; 42.38 @@ -109,20 +110,20 @@ 42.39 } 42.40 } 42.41 42.42 -uint8_t pic_read(uint16_t addr) 42.43 +uint8_t pic_read(uint16_t addr, void *priv) 42.44 { 42.45 if (addr&1) { /*pclog("Read PIC mask %02X\n",pic.mask);*/ return pic.mask; } 42.46 - if (pic.read) { /*pclog("Read PIC ins %02X\n",pic.ins);*/ return pic.ins; } 42.47 + if (pic.read) { /*pclog("Read PIC ins %02X\n",pic.ins);*/ return pic.ins | (pic2.ins ? 4 : 0); } 42.48 // pclog("Read PIC pend %02X %08X\n",pic.pend,EDX); 42.49 return pic.pend; 42.50 } 42.51 42.52 void pic_init() 42.53 { 42.54 - io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL); 42.55 + io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, NULL); 42.56 } 42.57 42.58 -void pic2_write(uint16_t addr, uint8_t val) 42.59 +void pic2_write(uint16_t addr, uint8_t val, void *priv) 42.60 { 42.61 int c; 42.62 // pclog("Write PIC2 %04X %02X %04X:%04X %i\n",addr,val,CS,pc,ins); 42.63 @@ -137,6 +138,7 @@ 42.64 break; 42.65 case 1: /*ICW2*/ 42.66 pic2.vector=val&0xF8; 42.67 +// pclog("PIC2 vector %02X\n", val & 0xf8); 42.68 if (pic2.icw1&2) pic2.icw=3; 42.69 else pic2.icw=2; 42.70 break; 42.71 @@ -188,17 +190,17 @@ 42.72 } 42.73 } 42.74 42.75 -uint8_t pic2_read(uint16_t addr) 42.76 +uint8_t pic2_read(uint16_t addr, void *priv) 42.77 { 42.78 if (addr&1) { /*pclog("Read PIC2 mask %02X %04X:%08X\n",pic2.mask,CS,pc); */return pic2.mask; } 42.79 if (pic2.read) { /*pclog("Read PIC2 ins %02X %04X:%08X\n",pic2.ins,CS,pc); */return pic2.ins; } 42.80 -// pclog("Read PIC2 pend %02X %04X:%08X\n",pic2.pend,CS,pc); 42.81 + /*pclog("Read PIC2 pend %02X %04X:%08X\n",pic2.pend,CS,pc);*/ 42.82 return pic2.pend; 42.83 } 42.84 42.85 void pic2_init() 42.86 { 42.87 - io_sethandler(0x00a0, 0x0002, pic2_read, NULL, NULL, pic2_write, NULL, NULL); 42.88 + io_sethandler(0x00a0, 0x0002, pic2_read, NULL, NULL, pic2_write, NULL, NULL, NULL); 42.89 } 42.90 42.91 42.92 @@ -213,6 +215,7 @@ 42.93 42.94 void picint(uint16_t num) 42.95 { 42.96 +// pclog("picint : %04X\n", num); 42.97 // if (num == 0x10) pclog("PICINT 10\n"); 42.98 if (num>0xFF) 42.99 { 42.100 @@ -222,6 +225,7 @@ 42.101 { 42.102 pic.pend|=num; 42.103 } 42.104 +// pclog("picint : PEND now %02X %02X\n", pic.pend, pic2.pend); 42.105 pic_updatepending(); 42.106 } 42.107 42.108 @@ -248,7 +252,7 @@ 42.109 { 42.110 int c = 0; 42.111 while (!(num & (1 << c))) c++; 42.112 -// pclog("INTC %04X %i\n", num, c); 42.113 + //pclog("INTC %04X %i\n", num, c); 42.114 pic_current[c]=0; 42.115 if (num>0xFF) pic2.pend&=~(num>>8); 42.116 else 42.117 @@ -270,6 +274,7 @@ 42.118 pic.mask2|=(1<<c); 42.119 42.120 pic_updatepending(); 42.121 +// pclog("picinterrupt : Taking PIC1 int %i\n", c); 42.122 // if (!c) pclog("Taking timer int\n"); 42.123 // if (c==5) printf("GUS IRQ!\n"); 42.124 // if (c==1) printf("Keyboard int!\n"); 42.125 @@ -277,6 +282,8 @@ 42.126 return c+pic.vector; 42.127 } 42.128 } 42.129 +/* if (pic.mask2 & 4) 42.130 + return 0xff;*/ 42.131 temp=pic2.pend&~pic2.mask; 42.132 for (c=0;c<8;c++) 42.133 { 42.134 @@ -286,6 +293,7 @@ 42.135 pic2.ins|=(1<<c); 42.136 pic2.mask2|=(1<<c); 42.137 pic_updatepending(); 42.138 + //pclog("Taking PIC2 int %i\n", c); 42.139 // if (c==(14-8)) pclog("Taking IRQ 14 %02X\n",c+pic2.vector); 42.140 // printf("Taking high IRQ! %i\n",c); 42.141 // if (c==1) printf("Keyboard int!\n"); 42.142 @@ -298,10 +306,9 @@ 42.143 42.144 void picclear(int num) 42.145 { 42.146 -// printf("Pic clear %02X\n",num); 42.147 +// pclog("Pic clear %02X\n",num); 42.148 pic.pend&=~num; 42.149 pic.ins&=~num; 42.150 - if (num==1) pit0=1; 42.151 pic_updatepending(); 42.152 } 42.153
43.1 --- a/src/pic.h Sun Apr 21 14:54:35 2013 +0100 43.2 +++ b/src/pic.h Mon May 27 17:46:42 2013 +0100 43.3 @@ -1,3 +1,9 @@ 43.4 void pic_init(); 43.5 void pic2_init(); 43.6 void pic_reset(); 43.7 + 43.8 +void picint(uint16_t num); 43.9 +void picintlevel(uint16_t num); 43.10 +void picintc(uint16_t num); 43.11 +uint8_t picinterrupt(); 43.12 +void picclear(int num);
44.1 --- a/src/pit.c Sun Apr 21 14:54:35 2013 +0100 44.2 +++ b/src/pit.c Mon May 27 17:46:42 2013 +0100 44.3 @@ -5,9 +5,15 @@ 44.4 44.5 #include <string.h> 44.6 #include "ibm.h" 44.7 + 44.8 +#include "cpu.h" 44.9 +#include "dma.h" 44.10 +#include "io.h" 44.11 +#include "pic.h" 44.12 #include "pit.h" 44.13 +#include "timer.h" 44.14 #include "video.h" 44.15 -#include "cpu.h" 44.16 + 44.17 /*B0 to 40, two writes to 43, then two reads - value does not change!*/ 44.18 /*B4 to 40, two writes to 43, then two reads - value _does_ change!*/ 44.19 //Tyrian writes 4300 or 17512 44.20 @@ -21,31 +27,25 @@ 44.21 int firsttime=1; 44.22 void setpitclock(float clock) 44.23 { 44.24 - float temp; 44.25 // printf("PIT clock %f\n",clock); 44.26 cpuclock=clock; 44.27 PITCONST=clock/1193182.0; 44.28 - SPKCONST=clock/48000.0; 44.29 CGACONST=(clock/(19687500.0/11.0)); 44.30 MDACONST=(clock/1813000.0); 44.31 VGACONST1=(clock/25175000.0); 44.32 VGACONST2=(clock/28322000.0); 44.33 - setsbclock(clock); 44.34 - SOUNDCONST=clock/200.0; 44.35 - CASCONST=PITCONST*1192; 44.36 isa_timing = clock/8000000.0; 44.37 bus_timing = clock/(double)cpu_busspeed; 44.38 video_updatetiming(); 44.39 // pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock); 44.40 - GUSCONST=(clock/3125.0)/4.0; 44.41 - GUSCONST2=(clock/3125.0)/4.0; //Timer 2 at different rate to 1? 44.42 video_recalctimings(); 44.43 RTCCONST=clock/32768.0; 44.44 + TIMER_USEC = (int)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT)); 44.45 + device_speed_changed(); 44.46 } 44.47 44.48 //#define PITCONST (8000000.0/1193000.0) 44.49 //#define PITCONST (cpuclock/1193000.0) 44.50 -int pit0; 44.51 void pit_reset() 44.52 { 44.53 memset(&pit,0,sizeof(PIT)); 44.54 @@ -69,12 +69,10 @@ 44.55 return 1193182.0f/(float)pit.l[0]; 44.56 } 44.57 extern int ins; 44.58 -void pit_write(uint16_t addr, uint8_t val) 44.59 +void pit_write(uint16_t addr, uint8_t val, void *priv) 44.60 { 44.61 int t; 44.62 - uint8_t oldctrl=pit.ctrl; 44.63 cycles -= (int)PITCONST; 44.64 - pit0=1; 44.65 // printf("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,pc,ins); 44.66 switch (addr&3) 44.67 { 44.68 @@ -135,13 +133,15 @@ 44.69 pit.l[t]=val; 44.70 pit.thit[t]=0; 44.71 pit.c[t]=pit.l[t]*PITCONST; 44.72 - picintc(1); 44.73 + if (!t) 44.74 + picintc(1); 44.75 break; 44.76 case 2: 44.77 pit.l[t]=(val<<8); 44.78 pit.thit[t]=0; 44.79 pit.c[t]=pit.l[t]*PITCONST; 44.80 - picintc(1); 44.81 + if (!t) 44.82 + picintc(1); 44.83 break; 44.84 case 0: 44.85 pit.l[t]&=0xFF; 44.86 @@ -150,7 +150,8 @@ 44.87 // pclog("%04X %f\n",pit.l[t],pit.c[t]); 44.88 pit.thit[t]=0; 44.89 pit.wm[t]=3; 44.90 - picintc(1); 44.91 + if (!t) 44.92 + picintc(1); 44.93 break; 44.94 case 3: 44.95 pit.l[t]&=0xFF00; 44.96 @@ -190,7 +191,7 @@ 44.97 } 44.98 } 44.99 44.100 -uint8_t pit_read(uint16_t addr) 44.101 +uint8_t pit_read(uint16_t addr, void *priv) 44.102 { 44.103 uint8_t temp; 44.104 cycles -= (int)PITCONST; 44.105 @@ -250,8 +251,8 @@ 44.106 else pit.c[0]+=((float)(0x10000*PITCONST)); 44.107 } 44.108 // pit.c[0]+=(pit.l[0]*PITCONST); 44.109 -// printf("PIT over! %f %i\n",pit.c[0],pit.m[0]); 44.110 - if (!pit.thit[0] && (pit.l[0]>0x14)) 44.111 +// if (output) printf("PIT over! %f %i\n",pit.c[0],pit.m[0]); 44.112 + if (!pit.thit[0])// && (pit.l[0]>0x14)) 44.113 { 44.114 // printf("PIT int!\n"); 44.115 /// printf("%05X %05X %02X\n",pit.c[0],pit.l[0],pit.ctrls[0]); 44.116 @@ -259,7 +260,6 @@ 44.117 } 44.118 if (!pit.m[0] || pit.m[0]==4) pit.thit[0]=1; 44.119 // if ((pit.ctrls[0]&0xE)==2) pit.thit[0]=1; 44.120 - pit0=0; 44.121 pitcount++; 44.122 } 44.123 if (pit.c[1]<1) 44.124 @@ -301,5 +301,5 @@ 44.125 44.126 void pit_init() 44.127 { 44.128 - io_sethandler(0x0040, 0x0004, pit_read, NULL, NULL, pit_write, NULL, NULL); 44.129 + io_sethandler(0x0040, 0x0004, pit_read, NULL, NULL, pit_write, NULL, NULL, NULL); 44.130 }
45.1 --- a/src/resources.h Sun Apr 21 14:54:35 2013 +0100 45.2 +++ b/src/resources.h Mon May 27 17:46:42 2013 +0100 45.3 @@ -31,6 +31,7 @@ 45.4 #define IDC_CHECK2 1011 45.5 #define IDC_CHECK3 1012 45.6 #define IDC_CHECK4 1013 45.7 +#define IDC_CHECKGUS 1014 45.8 #define IDC_STATIC 1020 45.9 #define IDC_EDIT1 1030 45.10 #define IDC_EDIT2 1031
46.1 --- a/src/serial.c Sun Apr 21 14:54:35 2013 +0100 46.2 +++ b/src/serial.c Mon May 27 17:46:42 2013 +0100 46.3 @@ -1,7 +1,9 @@ 46.4 #include "ibm.h" 46.5 #include "io.h" 46.6 #include "mouse.h" 46.7 +#include "pic.h" 46.8 #include "serial.h" 46.9 +#include "timer.h" 46.10 46.11 SERIAL serial,serial2; 46.12 46.13 @@ -48,7 +50,7 @@ 46.14 serial.iir=4; 46.15 } 46.16 46.17 -void serial_write(uint16_t addr, uint8_t val) 46.18 +void serial_write(uint16_t addr, uint8_t val, void *priv) 46.19 { 46.20 // printf("Write serial %03X %02X %04X:%04X\n",addr,val,CS,pc); 46.21 switch (addr&7) 46.22 @@ -89,7 +91,7 @@ 46.23 } 46.24 } 46.25 46.26 -uint8_t serial_read(uint16_t addr) 46.27 +uint8_t serial_read(uint16_t addr, void *priv) 46.28 { 46.29 uint8_t temp; 46.30 // printf("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, pc, mousedelay, ins); 46.31 @@ -104,7 +106,7 @@ 46.32 if (serial_fifo_read != serial_fifo_write) 46.33 { 46.34 mousepos = 0; 46.35 - mousedelay = 1000; 46.36 + mousedelay = 5000 * (1 << TIMER_SHIFT); 46.37 // pclog("Next FIFO\n"); 46.38 } 46.39 break; 46.40 @@ -122,7 +124,7 @@ 46.41 return temp; 46.42 } 46.43 46.44 -void serial2_write(uint16_t addr, uint8_t val) 46.45 +void serial2_write(uint16_t addr, uint8_t val, void *priv) 46.46 { 46.47 // printf("Write serial2 %03X %02X %04X:%04X\n",addr,val,cs>>4,pc); 46.48 switch (addr&7) 46.49 @@ -156,7 +158,7 @@ 46.50 } 46.51 } 46.52 46.53 -uint8_t serial2_read(uint16_t addr) 46.54 +uint8_t serial2_read(uint16_t addr, void *priv) 46.55 { 46.56 uint8_t temp; 46.57 // printf("Read serial2 %03X %04X:%04X\n",addr,cs>>4,pc); 46.58 @@ -186,25 +188,25 @@ 46.59 /*Tandy might need COM1 at 2f8*/ 46.60 void serial1_init(uint16_t addr) 46.61 { 46.62 - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL); 46.63 + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, NULL); 46.64 serial_rcr = NULL; 46.65 } 46.66 void serial1_remove() 46.67 { 46.68 - io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL); 46.69 - io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL); 46.70 - io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL); 46.71 - io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL); 46.72 + io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, NULL); 46.73 + io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, NULL); 46.74 + io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, NULL); 46.75 + io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, NULL); 46.76 } 46.77 46.78 void serial2_init(uint16_t addr) 46.79 { 46.80 - io_sethandler(addr, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL); 46.81 + io_sethandler(addr, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL, NULL); 46.82 } 46.83 void serial2_remove() 46.84 { 46.85 - io_removehandler(0x2e8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL); 46.86 - io_removehandler(0x2f8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL); 46.87 - io_removehandler(0x3e8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL); 46.88 - io_removehandler(0x3f8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL); 46.89 + io_removehandler(0x2e8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL, NULL); 46.90 + io_removehandler(0x2f8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL, NULL); 46.91 + io_removehandler(0x3e8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL, NULL); 46.92 + io_removehandler(0x3f8, 0x0008, serial2_read, NULL, NULL, serial2_write, NULL, NULL, NULL); 46.93 }
47.1 --- a/src/sound.c Sun Apr 21 14:54:35 2013 +0100 47.2 +++ b/src/sound.c Mon May 27 17:46:42 2013 +0100 47.3 @@ -1,180 +1,146 @@ 47.4 #include <stdio.h> 47.5 +#include <stdlib.h> 47.6 #include "ibm.h" 47.7 +#include "device.h" 47.8 + 47.9 #include "filters.h" 47.10 47.11 +#include "sound_opl.h" 47.12 + 47.13 +#include "sound.h" 47.14 +#include "sound_adlib.h" 47.15 +#include "sound_adlibgold.h" 47.16 +#include "sound_pas16.h" 47.17 +#include "sound_sb.h" 47.18 +#include "sound_sb_dsp.h" 47.19 +#include "sound_wss.h" 47.20 + 47.21 +#include "timer.h" 47.22 + 47.23 +int sound_card_current = 0; 47.24 +static int sound_card_last = 0; 47.25 + 47.26 +typedef struct 47.27 +{ 47.28 + char name[32]; 47.29 + device_t *device; 47.30 +} SOUND_CARD; 47.31 + 47.32 +static SOUND_CARD sound_cards[] = 47.33 +{ 47.34 + {"None", NULL}, 47.35 + {"Adlib", &adlib_device}, 47.36 + {"Sound Blaster 1.0", &sb_1_device}, 47.37 + {"Sound Blaster 1.5", &sb_15_device}, 47.38 + {"Sound Blaster 2.0", &sb_2_device}, 47.39 + {"Sound Blaster Pro v1", &sb_pro_v1_device}, 47.40 + {"Sound Blaster Pro v2", &sb_pro_v1_device}, 47.41 + {"Sound Blaster 16", &sb_16_device}, 47.42 + {"Adlib Gold", &adgold_device}, 47.43 + {"Windows Sound System", &wss_device}, 47.44 + {"Pro Audio Spectrum 16", &pas16_device}, 47.45 + {"", NULL} 47.46 +}; 47.47 + 47.48 +char *sound_card_getname(int card) 47.49 +{ 47.50 + return sound_cards[card].name; 47.51 +} 47.52 + 47.53 +void sound_card_init() 47.54 +{ 47.55 + if (sound_cards[sound_card_current].device) 47.56 + device_add(sound_cards[sound_card_current].device); 47.57 + sound_card_last = sound_card_current; 47.58 +} 47.59 + 47.60 +static struct 47.61 +{ 47.62 + void (*poll)(void *p); 47.63 + void (*get_buffer)(int16_t *buffer, int len, void *p); 47.64 + void *priv; 47.65 +} sound_handlers[8]; 47.66 + 47.67 +static int sound_handlers_num; 47.68 + 47.69 +static int sound_poll_time = 0, sound_get_buffer_time = 0; 47.70 + 47.71 int soundon = 1; 47.72 -int16_t *adbuffer,*adbuffer2; 47.73 -int16_t *psgbuffer; 47.74 -uint16_t *cmsbuffer; 47.75 -int16_t *spkbuffer; 47.76 -int16_t *outbuffer; 47.77 -uint16_t *gusbuffer; 47.78 47.79 -void initsound() 47.80 + 47.81 +static int16_t cd_buffer[SOUNDBUFLEN * 2]; 47.82 + 47.83 +void sound_cd_poll(void *p) 47.84 +{ 47.85 +} 47.86 + 47.87 +void sound_cd_get_buffer(int16_t *buffer, int len, void *p) 47.88 +{ 47.89 + int pos, c; 47.90 + ioctl_audio_callback(cd_buffer, (len * 2 * 441) / 480); 47.91 + pos = 0; 47.92 + 47.93 + for (c = 0; c < len * 2; c+=2) 47.94 + { 47.95 + buffer[c] += cd_buffer[((pos >> 16) << 1)] / 2; 47.96 + buffer[c + 1] += cd_buffer[((pos >> 16) << 1) + 1] / 2; 47.97 + pos += 60211; //(44100 * 65536) / 48000; 47.98 + } 47.99 +} 47.100 + 47.101 +static uint16_t *outbuffer; 47.102 + 47.103 +void sound_init() 47.104 { 47.105 initalmain(0,NULL); 47.106 inital(); 47.107 -// install_sound(DIGI_AUTODETECT,MIDI_NONE,0); 47.108 -// as=play_audio_stream(SOUNDBUFLEN,16,1,48000,255,128); 47.109 - adbuffer=malloc((SOUNDBUFLEN)*2); 47.110 - adbuffer2=malloc((SOUNDBUFLEN)*2); 47.111 - psgbuffer=malloc((SOUNDBUFLEN)*2); 47.112 - cmsbuffer=malloc((SOUNDBUFLEN)*2*2); 47.113 - gusbuffer=malloc((SOUNDBUFLEN)*2*2); 47.114 - spkbuffer=malloc(((SOUNDBUFLEN)*2)+32); 47.115 - outbuffer=malloc((SOUNDBUFLEN)*2*2); 47.116 + 47.117 + outbuffer = malloc(SOUNDBUFLEN * 2 * sizeof(int16_t)); 47.118 + 47.119 + sound_add_handler(sound_cd_poll, sound_cd_get_buffer, NULL); 47.120 } 47.121 47.122 -int adpoll=0; 47.123 -void pollad() 47.124 +void sound_add_handler(void (*poll)(void *p), void (*get_buffer)(int16_t *buffer, int len, void *p), void *p) 47.125 { 47.126 -/* if (adpoll>=20) return; 47.127 - getadlibl(adbuffer+(adpoll*(48000/200)),48000/200); 47.128 - getadlibr(adbuffer2+(adpoll*(48000/200)),48000/200); 47.129 - adpoll++;*/ 47.130 -// printf("ADPOLL %i\n",adpoll); 47.131 + sound_handlers[sound_handlers_num].poll = poll; 47.132 + sound_handlers[sound_handlers_num].get_buffer = get_buffer; 47.133 + sound_handlers[sound_handlers_num].priv = p; 47.134 + sound_handlers_num++; 47.135 } 47.136 47.137 -void polladlib() 47.138 +void sound_poll(void *priv) 47.139 { 47.140 - getadlib(adbuffer+(adpoll),adbuffer2+(adpoll),1); 47.141 - adpoll++; 47.142 -} 47.143 + int c; 47.144 47.145 -int psgpoll=0; 47.146 -void pollpsg() 47.147 -{ 47.148 - if (psgpoll>=20) return; 47.149 - getpsg(psgbuffer+(psgpoll*(48000/200)),48000/200); 47.150 - psgpoll++; 47.151 -} 47.152 - 47.153 -int cmspoll=0; 47.154 -void pollcms() 47.155 -{ 47.156 - if (cmspoll>=20) return; 47.157 - getcms(cmsbuffer+(cmspoll*(48000/200)*2),48000/200); 47.158 - cmspoll++; 47.159 -} 47.160 - 47.161 -int guspoll=0; 47.162 -void pollgussnd() 47.163 -{ 47.164 - if (guspoll>=20) return; 47.165 - getgus(gusbuffer+(guspoll*(48000/200)*2),48000/200); 47.166 - guspoll++; 47.167 -} 47.168 - 47.169 -int spkpos=0; 47.170 -int wasgated = 0; 47.171 -void pollspk() 47.172 -{ 47.173 - if (spkpos>=SOUNDBUFLEN) return; 47.174 -// printf("SPeaker - %i %i %i %02X\n",speakval,gated,speakon,pit.m[2]); 47.175 - if (gated) 47.176 - { 47.177 - if (!pit.m[2] || pit.m[2]==4) 47.178 - spkbuffer[spkpos]=speakval; 47.179 - else 47.180 - spkbuffer[spkpos]=(speakon)?0x1400:0; 47.181 - } 47.182 - else 47.183 - spkbuffer[spkpos]=(wasgated)?0x1400:0; 47.184 - spkpos++; 47.185 - wasgated=0; 47.186 + sound_poll_time += (int)((double)TIMER_USEC * (1000000.0 / 48000.0)); 47.187 + 47.188 + for (c = 0; c < sound_handlers_num; c++) 47.189 + sound_handlers[c].poll(sound_handlers[c].priv); 47.190 } 47.191 47.192 FILE *soundf; 47.193 47.194 -static int16_t cd_buffer[(SOUNDBUFLEN) * 2]; 47.195 -void pollsound() 47.196 +void sound_get_buffer(void *priv) 47.197 { 47.198 int c; 47.199 - int16_t t[4]; 47.200 - uint32_t pos; 47.201 -// printf("Pollsound! %i\n",soundon); 47.202 -// if (soundon) 47.203 -// { 47.204 - for (c=0;c<(SOUNDBUFLEN);c++) outbuffer[c<<1]=outbuffer[(c<<1)+1]=0; 47.205 - for (c=0;c<(SOUNDBUFLEN);c++) 47.206 - { 47.207 - outbuffer[c<<1]+=((adbuffer[c]*mixer.fm_l)>>16); 47.208 - outbuffer[(c<<1)+1]+=((adbuffer[c]*mixer.fm_r)>>16); 47.209 -// if (!c) pclog("F %04X %04X %04X\n",adbuffer[c],outbuffer[c<<1],mixer.fm_l); 47.210 - } 47.211 - addsb(outbuffer); 47.212 - for (c=0;c<(SOUNDBUFLEN);c++) 47.213 - { 47.214 -// if (!c) pclog("M %04X ",outbuffer[c<<1]); 47.215 - outbuffer[c<<1]=(outbuffer[c<<1]*mixer.master_l)>>16; 47.216 - outbuffer[(c<<1)+1]=(outbuffer[(c<<1)+1]*mixer.master_r)>>16; 47.217 -// if (!c) pclog("%04X %04X\n",outbuffer[c<<1],mixer.master_l); 47.218 - } 47.219 - if (mixer.bass_l!=8 || mixer.bass_r!=8 || mixer.treble_l!=8 || mixer.treble_r!=8) 47.220 - { 47.221 - for (c=0;c<(SOUNDBUFLEN);c++) 47.222 - { 47.223 - if (mixer.bass_l>8) outbuffer[c<<1] =(outbuffer[c<<1] +(((int16_t)low_iir(0,(float)outbuffer[c<<1]) *(mixer.bass_l-8))>>1))*((15-mixer.bass_l)+16)>>5; 47.224 - if (mixer.bass_r>8) outbuffer[(c<<1)+1]=(outbuffer[(c<<1)+1]+(((int16_t)low_iir(1,(float)outbuffer[(c<<1)+1]) *(mixer.bass_r-8))>>1))*((15-mixer.bass_r)+16)>>5; 47.225 - if (mixer.treble_l>8) outbuffer[c<<1] =(outbuffer[c<<1] +(((int16_t)high_iir(0,(float)outbuffer[c<<1]) *(mixer.treble_l-8))>>1))*((15-mixer.treble_l)+16)>>5; 47.226 - if (mixer.treble_r>8) outbuffer[(c<<1)+1]=(outbuffer[(c<<1)+1]+(((int16_t)high_iir(1,(float)outbuffer[(c<<1)+1]) *(mixer.treble_r-8))>>1))*((15-mixer.treble_r)+16)>>5; 47.227 - if (mixer.bass_l<8) outbuffer[c<<1] =(outbuffer[c<<1] +(((int16_t)low_cut_iir(0,(float)outbuffer[c<<1]) *(8-mixer.bass_l))>>1))*(mixer.bass_l+16)>>5; 47.228 - if (mixer.bass_r<8) outbuffer[(c<<1)+1]=(outbuffer[(c<<1)+1]+(((int16_t)low_cut_iir(1,(float)outbuffer[(c<<1)+1]) *(8-mixer.bass_r))>>1))*(mixer.bass_r+16)>>5; 47.229 - if (mixer.treble_l<8) outbuffer[c<<1] =(outbuffer[c<<1] +(((int16_t)high_cut_iir(0,(float)outbuffer[c<<1]) *(8-mixer.treble_l))>>1))*(mixer.treble_l+16)>>5; 47.230 - if (mixer.treble_r<8) outbuffer[(c<<1)+1]=(outbuffer[(c<<1)+1]+(((int16_t)high_cut_iir(1,(float)outbuffer[(c<<1)+1])*(8-mixer.treble_r))>>1))*(mixer.treble_r+16)>>5; 47.231 - } 47.232 - } 47.233 - for (c=0;c<(SOUNDBUFLEN);c++) 47.234 - { 47.235 - outbuffer[c<<1]+=(spkbuffer[c]/2); 47.236 - outbuffer[(c<<1)+1]+=(spkbuffer[c]/2); 47.237 - } 47.238 - for (c=0;c<(SOUNDBUFLEN);c++) 47.239 - { 47.240 - outbuffer[c<<1]+=(psgbuffer[c]/2); 47.241 - outbuffer[(c<<1)+1]+=(psgbuffer[c]/2); 47.242 - } 47.243 - for (c=0;c<((SOUNDBUFLEN)*2);c++) 47.244 - outbuffer[c]+=(cmsbuffer[c]/2); 47.245 - for (c=0;c<((SOUNDBUFLEN)*2);c++) 47.246 - outbuffer[c]+=(gusbuffer[c]); 47.247 - adddac(outbuffer); 47.248 - ioctl_audio_callback(cd_buffer, ((SOUNDBUFLEN) * 2 * 441) / 480); 47.249 - pos = 0; 47.250 - for (c = 0; c < (SOUNDBUFLEN) * 2; c+=2) 47.251 - { 47.252 - outbuffer[c] += cd_buffer[((pos >> 16) << 1)] / 2; 47.253 - outbuffer[c + 1] += cd_buffer[((pos >> 16) << 1) + 1] / 2; 47.254 -// outbuffer[c] += (int16_t)((int32_t)cd_buffer[pos >> 16] * (65536 - (pos & 0xffff))) / 65536; 47.255 -// outbuffer[c] += (int16_t)((int32_t)cd_buffer[(pos >> 16) + 1] * (pos & 0xffff)) / 65536; 47.256 - pos += 60211; //(44100 * 65536) / 48000; 47.257 - } 47.258 - 47.259 -// if (!soundf) soundf=fopen("sound.pcm","wb"); 47.260 -// fwrite(outbuffer,(SOUNDBUFLEN)*2*2,1,soundf); 47.261 - if (soundon) givealbuffer(outbuffer); 47.262 -// } 47.263 -// addsb(outbuffer); 47.264 -// adddac(outbuffer); 47.265 - adpoll=0; 47.266 - psgpoll=0; 47.267 - cmspoll=0; 47.268 - spkpos=0; 47.269 - guspoll=0; 47.270 + 47.271 + sound_get_buffer_time += (TIMER_USEC * (1000000 / 10)); 47.272 + 47.273 + memset(outbuffer, 0, SOUNDBUFLEN * 2 * sizeof(int16_t)); 47.274 + 47.275 + for (c = 0; c < sound_handlers_num; c++) 47.276 + sound_handlers[c].get_buffer(outbuffer, SOUNDBUFLEN, sound_handlers[c].priv); 47.277 + 47.278 +/* if (!soundf) soundf=fopen("sound.pcm","wb"); 47.279 + fwrite(outbuffer,(SOUNDBUFLEN)*2*2,1,soundf);*/ 47.280 + 47.281 + if (soundon) givealbuffer(outbuffer); 47.282 } 47.283 47.284 -int sndcount; 47.285 -void pollsound60hz() 47.286 +void sound_reset() 47.287 { 47.288 -// printf("Poll sound %i\n",sndcount); 47.289 -// pollad(); 47.290 - pollpsg(); 47.291 - pollcms(); 47.292 - pollgussnd(); 47.293 - sndcount++; 47.294 - if (sndcount==20) 47.295 - { 47.296 - sndcount=0; 47.297 - pollsound(); 47.298 - } 47.299 + timer_add(sound_poll, &sound_poll_time, TIMER_ALWAYS_ENABLED, NULL); 47.300 + timer_add(sound_get_buffer, &sound_get_buffer_time, TIMER_ALWAYS_ENABLED, NULL); 47.301 + 47.302 + sound_handlers_num = 0; 47.303 }
48.1 --- a/src/sound.h Sun Apr 21 14:54:35 2013 +0100 48.2 +++ b/src/sound.h Mon May 27 17:46:42 2013 +0100 48.3 @@ -1,1 +1,9 @@ 48.4 +void sound_add_handler(void (*poll)(void *p), void (*get_buffer)(int16_t *buffer, int len, void *p), void *p); 48.5 + 48.6 extern int wasgated; 48.7 +extern int sbtype; 48.8 + 48.9 +extern int sound_card_current; 48.10 + 48.11 +char *sound_card_getname(int card); 48.12 +void sound_card_init();
49.1 --- a/src/soundopenal.c Sun Apr 21 14:54:35 2013 +0100 49.2 +++ b/src/soundopenal.c Mon May 27 17:46:42 2013 +0100 49.3 @@ -1,6 +1,7 @@ 49.4 #define USE_OPENAL 49.5 #include <stdio.h> 49.6 #include <string.h> 49.7 +#include <stdlib.h> 49.8 #ifdef USE_OPENAL 49.9 #include <AL/al.h> 49.10 #include <AL/alut.h> 49.11 @@ -91,7 +92,6 @@ 49.12 #ifdef USE_OPENAL 49.13 int processed; 49.14 int state; 49.15 - int c; 49.16 49.17 //return; 49.18
50.1 --- a/src/um8881f.c Sun Apr 21 14:54:35 2013 +0100 50.2 +++ b/src/um8881f.c Mon May 27 17:46:42 2013 +0100 50.3 @@ -1,22 +1,23 @@ 50.4 #include "ibm.h" 50.5 #include "io.h" 50.6 #include "mem.h" 50.7 +#include "pci.h" 50.8 50.9 #include "um8881f.h" 50.10 50.11 static uint8_t card_16[256]; 50.12 static uint8_t card_18[256]; 50.13 50.14 -void um8881f_write(int func, int addr, uint8_t val) 50.15 +void um8881f_write(int func, int addr, uint8_t val, void *priv) 50.16 { 50.17 if (addr == 0x54) 50.18 { 50.19 if ((card_16[0x54] ^ val) & 0x01) 50.20 { 50.21 if (val & 1) 50.22 - mem_sethandler(0xe0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); 50.23 + mem_sethandler(0xe0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); 50.24 else 50.25 - mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL ); 50.26 + mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL , NULL); 50.27 } 50.28 flushmmucache_nopc(); 50.29 } 50.30 @@ -26,10 +27,10 @@ 50.31 { 50.32 switch (val & 0xc0) 50.33 { 50.34 - case 0x00: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml); break; 50.35 - case 0x40: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL ); break; 50.36 - case 0x80: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml); break; 50.37 - case 0xc0: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL ); break; 50.38 + case 0x00: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break; 50.39 + case 0x40: mem_sethandler(0xf0000, 0x10000, mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL , NULL); break; 50.40 + case 0x80: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break; 50.41 + case 0xc0: mem_sethandler(0xf0000, 0x10000, mem_read_ram, mem_read_ramw, mem_read_raml, NULL, NULL, NULL , NULL); break; 50.42 } 50.43 shadowbios = val & 0x80; 50.44 shadowbios_write = !(val & 0x40); 50.45 @@ -40,18 +41,18 @@ 50.46 card_16[addr] = val; 50.47 } 50.48 50.49 -uint8_t um8881f_read(int func, int addr) 50.50 +uint8_t um8881f_read(int func, int addr, void *priv) 50.51 { 50.52 return card_16[addr]; 50.53 } 50.54 50.55 -void um8886f_write(int func, int addr, uint8_t val) 50.56 +void um8886f_write(int func, int addr, uint8_t val, void *priv) 50.57 { 50.58 if (addr >= 4) 50.59 card_18[addr] = val; 50.60 } 50.61 50.62 -uint8_t um8886f_read(int func, int addr) 50.63 +uint8_t um8886f_read(int func, int addr, void *priv) 50.64 { 50.65 return card_18[addr]; 50.66 } 50.67 @@ -60,8 +61,8 @@ 50.68 50.69 void um8881f_init() 50.70 { 50.71 - pci_add_specific(16, um8881f_read, um8881f_write); 50.72 - pci_add_specific(18, um8886f_read, um8886f_write); 50.73 + pci_add_specific(16, um8881f_read, um8881f_write, NULL); 50.74 + pci_add_specific(18, um8886f_read, um8886f_write, NULL); 50.75 50.76 card_16[0] = card_18[0] = 0x60; /*UMC*/ 50.77 card_16[1] = card_18[1] = 0x10;
51.1 --- a/src/vid_cga.c Sun Apr 21 14:54:35 2013 +0100 51.2 +++ b/src/vid_cga.c Mon May 27 17:46:42 2013 +0100 51.3 @@ -1,8 +1,15 @@ 51.4 /*CGA emulation*/ 51.5 +#include <math.h> 51.6 #include "ibm.h" 51.7 +#include "io.h" 51.8 +#include "mem.h" 51.9 +#include "timer.h" 51.10 #include "video.h" 51.11 +#include "vid_cga.h" 51.12 51.13 -void cga_out(uint16_t addr, uint8_t val) 51.14 +void cga_recalctimings(); 51.15 + 51.16 +void cga_out(uint16_t addr, uint8_t val, void *priv) 51.17 { 51.18 uint8_t old; 51.19 // pclog("CGA_OUT %04X %02X\n", addr, val); 51.20 @@ -32,7 +39,7 @@ 51.21 } 51.22 } 51.23 51.24 -uint8_t cga_in(uint16_t addr) 51.25 +uint8_t cga_in(uint16_t addr, void *priv) 51.26 { 51.27 // pclog("CGA_IN %04X\n", addr); 51.28 switch (addr) 51.29 @@ -49,7 +56,7 @@ 51.30 51.31 extern uint8_t charbuffer[256]; 51.32 51.33 -void cga_write(uint32_t addr, uint8_t val) 51.34 +void cga_write(uint32_t addr, uint8_t val, void *priv) 51.35 { 51.36 // pclog("CGA_WRITE %04X %02X\n", addr, val); 51.37 vram[addr&0x3FFF]=val; 51.38 @@ -58,7 +65,7 @@ 51.39 cycles -= 4; 51.40 } 51.41 51.42 -uint8_t cga_read(uint32_t addr) 51.43 +uint8_t cga_read(uint32_t addr, void *priv) 51.44 { 51.45 cycles -= 4; 51.46 charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = vram[addr&0x3FFF]; 51.47 @@ -69,22 +76,25 @@ 51.48 51.49 void cga_recalctimings() 51.50 { 51.51 + double _dispontime, _dispofftime; 51.52 pclog("Recalc - %i %i %i\n", crtc[0], crtc[1], cgamode & 1); 51.53 if (cgamode&1) 51.54 { 51.55 disptime=crtc[0]+1; 51.56 - dispontime=crtc[1]; 51.57 + _dispontime=crtc[1]; 51.58 } 51.59 else 51.60 { 51.61 disptime=(crtc[0]+1)<<1; 51.62 - dispontime=crtc[1]<<1; 51.63 + _dispontime=crtc[1]<<1; 51.64 } 51.65 - dispofftime=disptime-dispontime; 51.66 + _dispofftime=disptime-_dispontime; 51.67 // printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); 51.68 - dispontime*=CGACONST; 51.69 - dispofftime*=CGACONST; 51.70 + _dispontime*=CGACONST; 51.71 + _dispofftime*=CGACONST; 51.72 // printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); 51.73 + dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); 51.74 + dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); 51.75 } 51.76 51.77 static int linepos,displine; 51.78 @@ -92,7 +102,7 @@ 51.79 static int cgadispon; 51.80 static int con,coff,cursoron,cgablink; 51.81 static int vsynctime,vadj; 51.82 -static uint16_t ma,maback,ca; 51.83 +static uint16_t ma,maback; 51.84 static int oddeven = 0; 51.85 51.86 static int ntsc_col[8][8]= 51.87 @@ -117,7 +127,7 @@ 51.88 int x,c; 51.89 int oldvc; 51.90 uint8_t chr,attr; 51.91 - uint16_t dat,dat2,dat3,dat4; 51.92 + uint16_t dat; 51.93 int cols[4]; 51.94 int col; 51.95 int oldsc; 51.96 @@ -467,7 +477,7 @@ 51.97 i_filt[c]=512.0*cos((3.14*(cga_tint+c*4)/16.0) - 33.0/180.0); 51.98 q_filt[c]=512.0*sin((3.14*(cga_tint+c*4)/16.0) - 33.0/180.0); 51.99 } 51.100 - mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL); 51.101 + mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL); 51.102 return 0; 51.103 } 51.104
52.1 --- a/src/vid_cga.h Sun Apr 21 14:54:35 2013 +0100 52.2 +++ b/src/vid_cga.h Mon May 27 17:46:42 2013 +0100 52.3 @@ -1,7 +1,7 @@ 52.4 int cga_init(); 52.5 -void cga_out(uint16_t addr, uint8_t val); 52.6 -uint8_t cga_in(uint16_t addr); 52.7 +void cga_out(uint16_t addr, uint8_t val, void *priv); 52.8 +uint8_t cga_in(uint16_t addr, void *priv); 52.9 void cga_poll(); 52.10 -void cga_write(uint32_t addr, uint8_t val); 52.11 -uint8_t cga_read(uint32_t addr); 52.12 +void cga_write(uint32_t addr, uint8_t val, void *priv); 52.13 +uint8_t cga_read(uint32_t addr, void *priv); 52.14 void cga_recalctimings();
53.1 --- a/src/vid_ega.c Sun Apr 21 14:54:35 2013 +0100 53.2 +++ b/src/vid_ega.c Mon May 27 17:46:42 2013 +0100 53.3 @@ -1,10 +1,11 @@ 53.4 /*EGA emulation*/ 53.5 #include "ibm.h" 53.6 +#include "io.h" 53.7 +#include "mem.h" 53.8 +#include "timer.h" 53.9 #include "video.h" 53.10 - 53.11 -void ega_recalctimings(); 53.12 -void ega_write(uint32_t addr, uint8_t val); 53.13 -uint8_t ega_read(uint32_t addr); 53.14 +#include "vid_ega.h" 53.15 +#include "vid_svga.h" 53.16 53.17 extern uint8_t edatlookup[4][4]; 53.18 53.19 @@ -16,7 +17,7 @@ 53.20 /*3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour)*/ 53.21 int egaswitchread,egaswitches=9; /*7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines)*/ 53.22 53.23 -void ega_out(uint16_t addr, uint8_t val) 53.24 +void ega_out(uint16_t addr, uint8_t val, void *priv) 53.25 { 53.26 int c; 53.27 uint8_t o,old; 53.28 @@ -73,21 +74,21 @@ 53.29 case 4: readplane=val&3; break; 53.30 case 5: writemode=val&3; readmode=val&8; break; 53.31 case 6: 53.32 - mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL); 53.33 + mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); 53.34 // pclog("Write mapping %02X\n", val); 53.35 switch (val&0xC) 53.36 { 53.37 case 0x0: /*128k at A0000*/ 53.38 - mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL); 53.39 + mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); 53.40 break; 53.41 case 0x4: /*64k at A0000*/ 53.42 - mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL); 53.43 + mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); 53.44 break; 53.45 case 0x8: /*32k at B0000*/ 53.46 - mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL); 53.47 + mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); 53.48 break; 53.49 case 0xC: /*32k at B8000*/ 53.50 - mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL); 53.51 + mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); 53.52 break; 53.53 } 53.54 53.55 @@ -114,9 +115,8 @@ 53.56 } 53.57 } 53.58 53.59 -uint8_t ega_in(uint16_t addr) 53.60 +uint8_t ega_in(uint16_t addr, void *priv) 53.61 { 53.62 - uint8_t temp; 53.63 if ((addr&0xFFF0) == 0x3B0) addr |= 0x20; 53.64 switch (addr) 53.65 { 53.66 @@ -161,8 +161,9 @@ 53.67 53.68 void ega_recalctimings() 53.69 { 53.70 - float crtcconst; 53.71 - int temp; 53.72 + double _dispontime, _dispofftime; 53.73 + double crtcconst; 53.74 + 53.75 ega_vtotal=crtc[6]; 53.76 ega_dispend=crtc[0x12]; 53.77 ega_vsyncstart=crtc[0x10]; 53.78 @@ -195,14 +196,16 @@ 53.79 else crtcconst=(seqregs[1]&1)?(CGACONST*(8.0/9.0)):CGACONST; 53.80 53.81 disptime=crtc[0]+2; 53.82 - dispontime=crtc[1]+1; 53.83 + _dispontime=crtc[1]+1; 53.84 53.85 - printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); 53.86 - if (seqregs[1]&8) { disptime*=2; dispontime*=2; } 53.87 - dispofftime=disptime-dispontime; 53.88 - dispontime*=crtcconst; 53.89 - dispofftime*=crtcconst; 53.90 + printf("Disptime %f dispontime %f hdisp %i\n",disptime,_dispontime,crtc[1]*8); 53.91 + if (seqregs[1]&8) { disptime*=2; _dispontime*=2; } 53.92 + _dispofftime=disptime-_dispontime; 53.93 + _dispontime*=crtcconst; 53.94 + _dispofftime*=crtcconst; 53.95 53.96 + dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); 53.97 + dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); 53.98 53.99 // printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4)); 53.100 // printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart); 53.101 @@ -525,11 +528,9 @@ 53.102 } 53.103 53.104 53.105 -void ega_write(uint32_t addr, uint8_t val) 53.106 +void ega_write(uint32_t addr, uint8_t val, void *priv) 53.107 { 53.108 - int x,y; 53.109 - char s[2]={0,0}; 53.110 - uint8_t vala,valb,valc,vald,wm=writemask; 53.111 + uint8_t vala,valb,valc,vald; 53.112 53.113 egawrites++; 53.114 cycles -= video_timing_b; 53.115 @@ -647,10 +648,9 @@ 53.116 } 53.117 } 53.118 53.119 -uint8_t ega_read(uint32_t addr) 53.120 +uint8_t ega_read(uint32_t addr, void *priv) 53.121 { 53.122 uint8_t temp,temp2,temp3,temp4; 53.123 - uint32_t addr2; 53.124 egareads++; 53.125 cycles -= video_timing_b; 53.126 cycles_lost += video_timing_b;
54.1 --- a/src/vid_ega.h Sun Apr 21 14:54:35 2013 +0100 54.2 +++ b/src/vid_ega.h Mon May 27 17:46:42 2013 +0100 54.3 @@ -1,7 +1,7 @@ 54.4 int ega_init(); 54.5 -void ega_out(uint16_t addr, uint8_t val); 54.6 -uint8_t ega_in(uint16_t addr); 54.7 +void ega_out(uint16_t addr, uint8_t val, void *priv); 54.8 +uint8_t ega_in(uint16_t addr, void *priv); 54.9 void ega_poll(); 54.10 void ega_recalctimings(); 54.11 -void ega_write(uint32_t addr, uint8_t val); 54.12 -uint8_t ega_read(uint32_t addr); 54.13 +void ega_write(uint32_t addr, uint8_t val, void *priv); 54.14 +uint8_t ega_read(uint32_t addr, void *priv);
55.1 --- a/src/vid_et4000.c Sun Apr 21 14:54:35 2013 +0100 55.2 +++ b/src/vid_et4000.c Mon May 27 17:46:42 2013 +0100 55.3 @@ -1,5 +1,6 @@ 55.4 /*ET4000 emulation*/ 55.5 #include "ibm.h" 55.6 +#include "io.h" 55.7 #include "video.h" 55.8 #include "vid_svga.h" 55.9 #include "vid_unk_ramdac.h" 55.10 @@ -7,7 +8,7 @@ 55.11 int et4k_b8000; 55.12 55.13 55.14 -void et4000_out(uint16_t addr, uint8_t val) 55.15 +void et4000_out(uint16_t addr, uint8_t val, void *priv) 55.16 { 55.17 uint8_t old; 55.18 55.19 @@ -18,7 +19,7 @@ 55.20 switch (addr) 55.21 { 55.22 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 55.23 - unk_ramdac_out(addr,val); 55.24 + unk_ramdac_out(addr, val, NULL); 55.25 return; 55.26 55.27 case 0x3CD: /*Banking*/ 55.28 @@ -57,13 +58,11 @@ 55.29 if (val==0x29) svgaon=0; 55.30 break; 55.31 } 55.32 - svga_out(addr,val); 55.33 + svga_out(addr, val, priv); 55.34 } 55.35 55.36 -uint8_t et4000_in(uint16_t addr) 55.37 +uint8_t et4000_in(uint16_t addr, void *priv) 55.38 { 55.39 - uint8_t temp; 55.40 - 55.41 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 55.42 55.43 if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr); 55.44 @@ -75,7 +74,7 @@ 55.45 break; 55.46 55.47 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 55.48 - return unk_ramdac_in(addr); 55.49 + return unk_ramdac_in(addr, NULL); 55.50 55.51 case 0x3CD: /*Banking*/ 55.52 return svgaseg; 55.53 @@ -84,7 +83,7 @@ 55.54 case 0x3D5: 55.55 return crtc[crtcreg]; 55.56 } 55.57 - return svga_in(addr); 55.58 + return svga_in(addr, priv); 55.59 } 55.60 55.61 void et4000_recalctimings() 55.62 @@ -98,6 +97,7 @@ 55.63 // if (crtc[0x3F]&0x80) svga_rowoffset+=0x100; 55.64 if (crtc[0x3F]&1) svga_htotal+=256; 55.65 if (attrregs[0x16]&0x20) svga_hdisp<<=1; 55.66 + 55.67 // pclog("Rowoffset %i\n",svga_rowoffset); 55.68 55.69 switch (((svga_miscout >> 2) & 3) | ((crtc[0x34] << 1) & 4))
56.1 --- a/src/vid_et4000w32.c Sun Apr 21 14:54:35 2013 +0100 56.2 +++ b/src/vid_et4000w32.c Mon May 27 17:46:42 2013 +0100 56.3 @@ -5,6 +5,8 @@ 56.4 */ 56.5 56.6 #include "ibm.h" 56.7 +#include "io.h" 56.8 +#include "pci.h" 56.9 #include "video.h" 56.10 #include "vid_svga.h" 56.11 #include "vid_icd2061.h" 56.12 @@ -15,14 +17,14 @@ 56.13 56.14 void et4000w32p_recalcmapping(); 56.15 56.16 -uint8_t et4000w32p_mmu_read(uint32_t addr); 56.17 -void et4000w32p_mmu_write(uint32_t addr, uint8_t val); 56.18 +uint8_t et4000w32p_mmu_read(uint32_t addr, void *priv); 56.19 +void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv); 56.20 56.21 static int et4000w32p_index; 56.22 static uint8_t et4000w32p_regs[256]; 56.23 static uint32_t et4000w32p_linearbase, et4000w32p_linearbase_old; 56.24 56.25 -void et4000w32p_out(uint16_t addr, uint8_t val) 56.26 +void et4000w32p_out(uint16_t addr, uint8_t val, void *priv) 56.27 { 56.28 uint8_t old; 56.29 56.30 @@ -39,7 +41,7 @@ 56.31 break; 56.32 56.33 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 56.34 - stg_ramdac_out(addr,val); 56.35 + stg_ramdac_out(addr, val, NULL); 56.36 return; 56.37 56.38 case 0x3CB: /*Banking extension*/ 56.39 @@ -111,10 +113,10 @@ 56.40 return; 56.41 56.42 } 56.43 - svga_out(addr,val); 56.44 + svga_out(addr, val, NULL); 56.45 } 56.46 56.47 -uint8_t et4000w32p_in(uint16_t addr) 56.48 +uint8_t et4000w32p_in(uint16_t addr, void *priv) 56.49 { 56.50 uint8_t temp; 56.51 // if (addr==0x3DA) pclog("In 3DA %04X(%06X):%04X\n",CS,cs,pc); 56.52 @@ -132,7 +134,7 @@ 56.53 break; 56.54 56.55 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 56.56 - return stg_ramdac_in(addr); 56.57 + return stg_ramdac_in(addr, NULL); 56.58 56.59 case 0x3CB: 56.60 return svgaseg2; 56.61 @@ -166,15 +168,14 @@ 56.62 } 56.63 return et4000w32p_regs[et4000w32p_index]; 56.64 } 56.65 - return svga_in(addr); 56.66 + return svga_in(addr, NULL); 56.67 } 56.68 56.69 void et4000w32p_recalctimings() 56.70 { 56.71 - double clk; 56.72 // pclog("Recalc %08X ",svga_ma); 56.73 svga_ma|=(crtc[0x33]&0x7)<<16; 56.74 - pclog("SVGA_MA %08X %i\n", svga_ma, (svga_miscout >> 2) & 3); 56.75 +// pclog("SVGA_MA %08X %i\n", svga_ma, (svga_miscout >> 2) & 3); 56.76 if (crtc[0x35]&2) svga_vtotal+=0x400; 56.77 if (crtc[0x35]&4) svga_dispend+=0x400; 56.78 if (crtc[0x35]&8) svga_vsyncstart+=0x400; 56.79 @@ -205,12 +206,12 @@ 56.80 { 56.81 int map; 56.82 56.83 - mem_removehandler(et4000w32p_linearbase_old, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear); 56.84 - mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 56.85 - mem_removehandler(0xb0000, 0x10000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL); 56.86 + mem_removehandler(et4000w32p_linearbase_old, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); 56.87 + mem_removehandler( 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 56.88 + mem_removehandler( 0xb0000, 0x10000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL); 56.89 if (crtc[0x36] & 0x10) /*Linear frame buffer*/ 56.90 { 56.91 - mem_sethandler(et4000w32p_linearbase, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear); 56.92 + mem_sethandler(et4000w32p_linearbase, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); 56.93 } 56.94 else 56.95 { 56.96 @@ -220,28 +221,28 @@ 56.97 switch (map) 56.98 { 56.99 case 0x0: case 0x4: case 0x8: case 0xC: /*128k at A0000*/ 56.100 - mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 56.101 + mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 56.102 break; 56.103 case 0x1: /*64k at A0000*/ 56.104 - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 56.105 + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 56.106 break; 56.107 case 0x2: /*32k at B0000*/ 56.108 - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 56.109 + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 56.110 break; 56.111 case 0x3: /*32k at B8000*/ 56.112 - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 56.113 + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 56.114 break; 56.115 case 0x5: case 0x9: case 0xD: /*64k at A0000, MMU at B8000*/ 56.116 - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 56.117 - mem_sethandler(0xb8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL); 56.118 + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 56.119 + mem_sethandler(0xb8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL); 56.120 break; 56.121 case 0x6: case 0xA: case 0xE: /*32k at B0000, MMU at A8000*/ 56.122 - mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL); 56.123 - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 56.124 + mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL); 56.125 + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 56.126 break; 56.127 case 0x7: case 0xB: case 0xF: /*32k at B8000, MMU at A8000*/ 56.128 - mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL); 56.129 - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 56.130 + mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL); 56.131 + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 56.132 break; 56.133 } 56.134 // pclog("ET4K map %02X\n", map); 56.135 @@ -295,7 +296,7 @@ 56.136 void et4000w32_blit_start(); 56.137 void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input); 56.138 56.139 -void et4000w32p_mmu_write(uint32_t addr, uint8_t val) 56.140 +void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv) 56.141 { 56.142 int bank; 56.143 // pclog("ET4K write %08X %02X %02X %04X(%08X):%08X\n",addr,val,acl.status,acl.internal.ctrl_routing,CS,cs,pc); 56.144 @@ -402,7 +403,7 @@ 56.145 } 56.146 } 56.147 56.148 -uint8_t et4000w32p_mmu_read(uint32_t addr) 56.149 +uint8_t et4000w32p_mmu_read(uint32_t addr, void *priv) 56.150 { 56.151 int bank; 56.152 uint8_t temp; 56.153 @@ -482,6 +483,7 @@ 56.154 } 56.155 return 0xFF; 56.156 } 56.157 + return 0xff; 56.158 } 56.159 56.160 int et4000w32_max_x[8]={0,0,4,8,16,32,64,0x70000000}; 56.161 @@ -846,7 +848,7 @@ 56.162 svga_hwcursor_latch.addr += 16; 56.163 } 56.164 56.165 -uint8_t et4000w32p_pci_read(int func, int addr) 56.166 +uint8_t et4000w32p_pci_read(int func, int addr, void *priv) 56.167 { 56.168 pclog("ET4000 PCI read %08X\n", addr); 56.169 switch (addr) 56.170 @@ -880,7 +882,7 @@ 56.171 return 0; 56.172 } 56.173 56.174 -void et4000w32p_pci_write(int func, int addr, uint8_t val) 56.175 +void et4000w32p_pci_write(int func, int addr, uint8_t val, void *priv) 56.176 { 56.177 switch (addr) 56.178 { 56.179 @@ -893,16 +895,16 @@ 56.180 svga_recalctimings_ex = et4000w32p_recalctimings; 56.181 svga_hwcursor_draw = et4000w32p_cursor_draw; 56.182 56.183 - io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL); 56.184 - io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL); 56.185 - io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL); 56.186 - io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL); 56.187 - io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL); 56.188 - io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL); 56.189 - io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL); 56.190 - io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL); 56.191 + io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); 56.192 + io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); 56.193 + io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); 56.194 + io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); 56.195 + io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); 56.196 + io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); 56.197 + io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); 56.198 + io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL); 56.199 56.200 - pci_add(et4000w32p_pci_read, et4000w32p_pci_write); 56.201 + pci_add(et4000w32p_pci_read, et4000w32p_pci_write, NULL); 56.202 56.203 svga_vram_limit = 2 << 20; /*2mb - chip supports 4mb but can't map both 4mb linear frame buffer and accelerator registers*/ 56.204
57.1 --- a/src/vid_hercules.c Sun Apr 21 14:54:35 2013 +0100 57.2 +++ b/src/vid_hercules.c Mon May 27 17:46:42 2013 +0100 57.3 @@ -1,15 +1,17 @@ 57.4 /*Hercules emulation*/ 57.5 #include "ibm.h" 57.6 +#include "mem.h" 57.7 +#include "timer.h" 57.8 #include "video.h" 57.9 57.10 void hercules_recalctimings(); 57.11 -void hercules_write(uint32_t addr, uint8_t val); 57.12 -uint8_t hercules_read(uint32_t addr); 57.13 +void hercules_write(uint32_t addr, uint8_t val, void *priv); 57.14 +uint8_t hercules_read(uint32_t addr, void *priv); 57.15 57.16 static uint8_t hercules_ctrl, hercules_ctrl2, hercules_stat; 57.17 uint8_t crtcm[32],crtcmreg; 57.18 57.19 -void hercules_out(uint16_t addr, uint8_t val) 57.20 +void hercules_out(uint16_t addr, uint8_t val, void *priv) 57.21 { 57.22 // pclog("Herc out %04X %02X\n",addr,val); 57.23 switch (addr) 57.24 @@ -37,7 +39,7 @@ 57.25 } 57.26 } 57.27 57.28 -uint8_t hercules_in(uint16_t addr) 57.29 +uint8_t hercules_in(uint16_t addr, void *priv) 57.30 { 57.31 // pclog("Herc in %04X %02X %04X:%04X %04X\n",addr,(hercules_stat & 0xF) | ((hercules_stat & 8) << 4),CS,pc,CX); 57.32 switch (addr) 57.33 @@ -49,33 +51,37 @@ 57.34 case 0x3BA: 57.35 return (hercules_stat & 0xF) | ((hercules_stat & 8) << 4); 57.36 } 57.37 + return 0xff; 57.38 } 57.39 57.40 -void hercules_write(uint32_t addr, uint8_t val) 57.41 +void hercules_write(uint32_t addr, uint8_t val, void *priv) 57.42 { 57.43 // pclog("Herc write %08X %02X\n",addr,val); 57.44 vram[addr&0xFFFF]=val; 57.45 } 57.46 57.47 -uint8_t hercules_read(uint32_t addr) 57.48 +uint8_t hercules_read(uint32_t addr, void *priv) 57.49 { 57.50 return vram[addr&0xFFFF]; 57.51 } 57.52 57.53 void hercules_recalctimings() 57.54 { 57.55 + double _dispontime, _dispofftime; 57.56 disptime=crtc[0]+1; 57.57 - dispontime=crtc[1]; 57.58 - dispofftime=disptime-dispontime; 57.59 - dispontime*=MDACONST; 57.60 - dispofftime*=MDACONST; 57.61 + _dispontime=crtc[1]; 57.62 + _dispofftime=disptime-_dispontime; 57.63 + _dispontime*=MDACONST; 57.64 + _dispofftime*=MDACONST; 57.65 + dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); 57.66 + dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); 57.67 } 57.68 57.69 int mdacols[256][2][2]; 57.70 57.71 static int linepos,displine; 57.72 static int vc,sc; 57.73 -static uint16_t ma,maback,ca; 57.74 +static uint16_t ma,maback; 57.75 static int con,coff,cursoron; 57.76 static int cgadispon,cgablink; 57.77 static int vsynctime,vadj; 57.78 @@ -87,9 +93,8 @@ 57.79 int x,c; 57.80 int oldvc; 57.81 uint8_t chr,attr; 57.82 - uint16_t dat,dat2,dat3,dat4; 57.83 + uint16_t dat; 57.84 int cols[4]; 57.85 - int col; 57.86 int oldsc; 57.87 int blink; 57.88 if (!linepos) 57.89 @@ -264,7 +269,7 @@ 57.90 57.91 int hercules_init() 57.92 { 57.93 - mem_sethandler(0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL); 57.94 + mem_sethandler(0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL); 57.95 return 0; 57.96 } 57.97
58.1 --- a/src/vid_mda.c Sun Apr 21 14:54:35 2013 +0100 58.2 +++ b/src/vid_mda.c Mon May 27 17:46:42 2013 +0100 58.3 @@ -1,5 +1,8 @@ 58.4 /*MDA emulation*/ 58.5 #include "ibm.h" 58.6 +#include "io.h" 58.7 +#include "mem.h" 58.8 +#include "timer.h" 58.9 #include "video.h" 58.10 58.11 void mda_recalctimings(); 58.12 @@ -7,7 +10,7 @@ 58.13 static uint8_t mda_ctrl,mda_stat; 58.14 uint8_t crtcm[32],crtcmreg; 58.15 58.16 -void mda_out(uint16_t addr, uint8_t val) 58.17 +void mda_out(uint16_t addr, uint8_t val, void *priv) 58.18 { 58.19 switch (addr) 58.20 { 58.21 @@ -29,7 +32,7 @@ 58.22 } 58.23 } 58.24 58.25 -uint8_t mda_in(uint16_t addr) 58.26 +uint8_t mda_in(uint16_t addr, void *priv) 58.27 { 58.28 switch (addr) 58.29 { 58.30 @@ -40,32 +43,36 @@ 58.31 case 0x3BA: 58.32 return mda_stat | 0xF0; 58.33 } 58.34 + return 0xff; 58.35 } 58.36 58.37 -void mda_write(uint32_t addr, uint8_t val) 58.38 +void mda_write(uint32_t addr, uint8_t val, void *priv) 58.39 { 58.40 vram[addr&0xFFF]=val; 58.41 } 58.42 58.43 -uint8_t mda_read(uint32_t addr) 58.44 +uint8_t mda_read(uint32_t addr, void *priv) 58.45 { 58.46 return vram[addr&0xFFF]; 58.47 } 58.48 58.49 void mda_recalctimings() 58.50 { 58.51 + double _dispontime, _dispofftime; 58.52 disptime=crtc[0]+1; 58.53 - dispontime=crtc[1]; 58.54 - dispofftime=disptime-dispontime; 58.55 - dispontime*=MDACONST; 58.56 - dispofftime*=MDACONST; 58.57 + _dispontime=crtc[1]; 58.58 + _dispofftime=disptime-_dispontime; 58.59 + _dispontime*=MDACONST; 58.60 + _dispofftime*=MDACONST; 58.61 + dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); 58.62 + dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); 58.63 } 58.64 58.65 int mdacols[256][2][2]; 58.66 58.67 static int linepos,displine; 58.68 static int vc,sc; 58.69 -static uint16_t ma,maback,ca; 58.70 +static uint16_t ma,maback; 58.71 static int con,coff,cursoron; 58.72 static int cgadispon,cgablink; 58.73 static int vsynctime,vadj; 58.74 @@ -77,9 +84,7 @@ 58.75 int x,c; 58.76 int oldvc; 58.77 uint8_t chr,attr; 58.78 - uint16_t dat,dat2,dat3,dat4; 58.79 int cols[4]; 58.80 - int col; 58.81 int oldsc; 58.82 int blink; 58.83 if (!linepos) 58.84 @@ -227,7 +232,7 @@ 58.85 58.86 int mda_init() 58.87 { 58.88 - mem_sethandler(0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL); 58.89 + mem_sethandler(0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL); 58.90 return 0; 58.91 } 58.92
59.1 --- a/src/vid_olivetti_m24.c Sun Apr 21 14:54:35 2013 +0100 59.2 +++ b/src/vid_olivetti_m24.c Mon May 27 17:46:42 2013 +0100 59.3 @@ -1,12 +1,17 @@ 59.4 /*Olivetti M24 video emulation 59.5 Essentially double-res CGA*/ 59.6 #include "ibm.h" 59.7 +#include "io.h" 59.8 +#include "mem.h" 59.9 +#include "timer.h" 59.10 #include "video.h" 59.11 59.12 +void m24_recalctimings(); 59.13 + 59.14 static uint8_t m24_ctrl; 59.15 static uint32_t m24_base; 59.16 59.17 -void m24_out(uint16_t addr, uint8_t val) 59.18 +void m24_out(uint16_t addr, uint8_t val, void *priv) 59.19 { 59.20 uint8_t old; 59.21 switch (addr) 59.22 @@ -39,7 +44,7 @@ 59.23 } 59.24 } 59.25 59.26 -uint8_t m24_in(uint16_t addr) 59.27 +uint8_t m24_in(uint16_t addr, void *priv) 59.28 { 59.29 switch (addr) 59.30 { 59.31 @@ -55,35 +60,38 @@ 59.32 59.33 static uint8_t charbuffer[256]; 59.34 59.35 -void m24_write(uint32_t addr, uint8_t val) 59.36 +void m24_write(uint32_t addr, uint8_t val, void *priv) 59.37 { 59.38 vram[addr & 0x7FFF]=val; 59.39 charbuffer[ ((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val; 59.40 charbuffer[(((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val; 59.41 } 59.42 59.43 -uint8_t m24_read(uint32_t addr) 59.44 +uint8_t m24_read(uint32_t addr, void *priv) 59.45 { 59.46 return vram[addr & 0x7FFF]; 59.47 } 59.48 59.49 void m24_recalctimings() 59.50 { 59.51 + double _dispontime, _dispofftime; 59.52 if (cgamode & 1) 59.53 { 59.54 disptime = crtc[0] + 1; 59.55 - dispontime = crtc[1]; 59.56 + _dispontime = crtc[1]; 59.57 } 59.58 else 59.59 { 59.60 disptime = (crtc[0] + 1) << 1; 59.61 - dispontime = crtc[1] << 1; 59.62 + _dispontime = crtc[1] << 1; 59.63 } 59.64 - dispofftime = disptime - dispontime; 59.65 + _dispofftime = disptime - _dispontime; 59.66 // printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); 59.67 - dispontime *= CGACONST / 2; 59.68 - dispofftime *= CGACONST / 2; 59.69 + _dispontime *= CGACONST / 2; 59.70 + _dispofftime *= CGACONST / 2; 59.71 // printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); 59.72 + dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); 59.73 + dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); 59.74 } 59.75 59.76 static int linepos,displine; 59.77 @@ -92,7 +100,7 @@ 59.78 static int con,coff,cursoron,cgablink; 59.79 static int vsynctime,vadj; 59.80 static int m24_lineff = 0; 59.81 -static uint16_t ma,maback,ca; 59.82 +static uint16_t ma,maback; 59.83 59.84 void m24_poll() 59.85 { 59.86 @@ -101,7 +109,7 @@ 59.87 int x,c; 59.88 int oldvc; 59.89 uint8_t chr,attr; 59.90 - uint16_t dat,dat2,dat3,dat4; 59.91 + uint16_t dat,dat2; 59.92 int cols[4]; 59.93 int col; 59.94 int oldsc; 59.95 @@ -401,7 +409,7 @@ 59.96 59.97 int m24_init() 59.98 { 59.99 - mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL); 59.100 + mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL); 59.101 return 0; 59.102 } 59.103
60.1 --- a/src/vid_oti067.c Sun Apr 21 14:54:35 2013 +0100 60.2 +++ b/src/vid_oti067.c Mon May 27 17:46:42 2013 +0100 60.3 @@ -1,16 +1,19 @@ 60.4 /*Oak OTI067 emulation*/ 60.5 #include "ibm.h" 60.6 +#include "io.h" 60.7 #include "video.h" 60.8 #include "vid_svga.h" 60.9 60.10 static int oti067_index; 60.11 static uint8_t oti067_regs[32]; 60.12 60.13 -void oti067_out(uint16_t addr, uint8_t val) 60.14 +void oti067_out(uint16_t addr, uint8_t val, void *priv) 60.15 { 60.16 uint8_t old; 60.17 - 60.18 - if ((addr&0xFFF0) == 0x3B0) addr |= 0x20; 60.19 + 60.20 +// pclog("oti067_out : %04X %02X %02X %i\n", addr, val, ram[0x489], ins); 60.21 + 60.22 + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga_miscout&1)) addr ^= 0x60; 60.23 60.24 switch (addr) 60.25 { 60.26 @@ -46,28 +49,41 @@ 60.27 } 60.28 return; 60.29 } 60.30 - svga_out(addr,val); 60.31 + svga_out(addr, val, NULL); 60.32 } 60.33 60.34 -uint8_t oti067_in(uint16_t addr) 60.35 +uint8_t oti067_in(uint16_t addr, void *priv) 60.36 { 60.37 uint8_t temp; 60.38 60.39 - if ((addr&0xFFF0) == 0x3B0) addr |= 0x20; 60.40 +// if (addr != 0x3da && addr != 0x3ba) pclog("oti067_in : %04X ", addr); 60.41 + 60.42 + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga_miscout&1)) addr ^= 0x60; 60.43 60.44 switch (addr) 60.45 { 60.46 case 0x3D4: 60.47 - return crtcreg; 60.48 + temp = crtcreg; 60.49 + break; 60.50 case 0x3D5: 60.51 - return crtc[crtcreg]; 60.52 - case 0x3DE: return oti067_index|(2<<5); 60.53 + temp = crtc[crtcreg]; 60.54 + break; 60.55 + 60.56 + case 0x3DE: 60.57 + temp = oti067_index|(2<<5); 60.58 + break; 60.59 case 0x3DF: 60.60 - if (oti067_index==0x10) return 0x40; 60.61 - if (oti067_index==0xD) return oti067_regs[oti067_index]|0xC0; 60.62 - return oti067_regs[oti067_index]; 60.63 + if (oti067_index==0x10) temp = 0x18; 60.64 + else if (oti067_index==0xD) temp = oti067_regs[oti067_index]|0xC0; 60.65 + else temp = oti067_regs[oti067_index]; 60.66 + break; 60.67 + 60.68 + default: 60.69 + temp = svga_in(addr, NULL); 60.70 + break; 60.71 } 60.72 - return svga_in(addr); 60.73 +// if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,pc); 60.74 + return temp; 60.75 } 60.76 60.77 void oti067_recalctimings() 60.78 @@ -82,6 +98,8 @@ 60.79 svga_recalctimings_ex = oti067_recalctimings; 60.80 svga_vram_limit = 1 << 19; /*512kb*/ 60.81 vrammask = 0x7ffff; 60.82 + bpp = 8; 60.83 + svga_miscout = 1; 60.84 return svga_init(); 60.85 } 60.86
61.1 --- a/src/vid_paradise.c Sun Apr 21 14:54:35 2013 +0100 61.2 +++ b/src/vid_paradise.c Mon May 27 17:46:42 2013 +0100 61.3 @@ -4,12 +4,14 @@ 61.4 MegaPC uses W90C11A 61.5 */ 61.6 #include "ibm.h" 61.7 +#include "mem.h" 61.8 #include "video.h" 61.9 #include "vid_svga.h" 61.10 #include "vid_unk_ramdac.h" 61.11 61.12 -void paradise_write(uint32_t addr, uint8_t val); 61.13 -uint8_t paradise_read(uint32_t addr); 61.14 +void paradise_write(uint32_t addr, uint8_t val, void *priv); 61.15 +uint8_t paradise_read(uint32_t addr, void *priv); 61.16 +void paradise_remap(); 61.17 61.18 enum 61.19 { 61.20 @@ -21,7 +23,7 @@ 61.21 61.22 static uint32_t paradise_bank_r[4], paradise_bank_w[4]; 61.23 61.24 -void paradise_out(uint16_t addr, uint8_t val) 61.25 +void paradise_out(uint16_t addr, uint8_t val, void *priv) 61.26 { 61.27 uint8_t old; 61.28 61.29 @@ -52,21 +54,21 @@ 61.30 { 61.31 if ((gdcreg[6] & 0xc) != (val & 0xc)) 61.32 { 61.33 - mem_removehandler(0xa0000, 0x20000, paradise_read, NULL, NULL, svga_write, NULL, NULL); 61.34 + mem_removehandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL); 61.35 // pclog("Write mapping %02X\n", val); 61.36 switch (val&0xC) 61.37 { 61.38 case 0x0: /*128k at A0000*/ 61.39 - mem_sethandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL); 61.40 + mem_sethandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL); 61.41 break; 61.42 case 0x4: /*64k at A0000*/ 61.43 - mem_sethandler(0xa0000, 0x10000, paradise_read, NULL, NULL, paradise_write, NULL, NULL); 61.44 + mem_sethandler(0xa0000, 0x10000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL); 61.45 break; 61.46 case 0x8: /*32k at B0000*/ 61.47 - mem_sethandler(0xb0000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL); 61.48 + mem_sethandler(0xb0000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL); 61.49 break; 61.50 case 0xC: /*32k at B8000*/ 61.51 - mem_sethandler(0xb8000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL); 61.52 + mem_sethandler(0xb8000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL, NULL); 61.53 break; 61.54 } 61.55 } 61.56 @@ -114,13 +116,11 @@ 61.57 } 61.58 break; 61.59 } 61.60 - svga_out(addr,val); 61.61 + svga_out(addr, val, NULL); 61.62 } 61.63 61.64 -uint8_t paradise_in(uint16_t addr) 61.65 +uint8_t paradise_in(uint16_t addr, void *priv) 61.66 { 61.67 - uint8_t temp; 61.68 - 61.69 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 61.70 61.71 // if (addr != 0x3da) pclog("Paradise in %04X\n", addr); 61.72 @@ -157,7 +157,7 @@ 61.73 return 0xff; 61.74 return crtc[crtcreg]; 61.75 } 61.76 - return svga_in(addr); 61.77 + return svga_in(addr, NULL); 61.78 } 61.79 61.80 void paradise_remap() 61.81 @@ -185,8 +185,8 @@ 61.82 // pclog("Remap 3\n"); 61.83 paradise_bank_r[0] = paradise_bank_w[0] = (gdcreg[0xa] & 0x7f) << 12; 61.84 paradise_bank_r[1] = paradise_bank_w[1] = ((gdcreg[0xa] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); 61.85 - paradise_bank_w[2] = paradise_bank_w[2] = (gdcreg[0x9] & 0x7f) << 12; 61.86 - paradise_bank_w[3] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); 61.87 + paradise_bank_r[2] = paradise_bank_w[2] = (gdcreg[0x9] & 0x7f) << 12; 61.88 + paradise_bank_r[3] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000); 61.89 } 61.90 } 61.91 else 61.92 @@ -207,20 +207,20 @@ 61.93 61.94 #define egacycles 1 61.95 #define egacycles2 1 61.96 -void paradise_write(uint32_t addr, uint8_t val) 61.97 +void paradise_write(uint32_t addr, uint8_t val, void *priv) 61.98 { 61.99 // pclog("paradise_write : %05X %02X ", addr, val); 61.100 addr = (addr & 0x7fff) + paradise_bank_w[(addr >> 15) & 3]; 61.101 // pclog("%08X\n", addr); 61.102 - svga_write_linear(addr, val); 61.103 + svga_write_linear(addr, val, priv); 61.104 } 61.105 61.106 -uint8_t paradise_read(uint32_t addr) 61.107 +uint8_t paradise_read(uint32_t addr, void *priv) 61.108 { 61.109 // pclog("paradise_read : %05X ", addr); 61.110 addr = (addr & 0x7fff) + paradise_bank_r[(addr >> 15) & 3]; 61.111 // pclog("%08X\n", addr); 61.112 - return svga_read_linear(addr); 61.113 + return svga_read_linear(addr, priv); 61.114 } 61.115 61.116 int paradise_init()
62.1 --- a/src/vid_pc1512.c Sun Apr 21 14:54:35 2013 +0100 62.2 +++ b/src/vid_pc1512.c Mon May 27 17:46:42 2013 +0100 62.3 @@ -8,6 +8,9 @@ 62.4 and 46 cycles. PCem currently always uses the lower number.*/ 62.5 62.6 #include "ibm.h" 62.7 +#include "io.h" 62.8 +#include "mem.h" 62.9 +#include "timer.h" 62.10 #include "video.h" 62.11 #include "vid_cga.h" 62.12 62.13 @@ -15,7 +18,7 @@ 62.14 62.15 void pc1512_recalctimings(); 62.16 62.17 -void pc1512_out(uint16_t addr, uint8_t val) 62.18 +void pc1512_out(uint16_t addr, uint8_t val, void *priv) 62.19 { 62.20 uint8_t old; 62.21 // pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc); 62.22 @@ -59,7 +62,7 @@ 62.23 } 62.24 } 62.25 62.26 -uint8_t pc1512_in(uint16_t addr) 62.27 +uint8_t pc1512_in(uint16_t addr, void *priv) 62.28 { 62.29 // pclog("PC1512 in %04X %02X %04X:%04X\n",addr,CS,pc); 62.30 switch (addr) 62.31 @@ -74,7 +77,7 @@ 62.32 return 0xFF; 62.33 } 62.34 62.35 -void pc1512_write(uint32_t addr, uint8_t val) 62.36 +void pc1512_write(uint32_t addr, uint8_t val, void *priv) 62.37 { 62.38 /* if (CS==0x023E && pc==0x524E) 62.39 { 62.40 @@ -95,7 +98,7 @@ 62.41 vram[addr]=val; 62.42 } 62.43 62.44 -uint8_t pc1512_read(uint32_t addr) 62.45 +uint8_t pc1512_read(uint32_t addr, void *priv) 62.46 { 62.47 // pclog("PC1512 read %08X %02X %01X\n",addr,cgamode&0x12,pc1512_plane_read); 62.48 cycles-=12; 62.49 @@ -111,32 +114,23 @@ 62.50 static int cgadispon; 62.51 static int con,coff,cursoron,cgablink; 62.52 static int vsynctime,vadj; 62.53 -static uint16_t ma,maback,ca; 62.54 - 62.55 -static int ntsc_col[8][8]= 62.56 -{ 62.57 - {0,0,0,0,0,0,0,0}, /*Black*/ 62.58 - {0,0,1,1,1,1,0,0}, /*Blue*/ 62.59 - {1,0,0,0,0,1,1,1}, /*Green*/ 62.60 - {0,0,0,0,1,1,1,1}, /*Cyan*/ 62.61 - {1,1,1,1,0,0,0,0}, /*Red*/ 62.62 - {0,1,1,1,1,0,0,0}, /*Magenta*/ 62.63 - {1,1,0,0,0,0,1,1}, /*Yellow*/ 62.64 - {1,1,1,1,1,1,1,1} /*White*/ 62.65 -}; 62.66 +static uint16_t ma,maback; 62.67 62.68 int i_filt[8],q_filt[8]; 62.69 62.70 62.71 void pc1512_recalctimings() 62.72 { 62.73 + double _dispontime, _dispofftime; 62.74 disptime = 128; /*Fixed on PC1512*/ 62.75 - dispontime = 80; 62.76 - dispofftime=disptime-dispontime; 62.77 + _dispontime = 80; 62.78 + _dispofftime=disptime-_dispontime; 62.79 // printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); 62.80 - dispontime*=CGACONST; 62.81 - dispofftime*=CGACONST; 62.82 + _dispontime*=CGACONST; 62.83 + _dispofftime*=CGACONST; 62.84 // printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); 62.85 + dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); 62.86 + dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); 62.87 } 62.88 62.89 void pc1512_poll() 62.90 @@ -417,7 +411,7 @@ 62.91 62.92 int pc1512_init() 62.93 { 62.94 - mem_sethandler(0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL); 62.95 + mem_sethandler(0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, NULL); 62.96 return 0; 62.97 } 62.98
63.1 --- a/src/vid_pc1640.c Sun Apr 21 14:54:35 2013 +0100 63.2 +++ b/src/vid_pc1640.c Mon May 27 17:46:42 2013 +0100 63.3 @@ -1,54 +1,56 @@ 63.4 /*PC1640 video emulation. 63.5 Mostly standard EGA, but with CGA & Hercules emulation*/ 63.6 #include "ibm.h" 63.7 +#include "io.h" 63.8 +#include "mem.h" 63.9 #include "video.h" 63.10 #include "vid_cga.h" 63.11 #include "vid_ega.h" 63.12 63.13 static int pc1640_cga=1; 63.14 63.15 -void pc1640_out(uint16_t addr, uint8_t val) 63.16 +void pc1640_out(uint16_t addr, uint8_t val, void *priv) 63.17 { 63.18 switch (addr) 63.19 { 63.20 case 0x3DB: 63.21 pc1640_cga=val&0x40; 63.22 - mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL); 63.23 - mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL); 63.24 + mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); 63.25 + mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL); 63.26 if (pc1640_cga) 63.27 - mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL); 63.28 + mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL); 63.29 else 63.30 { 63.31 switch (gdcreg[6] & 0xC) 63.32 { 63.33 case 0x0: /*128k at A0000*/ 63.34 - mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL); 63.35 + mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); 63.36 break; 63.37 case 0x4: /*64k at A0000*/ 63.38 - mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL); 63.39 + mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); 63.40 break; 63.41 case 0x8: /*32k at B0000*/ 63.42 - mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL); 63.43 + mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); 63.44 break; 63.45 case 0xC: /*32k at B8000*/ 63.46 - mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL); 63.47 + mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL); 63.48 break; 63.49 } 63.50 } 63.51 pclog("3DB write %02X\n", val); 63.52 return; 63.53 } 63.54 - if (pc1640_cga) cga_out(addr,val); 63.55 - else ega_out(addr,val); 63.56 + if (pc1640_cga) cga_out(addr, val, NULL); 63.57 + else ega_out(addr, val, NULL); 63.58 } 63.59 63.60 -uint8_t pc1640_in(uint16_t addr) 63.61 +uint8_t pc1640_in(uint16_t addr, void *priv) 63.62 { 63.63 switch (addr) 63.64 { 63.65 } 63.66 - if (pc1640_cga) return cga_in(addr); 63.67 - else return ega_in(addr); 63.68 + if (pc1640_cga) return cga_in(addr, NULL); 63.69 + else return ega_in(addr, NULL); 63.70 } 63.71 63.72 void pc1640_recalctimings() 63.73 @@ -69,7 +71,7 @@ 63.74 63.75 pc1640_cga = 1; 63.76 63.77 - mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL); 63.78 + mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL); 63.79 63.80 return r; 63.81 }
64.1 --- a/src/vid_pc200.c Sun Apr 21 14:54:35 2013 +0100 64.2 +++ b/src/vid_pc200.c Mon May 27 17:46:42 2013 +0100 64.3 @@ -2,12 +2,14 @@ 64.4 CGA with some NMI stuff. But we don't need that as it's only used for TV and 64.5 LCD displays, and we're emulating a CRT*/ 64.6 #include "ibm.h" 64.7 +#include "io.h" 64.8 +#include "mem.h" 64.9 #include "video.h" 64.10 #include "vid_cga.h" 64.11 64.12 uint8_t pc200_3dd, pc200_3de, pc200_3df; 64.13 64.14 -void pc200_out(uint16_t addr, uint8_t val) 64.15 +void pc200_out(uint16_t addr, uint8_t val, void *priv) 64.16 { 64.17 uint8_t old; 64.18 switch (addr) 64.19 @@ -48,10 +50,10 @@ 64.20 if (val&0x80) pc200_3dd|=0x40; 64.21 return; 64.22 } 64.23 - cga_out(addr,val); 64.24 + cga_out(addr, val, NULL); 64.25 } 64.26 64.27 -uint8_t pc200_in(uint16_t addr) 64.28 +uint8_t pc200_in(uint16_t addr, void *priv) 64.29 { 64.30 uint8_t temp; 64.31 switch (addr) 64.32 @@ -70,12 +72,12 @@ 64.33 case 0x3DF: 64.34 return pc200_3df; 64.35 } 64.36 - return cga_in(addr); 64.37 + return cga_in(addr, NULL); 64.38 } 64.39 64.40 int pc200_init() 64.41 { 64.42 - mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL); 64.43 + mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL); 64.44 return cga_init(); 64.45 } 64.46
65.1 --- a/src/vid_s3.c Sun Apr 21 14:54:35 2013 +0100 65.2 +++ b/src/vid_s3.c Mon May 27 17:46:42 2013 +0100 65.3 @@ -1,17 +1,19 @@ 65.4 /*S3 emulation*/ 65.5 #include "ibm.h" 65.6 +#include "io.h" 65.7 #include "mem.h" 65.8 #include "pci.h" 65.9 #include "video.h" 65.10 #include "vid_svga.h" 65.11 +#include "vid_svga_render.h" 65.12 #include "vid_sdac_ramdac.h" 65.13 65.14 void s3_updatemapping(); 65.15 65.16 -void s3_accel_write(uint32_t addr, uint8_t val); 65.17 -void s3_accel_write_w(uint32_t addr, uint16_t val); 65.18 -void s3_accel_write_l(uint32_t addr, uint32_t val); 65.19 -uint8_t s3_accel_read(uint32_t addr); 65.20 +void s3_accel_write(uint32_t addr, uint8_t val, void *priv); 65.21 +void s3_accel_write_w(uint32_t addr, uint16_t val, void *priv); 65.22 +void s3_accel_write_l(uint32_t addr, uint32_t val, void *priv); 65.23 +uint8_t s3_accel_read(uint32_t addr, void *priv); 65.24 65.25 static uint8_t s3_bank; 65.26 static uint8_t s3_ma_ext; 65.27 @@ -20,7 +22,7 @@ 65.28 65.29 static uint8_t s3_id, s3_id_ext; 65.30 65.31 -void s3_out(uint16_t addr, uint8_t val) 65.32 +void s3_out(uint16_t addr, uint8_t val, void *priv) 65.33 { 65.34 uint8_t old; 65.35 65.36 @@ -40,7 +42,7 @@ 65.37 65.38 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 65.39 // pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); 65.40 - sdac_ramdac_out(addr,val); 65.41 + sdac_ramdac_out(addr, val, NULL); 65.42 return; 65.43 65.44 case 0x3D4: 65.45 @@ -141,13 +143,11 @@ 65.46 } 65.47 break; 65.48 } 65.49 - svga_out(addr,val); 65.50 + svga_out(addr, val, NULL); 65.51 } 65.52 65.53 -uint8_t s3_in(uint16_t addr) 65.54 +uint8_t s3_in(uint16_t addr, void *priv) 65.55 { 65.56 - uint8_t temp; 65.57 - 65.58 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 65.59 65.60 // if (addr != 0x3da) pclog("S3 in %04X\n", addr); 65.61 @@ -155,7 +155,7 @@ 65.62 { 65.63 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 65.64 // pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); 65.65 - return sdac_ramdac_in(addr); 65.66 + return sdac_ramdac_in(addr, NULL); 65.67 65.68 case 0x3D4: 65.69 return crtcreg; 65.70 @@ -174,7 +174,7 @@ 65.71 } 65.72 return crtc[crtcreg]; 65.73 } 65.74 - return svga_in(addr); 65.75 + return svga_in(addr, NULL); 65.76 } 65.77 65.78 void s3_recalctimings() 65.79 @@ -182,7 +182,27 @@ 65.80 // pclog("recalctimings\n"); 65.81 svga_ma |= (s3_ma_ext << 16); 65.82 // pclog("SVGA_MA %08X\n", svga_ma); 65.83 - if (gdcreg[5] & 0x40) svga_lowres = !(crtc[0x3a] & 0x10); 65.84 + if ((gdcreg[5] & 0x40) && (crtc[0x3a] & 0x10)) 65.85 + { 65.86 + switch (bpp) 65.87 + { 65.88 + case 8: 65.89 + svga_render = svga_render_8bpp_highres; 65.90 + break; 65.91 + case 15: 65.92 + svga_render = svga_render_15bpp_highres; 65.93 + break; 65.94 + case 16: 65.95 + svga_render = svga_render_16bpp_highres; 65.96 + break; 65.97 + case 24: 65.98 + svga_render = svga_render_24bpp_highres; 65.99 + break; 65.100 + case 32: 65.101 + svga_render = svga_render_32bpp_highres; 65.102 + break; 65.103 + } 65.104 + } 65.105 if (crtc[0x5d] & 0x01) svga_htotal += 0x100; 65.106 if (crtc[0x5d] & 0x02) svga_hdisp += 0x100; 65.107 if (crtc[0x5e] & 0x01) svga_vtotal += 0x400; 65.108 @@ -201,25 +221,25 @@ 65.109 static uint32_t s3_linear_base = 0, s3_linear_size = 0; 65.110 void s3_updatemapping() 65.111 { 65.112 - 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); 65.113 + 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); 65.114 65.115 // video_write_a000_w = video_write_a000_l = NULL; 65.116 65.117 - mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 65.118 + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 65.119 // pclog("Update mapping - bank %02X ", gdcreg[6] & 0xc); 65.120 switch (gdcreg[6] & 0xc) /*Banked framebuffer*/ 65.121 { 65.122 case 0x0: /*128k at A0000*/ 65.123 - mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 65.124 + mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 65.125 break; 65.126 case 0x4: /*64k at A0000*/ 65.127 - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 65.128 + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 65.129 break; 65.130 case 0x8: /*32k at B0000*/ 65.131 - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 65.132 + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 65.133 break; 65.134 case 0xC: /*32k at B8000*/ 65.135 - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 65.136 + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 65.137 break; 65.138 } 65.139 65.140 @@ -246,15 +266,15 @@ 65.141 // pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]); 65.142 // pclog("Linear framebuffer at %08X size %08X\n", linear_base, linear_size); 65.143 if (s3_linear_base == 0xa0000) 65.144 - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 65.145 + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 65.146 else 65.147 - 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); 65.148 + 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); 65.149 } 65.150 65.151 // pclog("Memory mapped IO %02X\n", crtc[0x53] & 0x10); 65.152 if (crtc[0x53] & 0x10) /*Memory mapped IO*/ 65.153 { 65.154 - mem_sethandler(0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l); 65.155 + mem_sethandler(0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, NULL); 65.156 /* video_write_a000 = s3_accel_write; 65.157 video_write_a000_w = s3_accel_write_w; 65.158 video_write_a000_l = s3_accel_write_l; 65.159 @@ -299,7 +319,7 @@ 65.160 65.161 void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat); 65.162 65.163 -void s3_accel_out(uint16_t port, uint8_t val) 65.164 +void s3_accel_out(uint16_t port, uint8_t val, void *priv) 65.165 { 65.166 // pclog("Accel out %04X %02X\n", port, val); 65.167 switch (port) 65.168 @@ -503,7 +523,7 @@ 65.169 } 65.170 } 65.171 65.172 -void s3_accel_out_w(uint16_t port, uint16_t val) 65.173 +void s3_accel_out_w(uint16_t port, uint16_t val, void *priv) 65.174 { 65.175 // pclog("Accel out w %04X %04X\n", port, val); 65.176 if (s3_accel.cmd & 0x100) 65.177 @@ -519,7 +539,7 @@ 65.178 } 65.179 } 65.180 65.181 -void s3_accel_out_l(uint16_t port, uint32_t val) 65.182 +void s3_accel_out_l(uint16_t port, uint32_t val, void *priv) 65.183 { 65.184 // pclog("Accel out l %04X %08X\n", port, val); 65.185 if (s3_accel.cmd & 0x100) 65.186 @@ -563,7 +583,7 @@ 65.187 } 65.188 } 65.189 65.190 -uint8_t s3_accel_in(uint16_t port) 65.191 +uint8_t s3_accel_in(uint16_t port, void *priv) 65.192 { 65.193 int temp; 65.194 // pclog("Accel in %04X\n", port); 65.195 @@ -682,11 +702,11 @@ 65.196 return 0; 65.197 } 65.198 65.199 -void s3_accel_write(uint32_t addr, uint8_t val) 65.200 +void s3_accel_write(uint32_t addr, uint8_t val, void *priv) 65.201 { 65.202 // pclog("Write S3 accel %08X %02X\n", addr, val); 65.203 if (addr & 0x8000) 65.204 - s3_accel_out(addr & 0xffff, val); 65.205 + s3_accel_out(addr & 0xffff, val, priv); 65.206 else 65.207 { 65.208 if (s3_accel.cmd & 0x100) 65.209 @@ -699,13 +719,13 @@ 65.210 } 65.211 } 65.212 65.213 -void s3_accel_write_w(uint32_t addr, uint16_t val) 65.214 +void s3_accel_write_w(uint32_t addr, uint16_t val, void *priv) 65.215 { 65.216 // pclog("Write S3 accel w %08X %04X\n", addr, val); 65.217 if (addr & 0x8000) 65.218 { 65.219 - s3_accel_out( addr & 0xffff, val); 65.220 - s3_accel_out((addr & 0xffff) + 1, val >> 8); 65.221 + s3_accel_out( addr & 0xffff, val, priv); 65.222 + s3_accel_out((addr & 0xffff) + 1, val >> 8, priv); 65.223 } 65.224 else 65.225 { 65.226 @@ -723,15 +743,15 @@ 65.227 } 65.228 } 65.229 65.230 -void s3_accel_write_l(uint32_t addr, uint32_t val) 65.231 +void s3_accel_write_l(uint32_t addr, uint32_t val, void *priv) 65.232 { 65.233 // pclog("Write S3 accel l %08X %08X\n", addr, val); 65.234 if (addr & 0x8000) 65.235 { 65.236 - s3_accel_out( addr & 0xffff, val); 65.237 - s3_accel_out((addr & 0xffff) + 1, val >> 8); 65.238 - s3_accel_out((addr & 0xffff) + 2, val >> 16); 65.239 - s3_accel_out((addr & 0xffff) + 3, val >> 24); 65.240 + s3_accel_out( addr & 0xffff, val, priv); 65.241 + s3_accel_out((addr & 0xffff) + 1, val >> 8, priv); 65.242 + s3_accel_out((addr & 0xffff) + 2, val >> 16, priv); 65.243 + s3_accel_out((addr & 0xffff) + 3, val >> 24, priv); 65.244 } 65.245 else 65.246 { 65.247 @@ -777,11 +797,11 @@ 65.248 } 65.249 } 65.250 65.251 -uint8_t s3_accel_read(uint32_t addr) 65.252 +uint8_t s3_accel_read(uint32_t addr, void *priv) 65.253 { 65.254 // pclog("Read S3 accel %08X\n", addr); 65.255 if (addr & 0x8000) 65.256 - return s3_accel_in(addr & 0xffff); 65.257 + return s3_accel_in(addr & 0xffff, priv); 65.258 return 0; 65.259 } 65.260 65.261 @@ -828,12 +848,8 @@ 65.262 65.263 void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat) 65.264 { 65.265 - uint32_t dest, destbak; 65.266 - int sx, sy, cx, cy; 65.267 - int x, y; 65.268 uint32_t src_dat, dest_dat; 65.269 int frgd_mix, bkgd_mix; 65.270 - int mix; 65.271 int clip_t = s3_accel.multifunc[1] & 0xfff; 65.272 int clip_l = s3_accel.multifunc[2] & 0xfff; 65.273 int clip_b = s3_accel.multifunc[3] & 0xfff; 65.274 @@ -1390,6 +1406,7 @@ 65.275 int xx; 65.276 int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff; 65.277 65.278 + pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y); 65.279 for (x = 0; x < 64; x += 16) 65.280 { 65.281 dat[0] = (vram[svga_hwcursor_latch.addr] << 8) | vram[svga_hwcursor_latch.addr + 1]; 65.282 @@ -1414,9 +1431,9 @@ 65.283 } 65.284 65.285 65.286 -uint8_t s3_pci_read(int func, int addr) 65.287 +uint8_t s3_pci_read(int func, int addr, void *priv) 65.288 { 65.289 - pclog("S3 PCI read %08X\n", addr); 65.290 +// pclog("S3 PCI read %08X\n", addr); 65.291 switch (addr) 65.292 { 65.293 case 0x00: return 0x33; /*'S3'*/ 65.294 @@ -1448,7 +1465,7 @@ 65.295 return 0; 65.296 } 65.297 65.298 -void s3_pci_write(int func, int addr, uint8_t val) 65.299 +void s3_pci_write(int func, int addr, uint8_t val, void *priv) 65.300 { 65.301 switch (addr) 65.302 { 65.303 @@ -1482,28 +1499,28 @@ 65.304 65.305 vrammask = 0x3fffff; 65.306 65.307 - io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.308 - io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.309 - io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.310 - io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.311 - io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.312 - io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.313 - io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.314 - io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.315 - io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.316 - io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.317 - io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.318 - io_sethandler(0xa2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.319 - io_sethandler(0xa6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.320 - io_sethandler(0xaae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.321 - io_sethandler(0xaee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.322 - io_sethandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.323 - io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.324 - io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.325 - io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL); 65.326 - io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l); 65.327 + io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.328 + io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.329 + io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.330 + io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.331 + io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.332 + io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.333 + io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.334 + io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.335 + io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.336 + io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.337 + io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.338 + io_sethandler(0xa2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.339 + io_sethandler(0xa6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.340 + io_sethandler(0xaae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.341 + io_sethandler(0xaee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.342 + io_sethandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.343 + io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.344 + io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.345 + io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, NULL); 65.346 + io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, NULL); 65.347 65.348 - pci_add(s3_pci_read, s3_pci_write); 65.349 + pci_add(s3_pci_read, s3_pci_write, NULL); 65.350 65.351 svga_vram_limit = 4 << 20; /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/ 65.352 return svga_init();
66.1 --- a/src/vid_sdac_ramdac.c Sun Apr 21 14:54:35 2013 +0100 66.2 +++ b/src/vid_sdac_ramdac.c Mon May 27 17:46:42 2013 +0100 66.3 @@ -15,9 +15,8 @@ 66.4 int rs2; 66.5 } sdac_ramdac; 66.6 66.7 -void sdac_ramdac_out(uint16_t addr, uint8_t val) 66.8 +void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv) 66.9 { 66.10 - int didwrite; 66.11 // /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i\n",addr,val,sdac_ramdac.magic_count,CS,pc, sdac_ramdac.rs2); 66.12 switch (addr) 66.13 { 66.14 @@ -68,10 +67,10 @@ 66.15 } 66.16 break; 66.17 } 66.18 - svga_out(addr,val); 66.19 + svga_out(addr, val, NULL); 66.20 } 66.21 66.22 -uint8_t sdac_ramdac_in(uint16_t addr) 66.23 +uint8_t sdac_ramdac_in(uint16_t addr, void *priv) 66.24 { 66.25 uint8_t temp; 66.26 // /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, sdac_ramdac.rs2); 66.27 @@ -128,7 +127,7 @@ 66.28 } 66.29 break; 66.30 } 66.31 - return svga_in(addr); 66.32 + return svga_in(addr, NULL); 66.33 } 66.34 66.35 float sdac_getclock(int clock)
67.1 --- a/src/vid_sdac_ramdac.h Sun Apr 21 14:54:35 2013 +0100 67.2 +++ b/src/vid_sdac_ramdac.h Mon May 27 17:46:42 2013 +0100 67.3 @@ -1,4 +1,4 @@ 67.4 -void sdac_ramdac_out(uint16_t addr, uint8_t val); 67.5 -uint8_t sdac_ramdac_in(uint16_t addr); 67.6 +void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv); 67.7 +uint8_t sdac_ramdac_in(uint16_t addr, void *priv); 67.8 67.9 float sdac_getclock(int clock);
68.1 --- a/src/vid_stg_ramdac.c Sun Apr 21 14:54:35 2013 +0100 68.2 +++ b/src/vid_stg_ramdac.c Mon May 27 17:46:42 2013 +0100 68.3 @@ -15,7 +15,7 @@ 68.4 int stg_state_read[2][8]={{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; 68.5 int stg_state_write[8]={0,0,0,0,0,6,7,7}; 68.6 68.7 -void stg_ramdac_out(uint16_t addr, uint8_t val) 68.8 +void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv) 68.9 { 68.10 int didwrite; 68.11 //if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc); 68.12 @@ -64,10 +64,10 @@ 68.13 stg_ramdac.magic_count=0; 68.14 break; 68.15 } 68.16 - svga_out(addr,val); 68.17 + svga_out(addr, val, NULL); 68.18 } 68.19 68.20 -uint8_t stg_ramdac_in(uint16_t addr) 68.21 +uint8_t stg_ramdac_in(uint16_t addr, void *priv) 68.22 { 68.23 uint8_t temp; 68.24 //if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc); 68.25 @@ -100,5 +100,5 @@ 68.26 stg_ramdac.magic_count=0; 68.27 break; 68.28 } 68.29 - return svga_in(addr); 68.30 + return svga_in(addr, NULL); 68.31 }
69.1 --- a/src/vid_stg_ramdac.h Sun Apr 21 14:54:35 2013 +0100 69.2 +++ b/src/vid_stg_ramdac.h Mon May 27 17:46:42 2013 +0100 69.3 @@ -1,2 +1,2 @@ 69.4 -void stg_ramdac_out(uint16_t addr, uint8_t val); 69.5 -uint8_t stg_ramdac_in(uint16_t addr); 69.6 +void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv); 69.7 +uint8_t stg_ramdac_in(uint16_t addr, void *priv);
70.1 --- a/src/vid_svga.c Sun Apr 21 14:54:35 2013 +0100 70.2 +++ b/src/vid_svga.c Mon May 27 17:46:42 2013 +0100 70.3 @@ -1,9 +1,14 @@ 70.4 /*Generic SVGA handling*/ 70.5 /*This is intended to be used by another SVGA driver, and not as a card in it's own right*/ 70.6 #include "ibm.h" 70.7 +#include "mem.h" 70.8 #include "video.h" 70.9 #include "vid_svga.h" 70.10 +#include "vid_svga_render.h" 70.11 #include "io.h" 70.12 +#include "timer.h" 70.13 + 70.14 +#define svga_output 0 70.15 70.16 uint32_t svga_vram_limit; 70.17 70.18 @@ -11,15 +16,19 @@ 70.19 uint8_t svga_miscout; 70.20 70.21 static uint8_t la, lb, lc, ld; 70.22 -static uint8_t svga_rotate[8][256]; 70.23 +uint8_t svga_rotate[8][256]; 70.24 70.25 static int svga_fast; 70.26 70.27 -void svga_out(uint16_t addr, uint8_t val) 70.28 +void (*svga_render)(); 70.29 + 70.30 +static uint8_t dacmask, dacstatus; 70.31 + 70.32 +void svga_out(uint16_t addr, uint8_t val, void *priv) 70.33 { 70.34 int c; 70.35 uint8_t o; 70.36 - //printf("OUT SVGA %03X %02X %04X:%04X %i %08X\n",addr,val,CS,pc,TRIDENT,svgawbank); 70.37 +// printf("OUT SVGA %03X %02X %04X:%04X %i %08X\n",addr,val,CS,pc,TRIDENT,svgawbank); 70.38 switch (addr) 70.39 { 70.40 case 0x3C0: 70.41 @@ -45,10 +54,16 @@ 70.42 svga_miscout = val; 70.43 vres = 0; pallook = pallook256; 70.44 vidclock = val & 4; printf("3C2 write %02X\n",val); 70.45 - if (val&1) 70.46 - io_sethandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL); 70.47 + if (val & 1) 70.48 + { 70.49 + pclog("Remove mono handler\n"); 70.50 + io_removehandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL, NULL); 70.51 + } 70.52 else 70.53 - io_sethandler(0x03a0, 0x0020, video_in_null, NULL, NULL, video_out_null, NULL, NULL); 70.54 + { 70.55 + pclog("Set mono handler\n"); 70.56 + io_sethandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL, NULL); 70.57 + } 70.58 break; 70.59 case 0x3C4: seqaddr=val; break; 70.60 case 0x3C5: 70.61 @@ -58,7 +73,12 @@ 70.62 if (o!=val && (seqaddr&0xF)==1) svga_recalctimings(); 70.63 switch (seqaddr&0xF) 70.64 { 70.65 - case 1: if (scrblank && !(val&0x20)) fullchange=3; scrblank=(scrblank&~0x20)|(val&0x20); break; 70.66 + case 1: 70.67 + if (scrblank && !(val&0x20)) 70.68 + fullchange=3; 70.69 + scrblank=(scrblank&~0x20)|(val&0x20); 70.70 + svga_recalctimings(); 70.71 + break; 70.72 case 2: writemask=val&0xF; break; 70.73 case 3: 70.74 charset=val&0xF; 70.75 @@ -71,9 +91,16 @@ 70.76 break; 70.77 } 70.78 break; 70.79 + case 0x3c6: dacmask=val; break; 70.80 case 0x3C7: dacread=val; dacpos=0; break; 70.81 case 0x3C8: dacwrite=val; dacpos=0; break; 70.82 case 0x3C9: 70.83 + dacstatus = 0; 70.84 +/* if (pc == 0x68AD) 70.85 + { 70.86 + dumpregs(); 70.87 + exit(-1); 70.88 + }*/ 70.89 palchange=1; 70.90 fullchange=changeframecount; 70.91 switch (dacpos) 70.92 @@ -85,6 +112,7 @@ 70.93 break; 70.94 case 0x3CE: gdcaddr=val; break; 70.95 case 0x3CF: 70.96 + o = gdcreg[gdcaddr & 15]; 70.97 switch (gdcaddr&15) 70.98 { 70.99 case 2: colourcompare=val; break; 70.100 @@ -93,21 +121,21 @@ 70.101 case 6: 70.102 if ((gdcreg[6] & 0xc) != (val & 0xc)) 70.103 { 70.104 - mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 70.105 -// pclog("Write mapping %02X\n", val); 70.106 + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 70.107 + pclog("Write mapping %02X\n", val); 70.108 switch (val&0xC) 70.109 { 70.110 case 0x0: /*128k at A0000*/ 70.111 - mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 70.112 + mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 70.113 break; 70.114 case 0x4: /*64k at A0000*/ 70.115 - mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 70.116 + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 70.117 break; 70.118 case 0x8: /*32k at B0000*/ 70.119 - mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 70.120 + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 70.121 break; 70.122 case 0xC: /*32k at B8000*/ 70.123 - mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); 70.124 + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 70.125 break; 70.126 } 70.127 } 70.128 @@ -116,11 +144,13 @@ 70.129 } 70.130 gdcreg[gdcaddr&15]=val; 70.131 svga_fast = (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) && chain4; 70.132 + if (((gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((gdcaddr & 15) == 6 && (val ^ o) & 1)) 70.133 + svga_recalctimings(); 70.134 break; 70.135 } 70.136 } 70.137 70.138 -uint8_t svga_in(uint16_t addr) 70.139 +uint8_t svga_in(uint16_t addr, void *priv) 70.140 { 70.141 uint8_t temp; 70.142 // if (addr!=0x3da) pclog("Read port %04X\n",addr); 70.143 @@ -128,12 +158,20 @@ 70.144 { 70.145 case 0x3C0: return attraddr; 70.146 case 0x3C1: return attrregs[attraddr]; 70.147 - case 0x3C2: return 0x10; 70.148 + case 0x3c2: 70.149 + if ((vgapal[0].r + vgapal[0].g + vgapal[0].b) >= 0x50) 70.150 + temp = 0; 70.151 + else 70.152 + temp = 0x10; 70.153 + return temp; 70.154 case 0x3C4: return seqaddr; 70.155 case 0x3C5: 70.156 return seqregs[seqaddr&0xF]; 70.157 + case 0x3c6: return dacmask; 70.158 + case 0x3c7: return dacstatus; 70.159 case 0x3C8: return dacwrite; 70.160 case 0x3C9: 70.161 + dacstatus=3; 70.162 palchange=1; 70.163 switch (dacpos) 70.164 { 70.165 @@ -156,8 +194,9 @@ 70.166 } 70.167 70.168 int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split; 70.169 -int svga_hdisp, svga_htotal, svga_rowoffset; 70.170 +int svga_hdisp, svga_htotal, svga_hdisp_time, svga_rowoffset; 70.171 int svga_lowres, svga_interlace; 70.172 +int svga_linedbl, svga_rowcount; 70.173 double svga_clock; 70.174 uint32_t svga_ma; 70.175 void (*svga_recalctimings_ex)() = NULL; 70.176 @@ -166,7 +205,8 @@ 70.177 void svga_recalctimings() 70.178 { 70.179 double crtcconst; 70.180 - int temp; 70.181 + double _dispontime, _dispofftime; 70.182 + 70.183 svga_vtotal=crtc[6]; 70.184 svga_dispend=crtc[0x12]; 70.185 svga_vsyncstart=crtc[0x10]; 70.186 @@ -204,32 +244,131 @@ 70.187 svga_interlace = 0; 70.188 70.189 svga_ma = (crtc[0xC]<<8)|crtc[0xD]; 70.190 + 70.191 + svga_hdisp_time = svga_hdisp; 70.192 + svga_render = svga_render_blank; 70.193 + if (!scrblank) 70.194 + { 70.195 + if (!(gdcreg[6]&1)) /*Text mode*/ 70.196 + { 70.197 + if (seqregs[1]&8) /*40 column*/ 70.198 + { 70.199 + svga_render = svga_render_text_40; 70.200 + svga_hdisp *= (seqregs[1] & 1) ? 16 : 18; 70.201 + } 70.202 + else 70.203 + { 70.204 + svga_render = svga_render_text_80; 70.205 + svga_hdisp *= (seqregs[1] & 1) ? 8 : 9; 70.206 + } 70.207 + } 70.208 + else 70.209 + { 70.210 + svga_hdisp *= (seqregs[1] & 8) ? 16 : 8; 70.211 + 70.212 + switch (gdcreg[5]&0x60) 70.213 + { 70.214 + case 0x00: /*16 colours*/ 70.215 + if (seqregs[1]&8) /*Low res (320)*/ 70.216 + svga_render = svga_render_4bpp_lowres; 70.217 + else 70.218 + svga_render = svga_render_4bpp_highres; 70.219 + break; 70.220 + case 0x20: /*4 colours*/ 70.221 + svga_render = svga_render_2bpp_lowres; 70.222 + break; 70.223 + case 0x40: case 0x60: /*256+ colours*/ 70.224 + switch (bpp) 70.225 + { 70.226 + case 8: 70.227 + if (svga_lowres) 70.228 + svga_render = svga_render_8bpp_lowres; 70.229 + else 70.230 + { 70.231 + svga_render = svga_render_8bpp_highres; 70.232 +// svga_hdisp <<= 1; 70.233 + } 70.234 + break; 70.235 + case 15: 70.236 + if (svga_lowres) 70.237 + svga_render = svga_render_15bpp_lowres; 70.238 + else 70.239 + { 70.240 + svga_render = svga_render_15bpp_highres; 70.241 + svga_hdisp <<= 1; 70.242 + } 70.243 + break; 70.244 + case 16: 70.245 + if (svga_lowres) 70.246 + svga_render = svga_render_16bpp_lowres; 70.247 + else 70.248 + { 70.249 + svga_render = svga_render_16bpp_highres; 70.250 + svga_hdisp <<= 1; 70.251 + } 70.252 + break; 70.253 + case 24: 70.254 + if (svga_lowres) 70.255 + { 70.256 + svga_render = svga_render_24bpp_lowres; 70.257 + svga_hdisp = ((svga_hdisp<<3)/3); 70.258 + } 70.259 + else 70.260 + { 70.261 + svga_render = svga_render_24bpp_highres; 70.262 + svga_hdisp = ((svga_hdisp<<3)/3); 70.263 + } 70.264 + break; 70.265 + case 32: 70.266 + if (svga_lowres) 70.267 + svga_render = svga_render_32bpp_lowres; 70.268 + else 70.269 + { 70.270 + svga_render = svga_render_32bpp_highres; 70.271 + svga_hdisp <<= 1; 70.272 + } 70.273 + break; 70.274 + } 70.275 + break; 70.276 + } 70.277 + } 70.278 + } 70.279 + 70.280 +// pclog("svga_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8); 70.281 70.282 + svga_linedbl = crtc[9] & 0x80; 70.283 + svga_rowcount = crtc[9] & 31; 70.284 if (svga_recalctimings_ex) svga_recalctimings_ex(); 70.285 70.286 crtcconst=(seqregs[1]&1)?(svga_clock*8.0):(svga_clock*9.0); 70.287 70.288 disptime =svga_htotal; 70.289 - dispontime=svga_hdisp; 70.290 + _dispontime = svga_hdisp_time; 70.291 + 70.292 +// printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); 70.293 + if (seqregs[1]&8) { disptime*=2; _dispontime*=2; } 70.294 + _dispofftime=disptime-_dispontime; 70.295 + _dispontime*=crtcconst; 70.296 + _dispofftime*=crtcconst; 70.297 70.298 -// printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); 70.299 - if (seqregs[1]&8) { disptime*=2; dispontime*=2; } 70.300 - dispofftime=disptime-dispontime; 70.301 - dispontime*=crtcconst; 70.302 - dispofftime*=crtcconst; 70.303 - 70.304 + dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); 70.305 + dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); 70.306 // printf("SVGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4)); 70.307 // printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga_vtotal,svga_dispend,(crtc[9]&31)+1,svga_vsyncstart); 70.308 // printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*svga_vtotal,(dispontime+dispofftime)*svga_vtotal*70,seqregs[1]); 70.309 + 70.310 +// pclog("svga_render %08X\n", svga_render); 70.311 } 70.312 70.313 +void (*svga_render)(); 70.314 70.315 -static uint32_t ma,maback,ca; 70.316 -static int vc,sc; 70.317 -static int linepos, displine, vslines, linecountff, oddeven; 70.318 +uint32_t ma, maback, ca; 70.319 +static int vc; 70.320 +int sc; 70.321 +static int linepos, vslines, linecountff, oddeven; 70.322 static int svga_dispon; 70.323 -static int con, coff, cursoron, cgablink; 70.324 -static int scrollcache; 70.325 +int con, coff, cursoron, cgablink; 70.326 +int scrollcache; 70.327 70.328 int svga_hwcursor_on; 70.329 70.330 @@ -237,17 +376,13 @@ 70.331 70.332 int svga_hdisp_on; 70.333 70.334 -static int firstline_draw = 2000, lastline_draw = 0; 70.335 +int firstline_draw = 2000, lastline_draw = 0; 70.336 +int displine; 70.337 70.338 void svga_poll() 70.339 { 70.340 - uint8_t chr,dat,attr; 70.341 - uint32_t charaddr; 70.342 - int x,xx; 70.343 - uint32_t fg,bg; 70.344 - int offset; 70.345 - uint8_t edat[4]; 70.346 - int drawcursor=0; 70.347 + int x; 70.348 + 70.349 if (!linepos) 70.350 { 70.351 // if (!(vc & 15)) pclog("VC %i %i\n", vc, GetTickCount()); 70.352 @@ -264,305 +399,17 @@ 70.353 70.354 ma&=vrammask; 70.355 if (firstline==2000) firstline=displine; 70.356 - if (scrblank) 70.357 - { 70.358 - if (firstline_draw == 2000) firstline_draw = displine; 70.359 - lastline_draw = displine; 70.360 - for (x=0;x<svga_hdisp;x++) 70.361 - { 70.362 - switch (seqregs[1]&9) 70.363 - { 70.364 - case 0: 70.365 - for (xx=0;xx<9;xx++) ((uint32_t *)buffer32->line[displine])[(x*9)+xx+32]=0; 70.366 - break; 70.367 - case 1: 70.368 - for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[(x*8)+xx+32]=0; 70.369 - break; 70.370 - case 8: 70.371 - for (xx=0;xx<18;xx++) ((uint32_t *)buffer32->line[displine])[(x*18)+xx+32]=0; 70.372 - break; 70.373 - case 9: 70.374 - for (xx=0;xx<16;xx++) ((uint32_t *)buffer32->line[displine])[(x*16)+xx+32]=0; 70.375 - break; 70.376 - } 70.377 - } 70.378 - } 70.379 - else if (!(gdcreg[6]&1)) /*Text mode*/ 70.380 - { 70.381 - if (firstline_draw == 2000) firstline_draw = displine; 70.382 - lastline_draw = displine; 70.383 - if (fullchange) 70.384 - { 70.385 - for (x=0;x<svga_hdisp;x++) 70.386 - { 70.387 - drawcursor=((ma==ca) && con && cursoron); 70.388 - chr=vram[(ma<<1)]; 70.389 - attr=vram[(ma<<1)+4]; 70.390 - if (attr&8) charaddr=charsetb+(chr*128); 70.391 - else charaddr=charseta+(chr*128); 70.392 - 70.393 - if (drawcursor) { bg=pallook[egapal[attr&15]]; fg=pallook[egapal[attr>>4]]; } 70.394 - else 70.395 - { 70.396 - fg=pallook[egapal[attr&15]]; 70.397 - bg=pallook[egapal[attr>>4]]; 70.398 - if (attr&0x80 && attrregs[0x10]&8) 70.399 - { 70.400 - bg=pallook[egapal[(attr>>4)&7]]; 70.401 - if (cgablink&16) fg=bg; 70.402 - } 70.403 - } 70.404 - 70.405 - dat=vram[charaddr+(sc<<2)]; 70.406 - if (seqregs[1]&8) /*40 column*/ 70.407 - { 70.408 - if (seqregs[1]&1) { for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x<<4)+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[((x<<4)+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; } 70.409 - else 70.410 - { 70.411 - for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x*18)+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; 70.412 - if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) ((uint32_t *)buffer32->line[displine])[((x*18)+32+16)&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+32+17)&2047]=bg; 70.413 - else ((uint32_t *)buffer32->line[displine])[((x*18)+32+16)&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+32+17)&2047]=(dat&1)?fg:bg; 70.414 - } 70.415 - } 70.416 - else /*80 column*/ 70.417 - { 70.418 - if (seqregs[1]&1) { for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x<<3)+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; } 70.419 - else 70.420 - { 70.421 - for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x*9)+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; 70.422 - if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) ((uint32_t *)buffer32->line[displine])[((x*9)+32+8)&2047]=bg; 70.423 - else ((uint32_t *)buffer32->line[displine])[((x*9)+32+8)&2047]=(dat&1)?fg:bg; 70.424 - } 70.425 - } 70.426 - ma+=4; ma&=vrammask; 70.427 - } 70.428 - } 70.429 - } 70.430 - else 70.431 - { 70.432 -// if (hwcursor_on) changedvram[ma>>10]=changedvram[(ma>>10)+1]=2; 70.433 - switch (gdcreg[5]&0x60) 70.434 - { 70.435 - case 0x00: /*16 colours*/ 70.436 - if (firstline_draw == 2000) firstline_draw = displine; 70.437 - lastline_draw = displine; 70.438 - if (seqregs[1]&8) /*Low res (320)*/ 70.439 - { 70.440 - offset=((8-scrollcache)<<1)+16; 70.441 - for (x=0;x<=svga_hdisp;x++) 70.442 - { 70.443 - edat[0]=vram[ma]; 70.444 - edat[1]=vram[ma|0x1]; 70.445 - edat[2]=vram[ma|0x2]; 70.446 - edat[3]=vram[ma|0x3]; 70.447 - ma+=4; ma&=vrammask; 70.448 - 70.449 - dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2); 70.450 - ((uint32_t *)buffer32->line[displine])[(x<<4)+14+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+15+offset]=pallook[egapal[dat&0xF]]; 70.451 - ((uint32_t *)buffer32->line[displine])[(x<<4)+12+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+13+offset]=pallook[egapal[dat>>4]]; 70.452 - dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2); 70.453 - ((uint32_t *)buffer32->line[displine])[(x<<4)+10+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+11+offset]=pallook[egapal[dat&0xF]]; 70.454 - ((uint32_t *)buffer32->line[displine])[(x<<4)+8+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+9+offset]=pallook[egapal[dat>>4]]; 70.455 - dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2); 70.456 - ((uint32_t *)buffer32->line[displine])[(x<<4)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+7+offset]=pallook[egapal[dat&0xF]]; 70.457 - ((uint32_t *)buffer32->line[displine])[(x<<4)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+5+offset]=pallook[egapal[dat>>4]]; 70.458 - dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); 70.459 - ((uint32_t *)buffer32->line[displine])[(x<<4)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+3+offset]=pallook[egapal[dat&0xF]]; 70.460 - ((uint32_t *)buffer32->line[displine])[(x<<4)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+1+offset]=pallook[egapal[dat>>4]]; 70.461 - } 70.462 - } 70.463 - else /*High res (640)*/ 70.464 - { 70.465 - offset=(8-scrollcache)+24; 70.466 - for (x=0;x<=svga_hdisp;x++) 70.467 - { 70.468 - edat[0]=vram[ma]; 70.469 - edat[1]=vram[ma|0x1]; 70.470 - edat[2]=vram[ma|0x2]; 70.471 - edat[3]=vram[ma|0x3]; 70.472 - ma+=4; ma&=vrammask; 70.473 - 70.474 - dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2); 70.475 - ((uint32_t *)buffer32->line[displine])[(x<<3)+7+offset]=pallook[egapal[dat&0xF]]; 70.476 - ((uint32_t *)buffer32->line[displine])[(x<<3)+6+offset]=pallook[egapal[dat>>4]]; 70.477 - dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2); 70.478 - ((uint32_t *)buffer32->line[displine])[(x<<3)+5+offset]=pallook[egapal[dat&0xF]]; 70.479 - ((uint32_t *)buffer32->line[displine])[(x<<3)+4+offset]=pallook[egapal[dat>>4]]; 70.480 - dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2); 70.481 - ((uint32_t *)buffer32->line[displine])[(x<<3)+3+offset]=pallook[egapal[dat&0xF]]; 70.482 - ((uint32_t *)buffer32->line[displine])[(x<<3)+2+offset]=pallook[egapal[dat>>4]]; 70.483 - dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); 70.484 - ((uint32_t *)buffer32->line[displine])[(x<<3)+1+offset]=pallook[egapal[dat&0xF]]; 70.485 - ((uint32_t *)buffer32->line[displine])[(x<<3)+offset]= pallook[egapal[dat>>4]]; 70.486 - } 70.487 - } 70.488 - break; 70.489 - case 0x20: /*4 colours*/ 70.490 - if (firstline_draw == 2000) firstline_draw = displine; 70.491 - lastline_draw = displine; 70.492 - offset=((8-scrollcache)<<1)+16; 70.493 - /*Low res (320) only, though high res (640) should be possible*/ 70.494 - for (x=0;x<=svga_hdisp;x++) 70.495 - { 70.496 - if (sc&1 && !(crtc[0x17]&1)) 70.497 - { 70.498 - edat[0]=vram[(ma<<1)+0x8000]; 70.499 - edat[1]=vram[(ma<<1)+0x8004]; 70.500 - } 70.501 - else 70.502 - { 70.503 - edat[0]=vram[(ma<<1)]; 70.504 - edat[1]=vram[(ma<<1)+4]; 70.505 - } 70.506 - ma+=4; ma&=vrammask; 70.507 - 70.508 - ((uint32_t *)buffer32->line[displine])[(x<<4)+14+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+15+offset]=pallook[egapal[edat[1]&3]]; 70.509 - ((uint32_t *)buffer32->line[displine])[(x<<4)+12+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+13+offset]=pallook[egapal[(edat[1]>>2)&3]]; 70.510 - dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2); 70.511 - ((uint32_t *)buffer32->line[displine])[(x<<4)+10+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+11+offset]=pallook[egapal[(edat[1]>>4)&3]]; 70.512 - ((uint32_t *)buffer32->line[displine])[(x<<4)+8+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+9+offset]=pallook[egapal[(edat[1]>>6)&3]]; 70.513 - dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2); 70.514 - ((uint32_t *)buffer32->line[displine])[(x<<4)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+7+offset]=pallook[egapal[(edat[0]>>0)&3]]; 70.515 - ((uint32_t *)buffer32->line[displine])[(x<<4)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+5+offset]=pallook[egapal[(edat[0]>>2)&3]]; 70.516 - dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2); 70.517 - ((uint32_t *)buffer32->line[displine])[(x<<4)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+3+offset]=pallook[egapal[(edat[0]>>4)&3]]; 70.518 - ((uint32_t *)buffer32->line[displine])[(x<<4)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+1+offset]=pallook[egapal[(edat[0]>>6)&3]]; 70.519 - } 70.520 - break; 70.521 - case 0x40: case 0x60: /*256 colours (and more, with high/true colour RAMDAC)*/ 70.522 - if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange) 70.523 - { 70.524 - if (firstline_draw == 2000) firstline_draw = displine; 70.525 - lastline_draw = displine; 70.526 - if (svga_lowres) /*Low res (320)*/ 70.527 - { 70.528 -// if (!displine) pclog("Lo res %i %i %i\n",bpp,svga_hdisp,(svga_hdisp<<3)/3); 70.529 - offset=(8-(scrollcache&6))+24; 70.530 - if (bpp==8) /*Regular 8 bpp palette mode*/ 70.531 - { 70.532 - for (x=0;x<=svga_hdisp;x++) 70.533 - { 70.534 - edat[0]=vram[ma]; 70.535 - edat[1]=vram[ma|0x1]; 70.536 - edat[2]=vram[ma|0x2]; 70.537 - edat[3]=vram[ma|0x3]; 70.538 - ma+=4; ma&=vrammask; 70.539 - ((uint32_t *)buffer32->line[displine])[(x<<3)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+7+offset]=pallook[edat[3]]; 70.540 - ((uint32_t *)buffer32->line[displine])[(x<<3)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+5+offset]=pallook[edat[2]]; 70.541 - ((uint32_t *)buffer32->line[displine])[(x<<3)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+3+offset]=pallook[edat[1]]; 70.542 - ((uint32_t *)buffer32->line[displine])[(x<<3)+offset]= ((uint32_t *)buffer32->line[displine])[(x<<3)+1+offset]=pallook[edat[0]]; 70.543 - } 70.544 - } 70.545 - else if (bpp==16) /*16 bpp 565 mode*/ 70.546 - { 70.547 - for (x=0;x<=svga_hdisp;x++) 70.548 - { 70.549 - fg=vram[ma]|(vram[ma|0x1]<<8); 70.550 - bg=vram[ma|0x2]|(vram[ma|0x3]<<8); 70.551 - ma+=4; ma&=vrammask; 70.552 - ((uint32_t *)buffer32->line[displine])[(x<<2)+2+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+3+offset]=((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19); 70.553 - ((uint32_t *)buffer32->line[displine])[(x<<2)+0+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+1+offset]=((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19); 70.554 - } 70.555 - } 70.556 - else if (bpp==15) /*15 bpp 555 mode*/ 70.557 - { 70.558 - for (x=0;x<=svga_hdisp;x++) 70.559 - { 70.560 - fg=vram[ma]|(vram[ma|0x1]<<8); 70.561 - bg=vram[ma|0x2]|(vram[ma|0x3]<<8); 70.562 - ma+=4; ma&=vrammask; 70.563 - ((uint32_t *)buffer32->line[displine])[(x<<1)+2+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+3+offset]=((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19); 70.564 - ((uint32_t *)buffer32->line[displine])[(x<<1)+0+offset]=((uint32_t *)buffer32->line[displine])[(x<<2)+1+offset]=((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19); 70.565 - } 70.566 - } 70.567 - else if (bpp==24) /*24 bpp 888 mode*/ 70.568 - { 70.569 - for (x=0;x<=((svga_hdisp<<3)/3);x++) 70.570 - { 70.571 - fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16); 70.572 - ma+=3; ma&=vrammask; 70.573 - ((uint32_t *)buffer32->line[displine])[(x<<1)+offset]=((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=fg; 70.574 - } 70.575 - } 70.576 - else if (bpp==32) /*32 bpp 8888 mode*/ 70.577 - { 70.578 - for (x = 0; x <= svga_hdisp; x++) 70.579 - { 70.580 - fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16); 70.581 - ma += 4; ma &= vrammask; 70.582 - ((uint32_t *)buffer32->line[displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[displine])[(x << 1) + 1 + offset] = fg; 70.583 - } 70.584 - } 70.585 - } 70.586 - else /*High res (SVGA only)*/ 70.587 - { 70.588 -// if (!displine) pclog("Hi res %i %i %i\n",bpp,svga_hdisp,(svga_hdisp<<3)/3); 70.589 - offset=(8-((scrollcache&6)>>1))+24; 70.590 - if (bpp==8) 70.591 - { 70.592 - for (x=0;x<=(svga_hdisp<<1);x++) 70.593 - { 70.594 - edat[0]=vram[ma]; 70.595 - edat[1]=vram[ma|0x1]; 70.596 - edat[2]=vram[ma|0x2]; 70.597 - edat[3]=vram[ma|0x3]; 70.598 - ma+=4; ma&=vrammask; 70.599 - ((uint32_t *)buffer32->line[displine])[(x<<2)+3+offset]=pallook[edat[3]]; 70.600 - ((uint32_t *)buffer32->line[displine])[(x<<2)+2+offset]=pallook[edat[2]]; 70.601 - ((uint32_t *)buffer32->line[displine])[(x<<2)+1+offset]=pallook[edat[1]]; 70.602 - ((uint32_t *)buffer32->line[displine])[(x<<2)+offset]= pallook[edat[0]]; 70.603 - } 70.604 - } 70.605 - else if (bpp==16) 70.606 - { 70.607 - for (x=0;x<=(svga_hdisp<<1);x++) 70.608 - { 70.609 - fg=vram[ma]|(vram[ma|0x1]<<8); 70.610 - bg=vram[ma|0x2]|(vram[ma|0x3]<<8); 70.611 - ma+=4; ma&=vrammask; 70.612 - ((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19); 70.613 - ((uint32_t *)buffer32->line[displine])[(x<<1)+0+offset]=((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19); 70.614 - } 70.615 - } 70.616 - else if (bpp==15) 70.617 - { 70.618 - for (x=0;x<=(svga_hdisp<<1);x++) 70.619 - { 70.620 - fg=vram[ma]|(vram[ma|0x1]<<8); 70.621 - bg=vram[ma|0x2]|(vram[ma|0x3]<<8); 70.622 - ma+=4; ma&=vrammask; 70.623 - ((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19); 70.624 - ((uint32_t *)buffer32->line[displine])[(x<<1)+0+offset]=((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19); 70.625 - } 70.626 - } 70.627 - else if (bpp==24) 70.628 - { 70.629 - for (x=0;x<=((svga_hdisp<<3)/3);x++) 70.630 - { 70.631 - fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16); 70.632 - ma+=3; ma&=vrammask; 70.633 - ((uint32_t *)buffer32->line[displine])[x+offset]=fg; 70.634 - } 70.635 - } 70.636 - else if (bpp==32) 70.637 - { 70.638 - for (x = 0; x <= (svga_hdisp<<2); x++) 70.639 - { 70.640 - fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16); 70.641 - ma += 4; ma &= vrammask; 70.642 - ((uint32_t *)buffer32->line[displine])[x + offset] = fg; 70.643 - } 70.644 - } 70.645 - } 70.646 - } 70.647 - break; 70.648 - } 70.649 + 70.650 + if (svga_hwcursor_on) changedvram[ma >> 10] = changedvram[(ma >> 10) + 1] = 2; 70.651 + 70.652 + svga_render(); 70.653 + 70.654 if (svga_hwcursor_on) 70.655 { 70.656 svga_hwcursor_draw(displine); 70.657 svga_hwcursor_on--; 70.658 } 70.659 - } 70.660 + 70.661 if (lastline<displine) lastline=displine; 70.662 } 70.663 70.664 @@ -592,12 +439,12 @@ 70.665 if (sc==(crtc[11]&31)) con = 0; 70.666 if (svga_dispon) 70.667 { 70.668 - if ((crtc[9]&0x80) && !linecountff) 70.669 + if (svga_linedbl && !linecountff) 70.670 { 70.671 linecountff=1; 70.672 ma=maback; 70.673 } 70.674 - else if (sc==(crtc[9]&31)) 70.675 + else if (sc == svga_rowcount) 70.676 { 70.677 linecountff=0; 70.678 sc=0; 70.679 @@ -642,11 +489,11 @@ 70.680 // pclog("VC vsync %i %i\n", firstline_draw, lastline_draw); 70.681 svga_dispon=0; 70.682 cgastat|=8; 70.683 - if (seqregs[1]&8) x=svga_hdisp*((seqregs[1]&1)?8:9)*2; 70.684 - else x=svga_hdisp*((seqregs[1]&1)?8:9); 70.685 + /*if (seqregs[1]&8) x=(svga_hdisp*((seqregs[1]&1)?8:9))*2; 70.686 + else */x = svga_hdisp;//*((seqregs[1]&1)?8:9); 70.687 70.688 if (bpp == 16 || bpp == 15) x /= 2; 70.689 - if (bpp == 24) x /= 3; 70.690 +// if (bpp == 24) x /= 3; 70.691 if (bpp == 32) x /= 4; 70.692 if (svga_interlace && !oddeven) lastline++; 70.693 if (svga_interlace && oddeven) firstline--; 70.694 @@ -704,7 +551,7 @@ 70.695 case 0x40: case 0x60: video_bpp = bpp; break; 70.696 } 70.697 } 70.698 - 70.699 + video_bpp = bpp; 70.700 // if (svga_interlace && oddeven) ma=maback=ma+(svga_rowoffset<<2); 70.701 70.702 // pclog("Addr %08X vson %03X vsoff %01X %02X %02X %02X %i %i\n",ma,svga_vsyncstart,crtc[0x11]&0xF,crtc[0xD],crtc[0xC],crtc[0x33], svga_interlace, oddeven); 70.703 @@ -751,20 +598,17 @@ 70.704 70.705 #define egacycles 1 70.706 #define egacycles2 1 70.707 -void svga_write(uint32_t addr, uint8_t val) 70.708 +void svga_write(uint32_t addr, uint8_t val, void *priv) 70.709 { 70.710 - int x,y; 70.711 - char s[2]={0,0}; 70.712 uint8_t vala,valb,valc,vald,wm=writemask; 70.713 int writemask2 = writemask; 70.714 - int bankaddr; 70.715 70.716 egawrites++; 70.717 70.718 cycles -= video_timing_b; 70.719 cycles_lost += video_timing_b; 70.720 70.721 -// pclog("Writeega %06X ",addr); 70.722 + if (svga_output) pclog("Writeega %06X ",addr); 70.723 if (addr>=0xB0000) addr&=0x7FFF; 70.724 else 70.725 { 70.726 @@ -783,8 +627,8 @@ 70.727 { 70.728 addr<<=2; 70.729 } 70.730 -// pclog("%08X %02X %i %i %i\n", addr, val, writemask2, writemode, chain4); 70.731 addr&=0x7FFFFF; 70.732 + if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i\n", addr, addr & 1023, addr >> 10, val, writemask2, writemode, chain4); 70.733 changedvram[addr>>10]=changeframecount; 70.734 70.735 switch (writemode) 70.736 @@ -929,10 +773,9 @@ 70.737 } 70.738 } 70.739 70.740 -uint8_t svga_read(uint32_t addr) 70.741 +uint8_t svga_read(uint32_t addr, void *priv) 70.742 { 70.743 uint8_t temp,temp2,temp3,temp4; 70.744 - uint32_t addr2; 70.745 70.746 cycles -= video_timing_b; 70.747 cycles_lost += video_timing_b; 70.748 @@ -985,20 +828,17 @@ 70.749 return vram[addr|readplane]; 70.750 } 70.751 70.752 -void svga_write_linear(uint32_t addr, uint8_t val) 70.753 +void svga_write_linear(uint32_t addr, uint8_t val, void *priv) 70.754 { 70.755 - int x,y; 70.756 - char s[2]={0,0}; 70.757 uint8_t vala,valb,valc,vald,wm=writemask; 70.758 int writemask2 = writemask; 70.759 - int bankaddr; 70.760 70.761 cycles -= video_timing_b; 70.762 cycles_lost += video_timing_b; 70.763 70.764 egawrites++; 70.765 70.766 -// pclog("Write LFB %08X %02X ", addr, val); 70.767 + if (svga_output) pclog("Write LFB %08X %02X ", addr, val); 70.768 if (!(gdcreg[6]&1)) fullchange=2; 70.769 if (chain4) 70.770 { 70.771 @@ -1010,7 +850,7 @@ 70.772 addr<<=2; 70.773 } 70.774 addr &= 0x7fffff; 70.775 -// pclog("%08X\n", addr); 70.776 + if (svga_output) pclog("%08X\n", addr); 70.777 changedvram[addr>>10]=changeframecount; 70.778 70.779 switch (writemode) 70.780 @@ -1155,7 +995,7 @@ 70.781 } 70.782 } 70.783 70.784 -uint8_t svga_read_linear(uint32_t addr) 70.785 +uint8_t svga_read_linear(uint32_t addr, void *priv) 70.786 { 70.787 uint8_t temp,temp2,temp3,temp4; 70.788 70.789 @@ -1220,8 +1060,16 @@ 70.790 ysize=wy+1; 70.791 if (xsize<64) xsize=656; 70.792 if (ysize<32) ysize=200; 70.793 - if (vres) updatewindowsize(xsize,ysize<<1); 70.794 - else updatewindowsize(xsize,ysize); 70.795 +/* if (bpp > 8) 70.796 + { 70.797 + if (vres) updatewindowsize(xsize<<1,ysize<<1); 70.798 + else updatewindowsize(xsize<<1,ysize); 70.799 + } 70.800 + else 70.801 + {*/ 70.802 + if (vres) updatewindowsize(xsize,ysize<<1); 70.803 + else updatewindowsize(xsize,ysize); 70.804 +// } 70.805 } 70.806 if (vid_resize) 70.807 { 70.808 @@ -1234,12 +1082,12 @@ 70.809 70.810 } 70.811 70.812 -void svga_writew(uint32_t addr, uint16_t val) 70.813 +void svga_writew(uint32_t addr, uint16_t val, void *priv) 70.814 { 70.815 if (!svga_fast) 70.816 { 70.817 - svga_write(addr, val); 70.818 - svga_write(addr + 1, val >> 8); 70.819 + svga_write(addr, val, priv); 70.820 + svga_write(addr + 1, val >> 8, priv); 70.821 return; 70.822 } 70.823 70.824 @@ -1248,22 +1096,22 @@ 70.825 cycles -= video_timing_w; 70.826 cycles_lost += video_timing_w; 70.827 70.828 -// pclog("Writew %05X ", addr); 70.829 + if (svga_output) pclog("Writew %05X ", addr); 70.830 addr = (addr & 0xffff) + svgawbank; 70.831 addr &= 0x7FFFFF; 70.832 -// pclog("%08X %04X\n", addr, val); 70.833 + if (svga_output) pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val); 70.834 changedvram[addr >> 10] = changeframecount; 70.835 *(uint16_t *)&vram[addr] = val; 70.836 } 70.837 70.838 -void svga_writel(uint32_t addr, uint32_t val) 70.839 +void svga_writel(uint32_t addr, uint32_t val, void *priv) 70.840 { 70.841 if (!svga_fast) 70.842 { 70.843 - svga_write(addr, val); 70.844 - svga_write(addr + 1, val >> 8); 70.845 - svga_write(addr + 2, val >> 16); 70.846 - svga_write(addr + 3, val >> 24); 70.847 + svga_write(addr, val, priv); 70.848 + svga_write(addr + 1, val >> 8, priv); 70.849 + svga_write(addr + 2, val >> 16, priv); 70.850 + svga_write(addr + 3, val >> 24, priv); 70.851 return; 70.852 } 70.853 70.854 @@ -1272,19 +1120,19 @@ 70.855 cycles -= video_timing_l; 70.856 cycles_lost += video_timing_l; 70.857 70.858 -// pclog("Writel %05X ", addr); 70.859 + if (svga_output) pclog("Writel %05X ", addr); 70.860 addr = (addr & 0xffff) + svgawbank; 70.861 addr &= 0x7FFFFF; 70.862 -// pclog("%08X %08X\n", addr, val); 70.863 + if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val); 70.864 70.865 changedvram[addr >> 10] = changeframecount; 70.866 *(uint32_t *)&vram[addr] = val; 70.867 } 70.868 70.869 -uint16_t svga_readw(uint32_t addr) 70.870 +uint16_t svga_readw(uint32_t addr, void *priv) 70.871 { 70.872 if (!svga_fast) 70.873 - return svga_read(addr) | (svga_read(addr + 1) << 8); 70.874 + return svga_read(addr, priv) | (svga_read(addr + 1, priv) << 8); 70.875 70.876 egareads += 2; 70.877 70.878 @@ -1300,10 +1148,10 @@ 70.879 return *(uint16_t *)&vram[addr]; 70.880 } 70.881 70.882 -uint32_t svga_readl(uint32_t addr) 70.883 +uint32_t svga_readl(uint32_t addr, void *priv) 70.884 { 70.885 if (!svga_fast) 70.886 - return svga_read(addr) | (svga_read(addr + 1) << 8) | (svga_read(addr + 2) << 16) | (svga_read(addr + 3) << 24); 70.887 + return svga_read(addr, priv) | (svga_read(addr + 1, priv) << 8) | (svga_read(addr + 2, priv) << 16) | (svga_read(addr + 3, priv) << 24); 70.888 70.889 egareads += 4; 70.890 70.891 @@ -1319,12 +1167,12 @@ 70.892 return *(uint32_t *)&vram[addr]; 70.893 } 70.894 70.895 -void svga_writew_linear(uint32_t addr, uint16_t val) 70.896 +void svga_writew_linear(uint32_t addr, uint16_t val, void *priv) 70.897 { 70.898 if (!svga_fast) 70.899 { 70.900 - svga_write_linear(addr, val); 70.901 - svga_write_linear(addr + 1, val >> 8); 70.902 + svga_write_linear(addr, val, priv); 70.903 + svga_write_linear(addr + 1, val >> 8, priv); 70.904 return; 70.905 } 70.906 70.907 @@ -1333,19 +1181,20 @@ 70.908 cycles -= video_timing_w; 70.909 cycles_lost += video_timing_w; 70.910 70.911 + if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val); 70.912 addr &= 0x7FFFFF; 70.913 changedvram[addr >> 10] = changeframecount; 70.914 *(uint16_t *)&vram[addr] = val; 70.915 } 70.916 70.917 -void svga_writel_linear(uint32_t addr, uint32_t val) 70.918 +void svga_writel_linear(uint32_t addr, uint32_t val, void *priv) 70.919 { 70.920 if (!svga_fast) 70.921 { 70.922 - svga_write_linear(addr, val); 70.923 - svga_write_linear(addr + 1, val >> 8); 70.924 - svga_write_linear(addr + 2, val >> 16); 70.925 - svga_write_linear(addr + 3, val >> 24); 70.926 + svga_write_linear(addr, val, priv); 70.927 + svga_write_linear(addr + 1, val >> 8, priv); 70.928 + svga_write_linear(addr + 2, val >> 16, priv); 70.929 + svga_write_linear(addr + 3, val >> 24, priv); 70.930 return; 70.931 } 70.932 70.933 @@ -1354,15 +1203,16 @@ 70.934 cycles -= video_timing_l; 70.935 cycles_lost += video_timing_l; 70.936 70.937 + if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val); 70.938 addr &= 0x7fffff; 70.939 changedvram[addr >> 10] = changeframecount; 70.940 *(uint32_t *)&vram[addr] = val; 70.941 } 70.942 70.943 -uint16_t svga_readw_linear(uint32_t addr) 70.944 +uint16_t svga_readw_linear(uint32_t addr, void *priv) 70.945 { 70.946 if (!svga_fast) 70.947 - return svga_read_linear(addr) | (svga_read_linear(addr + 1) << 8); 70.948 + return svga_read_linear(addr, priv) | (svga_read_linear(addr + 1, priv) << 8); 70.949 70.950 egareads += 2; 70.951 70.952 @@ -1375,10 +1225,10 @@ 70.953 return *(uint16_t *)&vram[addr]; 70.954 } 70.955 70.956 -uint32_t svga_readl_linear(uint32_t addr) 70.957 +uint32_t svga_readl_linear(uint32_t addr, void *priv) 70.958 { 70.959 if (!svga_fast) 70.960 - return svga_read_linear(addr) | (svga_read_linear(addr + 1) << 8) | (svga_read_linear(addr + 2) << 16) | (svga_read_linear(addr + 3) << 24); 70.961 + return svga_read_linear(addr, priv) | (svga_read_linear(addr + 1, priv) << 8) | (svga_read_linear(addr + 2, priv) << 16) | (svga_read_linear(addr + 3, priv) << 24); 70.962 70.963 egareads += 4; 70.964
71.1 --- a/src/vid_svga.h Sun Apr 21 14:54:35 2013 +0100 71.2 +++ b/src/vid_svga.h Mon May 27 17:46:42 2013 +0100 71.3 @@ -1,10 +1,12 @@ 71.4 /*Vertical timings*/ 71.5 extern int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split; 71.6 /*Horizontal timings*/ 71.7 -extern int svga_hdisp, svga_htotal, svga_rowoffset; 71.8 +extern int svga_hdisp, svga_htotal, svga_hdisp_time, svga_rowoffset; 71.9 /*Flags - svga_lowres = 1/2 clock in 256+ colour modes, svga_interlace = interlace mode enabled*/ 71.10 extern int svga_lowres, svga_interlace; 71.11 71.12 +extern int svga_linedbl, svga_rowcount; 71.13 + 71.14 /*Status of display on*/ 71.15 extern int svga_hdisp_on; 71.16 71.17 @@ -35,19 +37,24 @@ 71.18 extern int svga_hwcursor_on; 71.19 extern void (*svga_hwcursor_draw)(int displine); 71.20 71.21 -uint8_t svga_read(uint32_t addr); 71.22 -uint16_t svga_readw(uint32_t addr); 71.23 -uint32_t svga_readl(uint32_t addr); 71.24 -void svga_write(uint32_t addr, uint8_t val); 71.25 -void svga_writew(uint32_t addr, uint16_t val); 71.26 -void svga_writel(uint32_t addr, uint32_t val); 71.27 -uint8_t svga_read_linear(uint32_t addr); 71.28 -uint16_t svga_readw_linear(uint32_t addr); 71.29 -uint32_t svga_readl_linear(uint32_t addr); 71.30 -void svga_write_linear(uint32_t addr, uint8_t val); 71.31 -void svga_writew_linear(uint32_t addr, uint16_t val); 71.32 -void svga_writel_linear(uint32_t addr, uint32_t val); 71.33 +uint8_t svga_read(uint32_t addr, void *priv); 71.34 +uint16_t svga_readw(uint32_t addr, void *priv); 71.35 +uint32_t svga_readl(uint32_t addr, void *priv); 71.36 +void svga_write(uint32_t addr, uint8_t val, void *priv); 71.37 +void svga_writew(uint32_t addr, uint16_t val, void *priv); 71.38 +void svga_writel(uint32_t addr, uint32_t val, void *priv); 71.39 +uint8_t svga_read_linear(uint32_t addr, void *priv); 71.40 +uint16_t svga_readw_linear(uint32_t addr, void *priv); 71.41 +uint32_t svga_readl_linear(uint32_t addr, void *priv); 71.42 +void svga_write_linear(uint32_t addr, uint8_t val, void *priv); 71.43 +void svga_writew_linear(uint32_t addr, uint16_t val, void *priv); 71.44 +void svga_writel_linear(uint32_t addr, uint32_t val, void *priv); 71.45 71.46 void svga_doblit(int y1, int y2); 71.47 71.48 extern uint32_t svga_vram_limit; 71.49 + 71.50 +extern uint8_t svga_rotate[8][256]; 71.51 + 71.52 +void svga_out(uint16_t addr, uint8_t val, void *priv); 71.53 +uint8_t svga_in(uint16_t addr, void *priv);
72.1 --- a/src/vid_tandy.c Sun Apr 21 14:54:35 2013 +0100 72.2 +++ b/src/vid_tandy.c Mon May 27 17:46:42 2013 +0100 72.3 @@ -2,6 +2,7 @@ 72.4 #include "video.h" 72.5 #include "io.h" 72.6 #include "mem.h" 72.7 +#include "timer.h" 72.8 72.9 static int tandy_array_index; 72.10 static uint8_t tandy_array[32]; 72.11 @@ -14,7 +15,7 @@ 72.12 void tandy_recalcaddress(); 72.13 void tandy_recalctimings(); 72.14 72.15 -void tandy_out(uint16_t addr, uint8_t val) 72.16 +void tandy_out(uint16_t addr, uint8_t val, void *priv) 72.17 { 72.18 uint8_t old; 72.19 // pclog("Tandy OUT %04X %02X\n",addr,val); 72.20 @@ -59,7 +60,7 @@ 72.21 } 72.22 } 72.23 72.24 -uint8_t tandy_in(uint16_t addr) 72.25 +uint8_t tandy_in(uint16_t addr, void *priv) 72.26 { 72.27 // if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr); 72.28 switch (addr) 72.29 @@ -90,14 +91,14 @@ 72.30 } 72.31 } 72.32 72.33 -void tandy_write(uint32_t addr, uint8_t val) 72.34 +void tandy_write(uint32_t addr, uint8_t val, void *priv) 72.35 { 72.36 if (tandy_memctrl==-1) return; 72.37 // pclog("Tandy VRAM write %05X %02X %04X:%04X %04X:%04X\n",addr,val,CS,pc,DS,SI); 72.38 tandy_b8000[addr&0x7FFF]=val; 72.39 } 72.40 72.41 -uint8_t tandy_read(uint32_t addr) 72.42 +uint8_t tandy_read(uint32_t addr, void *priv) 72.43 { 72.44 if (tandy_memctrl==-1) return 0xFF; 72.45 // pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy_b8000[addr&0x7FFF],CS,pc); 72.46 @@ -106,19 +107,22 @@ 72.47 72.48 void tandy_recalctimings() 72.49 { 72.50 + double _dispontime, _dispofftime; 72.51 if (tandy_mode&1) 72.52 { 72.53 disptime=crtc[0]+1; 72.54 - dispontime=crtc[1]; 72.55 + _dispontime=crtc[1]; 72.56 } 72.57 else 72.58 { 72.59 disptime=(crtc[0]+1)<<1; 72.60 - dispontime=crtc[1]<<1; 72.61 + _dispontime=crtc[1]<<1; 72.62 } 72.63 - dispofftime=disptime-dispontime; 72.64 - dispontime*=CGACONST; 72.65 - dispofftime*=CGACONST; 72.66 + _dispofftime=disptime-_dispontime; 72.67 + _dispontime*=CGACONST; 72.68 + _dispofftime*=CGACONST; 72.69 + dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); 72.70 + dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); 72.71 } 72.72 72.73 72.74 @@ -127,7 +131,7 @@ 72.75 static int cgadispon; 72.76 static int con,coff,cursoron,cgablink; 72.77 static int vsynctime,vadj; 72.78 -static uint16_t ma,maback,ca; 72.79 +static uint16_t ma,maback; 72.80 72.81 static int ntsc_col[8][8]= 72.82 { 72.83 @@ -157,7 +161,7 @@ 72.84 int x,c; 72.85 int oldvc; 72.86 uint8_t chr,attr; 72.87 - uint16_t dat,dat2,dat3,dat4; 72.88 + uint16_t dat; 72.89 int cols[4]; 72.90 int col; 72.91 int oldsc; 72.92 @@ -582,8 +586,8 @@ 72.93 72.94 int tandy_init() 72.95 { 72.96 - mem_sethandler(0xb8000, 0x8000, tandy_read, NULL, NULL, tandy_write, NULL, NULL); 72.97 - io_sethandler(0x00a0, 0x0002, tandy_in, NULL, NULL, tandy_out, NULL, NULL); 72.98 + mem_sethandler(0xb8000, 0x8000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, NULL); 72.99 + io_sethandler(0x00a0, 0x0002, tandy_in, NULL, NULL, tandy_out, NULL, NULL, NULL); 72.100 tandy_memctrl = -1; 72.101 return 0; 72.102 }
73.1 --- a/src/vid_tkd8001_ramdac.c Sun Apr 21 14:54:35 2013 +0100 73.2 +++ b/src/vid_tkd8001_ramdac.c Mon May 27 17:46:42 2013 +0100 73.3 @@ -7,7 +7,7 @@ 73.4 static int tkd8001_state=0; 73.5 static uint8_t tkd8001_ctrl; 73.6 73.7 -void tkd8001_ramdac_out(uint16_t addr, uint8_t val) 73.8 +void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv) 73.9 { 73.10 // pclog("OUT RAMDAC %04X %02X %04X:%04X\n",addr,val,CS,pc); 73.11 switch (addr) 73.12 @@ -40,10 +40,10 @@ 73.13 tkd8001_state = 0; 73.14 break; 73.15 } 73.16 - svga_out(addr,val); 73.17 + svga_out(addr, val, NULL); 73.18 } 73.19 73.20 -uint8_t tkd8001_ramdac_in(uint16_t addr) 73.21 +uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv) 73.22 { 73.23 // pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc); 73.24 switch (addr) 73.25 @@ -60,5 +60,5 @@ 73.26 tkd8001_state = 0; 73.27 break; 73.28 } 73.29 - return svga_in(addr); 73.30 + return svga_in(addr, NULL); 73.31 }
74.1 --- a/src/vid_tkd8001_ramdac.h Sun Apr 21 14:54:35 2013 +0100 74.2 +++ b/src/vid_tkd8001_ramdac.h Mon May 27 17:46:42 2013 +0100 74.3 @@ -1,2 +1,2 @@ 74.4 -void tkd8001_ramdac_out(uint16_t addr, uint8_t val); 74.5 -uint8_t tkd8001_ramdac_in(uint16_t addr); 74.6 +void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv); 74.7 +uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv);
75.1 --- a/src/vid_tvga.c Sun Apr 21 14:54:35 2013 +0100 75.2 +++ b/src/vid_tvga.c Mon May 27 17:46:42 2013 +0100 75.3 @@ -1,18 +1,37 @@ 75.4 /*Trident TVGA (8900D) emulation*/ 75.5 #include "ibm.h" 75.6 +#include "io.h" 75.7 +#include "mem.h" 75.8 #include "video.h" 75.9 #include "vid_svga.h" 75.10 +#include "vid_svga_render.h" 75.11 #include "vid_tkd8001_ramdac.h" 75.12 75.13 +void tvga_recalcmapping(); 75.14 + 75.15 uint8_t trident3d8,trident3d9; 75.16 int tridentoldmode; 75.17 uint8_t tridentoldctrl2,tridentnewctrl2; 75.18 uint8_t tridentdac; 75.19 75.20 -void tvga_out(uint16_t addr, uint8_t val) 75.21 +uint32_t tvga_linear_base, tvga_linear_size; 75.22 + 75.23 +uint8_t tvga_accel_read(uint32_t addr, void *priv); 75.24 +uint16_t tvga_accel_read_w(uint32_t addr, void *priv); 75.25 +uint32_t tvga_accel_read_l(uint32_t addr, void *priv); 75.26 + 75.27 +void tvga_accel_write(uint32_t addr, uint8_t val, void *priv); 75.28 +void tvga_accel_write_w(uint32_t addr, uint16_t val, void *priv); 75.29 +void tvga_accel_write_l(uint32_t addr, uint32_t val, void *priv); 75.30 + 75.31 + 75.32 +void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv); 75.33 + 75.34 +void tvga_out(uint16_t addr, uint8_t val, void *priv) 75.35 { 75.36 uint8_t old; 75.37 75.38 +// pclog("tvga_out : %04X %02X %04X:%04X %i\n", addr, val, CS,pc, bpp); 75.39 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 75.40 75.41 switch (addr) 75.42 @@ -32,12 +51,24 @@ 75.43 break; 75.44 75.45 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 75.46 - tkd8001_ramdac_out(addr,val); 75.47 - return; 75.48 + if (gfxcard != GFX_TGUI9440) 75.49 + { 75.50 + tkd8001_ramdac_out(addr, val, NULL); 75.51 + return; 75.52 + } 75.53 + break; 75.54 75.55 case 0x3CF: 75.56 switch (gdcaddr&15) 75.57 { 75.58 + case 0x6: 75.59 + if (gdcreg[6] != val) 75.60 + { 75.61 + gdcreg[6] = val; 75.62 + tvga_recalcmapping(); 75.63 + } 75.64 + return; 75.65 + 75.66 case 0xE: 75.67 gdcreg[0xE]=val^2; 75.68 if ((gdcreg[0xF]&1)==1) 75.69 @@ -51,7 +82,8 @@ 75.70 } 75.71 break; 75.72 case 0x3D4: 75.73 - crtcreg=val&63; 75.74 + if (gfxcard == GFX_TGUI9440) crtcreg = val & 0x7f; 75.75 + else crtcreg = val & 0x3f; 75.76 return; 75.77 case 0x3D5: 75.78 if (crtcreg <= 7 && crtc[0x11] & 0x80) return; 75.79 @@ -66,6 +98,37 @@ 75.80 svga_recalctimings(); 75.81 } 75.82 } 75.83 + switch (crtcreg) 75.84 + { 75.85 + case 0x21: 75.86 + if (old != val) 75.87 + tvga_recalcmapping(); 75.88 + break; 75.89 + 75.90 + 75.91 + case 0x38: /*Pixel bus register*/ 75.92 +// pclog("Pixel bus register %02X\n", val); 75.93 + if (gfxcard != GFX_TGUI9440) 75.94 + break; 75.95 + 75.96 + if ((val & 0xc) == 4) bpp = 16; 75.97 + else if (!(val & 0xc)) bpp = 8; 75.98 + else bpp = 24; 75.99 + break; 75.100 + 75.101 + case 0x40: case 0x41: case 0x42: case 0x43: 75.102 + case 0x44: case 0x45: case 0x46: case 0x47: 75.103 + svga_hwcursor.x = (crtc[0x40] | (crtc[0x41] << 8)) & 0x7ff; 75.104 + svga_hwcursor.y = (crtc[0x42] | (crtc[0x43] << 8)) & 0x7ff; 75.105 + svga_hwcursor.xoff = crtc[0x46] & 0x3f; 75.106 + svga_hwcursor.yoff = crtc[0x47] & 0x3f; 75.107 + svga_hwcursor.addr = (crtc[0x44] << 10) | ((crtc[0x45] & 0x7) << 18) | (svga_hwcursor.yoff * 8); 75.108 + break; 75.109 + 75.110 + case 0x50: 75.111 + svga_hwcursor.ena = val & 0x80; 75.112 + break; 75.113 + } 75.114 return; 75.115 case 0x3D8: 75.116 trident3d8=val; 75.117 @@ -89,12 +152,12 @@ 75.118 } 75.119 return; 75.120 } 75.121 - svga_out(addr,val); 75.122 + svga_out(addr, val, priv); 75.123 } 75.124 75.125 -uint8_t tvga_in(uint16_t addr) 75.126 +uint8_t tvga_in(uint16_t addr, void *priv) 75.127 { 75.128 - uint8_t temp; 75.129 +// if (addr != 0x3da) pclog("tvga_in : %04X %04X:%04X\n", addr, CS,pc); 75.130 75.131 if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60; 75.132 75.133 @@ -105,7 +168,8 @@ 75.134 { 75.135 // printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); 75.136 tridentoldmode=0; 75.137 - return 0x33; /*TVGA8900D*/ 75.138 + if (gfxcard == GFX_TVGA) return 0x33; /*TVGA8900D*/ 75.139 + else return 0xe3; /*TGUI9440AGi*/ 75.140 } 75.141 if ((seqaddr&0xF)==0xC) 75.142 { 75.143 @@ -119,15 +183,21 @@ 75.144 } 75.145 break; 75.146 case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: 75.147 - return tkd8001_ramdac_in(addr); 75.148 + if (gfxcard != GFX_TGUI9440) 75.149 + return tkd8001_ramdac_in(addr, NULL); 75.150 + break; 75.151 case 0x3CD: /*Banking*/ 75.152 return svgaseg; 75.153 case 0x3D4: 75.154 return crtcreg; 75.155 case 0x3D5: 75.156 return crtc[crtcreg]; 75.157 + case 0x3d8: 75.158 + return trident3d8; 75.159 + case 0x3d9: 75.160 + return trident3d9; 75.161 } 75.162 - return svga_in(addr); 75.163 + return svga_in(addr, priv); 75.164 } 75.165 75.166 void tvga_recalctimings() 75.167 @@ -147,7 +217,9 @@ 75.168 } 75.169 if (tridentoldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/ 75.170 svga_lowres=0; 75.171 - 75.172 + if (gfxcard == GFX_TGUI9440) 75.173 + svga_lowres = !(crtc[0x2a] & 0x40); 75.174 + 75.175 if (gdcreg[0xF] & 8) 75.176 { 75.177 svga_htotal<<=1; 75.178 @@ -166,16 +238,703 @@ 75.179 case 6: svga_clock = cpuclock/50350000.0; break; 75.180 case 7: svga_clock = cpuclock/40000000.0; break; 75.181 } 75.182 + 75.183 + if ((tridentoldctrl2 & 0x10) || (gfxcard == GFX_TGUI9440 && (crtc[0x2a] & 0x40))) 75.184 + { 75.185 + switch (bpp) 75.186 + { 75.187 + case 8: 75.188 + svga_render = svga_render_8bpp_highres; 75.189 + break; 75.190 + case 15: 75.191 + svga_render = svga_render_15bpp_highres; 75.192 + break; 75.193 + case 16: 75.194 + svga_render = svga_render_16bpp_highres; 75.195 + break; 75.196 + case 24: 75.197 + svga_render = svga_render_24bpp_highres; 75.198 + break; 75.199 + case 32: 75.200 + svga_render = svga_render_32bpp_highres; 75.201 + break; 75.202 + } 75.203 + } 75.204 +} 75.205 + 75.206 +void tvga_recalcmapping() 75.207 +{ 75.208 + pclog("tvga_recalcmapping : %02X %02X\n", crtc[0x21], gdcreg[6]); 75.209 + mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 75.210 + mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); 75.211 + mem_removehandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL, NULL); 75.212 + 75.213 + if (crtc[0x21] & 0x20) 75.214 + { 75.215 + tvga_linear_base = ((crtc[0x21] & 0xf) | ((crtc[0x21] >> 2) & 0x30)) << 20; 75.216 + tvga_linear_size = (crtc[0x21] & 0x10) ? 0x200000 : 0x100000; 75.217 + mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); 75.218 + pclog("Trident linear framebuffer at %08X - size %06X\n", tvga_linear_base, tvga_linear_size); 75.219 + mem_sethandler(0xbc000, 0x4000, tvga_accel_read, tvga_accel_read_w, tvga_accel_read_l, tvga_accel_write, tvga_accel_write_w, tvga_accel_write_l, NULL); 75.220 + } 75.221 + else 75.222 + { 75.223 +// pclog("Write mapping %02X\n", val); 75.224 + switch (gdcreg[6] & 0xC) 75.225 + { 75.226 + case 0x0: /*128k at A0000*/ 75.227 + mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 75.228 + break; 75.229 + case 0x4: /*64k at A0000*/ 75.230 + mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 75.231 + mem_sethandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL, NULL); 75.232 + break; 75.233 + case 0x8: /*32k at B0000*/ 75.234 + mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 75.235 + break; 75.236 + case 0xC: /*32k at B8000*/ 75.237 + mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL); 75.238 + break; 75.239 + } 75.240 + } 75.241 +} 75.242 + 75.243 +void tvga_hwcursor_draw(int displine) 75.244 +{ 75.245 +// int x; 75.246 + uint32_t dat[2]; 75.247 + int xx; 75.248 + int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff; 75.249 + 75.250 +// pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y); 75.251 +// for (x = 0; x < 32; x += 32) 75.252 +// { 75.253 + dat[0] = (vram[svga_hwcursor_latch.addr] << 24) | (vram[svga_hwcursor_latch.addr + 1] << 16) | (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3]; 75.254 + dat[1] = (vram[svga_hwcursor_latch.addr + 4] << 24) | (vram[svga_hwcursor_latch.addr + 5] << 16) | (vram[svga_hwcursor_latch.addr + 6] << 8) | vram[svga_hwcursor_latch.addr + 7]; 75.255 + for (xx = 0; xx < 32; xx++) 75.256 + { 75.257 + if (offset >= svga_hwcursor_latch.x) 75.258 + { 75.259 + if (!(dat[0] & 0x80000000)) 75.260 + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x80000000) ? 0xffffff : 0; 75.261 + else if (dat[1] & 0x80000000) 75.262 + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; 75.263 +// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]); 75.264 + } 75.265 + 75.266 + offset++; 75.267 + dat[0] <<= 1; 75.268 + dat[1] <<= 1; 75.269 + } 75.270 + svga_hwcursor_latch.addr += 8; 75.271 +// } 75.272 } 75.273 75.274 int tvga_init() 75.275 { 75.276 svga_recalctimings_ex = tvga_recalctimings; 75.277 - svga_vram_limit = 1 << 20; /*1mb - chip supports 2mb, but drivers are buggy*/ 75.278 - vrammask = 0xfffff; 75.279 + svga_hwcursor_draw = tvga_hwcursor_draw; 75.280 + if (gfxcard == GFX_TVGA) 75.281 + { 75.282 + vrammask = 0xfffff; 75.283 + svga_vram_limit = 1 << 20; /*1mb - chip supports 2mb, but drivers are buggy*/ 75.284 + } 75.285 + else 75.286 + { 75.287 + vrammask = 0x1fffff; 75.288 + svga_vram_limit = 1 << 21; /*2mb*/ 75.289 + } 75.290 return svga_init(); 75.291 } 75.292 75.293 +struct tvga_accel 75.294 +{ 75.295 + uint16_t src_x, src_y; 75.296 + uint16_t dst_x, dst_y; 75.297 + uint16_t size_x, size_y; 75.298 + uint16_t fg_col, bg_col; 75.299 + uint8_t rop; 75.300 + uint16_t flags; 75.301 + uint8_t pattern[0x80]; 75.302 + int command; 75.303 + int offset; 75.304 + uint8_t ger22; 75.305 + 75.306 + int x, y; 75.307 + uint32_t src, dst, src_old, dst_old; 75.308 + int pat_x, pat_y; 75.309 + int use_src; 75.310 + 75.311 + int pitch, bpp; 75.312 +} tvga_accel; 75.313 + 75.314 +enum 75.315 +{ 75.316 + TGUI_BITBLT = 1 75.317 +}; 75.318 + 75.319 +enum 75.320 +{ 75.321 + TGUI_SRCCPU = 0, 75.322 + 75.323 + TGUI_SRCDISP = 0x04, /*Source is from display*/ 75.324 + TGUI_PATMONO = 0x20, /*Pattern is monochrome and needs expansion*/ 75.325 + TGUI_SRCMONO = 0x40, /*Source is monochrome from CPU and needs expansion*/ 75.326 + TGUI_TRANSENA = 0x1000, /*Transparent (no draw when source == bg col)*/ 75.327 + TGUI_TRANSREV = 0x2000, /*Reverse fg/bg for transparent*/ 75.328 + TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/ 75.329 +}; 75.330 + 75.331 +#define READ(addr, dat) if (tvga_accel.bpp == 0) dat = vram[addr & 0x1fffff]; \ 75.332 + else dat = vram_w[addr & 0xfffff]; 75.333 + 75.334 +#define MIX() do \ 75.335 + { \ 75.336 + out = 0; \ 75.337 + for (c=0;c<16;c++) \ 75.338 + { \ 75.339 + d=(dst_dat & (1<<c)) ? 1:0; \ 75.340 + if (src_dat & (1<<c)) d|=2; \ 75.341 + if (pat_dat & (1<<c)) d|=4; \ 75.342 + if (tvga_accel.rop & (1<<d)) out|=(1<<c); \ 75.343 + } \ 75.344 + } while (0) 75.345 + 75.346 +#define WRITE(addr, dat) if (tvga_accel.bpp == 0) \ 75.347 + { \ 75.348 + vram[addr & 0x1fffff] = dat; \ 75.349 + changedvram[((addr) & 0x1fffff) >> 10] = changeframecount; \ 75.350 + } \ 75.351 + else \ 75.352 + { \ 75.353 + vram_w[addr & 0xfffff] = dat; \ 75.354 + changedvram[((addr) & 0xfffff) >> 9] = changeframecount; \ 75.355 + } 75.356 + 75.357 +static uint16_t tvga_pattern[8][8]; 75.358 + 75.359 +void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv); 75.360 +void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv); 75.361 + 75.362 +void tvga_accel_command(int count, uint32_t cpu_dat) 75.363 +{ 75.364 + int x, y; 75.365 + int c, d; 75.366 + uint16_t src_dat, dst_dat, pat_dat; 75.367 + uint16_t out; 75.368 + int xdir = (tvga_accel.flags & 0x200) ? -1 : 1; 75.369 + int ydir = (tvga_accel.flags & 0x100) ? -1 : 1; 75.370 + uint16_t trans_col = (tvga_accel.flags & TGUI_TRANSREV) ? tvga_accel.fg_col : tvga_accel.bg_col; 75.371 + uint16_t *vram_w = (uint16_t *)vram; 75.372 + 75.373 + if (tvga_accel.bpp == 0) 75.374 + trans_col &= 0xff; 75.375 + 75.376 + if (count != -1 && !tvga_accel.x) 75.377 + { 75.378 + count -= tvga_accel.offset; 75.379 + cpu_dat <<= tvga_accel.offset; 75.380 + } 75.381 + if (count == -1) 75.382 + { 75.383 + tvga_accel.x = tvga_accel.y = 0; 75.384 + } 75.385 + if (tvga_accel.flags & TGUI_SOLIDFILL) 75.386 + { 75.387 +// pclog("SOLIDFILL\n"); 75.388 + for (y = 0; y < 8; y++) 75.389 + { 75.390 + for (x = 0; x < 8; x++) 75.391 + { 75.392 + tvga_pattern[y][x] = tvga_accel.fg_col; 75.393 + } 75.394 + } 75.395 + } 75.396 + else if (tvga_accel.flags & TGUI_PATMONO) 75.397 + { 75.398 +// pclog("PATMONO\n"); 75.399 + for (y = 0; y < 8; y++) 75.400 + { 75.401 + for (x = 0; x < 8; x++) 75.402 + { 75.403 + tvga_pattern[y][x] = (tvga_accel.pattern[y] & (1 << x)) ? tvga_accel.fg_col : tvga_accel.bg_col; 75.404 + } 75.405 + } 75.406 + } 75.407 + else 75.408 + { 75.409 +// pclog("OTHER\n"); 75.410 + for (y = 0; y < 8; y++) 75.411 + { 75.412 + for (x = 0; x < 8; x++) 75.413 + { 75.414 + tvga_pattern[y][x] = tvga_accel.pattern[x + y*8]; 75.415 + } 75.416 + } 75.417 + } 75.418 + for (y = 0; y < 8; y++) 75.419 + { 75.420 + if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tvga_pattern[y][0], tvga_pattern[y][1], tvga_pattern[y][2], tvga_pattern[y][3], tvga_pattern[y][4], tvga_pattern[y][5], tvga_pattern[y][6], tvga_pattern[y][7]); 75.421 + } 75.422 + if (count == -1) pclog("Command %i %i\n", tvga_accel.command, TGUI_BITBLT); 75.423 + switch (tvga_accel.command) 75.424 + { 75.425 + case TGUI_BITBLT: 75.426 + if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tvga_accel.src_x, tvga_accel.src_y, tvga_accel.dst_x, tvga_accel.dst_y, tvga_accel.size_x, tvga_accel.size_y, tvga_accel.flags); 75.427 + if (count == -1) 75.428 + { 75.429 + tvga_accel.src = tvga_accel.src_old = tvga_accel.src_x + (tvga_accel.src_y * tvga_accel.pitch); 75.430 + tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_x + (tvga_accel.dst_y * tvga_accel.pitch); 75.431 + tvga_accel.pat_x = tvga_accel.dst_x; 75.432 + tvga_accel.pat_y = tvga_accel.dst_y; 75.433 + } 75.434 + 75.435 + switch (tvga_accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP)) 75.436 + { 75.437 + case TGUI_SRCCPU: 75.438 + if (count == -1) 75.439 + { 75.440 +// pclog("Blit start\n"); 75.441 + if (crtc[0x21] & 0x20) 75.442 + { 75.443 + mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); 75.444 + mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); 75.445 + } 75.446 + if (tvga_accel.use_src) 75.447 + return; 75.448 + } 75.449 + else 75.450 + count >>= 3; 75.451 + while (count) 75.452 + { 75.453 + if (tvga_accel.bpp == 0) 75.454 + { 75.455 + src_dat = cpu_dat >> 24; 75.456 + cpu_dat <<= 8; 75.457 + } 75.458 + else 75.459 + { 75.460 + src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00); 75.461 + cpu_dat <<= 16; 75.462 + count--; 75.463 + } 75.464 + READ(tvga_accel.dst, dst_dat); 75.465 + pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7]; 75.466 + 75.467 + if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col) 75.468 + { 75.469 + MIX(); 75.470 + 75.471 + WRITE(tvga_accel.dst, out); 75.472 + } 75.473 + 75.474 +// pclog(" %i,%i %02X %02X %02X %02X\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out); 75.475 + 75.476 + tvga_accel.src += xdir; 75.477 + tvga_accel.dst += xdir; 75.478 + tvga_accel.pat_x += xdir; 75.479 + 75.480 + tvga_accel.x++; 75.481 + if (tvga_accel.x > tvga_accel.size_x) 75.482 + { 75.483 + tvga_accel.x = 0; 75.484 + tvga_accel.y++; 75.485 + 75.486 + tvga_accel.pat_x = tvga_accel.dst_x; 75.487 + 75.488 + tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch); 75.489 + tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch); 75.490 + tvga_accel.pat_y += ydir; 75.491 + 75.492 + if (tvga_accel.y > tvga_accel.size_y) 75.493 + { 75.494 + if (crtc[0x21] & 0x20) 75.495 + { 75.496 +// pclog("Blit end\n"); 75.497 + mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); 75.498 + mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); 75.499 + } 75.500 + return; 75.501 + } 75.502 + if (tvga_accel.use_src) 75.503 + return; 75.504 + } 75.505 + count--; 75.506 + } 75.507 + break; 75.508 + 75.509 + case TGUI_SRCMONO | TGUI_SRCCPU: 75.510 + if (count == -1) 75.511 + { 75.512 +// pclog("Blit start\n"); 75.513 + if (crtc[0x21] & 0x20) 75.514 + { 75.515 + mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); 75.516 + mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); 75.517 + } 75.518 + if (tvga_accel.use_src) 75.519 + return; 75.520 + } 75.521 +// pclog("TGUI_SRCMONO | TGUI_SRCCPU\n"); 75.522 + while (count) 75.523 + { 75.524 + src_dat = ((cpu_dat >> 31) ? tvga_accel.fg_col : tvga_accel.bg_col); 75.525 + if (tvga_accel.bpp == 0) 75.526 + src_dat &= 0xff; 75.527 + 75.528 + READ(tvga_accel.dst, dst_dat); 75.529 + pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7]; 75.530 + 75.531 + if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col) 75.532 + { 75.533 + MIX(); 75.534 + 75.535 + WRITE(tvga_accel.dst, out); 75.536 + } 75.537 +// pclog(" %i,%i %02X %02X %02X %02X %i\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out, (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col)); 75.538 + cpu_dat <<= 1; 75.539 + tvga_accel.src += xdir; 75.540 + tvga_accel.dst += xdir; 75.541 + tvga_accel.pat_x += xdir; 75.542 + 75.543 + tvga_accel.x++; 75.544 + if (tvga_accel.x > tvga_accel.size_x) 75.545 + { 75.546 + tvga_accel.x = 0; 75.547 + tvga_accel.y++; 75.548 + 75.549 + tvga_accel.pat_x = tvga_accel.dst_x; 75.550 + 75.551 + tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch); 75.552 + tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch); 75.553 + tvga_accel.pat_y += ydir; 75.554 + 75.555 + if (tvga_accel.y > tvga_accel.size_y) 75.556 + { 75.557 + if (crtc[0x21] & 0x20) 75.558 + { 75.559 +// pclog("Blit end\n"); 75.560 + mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l, NULL); 75.561 + mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL); 75.562 + } 75.563 + return; 75.564 + } 75.565 + if (tvga_accel.use_src) 75.566 + return; 75.567 + } 75.568 + count--; 75.569 + } 75.570 + break; 75.571 + 75.572 + default: 75.573 + while (count) 75.574 + { 75.575 + READ(tvga_accel.src, src_dat); 75.576 + READ(tvga_accel.dst, dst_dat); 75.577 + pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7]; 75.578 + 75.579 + if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col) 75.580 + { 75.581 + MIX(); 75.582 + 75.583 + WRITE(tvga_accel.dst, out); 75.584 + } 75.585 +// pclog(" %i,%i %02X %02X %02X %02X\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out); 75.586 + 75.587 + tvga_accel.src += xdir; 75.588 + tvga_accel.dst += xdir; 75.589 + tvga_accel.pat_x += xdir; 75.590 + 75.591 + tvga_accel.x++; 75.592 + if (tvga_accel.x > tvga_accel.size_x) 75.593 + { 75.594 + tvga_accel.x = 0; 75.595 + tvga_accel.y++; 75.596 + 75.597 + tvga_accel.pat_x = tvga_accel.dst_x; 75.598 + 75.599 + tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch); 75.600 + tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch); 75.601 + tvga_accel.pat_y += ydir; 75.602 + 75.603 + if (tvga_accel.y > tvga_accel.size_y) 75.604 + return; 75.605 + } 75.606 + count--; 75.607 + } 75.608 + break; 75.609 + } 75.610 + break; 75.611 + } 75.612 +} 75.613 + 75.614 +void tvga_accel_write(uint32_t addr, uint8_t val, void *priv) 75.615 +{ 75.616 + pclog("tvga_accel_write : %08X %02X %04X(%08X):%08X %02X\n", addr, val, CS,cs,pc, opcode); 75.617 + if ((addr & ~0xff) != 0xbff00) 75.618 + return; 75.619 + switch (addr & 0xff) 75.620 + { 75.621 + case 0x22: 75.622 + tvga_accel.ger22 = val; 75.623 + tvga_accel.pitch = 512 << ((val >> 2) & 3); 75.624 + tvga_accel.bpp = (val & 3) ? 1 : 0; 75.625 + tvga_accel.pitch >>= tvga_accel.bpp; 75.626 + break; 75.627 + 75.628 + case 0x24: /*Command*/ 75.629 + tvga_accel.command = val; 75.630 + tvga_accel_command(-1, 0); 75.631 + break; 75.632 + 75.633 + case 0x27: /*ROP*/ 75.634 + tvga_accel.rop = val; 75.635 + tvga_accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); 75.636 + pclog("Write ROP %02X %i\n", val, tvga_accel.use_src); 75.637 + break; 75.638 + 75.639 + case 0x28: /*Flags*/ 75.640 + tvga_accel.flags = (tvga_accel.flags & 0xff00) | val; 75.641 + break; 75.642 + case 0x29: /*Flags*/ 75.643 + tvga_accel.flags = (tvga_accel.flags & 0xff) | (val << 8); 75.644 + break; 75.645 + 75.646 + case 0x2b: 75.647 + tvga_accel.offset = val & 7; 75.648 + break; 75.649 + 75.650 + case 0x2c: /*Foreground colour*/ 75.651 + tvga_accel.fg_col = (tvga_accel.fg_col & 0xff00) | val; 75.652 + break; 75.653 + case 0x2d: /*Foreground colour*/ 75.654 + tvga_accel.fg_col = (tvga_accel.fg_col & 0xff) | (val << 8); 75.655 + break; 75.656 + 75.657 + case 0x30: /*Background colour*/ 75.658 + tvga_accel.bg_col = (tvga_accel.bg_col & 0xff00) | val; 75.659 + break; 75.660 + case 0x31: /*Background colour*/ 75.661 + tvga_accel.bg_col = (tvga_accel.bg_col & 0xff) | (val << 8); 75.662 + break; 75.663 + 75.664 + case 0x38: /*Dest X*/ 75.665 + tvga_accel.dst_x = (tvga_accel.dst_x & 0xff00) | val; 75.666 + break; 75.667 + case 0x39: /*Dest X*/ 75.668 + tvga_accel.dst_x = (tvga_accel.dst_x & 0xff) | (val << 8); 75.669 + break; 75.670 + case 0x3a: /*Dest Y*/ 75.671 + tvga_accel.dst_y = (tvga_accel.dst_y & 0xff00) | val; 75.672 + break; 75.673 + case 0x3b: /*Dest Y*/ 75.674 + tvga_accel.dst_y = (tvga_accel.dst_y & 0xff) | (val << 8); 75.675 + break; 75.676 + 75.677 + case 0x3c: /*Src X*/ 75.678 + tvga_accel.src_x = (tvga_accel.src_x & 0xff00) | val; 75.679 + break; 75.680 + case 0x3d: /*Src X*/ 75.681 + tvga_accel.src_x = (tvga_accel.src_x & 0xff) | (val << 8); 75.682 + break; 75.683 + case 0x3e: /*Src Y*/ 75.684 + tvga_accel.src_y = (tvga_accel.src_y & 0xff00) | val; 75.685 + break; 75.686 + case 0x3f: /*Src Y*/ 75.687 + tvga_accel.src_y = (tvga_accel.src_y & 0xff) | (val << 8); 75.688 + break; 75.689 + 75.690 + case 0x40: /*Size X*/ 75.691 + tvga_accel.size_x = (tvga_accel.size_x & 0xff00) | val; 75.692 + break; 75.693 + case 0x41: /*Size X*/ 75.694 + tvga_accel.size_x = (tvga_accel.size_x & 0xff) | (val << 8); 75.695 + break; 75.696 + case 0x42: /*Size Y*/ 75.697 + tvga_accel.size_y = (tvga_accel.size_y & 0xff00) | val; 75.698 + break; 75.699 + case 0x43: /*Size Y*/ 75.700 + tvga_accel.size_y = (tvga_accel.size_y & 0xff) | (val << 8); 75.701 + break; 75.702 + 75.703 + case 0x80: case 0x81: case 0x82: case 0x83: 75.704 + case 0x84: case 0x85: case 0x86: case 0x87: 75.705 + case 0x88: case 0x89: case 0x8a: case 0x8b: 75.706 + case 0x8c: case 0x8d: case 0x8e: case 0x8f: 75.707 + case 0x90: case 0x91: case 0x92: case 0x93: 75.708 + case 0x94: case 0x95: case 0x96: case 0x97: 75.709 + case 0x98: case 0x99: case 0x9a: case 0x9b: 75.710 + case 0x9c: case 0x9d: case 0x9e: case 0x9f: 75.711 + case 0xa0: case 0xa1: case 0xa2: case 0xa3: 75.712 + case 0xa4: case 0xa5: case 0xa6: case 0xa7: 75.713 + case 0xa8: case 0xa9: case 0xaa: case 0xab: 75.714 + case 0xac: case 0xad: case 0xae: case 0xaf: 75.715 + case 0xb0: case 0xb1: case 0xb2: case 0xb3: 75.716 + case 0xb4: case 0xb5: case 0xb6: case 0xb7: 75.717 + case 0xb8: case 0xb9: case 0xba: case 0xbb: 75.718 + case 0xbc: case 0xbd: case 0xbe: case 0xbf: 75.719 + case 0xc0: case 0xc1: case 0xc2: case 0xc3: 75.720 + case 0xc4: case 0xc5: case 0xc6: case 0xc7: 75.721 + case 0xc8: case 0xc9: case 0xca: case 0xcb: 75.722 + case 0xcc: case 0xcd: case 0xce: case 0xcf: 75.723 + case 0xd0: case 0xd1: case 0xd2: case 0xd3: 75.724 + case 0xd4: case 0xd5: case 0xd6: case 0xd7: 75.725 + case 0xd8: case 0xd9: case 0xda: case 0xdb: 75.726 + case 0xdc: case 0xdd: case 0xde: case 0xdf: 75.727 + case 0xe0: case 0xe1: case 0xe2: case 0xe3: 75.728 + case 0xe4: case 0xe5: case 0xe6: case 0xe7: 75.729 + case 0xe8: case 0xe9: case 0xea: case 0xeb: 75.730 + case 0xec: case 0xed: case 0xee: case 0xef: 75.731 + case 0xf0: case 0xf1: case 0xf2: case 0xf3: 75.732 + case 0xf4: case 0xf5: case 0xf6: case 0xf7: 75.733 + case 0xf8: case 0xf9: case 0xfa: case 0xfb: 75.734 + case 0xfc: case 0xfd: case 0xfe: case 0xff: 75.735 + tvga_accel.pattern[addr & 0x7f] = val; 75.736 + break; 75.737 + } 75.738 +} 75.739 + 75.740 +void tvga_accel_write_w(uint32_t addr, uint16_t val, void *priv) 75.741 +{ 75.742 + pclog("tvga_accel_write_w %08X %04X\n", addr, val); 75.743 + tvga_accel_write(addr, val, NULL); 75.744 + tvga_accel_write(addr + 1, val >> 8, NULL); 75.745 +} 75.746 + 75.747 +void tvga_accel_write_l(uint32_t addr, uint32_t val, void *priv) 75.748 +{ 75.749 + pclog("tvga_accel_write_l %08X %08X\n", addr, val); 75.750 + tvga_accel_write(addr, val, NULL); 75.751 + tvga_accel_write(addr + 1, val >> 8, NULL); 75.752 + tvga_accel_write(addr + 2, val >> 16, NULL); 75.753 + tvga_accel_write(addr + 3, val >> 24, NULL); 75.754 +} 75.755 + 75.756 +uint8_t tvga_accel_read(uint32_t addr, void *priv) 75.757 +{ 75.758 +// pclog("tvga_accel_read : %08X\n", addr); 75.759 + if ((addr & ~0xff) != 0xbff00) 75.760 + return 0xff; 75.761 + switch (addr & 0xff) 75.762 + { 75.763 + case 0x20: /*Status*/ 75.764 + return 0; 75.765 + 75.766 + case 0x27: /*ROP*/ 75.767 + return tvga_accel.rop; 75.768 + 75.769 + case 0x28: /*Flags*/ 75.770 + return tvga_accel.flags & 0xff; 75.771 + case 0x29: /*Flags*/ 75.772 + return tvga_accel.flags >> 8; 75.773 + 75.774 + case 0x2b: 75.775 + return tvga_accel.offset; 75.776 + 75.777 + case 0x2c: /*Background colour*/ 75.778 + return tvga_accel.bg_col & 0xff; 75.779 + case 0x2d: /*Background colour*/ 75.780 + return tvga_accel.bg_col >> 8; 75.781 + 75.782 + case 0x30: /*Foreground colour*/ 75.783 + return tvga_accel.fg_col & 0xff; 75.784 + case 0x31: /*Foreground colour*/ 75.785 + return tvga_accel.fg_col >> 8; 75.786 + 75.787 + case 0x38: /*Dest X*/ 75.788 + return tvga_accel.dst_x & 0xff; 75.789 + case 0x39: /*Dest X*/ 75.790 + return tvga_accel.dst_x >> 8; 75.791 + case 0x3a: /*Dest Y*/ 75.792 + return tvga_accel.dst_y & 0xff; 75.793 + case 0x3b: /*Dest Y*/ 75.794 + return tvga_accel.dst_y >> 8; 75.795 + 75.796 + case 0x3c: /*Src X*/ 75.797 + return tvga_accel.src_x & 0xff; 75.798 + case 0x3d: /*Src X*/ 75.799 + return tvga_accel.src_x >> 8; 75.800 + case 0x3e: /*Src Y*/ 75.801 + return tvga_accel.src_y & 0xff; 75.802 + case 0x3f: /*Src Y*/ 75.803 + return tvga_accel.src_y >> 8; 75.804 + 75.805 + case 0x40: /*Size X*/ 75.806 + return tvga_accel.size_x & 0xff; 75.807 + case 0x41: /*Size X*/ 75.808 + return tvga_accel.size_x >> 8; 75.809 + case 0x42: /*Size Y*/ 75.810 + return tvga_accel.size_y & 0xff; 75.811 + case 0x43: /*Size Y*/ 75.812 + return tvga_accel.size_y >> 8; 75.813 + 75.814 + case 0x80: case 0x81: case 0x82: case 0x83: 75.815 + case 0x84: case 0x85: case 0x86: case 0x87: 75.816 + case 0x88: case 0x89: case 0x8a: case 0x8b: 75.817 + case 0x8c: case 0x8d: case 0x8e: case 0x8f: 75.818 + case 0x90: case 0x91: case 0x92: case 0x93: 75.819 + case 0x94: case 0x95: case 0x96: case 0x97: 75.820 + case 0x98: case 0x99: case 0x9a: case 0x9b: 75.821 + case 0x9c: case 0x9d: case 0x9e: case 0x9f: 75.822 + case 0xa0: case 0xa1: case 0xa2: case 0xa3: 75.823 + case 0xa4: case 0xa5: case 0xa6: case 0xa7: 75.824 + case 0xa8: case 0xa9: case 0xaa: case 0xab: 75.825 + case 0xac: case 0xad: case 0xae: case 0xaf: 75.826 + case 0xb0: case 0xb1: case 0xb2: case 0xb3: 75.827 + case 0xb4: case 0xb5: case 0xb6: case 0xb7: 75.828 + case 0xb8: case 0xb9: case 0xba: case 0xbb: 75.829 + case 0xbc: case 0xbd: case 0xbe: case 0xbf: 75.830 + case 0xc0: case 0xc1: case 0xc2: case 0xc3: 75.831 + case 0xc4: case 0xc5: case 0xc6: case 0xc7: 75.832 + case 0xc8: case 0xc9: case 0xca: case 0xcb: 75.833 + case 0xcc: case 0xcd: case 0xce: case 0xcf: 75.834 + case 0xd0: case 0xd1: case 0xd2: case 0xd3: 75.835 + case 0xd4: case 0xd5: case 0xd6: case 0xd7: 75.836 + case 0xd8: case 0xd9: case 0xda: case 0xdb: 75.837 + case 0xdc: case 0xdd: case 0xde: case 0xdf: 75.838 + case 0xe0: case 0xe1: case 0xe2: case 0xe3: 75.839 + case 0xe4: case 0xe5: case 0xe6: case 0xe7: 75.840 + case 0xe8: case 0xe9: case 0xea: case 0xeb: 75.841 + case 0xec: case 0xed: case 0xee: case 0xef: 75.842 + case 0xf0: case 0xf1: case 0xf2: case 0xf3: 75.843 + case 0xf4: case 0xf5: case 0xf6: case 0xf7: 75.844 + case 0xf8: case 0xf9: case 0xfa: case 0xfb: 75.845 + case 0xfc: case 0xfd: case 0xfe: case 0xff: 75.846 + return tvga_accel.pattern[addr & 0x7f]; 75.847 + } 75.848 + return 0xff; 75.849 +} 75.850 + 75.851 +uint16_t tvga_accel_read_w(uint32_t addr, void *priv) 75.852 +{ 75.853 + pclog("tvga_accel_read_w %08X\n", addr); 75.854 + return tvga_accel_read(addr, NULL) | (tvga_accel_read(addr + 1, NULL) << 8); 75.855 +} 75.856 + 75.857 +uint32_t tvga_accel_read_l(uint32_t addr, void *priv) 75.858 +{ 75.859 + pclog("tvga_accel_read_l %08X\n", addr); 75.860 + return tvga_accel_read_w(addr, NULL) | (tvga_accel_read_w(addr + 2, NULL) << 16); 75.861 +} 75.862 + 75.863 +void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv) 75.864 +{ 75.865 +// pclog("tvga_accel_write_fb_b %08X %02X\n", addr, val); 75.866 + tvga_accel_command(8, val << 24); 75.867 +} 75.868 + 75.869 +void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv) 75.870 +{ 75.871 +// pclog("tvga_accel_write_fb_w %08X %04X\n", addr, val); 75.872 + tvga_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16); 75.873 +} 75.874 + 75.875 +void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv) 75.876 +{ 75.877 +// pclog("tvga_accel_write_fb_l %08X %08X\n", addr, val); 75.878 + tvga_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); 75.879 +} 75.880 + 75.881 GFXCARD vid_tvga = 75.882 { 75.883 tvga_init, 75.884 @@ -197,3 +956,27 @@ 75.885 video_read_null, 75.886 video_read_null 75.887 }; 75.888 + 75.889 +GFXCARD vid_tgui9440 = 75.890 +{ 75.891 + tvga_init, 75.892 + /*IO at 3Cx/3Dx*/ 75.893 + tvga_out, 75.894 + tvga_in, 75.895 + /*IO at 3Ax/3Bx*/ 75.896 + video_out_null, 75.897 + video_in_null, 75.898 + 75.899 + svga_poll, 75.900 + svga_recalctimings, 75.901 + 75.902 + svga_write, 75.903 + video_write_null, 75.904 + video_write_null, 75.905 + 75.906 + svga_read, 75.907 + video_read_null, 75.908 + video_read_null 75.909 +}; 75.910 + 75.911 +
76.1 --- a/src/vid_unk_ramdac.c Sun Apr 21 14:54:35 2013 +0100 76.2 +++ b/src/vid_unk_ramdac.c Mon May 27 17:46:42 2013 +0100 76.3 @@ -9,7 +9,7 @@ 76.4 static int unk_state=0; 76.5 static uint8_t unk_ctrl; 76.6 76.7 -void unk_ramdac_out(uint16_t addr, uint8_t val) 76.8 +void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv) 76.9 { 76.10 //pclog("OUT RAMDAC %04X %02X\n",addr,val); 76.11 switch (addr) 76.12 @@ -42,10 +42,10 @@ 76.13 unk_state = 0; 76.14 break; 76.15 } 76.16 - svga_out(addr,val); 76.17 + svga_out(addr, val, NULL); 76.18 } 76.19 76.20 -uint8_t unk_ramdac_in(uint16_t addr) 76.21 +uint8_t unk_ramdac_in(uint16_t addr, void *priv) 76.22 { 76.23 //pclog("IN RAMDAC %04X\n",addr); 76.24 switch (addr) 76.25 @@ -62,5 +62,5 @@ 76.26 unk_state = 0; 76.27 break; 76.28 } 76.29 - return svga_in(addr); 76.30 + return svga_in(addr, NULL); 76.31 }
77.1 --- a/src/vid_unk_ramdac.h Sun Apr 21 14:54:35 2013 +0100 77.2 +++ b/src/vid_unk_ramdac.h Mon May 27 17:46:42 2013 +0100 77.3 @@ -1,2 +1,2 @@ 77.4 -void unk_ramdac_out(uint16_t addr, uint8_t val); 77.5 -uint8_t unk_ramdac_in(uint16_t addr); 77.6 +void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv); 77.7 +uint8_t unk_ramdac_in(uint16_t addr, void *priv);
78.1 --- a/src/video.c Sun Apr 21 14:54:35 2013 +0100 78.2 +++ b/src/video.c Mon May 27 17:46:42 2013 +0100 78.3 @@ -5,6 +5,9 @@ 78.4 #include "vid_svga.h" 78.5 #include "io.h" 78.6 #include "cpu.h" 78.7 +#include "timer.h" 78.8 + 78.9 +int video_timer; 78.10 78.11 /*Video timing settings - 78.12 78.13 @@ -81,46 +84,46 @@ 78.14 void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h); 78.15 void (*video_blit_memtoscreen_8)(int x, int y, int w, int h); 78.16 78.17 -void (*video_out) (uint16_t addr, uint8_t val); 78.18 -void (*video_mono_out)(uint16_t addr, uint8_t val); 78.19 -uint8_t (*video_in) (uint16_t addr); 78.20 -uint8_t (*video_mono_in)(uint16_t addr); 78.21 +void (*video_out) (uint16_t addr, uint8_t val, void *priv); 78.22 +void (*video_mono_out)(uint16_t addr, uint8_t val, void *priv); 78.23 +uint8_t (*video_in) (uint16_t addr, void *priv); 78.24 +uint8_t (*video_mono_in)(uint16_t addr, void *priv); 78.25 78.26 -void (*video_write_a000)(uint32_t addr, uint8_t val); 78.27 -void (*video_write_b000)(uint32_t addr, uint8_t val); 78.28 -void (*video_write_b800)(uint32_t addr, uint8_t val); 78.29 +void (*video_write_a000)(uint32_t addr, uint8_t val, void *priv); 78.30 +void (*video_write_b000)(uint32_t addr, uint8_t val, void *priv); 78.31 +void (*video_write_b800)(uint32_t addr, uint8_t val, void *priv); 78.32 78.33 -void (*video_write_a000_w)(uint32_t addr, uint16_t val); 78.34 -void (*video_write_a000_l)(uint32_t addr, uint32_t val); 78.35 +void (*video_write_a000_w)(uint32_t addr, uint16_t val, void *priv); 78.36 +void (*video_write_a000_l)(uint32_t addr, uint32_t val, void *priv); 78.37 78.38 -uint8_t (*video_read_a000)(uint32_t addr); 78.39 -uint8_t (*video_read_b000)(uint32_t addr); 78.40 -uint8_t (*video_read_b800)(uint32_t addr); 78.41 +uint8_t (*video_read_a000)(uint32_t addr, void *priv); 78.42 +uint8_t (*video_read_b000)(uint32_t addr, void *priv); 78.43 +uint8_t (*video_read_b800)(uint32_t addr, void *priv); 78.44 78.45 void (*video_recalctimings)(); 78.46 78.47 -void video_out_null(uint16_t addr, uint8_t val) 78.48 +void video_out_null(uint16_t addr, uint8_t val, void *priv) 78.49 { 78.50 } 78.51 78.52 -uint8_t video_in_null(uint16_t addr) 78.53 +uint8_t video_in_null(uint16_t addr, void *priv) 78.54 { 78.55 return 0xFF; 78.56 } 78.57 78.58 -void video_write_null(uint32_t addr, uint8_t val) 78.59 +void video_write_null(uint32_t addr, uint8_t val, void *priv) 78.60 { 78.61 } 78.62 78.63 -uint8_t video_read_null(uint32_t addr) 78.64 +uint8_t video_read_null(uint32_t addr, void *priv) 78.65 { 78.66 return 0xff; 78.67 } 78.68 78.69 void video_load(GFXCARD g) 78.70 { 78.71 - io_sethandler(0x03a0, 0x0020, g.mono_in, NULL, NULL, g.mono_out, NULL, NULL); 78.72 - io_sethandler(0x03c0, 0x0020, g.in, NULL, NULL, g.out, NULL, NULL); 78.73 + io_sethandler(0x03a0, 0x0020, g.mono_in, NULL, NULL, g.mono_out, NULL, NULL, NULL); 78.74 + io_sethandler(0x03c0, 0x0020, g.in, NULL, NULL, g.out, NULL, NULL, NULL); 78.75 78.76 video_out = g.out; 78.77 video_in = g.in; 78.78 @@ -141,6 +144,8 @@ 78.79 video_write_a000_w = video_write_a000_l = NULL; 78.80 78.81 g.init(); 78.82 + 78.83 + video_timer = timer_add(pollvideo, &vidtime, TIMER_ALWAYS_ENABLED, NULL); 78.84 } 78.85 78.86 void video_init() 78.87 @@ -221,6 +226,38 @@ 78.88 video_load(vid_s3); 78.89 break; 78.90 78.91 + case GFX_VIRGE: 78.92 + video_load(vid_s3_virge); 78.93 + break; 78.94 + 78.95 + case GFX_TGUI9440: 78.96 + video_load(vid_tgui9440); 78.97 + break; 78.98 + 78.99 + case GFX_VGA: 78.100 + video_load(vid_vga); 78.101 + break; 78.102 + 78.103 + case GFX_VGAEDGE16: 78.104 + video_load(vid_ati18800); 78.105 + break; 78.106 + 78.107 + case GFX_VGACHARGER: 78.108 + video_load(vid_ati28800); 78.109 + break; 78.110 + 78.111 + case GFX_OTI067: 78.112 + video_load(vid_oti067); 78.113 + return; 78.114 + 78.115 + case GFX_MACH64GX: 78.116 + video_load(vid_mach64); 78.117 + return; 78.118 + 78.119 + case GFX_CL_GD5429: 78.120 + video_load(vid_gd5429); 78.121 + return; 78.122 + 78.123 default: 78.124 fatal("Bad gfx card %i\n",gfxcard); 78.125 } 78.126 @@ -235,7 +272,8 @@ 78.127 uint8_t fontdat[256][8]; 78.128 uint8_t fontdatm[256][16]; 78.129 78.130 -float dispontime,dispofftime,disptime; 78.131 +int dispontime,dispofftime; 78.132 +double disptime; 78.133 int svgaon; 78.134 uint8_t cgamode=1,cgastat,cgacol=7,ocgamode; 78.135 int linepos=0; 78.136 @@ -404,7 +442,7 @@ 78.137 78.138 void initvideo() 78.139 { 78.140 - int c,d; 78.141 + int c; 78.142 // set_color_depth(desktop_color_depth()); 78.143 // if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,2048,2048,0,0)) 78.144 // set_gfx_mode(GFX_AUTODETECT_WINDOWED,1024,768,0,0); 78.145 @@ -473,18 +511,6 @@ 78.146 mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; 78.147 mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; 78.148 mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; 78.149 -/* switch (gfxcard) 78.150 - { 78.151 - case GFX_CGA: pollvideo=pollcga; break; 78.152 - case GFX_MDA: 78.153 - case GFX_HERCULES: pollvideo=pollmda; break; 78.154 - } 78.155 - if (TANDY) pollvideo=polltandy; 78.156 - if (EGA) pollvideo=pollega; 78.157 - if (romset==ROM_PC1512 || romset==ROM_PC200) pollvideo=pollcga;*/ 78.158 -// tandyvram=&ram[0x9C000]; 78.159 -// printf("Tandy VRAM %08X\n",tandyvram); 78.160 -// tandyb8000=&ram[0x9C000]; 78.161 } 78.162 78.163 void closevideo()
79.1 --- a/src/video.h Sun Apr 21 14:54:35 2013 +0100 79.2 +++ b/src/video.h Mon May 27 17:46:42 2013 +0100 79.3 @@ -10,7 +10,7 @@ 79.4 extern int gdcaddr; 79.5 extern uint8_t attrregs[32]; 79.6 extern int attraddr,attrff; 79.7 -extern uint8_t seqregs[32]; 79.8 +extern uint8_t seqregs[64]; 79.9 extern int seqaddr; 79.10 extern int svgaon; 79.11 79.12 @@ -34,31 +34,34 @@ 79.13 79.14 extern int firstline,lastline; 79.15 extern int ega_hdisp,ega_rowoffset,ega_split,ega_dispend,ega_vsyncstart,ega_vtotal; 79.16 -extern float dispontime,dispofftime,disptime; 79.17 +extern int dispontime,dispofftime; 79.18 +extern double disptime; 79.19 79.20 -extern void (*video_out) (uint16_t addr, uint8_t val); 79.21 -extern void (*video_mono_out)(uint16_t addr, uint8_t val); 79.22 -extern uint8_t (*video_in) (uint16_t addr); 79.23 -extern uint8_t (*video_mono_in)(uint16_t addr); 79.24 +extern void (*video_out) (uint16_t addr, uint8_t val, void *priv); 79.25 +extern void (*video_mono_out)(uint16_t addr, uint8_t val, void *priv); 79.26 +extern uint8_t (*video_in) (uint16_t addr, void *priv); 79.27 +extern uint8_t (*video_mono_in)(uint16_t addr, void *priv); 79.28 79.29 -extern void (*video_write_a000)(uint32_t addr, uint8_t val); 79.30 -extern void (*video_write_b000)(uint32_t addr, uint8_t val); 79.31 -extern void (*video_write_b800)(uint32_t addr, uint8_t val); 79.32 +extern void (*video_write_a000)(uint32_t addr, uint8_t val, void *priv); 79.33 +extern void (*video_write_b000)(uint32_t addr, uint8_t val, void *priv); 79.34 +extern void (*video_write_b800)(uint32_t addr, uint8_t val, void *priv); 79.35 79.36 -extern uint8_t (*video_read_a000)(uint32_t addr); 79.37 -extern uint8_t (*video_read_b000)(uint32_t addr); 79.38 -extern uint8_t (*video_read_b800)(uint32_t addr); 79.39 +extern uint8_t (*video_read_a000)(uint32_t addr, void *priv); 79.40 +extern uint8_t (*video_read_b000)(uint32_t addr, void *priv); 79.41 +extern uint8_t (*video_read_b800)(uint32_t addr, void *priv); 79.42 79.43 -extern void (*video_write_a000_w)(uint32_t addr, uint16_t val); 79.44 -extern void (*video_write_a000_l)(uint32_t addr, uint32_t val); 79.45 +extern void (*video_write_a000_w)(uint32_t addr, uint16_t val, void *priv); 79.46 +extern void (*video_write_a000_l)(uint32_t addr, uint32_t val, void *priv); 79.47 79.48 -extern void video_out_null(uint16_t addr, uint8_t val); 79.49 -extern uint8_t video_in_null(uint16_t addr); 79.50 +extern void video_out_null(uint16_t addr, uint8_t val, void *priv); 79.51 +extern uint8_t video_in_null(uint16_t addr, void *priv); 79.52 79.53 -extern void video_write_null(uint32_t addr, uint8_t val); 79.54 -extern uint8_t video_read_null (uint32_t addr); 79.55 +extern void video_write_null(uint32_t addr, uint8_t val, void *priv); 79.56 +extern uint8_t video_read_null (uint32_t addr, void *priv); 79.57 79.58 79.59 +extern int video_timer; 79.60 + 79.61 extern uint8_t tridentoldctrl2,tridentnewctrl2; 79.62 extern int rowdbl; 79.63 79.64 @@ -73,6 +76,8 @@ 79.65 79.66 extern BITMAP *screen; 79.67 79.68 +BITMAP *create_bitmap(int w, int h); 79.69 + 79.70 extern int wx,wy; 79.71 79.72 extern uint8_t fontdat[256][8]; 79.73 @@ -98,18 +103,18 @@ 79.74 typedef struct 79.75 { 79.76 int (*init)(); 79.77 - void (*out)(uint16_t addr, uint8_t val); 79.78 - uint8_t (*in)(uint16_t addr); 79.79 - void (*mono_out)(uint16_t addr, uint8_t val); 79.80 - uint8_t (*mono_in)(uint16_t addr); 79.81 + void (*out)(uint16_t addr, uint8_t val, void *priv); 79.82 + uint8_t (*in)(uint16_t addr, void *priv); 79.83 + void (*mono_out)(uint16_t addr, uint8_t val, void *priv); 79.84 + uint8_t (*mono_in)(uint16_t addr, void *priv); 79.85 void (*poll)(); 79.86 void (*recalctimings)(); 79.87 - void (*write_a000)(uint32_t addr, uint8_t val); 79.88 - void (*write_b000)(uint32_t addr, uint8_t val); 79.89 - void (*write_b800)(uint32_t addr, uint8_t val); 79.90 - uint8_t (*read_a000)(uint32_t addr); 79.91 - uint8_t (*read_b000)(uint32_t addr); 79.92 - uint8_t (*read_b800)(uint32_t addr); 79.93 + void (*write_a000)(uint32_t addr, uint8_t val, void *priv); 79.94 + void (*write_b000)(uint32_t addr, uint8_t val, void *priv); 79.95 + void (*write_b800)(uint32_t addr, uint8_t val, void *priv); 79.96 + uint8_t (*read_a000)(uint32_t addr, void *priv); 79.97 + uint8_t (*read_b000)(uint32_t addr, void *priv); 79.98 + uint8_t (*read_b800)(uint32_t addr, void *priv); 79.99 } GFXCARD; 79.100 79.101 extern GFXCARD vid_cga; 79.102 @@ -127,7 +132,13 @@ 79.103 extern GFXCARD vid_et4000; 79.104 extern GFXCARD vid_et4000w32p; 79.105 extern GFXCARD vid_s3; 79.106 - 79.107 +extern GFXCARD vid_s3_virge; 79.108 +extern GFXCARD vid_tgui9440; 79.109 +extern GFXCARD vid_vga; 79.110 +extern GFXCARD vid_ati18800; 79.111 +extern GFXCARD vid_ati28800; 79.112 +extern GFXCARD vid_mach64; 79.113 +extern GFXCARD vid_gd5429; 79.114 79.115 extern float cpuclock; 79.116
80.1 --- a/src/wd76c10.c Sun Apr 21 14:54:35 2013 +0100 80.2 +++ b/src/wd76c10.c Mon May 27 17:46:42 2013 +0100 80.3 @@ -10,7 +10,7 @@ 80.4 static uint16_t wd76c10_2872; 80.5 static uint16_t wd76c10_5872; 80.6 80.7 -uint16_t wd76c10_read(uint16_t port) 80.8 +uint16_t wd76c10_read(uint16_t port, void *priv) 80.9 { 80.10 switch (port) 80.11 { 80.12 @@ -29,7 +29,7 @@ 80.13 return 0; 80.14 } 80.15 80.16 -void wd76c10_write(uint16_t port, uint16_t val) 80.17 +void wd76c10_write(uint16_t port, uint16_t val, void *priv) 80.18 { 80.19 pclog("WD76C10 write %04X %04X\n", port, val); 80.20 switch (port) 80.21 @@ -68,7 +68,7 @@ 80.22 80.23 fdc_remove(); 80.24 if (!(val & 1)) 80.25 - fdc_init(); 80.26 + fdc_add(); 80.27 break; 80.28 80.29 case 0x5872: 80.30 @@ -77,26 +77,26 @@ 80.31 } 80.32 } 80.33 80.34 -uint8_t wd76c10_readb(uint16_t port) 80.35 +uint8_t wd76c10_readb(uint16_t port, void *priv) 80.36 { 80.37 if (port & 1) 80.38 - return wd76c10_read(port & ~1) >> 8; 80.39 - return wd76c10_read(port) & 0xff; 80.40 + return wd76c10_read(port & ~1, priv) >> 8; 80.41 + return wd76c10_read(port, priv) & 0xff; 80.42 } 80.43 80.44 -void wd76c10_writeb(uint16_t port, uint8_t val) 80.45 +void wd76c10_writeb(uint16_t port, uint8_t val, void *priv) 80.46 { 80.47 - uint16_t temp = wd76c10_read(port); 80.48 + uint16_t temp = wd76c10_read(port, priv); 80.49 if (port & 1) 80.50 - wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8)); 80.51 + wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8), priv); 80.52 else 80.53 - wd76c10_write(port , (temp & 0xff00) | val); 80.54 + wd76c10_write(port , (temp & 0xff00) | val, priv); 80.55 } 80.56 80.57 void wd76c10_init() 80.58 { 80.59 - io_sethandler(0x0092, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL); 80.60 - io_sethandler(0x2072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL); 80.61 - io_sethandler(0x2872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL); 80.62 - io_sethandler(0x5872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL); 80.63 + io_sethandler(0x0092, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); 80.64 + io_sethandler(0x2072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); 80.65 + io_sethandler(0x2872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); 80.66 + io_sethandler(0x5872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); 80.67 }
81.1 --- a/src/win-video.c Sun Apr 21 14:54:35 2013 +0100 81.2 +++ b/src/win-video.c Mon May 27 17:46:42 2013 +0100 81.3 @@ -1,4 +1,6 @@ 81.4 #include <stdint.h> 81.5 +#include <stdlib.h> 81.6 +#include <string.h> 81.7 #include "video.h" 81.8 81.9 BITMAP *screen;
82.1 --- a/src/win.c Sun Apr 21 14:54:35 2013 +0100 82.2 +++ b/src/win.c Mon May 27 17:46:42 2013 +0100 82.3 @@ -15,6 +15,8 @@ 82.4 #include "video.h" 82.5 #include "resources.h" 82.6 #include "ide.h" 82.7 +#include "nvr.h" 82.8 +#include "sound.h" 82.9 82.10 #include "plat-keyboard.h" 82.11 82.12 @@ -25,7 +27,7 @@ 82.13 #define TIMER_1SEC 1 82.14 82.15 int winsizex=640,winsizey=480; 82.16 -int svgapresent, et4000w32_present, bahamas64_present, n9_9fx_present; 82.17 +int gfx_present[18]; 82.18 int wakeups,wokeups; 82.19 #undef cs 82.20 CRITICAL_SECTION cs; 82.21 @@ -44,8 +46,6 @@ 82.22 void endsoundthread(); 82.23 void silencesound(); 82.24 void restoresound(); 82.25 -static HANDLE soundobject; 82.26 - 82.27 static HANDLE frameobject; 82.28 82.29 int infocus=1; 82.30 @@ -61,7 +61,7 @@ 82.31 // } 82.32 } 82.33 82.34 -int romspresent[25]; 82.35 +int romspresent[26]; 82.36 int quited=0; 82.37 82.38 RECT oldclip,pcclip; 82.39 @@ -99,11 +99,6 @@ 82.40 } 82.41 } 82.42 82.43 -static LARGE_INTEGER counter_base; 82.44 -static LARGE_INTEGER counter_freq; 82.45 -static LARGE_INTEGER counter_pos; 82.46 -static LARGE_INTEGER counter_posold; 82.47 - 82.48 void setrefresh(int rate) 82.49 { 82.50 return; 82.51 @@ -155,6 +150,7 @@ 82.52 void mainthread(LPVOID param) 82.53 { 82.54 int t = 0; 82.55 + int frames = 0; 82.56 DWORD old_time, new_time; 82.57 mainthreadon=1; 82.58 // Sleep(500); 82.59 @@ -190,12 +186,19 @@ 82.60 runpc(); 82.61 // ddraw_draw(); 82.62 endblit(); 82.63 + frames++; 82.64 + if (frames >= 200 && nvr_dosave) 82.65 + { 82.66 + frames = 0; 82.67 + nvr_dosave = 0; 82.68 + savenvr(); 82.69 + } 82.70 //#if 0 82.71 //#endif 82.72 } 82.73 else 82.74 { 82.75 -// Sleep(1); 82.76 + Sleep(1); 82.77 } 82.78 // } 82.79 } 82.80 @@ -246,9 +249,7 @@ 82.81 HWND hwnd; /* This is the handle for our window */ 82.82 MSG messages; /* Here messages to the application are saved */ 82.83 WNDCLASSEX wincl; /* Data structure for the windowclass */ 82.84 - int c,d; 82.85 - FILE *f; 82.86 - int oldinfocus=0; 82.87 + int c, d; 82.88 82.89 hinstance=hThisInstance; 82.90 /* The Window structure */ 82.91 @@ -317,19 +318,19 @@ 82.92 // set_display_switch_mode(SWITCH_BACKGROUND); 82.93 82.94 d=romset; 82.95 - for (c=0;c<25;c++) 82.96 + for (c=0;c<26;c++) 82.97 { 82.98 romset=c; 82.99 romspresent[c]=loadbios(); 82.100 pclog("romset %i - %i\n", c, romspresent[c]); 82.101 } 82.102 82.103 - for (c = 0; c < 25; c++) 82.104 + for (c = 0; c < 26; c++) 82.105 { 82.106 if (romspresent[c]) 82.107 break; 82.108 } 82.109 - if (c == 25) 82.110 + if (c == 26) 82.111 { 82.112 MessageBox(hwnd,"No ROMs present!\nYou must have at least one romset to use PCem.","PCem fatal error",MB_OK); 82.113 return 0; 82.114 @@ -340,8 +341,8 @@ 82.115 82.116 if (!c) 82.117 { 82.118 - if (romset!=-1) MessageBox(hwnd,"Configured romset not available.\nDefaulting to available romset.","PCemu error",MB_OK); 82.119 - for (c=0;c<25;c++) 82.120 + if (romset!=-1) MessageBox(hwnd,"Configured romset not available.\nDefaulting to available romset.","PCem error",MB_OK); 82.121 + for (c=0;c<26;c++) 82.122 { 82.123 if (romspresent[c]) 82.124 { 82.125 @@ -352,60 +353,26 @@ 82.126 } 82.127 } 82.128 82.129 - f=romfopen("roms/trident.bin","rb"); 82.130 - if (f) 82.131 + d = gfxcard; 82.132 + for (c = 0; c < 18; c++) 82.133 { 82.134 - fclose(f); 82.135 - vgapresent=1; 82.136 + gfxcard = c; 82.137 + gfx_present[c] = mem_load_video_bios(); 82.138 } 82.139 - else 82.140 + gfxcard = d; 82.141 + c = mem_load_video_bios(); 82.142 + if (!c) 82.143 { 82.144 - vgapresent=0; 82.145 - if (gfxcard==GFX_TVGA) gfxcard=GFX_CGA; 82.146 - } 82.147 - f=romfopen("roms/et4000.bin","rb"); 82.148 - if (f) 82.149 - { 82.150 - fclose(f); 82.151 - svgapresent=1; 82.152 - } 82.153 - else 82.154 - { 82.155 - svgapresent=0; 82.156 - if (gfxcard==GFX_ET4000) gfxcard=(svgapresent)?GFX_TVGA:GFX_CGA; 82.157 - } 82.158 - f=romfopen("roms/et4000w32.bin","rb"); 82.159 - if (f) 82.160 - { 82.161 - fclose(f); 82.162 - et4000w32_present=1; 82.163 - } 82.164 - else 82.165 - { 82.166 - et4000w32_present=0; 82.167 - if (gfxcard==GFX_ET4000W32) gfxcard=(svgapresent)?GFX_TVGA:GFX_CGA; 82.168 - } 82.169 - f=romfopen("roms/bahamas64.bin","rb"); 82.170 - if (f) 82.171 - { 82.172 - fclose(f); 82.173 - bahamas64_present=1; 82.174 - } 82.175 - else 82.176 - { 82.177 - bahamas64_present=0; 82.178 - if (gfxcard==GFX_BAHAMAS64) gfxcard=(svgapresent)?GFX_TVGA:GFX_CGA; 82.179 - } 82.180 - f=romfopen("roms/s3_764.bin","rb"); 82.181 - if (f) 82.182 - { 82.183 - fclose(f); 82.184 - n9_9fx_present=1; 82.185 - } 82.186 - else 82.187 - { 82.188 - n9_9fx_present=0; 82.189 - if (gfxcard==GFX_N9_9FX) gfxcard=(svgapresent)?GFX_TVGA:GFX_CGA; 82.190 + if (romset!=-1) MessageBox(hwnd,"Configured video BIOS not available.\nDefaulting to available romset.","PCem error",MB_OK); 82.191 + for (c=0;c<18;c++) 82.192 + { 82.193 + if (gfx_present[c]) 82.194 + { 82.195 + gfxcard = c; 82.196 + mem_load_video_bios(); 82.197 + break; 82.198 + } 82.199 + } 82.200 } 82.201 timeBeginPeriod(1); 82.202 // soundobject=CreateEvent(NULL, FALSE, FALSE, NULL); 82.203 @@ -505,7 +472,6 @@ 82.204 int getfile(HWND hwnd, char *f, char *fn) 82.205 { 82.206 OPENFILENAME ofn; // common dialog box structure 82.207 - char szFile[260]; // buffer for file name 82.208 BOOL r; 82.209 DWORD err; 82.210 82.211 @@ -546,7 +512,6 @@ 82.212 int getsfile(HWND hwnd, char *f, char *fn) 82.213 { 82.214 OPENFILENAME ofn; // common dialog box structure 82.215 - char szFile[260]; // buffer for file name 82.216 BOOL r; 82.217 DWORD err; 82.218 82.219 @@ -585,12 +550,18 @@ 82.220 } 82.221 82.222 extern int is486; 82.223 -int romstolist[25], listtomodel[23], romstomodel[25], modeltolist[23]; 82.224 -int vidtolist[10],listtovid[10]; 82.225 +int romstolist[26], listtomodel[26], romstomodel[26], modeltolist[26]; 82.226 +int vidtolist[20],listtovid[20]; 82.227 82.228 -int mem_list_to_size[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,32,48,64}; 82.229 +int mem_list_to_size[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,32,48,64,256}; 82.230 int mem_size_to_list[]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16, 82.231 - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,18}; 82.232 + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,18, 82.233 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 82.234 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 82.235 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 82.236 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 82.237 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 82.238 + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 19}; 82.239 82.240 #include "cpu.h" 82.241 #include "model.h" 82.242 @@ -601,13 +572,14 @@ 82.243 int c, d; 82.244 int rom,gfx,mem,fpu; 82.245 int temp_cpu, temp_cpu_m, temp_model; 82.246 + int temp_GAMEBLASTER, temp_GUS, temp_sound_card_current; 82.247 // pclog("Dialog msg %i %08X\n",message,message); 82.248 switch (message) 82.249 { 82.250 case WM_INITDIALOG: 82.251 pause=1; 82.252 h=GetDlgItem(hdlg,IDC_COMBO1); 82.253 - for (c=0;c<25;c++) romstolist[c]=0; 82.254 + for (c=0;c<26;c++) romstolist[c]=0; 82.255 c = d = 0; 82.256 while (models[c].id != -1) 82.257 { 82.258 @@ -632,11 +604,19 @@ 82.259 SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"MDA"); vidtolist[GFX_MDA]=1; listtovid[1]=1; 82.260 SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Hercules"); vidtolist[GFX_HERCULES]=2; listtovid[2]=2; 82.261 SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"EGA"); vidtolist[GFX_EGA]=3; listtovid[3]=3; 82.262 - if (vgapresent) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Trident 8900D"); vidtolist[GFX_TVGA]=c; listtovid[c]=GFX_TVGA; c++; } 82.263 - if (svgapresent) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Tseng ET4000AX"); vidtolist[GFX_ET4000]=c; listtovid[c]=GFX_ET4000; c++; } 82.264 - if (et4000w32_present) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Diamond Stealth 32"); vidtolist[GFX_ET4000W32]=c; listtovid[c]=GFX_ET4000W32; c++; } 82.265 - if (bahamas64_present) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Paradise Bahamas 64"); vidtolist[GFX_BAHAMAS64]=c; listtovid[c]=GFX_BAHAMAS64; c++; } 82.266 - if (n9_9fx_present) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Number Nine 9FX"); vidtolist[GFX_N9_9FX]=c; listtovid[c]=GFX_N9_9FX; c++; } 82.267 + if (gfx_present[GFX_TVGA]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Trident 8900D"); vidtolist[GFX_TVGA]=c; listtovid[c]=GFX_TVGA; c++; } 82.268 + if (gfx_present[GFX_ET4000]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Tseng ET4000AX"); vidtolist[GFX_ET4000]=c; listtovid[c]=GFX_ET4000; c++; } 82.269 + if (gfx_present[GFX_ET4000W32]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Diamond Stealth 32"); vidtolist[GFX_ET4000W32]=c; listtovid[c]=GFX_ET4000W32; c++; } 82.270 + if (gfx_present[GFX_BAHAMAS64]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Paradise Bahamas 64"); vidtolist[GFX_BAHAMAS64]=c; listtovid[c]=GFX_BAHAMAS64; c++; } 82.271 + if (gfx_present[GFX_N9_9FX]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Number Nine 9FX"); vidtolist[GFX_N9_9FX]=c; listtovid[c]=GFX_N9_9FX; c++; } 82.272 + if (gfx_present[GFX_VIRGE]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"S3 VIRGE"); vidtolist[GFX_VIRGE]=c; listtovid[c]=GFX_VIRGE; c++; } 82.273 + if (gfx_present[GFX_TGUI9440]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Trident TGUI9440"); vidtolist[GFX_TGUI9440]=c; listtovid[c]=GFX_TGUI9440; c++; } 82.274 + if (gfx_present[GFX_VGA]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"VGA"); vidtolist[GFX_VGA]=c; listtovid[c]=GFX_VGA; c++; } 82.275 + if (gfx_present[GFX_VGAEDGE16]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"ATI VGA Edge-16"); vidtolist[GFX_VGAEDGE16]=c; listtovid[c]=GFX_VGAEDGE16; c++; } 82.276 + if (gfx_present[GFX_VGACHARGER]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"ATI VGA Charger"); vidtolist[GFX_VGACHARGER]=c; listtovid[c]=GFX_VGACHARGER; c++; } 82.277 + if (gfx_present[GFX_OTI067]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Oak OTI-067"); vidtolist[GFX_OTI067]=c; listtovid[c]=GFX_OTI067; c++; } 82.278 + if (gfx_present[GFX_MACH64GX]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"ATI Graphics Pro Turbo"); vidtolist[GFX_MACH64GX]=c; listtovid[c]=GFX_MACH64GX; c++; } 82.279 + if (gfx_present[GFX_CL_GD5429]) { SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"Cirrus Logic CL-GD5429"); vidtolist[GFX_CL_GD5429]=c; listtovid[c]=GFX_CL_GD5429; c++; } 82.280 SendMessage(h,CB_SETCURSEL,vidtolist[gfxcard],0); 82.281 if (models[model].fixed_gfxcard) EnableWindow(h,FALSE); 82.282 82.283 @@ -663,30 +643,30 @@ 82.284 SendMessage(h, CB_SETCURSEL, cpu, 0); 82.285 82.286 h=GetDlgItem(hdlg,IDC_COMBOSND); 82.287 - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"None"); 82.288 - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"AdLib"); 82.289 - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SoundBlaster v1.0"); 82.290 - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SoundBlaster v1.5"); 82.291 - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SoundBlaster v2.0"); 82.292 - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SB Pro v1"); 82.293 - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SB Pro v2"); 82.294 - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"SoundBlaster 16"); 82.295 - SendMessage(h,CB_SETCURSEL,sbtype,0); 82.296 + c = 0; 82.297 + while (1) 82.298 + { 82.299 + char *s = sound_card_getname(c); 82.300 82.301 -// h=GetDlgItem(hdlg,IDC_CHECK2); 82.302 -// SendMessage(h,BM_SETCHECK,ADLIB,0); 82.303 + if (!s[0]) 82.304 + break; 82.305 + 82.306 + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); 82.307 + c++; 82.308 + } 82.309 + SendMessage(h, CB_SETCURSEL, sound_card_current, 0); 82.310 + 82.311 + h=GetDlgItem(hdlg, IDC_CHECK3); 82.312 + SendMessage(h, BM_SETCHECK, GAMEBLASTER, 0); 82.313 + 82.314 + h=GetDlgItem(hdlg, IDC_CHECKGUS); 82.315 + SendMessage(h, BM_SETCHECK, GUS, 0); 82.316 82.317 - h=GetDlgItem(hdlg,IDC_CHECK3); 82.318 - SendMessage(h,BM_SETCHECK,GAMEBLASTER,0); 82.319 - 82.320 - h=GetDlgItem(hdlg,IDC_CHECK1); 82.321 - SendMessage(h,BM_SETCHECK,FASTDISC,0); 82.322 + h=GetDlgItem(hdlg, IDC_CHECK2); 82.323 + SendMessage(h, BM_SETCHECK, slowega, 0); 82.324 82.325 - h=GetDlgItem(hdlg,IDC_CHECK2); 82.326 - SendMessage(h,BM_SETCHECK,slowega,0); 82.327 - 82.328 - h=GetDlgItem(hdlg,IDC_CHECK4); 82.329 - SendMessage(h,BM_SETCHECK,cga_comp,0); 82.330 + h=GetDlgItem(hdlg, IDC_CHECK4); 82.331 + SendMessage(h, BM_SETCHECK, cga_comp, 0); 82.332 82.333 h=GetDlgItem(hdlg,IDC_COMBOCHC); 82.334 SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"A little"); 82.335 @@ -725,6 +705,7 @@ 82.336 SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"32 MB"); 82.337 SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"48 MB"); 82.338 SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"64 MB"); 82.339 + SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)"256 MB"); 82.340 SendMessage(h,CB_SETCURSEL,mem_size_to_list[mem_size-1],0); 82.341 82.342 pclog("Init cpuspeed %i\n",cpuspeed); 82.343 @@ -750,7 +731,16 @@ 82.344 fpu = (models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type >= CPU_i486DX) ? 1 : 0; 82.345 pclog("newcpu - %i %i %i %i\n",temp_cpu_m,temp_cpu,fpu,models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type); 82.346 82.347 - if (temp_model != model || gfx!=gfxcard || mem!=mem_size || fpu!=hasfpu) 82.348 + h = GetDlgItem(hdlg, IDC_CHECK3); 82.349 + temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); 82.350 + 82.351 + h = GetDlgItem(hdlg, IDC_CHECKGUS); 82.352 + temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); 82.353 + 82.354 + h = GetDlgItem(hdlg, IDC_COMBOSND); 82.355 + temp_sound_card_current = SendMessage(h, CB_GETCURSEL, 0, 0); 82.356 + 82.357 + if (temp_model != model || gfx != gfxcard || mem != mem_size || fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || temp_sound_card_current != sound_card_current) 82.358 { 82.359 if (MessageBox(NULL,"This will reset PCem!\nOkay to continue?","PCem",MB_OKCANCEL)==IDOK) 82.360 { 82.361 @@ -760,9 +750,13 @@ 82.362 mem_size=mem; 82.363 cpu_manufacturer = temp_cpu_m; 82.364 cpu = temp_cpu; 82.365 + GAMEBLASTER = temp_GAMEBLASTER; 82.366 + GUS = temp_GUS; 82.367 + sound_card_current = temp_sound_card_current; 82.368 82.369 mem_resize(); 82.370 loadbios(); 82.371 + mem_load_video_bios(); 82.372 resetpchard(); 82.373 } 82.374 else 82.375 @@ -776,12 +770,6 @@ 82.376 h=GetDlgItem(hdlg,IDC_COMBOSPD); 82.377 video_speed = SendMessage(h,CB_GETCURSEL,0,0); 82.378 82.379 - h=GetDlgItem(hdlg,IDC_CHECK3); 82.380 - GAMEBLASTER=SendMessage(h,BM_GETCHECK,0,0); 82.381 - 82.382 - h=GetDlgItem(hdlg,IDC_CHECK1); 82.383 - FASTDISC=SendMessage(h,BM_GETCHECK,0,0); 82.384 - 82.385 h=GetDlgItem(hdlg,IDC_CHECK4); 82.386 cga_comp=SendMessage(h,BM_GETCHECK,0,0); 82.387 82.388 @@ -789,9 +777,6 @@ 82.389 cpu = temp_cpu; 82.390 cpu_set(); 82.391 82.392 - h=GetDlgItem(hdlg,IDC_COMBOSND); 82.393 - sbtype=SendMessage(h,CB_GETCURSEL,0,0); 82.394 - 82.395 h=GetDlgItem(hdlg,IDC_COMBOCHC); 82.396 cache=SendMessage(h,CB_GETCURSEL,0,0); 82.397 mem_updatecache(); 82.398 @@ -890,7 +875,6 @@ 82.399 HWND h; 82.400 int c; 82.401 PcemHDC hd[2]; 82.402 - int changeddrv=0; 82.403 FILE *f; 82.404 uint8_t buf[512]; 82.405 switch (message) 82.406 @@ -1004,11 +988,7 @@ 82.407 { 82.408 char s[260]; 82.409 HWND h; 82.410 - int c; 82.411 PcemHDC hd[2]; 82.412 - int changeddrv=0; 82.413 - FILE *f; 82.414 - uint8_t buf[512]; 82.415 switch (message) 82.416 { 82.417 case WM_INITDIALOG: 82.418 @@ -1090,9 +1070,7 @@ 82.419 { 82.420 char s[260]; 82.421 HWND h; 82.422 - int c; 82.423 PcemHDC hd[2]; 82.424 - int changeddrv=0; 82.425 FILE *f; 82.426 off64_t sz; 82.427 switch (message) 82.428 @@ -1344,8 +1322,6 @@ 82.429 82.430 BOOL CALLBACK statusdlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) 82.431 { 82.432 - HWND h; 82.433 - int c; 82.434 int egasp; 82.435 char s[256]; 82.436 switch (message) 82.437 @@ -1374,12 +1350,12 @@ 82.438 if (chain4) sprintf(s,"VGA chained (possibly mode 13h)"); 82.439 else sprintf(s,"VGA unchained (possibly mode-X)"); 82.440 SendDlgItemMessage(hdlg,IDC_STEXT9,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); 82.441 - if (!video_bpp) sprintf(s,"VGA in text mode"); 82.442 - else sprintf(s,"VGA colour depth : %i bpp", video_bpp); 82.443 +/* if (!video_bpp) sprintf(s,"VGA in text mode"); 82.444 + else */sprintf(s,"VGA colour depth : %i bpp", video_bpp); 82.445 SendDlgItemMessage(hdlg,IDC_STEXT10,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); 82.446 sprintf(s,"VGA resolution : %i x %i", video_res_x, video_res_y); 82.447 SendDlgItemMessage(hdlg,IDC_STEXT11,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); 82.448 - sprintf(s,"SB frequency : %i Hz",sb_freq); 82.449 + sprintf(s,"SB frequency : %i Hz",0); 82.450 SendDlgItemMessage(hdlg,IDC_STEXT12,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); 82.451 sprintf(s,"Video refresh rate : %i Hz", emu_fps); 82.452 SendDlgItemMessage(hdlg,IDC_STEXT13,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s); 82.453 @@ -1421,9 +1397,6 @@ 82.454 { 82.455 HMENU hmenu; 82.456 RECT rect; 82.457 - int c; 82.458 - int x, y; 82.459 - POINT po; 82.460 // pclog("Message %i %08X\n",message,message); 82.461 switch (message) 82.462 {
83.1 --- a/src/x86.h Sun Apr 21 14:54:35 2013 +0100 83.2 +++ b/src/x86.h Mon May 27 17:46:42 2013 +0100 83.3 @@ -1,4 +1,3 @@ 83.4 -uint32_t old8,old82,old83; 83.5 uint16_t oldcs; 83.6 uint32_t oldpc; 83.7 extern uint32_t rmdat32; 83.8 @@ -16,11 +15,9 @@ 83.9 int inhlt; 83.10 83.11 uint8_t opcode; 83.12 -int ins,noint,notpresent; 83.13 -int inint; 83.14 +int ins,noint; 83.15 83.16 uint16_t lastcs,lastpc; 83.17 -int lldt; 83.18 int timetolive,keyboardtimer; 83.19 83.20 #define setznp168 setznp16 83.21 @@ -96,3 +93,7 @@ 83.22 83.23 extern uint16_t rds; 83.24 extern uint32_t rmdat32; 83.25 + 83.26 +extern int inscounts[256]; 83.27 + 83.28 +void x86illegal();
84.1 --- a/src/x86_flags.h Sun Apr 21 14:54:35 2013 +0100 84.2 +++ b/src/x86_flags.h Mon May 27 17:46:42 2013 +0100 84.3 @@ -1,17 +1,387 @@ 84.4 +enum 84.5 +{ 84.6 + FLAGS_UNKNOWN, 84.7 + 84.8 + FLAGS_ZN8, 84.9 + FLAGS_ZN16, 84.10 + FLAGS_ZN32, 84.11 + 84.12 + FLAGS_ADD8, 84.13 + FLAGS_ADD16, 84.14 + FLAGS_ADD32, 84.15 + 84.16 + FLAGS_SUB8, 84.17 + FLAGS_SUB16, 84.18 + FLAGS_SUB32 84.19 +}; 84.20 + 84.21 +static int flags_op; 84.22 +static uint32_t flags_res; 84.23 +static uint32_t flags_op1, flags_op2; 84.24 + 84.25 +static inline int ZF_SET() 84.26 +{ 84.27 + switch (flags_op) 84.28 + { 84.29 + case FLAGS_ZN8: 84.30 + case FLAGS_ZN16: 84.31 + case FLAGS_ZN32: 84.32 + case FLAGS_ADD8: 84.33 + case FLAGS_ADD16: 84.34 + case FLAGS_ADD32: 84.35 + case FLAGS_SUB8: 84.36 + case FLAGS_SUB16: 84.37 + case FLAGS_SUB32: 84.38 + return !flags_res; 84.39 + 84.40 + case FLAGS_UNKNOWN: 84.41 + return flags & Z_FLAG; 84.42 + } 84.43 +} 84.44 + 84.45 +static inline int NF_SET() 84.46 +{ 84.47 + switch (flags_op) 84.48 + { 84.49 + case FLAGS_ZN8: 84.50 + case FLAGS_ADD8: 84.51 + case FLAGS_SUB8: 84.52 + return flags_res & 0x80; 84.53 + 84.54 + case FLAGS_ZN16: 84.55 + case FLAGS_ADD16: 84.56 + case FLAGS_SUB16: 84.57 + return flags_res & 0x8000; 84.58 + 84.59 + case FLAGS_ZN32: 84.60 + case FLAGS_ADD32: 84.61 + case FLAGS_SUB32: 84.62 + return flags_res & 0x80000000; 84.63 + 84.64 + case FLAGS_UNKNOWN: 84.65 + return flags & N_FLAG; 84.66 + } 84.67 +} 84.68 + 84.69 +static inline int PF_SET() 84.70 +{ 84.71 + switch (flags_op) 84.72 + { 84.73 + case FLAGS_ZN8: 84.74 + case FLAGS_ZN16: 84.75 + case FLAGS_ZN32: 84.76 + case FLAGS_ADD8: 84.77 + case FLAGS_ADD16: 84.78 + case FLAGS_ADD32: 84.79 + case FLAGS_SUB8: 84.80 + case FLAGS_SUB16: 84.81 + case FLAGS_SUB32: 84.82 + return znptable8[flags_res & 0xff] & P_FLAG; 84.83 + 84.84 + case FLAGS_UNKNOWN: 84.85 + return flags & P_FLAG; 84.86 + } 84.87 +} 84.88 + 84.89 +static inline int VF_SET() 84.90 +{ 84.91 + switch (flags_op) 84.92 + { 84.93 + case FLAGS_ZN8: 84.94 + case FLAGS_ZN16: 84.95 + case FLAGS_ZN32: 84.96 + return 0; 84.97 + 84.98 + case FLAGS_ADD8: 84.99 + return !((flags_op1 ^ flags_op2) & 0x80) && ((flags_op1 ^ flags_res) & 0x80); 84.100 + case FLAGS_ADD16: 84.101 + return !((flags_op1 ^ flags_op2) & 0x8000) && ((flags_op1 ^ flags_res) & 0x8000); 84.102 + case FLAGS_ADD32: 84.103 + return !((flags_op1 ^ flags_op2) & 0x80000000) && ((flags_op1 ^ flags_res) & 0x80000000); 84.104 + 84.105 + case FLAGS_SUB8: 84.106 + return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x80); 84.107 + case FLAGS_SUB16: 84.108 + return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x8000); 84.109 + case FLAGS_SUB32: 84.110 + return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x80000000); 84.111 + 84.112 + case FLAGS_UNKNOWN: 84.113 + return flags & V_FLAG; 84.114 + } 84.115 +} 84.116 + 84.117 +static inline int AF_SET() 84.118 +{ 84.119 + switch (flags_op) 84.120 + { 84.121 + case FLAGS_ZN8: 84.122 + case FLAGS_ZN16: 84.123 + case FLAGS_ZN32: 84.124 + return 0; 84.125 + 84.126 + case FLAGS_ADD8: 84.127 + case FLAGS_ADD16: 84.128 + case FLAGS_ADD32: 84.129 + return ((flags_op1 & 0xF) + (flags_op2 & 0xF)) & 0x10; 84.130 + 84.131 + case FLAGS_SUB8: 84.132 + case FLAGS_SUB16: 84.133 + case FLAGS_SUB32: 84.134 + return ((flags_op1 & 0xF) - (flags_op2 & 0xF)) & 0x10; 84.135 + 84.136 + case FLAGS_UNKNOWN: 84.137 + return flags & A_FLAG; 84.138 + } 84.139 +} 84.140 + 84.141 +#if 0 84.142 +static inline int CF_SET() 84.143 +{ 84.144 + switch (flags_op) 84.145 + { 84.146 + case FLAGS_ZN8: 84.147 + case FLAGS_ZN16: 84.148 + case FLAGS_ZN32: 84.149 + return flags & C_FLAG; /*Temporary*/ 84.150 + 84.151 + case FLAGS_ADD8: 84.152 + return (flags_op1 + flags_op2) & 0x100; 84.153 + case FLAGS_ADD16: 84.154 +// return (flags_op1 + flags_op2) & 0x10000; 84.155 + 84.156 + case FLAGS_UNKNOWN: 84.157 + return flags & C_FLAG; 84.158 + } 84.159 +} 84.160 +#endif 84.161 + 84.162 +//#define ZF_SET() (flags & Z_FLAG) 84.163 +//#define NF_SET() (flags & N_FLAG) 84.164 +//#define PF_SET() (flags & P_FLAG) 84.165 +//#define VF_SET() (flags & V_FLAG) 84.166 +#define CF_SET() (flags & C_FLAG) 84.167 +//#define AF_SET() (flags & A_FLAG) 84.168 + 84.169 +static inline void flags_rebuild() 84.170 +{ 84.171 + if (flags_op != FLAGS_UNKNOWN) 84.172 + { 84.173 + uint16_t tempf = 0; 84.174 + if (CF_SET()) tempf |= C_FLAG; 84.175 + if (PF_SET()) tempf |= P_FLAG; 84.176 + if (AF_SET()) tempf |= A_FLAG; 84.177 + if (ZF_SET()) tempf |= Z_FLAG; 84.178 + if (NF_SET()) tempf |= N_FLAG; 84.179 + if (VF_SET()) tempf |= V_FLAG; 84.180 + flags = (flags & ~0x8d5) | tempf; 84.181 + flags_op = FLAGS_UNKNOWN; 84.182 + } 84.183 +} 84.184 + 84.185 +static inline void flags_extract() 84.186 +{ 84.187 + flags_op = FLAGS_UNKNOWN; 84.188 +} 84.189 + 84.190 +static inline void flags_rebuild_c() 84.191 +{ 84.192 + if (flags_op != FLAGS_UNKNOWN) 84.193 + { 84.194 + if (CF_SET()) 84.195 + flags |= C_FLAG; 84.196 + else 84.197 + flags &= ~C_FLAG; 84.198 + } 84.199 +} 84.200 + 84.201 static inline void setznp8(uint8_t val) 84.202 { 84.203 - flags&=~0x8d5; 84.204 - flags|=znptable8[val]; 84.205 + flags_op = FLAGS_ZN8; 84.206 + flags_res = val; 84.207 + flags &= ~C_FLAG; 84.208 } 84.209 - 84.210 static inline void setznp16(uint16_t val) 84.211 { 84.212 - flags&=~0x8d5; 84.213 - flags|=znptable16[val]; 84.214 + flags_op = FLAGS_ZN16; 84.215 + flags_res = val; 84.216 + flags &= ~C_FLAG; 84.217 } 84.218 static inline void setznp32(uint32_t val) 84.219 { 84.220 - flags&=~0x8d5; 84.221 - flags|=((val&0x80000000)?N_FLAG:((!val)?Z_FLAG:0)); 84.222 - flags|=znptable8[val&0xFF]&P_FLAG; 84.223 + flags_op = FLAGS_ZN32; 84.224 + flags_res = val; 84.225 + flags &= ~C_FLAG; 84.226 } 84.227 + 84.228 +static inline void setadd8(uint8_t a, uint8_t b) 84.229 +{ 84.230 + flags_op1 = a; 84.231 + flags_op2 = b; 84.232 + flags_res = (a + b) & 0xff; 84.233 + flags_op = FLAGS_ADD8; 84.234 + 84.235 + if ((a + b) & 0x100) flags |= C_FLAG; 84.236 + else flags &= ~C_FLAG; 84.237 +} 84.238 +static inline void setadd16(uint16_t a, uint16_t b) 84.239 +{ 84.240 + flags_op1 = a; 84.241 + flags_op2 = b; 84.242 + flags_res = (a + b) & 0xffff; 84.243 + flags_op = FLAGS_ADD16; 84.244 + 84.245 + if ((a + b) & 0x10000) flags |= C_FLAG; 84.246 + else flags &= ~C_FLAG; 84.247 +} 84.248 +static inline void setadd32(uint32_t a, uint32_t b) 84.249 +{ 84.250 + flags_op1 = a; 84.251 + flags_op2 = b; 84.252 + flags_res = a + b; 84.253 + flags_op = FLAGS_ADD32; 84.254 + 84.255 + if (flags_res < a) flags |= C_FLAG; 84.256 + else flags &= ~C_FLAG; 84.257 +} 84.258 +static inline void setadd8nc(uint8_t a, uint8_t b) 84.259 +{ 84.260 + flags_op1 = a; 84.261 + flags_op2 = b; 84.262 + flags_res = (a + b) & 0xff; 84.263 + flags_op = FLAGS_ADD8; 84.264 +} 84.265 +static inline void setadd16nc(uint16_t a, uint16_t b) 84.266 +{ 84.267 + flags_op1 = a; 84.268 + flags_op2 = b; 84.269 + flags_res = (a + b) & 0xffff; 84.270 + flags_op = FLAGS_ADD16; 84.271 +} 84.272 +static inline void setadd32nc(uint32_t a, uint32_t b) 84.273 +{ 84.274 + flags_op1 = a; 84.275 + flags_op2 = b; 84.276 + flags_res = a + b; 84.277 + flags_op = FLAGS_ADD32; 84.278 +} 84.279 + 84.280 +static inline void setsub8(uint8_t a, uint8_t b) 84.281 +{ 84.282 + flags_op1 = a; 84.283 + flags_op2 = b; 84.284 + flags_res = (a - b) & 0xff; 84.285 + flags_op = FLAGS_SUB8; 84.286 + 84.287 + if (a < b) flags |= C_FLAG; 84.288 + else flags &= ~C_FLAG; 84.289 +} 84.290 +static inline void setsub16(uint16_t a, uint16_t b) 84.291 +{ 84.292 + flags_op1 = a; 84.293 + flags_op2 = b; 84.294 + flags_res = (a - b) & 0xffff; 84.295 + flags_op = FLAGS_SUB16; 84.296 + 84.297 + if (a < b) flags |= C_FLAG; 84.298 + else flags &= ~C_FLAG; 84.299 +} 84.300 +static inline void setsub32(uint32_t a, uint32_t b) 84.301 +{ 84.302 + flags_op1 = a; 84.303 + flags_op2 = b; 84.304 + flags_res = a - b; 84.305 + flags_op = FLAGS_SUB32; 84.306 + 84.307 + if (a < b) flags |= C_FLAG; 84.308 + else flags &= ~C_FLAG; 84.309 +} 84.310 + 84.311 +static inline void setsub8nc(uint8_t a, uint8_t b) 84.312 +{ 84.313 + flags_op1 = a; 84.314 + flags_op2 = b; 84.315 + flags_res = (a - b) & 0xff; 84.316 + flags_op = FLAGS_SUB8; 84.317 +} 84.318 +static inline void setsub16nc(uint16_t a, uint16_t b) 84.319 +{ 84.320 + flags_op1 = a; 84.321 + flags_op2 = b; 84.322 + flags_res = (a - b) & 0xffff; 84.323 + flags_op = FLAGS_SUB16; 84.324 +} 84.325 +static inline void setsub32nc(uint32_t a, uint32_t b) 84.326 +{ 84.327 + flags_op1 = a; 84.328 + flags_op2 = b; 84.329 + flags_res = a - b; 84.330 + flags_op = FLAGS_SUB32; 84.331 +} 84.332 + 84.333 +static inline void setadc8(uint8_t a, uint8_t b) 84.334 +{ 84.335 + uint16_t c=(uint16_t)a+(uint16_t)b+tempc; 84.336 + flags_op = FLAGS_UNKNOWN; 84.337 + flags&=~0x8D5; 84.338 + flags|=znptable8[c&0xFF]; 84.339 + if (c&0x100) flags|=C_FLAG; 84.340 + if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; 84.341 + if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 84.342 +} 84.343 +static inline void setadc16(uint16_t a, uint16_t b) 84.344 +{ 84.345 + uint32_t c=(uint32_t)a+(uint32_t)b+tempc; 84.346 + flags_op = FLAGS_UNKNOWN; 84.347 + flags&=~0x8D5; 84.348 + flags|=znptable16[c&0xFFFF]; 84.349 + if (c&0x10000) flags|=C_FLAG; 84.350 + if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; 84.351 + if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; 84.352 +} 84.353 + 84.354 +static inline void setsbc8(uint8_t a, uint8_t b) 84.355 +{ 84.356 + uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc); 84.357 + flags_op = FLAGS_UNKNOWN; 84.358 + flags&=~0x8D5; 84.359 + flags|=znptable8[c&0xFF]; 84.360 + if (c&0x100) flags|=C_FLAG; 84.361 + if ((a^b)&(a^c)&0x80) flags|=V_FLAG; 84.362 + if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 84.363 +} 84.364 +static inline void setsbc16(uint16_t a, uint16_t b) 84.365 +{ 84.366 + uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); 84.367 + flags_op = FLAGS_UNKNOWN; 84.368 + flags&=~0x8D5; 84.369 + flags|=(znptable16[c&0xFFFF]&~4); 84.370 + flags|=(znptable8[c&0xFF]&4); 84.371 + if (c&0x10000) flags|=C_FLAG; 84.372 + if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; 84.373 + if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; 84.374 +} 84.375 + 84.376 +static inline void setadc32(uint32_t a, uint32_t b) 84.377 +{ 84.378 + uint32_t c=(uint32_t)a+(uint32_t)b+tempc; 84.379 + flags_op = FLAGS_UNKNOWN; 84.380 + flags&=~0x8D5; 84.381 + flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); 84.382 + flags|=(znptable8[c&0xFF]&P_FLAG); 84.383 + if ((c<a) || (c==a && tempc)) flags|=C_FLAG; 84.384 + if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) flags|=V_FLAG; 84.385 + if (((a&0xF)+(b&0xF)+tempc)&0x10) flags|=A_FLAG; 84.386 +} 84.387 +static inline void setsbc32(uint32_t a, uint32_t b) 84.388 +{ 84.389 + uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); 84.390 + flags_op = FLAGS_UNKNOWN; 84.391 + flags&=~0x8D5; 84.392 + flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); 84.393 + flags|=(znptable8[c&0xFF]&P_FLAG); 84.394 + if ((c>a) || (c==a && tempc)) flags|=C_FLAG; 84.395 + if ((a^b)&(a^c)&0x80000000) flags|=V_FLAG; 84.396 + if (((a&0xF)-((b&0xF)+tempc))&0x10) flags|=A_FLAG; 84.397 +} 84.398 +
85.1 --- a/src/x86seg.c Sun Apr 21 14:54:35 2013 +0100 85.2 +++ b/src/x86seg.c Mon May 27 17:46:42 2013 +0100 85.3 @@ -1,8 +1,11 @@ 85.4 //#if 0 85.5 #include <stdio.h> 85.6 #include <stdarg.h> 85.7 +#include <stdlib.h> 85.8 #include "ibm.h" 85.9 +#include "mem.h" 85.10 #include "x86.h" 85.11 +#include "386.h" 85.12 85.13 /*Controls whether the accessed bit in a descriptor is set when CS is loaded. The 85.14 386 PRM is ambiguous on this subject, but BOCHS doesn't set it and Windows 98 85.15 @@ -29,7 +32,6 @@ 85.16 void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); 85.17 void taskswitch386(uint16_t seg, uint16_t *segdat); 85.18 85.19 -int notpresent=0; 85.20 int output; 85.21 void pmodeint(int num, int soft); 85.22 /*NOT PRESENT is INT 0B 85.23 @@ -125,8 +127,6 @@ 85.24 void x86np(char *s, uint16_t error) 85.25 { 85.26 // pclog("NP %04X : %s\n", error, s); 85.27 -// dumpregs(); 85.28 -// exit(-1); 85.29 abrt = ABRT_NP; 85.30 abrt_error = error; 85.31 } 85.32 @@ -325,8 +325,6 @@ 85.33 { 85.34 uint16_t segdat[4]; 85.35 uint32_t addr; 85.36 - int count; 85.37 - uint16_t oldss,oldsp; 85.38 if (output) pclog("Load CS %04X\n",seg); 85.39 if (msw&1 && !(eflags&VM_FLAG)) 85.40 { 85.41 @@ -452,10 +450,9 @@ 85.42 uint16_t segdat[4]; 85.43 uint32_t addr; 85.44 int count; 85.45 - uint16_t oldss,oldsp; 85.46 uint16_t type,seg2; 85.47 uint32_t newpc; 85.48 - if (output) pclog("Load CS JMP %04X\n",seg); 85.49 +// pclog("Load CS JMP %04X\n",seg); 85.50 if (msw&1 && !(eflags&VM_FLAG)) 85.51 { 85.52 if (!(seg&~3)) 85.53 @@ -495,6 +492,7 @@ 85.54 if (output) pclog("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]); 85.55 if (segdat[2]&0x1000) /*Normal code segment*/ 85.56 { 85.57 +// pclog("Normal CS\n"); 85.58 if (!(segdat[2]&0x400)) /*Not conforming*/ 85.59 { 85.60 if ((seg&3)>CPL) 85.61 @@ -528,7 +526,7 @@ 85.62 #endif 85.63 85.64 CS = (seg & ~3) | CPL; 85.65 - segdat[2] = (segdat[2] & ~(3 << 5+8)) | (CPL << 5+8); 85.66 + segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); 85.67 85.68 _cs.limit=segdat[0]|((segdat[3]&0xF)<<16); 85.69 if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF; 85.70 @@ -541,6 +539,7 @@ 85.71 } 85.72 else /*System segment*/ 85.73 { 85.74 +// pclog("System CS\n"); 85.75 if (!(segdat[2]&0x8000)) 85.76 { 85.77 x86np("Load CS JMP system selector not present\n", seg & 0xfffc); 85.78 @@ -553,6 +552,7 @@ 85.79 { 85.80 case 0x400: /*Call gate*/ 85.81 case 0xC00: 85.82 +// pclog("Call gate\n"); 85.83 cgate32=(type&0x800); 85.84 cgate16=!cgate32; 85.85 oldcs=CS; 85.86 @@ -654,6 +654,7 @@ 85.87 85.88 85.89 case 0x900: /*386 Task gate*/ 85.90 +// pclog("Task gate\n"); 85.91 pc=oxpc; 85.92 cpl_override=1; 85.93 taskswitch286(seg,segdat,segdat[2]&0x800); 85.94 @@ -853,7 +854,7 @@ 85.95 if (segdat[2]&0x400) 85.96 { 85.97 seg = (seg & ~3) | CPL; 85.98 - segdat[2] = (segdat[2] & ~(3 << 5+8)) | (CPL << 5+8); 85.99 + segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); 85.100 } 85.101 else /*On non-conforming segments, set RPL = CPL*/ 85.102 seg = (seg & ~3) | CPL; 85.103 @@ -1332,7 +1333,7 @@ 85.104 85.105 pc=newpc; 85.106 if (segdat[2] & 0x400) 85.107 - segdat[2] = (segdat[2] & ~(3 << 5+8)) | ((seg & 3) << 5+8); 85.108 + segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); 85.109 CS = seg; 85.110 _cs.limit=segdat[0]|((segdat[3]&0xF)<<16); 85.111 if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF; 85.112 @@ -1493,7 +1494,7 @@ 85.113 #endif 85.114 /*Conforming segments don't change CPL, so CPL = RPL*/ 85.115 if (segdat[2]&0x400) 85.116 - segdat[2] = (segdat[2] & ~(3 << 5+8)) | ((seg & 3) << 5+8); 85.117 + segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); 85.118 85.119 pc=newpc; 85.120 CS=seg; 85.121 @@ -1521,14 +1522,11 @@ 85.122 { 85.123 uint16_t segdat[4],segdat2[4],segdat3[4]; 85.124 uint32_t addr, oaddr; 85.125 - int dpl; 85.126 - uint16_t oldcs=CPL,oldcs2,newss; 85.127 + uint16_t newss; 85.128 uint32_t oldss,oldsp; 85.129 - uint8_t oldaccess; 85.130 int type; 85.131 uint32_t newsp; 85.132 uint16_t seg; 85.133 - int v86int=eflags&VM_FLAG; 85.134 int stack_changed=0; 85.135 // if (!num) pclog("Pmode int 0 at %04X(%06X):%08X\n",CS,cs,pc); 85.136 // pclog("Pmode int %02X %i %04X:%08X %04X:%08X %i\n",num,soft,CS,pc, SS, ESP, abrt); 85.137 @@ -1910,12 +1908,10 @@ 85.138 } 85.139 } 85.140 85.141 -int inint; 85.142 void pmodeiret(int is32) 85.143 { 85.144 uint32_t newsp; 85.145 - uint16_t oldcs=CPL,newss; 85.146 - uint16_t tempw,tempw2; 85.147 + uint16_t newss; 85.148 uint32_t tempflags,flagmask; 85.149 uint32_t newpc; 85.150 uint16_t segdat[4],segdat2[4]; 85.151 @@ -1991,7 +1987,6 @@ 85.152 cpl_override=0; 85.153 return; 85.154 } 85.155 - inint=0; 85.156 oxpc=pc; 85.157 flagmask=0xFFFF; 85.158 if (CPL) flagmask&=~0x3000; 85.159 @@ -2254,7 +2249,7 @@ 85.160 #endif 85.161 /*Conforming segments don't change CPL, so CPL = RPL*/ 85.162 if (segdat[2]&0x400) 85.163 - segdat[2] = (segdat[2] & ~(3 << 5+8)) | ((seg & 3) << 5+8); 85.164 + segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); 85.165 85.166 CS=seg; 85.167 _cs.limit=segdat[0]|((segdat[3]&0xF)<<16); 85.168 @@ -2295,12 +2290,10 @@ 85.169 85.170 void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) 85.171 { 85.172 - uint32_t base,obase=tr.base; 85.173 + uint32_t base; 85.174 uint32_t limit; 85.175 - int x386; 85.176 uint32_t templ; 85.177 uint16_t tempw; 85.178 - int c; 85.179 85.180 uint32_t new_cr3=0; 85.181 uint16_t new_es,new_cs,new_ss,new_ds,new_fs,new_gs; 85.182 @@ -2310,8 +2303,6 @@ 85.183 85.184 uint32_t addr; 85.185 85.186 - uint16_t oldflags; 85.187 - 85.188 uint16_t segdat2[4]; 85.189 85.190 //output=3; 85.191 @@ -2361,6 +2352,7 @@ 85.192 if (optype==IRET) flags&=~NT_FLAG; 85.193 85.194 // if (output) pclog("Write PC %08X %08X\n",tr.base,pc); 85.195 + cpu_386_flags_rebuild(); 85.196 writememl(tr.base,0x1C,cr3); 85.197 writememl(tr.base,0x20,pc); 85.198 writememl(tr.base,0x24,flags|(eflags<<16)); 85.199 @@ -2402,7 +2394,7 @@ 85.200 85.201 85.202 cr3=new_cr3; 85.203 -// pclog("New CR3 %08X\n",cr3); 85.204 + pclog("TS New CR3 %08X\n",cr3); 85.205 flushmmucache(); 85.206 85.207 85.208 @@ -2411,6 +2403,7 @@ 85.209 // if (output) pclog("New pc %08X\n",new_pc); 85.210 flags=new_flags; 85.211 eflags=new_flags>>16; 85.212 + cpu_386_flags_extract(); 85.213 85.214 // if (output) pclog("Load LDT %04X\n",new_ldt); 85.215 ldt.seg=new_ldt;
86.1 --- a/src/x87.c Sun Apr 21 14:54:35 2013 +0100 86.2 +++ b/src/x87.c Mon May 27 17:46:42 2013 +0100 86.3 @@ -8,8 +8,11 @@ 86.4 //SCR_CalcRefdef 86.5 //Calls R_SetVrect and R_ViewChanged 86.6 86.7 +#define fplog 0 86.8 + 86.9 #include <math.h> 86.10 #include "ibm.h" 86.11 +#include "pic.h" 86.12 #include "x86.h" 86.13 #include "x87.h" 86.14 86.15 @@ -67,6 +70,30 @@ 86.16 #define C2 (1<<10) 86.17 #define C3 (1<<14) 86.18 86.19 +#define STATUS_ZERODIVIDE 4 86.20 + 86.21 +#define x87_div(dst, src1, src2) do \ 86.22 + { \ 86.23 + if (((double)src2) == 0.0) \ 86.24 + { \ 86.25 + npxs |= STATUS_ZERODIVIDE; \ 86.26 + if (npxc & STATUS_ZERODIVIDE) \ 86.27 + dst = src1 / (double)src2; \ 86.28 + else \ 86.29 + { \ 86.30 + pclog("FPU : divide by zero\n"); \ 86.31 + picint(1 << 13); \ 86.32 + } \ 86.33 + return; \ 86.34 + } \ 86.35 + else \ 86.36 + dst = src1 / (double)src2; \ 86.37 + } while (0) 86.38 + 86.39 +void x87_checkexceptions() 86.40 +{ 86.41 +} 86.42 + 86.43 void x87_reset() 86.44 { 86.45 } 86.46 @@ -80,8 +107,8 @@ 86.47 86.48 void x87_print() 86.49 { 86.50 - pclog("\tST(0)=%.20f\tST(1)=%.20f\tST(2)=%f\tST(3)=%f\t",ST[TOP],ST[(TOP+1)&7],ST[(TOP+2)&7],ST[(TOP+3)&7]); 86.51 - pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n\n",ST[(TOP+4)&7],ST[(TOP+5)&7],ST[(TOP+6)&7],ST[(TOP+7)&7]); 86.52 + pclog("\tST(0)=%.20f\tST(1)=%.20f\tST(2)=%f\tST(3)=%f\t",ST[TOP&7],ST[(TOP+1)&7],ST[(TOP+2)&7],ST[(TOP+3)&7]); 86.53 + pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t TOP=%i CR=%04X SR=%04X TAG=%04X\n",ST[(TOP+4)&7],ST[(TOP+5)&7],ST[(TOP+6)&7],ST[(TOP+7)&7], TOP, npxc, npxs, tag); 86.54 } 86.55 86.56 void x87_push(double i) 86.57 @@ -186,16 +213,19 @@ 86.58 { 86.59 case 0xC0: case 0xC1: case 0xC2: case 0xC3: /*FADD*/ 86.60 case 0xC4: case 0xC5: case 0xC6: case 0xC7: 86.61 + if (fplog) pclog("FADD\n"); 86.62 ST(0)=ST(0)+ST(rmdat32&7); 86.63 cycles-=8; 86.64 return; 86.65 case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*FMUL*/ 86.66 case 0xCC: case 0xCD: case 0xCE: case 0xCF: 86.67 + if (fplog) pclog("FMUL\n"); 86.68 ST(0)=ST(0)*ST(rmdat32&7); 86.69 cycles-=16; 86.70 return; 86.71 case 0xD0: case 0xD1: case 0xD2: case 0xD3: /*FCOM*/ 86.72 case 0xD4: case 0xD5: case 0xD6: case 0xD7: 86.73 + if (fplog) pclog("FCOM\n"); 86.74 npxs&=~(C0|C2|C3); 86.75 if (ST(0)==ST(rmdat32&7)) npxs|=C3; 86.76 else if (ST(0)<ST(rmdat32&7)) npxs|=C0; 86.77 @@ -203,6 +233,7 @@ 86.78 return; 86.79 case 0xD8: case 0xD9: case 0xDA: case 0xDB: /*FCOMP*/ 86.80 case 0xDC: case 0xDD: case 0xDE: case 0xDF: 86.81 + if (fplog) pclog("FCOMP\n"); 86.82 npxs&=~(C0|C2|C3); 86.83 if (ST(0)==ST(rmdat32&7)) npxs|=C3; 86.84 else if (ST(0)<ST(rmdat32&7)) npxs|=C0; 86.85 @@ -211,22 +242,26 @@ 86.86 return; 86.87 case 0xE0: case 0xE1: case 0xE2: case 0xE3: /*FSUB*/ 86.88 case 0xE4: case 0xE5: case 0xE6: case 0xE7: 86.89 + if (fplog) pclog("FSUB\n"); 86.90 ST(0)=ST(0)-ST(rmdat32&7); 86.91 cycles-=8; 86.92 return; 86.93 case 0xE8: case 0xE9: case 0xEA: case 0xEB: /*FSUBR*/ 86.94 case 0xEC: case 0xED: case 0xEE: case 0xEF: 86.95 + if (fplog) pclog("FSUBR\n"); 86.96 ST(0)=ST(rmdat32&7)-ST(0); 86.97 cycles-=8; 86.98 return; 86.99 case 0xF0: case 0xF1: case 0xF2: case 0xF3: /*FDIV*/ 86.100 case 0xF4: case 0xF5: case 0xF6: case 0xF7: 86.101 - ST(0)=ST(0)/ST(rmdat32&7); 86.102 + if (fplog) pclog("FDIV\n"); 86.103 + x87_div(ST(0), ST(0), ST(rmdat32&7)); 86.104 cycles-=73; 86.105 return; 86.106 case 0xF8: case 0xF9: case 0xFA: case 0xFB: /*FDIVR*/ 86.107 case 0xFC: case 0xFD: case 0xFE: case 0xFF: 86.108 - ST(0)=ST(rmdat32&7)/ST(0); 86.109 + if (fplog) pclog("FDIVR\n"); 86.110 + x87_div(ST(0), ST(rmdat32&7), ST(0)); 86.111 cycles-=73; 86.112 return; 86.113 } 86.114 @@ -237,20 +272,25 @@ 86.115 switch (reg) 86.116 { 86.117 case 0: /*FADD short*/ 86.118 + if (fplog) pclog("FADDs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s); 86.119 ST(0)+=ts.s; 86.120 cycles-=8; 86.121 return; 86.122 case 1: /*FMUL short*/ 86.123 + if (fplog) pclog("FMULs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s); 86.124 ST(0)*=ts.s; 86.125 cycles-=11; 86.126 + if (abrt) pclog("ABRT FMUL\n"); 86.127 return; 86.128 case 2: /*FCOM short*/ 86.129 + if (fplog) pclog("FCOMs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s); 86.130 npxs&=~(C0|C2|C3); 86.131 if (ST(0)==ts.s) npxs|=C3; 86.132 else if (ST(0)<ts.s) npxs|=C0; 86.133 cycles-=4; 86.134 return; 86.135 case 3: /*FCOMP short*/ 86.136 + if (fplog) pclog("FCOMPs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s); 86.137 npxs&=~(C0|C2|C3); 86.138 if (ST(0)==ts.s) npxs|=C3; 86.139 else if (ST(0)<ts.s) npxs|=C0; 86.140 @@ -258,19 +298,23 @@ 86.141 x87_pop(); 86.142 return; 86.143 case 4: /*FSUB short*/ 86.144 + if (fplog) pclog("FSUBs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s); 86.145 ST(0)-=ts.s; 86.146 cycles-=8; 86.147 return; 86.148 case 5: /*FSUBR short*/ 86.149 + if (fplog) pclog("FSUBRs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s); 86.150 ST(0)=ts.s-ST(0); 86.151 cycles-=8; 86.152 return; 86.153 case 6: /*FDIV short*/ 86.154 - ST(0)=ST(0)/ts.s; 86.155 + if (fplog) pclog("FDIVs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s); 86.156 + x87_div(ST(0), ST(0), ts.s); 86.157 cycles-=73; 86.158 return; 86.159 case 7: /*FDIVR short*/ 86.160 - ST(0)=ts.s/ST(0); 86.161 + if (fplog) pclog("FDIVRs %08X:%08X %f %f\n", easeg, eaaddr, ST(0), ts.s); 86.162 + x87_div(ST(0), ts.s, ST(0)); 86.163 cycles-=73; 86.164 return; 86.165 } 86.166 @@ -285,7 +329,6 @@ 86.167 float s; 86.168 uint32_t i; 86.169 } ts; 86.170 - float t; 86.171 double td; 86.172 int64_t temp64; 86.173 uint16_t tempw; 86.174 @@ -295,82 +338,99 @@ 86.175 { 86.176 case 0xC0: case 0xC1: case 0xC2: case 0xC3: /*FLD*/ 86.177 case 0xC4: case 0xC5: case 0xC6: case 0xC7: 86.178 + if (fplog) pclog("FLD %f\n", ST(rmdat32 & 7)); 86.179 x87_push(ST(rmdat32&7)); 86.180 cycles-=4; 86.181 return; 86.182 case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*FXCH*/ 86.183 case 0xCC: case 0xCD: case 0xCE: case 0xCF: 86.184 + if (fplog) pclog("FXCH\n"); 86.185 td=ST(0); 86.186 ST(0)=ST(rmdat32&7); 86.187 ST(rmdat32&7)=td; 86.188 cycles-=4; 86.189 return; 86.190 case 0xD0: /*FNOP*/ 86.191 + if (fplog) pclog("FNOP\n"); 86.192 cycles-=3; 86.193 return; 86.194 case 0xE0: /*FCHS*/ 86.195 + if (fplog) pclog("FCHS\n"); 86.196 ST(0)=-ST(0); 86.197 cycles-=6; 86.198 return; 86.199 case 0xE1: /*FABS*/ 86.200 + if (fplog) pclog("FABS %f\n", ST(0)); 86.201 ST(0)=fabs(ST(0)); 86.202 cycles-=3; 86.203 return; 86.204 case 0xE4: /*FTST*/ 86.205 + if (fplog) pclog("FTST\n"); 86.206 npxs&=~(C0|C2|C3); 86.207 if (ST(0)==0.0) npxs|=C3; 86.208 else if (ST(0)<0.0) npxs|=C0; 86.209 cycles-=4; 86.210 return; 86.211 case 0xE5: /*FXAM*/ 86.212 -// pclog("FXAM %f %i\n",ST(0),(tag>>((TOP&1)<<1))&3); 86.213 + if (fplog) pclog("FXAM %i %f\n", ((tag>>((TOP&7)<<1))&3), ST(0)); 86.214 +// pclog("FXAM %f %i\n",ST(0),(tag>>((TOP&7)<<1))&3); 86.215 npxs&=~(C0|C2|C3); 86.216 - if (((tag>>((TOP&1)<<1))&3)==3) npxs|=(C0|C3); 86.217 + if (((tag>>((TOP&7)<<1))&3)==3) npxs|=(C0|C3); 86.218 else if (ST(0)==0.0) npxs|=C3; 86.219 else npxs|=C2; 86.220 if (ST(0)<0.0) npxs|=C1; 86.221 cycles-=8; 86.222 return; 86.223 case 0xE8: /*FLD1*/ 86.224 + if (fplog) pclog("FLD1\n"); 86.225 x87_push(1.0); 86.226 cycles-=4; 86.227 return; 86.228 case 0xE9: /*FLDL2T*/ 86.229 + if (fplog) pclog("FLDL2T\n"); 86.230 x87_push(3.3219280948873623); 86.231 cycles-=8; 86.232 return; 86.233 case 0xEA: /*FLDL2E*/ 86.234 + if (fplog) pclog("FLDL2E\n"); 86.235 x87_push(1.4426950408889634); 86.236 cycles-=8; 86.237 return; 86.238 case 0xEB: /*FLDPI*/ 86.239 + if (fplog) pclog("FLDPI\n"); 86.240 x87_push(3.141592653589793); 86.241 cycles-=8; 86.242 return; 86.243 case 0xEC: /*FLDEG2*/ 86.244 + if (fplog) pclog("FLDEG2\n"); 86.245 x87_push(0.3010299956639812); 86.246 cycles-=8; 86.247 return; 86.248 case 0xED: /*FLDLN2*/ 86.249 + if (fplog) pclog("FLDLN2\n"); 86.250 x87_push(0.693147180559945); 86.251 cycles-=8; 86.252 return; 86.253 case 0xEE: /*FLDZ*/ 86.254 + if (fplog) pclog("FLDZ\n"); 86.255 // pclog("FLDZ %04X:%08X\n",CS,pc); 86.256 x87_push(0.0); 86.257 tag|=(1<<((TOP&7)<<1)); 86.258 cycles-=4; 86.259 return; 86.260 case 0xF0: /*F2XM1*/ 86.261 + if (fplog) pclog("F2XM1\n"); 86.262 ST(0)=pow(2.0,ST(0))-1.0; 86.263 cycles-=200; 86.264 return; 86.265 case 0xF1: /*FYL2X*/ 86.266 + if (fplog) pclog("FYL2X\n"); 86.267 ST(1)=ST(1)*(log(ST(0))/log(2.0)); 86.268 x87_pop(); 86.269 cycles-=250; 86.270 return; 86.271 case 0xF2: /*FPTAN*/ 86.272 + if (fplog) pclog("FPTAN\n"); 86.273 // pclog("Tan of %f = ",ST(0)); 86.274 ST(0)=tan(ST(0)); 86.275 // pclog("%f\n",ST(0)); 86.276 @@ -379,20 +439,31 @@ 86.277 cycles-=235; 86.278 return; 86.279 case 0xF3: /*FPATAN*/ 86.280 + if (fplog) pclog("FPATAN\n"); 86.281 +/* times++; 86.282 + if (times==50) 86.283 + { 86.284 + dumpregs(); 86.285 + exit(-1); 86.286 + }*/ 86.287 // pclog("FPATAN %08X\n",pc); 86.288 ST(1)=atan2(ST(1),ST(0)); 86.289 x87_pop(); 86.290 cycles-=250; 86.291 return; 86.292 case 0xF6: /*FDECSTP*/ 86.293 + if (fplog) pclog("FDECSTP\n"); 86.294 TOP=(TOP-1)&7; 86.295 return; 86.296 case 0xF7: /*FINCSTP*/ 86.297 + if (fplog) pclog("FINCSTP\n"); 86.298 TOP=(TOP+1)&7; 86.299 return; 86.300 case 0xF8: /*FPREM*/ 86.301 + if (fplog) pclog("FPREM %f %f ", ST(0), ST(1)); 86.302 temp64=(int64_t)(ST(0)/ST(1)); 86.303 ST(0)=ST(0)-(ST(1)*(double)temp64); 86.304 + if (fplog) pclog("%f\n", ST(0)); 86.305 npxs&=~(C0|C1|C2|C3); 86.306 if (temp64&4) npxs|=C0; 86.307 if (temp64&2) npxs|=C3; 86.308 @@ -400,10 +471,12 @@ 86.309 cycles-=100; 86.310 return; 86.311 case 0xFA: /*FSQRT*/ 86.312 + if (fplog) pclog("FSQRT\n"); 86.313 ST(0)=sqrt(ST(0)); 86.314 cycles-=83; 86.315 return; 86.316 case 0xFB: /*FSINCOS*/ 86.317 + if (fplog) pclog("FSINCOS\n"); 86.318 td=ST(0); 86.319 ST(0)=sin(td); 86.320 x87_push(cos(td)); 86.321 @@ -411,22 +484,26 @@ 86.322 cycles-=330; 86.323 return; 86.324 case 0xFC: /*FRNDINT*/ 86.325 + if (fplog) pclog("FRNDINT\n"); 86.326 // pclog("FRNDINT %f %i ",ST(0),(npxc>>10)&3); 86.327 ST(0)=(double)x87_fround(ST(0)); 86.328 // pclog("%f\n",ST(0)); 86.329 cycles-=21; 86.330 return; 86.331 case 0xFD: /*FSCALE*/ 86.332 + if (fplog) pclog("FSCALE\n"); 86.333 temp64=(int64_t)ST(1); 86.334 ST(0)=ST(0)*pow(2.0,(double)temp64); 86.335 cycles-=30; 86.336 return; 86.337 case 0xFE: /*FSIN*/ 86.338 + if (fplog) pclog("FSIN\n"); 86.339 ST(0)=sin(ST(0)); 86.340 npxs&=~C2; 86.341 cycles-=300; 86.342 return; 86.343 case 0xFF: /*FCOS*/ 86.344 + if (fplog) pclog("FCOS\n"); 86.345 ST(0)=cos(ST(0)); 86.346 npxs&=~C2; 86.347 cycles-=300; 86.348 @@ -438,24 +515,30 @@ 86.349 switch (reg) 86.350 { 86.351 case 0: /*FLD single-precision*/ 86.352 + if (fplog) pclog("FLDs %08X:%08X\n", easeg, eaaddr); 86.353 // if ((rmdat32&0xFFFF)==0xD445) { pclog("FLDS\n"); output=3; dumpregs(); exit(-1); } 86.354 - ts.i=(float)geteal(); if (abrt) return; 86.355 + ts.i=geteal(); if (abrt) { pclog("FLD sp abort\n"); return; } 86.356 + if (fplog) pclog(" %f\n", ts.s); 86.357 x87_push((double)ts.s); 86.358 cycles-=3; 86.359 return; 86.360 case 2: /*FST single-precision*/ 86.361 + if (fplog) pclog("FSTs %08X:%08X\n", easeg, eaaddr); 86.362 ts.s=(float)ST(0); 86.363 seteal(ts.i); 86.364 + if (abrt) { pclog("FST sp abort\n"); return; } 86.365 cycles-=7; 86.366 return; 86.367 case 3: /*FSTP single-precision*/ 86.368 + if (fplog) pclog("FSTPs %08X:%08X\n", easeg, eaaddr); 86.369 ts.s=(float)ST(0); 86.370 - seteal(ts.i); if (abrt) return; 86.371 + seteal(ts.i); if (abrt) { pclog("FSTP sp abort\n"); return; } 86.372 // if (pc==0x3f50c) pclog("FSTP %f %f %08X\n",ST(0),ts.s,ts.i); 86.373 x87_pop(); 86.374 cycles-=7; 86.375 return; 86.376 case 4: /*FLDENV*/ 86.377 + if (fplog) pclog("FLDENV %08X:%08X\n", easeg, eaaddr); 86.378 switch ((cr0&1)|(op32&0x100)) 86.379 { 86.380 case 0x000: /*16-bit real mode*/ 86.381 @@ -474,14 +557,17 @@ 86.382 break; 86.383 } 86.384 cycles-=(cr0&1)?34:44; 86.385 + if (abrt) { pclog("FLDENV\n"); return; } 86.386 return; 86.387 case 5: /*FLDCW*/ 86.388 + if (fplog) pclog("FLDCW %08X:%08X\n", easeg, eaaddr); 86.389 tempw=geteaw(); 86.390 - if (abrt) return; 86.391 + if (abrt) if (abrt) { pclog("FLDCW abort\n"); return; } 86.392 npxc=tempw; 86.393 cycles-=4; 86.394 return; 86.395 case 6: /*FSTENV*/ 86.396 + if (fplog) pclog("FSTENV %08X:%08X\n", easeg, eaaddr); 86.397 switch ((cr0&1)|(op32&0x100)) 86.398 { 86.399 case 0x000: /*16-bit real mode*/ 86.400 @@ -518,10 +604,13 @@ 86.401 writememl(easeg,eaaddr+24,x87_op_seg); 86.402 break; 86.403 } 86.404 + if (abrt) { pclog("FSTENV\n"); return; } 86.405 cycles-=(cr0&1)?56:67; 86.406 return; 86.407 case 7: /*FSTCW*/ 86.408 + if (fplog) pclog("FSTCW %08X:%08X\n", easeg, eaaddr); 86.409 seteaw(npxc); 86.410 + if (abrt) { pclog("FSTCW\n"); return; } 86.411 cycles-=3; 86.412 return; 86.413 } 86.414 @@ -537,6 +626,7 @@ 86.415 switch (rmdat32&0xFF) 86.416 { 86.417 case 0xE9: /*FUCOMPP*/ 86.418 + if (fplog) pclog("FUCOMPP\n", easeg, eaaddr); 86.419 npxs&=~(C0|C2|C3); 86.420 if (ST(0)==ST(1)) npxs|=C3; 86.421 else if (ST(0)<ST(1)) npxs|=C0; 86.422 @@ -548,24 +638,28 @@ 86.423 } 86.424 else 86.425 { 86.426 - templ=geteal(); if (abrt) return; 86.427 + templ=(int32_t)geteal(); if (abrt) return; 86.428 switch (reg) 86.429 { 86.430 case 0: /*FIADD*/ 86.431 + if (fplog) pclog("FIADDl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.432 ST(0)=ST(0)+(double)templ; 86.433 cycles-=20; 86.434 return; 86.435 case 1: /*FIMUL*/ 86.436 + if (fplog) pclog("FIMULl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.437 ST(0)=ST(0)*(double)templ; 86.438 cycles-=22; 86.439 return; 86.440 case 2: /*FICOM*/ 86.441 + if (fplog) pclog("FICOMl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.442 npxs&=~(C0|C2|C3); 86.443 if (ST(0)==(double)templ) npxs|=C3; 86.444 else if (ST(0)<(double)templ) npxs|=C0; 86.445 cycles-=15; 86.446 return; 86.447 case 3: /*FICOMP*/ 86.448 + if (fplog) pclog("FICOMPl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.449 npxs&=~(C0|C2|C3); 86.450 if (ST(0)==(double)templ) npxs|=C3; 86.451 else if (ST(0)<(double)templ) npxs|=C0; 86.452 @@ -573,19 +667,23 @@ 86.453 cycles-=15; 86.454 return; 86.455 case 4: /*FISUB*/ 86.456 + if (fplog) pclog("FISUBl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.457 ST(0)=ST(0)-(double)templ; 86.458 cycles-=20; 86.459 return; 86.460 case 5: /*FISUBR*/ 86.461 + if (fplog) pclog("FISUBRl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.462 ST(0)=(double)templ-ST(0); 86.463 cycles-=19; 86.464 return; 86.465 case 6: /*FIDIV*/ 86.466 - ST(0)=ST(0)/(double)templ; 86.467 + if (fplog) pclog("FIDIVl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.468 + x87_div(ST(0), ST(0), (double)templ); 86.469 cycles-=84; 86.470 return; 86.471 case 7: /*FIDIVR*/ 86.472 - ST(0)=(double)templ/ST(0); 86.473 + if (fplog) pclog("FIDIVRl %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.474 + x87_div(ST(0), (double)templ, ST(0)); 86.475 cycles-=84; 86.476 return; 86.477 } 86.478 @@ -597,6 +695,7 @@ 86.479 { 86.480 double t; 86.481 int32_t templ; 86.482 + int64_t temp64; 86.483 if (mod==3) 86.484 { 86.485 switch (reg) 86.486 @@ -607,9 +706,11 @@ 86.487 case 0xE1: 86.488 return; 86.489 case 0xE2: /*FCLEX*/ 86.490 + if (fplog) pclog("FCLEX\n"); 86.491 npxs&=0xFF00; 86.492 return; 86.493 case 0xE3: /*FINIT*/ 86.494 + if (fplog) pclog("FINIT\n"); 86.495 npxc=0x37F; 86.496 npxs=0; 86.497 tag=0xFFFF; 86.498 @@ -627,25 +728,38 @@ 86.499 switch (reg) 86.500 { 86.501 case 0: /*FILD short*/ 86.502 + if (fplog) pclog("FILDs %08X:%08X\n", easeg, eaaddr); 86.503 templ=geteal(); if (abrt) return; 86.504 + if (fplog) pclog(" %f %08X %i\n", (double)templ, templ, templ); 86.505 x87_push((double)templ); 86.506 cycles-=9; 86.507 return; 86.508 case 2: /*FIST short*/ 86.509 - seteal((int32_t)x87_fround(ST(0))); 86.510 + if (fplog) pclog("FISTs %08X:%08X\n", easeg, eaaddr); 86.511 + temp64 = x87_fround(ST(0)); 86.512 +/* if (temp64 > 2147483647 || temp64 < -2147483647) 86.513 + fatal("FISTl out of range! %i\n", temp64);*/ 86.514 + seteal((int32_t)temp64); 86.515 cycles-=28; 86.516 return; 86.517 case 3: /*FISTP short*/ 86.518 - seteal((int32_t)x87_fround(ST(0))); if (abrt) return; 86.519 + if (fplog) pclog("FISTPs %08X:%08X\n", easeg, eaaddr); 86.520 + temp64 = x87_fround(ST(0)); 86.521 +/* if (temp64 > 2147483647 || temp64 < -2147483647) 86.522 + fatal("FISTPl out of range! %i\n", temp64);*/ 86.523 + seteal((int32_t)temp64); if (abrt) return; 86.524 x87_pop(); 86.525 cycles-=28; 86.526 return; 86.527 case 5: /*FLD extended*/ 86.528 + if (fplog) pclog("FLDe %08X:%08X\n", easeg, eaaddr); 86.529 t=x87_ld80(); if (abrt) return; 86.530 + if (fplog) pclog(" %f\n", t); 86.531 x87_push(t); 86.532 cycles-=6; 86.533 return; 86.534 case 7: /*FSTP extended*/ 86.535 + if (fplog) pclog("FSTPe %08X:%08X\n", easeg, eaaddr); 86.536 x87_st80(ST(0)); if (abrt) return; 86.537 x87_pop(); 86.538 cycles-=6; 86.539 @@ -668,32 +782,38 @@ 86.540 { 86.541 case 0xC0: case 0xC1: case 0xC2: case 0xC3: /*FADD*/ 86.542 case 0xC4: case 0xC5: case 0xC6: case 0xC7: 86.543 + if (fplog) pclog("FADD %f %f\n", ST(rmdat32 & 7), ST(0)); 86.544 ST(rmdat32&7)=ST(rmdat32&7)+ST(0); 86.545 cycles-=8; 86.546 return; 86.547 case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*FMUL*/ 86.548 case 0xCC: case 0xCD: case 0xCE: case 0xCF: 86.549 + if (fplog) pclog("FMUL %f %f\n", ST(rmdat32 & 7), ST(0)); 86.550 ST(rmdat32&7)=ST(rmdat32&7)*ST(0); 86.551 cycles-=16; 86.552 return; 86.553 case 0xE0: case 0xE1: case 0xE2: case 0xE3: /*FSUBR*/ 86.554 case 0xE4: case 0xE5: case 0xE6: case 0xE7: 86.555 + if (fplog) pclog("FSUBR %f %f\n", ST(rmdat32 & 7), ST(0)); 86.556 ST(rmdat32&7)=ST(0)-ST(rmdat32&7); 86.557 cycles-=8; 86.558 return; 86.559 case 0xE8: case 0xE9: case 0xEA: case 0xEB: /*FSUB*/ 86.560 case 0xEC: case 0xED: case 0xEE: case 0xEF: 86.561 + if (fplog) pclog("FSUB %f %f\n", ST(rmdat32 & 7), ST(0)); 86.562 ST(rmdat32&7)=ST(rmdat32&7)-ST(0); 86.563 cycles-=8; 86.564 return; 86.565 case 0xF0: case 0xF1: case 0xF2: case 0xF3: /*FDIVR*/ 86.566 case 0xF4: case 0xF5: case 0xF6: case 0xF7: 86.567 - ST(rmdat32&7)=ST(0)/ST(rmdat32&7); 86.568 + if (fplog) pclog("FDIVR %f %f\n", ST(rmdat32 & 7), ST(0)); 86.569 + x87_div(ST(rmdat32&7), ST(0), ST(rmdat32&7)); 86.570 cycles-=73; 86.571 return; 86.572 case 0xF8: case 0xF9: case 0xFA: case 0xFB: /*FDIV*/ 86.573 case 0xFC: case 0xFD: case 0xFE: case 0xFF: 86.574 - ST(rmdat32&7)=ST(rmdat32&7)/ST(0); 86.575 + if (fplog) pclog("FDIV %f %f\n", ST(rmdat32 & 7), ST(0)); 86.576 + x87_div(ST(rmdat32&7), ST(rmdat32&7), ST(0)); 86.577 cycles-=73; 86.578 return; 86.579 } 86.580 @@ -706,20 +826,24 @@ 86.581 switch (reg) 86.582 { 86.583 case 0: /*FADD double*/ 86.584 + if (fplog) pclog("FADDd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d); 86.585 ST(0)+=t.d; 86.586 cycles-=8; 86.587 return; 86.588 case 1: /*FMUL double*/ 86.589 + if (fplog) pclog("FMULd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d); 86.590 ST(0)*=t.d; 86.591 cycles-=14; 86.592 return; 86.593 case 2: /*FCOM double*/ 86.594 + if (fplog) pclog("FCOMd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d); 86.595 npxs&=~(C0|C2|C3); 86.596 if (ST(0)==t.d) npxs|=C3; 86.597 else if (ST(0)<t.d) npxs|=C0; 86.598 cycles-=4; 86.599 return; 86.600 case 3: /*FCOMP double*/ 86.601 + if (fplog) pclog("FCOMPd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d); 86.602 npxs&=~(C0|C2|C3); 86.603 if (ST(0)==t.d) npxs|=C3; 86.604 else if (ST(0)<t.d) npxs|=C0; 86.605 @@ -727,19 +851,23 @@ 86.606 x87_pop(); 86.607 return; 86.608 case 4: /*FSUB double*/ 86.609 + if (fplog) pclog("FSUBd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d); 86.610 ST(0)-=t.d; 86.611 cycles-=8; 86.612 return; 86.613 case 5: /*FSUBR double*/ 86.614 + if (fplog) pclog("FSUBRd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d); 86.615 ST(0)=t.d-ST(0); 86.616 cycles-=8; 86.617 return; 86.618 case 6: /*FDIV double*/ 86.619 - ST(0)=ST(0)/t.d; 86.620 + if (fplog) pclog("FDIVd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d); 86.621 + x87_div(ST(0), ST(0), t.d); 86.622 cycles-=73; 86.623 return; 86.624 case 7: /*FDIVR double*/ 86.625 - ST(0)=t.d/ST(0); 86.626 + if (fplog) pclog("FDIVRd %08X:%08X %f %f\n", easeg, eaaddr, ST(0), t.d); 86.627 + x87_div(ST(0), t.d, ST(0)); 86.628 cycles-=73; 86.629 return; 86.630 } 86.631 @@ -760,10 +888,12 @@ 86.632 switch (reg) 86.633 { 86.634 case 0: /*FFREE*/ 86.635 + if (fplog) pclog("FFREE\n"); 86.636 tag|=(3<<((rmdat32&7)<<1)); 86.637 cycles-=3; 86.638 return; 86.639 case 2: /*FST*/ 86.640 + if (fplog) pclog("FST\n"); 86.641 ST(rmdat32&7)=ST(0); 86.642 temp=(tag>>((TOP&7)<<1))&3; 86.643 tag&=~(3<<((rmdat32&7)<<1)); 86.644 @@ -771,6 +901,7 @@ 86.645 cycles-=3; 86.646 return; 86.647 case 3: /*FSTP*/ 86.648 + if (fplog) pclog("FSTP\n"); 86.649 ST(rmdat32&7)=ST(0); 86.650 temp=(tag>>((TOP&7)<<1))&3; 86.651 tag&=~(3<<((rmdat32&7)<<1)); 86.652 @@ -779,12 +910,14 @@ 86.653 cycles-=3; 86.654 return; 86.655 case 4: /*FUCOM*/ 86.656 + if (fplog) pclog("FUCOM\n"); 86.657 npxs&=~(C0|C2|C3); 86.658 if (ST(0)==ST(rmdat32&7)) npxs|=C3; 86.659 else if (ST(0)<ST(rmdat32&7)) npxs|=C0; 86.660 cycles-=4; 86.661 return; 86.662 case 5: /*FUCOMP*/ 86.663 + if (fplog) pclog("FUCOMP\n"); 86.664 npxs&=~(C0|C2|C3); 86.665 if (ST(0)==ST(rmdat32&7)) npxs|=C3; 86.666 else if (ST(0)<ST(rmdat32&7)) npxs|=C0; 86.667 @@ -798,18 +931,22 @@ 86.668 switch (reg) 86.669 { 86.670 case 0: /*FLD double-precision*/ 86.671 + if (fplog) pclog("FLDd %08X:%08X\n", easeg, eaaddr); 86.672 t.i=readmeml(easeg,eaaddr); 86.673 t.i|=(uint64_t)readmeml(easeg,eaaddr+4)<<32; if (abrt) return; 86.674 + if (fplog) pclog(" %f\n", t.d); 86.675 x87_push(t.d); 86.676 cycles-=3; 86.677 return; 86.678 case 2: /*FST double-precision*/ 86.679 + if (fplog) pclog("FSTd %08X:%08X\n", easeg, eaaddr); 86.680 t.d=ST(0); 86.681 writememl(easeg,eaaddr,t.i); 86.682 writememl(easeg,eaaddr+4,(t.i>>32)); 86.683 cycles-=8; 86.684 return; 86.685 case 3: /*FSTP double-precision*/ 86.686 + if (fplog) pclog("FSTPd %08X:%08X\n", easeg, eaaddr); 86.687 t.d=ST(0); 86.688 writememl(easeg,eaaddr,t.i); 86.689 writememl(easeg,eaaddr+4,(t.i>>32)); if (abrt) return; 86.690 @@ -817,6 +954,7 @@ 86.691 cycles-=8; 86.692 return; 86.693 case 4: /*FRSTOR*/ 86.694 + if (fplog) pclog("FRSTOR %08X:%08X\n", easeg, eaaddr); 86.695 switch ((cr0&1)|(op32&0x100)) 86.696 { 86.697 case 0x000: /*16-bit real mode*/ 86.698 @@ -847,6 +985,7 @@ 86.699 cycles-=(cr0&1)?34:44; 86.700 return; 86.701 case 6: /*FSAVE*/ 86.702 + if (fplog) pclog("FSAVE %08X:%08X\n", easeg, eaaddr); 86.703 switch ((cr0&1)|(op32&0x100)) 86.704 { 86.705 case 0x000: /*16-bit real mode*/ 86.706 @@ -922,6 +1061,7 @@ 86.707 cycles-=(cr0&1)?56:67; 86.708 return; 86.709 case 7: /*FSTSW*/ 86.710 + if (fplog) pclog("FSTSW %08X:%08X\n", easeg, eaaddr); 86.711 seteaw((npxs&0xC7FF)|(TOP<<11)); 86.712 cycles-=3; 86.713 return; 86.714 @@ -932,7 +1072,6 @@ 86.715 } 86.716 void x87_de() 86.717 { 86.718 - double t; 86.719 int32_t templ; 86.720 if (mod==3) 86.721 { 86.722 @@ -940,17 +1079,20 @@ 86.723 { 86.724 case 0xC0: case 0xC1: case 0xC2: case 0xC3: /*FADDP*/ 86.725 case 0xC4: case 0xC5: case 0xC6: case 0xC7: 86.726 - ST(rmdat32&7)=ST(rmdat32&7)+ST[TOP]; 86.727 + if (fplog) pclog("FADDP %f %f\n", ST(rmdat32 & 7), ST(0)); 86.728 + ST(rmdat32&7)=ST(rmdat32&7)+ST(0); 86.729 x87_pop(); 86.730 cycles-=8; 86.731 return; 86.732 case 0xC8: case 0xC9: case 0xCA: case 0xCB: /*FMULP*/ 86.733 case 0xCC: case 0xCD: case 0xCE: case 0xCF: 86.734 - ST(rmdat32&7)=ST(rmdat32&7)*ST[TOP]; 86.735 + if (fplog) pclog("FMULP %f %f\n", ST(rmdat32 & 7), ST(0)); 86.736 + ST(rmdat32&7)=ST(rmdat32&7)*ST(0); 86.737 x87_pop(); 86.738 cycles-=16; 86.739 return; 86.740 case 0xD9: /*FCOMPP*/ 86.741 + if (fplog) pclog("FCOMPP %f %f\n", ST(0), ST(1)); 86.742 npxs&=~(C0|C2|C3); 86.743 if (ST(0)==ST(1)) npxs|=C3; 86.744 else if (ST(0)<ST(1)) npxs|=C0; 86.745 @@ -960,25 +1102,29 @@ 86.746 return; 86.747 case 0xE0: case 0xE1: case 0xE2: case 0xE3: /*FSUBRP*/ 86.748 case 0xE4: case 0xE5: case 0xE6: case 0xE7: 86.749 + if (fplog) pclog("FSUBRP %f %f\n", ST(rmdat32 & 7), ST(0)); 86.750 ST(rmdat32&7)=ST(0)-ST(rmdat32&7); 86.751 x87_pop(); 86.752 cycles-=8; 86.753 return; 86.754 case 0xE8: case 0xE9: case 0xEA: case 0xEB: /*FSUBP*/ 86.755 case 0xEC: case 0xED: case 0xEE: case 0xEF: 86.756 - ST(rmdat32&7)=ST(rmdat32&7)-ST[TOP]; 86.757 + if (fplog) pclog("FSUBP %f %f\n", ST(rmdat32 & 7), ST(0)); 86.758 + ST(rmdat32&7)=ST(rmdat32&7)-ST(0); 86.759 x87_pop(); 86.760 cycles-=8; 86.761 return; 86.762 case 0xF0: case 0xF1: case 0xF2: case 0xF3: /*FDIVRP*/ 86.763 case 0xF4: case 0xF5: case 0xF6: case 0xF7: 86.764 - ST(rmdat32&7)=ST(0)/ST(rmdat32&7); 86.765 + if (fplog) pclog("FDIVRP %f %f\n", ST(rmdat32 & 7), ST(0)); 86.766 + x87_div(ST(rmdat32&7), ST(0), ST(rmdat32&7)); 86.767 x87_pop(); 86.768 cycles-=73; 86.769 return; 86.770 case 0xF8: case 0xF9: case 0xFA: case 0xFB: /*FDIVP*/ 86.771 case 0xFC: case 0xFD: case 0xFE: case 0xFF: 86.772 - ST(rmdat32&7)=ST(rmdat32&7)/ST[TOP]; 86.773 + if (fplog) pclog("FDIVP %f %f %i\n", ST(rmdat32 & 7), ST(0), rmdat32 & 7); 86.774 + x87_div(ST(rmdat32&7), ST(rmdat32&7), ST(0)); 86.775 x87_pop(); 86.776 cycles-=73; 86.777 return; 86.778 @@ -986,24 +1132,28 @@ 86.779 } 86.780 else 86.781 { 86.782 - templ=(int32_t)geteaw(); if (abrt) return; 86.783 + templ=(int32_t)(int16_t)geteaw(); if (abrt) return; 86.784 switch (reg) 86.785 { 86.786 case 0: /*FIADD*/ 86.787 + if (fplog) pclog("FIADDw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.788 ST(0)=ST(0)+(double)templ; 86.789 cycles-=20; 86.790 return; 86.791 case 1: /*FIMUL*/ 86.792 + if (fplog) pclog("FIMULw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.793 ST(0)=ST(0)*(double)templ; 86.794 cycles-=22; 86.795 return; 86.796 case 2: /*FICOM*/ 86.797 + if (fplog) pclog("FICOMw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.798 npxs&=~(C0|C2|C3); 86.799 if (ST(0)==(double)templ) npxs|=C3; 86.800 else if (ST(0)<(double)templ) npxs|=C0; 86.801 cycles-=15; 86.802 return; 86.803 case 3: /*FICOMP*/ 86.804 + if (fplog) pclog("FICOMPw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.805 npxs&=~(C0|C2|C3); 86.806 if (ST(0)==(double)templ) npxs|=C3; 86.807 else if (ST(0)<(double)templ) npxs|=C0; 86.808 @@ -1011,19 +1161,23 @@ 86.809 cycles-=15; 86.810 return; 86.811 case 4: /*FISUB*/ 86.812 + if (fplog) pclog("FISUBw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.813 ST(0)=ST(0)-(double)templ; 86.814 cycles-=20; 86.815 return; 86.816 case 5: /*FISUBR*/ 86.817 + if (fplog) pclog("FISUBRw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.818 ST(0)=(double)templ-ST(0); 86.819 cycles-=19; 86.820 return; 86.821 case 6: /*FIDIV*/ 86.822 - ST(0)=ST(0)/(double)templ; 86.823 + if (fplog) pclog("FIDIVw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.824 + x87_div(ST(0), ST(0), (double)templ); 86.825 cycles-=84; 86.826 return; 86.827 case 7: /*FIDIVR*/ 86.828 - ST(0)=(double)templ/ST(0); 86.829 + if (fplog) pclog("FIDIVRw %08X:%08X %f %f\n", easeg, eaaddr, ST(0), (double)templ); 86.830 + x87_div(ST(0), (double)templ, ST(0)); 86.831 cycles-=84; 86.832 return; 86.833 } 86.834 @@ -1046,6 +1200,7 @@ 86.835 switch (rmdat32&0xFF) 86.836 { 86.837 case 0xE0: /*FSTSW AX*/ 86.838 + if (fplog) pclog("FSTSW\n"); 86.839 AX=npxs; 86.840 cycles-=3; 86.841 return; 86.842 @@ -1058,29 +1213,42 @@ 86.843 switch (reg) 86.844 { 86.845 case 0: /*FILD short*/ 86.846 + if (fplog) pclog("FILDw %08X:%08X\n", easeg, eaaddr); 86.847 temp16=geteaw(); if (abrt) return; 86.848 + if (fplog) pclog(" %f\n", (double)temp16); 86.849 x87_push((double)temp16); 86.850 cycles-=13; 86.851 return; 86.852 case 2: /*FIST word*/ 86.853 - temp16=x87_fround(ST(0)); 86.854 - seteaw(temp16); 86.855 + if (fplog) pclog("FISTw %08X:%08X\n", easeg, eaaddr); 86.856 + temp64 = x87_fround(ST(0)); 86.857 +/* if (temp64 > 32767 || temp64 < -32768) 86.858 + fatal("FISTw overflow %i\n", temp64);*/ 86.859 + seteaw((int16_t)temp64); 86.860 cycles-=29; 86.861 return; 86.862 case 3: /*FISTP word*/ 86.863 - temp16=x87_fround(ST(0)); 86.864 - seteaw(temp16); if (abrt) return; 86.865 + if (fplog) pclog("FISTPw %08X:%08X\n", easeg, eaaddr); 86.866 + temp64 = x87_fround(ST(0)); 86.867 +/* if (temp64 > 32767 || temp64 < -32768) 86.868 + fatal("FISTw overflow %i\n", temp64);*/ 86.869 + seteaw((int16_t)temp64); if (abrt) return; 86.870 x87_pop(); 86.871 cycles-=29; 86.872 return; 86.873 case 5: /*FILD long*/ 86.874 + if (fplog) pclog("FILDl %08X:%08X\n", easeg, eaaddr); 86.875 temp64=geteal(); if (abrt) return; 86.876 temp64|=(uint64_t)readmeml(easeg,eaaddr+4)<<32; 86.877 + if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,eaaddr), readmeml(easeg,eaaddr+4)); 86.878 x87_push((double)temp64); 86.879 cycles-=10; 86.880 return; 86.881 case 6: /*FBSTP*/ 86.882 + if (fplog) pclog("FBSTP %08X:%08X\n", easeg, eaaddr); 86.883 tempd=ST(0); 86.884 + if (tempd < 0.0) 86.885 + tempd = -tempd; 86.886 for (c=0;c<9;c++) 86.887 { 86.888 tempc=(uint8_t)floor(fmod(tempd,10.0)); tempd-=floor(fmod(tempd,10.0)); tempd/=10.0; 86.889 @@ -1088,11 +1256,12 @@ 86.890 writememb(easeg,eaaddr+c,tempc); 86.891 } 86.892 tempc=(uint8_t)floor(fmod(tempd,10.0)); 86.893 - if (tempd<0.0) tempc|=0x80; 86.894 + if (ST(0)<0.0) tempc|=0x80; 86.895 writememb(easeg,eaaddr+9,tempc); if (abrt) return; 86.896 x87_pop(); 86.897 return; 86.898 case 7: /*FISTP long*/ 86.899 + if (fplog) pclog("FISTPl %08X:%08X\n", easeg, eaaddr); 86.900 temp64=x87_fround(ST(0)); 86.901 seteal(temp64); 86.902 writememl(easeg,eaaddr+4,temp64>>32); if (abrt) return;
87.1 --- a/src/xtide.c Sun Apr 21 14:54:35 2013 +0100 87.2 +++ b/src/xtide.c Mon May 27 17:46:42 2013 +0100 87.3 @@ -1,10 +1,12 @@ 87.4 #include "ibm.h" 87.5 + 87.6 +#include "io.h" 87.7 +#include "ide.h" 87.8 #include "xtide.h" 87.9 -#include "ide.h" 87.10 87.11 uint8_t xtide_high; 87.12 87.13 -void xtide_write(uint16_t port, uint8_t val) 87.14 +void xtide_write(uint16_t port, uint8_t val, void *priv) 87.15 { 87.16 switch (port & 0xf) 87.17 { 87.18 @@ -27,7 +29,7 @@ 87.19 } 87.20 } 87.21 87.22 -uint8_t xtide_read(uint16_t port) 87.23 +uint8_t xtide_read(uint16_t port, void *priv) 87.24 { 87.25 uint16_t tempw; 87.26 switch (port & 0xf) 87.27 @@ -51,5 +53,6 @@ 87.28 87.29 void xtide_init() 87.30 { 87.31 - io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL); 87.32 + ide_init(); 87.33 + io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, NULL); 87.34 }
