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
author TomW
date Mon May 27 17:46:42 2013 +0100
parents bba9a2b71a78
children 9c201151bb4b
files src/386.c src/Makefile.mingw src/acer386sx.c src/ali1429.c src/amstrad.c src/cdrom-ioctl.c src/config.c src/config.h src/cpu.c src/cpu.h src/dma.c src/dma.h src/ega.c src/fdc.c src/fdc.h src/headland.c src/ibm.h src/ide.c src/ide.h src/io.c src/io.h src/jim.c src/keyboard.c src/keyboard_amstrad.c src/keyboard_at.c src/keyboard_olim24.c src/keyboard_xt.c src/lpt.c src/lpt.h src/mem.c src/mem.h src/model.c src/model.h src/mouse_serial.c src/neat.c src/nvr.c src/nvr.h src/olivetti_m24.c src/pc.c src/pci.c src/pci.h src/pic.c src/pic.h src/pit.c src/resources.h src/serial.c src/sound.c src/sound.h src/soundopenal.c src/um8881f.c src/vid_cga.c src/vid_cga.h src/vid_ega.c src/vid_ega.h src/vid_et4000.c src/vid_et4000w32.c src/vid_hercules.c src/vid_mda.c src/vid_olivetti_m24.c src/vid_oti067.c src/vid_paradise.c src/vid_pc1512.c src/vid_pc1640.c src/vid_pc200.c src/vid_s3.c src/vid_sdac_ramdac.c src/vid_sdac_ramdac.h src/vid_stg_ramdac.c src/vid_stg_ramdac.h src/vid_svga.c src/vid_svga.h src/vid_tandy.c src/vid_tkd8001_ramdac.c src/vid_tkd8001_ramdac.h src/vid_tvga.c src/vid_unk_ramdac.c src/vid_unk_ramdac.h src/video.c src/video.h src/wd76c10.c src/win-video.c src/win.c src/x86.h src/x86_flags.h src/x86seg.c src/x87.c src/xtide.c
diffstat 87 files changed, 4471 insertions(+), 9316 deletions(-) [+]
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  }