PCem

changeset 2:9c201151bb4b

Add missing files from last commit.
author TomW
date Mon May 27 19:56:33 2013 +0100
parents fb4a67daaa1b
children ee7a3f8ad75d
files src/286.c src/386.h src/386_ops.h src/808x.c src/adlib.c src/cms.c src/device.c src/device.h src/gus.c src/i430vx.c src/i430vx.h src/piix.c src/piix.h src/ppi.h src/psg.c src/psg.h src/sblaster.c src/sound_adlib.c src/sound_adlib.h src/sound_adlibgold.c src/sound_adlibgold.h src/sound_cms.c src/sound_cms.h src/sound_gus.c src/sound_gus.h src/sound_opl.c src/sound_opl.h src/sound_pas16.c src/sound_pas16.h src/sound_sb.c src/sound_sb.h src/sound_sb_dsp.c src/sound_sb_dsp.h src/sound_sn76489.c src/sound_sn76489.h src/sound_speaker.c src/sound_speaker.h src/sound_wss.c src/sound_wss.h src/timer.c src/timer.h src/um8669f.c src/um8669f.h src/vid_ati18800.c src/vid_ati28800.c src/vid_ati68860_ramdac.c src/vid_ati68860_ramdac.h src/vid_ati_eeprom.c src/vid_ati_eeprom.h src/vid_ati_mach64.c src/vid_cl5429.c src/vid_et4000w32.h src/vid_ics2595.c src/vid_ics2595.h src/vid_s3_virge.c src/vid_svga_render.c src/vid_svga_render.h src/vid_vga.c src/vid_voodoo.c src/vid_voodoo.h src/x86.c src/x86_ops.h src/x86_ops_arith.h src/x86_ops_atomic.h src/x86_ops_bcd.h src/x86_ops_bit.h src/x86_ops_bitscan.h src/x86_ops_call.h src/x86_ops_flag.h src/x86_ops_fpu.h src/x86_ops_inc_dec.h src/x86_ops_int.h src/x86_ops_io.h src/x86_ops_jump.h src/x86_ops_misc.h src/x86_ops_mov.h src/x86_ops_mov_ctrl.h src/x86_ops_mov_seg.h src/x86_ops_movx.h src/x86_ops_msr.h src/x86_ops_mul.h src/x86_ops_pmode.h src/x86_ops_prefix.h src/x86_ops_rep.h src/x86_ops_ret.h src/x86_ops_set.h src/x86_ops_shift.h src/x86_ops_stack.h src/x86_ops_string.h src/x86_ops_xchg.h
diffstat 89 files changed, 21783 insertions(+), 9738 deletions(-) [+]
line diff
     1.1 --- a/src/286.c	Mon May 27 17:46:42 2013 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,3787 +0,0 @@
     1.4 -#include "ibm.h"
     1.5 -#include "x86.h"
     1.6 -#include "x86_flags.h"
     1.7 -#include "cpu.h"
     1.8 -#include "pit.h"
     1.9 -#include "keyboard.h"
    1.10 -
    1.11 -#define getword getword286
    1.12 -
    1.13 -#define checkio_perm(port) if (!IOPLp) \
    1.14 -                        { \
    1.15 -                                x86gpf(NULL,0); \
    1.16 -                                break; \
    1.17 -                        }
    1.18 -
    1.19 -#undef readmemb
    1.20 -#undef writememb
    1.21 -
    1.22 -#define readmemb(s,a) ((readlookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF)?readmemb386l(s,a):ram[readlookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)])
    1.23 -#define writememb(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememb386l(s,a,v); else ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]=v
    1.24 -#define writememw(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) writememwl(s,a,v); else *((uint16_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v
    1.25 -
    1.26 -extern int keywaiting;
    1.27 -
    1.28 -#define checklimit(a)
    1.29 -
    1.30 -/*#define checklimit(a)   if (msw&1 && (a)) \
    1.31 -                        { \
    1.32 -                                pclog("Seg limit GPF at %04X:%04X\n",CS,pc); \
    1.33 -                                pclog("%04X %04X %04X %i %04X %04X\n", ealimitw, ealimit, eaaddr, mod, _ds.limit, _ss.limit); \
    1.34 -                                x86gpf(NULL,0); \
    1.35 -                                break; \
    1.36 -                        }*/
    1.37 -
    1.38 -#define NOTRM   if (!(msw & 1))\
    1.39 -                { \
    1.40 -                        x86_int(6); \
    1.41 -                        break; \
    1.42 -                }
    1.43 -
    1.44 -
    1.45 -static inline uint8_t geteab()
    1.46 -{
    1.47 -        if (mod==3)
    1.48 -           return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l;
    1.49 -//        cycles-=3;
    1.50 -        return readmemb(easeg, eaaddr);
    1.51 -}
    1.52 -
    1.53 -static inline uint16_t geteaw()
    1.54 -{
    1.55 -        if (mod==3)
    1.56 -           return regs[rm].w;
    1.57 -//        cycles-=3;
    1.58 -//        if (output==3) printf("GETEAW %04X:%08X\n",easeg,eaaddr);
    1.59 -        return readmemw(easeg, eaaddr);
    1.60 -}
    1.61 -
    1.62 -static inline uint16_t geteaw2()
    1.63 -{
    1.64 -        if (mod==3)
    1.65 -           return regs[rm].w;
    1.66 -//        cycles-=2;
    1.67 -//        printf("Getting addr from %04X:%04X %05X\n",easeg,eaaddr+2,easeg+eaaddr+2);
    1.68 -        return readmemw(easeg,(eaaddr+2)&0xFFFF);
    1.69 -}
    1.70 -
    1.71 -static inline void seteab(uint8_t val)
    1.72 -{
    1.73 -        if (mod==3)
    1.74 -        {
    1.75 -                if (rm&4) regs[rm&3].b.h=val;
    1.76 -                else      regs[rm&3].b.l=val;
    1.77 -        }
    1.78 -        else
    1.79 -        {
    1.80 -//                cycles-=2;
    1.81 -                writememb(easeg, eaaddr, val);
    1.82 -        }
    1.83 -}
    1.84 -
    1.85 -static inline void seteaw(uint16_t val)
    1.86 -{
    1.87 -        if (mod==3)
    1.88 -           regs[rm].w=val;
    1.89 -        else
    1.90 -        {
    1.91 -//                cycles-=2;
    1.92 -                writememw(easeg, eaaddr, val);
    1.93 -//                writememb(easeg+eaaddr+1,val>>8);
    1.94 -        }
    1.95 -}
    1.96 -
    1.97 -#undef fetchea
    1.98 -
    1.99 -#define fetchea()   { rmdat=readmemb(cs, pc); pc++;     \
   1.100 -                    reg=(rmdat>>3)&7;                  \
   1.101 -                    mod=(rmdat>>6)&3;                  \
   1.102 -                    rm=rmdat&7;                        \
   1.103 -                    if (mod!=3) fetcheal286(); }
   1.104 -
   1.105 -void fetcheal286()
   1.106 -{
   1.107 -        if (!mod && rm==6) { eaaddr=getword(); easeg=ds; ealimit=_ds.limit; ealimitw=_ds.limitw; }
   1.108 -        else
   1.109 -        {
   1.110 -                switch (mod)
   1.111 -                {
   1.112 -                        case 0:
   1.113 -                        eaaddr=0;
   1.114 -                        break;
   1.115 -                        case 1:
   1.116 -                        eaaddr=(uint16_t)(int8_t)readmemb(cs, pc); pc++;
   1.117 -                        break;
   1.118 -                        case 2:
   1.119 -                        eaaddr=getword();
   1.120 -                        break;
   1.121 -                }
   1.122 -                eaaddr+=(*mod1add[0][rm])+(*mod1add[1][rm]);
   1.123 -                easeg=*mod1seg[rm];
   1.124 -                if (mod1seg[rm] == &ss) { ealimit=_ss.limit; ealimitw=_ss.limitw; }
   1.125 -                else                    { ealimit=_ds.limit; ealimitw=_ds.limitw; }
   1.126 -//                if (output) pclog("Limit %08X %08X %08X %08X\n",ealimit,_ds.limit,mod1seg[rm],&ss);
   1.127 -        }
   1.128 -        eaaddr&=0xFFFF;        
   1.129 -}
   1.130 -
   1.131 -void rep286(int fv)
   1.132 -{
   1.133 -        uint8_t temp;
   1.134 -        uint32_t c;//=CX;
   1.135 -        uint8_t temp2;
   1.136 -        uint16_t tempw,tempw2,tempw3,of=flags;
   1.137 -        uint32_t ipc=oldpc;//pc-1;
   1.138 -        int changeds=0;
   1.139 -        uint32_t oldds;
   1.140 -        uint32_t templ,templ2;
   1.141 -        int tempz;
   1.142 -        int tempi;
   1.143 -//        if (output) pclog("REP32 %04X %04X  ",use32,rep32);
   1.144 -        startrep:
   1.145 -        temp=opcode2=readmemb(cs,pc); pc++;
   1.146 -//        if (firstrepcycle && temp==0xA5) pclog("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI);
   1.147 -//        if (output) pclog("REP %02X %04X\n",temp,ipc);
   1.148 -        c = CX;
   1.149 -/*        if (rep32 && (msw&1))
   1.150 -        {
   1.151 -                if (temp!=0x67 && temp!=0x66 && (rep32|temp)!=0x1AB && (rep32|temp)!=0x3AB) pclog("32-bit REP %03X %08X %04X:%06X\n",temp|rep32,c,CS,pc);
   1.152 -        }*/
   1.153 -        switch (temp)
   1.154 -        {
   1.155 -                case 0x26: /*ES:*/
   1.156 -                oldds=ds;
   1.157 -                ds=es;
   1.158 -                rds=ES;
   1.159 -                changeds=1;
   1.160 -                goto startrep;
   1.161 -                break;
   1.162 -                case 0x2E: /*CS:*/
   1.163 -                oldds=ds;
   1.164 -                ds=cs;
   1.165 -                rds=CS;
   1.166 -                changeds=1;
   1.167 -                goto startrep;
   1.168 -                break;
   1.169 -                case 0x36: /*SS:*/
   1.170 -                oldds=ds;
   1.171 -                ds=ss;
   1.172 -                rds=SS;
   1.173 -                changeds=1;
   1.174 -                goto startrep;
   1.175 -                break;
   1.176 -                case 0x3E: /*DS:*/
   1.177 -                oldds=ds;
   1.178 -                ds=ds;
   1.179 -                changeds=1;
   1.180 -                goto startrep;
   1.181 -                break;
   1.182 -                case 0x6C: /*REP INSB*/
   1.183 -                if (c>0)
   1.184 -                {
   1.185 -                        checkio_perm(DX);
   1.186 -                        temp2=inb(DX);
   1.187 -                        writememb(es,DI,temp2);
   1.188 -                        if (abrt) break;
   1.189 -                        if (flags&D_FLAG) DI--;
   1.190 -                        else              DI++;
   1.191 -                        c--;
   1.192 -                        cycles-=15;
   1.193 -                }
   1.194 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.195 -                else firstrepcycle=1;
   1.196 -                break;
   1.197 -                case 0x6D: /*REP INSW*/
   1.198 -                if (c>0)
   1.199 -                {
   1.200 -                        tempw=inw(DX);
   1.201 -                        writememw(es,DI,tempw);
   1.202 -                        if (abrt) break;
   1.203 -                        if (flags&D_FLAG) DI-=2;
   1.204 -                        else              DI+=2;
   1.205 -                        c--;
   1.206 -                        cycles-=15;
   1.207 -                }
   1.208 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.209 -                else firstrepcycle=1;
   1.210 -                break;
   1.211 -                case 0x6E: /*REP OUTSB*/
   1.212 -                if (c>0)
   1.213 -                {
   1.214 -                        temp2=readmemb(ds,SI);
   1.215 -                        if (abrt) break;
   1.216 -                        checkio_perm(DX);
   1.217 -                        outb(DX,temp2);
   1.218 -                        if (flags&D_FLAG) SI--;
   1.219 -                        else              SI++;
   1.220 -                        c--;
   1.221 -                        cycles-=14;
   1.222 -                }
   1.223 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.224 -                else firstrepcycle=1;
   1.225 -                break;
   1.226 -                case 0x6F: /*REP OUTSW*/
   1.227 -                if (c>0)
   1.228 -                {
   1.229 -                        tempw=readmemw(ds,SI);
   1.230 -                        if (abrt) break;
   1.231 -//                        pclog("OUTSW %04X -> %04X\n",SI,tempw);
   1.232 -                        outw(DX,tempw);
   1.233 -                        if (flags&D_FLAG) SI-=2;
   1.234 -                        else              SI+=2;
   1.235 -                        c--;
   1.236 -                        cycles-=14;
   1.237 -                }
   1.238 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.239 -                else firstrepcycle=1;
   1.240 -                break;
   1.241 -                case 0xA4: /*REP MOVSB*/
   1.242 -                if (c>0)
   1.243 -                {
   1.244 -                        temp2=readmemb(ds,SI);  if (abrt) break;
   1.245 -                        writememb(es,DI,temp2); if (abrt) break;
   1.246 -//                        if (output==3) pclog("MOVSB %08X:%04X -> %08X:%04X %02X\n",ds,SI,es,DI,temp2);
   1.247 -                        if (flags&D_FLAG) { DI--; SI--; }
   1.248 -                        else              { DI++; SI++; }
   1.249 -                        c--;
   1.250 -                        cycles-=(is486)?3:4;
   1.251 -                }
   1.252 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.253 -                else firstrepcycle=1;
   1.254 -                break;
   1.255 -                case 0xA5: /*REP MOVSW*/
   1.256 -                if (c>0)
   1.257 -                {
   1.258 -                        tempw=readmemw(ds,SI);  if (abrt) break;
   1.259 -                        writememw(es,DI,tempw); if (abrt) break;
   1.260 -                        if (flags&D_FLAG) { DI-=2; SI-=2; }
   1.261 -                        else              { DI+=2; SI+=2; }
   1.262 -                        c--;
   1.263 -                        cycles-=(is486)?3:4;
   1.264 -                }
   1.265 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.266 -                else firstrepcycle=1;
   1.267 -                break;
   1.268 -                case 0xA6: /*REP CMPSB*/
   1.269 -                if (fv) flags|=Z_FLAG;
   1.270 -                else    flags&=~Z_FLAG;
   1.271 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))
   1.272 -                {
   1.273 -                        temp=readmemb(ds,SI);
   1.274 -                        temp2=readmemb(es,DI);
   1.275 -                        if (abrt) { flags=of; break; }
   1.276 -                        if (flags&D_FLAG) { DI--; SI--; }
   1.277 -                        else              { DI++; SI++; }
   1.278 -                        c--;
   1.279 -                        cycles-=(is486)?7:9;
   1.280 -                        setsub8(temp,temp2);
   1.281 -                }
   1.282 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.283 -                else firstrepcycle=1;
   1.284 -                break;
   1.285 -                case 0xA7: /*REP CMPSW*/
   1.286 -                if (fv) flags|=Z_FLAG;
   1.287 -                else    flags&=~Z_FLAG;
   1.288 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))
   1.289 -                {
   1.290 -                        tempw=readmemw(ds,SI);
   1.291 -                        tempw2=readmemw(es,DI);
   1.292 -                        if (abrt) { flags=of; break; }
   1.293 -                        if (flags&D_FLAG) { DI-=2; SI-=2; }
   1.294 -                        else              { DI+=2; SI+=2; }
   1.295 -                        c--;
   1.296 -                        cycles-=(is486)?7:9;
   1.297 -                        setsub16(tempw,tempw2);
   1.298 -                }
   1.299 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.300 -                else firstrepcycle=1;
   1.301 -                break;
   1.302 -
   1.303 -                case 0xAA: /*REP STOSB*/
   1.304 -                if (c>0)
   1.305 -                {
   1.306 -                        writememb(es,DI,AL);
   1.307 -                        if (abrt) break;
   1.308 -                        if (flags&D_FLAG) DI--;
   1.309 -                        else              DI++;
   1.310 -                        c--;
   1.311 -                        cycles-=(is486)?4:5;
   1.312 -                }
   1.313 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.314 -                else firstrepcycle=1;
   1.315 -                break;
   1.316 -                case 0xAB: /*REP STOSW*/
   1.317 -                if (c>0)
   1.318 -                {
   1.319 -                        writememw(es,DI,AX);
   1.320 -                        if (abrt) break;
   1.321 -                        if (flags&D_FLAG) DI-=2;
   1.322 -                        else              DI+=2;
   1.323 -                        c--;
   1.324 -                        cycles-=(is486)?4:5;
   1.325 -                }
   1.326 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.327 -                else firstrepcycle=1;
   1.328 -                break;
   1.329 -                case 0xAC: /*REP LODSB*/
   1.330 -//                if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
   1.331 -                if (c>0)
   1.332 -                {
   1.333 -                        AL=readmemb(ds,SI);
   1.334 -                        if (abrt) break;
   1.335 -                        if (flags&D_FLAG) SI--;
   1.336 -                        else              SI++;
   1.337 -                        c--;
   1.338 -                        cycles-=5;
   1.339 -                }
   1.340 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.341 -                else firstrepcycle=1;
   1.342 -                break;
   1.343 -                case 0xAD: /*REP LODSW*/
   1.344 -//                if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
   1.345 -                if (c>0)
   1.346 -                {
   1.347 -                        AX=readmemw(ds,SI);
   1.348 -                        if (abrt) break;
   1.349 -                        if (flags&D_FLAG) SI-=2;
   1.350 -                        else              SI+=2;
   1.351 -                        c--;
   1.352 -                        cycles-=5;
   1.353 -                }
   1.354 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.355 -                else firstrepcycle=1;
   1.356 -                break;
   1.357 -                case 0xAE: /*REP SCASB*/
   1.358 -//                if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
   1.359 -//                tempz=(fv)?1:0;
   1.360 -                if (fv) flags|=Z_FLAG;
   1.361 -                else    flags&=~Z_FLAG;
   1.362 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))
   1.363 -                {
   1.364 -                        temp2=readmemb(es,DI);
   1.365 -                        if (abrt) { flags=of; break; }
   1.366 -                        setsub8(AL,temp2);
   1.367 -                        if (flags&D_FLAG) DI--;
   1.368 -                        else              DI++;
   1.369 -                        c--;
   1.370 -                        cycles-=(is486)?5:8;
   1.371 -                }
   1.372 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.373 -                else firstrepcycle=1;
   1.374 -                break;
   1.375 -                case 0xAF: /*REP SCASW*/
   1.376 -//                if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
   1.377 -                if (fv) flags|=Z_FLAG;
   1.378 -                else    flags&=~Z_FLAG;
   1.379 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))
   1.380 -                {
   1.381 -                        tempw=readmemw(es,DI);
   1.382 -                        if (abrt) { flags=of; break; }
   1.383 -                        setsub16(AX,tempw);
   1.384 -                        if (flags&D_FLAG) DI-=2;
   1.385 -                        else              DI+=2;
   1.386 -                        c--;
   1.387 -                        cycles-=(is486)?5:8;
   1.388 -                }
   1.389 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.390 -                else firstrepcycle=1;
   1.391 -                break;
   1.392 -
   1.393 -                default:
   1.394 -                        pc=ipc;
   1.395 -                        cycles-=20;
   1.396 -                x86illegal();
   1.397 -                pclog("Bad REP %02X\n", temp);
   1.398 -                //dumpregs();
   1.399 -                //exit(-1);
   1.400 -        }
   1.401 -        CX=c;
   1.402 -        if (changeds) ds=oldds;
   1.403 -//        if (output) pclog("%03X %03X\n",rep32,use32);
   1.404 -}
   1.405 -
   1.406 -void x86illegal()
   1.407 -{
   1.408 -        uint16_t addr;
   1.409 -        pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode);
   1.410 -//        if (output)
   1.411 -//        {
   1.412 -//                dumpregs();
   1.413 -//                exit(-1);
   1.414 -//        }
   1.415 -        if (msw&1)
   1.416 -        {
   1.417 -                pmodeint(6,0);
   1.418 -        }
   1.419 -        else
   1.420 -        {
   1.421 -                if (ssegs) { ss=oldss; _ss.limit=oldsslimit; _ss.limitw=oldsslimitw; }
   1.422 -                writememw(ss,((SP-2)&0xFFFF),flags);
   1.423 -                writememw(ss,((SP-4)&0xFFFF),CS);
   1.424 -                writememw(ss,((SP-6)&0xFFFF),pc);
   1.425 -                SP-=6;
   1.426 -                flags&=~I_FLAG;
   1.427 -                flags&=~T_FLAG;
   1.428 -                addr=6<<2;
   1.429 -                pc=readmemw(0,addr);
   1.430 -                loadcs(readmemw(0,addr+2));
   1.431 -        }
   1.432 -        cycles-=70;
   1.433 -}
   1.434 -//#endif
   1.435 -//#if 0
   1.436 -
   1.437 -static inline uint8_t getbytef()
   1.438 -{
   1.439 -        uint8_t temp = readmemb(cs, pc); pc++;
   1.440 -        return temp;
   1.441 -}
   1.442 -static inline uint16_t getwordf()
   1.443 -{
   1.444 -        uint16_t tempw = readmemw(cs, pc); pc+=2;
   1.445 -        return tempw;
   1.446 -}
   1.447 -
   1.448 -/*Conditional jump timing is WRONG*/
   1.449 -void exec286(int cycs)
   1.450 -{
   1.451 -        uint8_t temp,temp2;
   1.452 -        uint16_t addr,tempw,tempw2,tempw3,tempw4;
   1.453 -        int8_t offset;
   1.454 -        volatile int tempws, tempws2;
   1.455 -        uint32_t templ, templ2, templ3;
   1.456 -        int8_t temps;
   1.457 -        int16_t temps16;
   1.458 -        int c;//,cycdiff;
   1.459 -        int tempi;
   1.460 -        FILE *f;
   1.461 -        int trap;
   1.462 -        int cyclast;
   1.463 -//        printf("Run 286! %i %i\n",cycles,cycs);
   1.464 -        cycles+=cycs;
   1.465 -//        i86_Execute(cycs);
   1.466 -//        return;
   1.467 -        while (cycles>0)
   1.468 -        {
   1.469 -                cyclast = cycdiff;
   1.470 -                cycdiff=cycles;
   1.471 -                oldcs=CS;
   1.472 -                oldpc=pc;
   1.473 -                oldcpl=CPL;
   1.474 -                
   1.475 -                opcodestart:
   1.476 -                opcode = readmemb(cs, pc);
   1.477 -                if (abrt) goto opcodeend;
   1.478 -                tempc=flags&C_FLAG;
   1.479 -                trap=flags&T_FLAG;
   1.480 -                
   1.481 -                if (output && /*cs<0xF0000 && */!ssegs)//opcode!=0x26 && opcode!=0x36 && opcode!=0x2E && opcode!=0x3E)
   1.482 -                {
   1.483 -                        if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle)
   1.484 -                        {
   1.485 -                                if (!skipnextprint) printf("%04X(%06X):%04X : %04X %04X %04X %04X %04X(%06X) %04X(%06X) %04X(%06X) %04X(%06X) %04X %04X %04X %04X %02X %04X  %04X  %04X %04X %04X  %08X %i %i  %i %08X  %i %f %f\n",CS,cs,pc,AX,BX,CX,DX,CS,cs,DS,ds,ES,es,SS,ss,DI,SI,BP,SP,opcode,flags,msw,ram[0x7c3e],ram[(0x7c3e)+3],ram[0x7c40],_ds.limitw,keybsenddelay,keywaiting,ins, _ss.limit, cyclast, pit.c[1], PITCONST);
   1.486 -                                skipnextprint=0;
   1.487 -//                                ins++;
   1.488 -/*                                if (ins==50000)
   1.489 -                                {
   1.490 -                                        dumpregs();
   1.491 -                                        exit(-1);
   1.492 -                                }*/
   1.493 -/*                                if (ins==500000)
   1.494 -                                {
   1.495 -                                        dumpregs();
   1.496 -                                        exit(-1);
   1.497 -                                }*/
   1.498 -                        }
   1.499 -                }
   1.500 -//#endif
   1.501 -                pc++;
   1.502 -                inhlt=0;
   1.503 -//                if (ins==500000) { dumpregs(); exit(0); }*/
   1.504 -                switch (opcode)
   1.505 -                {
   1.506 -                        case 0x00: /*ADD 8,reg*/
   1.507 -                        fetchea();
   1.508 -                        //if (!rmdat && output) pc--;
   1.509 -/*                        if (!rmdat && output)
   1.510 -                        {
   1.511 -                                pclog("Crashed\n");
   1.512 -//                                clear_keybuf();
   1.513 -//                                readkey();
   1.514 -                                dumpregs();
   1.515 -                                exit(-1);
   1.516 -                        }*/
   1.517 -                        if (mod == 3)
   1.518 -                        {
   1.519 -                                temp  = getr8(rm);
   1.520 -                                temp2 = getr8(reg);
   1.521 -                                setadd8(temp, temp2);
   1.522 -                                setr8(rm, temp + temp2);
   1.523 -                                cycles -= 2;
   1.524 -                        }
   1.525 -                        else
   1.526 -                        {
   1.527 -                                temp  = geteab();     if (abrt) break;
   1.528 -                                temp2 = getr8(reg);
   1.529 -                                seteab(temp + temp2); if (abrt) break;
   1.530 -                                setadd8(temp, temp2);
   1.531 -                                cycles -= 7;
   1.532 -                        }
   1.533 -                        break;
   1.534 -                        case 0x01: /*ADD 16,reg*/
   1.535 -                        fetchea();
   1.536 -                        if (mod == 3)
   1.537 -                        {
   1.538 -                                setadd16(regs[rm].w, regs[reg].w);
   1.539 -                                regs[rm].w += regs[reg].w;
   1.540 -                                cycles -= 2;
   1.541 -                        }
   1.542 -                        else
   1.543 -                        {
   1.544 -                                tempw = geteaw();             if (abrt) break;
   1.545 -                                seteaw(tempw + regs[reg].w);  if (abrt) break;
   1.546 -                                setadd16(tempw, regs[reg].w);
   1.547 -                                cycles -= 7;
   1.548 -                        }
   1.549 -                        break;
   1.550 -                        case 0x02: /*ADD reg,8*/
   1.551 -                        fetchea();
   1.552 -                        temp=geteab();        if (abrt) break;
   1.553 -                        setadd8(getr8(reg),temp);
   1.554 -                        setr8(reg,getr8(reg)+temp);
   1.555 -                        cycles -= (mod == 3) ? 2 : 7;
   1.556 -                        break;
   1.557 -                        case 0x03: /*ADD reg,16*/
   1.558 -                        fetchea();
   1.559 -                        tempw=geteaw();       if (abrt) break;
   1.560 -                        setadd16(regs[reg].w,tempw);
   1.561 -                        regs[reg].w+=tempw;
   1.562 -                        cycles -= (mod == 3) ? 2 : 7;
   1.563 -                        break;
   1.564 -                        case 0x04: /*ADD AL,#8*/
   1.565 -                        temp=getbytef();
   1.566 -                        setadd8(AL,temp);
   1.567 -                        AL+=temp;
   1.568 -                        cycles -= 3;
   1.569 -                        break;
   1.570 -                        case 0x05: /*ADD AX,#16*/
   1.571 -                        tempw=getwordf();
   1.572 -                        setadd16(AX,tempw);
   1.573 -                        AX+=tempw;
   1.574 -                        cycles -= 3;
   1.575 -                        break;
   1.576 -
   1.577 -                        case 0x06: /*PUSH ES*/
   1.578 -                        if (ssegs) ss=oldss;
   1.579 -                        writememw(ss,((SP-2)&0xFFFF),ES); if (abrt) break;
   1.580 -                        SP-=2;
   1.581 -                        cycles-=3;
   1.582 -                        break;
   1.583 -                        case 0x07: 
   1.584 -                        if (ssegs) ss=oldss;
   1.585 -                        tempw=readmemw(ss,SP);          if (abrt) break;
   1.586 -                        loadseg(tempw,&_es);            if (abrt) break;
   1.587 -                        SP+=2;
   1.588 -                        cycles -= (msw & 1) ? 20 : 5;
   1.589 -                        break;
   1.590 -
   1.591 -                        case 0x08: /*OR 8,reg*/
   1.592 -                        fetchea();
   1.593 -                        if (mod == 3)
   1.594 -                        {
   1.595 -                                temp  = getr8(rm) | getr8(reg);
   1.596 -                                setr8(rm, temp);
   1.597 -                                setznp8(temp);
   1.598 -                                cycles -= 2;
   1.599 -                        }
   1.600 -                        else
   1.601 -                        {
   1.602 -                                temp  = geteab();          if (abrt) break;
   1.603 -                                temp2 = getr8(reg);
   1.604 -                                seteab(temp | temp2);     if (abrt) break;
   1.605 -                                setznp8(temp | temp2);
   1.606 -                                cycles -= 7;
   1.607 -                        }
   1.608 -                        break;
   1.609 -                        case 0x09: /*OR 16,reg*/
   1.610 -                        fetchea();
   1.611 -                        if (mod == 3)
   1.612 -                        {
   1.613 -                                regs[rm].w |= regs[reg].w;
   1.614 -                                setznp16(regs[rm].w);
   1.615 -                                cycles -= 2;
   1.616 -                        }
   1.617 -                        else
   1.618 -                        {
   1.619 -                                tempw = geteaw() | regs[reg].w; if (abrt) break;
   1.620 -                                seteaw(tempw);                  if (abrt) break;
   1.621 -                                setznp16(tempw);
   1.622 -                                cycles -= 7;
   1.623 -                        }
   1.624 -                        break;
   1.625 -                        case 0x0A: /*OR reg,8*/
   1.626 -                        fetchea();
   1.627 -                        temp=geteab();          if (abrt) break;
   1.628 -                        temp|=getr8(reg);
   1.629 -                        setznp8(temp);
   1.630 -                        setr8(reg,temp);
   1.631 -                        cycles -= (mod == 3) ? 2 : 7;
   1.632 -                        break;
   1.633 -                        case 0x0B: /*OR reg,16*/
   1.634 -                        fetchea();
   1.635 -                        tempw=geteaw();         if (abrt) break;
   1.636 -                        tempw|=regs[reg].w;
   1.637 -                        setznp16(tempw);
   1.638 -                        regs[reg].w=tempw;
   1.639 -                        cycles -= (mod == 3) ? 2 : 7;
   1.640 -                        break;
   1.641 -                        case 0x0C: /*OR AL,#8*/
   1.642 -                        AL|=getbytef();
   1.643 -                        setznp8(AL);
   1.644 -                        cycles -= 2;
   1.645 -                        break;
   1.646 -                        case 0x0D: /*OR AX,#16*/
   1.647 -                        AX|=getwordf();
   1.648 -                        setznp16(AX);
   1.649 -                        cycles -= 2;
   1.650 -                        break;
   1.651 -
   1.652 -                        case 0x0E: /*PUSH CS*/
   1.653 -                        if (ssegs) ss=oldss;
   1.654 -                        writememw(ss,((SP-2)&0xFFFF),CS);       if (abrt) break;
   1.655 -                        SP-=2;
   1.656 -                        cycles-=3;
   1.657 -                        break;
   1.658 -
   1.659 -                        case 0x0F:
   1.660 -                        temp = readmemb(cs, pc); pc++;
   1.661 -                        opcode2 = temp;
   1.662 -//                        if (temp>5 && temp!=0x82 && temp!=0x85 && temp!=0x84 && temp!=0x87 && temp!=0x8D && temp!=0x8F && temp!=0x8C && temp!=0x20 && temp!=0x22) pclog("Using magic 386 0F instruction %02X!\n",temp);
   1.663 -                        switch (temp)
   1.664 -                        {
   1.665 -                                case 0:
   1.666 -                                fetchea(); if (abrt) break;
   1.667 -                                switch (rmdat&0x38)
   1.668 -                                {
   1.669 -                                        case 0x00: /*SLDT*/
   1.670 -                                        NOTRM
   1.671 -                                        seteaw(ldt.seg);
   1.672 -                                        cycles -= (mod == 3) ? 3 : 2;
   1.673 -                                        break;
   1.674 -                                        case 0x08: /*STR*/
   1.675 -                                        NOTRM
   1.676 -                                        seteaw(tr.seg);
   1.677 -                                        cycles -= (mod == 3) ? 3 : 2;
   1.678 -                                        break;
   1.679 -                                        case 0x10: /*LLDT*/
   1.680 -                                        if (CPL && (msw & 1))
   1.681 -                                        {
   1.682 -                                                pclog("Invalid LLDT!\n");
   1.683 -                                                x86gpf(NULL,0);
   1.684 -                                                break;
   1.685 -                                        }
   1.686 -                                        NOTRM
   1.687 -                                        ldt.seg=geteaw();
   1.688 -//                                        pclog("Load LDT %04X ",ldt.seg);
   1.689 -                                        templ=(ldt.seg&~7)+gdt.base;
   1.690 -//                                        pclog("%06X ",gdt.base);
   1.691 -                                        templ3=readmemw(0,templ)+((readmemb(0,templ+6)&0xF)<<16);
   1.692 -                                        templ2=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24);
   1.693 -                                        if (abrt) break;
   1.694 -                                        ldt.limit=templ3;
   1.695 -                                        ldt.access=readmemb(0,templ+6);
   1.696 -                                        if (readmemb(0,templ+6)&0x80)
   1.697 -                                        {
   1.698 -                                                ldt.limit<<=12;
   1.699 -                                                ldt.limit|=0xFFF;
   1.700 -                                        }
   1.701 -                                        ldt.base=templ2;
   1.702 -//                                        /*if (output==3) */pclog("LLDT %04X %08X %04X  %08X %08X\n",ldt.seg,ldt.base,ldt.limit,readmeml(0,templ),readmeml(0,templ+4));
   1.703 -
   1.704 -                                        cycles -= (mod == 3) ? 17 : 19;
   1.705 -                                        break;
   1.706 -                                        case 0x18: /*LTR*/
   1.707 -                                        if (CPL && (msw & 1))
   1.708 -                                        {
   1.709 -                                                pclog("Invalid LTR!\n");
   1.710 -                                                x86gpf(NULL,0);
   1.711 -                                                break;
   1.712 -                                        }
   1.713 -                                        NOTRM
   1.714 -                                        tr.seg=geteaw();
   1.715 -                                        templ=(tr.seg&~7)+gdt.base;
   1.716 -                                        templ3=readmemw(0,templ)+((readmemb(0,templ+6)&0xF)<<16);
   1.717 -                                        templ2=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24);
   1.718 -                                        temp=readmemb(0,templ+5);
   1.719 -                                        if (abrt) break;
   1.720 -                                        tr.limit=templ3;
   1.721 -                                        tr.access=readmemb(0,templ+6);
   1.722 -                                        if (readmemb(0,templ+6)&0x80)
   1.723 -                                        {
   1.724 -                                                tr.limit<<=12;
   1.725 -                                                tr.limit|=0xFFF;
   1.726 -                                        }
   1.727 -                                        tr.base=templ2;
   1.728 -//                                        pclog("TR base = %08X\n",templ2);
   1.729 -                                        tr.access=temp;
   1.730 -                                        cycles -= (mod == 3) ? 17 : 19;
   1.731 -                                        break;
   1.732 -                                        case 0x20: /*VERR*/
   1.733 -                                        NOTRM
   1.734 -                                        tempw=geteaw(); if (abrt) break;
   1.735 -                                        flags&=~Z_FLAG;
   1.736 -                                        if (!(tempw&0xFFFC)) break; /*Null selector*/
   1.737 -                                        cpl_override=1;
   1.738 -                                        tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit);
   1.739 -                                        tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4);
   1.740 -                                        cpl_override=0;
   1.741 -                                        if (abrt) break;
   1.742 -                                        if (!(tempw2&0x1000)) tempi=0;
   1.743 -                                        if ((tempw2&0xC00)!=0xC00) /*Exclude conforming code segments*/
   1.744 -                                        {
   1.745 -                                                tempw3=(tempw2>>13)&3; /*Check permissions*/
   1.746 -                                                if (tempw3<CPL || tempw3<(tempw&3)) tempi=0;
   1.747 -                                        }
   1.748 -                                        if ((tempw2&0x0800) && !(tempw2&0x0200)) tempi=0; /*Non-readable code*/
   1.749 -                                        if (tempi) flags|=Z_FLAG;
   1.750 -                                        cycles -= (mod == 3) ? 14 : 16;
   1.751 -                                        break;
   1.752 -                                        case 0x28: /*VERW*/
   1.753 -                                        NOTRM
   1.754 -                                        tempw=geteaw(); if (abrt) break;
   1.755 -                                        flags&=~Z_FLAG;
   1.756 -                                        if (!(tempw&0xFFFC)) break; /*Null selector*/
   1.757 -                                        cpl_override=1;
   1.758 -                                        tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit);
   1.759 -                                        tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4);
   1.760 -                                        cpl_override=0;
   1.761 -                                        if (abrt) break;
   1.762 -                                        if (!(tempw2&0x1000)) tempi=0;
   1.763 -                                        tempw3=(tempw2>>13)&3; /*Check permissions*/
   1.764 -                                        if (tempw3<CPL || tempw3<(tempw&3)) tempi=0;
   1.765 -                                        if (tempw2&0x0800) tempi=0; /*Code*/
   1.766 -                                        else if (!(tempw2&0x0200)) tempi=0; /*Read-only data*/
   1.767 -                                        if (tempi) flags|=Z_FLAG;
   1.768 -                                        cycles -= (mod == 3) ? 14 : 16;
   1.769 -                                        break;
   1.770 -
   1.771 -
   1.772 -                                        default:
   1.773 -                                        pclog("Bad 0F 00 opcode %02X\n",rmdat&0x38);
   1.774 -                                        pc-=3;
   1.775 -                                        x86illegal();
   1.776 -                                        break;
   1.777 -//                                        dumpregs();
   1.778 -//                                        exit(-1);
   1.779 -                                }
   1.780 -                                break;
   1.781 -                                case 1:
   1.782 -                                fetchea(); if (abrt) break;
   1.783 -                                switch (rmdat&0x38)
   1.784 -                                {
   1.785 -                                        case 0x00: /*SGDT*/
   1.786 -                                        seteaw(gdt.limit);
   1.787 -                                        writememw(easeg, eaaddr + 2, gdt.base);
   1.788 -                                        writememw(easeg, eaaddr + 4, (gdt.base >> 16) | 0xFF00);
   1.789 -                                        cycles -= 11;
   1.790 -                                        break;
   1.791 -                                        case 0x08: /*SIDT*/
   1.792 -                                        seteaw(idt.limit);
   1.793 -                                        writememw(easeg, eaaddr + 2, idt.base);
   1.794 -                                        writememw(easeg, eaaddr + 4, (idt.base >> 16) | 0xFF00);
   1.795 -                                        cycles -= 12;
   1.796 -                                        break;
   1.797 -                                        case 0x10: /*LGDT*/
   1.798 -                                        if (CPL && (msw & 1))
   1.799 -                                        {
   1.800 -                                                pclog("Invalid LGDT!\n");
   1.801 -                                                x86gpf(NULL,0);
   1.802 -                                                break;
   1.803 -                                        }
   1.804 -                                        tempw=geteaw();
   1.805 -                                        templ=readmeml(0,easeg+eaaddr+2)&0xFFFFFF;
   1.806 -                                        if (abrt) break;
   1.807 -                                        gdt.limit=tempw;
   1.808 -                                        gdt.base=templ;
   1.809 -                                        cycles-=11;
   1.810 -                                        break;
   1.811 -                                        case 0x18: /*LIDT*/
   1.812 -                                        if (CPL && (msw & 1))
   1.813 -                                        {
   1.814 -                                                pclog("Invalid LIDT!\n");
   1.815 -                                                x86gpf(NULL,0);
   1.816 -                                                break;
   1.817 -                                        }
   1.818 -                                        tempw=geteaw();
   1.819 -                                        templ=readmeml(0,easeg+eaaddr+2)&0xFFFFFF;
   1.820 -                                        if (abrt) break;
   1.821 -                                        idt.limit=tempw;
   1.822 -                                        idt.base=templ;
   1.823 -                                        cycles-=12;
   1.824 -                                        break;
   1.825 -
   1.826 -                                        case 0x20: /*SMSW*/
   1.827 -                                        if (is486) seteaw(msw);
   1.828 -                                        else       seteaw(msw|0xFF00);
   1.829 -//                                        pclog("SMSW %04X:%04X  %04X %i\n",CS,pc,msw,is486);
   1.830 -                                        cycles -= (mod == 3) ? 2 : 3;
   1.831 -                                        break;
   1.832 -                                        case 0x30: /*LMSW*/
   1.833 -                                        if (CPL && (msw&1))
   1.834 -                                        {
   1.835 -                                                pclog("LMSW - ring not zero!\n");
   1.836 -                                                x86gpf(NULL,0);
   1.837 -                                                break;
   1.838 -                                        }
   1.839 -                                        tempw=geteaw(); if (abrt) break;
   1.840 -                                        if (msw&1) tempw|=1;
   1.841 -                                        msw=tempw;
   1.842 -                                        cycles -= (mod == 3) ? 3 : 6;
   1.843 -                                        pclog("LMSW %04X %08X %04X:%04X\n", msw, cs, CS, pc);
   1.844 -                                        break;
   1.845 -
   1.846 -                                        default:
   1.847 -                                        pclog("Bad 0F 01 opcode %02X\n",rmdat&0x38);
   1.848 -                                        pc-=3;
   1.849 -                                        x86illegal();
   1.850 -                                        break;
   1.851 -//                                        dumpregs();
   1.852 -//                                        exit(-1);
   1.853 -                                }
   1.854 -                                break;
   1.855 -
   1.856 -                                case 2: /*LAR*/
   1.857 -                                NOTRM
   1.858 -                                fetchea();
   1.859 -                                tempw=geteaw(); if (abrt) break;
   1.860 -//                                pclog("LAR seg %04X\n",tempw);
   1.861 -                                
   1.862 -                                if (!(tempw&0xFFFC)) { flags&=~Z_FLAG; break; } /*Null selector*/
   1.863 -                                tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit);
   1.864 -                                if (tempi)
   1.865 -                                {
   1.866 -                                        cpl_override=1;
   1.867 -                                        tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4);
   1.868 -                                        cpl_override=0;
   1.869 -                                        if (abrt) break;
   1.870 -                                }
   1.871 -                                flags&=~Z_FLAG;
   1.872 -//                                pclog("tempw2 %04X  %i  %04X %04X\n",tempw2,tempi,ldt.limit,gdt.limit);
   1.873 -                                if ((tempw2&0x1F00)==0x000) tempi=0;
   1.874 -                                if ((tempw2&0x1F00)==0x800) tempi=0;
   1.875 -                                if ((tempw2&0x1F00)==0xA00) tempi=0;
   1.876 -                                if ((tempw2&0x1F00)==0xD00) tempi=0;
   1.877 -                                if ((tempw2&0x1C00)<0x1C00) /*Exclude conforming code segments*/
   1.878 -                                {
   1.879 -                                        tempw3=(tempw2>>13)&3;
   1.880 -                                        if (tempw3<CPL || tempw3<(tempw&3)) tempi=0;
   1.881 -                                }
   1.882 -                                if (tempi)
   1.883 -                                {
   1.884 -                                        flags|=Z_FLAG;
   1.885 -                                        cpl_override=1;
   1.886 -                                        regs[reg].w=readmemb(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+5)<<8;
   1.887 -                                        cpl_override=0;
   1.888 -                                }
   1.889 -                                cycles -= (mod == 3) ? 14 : 16;
   1.890 -                                break;
   1.891 -
   1.892 -                                case 3: /*LSL*/
   1.893 -                                NOTRM
   1.894 -                                fetchea();
   1.895 -                                tempw=geteaw(); if (abrt) break;
   1.896 -                                flags&=~Z_FLAG;
   1.897 -                                if (!(tempw&0xFFFC)) break; /*Null selector*/
   1.898 -                                tempi=(tempw&~7)<((tempw&4)?ldt.limit:gdt.limit);
   1.899 -                                cpl_override=1;
   1.900 -                                if (tempi)
   1.901 -                                {
   1.902 -                                        tempw2=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7)+4);
   1.903 -                                }
   1.904 -                                cpl_override=0;
   1.905 -                                if (abrt) break;
   1.906 -                                if ((tempw2&0x1400)==0x400) tempi=0; /*Interrupt or trap or call gate*/
   1.907 -                                if ((tempw2&0x1F00)==0x000) tempi=0; /*Invalid*/
   1.908 -                                if ((tempw2&0x1F00)==0xA00) tempi=0; /*Invalid*/
   1.909 -                                if ((tempw2&0x1C00)!=0x1C00) /*Exclude conforming code segments*/
   1.910 -                                {
   1.911 -                                        tempw3=(tempw2>>13)&3;
   1.912 -                                        if (tempw3<CPL || tempw3<(tempw&3)) tempi=0;
   1.913 -                                }
   1.914 -                                if (tempi)
   1.915 -                                {
   1.916 -                                        flags|=Z_FLAG;
   1.917 -                                        cpl_override=1;
   1.918 -                                        regs[reg].w=readmemw(0,((tempw&4)?ldt.base:gdt.base)+(tempw&~7));
   1.919 -                                        cpl_override=0;
   1.920 -                                }
   1.921 -                                cycles -= (mod == 3) ? 14 : 16;
   1.922 -                                break;
   1.923 -
   1.924 -                                case 5: /*LOADALL*/
   1.925 -//                                pclog("At %04X:%04X  ",CS,pc);
   1.926 -                                flags=(readmemw(0,0x818)&0xFFD5)|2;
   1.927 -                                pc=readmemw(0,0x81A);
   1.928 -                                DS=readmemw(0,0x81E);
   1.929 -                                SS=readmemw(0,0x820);
   1.930 -                                CS=readmemw(0,0x822);
   1.931 -                                ES=readmemw(0,0x824);
   1.932 -                                DI=readmemw(0,0x826);
   1.933 -                                SI=readmemw(0,0x828);
   1.934 -                                BP=readmemw(0,0x82A);
   1.935 -                                SP=readmemw(0,0x82C);
   1.936 -                                BX=readmemw(0,0x82E);
   1.937 -                                DX=readmemw(0,0x830);
   1.938 -                                CX=readmemw(0,0x832);
   1.939 -                                AX=readmemw(0,0x834);
   1.940 -                                /*if (readmemw(0,0x806))
   1.941 -                                {
   1.942 -                                        pclog("Something in LOADALL!\n");
   1.943 -                                        dumpregs();
   1.944 -                                        exit(-1);
   1.945 -                                }*/
   1.946 -                                es=readmemw(0,0x836)|(readmemb(0,0x838)<<16);
   1.947 -                                cs=readmemw(0,0x83C)|(readmemb(0,0x83E)<<16);
   1.948 -                                ss=readmemw(0,0x842)|(readmemb(0,0x844)<<16);
   1.949 -                                ds=readmemw(0,0x848)|(readmemb(0,0x84A)<<16);
   1.950 -                                cycles-=195;
   1.951 -//                                pclog("LOADALL - %06X:%04X %06X:%04X %04X\n",ds,SI,es,DI,DX);
   1.952 -                                break;
   1.953 -                                
   1.954 -                                case 6: /*CLTS*/
   1.955 -                                if (CPL && (msw & 1))
   1.956 -                                {
   1.957 -                                        pclog("Can't CLTS\n");
   1.958 -                                        x86gpf(NULL,0);
   1.959 -                                        break;
   1.960 -                                }
   1.961 -                                msw &= ~8;
   1.962 -                                cycles-=2;
   1.963 -                                break;
   1.964 -                                
   1.965 -                                case 0xFF: /*Invalid - Windows 3.1 syscall trap?*/
   1.966 -                                inv16:
   1.967 -                                pc-=2;
   1.968 -                                if (msw&1)
   1.969 -                                {
   1.970 -                                        pmodeint(6,0);
   1.971 -                                }
   1.972 -                                else
   1.973 -                                {
   1.974 -                                        if (ssegs) ss=oldss;
   1.975 -                                        writememw(ss,((SP-2)&0xFFFF),flags);
   1.976 -                                        writememw(ss,((SP-4)&0xFFFF),CS);
   1.977 -                                        writememw(ss,((SP-6)&0xFFFF),pc);
   1.978 -                                        SP-=6;
   1.979 -                                        addr=6<<2;
   1.980 -                                        flags&=~I_FLAG;
   1.981 -                                        flags&=~T_FLAG;
   1.982 -                                        oxpc=pc;
   1.983 -                                        pc=readmemw(0,addr);
   1.984 -                                        loadcs(readmemw(0,addr+2));
   1.985 -/*                                        if (!pc && !cs)
   1.986 -                                        {
   1.987 -                                                pclog("Bad int %02X %04X:%04X\n",temp,oldcs,oldpc);
   1.988 -                                                dumpregs();
   1.989 -                                                exit(-1);
   1.990 -                                        }*/
   1.991 -                                }
   1.992 -                                cycles-=23;
   1.993 -                                break;
   1.994 -
   1.995 -                                default:
   1.996 -                                pclog("Bad 16-bit 0F opcode %02X 386 %i\n",temp,ins);
   1.997 -                                pc=oldpc;
   1.998 -//                                output=3;
   1.999 -//                                timetolive=100000;
  1.1000 -//                                dumpregs();
  1.1001 -//                                exit(-1);
  1.1002 -                                x86illegal();
  1.1003 -                                break;
  1.1004 -                        }
  1.1005 -                        break;
  1.1006 -
  1.1007 -                        case 0x10: /*ADC 8,reg*/
  1.1008 -                        fetchea();
  1.1009 -                        if (mod == 3)
  1.1010 -                        {
  1.1011 -                                temp  = getr8(rm);
  1.1012 -                                temp2 = getr8(reg);
  1.1013 -                                setadc8(temp, temp2);
  1.1014 -                                setr8(rm, temp + temp2 + tempc);
  1.1015 -                                cycles -= 2;
  1.1016 -                        }
  1.1017 -                        else
  1.1018 -                        {
  1.1019 -                                temp  = geteab();               if (abrt) break;
  1.1020 -                                temp2 = getr8(reg);
  1.1021 -                                seteab(temp + temp2 + tempc);   if (abrt) break;
  1.1022 -                                setadc8(temp, temp2);
  1.1023 -                                cycles -= 7;
  1.1024 -                        }
  1.1025 -                        break;
  1.1026 -                        case 0x11: /*ADC 16,reg*/
  1.1027 -                        fetchea();
  1.1028 -                        if (mod == 3)
  1.1029 -                        {
  1.1030 -                                setadc16(regs[rm].w, regs[reg].w);
  1.1031 -                                regs[rm].w += regs[reg].w + tempc;
  1.1032 -                                cycles -= 2;
  1.1033 -                        }
  1.1034 -                        else
  1.1035 -                        {
  1.1036 -                                tempw  = geteaw();              if (abrt) break;
  1.1037 -                                tempw2 = regs[reg].w;
  1.1038 -                                seteaw(tempw + tempw2 + tempc); if (abrt) break;
  1.1039 -                                setadc16(tempw, tempw2);
  1.1040 -                                cycles -= 7;
  1.1041 -                        }
  1.1042 -                        break;
  1.1043 -                        case 0x12: /*ADC reg,8*/
  1.1044 -                        fetchea();
  1.1045 -                        temp=geteab();                  if (abrt) break;
  1.1046 -                        setadc8(getr8(reg),temp);
  1.1047 -                        setr8(reg,getr8(reg)+temp+tempc);
  1.1048 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1049 -                        break;
  1.1050 -                        case 0x13: /*ADC reg,16*/
  1.1051 -                        fetchea();
  1.1052 -                        tempw=geteaw();                 if (abrt) break;
  1.1053 -                        setadc16(regs[reg].w,tempw);
  1.1054 -                        regs[reg].w+=tempw+tempc;
  1.1055 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1056 -                        break;
  1.1057 -                        case 0x14: /*ADC AL,#8*/
  1.1058 -                        tempw=getbytef();
  1.1059 -                        setadc8(AL,tempw);
  1.1060 -                        AL+=tempw+tempc;
  1.1061 -                        cycles -= 3;
  1.1062 -                        break;
  1.1063 -                        case 0x15: /*ADC AX,#16*/
  1.1064 -                        tempw=getwordf();
  1.1065 -                        setadc16(AX,tempw);
  1.1066 -                        AX+=tempw+tempc;
  1.1067 -                        cycles -= 3;
  1.1068 -                        break;
  1.1069 -
  1.1070 -                        case 0x16: /*PUSH SS*/
  1.1071 -                        if (ssegs) ss=oldss;
  1.1072 -                        writememw(ss,((SP-2)&0xFFFF),SS); if (abrt) break;
  1.1073 -                        SP-=2;
  1.1074 -                        cycles-=3;
  1.1075 -                        break;
  1.1076 -                        case 0x17: /*POP SS*/
  1.1077 -                        if (ssegs) ss=oldss;
  1.1078 -                        tempw=readmemw(ss,SP);  if (abrt) break;
  1.1079 -                        loadseg(tempw,&_ss); if (abrt) break;
  1.1080 -                        SP += 2;
  1.1081 -                        cycles -= (msw & 1) ? 20 : 5;
  1.1082 -                        break;
  1.1083 -
  1.1084 -                        case 0x18: /*SBB 8,reg*/
  1.1085 -                        fetchea();
  1.1086 -                        if (mod == 3)
  1.1087 -                        {
  1.1088 -                                temp  = getr8(rm);
  1.1089 -                                temp2 = getr8(reg);
  1.1090 -                                setsbc8(temp, temp2);
  1.1091 -                                setr8(rm, temp - (temp2 + tempc));
  1.1092 -                                cycles -= 2;
  1.1093 -                        }
  1.1094 -                        else
  1.1095 -                        {
  1.1096 -                                temp  = geteab();                  if (abrt) break;
  1.1097 -                                temp2 = getr8(reg);
  1.1098 -                                seteab(temp - (temp2 + tempc));    if (abrt) break;
  1.1099 -                                setsbc8(temp, temp2);
  1.1100 -                                cycles -= 7;
  1.1101 -                        }
  1.1102 -                        break;
  1.1103 -                        case 0x19: /*SBB 16,reg*/
  1.1104 -                        fetchea();
  1.1105 -                        if (mod == 3)
  1.1106 -                        {
  1.1107 -                                setsbc16(regs[rm].w, regs[reg].w);
  1.1108 -                                regs[rm].w -= (regs[reg].w + tempc);
  1.1109 -                                cycles -= 2;
  1.1110 -                        }
  1.1111 -                        else
  1.1112 -                        {
  1.1113 -                                tempw  = geteaw();                 if (abrt) break;
  1.1114 -                                tempw2 = regs[reg].w;
  1.1115 -                                seteaw(tempw - (tempw2 + tempc));  if (abrt) break;
  1.1116 -                                setsbc16(tempw, tempw2);
  1.1117 -                                cycles -= 7;
  1.1118 -                        }
  1.1119 -                        break;
  1.1120 -                        case 0x1A: /*SBB reg,8*/
  1.1121 -                        fetchea();
  1.1122 -                        temp=geteab();                  if (abrt) break;
  1.1123 -                        setsbc8(getr8(reg),temp);
  1.1124 -                        setr8(reg,getr8(reg)-(temp+tempc));
  1.1125 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1126 -                        break;
  1.1127 -                        case 0x1B: /*SBB reg,16*/
  1.1128 -                        fetchea();
  1.1129 -                        tempw=geteaw();                 if (abrt) break;
  1.1130 -                        tempw2=regs[reg].w;
  1.1131 -                        setsbc16(tempw2,tempw);
  1.1132 -                        tempw2-=(tempw+tempc);
  1.1133 -                        regs[reg].w=tempw2;
  1.1134 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1135 -                        break;
  1.1136 -                        case 0x1C: /*SBB AL,#8*/
  1.1137 -                        temp=getbytef();
  1.1138 -                        setsbc8(AL,temp);
  1.1139 -                        AL-=(temp+tempc);
  1.1140 -                        cycles -= 3;
  1.1141 -                        break;
  1.1142 -                        case 0x1D: /*SBB AX,#16*/
  1.1143 -                        tempw=getwordf();
  1.1144 -                        setsbc16(AX,tempw);
  1.1145 -                        AX-=(tempw+tempc);
  1.1146 -                        cycles -= 3;
  1.1147 -                        break;
  1.1148 -
  1.1149 -                        case 0x1E: /*PUSH DS*/
  1.1150 -                        if (ssegs) ss=oldss;
  1.1151 -                        writememw(ss,((SP-2)&0xFFFF),DS);       if (abrt) break;
  1.1152 -                        SP-=2;
  1.1153 -                        cycles-=3;
  1.1154 -                        break;
  1.1155 -                        case 0x1F: case 0x21F: /*POP DS*/
  1.1156 -                        if (ssegs) ss=oldss;
  1.1157 -                        tempw=readmemw(ss,SP);                  if (abrt) break;
  1.1158 -                        loadseg(tempw,&_ds); if (abrt) break;
  1.1159 -                        SP+=2;
  1.1160 -                        cycles -= (msw & 1) ? 20 : 5;
  1.1161 -                        break;
  1.1162 -
  1.1163 -                        case 0x20: /*AND 8,reg*/
  1.1164 -                        fetchea();
  1.1165 -                        if (mod == 3)
  1.1166 -                        {
  1.1167 -                                temp  = getr8(rm) & getr8(reg);
  1.1168 -                                setr8(rm, temp);
  1.1169 -                                setznp8(temp);
  1.1170 -                                cycles -= 2;
  1.1171 -                        }
  1.1172 -                        else
  1.1173 -                        {
  1.1174 -                                temp  = geteab();    if (abrt) break;
  1.1175 -                                temp &= getr8(reg);
  1.1176 -                                seteab(temp);        if (abrt) break;
  1.1177 -                                setznp8(temp);
  1.1178 -                                cycles -= 7;
  1.1179 -                        }
  1.1180 -                        break;
  1.1181 -                        case 0x21: /*AND 16,reg*/
  1.1182 -                        fetchea();
  1.1183 -                        if (mod == 3)
  1.1184 -                        {
  1.1185 -                                regs[rm].w &= regs[reg].w;
  1.1186 -                                setznp16(regs[rm].w);
  1.1187 -                                cycles -= 2;
  1.1188 -                        }
  1.1189 -                        else
  1.1190 -                        {
  1.1191 -                                tempw = geteaw() & regs[reg].w; if (abrt) break;
  1.1192 -                                seteaw(tempw);                  if (abrt) break;
  1.1193 -                                setznp16(tempw);
  1.1194 -                                cycles -= 7;
  1.1195 -                        }
  1.1196 -                        break;
  1.1197 -                        case 0x22: /*AND reg,8*/
  1.1198 -                        fetchea();
  1.1199 -                        temp=geteab();          if (abrt) break;
  1.1200 -                        temp&=getr8(reg);
  1.1201 -                        setznp8(temp);
  1.1202 -                        setr8(reg,temp);
  1.1203 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1204 -                        break;
  1.1205 -                        case 0x23: /*AND reg,16*/
  1.1206 -                        fetchea();
  1.1207 -                        tempw=geteaw();         if (abrt) break;
  1.1208 -                        tempw&=regs[reg].w;
  1.1209 -                        setznp16(tempw);
  1.1210 -                        regs[reg].w=tempw;
  1.1211 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1212 -                        break;
  1.1213 -                        case 0x24: /*AND AL,#8*/
  1.1214 -                        AL&=getbytef();
  1.1215 -                        setznp8(AL);
  1.1216 -                        cycles -= 3;
  1.1217 -                        break;
  1.1218 -                        case 0x25: /*AND AX,#16*/
  1.1219 -                        AX&=getwordf();
  1.1220 -                        setznp16(AX);
  1.1221 -                        cycles -= 3;
  1.1222 -                        break;
  1.1223 -
  1.1224 -                        case 0x26: /*ES:*/
  1.1225 -                        oldss=ss;
  1.1226 -                        oldds=ds;
  1.1227 -                        ds=ss=es;
  1.1228 -                        rds=ES;
  1.1229 -                        ssegs=2;
  1.1230 -                        cycles-=2;
  1.1231 -                        goto opcodestart;
  1.1232 -//                        break;
  1.1233 -
  1.1234 -                        case 0x27: /*DAA*/
  1.1235 -                        if ((flags & A_FLAG) || ((AL & 0xF) > 9))
  1.1236 -                        {
  1.1237 -                                tempi = ((uint16_t)AL) + 6;
  1.1238 -                                AL += 6;
  1.1239 -                                flags |= A_FLAG;
  1.1240 -                                if (tempi & 0x100) flags |= C_FLAG;
  1.1241 -                        }
  1.1242 -                        if ((flags&C_FLAG) || (AL>0x9F))
  1.1243 -                        {
  1.1244 -                                AL+=0x60;
  1.1245 -                                flags|=C_FLAG;
  1.1246 -                        }
  1.1247 -                        tempw = flags & (C_FLAG | A_FLAG);
  1.1248 -                        setznp8(AL);
  1.1249 -                        flags |= tempw;
  1.1250 -                        cycles -= 3;
  1.1251 -                        break;
  1.1252 -
  1.1253 -                        case 0x28: /*SUB 8,reg*/
  1.1254 -                        fetchea();
  1.1255 -                        if (mod == 3)
  1.1256 -                        {
  1.1257 -                                temp  = getr8(rm);
  1.1258 -                                temp2 = getr8(reg);
  1.1259 -                                setsub8(temp, temp2);
  1.1260 -                                setr8(rm, temp - temp2);
  1.1261 -                                cycles -= 2;
  1.1262 -                        }
  1.1263 -                        else
  1.1264 -                        {
  1.1265 -                                temp  = geteab();     if (abrt) break;
  1.1266 -                                temp2 = getr8(reg);
  1.1267 -                                seteab(temp - temp2); if (abrt) break;
  1.1268 -                                setsub8(temp, temp2);
  1.1269 -                                cycles -= 7;
  1.1270 -                        }
  1.1271 -                        break;
  1.1272 -                        case 0x29: /*SUB 16,reg*/
  1.1273 -                        fetchea();
  1.1274 -                        if (mod == 3)
  1.1275 -                        {
  1.1276 -                                setsub16(regs[rm].w, regs[reg].w);
  1.1277 -                                regs[rm].w -= regs[reg].w;
  1.1278 -                                cycles -= 2;
  1.1279 -                        }
  1.1280 -                        else
  1.1281 -                        {
  1.1282 -                                tempw = geteaw();             if (abrt) break;
  1.1283 -                                seteaw(tempw - regs[reg].w);  if (abrt) break;
  1.1284 -                                setsub16(tempw, regs[reg].w);
  1.1285 -                                cycles -= 7;
  1.1286 -                        }
  1.1287 -                        break;
  1.1288 -                        case 0x2A: /*SUB reg,8*/
  1.1289 -                        fetchea();
  1.1290 -                        temp=geteab();          if (abrt) break;
  1.1291 -                        setsub8(getr8(reg),temp);
  1.1292 -                        setr8(reg,getr8(reg)-temp);
  1.1293 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1294 -                        break;
  1.1295 -                        case 0x2B: /*SUB reg,16*/
  1.1296 -                        fetchea();
  1.1297 -                        tempw=geteaw();         if (abrt) break;
  1.1298 -                        setsub16(regs[reg].w,tempw);
  1.1299 -                        regs[reg].w-=tempw;
  1.1300 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1301 -                        break;
  1.1302 -                        case 0x2C: /*SUB AL,#8*/
  1.1303 -                        temp=getbytef();
  1.1304 -                        setsub8(AL,temp);
  1.1305 -                        AL-=temp;
  1.1306 -                        cycles -= 3;
  1.1307 -                        break;
  1.1308 -                        case 0x2D: /*SUB AX,#16*/
  1.1309 -                        tempw=getwordf();
  1.1310 -                        setsub16(AX,tempw);
  1.1311 -                        AX-=tempw;
  1.1312 -                        cycles -= 3;
  1.1313 -                        break;
  1.1314 -
  1.1315 -                        case 0x2E: /*CS:*/
  1.1316 -                        oldss=ss;
  1.1317 -                        oldds=ds;
  1.1318 -                        ds=ss=cs;
  1.1319 -                        rds=CS;
  1.1320 -                        ssegs=2;
  1.1321 -                        cycles-=2;
  1.1322 -                        goto opcodestart;
  1.1323 -                        
  1.1324 -                        case 0x2F: /*DAS*/
  1.1325 -                        if ((flags&A_FLAG)||((AL&0xF)>9))
  1.1326 -                        {
  1.1327 -                                tempi=((uint16_t)AL)-6;
  1.1328 -                                AL-=6;
  1.1329 -                                flags|=A_FLAG;
  1.1330 -                                if (tempi&0x100) flags|=C_FLAG;
  1.1331 -                        }
  1.1332 -//                        else
  1.1333 -//                           flags&=~A_FLAG;
  1.1334 -                        if ((flags&C_FLAG)||(AL>0x9F))
  1.1335 -                        {
  1.1336 -                                AL-=0x60;
  1.1337 -                                flags|=C_FLAG;
  1.1338 -                        }
  1.1339 -//                        else
  1.1340 -//                           flags&=~C_FLAG;
  1.1341 -                        tempw = flags & (C_FLAG | A_FLAG);
  1.1342 -                        setznp8(AL);
  1.1343 -                        flags |= tempw;
  1.1344 -                        cycles -= 3;
  1.1345 -                        break;
  1.1346 -
  1.1347 -                        case 0x30: /*XOR 8,reg*/
  1.1348 -                        fetchea();
  1.1349 -                        if (mod == 3)
  1.1350 -                        {
  1.1351 -                                temp = getr8(rm) ^ getr8(reg);
  1.1352 -                                setr8(rm, temp);
  1.1353 -                                setznp8(temp);
  1.1354 -                                cycles -= 2;
  1.1355 -                        }
  1.1356 -                        else
  1.1357 -                        {
  1.1358 -                                temp  = geteab();    if (abrt) break;
  1.1359 -                                temp ^= getr8(reg);
  1.1360 -                                seteab(temp);        if (abrt) break;
  1.1361 -                                setznp8(temp);
  1.1362 -                                cycles -= 7;
  1.1363 -                        }
  1.1364 -                        break;
  1.1365 -                        case 0x31: /*XOR 16,reg*/
  1.1366 -                        fetchea();
  1.1367 -                        if (mod == 3)
  1.1368 -                        {
  1.1369 -                                regs[rm].w ^= regs[reg].w;
  1.1370 -                                setznp16(regs[rm].w);
  1.1371 -                                cycles -= 2;
  1.1372 -                        }
  1.1373 -                        else
  1.1374 -                        {
  1.1375 -                                tempw = geteaw() ^ regs[reg].w; if (abrt) break;
  1.1376 -                                seteaw(tempw);                  if (abrt) break;
  1.1377 -                                setznp16(tempw);
  1.1378 -                                cycles -= 7;
  1.1379 -                        }
  1.1380 -                        break;
  1.1381 -                        case 0x32: /*XOR reg,8*/
  1.1382 -                        fetchea();
  1.1383 -                        temp=geteab();          if (abrt) break;
  1.1384 -                        temp^=getr8(reg);
  1.1385 -                        setznp8(temp);
  1.1386 -                        setr8(reg,temp);
  1.1387 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1388 -                        break;
  1.1389 -                        case 0x33: /*XOR reg,16*/
  1.1390 -                        fetchea();
  1.1391 -                        tempw=geteaw();         if (abrt) break;
  1.1392 -                        tempw^=regs[reg].w;
  1.1393 -                        setznp16(tempw);
  1.1394 -                        regs[reg].w=tempw;
  1.1395 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1396 -                        break;
  1.1397 -                        case 0x34: /*XOR AL,#8*/
  1.1398 -                        AL^=getbytef();
  1.1399 -                        setznp8(AL);
  1.1400 -                        cycles -= 3;
  1.1401 -                        break;
  1.1402 -                        case 0x35: /*XOR AX,#16*/
  1.1403 -                        AX^=getwordf();
  1.1404 -                        setznp16(AX);
  1.1405 -                        cycles -= 3;
  1.1406 -                        break;
  1.1407 -
  1.1408 -                        case 0x36: /*SS:*/
  1.1409 -                        oldss=ss;
  1.1410 -                        oldds=ds;
  1.1411 -                        ds=ss=ss;
  1.1412 -                        rds=SS;
  1.1413 -                        ssegs=2;
  1.1414 -                        cycles-=2;
  1.1415 -                        goto opcodestart;
  1.1416 -//                        break;
  1.1417 -
  1.1418 -                        case 0x37: /*AAA*/
  1.1419 -                        if ((flags&A_FLAG)||((AL&0xF)>9))
  1.1420 -                        {
  1.1421 -                                AL+=6;
  1.1422 -                                AH++;
  1.1423 -                                flags|=(A_FLAG|C_FLAG);
  1.1424 -                        }
  1.1425 -                        else
  1.1426 -                           flags&=~(A_FLAG|C_FLAG);
  1.1427 -                        AL&=0xF;
  1.1428 -                        cycles -= 3;
  1.1429 -                        break;
  1.1430 -
  1.1431 -                        case 0x38: /*CMP 8,reg*/
  1.1432 -                        fetchea();
  1.1433 -                        temp=geteab();          if (abrt) break;
  1.1434 -                        setsub8(temp,getr8(reg));
  1.1435 -                        cycles -= (mod == 3) ? 2 : 7;
  1.1436 -                        break;
  1.1437 -                        case 0x39: /*CMP 16,reg*/
  1.1438 -                        fetchea();
  1.1439 -                        tempw=geteaw();         if (abrt) break;
  1.1440 -//                        if (output) pclog("CMP %04X %04X\n",tempw,regs[reg].w);
  1.1441 -                        setsub16(tempw,regs[reg].w);
  1.1442 -                        cycles -= (mod == 3) ? 2 : 7;                        
  1.1443 -                        break;
  1.1444 -                        case 0x3A: /*CMP reg,8*/
  1.1445 -                        fetchea();
  1.1446 -                        temp=geteab();          if (abrt) break;
  1.1447 -//                        if (output) pclog("CMP %02X-%02X\n",getr8(reg),temp);
  1.1448 -                        setsub8(getr8(reg),temp);
  1.1449 -                        cycles -= (mod == 3) ? 2 : 6;
  1.1450 -                        break;
  1.1451 -                        case 0x3B: /*CMP reg,16*/
  1.1452 -                        fetchea();
  1.1453 -                        tempw=geteaw();         if (abrt) break;
  1.1454 -                        setsub16(regs[reg].w,tempw);
  1.1455 -                        cycles -= (mod == 3) ? 2 : 6;
  1.1456 -                        break;
  1.1457 -                        case 0x3C: /*CMP AL,#8*/
  1.1458 -                        temp=getbytef();
  1.1459 -                        setsub8(AL,temp);
  1.1460 -                        cycles -= 3;
  1.1461 -                        break;
  1.1462 -                        case 0x3D: /*CMP AX,#16*/
  1.1463 -                        tempw=getwordf();
  1.1464 -                        setsub16(AX,tempw);
  1.1465 -                        cycles -= 3;
  1.1466 -                        break;
  1.1467 -
  1.1468 -                        case 0x3E: /*DS:*/
  1.1469 -                        oldss=ss;
  1.1470 -                        oldds=ds;
  1.1471 -                        ds=ss=ds;
  1.1472 -                        ssegs=2;
  1.1473 -                        cycles-=2;
  1.1474 -                        goto opcodestart;
  1.1475 -//                        break;
  1.1476 -
  1.1477 -                        case 0x3F: /*AAS*/
  1.1478 -                        if ((flags&A_FLAG)||((AL&0xF)>9))
  1.1479 -                        {
  1.1480 -                                AL-=6;
  1.1481 -                                AH--;
  1.1482 -                                flags|=(A_FLAG|C_FLAG);
  1.1483 -                        }
  1.1484 -                        else
  1.1485 -                           flags&=~(A_FLAG|C_FLAG);
  1.1486 -                        AL&=0xF;
  1.1487 -                        cycles -= 3;
  1.1488 -                        break;
  1.1489 -
  1.1490 -                        case 0x40: case 0x41: case 0x42: case 0x43: /*INC r16*/
  1.1491 -                        case 0x44: case 0x45: case 0x46: case 0x47:
  1.1492 -                        setadd16nc(regs[opcode&7].w,1);
  1.1493 -                        regs[opcode&7].w++;
  1.1494 -                        cycles -= 2;
  1.1495 -                        break;
  1.1496 -                        case 0x48: case 0x49: case 0x4A: case 0x4B: /*DEC r16*/
  1.1497 -                        case 0x4C: case 0x4D: case 0x4E: case 0x4F:
  1.1498 -                        setsub16nc(regs[opcode&7].w,1);
  1.1499 -                        regs[opcode&7].w--;
  1.1500 -                        cycles -= 2;
  1.1501 -                        break;
  1.1502 -
  1.1503 -                        case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/
  1.1504 -                        case 0x54: case 0x55: case 0x56: case 0x57:
  1.1505 -                        if (ssegs) ss=oldss;
  1.1506 -                        writememw(ss,(SP-2)&0xFFFF,regs[opcode&7].w);   if (abrt) break;
  1.1507 -                        SP-=2;
  1.1508 -                        cycles -= 3;
  1.1509 -                        break;
  1.1510 -                        case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/
  1.1511 -                        case 0x5C: case 0x5D: case 0x5E: case 0x5F:
  1.1512 -                        if (ssegs) ss=oldss;
  1.1513 -                        SP+=2;
  1.1514 -                        tempw=readmemw(ss,(SP-2)&0xFFFF);    if (abrt) { SP-=2; break; }
  1.1515 -                        regs[opcode&7].w=tempw;
  1.1516 -                        cycles -= 5;
  1.1517 -                        break;
  1.1518 -
  1.1519 -                        case 0x60: /*PUSHA*/
  1.1520 -                        writememw(ss,((SP-2)&0xFFFF),AX);
  1.1521 -                        writememw(ss,((SP-4)&0xFFFF),CX);
  1.1522 -                        writememw(ss,((SP-6)&0xFFFF),DX);
  1.1523 -                        writememw(ss,((SP-8)&0xFFFF),BX);
  1.1524 -                        writememw(ss,((SP-10)&0xFFFF),SP);
  1.1525 -                        writememw(ss,((SP-12)&0xFFFF),BP);
  1.1526 -                        writememw(ss,((SP-14)&0xFFFF),SI);
  1.1527 -                        writememw(ss,((SP-16)&0xFFFF),DI);
  1.1528 -                        if (!abrt) SP-=16;
  1.1529 -                        cycles -= 17;
  1.1530 -                        break;
  1.1531 -                        case 0x61: /*POPA*/
  1.1532 -                        DI=readmemw(ss,((SP)&0xFFFF));          if (abrt) break;
  1.1533 -                        SI=readmemw(ss,((SP+2)&0xFFFF));        if (abrt) break;
  1.1534 -                        BP=readmemw(ss,((SP+4)&0xFFFF));        if (abrt) break;
  1.1535 -                        BX=readmemw(ss,((SP+8)&0xFFFF));        if (abrt) break;
  1.1536 -                        DX=readmemw(ss,((SP+10)&0xFFFF));       if (abrt) break;
  1.1537 -                        CX=readmemw(ss,((SP+12)&0xFFFF));       if (abrt) break;
  1.1538 -                        AX=readmemw(ss,((SP+14)&0xFFFF));       if (abrt) break;
  1.1539 -                        SP+=16;
  1.1540 -                        cycles -= 19;
  1.1541 -                        break;
  1.1542 -
  1.1543 -                        case 0x62: /*BOUND*/
  1.1544 -                        fetchea();
  1.1545 -                        tempw=geteaw();
  1.1546 -                        tempw2=readmemw(easeg,eaaddr+2); if (abrt) break;
  1.1547 -                        if (((int16_t)regs[reg].w<(int16_t)tempw) || ((int16_t)regs[reg].w>(int16_t)tempw2))
  1.1548 -                        {
  1.1549 -                                x86_int(5);
  1.1550 -                        }
  1.1551 -                        cycles -= 13;
  1.1552 -                        break;
  1.1553 -                        
  1.1554 -                        case 0x63: /*ARPL*/
  1.1555 -                        NOTRM
  1.1556 -                        fetchea();
  1.1557 -                        tempw=geteaw(); if (abrt) break;
  1.1558 -                        if ((tempw&3)<(regs[reg].w&3))
  1.1559 -                        {
  1.1560 -                                tempw=(tempw&0xFFFC)|(regs[reg].w&3);
  1.1561 -                                seteaw(tempw); if (abrt) break;
  1.1562 -                                flags|=Z_FLAG;
  1.1563 -                        }
  1.1564 -                        else
  1.1565 -                           flags&=~Z_FLAG;
  1.1566 -                        cycles -= (mod == 3) ? 10 : 11;
  1.1567 -                        break;
  1.1568 -
  1.1569 -                        case 0x68: /*PUSH #w*/
  1.1570 -                        tempw=getword();
  1.1571 -                        writememw(ss,((SP-2)&0xFFFF),tempw);    if (abrt) break;
  1.1572 -                        SP-=2;
  1.1573 -                        cycles -= 3;
  1.1574 -                        break;
  1.1575 -                        case 0x69: /*IMUL r16*/
  1.1576 -                        fetchea();
  1.1577 -                        tempw=geteaw();         if (abrt) break;
  1.1578 -                        tempw2=getword();       if (abrt) break;
  1.1579 -                        templ=((int)(int16_t)tempw)*((int)(int16_t)tempw2);
  1.1580 -                        if ((templ>>16)!=0 && (templ>>16)!=0xFFFF) flags|=C_FLAG|V_FLAG;
  1.1581 -                        else                                       flags&=~(C_FLAG|V_FLAG);
  1.1582 -                        regs[reg].w=templ&0xFFFF;
  1.1583 -                        cycles -= (mod == 3) ? 21 : 24;
  1.1584 -                        break;
  1.1585 -                        case 0x6A: /*PUSH #eb*/
  1.1586 -                        tempw=readmemb(cs,pc); pc++;
  1.1587 -                        if (tempw&0x80) tempw|=0xFF00;
  1.1588 -                        writememw(ss,((SP-2)&0xFFFF),tempw);    if (abrt) break;
  1.1589 -                        SP-=2;
  1.1590 -                        cycles -= 3;
  1.1591 -                        break;
  1.1592 -                        case 0x6B: /*IMUL r8*/
  1.1593 -                        fetchea();
  1.1594 -                        tempw=geteaw();                 if (abrt) break;
  1.1595 -                        tempw2=readmemb(cs,pc); pc++;   if (abrt) break;
  1.1596 -                        if (tempw2&0x80) tempw2|=0xFF00;
  1.1597 -                        templ=((int)(int16_t)tempw)*((int)(int16_t)tempw2);
  1.1598 -                        if ((templ>>16)!=0 && ((templ>>16)&0xFFFF)!=0xFFFF) flags|=C_FLAG|V_FLAG;
  1.1599 -                        else                                                flags&=~(C_FLAG|V_FLAG);
  1.1600 -                        regs[reg].w=templ&0xFFFF;
  1.1601 -                        cycles -= (mod == 3) ? 21 : 24;
  1.1602 -                        break;
  1.1603 -
  1.1604 -                        case 0x6C: /*INSB*/
  1.1605 -                        checkio_perm(DX);
  1.1606 -                        temp=inb(DX);
  1.1607 -                        writememb(es,DI,temp);          if (abrt) break;
  1.1608 -                        if (flags&D_FLAG) DI--;
  1.1609 -                        else              DI++;
  1.1610 -                        cycles -= 5;
  1.1611 -                        break;
  1.1612 -                        case 0x6D: /*INSW*/
  1.1613 -                        checkio_perm(DX);
  1.1614 -                        checkio_perm(DX+1);
  1.1615 -                        tempw=inw(DX);
  1.1616 -                        writememw(es,DI,tempw);         if (abrt) break;
  1.1617 -                        if (flags&D_FLAG) DI-=2;
  1.1618 -                        else              DI+=2;
  1.1619 -                        cycles -= 5;
  1.1620 -                        break;
  1.1621 -                        case 0x6E: /*OUTSB*/
  1.1622 -                        temp=readmemb(ds,SI);           if (abrt) break;
  1.1623 -                        checkio_perm(DX);
  1.1624 -                        if (flags&D_FLAG) SI--;
  1.1625 -                        else              SI++;
  1.1626 -                        outb(DX,temp);
  1.1627 -                        cycles -= 5;
  1.1628 -                        break;
  1.1629 -                        case 0x6F: /*OUTSW*/
  1.1630 -                        tempw=readmemw(ds,SI);          if (abrt) break;
  1.1631 -                        checkio_perm(DX);
  1.1632 -                        checkio_perm(DX+1);
  1.1633 -                        if (flags&D_FLAG) SI-=2;
  1.1634 -                        else              SI+=2;
  1.1635 -                        outw(DX,tempw);
  1.1636 -//                        outb(DX+1,tempw>>8);
  1.1637 -                        cycles -= 5;
  1.1638 -                        break;
  1.1639 -
  1.1640 -                        case 0x70: /*JO*/
  1.1641 -                        offset=(int8_t)getbytef();
  1.1642 -                        if (flags&V_FLAG) { pc += offset; cycles -= 4; cycles -= 2; }
  1.1643 -                        cycles -= 3;
  1.1644 -                        break;
  1.1645 -                        case 0x71: /*JNO*/
  1.1646 -                        offset=(int8_t)getbytef();
  1.1647 -                        if (!(flags&V_FLAG)) { pc += offset; cycles -= 4; cycles -= 2; }
  1.1648 -                        cycles -= 3;
  1.1649 -                        break;
  1.1650 -                        case 0x72: /*JB*/
  1.1651 -                        offset=(int8_t)getbytef();
  1.1652 -                        if (flags&C_FLAG) { pc += offset; cycles -= 4; cycles -= 2; }
  1.1653 -                        cycles -= 3;
  1.1654 -                        break;
  1.1655 -                        case 0x73: /*JNB*/
  1.1656 -                        offset=(int8_t)getbytef();
  1.1657 -                        if (!(flags&C_FLAG)) { pc += offset; cycles -= 4; cycles -= 2; }
  1.1658 -                        cycles -= 3;
  1.1659 -                        break;
  1.1660 -                        case 0x74: /*JZ*/
  1.1661 -                        offset=(int8_t)getbytef();
  1.1662 -                        if (flags&Z_FLAG) { pc += offset; cycles -= 4; cycles -= 2; }
  1.1663 -                        cycles -= 3;
  1.1664 -                        break;
  1.1665 -                        case 0x75: /*JNZ*/
  1.1666 -                        offset=(int8_t)getbytef();
  1.1667 -                        if (!(flags&Z_FLAG)) { pc += offset; cycles -= 4; cycles -= 2; }
  1.1668 -                        cycles -= 3;
  1.1669 -                        break;
  1.1670 -                        case 0x76: /*JBE*/
  1.1671 -                        offset=(int8_t)getbytef();
  1.1672 -                        if (flags&(C_FLAG|Z_FLAG)) { pc += offset; cycles -= 4; cycles -= 2; }
  1.1673 -                        cycles -= 3;
  1.1674 -                        break;
  1.1675 -                        case 0x77: /*JNBE*/
  1.1676 -                        offset=(int8_t)getbytef();
  1.1677 -                        if (!(flags&(C_FLAG|Z_FLAG))) { pc += offset; cycles -= 4; cycles -= 2; }
  1.1678 -                        cycles -= 3;
  1.1679 -                        break;
  1.1680 -                        case 0x78: /*JS*/
  1.1681 -                        offset=(int8_t)getbytef();
  1.1682 -                        if (flags&N_FLAG)  { pc += offset; cycles -= 4; cycles -= 2; }
  1.1683 -                        cycles -= 3;
  1.1684 -                        break;
  1.1685 -                        case 0x79: /*JNS*/
  1.1686 -                        offset=(int8_t)getbytef();
  1.1687 -                        if (!(flags&N_FLAG))  { pc += offset; cycles -= 4; cycles -= 2; }
  1.1688 -                        cycles -= 3;
  1.1689 -                        break;
  1.1690 -                        case 0x7A: /*JP*/
  1.1691 -                        offset=(int8_t)getbytef();
  1.1692 -                        if (flags&P_FLAG)  { pc += offset; cycles -= 4; cycles -= 2; }
  1.1693 -                        cycles -= 3;
  1.1694 -                        break;
  1.1695 -                        case 0x7B: /*JNP*/
  1.1696 -                        offset=(int8_t)getbytef();
  1.1697 -                        if (!(flags&P_FLAG))  { pc += offset; cycles -= 4; cycles -= 2; }
  1.1698 -                        cycles -= 3;
  1.1699 -                        break;
  1.1700 -                        case 0x7C: /*JL*/
  1.1701 -                        offset=(int8_t)getbytef();
  1.1702 -                        temp=(flags&N_FLAG)?1:0;
  1.1703 -                        temp2=(flags&V_FLAG)?1:0;
  1.1704 -                        if (temp!=temp2)  { pc += offset; cycles -= 4; cycles -= 2; }
  1.1705 -                        cycles -= 3;
  1.1706 -                        break;
  1.1707 -                        case 0x7D: /*JNL*/
  1.1708 -                        offset=(int8_t)getbytef();
  1.1709 -                        temp=(flags&N_FLAG)?1:0;
  1.1710 -                        temp2=(flags&V_FLAG)?1:0;
  1.1711 -                        if (temp==temp2)  { pc += offset; cycles -= 4; cycles -= 2; }
  1.1712 -                        cycles -= 3;
  1.1713 -                        break;
  1.1714 -                        case 0x7E: /*JLE*/
  1.1715 -                        offset=(int8_t)getbytef();
  1.1716 -                        temp=(flags&N_FLAG)?1:0;
  1.1717 -                        temp2=(flags&V_FLAG)?1:0;
  1.1718 -                        if ((flags&Z_FLAG) || (temp!=temp2))  { pc += offset; cycles -= 4; cycles -= 2; }
  1.1719 -                        cycles -= 3;
  1.1720 -                        break;
  1.1721 -                        case 0x7F: /*JNLE*/
  1.1722 -                        offset=(int8_t)getbytef();
  1.1723 -                        temp=(flags&N_FLAG)?1:0;
  1.1724 -                        temp2=(flags&V_FLAG)?1:0;
  1.1725 -                        if (!((flags&Z_FLAG) || (temp!=temp2)))  { pc += offset; cycles -= 4; cycles -= 2; }
  1.1726 -                        cycles -= 3;
  1.1727 -                        break;
  1.1728 -
  1.1729 -
  1.1730 -                        case 0x80: 
  1.1731 -                        case 0x82:
  1.1732 -                        fetchea();
  1.1733 -                        temp=geteab();                  if (abrt) break;
  1.1734 -                        temp2=readmemb(cs,pc); pc++;    if (abrt) break;
  1.1735 -                        switch (rmdat&0x38)
  1.1736 -                        {
  1.1737 -                                case 0x00: /*ADD b,#8*/
  1.1738 -                                seteab(temp+temp2);             if (abrt) break;
  1.1739 -                                setadd8(temp,temp2);
  1.1740 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1741 -                                break;
  1.1742 -                                case 0x08: /*OR b,#8*/
  1.1743 -                                temp|=temp2;
  1.1744 -                                seteab(temp);                   if (abrt) break;
  1.1745 -                                setznp8(temp);
  1.1746 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1747 -                                break;
  1.1748 -                                case 0x10: /*ADC b,#8*/
  1.1749 -                                seteab(temp+temp2+tempc);       if (abrt) break;
  1.1750 -                                setadc8(temp,temp2);
  1.1751 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1752 -                                break;
  1.1753 -                                case 0x18: /*SBB b,#8*/
  1.1754 -                                seteab(temp-(temp2+tempc));     if (abrt) break;
  1.1755 -                                setsbc8(temp,temp2);
  1.1756 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1757 -                                break;
  1.1758 -                                case 0x20: /*AND b,#8*/
  1.1759 -                                temp&=temp2;
  1.1760 -                                seteab(temp);                   if (abrt) break;
  1.1761 -                                setznp8(temp);
  1.1762 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1763 -                                break;
  1.1764 -                                case 0x28: /*SUB b,#8*/
  1.1765 -                                seteab(temp-temp2);             if (abrt) break;
  1.1766 -                                setsub8(temp,temp2);
  1.1767 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1768 -                                break;
  1.1769 -                                case 0x30: /*XOR b,#8*/
  1.1770 -                                temp^=temp2;
  1.1771 -                                seteab(temp);                   if (abrt) break;
  1.1772 -                                setznp8(temp);
  1.1773 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1774 -                                break;
  1.1775 -                                case 0x38: /*CMP b,#8*/
  1.1776 -                                setsub8(temp,temp2);
  1.1777 -                                cycles -= (mod == 3) ? 3 : 6;
  1.1778 -                                break;
  1.1779 -
  1.1780 -//                                default:
  1.1781 -//                                pclog("Bad 80 opcode %02X\n",rmdat&0x38);
  1.1782 -//                                dumpregs();
  1.1783 -//                                exit(-1);
  1.1784 -                        }
  1.1785 -                        break;
  1.1786 -
  1.1787 -                        case 0x81: 
  1.1788 -                        fetchea();
  1.1789 -                        tempw=geteaw();         if (abrt) break;
  1.1790 -                        tempw2=getword();       if (abrt) break;
  1.1791 -                        switch (rmdat&0x38)
  1.1792 -                        {
  1.1793 -                                case 0x00: /*ADD w,#16*/
  1.1794 -                                seteaw(tempw+tempw2);   if (abrt) break;
  1.1795 -                                setadd16(tempw,tempw2);
  1.1796 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1797 -                                break;
  1.1798 -                                case 0x08: /*OR w,#16*/
  1.1799 -                                tempw|=tempw2;
  1.1800 -                                seteaw(tempw);          if (abrt) break;
  1.1801 -                                setznp16(tempw);
  1.1802 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1803 -                                break;
  1.1804 -                                case 0x10: /*ADC w,#16*/
  1.1805 -                                seteaw(tempw+tempw2+tempc); if (abrt) break;
  1.1806 -                                setadc16(tempw,tempw2);
  1.1807 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1808 -                                break;
  1.1809 -                                case 0x20: /*AND w,#16*/
  1.1810 -                                tempw&=tempw2;
  1.1811 -                                seteaw(tempw);          if (abrt) break;
  1.1812 -                                setznp16(tempw);
  1.1813 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1814 -                                break;
  1.1815 -                                case 0x18: /*SBB w,#16*/
  1.1816 -                                seteaw(tempw-(tempw2+tempc));   if (abrt) break;
  1.1817 -                                setsbc16(tempw,tempw2);
  1.1818 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1819 -                                break;
  1.1820 -                                case 0x28: /*SUB w,#16*/
  1.1821 -                                seteaw(tempw-tempw2);           if (abrt) break;
  1.1822 -                                setsub16(tempw,tempw2);
  1.1823 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1824 -                                break;
  1.1825 -                                case 0x30: /*XOR w,#16*/
  1.1826 -                                tempw^=tempw2;
  1.1827 -                                seteaw(tempw);                  if (abrt) break;
  1.1828 -                                setznp16(tempw);
  1.1829 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1830 -                                break;
  1.1831 -                                case 0x38: /*CMP w,#16*/
  1.1832 -//                                pclog("CMP %04X %04X\n", tempw, tempw2);
  1.1833 -                                setsub16(tempw,tempw2);
  1.1834 -                                cycles -= (mod == 3) ? 3 : 6;
  1.1835 -                                break;
  1.1836 -                        }
  1.1837 -                        break;
  1.1838 -
  1.1839 -                        case 0x83:
  1.1840 -                        fetchea();
  1.1841 -                        tempw=geteaw();                 if (abrt) break;
  1.1842 -                        tempw2=readmemb(cs,pc); pc++;   if (abrt) break;
  1.1843 -                        if (tempw2&0x80) tempw2|=0xFF00;
  1.1844 -                        switch (rmdat&0x38)
  1.1845 -                        {
  1.1846 -                                case 0x00: /*ADD w,#8*/
  1.1847 -                                seteaw(tempw+tempw2);           if (abrt) break;
  1.1848 -                                setadd16(tempw,tempw2);
  1.1849 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1850 -                                break;
  1.1851 -                                case 0x08: /*OR w,#8*/
  1.1852 -                                tempw|=tempw2;
  1.1853 -                                seteaw(tempw);                  if (abrt) break;
  1.1854 -                                setznp16(tempw);
  1.1855 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1856 -                                break;
  1.1857 -                                case 0x10: /*ADC w,#8*/
  1.1858 -                                seteaw(tempw+tempw2+tempc);     if (abrt) break;
  1.1859 -                                setadc16(tempw,tempw2);
  1.1860 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1861 -                                break;
  1.1862 -                                case 0x18: /*SBB w,#8*/
  1.1863 -                                seteaw(tempw-(tempw2+tempc));   if (abrt) break;
  1.1864 -                                setsbc16(tempw,tempw2);
  1.1865 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1866 -                                break;
  1.1867 -                                case 0x20: /*AND w,#8*/
  1.1868 -                                tempw&=tempw2;
  1.1869 -                                seteaw(tempw);                  if (abrt) break;
  1.1870 -                                setznp16(tempw);
  1.1871 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1872 -                                break;
  1.1873 -                                case 0x28: /*SUB w,#8*/
  1.1874 -                                seteaw(tempw-tempw2);           if (abrt) break;
  1.1875 -                                setsub16(tempw,tempw2);
  1.1876 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1877 -                                break;
  1.1878 -                                case 0x30: /*XOR w,#8*/
  1.1879 -                                tempw^=tempw2;
  1.1880 -                                seteaw(tempw);                  if (abrt) break;
  1.1881 -                                setznp16(tempw);
  1.1882 -                                cycles -= (mod == 3) ? 3 : 7;
  1.1883 -                                break;
  1.1884 -                                case 0x38: /*CMP w,#8*/
  1.1885 -                                setsub16(tempw,tempw2);
  1.1886 -                                cycles -= (mod == 3) ? 3 : 6;
  1.1887 -                                break;
  1.1888 -
  1.1889 -//                                default:
  1.1890 -//                                pclog("Bad 83 opcode %02X\n",rmdat&0x38);
  1.1891 -//                                dumpregs();
  1.1892 -//                                exit(-1);
  1.1893 -                        }
  1.1894 -                        break;
  1.1895 -
  1.1896 -                        case 0x84: /*TEST b,reg*/
  1.1897 -                        fetchea();
  1.1898 -                        temp=geteab();          if (abrt) break;
  1.1899 -                        temp2=getr8(reg);
  1.1900 -                        setznp8(temp&temp2);
  1.1901 -                        cycles -= (mod == 3) ? 2 : 6;
  1.1902 -                        break;
  1.1903 -                        case 0x85: /*TEST w,reg*/
  1.1904 -                        fetchea();
  1.1905 -                        tempw=geteaw();         if (abrt) break;
  1.1906 -                        tempw2=regs[reg].w;
  1.1907 -                        setznp16(tempw&tempw2);
  1.1908 -                        cycles -= (mod == 3) ? 2 : 6;
  1.1909 -                        break;
  1.1910 -                        case 0x86: /*XCHG b,reg*/
  1.1911 -                        fetchea();
  1.1912 -                        temp=geteab();          if (abrt) break;
  1.1913 -                        seteab(getr8(reg));     if (abrt) break;
  1.1914 -                        setr8(reg,temp);
  1.1915 -                        cycles -= (mod == 3) ? 3 : 5;
  1.1916 -                        break;
  1.1917 -                        case 0x87: /*XCHG w,reg*/
  1.1918 -                        fetchea();
  1.1919 -                        tempw=geteaw();         if (abrt) break;
  1.1920 -                        seteaw(regs[reg].w);    if (abrt) break;
  1.1921 -                        regs[reg].w=tempw;
  1.1922 -                        cycles -= (mod == 3) ? 3 : 5;
  1.1923 -                        break;
  1.1924 -
  1.1925 -                        case 0x88: /*MOV b,reg*/
  1.1926 -                        fetchea();
  1.1927 -                        seteab(getr8(reg));
  1.1928 -                        cycles -= (mod == 3) ? 2 : 3;
  1.1929 -                        break;
  1.1930 -                        case 0x89: /*MOV w,reg*/
  1.1931 -                        fetchea();
  1.1932 -                        seteaw(regs[reg].w);
  1.1933 -                        cycles -= (mod == 3) ? 2 : 3;
  1.1934 -                        break;
  1.1935 -                        case 0x8A: /*MOV reg,b*/
  1.1936 -                        fetchea();
  1.1937 -                        temp=geteab();          if (abrt) break;
  1.1938 -                        setr8(reg,temp);
  1.1939 -                        cycles -= (mod == 3) ? 5 : 3;
  1.1940 -                        break;
  1.1941 -                        case 0x8B: /*MOV reg,w*/
  1.1942 -                        fetchea();
  1.1943 -                        tempw=geteaw();         if (abrt) break;
  1.1944 -                        regs[reg].w=tempw;
  1.1945 -                        cycles -= (mod == 3) ? 5 : 3;
  1.1946 -                        break;
  1.1947 -
  1.1948 -                        case 0x8C: /*MOV w,sreg*/
  1.1949 -                        fetchea();
  1.1950 -                        switch (rmdat&0x38)
  1.1951 -                        {
  1.1952 -                                case 0x00: /*ES*/
  1.1953 -                                seteaw(ES);
  1.1954 -                                break;
  1.1955 -                                case 0x08: /*CS*/
  1.1956 -                                seteaw(CS);
  1.1957 -                                break;
  1.1958 -                                case 0x18: /*DS*/
  1.1959 -                                if (ssegs) ds=oldds;
  1.1960 -                                seteaw(DS);
  1.1961 -                                break;
  1.1962 -                                case 0x10: /*SS*/
  1.1963 -                                if (ssegs) ss=oldss;
  1.1964 -                                seteaw(SS);
  1.1965 -                                break;
  1.1966 -                        }
  1.1967 -                        cycles -= (mod == 3) ? 2 : 3;
  1.1968 -                        break;
  1.1969 -
  1.1970 -                        case 0x8D: /*LEA*/
  1.1971 -                        fetchea();
  1.1972 -                        regs[reg].w=eaaddr;
  1.1973 -                        cycles -= 3;
  1.1974 -                        break;
  1.1975 -
  1.1976 -                        case 0x8E: /*MOV sreg,w*/
  1.1977 -                        fetchea();
  1.1978 -                        switch (rmdat&0x38)
  1.1979 -                        {
  1.1980 -                                case 0x00: /*ES*/
  1.1981 -                                tempw=geteaw();         if (abrt) break;
  1.1982 -                                loadseg(tempw,&_es);
  1.1983 -                                break;
  1.1984 -                                case 0x18: /*DS*/
  1.1985 -                                tempw=geteaw();         if (abrt) break;
  1.1986 -                                loadseg(tempw,&_ds);
  1.1987 -                                if (ssegs) oldds=ds;
  1.1988 -                                break;
  1.1989 -                                case 0x10: /*SS*/
  1.1990 -//                                if (output==3) pclog("geteaw\n");
  1.1991 -                                tempw=geteaw();         if (abrt) break;
  1.1992 -//                                if (output==3) pclog("loadseg\n");
  1.1993 -                                loadseg(tempw,&_ss);
  1.1994 -//                                if (output==3) pclog("done\n");
  1.1995 -                                if (ssegs) oldss=ss;
  1.1996 -                                skipnextprint=1;
  1.1997 -				noint=1;
  1.1998 -                                break;
  1.1999 -                        }
  1.2000 -                        if (msw & 1) cycles -= (mod == 3) ? 17 : 19;
  1.2001 -                        else         cycles -= (mod == 3) ?  2 :  5;
  1.2002 -                        break;
  1.2003 -
  1.2004 -                        case 0x8F: /*POPW*/
  1.2005 -                        if (ssegs) templ2=oldss;
  1.2006 -                        else       templ2=ss;
  1.2007 -                        tempw=readmemw(templ2,SP);      if (abrt) break;
  1.2008 -                        SP+=2;
  1.2009 -                        fetchea();
  1.2010 -                        if (ssegs) ss=oldss;
  1.2011 -                        seteaw(tempw);
  1.2012 -                        if (abrt) SP-=2;
  1.2013 -                        cycles -= 5;
  1.2014 -                        break;
  1.2015 -
  1.2016 -                        case 0x90: /*NOP*/
  1.2017 -                        cycles -= 3;
  1.2018 -                        break;
  1.2019 -
  1.2020 -                        case 0x91: case 0x92: case 0x93: /*XCHG AX*/
  1.2021 -                        case 0x94: case 0x95: case 0x96: case 0x97:
  1.2022 -                        tempw=AX;
  1.2023 -                        AX=regs[opcode&7].w;
  1.2024 -                        regs[opcode&7].w=tempw;
  1.2025 -                        cycles -= 3;
  1.2026 -                        break;
  1.2027 -
  1.2028 -                        case 0x98: /*CBW*/
  1.2029 -                        AH=(AL&0x80)?0xFF:0;
  1.2030 -                        cycles -= 2;
  1.2031 -                        break;
  1.2032 -                        case 0x99: /*CWD*/
  1.2033 -                        DX=(AX&0x8000)?0xFFFF:0;
  1.2034 -                        cycles -= 2;
  1.2035 -                        break;
  1.2036 -                        case 0x9A: /*CALL FAR*/
  1.2037 -                        tempw=getword();
  1.2038 -                        tempw2=getword();       if (abrt) break;
  1.2039 -                        tempw3 = CS;
  1.2040 -                        templ2 = pc;
  1.2041 -                        if (ssegs) ss=oldss;
  1.2042 -                        oxpc=pc;
  1.2043 -                        pc=tempw;
  1.2044 -                        optype=CALL;
  1.2045 -                        if (msw&1) loadcscall(tempw2);
  1.2046 -                        else       loadcs(tempw2);
  1.2047 -                        optype=0;
  1.2048 -                        if (abrt) break;
  1.2049 -                        oldss=ss;
  1.2050 -                        writememw(ss,(SP-2)&0xFFFF,tempw3);
  1.2051 -                        writememw(ss,(SP-4)&0xFFFF,templ2);     if (abrt) break;
  1.2052 -                        SP-=4;
  1.2053 -                        cycles -= (msw & 1) ? 26 : 13;
  1.2054 -                        break;
  1.2055 -                        case 0x9B: /*WAIT*/
  1.2056 -                        cycles -= 3;
  1.2057 -                        break;
  1.2058 -                        case 0x9C: /*PUSHF*/
  1.2059 -                        if (ssegs) ss=oldss;
  1.2060 -                        if (msw & 1) { writememw(ss, ((SP-2)&0xFFFF), flags & 0x7fff); }
  1.2061 -                        else         { writememw(ss, ((SP-2)&0xFFFF), flags & 0x0fff); }   
  1.2062 -                        if (abrt) break;
  1.2063 -                        SP-=2;
  1.2064 -                        cycles -= 3;
  1.2065 -                        break;
  1.2066 -                        case 0x9D: /*POPF*/
  1.2067 -                        if (ssegs) ss=oldss;
  1.2068 -                        tempw=readmemw(ss,SP);                  if (abrt) break;
  1.2069 -                        SP+=2;
  1.2070 -                        if (!(CPL) || !(msw&1)) flags=(tempw&0xFFD5)|2;
  1.2071 -                        else if (IOPLp) flags=(flags&0x3000)|(tempw&0x4FD5)|2;
  1.2072 -                        else            flags=(flags&0x7200)|(tempw&0x0DD5)|2;
  1.2073 -                        pclog("POPF %04X %04X  %04X:%04X\n", tempw, flags, CS, pc);
  1.2074 -                        cycles -= 5;
  1.2075 -                        break;
  1.2076 -                        case 0x9E: /*SAHF*/
  1.2077 -                        flags=(flags&0xFF00)|(AH&0xD5)|2;
  1.2078 -                        cycles -= 2;
  1.2079 -                        break;
  1.2080 -                        case 0x9F: /*LAHF*/
  1.2081 -                        AH=flags&0xFF;
  1.2082 -                        cycles -= 2;
  1.2083 -                        break;
  1.2084 -
  1.2085 -                        case 0xA0: /*MOV AL,(w)*/
  1.2086 -                        addr=getword(); if (abrt) break;
  1.2087 -                        temp=readmemb(ds,addr);         if (abrt) break;
  1.2088 -                        AL=temp;
  1.2089 -                        cycles -= 5;
  1.2090 -                        break;
  1.2091 -                        case 0xA1: /*MOV AX,(w)*/
  1.2092 -                        addr=getword(); if (abrt) break;
  1.2093 -                        tempw=readmemw(ds,addr);        if (abrt) break;
  1.2094 -                        AX=tempw;
  1.2095 -                        cycles -= 5;
  1.2096 -                        break;
  1.2097 -                        case 0xA2: /*MOV (w),AL*/
  1.2098 -                        addr=getword(); if (abrt) break;
  1.2099 -                        writememb(ds,addr,AL);
  1.2100 -                        cycles -= 3;
  1.2101 -                        break;
  1.2102 -                        case 0xA3: /*MOV (w),AX*/
  1.2103 -                        addr=getword(); if (abrt) break;
  1.2104 -                        writememw(ds,addr,AX);
  1.2105 -                        cycles -= 3;
  1.2106 -                        break;
  1.2107 -
  1.2108 -                        case 0xA4: /*MOVSB*/
  1.2109 -                        temp=readmemb(ds,SI);  if (abrt) break;
  1.2110 -                        writememb(es,DI,temp); if (abrt) break;
  1.2111 -                        if (flags&D_FLAG) { DI--; SI--; }
  1.2112 -                        else              { DI++; SI++; }
  1.2113 -                        cycles -= 5;
  1.2114 -                        break;
  1.2115 -                        case 0xA5: /*MOVSW*/
  1.2116 -                        tempw=readmemw(ds,SI);  if (abrt) break;
  1.2117 -                        writememw(es,DI,tempw); if (abrt) break;
  1.2118 -                        if (flags&D_FLAG) { DI-=2; SI-=2; }
  1.2119 -                        else              { DI+=2; SI+=2; }
  1.2120 -                        cycles -= 5;
  1.2121 -                        break;
  1.2122 -                        case 0xA6: /*CMPSB*/
  1.2123 -                        temp =readmemb(ds,SI);
  1.2124 -                        temp2=readmemb(es,DI);
  1.2125 -                        if (abrt) break;
  1.2126 -                        setsub8(temp,temp2);
  1.2127 -                        if (flags&D_FLAG) { DI--; SI--; }
  1.2128 -                        else              { DI++; SI++; }
  1.2129 -                        cycles -= 8;
  1.2130 -                        break;
  1.2131 -                        case 0xA7: /*CMPSW*/
  1.2132 -                        tempw =readmemw(ds,SI);
  1.2133 -                        tempw2=readmemw(es,DI);
  1.2134 -                        if (abrt) break;
  1.2135 -                        setsub16(tempw,tempw2);
  1.2136 -                        if (flags&D_FLAG) { DI-=2; SI-=2; }
  1.2137 -                        else              { DI+=2; SI+=2; }
  1.2138 -                        cycles -= 8;
  1.2139 -                        break;
  1.2140 -                        case 0xA8: /*TEST AL,#8*/
  1.2141 -                        temp=getbytef();
  1.2142 -                        setznp8(AL&temp);
  1.2143 -                        cycles -= 3;
  1.2144 -                        break;
  1.2145 -                        case 0xA9: /*TEST AX,#16*/
  1.2146 -                        tempw=getwordf();
  1.2147 -                        setznp16(AX&tempw);
  1.2148 -                        cycles -= 3;
  1.2149 -                        break;
  1.2150 -                        case 0xAA: /*STOSB*/
  1.2151 -                        writememb(es,DI,AL);    if (abrt) break;
  1.2152 -                        if (flags&D_FLAG) DI--;
  1.2153 -                        else              DI++;
  1.2154 -                        cycles -= 3;
  1.2155 -                        break;
  1.2156 -                        case 0xAB: /*STOSW*/
  1.2157 -                        writememw(es,DI,AX);    if (abrt) break;
  1.2158 -                        if (flags&D_FLAG) DI-=2;
  1.2159 -                        else              DI+=2;
  1.2160 -                        cycles -= 3;
  1.2161 -                        break;
  1.2162 -                        case 0xAC: /*LODSB*/
  1.2163 -                        temp=readmemb(ds,SI);
  1.2164 -                        if (abrt) break;
  1.2165 -                        AL=temp;
  1.2166 -                        if (flags&D_FLAG) SI--;
  1.2167 -                        else              SI++;
  1.2168 -                        cycles -= 5;
  1.2169 -                        break;
  1.2170 -                        case 0xAD: /*LODSW*/
  1.2171 -                        tempw=readmemw(ds,SI);
  1.2172 -                        if (abrt) break;
  1.2173 -                        AX=tempw;
  1.2174 -//                        if (output) pclog("Load from %05X:%04X\n",ds,SI);
  1.2175 -                        if (flags&D_FLAG) SI-=2;
  1.2176 -                        else              SI+=2;
  1.2177 -                        cycles -= 5;
  1.2178 -                        break;
  1.2179 -                        case 0xAE: /*SCASB*/
  1.2180 -                        temp=readmemb(es,DI);
  1.2181 -                        if (abrt) break;
  1.2182 -                        setsub8(AL,temp);
  1.2183 -                        if (flags&D_FLAG) DI--;
  1.2184 -                        else              DI++;
  1.2185 -                        cycles -= 7;
  1.2186 -                        break;
  1.2187 -                        case 0xAF: /*SCASW*/
  1.2188 -                        tempw=readmemw(es,DI);
  1.2189 -                        if (abrt) break;
  1.2190 -                        setsub16(AX,tempw);
  1.2191 -                        if (flags&D_FLAG) DI-=2;
  1.2192 -                        else              DI+=2;
  1.2193 -                        cycles -= 7;
  1.2194 -                        break;
  1.2195 -
  1.2196 -                        case 0xB0: /*MOV AL,#8*/
  1.2197 -                        AL=getbytef();
  1.2198 -                        cycles -= 2;
  1.2199 -                        break;
  1.2200 -                        case 0xB1: /*MOV CL,#8*/
  1.2201 -                        CL=getbytef();
  1.2202 -                        cycles -= 2;
  1.2203 -                        break;
  1.2204 -                        case 0xB2: /*MOV DL,#8*/
  1.2205 -                        DL=getbytef();
  1.2206 -                        cycles -= 2;
  1.2207 -                        break;
  1.2208 -                        case 0xB3: /*MOV BL,#8*/
  1.2209 -                        BL=getbytef();
  1.2210 -                        cycles -= 2;
  1.2211 -                        break;
  1.2212 -                        case 0xB4: /*MOV AH,#8*/
  1.2213 -                        AH=getbytef();
  1.2214 -                        cycles -= 2;
  1.2215 -                        break;
  1.2216 -                        case 0xB5: /*MOV CH,#8*/
  1.2217 -                        CH=getbytef();
  1.2218 -                        cycles -= 2;
  1.2219 -                        break;
  1.2220 -                        case 0xB6: /*MOV DH,#8*/
  1.2221 -                        DH=getbytef();
  1.2222 -                        cycles -= 2;
  1.2223 -                        break;
  1.2224 -                        case 0xB7: /*MOV BH,#8*/
  1.2225 -                        BH=getbytef();
  1.2226 -                        cycles -= 2;
  1.2227 -                        break;
  1.2228 -                        case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV reg,#16*/
  1.2229 -                        case 0xBC: case 0xBD: case 0xBE: case 0xBF:
  1.2230 -                        regs[opcode&7].w=getwordf();
  1.2231 -                        cycles -= 2;
  1.2232 -                        break;
  1.2233 -
  1.2234 -                        case 0xC0:
  1.2235 -                        fetchea();
  1.2236 -                        c=readmemb(cs,pc); pc++;
  1.2237 -                        temp=geteab();          if (abrt) break;
  1.2238 -                        c&=31;
  1.2239 -                        if (!c) break;
  1.2240 -                        cycles -= c;                        
  1.2241 -                        switch (rmdat&0x38)
  1.2242 -                        {
  1.2243 -                                case 0x00: /*ROL b,CL*/
  1.2244 -                                while (c>0)
  1.2245 -                                {
  1.2246 -                                        temp2=(temp&0x80)?1:0;
  1.2247 -                                        temp=(temp<<1)|temp2;
  1.2248 -                                        c--;
  1.2249 -                                }
  1.2250 -                                seteab(temp);   if (abrt) break;
  1.2251 -                                flags&=~(C_FLAG|V_FLAG);
  1.2252 -                                if (temp2) flags|=C_FLAG;
  1.2253 -                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
  1.2254 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2255 -                                break;
  1.2256 -                                case 0x08: /*ROR b,CL*/
  1.2257 -                                while (c>0)
  1.2258 -                                {
  1.2259 -                                        temp2=temp&1;
  1.2260 -                                        temp>>=1;
  1.2261 -                                        if (temp2) temp|=0x80;
  1.2262 -                                        c--;
  1.2263 -                                }
  1.2264 -                                seteab(temp);   if (abrt) break;
  1.2265 -                                flags&=~(C_FLAG|V_FLAG);
  1.2266 -                                if (temp2) flags|=C_FLAG;
  1.2267 -                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
  1.2268 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2269 -                                break;
  1.2270 -                                case 0x10: /*RCL b,CL*/
  1.2271 -                                temp2=flags&C_FLAG;
  1.2272 -                                while (c>0)
  1.2273 -                                {
  1.2274 -                                        tempc=(temp2)?1:0;
  1.2275 -                                        temp2=temp&0x80;
  1.2276 -                                        temp=(temp<<1)|tempc;
  1.2277 -                                        c--;
  1.2278 -                                        if (is486) cycles--;
  1.2279 -                                }
  1.2280 -                                seteab(temp);   if (abrt) break;
  1.2281 -                                flags&=~(C_FLAG|V_FLAG);
  1.2282 -                                if (temp2) flags|=C_FLAG;
  1.2283 -                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
  1.2284 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2285 -                                break;
  1.2286 -                                case 0x18: /*RCR b,CL*/
  1.2287 -                                temp2=flags&C_FLAG;
  1.2288 -                                while (c>0)
  1.2289 -                                {
  1.2290 -                                        tempc=(temp2)?0x80:0;
  1.2291 -                                        temp2=temp&1;
  1.2292 -                                        temp=(temp>>1)|tempc;
  1.2293 -                                        c--;
  1.2294 -                                        if (is486) cycles--;
  1.2295 -                                }
  1.2296 -                                seteab(temp);   if (abrt) break;
  1.2297 -                                flags&=~(C_FLAG|V_FLAG);
  1.2298 -                                if (temp2) flags|=C_FLAG;
  1.2299 -                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
  1.2300 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2301 -                                break;
  1.2302 -                                case 0x20: case 0x30: /*SHL b,CL*/
  1.2303 -                                seteab(temp<<c);        if (abrt) break;
  1.2304 -                                setznp8(temp<<c);
  1.2305 -                                if ((temp<<(c-1))&0x80) flags|=C_FLAG;
  1.2306 -                                if (((temp<<c)^(temp<<(c-1)))&0x80) flags|=V_FLAG;
  1.2307 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2308 -                                break;
  1.2309 -                                case 0x28: /*SHR b,CL*/
  1.2310 -                                seteab(temp>>c);        if (abrt) break;
  1.2311 -                                setznp8(temp>>c);
  1.2312 -                                if ((temp>>(c-1))&1) flags|=C_FLAG;
  1.2313 -                                if (c==1 && temp&0x80) flags|=V_FLAG;
  1.2314 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2315 -                                break;
  1.2316 -                                case 0x38: /*SAR b,CL*/
  1.2317 -                                tempc=((temp>>(c-1))&1);
  1.2318 -                                while (c>0)
  1.2319 -                                {
  1.2320 -                                        temp>>=1;
  1.2321 -                                        if (temp&0x40) temp|=0x80;
  1.2322 -                                        c--;
  1.2323 -                                }
  1.2324 -                                seteab(temp);   if (abrt) break;
  1.2325 -                                setznp8(temp);
  1.2326 -                                if (tempc) flags|=C_FLAG;
  1.2327 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2328 -                                break;
  1.2329 -
  1.2330 -//                                default:
  1.2331 -//                                pclog("Bad C0 opcode %02X\n",rmdat&0x38);
  1.2332 -//                                dumpregs();
  1.2333 -//                                exit(-1);
  1.2334 -                        }
  1.2335 -                        break;
  1.2336 -
  1.2337 -                        case 0xC1:
  1.2338 -                        fetchea();
  1.2339 -                        c=readmemb(cs,pc)&31; pc++;
  1.2340 -                        tempw=geteaw();         if (abrt) break;
  1.2341 -                        if (!c) break;
  1.2342 -                        cycles -= c;
  1.2343 -                        switch (rmdat&0x38)
  1.2344 -                        {
  1.2345 -                                case 0x00: /*ROL w,CL*/
  1.2346 -                                while (c>0)
  1.2347 -                                {
  1.2348 -                                        temp=(tempw&0x8000)?1:0;
  1.2349 -                                        tempw=(tempw<<1)|temp;
  1.2350 -                                        c--;
  1.2351 -                                }
  1.2352 -                                seteaw(tempw);  if (abrt) break;
  1.2353 -                                flags&=~(C_FLAG|V_FLAG);
  1.2354 -                                if (temp) flags|=C_FLAG;
  1.2355 -                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
  1.2356 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2357 -                                break;
  1.2358 -                                case 0x08: /*ROR w,CL*/
  1.2359 -                                while (c>0)
  1.2360 -                                {
  1.2361 -                                        tempw2=(tempw&1)?0x8000:0;
  1.2362 -                                        tempw=(tempw>>1)|tempw2;
  1.2363 -                                        c--;
  1.2364 -                                }
  1.2365 -                                seteaw(tempw);  if (abrt) break;
  1.2366 -                                flags&=~(C_FLAG|V_FLAG);
  1.2367 -                                if (tempw2) flags|=C_FLAG;
  1.2368 -                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
  1.2369 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2370 -                                break;
  1.2371 -                                case 0x10: /*RCL w,CL*/
  1.2372 -                                temp2=flags&C_FLAG;
  1.2373 -                                while (c>0)
  1.2374 -                                {
  1.2375 -                                        tempc=(temp2)?1:0;
  1.2376 -                                        temp2=(tempw>>15);
  1.2377 -                                        tempw=(tempw<<1)|tempc;
  1.2378 -                                        c--;
  1.2379 -                                        if (is486) cycles--;
  1.2380 -                                }
  1.2381 -                                seteaw(tempw);  if (abrt) break;
  1.2382 -                                flags&=~(C_FLAG|V_FLAG);
  1.2383 -                                if (temp2) flags|=C_FLAG;
  1.2384 -                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
  1.2385 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2386 -                                break;
  1.2387 -                                case 0x18: /*RCR w,CL*/
  1.2388 -                                temp2=flags&C_FLAG;
  1.2389 -                                while (c>0)
  1.2390 -                                {
  1.2391 -                                        tempc=(temp2)?0x8000:0;
  1.2392 -                                        temp2=tempw&1;
  1.2393 -                                        tempw=(tempw>>1)|tempc;
  1.2394 -                                        c--;
  1.2395 -                                        if (is486) cycles--;
  1.2396 -                                }
  1.2397 -                                seteaw(tempw);  if (abrt) break;
  1.2398 -                                flags&=~(C_FLAG|V_FLAG);
  1.2399 -                                if (temp2) flags|=C_FLAG;
  1.2400 -                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
  1.2401 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2402 -                                break;
  1.2403 -
  1.2404 -                                case 0x20: case 0x30: /*SHL w,CL*/
  1.2405 -                                seteaw(tempw<<c); if (abrt) break;
  1.2406 -                                setznp16(tempw<<c);
  1.2407 -                                if ((tempw<<(c-1))&0x8000) flags|=C_FLAG;
  1.2408 -                                if (((tempw<<c)^(tempw<<(c-1)))&0x8000) flags|=V_FLAG;
  1.2409 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2410 -                                break;
  1.2411 -
  1.2412 -                                case 0x28:            /*SHR w,CL*/
  1.2413 -                                seteaw(tempw>>c); if (abrt) break;
  1.2414 -                                setznp16(tempw>>c);
  1.2415 -                                if ((tempw>>(c-1))&1) flags|=C_FLAG;
  1.2416 -                                if (c==1 && tempw&0x8000) flags|=V_FLAG;
  1.2417 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2418 -                                break;
  1.2419 -
  1.2420 -                                case 0x38:            /*SAR w,CL*/
  1.2421 -                                tempw2=tempw&0x8000;
  1.2422 -                                tempc=(tempw>>(c-1))&1;
  1.2423 -                                while (c>0)
  1.2424 -                                {
  1.2425 -                                        tempw=(tempw>>1)|tempw2;
  1.2426 -                                        c--;
  1.2427 -                                }
  1.2428 -                                seteaw(tempw);  if (abrt) break;
  1.2429 -                                setznp16(tempw);
  1.2430 -                                if (tempc) flags|=C_FLAG;
  1.2431 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2432 -                                break;
  1.2433 -
  1.2434 -//                                default:
  1.2435 -//                                pclog("Bad C1 opcode %02X\n",rmdat&0x38);
  1.2436 -//                                dumpregs();
  1.2437 -//                                exit(-1);
  1.2438 -                        }
  1.2439 -                        break;
  1.2440 -
  1.2441 -                        case 0xC2: /*RET*/
  1.2442 -                        tempw=getword();
  1.2443 -                        if (ssegs) ss=oldss;
  1.2444 -                        tempw2=readmemw(ss,SP); if (abrt) break;
  1.2445 -                        SP+=2+tempw;
  1.2446 -                        pc=tempw2;
  1.2447 -                        cycles -= 11;
  1.2448 -                        break;
  1.2449 -                        case 0xC3: /*RET*/
  1.2450 -                        if (ssegs) ss=oldss;
  1.2451 -                        tempw=readmemw(ss,SP);  if (abrt) break;
  1.2452 -                        SP+=2;
  1.2453 -                        pc=tempw;
  1.2454 -                        cycles -= 11;
  1.2455 -                        break;
  1.2456 -                        case 0xC4: /*LES*/
  1.2457 -                        fetchea();
  1.2458 -                        tempw2=readmemw(easeg,eaaddr);
  1.2459 -                        tempw=readmemw(easeg,eaaddr+2); if (abrt) break;
  1.2460 -                        loadseg(tempw,&_es);            if (abrt) break;
  1.2461 -                        regs[reg].w=tempw2;
  1.2462 -                        cycles -= 7;
  1.2463 -                        break;
  1.2464 -                        case 0xC5: /*LDS*/
  1.2465 -                        fetchea();
  1.2466 -                        tempw2=readmemw(easeg,eaaddr);
  1.2467 -                        tempw=readmemw(easeg,eaaddr+2); if (abrt) break;
  1.2468 -                        loadseg(tempw,&_ds);            if (abrt) break;
  1.2469 -                        if (ssegs) oldds=ds;
  1.2470 -                        regs[reg].w=tempw2;
  1.2471 -                        cycles -= 7;
  1.2472 -                        break;
  1.2473 -                        case 0xC6: /*MOV b,#8*/
  1.2474 -                        fetchea();
  1.2475 -                        temp=readmemb(cs,pc); pc++;     if (abrt) break;
  1.2476 -                        seteab(temp);
  1.2477 -                        cycles -= (mod == 3) ? 2 : 3;
  1.2478 -                        break;
  1.2479 -                        case 0xC7: /*MOV w,#16*/
  1.2480 -                        fetchea();
  1.2481 -                        tempw=getword();                if (abrt) break;
  1.2482 -                        seteaw(tempw);
  1.2483 -                        cycles -= (mod == 3) ? 2 : 3;
  1.2484 -                        break;
  1.2485 -                        case 0xC8: /*ENTER*/
  1.2486 -                        tempw2=getword();
  1.2487 -                        tempi=readmemb(cs,pc); pc++;
  1.2488 -                        templ=BP;
  1.2489 -                        writememw(ss,((SP-2)&0xFFFF),BP); if (abrt) break; 
  1.2490 -                        SP-=2;
  1.2491 -                        templ2=SP;
  1.2492 -                        if (tempi>0)
  1.2493 -                        {
  1.2494 -                                while (--tempi)
  1.2495 -                                {
  1.2496 -                                        BP-=2;
  1.2497 -                                        tempw=readmemw(ss,BP);
  1.2498 -                                        if (abrt) { SP=templ2; BP=templ; break; }
  1.2499 -                                        writememw(ss,((SP-2)&0xFFFF),tempw); SP-=2;
  1.2500 -                                        if (abrt) { SP=templ2; BP=templ; break; }
  1.2501 -                                        cycles-=(is486)?3:4;
  1.2502 -                                }
  1.2503 -                                writememw(ss,((SP-2)&0xFFFF),templ2); SP-=2;
  1.2504 -                                if (abrt) { SP=templ2; BP=templ; break; }
  1.2505 -                                cycles -= 4;
  1.2506 -                        }
  1.2507 -                        BP = templ2;
  1.2508 -                        SP-=tempw2;
  1.2509 -                        cycles -= 12;
  1.2510 -                        break;
  1.2511 -                        case 0xC9: /*LEAVE*/
  1.2512 -                        templ=SP;
  1.2513 -                        SP=BP;
  1.2514 -                        tempw=readmemw(ss,SP);   SP+=2;
  1.2515 -                        if (abrt) { SP=templ; break; }
  1.2516 -                        BP=tempw;
  1.2517 -                        cycles -= 5;
  1.2518 -                        break;
  1.2519 -                        case 0xCA: /*RETF*/
  1.2520 -                        tempw=getword();
  1.2521 -                        if (msw&1)
  1.2522 -                        {
  1.2523 -                                pmoderetf(0,tempw);
  1.2524 -                                break;
  1.2525 -                        }
  1.2526 -                        tempw2=CPL;
  1.2527 -                        if (ssegs) ss=oldss;
  1.2528 -                        oxpc=pc;
  1.2529 -                        pc=readmemw(ss,SP);
  1.2530 -                        loadcs(readmemw(ss,SP+2));
  1.2531 -                        if (abrt) break;
  1.2532 -                        SP+=4+tempw;
  1.2533 -                        cycles -= 15;
  1.2534 -                        break;
  1.2535 -                        case 0xCB: /*RETF*/
  1.2536 -                        if (msw&1)
  1.2537 -                        {
  1.2538 -                                pmoderetf(0,0);
  1.2539 -                                break;
  1.2540 -                        }
  1.2541 -                        tempw2=CPL;
  1.2542 -                        if (ssegs) ss=oldss;
  1.2543 -                        oxpc=pc;
  1.2544 -                        pc=readmemw(ss,SP);
  1.2545 -                        loadcs(readmemw(ss,SP+2));
  1.2546 -                        if (abrt) break;
  1.2547 -                        SP+=4;
  1.2548 -                        cycles -= 15;
  1.2549 -                        break;
  1.2550 -                        case 0xCC: /*INT 3*/
  1.2551 -                        if (msw&1)
  1.2552 -                        {
  1.2553 -                                pmodeint(3,1);
  1.2554 -                                cycles -= 40;
  1.2555 -                        }
  1.2556 -                        else
  1.2557 -                        {
  1.2558 -                                if (ssegs) ss=oldss;
  1.2559 -                                writememw(ss,((SP-2)&0xFFFF),flags);
  1.2560 -                                writememw(ss,((SP-4)&0xFFFF),CS);
  1.2561 -                                writememw(ss,((SP-6)&0xFFFF),pc);
  1.2562 -                                SP-=6;
  1.2563 -                                addr=3<<2;
  1.2564 -//                                flags&=~I_FLAG;
  1.2565 -                                flags&=~T_FLAG;
  1.2566 -                                oxpc=pc;
  1.2567 -                                pc=readmemw(0,addr);
  1.2568 -                                loadcs(readmemw(0,addr+2));
  1.2569 -                                cycles -= 23;
  1.2570 -                        }
  1.2571 -                        break;
  1.2572 -                        case 0xCD: /*INT*/
  1.2573 -                        lastpc=pc;
  1.2574 -                        lastcs=CS;
  1.2575 -                        temp=readmemb(cs,pc); pc++;
  1.2576 -                        intrt:
  1.2577 -                                pclog("INT %02X  %04X %04X %04X %04X  %04X:%04X\n", temp, AX, BX, CX, DX, CS, pc);
  1.2578 -                        if (1)
  1.2579 -                        {
  1.2580 -                                if (msw&1)
  1.2581 -                                {
  1.2582 -//                                        pclog("PMODE int %02X %04X at %04X:%04X  ",temp,AX,CS,pc);
  1.2583 -                                        pmodeint(temp,1);
  1.2584 -                                        cycles -= 40;
  1.2585 -//                                        pclog("to %04X:%04X\n",CS,pc);
  1.2586 -                                }
  1.2587 -                                else
  1.2588 -                                {
  1.2589 -                                        if (ssegs) ss=oldss;
  1.2590 -                                        writememw(ss,((SP-2)&0xFFFF),flags);
  1.2591 -                                        writememw(ss,((SP-4)&0xFFFF),CS);
  1.2592 -                                        writememw(ss,((SP-6)&0xFFFF),pc);
  1.2593 -                                        SP-=6;
  1.2594 -                                        addr=temp<<2;
  1.2595 -//                                        flags&=~I_FLAG;
  1.2596 -                                        flags&=~T_FLAG;
  1.2597 -                                        oxpc=pc;
  1.2598 -//                                        pclog("%04X:%04X : ",CS,pc);
  1.2599 -                                        pc=readmemw(0,addr);
  1.2600 -                                        loadcs(readmemw(0,addr+2));
  1.2601 -                                        cycles -= 23;
  1.2602 -//                                        pclog("INT %02X - %04X %04X:%04X\n",temp,addr,CS,pc);
  1.2603 -                                }
  1.2604 -                        }
  1.2605 -                        break;
  1.2606 -                        case 0xCE: /*INTO*/
  1.2607 -                        if (flags&V_FLAG)
  1.2608 -                        {
  1.2609 -                                temp=4;
  1.2610 -                                goto intrt;
  1.2611 -/*                                pclog("INTO interrupt!\n");
  1.2612 -                                dumpregs();
  1.2613 -                                exit(-1);*/
  1.2614 -                        }
  1.2615 -                        cycles-=3;
  1.2616 -                        break;
  1.2617 -                        case 0xCF: /*IRET*/
  1.2618 -                        if (ssegs) ss=oldss;
  1.2619 -                        if (msw&1)
  1.2620 -                        {
  1.2621 -                                optype=IRET;
  1.2622 -                                pmodeiret(0);
  1.2623 -                                optype=0;
  1.2624 -                        }
  1.2625 -                        else
  1.2626 -                        {
  1.2627 -                                tempw=CS;
  1.2628 -                                tempw2=pc;
  1.2629 -                                inint=0;
  1.2630 -                                oxpc=pc;
  1.2631 -                                pc=readmemw(ss,SP);
  1.2632 -                                loadcs(readmemw(ss,((SP+2)&0xFFFF)));
  1.2633 -                                flags=(readmemw(ss,((SP+4)&0xFFFF))&0x0FD5)|2;
  1.2634 -                                SP+=6;
  1.2635 -                        }
  1.2636 -                        cycles -= 17;
  1.2637 -                        break;
  1.2638 -                        
  1.2639 -                        case 0xD0:
  1.2640 -                        fetchea();
  1.2641 -                        temp=geteab(); if (abrt) break;
  1.2642 -                        switch (rmdat&0x38)
  1.2643 -                        {
  1.2644 -                                case 0x00: /*ROL b,1*/
  1.2645 -                                seteab((temp<<1)|((temp&0x80)?1:0)); if (abrt) break;
  1.2646 -                                if (temp&0x80) flags|=C_FLAG;
  1.2647 -                                else           flags&=~C_FLAG;
  1.2648 -                                temp<<=1;
  1.2649 -                                if (flags&C_FLAG) temp|=1;
  1.2650 -                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
  1.2651 -                                else                          flags&=~V_FLAG;
  1.2652 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2653 -                                break;
  1.2654 -                                case 0x08: /*ROR b,1*/
  1.2655 -                                seteab((temp>>1)|((temp&1)?0x80:0)); if (abrt) break;
  1.2656 -                                if (temp&1) flags|=C_FLAG;
  1.2657 -                                else        flags&=~C_FLAG;
  1.2658 -                                temp>>=1;
  1.2659 -                                if (flags&C_FLAG) temp|=0x80;
  1.2660 -                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
  1.2661 -                                else                       flags&=~V_FLAG;
  1.2662 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2663 -                                break;
  1.2664 -                                case 0x10: /*RCL b,1*/
  1.2665 -                                temp2=flags&C_FLAG;
  1.2666 -                                seteab((temp<<1)|temp2); if (abrt) break;
  1.2667 -                                if (temp&0x80) flags|=C_FLAG;
  1.2668 -                                else           flags&=~C_FLAG;
  1.2669 -                                temp<<=1;
  1.2670 -                                if (temp2) temp|=1;
  1.2671 -                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
  1.2672 -                                else                          flags&=~V_FLAG;
  1.2673 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2674 -                                break;
  1.2675 -                                case 0x18: /*RCR b,1*/
  1.2676 -                                temp2=flags&C_FLAG;
  1.2677 -                                seteab((temp>>1)|(temp2?0x80:0)); if (abrt) break;
  1.2678 -                                if (temp&1) flags|=C_FLAG;
  1.2679 -                                else        flags&=~C_FLAG;
  1.2680 -                                temp>>=1;
  1.2681 -                                if (temp2) temp|=0x80;
  1.2682 -                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
  1.2683 -                                else                       flags&=~V_FLAG;
  1.2684 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2685 -                                break;
  1.2686 -                                case 0x20: case 0x30: /*SHL b,1*/
  1.2687 -                                seteab(temp<<1); if (abrt) break;
  1.2688 -                                setznp8(temp<<1);
  1.2689 -                                if (temp&0x80) flags|=C_FLAG;
  1.2690 -                                if ((temp^(temp<<1))&0x80) flags|=V_FLAG;
  1.2691 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2692 -                                break;
  1.2693 -                                case 0x28: /*SHR b,1*/
  1.2694 -                                seteab(temp>>1); if (abrt) break;
  1.2695 -                                setznp8(temp>>1);
  1.2696 -                                if (temp&1) flags|=C_FLAG;
  1.2697 -                                if (temp&0x80) flags|=V_FLAG;
  1.2698 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2699 -                                break;
  1.2700 -                                case 0x38: /*SAR b,1*/
  1.2701 -                                seteab((temp>>1)|(temp&0x80)); if (abrt) break;
  1.2702 -                                setznp8((temp>>1)|(temp&0x80));
  1.2703 -                                if (temp&1) flags|=C_FLAG;
  1.2704 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2705 -                                break;
  1.2706 -
  1.2707 -//                                default:
  1.2708 -//                                pclog("Bad D0 opcode %02X\n",rmdat&0x38);
  1.2709 -//                                dumpregs();
  1.2710 -//                                exit(-1);
  1.2711 -                        }
  1.2712 -                        break;
  1.2713 -                        case 0xD1:
  1.2714 -                        fetchea();
  1.2715 -                        tempw=geteaw(); if (abrt) break;
  1.2716 -                        switch (rmdat&0x38)
  1.2717 -                        {
  1.2718 -                                case 0x00: /*ROL w,1*/
  1.2719 -                                seteaw((tempw<<1)|(tempw>>15)); if (abrt) break;
  1.2720 -                                if (tempw&0x8000) flags|=C_FLAG;
  1.2721 -                                else              flags&=~C_FLAG;
  1.2722 -                                tempw<<=1;
  1.2723 -                                if (flags&C_FLAG) tempw|=1;
  1.2724 -                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
  1.2725 -                                else                            flags&=~V_FLAG;
  1.2726 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2727 -                                break;
  1.2728 -                                case 0x08: /*ROR w,1*/
  1.2729 -                                seteaw((tempw>>1)|(tempw<<15)); if (abrt) break;
  1.2730 -                                if (tempw&1) flags|=C_FLAG;
  1.2731 -                                else         flags&=~C_FLAG;
  1.2732 -                                tempw>>=1;
  1.2733 -                                if (flags&C_FLAG) tempw|=0x8000;
  1.2734 -                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
  1.2735 -                                else                           flags&=~V_FLAG;
  1.2736 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2737 -                                break;
  1.2738 -                                case 0x10: /*RCL w,1*/
  1.2739 -                                temp2=flags&C_FLAG;
  1.2740 -                                seteaw((tempw<<1)|temp2);       if (abrt) break;
  1.2741 -                                if (tempw&0x8000) flags|=C_FLAG;
  1.2742 -                                else              flags&=~C_FLAG;
  1.2743 -                                tempw<<=1;
  1.2744 -                                if (temp2) tempw|=1;
  1.2745 -                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
  1.2746 -                                else                            flags&=~V_FLAG;
  1.2747 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2748 -                                break;
  1.2749 -                                case 0x18: /*RCR w,1*/
  1.2750 -                                temp2=flags&C_FLAG;
  1.2751 -                                seteaw((tempw>>1)|(temp2?0x8000:0));      if (abrt) break;
  1.2752 -                                if (tempw&1) flags|=C_FLAG;
  1.2753 -                                else         flags&=~C_FLAG;
  1.2754 -                                tempw>>=1;
  1.2755 -                                if (temp2) tempw|=0x8000;
  1.2756 -                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
  1.2757 -                                else                           flags&=~V_FLAG;
  1.2758 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2759 -                                break;
  1.2760 -                                case 0x20: case 0x30: /*SHL w,1*/
  1.2761 -                                seteaw(tempw<<1);       if (abrt) break;
  1.2762 -                                setznp16(tempw<<1);
  1.2763 -                                if (tempw&0x8000) flags|=C_FLAG;
  1.2764 -                                if ((tempw^(tempw<<1))&0x8000) flags|=V_FLAG;
  1.2765 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2766 -                                break;
  1.2767 -                                case 0x28: /*SHR w,1*/
  1.2768 -                                seteaw(tempw>>1);       if (abrt) break;
  1.2769 -                                setznp16(tempw>>1);
  1.2770 -                                if (tempw&1) flags|=C_FLAG;
  1.2771 -                                if (tempw&0x8000) flags|=V_FLAG;
  1.2772 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2773 -                                break;
  1.2774 -                                case 0x38: /*SAR w,1*/
  1.2775 -                                seteaw((tempw>>1)|(tempw&0x8000)); if (abrt) break;
  1.2776 -                                setznp16((tempw>>1)|(tempw&0x8000));
  1.2777 -                                if (tempw&1) flags|=C_FLAG;
  1.2778 -                                cycles -= (mod == 3) ? 2 : 7;
  1.2779 -                                break;
  1.2780 -
  1.2781 -                                default:
  1.2782 -                                pclog("Bad D1 opcode %02X\n",rmdat&0x38);
  1.2783 -                        }
  1.2784 -                        break;
  1.2785 -
  1.2786 -                        case 0xD2:
  1.2787 -                        fetchea();
  1.2788 -                        temp=geteab();  if (abrt) break;
  1.2789 -                        c=CL&31;
  1.2790 -//                        cycles-=c;
  1.2791 -                        if (!c) break;
  1.2792 -//                        if (c>7) pclog("Shiftb %i %02X\n",rmdat&0x38,c);
  1.2793 -                        cycles -= c;
  1.2794 -                        switch (rmdat&0x38)
  1.2795 -                        {
  1.2796 -                                case 0x00: /*ROL b,CL*/
  1.2797 -                                while (c>0)
  1.2798 -                                {
  1.2799 -                                        temp2=(temp&0x80)?1:0;
  1.2800 -                                        temp=(temp<<1)|temp2;
  1.2801 -                                        c--;
  1.2802 -                                }
  1.2803 -                                seteab(temp); if (abrt) break;
  1.2804 -                                flags&=~(C_FLAG|V_FLAG);
  1.2805 -                                if (temp2) flags|=C_FLAG;
  1.2806 -                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
  1.2807 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2808 -                                break;
  1.2809 -                                case 0x08: /*ROR b,CL*/
  1.2810 -                                while (c>0)
  1.2811 -                                {
  1.2812 -                                        temp2=temp&1;
  1.2813 -                                        temp>>=1;
  1.2814 -                                        if (temp2) temp|=0x80;
  1.2815 -                                        c--;
  1.2816 -                                }
  1.2817 -                                seteab(temp); if (abrt) break;
  1.2818 -                                flags&=~(C_FLAG|V_FLAG);
  1.2819 -                                if (temp2) flags|=C_FLAG;
  1.2820 -                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
  1.2821 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2822 -                                break;
  1.2823 -                                case 0x10: /*RCL b,CL*/
  1.2824 -                                tempc=flags&C_FLAG;
  1.2825 -                                while (c>0)
  1.2826 -                                {
  1.2827 -                                        templ=tempc;
  1.2828 -                                        tempc=temp&0x80;
  1.2829 -                                        temp<<=1;
  1.2830 -                                        if (templ) temp|=1;
  1.2831 -                                        c--;
  1.2832 -                                }
  1.2833 -                                seteab(temp); if (abrt) break;
  1.2834 -                                flags&=~(C_FLAG|V_FLAG);
  1.2835 -                                if (tempc) flags|=C_FLAG;
  1.2836 -                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
  1.2837 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2838 -                                break;
  1.2839 -                                case 0x18: /*RCR b,CL*/
  1.2840 -                                tempc=flags&C_FLAG;
  1.2841 -                                while (c>0)
  1.2842 -                                {
  1.2843 -                                        templ=tempc;
  1.2844 -                                        tempc=temp&1;
  1.2845 -                                        temp>>=1;
  1.2846 -                                        if (templ) temp|=0x80;
  1.2847 -                                        c--;
  1.2848 -                                }
  1.2849 -                                seteab(temp); if (abrt) break;
  1.2850 -                                flags&=~(C_FLAG|V_FLAG);
  1.2851 -                                if (tempc) flags|=C_FLAG;
  1.2852 -                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
  1.2853 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2854 -                                break;
  1.2855 -                                case 0x20: case 0x30: /*SHL b,CL*/
  1.2856 -                                seteab(temp<<c); if (abrt) break;
  1.2857 -                                setznp8(temp<<c);
  1.2858 -                                if ((temp<<(c-1))&0x80) flags|=C_FLAG;
  1.2859 -                                if (((temp<<c)^(temp<<(c-1)))&0x80) flags|=V_FLAG;
  1.2860 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2861 -                                break;
  1.2862 -                                case 0x28: /*SHR b,CL*/
  1.2863 -                                seteab(temp>>c); if (abrt) break;
  1.2864 -                                setznp8(temp>>c);
  1.2865 -                                if ((temp>>(c-1))&1) flags|=C_FLAG;
  1.2866 -                                if (c==1 && temp&0x80) flags|=V_FLAG;
  1.2867 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2868 -                                break;
  1.2869 -                                case 0x38: /*SAR b,CL*/
  1.2870 -                                tempc=(temp>>(c-1))&1;
  1.2871 -                                while (c>0)
  1.2872 -                                {
  1.2873 -                                        temp>>=1;
  1.2874 -                                        if (temp&0x40) temp|=0x80;
  1.2875 -                                        c--;
  1.2876 -                                }
  1.2877 -                                seteab(temp); if (abrt) break;
  1.2878 -                                setznp8(temp);
  1.2879 -                                if (tempc) flags|=C_FLAG;
  1.2880 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2881 -                                break;
  1.2882 -
  1.2883 -//                                default:
  1.2884 -//                                pclog("Bad D2 opcode %02X\n",rmdat&0x38);
  1.2885 -//                                dumpregs();
  1.2886 -//                                exit(-1);
  1.2887 -                        }
  1.2888 -                        break;
  1.2889 -
  1.2890 -                        case 0xD3:
  1.2891 -                        fetchea();
  1.2892 -                        tempw=geteaw(); if (abrt) break;
  1.2893 -                        c=CL&31;
  1.2894 -                        if (!c) break;
  1.2895 -                        cycles -= c;
  1.2896 -                        switch (rmdat&0x38)
  1.2897 -                        {
  1.2898 -                                case 0x00: /*ROL w,CL*/
  1.2899 -                                while (c>0)
  1.2900 -                                {
  1.2901 -                                        temp=(tempw&0x8000)?1:0;
  1.2902 -                                        tempw=(tempw<<1)|temp;
  1.2903 -                                        c--;
  1.2904 -                                }
  1.2905 -                                seteaw(tempw); if (abrt) break;
  1.2906 -                                flags&=~(C_FLAG|V_FLAG);
  1.2907 -                                if (temp) flags|=C_FLAG;
  1.2908 -                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
  1.2909 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2910 -                                break;
  1.2911 -                                case 0x08: /*ROR w,CL*/
  1.2912 -                                while (c>0)
  1.2913 -                                {
  1.2914 -                                        tempw2=(tempw&1)?0x8000:0;
  1.2915 -                                        tempw=(tempw>>1)|tempw2;
  1.2916 -                                        c--;
  1.2917 -                                }
  1.2918 -                                seteaw(tempw); if (abrt) break;
  1.2919 -                                flags&=~(C_FLAG|V_FLAG);
  1.2920 -                                if (tempw2) flags|=C_FLAG;
  1.2921 -                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
  1.2922 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2923 -                                break;
  1.2924 -                                case 0x10: /*RCL w,CL*/
  1.2925 -                                tempc=flags&C_FLAG;
  1.2926 -                                while (c>0)
  1.2927 -                                {
  1.2928 -                                        templ=tempc;
  1.2929 -                                        tempc=tempw&0x8000;
  1.2930 -                                        tempw=(tempw<<1)|templ;
  1.2931 -                                        c--;
  1.2932 -                                }
  1.2933 -                                seteaw(tempw); if (abrt) break;
  1.2934 -                                flags&=~(C_FLAG|V_FLAG);
  1.2935 -                                if (tempc) flags|=C_FLAG;
  1.2936 -                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
  1.2937 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2938 -                                break;
  1.2939 -                                case 0x18: /*RCR w,CL*/
  1.2940 -                                tempc=flags&C_FLAG;
  1.2941 -                                while (c>0)
  1.2942 -                                {
  1.2943 -                                        templ=tempc;
  1.2944 -                                        tempw2=(templ&1)?0x8000:0;
  1.2945 -                                        tempc=tempw&1;
  1.2946 -                                        tempw=(tempw>>1)|tempw2;
  1.2947 -                                        c--;
  1.2948 -                                }
  1.2949 -                                seteaw(tempw); if (abrt) break;
  1.2950 -                                flags&=~(C_FLAG|V_FLAG);
  1.2951 -                                if (tempc) flags|=C_FLAG;
  1.2952 -                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
  1.2953 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2954 -                                break;
  1.2955 -
  1.2956 -                                case 0x20: case 0x30: /*SHL w,CL*/
  1.2957 -                                seteaw(tempw<<c); if (abrt) break;
  1.2958 -                                setznp16(tempw<<c);
  1.2959 -                                if ((tempw<<(c-1))&0x8000) flags|=C_FLAG;
  1.2960 -                                if (((tempw<<c)^(tempw<<(c-1)))&0x8000) flags|=V_FLAG;
  1.2961 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2962 -                                break;
  1.2963 -
  1.2964 -                                case 0x28:            /*SHR w,CL*/
  1.2965 -                                seteaw(tempw>>c); if (abrt) break;
  1.2966 -                                setznp16(tempw>>c);
  1.2967 -                                if ((tempw>>(c-1))&1) flags|=C_FLAG;
  1.2968 -                                if (c==1 && tempw&0x8000) flags|=V_FLAG;
  1.2969 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2970 -                                break;
  1.2971 -
  1.2972 -                                case 0x38:            /*SAR w,CL*/
  1.2973 -                                tempw2=tempw&0x8000;
  1.2974 -                                tempc=((int16_t)tempw>>(c-1))&1;
  1.2975 -                                while (c>0)
  1.2976 -                                {
  1.2977 -                                        tempw=(tempw>>1)|tempw2;
  1.2978 -                                        c--;
  1.2979 -                                }
  1.2980 -                                seteaw(tempw); if (abrt) break;
  1.2981 -                                setznp16(tempw);
  1.2982 -                                if (tempc) flags|=C_FLAG;
  1.2983 -                                cycles -= (mod == 3) ? 5 : 8;
  1.2984 -                                break;
  1.2985 -
  1.2986 -//                                default:
  1.2987 -//                                pclog("Bad D3 opcode %02X\n",rmdat&0x38);
  1.2988 -//                                dumpregs();
  1.2989 -//                                exit(-1);
  1.2990 -                        }
  1.2991 -                        break;
  1.2992 -
  1.2993 -                        case 0xD4: /*AAM*/
  1.2994 -                        tempws=readmemb(cs,pc); pc++;
  1.2995 -                        AH=AL/tempws;
  1.2996 -                        AL%=tempws;
  1.2997 -                        setznp16(AX);
  1.2998 -                        cycles -= 16;
  1.2999 -                        break;
  1.3000 -                        case 0xD5: /*AAD*/
  1.3001 -                        tempws=readmemb(cs,pc); pc++;
  1.3002 -                        AL=(AH*tempws)+AL;
  1.3003 -                        AH=0;
  1.3004 -                        setznp16(AX);
  1.3005 -                        cycles -= 14;
  1.3006 -                        break;
  1.3007 -                        case 0xD6: /*SETALC*/
  1.3008 -                        AL=(flags&C_FLAG)?0xFF:0;
  1.3009 -                        cycles -= 3;
  1.3010 -                        break;
  1.3011 -                        case 0xD7: /*XLAT*/
  1.3012 -                        addr=(BX+AL)&0xFFFF;
  1.3013 -                        temp=readmemb(ds,addr); if (abrt) break;
  1.3014 -                        AL=temp;
  1.3015 -                        cycles -= 5;
  1.3016 -                        break;
  1.3017 -                        case 0xD9: case 0xDA: case 0xDB: case 0xDD:     /*ESCAPE*/
  1.3018 -                        case 0xD8:
  1.3019 -                        case 0xDC:
  1.3020 -                        case 0xDE:
  1.3021 -                        case 0xDF:
  1.3022 -                        if ((msw & 6) == 4)
  1.3023 -                        {
  1.3024 -                                pc=oldpc;
  1.3025 -                                pmodeint(7,0);
  1.3026 -                                cycles -= 40;
  1.3027 -                        }
  1.3028 -                        else
  1.3029 -                        {
  1.3030 -                                fetchea();
  1.3031 -                        }
  1.3032 -                        break;
  1.3033 -
  1.3034 -                        case 0xE0: /*LOOPNE*/
  1.3035 -                        offset=(int8_t)readmemb(cs,pc); pc++;
  1.3036 -                        CX--;
  1.3037 -                        if (CX && !(flags&Z_FLAG)) { pc+=offset; cycles -= 4; cycles -= 2; }
  1.3038 -                        cycles -= 4;
  1.3039 -                        break;
  1.3040 -                        case 0xE1: /*LOOPE*/
  1.3041 -                        offset=(int8_t)readmemb(cs,pc); pc++;
  1.3042 -                        CX--;
  1.3043 -                        if (CX && (flags&Z_FLAG)) { pc+=offset; cycles -= 4; cycles -= 2; }
  1.3044 -                        cycles -= 4;
  1.3045 -                        break;
  1.3046 -                        case 0xE2: /*LOOP*/
  1.3047 -                        offset=(int8_t)readmemb(cs,pc); pc++;
  1.3048 -                        CX--;
  1.3049 -                        if (CX) { pc+=offset; cycles -= 4; cycles -= 2; }
  1.3050 -                        cycles -= 4;
  1.3051 -                        break;
  1.3052 -                        case 0xE3: /*JCXZ*/
  1.3053 -                        offset=(int8_t)readmemb(cs,pc); pc++;
  1.3054 -                        if (!CX) { pc+=offset; cycles -= 4; cycles -= 2; }
  1.3055 -                        cycles-=4;
  1.3056 -                        break;
  1.3057 -
  1.3058 -                        case 0xE4: /*IN AL*/
  1.3059 -                        temp=readmemb(cs,pc);
  1.3060 -                        checkio_perm(temp);
  1.3061 -                        pc++;
  1.3062 -                        AL=inb(temp);
  1.3063 -                        cycles -= 5;
  1.3064 -                        break;
  1.3065 -                        case 0xE5: /*IN AX*/
  1.3066 -                        temp=readmemb(cs,pc);
  1.3067 -                        checkio_perm(temp);
  1.3068 -                        checkio_perm(temp+1);
  1.3069 -                        pc++;
  1.3070 -                        AX=inw(temp);
  1.3071 -                        cycles -= 5;
  1.3072 -                        break;
  1.3073 -                        case 0xE6: /*OUT AL*/
  1.3074 -                        temp=readmemb(cs,pc);
  1.3075 -                        checkio_perm(temp);
  1.3076 -                        pc++;
  1.3077 -                        outb(temp,AL);
  1.3078 -                        cycles -= 3;
  1.3079 -                        break;
  1.3080 -                        case 0xE7: /*OUT AX*/
  1.3081 -                        temp=readmemb(cs,pc);
  1.3082 -                        checkio_perm(temp);
  1.3083 -                        checkio_perm(temp+1);
  1.3084 -                        pc++;
  1.3085 -                        outw(temp,AX);
  1.3086 -                        cycles -= 3;
  1.3087 -                        break;
  1.3088 -
  1.3089 -                        case 0xE8: /*CALL rel 16*/
  1.3090 -                        tempw=getword(); if (abrt) break;
  1.3091 -                        if (ssegs) ss=oldss;
  1.3092 -                        writememw(ss,((SP-2)&0xFFFF),pc); if (abrt) break;
  1.3093 -                        SP-=2;
  1.3094 -                        pc+=(int16_t)tempw;
  1.3095 -                        cycles -= 7;
  1.3096 -                        break;
  1.3097 -                        case 0xE9: /*JMP rel 16*/
  1.3098 -                        tempw=getword(); if (abrt) break;
  1.3099 -                        pc+=(int16_t)tempw;
  1.3100 -                        cycles -= 7;
  1.3101 -                        break;
  1.3102 -                        case 0xEA: /*JMP far*/
  1.3103 -                        addr=getword();
  1.3104 -                        tempw=getword(); if (abrt) { if (output==3) pclog("JMP ABRT\n"); break; }
  1.3105 -                        oxpc=pc;
  1.3106 -                        pc=addr;
  1.3107 -                        loadcsjmp(tempw,oxpc);
  1.3108 -                        cycles -= 11;
  1.3109 -                        break;
  1.3110 -                        case 0xEB: /*JMP rel*/
  1.3111 -                        offset=(int8_t)readmemb(cs,pc); pc++;
  1.3112 -                        pc+=offset;
  1.3113 -                        cycles -= 7;
  1.3114 -                        break;
  1.3115 -                        case 0xEC: /*IN AL,DX*/
  1.3116 -                        checkio_perm(DX);
  1.3117 -                        AL=inb(DX);
  1.3118 -                        cycles -= 5;
  1.3119 -                        break;
  1.3120 -                        case 0xED: /*IN AX,DX*/
  1.3121 -                        checkio_perm(DX);
  1.3122 -                        checkio_perm(DX+1);
  1.3123 -                        AX=inw(DX);
  1.3124 -                        cycles -= 5;
  1.3125 -                        break;
  1.3126 -                        case 0xEE: /*OUT DX,AL*/
  1.3127 -                        checkio_perm(DX);
  1.3128 -                        outb(DX,AL);
  1.3129 -                        cycles -= 4;
  1.3130 -                        break;
  1.3131 -                        case 0xEF: /*OUT DX,AX*/
  1.3132 -                        checkio_perm(DX);
  1.3133 -                        checkio_perm(DX+1);
  1.3134 -                        outw(DX,AX);
  1.3135 -                        cycles -= 4;
  1.3136 -                        break;
  1.3137 -
  1.3138 -                        case 0xF0: /*LOCK*/
  1.3139 -                        break;
  1.3140 -
  1.3141 -                        case 0xF2: /*REPNE*/
  1.3142 -                        rep386(0);
  1.3143 -                        break;
  1.3144 -                        case 0xF3: /*REPE*/
  1.3145 -                        rep386(1);
  1.3146 -                        break;
  1.3147 -
  1.3148 -                        case 0xF4: /*HLT*/
  1.3149 -                        inhlt=1;
  1.3150 -                        pc--;
  1.3151 -                        cycles -= 2;
  1.3152 -/*                        if (!(flags & I_FLAG))
  1.3153 -                        {
  1.3154 -                                pclog("Complete HLT\n");
  1.3155 -                                dumpregs();
  1.3156 -                                exit(-1);
  1.3157 -                        }*/
  1.3158 -                        break;
  1.3159 -                        case 0xF5: /*CMC*/
  1.3160 -                        flags^=C_FLAG;
  1.3161 -                        cycles -= 2;
  1.3162 -                        break;
  1.3163 -
  1.3164 -                        case 0xF6:
  1.3165 -                        fetchea();
  1.3166 -                        temp=geteab(); if (abrt) break;
  1.3167 -                        switch (rmdat&0x38)
  1.3168 -                        {
  1.3169 -                                case 0x00: /*TEST b,#8*/
  1.3170 -                                temp2=readmemb(cs,pc); pc++; if (abrt) break;
  1.3171 -//                                pclog("TEST %02X,%02X\n",temp,temp2);
  1.3172 -/*                        if (cs==0x700 && !temp && temp2==0x10)
  1.3173 -                        {
  1.3174 -                                dumpregs();
  1.3175 -                                exit(-1);
  1.3176 -                        }*/
  1.3177 -                                temp&=temp2;
  1.3178 -                                setznp8(temp);
  1.3179 -                                cycles -= (mod == 3) ? 3 : 6;
  1.3180 -                                break;
  1.3181 -                                case 0x10: /*NOT b*/
  1.3182 -                                temp=~temp;
  1.3183 -                                seteab(temp);
  1.3184 -                                cycles -= (mod == 3) ? 2 : 7;
  1.3185 -                                break;
  1.3186 -                                case 0x18: /*NEG b*/
  1.3187 -                                setsub8(0,temp);
  1.3188 -                                temp=0-temp;
  1.3189 -                                seteab(temp);
  1.3190 -                                cycles -= (mod == 3) ? 2 : 7;
  1.3191 -                                break;
  1.3192 -                                case 0x20: /*MUL AL,b*/
  1.3193 -//                                setznp8(AL);
  1.3194 -                                AX=AL*temp;
  1.3195 -//                                if (AX) flags&=~Z_FLAG;
  1.3196 -//                                else    flags|=Z_FLAG;
  1.3197 -                                if (AH) flags|=(C_FLAG|V_FLAG);
  1.3198 -                                else    flags&=~(C_FLAG|V_FLAG);
  1.3199 -                                cycles -= (mod == 3) ? 13 : 16;
  1.3200 -                                break;
  1.3201 -                                case 0x28: /*IMUL AL,b*/
  1.3202 -//                                setznp8(AL);
  1.3203 -                                tempws=(int)((int8_t)AL)*(int)((int8_t)temp);
  1.3204 -                                AX=tempws&0xFFFF;
  1.3205 -//                                if (AX) flags&=~Z_FLAG;
  1.3206 -//                                else    flags|=Z_FLAG;
  1.3207 -                                if (AH && AH!=0xFF) flags|=(C_FLAG|V_FLAG);
  1.3208 -                                else                flags&=~(C_FLAG|V_FLAG);
  1.3209 -                                cycles -= (mod == 3) ? 13 : 16;
  1.3210 -                                break;
  1.3211 -                                case 0x30: /*DIV AL,b*/
  1.3212 -                                tempw=AX;
  1.3213 -                                if (temp) tempw2=tempw/temp;
  1.3214 -//                                pclog("DIV %04X/%02X %04X:%04X\n",tempw,temp,CS,pc);
  1.3215 -                                if (temp && !(tempw2&0xFF00))
  1.3216 -                                {
  1.3217 -                                        tempw2=tempw%temp;
  1.3218 -                                        AH=tempw2;
  1.3219 -                                        tempw/=temp;
  1.3220 -                                        AL=tempw&0xFF;
  1.3221 -                                        flags|=0x8D5; /*Not a Cyrix*/
  1.3222 -                                }
  1.3223 -                                else
  1.3224 -                                {
  1.3225 -                                        pclog("DIVb BY 0 %04X:%04X\n",cs>>4,pc);
  1.3226 -                                        pc=oldpc;
  1.3227 -                                        if (msw&1) pmodeint(0,0);
  1.3228 -                                        else
  1.3229 -                                        {
  1.3230 -//                                        pclog("%04X:%04X\n",cs>>4,pc);
  1.3231 -                                                writememw(ss,(SP-2)&0xFFFF,flags);
  1.3232 -                                                writememw(ss,(SP-4)&0xFFFF,CS);
  1.3233 -                                                writememw(ss,(SP-6)&0xFFFF,pc);
  1.3234 -                                                SP-=6;
  1.3235 -                                                flags&=~I_FLAG;
  1.3236 -                                                oxpc=pc;
  1.3237 -                                                pc=readmemw(0,0);
  1.3238 -                                                loadcs(readmemw(0,2));
  1.3239 -                                        }
  1.3240 -//                                                cs=loadcs(CS);
  1.3241 -//                                                cs=CS<<4;
  1.3242 -//                                        pclog("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x30);
  1.3243 -//                                        dumpregs();
  1.3244 -//                                        exit(-1);
  1.3245 -                                }
  1.3246 -                                cycles -= (mod == 3) ? 14 : 17;
  1.3247 -                                break;
  1.3248 -                                case 0x38: /*IDIV AL,b*/
  1.3249 -//                                pclog("IDIV %04X/%02X\n",tempw,temp);
  1.3250 -                                tempws=(int)(int16_t)AX;
  1.3251 -                                if (temp!=0) tempws2=tempws/(int)((int8_t)temp);
  1.3252 -                                temps=tempws2&0xFF;
  1.3253 -                                if ((temp!=0) && ((int)temps==tempws2))
  1.3254 -                                {
  1.3255 -                                        tempw2=tempws%(int)((int8_t)temp);
  1.3256 -                                        AH=tempw2&0xFF;
  1.3257 -                                        AL=tempws2&0xFF;
  1.3258 -                                        if (!cpu_iscyrix) flags|=0x8D5; /*Not a Cyrix*/
  1.3259 -                                }
  1.3260 -                                else
  1.3261 -                                {
  1.3262 -                                        pclog("IDIVb exception - %X / %08X = %X\n",tempws,temp,tempws2);
  1.3263 -//                                        pclog("IDIVb BY 0 %04X:%04X\n",cs>>4,pc);
  1.3264 -                                        pc=oldpc;
  1.3265 -                                        if (msw&1) pmodeint(0,0);
  1.3266 -                                        else
  1.3267 -                                        {
  1.3268 -                                                writememw(ss,(SP-2)&0xFFFF,flags);
  1.3269 -                                                writememw(ss,(SP-4)&0xFFFF,CS);
  1.3270 -                                                writememw(ss,(SP-6)&0xFFFF,pc);
  1.3271 -                                                SP-=6;
  1.3272 -                                                flags&=~I_FLAG;
  1.3273 -                                                oxpc=pc;
  1.3274 -                                                pc=readmemw(0,0);
  1.3275 -                                                loadcs(readmemw(0,2));
  1.3276 -                                        }
  1.3277 -//                                                cs=loadcs(CS);
  1.3278 -//                                                cs=CS<<4;
  1.3279 -//                                        pclog("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x38);
  1.3280 -                                }
  1.3281 -                                cycles -= (mod == 3) ? 17 : 20;
  1.3282 -                                break;
  1.3283 -
  1.3284 -                                default:
  1.3285 -                                pclog("Bad F6 opcode %02X\n",rmdat&0x38);
  1.3286 -                                x86illegal();
  1.3287 -//                                dumpregs();
  1.3288 -//                                exit(-1);
  1.3289 -                        }
  1.3290 -                        break;
  1.3291 -
  1.3292 -                        case 0xF7:
  1.3293 -                        fetchea();
  1.3294 -                        tempw=geteaw(); if (abrt) break;
  1.3295 -                        switch (rmdat&0x38)
  1.3296 -                        {
  1.3297 -                                case 0x00: /*TEST w*/
  1.3298 -                                tempw2=getword(); if (abrt) break;
  1.3299 -//                                if (output==3) pclog("TEST %04X %04X\n",tempw,tempw2);
  1.3300 -                                setznp16(tempw&tempw2);
  1.3301 -                                cycles -= (mod == 3) ? 3 : 6;
  1.3302 -                                break;
  1.3303 -                                case 0x10: /*NOT w*/
  1.3304 -                                seteaw(~tempw);
  1.3305 -                                cycles -= (mod == 3) ? 2 : 7;
  1.3306 -                                break;
  1.3307 -                                case 0x18: /*NEG w*/
  1.3308 -                                setsub16(0,tempw);
  1.3309 -                                tempw=0-tempw;
  1.3310 -                                seteaw(tempw);
  1.3311 -                                cycles -= (mod == 3) ? 2 : 7;
  1.3312 -                                break;
  1.3313 -                                case 0x20: /*MUL AX,w*/
  1.3314 -//                                setznp16(AX);
  1.3315 -                                templ=AX*tempw;
  1.3316 -                                AX=templ&0xFFFF;
  1.3317 -                                DX=templ>>16;
  1.3318 -//                                if (AX|DX) flags&=~Z_FLAG;
  1.3319 -//                                else       flags|=Z_FLAG;
  1.3320 -                                if (DX)    flags|=(C_FLAG|V_FLAG);
  1.3321 -                                else       flags&=~(C_FLAG|V_FLAG);
  1.3322 -                                cycles -= (mod == 3) ? 21 : 24;
  1.3323 -                                break;
  1.3324 -                                case 0x28: /*IMUL AX,w*/
  1.3325 -                                templ=(int)((int16_t)AX)*(int)((int16_t)tempw);
  1.3326 -                                AX=templ&0xFFFF;
  1.3327 -                                DX=templ>>16;
  1.3328 -                                if (DX && DX!=0xFFFF) flags|=(C_FLAG|V_FLAG);
  1.3329 -                                else                  flags&=~(C_FLAG|V_FLAG);
  1.3330 -                                cycles -= (mod == 3) ? 21 : 24;
  1.3331 -                                break;
  1.3332 -                                case 0x30: /*DIV AX,w*/
  1.3333 -                                templ=(DX<<16)|AX;
  1.3334 -                                if (tempw) templ2=templ/tempw;
  1.3335 -                                if (tempw && !(templ2&0xFFFF0000))
  1.3336 -                                {
  1.3337 -                                        tempw2=templ%tempw;
  1.3338 -                                        DX=tempw2;
  1.3339 -                                        templ/=tempw;
  1.3340 -                                        AX=templ&0xFFFF;
  1.3341 -                                        if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/
  1.3342 -                                }
  1.3343 -                                else
  1.3344 -                                {
  1.3345 -//                                        AX=DX=0;
  1.3346 -//                                        break;
  1.3347 -                                        pclog("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins);
  1.3348 -//                                        dumpregs();
  1.3349 -//                                        exit(-1);
  1.3350 -                                        pc=oldpc;
  1.3351 -                                        if (msw&1) pmodeint(0,0);
  1.3352 -                                        else
  1.3353 -                                        {
  1.3354 -//                                        pclog("%04X:%04X\n",cs>>4,pc);
  1.3355 -                                                writememw(ss,(SP-2)&0xFFFF,flags);
  1.3356 -                                                writememw(ss,(SP-4)&0xFFFF,CS);
  1.3357 -                                                writememw(ss,(SP-6)&0xFFFF,pc);
  1.3358 -                                                SP-=6;
  1.3359 -                                                flags&=~I_FLAG;
  1.3360 -                                                oxpc=pc;
  1.3361 -                                                pc=readmemw(0,0);
  1.3362 -                                                loadcs(readmemw(0,2));
  1.3363 -                                        }
  1.3364 -//                                                cs=loadcs(CS);
  1.3365 -//                                                cs=CS<<4;
  1.3366 -//                                        pclog("Div by zero %04X:%04X %02X %02X 1\n",cs>>4,pc,0xf7,0x30);
  1.3367 -                                }
  1.3368 -                                cycles -= (mod == 3) ? 22 : 25;
  1.3369 -                                break;
  1.3370 -                                case 0x38: /*IDIV AX,w*/
  1.3371 -                                tempws=(int)((DX<<16)|AX);
  1.3372 -                                if (tempw!=0) tempws2=tempws/(int)((int16_t)tempw);
  1.3373 -                                temps16=tempws2&0xFFFF;
  1.3374 -//                                pclog("IDIV %i %i ",tempws,tempw);
  1.3375 -                                if ((tempw!=0) && ((int)temps16==tempws2))
  1.3376 -                                {
  1.3377 -                                        DX=tempws%(int)((int16_t)tempw);
  1.3378 -                                        AX=tempws2&0xFFFF;
  1.3379 -                                        if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/
  1.3380 -                                }
  1.3381 -                                else
  1.3382 -                                {
  1.3383 -                                        pclog("IDIVw exception - %X / %08X = %X\n",tempws,tempw,tempws2);
  1.3384 -//                                        pclog("IDIVw BY 0 %04X:%04X\n",cs>>4,pc);
  1.3385 -//                                        DX=0;
  1.3386 -//                                        AX=0xFFFF;
  1.3387 -                                        pc=oldpc;
  1.3388 -                                        if (msw&1) pmodeint(0,0);
  1.3389 -                                        else
  1.3390 -                                        {
  1.3391 -//                                        pclog("%04X:%04X\n",cs>>4,pc);
  1.3392 -                                                writememw(ss,(SP-2)&0xFFFF,flags);
  1.3393 -                                                writememw(ss,(SP-4)&0xFFFF,CS);
  1.3394 -                                                writememw(ss,(SP-6)&0xFFFF,pc);
  1.3395 -                                                SP-=6;
  1.3396 -                                                flags&=~I_FLAG;
  1.3397 -                                                oxpc=pc;
  1.3398 -                                                pc=readmemw(0,0);
  1.3399 -                                                loadcs(readmemw(0,2));
  1.3400 -                                        }
  1.3401 -//                                                cs=loadcs(CS);
  1.3402 -//                                                cs=CS<<4;
  1.3403 -//                                        pclog("Div by zero %04X:%04X %02X %02X 1\n",cs>>4,pc,0xf7,0x38);
  1.3404 -                                }
  1.3405 -                                cycles -= (mod == 3) ? 25 : 28;
  1.3406 -                                break;
  1.3407 -
  1.3408 -                                default:
  1.3409 -                                pclog("Bad F7 opcode %02X\n",rmdat&0x38);
  1.3410 -                                x86illegal();
  1.3411 -//                                dumpregs();
  1.3412 -//                                exit(-1);
  1.3413 -                        }
  1.3414 -                        break;
  1.3415 -
  1.3416 -                        case 0xF8: /*CLC*/
  1.3417 -                        flags&=~C_FLAG;
  1.3418 -                        cycles -= 2;
  1.3419 -                        break;
  1.3420 -                        case 0xF9: /*STC*/
  1.3421 -//                        pclog("STC %04X\n",pc);
  1.3422 -                        flags|=C_FLAG;
  1.3423 -                        cycles -= 2;
  1.3424 -                        break;
  1.3425 -                        case 0xFA: /*CLI*/
  1.3426 -                        if (!IOPLp)
  1.3427 -                        {
  1.3428 -                                x86gpf(NULL,0);
  1.3429 -                        }
  1.3430 -                        else
  1.3431 -                           flags&=~I_FLAG;
  1.3432 -                        cycles -= 3;
  1.3433 -                        break;
  1.3434 -                        case 0xFB: /*STI*/
  1.3435 -                        if (!IOPLp)
  1.3436 -                        {
  1.3437 -                                x86gpf(NULL,0);
  1.3438 -                        }
  1.3439 -                        else
  1.3440 -                           flags|=I_FLAG;
  1.3441 -                        cycles -= 2;
  1.3442 -                        break;
  1.3443 -                        case 0xFC: /*CLD*/
  1.3444 -                        flags&=~D_FLAG;
  1.3445 -                        cycles -= 2;
  1.3446 -                        break;
  1.3447 -                        case 0xFD: /*STD*/
  1.3448 -                        flags|=D_FLAG;
  1.3449 -                        cycles -= 2;
  1.3450 -                        break;
  1.3451 -
  1.3452 -                        case 0xFE: /*INC/DEC b*/
  1.3453 -                        fetchea();
  1.3454 -                        temp=geteab(); if (abrt) break;
  1.3455 -                        if (rmdat&0x38)
  1.3456 -                        {
  1.3457 -                                seteab(temp-1); if (abrt) break;
  1.3458 -                                flags&=~V_FLAG;
  1.3459 -                                setsub8nc(temp,1);
  1.3460 -                                temp2=temp-1;
  1.3461 -                                if ((temp&0x80) && !(temp2&0x80)) flags|=V_FLAG;
  1.3462 -                        }
  1.3463 -                        else
  1.3464 -                        {
  1.3465 -                                seteab(temp+1); if (abrt) break;
  1.3466 -                                flags&=~V_FLAG;
  1.3467 -                                setadd8nc(temp,1);
  1.3468 -                                temp2=temp+1;
  1.3469 -                                if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG;
  1.3470 -                        }
  1.3471 -                        cycles -= (mod == 3) ? 2 : 7;
  1.3472 -                        break;
  1.3473 -
  1.3474 -                        case 0xFF:
  1.3475 -                        fetchea();
  1.3476 -                        switch (rmdat&0x38)
  1.3477 -                        {
  1.3478 -                                case 0x00: /*INC w*/
  1.3479 -                                tempw=geteaw();  if (abrt) break;
  1.3480 -                                seteaw(tempw+1); if (abrt) break;
  1.3481 -                                setadd16nc(tempw,1);
  1.3482 -                                cycles -= (mod == 3) ? 2 : 7;
  1.3483 -                                break;
  1.3484 -                                case 0x08: /*DEC w*/
  1.3485 -                                tempw=geteaw();  if (abrt) break;
  1.3486 -                                seteaw(tempw-1); if (abrt) break;
  1.3487 -                                setsub16nc(tempw,1);
  1.3488 -                                cycles -= (mod == 3) ? 2 : 7;
  1.3489 -                                break;
  1.3490 -                                case 0x10: /*CALL*/
  1.3491 -                                tempw=geteaw();
  1.3492 -                                if (abrt) break;
  1.3493 -                                if (ssegs) ss=oldss;
  1.3494 -                                writememw(ss,(SP-2)&0xFFFF,pc); if (abrt) break;
  1.3495 -                                SP-=2;
  1.3496 -                                pc=tempw;
  1.3497 -                                cycles -= (mod == 3) ? 7 : 11;
  1.3498 -                                break;
  1.3499 -                                case 0x18: /*CALL far*/
  1.3500 -                                tempw=readmemw(easeg,eaaddr);
  1.3501 -                                tempw2=readmemw(easeg,(eaaddr+2)); if (output==3) pclog("CALL FAR %04X:%04X\n",tempw,tempw2); if (abrt) break;
  1.3502 -                                tempw3=CS;
  1.3503 -                                templ2=pc;
  1.3504 -                                if (ssegs) ss=oldss;
  1.3505 -                                oxpc=pc;
  1.3506 -                                pc=tempw;
  1.3507 -                                optype=CALL;
  1.3508 -                                if (msw&1) loadcscall(tempw2);
  1.3509 -                                else       loadcs(tempw2);
  1.3510 -                                optype=0;
  1.3511 -                                if (abrt) break;
  1.3512 -                                oldss=ss;
  1.3513 -                                writememw(ss,(SP-2)&0xFFFF,tempw3);
  1.3514 -                                writememw(ss,((SP-4)&0xFFFF),templ2);
  1.3515 -                                SP-=4;
  1.3516 -                                cycles -= 16;
  1.3517 -                                break;
  1.3518 -                                case 0x20: /*JMP*/
  1.3519 -                                tempw=geteaw(); if (abrt) break;
  1.3520 -                                pc=tempw;
  1.3521 -                                cycles -= (mod == 3) ? 7 : 11;
  1.3522 -                                break;
  1.3523 -                                case 0x28: /*JMP far*/
  1.3524 -                                oxpc=pc;
  1.3525 -                                tempw=readmemw(easeg,eaaddr);
  1.3526 -                                tempw2=readmemw(easeg,eaaddr+2); if (abrt) break;
  1.3527 -                                pc=tempw;                                
  1.3528 -                                loadcsjmp(tempw2,oxpc); if (abrt) break;
  1.3529 -                                cycles -= 15;
  1.3530 -                                break;
  1.3531 -                                case 0x30: /*PUSH w*/
  1.3532 -                                tempw=geteaw(); if (abrt) break;
  1.3533 -                                if (ssegs) ss=oldss;
  1.3534 -                                writememw(ss,((SP-2)&0xFFFF),tempw); if (abrt) break;
  1.3535 -                                SP-=2;
  1.3536 -                                cycles -= (mod==3) ? 3 : 5;
  1.3537 -                                break;
  1.3538 -
  1.3539 -                                default:
  1.3540 -                                pclog("Bad FF opcode %02X\n",rmdat&0x38);
  1.3541 -                                x86illegal();
  1.3542 -                                //dumpregs();
  1.3543 -                                //exit(-1);
  1.3544 -                        }
  1.3545 -                        break;
  1.3546 -
  1.3547 -                        default:
  1.3548 -//                        pc--;
  1.3549 -//                        cycles-=8;
  1.3550 -//                        break;
  1.3551 -                        pclog("Bad opcode %02X at %04X:%04X from %04X:%04X %08X\n",opcode,cs>>4,pc,old8>>16,old8&0xFFFF,old82);
  1.3552 -                        x86illegal();
  1.3553 -//                        dumpregs();
  1.3554 -//                        exit(-1);
  1.3555 -                }
  1.3556 -                opcodeend:
  1.3557 -                pc&=0xFFFF;
  1.3558 -
  1.3559 -//                output = 3;
  1.3560 -/*                output = 3;
  1.3561 -                
  1.3562 -                if (pc == 0xcdd && CS == 0xf000)
  1.3563 -                {
  1.3564 -                        dumpregs();
  1.3565 -                        exit(-1);
  1.3566 -                }*/
  1.3567 -                //if (ins == 20768972) output = 3;
  1.3568 -                
  1.3569 -                if (ssegs)
  1.3570 -                {
  1.3571 -                        ds=oldds; _ds.limit=olddslimit; _ds.limitw=olddslimitw;
  1.3572 -                        ss=oldss; _ss.limit=oldsslimit; _ss.limitw=oldsslimitw;
  1.3573 -                        ssegs=0;
  1.3574 -                }
  1.3575 -                if (abrt)
  1.3576 -                {
  1.3577 -                        tempi = abrt;
  1.3578 -                        abrt = 0;
  1.3579 -                        x86_doabrt(tempi);
  1.3580 -                        if (abrt)
  1.3581 -                        {
  1.3582 -                                abrt = 0;
  1.3583 -                                CS = oldcs;
  1.3584 -                                pc = oldpc;
  1.3585 -                                pclog("Double fault\n");
  1.3586 -//                                dumpregs();
  1.3587 -//                                exit(-1);
  1.3588 -                                pmodeint(8, 0);
  1.3589 -                                if (abrt)
  1.3590 -                                {
  1.3591 -                                        abrt = 0;
  1.3592 -                                        softresetx86();
  1.3593 -                                        pclog("Triple fault - reset\n");
  1.3594 -                                }
  1.3595 -                        }
  1.3596 -                }
  1.3597 -                cycdiff-=cycles;
  1.3598 -
  1.3599 -                pit.c[0]-=cycdiff;
  1.3600 -                pit.c[1]-=cycdiff;
  1.3601 -                if (ppi.pb&1)         pit.c[2]-=cycdiff;
  1.3602 -
  1.3603 -                if ((pit.c[0]<1)||(pit.c[1]<1)||(pit.c[2]<1)) pit_poll();
  1.3604 -
  1.3605 -                spktime-=cycdiff;
  1.3606 -                if (spktime<=0.0)
  1.3607 -                {
  1.3608 -                        spktime+=SPKCONST;
  1.3609 -//                        pclog("1Poll spk\n");
  1.3610 -                        pollspk();
  1.3611 -                        pollgussamp();
  1.3612 -                        getsbsamp();
  1.3613 -                        polladlib();
  1.3614 -                        getdacsamp();
  1.3615 -//                        pclog("2Poll spk\n");
  1.3616 -                }
  1.3617 -                soundtime-=cycdiff;
  1.3618 -                if (soundtime<=0.0)
  1.3619 -                {
  1.3620 -                        soundtime+=SOUNDCONST;
  1.3621 -//                        pclog("1Poll sound60hz\n");
  1.3622 -                        pollsound60hz();
  1.3623 -//                        pclog("2Poll sound60hz\n");
  1.3624 -                }
  1.3625 -                gustime-=cycdiff;
  1.3626 -                while (gustime<=0.0)
  1.3627 -                {
  1.3628 -                        gustime+=GUSCONST;
  1.3629 -                        pollgus();
  1.3630 -                }
  1.3631 -                gustime2-=cycdiff;
  1.3632 -                while (gustime2<=0.0)
  1.3633 -                {
  1.3634 -                        gustime2+=GUSCONST2;
  1.3635 -                        pollgus2();
  1.3636 -                }
  1.3637 -                vidtime-=cycdiff;
  1.3638 -                if (vidtime<=0.0)
  1.3639 -                {
  1.3640 -//                        pclog("1Poll video\n");
  1.3641 -                        pollvideo();
  1.3642 -//                        pclog("2Poll video\n");
  1.3643 -                }
  1.3644 -                if (disctime)
  1.3645 -                {
  1.3646 -                        disctime-=cycdiff/4;
  1.3647 -                        if (disctime<=0)
  1.3648 -                        {
  1.3649 -//                                pclog("1Poll disc\n");
  1.3650 -                                disctime=0;
  1.3651 -                                fdc_poll();
  1.3652 -//                                pclog("2Poll disc\n");
  1.3653 -                        }
  1.3654 -                }
  1.3655 -                if (mousedelay)
  1.3656 -                {
  1.3657 -                        mousedelay-=20;
  1.3658 -                        if (!mousedelay)
  1.3659 -                        {
  1.3660 -//                                pclog("1Poll mouse\n");
  1.3661 -                                mousecallback();
  1.3662 -//                                pclog("2Poll disc\n");
  1.3663 -                        }
  1.3664 -                }
  1.3665 -                if (sbenable)
  1.3666 -                {
  1.3667 -                        sbcount-=cycdiff;
  1.3668 -                        if (sbcount<0)
  1.3669 -                        {
  1.3670 -                                sbcount+=sblatcho;
  1.3671 -                                pollsb();
  1.3672 -                        }
  1.3673 -                }
  1.3674 -                if (sb_enable_i)
  1.3675 -                {
  1.3676 -                        sb_count_i-=cycdiff;
  1.3677 -                        if (sb_count_i<0)
  1.3678 -                        {
  1.3679 -                                sb_count_i+=sblatchi;
  1.3680 -                                sb_poll_i();
  1.3681 -                        }
  1.3682 -                }
  1.3683 -                rtctime-=cycdiff;
  1.3684 -                if (rtctime<0)
  1.3685 -                {
  1.3686 -                        nvr_rtc();
  1.3687 -                }
  1.3688 -                if (idecallback[0])
  1.3689 -                {
  1.3690 -                        idecallback[0]--;
  1.3691 -                        if (idecallback[0]<=0)
  1.3692 -                        {
  1.3693 -//                                pclog("IDE time over\n");
  1.3694 -                                idecallback[0]=0;
  1.3695 -                                callbackide(0);
  1.3696 -                        }
  1.3697 -                }
  1.3698 -                if (idecallback[1])
  1.3699 -                {
  1.3700 -                        idecallback[1]--;
  1.3701 -                        if (idecallback[1]<=0)
  1.3702 -                        {
  1.3703 -//                                pclog("IDE time over\n");
  1.3704 -                                idecallback[1]=0;
  1.3705 -                                callbackide(1);
  1.3706 -                        }
  1.3707 -                }
  1.3708 -                if (trap && (flags&T_FLAG) && !noint)
  1.3709 -                {
  1.3710 -                        if (msw&1)
  1.3711 -                        {
  1.3712 -                                pmodeint(1,0);
  1.3713 -                                cycles -= 40;
  1.3714 -                        }
  1.3715 -                        else
  1.3716 -                        {
  1.3717 -                                writememw(ss,(SP-2)&0xFFFF,flags);
  1.3718 -                                writememw(ss,(SP-4)&0xFFFF,CS);
  1.3719 -                                writememw(ss,(SP-6)&0xFFFF,pc);
  1.3720 -                                SP-=6;
  1.3721 -                                addr=1<<2;
  1.3722 -                                flags&=~I_FLAG;
  1.3723 -                                flags&=~T_FLAG;
  1.3724 -                                pc=readmemw(0,addr);
  1.3725 -                                loadcs(readmemw(0,addr+2));
  1.3726 -                                cycles -= 23;
  1.3727 -                        }
  1.3728 -                }
  1.3729 -                else if ((flags&I_FLAG) && (((pic.pend&~pic.mask)&~pic.mask2) || ((pic2.pend&~pic2.mask)&~pic2.mask2)) && !ssegs && !noint)
  1.3730 -                {
  1.3731 -//                        pclog("Test %02X %02X %02X\n", pic.pend, pic.mask, pic.mask2);
  1.3732 -                        temp=picinterrupt();
  1.3733 -                        if (temp!=0xFF)
  1.3734 -                        {
  1.3735 -//                                pclog("286 int %02X %02X %02X %02X\n",temp, pic.pend, pic.mask, pic.mask2);
  1.3736 -                                if (inhlt) pc++;
  1.3737 -//                                intcount++;
  1.3738 -                                if (msw&1)
  1.3739 -                                {
  1.3740 -                                        pmodeint(temp,0);
  1.3741 -                                        cycles -= 40;
  1.3742 -                                }
  1.3743 -                                else
  1.3744 -                                {
  1.3745 -                                        writememw(ss,(SP-2)&0xFFFF,flags);
  1.3746 -                                        writememw(ss,(SP-4)&0xFFFF,CS);
  1.3747 -                                        writememw(ss,(SP-6)&0xFFFF,pc);
  1.3748 -                                        SP-=6;
  1.3749 -                                        addr=temp<<2;
  1.3750 -                                        flags&=~I_FLAG;
  1.3751 -                                        flags&=~T_FLAG;
  1.3752 -                                        pc=readmemw(0,addr);
  1.3753 -                                        loadcs(readmemw(0,addr+2));
  1.3754 -                                        cycles -= 23;
  1.3755 -                                }
  1.3756 -                                inint=1;
  1.3757 -                        }
  1.3758 -                }
  1.3759 -
  1.3760 -/*                if (pc==0xCC32 && es>0x180000)
  1.3761 -                {
  1.3762 -                        pc=0xCBEB;
  1.3763 -//                        output=1;
  1.3764 -//                        timetolive=500000;
  1.3765 -                }*/
  1.3766 -
  1.3767 -                if (noint) noint=0;
  1.3768 -                ins++;
  1.3769 -                insc++;
  1.3770 -                
  1.3771 -//                if (ins == 25000000) output = 3;
  1.3772 -/*                if (timetolive)
  1.3773 -                {
  1.3774 -                        timetolive--;
  1.3775 -                        if (!timetolive)
  1.3776 -                        {
  1.3777 -                                dumpregs();
  1.3778 -                                exit(-1);
  1.3779 -                        } //output=0;
  1.3780 -                }*/
  1.3781 -                keybsenddelay--;
  1.3782 -                if (keybsenddelay<1)
  1.3783 -                {
  1.3784 -                        keybsenddelay = 2500;
  1.3785 -                        keyboard_poll();
  1.3786 -                }
  1.3787 -                //output = 3;
  1.3788 -        }
  1.3789 -}
  1.3790 -//#endif
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/386.h	Mon May 27 19:56:33 2013 +0100
     2.3 @@ -0,0 +1,2 @@
     2.4 +extern void cpu_386_flags_extract();
     2.5 +extern void cpu_386_flags_rebuild();
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/386_ops.h	Mon May 27 19:56:33 2013 +0100
     3.3 @@ -0,0 +1,499 @@
     3.4 +#include "x86_ops.h"
     3.5 +
     3.6 +OpFn *x86_opcodes;
     3.7 +OpFn *x86_opcodes_0f;
     3.8 +
     3.9 +static inline void PUSH_W(uint16_t val)
    3.10 +{
    3.11 +        if (stack32)
    3.12 +        {
    3.13 +                writememw(ss, ESP - 2, val);              if (abrt) return;
    3.14 +                ESP -= 2;
    3.15 +        }
    3.16 +        else
    3.17 +        {
    3.18 +                writememw(ss, (SP - 2) & 0xFFFF, val);    if (abrt) return;
    3.19 +                SP -= 2;
    3.20 +        }
    3.21 +}
    3.22 +
    3.23 +static inline void PUSH_L(uint32_t val)
    3.24 +{
    3.25 +        if (stack32)
    3.26 +        {
    3.27 +                writememl(ss, ESP - 4, val);              if (abrt) return;
    3.28 +                ESP -= 4;
    3.29 +        }
    3.30 +        else
    3.31 +        {
    3.32 +                writememl(ss, (SP - 4) & 0xFFFF, val);    if (abrt) return;
    3.33 +                SP -= 4;
    3.34 +        }
    3.35 +}
    3.36 +
    3.37 +static inline uint16_t POP_W()
    3.38 +{
    3.39 +        uint16_t ret;
    3.40 +        if (stack32)
    3.41 +        {
    3.42 +                ret = readmemw(ss, ESP);                        if (abrt) return 0;
    3.43 +                ESP += 2;
    3.44 +        }
    3.45 +        else
    3.46 +        {
    3.47 +                ret = readmemw(ss, SP);                         if (abrt) return 0;
    3.48 +                SP += 2;
    3.49 +        }
    3.50 +        return ret;
    3.51 +}
    3.52 +
    3.53 +static inline uint32_t POP_L()
    3.54 +{
    3.55 +        uint32_t ret;
    3.56 +        if (stack32)
    3.57 +        {
    3.58 +                ret = readmeml(ss, ESP);                        if (abrt) return 0;
    3.59 +                ESP += 4;
    3.60 +        }
    3.61 +        else
    3.62 +        {
    3.63 +                ret = readmeml(ss, SP);                         if (abrt) return 0;
    3.64 +                SP += 4;
    3.65 +        }
    3.66 +        return ret;
    3.67 +}
    3.68 +
    3.69 +#include "x86_ops_arith.h"
    3.70 +#include "x86_ops_atomic.h"
    3.71 +#include "x86_ops_bcd.h"
    3.72 +#include "x86_ops_bit.h"
    3.73 +#include "x86_ops_bitscan.h"
    3.74 +#include "x86_ops_call.h"
    3.75 +#include "x86_ops_flag.h"
    3.76 +#include "x86_ops_fpu.h"
    3.77 +#include "x86_ops_inc_dec.h"
    3.78 +#include "x86_ops_int.h"
    3.79 +#include "x86_ops_io.h"
    3.80 +#include "x86_ops_jump.h"
    3.81 +#include "x86_ops_misc.h"
    3.82 +#include "x86_ops_mov.h"
    3.83 +#include "x86_ops_mov_ctrl.h"
    3.84 +#include "x86_ops_mov_seg.h"
    3.85 +#include "x86_ops_movx.h"
    3.86 +#include "x86_ops_msr.h"
    3.87 +#include "x86_ops_mul.h"
    3.88 +#include "x86_ops_pmode.h"
    3.89 +#include "x86_ops_prefix.h"
    3.90 +#include "x86_ops_rep.h"
    3.91 +#include "x86_ops_ret.h"
    3.92 +#include "x86_ops_set.h"
    3.93 +#include "x86_ops_shift.h"
    3.94 +#include "x86_ops_stack.h"
    3.95 +#include "x86_ops_string.h"
    3.96 +#include "x86_ops_xchg.h"
    3.97 +
    3.98 +static int ILLEGAL(uint32_t fetchdat)
    3.99 +{
   3.100 +        pc = oldpc;
   3.101 +        x86illegal();
   3.102 +        return 0;
   3.103 +}
   3.104 +
   3.105 +static int op0F_w_a16(uint32_t fetchdat)
   3.106 +{
   3.107 +        int opcode = fetchdat & 0xff;
   3.108 +        pc++;
   3.109 +        
   3.110 +        return x86_opcodes_0f[opcode](fetchdat >> 8);
   3.111 +}
   3.112 +static int op0F_l_a16(uint32_t fetchdat)
   3.113 +{
   3.114 +        int opcode = fetchdat & 0xff;
   3.115 +        pc++;
   3.116 +        
   3.117 +        return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8);
   3.118 +}
   3.119 +static int op0F_w_a32(uint32_t fetchdat)
   3.120 +{
   3.121 +        int opcode = fetchdat & 0xff;
   3.122 +        pc++;
   3.123 +        
   3.124 +        return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8);
   3.125 +}
   3.126 +static int op0F_l_a32(uint32_t fetchdat)
   3.127 +{
   3.128 +        int opcode = fetchdat & 0xff;
   3.129 +        pc++;
   3.130 +        
   3.131 +        return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
   3.132 +}
   3.133 +
   3.134 +void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f)
   3.135 +{
   3.136 +        x86_opcodes = opcodes;
   3.137 +        x86_opcodes_0f = opcodes_0f;
   3.138 +}
   3.139 +        
   3.140 +OpFn ops_286_0f[1024] = 
   3.141 +{
   3.142 +        /*16-bit data, 16-bit addr*/
   3.143 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.144 +/*00*/  op0F00_a16,     op0F01_w_a16,   opLAR_w_a16,    opLSL_w_a16,    ILLEGAL,        opLOADALL,      opCLTS,         ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.145 +/*10*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.146 +/*20*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.147 +/*30*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.148 +
   3.149 +/*40*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.150 +/*50*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.151 +/*60*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.152 +/*70*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.153 +
   3.154 +/*80*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.155 +/*90*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.156 +/*a0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.157 +/*b0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.158 +
   3.159 +/*c0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.160 +/*d0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.161 +/*e0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.162 +/*f0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.163 +
   3.164 +        /*32-bit data, 16-bit addr*/
   3.165 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.166 +/*00*/  op0F00_a16,     op0F01_w_a16,   opLAR_w_a16,    opLSL_w_a16,    ILLEGAL,        opLOADALL,      opCLTS,         ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.167 +/*10*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.168 +/*20*/  opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.169 +/*30*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.170 +
   3.171 +/*40*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.172 +/*50*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.173 +/*60*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.174 +/*70*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.175 +
   3.176 +/*80*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.177 +/*90*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.178 +/*a0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.179 +/*b0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.180 +
   3.181 +/*c0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.182 +/*d0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.183 +/*e0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.184 +/*f0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.185 +
   3.186 +        /*16-bit data, 32-bit addr*/
   3.187 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.188 +/*00*/  op0F00_a16,     op0F01_w_a16,   opLAR_w_a16,    opLSL_w_a16,    ILLEGAL,        opLOADALL,      opCLTS,         ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.189 +/*10*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.190 +/*20*/  opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.191 +/*30*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.192 +
   3.193 +/*40*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.194 +/*50*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.195 +/*60*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.196 +/*70*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.197 +
   3.198 +/*80*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.199 +/*90*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.200 +/*a0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.201 +/*b0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.202 +
   3.203 +/*c0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.204 +/*d0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.205 +/*e0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.206 +/*f0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.207 +
   3.208 +        /*32-bit data, 32-bit addr*/
   3.209 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.210 +/*00*/  op0F00_a16,     op0F01_w_a16,   opLAR_w_a16,    opLSL_w_a16,    ILLEGAL,        opLOADALL,      opCLTS,         ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.211 +/*10*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.212 +/*20*/  opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.213 +/*30*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.214 +
   3.215 +/*40*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.216 +/*50*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.217 +/*60*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.218 +/*70*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.219 +
   3.220 +/*80*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.221 +/*90*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.222 +/*a0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.223 +/*b0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.224 +
   3.225 +/*c0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.226 +/*d0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.227 +/*e0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.228 +/*f0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.229 +};
   3.230 +
   3.231 +OpFn ops_386_0f[1024] = 
   3.232 +{
   3.233 +        /*16-bit data, 16-bit addr*/
   3.234 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.235 +/*00*/  op0F00_a16,     op0F01_w_a16,   opLAR_w_a16,    opLSL_w_a16,    ILLEGAL,        opLOADALL,      opCLTS,         ILLEGAL,        opINVD,         opWBINVD,       ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.236 +/*10*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.237 +/*20*/  opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.238 +/*30*/  ILLEGAL,        opRDTSC,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.239 +
   3.240 +/*40*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.241 +/*50*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.242 +/*60*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.243 +/*70*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.244 +
   3.245 +/*80*/  opJO_w,         opJNO_w,        opJB_w,         opJNB_w,        opJE_w,         opJNE_w,        opJBE_w,        opJNBE_w,       opJS_w,         opJNS_w,        opJP_w,         opJNP_w,        opJL_w,         opJNL_w,        opJLE_w,        opJNLE_w,
   3.246 +/*90*/  opSETO_a16,     opSETNO_a16,    opSETB_a16,     opSETNB_a16,    opSETE_a16,     opSETNE_a16,    opSETBE_a16,    opSETNBE_a16,   opSETS_a16,     opSETNS_a16,    opSETP_a16,     opSETNP_a16,    opSETL_a16,     opSETNL_a16,    opSETLE_a16,    opSETNLE_a16,
   3.247 +/*a0*/  opPUSH_FS_w,    opPOP_FS_w,     opCPUID,        opBT_w_r_a16,   opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL,        ILLEGAL,        opPUSH_GS_w,    opPOP_GS_w,     ILLEGAL,        opBTS_w_r_a16,  opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL,        opIMUL_w_w_a16,
   3.248 +/*b0*/  opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16,    opBTR_w_r_a16,  opLFS_w_a16,    opLGS_w_a16,    opMOVZX_w_b_a16,ILLEGAL,        ILLEGAL,        ILLEGAL,        opBA_w_a16,     opBTC_w_r_a16,  opBSF_w_a16,    opBSR_w_a16,    opMOVSX_w_b_a16,ILLEGAL,
   3.249 +
   3.250 +/*c0*/  opXADD_b_a16,   opXADD_w_a16,   ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opBSWAP_EAX,    opBSWAP_ECX,    opBSWAP_EDX,    opBSWAP_EBX,    opBSWAP_ESP,    opBSWAP_EBP,    opBSWAP_ESI,    opBSWAP_EDI,
   3.251 +/*d0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.252 +/*e0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.253 +/*f0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.254 +
   3.255 +        /*32-bit data, 16-bit addr*/
   3.256 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.257 +/*00*/  op0F00_a16,     op0F01_l_a16,   opLAR_l_a16,    opLSL_l_a16,    ILLEGAL,        opLOADALL,      opCLTS,         ILLEGAL,        opINVD,         opWBINVD,       ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.258 +/*10*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.259 +/*20*/  opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.260 +/*30*/  ILLEGAL,        opRDTSC,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.261 +
   3.262 +/*40*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.263 +/*50*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.264 +/*60*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.265 +/*70*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.266 +
   3.267 +/*80*/  opJO_l,         opJNO_l,        opJB_l,         opJNB_l,        opJE_l,         opJNE_l,        opJBE_l,        opJNBE_l,       opJS_l,         opJNS_l,        opJP_l,         opJNP_l,        opJL_l,         opJNL_l,        opJLE_l,        opJNLE_l,
   3.268 +/*90*/  opSETO_a16,     opSETNO_a16,    opSETB_a16,     opSETNB_a16,    opSETE_a16,     opSETNE_a16,    opSETBE_a16,    opSETNBE_a16,   opSETS_a16,     opSETNS_a16,    opSETP_a16,     opSETNP_a16,    opSETL_a16,     opSETNL_a16,    opSETLE_a16,    opSETNLE_a16,
   3.269 +/*a0*/  opPUSH_FS_l,    opPOP_FS_l,     opCPUID,        opBT_l_r_a16,   opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL,        ILLEGAL,        opPUSH_GS_l,    opPOP_GS_l,     ILLEGAL,        opBTS_l_r_a16,  opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL,        opIMUL_l_l_a16,
   3.270 +/*b0*/  opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16,    opBTR_l_r_a16,  opLFS_l_a16,    opLGS_l_a16,    opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL,        ILLEGAL,        opBA_l_a16,     opBTC_l_r_a16,  opBSF_l_a16,    opBSR_l_a16,    opMOVSX_l_b_a16,opMOVSX_l_w_a16,
   3.271 +
   3.272 +/*c0*/  opXADD_b_a16,   opXADD_l_a16,   ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opBSWAP_EAX,    opBSWAP_ECX,    opBSWAP_EDX,    opBSWAP_EBX,    opBSWAP_ESP,    opBSWAP_EBP,    opBSWAP_ESI,    opBSWAP_EDI,
   3.273 +/*d0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.274 +/*e0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.275 +/*f0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.276 +
   3.277 +        /*16-bit data, 32-bit addr*/
   3.278 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.279 +/*00*/  op0F00_a32,     op0F01_w_a32,   opLAR_w_a32,    opLSL_w_a32,    ILLEGAL,        opLOADALL,      opCLTS,         ILLEGAL,        opINVD,         opWBINVD,       ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.280 +/*10*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.281 +/*20*/  opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.282 +/*30*/  ILLEGAL,        opRDTSC,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.283 +
   3.284 +/*40*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.285 +/*50*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.286 +/*60*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.287 +/*70*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.288 +
   3.289 +/*80*/  opJO_w,         opJNO_w,        opJB_w,         opJNB_w,        opJE_w,         opJNE_w,        opJBE_w,        opJNBE_w,       opJS_w,         opJNS_w,        opJP_w,         opJNP_w,        opJL_w,         opJNL_w,        opJLE_w,        opJNLE_w,
   3.290 +/*90*/  opSETO_a32,     opSETNO_a32,    opSETB_a32,     opSETNB_a32,    opSETE_a32,     opSETNE_a32,    opSETBE_a32,    opSETNBE_a32,   opSETS_a32,     opSETNS_a32,    opSETP_a32,     opSETNP_a32,    opSETL_a32,     opSETNL_a32,    opSETLE_a32,    opSETNLE_a32,
   3.291 +/*a0*/  opPUSH_FS_w,    opPOP_FS_w,     opCPUID,        opBT_w_r_a32,   opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL,        ILLEGAL,        opPUSH_GS_w,    opPOP_GS_w,     ILLEGAL,        opBTS_w_r_a32,  opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL,        opIMUL_w_w_a32,
   3.292 +/*b0*/  opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32,    opBTR_w_r_a32,  opLFS_w_a32,    opLGS_w_a32,    opMOVZX_w_b_a32,ILLEGAL,        ILLEGAL,        ILLEGAL,        opBA_w_a32,     opBTC_w_r_a32,  opBSF_w_a32,    opBSR_w_a32,    opMOVSX_w_b_a32,ILLEGAL,
   3.293 +
   3.294 +/*c0*/  opXADD_b_a32,   opXADD_w_a32,   ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opBSWAP_EAX,    opBSWAP_ECX,    opBSWAP_EDX,    opBSWAP_EBX,    opBSWAP_ESP,    opBSWAP_EBP,    opBSWAP_ESI,    opBSWAP_EDI,
   3.295 +/*d0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.296 +/*e0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.297 +/*f0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.298 +
   3.299 +        /*32-bit data, 32-bit addr*/
   3.300 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.301 +/*00*/  op0F00_a32,     op0F01_l_a32,   opLAR_l_a32,    opLSL_l_a32,    ILLEGAL,        opLOADALL,      opCLTS,         ILLEGAL,        opINVD,         opWBINVD,       ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.302 +/*10*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.303 +/*20*/  opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.304 +/*30*/  ILLEGAL,        opRDTSC,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.305 +
   3.306 +/*40*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.307 +/*50*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.308 +/*60*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.309 +/*70*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.310 +
   3.311 +/*80*/  opJO_l,         opJNO_l,        opJB_l,         opJNB_l,        opJE_l,         opJNE_l,        opJBE_l,        opJNBE_l,       opJS_l,         opJNS_l,        opJP_l,         opJNP_l,        opJL_l,         opJNL_l,        opJLE_l,        opJNLE_l,
   3.312 +/*90*/  opSETO_a32,     opSETNO_a32,    opSETB_a32,     opSETNB_a32,    opSETE_a32,     opSETNE_a32,    opSETBE_a32,    opSETNBE_a32,   opSETS_a32,     opSETNS_a32,    opSETP_a32,     opSETNP_a32,    opSETL_a32,     opSETNL_a32,    opSETLE_a32,    opSETNLE_a32,
   3.313 +/*a0*/  opPUSH_FS_l,    opPOP_FS_l,     opCPUID,        opBT_l_r_a32,   opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL,        ILLEGAL,        opPUSH_GS_l,    opPOP_GS_l,     ILLEGAL,        opBTS_l_r_a32,  opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL,        opIMUL_l_l_a32,
   3.314 +/*b0*/  opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32,    opBTR_l_r_a32,  opLFS_l_a32,    opLGS_l_a32,    opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL,        ILLEGAL,        opBA_l_a32,     opBTC_l_r_a32,  opBSF_l_a32,    opBSR_l_a32,    opMOVSX_l_b_a32,opMOVSX_l_w_a32,
   3.315 +
   3.316 +/*c0*/  opXADD_b_a32,   opXADD_l_a32,   ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opBSWAP_EAX,    opBSWAP_ECX,    opBSWAP_EDX,    opBSWAP_EBX,    opBSWAP_ESP,    opBSWAP_EBP,    opBSWAP_ESI,    opBSWAP_EDI,
   3.317 +/*d0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.318 +/*e0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.319 +/*f0*/  ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,
   3.320 +};
   3.321 +
   3.322 +OpFn ops_286[1024] = 
   3.323 +{
   3.324 +        /*16-bit data, 16-bit addr*/
   3.325 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.326 +/*00*/  opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm,   opADD_AX_imm,   opPUSH_ES_w,    opPOP_ES_w,     opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16,  opOR_w_rm_a16,  opOR_AL_imm,    opOR_AX_imm,    opPUSH_CS_w,    op0F_w_a16,
   3.327 +/*10*/  opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm,   opADC_AX_imm,   opPUSH_SS_w,    opPOP_SS_w,     opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm,   opSBB_AX_imm,   opPUSH_DS_w,    opPOP_DS_w,
   3.328 +/*20*/  opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm,   opAND_AX_imm,   op_ES,          opDAA,          opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm,   opSUB_AX_imm,   op_CS,          opDAS,
   3.329 +/*30*/  opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm,   opXOR_AX_imm,   op_SS,          opAAA,          opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm,   opCMP_AX_imm,   op_DS,          opAAS,
   3.330 +
   3.331 +/*40*/  opINC_AX,       opINC_CX,       opINC_DX,       opINC_BX,       opINC_SP,       opINC_BP,       opINC_SI,       opINC_DI,       opDEC_AX,       opDEC_CX,       opDEC_DX,       opDEC_BX,       opDEC_SP,       opDEC_BP,       opDEC_SI,       opDEC_DI,  
   3.332 +/*50*/  opPUSH_AX,      opPUSH_CX,      opPUSH_DX,      opPUSH_BX,      opPUSH_SP,      opPUSH_BP,      opPUSH_SI,      opPUSH_DI,      opPOP_AX,       opPOP_CX,       opPOP_DX,       opPOP_BX,       opPOP_SP,       opPOP_BP,       opPOP_SI,       opPOP_DI, 
   3.333 +/*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a16,  opARPL_a16,     ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opPUSH_imm_w,   opIMUL_w_iw_a16,opPUSH_imm_bw,  opIMUL_w_ib_a16,opINSB_a16,     opINSW_a16,     opOUTSB_a16,    opOUTSW_a16,
   3.334 +/*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
   3.335 +
   3.336 +/*80*/  op80_a16,       op81_w_a16,     ILLEGAL,        op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
   3.337 +/*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF_286,     opSAHF,         opLAHF,
   3.338 +/*a0*/  opMOV_AL_a16,   opMOV_AX_a16,   opMOV_a16_AL,   opMOV_a16_AX,   opMOVSB_a16,    opMOVSW_a16,    opCMPSB_a16,    opCMPSW_a16,    opTEST_AL,      opTEST_AX,      opSTOSB_a16,    opSTOSW_a16,    opLODSB_a16,    opLODSW_a16,    opSCASB_a16,    opSCASW_a16,
   3.339 +/*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
   3.340 +
   3.341 +/*c0*/  opC0_a16,       opC1_w_a16,     opRET_w_imm,    opRET_w,        opLES_w_a16,    opLDS_w_a16,    opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w,      opLEAVE_w,      opRETF_a16_imm, opRETF_a16,     opINT3,         opINT,          opINTO,         opIRET,
   3.342 +/*d0*/  opD0_a16,       opD1_w_a16,     opD2_a16,       opD3_w_a16,     opAAM,          opAAD,          opSETALC,       opXLAT_a16,     opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
   3.343 +/*e0*/  opLOOPNE_w,     opLOOPE_w,      opLOOP_w,       opJCXZ,         opIN_AL_imm,    opIN_AX_imm,    opOUT_AL_imm,   opOUT_AX_imm,   opCALL_r16,     opJMP_r16,      opJMP_far_a16,  opJMP_r8,       opIN_AL_DX,     opIN_AX_DX,     opOUT_AL_DX,    opOUT_AX_DX,
   3.344 +/*f0*/  opLOCK,         ILLEGAL,        opREPNE,        opREPE,         opHLT,          opCMC,          opF6_a16,       opF7_w_a16,     opCLC,          opSTC,          opCLI,          opSTI,          opCLD,          opSTD,          opINCDEC_b_a16, opFF_w_a16,
   3.345 +
   3.346 +        /*32-bit data, 16-bit addr*/
   3.347 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.348 +/*00*/  opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm,   opADD_AX_imm,   opPUSH_ES_w,    opPOP_ES_w,     opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16,  opOR_w_rm_a16,  opOR_AL_imm,    opOR_AX_imm,    opPUSH_CS_w,    op0F_w_a16,
   3.349 +/*10*/  opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm,   opADC_AX_imm,   opPUSH_SS_w,    opPOP_SS_w,     opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm,   opSBB_AX_imm,   opPUSH_DS_w,    opPOP_DS_w,
   3.350 +/*20*/  opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm,   opAND_AX_imm,   op_ES,          opDAA,          opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm,   opSUB_AX_imm,   op_CS,          opDAS,
   3.351 +/*30*/  opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm,   opXOR_AX_imm,   op_SS,          opAAA,          opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm,   opCMP_AX_imm,   op_DS,          opAAS,
   3.352 +
   3.353 +/*40*/  opINC_AX,       opINC_CX,       opINC_DX,       opINC_BX,       opINC_SP,       opINC_BP,       opINC_SI,       opINC_DI,       opDEC_AX,       opDEC_CX,       opDEC_DX,       opDEC_BX,       opDEC_SP,       opDEC_BP,       opDEC_SI,       opDEC_DI,  
   3.354 +/*50*/  opPUSH_AX,      opPUSH_CX,      opPUSH_DX,      opPUSH_BX,      opPUSH_SP,      opPUSH_BP,      opPUSH_SI,      opPUSH_DI,      opPOP_AX,       opPOP_CX,       opPOP_DX,       opPOP_BX,       opPOP_SP,       opPOP_BP,       opPOP_SI,       opPOP_DI, 
   3.355 +/*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a16,  opARPL_a16,     ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opPUSH_imm_w,   opIMUL_w_iw_a16,opPUSH_imm_bw,  opIMUL_w_ib_a16,opINSB_a16,     opINSW_a16,     opOUTSB_a16,    opOUTSW_a16,
   3.356 +/*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
   3.357 +
   3.358 +/*80*/  op80_a16,       op81_w_a16,     ILLEGAL,        op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
   3.359 +/*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF_286,     opSAHF,         opLAHF,
   3.360 +/*a0*/  opMOV_AL_a16,   opMOV_AX_a16,   opMOV_a16_AL,   opMOV_a16_AX,   opMOVSB_a16,    opMOVSW_a16,    opCMPSB_a16,    opCMPSW_a16,    opTEST_AL,      opTEST_AX,      opSTOSB_a16,    opSTOSW_a16,    opLODSB_a16,    opLODSW_a16,    opSCASB_a16,    opSCASW_a16,
   3.361 +/*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
   3.362 +
   3.363 +/*c0*/  opC0_a16,       opC1_w_a16,     opRET_w_imm,    opRET_w,        opLES_w_a16,    opLDS_w_a16,    opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w,      opLEAVE_w,      opRETF_a16_imm, opRETF_a16,     opINT3,         opINT,          opINTO,         opIRET,
   3.364 +/*d0*/  opD0_a16,       opD1_w_a16,     opD2_a16,       opD3_w_a16,     opAAM,          opAAD,          opSETALC,       opXLAT_a16,     opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
   3.365 +/*e0*/  opLOOPNE_w,     opLOOPE_w,      opLOOP_w,       opJCXZ,         opIN_AL_imm,    opIN_AX_imm,    opOUT_AL_imm,   opOUT_AX_imm,   opCALL_r16,     opJMP_r16,      opJMP_far_a16,  opJMP_r8,       opIN_AL_DX,     opIN_AX_DX,     opOUT_AL_DX,    opOUT_AX_DX,
   3.366 +/*f0*/  opLOCK,         ILLEGAL,        opREPNE,        opREPE,         opHLT,          opCMC,          opF6_a16,       opF7_w_a16,     opCLC,          opSTC,          opCLI,          opSTI,          opCLD,          opSTD,          opINCDEC_b_a16, opFF_w_a16,
   3.367 +
   3.368 +        /*16-bit data, 32-bit addr*/
   3.369 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.370 +/*00*/  opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm,   opADD_AX_imm,   opPUSH_ES_w,    opPOP_ES_w,     opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16,  opOR_w_rm_a16,  opOR_AL_imm,    opOR_AX_imm,    opPUSH_CS_w,    op0F_w_a16,
   3.371 +/*10*/  opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm,   opADC_AX_imm,   opPUSH_SS_w,    opPOP_SS_w,     opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm,   opSBB_AX_imm,   opPUSH_DS_w,    opPOP_DS_w,
   3.372 +/*20*/  opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm,   opAND_AX_imm,   op_ES,          opDAA,          opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm,   opSUB_AX_imm,   op_CS,          opDAS,
   3.373 +/*30*/  opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm,   opXOR_AX_imm,   op_SS,          opAAA,          opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm,   opCMP_AX_imm,   op_DS,          opAAS,
   3.374 +
   3.375 +/*40*/  opINC_AX,       opINC_CX,       opINC_DX,       opINC_BX,       opINC_SP,       opINC_BP,       opINC_SI,       opINC_DI,       opDEC_AX,       opDEC_CX,       opDEC_DX,       opDEC_BX,       opDEC_SP,       opDEC_BP,       opDEC_SI,       opDEC_DI,  
   3.376 +/*50*/  opPUSH_AX,      opPUSH_CX,      opPUSH_DX,      opPUSH_BX,      opPUSH_SP,      opPUSH_BP,      opPUSH_SI,      opPUSH_DI,      opPOP_AX,       opPOP_CX,       opPOP_DX,       opPOP_BX,       opPOP_SP,       opPOP_BP,       opPOP_SI,       opPOP_DI, 
   3.377 +/*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a16,  opARPL_a16,     ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opPUSH_imm_w,   opIMUL_w_iw_a16,opPUSH_imm_bw,  opIMUL_w_ib_a16,opINSB_a16,     opINSW_a16,     opOUTSB_a16,    opOUTSW_a16,
   3.378 +/*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
   3.379 +
   3.380 +/*80*/  op80_a16,       op81_w_a16,     ILLEGAL,        op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
   3.381 +/*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF_286,     opSAHF,         opLAHF,
   3.382 +/*a0*/  opMOV_AL_a16,   opMOV_AX_a16,   opMOV_a16_AL,   opMOV_a16_AX,   opMOVSB_a16,    opMOVSW_a16,    opCMPSB_a16,    opCMPSW_a16,    opTEST_AL,      opTEST_AX,      opSTOSB_a16,    opSTOSW_a16,    opLODSB_a16,    opLODSW_a16,    opSCASB_a16,    opSCASW_a16,
   3.383 +/*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
   3.384 +
   3.385 +/*c0*/  opC0_a16,       opC1_w_a16,     opRET_w_imm,    opRET_w,        opLES_w_a16,    opLDS_w_a16,    opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w,      opLEAVE_w,      opRETF_a16_imm, opRETF_a16,     opINT3,         opINT,          opINTO,         opIRET,
   3.386 +/*d0*/  opD0_a16,       opD1_w_a16,     opD2_a16,       opD3_w_a16,     opAAM,          opAAD,          opSETALC,       opXLAT_a16,     opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
   3.387 +/*e0*/  opLOOPNE_w,     opLOOPE_w,      opLOOP_w,       opJCXZ,         opIN_AL_imm,    opIN_AX_imm,    opOUT_AL_imm,   opOUT_AX_imm,   opCALL_r16,     opJMP_r16,      opJMP_far_a16,  opJMP_r8,       opIN_AL_DX,     opIN_AX_DX,     opOUT_AL_DX,    opOUT_AX_DX,
   3.388 +/*f0*/  opLOCK,         ILLEGAL,        opREPNE,        opREPE,         opHLT,          opCMC,          opF6_a16,       opF7_w_a16,     opCLC,          opSTC,          opCLI,          opSTI,          opCLD,          opSTD,          opINCDEC_b_a16, opFF_w_a16,
   3.389 +
   3.390 +        /*32-bit data, 32-bit addr*/
   3.391 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.392 +/*00*/  opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm,   opADD_AX_imm,   opPUSH_ES_w,    opPOP_ES_w,     opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16,  opOR_w_rm_a16,  opOR_AL_imm,    opOR_AX_imm,    opPUSH_CS_w,    op0F_w_a16,
   3.393 +/*10*/  opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm,   opADC_AX_imm,   opPUSH_SS_w,    opPOP_SS_w,     opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm,   opSBB_AX_imm,   opPUSH_DS_w,    opPOP_DS_w,
   3.394 +/*20*/  opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm,   opAND_AX_imm,   op_ES,          opDAA,          opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm,   opSUB_AX_imm,   op_CS,          opDAS,
   3.395 +/*30*/  opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm,   opXOR_AX_imm,   op_SS,          opAAA,          opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm,   opCMP_AX_imm,   op_DS,          opAAS,
   3.396 +
   3.397 +/*40*/  opINC_AX,       opINC_CX,       opINC_DX,       opINC_BX,       opINC_SP,       opINC_BP,       opINC_SI,       opINC_DI,       opDEC_AX,       opDEC_CX,       opDEC_DX,       opDEC_BX,       opDEC_SP,       opDEC_BP,       opDEC_SI,       opDEC_DI,  
   3.398 +/*50*/  opPUSH_AX,      opPUSH_CX,      opPUSH_DX,      opPUSH_BX,      opPUSH_SP,      opPUSH_BP,      opPUSH_SI,      opPUSH_DI,      opPOP_AX,       opPOP_CX,       opPOP_DX,       opPOP_BX,       opPOP_SP,       opPOP_BP,       opPOP_SI,       opPOP_DI, 
   3.399 +/*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a16,  opARPL_a16,     ILLEGAL,        ILLEGAL,        ILLEGAL,        ILLEGAL,        opPUSH_imm_w,   opIMUL_w_iw_a16,opPUSH_imm_bw,  opIMUL_w_ib_a16,opINSB_a16,     opINSW_a16,     opOUTSB_a16,    opOUTSW_a16,
   3.400 +/*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
   3.401 +
   3.402 +/*80*/  op80_a16,       op81_w_a16,     ILLEGAL,        op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
   3.403 +/*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF_286,     opSAHF,         opLAHF,
   3.404 +/*a0*/  opMOV_AL_a16,   opMOV_AX_a16,   opMOV_a16_AL,   opMOV_a16_AX,   opMOVSB_a16,    opMOVSW_a16,    opCMPSB_a16,    opCMPSW_a16,    opTEST_AL,      opTEST_AX,      opSTOSB_a16,    opSTOSW_a16,    opLODSB_a16,    opLODSW_a16,    opSCASB_a16,    opSCASW_a16,
   3.405 +/*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
   3.406 +
   3.407 +/*c0*/  opC0_a16,       opC1_w_a16,     opRET_w_imm,    opRET_w,        opLES_w_a16,    opLDS_w_a16,    opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w,      opLEAVE_w,      opRETF_a16_imm, opRETF_a16,     opINT3,         opINT,          opINTO,         opIRET,
   3.408 +/*d0*/  opD0_a16,       opD1_w_a16,     opD2_a16,       opD3_w_a16,     opAAM,          opAAD,          opSETALC,       opXLAT_a16,     opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
   3.409 +/*e0*/  opLOOPNE_w,     opLOOPE_w,      opLOOP_w,       opJCXZ,         opIN_AL_imm,    opIN_AX_imm,    opOUT_AL_imm,   opOUT_AX_imm,   opCALL_r16,     opJMP_r16,      opJMP_far_a16,  opJMP_r8,       opIN_AL_DX,     opIN_AX_DX,     opOUT_AL_DX,    opOUT_AX_DX,
   3.410 +/*f0*/  opLOCK,         ILLEGAL,        opREPNE,        opREPE,         opHLT,          opCMC,          opF6_a16,       opF7_w_a16,     opCLC,          opSTC,          opCLI,          opSTI,          opCLD,          opSTD,          opINCDEC_b_a16, opFF_w_a16,
   3.411 +};
   3.412 +
   3.413 +OpFn ops_386[1024] = 
   3.414 +{
   3.415 +        /*16-bit data, 16-bit addr*/
   3.416 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/        
   3.417 +/*00*/  opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm,   opADD_AX_imm,   opPUSH_ES_w,    opPOP_ES_w,     opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16,  opOR_w_rm_a16,  opOR_AL_imm,    opOR_AX_imm,    opPUSH_CS_w,    op0F_w_a16,
   3.418 +/*10*/  opADC_b_rmw_a16,opADC_w_rmw_a16,opADC_b_rm_a16, opADC_w_rm_a16, opADC_AL_imm,   opADC_AX_imm,   opPUSH_SS_w,    opPOP_SS_w,     opSBB_b_rmw_a16,opSBB_w_rmw_a16,opSBB_b_rm_a16, opSBB_w_rm_a16, opSBB_AL_imm,   opSBB_AX_imm,   opPUSH_DS_w,    opPOP_DS_w,
   3.419 +/*20*/  opAND_b_rmw_a16,opAND_w_rmw_a16,opAND_b_rm_a16, opAND_w_rm_a16, opAND_AL_imm,   opAND_AX_imm,   op_ES,          opDAA,          opSUB_b_rmw_a16,opSUB_w_rmw_a16,opSUB_b_rm_a16, opSUB_w_rm_a16, opSUB_AL_imm,   opSUB_AX_imm,   op_CS,          opDAS,
   3.420 +/*30*/  opXOR_b_rmw_a16,opXOR_w_rmw_a16,opXOR_b_rm_a16, opXOR_w_rm_a16, opXOR_AL_imm,   opXOR_AX_imm,   op_SS,          opAAA,          opCMP_b_rmw_a16,opCMP_w_rmw_a16,opCMP_b_rm_a16, opCMP_w_rm_a16, opCMP_AL_imm,   opCMP_AX_imm,   op_DS,          opAAS,
   3.421 +
   3.422 +/*40*/  opINC_AX,       opINC_CX,       opINC_DX,       opINC_BX,       opINC_SP,       opINC_BP,       opINC_SI,       opINC_DI,       opDEC_AX,       opDEC_CX,       opDEC_DX,       opDEC_BX,       opDEC_SP,       opDEC_BP,       opDEC_SI,       opDEC_DI,  
   3.423 +/*50*/  opPUSH_AX,      opPUSH_CX,      opPUSH_DX,      opPUSH_BX,      opPUSH_SP,      opPUSH_BP,      opPUSH_SI,      opPUSH_DI,      opPOP_AX,       opPOP_CX,       opPOP_DX,       opPOP_BX,       opPOP_SP,       opPOP_BP,       opPOP_SI,       opPOP_DI, 
   3.424 +/*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a16,  opARPL_a16,     op_FS,          op_GS,          op_66,          op_67,          opPUSH_imm_w,   opIMUL_w_iw_a16,opPUSH_imm_bw,  opIMUL_w_ib_a16,opINSB_a16,     opINSW_a16,     opOUTSB_a16,    opOUTSW_a16,
   3.425 +/*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
   3.426 +
   3.427 +/*80*/  op80_a16,       op81_w_a16,     ILLEGAL,        op83_w_a16,     opTEST_b_a16,   opTEST_w_a16,   opXCHG_b_a16,   opXCHG_w_a16,   opMOV_b_r_a16,  opMOV_w_r_a16,  opMOV_r_b_a16,  opMOV_r_w_a16,  opMOV_w_seg_a16,opLEA_w_a16,    opMOV_seg_w_a16,opPOPW_a16,
   3.428 +/*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF,         opSAHF,         opLAHF,
   3.429 +/*a0*/  opMOV_AL_a16,   opMOV_AX_a16,   opMOV_a16_AL,   opMOV_a16_AX,   opMOVSB_a16,    opMOVSW_a16,    opCMPSB_a16,    opCMPSW_a16,    opTEST_AL,      opTEST_AX,      opSTOSB_a16,    opSTOSW_a16,    opLODSB_a16,    opLODSW_a16,    opSCASB_a16,    opSCASW_a16,
   3.430 +/*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
   3.431 +
   3.432 +/*c0*/  opC0_a16,       opC1_w_a16,     opRET_w_imm,    opRET_w,        opLES_w_a16,    opLDS_w_a16,    opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w,      opLEAVE_w,      opRETF_a16_imm, opRETF_a16,     opINT3,         opINT,          opINTO,         opIRET,
   3.433 +/*d0*/  opD0_a16,       opD1_w_a16,     opD2_a16,       opD3_w_a16,     opAAM,          opAAD,          opSETALC,       opXLAT_a16,     opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
   3.434 +/*e0*/  opLOOPNE_w,     opLOOPE_w,      opLOOP_w,       opJCXZ,         opIN_AL_imm,    opIN_AX_imm,    opOUT_AL_imm,   opOUT_AX_imm,   opCALL_r16,     opJMP_r16,      opJMP_far_a16,  opJMP_r8,       opIN_AL_DX,     opIN_AX_DX,     opOUT_AL_DX,    opOUT_AX_DX,
   3.435 +/*f0*/  opLOCK,         ILLEGAL,        opREPNE,        opREPE,         opHLT,          opCMC,          opF6_a16,       opF7_w_a16,     opCLC,          opSTC,          opCLI,          opSTI,          opCLD,          opSTD,          opINCDEC_b_a16, opFF_w_a16,
   3.436 +
   3.437 +        /*32-bit data, 16-bit addr*/
   3.438 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/
   3.439 +/*00*/  opADD_b_rmw_a16,opADD_l_rmw_a16,opADD_b_rm_a16, opADD_l_rm_a16, opADD_AL_imm,   opADD_EAX_imm,  opPUSH_ES_l,    opPOP_ES_l,     opOR_b_rmw_a16, opOR_l_rmw_a16, opOR_b_rm_a16,  opOR_l_rm_a16,  opOR_AL_imm,    opOR_EAX_imm,   opPUSH_CS_l,    op0F_l_a16,
   3.440 +/*10*/  opADC_b_rmw_a16,opADC_l_rmw_a16,opADC_b_rm_a16, opADC_l_rm_a16, opADC_AL_imm,   opADC_EAX_imm,  opPUSH_SS_l,    opPOP_SS_l,     opSBB_b_rmw_a16,opSBB_l_rmw_a16,opSBB_b_rm_a16, opSBB_l_rm_a16, opSBB_AL_imm,   opSBB_EAX_imm,  opPUSH_DS_l,    opPOP_DS_l,
   3.441 +/*20*/  opAND_b_rmw_a16,opAND_l_rmw_a16,opAND_b_rm_a16, opAND_l_rm_a16, opAND_AL_imm,   opAND_EAX_imm,  op_ES,          opDAA,          opSUB_b_rmw_a16,opSUB_l_rmw_a16,opSUB_b_rm_a16, opSUB_l_rm_a16, opSUB_AL_imm,   opSUB_EAX_imm,  op_CS,          opDAS,
   3.442 +/*30*/  opXOR_b_rmw_a16,opXOR_l_rmw_a16,opXOR_b_rm_a16, opXOR_l_rm_a16, opXOR_AL_imm,   opXOR_EAX_imm,  op_SS,          opAAA,          opCMP_b_rmw_a16,opCMP_l_rmw_a16,opCMP_b_rm_a16, opCMP_l_rm_a16, opCMP_AL_imm,   opCMP_EAX_imm,  op_DS,          opAAS,
   3.443 +
   3.444 +/*40*/  opINC_EAX,      opINC_ECX,      opINC_EDX,      opINC_EBX,      opINC_ESP,      opINC_EBP,      opINC_ESI,      opINC_EDI,      opDEC_EAX,      opDEC_ECX,      opDEC_EDX,      opDEC_EBX,      opDEC_ESP,      opDEC_EBP,      opDEC_ESI,      opDEC_EDI,
   3.445 +/*50*/  opPUSH_EAX,     opPUSH_ECX,     opPUSH_EDX,     opPUSH_EBX,     opPUSH_ESP,     opPUSH_EBP,     opPUSH_ESI,     opPUSH_EDI,     opPOP_EAX,      opPOP_ECX,      opPOP_EDX,      opPOP_EBX,      opPOP_ESP,      opPOP_EBP,      opPOP_ESI,      opPOP_EDI, 
   3.446 +/*60*/  opPUSHA_l,      opPOPA_l,       opBOUND_l_a16,  opARPL_a16,     op_FS,          op_GS,          op_66,          op_67,          opPUSH_imm_l,   opIMUL_l_il_a16,opPUSH_imm_bl,  opIMUL_l_ib_a16,opINSB_a16,     opINSL_a16,     opOUTSB_a16,    opOUTSL_a16,
   3.447 +/*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
   3.448 +
   3.449 +/*80*/  op80_a16,       op81_l_a16,     ILLEGAL,        op83_l_a16,     opTEST_b_a16,   opTEST_l_a16,   opXCHG_b_a16,   opXCHG_l_a16,   opMOV_b_r_a16,  opMOV_l_r_a16,  opMOV_r_b_a16,  opMOV_r_l_a16,  opMOV_l_seg_a16,opLEA_l_a16,    opMOV_seg_w_a16,opPOPL_a16,
   3.450 +/*90*/  opNOP,          opXCHG_EAX_ECX, opXCHG_EAX_EDX, opXCHG_EAX_EBX, opXCHG_EAX_ESP, opXCHG_EAX_EBP, opXCHG_EAX_ESI, opXCHG_EAX_EDI, opCWDE,         opCDQ,          opCALL_far_l,   opWAIT,         opPUSHFD,       opPOPFD,        opSAHF,         opLAHF,
   3.451 +/*a0*/  opMOV_AL_a16,   opMOV_EAX_a16,  opMOV_a16_AL,   opMOV_a16_EAX,  opMOVSB_a16,    opMOVSL_a16,    opCMPSB_a16,    opCMPSL_a16,    opTEST_AL,      opTEST_EAX,     opSTOSB_a16,    opSTOSL_a16,    opLODSB_a16,    opLODSL_a16,    opSCASB_a16,    opSCASL_a16,
   3.452 +/*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_EAX_imm,  opMOV_ECX_imm,  opMOV_EDX_imm,  opMOV_EBX_imm,  opMOV_ESP_imm,  opMOV_EBP_imm,  opMOV_ESI_imm,  opMOV_EDI_imm,
   3.453 +
   3.454 +/*c0*/  opC0_a16,       opC1_l_a16,     opRET_l_imm,    opRET_l,        opLES_l_a16,    opLDS_l_a16,    opMOV_b_imm_a16,opMOV_l_imm_a16,opENTER_l,      opLEAVE_l,      opRETF_a32_imm, opRETF_a32,     opINT3,         opINT,          opINTO,         opIRETD,
   3.455 +/*d0*/  opD0_a16,       opD1_l_a16,     opD2_a16,       opD3_l_a16,     opAAM,          opAAD,          opSETALC,       opXLAT_a16,     opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
   3.456 +/*e0*/  opLOOPNE_w,     opLOOPE_w,      opLOOP_w,       opJCXZ,         opIN_AL_imm,    opIN_EAX_imm,   opOUT_AL_imm,   opOUT_EAX_imm,  opCALL_r32,     opJMP_r32,      opJMP_far_a32,  opJMP_r8,       opIN_AL_DX,     opIN_EAX_DX,    opOUT_AL_DX,    opOUT_EAX_DX,
   3.457 +/*f0*/  opLOCK,         ILLEGAL,        opREPNE,        opREPE,         opHLT,          opCMC,          opF6_a16,       opF7_l_a16,     opCLC,          opSTC,          opCLI,          opSTI,          opCLD,          opSTD,          opINCDEC_b_a16, opFF_l_a16,
   3.458 +
   3.459 +        /*16-bit data, 32-bit addr*/
   3.460 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/
   3.461 +/*00*/  opADD_b_rmw_a32,opADD_w_rmw_a32,opADD_b_rm_a32, opADD_w_rm_a32, opADD_AL_imm,   opADD_AX_imm,   opPUSH_ES_w,    opPOP_ES_w,     opOR_b_rmw_a32, opOR_w_rmw_a32, opOR_b_rm_a32,  opOR_w_rm_a32,  opOR_AL_imm,    opOR_AX_imm,    opPUSH_CS_w,    op0F_w_a32,
   3.462 +/*10*/  opADC_b_rmw_a32,opADC_w_rmw_a32,opADC_b_rm_a32, opADC_w_rm_a32, opADC_AL_imm,   opADC_AX_imm,   opPUSH_SS_w,    opPOP_SS_w,     opSBB_b_rmw_a32,opSBB_w_rmw_a32,opSBB_b_rm_a32, opSBB_w_rm_a32, opSBB_AL_imm,   opSBB_AX_imm,   opPUSH_DS_w,    opPOP_DS_w,
   3.463 +/*20*/  opAND_b_rmw_a32,opAND_w_rmw_a32,opAND_b_rm_a32, opAND_w_rm_a32, opAND_AL_imm,   opAND_AX_imm,   op_ES,          opDAA,          opSUB_b_rmw_a32,opSUB_w_rmw_a32,opSUB_b_rm_a32, opSUB_w_rm_a32, opSUB_AL_imm,   opSUB_AX_imm,   op_CS,          opDAS,
   3.464 +/*30*/  opXOR_b_rmw_a32,opXOR_w_rmw_a32,opXOR_b_rm_a32, opXOR_w_rm_a32, opXOR_AL_imm,   opXOR_AX_imm,   op_SS,          opAAA,          opCMP_b_rmw_a32,opCMP_w_rmw_a32,opCMP_b_rm_a32, opCMP_w_rm_a32, opCMP_AL_imm,   opCMP_AX_imm,   op_DS,          opAAS,
   3.465 +
   3.466 +/*40*/  opINC_AX,       opINC_CX,       opINC_DX,       opINC_BX,       opINC_SP,       opINC_BP,       opINC_SI,       opINC_DI,       opDEC_AX,       opDEC_CX,       opDEC_DX,       opDEC_BX,       opDEC_SP,       opDEC_BP,       opDEC_SI,       opDEC_DI,  
   3.467 +/*50*/  opPUSH_AX,      opPUSH_CX,      opPUSH_DX,      opPUSH_BX,      opPUSH_SP,      opPUSH_BP,      opPUSH_SI,      opPUSH_DI,      opPOP_AX,       opPOP_CX,       opPOP_DX,       opPOP_BX,       opPOP_SP,       opPOP_BP,       opPOP_SI,       opPOP_DI, 
   3.468 +/*60*/  opPUSHA_w,      opPOPA_w,       opBOUND_w_a32,  opARPL_a32,     op_FS,          op_GS,          op_66,          op_67,          opPUSH_imm_w,   opIMUL_w_iw_a32,opPUSH_imm_bw,  opIMUL_w_ib_a32,opINSB_a32,     opINSW_a32,     opOUTSB_a32,    opOUTSW_a32,
   3.469 +/*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
   3.470 +
   3.471 +/*80*/  op80_a32,       op81_w_a32,     ILLEGAL,        op83_w_a32,     opTEST_b_a32,   opTEST_w_a32,   opXCHG_b_a32,   opXCHG_w_a32,   opMOV_b_r_a32,  opMOV_w_r_a32,  opMOV_r_b_a32,  opMOV_r_w_a32,  opMOV_w_seg_a32,opLEA_w_a32,    opMOV_seg_w_a32,opPOPW_a32,
   3.472 +/*90*/  opNOP,          opXCHG_AX_CX,   opXCHG_AX_DX,   opXCHG_AX_BX,   opXCHG_AX_SP,   opXCHG_AX_BP,   opXCHG_AX_SI,   opXCHG_AX_DI,   opCBW,          opCWD,          opCALL_far_w,   opWAIT,         opPUSHF,        opPOPF,         opSAHF,         opLAHF,
   3.473 +/*a0*/  opMOV_AL_a32,   opMOV_AX_a32,   opMOV_a32_AL,   opMOV_a32_AX,   opMOVSB_a32,    opMOVSW_a32,    opCMPSB_a32,    opCMPSW_a32,    opTEST_AL,      opTEST_AX,      opSTOSB_a32,    opSTOSW_a32,    opLODSB_a32,    opLODSW_a32,    opSCASB_a32,    opSCASW_a32,
   3.474 +/*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_AX_imm,   opMOV_CX_imm,   opMOV_DX_imm,   opMOV_BX_imm,   opMOV_SP_imm,   opMOV_BP_imm,   opMOV_SI_imm,   opMOV_DI_imm,
   3.475 +
   3.476 +/*c0*/  opC0_a32,       opC1_w_a32,     opRET_w_imm,    opRET_w,        opLES_w_a32,    opLDS_w_a32,    opMOV_b_imm_a32,opMOV_w_imm_a32,opENTER_w,      opLEAVE_w,      opRETF_a16_imm, opRETF_a16,     opINT3,         opINT,          opINTO,         opIRET,
   3.477 +/*d0*/  opD0_a32,       opD1_w_a32,     opD2_a32,       opD3_w_a32,     opAAM,          opAAD,          opSETALC,       opXLAT_a32,     opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32,
   3.478 +/*e0*/  opLOOPNE_l,     opLOOPE_l,      opLOOP_l,       opJECXZ,        opIN_AL_imm,    opIN_AX_imm,    opOUT_AL_imm,   opOUT_AX_imm,   opCALL_r16,     opJMP_r16,      opJMP_far_a16,  opJMP_r8,       opIN_AL_DX,     opIN_AX_DX,     opOUT_AL_DX,    opOUT_AX_DX,
   3.479 +/*f0*/  opLOCK,         ILLEGAL,        opREPNE,        opREPE,         opHLT,          opCMC,          opF6_a32,       opF7_w_a32,     opCLC,          opSTC,          opCLI,          opSTI,          opCLD,          opSTD,          opINCDEC_b_a32, opFF_w_a32,
   3.480 +
   3.481 +        /*32-bit data, 32-bit addr*/
   3.482 +/*      00              01              02              03              04              05              06              07              08              09              0a              0b              0c              0d              0e              0f*/
   3.483 +/*00*/  opADD_b_rmw_a32,opADD_l_rmw_a32,opADD_b_rm_a32, opADD_l_rm_a32, opADD_AL_imm,   opADD_EAX_imm,  opPUSH_ES_l,    opPOP_ES_l,     opOR_b_rmw_a32, opOR_l_rmw_a32, opOR_b_rm_a32,  opOR_l_rm_a32,  opOR_AL_imm,    opOR_EAX_imm,   opPUSH_CS_l,    op0F_l_a32,
   3.484 +/*10*/  opADC_b_rmw_a32,opADC_l_rmw_a32,opADC_b_rm_a32, opADC_l_rm_a32, opADC_AL_imm,   opADC_EAX_imm,  opPUSH_SS_l,    opPOP_SS_l,     opSBB_b_rmw_a32,opSBB_l_rmw_a32,opSBB_b_rm_a32, opSBB_l_rm_a32, opSBB_AL_imm,   opSBB_EAX_imm,  opPUSH_DS_l,    opPOP_DS_l,
   3.485 +/*20*/  opAND_b_rmw_a32,opAND_l_rmw_a32,opAND_b_rm_a32, opAND_l_rm_a32, opAND_AL_imm,   opAND_EAX_imm,  op_ES,          opDAA,          opSUB_b_rmw_a32,opSUB_l_rmw_a32,opSUB_b_rm_a32, opSUB_l_rm_a32, opSUB_AL_imm,   opSUB_EAX_imm,  op_CS,          opDAS,
   3.486 +/*30*/  opXOR_b_rmw_a32,opXOR_l_rmw_a32,opXOR_b_rm_a32, opXOR_l_rm_a32, opXOR_AL_imm,   opXOR_EAX_imm,  op_SS,          opAAA,          opCMP_b_rmw_a32,opCMP_l_rmw_a32,opCMP_b_rm_a32, opCMP_l_rm_a32, opCMP_AL_imm,   opCMP_EAX_imm,  op_DS,          opAAS,
   3.487 +
   3.488 +/*40*/  opINC_EAX,      opINC_ECX,      opINC_EDX,      opINC_EBX,      opINC_ESP,      opINC_EBP,      opINC_ESI,      opINC_EDI,      opDEC_EAX,      opDEC_ECX,      opDEC_EDX,      opDEC_EBX,      opDEC_ESP,      opDEC_EBP,      opDEC_ESI,      opDEC_EDI,
   3.489 +/*50*/  opPUSH_EAX,     opPUSH_ECX,     opPUSH_EDX,     opPUSH_EBX,     opPUSH_ESP,     opPUSH_EBP,     opPUSH_ESI,     opPUSH_EDI,     opPOP_EAX,      opPOP_ECX,      opPOP_EDX,      opPOP_EBX,      opPOP_ESP,      opPOP_EBP,      opPOP_ESI,      opPOP_EDI, 
   3.490 +/*60*/  opPUSHA_l,      opPOPA_l,       opBOUND_l_a32,  opARPL_a32,     op_FS,          op_GS,          op_66,          op_67,          opPUSH_imm_l,   opIMUL_l_il_a32,opPUSH_imm_bl,  opIMUL_l_ib_a32,opINSB_a32,     opINSL_a32,     opOUTSB_a32,    opOUTSL_a32,
   3.491 +/*70*/  opJO,           opJNO,          opJB,           opJNB,          opJE,           opJNE,          opJBE,          opJNBE,         opJS,           opJNS,          opJP,           opJNP,          opJL,           opJNL,          opJLE,          opJNLE,
   3.492 +
   3.493 +/*80*/  op80_a32,       op81_l_a32,     ILLEGAL,        op83_l_a32,     opTEST_b_a32,   opTEST_l_a32,   opXCHG_b_a32,   opXCHG_l_a32,   opMOV_b_r_a32,  opMOV_l_r_a32,  opMOV_r_b_a32,  opMOV_r_l_a32,  opMOV_l_seg_a32,opLEA_l_a32,    opMOV_seg_w_a32,opPOPL_a32,
   3.494 +/*90*/  opNOP,          opXCHG_EAX_ECX, opXCHG_EAX_EDX, opXCHG_EAX_EBX, opXCHG_EAX_ESP, opXCHG_EAX_EBP, opXCHG_EAX_ESI, opXCHG_EAX_EDI, opCWDE,         opCDQ,          opCALL_far_l,   opWAIT,         opPUSHFD,       opPOPFD,        opSAHF,         opLAHF,
   3.495 +/*a0*/  opMOV_AL_a32,   opMOV_EAX_a32,  opMOV_a32_AL,   opMOV_a32_EAX,  opMOVSB_a32,    opMOVSL_a32,    opCMPSB_a32,    opCMPSL_a32,    opTEST_AL,      opTEST_EAX,     opSTOSB_a32,    opSTOSL_a32,    opLODSB_a32,    opLODSL_a32,    opSCASB_a32,    opSCASL_a32,
   3.496 +/*b0*/  opMOV_AL_imm,   opMOV_CL_imm,   opMOV_DL_imm,   opMOV_BL_imm,   opMOV_AH_imm,   opMOV_CH_imm,   opMOV_DH_imm,   opMOV_BH_imm,   opMOV_EAX_imm,  opMOV_ECX_imm,  opMOV_EDX_imm,  opMOV_EBX_imm,  opMOV_ESP_imm,  opMOV_EBP_imm,  opMOV_ESI_imm,  opMOV_EDI_imm,
   3.497 +
   3.498 +/*c0*/  opC0_a32,       opC1_l_a32,     opRET_l_imm,    opRET_l,        opLES_l_a32,    opLDS_l_a32,    opMOV_b_imm_a32,opMOV_l_imm_a32,opENTER_l,      opLEAVE_l,      opRETF_a32_imm, opRETF_a32,     opINT3,         opINT,          opINTO,         opIRETD,
   3.499 +/*d0*/  opD0_a32,       opD1_l_a32,     opD2_a32,       opD3_l_a32,     opAAM,          opAAD,          opSETALC,       opXLAT_a32,     opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32,
   3.500 +/*e0*/  opLOOPNE_l,     opLOOPE_l,      opLOOP_l,       opJECXZ,        opIN_AL_imm,    opIN_EAX_imm,   opOUT_AL_imm,   opOUT_EAX_imm,  opCALL_r32,     opJMP_r32,      opJMP_far_a32,  opJMP_r8,       opIN_AL_DX,     opIN_EAX_DX,    opOUT_AL_DX,    opOUT_EAX_DX,
   3.501 +/*f0*/  opLOCK,         ILLEGAL,        opREPNE,        opREPE,         opHLT,          opCMC,          opF6_a32,       opF7_l_a32,     opCLC,          opSTC,          opCLI,          opSTI,          opCLD,          opSTD,          opINCDEC_b_a32, opFF_l_a32,
   3.502 +};
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/808x.c	Mon May 27 19:56:33 2013 +0100
     4.3 @@ -0,0 +1,3474 @@
     4.4 +//1B64 - Vid_SetMode (Vid_Vesa.c)
     4.5 +//6689c - CONS_Printf
     4.6 +/*SHR AX,1
     4.7 +
     4.8 +        4 clocks - fetch opcode
     4.9 +        4 clocks - fetch mod/rm
    4.10 +        2 clocks - execute              2 clocks - fetch opcode 1
    4.11 +                                        2 clocks - fetch opcode 2
    4.12 +                                        4 clocks - fetch mod/rm
    4.13 +        2 clocks - fetch opcode 1       2 clocks - execute
    4.14 +        2 clocks - fetch opcode 2  etc*/
    4.15 +#include <stdio.h>
    4.16 +#include "ibm.h"
    4.17 +
    4.18 +#include "cpu.h"
    4.19 +#include "keyboard.h"
    4.20 +#include "mem.h"
    4.21 +#include "pic.h"
    4.22 +#include "timer.h"
    4.23 +#include "x86.h"
    4.24 +
    4.25 +int nextcyc=0;
    4.26 +int cycdiff;
    4.27 +int is8086=0;
    4.28 +
    4.29 +int memcycs;
    4.30 +int nopageerrors=0;
    4.31 +
    4.32 +void FETCHCOMPLETE();
    4.33 +
    4.34 +uint8_t readmembl(uint32_t addr);
    4.35 +void writemembl(uint32_t addr, uint8_t val);
    4.36 +uint16_t readmemwl(uint32_t seg, uint32_t addr);
    4.37 +void writememwl(uint32_t seg, uint32_t addr, uint16_t val);
    4.38 +uint32_t readmemll(uint32_t seg, uint32_t addr);
    4.39 +void writememll(uint32_t seg, uint32_t addr, uint32_t val);
    4.40 +
    4.41 +#undef readmemb
    4.42 +#undef readmemw
    4.43 +uint8_t readmemb(uint32_t a)
    4.44 +{
    4.45 +        if (a!=(cs+pc)) memcycs+=4;
    4.46 +        if (readlookup2[(a)>>12]==0xFFFFFFFF) return readmembl(a);
    4.47 +        else return ram[readlookup2[(a)>>12]+((a)&0xFFF)];
    4.48 +}
    4.49 +
    4.50 +uint8_t readmembf(uint32_t a)
    4.51 +{
    4.52 +        if (readlookup2[(a)>>12]==0xFFFFFFFF) return readmembl(a);
    4.53 +        else return ram[readlookup2[(a)>>12]+((a)&0xFFF)];
    4.54 +}
    4.55 +
    4.56 +uint16_t readmemw(uint32_t s, uint16_t a)
    4.57 +{
    4.58 +        if (a!=(cs+pc)) memcycs+=(8>>is8086);
    4.59 +        if ((readlookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF)) return readmemwl(s,a);
    4.60 +        else return *((uint16_t *)(&ram[readlookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]));
    4.61 +}
    4.62 +
    4.63 +void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); memcycs+=4; }
    4.64 +
    4.65 +#undef fetchea
    4.66 +#define fetchea()   { rmdat=FETCH();  \
    4.67 +                    reg=(rmdat>>3)&7;             \
    4.68 +                    mod=(rmdat>>6)&3;             \
    4.69 +                    rm=rmdat&7;                   \
    4.70 +                    if (mod!=3) fetcheal(); }
    4.71 +
    4.72 +void writemembl(uint32_t addr, uint8_t val);
    4.73 +void writememb(uint32_t a, uint8_t v)
    4.74 +{
    4.75 +        memcycs+=4;
    4.76 +        if (writelookup2[(a)>>12]==0xFFFFFFFF) writemembl(a,v);
    4.77 +        else ram[writelookup2[(a)>>12]+((a)&0xFFF)]=v;
    4.78 +}
    4.79 +void writememwl(uint32_t seg, uint32_t addr, uint16_t val);
    4.80 +void writememw(uint32_t s, uint32_t a, uint16_t v)
    4.81 +{
    4.82 +        memcycs+=(8>>is8086);
    4.83 +        if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememwl(s,a,v);
    4.84 +        else *((uint16_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v;
    4.85 +}
    4.86 +void writememll(uint32_t seg, uint32_t addr, uint32_t val);
    4.87 +void writememl(uint32_t s, uint32_t a, uint32_t v)
    4.88 +{
    4.89 +        if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememll(s,a,v);
    4.90 +        else *((uint32_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v;
    4.91 +}
    4.92 +
    4.93 +
    4.94 +void dumpregs();
    4.95 +uint16_t oldcs;
    4.96 +int oldcpl;
    4.97 +
    4.98 +int tempc;
    4.99 +uint8_t opcode;
   4.100 +int times=0;
   4.101 +uint16_t pc2,pc3;
   4.102 +int noint=0;
   4.103 +
   4.104 +int output=0;
   4.105 +
   4.106 +int shadowbios=0;
   4.107 +
   4.108 +int ins=0;
   4.109 +//#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a))
   4.110 +
   4.111 +int ssegs;
   4.112 +
   4.113 +int fetchcycles=0,memcycs,fetchclocks;
   4.114 +
   4.115 +uint8_t prefetchqueue[6];
   4.116 +uint16_t prefetchpc;
   4.117 +int prefetchw=0;
   4.118 +inline uint8_t FETCH()
   4.119 +{
   4.120 +        uint8_t temp;
   4.121 +/*        temp=prefetchqueue[0];
   4.122 +        prefetchqueue[0]=prefetchqueue[1];
   4.123 +        prefetchqueue[1]=prefetchqueue[2];
   4.124 +        prefetchqueue[2]=prefetchqueue[3];
   4.125 +        prefetchqueue[3]=prefetchqueue[4];
   4.126 +        prefetchqueue[4]=prefetchqueue[5];
   4.127 +        if (prefetchw<=((is8086)?4:3))
   4.128 +        {
   4.129 +                prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++;
   4.130 +                if (is8086 && (prefetchpc&1))
   4.131 +                {
   4.132 +                        prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++;
   4.133 +                }
   4.134 +        }*/
   4.135 +
   4.136 +//        uint8_t temp=readmemb(cs+pc);
   4.137 +//        if (output) printf("FETCH %04X %i\n",pc,fetchcycles);
   4.138 +        if (prefetchw==0) //(fetchcycles<4)
   4.139 +        {
   4.140 +                cycles-=(4-(fetchcycles&3));
   4.141 +                fetchclocks+=(4-(fetchcycles&3));
   4.142 +                fetchcycles=4;
   4.143 +                temp=readmembf(cs+pc);
   4.144 +                prefetchpc=pc=pc+1;
   4.145 +//                if (output) printf("   FETCH %04X:%04X %02X %04X %04X %i\n",CS,pc-1,temp,pc,prefetchpc,prefetchw);
   4.146 +                if (is8086 && (pc&1))
   4.147 +                {
   4.148 +                        prefetchqueue[0]=readmembf(cs+pc);
   4.149 +//                        if (output) printf("   PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]);
   4.150 +                        prefetchpc++;
   4.151 +                        prefetchw++;
   4.152 +                }
   4.153 +        }
   4.154 +        else
   4.155 +        {
   4.156 +                temp=prefetchqueue[0];
   4.157 +                prefetchqueue[0]=prefetchqueue[1];
   4.158 +                prefetchqueue[1]=prefetchqueue[2];
   4.159 +                prefetchqueue[2]=prefetchqueue[3];
   4.160 +                prefetchqueue[3]=prefetchqueue[4];
   4.161 +                prefetchqueue[4]=prefetchqueue[5];
   4.162 +                prefetchw--;
   4.163 +//                if (output) printf("PREFETCH %04X:%04X %02X %04X %04X %i\n",CS,pc,temp,pc,prefetchpc,prefetchw);
   4.164 +                fetchcycles-=4;
   4.165 +//                fetchclocks+=4;
   4.166 +                pc++;
   4.167 +        }
   4.168 +//        if (output) printf("%i\n",fetchcycles);
   4.169 +        return temp;
   4.170 +}
   4.171 +
   4.172 +inline void FETCHADD(int c)
   4.173 +{
   4.174 +        int d;
   4.175 +//        if (output) printf("FETCHADD %i\n",c);
   4.176 +        if (c<0) return;
   4.177 +        if (prefetchw>((is8086)?4:3)) return;
   4.178 +        d=c+(fetchcycles&3);
   4.179 +        while (d>3 && prefetchw<((is8086)?6:4))
   4.180 +        {
   4.181 +                d-=4;
   4.182 +                if (is8086 && !(prefetchpc&1))
   4.183 +                {
   4.184 +                        prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
   4.185 +//                        printf("PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]);
   4.186 +                        prefetchpc++;
   4.187 +                        prefetchw++;
   4.188 +                }
   4.189 +                if (prefetchw<6)
   4.190 +                {
   4.191 +                        prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
   4.192 +//                        printf("PREFETCHED from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]);
   4.193 +                        prefetchpc++;
   4.194 +                        prefetchw++;
   4.195 +                }
   4.196 +        }
   4.197 +        fetchcycles+=c;
   4.198 +        if (fetchcycles>16) fetchcycles=16;
   4.199 +//        if (fetchcycles>24) fetchcycles=24;
   4.200 +}
   4.201 +
   4.202 +void FETCHCOMPLETE()
   4.203 +{
   4.204 +//        pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw);
   4.205 +        if (!(fetchcycles&3)) return;
   4.206 +        if (prefetchw>((is8086)?4:3)) return;
   4.207 +        if (!prefetchw) nextcyc=(4-(fetchcycles&3));
   4.208 +        cycles-=(4-(fetchcycles&3));
   4.209 +        fetchclocks+=(4-(fetchcycles&3));
   4.210 +                if (is8086 && !(prefetchpc&1))
   4.211 +                {
   4.212 +                        prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
   4.213 +//                        printf("PREFETCHEDc from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]);
   4.214 +                        prefetchpc++;
   4.215 +                        prefetchw++;
   4.216 +                }
   4.217 +                if (prefetchw<6)
   4.218 +                {
   4.219 +                        prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
   4.220 +//                        printf("PREFETCHEDc from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]);
   4.221 +                        prefetchpc++;
   4.222 +                        prefetchw++;
   4.223 +                }
   4.224 +                fetchcycles+=(4-(fetchcycles&3));
   4.225 +}
   4.226 +
   4.227 +inline void FETCHCLEAR()
   4.228 +{
   4.229 +/*        int c;
   4.230 +        fetchcycles=0;
   4.231 +        prefetchpc=pc;
   4.232 +        if (is8086 && (prefetchpc&1)) cycles-=4;
   4.233 +        for (c=0;c<((is8086)?6:4);c++)
   4.234 +        {
   4.235 +                prefetchqueue[c]=readmembf(cs+prefetchpc);
   4.236 +                if (!is8086 || !(prefetchpc&1)) cycles-=4;
   4.237 +                prefetchpc++;
   4.238 +        }
   4.239 +        prefetchw=(is8086)?6:4;*/
   4.240 +//        fetchcycles=0;
   4.241 +        prefetchpc=pc;
   4.242 +        prefetchw=0;
   4.243 +        memcycs=cycdiff-cycles;
   4.244 +        fetchclocks=0;
   4.245 +//        memcycs=cycles;
   4.246 +/*        prefetchqueue[0]=readmembf(cs+prefetchpc);
   4.247 +        prefetchpc++;
   4.248 +        prefetchw=1;
   4.249 +        if (is8086 && prefetchpc&1)
   4.250 +        {
   4.251 +                prefetchqueue[1]=readmembf(cs+prefetchpc);
   4.252 +                prefetchpc++;
   4.253 +        }*/
   4.254 +}
   4.255 +
   4.256 +static uint16_t getword()
   4.257 +{
   4.258 +        uint8_t temp=FETCH();
   4.259 +        return temp|(FETCH()<<8);
   4.260 +}
   4.261 +
   4.262 +
   4.263 +/*EA calculation*/
   4.264 +
   4.265 +/*R/M - bits 0-2 - R/M   bits 3-5 - Reg   bits 6-7 - mod
   4.266 +  From 386 programmers manual :
   4.267 +r8(/r)                     AL    CL    DL    BL    AH    CH    DH    BH
   4.268 +r16(/r)                    AX    CX    DX    BX    SP    BP    SI    DI
   4.269 +r32(/r)                    EAX   ECX   EDX   EBX   ESP   EBP   ESI   EDI
   4.270 +/digit (Opcode)            0     1     2     3     4     5     6     7
   4.271 +REG =                      000   001   010   011   100   101   110   111
   4.272 +  ÚÄÄÄAddress
   4.273 +disp8 denotes an 8-bit displacement following the ModR/M byte, to be
   4.274 +sign-extended and added to the index. disp16 denotes a 16-bit displacement
   4.275 +following the ModR/M byte, to be added to the index. Default segment
   4.276 +register is SS for the effective addresses containing a BP index, DS for
   4.277 +other effective addresses.
   4.278 +            ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄModR/M Values in HexadecimalÄÄÄÄÄÄÄÄ¿
   4.279 +
   4.280 +[BX + SI]            000   00    08    10    18    20    28    30    38
   4.281 +[BX + DI]            001   01    09    11    19    21    29    31    39
   4.282 +[BP + SI]            010   02    0A    12    1A    22    2A    32    3A
   4.283 +[BP + DI]            011   03    0B    13    1B    23    2B    33    3B
   4.284 +[SI]             00  100   04    0C    14    1C    24    2C    34    3C
   4.285 +[DI]                 101   05    0D    15    1D    25    2D    35    3D
   4.286 +disp16               110   06    0E    16    1E    26    2E    36    3E
   4.287 +[BX]                 111   07    0F    17    1F    27    2F    37    3F
   4.288 +
   4.289 +[BX+SI]+disp8        000   40    48    50    58    60    68    70    78
   4.290 +[BX+DI]+disp8        001   41    49    51    59    61    69    71    79
   4.291 +[BP+SI]+disp8        010   42    4A    52    5A    62    6A    72    7A
   4.292 +[BP+DI]+disp8        011   43    4B    53    5B    63    6B    73    7B
   4.293 +[SI]+disp8       01  100   44    4C    54    5C    64    6C    74    7C
   4.294 +[DI]+disp8           101   45    4D    55    5D    65    6D    75    7D
   4.295 +[BP]+disp8           110   46    4E    56    5E    66    6E    76    7E
   4.296 +[BX]+disp8           111   47    4F    57    5F    67    6F    77    7F
   4.297 +
   4.298 +[BX+SI]+disp16       000   80    88    90    98    A0    A8    B0    B8
   4.299 +[BX+DI]+disp16       001   81    89    91    99    A1    A9    B1    B9
   4.300 +[BX+SI]+disp16       010   82    8A    92    9A    A2    AA    B2    BA
   4.301 +[BX+DI]+disp16       011   83    8B    93    9B    A3    AB    B3    BB
   4.302 +[SI]+disp16      10  100   84    8C    94    9C    A4    AC    B4    BC
   4.303 +[DI]+disp16          101   85    8D    95    9D    A5    AD    B5    BD
   4.304 +[BP]+disp16          110   86    8E    96    9E    A6    AE    B6    BE
   4.305 +[BX]+disp16          111   87    8F    97    9F    A7    AF    B7    BF
   4.306 +
   4.307 +EAX/AX/AL            000   C0    C8    D0    D8    E0    E8    F0    F8
   4.308 +ECX/CX/CL            001   C1    C9    D1    D9    E1    E9    F1    F9
   4.309 +EDX/DX/DL            010   C2    CA    D2    DA    E2    EA    F2    FA
   4.310 +EBX/BX/BL            011   C3    CB    D3    DB    E3    EB    F3    FB
   4.311 +ESP/SP/AH        11  100   C4    CC    D4    DC    E4    EC    F4    FC
   4.312 +EBP/BP/CH            101   C5    CD    D5    DD    E5    ED    F5    FD
   4.313 +ESI/SI/DH            110   C6    CE    D6    DE    E6    EE    F6    FE
   4.314 +EDI/DI/BH            111   C7    CF    D7    DF    E7    EF    F7    FF
   4.315 +
   4.316 +mod = 11 - register
   4.317 +      10 - address + 16 bit displacement
   4.318 +      01 - address + 8 bit displacement
   4.319 +      00 - address
   4.320 +
   4.321 +reg = If mod=11,  (depending on data size, 16 bits/8 bits, 32 bits=extend 16 bit registers)
   4.322 +      0=AX/AL   1=CX/CL   2=DX/DL   3=BX/BL
   4.323 +      4=SP/AH   5=BP/CH   6=SI/DH   7=DI/BH
   4.324 +
   4.325 +      Otherwise, LSB selects SI/DI (0=SI), NMSB selects BX/BP (0=BX), and MSB
   4.326 +      selects whether BX/BP are used at all (0=used).
   4.327 +
   4.328 +      mod=00 is an exception though
   4.329 +      6=16 bit displacement only
   4.330 +      7=[BX]
   4.331 +
   4.332 +      Usage varies with instructions.
   4.333 +
   4.334 +      MOV AL,BL has ModR/M as C3, for example.
   4.335 +      mod=11, reg=0, r/m=3
   4.336 +      MOV uses reg as dest, and r/m as src.
   4.337 +      reg 0 is AL, reg 3 is BL
   4.338 +
   4.339 +      If BP or SP are in address calc, seg is SS, else DS
   4.340 +*/
   4.341 +
   4.342 +int cycles=0;
   4.343 +uint32_t easeg,eaaddr;
   4.344 +int rm,reg,mod,rmdat;
   4.345 +
   4.346 +uint16_t zero=0;
   4.347 +uint16_t *mod1add[2][8];
   4.348 +uint32_t *mod1seg[8];
   4.349 +
   4.350 +int slowrm[8];
   4.351 +
   4.352 +void makemod1table()
   4.353 +{
   4.354 +        mod1add[0][0]=&BX; mod1add[0][1]=&BX; mod1add[0][2]=&BP; mod1add[0][3]=&BP;
   4.355 +        mod1add[0][4]=&SI; mod1add[0][5]=&DI; mod1add[0][6]=&BP; mod1add[0][7]=&BX;
   4.356 +        mod1add[1][0]=&SI; mod1add[1][1]=&DI; mod1add[1][2]=&SI; mod1add[1][3]=&DI;
   4.357 +        mod1add[1][4]=&zero; mod1add[1][5]=&zero; mod1add[1][6]=&zero; mod1add[1][7]=&zero;
   4.358 +        slowrm[0]=0; slowrm[1]=1; slowrm[2]=1; slowrm[3]=0;
   4.359 +        mod1seg[0]=&ds; mod1seg[1]=&ds; mod1seg[2]=&ss; mod1seg[3]=&ss;
   4.360 +        mod1seg[4]=&ds; mod1seg[5]=&ds; mod1seg[6]=&ss; mod1seg[7]=&ds;
   4.361 +}
   4.362 +
   4.363 +static void fetcheal()
   4.364 +{
   4.365 +        if (!mod && rm==6) { eaaddr=getword(); easeg=ds; FETCHADD(6); }
   4.366 +        else
   4.367 +        {
   4.368 +                switch (mod)
   4.369 +                {
   4.370 +                        case 0:
   4.371 +                        eaaddr=0;
   4.372 +                        if (rm&4) FETCHADD(5);
   4.373 +                        else      FETCHADD(7+slowrm[rm]);
   4.374 +                        break;
   4.375 +                        case 1:
   4.376 +                        eaaddr=(uint16_t)(int8_t)FETCH();
   4.377 +                        if (rm&4) FETCHADD(9);
   4.378 +                        else      FETCHADD(11+slowrm[rm]);
   4.379 +                        break;
   4.380 +                        case 2:
   4.381 +                        eaaddr=getword();
   4.382 +                        if (rm&4) FETCHADD(9);
   4.383 +                        else      FETCHADD(11+slowrm[rm]);
   4.384 +                        break;
   4.385 +                }
   4.386 +                eaaddr+=(*mod1add[0][rm])+(*mod1add[1][rm]);
   4.387 +                easeg=*mod1seg[rm];
   4.388 +                eaaddr&=0xFFFF;
   4.389 +        }
   4.390 +}
   4.391 +
   4.392 +static inline uint8_t geteab()
   4.393 +{
   4.394 +        if (mod==3)
   4.395 +           return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l;
   4.396 +        return readmemb(easeg+eaaddr);
   4.397 +}
   4.398 +
   4.399 +static inline uint16_t geteaw()
   4.400 +{
   4.401 +        if (mod==3)
   4.402 +           return regs[rm].w;
   4.403 +//        if (output==3) printf("GETEAW %04X:%08X\n",easeg,eaaddr);
   4.404 +        return readmemw(easeg,eaaddr);
   4.405 +}
   4.406 +
   4.407 +static inline uint16_t geteaw2()
   4.408 +{
   4.409 +        if (mod==3)
   4.410 +           return regs[rm].w;
   4.411 +//        printf("Getting addr from %04X:%04X %05X\n",easeg,eaaddr+2,easeg+eaaddr+2);
   4.412 +        return readmemw(easeg,(eaaddr+2)&0xFFFF);
   4.413 +}
   4.414 +
   4.415 +static inline void seteab(uint8_t val)
   4.416 +{
   4.417 +        if (mod==3)
   4.418 +        {
   4.419 +                if (rm&4) regs[rm&3].b.h=val;
   4.420 +                else      regs[rm&3].b.l=val;
   4.421 +        }
   4.422 +        else
   4.423 +        {
   4.424 +                writememb(easeg+eaaddr,val);
   4.425 +        }
   4.426 +}
   4.427 +
   4.428 +static inline void seteaw(uint16_t val)
   4.429 +{
   4.430 +        if (mod==3)
   4.431 +           regs[rm].w=val;
   4.432 +        else
   4.433 +        {
   4.434 +                writememw(easeg,eaaddr,val);
   4.435 +//                writememb(easeg+eaaddr+1,val>>8);
   4.436 +        }
   4.437 +}
   4.438 +
   4.439 +#define getr8(r)   ((r&4)?regs[r&3].b.h:regs[r&3].b.l)
   4.440 +
   4.441 +#define setr8(r,v) if (r&4) regs[r&3].b.h=v; \
   4.442 +                   else     regs[r&3].b.l=v;
   4.443 +
   4.444 +
   4.445 +/*Flags*/
   4.446 +uint8_t znptable8[256];
   4.447 +uint16_t znptable16[65536];
   4.448 +
   4.449 +void makeznptable()
   4.450 +{
   4.451 +        int c,d;
   4.452 +        for (c=0;c<256;c++)
   4.453 +        {
   4.454 +                d=0;
   4.455 +                if (c&1) d++;
   4.456 +                if (c&2) d++;
   4.457 +                if (c&4) d++;
   4.458 +                if (c&8) d++;
   4.459 +                if (c&16) d++;
   4.460 +                if (c&32) d++;
   4.461 +                if (c&64) d++;
   4.462 +                if (c&128) d++;
   4.463 +                if (d&1)
   4.464 +                   znptable8[c]=0;
   4.465 +                else
   4.466 +                   znptable8[c]=P_FLAG;
   4.467 +                   if (c == 0xb1) pclog("znp8 b1 = %i %02X\n", d, znptable8[c]);
   4.468 +                if (!c) znptable8[c]|=Z_FLAG;
   4.469 +                if (c&0x80) znptable8[c]|=N_FLAG;
   4.470 +        }
   4.471 +        for (c=0;c<65536;c++)
   4.472 +        {
   4.473 +                d=0;
   4.474 +                if (c&1) d++;
   4.475 +                if (c&2) d++;
   4.476 +                if (c&4) d++;
   4.477 +                if (c&8) d++;
   4.478 +                if (c&16) d++;
   4.479 +                if (c&32) d++;
   4.480 +                if (c&64) d++;
   4.481 +                if (c&128) d++;
   4.482 +                if (d&1)
   4.483 +                   znptable16[c]=0;
   4.484 +                else
   4.485 +                   znptable16[c]=P_FLAG;
   4.486 +                if (c == 0xb1) pclog("znp16 b1 = %i %02X\n", d, znptable16[c]);
   4.487 +                if (c == 0x65b1) pclog("znp16 65b1 = %i %02X\n", d, znptable16[c]);
   4.488 +                if (!c) znptable16[c]|=Z_FLAG;
   4.489 +                if (c&0x8000) znptable16[c]|=N_FLAG;
   4.490 +      }
   4.491 +//        isram[0xF]=1;
   4.492 +//        printf("isram 0 = %i\n",isram[0]);
   4.493 +      
   4.494 +//      makemod1table();
   4.495 +}
   4.496 +int timetolive=0;
   4.497 +
   4.498 +extern uint32_t oldcs2;
   4.499 +extern uint32_t oldpc2;
   4.500 +
   4.501 +int indump = 0;
   4.502 +
   4.503 +void dumpregs()
   4.504 +{
   4.505 +        FILE *f;
   4.506 +        int c,d=0,e=0,ff;
   4.507 +        if (indump) return;
   4.508 +        indump = 1;
   4.509 +//        return;
   4.510 +        output=0;
   4.511 +//        return;
   4.512 +//        savenvr();
   4.513 +//        return;
   4.514 +chdir(pcempath);
   4.515 +        nopageerrors=1;
   4.516 +/*        f=fopen("rram3.dmp","wb");
   4.517 +        for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f);
   4.518 +        fclose(f);*/
   4.519 +        f=fopen("ram.dmp","wb");
   4.520 +        fwrite(ram,mem_size*1024*1024,1,f);
   4.521 +        fclose(f);
   4.522 +/*        pclog("Dumping rram5.dmp\n");
   4.523 +        f=fopen("rram5.dmp","wb");
   4.524 +        for (c=0;c<0x1000000;c++) putc(readmemb(c+0x10150000),f);
   4.525 +        fclose(f);*/
   4.526 +        pclog("Dumping rram.dmp\n");
   4.527 +        f=fopen("rram.dmp","wb");
   4.528 +        for (c=0;c<0x1000000;c++) putc(readmemb(c),f);
   4.529 +        fclose(f);
   4.530 +/*        f=fopen("rram2.dmp","wb");
   4.531 +        for (c=0;c<0x100000;c++) putc(readmemb(c+0xbff00000),f);
   4.532 +        fclose(f);
   4.533 +        f = fopen("stack.dmp","wb");
   4.534 +        for (c = 0; c < 0x6000; c++) putc(readmemb(c+0xFFDFA000), f);
   4.535 +        fclose(f);
   4.536 +        f = fopen("tempx.dmp","wb");
   4.537 +        for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFC816000), f);
   4.538 +        fclose(f);
   4.539 +        f = fopen("tempx2.dmp","wb");
   4.540 +        for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFDEF5000), f);
   4.541 +        fclose(f);*/
   4.542 +        pclog("Dumping rram4.dmp\n");
   4.543 +        f=fopen("rram4.dmp","wb");
   4.544 +        for (c=0;c<0x0050000;c++) 
   4.545 +        {
   4.546 +                abrt = 0;
   4.547 +                putc(readmemb386l(0,c+0x80000000),f);
   4.548 +        }
   4.549 +        fclose(f);
   4.550 +        pclog("Dumping done\n");        
   4.551 +/*        f=fopen("rram6.dmp","wb");
   4.552 +        for (c=0;c<0x1000000;c++) putc(readmemb(c+0xBF000000),f);
   4.553 +        fclose(f);*/
   4.554 +/*        f=fopen("ram6.bin","wb");
   4.555 +        fwrite(ram+0x10100,0xA000,1,f);
   4.556 +        fclose(f);
   4.557 +        f=fopen("boot.bin","wb");
   4.558 +        fwrite(ram+0x7C00,0x200,1,f);
   4.559 +        fclose(f);
   4.560 +        f=fopen("ram7.bin","wb");
   4.561 +        fwrite(ram+0x11100,0x2000,1,f);
   4.562 +        fclose(f);
   4.563 +        f=fopen("ram8.bin","wb");
   4.564 +        fwrite(ram+0x3D210,0x200,1,f);
   4.565 +        fclose(f);        */
   4.566 +        f=fopen("vram.dmp","wb");
   4.567 +        fwrite(vram,0x400000,1,f);
   4.568 +        fclose(f);
   4.569 +/*        f=fopen("bios.dmp","wb");
   4.570 +        fwrite(rom,0x20000,1,f);
   4.571 +        fclose(f);
   4.572 +        f=fopen("vbios.dmp","wb");
   4.573 +        fwrite(vrom,0x8000,1,f);
   4.574 +        fclose(f);*/
   4.575 +/*        f=fopen("kernel.dmp","wb");
   4.576 +        for (c=0;c<0x200000;c++) putc(readmemb(c+0xC0000000),f);
   4.577 +        fclose(f);*/
   4.578 +/*        f=fopen("rram.dmp","wb");
   4.579 +        for (c=0;c<0x1500000;c++) putc(readmemb(c),f);
   4.580 +        fclose(f);
   4.581 +        if (!times)
   4.582 +        {
   4.583 +                f=fopen("thing.dmp","wb");
   4.584 +                fwrite(ram+0x11E50,0x1000,1,f);
   4.585 +                fclose(f);
   4.586 +        }*/
   4.587 +        if (is386)
   4.588 +           printf("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",EAX,EBX,ECX,EDX,EDI,ESI,EBP,ESP);
   4.589 +        else
   4.590 +           printf("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP);
   4.591 +        printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",pc,CS,DS,ES,SS,flags);
   4.592 +        printf("%04X:%04X %04X:%04X\n",oldcs,oldpc, oldcs2, oldpc2);
   4.593 +        printf("%i ins\n",ins);
   4.594 +        if (is386)
   4.595 +           printf("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real");
   4.596 +        else
   4.597 +           printf("In %s mode\n",(msw&1)?"protected":"real");
   4.598 +        printf("CS : base=%06X limit=%04X access=%02X\n",cs,_cs.limit,_cs.access);
   4.599 +        printf("DS : base=%06X limit=%04X access=%02X\n",ds,_ds.limit,_ds.access);
   4.600 +        printf("ES : base=%06X limit=%04X access=%02X\n",es,_es.limit,_es.access);
   4.601 +        if (is386)
   4.602 +        {
   4.603 +                printf("FS : base=%06X limit=%04X access=%02X\n",fs,_fs.limit,_fs.access);
   4.604 +                printf("GS : base=%06X limit=%04X access=%02X\n",gs,_gs.limit,_gs.access);
   4.605 +        }
   4.606 +        printf("SS : base=%06X limit=%04X access=%02X\n",ss,_ss.limit,_ss.access);
   4.607 +        printf("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit);
   4.608 +        printf("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit);
   4.609 +        printf("IDT : base=%06X limit=%04X\n",idt.base,idt.limit);
   4.610 +        printf("TR  : base=%06X limit=%04X\n", tr.base, tr.limit);
   4.611 +        if (is386)
   4.612 +        {
   4.613 +                printf("386 in %s mode   stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit");
   4.614 +                printf("CR0=%08X CR2=%08X CR3=%08X\n",cr0,cr2,cr3);
   4.615 +        }
   4.616 +        printf("Entries in readlookup : %i    writelookup : %i\n",readlnum,writelnum);
   4.617 +        for (c=0;c<1024*1024;c++)
   4.618 +        {
   4.619 +                if (readlookup2[c]!=0xFFFFFFFF) d++;
   4.620 +                if (writelookup2[c]!=0xFFFFFFFF) e++;
   4.621 +        }
   4.622 +        printf("Entries in readlookup : %i    writelookup : %i\n",d,e);
   4.623 +        d=0;
   4.624 +        x87_dumpregs();
   4.625 +        for (c = 0; c < 256; c++)
   4.626 +        {
   4.627 +                e = -1;
   4.628 +                for (d = 0; d < 256; d++)
   4.629 +                {
   4.630 +                        if (inscounts[d] > e)
   4.631 +                        {
   4.632 +                                e = inscounts[d];
   4.633 +                                ff = d;
   4.634 +                        }
   4.635 +                }
   4.636 +                inscounts[ff] = -1;
   4.637 +//                printf("Opcode %02x - %i\n", ff, e);
   4.638 +        }
   4.639 +/*        for (c=0;c<1024*1024;c++)
   4.640 +        {
   4.641 +                if (mmucache[c]!=0xFFFFFFFF) d++;
   4.642 +        }
   4.643 +        printf("Entries in MMU cache : %i\n",d);*/
   4.644 +        indump = 0;
   4.645 +}
   4.646 +
   4.647 +int resets = 0;
   4.648 +void resetx86()
   4.649 +{
   4.650 +        pclog("x86 reset\n");
   4.651 +        resets++;
   4.652 +        ins = 0;
   4.653 +        use32=0;
   4.654 +        stack32=0;
   4.655 +//        i86_Reset();
   4.656 +//        cs=0xFFFF0;
   4.657 +        pc=0;
   4.658 +        msw=0;
   4.659 +        cr0=0;
   4.660 +        eflags=0;
   4.661 +        cgate32=0;
   4.662 +        loadcs(0xFFFF);
   4.663 +        rammask=0xFFFFFFFF;
   4.664 +        flags=2;
   4.665 +        initmmucache();
   4.666 +        resetreadlookup();
   4.667 +        makemod1table();
   4.668 +        resetmcr();
   4.669 +        FETCHCLEAR();
   4.670 +        x87_reset();
   4.671 +        cpu_set_edx();
   4.672 +        ESP=0;
   4.673 +        mmu_perm=4;
   4.674 +        memset(inscounts, 0, sizeof(inscounts));
   4.675 +}
   4.676 +
   4.677 +void softresetx86()
   4.678 +{
   4.679 +//      dumpregs();
   4.680 +//        exit(-1);
   4.681 +        use32=0;
   4.682 +        stack32=0;
   4.683 +//        i86_Reset();
   4.684 +//        cs=0xFFFF0;
   4.685 +        pc=0;
   4.686 +        msw=0;
   4.687 +        cr0=0;
   4.688 +        eflags=0;
   4.689 +        cgate32=0;
   4.690 +        loadcs(0xFFFF);
   4.691 +        //rammask=0xFFFFFFFF;
   4.692 +        flags=2;
   4.693 +}
   4.694 +
   4.695 +static void setznp8(uint8_t val)
   4.696 +{
   4.697 +        flags&=~0xC4;
   4.698 +        flags|=znptable8[val];
   4.699 +}
   4.700 +
   4.701 +static void setznp16(uint16_t val)
   4.702 +{
   4.703 +        flags&=~0xC4;
   4.704 +        flags|=znptable16[val];
   4.705 +}
   4.706 +
   4.707 +static void setadd8(uint8_t a, uint8_t b)
   4.708 +{
   4.709 +        uint16_t c=(uint16_t)a+(uint16_t)b;
   4.710 +        flags&=~0x8D5;
   4.711 +        flags|=znptable8[c&0xFF];
   4.712 +        if (c&0x100) flags|=C_FLAG;
   4.713 +        if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
   4.714 +        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
   4.715 +}
   4.716 +static void setadd8nc(uint8_t a, uint8_t b)
   4.717 +{
   4.718 +        uint16_t c=(uint16_t)a+(uint16_t)b;
   4.719 +        flags&=~0x8D4;
   4.720 +        flags|=znptable8[c&0xFF];
   4.721 +        if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
   4.722 +        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
   4.723 +}
   4.724 +static void setadc8(uint8_t a, uint8_t b)
   4.725 +{
   4.726 +        uint16_t c=(uint16_t)a+(uint16_t)b+tempc;
   4.727 +        flags&=~0x8D5;
   4.728 +        flags|=znptable8[c&0xFF];
   4.729 +        if (c&0x100) flags|=C_FLAG;
   4.730 +        if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
   4.731 +        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
   4.732 +}
   4.733 +static void setadd16(uint16_t a, uint16_t b)
   4.734 +{
   4.735 +        uint32_t c=(uint32_t)a+(uint32_t)b;
   4.736 +        flags&=~0x8D5;
   4.737 +        flags|=znptable16[c&0xFFFF];
   4.738 +        if (c&0x10000) flags|=C_FLAG;
   4.739 +        if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
   4.740 +        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
   4.741 +}
   4.742 +static void setadd16nc(uint16_t a, uint16_t b)
   4.743 +{
   4.744 +        uint32_t c=(uint32_t)a+(uint32_t)b;
   4.745 +        flags&=~0x8D4;
   4.746 +        flags|=znptable16[c&0xFFFF];
   4.747 +        if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
   4.748 +        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
   4.749 +}
   4.750 +static void setadc16(uint16_t a, uint16_t b)
   4.751 +{
   4.752 +        uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
   4.753 +        flags&=~0x8D5;
   4.754 +        flags|=znptable16[c&0xFFFF];
   4.755 +        if (c&0x10000) flags|=C_FLAG;
   4.756 +        if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
   4.757 +        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
   4.758 +}
   4.759 +
   4.760 +static void setsub8(uint8_t a, uint8_t b)
   4.761 +{
   4.762 +        uint16_t c=(uint16_t)a-(uint16_t)b;
   4.763 +        flags&=~0x8D5;
   4.764 +        flags|=znptable8[c&0xFF];
   4.765 +        if (c&0x100) flags|=C_FLAG;
   4.766 +        if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
   4.767 +        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
   4.768 +}
   4.769 +static void setsub8nc(uint8_t a, uint8_t b)
   4.770 +{
   4.771 +        uint16_t c=(uint16_t)a-(uint16_t)b;
   4.772 +        flags&=~0x8D4;
   4.773 +        flags|=znptable8[c&0xFF];
   4.774 +        if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
   4.775 +        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
   4.776 +}
   4.777 +static void setsbc8(uint8_t a, uint8_t b)
   4.778 +{
   4.779 +        uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc);
   4.780 +        flags&=~0x8D5;
   4.781 +        flags|=znptable8[c&0xFF];
   4.782 +        if (c&0x100) flags|=C_FLAG;
   4.783 +        if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
   4.784 +        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
   4.785 +}
   4.786 +static void setsub16(uint16_t a, uint16_t b)
   4.787 +{
   4.788 +        uint32_t c=(uint32_t)a-(uint32_t)b;
   4.789 +        flags&=~0x8D5;
   4.790 +        flags|=znptable16[c&0xFFFF];
   4.791 +        if (c&0x10000) flags|=C_FLAG;
   4.792 +        if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
   4.793 +//        if (output) printf("%04X %04X %i\n",a^b,a^c,flags&V_FLAG);
   4.794 +        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
   4.795 +}
   4.796 +static void setsub16nc(uint16_t a, uint16_t b)
   4.797 +{
   4.798 +        uint32_t c=(uint32_t)a-(uint32_t)b;
   4.799 +        flags&=~0x8D4;
   4.800 +        flags|=(znptable16[c&0xFFFF]&~4);
   4.801 +        flags|=(znptable8[c&0xFF]&4);
   4.802 +        if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
   4.803 +        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
   4.804 +}
   4.805 +static void setsbc16(uint16_t a, uint16_t b)
   4.806 +{
   4.807 +        uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
   4.808 +        flags&=~0x8D5;
   4.809 +        flags|=(znptable16[c&0xFFFF]&~4);
   4.810 +        flags|=(znptable8[c&0xFF]&4);
   4.811 +        if (c&0x10000) flags|=C_FLAG;
   4.812 +        if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
   4.813 +        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
   4.814 +}
   4.815 +
   4.816 +int totaldiff = 0;
   4.817 +int current_diff = 0;
   4.818 +void clockhardware()
   4.819 +{
   4.820 +        int diff = cycdiff - cycles - current_diff;
   4.821 +        
   4.822 +        current_diff += diff;
   4.823 +        totaldiff += diff;
   4.824 +        pit.c[0] -= diff;
   4.825 +        pit.c[1] -= diff;
   4.826 +        if (ppi.pb & 1) pit.c[2] -= diff;
   4.827 +        if ((pit.c[0] < 1) || (pit.c[1] < 1) || (pit.c[2] < 1)) pit_poll();
   4.828 +        
   4.829 +        timer_clock(diff);
   4.830 +}
   4.831 +
   4.832 +
   4.833 +int firstrepcycle=1;
   4.834 +
   4.835 +void rep(int fv)
   4.836 +{
   4.837 +        uint8_t temp;
   4.838 +        int c=CX;
   4.839 +        uint8_t temp2;
   4.840 +        uint16_t tempw,tempw2;
   4.841 +        uint16_t ipc=oldpc;//pc-1;
   4.842 +        int changeds=0;
   4.843 +        uint32_t oldds;
   4.844 +        startrep:
   4.845 +        temp=FETCH();
   4.846 +//        if (firstrepcycle && temp==0xA5) printf("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI);
   4.847 +//        if (output) printf("REP %02X %04X\n",temp,ipc);
   4.848 +        switch (temp)
   4.849 +        {
   4.850 +                case 0x08:
   4.851 +                pc=ipc+1;
   4.852 +                cycles-=2;
   4.853 +                FETCHCLEAR();
   4.854 +                break;
   4.855 +                case 0x26: /*ES:*/
   4.856 +                oldds=ds;
   4.857 +                ds=es;
   4.858 +                changeds=1;
   4.859 +                cycles-=2;
   4.860 +                goto startrep;
   4.861 +                break;
   4.862 +                case 0x2E: /*CS:*/
   4.863 +                oldds=ds;
   4.864 +                ds=cs;
   4.865 +                changeds=1;
   4.866 +                cycles-=2;
   4.867 +                goto startrep;
   4.868 +                break;
   4.869 +                case 0x36: /*SS:*/
   4.870 +                oldds=ds;
   4.871 +                ds=ss;
   4.872 +                changeds=1;
   4.873 +                cycles-=2;
   4.874 +                goto startrep;
   4.875 +                break;
   4.876 +                case 0x6E: /*REP OUTSB*/
   4.877 +                if (c>0)
   4.878 +                {
   4.879 +                        temp2=readmemb(ds+SI);
   4.880 +                        outb(DX,temp2);
   4.881 +                        if (flags&D_FLAG) SI--;
   4.882 +                        else              SI++;
   4.883 +                        c--;
   4.884 +                        cycles-=5;
   4.885 +                }
   4.886 +                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
   4.887 +                else firstrepcycle=1;
   4.888 +                break;
   4.889 +                case 0xA4: /*REP MOVSB*/
   4.890 +                while (c>0 && !IRQTEST)
   4.891 +                {
   4.892 +                        temp2=readmemb(ds+SI);
   4.893 +                        writememb(es+DI,temp2);
   4.894 +//                        if (output) printf("Moved %02X from %04X:%04X to %04X:%04X\n",temp2,ds>>4,SI,es>>4,DI);
   4.895 +                        if (flags&D_FLAG) { DI--; SI--; }
   4.896 +                        else              { DI++; SI++; }
   4.897 +                        c--;
   4.898 +                        cycles-=17;
   4.899 +                        clockhardware();
   4.900 +                        FETCHADD(17-memcycs);
   4.901 +                }
   4.902 +                if (IRQTEST && c>0) pc=ipc;
   4.903 +//                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
   4.904 +//                else firstrepcycle=1;
   4.905 +//                }
   4.906 +                break;
   4.907 +                case 0xA5: /*REP MOVSW*/
   4.908 +                while (c>0 && !IRQTEST)
   4.909 +                {
   4.910 +                        memcycs=0;
   4.911 +                        tempw=readmemw(ds,SI);
   4.912 +                        writememw(es,DI,tempw);
   4.913 +                        if (flags&D_FLAG) { DI-=2; SI-=2; }
   4.914 +                        else              { DI+=2; SI+=2; }
   4.915 +                        c--;
   4.916 +                        cycles-=17;
   4.917 +                        clockhardware();
   4.918 +                        FETCHADD(17 - memcycs);
   4.919 +                }
   4.920 +                if (IRQTEST && c>0) pc=ipc;
   4.921 +//                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
   4.922 +//                else firstrepcycle=1;
   4.923 +//                }
   4.924 +                break;
   4.925 +                case 0xA6: /*REP CMPSB*/
   4.926 +                if (fv) flags|=Z_FLAG;
   4.927 +                else    flags&=~Z_FLAG;
   4.928 +                while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST)
   4.929 +                {
   4.930 +                        memcycs=0;
   4.931 +                        temp=readmemb(ds+SI);
   4.932 +                        temp2=readmemb(es+DI);
   4.933 +//                        printf("CMPSB %c %c %i %05X %05X %04X:%04X\n",temp,temp2,c,ds+SI,es+DI,cs>>4,pc);
   4.934 +                        if (flags&D_FLAG) { DI--; SI--; }
   4.935 +                        else              { DI++; SI++; }
   4.936 +                        c--;
   4.937 +                        cycles -= 30;
   4.938 +                        setsub8(temp,temp2);
   4.939 +                        clockhardware();
   4.940 +                        FETCHADD(30 - memcycs);
   4.941 +                }
   4.942 +                if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) pc=ipc;
   4.943 +//                if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
   4.944 +//                else firstrepcycle=1;
   4.945 +                break;
   4.946 +                case 0xA7: /*REP CMPSW*/
   4.947 +                if (fv) flags|=Z_FLAG;
   4.948 +                else    flags&=~Z_FLAG;
   4.949 +                while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST)
   4.950 +                {
   4.951 +                        memcycs=0;
   4.952 +                        tempw=readmemw(ds,SI);
   4.953 +                        tempw2=readmemw(es,DI);
   4.954 +                        if (flags&D_FLAG) { DI-=2; SI-=2; }
   4.955 +                        else              { DI+=2; SI+=2; }
   4.956 +                        c--;
   4.957 +                        cycles -= 30;
   4.958 +                        setsub16(tempw,tempw2);
   4.959 +                        clockhardware();
   4.960 +                        FETCHADD(30 - memcycs);
   4.961 +                }
   4.962 +                if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) pc=ipc;
   4.963 +//                if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
   4.964 +//                else firstrepcycle=1;
   4.965 +//                if (firstrepcycle) printf("REP CMPSW  %06X:%04X %06X:%04X %04X %04X\n",ds,SI,es,DI,tempw,tempw2);
   4.966 +                break;
   4.967 +                case 0xAA: /*REP STOSB*/
   4.968 +                while (c>0 && !IRQTEST)
   4.969 +                {
   4.970 +                        memcycs=0;
   4.971 +                        writememb(es+DI,AL);
   4.972 +                        if (flags&D_FLAG) DI--;
   4.973 +                        else              DI++;
   4.974 +                        c--;
   4.975 +                        cycles -= 10;
   4.976 +                        clockhardware();
   4.977 +                        FETCHADD(10 - memcycs);
   4.978 +                }
   4.979 +                if (IRQTEST && c>0) pc=ipc;
   4.980 +//                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
   4.981 +//                else firstrepcycle=1;
   4.982 +                break;
   4.983 +                case 0xAB: /*REP STOSW*/
   4.984 +                while (c>0 && !IRQTEST)
   4.985 +                {
   4.986 +                        memcycs=0;
   4.987 +                        writememw(es,DI,AX);
   4.988 +                        if (flags&D_FLAG) DI-=2;
   4.989 +                        else              DI+=2;
   4.990 +                        c--;
   4.991 +                        cycles -= 10;
   4.992 +                        clockhardware();
   4.993 +                        FETCHADD(10 - memcycs);
   4.994 +                }
   4.995 +                if (IRQTEST && c>0) pc=ipc;
   4.996 +//                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
   4.997 +//                else firstrepcycle=1;
   4.998 +                break;
   4.999 +                case 0xAC: /*REP LODSB*/
  4.1000 +                if (c>0)
  4.1001 +                {
  4.1002 +                        temp2=readmemb(ds+SI);
  4.1003 +                        if (flags&D_FLAG) SI--;
  4.1004 +                        else              SI++;
  4.1005 +                        c--;
  4.1006 +                        cycles-=4;
  4.1007 +                }
  4.1008 +                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
  4.1009 +                else firstrepcycle=1;
  4.1010 +                break;
  4.1011 +                case 0xAD: /*REP LODSW*/
  4.1012 +                if (c>0)
  4.1013 +                {
  4.1014 +                        tempw2=readmemw(ds,SI);
  4.1015 +                        if (flags&D_FLAG) SI-=2;
  4.1016 +                        else              SI+=2;
  4.1017 +                        c--;
  4.1018 +                        cycles-=4;
  4.1019 +                }
  4.1020 +                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
  4.1021 +                else firstrepcycle=1;
  4.1022 +                break;
  4.1023 +                case 0xAE: /*REP SCASB*/
  4.1024 +                if (fv) flags|=Z_FLAG;
  4.1025 +                else    flags&=~Z_FLAG;
  4.1026 +                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))
  4.1027 +                {
  4.1028 +                        temp2=readmemb(es+DI);
  4.1029 +//                        if (output) printf("SCASB %02X %c %02X %05X  ",temp2,temp2,AL,es+DI);
  4.1030 +                        setsub8(AL,temp2);
  4.1031 +//                        if (output && flags&Z_FLAG) printf("Match %02X %02X\n",AL,temp2);
  4.1032 +                        if (flags&D_FLAG) DI--;
  4.1033 +                        else              DI++;
  4.1034 +                        c--;
  4.1035 +                        cycles -= 15;
  4.1036 +                }
  4.1037 +//if (output)                printf("%i %i %i %i\n",c,(c>0),(fv==((flags&Z_FLAG)?1:0)),((c>0) && (fv==((flags&Z_FLAG)?1:0))));
  4.1038 +                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
  4.1039 +                else firstrepcycle=1;
  4.1040 +//                cycles-=120;
  4.1041 +                break;
  4.1042 +                case 0xAF: /*REP SCASW*/
  4.1043 +                if (fv) flags|=Z_FLAG;
  4.1044 +                else    flags&=~Z_FLAG;
  4.1045 +                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))
  4.1046 +                {
  4.1047 +                        tempw=readmemw(es,DI);
  4.1048 +                        setsub16(AX,tempw);
  4.1049 +                        if (flags&D_FLAG) DI-=2;
  4.1050 +                        else              DI+=2;
  4.1051 +                        c--;
  4.1052 +                        cycles -= 15;
  4.1053 +                }
  4.1054 +                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
  4.1055 +                else firstrepcycle=1;
  4.1056 +                break;
  4.1057 +                default:
  4.1058 +                        pc=ipc;
  4.1059 +                        cycles-=20;
  4.1060 +                        FETCHCLEAR();
  4.1061 +//                printf("Bad REP %02X\n",temp);
  4.1062 +//                dumpregs();
  4.1063 +//                exit(-1);
  4.1064 +        }
  4.1065 +        CX=c;
  4.1066 +        if (changeds) ds=oldds;
  4.1067 +//        if (pc==ipc) FETCHCLEAR();
  4.1068 +}
  4.1069 +
  4.1070 +
  4.1071 +int inhlt=0;
  4.1072 +uint16_t lastpc,lastcs;
  4.1073 +int firstrepcycle;
  4.1074 +int skipnextprint=0;
  4.1075 +
  4.1076 +
  4.1077 +int instime=0;
  4.1078 +//#if 0
  4.1079 +void execx86(int cycs)
  4.1080 +{
  4.1081 +        uint8_t temp,temp2;
  4.1082 +        uint16_t addr,tempw,tempw2,tempw3,tempw4;
  4.1083 +        int8_t offset;
  4.1084 +        int tempws;
  4.1085 +        uint32_t templ;
  4.1086 +        int c;
  4.1087 +        int tempi;
  4.1088 +        int trap;
  4.1089 +
  4.1090 +//        printf("Run x86! %i %i\n",cycles,cycs);
  4.1091 +        cycles+=cycs;
  4.1092 +//        i86_Execute(cycs);
  4.1093 +//        return;
  4.1094 +        while (cycles>0)
  4.1095 +        {
  4.1096 +//                old83=old82;
  4.1097 +//                old82=old8;
  4.1098 +//                old8=oldpc|(oldcs<<16);
  4.1099 +//                if (pc==0x96B && cs==0x9E040) { printf("Hit it\n"); output=1; timetolive=150; }
  4.1100 +//                if (pc<0x8000) printf("%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i\n",pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags,disctime);
  4.1101 +                cycdiff=cycles;
  4.1102 +                current_diff = 0;
  4.1103 +                cycles-=nextcyc;
  4.1104 +//                if (instime) pclog("Cycles %i %i\n",cycles,cycdiff);
  4.1105 +                nextcyc=0;
  4.1106 +//        if (output) printf("CLOCK %i %i\n",cycdiff,cycles);
  4.1107 +                fetchclocks=0;
  4.1108 +                oldcs=CS;
  4.1109 +                oldpc=pc;
  4.1110 +                opcodestart:
  4.1111 +                opcode=FETCH();
  4.1112 +                tempc=flags&C_FLAG;
  4.1113 +                trap=flags&T_FLAG;
  4.1114 +                pc--;
  4.1115 +//                output=1;
  4.1116 +//                if (output) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X\n",cs>>4,pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags&~0x200,rmdat);
  4.1117 +//#if 0
  4.1118 +                if (output)
  4.1119 +                {
  4.1120 +//                        if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle)
  4.1121 +//                        {
  4.1122 +                                if (!skipnextprint) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X  %02X %02X %02X %02X\n",cs,pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ram[0x413], ram[0x414], ram[0x415], ram[0x416]);
  4.1123 +                                skipnextprint=0;
  4.1124 +//                                ins++;
  4.1125 +//                        }
  4.1126 +                }
  4.1127 +//#endif
  4.1128 +                pc++;
  4.1129 +                inhlt=0;
  4.1130 +//                if (ins==500000) { dumpregs(); exit(0); }*/
  4.1131 +                switch (opcode)
  4.1132 +                {
  4.1133 +                        case 0x00: /*ADD 8,reg*/
  4.1134 +                        fetchea();
  4.1135 +/*                        if (!rmdat) pc--;
  4.1136 +                        if (!rmdat)
  4.1137 +                        {
  4.1138 +                                fatal("Crashed\n");
  4.1139 +//                                clear_keybuf();
  4.1140 +//                                readkey();
  4.1141 +                        }*/
  4.1142 +                        temp=geteab();
  4.1143 +                        setadd8(temp,getr8(reg));
  4.1144 +                        temp+=getr8(reg);
  4.1145 +                        seteab(temp);
  4.1146 +                        cycles-=((mod==3)?3:24);
  4.1147 +                        break;
  4.1148 +                        case 0x01: /*ADD 16,reg*/
  4.1149 +                        fetchea();
  4.1150 +                        tempw=geteaw();
  4.1151 +                        setadd16(tempw,regs[reg].w);
  4.1152 +                        tempw+=regs[reg].w;
  4.1153 +                        seteaw(tempw);
  4.1154 +                        cycles-=((mod==3)?3:24);
  4.1155 +                        break;
  4.1156 +                        case 0x02: /*ADD reg,8*/
  4.1157 +                        fetchea();
  4.1158 +                        temp=geteab();
  4.1159 +                        setadd8(getr8(reg),temp);
  4.1160 +                        setr8(reg,getr8(reg)+temp);
  4.1161 +                        cycles-=((mod==3)?3:13);
  4.1162 +                        break;
  4.1163 +                        case 0x03: /*ADD reg,16*/
  4.1164 +                        fetchea();
  4.1165 +                        tempw=geteaw();
  4.1166 +                        setadd16(regs[reg].w,tempw);
  4.1167 +                        regs[reg].w+=tempw;
  4.1168 +                        cycles-=((mod==3)?3:13);
  4.1169 +                        break;
  4.1170 +                        case 0x04: /*ADD AL,#8*/
  4.1171 +                        temp=FETCH();
  4.1172 +                        setadd8(AL,temp);
  4.1173 +                        AL+=temp;
  4.1174 +                        cycles-=4;
  4.1175 +                        break;
  4.1176 +                        case 0x05: /*ADD AX,#16*/
  4.1177 +                        tempw=getword();
  4.1178 +                        setadd16(AX,tempw);
  4.1179 +                        AX+=tempw;
  4.1180 +                        cycles-=4;
  4.1181 +                        break;
  4.1182 +
  4.1183 +                        case 0x06: /*PUSH ES*/
  4.1184 +                        if (ssegs) ss=oldss;
  4.1185 +                        writememw(ss,((SP-2)&0xFFFF),ES);
  4.1186 +                        SP-=2;
  4.1187 +                        cycles-=14;
  4.1188 +                        break;
  4.1189 +                        case 0x07: /*POP ES*/
  4.1190 +                        if (ssegs) ss=oldss;
  4.1191 +                        tempw=readmemw(ss,SP);
  4.1192 +                        loadseg(tempw,&_es);
  4.1193 +                        SP+=2;
  4.1194 +                        cycles-=12;
  4.1195 +                        break;
  4.1196 +
  4.1197 +                        case 0x08: /*OR 8,reg*/
  4.1198 +                        fetchea();
  4.1199 +                        temp=geteab();
  4.1200 +                        temp|=getr8(reg);
  4.1201 +                        setznp8(temp);
  4.1202 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1203 +                        seteab(temp);
  4.1204 +                        cycles-=((mod==3)?3:24);
  4.1205 +                        break;
  4.1206 +                        case 0x09: /*OR 16,reg*/
  4.1207 +                        fetchea();
  4.1208 +                        tempw=geteaw();
  4.1209 +                        tempw|=regs[reg].w;
  4.1210 +                        setznp16(tempw);
  4.1211 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1212 +                        seteaw(tempw);
  4.1213 +                        cycles-=((mod==3)?3:24);
  4.1214 +                        break;
  4.1215 +                        case 0x0A: /*OR reg,8*/
  4.1216 +                        fetchea();
  4.1217 +                        temp=geteab();
  4.1218 +                        temp|=getr8(reg);
  4.1219 +                        setznp8(temp);
  4.1220 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1221 +                        setr8(reg,temp);
  4.1222 +                        cycles-=((mod==3)?3:13);
  4.1223 +                        break;
  4.1224 +                        case 0x0B: /*OR reg,16*/
  4.1225 +                        fetchea();
  4.1226 +                        tempw=geteaw();
  4.1227 +                        tempw|=regs[reg].w;
  4.1228 +                        setznp16(tempw);
  4.1229 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1230 +                        regs[reg].w=tempw;
  4.1231 +                        cycles-=((mod==3)?3:13);
  4.1232 +                        break;
  4.1233 +                        case 0x0C: /*OR AL,#8*/
  4.1234 +                        AL|=FETCH();
  4.1235 +                        setznp8(AL);
  4.1236 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1237 +                        cycles-=4;
  4.1238 +                        break;
  4.1239 +                        case 0x0D: /*OR AX,#16*/
  4.1240 +                        AX|=getword();
  4.1241 +                        setznp16(AX);
  4.1242 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1243 +                        cycles-=4;
  4.1244 +                        break;
  4.1245 +
  4.1246 +                        case 0x0E: /*PUSH CS*/
  4.1247 +                        if (ssegs) ss=oldss;
  4.1248 +                        writememw(ss,((SP-2)&0xFFFF),CS);
  4.1249 +                        SP-=2;
  4.1250 +                        cycles-=14;
  4.1251 +                        break;
  4.1252 +                        case 0x0F: /*POP CS - 8088/8086 only*/
  4.1253 +                        if (ssegs) ss=oldss;
  4.1254 +                        tempw=readmemw(ss,SP);
  4.1255 +                        loadseg(tempw,&_cs);
  4.1256 +                        SP+=2;
  4.1257 +                        cycles-=12;
  4.1258 +                        break;
  4.1259 +
  4.1260 +                        case 0x10: /*ADC 8,reg*/
  4.1261 +                        fetchea();
  4.1262 +                        temp=geteab();
  4.1263 +                        temp2=getr8(reg);
  4.1264 +                        setadc8(temp,temp2);
  4.1265 +                        temp+=temp2+tempc;
  4.1266 +                        seteab(temp);
  4.1267 +                        cycles-=((mod==3)?3:24);
  4.1268 +                        break;
  4.1269 +                        case 0x11: /*ADC 16,reg*/
  4.1270 +                        fetchea();
  4.1271 +                        tempw=geteaw();
  4.1272 +                        tempw2=regs[reg].w;
  4.1273 +                        setadc16(tempw,tempw2);
  4.1274 +                        tempw+=tempw2+tempc;
  4.1275 +                        seteaw(tempw);
  4.1276 +                        cycles-=((mod==3)?3:24);
  4.1277 +                        break;
  4.1278 +                        case 0x12: /*ADC reg,8*/
  4.1279 +                        fetchea();
  4.1280 +                        temp=geteab();
  4.1281 +                        setadc8(getr8(reg),temp);
  4.1282 +                        setr8(reg,getr8(reg)+temp+tempc);
  4.1283 +                        cycles-=((mod==3)?3:13);
  4.1284 +                        break;
  4.1285 +                        case 0x13: /*ADC reg,16*/
  4.1286 +                        fetchea();
  4.1287 +                        tempw=geteaw();
  4.1288 +                        setadc16(regs[reg].w,tempw);
  4.1289 +                        regs[reg].w+=tempw+tempc;
  4.1290 +                        cycles-=((mod==3)?3:13);
  4.1291 +                        break;
  4.1292 +                        case 0x14: /*ADC AL,#8*/
  4.1293 +                        tempw=FETCH();
  4.1294 +                        setadc8(AL,tempw);
  4.1295 +                        AL+=tempw+tempc;
  4.1296 +                        cycles-=4;
  4.1297 +                        break;
  4.1298 +                        case 0x15: /*ADC AX,#16*/
  4.1299 +                        tempw=getword();
  4.1300 +                        setadc16(AX,tempw);
  4.1301 +                        AX+=tempw+tempc;
  4.1302 +                        cycles-=4;
  4.1303 +                        break;
  4.1304 +
  4.1305 +                        case 0x16: /*PUSH SS*/
  4.1306 +                        if (ssegs) ss=oldss;
  4.1307 +                        writememw(ss,((SP-2)&0xFFFF),SS);
  4.1308 +                        SP-=2;
  4.1309 +                        cycles-=14;
  4.1310 +                        break;
  4.1311 +                        case 0x17: /*POP SS*/
  4.1312 +                        if (ssegs) ss=oldss;
  4.1313 +                        tempw=readmemw(ss,SP);
  4.1314 +                        loadseg(tempw,&_ss);
  4.1315 +                        SP+=2;
  4.1316 +                        noint=1;
  4.1317 +                        cycles-=12;
  4.1318 +//                        output=1;
  4.1319 +                        break;
  4.1320 +
  4.1321 +                        case 0x18: /*SBB 8,reg*/
  4.1322 +                        fetchea();
  4.1323 +                        temp=geteab();
  4.1324 +                        temp2=getr8(reg);
  4.1325 +                        setsbc8(temp,temp2);
  4.1326 +                        temp-=(temp2+tempc);
  4.1327 +                        seteab(temp);
  4.1328 +                        cycles-=((mod==3)?3:24);
  4.1329 +                        break;
  4.1330 +                        case 0x19: /*SBB 16,reg*/
  4.1331 +                        fetchea();
  4.1332 +                        tempw=geteaw();
  4.1333 +                        tempw2=regs[reg].w;
  4.1334 +//                        printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc);
  4.1335 +                        setsbc16(tempw,tempw2);
  4.1336 +                        tempw-=(tempw2+tempc);
  4.1337 +                        seteaw(tempw);
  4.1338 +                        cycles-=((mod==3)?3:24);
  4.1339 +                        break;
  4.1340 +                        case 0x1A: /*SBB reg,8*/
  4.1341 +                        fetchea();
  4.1342 +                        temp=geteab();
  4.1343 +                        setsbc8(getr8(reg),temp);
  4.1344 +                        setr8(reg,getr8(reg)-(temp+tempc));
  4.1345 +                        cycles-=((mod==3)?3:13);
  4.1346 +                        break;
  4.1347 +                        case 0x1B: /*SBB reg,16*/
  4.1348 +                        fetchea();
  4.1349 +                        tempw=geteaw();
  4.1350 +                        tempw2=regs[reg].w;
  4.1351 +//                        printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc);
  4.1352 +                        setsbc16(tempw2,tempw);
  4.1353 +                        tempw2-=(tempw+tempc);
  4.1354 +                        regs[reg].w=tempw2;
  4.1355 +                        cycles-=((mod==3)?3:13);
  4.1356 +                        break;
  4.1357 +                        case 0x1C: /*SBB AL,#8*/
  4.1358 +                        temp=FETCH();
  4.1359 +                        setsbc8(AL,temp);
  4.1360 +                        AL-=(temp+tempc);
  4.1361 +                        cycles-=4;
  4.1362 +                        break;
  4.1363 +                        case 0x1D: /*SBB AX,#16*/
  4.1364 +                        tempw=getword();
  4.1365 +                        setsbc16(AX,tempw);
  4.1366 +                        AX-=(tempw+tempc);
  4.1367 +                        cycles-=4;
  4.1368 +                        break;
  4.1369 +
  4.1370 +                        case 0x1E: /*PUSH DS*/
  4.1371 +                        if (ssegs) ss=oldss;
  4.1372 +                        writememw(ss,((SP-2)&0xFFFF),DS);
  4.1373 +                        SP-=2;
  4.1374 +                        cycles-=14;
  4.1375 +                        break;
  4.1376 +                        case 0x1F: /*POP DS*/
  4.1377 +                        if (ssegs) ss=oldss;
  4.1378 +                        tempw=readmemw(ss,SP);
  4.1379 +                        loadseg(tempw,&_ds);
  4.1380 +                        if (ssegs) oldds=ds;
  4.1381 +                        SP+=2;
  4.1382 +                        cycles-=12;
  4.1383 +                        break;
  4.1384 +
  4.1385 +                        case 0x20: /*AND 8,reg*/
  4.1386 +                        fetchea();
  4.1387 +                        temp=geteab();
  4.1388 +                        temp&=getr8(reg);
  4.1389 +                        setznp8(temp);
  4.1390 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1391 +                        seteab(temp);
  4.1392 +                        cycles-=((mod==3)?3:24);
  4.1393 +                        break;
  4.1394 +                        case 0x21: /*AND 16,reg*/
  4.1395 +                        fetchea();
  4.1396 +                        tempw=geteaw();
  4.1397 +                        tempw&=regs[reg].w;
  4.1398 +                        setznp16(tempw);
  4.1399 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1400 +                        seteaw(tempw);
  4.1401 +                        cycles-=((mod==3)?3:24);
  4.1402 +                        break;
  4.1403 +                        case 0x22: /*AND reg,8*/
  4.1404 +                        fetchea();
  4.1405 +                        temp=geteab();
  4.1406 +                        temp&=getr8(reg);
  4.1407 +                        setznp8(temp);
  4.1408 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1409 +                        setr8(reg,temp);
  4.1410 +                        cycles-=((mod==3)?3:13);
  4.1411 +                        break;
  4.1412 +                        case 0x23: /*AND reg,16*/
  4.1413 +                        fetchea();
  4.1414 +                        tempw=geteaw();
  4.1415 +                        tempw&=regs[reg].w;
  4.1416 +                        setznp16(tempw);
  4.1417 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1418 +                        regs[reg].w=tempw;
  4.1419 +                        cycles-=((mod==3)?3:13);
  4.1420 +                        break;
  4.1421 +                        case 0x24: /*AND AL,#8*/
  4.1422 +                        AL&=FETCH();
  4.1423 +                        setznp8(AL);
  4.1424 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1425 +                        cycles-=4;
  4.1426 +                        break;
  4.1427 +                        case 0x25: /*AND AX,#16*/
  4.1428 +                        AX&=getword();
  4.1429 +                        setznp16(AX);
  4.1430 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1431 +                        cycles-=4;
  4.1432 +                        break;
  4.1433 +
  4.1434 +                        case 0x26: /*ES:*/
  4.1435 +                        oldss=ss;
  4.1436 +                        oldds=ds;
  4.1437 +                        ds=ss=es;
  4.1438 +                        ssegs=2;
  4.1439 +                        cycles-=4;
  4.1440 +                        goto opcodestart;
  4.1441 +//                        break;
  4.1442 +
  4.1443 +                        case 0x27: /*DAA*/
  4.1444 +                        if ((flags&A_FLAG) || ((AL&0xF)>9))
  4.1445 +                        {
  4.1446 +                                tempi=((uint16_t)AL)+6;
  4.1447 +                                AL+=6;
  4.1448 +                                flags|=A_FLAG;
  4.1449 +                                if (tempi&0x100) flags|=C_FLAG;
  4.1450 +                        }
  4.1451 +//                        else
  4.1452 +//                           flags&=~A_FLAG;
  4.1453 +                        if ((flags&C_FLAG) || (AL>0x9F))
  4.1454 +                        {
  4.1455 +                                AL+=0x60;
  4.1456 +                                flags|=C_FLAG;
  4.1457 +                        }
  4.1458 +//                        else
  4.1459 +//                           flags&=~C_FLAG;
  4.1460 +                        setznp8(AL);
  4.1461 +                        cycles-=4;
  4.1462 +                        break;
  4.1463 +
  4.1464 +                        case 0x28: /*SUB 8,reg*/
  4.1465 +                        fetchea();
  4.1466 +                        temp=geteab();
  4.1467 +                        setsub8(temp,getr8(reg));
  4.1468 +                        temp-=getr8(reg);
  4.1469 +                        seteab(temp);
  4.1470 +                        cycles-=((mod==3)?3:24);
  4.1471 +                        break;
  4.1472 +                        case 0x29: /*SUB 16,reg*/
  4.1473 +                        fetchea();
  4.1474 +                        tempw=geteaw();
  4.1475 +//                        printf("%04X:%04X  %04X-%04X\n",cs>>4,pc,tempw,regs[reg].w);
  4.1476 +                        setsub16(tempw,regs[reg].w);
  4.1477 +                        tempw-=regs[reg].w;
  4.1478 +                        seteaw(tempw);
  4.1479 +                        cycles-=((mod==3)?3:24);
  4.1480 +                        break;
  4.1481 +                        case 0x2A: /*SUB reg,8*/
  4.1482 +                        fetchea();
  4.1483 +                        temp=geteab();
  4.1484 +                        setsub8(getr8(reg),temp);
  4.1485 +                        setr8(reg,getr8(reg)-temp);
  4.1486 +                        cycles-=((mod==3)?3:13);
  4.1487 +                        break;
  4.1488 +                        case 0x2B: /*SUB reg,16*/
  4.1489 +                        fetchea();
  4.1490 +                        tempw=geteaw();
  4.1491 +//                        printf("%04X:%04X  %04X-%04X\n",cs>>4,pc,regs[reg].w,tempw);
  4.1492 +                        setsub16(regs[reg].w,tempw);
  4.1493 +                        regs[reg].w-=tempw;
  4.1494 +                        cycles-=((mod==3)?3:13);
  4.1495 +                        break;
  4.1496 +                        case 0x2C: /*SUB AL,#8*/
  4.1497 +                        temp=FETCH();
  4.1498 +                        setsub8(AL,temp);
  4.1499 +                        AL-=temp;
  4.1500 +                        cycles-=4;
  4.1501 +                        break;
  4.1502 +                        case 0x2D: /*SUB AX,#16*/
  4.1503 +//                        printf("INS %i\n",ins);
  4.1504 +//                        output=1;
  4.1505 +                        tempw=getword();
  4.1506 +                        setsub16(AX,tempw);
  4.1507 +                        AX-=tempw;
  4.1508 +                        cycles-=4;
  4.1509 +                        break;
  4.1510 +                        case 0x2E: /*CS:*/
  4.1511 +                        oldss=ss;
  4.1512 +                        oldds=ds;
  4.1513 +                        ds=ss=cs;
  4.1514 +                        ssegs=2;
  4.1515 +                        cycles-=4;
  4.1516 +                        goto opcodestart;
  4.1517 +                        case 0x2F: /*DAS*/
  4.1518 +                        if ((flags&A_FLAG)||((AL&0xF)>9))
  4.1519 +                        {
  4.1520 +                                tempi=((uint16_t)AL)-6;
  4.1521 +                                AL-=6;
  4.1522 +                                flags|=A_FLAG;
  4.1523 +                                if (tempi&0x100) flags|=C_FLAG;
  4.1524 +                        }
  4.1525 +//                        else
  4.1526 +//                           flags&=~A_FLAG;
  4.1527 +                        if ((flags&C_FLAG)||(AL>0x9F))
  4.1528 +                        {
  4.1529 +                                AL-=0x60;
  4.1530 +                                flags|=C_FLAG;
  4.1531 +                        }
  4.1532 +//                        else
  4.1533 +//                           flags&=~C_FLAG;
  4.1534 +                        setznp8(AL);
  4.1535 +                        cycles-=4;
  4.1536 +                        break;
  4.1537 +                        case 0x30: /*XOR 8,reg*/
  4.1538 +                        fetchea();
  4.1539 +                        temp=geteab();
  4.1540 +                        temp^=getr8(reg);
  4.1541 +                        setznp8(temp);
  4.1542 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1543 +                        seteab(temp);
  4.1544 +                        cycles-=((mod==3)?3:24);
  4.1545 +                        break;
  4.1546 +                        case 0x31: /*XOR 16,reg*/
  4.1547 +                        fetchea();
  4.1548 +                        tempw=geteaw();
  4.1549 +                        tempw^=regs[reg].w;
  4.1550 +                        setznp16(tempw);
  4.1551 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1552 +                        seteaw(tempw);
  4.1553 +                        cycles-=((mod==3)?3:24);
  4.1554 +                        break;
  4.1555 +                        case 0x32: /*XOR reg,8*/
  4.1556 +                        fetchea();
  4.1557 +                        temp=geteab();
  4.1558 +                        temp^=getr8(reg);
  4.1559 +                        setznp8(temp);
  4.1560 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1561 +                        setr8(reg,temp);
  4.1562 +                        cycles-=((mod==3)?3:13);
  4.1563 +                        break;
  4.1564 +                        case 0x33: /*XOR reg,16*/
  4.1565 +                        fetchea();
  4.1566 +                        tempw=geteaw();
  4.1567 +                        tempw^=regs[reg].w;
  4.1568 +                        setznp16(tempw);
  4.1569 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1570 +                        regs[reg].w=tempw;
  4.1571 +                        cycles-=((mod==3)?3:13);
  4.1572 +                        break;
  4.1573 +                        case 0x34: /*XOR AL,#8*/
  4.1574 +                        AL^=FETCH();
  4.1575 +                        setznp8(AL);
  4.1576 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1577 +                        cycles-=4;
  4.1578 +                        break;
  4.1579 +                        case 0x35: /*XOR AX,#16*/
  4.1580 +                        AX^=getword();
  4.1581 +                        setznp16(AX);
  4.1582 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1583 +                        cycles-=4;
  4.1584 +                        break;
  4.1585 +
  4.1586 +                        case 0x36: /*SS:*/
  4.1587 +                        oldss=ss;
  4.1588 +                        oldds=ds;
  4.1589 +                        ds=ss=ss;
  4.1590 +                        ssegs=2;
  4.1591 +                        cycles-=4;
  4.1592 +                        goto opcodestart;
  4.1593 +//                        break;
  4.1594 +
  4.1595 +                        case 0x37: /*AAA*/
  4.1596 +                        if ((flags&A_FLAG)||((AL&0xF)>9))
  4.1597 +                        {
  4.1598 +                                AL+=6;
  4.1599 +                                AH++;
  4.1600 +                                flags|=(A_FLAG|C_FLAG);
  4.1601 +                        }
  4.1602 +                        else
  4.1603 +                           flags&=~(A_FLAG|C_FLAG);
  4.1604 +                        AL&=0xF;
  4.1605 +                        cycles-=8;
  4.1606 +                        break;
  4.1607 +
  4.1608 +                        case 0x38: /*CMP 8,reg*/
  4.1609 +                        fetchea();
  4.1610 +                        temp=geteab();
  4.1611 +//                        if (output) printf("CMP %02X-%02X\n",temp,getr8(reg));
  4.1612 +                        setsub8(temp,getr8(reg));
  4.1613 +                        cycles-=((mod==3)?3:13);
  4.1614 +                        break;
  4.1615 +                        case 0x39: /*CMP 16,reg*/
  4.1616 +                        fetchea();
  4.1617 +                        tempw=geteaw();
  4.1618 +//                        if (output) printf("CMP %04X-%04X\n",tempw,regs[reg].w);
  4.1619 +                        setsub16(tempw,regs[reg].w);
  4.1620 +                        cycles-=((mod==3)?3:13);
  4.1621 +                        break;
  4.1622 +                        case 0x3A: /*CMP reg,8*/
  4.1623 +                        fetchea();
  4.1624 +                        temp=geteab();
  4.1625 +//                        if (output) printf("CMP %02X-%02X\n",getr8(reg),temp);
  4.1626 +                        setsub8(getr8(reg),temp);
  4.1627 +                        cycles-=((mod==3)?3:13);
  4.1628 +                        break;
  4.1629 +                        case 0x3B: /*CMP reg,16*/
  4.1630 +                        fetchea();
  4.1631 +                        tempw=geteaw();
  4.1632 +//                        printf("CMP %04X-%04X\n",regs[reg].w,tempw);
  4.1633 +                        setsub16(regs[reg].w,tempw);
  4.1634 +                        cycles-=((mod==3)?3:13);
  4.1635 +                        break;
  4.1636 +                        case 0x3C: /*CMP AL,#8*/
  4.1637 +                        temp=FETCH();
  4.1638 +                        setsub8(AL,temp);
  4.1639 +                        cycles-=4;
  4.1640 +                        break;
  4.1641 +                        case 0x3D: /*CMP AX,#16*/
  4.1642 +                        tempw=getword();
  4.1643 +                        setsub16(AX,tempw);
  4.1644 +                        cycles-=4;
  4.1645 +                        break;
  4.1646 +
  4.1647 +                        case 0x3E: /*DS:*/
  4.1648 +                        oldss=ss;
  4.1649 +                        oldds=ds;
  4.1650 +                        ds=ss=ds;
  4.1651 +                        ssegs=2;
  4.1652 +                        cycles-=4;
  4.1653 +                        goto opcodestart;
  4.1654 +//                        break;
  4.1655 +
  4.1656 +                        case 0x3F: /*AAS*/
  4.1657 +                        if ((flags&A_FLAG)||((AL&0xF)>9))
  4.1658 +                        {
  4.1659 +                                AL-=6;
  4.1660 +                                AH--;
  4.1661 +                                flags|=(A_FLAG|C_FLAG);
  4.1662 +                        }
  4.1663 +                        else
  4.1664 +                           flags&=~(A_FLAG|C_FLAG);
  4.1665 +                        AL&=0xF;
  4.1666 +                        cycles-=8;
  4.1667 +                        break;
  4.1668 +
  4.1669 +                        case 0x40: case 0x41: case 0x42: case 0x43: /*INC r16*/
  4.1670 +                        case 0x44: case 0x45: case 0x46: case 0x47:
  4.1671 +                        setadd16nc(regs[opcode&7].w,1);
  4.1672 +                        regs[opcode&7].w++;
  4.1673 +                        cycles-=3;
  4.1674 +                        break;
  4.1675 +                        case 0x48: case 0x49: case 0x4A: case 0x4B: /*DEC r16*/
  4.1676 +                        case 0x4C: case 0x4D: case 0x4E: case 0x4F:
  4.1677 +                        setsub16nc(regs[opcode&7].w,1);
  4.1678 +                        regs[opcode&7].w--;
  4.1679 +                        cycles-=3;
  4.1680 +                        break;
  4.1681 +
  4.1682 +                        case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/
  4.1683 +                        case 0x54: case 0x55: case 0x56: case 0x57:
  4.1684 +                        if (ssegs) ss=oldss;
  4.1685 +                        SP-=2;
  4.1686 +                        writememw(ss,SP,regs[opcode&7].w);
  4.1687 +                        cycles-=15;
  4.1688 +                        break;
  4.1689 +                        case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/
  4.1690 +                        case 0x5C: case 0x5D: case 0x5E: case 0x5F:
  4.1691 +                        if (ssegs) ss=oldss;
  4.1692 +                        SP+=2;
  4.1693 +                        regs[opcode&7].w=readmemw(ss,(SP-2)&0xFFFF);
  4.1694 +                        cycles-=12;
  4.1695 +                        break;
  4.1696 +
  4.1697 +
  4.1698 +                        case 0x70: /*JO*/
  4.1699 +                        offset=(int8_t)FETCH();
  4.1700 +                        if (flags&V_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1701 +                        cycles-=4;
  4.1702 +                        break;
  4.1703 +                        case 0x71: /*JNO*/
  4.1704 +                        offset=(int8_t)FETCH();
  4.1705 +                        if (!(flags&V_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1706 +                        cycles-=4;
  4.1707 +                        break;
  4.1708 +                        case 0x72: /*JB*/
  4.1709 +                        offset=(int8_t)FETCH();
  4.1710 +                        if (flags&C_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1711 +                        cycles-=4;
  4.1712 +                        break;
  4.1713 +                        case 0x73: /*JNB*/
  4.1714 +                        offset=(int8_t)FETCH();
  4.1715 +                        if (!(flags&C_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1716 +                        cycles-=4;
  4.1717 +                        break;
  4.1718 +                        case 0x74: /*JE*/
  4.1719 +                        offset=(int8_t)FETCH();
  4.1720 +                        if (flags&Z_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1721 +                        cycles-=4;
  4.1722 +                        break;
  4.1723 +                        case 0x75: /*JNE*/
  4.1724 +                        offset=(int8_t)FETCH();
  4.1725 +                        cycles-=4;
  4.1726 +                        if (!(flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1727 +                        break;
  4.1728 +                        case 0x76: /*JBE*/
  4.1729 +                        offset=(int8_t)FETCH();
  4.1730 +                        if (flags&(C_FLAG|Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1731 +                        cycles-=4;
  4.1732 +                        break;
  4.1733 +                        case 0x77: /*JNBE*/
  4.1734 +                        offset=(int8_t)FETCH();
  4.1735 +                        if (!(flags&(C_FLAG|Z_FLAG))) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1736 +                        cycles-=4;
  4.1737 +                        break;
  4.1738 +                        case 0x78: /*JS*/
  4.1739 +                        offset=(int8_t)FETCH();
  4.1740 +                        if (flags&N_FLAG)  { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1741 +                        cycles-=4;
  4.1742 +                        break;
  4.1743 +                        case 0x79: /*JNS*/
  4.1744 +                        offset=(int8_t)FETCH();
  4.1745 +                        if (!(flags&N_FLAG))  { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1746 +                        cycles-=4;
  4.1747 +                        break;
  4.1748 +                        case 0x7A: /*JP*/
  4.1749 +                        offset=(int8_t)FETCH();
  4.1750 +                        if (flags&P_FLAG)  { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1751 +                        cycles-=4;
  4.1752 +                        break;
  4.1753 +                        case 0x7B: /*JNP*/
  4.1754 +                        offset=(int8_t)FETCH();
  4.1755 +                        if (!(flags&P_FLAG))  { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1756 +                        cycles-=4;
  4.1757 +                        break;
  4.1758 +                        case 0x7C: /*JL*/
  4.1759 +                        offset=(int8_t)FETCH();
  4.1760 +                        temp=(flags&N_FLAG)?1:0;
  4.1761 +                        temp2=(flags&V_FLAG)?1:0;
  4.1762 +                        if (temp!=temp2)  { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1763 +                        cycles-=4;
  4.1764 +                        break;
  4.1765 +                        case 0x7D: /*JNL*/
  4.1766 +                        offset=(int8_t)FETCH();
  4.1767 +                        temp=(flags&N_FLAG)?1:0;
  4.1768 +                        temp2=(flags&V_FLAG)?1:0;
  4.1769 +                        if (temp==temp2)  { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1770 +                        cycles-=4;
  4.1771 +                        break;
  4.1772 +                        case 0x7E: /*JLE*/
  4.1773 +                        offset=(int8_t)FETCH();
  4.1774 +                        temp=(flags&N_FLAG)?1:0;
  4.1775 +                        temp2=(flags&V_FLAG)?1:0;
  4.1776 +                        if ((flags&Z_FLAG) || (temp!=temp2))  { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1777 +                        cycles-=4;
  4.1778 +                        break;
  4.1779 +                        case 0x7F: /*JNLE*/
  4.1780 +                        offset=(int8_t)FETCH();
  4.1781 +                        temp=(flags&N_FLAG)?1:0;
  4.1782 +                        temp2=(flags&V_FLAG)?1:0;
  4.1783 +                        if (!((flags&Z_FLAG) || (temp!=temp2)))  { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.1784 +                        cycles-=4;
  4.1785 +                        break;
  4.1786 +
  4.1787 +                        case 0x80: case 0x82:
  4.1788 +                        fetchea();
  4.1789 +                        temp=geteab();
  4.1790 +                        temp2=FETCH();
  4.1791 +                        switch (rmdat&0x38)
  4.1792 +                        {
  4.1793 +                                case 0x00: /*ADD b,#8*/
  4.1794 +                                setadd8(temp,temp2);
  4.1795 +                                seteab(temp+temp2);
  4.1796 +                                cycles-=((mod==3)?4:23);
  4.1797 +                                break;
  4.1798 +                                case 0x08: /*OR b,#8*/
  4.1799 +                                temp|=temp2;
  4.1800 +                                setznp8(temp);
  4.1801 +                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1802 +                                seteab(temp);
  4.1803 +                                cycles-=((mod==3)?4:23);
  4.1804 +                                break;
  4.1805 +                                case 0x10: /*ADC b,#8*/
  4.1806 +//                                temp2+=(flags&C_FLAG);
  4.1807 +                                setadc8(temp,temp2);
  4.1808 +                                seteab(temp+temp2+tempc);
  4.1809 +                                cycles-=((mod==3)?4:23);
  4.1810 +                                break;
  4.1811 +                                case 0x18: /*SBB b,#8*/
  4.1812 +//                                temp2+=(flags&C_FLAG);
  4.1813 +                                setsbc8(temp,temp2);
  4.1814 +                                seteab(temp-(temp2+tempc));
  4.1815 +                                cycles-=((mod==3)?4:23);
  4.1816 +                                break;
  4.1817 +                                case 0x20: /*AND b,#8*/
  4.1818 +                                temp&=temp2;
  4.1819 +                                setznp8(temp);
  4.1820 +                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1821 +                                seteab(temp);
  4.1822 +                                cycles-=((mod==3)?4:23);
  4.1823 +                                break;
  4.1824 +                                case 0x28: /*SUB b,#8*/
  4.1825 +                                setsub8(temp,temp2);
  4.1826 +                                seteab(temp-temp2);
  4.1827 +                                cycles-=((mod==3)?4:23);
  4.1828 +                                break;
  4.1829 +                                case 0x30: /*XOR b,#8*/
  4.1830 +                                temp^=temp2;
  4.1831 +                                setznp8(temp);
  4.1832 +                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1833 +                                seteab(temp);
  4.1834 +                                cycles-=((mod==3)?4:23);
  4.1835 +                                break;
  4.1836 +                                case 0x38: /*CMP b,#8*/
  4.1837 +                                setsub8(temp,temp2);
  4.1838 +                                cycles-=((mod==3)?4:14);
  4.1839 +                                break;
  4.1840 +
  4.1841 +//                                default:
  4.1842 +//                                printf("Bad 80 opcode %02X\n",rmdat&0x38);
  4.1843 +//                                dumpregs();
  4.1844 +//                                exit(-1);
  4.1845 +                        }
  4.1846 +                        break;
  4.1847 +
  4.1848 +                        case 0x81:
  4.1849 +                        fetchea();
  4.1850 +                        tempw=geteaw();
  4.1851 +                        tempw2=getword();
  4.1852 +                        switch (rmdat&0x38)
  4.1853 +                        {
  4.1854 +                                case 0x00: /*ADD w,#16*/
  4.1855 +                                setadd16(tempw,tempw2);
  4.1856 +                                tempw+=tempw2;
  4.1857 +                                seteaw(tempw);
  4.1858 +                                cycles-=((mod==3)?4:23);
  4.1859 +                                break;
  4.1860 +                                case 0x08: /*OR w,#16*/
  4.1861 +                                tempw|=tempw2;
  4.1862 +                                setznp16(tempw);
  4.1863 +                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1864 +                                seteaw(tempw);
  4.1865 +                                cycles-=((mod==3)?4:23);
  4.1866 +                                break;
  4.1867 +                                case 0x10: /*ADC w,#16*/
  4.1868 +//                                tempw2+=(flags&C_FLAG);
  4.1869 +                                setadc16(tempw,tempw2);
  4.1870 +                                tempw+=tempw2+tempc;
  4.1871 +                                seteaw(tempw);
  4.1872 +                                cycles-=((mod==3)?4:23);
  4.1873 +                                break;
  4.1874 +                                case 0x20: /*AND w,#16*/
  4.1875 +                                tempw&=tempw2;
  4.1876 +                                setznp16(tempw);
  4.1877 +                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1878 +                                seteaw(tempw);
  4.1879 +                                cycles-=((mod==3)?4:23);
  4.1880 +                                break;
  4.1881 +                                case 0x18: /*SBB w,#16*/
  4.1882 +//                                tempw2+=(flags&C_FLAG);
  4.1883 +                                setsbc16(tempw,tempw2);
  4.1884 +                                seteaw(tempw-(tempw2+tempc));
  4.1885 +                                cycles-=((mod==3)?4:23);
  4.1886 +                                break;
  4.1887 +                                case 0x28: /*SUB w,#16*/
  4.1888 +                                setsub16(tempw,tempw2);
  4.1889 +                                tempw-=tempw2;
  4.1890 +                                seteaw(tempw);
  4.1891 +                                cycles-=((mod==3)?4:23);
  4.1892 +                                break;
  4.1893 +                                case 0x30: /*XOR w,#16*/
  4.1894 +                                tempw^=tempw2;
  4.1895 +                                setznp16(tempw);
  4.1896 +                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1897 +                                seteaw(tempw);
  4.1898 +                                cycles-=((mod==3)?4:23);
  4.1899 +                                break;
  4.1900 +                                case 0x38: /*CMP w,#16*/
  4.1901 +//                                printf("CMP %04X %04X\n",tempw,tempw2);
  4.1902 +                                setsub16(tempw,tempw2);
  4.1903 +                                cycles-=((mod==3)?4:14);
  4.1904 +                                break;
  4.1905 +
  4.1906 +//                                default:
  4.1907 +//                                printf("Bad 81 opcode %02X\n",rmdat&0x38);
  4.1908 +//                                dumpregs();
  4.1909 +//                                exit(-1);
  4.1910 +                        }
  4.1911 +                        break;
  4.1912 +
  4.1913 +                        case 0x83:
  4.1914 +                        fetchea();
  4.1915 +                        tempw=geteaw();
  4.1916 +                        tempw2=FETCH();
  4.1917 +                        if (tempw2&0x80) tempw2|=0xFF00;
  4.1918 +                        switch (rmdat&0x38)
  4.1919 +                        {
  4.1920 +                                case 0x00: /*ADD w,#8*/
  4.1921 +                                setadd16(tempw,tempw2);
  4.1922 +                                tempw+=tempw2;
  4.1923 +                                seteaw(tempw);
  4.1924 +                                cycles-=((mod==3)?4:23);
  4.1925 +                                break;
  4.1926 +                                case 0x08: /*OR w,#8*/
  4.1927 +                                tempw|=tempw2;
  4.1928 +                                setznp16(tempw);
  4.1929 +                                seteaw(tempw);
  4.1930 +                                flags&=~(C_FLAG|A_FLAG|V_FLAG);
  4.1931 +                                cycles-=((mod==3)?4:23);
  4.1932 +                                break;
  4.1933 +                                case 0x10: /*ADC w,#8*/
  4.1934 +//                                tempw2+=(flags&C_FLAG);
  4.1935 +                                setadc16(tempw,tempw2);
  4.1936 +                                tempw+=tempw2+tempc;
  4.1937 +                                seteaw(tempw);
  4.1938 +                                cycles-=((mod==3)?4:23);
  4.1939 +                                break;
  4.1940 +                                case 0x18: /*SBB w,#8*/
  4.1941 +//                                tempw2+=(flags&C_FLAG);
  4.1942 +                                setsbc16(tempw,tempw2);
  4.1943 +                                tempw-=(tempw2+tempc);
  4.1944 +                                seteaw(tempw);
  4.1945 +                                cycles-=((mod==3)?4:23);
  4.1946 +                                break;
  4.1947 +                                case 0x20: /*AND w,#8*/
  4.1948 +                                tempw&=tempw2;
  4.1949 +                                setznp16(tempw);
  4.1950 +                                seteaw(tempw);
  4.1951 +                                cycles-=((mod==3)?4:23);
  4.1952 +                                flags&=~(C_FLAG|A_FLAG|V_FLAG);
  4.1953 +                                break;
  4.1954 +                                case 0x28: /*SUB w,#8*/
  4.1955 +                                setsub16(tempw,tempw2);
  4.1956 +                                tempw-=tempw2;
  4.1957 +                                seteaw(tempw);
  4.1958 +                                cycles-=((mod==3)?4:23);
  4.1959 +                                break;
  4.1960 +                                case 0x30: /*XOR w,#8*/
  4.1961 +                                tempw^=tempw2;
  4.1962 +                                setznp16(tempw);
  4.1963 +                                seteaw(tempw);
  4.1964 +                                cycles-=((mod==3)?4:23);
  4.1965 +                                flags&=~(C_FLAG|A_FLAG|V_FLAG);
  4.1966 +                                break;
  4.1967 +                                case 0x38: /*CMP w,#8*/
  4.1968 +                                setsub16(tempw,tempw2);
  4.1969 +                                cycles-=((mod==3)?4:14);
  4.1970 +                                break;
  4.1971 +
  4.1972 +//                                default:
  4.1973 +//                                printf("Bad 83 opcode %02X\n",rmdat&0x38);
  4.1974 +//                                dumpregs();
  4.1975 +//                                exit(-1);
  4.1976 +                        }
  4.1977 +                        break;
  4.1978 +
  4.1979 +                        case 0x84: /*TEST b,reg*/
  4.1980 +                        fetchea();
  4.1981 +                        temp=geteab();
  4.1982 +                        temp2=getr8(reg);
  4.1983 +                        setznp8(temp&temp2);
  4.1984 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1985 +                        cycles-=((mod==3)?3:13);
  4.1986 +                        break;
  4.1987 +                        case 0x85: /*TEST w,reg*/
  4.1988 +                        fetchea();
  4.1989 +                        tempw=geteaw();
  4.1990 +                        tempw2=regs[reg].w;
  4.1991 +                        setznp16(tempw&tempw2);
  4.1992 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.1993 +                        cycles-=((mod==3)?3:13);
  4.1994 +                        break;
  4.1995 +                        case 0x86: /*XCHG b,reg*/
  4.1996 +                        fetchea();
  4.1997 +                        temp=geteab();
  4.1998 +                        seteab(getr8(reg));
  4.1999 +                        setr8(reg,temp);
  4.2000 +                        cycles-=((mod==3)?4:25);
  4.2001 +                        break;
  4.2002 +                        case 0x87: /*XCHG w,reg*/
  4.2003 +                        fetchea();
  4.2004 +                        tempw=geteaw();
  4.2005 +                        seteaw(regs[reg].w);
  4.2006 +                        regs[reg].w=tempw;
  4.2007 +                        cycles-=((mod==3)?4:25);
  4.2008 +                        break;
  4.2009 +
  4.2010 +                        case 0x88: /*MOV b,reg*/
  4.2011 +                        fetchea();
  4.2012 +                        seteab(getr8(reg));
  4.2013 +                        cycles-=((mod==3)?2:13);
  4.2014 +                        break;
  4.2015 +                        case 0x89: /*MOV w,reg*/
  4.2016 +                        fetchea();
  4.2017 +                        seteaw(regs[reg].w);
  4.2018 +                        cycles-=((mod==3)?2:13);
  4.2019 +                        break;
  4.2020 +                        case 0x8A: /*MOV reg,b*/
  4.2021 +                        fetchea();
  4.2022 +                        temp=geteab();
  4.2023 +                        setr8(reg,temp);
  4.2024 +                        cycles-=((mod==3)?2:12);
  4.2025 +                        break;
  4.2026 +                        case 0x8B: /*MOV reg,w*/
  4.2027 +                        fetchea();
  4.2028 +                        tempw=geteaw();
  4.2029 +                        regs[reg].w=tempw;
  4.2030 +                        cycles-=((mod==3)?2:12);
  4.2031 +                        break;
  4.2032 +
  4.2033 +                        case 0x8C: /*MOV w,sreg*/
  4.2034 +                        fetchea();
  4.2035 +                        switch (rmdat&0x38)
  4.2036 +                        {
  4.2037 +                                case 0x00: /*ES*/
  4.2038 +                                seteaw(ES);
  4.2039 +                                break;
  4.2040 +                                case 0x08: /*CS*/
  4.2041 +                                seteaw(CS);
  4.2042 +                                break;
  4.2043 +                                case 0x18: /*DS*/
  4.2044 +                                if (ssegs) ds=oldds;
  4.2045 +                                seteaw(DS);
  4.2046 +                                break;
  4.2047 +                                case 0x10: /*SS*/
  4.2048 +                                if (ssegs) ss=oldss;
  4.2049 +                                seteaw(SS);
  4.2050 +                                break;
  4.2051 +                        }
  4.2052 +                        cycles-=((mod==3)?2:13);
  4.2053 +                        break;
  4.2054 +
  4.2055 +                        case 0x8D: /*LEA*/
  4.2056 +                        fetchea();
  4.2057 +                        regs[reg].w=eaaddr;
  4.2058 +                        cycles-=2;
  4.2059 +                        break;
  4.2060 +
  4.2061 +                        case 0x8E: /*MOV sreg,w*/
  4.2062 +//                        if (output) printf("MOV %04X  ",pc);
  4.2063 +                        fetchea();
  4.2064 +//                        if (output) printf("%04X %02X\n",pc,rmdat);
  4.2065 +                        switch (rmdat&0x38)
  4.2066 +                        {
  4.2067 +                                case 0x00: /*ES*/
  4.2068 +                                tempw=geteaw();
  4.2069 +                                loadseg(tempw,&_es);
  4.2070 +                                break;
  4.2071 +                                case 0x08: /*CS - 8088/8086 only*/
  4.2072 +                                tempw=geteaw();
  4.2073 +                                loadseg(tempw,&_cs);
  4.2074 +                                break;
  4.2075 +                                case 0x18: /*DS*/
  4.2076 +                                tempw=geteaw();
  4.2077 +                                loadseg(tempw,&_ds);
  4.2078 +                                if (ssegs) oldds=ds;
  4.2079 +                                break;
  4.2080 +                                case 0x10: /*SS*/
  4.2081 +                                tempw=geteaw();
  4.2082 +                                loadseg(tempw,&_ss);
  4.2083 +                                if (ssegs) oldss=ss;
  4.2084 +//                                printf("LOAD SS %04X %04X\n",tempw,SS);
  4.2085 +//				printf("SS loaded with %04X %04X:%04X %04X %04X %04X\n",ss>>4,cs>>4,pc,CX,DX,es>>4);
  4.2086 +                                break;
  4.2087 +                        }
  4.2088 +                        cycles-=((mod==3)?2:12);
  4.2089 +                                skipnextprint=1;
  4.2090 +				noint=1;
  4.2091 +                        break;
  4.2092 +
  4.2093 +                        case 0x8F: /*POPW*/
  4.2094 +                        fetchea();
  4.2095 +                        if (ssegs) ss=oldss;
  4.2096 +                        tempw=readmemw(ss,SP);
  4.2097 +                        SP+=2;
  4.2098 +                        seteaw(tempw);
  4.2099 +                        cycles-=25;
  4.2100 +                        break;
  4.2101 +
  4.2102 +                        case 0x90: /*NOP*/
  4.2103 +                        cycles-=3;
  4.2104 +                        break;
  4.2105 +
  4.2106 +                        case 0x91: case 0x92: case 0x93: /*XCHG AX*/
  4.2107 +                        case 0x94: case 0x95: case 0x96: case 0x97:
  4.2108 +                        tempw=AX;
  4.2109 +                        AX=regs[opcode&7].w;
  4.2110 +                        regs[opcode&7].w=tempw;
  4.2111 +                        cycles-=3;
  4.2112 +                        break;
  4.2113 +
  4.2114 +                        case 0x98: /*CBW*/
  4.2115 +                        AH=(AL&0x80)?0xFF:0;
  4.2116 +                        cycles-=2;
  4.2117 +                        break;
  4.2118 +                        case 0x99: /*CWD*/
  4.2119 +                        DX=(AX&0x8000)?0xFFFF:0;
  4.2120 +                        cycles-=5;
  4.2121 +                        break;
  4.2122 +                        case 0x9A: /*CALL FAR*/
  4.2123 +                        tempw=getword();
  4.2124 +                        tempw2=getword();
  4.2125 +                        tempw3=CS;
  4.2126 +                        tempw4=pc;
  4.2127 +                        if (ssegs) ss=oldss;
  4.2128 +                        pc=tempw;
  4.2129 +//                        printf("0x9a");
  4.2130 +                        loadcs(tempw2);
  4.2131 +                        writememw(ss,(SP-2)&0xFFFF,tempw3);
  4.2132 +                        writememw(ss,(SP-4)&0xFFFF,tempw4);
  4.2133 +                        SP-=4;
  4.2134 +                        cycles-=36;
  4.2135 +                        FETCHCLEAR();
  4.2136 +                        break;
  4.2137 +                        case 0x9B: /*WAIT*/
  4.2138 +                        cycles-=4;
  4.2139 +                        break;
  4.2140 +                        case 0x9C: /*PUSHF*/
  4.2141 +                        if (ssegs) ss=oldss;
  4.2142 +                        writememw(ss,((SP-2)&0xFFFF),flags|0xF000);
  4.2143 +                        SP-=2;
  4.2144 +                        cycles-=14;
  4.2145 +                        break;
  4.2146 +                        case 0x9D: /*POPF*/
  4.2147 +                        if (ssegs) ss=oldss;
  4.2148 +                        flags=readmemw(ss,SP)&0xFFF;
  4.2149 +                        SP+=2;
  4.2150 +                        cycles-=12;
  4.2151 +                        break;
  4.2152 +                        case 0x9E: /*SAHF*/
  4.2153 +                        flags=(flags&0xFF00)|AH;
  4.2154 +                        cycles-=4;
  4.2155 +                        break;
  4.2156 +                        case 0x9F: /*LAHF*/
  4.2157 +                        AH=flags&0xFF;
  4.2158 +                        cycles-=4;
  4.2159 +                        break;
  4.2160 +
  4.2161 +                        case 0xA0: /*MOV AL,(w)*/
  4.2162 +                        addr=getword();
  4.2163 +                        AL=readmemb(ds+addr);
  4.2164 +                        cycles-=14;
  4.2165 +                        break;
  4.2166 +                        case 0xA1: /*MOV AX,(w)*/
  4.2167 +                        addr=getword();
  4.2168 +//                        printf("Reading AX from %05X %04X:%04X\n",ds+addr,ds>>4,addr);
  4.2169 +                        AX=readmemw(ds,addr);
  4.2170 +                        cycles-=!4;
  4.2171 +                        break;
  4.2172 +                        case 0xA2: /*MOV (w),AL*/
  4.2173 +                        addr=getword();
  4.2174 +                        writememb(ds+addr,AL);
  4.2175 +                        cycles-=14;
  4.2176 +                        break;
  4.2177 +                        case 0xA3: /*MOV (w),AX*/
  4.2178 +                        addr=getword();
  4.2179 +//                        if (!addr) printf("Write !addr %04X:%04X\n",cs>>4,pc);
  4.2180 +                        writememw(ds,addr,AX);
  4.2181 +                        cycles-=14;
  4.2182 +                        break;
  4.2183 +
  4.2184 +                        case 0xA4: /*MOVSB*/
  4.2185 +                        temp=readmemb(ds+SI);
  4.2186 +                        writememb(es+DI,temp);
  4.2187 +                        if (flags&D_FLAG) { DI--; SI--; }
  4.2188 +                        else              { DI++; SI++; }
  4.2189 +                        cycles-=18;
  4.2190 +                        break;
  4.2191 +                        case 0xA5: /*MOVSW*/
  4.2192 +                        tempw=readmemw(ds,SI);
  4.2193 +                        writememw(es,DI,tempw);
  4.2194 +                        if (flags&D_FLAG) { DI-=2; SI-=2; }
  4.2195 +                        else              { DI+=2; SI+=2; }
  4.2196 +                        cycles-=18;
  4.2197 +                        break;
  4.2198 +                        case 0xA6: /*CMPSB*/
  4.2199 +                        temp =readmemb(ds+SI);
  4.2200 +                        temp2=readmemb(es+DI);
  4.2201 +                        setsub8(temp,temp2);
  4.2202 +                        if (flags&D_FLAG) { DI--; SI--; }
  4.2203 +                        else              { DI++; SI++; }
  4.2204 +                        cycles-=30;
  4.2205 +                        break;
  4.2206 +                        case 0xA7: /*CMPSW*/
  4.2207 +                        tempw =readmemw(ds,SI);
  4.2208 +                        tempw2=readmemw(es,DI);
  4.2209 +//                        printf("CMPSW %04X %04X\n",tempw,tempw2);
  4.2210 +                        setsub16(tempw,tempw2);
  4.2211 +                        if (flags&D_FLAG) { DI-=2; SI-=2; }
  4.2212 +                        else              { DI+=2; SI+=2; }
  4.2213 +                        cycles-=30;
  4.2214 +                        break;
  4.2215 +                        case 0xA8: /*TEST AL,#8*/
  4.2216 +                        temp=FETCH();
  4.2217 +                        setznp8(AL&temp);
  4.2218 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.2219 +                        cycles-=5;
  4.2220 +                        break;
  4.2221 +                        case 0xA9: /*TEST AX,#16*/
  4.2222 +                        tempw=getword();
  4.2223 +                        setznp16(AX&tempw);
  4.2224 +                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.2225 +                        cycles-=5;
  4.2226 +                        break;
  4.2227 +                        case 0xAA: /*STOSB*/
  4.2228 +                        writememb(es+DI,AL);
  4.2229 +                        if (flags&D_FLAG) DI--;
  4.2230 +                        else              DI++;
  4.2231 +                        cycles-=11;
  4.2232 +                        break;
  4.2233 +                        case 0xAB: /*STOSW*/
  4.2234 +                        writememw(es,DI,AX);
  4.2235 +                        if (flags&D_FLAG) DI-=2;
  4.2236 +                        else              DI+=2;
  4.2237 +                        cycles-=11;
  4.2238 +                        break;
  4.2239 +                        case 0xAC: /*LODSB*/
  4.2240 +                        AL=readmemb(ds+SI);
  4.2241 +//                        printf("LODSB %04X:%04X %02X %04X:%04X\n",cs>>4,pc,AL,ds>>4,SI);
  4.2242 +                        if (flags&D_FLAG) SI--;
  4.2243 +                        else              SI++;
  4.2244 +                        cycles-=16;
  4.2245 +                        break;
  4.2246 +                        case 0xAD: /*LODSW*/
  4.2247 +//                        if (times) printf("LODSW %04X:%04X\n",cs>>4,pc);
  4.2248 +                        AX=readmemw(ds,SI);
  4.2249 +                        if (flags&D_FLAG) SI-=2;
  4.2250 +                        else              SI+=2;
  4.2251 +                        cycles-=16;
  4.2252 +                        break;
  4.2253 +                        case 0xAE: /*SCASB*/
  4.2254 +                        temp=readmemb(es+DI);
  4.2255 +                        setsub8(AL,temp);
  4.2256 +                        if (flags&D_FLAG) DI--;
  4.2257 +                        else              DI++;
  4.2258 +                        cycles-=19;
  4.2259 +                        break;
  4.2260 +                        case 0xAF: /*SCASW*/
  4.2261 +                        tempw=readmemw(es,DI);
  4.2262 +                        setsub16(AX,tempw);
  4.2263 +                        if (flags&D_FLAG) DI-=2;
  4.2264 +                        else              DI+=2;
  4.2265 +                        cycles-=19;
  4.2266 +                        break;
  4.2267 +
  4.2268 +                        case 0xB0: /*MOV AL,#8*/
  4.2269 +                        AL=FETCH();
  4.2270 +                        cycles-=4;
  4.2271 +                        break;
  4.2272 +                        case 0xB1: /*MOV CL,#8*/
  4.2273 +                        CL=FETCH();
  4.2274 +                        cycles-=4;
  4.2275 +                        break;
  4.2276 +                        case 0xB2: /*MOV DL,#8*/
  4.2277 +                        DL=FETCH();
  4.2278 +                        cycles-=4;
  4.2279 +                        break;
  4.2280 +                        case 0xB3: /*MOV BL,#8*/
  4.2281 +                        BL=FETCH();
  4.2282 +                        cycles-=4;
  4.2283 +                        break;
  4.2284 +                        case 0xB4: /*MOV AH,#8*/
  4.2285 +                        AH=FETCH();
  4.2286 +                        cycles-=4;
  4.2287 +                        break;
  4.2288 +                        case 0xB5: /*MOV CH,#8*/
  4.2289 +                        CH=FETCH();
  4.2290 +                        cycles-=4;
  4.2291 +                        break;
  4.2292 +                        case 0xB6: /*MOV DH,#8*/
  4.2293 +                        DH=FETCH();
  4.2294 +                        cycles-=4;
  4.2295 +                        break;
  4.2296 +                        case 0xB7: /*MOV BH,#8*/
  4.2297 +                        BH=FETCH();
  4.2298 +                        cycles-=4;
  4.2299 +                        break;
  4.2300 +                        case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV reg,#16*/
  4.2301 +                        case 0xBC: case 0xBD: case 0xBE: case 0xBF:
  4.2302 +                        regs[opcode&7].w=getword();
  4.2303 +                        cycles-=4;
  4.2304 +                        break;
  4.2305 +
  4.2306 +                        case 0xC2: /*RET*/
  4.2307 +                        tempw=getword();
  4.2308 +                        if (ssegs) ss=oldss;
  4.2309 +                        pc=readmemw(ss,SP);
  4.2310 +//                        printf("C2\n");
  4.2311 +//                        printf("RET to %04X\n",pc);
  4.2312 +                        SP+=2+tempw;
  4.2313 +                        cycles-=24;
  4.2314 +                        FETCHCLEAR();
  4.2315 +                        break;
  4.2316 +                        case 0xC3: /*RET*/
  4.2317 +                        if (ssegs) ss=oldss;
  4.2318 +                        pc=readmemw(ss,SP);
  4.2319 +//                        printf("C3\n");
  4.2320 +//                        if (output) printf("RET to %04X %05X\n",pc,ss+SP);
  4.2321 +                        SP+=2;
  4.2322 +                        cycles-=20;
  4.2323 +                        FETCHCLEAR();
  4.2324 +                        break;
  4.2325 +                        case 0xC4: /*LES*/
  4.2326 +                        fetchea();
  4.2327 +                        regs[reg].w=readmemw(easeg,eaaddr); //geteaw();
  4.2328 +                        tempw=readmemw(easeg,(eaaddr+2)&0xFFFF); //geteaw2();
  4.2329 +                        loadseg(tempw,&_es);
  4.2330 +                        cycles-=24;
  4.2331 +                        break;
  4.2332 +                        case 0xC5: /*LDS*/
  4.2333 +                        fetchea();
  4.2334 +                        regs[reg].w=readmemw(easeg,eaaddr);
  4.2335 +                        tempw=readmemw(easeg,(eaaddr+2)&0xFFFF);
  4.2336 +                        loadseg(tempw,&_ds);
  4.2337 +                        if (ssegs) oldds=ds;
  4.2338 +                        cycles-=24;
  4.2339 +                        break;
  4.2340 +                        case 0xC6: /*MOV b,#8*/
  4.2341 +                        fetchea();
  4.2342 +                        temp=FETCH();
  4.2343 +                        seteab(temp);
  4.2344 +                        cycles-=((mod==3)?4:14);
  4.2345 +                        break;
  4.2346 +                        case 0xC7: /*MOV w,#16*/
  4.2347 +                        fetchea();
  4.2348 +                        tempw=getword();
  4.2349 +                        seteaw(tempw);
  4.2350 +                        cycles-=((mod==3)?4:14);
  4.2351 +                        break;
  4.2352 +
  4.2353 +                        case 0xCA: /*RETF*/
  4.2354 +                        tempw=getword();
  4.2355 +                        if (ssegs) ss=oldss;
  4.2356 +                        pc=readmemw(ss,SP);
  4.2357 +//                        printf("CA\n");
  4.2358 +                        loadcs(readmemw(ss,SP+2));
  4.2359 +                        SP+=4;
  4.2360 +                        SP+=tempw;
  4.2361 +                        cycles-=33;
  4.2362 +                        FETCHCLEAR();
  4.2363 +                        break;
  4.2364 +                        case 0xCB: /*RETF*/
  4.2365 +                        if (ssegs) ss=oldss;
  4.2366 +                        pc=readmemw(ss,SP);
  4.2367 +//                        printf("CB\n");
  4.2368 +                        loadcs(readmemw(ss,SP+2));
  4.2369 +                        SP+=4;
  4.2370 +                        cycles-=34;
  4.2371 +                        FETCHCLEAR();
  4.2372 +                        break;
  4.2373 +                        case 0xCC: /*INT 3*/
  4.2374 +                        if (ssegs) ss=oldss;
  4.2375 +                        writememw(ss,((SP-2)&0xFFFF),flags|0xF000);
  4.2376 +                        writememw(ss,((SP-4)&0xFFFF),CS);
  4.2377 +                        writememw(ss,((SP-6)&0xFFFF),pc);
  4.2378 +                        SP-=6;
  4.2379 +                        addr=3<<2;
  4.2380 +                        flags&=~I_FLAG;
  4.2381 +                        flags&=~T_FLAG;
  4.2382 +//                        printf("CC %04X:%04X  ",CS,pc);
  4.2383 +                        pc=readmemw(0,addr);
  4.2384 +                        loadcs(readmemw(0,addr+2));
  4.2385 +                        FETCHCLEAR();
  4.2386 +//                        printf("%04X:%04X\n",CS,pc);
  4.2387 +                        cycles-=72;
  4.2388 +                        break;
  4.2389 +                        case 0xCD: /*INT*/
  4.2390 +                        lastpc=pc;
  4.2391 +                        lastcs=CS;
  4.2392 +                        temp=FETCH();
  4.2393 +                        
  4.2394 +                        if (ssegs) ss=oldss;
  4.2395 +                        writememw(ss,((SP-2)&0xFFFF),flags|0xF000);
  4.2396 +                        writememw(ss,((SP-4)&0xFFFF),CS);
  4.2397 +                        writememw(ss,((SP-6)&0xFFFF),pc);
  4.2398 +                        flags&=~T_FLAG;
  4.2399 +                        SP-=6;
  4.2400 +                        addr=temp<<2;
  4.2401 +                        pc=readmemw(0,addr);
  4.2402 +
  4.2403 +                        loadcs(readmemw(0,addr+2));
  4.2404 +                        FETCHCLEAR();
  4.2405 +
  4.2406 +                        cycles-=71;
  4.2407 +                        break;
  4.2408 +                        case 0xCF: /*IRET*/
  4.2409 +                        if (ssegs) ss=oldss;
  4.2410 +                        tempw=CS;
  4.2411 +                        tempw2=pc;
  4.2412 +                        pc=readmemw(ss,SP);
  4.2413 +//                        printf("CF\n");
  4.2414 +                        loadcs(readmemw(ss,((SP+2)&0xFFFF)));
  4.2415 +                        flags=readmemw(ss,((SP+4)&0xFFFF))&0xFFF;
  4.2416 +                        SP+=6;
  4.2417 +                        cycles-=44;
  4.2418 +                        FETCHCLEAR();
  4.2419 +                        break;
  4.2420 +                        case 0xD0:
  4.2421 +                        fetchea();
  4.2422 +                        temp=geteab();
  4.2423 +                        switch (rmdat&0x38)
  4.2424 +                        {
  4.2425 +                                case 0x00: /*ROL b,1*/
  4.2426 +                                if (temp&0x80) flags|=C_FLAG;
  4.2427 +                                else           flags&=~C_FLAG;
  4.2428 +                                temp<<=1;
  4.2429 +                                if (flags&C_FLAG) temp|=1;
  4.2430 +                                seteab(temp);
  4.2431 +//                                setznp8(temp);
  4.2432 +                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
  4.2433 +                                else                          flags&=~V_FLAG;
  4.2434 +                                cycles-=((mod==3)?2:23);
  4.2435 +                                break;
  4.2436 +                                case 0x08: /*ROR b,1*/
  4.2437 +                                if (temp&1) flags|=C_FLAG;
  4.2438 +                                else        flags&=~C_FLAG;
  4.2439 +                                temp>>=1;
  4.2440 +                                if (flags&C_FLAG) temp|=0x80;
  4.2441 +                                seteab(temp);
  4.2442 +//                                setznp8(temp);
  4.2443 +                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
  4.2444 +                                else                       flags&=~V_FLAG;
  4.2445 +                                cycles-=((mod==3)?2:23);
  4.2446 +                                break;
  4.2447 +                                case 0x10: /*RCL b,1*/
  4.2448 +                                temp2=flags&C_FLAG;
  4.2449 +                                if (temp&0x80) flags|=C_FLAG;
  4.2450 +                                else           flags&=~C_FLAG;
  4.2451 +                                temp<<=1;
  4.2452 +                                if (temp2) temp|=1;
  4.2453 +                                seteab(temp);
  4.2454 +//                                setznp8(temp);
  4.2455 +                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
  4.2456 +                                else                          flags&=~V_FLAG;
  4.2457 +                                cycles-=((mod==3)?2:23);
  4.2458 +                                break;
  4.2459 +                                case 0x18: /*RCR b,1*/
  4.2460 +                                temp2=flags&C_FLAG;
  4.2461 +                                if (temp&1) flags|=C_FLAG;
  4.2462 +                                else        flags&=~C_FLAG;
  4.2463 +                                temp>>=1;
  4.2464 +                                if (temp2) temp|=0x80;
  4.2465 +                                seteab(temp);
  4.2466 +//                                setznp8(temp);
  4.2467 +                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
  4.2468 +                                else                       flags&=~V_FLAG;
  4.2469 +                                cycles-=((mod==3)?2:23);
  4.2470 +                                break;
  4.2471 +                                case 0x20: case 0x30: /*SHL b,1*/
  4.2472 +                                if (temp&0x80) flags|=C_FLAG;
  4.2473 +                                else           flags&=~C_FLAG;
  4.2474 +                                if ((temp^(temp<<1))&0x80) flags|=V_FLAG;
  4.2475 +                                else                       flags&=~V_FLAG;
  4.2476 +                                temp<<=1;
  4.2477 +                                seteab(temp);
  4.2478 +                                setznp8(temp);
  4.2479 +                                cycles-=((mod==3)?2:23);
  4.2480 +                                flags|=A_FLAG;
  4.2481 +                                break;
  4.2482 +                                case 0x28: /*SHR b,1*/
  4.2483 +                                if (temp&1) flags|=C_FLAG;
  4.2484 +                                else        flags&=~C_FLAG;
  4.2485 +                                if (temp&0x80) flags|=V_FLAG;
  4.2486 +                                else           flags&=~V_FLAG;
  4.2487 +                                temp>>=1;
  4.2488 +                                seteab(temp);
  4.2489 +                                setznp8(temp);
  4.2490 +                                cycles-=((mod==3)?2:23);
  4.2491 +                                flags|=A_FLAG;
  4.2492 +                                break;
  4.2493 +                                case 0x38: /*SAR b,1*/
  4.2494 +                                if (temp&1) flags|=C_FLAG;
  4.2495 +                                else        flags&=~C_FLAG;
  4.2496 +                                temp>>=1;
  4.2497 +                                if (temp&0x40) temp|=0x80;
  4.2498 +                                seteab(temp);
  4.2499 +                                setznp8(temp);
  4.2500 +                                cycles-=((mod==3)?2:23);
  4.2501 +                                flags|=A_FLAG;
  4.2502 +                                flags&=~V_FLAG;
  4.2503 +                                break;
  4.2504 +
  4.2505 +//                                default:
  4.2506 +//                                printf("Bad D0 opcode %02X\n",rmdat&0x38);
  4.2507 +//                                dumpregs();
  4.2508 +//                                exit(-1);
  4.2509 +                        }
  4.2510 +                        break;
  4.2511 +
  4.2512 +                        case 0xD1:
  4.2513 +                        fetchea();
  4.2514 +                        tempw=geteaw();
  4.2515 +                        switch (rmdat&0x38)
  4.2516 +                        {
  4.2517 +                                case 0x00: /*ROL w,1*/
  4.2518 +                                if (tempw&0x8000) flags|=C_FLAG;
  4.2519 +                                else              flags&=~C_FLAG;
  4.2520 +                                tempw<<=1;
  4.2521 +                                if (flags&C_FLAG) tempw|=1;
  4.2522 +                                seteaw(tempw);
  4.2523 +//                                setznp16(tempw);
  4.2524 +                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
  4.2525 +                                else                            flags&=~V_FLAG;
  4.2526 +                                cycles-=((mod==3)?2:23);
  4.2527 +                                break;
  4.2528 +                                case 0x08: /*ROR w,1*/
  4.2529 +                                if (tempw&1) flags|=C_FLAG;
  4.2530 +                                else         flags&=~C_FLAG;
  4.2531 +                                tempw>>=1;
  4.2532 +                                if (flags&C_FLAG) tempw|=0x8000;
  4.2533 +                                seteaw(tempw);
  4.2534 +//                                setznp16(tempw);
  4.2535 +                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
  4.2536 +                                else                           flags&=~V_FLAG;
  4.2537 +                                cycles-=((mod==3)?2:23);
  4.2538 +                                break;
  4.2539 +                                case 0x10: /*RCL w,1*/
  4.2540 +                                temp2=flags&C_FLAG;
  4.2541 +                                if (tempw&0x8000) flags|=C_FLAG;
  4.2542 +                                else              flags&=~C_FLAG;
  4.2543 +                                tempw<<=1;
  4.2544 +                                if (temp2) tempw|=1;
  4.2545 +                                seteaw(tempw);
  4.2546 +                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
  4.2547 +                                else                            flags&=~V_FLAG;
  4.2548 +                                cycles-=((mod==3)?2:23);
  4.2549 +                                break;
  4.2550 +                                case 0x18: /*RCR w,1*/
  4.2551 +                                temp2=flags&C_FLAG;
  4.2552 +                                if (tempw&1) flags|=C_FLAG;
  4.2553 +                                else         flags&=~C_FLAG;
  4.2554 +                                tempw>>=1;
  4.2555 +                                if (temp2) tempw|=0x8000;
  4.2556 +                                seteaw(tempw);
  4.2557 +//                                setznp16(tempw);
  4.2558 +                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
  4.2559 +                                else                           flags&=~V_FLAG;
  4.2560 +                                cycles-=((mod==3)?2:23);
  4.2561 +                                break;
  4.2562 +                                case 0x20: case 0x30: /*SHL w,1*/
  4.2563 +                                if (tempw&0x8000) flags|=C_FLAG;
  4.2564 +                                else              flags&=~C_FLAG;
  4.2565 +                                if ((tempw^(tempw<<1))&0x8000) flags|=V_FLAG;
  4.2566 +                                else                           flags&=~V_FLAG;
  4.2567 +                                tempw<<=1;
  4.2568 +                                seteaw(tempw);
  4.2569 +                                setznp16(tempw);
  4.2570 +                                cycles-=((mod==3)?2:23);
  4.2571 +                                flags|=A_FLAG;
  4.2572 +                                break;
  4.2573 +                                case 0x28: /*SHR w,1*/
  4.2574 +                                if (tempw&1) flags|=C_FLAG;
  4.2575 +                                else         flags&=~C_FLAG;
  4.2576 +                                if (tempw&0x8000) flags|=V_FLAG;
  4.2577 +                                else              flags&=~V_FLAG;
  4.2578 +                                tempw>>=1;
  4.2579 +                                seteaw(tempw);
  4.2580 +                                setznp16(tempw);
  4.2581 +                                cycles-=((mod==3)?2:23);
  4.2582 +                                flags|=A_FLAG;
  4.2583 +                                break;
  4.2584 +
  4.2585 +                                case 0x38: /*SAR w,1*/
  4.2586 +                                if (tempw&1) flags|=C_FLAG;
  4.2587 +                                else         flags&=~C_FLAG;
  4.2588 +                                tempw>>=1;
  4.2589 +                                if (tempw&0x4000) tempw|=0x8000;
  4.2590 +                                seteaw(tempw);
  4.2591 +                                setznp16(tempw);
  4.2592 +                                cycles-=((mod==3)?2:23);
  4.2593 +                                flags|=A_FLAG;
  4.2594 +                                flags&=~V_FLAG;
  4.2595 +                                break;
  4.2596 +
  4.2597 +//                                default:
  4.2598 +//                                printf("Bad D1 opcode %02X\n",rmdat&0x38);
  4.2599 +//                                dumpregs();
  4.2600 +//                                exit(-1);
  4.2601 +                        }
  4.2602 +                        break;
  4.2603 +
  4.2604 +                        case 0xD2:
  4.2605 +                        fetchea();
  4.2606 +                        temp=geteab();
  4.2607 +                        c=CL;
  4.2608 +//                        cycles-=c;
  4.2609 +                        if (!c) break;
  4.2610 +//                        if (c>7) printf("Shiftb %i %02X\n",rmdat&0x38,c);
  4.2611 +                        switch (rmdat&0x38)
  4.2612 +                        {
  4.2613 +                                case 0x00: /*ROL b,CL*/
  4.2614 +                                while (c>0)
  4.2615 +                                {
  4.2616 +                                        temp2=(temp&0x80)?1:0;
  4.2617 +                                        temp=(temp<<1)|temp2;
  4.2618 +                                        c--;
  4.2619 +                                        cycles-=4;
  4.2620 +                                }
  4.2621 +                                if (temp2) flags|=C_FLAG;
  4.2622 +                                else       flags&=~C_FLAG;
  4.2623 +                                seteab(temp);
  4.2624 +//                                setznp8(temp);
  4.2625 +                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
  4.2626 +                                else                          flags&=~V_FLAG;
  4.2627 +                                cycles-=((mod==3)?8:28);
  4.2628 +                                break;
  4.2629 +                                case 0x08: /*ROR b,CL*/
  4.2630 +                                while (c>0)
  4.2631 +                                {
  4.2632 +                                        temp2=temp&1;
  4.2633 +                                        temp>>=1;
  4.2634 +                                        if (temp2) temp|=0x80;
  4.2635 +                                        c--;
  4.2636 +                                        cycles-=4;
  4.2637 +                                }
  4.2638 +                                if (temp2) flags|=C_FLAG;
  4.2639 +                                else       flags&=~C_FLAG;
  4.2640 +                                seteab(temp);
  4.2641 +                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
  4.2642 +                                else                       flags&=~V_FLAG;
  4.2643 +                                cycles-=((mod==3)?8:28);
  4.2644 +                                break;
  4.2645 +                                case 0x10: /*RCL b,CL*/
  4.2646 +//                                printf("RCL %i %02X %02X\n",c,CL,temp);
  4.2647 +                                while (c>0)
  4.2648 +                                {
  4.2649 +                                        templ=flags&C_FLAG;
  4.2650 +                                        temp2=temp&0x80;
  4.2651 +                                        temp<<=1;
  4.2652 +                                        if (temp2) flags|=C_FLAG;
  4.2653 +                                        else       flags&=~C_FLAG;
  4.2654 +                                        if (templ) temp|=1;
  4.2655 +                                        c--;
  4.2656 +                                        cycles-=4;
  4.2657 +                                }
  4.2658 +//                                printf("Now %02X\n",temp);
  4.2659 +                                seteab(temp);
  4.2660 +                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
  4.2661 +                                else                          flags&=~V_FLAG;
  4.2662 +                                cycles-=((mod==3)?8:28);
  4.2663 +                                break;
  4.2664 +                                case 0x18: /*RCR b,CL*/
  4.2665 +                                while (c>0)
  4.2666 +                                {
  4.2667 +                                        templ=flags&C_FLAG;
  4.2668 +                                        temp2=temp&1;
  4.2669 +                                        temp>>=1;
  4.2670 +                                        if (temp2) flags|=C_FLAG;
  4.2671 +                                        else       flags&=~C_FLAG;
  4.2672 +                                        if (templ) temp|=0x80;
  4.2673 +                                        c--;
  4.2674 +                                        cycles-=4;
  4.2675 +                                }
  4.2676 +//                                if (temp2) flags|=C_FLAG;
  4.2677 +//                                else       flags&=~C_FLAG;
  4.2678 +                                seteab(temp);
  4.2679 +                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
  4.2680 +                                else                       flags&=~V_FLAG;
  4.2681 +                                cycles-=((mod==3)?8:28);
  4.2682 +                                break;
  4.2683 +                                case 0x20: case 0x30: /*SHL b,CL*/
  4.2684 +                                if ((temp<<(c-1))&0x80) flags|=C_FLAG;
  4.2685 +                                else                    flags&=~C_FLAG;
  4.2686 +                                temp<<=c;
  4.2687 +                                seteab(temp);
  4.2688 +                                setznp8(temp);
  4.2689 +                                cycles-=(c*4);
  4.2690 +                                cycles-=((mod==3)?8:28);
  4.2691 +                                flags|=A_FLAG;
  4.2692 +                                break;
  4.2693 +                                case 0x28: /*SHR b,CL*/
  4.2694 +                                if ((temp>>(c-1))&1) flags|=C_FLAG;
  4.2695 +                                else                 flags&=~C_FLAG;
  4.2696 +                                temp>>=c;
  4.2697 +                                seteab(temp);
  4.2698 +                                setznp8(temp);
  4.2699 +                                cycles-=(c*4);
  4.2700 +                                cycles-=((mod==3)?8:28);
  4.2701 +                                flags|=A_FLAG;
  4.2702 +                                break;
  4.2703 +                                case 0x38: /*SAR b,CL*/
  4.2704 +                                if ((temp>>(c-1))&1) flags|=C_FLAG;
  4.2705 +                                else                 flags&=~C_FLAG;
  4.2706 +                                while (c>0)
  4.2707 +                                {
  4.2708 +                                        temp>>=1;
  4.2709 +                                        if (temp&0x40) temp|=0x80;
  4.2710 +                                        c--;
  4.2711 +                                        cycles-=4;
  4.2712 +                                }
  4.2713 +                                seteab(temp);
  4.2714 +                                setznp8(temp);
  4.2715 +                                cycles-=((mod==3)?8:28);
  4.2716 +                                flags|=A_FLAG;
  4.2717 +                                break;
  4.2718 +
  4.2719 +//                                default:
  4.2720 +//                                printf("Bad D2 opcode %02X\n",rmdat&0x38);
  4.2721 +//                                dumpregs();
  4.2722 +//                                exit(-1);
  4.2723 +                        }
  4.2724 +                        break;
  4.2725 +
  4.2726 +                        case 0xD3:
  4.2727 +                        fetchea();
  4.2728 +                        tempw=geteaw();
  4.2729 +                        c=CL;
  4.2730 +//                      cycles-=c;
  4.2731 +                        if (!c) break;
  4.2732 +//                        if (c>15) printf("Shiftw %i %02X\n",rmdat&0x38,c);
  4.2733 +                        switch (rmdat&0x38)
  4.2734 +                        {
  4.2735 +                                case 0x00: /*ROL w,CL*/
  4.2736 +                                while (c>0)
  4.2737 +                                {
  4.2738 +                                        temp=(tempw&0x8000)?1:0;
  4.2739 +                                        tempw=(tempw<<1)|temp;
  4.2740 +                                        c--;
  4.2741 +                                        cycles-=4;
  4.2742 +                                }
  4.2743 +                                if (temp) flags|=C_FLAG;
  4.2744 +                                else      flags&=~C_FLAG;
  4.2745 +                                seteaw(tempw);
  4.2746 +                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
  4.2747 +                                else                            flags&=~V_FLAG;
  4.2748 +                                cycles-=((mod==3)?8:28);
  4.2749 +                                break;
  4.2750 +                                case 0x08: /*ROR w,CL*/
  4.2751 +                                while (c>0)
  4.2752 +                                {
  4.2753 +                                        tempw2=(tempw&1)?0x8000:0;
  4.2754 +                                        tempw=(tempw>>1)|tempw2;
  4.2755 +                                        c--;
  4.2756 +                                        cycles-=4;
  4.2757 +                                }
  4.2758 +                                if (tempw2) flags|=C_FLAG;
  4.2759 +                                else        flags&=~C_FLAG;
  4.2760 +                                seteaw(tempw);
  4.2761 +                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
  4.2762 +                                else                           flags&=~V_FLAG;
  4.2763 +                                cycles-=((mod==3)?8:28);
  4.2764 +                                break;
  4.2765 +                                case 0x10: /*RCL w,CL*/
  4.2766 +                                while (c>0)
  4.2767 +                                {
  4.2768 +                                        templ=flags&C_FLAG;
  4.2769 +                                        if (tempw&0x8000) flags|=C_FLAG;
  4.2770 +                                        else              flags&=~C_FLAG;
  4.2771 +                                        tempw=(tempw<<1)|templ;
  4.2772 +                                        c--;
  4.2773 +                                        cycles-=4;
  4.2774 +                                }
  4.2775 +                                if (temp) flags|=C_FLAG;
  4.2776 +                                else      flags&=~C_FLAG;
  4.2777 +                                seteaw(tempw);
  4.2778 +                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
  4.2779 +                                else                            flags&=~V_FLAG;
  4.2780 +                                cycles-=((mod==3)?8:28);
  4.2781 +                                break;
  4.2782 +                                case 0x18: /*RCR w,CL*/
  4.2783 +                                while (c>0)
  4.2784 +                                {
  4.2785 +                                        templ=flags&C_FLAG;
  4.2786 +                                        tempw2=(templ&1)?0x8000:0;
  4.2787 +                                        if (tempw&1) flags|=C_FLAG;
  4.2788 +                                        else         flags&=~C_FLAG;
  4.2789 +                                        tempw=(tempw>>1)|tempw2;
  4.2790 +                                        c--;
  4.2791 +                                        cycles-=4;
  4.2792 +                                }
  4.2793 +                                if (tempw2) flags|=C_FLAG;
  4.2794 +                                else        flags&=~C_FLAG;
  4.2795 +                                seteaw(tempw);
  4.2796 +                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
  4.2797 +                                else                           flags&=~V_FLAG;
  4.2798 +                                cycles-=((mod==3)?8:28);
  4.2799 +                                break;
  4.2800 +
  4.2801 +                                case 0x20: case 0x30: /*SHL w,CL*/
  4.2802 +                                if (c>16)
  4.2803 +                                {
  4.2804 +                                        tempw=0;
  4.2805 +                                        flags&=~C_FLAG;
  4.2806 +                                }
  4.2807 +                                else
  4.2808 +                                {
  4.2809 +                                        if ((tempw<<(c-1))&0x8000) flags|=C_FLAG;
  4.2810 +                                        else                       flags&=~C_FLAG;
  4.2811 +                                        tempw<<=c;
  4.2812 +                                }
  4.2813 +                                seteaw(tempw);
  4.2814 +                                setznp16(tempw);
  4.2815 +                                cycles-=(c*4);
  4.2816 +                                cycles-=((mod==3)?8:28);
  4.2817 +                                flags|=A_FLAG;
  4.2818 +                                break;
  4.2819 +
  4.2820 +                                case 0x28:            /*SHR w,CL*/
  4.2821 +                                if ((tempw>>(c-1))&1) flags|=C_FLAG;
  4.2822 +                                else                  flags&=~C_FLAG;
  4.2823 +                                tempw>>=c;
  4.2824 +                                seteaw(tempw);
  4.2825 +                                setznp16(tempw);
  4.2826 +                                cycles-=(c*4);
  4.2827 +                                cycles-=((mod==3)?8:28);
  4.2828 +                                flags|=A_FLAG;
  4.2829 +                                break;
  4.2830 +
  4.2831 +                                case 0x38:            /*SAR w,CL*/
  4.2832 +                                tempw2=tempw&0x8000;
  4.2833 +                                if ((tempw>>(c-1))&1) flags|=C_FLAG;
  4.2834 +                                else                  flags&=~C_FLAG;
  4.2835 +                                while (c>0)
  4.2836 +                                {
  4.2837 +                                        tempw=(tempw>>1)|tempw2;
  4.2838 +                                        c--;
  4.2839 +                                        cycles-=4;
  4.2840 +                                }
  4.2841 +                                seteaw(tempw);
  4.2842 +                                setznp16(tempw);
  4.2843 +                                cycles-=((mod==3)?8:28);
  4.2844 +                                flags|=A_FLAG;
  4.2845 +                                break;
  4.2846 +
  4.2847 +//                                default:
  4.2848 +//                                printf("Bad D3 opcode %02X\n",rmdat&0x38);
  4.2849 +//                                dumpregs();
  4.2850 +//                                exit(-1);
  4.2851 +                        }
  4.2852 +                        break;
  4.2853 +
  4.2854 +                        case 0xD4: /*AAM*/
  4.2855 +                        tempws=FETCH();
  4.2856 +                        AH=AL/tempws;
  4.2857 +                        AL%=tempws;
  4.2858 +                        setznp16(AX);
  4.2859 +                        cycles-=83;
  4.2860 +                        break;
  4.2861 +                        case 0xD5: /*AAD*/
  4.2862 +                        tempws=FETCH();
  4.2863 +                        AL=(AH*tempws)+AL;
  4.2864 +                        AH=0;
  4.2865 +                        setznp16(AX);
  4.2866 +                        cycles-=60;
  4.2867 +                        break;
  4.2868 +                        case 0xD7: /*XLAT*/
  4.2869 +                        addr=BX+AL;
  4.2870 +                        AL=readmemb(ds+addr);
  4.2871 +                        cycles-=11;
  4.2872 +                        break;
  4.2873 +                        case 0xD9: case 0xDA: case 0xDB: case 0xDD: /*ESCAPE*/
  4.2874 +                        case 0xDC: case 0xDE: case 0xDF: case 0xD8:
  4.2875 +                        fetchea();
  4.2876 +                        geteab();
  4.2877 +                        break;
  4.2878 +
  4.2879 +                        case 0xE0: /*LOOPNE*/
  4.2880 +                        offset=(int8_t)FETCH();
  4.2881 +                        CX--;
  4.2882 +                        if (CX && !(flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.2883 +                        cycles-=6;
  4.2884 +                        break;
  4.2885 +                        case 0xE1: /*LOOPE*/
  4.2886 +                        offset=(int8_t)FETCH();
  4.2887 +                        CX--;
  4.2888 +                        if (CX && (flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.2889 +                        cycles-=6;
  4.2890 +                        break;
  4.2891 +                        case 0xE2: /*LOOP*/
  4.2892 +//                        printf("LOOP start\n");
  4.2893 +                        offset=(int8_t)FETCH();
  4.2894 +                        CX--;
  4.2895 +                        if (CX) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.2896 +                        cycles-=5;
  4.2897 +//                        printf("LOOP end!\n");
  4.2898 +                        break;
  4.2899 +                        case 0xE3: /*JCXZ*/
  4.2900 +                        offset=(int8_t)FETCH();
  4.2901 +                        if (!CX) { pc+=offset; cycles-=12; FETCHCLEAR(); }
  4.2902 +                        cycles-=6;
  4.2903 +                        break;
  4.2904 +
  4.2905 +                        case 0xE4: /*IN AL*/
  4.2906 +                        temp=FETCH();
  4.2907 +                        AL=inb(temp);
  4.2908 +                        cycles-=14;
  4.2909 +                        break;
  4.2910 +                        case 0xE5: /*IN AX*/
  4.2911 +                        temp=FETCH();
  4.2912 +                        AL=inb(temp);
  4.2913 +                        AH=inb(temp+1);
  4.2914 +                        cycles-=14;
  4.2915 +                        break;
  4.2916 +                        case 0xE6: /*OUT AL*/
  4.2917 +                        temp=FETCH();
  4.2918 +                        outb(temp,AL);
  4.2919 +                        cycles-=14;
  4.2920 +                        break;
  4.2921 +                        case 0xE7: /*OUT AX*/
  4.2922 +                        temp=FETCH();
  4.2923 +                        outb(temp,AL);
  4.2924 +                        outb(temp+1,AH);
  4.2925 +                        cycles-=14;
  4.2926 +                        break;
  4.2927 +
  4.2928 +                        case 0xE8: /*CALL rel 16*/
  4.2929 +                        tempw=getword();
  4.2930 +                        if (ssegs) ss=oldss;
  4.2931 +//                        writememb(ss+((SP-1)&0xFFFF),pc>>8);
  4.2932 +                        writememw(ss,((SP-2)&0xFFFF),pc);
  4.2933 +                        SP-=2;
  4.2934 +                        pc+=tempw;
  4.2935 +                        cycles-=23;
  4.2936 +                        FETCHCLEAR();
  4.2937 +                        break;
  4.2938 +                        case 0xE9: /*JMP rel 16*/
  4.2939 +//                        printf("PC was %04X\n",pc);
  4.2940 +                        pc+=getword();
  4.2941 +//                        printf("PC now %04X\n",pc);
  4.2942 +                        cycles-=15;
  4.2943 +                        FETCHCLEAR();
  4.2944 +                        break;
  4.2945 +                        case 0xEA: /*JMP far*/
  4.2946 +                        addr=getword();
  4.2947 +                        tempw=getword();
  4.2948 +                        pc=addr;
  4.2949 +//                        printf("EA\n");
  4.2950 +                        loadcs(tempw);
  4.2951 +//                        cs=loadcs(CS);
  4.2952 +//                        cs=CS<<4;
  4.2953 +                        cycles-=15;
  4.2954 +                        FETCHCLEAR();
  4.2955 +                        break;
  4.2956 +                        case 0xEB: /*JMP rel*/
  4.2957 +                        offset=(int8_t)FETCH();
  4.2958 +                        pc+=offset;
  4.2959 +                        cycles-=15;
  4.2960 +                        FETCHCLEAR();
  4.2961 +                        break;
  4.2962 +                        case 0xEC: /*IN AL,DX*/
  4.2963 +                        AL=inb(DX);
  4.2964 +                        cycles-=12;
  4.2965 +                        break;
  4.2966 +                        case 0xED: /*IN AX,DX*/
  4.2967 +                        AL=inb(DX);
  4.2968 +                        AH=inb(DX+1);
  4.2969 +                        cycles-=12;
  4.2970 +                        break;
  4.2971 +                        case 0xEE: /*OUT DX,AL*/
  4.2972 +                        outb(DX,AL);
  4.2973 +                        cycles-=12;
  4.2974 +                        break;
  4.2975 +                        case 0xEF: /*OUT DX,AX*/
  4.2976 +                        outb(DX,AL);
  4.2977 +                        outb(DX+1,AH);
  4.2978 +                        cycles-=12;
  4.2979 +                        break;
  4.2980 +
  4.2981 +                        case 0xF0: /*LOCK*/
  4.2982 +                        cycles-=4;
  4.2983 +                        break;
  4.2984 +
  4.2985 +                        case 0xF2: /*REPNE*/
  4.2986 +                        rep(0);
  4.2987 +                        break;
  4.2988 +                        case 0xF3: /*REPE*/
  4.2989 +                        rep(1);
  4.2990 +                        break;
  4.2991 +
  4.2992 +                        case 0xF4: /*HLT*/
  4.2993 +//                        printf("IN HLT!!!! %04X:%04X %08X %08X %08X\n",oldcs,oldpc,old8,old82,old83);
  4.2994 +/*                        if (!(flags & I_FLAG))
  4.2995 +                        {
  4.2996 +                                pclog("HLT\n");
  4.2997 +                                dumpregs();
  4.2998 +                                exit(-1);
  4.2999 +                        }*/
  4.3000 +                        inhlt=1;
  4.3001 +                        pc--;
  4.3002 +                        FETCHCLEAR();
  4.3003 +                        cycles-=2;
  4.3004 +                        break;
  4.3005 +                        case 0xF5: /*CMC*/
  4.3006 +                        flags^=C_FLAG;
  4.3007 +                        cycles-=2;
  4.3008 +                        break;
  4.3009 +
  4.3010 +                        case 0xF6:
  4.3011 +                        fetchea();
  4.3012 +                        temp=geteab();
  4.3013 +                        switch (rmdat&0x38)
  4.3014 +                        {
  4.3015 +                                case 0x00: /*TEST b,#8*/
  4.3016 +                                temp2=FETCH();
  4.3017 +                                temp&=temp2;
  4.3018 +                                setznp8(temp);
  4.3019 +                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.3020 +                                cycles-=((mod==3)?5:11);
  4.3021 +                                break;
  4.3022 +                                case 0x10: /*NOT b*/
  4.3023 +                                temp=~temp;
  4.3024 +                                seteab(temp);
  4.3025 +                                cycles-=((mod==3)?3:24);
  4.3026 +                                break;
  4.3027 +                                case 0x18: /*NEG b*/
  4.3028 +                                setsub8(0,temp);
  4.3029 +                                temp=0-temp;
  4.3030 +                                seteab(temp);
  4.3031 +                                cycles-=((mod==3)?3:24);
  4.3032 +                                break;
  4.3033 +                                case 0x20: /*MUL AL,b*/
  4.3034 +                                setznp8(AL);
  4.3035 +                                AX=AL*temp;
  4.3036 +                                if (AX) flags&=~Z_FLAG;
  4.3037 +                                else    flags|=Z_FLAG;
  4.3038 +                                if (AH) flags|=(C_FLAG|V_FLAG);
  4.3039 +                                else    flags&=~(C_FLAG|V_FLAG);
  4.3040 +                                cycles-=70;
  4.3041 +                                break;
  4.3042 +                                case 0x28: /*IMUL AL,b*/
  4.3043 +                                setznp8(AL);
  4.3044 +                                tempws=(int)((int8_t)AL)*(int)((int8_t)temp);
  4.3045 +                                AX=tempws&0xFFFF;
  4.3046 +                                if (AX) flags&=~Z_FLAG;
  4.3047 +                                else    flags|=Z_FLAG;
  4.3048 +                                if (AH) flags|=(C_FLAG|V_FLAG);
  4.3049 +                                else    flags&=~(C_FLAG|V_FLAG);
  4.3050 +                                cycles-=80;
  4.3051 +                                break;
  4.3052 +                                case 0x30: /*DIV AL,b*/
  4.3053 +                                tempw=AX;
  4.3054 +                                if (temp)
  4.3055 +                                {
  4.3056 +                                        tempw2=tempw%temp;
  4.3057 +/*                                        if (!tempw)
  4.3058 +                                        {
  4.3059 +                                                writememw((ss+SP)-2,flags|0xF000);
  4.3060 +                                                writememw((ss+SP)-4,cs>>4);
  4.3061 +                                                writememw((ss+SP)-6,pc);
  4.3062 +                                                SP-=6;
  4.3063 +                                                flags&=~I_FLAG;
  4.3064 +                                                pc=readmemw(0);
  4.3065 +                                                cs=readmemw(2)<<4;
  4.3066 +                                                printf("Div by zero %04X:%04X\n",cs>>4,pc);
  4.3067 +//                                                dumpregs();
  4.3068 +//                                                exit(-1);
  4.3069 +                                        }
  4.3070 +                                        else
  4.3071 +                                        {*/
  4.3072 +                                                AH=tempw2;
  4.3073 +                                                tempw/=temp;
  4.3074 +                                                AL=tempw&0xFF;
  4.3075 +//                                        }
  4.3076 +                                }
  4.3077 +                                else
  4.3078 +                                {
  4.3079 +                                        printf("DIVb BY 0 %04X:%04X\n",cs>>4,pc);
  4.3080 +                                        writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
  4.3081 +                                        writememw(ss,(SP-4)&0xFFFF,CS);
  4.3082 +                                        writememw(ss,(SP-6)&0xFFFF,pc);
  4.3083 +                                        SP-=6;
  4.3084 +                                        flags&=~I_FLAG;
  4.3085 +                                        flags&=~T_FLAG;
  4.3086 +                                        pc=readmemw(0,0);
  4.3087 +//                        printf("F6 30\n");
  4.3088 +                                        loadcs(readmemw(0,2));
  4.3089 +                                        FETCHCLEAR();
  4.3090 +//                                                cs=loadcs(CS);
  4.3091 +//                                                cs=CS<<4;
  4.3092 +//                                        printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x30);
  4.3093 +//                                        dumpregs();
  4.3094 +//                                        exit(-1);
  4.3095 +                                }
  4.3096 +                                cycles-=80;
  4.3097 +                                break;
  4.3098 +                                case 0x38: /*IDIV AL,b*/
  4.3099 +                                tempws=(int)AX;
  4.3100 +                                if (temp)
  4.3101 +                                {
  4.3102 +                                        tempw2=tempws%(int)((int8_t)temp);
  4.3103 +/*                                        if (!tempw)
  4.3104 +                                        {
  4.3105 +                                                writememw((ss+SP)-2,flags|0xF000);
  4.3106 +                                                writememw((ss+SP)-4,cs>>4);
  4.3107 +                                                writememw((ss+SP)-6,pc);
  4.3108 +                                                SP-=6;
  4.3109 +                                                flags&=~I_FLAG;
  4.3110 +                                                pc=readmemw(0);
  4.3111 +                                                cs=readmemw(2)<<4;
  4.3112 +                                                printf("Div by zero %04X:%04X\n",cs>>4,pc);
  4.3113 +                                        }
  4.3114 +                                        else
  4.3115 +                                        {*/
  4.3116 +                                                AH=tempw2&0xFF;
  4.3117 +                                                tempws/=(int)((int8_t)temp);
  4.3118 +                                                AL=tempws&0xFF;
  4.3119 +//                                        }
  4.3120 +                                }
  4.3121 +                                else
  4.3122 +                                {
  4.3123 +                                        printf("IDIVb BY 0 %04X:%04X\n",cs>>4,pc);
  4.3124 +                                        writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
  4.3125 +                                        writememw(ss,(SP-4)&0xFFFF,CS);
  4.3126 +                                        writememw(ss,(SP-6)&0xFFFF,pc);
  4.3127 +                                        SP-=6;
  4.3128 +                                        flags&=~I_FLAG;
  4.3129 +                                        flags&=~T_FLAG;
  4.3130 +                                        pc=readmemw(0,0);
  4.3131 +//                        printf("F6 38\n");
  4.3132 +                                        loadcs(readmemw(0,2));
  4.3133 +                                        FETCHCLEAR();
  4.3134 +//                                                cs=loadcs(CS);
  4.3135 +//                                                cs=CS<<4;
  4.3136 +//                                        printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x38);
  4.3137 +                                }
  4.3138 +                                cycles-=101;
  4.3139 +                                break;
  4.3140 +
  4.3141 +//                                default:
  4.3142 +//                                printf("Bad F6 opcode %02X\n",rmdat&0x38);
  4.3143 +//                                dumpregs();
  4.3144 +//                                exit(-1);
  4.3145 +                        }
  4.3146 +                        break;
  4.3147 +
  4.3148 +                        case 0xF7:
  4.3149 +                        fetchea();
  4.3150 +                        tempw=geteaw();
  4.3151 +                        switch (rmdat&0x38)
  4.3152 +                        {
  4.3153 +                                case 0x00: /*TEST w*/
  4.3154 +                                tempw2=getword();
  4.3155 +                                setznp16(tempw&tempw2);
  4.3156 +                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
  4.3157 +                                cycles-=((mod==3)?5:11);
  4.3158 +                                break;
  4.3159 +                                case 0x10: /*NOT w*/
  4.3160 +                                seteaw(~tempw);
  4.3161 +                                cycles-=((mod==3)?3:24);
  4.3162 +                                break;
  4.3163 +                                case 0x18: /*NEG w*/
  4.3164 +                                setsub16(0,tempw);
  4.3165 +                                tempw=0-tempw;
  4.3166 +                                seteaw(tempw);
  4.3167 +                                cycles-=((mod==3)?3:24);
  4.3168 +                                break;
  4.3169 +                                case 0x20: /*MUL AX,w*/
  4.3170 +                                setznp16(AX);
  4.3171 +                                templ=AX*tempw;
  4.3172 +//                                if (output) printf("%04X*%04X=%08X\n",AX,tempw,templ);
  4.3173 +                                AX=templ&0xFFFF;
  4.3174 +                                DX=templ>>16;
  4.3175 +                                if (AX|DX) flags&=~Z_FLAG;
  4.3176 +                                else       flags|=Z_FLAG;
  4.3177 +                                if (DX)    flags|=(C_FLAG|V_FLAG);
  4.3178 +                                else       flags&=~(C_FLAG|V_FLAG);
  4.3179 +                                cycles-=118;
  4.3180 +                                break;
  4.3181 +                                case 0x28: /*IMUL AX,w*/
  4.3182 +                                setznp16(AX);
  4.3183 +//                                printf("IMUL %i %i ",(int)((int16_t)AX),(int)((int16_t)tempw));
  4.3184 +                                tempws=(int)((int16_t)AX)*(int)((int16_t)tempw);
  4.3185 +                                if ((tempws>>15) && ((tempws>>15)!=-1)) flags|=(C_FLAG|V_FLAG);
  4.3186 +                                else                                    flags&=~(C_FLAG|V_FLAG);
  4.3187 +//                                printf("%i ",tempws);
  4.3188 +                                AX=tempws&0xFFFF;
  4.3189 +                                tempws=(uint16_t)(tempws>>16);
  4.3190 +                                DX=tempws&0xFFFF;
  4.3191 +//                                printf("%04X %04X\n",AX,DX);
  4.3192 +//                                dumpregs();
  4.3193 +//                                exit(-1);
  4.3194 +                                if (AX|DX) flags&=~Z_FLAG;
  4.3195 +                                else       flags|=Z_FLAG;
  4.3196 +                                cycles-=128;
  4.3197 +                                break;
  4.3198 +                                case 0x30: /*DIV AX,w*/
  4.3199 +                                templ=(DX<<16)|AX;
  4.3200 +//                                printf("DIV %08X/%04X\n",templ,tempw);
  4.3201 +                                if (tempw)
  4.3202 +                                {
  4.3203 +                                        tempw2=templ%tempw;
  4.3204 +                                        DX=tempw2;
  4.3205 +                                        templ/=tempw;
  4.3206 +                                        AX=templ&0xFFFF;
  4.3207 +                                }
  4.3208 +                                else
  4.3209 +                                {
  4.3210 +                                        printf("DIVw BY 0 %04X:%04X\n",cs>>4,pc);
  4.3211 +                                        writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
  4.3212 +                                        writememw(ss,(SP-4)&0xFFFF,CS);
  4.3213 +                                        writememw(ss,(SP-6)&0xFFFF,pc);
  4.3214 +                                        SP-=6;
  4.3215 +                                        flags&=~I_FLAG;
  4.3216 +                                        flags&=~T_FLAG;
  4.3217 +                                        pc=readmemw(0,0);
  4.3218 +//                        printf("F7 30\n");
  4.3219 +                                        loadcs(readmemw(0,2));
  4.3220 +                                        FETCHCLEAR();
  4.3221 +                                }
  4.3222 +                                cycles-=144;
  4.3223 +                                break;
  4.3224 +                                case 0x38: /*IDIV AX,w*/
  4.3225 +                                tempws=(int)((DX<<16)|AX);
  4.3226 +//                                printf("IDIV %i %i ",tempws,tempw);
  4.3227 +                                if (tempw)
  4.3228 +                                {
  4.3229 +                                        tempw2=tempws%(int)((int16_t)tempw);
  4.3230 +//                                        printf("%04X ",tempw2);
  4.3231 +                                                DX=tempw2;
  4.3232 +                                                tempws/=(int)((int16_t)tempw);
  4.3233 +                                                AX=tempws&0xFFFF;
  4.3234 +                                }
  4.3235 +                                else
  4.3236 +                                {
  4.3237 +                                        printf("IDIVw BY 0 %04X:%04X\n",cs>>4,pc);
  4.3238 +                                        writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
  4.3239 +                                        writememw(ss,(SP-4)&0xFFFF,CS);
  4.3240 +                                        writememw(ss,(SP-6)&0xFFFF,pc);
  4.3241 +                                        SP-=6;
  4.3242 +                                        flags&=~I_FLAG;
  4.3243 +                                        flags&=~T_FLAG;
  4.3244 +                                        pc=readmemw(0,0);
  4.3245 +//                        printf("F7 38\n");
  4.3246 +                                        loadcs(readmemw(0,2));
  4.3247 +                                        FETCHCLEAR();
  4.3248 +                                }
  4.3249 +                                cycles-=165;
  4.3250 +                                break;
  4.3251 +
  4.3252 +//                                default:
  4.3253 +//                                printf("Bad F7 opcode %02X\n",rmdat&0x38);
  4.3254 +//                                dumpregs();
  4.3255 +//                                exit(-1);
  4.3256 +                        }
  4.3257 +                        break;
  4.3258 +
  4.3259 +                        case 0xF8: /*CLC*/
  4.3260 +                        flags&=~C_FLAG;
  4.3261 +                        cycles-=2;
  4.3262 +                        break;
  4.3263 +                        case 0xF9: /*STC*/
  4.3264 +//                        printf("STC %04X\n",pc);
  4.3265 +                        flags|=C_FLAG;
  4.3266 +                        cycles-=2;
  4.3267 +                        break;
  4.3268 +                        case 0xFA: /*CLI*/
  4.3269 +                        flags&=~I_FLAG;
  4.3270 +//                        printf("CLI at %04X:%04X\n",cs>>4,pc);
  4.3271 +                        cycles-=3;
  4.3272 +                        break;
  4.3273 +                        case 0xFB: /*STI*/
  4.3274 +                        flags|=I_FLAG;
  4.3275 +//                        printf("STI at %04X:%04X\n",cs>>4,pc);
  4.3276 +                        cycles-=2;
  4.3277 +                        break;
  4.3278 +                        case 0xFC: /*CLD*/
  4.3279 +                        flags&=~D_FLAG;
  4.3280 +                        cycles-=2;
  4.3281 +                        break;
  4.3282 +                        case 0xFD: /*STD*/
  4.3283 +                        flags|=D_FLAG;
  4.3284 +                        cycles-=2;
  4.3285 +                        break;
  4.3286 +
  4.3287 +                        case 0xFE: /*INC/DEC b*/
  4.3288 +                        fetchea();
  4.3289 +                        temp=geteab();
  4.3290 +                        flags&=~V_FLAG;
  4.3291 +                        if (rmdat&0x38)
  4.3292 +                        {
  4.3293 +                                setsub8nc(temp,1);
  4.3294 +                                temp2=temp-1;
  4.3295 +                                if ((temp&0x80) && !(temp2&0x80)) flags|=V_FLAG;
  4.3296 +                        }
  4.3297 +                        else
  4.3298 +                        {
  4.3299 +                                setadd8nc(temp,1);
  4.3300 +                                temp2=temp+1;
  4.3301 +                                if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG;
  4.3302 +                        }
  4.3303 +//                        setznp8(temp2);
  4.3304 +                        seteab(temp2);
  4.3305 +                        cycles-=((mod==3)?3:23);
  4.3306 +                        break;
  4.3307 +
  4.3308 +                        case 0xFF:
  4.3309 +                        fetchea();
  4.3310 +                        switch (rmdat&0x38)
  4.3311 +                        {
  4.3312 +                                case 0x00: /*INC w*/
  4.3313 +                                tempw=geteaw();
  4.3314 +                                setadd16nc(tempw,1);
  4.3315 +//                                setznp16(tempw+1);
  4.3316 +                                seteaw(tempw+1);
  4.3317 +                                cycles-=((mod==3)?3:23);
  4.3318 +                                break;
  4.3319 +                                case 0x08: /*DEC w*/
  4.3320 +                                tempw=geteaw();
  4.3321 +//                                setsub16(tempw,1);
  4.3322 +                                setsub16nc(tempw,1);
  4.3323 +//                                setznp16(tempw-1);
  4.3324 +                                seteaw(tempw-1);
  4.3325 +//                                if (output) printf("DEC - %04X\n",tempw);
  4.3326 +                                cycles-=((mod==3)?3:23);
  4.3327 +                                break;
  4.3328 +                                case 0x10: /*CALL*/
  4.3329 +                                tempw=geteaw();
  4.3330 +                                if (ssegs) ss=oldss;
  4.3331 +                                writememw(ss,(SP-2)&0xFFFF,pc);
  4.3332 +                                SP-=2;
  4.3333 +                                pc=tempw;
  4.3334 +//                        printf("FF 10\n");
  4.3335 +                                cycles-=((mod==3)?20:29);
  4.3336 +                                FETCHCLEAR();
  4.3337 +                                break;
  4.3338 +                                case 0x18: /*CALL far*/
  4.3339 +                                tempw=readmemw(easeg,eaaddr);
  4.3340 +                                tempw2=readmemw(easeg,(eaaddr+2)&0xFFFF); //geteaw2();
  4.3341 +                                tempw3=CS;
  4.3342 +                                tempw4=pc;
  4.3343 +                                if (ssegs) ss=oldss;
  4.3344 +                                pc=tempw;
  4.3345 +//                        printf("FF 18\n");
  4.3346 +                                loadcs(tempw2);
  4.3347 +                                writememw(ss,(SP-2)&0xFFFF,tempw3);
  4.3348 +                                writememw(ss,((SP-4)&0xFFFF),tempw4);
  4.3349 +                                SP-=4;
  4.3350 +                                cycles-=53;
  4.3351 +                                FETCHCLEAR();
  4.3352 +                                break;
  4.3353 +                                case 0x20: /*JMP*/
  4.3354 +                                pc=geteaw();
  4.3355 +//                        printf("FF 20\n");
  4.3356 +                                cycles-=((mod==3)?11:18);
  4.3357 +                                FETCHCLEAR();
  4.3358 +                                break;
  4.3359 +                                case 0x28: /*JMP far*/
  4.3360 +                                pc=readmemw(easeg,eaaddr); //geteaw();
  4.3361 +//                        printf("FF 28\n");
  4.3362 +                                loadcs(readmemw(easeg,(eaaddr+2)&0xFFFF)); //geteaw2();
  4.3363 +//                                cs=loadcs(CS);
  4.3364 +//                                cs=CS<<4;
  4.3365 +                                cycles-=24;
  4.3366 +                                FETCHCLEAR();
  4.3367 +                                break;
  4.3368 +                                case 0x30: /*PUSH w*/
  4.3369 +                                tempw=geteaw();
  4.3370 +//                                if (output) printf("PUSH %04X %i %02X %04X %04X %02X %02X\n",tempw,rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]);
  4.3371 +                                if (ssegs) ss=oldss;
  4.3372 +                                writememw(ss,((SP-2)&0xFFFF),tempw);
  4.3373 +                                SP-=2;
  4.3374 +                                cycles-=((mod==3)?15:24);
  4.3375 +                                break;
  4.3376 +
  4.3377 +//                                default:
  4.3378 +//                                printf("Bad FF opcode %02X\n",rmdat&0x38);
  4.3379 +//                                dumpregs();
  4.3380 +//                                exit(-1);
  4.3381 +                        }
  4.3382 +                        break;
  4.3383 +
  4.3384 +                        default:
  4.3385 +                        FETCH();
  4.3386 +                        cycles-=8;
  4.3387 +                        break;
  4.3388 +
  4.3389 +/*                        printf("Bad opcode %02X at %04X:%04X from %04X:%04X %08X\n",opcode,cs>>4,pc,old8>>16,old8&0xFFFF,old82);
  4.3390 +                        dumpregs();
  4.3391 +                        exit(-1);*/
  4.3392 +                }
  4.3393 +                pc&=0xFFFF;
  4.3394 +
  4.3395 +/*                if ((CS & 0xf000) == 0xa000)
  4.3396 +                {
  4.3397 +                        dumpregs();
  4.3398 +                        exit(-1);
  4.3399 +                }*/
  4.3400 +//                output = 3;
  4.3401 +/*                if (CS == 0xf000)
  4.3402 +                {
  4.3403 +                        dumpregs();
  4.3404 +                        exit(-1);
  4.3405 +                }
  4.3406 +                output = 3;*/
  4.3407 +                if (ssegs)
  4.3408 +                {
  4.3409 +                        ds=oldds;
  4.3410 +                        ss=oldss;
  4.3411 +                        ssegs=0;
  4.3412 +                }
  4.3413 +                
  4.3414 +//                output = 3;
  4.3415 +               // if (instime) printf("%i %i %i %i\n",cycdiff,cycles,memcycs,fetchclocks);
  4.3416 +                FETCHADD(((cycdiff-cycles)-memcycs)-fetchclocks);
  4.3417 +                if ((cycdiff-cycles)<memcycs) cycles-=(memcycs-(cycdiff-cycles));
  4.3418 +                if (romset==ROM_IBMPC)
  4.3419 +                {
  4.3420 +                        if ((cs+pc)==0xFE4A7) /*You didn't seriously think I was going to emulate the cassette, did you?*/
  4.3421 +                        {
  4.3422 +                                CX=1;
  4.3423 +                                BX=0x500;
  4.3424 +                        }
  4.3425 +                }
  4.3426 +                memcycs=0;
  4.3427 +
  4.3428 +                insc++;
  4.3429 +//                output=(CS==0xEB9);
  4.3430 +                clockhardware();
  4.3431 +
  4.3432 +
  4.3433 +                if (trap && (flags&T_FLAG) && !noint)
  4.3434 +                {
  4.3435 +//                        printf("TRAP!!! %04X:%04X\n",CS,pc);
  4.3436 +                        writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
  4.3437 +                        writememw(ss,(SP-4)&0xFFFF,CS);
  4.3438 +                        writememw(ss,(SP-6)&0xFFFF,pc);
  4.3439 +                        SP-=6;
  4.3440 +                        addr=1<<2;
  4.3441 +                        flags&=~I_FLAG;
  4.3442 +                        flags&=~T_FLAG;
  4.3443 +                        pc=readmemw(0,addr);
  4.3444 +                        loadcs(readmemw(0,addr+2));
  4.3445 +                        FETCHCLEAR();
  4.3446 +                }
  4.3447 +                else if ((flags&I_FLAG) && (pic.pend&~pic.mask) && !ssegs && !noint)
  4.3448 +                {
  4.3449 +                        temp=picinterrupt();
  4.3450 +                        if (temp!=0xFF)
  4.3451 +                        {
  4.3452 +                                if (inhlt) pc++;
  4.3453 +                                writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
  4.3454 +                                writememw(ss,(SP-4)&0xFFFF,CS);
  4.3455 +                                writememw(ss,(SP-6)&0xFFFF,pc);
  4.3456 +                                SP-=6;
  4.3457 +                                addr=temp<<2;
  4.3458 +                                flags&=~I_FLAG;
  4.3459 +                                flags&=~T_FLAG;
  4.3460 +                                pc=readmemw(0,addr);
  4.3461 +//                        printf("INT INT INT\n");
  4.3462 +                                loadcs(readmemw(0,addr+2));
  4.3463 +                                FETCHCLEAR();
  4.3464 +//                                printf("INTERRUPT\n");
  4.3465 +                        }
  4.3466 +                }
  4.3467 +
  4.3468 +                if (noint) noint=0;
  4.3469 +                ins++;
  4.3470 +/*                if (timetolive)
  4.3471 +                {
  4.3472 +                        timetolive--;
  4.3473 +                        if (!timetolive) exit(-1); //output=0;
  4.3474 +                }*/
  4.3475 +        }
  4.3476 +}
  4.3477 +
     5.1 --- a/src/adlib.c	Mon May 27 17:46:42 2013 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,187 +0,0 @@
     5.4 -#include <stdint.h>
     5.5 -#include <stdlib.h>
     5.6 -#include "ibm.h"
     5.7 -#include "mame/fmopl.h"
     5.8 -#include "mame/ymf262.h"
     5.9 -
    5.10 -/*Interfaces between PCem and the actual Adlib emulator*/
    5.11 -
    5.12 -static int adlib_inited = 0;
    5.13 -int adlibpos=0;
    5.14 -void *YM3812[2];
    5.15 -void *YMF262;
    5.16 -int fm_timers[2][2],fm_timers_enable[2][2];
    5.17 -
    5.18 -void adlib_write(uint16_t a, uint8_t v)
    5.19 -{
    5.20 -//        printf("Adlib write %04X %02X %i\n",a,v,sbtype);
    5.21 -        if (!sbtype) return;
    5.22 -        if (sbtype<SBPRO && a<0x224) return;
    5.23 -        switch (a)
    5.24 -        {
    5.25 -                case 0x220: case 0x221:
    5.26 -                if (sbtype<SBPRO2) ym3812_write(YM3812[0],a,v);
    5.27 -                else               ymf262_write(YMF262,a,v);
    5.28 -                break;
    5.29 -                case 0x222: case 0x223:
    5.30 -                if (sbtype<SBPRO2) ym3812_write(YM3812[1],a,v);
    5.31 -                else               ymf262_write(YMF262,a,v);
    5.32 -                break;
    5.33 -                case 0x228: case 0x229: case 0x388: case 0x389:
    5.34 -                if (sbtype<SBPRO2)
    5.35 -                {
    5.36 -                        ym3812_write(YM3812[0],a,v);
    5.37 -                        ym3812_write(YM3812[1],a,v);
    5.38 -                }
    5.39 -                else
    5.40 -                        ymf262_write(YMF262,a,v);
    5.41 -                break;
    5.42 -        }
    5.43 -}
    5.44 -
    5.45 -uint8_t adlib_read(uint16_t a)
    5.46 -{
    5.47 -        uint8_t temp;
    5.48 -//        printf("Adlib read %04X\n",a);
    5.49 -        if (sbtype>=SBPRO2)
    5.50 -        {
    5.51 -                switch (a)
    5.52 -                {
    5.53 -                        case 0x220: case 0x221:
    5.54 -                        case 0x222: case 0x223:
    5.55 -                        case 0x228: case 0x229:
    5.56 -                        case 0x388: case 0x389:
    5.57 -                        temp=ymf262_read(YMF262,a);
    5.58 -//                        pclog("YMF262 read %03X %02X\n",a,temp);
    5.59 -                        cycles-=(int)(isa_timing * 8);
    5.60 -                        return temp;
    5.61 -                }
    5.62 -        }
    5.63 -        if (!sbtype) return 0xFF;
    5.64 -        switch (a)
    5.65 -        {
    5.66 -                case 0x220: case 0x221:
    5.67 -                if (sbtype<SBPRO) return 0xFF;
    5.68 -                case 0x228: case 0x229:
    5.69 -                case 0x388: case 0x389:
    5.70 -                cycles-=(int)(isa_timing * 8);
    5.71 -                return ym3812_read(YM3812[0],a);
    5.72 -                case 0x222: case 0x223:
    5.73 -                if (sbtype<SBPRO) return 0xFF;
    5.74 -                return ym3812_read(YM3812[1],a);
    5.75 -        }
    5.76 -/*        if (sbtype<SBPRO && a<0x224) return 0xFF;
    5.77 -        if (a==0x222) return adlibstat2;
    5.78 -        if (!(a&1)) return adlibstat;
    5.79 -        return 0;*/
    5.80 -}
    5.81 -
    5.82 -signed short *ad_bufs[4];
    5.83 -int16_t ad_filtbuf[2]={0,0};
    5.84 -void getadlib(signed short *bufl, signed short *bufr, int size)
    5.85 -{
    5.86 -        int c;
    5.87 -        if (sbtype>=SBPRO2)
    5.88 -        {
    5.89 -                ymf262_update_one(YMF262,ad_bufs,size);
    5.90 -                for (c=0;c<size;c++)
    5.91 -                {
    5.92 -                        ad_filtbuf[0]=bufl[c]=(ad_bufs[0][c]/4)+((ad_filtbuf[0]*11)/16);
    5.93 -                        ad_filtbuf[1]=bufr[c]=(ad_bufs[1][c]/4)+((ad_filtbuf[1]*11)/16);
    5.94 -                }
    5.95 -                if (fm_timers_enable[0][0])
    5.96 -                {
    5.97 -                        fm_timers[0][0]--;
    5.98 -                        if (fm_timers[0][0]<0) ymf262_timer_over(YMF262,0);
    5.99 -                }
   5.100 -                if (fm_timers_enable[0][1])
   5.101 -                {
   5.102 -                        fm_timers[0][1]--;
   5.103 -                        if (fm_timers[0][1]<0) ymf262_timer_over(YMF262,1);
   5.104 -                }
   5.105 -        }
   5.106 -        else
   5.107 -        {
   5.108 -                ym3812_update_one(YM3812[0],bufl,size);
   5.109 -                ym3812_update_one(YM3812[1],bufr,size);
   5.110 -                for (c=0;c<size;c++)
   5.111 -                {
   5.112 -                        ad_filtbuf[0]=bufl[c]=(bufl[c]/4)+((ad_filtbuf[0]*11)/16);
   5.113 -                        ad_filtbuf[1]=bufr[c]=(bufr[c]/4)+((ad_filtbuf[1]*11)/16);
   5.114 -                }
   5.115 -                if (fm_timers_enable[0][0])
   5.116 -                {
   5.117 -                        fm_timers[0][0]--;
   5.118 -                        if (fm_timers[0][0]<0) ym3812_timer_over(YM3812[0],0);
   5.119 -                }
   5.120 -                if (fm_timers_enable[0][1])
   5.121 -                {
   5.122 -                        fm_timers[0][1]--;
   5.123 -                        if (fm_timers[0][1]<0) ym3812_timer_over(YM3812[0],1);
   5.124 -                }
   5.125 -                if (fm_timers_enable[1][0])
   5.126 -                {
   5.127 -                        fm_timers[1][0]--;
   5.128 -                        if (fm_timers[1][0]<0) ym3812_timer_over(YM3812[1],0);
   5.129 -                }
   5.130 -                if (fm_timers_enable[1][1])
   5.131 -                {
   5.132 -                        fm_timers[1][1]--;
   5.133 -                        if (fm_timers[1][1]<0) ym3812_timer_over(YM3812[1],1);
   5.134 -                }
   5.135 -        }
   5.136 -//        for (c=0;c<size;c++) buf[c]/=2;
   5.137 -}
   5.138 -
   5.139 -void ym3812_timer_set_0(void *param,int timer,attotime period)
   5.140 -{
   5.141 -        fm_timers[0][timer]=period/20833;
   5.142 -        if (!fm_timers[0][timer]) fm_timers[0][timer]=1;
   5.143 -        fm_timers_enable[0][timer]=(period)?1:0;
   5.144 -}
   5.145 -void ym3812_timer_set_1(void *param,int timer,attotime period)
   5.146 -{
   5.147 -        fm_timers[1][timer]=period/20833;
   5.148 -        if (!fm_timers[1][timer]) fm_timers[1][timer]=1;
   5.149 -        fm_timers_enable[1][timer]=(period)?1:0;
   5.150 -}
   5.151 -
   5.152 -void ymf262_timer_set(void *param,int timer,attotime period)
   5.153 -{
   5.154 -        fm_timers[0][timer]=period/20833;
   5.155 -        if (!fm_timers[0][timer]) fm_timers[0][timer]=1;
   5.156 -        fm_timers_enable[0][timer]=(period)?1:0;
   5.157 -}
   5.158 -
   5.159 -void adlib_init()
   5.160 -{
   5.161 -        if (!adlib_inited)
   5.162 -        {
   5.163 -                ad_bufs[0]=(signed short *)malloc(48000);
   5.164 -                ad_bufs[1]=(signed short *)malloc(48000);
   5.165 -                ad_bufs[2]=(signed short *)malloc(48000);
   5.166 -                ad_bufs[3]=(signed short *)malloc(48000);
   5.167 -                
   5.168 -                YM3812[0]=ym3812_init((void *)NULL,3579545,48000);
   5.169 -                ym3812_reset_chip(YM3812[0]);
   5.170 -                ym3812_set_timer_handler(YM3812[0],ym3812_timer_set_0,NULL);
   5.171 -                YM3812[1]=ym3812_init((void *)NULL,3579545,48000);
   5.172 -                ym3812_reset_chip(YM3812[1]);
   5.173 -                ym3812_set_timer_handler(YM3812[1],ym3812_timer_set_1,NULL);
   5.174 -                
   5.175 -                YMF262=ymf262_init((void *)NULL,3579545*4,48000);
   5.176 -                ymf262_reset_chip(YMF262);
   5.177 -                ymf262_set_timer_handler(YMF262,ymf262_timer_set,NULL);
   5.178 -        }        
   5.179 -        
   5.180 -        adlib_inited = 1;
   5.181 -        
   5.182 -        io_sethandler(0x0388, 0x0002, adlib_read, NULL, NULL, adlib_write, NULL, NULL);
   5.183 -}
   5.184 -
   5.185 -void adlib_reset()
   5.186 -{
   5.187 -        ym3812_reset_chip(YM3812[0]);
   5.188 -        ym3812_reset_chip(YM3812[1]);
   5.189 -        ymf262_reset_chip(YMF262);
   5.190 -}
     6.1 --- a/src/cms.c	Mon May 27 17:46:42 2013 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,141 +0,0 @@
     6.4 -#include <stdio.h>
     6.5 -#include "ibm.h"
     6.6 -
     6.7 -int cmsaddrs[2];
     6.8 -uint8_t cmsregs[2][32];
     6.9 -uint16_t cmslatch[12],cmsnoisefreq[12];
    6.10 -int cmsfreq[12];
    6.11 -float cmscount[12];
    6.12 -int cmsvol[12][2];
    6.13 -int cmsstat[12];
    6.14 -uint16_t cmsnoise[4];
    6.15 -int cmsnoisecount[4];
    6.16 -int cmsnoisetype[4];
    6.17 -
    6.18 -#define CMSCONST (62500.0/44100.0)
    6.19 -
    6.20 -void getcms(signed short *p, int size)
    6.21 -{
    6.22 -        int c,d;
    6.23 -        int ena[12],noiseena[12];
    6.24 -        for (c=0;c<6;c++)
    6.25 -        {
    6.26 -                ena[c]=(cmsregs[0][0x14]&(1<<c));
    6.27 -                ena[c+6]=(cmsregs[1][0x14]&(1<<c));
    6.28 -        }
    6.29 -        if (!(cmsregs[0][0x1C]&1))
    6.30 -        {
    6.31 -                for (c=0;c<6;c++) ena[c]=0;
    6.32 -        }
    6.33 -        if (!(cmsregs[1][0x1C]&1))
    6.34 -        {
    6.35 -                for (c=0;c<6;c++) ena[c+6]=0;
    6.36 -        }
    6.37 -        for (c=0;c<6;c++)
    6.38 -        {
    6.39 -                noiseena[c]=(cmsregs[0][0x15]&(1<<c));
    6.40 -                noiseena[c+6]=(cmsregs[1][0x15]&(1<<c));
    6.41 -        }
    6.42 -        if (!(cmsregs[0][0x1C]&1))
    6.43 -        {
    6.44 -                for (c=0;c<6;c++) noiseena[c]=0;
    6.45 -        }
    6.46 -        if (!(cmsregs[1][0x1C]&1))
    6.47 -        {
    6.48 -                for (c=0;c<6;c++) noiseena[c+6]=0;
    6.49 -        }
    6.50 -        for (c=0;c<4;c++)
    6.51 -        {
    6.52 -                switch (cmsnoisetype[c])
    6.53 -                {
    6.54 -                        case 0: cmsnoisefreq[c]=31250; break;
    6.55 -                        case 1: cmsnoisefreq[c]=15625; break;
    6.56 -                        case 2: cmsnoisefreq[c]=7812; break;
    6.57 -                        case 3: cmsnoisefreq[c]=cmsfreq[c*3]; break;
    6.58 -                }
    6.59 -        }
    6.60 -        for (c=0;c<(size<<1);c+=2)
    6.61 -        {
    6.62 -                p[c]=0;
    6.63 -                p[c+1]=0;
    6.64 -                for (d=0;d<12;d++)
    6.65 -                {
    6.66 -                        if (ena[d])
    6.67 -                        {
    6.68 -                                if (cmsstat[d]) p[c]  +=(cmsvol[d][0]*90);
    6.69 -                                if (cmsstat[d]) p[c+1]+=(cmsvol[d][1]*90);
    6.70 -                                cmscount[d]+=cmsfreq[d];
    6.71 -                                if (cmscount[d]>=(22050))
    6.72 -                                {
    6.73 -                                        cmscount[d]-=(22050);
    6.74 -                                        cmsstat[d]^=1;
    6.75 -                                }
    6.76 -                        }
    6.77 -                        else if (noiseena[d])
    6.78 -                        {
    6.79 -                                if (cmsnoise[d/3]&1) p[c]  +=(cmsvol[d][0]*90);
    6.80 -                                if (cmsnoise[d/3]&1) p[c+1]+=(cmsvol[d][0]*90);
    6.81 -                        }
    6.82 -                }
    6.83 -                for (d=0;d<4;d++)
    6.84 -                {
    6.85 -                        cmsnoisecount[d]+=cmsnoisefreq[d];
    6.86 -                        while (cmsnoisecount[d]>=22050)
    6.87 -                        {
    6.88 -                                cmsnoisecount[d]-=22050;
    6.89 -                                cmsnoise[d]<<=1;
    6.90 -                                if (!(((cmsnoise[d]&0x4000)>>8)^(cmsnoise[d]&0x40))) cmsnoise[d]|=1;
    6.91 -                        }
    6.92 -                }
    6.93 -        }
    6.94 -}
    6.95 -
    6.96 -void writecms(uint16_t addr, uint8_t val)
    6.97 -{
    6.98 -        int voice;
    6.99 -        int chip=(addr&2)>>1;
   6.100 -        if (addr&1)
   6.101 -           cmsaddrs[chip]=val&31;
   6.102 -        else
   6.103 -        {
   6.104 -                cmsregs[chip][cmsaddrs[chip]&31]=val;
   6.105 -                switch (cmsaddrs[chip]&31)
   6.106 -                {
   6.107 -                        case 0x00: case 0x01: case 0x02: /*Volume*/
   6.108 -                        case 0x03: case 0x04: case 0x05:
   6.109 -                        voice=cmsaddrs[chip]&7;
   6.110 -                        if (chip) voice+=6;
   6.111 -                        cmsvol[voice][0]=val&0xF;//((val&0xF)+(val>>4))>>1;
   6.112 -                        cmsvol[voice][1]=val>>4;
   6.113 -                        break;
   6.114 -                        case 0x08: case 0x09: case 0x0A: /*Frequency*/
   6.115 -                        case 0x0B: case 0x0C: case 0x0D:
   6.116 -                        voice=cmsaddrs[chip]&7;
   6.117 -                        if (chip) voice+=6;
   6.118 -                        cmslatch[voice]=(cmslatch[voice]&0x700)|val;
   6.119 -                        cmsfreq[voice]=(15625<<(cmslatch[voice]>>8))/(511-(cmslatch[voice]&255));
   6.120 -                        break;
   6.121 -                        case 0x10: case 0x11: case 0x12: /*Octave*/
   6.122 -                        voice=(cmsaddrs[chip]&3)<<1;
   6.123 -                        if (chip) voice+=6;
   6.124 -                        cmslatch[voice]=(cmslatch[voice]&0xFF)|((val&7)<<8);
   6.125 -                        cmslatch[voice+1]=(cmslatch[voice+1]&0xFF)|((val&0x70)<<4);
   6.126 -                        cmsfreq[voice]=(15625<<(cmslatch[voice]>>8))/(511-(cmslatch[voice]&255));
   6.127 -                        cmsfreq[voice+1]=(15625<<(cmslatch[voice+1]>>8))/(511-(cmslatch[voice+1]&255));
   6.128 -                        break;
   6.129 -                        case 0x16: /*Noise*/
   6.130 -                        voice=chip*2;
   6.131 -                        cmsnoisetype[voice]=val&3;
   6.132 -                        cmsnoisetype[voice+1]=(val>>4)&3;
   6.133 -                        break;
   6.134 -                }
   6.135 -        }
   6.136 -}
   6.137 -
   6.138 -uint8_t readcms(uint16_t addr)
   6.139 -{
   6.140 -        int chip=(addr&2)>>1;
   6.141 -        if (addr&1) return cmsaddrs[chip];
   6.142 -        return cmsregs[chip][cmsaddrs[chip]&31];
   6.143 -}
   6.144 -
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/device.c	Mon May 27 19:56:33 2013 +0100
     7.3 @@ -0,0 +1,59 @@
     7.4 +#include "ibm.h"
     7.5 +#include "device.h"
     7.6 +
     7.7 +static void *device_priv[256];
     7.8 +static device_t *devices[256];
     7.9 +
    7.10 +void device_init()
    7.11 +{
    7.12 +        memset(devices, 0, sizeof(devices));
    7.13 +}
    7.14 +
    7.15 +void device_add(device_t *d)
    7.16 +{
    7.17 +        int c = 0;
    7.18 +        void *priv;
    7.19 +        
    7.20 +        while (devices[c] != NULL && c < 256)
    7.21 +                c++;
    7.22 +        
    7.23 +        if (c >= 256)
    7.24 +                fatal("device_add : too many devices\n");
    7.25 +        
    7.26 +        priv = d->init();
    7.27 +        if (priv == NULL)
    7.28 +                fatal("device_add : device init failed\n");
    7.29 +        
    7.30 +        devices[c] = d;
    7.31 +        device_priv[c] = priv;        
    7.32 +}
    7.33 +
    7.34 +void device_close_all()
    7.35 +{
    7.36 +        int c;
    7.37 +        
    7.38 +        for (c = 0; c < 256; c++)
    7.39 +        {
    7.40 +                if (devices[c] != NULL)
    7.41 +                {
    7.42 +                        devices[c]->close(device_priv[c]);
    7.43 +                        devices[c] = device_priv[c] = NULL;
    7.44 +                }
    7.45 +        }
    7.46 +}
    7.47 +
    7.48 +void device_speed_changed()
    7.49 +{
    7.50 +        int c;
    7.51 +        
    7.52 +        for (c = 0; c < 256; c++)
    7.53 +        {
    7.54 +                if (devices[c] != NULL)
    7.55 +                {
    7.56 +                        if (devices[c]->speed_changed != NULL)
    7.57 +                        {
    7.58 +                                devices[c]->speed_changed(device_priv[c]);
    7.59 +                        }
    7.60 +                }
    7.61 +        }
    7.62 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/device.h	Mon May 27 19:56:33 2013 +0100
     8.3 @@ -0,0 +1,12 @@
     8.4 +typedef struct device_t
     8.5 +{
     8.6 +        char name[50];
     8.7 +        void *(*init)();
     8.8 +        void (*close)(void *priv);
     8.9 +        void (*speed_changed)(void *priv);
    8.10 +} device_t;
    8.11 +
    8.12 +void device_init();
    8.13 +void device_add(device_t *d);
    8.14 +void device_close_all();
    8.15 +void device_speed_changed();
     9.1 --- a/src/gus.c	Mon May 27 17:46:42 2013 +0100
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,625 +0,0 @@
     9.4 -#include <stdio.h>
     9.5 -#include <stdlib.h>
     9.6 -#include <string.h>
     9.7 -#include "ibm.h"
     9.8 -
     9.9 -extern int ins;
    9.10 -extern int timetolive;
    9.11 -int output;
    9.12 -//#define GUSRATECONST (44100.0/48000.0)
    9.13 -uint8_t *gusram;
    9.14 -
    9.15 -struct
    9.16 -{
    9.17 -        int global;
    9.18 -        uint32_t addr,dmaaddr;
    9.19 -        int voice;
    9.20 -        uint32_t start[32],end[32],cur[32];
    9.21 -        uint32_t startx[32],endx[32],curx[32];
    9.22 -        uint32_t rstart[32],rend[32],rcur[32];
    9.23 -        uint16_t freq[32];
    9.24 -        uint16_t rfreq[32];
    9.25 -        uint8_t ctrl[32];
    9.26 -        uint8_t rctrl[32];
    9.27 -        int curvol[32];
    9.28 -        int t1on,t2on;
    9.29 -        uint8_t tctrl;
    9.30 -        uint16_t t1,t2,t1l,t2l;
    9.31 -        uint8_t irqstatus,irqstatus2;
    9.32 -        uint8_t adcommand;
    9.33 -        int waveirqs[32],rampirqs[32];
    9.34 -        int voices;
    9.35 -        uint8_t dmactrl;
    9.36 -} gus;
    9.37 -
    9.38 -double vol16bit[4096];
    9.39 -
    9.40 -void initgus()
    9.41 -{
    9.42 -        int c;
    9.43 -        for (c=0;c<32;c++)
    9.44 -        {
    9.45 -                gus.ctrl[c]=1;
    9.46 -                gus.rctrl[c]=1;
    9.47 -                gus.rfreq[c]=63*512;
    9.48 -        }
    9.49 -        gusram=malloc(1024*1024);
    9.50 -
    9.51 -	double out = 1.0;
    9.52 -	for (c=4095;c>=0;c--) {
    9.53 -		vol16bit[c]=out;//(float)c/4095.0;//out;
    9.54 -		out/=1.002709201;		/* 0.0235 dB Steps */
    9.55 -	}
    9.56 -
    9.57 -	printf("Top volume %f %f %f %f\n",vol16bit[4095],vol16bit[3800],vol16bit[3000],vol16bit[2048]);
    9.58 -	gus.voices=14;
    9.59 -
    9.60 -}
    9.61 -
    9.62 -void dumpgus()
    9.63 -{
    9.64 -/*        FILE *f=fopen("gusram.dmp","wb");
    9.65 -        fwrite(gusram,1024*1024,1,f);
    9.66 -        fclose(f);*/
    9.67 -}
    9.68 -
    9.69 -void pollgusirqs()
    9.70 -{
    9.71 -        int c;
    9.72 -        gus.irqstatus&=~0x60;
    9.73 -        for (c=0;c<32;c++)
    9.74 -        {
    9.75 -                if (gus.waveirqs[c])
    9.76 -                {
    9.77 -//                        gus.waveirqs[c]=0;
    9.78 -                        gus.irqstatus2=0x60|c;
    9.79 -                        gus.irqstatus|=0x20;
    9.80 -//                        printf("Voice IRQ %i %02X %i\n",c,gus.irqstatus2,ins);
    9.81 -                        picintlevel(0x20);
    9.82 -//                        output=3;
    9.83 -//                        timetolive=5000;
    9.84 -                        return;
    9.85 -                }
    9.86 -                if (gus.rampirqs[c])
    9.87 -                {
    9.88 -//                        gus.rampirqs[c]=0;
    9.89 -                        gus.irqstatus2=0xA0|c;
    9.90 -                        gus.irqstatus|=0x40;
    9.91 -//                        printf("Ramp IRQ %i %02X %i\n",c,gus.irqstatus2,ins);
    9.92 -                        picintlevel(0x20);
    9.93 -                        return;
    9.94 -                }
    9.95 -        }
    9.96 -        gus.irqstatus2=0xE0;
    9.97 -//        gus.irqstatus&=~0x20;
    9.98 -        if (!gus.irqstatus) picintc(0x20);
    9.99 -}
   9.100 -
   9.101 -int gusirqnext=0;
   9.102 -
   9.103 -void writegus(uint16_t addr, uint8_t val)
   9.104 -{
   9.105 -        int c,d;
   9.106 -//        printf("Write GUS %04X %02X %04X:%04X\n",addr,val,CS,pc);
   9.107 -        switch (addr)
   9.108 -        {
   9.109 -                case 0x342: /*Voice select*/
   9.110 -                gus.voice=val&31;
   9.111 -                break;
   9.112 -                case 0x343: /*Global select*/
   9.113 -                gus.global=val;
   9.114 -                break;
   9.115 -                case 0x344: /*Global low*/
   9.116 -//                if (gus.global!=0x43 && gus.global!=0x44) printf("Writing register %02X %02X %02X\n",gus.global,gus.voice,val);
   9.117 -                switch (gus.global)
   9.118 -                {
   9.119 -                        case 0: /*Voice control*/
   9.120 -//                        if (val&1 && !(gus.ctrl[gus.voice]&1)) printf("Voice on %i\n",gus.voice);
   9.121 -                        gus.ctrl[gus.voice]=val;
   9.122 -                        break;
   9.123 -                        case 1: /*Frequency control*/
   9.124 -                        gus.freq[gus.voice]=(gus.freq[gus.voice]&0xFF00)|val;
   9.125 -                        break;
   9.126 -                        case 2: /*Start addr high*/
   9.127 -                        gus.startx[gus.voice]=(gus.startx[gus.voice]&0xF807F)|(val<<7);
   9.128 -                        gus.start[gus.voice]=(gus.start[gus.voice]&0x1F00FFFF)|(val<<16);
   9.129 -//                        printf("Write %i start %08X %08X\n",gus.voice,gus.start[gus.voice],gus.startx[gus.voice]);
   9.130 -                        break;
   9.131 -                        case 3: /*Start addr low*/
   9.132 -                        gus.start[gus.voice]=(gus.start[gus.voice]&0x1FFFFF00)|val;
   9.133 -//                        printf("Write %i start %08X %08X\n",gus.voice,gus.start[gus.voice],gus.startx[gus.voice]);
   9.134 -                        break;
   9.135 -                        case 4: /*End addr high*/
   9.136 -                        gus.endx[gus.voice]=(gus.endx[gus.voice]&0xF807F)|(val<<7);
   9.137 -                        gus.end[gus.voice]=(gus.end[gus.voice]&0x1F00FFFF)|(val<<16);
   9.138 -//                        printf("Write %i end %08X %08X\n",gus.voice,gus.end[gus.voice],gus.endx[gus.voice]);
   9.139 -                        break;
   9.140 -                        case 5: /*End addr low*/
   9.141 -                        gus.end[gus.voice]=(gus.end[gus.voice]&0x1FFFFF00)|val;
   9.142 -//                        printf("Write %i end %08X %08X\n",gus.voice,gus.end[gus.voice],gus.endx[gus.voice]);
   9.143 -                        break;
   9.144 -
   9.145 -                        case 0x6: /*Ramp frequency*/
   9.146 -                        gus.rfreq[gus.voice] = (int)( (double)((val & 63)*512)/(double)(1 << (3*(val >> 6))));
   9.147 -//                        printf("RFREQ %02X %i %i %f\n",val,gus.voice,gus.rfreq[gus.voice],(double)(val & 63)/(double)(1 << (3*(val >> 6))));
   9.148 -                        break;
   9.149 -
   9.150 -                        case 0x9: /*Current volume*/
   9.151 -                        gus.curvol[gus.voice]=gus.rcur[gus.voice]=(gus.rcur[gus.voice]&0x1FE0000)|(val<<9);
   9.152 -//                        printf("Vol %i is %04X\n",gus.voice,gus.curvol[gus.voice]);
   9.153 -                        break;
   9.154 -
   9.155 -                        case 0xA: /*Current addr high*/
   9.156 -                        gus.cur[gus.voice]=(gus.cur[gus.voice]&0x1F00FFFF)|(val<<16);
   9.157 -gus.curx[gus.voice]=(gus.curx[gus.voice]&0xF807F00)|((val<<7)<<8);
   9.158 -//                      gus.cur[gus.voice]=(gus.cur[gus.voice]&0x0F807F00)|((val<<7)<<8);
   9.159 -//                        printf("Write %i cur %08X\n",gus.voice,gus.cur[gus.voice],gus.curx[gus.voice]);
   9.160 -                        break;
   9.161 -                        case 0xB: /*Current addr low*/
   9.162 -                        gus.cur[gus.voice]=(gus.cur[gus.voice]&0x1FFFFF00)|val;
   9.163 -//                        printf("Write %i cur %08X\n",gus.voice,gus.cur[gus.voice],gus.curx[gus.voice]);
   9.164 -                        break;
   9.165 -
   9.166 -                        case 0x42: /*DMA address low*/
   9.167 -                        gus.dmaaddr=(gus.dmaaddr&0xFF000)|(val<<4);
   9.168 -                        break;
   9.169 -
   9.170 -                        case 0x43: /*Address low*/
   9.171 -                        gus.addr=(gus.addr&0xFFF00)|val;
   9.172 -                        break;
   9.173 -                        case 0x45: /*Timer control*/
   9.174 -//                        printf("Timer control %02X\n",val);
   9.175 -                        gus.tctrl=val;
   9.176 -                        break;
   9.177 -                }
   9.178 -                break;
   9.179 -                case 0x345: /*Global high*/
   9.180 -//                if (gus.global!=0x43 && gus.global!=0x44) printf("HWriting register %02X %02X %02X %04X:%04X\n",gus.global,gus.voice,val,CS,pc);
   9.181 -                switch (gus.global)
   9.182 -                {
   9.183 -                        case 0: /*Voice control*/
   9.184 -                        if (!(val&1) && gus.ctrl[gus.voice]&1)
   9.185 -                        {
   9.186 -//                                printf("Voice on %i - start %05X end %05X freq %04X\n",gus.voice,gus.start[gus.voice],gus.end[gus.voice],gus.freq[gus.voice]);
   9.187 -//                                if (val&0x40) gus.cur[gus.voice]=gus.end[gus.voice]<<8;
   9.188 -//                                else          gus.cur[gus.voice]=gus.start[gus.voice]<<8;
   9.189 -                        }
   9.190 -                        if (val&2) val|=1;
   9.191 -                        gus.waveirqs[gus.voice]=val&0x80;
   9.192 -                        gus.ctrl[gus.voice]=val&0x7F;
   9.193 -                        pollgusirqs();
   9.194 -                        break;
   9.195 -                        case 1: /*Frequency control*/
   9.196 -                        gus.freq[gus.voice]=(gus.freq[gus.voice]&0xFF)|(val<<8);
   9.197 -                        break;
   9.198 -                        case 2: /*Start addr high*/
   9.199 -                        gus.startx[gus.voice]=(gus.startx[gus.voice]&0x07FFF)|(val<<15);
   9.200 -                        gus.start[gus.voice]=(gus.start[gus.voice]&0x00FFFFFF)|((val&0x1F)<<24);
   9.201 -//                        printf("Write %i start %08X %08X %02X\n",gus.voice,gus.start[gus.voice],gus.startx[gus.voice],val);
   9.202 -                        break;
   9.203 -                        case 3: /*Start addr low*/
   9.204 -                        gus.startx[gus.voice]=(gus.startx[gus.voice]&0xFFF80)|(val&0x7F);
   9.205 -                        gus.start[gus.voice]=(gus.start[gus.voice]&0x1FFF00FF)|(val<<8);
   9.206 -//                        printf("Write %i start %08X %08X\n",gus.voice,gus.start[gus.voice],gus.startx[gus.voice]);
   9.207 -                        break;
   9.208 -                        case 4: /*End addr high*/
   9.209 -                        gus.endx[gus.voice]=(gus.endx[gus.voice]&0x07FFF)|(val<<15);
   9.210 -                        gus.end[gus.voice]=(gus.end[gus.voice]&0x00FFFFFF)|((val&0x1F)<<24);
   9.211 -//                        printf("Write %i end %08X %08X %02X\n",gus.voice,gus.end[gus.voice],gus.endx[gus.voice],val);
   9.212 -                        break;
   9.213 -                        case 5: /*End addr low*/
   9.214 -                        gus.endx[gus.voice]=(gus.endx[gus.voice]&0xFFF80)|(val&0x7F);
   9.215 -                        gus.end[gus.voice]=(gus.end[gus.voice]&0x1FFF00FF)|(val<<8);
   9.216 -//                        printf("Write %i end %08X %08X\n",gus.voice,gus.end[gus.voice],gus.endx[gus.voice]);
   9.217 -                        break;
   9.218 -
   9.219 -                        case 0x6: /*Ramp frequency*/
   9.220 -                        gus.rfreq[gus.voice] = (int)( (double)((val & 63)*512)/(double)(1 << (3*(val >> 6))));
   9.221 -//                        printf("RFREQ %02X %i %i %f %i\n",val,gus.voice,gus.rfreq[gus.voice],(double)(val & 63)/(double)(1 << (3*(val >> 6))),ins);
   9.222 -                        break;
   9.223 -                        case 0x7: /*Ramp start*/
   9.224 -                        gus.rstart[gus.voice]=val<<17;
   9.225 -                        break;
   9.226 -                        case 0x8: /*Ramp end*/
   9.227 -                        gus.rend[gus.voice]=val<<17;
   9.228 -                        break;
   9.229 -                        case 0x9: /*Current volume*/
   9.230 -                        gus.curvol[gus.voice]=gus.rcur[gus.voice]=(gus.rcur[gus.voice]&0x1FE00)|(val<<17);
   9.231 -//                        printf("Vol %i is %04X\n",gus.voice,gus.curvol[gus.voice]);
   9.232 -                        break;
   9.233 -
   9.234 -                        case 0xA: /*Current addr high*/
   9.235 -                        gus.cur[gus.voice]=(gus.cur[gus.voice]&0x00FFFFFF)|((val&0x1F)<<24);
   9.236 -gus.curx[gus.voice]=(gus.curx[gus.voice]&0x07FFF00)|((val<<15)<<8);
   9.237 -//                        printf("Write %i cur %08X %08X %02X\n",gus.voice,gus.cur[gus.voice],gus.curx[gus.voice],val);
   9.238 -//                      gus.cur[gus.voice]=(gus.cur[gus.voice]&0x007FFF00)|((val<<15)<<8);
   9.239 -                        break;
   9.240 -                        case 0xB: /*Current addr low*/
   9.241 -                        gus.cur[gus.voice]=(gus.cur[gus.voice]&0x1FFF00FF)|(val<<8);
   9.242 -gus.curx[gus.voice]=(gus.curx[gus.voice]&0xFFF8000)|((val&0x7F)<<8);
   9.243 -//                      gus.cur[gus.voice]=(gus.cur[gus.voice]&0x0FFF8000)|((val&0x7F)<<8);
   9.244 -//                        printf("Write %i cur %08X %08X\n",gus.voice,gus.cur[gus.voice],gus.curx[gus.voice]);
   9.245 -                        break;
   9.246 -                        case 0xD: /*Ramp control*/
   9.247 -                        if (val&2) val|=1;
   9.248 -                        gus.rampirqs[gus.voice]=val&0x80;
   9.249 -                        gus.rctrl[gus.voice]=val&0x7F;
   9.250 -                        pollgusirqs();
   9.251 -//                        printf("Ramp control %02i %02X %02X %i\n",gus.voice,val,gus.rampirqs[gus.voice],ins);
   9.252 -                        break;
   9.253 -
   9.254 -                        case 0xE:
   9.255 -                        gus.voices=(val&63)+1;
   9.256 -                        if (gus.voices>32) gus.voices=32;
   9.257 -                        if (gus.voices<14) gus.voices=14;
   9.258 -                        gus.global=val;
   9.259 -//                        printf("GUS voices %i\n",val&31);
   9.260 -                        break;
   9.261 -
   9.262 -                        case 0x41: /*DMA*/
   9.263 -                        if (val&1)
   9.264 -                        {
   9.265 -//                                printf("DMA start! %05X %02X\n",gus.dmaaddr,val);
   9.266 -                                c=0;
   9.267 -                                while (c<65536)
   9.268 -                                {
   9.269 -                                        d=readdma3();
   9.270 -                                        if (d==-1) break;
   9.271 -                                        if (val&0x80) d^=0x80;
   9.272 -                                        gusram[gus.dmaaddr]=d;
   9.273 -                                        gus.dmaaddr++;
   9.274 -                                        gus.dmaaddr&=0xFFFFF;
   9.275 -                                        c++;
   9.276 -                                }
   9.277 -//                                printf("Transferred %i bytes\n",c);
   9.278 -                                gus.dmactrl=val&~0x40;
   9.279 -                                if (val&0x20) gusirqnext=1;
   9.280 -//                                exit(-1);
   9.281 -                        }
   9.282 -                        break;
   9.283 -
   9.284 -                        case 0x42: /*DMA address low*/
   9.285 -                        gus.dmaaddr=(gus.dmaaddr&0xFF0)|(val<<12);
   9.286 -                        break;
   9.287 -
   9.288 -                        case 0x43: /*Address low*/
   9.289 -                        gus.addr=(gus.addr&0xF00FF)|(val<<8);
   9.290 -                        break;
   9.291 -                        case 0x44: /*Address high*/
   9.292 -                        gus.addr=(gus.addr&0xFFFF)|((val<<16)&0xF0000);
   9.293 -                        break;
   9.294 -                        case 0x45: /*Timer control*/
   9.295 -                        if (!(val&4)) gus.irqstatus&=~4;
   9.296 -                        if (!(val&8)) gus.irqstatus&=~8;
   9.297 -//                        printf("Timer control %02X\n",val);
   9.298 -/*                        if ((val&4) && !(gus.tctrl&4))
   9.299 -                        {
   9.300 -                                gus.t1=gus.t1l;
   9.301 -                                gus.t1on=1;
   9.302 -                        }*/
   9.303 -                        gus.tctrl=val;
   9.304 -                        break;
   9.305 -                        case 0x46: /*Timer 1*/
   9.306 -                        gus.t1=gus.t1l=val;
   9.307 -                        gus.t1on=1;
   9.308 -//                        printf("GUS timer 1 %i\n",val);
   9.309 -                        break;
   9.310 -                        case 0x47: /*Timer 2*/
   9.311 -                        gus.t2=gus.t2l=val<<2;
   9.312 -                        gus.t2on=1;
   9.313 -//                        printf("GUS timer 2 %i\n",val);
   9.314 -                        break;
   9.315 -                }
   9.316 -                break;
   9.317 -                case 0x347: /*DRAM access*/
   9.318 -                gusram[gus.addr]=val;
   9.319 -//                pclog("GUS RAM write %05X %02X\n",gus.addr,val);
   9.320 -                gus.addr&=0xFFFFF;
   9.321 -                break;
   9.322 -                case 0x248: case 0x388: gus.adcommand=val; break;
   9.323 -        }
   9.324 -}
   9.325 -
   9.326 -uint8_t readgus(uint16_t addr)
   9.327 -{
   9.328 -        uint8_t val;
   9.329 -//        /*if (addr!=0x246) */printf("Read GUS %04X %04X(%06X):%04X %02X\n",addr,CS,cs,pc,gus.global);
   9.330 -//        output=3;
   9.331 -        switch (addr)
   9.332 -        {
   9.333 -                case 0x240: return 0;
   9.334 -                case 0x246: /*IRQ status*/
   9.335 -                val=gus.irqstatus;
   9.336 -//                printf("246 status %02X\n",val);
   9.337 -//                gus.irqstatus=0;
   9.338 -//                if (gus.irqstatus2==0xE0) picintc(0x20);
   9.339 -                return val;
   9.340 -                case 0x24A:
   9.341 -                return gus.adcommand;
   9.342 -                case 0x24B: case 0x24F: return 0;
   9.343 -                case 0x340: /*MIDI status*/
   9.344 -                case 0x341: /*MIDI data*/
   9.345 -                return 0;
   9.346 -                case 0x342: return gus.voice;
   9.347 -                case 0x343: return gus.global;
   9.348 -                case 0x344: /*Global low*/
   9.349 -//                /*if (gus.global!=0x43 && gus.global!=0x44) */printf("Reading register %02X %02X\n",gus.global,gus.voice);
   9.350 -                switch (gus.global)
   9.351 -                {
   9.352 -                        case 0x82: /*Start addr high*/
   9.353 -                        return gus.start[gus.voice]>>16;
   9.354 -                        case 0x83: /*Start addr low*/
   9.355 -                        return gus.start[gus.voice]&0xFF;
   9.356 -
   9.357 -                        case 0x89: /*Current volume*/
   9.358 -                        return gus.rcur[gus.voice]>>9;
   9.359 -                        case 0x8A: /*Current addr high*/
   9.360 -                        return gus.cur[gus.voice]>>16;
   9.361 -                        case 0x8B: /*Current addr low*/
   9.362 -                        return gus.cur[gus.voice]&0xFF;
   9.363 -
   9.364 -                        case 0x8F: /*IRQ status*/
   9.365 -                        val=gus.irqstatus2;
   9.366 -//                        pclog("Read IRQ status - %02X\n",val);
   9.367 -                        gus.rampirqs[gus.irqstatus2&0x1F]=0;
   9.368 -                        gus.waveirqs[gus.irqstatus2&0x1F]=0;
   9.369 -                        pollgusirqs();
   9.370 -                        return val;
   9.371 -                }
   9.372 -                //fatal("Bad GUS global low read %02X\n",gus.global);
   9.373 -                break;
   9.374 -                case 0x345: /*Global high*/
   9.375 -//                /*if (gus.global!=0x43 && gus.global!=0x44) */printf("HReading register %02X %02X\n",gus.global,gus.voice);
   9.376 -                switch (gus.global)
   9.377 -                {
   9.378 -                        case 0x80: /*Voice control*/
   9.379 -                        return gus.ctrl[gus.voice]|(gus.waveirqs[gus.voice]?0x80:0);
   9.380 -
   9.381 -                        case 0x82: /*Start addr high*/
   9.382 -                        return gus.start[gus.voice]>>24;
   9.383 -                        case 0x83: /*Start addr low*/
   9.384 -                        return gus.start[gus.voice]>>8;
   9.385 -
   9.386 -                        case 0x89: /*Current volume*/
   9.387 -                        return gus.rcur[gus.voice]>>17;
   9.388 -
   9.389 -                        case 0x8A: /*Current addr high*/
   9.390 -                        return gus.cur[gus.voice]>>24;
   9.391 -                        case 0x8B: /*Current addr low*/
   9.392 -                        return gus.cur[gus.voice]>>8;
   9.393 -
   9.394 -                        case 0x8D:
   9.395 -//                                pclog("Read ramp control %02X %08X %08X  %08X %08X\n",gus.rctrl[gus.voice]|(gus.rampirqs[gus.voice]?0x80:0),gus.rcur[gus.voice],gus.rfreq[gus.voice],gus.rstart[gus.voice],gus.rend[gus.voice]);
   9.396 -                        return gus.rctrl[gus.voice]|(gus.rampirqs[gus.voice]?0x80:0);
   9.397 -
   9.398 -                        case 0x8F: /*IRQ status*/
   9.399 -                        val=gus.irqstatus2;
   9.400 -//                        pclog("Read IRQ status - %02X\n",val);
   9.401 -                        gus.rampirqs[gus.irqstatus2&0x1F]=0;
   9.402 -                        gus.waveirqs[gus.irqstatus2&0x1F]=0;
   9.403 -                        pollgusirqs();
   9.404 -                        return val;
   9.405 -
   9.406 -                        case 0x41: /*DMA control*/
   9.407 -                        val=gus.dmactrl|((gus.irqstatus&0x80)?0x40:0);
   9.408 -                        gus.irqstatus&=~0x80;
   9.409 -                        return val;
   9.410 -                        case 0x45: /*Timer control*/
   9.411 -                        return gus.tctrl;
   9.412 -                        case 0x49: /*Sampling control*/
   9.413 -                        return 0;
   9.414 -                }
   9.415 -                //fatal("Bad GUS global high read %02X\n",gus.global);
   9.416 -                break;
   9.417 -                case 0x346: return 0;
   9.418 -                case 0x347: /*DRAM access*/
   9.419 -                val=gusram[gus.addr];
   9.420 -//                pclog("GUS RAM read %05X %02X\n",gus.addr,val);
   9.421 -//                output=3;
   9.422 -                gus.addr&=0xFFFFF;
   9.423 -                return val;
   9.424 -                case 0x349: return 0;
   9.425 -        }
   9.426 -//        printf("Bad GUS read %04X! %02X\n",addr,gus.global);
   9.427 -//        exit(-1);
   9.428 -        return 0;
   9.429 -}
   9.430 -
   9.431 -void pollgus()
   9.432 -{
   9.433 -        if (gus.t1on)
   9.434 -        {
   9.435 -                gus.t1++;
   9.436 -                if (gus.t1>=0xFF)
   9.437 -                {
   9.438 -//                        gus.t1on=0;
   9.439 -                        gus.t1=gus.t1l;
   9.440 -                        if (gus.tctrl&4)
   9.441 -                        {
   9.442 -                                picintlevel(0x20);
   9.443 -                                gus.irqstatus|=4;
   9.444 -//                                printf("GUS T1 IRQ!\n");
   9.445 -                        }
   9.446 -                }
   9.447 -        }
   9.448 -        if (gusirqnext)
   9.449 -        {
   9.450 -                gusirqnext=0;
   9.451 -                gus.irqstatus|=0x80;
   9.452 -                picintlevel(0x20);
   9.453 -        }
   9.454 -}
   9.455 -
   9.456 -void pollgus2()
   9.457 -{
   9.458 -        if (gus.t2on)
   9.459 -        {
   9.460 -                gus.t2++;
   9.461 -                if (gus.t2>=(0xFF<<2))
   9.462 -                {
   9.463 -//                        gus.t2on=0;
   9.464 -                        gus.t2=gus.t2l;
   9.465 -                        if (gus.tctrl&8)
   9.466 -                        {
   9.467 -                                picintlevel(0x20);
   9.468 -                                gus.irqstatus|=8;
   9.469 -//                                printf("GUS T2 IRQ!\n");
   9.470 -                        }
   9.471 -                }
   9.472 -        }
   9.473 -        if (gusirqnext)
   9.474 -        {
   9.475 -                gusirqnext=0;
   9.476 -                gus.irqstatus|=0x80;
   9.477 -                picintlevel(0x20);
   9.478 -        }
   9.479 -}
   9.480 -
   9.481 -float gusfreqs[]=
   9.482 -{
   9.483 -        44100,41160,38587,36317,34300,32494,30870,29400,28063,26843,25725,24696,
   9.484 -        23746,22866,22050,21289,20580,19916,19293
   9.485 -};
   9.486 -
   9.487 -int16_t gusbufferx[65536];
   9.488 -int guspos=0;
   9.489 -void getgus(int16_t *p, int count)
   9.490 -{
   9.491 -        memcpy(p,gusbufferx,count*4);
   9.492 -//        printf("Get %i samples %i\n",guspos,count);
   9.493 -        guspos=0;
   9.494 -        pollgusirqs();
   9.495 -}
   9.496 -
   9.497 -void pollgussamp()
   9.498 -{
   9.499 -        uint32_t addr;
   9.500 -        int c,d;
   9.501 -        int16_t v;
   9.502 -        int32_t vl;
   9.503 -        int16_t p[2];
   9.504 -        float GUSRATECONST;
   9.505 -        if (guspos>65500) return;
   9.506 -//        return;
   9.507 -        if (gus.voices<14) GUSRATECONST=44100.0/48000.0;
   9.508 -        else               GUSRATECONST=gusfreqs[gus.voices-14]/48000.0;
   9.509 -//        printf("Voices %i freq %f\n",gus.voices,GUSRATECONST*48000.0);
   9.510 -//        for (c=0;c<count;c++)
   9.511 -//        {
   9.512 -                p[0]=p[1]=0;
   9.513 -                for (d=0;d<32;d++)
   9.514 -                {
   9.515 -                        if (!(gus.ctrl[d]&1))
   9.516 -                        {
   9.517 -                                if (gus.ctrl[d]&4)
   9.518 -                                {
   9.519 -                                        addr=gus.cur[d]>>9;
   9.520 -                                        addr=(addr&0xC0000)|((addr<<1)&0x3FFFE);
   9.521 -                                        if (!(gus.freq[d]>>10)) /*Interpolate*/
   9.522 -                                        {
   9.523 -                                                vl=(int16_t)(int8_t)((gusram[(addr+1)&0xFFFFF]^0x80)-0x80)*(511-(gus.cur[d]&511));
   9.524 -                                                vl+=(int16_t)(int8_t)((gusram[(addr+3)&0xFFFFF]^0x80)-0x80)*(gus.cur[d]&511);
   9.525 -                                                v=vl>>9;
   9.526 -                                        }
   9.527 -                                        else
   9.528 -                                           v=(int16_t)(int8_t)((gusram[(addr+1)&0xFFFFF]^0x80)-0x80);
   9.529 -                                }
   9.530 -                                else
   9.531 -                                {
   9.532 -                                        if (!(gus.freq[d]>>10)) /*Interpolate*/
   9.533 -                                        {
   9.534 -                                                vl=((int8_t)((gusram[(gus.cur[d]>>9)&0xFFFFF]^0x80)-0x80))*(511-(gus.cur[d]&511));
   9.535 -                                                vl+=((int8_t)((gusram[((gus.cur[d]>>9)+1)&0xFFFFF]^0x80)-0x80))*(gus.cur[d]&511);
   9.536 -                                                v=vl>>9;
   9.537 -                                        }
   9.538 -                                        else
   9.539 -                                           v=(int16_t)(int8_t)((gusram[(gus.cur[d]>>9)&0xFFFFF]^0x80)-0x80);
   9.540 -                                }
   9.541 -//                                   v=(int16_t)((float)((gusram[(gus.cur[d]>>9)&0xFFFFF]^0x80)-0x80)*32.0*vol16bit[(gus.rcur[d]>>13)&4095]);
   9.542 -                                if ((gus.rcur[d]>>13)>4095) v=(int16_t)(float)(v)*24.0*vol16bit[4095];
   9.543 -                                else                        v=(int16_t)(float)(v)*24.0*vol16bit[(gus.rcur[d]>>13)&4095];
   9.544 -//                                if (!d) printf("%08X  %08X %08X  %05X  %08X %08X  %04X %f %04X %08X %i\n",gus.cur[d],gus.start[d],gus.end[d],gus.cur[d]>>9,gus.startx[d],gus.endx[d],gus.rcur[d],vol16bit[0],v,gus.freq[d],ins);
   9.545 -//                                if (!d)
   9.546 -//                                {
   9.547 -                                        p[0]+=v;
   9.548 -                                        p[1]+=v;
   9.549 -//                                }
   9.550 -//                                printf("Data from %08X\n",gus.cur[d]>>8);
   9.551 -                                if (gus.ctrl[d]&0x40)
   9.552 -                                {
   9.553 -                                        gus.cur[d]-=(gus.freq[d]>>1)*GUSRATECONST;
   9.554 -                                        if (gus.cur[d]<=gus.start[d])
   9.555 -                                        {
   9.556 -                                                if (!(gus.rctrl[d]&4))
   9.557 -                                                {
   9.558 -                                                        if (!(gus.ctrl[d]&8)) gus.ctrl[d]|=1;
   9.559 -                                                        else if (gus.ctrl[d]&0x10) gus.ctrl[d]^=0x40;
   9.560 -                                                        gus.cur[d]=(gus.ctrl[d]&0x40)?gus.end[d]:gus.start[d];
   9.561 -                                                }
   9.562 -                                                if (gus.ctrl[d]&0x20) gus.waveirqs[d]=1;
   9.563 -                                        }
   9.564 -                                }
   9.565 -                                else
   9.566 -                                {
   9.567 -                                        gus.cur[d]+=(gus.freq[d]>>1)*GUSRATECONST;
   9.568 -//                                        pclog("GUS add %08X %f\n",gus.freq[d],GUSRATECONST);
   9.569 -                                        if (gus.cur[d]>=gus.end[d])
   9.570 -                                        {
   9.571 -                                                if (!(gus.rctrl[d]&4))
   9.572 -                                                {
   9.573 -//                                                        gus.ctrl[d]|=1;
   9.574 -                                                        if (!(gus.ctrl[d]&8)) gus.ctrl[d]|=1;
   9.575 -                                                        else if (gus.ctrl[d]&0x10) gus.ctrl[d]^=0x40;
   9.576 -                                                        gus.cur[d]=(gus.ctrl[d]&0x40)?gus.end[d]:gus.start[d];
   9.577 -                                                }
   9.578 -                                                if (gus.ctrl[d]&0x20) gus.waveirqs[d]=1;
   9.579 -                                        }
   9.580 -                                }
   9.581 -                        }
   9.582 -                        if (!(gus.rctrl[d]&1))
   9.583 -                        {
   9.584 -                                if (gus.rctrl[d]&0x40)
   9.585 -                                {
   9.586 -                                        gus.rcur[d]-=gus.rfreq[d]*GUSRATECONST*16;
   9.587 -//                                        printf("RCUR- %i %i %i %i %i\n",d,gus.rfreq[d],gus.rcur[d],gus.rstart[d],gus.rend[d]);
   9.588 -                                        if (gus.rcur[d]<=gus.rstart[d])
   9.589 -                                        {
   9.590 -                                                if (gus.rctrl[d]&8)    gus.rcur[d]=gus.rend[d]<<8;
   9.591 -                                                else                   gus.rctrl[d]|=1;
   9.592 -                                                if (gus.rctrl[d]&0x20)
   9.593 -                                                {
   9.594 -                                                        gus.rampirqs[d]=1;
   9.595 -//                                                        pclog("Causing ramp IRQ %02X\n",gus.rctrl[d]);
   9.596 -                                                }
   9.597 -                                        }
   9.598 -                                }
   9.599 -                                else
   9.600 -                                {
   9.601 -                                        gus.rcur[d]+=gus.rfreq[d]*GUSRATECONST*16;
   9.602 -//                                        printf("RCUR+ %i %08X %08X %08X %08X\n",d,gus.rfreq[d],gus.rcur[d],gus.rstart[d],gus.rend[d]);
   9.603 -                                        if (gus.rcur[d]>=gus.rend[d])
   9.604 -                                        {
   9.605 -                                                if (gus.rctrl[d]&8) gus.rcur[d]=gus.rstart[d]<<8;
   9.606 -                                                else                gus.rctrl[d]|=1;
   9.607 -                                                if (gus.rctrl[d]&0x20)
   9.608 -                                                {
   9.609 -                                                        gus.rampirqs[d]=1;
   9.610 -//                                                        pclog("Causing ramp IRQ %02X\n",gus.rctrl[d]);
   9.611 -                                                }
   9.612 -                                        }
   9.613 -                                }
   9.614 -                        }
   9.615 -                }
   9.616 -                gusbufferx[guspos++]=p[0];
   9.617 -                gusbufferx[guspos++]=p[1];
   9.618 -                if (guspos==65536) guspos=0;
   9.619 -//        }
   9.620 -        pollgusirqs();
   9.621 -}
   9.622 -
   9.623 -void gus_init()
   9.624 -{
   9.625 -        io_sethandler(0x0240, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL);
   9.626 -        io_sethandler(0x0340, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL);
   9.627 -        io_sethandler(0x0388, 0x0001, NULL,    NULL, NULL, writegus, NULL, NULL);
   9.628 -}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/i430vx.c	Mon May 27 19:56:33 2013 +0100
    10.3 @@ -0,0 +1,96 @@
    10.4 +#include <string.h>
    10.5 +
    10.6 +#include "ibm.h"
    10.7 +#include "io.h"
    10.8 +#include "mem.h"
    10.9 +#include "pci.h"
   10.10 +
   10.11 +#include "i430vx.h"
   10.12 +
   10.13 +static uint8_t card_i430vx[256];
   10.14 +
   10.15 +static void i430vx_map(uint32_t addr, uint32_t size, int state)
   10.16 +{
   10.17 +        switch (state & 3)
   10.18 +        {
   10.19 +                case 0x0: mem_sethandler(addr, size, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   NULL,          NULL,           NULL          , NULL); break; /*DRAM disabled, accesses directed to PCI bus*/
   10.20 +                case 0x1: mem_sethandler(addr, size, mem_read_ram,    mem_read_ramw,    mem_read_raml,    NULL,          NULL,           NULL          , NULL); break; /*Read only, DRAM write protected, non-cacheable*/
   10.21 +                case 0x2: mem_sethandler(addr, size, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break; /*Write only*/
   10.22 +                case 0x3: mem_sethandler(addr, size, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml, NULL); break; /*Read/write, non-cacheable*/
   10.23 +                /*Below are redundant*/
   10.24 +//                case 0x5: mem_sethandler(addr, size, mem_read_ram,    mem_read_ramw,    mem_read_raml,    NULL,          NULL,           NULL          ); break; /*Read only, DRAM write protected, cacheable*/
   10.25 +//                case 0x7: mem_sethandler(addr, size, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml); break; /*Read/write, non-cacheable*/                
   10.26 +        }
   10.27 +        flushmmucache_nopc();        
   10.28 +}
   10.29 +void i430vx_write(int func, int addr, uint8_t val, void *priv)
   10.30 +{
   10.31 +        if (func)
   10.32 +           return;
   10.33 +           
   10.34 +        switch (addr)
   10.35 +        {
   10.36 +                case 0x00: case 0x01: case 0x02: case 0x03:
   10.37 +                case 0x08: case 0x09: case 0x0a: case 0x0b:
   10.38 +                case 0x0e:
   10.39 +                return;
   10.40 +                
   10.41 +                case 0x59: /*PAM0*/
   10.42 +                if ((card_i430vx[0x59] ^ val) & 0xf0)
   10.43 +                {
   10.44 +                        i430vx_map(0xf0000, 0x10000, val >> 4);
   10.45 +                        shadowbios = (val & 0x10);
   10.46 +                }
   10.47 +                pclog("i430vx_write : PAM0 write %02X\n", val);
   10.48 +                break;
   10.49 +                case 0x5e: /*PAM5*/
   10.50 +                if ((card_i430vx[0x5e] ^ val) & 0x0f)
   10.51 +                   i430vx_map(0xe0000, 0x04000, val & 0xf);
   10.52 +                if ((card_i430vx[0x5e] ^ val) & 0xf0)
   10.53 +                   i430vx_map(0xe4000, 0x04000, val >> 4);
   10.54 +                pclog("i430vx_write : PAM5 write %02X\n", val);
   10.55 +                break;
   10.56 +                case 0x5f: /*PAM6*/
   10.57 +                if ((card_i430vx[0x5f] ^ val) & 0x0f)
   10.58 +                   i430vx_map(0xe8000, 0x04000, val & 0xf);
   10.59 +                if ((card_i430vx[0x5f] ^ val) & 0xf0)
   10.60 +                   i430vx_map(0xec000, 0x04000, val >> 4);
   10.61 +                pclog("i430vx_write : PAM6 write %02X\n", val);
   10.62 +                break;
   10.63 +        }
   10.64 +                
   10.65 +        card_i430vx[addr] = val;
   10.66 +}
   10.67 +
   10.68 +uint8_t i430vx_read(int func, int addr, void *priv)
   10.69 +{
   10.70 +        if (func)
   10.71 +           return 0xff;
   10.72 +
   10.73 +        return card_i430vx[addr];
   10.74 +}
   10.75 + 
   10.76 +    
   10.77 +void i430vx_init()
   10.78 +{
   10.79 +        pci_add_specific(0, i430vx_read, i430vx_write, NULL);
   10.80 +        
   10.81 +        memset(card_i430vx, 0, 256);
   10.82 +        card_i430vx[0x00] = 0x86; card_i430vx[0x01] = 0x80; /*Intel*/
   10.83 +        card_i430vx[0x02] = 0x30; card_i430vx[0x03] = 0x70; /*82437VX*/
   10.84 +        card_i430vx[0x04] = 0x06; card_i430vx[0x05] = 0x00;
   10.85 +        card_i430vx[0x06] = 0x00; card_i430vx[0x07] = 0x02;
   10.86 +        card_i430vx[0x08] = 0x00; /*A0 stepping*/
   10.87 +        card_i430vx[0x09] = 0x00; card_i430vx[0x0a] = 0x00; card_i430vx[0x0b] = 0x06;
   10.88 +        card_i430vx[0x52] = 0x42; /*256kb PLB cache*/
   10.89 +        card_i430vx[0x53] = 0x14;
   10.90 +        card_i430vx[0x56] = 0x52; /*DRAM control*/
   10.91 +        card_i430vx[0x57] = 0x01;
   10.92 +        card_i430vx[0x60] = card_i430vx[0x61] = card_i430vx[0x62] = card_i430vx[0x63] = card_i430vx[0x64] = 0x02;
   10.93 +        card_i430vx[0x67] = 0x11;
   10.94 +        card_i430vx[0x69] = 0x03;
   10.95 +        card_i430vx[0x70] = 0x20;
   10.96 +        card_i430vx[0x72] = 0x02;
   10.97 +        card_i430vx[0x74] = 0x0e;
   10.98 +        card_i430vx[0x78] = 0x23;
   10.99 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/i430vx.h	Mon May 27 19:56:33 2013 +0100
    11.3 @@ -0,0 +1,1 @@
    11.4 +void i430vx_init();
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/piix.c	Mon May 27 19:56:33 2013 +0100
    12.3 @@ -0,0 +1,303 @@
    12.4 +/*PRD format :
    12.5 +        
    12.6 +        word 0 - base address
    12.7 +        word 1 - bits 1 - 15 = byte count, bit 31 = end of transfer
    12.8 +*/
    12.9 +#include <string.h>
   12.10 +
   12.11 +#include "ibm.h"
   12.12 +#include "ide.h"
   12.13 +#include "io.h"
   12.14 +#include "pci.h"
   12.15 +
   12.16 +#include "piix.h"
   12.17 +
   12.18 +uint8_t piix_bus_master_read(uint16_t port, void *priv);
   12.19 +void piix_bus_master_write(uint16_t port, uint8_t val, void *priv);
   12.20 +
   12.21 +static uint8_t card_piix[256], card_piix_ide[256];
   12.22 +
   12.23 +void piix_write(int func, int addr, uint8_t val, void *priv)
   12.24 +{
   12.25 +        if (func > 1)
   12.26 +           return;
   12.27 +        
   12.28 +        if (func == 1) /*IDE*/
   12.29 +        {
   12.30 +                switch (addr)
   12.31 +                {
   12.32 +                        case 0x00: case 0x01: case 0x02: case 0x03:
   12.33 +                        case 0x08: case 0x09: case 0x0a: case 0x0b:
   12.34 +                        case 0x0e:
   12.35 +                        return;
   12.36 +                        case 0x20:
   12.37 +                        val |= 1;
   12.38 +                        break;
   12.39 +                        case 0x41:
   12.40 +                        if ((val ^ card_piix_ide[0x41]) & 0x80)
   12.41 +                        {
   12.42 +                                if (val & 0x80)
   12.43 +                                   ide_pri_enable();
   12.44 +                                else
   12.45 +                                   ide_pri_disable();
   12.46 +                        }
   12.47 +                        break;
   12.48 +                        case 0x43:
   12.49 +                        if ((val ^ card_piix_ide[0x43]) & 0x80)
   12.50 +                        {
   12.51 +                                if (val & 0x80)
   12.52 +                                   ide_sec_enable();
   12.53 +                                else
   12.54 +                                   ide_sec_disable();
   12.55 +                        }
   12.56 +                        break;
   12.57 +                }
   12.58 +                card_piix_ide[addr] = val;
   12.59 +                if ((addr & ~3) == 0x20) /*Bus master base address*/                
   12.60 +                {
   12.61 +                        uint16_t base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8);
   12.62 +                        io_removehandler(0, 0x10000, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL,  NULL);
   12.63 +                        io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL,  NULL);
   12.64 +                }
   12.65 +//                pclog("PIIX write %02X %02X\n", addr, val);
   12.66 +        }
   12.67 +        else
   12.68 +        {
   12.69 +                switch (addr)
   12.70 +                {
   12.71 +                        case 0x00: case 0x01: case 0x02: case 0x03:
   12.72 +                        case 0x08: case 0x09: case 0x0a: case 0x0b:
   12.73 +                        case 0x0e:
   12.74 +                        return;
   12.75 +                }
   12.76 +                card_piix[addr] = val;
   12.77 +        }
   12.78 +}
   12.79 +
   12.80 +uint8_t piix_read(int func, int addr, void *priv)
   12.81 +{
   12.82 +        if (func > 1)
   12.83 +           return 0xff;
   12.84 +
   12.85 +        if (func == 1) /*IDE*/
   12.86 +        {
   12.87 +//                pclog("PIIX IDE read %02X %02X\n", addr, card_piix_ide[addr]);                
   12.88 +                return card_piix_ide[addr];
   12.89 +        }
   12.90 +        else
   12.91 +           return card_piix[addr];
   12.92 +}
   12.93 +
   12.94 +struct
   12.95 +{
   12.96 +        uint8_t command;
   12.97 +        uint8_t status;
   12.98 +        uint32_t ptr, ptr_cur;
   12.99 +        int count;
  12.100 +        uint32_t addr;
  12.101 +        int eot;
  12.102 +} piix_busmaster[2];
  12.103 +
  12.104 +static void piix_bus_master_next_addr(int channel)
  12.105 +{
  12.106 +        piix_busmaster[channel].addr = (*(unsigned long *)(&ram[piix_busmaster[channel].ptr_cur])) & ~1;
  12.107 +        piix_busmaster[channel].count = (*(unsigned long *)(&ram[piix_busmaster[channel].ptr_cur + 4])) & 0xfffe;
  12.108 +        piix_busmaster[channel].eot = (*(unsigned long *)(&ram[piix_busmaster[channel].ptr_cur + 4])) >> 31;
  12.109 +        piix_busmaster[channel].ptr_cur += 8;
  12.110 +//        pclog("New DMA settings on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
  12.111 +}
  12.112 +
  12.113 +void piix_bus_master_write(uint16_t port, uint8_t val, void *priv)
  12.114 +{
  12.115 +        int channel = (port & 8) ? 1 : 0;
  12.116 +//        pclog("PIIX Bus Master write %04X %02X\n", port, val);
  12.117 +        switch (port & 7)
  12.118 +        {
  12.119 +                case 0:
  12.120 +                if ((val & 1) && !(piix_busmaster[channel].command & 1)) /*Start*/
  12.121 +                {
  12.122 +                        piix_busmaster[channel].ptr_cur = piix_busmaster[channel].ptr;
  12.123 +                        piix_bus_master_next_addr(channel);
  12.124 +                        piix_busmaster[channel].status |= 1;
  12.125 +                }
  12.126 +                if (!(val & 1) && (piix_busmaster[channel].command & 1)) /*Stop*/
  12.127 +                   piix_busmaster[channel].status &= ~1;
  12.128 +                   
  12.129 +                piix_busmaster[channel].command = val;
  12.130 +                break;
  12.131 +                case 2:
  12.132 +                piix_busmaster[channel].status = (val & 0x60) | ((piix_busmaster[channel].status & ~val) & 6) | (piix_busmaster[channel].status & 1);
  12.133 +                break;
  12.134 +                case 4:
  12.135 +                piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xffffff00) | val;
  12.136 +                break;
  12.137 +                case 5:
  12.138 +                piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xffff00ff) | (val << 8);
  12.139 +                break;
  12.140 +                case 6:
  12.141 +                piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xff00ffff) | (val << 16);
  12.142 +                break;
  12.143 +                case 7:
  12.144 +                piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0x00ffffff) | (val << 24);
  12.145 +                break;
  12.146 +        }
  12.147 +}
  12.148 +                
  12.149 +uint8_t piix_bus_master_read(uint16_t port, void *priv)
  12.150 +{
  12.151 +        int channel = (port & 8) ? 1 : 0;
  12.152 +        switch (port & 7)
  12.153 +        {
  12.154 +                case 0:
  12.155 +                return piix_busmaster[channel].command;
  12.156 +                case 2:
  12.157 +                return piix_busmaster[channel].status;
  12.158 +                case 4:
  12.159 +                return piix_busmaster[channel].ptr;
  12.160 +                case 5:
  12.161 +                return piix_busmaster[channel].ptr >> 8;
  12.162 +                case 6:
  12.163 +                return piix_busmaster[channel].ptr >> 16;
  12.164 +                case 7:
  12.165 +                return piix_busmaster[channel].ptr >> 24;
  12.166 +        }
  12.167 +        return 0xff;
  12.168 +}
  12.169 +
  12.170 +int piix_bus_master_sector_read(int channel, uint8_t *data)
  12.171 +{
  12.172 +        int transferred = 0;
  12.173 +        
  12.174 +        if (!(piix_busmaster[channel].status & 1))
  12.175 +           return 1;                                    /*DMA disabled*/
  12.176 +           
  12.177 +        while (transferred < 512)
  12.178 +        {
  12.179 +                if (piix_busmaster[channel].count < (512 - transferred) && piix_busmaster[channel].eot)
  12.180 +                   fatal("DMA on channel %i - Read count less than 512! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
  12.181 +                
  12.182 +                if (piix_busmaster[channel].count < (512 - transferred))
  12.183 +                {
  12.184 +//                        pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count);
  12.185 +                        memcpy(&ram[piix_busmaster[channel].addr], data + transferred, piix_busmaster[channel].count);
  12.186 +                        transferred += piix_busmaster[channel].count;
  12.187 +                        piix_busmaster[channel].addr += piix_busmaster[channel].count;
  12.188 +                        piix_busmaster[channel].count = 0;
  12.189 +                }                       
  12.190 +                else
  12.191 +                {
  12.192 +//                        pclog("Transferring larger - %i bytes\n", 512 - transferred);
  12.193 +                        memcpy(&ram[piix_busmaster[channel].addr], data + transferred, 512 - transferred);
  12.194 +                        piix_busmaster[channel].addr += (512 - transferred);
  12.195 +                        piix_busmaster[channel].count -= (512 - transferred);
  12.196 +                        transferred += (512 - transferred);                        
  12.197 +                }
  12.198 +
  12.199 +//                pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
  12.200 +
  12.201 +                if (!piix_busmaster[channel].count)
  12.202 +                {
  12.203 +//                        pclog("DMA on channel %i - block over\n", channel);
  12.204 +                        if (piix_busmaster[channel].eot) /*End of transfer?*/
  12.205 +                        {
  12.206 +//                                pclog("DMA on channel %i - transfer over\n", channel);
  12.207 +                                piix_busmaster[channel].status &= ~1;
  12.208 +                        }
  12.209 +                        else
  12.210 +                           piix_bus_master_next_addr(channel);
  12.211 +                }
  12.212 +        }
  12.213 +        return 0;
  12.214 +}
  12.215 +int piix_bus_master_sector_write(int channel, uint8_t *data)
  12.216 +{
  12.217 +        int transferred = 0;
  12.218 +        
  12.219 +        if (!(piix_busmaster[channel].status & 1))
  12.220 +           return 1;                                    /*DMA disabled*/
  12.221 +
  12.222 +        while (transferred < 512)
  12.223 +        {
  12.224 +                if (piix_busmaster[channel].count < (512 - transferred) && piix_busmaster[channel].eot)
  12.225 +                   fatal("DMA on channel %i - Write count less than 512! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
  12.226 +                
  12.227 +                if (piix_busmaster[channel].count < (512 - transferred))
  12.228 +                {
  12.229 +//                        pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count);
  12.230 +                        memcpy(data + transferred, &ram[piix_busmaster[channel].addr], piix_busmaster[channel].count);
  12.231 +                        transferred += piix_busmaster[channel].count;
  12.232 +                        piix_busmaster[channel].addr += piix_busmaster[channel].count;
  12.233 +                        piix_busmaster[channel].count = 0;
  12.234 +                }                       
  12.235 +                else
  12.236 +                {
  12.237 +//                        pclog("Transferring larger - %i bytes\n", 512 - transferred);
  12.238 +                        memcpy(data + transferred, &ram[piix_busmaster[channel].addr], 512 - transferred);
  12.239 +                        piix_busmaster[channel].addr += (512 - transferred);
  12.240 +                        piix_busmaster[channel].count -= (512 - transferred);
  12.241 +                        transferred += (512 - transferred);                        
  12.242 +                }
  12.243 +
  12.244 +//                pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
  12.245 +
  12.246 +                if (!piix_busmaster[channel].count)
  12.247 +                {
  12.248 +//                        pclog("DMA on channel %i - block over\n", channel);
  12.249 +                        if (piix_busmaster[channel].eot) /*End of transfer?*/
  12.250 +                        {
  12.251 +//                                pclog("DMA on channel %i - transfer over\n", channel);
  12.252 +                                piix_busmaster[channel].status &= ~1;
  12.253 +                        }
  12.254 +                        else
  12.255 +                           piix_bus_master_next_addr(channel);
  12.256 +                }
  12.257 +        }
  12.258 +        return 0;
  12.259 +}
  12.260 +
  12.261 +void piix_bus_master_set_irq(int channel)
  12.262 +{
  12.263 +        piix_busmaster[channel].status |= 4;
  12.264 +}
  12.265 +
  12.266 +void piix_init(int card)
  12.267 +{
  12.268 +        pci_add_specific(card, piix_read, piix_write, NULL);
  12.269 +        
  12.270 +        memset(card_piix, 0, 256);
  12.271 +        card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/
  12.272 +        card_piix[0x02] = 0x2e; card_piix[0x03] = 0x12; /*82371FB (PIIX)*/
  12.273 +        card_piix[0x04] = 0x07; card_piix[0x05] = 0x00;
  12.274 +        card_piix[0x06] = 0x00; card_piix[0x07] = 0x02;
  12.275 +        card_piix[0x08] = 0x00; /*A0 stepping*/
  12.276 +        card_piix[0x09] = 0x00; card_piix[0x0a] = 0x01; card_piix[0x0b] = 0x06;
  12.277 +        card_piix[0x0e] = 0x80; /*Multi-function device*/
  12.278 +        card_piix[0x4c] = 0x4d;
  12.279 +        card_piix[0x4e] = 0x03;
  12.280 +        card_piix[0x60] = card_piix[0x61] = card_piix[0x62] = card_piix[0x63] = 0x80;
  12.281 +        card_piix[0x69] = 0x02;
  12.282 +        card_piix[0x70] = card_piix[0x71] = 0x80;
  12.283 +        card_piix[0x76] = card_piix[0x77] = 0x0c;
  12.284 +        card_piix[0x78] = 0x02; card_piix[0x79] = 0x00;
  12.285 +        card_piix[0xa0] = 0x08;
  12.286 +        card_piix[0xa2] = card_piix[0xa3] = 0x00;
  12.287 +        card_piix[0xa4] = card_piix[0xa5] = card_piix[0xa6] = card_piix[0xa7] = 0x00;
  12.288 +        card_piix[0xa8] = 0x0f;
  12.289 +        card_piix[0xaa] = card_piix[0xab] = 0x00;
  12.290 +        card_piix[0xac] = 0x00;
  12.291 +        card_piix[0xae] = 0x00;
  12.292 +
  12.293 +        card_piix_ide[0x00] = 0x86; card_piix_ide[0x01] = 0x80; /*Intel*/
  12.294 +        card_piix_ide[0x02] = 0x30; card_piix_ide[0x03] = 0x12; /*82371FB (PIIX)*/
  12.295 +        card_piix_ide[0x04] = 0x00; card_piix_ide[0x05] = 0x00;
  12.296 +        card_piix_ide[0x06] = 0x80; card_piix_ide[0x07] = 0x02;
  12.297 +        card_piix_ide[0x08] = 0x00;
  12.298 +        card_piix_ide[0x09] = 0x80; card_piix_ide[0x0a] = 0x01; card_piix_ide[0x0b] = 0x01;
  12.299 +        card_piix_ide[0x0d] = 0x00;
  12.300 +        card_piix_ide[0x0e] = 0x00;
  12.301 +        card_piix_ide[0x20] = 0x01; card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/
  12.302 +        card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00;
  12.303 +        card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00;
  12.304 +        
  12.305 +        ide_set_bus_master(piix_bus_master_sector_read, piix_bus_master_sector_write, piix_bus_master_set_irq);
  12.306 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/piix.h	Mon May 27 19:56:33 2013 +0100
    13.3 @@ -0,0 +1,1 @@
    13.4 +void piix_init(int card);
    14.1 --- a/src/ppi.h	Mon May 27 17:46:42 2013 +0100
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,1 +0,0 @@
    14.4 -extern int wasgated;
    15.1 --- a/src/psg.c	Mon May 27 17:46:42 2013 +0100
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,206 +0,0 @@
    15.4 -#include "ibm.h"
    15.5 -
    15.6 -float volslog[16]=
    15.7 -{
    15.8 -	0.00000f,0.59715f,0.75180f,0.94650f,
    15.9 -        1.19145f,1.50000f,1.88835f,2.37735f,
   15.10 -        2.99295f,3.76785f,4.74345f,5.97165f,
   15.11 -        7.51785f,9.46440f,11.9194f,15.0000f
   15.12 -};
   15.13 -
   15.14 -float psgcount[4],psglatch[4];
   15.15 -int psgstat[4];
   15.16 -int snlatch[4],sncount[4];
   15.17 -int snfreqlo[4],snfreqhi[4];
   15.18 -int snvol[4];
   15.19 -int curfreq[4];
   15.20 -uint32_t snshift[2]={0x8000,0x8000};
   15.21 -
   15.22 -#define SNCLOCK (2386360>>5)
   15.23 -uint8_t snnoise;
   15.24 -
   15.25 -void initpsg()
   15.26 -{
   15.27 -        int c;
   15.28 -        for (c=0;c<4;c++)
   15.29 -        {
   15.30 -                psgcount[c]=psglatch[c]=100000;
   15.31 -                psgstat[c]=0;
   15.32 -        }
   15.33 -}
   15.34 -
   15.35 -#define PSGCONST (32000.0/48000.0)
   15.36 -
   15.37 -void getpsg(signed short *p, int size)
   15.38 -{
   15.39 -//        printf("Getpsg %08X %i\n",p,size);
   15.40 -//        return;
   15.41 -        int c,d;
   15.42 -        for (c=0;c<size;c++)
   15.43 -        {
   15.44 -                p[c]=0;
   15.45 -                for (d=1;d<4;d++)
   15.46 -                {
   15.47 -                        if (psgstat[d]) p[c]+=volslog[snvol[d]]*170;
   15.48 -                        else            p[c]-=volslog[snvol[d]]*170;
   15.49 -                        psgcount[d]-=(512*PSGCONST);
   15.50 -                        while (psgcount[d]<=0.0 && psglatch[d]>1.0)
   15.51 -                        {
   15.52 -                                psgcount[d]+=psglatch[d];
   15.53 -                                psgstat[d]^=1;
   15.54 -                        }
   15.55 -                        if (psgcount[d]<=0.0) psgcount[d]=1.0;
   15.56 -                }
   15.57 -                d=(snnoise&4)?0:1;
   15.58 -                if (snshift[d]&1) p[c]+=volslog[snvol[0]]*170;
   15.59 -                psgcount[0]-=(512*PSGCONST);
   15.60 -                while (psgcount[0]<=0.0 && psglatch[0]>1.0)
   15.61 -                {
   15.62 -                        psgcount[0]+=psglatch[0];
   15.63 -                        snshift[1]>>=1;
   15.64 -                        if (!snshift[1]) snshift[1]=0x4000;
   15.65 -                        if ((snshift[0]&1)^((snshift[0]&4)?1:0)^((snshift[0]&0x8000)?1:0))
   15.66 -                           snshift[0]|=0x10000;
   15.67 -                        snshift[0]>>=1;
   15.68 -                }
   15.69 -                if (psgcount[0]<=0.0) psgcount[0]=1.0;
   15.70 -        }
   15.71 -}
   15.72 -
   15.73 -int lasttone;
   15.74 -uint8_t firstdat;
   15.75 -void writepsg(uint16_t addr, uint8_t data)
   15.76 -{
   15.77 -        int c;
   15.78 -        int freq;
   15.79 -        pclog("Write PSG %02X\n", data);
   15.80 -        if (data&0x80)
   15.81 -        {
   15.82 -                firstdat=data;
   15.83 -                switch (data&0x70)
   15.84 -                {
   15.85 -                        case 0:
   15.86 -                        snfreqlo[3]=data&0xF;
   15.87 -                        lasttone=3;
   15.88 -                        break;
   15.89 -                        case 0x10:
   15.90 -                        data&=0xF;
   15.91 -                        snvol[3]=0xF-data;
   15.92 -                        break;
   15.93 -                        case 0x20:
   15.94 -                        snfreqlo[2]=data&0xF;
   15.95 -                        lasttone=2;
   15.96 -                        break;
   15.97 -                        case 0x30:
   15.98 -                        data&=0xF;
   15.99 -                        snvol[2]=0xF-data;
  15.100 -                        break;
  15.101 -                        case 0x40:
  15.102 -                        snfreqlo[1]=data&0xF;
  15.103 -                        lasttone=1;
  15.104 -                        break;
  15.105 -                        case 0x50:
  15.106 -                        data&=0xF;
  15.107 -                        snvol[1]=0xF-data;
  15.108 -                        break;
  15.109 -                        case 0x60:
  15.110 -                        if ((data&3)!=(snnoise&3)) sncount[0]=0;
  15.111 -                        snnoise=data&0xF;
  15.112 -                        if ((data&3)==3)
  15.113 -                        {
  15.114 -                                curfreq[0]=curfreq[1]>>4;
  15.115 -                                snlatch[0]=snlatch[1];
  15.116 -                        }
  15.117 -                        else
  15.118 -                        {
  15.119 -                                switch (data&3)
  15.120 -                                {
  15.121 -                                        case 0:
  15.122 -                                        snlatch[0]=128<<7;
  15.123 -                                        curfreq[0]=SNCLOCK/256;
  15.124 -                                        snlatch[0]=0x400;
  15.125 -                                        sncount[0]=0;
  15.126 -                                        break;
  15.127 -                                        case 1:
  15.128 -                                        snlatch[0]=256<<7;
  15.129 -                                        curfreq[0]=SNCLOCK/512;
  15.130 -                                        snlatch[0]=0x800;
  15.131 -                                        sncount[0]=0;
  15.132 -                                        break;
  15.133 -                                        case 2:
  15.134 -                                        snlatch[0]=512<<7;
  15.135 -                                        curfreq[0]=SNCLOCK/1024;
  15.136 -                                        snlatch[0]=0x1000;
  15.137 -                                        sncount[0]=0;
  15.138 -                                        break;
  15.139 -                                        case 3:
  15.140 -                                        snlatch[0]=snlatch[1];
  15.141 -                                        sncount[0]=0;
  15.142 -                                }
  15.143 -                                if (snnoise&4) snlatch[0]<<=1;
  15.144 -                        }
  15.145 -                        break;
  15.146 -                        case 0x70:
  15.147 -                        data&=0xF;
  15.148 -                        snvol[0]=0xF-data;
  15.149 -                        break;
  15.150 -                }
  15.151 -        }
  15.152 -        else
  15.153 -        {
  15.154 -                if ((firstdat&0x70)==0x60)
  15.155 -                {
  15.156 -                        if ((data&3)!=(snnoise&3)) sncount[0]=0;
  15.157 -                        snnoise=data&0xF;
  15.158 -                        if ((data&3)==3)
  15.159 -                        {
  15.160 -                                curfreq[0]=curfreq[1]>>4;
  15.161 -                                snlatch[0]=snlatch[1];
  15.162 -//                                printf("SN 0 latch %04X\n",snlatch[0]);
  15.163 -                        }
  15.164 -                        else
  15.165 -                        {
  15.166 -                                switch (data&3)
  15.167 -                                {
  15.168 -                                        case 0:
  15.169 -                                        snlatch[0]=128<<7;
  15.170 -                                        curfreq[0]=SNCLOCK/256;
  15.171 -                                        snlatch[0]=0x400;
  15.172 -                                        sncount[0]=0;
  15.173 -                                        break;
  15.174 -                                        case 1:
  15.175 -                                        snlatch[0]=256<<7;
  15.176 -                                        curfreq[0]=SNCLOCK/512;
  15.177 -                                        snlatch[0]=0x800;
  15.178 -                                        sncount[0]=0;
  15.179 -                                        break;
  15.180 -                                        case 2:
  15.181 -                                        snlatch[0]=512<<7;
  15.182 -                                        curfreq[0]=SNCLOCK/1024;
  15.183 -                                        snlatch[0]=0x1000;
  15.184 -                                        sncount[0]=0;
  15.185 -                                        break;
  15.186 -                                        case 3:
  15.187 -                                        snlatch[0]=snlatch[1];
  15.188 -//                                        printf("SN 0 latch %04X\n",snlatch[0]);
  15.189 -                                        sncount[0]=0;
  15.190 -                                }
  15.191 -                                if (snnoise&4) snlatch[0]<<=1;
  15.192 -                        }
  15.193 -                        return;
  15.194 -                }
  15.195 -                else
  15.196 -                {
  15.197 -                        snfreqhi[lasttone]=data&0x3F;
  15.198 -                        freq=snfreqlo[lasttone]|(snfreqhi[lasttone]<<4);
  15.199 -                        snlatch[lasttone]=freq<<6;
  15.200 -                }
  15.201 -        }
  15.202 -        for (c=0;c<4;c++) psglatch[c]=(float)snlatch[c];
  15.203 -}
  15.204 -
  15.205 -void psg_init()
  15.206 -{
  15.207 -        pclog("psg_init\n");
  15.208 -        io_sethandler(0x00C0, 0x0001, NULL, NULL, NULL, writepsg, NULL, NULL);
  15.209 -}
    16.1 --- a/src/psg.h	Mon May 27 17:46:42 2013 +0100
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,1 +0,0 @@
    16.4 -void psg_init();
    17.1 --- a/src/sblaster.c	Mon May 27 17:46:42 2013 +0100
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,1104 +0,0 @@
    17.4 -/*Jazz sample rates :
    17.5 -  386-33 - 12kHz
    17.6 -  486-33 - 20kHz
    17.7 -  486-50 - 32kHz
    17.8 -  Pentium - 45kHz*/
    17.9 -
   17.10 -#include <stdint.h>
   17.11 -#include <stdio.h>
   17.12 -#include "ibm.h"
   17.13 -#include "filters.h"
   17.14 -#include "io.h"
   17.15 -
   17.16 -static int sb_8_length,  sb_8_format,  sb_8_autoinit,  sb_8_pause,  sb_8_enable,  sb_8_autolen,  sb_8_output;
   17.17 -static int sb_16_length, sb_16_format, sb_16_autoinit, sb_16_pause, sb_16_enable, sb_16_autolen, sb_16_output;
   17.18 -static int sb_pausetime = -1;
   17.19 -
   17.20 -static uint8_t sb_read_data[256];
   17.21 -static int sb_read_wp, sb_read_rp;
   17.22 -static int sb_speaker;
   17.23 -
   17.24 -static int sb_data_stat=-1;
   17.25 -
   17.26 -static int sb_irqnum = 7;
   17.27 -
   17.28 -static uint8_t sbe2;
   17.29 -static int sbe2count;
   17.30 -
   17.31 -static int sbe2dat[4][9] = {
   17.32 -  {  0x01, -0x02, -0x04,  0x08, -0x10,  0x20,  0x40, -0x80, -106 },
   17.33 -  { -0x01,  0x02, -0x04,  0x08,  0x10, -0x20,  0x40, -0x80,  165 },
   17.34 -  { -0x01,  0x02,  0x04, -0x08,  0x10, -0x20, -0x40,  0x80, -151 },
   17.35 -  {  0x01, -0x02,  0x04, -0x08, -0x10,  0x20, -0x40,  0x80,   90 }
   17.36 -};
   17.37 -
   17.38 -static uint8_t sb_data[8];
   17.39 -static int sb_commands[256]=
   17.40 -{
   17.41 -        -1,-1,-1,-1, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1,
   17.42 -         1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0,
   17.43 -         0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,
   17.44 -        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
   17.45 -         1, 2, 2,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,
   17.46 -        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
   17.47 -        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
   17.48 -        -1,-1,-1,-1, 2, 2, 2, 2,-1,-1,-1,-1,-1, 0,-1, 0,
   17.49 -         2, 2,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1,
   17.50 -         0,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1,
   17.51 -        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
   17.52 -         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   17.53 -         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   17.54 -         0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1,
   17.55 -         1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1,
   17.56 -        -1,-1, 0,-1,-1,-1,-1,-1,-1, 1, 2,-1,-1,-1,-1, 0
   17.57 -};
   17.58 -
   17.59 -char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
   17.60 -uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405};
   17.61 -
   17.62 -/*These tables were 'borrowed' from DOSBox*/
   17.63 -	int8_t scaleMap4[64] = {
   17.64 -		0,  1,  2,  3,  4,  5,  6,  7,  0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,
   17.65 -		1,  3,  5,  7,  9, 11, 13, 15, -1,  -3,  -5,  -7,  -9, -11, -13, -15,
   17.66 -		2,  6, 10, 14, 18, 22, 26, 30, -2,  -6, -10, -14, -18, -22, -26, -30,
   17.67 -		4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60
   17.68 -	};
   17.69 -	uint8_t adjustMap4[64] = {
   17.70 -		  0, 0, 0, 0, 0, 16, 16, 16,
   17.71 -		  0, 0, 0, 0, 0, 16, 16, 16,
   17.72 -		240, 0, 0, 0, 0, 16, 16, 16,
   17.73 -		240, 0, 0, 0, 0, 16, 16, 16,
   17.74 -		240, 0, 0, 0, 0, 16, 16, 16,
   17.75 -		240, 0, 0, 0, 0, 16, 16, 16,
   17.76 -		240, 0, 0, 0, 0,  0,  0,  0,
   17.77 -		240, 0, 0, 0, 0,  0,  0,  0
   17.78 -	};
   17.79 -
   17.80 -	int8_t scaleMap26[40] = {
   17.81 -		0,  1,  2,  3,  0,  -1,  -2,  -3,
   17.82 -		1,  3,  5,  7, -1,  -3,  -5,  -7,
   17.83 -		2,  6, 10, 14, -2,  -6, -10, -14,
   17.84 -		4, 12, 20, 28, -4, -12, -20, -28,
   17.85 -		5, 15, 25, 35, -5, -15, -25, -35
   17.86 -	};
   17.87 -	uint8_t adjustMap26[40] = {
   17.88 -		  0, 0, 0, 8,   0, 0, 0, 8,
   17.89 -		248, 0, 0, 8, 248, 0, 0, 8,
   17.90 -		248, 0, 0, 8, 248, 0, 0, 8,
   17.91 -		248, 0, 0, 8, 248, 0, 0, 8,
   17.92 -		248, 0, 0, 0, 248, 0, 0, 0
   17.93 -	};
   17.94 -
   17.95 -	int8_t scaleMap2[24] = {
   17.96 -		0,  1,  0,  -1, 1,  3,  -1,  -3,
   17.97 -		2,  6, -2,  -6, 4, 12,  -4, -12,
   17.98 -		8, 24, -8, -24, 6, 48, -16, -48
   17.99 -	};
  17.100 -	uint8_t adjustMap2[24] = {
  17.101 -		  0, 4,   0, 4,
  17.102 -		252, 4, 252, 4, 252, 4, 252, 4,
  17.103 -		252, 4, 252, 4, 252, 4, 252, 4,
  17.104 -		252, 0, 252, 0
  17.105 -	};
  17.106 -
  17.107 -
  17.108 -int sb_freq;
  17.109 -
  17.110 -int sbtype=0;
  17.111 -
  17.112 -int writebusy=0; /*Needed for Amnesia*/
  17.113 -
  17.114 -int16_t sbdatl=0,sbdatr=0;
  17.115 -int16_t sb16datl=0,sb16datr=0;
  17.116 -
  17.117 -int16_t sbdat;
  17.118 -uint8_t sbref;
  17.119 -int sbdacmode,sbdacpos,sbdat2;
  17.120 -int8_t sbstep;
  17.121 -int sbleftright=0;
  17.122 -int sbinput=0;
  17.123 -int sbreadstat,sbwritestat;
  17.124 -int sbreset;
  17.125 -uint8_t sbreaddat;
  17.126 -uint8_t sb_command,sbdata;
  17.127 -int sbcommandnext=1;
  17.128 -uint8_t sb_test;
  17.129 -int sb_timei,sb_timeo;
  17.130 -int sbcommandstat;
  17.131 -int sbhalted;
  17.132 -int adpcmstat=0;
  17.133 -int sbautolen;
  17.134 -int sbautoinit=0;
  17.135 -uint8_t sbcurcommand,sbdmacommand;
  17.136 -float SBCONST;
  17.137 -int sbstereo=0;
  17.138 -
  17.139 -int sbsamprate;
  17.140 -uint8_t sb_transfertype;
  17.141 -int sb_newtransfer;
  17.142 -int sb_dma16;
  17.143 -int sb_uart;
  17.144 -int sb_irq8,sb_irq16;
  17.145 -int sb_16_exit;
  17.146 -
  17.147 -uint8_t mixerindex;
  17.148 -uint8_t sb_mixer[256];
  17.149 -uint8_t sb_asp_regs[256];
  17.150 -
  17.151 -
  17.152 -int sb_att[]=
  17.153 -{
  17.154 -        310,368,437,520,618,735,873,1038,1234,1467,1743,2072,2463,2927,3479,
  17.155 -        4134,4914,5840,6941,8250,9805,11653,13850,16461,19564,23252,27635,32845,
  17.156 -        39036,46395,55140,65535
  17.157 -};
  17.158 -
  17.159 -void sb_irq(int irq8)
  17.160 -{
  17.161 -//        pclog("IRQ %i %02X\n",irq8,pic.mask);
  17.162 -        if (irq8) sb_irq8=1;
  17.163 -        else      sb_irq16=1;
  17.164 -        picint(1 << sb_irqnum);
  17.165 -}
  17.166 -void sb_irqc(int irq8)
  17.167 -{
  17.168 -        if (irq8) sb_irq8=0;
  17.169 -        else      sb_irq16=0;
  17.170 -        picintc(1 << sb_irqnum);
  17.171 -}
  17.172 -
  17.173 -void sb_mixer_set()
  17.174 -{
  17.175 -        if (sbtype==SB16)
  17.176 -        {
  17.177 -                mixer.master_l=sb_att[sb_mixer[0x30]>>3];
  17.178 -                mixer.master_r=sb_att[sb_mixer[0x31]>>3];
  17.179 -                mixer.voice_l =sb_att[sb_mixer[0x32]>>3];
  17.180 -                mixer.voice_r =sb_att[sb_mixer[0x33]>>3];
  17.181 -                mixer.fm_l    =sb_att[sb_mixer[0x34]>>3];
  17.182 -                mixer.fm_r    =sb_att[sb_mixer[0x35]>>3];
  17.183 -                mixer.bass_l  =sb_mixer[0x46]>>4;
  17.184 -                mixer.bass_r  =sb_mixer[0x47]>>4;
  17.185 -                mixer.treble_l=sb_mixer[0x44]>>4;
  17.186 -                mixer.treble_r=sb_mixer[0x45]>>4;
  17.187 -                mixer.filter=0;
  17.188 -                pclog("%02X %02X %02X %02X %02X %02X\n",sb_mixer[0x30],sb_mixer[0x31],sb_mixer[0x32],sb_mixer[0x33],sb_mixer[0x34],sb_mixer[0x35]);
  17.189 -                pclog("Mixer - %04X %04X %04X %04X %04X %04X\n",mixer.master_l,mixer.master_r,mixer.voice_l,mixer.voice_r,mixer.fm_l,mixer.fm_r);
  17.190 -        }
  17.191 -        else if (sbtype==SBPRO || sbtype==SBPRO2)
  17.192 -        {
  17.193 -                mixer.master_l=sb_att[(sb_mixer[0x22]>>4)|0x11];
  17.194 -                mixer.master_r=sb_att[(sb_mixer[0x22]&0xF)|0x11];
  17.195 -                mixer.voice_l =sb_att[(sb_mixer[0x04]>>4)|0x11];
  17.196 -                mixer.voice_r =sb_att[(sb_mixer[0x04]&0xF)|0x11];
  17.197 -                mixer.fm_l    =sb_att[(sb_mixer[0x26]>>4)|0x11];
  17.198 -                mixer.fm_r    =sb_att[(sb_mixer[0x26]&0xF)|0x11];
  17.199 -                mixer.filter  =!(sb_mixer[0xE]&0x20);
  17.200 -                mixer.bass_l  =mixer.bass_r  =8;
  17.201 -                mixer.treble_l=mixer.treble_r=8;
  17.202 -                pclog("%02X %02X %02X\n",sb_mixer[0x04],sb_mixer[0x22],sb_mixer[0x26]);
  17.203 -                pclog("Mixer - %04X %04X %04X %04X %04X %04X\n",mixer.master_l,mixer.master_r,mixer.voice_l,mixer.voice_r,mixer.fm_l,mixer.fm_r);
  17.204 -        }
  17.205 -        else
  17.206 -        {
  17.207 -                mixer.master_l=mixer.master_r=65535;
  17.208 -                mixer.voice_l =mixer.voice_r =65535;
  17.209 -                mixer.fm_l    =mixer.fm_r    =65535;
  17.210 -                mixer.bass_l  =mixer.bass_r  =8;
  17.211 -                mixer.treble_l=mixer.treble_r=8;
  17.212 -                mixer.filter=1;
  17.213 -        }
  17.214 -}
  17.215 -
  17.216 -void sb_mixer_reset()
  17.217 -{
  17.218 -        pclog("Mixer reset\n");
  17.219 -        if (sbtype==SB16)
  17.220 -        {
  17.221 -                sb_mixer[0x30]=31<<3;
  17.222 -                sb_mixer[0x31]=31<<3;
  17.223 -                sb_mixer[0x32]=31<<3;
  17.224 -                sb_mixer[0x33]=31<<3;
  17.225 -                sb_mixer[0x34]=31<<3;
  17.226 -                sb_mixer[0x35]=31<<3;
  17.227 -                sb_mixer[0x44]=8<<4;
  17.228 -                sb_mixer[0x45]=8<<4;
  17.229 -                sb_mixer[0x46]=8<<4;
  17.230 -                sb_mixer[0x47]=8<<4;
  17.231 -                sb_mixer[0x22]=(sb_mixer[0x30]&0xF0)|(sb_mixer[0x31]>>4);
  17.232 -                sb_mixer[0x04]=(sb_mixer[0x32]&0xF0)|(sb_mixer[0x33]>>4);
  17.233 -                sb_mixer[0x26]=(sb_mixer[0x34]&0xF0)|(sb_mixer[0x35]>>4);
  17.234 -        }
  17.235 -        if (sbtype==SBPRO || sbtype==SBPRO2)
  17.236 -        {
  17.237 -                sb_mixer[0x22]=0xFF;
  17.238 -                sb_mixer[0x04]=0xFF;
  17.239 -                sb_mixer[0x26]=0xFF;
  17.240 -                sb_mixer[0xE]=0;
  17.241 -        }
  17.242 -}
  17.243 -
  17.244 -void sb_dsp_reset()
  17.245 -{
  17.246 -        sbenable = sb_enable_i = 0;
  17.247 -        sb_command = 0;
  17.248 -        
  17.249 -        sb_uart = 0;
  17.250 -        sb_8_length = sbautolen = 0xFFFF;
  17.251 -
  17.252 -        sb_irqc(0);
  17.253 -        sb_irqc(1);
  17.254 -        sb_16_pause = 0;
  17.255 -        sb_read_wp = sb_read_rp = 0;
  17.256 -        sb_data_stat = -1;
  17.257 -        sb_speaker = 0;
  17.258 -        sb_pausetime = -1;
  17.259 -        sbe2 = 0xAA;
  17.260 -        sbe2count = 0;
  17.261 -
  17.262 -        sbreset = 0;
  17.263 -        sbenable = sb_enable_i = sb_count_i = 0;
  17.264 -        sbhalted = 0;
  17.265 -        sbdmacommand = 0;
  17.266 -        sbstereo = 0;
  17.267 -
  17.268 -        picintc(1 << sb_irqnum);
  17.269 -}
  17.270 -
  17.271 -void sb_reset()
  17.272 -{
  17.273 -        int c;
  17.274 -        
  17.275 -        sb_dsp_reset();
  17.276 -        sb_mixer_reset();
  17.277 -        sb_mixer_set();
  17.278 -        
  17.279 -        if (sbtype==SB16) sb_commands[8]=1;
  17.280 -        else              sb_commands[8]=-1;
  17.281 -        
  17.282 -        for (c = 0; c < 256; c++)
  17.283 -            sb_asp_regs[c] = 0;
  17.284 -        sb_asp_regs[5] = 0x01;
  17.285 -        sb_asp_regs[9] = 0xf8;
  17.286 -}
  17.287 -
  17.288 -void setsbclock(float clock)
  17.289 -{
  17.290 -        SBCONST=clock/1000000.0f;
  17.291 -        printf("SBCONST %f %f\n",SBCONST,clock);
  17.292 -        if (sb_timeo>255) sblatcho=(int)(SBCONST*(1000000.0f/(float)(sb_timeo-256)));
  17.293 -        else              sblatcho=SBCONST*(256-sb_timeo);
  17.294 -        if (sb_timei>255) sblatchi=(int)(SBCONST*(1000000.0f/(float)(sb_timei-256)));
  17.295 -        else              sblatchi=SBCONST*(256-sb_timei);
  17.296 -}
  17.297 -
  17.298 -void outmidi(uint8_t v)
  17.299 -{
  17.300 -        printf("Write MIDI %02X\n",v);
  17.301 -}
  17.302 -
  17.303 -void setsbtype(int type)
  17.304 -{
  17.305 -        sbtype=type;
  17.306 -        sbstereo=0;
  17.307 -        sb_mixer_set();
  17.308 -        if (sbtype==SB16) sb_commands[8]=1;
  17.309 -        else              sb_commands[8]=-1;
  17.310 -}
  17.311 -
  17.312 -
  17.313 -
  17.314 -
  17.315 -
  17.316 -
  17.317 -
  17.318 -void sb_add_data(uint8_t v)
  17.319 -{
  17.320 -        sb_read_data[sb_read_wp++]=v;
  17.321 -        sb_read_wp&=0xFF;
  17.322 -}
  17.323 -
  17.324 -#define ADPCM_4  1
  17.325 -#define ADPCM_26 2
  17.326 -#define ADPCM_2  3
  17.327 -
  17.328 -void sb_start_dma(int dma8, int autoinit, uint8_t format, int len)
  17.329 -{
  17.330 -        if (dma8)
  17.331 -        {
  17.332 -                sb_8_length=len;
  17.333 -                sb_8_format=format;
  17.334 -                sb_8_autoinit=autoinit;
  17.335 -                sb_8_pause=0;
  17.336 -                sb_8_enable=1;
  17.337 -                if (sb_16_enable && sb_16_output) sb_16_enable = 0;
  17.338 -                sb_8_output=1;
  17.339 -                sbenable=sb_8_enable;
  17.340 -                sbleftright=0;
  17.341 -                sbdacpos=0;
  17.342 -//                pclog("Start 8-bit DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len);
  17.343 -        }
  17.344 -        else
  17.345 -        {
  17.346 -                sb_16_length=len;
  17.347 -                sb_16_format=format;
  17.348 -                sb_16_autoinit=autoinit;
  17.349 -                sb_16_pause=0;
  17.350 -                sb_16_enable=1;
  17.351 -                if (sb_8_enable && sb_8_output) sb_8_enable = 0;
  17.352 -                sb_16_output=1;
  17.353 -                sbenable=sb_16_enable;
  17.354 -//                pclog("Start 16-bit DMA addr %06X len %04X\n",dma16.ac[1]+(dma16.page[1]<<16),len);
  17.355 -        }
  17.356 -}
  17.357 -
  17.358 -void sb_start_dma_i(int dma8, int autoinit, uint8_t format, int len)
  17.359 -{
  17.360 -        if (dma8)
  17.361 -        {
  17.362 -                sb_8_length=len;
  17.363 -                sb_8_format=format;
  17.364 -                sb_8_autoinit=autoinit;
  17.365 -                sb_8_pause=0;
  17.366 -                sb_8_enable=1;
  17.367 -                if (sb_16_enable && !sb_16_output) sb_16_enable = 0;                
  17.368 -                sb_8_output=0;
  17.369 -                sb_enable_i=sb_8_enable;
  17.370 -//                pclog("Start 8-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len);
  17.371 -        }
  17.372 -        else
  17.373 -        {
  17.374 -                sb_16_length=len;
  17.375 -                sb_16_format=format;
  17.376 -                sb_16_autoinit=autoinit;
  17.377 -                sb_16_pause=0;
  17.378 -                sb_16_enable=1;
  17.379 -                if (sb_8_enable && !sb_8_output) sb_8_enable = 0;                
  17.380 -                sb_16_output=0;
  17.381 -                sb_enable_i=sb_16_enable;
  17.382 -//                pclog("Start 16-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len);
  17.383 -        }
  17.384 -}
  17.385 -
  17.386 -uint8_t sb_8_read_dma()
  17.387 -{
  17.388 -        return readdma1();
  17.389 -}
  17.390 -void sb_8_write_dma(uint8_t val)
  17.391 -{
  17.392 -        writedma1(val);
  17.393 -}
  17.394 -uint16_t sb_16_read_dma()
  17.395 -{
  17.396 -        return readdma5();
  17.397 -}
  17.398 -void sb_16_write_dma(uint16_t val)
  17.399 -{
  17.400 -        writedma5(val);
  17.401 -}
  17.402 -
  17.403 -void sb_exec_command()
  17.404 -{
  17.405 -        int temp,c;
  17.406 -//        pclog("SB command %02X\n",sb_command);
  17.407 -        switch (sb_command)
  17.408 -        {
  17.409 -                case 0x10: /*8-bit direct mode*/
  17.410 -                sbdat=sbdatl=sbdatr=(sb_data[0]^0x80)<<8;
  17.411 -                break;
  17.412 -                case 0x14: /*8-bit single cycle DMA output*/
  17.413 -                sb_start_dma(1,0,0,sb_data[0]+(sb_data[1]<<8));
  17.414 -                break;
  17.415 -                case 0x17: /*2-bit ADPCM output with reference*/
  17.416 -                sbref=sb_8_read_dma();
  17.417 -                sbstep=0;
  17.418 -//                pclog("Ref byte 2 %02X\n",sbref);
  17.419 -                case 0x16: /*2-bit ADPCM output*/
  17.420 -                sb_start_dma(1,0,ADPCM_2,sb_data[0]+(sb_data[1]<<8));
  17.421 -                sbdat2=sb_8_read_dma();
  17.422 -                sb_8_length--;
  17.423 -                break;
  17.424 -                case 0x1C: /*8-bit autoinit DMA output*/
  17.425 -                if (sbtype<SB15) break;
  17.426 -                sb_start_dma(1,1,0,sb_8_autolen);
  17.427 -                break;
  17.428 -                case 0x1F: /*2-bit ADPCM autoinit output*/
  17.429 -                if (sbtype<SB15) break;
  17.430 -                sb_start_dma(1,1,ADPCM_2,sb_data[0]+(sb_data[1]<<8));
  17.431 -                sbdat2=sb_8_read_dma();
  17.432 -                sb_8_length--;
  17.433 -                break;
  17.434 -                case 0x20: /*8-bit direct input*/
  17.435 -                sb_add_data(0);
  17.436 -                break;
  17.437 -                case 0x24: /*8-bit single cycle DMA input*/
  17.438 -                sb_start_dma_i(1,0,0,sb_data[0]+(sb_data[1]<<8));
  17.439 -                break;
  17.440 -                case 0x2C: /*8-bit autoinit DMA input*/
  17.441 -                if (sbtype<SB15) break;
  17.442 -                sb_start_dma_i(1,1,0,sb_data[0]+(sb_data[1]<<8));
  17.443 -                break;
  17.444 -                case 0x40: /*Set time constant*/
  17.445 -                sb_timei=sb_timeo=sb_data[0];
  17.446 -                sblatcho=sblatchi=SBCONST*(256-sb_data[0]);
  17.447 -                temp=256-sb_data[0];
  17.448 -                temp=1000000/temp;
  17.449 -//                printf("Sample rate - %ihz (%i)\n",temp, sblatcho);
  17.450 -                sb_freq=temp;
  17.451 -                break;
  17.452 -                case 0x41: /*Set output sampling rate*/
  17.453 -                if (sbtype<SB16) break;
  17.454 -                sblatcho=(int)(SBCONST*(1000000.0f/(float)(sb_data[1]+(sb_data[0]<<8))));
  17.455 -//                printf("Sample rate - %ihz (%i)\n",sb_data[1]+(sb_data[0]<<8), sblatcho);
  17.456 -                sb_freq=sb_data[1]+(sb_data[0]<<8);
  17.457 -                sb_timeo=256+sb_freq;
  17.458 -                break;
  17.459 -                case 0x42: /*Set input sampling rate*/
  17.460 -                if (sbtype<SB16) break;
  17.461 -                sblatchi=(int)(SBCONST*(1000000.0f/(float)(sb_data[1]+(sb_data[0]<<8))));
  17.462 -//                printf("iample rate - %ihz\n",sb_data[1]+(sb_data[0]<<8));
  17.463 -                sb_timei=256+sb_data[1]+(sb_data[0]<<8);
  17.464 -                break;
  17.465 -                case 0x48: /*Set DSP block transfer size*/
  17.466 -                sb_8_autolen=sb_data[0]+(sb_data[1]<<8);
  17.467 -                break;
  17.468 -                case 0x75: /*4-bit ADPCM output with reference*/
  17.469 -                sbref=sb_8_read_dma();
  17.470 -                sbstep=0;
  17.471 -//                pclog("Ref byte 4 %02X\n",sbref);
  17.472 -                case 0x74: /*4-bit ADPCM output*/
  17.473 -                sb_start_dma(1,0,ADPCM_4,sb_data[0]+(sb_data[1]<<8));
  17.474 -                sbdat2=sb_8_read_dma();
  17.475 -                sb_8_length--;
  17.476 -                break;
  17.477 -                case 0x77: /*2.6-bit ADPCM output with reference*/
  17.478 -                sbref=sb_8_read_dma();
  17.479 -                sbstep=0;
  17.480 -//                pclog("Ref byte 26 %02X\n",sbref);
  17.481 -                case 0x76: /*2.6-bit ADPCM output*/
  17.482 -                sb_start_dma(1,0,ADPCM_26,sb_data[0]+(sb_data[1]<<8));
  17.483 -                sbdat2=sb_8_read_dma();
  17.484 -                sb_8_length--;
  17.485 -                break;
  17.486 -                case 0x7D: /*4-bit ADPCM autoinit output*/
  17.487 -                if (sbtype<SB15) break;
  17.488 -                sb_start_dma(1,1,ADPCM_4,sb_data[0]+(sb_data[1]<<8));
  17.489 -                sbdat2=sb_8_read_dma();
  17.490 -                sb_8_length--;
  17.491 -                break;
  17.492 -                case 0x7F: /*2.6-bit ADPCM autoinit output*/
  17.493 -                if (sbtype<SB15) break;
  17.494 -                sb_start_dma(1,1,ADPCM_26,sb_data[0]+(sb_data[1]<<8));
  17.495 -                sbdat2=sb_8_read_dma();
  17.496 -                sb_8_length--;
  17.497 -                break;
  17.498 -                case 0x80: /*Pause DAC*/
  17.499 -                sb_pausetime=sb_data[0]+(sb_data[1]<<8);
  17.500 -//                pclog("SB pause %04X\n",sb_pausetime);
  17.501 -                sbenable=1;
  17.502 -                break;
  17.503 -                case 0x90: /*High speed 8-bit autoinit DMA output*/
  17.504 -                if (sbtype<SB2) break;
  17.505 -                sb_start_dma(1,1,0,sb_8_autolen);
  17.506 -                break;
  17.507 -                case 0x91: /*High speed 8-bit single cycle DMA output*/
  17.508 -                if (sbtype<SB2) break;
  17.509 -                sb_start_dma(1,0,0,sb_8_autolen);
  17.510 -                break;
  17.511 -                case 0x98: /*High speed 8-bit autoinit DMA input*/
  17.512 -                if (sbtype<SB2) break;
  17.513 -                sb_start_dma_i(1,1,0,sb_8_autolen);
  17.514 -                break;
  17.515 -                case 0x99: /*High speed 8-bit single cycle DMA input*/
  17.516 -                if (sbtype<SB2) break;
  17.517 -                sb_start_dma_i(1,0,0,sb_8_autolen);
  17.518 -                break;
  17.519 -                case 0xA0: /*Set input mode to mono*/
  17.520 -                case 0xA8: /*Set input mode to stereo*/
  17.521 -                break;
  17.522 -                case 0xB0: case 0xB1: case 0xB2: case 0xB3:
  17.523 -                case 0xB4: case 0xB5: case 0xB6: case 0xB7: /*16-bit DMA output*/
  17.524 -                if (sbtype<SB16) break;
  17.525 -                sb_start_dma(0,sb_command&4,sb_data[0],sb_data[1]+(sb_data[2]<<8));
  17.526 -                sb_16_autolen=sb_data[1]+(sb_data[2]<<8);
  17.527 -                break;
  17.528 -                case 0xB8: case 0xB9: case 0xBA: case 0xBB:
  17.529 -                case 0xBC: case 0xBD: case 0xBE: case 0xBF: /*16-bit DMA input*/
  17.530 -                if (sbtype<SB16) break;
  17.531 -                sb_start_dma_i(0,sb_command&4,sb_data[0],sb_data[1]+(sb_data[2]<<8));
  17.532 -                sb_16_autolen=sb_data[1]+(sb_data[2]<<8);
  17.533 -                break;
  17.534 -                case 0xC0: case 0xC1: case 0xC2: case 0xC3:
  17.535 -                case 0xC4: case 0xC5: case 0xC6: case 0xC7: /*8-bit DMA output*/
  17.536 -                if (sbtype<SB16) break;
  17.537 -                sb_start_dma(1,sb_command&4,sb_data[0],sb_data[1]+(sb_data[2]<<8));
  17.538 -                sb_8_autolen=sb_data[1]+(sb_data[2]<<8);
  17.539 -                break;
  17.540 -                case 0xC8: case 0xC9: case 0xCA: case 0xCB:
  17.541 -                case 0xCC: case 0xCD: case 0xCE: case 0xCF: /*8-bit DMA input*/
  17.542 -                if (sbtype<SB16) break;
  17.543 -                sb_start_dma_i(1,sb_command&4,sb_data[0],sb_data[1]+(sb_data[2]<<8));
  17.544 -                sb_8_autolen=sb_data[1]+(sb_data[2]<<8);
  17.545 -                break;
  17.546 -                case 0xD0: /*Pause 8-bit DMA*/
  17.547 -                sb_8_pause=1;
  17.548 -                break;
  17.549 -                case 0xD1: /*Speaker on*/
  17.550 -                sb_speaker=1;
  17.551 -                break;
  17.552 -                case 0xD3: /*Speaker off*/
  17.553 -                sb_speaker=0;
  17.554 -                break;
  17.555 -                case 0xD4: /*Continue 8-bit DMA*/
  17.556 -                sb_8_pause=0;
  17.557 -                break;
  17.558 -                case 0xD5: /*Pause 16-bit DMA*/
  17.559 -                if (sbtype<SB16) break;
  17.560 -                sb_16_pause=1;
  17.561 -                break;
  17.562 -                case 0xD6: /*Continue 16-bit DMA*/
  17.563 -                if (sbtype<SB16) break;
  17.564 -                sb_16_pause=0;
  17.565 -                break;
  17.566 -                case 0xD8: /*Get speaker status*/
  17.567 -                sb_add_data(sb_speaker?0xFF:0);
  17.568 -                break;
  17.569 -                case 0xD9: /*Exit 16-bit auto-init mode*/
  17.570 -                if (sbtype<SB16) break;
  17.571 -                sb_16_autoinit=0;
  17.572 -                break;
  17.573 -                case 0xDA: /*Exit 8-bit auto-init mode*/
  17.574 -                sb_8_autoinit=0;
  17.575 -                break;
  17.576 -                case 0xE0: /*DSP identification*/
  17.577 -                sb_add_data(~sb_data[0]);
  17.578 -                break;
  17.579 -                case 0xE1: /*Get DSP version*/
  17.580 -                sb_add_data(sb_dsp_versions[sbtype]>>8);
  17.581 -                sb_add_data(sb_dsp_versions[sbtype]&0xFF);
  17.582 -                break;
  17.583 -                case 0xE2: /*Stupid ID/protection*/
  17.584 -                for (c=0;c<8;c++)
  17.585 -                    if (sb_data[0]&(1<<c)) sbe2+=sbe2dat[sbe2count&3][c];
  17.586 -                sbe2+=sbe2dat[sbe2count&3][8];
  17.587 -                sbe2count++;
  17.588 -                sb_8_write_dma(sbe2);
  17.589 -                break;
  17.590 -                case 0xE3: /*DSP copyright*/
  17.591 -                if (sbtype<SB16) break;
  17.592 -                c=0;
  17.593 -                while (sb16_copyright[c])
  17.594 -                      sb_add_data(sb16_copyright[c++]);
  17.595 -                sb_add_data(0);
  17.596 -                break;
  17.597 -                case 0xE4: /*Write test register*/
  17.598 -                sb_test=sb_data[0];
  17.599 -                break;
  17.600 -                case 0xE8: /*Read test register*/
  17.601 -                sb_add_data(sb_test);
  17.602 -                break;
  17.603 -                case 0xF2: /*Trigger 8-bit IRQ*/
  17.604 -//                pclog("Trigger IRQ\n");
  17.605 -                sb_irq(1);
  17.606 -                break;
  17.607 -                case 0xE7: /*???*/
  17.608 -                case 0xFA: /*???*/
  17.609 -                break;
  17.610 -                case 0x07: /*No, that's not how you program auto-init DMA*/
  17.611 -                case 0xFF:
  17.612 -                break;
  17.613 -                case 0x08: /*ASP get version*/
  17.614 -                if (sbtype<SB16) break;
  17.615 -                sb_add_data(0x18);
  17.616 -                break;
  17.617 -                case 0x0E: /*ASP set register*/
  17.618 -                if (sbtype<SB16) break;
  17.619 -                sb_asp_regs[sb_data[0]] = sb_data[1];
  17.620 -//                pclog("ASP write reg %02X %02X\n", sb_data[0], sb_data[1]);
  17.621 -                break;
  17.622 -                case 0x0F: /*ASP get register*/
  17.623 -                if (sbtype<SB16) break;
  17.624 -//                sb_add_data(0);
  17.625 -                sb_add_data(sb_asp_regs[sb_data[0]]);
  17.626 -//                pclog("ASP read reg %02X %02X\n", sb_data[0], sb_asp_regs[sb_data[0]]);
  17.627 -                break;
  17.628 -                case 0xF9:
  17.629 -                if (sbtype<SB16) break;
  17.630 -                if (sb_data[0] == 0x0e)      sb_add_data(0xff);
  17.631 -                else if (sb_data[0] == 0x0f) sb_add_data(0x07);
  17.632 -                else if (sb_data[0] == 0x37) sb_add_data(0x38);
  17.633 -                else                         sb_add_data(0x00);
  17.634 -                case 0x04:
  17.635 -                case 0x05:
  17.636 -                break;
  17.637 -//                default:
  17.638 -//                fatal("Exec bad SB command %02X\n",sb_command);
  17.639 -        }
  17.640 -}
  17.641 -        
  17.642 -void sb_write(uint16_t a, uint8_t v)
  17.643 -{
  17.644 -        int temp;
  17.645 -        int c;
  17.646 -//        printf("Write soundblaster %04X %02X %04X:%04X %02X\n",a,v,cs>>4,pc,sb_command);
  17.647 -        switch (a&0xF)
  17.648 -        {
  17.649 -                case 0: case 1: case 2: case 3: /*OPL or Gameblaster*/
  17.650 -                if (GAMEBLASTER && sbtype < SBPRO)
  17.651 -                   writecms(a, v);
  17.652 -                else if (sbtype >= SBPRO)
  17.653 -                   adlib_write(a,v); 
  17.654 -                return;
  17.655 -                case 4: mixerindex=v; return;
  17.656 -                case 5:
  17.657 -                sb_mixer[mixerindex]=v;
  17.658 -//                pclog("Write mixer data %02X %02X\n",mixerindex,sb_mixer[mixerindex]);
  17.659 -                if (sbtype==SB16)
  17.660 -                {
  17.661 -                        switch (mixerindex)
  17.662 -                        {
  17.663 -                                case 0x22:
  17.664 -                                sb_mixer[0x30]=((sb_mixer[0x22]>>4)|0x11)<<3;
  17.665 -                                sb_mixer[0x31]=((sb_mixer[0x22]&0xF)|0x11)<<3;
  17.666 -                                break;
  17.667 -                                case 0x04:
  17.668 -                                sb_mixer[0x32]=((sb_mixer[0x04]>>4)|0x11)<<3;
  17.669 -                                sb_mixer[0x33]=((sb_mixer[0x04]&0xF)|0x11)<<3;
  17.670 -                                break;
  17.671 -                                case 0x26:
  17.672 -                                sb_mixer[0x34]=((sb_mixer[0x26]>>4)|0x11)<<3;
  17.673 -                                sb_mixer[0x35]=((sb_mixer[0x26]&0xF)|0x11)<<3;
  17.674 -                                break;
  17.675 -                                case 0x80:
  17.676 -                                if (v & 1) sb_irqnum = 2;
  17.677 -                                if (v & 2) sb_irqnum = 5;
  17.678 -                                if (v & 4) sb_irqnum = 7;
  17.679 -                                if (v & 8) sb_irqnum = 10;
  17.680 -                                break;
  17.681 -                        }
  17.682 -                }
  17.683 -//                if (!mixerindex) sb_mixer_reset();
  17.684 -                sb_mixer_set();
  17.685 -                return;
  17.686 -                case 6: /*Reset*/
  17.687 -                if (!(v&1) && (sbreset&1))
  17.688 -                {
  17.689 -                        sb_dsp_reset();
  17.690 -                        sb_add_data(0xAA);
  17.691 -                }
  17.692 -                sbreset=v;
  17.693 -                return;
  17.694 -                case 8: case 9: adlib_write(a,v); return; /*OPL*/
  17.695 -                case 0xC: /*Command/data write*/
  17.696 -                if (sb_uart) return;
  17.697 -                if (sb_data_stat==-1)
  17.698 -                {
  17.699 -                        sb_command=v;
  17.700 -//                        if (sb_commands[v]==-1)
  17.701 -//                           fatal("Bad SB command %02X\n",v);
  17.702 -                        sb_data_stat++;
  17.703 -                }
  17.704 -                else
  17.705 -                   sb_data[sb_data_stat++]=v;
  17.706 -                if (sb_data_stat==sb_commands[sb_command] || sb_commands[sb_command]==-1)
  17.707 -                {
  17.708 -                        sb_exec_command();
  17.709 -                        sb_data_stat=-1;
  17.710 -                }
  17.711 -                break;
  17.712 -        }
  17.713 -}
  17.714 -
  17.715 -uint8_t sb_read(uint16_t a)
  17.716 -{
  17.717 -        uint8_t temp;
  17.718 -//        if (a==0x224) output=1;
  17.719 -//        printf("Read soundblaster %04X %04X:%04X\n",a,cs,pc);
  17.720 -        switch (a&0xF)
  17.721 -        {
  17.722 -                case 0: case 1: case 2: case 3: /*OPL or GameBlaster*/
  17.723 -                if (GAMEBLASTER && sbtype < SBPRO)
  17.724 -                   return readcms(a);
  17.725 -                return adlib_read(a); 
  17.726 -                break;
  17.727 -                case 5:
  17.728 -                if (sbtype<SBPRO) return 0;
  17.729 -//                pclog("Read mixer data %02X %02X\n",mixerindex,sb_mixer[mixerindex]);
  17.730 -                if (mixerindex==0x80 && sbtype>=SB16)
  17.731 -                {
  17.732 -                        switch (sb_irqnum)
  17.733 -                        {
  17.734 -                                case 2: return 1; /*IRQ 7*/
  17.735 -                                case 5: return 2; /*IRQ 7*/
  17.736 -                                case 7: return 4; /*IRQ 7*/
  17.737 -                                case 10: return 8; /*IRQ 7*/
  17.738 -                        }
  17.739 -                }
  17.740 -                if (mixerindex==0x81 && sbtype>=SB16) return 0x22; /*DMA 1 and 5*/
  17.741 -                if (mixerindex==0x82 && sbtype>=SB16) return ((sb_irq8)?1:0)|((sb_irq16)?2:0);
  17.742 -                return sb_mixer[mixerindex];
  17.743 -                case 8: case 9: return adlib_read(a); /*OPL*/
  17.744 -                case 0xA: /*Read data*/
  17.745 -                if (sb_uart) return;
  17.746 -                sbreaddat=sb_read_data[sb_read_rp];
  17.747 -                if (sb_read_rp!=sb_read_wp)
  17.748 -                {
  17.749 -                        sb_read_rp++;
  17.750 -                        sb_read_rp&=0xFF;
  17.751 -                }
  17.752 -//                pclog("SB read %02X\n",sbreaddat);
  17.753 -                return sbreaddat;
  17.754 -                case 0xC: /*Write data ready*/
  17.755 -                cycles-=100;
  17.756 -                writebusy++;
  17.757 -                if (writebusy&8) return 0xFF;
  17.758 -                return 0x7F;
  17.759 -                case 0xE: /*Read data ready*/
  17.760 -                picintc(1 << sb_irqnum);
  17.761 -                sb_irq8=sb_irq16=0;
  17.762 -                return (sb_read_rp==sb_read_wp)?0x7f:0xff;
  17.763 -                case 0xF: /*16-bit ack*/
  17.764 -                sb_irq16=0;
  17.765 -                if (!sb_irq8) picintc(1 << sb_irqnum);
  17.766 -                return 0xff;
  17.767 -        }
  17.768 -        return 0;
  17.769 -}
  17.770 -
  17.771 -void sb_init()
  17.772 -{
  17.773 -        int c;
  17.774 -        
  17.775 -        sb_reset();
  17.776 -        
  17.777 -        io_sethandler(0x0220, 0x0010, sb_read, NULL, NULL, sb_write, NULL, NULL);
  17.778 -}
  17.779 -
  17.780 -
  17.781 -int sbshift4[8]={-2,-1,0,0,1,1,1,1};
  17.782 -void pollsb()
  17.783 -{
  17.784 -        int tempi,ref;
  17.785 -//        pclog("PollSB %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output);
  17.786 -        if (sb_8_enable && !sb_8_pause && sb_pausetime<0 && sb_8_output)
  17.787 -        {
  17.788 -//                pclog("Dopoll %i %02X %i\n", sb_8_length, sb_8_format, sblatcho);
  17.789 -                switch (sb_8_format)
  17.790 -                {
  17.791 -                        case 0x00: /*Mono unsigned*/
  17.792 -                        sbdat=(sb_8_read_dma()^0x80)<<8;
  17.793 -                        if (sbtype>=SBPRO && sbtype<SB16 && sb_mixer[0xE]&2)
  17.794 -                        {
  17.795 -                                if (sbleftright) sbdatl=sbdat;
  17.796 -                                else             sbdatr=sbdat;
  17.797 -                                sbleftright=!sbleftright;
  17.798 -                        }
  17.799 -                        else
  17.800 -                           sbdatl=sbdatr=sbdat;
  17.801 -                        sb_8_length--;
  17.802 -                        break;
  17.803 -                        case 0x10: /*Mono signed*/
  17.804 -                        sbdat=sb_8_read_dma()<<8;
  17.805 -                        if (sbtype>=SBPRO && sbtype<SB16 && sb_mixer[0xE]&2)
  17.806 -                        {
  17.807 -                                if (sbleftright) sbdatl=sbdat;
  17.808 -                                else             sbdatr=sbdat;
  17.809 -                                sbleftright=!sbleftright;
  17.810 -                        }
  17.811 -                        else
  17.812 -                           sbdatl=sbdatr=sbdat;
  17.813 -                        sb_8_length--;
  17.814 -                        break;
  17.815 -                        case 0x20: /*Stereo unsigned*/
  17.816 -                        sbdatl=(sb_8_read_dma()^0x80)<<8;
  17.817 -                        sbdatr=(sb_8_read_dma()^0x80)<<8;
  17.818 -                        sb_8_length-=2;
  17.819 -                        break;
  17.820 -                        case 0x30: /*Stereo signed*/
  17.821 -                        sbdatl=sb_8_read_dma()<<8;
  17.822 -                        sbdatr=sb_8_read_dma()<<8;
  17.823 -                        sb_8_length-=2;
  17.824 -                        break;
  17.825 -
  17.826 -                        case ADPCM_4:
  17.827 -                        if (sbdacpos) tempi=(sbdat2&0xF)+sbstep;
  17.828 -                        else          tempi=(sbdat2>>4)+sbstep;
  17.829 -                        if (tempi<0) tempi=0;
  17.830 -                        if (tempi>63) tempi=63;
  17.831 -
  17.832 -                        ref = sbref + scaleMap4[tempi];
  17.833 -                        if (ref > 0xff) sbref = 0xff;
  17.834 -                        else if (ref < 0x00) sbref = 0x00;
  17.835 -                        else sbref = ref;
  17.836 -
  17.837 -                        sbstep = (sbstep + adjustMap4[tempi]) & 0xff;
  17.838 -
  17.839 -                        sbdat=(sbref^0x80)<<8;
  17.840 -
  17.841 -                        sbdacpos++;
  17.842 -                        if (sbdacpos>=2)
  17.843 -                        {
  17.844 -                                sbdacpos=0;
  17.845 -                                sbdat2=sb_8_read_dma();
  17.846 -                                sb_8_length--;
  17.847 -                        }
  17.848 -
  17.849 -                        if (sbtype>=SBPRO && sbtype<SB16 && sb_mixer[0xE]&2)
  17.850 -                        {
  17.851 -                                if (sbleftright) sbdatl=sbdat;
  17.852 -                                else             sbdatr=sbdat;
  17.853 -                                sbleftright=!sbleftright;
  17.854 -                        }
  17.855 -                        else
  17.856 -                           sbdatl=sbdatr=sbdat;
  17.857 -                        break;
  17.858 -                        
  17.859 -                        case ADPCM_26:
  17.860 -                        if (!sbdacpos)        tempi=(sbdat2>>5)+sbstep;
  17.861 -                        else if (sbdacpos==1) tempi=((sbdat2>>2)&7)+sbstep;
  17.862 -                        else                  tempi=((sbdat2<<1)&7)+sbstep;
  17.863 -
  17.864 -                        if (tempi<0) tempi=0;
  17.865 -                        if (tempi>39) tempi=39;
  17.866 -
  17.867 -                        ref = sbref + scaleMap26[tempi];
  17.868 -                        if (ref > 0xff) sbref = 0xff;
  17.869 -                        else if (ref < 0x00) sbref = 0x00;
  17.870 -                        else sbref = ref;
  17.871 -                        sbstep = (sbstep + adjustMap26[tempi]) & 0xff;
  17.872 -
  17.873 -                        sbdat=(sbref^0x80)<<8;
  17.874 -
  17.875 -                        sbdacpos++;
  17.876 -                        if (sbdacpos>=3)
  17.877 -                        {
  17.878 -                                sbdacpos=0;
  17.879 -                                sbdat2=readdma1();
  17.880 -                                sb_8_length--;
  17.881 -                        }
  17.882 -
  17.883 -                        if (sbtype>=SBPRO && sbtype<SB16 && sb_mixer[0xE]&2)
  17.884 -                        {
  17.885 -                                if (sbleftright) sbdatl=sbdat;
  17.886 -                                else             sbdatr=sbdat;
  17.887 -                                sbleftright=!sbleftright;
  17.888 -                        }
  17.889 -                        else
  17.890 -                           sbdatl=sbdatr=sbdat;
  17.891 -                        break;
  17.892 -
  17.893 -                        case ADPCM_2:
  17.894 -                        tempi=((sbdat2>>((3-sbdacpos)*2))&3)+sbstep;
  17.895 -                        if (tempi<0) tempi=0;
  17.896 -                        if (tempi>23) tempi=23;
  17.897 -
  17.898 -                        ref = sbref + scaleMap2[tempi];
  17.899 -                        if (ref > 0xff) sbref = 0xff;
  17.900 -                        else if (ref < 0x00) sbref = 0x00;
  17.901 -                        else sbref = ref;
  17.902 -                        sbstep = (sbstep + adjustMap2[tempi]) & 0xff;
  17.903 -                        
  17.904 -                        sbdat=(sbref^0x80)<<8;
  17.905 -
  17.906 -                        sbdacpos++;
  17.907 -                        if (sbdacpos>=4)
  17.908 -                        {
  17.909 -                                sbdacpos=0;
  17.910 -                                sbdat2=readdma1();
  17.911 -                        }
  17.912 -
  17.913 -                        if (sbtype>=SBPRO && sbtype<SB16 && sb_mixer[0xE]&2)
  17.914 -                        {
  17.915 -                                if (sbleftright) sbdatl=sbdat;
  17.916 -                                else             sbdatr=sbdat;
  17.917 -                                sbleftright=!sbleftright;
  17.918 -                        }
  17.919 -                        else
  17.920 -                           sbdatl=sbdatr=sbdat;
  17.921 -                        break;
  17.922 -
  17.923 -//                        default:
  17.924 -                                //fatal("Unrecognised SB 8-bit format %02X\n",sb_8_format);
  17.925 -                }
  17.926 -                
  17.927 -                if (sb_8_length<0)
  17.928 -                {
  17.929 -//                        pclog("DMA over %i %i\n", sb_8_autoinit, sb_irqnum);
  17.930 -                        if (sb_8_autoinit) sb_8_length=sb_8_autolen;
  17.931 -                        else               sb_8_enable=sbenable=0;
  17.932 -                        sb_irq(1);
  17.933 -                }
  17.934 -        }
  17.935 -        if (sb_16_enable && !sb_16_pause && sb_pausetime<0 && sb_16_output)
  17.936 -        {
  17.937 -                switch (sb_16_format)
  17.938 -                {
  17.939 -                        case 0x00: /*Mono unsigned*/
  17.940 -                        sbdatl=sbdatr=sb_16_read_dma()^0x8000;
  17.941 -                        sb_16_length--;
  17.942 -                        break;
  17.943 -                        case 0x10: /*Mono signed*/
  17.944 -                        sbdatl=sbdatr=sb_16_read_dma();
  17.945 -                        sb_16_length--;
  17.946 -                        break;
  17.947 -                        case 0x20: /*Stereo unsigned*/
  17.948 -                        sbdatl=sb_16_read_dma()^0x8000;
  17.949 -                        sbdatr=sb_16_read_dma()^0x8000;
  17.950 -                        sb_16_length-=2;
  17.951 -                        break;
  17.952 -                        case 0x30: /*Stereo signed*/
  17.953 -                        sbdatl=sb_16_read_dma();
  17.954 -                        sbdatr=sb_16_read_dma();
  17.955 -                        sb_16_length-=2;
  17.956 -                        break;
  17.957 -
  17.958 -//                        default:
  17.959 -//                                fatal("Unrecognised SB 16-bit format %02X\n",sb_16_format);
  17.960 -                }
  17.961 -
  17.962 -                if (sb_16_length<0)
  17.963 -                {
  17.964 -//                        pclog("16DMA over %i\n",sb_16_autoinit);
  17.965 -                        if (sb_16_autoinit) sb_16_length=sb_16_autolen;
  17.966 -                        else                sb_16_enable=sbenable=0;
  17.967 -                        sb_irq(0);
  17.968 -                }
  17.969 -        }
  17.970 -        if (sb_pausetime>-1)
  17.971 -        {
  17.972 -                sb_pausetime--;
  17.973 -                if (sb_pausetime<0)
  17.974 -                {
  17.975 -                        sb_irq(1);
  17.976 -                        sbenable=sb_8_enable;
  17.977 -                        pclog("SB pause over\n");
  17.978 -                }
  17.979 -        }
  17.980 -}
  17.981 -
  17.982 -void sb_poll_i()
  17.983 -{
  17.984 -//        pclog("PollSBi %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output);        
  17.985 -        if (sb_8_enable && !sb_8_pause && sb_pausetime<0 && !sb_8_output)
  17.986 -        {
  17.987 -                switch (sb_8_format)
  17.988 -                {
  17.989 -                        case 0x00: /*Mono unsigned*/
  17.990 -                        sb_8_write_dma(0x80);
  17.991 -                        sb_8_length--;
  17.992 -                        break;
  17.993 -                        case 0x10: /*Mono signed*/
  17.994 -                        sb_8_write_dma(0x00);
  17.995 -                        sb_8_length--;
  17.996 -                        break;
  17.997 -                        case 0x20: /*Stereo unsigned*/
  17.998 -                        sb_8_write_dma(0x80);
  17.999 -                        sb_8_write_dma(0x80);
 17.1000 -                        sb_8_length-=2;
 17.1001 -                        break;
 17.1002 -                        case 0x30: /*Stereo signed*/
 17.1003 -                        sb_8_write_dma(0x00);
 17.1004 -                        sb_8_write_dma(0x00);
 17.1005 -                        sb_8_length-=2;
 17.1006 -                        break;
 17.1007 -
 17.1008 -//                        default:
 17.1009 -//                                fatal("Unrecognised SB 8-bit input format %02X\n",sb_8_format);
 17.1010 -                }
 17.1011 -                
 17.1012 -                if (sb_8_length<0)
 17.1013 -                {
 17.1014 -//                        pclog("Input DMA over %i\n",sb_8_autoinit);
 17.1015 -                        if (sb_8_autoinit) sb_8_length=sb_8_autolen;
 17.1016 -                        else               sb_8_enable=sbenable=0;
 17.1017 -                        sb_irq(1);
 17.1018 -                }
 17.1019 -        }
 17.1020 -        if (sb_16_enable && !sb_16_pause && sb_pausetime<0 && !sb_16_output)
 17.1021 -        {
 17.1022 -                switch (sb_16_format)
 17.1023 -                {
 17.1024 -                        case 0x00: /*Unsigned mono*/
 17.1025 -                        sb_16_write_dma(0x8000);
 17.1026 -                        sb_16_length--;
 17.1027 -                        break;
 17.1028 -                        case 0x10: /*Signed mono*/
 17.1029 -                        sb_16_write_dma(0);
 17.1030 -                        sb_16_length--;
 17.1031 -                        break;
 17.1032 -                        case 0x20: /*Unsigned stereo*/
 17.1033 -                        sb_16_write_dma(0x8000);
 17.1034 -                        sb_16_write_dma(0x8000);
 17.1035 -                        sb_16_length-=2;
 17.1036 -                        break;
 17.1037 -                        case 0x30: /*Signed stereo*/
 17.1038 -                        sb_16_write_dma(0);
 17.1039 -                        sb_16_write_dma(0);
 17.1040 -                        sb_16_length-=2;
 17.1041 -                        break;
 17.1042 -                        
 17.1043 -//                        default:
 17.1044 -//                                fatal("Unrecognised SB 16-bit input format %02X\n",sb_16_format);
 17.1045 -                }
 17.1046 -                
 17.1047 -                if (sb_16_length<0)
 17.1048 -                {
 17.1049 -//                        pclog("16iDMA over %i\n",sb_16_autoinit);
 17.1050 -                        if (sb_16_autoinit) sb_16_length=sb_16_autolen;
 17.1051 -                        else                sb_16_enable=sbenable=0;
 17.1052 -                        sb_irq(0);
 17.1053 -                }
 17.1054 -        }
 17.1055 -}
 17.1056 -
 17.1057 -int16_t sbbuffer[2][SOUNDBUFLEN+20];
 17.1058 -int sbbufferpos=0;
 17.1059 -int _sampcnt=0;
 17.1060 -int16_t sb_filtbuf[4]={0,0,0,0};
 17.1061 -void getsbsamp()
 17.1062 -{
 17.1063 -        int vocl=sbpmixer.vocl*sbpmixer.masl;
 17.1064 -        int vocr=sbpmixer.vocr*sbpmixer.masr;
 17.1065 -        int16_t sbdat[2];
 17.1066 -        double t;
 17.1067 -        
 17.1068 -        vocl=256-vocl;
 17.1069 -        vocr=256-vocr;
 17.1070 -        if (!vocl) vocl=1;
 17.1071 -        if (!vocr) vocr=1;
 17.1072 -        if (sbbufferpos>=(SOUNDBUFLEN+20)) return;
 17.1073 -        
 17.1074 -        sbdat[0]=sbdatl;
 17.1075 -        sbdat[1]=sbdatr;
 17.1076 -
 17.1077 -        if (mixer.filter)
 17.1078 -        {
 17.1079 -                /*3.2kHz output filter*/
 17.1080 -                sbdat[0]=(int16_t)(sb_iir(0,(float)sbdat[0])/1.3);
 17.1081 -                sbdat[1]=(int16_t)(sb_iir(1,(float)sbdat[1])/1.3);
 17.1082 -        }
 17.1083 -
 17.1084 -        sbbuffer[0][sbbufferpos]=sbdat[0];
 17.1085 -        sbbuffer[1][sbbufferpos]=sbdat[1];
 17.1086 -        sbbufferpos++;
 17.1087 -}
 17.1088 -
 17.1089 -void addsb(int16_t *p)
 17.1090 -{
 17.1091 -        int c;
 17.1092 -        if (sbbufferpos>SOUNDBUFLEN) sbbufferpos=SOUNDBUFLEN;
 17.1093 -//        printf("Addsb - %i %04X\n",sbbufferpos,p[0]);
 17.1094 -        for (c=0;c<sbbufferpos;c++)
 17.1095 -        {
 17.1096 -                p[c<<1]+=(((sbbuffer[0][c]/3)*mixer.voice_l)>>16);
 17.1097 -                p[(c<<1)+1]+=(((sbbuffer[1][c]/3)*mixer.voice_r)>>16);
 17.1098 -//                if (!c) pclog("V %04X %04X %04X\n",sbbuffer[0][c],p[c<<1],mixer.voice_l);
 17.1099 -        }
 17.1100 -        for (;c<SOUNDBUFLEN;c++)
 17.1101 -        {
 17.1102 -                p[c<<1]+=(((sbbuffer[0][sbbufferpos-1]/3)*mixer.voice_l)>>16);
 17.1103 -                p[(c<<1)+1]+=(((sbbuffer[0][sbbufferpos-1]/3)*mixer.voice_l)>>16);
 17.1104 -        }
 17.1105 -        sbbufferpos=0;
 17.1106 -}
 17.1107 -
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/sound_adlib.c	Mon May 27 19:56:33 2013 +0100
    18.3 @@ -0,0 +1,62 @@
    18.4 +#include <stdlib.h>
    18.5 +#include "ibm.h"
    18.6 +#include "device.h"
    18.7 +#include "sound.h"
    18.8 +
    18.9 +#include "sound_adlib.h"
   18.10 +#include "sound_opl.h"
   18.11 +
   18.12 +typedef struct adlib_t
   18.13 +{
   18.14 +        opl_t   opl;
   18.15 +        int16_t buffer[SOUNDBUFLEN * 2];
   18.16 +        int     pos;
   18.17 +} adlib_t;
   18.18 +
   18.19 +static void adlib_poll(void *p)
   18.20 +{
   18.21 +        adlib_t *adlib = (adlib_t *)p;
   18.22 +        
   18.23 +        if (adlib->pos >= SOUNDBUFLEN) return;
   18.24 +        
   18.25 +        opl2_poll(&adlib->opl, &adlib->buffer[adlib->pos * 2], &adlib->buffer[(adlib->pos * 2) + 1]);
   18.26 +        adlib->pos++;
   18.27 +}
   18.28 +
   18.29 +static void adlib_get_buffer(int16_t *buffer, int len, void *p)
   18.30 +{
   18.31 +        adlib_t *adlib = (adlib_t *)p;
   18.32 +        int c;
   18.33 +
   18.34 +        for (c = 0; c < len * 2; c++)
   18.35 +                buffer[c] += adlib->buffer[c];
   18.36 +
   18.37 +        adlib->pos = 0;
   18.38 +}
   18.39 +
   18.40 +void *adlib_init()
   18.41 +{
   18.42 +        adlib_t *adlib = malloc(sizeof(adlib_t));
   18.43 +        memset(adlib, 0, sizeof(adlib_t));
   18.44 +        
   18.45 +        pclog("adlib_init\n");
   18.46 +        opl2_init(&adlib->opl);
   18.47 +        io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl);
   18.48 +        sound_add_handler(adlib_poll, adlib_get_buffer, adlib);
   18.49 +        return adlib;
   18.50 +}
   18.51 +
   18.52 +void adlib_close(void *p)
   18.53 +{
   18.54 +        adlib_t *adlib = (adlib_t *)p;
   18.55 +
   18.56 +        free(adlib);
   18.57 +}
   18.58 +
   18.59 +device_t adlib_device =
   18.60 +{
   18.61 +        "AdLib",
   18.62 +        adlib_init,
   18.63 +        adlib_close,
   18.64 +        NULL
   18.65 +};
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/sound_adlib.h	Mon May 27 19:56:33 2013 +0100
    19.3 @@ -0,0 +1,1 @@
    19.4 +extern device_t adlib_device;
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/sound_adlibgold.c	Mon May 27 19:56:33 2013 +0100
    20.3 @@ -0,0 +1,597 @@
    20.4 +#include <stdlib.h>
    20.5 +#include <string.h>
    20.6 +#include "ibm.h"
    20.7 +#include "device.h"
    20.8 +
    20.9 +#include "sound_opl.h"
   20.10 +#include "dma.h"
   20.11 +#include "io.h"
   20.12 +#include "pic.h"
   20.13 +#include "pit.h"
   20.14 +#include "timer.h"
   20.15 +
   20.16 +void adgold_timer_poll();
   20.17 +
   20.18 +typedef struct adgold_t
   20.19 +{
   20.20 +        int adgold_irq_status;
   20.21 +
   20.22 +        uint8_t adgold_eeprom[0x19];
   20.23 +
   20.24 +        uint8_t adgold_status;
   20.25 +        int adgold_38x_state, adgold_38x_addr;
   20.26 +        uint8_t adgold_38x_regs[0x19];
   20.27 +
   20.28 +        int adgold_mma_addr;
   20.29 +        uint8_t adgold_mma_regs[2][0xe];
   20.30 +
   20.31 +        int adgold_mma_enable[2];
   20.32 +        uint8_t adgold_mma_fifo[2][256];
   20.33 +        int adgold_mma_fifo_start[2], adgold_mma_fifo_end[2];
   20.34 +        uint8_t adgold_mma_status;
   20.35 +
   20.36 +        int16_t adgold_mma_out[2];
   20.37 +        int adgold_mma_intpos[2];
   20.38 +
   20.39 +        int adgold_mma_timer_count;
   20.40 +
   20.41 +        struct
   20.42 +        {
   20.43 +                int timer0_latch, timer0_count;
   20.44 +                int timerbase_latch, timerbase_count;
   20.45 +                int timer1_latch, timer1_count;
   20.46 +                int timer2_latch, timer2_count, timer2_read;
   20.47 +        
   20.48 +                int voice_count[2], voice_latch[2];
   20.49 +        } adgold_mma;
   20.50 +
   20.51 +        opl_t    opl;
   20.52 +
   20.53 +        int16_t opl_buffer[SOUNDBUFLEN * 2];
   20.54 +        int16_t mma_buffer[2][SOUNDBUFLEN];
   20.55 +
   20.56 +        int pos;
   20.57 +} adgold_t;
   20.58 +
   20.59 +void adgold_update_irq_status(adgold_t *adgold)
   20.60 +{
   20.61 +        uint8_t temp = 0xf;
   20.62 +
   20.63 +        if (!(adgold->adgold_mma_regs[0][8] & 0x10) && (adgold->adgold_mma_status & 0x10))      /*Timer 0*/
   20.64 +                temp &= ~2;
   20.65 +        if (!(adgold->adgold_mma_regs[0][8] & 0x20) && (adgold->adgold_mma_status & 0x20))      /*Timer 1*/
   20.66 +                temp &= ~2;
   20.67 +        if (!(adgold->adgold_mma_regs[0][8] & 0x40) && (adgold->adgold_mma_status & 0x40))      /*Timer 2*/
   20.68 +                temp &= ~2;
   20.69 +
   20.70 +        if ((adgold->adgold_mma_status & 0x01) &&  !(adgold->adgold_mma_regs[0][0xc] & 2))
   20.71 +                temp &= ~2;
   20.72 +        if ((adgold->adgold_mma_status & 0x02) &&  !(adgold->adgold_mma_regs[1][0xc] & 2))
   20.73 +                temp &= ~2;
   20.74 +        adgold->adgold_status = temp;
   20.75 +        
   20.76 +        if ((adgold->adgold_status ^ 0xf) && !adgold->adgold_irq_status)
   20.77 +        {
   20.78 +                pclog("adgold irq %02X\n", adgold->adgold_status);
   20.79 +                picint(0x80);
   20.80 +        }
   20.81 +                
   20.82 +        adgold->adgold_irq_status = adgold->adgold_status ^ 0xf;
   20.83 +}
   20.84 +
   20.85 +void adgold_getsamp_dma(adgold_t *adgold, int channel)
   20.86 +{
   20.87 +        int temp;
   20.88 +        
   20.89 +        if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127))
   20.90 +                return;
   20.91 +                
   20.92 +        temp = readdma1();
   20.93 +//        pclog("adgold DMA1 return %02X %i L\n", temp, channel);
   20.94 +        if (temp == -1) return;
   20.95 +        adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp;
   20.96 +        adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;
   20.97 +        if (adgold->adgold_mma_regs[channel][0xc] & 0x60)
   20.98 +        {
   20.99 +                temp = readdma1();
  20.100 +//                pclog("adgold DMA1 return %02X %i H\n", temp, channel);
  20.101 +                adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp;
  20.102 +                adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;
  20.103 +        }      
  20.104 +        if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= adgold->adgold_mma_intpos[channel])
  20.105 +        {
  20.106 +                adgold->adgold_mma_status &= ~(0x01 << channel);
  20.107 +                adgold_update_irq_status(adgold);
  20.108 +        }
  20.109 +}
  20.110 +
  20.111 +void adgold_write(uint16_t addr, uint8_t val, void *p)
  20.112 +{
  20.113 +        adgold_t *adgold = (adgold_t *)p;
  20.114 +        if (addr > 0x389) pclog("adgold_write : addr %04X val %02X %04X:%04X\n", addr, val, CS, pc);
  20.115 +        switch (addr & 7)
  20.116 +        {
  20.117 +                case 0: case 1:
  20.118 +                opl3_write(addr, val, &adgold->opl);
  20.119 +                break;
  20.120 +
  20.121 +                case 2:
  20.122 +                if (val == 0xff)
  20.123 +                {
  20.124 +                        adgold->adgold_38x_state = 1;
  20.125 +                        return;
  20.126 +                }
  20.127 +                if (val == 0xfe)
  20.128 +                {                
  20.129 +                        adgold->adgold_38x_state = 0;
  20.130 +                        return;
  20.131 +                }
  20.132 +                if (adgold->adgold_38x_state)   /*Write to control chip*/
  20.133 +                        adgold->adgold_38x_addr = val;
  20.134 +                else
  20.135 +                        opl3_write(addr, val, &adgold->opl);
  20.136 +                break;
  20.137 +                case 3:
  20.138 +                if (adgold->adgold_38x_state)
  20.139 +                {
  20.140 +                        if (adgold->adgold_38x_addr >= 0x19) break;
  20.141 +                        switch (adgold->adgold_38x_addr)
  20.142 +                        {
  20.143 +                                case 0x00: /*Control/ID*/
  20.144 +                                if (val & 1)
  20.145 +                                        memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19);
  20.146 +                                if (val & 2)
  20.147 +                                        memcpy(adgold->adgold_eeprom, adgold->adgold_38x_regs, 0x19);
  20.148 +                                break;
  20.149 +                                
  20.150 +                                default:
  20.151 +                                adgold->adgold_38x_regs[adgold->adgold_38x_addr] = val;
  20.152 +                                break;
  20.153 +                        }
  20.154 +                }
  20.155 +                else
  20.156 +                        opl3_write(addr, val, &adgold->opl);
  20.157 +                break;
  20.158 +                case 4: case 6:
  20.159 +                adgold->adgold_mma_addr = val;
  20.160 +                break;
  20.161 +                case 5:
  20.162 +                if (adgold->adgold_mma_addr >= 0xf) break;
  20.163 +                switch (adgold->adgold_mma_addr)
  20.164 +                {
  20.165 +                        case 0x2:
  20.166 +                        adgold->adgold_mma.timer0_latch = (adgold->adgold_mma.timer0_latch & 0xff00) | val;
  20.167 +                        break;
  20.168 +                        case 0x3:
  20.169 +                        adgold->adgold_mma.timer0_latch = (adgold->adgold_mma.timer0_latch & 0xff) | (val << 8);
  20.170 +                        break;
  20.171 +                        case 0x4:
  20.172 +                        adgold->adgold_mma.timerbase_latch = (adgold->adgold_mma.timerbase_latch & 0xf00) | val;
  20.173 +                        break;
  20.174 +                        case 0x5:
  20.175 +                        adgold->adgold_mma.timerbase_latch = (adgold->adgold_mma.timerbase_latch & 0xff) | ((val & 0xf) << 8);
  20.176 +                        adgold->adgold_mma.timer1_latch = val >> 4;
  20.177 +                        break;
  20.178 +                        case 0x6:
  20.179 +                        adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff00) | val;
  20.180 +                        break;
  20.181 +                        case 0x7:
  20.182 +                        adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff) | (val << 8);
  20.183 +                        break;
  20.184 +                        
  20.185 +                        case 0x8: 
  20.186 +                        if ((val & 1) && !(adgold->adgold_mma_regs[0][8] & 1)) /*Reload timer 0*/
  20.187 +                                adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch;
  20.188 +                                
  20.189 +                        if ((val & 2) && !(adgold->adgold_mma_regs[0][8] & 2)) /*Reload timer 1*/
  20.190 +                                adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch;
  20.191 +
  20.192 +                        if ((val & 4) && !(adgold->adgold_mma_regs[0][8] & 4)) /*Reload timer 2*/
  20.193 +                                adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch;
  20.194 +
  20.195 +                        if ((val & 8) && !(adgold->adgold_mma_regs[0][8] & 8)) /*Reload base timer*/
  20.196 +                                adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch;
  20.197 +                        break;
  20.198 +                        
  20.199 +                        case 0x9:
  20.200 +                        switch (val & 0x18)
  20.201 +                        {
  20.202 +                                case 0x00: adgold->adgold_mma.voice_latch[0] = 12; break; /*44100 Hz*/
  20.203 +                                case 0x08: adgold->adgold_mma.voice_latch[0] = 24; break; /*22050 Hz*/
  20.204 +                                case 0x10: adgold->adgold_mma.voice_latch[0] = 48; break; /*11025 Hz*/
  20.205 +                                case 0x18: adgold->adgold_mma.voice_latch[0] = 72; break; /* 7350 Hz*/
  20.206 +                        }
  20.207 +                        if (val & 0x80)
  20.208 +                        {
  20.209 +                                adgold->adgold_mma_enable[0] = 0;
  20.210 +                                adgold->adgold_mma_fifo_end[0] = adgold->adgold_mma_fifo_start[0] = 0;
  20.211 +                                adgold->adgold_mma_status &= ~0x01;
  20.212 +                                adgold_update_irq_status(adgold);
  20.213 +                        }
  20.214 +                        if ((val & 0x01))     /*Start playback*/
  20.215 +                        {
  20.216 +                                if (!(adgold->adgold_mma_regs[0][0x9] & 1))
  20.217 +                                        adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0];
  20.218 +                                        
  20.219 +                                pclog("adgold start! FIFO fill %i  %i %i %02X\n", (adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255, adgold->adgold_mma_fifo_end[0], adgold->adgold_mma_fifo_start[0], adgold->adgold_mma_regs[0][0xc]);
  20.220 +                                if (adgold->adgold_mma_regs[0][0xc] & 1)
  20.221 +                                {
  20.222 +                                        if (adgold->adgold_mma_regs[0][0xc] & 0x80)
  20.223 +                                        {
  20.224 +//                                                pclog("adgold start interleaved %i %i
  20.225 +                                                adgold->adgold_mma_enable[1] = 1;
  20.226 +                                                adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1];
  20.227 +
  20.228 +                                                while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128)
  20.229 +                                                {
  20.230 +                                                        adgold_getsamp_dma(adgold, 0);
  20.231 +                                                        adgold_getsamp_dma(adgold, 1);
  20.232 +                                                }
  20.233 +                                                if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0])
  20.234 +                                                {
  20.235 +                                                        adgold->adgold_mma_status &= ~0x01;
  20.236 +                                                        adgold_update_irq_status(adgold);
  20.237 +                                                }
  20.238 +                                                if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1])
  20.239 +                                                {
  20.240 +                                                        adgold->adgold_mma_status &= ~0x02;
  20.241 +                                                        adgold_update_irq_status(adgold);
  20.242 +                                                }
  20.243 +                                        }
  20.244 +                                        else
  20.245 +                                        {
  20.246 +                                                while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128)
  20.247 +                                                {
  20.248 +                                                        adgold_getsamp_dma(adgold, 0);
  20.249 +                                                }
  20.250 +                                                if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0])
  20.251 +                                                {
  20.252 +                                                        adgold->adgold_mma_status &= ~0x01;
  20.253 +                                                        adgold_update_irq_status(adgold);
  20.254 +                                                }
  20.255 +                                        }
  20.256 +                                }
  20.257 +                                pclog("adgold end\n");
  20.258 +                        }
  20.259 +                        adgold->adgold_mma_enable[0] = val & 0x01;
  20.260 +                        break;
  20.261 +                        
  20.262 +                        case 0xb:
  20.263 +                        if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128)
  20.264 +                        {
  20.265 +                                adgold->adgold_mma_fifo[0][adgold->adgold_mma_fifo_end[0]] = val;
  20.266 +                                adgold->adgold_mma_fifo_end[0] = (adgold->adgold_mma_fifo_end[0] + 1) & 255;
  20.267 +                                if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0])
  20.268 +                                {
  20.269 +                                        adgold->adgold_mma_status &= ~0x01;
  20.270 +                                        adgold_update_irq_status(adgold);
  20.271 +                                }
  20.272 +                        }
  20.273 +                        break;
  20.274 +                        
  20.275 +                        case 0xc:
  20.276 +                        adgold->adgold_mma_intpos[0] = (7 - ((val >> 2) & 7)) * 8;
  20.277 +                        break;
  20.278 +                }
  20.279 +                adgold->adgold_mma_regs[0][adgold->adgold_mma_addr] = val;
  20.280 +                break;
  20.281 +                case 7:
  20.282 +                if (adgold->adgold_mma_addr >= 0xf) break;
  20.283 +                switch (adgold->adgold_mma_addr)
  20.284 +                {
  20.285 +                        case 0x9:
  20.286 +                        switch (val & 0x18)
  20.287 +                        {
  20.288 +                                case 0x00: adgold->adgold_mma.voice_latch[1] = 12; break; /*44100 Hz*/
  20.289 +                                case 0x08: adgold->adgold_mma.voice_latch[1] = 24; break; /*22050 Hz*/
  20.290 +                                case 0x10: adgold->adgold_mma.voice_latch[1] = 48; break; /*11025 Hz*/
  20.291 +                                case 0x18: adgold->adgold_mma.voice_latch[1] = 72; break; /* 7350 Hz*/
  20.292 +                        }
  20.293 +                        if (val & 0x80)
  20.294 +                        {
  20.295 +                                adgold->adgold_mma_enable[1] = 0;
  20.296 +                                adgold->adgold_mma_fifo_end[1] = adgold->adgold_mma_fifo_start[1] = 0;
  20.297 +                                adgold->adgold_mma_status &= ~0x02;
  20.298 +                                adgold_update_irq_status(adgold);
  20.299 +                        }
  20.300 +                        if ((val & 0x01))     /*Start playback*/
  20.301 +                        {
  20.302 +                                if (!(adgold->adgold_mma_regs[1][0x9] & 1)) 
  20.303 +                                        adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1];
  20.304 +                                        
  20.305 +                                pclog("adgold start! FIFO fill %i  %i %i %02X\n", (adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255, adgold->adgold_mma_fifo_end[1], adgold->adgold_mma_fifo_start[1], adgold->adgold_mma_regs[1][0xc]);
  20.306 +                                if (adgold->adgold_mma_regs[1][0xc] & 1)
  20.307 +                                {
  20.308 +                                        while (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128)
  20.309 +                                        {
  20.310 +                                                adgold_getsamp_dma(adgold, 1);
  20.311 +                                        }
  20.312 +                                }
  20.313 +                                pclog("adgold end\n");
  20.314 +                        }
  20.315 +                        adgold->adgold_mma_enable[1] = val & 0x01;
  20.316 +                        break;
  20.317 +                        
  20.318 +                        case 0xb:
  20.319 +                        if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128)
  20.320 +                        {
  20.321 +                                adgold->adgold_mma_fifo[1][adgold->adgold_mma_fifo_end[1]] = val;
  20.322 +                                adgold->adgold_mma_fifo_end[1] = (adgold->adgold_mma_fifo_end[1] + 1) & 255;
  20.323 +                                if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1])
  20.324 +                                {
  20.325 +                                        adgold->adgold_mma_status &= ~0x02;
  20.326 +                                        adgold_update_irq_status(adgold);
  20.327 +                                }
  20.328 +                        }
  20.329 +                        break;
  20.330 +
  20.331 +                        case 0xc:
  20.332 +                        adgold->adgold_mma_intpos[1] = (7 - ((val >> 2) & 7)) * 8;
  20.333 +                        break;
  20.334 +                }
  20.335 +                adgold->adgold_mma_regs[1][adgold->adgold_mma_addr] = val;
  20.336 +                break;
  20.337 +        }
  20.338 +}
  20.339 +
  20.340 +uint8_t adgold_read(uint16_t addr, void *p)
  20.341 +{
  20.342 +        adgold_t *adgold = (adgold_t *)p;
  20.343 +        uint8_t temp;
  20.344 +        
  20.345 +        switch (addr & 7)
  20.346 +        {
  20.347 +                case 0: case 1:
  20.348 +                temp = opl3_read(addr, &adgold->opl);
  20.349 +                break;
  20.350 +                
  20.351 +                case 2:
  20.352 +                if (adgold->adgold_38x_state)   /*Read from control chip*/
  20.353 +                        temp = adgold->adgold_status;
  20.354 +                else
  20.355 +                        temp = opl3_read(addr, &adgold->opl);
  20.356 +                break;
  20.357 +                
  20.358 +                case 3:
  20.359 +                if (adgold->adgold_38x_state)
  20.360 +                {
  20.361 +                        if (adgold->adgold_38x_addr >= 0x19) temp = 0xff;
  20.362 +                        switch (adgold->adgold_38x_addr)
  20.363 +                        {
  20.364 +                                case 0x00: /*Control/ID*/
  20.365 +                                temp = 0x70; /*16-bit ISA, no telephone/surround/CD-ROM*/
  20.366 +                                break;
  20.367 +                                
  20.368 +                                default:
  20.369 +                                temp = adgold->adgold_38x_regs[adgold->adgold_38x_addr];
  20.370 +                        }                
  20.371 +                }
  20.372 +                else
  20.373 +                        temp = opl3_read(addr, &adgold->opl);
  20.374 +                break;
  20.375 +
  20.376 +                case 4: case 6:
  20.377 +                temp = adgold->adgold_mma_status;
  20.378 +                adgold->adgold_mma_status = 0; /*JUKEGOLD expects timer status flags to auto-clear*/
  20.379 +                adgold_update_irq_status(adgold);
  20.380 +                break;
  20.381 +                case 5:
  20.382 +                if (adgold->adgold_mma_addr >= 0xf) temp = 0xff;
  20.383 +                switch (adgold->adgold_mma_addr)
  20.384 +                {
  20.385 +                        case 6: /*Timer 2 low*/
  20.386 +                        adgold->adgold_mma.timer2_read = adgold->adgold_mma.timer2_count;
  20.387 +                        temp = adgold->adgold_mma.timer2_read & 0xff;
  20.388 +                        break;
  20.389 +                        case 7: /*Timer 2 high*/
  20.390 +                        temp = adgold->adgold_mma.timer2_read >> 8;
  20.391 +                        break;
  20.392 +                        
  20.393 +                        default:
  20.394 +                        temp = adgold->adgold_mma_regs[0][adgold->adgold_mma_addr];
  20.395 +                        break;
  20.396 +                }
  20.397 +                break;
  20.398 +                case 7:
  20.399 +                if (adgold->adgold_mma_addr >= 0xf) temp = 0xff;
  20.400 +                temp = adgold->adgold_mma_regs[1][adgold->adgold_mma_addr];
  20.401 +                break;
  20.402 +        }
  20.403 +        if (addr > 0x389) pclog("adgold_read : addr %04X %02X\n", addr, temp);
  20.404 +        return temp;
  20.405 +}
  20.406 +
  20.407 +void adgold_mma_poll(adgold_t *adgold, int channel)
  20.408 +{
  20.409 +        int16_t dat;
  20.410 +
  20.411 +        if (adgold->adgold_mma_fifo_start[channel] != adgold->adgold_mma_fifo_end[channel])
  20.412 +        {
  20.413 +                switch (adgold->adgold_mma_regs[channel][0xc] & 0x60)
  20.414 +                {
  20.415 +                        case 0x00: /*8-bit*/
  20.416 +                        dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] * 256;
  20.417 +                        adgold->adgold_mma_out[channel] = dat;
  20.418 +                        adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255;
  20.419 +                        break;
  20.420 +                        
  20.421 +                        case 0x40: /*12-bit sensible format*/
  20.422 +                        if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < 2)
  20.423 +                                return;
  20.424 +                                
  20.425 +                        dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] & 0xf0;
  20.426 +                        adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255;
  20.427 +                        dat |= (adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] << 8);
  20.428 +                        adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255;
  20.429 +                        adgold->adgold_mma_out[channel] = dat;
  20.430 +                        break;
  20.431 +                }
  20.432 +                
  20.433 +                if (adgold->adgold_mma_regs[channel][0xc] & 1)
  20.434 +                {
  20.435 +                        adgold_getsamp_dma(adgold, channel);
  20.436 +                }
  20.437 +                if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < adgold->adgold_mma_intpos[channel] && !(adgold->adgold_mma_status & 0x01))
  20.438 +                {
  20.439 +//                        pclog("adgold_mma_poll - IRQ! %i\n", channel);
  20.440 +                        adgold->adgold_mma_status |= 1 << channel;
  20.441 +                        adgold_update_irq_status(adgold);
  20.442 +                }
  20.443 +        }
  20.444 +        if (adgold->adgold_mma_fifo_start[channel] == adgold->adgold_mma_fifo_end[channel])
  20.445 +        {
  20.446 +                adgold->adgold_mma_enable[channel] = 0;
  20.447 +        }
  20.448 +}
  20.449 +
  20.450 +void adgold_timer_poll(void *p)
  20.451 +{
  20.452 +        adgold_t *adgold = (adgold_t *)p;
  20.453 +        
  20.454 +        while (adgold->adgold_mma_timer_count <= 0)
  20.455 +        {
  20.456 +                adgold->adgold_mma_timer_count += (int)((double)TIMER_USEC * 1.88964);
  20.457 +                if (adgold->adgold_mma_regs[0][8] & 0x01) /*Timer 0*/
  20.458 +                {
  20.459 +                        adgold->adgold_mma.timer0_count--;
  20.460 +                        if (!adgold->adgold_mma.timer0_count)
  20.461 +                        {
  20.462 +                                adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch;
  20.463 +                                pclog("Timer 0 interrupt\n");
  20.464 +                                adgold->adgold_mma_status |= 0x10;
  20.465 +                                adgold_update_irq_status(adgold);
  20.466 +                        }
  20.467 +                }
  20.468 +                if (adgold->adgold_mma_regs[0][8] & 0x08) /*Base timer*/
  20.469 +                {
  20.470 +                        adgold->adgold_mma.timerbase_count--;
  20.471 +                        if (!adgold->adgold_mma.timerbase_count)
  20.472 +                        {
  20.473 +                                adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch;
  20.474 +                                if (adgold->adgold_mma_regs[0][8] & 0x02) /*Timer 1*/
  20.475 +                                {
  20.476 +                                        adgold->adgold_mma.timer1_count--;
  20.477 +                                        if (!adgold->adgold_mma.timer1_count)
  20.478 +                                        {
  20.479 +                                                adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch;
  20.480 +                                                pclog("Timer 1 interrupt\n");
  20.481 +                                                adgold->adgold_mma_status |= 0x20;
  20.482 +                                                adgold_update_irq_status(adgold);
  20.483 +                                        }
  20.484 +                                }
  20.485 +                                if (adgold->adgold_mma_regs[0][8] & 0x04) /*Timer 2*/
  20.486 +                                {
  20.487 +                                        adgold->adgold_mma.timer2_count--;
  20.488 +                                        if (!adgold->adgold_mma.timer2_count)
  20.489 +                                        {
  20.490 +                                                adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch;
  20.491 +                                                pclog("Timer 2 interrupt\n");
  20.492 +                                                adgold->adgold_mma_status |= 0x40;
  20.493 +                                                adgold_update_irq_status(adgold);
  20.494 +                                        }
  20.495 +                                }
  20.496 +                        }
  20.497 +                }
  20.498 +
  20.499 +                if (adgold->adgold_mma_enable[0])
  20.500 +                {
  20.501 +                        adgold->adgold_mma.voice_count[0]--;
  20.502 +                        if (!adgold->adgold_mma.voice_count[0])
  20.503 +                        {
  20.504 +                                adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0];
  20.505 +                                adgold_mma_poll(adgold, 0);
  20.506 +                        }
  20.507 +                }
  20.508 +                if (adgold->adgold_mma_enable[1])
  20.509 +                {
  20.510 +                        adgold->adgold_mma.voice_count[1]--;
  20.511 +                        if (!adgold->adgold_mma.voice_count[1])
  20.512 +                        {
  20.513 +                                adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1];
  20.514 +                                adgold_mma_poll(adgold, 1);
  20.515 +                        }
  20.516 +                }
  20.517 +        }
  20.518 +}
  20.519 +
  20.520 +void adgold_poll(void *p)
  20.521 +{
  20.522 +        adgold_t *adgold = (adgold_t *)p;
  20.523 +        
  20.524 +        if (adgold->pos >= SOUNDBUFLEN)
  20.525 +                return;
  20.526 +
  20.527 +        opl3_poll(&adgold->opl, &adgold->opl_buffer[adgold->pos * 2], &adgold->opl_buffer[(adgold->pos * 2) + 1]);
  20.528 +        adgold->mma_buffer[0][adgold->pos] = adgold->mma_buffer[1][adgold->pos] = 0;
  20.529 +        
  20.530 +        if (adgold->adgold_mma_regs[0][9] & 0x20)
  20.531 +                adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[0] / 2;
  20.532 +        if (adgold->adgold_mma_regs[0][9] & 0x40)
  20.533 +                adgold->mma_buffer[1][adgold->pos] += adgold->adgold_mma_out[0] / 2;
  20.534 +
  20.535 +        if (adgold->adgold_mma_regs[1][9] & 0x20)
  20.536 +                adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[1] / 2;
  20.537 +        if (adgold->adgold_mma_regs[1][9] & 0x40)
  20.538 +                adgold->mma_buffer[1][adgold->pos] += adgold->adgold_mma_out[1] / 2;
  20.539 +
  20.540 +        adgold->pos++;
  20.541 +}
  20.542 +
  20.543 +static void adgold_get_buffer(int16_t *buffer, int len, void *p)
  20.544 +{
  20.545 +        adgold_t *adgold = (adgold_t *)p;
  20.546 +        
  20.547 +        int c;
  20.548 +
  20.549 +        for (c = 0; c < len * 2; c++)
  20.550 +        {
  20.551 +                buffer[c] += adgold->opl_buffer[c];
  20.552 +                buffer[c] += adgold->mma_buffer[c & 1][c >> 1] / 2;
  20.553 +        }
  20.554 +
  20.555 +        adgold->pos = 0;
  20.556 +}
  20.557 +
  20.558 +
  20.559 +void *adgold_init()
  20.560 +{
  20.561 +        adgold_t *adgold = malloc(sizeof(adgold_t));
  20.562 +        memset(adgold, 0, sizeof(adgold_t));
  20.563 +
  20.564 +        opl3_init(&adgold->opl);
  20.565 +
  20.566 +        adgold->adgold_status = 0xf;
  20.567 +        adgold->adgold_38x_addr = 0;
  20.568 +        adgold->adgold_eeprom[0x09] = adgold->adgold_eeprom[0x0a] = 255;
  20.569 +        adgold->adgold_eeprom[0x13] = 3 | (1 << 4);     /*IRQ 7, DMA 1*/
  20.570 +        adgold->adgold_eeprom[0x14] = 3 << 4;           /*DMA 3*/
  20.571 +        adgold->adgold_eeprom[0x15] = 0x388 / 8;        /*Present at 388-38f*/
  20.572 +        memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19);
  20.573 +
  20.574 +        adgold->adgold_mma_enable[0] = 0;
  20.575 +        adgold->adgold_mma_fifo_start[0] = adgold->adgold_mma_fifo_end[0] = 0;
  20.576 +        
  20.577 +        /*388/389 are handled by adlib_init*/
  20.578 +        io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold);
  20.579 +        
  20.580 +        timer_add(adgold_timer_poll, &adgold->adgold_mma_timer_count, TIMER_ALWAYS_ENABLED, adgold);
  20.581 +
  20.582 +        sound_add_handler(adgold_poll, adgold_get_buffer, adgold);
  20.583 +        
  20.584 +        return adgold;
  20.585 +}
  20.586 +
  20.587 +void adgold_close(void *p)
  20.588 +{
  20.589 +        adgold_t *adgold = (adgold_t *)p;
  20.590 +        
  20.591 +        free(adgold);
  20.592 +}
  20.593 +
  20.594 +device_t adgold_device =
  20.595 +{
  20.596 +        "AdLib Gold",
  20.597 +        adgold_init,
  20.598 +        adgold_close,
  20.599 +        NULL
  20.600 +};
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/src/sound_adlibgold.h	Mon May 27 19:56:33 2013 +0100
    21.3 @@ -0,0 +1,1 @@
    21.4 +extern device_t adgold_device;
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/src/sound_cms.c	Mon May 27 19:56:33 2013 +0100
    22.3 @@ -0,0 +1,179 @@
    22.4 +#include <stdio.h>
    22.5 +#include <stdlib.h>
    22.6 +#include "ibm.h"
    22.7 +
    22.8 +#include "device.h"
    22.9 +#include "io.h"
   22.10 +#include "sound.h"
   22.11 +#include "sound_cms.h"
   22.12 +
   22.13 +typedef struct cms_t
   22.14 +{
   22.15 +        int addrs[2];
   22.16 +        uint8_t regs[2][32];
   22.17 +        uint16_t latch[2][6];
   22.18 +        int freq[2][6];
   22.19 +        float count[2][6];
   22.20 +        int vol[2][6][2];
   22.21 +        int stat[2][6];
   22.22 +        uint16_t noise[2][2];
   22.23 +        uint16_t noisefreq[2][2];
   22.24 +        int noisecount[2][2];
   22.25 +        int noisetype[2][2];
   22.26 +
   22.27 +        int16_t buffer[SOUNDBUFLEN * 2];
   22.28 +
   22.29 +        int pos;
   22.30 +} cms_t;
   22.31 +
   22.32 +void cms_poll(void *p)
   22.33 +{
   22.34 +        cms_t *cms = (cms_t *)p;
   22.35 +        int c, d;
   22.36 +        int16_t out_l = 0, out_r = 0;
   22.37 +
   22.38 +        if (cms->pos >= SOUNDBUFLEN)
   22.39 +                return;
   22.40 +
   22.41 +        for (c = 0; c < 4; c++)
   22.42 +        {
   22.43 +                switch (cms->noisetype[c >> 1][c & 1])
   22.44 +                {
   22.45 +                        case 0: cms->noisefreq[c >> 1][c & 1] = 31250; break;
   22.46 +                        case 1: cms->noisefreq[c >> 1][c & 1] = 15625; break;
   22.47 +                        case 2: cms->noisefreq[c >> 1][c & 1] = 7812; break;
   22.48 +                        case 3: cms->noisefreq[c >> 1][c & 1] = cms->freq[c >> 1][(c & 1) * 3]; break;
   22.49 +                }
   22.50 +        }
   22.51 +        for (c = 0; c < 2; c ++)
   22.52 +        {
   22.53 +                if (cms->regs[c][0x1C] & 1)
   22.54 +                {
   22.55 +                        for (d = 0; d < 6; d++)
   22.56 +                        {
   22.57 +                                if (cms->regs[c][0x14] & (1 << d))
   22.58 +                                {
   22.59 +                                        if (cms->stat[c][d]) out_l += (cms->vol[c][d][0] * 90);
   22.60 +                                        if (cms->stat[c][d]) out_r += (cms->vol[c][d][1] * 90);
   22.61 +                                        cms->count[c][d] += cms->freq[c][d];
   22.62 +                                        if (cms->count[c][d] >= 24000)
   22.63 +                                        {
   22.64 +                                                cms->count[c][d] -= 24000;
   22.65 +                                                cms->stat[c][d] ^= 1;
   22.66 +                                        }
   22.67 +                                }
   22.68 +                                else if (cms->regs[c][0x15] & (1 << d))
   22.69 +                                {
   22.70 +                                        if (cms->noise[c][d / 3] & 1) out_l += (cms->vol[c][d][0] * 90);
   22.71 +                                        if (cms->noise[c][d / 3] & 1) out_r += (cms->vol[c][d][0] * 90);
   22.72 +                                }
   22.73 +                        }
   22.74 +                        for (d = 0; d < 2; d++)
   22.75 +                        {
   22.76 +                                cms->noisecount[c][d] += cms->noisefreq[c][d];
   22.77 +                                while (cms->noisecount[c][d] >= 24000)
   22.78 +                                {
   22.79 +                                        cms->noisecount[c][d] -= 24000;
   22.80 +                                        cms->noise[c][d] <<= 1;
   22.81 +                                        if (!(((cms->noise[c][d] & 0x4000) >> 8) ^ (cms->noise[c][d] & 0x40))) 
   22.82 +                                                cms->noise[c][d] |= 1;
   22.83 +                                }
   22.84 +                        }
   22.85 +                }
   22.86 +        }
   22.87 +        cms->buffer[(cms->pos << 1)] = out_l;
   22.88 +        cms->buffer[(cms->pos << 1) + 1] = out_r;
   22.89 +
   22.90 +        cms->pos++;
   22.91 +}
   22.92 +
   22.93 +void cms_get_buffer(int16_t *buffer, int len, void *p)
   22.94 +{
   22.95 +        cms_t *cms = (cms_t *)p;
   22.96 +        
   22.97 +        int c;
   22.98 +
   22.99 +        for (c = 0; c < len * 2; c++)
  22.100 +                buffer[c] += cms->buffer[c];
  22.101 +
  22.102 +        cms->pos = 0;
  22.103 +}
  22.104 +
  22.105 +void cms_write(uint16_t addr, uint8_t val, void *p)
  22.106 +{
  22.107 +        cms_t *cms = (cms_t *)p;
  22.108 +        int voice;
  22.109 +        int chip = (addr & 2) >> 1;
  22.110 +        
  22.111 +        pclog("cms_write : addr %04X val %02X\n", addr, val);
  22.112 +        
  22.113 +        if (addr & 1)
  22.114 +           cms->addrs[chip] = val & 31;
  22.115 +        else
  22.116 +        {
  22.117 +                cms->regs[chip][cms->addrs[chip] & 31] = val;
  22.118 +                switch (cms->addrs[chip] & 31)
  22.119 +                {
  22.120 +                        case 0x00: case 0x01: case 0x02: /*Volume*/
  22.121 +                        case 0x03: case 0x04: case 0x05:
  22.122 +                        voice = cms->addrs[chip] & 7;
  22.123 +                        cms->vol[chip][voice][0] = val & 0xf;
  22.124 +                        cms->vol[chip][voice][1] = val >> 4;
  22.125 +                        break;
  22.126 +                        case 0x08: case 0x09: case 0x0A: /*Frequency*/
  22.127 +                        case 0x0B: case 0x0C: case 0x0D:
  22.128 +                        voice = cms->addrs[chip] & 7;
  22.129 +                        cms->latch[chip][voice] = (cms->latch[chip][voice] & 0x700) | val;
  22.130 +                        cms->freq[chip][voice] = (15625 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255));
  22.131 +                        break;
  22.132 +                        case 0x10: case 0x11: case 0x12: /*Octave*/
  22.133 +                        voice = (cms->addrs[chip] & 3) << 1;
  22.134 +                        cms->latch[chip][voice] = (cms->latch[chip][voice] & 0xFF) | ((val & 7) << 8);
  22.135 +                        cms->latch[chip][voice + 1] = (cms->latch[chip][voice + 1] & 0xFF) | ((val & 0x70) << 4);
  22.136 +                        cms->freq[chip][voice] = (15625 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255));
  22.137 +                        cms->freq[chip][voice + 1] = (15625 << (cms->latch[chip][voice + 1] >> 8)) / (511 - (cms->latch[chip][voice + 1] & 255));
  22.138 +                        break;
  22.139 +                        case 0x16: /*Noise*/
  22.140 +                        cms->noisetype[chip][0] = val & 3;
  22.141 +                        cms->noisetype[chip][1] = (val >> 4) & 3;
  22.142 +                        break;
  22.143 +                }
  22.144 +        }
  22.145 +}
  22.146 +
  22.147 +uint8_t cms_read(uint16_t addr, void *p)
  22.148 +{
  22.149 +        cms_t *cms = (cms_t *)p;
  22.150 +        int chip = (addr & 2) >> 1;
  22.151 +        
  22.152 +        if (addr & 1) 
  22.153 +                return cms->addrs[chip];
  22.154 +                
  22.155 +        return cms->regs[chip][cms->addrs[chip] & 31];
  22.156 +}
  22.157 +
  22.158 +void *cms_init()
  22.159 +{
  22.160 +        cms_t *cms = malloc(sizeof(cms_t));
  22.161 +        memset(cms, 0, sizeof(cms_t));
  22.162 +
  22.163 +        pclog("cms_init\n");
  22.164 +        io_sethandler(0x0220, 0x0004, cms_read, NULL, NULL, cms_write, NULL, NULL, cms);
  22.165 +        sound_add_handler(cms_poll, cms_get_buffer, cms);
  22.166 +        return cms;
  22.167 +}
  22.168 +
  22.169 +void cms_close(void *p)
  22.170 +{
  22.171 +        cms_t *cms = (cms_t *)p;
  22.172 +        
  22.173 +        free(cms);
  22.174 +}
  22.175 +
  22.176 +device_t cms_device =
  22.177 +{
  22.178 +        "Creative Music System / Game Blaster",
  22.179 +        cms_init,
  22.180 +        cms_close,
  22.181 +        NULL
  22.182 +};
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/src/sound_cms.h	Mon May 27 19:56:33 2013 +0100
    23.3 @@ -0,0 +1,1 @@
    23.4 +extern device_t cms_device;
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/src/sound_gus.c	Mon May 27 19:56:33 2013 +0100
    24.3 @@ -0,0 +1,1107 @@
    24.4 +#include <stdio.h>
    24.5 +#include <stdlib.h>
    24.6 +#include <string.h>
    24.7 +#include "ibm.h"
    24.8 +
    24.9 +#include "device.h"
   24.10 +#include "dma.h"
   24.11 +#include "io.h"
   24.12 +#include "pic.h"
   24.13 +#include "sound.h"
   24.14 +#include "sound_gus.h"
   24.15 +#include "timer.h"
   24.16 +
   24.17 +typedef struct gus_t
   24.18 +{
   24.19 +        int reset;
   24.20 +        
   24.21 +        int global;
   24.22 +        uint32_t addr,dmaaddr;
   24.23 +        int voice;
   24.24 +        uint32_t start[32],end[32],cur[32];
   24.25 +        uint32_t startx[32],endx[32],curx[32];
   24.26 +        int rstart[32],rend[32];
   24.27 +        int rcur[32];
   24.28 +        uint16_t freq[32];
   24.29 +        uint16_t rfreq[32];
   24.30 +        uint8_t ctrl[32];
   24.31 +        uint8_t rctrl[32];
   24.32 +        int curvol[32];
   24.33 +        int t1on,t2on;
   24.34 +        uint8_t tctrl;
   24.35 +        uint16_t t1,t2,t1l,t2l;
   24.36 +        uint8_t irqstatus,irqstatus2;
   24.37 +        uint8_t adcommand;
   24.38 +        int waveirqs[32],rampirqs[32];
   24.39 +        int voices;
   24.40 +        uint8_t dmactrl;
   24.41 +
   24.42 +        int16_t out_l, out_r;
   24.43 +        
   24.44 +        int16_t buffer[2][SOUNDBUFLEN];
   24.45 +        int pos;
   24.46 +        
   24.47 +        int samp_timer, samp_latch;
   24.48 +        
   24.49 +        uint8_t *ram;
   24.50 +        
   24.51 +        int irqnext;
   24.52 +        
   24.53 +        int timer_1, timer_2;
   24.54 +        
   24.55 +        int irq, dma, irq_midi;
   24.56 +        int latch_enable;
   24.57 +        
   24.58 +        uint8_t sb_2xa, sb_2xc, sb_2xe;
   24.59 +        uint8_t sb_ctrl;
   24.60 +        int sb_nmi;
   24.61 +        
   24.62 +        uint8_t reg_ctrl;
   24.63 +        
   24.64 +        uint8_t ad_status, ad_data;
   24.65 +        uint8_t ad_timer_ctrl;
   24.66 +        
   24.67 +        uint8_t midi_ctrl, midi_status;
   24.68 +        uint8_t midi_data;
   24.69 +        int midi_loopback;
   24.70 +        
   24.71 +        uint8_t gp1, gp2;
   24.72 +        uint16_t gp1_addr, gp2_addr;
   24.73 +        
   24.74 +        uint8_t usrr;
   24.75 +} gus_t;
   24.76 +
   24.77 +static int gus_irqs[8] = {-1, 2, 5, 3, 7, 11, 12, 15};
   24.78 +static int gus_irqs_midi[8] = {-1, 2, 5, 3, 7, 11, 12, 15};
   24.79 +static int gus_dmas[8] = {-1, 1, 3, 5, 6, 7, -1, -1};
   24.80 +
   24.81 +int gusfreqs[]=
   24.82 +{
   24.83 +        44100,41160,38587,36317,34300,32494,30870,29400,28063,26843,25725,24696,
   24.84 +        23746,22866,22050,21289,20580,19916,19293
   24.85 +};
   24.86 +
   24.87 +double vol16bit[4096];
   24.88 +
   24.89 +void pollgusirqs(gus_t *gus)
   24.90 +{
   24.91 +        int c;
   24.92 +
   24.93 +        gus->irqstatus&=~0x60;
   24.94 +        for (c=0;c<32;c++)
   24.95 +        {
   24.96 +                if (gus->waveirqs[c])
   24.97 +                {
   24.98 +//                        gus->waveirqs[c]=0;
   24.99 +                        gus->irqstatus2=0x60|c;
  24.100 +                        if (gus->rampirqs[c]) gus->irqstatus2 |= 0x80;
  24.101 +                        gus->irqstatus|=0x20;
  24.102 +//                        printf("Voice IRQ %i %02X %i\n",c,gus->irqstatus2,ins);
  24.103 +                        if (gus->irq != -1)
  24.104 +                                picint(1 << gus->irq);
  24.105 +                        return;
  24.106 +                }
  24.107 +                if (gus->rampirqs[c])
  24.108 +                {
  24.109 +//                        gus->rampirqs[c]=0;
  24.110 +                        gus->irqstatus2=0xA0|c;
  24.111 +                        gus->irqstatus|=0x40;
  24.112 +//                        printf("Ramp IRQ %i %02X %i\n",c,gus->irqstatus2,ins);
  24.113 +                        if (gus->irq != -1)
  24.114 +                                picint(1 << gus->irq);
  24.115 +                        return;
  24.116 +                }
  24.117 +        }
  24.118 +        gus->irqstatus2=0xE0;
  24.119 +//        gus->irqstatus&=~0x20;
  24.120 +        if (!gus->irqstatus && gus->irq != -1) picintc(1 << gus->irq);
  24.121 +}
  24.122 +
  24.123 +enum
  24.124 +{
  24.125 +        MIDI_INT_RECEIVE = 0x01,
  24.126 +        MIDI_INT_TRANSMIT = 0x02,
  24.127 +        MIDI_INT_MASTER = 0x80
  24.128 +};
  24.129 +
  24.130 +enum
  24.131 +{
  24.132 +        MIDI_CTRL_TRANSMIT_MASK = 0x60,
  24.133 +        MIDI_CTRL_TRANSMIT = 0x20,
  24.134 +        MIDI_CTRL_RECEIVE = 0x80
  24.135 +};
  24.136 +
  24.137 +enum
  24.138 +{
  24.139 +        GUS_INT_MIDI_TRANSMIT = 0x01,
  24.140 +        GUS_INT_MIDI_RECEIVE  = 0x02
  24.141 +};
  24.142 +
  24.143 +enum
  24.144 +{
  24.145 +        GUS_TIMER_CTRL_AUTO = 0x01
  24.146 +};
  24.147 +
  24.148 +void gus_midi_update_int_status(gus_t *gus)
  24.149 +{
  24.150 +        gus->midi_status &= ~MIDI_INT_MASTER;
  24.151 +        if ((gus->midi_ctrl & MIDI_CTRL_TRANSMIT_MASK) == MIDI_CTRL_TRANSMIT && (gus->midi_status & MIDI_INT_TRANSMIT))
  24.152 +        {
  24.153 +                gus->midi_status |= MIDI_INT_MASTER;
  24.154 +                gus->irqstatus |= GUS_INT_MIDI_TRANSMIT;
  24.155 +        }
  24.156 +        else
  24.157 +                gus->irqstatus &= ~GUS_INT_MIDI_TRANSMIT;
  24.158 +                
  24.159 +        if ((gus->midi_ctrl & MIDI_CTRL_RECEIVE) && (gus->midi_status & MIDI_INT_RECEIVE))
  24.160 +        {
  24.161 +                gus->midi_status |= MIDI_INT_MASTER;
  24.162 +                gus->irqstatus |= GUS_INT_MIDI_RECEIVE;
  24.163 +        }
  24.164 +        else
  24.165 +                gus->irqstatus &= ~GUS_INT_MIDI_RECEIVE;
  24.166 +
  24.167 +        if ((gus->midi_status & MIDI_INT_MASTER) && (gus->irq_midi != -1))
  24.168 +        {
  24.169 +//                pclog("Take MIDI IRQ\n");
  24.170 +                picint(1 << gus->irq_midi);
  24.171 +        }
  24.172 +}
  24.173 +        
  24.174 +void writegus(uint16_t addr, uint8_t val, void *p)
  24.175 +{
  24.176 +        gus_t *gus = (gus_t *)p;
  24.177 +        int c, d;
  24.178 +        int old;
  24.179 +//        pclog("Write GUS %04X %02X %04X:%04X\n",addr,val,CS,pc);
  24.180 +        if (gus->latch_enable && addr != 0x24b)
  24.181 +                gus->latch_enable = 0;
  24.182 +        switch (addr)
  24.183 +        {
  24.184 +                case 0x340: /*MIDI control*/
  24.185 +                old = gus->midi_ctrl;
  24.186 +                gus->midi_ctrl = val;
  24.187 +                
  24.188 +                if ((val & 3) == 3)
  24.189 +                        gus->midi_status = 0;
  24.190 +                else if ((old & 3) == 3)
  24.191 +                {
  24.192 +                        gus->midi_status |= MIDI_INT_TRANSMIT;
  24.193 +//                        pclog("MIDI_INT_TRANSMIT\n");
  24.194 +                }                
  24.195 +                gus_midi_update_int_status(gus);
  24.196 +                break;
  24.197 +                
  24.198 +                case 0x341: /*MIDI data*/
  24.199 +                if (gus->midi_loopback)
  24.200 +                {
  24.201 +                        gus->midi_status |= MIDI_INT_RECEIVE;
  24.202 +                        gus->midi_data = val;
  24.203 +                }
  24.204 +                else
  24.205 +                        gus->midi_status |= MIDI_INT_TRANSMIT;
  24.206 +                break;
  24.207 +                
  24.208 +                case 0x342: /*Voice select*/
  24.209 +                gus->voice=val&31;
  24.210 +                break;
  24.211 +                case 0x343: /*Global select*/
  24.212 +                gus->global=val;
  24.213 +                break;
  24.214 +                case 0x344: /*Global low*/
  24.215 +//                if (gus->global!=0x43 && gus->global!=0x44) printf("Writing register %02X %02X %02X %i\n",gus->global,gus->voice,val, ins);
  24.216 +                switch (gus->global)
  24.217 +                {
  24.218 +                        case 0: /*Voice control*/
  24.219 +//                        if (val&1 && !(gus->ctrl[gus->voice]&1)) printf("Voice on %i\n",gus->voice);
  24.220 +                        gus->ctrl[gus->voice]=val;
  24.221 +                        break;
  24.222 +                        case 1: /*Frequency control*/
  24.223 +                        gus->freq[gus->voice]=(gus->freq[gus->voice]&0xFF00)|val;
  24.224 +                        break;
  24.225 +                        case 2: /*Start addr high*/
  24.226 +                        gus->startx[gus->voice]=(gus->startx[gus->voice]&0xF807F)|(val<<7);
  24.227 +                        gus->start[gus->voice]=(gus->start[gus->voice]&0x1F00FFFF)|(val<<16);
  24.228 +//                        printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]);
  24.229 +                        break;
  24.230 +                        case 3: /*Start addr low*/
  24.231 +                        gus->start[gus->voice]=(gus->start[gus->voice]&0x1FFFFF00)|val;
  24.232 +//                        printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]);
  24.233 +                        break;
  24.234 +                        case 4: /*End addr high*/
  24.235 +                        gus->endx[gus->voice]=(gus->endx[gus->voice]&0xF807F)|(val<<7);
  24.236 +                        gus->end[gus->voice]=(gus->end[gus->voice]&0x1F00FFFF)|(val<<16);
  24.237 +//                        printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]);
  24.238 +                        break;
  24.239 +                        case 5: /*End addr low*/
  24.240 +                        gus->end[gus->voice]=(gus->end[gus->voice]&0x1FFFFF00)|val;
  24.241 +//                        printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]);
  24.242 +                        break;
  24.243 +
  24.244 +                        case 0x6: /*Ramp frequency*/
  24.245 +                        gus->rfreq[gus->voice] = (int)( (double)((val & 63)*512)/(double)(1 << (3*(val >> 6))));
  24.246 +//                        printf("RFREQ %02X %i %i %f\n",val,gus->voice,gus->rfreq[gus->voice],(double)(val & 63)/(double)(1 << (3*(val >> 6))));
  24.247 +                        break;
  24.248 +
  24.249 +                        case 0x9: /*Current volume*/
  24.250 +                        gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 6)) | (val << 6);
  24.251 +//                        printf("Vol %i is %04X\n",gus->voice,gus->curvol[gus->voice]);
  24.252 +                        break;
  24.253 +
  24.254 +                        case 0xA: /*Current addr high*/
  24.255 +                        gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1F00FFFF)|(val<<16);
  24.256 +gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8);
  24.257 +//                      gus->cur[gus->voice]=(gus->cur[gus->voice]&0x0F807F00)|((val<<7)<<8);
  24.258 +//                        printf("Write %i cur %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]);
  24.259 +                        break;
  24.260 +                        case 0xB: /*Current addr low*/
  24.261 +                        gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFFFF00)|val;
  24.262 +//                        printf("Write %i cur %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]);
  24.263 +                        break;
  24.264 +
  24.265 +                        case 0x42: /*DMA address low*/
  24.266 +                        gus->dmaaddr=(gus->dmaaddr&0xFF000)|(val<<4);
  24.267 +                        break;
  24.268 +
  24.269 +                        case 0x43: /*Address low*/
  24.270 +                        gus->addr=(gus->addr&0xFFF00)|val;
  24.271 +                        break;
  24.272 +                        case 0x45: /*Timer control*/
  24.273 +//                        printf("Timer control %02X\n",val);
  24.274 +                        gus->tctrl=val;
  24.275 +                        break;
  24.276 +                }
  24.277 +                break;
  24.278 +                case 0x345: /*Global high*/
  24.279 +//                if (gus->global!=0x43 && gus->global!=0x44) printf("HWriting register %02X %02X %02X %04X:%04X %i %X\n",gus->global,gus->voice,val,CS,pc, ins, gus->rcur[1] >> 10);
  24.280 +                switch (gus->global)
  24.281 +                {
  24.282 +                        case 0: /*Voice control*/
  24.283 +                        if (!(val&1) && gus->ctrl[gus->voice]&1)
  24.284 +                        {
  24.285 +//                                printf("Voice on %i - start %05X end %05X freq %04X\n",gus->voice,gus->start[gus->voice],gus->end[gus->voice],gus->freq[gus->voice]);
  24.286 +//                                if (val&0x40) gus->cur[gus->voice]=gus->end[gus->voice]<<8;
  24.287 +//                                else          gus->cur[gus->voice]=gus->start[gus->voice]<<8;
  24.288 +                        }
  24.289 +
  24.290 +                        gus->ctrl[gus->voice] = val & 0x7f;
  24.291 +
  24.292 +                        old = gus->waveirqs[gus->voice];                        
  24.293 +                        gus->waveirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0;                        
  24.294 +                        if (gus->waveirqs[gus->voice] != old) 
  24.295 +                                pollgusirqs(gus);
  24.296 +                        break;
  24.297 +                        case 1: /*Frequency control*/
  24.298 +                        gus->freq[gus->voice]=(gus->freq[gus->voice]&0xFF)|(val<<8);
  24.299 +                        break;
  24.300 +                        case 2: /*Start addr high*/
  24.301 +                        gus->startx[gus->voice]=(gus->startx[gus->voice]&0x07FFF)|(val<<15);
  24.302 +                        gus->start[gus->voice]=(gus->start[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24);
  24.303 +//                        printf("Write %i start %08X %08X %02X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice],val);
  24.304 +                        break;
  24.305 +                        case 3: /*Start addr low*/
  24.306 +                        gus->startx[gus->voice]=(gus->startx[gus->voice]&0xFFF80)|(val&0x7F);
  24.307 +                        gus->start[gus->voice]=(gus->start[gus->voice]&0x1FFF00FF)|(val<<8);
  24.308 +//                        printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]);
  24.309 +                        break;
  24.310 +                        case 4: /*End addr high*/
  24.311 +                        gus->endx[gus->voice]=(gus->endx[gus->voice]&0x07FFF)|(val<<15);
  24.312 +                        gus->end[gus->voice]=(gus->end[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24);
  24.313 +//                        printf("Write %i end %08X %08X %02X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice],val);
  24.314 +                        break;
  24.315 +                        case 5: /*End addr low*/
  24.316 +                        gus->endx[gus->voice]=(gus->endx[gus->voice]&0xFFF80)|(val&0x7F);
  24.317 +                        gus->end[gus->voice]=(gus->end[gus->voice]&0x1FFF00FF)|(val<<8);
  24.318 +//                        printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]);
  24.319 +                        break;
  24.320 +
  24.321 +                        case 0x6: /*Ramp frequency*/
  24.322 +                        gus->rfreq[gus->voice] = (int)( (double)((val & 63) * (1 << 10))/(double)(1 << (3 * (val >> 6))));
  24.323 +//                        pclog("Ramp freq %02X %i %i %f %i\n", val, gus->voice, gus->rfreq[gus->voice], (double)(val & 63)/(double)(1 << (3*(val >> 6))), ins);
  24.324 +                        break;
  24.325 +                        case 0x7: /*Ramp start*/
  24.326 +                        gus->rstart[gus->voice] = val << 14;
  24.327 +//                        pclog("Ramp start %04X\n", gus->rstart[gus->voice] >> 10);
  24.328 +                        break;
  24.329 +                        case 0x8: /*Ramp end*/
  24.330 +                        gus->rend[gus->voice] = val << 14;
  24.331 +//                        pclog("Ramp end %04X\n", gus->rend[gus->voice] >> 10);
  24.332 +                        break;
  24.333 +                        case 0x9: /*Current volume*/
  24.334 +                        gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 14)) | (val << 14);
  24.335 +//                        printf("Vol %i is %04X\n",gus->voice,gus->curvol[gus->voice]);
  24.336 +                        break;
  24.337 +
  24.338 +                        case 0xA: /*Current addr high*/
  24.339 +                        gus->cur[gus->voice]=(gus->cur[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24);
  24.340 +                        gus->curx[gus->voice]=(gus->curx[gus->voice]&0x07FFF00)|((val<<15)<<8);
  24.341 +//                        printf("Write %i cur %08X %08X %02X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice],val);
  24.342 +//                      gus->cur[gus->voice]=(gus->cur[gus->voice]&0x007FFF00)|((val<<15)<<8);
  24.343 +                        break;
  24.344 +                        case 0xB: /*Current addr low*/
  24.345 +                        gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFF00FF)|(val<<8);
  24.346 +gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
  24.347 +//                      gus->cur[gus->voice]=(gus->cur[gus->voice]&0x0FFF8000)|((val&0x7F)<<8);
  24.348 +//                        printf("Write %i cur %08X %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]);
  24.349 +                        break;
  24.350 +                        case 0xD: /*Ramp control*/
  24.351 +                        old = gus->rampirqs[gus->voice];
  24.352 +                        gus->rctrl[gus->voice] = val & 0x7F;
  24.353 +                        gus->rampirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0;                        
  24.354 +                        if (gus->rampirqs[gus->voice] != old)
  24.355 +                                pollgusirqs(gus);
  24.356 +//                        printf("Ramp control %02i %02X %02X %i\n",gus->voice,val,gus->rampirqs[gus->voice],ins);
  24.357 +                        break;
  24.358 +
  24.359 +                        case 0xE:
  24.360 +                        gus->voices=(val&63)+1;
  24.361 +                        if (gus->voices>32) gus->voices=32;
  24.362 +                        if (gus->voices<14) gus->voices=14;
  24.363 +                        gus->global=val;
  24.364 +//                        printf("GUS voices %i\n",val&31);
  24.365 +                        if (gus->voices < 14)
  24.366 +                                gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0));
  24.367 +                        else
  24.368 +                                gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
  24.369 +                        break;
  24.370 +
  24.371 +                        case 0x41: /*DMA*/
  24.372 +                        if (val&1 && gus->dma != -1)
  24.373 +                        {
  24.374 +//                                printf("DMA start! %05X %02X\n",gus->dmaaddr,val);
  24.375 +                                if (val & 2)
  24.376 +                                {
  24.377 +                                        c=0;
  24.378 +                                        while (c<65536)
  24.379 +                                        {
  24.380 +                                                d = gus->ram[gus->dmaaddr];
  24.381 +                                                if (val & 0x80) d ^= 0x80;
  24.382 +                                                if (dma_channel_write(gus->dma, d) == DMA_NODATA) break;
  24.383 +                                                gus->dmaaddr++;
  24.384 +                                                gus->dmaaddr&=0xFFFFF;
  24.385 +                                                c++;
  24.386 +                                        }
  24.387 +//                                        printf("GUS->MEM Transferred %i bytes\n",c);
  24.388 +                                        gus->dmactrl=val&~0x40;
  24.389 +                                        if (val&0x20) gus->irqnext=1;
  24.390 +                                }
  24.391 +                                else
  24.392 +                                {
  24.393 +                                        c=0;
  24.394 +                                        while (c<65536)
  24.395 +                                        {
  24.396 +                                                d = dma_channel_read(gus->dma);
  24.397 +                                                if (d == DMA_NODATA) break;
  24.398 +                                                if (val&0x80) d^=0x80;
  24.399 +                                                gus->ram[gus->dmaaddr]=d;
  24.400 +                                                gus->dmaaddr++;
  24.401 +                                                gus->dmaaddr&=0xFFFFF;
  24.402 +                                                c++;
  24.403 +                                        }
  24.404 +//                                        printf("MEM->GUS Transferred %i bytes\n",c);
  24.405 +                                        gus->dmactrl=val&~0x40;
  24.406 +                                        if (val&0x20) gus->irqnext=1;
  24.407 +                                }
  24.408 +//                                exit(-1);
  24.409 +                        }
  24.410 +                        break;
  24.411 +
  24.412 +                        case 0x42: /*DMA address low*/
  24.413 +                        gus->dmaaddr=(gus->dmaaddr&0xFF0)|(val<<12);
  24.414 +                        break;
  24.415 +
  24.416 +                        case 0x43: /*Address low*/
  24.417 +                        gus->addr=(gus->addr&0xF00FF)|(val<<8);
  24.418 +                        break;
  24.419 +                        case 0x44: /*Address high*/
  24.420 +                        gus->addr=(gus->addr&0xFFFF)|((val<<16)&0xF0000);
  24.421 +                        break;
  24.422 +                        case 0x45: /*Timer control*/
  24.423 +                        if (!(val&4)) gus->irqstatus&=~4;
  24.424 +                        if (!(val&8)) gus->irqstatus&=~8;
  24.425 +                        if (!(val & 0x20))
  24.426 +                        {
  24.427 +                                gus->ad_status &= ~0x18;
  24.428 +                                nmi = 0;
  24.429 +                        }
  24.430 +                        if (!(val & 0x02))
  24.431 +                        {
  24.432 +                                gus->ad_status &= ~0x01;
  24.433 +                                nmi = 0;
  24.434 +                        }
  24.435 +//                        printf("Timer control %02X\n",val);
  24.436 +/*                        if ((val&4) && !(gus->tctrl&4))
  24.437 +                        {
  24.438 +                                gus->t1=gus->t1l;
  24.439 +                                gus->t1on=1;
  24.440 +                        }*/
  24.441 +                        gus->tctrl=val;
  24.442 +                        gus->sb_ctrl = val;
  24.443 +                        break;
  24.444 +                        case 0x46: /*Timer 1*/
  24.445 +                        gus->t1 = gus->t1l = val;
  24.446 +                        gus->t1on = 1;
  24.447 +//                        printf("GUS timer 1 %i\n",val);
  24.448 +                        break;
  24.449 +                        case 0x47: /*Timer 2*/
  24.450 +                        gus->t2 = gus->t2l = val;
  24.451 +                        gus->t2on = 1;
  24.452 +//                        printf("GUS timer 2 %i\n",val);
  24.453 +                        break;
  24.454 +                        
  24.455 +                        case 0x4c: /*Reset*/
  24.456 +                        gus->reset = val;
  24.457 +                        break;
  24.458 +                }
  24.459 +                break;
  24.460 +                case 0x347: /*DRAM access*/
  24.461 +                gus->ram[gus->addr]=val;
  24.462 +//                pclog("GUS RAM write %05X %02X\n",gus->addr,val);
  24.463 +                gus->addr&=0xFFFFF;
  24.464 +                break;
  24.465 +                case 0x248: case 0x388: 
  24.466 +                gus->adcommand = val; 
  24.467 +//                pclog("Setting ad command %02X %02X %p\n", val, gus->adcommand, &gus->adcommand);
  24.468 +                break;
  24.469 +                
  24.470 +                case 0x389:
  24.471 +                if ((gus->tctrl & GUS_TIMER_CTRL_AUTO) || gus->adcommand != 4)
  24.472 +                {
  24.473 +                        gus->ad_data = val;
  24.474 +                        gus->ad_status |= 0x01;
  24.475 +                        if (gus->sb_ctrl & 0x02)
  24.476 +                        {
  24.477 +                                if (gus->sb_nmi)
  24.478 +                                        nmi = 1;
  24.479 +                                else if (gus->irq != -1)
  24.480 +                                        picint(1 << gus->irq);
  24.481 +                        }
  24.482 +                }
  24.483 +                else if (!(gus->tctrl & GUS_TIMER_CTRL_AUTO) && gus->adcommand == 4)
  24.484 +                {
  24.485 +                        if (val & 0x80)
  24.486 +                        {
  24.487 +                                gus->ad_status &= ~0x60;
  24.488 +                        }
  24.489 +                        else
  24.490 +                        {
  24.491 +                                gus->ad_timer_ctrl = val;
  24.492 +                        
  24.493 +                                if (val & 0x01)
  24.494 +                                        gus->t1on = 1;
  24.495 +                                else
  24.496 +                                        gus->t1 = gus->t1l;
  24.497 +
  24.498 +                                if (val & 0x02)
  24.499 +                                        gus->t2on = 1;
  24.500 +                                else
  24.501 +                                        gus->t2 = gus->t2l;
  24.502 +                        }
  24.503 +                }
  24.504 +                break;
  24.505 +                                
  24.506 +                case 0x240:
  24.507 +                gus->midi_loopback = val & 0x20;
  24.508 +                gus->latch_enable = (val & 0x40) ? 2 : 1;
  24.509 +                break;
  24.510 +                
  24.511 +                case 0x24b:
  24.512 +                switch (gus->reg_ctrl & 0x07)
  24.513 +                {
  24.514 +                        case 0:
  24.515 +                        if (gus->latch_enable == 1)
  24.516 +                                gus->dma = gus_dmas[val & 7];
  24.517 +                        if (gus->latch_enable == 2)
  24.518 +                        {
  24.519 +                                gus->irq = gus_irqs[val & 7];
  24.520 +                                if (val & 0x40)
  24.521 +                                        gus->irq_midi = gus->irq;
  24.522 +                                else
  24.523 +                                        gus->irq_midi = gus_irqs_midi[(val >> 3) & 7];
  24.524 +                        
  24.525 +                                gus->sb_nmi = val & 0x80;
  24.526 +                        }
  24.527 +                        gus->latch_enable = 0;
  24.528 +//                        pclog("IRQ %i DMA %i\n", gus->irq, gus->dma);
  24.529 +                        break;
  24.530 +                        case 1:
  24.531 +                        gus->gp1 = val;
  24.532 +                        break;
  24.533 +                        case 2:
  24.534 +                        gus->gp2 = val;
  24.535 +                        break;
  24.536 +                        case 3:
  24.537 +                        gus->gp1_addr = val;
  24.538 +                        break;
  24.539 +                        case 4:
  24.540 +                        gus->gp2_addr = val;
  24.541 +                        break;
  24.542 +                        case 5:
  24.543 +                        gus->usrr = 0;
  24.544 +                        break;
  24.545 +                        case 6:
  24.546 +                        break;                        
  24.547 +                }                
  24.548 +                break;
  24.549 +                
  24.550 +                case 0x246:
  24.551 +                gus->ad_status |= 0x08;
  24.552 +                if (gus->sb_ctrl & 0x20)
  24.553 +                {
  24.554 +                        if (gus->sb_nmi)
  24.555 +                                nmi = 1;
  24.556 +                        else if (gus->irq != -1)
  24.557 +                                picint(1 << gus->irq);
  24.558 +                }
  24.559 +                break;
  24.560 +                case 0x24a:
  24.561 +                gus->sb_2xa = val;
  24.562 +                break;
  24.563 +                case 0x24c:
  24.564 +                gus->ad_status |= 0x10;
  24.565 +                if (gus->sb_ctrl & 0x20)
  24.566 +                {
  24.567 +                        if (gus->sb_nmi)
  24.568 +                                nmi = 1;
  24.569 +                        else if (gus->irq != -1)
  24.570 +                                picint(1 << gus->irq);
  24.571 +                }
  24.572 +                case 0x24d:
  24.573 +                gus->sb_2xc = val;
  24.574 +                break;
  24.575 +                case 0x24e:
  24.576 +                gus->sb_2xe = val;
  24.577 +                break;
  24.578 +                case 0x24f:
  24.579 +                gus->reg_ctrl = val;
  24.580 +                break;
  24.581 +        }
  24.582 +}
  24.583 +
  24.584 +uint8_t readgus(uint16_t addr, void *p)
  24.585 +{
  24.586 +        gus_t *gus = (gus_t *)p;
  24.587 +        uint8_t val;
  24.588 +//        /*if (addr!=0x246) */printf("Read GUS %04X %04X(%06X):%04X %02X\n",addr,CS,cs,pc,gus->global);
  24.589 +        switch (addr)
  24.590 +        {
  24.591 +                case 0x340: /*MIDI status*/
  24.592 +                val = gus->midi_status;
  24.593 +//                pclog("Read MIDI status %02X\n", val);
  24.594 +                break;
  24.595 +
  24.596 +                case 0x341: /*MIDI data*/
  24.597 +                val = gus->midi_data;
  24.598 +                gus->midi_status &= ~MIDI_INT_RECEIVE;
  24.599 +                gus_midi_update_int_status(gus);
  24.600 +                break;
  24.601 +                
  24.602 +                case 0x240: return 0;
  24.603 +                case 0x246: /*IRQ status*/
  24.604 +                val = gus->irqstatus & ~0x10;
  24.605 +                if (gus->ad_status & 0x19)
  24.606 +                        val |= 0x10;
  24.607 +//                pclog("Read IRQ status %02X\n", val);
  24.608 +                return val;
  24.609 +
  24.610 +                case 0x24F: return 0;
  24.611 +                case 0x342: return gus->voice;
  24.612 +                case 0x343: return gus->global;
  24.613 +                case 0x344: /*Global low*/
  24.614 +//                /*if (gus->global!=0x43 && gus->global!=0x44) */printf("Reading register %02X %02X\n",gus->global,gus->voice);
  24.615 +                switch (gus->global)
  24.616 +                {
  24.617 +                        case 0x82: /*Start addr high*/
  24.618 +                        return gus->start[gus->voice]>>16;
  24.619 +                        case 0x83: /*Start addr low*/
  24.620 +                        return gus->start[gus->voice]&0xFF;
  24.621 +
  24.622 +                        case 0x89: /*Current volume*/
  24.623 +                        return gus->rcur[gus->voice]>>6;
  24.624 +                        case 0x8A: /*Current addr high*/
  24.625 +                        return gus->cur[gus->voice]>>16;
  24.626 +                        case 0x8B: /*Current addr low*/
  24.627 +                        return gus->cur[gus->voice]&0xFF;
  24.628 +
  24.629 +                        case 0x8F: /*IRQ status*/
  24.630 +                        val=gus->irqstatus2;
  24.631 +//                        pclog("Read IRQ status - %02X\n",val);
  24.632 +                        gus->rampirqs[gus->irqstatus2&0x1F]=0;
  24.633 +                        gus->waveirqs[gus->irqstatus2&0x1F]=0;
  24.634 +                        pollgusirqs(gus);
  24.635 +                        return val;
  24.636 +                        
  24.637 +                        case 0x00: case 0x01: case 0x02: case 0x03:
  24.638 +                        case 0x04: case 0x05: case 0x06: case 0x07:
  24.639 +                        case 0x08: case 0x09: case 0x0a: case 0x0b:
  24.640 +                        case 0x0c: case 0x0d: case 0x0e: case 0x0f:
  24.641 +                        val = 0xff;
  24.642 +                        break;
  24.643 +                        
  24.644 +                        default:
  24.645 +                        fatal("Bad GUS global low read %02X\n",gus->global);
  24.646 +                }
  24.647 +                break;
  24.648 +                case 0x345: /*Global high*/
  24.649 +//                /*if (gus->global!=0x43 && gus->global!=0x44) */printf("HReading register %02X %02X\n",gus->global,gus->voice);
  24.650 +                switch (gus->global)
  24.651 +                {
  24.652 +                        case 0x80: /*Voice control*/
  24.653 +//                        pclog("Read voice control %02i %02X\n", gus->voice, gus->ctrl[gus->voice]|(gus->waveirqs[gus->voice]?0x80:0));
  24.654 +                        return gus->ctrl[gus->voice]|(gus->waveirqs[gus->voice]?0x80:0);
  24.655 +
  24.656 +                        case 0x82: /*Start addr high*/
  24.657 +                        return gus->start[gus->voice]>>24;
  24.658 +                        case 0x83: /*Start addr low*/
  24.659 +                        return gus->start[gus->voice]>>8;
  24.660 +
  24.661 +                        case 0x89: /*Current volume*/
  24.662 +//                        pclog("Read current volume %i\n", gus->rcur[gus->voice] >> 14);
  24.663 +                        return gus->rcur[gus->voice]>>14;
  24.664 +
  24.665 +                        case 0x8A: /*Current addr high*/
  24.666 +                        return gus->cur[gus->voice]>>24;
  24.667 +                        case 0x8B: /*Current addr low*/
  24.668 +                        return gus->cur[gus->voice]>>8;
  24.669 +
  24.670 +                        case 0x8D:
  24.671 +//                        pclog("Read ramp control %02X %04X %08X  %08X %08X\n",gus->rctrl[gus->voice]|(gus->rampirqs[gus->voice]?0x80:0),gus->rcur[gus->voice] >> 14,gus->rfreq[gus->voice],gus->rstart[gus->voice],gus->rend[gus->voice]);
  24.672 +                        return gus->rctrl[gus->voice]|(gus->rampirqs[gus->voice]?0x80:0);
  24.673 +
  24.674 +                        case 0x8F: /*IRQ status*/
  24.675 +//                        pclog("Read IRQ 1\n");
  24.676 +                        val=gus->irqstatus2;
  24.677 +                        gus->rampirqs[gus->irqstatus2&0x1F]=0;
  24.678 +                        gus->waveirqs[gus->irqstatus2&0x1F]=0;
  24.679 +                        pollgusirqs(gus);
  24.680 +//                        pclog("Read IRQ status - %02X  %i %i\n",val, gus->waveirqs[gus->irqstatus2&0x1F], gus->rampirqs[gus->irqstatus2&0x1F]);
  24.681 +                        return val;
  24.682 +
  24.683 +                        case 0x41: /*DMA control*/
  24.684 +                        val=gus->dmactrl|((gus->irqstatus&0x80)?0x40:0);
  24.685 +                        gus->irqstatus&=~0x80;
  24.686 +                        return val;
  24.687 +                        case 0x45: /*Timer control*/
  24.688 +                        return gus->tctrl;
  24.689 +                        case 0x49: /*Sampling control*/
  24.690 +                        return 0;
  24.691 +
  24.692 +                        case 0x00: case 0x01: case 0x02: case 0x03:
  24.693 +                        case 0x04: case 0x05: case 0x06: case 0x07:
  24.694 +                        case 0x08: case 0x09: case 0x0a: case 0x0b:
  24.695 +                        case 0x0c: case 0x0d: case 0x0e: case 0x0f:
  24.696 +                        val = 0xff;
  24.697 +                        break;
  24.698 +                        
  24.699 +                        default:
  24.700 +                        fatal("Bad GUS global high read %02X\n",gus->global);
  24.701 +                }                
  24.702 +                break;
  24.703 +                case 0x346: return 0xff;
  24.704 +                case 0x347: /*DRAM access*/
  24.705 +                val=gus->ram[gus->addr];
  24.706 +//                pclog("GUS RAM read %05X %02X\n",gus->addr,val);
  24.707 +                gus->addr&=0xFFFFF;
  24.708 +                return val;
  24.709 +                case 0x349: return 0;
  24.710 +                case 0x746: /*Revision level*/
  24.711 +                return 0xff; /*Pre 3.7 - no mixer*/
  24.712 +
  24.713 +                case 0x24b:
  24.714 +                switch (gus->reg_ctrl & 0x07)
  24.715 +                {
  24.716 +                        case 1:
  24.717 +                        val = gus->gp1;
  24.718 +                        break;
  24.719 +                        case 2:
  24.720 +                        val = gus->gp2;
  24.721 +                        break;
  24.722 +                        case 3:
  24.723 +                        val = gus->gp1_addr;
  24.724 +                        break;
  24.725 +                        case 4:
  24.726 +                        val = gus->gp2_addr;
  24.727 +                        break;
  24.728 +                }                
  24.729 +                break;
  24.730 +
  24.731 +                case 0x24c:
  24.732 +                val = gus->sb_2xc;
  24.733 +                if (gus->reg_ctrl & 0x20)
  24.734 +                        gus->sb_2xc &= 0x80;
  24.735 +                break;
  24.736 +                case 0x24e:
  24.737 +/*                gus->ad_status |= 0x10;
  24.738 +                if (gus->reg_ctrl & 0x80)
  24.739 +                {
  24.740 +                        gus->reg_ctrl_r |= 0x80;
  24.741 +                        if (gus->sb_nmi)
  24.742 +                                nmi = 1;
  24.743 +                        else
  24.744 +                                picint(1 << gus->irq);
  24.745 +                }*/
  24.746 +                return gus->sb_2xe;
  24.747 +                
  24.748 +                case 0x248: case 0x388:
  24.749 +//                pclog("Read ad_status %02X\n", gus->ad_status);
  24.750 +                if (gus->tctrl & GUS_TIMER_CTRL_AUTO)
  24.751 +                        val = gus->sb_2xa;
  24.752 +                else
  24.753 +                {
  24.754 +                        val = gus->ad_status & ~(gus->ad_timer_ctrl & 0x60);
  24.755 +                        if (val & 0x60)
  24.756 +                                val |= 0x80;
  24.757 +                }
  24.758 +                break;
  24.759 +
  24.760 +                case 0x249: 
  24.761 +                gus->ad_status &= ~0x01;
  24.762 +                nmi = 0;
  24.763 +                case 0x389:
  24.764 +                val = gus->ad_data;
  24.765 +                break;
  24.766 +                
  24.767 +                case 0x24A:
  24.768 +                val = gus->adcommand;
  24.769 +//                pclog("Read ad command %02X %02X %p\n", gus->adcommand, val, &gus->adcommand);
  24.770 +                break;
  24.771 +
  24.772 +        }
  24.773 +//        printf("Bad GUS read %04X! %02X\n",addr,gus->global);
  24.774 +//        exit(-1);
  24.775 +        return val;
  24.776 +}
  24.777 +
  24.778 +void gus_poll_timer_1(void *p)
  24.779 +{
  24.780 +        gus_t *gus = (gus_t *)p;
  24.781 +        
  24.782 +	gus->timer_1 += (TIMER_USEC * 80);
  24.783 +//	pclog("gus_poll_timer_1 %i %i  %i %i %02X\n", gustime, gus->t1on, gus->t1, gus->t1l, gus->tctrl);
  24.784 +        if (gus->t1on)
  24.785 +        {
  24.786 +                gus->t1++;
  24.787 +                if (gus->t1 > 0xFF)
  24.788 +                {                        
  24.789 +//                        gus->t1on=0;
  24.790 +                        gus->t1=gus->t1l;
  24.791 +                        gus->ad_status |= 0x40;
  24.792 +                        if (gus->tctrl&4)
  24.793 +                        {
  24.794 +                                if (gus->irq != -1)
  24.795 +                                        picint(1 << gus->irq);
  24.796 +                                gus->ad_status |= 0x04;
  24.797 +                                gus->irqstatus |= 0x04;
  24.798 +//                                pclog("GUS T1 IRQ!\n");
  24.799 +                        }
  24.800 +                }
  24.801 +        }
  24.802 +        if (gus->irqnext)
  24.803 +        {
  24.804 +//                pclog("Take IRQ\n");
  24.805 +                gus->irqnext=0;
  24.806 +                gus->irqstatus|=0x80;
  24.807 +                if (gus->irq != -1)
  24.808 +                        picint(1 << gus->irq);
  24.809 +        }
  24.810 +        gus_midi_update_int_status(gus);
  24.811 +}
  24.812 +
  24.813 +void gus_poll_timer_2(void *p)
  24.814 +{
  24.815 +        gus_t *gus = (gus_t *)p;
  24.816 +        
  24.817 +	gus->timer_2 += (TIMER_USEC * 320);
  24.818 +//	pclog("pollgus2 %i %i  %i %i %02X\n", gustime, gus->t2on, gus->t2, gus->t2l, gus->tctrl);
  24.819 +        if (gus->t2on)
  24.820 +        {
  24.821 +                gus->t2++;
  24.822 +                if (gus->t2 > 0xFF)
  24.823 +                {                        
  24.824 +//                        gus->t2on=0;
  24.825 +                        gus->t2=gus->t2l;
  24.826 +                        gus->ad_status |= 0x20;
  24.827 +                        if (gus->tctrl&8)
  24.828 +                        {
  24.829 +                                if (gus->irq != -1)
  24.830 +                                        picint(1 << gus->irq);
  24.831 +                                gus->ad_status |= 0x02;
  24.832 +                                gus->irqstatus |= 0x08;
  24.833 +//                                pclog("GUS T2 IRQ!\n");
  24.834 +                        }
  24.835 +                }
  24.836 +        }
  24.837 +        if (gus->irqnext)
  24.838 +        {
  24.839 +//                pclog("Take IRQ\n");
  24.840 +                gus->irqnext=0;
  24.841 +                gus->irqstatus|=0x80;
  24.842 +                if (gus->irq != -1)
  24.843 +                        picint(1 << gus->irq);
  24.844 +        }
  24.845 +}
  24.846 +
  24.847 +void gus_poll_wave(void *p)
  24.848 +{
  24.849 +        gus_t *gus = (gus_t *)p;
  24.850 +        uint32_t addr;
  24.851 +        int d;
  24.852 +        int16_t v;
  24.853 +        int32_t vl;
  24.854 +        int update_irqs = 0;
  24.855 +                
  24.856 +        gus->samp_timer += gus->samp_latch;
  24.857 +        
  24.858 +        gus->out_l = gus->out_r = 0;
  24.859 +
  24.860 +        if ((gus->reset & 3) != 3)
  24.861 +                return;
  24.862 +//pclog("gus_poll_wave\n");        
  24.863 +        for (d=0;d<32;d++)
  24.864 +        {
  24.865 +                if (!(gus->ctrl[d] & 3))
  24.866 +                {
  24.867 +                        if (gus->ctrl[d] & 4)
  24.868 +                        {
  24.869 +                                addr = gus->cur[d] >> 9;
  24.870 +                                addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE);
  24.871 +                                if (!(gus->freq[d] >> 10)) /*Interpolate*/
  24.872 +                                {
  24.873 +                                        vl  = (int16_t)(int8_t)((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (gus->cur[d] & 511));
  24.874 +                                        vl += (int16_t)(int8_t)((gus->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (gus->cur[d] & 511);
  24.875 +                                        v = vl >> 9;
  24.876 +                                }
  24.877 +                                else
  24.878 +                                        v = (int16_t)(int8_t)((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80);
  24.879 +                        }
  24.880 +                        else
  24.881 +                        {
  24.882 +                                if (!(gus->freq[d] >> 10)) /*Interpolate*/
  24.883 +                                {
  24.884 +                                        vl  = ((int8_t)((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (gus->cur[d] & 511));
  24.885 +                                        vl += ((int8_t)((gus->ram[((gus->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (gus->cur[d] & 511);
  24.886 +                                        v = vl >> 9;
  24.887 +                                }
  24.888 +                                else
  24.889 +                                        v = (int16_t)(int8_t)((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80);
  24.890 +                        }
  24.891 +
  24.892 +//                        pclog("Voice %i : %04X %05X %04X ", d, v, gus->cur[d] >> 9, gus->rcur[d] >> 10);
  24.893 +                        if ((gus->rcur[d] >> 14) > 4095) v = (int16_t)(float)(v) * 24.0 * vol16bit[4095];
  24.894 +                        else                            v = (int16_t)(float)(v) * 24.0 * vol16bit[(gus->rcur[d]>>10) & 4095];
  24.895 +//                        pclog("%f %04X\n", vol16bit[(gus->rcur[d]>>10) & 4095], v);
  24.896 +
  24.897 +                        gus->out_l += v;
  24.898 +                        gus->out_r += v;
  24.899 +
  24.900 +                        if (gus->ctrl[d]&0x40)
  24.901 +                        {
  24.902 +                                gus->cur[d] -= (gus->freq[d] >> 1);
  24.903 +                                if (gus->cur[d] <= gus->start[d])
  24.904 +                                {
  24.905 +                                        int diff = gus->start[d] - gus->cur[d];
  24.906 +                                        if (!(gus->rctrl[d]&4))
  24.907 +                                        {
  24.908 +                                                if (!(gus->ctrl[d]&8)) 
  24.909 +                                                {
  24.910 +                                                        gus->ctrl[d] |= 1;
  24.911 +                                                        gus->cur[d] = (gus->ctrl[d] & 0x40) ? gus->end[d] : gus->start[d];
  24.912 +                                                }                                                
  24.913 +                                                else 
  24.914 +                                                {
  24.915 +                                                        if (gus->ctrl[d]&0x10) gus->ctrl[d]^=0x40;
  24.916 +                                                        gus->cur[d] = (gus->ctrl[d] & 0x40) ? (gus->end[d] - diff) : (gus->start[d] + diff);
  24.917 +                                                }
  24.918 +                                        }
  24.919 +                                        if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d])
  24.920 +                                        {
  24.921 +                                                gus->waveirqs[d] = 1;
  24.922 +                                                update_irqs = 1;
  24.923 +//                                                pclog("Causing wave IRQ %02X %i\n", gus->ctrl[d], d);
  24.924 +                                        }
  24.925 +                                }
  24.926 +                        }
  24.927 +                        else
  24.928 +                        {
  24.929 +                                gus->cur[d] += (gus->freq[d] >> 1);
  24.930 +
  24.931 +                                if (gus->cur[d] >= gus->end[d])
  24.932 +                                {
  24.933 +                                        int diff = gus->cur[d] - gus->end[d];
  24.934 +                                        if (!(gus->rctrl[d]&4))
  24.935 +                                        {
  24.936 +                                                if (!(gus->ctrl[d]&8)) 
  24.937 +                                                {
  24.938 +                                                        gus->ctrl[d] |= 1;
  24.939 +                                                        gus->cur[d] = (gus->ctrl[d] & 0x40) ? gus->end[d] : gus->start[d];
  24.940 +                                                }                                                
  24.941 +                                                else 
  24.942 +                                                {
  24.943 +                                                        if (gus->ctrl[d]&0x10) gus->ctrl[d]^=0x40;
  24.944 +                                                        gus->cur[d] = (gus->ctrl[d] & 0x40) ? (gus->end[d] - diff) : (gus->start[d] + diff);
  24.945 +                                                }
  24.946 +                                        }
  24.947 +                                        if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d]) 
  24.948 +                                        {
  24.949 +                                                gus->waveirqs[d] = 1;
  24.950 +                                                update_irqs = 1;
  24.951 +//                                                pclog("Causing wave IRQ %02X %i\n", gus->ctrl[d], d);
  24.952 +                                        }
  24.953 +                                }
  24.954 +                        }
  24.955 +                }
  24.956 +                if (!(gus->rctrl[d] & 3))
  24.957 +                {
  24.958 +                        if (gus->rctrl[d] & 0x40)
  24.959 +                        {
  24.960 +                                gus->rcur[d] -= gus->rfreq[d];
  24.961 +                                if (gus->rcur[d] <= gus->rstart[d])
  24.962 +                                {
  24.963 +                                        int diff = gus->rstart[d] - gus->rcur[d];
  24.964 +                                        if (!(gus->rctrl[d] & 8)) 
  24.965 +                                        {
  24.966 +                                                gus->rctrl[d] |= 1;
  24.967 +                                                gus->rcur[d] = (gus->rctrl[d] & 0x40) ? gus->rstart[d] : gus->rend[d];
  24.968 +                                        }                                                
  24.969 +                                        else 
  24.970 +                                        {
  24.971 +                                                if (gus->rctrl[d] & 0x10) gus->rctrl[d] ^= 0x40;
  24.972 +                                                gus->rcur[d] = (gus->rctrl[d] & 0x40) ? (gus->rend[d] - diff) : (gus->rstart[d] + diff);
  24.973 +                                        }
  24.974 +
  24.975 +                                        if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d])
  24.976 +                                        {
  24.977 +                                                gus->rampirqs[d] = 1;
  24.978 +                                                update_irqs = 1;
  24.979 +//                                                pclog("Causing ramp IRQ %02X %i\n",gus->rctrl[d], d);
  24.980 +                                        }
  24.981 +                                }
  24.982 +                        }
  24.983 +                        else
  24.984 +                        {
  24.985 +                                gus->rcur[d] += gus->rfreq[d];
  24.986 +//                                        if (d == 1) printf("RCUR+ %i %08X %08X %08X %08X\n",d,gus->rfreq[d],gus->rcur[d],gus->rstart[d],gus->rend[d]);
  24.987 +                                if (gus->rcur[d] >= gus->rend[d])
  24.988 +                                {
  24.989 +                                        int diff = gus->rcur[d] - gus->rend[d];
  24.990 +                                        if (!(gus->rctrl[d] & 8)) 
  24.991 +                                        {
  24.992 +                                                gus->rctrl[d] |= 1;
  24.993 +                                                gus->rcur[d] = (gus->rctrl[d] & 0x40) ? gus->rstart[d] : gus->rend[d];
  24.994 +                                        }                                                
  24.995 +                                        else 
  24.996 +                                        {
  24.997 +                                                if (gus->rctrl[d] & 0x10) gus->rctrl[d] ^= 0x40;
  24.998 +                                                gus->rcur[d] = (gus->rctrl[d] & 0x40) ? (gus->rend[d] - diff) : (gus->rstart[d] + diff);
  24.999 +                                        }
 24.1000 +
 24.1001 +                                        if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d])
 24.1002 +                                        {
 24.1003 +                                                gus->rampirqs[d] = 1;
 24.1004 +                                                update_irqs = 1;
 24.1005 +//                                                        pclog("Causing ramp IRQ %02X %i\n",gus->rctrl[d], d);
 24.1006 +                                        }
 24.1007 +                                }
 24.1008 +                        }
 24.1009 +                }
 24.1010 +        }
 24.1011 +
 24.1012 +        if (update_irqs)
 24.1013 +                pollgusirqs(gus);
 24.1014 +}
 24.1015 +
 24.1016 +void gus_poll(void *p)
 24.1017 +{
 24.1018 +        gus_t *gus = (gus_t *)p;
 24.1019 +        
 24.1020 +        if (gus->pos >= SOUNDBUFLEN)
 24.1021 +                return;
 24.1022 +
 24.1023 +        //pclog("gus_poll\n");
 24.1024 +        gus->buffer[0][gus->pos] = gus->out_l;
 24.1025 +        gus->buffer[1][gus->pos] = gus->out_r;
 24.1026 +
 24.1027 +        gus->pos++;
 24.1028 +}
 24.1029 +
 24.1030 +static void gus_get_buffer(int16_t *buffer, int len, void *p)
 24.1031 +{
 24.1032 +        gus_t *gus = (gus_t *)p;
 24.1033 +        int c;
 24.1034 +
 24.1035 +        for (c = 0; c < len * 2; c++)
 24.1036 +        {
 24.1037 +                buffer[c] += gus->buffer[c & 1][c >> 1];
 24.1038 +        }
 24.1039 +
 24.1040 +        gus->pos = 0;
 24.1041 +}
 24.1042 +
 24.1043 +
 24.1044 +void *gus_init()
 24.1045 +{
 24.1046 +        int c;
 24.1047 +	double out = 1.0;
 24.1048 +        gus_t *gus = malloc(sizeof(gus_t));
 24.1049 +        memset(gus, 0, sizeof(gus_t));
 24.1050 +
 24.1051 +        gus->ram = malloc(1 << 20);
 24.1052 +        memset(gus->ram, 0, 1 << 20);
 24.1053 +        
 24.1054 +        pclog("gus_init\n");
 24.1055 +        
 24.1056 +        for (c=0;c<32;c++)
 24.1057 +        {
 24.1058 +                gus->ctrl[c]=1;
 24.1059 +                gus->rctrl[c]=1;
 24.1060 +                gus->rfreq[c]=63*512;
 24.1061 +        }
 24.1062 +
 24.1063 +	for (c=4095;c>=0;c--) {
 24.1064 +		vol16bit[c]=out;//(float)c/4095.0;//out;
 24.1065 +		out/=1.002709201;		/* 0.0235 dB Steps */
 24.1066 +	}
 24.1067 +
 24.1068 +	printf("Top volume %f %f %f %f\n",vol16bit[4095],vol16bit[3800],vol16bit[3000],vol16bit[2048]);
 24.1069 +	gus->voices=14;
 24.1070 +
 24.1071 +        gus->samp_timer = gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0));
 24.1072 +        
 24.1073 +        io_sethandler(0x0240, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL,  gus);
 24.1074 +        io_sethandler(0x0340, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL,  gus);
 24.1075 +        io_sethandler(0x0746, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL,  gus);        
 24.1076 +        io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL,  gus);
 24.1077 +        timer_add(gus_poll_wave, &gus->samp_timer, TIMER_ALWAYS_ENABLED,  gus);
 24.1078 +        timer_add(gus_poll_timer_1, &gus->timer_1, TIMER_ALWAYS_ENABLED,  gus);
 24.1079 +        timer_add(gus_poll_timer_2, &gus->timer_2, TIMER_ALWAYS_ENABLED,  gus);
 24.1080 +
 24.1081 +        sound_add_handler(gus_poll, gus_get_buffer, gus);
 24.1082 +        
 24.1083 +        return gus;
 24.1084 +}
 24.1085 +
 24.1086 +void gus_close(void *p)
 24.1087 +{
 24.1088 +        gus_t *gus = (gus_t *)p;
 24.1089 +        
 24.1090 +        free(gus->ram);
 24.1091 +        free(gus);
 24.1092 +}
 24.1093 +
 24.1094 +void gus_speed_changed(void *p)
 24.1095 +{
 24.1096 +        gus_t *gus = (gus_t *)p;
 24.1097 +
 24.1098 +        if (gus->voices < 14)
 24.1099 +                gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0));
 24.1100 +        else
 24.1101 +                gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
 24.1102 +}
 24.1103 +
 24.1104 +device_t gus_device =
 24.1105 +{
 24.1106 +        "Gravis UltraSound",
 24.1107 +        gus_init,
 24.1108 +        gus_close,
 24.1109 +        gus_speed_changed
 24.1110 +};
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/src/sound_gus.h	Mon May 27 19:56:33 2013 +0100
    25.3 @@ -0,0 +1,1 @@
    25.4 +extern device_t gus_device;
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/src/sound_opl.c	Mon May 27 19:56:33 2013 +0100
    26.3 @@ -0,0 +1,195 @@
    26.4 +#include <stdint.h>
    26.5 +#include <stdlib.h>
    26.6 +#include "ibm.h"
    26.7 +#include "io.h"
    26.8 +#include "sound_opl.h"
    26.9 +
   26.10 +/*Interfaces between PCem and the actual OPL emulator*/
   26.11 +
   26.12 +
   26.13 +uint8_t opl2_read(uint16_t a, void *priv)
   26.14 +{
   26.15 +        opl_t *opl = (opl_t *)priv;
   26.16 +
   26.17 +        cycles -= (int)(isa_timing * 8);
   26.18 +        return ym3812_read(opl->YM3812[0], a);
   26.19 +}
   26.20 +void opl2_write(uint16_t a, uint8_t v, void *priv)
   26.21 +{
   26.22 +        opl_t *opl = (opl_t *)priv;
   26.23 +
   26.24 +        ym3812_write(opl->YM3812[0],a,v);
   26.25 +        ym3812_write(opl->YM3812[1],a,v);
   26.26 +}
   26.27 +
   26.28 +uint8_t opl2_l_read(uint16_t a, void *priv)
   26.29 +{
   26.30 +        opl_t *opl = (opl_t *)priv;
   26.31 +
   26.32 +        cycles -= (int)(isa_timing * 8);
   26.33 +        return ym3812_read(opl->YM3812[0], a);
   26.34 +}
   26.35 +void opl2_l_write(uint16_t a, uint8_t v, void *priv)
   26.36 +{
   26.37 +        opl_t *opl = (opl_t *)priv;
   26.38 +
   26.39 +        ym3812_write(opl->YM3812[0],a,v);
   26.40 +}
   26.41 +
   26.42 +uint8_t opl2_r_read(uint16_t a, void *priv)
   26.43 +{
   26.44 +        opl_t *opl = (opl_t *)priv;
   26.45 +
   26.46 +        cycles -= (int)(isa_timing * 8);
   26.47 +        return ym3812_read(opl->YM3812[1], a);
   26.48 +}
   26.49 +void opl2_r_write(uint16_t a, uint8_t v, void *priv)
   26.50 +{
   26.51 +        opl_t *opl = (opl_t *)priv;
   26.52 +
   26.53 +        ym3812_write(opl->YM3812[1],a,v);
   26.54 +}
   26.55 +
   26.56 +uint8_t opl3_read(uint16_t a, void *priv)
   26.57 +{
   26.58 +        opl_t *opl = (opl_t *)priv;
   26.59 +
   26.60 +        cycles -= (int)(isa_timing * 8);
   26.61 +        return ymf262_read(opl->YMF262, a);
   26.62 +}
   26.63 +void opl3_write(uint16_t a, uint8_t v, void *priv)
   26.64 +{
   26.65 +        opl_t *opl = (opl_t *)priv;
   26.66 +        
   26.67 +        ymf262_write(opl->YMF262, a, v);
   26.68 +}
   26.69 +
   26.70 +
   26.71 +void opl2_poll(opl_t *opl, int16_t *bufl, int16_t *bufr)
   26.72 +{
   26.73 +        ym3812_update_one(opl->YM3812[0], bufl, 1);
   26.74 +        ym3812_update_one(opl->YM3812[1], bufr, 1);
   26.75 +
   26.76 +        opl->filtbuf[0] = *bufl = ((*bufl) / 4) + ((opl->filtbuf[0] * 11) / 16);
   26.77 +        opl->filtbuf[1] = *bufr = ((*bufr) / 4) + ((opl->filtbuf[1] * 11) / 16);
   26.78 +
   26.79 +        if (opl->timers_enable[0][0])
   26.80 +        {
   26.81 +                opl->timers[0][0]--;
   26.82 +                if (opl->timers[0][0] < 0) ym3812_timer_over(opl->YM3812[0], 0);
   26.83 +        }
   26.84 +        if (opl->timers_enable[0][1])
   26.85 +        {
   26.86 +                opl->timers[0][1]--;
   26.87 +                if (opl->timers[0][1] < 0) ym3812_timer_over(opl->YM3812[0], 1);
   26.88 +        }
   26.89 +        if (opl->timers_enable[1][0])
   26.90 +        {
   26.91 +                opl->timers[1][0]--;
   26.92 +                if (opl->timers[1][0] < 0) ym3812_timer_over(opl->YM3812[1], 0);
   26.93 +        }
   26.94 +        if (opl->timers_enable[1][1])
   26.95 +        {
   26.96 +                opl->timers[1][1]--;
   26.97 +                if (opl->timers[1][1] < 0) ym3812_timer_over(opl->YM3812[1], 1);
   26.98 +        }
   26.99 +}
  26.100 +
  26.101 +void opl3_poll(opl_t *opl, int16_t *bufl, int16_t *bufr)
  26.102 +{
  26.103 +        ymf262_update_one(opl->YMF262, opl->bufs, 1);
  26.104 +
  26.105 +        opl->filtbuf[0] = *bufl = ((opl->bufs[0][0]) / 4) + ((opl->filtbuf[0] * 11) / 16);
  26.106 +        opl->filtbuf[1] = *bufr = ((opl->bufs[1][0]) / 4) + ((opl->filtbuf[1] * 11) / 16);
  26.107 +
  26.108 +        if (opl->timers_enable[0][0])
  26.109 +        {
  26.110 +                opl->timers[0][0]--;
  26.111 +                if (opl->timers[0][0] < 0) 
  26.112 +                {
  26.113 +                        opl->timers_enable[0][0] = 0;
  26.114 +                        ymf262_timer_over(opl->YMF262, 0);
  26.115 +                }
  26.116 +        }
  26.117 +        if (opl->timers_enable[0][1])
  26.118 +        {
  26.119 +                opl->timers[0][1]--;
  26.120 +                if (opl->timers[0][1] < 0) 
  26.121 +                {
  26.122 +                        opl->timers_enable[0][1] = 0;
  26.123 +                        ymf262_timer_over(opl->YMF262, 1);
  26.124 +                }
  26.125 +        }
  26.126 +}
  26.127 +
  26.128 +void ym3812_timer_set_0(void *param, int timer, attotime period)
  26.129 +{
  26.130 +        opl_t *opl = (opl_t *)param;
  26.131 +        
  26.132 +        opl->timers[0][timer] = period / 20833;
  26.133 +        if (!opl->timers[0][timer]) opl->timers[0][timer] = 1;
  26.134 +        opl->timers_enable[0][timer] = period ? 1 : 0;
  26.135 +}
  26.136 +void ym3812_timer_set_1(void *param, int timer, attotime period)
  26.137 +{
  26.138 +        opl_t *opl = (opl_t *)param;
  26.139 +
  26.140 +        opl->timers[1][timer] = period / 20833;
  26.141 +        if (!opl->timers[1][timer]) opl->timers[1][timer] = 1;
  26.142 +        opl->timers_enable[1][timer] = period ? 1 : 0;
  26.143 +}
  26.144 +
  26.145 +void ymf262_timer_set(void *param, int timer, attotime period)
  26.146 +{
  26.147 +        opl_t *opl = (opl_t *)param;
  26.148 +
  26.149 +        opl->timers[0][timer] = period / 20833;
  26.150 +        if (!opl->timers[0][timer]) opl->timers[0][timer] = 1;
  26.151 +        opl->timers_enable[0][timer] = period ? 1 : 0;
  26.152 +}
  26.153 +
  26.154 +void opl2_init(opl_t *opl)
  26.155 +{
  26.156 +        opl->bufs[0] = (int16_t *)malloc(4);
  26.157 +        opl->bufs[1] = (int16_t *)malloc(4);
  26.158 +        opl->bufs[2] = (int16_t *)malloc(4);
  26.159 +        opl->bufs[3] = (int16_t *)malloc(4);
  26.160 +        
  26.161 +        opl->YM3812[0] = ym3812_init(NULL, 3579545, 48000);
  26.162 +        ym3812_reset_chip(opl->YM3812[0]);
  26.163 +        ym3812_set_timer_handler(opl->YM3812[0], ym3812_timer_set_0, opl);
  26.164 +
  26.165 +        opl->YM3812[1] = ym3812_init(NULL, 3579545, 48000);
  26.166 +        ym3812_reset_chip(opl->YM3812[1]);
  26.167 +        ym3812_set_timer_handler(opl->YM3812[1], ym3812_timer_set_1, opl);
  26.168 +}
  26.169 +
  26.170 +void opl3_init(opl_t *opl)
  26.171 +{
  26.172 +        opl->bufs[0] = (int16_t *)malloc(4);
  26.173 +        opl->bufs[1] = (int16_t *)malloc(4);
  26.174 +        opl->bufs[2] = (int16_t *)malloc(4);
  26.175 +        opl->bufs[3] = (int16_t *)malloc(4);
  26.176 +
  26.177 +        opl->YMF262 = ymf262_init(NULL, 3579545 * 4, 48000);
  26.178 +        ymf262_reset_chip(opl->YMF262);
  26.179 +        ymf262_set_timer_handler(opl->YMF262, ymf262_timer_set, opl);
  26.180 +}
  26.181 +
  26.182 +void opl2_close(opl_t *opl)
  26.183 +{
  26.184 +        free(opl->bufs[0]);
  26.185 +        free(opl->bufs[1]);
  26.186 +        
  26.187 +        ym3812_shutdown(opl->YM3812[0]);
  26.188 +        ym3812_shutdown(opl->YM3812[1]);
  26.189 +}
  26.190 +
  26.191 +void opl3_close(opl_t *opl)
  26.192 +{
  26.193 +        free(opl->bufs[0]);
  26.194 +        free(opl->bufs[1]);
  26.195 +        
  26.196 +        ym3812_shutdown(opl->YM3812[0]);
  26.197 +        ymf262_shutdown(opl->YMF262);
  26.198 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/src/sound_opl.h	Mon May 27 19:56:33 2013 +0100
    27.3 @@ -0,0 +1,35 @@
    27.4 +#include "mame/fmopl.h"
    27.5 +#include "mame/ymf262.h"
    27.6 +
    27.7 +typedef struct opl_t
    27.8 +{
    27.9 +        void *YM3812[2];
   27.10 +        void *YMF262;
   27.11 +        
   27.12 +        int timers[2][2];
   27.13 +        int timers_enable[2][2];
   27.14 +
   27.15 +        int16_t *bufs[4];
   27.16 +        int16_t filtbuf[2];
   27.17 +} opl_t;
   27.18 +
   27.19 +uint8_t opl_read(uint16_t a, void *priv);
   27.20 +void opl_write(uint16_t a, uint8_t v, void *priv);
   27.21 +
   27.22 +uint8_t opl2_read(uint16_t a, void *priv);
   27.23 +void opl2_write(uint16_t a, uint8_t v, void *priv);
   27.24 +uint8_t opl2_l_read(uint16_t a, void *priv);
   27.25 +void opl2_l_write(uint16_t a, uint8_t v, void *priv);
   27.26 +uint8_t opl2_r_read(uint16_t a, void *priv);
   27.27 +void opl2_r_write(uint16_t a, uint8_t v, void *priv);
   27.28 +uint8_t opl3_read(uint16_t a, void *priv);
   27.29 +void opl3_write(uint16_t a, uint8_t v, void *priv);
   27.30 +
   27.31 +void opl2_poll(opl_t *opl, int16_t *bufl, int16_t *bufr);
   27.32 +void opl3_poll(opl_t *opl, int16_t *bufl, int16_t *bufr);
   27.33 +
   27.34 +void opl2_init(opl_t *opl);
   27.35 +void opl3_init(opl_t *opl);
   27.36 +
   27.37 +void opl2_close(opl_t *opl);
   27.38 +void opl3_close(opl_t *opl);
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/src/sound_pas16.c	Mon May 27 19:56:33 2013 +0100
    28.3 @@ -0,0 +1,753 @@
    28.4 +#include <stdlib.h>
    28.5 +#include "ibm.h"
    28.6 +
    28.7 +#include "device.h"
    28.8 +#include "dma.h"
    28.9 +#include "filters.h"
   28.10 +#include "io.h"
   28.11 +#include "pic.h"
   28.12 +#include "pit.h"
   28.13 +#include "sound_opl.h"
   28.14 +#include "sound_pas16.h"
   28.15 +#include "sound_sb_dsp.h"
   28.16 +#include "timer.h"
   28.17 +
   28.18 +/*      Original PAS uses
   28.19 +                2 x OPL2
   28.20 +                PIT - sample rate/count
   28.21 +                LMC835N/LMC1982 - mixer
   28.22 +                YM3802 - MIDI Control System
   28.23 +                
   28.24 +
   28.25 +        9A01 - IO base
   28.26 +                base >> 2
   28.27 +                
   28.28 +        All below + IO base
   28.29 +
   28.30 +        B89 - interrupt status / clear
   28.31 +                bit 2 - sample rate
   28.32 +                bit 3 - PCM
   28.33 +                bit 4 - MIDI
   28.34 +        
   28.35 +        B88 - Audio mixer control register
   28.36 +        
   28.37 +        B8A - Audio filter control
   28.38 +                bit 5 - mute?
   28.39 +        
   28.40 +        B8B - interrupt mask / board ID
   28.41 +                bits 5-7 - board ID (read only on PAS16)
   28.42 +
   28.43 +        F88 - PCM data (low)
   28.44 +        
   28.45 +        F89 - PCM data (high)
   28.46 +        
   28.47 +        F8A - PCM control?
   28.48 +                bit 4 - input/output select (1 = output)
   28.49 +                bit 5 - mono/stereo select
   28.50 +                bit 6 - PCM enable
   28.51 +                
   28.52 +        1388-138b - PIT clocked at 1193180 Hz
   28.53 +                1388 - sample rate
   28.54 +                1389 - sample count
   28.55 +                
   28.56 +        178b - 
   28.57 +        2789 - board revision
   28.58 +        
   28.59 +        8389 -
   28.60 +                bit 2 - 8/16 bit
   28.61 +                
   28.62 +        BF88 - wait states
   28.63 +        
   28.64 +        EF8B -
   28.65 +                bit 3 - 16 bits okay ?
   28.66 +                 
   28.67 +        F388 - 
   28.68 +                bit 6 - joystick enable
   28.69 +        
   28.70 +        F389 -
   28.71 +                bits 0-2 - DMA
   28.72 +                
   28.73 +        F38A -
   28.74 +                bits 0-3 - IRQ
   28.75 +
   28.76 +        F788 -
   28.77 +                bit 1 - SB emulation
   28.78 +                bit 0 - MPU401 emulation
   28.79 +                
   28.80 +        F789 - SB base addr
   28.81 +                bits 0-3 - addr bits 4-7
   28.82 +        
   28.83 +        FB8A - SB IRQ/DMA
   28.84 +                bits 3-5 - IRQ
   28.85 +                bits 6-7 - DMA
   28.86 +        
   28.87 +        FF88 - board model
   28.88 +                3 = PAS16
   28.89 +*/
   28.90 +
   28.91 +static uint8_t pas16_pit_in(uint16_t port, void *priv);
   28.92 +static void pas16_pit_out(uint16_t port, uint8_t val, void *priv);
   28.93 +//static void pas16_update_irqs();
   28.94 +
   28.95 +typedef struct pas16_t
   28.96 +{
   28.97 +        uint16_t base;
   28.98 +        
   28.99 +        int irq, dma;
  28.100 + 
  28.101 +        uint8_t audiofilt;
  28.102 +        
  28.103 +        uint8_t audio_mixer;
  28.104 +               
  28.105 +        uint8_t compat, compat_base;
  28.106 +        
  28.107 +        uint8_t enhancedscsi;
  28.108 +        
  28.109 +        uint8_t io_conf_1, io_conf_2, io_conf_3, io_conf_4;
  28.110 +        
  28.111 +        uint8_t irq_stat, irq_ena;
  28.112 +        
  28.113 +        uint8_t pcm_ctrl;
  28.114 +        uint16_t pcm_dat;
  28.115 +
  28.116 +        uint16_t pcm_dat_l, pcm_dat_r;
  28.117 +                
  28.118 +        uint8_t sb_irqdma;
  28.119 +        
  28.120 +        int stereo_lr;
  28.121 +        
  28.122 +        uint8_t sys_conf_1, sys_conf_2, sys_conf_3, sys_conf_4;
  28.123 +        
  28.124 +        struct
  28.125 +        {
  28.126 +                uint32_t l[3];
  28.127 +                int c[3];
  28.128 +                uint8_t m[3];
  28.129 +                uint8_t ctrl, ctrls[2];
  28.130 +                int wp, rm[3], wm[3];
  28.131 +                uint16_t rl[3];
  28.132 +                int thit[3];
  28.133 +                int delay[3];
  28.134 +                int rereadlatch[3];
  28.135 +                int enable[3];
  28.136 +        } pit;
  28.137 +
  28.138 +        opl_t    opl;
  28.139 +        sb_dsp_t dsp;
  28.140 +
  28.141 +        int16_t opl_buffer[SOUNDBUFLEN * 2];
  28.142 +        int16_t pcm_buffer[2][SOUNDBUFLEN];
  28.143 +        int16_t dsp_buffer[SOUNDBUFLEN * 2];
  28.144 +
  28.145 +        int pos;
  28.146 +} pas16_t;
  28.147 +
  28.148 +static int pas16_dmas[8] = {4, 1, 2, 3, 0, 5, 6, 7};
  28.149 +static int pas16_irqs[16] = {0, 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, 15, 0, 0, 0, 0};
  28.150 +static int pas16_sb_irqs[8] = {0, 2, 3, 5, 7, 10, 11, 12};
  28.151 +static int pas16_sb_dmas[8] = {0, 1, 2, 3};
  28.152 +
  28.153 +enum
  28.154 +{
  28.155 +        PAS16_INT_SAMP = 0x04,
  28.156 +        PAS16_INT_PCM  = 0x08,
  28.157 +};
  28.158 +
  28.159 +enum
  28.160 +{
  28.161 +        PAS16_PCM_MONO = 0x20,
  28.162 +        PAS16_PCM_ENA  = 0x40
  28.163 +};
  28.164 +
  28.165 +enum
  28.166 +{
  28.167 +        PAS16_SC2_16BIT = 0x04,
  28.168 +        PAS16_SC2_MSBINV = 0x10
  28.169 +};
  28.170 +
  28.171 +enum
  28.172 +{
  28.173 +        PAS16_FILT_MUTE = 0x20
  28.174 +};
  28.175 +
  28.176 +static uint8_t pas16_in(uint16_t port, void *p)
  28.177 +{
  28.178 +        pas16_t *pas16 = (pas16_t *)p;
  28.179 +        uint8_t temp;
  28.180 +/*        if (CS == 0xCA53 && pc == 0x3AFC)
  28.181 +                fatal("here");*/
  28.182 +        switch ((port - pas16->base) + 0x388)
  28.183 +        {
  28.184 +                case 0x388: case 0x389: case 0x38a: case 0x38b:
  28.185 +                temp = opl3_read((port - pas16->base) + 0x388, &pas16->opl);
  28.186 +                break;
  28.187 +                
  28.188 +                case 0xb88:
  28.189 +                temp = pas16->audio_mixer;
  28.190 +                break;
  28.191 +                
  28.192 +                case 0xb89:
  28.193 +                temp = pas16->irq_stat;
  28.194 +                break;
  28.195 +        
  28.196 +                case 0xb8a:
  28.197 +                temp = pas16->audiofilt;
  28.198 +                break;
  28.199 +                        
  28.200 +                case 0xb8b:
  28.201 +                temp = (pas16->irq_ena & ~0xe0) | 0x20;
  28.202 +                break;
  28.203 +                
  28.204 +                case 0xf8a:
  28.205 +                temp = pas16->pcm_ctrl;
  28.206 +                break;
  28.207 +                                
  28.208 +                case 0x1388: case 0x1389: case 0x138a: case 0x138b:
  28.209 +                temp = pas16_pit_in(port, pas16);
  28.210 +                break;
  28.211 +
  28.212 +                case 0x2789: /*Board revision*/
  28.213 +                temp = 0;
  28.214 +                break;
  28.215 +                
  28.216 +                case 0x7f89:
  28.217 +                temp = pas16->enhancedscsi & ~1;
  28.218 +                break;
  28.219 +                
  28.220 +                case 0x8388:
  28.221 +                temp = pas16->sys_conf_1;
  28.222 +                break;
  28.223 +                case 0x8389:
  28.224 +                temp = pas16->sys_conf_2;
  28.225 +                break;
  28.226 +                case 0x838b:
  28.227 +                temp = pas16->sys_conf_3;
  28.228 +                break;
  28.229 +                case 0x838c:
  28.230 +                temp = pas16->sys_conf_4;
  28.231 +                break;
  28.232 +                
  28.233 +                case 0xef8b:
  28.234 +                temp = 0x0c;
  28.235 +                break;
  28.236 +
  28.237 +                case 0xf388:
  28.238 +                temp = pas16->io_conf_1;
  28.239 +                break;
  28.240 +                case 0xf389:
  28.241 +                temp = pas16->io_conf_2;
  28.242 +                break;
  28.243 +                case 0xf38b:
  28.244 +                temp = pas16->io_conf_3;
  28.245 +                break;
  28.246 +                case 0xf38c:
  28.247 +                temp = pas16->io_conf_4;
  28.248 +                break;
  28.249 +
  28.250 +                case 0xf788:
  28.251 +                temp = pas16->compat;
  28.252 +                break;
  28.253 +                case 0xf789:
  28.254 +                temp = pas16->compat_base;
  28.255 +                break;
  28.256 +                
  28.257 +                case 0xfb8a:
  28.258 +                temp = pas16->sb_irqdma;
  28.259 +                break;
  28.260 +
  28.261 +                case 0xff88: /*Board model*/
  28.262 +                temp = 4; /*PAS16*/
  28.263 +                break;
  28.264 +                case 0xff8b: /*Master mode read*/
  28.265 +                temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/
  28.266 +                break;
  28.267 +        }
  28.268 +/*        if (port != 0x388 && port != 0x389 && port != 0xb8b) */pclog("pas16_in : port %04X return %02X  %04X:%04X\n", port, temp, CS,pc);
  28.269 +/*        if (CS == 0x1FF4 && pc == 0x0585)
  28.270 +        {
  28.271 +                if (output)
  28.272 +                        fatal("here");
  28.273 +                output = 3;
  28.274 +        }*/
  28.275 +        return temp;
  28.276 +}
  28.277 +
  28.278 +static void pas16_out(uint16_t port, uint8_t val, void *p)
  28.279 +{
  28.280 +        pas16_t *pas16 = (pas16_t *)p;
  28.281 +/*        if (port != 0x388 && port != 0x389) */pclog("pas16_out : port %04X val %02X  %04X:%04X\n", port, val, CS,pc);
  28.282 +/*        if (CS == 0x369 && pc == 0x2AC5)
  28.283 +                fatal("here\n");*/
  28.284 +        switch ((port - pas16->base) + 0x388)
  28.285 +        {
  28.286 +                case 0x388: case 0x389: case 0x38a: case 0x38b:
  28.287 +                opl3_write((port - pas16->base) + 0x388, val, &pas16->opl);
  28.288 +                break;
  28.289 +                
  28.290 +                case 0xb88:
  28.291 +                pas16->audio_mixer = val;
  28.292 +                break;
  28.293 +
  28.294 +                case 0xb89:
  28.295 +                pas16->irq_stat &= ~val;
  28.296 +//                pas16_update_irqs();
  28.297 +                break;
  28.298 +
  28.299 +                case 0xb8a:
  28.300 +                pas16->audiofilt = val;
  28.301 +                break;
  28.302 +
  28.303 +                case 0xb8b:
  28.304 +                pas16->irq_ena = val;
  28.305 +//                pas16_update_irqs();
  28.306 +                break;
  28.307 +
  28.308 +                case 0xf88:
  28.309 +                pas16->pcm_dat = (pas16->pcm_dat & 0xff00) | val;
  28.310 +                break;
  28.311 +                case 0xf89:
  28.312 +                pas16->pcm_dat = (pas16->pcm_dat & 0x00ff) | (val << 8);
  28.313 +                break;               
  28.314 +                case 0xf8a:
  28.315 +                if ((val & PAS16_PCM_ENA) && !(pas16->pcm_ctrl & PAS16_PCM_ENA)) /*Guess*/
  28.316 +                        pas16->stereo_lr = 0;
  28.317 +                pas16->pcm_ctrl = val;
  28.318 +                break;
  28.319 +                
  28.320 +                case 0x1388: case 0x1389: case 0x138a: case 0x138b:
  28.321 +                pas16_pit_out(port, val, pas16);
  28.322 +                break;
  28.323 +
  28.324 +                case 0x7f89:
  28.325 +                pas16->enhancedscsi = val;
  28.326 +                break;
  28.327 +
  28.328 +                case 0x8388:
  28.329 +                pas16->sys_conf_1 = val;
  28.330 +                break;
  28.331 +                case 0x8389:
  28.332 +                pas16->sys_conf_2 = val;
  28.333 +                break;
  28.334 +                case 0x838a:
  28.335 +                pas16->sys_conf_3 = val;
  28.336 +                break;
  28.337 +                case 0x838b:
  28.338 +                pas16->sys_conf_4 = val;
  28.339 +                break;
  28.340 +
  28.341 +                case 0xf388:
  28.342 +                pas16->io_conf_1 = val;
  28.343 +                break;
  28.344 +                case 0xf389:
  28.345 +                pas16->io_conf_2 = val;
  28.346 +                pas16->dma = pas16_dmas[val & 0x7];
  28.347 +                pclog("pas16_out : set PAS DMA %i\n", pas16->dma);
  28.348 +                break;
  28.349 +                case 0xf38a:
  28.350 +                pas16->io_conf_3 = val;
  28.351 +                pas16->irq = pas16_irqs[val & 0xf];
  28.352 +                pclog("pas16_out : set PAS IRQ %i\n", pas16->irq);
  28.353 +                break;
  28.354 +                case 0xf38b:
  28.355 +                pas16->io_conf_4 = val;
  28.356 +                break;
  28.357 +
  28.358 +                case 0xf788:
  28.359 +                pas16->compat = val;
  28.360 +                if (pas16->compat & 0x02)
  28.361 +                        sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200);
  28.362 +                else
  28.363 +                        sb_dsp_setaddr(&pas16->dsp, 0);
  28.364 +                break;
  28.365 +                case 0xf789:
  28.366 +                pas16->compat_base = val;
  28.367 +                if (pas16->compat & 0x02)
  28.368 +                        sb_dsp_setaddr(&pas16->dsp, ((pas16->compat_base & 0xf) << 4) | 0x200);
  28.369 +                break;
  28.370 +                
  28.371 +                case 0xfb8a:
  28.372 +                pas16->sb_irqdma = val;
  28.373 +                sb_dsp_setirq(&pas16->dsp, pas16_sb_irqs[(val >> 3) & 7]);
  28.374 +                sb_dsp_setdma8(&pas16->dsp, pas16_sb_dmas[(val >> 6) & 3]);
  28.375 +                pclog("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]);
  28.376 +                break;
  28.377 +                
  28.378 +                default:
  28.379 +                pclog("pas16_out : unknown %04X\n", port);
  28.380 +        }
  28.381 +        if (pc == 0x80048CF3)
  28.382 +        {
  28.383 +                if (output)
  28.384 +                        fatal("here\n");
  28.385 +                output = 3;
  28.386 +        }
  28.387 +/*        if (CS == 0x1FF4 && pc == 0x0431)
  28.388 +                output = 3;*/
  28.389 +}
  28.390 +
  28.391 +static void pas16_pit_out(uint16_t port, uint8_t val, void *p)
  28.392 +{
  28.393 +        pas16_t *pas16 = (pas16_t *)p;
  28.394 +        int t;
  28.395 +        switch (port & 3)
  28.396 +        {
  28.397 +                case 3: /*CTRL*/
  28.398 +                if ((val & 0xC0) == 0xC0)
  28.399 +                {
  28.400 +                        if (!(val & 0x20))
  28.401 +                        {
  28.402 +                                if (val & 2) pas16->pit.rl[0] = pas16->pit.c[0] / (PITCONST * (1 << TIMER_SHIFT));
  28.403 +                                if (val & 4) pas16->pit.rl[1] = pas16->pit.c[1];
  28.404 +                                if (val & 8) pas16->pit.rl[2] = pas16->pit.c[2];
  28.405 +                        }
  28.406 +                        return;
  28.407 +                }
  28.408 +                t = val >> 6;
  28.409 +                pas16->pit.ctrls[t] = pas16->pit.ctrl = val;
  28.410 +                if (t == 3)
  28.411 +                {
  28.412 +                        printf("Bad PIT reg select\n");
  28.413 +                        return;
  28.414 +                }
  28.415 +                if (!(pas16->pit.ctrl & 0x30))
  28.416 +                {
  28.417 +                        pas16->pit.rl[t] = pas16->pit.c[t];
  28.418 +                        if (!t)
  28.419 +                                pas16->pit.rl[t] /= (PITCONST * (1 << TIMER_SHIFT));
  28.420 +                        if (pas16->pit.c[t] < 0) 
  28.421 +                                pas16->pit.rl[t] = 0;
  28.422 +                        pas16->pit.ctrl |= 0x30;
  28.423 +                        pas16->pit.rereadlatch[t] = 0;
  28.424 +                        pas16->pit.rm[t] = 3;
  28.425 +                }
  28.426 +                else
  28.427 +                {
  28.428 +                        pas16->pit.rm[t] = pas16->pit.wm[t] = (pas16->pit.ctrl >> 4) & 3;
  28.429 +                        pas16->pit.m[t] = (val >> 1) & 7;
  28.430 +                        if (pas16->pit.m[t] > 5)
  28.431 +                                pas16->pit.m[t] &= 3;
  28.432 +                        if (!pas16->pit.rm[t])
  28.433 +                        {
  28.434 +                                pas16->pit.rm[t] = 3;
  28.435 +                                pas16->pit.rl[t] = pit.c[t];
  28.436 +                                if (!t)
  28.437 +                                        pas16->pit.rl[t] /= (PITCONST * (1 << TIMER_SHIFT));
  28.438 +                        }
  28.439 +                        pas16->pit.rereadlatch[t] = 1;
  28.440 +                }
  28.441 +                pas16->pit.wp = 0;
  28.442 +                pas16->pit.thit[t] = 0;
  28.443 +                break;
  28.444 +                case 0: case 1: case 2: /*Timers*/
  28.445 +                t = port & 3;
  28.446 +                switch (pas16->pit.wm[t])
  28.447 +                {
  28.448 +                        case 1:
  28.449 +                        pas16->pit.l[t] = val;
  28.450 +                        pas16->pit.thit[t] = 0;
  28.451 +                        pas16->pit.c[t] = pas16->pit.l[t];
  28.452 +                        if (!t)
  28.453 +                                pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT);
  28.454 +                        pas16->pit.enable[t] = 1;
  28.455 +                        break;
  28.456 +                        case 2:
  28.457 +                        pas16->pit.l[t] = val << 8;
  28.458 +                        pas16->pit.thit[t] = 0;
  28.459 +                        pas16->pit.c[t] = pas16->pit.l[t];
  28.460 +                        if (!t)
  28.461 +                                pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT);
  28.462 +                        pas16->pit.enable[t] = 1;
  28.463 +                        break;
  28.464 +                        case 0:
  28.465 +                        pas16->pit.l[t] &= 0xFF;
  28.466 +                        pas16->pit.l[t] |= (val << 8);
  28.467 +                        pas16->pit.c[t] = pas16->pit.l[t];
  28.468 +                        if (!t)
  28.469 +                                pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT);
  28.470 +                        pas16->pit.thit[t] = 0;
  28.471 +                        pas16->pit.wm[t] = 3;
  28.472 +                        pas16->pit.enable[t] = 1;
  28.473 +                        break;
  28.474 +                        case 3:
  28.475 +                        pas16->pit.l[t] &= 0xFF00;
  28.476 +                        pas16->pit.l[t] |= val;
  28.477 +                        pas16->pit.wm[t] = 0;                        
  28.478 +                        break;
  28.479 +                }
  28.480 +                if (!pas16->pit.l[t])
  28.481 +                {
  28.482 +                        pas16->pit.l[t] |= 0x10000;
  28.483 +                        pas16->pit.c[t] = pas16->pit.l[t];
  28.484 +                        if (!t)
  28.485 +                                pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT);
  28.486 +                }
  28.487 +                break;
  28.488 +        }
  28.489 +}
  28.490 +
  28.491 +static uint8_t pas16_pit_in(uint16_t port, void *p)
  28.492 +{
  28.493 +        pas16_t *pas16 = (pas16_t *)p;
  28.494 +        uint8_t temp;
  28.495 +        int t = port & 3;
  28.496 +//        printf("Read PIT %04X ",addr);
  28.497 +        switch (port & 3)
  28.498 +        {
  28.499 +                case 0: case 1: case 2: /*Timers*/
  28.500 +                if (pas16->pit.rereadlatch[t])
  28.501 +                {
  28.502 +                        pas16->pit.rereadlatch[t] = 0;
  28.503 +                        if (!t)
  28.504 +                        {
  28.505 +                                pas16->pit.rl[t] = pas16->pit.c[t] / (PITCONST * (1 << TIMER_SHIFT));
  28.506 +                                if ((pas16->pit.c[t] / (PITCONST * (1 << TIMER_SHIFT))) > 65536) 
  28.507 +                                        pas16->pit.rl[t] = 0xFFFF;
  28.508 +                        }
  28.509 +                        else
  28.510 +                        {
  28.511 +                                pas16->pit.rl[t] = pas16->pit.c[t];
  28.512 +                                if (pas16->pit.c[t] > 65536) 
  28.513 +                                        pas16->pit.rl[t] = 0xFFFF;
  28.514 +                        }
  28.515 +                }
  28.516 +                switch (pas16->pit.rm[t])
  28.517 +                {
  28.518 +                        case 0:
  28.519 +                        temp = pas16->pit.rl[t] >> 8;
  28.520 +                        pas16->pit.rm[t] = 3;
  28.521 +                        pas16->pit.rereadlatch[t] = 1;
  28.522 +                        break;
  28.523 +                        case 1:
  28.524 +                        temp = (pas16->pit.rl[t]) & 0xFF;
  28.525 +                        pas16->pit.rereadlatch[t] = 1;
  28.526 +                        break;
  28.527 +                        case 2:
  28.528 +                        temp = (pas16->pit.rl[t]) >> 8;
  28.529 +                        pas16->pit.rereadlatch[t] = 1;
  28.530 +                        break;
  28.531 +                        case 3:
  28.532 +                        temp = (pas16->pit.rl[t]) & 0xFF;
  28.533 +                        if (pas16->pit.m[t] & 0x80) pas16->pit.m[t] &= 7;
  28.534 +                        else pas16->pit.rm[t] = 0;
  28.535 +                        break;
  28.536 +                }
  28.537 +                break;
  28.538 +                case 3: /*Control*/
  28.539 +                temp = pas16->pit.ctrl;
  28.540 +                break;
  28.541 +        }
  28.542 +//        printf("%02X %i %i %04X:%04X\n",temp,pit.rm[addr&3],pit.wp,cs>>4,pc);
  28.543 +        return temp;
  28.544 +}
  28.545 +
  28.546 +static uint8_t pas16_readdma(pas16_t *pas16)
  28.547 +{
  28.548 +        return dma_channel_read(pas16->dma);
  28.549 +}
  28.550 +
  28.551 +static void pas16_pcm_poll(void *p)
  28.552 +{
  28.553 +        pas16_t *pas16 = (pas16_t *)p;
  28.554 +//        if (pas16->pcm_ctrl & PAS16_PCM_ENA)
  28.555 +//                pclog("pas16_pcm_poll : poll %i %i ", pas16->pit.c[0], pas16->pit.l[0]);
  28.556 +        if (pas16->pit.m[0] & 2)
  28.557 +        {
  28.558 +                if (pas16->pit.l[0]) 
  28.559 +                        pas16->pit.c[0] += (pas16->pit.l[0] * PITCONST * (1 << TIMER_SHIFT));
  28.560 +                else                
  28.561 +                        pas16->pit.c[0] += (0x10000 * PITCONST * (1 << TIMER_SHIFT));
  28.562 +        }
  28.563 +        else
  28.564 +        {
  28.565 +                pas16->pit.c[0] = -1;
  28.566 +                pas16->pit.enable[0] = 0;
  28.567 +        }
  28.568 +//        if (pas16->pcm_ctrl & PAS16_PCM_ENA)
  28.569 +//                pclog(" %i\n", pas16->pit.c[0]);
  28.570 +
  28.571 +        pas16->irq_stat |= PAS16_INT_SAMP;
  28.572 +        if (pas16->irq_ena & PAS16_INT_SAMP)
  28.573 +                picint(1 << pas16->irq);
  28.574 +//        pas16_update_irqs();
  28.575 +        
  28.576 +        /*Update sample rate counter*/
  28.577 +        if (pas16->pit.enable[1])
  28.578 +        {               
  28.579 +                if (pas16->pcm_ctrl & PAS16_PCM_ENA)
  28.580 +                {
  28.581 +                        uint16_t temp;
  28.582 +                        
  28.583 +                        if (pas16->sys_conf_2 & PAS16_SC2_16BIT)
  28.584 +                        {
  28.585 +                                temp = pas16_readdma(pas16) << 8;
  28.586 +                                temp |= pas16_readdma(pas16);
  28.587 +                        }
  28.588 +                        else
  28.589 +                                temp = (pas16_readdma(pas16) ^ 0x80) << 8;
  28.590 +                        
  28.591 +                        if (pas16->sys_conf_2 & PAS16_SC2_MSBINV)
  28.592 +                                temp ^= 0x8000;
  28.593 +                        if (pas16->pcm_ctrl & PAS16_PCM_MONO)
  28.594 +                                pas16->pcm_dat_l = pas16->pcm_dat_r = temp;
  28.595 +                        else
  28.596 +                        {
  28.597 +                                if (pas16->stereo_lr)
  28.598 +                                        pas16->pcm_dat_r = temp;
  28.599 +                                else
  28.600 +                                        pas16->pcm_dat_l = temp;
  28.601 +                                        
  28.602 +                                pas16->stereo_lr = !pas16->stereo_lr;
  28.603 +                        }
  28.604 +//                        pclog("pas16_pcm_poll : %04X %i\n", temp, pas16->stereo_lr);
  28.605 +//                        pclog("pas16_pcm_poll : %i %02X  %i\n", pas16->pit.c[1], temp, pas16->pit.c[0]);
  28.606 +/*                        if (!pas16_pcm)
  28.607 +                                pas16_pcm=fopen("pas16->pcm", "wb");
  28.608 +                        putc(temp, pas16_pcm);*/
  28.609 +                }
  28.610 +                if (pas16->sys_conf_2 & PAS16_SC2_16BIT)
  28.611 +                        pas16->pit.c[1] -= 2;
  28.612 +                else
  28.613 +                        pas16->pit.c[1]--;
  28.614 +                if (pas16->pit.c[1] == 0)
  28.615 +                {
  28.616 +//                        if (pas16->pcm_ctrl & PAS16_PCM_ENA)
  28.617 +//                                pclog("pas16_pcm_poll : buffer over\n");
  28.618 +                        if (pas16->pit.m[1] & 2)
  28.619 +                        {
  28.620 +                                if (pas16->pit.l[1]) 
  28.621 +                                        pas16->pit.c[1] += pas16->pit.l[1];
  28.622 +                                else                
  28.623 +                                        pas16->pit.c[1] += 0x10000;
  28.624 +                        }
  28.625 +                        else
  28.626 +                        {
  28.627 +                                pas16->pit.c[1] = -1;
  28.628 +                                pas16->pit.enable[1] = 0;
  28.629 +                        }
  28.630 +                
  28.631 +                        pas16->irq_stat |= PAS16_INT_PCM;
  28.632 +                        if (pas16->irq_ena & PAS16_INT_PCM)
  28.633 +                        {
  28.634 +                                pclog("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq);
  28.635 +                                picint(1 << pas16->irq);
  28.636 +                        }
  28.637 +                }
  28.638 +        }
  28.639 +}
  28.640 +
  28.641 +static void pas16_out_base(uint16_t port, uint8_t val, void *p)
  28.642 +{
  28.643 +        pas16_t *pas16 = (pas16_t *)p;
  28.644 +
  28.645 +        io_removehandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.646 +        io_removehandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.647 +        io_removehandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.648 +        io_removehandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.649 +        io_removehandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.650 +        io_removehandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.651 +        io_removehandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.652 +        io_removehandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.653 +        io_removehandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.654 +        io_removehandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.655 +        io_removehandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.656 +        io_removehandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.657 +        io_removehandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.658 +        io_removehandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.659 +        io_removehandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.660 +        io_removehandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.661 +        io_removehandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.662 +        io_removehandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.663 +        
  28.664 +        pas16->base = val << 2;
  28.665 +        pclog("pas16_write_base : PAS16 base now at %04X\n", pas16->base);
  28.666 +
  28.667 +        io_sethandler((pas16->base - 0x388) + 0x0388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.668 +        io_sethandler((pas16->base - 0x388) + 0x0788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.669 +        io_sethandler((pas16->base - 0x388) + 0x0b88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.670 +        io_sethandler((pas16->base - 0x388) + 0x0f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.671 +        io_sethandler((pas16->base - 0x388) + 0x1388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.672 +        io_sethandler((pas16->base - 0x388) + 0x1788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.673 +        io_sethandler((pas16->base - 0x388) + 0x2788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.674 +        io_sethandler((pas16->base - 0x388) + 0x7f88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.675 +        io_sethandler((pas16->base - 0x388) + 0x8388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.676 +        io_sethandler((pas16->base - 0x388) + 0xbf88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.677 +        io_sethandler((pas16->base - 0x388) + 0xe388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.678 +        io_sethandler((pas16->base - 0x388) + 0xe788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.679 +        io_sethandler((pas16->base - 0x388) + 0xeb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.680 +        io_sethandler((pas16->base - 0x388) + 0xef88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.681 +        io_sethandler((pas16->base - 0x388) + 0xf388, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.682 +        io_sethandler((pas16->base - 0x388) + 0xf788, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.683 +        io_sethandler((pas16->base - 0x388) + 0xfb88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.684 +        io_sethandler((pas16->base - 0x388) + 0xff88, 0x0004, pas16_in, NULL, NULL, pas16_out, NULL, NULL,  pas16);
  28.685 +}
  28.686 +
  28.687 +
  28.688 +void pas16_poll(void *p)
  28.689 +{
  28.690 +        pas16_t *pas16 = (pas16_t *)p;
  28.691 +
  28.692 +        if (pas16->pos >= SOUNDBUFLEN)
  28.693 +                return;
  28.694 +
  28.695 +        opl3_poll(&pas16->opl, &pas16->opl_buffer[pas16->pos * 2], &pas16->opl_buffer[(pas16->pos * 2) + 1]);
  28.696 +        sb_dsp_poll(&pas16->dsp, &pas16->dsp_buffer[pas16->pos * 2], &pas16->dsp_buffer[(pas16->pos * 2) + 1]);
  28.697 +        
  28.698 +        if (!(pas16->audiofilt & PAS16_FILT_MUTE))
  28.699 +        {
  28.700 +                pas16->pcm_buffer[0][pas16->pos] = 0;
  28.701 +                pas16->pcm_buffer[1][pas16->pos] = 0;
  28.702 +        }
  28.703 +        else
  28.704 +        {
  28.705 +                pas16->pcm_buffer[0][pas16->pos] = (int16_t)pas16->pcm_dat_l;
  28.706 +                pas16->pcm_buffer[1][pas16->pos] = (int16_t)pas16->pcm_dat_r;
  28.707 +        }
  28.708 +        pas16->pos++;
  28.709 +}
  28.710 +
  28.711 +void pas16_get_buffer(int16_t *buffer, int len, void *p)
  28.712 +{
  28.713 +        pas16_t *pas16 = (pas16_t *)p;
  28.714 +        int c;
  28.715 +
  28.716 +        for (c = 0; c < len * 2; c++)
  28.717 +        {
  28.718 +                buffer[c] += pas16->opl_buffer[c];
  28.719 +                buffer[c] += (int16_t)(sb_iir(c & 1, (float)pas16->dsp_buffer[c]) / 1.3) / 2;
  28.720 +                buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2);
  28.721 +        }
  28.722 +
  28.723 +        pas16->pos = 0;
  28.724 +}
  28.725 +
  28.726 +void *pas16_init()
  28.727 +{
  28.728 +        pas16_t *pas16 = malloc(sizeof(pas16_t));
  28.729 +        memset(pas16, 0, sizeof(pas16_t));
  28.730 +
  28.731 +        opl3_init(&pas16->opl);
  28.732 +        sb_dsp_init(&pas16->dsp, SB2);
  28.733 +
  28.734 +        io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL,  pas16);
  28.735 +        
  28.736 +        timer_add(pas16_pcm_poll, &pas16->pit.c[0], &pas16->pit.enable[0],  pas16);
  28.737 +        
  28.738 +        sound_add_handler(pas16_poll, pas16_get_buffer, pas16);
  28.739 +        
  28.740 +        return pas16;
  28.741 +}
  28.742 +
  28.743 +void pas16_close(void *p)
  28.744 +{
  28.745 +        pas16_t *pas16 = (pas16_t *)p;
  28.746 +        
  28.747 +        free(pas16);
  28.748 +}
  28.749 +
  28.750 +device_t pas16_device =
  28.751 +{
  28.752 +        "Pro Audio Spectrum 16",
  28.753 +        pas16_init,
  28.754 +        pas16_close,
  28.755 +        NULL
  28.756 +};
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/src/sound_pas16.h	Mon May 27 19:56:33 2013 +0100
    29.3 @@ -0,0 +1,1 @@
    29.4 +extern device_t pas16_device;
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/src/sound_sb.c	Mon May 27 19:56:33 2013 +0100
    30.3 @@ -0,0 +1,412 @@
    30.4 +#include <stdlib.h>
    30.5 +#include "ibm.h"
    30.6 +#include "device.h"
    30.7 +#include "sound_sb.h"
    30.8 +#include "sound_sb_dsp.h"
    30.9 +#include "sound_opl.h"
   30.10 +
   30.11 +#include "filters.h"
   30.12 +
   30.13 +typedef struct sb_mixer_t
   30.14 +{
   30.15 +        int master_l, master_r;
   30.16 +        int voice_l,  voice_r;
   30.17 +        int fm_l,     fm_r;
   30.18 +        int bass_l,   bass_r;
   30.19 +        int treble_l, treble_r;
   30.20 +        int filter;
   30.21 +
   30.22 +        int index;
   30.23 +        uint8_t regs[256];
   30.24 +} sb_mixer_t;
   30.25 +
   30.26 +typedef struct sb_t
   30.27 +{
   30.28 +        opl_t      opl;
   30.29 +        sb_dsp_t   dsp;
   30.30 +        sb_mixer_t mixer;
   30.31 +
   30.32 +        int16_t opl_buffer[SOUNDBUFLEN * 2];
   30.33 +        int16_t dsp_buffer[SOUNDBUFLEN * 2];
   30.34 +
   30.35 +        int pos;
   30.36 +} sb_t;
   30.37 +
   30.38 +static int sb_att[]=
   30.39 +{
   30.40 +        310,368,437,520,618,735,873,1038,1234,1467,1743,2072,2463,2927,3479,
   30.41 +        4134,4914,5840,6941,8250,9805,11653,13850,16461,19564,23252,27635,32845,
   30.42 +        39036,46395,55140,65535
   30.43 +};
   30.44 +
   30.45 +
   30.46 +
   30.47 +static void sb_opl2_poll(void *p)
   30.48 +{
   30.49 +        sb_t *sb = (sb_t *)p;
   30.50 +        
   30.51 +        if (sb->pos >= SOUNDBUFLEN) return;
   30.52 +        
   30.53 +        opl2_poll(&sb->opl, &sb->opl_buffer[sb->pos * 2], &sb->opl_buffer[(sb->pos * 2) + 1]);
   30.54 +        sb_dsp_poll(&sb->dsp, &sb->dsp_buffer[sb->pos * 2], &sb->dsp_buffer[(sb->pos * 2) + 1]);
   30.55 +        sb->pos++;
   30.56 +}
   30.57 +
   30.58 +static void sb_opl3_poll(void *p)
   30.59 +{
   30.60 +        sb_t *sb = (sb_t *)p;
   30.61 +        
   30.62 +        if (sb->pos >= SOUNDBUFLEN) return;
   30.63 +        
   30.64 +        opl3_poll(&sb->opl, &sb->opl_buffer[sb->pos * 2], &sb->opl_buffer[(sb->pos * 2) + 1]);
   30.65 +        sb_dsp_poll(&sb->dsp, &sb->dsp_buffer[sb->pos * 2], &sb->dsp_buffer[(sb->pos * 2) + 1]);
   30.66 +        sb->pos++;
   30.67 +}
   30.68 +
   30.69 +static void sb_get_buffer(int16_t *buffer, int len, void *p)
   30.70 +{
   30.71 +        sb_t *sb = (sb_t *)p;
   30.72 +        sb_mixer_t *mixer = &sb->mixer;
   30.73 +                
   30.74 +        int c;
   30.75 +
   30.76 +        for (c = 0; c < len * 2; c += 2)
   30.77 +        {
   30.78 +                int16_t out_l, out_r;
   30.79 +                
   30.80 +                out_l = ((sb->opl_buffer[c]     * mixer->fm_l) >> 16);
   30.81 +                out_r = ((sb->opl_buffer[c + 1] * mixer->fm_r) >> 16);
   30.82 +                if (sb->mixer.filter)
   30.83 +                {
   30.84 +                        out_l += (int)(((sb_iir(0, (float)sb->dsp_buffer[c])     / 1.3) * mixer->voice_l) / 3) >> 16;
   30.85 +                        out_r += (int)(((sb_iir(1, (float)sb->dsp_buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 16;
   30.86 +                }
   30.87 +                else
   30.88 +                {
   30.89 +                        out_l += ((sb->dsp_buffer[c]     * mixer->voice_l) / 3) >> 16;
   30.90 +                        out_r += ((sb->dsp_buffer[c + 1] * mixer->voice_r) / 3) >> 16;
   30.91 +                }
   30.92 +                
   30.93 +                out_l = (out_l * mixer->master_l) >> 16;
   30.94 +                out_r = (out_r * mixer->master_r) >> 16;
   30.95 +
   30.96 +                if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8)
   30.97 +                {
   30.98 +                        if (mixer->bass_l>8)   out_l = (out_l + (((int16_t)     low_iir(0, (float)out_l) * (mixer->bass_l   - 8)) >> 1)) * ((15 - mixer->bass_l)   + 16) >> 5;
   30.99 +                        if (mixer->bass_r>8)   out_r = (out_r + (((int16_t)     low_iir(1, (float)out_r) * (mixer->bass_r   - 8)) >> 1)) * ((15 - mixer->bass_r)   + 16) >> 5;
  30.100 +                        if (mixer->treble_l>8) out_l = (out_l + (((int16_t)    high_iir(0, (float)out_l) * (mixer->treble_l - 8)) >> 1)) * ((15 - mixer->treble_l) + 16) >> 5;
  30.101 +                        if (mixer->treble_r>8) out_r = (out_r + (((int16_t)    high_iir(1, (float)out_r) * (mixer->treble_r - 8)) >> 1)) * ((15 - mixer->treble_r) + 16) >> 5;
  30.102 +                        if (mixer->bass_l<8)   out_l = (out_l + (((int16_t) low_cut_iir(0, (float)out_l) * (8 - mixer->bass_l))   >> 1)) * (mixer->bass_l   + 16)        >> 5;
  30.103 +                        if (mixer->bass_r<8)   out_r = (out_r + (((int16_t) low_cut_iir(1, (float)out_r) * (8 - mixer->bass_r))   >> 1)) * (mixer->bass_r   + 16)        >> 5;
  30.104 +                        if (mixer->treble_l<8) out_l = (out_l + (((int16_t)high_cut_iir(0, (float)out_l) * (8 - mixer->treble_l)) >> 1)) * (mixer->treble_l + 16)        >> 5;
  30.105 +                        if (mixer->treble_r<8) out_r = (out_r + (((int16_t)high_cut_iir(1, (float)out_r) * (8 - mixer->treble_r)) >> 1)) * (mixer->treble_r + 16)        >> 5;
  30.106 +                }
  30.107 +                        
  30.108 +                buffer[c]     += out_l;
  30.109 +                buffer[c + 1] += out_r;
  30.110 +        }
  30.111 +
  30.112 +        sb->pos = 0;
  30.113 +}
  30.114 +
  30.115 +
  30.116 +void sb_pro_mixer_write(uint16_t addr, uint8_t val, void *p)
  30.117 +{
  30.118 +        sb_t *sb = (sb_t *)p;
  30.119 +        sb_mixer_t *mixer = &sb->mixer;
  30.120 +        
  30.121 +        if (!(addr & 1))
  30.122 +                mixer->index = val & 0xff;
  30.123 +        else
  30.124 +        {
  30.125 +                mixer->regs[mixer->index] = val;
  30.126 +  
  30.127 +                mixer->master_l = sb_att[(mixer->regs[0x22] >> 4)  | 0x11];
  30.128 +                mixer->master_r = sb_att[(mixer->regs[0x22] & 0xf) | 0x11];
  30.129 +                mixer->voice_l  = sb_att[(mixer->regs[0x04] >> 4)  | 0x11];
  30.130 +                mixer->voice_r  = sb_att[(mixer->regs[0x04] & 0xf) | 0x11];
  30.131 +                mixer->fm_l     = sb_att[(mixer->regs[0x26] >> 4)  | 0x11];
  30.132 +                mixer->fm_r     = sb_att[(mixer->regs[0x26] & 0xf) | 0x11];
  30.133 +                mixer->filter   = !(mixer->regs[0xe] & 0x20);
  30.134 +                mixer->bass_l   = mixer->bass_r   = 8;
  30.135 +                mixer->treble_l = mixer->treble_r = 8;
  30.136 +                pclog("%02X %02X %02X\n", mixer->regs[0x04], mixer->regs[0x22], mixer->regs[0x26]);
  30.137 +                pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r);
  30.138 +                if (mixer->index == 0xe)
  30.139 +                        sb_dsp_set_stereo(&sb->dsp, val & 2);
  30.140 +        }
  30.141 +}
  30.142 +
  30.143 +uint8_t sb_pro_mixer_read(uint16_t addr, void *p)
  30.144 +{
  30.145 +        sb_t *sb = (sb_t *)p;
  30.146 +        sb_mixer_t *mixer = &sb->mixer;
  30.147 +
  30.148 +        if (!(addr & 1))
  30.149 +                return mixer->index;
  30.150 +
  30.151 +        return mixer->regs[mixer->index];                
  30.152 +}
  30.153 +
  30.154 +void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p)
  30.155 +{
  30.156 +        sb_t *sb = (sb_t *)p;
  30.157 +        sb_mixer_t *mixer = &sb->mixer;
  30.158 +        
  30.159 +        if (!(addr & 1))
  30.160 +                mixer->index = val;
  30.161 +        else
  30.162 +        {
  30.163 +                mixer->regs[mixer->index] = val;
  30.164 +                switch (mixer->index)
  30.165 +                {
  30.166 +                        case 0x22:
  30.167 +                        mixer->regs[0x30] = ((mixer->regs[0x22] >> 4)  | 0x11) << 3;
  30.168 +                        mixer->regs[0x31] = ((mixer->regs[0x22] & 0xf) | 0x11) << 3;
  30.169 +                        break;
  30.170 +                        case 0x04:
  30.171 +                        mixer->regs[0x32] = ((mixer->regs[0x04] >> 4)  | 0x11) << 3;
  30.172 +                        mixer->regs[0x33] = ((mixer->regs[0x04] & 0xf) | 0x11) << 3;
  30.173 +                        break;
  30.174 +                        case 0x26:
  30.175 +                        mixer->regs[0x34] = ((mixer->regs[0x26] >> 4)  | 0x11) << 3;
  30.176 +                        mixer->regs[0x35] = ((mixer->regs[0x26] & 0xf) | 0x11) << 3;
  30.177 +                        break;
  30.178 +                        case 0x80:
  30.179 +                        if (val & 1) sb->dsp.sb_irqnum = 2;
  30.180 +                        if (val & 2) sb->dsp.sb_irqnum = 5;
  30.181 +                        if (val & 4) sb->dsp.sb_irqnum = 7;
  30.182 +                        if (val & 8) sb->dsp.sb_irqnum = 10;
  30.183 +                        break;
  30.184 +                }
  30.185 +                mixer->master_l = sb_att[mixer->regs[0x30] >> 3];
  30.186 +                mixer->master_r = sb_att[mixer->regs[0x31] >> 3];
  30.187 +                mixer->voice_l  = sb_att[mixer->regs[0x32] >> 3];
  30.188 +                mixer->voice_r  = sb_att[mixer->regs[0x33] >> 3];
  30.189 +                mixer->fm_l     = sb_att[mixer->regs[0x34] >> 3];
  30.190 +                mixer->fm_r     = sb_att[mixer->regs[0x35] >> 3];
  30.191 +                mixer->bass_l   = mixer->regs[0x46] >> 4;
  30.192 +                mixer->bass_r   = mixer->regs[0x47] >> 4;
  30.193 +                mixer->treble_l = mixer->regs[0x44] >> 4;
  30.194 +                mixer->treble_r = mixer->regs[0x45] >> 4;
  30.195 +                mixer->filter = 0;
  30.196 +                pclog("%02X %02X %02X %02X %02X %02X\n", mixer->regs[0x30], mixer->regs[0x31], mixer->regs[0x32], mixer->regs[0x33], mixer->regs[0x34], mixer->regs[0x35]);
  30.197 +                pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r);
  30.198 +        }
  30.199 +}
  30.200 +
  30.201 +uint8_t sb_16_mixer_read(uint16_t addr, void *p)
  30.202 +{
  30.203 +        sb_t *sb = (sb_t *)p;
  30.204 +        sb_mixer_t *mixer = &sb->mixer;
  30.205 +
  30.206 +        if (!(addr & 1))
  30.207 +                return mixer->index;
  30.208 +
  30.209 +        switch (mixer->index)
  30.210 +        {
  30.211 +                case 0x80:
  30.212 +                switch (sb->dsp.sb_irqnum)
  30.213 +                {
  30.214 +                        case 2: return 1; /*IRQ 7*/
  30.215 +                        case 5: return 2; /*IRQ 7*/
  30.216 +                        case 7: return 4; /*IRQ 7*/
  30.217 +                        case 10: return 8; /*IRQ 7*/
  30.218 +                }
  30.219 +                break;
  30.220 +                case 0x81:
  30.221 +                return 0x22; /*DMA 1 and 5*/
  30.222 +                case 0x82:
  30.223 +                return ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0);
  30.224 +        }
  30.225 +        return mixer->regs[mixer->index];                
  30.226 +}
  30.227 +
  30.228 +void sb_mixer_init(sb_mixer_t *mixer)
  30.229 +{
  30.230 +        mixer->master_l = mixer->master_r = 65535;
  30.231 +        mixer->voice_l  = mixer->voice_r  = 65535;
  30.232 +        mixer->fm_l     = mixer->fm_r     = 65535;
  30.233 +        mixer->bass_l   = mixer->bass_r   = 8;
  30.234 +        mixer->treble_l = mixer->treble_r = 8;
  30.235 +        mixer->filter = 1;
  30.236 +}
  30.237 +        
  30.238 +void *sb_1_init()
  30.239 +{
  30.240 +        sb_t *sb = malloc(sizeof(sb_t));
  30.241 +        memset(sb, 0, sizeof(sb_t));
  30.242 +        
  30.243 +        opl2_init(&sb->opl);
  30.244 +        sb_dsp_init(&sb->dsp, SB1);
  30.245 +        sb_dsp_setaddr(&sb->dsp, 0x0220);
  30.246 +        sb_mixer_init(&sb->mixer);
  30.247 +        io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
  30.248 +        io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
  30.249 +        sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
  30.250 +        return sb;
  30.251 +}
  30.252 +void *sb_15_init()
  30.253 +{
  30.254 +        sb_t *sb = malloc(sizeof(sb_t));
  30.255 +        memset(sb, 0, sizeof(sb_t));
  30.256 +
  30.257 +        opl2_init(&sb->opl);
  30.258 +        sb_dsp_init(&sb->dsp, SB15);
  30.259 +        sb_dsp_setaddr(&sb->dsp, 0x0220);
  30.260 +        sb_mixer_init(&sb->mixer);
  30.261 +        io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
  30.262 +        io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
  30.263 +        sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
  30.264 +        return sb;
  30.265 +}
  30.266 +void *sb_2_init()
  30.267 +{
  30.268 +        sb_t *sb = malloc(sizeof(sb_t));
  30.269 +        memset(sb, 0, sizeof(sb_t));
  30.270 +
  30.271 +        opl2_init(&sb->opl);
  30.272 +        sb_dsp_init(&sb->dsp, SB2);
  30.273 +        sb_dsp_setaddr(&sb->dsp, 0x0220);
  30.274 +        sb_mixer_init(&sb->mixer);
  30.275 +        io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
  30.276 +        io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
  30.277 +        sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
  30.278 +        return sb;
  30.279 +}
  30.280 +
  30.281 +void *sb_pro_v1_init()
  30.282 +{
  30.283 +        sb_t *sb = malloc(sizeof(sb_t));
  30.284 +        memset(sb, 0, sizeof(sb_t));
  30.285 +
  30.286 +        opl2_init(&sb->opl);
  30.287 +        sb_dsp_init(&sb->dsp, SBPRO);
  30.288 +        sb_dsp_setaddr(&sb->dsp, 0x0220);
  30.289 +        sb_mixer_init(&sb->mixer);
  30.290 +        io_sethandler(0x0220, 0x0002, opl2_l_read, NULL, NULL, opl2_l_write, NULL, NULL, &sb->opl);
  30.291 +        io_sethandler(0x0222, 0x0002, opl2_r_read, NULL, NULL, opl2_r_write, NULL, NULL, &sb->opl);
  30.292 +        io_sethandler(0x0228, 0x0002, opl2_read,   NULL, NULL, opl2_write,   NULL, NULL, &sb->opl);
  30.293 +        io_sethandler(0x0388, 0x0002, opl2_read,   NULL, NULL, opl2_write,   NULL, NULL, &sb->opl);
  30.294 +        io_sethandler(0x0224, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb);
  30.295 +        sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
  30.296 +
  30.297 +        sb->mixer.regs[0x22] = 0xff;
  30.298 +        sb->mixer.regs[0x04] = 0xff;
  30.299 +        sb->mixer.regs[0x26] = 0xff;
  30.300 +        sb->mixer.regs[0xe]  = 0;
  30.301 +
  30.302 +        return sb;
  30.303 +}
  30.304 +
  30.305 +void *sb_pro_v2_init()
  30.306 +{
  30.307 +        sb_t *sb = malloc(sizeof(sb_t));
  30.308 +        memset(sb, 0, sizeof(sb_t));
  30.309 +
  30.310 +        opl3_init(&sb->opl);
  30.311 +        sb_dsp_init(&sb->dsp, SBPRO2);
  30.312 +        sb_dsp_setaddr(&sb->dsp, 0x0220);
  30.313 +        sb_mixer_init(&sb->mixer);
  30.314 +        io_sethandler(0x0220, 0x0004, opl3_read,   NULL, NULL, opl3_write,   NULL, NULL, &sb->opl);
  30.315 +        io_sethandler(0x0228, 0x0002, opl3_read,   NULL, NULL, opl3_write,   NULL, NULL, &sb->opl);
  30.316 +        io_sethandler(0x0388, 0x0002, opl3_read,   NULL, NULL, opl3_write,   NULL, NULL, &sb->opl);
  30.317 +        io_sethandler(0x0224, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb);
  30.318 +        sound_add_handler(sb_opl3_poll, sb_get_buffer, sb);
  30.319 +
  30.320 +        sb->mixer.regs[0x22] = 0xff;
  30.321 +        sb->mixer.regs[0x04] = 0xff;
  30.322 +        sb->mixer.regs[0x26] = 0xff;
  30.323 +        sb->mixer.regs[0xe]  = 0;
  30.324 +
  30.325 +        return sb;
  30.326 +}
  30.327 +
  30.328 +void *sb_16_init()
  30.329 +{
  30.330 +        sb_t *sb = malloc(sizeof(sb_t));
  30.331 +        memset(sb, 0, sizeof(sb_t));
  30.332 +
  30.333 +        opl3_init(&sb->opl);
  30.334 +        sb_dsp_init(&sb->dsp, SB16);
  30.335 +        sb_dsp_setaddr(&sb->dsp, 0x0220);
  30.336 +        sb_mixer_init(&sb->mixer);
  30.337 +        io_sethandler(0x0220, 0x0004, opl3_read,   NULL, NULL, opl3_write,   NULL, NULL, &sb->opl);
  30.338 +        io_sethandler(0x0228, 0x0002, opl3_read,   NULL, NULL, opl3_write,   NULL, NULL, &sb->opl);
  30.339 +        io_sethandler(0x0388, 0x0002, opl3_read,   NULL, NULL, opl3_write,   NULL, NULL, &sb->opl);
  30.340 +        io_sethandler(0x0224, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb);
  30.341 +        sound_add_handler(sb_opl3_poll, sb_get_buffer, sb);
  30.342 +
  30.343 +        sb->mixer.regs[0x30] = 31 << 3;
  30.344 +        sb->mixer.regs[0x31] = 31 << 3;
  30.345 +        sb->mixer.regs[0x32] = 31 << 3;
  30.346 +        sb->mixer.regs[0x33] = 31 << 3;
  30.347 +        sb->mixer.regs[0x34] = 31 << 3;
  30.348 +        sb->mixer.regs[0x35] = 31 << 3;
  30.349 +        sb->mixer.regs[0x44] =  8 << 4;
  30.350 +        sb->mixer.regs[0x45] =  8 << 4;
  30.351 +        sb->mixer.regs[0x46] =  8 << 4;
  30.352 +        sb->mixer.regs[0x47] =  8 << 4;
  30.353 +        sb->mixer.regs[0x22] = (sb->mixer.regs[0x30] & 0xf0) | (sb->mixer.regs[0x31] >> 4);
  30.354 +        sb->mixer.regs[0x04] = (sb->mixer.regs[0x32] & 0xf0) | (sb->mixer.regs[0x33] >> 4);
  30.355 +        sb->mixer.regs[0x26] = (sb->mixer.regs[0x34] & 0xf0) | (sb->mixer.regs[0x35] >> 4);
  30.356 +
  30.357 +        return sb;
  30.358 +}
  30.359 +
  30.360 +void sb_close(void *p)
  30.361 +{
  30.362 +        sb_t *sb = (sb_t *)p;
  30.363 +        
  30.364 +        free(sb);
  30.365 +}
  30.366 +
  30.367 +void sb_speed_changed(void *p)
  30.368 +{
  30.369 +        sb_t *sb = (sb_t *)p;
  30.370 +        
  30.371 +        sb_dsp_speed_changed(&sb->dsp);
  30.372 +}
  30.373 +
  30.374 +device_t sb_1_device =
  30.375 +{
  30.376 +        "Sound Blaster v1.0",
  30.377 +        sb_1_init,
  30.378 +        sb_close,
  30.379 +        sb_speed_changed
  30.380 +};
  30.381 +device_t sb_15_device =
  30.382 +{
  30.383 +        "Sound Blaster v1.5",
  30.384 +        sb_15_init,
  30.385 +        sb_close,
  30.386 +        sb_speed_changed
  30.387 +};
  30.388 +device_t sb_2_device =
  30.389 +{
  30.390 +        "Sound Blaster v2.0",
  30.391 +        sb_2_init,
  30.392 +        sb_close,
  30.393 +        sb_speed_changed
  30.394 +};
  30.395 +device_t sb_pro_v1_device =
  30.396 +{
  30.397 +        "Sound Blaster Pro v1",
  30.398 +        sb_pro_v1_init,
  30.399 +        sb_close,
  30.400 +        sb_speed_changed
  30.401 +};
  30.402 +device_t sb_pro_v2_device =
  30.403 +{
  30.404 +        "Sound Blaster Pro v2",
  30.405 +        sb_pro_v2_init,
  30.406 +        sb_close,
  30.407 +        sb_speed_changed
  30.408 +};
  30.409 +device_t sb_16_device =
  30.410 +{
  30.411 +        "Sound Blaster 16",
  30.412 +        sb_16_init,
  30.413 +        sb_close,
  30.414 +        sb_speed_changed
  30.415 +};
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/src/sound_sb.h	Mon May 27 19:56:33 2013 +0100
    31.3 @@ -0,0 +1,6 @@
    31.4 +extern device_t sb_1_device;
    31.5 +extern device_t sb_15_device;
    31.6 +extern device_t sb_2_device;
    31.7 +extern device_t sb_pro_v1_device;
    31.8 +extern device_t sb_pro_v2_device;
    31.9 +extern device_t sb_16_device;
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/src/sound_sb_dsp.c	Mon May 27 19:56:33 2013 +0100
    32.3 @@ -0,0 +1,908 @@
    32.4 +/*Jazz sample rates :
    32.5 +  386-33 - 12kHz
    32.6 +  486-33 - 20kHz
    32.7 +  486-50 - 32kHz
    32.8 +  Pentium - 45kHz*/
    32.9 +
   32.10 +#include <stdint.h>
   32.11 +#include <stdio.h>
   32.12 +#include "ibm.h"
   32.13 +
   32.14 +
   32.15 +#include "dma.h"
   32.16 +#include "io.h"
   32.17 +#include "pic.h"
   32.18 +#include "sound.h"
   32.19 +#include "sound_sb_dsp.h"
   32.20 +#include "timer.h"
   32.21 +
   32.22 +void pollsb(void *p);
   32.23 +void sb_poll_i(void *p);
   32.24 +
   32.25 +
   32.26 +
   32.27 +static int sbe2dat[4][9] = {
   32.28 +  {  0x01, -0x02, -0x04,  0x08, -0x10,  0x20,  0x40, -0x80, -106 },
   32.29 +  { -0x01,  0x02, -0x04,  0x08,  0x10, -0x20,  0x40, -0x80,  165 },
   32.30 +  { -0x01,  0x02,  0x04, -0x08,  0x10, -0x20, -0x40,  0x80, -151 },
   32.31 +  {  0x01, -0x02,  0x04, -0x08, -0x10,  0x20, -0x40,  0x80,   90 }
   32.32 +};
   32.33 +
   32.34 +static int sb_commands[256]=
   32.35 +{
   32.36 +        -1,-1,-1,-1, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1,
   32.37 +         1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0,
   32.38 +         0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,
   32.39 +        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
   32.40 +         1, 2, 2,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,
   32.41 +        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
   32.42 +        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
   32.43 +        -1,-1,-1,-1, 2, 2, 2, 2,-1,-1,-1,-1,-1, 0,-1, 0,
   32.44 +         2, 2,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1,
   32.45 +         0,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1,
   32.46 +        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
   32.47 +         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   32.48 +         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   32.49 +         0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1,
   32.50 +         1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1,
   32.51 +        -1,-1, 0,-1,-1,-1,-1,-1,-1, 1, 2,-1,-1,-1,-1, 0
   32.52 +};
   32.53 +
   32.54 +char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
   32.55 +uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405};
   32.56 +
   32.57 +/*These tables were 'borrowed' from DOSBox*/
   32.58 +	int8_t scaleMap4[64] = {
   32.59 +		0,  1,  2,  3,  4,  5,  6,  7,  0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,
   32.60 +		1,  3,  5,  7,  9, 11, 13, 15, -1,  -3,  -5,  -7,  -9, -11, -13, -15,
   32.61 +		2,  6, 10, 14, 18, 22, 26, 30, -2,  -6, -10, -14, -18, -22, -26, -30,
   32.62 +		4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60
   32.63 +	};
   32.64 +	uint8_t adjustMap4[64] = {
   32.65 +		  0, 0, 0, 0, 0, 16, 16, 16,
   32.66 +		  0, 0, 0, 0, 0, 16, 16, 16,
   32.67 +		240, 0, 0, 0, 0, 16, 16, 16,
   32.68 +		240, 0, 0, 0, 0, 16, 16, 16,
   32.69 +		240, 0, 0, 0, 0, 16, 16, 16,
   32.70 +		240, 0, 0, 0, 0, 16, 16, 16,
   32.71 +		240, 0, 0, 0, 0,  0,  0,  0,
   32.72 +		240, 0, 0, 0, 0,  0,  0,  0
   32.73 +	};
   32.74 +
   32.75 +	int8_t scaleMap26[40] = {
   32.76 +		0,  1,  2,  3,  0,  -1,  -2,  -3,
   32.77 +		1,  3,  5,  7, -1,  -3,  -5,  -7,
   32.78 +		2,  6, 10, 14, -2,  -6, -10, -14,
   32.79 +		4, 12, 20, 28, -4, -12, -20, -28,
   32.80 +		5, 15, 25, 35, -5, -15, -25, -35
   32.81 +	};
   32.82 +	uint8_t adjustMap26[40] = {
   32.83 +		  0, 0, 0, 8,   0, 0, 0, 8,
   32.84 +		248, 0, 0, 8, 248, 0, 0, 8,
   32.85 +		248, 0, 0, 8, 248, 0, 0, 8,
   32.86 +		248, 0, 0, 8, 248, 0, 0, 8,
   32.87 +		248, 0, 0, 0, 248, 0, 0, 0
   32.88 +	};
   32.89 +
   32.90 +	int8_t scaleMap2[24] = {
   32.91 +		0,  1,  0,  -1, 1,  3,  -1,  -3,
   32.92 +		2,  6, -2,  -6, 4, 12,  -4, -12,
   32.93 +		8, 24, -8, -24, 6, 48, -16, -48
   32.94 +	};
   32.95 +	uint8_t adjustMap2[24] = {
   32.96 +		  0, 4,   0, 4,
   32.97 +		252, 4, 252, 4, 252, 4, 252, 4,
   32.98 +		252, 4, 252, 4, 252, 4, 252, 4,
   32.99 +		252, 0, 252, 0
  32.100 +	};
  32.101 +
  32.102 +
  32.103 +
  32.104 +void sb_irq(sb_dsp_t *dsp, int irq8)
  32.105 +{
  32.106 +//        pclog("IRQ %i %02X\n",irq8,pic.mask);
  32.107 +        if (irq8) dsp->sb_irq8  = 1;
  32.108 +        else      dsp->sb_irq16 = 1;
  32.109 +        picint(1 << dsp->sb_irqnum);
  32.110 +}
  32.111 +void sb_irqc(sb_dsp_t *dsp, int irq8)
  32.112 +{
  32.113 +        if (irq8) dsp->sb_irq8  = 0;
  32.114 +        else      dsp->sb_irq16 = 0;
  32.115 +        picintc(1 << dsp->sb_irqnum);
  32.116 +}
  32.117 +
  32.118 +void sb_dsp_reset(sb_dsp_t *dsp)
  32.119 +{
  32.120 +        dsp->sbenable = dsp->sb_enable_i = 0;
  32.121 +        dsp->sb_command = 0;
  32.122 +        
  32.123 +        dsp->sb_8_length = 0xffff;
  32.124 +
  32.125 +        sb_irqc(dsp, 0);
  32.126 +        sb_irqc(dsp, 1);
  32.127 +        dsp->sb_16_pause = 0;
  32.128 +        dsp->sb_read_wp = dsp->sb_read_rp = 0;
  32.129 +        dsp->sb_data_stat = -1;
  32.130 +        dsp->sb_speaker = 0;
  32.131 +        dsp->sb_pausetime = -1;
  32.132 +        dsp->sbe2 = 0xAA;
  32.133 +        dsp->sbe2count = 0;
  32.134 +
  32.135 +        dsp->sbreset = 0;
  32.136 +        dsp->sbenable = dsp->sb_enable_i = dsp->sb_count_i = 0;
  32.137 +
  32.138 +        picintc(1 << dsp->sb_irqnum);
  32.139 +}
  32.140 +
  32.141 +void sb_doreset(sb_dsp_t *dsp)
  32.142 +{
  32.143 +        int c;
  32.144 +        
  32.145 +        sb_dsp_reset(dsp);
  32.146 +        
  32.147 +        if (dsp->sb_type==SB16) sb_commands[8] =  1;
  32.148 +        else                    sb_commands[8] = -1;
  32.149 +        
  32.150 +        for (c = 0; c < 256; c++)
  32.151 +            dsp->sb_asp_regs[c] = 0;
  32.152 +        dsp->sb_asp_regs[5] = 0x01;
  32.153 +        dsp->sb_asp_regs[9] = 0xf8;
  32.154 +}
  32.155 +
  32.156 +void sb_dsp_speed_changed(sb_dsp_t *dsp)
  32.157 +{
  32.158 +        if (dsp->sb_timeo < 256)
  32.159 +                dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo);
  32.160 +        else
  32.161 +                dsp->sblatcho = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256)));
  32.162 +
  32.163 +        if (dsp->sb_timei < 256)
  32.164 +                dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei);
  32.165 +        else
  32.166 +                dsp->sblatchi = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256)));
  32.167 +}
  32.168 +
  32.169 +void sb_add_data(sb_dsp_t *dsp, uint8_t v)
  32.170 +{
  32.171 +        dsp->sb_read_data[dsp->sb_read_wp++] = v;
  32.172 +        dsp->sb_read_wp &= 0xff;
  32.173 +}
  32.174 +
  32.175 +#define ADPCM_4  1
  32.176 +#define ADPCM_26 2
  32.177 +#define ADPCM_2  3
  32.178 +
  32.179 +void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
  32.180 +{
  32.181 +        if (dma8)
  32.182 +        {
  32.183 +                dsp->sb_8_length = len;
  32.184 +                dsp->sb_8_format = format;
  32.185 +                dsp->sb_8_autoinit = autoinit;
  32.186 +                dsp->sb_8_pause = 0;
  32.187 +                dsp->sb_8_enable = 1;
  32.188 +                if (dsp->sb_16_enable && dsp->sb_16_output) dsp->sb_16_enable = 0;
  32.189 +                dsp->sb_8_output = 1;
  32.190 +                timer_process();
  32.191 +                dsp->sbenable = dsp->sb_8_enable;
  32.192 +                timer_update_outstanding();
  32.193 +                dsp->sbleftright = 0;
  32.194 +                dsp->sbdacpos = 0;
  32.195 +//                pclog("Start 8-bit DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len);
  32.196 +        }
  32.197 +        else
  32.198 +        {
  32.199 +                dsp->sb_16_length = len;
  32.200 +                dsp->sb_16_format = format;
  32.201 +                dsp->sb_16_autoinit = autoinit;
  32.202 +                dsp->sb_16_pause = 0;
  32.203 +                dsp->sb_16_enable = 1;
  32.204 +                if (dsp->sb_8_enable && dsp->sb_8_output) dsp->sb_8_enable = 0;
  32.205 +                dsp->sb_16_output = 1;
  32.206 +                timer_process();
  32.207 +		dsp->sbenable = dsp->sb_16_enable;
  32.208 +		timer_update_outstanding();
  32.209 +//                pclog("Start 16-bit DMA addr %06X len %04X\n",dma16.ac[1]+(dma16.page[1]<<16),len);
  32.210 +        }
  32.211 +}
  32.212 +
  32.213 +void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len)
  32.214 +{
  32.215 +        if (dma8)
  32.216 +        {
  32.217 +                dsp->sb_8_length = len;
  32.218 +                dsp->sb_8_format = format;
  32.219 +                dsp->sb_8_autoinit = autoinit;
  32.220 +                dsp->sb_8_pause = 0;
  32.221 +                dsp->sb_8_enable = 1;
  32.222 +                if (dsp->sb_16_enable && !dsp->sb_16_output) dsp->sb_16_enable = 0;                
  32.223 +                dsp->sb_8_output = 0;
  32.224 +                timer_process();
  32.225 +                dsp->sb_enable_i = dsp->sb_8_enable;
  32.226 +                timer_update_outstanding();
  32.227 +//                pclog("Start 8-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len);
  32.228 +        }
  32.229 +        else
  32.230 +        {
  32.231 +                dsp->sb_16_length = len;
  32.232 +                dsp->sb_16_format = format;
  32.233 +                dsp->sb_16_autoinit = autoinit;
  32.234 +                dsp->sb_16_pause = 0;
  32.235 +                dsp->sb_16_enable = 1;
  32.236 +                if (dsp->sb_8_enable && !dsp->sb_8_output) dsp->sb_8_enable = 0;
  32.237 +                dsp->sb_16_output = 0;
  32.238 +                timer_process();
  32.239 +                dsp->sb_enable_i = dsp->sb_16_enable;
  32.240 +                timer_update_outstanding();
  32.241 +//                pclog("Start 16-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len);
  32.242 +        }
  32.243 +}
  32.244 +
  32.245 +int sb_8_read_dma(sb_dsp_t *dsp)
  32.246 +{
  32.247 +        return dma_channel_read(dsp->sb_8_dmanum);
  32.248 +}
  32.249 +void sb_8_write_dma(sb_dsp_t *dsp, uint8_t val)
  32.250 +{
  32.251 +        dma_channel_write(dsp->sb_8_dmanum, val);
  32.252 +}
  32.253 +uint16_t sb_16_read_dma(sb_dsp_t *dsp)
  32.254 +{
  32.255 +        return dma_channel_read(5);
  32.256 +}
  32.257 +void sb_16_write_dma(sb_dsp_t *dsp, uint16_t val)
  32.258 +{
  32.259 +        dma_channel_write(5, val);
  32.260 +}
  32.261 +
  32.262 +void sb_dsp_setirq(sb_dsp_t *dsp, int irq)
  32.263 +{
  32.264 +        dsp->sb_irqnum = irq;
  32.265 +}
  32.266 +
  32.267 +void sb_dsp_setdma8(sb_dsp_t *dsp, int dma)
  32.268 +{
  32.269 +        dsp->sb_8_dmanum = dma;
  32.270 +}
  32.271 +
  32.272 +void sb_exec_command(sb_dsp_t *dsp)
  32.273 +{
  32.274 +        int temp,c;
  32.275 +        pclog("sb_exec_command : SB command %02X\n", dsp->sb_command);
  32.276 +        switch (dsp->sb_command)
  32.277 +        {
  32.278 +                case 0x10: /*8-bit direct mode*/
  32.279 +                dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8;
  32.280 +                break;
  32.281 +                case 0x14: /*8-bit single cycle DMA output*/
  32.282 +                sb_start_dma(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
  32.283 +                break;
  32.284 +                case 0x17: /*2-bit ADPCM output with reference*/
  32.285 +                dsp->sbref = sb_8_read_dma(dsp);
  32.286 +                dsp->sbstep = 0;
  32.287 +//                pclog("Ref byte 2 %02X\n",sbref);
  32.288 +                case 0x16: /*2-bit ADPCM output*/
  32.289 +                sb_start_dma(dsp, 1, 0, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
  32.290 +                dsp->sbdat2 = sb_8_read_dma(dsp);
  32.291 +                dsp->sb_8_length--;
  32.292 +                break;
  32.293 +                case 0x1C: /*8-bit autoinit DMA output*/
  32.294 +                if (dsp->sb_type < SB15) break;
  32.295 +                sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen);
  32.296 +                break;
  32.297 +                case 0x1F: /*2-bit ADPCM autoinit output*/
  32.298 +                if (dsp->sb_type < SB15) break;
  32.299 +                sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
  32.300 +                dsp->sbdat2 = sb_8_read_dma(dsp);
  32.301 +                dsp->sb_8_length--;
  32.302 +                break;
  32.303 +                case 0x20: /*8-bit direct input*/
  32.304 +                sb_add_data(dsp, 0);
  32.305 +                break;
  32.306 +                case 0x24: /*8-bit single cycle DMA input*/
  32.307 +                sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
  32.308 +                break;
  32.309 +                case 0x2C: /*8-bit autoinit DMA input*/
  32.310 +                if (dsp->sb_type < SB15) break;
  32.311 +                sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
  32.312 +                break;
  32.313 +                case 0x40: /*Set time constant*/
  32.314 +                dsp->sb_timei = dsp->sb_timeo = dsp->sb_data[0];
  32.315 +                dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]);
  32.316 +                temp = 256 - dsp->sb_data[0];
  32.317 +                temp = 1000000 / temp;
  32.318 +//                printf("Sample rate - %ihz (%i)\n",temp, sblatcho);
  32.319 +                dsp->sb_freq = temp;
  32.320 +                break;
  32.321 +                case 0x41: /*Set output sampling rate*/
  32.322 +                if (dsp->sb_type < SB16) break;
  32.323 +                dsp->sblatcho = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8))));
  32.324 +//                printf("Sample rate - %ihz (%i)\n",sb_data[1]+(sb_data[0]<<8), sblatcho);
  32.325 +                dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8);
  32.326 +                dsp->sb_timeo = 256 + dsp->sb_freq;
  32.327 +                break;
  32.328 +                case 0x42: /*Set input sampling rate*/
  32.329 +                if (dsp->sb_type < SB16) break;
  32.330 +                dsp->sblatchi = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8))));
  32.331 +//                printf("iample rate - %ihz\n",sb_data[1]+(sb_data[0]<<8));
  32.332 +                dsp->sb_timei = 256 + dsp->sb_data[1] + (dsp->sb_data[0] << 8);
  32.333 +                break;
  32.334 +                case 0x48: /*Set DSP block transfer size*/
  32.335 +                dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8);
  32.336 +                break;
  32.337 +                case 0x75: /*4-bit ADPCM output with reference*/
  32.338 +                dsp->sbref = sb_8_read_dma(dsp);
  32.339 +                dsp->sbstep = 0;
  32.340 +//                pclog("Ref byte 4 %02X\n",sbref);
  32.341 +                case 0x74: /*4-bit ADPCM output*/
  32.342 +                sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
  32.343 +                dsp->sbdat2 = sb_8_read_dma(dsp);
  32.344 +                dsp->sb_8_length--;
  32.345 +                break;
  32.346 +                case 0x77: /*2.6-bit ADPCM output with reference*/
  32.347 +                dsp->sbref = sb_8_read_dma(dsp);
  32.348 +                dsp->sbstep = 0;
  32.349 +//                pclog("Ref byte 26 %02X\n",sbref);
  32.350 +                case 0x76: /*2.6-bit ADPCM output*/
  32.351 +                sb_start_dma(dsp, 1, 0, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
  32.352 +                dsp->sbdat2 = sb_8_read_dma(dsp);
  32.353 +                dsp->sb_8_length--;
  32.354 +                break;
  32.355 +                case 0x7D: /*4-bit ADPCM autoinit output*/
  32.356 +                if (dsp->sb_type < SB15) break;
  32.357 +                sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
  32.358 +                dsp->sbdat2 = sb_8_read_dma(dsp);
  32.359 +                dsp->sb_8_length--;
  32.360 +                break;
  32.361 +                case 0x7F: /*2.6-bit ADPCM autoinit output*/
  32.362 +                if (dsp->sb_type < SB15) break;
  32.363 +                sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
  32.364 +                dsp->sbdat2 = sb_8_read_dma(dsp);
  32.365 +                dsp->sb_8_length--;
  32.366 +                break;
  32.367 +                case 0x80: /*Pause DAC*/
  32.368 +                dsp->sb_pausetime = dsp->sb_data[0] + (dsp->sb_data[1] << 8);
  32.369 +//                pclog("SB pause %04X\n",sb_pausetime);
  32.370 +		timer_process();
  32.371 +                dsp->sbenable = 1;
  32.372 +                timer_update_outstanding();
  32.373 +                break;
  32.374 +                case 0x90: /*High speed 8-bit autoinit DMA output*/
  32.375 +                if (dsp->sb_type < SB2) break;
  32.376 +                sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen);
  32.377 +                break;
  32.378 +                case 0x91: /*High speed 8-bit single cycle DMA output*/
  32.379 +                if (dsp->sb_type < SB2) break;
  32.380 +                sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen);
  32.381 +                break;
  32.382 +                case 0x98: /*High speed 8-bit autoinit DMA input*/
  32.383 +                if (dsp->sb_type < SB2) break;
  32.384 +                sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen);
  32.385 +                break;
  32.386 +                case 0x99: /*High speed 8-bit single cycle DMA input*/
  32.387 +                if (dsp->sb_type < SB2) break;
  32.388 +                sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen);
  32.389 +                break;
  32.390 +                case 0xA0: /*Set input mode to mono*/
  32.391 +                case 0xA8: /*Set input mode to stereo*/
  32.392 +                break;
  32.393 +                case 0xB0: case 0xB1: case 0xB2: case 0xB3:
  32.394 +                case 0xB4: case 0xB5: case 0xB6: case 0xB7: /*16-bit DMA output*/
  32.395 +                if (dsp->sb_type < SB16) break;
  32.396 +                sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8));
  32.397 +                dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
  32.398 +                break;
  32.399 +                case 0xB8: case 0xB9: case 0xBA: case 0xBB:
  32.400 +                case 0xBC: case 0xBD: case 0xBE: case 0xBF: /*16-bit DMA input*/
  32.401 +                if (dsp->sb_type < SB16) break;
  32.402 +                sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8));
  32.403 +                dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
  32.404 +                break;
  32.405 +                case 0xC0: case 0xC1: case 0xC2: case 0xC3:
  32.406 +                case 0xC4: case 0xC5: case 0xC6: case 0xC7: /*8-bit DMA output*/
  32.407 +                if (dsp->sb_type < SB16) break;
  32.408 +                sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8));
  32.409 +                dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
  32.410 +                break;
  32.411 +                case 0xC8: case 0xC9: case 0xCA: case 0xCB:
  32.412 +                case 0xCC: case 0xCD: case 0xCE: case 0xCF: /*8-bit DMA input*/
  32.413 +                if (dsp->sb_type < SB16) break;
  32.414 +                sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8));
  32.415 +                dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
  32.416 +                break;
  32.417 +                case 0xD0: /*Pause 8-bit DMA*/
  32.418 +                dsp->sb_8_pause = 1;
  32.419 +                break;
  32.420 +                case 0xD1: /*Speaker on*/
  32.421 +                dsp->sb_speaker = 1;
  32.422 +                break;
  32.423 +                case 0xD3: /*Speaker off*/
  32.424 +                dsp->sb_speaker = 0;
  32.425 +                break;
  32.426 +                case 0xD4: /*Continue 8-bit DMA*/
  32.427 +                dsp->sb_8_pause = 0;
  32.428 +                break;
  32.429 +                case 0xD5: /*Pause 16-bit DMA*/
  32.430 +                if (dsp->sb_type < SB16) break;
  32.431 +                dsp->sb_16_pause = 1;
  32.432 +                break;
  32.433 +                case 0xD6: /*Continue 16-bit DMA*/
  32.434 +                if (dsp->sb_type < SB16) break;
  32.435 +                dsp->sb_16_pause = 0;
  32.436 +                break;
  32.437 +                case 0xD8: /*Get speaker status*/
  32.438 +                sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0);
  32.439 +                break;
  32.440 +                case 0xD9: /*Exit 16-bit auto-init mode*/
  32.441 +                if (dsp->sb_type < SB16) break;
  32.442 +                dsp->sb_16_autoinit = 0;
  32.443 +                break;
  32.444 +                case 0xDA: /*Exit 8-bit auto-init mode*/
  32.445 +                dsp->sb_8_autoinit = 0;
  32.446 +                break;
  32.447 +                case 0xE0: /*DSP identification*/
  32.448 +                sb_add_data(dsp, ~dsp->sb_data[0]);
  32.449 +                break;
  32.450 +                case 0xE1: /*Get DSP version*/
  32.451 +                sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] >> 8);
  32.452 +                sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] & 0xff);
  32.453 +                break;
  32.454 +                case 0xE2: /*Stupid ID/protection*/
  32.455 +                for (c = 0; c < 8; c++)
  32.456 +                    if (dsp->sb_data[0] & (1 << c)) dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][c];
  32.457 +                dsp->sbe2 += sbe2dat[dsp->sbe2count & 3][8];
  32.458 +                dsp->sbe2count++;
  32.459 +                sb_8_write_dma(dsp, dsp->sbe2);
  32.460 +                break;
  32.461 +                case 0xE3: /*DSP copyright*/
  32.462 +                if (dsp->sb_type < SB16) break;
  32.463 +                c = 0;
  32.464 +                while (sb16_copyright[c])
  32.465 +                      sb_add_data(dsp, sb16_copyright[c++]);
  32.466 +                sb_add_data(dsp, 0);
  32.467 +                break;
  32.468 +                case 0xE4: /*Write test register*/
  32.469 +                dsp->sb_test = dsp->sb_data[0];
  32.470 +                break;
  32.471 +                case 0xE8: /*Read test register*/
  32.472 +                sb_add_data(dsp, dsp->sb_test);
  32.473 +                break;
  32.474 +                case 0xF2: /*Trigger 8-bit IRQ*/
  32.475 +//                pclog("Trigger IRQ\n");
  32.476 +                sb_irq(dsp, 1);
  32.477 +                break;
  32.478 +                case 0xE7: /*???*/
  32.479 +                case 0xFA: /*???*/
  32.480 +                break;
  32.481 +                case 0x07: /*No, that's not how you program auto-init DMA*/
  32.482 +                case 0xFF:
  32.483 +                break;
  32.484 +                case 0x08: /*ASP get version*/
  32.485 +                if (dsp->sb_type < SB16) break;
  32.486 +                sb_add_data(dsp, 0x18);
  32.487 +                break;
  32.488 +                case 0x0E: /*ASP set register*/
  32.489 +                if (dsp->sb_type < SB16) break;
  32.490 +                dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1];
  32.491 +//                pclog("ASP write reg %02X %02X\n", sb_data[0], sb_data[1]);
  32.492 +                break;
  32.493 +                case 0x0F: /*ASP get register*/
  32.494 +                if (dsp->sb_type < SB16) break;
  32.495 +//                sb_add_data(0);
  32.496 +                sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]);
  32.497 +//                pclog("ASP read reg %02X %02X\n", sb_data[0], sb_asp_regs[sb_data[0]]);
  32.498 +                break;
  32.499 +                case 0xF9:
  32.500 +                if (dsp->sb_type < SB16) break;
  32.501 +                if (dsp->sb_data[0] == 0x0e)      sb_add_data(dsp, 0xff);
  32.502 +                else if (dsp->sb_data[0] == 0x0f) sb_add_data(dsp, 0x07);
  32.503 +                else if (dsp->sb_data[0] == 0x37) sb_add_data(dsp, 0x38);
  32.504 +                else                              sb_add_data(dsp, 0x00);
  32.505 +                case 0x04:
  32.506 +                case 0x05:
  32.507 +                break;
  32.508 +//                default:
  32.509 +//                fatal("Exec bad SB command %02X\n",sb_command);
  32.510 +        }
  32.511 +}
  32.512 +        
  32.513 +void sb_write(uint16_t a, uint8_t v, void *priv)
  32.514 +{
  32.515 +        sb_dsp_t *dsp = (sb_dsp_t *)priv;
  32.516 +        printf("sb_write : Write soundblaster %04X %02X %04X:%04X %02X\n",a,v,CS,pc,dsp->sb_command);
  32.517 +        switch (a&0xF)
  32.518 +        {
  32.519 +                case 6: /*Reset*/
  32.520 +                if (!(v & 1) && (dsp->sbreset & 1))
  32.521 +                {
  32.522 +                        sb_dsp_reset(dsp);
  32.523 +                        sb_add_data(dsp, 0xAA);
  32.524 +                }
  32.525 +                dsp->sbreset = v;
  32.526 +                return;
  32.527 +                case 0xC: /*Command/data write*/
  32.528 +                if (dsp->sb_data_stat == -1)
  32.529 +                {
  32.530 +                        dsp->sb_command = v;
  32.531 +//                        if (sb_commands[v]==-1)
  32.532 +//                           fatal("Bad SB command %02X\n",v);
  32.533 +                        dsp->sb_data_stat++;
  32.534 +                }
  32.535 +                else
  32.536 +                   dsp->sb_data[dsp->sb_data_stat++] = v;
  32.537 +                if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1)
  32.538 +                {
  32.539 +                        sb_exec_command(dsp);
  32.540 +                        dsp->sb_data_stat = -1;
  32.541 +                }
  32.542 +                break;
  32.543 +        }
  32.544 +}
  32.545 +
  32.546 +uint8_t sb_read(uint16_t a, void *priv)
  32.547 +{
  32.548 +        sb_dsp_t *dsp = (sb_dsp_t *)priv;
  32.549 +//        if (a==0x224) output=1;
  32.550 +        pclog("sb_read : Read soundblaster %04X %04X:%04X\n",a,CS,pc);
  32.551 +        switch (a & 0xf)
  32.552 +        {
  32.553 +                case 0xA: /*Read data*/
  32.554 +                dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp];
  32.555 +                if (dsp->sb_read_rp != dsp->sb_read_wp)
  32.556 +                {
  32.557 +                        dsp->sb_read_rp++;
  32.558 +                        dsp->sb_read_rp &= 0xFF;
  32.559 +                }
  32.560 +//                pclog("SB read %02X\n",sbreaddat);
  32.561 +                return dsp->sbreaddat;
  32.562 +                case 0xC: /*Write data ready*/
  32.563 +                cycles -= 100;
  32.564 +                dsp->writebusy++;
  32.565 +                if (dsp->writebusy & 8) return 0xff;
  32.566 +                return 0x7f;
  32.567 +                case 0xE: /*Read data ready*/
  32.568 +                picintc(1 << dsp->sb_irqnum);
  32.569 +                dsp->sb_irq8 = dsp->sb_irq16 = 0;
  32.570 +                return (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff;
  32.571 +                case 0xF: /*16-bit ack*/
  32.572 +                dsp->sb_irq16 = 0;
  32.573 +                if (!dsp->sb_irq8) picintc(1 << dsp->sb_irqnum);
  32.574 +                return 0xff;
  32.575 +        }
  32.576 +        return 0;
  32.577 +}
  32.578 +
  32.579 +void sb_dsp_init(sb_dsp_t *dsp, int type)
  32.580 +{
  32.581 +        dsp->sb_type = type;
  32.582 +        
  32.583 +        dsp->sb_irqnum = 7;
  32.584 +        dsp->sb_8_dmanum = 1;
  32.585 +        
  32.586 +        sb_doreset(dsp);
  32.587 +
  32.588 +        timer_add(pollsb, &dsp->sbcount, &dsp->sbenable, dsp);
  32.589 +        timer_add(sb_poll_i, &dsp->sb_count_i, &dsp->sb_enable_i, dsp);
  32.590 +}
  32.591 +
  32.592 +void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr)
  32.593 +{
  32.594 +        pclog("sb_dsp_setaddr : %04X\n", addr);
  32.595 +        io_removehandler(dsp->sb_addr + 6,   0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp);
  32.596 +        io_removehandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp);        
  32.597 +        dsp->sb_addr = addr;
  32.598 +        if (dsp->sb_addr != 0)
  32.599 +        {
  32.600 +                io_sethandler(dsp->sb_addr + 6,   0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp);
  32.601 +                io_sethandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp);        
  32.602 +        }
  32.603 +}
  32.604 +
  32.605 +void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo)
  32.606 +{
  32.607 +        dsp->stereo = stereo;
  32.608 +}
  32.609 +
  32.610 +void pollsb(void *p)
  32.611 +{
  32.612 +        sb_dsp_t *dsp = (sb_dsp_t *)p;
  32.613 +        int tempi,ref;
  32.614 +        
  32.615 +        dsp->sbcount += dsp->sblatcho;
  32.616 +//        pclog("PollSB %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output);
  32.617 +        if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output)
  32.618 +        {
  32.619 +                int data[2];
  32.620 +//                pclog("Dopoll %i %02X %i\n", sb_8_length, sb_8_format, sblatcho);
  32.621 +                switch (dsp->sb_8_format)
  32.622 +                {
  32.623 +                        case 0x00: /*Mono unsigned*/
  32.624 +                        data[0] = sb_8_read_dma(dsp);
  32.625 +                        /*Needed to prevent clicking in Worms, which programs the DSP to
  32.626 +                          auto-init DMA but programs the DMA controller to single cycle*/
  32.627 +                        if (data[0] == DMA_NODATA)
  32.628 +                                break;
  32.629 +                        dsp->sbdat = (data[0] ^ 0x80) << 8;
  32.630 +                        if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo)
  32.631 +                        {
  32.632 +                                if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat;
  32.633 +                                else                  dsp->sbdatr = dsp->sbdat;
  32.634 +                                dsp->sbleftright = !dsp->sbleftright;
  32.635 +                        }
  32.636 +                        else
  32.637 +                           dsp->sbdatl = dsp->sbdatr = dsp->sbdat;
  32.638 +                        dsp->sb_8_length--;
  32.639 +                        break;
  32.640 +                        case 0x10: /*Mono signed*/
  32.641 +                        data[0] = sb_8_read_dma(dsp);
  32.642 +                        if (data[0] == DMA_NODATA)
  32.643 +                                break;
  32.644 +                        dsp->sbdat = data[0] << 8;
  32.645 +                        if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo)
  32.646 +                        {
  32.647 +                                if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat;
  32.648 +                                else                  dsp->sbdatr = dsp->sbdat;
  32.649 +                                dsp->sbleftright = !dsp->sbleftright;
  32.650 +                        }
  32.651 +                        else
  32.652 +                           dsp->sbdatl = dsp->sbdatr = dsp->sbdat;
  32.653 +                        dsp->sb_8_length--;
  32.654 +                        break;
  32.655 +                        case 0x20: /*Stereo unsigned*/
  32.656 +                        data[0] = sb_8_read_dma(dsp);
  32.657 +                        data[1] = sb_8_read_dma(dsp);
  32.658 +                        if (data[0] == DMA_NODATA || data[1] == DMA_NODATA)
  32.659 +                                break;
  32.660 +                        dsp->sbdatl = (data[0] ^ 0x80) << 8;
  32.661 +                        dsp->sbdatr = (data[1] ^ 0x80) << 8;
  32.662 +                        dsp->sb_8_length -= 2;
  32.663 +                        break;
  32.664 +                        case 0x30: /*Stereo signed*/
  32.665 +                        data[0] = sb_8_read_dma(dsp);
  32.666 +                        data[1] = sb_8_read_dma(dsp);
  32.667 +                        if (data[0] == DMA_NODATA || data[1] == DMA_NODATA)
  32.668 +                                break;
  32.669 +                        dsp->sbdatl = data[0] << 8;
  32.670 +                        dsp->sbdatr = data[1] << 8;
  32.671 +                        dsp->sb_8_length -= 2;
  32.672 +                        break;
  32.673 +
  32.674 +                        case ADPCM_4:
  32.675 +                        if (dsp->sbdacpos) tempi = (dsp->sbdat2 & 0xF) + dsp->sbstep;
  32.676 +                        else               tempi = (dsp->sbdat2 >> 4)  + dsp->sbstep;
  32.677 +                        if (tempi < 0)  tempi = 0;
  32.678 +                        if (tempi > 63) tempi = 63;
  32.679 +
  32.680 +                        ref = dsp->sbref + scaleMap4[tempi];
  32.681 +                        if (ref > 0xff) dsp->sbref = 0xff;
  32.682 +                        else if (ref < 0x00) dsp->sbref = 0x00;
  32.683 +                        else dsp->sbref = ref;
  32.684 +
  32.685 +                        dsp->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff;
  32.686 +
  32.687 +                        dsp->sbdat = (dsp->sbref ^ 0x80) << 8;
  32.688 +
  32.689 +                        dsp->sbdacpos++;
  32.690 +                        if (dsp->sbdacpos >= 2)
  32.691 +                        {
  32.692 +                                dsp->sbdacpos = 0;
  32.693 +                                dsp->sbdat2 = sb_8_read_dma(dsp);
  32.694 +                                dsp->sb_8_length--;
  32.695 +                        }
  32.696 +
  32.697 +                        if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo)
  32.698 +                        {
  32.699 +                                if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat;
  32.700 +                                else                  dsp->sbdatr = dsp->sbdat;
  32.701 +                                dsp->sbleftright = !dsp->sbleftright;
  32.702 +                        }
  32.703 +                        else
  32.704 +                           dsp->sbdatl = dsp->sbdatr = dsp->sbdat;
  32.705 +                        break;
  32.706 +                        
  32.707 +                        case ADPCM_26:
  32.708 +                        if (!dsp->sbdacpos)          tempi = (dsp->sbdat2 >> 5) + dsp->sbstep;
  32.709 +                        else if (dsp->sbdacpos == 1) tempi = ((dsp->sbdat2 >> 2) & 7) + dsp->sbstep;
  32.710 +                        else                         tempi = ((dsp->sbdat2 << 1) & 7) + dsp->sbstep;
  32.711 +
  32.712 +                        if (tempi < 0)  tempi = 0;
  32.713 +                        if (tempi > 39) tempi = 39;
  32.714 +
  32.715 +                        ref = dsp->sbref + scaleMap26[tempi];
  32.716 +                        if (ref > 0xff) dsp->sbref = 0xff;
  32.717 +                        else if (ref < 0x00) dsp->sbref = 0x00;
  32.718 +                        else dsp->sbref = ref;
  32.719 +                        dsp->sbstep = (dsp->sbstep + adjustMap26[tempi]) & 0xff;
  32.720 +
  32.721 +                        dsp->sbdat = (dsp->sbref ^ 0x80) << 8;
  32.722 +
  32.723 +                        dsp->sbdacpos++;
  32.724 +                        if (dsp->sbdacpos>=3)
  32.725 +                        {
  32.726 +                                dsp->sbdacpos = 0;
  32.727 +                                dsp->sbdat2 = sb_8_read_dma(dsp);
  32.728 +                                dsp->sb_8_length--;
  32.729 +                        }
  32.730 +
  32.731 +                        if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo)
  32.732 +                        {
  32.733 +                                if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat;
  32.734 +                                else                  dsp->sbdatr = dsp->sbdat;
  32.735 +                                dsp->sbleftright = !dsp->sbleftright;
  32.736 +                        }
  32.737 +                        else
  32.738 +                           dsp->sbdatl = dsp->sbdatr = dsp->sbdat;
  32.739 +                        break;
  32.740 +
  32.741 +                        case ADPCM_2:
  32.742 +                        tempi = ((dsp->sbdat2 >> ((3 - dsp->sbdacpos) * 2)) & 3) + dsp->sbstep;
  32.743 +                        if (tempi < 0)  tempi = 0;
  32.744 +                        if (tempi > 23) tempi = 23;
  32.745 +
  32.746 +                        ref = dsp->sbref + scaleMap2[tempi];
  32.747 +                        if (ref > 0xff) dsp->sbref = 0xff;
  32.748 +                        else if (ref < 0x00) dsp->sbref = 0x00;
  32.749 +                        else dsp->sbref = ref;
  32.750 +                        dsp->sbstep = (dsp->sbstep + adjustMap2[tempi]) & 0xff;
  32.751 +                        
  32.752 +                        dsp->sbdat = (dsp->sbref ^ 0x80) << 8;
  32.753 +
  32.754 +                        dsp->sbdacpos++;
  32.755 +                        if (dsp->sbdacpos >= 4)
  32.756 +                        {
  32.757 +                                dsp->sbdacpos = 0;
  32.758 +                                dsp->sbdat2 = sb_8_read_dma(dsp);
  32.759 +                        }
  32.760 +
  32.761 +                        if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo)
  32.762 +                        {
  32.763 +                                if (dsp->sbleftright) dsp->sbdatl = dsp->sbdat;
  32.764 +                                else                  dsp->sbdatr = dsp->sbdat;
  32.765 +                                dsp->sbleftright = !dsp->sbleftright;
  32.766 +                        }
  32.767 +                        else
  32.768 +                           dsp->sbdatl = dsp->sbdatr = dsp->sbdat;
  32.769 +                        break;
  32.770 +
  32.771 +//                        default:
  32.772 +                                //fatal("Unrecognised SB 8-bit format %02X\n",sb_8_format);
  32.773 +                }
  32.774 +                
  32.775 +                if (dsp->sb_8_length < 0)
  32.776 +                {
  32.777 +                        if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_autolen;
  32.778 +                        else                    dsp->sb_8_enable = dsp->sbenable=0;
  32.779 +                        sb_irq(dsp, 1);
  32.780 +                }
  32.781 +        }
  32.782 +        if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0 && dsp->sb_16_output)
  32.783 +        {
  32.784 +                switch (dsp->sb_16_format)
  32.785 +                {
  32.786 +                        case 0x00: /*Mono unsigned*/
  32.787 +                        dsp->sbdatl = dsp->sbdatr = sb_16_read_dma(dsp) ^ 0x8000;
  32.788 +                        dsp->sb_16_length--;
  32.789 +                        break;
  32.790 +                        case 0x10: /*Mono signed*/
  32.791 +                        dsp->sbdatl = dsp->sbdatr = sb_16_read_dma(dsp);
  32.792 +                        dsp->sb_16_length--;
  32.793 +                        break;
  32.794 +                        case 0x20: /*Stereo unsigned*/
  32.795 +                        dsp->sbdatl = sb_16_read_dma(dsp) ^ 0x8000;
  32.796 +                        dsp->sbdatr = sb_16_read_dma(dsp) ^ 0x8000;
  32.797 +                        dsp->sb_16_length -= 2;
  32.798 +                        break;
  32.799 +                        case 0x30: /*Stereo signed*/
  32.800 +                        dsp->sbdatl = sb_16_read_dma(dsp);
  32.801 +                        dsp->sbdatr = sb_16_read_dma(dsp);
  32.802 +                        dsp->sb_16_length -= 2;
  32.803 +                        break;
  32.804 +
  32.805 +//                        default:
  32.806 +//                                fatal("Unrecognised SB 16-bit format %02X\n",sb_16_format);
  32.807 +                }
  32.808 +
  32.809 +                if (dsp->sb_16_length < 0)
  32.810 +                {
  32.811 +//                        pclog("16DMA over %i\n",sb_16_autoinit);
  32.812 +                        if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen;
  32.813 +                        else                     dsp->sb_16_enable = dsp->sbenable = 0;
  32.814 +                        sb_irq(dsp, 0);
  32.815 +                }
  32.816 +        }
  32.817 +        if (dsp->sb_pausetime > -1)
  32.818 +        {
  32.819 +                dsp->sb_pausetime--;
  32.820 +                if (dsp->sb_pausetime < 0)
  32.821 +                {
  32.822 +                        sb_irq(dsp, 1);
  32.823 +                        dsp->sbenable = dsp->sb_8_enable;
  32.824 +                        pclog("SB pause over\n");
  32.825 +                }
  32.826 +        }
  32.827 +}
  32.828 +
  32.829 +void sb_poll_i(void *p)
  32.830 +{
  32.831 +        sb_dsp_t *dsp = (sb_dsp_t *)p;
  32.832 +        
  32.833 +        dsp->sb_count_i += dsp->sblatchi;
  32.834 +//        pclog("PollSBi %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output);        
  32.835 +        if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output)
  32.836 +        {
  32.837 +                switch (dsp->sb_8_format)
  32.838 +                {
  32.839 +                        case 0x00: /*Mono unsigned*/
  32.840 +                        sb_8_write_dma(dsp, 0x80);
  32.841 +                        dsp->sb_8_length--;
  32.842 +                        break;
  32.843 +                        case 0x10: /*Mono signed*/
  32.844 +                        sb_8_write_dma(dsp, 0x00);
  32.845 +                        dsp->sb_8_length--;
  32.846 +                        break;
  32.847 +                        case 0x20: /*Stereo unsigned*/
  32.848 +                        sb_8_write_dma(dsp, 0x80);
  32.849 +                        sb_8_write_dma(dsp, 0x80);
  32.850 +                        dsp->sb_8_length -= 2;
  32.851 +                        break;
  32.852 +                        case 0x30: /*Stereo signed*/
  32.853 +                        sb_8_write_dma(dsp, 0x00);
  32.854 +                        sb_8_write_dma(dsp, 0x00);
  32.855 +                        dsp->sb_8_length -= 2;
  32.856 +                        break;
  32.857 +
  32.858 +//                        default:
  32.859 +//                                fatal("Unrecognised SB 8-bit input format %02X\n",sb_8_format);
  32.860 +                }
  32.861 +                
  32.862 +                if (dsp->sb_8_length < 0)
  32.863 +                {
  32.864 +//                        pclog("Input DMA over %i\n",sb_8_autoinit);
  32.865 +                        if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_autolen;
  32.866 +                        else                    dsp->sb_8_enable = dsp->sbenable = 0;
  32.867 +                        sb_irq(dsp, 1);
  32.868 +                }
  32.869 +        }
  32.870 +        if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0 && !dsp->sb_16_output)
  32.871 +        {
  32.872 +                switch (dsp->sb_16_format)
  32.873 +                {
  32.874 +                        case 0x00: /*Unsigned mono*/
  32.875 +                        sb_16_write_dma(dsp, 0x8000);
  32.876 +                        dsp->sb_16_length--;
  32.877 +                        break;
  32.878 +                        case 0x10: /*Signed mono*/
  32.879 +                        sb_16_write_dma(dsp, 0);
  32.880 +                        dsp->sb_16_length--;
  32.881 +                        break;
  32.882 +                        case 0x20: /*Unsigned stereo*/
  32.883 +                        sb_16_write_dma(dsp, 0x8000);
  32.884 +                        sb_16_write_dma(dsp, 0x8000);
  32.885 +                        dsp->sb_16_length -= 2;
  32.886 +                        break;
  32.887 +                        case 0x30: /*Signed stereo*/
  32.888 +                        sb_16_write_dma(dsp, 0);
  32.889 +                        sb_16_write_dma(dsp, 0);
  32.890 +                        dsp->sb_16_length -= 2;
  32.891 +                        break;
  32.892 +                        
  32.893 +//                        default:
  32.894 +//                                fatal("Unrecognised SB 16-bit input format %02X\n",sb_16_format);
  32.895 +                }
  32.896 +                
  32.897 +                if (dsp->sb_16_length < 0)
  32.898 +                {
  32.899 +//                        pclog("16iDMA over %i\n",sb_16_autoinit);
  32.900 +                        if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen;
  32.901 +                        else                     dsp->sb_16_enable = dsp->sbenable = 0;
  32.902 +                        sb_irq(dsp, 0);
  32.903 +                }
  32.904 +        }
  32.905 +}
  32.906 +
  32.907 +void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r)
  32.908 +{
  32.909 +        *l = dsp->sbdatl;
  32.910 +        *r = dsp->sbdatr;
  32.911 +}
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/src/sound_sb_dsp.h	Mon May 27 19:56:33 2013 +0100
    33.3 @@ -0,0 +1,69 @@
    33.4 +typedef struct sb_dsp_t
    33.5 +{
    33.6 +        int sb_type;
    33.7 +
    33.8 +        int sb_8_length,  sb_8_format,  sb_8_autoinit,  sb_8_pause,  sb_8_enable,  sb_8_autolen,  sb_8_output;
    33.9 +        int sb_8_dmanum;
   33.10 +        int sb_16_length, sb_16_format, sb_16_autoinit, sb_16_pause, sb_16_enable, sb_16_autolen, sb_16_output;
   33.11 +        int sb_pausetime;
   33.12 +
   33.13 +        uint8_t sb_read_data[256];
   33.14 +        int sb_read_wp, sb_read_rp;
   33.15 +        int sb_speaker;
   33.16 +
   33.17 +        int sb_data_stat;
   33.18 +
   33.19 +        int sb_irqnum;
   33.20 +
   33.21 +        uint8_t sbe2;
   33.22 +        int sbe2count;
   33.23 +
   33.24 +        uint8_t sb_data[8];
   33.25 +
   33.26 +        int sb_freq;
   33.27 +        
   33.28 +        int writebusy; /*Needed for Amnesia*/
   33.29 +
   33.30 +        int16_t sbdat;
   33.31 +        int sbdat2;
   33.32 +        int16_t sbdatl, sbdatr;
   33.33 +
   33.34 +        uint8_t sbref;
   33.35 +        int8_t sbstep;
   33.36 +
   33.37 +        int sbdacpos;
   33.38 +
   33.39 +        int sbleftright;
   33.40 +
   33.41 +        int sbreset;
   33.42 +        uint8_t sbreaddat;
   33.43 +        uint8_t sb_command;
   33.44 +        uint8_t sb_test;
   33.45 +        int sb_timei, sb_timeo;
   33.46 +
   33.47 +        int sb_irq8, sb_irq16;
   33.48 +
   33.49 +        uint8_t sb_asp_regs[256];
   33.50 +        
   33.51 +        int sbenable, sb_enable_i;
   33.52 +        
   33.53 +        int sbcount, sb_count_i;
   33.54 +        
   33.55 +        int sblatcho, sblatchi;
   33.56 +        
   33.57 +        uint16_t sb_addr;
   33.58 +        
   33.59 +        int stereo;
   33.60 +} sb_dsp_t;
   33.61 +
   33.62 +void sb_dsp_init(sb_dsp_t *dsp, int type);
   33.63 +
   33.64 +void sb_dsp_setirq(sb_dsp_t *dsp, int irq);
   33.65 +void sb_dsp_setdma8(sb_dsp_t *dsp, int dma);
   33.66 +void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr);
   33.67 +
   33.68 +void sb_dsp_speed_changed(sb_dsp_t *dsp);
   33.69 +
   33.70 +void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r);
   33.71 +
   33.72 +void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo);
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/src/sound_sn76489.c	Mon May 27 19:56:33 2013 +0100
    34.3 @@ -0,0 +1,198 @@
    34.4 +#include <stdlib.h>
    34.5 +#include "ibm.h"
    34.6 +#include "device.h"
    34.7 +#include "io.h"
    34.8 +#include "sound.h"
    34.9 +#include "sound_sn76489.h"
   34.10 +
   34.11 +static float volslog[16]=
   34.12 +{
   34.13 +	0.00000f,0.59715f,0.75180f,0.94650f,
   34.14 +        1.19145f,1.50000f,1.88835f,2.37735f,
   34.15 +        2.99295f,3.76785f,4.74345f,5.97165f,
   34.16 +        7.51785f,9.46440f,11.9194f,15.0000f
   34.17 +};
   34.18 +
   34.19 +typedef struct sn76489_t
   34.20 +{
   34.21 +        int stat[4];
   34.22 +        int latch[4], count[4];
   34.23 +        int freqlo[4], freqhi[4];
   34.24 +        int vol[4];
   34.25 +        uint32_t shift;
   34.26 +        uint8_t noise;
   34.27 +        int lasttone;
   34.28 +        uint8_t firstdat;
   34.29 +        
   34.30 +        int16_t buffer[SOUNDBUFLEN];
   34.31 +        int pos;
   34.32 +} sn76489_t;
   34.33 +
   34.34 +#define PSGCONST ((3579545.0 / 64.0) / 48000.0)
   34.35 +
   34.36 +void sn76489_poll(void *p)
   34.37 +{
   34.38 +        sn76489_t *sn76489 = (sn76489_t *)p;
   34.39 +        int c;
   34.40 +        int16_t result = 0;
   34.41 +        
   34.42 +        if (sn76489->pos >= SOUNDBUFLEN)
   34.43 +                return;
   34.44 +                
   34.45 +        for (c = 1; c < 4; c++)
   34.46 +        {
   34.47 +                if (sn76489->latch[c] > 256) result += (int16_t) (volslog[sn76489->vol[c]] * sn76489->stat[c]);
   34.48 +                else                         result += (int16_t) (volslog[sn76489->vol[c]] * 127);
   34.49 +
   34.50 +                sn76489->count[c] -= (256 * PSGCONST);
   34.51 +                while ((int)sn76489->count[c] < 0 && sn76489->latch[c])
   34.52 +                {
   34.53 +                        sn76489->count[c] += sn76489->latch[c];
   34.54 +                        sn76489->stat[c] = -sn76489->stat[c];
   34.55 +                }
   34.56 +        }
   34.57 +        result += (((sn76489->shift & 1) ^ 1) * 127 * volslog[sn76489->vol[0]] * 2);
   34.58 +
   34.59 +        sn76489->count[0] -= (512 * PSGCONST);
   34.60 +        while ((int)sn76489->count[0] < 0 && sn76489->latch[0])
   34.61 +        {
   34.62 +                sn76489->count[0] += (sn76489->latch[0] * 2);
   34.63 +                if (!(sn76489->noise & 4))
   34.64 +                {
   34.65 +                        if (sn76489->shift & 1) 
   34.66 +                                sn76489->shift |= 0x8000;
   34.67 +                        sn76489->shift >>= 1;
   34.68 +                }
   34.69 +                else
   34.70 +                {
   34.71 +                        if ((sn76489->shift & 1) ^ ((sn76489->shift >> 1) & 1)) 
   34.72 +                                sn76489->shift |= 0x8000;
   34.73 +                        sn76489->shift >>= 1;
   34.74 +                }
   34.75 +        }
   34.76 +        
   34.77 +        sn76489->buffer[sn76489->pos++] = result;
   34.78 +}
   34.79 +
   34.80 +void sn76489_get_buffer(int16_t *buffer, int len, void *p)
   34.81 +{
   34.82 +        sn76489_t *sn76489 = (sn76489_t *)p;
   34.83 +        
   34.84 +        int c;
   34.85 +
   34.86 +        for (c = 0; c < len * 2; c++)
   34.87 +                buffer[c] += sn76489->buffer[c >> 1];
   34.88 +
   34.89 +        sn76489->pos = 0;
   34.90 +}
   34.91 +
   34.92 +void sn76489_write(uint16_t addr, uint8_t data, void *p)
   34.93 +{
   34.94 +        sn76489_t *sn76489 = (sn76489_t *)p;
   34.95 +        int freq;
   34.96 +
   34.97 +        if (data & 0x80)
   34.98 +        {
   34.99 +                sn76489->firstdat = data;
  34.100 +                switch (data & 0x70)
  34.101 +                {
  34.102 +                        case 0:
  34.103 +                        sn76489->freqlo[3] = data & 0xf;
  34.104 +                        sn76489->latch[3] = (sn76489->freqlo[3] | (sn76489->freqhi[3] << 4)) << 6;
  34.105 +                        sn76489->lasttone = 3;
  34.106 +                        break;
  34.107 +                        case 0x10:
  34.108 +                        data &= 0xf;
  34.109 +                        sn76489->vol[3] = 0xf - data;
  34.110 +                        break;
  34.111 +                        case 0x20:
  34.112 +                        sn76489->freqlo[2] = data & 0xf;
  34.113 +                        sn76489->latch[2] = (sn76489->freqlo[2] | (sn76489->freqhi[2] << 4)) << 6;
  34.114 +                        sn76489->lasttone = 2;
  34.115 +                        break;
  34.116 +                        case 0x30:
  34.117 +                        data &= 0xf;
  34.118 +                        sn76489->vol[2] = 0xf - data;
  34.119 +                        break;
  34.120 +                        case 0x40:
  34.121 +                        sn76489->freqlo[1] = data & 0xf;
  34.122 +                        sn76489->latch[1] = (sn76489->freqlo[1] | (sn76489->freqhi[1] << 4)) << 6;
  34.123 +                        sn76489->lasttone = 1;
  34.124 +                        break;
  34.125 +                        case 0x50:
  34.126 +                        data &= 0xf;
  34.127 +                        sn76489->vol[1] = 0xf - data;
  34.128 +                        break;
  34.129 +                        case 0x60:
  34.130 +                        sn76489->shift = 0x4000;
  34.131 +                        if ((data & 3) != (sn76489->noise & 3)) sn76489->count[0] = 0;
  34.132 +                        sn76489->noise = data & 0xf;
  34.133 +                        if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1];
  34.134 +                        else                 sn76489->latch[0] = 0x400 << (data & 3);
  34.135 +                        break;
  34.136 +                        case 0x70:
  34.137 +                        data &= 0xf;
  34.138 +                        sn76489->vol[0] = 0xf - data;
  34.139 +                        break;
  34.140 +                }
  34.141 +        }
  34.142 +        else
  34.143 +        {
  34.144 +                if ((sn76489->firstdat & 0x70) == 0x60)
  34.145 +                {
  34.146 +                        sn76489->shift = 0x4000;
  34.147 +                        if ((data & 3) != (sn76489->noise & 3)) 
  34.148 +                                sn76489->count[0] = 0;
  34.149 +                        sn76489->noise = data & 0xf;
  34.150 +                        if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1];
  34.151 +                        else                 sn76489->latch[0] = 0x400 << (data & 3);
  34.152 +                }
  34.153 +                else
  34.154 +                {
  34.155 +                        sn76489->freqhi[sn76489->lasttone] = data & 0x3F;
  34.156 +                        freq = sn76489->freqlo[sn76489->lasttone] | (sn76489->freqhi[sn76489->lasttone] << 4);
  34.157 +                        if ((sn76489->noise & 3) == 3 && sn76489->lasttone == 1)
  34.158 +                           sn76489->latch[0] = freq << 6;
  34.159 +                        sn76489->latch[sn76489->lasttone] = freq << 6;
  34.160 +                }
  34.161 +        }
  34.162 +}
  34.163 +
  34.164 +void *sn76489_init()
  34.165 +{
  34.166 +        sn76489_t *sn76489 = malloc(sizeof(sn76489_t));
  34.167 +        memset(sn76489, 0, sizeof(sn76489_t));
  34.168 +
  34.169 +        io_sethandler(0x00C0, 0x0001, NULL, NULL, NULL, sn76489_write, NULL, NULL, sn76489);
  34.170 +
  34.171 +        sound_add_handler(sn76489_poll, sn76489_get_buffer, sn76489);
  34.172 +
  34.173 +        sn76489->latch[0] = sn76489->latch[1] = sn76489->latch[2] = sn76489->latch[3] = 0x3FF << 6;
  34.174 +        sn76489->vol[0] = 0;
  34.175 +        sn76489->vol[1] = sn76489->vol[2] = sn76489->vol[3] = 8;
  34.176 +        sn76489->stat[0] = sn76489->stat[1] = sn76489->stat[2] = sn76489->stat[3] = 127;
  34.177 +        srand(time(NULL));
  34.178 +        sn76489->count[0] = 0;
  34.179 +        sn76489->count[1] = (rand()&0x3FF)<<6;
  34.180 +        sn76489->count[2] = (rand()&0x3FF)<<6;
  34.181 +        sn76489->count[3] = (rand()&0x3FF)<<6;
  34.182 +        sn76489->noise = 3;
  34.183 +        sn76489->shift = 0x4000;
  34.184 +
  34.185 +        return sn76489;
  34.186 +}
  34.187 +
  34.188 +void sn76489_close(void *p)
  34.189 +{
  34.190 +        sn76489_t *sn76489 = (sn76489_t *)p;
  34.191 +
  34.192 +        free(sn76489);        
  34.193 +}
  34.194 +
  34.195 +device_t sn76489_device =
  34.196 +{
  34.197 +        "TI SN74689 PSG",
  34.198 +        sn76489_init,
  34.199 +        sn76489_close,
  34.200 +        NULL
  34.201 +};
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/src/sound_sn76489.h	Mon May 27 19:56:33 2013 +0100
    35.3 @@ -0,0 +1,1 @@
    35.4 +extern device_t sn76489_device;
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/src/sound_speaker.c	Mon May 27 19:56:33 2013 +0100
    36.3 @@ -0,0 +1,42 @@
    36.4 +#include "ibm.h"
    36.5 +#include "sound.h"
    36.6 +#include "sound_speaker.h"
    36.7 +
    36.8 +static int16_t speaker_buffer[SOUNDBUFLEN];
    36.9 +
   36.10 +static int speaker_pos = 0;
   36.11 +
   36.12 +int wasgated = 0;
   36.13 +
   36.14 +static void speaker_poll(void *p)
   36.15 +{
   36.16 +        if (speaker_pos >= SOUNDBUFLEN) return;
   36.17 +
   36.18 +//        printf("SPeaker - %i %i %i %02X\n",speakval,gated,speakon,pit.m[2]);
   36.19 +        if (gated)
   36.20 +        {
   36.21 +                if (!pit.m[2] || pit.m[2]==4)
   36.22 +                   speaker_buffer[speaker_pos] = speakval;
   36.23 +                else 
   36.24 +                   speaker_buffer[speaker_pos] = speakon ? 0x1400 : 0;
   36.25 +        }
   36.26 +        else
   36.27 +           speaker_buffer[speaker_pos] = wasgated ? 0x1400 : 0;
   36.28 +        speaker_pos++;
   36.29 +        wasgated = 0;
   36.30 +}
   36.31 +
   36.32 +static void speaker_get_buffer(int16_t *buffer, int len, void *p)
   36.33 +{
   36.34 +        int c;
   36.35 +
   36.36 +        for (c = 0; c < len * 2; c++)
   36.37 +                buffer[c] += speaker_buffer[c >> 1];
   36.38 +
   36.39 +        speaker_pos = 0;
   36.40 +}
   36.41 +
   36.42 +void speaker_init()
   36.43 +{
   36.44 +        sound_add_handler(speaker_poll, speaker_get_buffer, NULL);
   36.45 +}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/src/sound_speaker.h	Mon May 27 19:56:33 2013 +0100
    37.3 @@ -0,0 +1,1 @@
    37.4 +void speaker_init();
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/src/sound_wss.c	Mon May 27 19:56:33 2013 +0100
    38.3 @@ -0,0 +1,307 @@
    38.4 +/*PCem v0.8 by Tom Walker
    38.5 +
    38.6 +  Windows Sound System compatible CODEC emulation (AD1848)*/
    38.7 +
    38.8 +#include <math.h>  
    38.9 +#include <stdlib.h>
   38.10 +#include "ibm.h"
   38.11 +
   38.12 +#include "device.h"
   38.13 +#include "dma.h"
   38.14 +#include "io.h"
   38.15 +#include "pic.h"
   38.16 +#include "sound_opl.h"
   38.17 +#include "sound_wss.h"
   38.18 +
   38.19 +/*530, 11, 3 - 530=23*/
   38.20 +/*530, 11, 1 - 530=22*/
   38.21 +/*530, 11, 0 - 530=21*/
   38.22 +/*530, 10, 1 - 530=1a*/
   38.23 +/*530, 9,  1 - 530=12*/
   38.24 +/*530, 7,  1 - 530=0a*/
   38.25 +/*604, 11, 1 - 530=22*/
   38.26 +/*e80, 11, 1 - 530=22*/
   38.27 +/*f40, 11, 1 - 530=22*/
   38.28 +
   38.29 +
   38.30 +static int wss_dma[4] = {0, 0, 1, 3};
   38.31 +static int wss_irq[8] = {5, 7, 9, 10, 11, 12, 14, 15}; /*W95 only uses 7-9, others may be wrong*/
   38.32 +static uint16_t wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40};
   38.33 +
   38.34 +typedef struct wss_t
   38.35 +{
   38.36 +        uint8_t config;
   38.37 +        
   38.38 +        int index;
   38.39 +        uint8_t regs[16];
   38.40 +        uint8_t status;
   38.41 +        
   38.42 +        int trd;
   38.43 +        int mce;
   38.44 +        
   38.45 +        int count;
   38.46 +        
   38.47 +        int16_t out_l, out_r;
   38.48 +        
   38.49 +        int interp_count, inc;
   38.50 +
   38.51 +        int enable;
   38.52 +
   38.53 +        int irq, dma;
   38.54 +        
   38.55 +        opl_t    opl;
   38.56 +
   38.57 +        int16_t opl_buffer[SOUNDBUFLEN * 2];
   38.58 +        int16_t pcm_buffer[2][SOUNDBUFLEN];
   38.59 +
   38.60 +        int pos;
   38.61 +} wss_t;
   38.62 +
   38.63 +static int wss_vols[64];
   38.64 +
   38.65 +uint8_t wss_read(uint16_t addr, void *p)
   38.66 +{
   38.67 +        wss_t *wss = (wss_t *)p;
   38.68 +        uint8_t temp = 0xff;
   38.69 +//        pclog("wss_read - addr %04X %04X(%08X):%08X ", addr, CS, cs, pc);
   38.70 +        switch (addr & 7)
   38.71 +        {
   38.72 +                case 0: case 1: case 2: case 3: /*Version*/
   38.73 +                temp = 4 | (wss->config & 0x40);
   38.74 +                break;
   38.75 +                
   38.76 +                case 4: /*Index*/
   38.77 +                temp = wss->index | wss->trd | wss->mce;
   38.78 +                break;
   38.79 +                case 5:
   38.80 +                temp = wss->regs[wss->index];
   38.81 +                break;
   38.82 +                case 6:
   38.83 +                temp = wss->status;
   38.84 +                break;
   38.85 +        }
   38.86 +//        pclog("return %02X\n", temp);
   38.87 +        return temp;
   38.88 +}
   38.89 +
   38.90 +void wss_write(uint16_t addr, uint8_t val, void *p)
   38.91 +{
   38.92 +        wss_t *wss = (wss_t *)p;
   38.93 +        double freq;
   38.94 +        pclog("wss_write - addr %04X val %02X  %04X(%08X):%08X\n", addr, val, CS, cs, pc);
   38.95 +        switch (addr & 7)
   38.96 +        {
   38.97 +                case 0: case 1: case 2: case 3: /*Config*/
   38.98 +                wss->config = val;
   38.99 +                wss->dma = wss_dma[val & 3];
  38.100 +                wss->irq = wss_irq[(val >> 3) & 7];
  38.101 +                break;
  38.102 +                
  38.103 +                case 4: /*Index*/
  38.104 +                wss->index = val & 0xf;
  38.105 +                wss->trd   = val & 0x20;
  38.106 +                wss->mce   = val & 0x40;
  38.107 +                break;
  38.108 +                case 5:
  38.109 +                switch (wss->index)
  38.110 +                {
  38.111 +                        case 8:
  38.112 +                        freq = (val & 1) ? 16934400 : 24576000;
  38.113 +                        switch ((val >> 1) & 7)
  38.114 +                        {
  38.115 +                                case 0: freq /= 3072; break;
  38.116 +                                case 1: freq /= 1536; break;
  38.117 +                                case 2: freq /= 896;  break;
  38.118 +                                case 3: freq /= 768;  break;
  38.119 +                                case 4: freq /= 448;  break;
  38.120 +                                case 5: freq /= 384;  break;
  38.121 +                                case 6: freq /= 512;  break;
  38.122 +                                case 7: freq /= 2560; break;
  38.123 +                        }
  38.124 +                        wss->inc = (int)((freq * 65536) / 48000);
  38.125 +                        break;
  38.126 +                        
  38.127 +                        case 9:
  38.128 +                        if (!wss->enable)
  38.129 +                                wss->interp_count = 0;
  38.130 +                                
  38.131 +                        wss->enable = ((val & 0x41) == 0x01);
  38.132 +                        break;
  38.133 +                                
  38.134 +                        case 12:
  38.135 +                        return;
  38.136 +                        
  38.137 +                        case 14:
  38.138 +                        wss->count = wss->regs[15] | (val << 8);
  38.139 +                        break;
  38.140 +                }
  38.141 +                wss->regs[wss->index] = val;
  38.142 +                break;
  38.143 +                case 6:
  38.144 +                wss->status &= 0xfe;
  38.145 +                break;              
  38.146 +        }
  38.147 +}
  38.148 +
  38.149 +static void wss_poll(void *p)
  38.150 +{
  38.151 +        wss_t *wss = (wss_t *)p;
  38.152 +        
  38.153 +        if (wss->pos >= SOUNDBUFLEN)
  38.154 +                return;
  38.155 +
  38.156 +        opl3_poll(&wss->opl, &wss->opl_buffer[wss->pos * 2], &wss->opl_buffer[(wss->pos * 2) + 1]);
  38.157 +        
  38.158 +        if (wss->enable)
  38.159 +        {
  38.160 +                int32_t temp;
  38.161 +                
  38.162 +                if (wss->regs[6] & 0x80)
  38.163 +                        wss->pcm_buffer[1][wss->pos] = 0;
  38.164 +                else
  38.165 +                        wss->pcm_buffer[1][wss->pos] = (wss->out_l * wss_vols[wss->regs[6] & 0x3f]) >> 16;
  38.166 +
  38.167 +                if (wss->regs[7] & 0x80)
  38.168 +                        wss->pcm_buffer[0][wss->pos] = 0;
  38.169 +                else
  38.170 +                        wss->pcm_buffer[0][wss->pos] = (wss->out_r * wss_vols[wss->regs[7] & 0x3f]) >> 16;
  38.171 +                
  38.172 +                wss->interp_count += wss->inc;
  38.173 +                if (wss->interp_count >= 0x10000)
  38.174 +                {
  38.175 +                        wss->interp_count -= 0x10000;
  38.176 +
  38.177 +                        if (wss->count < 0)
  38.178 +                        {               
  38.179 +                                wss->count = wss->regs[15] | (wss->regs[14] << 8);
  38.180 +                                if (!(wss->status & 0x01))
  38.181 +                                {
  38.182 +                                        wss->status |= 0x01;
  38.183 +                                        if (wss->regs[0xa] & 2)
  38.184 +                                                picint(1 << wss->irq);
  38.185 +                                }                                
  38.186 +                        }
  38.187 +
  38.188 +                        switch (wss->regs[8] & 0x70)
  38.189 +                        {
  38.190 +                                case 0x00: /*Mono, 8-bit PCM*/
  38.191 +                                wss->out_l = wss->out_r = (dma_channel_read(wss->dma) ^ 0x80) * 256;
  38.192 +                                break;
  38.193 +                                case 0x10: /*Stereo, 8-bit PCM*/
  38.194 +                                wss->out_l = (dma_channel_read(wss->dma) ^ 0x80)  * 256;
  38.195 +                                wss->out_r = (dma_channel_read(wss->dma) ^ 0x80)  * 256;
  38.196 +                                break;
  38.197 +                
  38.198 +                                case 0x40: /*Mono, 16-bit PCM*/
  38.199 +                                temp = dma_channel_read(wss->dma);
  38.200 +                                wss->out_l = wss->out_r = dma_channel_read(wss->dma) | (temp << 8);
  38.201 +                                break;
  38.202 +                                case 0x50: /*Stereo, 16-bit PCM*/
  38.203 +                                temp = dma_channel_read(wss->dma);
  38.204 +                                wss->out_l = dma_channel_read(wss->dma) | (temp << 8);
  38.205 +                                temp = dma_channel_read(wss->dma);
  38.206 +                                wss->out_r = dma_channel_read(wss->dma) | (temp << 8);
  38.207 +                                break;
  38.208 +                        }
  38.209 +        
  38.210 +                        wss->count--;
  38.211 +                }
  38.212 +//                pclog("wss_poll : enable %X %X  %X %X  %X %X\n", wss->pcm_buffer[0][wss->pos], wss->pcm_buffer[1][wss->pos], wss->out_l[0], wss->out_r[0], wss->out_l[1], wss->out_r[1]);
  38.213 +        }
  38.214 +        else
  38.215 +        {
  38.216 +                wss->pcm_buffer[0][wss->pos] = wss->pcm_buffer[1][wss->pos] = 0;
  38.217 +//                pclog("wss_poll : not enable\n");
  38.218 +        }
  38.219 +        wss->pos++;
  38.220 +}
  38.221 +
  38.222 +static void wss_get_buffer(int16_t *buffer, int len, void *p)
  38.223 +{
  38.224 +        wss_t *wss = (wss_t *)p;
  38.225 +        
  38.226 +        int c;
  38.227 +
  38.228 +        for (c = 0; c < len * 2; c++)
  38.229 +        {
  38.230 +                buffer[c] += wss->opl_buffer[c];
  38.231 +                buffer[c] += (wss->pcm_buffer[c & 1][c >> 1] / 2);
  38.232 +        }
  38.233 +
  38.234 +        wss->pos = 0;
  38.235 +}
  38.236 +
  38.237 +void *wss_init()
  38.238 +{
  38.239 +        wss_t *wss = malloc(sizeof(wss_t));
  38.240 +        int c;
  38.241 +        double attenuation;
  38.242 +
  38.243 +        memset(wss, 0, sizeof(wss_t));
  38.244 +
  38.245 +        opl3_init(&wss->opl);
  38.246 +        
  38.247 +        pclog("wss_init - %i %i\n", sbtype, SND_WSS);
  38.248 +
  38.249 +        wss->enable = 0;
  38.250 +                        
  38.251 +        wss->status = 0xcc;
  38.252 +        wss->index = wss->trd = 0;
  38.253 +        wss->mce = 0x40;
  38.254 +        
  38.255 +        wss->regs[0] = wss->regs[1] = 0;
  38.256 +        wss->regs[2] = wss->regs[3] = 0x80;
  38.257 +        wss->regs[4] = wss->regs[5] = 0x80;
  38.258 +        wss->regs[6] = wss->regs[7] = 0x80;
  38.259 +        wss->regs[8] = 0;
  38.260 +        wss->regs[9] = 0x08;
  38.261 +        wss->regs[10] = wss->regs[11] = 0;
  38.262 +        wss->regs[12] = 0xa;
  38.263 +        wss->regs[13] = 0;
  38.264 +        wss->regs[14] = wss->regs[15] = 0;
  38.265 +        
  38.266 +        wss->out_l = 0;
  38.267 +        wss->out_r = 0;
  38.268 +        wss->interp_count = 0;
  38.269 +        
  38.270 +        wss->irq = 7;
  38.271 +        wss->dma = 3;
  38.272 +
  38.273 +        io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL,  &wss->opl);
  38.274 +        io_sethandler(0x0530, 0x0008, wss_read,  NULL, NULL, wss_write,  NULL, NULL,  wss);
  38.275 +        
  38.276 +        sound_add_handler(wss_poll, wss_get_buffer, wss);
  38.277 +        
  38.278 +        for (c = 0; c < 64; c++)
  38.279 +        {
  38.280 +                attenuation = 0.0;
  38.281 +                if (c & 0x01) attenuation -= 1.5;
  38.282 +                if (c & 0x02) attenuation -= 3.0;
  38.283 +                if (c & 0x04) attenuation -= 6.0;
  38.284 +                if (c & 0x08) attenuation -= 12.0;
  38.285 +                if (c & 0x10) attenuation -= 24.0;
  38.286 +                if (c & 0x20) attenuation -= 48.0;
  38.287 +                
  38.288 +                attenuation = pow(10, attenuation / 10);
  38.289 +                
  38.290 +                wss_vols[c] = (int)(attenuation * 65536);
  38.291 +                pclog("wss_vols %i = %f %i\n", c, attenuation, wss_vols[c]);
  38.292 +        }
  38.293 +        
  38.294 +        return wss;
  38.295 +}
  38.296 +
  38.297 +void wss_close(void *p)
  38.298 +{
  38.299 +        wss_t *wss = (wss_t *)p;
  38.300 +        
  38.301 +        free(wss);
  38.302 +}
  38.303 +
  38.304 +device_t wss_device =
  38.305 +{
  38.306 +        "Windows Sound System",
  38.307 +        wss_init,
  38.308 +        wss_close,
  38.309 +        NULL
  38.310 +};
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/src/sound_wss.h	Mon May 27 19:56:33 2013 +0100
    39.3 @@ -0,0 +1,1 @@
    39.4 +extern device_t wss_device;
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/src/timer.c	Mon May 27 19:56:33 2013 +0100
    40.3 @@ -0,0 +1,94 @@
    40.4 +#include "ibm.h"
    40.5 +
    40.6 +/*#include "sound_opl.h"
    40.7 +#include "adlibgold.h"
    40.8 +#include "sound_pas16.h"
    40.9 +#include "sound_sb.h"
   40.10 +#include "sound_sb_dsp.h"
   40.11 +#include "sound_wss.h"*/
   40.12 +#include "timer.h"
   40.13 +
   40.14 +#define TIMERS_MAX 32
   40.15 +
   40.16 +int TIMER_USEC;
   40.17 +
   40.18 +static struct
   40.19 +{
   40.20 +	int present;
   40.21 +	void (*callback)(void *priv);
   40.22 +	void *priv;
   40.23 +	int *enable;
   40.24 +	int *count;
   40.25 +} timers[TIMERS_MAX];
   40.26 +
   40.27 +int timers_present = 0;
   40.28 +int timer_one = 1;
   40.29 +	
   40.30 +int timer_count = 0, timer_latch = 0;
   40.31 +
   40.32 +void timer_process()
   40.33 +{
   40.34 +	int c;
   40.35 +	
   40.36 +	/*Get actual elapsed time*/
   40.37 +	timer_latch -= timer_count;
   40.38 +
   40.39 +	for (c = 0; c < timers_present; c++)
   40.40 +	{
   40.41 +//		pclog("timer_process : %i enable %i %X\n", c, timers[c].enable, *timers[c].enable);
   40.42 +		if (*timers[c].enable)
   40.43 +		{
   40.44 +			*timers[c].count = *timers[c].count - (timer_latch << TIMER_SHIFT);
   40.45 +			if (*timers[c].count <= 0)
   40.46 +			{
   40.47 +				timers[c].callback(timers[c].priv);
   40.48 +			}
   40.49 +		}
   40.50 +	}
   40.51 +}
   40.52 +
   40.53 +void timer_update_outstanding()
   40.54 +{
   40.55 +	int c;
   40.56 +	timer_latch = 0x7fffffff;
   40.57 +	for (c = 0; c < timers_present; c++)
   40.58 +	{
   40.59 +		if (*timers[c].enable && *timers[c].count < timer_latch)
   40.60 +			timer_latch = *timers[c].count;
   40.61 +	}
   40.62 +	if (spktime < timer_latch)	timer_latch = spktime;
   40.63 +	//if (soundtime < timer_latch)	timer_latch = soundtime;
   40.64 +	//if (gustime   < timer_latch)	timer_latch = gustime;
   40.65 +	//if (gustime2  < timer_latch)	timer_latch = gustime2;
   40.66 +	//if (vidtime   < timer_latch)	timer_latch = vidtime;
   40.67 +	timer_count = timer_latch = (timer_latch + ((1 << TIMER_SHIFT) - 1)) >> TIMER_SHIFT;
   40.68 +}
   40.69 +
   40.70 +void timer_reset()
   40.71 +{
   40.72 +	pclog("timer_reset\n");
   40.73 +	timers_present = 0;
   40.74 +	timer_latch = timer_count = 0;
   40.75 +//	timer_process();
   40.76 +}
   40.77 +
   40.78 +int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv)
   40.79 +{
   40.80 +	if (timers_present < TIMERS_MAX)
   40.81 +	{
   40.82 +		pclog("timer_add : adding timer %i\n", timers_present);
   40.83 +		timers[timers_present].present = 1;
   40.84 +		timers[timers_present].callback = callback;
   40.85 +		timers[timers_present].priv = priv;
   40.86 +		timers[timers_present].count = count;
   40.87 +		timers[timers_present].enable = enable;
   40.88 +		timers_present++;
   40.89 +		return timers_present - 1;
   40.90 +	}
   40.91 +	return -1;
   40.92 +}
   40.93 +
   40.94 +void timer_set_callback(int timer, void (*callback)(void *priv))
   40.95 +{
   40.96 +	timers[timer].callback = callback;
   40.97 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/src/timer.h	Mon May 27 19:56:33 2013 +0100
    41.3 @@ -0,0 +1,25 @@
    41.4 +#define timer_clock(cycles) 				\
    41.5 +	do 						\
    41.6 +	{						\
    41.7 +		timer_count -= cycles;			\
    41.8 +		if (timer_count <= 0)			\
    41.9 +		{					\
   41.10 +			timer_process();		\
   41.11 +			timer_update_outstanding();	\
   41.12 +		}					\
   41.13 +	} while (0)
   41.14 +	
   41.15 +void timer_process();
   41.16 +void timer_update_outstanding();
   41.17 +void timer_reset();
   41.18 +int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv);
   41.19 +void timer_set_callback(int timer, void (*callback)(void *priv));
   41.20 +
   41.21 +#define TIMER_ALWAYS_ENABLED &timer_one
   41.22 +
   41.23 +extern int timer_count;
   41.24 +extern int timer_one;
   41.25 +
   41.26 +#define TIMER_SHIFT 6
   41.27 +
   41.28 +extern int TIMER_USEC;
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/src/um8669f.c	Mon May 27 19:56:33 2013 +0100
    42.3 @@ -0,0 +1,138 @@
    42.4 +/*um8669f :
    42.5 +        
    42.6 +  aa to 108 unlocks
    42.7 +  next 108 write is register select (Cx?)
    42.8 +  data read/write to 109
    42.9 +  55 to 108 locks
   42.10 +  
   42.11 +  
   42.12 +
   42.13 +
   42.14 +C0
   42.15 +bit 3 = LPT1 enable
   42.16 +bit 2 = COM2 enable
   42.17 +bit 1 = COM1 enable
   42.18 +bit 0 = FDC enable
   42.19 +
   42.20 +C1
   42.21 +bits 7-6 = LPT1 mode : 11 = ECP/EPP, 01 = EPP, 10 = SPP
   42.22 +bit 3 = clear when LPT1 = 278
   42.23 +
   42.24 +C3
   42.25 +bits 7-6 = LPT1 DMA mode : 11 = ECP/EPP DMA1, 10 = ECP/EPP DMA3, 01 = EPP/SPP, 00 = ECP
   42.26 +bits 5-4 = LPT1 addr : 10 = 278/IRQ5, 01 = 3BC/IRQ7, 00 = 378/IRQ7
   42.27 +
   42.28 +COM1 :
   42.29 +3f8, IRQ4 - C1 = BF, C3 = 00
   42.30 +2f8, IRQ3 - C1 = BF, C3 = 03
   42.31 +3e8, IRQ4 - C1 = BD, C3 = 00
   42.32 +2e8, IRQ3 - B1 = BD, C3 = 03
   42.33 +
   42.34 +COM2 :
   42.35 +3f8, IRQ4 - C1 = BF, C3 = 0C
   42.36 +2f8, IRQ3 - C1 = BF, C3 = 00
   42.37 +3e8, IRQ4 - C1 = BB, C3 = 0C
   42.38 +2e8, IRQ3 - C1 = BB, C3 = 00
   42.39 +
   42.40 +  */
   42.41 +
   42.42 +#include "ibm.h"
   42.43 +
   42.44 +#include "fdc.h"
   42.45 +#include "io.h"
   42.46 +#include "lpt.h"
   42.47 +#include "mouse_serial.h"
   42.48 +#include "serial.h"
   42.49 +#include "um8669f.h"
   42.50 +
   42.51 +static int um8669f_locked;
   42.52 +static int um8669f_curreg;
   42.53 +static uint8_t um8669f_regs[256];
   42.54 +
   42.55 +void um8669f_write(uint16_t port, uint8_t val, void *priv)
   42.56 +{
   42.57 +        int temp;
   42.58 +        if (um8669f_locked)
   42.59 +        {
   42.60 +                if (port == 0x108 && val == 0xaa)
   42.61 +                   um8669f_locked = 0;
   42.62 +        }
   42.63 +        else
   42.64 +        {
   42.65 +                if (port == 0x108)
   42.66 +                {
   42.67 +                        if (val == 0x55)
   42.68 +                           um8669f_locked = 1;
   42.69 +                        else
   42.70 +                           um8669f_curreg = val;
   42.71 +                }
   42.72 +                else
   42.73 +                {
   42.74 +                        um8669f_regs[um8669f_curreg] = val;
   42.75 +                        pclog("um8669f_write : reg %02X = %02X\n", um8669f_curreg, val);
   42.76 +
   42.77 +                        fdc_remove();
   42.78 +                        if (um8669f_regs[0xc0] & 1)
   42.79 +                           fdc_add();
   42.80 +                           
   42.81 +                        serial1_remove();
   42.82 +                        if (um8669f_regs[0xc0] & 2)
   42.83 +                        {
   42.84 +                                temp = um8669f_regs[0xc3] & 1; /*might be & 2*/
   42.85 +                                if (!(um8669f_regs[0xc1] & 2))
   42.86 +                                   temp |= 2;
   42.87 +                                switch (temp)
   42.88 +                                {
   42.89 +                                        case 0: serial1_init(0x3f8); break;
   42.90 +                                        case 1: serial1_init(0x2f8); break;
   42.91 +                                        case 2: serial1_init(0x3e8); break;
   42.92 +                                        case 3: serial1_init(0x2e8); break;
   42.93 +                                }
   42.94 +                        }
   42.95 +                        
   42.96 +                        serial2_remove();
   42.97 +                        if (um8669f_regs[0xc0] & 4)
   42.98 +                        {
   42.99 +                                temp = (um8669f_regs[0xc3] & 4) ? 0 : 1; /*might be & 8*/
  42.100 +                                if (!(um8669f_regs[0xc1] & 4))
  42.101 +                                   temp |= 2;
  42.102 +                                switch (temp)
  42.103 +                                {
  42.104 +                                        case 0: serial2_init(0x3f8); break;
  42.105 +                                        case 1: serial2_init(0x2f8); break;
  42.106 +                                        case 2: serial2_init(0x3e8); break;
  42.107 +                                        case 3: serial2_init(0x2e8); break;
  42.108 +                                }
  42.109 +                        }
  42.110 +                        
  42.111 +                        mouse_serial_init();
  42.112 +                        
  42.113 +                        lpt1_remove();
  42.114 +                        lpt2_remove();
  42.115 +                        temp = (um8669f_regs[0xc3] >> 4) & 3;
  42.116 +                        switch (temp)
  42.117 +                        {
  42.118 +                                case 0: lpt1_init(0x378); break;
  42.119 +                                case 1: lpt1_init(0x3bc); break;
  42.120 +                                case 2: lpt1_init(0x278); break;
  42.121 +                        }
  42.122 +                }
  42.123 +        }
  42.124 +}
  42.125 +
  42.126 +uint8_t um8669f_read(uint16_t port, void *priv)
  42.127 +{
  42.128 +        if (um8669f_locked)
  42.129 +           return 0xff;
  42.130 +        
  42.131 +        if (port == 0x108)
  42.132 +           return um8669f_curreg; /*???*/
  42.133 +        else
  42.134 +           return um8669f_regs[um8669f_curreg];
  42.135 +}
  42.136 +
  42.137 +void um8669f_init()
  42.138 +{
  42.139 +        io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL,  NULL);
  42.140 +        um8669f_locked = 1;
  42.141 +}
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/src/um8669f.h	Mon May 27 19:56:33 2013 +0100
    43.3 @@ -0,0 +1,1 @@
    43.4 +extern void um8669f_init();
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/src/vid_ati18800.c	Mon May 27 19:56:33 2013 +0100
    44.3 @@ -0,0 +1,142 @@
    44.4 +/*ATI 18800 emulation (VGA Edge-16)*/
    44.5 +#include "ibm.h"
    44.6 +#include "io.h"
    44.7 +#include "video.h"
    44.8 +#include "vid_ati_eeprom.h"
    44.9 +#include "vid_svga.h"
   44.10 +
   44.11 +static uint8_t ati_regs[256];
   44.12 +static int ati_index;
   44.13 +
   44.14 +void ati18800_out(uint16_t addr, uint8_t val, void *priv)
   44.15 +{
   44.16 +        uint8_t old;
   44.17 +        
   44.18 +        pclog("ati18800_out : %04X %02X  %04X:%04X\n", addr, val, CS,pc);
   44.19 +                
   44.20 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   44.21 +
   44.22 +        switch (addr)
   44.23 +        {
   44.24 +                case 0x1ce:
   44.25 +                ati_index = val;
   44.26 +                break;
   44.27 +                case 0x1cf:
   44.28 +                ati_regs[ati_index] = val;
   44.29 +                switch (ati_index)
   44.30 +                {
   44.31 +                        case 0xb2:
   44.32 +                        case 0xbe:
   44.33 +                        if (ati_regs[0xbe] & 8) /*Read/write bank mode*/
   44.34 +                        {
   44.35 +                                svgarbank = ((ati_regs[0xb2] >> 5) & 7) * 0x10000;
   44.36 +                                svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
   44.37 +                        }
   44.38 +                        else                    /*Single bank mode*/
   44.39 +                                svgarbank = svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
   44.40 +                        break;
   44.41 +                        case 0xb3:
   44.42 +                        ati_eeprom_write(val & 8, val & 2, val & 1);
   44.43 +                        break;
   44.44 +                }
   44.45 +                break;
   44.46 +                
   44.47 +                case 0x3D4:
   44.48 +                crtcreg = val & 0x3f;
   44.49 +                return;
   44.50 +                case 0x3D5:
   44.51 +                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
   44.52 +                old=crtc[crtcreg];
   44.53 +                crtc[crtcreg]=val;
   44.54 +                if (old!=val)
   44.55 +                {
   44.56 +                        if (crtcreg<0xE || crtcreg>0x10)
   44.57 +                        {
   44.58 +                                fullchange=changeframecount;
   44.59 +                                svga_recalctimings();
   44.60 +                        }
   44.61 +                }
   44.62 +                break;
   44.63 +        }
   44.64 +        svga_out(addr, val, NULL);
   44.65 +}
   44.66 +
   44.67 +uint8_t ati18800_in(uint16_t addr, void *priv)
   44.68 +{
   44.69 +        uint8_t temp;
   44.70 +
   44.71 +        if (addr != 0x3da) pclog("ati18800_in : %04X ", addr);
   44.72 +                
   44.73 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   44.74 +             
   44.75 +        switch (addr)
   44.76 +        {
   44.77 +                case 0x1ce:
   44.78 +                temp = ati_index;
   44.79 +                break;
   44.80 +                case 0x1cf:
   44.81 +                switch (ati_index)
   44.82 +                {
   44.83 +                        case 0xb7:
   44.84 +                        temp = ati_regs[ati_index] & ~8;
   44.85 +                        if (ati_eeprom_read())
   44.86 +                                temp |= 8;
   44.87 +                        break;
   44.88 +                        
   44.89 +                        default:
   44.90 +                        temp = ati_regs[ati_index];
   44.91 +                        break;
   44.92 +                }
   44.93 +                break;
   44.94 +
   44.95 +                case 0x3D4:
   44.96 +                temp = crtcreg;
   44.97 +                break;
   44.98 +                case 0x3D5:
   44.99 +                temp = crtc[crtcreg];
  44.100 +                break;
  44.101 +                default:
  44.102 +                temp = svga_in(addr, NULL);
  44.103 +                break;
  44.104 +        }
  44.105 +        if (addr != 0x3da) pclog("%02X  %04X:%04X\n", temp, CS,pc);
  44.106 +        return temp;
  44.107 +}
  44.108 +
  44.109 +int ati18800_init()
  44.110 +{
  44.111 +        svga_recalctimings_ex = NULL;
  44.112 +        svga_vram_limit = 1 << 19; /*512kb*/
  44.113 +        vrammask = 0x7ffff;
  44.114 +        svgawbank = svgarbank = 0;
  44.115 +        bpp = 8;
  44.116 +        svga_miscout = 1;
  44.117 +        
  44.118 +        io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL,  NULL);
  44.119 +        
  44.120 +        ati_eeprom_load("ati18800.nvr", 0);
  44.121 +        
  44.122 +        return svga_init();
  44.123 +}
  44.124 +
  44.125 +GFXCARD vid_ati18800 =
  44.126 +{
  44.127 +        ati18800_init,
  44.128 +        /*IO at 3Cx/3Dx*/
  44.129 +        ati18800_out,
  44.130 +        ati18800_in,
  44.131 +        /*IO at 3Ax/3Bx*/
  44.132 +        video_out_null,
  44.133 +        video_in_null,
  44.134 +
  44.135 +        svga_poll,
  44.136 +        svga_recalctimings,
  44.137 +
  44.138 +        svga_write,
  44.139 +        video_write_null,
  44.140 +        video_write_null,
  44.141 +
  44.142 +        svga_read,
  44.143 +        video_read_null,
  44.144 +        video_read_null
  44.145 +};
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/src/vid_ati28800.c	Mon May 27 19:56:33 2013 +0100
    45.3 @@ -0,0 +1,161 @@
    45.4 +/*ATI 28800 emulation (VGA Charger)*/
    45.5 +#include "ibm.h"
    45.6 +#include "io.h"
    45.7 +#include "video.h"
    45.8 +#include "vid_ati_eeprom.h"
    45.9 +#include "vid_svga.h"
   45.10 +#include "vid_svga_render.h"
   45.11 +
   45.12 +static uint8_t ati_regs[256];
   45.13 +static int ati_index;
   45.14 +
   45.15 +void ati28800_out(uint16_t addr, uint8_t val, void *priv)
   45.16 +{
   45.17 +        uint8_t old;
   45.18 +        
   45.19 +        pclog("ati28800_out : %04X %02X  %04X:%04X\n", addr, val, CS,pc);
   45.20 +                
   45.21 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   45.22 +
   45.23 +        switch (addr)
   45.24 +        {
   45.25 +                case 0x1ce:
   45.26 +                ati_index = val;
   45.27 +                break;
   45.28 +                case 0x1cf:
   45.29 +                ati_regs[ati_index] = val;
   45.30 +                switch (ati_index)
   45.31 +                {
   45.32 +                        case 0xb2:
   45.33 +                        case 0xbe:
   45.34 +                        if (ati_regs[0xbe] & 8) /*Read/write bank mode*/
   45.35 +                        {
   45.36 +                                svgarbank = ((ati_regs[0xb2] >> 5) & 7) * 0x10000;
   45.37 +                                svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
   45.38 +                        }
   45.39 +                        else                    /*Single bank mode*/
   45.40 +                                svgarbank = svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
   45.41 +                        break;
   45.42 +                        case 0xb3:
   45.43 +                        ati_eeprom_write(val & 8, val & 2, val & 1);
   45.44 +                        break;
   45.45 +                }
   45.46 +                break;
   45.47 +                
   45.48 +                case 0x3D4:
   45.49 +                crtcreg = val & 0x3f;
   45.50 +                return;
   45.51 +                case 0x3D5:
   45.52 +                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
   45.53 +                old=crtc[crtcreg];
   45.54 +                crtc[crtcreg]=val;
   45.55 +                if (old!=val)
   45.56 +                {
   45.57 +                        if (crtcreg<0xE || crtcreg>0x10)
   45.58 +                        {
   45.59 +                                fullchange=changeframecount;
   45.60 +                                svga_recalctimings();
   45.61 +                        }
   45.62 +                }
   45.63 +                break;
   45.64 +        }
   45.65 +        svga_out(addr, val, NULL);
   45.66 +}
   45.67 +
   45.68 +uint8_t ati28800_in(uint16_t addr, void *priv)
   45.69 +{
   45.70 +        uint8_t temp;
   45.71 +
   45.72 +        if (addr != 0x3da) pclog("ati28800_in : %04X ", addr);
   45.73 +                
   45.74 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   45.75 +             
   45.76 +        switch (addr)
   45.77 +        {
   45.78 +                case 0x1ce:
   45.79 +                temp = ati_index;
   45.80 +                break;
   45.81 +                case 0x1cf:
   45.82 +                switch (ati_index)
   45.83 +                {
   45.84 +                        case 0xb7:
   45.85 +                        temp = ati_regs[ati_index] & ~8;
   45.86 +                        if (ati_eeprom_read())
   45.87 +                                temp |= 8;
   45.88 +                        break;
   45.89 +                        
   45.90 +                        default:
   45.91 +                        temp = ati_regs[ati_index];
   45.92 +                        break;
   45.93 +                }
   45.94 +                break;
   45.95 +
   45.96 +                case 0x3c2:
   45.97 +                if ((vgapal[0].r + vgapal[0].g + vgapal[0].b) >= 0x50)
   45.98 +                        temp = 0;
   45.99 +                else
  45.100 +                        temp = 0x10;
  45.101 +                break;
  45.102 +                case 0x3D4:
  45.103 +                temp = crtcreg;
  45.104 +                break;
  45.105 +                case 0x3D5:
  45.106 +                temp = crtc[crtcreg];
  45.107 +                break;
  45.108 +                default:
  45.109 +                temp = svga_in(addr, NULL);
  45.110 +                break;
  45.111 +        }
  45.112 +        if (addr != 0x3da) pclog("%02X  %04X:%04X\n", temp, CS,pc);
  45.113 +        return temp;
  45.114 +}
  45.115 +
  45.116 +void ati28800_recalctimings()
  45.117 +{
  45.118 +        pclog("ati28800_recalctimings\n");
  45.119 +        if (!scrblank && (ati_regs[0xb0] & 0x20)) /*Extended 256 colour modes*/
  45.120 +        {
  45.121 +                pclog("8bpp_highres\n");
  45.122 +                svga_render = svga_render_8bpp_highres;
  45.123 +                svga_rowoffset <<= 1;
  45.124 +                svga_ma <<= 1;
  45.125 +        }
  45.126 +}               
  45.127 +
  45.128 +int ati28800_init()
  45.129 +{
  45.130 +        svga_recalctimings_ex = ati28800_recalctimings;
  45.131 +        svga_vram_limit = 1 << 19; /*512kb*/
  45.132 +        vrammask = 0x7ffff;
  45.133 +        svgawbank = svgarbank = 0;
  45.134 +        bpp = 8;
  45.135 +        svga_miscout = 1;
  45.136 +        
  45.137 +        io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL,  NULL);
  45.138 +        
  45.139 +        ati_eeprom_load("ati28800.nvr", 0);
  45.140 +        
  45.141 +        return svga_init();
  45.142 +}
  45.143 +
  45.144 +GFXCARD vid_ati28800 =
  45.145 +{
  45.146 +        ati28800_init,
  45.147 +        /*IO at 3Cx/3Dx*/
  45.148 +        ati28800_out,
  45.149 +        ati28800_in,
  45.150 +        /*IO at 3Ax/3Bx*/
  45.151 +        video_out_null,
  45.152 +        video_in_null,
  45.153 +
  45.154 +        svga_poll,
  45.155 +        svga_recalctimings,
  45.156 +
  45.157 +        svga_write,
  45.158 +        video_write_null,
  45.159 +        video_write_null,
  45.160 +
  45.161 +        svga_read,
  45.162 +        video_read_null,
  45.163 +        video_read_null
  45.164 +};
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/src/vid_ati68860_ramdac.c	Mon May 27 19:56:33 2013 +0100
    46.3 @@ -0,0 +1,83 @@
    46.4 +/*ATI 68860 RAMDAC emulation (for Mach64)*/
    46.5 +/*
    46.6 +ATI 68860/68880 Truecolor DACs:
    46.7 +REG08 (R/W):
    46.8 +bit 0-?  Always 2 ??
    46.9 +
   46.10 +REG0A (R/W):
   46.11 +bit 0-?  Always 1Dh ??
   46.12 +
   46.13 +REG0B (R/W):  (GMR ?)
   46.14 +bit 0-7  Mode. 82h: 4bpp, 83h: 8bpp, A0h: 15bpp, A1h: 16bpp, C0h: 24bpp,
   46.15 +          E3h: 32bpp  (80h for VGA modes ?)
   46.16 +
   46.17 +REG0C (R/W):  Device Setup Register A
   46.18 +bit   0  Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT
   46.19 +    2-3  Depends on Video memory (= VRAM width ?) . 1: Less than 1Mb, 2: 1Mb,
   46.20 +           3: > 1Mb
   46.21 +    5-6  Always set ?
   46.22 +      7  If set can remove "snow" in some cases (A860_Delay_L ?) ??
   46.23 +*/
   46.24 +#include "ibm.h"
   46.25 +#include "video.h"
   46.26 +#include "vid_svga.h"
   46.27 +#include "vid_ati68860_ramdac.h"
   46.28 +
   46.29 +static uint8_t ramdac_regs[16];
   46.30 +void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv)
   46.31 +{
   46.32 +//        pclog("ati68860_out : addr %04X val %02X  %04X:%04X\n", addr, val, CS,pc);
   46.33 +        switch (addr)
   46.34 +        {
   46.35 +                case 0: 
   46.36 +                svga_out(0x3c8, val, NULL); 
   46.37 +                break;
   46.38 +                case 1: 
   46.39 +                svga_out(0x3c9, val, NULL); 
   46.40 +                break;
   46.41 +                case 2: 
   46.42 +                svga_out(0x3c6, val, NULL); 
   46.43 +                break;
   46.44 +                case 3: 
   46.45 +                svga_out(0x3c7, val, NULL); 
   46.46 +                break;
   46.47 +                default:
   46.48 +                ramdac_regs[addr & 0xf] = val;
   46.49 +                break;
   46.50 +        }
   46.51 +}
   46.52 +
   46.53 +uint8_t ati68860_ramdac_in(uint16_t addr, void *priv)
   46.54 +{
   46.55 +        uint8_t ret = 0;
   46.56 +        switch (addr)
   46.57 +        {
   46.58 +                case 0:
   46.59 +                ret = svga_in(0x3c8, NULL);
   46.60 +                break;
   46.61 +                case 1:
   46.62 +                ret = svga_in(0x3c9, NULL);
   46.63 +                break;
   46.64 +                case 2:
   46.65 +                ret = svga_in(0x3c6, NULL);
   46.66 +                break;
   46.67 +                case 3:
   46.68 +                ret = svga_in(0x3c7, NULL);
   46.69 +                break;
   46.70 +                case 4: case 8:
   46.71 +                ret = 2; 
   46.72 +                break;
   46.73 +                case 6: case 0xa:
   46.74 +                ret = 0x1d;
   46.75 +                break;
   46.76 +                case 0xf:
   46.77 +                ret = 0xd0;
   46.78 +                break;
   46.79 +                
   46.80 +                default:
   46.81 +                ret = ramdac_regs[addr & 0xf];
   46.82 +                break;
   46.83 +        }
   46.84 +//        pclog("ati68860_in  : addr %04X ret %02X  %04X:%04X\n", addr, ret, CS,pc);
   46.85 +        return ret;
   46.86 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/src/vid_ati68860_ramdac.h	Mon May 27 19:56:33 2013 +0100
    47.3 @@ -0,0 +1,2 @@
    47.4 +void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv);
    47.5 +uint8_t ati68860_ramdac_in(uint16_t addr, void *priv);
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/src/vid_ati_eeprom.c	Mon May 27 19:56:33 2013 +0100
    48.3 @@ -0,0 +1,229 @@
    48.4 +#include "ibm.h"
    48.5 +#include "vid_ati_eeprom.h"
    48.6 +
    48.7 +static uint16_t eeprom[256];
    48.8 +enum
    48.9 +{
   48.10 +        EEPROM_IDLE,
   48.11 +        EEPROM_WAIT,
   48.12 +        EEPROM_OPCODE,
   48.13 +        EEPROM_INPUT,
   48.14 +        EEPROM_OUTPUT
   48.15 +};
   48.16 +
   48.17 +enum
   48.18 +{
   48.19 +        EEPROM_OP_EW    = 4,
   48.20 +        EEPROM_OP_WRITE = 5,
   48.21 +        EEPROM_OP_READ  = 6,
   48.22 +        EEPROM_OP_ERASE = 7,
   48.23 +        
   48.24 +        EEPROM_OP_WRALMAIN = -1
   48.25 +};
   48.26 +
   48.27 +enum
   48.28 +{
   48.29 +        EEPROM_OP_EWDS = 0,
   48.30 +        EEPROM_OP_WRAL = 1,
   48.31 +        EEPROM_OP_ERAL = 2,
   48.32 +        EEPROM_OP_EWEN = 3
   48.33 +};
   48.34 +
   48.35 +static int oldclk, oldena;
   48.36 +static int eeprom_opcode, eeprom_state, eeprom_count, eeprom_out;
   48.37 +static int eeprom_wp;
   48.38 +static uint32_t eeprom_dat;
   48.39 +static int eeprom_type;
   48.40 +
   48.41 +static char eeprom_fn[256] = {0};
   48.42 +
   48.43 +void ati_eeprom_load(char *fn, int type)
   48.44 +{
   48.45 +        FILE *f;
   48.46 +        eeprom_type = type;
   48.47 +        strcpy(eeprom_fn, fn);
   48.48 +        f = romfopen(eeprom_fn, "rb");
   48.49 +        if (!f)
   48.50 +        {
   48.51 +                memset(eeprom, 0, type ? 512 : 128);
   48.52 +                return;
   48.53 +        }
   48.54 +        fread(eeprom, 1, type ? 512 : 128, f);
   48.55 +        fclose(f);
   48.56 +}
   48.57 +
   48.58 +void ati_eeprom_save()
   48.59 +{
   48.60 +        FILE *f = romfopen(eeprom_fn, "wb");
   48.61 +        if (!f) return;
   48.62 +        fwrite(eeprom, 1, eeprom_type ? 512 : 128, f);
   48.63 +        fclose(f);
   48.64 +}
   48.65 +
   48.66 +void ati_eeprom_write(int ena, int clk, int dat)
   48.67 +{
   48.68 +        int c;
   48.69 +        pclog("EEPROM write %i %i %i\n", ena, clk, dat);
   48.70 +        if (!ena)
   48.71 +        {
   48.72 +                eeprom_out = 1;
   48.73 +        }
   48.74 +        if (clk && !oldclk)
   48.75 +        {
   48.76 +                if (ena && !oldena)
   48.77 +                {
   48.78 +                        eeprom_state = EEPROM_WAIT;
   48.79 +                        eeprom_opcode = 0;
   48.80 +                        eeprom_count = 3;
   48.81 +                        eeprom_out = 1;
   48.82 +                }
   48.83 +                else if (ena)
   48.84 +                {
   48.85 +                        pclog("EEPROM receive %i %i %i\n", ena, clk, dat);
   48.86 +                        switch (eeprom_state)
   48.87 +                        {
   48.88 +                                case EEPROM_WAIT:
   48.89 +                                if (!dat)
   48.90 +                                        break;
   48.91 +                                eeprom_state = EEPROM_OPCODE;
   48.92 +                                /* fall through */
   48.93 +                                case EEPROM_OPCODE:
   48.94 +                                eeprom_opcode = (eeprom_opcode << 1) | (dat ? 1 : 0);
   48.95 +                                eeprom_count--;
   48.96 +                                if (!eeprom_count)
   48.97 +                                {
   48.98 +                                        pclog("EEPROM opcode - %i\n", eeprom_opcode);
   48.99 +                                        switch (eeprom_opcode)
  48.100 +                                        {
  48.101 +                                                case EEPROM_OP_WRITE:
  48.102 +                                                eeprom_count = eeprom_type ? 24 : 22;
  48.103 +                                                eeprom_state = EEPROM_INPUT;
  48.104 +                                                eeprom_dat = 0;
  48.105 +                                                break;
  48.106 +                                                case EEPROM_OP_READ:
  48.107 +                                                eeprom_count = eeprom_type ? 8 : 6;
  48.108 +                                                eeprom_state = EEPROM_INPUT;
  48.109 +                                                eeprom_dat = 0;
  48.110 +                                                break;
  48.111 +                                                case EEPROM_OP_EW:
  48.112 +                                                eeprom_count = 2;
  48.113 +                                                eeprom_state = EEPROM_INPUT;
  48.114 +                                                eeprom_dat = 0;
  48.115 +                                                break;
  48.116 +                                                case EEPROM_OP_ERASE:
  48.117 +                                                eeprom_count = eeprom_type ? 8 : 6;
  48.118 +                                                eeprom_state = EEPROM_INPUT;
  48.119 +                                                eeprom_dat = 0;
  48.120 +                                                break;
  48.121 +                                        }
  48.122 +                                }
  48.123 +                                break;
  48.124 +                                
  48.125 +                                case EEPROM_INPUT:
  48.126 +                                eeprom_dat = (eeprom_dat << 1) | (dat ? 1 : 0);
  48.127 +                                eeprom_count--;
  48.128 +                                if (!eeprom_count)
  48.129 +                                {
  48.130 +                                        pclog("EEPROM dat - %02X\n", eeprom_dat);
  48.131 +                                        switch (eeprom_opcode)
  48.132 +                                        {
  48.133 +                                                case EEPROM_OP_WRITE:
  48.134 +                                                pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom_dat >> 16) & (eeprom_type ? 255 : 63), eeprom_dat & 0xffff);
  48.135 +                                                if (!eeprom_wp)
  48.136 +                                                {
  48.137 +                                                        eeprom[(eeprom_dat >> 16) & (eeprom_type ? 255 : 63)] = eeprom_dat & 0xffff;
  48.138 +                                                        ati_eeprom_save();
  48.139 +                                                }
  48.140 +                                                eeprom_state = EEPROM_IDLE;
  48.141 +                                                eeprom_out = 1;
  48.142 +                                                break;
  48.143 +
  48.144 +                                                case EEPROM_OP_READ:
  48.145 +                                                eeprom_count = 17;
  48.146 +                                                eeprom_state = EEPROM_OUTPUT;
  48.147 +                                                eeprom_dat = eeprom[eeprom_dat];
  48.148 +                                                pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom_dat);
  48.149 +                                                break;
  48.150 +                                                case EEPROM_OP_EW:
  48.151 +                                                pclog("EEPROM_OP_EW %i\n", eeprom_dat);
  48.152 +                                                switch (eeprom_dat)
  48.153 +                                                {
  48.154 +                                                        case EEPROM_OP_EWDS:
  48.155 +                                                        eeprom_wp = 1;
  48.156 +                                                        break;
  48.157 +                                                        case EEPROM_OP_WRAL:
  48.158 +                                                        opcode = EEPROM_OP_WRALMAIN;
  48.159 +                                                        eeprom_count = 20;
  48.160 +                                                        break;
  48.161 +                                                        case EEPROM_OP_ERAL:
  48.162 +                                                        if (!eeprom_wp)
  48.163 +                                                        {
  48.164 +                                                                memset(eeprom, 0xff, 128);
  48.165 +                                                                ati_eeprom_save();
  48.166 +                                                        }
  48.167 +                                                        break;
  48.168 +                                                        case EEPROM_OP_EWEN:
  48.169 +                                                        eeprom_wp = 0;
  48.170 +                                                        break;
  48.171 +                                                }
  48.172 +                                                eeprom_state = EEPROM_IDLE;
  48.173 +                                                eeprom_out = 1;
  48.174 +                                                break;
  48.175 +
  48.176 +                                                case EEPROM_OP_ERASE:
  48.177 +                                                pclog("EEPROM_OP_ERASE %i\n", eeprom_dat);
  48.178 +                                                if (!eeprom_wp)
  48.179 +                                                {
  48.180 +                                                        eeprom[eeprom_dat] = 0xffff;
  48.181 +                                                        ati_eeprom_save();
  48.182 +                                                }
  48.183 +                                                eeprom_state = EEPROM_IDLE;
  48.184 +                                                eeprom_out = 1;
  48.185 +                                                break;
  48.186 +
  48.187 +                                                case EEPROM_OP_WRALMAIN:
  48.188 +                                                pclog("EEPROM_OP_WRAL %04X\n", eeprom_dat);
  48.189 +                                                if (!eeprom_wp)
  48.190 +                                                {
  48.191 +                                                        for (c = 0; c < 256; c++)
  48.192 +                                                                eeprom[c] = eeprom_dat;
  48.193 +                                                        ati_eeprom_save();
  48.194 +                                                }
  48.195 +                                                eeprom_state = EEPROM_IDLE;
  48.196 +                                                eeprom_out = 1;
  48.197 +                                                break;
  48.198 +                                        }
  48.199 +                                }
  48.200 +                                break;
  48.201 +                        }
  48.202 +                }                
  48.203 +                oldena = ena;
  48.204 +        }
  48.205 +        else if (!clk && oldclk)
  48.206 +        {
  48.207 +                if (ena)
  48.208 +                {
  48.209 +                        switch (eeprom_state)
  48.210 +                        {
  48.211 +                                case EEPROM_OUTPUT:
  48.212 +                                eeprom_out = (eeprom_dat & 0x10000) ? 1 : 0;
  48.213 +                                eeprom_dat <<= 1;
  48.214 +                                pclog("EEPROM_OUTPUT - data %i\n", eeprom_out);                                
  48.215 +                                eeprom_count--;
  48.216 +                                if (!eeprom_count)
  48.217 +                                {
  48.218 +                                        pclog("EEPROM_OUTPUT complete\n");
  48.219 +                                        eeprom_state = EEPROM_IDLE;
  48.220 +                                }
  48.221 +                                break;
  48.222 +                        }
  48.223 +                }
  48.224 +        }
  48.225 +        oldclk = clk;
  48.226 +}
  48.227 +
  48.228 +int ati_eeprom_read()
  48.229 +{
  48.230 +        return eeprom_out;
  48.231 +}
  48.232 +
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/src/vid_ati_eeprom.h	Mon May 27 19:56:33 2013 +0100
    49.3 @@ -0,0 +1,3 @@
    49.4 +void ati_eeprom_load(char *fn, int type);
    49.5 +void ati_eeprom_write(int ena, int clk, int dat);
    49.6 +int ati_eeprom_read();
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/src/vid_ati_mach64.c	Mon May 27 19:56:33 2013 +0100
    50.3 @@ -0,0 +1,1767 @@
    50.4 +/*ATI Mach64 emulation*/
    50.5 +#include "ibm.h"
    50.6 +#include "io.h"
    50.7 +#include "mem.h"
    50.8 +#include "video.h"
    50.9 +#include "vid_svga.h"
   50.10 +#include "vid_ati68860_ramdac.h"
   50.11 +#include "vid_ati_eeprom.h"
   50.12 +#include "vid_ics2595.h"
   50.13 +#include "vid_svga_render.h"
   50.14 +
   50.15 +//#define MACH64_DEBUG
   50.16 +static int mach64_bank_r[2] = {0, 0};
   50.17 +static int mach64_bank_w[2] = {0, 0};
   50.18 +void mach64_write(uint32_t addr, uint8_t val, void *priv);
   50.19 +uint8_t mach64_read(uint32_t addr, void *priv);
   50.20 +
   50.21 +static uint8_t ati_regs[256];
   50.22 +static int ati_index;
   50.23 +
   50.24 +struct
   50.25 +{
   50.26 +        uint32_t config_cntl;
   50.27 +
   50.28 +        uint32_t context_load_cntl;
   50.29 +        uint32_t context_mask;
   50.30 +                
   50.31 +        uint32_t crtc_gen_cntl;
   50.32 +        uint8_t  crtc_int_cntl;
   50.33 +        uint32_t crtc_h_total_disp;
   50.34 +        uint32_t crtc_v_sync_strt_wid;
   50.35 +        uint32_t crtc_v_total_disp;
   50.36 +        uint32_t crtc_off_pitch;
   50.37 +
   50.38 +        uint32_t clock_cntl;
   50.39 +
   50.40 +        uint32_t cur_horz_vert_off;        
   50.41 +        uint32_t cur_horz_vert_posn;
   50.42 +        uint32_t cur_offset;
   50.43 +        
   50.44 +        uint32_t dac_cntl;
   50.45 +        
   50.46 +        uint32_t dp_bkgd_clr;
   50.47 +        uint32_t dp_frgd_clr;
   50.48 +        uint32_t dp_mix;
   50.49 +        uint32_t dp_pix_width;
   50.50 +        uint32_t dp_src;
   50.51 +        
   50.52 +        uint32_t dst_bres_lnth;
   50.53 +        uint32_t dst_bres_dec;
   50.54 +        uint32_t dst_bres_err;
   50.55 +        uint32_t dst_bres_inc;
   50.56 +        
   50.57 +        uint32_t dst_cntl;
   50.58 +        uint32_t dst_height_width;
   50.59 +        uint32_t dst_off_pitch;
   50.60 +        uint32_t dst_y_x;
   50.61 +
   50.62 +        uint32_t gen_test_cntl;
   50.63 +        
   50.64 +        uint32_t gui_traj_cntl;
   50.65 +                
   50.66 +        uint32_t mem_cntl;
   50.67 +
   50.68 +        uint32_t pat_cntl;        
   50.69 +        uint32_t pat_reg0, pat_reg1;
   50.70 +        
   50.71 +        uint32_t sc_left_right, sc_top_bottom;
   50.72 +        
   50.73 +        uint32_t scratch_reg0, scratch_reg1;
   50.74 +
   50.75 +        uint32_t src_cntl;        
   50.76 +        uint32_t src_off_pitch;
   50.77 +        uint32_t src_y_x;
   50.78 +
   50.79 +        struct
   50.80 +        {
   50.81 +                int op;
   50.82 +                
   50.83 +                int dst_x, dst_y;
   50.84 +                int dst_x_start;
   50.85 +                int src_x, src_y;
   50.86 +                int src_x_start;
   50.87 +                int xinc, yinc;
   50.88 +                int x_count, y_count;
   50.89 +                uint32_t src_offset, src_pitch;
   50.90 +                uint32_t dst_offset, dst_pitch;                
   50.91 +                int mix_bg, mix_fg;
   50.92 +                int source_bg, source_fg, source_mix;
   50.93 +                int source_host;                
   50.94 +                int dst_width, dst_height;
   50.95 +                int busy;
   50.96 +                int pattern[8][8];
   50.97 +                int sc_left, sc_right, sc_top, sc_bottom;
   50.98 +                int dst_pix_width, src_pix_width, host_pix_width;
   50.99 +                int dst_size, src_size;
  50.100 +
  50.101 +                uint32_t dp_bkgd_clr;
  50.102 +                uint32_t dp_frgd_clr;
  50.103 +                
  50.104 +                int err;
  50.105 +        } accel;
  50.106 +} mach64;
  50.107 +
  50.108 +enum
  50.109 +{
  50.110 +        SRC_BG      = 0,
  50.111 +        SRC_FG      = 1,
  50.112 +        SRC_HOST    = 2,
  50.113 +        SRC_BLITSRC = 3,
  50.114 +        SRC_PAT     = 4
  50.115 +};
  50.116 +
  50.117 +enum
  50.118 +{
  50.119 +        MONO_SRC_1       = 0,
  50.120 +        MONO_SRC_PAT     = 1,
  50.121 +        MONO_SRC_HOST    = 2,
  50.122 +        MONO_SRC_BLITSRC = 3
  50.123 +};
  50.124 +
  50.125 +enum
  50.126 +{
  50.127 +        BPP_1  = 0,
  50.128 +        BPP_4  = 1,
  50.129 +        BPP_8  = 2,
  50.130 +        BPP_15 = 3,
  50.131 +        BPP_16 = 4,
  50.132 +        BPP_32 = 5
  50.133 +};
  50.134 +
  50.135 +enum
  50.136 +{
  50.137 +        OP_RECT,
  50.138 +        OP_LINE
  50.139 +};
  50.140 +
  50.141 +static int mach64_width[6] = {0, 0, 0, 1, 1, 2};
  50.142 +
  50.143 +enum
  50.144 +{
  50.145 +        DST_24_ROT_EN = 0x80
  50.146 +};
  50.147 +
  50.148 +uint8_t  mach64_ext_readb(uint32_t addr, void *priv);
  50.149 +uint16_t mach64_ext_readw(uint32_t addr, void *priv);
  50.150 +uint32_t mach64_ext_readl(uint32_t addr, void *priv);
  50.151 +void     mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv);
  50.152 +void     mach64_ext_writew(uint32_t addr, uint16_t val, void *priv);
  50.153 +void     mach64_ext_writel(uint32_t addr, uint32_t val, void *priv);
  50.154 +
  50.155 +void mach64_out(uint16_t addr, uint8_t val, void *priv)
  50.156 +{
  50.157 +        uint8_t old;
  50.158 +        
  50.159 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  50.160 +
  50.161 +//        pclog("mach64 out %04X %02X\n", addr, val);
  50.162 +                
  50.163 +        switch (addr)
  50.164 +        {
  50.165 +                case 0x1ce:
  50.166 +                ati_index = val;
  50.167 +                break;
  50.168 +                case 0x1cf:
  50.169 +                ati_regs[ati_index] = val;
  50.170 +                break;
  50.171 +                
  50.172 +                case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  50.173 +                ati68860_ramdac_out((addr & 3) | ((mach64.dac_cntl & 3) << 2), val, NULL);
  50.174 +                return;
  50.175 +                
  50.176 +                case 0x3cf:
  50.177 +                if (gdcaddr == 6)
  50.178 +                {
  50.179 +                        if ((gdcreg[6] & 0xc) != (val & 0xc))
  50.180 +                        {
  50.181 +                                mem_removehandler(0xa0000, 0x20000, mach64_read, NULL, NULL, mach64_write, NULL, NULL,  NULL);
  50.182 +                                mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  50.183 +                                mem_removehandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel,  NULL);
  50.184 +                                pclog("Write mapping %02X\n", val);
  50.185 +                                switch (val&0xC)
  50.186 +                                {
  50.187 +                                        case 0x0: /*128k at A0000*/
  50.188 +                                        mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL,  NULL);
  50.189 +                                        mem_sethandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel,  NULL);
  50.190 +                                        break;
  50.191 +                                        case 0x4: /*64k at A0000*/
  50.192 +                                        mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL,  NULL);
  50.193 +                                        break;
  50.194 +                                        case 0x8: /*32k at B0000*/
  50.195 +                                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  50.196 +                                        break;
  50.197 +                                        case 0xC: /*32k at B8000*/
  50.198 +                                        mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  50.199 +                                        break;
  50.200 +                                }
  50.201 +                        }
  50.202 +                        gdcreg[6] = val;
  50.203 +                        return;
  50.204 +                }
  50.205 +                break;
  50.206 +                
  50.207 +                case 0x3D4:
  50.208 +                crtcreg = val & 0x3f;
  50.209 +                return;
  50.210 +                case 0x3D5:
  50.211 +                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
  50.212 +                old=crtc[crtcreg];
  50.213 +                crtc[crtcreg]=val;
  50.214 +
  50.215 +                if (old!=val)
  50.216 +                {
  50.217 +                        if (crtcreg<0xE || crtcreg>0x10)
  50.218 +                        {
  50.219 +                                fullchange=changeframecount;
  50.220 +                                svga_recalctimings();
  50.221 +                        }
  50.222 +                }
  50.223 +                break;
  50.224 +        }
  50.225 +        svga_out(addr, val, NULL);
  50.226 +}
  50.227 +
  50.228 +uint8_t mach64_in(uint16_t addr, void *priv)
  50.229 +{
  50.230 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  50.231 +        
  50.232 +//        pclog("IN mach64 %04X\n", addr);
  50.233 +        
  50.234 +        switch (addr)
  50.235 +        {
  50.236 +                case 0x1ce:
  50.237 +                return ati_index;
  50.238 +                case 0x1cf:
  50.239 +                return ati_regs[ati_index];
  50.240 +
  50.241 +                case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  50.242 +                return ati68860_ramdac_in((addr & 3) | ((mach64.dac_cntl & 3) << 2), NULL);
  50.243 +                
  50.244 +                case 0x3D4:
  50.245 +                return crtcreg;
  50.246 +                case 0x3D5:
  50.247 +                return crtc[crtcreg];
  50.248 +        }
  50.249 +        return svga_in(addr, NULL);
  50.250 +}
  50.251 +
  50.252 +void mach64_recalctimings()
  50.253 +{
  50.254 +        if (((mach64.crtc_gen_cntl >> 24) & 3) == 3)
  50.255 +        {
  50.256 +                svga_vtotal = (mach64.crtc_v_total_disp & 2047) + 1;
  50.257 +                svga_dispend = ((mach64.crtc_v_total_disp >> 16) & 2047) + 1;
  50.258 +                svga_htotal = (mach64.crtc_h_total_disp & 255) + 1;
  50.259 +                svga_hdisp_time = svga_hdisp = ((mach64.crtc_h_total_disp >> 16) & 255) + 1;
  50.260 +                svga_vsyncstart = (mach64.crtc_v_sync_strt_wid & 2047) + 1;
  50.261 +                svga_rowoffset = (mach64.crtc_off_pitch >> 22);
  50.262 +                svga_clock = cpuclock / ics2595_output_clock;
  50.263 +                svga_ma = (mach64.crtc_off_pitch & 0x1fffff) * 2;
  50.264 +                svga_linedbl = svga_rowcount = 0;
  50.265 +//                svga_htotal <<= 1;
  50.266 +//                svga_hdisp <<= 1;
  50.267 +                svga_rowoffset <<= 1;
  50.268 +                switch ((mach64.crtc_gen_cntl >> 8) & 7)
  50.269 +                {
  50.270 +                        case 1: 
  50.271 +                        svga_render = svga_render_4bpp_highres; 
  50.272 +                        svga_hdisp *= 8;
  50.273 +                        break;
  50.274 +                        case 2: 
  50.275 +                        svga_render = svga_render_8bpp_highres; 
  50.276 +                        svga_hdisp *= 8;
  50.277 +                        svga_rowoffset /= 2;
  50.278 +                        break;
  50.279 +                        case 3: 
  50.280 +                        svga_render = svga_render_15bpp_highres; 
  50.281 +                        svga_hdisp *= 8;
  50.282 +                        //svga_rowoffset *= 2;
  50.283 +                        break;
  50.284 +                        case 4: 
  50.285 +                        svga_render = svga_render_16bpp_highres; 
  50.286 +                        svga_hdisp *= 8;
  50.287 +                        //svga_rowoffset *= 2;
  50.288 +                        break;
  50.289 +                        case 5: 
  50.290 +                        svga_render = svga_render_24bpp_highres; 
  50.291 +                        svga_hdisp *= 8;
  50.292 +                        svga_rowoffset = (svga_rowoffset * 3) / 2;
  50.293 +                        break;
  50.294 +                        case 6: 
  50.295 +                        svga_render = svga_render_32bpp_highres; 
  50.296 +                        svga_hdisp *= 8;
  50.297 +                        break;
  50.298 +                }
  50.299 +                
  50.300 +                pclog("mach64_recalctimings : frame %i,%i disp %i,%i vsync at %i rowoffset %i pixel clock %f MA %08X\n", svga_htotal, svga_vtotal, svga_hdisp, svga_dispend, svga_vsyncstart, svga_rowoffset, svga_clock, svga_ma);
  50.301 +        }
  50.302 +}
  50.303 +
  50.304 +#define READ8(addr, var)        switch ((addr) & 3)                                     \
  50.305 +                                {                                                       \
  50.306 +                                        case 0: ret = (var) & 0xff;         break;      \
  50.307 +                                        case 1: ret = ((var) >> 8) & 0xff;  break;      \
  50.308 +                                        case 2: ret = ((var) >> 16) & 0xff; break;      \
  50.309 +                                        case 3: ret = ((var) >> 24) & 0xff; break;      \
  50.310 +                                }
  50.311 +                                
  50.312 +#define WRITE8(addr, var, val)  switch ((addr) & 3)                                             \
  50.313 +                                {                                                               \
  50.314 +                                        case 0: var = (var & 0xffffff00) | (val);         break;  \
  50.315 +                                        case 1: var = (var & 0xffff00ff) | ((val) << 8);  break;  \
  50.316 +                                        case 2: var = (var & 0xff00ffff) | ((val) << 16); break;  \
  50.317 +                                        case 3: var = (var & 0x00ffffff) | ((val) << 24); break;  \
  50.318 +                                }
  50.319 +
  50.320 +void mach64_cursor_dump()
  50.321 +{
  50.322 +        pclog("Mach64 cursor :\n");
  50.323 +        pclog("Ena = %i X = %i Y = %i Addr = %05X Xoff = %i Yoff = %i\n", svga_hwcursor.ena, svga_hwcursor.x, svga_hwcursor.y, svga_hwcursor.addr, svga_hwcursor.xoff, svga_hwcursor.yoff);
  50.324 +}
  50.325 +
  50.326 +void mach64_start_fill()
  50.327 +{
  50.328 +        int x, y;
  50.329 +        
  50.330 +        mach64.accel.dst_x = (mach64.dst_y_x >> 16) & 0xfff;
  50.331 +        mach64.accel.dst_y =  mach64.dst_y_x        & 0xfff;
  50.332 +
  50.333 +        mach64.accel.dst_width  = (mach64.dst_height_width >> 16) & 0x1fff;
  50.334 +        mach64.accel.dst_height =  mach64.dst_height_width        & 0x1fff;        
  50.335 +        mach64.accel.x_count = mach64.accel.dst_width;
  50.336 +        
  50.337 +        mach64.accel.src_x = (mach64.src_y_x >> 16) & 0xfff;
  50.338 +        mach64.accel.src_y =  mach64.src_y_x        & 0xfff;
  50.339 +
  50.340 +        mach64.accel.src_pitch  = (mach64.src_off_pitch >> 22) * 8;
  50.341 +        mach64.accel.src_offset = (mach64.src_off_pitch & 0xfffff) * 8;
  50.342 +
  50.343 +        mach64.accel.dst_pitch  = (mach64.dst_off_pitch >> 22) * 8;
  50.344 +        mach64.accel.dst_offset = (mach64.dst_off_pitch & 0xfffff) * 8;
  50.345 +        
  50.346 +        mach64.accel.mix_fg = (mach64.dp_mix >> 16) & 0x1f;
  50.347 +        mach64.accel.mix_bg = mach64.dp_mix & 0x1f;
  50.348 +        
  50.349 +        mach64.accel.source_bg  =  mach64.dp_src & 7;
  50.350 +        mach64.accel.source_fg  = (mach64.dp_src >> 8) & 7;
  50.351 +        mach64.accel.source_mix = (mach64.dp_src >> 16) & 7;
  50.352 +        
  50.353 +        mach64.accel.dst_pix_width  =  mach64.dp_pix_width        & 7;
  50.354 +        mach64.accel.src_pix_width  = (mach64.dp_pix_width >>  8) & 7;
  50.355 +        mach64.accel.host_pix_width = (mach64.dp_pix_width >> 16) & 7;
  50.356 +        
  50.357 +        mach64.accel.dst_size = mach64_width[mach64.accel.dst_pix_width];
  50.358 +        mach64.accel.src_size = mach64_width[mach64.accel.src_pix_width];
  50.359 +
  50.360 +/*        mach64.accel.src_x     *= mach64_inc[mach64.accel.src_pix_width];
  50.361 +        mach64.accel.src_pitch *= mach64_inc[mach64.accel.src_pix_width];
  50.362 +        mach64.accel.dst_x     *= mach64_inc[mach64.accel.dst_pix_width];
  50.363 +        mach64.accel.dst_pitch *= mach64_inc[mach64.accel.dst_pix_width];*/
  50.364 +        
  50.365 +        mach64.accel.src_offset >>= mach64.accel.src_size;
  50.366 +        mach64.accel.dst_offset >>= mach64.accel.dst_size;
  50.367 +
  50.368 +        mach64.accel.src_x_start = mach64.accel.src_x;
  50.369 +        mach64.accel.dst_x_start = mach64.accel.dst_x;
  50.370 +                
  50.371 +/*        if (mach64.accel.source_fg == SRC_BLITSRC || mach64.accel.source_bg == SRC_BLITSRC)
  50.372 +        {*/
  50.373 +                mach64.accel.xinc = (mach64.dst_cntl & 1) ? 1 : -1;
  50.374 +                mach64.accel.yinc = (mach64.dst_cntl & 2) ? 1 : -1;        
  50.375 +/*        }
  50.376 +        else
  50.377 +        {
  50.378 +                mach64.accel.xinc = mach64_inc[mach64.accel.src_pix_width];
  50.379 +                mach64.accel.yinc = 1;
  50.380 +        }*/
  50.381 +        
  50.382 +        mach64.accel.source_host = ((mach64.dp_src & 7) == SRC_HOST) || (((mach64.dp_src >> 8) & 7) == SRC_HOST);
  50.383 +        
  50.384 +        
  50.385 +//        pclog("mach64_start_fill : pattern %08X %08X\n", mach64.pat_reg0, mach64.pat_reg1);
  50.386 +        for (y = 0; y < 8; y++)
  50.387 +        {
  50.388 +                for (x = 0; x < 8; x++)
  50.389 +                {
  50.390 +                        uint32_t temp = (y & 4) ? mach64.pat_reg1 : mach64.pat_reg0;
  50.391 +                        mach64.accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1;
  50.392 +//                        pclog("%i ", mach64.accel.pattern[y][x]);                        
  50.393 +                }
  50.394 +//                pclog("\n");
  50.395 +        }
  50.396 +        
  50.397 +        mach64.accel.sc_left   =  mach64.sc_left_right & 0x1fff;
  50.398 +        mach64.accel.sc_right  = (mach64.sc_left_right >> 16) & 0x1fff;
  50.399 +        mach64.accel.sc_top    =  mach64.sc_top_bottom & 0x7fff;
  50.400 +        mach64.accel.sc_bottom = (mach64.sc_top_bottom >> 16) & 0x7fff;
  50.401 +
  50.402 +/*        mach64.accel.sc_left   *= mach64_inc[mach64.accel.dst_pix_width];
  50.403 +        mach64.accel.sc_right  *= mach64_inc[mach64.accel.dst_pix_width];*/
  50.404 +        
  50.405 +        mach64.accel.dp_frgd_clr = mach64.dp_frgd_clr;
  50.406 +        mach64.accel.dp_bkgd_clr = mach64.dp_bkgd_clr;        
  50.407 +        
  50.408 +        mach64.accel.busy = 1;
  50.409 +#ifdef MACH64_DEBUG
  50.410 +        pclog("mach64_start_fill : dst %i, %i  src %i, %i  size %i, %i  src pitch %i offset %X  dst pitch %i offset %X  scissor %i %i %i %i  src_fg %i\n", mach64.accel.dst_x, mach64.accel.dst_y, mach64.accel.src_x, mach64.accel.src_y, mach64.accel.dst_width, mach64.accel.dst_height, mach64.accel.src_pitch, mach64.accel.src_offset, mach64.accel.dst_pitch, mach64.accel.dst_offset, mach64.accel.sc_left, mach64.accel.sc_right, mach64.accel.sc_top, mach64.accel.sc_bottom, mach64.accel.source_fg);
  50.411 +#endif
  50.412 +        mach64.accel.op = OP_RECT;
  50.413 +}
  50.414 +
  50.415 +void mach64_start_line()
  50.416 +{
  50.417 +        int x, y;
  50.418 +        
  50.419 +        mach64.accel.dst_x = (mach64.dst_y_x >> 16) & 0xfff;
  50.420 +        mach64.accel.dst_y =  mach64.dst_y_x        & 0xfff;
  50.421 +
  50.422 +        mach64.accel.src_x = (mach64.src_y_x >> 16) & 0xfff;
  50.423 +        mach64.accel.src_y =  mach64.src_y_x        & 0xfff;
  50.424 +
  50.425 +        mach64.accel.src_pitch  = (mach64.src_off_pitch >> 22) * 8;
  50.426 +        mach64.accel.src_offset = (mach64.src_off_pitch & 0xfffff) * 8;
  50.427 +
  50.428 +        mach64.accel.dst_pitch  = (mach64.dst_off_pitch >> 22) * 8;
  50.429 +        mach64.accel.dst_offset = (mach64.dst_off_pitch & 0xfffff) * 8;
  50.430 +        
  50.431 +        mach64.accel.mix_fg = (mach64.dp_mix >> 16) & 0x1f;
  50.432 +        mach64.accel.mix_bg = mach64.dp_mix & 0x1f;
  50.433 +        
  50.434 +        mach64.accel.source_bg  =  mach64.dp_src & 7;
  50.435 +        mach64.accel.source_fg  = (mach64.dp_src >> 8) & 7;
  50.436 +        mach64.accel.source_mix = (mach64.dp_src >> 16) & 7;
  50.437 +        
  50.438 +        mach64.accel.dst_pix_width  =  mach64.dp_pix_width        & 7;
  50.439 +        mach64.accel.src_pix_width  = (mach64.dp_pix_width >>  8) & 7;
  50.440 +        mach64.accel.host_pix_width = (mach64.dp_pix_width >> 16) & 7;
  50.441 +        
  50.442 +        mach64.accel.dst_size = mach64_width[mach64.accel.dst_pix_width];
  50.443 +        mach64.accel.src_size = mach64_width[mach64.accel.src_pix_width];
  50.444 +
  50.445 +        mach64.accel.src_offset >>= mach64.accel.src_size;
  50.446 +        mach64.accel.dst_offset >>= mach64.accel.dst_size;
  50.447 +
  50.448 +/*        mach64.accel.src_pitch *= mach64_inc[mach64.accel.src_pix_width];
  50.449 +        mach64.accel.dst_pitch *= mach64_inc[mach64.accel.dst_pix_width];*/
  50.450 +      
  50.451 +        mach64.accel.source_host = ((mach64.dp_src & 7) == SRC_HOST) || (((mach64.dp_src >> 8) & 7) == SRC_HOST);
  50.452 +        
  50.453 +        for (y = 0; y < 8; y++)
  50.454 +        {
  50.455 +                for (x = 0; x < 8; x++)
  50.456 +                {
  50.457 +                        uint32_t temp = (y & 4) ? mach64.pat_reg1 : mach64.pat_reg0;
  50.458 +                        mach64.accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1;
  50.459 +                }
  50.460 +        }
  50.461 +        
  50.462 +        mach64.accel.sc_left   =  mach64.sc_left_right & 0x1fff;
  50.463 +        mach64.accel.sc_right  = (mach64.sc_left_right >> 16) & 0x1fff;
  50.464 +        mach64.accel.sc_top    =  mach64.sc_top_bottom & 0x7fff;
  50.465 +        mach64.accel.sc_bottom = (mach64.sc_top_bottom >> 16) & 0x7fff;
  50.466 +        
  50.467 +        mach64.accel.dp_frgd_clr = mach64.dp_frgd_clr;
  50.468 +        mach64.accel.dp_bkgd_clr = mach64.dp_bkgd_clr;        
  50.469 +        
  50.470 +        mach64.accel.x_count = mach64.dst_bres_lnth & 0x7fff;
  50.471 +        mach64.accel.err = (mach64.dst_bres_err & 0x3ffff) | ((mach64.dst_bres_err & 0x40000) ? 0xfffc0000 : 0);
  50.472 +        
  50.473 +        mach64.accel.busy = 1;
  50.474 +#ifdef MACH64_DEBUG
  50.475 +        pclog("mach64_start_line\n");
  50.476 +#endif
  50.477 +        mach64.accel.op = OP_LINE;
  50.478 +}
  50.479 +
  50.480 +#define READ(addr, dat, width) if (width == 0)      dat =               vram[((addr))      & 0x7fffff]; \
  50.481 +                               else if (width == 1) dat = *(uint16_t *)&vram[((addr) << 1) & 0x7fffff]; \
  50.482 +                               else                 dat = *(uint32_t *)&vram[((addr) << 2) & 0x7fffff];
  50.483 +
  50.484 +#define MIX     switch (mix ? mach64.accel.mix_fg : mach64.accel.mix_bg)                                \
  50.485 +                {                                                                                       \
  50.486 +                        case 0x0: dest_dat =             ~dest_dat;  break;                             \
  50.487 +                        case 0x1: dest_dat =  0;                     break;                             \
  50.488 +                        case 0x2: dest_dat =  0xffffffff;            break;                             \
  50.489 +                        case 0x3: dest_dat =              dest_dat;  break;                             \
  50.490 +                        case 0x4: dest_dat =  ~src_dat;              break;                             \
  50.491 +                        case 0x5: dest_dat =   src_dat ^  dest_dat;  break;                             \
  50.492 +                        case 0x6: dest_dat = ~(src_dat ^  dest_dat); break;                             \
  50.493 +                        case 0x7: dest_dat =   src_dat;              break;                             \
  50.494 +                        case 0x8: dest_dat = ~(src_dat &  dest_dat); break;                             \
  50.495 +                        case 0x9: dest_dat =  ~src_dat |  dest_dat;  break;                             \
  50.496 +                        case 0xa: dest_dat =   src_dat | ~dest_dat;  break;                             \
  50.497 +                        case 0xb: dest_dat =   src_dat |  dest_dat;  break;                             \
  50.498 +                        case 0xc: dest_dat =   src_dat &  dest_dat;  break;                             \
  50.499 +                        case 0xd: dest_dat =   src_dat & ~dest_dat;  break;                             \
  50.500 +                        case 0xe: dest_dat =  ~src_dat &  dest_dat;  break;                             \
  50.501 +                        case 0xf: dest_dat = ~(src_dat |  dest_dat); break;                             \
  50.502 +                }
  50.503 +
  50.504 +#define WRITE(addr, width)      if (width == 0)                                                         \
  50.505 +                                {                                                                       \
  50.506 +                                        vram[(addr) & 0x7fffff] = dest_dat;                             \
  50.507 +                                        changedvram[((addr) & 0x7fffff) >> 10] = changeframecount;      \
  50.508 +                                }                                                                       \
  50.509 +                                else if (width == 1)                                                    \
  50.510 +                                {                                                                       \
  50.511 +                                        *(uint16_t *)&vram[((addr) << 1) & 0x7fffff] = dest_dat;          \
  50.512 +                                        changedvram[(((addr) << 1) & 0x7fffff) >> 10] = changeframecount; \
  50.513 +                                }                                                                       \
  50.514 +                                else                                                                    \
  50.515 +                                {                                                                       \
  50.516 +                                        *(uint32_t *)&vram[((addr) << 2) & 0x7fffff] = dest_dat;          \
  50.517 +                                        changedvram[(((addr) << 2) & 0x7fffff) >> 10] = changeframecount; \
  50.518 +                                }
  50.519 +
  50.520 +void mach64_blit(uint32_t cpu_dat, int count)
  50.521 +{
  50.522 +        if (!mach64.accel.busy)
  50.523 +        {
  50.524 +#ifdef MACH64_DEBUG
  50.525 +                pclog("mach64_blit : return as not busy\n");
  50.526 +#endif
  50.527 +                return;
  50.528 +        }
  50.529 +        switch (mach64.accel.op)
  50.530 +        {
  50.531 +                case OP_RECT:
  50.532 +                while (count)
  50.533 +                {
  50.534 +                        uint32_t src_dat, dest_dat;
  50.535 +                        uint32_t host_dat;
  50.536 +                        int mix;
  50.537 +                
  50.538 +                        if (mach64.accel.source_host)
  50.539 +                        {
  50.540 +                                host_dat = cpu_dat;
  50.541 +                                switch (mach64.accel.src_size)
  50.542 +                                {
  50.543 +                                        case 0:
  50.544 +                                        cpu_dat >>= 8;
  50.545 +                                        count -= 8;
  50.546 +                                        break;
  50.547 +                                        case 1:
  50.548 +                                        cpu_dat >>= 16;
  50.549 +                                        count -= 16;
  50.550 +                                        break;
  50.551 +                                        case 2:
  50.552 +                                        count -= 32;
  50.553 +                                        break;
  50.554 +                                }
  50.555 +                        }
  50.556 +                        else
  50.557 +                           count--;
  50.558 +
  50.559 +                        switch (mach64.accel.source_mix)
  50.560 +                        {
  50.561 +                                case MONO_SRC_HOST:
  50.562 +                                mix = cpu_dat >> 31;
  50.563 +                                cpu_dat <<= 1;
  50.564 +                                break;
  50.565 +                                case MONO_SRC_PAT:
  50.566 +                                mix = mach64.accel.pattern[mach64.accel.dst_y & 7][mach64.accel.dst_x & 7];
  50.567 +                                break;
  50.568 +                                case MONO_SRC_1:
  50.569 +                                default:
  50.570 +                                mix = 1;
  50.571 +                                break;
  50.572 +                        }
  50.573 +                
  50.574 +                        if (mach64.accel.dst_x >= mach64.accel.sc_left && mach64.accel.dst_x <= mach64.accel.sc_right &&
  50.575 +                            mach64.accel.dst_y >= mach64.accel.sc_top  && mach64.accel.dst_y <= mach64.accel.sc_bottom)
  50.576 +                        {
  50.577 +                                switch (mix ? mach64.accel.source_fg : mach64.accel.source_bg)
  50.578 +                                {
  50.579 +                                        case SRC_HOST:
  50.580 +                                        src_dat = host_dat;
  50.581 +                                        break;
  50.582 +                                        case SRC_BLITSRC:
  50.583 +                                        READ(mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x, src_dat, mach64.accel.src_size);
  50.584 +                                        break;
  50.585 +                                        case SRC_FG:
  50.586 +                                        src_dat = mach64.accel.dp_frgd_clr;
  50.587 +                                        break;
  50.588 +                                        case SRC_BG:
  50.589 +                                        src_dat = mach64.accel.dp_bkgd_clr;
  50.590 +                                        break;
  50.591 +                                        default:
  50.592 +                                        src_dat = 0;
  50.593 +                                        break;
  50.594 +                                }
  50.595 +                
  50.596 +                                READ(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, dest_dat, mach64.accel.dst_size);
  50.597 +
  50.598 +//                                pclog("Blit %i,%i %i,%i  %X %X  %i  %02X %02X %i ", mach64.accel.src_x, mach64.accel.src_y, mach64.accel.dst_x, mach64.accel.dst_y,  (mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x) & 0x7fffff, (mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix);
  50.599 +                                
  50.600 +                                MIX
  50.601 +
  50.602 +//                                pclog("%02X  %i\n", dest_dat, mach64.accel.dst_height);
  50.603 +
  50.604 +                                WRITE(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, mach64.accel.dst_size);
  50.605 +                        }
  50.606 +                
  50.607 +                        if (mach64.dst_cntl & DST_24_ROT_EN)
  50.608 +                        {
  50.609 +                                mach64.accel.dp_frgd_clr = ((mach64.accel.dp_frgd_clr >> 8) & 0xffff) | (mach64.accel.dp_frgd_clr << 16);
  50.610 +                                mach64.accel.dp_bkgd_clr = ((mach64.accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64.accel.dp_bkgd_clr << 16);
  50.611 +                        }
  50.612 +                
  50.613 +                        mach64.accel.src_x += mach64.accel.xinc;
  50.614 +                        mach64.accel.dst_x += mach64.accel.xinc;
  50.615 +                        mach64.accel.x_count--;
  50.616 +                        
  50.617 +                        if (mach64.accel.x_count <= 0)
  50.618 +                        {
  50.619 +                                mach64.accel.x_count = mach64.accel.dst_width;
  50.620 +                                mach64.accel.src_x = mach64.accel.src_x_start;
  50.621 +                                mach64.accel.dst_x = mach64.accel.dst_x_start;
  50.622 +
  50.623 +                                mach64.accel.src_y += mach64.accel.yinc;                        
  50.624 +                                mach64.accel.dst_y += mach64.accel.yinc;
  50.625 +                                mach64.accel.dst_height--;
  50.626 +                
  50.627 +                                if (mach64.accel.dst_height <= 0)
  50.628 +                                {
  50.629 +                                        /*Blit finished*/
  50.630 +#ifdef MACH64_DEBUG
  50.631 +                                        pclog("mach64 blit finished\n");
  50.632 +#endif
  50.633 +                                        mach64.accel.busy = 0;
  50.634 +                                        return;
  50.635 +                                }
  50.636 +                                if (mach64.accel.source_host)
  50.637 +                                        return;
  50.638 +                        }
  50.639 +                }        
  50.640 +                break;
  50.641 +                
  50.642 +                case OP_LINE:
  50.643 +                while (count)
  50.644 +                {
  50.645 +                        uint32_t src_dat, dest_dat;
  50.646 +                        uint32_t host_dat;
  50.647 +                        int mix;
  50.648 +                
  50.649 +                        if (mach64.accel.source_host)
  50.650 +                        {
  50.651 +                                host_dat = cpu_dat;
  50.652 +                                switch (mach64.accel.src_size)
  50.653 +                                {
  50.654 +                                        case 0:
  50.655 +                                        cpu_dat >>= 8;
  50.656 +                                        count -= 8;
  50.657 +                                        break;
  50.658 +                                        case 1:
  50.659 +                                        cpu_dat >>= 16;
  50.660 +                                        count -= 16;
  50.661 +                                        break;
  50.662 +                                        case 2:
  50.663 +                                        count -= 32;
  50.664 +                                        break;
  50.665 +                                }
  50.666 +                        }
  50.667 +                        else
  50.668 +                           count--;
  50.669 +
  50.670 +                        switch (mach64.accel.source_mix)
  50.671 +                        {
  50.672 +                                case MONO_SRC_HOST:
  50.673 +                                mix = cpu_dat >> 31;
  50.674 +                                cpu_dat <<= 1;
  50.675 +                                break;
  50.676 +                                case MONO_SRC_PAT:
  50.677 +                                mix = mach64.accel.pattern[mach64.accel.dst_y & 7][mach64.accel.dst_x & 7];
  50.678 +                                break;
  50.679 +                                case MONO_SRC_1:
  50.680 +                                default:
  50.681 +                                mix = 1;
  50.682 +                                break;
  50.683 +                        }
  50.684 +                
  50.685 +                        if (mach64.accel.dst_x >= mach64.accel.sc_left && mach64.accel.dst_x <= mach64.accel.sc_right &&
  50.686 +                            mach64.accel.dst_y >= mach64.accel.sc_top  && mach64.accel.dst_y <= mach64.accel.sc_bottom)
  50.687 +                        {
  50.688 +                                switch (mix ? mach64.accel.source_fg : mach64.accel.source_bg)
  50.689 +                                {
  50.690 +                                        case SRC_HOST:
  50.691 +                                        src_dat = host_dat;
  50.692 +                                        break;
  50.693 +                                        case SRC_BLITSRC:
  50.694 +                                        READ(mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x, src_dat, mach64.accel.src_size);
  50.695 +                                        break;
  50.696 +                                        case SRC_FG:
  50.697 +                                        src_dat = mach64.accel.dp_frgd_clr;
  50.698 +                                        break;
  50.699 +                                        case SRC_BG:
  50.700 +                                        src_dat = mach64.accel.dp_bkgd_clr;
  50.701 +                                        break;
  50.702 +                                        default:
  50.703 +                                        src_dat = 0;
  50.704 +                                        break;
  50.705 +                                }
  50.706 +                
  50.707 +                                READ(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, dest_dat, mach64.accel.dst_size);
  50.708 +
  50.709 +//                                pclog("Blit %i,%i %i,%i  %X %X  %i  %02X %02X %i ", mach64.accel.src_x, mach64.accel.src_y, mach64.accel.dst_x, mach64.accel.dst_y,  (mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x) & 0x7fffff, (mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix);
  50.710 +                                
  50.711 +                                MIX
  50.712 +
  50.713 +//                                pclog("%02X  %i\n", dest_dat, mach64.accel.dst_height);
  50.714 +
  50.715 +                                WRITE(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, mach64.accel.dst_size);
  50.716 +                        }
  50.717 +                
  50.718 +                        mach64.accel.x_count--;                
  50.719 +                        if (mach64.accel.x_count <= 0)
  50.720 +                        {
  50.721 +                                /*Blit finished*/
  50.722 +#ifdef MACH64_DEBUG
  50.723 +                                pclog("mach64 blit finished\n");
  50.724 +#endif
  50.725 +                                mach64.accel.busy = 0;
  50.726 +                                return;
  50.727 +                        }
  50.728 +                        
  50.729 +                        switch (mach64.dst_cntl & 7)
  50.730 +                        {
  50.731 +                                case 0: case 2: 
  50.732 +                                mach64.accel.src_x--;
  50.733 +                                mach64.accel.dst_x--;
  50.734 +                                break;
  50.735 +                                case 1: case 3:
  50.736 +                                mach64.accel.src_x++;
  50.737 +                                mach64.accel.dst_x++;
  50.738 +                                break;
  50.739 +                                case 4: case 5: 
  50.740 +                                mach64.accel.src_y--;
  50.741 +                                mach64.accel.dst_y--;
  50.742 +                                break;
  50.743 +                                case 6: case 7:
  50.744 +                                mach64.accel.src_y++;
  50.745 +                                mach64.accel.dst_y++;
  50.746 +                                break;
  50.747 +                        }
  50.748 +#ifdef MACH64_DEBUG
  50.749 +                        pclog("x %i y %i err %i inc %i dec %i\n", mach64.accel.dst_x, mach64.accel.dst_y, mach64.accel.err, mach64.dst_bres_inc, mach64.dst_bres_dec);
  50.750 +#endif
  50.751 +                        if (mach64.accel.err >= 0)
  50.752 +                        {
  50.753 +                                mach64.accel.err += mach64.dst_bres_dec;
  50.754 +                                
  50.755 +                                switch (mach64.dst_cntl & 7)
  50.756 +                                {
  50.757 +                                        case 0: case 1: 
  50.758 +                                        mach64.accel.src_y--;
  50.759 +                                        mach64.accel.dst_y--;
  50.760 +                                        break;
  50.761 +                                        case 2: case 3:
  50.762 +                                        mach64.accel.src_y++;
  50.763 +                                        mach64.accel.dst_y++;
  50.764 +                                        break;
  50.765 +                                        case 4: case 6: 
  50.766 +                                        mach64.accel.src_x--;
  50.767 +                                        mach64.accel.dst_x--;
  50.768 +                                        break;
  50.769 +                                        case 5: case 7:
  50.770 +                                        mach64.accel.src_x++;
  50.771 +                                        mach64.accel.dst_x++;
  50.772 +                                        break;
  50.773 +                                }
  50.774 +                        }
  50.775 +                        else
  50.776 +                                mach64.accel.err += mach64.dst_bres_inc;
  50.777 +                }
  50.778 +                break;
  50.779 +        }
  50.780 +}
  50.781 +
  50.782 +void mach64_load_context()
  50.783 +{
  50.784 +        uint32_t addr;
  50.785 +        
  50.786 +        while (mach64.context_load_cntl & 0x30000)
  50.787 +        {
  50.788 +                addr = (0x3fff - (mach64.context_load_cntl & 0x3fff)) * 256;
  50.789 +                mach64.context_mask = *(uint32_t *)&vram[addr];
  50.790 +#ifdef MACH64_DEBUG
  50.791 +                pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64.context_load_cntl, addr, mach64.context_mask);
  50.792 +#endif
  50.793 + 
  50.794 +                if (mach64.context_mask & (1 << 2))
  50.795 +                        mach64_ext_writel(0x100, *(uint32_t *)&vram[addr + 0x08], NULL);
  50.796 +                if (mach64.context_mask & (1 << 3))
  50.797 +                        mach64_ext_writel(0x10c, *(uint32_t *)&vram[addr + 0x0c], NULL);
  50.798 +                if (mach64.context_mask & (1 << 4))
  50.799 +                        mach64_ext_writel(0x118, *(uint32_t *)&vram[addr + 0x10], NULL);
  50.800 +                if (mach64.context_mask & (1 << 5))
  50.801 +                        mach64_ext_writel(0x124, *(uint32_t *)&vram[addr + 0x14], NULL);
  50.802 +                if (mach64.context_mask & (1 << 6))
  50.803 +                        mach64_ext_writel(0x128, *(uint32_t *)&vram[addr + 0x18], NULL);
  50.804 +                if (mach64.context_mask & (1 << 7))
  50.805 +                        mach64_ext_writel(0x12c, *(uint32_t *)&vram[addr + 0x1c], NULL);
  50.806 +                if (mach64.context_mask & (1 << 8))
  50.807 +                        mach64_ext_writel(0x180, *(uint32_t *)&vram[addr + 0x20], NULL);
  50.808 +                if (mach64.context_mask & (1 << 9))
  50.809 +                        mach64_ext_writel(0x18c, *(uint32_t *)&vram[addr + 0x24], NULL);
  50.810 +                if (mach64.context_mask & (1 << 10))
  50.811 +                        mach64_ext_writel(0x198, *(uint32_t *)&vram[addr + 0x28], NULL);
  50.812 +                if (mach64.context_mask & (1 << 11))
  50.813 +                        mach64_ext_writel(0x1a4, *(uint32_t *)&vram[addr + 0x2c], NULL);
  50.814 +                if (mach64.context_mask & (1 << 12))
  50.815 +                        mach64_ext_writel(0x1b0, *(uint32_t *)&vram[addr + 0x30], NULL);
  50.816 +                if (mach64.context_mask & (1 << 13))
  50.817 +                        mach64_ext_writel(0x280, *(uint32_t *)&vram[addr + 0x34], NULL);
  50.818 +                if (mach64.context_mask & (1 << 14))
  50.819 +                        mach64_ext_writel(0x284, *(uint32_t *)&vram[addr + 0x38], NULL);
  50.820 +                if (mach64.context_mask & (1 << 15))
  50.821 +                        mach64_ext_writel(0x2a8, *(uint32_t *)&vram[addr + 0x3c], NULL);
  50.822 +                if (mach64.context_mask & (1 << 16))
  50.823 +                        mach64_ext_writel(0x2b4, *(uint32_t *)&vram[addr + 0x40], NULL);
  50.824 +                if (mach64.context_mask & (1 << 17))
  50.825 +                        mach64_ext_writel(0x2c0, *(uint32_t *)&vram[addr + 0x44], NULL);
  50.826 +                if (mach64.context_mask & (1 << 18))
  50.827 +                        mach64_ext_writel(0x2c4, *(uint32_t *)&vram[addr + 0x48], NULL);
  50.828 +                if (mach64.context_mask & (1 << 19))
  50.829 +                        mach64_ext_writel(0x2c8, *(uint32_t *)&vram[addr + 0x4c], NULL);
  50.830 +                if (mach64.context_mask & (1 << 20))
  50.831 +                        mach64_ext_writel(0x2cc, *(uint32_t *)&vram[addr + 0x50], NULL);
  50.832 +                if (mach64.context_mask & (1 << 21))
  50.833 +                        mach64_ext_writel(0x2d0, *(uint32_t *)&vram[addr + 0x54], NULL);
  50.834 +                if (mach64.context_mask & (1 << 22))
  50.835 +                        mach64_ext_writel(0x2d4, *(uint32_t *)&vram[addr + 0x58], NULL);
  50.836 +                if (mach64.context_mask & (1 << 23))
  50.837 +                        mach64_ext_writel(0x2d8, *(uint32_t *)&vram[addr + 0x5c], NULL);
  50.838 +                if (mach64.context_mask & (1 << 24))
  50.839 +                        mach64_ext_writel(0x300, *(uint32_t *)&vram[addr + 0x60], NULL);
  50.840 +                if (mach64.context_mask & (1 << 25))
  50.841 +                        mach64_ext_writel(0x304, *(uint32_t *)&vram[addr + 0x64], NULL);
  50.842 +                if (mach64.context_mask & (1 << 26))
  50.843 +                        mach64_ext_writel(0x308, *(uint32_t *)&vram[addr + 0x68], NULL);
  50.844 +                if (mach64.context_mask & (1 << 27))
  50.845 +                        mach64_ext_writel(0x330, *(uint32_t *)&vram[addr + 0x6c], NULL);
  50.846 +                
  50.847 +                mach64.context_load_cntl = *(uint32_t *)&vram[addr + 0x70];
  50.848 +        }
  50.849 +}
  50.850 +
  50.851 +uint8_t mach64_ext_readb(uint32_t addr, void *priv)
  50.852 +{
  50.853 +        uint8_t ret;
  50.854 +        switch (addr & 0x3ff)
  50.855 +        {
  50.856 +                case 0x00: case 0x01: case 0x02: case 0x03:
  50.857 +                READ8(addr, mach64.crtc_h_total_disp);
  50.858 +                break;
  50.859 +                case 0x08: case 0x09: case 0x0a: case 0x0b:
  50.860 +                READ8(addr, mach64.crtc_v_total_disp);
  50.861 +                break;
  50.862 +                case 0x0c: case 0x0d: case 0x0e: case 0x0f:
  50.863 +                READ8(addr, mach64.crtc_v_sync_strt_wid);
  50.864 +                break;
  50.865 +
  50.866 +                case 0x14: case 0x15: case 0x16: case 0x17:
  50.867 +                READ8(addr, mach64.crtc_off_pitch);
  50.868 +                break;
  50.869 +                
  50.870 +                case 0x18:
  50.871 +                ret = mach64.crtc_int_cntl & ~1;
  50.872 +                if (cgastat & 8)
  50.873 +                        ret |= 1;
  50.874 +                break;
  50.875 +
  50.876 +                case 0x1c: case 0x1d: case 0x1e: case 0x1f:
  50.877 +                READ8(addr, mach64.crtc_gen_cntl);
  50.878 +                break;
  50.879 +
  50.880 +                case 0x68: case 0x69: case 0x6a: case 0x6b:
  50.881 +                READ8(addr, mach64.cur_offset);
  50.882 +                break;
  50.883 +                case 0x6c: case 0x6d: case 0x6e: case 0x6f:
  50.884 +                READ8(addr, mach64.cur_horz_vert_posn);
  50.885 +                break;
  50.886 +                case 0x70: case 0x71: case 0x72: case 0x73:
  50.887 +                READ8(addr, mach64.cur_horz_vert_off);
  50.888 +                break;
  50.889 +
  50.890 +                case 0x80: case 0x81: case 0x82: case 0x83:
  50.891 +                READ8(addr, mach64.scratch_reg0);
  50.892 +                break;
  50.893 +                case 0x84: case 0x85: case 0x86: case 0x87:
  50.894 +                READ8(addr, mach64.scratch_reg1);
  50.895 +                break;
  50.896 +
  50.897 +                case 0x90: case 0x91: case 0x92: case 0x93:
  50.898 +                READ8(addr, mach64.clock_cntl);
  50.899 +                break;
  50.900 +
  50.901 +                case 0xb0: case 0xb1: case 0xb2: case 0xb3:
  50.902 +                READ8(addr, mach64.mem_cntl);
  50.903 +                break;
  50.904 +
  50.905 +                case 0xc4: case 0xc5: case 0xc6: case 0xc7:
  50.906 +                READ8(addr, mach64.dac_cntl);
  50.907 +                break;
  50.908 +
  50.909 +                case 0xd0: case 0xd1: case 0xd2: case 0xd3:
  50.910 +                READ8(addr, mach64.gen_test_cntl);
  50.911 +                break;
  50.912 +                
  50.913 +                case 0xe0: case 0xe1: case 0xe2: case 0xe3:
  50.914 +                READ8(addr, 0xd7); /*88800GX*/
  50.915 +                break;
  50.916 +                
  50.917 +                case 0x100: case 0x101: case 0x102: case 0x103:
  50.918 +                READ8(addr, mach64.dst_off_pitch);
  50.919 +                break;
  50.920 +                case 0x104: case 0x105:
  50.921 +                READ8(addr, mach64.dst_y_x);
  50.922 +                break;
  50.923 +                case 0x108: case 0x109: case 0x11c: case 0x11d:
  50.924 +                READ8(addr + 2, mach64.dst_y_x);
  50.925 +                break;
  50.926 +                case 0x10c: case 0x10d: case 0x10e: case 0x10f:
  50.927 +                READ8(addr, mach64.dst_y_x);
  50.928 +                break;
  50.929 +                case 0x110: case 0x111:
  50.930 +                addr += 2;
  50.931 +                case 0x114: case 0x115:
  50.932 +                case 0x118: case 0x119: case 0x11a: case 0x11b:
  50.933 +                case 0x11e: case 0x11f:
  50.934 +                READ8(addr, mach64.dst_height_width);
  50.935 +                break;
  50.936 +
  50.937 +                case 0x120: case 0x121: case 0x122: case 0x123:
  50.938 +                READ8(addr, mach64.dst_bres_lnth);
  50.939 +                break;
  50.940 +                case 0x124: case 0x125: case 0x126: case 0x127:
  50.941 +                READ8(addr, mach64.dst_bres_err);
  50.942 +                break;
  50.943 +                case 0x128: case 0x129: case 0x12a: case 0x12b:
  50.944 +                READ8(addr, mach64.dst_bres_inc);
  50.945 +                break;
  50.946 +                case 0x12c: case 0x12d: case 0x12e: case 0x12f:
  50.947 +                READ8(addr, mach64.dst_bres_dec);
  50.948 +                break;
  50.949 +
  50.950 +                case 0x130: case 0x131: case 0x132: case 0x133:
  50.951 +                READ8(addr, mach64.dst_cntl);
  50.952 +                break;
  50.953 +
  50.954 +                case 0x180: case 0x181: case 0x182: case 0x183:
  50.955 +                READ8(addr, mach64.src_off_pitch);
  50.956 +                break;
  50.957 +                case 0x184: case 0x185:
  50.958 +                READ8(addr, mach64.src_y_x);
  50.959 +                break;
  50.960 +                case 0x188: case 0x189:
  50.961 +                READ8(addr + 2, mach64.src_y_x);
  50.962 +                break;
  50.963 +                case 0x18c: case 0x18d: case 0x18e: case 0x18f:
  50.964 +                READ8(addr, mach64.src_y_x);
  50.965 +                break;
  50.966 +
  50.967 +                case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7:
  50.968 +                READ8(addr, mach64.src_cntl);
  50.969 +                break;
  50.970 +
  50.971 +                case 0x280: case 0x281: case 0x282: case 0x283:
  50.972 +                READ8(addr, mach64.pat_reg0);
  50.973 +                break;
  50.974 +                case 0x284: case 0x285: case 0x286: case 0x287:
  50.975 +                READ8(addr, mach64.pat_reg1);
  50.976 +                break;
  50.977 +
  50.978 +                case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9:
  50.979 +                READ8(addr, mach64.sc_left_right);
  50.980 +                break;
  50.981 +                case 0x2a4: case 0x2a5:
  50.982 +                addr += 2;
  50.983 +                case 0x2aa: case 0x2ab:                       
  50.984 +                READ8(addr, mach64.sc_left_right);
  50.985 +                break;
  50.986 +
  50.987 +                case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5:
  50.988 +                READ8(addr, mach64.sc_top_bottom);
  50.989 +                break;
  50.990 +                case 0x2b0: case 0x2b1:
  50.991 +                addr += 2;
  50.992 +                case 0x2b6: case 0x2b7:
  50.993 +                READ8(addr, mach64.sc_top_bottom);
  50.994 +                break;
  50.995 +
  50.996 +                case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3:
  50.997 +                READ8(addr, mach64.dp_bkgd_clr);
  50.998 +                break;
  50.999 +                case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7:
 50.1000 +                READ8(addr, mach64.dp_frgd_clr);
 50.1001 +                break;
 50.1002 +                        
 50.1003 +                case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3:
 50.1004 +                READ8(addr, mach64.dp_pix_width);
 50.1005 +                break;
 50.1006 +                case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7:
 50.1007 +                READ8(addr, mach64.dp_mix);
 50.1008 +                break;
 50.1009 +                case 0x2d8: case 0x2d9: case 0x2da: case 0x2db:
 50.1010 +                READ8(addr, mach64.dp_src);
 50.1011 +                break;
 50.1012 +
 50.1013 +                case 0x320: case 0x321: case 0x322: case 0x323:
 50.1014 +                READ8(addr, mach64.context_mask);
 50.1015 +                break;
 50.1016 +
 50.1017 +                case 0x330: case 0x331:
 50.1018 +                READ8(addr, mach64.dst_cntl);
 50.1019 +                break;
 50.1020 +                case 0x332:
 50.1021 +                READ8(addr - 2, mach64.src_cntl);
 50.1022 +                break;
 50.1023 +                case 0x333:
 50.1024 +                READ8(addr - 3, mach64.pat_cntl);
 50.1025 +                break;
 50.1026 +
 50.1027 +                default:
 50.1028 +                ret = 0;
 50.1029 +                break;
 50.1030 +        }
 50.1031 +#ifdef MACH64_DEBUG
 50.1032 +        if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readb : addr %08X ret %02X\n", addr, ret);
 50.1033 +#endif
 50.1034 +        return ret;
 50.1035 +}
 50.1036 +uint16_t mach64_ext_readw(uint32_t addr, void *priv)
 50.1037 +{
 50.1038 +        uint16_t ret;
 50.1039 +        switch (addr & 0x3ff)
 50.1040 +        {
 50.1041 +                default:
 50.1042 +#ifdef MACH64_DEBUG
 50.1043 +                pclog("  ");
 50.1044 +#endif
 50.1045 +                ret = mach64_ext_readb(addr, priv);
 50.1046 +#ifdef MACH64_DEBUG
 50.1047 +                pclog("  ");
 50.1048 +#endif
 50.1049 +                ret |= mach64_ext_readb(addr + 1, priv) << 8;
 50.1050 +                break;
 50.1051 +        }
 50.1052 +#ifdef MACH64_DEBUG
 50.1053 +        if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readw : addr %08X ret %04X\n", addr, ret);
 50.1054 +#endif
 50.1055 +        return ret;        
 50.1056 +}
 50.1057 +uint32_t mach64_ext_readl(uint32_t addr, void *priv)
 50.1058 +{
 50.1059 +        uint32_t ret;
 50.1060 +        switch (addr & 0x3ff)
 50.1061 +        {
 50.1062 +                case 0x18:
 50.1063 +                ret = mach64.crtc_int_cntl & ~1;
 50.1064 +                if (cgastat & 8)
 50.1065 +                        ret |= 1;
 50.1066 +                break;
 50.1067 +
 50.1068 +                case 0xb4:
 50.1069 +                ret = (mach64_bank_w[0] >> 15) | ((mach64_bank_w[1] >> 15) << 16);
 50.1070 +                break;
 50.1071 +                case 0xb8:
 50.1072 +                ret = (mach64_bank_r[0] >> 15) | ((mach64_bank_r[1] >> 15) << 16);
 50.1073 +                break;
 50.1074 +                
 50.1075 +                default:
 50.1076 +#ifdef MACH64_DEBUG
 50.1077 +                pclog("  ");
 50.1078 +#endif
 50.1079 +                ret = mach64_ext_readw(addr, priv);
 50.1080 +#ifdef MACH64_DEBUG
 50.1081 +                pclog("  ");
 50.1082 +#endif
 50.1083 +                ret |= mach64_ext_readw(addr + 2, priv) << 16;
 50.1084 +                break;
 50.1085 +        }
 50.1086 +#ifdef MACH64_DEBUG
 50.1087 +        if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readl : addr %08X ret %08X\n", addr, ret);
 50.1088 +#endif
 50.1089 +        return ret;
 50.1090 +}
 50.1091 +
 50.1092 +void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
 50.1093 +{
 50.1094 +#ifdef MACH64_DEBUG
 50.1095 +        pclog("mach64_ext_writeb : addr %08X val %02X\n", addr, val);
 50.1096 +#endif
 50.1097 +        switch (addr & 0x3ff)
 50.1098 +        {
 50.1099 +                case 0x00: case 0x01: case 0x02: case 0x03:
 50.1100 +                WRITE8(addr, mach64.crtc_h_total_disp, val);
 50.1101 +                svga_recalctimings();
 50.1102 +                break;
 50.1103 +                case 0x08: case 0x09: case 0x0a: case 0x0b:
 50.1104 +                WRITE8(addr, mach64.crtc_v_total_disp, val);
 50.1105 +                svga_recalctimings();
 50.1106 +                break;
 50.1107 +                case 0x0c: case 0x0d: case 0x0e: case 0x0f:
 50.1108 +                WRITE8(addr, mach64.crtc_v_sync_strt_wid, val);
 50.1109 +                svga_recalctimings();
 50.1110 +                break;
 50.1111 +
 50.1112 +                case 0x14: case 0x15: case 0x16: case 0x17:
 50.1113 +                WRITE8(addr, mach64.crtc_off_pitch, val);
 50.1114 +                svga_recalctimings();
 50.1115 +                fullchange = changeframecount;
 50.1116 +                break;
 50.1117 +                
 50.1118 +                case 0x18:
 50.1119 +                mach64.crtc_int_cntl = val;
 50.1120 +                break;
 50.1121 +
 50.1122 +                case 0x1c: case 0x1d: case 0x1e: case 0x1f:
 50.1123 +                WRITE8(addr, mach64.crtc_gen_cntl, val);
 50.1124 +                svga_recalctimings();
 50.1125 +                break;
 50.1126 +
 50.1127 +                case 0x68: case 0x69: case 0x6a: case 0x6b:
 50.1128 +                WRITE8(addr, mach64.cur_offset, val);
 50.1129 +                svga_hwcursor.addr = (mach64.cur_offset & 0xfffff) * 8;
 50.1130 +                mach64_cursor_dump();
 50.1131 +                break;
 50.1132 +                case 0x6c: case 0x6d: case 0x6e: case 0x6f:
 50.1133 +                WRITE8(addr, mach64.cur_horz_vert_posn, val);
 50.1134 +                svga_hwcursor.x = mach64.cur_horz_vert_posn & 0x7ff;
 50.1135 +                svga_hwcursor.y = (mach64.cur_horz_vert_posn >> 16) & 0x7ff;
 50.1136 +                mach64_cursor_dump();
 50.1137 +                break;
 50.1138 +                case 0x70: case 0x71: case 0x72: case 0x73:
 50.1139 +                WRITE8(addr, mach64.cur_horz_vert_off, val);
 50.1140 +                svga_hwcursor.xoff = mach64.cur_horz_vert_off & 0x3f;
 50.1141 +                svga_hwcursor.yoff = (mach64.cur_horz_vert_off >> 16) & 0x3f;
 50.1142 +                mach64_cursor_dump();
 50.1143 +                break;
 50.1144 +
 50.1145 +                case 0x80: case 0x81: case 0x82: case 0x83:
 50.1146 +                WRITE8(addr, mach64.scratch_reg0, val);
 50.1147 +                break;
 50.1148 +                case 0x84: case 0x85: case 0x86: case 0x87:
 50.1149 +                WRITE8(addr, mach64.scratch_reg1, val);
 50.1150 +                break;
 50.1151 +
 50.1152 +                case 0x90: case 0x91: case 0x92: case 0x93:
 50.1153 +                WRITE8(addr, mach64.clock_cntl, val);
 50.1154 +                ics2595_write(val & 0x40, val & 0xf);
 50.1155 +                break;
 50.1156 +
 50.1157 +                case 0xb0: case 0xb1: case 0xb2: case 0xb3:
 50.1158 +                WRITE8(addr, mach64.mem_cntl, val);
 50.1159 +                break;
 50.1160 +
 50.1161 +                case 0xb4:
 50.1162 +                mach64_bank_w[0] = val * 32768;
 50.1163 +#ifdef MACH64_DEBUG
 50.1164 +                pclog("mach64 : write bank A0000-A7FFF set to %08X\n", mach64_bank_w[0]);
 50.1165 +#endif
 50.1166 +                break;
 50.1167 +                case 0xb5: case 0xb6:
 50.1168 +                mach64_bank_w[1] = val * 32768;
 50.1169 +#ifdef MACH64_DEBUG
 50.1170 +                pclog("mach64 : write bank A8000-AFFFF set to %08X\n", mach64_bank_w[1]);
 50.1171 +#endif
 50.1172 +                break;
 50.1173 +                case 0xb8:
 50.1174 +                mach64_bank_r[0] = val * 32768;
 50.1175 +#ifdef MACH64_DEBUG
 50.1176 +                pclog("mach64 :  read bank A0000-A7FFF set to %08X\n", mach64_bank_r[0]);
 50.1177 +#endif
 50.1178 +                break;
 50.1179 +                case 0xb9: case 0xba:
 50.1180 +                mach64_bank_r[1] = val * 32768;
 50.1181 +#ifdef MACH64_DEBUG
 50.1182 +                pclog("mach64 :  read bank A8000-AFFFF set to %08X\n", mach64_bank_r[1]);
 50.1183 +#endif
 50.1184 +                break;
 50.1185 +
 50.1186 +                case 0xc4: case 0xc5: case 0xc6: case 0xc7:
 50.1187 +                WRITE8(addr, mach64.dac_cntl, val);
 50.1188 +                break;
 50.1189 +
 50.1190 +                case 0xd0: case 0xd1: case 0xd2: case 0xd3:
 50.1191 +                WRITE8(addr, mach64.gen_test_cntl, val);
 50.1192 +//                if (val == 2) output = 3;
 50.1193 +                ati_eeprom_write(mach64.gen_test_cntl & 0x10, mach64.gen_test_cntl & 2, mach64.gen_test_cntl & 1);
 50.1194 +                mach64.gen_test_cntl = (mach64.gen_test_cntl & ~8) | (ati_eeprom_read() ? 8 : 0);
 50.1195 +                svga_hwcursor.ena = mach64.gen_test_cntl & 0x80;
 50.1196 +                mach64_cursor_dump();
 50.1197 +                break;
 50.1198 +
 50.1199 +                case 0x100: case 0x101: case 0x102: case 0x103:
 50.1200 +                WRITE8(addr, mach64.dst_off_pitch, val);
 50.1201 +                break;
 50.1202 +                case 0x104: case 0x105: case 0x11c: case 0x11d:
 50.1203 +                WRITE8(addr + 2, mach64.dst_y_x, val);
 50.1204 +                break;
 50.1205 +                case 0x108: case 0x109:
 50.1206 +                WRITE8(addr, mach64.dst_y_x, val);
 50.1207 +                break;
 50.1208 +                case 0x10c: case 0x10d: case 0x10e: case 0x10f:
 50.1209 +                WRITE8(addr, mach64.dst_y_x, val);
 50.1210 +                break;
 50.1211 +                case 0x110: case 0x111:
 50.1212 +                addr += 2;
 50.1213 +                case 0x114: case 0x115:
 50.1214 +                case 0x118: case 0x119: case 0x11a: case 0x11b:
 50.1215 +                case 0x11e: case 0x11f:
 50.1216 +                WRITE8(addr, mach64.dst_height_width, val);
 50.1217 +                if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f)
 50.1218 +                {
 50.1219 +                        mach64_start_fill();
 50.1220 +#ifdef MACH64_DEBUG
 50.1221 +                        pclog("%i %i %i %i %i\n", (mach64.dst_height_width & 0x7ff), (mach64.dst_height_width & 0x7ff0000),
 50.1222 +                            ((mach64.dp_src & 7) != SRC_HOST), (((mach64.dp_src >> 8) & 7) != SRC_HOST),
 50.1223 +                            (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST));
 50.1224 +#endif                            
 50.1225 +                        if ((mach64.dst_height_width & 0x7ff) && (mach64.dst_height_width & 0x7ff0000) && 
 50.1226 +                            ((mach64.dp_src & 7) != SRC_HOST) && (((mach64.dp_src >> 8) & 7) != SRC_HOST) && 
 50.1227 +                            (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST))
 50.1228 +                                mach64_blit(0, -1);
 50.1229 +                }
 50.1230 +                break;
 50.1231 +
 50.1232 +                case 0x120: case 0x121: case 0x122: case 0x123:
 50.1233 +                WRITE8(addr, mach64.dst_bres_lnth, val);
 50.1234 +                if ((addr & 0x3ff) == 0x123 && !(val & 0x80))
 50.1235 +                {
 50.1236 +                        mach64_start_line();
 50.1237 +
 50.1238 +                        if ((mach64.dst_bres_lnth & 0x7fff) &&
 50.1239 +                            ((mach64.dp_src & 7) != SRC_HOST) && (((mach64.dp_src >> 8) & 7) != SRC_HOST) && 
 50.1240 +                            (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST))
 50.1241 +                                mach64_blit(0, -1);
 50.1242 +                }
 50.1243 +                break;
 50.1244 +                case 0x124: case 0x125: case 0x126: case 0x127:
 50.1245 +                WRITE8(addr, mach64.dst_bres_err, val);
 50.1246 +                break;
 50.1247 +                case 0x128: case 0x129: case 0x12a: case 0x12b:
 50.1248 +                WRITE8(addr, mach64.dst_bres_inc, val);
 50.1249 +                break;
 50.1250 +                case 0x12c: case 0x12d: case 0x12e: case 0x12f:
 50.1251 +                WRITE8(addr, mach64.dst_bres_dec, val);
 50.1252 +                break;
 50.1253 +
 50.1254 +                case 0x130: case 0x131: case 0x132: case 0x133:
 50.1255 +                WRITE8(addr, mach64.dst_cntl, val);
 50.1256 +                break;
 50.1257 +
 50.1258 +                case 0x180: case 0x181: case 0x182: case 0x183:
 50.1259 +                WRITE8(addr, mach64.src_off_pitch, val);
 50.1260 +                break;
 50.1261 +                case 0x184: case 0x185:
 50.1262 +                WRITE8(addr, mach64.src_y_x, val);
 50.1263 +                break;
 50.1264 +                case 0x188: case 0x189:
 50.1265 +                WRITE8(addr + 2, mach64.src_y_x, val);
 50.1266 +                break;
 50.1267 +                case 0x18c: case 0x18d: case 0x18e: case 0x18f:
 50.1268 +                WRITE8(addr, mach64.src_y_x, val);
 50.1269 +                break;
 50.1270 +
 50.1271 +                case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7:
 50.1272 +                WRITE8(addr, mach64.src_cntl, val);
 50.1273 +                break;
 50.1274 +
 50.1275 +                case 0x200: case 0x201: case 0x202: case 0x203:
 50.1276 +                case 0x204: case 0x205: case 0x206: case 0x207:
 50.1277 +                case 0x208: case 0x209: case 0x20a: case 0x20b:
 50.1278 +                case 0x20c: case 0x20d: case 0x20e: case 0x20f:
 50.1279 +                case 0x210: case 0x211: case 0x212: case 0x213:
 50.1280 +                case 0x214: case 0x215: case 0x216: case 0x217:
 50.1281 +                case 0x218: case 0x219: case 0x21a: case 0x21b:
 50.1282 +                case 0x21c: case 0x21d: case 0x21e: case 0x21f:
 50.1283 +                case 0x220: case 0x221: case 0x222: case 0x223:
 50.1284 +                case 0x224: case 0x225: case 0x226: case 0x227:
 50.1285 +                case 0x228: case 0x229: case 0x22a: case 0x22b:
 50.1286 +                case 0x22c: case 0x22d: case 0x22e: case 0x22f:
 50.1287 +                case 0x230: case 0x231: case 0x232: case 0x233:
 50.1288 +                case 0x234: case 0x235: case 0x236: case 0x237:
 50.1289 +                case 0x238: case 0x239: case 0x23a: case 0x23b:
 50.1290 +                case 0x23c: case 0x23d: case 0x23e: case 0x23f:
 50.1291 +                mach64_blit(val, 8);
 50.1292 +                break;
 50.1293 +
 50.1294 +                case 0x280: case 0x281: case 0x282: case 0x283:
 50.1295 +                WRITE8(addr, mach64.pat_reg0, val);
 50.1296 +                break;
 50.1297 +                case 0x284: case 0x285: case 0x286: case 0x287:
 50.1298 +                WRITE8(addr, mach64.pat_reg1, val);
 50.1299 +                break;
 50.1300 +
 50.1301 +                case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9:
 50.1302 +                WRITE8(addr, mach64.sc_left_right, val);
 50.1303 +                break;
 50.1304 +                case 0x2a4: case 0x2a5:
 50.1305 +                addr += 2;
 50.1306 +                case 0x2aa: case 0x2ab:                       
 50.1307 +                WRITE8(addr, mach64.sc_left_right, val);
 50.1308 +                break;
 50.1309 +
 50.1310 +                case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5:
 50.1311 +                WRITE8(addr, mach64.sc_top_bottom, val);
 50.1312 +                break;
 50.1313 +                case 0x2b0: case 0x2b1:
 50.1314 +                addr += 2;
 50.1315 +                case 0x2b6: case 0x2b7:
 50.1316 +                WRITE8(addr, mach64.sc_top_bottom, val);
 50.1317 +                break;
 50.1318 +
 50.1319 +                case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3:
 50.1320 +                WRITE8(addr, mach64.dp_bkgd_clr, val);
 50.1321 +                break;
 50.1322 +                case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7:
 50.1323 +                WRITE8(addr, mach64.dp_frgd_clr, val);
 50.1324 +                break;
 50.1325 +
 50.1326 +                case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3:
 50.1327 +                WRITE8(addr, mach64.dp_pix_width, val);
 50.1328 +                break;
 50.1329 +                case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7:
 50.1330 +                WRITE8(addr, mach64.dp_mix, val);
 50.1331 +                break;
 50.1332 +                case 0x2d8: case 0x2d9: case 0x2da: case 0x2db:
 50.1333 +                WRITE8(addr, mach64.dp_src, val);
 50.1334 +                break;
 50.1335 +
 50.1336 +                case 0x320: case 0x321: case 0x322: case 0x323:
 50.1337 +                WRITE8(addr, mach64.context_mask, val);
 50.1338 +                break;
 50.1339 +
 50.1340 +                case 0x330: case 0x331:
 50.1341 +                WRITE8(addr, mach64.dst_cntl, val);
 50.1342 +                break;
 50.1343 +                case 0x332:
 50.1344 +                WRITE8(addr - 2, mach64.src_cntl, val);
 50.1345 +                break;
 50.1346 +                case 0x333:
 50.1347 +                WRITE8(addr - 3, mach64.pat_cntl, val & 7);
 50.1348 +                break;
 50.1349 +        }
 50.1350 +}
 50.1351 +void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv)
 50.1352 +{
 50.1353 +#ifdef MACH64_DEBUG
 50.1354 +        pclog("mach64_ext_writew : addr %08X val %04X\n", addr, val);
 50.1355 +#endif
 50.1356 +        switch (addr & 0x3fe)
 50.1357 +        {
 50.1358 +                case 0x200: case 0x202: case 0x204: case 0x206:
 50.1359 +                case 0x208: case 0x20a: case 0x20c: case 0x20e:
 50.1360 +                case 0x210: case 0x212: case 0x214: case 0x216:
 50.1361 +                case 0x218: case 0x21a: case 0x21c: case 0x21e:
 50.1362 +                case 0x220: case 0x222: case 0x224: case 0x226:
 50.1363 +                case 0x228: case 0x22a: case 0x22c: case 0x22e:
 50.1364 +                case 0x230: case 0x232: case 0x234: case 0x236:
 50.1365 +                case 0x238: case 0x23a: case 0x23c: case 0x23e:
 50.1366 +                mach64_blit(val, 16);
 50.1367 +                break;
 50.1368 +
 50.1369 +                default:
 50.1370 +#ifdef MACH64_DEBUG
 50.1371 +                pclog("  ");
 50.1372 +#endif
 50.1373 +                mach64_ext_writeb(addr, val, priv);
 50.1374 +#ifdef MACH64_DEBUG
 50.1375 +                pclog("  ");
 50.1376 +#endif
 50.1377 +                mach64_ext_writeb(addr + 1, val >> 8, priv);
 50.1378 +                break;
 50.1379 +        }
 50.1380 +}
 50.1381 +void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv)
 50.1382 +{
 50.1383 +#ifdef MACH64_DEBUG
 50.1384 +        if ((addr & 0x3c0) != 0x200)
 50.1385 +                pclog("mach64_ext_writel : addr %08X val %08X\n", addr, val);
 50.1386 +#endif
 50.1387 +        switch (addr & 0x3fc)
 50.1388 +        {
 50.1389 +                case 0x32c:
 50.1390 +                mach64.context_load_cntl = val;
 50.1391 +                if (val & 0x30000)
 50.1392 +                        mach64_load_context();
 50.1393 +                break;
 50.1394 +                
 50.1395 +                case 0x200: case 0x204: case 0x208: case 0x20c:
 50.1396 +                case 0x210: case 0x214: case 0x218: case 0x21c:
 50.1397 +                case 0x220: case 0x224: case 0x228: case 0x22c:
 50.1398 +                case 0x230: case 0x234: case 0x238: case 0x23c:
 50.1399 +                if (mach64.accel.source_host)
 50.1400 +                        mach64_blit(val, 32);
 50.1401 +                else
 50.1402 +                        mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32);                
 50.1403 +                break;
 50.1404 +                
 50.1405 +                default:
 50.1406 +#ifdef MACH64_DEBUG
 50.1407 +                pclog("  ");
 50.1408 +#endif
 50.1409 +                mach64_ext_writew(addr, val, priv);
 50.1410 +#ifdef MACH64_DEBUG
 50.1411 +                pclog("  ");
 50.1412 +#endif
 50.1413 +                mach64_ext_writew(addr + 2, val >> 16, priv);
 50.1414 +                break;
 50.1415 +        }
 50.1416 +}
 50.1417 +
 50.1418 +uint8_t mach64_ext_inb(uint16_t port, void *priv)
 50.1419 +{
 50.1420 +        uint8_t ret;
 50.1421 +//        if (CS == 0x2be7) output = 3;
 50.1422 +        switch (port)
 50.1423 +        {
 50.1424 +                case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef:
 50.1425 +                ret = mach64_ext_readb(0x00 | (port & 3), NULL);
 50.1426 +                break;
 50.1427 +                case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef:
 50.1428 +                ret = mach64_ext_readb(0x08 | (port & 3), NULL);
 50.1429 +                break;
 50.1430 +                case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef:
 50.1431 +                ret = mach64_ext_readb(0x0c | (port & 3), NULL);
 50.1432 +                break;
 50.1433 +
 50.1434 +                case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef:
 50.1435 +                ret = mach64_ext_readb(0x14 | (port & 3), NULL);
 50.1436 +                break;
 50.1437 +
 50.1438 +                case 0x1aec:
 50.1439 +                ret = mach64_ext_readb(0x18, NULL);
 50.1440 +                break;
 50.1441 +
 50.1442 +                case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef:
 50.1443 +                ret = mach64_ext_readb(0x1c | (port & 3), NULL);
 50.1444 +                break;
 50.1445 +
 50.1446 +                case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef:
 50.1447 +                ret = mach64_ext_readb(0x68 | (port & 3), NULL);
 50.1448 +                break;
 50.1449 +                case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef:
 50.1450 +                ret = mach64_ext_readb(0x6c | (port & 3), NULL);
 50.1451 +                break;
 50.1452 +                case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef:
 50.1453 +                ret = mach64_ext_readb(0x70 | (port & 3), NULL);
 50.1454 +                break;
 50.1455 +
 50.1456 +                case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef:
 50.1457 +                ret = mach64_ext_readb(0x80 | (port & 3), NULL);
 50.1458 +                break;
 50.1459 +                case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef:
 50.1460 +                ret = mach64_ext_readb(0x84 | (port & 3), NULL);
 50.1461 +                break;
 50.1462 +                case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef:
 50.1463 +                ret = mach64_ext_readb(0x90 | (port & 3), NULL);
 50.1464 +                break;
 50.1465 +
 50.1466 +                case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef:
 50.1467 +                ret = mach64_ext_readb(0xb0 | (port & 3), NULL);
 50.1468 +                break;
 50.1469 +                        
 50.1470 +                case 0x56ec:
 50.1471 +                ret = mach64_ext_readb(0xb4, NULL);
 50.1472 +                break;
 50.1473 +                case 0x56ed: case 0x56ee:
 50.1474 +                ret = mach64_ext_readb(0xb5, NULL);
 50.1475 +                break;
 50.1476 +                case 0x5aec:
 50.1477 +                ret = mach64_ext_readb(0xb8, NULL);
 50.1478 +                break;
 50.1479 +                case 0x5aed: case 0x5aee:
 50.1480 +                ret = mach64_ext_readb(0xb9, NULL);
 50.1481 +                break;
 50.1482 +
 50.1483 +                case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef:
 50.1484 +                ret = ati68860_ramdac_in((port & 3) | ((mach64.dac_cntl & 3) << 2), NULL);
 50.1485 +                break;
 50.1486 +                
 50.1487 +                case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef:
 50.1488 +                ret = mach64_ext_readb(0xc4 | (port & 3), NULL);
 50.1489 +                break;
 50.1490 +                        
 50.1491 +                case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef:
 50.1492 +                ret = mach64_ext_readb(0xd0 | (port & 3), NULL);
 50.1493 +                break;
 50.1494 +
 50.1495 +                case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef:
 50.1496 +                READ8(port, mach64.config_cntl);
 50.1497 +                break;
 50.1498 +                
 50.1499 +                case 0x6eec: case 0x6eed: case 0x6eee: case 0x6eef:
 50.1500 +                ret = mach64_ext_readb(0xe0 | (port & 3), NULL);
 50.1501 +                break;
 50.1502 +
 50.1503 +                case 0x72ec:
 50.1504 +                ret = 6 | (3 << 3); /*VLB, 256Kx16 DRAM*/
 50.1505 +                break;
 50.1506 +                
 50.1507 +                default:
 50.1508 +                ret = 0;
 50.1509 +                break;
 50.1510 +        }
 50.1511 +#ifdef MACH64_DEBUG
 50.1512 +        pclog("mach64_ext_inb : port %04X ret %02X  %04X:%04X\n", port, ret, CS,pc);
 50.1513 +#endif
 50.1514 +        return ret;
 50.1515 +}
 50.1516 +uint16_t mach64_ext_inw(uint16_t port, void *priv)
 50.1517 +{
 50.1518 +        uint16_t ret;
 50.1519 +        switch (port)
 50.1520 +        {
 50.1521 +                default:
 50.1522 +                pclog("  ");
 50.1523 +                ret = mach64_ext_inb(port, priv);
 50.1524 +                pclog("  ");
 50.1525 +                ret |= (mach64_ext_inb(port + 1, priv) << 8);
 50.1526 +                break;
 50.1527 +        }
 50.1528 +#ifdef MACH64_DEBUG
 50.1529 +        pclog("mach64_ext_inw : port %04X ret %04X\n", port, ret);
 50.1530 +#endif
 50.1531 +        return ret;        
 50.1532 +}
 50.1533 +uint32_t mach64_ext_inl(uint16_t port, void *priv)
 50.1534 +{
 50.1535 +        uint32_t ret;
 50.1536 +        switch (port)
 50.1537 +        {
 50.1538 +                case 0x56ec:
 50.1539 +                ret = mach64_ext_readl(0xb4, NULL);
 50.1540 +                break;
 50.1541 +                case 0x5aec:
 50.1542 +                ret = mach64_ext_readl(0xb8, NULL);
 50.1543 +                break;
 50.1544 +
 50.1545 +                default:
 50.1546 +                pclog("  ");
 50.1547 +                ret = mach64_ext_inw(port, priv);
 50.1548 +                pclog("  ");
 50.1549 +                ret |= (mach64_ext_inw(port + 2, priv) << 16);
 50.1550 +                break;
 50.1551 +        }
 50.1552 +#ifdef MACH64_DEBUG
 50.1553 +        pclog("mach64_ext_inl : port %04X ret %08X\n", port, ret);
 50.1554 +#endif
 50.1555 +        return ret;
 50.1556 +}
 50.1557 +
 50.1558 +void mach64_ext_outb(uint16_t port, uint8_t val, void *priv)
 50.1559 +{
 50.1560 +#ifdef MACH64_DEBUG
 50.1561 +        pclog("mach64_ext_outb : port %04X val %02X  %04X:%04X\n", port, val, CS,pc);
 50.1562 +#endif
 50.1563 +        switch (port)
 50.1564 +        {
 50.1565 +                case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef:
 50.1566 +                case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef:
 50.1567 +                mach64_ext_writeb(0x00 | (port & 3), val, NULL);
 50.1568 +                break;
 50.1569 +                case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef:
 50.1570 +                mach64_ext_writeb(0x08 | (port & 3), val, NULL);
 50.1571 +                break;
 50.1572 +                case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef:
 50.1573 +                mach64_ext_writeb(0x0c | (port & 3), val, NULL);
 50.1574 +                break;
 50.1575 +
 50.1576 +                case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef:
 50.1577 +                mach64_ext_writeb(0x14 | (port & 3), val, NULL);
 50.1578 +                break;
 50.1579 +                
 50.1580 +                case 0x1aec:
 50.1581 +                mach64_ext_writeb(0x18, val, NULL);
 50.1582 +                break;
 50.1583 +
 50.1584 +                case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef:
 50.1585 +                mach64_ext_writeb(0x1c | (port & 3), val, NULL);
 50.1586 +                break;
 50.1587 +
 50.1588 +                case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef:
 50.1589 +                mach64_ext_writeb(0x68 | (port & 3), val, NULL);
 50.1590 +                break;
 50.1591 +                case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef:
 50.1592 +                mach64_ext_writeb(0x6c | (port & 3), val, NULL);
 50.1593 +                break;
 50.1594 +                case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef:
 50.1595 +                mach64_ext_writeb(0x70 | (port & 3), val, NULL);
 50.1596 +                break;
 50.1597 +
 50.1598 +                case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef:
 50.1599 +                mach64_ext_writeb(0x80 | (port & 3), val, NULL);
 50.1600 +                break;
 50.1601 +                case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef:
 50.1602 +                mach64_ext_writeb(0x84 | (port & 3), val, NULL);
 50.1603 +                break;
 50.1604 +                case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef:
 50.1605 +                mach64_ext_writeb(0x90 | (port & 3), val, NULL);
 50.1606 +                break;
 50.1607 +
 50.1608 +                case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef:
 50.1609 +                mach64_ext_writeb(0xb0 | (port & 3), val, NULL);
 50.1610 +                break;
 50.1611 +
 50.1612 +                case 0x56ec:
 50.1613 +                mach64_ext_writeb(0xb4, val, NULL);
 50.1614 +                break;
 50.1615 +                case 0x56ed: case 0x56ee:
 50.1616 +                mach64_ext_writeb(0xb5, val, NULL);
 50.1617 +                break;
 50.1618 +                case 0x5aec:
 50.1619 +                mach64_ext_writeb(0xb8, val, NULL);
 50.1620 +                break;
 50.1621 +                case 0x5aed: case 0x5aee:
 50.1622 +                mach64_ext_writeb(0xb9, val, NULL);
 50.1623 +                break;
 50.1624 +
 50.1625 +                case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef:
 50.1626 +                ati68860_ramdac_out((port & 3) | ((mach64.dac_cntl & 3) << 2), val, NULL);
 50.1627 +                break;
 50.1628 +
 50.1629 +                case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef:
 50.1630 +                mach64_ext_writeb(0xc4 | (port & 3), val, NULL);
 50.1631 +                break;
 50.1632 +
 50.1633 +                case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef:
 50.1634 +                mach64_ext_writeb(0xd0 | (port & 3), val, NULL);
 50.1635 +                break;
 50.1636 +
 50.1637 +                case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef:
 50.1638 +                WRITE8(port, mach64.config_cntl, val);
 50.1639 +                break;
 50.1640 +        }
 50.1641 +}
 50.1642 +void mach64_ext_outw(uint16_t port, uint16_t val, void *priv)
 50.1643 +{
 50.1644 +#ifdef MACH64_DEBUG
 50.1645 +        pclog("mach64_ext_outw : port %04X val %04X\n", port, val);
 50.1646 +#endif
 50.1647 +        switch (port)
 50.1648 +        {
 50.1649 +                default:
 50.1650 +#ifdef MACH64_DEBUG
 50.1651 +                pclog("  ");
 50.1652 +#endif
 50.1653 +                mach64_ext_outb(port, val, priv);
 50.1654 +#ifdef MACH64_DEBUG
 50.1655 +                pclog("  ");
 50.1656 +#endif
 50.1657 +                mach64_ext_outb(port + 1, val >> 8, priv);
 50.1658 +                break;
 50.1659 +        }
 50.1660 +}
 50.1661 +void mach64_ext_outl(uint16_t port, uint32_t val, void *priv)
 50.1662 +{
 50.1663 +        pclog("mach64_ext_outl : port %04X val %08X\n", port, val);
 50.1664 +        switch (port)
 50.1665 +        {
 50.1666 +                default:
 50.1667 +#ifdef MACH64_DEBUG
 50.1668 +                pclog("  ");
 50.1669 +#endif
 50.1670 +                mach64_ext_outw(port, val, priv);
 50.1671 +#ifdef MACH64_DEBUG
 50.1672 +                pclog("  ");
 50.1673 +#endif
 50.1674 +                mach64_ext_outw(port + 2, val >> 16, priv);
 50.1675 +                break;
 50.1676 +        }
 50.1677 +}
 50.1678 +
 50.1679 +void mach64_write(uint32_t addr, uint8_t val, void *priv)
 50.1680 +{
 50.1681 +//        pclog("mach64_write : %05X %02X  ", addr, val);
 50.1682 +        addr = (addr & 0x7fff) + mach64_bank_w[(addr >> 15) & 1];
 50.1683 +//        pclog("%08X\n", addr);
 50.1684 +        svga_write_linear(addr, val, priv);
 50.1685 +}
 50.1686 +
 50.1687 +uint8_t mach64_read(uint32_t addr, void *priv)
 50.1688 +{
 50.1689 +        uint8_t ret;
 50.1690 +//        pclog("mach64_read : %05X ", addr);
 50.1691 +        addr = (addr & 0x7fff) + mach64_bank_r[(addr >> 15) & 1];
 50.1692 +        ret = svga_read_linear(addr, priv);
 50.1693 +//        pclog("%08X %02X\n", addr, ret);  
 50.1694 +        return ret;      
 50.1695 +}
 50.1696 +
 50.1697 +void mach64_hwcursor_draw(int displine)
 50.1698 +{
 50.1699 +        int x, offset;
 50.1700 +        uint8_t dat;
 50.1701 +        offset = svga_hwcursor_latch.xoff;
 50.1702 +        for (x = 0; x < 64 - svga_hwcursor_latch.xoff; x += 4)
 50.1703 +        {
 50.1704 +                dat = vram[svga_hwcursor_latch.addr + (offset >> 2)];
 50.1705 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32]  = (dat & 1) ? 0xFFFFFF : 0;
 50.1706 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32] ^= 0xFFFFFF;
 50.1707 +                dat >>= 2;
 50.1708 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33]  = (dat & 1) ? 0xFFFFFF : 0;
 50.1709 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33] ^= 0xFFFFFF;
 50.1710 +                dat >>= 2;
 50.1711 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34]  = (dat & 1) ? 0xFFFFFF : 0;
 50.1712 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34] ^= 0xFFFFFF;
 50.1713 +                dat >>= 2;
 50.1714 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35]  = (dat & 1) ? 0xFFFFFF : 0;
 50.1715 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35] ^= 0xFFFFFF;
 50.1716 +                dat >>= 2;
 50.1717 +                offset += 4;
 50.1718 +        }
 50.1719 +        svga_hwcursor_latch.addr += 16;
 50.1720 +}
 50.1721 +
 50.1722 +int mach64_init()
 50.1723 +{
 50.1724 +        int c;
 50.1725 +        
 50.1726 +        svga_recalctimings_ex = mach64_recalctimings;
 50.1727 +        svga_hwcursor_draw    = mach64_hwcursor_draw;
 50.1728 +                
 50.1729 +        svga_vram_limit       = 1 << 22; /*4mb*/
 50.1730 +        vrammask = 0x3fffff;
 50.1731 +        
 50.1732 +        for (c = 0; c < 8; c++)
 50.1733 +        {
 50.1734 +                io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL);
 50.1735 +                io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL);
 50.1736 +                io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL);
 50.1737 +                io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, NULL);                                                
 50.1738 +        }
 50.1739 +
 50.1740 +        io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, NULL);
 50.1741 +        
 50.1742 +        ati_eeprom_load("mach64.nvr", 1);
 50.1743 +
 50.1744 +        mach64.dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/        
 50.1745 +        
 50.1746 +        mach64.dst_cntl = 3;
 50.1747 +        return svga_init();
 50.1748 +}
 50.1749 +
 50.1750 +GFXCARD vid_mach64 =
 50.1751 +{
 50.1752 +        mach64_init,
 50.1753 +        /*IO at 3Cx/3Dx*/
 50.1754 +        mach64_out,
 50.1755 +        mach64_in,
 50.1756 +        /*IO at 3Ax/3Bx*/
 50.1757 +        video_out_null,
 50.1758 +        video_in_null,
 50.1759 +
 50.1760 +        svga_poll,
 50.1761 +        svga_recalctimings,
 50.1762 +
 50.1763 +        svga_write,
 50.1764 +        video_write_null,
 50.1765 +        video_write_null,
 50.1766 +
 50.1767 +        svga_read,
 50.1768 +        video_read_null,
 50.1769 +        video_read_null
 50.1770 +};
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/src/vid_cl5429.c	Mon May 27 19:56:33 2013 +0100
    51.3 @@ -0,0 +1,850 @@
    51.4 +/*Cirrus Logic CL-GD5429 emulation*/
    51.5 +#include "ibm.h"
    51.6 +#include "io.h"
    51.7 +#include "mem.h"
    51.8 +#include "video.h"
    51.9 +#include "vid_svga.h"
   51.10 +#include "vid_svga_render.h"
   51.11 +#include "vid_unk_ramdac.h"
   51.12 +
   51.13 +struct
   51.14 +{
   51.15 +        uint32_t bank[2];
   51.16 +
   51.17 +        struct
   51.18 +        {
   51.19 +                uint16_t bg_col, fg_col;                
   51.20 +                uint16_t width, height;
   51.21 +                uint16_t dst_pitch, src_pitch;               
   51.22 +                uint32_t dst_addr, src_addr;
   51.23 +                uint8_t mask, mode, rop;
   51.24 +                
   51.25 +                uint32_t dst_addr_backup, src_addr_backup;
   51.26 +                uint16_t width_backup, height_internal;
   51.27 +                int x_count;
   51.28 +        } blt;
   51.29 +
   51.30 +} gd5429;
   51.31 +
   51.32 +void gd5429_write(uint32_t addr, uint8_t val, void *priv);
   51.33 +uint8_t gd5429_read(uint32_t addr, void *priv);
   51.34 +
   51.35 +void gd5429_mmio_write(uint32_t addr, uint8_t val, void *priv);
   51.36 +uint8_t gd5429_mmio_read(uint32_t addr, void *priv);
   51.37 +
   51.38 +void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *priv);
   51.39 +void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *priv);
   51.40 +
   51.41 +void gd5429_recalc_banking();
   51.42 +void gd5429_recalc_mapping();
   51.43 +
   51.44 +void gd5429_out(uint16_t addr, uint8_t val, void *priv)
   51.45 +{
   51.46 +        uint8_t old;
   51.47 +        
   51.48 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   51.49 +
   51.50 +        pclog("gd5429 out %04X %02X\n", addr, val);
   51.51 +                
   51.52 +        switch (addr)
   51.53 +        {
   51.54 +                case 0x3c4:
   51.55 +                seqaddr = val;
   51.56 +                break;
   51.57 +                case 0x3c5:
   51.58 +                if (seqaddr > 5)
   51.59 +                {
   51.60 +                        seqregs[seqaddr & 0x1f] = val;
   51.61 +                        switch (seqaddr & 0x1f)
   51.62 +                        {
   51.63 +                                case 0x10: case 0x30: case 0x50: case 0x70:
   51.64 +                                case 0x90: case 0xb0: case 0xd0: case 0xf0:
   51.65 +                                svga_hwcursor.x = (val << 3) | ((seqaddr >> 5) & 7);
   51.66 +                                pclog("svga_hwcursor.x = %i\n", svga_hwcursor.x);
   51.67 +                                break;
   51.68 +                                case 0x11: case 0x31: case 0x51: case 0x71:
   51.69 +                                case 0x91: case 0xb1: case 0xd1: case 0xf1:
   51.70 +                                svga_hwcursor.y = (val << 3) | ((seqaddr >> 5) & 7);
   51.71 +                                pclog("svga_hwcursor.y = %i\n", svga_hwcursor.y);
   51.72 +                                break;
   51.73 +                                case 0x12:
   51.74 +                                svga_hwcursor.ena = val & 1;
   51.75 +                                pclog("svga_hwcursor.ena = %i\n", svga_hwcursor.ena);
   51.76 +                                break;                               
   51.77 +                                case 0x13:
   51.78 +                                svga_hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256);
   51.79 +                                pclog("svga_hwcursor.addr = %x\n", svga_hwcursor.addr);
   51.80 +                                break;                                
   51.81 +                                
   51.82 +                                case 0x17:
   51.83 +                                gd5429_recalc_mapping();
   51.84 +                                break;
   51.85 +                        }
   51.86 +                        return;
   51.87 +                }
   51.88 +                break;
   51.89 +
   51.90 +                case 0x3cf:
   51.91 +                if (gdcaddr == 5)
   51.92 +                {
   51.93 +                        gdcreg[5] = val;
   51.94 +                        if (gdcreg[0xb] & 0x04)
   51.95 +                                writemode = gdcreg[5] & 7;
   51.96 +                        else
   51.97 +                                writemode = gdcreg[5] & 3;
   51.98 +                        readmode = val & 8;
   51.99 +                        pclog("writemode = %i\n", writemode);
  51.100 +                        return;
  51.101 +                }
  51.102 +                if (gdcaddr == 6)
  51.103 +                {
  51.104 +                        if ((gdcreg[6] & 0xc) != (val & 0xc))
  51.105 +                        {
  51.106 +                                gdcreg[6] = val;
  51.107 +                                gd5429_recalc_mapping();
  51.108 +                        }
  51.109 +                        gdcreg[6] = val;
  51.110 +                        return;
  51.111 +                }
  51.112 +                if (gdcaddr > 8)
  51.113 +                {
  51.114 +                        gdcreg[gdcaddr & 0x3f] = val;
  51.115 +                        switch (gdcaddr)
  51.116 +                        {
  51.117 +                                case 0x09: case 0x0a: case 0x0b:
  51.118 +                                gd5429_recalc_banking();
  51.119 +                                if (gdcreg[0xb] & 0x04)
  51.120 +                                        writemode = gdcreg[5] & 7;
  51.121 +                                else
  51.122 +                                        writemode = gdcreg[5] & 3;
  51.123 +                                break;
  51.124 +                        }                        
  51.125 +                        return;
  51.126 +                }
  51.127 +                break;
  51.128 +                
  51.129 +                case 0x3D4:
  51.130 +                crtcreg = val & 0x3f;
  51.131 +                return;
  51.132 +                case 0x3D5:
  51.133 +                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
  51.134 +                old=crtc[crtcreg];
  51.135 +                crtc[crtcreg]=val;
  51.136 +
  51.137 +                if (old!=val)
  51.138 +                {
  51.139 +                        if (crtcreg<0xE || crtcreg>0x10)
  51.140 +                        {
  51.141 +                                fullchange=changeframecount;
  51.142 +                                svga_recalctimings();
  51.143 +                        }
  51.144 +                }
  51.145 +                break;
  51.146 +        }
  51.147 +        svga_out(addr, val, NULL);
  51.148 +}
  51.149 +
  51.150 +uint8_t gd5429_in(uint16_t addr, void *priv)
  51.151 +{
  51.152 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  51.153 +        
  51.154 +        if (addr != 0x3da) pclog("IN gd5429 %04X\n", addr);
  51.155 +        
  51.156 +        switch (addr)
  51.157 +        {
  51.158 +                case 0x3c5:
  51.159 +                if (seqaddr > 5)
  51.160 +                {
  51.161 +                        switch (seqaddr)
  51.162 +                        {
  51.163 +                                case 6:
  51.164 +                                return ((seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f;
  51.165 +                        }
  51.166 +                        return seqregs[seqaddr & 0x3f];
  51.167 +                }
  51.168 +                break;
  51.169 +
  51.170 +                case 0x3cf:
  51.171 +                if (gdcaddr > 8)
  51.172 +                {
  51.173 +                        return gdcreg[seqaddr & 0x3f];
  51.174 +                }
  51.175 +                break;
  51.176 +
  51.177 +                case 0x3D4:
  51.178 +                return crtcreg;
  51.179 +                case 0x3D5:
  51.180 +                switch (crtcreg)
  51.181 +                {
  51.182 +                        case 0x27: /*ID*/
  51.183 +                        return 0x9c; /*GD5429*/
  51.184 +                }
  51.185 +                return crtc[crtcreg];
  51.186 +        }
  51.187 +        return svga_in(addr, NULL);
  51.188 +}
  51.189 +
  51.190 +void gd5429_recalc_banking()
  51.191 +{
  51.192 +        if (gdcreg[0xb] & 0x20)
  51.193 +                gd5429.bank[0] = (gdcreg[0x09] & 0x7f) << 14;
  51.194 +        else
  51.195 +                gd5429.bank[0] = gdcreg[0x09] << 12;
  51.196 +                                
  51.197 +        if (gdcreg[0xb] & 0x01)
  51.198 +        {
  51.199 +                if (gdcreg[0xb] & 0x20)
  51.200 +                        gd5429.bank[1] = (gdcreg[0x0a] & 0x7f) << 14;
  51.201 +                else
  51.202 +                        gd5429.bank[1] = gdcreg[0x0a] << 12;
  51.203 +        }
  51.204 +        else
  51.205 +                gd5429.bank[1] = gd5429.bank[0] + 0x8000;
  51.206 +}
  51.207 +
  51.208 +void gd5429_recalc_mapping()
  51.209 +{
  51.210 +        mem_removehandler(0xa0000, 0x20000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  NULL);
  51.211 +        mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  51.212 +        mem_removehandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL,  NULL);
  51.213 +        pclog("Write mapping %02X %i\n", gdcreg[6], seqregs[0x17] & 0x04);
  51.214 +        switch (gdcreg[6] & 0x0C)
  51.215 +        {
  51.216 +                case 0x0: /*128k at A0000*/
  51.217 +                mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  NULL);
  51.218 +                break;
  51.219 +                case 0x4: /*64k at A0000*/
  51.220 +                mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  NULL);
  51.221 +                if (seqregs[0x17] & 0x04)
  51.222 +                        mem_sethandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL,  NULL);
  51.223 +                break;
  51.224 +                case 0x8: /*32k at B0000*/
  51.225 +                mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  51.226 +                break;
  51.227 +                case 0xC: /*32k at B8000*/
  51.228 +                mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  51.229 +                break;
  51.230 +        }
  51.231 +}
  51.232 +        
  51.233 +void gd5429_recalctimings()
  51.234 +{
  51.235 +        if (seqregs[7] & 0x01)
  51.236 +        {
  51.237 +                svga_render = svga_render_8bpp_highres;
  51.238 +        }
  51.239 +        
  51.240 +        svga_ma |= ((crtc[0x1b] & 0x01) << 16) | ((crtc[0x1b] & 0xc) << 15);
  51.241 +        pclog("MA now %05X %02X\n", svga_ma, crtc[0x1b]);
  51.242 +}
  51.243 +
  51.244 +void gd5429_hwcursor_draw(int displine)
  51.245 +{
  51.246 +        int x;
  51.247 +        uint8_t dat[2];
  51.248 +        int xx;
  51.249 +        int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff;
  51.250 +        
  51.251 +        pclog("HWcursor %i %i  %i %i  %x %02X %02X\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y,  offset, displine, svga_hwcursor_latch.addr, vram[svga_hwcursor_latch.addr], vram[svga_hwcursor_latch.addr + 0x80]);
  51.252 +        for (x = 0; x < 32; x += 8)
  51.253 +        {
  51.254 +                dat[0] = vram[svga_hwcursor_latch.addr];
  51.255 +                dat[1] = vram[svga_hwcursor_latch.addr + 0x80];
  51.256 +                for (xx = 0; xx < 8; xx++)
  51.257 +                {
  51.258 +                        if (offset >= svga_hwcursor_latch.x)
  51.259 +                        {
  51.260 +                                if (dat[1] & 0x80)
  51.261 +                                        ((uint32_t *)buffer32->line[displine])[offset + 32] = 0;
  51.262 +                                if (dat[0] & 0x80)
  51.263 +                                        ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
  51.264 +                        }
  51.265 +                           
  51.266 +                        offset++;
  51.267 +                        dat[0] <<= 1;
  51.268 +                        dat[1] <<= 1;
  51.269 +                }
  51.270 +                svga_hwcursor_latch.addr++;
  51.271 +        }
  51.272 +}
  51.273 +
  51.274 +int gd5429_init()
  51.275 +{
  51.276 +        svga_recalctimings_ex = gd5429_recalctimings;
  51.277 +        svga_hwcursor_draw    = gd5429_hwcursor_draw;
  51.278 +        svga_vram_limit = 2 << 20; /*2mb*/
  51.279 +        vrammask = 0x1fffff;
  51.280 +
  51.281 +        svga_hwcursor.yoff = 32;
  51.282 +        svga_hwcursor.xoff = 0;
  51.283 +
  51.284 +        memset(&gd5429, 0, sizeof(gd5429));
  51.285 +        
  51.286 +        gd5429.bank[1] = 0x8000;
  51.287 +        
  51.288 +        return svga_init();
  51.289 +}
  51.290 +
  51.291 +static uint8_t la, lb, lc, ld;
  51.292 +
  51.293 +uint8_t gd5429_read_linear(uint32_t addr, void *priv);
  51.294 +void gd5429_write_linear(uint32_t addr, uint8_t val, void *priv);
  51.295 +
  51.296 +void gd5429_write(uint32_t addr, uint8_t val, void *priv)
  51.297 +{
  51.298 +//        pclog("gd5429_write : %05X %02X  ", addr, val);
  51.299 +        addr = (addr & 0x7fff) + gd5429.bank[(addr >> 15) & 1];
  51.300 +//        pclog("%08X\n", addr);
  51.301 +        gd5429_write_linear(addr, val, priv);
  51.302 +}
  51.303 +
  51.304 +uint8_t gd5429_read(uint32_t addr, void *priv)
  51.305 +{
  51.306 +        uint8_t ret;
  51.307 +//        pclog("gd5429_read : %05X ", addr);
  51.308 +        addr = (addr & 0x7fff) + gd5429.bank[(addr >> 15) & 1];
  51.309 +        ret = gd5429_read_linear(addr, priv);
  51.310 +//        pclog("%08X %02X\n", addr, ret);  
  51.311 +        return ret;      
  51.312 +}
  51.313 +
  51.314 +void gd5429_write_linear(uint32_t addr, uint8_t val, void *priv)
  51.315 +{
  51.316 +        uint8_t vala,valb,valc,vald,wm=writemask;
  51.317 +        int writemask2 = writemask;
  51.318 +
  51.319 +        cycles -= video_timing_b;
  51.320 +        cycles_lost += video_timing_b;
  51.321 +
  51.322 +        egawrites++;
  51.323 +        
  51.324 +//        if (svga_output) pclog("Write LFB %08X %02X ", addr, val);
  51.325 +        if (!(gdcreg[6]&1)) fullchange=2;
  51.326 +        if (chain4 && (writemode < 4))
  51.327 +        {
  51.328 +                writemask2=1<<(addr&3);
  51.329 +                addr&=~3;
  51.330 +        }
  51.331 +        else
  51.332 +        {
  51.333 +                addr<<=2;
  51.334 +        }
  51.335 +        addr &= 0x7fffff;
  51.336 +//        if (svga_output) pclog("%08X\n", addr);
  51.337 +        changedvram[addr>>10]=changeframecount;
  51.338 +        
  51.339 +        switch (writemode)
  51.340 +        {
  51.341 +                case 4:
  51.342 +                pclog("Writemode 4 : %X ", addr);
  51.343 +                addr <<= 1;
  51.344 +                changedvram[addr>>10]=changeframecount;
  51.345 +                pclog("%X %X\n", addr, val);
  51.346 +                if (val & 0x80)
  51.347 +                        vram[addr + 0] = gdcreg[1];
  51.348 +                if (val & 0x40)
  51.349 +                        vram[addr + 1] = gdcreg[1];
  51.350 +                if (val & 0x20)
  51.351 +                        vram[addr + 2] = gdcreg[1];
  51.352 +                if (val & 0x10)
  51.353 +                        vram[addr + 3] = gdcreg[1];
  51.354 +                if (val & 0x08)
  51.355 +                        vram[addr + 4] = gdcreg[1];
  51.356 +                if (val & 0x04)
  51.357 +                        vram[addr + 5] = gdcreg[1];
  51.358 +                if (val & 0x02)
  51.359 +                        vram[addr + 6] = gdcreg[1];
  51.360 +                if (val & 0x01)
  51.361 +                        vram[addr + 7] = gdcreg[1];
  51.362 +                break;
  51.363 +                        
  51.364 +                case 5:
  51.365 +                pclog("Writemode 5 : %X ", addr);
  51.366 +                addr <<= 1;
  51.367 +                changedvram[addr>>10]=changeframecount;
  51.368 +                pclog("%X %X\n", addr, val);
  51.369 +                vram[addr + 0] = (val & 0x80) ? gdcreg[1] : gdcreg[0];
  51.370 +                vram[addr + 1] = (val & 0x40) ? gdcreg[1] : gdcreg[0];
  51.371 +                vram[addr + 2] = (val & 0x20) ? gdcreg[1] : gdcreg[0];
  51.372 +                vram[addr + 3] = (val & 0x10) ? gdcreg[1] : gdcreg[0];
  51.373 +                vram[addr + 4] = (val & 0x08) ? gdcreg[1] : gdcreg[0];
  51.374 +                vram[addr + 5] = (val & 0x04) ? gdcreg[1] : gdcreg[0];
  51.375 +                vram[addr + 6] = (val & 0x02) ? gdcreg[1] : gdcreg[0];
  51.376 +                vram[addr + 7] = (val & 0x01) ? gdcreg[1] : gdcreg[0];
  51.377 +                break;
  51.378 +                
  51.379 +                case 1:
  51.380 +                if (writemask2&1) vram[addr]=la;
  51.381 +                if (writemask2&2) vram[addr|0x1]=lb;
  51.382 +                if (writemask2&4) vram[addr|0x2]=lc;
  51.383 +                if (writemask2&8) vram[addr|0x3]=ld;
  51.384 +                break;
  51.385 +                case 0:
  51.386 +                if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val];
  51.387 +                if (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1])
  51.388 +                {
  51.389 +                        if (writemask2&1) vram[addr]=val;
  51.390 +                        if (writemask2&2) vram[addr|0x1]=val;
  51.391 +                        if (writemask2&4) vram[addr|0x2]=val;
  51.392 +                        if (writemask2&8) vram[addr|0x3]=val;
  51.393 +                }
  51.394 +                else
  51.395 +                {
  51.396 +                        if (gdcreg[1]&1) vala=(gdcreg[0]&1)?0xFF:0;
  51.397 +                        else             vala=val;
  51.398 +                        if (gdcreg[1]&2) valb=(gdcreg[0]&2)?0xFF:0;
  51.399 +                        else             valb=val;
  51.400 +                        if (gdcreg[1]&4) valc=(gdcreg[0]&4)?0xFF:0;
  51.401 +                        else             valc=val;
  51.402 +                        if (gdcreg[1]&8) vald=(gdcreg[0]&8)?0xFF:0;
  51.403 +                        else             vald=val;
  51.404 +
  51.405 +                        switch (gdcreg[3]&0x18)
  51.406 +                        {
  51.407 +                                case 0: /*Set*/
  51.408 +                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
  51.409 +                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
  51.410 +                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
  51.411 +                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
  51.412 +                                break;
  51.413 +                                case 8: /*AND*/
  51.414 +                                if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
  51.415 +                                if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
  51.416 +                                if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
  51.417 +                                if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
  51.418 +                                break;
  51.419 +                                case 0x10: /*OR*/
  51.420 +                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
  51.421 +                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
  51.422 +                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
  51.423 +                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
  51.424 +                                break;
  51.425 +                                case 0x18: /*XOR*/
  51.426 +                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
  51.427 +                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
  51.428 +                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
  51.429 +                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
  51.430 +                                break;
  51.431 +                        }
  51.432 +//                        pclog("- %02X %02X %02X %02X   %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr);
  51.433 +                }
  51.434 +                break;
  51.435 +                case 2:
  51.436 +                if (!(gdcreg[3]&0x18) && !gdcreg[1])
  51.437 +                {
  51.438 +                        if (writemask2&1) vram[addr]=(((val&1)?0xFF:0)&gdcreg[8])|(la&~gdcreg[8]);
  51.439 +                        if (writemask2&2) vram[addr|0x1]=(((val&2)?0xFF:0)&gdcreg[8])|(lb&~gdcreg[8]);
  51.440 +                        if (writemask2&4) vram[addr|0x2]=(((val&4)?0xFF:0)&gdcreg[8])|(lc&~gdcreg[8]);
  51.441 +                        if (writemask2&8) vram[addr|0x3]=(((val&8)?0xFF:0)&gdcreg[8])|(ld&~gdcreg[8]);
  51.442 +                }
  51.443 +                else
  51.444 +                {
  51.445 +                        vala=((val&1)?0xFF:0);
  51.446 +                        valb=((val&2)?0xFF:0);
  51.447 +                        valc=((val&4)?0xFF:0);
  51.448 +                        vald=((val&8)?0xFF:0);
  51.449 +                        switch (gdcreg[3]&0x18)
  51.450 +                        {
  51.451 +                                case 0: /*Set*/
  51.452 +                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
  51.453 +                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
  51.454 +                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
  51.455 +                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
  51.456 +                                break;
  51.457 +                                case 8: /*AND*/
  51.458 +                                if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
  51.459 +                                if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
  51.460 +                                if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
  51.461 +                                if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
  51.462 +                                break;
  51.463 +                                case 0x10: /*OR*/
  51.464 +                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
  51.465 +                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
  51.466 +                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
  51.467 +                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
  51.468 +                                break;
  51.469 +                                case 0x18: /*XOR*/
  51.470 +                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
  51.471 +                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
  51.472 +                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
  51.473 +                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
  51.474 +                                break;
  51.475 +                        }
  51.476 +                }
  51.477 +                break;
  51.478 +                case 3:
  51.479 +                if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val];
  51.480 +                wm=gdcreg[8];
  51.481 +                gdcreg[8]&=val;
  51.482 +
  51.483 +                vala=(gdcreg[0]&1)?0xFF:0;
  51.484 +                valb=(gdcreg[0]&2)?0xFF:0;
  51.485 +                valc=(gdcreg[0]&4)?0xFF:0;
  51.486 +                vald=(gdcreg[0]&8)?0xFF:0;
  51.487 +                switch (gdcreg[3]&0x18)
  51.488 +                {
  51.489 +                        case 0: /*Set*/
  51.490 +                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
  51.491 +                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
  51.492 +                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
  51.493 +                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
  51.494 +                        break;
  51.495 +                        case 8: /*AND*/
  51.496 +                        if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
  51.497 +                        if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
  51.498 +                        if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
  51.499 +                        if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
  51.500 +                        break;
  51.501 +                        case 0x10: /*OR*/
  51.502 +                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
  51.503 +                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
  51.504 +                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
  51.505 +                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
  51.506 +                        break;
  51.507 +                        case 0x18: /*XOR*/
  51.508 +                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
  51.509 +                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
  51.510 +                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
  51.511 +                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
  51.512 +                        break;
  51.513 +                }
  51.514 +                gdcreg[8]=wm;
  51.515 +                break;
  51.516 +        }
  51.517 +}
  51.518 +
  51.519 +uint8_t gd5429_read_linear(uint32_t addr, void *priv)
  51.520 +{
  51.521 +        uint8_t temp,temp2,temp3,temp4;
  51.522 +  
  51.523 +        cycles -= video_timing_b;
  51.524 +        cycles_lost += video_timing_b;
  51.525 +
  51.526 +        egareads++;
  51.527 +        
  51.528 +        if (chain4) 
  51.529 +        { 
  51.530 +                addr &= 0x7fffff;
  51.531 +                if (addr >= svga_vram_limit)
  51.532 +                   return 0xff;
  51.533 +                return vram[addr & 0x7fffff]; 
  51.534 +        }
  51.535 +        else        addr<<=2;
  51.536 +
  51.537 +        addr &= 0x7fffff;
  51.538 +        
  51.539 +        if (addr >= svga_vram_limit)
  51.540 +           return 0xff;
  51.541 +
  51.542 +        la=vram[addr];
  51.543 +        lb=vram[addr|0x1];
  51.544 +        lc=vram[addr|0x2];
  51.545 +        ld=vram[addr|0x3];
  51.546 +        if (readmode)
  51.547 +        {
  51.548 +                temp= (colournocare&1) ?0xFF:0;
  51.549 +                temp&=la;
  51.550 +                temp^=(colourcompare&1)?0xFF:0;
  51.551 +                temp2= (colournocare&2) ?0xFF:0;
  51.552 +                temp2&=lb;
  51.553 +                temp2^=(colourcompare&2)?0xFF:0;
  51.554 +                temp3= (colournocare&4) ?0xFF:0;
  51.555 +                temp3&=lc;
  51.556 +                temp3^=(colourcompare&4)?0xFF:0;
  51.557 +                temp4= (colournocare&8) ?0xFF:0;
  51.558 +                temp4&=ld;
  51.559 +                temp4^=(colourcompare&8)?0xFF:0;
  51.560 +                return ~(temp|temp2|temp3|temp4);
  51.561 +        }
  51.562 +//printf("Read %02X %04X %04X\n",vram[addr|readplane],addr,readplane);
  51.563 +        return vram[addr|readplane];
  51.564 +}
  51.565 +
  51.566 +void gd5429_start_blit(uint32_t cpu_dat, int count)
  51.567 +{
  51.568 +        pclog("gd5429_start_blit %i\n", count);
  51.569 +        if (count == -1)
  51.570 +        {
  51.571 +                gd5429.blt.dst_addr_backup = gd5429.blt.dst_addr;
  51.572 +                gd5429.blt.src_addr_backup = gd5429.blt.src_addr;
  51.573 +                gd5429.blt.width_backup    = gd5429.blt.width;
  51.574 +                gd5429.blt.height_internal = gd5429.blt.height;
  51.575 +                gd5429.blt.x_count         = gd5429.blt.mask & 7;
  51.576 +                pclog("gd5429_start_blit : size %i, %i\n", gd5429.blt.width, gd5429.blt.height);
  51.577 +                
  51.578 +                if (gd5429.blt.mode & 0x04)
  51.579 +                {
  51.580 +//                        pclog("blt.mode & 0x04\n");
  51.581 +                        mem_removehandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  NULL);
  51.582 +                        mem_sethandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l,  NULL);
  51.583 +                        return;
  51.584 +                }
  51.585 +                else
  51.586 +                {
  51.587 +                        mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l,  NULL);
  51.588 +                        gd5429_recalc_mapping();
  51.589 +                }                
  51.590 +        }
  51.591 +        
  51.592 +        while (count)
  51.593 +        {
  51.594 +                uint8_t src, dst;
  51.595 +                int mask;
  51.596 +                
  51.597 +                if (gd5429.blt.mode & 0x04)
  51.598 +                {
  51.599 +                        if (gd5429.blt.mode & 0x80)
  51.600 +                        {
  51.601 +                                src = (cpu_dat & 0x80) ? gd5429.blt.fg_col : gd5429.blt.bg_col;
  51.602 +                                mask = cpu_dat & 0x80;
  51.603 +                                cpu_dat <<= 1;
  51.604 +                                count--;
  51.605 +                        }
  51.606 +                        else
  51.607 +                        {
  51.608 +                                src = cpu_dat & 0xff;
  51.609 +                                cpu_dat >>= 8;
  51.610 +                                count -= 8;
  51.611 +                                mask = 1;
  51.612 +                        }
  51.613 +                }
  51.614 +                else
  51.615 +                {
  51.616 +                        switch (gd5429.blt.mode & 0xc0)
  51.617 +                        {
  51.618 +                                case 0x00:
  51.619 +                                src = vram[gd5429.blt.src_addr & vrammask];
  51.620 +                                gd5429.blt.src_addr += ((gd5429.blt.mode & 0x01) ? -1 : 1);
  51.621 +                                mask = 1;
  51.622 +                                break;
  51.623 +                                case 0x40:
  51.624 +                                src = vram[(gd5429.blt.src_addr & (vrammask & ~7)) | (gd5429.blt.dst_addr & 7)];
  51.625 +                                mask = 1;
  51.626 +                                break;
  51.627 +                                case 0x80:
  51.628 +                                mask = vram[gd5429.blt.src_addr & vrammask] & (0x80 >> gd5429.blt.x_count);
  51.629 +                                src = mask ? gd5429.blt.fg_col : gd5429.blt.bg_col;
  51.630 +                                gd5429.blt.x_count++;
  51.631 +                                if (gd5429.blt.x_count == 8)
  51.632 +                                {
  51.633 +                                        gd5429.blt.x_count = 0;
  51.634 +                                        gd5429.blt.src_addr++;
  51.635 +                                }
  51.636 +                                break;
  51.637 +                                case 0xc0:
  51.638 +                                mask = vram[gd5429.blt.src_addr & vrammask] & (0x80 >> (gd5429.blt.dst_addr & 7));
  51.639 +                                src = mask ? gd5429.blt.fg_col : gd5429.blt.bg_col;
  51.640 +                                break;
  51.641 +                        }
  51.642 +                        count--;                        
  51.643 +                }
  51.644 +                dst = vram[gd5429.blt.dst_addr & vrammask];
  51.645 +                changedvram[(gd5429.blt.dst_addr & vrammask) >> 10] = changeframecount;
  51.646 +               
  51.647 +                pclog("Blit %i,%i %06X %06X  %06X %02X %02X  %02X %02X ", gd5429.blt.width, gd5429.blt.height_internal, gd5429.blt.src_addr, gd5429.blt.dst_addr, gd5429.blt.src_addr & vrammask, vram[gd5429.blt.src_addr & vrammask], 0x80 >> (gd5429.blt.dst_addr & 7), src, dst);
  51.648 +                switch (gd5429.blt.rop)
  51.649 +                {
  51.650 +                        case 0x00: dst = 0;             break;
  51.651 +                        case 0x05: dst =   src &  dst;  break;
  51.652 +                        case 0x06: dst =   dst;         break;
  51.653 +                        case 0x09: dst =   src & ~dst;  break;
  51.654 +                        case 0x0b: dst = ~ dst;         break;
  51.655 +                        case 0x0d: dst =   src;         break;
  51.656 +                        case 0x0e: dst = 0xff;          break;
  51.657 +                        case 0x50: dst = ~ src &  dst;  break;
  51.658 +                        case 0x59: dst =   src ^  dst;  break;
  51.659 +                        case 0x6d: dst =   src |  dst;  break;
  51.660 +                        case 0x90: dst = ~(src |  dst); break;
  51.661 +                        case 0x95: dst = ~(src ^  dst); break;
  51.662 +                        case 0xad: dst =   src | ~dst;  break;
  51.663 +                        case 0xd0: dst =  ~src;         break;
  51.664 +                        case 0xd6: dst =  ~src |  dst;  break;
  51.665 +                        case 0xda: dst = ~(src &  dst); break;                       
  51.666 +                }
  51.667 +                pclog("%02X  %02X\n", dst, mask);
  51.668 +                
  51.669 +                if ((gd5429.blt.width_backup - gd5429.blt.width) >= (gd5429.blt.mask & 7) &&
  51.670 +                    !((gd5429.blt.mode & 0x08) && !mask))
  51.671 +                        vram[gd5429.blt.dst_addr & vrammask] = dst;
  51.672 +                
  51.673 +                gd5429.blt.dst_addr += ((gd5429.blt.mode & 0x01) ? -1 : 1);
  51.674 +                
  51.675 +                gd5429.blt.width--;
  51.676 +                
  51.677 +                if (gd5429.blt.width == 0xffff)
  51.678 +                {
  51.679 +                        gd5429.blt.width = gd5429.blt.width_backup;
  51.680 +
  51.681 +                        gd5429.blt.dst_addr = gd5429.blt.dst_addr_backup = gd5429.blt.dst_addr_backup + ((gd5429.blt.mode & 0x01) ? -gd5429.blt.dst_pitch : gd5429.blt.dst_pitch);                        
  51.682 +                        
  51.683 +                        switch (gd5429.blt.mode & 0xc0)
  51.684 +                        {
  51.685 +                                case 0x00:
  51.686 +                                gd5429.blt.src_addr = gd5429.blt.src_addr_backup = gd5429.blt.src_addr_backup + ((gd5429.blt.mode & 0x01) ? -gd5429.blt.src_pitch : gd5429.blt.src_pitch);
  51.687 +                                break;
  51.688 +                                case 0x40:
  51.689 +                                gd5429.blt.src_addr = ((gd5429.blt.src_addr + ((gd5429.blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429.blt.src_addr & ~0x38);
  51.690 +                                break;
  51.691 +                                case 0x80:
  51.692 +                                if (gd5429.blt.x_count != 0)
  51.693 +                                {
  51.694 +                                        gd5429.blt.x_count = 0;
  51.695 +                                        gd5429.blt.src_addr++;
  51.696 +                                }
  51.697 +                                break;
  51.698 +                                case 0xc0:
  51.699 +                                gd5429.blt.src_addr = ((gd5429.blt.src_addr + ((gd5429.blt.mode & 0x01) ? -1 : 1)) & 7) | (gd5429.blt.src_addr & ~7);
  51.700 +                                break;
  51.701 +                        }
  51.702 +                        
  51.703 +                        gd5429.blt.height_internal--;
  51.704 +                        if (gd5429.blt.height_internal == 0xffff)
  51.705 +                        {
  51.706 +                                if (gd5429.blt.mode & 0x04)
  51.707 +                                {
  51.708 +                                        mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l,  NULL);
  51.709 +                                        gd5429_recalc_mapping();
  51.710 +                                }
  51.711 +                                return;
  51.712 +                        }
  51.713 +                                
  51.714 +                        if (gd5429.blt.mode & 0x04)
  51.715 +                                return;
  51.716 +                }                        
  51.717 +        }
  51.718 +}
  51.719 +
  51.720 +void gd5429_mmio_write(uint32_t addr, uint8_t val, void *priv)
  51.721 +{
  51.722 +        pclog("MMIO write %08X %02X\n", addr, val);
  51.723 +        switch (addr & 0xff)
  51.724 +        {
  51.725 +                case 0x00:
  51.726 +                gd5429.blt.bg_col = (gd5429.blt.bg_col & 0xff00) | val;
  51.727 +                break;
  51.728 +                case 0x01:
  51.729 +                gd5429.blt.bg_col = (gd5429.blt.bg_col & 0x00ff) | (val << 8);
  51.730 +                break;
  51.731 +
  51.732 +                case 0x04:
  51.733 +                gd5429.blt.fg_col = (gd5429.blt.fg_col & 0xff00) | val;
  51.734 +                break;
  51.735 +                case 0x05:
  51.736 +                gd5429.blt.fg_col = (gd5429.blt.fg_col & 0x00ff) | (val << 8);
  51.737 +                break;
  51.738 +
  51.739 +                case 0x08:
  51.740 +                gd5429.blt.width = (gd5429.blt.width & 0xff00) | val;
  51.741 +                break;
  51.742 +                case 0x09:
  51.743 +                gd5429.blt.width = (gd5429.blt.width & 0x00ff) | (val << 8);
  51.744 +                break;
  51.745 +                case 0x0a:
  51.746 +                gd5429.blt.height = (gd5429.blt.height & 0xff00) | val;
  51.747 +                break;
  51.748 +                case 0x0b:
  51.749 +                gd5429.blt.height = (gd5429.blt.height & 0x00ff) | (val << 8);
  51.750 +                break;
  51.751 +                case 0x0c:
  51.752 +                gd5429.blt.dst_pitch = (gd5429.blt.dst_pitch & 0xff00) | val;
  51.753 +                break;
  51.754 +                case 0x0d:
  51.755 +                gd5429.blt.dst_pitch = (gd5429.blt.dst_pitch & 0x00ff) | (val << 8);
  51.756 +                break;
  51.757 +                case 0x0e:
  51.758 +                gd5429.blt.src_pitch = (gd5429.blt.src_pitch & 0xff00) | val;
  51.759 +                break;
  51.760 +                case 0x0f:
  51.761 +                gd5429.blt.src_pitch = (gd5429.blt.src_pitch & 0x00ff) | (val << 8);
  51.762 +                break;
  51.763 +                
  51.764 +                case 0x10:
  51.765 +                gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0xffff00) | val;
  51.766 +                break;
  51.767 +                case 0x11:
  51.768 +                gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0xff00ff) | (val << 8);
  51.769 +                break;
  51.770 +                case 0x12:
  51.771 +                gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0x00ffff) | (val << 16);
  51.772 +                break;
  51.773 +
  51.774 +                case 0x14:
  51.775 +                gd5429.blt.src_addr = (gd5429.blt.src_addr & 0xffff00) | val;
  51.776 +                break;
  51.777 +                case 0x15:
  51.778 +                gd5429.blt.src_addr = (gd5429.blt.src_addr & 0xff00ff) | (val << 8);
  51.779 +                break;
  51.780 +                case 0x16:
  51.781 +                gd5429.blt.src_addr = (gd5429.blt.src_addr & 0x00ffff) | (val << 16);
  51.782 +                break;
  51.783 +
  51.784 +                case 0x17:
  51.785 +                gd5429.blt.mask = val;
  51.786 +                break;
  51.787 +                case 0x18:
  51.788 +                gd5429.blt.mode = val;
  51.789 +                break;
  51.790 +                
  51.791 +                case 0x1a:
  51.792 +                gd5429.blt.rop = val;
  51.793 +                break;
  51.794 +                
  51.795 +                case 0x40:
  51.796 +                if (val & 0x02)
  51.797 +                        gd5429_start_blit(0, -1);
  51.798 +                break;
  51.799 +        }
  51.800 +}
  51.801 +
  51.802 +uint8_t gd5429_mmio_read(uint32_t addr, void *priv)
  51.803 +{
  51.804 +        pclog("MMIO read %08X\n", addr);
  51.805 +        switch (addr & 0xff)
  51.806 +        {
  51.807 +                case 0x40: /*BLT status*/
  51.808 +                return 0;
  51.809 +        }
  51.810 +        return 0xff; /*All other registers read-only*/
  51.811 +}
  51.812 +
  51.813 +void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *priv)
  51.814 +{
  51.815 +        pclog("gd5429_blt_write_w %08X %08X\n", addr, val);
  51.816 +        gd5429_start_blit(val, 16);
  51.817 +}
  51.818 +
  51.819 +void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *priv)
  51.820 +{
  51.821 +        pclog("gd5429_blt_write_l %08X %08X  %04X %04X\n", addr, val,  ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00));
  51.822 +        if ((gd5429.blt.mode & 0x84) == 0x84)
  51.823 +        {
  51.824 +                gd5429_start_blit( val        & 0xff, 8);
  51.825 +                gd5429_start_blit((val >> 8)  & 0xff, 8);
  51.826 +                gd5429_start_blit((val >> 16) & 0xff, 8);
  51.827 +                gd5429_start_blit((val >> 24) & 0xff, 8);
  51.828 +        }
  51.829 +        else
  51.830 +                gd5429_start_blit(val, 32);
  51.831 +}
  51.832 +
  51.833 +GFXCARD vid_gd5429 =
  51.834 +{
  51.835 +        gd5429_init,
  51.836 +        /*IO at 3Cx/3Dx*/
  51.837 +        gd5429_out,
  51.838 +        gd5429_in,
  51.839 +        /*IO at 3Ax/3Bx*/
  51.840 +        video_out_null,
  51.841 +        video_in_null,
  51.842 +
  51.843 +        svga_poll,
  51.844 +        svga_recalctimings,
  51.845 +
  51.846 +        svga_write,
  51.847 +        video_write_null,
  51.848 +        video_write_null,
  51.849 +
  51.850 +        svga_read,
  51.851 +        video_read_null,
  51.852 +        video_read_null
  51.853 +};
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/src/vid_ics2595.c	Mon May 27 19:56:33 2013 +0100
    52.3 @@ -0,0 +1,63 @@
    52.4 +/*ICS2595 clock chip emulation
    52.5 +  Used by ATI Mach64*/
    52.6 +
    52.7 +#include "ibm.h"
    52.8 +#include "vid_ics2595.h"
    52.9 +
   52.10 +enum
   52.11 +{
   52.12 +        ICS2595_IDLE,
   52.13 +        ICS2595_WRITE,
   52.14 +        ICS2595_READ
   52.15 +};
   52.16 +
   52.17 +static int ics2595_oldfs3, ics2595_oldfs2;
   52.18 +static int ics2595_dat;
   52.19 +static int ics2595_pos;
   52.20 +static int ics2595_state = ICS2595_IDLE;
   52.21 +
   52.22 +static int ics2595_div[4] = {8, 4, 2, 1};
   52.23 +
   52.24 +static double ics2595_clocks[16];
   52.25 +double ics2595_output_clock;
   52.26 +
   52.27 +void ics2595_write(int strobe, int dat)
   52.28 +{
   52.29 +        pclog("ics2595_write : %i %i\n", strobe, dat);
   52.30 +        if (strobe)
   52.31 +        {
   52.32 +                if ((dat & 8) && !ics2595_oldfs3) /*Data clock*/
   52.33 +                {
   52.34 +                        pclog(" - new dat %i\n", dat & 4);
   52.35 +                        switch (ics2595_state)
   52.36 +                        {
   52.37 +                                case ICS2595_IDLE:
   52.38 +                                ics2595_state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE;
   52.39 +                                ics2595_pos = 0;
   52.40 +                                break;
   52.41 +                                case ICS2595_WRITE:
   52.42 +                                ics2595_dat = (ics2595_dat >> 1);
   52.43 +                                if (dat & 4)
   52.44 +                                        ics2595_dat |= (1 << 19);
   52.45 +                                ics2595_pos++;
   52.46 +                                if (ics2595_pos == 20)
   52.47 +                                {
   52.48 +                                        int d, n, l;
   52.49 +                                        pclog("ICS2595_WRITE : dat %08X\n", ics2595_dat);
   52.50 +                                        l = (ics2595_dat >> 2) & 31;
   52.51 +                                        n = ((ics2595_dat >> 7) & 255) + 257;
   52.52 +                                        d = ics2595_div[(ics2595_dat >> 16) & 3];
   52.53 +
   52.54 +                                        ics2595_clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d;
   52.55 +                                        pclog("ICS2595 clock set - L %i N %i D %i freq = %f\n", l, n, d, (14318181.8 * ((double)n / 46.0)) / (double)d);
   52.56 +                                        ics2595_state = ICS2595_IDLE;
   52.57 +                                }
   52.58 +                                break;                                                
   52.59 +                        }
   52.60 +                }
   52.61 +                        
   52.62 +                ics2595_oldfs2 = dat & 4;
   52.63 +                ics2595_oldfs3 = dat & 8;
   52.64 +        }
   52.65 +        ics2595_output_clock = ics2595_clocks[dat];
   52.66 +}
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/src/vid_ics2595.h	Mon May 27 19:56:33 2013 +0100
    53.3 @@ -0,0 +1,2 @@
    53.4 +void ics2595_write(int strobe, int dat);
    53.5 +extern double ics2595_output_clock;
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/src/vid_s3_virge.c	Mon May 27 19:56:33 2013 +0100
    54.3 @@ -0,0 +1,467 @@
    54.4 +/*S3 ViRGE emulation
    54.5 +
    54.6 +  The SVGA core is largely the same as older S3 chips, but the blitter is totally different*/
    54.7 +#include "ibm.h"
    54.8 +#include "io.h"
    54.9 +#include "mem.h"
   54.10 +#include "pci.h"
   54.11 +#include "video.h"
   54.12 +#include "vid_svga.h"
   54.13 +#include "vid_svga_render.h"
   54.14 +//#include "vid_sdac_ramdac.h"
   54.15 +
   54.16 +void s3_virge_updatemapping();
   54.17 +
   54.18 +static uint8_t s3_bank;
   54.19 +static uint8_t s3_ma_ext;
   54.20 +static int s3_width = 1024;
   54.21 +static int s3_bpp = 0;
   54.22 +
   54.23 +static uint8_t s3_virge_id, s3_virge_id_high, s3_virge_id_low, s3_virge_rev;
   54.24 +
   54.25 +uint8_t  s3_virge_mmio_read(uint32_t addr, void *priv);
   54.26 +uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv);
   54.27 +uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv);
   54.28 +void     s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv);
   54.29 +void     s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv);
   54.30 +void     s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv);
   54.31 +
   54.32 +void s3_virge_out(uint16_t addr, uint8_t val, void *priv)
   54.33 +{
   54.34 +        uint8_t old;
   54.35 +
   54.36 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   54.37 +        
   54.38 +        pclog("S3 out %04X %02X %04X:%08X  %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins);
   54.39 +
   54.40 +        switch (addr)
   54.41 +        {
   54.42 +                case 0x3c5:
   54.43 +                if (seqaddr >= 0x10)
   54.44 +                {
   54.45 +                        seqregs[seqaddr&0x1F]=val;
   54.46 +                        return;
   54.47 +                }
   54.48 +                if (seqaddr == 4) /*Chain-4 - update banking*/
   54.49 +                {
   54.50 +                        if (val & 8) svgawbank = svgarbank = s3_bank << 16;
   54.51 +                        else         svgawbank = svgarbank = s3_bank << 14;
   54.52 +                }
   54.53 +                break;
   54.54 +                
   54.55 +                //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
   54.56 +//                pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc);
   54.57 +                //sdac_ramdac_out(addr,val);
   54.58 +                //return;
   54.59 +
   54.60 +                case 0x3D4:
   54.61 +                crtcreg=val&0x7f;
   54.62 +                return;
   54.63 +                case 0x3D5:
   54.64 +//                        if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val);
   54.65 +                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
   54.66 +                if (crtcreg >= 0x20 && crtcreg != 0x38 && (crtc[0x38] & 0xcc) != 0x48) return;
   54.67 +                old=crtc[crtcreg];
   54.68 +                crtc[crtcreg]=val;
   54.69 +                switch (crtcreg)
   54.70 +                {
   54.71 +                        case 0x31:
   54.72 +                        s3_ma_ext = (s3_ma_ext & 0x1c) | ((val & 0x30) >> 4);
   54.73 +                        vrammask = (val & 8) ? 0x3fffff : 0x3ffff;
   54.74 +                        break;
   54.75 +                        
   54.76 +                        case 0x50:
   54.77 +                        switch (crtc[0x50] & 0xc1)
   54.78 +                        {
   54.79 +                                case 0x00: s3_width = (crtc[0x31] & 2) ? 2048 : 1024; break;
   54.80 +                                case 0x01: s3_width = 1152; break;
   54.81 +                                case 0x40: s3_width = 640;  break;
   54.82 +                                case 0x80: s3_width = 800;  break;
   54.83 +                                case 0x81: s3_width = 1600; break;
   54.84 +                                case 0xc0: s3_width = 1280; break;
   54.85 +                        }
   54.86 +                        s3_bpp = (crtc[0x50] >> 4) & 3;
   54.87 +                        break;
   54.88 +                        case 0x69:
   54.89 +                        s3_ma_ext = val & 0x1f;
   54.90 +                        break;
   54.91 +                        
   54.92 +                        case 0x35:
   54.93 +                        s3_bank = (s3_bank & 0x70) | (val & 0xf);
   54.94 +//                        pclog("CRTC write R35 %02X\n", val);
   54.95 +                        if (chain4) svgawbank = svgarbank = s3_bank << 16;
   54.96 +                        else        svgawbank = svgarbank = s3_bank << 14;
   54.97 +                        break;
   54.98 +                        case 0x51:
   54.99 +                        s3_bank = (s3_bank & 0x4f) | ((val & 0xc) << 2);
  54.100 +                        if (chain4) svgawbank = svgarbank = s3_bank << 16;
  54.101 +                        else        svgawbank = svgarbank = s3_bank << 14;
  54.102 +                        s3_ma_ext = (s3_ma_ext & ~0xc) | ((val & 3) << 2);
  54.103 +                        break;
  54.104 +                        case 0x6a:
  54.105 +                        s3_bank = val;
  54.106 +//                        pclog("CRTC write R6a %02X\n", val);
  54.107 +                        if (chain4) svgawbank = svgarbank = s3_bank << 16;
  54.108 +                        else        svgawbank = svgarbank = s3_bank << 14;
  54.109 +                        break;
  54.110 +                        
  54.111 +                        case 0x3a:
  54.112 +                        if (val & 0x10) gdcreg[5] |= 0x40; /*Horrible cheat*/
  54.113 +                        break;
  54.114 +                        
  54.115 +                        case 0x45:
  54.116 +                        svga_hwcursor.ena = val & 1;
  54.117 +                        break;
  54.118 +                        case 0x48:
  54.119 +                        svga_hwcursor.x = ((crtc[0x46] << 8) | crtc[0x47]) & 0x7ff;
  54.120 +                        if (bpp == 32) svga_hwcursor.x >>= 1;
  54.121 +                        svga_hwcursor.y = ((crtc[0x48] << 8) | crtc[0x49]) & 0x7ff;
  54.122 +                        svga_hwcursor.xoff = crtc[0x4e] & 63;
  54.123 +                        svga_hwcursor.yoff = crtc[0x4f] & 63;
  54.124 +                        svga_hwcursor.addr = ((((crtc[0x4c] << 8) | crtc[0x4d]) & 0xfff) * 1024) + (svga_hwcursor.yoff * 16);
  54.125 +                        break;
  54.126 +
  54.127 +                        case 0x53:
  54.128 +                        case 0x58: case 0x59: case 0x5a:
  54.129 +                        s3_virge_updatemapping();
  54.130 +                        break;
  54.131 +                        
  54.132 +                        case 0x67:
  54.133 +                        switch (val >> 4)
  54.134 +                        {
  54.135 +                                case 3:  bpp = 15; break;
  54.136 +                                case 5:  bpp = 16; break;
  54.137 +                                case 7:  bpp = 24; break;
  54.138 +                                case 13: bpp = 32; break;
  54.139 +                                default: bpp = 8;  break;
  54.140 +                        }
  54.141 +                        break;
  54.142 +                        //case 0x55: case 0x43:
  54.143 +//                                pclog("Write CRTC R%02X %02X\n", crtcreg, val);
  54.144 +                }
  54.145 +                if (old!=val)
  54.146 +                {
  54.147 +                        if (crtcreg<0xE || crtcreg>0x10)
  54.148 +                        {
  54.149 +                                fullchange=changeframecount;
  54.150 +                                svga_recalctimings();
  54.151 +                        }
  54.152 +                }
  54.153 +                break;
  54.154 +        }
  54.155 +        svga_out(addr, val, NULL);
  54.156 +}
  54.157 +
  54.158 +uint8_t s3_virge_in(uint16_t addr, void *priv)
  54.159 +{
  54.160 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  54.161 +
  54.162 +        if (addr != 0x3da) pclog("S3 in %04X %04X:%08X\n", addr, CS, pc);
  54.163 +        switch (addr)
  54.164 +        {
  54.165 +                //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  54.166 +//                pclog("Read RAMDAC %04X  %04X:%04X\n", addr, CS, pc);
  54.167 +                //return sdac_ramdac_in(addr);
  54.168 +
  54.169 +                case 0x3c5:
  54.170 +                if (seqaddr >= 0x10)
  54.171 +                   return seqregs[seqaddr&0x1F];
  54.172 +                break;
  54.173 +
  54.174 +                case 0x3D4:
  54.175 +                return crtcreg;
  54.176 +                case 0x3D5:
  54.177 +//                pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc);
  54.178 +                switch (crtcreg)
  54.179 +                {
  54.180 +                        case 0x2d: return s3_virge_id_high; /*Extended chip ID*/
  54.181 +                        case 0x2e: return s3_virge_id_low;  /*New chip ID*/
  54.182 +                        case 0x2f: return s3_virge_rev;
  54.183 +                        case 0x30: return s3_virge_id;      /*Chip ID*/
  54.184 +                        case 0x31: return (crtc[0x31] & 0xcf) | ((s3_ma_ext & 3) << 4);
  54.185 +                        case 0x35: return (crtc[0x35] & 0xf0) | (s3_bank & 0xf);
  54.186 +                        case 0x51: return (crtc[0x51] & 0xf0) | ((s3_bank >> 2) & 0xc) | ((s3_ma_ext >> 2) & 3);
  54.187 +                        case 0x69: return s3_ma_ext;
  54.188 +                        case 0x6a: return s3_bank;
  54.189 +                }
  54.190 +                return crtc[crtcreg];
  54.191 +        }
  54.192 +        return svga_in(addr, NULL);
  54.193 +}
  54.194 +
  54.195 +void s3_virge_recalctimings()
  54.196 +{
  54.197 +//        pclog("recalctimings\n");
  54.198 +        svga_ma |= (s3_ma_ext << 16);
  54.199 +//        pclog("SVGA_MA %08X\n", svga_ma);
  54.200 +//        if (gdcreg[5] & 0x40) svga_lowres = !(crtc[0x3a] & 0x10);
  54.201 +        if ((gdcreg[5] & 0x40) && (crtc[0x3a] & 0x10))
  54.202 +        {
  54.203 +                switch (bpp)
  54.204 +                {
  54.205 +                        case 8: 
  54.206 +                        svga_render = svga_render_8bpp_highres; 
  54.207 +                        break;
  54.208 +                        case 15: 
  54.209 +                        svga_render = svga_render_15bpp_highres; 
  54.210 +                        break;
  54.211 +                        case 16: 
  54.212 +                        svga_render = svga_render_16bpp_highres; 
  54.213 +                        break;
  54.214 +                        case 24: 
  54.215 +                        svga_render = svga_render_24bpp_highres; 
  54.216 +                        break;
  54.217 +                        case 32: 
  54.218 +                        svga_render = svga_render_32bpp_highres; 
  54.219 +                        break;
  54.220 +                }
  54.221 +        }
  54.222 +        
  54.223 +        if (crtc[0x5d] & 0x01) svga_htotal     += 0x100;
  54.224 +        if (crtc[0x5d] & 0x02) svga_hdisp      += 0x100;
  54.225 +        if (crtc[0x5e] & 0x01) svga_vtotal     += 0x400;
  54.226 +        if (crtc[0x5e] & 0x02) svga_dispend    += 0x400;
  54.227 +        if (crtc[0x5e] & 0x10) svga_vsyncstart += 0x400;
  54.228 +        if (crtc[0x5e] & 0x40) svga_split      += 0x400;
  54.229 +        if (crtc[0x51] & 0x30)      svga_rowoffset  += (crtc[0x51] & 0x30) << 4;
  54.230 +        else if (crtc[0x43] & 0x04) svga_rowoffset  += 0x100;
  54.231 +        if (!svga_rowoffset) svga_rowoffset = 256;
  54.232 +        svga_interlace = crtc[0x42] & 0x20;
  54.233 +        if (bpp == 32)
  54.234 +        {
  54.235 +                svga_htotal <<= 2;
  54.236 +                svga_hdisp <<= 2;
  54.237 +        }
  54.238 +        //svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3);
  54.239 +//        pclog("SVGA_CLOCK = %f  %02X  %f\n", svga_clock, svga_miscout, cpuclock);
  54.240 +        //if (bpp > 8) svga_clock /= 2;
  54.241 +}
  54.242 +
  54.243 +static uint32_t s3_linear_base = 0, s3_linear_size = 0;
  54.244 +void s3_virge_updatemapping()
  54.245 +{
  54.246 +        mem_removehandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
  54.247 +        
  54.248 +//        video_write_a000_w = video_write_a000_l = NULL;
  54.249 +
  54.250 +        mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  54.251 +        mem_removehandler(0xa0000, 0x20000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL);
  54.252 +        pclog("Update mapping - bank %02X ", gdcreg[6] & 0xc);        
  54.253 +        switch (gdcreg[6] & 0xc) /*Banked framebuffer*/
  54.254 +        {
  54.255 +                case 0x0: /*128k at A0000*/
  54.256 +                mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  54.257 +                break;
  54.258 +                case 0x4: /*64k at A0000*/
  54.259 +                mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  54.260 +                break;
  54.261 +                case 0x8: /*32k at B0000*/
  54.262 +                mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  54.263 +                break;
  54.264 +                case 0xC: /*32k at B8000*/
  54.265 +                mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  54.266 +                break;
  54.267 +        }
  54.268 +        
  54.269 +        pclog("Linear framebuffer %02X ", crtc[0x58] & 0x10);
  54.270 +        if (crtc[0x58] & 0x10) /*Linear framebuffer*/
  54.271 +        {
  54.272 +                s3_linear_base = (crtc[0x5a] << 16) | (crtc[0x59] << 24);
  54.273 +                switch (crtc[0x58] & 3)
  54.274 +                {
  54.275 +                        case 0: /*64k*/
  54.276 +                        s3_linear_size = 0x10000;
  54.277 +                        break;
  54.278 +                        case 1: /*1mb*/
  54.279 +                        s3_linear_size = 0x100000;
  54.280 +                        break;
  54.281 +                        case 2: /*2mb*/
  54.282 +                        s3_linear_size = 0x200000;
  54.283 +                        break;
  54.284 +                        case 3: /*8mb*/
  54.285 +                        s3_linear_size = 0x400000;
  54.286 +                        break;
  54.287 +                }
  54.288 +                s3_linear_base &= ~(s3_linear_size - 1);
  54.289 +//                pclog("%08X %08X  %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]);
  54.290 +                pclog("Linear framebuffer at %08X size %08X\n", s3_linear_base, s3_linear_size);
  54.291 +                if (s3_linear_base == 0xa0000)
  54.292 +                   mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  54.293 +                else
  54.294 +                   mem_sethandler(s3_linear_base, s3_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL);
  54.295 +        }
  54.296 +        
  54.297 +        pclog("Memory mapped IO %02X\n", crtc[0x53] & 0x18);
  54.298 +        output = 0;
  54.299 +        if ((crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/
  54.300 +        {
  54.301 +                output = 3;
  54.302 +                if (crtc[0x53] & 0x20)
  54.303 +                   mem_sethandler(0xb8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL);
  54.304 +                else
  54.305 +                   mem_sethandler(0xa8000, 0x8000, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL);
  54.306 +        }
  54.307 +
  54.308 +}
  54.309 +
  54.310 +
  54.311 +uint8_t s3_virge_mmio_read(uint32_t addr, void *priv)
  54.312 +{
  54.313 +        pclog("MMIO readb %08X\n", addr);
  54.314 +        return 0xff;
  54.315 +}
  54.316 +uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv)
  54.317 +{
  54.318 +        pclog("MMIO readw %08X\n", addr);
  54.319 +        return 0xffff;
  54.320 +}
  54.321 +uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv)
  54.322 +{
  54.323 +        pclog("MMIO readl %08X\n", addr);
  54.324 +        return 0xffffffff;
  54.325 +}
  54.326 +void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv)
  54.327 +{
  54.328 +        pclog("MMIO writeb %08X %02X\n", addr, val);
  54.329 +}
  54.330 +void     s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv)
  54.331 +{
  54.332 +        pclog("MMIO writew %08X %04X\n", addr, val);
  54.333 +}
  54.334 +void     s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
  54.335 +{
  54.336 +        pclog("MMIO writel %08X %08X\n", addr, val);
  54.337 +}
  54.338 +
  54.339 +
  54.340 +
  54.341 +void s3_virge_hwcursor_draw(int displine)
  54.342 +{
  54.343 +        int x;
  54.344 +        uint16_t dat[2];
  54.345 +        int xx;
  54.346 +        int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff;
  54.347 +        
  54.348 +        pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y);
  54.349 +        for (x = 0; x < 64; x += 16)
  54.350 +        {
  54.351 +                dat[0] = (vram[svga_hwcursor_latch.addr]     << 8) | vram[svga_hwcursor_latch.addr + 1];
  54.352 +                dat[1] = (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3];
  54.353 +                for (xx = 0; xx < 16; xx++)
  54.354 +                {
  54.355 +                        if (offset >= svga_hwcursor_latch.x)
  54.356 +                        {
  54.357 +                                if (!(dat[0] & 0x8000))
  54.358 +                                   ((uint32_t *)buffer32->line[displine])[offset + 32]  = (dat[1] & 0x8000) ? 0xffffff : 0;
  54.359 +                                else if (dat[1] & 0x8000)
  54.360 +                                   ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
  54.361 +//                                pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]);
  54.362 +                        }
  54.363 +                           
  54.364 +                        offset++;
  54.365 +                        dat[0] <<= 1;
  54.366 +                        dat[1] <<= 1;
  54.367 +                }
  54.368 +                svga_hwcursor_latch.addr += 4;
  54.369 +        }
  54.370 +}
  54.371 +
  54.372 +
  54.373 +static uint8_t s3_virge_pci_regs[256];
  54.374 +
  54.375 +uint8_t s3_virge_pci_read(int func, int addr, void *priv)
  54.376 +{
  54.377 +//        pclog("S3 PCI read %08X\n", addr);
  54.378 +        switch (addr)
  54.379 +        {
  54.380 +                case 0x00: return 0x33; /*'S3'*/
  54.381 +                case 0x01: return 0x53;
  54.382 +                
  54.383 +                case 0x02: return s3_virge_id_low;
  54.384 +                case 0x03: return s3_virge_id_high;
  54.385 +                
  54.386 +                case 0x08: return 0; /*Revision ID*/
  54.387 +                case 0x09: return 0; /*Programming interface*/
  54.388 +                
  54.389 +                case 0x0a: return 0x00; /*Supports VGA interface*/
  54.390 +                case 0x0b: return 0x03;
  54.391 +                
  54.392 +                case 0x10: return 0x00; /*Linear frame buffer address*/
  54.393 +                case 0x11: return 0x00;
  54.394 +                case 0x12: return 0x00;
  54.395 +                case 0x13: return crtc[0x59] & 0xfc;
  54.396 +
  54.397 +                case 0x30: return 0x01; /*BIOS ROM address*/
  54.398 +                case 0x31: return 0x00;
  54.399 +                case 0x32: return 0x0C;
  54.400 +                case 0x33: return 0x00;
  54.401 +                
  54.402 +        }
  54.403 +        return s3_virge_pci_regs[addr];
  54.404 +}
  54.405 +
  54.406 +void s3_virge_pci_write(int func, int addr, uint8_t val, void *priv)
  54.407 +{
  54.408 +        switch (addr)
  54.409 +        {
  54.410 +                case 0x00: case 0x01: case 0x02: case 0x03:
  54.411 +                case 0x08: case 0x09: case 0x0a: case 0x0b:
  54.412 +                case 0x3d: case 0x3e: case 0x3f:
  54.413 +                break;
  54.414 +                
  54.415 +                case 0x13: crtc[0x59] = val & 0xfc; s3_virge_updatemapping(); break;                
  54.416 +        }
  54.417 +        s3_virge_pci_regs[addr] = val;
  54.418 +}
  54.419 +
  54.420 +int s3_virge_init()
  54.421 +{
  54.422 +        s3_virge_pci_regs[4] = 3;
  54.423 +        s3_virge_pci_regs[5] = 0;        
  54.424 +        s3_virge_pci_regs[6] = 0;
  54.425 +        s3_virge_pci_regs[7] = 2;
  54.426 +        s3_virge_pci_regs[0x3d] = 1; 
  54.427 +        s3_virge_pci_regs[0x3e] = 4;
  54.428 +        s3_virge_pci_regs[0x3f] = 0xff;
  54.429 +        
  54.430 +        s3_virge_id_high = 0x56;
  54.431 +        s3_virge_id_low = 0x31;
  54.432 +        s3_virge_rev = 0;
  54.433 +        s3_virge_id = 0xe1;
  54.434 +
  54.435 +        svga_recalctimings_ex = s3_virge_recalctimings;
  54.436 +        svga_hwcursor_draw    = s3_virge_hwcursor_draw;
  54.437 +
  54.438 +        crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
  54.439 +        crtc[0x37] = 1 | (7 << 5);
  54.440 +        
  54.441 +        vrammask = 0x3fffff;
  54.442 +
  54.443 +        pci_add(s3_virge_pci_read, s3_virge_pci_write, NULL);
  54.444 + 
  54.445 +        svga_vram_limit = 4 << 20; /*4mb*/
  54.446 +        return svga_init();
  54.447 +}
  54.448 +
  54.449 +GFXCARD vid_s3_virge =
  54.450 +{
  54.451 +        s3_virge_init,
  54.452 +        /*IO at 3Cx/3Dx*/
  54.453 +        s3_virge_out,
  54.454 +        s3_virge_in,
  54.455 +        /*IO at 3Ax/3Bx*/
  54.456 +        video_out_null,
  54.457 +        video_in_null,
  54.458 +
  54.459 +        svga_poll,
  54.460 +        svga_recalctimings,
  54.461 +
  54.462 +        svga_write,
  54.463 +        video_write_null,
  54.464 +        video_write_null,
  54.465 +
  54.466 +        svga_read,
  54.467 +        video_read_null,
  54.468 +        video_read_null
  54.469 +};
  54.470 +
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/src/vid_svga_render.c	Mon May 27 19:56:33 2013 +0100
    55.3 @@ -0,0 +1,487 @@
    55.4 +#include "ibm.h"
    55.5 +#include "video.h"
    55.6 +#include "vid_svga.h"
    55.7 +#include "vid_svga_render.h"
    55.8 +
    55.9 +void svga_render_blank()
   55.10 +{
   55.11 +        int x, xx;
   55.12 +        
   55.13 +        if (firstline_draw == 2000) firstline_draw = displine;
   55.14 +        lastline_draw = displine;
   55.15 +        for (x=0;x<svga_hdisp;x++)
   55.16 +        {
   55.17 +                switch (seqregs[1]&9)
   55.18 +                {
   55.19 +                        case 0:
   55.20 +                        for (xx=0;xx<9;xx++) ((uint32_t *)buffer32->line[displine])[(x*9)+xx+32]=0;
   55.21 +                        break;
   55.22 +                        case 1:
   55.23 +                        for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[(x*8)+xx+32]=0;
   55.24 +                        break;
   55.25 +                        case 8:
   55.26 +                        for (xx=0;xx<18;xx++) ((uint32_t *)buffer32->line[displine])[(x*18)+xx+32]=0;
   55.27 +                        break;
   55.28 +                        case 9:
   55.29 +                        for (xx=0;xx<16;xx++) ((uint32_t *)buffer32->line[displine])[(x*16)+xx+32]=0;
   55.30 +                        break;
   55.31 +                }
   55.32 +        }
   55.33 +}
   55.34 +
   55.35 +void svga_render_text_40()
   55.36 +{     
   55.37 +        if (firstline_draw == 2000) firstline_draw = displine;
   55.38 +        lastline_draw = displine;
   55.39 +        
   55.40 +        if (fullchange)
   55.41 +        {
   55.42 +                int x, xx;
   55.43 +                int drawcursor;
   55.44 +                uint8_t chr, attr, dat;
   55.45 +                uint32_t charaddr;
   55.46 +                int fg, bg;
   55.47 +                int xinc = (seqregs[1] & 1) ? 16 : 18;
   55.48 +                
   55.49 +                for (x=0;x<svga_hdisp;x+=xinc)
   55.50 +                {
   55.51 +                        drawcursor=((ma==ca) && con && cursoron);
   55.52 +                        chr=vram[(ma<<1)];
   55.53 +                        attr=vram[(ma<<1)+4];
   55.54 +                        if (attr&8) charaddr=charsetb+(chr*128);
   55.55 +                        else        charaddr=charseta+(chr*128);
   55.56 +
   55.57 +                        if (drawcursor) 
   55.58 +                        { 
   55.59 +                                bg=pallook[egapal[attr&15]]; 
   55.60 +                                fg=pallook[egapal[attr>>4]]; 
   55.61 +                        }
   55.62 +                        else
   55.63 +                        {
   55.64 +                                fg=pallook[egapal[attr&15]];
   55.65 +                                bg=pallook[egapal[attr>>4]];
   55.66 +                                if (attr&0x80 && attrregs[0x10]&8)
   55.67 +                                {
   55.68 +                                        bg=pallook[egapal[(attr>>4)&7]];
   55.69 +                                        if (cgablink&16) fg=bg;
   55.70 +                                }
   55.71 +                        }
   55.72 +
   55.73 +                        dat=vram[charaddr+(sc<<2)];
   55.74 +                        if (seqregs[1]&1) 
   55.75 +                        { 
   55.76 +                                for (xx=0;xx<8;xx++) 
   55.77 +                                        ((uint32_t *)buffer32->line[displine])[(x+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[(x+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; 
   55.78 +                        }
   55.79 +                        else
   55.80 +                        {
   55.81 +                                for (xx=0;xx<8;xx++) 
   55.82 +                                        ((uint32_t *)buffer32->line[displine])[(x+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[(x+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg;
   55.83 +                                if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) 
   55.84 +                                        ((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=bg;
   55.85 +                                else                  
   55.86 +                                        ((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=(dat&1)?fg:bg;
   55.87 +                        }
   55.88 +                        ma+=4; ma&=vrammask;
   55.89 +                }
   55.90 +        }
   55.91 +}
   55.92 +
   55.93 +void svga_render_text_80()
   55.94 +{
   55.95 +        if (firstline_draw == 2000) firstline_draw = displine;
   55.96 +        lastline_draw = displine;
   55.97 +        
   55.98 +        if (fullchange)
   55.99 +        {
  55.100 +                int x, xx;
  55.101 +                int drawcursor;
  55.102 +                uint8_t chr, attr, dat;
  55.103 +                uint32_t charaddr;
  55.104 +                int fg, bg;
  55.105 +                int xinc = (seqregs[1] & 1) ? 8 : 9;
  55.106 +
  55.107 +                for (x=0;x<svga_hdisp;x+=xinc)
  55.108 +                {
  55.109 +                        drawcursor=((ma==ca) && con && cursoron);
  55.110 +                        chr=vram[(ma<<1)];
  55.111 +                        attr=vram[(ma<<1)+4];
  55.112 +                        if (attr&8) charaddr=charsetb+(chr*128);
  55.113 +                        else        charaddr=charseta+(chr*128);
  55.114 +
  55.115 +                        if (drawcursor) 
  55.116 +                        { 
  55.117 +                                bg=pallook[egapal[attr&15]]; 
  55.118 +                                fg=pallook[egapal[attr>>4]]; 
  55.119 +                        }
  55.120 +                        else
  55.121 +                        {
  55.122 +                                fg=pallook[egapal[attr&15]];
  55.123 +                                bg=pallook[egapal[attr>>4]];
  55.124 +                                if (attr&0x80 && attrregs[0x10]&8)
  55.125 +                                {
  55.126 +                                        bg=pallook[egapal[(attr>>4)&7]];
  55.127 +                                        if (cgablink&16) fg=bg;
  55.128 +                                }
  55.129 +                        }
  55.130 +
  55.131 +                        dat=vram[charaddr+(sc<<2)];
  55.132 +                        if (seqregs[1]&1) 
  55.133 +                        { 
  55.134 +                                for (xx=0;xx<8;xx++) 
  55.135 +                                        ((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; 
  55.136 +                        }
  55.137 +                        else
  55.138 +                        {
  55.139 +                                for (xx=0;xx<8;xx++) 
  55.140 +                                        ((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg;
  55.141 +                                if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) 
  55.142 +                                        ((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=bg;
  55.143 +                                else                  
  55.144 +                                        ((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=(dat&1)?fg:bg;
  55.145 +                        }
  55.146 +                        ma+=4; ma&=vrammask;
  55.147 +                }
  55.148 +        }
  55.149 +}
  55.150 +
  55.151 +void svga_render_4bpp_lowres()
  55.152 +{
  55.153 +        int x, offset;
  55.154 +        uint8_t edat[4], dat;
  55.155 +        
  55.156 +        if (firstline_draw == 2000) firstline_draw = displine;
  55.157 +        lastline_draw = displine;
  55.158 +
  55.159 +        offset=((8-scrollcache)<<1)+16;
  55.160 +        for (x = 0; x <= svga_hdisp; x += 16)
  55.161 +        {
  55.162 +                edat[0]=vram[ma];
  55.163 +                edat[1]=vram[ma|0x1];
  55.164 +                edat[2]=vram[ma|0x2];
  55.165 +                edat[3]=vram[ma|0x3];
  55.166 +                ma+=4; ma&=vrammask;
  55.167 +
  55.168 +                dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
  55.169 +                ((uint32_t *)buffer32->line[displine])[x+14+offset]=((uint32_t *)buffer32->line[displine])[x+15+offset]=pallook[egapal[dat&0xF]];
  55.170 +                ((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[dat>>4]];
  55.171 +                dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
  55.172 +                ((uint32_t *)buffer32->line[displine])[x+10+offset]=((uint32_t *)buffer32->line[displine])[x+11+offset]=pallook[egapal[dat&0xF]];
  55.173 +                ((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[dat>>4]];
  55.174 +                dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
  55.175 +                ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[dat&0xF]];
  55.176 +                ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat>>4]];
  55.177 +                dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
  55.178 +                ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[dat&0xF]];
  55.179 +                ((uint32_t *)buffer32->line[displine])[x+offset]=   ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat>>4]];
  55.180 +        }
  55.181 +}
  55.182 +
  55.183 +void svga_render_4bpp_highres()
  55.184 +{
  55.185 +        int x, offset;
  55.186 +        uint8_t edat[4], dat;
  55.187 +        
  55.188 +        if (firstline_draw == 2000) firstline_draw = displine;
  55.189 +        lastline_draw = displine;
  55.190 +
  55.191 +        offset=(8-scrollcache)+24;
  55.192 +        for (x = 0; x <= svga_hdisp; x += 8)
  55.193 +        {
  55.194 +                edat[0]=vram[ma];
  55.195 +                edat[1]=vram[ma|0x1];
  55.196 +                edat[2]=vram[ma|0x2];
  55.197 +                edat[3]=vram[ma|0x3];
  55.198 +                ma+=4; ma&=vrammask;
  55.199 +
  55.200 +                dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
  55.201 +                ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[dat&0xF]];
  55.202 +                ((uint32_t *)buffer32->line[displine])[x+6+offset]=pallook[egapal[dat>>4]];
  55.203 +                dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
  55.204 +                ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat&0xF]];
  55.205 +                ((uint32_t *)buffer32->line[displine])[x+4+offset]=pallook[egapal[dat>>4]];
  55.206 +                dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
  55.207 +                ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[dat&0xF]];
  55.208 +                ((uint32_t *)buffer32->line[displine])[x+2+offset]=pallook[egapal[dat>>4]];
  55.209 +                dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
  55.210 +                ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat&0xF]];
  55.211 +                ((uint32_t *)buffer32->line[displine])[x+offset]=  pallook[egapal[dat>>4]];
  55.212 +        }
  55.213 +}
  55.214 +
  55.215 +void svga_render_2bpp_lowres()
  55.216 +{
  55.217 +        int x, offset;
  55.218 +        uint8_t edat[4], dat;
  55.219 +                
  55.220 +        if (firstline_draw == 2000) firstline_draw = displine;
  55.221 +        lastline_draw = displine;
  55.222 +        offset=((8-scrollcache)<<1)+16;
  55.223 +        /*Low res (320) only, though high res (640) should be possible*/
  55.224 +        for (x = 0; x <= svga_hdisp; x += 16)
  55.225 +        {
  55.226 +                if (sc&1 && !(crtc[0x17]&1))
  55.227 +                {
  55.228 +                        edat[0]=vram[(ma<<1)+0x8000];
  55.229 +                        edat[1]=vram[(ma<<1)+0x8004];
  55.230 +                }
  55.231 +                else
  55.232 +                {
  55.233 +                        edat[0]=vram[(ma<<1)];
  55.234 +                        edat[1]=vram[(ma<<1)+4];
  55.235 +                }
  55.236 +                ma+=4; ma&=vrammask;
  55.237 +
  55.238 +                ((uint32_t *)buffer32->line[displine])[x+14+offset]=((uint32_t *)buffer32->line[displine])[x+15+offset]=pallook[egapal[edat[1]&3]];
  55.239 +                ((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[(edat[1]>>2)&3]];
  55.240 +                dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
  55.241 +                ((uint32_t *)buffer32->line[displine])[x+10+offset]=((uint32_t *)buffer32->line[displine])[x+11+offset]=pallook[egapal[(edat[1]>>4)&3]];
  55.242 +                ((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[(edat[1]>>6)&3]];
  55.243 +                dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
  55.244 +                ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[(edat[0]>>0)&3]];
  55.245 +                ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[(edat[0]>>2)&3]];
  55.246 +                dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
  55.247 +                ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[(edat[0]>>4)&3]];
  55.248 +                ((uint32_t *)buffer32->line[displine])[x+offset]=   ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[(edat[0]>>6)&3]];
  55.249 +        }
  55.250 +}
  55.251 +
  55.252 +void svga_render_8bpp_lowres()
  55.253 +{
  55.254 +        int x, offset;
  55.255 +        uint8_t edat[4];
  55.256 +                
  55.257 +        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  55.258 +        {
  55.259 +                if (firstline_draw == 2000) firstline_draw = displine;
  55.260 +                lastline_draw = displine;
  55.261 +
  55.262 +                offset=(8-(scrollcache&6))+24;
  55.263 +                                                                
  55.264 +                for (x = 0; x <= svga_hdisp; x += 8)
  55.265 +                {
  55.266 +                        edat[0]=vram[ma];
  55.267 +                        edat[1]=vram[ma|0x1];
  55.268 +                        edat[2]=vram[ma|0x2];
  55.269 +                        edat[3]=vram[ma|0x3];
  55.270 +                        ma+=4; ma&=vrammask;
  55.271 +                        ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[edat[3]];
  55.272 +                        ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[edat[2]];
  55.273 +                        ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[edat[1]];
  55.274 +                        ((uint32_t *)buffer32->line[displine])[x+offset]=   ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[edat[0]];
  55.275 +                }
  55.276 +        }
  55.277 +}
  55.278 +
  55.279 +void svga_render_8bpp_highres()
  55.280 +{
  55.281 +        int x, offset;
  55.282 +        uint8_t edat[4];
  55.283 +                
  55.284 +        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  55.285 +        {
  55.286 +                if (firstline_draw == 2000) firstline_draw = displine;
  55.287 +                lastline_draw = displine;
  55.288 +
  55.289 +                offset = (8 - ((scrollcache & 6) >> 1)) + 24;
  55.290 +                                                                
  55.291 +                for (x = 0; x <= svga_hdisp; x += 8)
  55.292 +                {
  55.293 +                        edat[0]=vram[ma];
  55.294 +                        edat[1]=vram[ma|0x1];
  55.295 +                        edat[2]=vram[ma|0x2];
  55.296 +                        edat[3]=vram[ma|0x3];
  55.297 +                        ma+=4; ma&=vrammask;
  55.298 +                        ((uint32_t *)buffer32->line[displine])[x+3+offset] = pallook[edat[3]];
  55.299 +                        ((uint32_t *)buffer32->line[displine])[x+2+offset] = pallook[edat[2]];
  55.300 +                        ((uint32_t *)buffer32->line[displine])[x+1+offset] = pallook[edat[1]];
  55.301 +                        ((uint32_t *)buffer32->line[displine])[x+offset]   = pallook[edat[0]];
  55.302 +                        edat[0]=vram[ma];
  55.303 +                        edat[1]=vram[ma|0x1];
  55.304 +                        edat[2]=vram[ma|0x2];
  55.305 +                        edat[3]=vram[ma|0x3];
  55.306 +                        ma+=4; ma&=vrammask;
  55.307 +                        ((uint32_t *)buffer32->line[displine])[x+7+offset] = pallook[edat[3]];
  55.308 +                        ((uint32_t *)buffer32->line[displine])[x+6+offset] = pallook[edat[2]];
  55.309 +                        ((uint32_t *)buffer32->line[displine])[x+5+offset] = pallook[edat[1]];
  55.310 +                        ((uint32_t *)buffer32->line[displine])[x+4+offset] = pallook[edat[0]];
  55.311 +                }
  55.312 +        }
  55.313 +}
  55.314 +
  55.315 +void svga_render_15bpp_lowres()
  55.316 +{
  55.317 +        int x, offset;
  55.318 +        uint16_t fg, bg;
  55.319 +        
  55.320 +        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  55.321 +        {
  55.322 +                if (firstline_draw == 2000) firstline_draw = displine;
  55.323 +                lastline_draw = displine;
  55.324 +
  55.325 +                offset=(8-(scrollcache&6))+24;
  55.326 +
  55.327 +                for (x = 0; x <= svga_hdisp; x += 4)
  55.328 +                {
  55.329 +                        fg=vram[ma]|(vram[ma|0x1]<<8);
  55.330 +                        bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
  55.331 +                        ma+=4; ma&=vrammask;
  55.332 +                        ((uint32_t *)buffer32->line[displine])[x+2+offset]=((uint32_t *)buffer32->line[displine])[x+3+offset]=((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19);
  55.333 +                        ((uint32_t *)buffer32->line[displine])[x+0+offset]=((uint32_t *)buffer32->line[displine])[x+1+offset]=((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19);
  55.334 +                }
  55.335 +        }
  55.336 +}
  55.337 +
  55.338 +void svga_render_15bpp_highres()
  55.339 +{
  55.340 +        int x, offset;
  55.341 +        uint16_t fg, bg;
  55.342 +        
  55.343 +        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  55.344 +        {
  55.345 +                if (firstline_draw == 2000) firstline_draw = displine;
  55.346 +                lastline_draw = displine;
  55.347 +
  55.348 +                offset = (8 - ((scrollcache & 6) >> 1)) + 24;
  55.349 +                                                                
  55.350 +                for (x = 0; x <= svga_hdisp; x += 2)
  55.351 +                {
  55.352 +                        fg=vram[ma]|(vram[ma|0x1]<<8);
  55.353 +                        bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
  55.354 +                        ma+=4; ma&=vrammask;
  55.355 +                        ((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19);
  55.356 +                        ((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19);
  55.357 +                }
  55.358 +        }
  55.359 +}
  55.360 +
  55.361 +void svga_render_16bpp_lowres()
  55.362 +{
  55.363 +        int x, offset;
  55.364 +        uint16_t fg, bg;
  55.365 +        
  55.366 +        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  55.367 +        {
  55.368 +                if (firstline_draw == 2000) firstline_draw = displine;
  55.369 +                lastline_draw = displine;
  55.370 +
  55.371 +                offset=(8-(scrollcache&6))+24;
  55.372 +
  55.373 +                for (x = 0; x <= svga_hdisp; x += 4)
  55.374 +                {
  55.375 +                        fg=vram[ma]|(vram[ma|0x1]<<8);
  55.376 +                        bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
  55.377 +                        ma+=4; ma&=vrammask;
  55.378 +                        ((uint32_t *)buffer32->line[displine])[x+2+offset]=((uint32_t *)buffer32->line[displine])[x+3+offset]=((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19);
  55.379 +                        ((uint32_t *)buffer32->line[displine])[x+0+offset]=((uint32_t *)buffer32->line[displine])[x+1+offset]=((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19);
  55.380 +                }
  55.381 +        }
  55.382 +}
  55.383 +
  55.384 +void svga_render_16bpp_highres()
  55.385 +{
  55.386 +        int x, offset;
  55.387 +        uint16_t fg, bg;
  55.388 +        
  55.389 +        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  55.390 +        {
  55.391 +                if (firstline_draw == 2000) firstline_draw = displine;
  55.392 +                lastline_draw = displine;
  55.393 +
  55.394 +                offset = (8 - ((scrollcache & 6) >> 1)) + 24;
  55.395 +                                                                
  55.396 +                for (x = 0; x <= svga_hdisp; x += 2)
  55.397 +                {
  55.398 +                        fg=vram[ma]|(vram[ma|0x1]<<8);
  55.399 +                        bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
  55.400 +                        ma+=4; ma&=vrammask;
  55.401 +                        ((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19);
  55.402 +                        ((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19);
  55.403 +                }
  55.404 +        }
  55.405 +}
  55.406 +
  55.407 +void svga_render_24bpp_lowres()
  55.408 +{
  55.409 +        int x, offset;
  55.410 +        uint32_t fg;
  55.411 +        
  55.412 +        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  55.413 +        {
  55.414 +                if (firstline_draw == 2000) firstline_draw = displine;
  55.415 +                lastline_draw = displine;
  55.416 +
  55.417 +                offset=(8-(scrollcache&6))+24;
  55.418 +
  55.419 +                for (x = 0; x <= svga_hdisp; x++)
  55.420 +                {
  55.421 +                        fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
  55.422 +                        ma+=3; ma&=vrammask;
  55.423 +                        ((uint32_t *)buffer32->line[displine])[(x<<1)+offset]=((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=fg;
  55.424 +                }
  55.425 +        }
  55.426 +}
  55.427 +
  55.428 +void svga_render_24bpp_highres()
  55.429 +{
  55.430 +        int x, offset;
  55.431 +        uint32_t fg;
  55.432 +        
  55.433 +        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  55.434 +        {
  55.435 +                if (firstline_draw == 2000) firstline_draw = displine;
  55.436 +                lastline_draw = displine;
  55.437 +
  55.438 +                offset = (8 - ((scrollcache & 6) >> 1)) + 24;
  55.439 +
  55.440 +                for (x = 0; x <= svga_hdisp; x++)
  55.441 +                {
  55.442 +                        fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
  55.443 +                        ma+=3; ma&=vrammask;
  55.444 +                        ((uint32_t *)buffer32->line[displine])[x + offset] = fg;
  55.445 +                }
  55.446 +        }
  55.447 +}
  55.448 +
  55.449 +void svga_render_32bpp_lowres()
  55.450 +{
  55.451 +        int x, offset;
  55.452 +        uint32_t fg;
  55.453 +        
  55.454 +        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  55.455 +        {
  55.456 +                if (firstline_draw == 2000) firstline_draw = displine;
  55.457 +                lastline_draw = displine;
  55.458 +
  55.459 +                offset=(8-(scrollcache&6))+24;
  55.460 +
  55.461 +                for (x = 0; x <= svga_hdisp; x++)
  55.462 +                {
  55.463 +                        fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16);
  55.464 +                        ma += 4; ma &= vrammask;
  55.465 +                        ((uint32_t *)buffer32->line[displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[displine])[(x << 1) + 1 + offset] = fg;
  55.466 +                }
  55.467 +        }
  55.468 +}
  55.469 +
  55.470 +void svga_render_32bpp_highres()
  55.471 +{
  55.472 +        int x, offset;
  55.473 +        uint32_t fg;
  55.474 +        
  55.475 +        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  55.476 +        {
  55.477 +                if (firstline_draw == 2000) firstline_draw = displine;
  55.478 +                lastline_draw = displine;
  55.479 +
  55.480 +                offset = (8 - ((scrollcache & 6) >> 1)) + 24;
  55.481 +
  55.482 +                for (x = 0; x <= svga_hdisp; x++)
  55.483 +                {
  55.484 +                        fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
  55.485 +                        ma+=4; ma&=vrammask;
  55.486 +                        ((uint32_t *)buffer32->line[displine])[x + offset] = fg;
  55.487 +                }
  55.488 +        }
  55.489 +}
  55.490 +
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/src/vid_svga_render.h	Mon May 27 19:56:33 2013 +0100
    56.3 @@ -0,0 +1,30 @@
    56.4 +extern int firstline_draw, lastline_draw;
    56.5 +extern int displine;
    56.6 +extern int sc;
    56.7 +
    56.8 +extern uint32_t ma, ca;
    56.9 +extern int con, cursoron, cgablink;
   56.10 +
   56.11 +extern int scrollcache;
   56.12 +
   56.13 +extern uint8_t edatlookup[4][4];
   56.14 +
   56.15 +void svga_render_blank();
   56.16 +void svga_render_text_40();
   56.17 +void svga_render_text_80();
   56.18 +
   56.19 +void svga_render_2bpp_lowres();
   56.20 +void svga_render_4bpp_lowres();
   56.21 +void svga_render_4bpp_highres();
   56.22 +void svga_render_8bpp_lowres();
   56.23 +void svga_render_8bpp_highres();
   56.24 +void svga_render_15bpp_lowres();
   56.25 +void svga_render_15bpp_highres();
   56.26 +void svga_render_16bpp_lowres();
   56.27 +void svga_render_16bpp_highres();
   56.28 +void svga_render_24bpp_lowres();
   56.29 +void svga_render_24bpp_highres();
   56.30 +void svga_render_32bpp_lowres();
   56.31 +void svga_render_32bpp_highres();
   56.32 +
   56.33 +extern void (*svga_render)();
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/src/vid_vga.c	Mon May 27 19:56:33 2013 +0100
    57.3 @@ -0,0 +1,92 @@
    57.4 +/*IBM VGA emulation*/
    57.5 +#include "ibm.h"
    57.6 +#include "io.h"
    57.7 +#include "video.h"
    57.8 +#include "vid_svga.h"
    57.9 +
   57.10 +void vga_out(uint16_t addr, uint8_t val, void *priv)
   57.11 +{
   57.12 +        uint8_t old;
   57.13 +        
   57.14 +        pclog("vga_out : %04X %02X  %04X:%04X  %02X  %i\n", addr, val, CS,pc, ram[0x489], ins);
   57.15 +                
   57.16 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   57.17 +
   57.18 +        switch (addr)
   57.19 +        {
   57.20 +                case 0x3D4:
   57.21 +                crtcreg = val & 0x1f;
   57.22 +                return;
   57.23 +                case 0x3D5:
   57.24 +                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
   57.25 +                old=crtc[crtcreg];
   57.26 +                crtc[crtcreg]=val;
   57.27 +                if (old!=val)
   57.28 +                {
   57.29 +                        if (crtcreg<0xE || crtcreg>0x10)
   57.30 +                        {
   57.31 +                                fullchange=changeframecount;
   57.32 +                                svga_recalctimings();
   57.33 +                        }
   57.34 +                }
   57.35 +                break;
   57.36 +        }
   57.37 +        svga_out(addr, val, NULL);
   57.38 +}
   57.39 +
   57.40 +uint8_t vga_in(uint16_t addr, void *priv)
   57.41 +{
   57.42 +        uint8_t temp;
   57.43 +
   57.44 +        if (addr != 0x3da) pclog("vga_in : %04X ", addr);
   57.45 +                
   57.46 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   57.47 +             
   57.48 +        switch (addr)
   57.49 +        {
   57.50 +                case 0x3D4:
   57.51 +                temp = crtcreg;
   57.52 +                break;
   57.53 +                case 0x3D5:
   57.54 +                temp = crtc[crtcreg];
   57.55 +                break;
   57.56 +                default:
   57.57 +                temp = svga_in(addr, NULL);
   57.58 +                break;
   57.59 +        }
   57.60 +        if (addr != 0x3da) pclog("%02X  %04X:%04X\n", temp, CS,pc);
   57.61 +        return temp;
   57.62 +}
   57.63 +
   57.64 +int vga_init()
   57.65 +{
   57.66 +        svga_recalctimings_ex = NULL;
   57.67 +        svga_vram_limit = 1 << 18; /*256kb*/
   57.68 +        vrammask = 0x3ffff;
   57.69 +        svgawbank = svgarbank = 0;
   57.70 +        bpp = 8;
   57.71 +        svga_miscout = 1;
   57.72 +        return svga_init();
   57.73 +}
   57.74 +
   57.75 +GFXCARD vid_vga =
   57.76 +{
   57.77 +        vga_init,
   57.78 +        /*IO at 3Cx/3Dx*/
   57.79 +        vga_out,
   57.80 +        vga_in,
   57.81 +        /*IO at 3Ax/3Bx*/
   57.82 +        video_out_null,
   57.83 +        video_in_null,
   57.84 +
   57.85 +        svga_poll,
   57.86 +        svga_recalctimings,
   57.87 +
   57.88 +        svga_write,
   57.89 +        video_write_null,
   57.90 +        video_write_null,
   57.91 +
   57.92 +        svga_read,
   57.93 +        video_read_null,
   57.94 +        video_read_null
   57.95 +};
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/src/vid_voodoo.c	Mon May 27 19:56:33 2013 +0100
    58.3 @@ -0,0 +1,732 @@
    58.4 +#include <stdlib.h>
    58.5 +#include "ibm.h"
    58.6 +#include "mem.h"
    58.7 +#include "pci.h"
    58.8 +#include "vid_voodoo.h"
    58.9 +
   58.10 +static int tris = 0;
   58.11 +
   58.12 +static struct voodoo
   58.13 +{
   58.14 +        int pci_enable;
   58.15 +
   58.16 +        uint32_t color0, color1;
   58.17 +        
   58.18 +        uint8_t dac_data[8];
   58.19 +        int dac_reg;
   58.20 +        uint8_t dac_readdata;
   58.21 +        
   58.22 +        uint32_t dRdX, dGdX, dBdX, dZdX, dAdX, dSdX, dTdX, dWdX;
   58.23 +        
   58.24 +        uint32_t dRdY, dGdY, dBdY, dZdY, dAdY, dSdY, dTdY, dWdY;
   58.25 +        
   58.26 +        uint32_t fbiInit0, fbiInit1, fbiInit2, fbiInit3, fbiInit4;
   58.27 +        
   58.28 +        uint32_t fbzMode;
   58.29 +        
   58.30 +        uint8_t initEnable;
   58.31 +        
   58.32 +        uint32_t lfbMode;
   58.33 +        
   58.34 +        uint32_t memBaseAddr;
   58.35 +        
   58.36 +        uint32_t startR, startG, startB, startZ, startA, startS, startT, startW;
   58.37 +        
   58.38 +        uint32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy;
   58.39 +        
   58.40 +        uint32_t front_offset, back_offset, aux_offset;
   58.41 +        
   58.42 +        uint32_t fb_read_offset, fb_write_offset;
   58.43 +        
   58.44 +        uint32_t draw_offset;
   58.45 +        
   58.46 +        int row_width;
   58.47 +        
   58.48 +        uint8_t *fb_mem, *tex_mem;
   58.49 +} voodoo;
   58.50 +
   58.51 +enum
   58.52 +{
   58.53 +        SST_status = 0x000,
   58.54 +        
   58.55 +        SST_vertexAx = 0x008,
   58.56 +        SST_vertexAy = 0x00c,
   58.57 +        SST_vertexBx = 0x010,
   58.58 +        SST_vertexBy = 0x014,
   58.59 +        SST_vertexCx = 0x018,
   58.60 +        SST_vertexCy = 0x01c,
   58.61 +        
   58.62 +        SST_startR   = 0x0020,
   58.63 +        SST_startG   = 0x0024,
   58.64 +        SST_startB   = 0x0028,
   58.65 +        SST_startZ   = 0x002c,
   58.66 +        SST_startA   = 0x0030,
   58.67 +        SST_startS   = 0x0034,
   58.68 +        SST_startT   = 0x0038,
   58.69 +        SST_startW   = 0x003c,
   58.70 +
   58.71 +        SST_dRdX     = 0x0040,
   58.72 +        SST_dGdX     = 0x0044,
   58.73 +        SST_dBdX     = 0x0048,
   58.74 +        SST_dZdX     = 0x004c,
   58.75 +        SST_dAdX     = 0x0050,
   58.76 +        SST_dSdX     = 0x0054,
   58.77 +        SST_dTdX     = 0x0058,
   58.78 +        SST_dWdX     = 0x005c,
   58.79 +        
   58.80 +        SST_dRdY     = 0x0060,
   58.81 +        SST_dGdY     = 0x0064,
   58.82 +        SST_dBdY     = 0x0068,
   58.83 +        SST_dZdY     = 0x006c,
   58.84 +        SST_dAdY     = 0x0070,
   58.85 +        SST_dSdY     = 0x0074,
   58.86 +        SST_dTdY     = 0x0078,
   58.87 +        SST_dWdY     = 0x007c,
   58.88 +        
   58.89 +        SST_triangleCMD = 0x0080,
   58.90 +        
   58.91 +        SST_fbzMode = 0x110,
   58.92 +        SST_lfbMode = 0x114,
   58.93 +        SST_swapbufferCMD = 0x128,
   58.94 +        
   58.95 +        SST_color0 = 0x144,
   58.96 +        SST_color1 = 0x148,
   58.97 +        
   58.98 +        SST_fbiInit4 = 0x200,
   58.99 +        SST_fbiInit0 = 0x210,
  58.100 +        SST_fbiInit1 = 0x214,
  58.101 +        SST_fbiInit2 = 0x218,
  58.102 +        SST_fbiInit3 = 0x21c,
  58.103 +        SST_dacData = 0x22c
  58.104 +};
  58.105 +
  58.106 +enum
  58.107 +{
  58.108 +        LFB_WRITE_FRONT = 0x0000,
  58.109 +        LFB_WRITE_BACK  = 0x0010,
  58.110 +        LFB_WRITE_MASK  = 0x0030
  58.111 +};
  58.112 +
  58.113 +enum
  58.114 +{
  58.115 +        LFB_READ_FRONT = 0x0000,
  58.116 +        LFB_READ_BACK  = 0x0040,
  58.117 +        LFB_READ_AUX   = 0x0080,
  58.118 +        LFB_READ_MASK  = 0x00c0
  58.119 +};
  58.120 +
  58.121 +enum
  58.122 +{
  58.123 +        LFB_FORMAT_RGB565 = 0,
  58.124 +        LFB_FORMAT_DEPTH = 15,
  58.125 +        LFB_FORMAT_MASK = 15
  58.126 +};
  58.127 +
  58.128 +enum
  58.129 +{
  58.130 +        LFB_WRITE_COLOUR = 1,
  58.131 +        LFB_WRITE_DEPTH = 2
  58.132 +};
  58.133 +
  58.134 +enum
  58.135 +{
  58.136 +        FBZ_DITHER  = 0x100,
  58.137 +        FBZ_DRAWRGB = 0x200,
  58.138 +        
  58.139 +        FBZ_DRAW_FRONT = 0x0000,
  58.140 +        FBZ_DRAW_BACK  = 0x4000,
  58.141 +        FBZ_DRAW_MASK  = 0xc000
  58.142 +};
  58.143 +
  58.144 +static int voodoo_reads = 0;
  58.145 +
  58.146 +static void voodoo_recalc()
  58.147 +{
  58.148 +        uint32_t buffer_offset = ((voodoo.fbiInit2 >> 11) & 511) * 4096;
  58.149 +        
  58.150 +        voodoo.front_offset = 0;
  58.151 +        voodoo.back_offset = buffer_offset;
  58.152 +        voodoo.aux_offset = buffer_offset * 2;
  58.153 +        
  58.154 +        switch (voodoo.lfbMode & LFB_WRITE_MASK)
  58.155 +        {
  58.156 +                case LFB_WRITE_FRONT:
  58.157 +                voodoo.fb_write_offset = voodoo.front_offset;
  58.158 +                break;
  58.159 +                case LFB_WRITE_BACK:
  58.160 +                voodoo.fb_write_offset = voodoo.back_offset;
  58.161 +                break;
  58.162 +
  58.163 +                default:
  58.164 +                fatal("voodoo_recalc : unknown lfb destination\n");
  58.165 +        }
  58.166 +
  58.167 +        switch (voodoo.lfbMode & LFB_READ_MASK)
  58.168 +        {
  58.169 +                case LFB_READ_FRONT:
  58.170 +                voodoo.fb_read_offset = voodoo.front_offset;
  58.171 +                break;
  58.172 +                case LFB_READ_BACK:
  58.173 +                voodoo.fb_read_offset = voodoo.back_offset;
  58.174 +                break;
  58.175 +                case LFB_READ_AUX:
  58.176 +                voodoo.fb_read_offset = voodoo.aux_offset;
  58.177 +                break;
  58.178 +
  58.179 +                default:
  58.180 +                fatal("voodoo_recalc : unknown lfb source\n");
  58.181 +        }
  58.182 +        
  58.183 +        switch (voodoo.fbzMode & FBZ_DRAW_MASK)
  58.184 +        {
  58.185 +                case FBZ_DRAW_FRONT:
  58.186 +                voodoo.draw_offset = voodoo.front_offset;
  58.187 +                break;
  58.188 +                case FBZ_DRAW_BACK:
  58.189 +                voodoo.draw_offset = voodoo.back_offset;
  58.190 +                break;
  58.191 +
  58.192 +                default:
  58.193 +                fatal("voodoo_recalc : unknown draw buffer\n");
  58.194 +        }
  58.195 +                
  58.196 +        voodoo.row_width = ((voodoo.fbiInit1 >> 4) & 15) * 64 * 2;
  58.197 +        pclog("voodoo_recalc : front_offset %08X  back_offset %08X  aux_offset %08X\n", voodoo.front_offset, voodoo.back_offset, voodoo.aux_offset);
  58.198 +        pclog("                fb_read_offset %08X  fb_write_offset %08X  row_width %i\n", voodoo.fb_read_offset, voodoo.fb_write_offset, voodoo.row_width);
  58.199 +}
  58.200 +
  58.201 +static int dither_matrix_4x4[16] =
  58.202 +{
  58.203 +	 0,  8,  2, 10,
  58.204 +	12,  4, 14,  6,
  58.205 +	 3, 11,  1,  9,
  58.206 +	15,  7, 13,  5
  58.207 +};
  58.208 +
  58.209 +static int dither_rb[256][4][4];
  58.210 +static int dither_g[256][4][4];
  58.211 +
  58.212 +static void voodoo_make_dither()
  58.213 +{
  58.214 +        int c, x, y;
  58.215 +        int seen_rb[1024];
  58.216 +        int seen_g[1024];
  58.217 +        
  58.218 +        for (c = 0; c < 256; c++)
  58.219 +        {
  58.220 +                int rb = (int)(((double)c *  496.0) / 256.0);
  58.221 +                int  g = (int)(((double)c * 1008.0) / 256.0);
  58.222 +                pclog("rb %i %i\n", rb, c);
  58.223 +                for (y = 0; y < 4; y++)
  58.224 +                {
  58.225 +                        for (x = 0; x < 4; x++)
  58.226 +                        {
  58.227 +                                int val;
  58.228 +                                
  58.229 +                                val = rb + dither_matrix_4x4[x + (y << 2)];
  58.230 +                                dither_rb[c][y][x] = val >> 4;
  58.231 +                                pclog("RB %i %i, %i  %i %i %i\n", c, x, y, val, val >> 4, dither_rb[c][y][x]);
  58.232 +                                
  58.233 +                                if (dither_rb[c][y][x] > 31)
  58.234 +                                        fatal("RB overflow %i %i %i  %i\n", c, x, y, dither_rb[c][y][x]);
  58.235 +
  58.236 +                                val = g + dither_matrix_4x4[x + (y << 2)];
  58.237 +                                dither_g[c][y][x] = val >> 4;                                
  58.238 +
  58.239 +                                if (dither_g[c][y][x] > 63)
  58.240 +                                        fatal("G overflow %i %i %i  %i\n", c, x, y, dither_g[c][y][x]);
  58.241 +                        }
  58.242 +                }
  58.243 +        }
  58.244 +        
  58.245 +        memset(seen_rb, 0, sizeof(seen_rb));
  58.246 +        memset(seen_g,  0, sizeof(seen_g));
  58.247 +        
  58.248 +        for (c = 0; c < 256; c++)
  58.249 +        {
  58.250 +                int total_rb = 0;
  58.251 +                int total_g = 0;
  58.252 +                for (y = 0; y < 4; y++)
  58.253 +                {
  58.254 +                        for (x = 0; x < 4; x++)
  58.255 +                        {
  58.256 +                                total_rb += dither_rb[c][y][x];
  58.257 +                                pclog("total_rb %i %i, %i  %i %i\n", c, x, y, total_rb, dither_rb[c][y][x]);
  58.258 +                                total_g += dither_g[c][y][x];
  58.259 +                        }
  58.260 +                }
  58.261 +
  58.262 +                if (seen_rb[total_rb])
  58.263 +                        fatal("Duplicate rb %i %i\n", c, total_rb);
  58.264 +                seen_rb[total_rb] = 1;
  58.265 +
  58.266 +                if (seen_g[total_g])
  58.267 +                        fatal("Duplicate g %i %i\n", c, total_g);
  58.268 +                seen_g[total_g] = 1;
  58.269 +        }
  58.270 +}
  58.271 +
  58.272 +static void voodoo_triangle(struct voodoo *voodoo)
  58.273 +{
  58.274 +        int y, yend, ydir;
  58.275 +        int xstart, xend, xdir;
  58.276 +        int dx1, dx2;
  58.277 +        
  58.278 +        pclog("voodoo_triangle %i : vA %f, %f  vB %f, %f  vC %f, %f\n", tris, (float)voodoo->vertexAx / 16.0, (float)voodoo->vertexAy / 16.0, 
  58.279 +                                                                     (float)voodoo->vertexBx / 16.0, (float)voodoo->vertexBy / 16.0, 
  58.280 +                                                                     (float)voodoo->vertexCx / 16.0, (float)voodoo->vertexCy / 16.0);
  58.281 +//        output = 3;
  58.282 +        tris++;
  58.283 +//        if (tris == 3)
  58.284 +//                fatal("tris 2\n");
  58.285 +
  58.286 +        y = voodoo->vertexAy >> 4;
  58.287 +        ydir = (voodoo->vertexAy >= voodoo->vertexCy) ? -1 : 1;
  58.288 +
  58.289 +        if (voodoo->vertexAy == voodoo->vertexBy)
  58.290 +        {
  58.291 +                xstart = voodoo->vertexAx << 8;
  58.292 +                xend = voodoo->vertexBx << 8;
  58.293 +        }
  58.294 +        else
  58.295 +                xstart = xend = voodoo->vertexAx << 8;
  58.296 +        xdir = (xstart >= xend) ? -1 : 1;
  58.297 +        
  58.298 +        if (voodoo->vertexAy != voodoo->vertexBy)
  58.299 +        {
  58.300 +                /*Draw top half*/
  58.301 +                dx1 = (int)(((voodoo->vertexBx << 8) - xstart) << 4) / (int)((voodoo->vertexBy - voodoo->vertexAy) * ydir);
  58.302 +                dx2 = (int)(((voodoo->vertexCx << 8) -   xend) << 4) / (int)((voodoo->vertexCy - voodoo->vertexAy) * ydir);
  58.303 +                yend = voodoo->vertexBy >> 4;
  58.304 +                
  58.305 +                pclog("voodoo_triangle : top-half %X %X %X %X %i  %i %i %i\n", xstart, xend, dx1, dx2, xdir,  y, yend, ydir);
  58.306 +                
  58.307 +                for (; y != yend; y += ydir)
  58.308 +                {
  58.309 +                        pclog("    %i : %i - %i\n", xstart >> 12, xend >> 12);
  58.310 +                        xstart += dx1;
  58.311 +                        xend += dx2;
  58.312 +                }
  58.313 +        }
  58.314 +        
  58.315 +        
  58.316 +        if (voodoo->vertexBy != voodoo->vertexCy)
  58.317 +        {        
  58.318 +                /*Draw bottom half*/
  58.319 +                dx1 = (int)(((voodoo->vertexCx << 8) - xstart) << 4) / (int)((voodoo->vertexCy - voodoo->vertexAy) * ydir);
  58.320 +                dx2 = (int)(((voodoo->vertexCx << 8) -   xend) << 4) / (int)((voodoo->vertexCy - voodoo->vertexAy) * ydir);
  58.321 +                yend = voodoo->vertexCy >> 4;
  58.322 +                                
  58.323 +                pclog("voodoo_triangle : bottom-half %X %X %X %X %X %i  %i %i %i\n", xstart, xend, dx1, dx2, dx2 * 36, xdir,  y, yend, ydir);
  58.324 +
  58.325 +                for (; y != yend; y += ydir)
  58.326 +                {
  58.327 +                        int x = xstart >> 12, x2 = xend >> 12;
  58.328 +                        pclog("    %i : %i - %i\n", y, x, x2);
  58.329 +                        
  58.330 +                        for (; x != x2; x += xdir)
  58.331 +                        {
  58.332 +                                if (voodoo->fbzMode & FBZ_DRAWRGB)
  58.333 +                                {
  58.334 +                                        int r = (voodoo->color1 >> 16) & 0xff;
  58.335 +                                        int g = (voodoo->color1 >> 8)  & 0xff;
  58.336 +                                        int b =  voodoo->color1        & 0xff;
  58.337 +                                        if (voodoo->fbzMode & FBZ_DITHER)
  58.338 +                                        {
  58.339 +                                                r = dither_rb[r][y & 3][x & 3];
  58.340 +                                                g =  dither_g[g][y & 3][x & 3];
  58.341 +                                                b = dither_rb[b][y & 3][x & 3];
  58.342 +/*                                                r = ((r << 1) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 4;
  58.343 +                                                g = ((g << 2) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 4;
  58.344 +                                                b = ((b << 1) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 4;
  58.345 +                                                if (r > 31) r = 31;
  58.346 +                                                if (g > 63) g = 63;
  58.347 +                                                if (b > 31) b = 31;*/
  58.348 +/*                                                r = (((r << 1) - (r >> 4) + (r >> 7) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 1) >> 3;
  58.349 +                                                g = (((g << 2) - (g >> 4) + (g >> 6) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 2) >> 2;
  58.350 +                                                b = (((b << 1) - (b >> 4) + (b >> 7) + dither_matrix_4x4[(x & 3) + ((y & 3) << 2)]) >> 1) >> 3;*/
  58.351 +                                        }
  58.352 +                                        else
  58.353 +                                        {
  58.354 +                                                r >>= 3;
  58.355 +                                                g >>= 2;
  58.356 +                                                b >>= 3;
  58.357 +                                        }
  58.358 +                                        *(uint16_t *)(&voodoo->fb_mem[voodoo->draw_offset + (y * voodoo->row_width) + (x << 1)]) = b | (g << 5) | (r << 11);
  58.359 +                                        pclog("       %i = %i %i %i %04X  %08X   %08X\n", x, r, g, b, b | (g << 5) | (r << 11), voodoo->draw_offset + (y * voodoo->row_width) + (x << 1), *(uint32_t *)(&voodoo->fb_mem[4]));
  58.360 +                                }
  58.361 +                        }
  58.362 +                        xstart += dx1;
  58.363 +                        xend += dx2;
  58.364 +                }
  58.365 +        }
  58.366 +                
  58.367 +/*        for (y = ystart, y != yend; y += ydir)
  58.368 +        {
  58.369 +                if (voodoo.fbzMode & FBZ_DITHER
  58.370 +        }*/
  58.371 +}
  58.372 +
  58.373 +static uint32_t voodoo_readl(uint32_t addr, void *priv)
  58.374 +{
  58.375 +        uint32_t temp;
  58.376 +        switch (addr & 0x3fc)
  58.377 +        {
  58.378 +                case SST_status:
  58.379 +                temp = 0x0ffff03f; /*FIFOs empty*/
  58.380 +                break;
  58.381 +                
  58.382 +                case SST_lfbMode:
  58.383 +                return voodoo.lfbMode;
  58.384 +                
  58.385 +                case SST_fbiInit4:
  58.386 +                temp = voodoo.fbiInit4;
  58.387 +                break;
  58.388 +                case SST_fbiInit0:
  58.389 +                temp = voodoo.fbiInit0;
  58.390 +                break;
  58.391 +                case SST_fbiInit1:
  58.392 +                temp = voodoo.fbiInit1 & ~5; /*Pass-thru board with one SST-1*/
  58.393 +                break;              
  58.394 +                case SST_fbiInit2:
  58.395 +                if (voodoo.initEnable & 0x04)
  58.396 +                        temp = voodoo.dac_readdata;
  58.397 +                else
  58.398 +                        temp = voodoo.fbiInit2;
  58.399 +                break;
  58.400 +                case SST_fbiInit3:
  58.401 +                temp = voodoo.fbiInit3;
  58.402 +                break;
  58.403 +                
  58.404 +                default:
  58.405 +                fatal("voodoo_readl  : bad addr %08X\n", addr);
  58.406 +                temp = 0xffffffff;
  58.407 +        }
  58.408 +        pclog("voodoo_readl  : addr %08X val %08X  %04X(%08X):%08X  %i\n", addr, temp, CS, cs, pc, voodoo_reads++);
  58.409 +//        if (voodoo_reads == 200494)
  58.410 +//          output = 3;
  58.411 +        return temp;
  58.412 +}
  58.413 +
  58.414 +static void voodoo_writel(uint32_t addr, uint32_t val, void *priv)
  58.415 +{
  58.416 +        pclog("voodoo_writel : addr %08X val %08X  %04X(%08X):%08X\n", addr, val, CS, cs, pc);
  58.417 +        switch (addr & 0x3fc)
  58.418 +        {
  58.419 +                case SST_swapbufferCMD:
  58.420 +                pclog("  start swap buffer command\n");
  58.421 +//                output = 3;
  58.422 +                break;
  58.423 +                        
  58.424 +                case SST_vertexAx:
  58.425 +                voodoo.vertexAx = val & 0xffff;
  58.426 +                break;
  58.427 +                case SST_vertexAy:
  58.428 +                voodoo.vertexAy = val & 0xffff;
  58.429 +                break;
  58.430 +                case SST_vertexBx:
  58.431 +                voodoo.vertexBx = val & 0xffff;
  58.432 +                break;
  58.433 +                case SST_vertexBy:
  58.434 +                voodoo.vertexBy = val & 0xffff;
  58.435 +                break;
  58.436 +                case SST_vertexCx:
  58.437 +                voodoo.vertexCx = val & 0xffff;
  58.438 +                break;
  58.439 +                case SST_vertexCy:
  58.440 +                voodoo.vertexCy = val & 0xffff;
  58.441 +                break;
  58.442 +                
  58.443 +                case SST_startR:
  58.444 +                voodoo.startR = val & 0xffffff;
  58.445 +                break;
  58.446 +                case SST_startG:
  58.447 +                voodoo.startG = val & 0xffffff;
  58.448 +                break;
  58.449 +                case SST_startB:
  58.450 +                voodoo.startB = val & 0xffffff;
  58.451 +                break;
  58.452 +                case SST_startZ:
  58.453 +                voodoo.startZ = val;
  58.454 +                break;
  58.455 +                case SST_startA:
  58.456 +                voodoo.startA = val & 0xffffff;
  58.457 +                break;
  58.458 +                case SST_startS:
  58.459 +                voodoo.startS = val;
  58.460 +                break;
  58.461 +                case SST_startT:
  58.462 +                voodoo.startT = val;
  58.463 +                break;
  58.464 +                case SST_startW:
  58.465 +                voodoo.startW = val;
  58.466 +                break;
  58.467 +
  58.468 +                case SST_dRdX:
  58.469 +                voodoo.dRdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0);
  58.470 +                break;
  58.471 +                case SST_dGdX:
  58.472 +                voodoo.dGdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0);
  58.473 +                break;
  58.474 +                case SST_dBdX:
  58.475 +                voodoo.dBdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0);
  58.476 +                break;
  58.477 +                case SST_dZdX:
  58.478 +                voodoo.dZdX = val;
  58.479 +                break;
  58.480 +                case SST_dAdX:
  58.481 +                voodoo.dAdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0);
  58.482 +                break;
  58.483 +                case SST_dSdX:
  58.484 +                voodoo.dSdX = val;
  58.485 +                break;
  58.486 +                case SST_dTdX:
  58.487 +                voodoo.dTdX = val;
  58.488 +                break;
  58.489 +                case SST_dWdX:
  58.490 +                voodoo.dWdX = val;
  58.491 +                break;
  58.492 +
  58.493 +                case SST_dRdY:
  58.494 +                voodoo.dRdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0);
  58.495 +                break;
  58.496 +                case SST_dGdY:
  58.497 +                voodoo.dGdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0);
  58.498 +                break;
  58.499 +                case SST_dBdY:
  58.500 +                voodoo.dBdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0);
  58.501 +                break;
  58.502 +                case SST_dZdY:
  58.503 +                voodoo.dZdY = val;
  58.504 +                break;
  58.505 +                case SST_dAdY:
  58.506 +                voodoo.dAdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0);
  58.507 +                break;
  58.508 +                case SST_dSdY:
  58.509 +                voodoo.dSdY = val;
  58.510 +                break;
  58.511 +                case SST_dTdY:
  58.512 +                voodoo.dTdY = val;
  58.513 +                break;
  58.514 +                case SST_dWdY:
  58.515 +                voodoo.dWdY = val;
  58.516 +                break;
  58.517 +
  58.518 +                case SST_triangleCMD:
  58.519 +                voodoo_triangle(&voodoo);
  58.520 +                break;
  58.521 +                
  58.522 +                        
  58.523 +                case SST_fbzMode:
  58.524 +                voodoo.fbzMode = val;
  58.525 +                break;
  58.526 +                case SST_lfbMode:
  58.527 +                voodoo.lfbMode = val;
  58.528 +                voodoo_recalc();
  58.529 +                break;
  58.530 +
  58.531 +                case SST_color0:
  58.532 +                voodoo.color0 = val;
  58.533 +                break;
  58.534 +                case SST_color1:
  58.535 +                voodoo.color1 = val;
  58.536 +                break;
  58.537 +
  58.538 +                case SST_fbiInit4:
  58.539 +                if (voodoo.initEnable & 0x01)
  58.540 +                        voodoo.fbiInit4 = val;
  58.541 +                break;
  58.542 +                case SST_fbiInit0:
  58.543 +                if (voodoo.initEnable & 0x01)
  58.544 +                        voodoo.fbiInit0 = val;
  58.545 +                break;
  58.546 +                case SST_fbiInit1:
  58.547 +                if (voodoo.initEnable & 0x01)
  58.548 +                        voodoo.fbiInit1 = val;
  58.549 +                break;
  58.550 +                case SST_fbiInit2:
  58.551 +                if (voodoo.initEnable & 0x01)
  58.552 +                {
  58.553 +                        voodoo.fbiInit2 = val;
  58.554 +                        voodoo_recalc();
  58.555 +                }
  58.556 +                break;
  58.557 +                case SST_fbiInit3:
  58.558 +                if (voodoo.initEnable & 0x01)
  58.559 +                        voodoo.fbiInit3 = val;
  58.560 +                break;
  58.561 +                
  58.562 +                case SST_dacData:
  58.563 +                voodoo.dac_reg = (val >> 8) & 7;
  58.564 +                voodoo.dac_readdata = 0xff;
  58.565 +                if (val & 0x800)
  58.566 +                {
  58.567 +                        pclog("  dacData read %i %02X\n", voodoo.dac_reg, voodoo.dac_data[7]);
  58.568 +                        if (voodoo.dac_reg == 5)
  58.569 +                        {
  58.570 +                                switch (voodoo.dac_data[7])
  58.571 +                                {
  58.572 +        				case 0x01: voodoo.dac_readdata = 0x55; break;
  58.573 +        				case 0x07: voodoo.dac_readdata = 0x71; break;
  58.574 +        				case 0x0b: voodoo.dac_readdata = 0x79; break;
  58.575 +                                }
  58.576 +                        }
  58.577 +                        else
  58.578 +                                voodoo.dac_readdata = voodoo.dac_data[voodoo.dac_readdata];
  58.579 +                }
  58.580 +                else
  58.581 +                        voodoo.dac_data[voodoo.dac_reg] = val & 0xff;
  58.582 +                break;
  58.583 +        }
  58.584 +}
  58.585 +
  58.586 +static uint16_t voodoo_fb_readw(uint32_t addr, void *priv)
  58.587 +{
  58.588 +        pclog("voodoo_fb_readw : %08X %04X\n", addr, *(uint16_t *)(&voodoo.fb_mem[addr & 0x1fffff]));
  58.589 +        return *(uint16_t *)(&voodoo.fb_mem[addr & 0x1fffff]);
  58.590 +}
  58.591 +static uint32_t voodoo_fb_readl(uint32_t addr, void *priv)
  58.592 +{
  58.593 +        int x, y;
  58.594 +        uint32_t read_addr;
  58.595 +        uint32_t temp;
  58.596 +        
  58.597 +        x = (addr >> 1) & 0x3ff;
  58.598 +        y = (addr >> 11) & 0x3ff;
  58.599 +        read_addr = voodoo.fb_read_offset + (x << 1) + (y * voodoo.row_width);
  58.600 +        
  58.601 +        temp = *(uint32_t *)(&voodoo.fb_mem[read_addr & 0x1fffff]);
  58.602 +
  58.603 +        pclog("voodoo_fb_readl : %08X %08X  %i %i  %08X %08X\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo.fb_mem[4]));
  58.604 +        return temp;
  58.605 +}
  58.606 +static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv)
  58.607 +{
  58.608 +        pclog("voodoo_fb_writew : %08X %04X\n", addr, val);
  58.609 +        *(uint16_t *)(&voodoo.fb_mem[addr & 0x1fffff]) = val;
  58.610 +}
  58.611 +static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv)
  58.612 +{
  58.613 +        int x, y;
  58.614 +        uint32_t write_addr, write_addr_aux;
  58.615 +        uint32_t colour_data, depth_data;
  58.616 +        int write_mask, count = 1;
  58.617 +        
  58.618 +        pclog("voodoo_fb_writel : %08X %08X\n", addr, val);
  58.619 +        
  58.620 +        if (voodoo.lfbMode & 0x100)
  58.621 +                fatal("voodoo_fb_writel : using pixel processing\n");
  58.622 +                
  58.623 +        switch (voodoo.lfbMode & LFB_FORMAT_MASK)
  58.624 +        {
  58.625 +                case LFB_FORMAT_RGB565:
  58.626 +                colour_data = val;
  58.627 +                write_mask = LFB_WRITE_COLOUR;
  58.628 +                break;
  58.629 +                
  58.630 +                case LFB_FORMAT_DEPTH:
  58.631 +                depth_data = val;
  58.632 +                write_mask = LFB_WRITE_DEPTH;
  58.633 +                addr <<= 1;
  58.634 +                count = 2;
  58.635 +                break;
  58.636 +                
  58.637 +                default:
  58.638 +                fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo.lfbMode);
  58.639 +        }
  58.640 +
  58.641 +        x = addr & 0x3fe;
  58.642 +        y = (addr >> 10) & 0x3ff;
  58.643 +
  58.644 +        write_addr = voodoo.fb_read_offset + x + (y * voodoo.row_width);      
  58.645 +        write_addr_aux = voodoo.aux_offset + x + (y * voodoo.row_width);
  58.646 +        
  58.647 +        while (count--)
  58.648 +        {               
  58.649 +                if (write_mask & LFB_WRITE_COLOUR)
  58.650 +                        *(uint16_t *)(&voodoo.fb_mem[write_addr & 0x1ffffe]) = colour_data;
  58.651 +                if (write_mask & LFB_WRITE_DEPTH)
  58.652 +                        *(uint16_t *)(&voodoo.fb_mem[write_addr_aux & 0x1ffffe]) = depth_data;
  58.653 +                        
  58.654 +                colour_data >>= 16;
  58.655 +                depth_data >>= 16;
  58.656 +                
  58.657 +                write_addr += 2;
  58.658 +                write_addr_aux += 2;
  58.659 +        }
  58.660 +}
  58.661 +
  58.662 +static void voodoo_tex_writew(uint32_t addr, uint16_t val, void *priv)
  58.663 +{
  58.664 +        pclog("voodoo_tex_write : %08X %04X\n", addr, val);
  58.665 +        *(uint16_t *)(&voodoo.tex_mem[addr & 0x1fffff]) = val;
  58.666 +}
  58.667 +static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *priv)
  58.668 +{
  58.669 +        pclog("voodoo_tex_write : %08X %08X\n", addr, val);
  58.670 +        *(uint32_t *)(&voodoo.tex_mem[addr & 0x1fffff]) = val;
  58.671 +}
  58.672 +
  58.673 +static void voodoo_recalcmapping()
  58.674 +{
  58.675 +        mem_removehandler(0x00000000, 0xffffffff, NULL, NULL, voodoo_readl, NULL, NULL, voodoo_writel, NULL);
  58.676 +        mem_removehandler(0x00000000, 0xffffffff, NULL, voodoo_fb_readw, voodoo_fb_readl, NULL, voodoo_fb_writew, voodoo_fb_writel, NULL);
  58.677 +        mem_removehandler(0x00000000, 0xffffffff, NULL, NULL, NULL, NULL, voodoo_tex_writew, voodoo_tex_writel, NULL);
  58.678 +        if (voodoo.pci_enable)
  58.679 +        {
  58.680 +                pclog("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo.memBaseAddr);
  58.681 +                mem_sethandler(voodoo.memBaseAddr,              0x003fffff, NULL, NULL, voodoo_readl, NULL, NULL, voodoo_writel, NULL);
  58.682 +                mem_sethandler(voodoo.memBaseAddr + 0x00400000, 0x003fffff, NULL, voodoo_fb_readw, voodoo_fb_readl, NULL, voodoo_fb_writew, voodoo_fb_writel, NULL);
  58.683 +                mem_sethandler(voodoo.memBaseAddr + 0x00800000, 0x007fffff, NULL, NULL, NULL, NULL, voodoo_tex_writew, voodoo_tex_writel, NULL);
  58.684 +        }
  58.685 +        else
  58.686 +                pclog("voodoo_recalcmapping : disabled\n");
  58.687 +}
  58.688 +
  58.689 +uint8_t voodoo_pci_read(int func, int addr, void *priv)
  58.690 +{
  58.691 +        pclog("Voodoo PCI read %08X\n", addr);
  58.692 +        switch (addr)
  58.693 +        {
  58.694 +                case 0x00: return 0x1a; /*3dfx*/
  58.695 +                case 0x01: return 0x12;
  58.696 +                
  58.697 +                case 0x02: return 0x01; /*SST-1 (Voodoo Graphics)*/
  58.698 +                case 0x03: return 0x00;
  58.699 +                
  58.700 +                case 0x04: return voodoo.pci_enable ? 0x02 : 0x00; /*Respond to memory accesses*/
  58.701 +
  58.702 +                case 0x08: return 0; /*Revision ID*/
  58.703 +                case 0x09: return 0; /*Programming interface*/
  58.704 +                
  58.705 +                case 0x10: return 0x00; /*memBaseAddr*/
  58.706 +                case 0x11: return 0x00;
  58.707 +                case 0x12: return 0x00;
  58.708 +                case 0x13: return voodoo.memBaseAddr >> 24;
  58.709 +
  58.710 +                case 0x40: return voodoo.initEnable;
  58.711 +        }
  58.712 +        return 0;
  58.713 +}
  58.714 +
  58.715 +void voodoo_pci_write(int func, int addr, uint8_t val, void *priv)
  58.716 +{
  58.717 +        pclog("Voodoo PCI write %04X %02X\n", addr, val);
  58.718 +        switch (addr)
  58.719 +        {
  58.720 +                case 0x04: voodoo.pci_enable = val & 2; voodoo_recalcmapping(); break;
  58.721 +                
  58.722 +                case 0x13: voodoo.memBaseAddr = val << 24; voodoo_recalcmapping(); break;
  58.723 +                
  58.724 +                case 0x40: voodoo.initEnable = val; break;
  58.725 +        }
  58.726 +}
  58.727 +
  58.728 +void voodoo_init()
  58.729 +{
  58.730 +        return;
  58.731 +        voodoo_make_dither();
  58.732 +        pci_add(voodoo_pci_read, voodoo_pci_write, NULL);
  58.733 +        voodoo.fb_mem = malloc(2 * 1024 * 1024);
  58.734 +        voodoo.tex_mem = malloc(2 * 1024 * 1024);        
  58.735 +}
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/src/vid_voodoo.h	Mon May 27 19:56:33 2013 +0100
    59.3 @@ -0,0 +1,1 @@
    59.4 +void voodoo_init();
    60.1 --- a/src/x86.c	Mon May 27 17:46:42 2013 +0100
    60.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.3 @@ -1,3686 +0,0 @@
    60.4 -//1B64 - Vid_SetMode (Vid_Vesa.c)
    60.5 -//6689c - CONS_Printf
    60.6 -/*SHR AX,1
    60.7 -
    60.8 -        4 clocks - fetch opcode
    60.9 -        4 clocks - fetch mod/rm
   60.10 -        2 clocks - execute              2 clocks - fetch opcode 1
   60.11 -                                        2 clocks - fetch opcode 2
   60.12 -                                        4 clocks - fetch mod/rm
   60.13 -        2 clocks - fetch opcode 1       2 clocks - execute
   60.14 -        2 clocks - fetch opcode 2  etc*/
   60.15 -#include <stdio.h>
   60.16 -#include "ibm.h"
   60.17 -#include "x86.h"
   60.18 -#include "mem.h"
   60.19 -#include "keyboard.h"
   60.20 -
   60.21 -int nextcyc=0;
   60.22 -int cycdiff;
   60.23 -int is8086=0;
   60.24 -
   60.25 -int memcycs;
   60.26 -int nopageerrors=0;
   60.27 -float cassettetime;
   60.28 -
   60.29 -void FETCHCOMPLETE();
   60.30 -
   60.31 -uint8_t readmembl(uint32_t addr);
   60.32 -void writemembl(uint32_t addr, uint8_t val);
   60.33 -uint16_t readmemwl(uint32_t seg, uint32_t addr);
   60.34 -void writememwl(uint32_t seg, uint32_t addr, uint16_t val);
   60.35 -uint32_t readmemll(uint32_t seg, uint32_t addr);
   60.36 -void writememll(uint32_t seg, uint32_t addr, uint32_t val);
   60.37 -
   60.38 -#undef readmemb
   60.39 -#undef readmemw
   60.40 -uint8_t readmemb(uint32_t a)
   60.41 -{
   60.42 -        if (a!=(cs+pc)) memcycs+=4;
   60.43 -        if (readlookup2[(a)>>12]==0xFFFFFFFF) return readmembl(a);
   60.44 -        else return ram[readlookup2[(a)>>12]+((a)&0xFFF)];
   60.45 -}
   60.46 -
   60.47 -uint8_t readmembf(uint32_t a)
   60.48 -{
   60.49 -        if (readlookup2[(a)>>12]==0xFFFFFFFF) return readmembl(a);
   60.50 -        else return ram[readlookup2[(a)>>12]+((a)&0xFFF)];
   60.51 -}
   60.52 -
   60.53 -uint16_t readmemw(uint32_t s, uint16_t a)
   60.54 -{
   60.55 -        if (a!=(cs+pc)) memcycs+=(8>>is8086);
   60.56 -        if ((readlookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF)) return readmemwl(s,a);
   60.57 -        else return *((uint16_t *)(&ram[readlookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]));
   60.58 -}
   60.59 -
   60.60 -void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); memcycs+=4; }
   60.61 -
   60.62 -#undef fetchea
   60.63 -#define fetchea()   { rmdat=FETCH();  \
   60.64 -                    reg=(rmdat>>3)&7;             \
   60.65 -                    mod=(rmdat>>6)&3;             \
   60.66 -                    rm=rmdat&7;                   \
   60.67 -                    if (mod!=3) fetcheal(); }
   60.68 -
   60.69 -void writemembl(uint32_t addr, uint8_t val);
   60.70 -void writememb(uint32_t a, uint8_t v)
   60.71 -{
   60.72 -        memcycs+=4;
   60.73 -        if (writelookup2[(a)>>12]==0xFFFFFFFF) writemembl(a,v);
   60.74 -        else ram[writelookup2[(a)>>12]+((a)&0xFFF)]=v;
   60.75 -}
   60.76 -void writememwl(uint32_t seg, uint32_t addr, uint16_t val);
   60.77 -void writememw(uint32_t s, uint32_t a, uint16_t v)
   60.78 -{
   60.79 -        memcycs+=(8>>is8086);
   60.80 -        if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememwl(s,a,v);
   60.81 -        else *((uint16_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v;
   60.82 -}
   60.83 -void writememll(uint32_t seg, uint32_t addr, uint32_t val);
   60.84 -void writememl(uint32_t s, uint32_t a, uint32_t v)
   60.85 -{
   60.86 -        if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememll(s,a,v);
   60.87 -        else *((uint32_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v;
   60.88 -}
   60.89 -
   60.90 -int lldt=0;
   60.91 -int notpresent;
   60.92 -uint16_t oldflags;
   60.93 -void dumpregs();
   60.94 -int incga;
   60.95 -uint32_t old8,old82,old83;
   60.96 -uint16_t oldcs;
   60.97 -int oldcpl;
   60.98 -
   60.99 -int dlE=0;
  60.100 -/*#define CS (cs>>4)
  60.101 -#define DS (ds>>4)
  60.102 -#define ES (es>>4)
  60.103 -#define SS (ss>>4)*/
  60.104 -
  60.105 -//#define loadseg(a) ((a)<<4)
  60.106 -
  60.107 -int keyboardtimer;
  60.108 -int tempc;
  60.109 -int bxcheck=0,spcheck=0;
  60.110 -uint16_t getword();
  60.111 -int count40=0;
  60.112 -int dosfunc;
  60.113 -uint8_t opcode;
  60.114 -int times=0;
  60.115 -uint16_t pc2,pc3;
  60.116 -int pit0=1;
  60.117 -int noint=0;
  60.118 -
  60.119 -int output=0;
  60.120 -
  60.121 -int shadowbios=0;
  60.122 -
  60.123 -int inint=0;
  60.124 -int ins=0;
  60.125 -//#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a))
  60.126 -
  60.127 -int ssegs;
  60.128 -
  60.129 -int fetchcycles=0,memcycs,fetchclocks;
  60.130 -
  60.131 -uint8_t prefetchqueue[6];
  60.132 -uint16_t prefetchpc;
  60.133 -int prefetchw=0;
  60.134 -inline uint8_t FETCH()
  60.135 -{
  60.136 -        uint8_t temp;
  60.137 -/*        temp=prefetchqueue[0];
  60.138 -        prefetchqueue[0]=prefetchqueue[1];
  60.139 -        prefetchqueue[1]=prefetchqueue[2];
  60.140 -        prefetchqueue[2]=prefetchqueue[3];
  60.141 -        prefetchqueue[3]=prefetchqueue[4];
  60.142 -        prefetchqueue[4]=prefetchqueue[5];
  60.143 -        if (prefetchw<=((is8086)?4:3))
  60.144 -        {
  60.145 -                prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++;
  60.146 -                if (is8086 && (prefetchpc&1))
  60.147 -                {
  60.148 -                        prefetchqueue[prefetchw++]=readmembf(cs+prefetchpc); prefetchpc++;
  60.149 -                }
  60.150 -        }*/
  60.151 -
  60.152 -//        uint8_t temp=readmemb(cs+pc);
  60.153 -//        if (output) printf("FETCH %04X %i\n",pc,fetchcycles);
  60.154 -        if (prefetchw==0) //(fetchcycles<4)
  60.155 -        {
  60.156 -                cycles-=(4-(fetchcycles&3));
  60.157 -                fetchclocks+=(4-(fetchcycles&3));
  60.158 -                fetchcycles=4;
  60.159 -                temp=readmembf(cs+pc);
  60.160 -                prefetchpc=pc=pc+1;
  60.161 -//                if (output) printf("   FETCH %04X:%04X %02X %04X %04X %i\n",CS,pc-1,temp,pc,prefetchpc,prefetchw);
  60.162 -                if (is8086 && (pc&1))
  60.163 -                {
  60.164 -                        prefetchqueue[0]=readmembf(cs+pc);
  60.165 -//                        if (output) printf("   PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]);
  60.166 -                        prefetchpc++;
  60.167 -                        prefetchw++;
  60.168 -                }
  60.169 -        }
  60.170 -        else
  60.171 -        {
  60.172 -                temp=prefetchqueue[0];
  60.173 -                prefetchqueue[0]=prefetchqueue[1];
  60.174 -                prefetchqueue[1]=prefetchqueue[2];
  60.175 -                prefetchqueue[2]=prefetchqueue[3];
  60.176 -                prefetchqueue[3]=prefetchqueue[4];
  60.177 -                prefetchqueue[4]=prefetchqueue[5];
  60.178 -                prefetchw--;
  60.179 -//                if (output) printf("PREFETCH %04X:%04X %02X %04X %04X %i\n",CS,pc,temp,pc,prefetchpc,prefetchw);
  60.180 -                fetchcycles-=4;
  60.181 -//                fetchclocks+=4;
  60.182 -                pc++;
  60.183 -        }
  60.184 -//        if (output) printf("%i\n",fetchcycles);
  60.185 -        return temp;
  60.186 -}
  60.187 -
  60.188 -inline void FETCHADD(int c)
  60.189 -{
  60.190 -        int d;
  60.191 -//        if (output) printf("FETCHADD %i\n",c);
  60.192 -        if (c<0) return;
  60.193 -        if (prefetchw>((is8086)?4:3)) return;
  60.194 -        d=c+(fetchcycles&3);
  60.195 -        while (d>3 && prefetchw<((is8086)?6:4))
  60.196 -        {
  60.197 -                d-=4;
  60.198 -                if (is8086 && !(prefetchpc&1))
  60.199 -                {
  60.200 -                        prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
  60.201 -//                        printf("PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]);
  60.202 -                        prefetchpc++;
  60.203 -                        prefetchw++;
  60.204 -                }
  60.205 -                if (prefetchw<6)
  60.206 -                {
  60.207 -                        prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
  60.208 -//                        printf("PREFETCHED from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]);
  60.209 -                        prefetchpc++;
  60.210 -                        prefetchw++;
  60.211 -                }
  60.212 -        }
  60.213 -        fetchcycles+=c;
  60.214 -        if (fetchcycles>16) fetchcycles=16;
  60.215 -//        if (fetchcycles>24) fetchcycles=24;
  60.216 -}
  60.217 -
  60.218 -void FETCHCOMPLETE()
  60.219 -{
  60.220 -//        pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw);
  60.221 -        if (!(fetchcycles&3)) return;
  60.222 -        if (prefetchw>((is8086)?4:3)) return;
  60.223 -        if (!prefetchw) nextcyc=(4-(fetchcycles&3));
  60.224 -        cycles-=(4-(fetchcycles&3));
  60.225 -        fetchclocks+=(4-(fetchcycles&3));
  60.226 -                if (is8086 && !(prefetchpc&1))
  60.227 -                {
  60.228 -                        prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
  60.229 -//                        printf("PREFETCHEDc from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]);
  60.230 -                        prefetchpc++;
  60.231 -                        prefetchw++;
  60.232 -                }
  60.233 -                if (prefetchw<6)
  60.234 -                {
  60.235 -                        prefetchqueue[prefetchw]=readmembf(cs+prefetchpc);
  60.236 -//                        printf("PREFETCHEDc from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]);
  60.237 -                        prefetchpc++;
  60.238 -                        prefetchw++;
  60.239 -                }
  60.240 -                fetchcycles+=(4-(fetchcycles&3));
  60.241 -}
  60.242 -
  60.243 -inline void FETCHCLEAR()
  60.244 -{
  60.245 -/*        int c;
  60.246 -        fetchcycles=0;
  60.247 -        prefetchpc=pc;
  60.248 -        if (is8086 && (prefetchpc&1)) cycles-=4;
  60.249 -        for (c=0;c<((is8086)?6:4);c++)
  60.250 -        {
  60.251 -                prefetchqueue[c]=readmembf(cs+prefetchpc);
  60.252 -                if (!is8086 || !(prefetchpc&1)) cycles-=4;
  60.253 -                prefetchpc++;
  60.254 -        }
  60.255 -        prefetchw=(is8086)?6:4;*/
  60.256 -//        fetchcycles=0;
  60.257 -        prefetchpc=pc;
  60.258 -        prefetchw=0;
  60.259 -        memcycs=cycdiff-cycles;
  60.260 -        fetchclocks=0;
  60.261 -//        memcycs=cycles;
  60.262 -/*        prefetchqueue[0]=readmembf(cs+prefetchpc);
  60.263 -        prefetchpc++;
  60.264 -        prefetchw=1;
  60.265 -        if (is8086 && prefetchpc&1)
  60.266 -        {
  60.267 -                prefetchqueue[1]=readmembf(cs+prefetchpc);
  60.268 -                prefetchpc++;
  60.269 -        }*/
  60.270 -}
  60.271 -
  60.272 -/*EA calculation*/
  60.273 -
  60.274 -/*R/M - bits 0-2 - R/M   bits 3-5 - Reg   bits 6-7 - mod
  60.275 -  From 386 programmers manual :
  60.276 -r8(/r)                     AL    CL    DL    BL    AH    CH    DH    BH
  60.277 -r16(/r)                    AX    CX    DX    BX    SP    BP    SI    DI
  60.278 -r32(/r)                    EAX   ECX   EDX   EBX   ESP   EBP   ESI   EDI
  60.279 -/digit (Opcode)            0     1     2     3     4     5     6     7
  60.280 -REG =                      000   001   010   011   100   101   110   111
  60.281 -  ÚÄÄÄAddress
  60.282 -disp8 denotes an 8-bit displacement following the ModR/M byte, to be
  60.283 -sign-extended and added to the index. disp16 denotes a 16-bit displacement
  60.284 -following the ModR/M byte, to be added to the index. Default segment
  60.285 -register is SS for the effective addresses containing a BP index, DS for
  60.286 -other effective addresses.
  60.287 -            ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄModR/M Values in HexadecimalÄÄÄÄÄÄÄÄ¿
  60.288 -
  60.289 -[BX + SI]            000   00    08    10    18    20    28    30    38
  60.290 -[BX + DI]            001   01    09    11    19    21    29    31    39
  60.291 -[BP + SI]            010   02    0A    12    1A    22    2A    32    3A
  60.292 -[BP + DI]            011   03    0B    13    1B    23    2B    33    3B
  60.293 -[SI]             00  100   04    0C    14    1C    24    2C    34    3C
  60.294 -[DI]                 101   05    0D    15    1D    25    2D    35    3D
  60.295 -disp16               110   06    0E    16    1E    26    2E    36    3E
  60.296 -[BX]                 111   07    0F    17    1F    27    2F    37    3F
  60.297 -
  60.298 -[BX+SI]+disp8        000   40    48    50    58    60    68    70    78
  60.299 -[BX+DI]+disp8        001   41    49    51    59    61    69    71    79
  60.300 -[BP+SI]+disp8        010   42    4A    52    5A    62    6A    72    7A
  60.301 -[BP+DI]+disp8        011   43    4B    53    5B    63    6B    73    7B
  60.302 -[SI]+disp8       01  100   44    4C    54    5C    64    6C    74    7C
  60.303 -[DI]+disp8           101   45    4D    55    5D    65    6D    75    7D
  60.304 -[BP]+disp8           110   46    4E    56    5E    66    6E    76    7E
  60.305 -[BX]+disp8           111   47    4F    57    5F    67    6F    77    7F
  60.306 -
  60.307 -[BX+SI]+disp16       000   80    88    90    98    A0    A8    B0    B8
  60.308 -[BX+DI]+disp16       001   81    89    91    99    A1    A9    B1    B9
  60.309 -[BX+SI]+disp16       010   82    8A    92    9A    A2    AA    B2    BA
  60.310 -[BX+DI]+disp16       011   83    8B    93    9B    A3    AB    B3    BB
  60.311 -[SI]+disp16      10  100   84    8C    94    9C    A4    AC    B4    BC
  60.312 -[DI]+disp16          101   85    8D    95    9D    A5    AD    B5    BD
  60.313 -[BP]+disp16          110   86    8E    96    9E    A6    AE    B6    BE
  60.314 -[BX]+disp16          111   87    8F    97    9F    A7    AF    B7    BF
  60.315 -
  60.316 -EAX/AX/AL            000   C0    C8    D0    D8    E0    E8    F0    F8
  60.317 -ECX/CX/CL            001   C1    C9    D1    D9    E1    E9    F1    F9
  60.318 -EDX/DX/DL            010   C2    CA    D2    DA    E2    EA    F2    FA
  60.319 -EBX/BX/BL            011   C3    CB    D3    DB    E3    EB    F3    FB
  60.320 -ESP/SP/AH        11  100   C4    CC    D4    DC    E4    EC    F4    FC
  60.321 -EBP/BP/CH            101   C5    CD    D5    DD    E5    ED    F5    FD
  60.322 -ESI/SI/DH            110   C6    CE    D6    DE    E6    EE    F6    FE
  60.323 -EDI/DI/BH            111   C7    CF    D7    DF    E7    EF    F7    FF
  60.324 -
  60.325 -mod = 11 - register
  60.326 -      10 - address + 16 bit displacement
  60.327 -      01 - address + 8 bit displacement
  60.328 -      00 - address
  60.329 -
  60.330 -reg = If mod=11,  (depending on data size, 16 bits/8 bits, 32 bits=extend 16 bit registers)
  60.331 -      0=AX/AL   1=CX/CL   2=DX/DL   3=BX/BL
  60.332 -      4=SP/AH   5=BP/CH   6=SI/DH   7=DI/BH
  60.333 -
  60.334 -      Otherwise, LSB selects SI/DI (0=SI), NMSB selects BX/BP (0=BX), and MSB
  60.335 -      selects whether BX/BP are used at all (0=used).
  60.336 -
  60.337 -      mod=00 is an exception though
  60.338 -      6=16 bit displacement only
  60.339 -      7=[BX]
  60.340 -
  60.341 -      Usage varies with instructions.
  60.342 -
  60.343 -      MOV AL,BL has ModR/M as C3, for example.
  60.344 -      mod=11, reg=0, r/m=3
  60.345 -      MOV uses reg as dest, and r/m as src.
  60.346 -      reg 0 is AL, reg 3 is BL
  60.347 -
  60.348 -      If BP or SP are in address calc, seg is SS, else DS
  60.349 -*/
  60.350 -
  60.351 -int cycles=0;
  60.352 -uint32_t easeg,eaaddr;
  60.353 -int rm,reg,mod,rmdat;
  60.354 -
  60.355 -uint16_t zero=0;
  60.356 -uint16_t *mod1add[2][8];
  60.357 -uint32_t *mod1seg[8];
  60.358 -
  60.359 -int slowrm[8];
  60.360 -
  60.361 -void makemod1table()
  60.362 -{
  60.363 -        mod1add[0][0]=&BX; mod1add[0][1]=&BX; mod1add[0][2]=&BP; mod1add[0][3]=&BP;
  60.364 -        mod1add[0][4]=&SI; mod1add[0][5]=&DI; mod1add[0][6]=&BP; mod1add[0][7]=&BX;
  60.365 -        mod1add[1][0]=&SI; mod1add[1][1]=&DI; mod1add[1][2]=&SI; mod1add[1][3]=&DI;
  60.366 -        mod1add[1][4]=&zero; mod1add[1][5]=&zero; mod1add[1][6]=&zero; mod1add[1][7]=&zero;
  60.367 -        slowrm[0]=0; slowrm[1]=1; slowrm[2]=1; slowrm[3]=0;
  60.368 -        mod1seg[0]=&ds; mod1seg[1]=&ds; mod1seg[2]=&ss; mod1seg[3]=&ss;
  60.369 -        mod1seg[4]=&ds; mod1seg[5]=&ds; mod1seg[6]=&ss; mod1seg[7]=&ds;
  60.370 -}
  60.371 -
  60.372 -void fetcheal()
  60.373 -{
  60.374 -        if (!mod && rm==6) { eaaddr=getword(); easeg=ds; FETCHADD(6); }
  60.375 -        else
  60.376 -        {
  60.377 -                switch (mod)
  60.378 -                {
  60.379 -                        case 0:
  60.380 -                        eaaddr=0;
  60.381 -                        if (rm&4) FETCHADD(5);
  60.382 -                        else      FETCHADD(7+slowrm[rm]);
  60.383 -                        break;
  60.384 -                        case 1:
  60.385 -                        eaaddr=(uint16_t)(int8_t)FETCH();
  60.386 -                        if (rm&4) FETCHADD(9);
  60.387 -                        else      FETCHADD(11+slowrm[rm]);
  60.388 -                        break;
  60.389 -                        case 2:
  60.390 -                        eaaddr=getword();
  60.391 -                        if (rm&4) FETCHADD(9);
  60.392 -                        else      FETCHADD(11+slowrm[rm]);
  60.393 -                        break;
  60.394 -                }
  60.395 -                eaaddr+=(*mod1add[0][rm])+(*mod1add[1][rm]);
  60.396 -                easeg=*mod1seg[rm];
  60.397 -                eaaddr&=0xFFFF;
  60.398 -        }
  60.399 -}
  60.400 -
  60.401 -/*void fetchea()
  60.402 -{
  60.403 -        rmdat=readmemb(cs+pc); pc++;
  60.404 -        reg=(rmdat>>3)&7;
  60.405 -        mod=rmdat>>6;
  60.406 -        rm=rmdat&7;
  60.407 -        switch (mod)
  60.408 -        {
  60.409 -                case 0:
  60.410 -                switch (rm)
  60.411 -                {
  60.412 -                        case 0: eaaddr=BX+SI; easeg=ds; if (!AT) cycles-=7; break;
  60.413 -                        case 1: eaaddr=BX+DI; easeg=ds; if (!AT) cycles-=8; break;
  60.414 -                        case 2: eaaddr=BP+SI; easeg=ss; if (!AT) cycles-=8; break;
  60.415 -                        case 3: eaaddr=BP+DI; easeg=ss; if (!AT) cycles-=7; break;
  60.416 -                        case 4: eaaddr=SI; easeg=ds; if (!AT) cycles-=5; break;
  60.417 -                        case 5: eaaddr=DI; easeg=ds; if (!AT) cycles-=5; break;
  60.418 -                        case 6: eaaddr=getword(); easeg=ds; if (!AT) cycles-=6; break;
  60.419 -                        case 7: eaaddr=BX; easeg=ds; if (!AT) cycles-=5; break;
  60.420 -                }
  60.421 -                if (AT && !(rm&4)) cycles--;
  60.422 -                break;
  60.423 -
  60.424 -                case 1:
  60.425 -                eaaddr=readmemb(cs+pc); pc++;
  60.426 -                if (eaaddr&0x80) eaaddr|=0xFF00;
  60.427 -//                if (output) printf("EAADDR %04X ",eaaddr);
  60.428 -                switch (rm)
  60.429 -                {
  60.430 -                        case 0: eaaddr+=BX+SI; easeg=ds; if (!AT) cycles-=11; break;
  60.431 -                        case 1: eaaddr+=BX+DI; easeg=ds; if (!AT) cycles-=12; break;
  60.432 -                        case 2: eaaddr+=BP+SI; easeg=ss; if (!AT) cycles-=12; break;
  60.433 -                        case 3: eaaddr+=BP+DI; easeg=ss; if (!AT) cycles-=11; break;
  60.434 -                        case 4: eaaddr+=SI; easeg=ds; if (!AT) cycles-=9; break;
  60.435 -                        case 5: eaaddr+=DI; easeg=ds; if (!AT) cycles-=9; break;
  60.436 -                        case 6: eaaddr+=BP; easeg=ss; if (!AT) cycles-=9; break;
  60.437 -                        case 7: eaaddr+=BX; easeg=ds; if (!AT) cycles-=9; break;
  60.438 -                }
  60.439 -                if (AT && !(rm&4)) cycles--;
  60.440 -//                if (output) printf("%04X %04X",eaaddr,BX);
  60.441 -                break;
  60.442 -
  60.443 -                case 2:
  60.444 -                eaaddr=getword();
  60.445 -                switch (rm)
  60.446 -                {
  60.447 -                        case 0: eaaddr+=BX+SI; easeg=ds; if (!AT) cycles-=11; break;
  60.448 -                        case 1: eaaddr+=BX+DI; easeg=ds; if (!AT) cycles-=12; break;
  60.449 -                        case 2: eaaddr+=BP+SI; easeg=ss; if (!AT) cycles-=12; break;
  60.450 -                        case 3: eaaddr+=BP+DI; easeg=ss; if (!AT) cycles-=11; break;
  60.451 -                        case 4: eaaddr+=SI; easeg=ds; if (!AT) cycles-=9; break;
  60.452 -                        case 5: eaaddr+=DI; easeg=ds; if (!AT) cycles-=9; break;
  60.453 -                        case 6: eaaddr+=BP; easeg=ss; if (!AT) cycles-=9; break;
  60.454 -                        case 7: eaaddr+=BX; easeg=ds; if (!AT) cycles-=9; break;
  60.455 -                }
  60.456 -                if (AT && !(rm&4)) cycles--;
  60.457 -                break;
  60.458 -        }
  60.459 -        eaaddr&=0xFFFF;
  60.460 -}*/
  60.461 -
  60.462 -static inline uint8_t geteab()
  60.463 -{
  60.464 -        if (mod==3)
  60.465 -           return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l;
  60.466 -        return readmemb(easeg+eaaddr);
  60.467 -}
  60.468 -
  60.469 -static inline uint16_t geteaw()
  60.470 -{
  60.471 -        if (mod==3)
  60.472 -           return regs[rm].w;
  60.473 -//        if (output==3) printf("GETEAW %04X:%08X\n",easeg,eaaddr);
  60.474 -        return readmemw(easeg,eaaddr);
  60.475 -}
  60.476 -
  60.477 -static inline uint16_t geteaw2()
  60.478 -{
  60.479 -        if (mod==3)
  60.480 -           return regs[rm].w;
  60.481 -//        printf("Getting addr from %04X:%04X %05X\n",easeg,eaaddr+2,easeg+eaaddr+2);
  60.482 -        return readmemw(easeg,(eaaddr+2)&0xFFFF);
  60.483 -}
  60.484 -
  60.485 -static inline void seteab(uint8_t val)
  60.486 -{
  60.487 -        if (mod==3)
  60.488 -        {
  60.489 -                if (rm&4) regs[rm&3].b.h=val;
  60.490 -                else      regs[rm&3].b.l=val;
  60.491 -        }
  60.492 -        else
  60.493 -        {
  60.494 -                writememb(easeg+eaaddr,val);
  60.495 -        }
  60.496 -}
  60.497 -
  60.498 -static inline void seteaw(uint16_t val)
  60.499 -{
  60.500 -        if (mod==3)
  60.501 -           regs[rm].w=val;
  60.502 -        else
  60.503 -        {
  60.504 -                writememw(easeg,eaaddr,val);
  60.505 -//                writememb(easeg+eaaddr+1,val>>8);
  60.506 -        }
  60.507 -}
  60.508 -
  60.509 -#define getr8(r)   ((r&4)?regs[r&3].b.h:regs[r&3].b.l)
  60.510 -
  60.511 -#define setr8(r,v) if (r&4) regs[r&3].b.h=v; \
  60.512 -                   else     regs[r&3].b.l=v;
  60.513 -
  60.514 -
  60.515 -/*Flags*/
  60.516 -uint8_t znptable8[256];
  60.517 -uint16_t znptable16[65536];
  60.518 -
  60.519 -void makeznptable()
  60.520 -{
  60.521 -        int c,d;
  60.522 -        for (c=0;c<256;c++)
  60.523 -        {
  60.524 -                d=0;
  60.525 -                if (c&1) d++;
  60.526 -                if (c&2) d++;
  60.527 -                if (c&4) d++;
  60.528 -                if (c&8) d++;
  60.529 -                if (c&16) d++;
  60.530 -                if (c&32) d++;
  60.531 -                if (c&64) d++;
  60.532 -                if (c&128) d++;
  60.533 -                if (d&1)
  60.534 -                   znptable8[c]=0;
  60.535 -                else
  60.536 -                   znptable8[c]=P_FLAG;
  60.537 -                   if (c == 0xb1) pclog("znp8 b1 = %i %02X\n", d, znptable8[c]);
  60.538 -                if (!c) znptable8[c]|=Z_FLAG;
  60.539 -                if (c&0x80) znptable8[c]|=N_FLAG;
  60.540 -        }
  60.541 -        for (c=0;c<65536;c++)
  60.542 -        {
  60.543 -                d=0;
  60.544 -                if (c&1) d++;
  60.545 -                if (c&2) d++;
  60.546 -                if (c&4) d++;
  60.547 -                if (c&8) d++;
  60.548 -                if (c&16) d++;
  60.549 -                if (c&32) d++;
  60.550 -                if (c&64) d++;
  60.551 -                if (c&128) d++;
  60.552 -                if (d&1)
  60.553 -                   znptable16[c]=0;
  60.554 -                else
  60.555 -                   znptable16[c]=P_FLAG;
  60.556 -                if (c == 0xb1) pclog("znp16 b1 = %i %02X\n", d, znptable16[c]);
  60.557 -                if (c == 0x65b1) pclog("znp16 65b1 = %i %02X\n", d, znptable16[c]);
  60.558 -                if (!c) znptable16[c]|=Z_FLAG;
  60.559 -                if (c&0x8000) znptable16[c]|=N_FLAG;
  60.560 -      }
  60.561 -//        isram[0xF]=1;
  60.562 -//        printf("isram 0 = %i\n",isram[0]);
  60.563 -      
  60.564 -//      makemod1table();
  60.565 -}
  60.566 -int timetolive=0;
  60.567 -
  60.568 -uint8_t cpu_readop(uint32_t addr) { return readmemb(addr); }
  60.569 -uint8_t cpu_readmem20(uint32_t addr) { return readmemb(addr); }
  60.570 -
  60.571 -void cpu_writemem20(uint32_t addr, uint8_t val) { writememb(addr,val); }
  60.572 -
  60.573 -uint16_t getword()
  60.574 -{
  60.575 -        uint8_t temp=FETCH();
  60.576 -        return temp|(FETCH()<<8);
  60.577 -//        pc+=2;
  60.578 -//        return readmemw(cs,(pc-2));
  60.579 -}
  60.580 -
  60.581 -uint16_t getword286()
  60.582 -{
  60.583 -        uint16_t temp=readmemw(cs,pc); pc+=2;
  60.584 -        return temp;
  60.585 -}
  60.586 -
  60.587 -int ratio1=0,ratio2=0;
  60.588 -
  60.589 -extern uint32_t oldcs2;
  60.590 -extern uint32_t oldpc2;
  60.591 -
  60.592 -void dumpregs()
  60.593 -{
  60.594 -        FILE *f;
  60.595 -        int c,d=0,e=0;
  60.596 -//        return;
  60.597 -        output=0;
  60.598 -//        return;
  60.599 -//        savenvr();
  60.600 -/*        printf("The ratio is %i %i\n",ratio1,ratio2);
  60.601 -        for (c=0;c<256;c++)
  60.602 -        {
  60.603 -                printf("ISRAM : %06X %i\n",c<<16,isram[c]);
  60.604 -        }*/
  60.605 -//        return;
  60.606 -chdir(pcempath);
  60.607 -        nopageerrors=1;
  60.608 -/*        f=fopen("rram3.dmp","wb");
  60.609 -        for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f);
  60.610 -        fclose(f);*/
  60.611 -/*        f=fopen("ram.dmp","wb");
  60.612 -        fwrite(ram,mem_size*1024*1024,1,f);
  60.613 -        fclose(f);*/
  60.614 -/*        f=fopen("rram.dmp","wb");
  60.615 -        for (c=0;c<0x1000000;c++) putc(readmemb(c),f);
  60.616 -        fclose(f);
  60.617 -        f=fopen("rram2.dmp","wb");
  60.618 -        for (c=0;c<0x100000;c++) putc(readmemb(c+0xbff00000),f);
  60.619 -        fclose(f);
  60.620 -        f = fopen("stack.dmp","wb");
  60.621 -        for (c = 0; c < 0x6000; c++) putc(readmemb(c+0xFFDFA000), f);
  60.622 -        fclose(f);
  60.623 -        f = fopen("tempx.dmp","wb");
  60.624 -        for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFC816000), f);
  60.625 -        fclose(f);
  60.626 -        f = fopen("tempx2.dmp","wb");
  60.627 -        for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFDEF5000), f);
  60.628 -        fclose(f);*/
  60.629 -/*        f=fopen("rram4.dmp","wb");
  60.630 -        for (c=0;c<0x3000000;c++) putc(readmemb(c+0x80000000),f);
  60.631 -        fclose(f);*/
  60.632 -/*        f=fopen("rram5.dmp","wb");
  60.633 -        for (c=0;c<0x1000000;c++) putc(readmemb(c+0x10000000),f);
  60.634 -        fclose(f);*/
  60.635 -/*        f=fopen("rram6.dmp","wb");
  60.636 -        for (c=0;c<0x1000000;c++) putc(readmemb(c+0xBF000000),f);
  60.637 -        fclose(f);*/
  60.638 -/*        f=fopen("ram6.bin","wb");
  60.639 -        fwrite(ram+0x10100,0xA000,1,f);
  60.640 -        fclose(f);
  60.641 -        f=fopen("boot.bin","wb");
  60.642 -        fwrite(ram+0x7C00,0x200,1,f);
  60.643 -        fclose(f);
  60.644 -        f=fopen("ram7.bin","wb");
  60.645 -        fwrite(ram+0x11100,0x2000,1,f);
  60.646 -        fclose(f);
  60.647 -        f=fopen("ram8.bin","wb");
  60.648 -        fwrite(ram+0x3D210,0x200,1,f);
  60.649 -        fclose(f);        */
  60.650 -/*        f=fopen("vram.dmp","wb");
  60.651 -        fwrite(vram,0x400000,1,f);
  60.652 -        fclose(f);
  60.653 -        f=fopen("bios.dmp","wb");
  60.654 -        fwrite(rom,0x20000,1,f);
  60.655 -        fclose(f);
  60.656 -        f=fopen("vbios.dmp","wb");
  60.657 -        fwrite(vrom,0x8000,1,f);
  60.658 -        fclose(f);*/
  60.659 -/*        f=fopen("kernel.dmp","wb");
  60.660 -        for (c=0;c<0x200000;c++) putc(readmemb(c+0xC0000000),f);
  60.661 -        fclose(f);*/
  60.662 -/*        f=fopen("rram.dmp","wb");
  60.663 -        for (c=0;c<0x1500000;c++) putc(readmemb(c),f);
  60.664 -        fclose(f);
  60.665 -        if (!times)
  60.666 -        {
  60.667 -                f=fopen("thing.dmp","wb");
  60.668 -                fwrite(ram+0x11E50,0x1000,1,f);
  60.669 -                fclose(f);
  60.670 -        }*/
  60.671 -        if (is386)
  60.672 -           printf("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",EAX,EBX,ECX,EDX,EDI,ESI,EBP,ESP);
  60.673 -        else
  60.674 -           printf("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP);
  60.675 -        printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",pc,CS,DS,ES,SS,flags);
  60.676 -        printf("%04X:%04X %04X:%04X %08X %08X %08X\n",oldcs,oldpc, oldcs2, oldpc2, old8,old82,old83);
  60.677 -        printf("%i ins\n",ins);
  60.678 -        if (is386)
  60.679 -           printf("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real");
  60.680 -        else
  60.681 -           printf("In %s mode\n",(msw&1)?"protected":"real");
  60.682 -        printf("CS : base=%06X limit=%04X access=%02X\n",cs,_cs.limit,_cs.access);
  60.683 -        printf("DS : base=%06X limit=%04X access=%02X\n",ds,_ds.limit,_ds.access);
  60.684 -        printf("ES : base=%06X limit=%04X access=%02X\n",es,_es.limit,_es.access);
  60.685 -        if (is386)
  60.686 -        {
  60.687 -                printf("FS : base=%06X limit=%04X access=%02X\n",fs,_fs.limit,_fs.access);
  60.688 -                printf("GS : base=%06X limit=%04X access=%02X\n",gs,_gs.limit,_gs.access);
  60.689 -        }
  60.690 -        printf("SS : base=%06X limit=%04X access=%02X\n",ss,_ss.limit,_ss.access);
  60.691 -        printf("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit);
  60.692 -        printf("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit);
  60.693 -        printf("IDT : base=%06X limit=%04X\n",idt.base,idt.limit);
  60.694 -        printf("TR  : base=%06X limit=%04X\n", tr.base, tr.limit);
  60.695 -        if (is386)
  60.696 -        {
  60.697 -                printf("386 in %s mode   stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit");
  60.698 -                printf("CR0=%08X CR2=%08X CR3=%08X\n",cr0,cr2,cr3);
  60.699 -        }
  60.700 -        printf("Entries in readlookup : %i    writelookup : %i\n",readlnum,writelnum);
  60.701 -        for (c=0;c<1024*1024;c++)
  60.702 -        {
  60.703 -                if (readlookup2[c]!=0xFFFFFFFF) d++;
  60.704 -                if (writelookup2[c]!=0xFFFFFFFF) e++;
  60.705 -        }
  60.706 -        printf("Entries in readlookup : %i    writelookup : %i\n",d,e);
  60.707 -        d=0;
  60.708 -        x87_dumpregs();
  60.709 -/*        for (c=0;c<1024*1024;c++)
  60.710 -        {
  60.711 -                if (mmucache[c]!=0xFFFFFFFF) d++;
  60.712 -        }
  60.713 -        printf("Entries in MMU cache : %i\n",d);*/
  60.714 -}
  60.715 -
  60.716 -int isAT;
  60.717 -int resets = 0;
  60.718 -void resetx86()
  60.719 -{
  60.720 -        pclog("x86 reset\n");
  60.721 -        resets++;
  60.722 -        ins = 0;
  60.723 -        use32=0;
  60.724 -        stack32=0;
  60.725 -//        i86_Reset();
  60.726 -//        cs=0xFFFF0;
  60.727 -        pc=0;
  60.728 -        msw=0;
  60.729 -        cr0=0;
  60.730 -        eflags=0;
  60.731 -        cgate32=0;
  60.732 -        loadcs(0xFFFF);
  60.733 -        rammask=0xFFFFFFFF;
  60.734 -        flags=2;
  60.735 -        initmmucache();
  60.736 -        resetreadlookup();
  60.737 -        makemod1table();
  60.738 -        resetmcr();
  60.739 -        isAT=AT;
  60.740 -        FETCHCLEAR();
  60.741 -        x87_reset();
  60.742 -        cpu_set_edx();
  60.743 -        ESP=0;
  60.744 -        mmu_perm=4;
  60.745 -}
  60.746 -
  60.747 -void softresetx86()
  60.748 -{
  60.749 -//      dumpregs();
  60.750 -//        exit(-1);
  60.751 -        use32=0;
  60.752 -        stack32=0;
  60.753 -//        i86_Reset();
  60.754 -//        cs=0xFFFF0;
  60.755 -        pc=0;
  60.756 -        msw=0;
  60.757 -        cr0=0;
  60.758 -        eflags=0;
  60.759 -        cgate32=0;
  60.760 -        loadcs(0xFFFF);
  60.761 -        //rammask=0xFFFFFFFF;
  60.762 -        flags=2;
  60.763 -}
  60.764 -
  60.765 -#undef AT
  60.766 -#define AT isAT
  60.767 -
  60.768 -extern int is486;
  60.769 -void setznp8(uint8_t val)
  60.770 -{
  60.771 -        flags&=~0xC4;
  60.772 -        flags|=znptable8[val];
  60.773 -}
  60.774 -
  60.775 -#define setznp168 setznp16
  60.776 -void setznp16(uint16_t val)
  60.777 -{
  60.778 -        flags&=~0xC4;
  60.779 -//        flags|=((val&0x8000)?N_FLAG:((!val)?Z_FLAG:0));
  60.780 -//        flags|=(((znptable8[val&0xFF]&P_FLAG)==(znptable8[val>>8]&P_FLAG))?P_FLAG:0);
  60.781 -        flags|=znptable16[val];
  60.782 -}
  60.783 -
  60.784 -/*void setznp168(uint16_t val)
  60.785 -{
  60.786 -        flags&=~0xC4;
  60.787 -        flags|=(znptable16[val]&0xC0)|(znptable8[val&0xFF]&4);
  60.788 -}*/
  60.789 -
  60.790 -void setadd8(uint8_t a, uint8_t b)
  60.791 -{
  60.792 -        uint16_t c=(uint16_t)a+(uint16_t)b;
  60.793 -        flags&=~0x8D5;
  60.794 -        flags|=znptable8[c&0xFF];
  60.795 -        if (c&0x100) flags|=C_FLAG;
  60.796 -        if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
  60.797 -        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
  60.798 -}
  60.799 -void setadd8nc(uint8_t a, uint8_t b)
  60.800 -{
  60.801 -        uint16_t c=(uint16_t)a+(uint16_t)b;
  60.802 -        flags&=~0x8D4;
  60.803 -        flags|=znptable8[c&0xFF];
  60.804 -        if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
  60.805 -        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
  60.806 -}
  60.807 -void setadc8(uint8_t a, uint8_t b)
  60.808 -{
  60.809 -        uint16_t c=(uint16_t)a+(uint16_t)b+tempc;
  60.810 -        flags&=~0x8D5;
  60.811 -        flags|=znptable8[c&0xFF];
  60.812 -        if (c&0x100) flags|=C_FLAG;
  60.813 -        if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
  60.814 -        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
  60.815 -}
  60.816 -void setadd16(uint16_t a, uint16_t b)
  60.817 -{
  60.818 -        uint32_t c=(uint32_t)a+(uint32_t)b;
  60.819 -        flags&=~0x8D5;
  60.820 -        flags|=znptable16[c&0xFFFF];
  60.821 -        if (c&0x10000) flags|=C_FLAG;
  60.822 -        if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
  60.823 -        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
  60.824 -}
  60.825 -void setadd16nc(uint16_t a, uint16_t b)
  60.826 -{
  60.827 -        uint32_t c=(uint32_t)a+(uint32_t)b;
  60.828 -        flags&=~0x8D4;
  60.829 -        flags|=znptable16[c&0xFFFF];
  60.830 -        if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
  60.831 -        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
  60.832 -}
  60.833 -void setadc16(uint16_t a, uint16_t b)
  60.834 -{
  60.835 -        uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
  60.836 -        flags&=~0x8D5;
  60.837 -        flags|=znptable16[c&0xFFFF];
  60.838 -        if (c&0x10000) flags|=C_FLAG;
  60.839 -        if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
  60.840 -        if (((a&0xF)+(b&0xF))&0x10)      flags|=A_FLAG;
  60.841 -}
  60.842 -
  60.843 -void setsub8(uint8_t a, uint8_t b)
  60.844 -{
  60.845 -        uint16_t c=(uint16_t)a-(uint16_t)b;
  60.846 -        flags&=~0x8D5;
  60.847 -        flags|=znptable8[c&0xFF];
  60.848 -        if (c&0x100) flags|=C_FLAG;
  60.849 -        if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
  60.850 -        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
  60.851 -}
  60.852 -void setsub8nc(uint8_t a, uint8_t b)
  60.853 -{
  60.854 -        uint16_t c=(uint16_t)a-(uint16_t)b;
  60.855 -        flags&=~0x8D4;
  60.856 -        flags|=znptable8[c&0xFF];
  60.857 -        if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
  60.858 -        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
  60.859 -}
  60.860 -void setsbc8(uint8_t a, uint8_t b)
  60.861 -{
  60.862 -        uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc);
  60.863 -        flags&=~0x8D5;
  60.864 -        flags|=znptable8[c&0xFF];
  60.865 -        if (c&0x100) flags|=C_FLAG;
  60.866 -        if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
  60.867 -        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
  60.868 -}
  60.869 -void setsub16(uint16_t a, uint16_t b)
  60.870 -{
  60.871 -        uint32_t c=(uint32_t)a-(uint32_t)b;
  60.872 -        flags&=~0x8D5;
  60.873 -        flags|=znptable16[c&0xFFFF];
  60.874 -        if (c&0x10000) flags|=C_FLAG;
  60.875 -        if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
  60.876 -//        if (output) printf("%04X %04X %i\n",a^b,a^c,flags&V_FLAG);
  60.877 -        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
  60.878 -}
  60.879 -void setsub16nc(uint16_t a, uint16_t b)
  60.880 -{
  60.881 -        uint32_t c=(uint32_t)a-(uint32_t)b;
  60.882 -        flags&=~0x8D4;
  60.883 -        flags|=(znptable16[c&0xFFFF]&~4);
  60.884 -        flags|=(znptable8[c&0xFF]&4);
  60.885 -        if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
  60.886 -        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
  60.887 -}
  60.888 -void setsbc16(uint16_t a, uint16_t b)
  60.889 -{
  60.890 -        uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
  60.891 -        flags&=~0x8D5;
  60.892 -        flags|=(znptable16[c&0xFFFF]&~4);
  60.893 -        flags|=(znptable8[c&0xFF]&4);
  60.894 -        if (c&0x10000) flags|=C_FLAG;
  60.895 -        if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
  60.896 -        if (((a&0xF)-(b&0xF))&0x10)      flags|=A_FLAG;
  60.897 -}
  60.898 -
  60.899 -
  60.900 -void clockhardware()
  60.901 -{
  60.902 -                cycdiff-=cycles;
  60.903 -                
  60.904 -                keybsenddelay--;
  60.905 -                if (keybsenddelay<1)
  60.906 -                {
  60.907 -                        keybsenddelay = 1000;//2500;
  60.908 -                        keyboard_poll();
  60.909 -                }
  60.910 -
  60.911 -                pit.c[0]-=cycdiff;
  60.912 -                pit.c[1]-=cycdiff;
  60.913 -                if (ppi.pb&1) pit.c[2]-=cycdiff;
  60.914 -
  60.915 -                if ((pit.c[0]<1)||(pit.c[1]<1)||(pit.c[2]<1)) pit_poll();
  60.916 -
  60.917 -                spktime-=cycdiff;
  60.918 -                if (spktime<=0.0)
  60.919 -                {
  60.920 -                        spktime+=SPKCONST;
  60.921 -                        pollspk();
  60.922 -                        pollgussamp();
  60.923 -                        getsbsamp();
  60.924 -                        getdacsamp();
  60.925 -                        polladlib();
  60.926 -                }
  60.927 -                soundtime-=cycdiff;
  60.928 -                if (soundtime<=0.0)
  60.929 -                {
  60.930 -                        soundtime+=SOUNDCONST;
  60.931 -                        pollsound60hz();
  60.932 -                }
  60.933 -                gustime-=cycdiff;
  60.934 -                while (gustime<=0.0)
  60.935 -                {
  60.936 -                        gustime+=GUSCONST;
  60.937 -//                        printf("1Poll GUS %f %f\n",gustime,GUSCONST);
  60.938 -                        pollgus();
  60.939 -//                        printf("2Poll GUS\n");
  60.940 -                }
  60.941 -                vidtime-=cycdiff;
  60.942 -                if (vidtime<=0.0)
  60.943 -                {
  60.944 -                        pollvideo();
  60.945 -//                        polltandy();
  60.946 -//                        pollmda();
  60.947 -//                        pollcga();
  60.948 -                }
  60.949 -                if (disctime)
  60.950 -                {
  60.951 -                        disctime-=(cycdiff/2);
  60.952 -                        if (disctime<=0)
  60.953 -                        {
  60.954 -                                disctime=0;
  60.955 -                                fdc_poll();
  60.956 -                        }
  60.957 -                }
  60.958 -                if (mousedelay)
  60.959 -                {
  60.960 -                        mousedelay--;
  60.961 -                        if (!mousedelay)
  60.962 -                           mousecallback();
  60.963 -                }
  60.964 -                if (sbenable)
  60.965 -                {
  60.966 -                        sbcount-=cycdiff;
  60.967 -                        if (sbcount<0)
  60.968 -                        {
  60.969 -                                sbcount+=sblatcho;
  60.970 -                                pollsb();
  60.971 -                        }
  60.972 -                }
  60.973 -                rtctime-=cycdiff;
  60.974 -                if (rtctime<0)
  60.975 -                {
  60.976 -                        nvr_rtc();
  60.977 -                }
  60.978 -                cycdiff=cycles;
  60.979 -                if (idecallback[0])
  60.980 -                {
  60.981 -                        idecallback[0]--;
  60.982 -                        if (idecallback[0]<=0)
  60.983 -                        {
  60.984 -//                                pclog("IDE time over\n");
  60.985 -                                idecallback[0]=0;
  60.986 -                                callbackide(0);
  60.987 -                        }
  60.988 -                }
  60.989 -}
  60.990 -
  60.991 -
  60.992 -                int firstrepcycle=1;
  60.993 -void cpu_writeport(uint32_t port, uint8_t val) { outb(port,val); }
  60.994 -void rep(int fv)
  60.995 -{
  60.996 -        uint8_t temp;
  60.997 -        int c=CX;
  60.998 -        uint8_t temp2;
  60.999 -        uint16_t tempw,tempw2,tempw3;
 60.1000 -        uint16_t ipc=oldpc;//pc-1;
 60.1001 -        int changeds=0;
 60.1002 -        uint32_t oldds;
 60.1003 -        startrep:
 60.1004 -        temp=FETCH();
 60.1005 -//        if (firstrepcycle && temp==0xA5) printf("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI);
 60.1006 -//        if (output) printf("REP %02X %04X\n",temp,ipc);
 60.1007 -        switch (temp)
 60.1008 -        {
 60.1009 -                case 0x08:
 60.1010 -                pc=ipc+1;
 60.1011 -                cycles-=2;
 60.1012 -                FETCHCLEAR();
 60.1013 -                break;
 60.1014 -                case 0x26: /*ES:*/
 60.1015 -                oldds=ds;
 60.1016 -                ds=es;
 60.1017 -                changeds=1;
 60.1018 -                cycles-=2;
 60.1019 -                goto startrep;
 60.1020 -                break;
 60.1021 -                case 0x2E: /*CS:*/
 60.1022 -                oldds=ds;
 60.1023 -                ds=cs;
 60.1024 -                changeds=1;
 60.1025 -                cycles-=2;
 60.1026 -                goto startrep;
 60.1027 -                break;
 60.1028 -                case 0x36: /*SS:*/
 60.1029 -                oldds=ds;
 60.1030 -                ds=ss;
 60.1031 -                changeds=1;
 60.1032 -                cycles-=2;
 60.1033 -                goto startrep;
 60.1034 -                break;
 60.1035 -                case 0x6E: /*REP OUTSB*/
 60.1036 -                if (c>0)
 60.1037 -                {
 60.1038 -                        temp2=readmemb(ds+SI);
 60.1039 -                        outb(DX,temp2);
 60.1040 -                        if (flags&D_FLAG) SI--;
 60.1041 -                        else              SI++;
 60.1042 -                        c--;
 60.1043 -                        cycles-=5;
 60.1044 -                }
 60.1045 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1046 -                else firstrepcycle=1;
 60.1047 -                break;
 60.1048 -                case 0xA4: /*REP MOVSB*/
 60.1049 -                while (c>0 && !IRQTEST)
 60.1050 -                {
 60.1051 -                        temp2=readmemb(ds+SI);
 60.1052 -                        writememb(es+DI,temp2);
 60.1053 -//                        if (output) printf("Moved %02X from %04X:%04X to %04X:%04X\n",temp2,ds>>4,SI,es>>4,DI);
 60.1054 -                        if (flags&D_FLAG) { DI--; SI--; }
 60.1055 -                        else              { DI++; SI++; }
 60.1056 -                        c--;
 60.1057 -                        cycles-=((AT)?4:17);
 60.1058 -                        clockhardware();
 60.1059 -                        FETCHADD(((AT)?4:17)-memcycs);
 60.1060 -                }
 60.1061 -                if (IRQTEST && c>0) pc=ipc;
 60.1062 -//                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1063 -//                else firstrepcycle=1;
 60.1064 -//                }
 60.1065 -                break;
 60.1066 -                case 0xA5: /*REP MOVSW*/
 60.1067 -                while (c>0 && !IRQTEST)
 60.1068 -                {
 60.1069 -                        memcycs=0;
 60.1070 -                        tempw=readmemw(ds,SI);
 60.1071 -                        writememw(es,DI,tempw);
 60.1072 -                        if (flags&D_FLAG) { DI-=2; SI-=2; }
 60.1073 -                        else              { DI+=2; SI+=2; }
 60.1074 -                        c--;
 60.1075 -                        cycles-=((AT)?4:17);
 60.1076 -                        clockhardware();
 60.1077 -                        FETCHADD(((AT)?4:17)-memcycs);
 60.1078 -                }
 60.1079 -                if (IRQTEST && c>0) pc=ipc;
 60.1080 -//                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1081 -//                else firstrepcycle=1;
 60.1082 -//                }
 60.1083 -                break;
 60.1084 -                case 0xA6: /*REP CMPSB*/
 60.1085 -                if (fv) flags|=Z_FLAG;
 60.1086 -                else    flags&=~Z_FLAG;
 60.1087 -                while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST)
 60.1088 -                {
 60.1089 -                        memcycs=0;
 60.1090 -                        temp=readmemb(ds+SI);
 60.1091 -                        temp2=readmemb(es+DI);
 60.1092 -//                        printf("CMPSB %c %c %i %05X %05X %04X:%04X\n",temp,temp2,c,ds+SI,es+DI,cs>>4,pc);
 60.1093 -                        if (flags&D_FLAG) { DI--; SI--; }
 60.1094 -                        else              { DI++; SI++; }
 60.1095 -                        c--;
 60.1096 -                        if (!AT) cycles-=30;
 60.1097 -                        else     cycles-=9;
 60.1098 -                        setsub8(temp,temp2);
 60.1099 -                        clockhardware();
 60.1100 -                        FETCHADD(((AT)?9:30)-memcycs);
 60.1101 -                }
 60.1102 -                if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) pc=ipc;
 60.1103 -//                if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1104 -//                else firstrepcycle=1;
 60.1105 -                break;
 60.1106 -                case 0xA7: /*REP CMPSW*/
 60.1107 -                if (fv) flags|=Z_FLAG;
 60.1108 -                else    flags&=~Z_FLAG;
 60.1109 -                while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST)
 60.1110 -                {
 60.1111 -                        memcycs=0;
 60.1112 -                        tempw=readmemw(ds,SI);
 60.1113 -                        tempw2=readmemw(es,DI);
 60.1114 -                        if (flags&D_FLAG) { DI-=2; SI-=2; }
 60.1115 -                        else              { DI+=2; SI+=2; }
 60.1116 -                        c--;
 60.1117 -                        if (!AT) cycles-=30;
 60.1118 -                        else     cycles-=9;
 60.1119 -                        setsub16(tempw,tempw2);
 60.1120 -                        clockhardware();
 60.1121 -                        FETCHADD(((AT)?9:30)-memcycs);
 60.1122 -                }
 60.1123 -                if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) pc=ipc;
 60.1124 -//                if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1125 -//                else firstrepcycle=1;
 60.1126 -//                if (firstrepcycle) printf("REP CMPSW  %06X:%04X %06X:%04X %04X %04X\n",ds,SI,es,DI,tempw,tempw2);
 60.1127 -                break;
 60.1128 -                case 0xAA: /*REP STOSB*/
 60.1129 -                while (c>0 && !IRQTEST)
 60.1130 -                {
 60.1131 -                        memcycs=0;
 60.1132 -                        writememb(es+DI,AL);
 60.1133 -                        if (flags&D_FLAG) DI--;
 60.1134 -                        else              DI++;
 60.1135 -                        c--;
 60.1136 -                        cycles-=((AT)?3:10);
 60.1137 -                        clockhardware();
 60.1138 -                        FETCHADD(((AT)?3:10)-memcycs);
 60.1139 -                }
 60.1140 -                if (IRQTEST && c>0) pc=ipc;
 60.1141 -//                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1142 -//                else firstrepcycle=1;
 60.1143 -                break;
 60.1144 -                case 0xAB: /*REP STOSW*/
 60.1145 -                while (c>0 && !IRQTEST)
 60.1146 -                {
 60.1147 -                        memcycs=0;
 60.1148 -                        writememw(es,DI,AX);
 60.1149 -                        if (flags&D_FLAG) DI-=2;
 60.1150 -                        else              DI+=2;
 60.1151 -                        c--;
 60.1152 -                        cycles-=((AT)?3:10);
 60.1153 -                        clockhardware();
 60.1154 -                        FETCHADD(((AT)?3:10)-memcycs);
 60.1155 -                }
 60.1156 -                if (IRQTEST && c>0) pc=ipc;
 60.1157 -//                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1158 -//                else firstrepcycle=1;
 60.1159 -//                printf("REP STOSW %04X:%04X %04X:%04X %04X %04X\n",CS,pc,ES,DI,AX,CX); }
 60.1160 -                break;
 60.1161 -                case 0xAC: /*REP LODSB*/
 60.1162 -                if (c>0)
 60.1163 -                {
 60.1164 -                        temp2=readmemb(ds+SI);
 60.1165 -                        if (flags&D_FLAG) SI--;
 60.1166 -                        else              SI++;
 60.1167 -                        c--;
 60.1168 -                        cycles-=4;
 60.1169 -                }
 60.1170 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1171 -                else firstrepcycle=1;
 60.1172 -                break;
 60.1173 -                case 0xAD: /*REP LODSW*/
 60.1174 -                if (c>0)
 60.1175 -                {
 60.1176 -                        tempw2=readmemw(ds,SI);
 60.1177 -                        if (flags&D_FLAG) SI-=2;
 60.1178 -                        else              SI+=2;
 60.1179 -                        c--;
 60.1180 -                        cycles-=4;
 60.1181 -                }
 60.1182 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1183 -                else firstrepcycle=1;
 60.1184 -                break;
 60.1185 -                case 0xAE: /*REP SCASB*/
 60.1186 -                if (fv) flags|=Z_FLAG;
 60.1187 -                else    flags&=~Z_FLAG;
 60.1188 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))
 60.1189 -                {
 60.1190 -                        temp2=readmemb(es+DI);
 60.1191 -//                        if (output) printf("SCASB %02X %c %02X %05X  ",temp2,temp2,AL,es+DI);
 60.1192 -                        setsub8(AL,temp2);
 60.1193 -//                        if (output && flags&Z_FLAG) printf("Match %02X %02X\n",AL,temp2);
 60.1194 -                        if (flags&D_FLAG) DI--;
 60.1195 -                        else              DI++;
 60.1196 -                        c--;
 60.1197 -                        cycles-=((AT)?8:15);
 60.1198 -                }
 60.1199 -//if (output)                printf("%i %i %i %i\n",c,(c>0),(fv==((flags&Z_FLAG)?1:0)),((c>0) && (fv==((flags&Z_FLAG)?1:0))));
 60.1200 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1201 -                else firstrepcycle=1;
 60.1202 -//                cycles-=120;
 60.1203 -                break;
 60.1204 -                case 0xAF: /*REP SCASW*/
 60.1205 -                if (fv) flags|=Z_FLAG;
 60.1206 -                else    flags&=~Z_FLAG;
 60.1207 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))
 60.1208 -                {
 60.1209 -                        tempw=readmemw(es,DI);
 60.1210 -                        setsub16(AX,tempw);
 60.1211 -                        if (flags&D_FLAG) DI-=2;
 60.1212 -                        else              DI+=2;
 60.1213 -                        c--;
 60.1214 -                        cycles-=((AT)?8:15);
 60.1215 -                }
 60.1216 -                if ((c>0) && (fv==((flags&Z_FLAG)?1:0)))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); }
 60.1217 -                else firstrepcycle=1;
 60.1218 -                break;
 60.1219 -                default:
 60.1220 -                        pc=ipc;
 60.1221 -                        cycles-=20;
 60.1222 -                        FETCHCLEAR();
 60.1223 -//                printf("Bad REP %02X\n",temp);
 60.1224 -//                dumpregs();
 60.1225 -//                exit(-1);
 60.1226 -        }
 60.1227 -        CX=c;
 60.1228 -        if (changeds) ds=oldds;
 60.1229 -//        if (pc==ipc) FETCHCLEAR();
 60.1230 -}
 60.1231 -
 60.1232 -
 60.1233 -int inhlt=0;
 60.1234 -uint16_t lastpc,lastcs;
 60.1235 -int firstrepcycle;
 60.1236 -int skipnextprint=0;
 60.1237 -
 60.1238 -
 60.1239 -int instime=0,instimer=0;
 60.1240 -//#if 0
 60.1241 -void execx86(int cycs)
 60.1242 -{
 60.1243 -        uint8_t temp,temp2;
 60.1244 -        uint16_t addr,tempw,tempw2,tempw3,tempw4;
 60.1245 -        int8_t offset;
 60.1246 -        int tempws;
 60.1247 -        uint32_t templ;
 60.1248 -        int c;
 60.1249 -        int tempi;
 60.1250 -        int trap;
 60.1251 -        FILE *f;
 60.1252 -//        printf("Run x86! %i %i\n",cycles,cycs);
 60.1253 -        cycles+=cycs;
 60.1254 -//        i86_Execute(cycs);
 60.1255 -//        return;
 60.1256 -        while (cycles>0)
 60.1257 -        {
 60.1258 -//                old83=old82;
 60.1259 -//                old82=old8;
 60.1260 -//                old8=oldpc|(oldcs<<16);
 60.1261 -//                if (pc==0x96B && cs==0x9E040) { printf("Hit it\n"); output=1; timetolive=150; }
 60.1262 -//                if (pc<0x8000) printf("%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i\n",pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags,disctime);
 60.1263 -                cycdiff=cycles;
 60.1264 -                cycles-=nextcyc;
 60.1265 -//                if (instime) pclog("Cycles %i %i\n",cycles,cycdiff);
 60.1266 -                nextcyc=0;
 60.1267 -//        if (output) printf("CLOCK %i %i\n",cycdiff,cycles);
 60.1268 -                fetchclocks=0;
 60.1269 -                oldcs=CS;
 60.1270 -                oldpc=pc;
 60.1271 -                opcodestart:
 60.1272 -                opcode=FETCH();
 60.1273 -                tempc=flags&C_FLAG;
 60.1274 -                trap=flags&T_FLAG;
 60.1275 -                pc--;
 60.1276 -//                output=1;
 60.1277 -//                if (output) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X\n",cs>>4,pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags&~0x200,rmdat);
 60.1278 -//#if 0
 60.1279 -                if (output && /*cs<0xF0000 && */!ssegs && (pc<0x43A || pc>0x44A))//opcode!=0x26 && opcode!=0x36 && opcode!=0x2E && opcode!=0x3E)
 60.1280 -                {
 60.1281 -                        if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle)
 60.1282 -                        {
 60.1283 -                                if (!skipnextprint) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X  %02X %02X %02X %02X\n",cs,pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ram[0x413], ram[0x414], ram[0x415], ram[0x416]);
 60.1284 -                                skipnextprint=0;
 60.1285 -//                                ins++;
 60.1286 -                        }
 60.1287 -                }
 60.1288 -//#endif
 60.1289 -                pc++;
 60.1290 -                inhlt=0;
 60.1291 -//                if (ins==500000) { dumpregs(); exit(0); }*/
 60.1292 -                switch (opcode)
 60.1293 -                {
 60.1294 -                        case 0x00: /*ADD 8,reg*/
 60.1295 -                        fetchea();
 60.1296 -/*                        if (!rmdat) pc--;
 60.1297 -                        if (!rmdat)
 60.1298 -                        {
 60.1299 -                                fatal("Crashed\n");
 60.1300 -//                                clear_keybuf();
 60.1301 -//                                readkey();
 60.1302 -                        }*/
 60.1303 -                        temp=geteab();
 60.1304 -                        setadd8(temp,getr8(reg));
 60.1305 -                        temp+=getr8(reg);
 60.1306 -                        seteab(temp);
 60.1307 -                        cycles-=((mod==3)?3:24);
 60.1308 -                        break;
 60.1309 -                        case 0x01: /*ADD 16,reg*/
 60.1310 -                        fetchea();
 60.1311 -                        tempw=geteaw();
 60.1312 -                        setadd16(tempw,regs[reg].w);
 60.1313 -                        tempw+=regs[reg].w;
 60.1314 -                        seteaw(tempw);
 60.1315 -                        cycles-=((mod==3)?3:24);
 60.1316 -                        break;
 60.1317 -                        case 0x02: /*ADD reg,8*/
 60.1318 -                        fetchea();
 60.1319 -                        temp=geteab();
 60.1320 -                        setadd8(getr8(reg),temp);
 60.1321 -                        setr8(reg,getr8(reg)+temp);
 60.1322 -                        cycles-=((mod==3)?3:13);
 60.1323 -                        break;
 60.1324 -                        case 0x03: /*ADD reg,16*/
 60.1325 -                        fetchea();
 60.1326 -                        tempw=geteaw();
 60.1327 -                        setadd16(regs[reg].w,tempw);
 60.1328 -                        regs[reg].w+=tempw;
 60.1329 -                        cycles-=((mod==3)?3:13);
 60.1330 -                        break;
 60.1331 -                        case 0x04: /*ADD AL,#8*/
 60.1332 -                        temp=FETCH();
 60.1333 -                        setadd8(AL,temp);
 60.1334 -                        AL+=temp;
 60.1335 -                        cycles-=4;
 60.1336 -                        break;
 60.1337 -                        case 0x05: /*ADD AX,#16*/
 60.1338 -                        tempw=getword();
 60.1339 -                        setadd16(AX,tempw);
 60.1340 -                        AX+=tempw;
 60.1341 -                        cycles-=4;
 60.1342 -                        break;
 60.1343 -
 60.1344 -                        case 0x06: /*PUSH ES*/
 60.1345 -                        if (ssegs) ss=oldss;
 60.1346 -                        writememw(ss,((SP-2)&0xFFFF),ES);
 60.1347 -                        SP-=2;
 60.1348 -                        cycles-=14;
 60.1349 -                        break;
 60.1350 -                        case 0x07: /*POP ES*/
 60.1351 -                        if (ssegs) ss=oldss;
 60.1352 -                        tempw=readmemw(ss,SP);
 60.1353 -                        loadseg(tempw,&_es);
 60.1354 -                        SP+=2;
 60.1355 -                        cycles-=12;
 60.1356 -                        break;
 60.1357 -
 60.1358 -                        case 0x08: /*OR 8,reg*/
 60.1359 -                        fetchea();
 60.1360 -                        temp=geteab();
 60.1361 -                        temp|=getr8(reg);
 60.1362 -                        setznp8(temp);
 60.1363 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1364 -                        seteab(temp);
 60.1365 -                        cycles-=((mod==3)?3:24);
 60.1366 -                        break;
 60.1367 -                        case 0x09: /*OR 16,reg*/
 60.1368 -                        fetchea();
 60.1369 -                        tempw=geteaw();
 60.1370 -                        tempw|=regs[reg].w;
 60.1371 -                        setznp16(tempw);
 60.1372 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1373 -                        seteaw(tempw);
 60.1374 -                        cycles-=((mod==3)?3:24);
 60.1375 -                        break;
 60.1376 -                        case 0x0A: /*OR reg,8*/
 60.1377 -                        fetchea();
 60.1378 -                        temp=geteab();
 60.1379 -                        temp|=getr8(reg);
 60.1380 -                        setznp8(temp);
 60.1381 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1382 -                        setr8(reg,temp);
 60.1383 -                        cycles-=((mod==3)?3:13);
 60.1384 -                        break;
 60.1385 -                        case 0x0B: /*OR reg,16*/
 60.1386 -                        fetchea();
 60.1387 -                        tempw=geteaw();
 60.1388 -                        tempw|=regs[reg].w;
 60.1389 -                        setznp16(tempw);
 60.1390 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1391 -                        regs[reg].w=tempw;
 60.1392 -                        cycles-=((mod==3)?3:13);
 60.1393 -                        break;
 60.1394 -                        case 0x0C: /*OR AL,#8*/
 60.1395 -                        AL|=FETCH();
 60.1396 -                        setznp8(AL);
 60.1397 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1398 -                        cycles-=4;
 60.1399 -                        break;
 60.1400 -                        case 0x0D: /*OR AX,#16*/
 60.1401 -                        AX|=getword();
 60.1402 -                        setznp16(AX);
 60.1403 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1404 -                        cycles-=4;
 60.1405 -                        break;
 60.1406 -
 60.1407 -                        case 0x0E: /*PUSH CS*/
 60.1408 -                        if (ssegs) ss=oldss;
 60.1409 -                        writememw(ss,((SP-2)&0xFFFF),CS);
 60.1410 -                        SP-=2;
 60.1411 -                        cycles-=14;
 60.1412 -                        break;
 60.1413 -                        case 0x0F: /*POP CS - 8088/8086 only*/
 60.1414 -                        if (ssegs) ss=oldss;
 60.1415 -                        tempw=readmemw(ss,SP);
 60.1416 -                        loadseg(tempw,&_cs);
 60.1417 -                        SP+=2;
 60.1418 -                        cycles-=12;
 60.1419 -                        break;
 60.1420 -
 60.1421 -                        case 0x10: /*ADC 8,reg*/
 60.1422 -                        fetchea();
 60.1423 -                        temp=geteab();
 60.1424 -                        temp2=getr8(reg);
 60.1425 -                        setadc8(temp,temp2);
 60.1426 -                        temp+=temp2+tempc;
 60.1427 -                        seteab(temp);
 60.1428 -                        cycles-=((mod==3)?3:24);
 60.1429 -                        break;
 60.1430 -                        case 0x11: /*ADC 16,reg*/
 60.1431 -                        fetchea();
 60.1432 -                        tempw=geteaw();
 60.1433 -                        tempw2=regs[reg].w;
 60.1434 -                        setadc16(tempw,tempw2);
 60.1435 -                        tempw+=tempw2+tempc;
 60.1436 -                        seteaw(tempw);
 60.1437 -                        cycles-=((mod==3)?3:24);
 60.1438 -                        break;
 60.1439 -                        case 0x12: /*ADC reg,8*/
 60.1440 -                        fetchea();
 60.1441 -                        temp=geteab();
 60.1442 -                        setadc8(getr8(reg),temp);
 60.1443 -                        setr8(reg,getr8(reg)+temp+tempc);
 60.1444 -                        cycles-=((mod==3)?3:13);
 60.1445 -                        break;
 60.1446 -                        case 0x13: /*ADC reg,16*/
 60.1447 -                        fetchea();
 60.1448 -                        tempw=geteaw();
 60.1449 -                        setadc16(regs[reg].w,tempw);
 60.1450 -                        regs[reg].w+=tempw+tempc;
 60.1451 -                        cycles-=((mod==3)?3:13);
 60.1452 -                        break;
 60.1453 -                        case 0x14: /*ADC AL,#8*/
 60.1454 -                        tempw=FETCH();
 60.1455 -                        setadc8(AL,tempw);
 60.1456 -                        AL+=tempw+tempc;
 60.1457 -                        cycles-=4;
 60.1458 -                        break;
 60.1459 -                        case 0x15: /*ADC AX,#16*/
 60.1460 -                        tempw=getword();
 60.1461 -                        setadc16(AX,tempw);
 60.1462 -                        AX+=tempw+tempc;
 60.1463 -                        cycles-=4;
 60.1464 -                        break;
 60.1465 -
 60.1466 -                        case 0x16: /*PUSH SS*/
 60.1467 -                        if (ssegs) ss=oldss;
 60.1468 -                        writememw(ss,((SP-2)&0xFFFF),SS);
 60.1469 -                        SP-=2;
 60.1470 -                        cycles-=14;
 60.1471 -                        break;
 60.1472 -                        case 0x17: /*POP SS*/
 60.1473 -                        if (ssegs) ss=oldss;
 60.1474 -                        tempw=readmemw(ss,SP);
 60.1475 -                        loadseg(tempw,&_ss);
 60.1476 -                        SP+=2;
 60.1477 -                        noint=1;
 60.1478 -                        cycles-=12;
 60.1479 -//                        output=1;
 60.1480 -                        break;
 60.1481 -
 60.1482 -                        case 0x18: /*SBB 8,reg*/
 60.1483 -                        fetchea();
 60.1484 -                        temp=geteab();
 60.1485 -                        temp2=getr8(reg);
 60.1486 -                        setsbc8(temp,temp2);
 60.1487 -                        temp-=(temp2+tempc);
 60.1488 -                        seteab(temp);
 60.1489 -                        cycles-=((mod==3)?3:24);
 60.1490 -                        break;
 60.1491 -                        case 0x19: /*SBB 16,reg*/
 60.1492 -                        fetchea();
 60.1493 -                        tempw=geteaw();
 60.1494 -                        tempw2=regs[reg].w;
 60.1495 -//                        printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc);
 60.1496 -                        setsbc16(tempw,tempw2);
 60.1497 -                        tempw-=(tempw2+tempc);
 60.1498 -                        seteaw(tempw);
 60.1499 -                        cycles-=((mod==3)?3:24);
 60.1500 -                        break;
 60.1501 -                        case 0x1A: /*SBB reg,8*/
 60.1502 -                        fetchea();
 60.1503 -                        temp=geteab();
 60.1504 -                        setsbc8(getr8(reg),temp);
 60.1505 -                        setr8(reg,getr8(reg)-(temp+tempc));
 60.1506 -                        cycles-=((mod==3)?3:13);
 60.1507 -                        break;
 60.1508 -                        case 0x1B: /*SBB reg,16*/
 60.1509 -                        fetchea();
 60.1510 -                        tempw=geteaw();
 60.1511 -                        tempw2=regs[reg].w;
 60.1512 -//                        printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc);
 60.1513 -                        setsbc16(tempw2,tempw);
 60.1514 -                        tempw2-=(tempw+tempc);
 60.1515 -                        regs[reg].w=tempw2;
 60.1516 -                        cycles-=((mod==3)?3:13);
 60.1517 -                        break;
 60.1518 -                        case 0x1C: /*SBB AL,#8*/
 60.1519 -                        temp=FETCH();
 60.1520 -                        setsbc8(AL,temp);
 60.1521 -                        AL-=(temp+tempc);
 60.1522 -                        cycles-=4;
 60.1523 -                        break;
 60.1524 -                        case 0x1D: /*SBB AX,#16*/
 60.1525 -                        tempw=getword();
 60.1526 -                        setsbc16(AX,tempw);
 60.1527 -                        AX-=(tempw+tempc);
 60.1528 -                        cycles-=4;
 60.1529 -                        break;
 60.1530 -
 60.1531 -                        case 0x1E: /*PUSH DS*/
 60.1532 -                        if (ssegs) ss=oldss;
 60.1533 -                        writememw(ss,((SP-2)&0xFFFF),DS);
 60.1534 -                        SP-=2;
 60.1535 -                        cycles-=14;
 60.1536 -                        break;
 60.1537 -                        case 0x1F: /*POP DS*/
 60.1538 -                        if (ssegs) ss=oldss;
 60.1539 -                        tempw=readmemw(ss,SP);
 60.1540 -                        loadseg(tempw,&_ds);
 60.1541 -                        if (ssegs) oldds=ds;
 60.1542 -                        SP+=2;
 60.1543 -                        cycles-=12;
 60.1544 -                        break;
 60.1545 -
 60.1546 -                        case 0x20: /*AND 8,reg*/
 60.1547 -                        fetchea();
 60.1548 -                        temp=geteab();
 60.1549 -                        temp&=getr8(reg);
 60.1550 -                        setznp8(temp);
 60.1551 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1552 -                        seteab(temp);
 60.1553 -                        cycles-=((mod==3)?3:24);
 60.1554 -                        break;
 60.1555 -                        case 0x21: /*AND 16,reg*/
 60.1556 -                        fetchea();
 60.1557 -                        tempw=geteaw();
 60.1558 -                        tempw&=regs[reg].w;
 60.1559 -                        setznp16(tempw);
 60.1560 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1561 -                        seteaw(tempw);
 60.1562 -                        cycles-=((mod==3)?3:24);
 60.1563 -                        break;
 60.1564 -                        case 0x22: /*AND reg,8*/
 60.1565 -                        fetchea();
 60.1566 -                        temp=geteab();
 60.1567 -                        temp&=getr8(reg);
 60.1568 -                        setznp8(temp);
 60.1569 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1570 -                        setr8(reg,temp);
 60.1571 -                        cycles-=((mod==3)?3:13);
 60.1572 -                        break;
 60.1573 -                        case 0x23: /*AND reg,16*/
 60.1574 -                        fetchea();
 60.1575 -                        tempw=geteaw();
 60.1576 -                        tempw&=regs[reg].w;
 60.1577 -                        setznp16(tempw);
 60.1578 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1579 -                        regs[reg].w=tempw;
 60.1580 -                        cycles-=((mod==3)?3:13);
 60.1581 -                        break;
 60.1582 -                        case 0x24: /*AND AL,#8*/
 60.1583 -                        AL&=FETCH();
 60.1584 -                        setznp8(AL);
 60.1585 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1586 -                        cycles-=4;
 60.1587 -                        break;
 60.1588 -                        case 0x25: /*AND AX,#16*/
 60.1589 -                        AX&=getword();
 60.1590 -                        setznp16(AX);
 60.1591 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1592 -                        cycles-=4;
 60.1593 -                        break;
 60.1594 -
 60.1595 -                        case 0x26: /*ES:*/
 60.1596 -                        oldss=ss;
 60.1597 -                        oldds=ds;
 60.1598 -                        ds=ss=es;
 60.1599 -                        ssegs=2;
 60.1600 -                        cycles-=4;
 60.1601 -                        goto opcodestart;
 60.1602 -//                        break;
 60.1603 -
 60.1604 -                        case 0x27: /*DAA*/
 60.1605 -                        if ((flags&A_FLAG) || ((AL&0xF)>9))
 60.1606 -                        {
 60.1607 -                                tempi=((uint16_t)AL)+6;
 60.1608 -                                AL+=6;
 60.1609 -                                flags|=A_FLAG;
 60.1610 -                                if (tempi&0x100) flags|=C_FLAG;
 60.1611 -                        }
 60.1612 -//                        else
 60.1613 -//                           flags&=~A_FLAG;
 60.1614 -                        if ((flags&C_FLAG) || (AL>0x9F))
 60.1615 -                        {
 60.1616 -                                AL+=0x60;
 60.1617 -                                flags|=C_FLAG;
 60.1618 -                        }
 60.1619 -//                        else
 60.1620 -//                           flags&=~C_FLAG;
 60.1621 -                        setznp8(AL);
 60.1622 -                        cycles-=4;
 60.1623 -                        break;
 60.1624 -
 60.1625 -                        case 0x28: /*SUB 8,reg*/
 60.1626 -                        fetchea();
 60.1627 -                        temp=geteab();
 60.1628 -                        setsub8(temp,getr8(reg));
 60.1629 -                        temp-=getr8(reg);
 60.1630 -                        seteab(temp);
 60.1631 -                        cycles-=((mod==3)?3:24);
 60.1632 -                        break;
 60.1633 -                        case 0x29: /*SUB 16,reg*/
 60.1634 -                        fetchea();
 60.1635 -                        tempw=geteaw();
 60.1636 -//                        printf("%04X:%04X  %04X-%04X\n",cs>>4,pc,tempw,regs[reg].w);
 60.1637 -                        setsub16(tempw,regs[reg].w);
 60.1638 -                        tempw-=regs[reg].w;
 60.1639 -                        seteaw(tempw);
 60.1640 -                        cycles-=((mod==3)?3:24);
 60.1641 -                        break;
 60.1642 -                        case 0x2A: /*SUB reg,8*/
 60.1643 -                        fetchea();
 60.1644 -                        temp=geteab();
 60.1645 -                        setsub8(getr8(reg),temp);
 60.1646 -                        setr8(reg,getr8(reg)-temp);
 60.1647 -                        cycles-=((mod==3)?3:13);
 60.1648 -                        break;
 60.1649 -                        case 0x2B: /*SUB reg,16*/
 60.1650 -                        fetchea();
 60.1651 -                        tempw=geteaw();
 60.1652 -//                        printf("%04X:%04X  %04X-%04X\n",cs>>4,pc,regs[reg].w,tempw);
 60.1653 -                        setsub16(regs[reg].w,tempw);
 60.1654 -                        regs[reg].w-=tempw;
 60.1655 -                        cycles-=((mod==3)?3:13);
 60.1656 -                        break;
 60.1657 -                        case 0x2C: /*SUB AL,#8*/
 60.1658 -                        temp=FETCH();
 60.1659 -                        setsub8(AL,temp);
 60.1660 -                        AL-=temp;
 60.1661 -                        cycles-=4;
 60.1662 -                        break;
 60.1663 -                        case 0x2D: /*SUB AX,#16*/
 60.1664 -//                        printf("INS %i\n",ins);
 60.1665 -//                        output=1;
 60.1666 -                        tempw=getword();
 60.1667 -                        setsub16(AX,tempw);
 60.1668 -                        AX-=tempw;
 60.1669 -                        cycles-=4;
 60.1670 -                        break;
 60.1671 -                        case 0x2E: /*CS:*/
 60.1672 -                        oldss=ss;
 60.1673 -                        oldds=ds;
 60.1674 -                        ds=ss=cs;
 60.1675 -                        ssegs=2;
 60.1676 -                        cycles-=4;
 60.1677 -                        goto opcodestart;
 60.1678 -                        case 0x2F: /*DAS*/
 60.1679 -                        if ((flags&A_FLAG)||((AL&0xF)>9))
 60.1680 -                        {
 60.1681 -                                tempi=((uint16_t)AL)-6;
 60.1682 -                                AL-=6;
 60.1683 -                                flags|=A_FLAG;
 60.1684 -                                if (tempi&0x100) flags|=C_FLAG;
 60.1685 -                        }
 60.1686 -//                        else
 60.1687 -//                           flags&=~A_FLAG;
 60.1688 -                        if ((flags&C_FLAG)||(AL>0x9F))
 60.1689 -                        {
 60.1690 -                                AL-=0x60;
 60.1691 -                                flags|=C_FLAG;
 60.1692 -                        }
 60.1693 -//                        else
 60.1694 -//                           flags&=~C_FLAG;
 60.1695 -                        setznp8(AL);
 60.1696 -                        cycles-=4;
 60.1697 -                        break;
 60.1698 -                        case 0x30: /*XOR 8,reg*/
 60.1699 -                        fetchea();
 60.1700 -                        temp=geteab();
 60.1701 -                        temp^=getr8(reg);
 60.1702 -                        setznp8(temp);
 60.1703 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1704 -                        seteab(temp);
 60.1705 -                        cycles-=((mod==3)?3:24);
 60.1706 -                        break;
 60.1707 -                        case 0x31: /*XOR 16,reg*/
 60.1708 -                        fetchea();
 60.1709 -                        tempw=geteaw();
 60.1710 -                        tempw^=regs[reg].w;
 60.1711 -                        setznp16(tempw);
 60.1712 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1713 -                        seteaw(tempw);
 60.1714 -                        cycles-=((mod==3)?3:24);
 60.1715 -                        break;
 60.1716 -                        case 0x32: /*XOR reg,8*/
 60.1717 -                        fetchea();
 60.1718 -                        temp=geteab();
 60.1719 -                        temp^=getr8(reg);
 60.1720 -                        setznp8(temp);
 60.1721 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1722 -                        setr8(reg,temp);
 60.1723 -                        cycles-=((mod==3)?3:13);
 60.1724 -                        break;
 60.1725 -                        case 0x33: /*XOR reg,16*/
 60.1726 -                        fetchea();
 60.1727 -                        tempw=geteaw();
 60.1728 -                        tempw^=regs[reg].w;
 60.1729 -                        setznp16(tempw);
 60.1730 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1731 -                        regs[reg].w=tempw;
 60.1732 -                        cycles-=((mod==3)?3:13);
 60.1733 -                        break;
 60.1734 -                        case 0x34: /*XOR AL,#8*/
 60.1735 -                        AL^=FETCH();
 60.1736 -                        setznp8(AL);
 60.1737 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1738 -                        cycles-=4;
 60.1739 -                        break;
 60.1740 -                        case 0x35: /*XOR AX,#16*/
 60.1741 -                        AX^=getword();
 60.1742 -                        setznp16(AX);
 60.1743 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1744 -                        cycles-=4;
 60.1745 -                        break;
 60.1746 -
 60.1747 -                        case 0x36: /*SS:*/
 60.1748 -                        oldss=ss;
 60.1749 -                        oldds=ds;
 60.1750 -                        ds=ss=ss;
 60.1751 -                        ssegs=2;
 60.1752 -                        cycles-=4;
 60.1753 -                        goto opcodestart;
 60.1754 -//                        break;
 60.1755 -
 60.1756 -                        case 0x37: /*AAA*/
 60.1757 -                        if ((flags&A_FLAG)||((AL&0xF)>9))
 60.1758 -                        {
 60.1759 -                                AL+=6;
 60.1760 -                                AH++;
 60.1761 -                                flags|=(A_FLAG|C_FLAG);
 60.1762 -                        }
 60.1763 -                        else
 60.1764 -                           flags&=~(A_FLAG|C_FLAG);
 60.1765 -                        AL&=0xF;
 60.1766 -                        cycles-=8;
 60.1767 -                        break;
 60.1768 -
 60.1769 -                        case 0x38: /*CMP 8,reg*/
 60.1770 -                        fetchea();
 60.1771 -                        temp=geteab();
 60.1772 -//                        if (output) printf("CMP %02X-%02X\n",temp,getr8(reg));
 60.1773 -                        setsub8(temp,getr8(reg));
 60.1774 -                        cycles-=((mod==3)?3:13);
 60.1775 -                        break;
 60.1776 -                        case 0x39: /*CMP 16,reg*/
 60.1777 -                        fetchea();
 60.1778 -                        tempw=geteaw();
 60.1779 -//                        if (output) printf("CMP %04X-%04X\n",tempw,regs[reg].w);
 60.1780 -                        setsub16(tempw,regs[reg].w);
 60.1781 -                        cycles-=((mod==3)?3:13);
 60.1782 -                        break;
 60.1783 -                        case 0x3A: /*CMP reg,8*/
 60.1784 -                        fetchea();
 60.1785 -                        temp=geteab();
 60.1786 -//                        if (output) printf("CMP %02X-%02X\n",getr8(reg),temp);
 60.1787 -                        setsub8(getr8(reg),temp);
 60.1788 -                        cycles-=((mod==3)?3:13);
 60.1789 -                        break;
 60.1790 -                        case 0x3B: /*CMP reg,16*/
 60.1791 -                        fetchea();
 60.1792 -                        tempw=geteaw();
 60.1793 -//                        printf("CMP %04X-%04X\n",regs[reg].w,tempw);
 60.1794 -                        setsub16(regs[reg].w,tempw);
 60.1795 -                        cycles-=((mod==3)?3:13);
 60.1796 -                        break;
 60.1797 -                        case 0x3C: /*CMP AL,#8*/
 60.1798 -                        temp=FETCH();
 60.1799 -                        setsub8(AL,temp);
 60.1800 -                        cycles-=4;
 60.1801 -                        break;
 60.1802 -                        case 0x3D: /*CMP AX,#16*/
 60.1803 -                        tempw=getword();
 60.1804 -                        setsub16(AX,tempw);
 60.1805 -                        cycles-=4;
 60.1806 -                        break;
 60.1807 -
 60.1808 -                        case 0x3E: /*DS:*/
 60.1809 -                        oldss=ss;
 60.1810 -                        oldds=ds;
 60.1811 -                        ds=ss=ds;
 60.1812 -                        ssegs=2;
 60.1813 -                        cycles-=4;
 60.1814 -                        goto opcodestart;
 60.1815 -//                        break;
 60.1816 -
 60.1817 -                        case 0x3F: /*AAS*/
 60.1818 -                        if ((flags&A_FLAG)||((AL&0xF)>9))
 60.1819 -                        {
 60.1820 -                                AL-=6;
 60.1821 -                                AH--;
 60.1822 -                                flags|=(A_FLAG|C_FLAG);
 60.1823 -                        }
 60.1824 -                        else
 60.1825 -                           flags&=~(A_FLAG|C_FLAG);
 60.1826 -                        AL&=0xF;
 60.1827 -                        cycles-=8;
 60.1828 -                        break;
 60.1829 -
 60.1830 -                        case 0x40: case 0x41: case 0x42: case 0x43: /*INC r16*/
 60.1831 -                        case 0x44: case 0x45: case 0x46: case 0x47:
 60.1832 -                        setadd16nc(regs[opcode&7].w,1);
 60.1833 -                        regs[opcode&7].w++;
 60.1834 -                        cycles-=3;
 60.1835 -                        break;
 60.1836 -                        case 0x48: case 0x49: case 0x4A: case 0x4B: /*DEC r16*/
 60.1837 -                        case 0x4C: case 0x4D: case 0x4E: case 0x4F:
 60.1838 -                        setsub16nc(regs[opcode&7].w,1);
 60.1839 -                        regs[opcode&7].w--;
 60.1840 -                        cycles-=3;
 60.1841 -                        break;
 60.1842 -
 60.1843 -                        case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/
 60.1844 -                        case 0x54: case 0x55: case 0x56: case 0x57:
 60.1845 -                        if (ssegs) ss=oldss;
 60.1846 -                        SP-=2;
 60.1847 -                        writememw(ss,SP,regs[opcode&7].w);
 60.1848 -                        cycles-=15;
 60.1849 -                        break;
 60.1850 -                        case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/
 60.1851 -                        case 0x5C: case 0x5D: case 0x5E: case 0x5F:
 60.1852 -                        if (ssegs) ss=oldss;
 60.1853 -                        SP+=2;
 60.1854 -                        regs[opcode&7].w=readmemw(ss,(SP-2)&0xFFFF);
 60.1855 -                        cycles-=12;
 60.1856 -                        break;
 60.1857 -
 60.1858 -
 60.1859 -                        case 0x70: /*JO*/
 60.1860 -                        offset=(int8_t)FETCH();
 60.1861 -                        if (flags&V_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1862 -                        cycles-=4;
 60.1863 -                        break;
 60.1864 -                        case 0x71: /*JNO*/
 60.1865 -                        offset=(int8_t)FETCH();
 60.1866 -                        if (!(flags&V_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1867 -                        cycles-=4;
 60.1868 -                        break;
 60.1869 -                        case 0x72: /*JB*/
 60.1870 -                        offset=(int8_t)FETCH();
 60.1871 -                        if (flags&C_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1872 -                        cycles-=4;
 60.1873 -                        break;
 60.1874 -                        case 0x73: /*JNB*/
 60.1875 -                        offset=(int8_t)FETCH();
 60.1876 -                        if (!(flags&C_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1877 -                        cycles-=4;
 60.1878 -                        break;
 60.1879 -                        case 0x74: /*JE*/
 60.1880 -                        offset=(int8_t)FETCH();
 60.1881 -                        if (flags&Z_FLAG) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1882 -                        cycles-=4;
 60.1883 -                        break;
 60.1884 -                        case 0x75: /*JNE*/
 60.1885 -                        offset=(int8_t)FETCH();
 60.1886 -                        cycles-=4;
 60.1887 -                        if (!(flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1888 -                        break;
 60.1889 -                        case 0x76: /*JBE*/
 60.1890 -                        offset=(int8_t)FETCH();
 60.1891 -                        if (flags&(C_FLAG|Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1892 -                        cycles-=4;
 60.1893 -                        break;
 60.1894 -                        case 0x77: /*JNBE*/
 60.1895 -                        offset=(int8_t)FETCH();
 60.1896 -                        if (!(flags&(C_FLAG|Z_FLAG))) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1897 -                        cycles-=4;
 60.1898 -                        break;
 60.1899 -                        case 0x78: /*JS*/
 60.1900 -                        offset=(int8_t)FETCH();
 60.1901 -                        if (flags&N_FLAG)  { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1902 -                        cycles-=4;
 60.1903 -                        break;
 60.1904 -                        case 0x79: /*JNS*/
 60.1905 -                        offset=(int8_t)FETCH();
 60.1906 -                        if (!(flags&N_FLAG))  { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1907 -                        cycles-=4;
 60.1908 -                        break;
 60.1909 -                        case 0x7A: /*JP*/
 60.1910 -                        offset=(int8_t)FETCH();
 60.1911 -                        if (flags&P_FLAG)  { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1912 -                        cycles-=4;
 60.1913 -                        break;
 60.1914 -                        case 0x7B: /*JNP*/
 60.1915 -                        offset=(int8_t)FETCH();
 60.1916 -                        if (!(flags&P_FLAG))  { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1917 -                        cycles-=4;
 60.1918 -                        break;
 60.1919 -                        case 0x7C: /*JL*/
 60.1920 -                        offset=(int8_t)FETCH();
 60.1921 -                        temp=(flags&N_FLAG)?1:0;
 60.1922 -                        temp2=(flags&V_FLAG)?1:0;
 60.1923 -                        if (temp!=temp2)  { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1924 -                        cycles-=4;
 60.1925 -                        break;
 60.1926 -                        case 0x7D: /*JNL*/
 60.1927 -                        offset=(int8_t)FETCH();
 60.1928 -                        temp=(flags&N_FLAG)?1:0;
 60.1929 -                        temp2=(flags&V_FLAG)?1:0;
 60.1930 -                        if (temp==temp2)  { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1931 -                        cycles-=4;
 60.1932 -                        break;
 60.1933 -                        case 0x7E: /*JLE*/
 60.1934 -                        offset=(int8_t)FETCH();
 60.1935 -                        temp=(flags&N_FLAG)?1:0;
 60.1936 -                        temp2=(flags&V_FLAG)?1:0;
 60.1937 -                        if ((flags&Z_FLAG) || (temp!=temp2))  { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1938 -                        cycles-=4;
 60.1939 -                        break;
 60.1940 -                        case 0x7F: /*JNLE*/
 60.1941 -                        offset=(int8_t)FETCH();
 60.1942 -                        temp=(flags&N_FLAG)?1:0;
 60.1943 -                        temp2=(flags&V_FLAG)?1:0;
 60.1944 -                        if (!((flags&Z_FLAG) || (temp!=temp2)))  { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.1945 -                        cycles-=4;
 60.1946 -                        break;
 60.1947 -
 60.1948 -                        case 0x80: case 0x82:
 60.1949 -                        fetchea();
 60.1950 -                        temp=geteab();
 60.1951 -                        temp2=FETCH();
 60.1952 -                        switch (rmdat&0x38)
 60.1953 -                        {
 60.1954 -                                case 0x00: /*ADD b,#8*/
 60.1955 -                                setadd8(temp,temp2);
 60.1956 -                                seteab(temp+temp2);
 60.1957 -                                cycles-=((mod==3)?4:23);
 60.1958 -                                break;
 60.1959 -                                case 0x08: /*OR b,#8*/
 60.1960 -                                temp|=temp2;
 60.1961 -                                setznp8(temp);
 60.1962 -                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1963 -                                seteab(temp);
 60.1964 -                                cycles-=((mod==3)?4:23);
 60.1965 -                                break;
 60.1966 -                                case 0x10: /*ADC b,#8*/
 60.1967 -//                                temp2+=(flags&C_FLAG);
 60.1968 -                                setadc8(temp,temp2);
 60.1969 -                                seteab(temp+temp2+tempc);
 60.1970 -                                cycles-=((mod==3)?4:23);
 60.1971 -                                break;
 60.1972 -                                case 0x18: /*SBB b,#8*/
 60.1973 -//                                temp2+=(flags&C_FLAG);
 60.1974 -                                setsbc8(temp,temp2);
 60.1975 -                                seteab(temp-(temp2+tempc));
 60.1976 -                                cycles-=((mod==3)?4:23);
 60.1977 -                                break;
 60.1978 -                                case 0x20: /*AND b,#8*/
 60.1979 -                                temp&=temp2;
 60.1980 -                                setznp8(temp);
 60.1981 -                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1982 -                                seteab(temp);
 60.1983 -                                cycles-=((mod==3)?4:23);
 60.1984 -                                break;
 60.1985 -                                case 0x28: /*SUB b,#8*/
 60.1986 -                                setsub8(temp,temp2);
 60.1987 -                                seteab(temp-temp2);
 60.1988 -                                cycles-=((mod==3)?4:23);
 60.1989 -                                break;
 60.1990 -                                case 0x30: /*XOR b,#8*/
 60.1991 -                                temp^=temp2;
 60.1992 -                                setznp8(temp);
 60.1993 -                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.1994 -                                seteab(temp);
 60.1995 -                                cycles-=((mod==3)?4:23);
 60.1996 -                                break;
 60.1997 -                                case 0x38: /*CMP b,#8*/
 60.1998 -                                setsub8(temp,temp2);
 60.1999 -                                cycles-=((mod==3)?4:14);
 60.2000 -                                break;
 60.2001 -
 60.2002 -//                                default:
 60.2003 -//                                printf("Bad 80 opcode %02X\n",rmdat&0x38);
 60.2004 -//                                dumpregs();
 60.2005 -//                                exit(-1);
 60.2006 -                        }
 60.2007 -                        break;
 60.2008 -
 60.2009 -                        case 0x81:
 60.2010 -                        fetchea();
 60.2011 -                        tempw=geteaw();
 60.2012 -                        tempw2=getword();
 60.2013 -                        switch (rmdat&0x38)
 60.2014 -                        {
 60.2015 -                                case 0x00: /*ADD w,#16*/
 60.2016 -                                setadd16(tempw,tempw2);
 60.2017 -                                tempw+=tempw2;
 60.2018 -                                seteaw(tempw);
 60.2019 -                                cycles-=((mod==3)?4:23);
 60.2020 -                                break;
 60.2021 -                                case 0x08: /*OR w,#16*/
 60.2022 -                                tempw|=tempw2;
 60.2023 -                                setznp16(tempw);
 60.2024 -                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.2025 -                                seteaw(tempw);
 60.2026 -                                cycles-=((mod==3)?4:23);
 60.2027 -                                break;
 60.2028 -                                case 0x10: /*ADC w,#16*/
 60.2029 -//                                tempw2+=(flags&C_FLAG);
 60.2030 -                                setadc16(tempw,tempw2);
 60.2031 -                                tempw+=tempw2+tempc;
 60.2032 -                                seteaw(tempw);
 60.2033 -                                cycles-=((mod==3)?4:23);
 60.2034 -                                break;
 60.2035 -                                case 0x20: /*AND w,#16*/
 60.2036 -                                tempw&=tempw2;
 60.2037 -                                setznp16(tempw);
 60.2038 -                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.2039 -                                seteaw(tempw);
 60.2040 -                                cycles-=((mod==3)?4:23);
 60.2041 -                                break;
 60.2042 -                                case 0x18: /*SBB w,#16*/
 60.2043 -//                                tempw2+=(flags&C_FLAG);
 60.2044 -                                setsbc16(tempw,tempw2);
 60.2045 -                                seteaw(tempw-(tempw2+tempc));
 60.2046 -                                cycles-=((mod==3)?4:23);
 60.2047 -                                break;
 60.2048 -                                case 0x28: /*SUB w,#16*/
 60.2049 -                                setsub16(tempw,tempw2);
 60.2050 -                                tempw-=tempw2;
 60.2051 -                                seteaw(tempw);
 60.2052 -                                cycles-=((mod==3)?4:23);
 60.2053 -                                break;
 60.2054 -                                case 0x30: /*XOR w,#16*/
 60.2055 -                                tempw^=tempw2;
 60.2056 -                                setznp16(tempw);
 60.2057 -                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.2058 -                                seteaw(tempw);
 60.2059 -                                cycles-=((mod==3)?4:23);
 60.2060 -                                break;
 60.2061 -                                case 0x38: /*CMP w,#16*/
 60.2062 -//                                printf("CMP %04X %04X\n",tempw,tempw2);
 60.2063 -                                setsub16(tempw,tempw2);
 60.2064 -                                cycles-=((mod==3)?4:14);
 60.2065 -                                break;
 60.2066 -
 60.2067 -//                                default:
 60.2068 -//                                printf("Bad 81 opcode %02X\n",rmdat&0x38);
 60.2069 -//                                dumpregs();
 60.2070 -//                                exit(-1);
 60.2071 -                        }
 60.2072 -                        break;
 60.2073 -
 60.2074 -                        case 0x83:
 60.2075 -                        fetchea();
 60.2076 -                        tempw=geteaw();
 60.2077 -                        tempw2=FETCH();
 60.2078 -                        if (tempw2&0x80) tempw2|=0xFF00;
 60.2079 -                        switch (rmdat&0x38)
 60.2080 -                        {
 60.2081 -                                case 0x00: /*ADD w,#8*/
 60.2082 -                                setadd16(tempw,tempw2);
 60.2083 -                                tempw+=tempw2;
 60.2084 -                                seteaw(tempw);
 60.2085 -                                cycles-=((mod==3)?4:23);
 60.2086 -                                break;
 60.2087 -                                case 0x08: /*OR w,#8*/
 60.2088 -                                tempw|=tempw2;
 60.2089 -                                setznp16(tempw);
 60.2090 -                                seteaw(tempw);
 60.2091 -                                flags&=~(C_FLAG|A_FLAG|V_FLAG);
 60.2092 -                                cycles-=((mod==3)?4:23);
 60.2093 -                                break;
 60.2094 -                                case 0x10: /*ADC w,#8*/
 60.2095 -//                                tempw2+=(flags&C_FLAG);
 60.2096 -                                setadc16(tempw,tempw2);
 60.2097 -                                tempw+=tempw2+tempc;
 60.2098 -                                seteaw(tempw);
 60.2099 -                                cycles-=((mod==3)?4:23);
 60.2100 -                                break;
 60.2101 -                                case 0x18: /*SBB w,#8*/
 60.2102 -//                                tempw2+=(flags&C_FLAG);
 60.2103 -                                setsbc16(tempw,tempw2);
 60.2104 -                                tempw-=(tempw2+tempc);
 60.2105 -                                seteaw(tempw);
 60.2106 -                                cycles-=((mod==3)?4:23);
 60.2107 -                                break;
 60.2108 -                                case 0x20: /*AND w,#8*/
 60.2109 -                                tempw&=tempw2;
 60.2110 -                                setznp16(tempw);
 60.2111 -                                seteaw(tempw);
 60.2112 -                                cycles-=((mod==3)?4:23);
 60.2113 -                                flags&=~(C_FLAG|A_FLAG|V_FLAG);
 60.2114 -                                break;
 60.2115 -                                case 0x28: /*SUB w,#8*/
 60.2116 -                                setsub16(tempw,tempw2);
 60.2117 -                                tempw-=tempw2;
 60.2118 -                                seteaw(tempw);
 60.2119 -                                cycles-=((mod==3)?4:23);
 60.2120 -                                break;
 60.2121 -                                case 0x30: /*XOR w,#8*/
 60.2122 -                                tempw^=tempw2;
 60.2123 -                                setznp16(tempw);
 60.2124 -                                seteaw(tempw);
 60.2125 -                                cycles-=((mod==3)?4:23);
 60.2126 -                                flags&=~(C_FLAG|A_FLAG|V_FLAG);
 60.2127 -                                break;
 60.2128 -                                case 0x38: /*CMP w,#8*/
 60.2129 -                                setsub16(tempw,tempw2);
 60.2130 -                                cycles-=((mod==3)?4:14);
 60.2131 -                                break;
 60.2132 -
 60.2133 -//                                default:
 60.2134 -//                                printf("Bad 83 opcode %02X\n",rmdat&0x38);
 60.2135 -//                                dumpregs();
 60.2136 -//                                exit(-1);
 60.2137 -                        }
 60.2138 -                        break;
 60.2139 -
 60.2140 -                        case 0x84: /*TEST b,reg*/
 60.2141 -                        fetchea();
 60.2142 -                        temp=geteab();
 60.2143 -                        temp2=getr8(reg);
 60.2144 -                        setznp8(temp&temp2);
 60.2145 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.2146 -                        cycles-=((mod==3)?3:13);
 60.2147 -                        break;
 60.2148 -                        case 0x85: /*TEST w,reg*/
 60.2149 -                        fetchea();
 60.2150 -                        tempw=geteaw();
 60.2151 -                        tempw2=regs[reg].w;
 60.2152 -                        setznp16(tempw&tempw2);
 60.2153 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.2154 -                        cycles-=((mod==3)?3:13);
 60.2155 -                        break;
 60.2156 -                        case 0x86: /*XCHG b,reg*/
 60.2157 -                        fetchea();
 60.2158 -                        temp=geteab();
 60.2159 -                        seteab(getr8(reg));
 60.2160 -                        setr8(reg,temp);
 60.2161 -                        cycles-=((mod==3)?4:25);
 60.2162 -                        break;
 60.2163 -                        case 0x87: /*XCHG w,reg*/
 60.2164 -                        fetchea();
 60.2165 -                        tempw=geteaw();
 60.2166 -                        seteaw(regs[reg].w);
 60.2167 -                        regs[reg].w=tempw;
 60.2168 -                        cycles-=((mod==3)?4:25);
 60.2169 -                        break;
 60.2170 -
 60.2171 -                        case 0x88: /*MOV b,reg*/
 60.2172 -                        fetchea();
 60.2173 -                        seteab(getr8(reg));
 60.2174 -                        cycles-=((mod==3)?2:13);
 60.2175 -                        break;
 60.2176 -                        case 0x89: /*MOV w,reg*/
 60.2177 -                        fetchea();
 60.2178 -                        seteaw(regs[reg].w);
 60.2179 -                        cycles-=((mod==3)?2:13);
 60.2180 -                        break;
 60.2181 -                        case 0x8A: /*MOV reg,b*/
 60.2182 -                        fetchea();
 60.2183 -                        temp=geteab();
 60.2184 -                        setr8(reg,temp);
 60.2185 -                        cycles-=((mod==3)?2:12);
 60.2186 -                        break;
 60.2187 -                        case 0x8B: /*MOV reg,w*/
 60.2188 -                        fetchea();
 60.2189 -                        tempw=geteaw();
 60.2190 -                        regs[reg].w=tempw;
 60.2191 -                        cycles-=((mod==3)?2:12);
 60.2192 -                        break;
 60.2193 -
 60.2194 -                        case 0x8C: /*MOV w,sreg*/
 60.2195 -                        fetchea();
 60.2196 -                        switch (rmdat&0x38)
 60.2197 -                        {
 60.2198 -                                case 0x00: /*ES*/
 60.2199 -                                seteaw(ES);
 60.2200 -                                break;
 60.2201 -                                case 0x08: /*CS*/
 60.2202 -                                seteaw(CS);
 60.2203 -                                break;
 60.2204 -                                case 0x18: /*DS*/
 60.2205 -                                if (ssegs) ds=oldds;
 60.2206 -                                seteaw(DS);
 60.2207 -                                break;
 60.2208 -                                case 0x10: /*SS*/
 60.2209 -                                if (ssegs) ss=oldss;
 60.2210 -                                seteaw(SS);
 60.2211 -                                break;
 60.2212 -                        }
 60.2213 -                        cycles-=((mod==3)?2:13);
 60.2214 -                        break;
 60.2215 -
 60.2216 -                        case 0x8D: /*LEA*/
 60.2217 -                        fetchea();
 60.2218 -                        regs[reg].w=eaaddr;
 60.2219 -                        cycles-=2;
 60.2220 -                        break;
 60.2221 -
 60.2222 -                        case 0x8E: /*MOV sreg,w*/
 60.2223 -//                        if (output) printf("MOV %04X  ",pc);
 60.2224 -                        fetchea();
 60.2225 -//                        if (output) printf("%04X %02X\n",pc,rmdat);
 60.2226 -                        switch (rmdat&0x38)
 60.2227 -                        {
 60.2228 -                                case 0x00: /*ES*/
 60.2229 -                                tempw=geteaw();
 60.2230 -                                loadseg(tempw,&_es);
 60.2231 -                                break;
 60.2232 -                                case 0x08: /*CS - 8088/8086 only*/
 60.2233 -                                tempw=geteaw();
 60.2234 -                                loadseg(tempw,&_cs);
 60.2235 -                                break;
 60.2236 -                                case 0x18: /*DS*/
 60.2237 -                                tempw=geteaw();
 60.2238 -                                loadseg(tempw,&_ds);
 60.2239 -                                if (ssegs) oldds=ds;
 60.2240 -                                break;
 60.2241 -                                case 0x10: /*SS*/
 60.2242 -                                tempw=geteaw();
 60.2243 -                                loadseg(tempw,&_ss);
 60.2244 -                                if (ssegs) oldss=ss;
 60.2245 -//                                printf("LOAD SS %04X %04X\n",tempw,SS);
 60.2246 -//				printf("SS loaded with %04X %04X:%04X %04X %04X %04X\n",ss>>4,cs>>4,pc,CX,DX,es>>4);
 60.2247 -                                break;
 60.2248 -                        }
 60.2249 -                        cycles-=((mod==3)?2:12);
 60.2250 -                                skipnextprint=1;
 60.2251 -				noint=1;
 60.2252 -                        break;
 60.2253 -
 60.2254 -                        case 0x8F: /*POPW*/
 60.2255 -                        fetchea();
 60.2256 -                        if (ssegs) ss=oldss;
 60.2257 -                        tempw=readmemw(ss,SP);
 60.2258 -                        SP+=2;
 60.2259 -                        seteaw(tempw);
 60.2260 -                        cycles-=25;
 60.2261 -                        break;
 60.2262 -
 60.2263 -                        case 0x90: /*NOP*/
 60.2264 -                        cycles-=3;
 60.2265 -                        break;
 60.2266 -
 60.2267 -                        case 0x91: case 0x92: case 0x93: /*XCHG AX*/
 60.2268 -                        case 0x94: case 0x95: case 0x96: case 0x97:
 60.2269 -                        tempw=AX;
 60.2270 -                        AX=regs[opcode&7].w;
 60.2271 -                        regs[opcode&7].w=tempw;
 60.2272 -                        cycles-=3;
 60.2273 -                        break;
 60.2274 -
 60.2275 -                        case 0x98: /*CBW*/
 60.2276 -                        AH=(AL&0x80)?0xFF:0;
 60.2277 -                        cycles-=2;
 60.2278 -                        break;
 60.2279 -                        case 0x99: /*CWD*/
 60.2280 -                        DX=(AX&0x8000)?0xFFFF:0;
 60.2281 -                        cycles-=5;
 60.2282 -                        break;
 60.2283 -                        case 0x9A: /*CALL FAR*/
 60.2284 -                        tempw=getword();
 60.2285 -                        tempw2=getword();
 60.2286 -                        tempw3=CS;
 60.2287 -                        tempw4=pc;
 60.2288 -                        if (ssegs) ss=oldss;
 60.2289 -                        pc=tempw;
 60.2290 -//                        printf("0x9a");
 60.2291 -                        loadcs(tempw2);
 60.2292 -                        writememw(ss,(SP-2)&0xFFFF,tempw3);
 60.2293 -                        writememw(ss,(SP-4)&0xFFFF,tempw4);
 60.2294 -                        SP-=4;
 60.2295 -                        cycles-=36;
 60.2296 -                        FETCHCLEAR();
 60.2297 -                        break;
 60.2298 -                        case 0x9B: /*WAIT*/
 60.2299 -                        cycles-=4;
 60.2300 -                        break;
 60.2301 -                        case 0x9C: /*PUSHF*/
 60.2302 -                        if (ssegs) ss=oldss;
 60.2303 -                        writememw(ss,((SP-2)&0xFFFF),flags|0xF000);
 60.2304 -                        SP-=2;
 60.2305 -                        cycles-=14;
 60.2306 -                        break;
 60.2307 -                        case 0x9D: /*POPF*/
 60.2308 -                        if (ssegs) ss=oldss;
 60.2309 -                        flags=readmemw(ss,SP)&0xFFF;
 60.2310 -                        SP+=2;
 60.2311 -                        cycles-=12;
 60.2312 -                        break;
 60.2313 -                        case 0x9E: /*SAHF*/
 60.2314 -                        flags=(flags&0xFF00)|AH;
 60.2315 -                        cycles-=4;
 60.2316 -                        break;
 60.2317 -                        case 0x9F: /*LAHF*/
 60.2318 -                        AH=flags&0xFF;
 60.2319 -                        cycles-=4;
 60.2320 -                        break;
 60.2321 -
 60.2322 -                        case 0xA0: /*MOV AL,(w)*/
 60.2323 -                        addr=getword();
 60.2324 -                        AL=readmemb(ds+addr);
 60.2325 -                        cycles-=14;
 60.2326 -                        break;
 60.2327 -                        case 0xA1: /*MOV AX,(w)*/
 60.2328 -                        addr=getword();
 60.2329 -//                        printf("Reading AX from %05X %04X:%04X\n",ds+addr,ds>>4,addr);
 60.2330 -                        AX=readmemw(ds,addr);
 60.2331 -                        cycles-=!4;
 60.2332 -                        break;
 60.2333 -                        case 0xA2: /*MOV (w),AL*/
 60.2334 -                        addr=getword();
 60.2335 -                        writememb(ds+addr,AL);
 60.2336 -                        cycles-=14;
 60.2337 -                        break;
 60.2338 -                        case 0xA3: /*MOV (w),AX*/
 60.2339 -                        addr=getword();
 60.2340 -//                        if (!addr) printf("Write !addr %04X:%04X\n",cs>>4,pc);
 60.2341 -                        writememw(ds,addr,AX);
 60.2342 -                        cycles-=14;
 60.2343 -                        break;
 60.2344 -
 60.2345 -                        case 0xA4: /*MOVSB*/
 60.2346 -                        temp=readmemb(ds+SI);
 60.2347 -                        writememb(es+DI,temp);
 60.2348 -                        if (flags&D_FLAG) { DI--; SI--; }
 60.2349 -                        else              { DI++; SI++; }
 60.2350 -                        cycles-=18;
 60.2351 -                        break;
 60.2352 -                        case 0xA5: /*MOVSW*/
 60.2353 -                        tempw=readmemw(ds,SI);
 60.2354 -                        writememw(es,DI,tempw);
 60.2355 -                        if (flags&D_FLAG) { DI-=2; SI-=2; }
 60.2356 -                        else              { DI+=2; SI+=2; }
 60.2357 -                        cycles-=18;
 60.2358 -                        break;
 60.2359 -                        case 0xA6: /*CMPSB*/
 60.2360 -                        temp =readmemb(ds+SI);
 60.2361 -                        temp2=readmemb(es+DI);
 60.2362 -                        setsub8(temp,temp2);
 60.2363 -                        if (flags&D_FLAG) { DI--; SI--; }
 60.2364 -                        else              { DI++; SI++; }
 60.2365 -                        cycles-=30;
 60.2366 -                        break;
 60.2367 -                        case 0xA7: /*CMPSW*/
 60.2368 -                        tempw =readmemw(ds,SI);
 60.2369 -                        tempw2=readmemw(es,DI);
 60.2370 -//                        printf("CMPSW %04X %04X\n",tempw,tempw2);
 60.2371 -                        setsub16(tempw,tempw2);
 60.2372 -                        if (flags&D_FLAG) { DI-=2; SI-=2; }
 60.2373 -                        else              { DI+=2; SI+=2; }
 60.2374 -                        cycles-=30;
 60.2375 -                        break;
 60.2376 -                        case 0xA8: /*TEST AL,#8*/
 60.2377 -                        temp=FETCH();
 60.2378 -                        setznp8(AL&temp);
 60.2379 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.2380 -                        cycles-=5;
 60.2381 -                        break;
 60.2382 -                        case 0xA9: /*TEST AX,#16*/
 60.2383 -                        tempw=getword();
 60.2384 -                        setznp16(AX&tempw);
 60.2385 -                        flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.2386 -                        cycles-=5;
 60.2387 -                        break;
 60.2388 -                        case 0xAA: /*STOSB*/
 60.2389 -                        writememb(es+DI,AL);
 60.2390 -                        if (flags&D_FLAG) DI--;
 60.2391 -                        else              DI++;
 60.2392 -                        cycles-=11;
 60.2393 -                        break;
 60.2394 -                        case 0xAB: /*STOSW*/
 60.2395 -                        writememw(es,DI,AX);
 60.2396 -                        if (flags&D_FLAG) DI-=2;
 60.2397 -                        else              DI+=2;
 60.2398 -                        cycles-=11;
 60.2399 -                        break;
 60.2400 -                        case 0xAC: /*LODSB*/
 60.2401 -                        AL=readmemb(ds+SI);
 60.2402 -//                        printf("LODSB %04X:%04X %02X %04X:%04X\n",cs>>4,pc,AL,ds>>4,SI);
 60.2403 -                        if (flags&D_FLAG) SI--;
 60.2404 -                        else              SI++;
 60.2405 -                        cycles-=16;
 60.2406 -                        break;
 60.2407 -                        case 0xAD: /*LODSW*/
 60.2408 -//                        if (times) printf("LODSW %04X:%04X\n",cs>>4,pc);
 60.2409 -                        AX=readmemw(ds,SI);
 60.2410 -                        if (flags&D_FLAG) SI-=2;
 60.2411 -                        else              SI+=2;
 60.2412 -                        cycles-=16;
 60.2413 -                        break;
 60.2414 -                        case 0xAE: /*SCASB*/
 60.2415 -                        temp=readmemb(es+DI);
 60.2416 -                        setsub8(AL,temp);
 60.2417 -                        if (flags&D_FLAG) DI--;
 60.2418 -                        else              DI++;
 60.2419 -                        cycles-=19;
 60.2420 -                        break;
 60.2421 -                        case 0xAF: /*SCASW*/
 60.2422 -                        tempw=readmemw(es,DI);
 60.2423 -                        setsub16(AX,tempw);
 60.2424 -                        if (flags&D_FLAG) DI-=2;
 60.2425 -                        else              DI+=2;
 60.2426 -                        cycles-=19;
 60.2427 -                        break;
 60.2428 -
 60.2429 -                        case 0xB0: /*MOV AL,#8*/
 60.2430 -                        AL=FETCH();
 60.2431 -                        cycles-=4;
 60.2432 -                        break;
 60.2433 -                        case 0xB1: /*MOV CL,#8*/
 60.2434 -                        CL=FETCH();
 60.2435 -                        cycles-=4;
 60.2436 -                        break;
 60.2437 -                        case 0xB2: /*MOV DL,#8*/
 60.2438 -                        DL=FETCH();
 60.2439 -                        cycles-=4;
 60.2440 -                        break;
 60.2441 -                        case 0xB3: /*MOV BL,#8*/
 60.2442 -                        BL=FETCH();
 60.2443 -                        cycles-=4;
 60.2444 -                        break;
 60.2445 -                        case 0xB4: /*MOV AH,#8*/
 60.2446 -                        AH=FETCH();
 60.2447 -                        cycles-=4;
 60.2448 -                        break;
 60.2449 -                        case 0xB5: /*MOV CH,#8*/
 60.2450 -                        CH=FETCH();
 60.2451 -                        cycles-=4;
 60.2452 -                        break;
 60.2453 -                        case 0xB6: /*MOV DH,#8*/
 60.2454 -                        DH=FETCH();
 60.2455 -                        cycles-=4;
 60.2456 -                        break;
 60.2457 -                        case 0xB7: /*MOV BH,#8*/
 60.2458 -                        BH=FETCH();
 60.2459 -                        cycles-=4;
 60.2460 -                        break;
 60.2461 -                        case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV reg,#16*/
 60.2462 -                        case 0xBC: case 0xBD: case 0xBE: case 0xBF:
 60.2463 -                        regs[opcode&7].w=getword();
 60.2464 -                        cycles-=4;
 60.2465 -                        break;
 60.2466 -
 60.2467 -                        case 0xC2: /*RET*/
 60.2468 -                        tempw=getword();
 60.2469 -                        if (ssegs) ss=oldss;
 60.2470 -                        pc=readmemw(ss,SP);
 60.2471 -//                        printf("C2\n");
 60.2472 -//                        printf("RET to %04X\n",pc);
 60.2473 -                        SP+=2+tempw;
 60.2474 -                        cycles-=24;
 60.2475 -                        FETCHCLEAR();
 60.2476 -                        break;
 60.2477 -                        case 0xC3: /*RET*/
 60.2478 -                        if (ssegs) ss=oldss;
 60.2479 -                        pc=readmemw(ss,SP);
 60.2480 -//                        printf("C3\n");
 60.2481 -//                        if (output) printf("RET to %04X %05X\n",pc,ss+SP);
 60.2482 -                        SP+=2;
 60.2483 -                        cycles-=20;
 60.2484 -                        FETCHCLEAR();
 60.2485 -                        break;
 60.2486 -                        case 0xC4: /*LES*/
 60.2487 -                        fetchea();
 60.2488 -                        regs[reg].w=readmemw(easeg,eaaddr); //geteaw();
 60.2489 -                        tempw=readmemw(easeg,(eaaddr+2)&0xFFFF); //geteaw2();
 60.2490 -                        loadseg(tempw,&_es);
 60.2491 -                        cycles-=24;
 60.2492 -                        break;
 60.2493 -                        case 0xC5: /*LDS*/
 60.2494 -                        fetchea();
 60.2495 -                        regs[reg].w=readmemw(easeg,eaaddr);
 60.2496 -                        tempw=readmemw(easeg,(eaaddr+2)&0xFFFF);
 60.2497 -                        loadseg(tempw,&_ds);
 60.2498 -                        if (ssegs) oldds=ds;
 60.2499 -                        cycles-=24;
 60.2500 -                        break;
 60.2501 -                        case 0xC6: /*MOV b,#8*/
 60.2502 -                        fetchea();
 60.2503 -                        temp=FETCH();
 60.2504 -                        seteab(temp);
 60.2505 -                        cycles-=((mod==3)?4:14);
 60.2506 -                        break;
 60.2507 -                        case 0xC7: /*MOV w,#16*/
 60.2508 -                        fetchea();
 60.2509 -                        tempw=getword();
 60.2510 -                        seteaw(tempw);
 60.2511 -                        cycles-=((mod==3)?4:14);
 60.2512 -                        break;
 60.2513 -
 60.2514 -                        case 0xCA: /*RETF*/
 60.2515 -                        tempw=getword();
 60.2516 -                        if (ssegs) ss=oldss;
 60.2517 -                        pc=readmemw(ss,SP);
 60.2518 -//                        printf("CA\n");
 60.2519 -                        loadcs(readmemw(ss,SP+2));
 60.2520 -                        SP+=4;
 60.2521 -                        SP+=tempw;
 60.2522 -                        cycles-=33;
 60.2523 -                        FETCHCLEAR();
 60.2524 -                        break;
 60.2525 -                        case 0xCB: /*RETF*/
 60.2526 -                        if (ssegs) ss=oldss;
 60.2527 -                        pc=readmemw(ss,SP);
 60.2528 -//                        printf("CB\n");
 60.2529 -                        loadcs(readmemw(ss,SP+2));
 60.2530 -                        SP+=4;
 60.2531 -                        cycles-=34;
 60.2532 -                        FETCHCLEAR();
 60.2533 -                        break;
 60.2534 -                        case 0xCC: /*INT 3*/
 60.2535 -                        if (ssegs) ss=oldss;
 60.2536 -                        writememw(ss,((SP-2)&0xFFFF),flags|0xF000);
 60.2537 -                        writememw(ss,((SP-4)&0xFFFF),CS);
 60.2538 -                        writememw(ss,((SP-6)&0xFFFF),pc);
 60.2539 -                        SP-=6;
 60.2540 -                        addr=3<<2;
 60.2541 -                        flags&=~I_FLAG;
 60.2542 -                        flags&=~T_FLAG;
 60.2543 -//                        printf("CC %04X:%04X  ",CS,pc);
 60.2544 -                        pc=readmemw(0,addr);
 60.2545 -                        loadcs(readmemw(0,addr+2));
 60.2546 -                        FETCHCLEAR();
 60.2547 -//                        printf("%04X:%04X\n",CS,pc);
 60.2548 -                        cycles-=72;
 60.2549 -                        break;
 60.2550 -                        case 0xCD: /*INT*/
 60.2551 -                        lastpc=pc;
 60.2552 -                        lastcs=CS;
 60.2553 -                        temp=FETCH();
 60.2554 -                        
 60.2555 -//                        if (temp == 0x13  && AX == 0x0201  && ES == 0x0BF5 && CX == 0x1D06) output = 3;
 60.2556 -//                        if (temp==0x10 && !AH) printf("Entering mode %02X\n",AL);
 60.2557 -//                        if (temp==0x18 || temp==0x19) { printf("INT %02X\n",temp); output=1; }
 60.2558 -//                        /*if (temp==0x13) */printf("INT %02X %04X %04X:%04X %04X %04X:%04X %04X:%04X\n",temp,AX,ES,BX,CX,DS,DX,CS,pc);
 60.2559 -                        //if (temp == 0x13 && AH == 2) output = 3;
 60.2560 -/*                        if (CS==0xC800 && temp==0x13)
 60.2561 -                        {
 60.2562 -                                output=3;
 60.2563 -                                timetolive=100000;
 60.2564 -                        }*/
 60.2565 -/*                        if (temp==0x10) printf("INT 10 %04X %04X %04X %04X %04X:%04X %06X %06X %c\n",AX,BX,CX,DX,cs>>4,pc,ds,ds+DX, (AL > 31) ? AL : '.');
 60.2566 -                        if (temp == 0x10 && AX == 0xe35)
 60.2567 -                        {
 60.2568 -                                dumpregs();
 60.2569 -
 60.2570 -                        }*/
 60.2571 -/*                        if (temp==0x21 && AH==9)
 60.2572 -                        {
 60.2573 -                                addr=0;
 60.2574 -                                while (ram[ds+DX+addr]!='$')
 60.2575 -                                {
 60.2576 -                                        printf("%c",ram[ds+DX+addr]);
 60.2577 -                                        addr++;
 60.2578 -                                }
 60.2579 -                                printf("\n");
 60.2580 -                                printf("Called from %04X\n",readmemw(ss,SP));
 60.2581 -                        }*/
 60.2582 -//                        output=0;
 60.2583 -//                        if (temp==0x13 && AH==3) printf("Write sector %04X:%04X %05X\n",es>>4,BX,es+BX);
 60.2584 -/*                        if (temp==0x13 && (DL==0x80 || DL==0x81) && AH>0)
 60.2585 -                        {
 60.2586 -                                int13hdc();
 60.2587 -                        }
 60.2588 -                        else *//*if (temp==0x13 && AH==2 && DL<2)// && FASTDISC)
 60.2589 -                        {
 60.2590 -                                int13read();
 60.2591 -                                //output=1;
 60.2592 -                        }
 60.2593 -                        else if (temp==0x13 && AH==3 && DL<2)// && FASTDISC)
 60.2594 -                        {
 60.2595 -                                int13write();
 60.2596 -                        }
 60.2597 -                        else if (temp==0x13 && AH==4 && DL<2)// && FASTDISC)
 60.2598 -                        {
 60.2599 -                                AH=0;
 60.2600 -                                flags&=~C_FLAG;
 60.2601 -                        }
 60.2602 -                        else
 60.2603 -                        {*/
 60.2604 -                                if (ssegs) ss=oldss;
 60.2605 -                                writememw(ss,((SP-2)&0xFFFF),flags|0xF000);
 60.2606 -                                writememw(ss,((SP-4)&0xFFFF),CS);
 60.2607 -                                writememw(ss,((SP-6)&0xFFFF),pc);
 60.2608 -                                flags&=~T_FLAG;
 60.2609 -                                SP-=6;
 60.2610 -                                addr=temp<<2;
 60.2611 -                                pc=readmemw(0,addr);
 60.2612 -//                        printf("CD\n");
 60.2613 -                                loadcs(readmemw(0,addr+2));
 60.2614 -                                FETCHCLEAR();
 60.2615 -//                        }
 60.2616 -                        cycles-=71;
 60.2617 -                        break;
 60.2618 -                        case 0xCF: /*IRET*/
 60.2619 -                        if (ssegs) ss=oldss;
 60.2620 -                        tempw=CS;
 60.2621 -                        tempw2=pc;
 60.2622 -                        inint=0;
 60.2623 -                        pc=readmemw(ss,SP);
 60.2624 -//                        printf("CF\n");
 60.2625 -                        loadcs(readmemw(ss,((SP+2)&0xFFFF)));
 60.2626 -                        flags=readmemw(ss,((SP+4)&0xFFFF))&0xFFF;
 60.2627 -                        SP+=6;
 60.2628 -                        cycles-=44;
 60.2629 -                        FETCHCLEAR();
 60.2630 -                        break;
 60.2631 -                        case 0xD0:
 60.2632 -                        fetchea();
 60.2633 -                        temp=geteab();
 60.2634 -                        switch (rmdat&0x38)
 60.2635 -                        {
 60.2636 -                                case 0x00: /*ROL b,1*/
 60.2637 -                                if (temp&0x80) flags|=C_FLAG;
 60.2638 -                                else           flags&=~C_FLAG;
 60.2639 -                                temp<<=1;
 60.2640 -                                if (flags&C_FLAG) temp|=1;
 60.2641 -                                seteab(temp);
 60.2642 -//                                setznp8(temp);
 60.2643 -                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
 60.2644 -                                else                          flags&=~V_FLAG;
 60.2645 -                                cycles-=((mod==3)?2:23);
 60.2646 -                                break;
 60.2647 -                                case 0x08: /*ROR b,1*/
 60.2648 -                                if (temp&1) flags|=C_FLAG;
 60.2649 -                                else        flags&=~C_FLAG;
 60.2650 -                                temp>>=1;
 60.2651 -                                if (flags&C_FLAG) temp|=0x80;
 60.2652 -                                seteab(temp);
 60.2653 -//                                setznp8(temp);
 60.2654 -                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
 60.2655 -                                else                       flags&=~V_FLAG;
 60.2656 -                                cycles-=((mod==3)?2:23);
 60.2657 -                                break;
 60.2658 -                                case 0x10: /*RCL b,1*/
 60.2659 -                                temp2=flags&C_FLAG;
 60.2660 -                                if (temp&0x80) flags|=C_FLAG;
 60.2661 -                                else           flags&=~C_FLAG;
 60.2662 -                                temp<<=1;
 60.2663 -                                if (temp2) temp|=1;
 60.2664 -                                seteab(temp);
 60.2665 -//                                setznp8(temp);
 60.2666 -                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
 60.2667 -                                else                          flags&=~V_FLAG;
 60.2668 -                                cycles-=((mod==3)?2:23);
 60.2669 -                                break;
 60.2670 -                                case 0x18: /*RCR b,1*/
 60.2671 -                                temp2=flags&C_FLAG;
 60.2672 -                                if (temp&1) flags|=C_FLAG;
 60.2673 -                                else        flags&=~C_FLAG;
 60.2674 -                                temp>>=1;
 60.2675 -                                if (temp2) temp|=0x80;
 60.2676 -                                seteab(temp);
 60.2677 -//                                setznp8(temp);
 60.2678 -                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
 60.2679 -                                else                       flags&=~V_FLAG;
 60.2680 -                                cycles-=((mod==3)?2:23);
 60.2681 -                                break;
 60.2682 -                                case 0x20: case 0x30: /*SHL b,1*/
 60.2683 -                                if (temp&0x80) flags|=C_FLAG;
 60.2684 -                                else           flags&=~C_FLAG;
 60.2685 -                                if ((temp^(temp<<1))&0x80) flags|=V_FLAG;
 60.2686 -                                else                       flags&=~V_FLAG;
 60.2687 -                                temp<<=1;
 60.2688 -                                seteab(temp);
 60.2689 -                                setznp8(temp);
 60.2690 -                                cycles-=((mod==3)?2:23);
 60.2691 -                                flags|=A_FLAG;
 60.2692 -                                break;
 60.2693 -                                case 0x28: /*SHR b,1*/
 60.2694 -                                if (temp&1) flags|=C_FLAG;
 60.2695 -                                else        flags&=~C_FLAG;
 60.2696 -                                if (temp&0x80) flags|=V_FLAG;
 60.2697 -                                else           flags&=~V_FLAG;
 60.2698 -                                temp>>=1;
 60.2699 -                                seteab(temp);
 60.2700 -                                setznp8(temp);
 60.2701 -                                cycles-=((mod==3)?2:23);
 60.2702 -                                flags|=A_FLAG;
 60.2703 -                                break;
 60.2704 -                                case 0x38: /*SAR b,1*/
 60.2705 -                                if (temp&1) flags|=C_FLAG;
 60.2706 -                                else        flags&=~C_FLAG;
 60.2707 -                                temp>>=1;
 60.2708 -                                if (temp&0x40) temp|=0x80;
 60.2709 -                                seteab(temp);
 60.2710 -                                setznp8(temp);
 60.2711 -                                cycles-=((mod==3)?2:23);
 60.2712 -                                flags|=A_FLAG;
 60.2713 -                                flags&=~V_FLAG;
 60.2714 -                                break;
 60.2715 -
 60.2716 -//                                default:
 60.2717 -//                                printf("Bad D0 opcode %02X\n",rmdat&0x38);
 60.2718 -//                                dumpregs();
 60.2719 -//                                exit(-1);
 60.2720 -                        }
 60.2721 -                        break;
 60.2722 -
 60.2723 -                        case 0xD1:
 60.2724 -                        fetchea();
 60.2725 -                        tempw=geteaw();
 60.2726 -                        switch (rmdat&0x38)
 60.2727 -                        {
 60.2728 -                                case 0x00: /*ROL w,1*/
 60.2729 -                                if (tempw&0x8000) flags|=C_FLAG;
 60.2730 -                                else              flags&=~C_FLAG;
 60.2731 -                                tempw<<=1;
 60.2732 -                                if (flags&C_FLAG) tempw|=1;
 60.2733 -                                seteaw(tempw);
 60.2734 -//                                setznp16(tempw);
 60.2735 -                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
 60.2736 -                                else                            flags&=~V_FLAG;
 60.2737 -                                cycles-=((mod==3)?2:23);
 60.2738 -                                break;
 60.2739 -                                case 0x08: /*ROR w,1*/
 60.2740 -                                if (tempw&1) flags|=C_FLAG;
 60.2741 -                                else         flags&=~C_FLAG;
 60.2742 -                                tempw>>=1;
 60.2743 -                                if (flags&C_FLAG) tempw|=0x8000;
 60.2744 -                                seteaw(tempw);
 60.2745 -//                                setznp16(tempw);
 60.2746 -                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
 60.2747 -                                else                           flags&=~V_FLAG;
 60.2748 -                                cycles-=((mod==3)?2:23);
 60.2749 -                                break;
 60.2750 -                                case 0x10: /*RCL w,1*/
 60.2751 -                                temp2=flags&C_FLAG;
 60.2752 -                                if (tempw&0x8000) flags|=C_FLAG;
 60.2753 -                                else              flags&=~C_FLAG;
 60.2754 -                                tempw<<=1;
 60.2755 -                                if (temp2) tempw|=1;
 60.2756 -                                seteaw(tempw);
 60.2757 -                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
 60.2758 -                                else                            flags&=~V_FLAG;
 60.2759 -                                cycles-=((mod==3)?2:23);
 60.2760 -                                break;
 60.2761 -                                case 0x18: /*RCR w,1*/
 60.2762 -                                temp2=flags&C_FLAG;
 60.2763 -                                if (tempw&1) flags|=C_FLAG;
 60.2764 -                                else         flags&=~C_FLAG;
 60.2765 -                                tempw>>=1;
 60.2766 -                                if (temp2) tempw|=0x8000;
 60.2767 -                                seteaw(tempw);
 60.2768 -//                                setznp16(tempw);
 60.2769 -                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
 60.2770 -                                else                           flags&=~V_FLAG;
 60.2771 -                                cycles-=((mod==3)?2:23);
 60.2772 -                                break;
 60.2773 -                                case 0x20: case 0x30: /*SHL w,1*/
 60.2774 -                                if (tempw&0x8000) flags|=C_FLAG;
 60.2775 -                                else              flags&=~C_FLAG;
 60.2776 -                                if ((tempw^(tempw<<1))&0x8000) flags|=V_FLAG;
 60.2777 -                                else                           flags&=~V_FLAG;
 60.2778 -                                tempw<<=1;
 60.2779 -                                seteaw(tempw);
 60.2780 -                                setznp16(tempw);
 60.2781 -                                cycles-=((mod==3)?2:23);
 60.2782 -                                flags|=A_FLAG;
 60.2783 -                                break;
 60.2784 -                                case 0x28: /*SHR w,1*/
 60.2785 -                                if (tempw&1) flags|=C_FLAG;
 60.2786 -                                else         flags&=~C_FLAG;
 60.2787 -                                if (tempw&0x8000) flags|=V_FLAG;
 60.2788 -                                else              flags&=~V_FLAG;
 60.2789 -                                tempw>>=1;
 60.2790 -                                seteaw(tempw);
 60.2791 -                                setznp16(tempw);
 60.2792 -                                cycles-=((mod==3)?2:23);
 60.2793 -                                flags|=A_FLAG;
 60.2794 -                                break;
 60.2795 -
 60.2796 -                                case 0x38: /*SAR w,1*/
 60.2797 -                                if (tempw&1) flags|=C_FLAG;
 60.2798 -                                else         flags&=~C_FLAG;
 60.2799 -                                tempw>>=1;
 60.2800 -                                if (tempw&0x4000) tempw|=0x8000;
 60.2801 -                                seteaw(tempw);
 60.2802 -                                setznp16(tempw);
 60.2803 -                                cycles-=((mod==3)?2:23);
 60.2804 -                                flags|=A_FLAG;
 60.2805 -                                flags&=~V_FLAG;
 60.2806 -                                break;
 60.2807 -
 60.2808 -//                                default:
 60.2809 -//                                printf("Bad D1 opcode %02X\n",rmdat&0x38);
 60.2810 -//                                dumpregs();
 60.2811 -//                                exit(-1);
 60.2812 -                        }
 60.2813 -                        break;
 60.2814 -
 60.2815 -                        case 0xD2:
 60.2816 -                        fetchea();
 60.2817 -                        temp=geteab();
 60.2818 -                        c=CL;
 60.2819 -//                        cycles-=c;
 60.2820 -                        if (!c) break;
 60.2821 -//                        if (c>7) printf("Shiftb %i %02X\n",rmdat&0x38,c);
 60.2822 -                        switch (rmdat&0x38)
 60.2823 -                        {
 60.2824 -                                case 0x00: /*ROL b,CL*/
 60.2825 -                                while (c>0)
 60.2826 -                                {
 60.2827 -                                        temp2=(temp&0x80)?1:0;
 60.2828 -                                        temp=(temp<<1)|temp2;
 60.2829 -                                        c--;
 60.2830 -                                        cycles-=4;
 60.2831 -                                }
 60.2832 -                                if (temp2) flags|=C_FLAG;
 60.2833 -                                else       flags&=~C_FLAG;
 60.2834 -                                seteab(temp);
 60.2835 -//                                setznp8(temp);
 60.2836 -                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
 60.2837 -                                else                          flags&=~V_FLAG;
 60.2838 -                                cycles-=((mod==3)?8:28);
 60.2839 -                                break;
 60.2840 -                                case 0x08: /*ROR b,CL*/
 60.2841 -                                while (c>0)
 60.2842 -                                {
 60.2843 -                                        temp2=temp&1;
 60.2844 -                                        temp>>=1;
 60.2845 -                                        if (temp2) temp|=0x80;
 60.2846 -                                        c--;
 60.2847 -                                        cycles-=4;
 60.2848 -                                }
 60.2849 -                                if (temp2) flags|=C_FLAG;
 60.2850 -                                else       flags&=~C_FLAG;
 60.2851 -                                seteab(temp);
 60.2852 -                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
 60.2853 -                                else                       flags&=~V_FLAG;
 60.2854 -                                cycles-=((mod==3)?8:28);
 60.2855 -                                break;
 60.2856 -                                case 0x10: /*RCL b,CL*/
 60.2857 -//                                printf("RCL %i %02X %02X\n",c,CL,temp);
 60.2858 -                                while (c>0)
 60.2859 -                                {
 60.2860 -                                        templ=flags&C_FLAG;
 60.2861 -                                        temp2=temp&0x80;
 60.2862 -                                        temp<<=1;
 60.2863 -                                        if (temp2) flags|=C_FLAG;
 60.2864 -                                        else       flags&=~C_FLAG;
 60.2865 -                                        if (templ) temp|=1;
 60.2866 -                                        c--;
 60.2867 -                                        cycles-=4;
 60.2868 -                                }
 60.2869 -//                                printf("Now %02X\n",temp);
 60.2870 -                                seteab(temp);
 60.2871 -                                if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG;
 60.2872 -                                else                          flags&=~V_FLAG;
 60.2873 -                                cycles-=((mod==3)?8:28);
 60.2874 -                                break;
 60.2875 -                                case 0x18: /*RCR b,CL*/
 60.2876 -                                while (c>0)
 60.2877 -                                {
 60.2878 -                                        templ=flags&C_FLAG;
 60.2879 -                                        temp2=temp&1;
 60.2880 -                                        temp>>=1;
 60.2881 -                                        if (temp2) flags|=C_FLAG;
 60.2882 -                                        else       flags&=~C_FLAG;
 60.2883 -                                        if (templ) temp|=0x80;
 60.2884 -                                        c--;
 60.2885 -                                        cycles-=4;
 60.2886 -                                }
 60.2887 -//                                if (temp2) flags|=C_FLAG;
 60.2888 -//                                else       flags&=~C_FLAG;
 60.2889 -                                seteab(temp);
 60.2890 -                                if ((temp^(temp>>1))&0x40) flags|=V_FLAG;
 60.2891 -                                else                       flags&=~V_FLAG;
 60.2892 -                                cycles-=((mod==3)?8:28);
 60.2893 -                                break;
 60.2894 -                                case 0x20: case 0x30: /*SHL b,CL*/
 60.2895 -                                if ((temp<<(c-1))&0x80) flags|=C_FLAG;
 60.2896 -                                else                    flags&=~C_FLAG;
 60.2897 -                                temp<<=c;
 60.2898 -                                seteab(temp);
 60.2899 -                                setznp8(temp);
 60.2900 -                                cycles-=(c*4);
 60.2901 -                                cycles-=((mod==3)?8:28);
 60.2902 -                                flags|=A_FLAG;
 60.2903 -                                break;
 60.2904 -                                case 0x28: /*SHR b,CL*/
 60.2905 -                                if ((temp>>(c-1))&1) flags|=C_FLAG;
 60.2906 -                                else                 flags&=~C_FLAG;
 60.2907 -                                temp>>=c;
 60.2908 -                                seteab(temp);
 60.2909 -                                setznp8(temp);
 60.2910 -                                cycles-=(c*4);
 60.2911 -                                cycles-=((mod==3)?8:28);
 60.2912 -                                flags|=A_FLAG;
 60.2913 -                                break;
 60.2914 -                                case 0x38: /*SAR b,CL*/
 60.2915 -                                if ((temp>>(c-1))&1) flags|=C_FLAG;
 60.2916 -                                else                 flags&=~C_FLAG;
 60.2917 -                                while (c>0)
 60.2918 -                                {
 60.2919 -                                        temp>>=1;
 60.2920 -                                        if (temp&0x40) temp|=0x80;
 60.2921 -                                        c--;
 60.2922 -                                        cycles-=4;
 60.2923 -                                }
 60.2924 -                                seteab(temp);
 60.2925 -                                setznp8(temp);
 60.2926 -                                cycles-=((mod==3)?8:28);
 60.2927 -                                flags|=A_FLAG;
 60.2928 -                                break;
 60.2929 -
 60.2930 -//                                default:
 60.2931 -//                                printf("Bad D2 opcode %02X\n",rmdat&0x38);
 60.2932 -//                                dumpregs();
 60.2933 -//                                exit(-1);
 60.2934 -                        }
 60.2935 -                        break;
 60.2936 -
 60.2937 -                        case 0xD3:
 60.2938 -                        fetchea();
 60.2939 -                        tempw=geteaw();
 60.2940 -                        c=CL;
 60.2941 -//                      cycles-=c;
 60.2942 -                        if (!c) break;
 60.2943 -//                        if (c>15) printf("Shiftw %i %02X\n",rmdat&0x38,c);
 60.2944 -                        switch (rmdat&0x38)
 60.2945 -                        {
 60.2946 -                                case 0x00: /*ROL w,CL*/
 60.2947 -                                while (c>0)
 60.2948 -                                {
 60.2949 -                                        temp=(tempw&0x8000)?1:0;
 60.2950 -                                        tempw=(tempw<<1)|temp;
 60.2951 -                                        c--;
 60.2952 -                                        cycles-=4;
 60.2953 -                                }
 60.2954 -                                if (temp) flags|=C_FLAG;
 60.2955 -                                else      flags&=~C_FLAG;
 60.2956 -                                seteaw(tempw);
 60.2957 -                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
 60.2958 -                                else                            flags&=~V_FLAG;
 60.2959 -                                cycles-=((mod==3)?8:28);
 60.2960 -                                break;
 60.2961 -                                case 0x08: /*ROR w,CL*/
 60.2962 -                                while (c>0)
 60.2963 -                                {
 60.2964 -                                        tempw2=(tempw&1)?0x8000:0;
 60.2965 -                                        tempw=(tempw>>1)|tempw2;
 60.2966 -                                        c--;
 60.2967 -                                        cycles-=4;
 60.2968 -                                }
 60.2969 -                                if (tempw2) flags|=C_FLAG;
 60.2970 -                                else        flags&=~C_FLAG;
 60.2971 -                                seteaw(tempw);
 60.2972 -                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
 60.2973 -                                else                           flags&=~V_FLAG;
 60.2974 -                                cycles-=((mod==3)?8:28);
 60.2975 -                                break;
 60.2976 -                                case 0x10: /*RCL w,CL*/
 60.2977 -                                while (c>0)
 60.2978 -                                {
 60.2979 -                                        templ=flags&C_FLAG;
 60.2980 -                                        if (tempw&0x8000) flags|=C_FLAG;
 60.2981 -                                        else              flags&=~C_FLAG;
 60.2982 -                                        tempw=(tempw<<1)|templ;
 60.2983 -                                        c--;
 60.2984 -                                        cycles-=4;
 60.2985 -                                }
 60.2986 -                                if (temp) flags|=C_FLAG;
 60.2987 -                                else      flags&=~C_FLAG;
 60.2988 -                                seteaw(tempw);
 60.2989 -                                if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG;
 60.2990 -                                else                            flags&=~V_FLAG;
 60.2991 -                                cycles-=((mod==3)?8:28);
 60.2992 -                                break;
 60.2993 -                                case 0x18: /*RCR w,CL*/
 60.2994 -                                while (c>0)
 60.2995 -                                {
 60.2996 -                                        templ=flags&C_FLAG;
 60.2997 -                                        tempw2=(templ&1)?0x8000:0;
 60.2998 -                                        if (tempw&1) flags|=C_FLAG;
 60.2999 -                                        else         flags&=~C_FLAG;
 60.3000 -                                        tempw=(tempw>>1)|tempw2;
 60.3001 -                                        c--;
 60.3002 -                                        cycles-=4;
 60.3003 -                                }
 60.3004 -                                if (tempw2) flags|=C_FLAG;
 60.3005 -                                else        flags&=~C_FLAG;
 60.3006 -                                seteaw(tempw);
 60.3007 -                                if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG;
 60.3008 -                                else                           flags&=~V_FLAG;
 60.3009 -                                cycles-=((mod==3)?8:28);
 60.3010 -                                break;
 60.3011 -
 60.3012 -                                case 0x20: case 0x30: /*SHL w,CL*/
 60.3013 -                                if (c>16)
 60.3014 -                                {
 60.3015 -                                        tempw=0;
 60.3016 -                                        flags&=~C_FLAG;
 60.3017 -                                }
 60.3018 -                                else
 60.3019 -                                {
 60.3020 -                                        if ((tempw<<(c-1))&0x8000) flags|=C_FLAG;
 60.3021 -                                        else                       flags&=~C_FLAG;
 60.3022 -                                        tempw<<=c;
 60.3023 -                                }
 60.3024 -                                seteaw(tempw);
 60.3025 -                                setznp16(tempw);
 60.3026 -                                cycles-=(c*4);
 60.3027 -                                cycles-=((mod==3)?8:28);
 60.3028 -                                flags|=A_FLAG;
 60.3029 -                                break;
 60.3030 -
 60.3031 -                                case 0x28:            /*SHR w,CL*/
 60.3032 -                                if ((tempw>>(c-1))&1) flags|=C_FLAG;
 60.3033 -                                else                  flags&=~C_FLAG;
 60.3034 -                                tempw>>=c;
 60.3035 -                                seteaw(tempw);
 60.3036 -                                setznp16(tempw);
 60.3037 -                                cycles-=(c*4);
 60.3038 -                                cycles-=((mod==3)?8:28);
 60.3039 -                                flags|=A_FLAG;
 60.3040 -                                break;
 60.3041 -
 60.3042 -                                case 0x38:            /*SAR w,CL*/
 60.3043 -                                tempw2=tempw&0x8000;
 60.3044 -                                if ((tempw>>(c-1))&1) flags|=C_FLAG;
 60.3045 -                                else                  flags&=~C_FLAG;
 60.3046 -                                while (c>0)
 60.3047 -                                {
 60.3048 -                                        tempw=(tempw>>1)|tempw2;
 60.3049 -                                        c--;
 60.3050 -                                        cycles-=4;
 60.3051 -                                }
 60.3052 -                                seteaw(tempw);
 60.3053 -                                setznp16(tempw);
 60.3054 -                                cycles-=((mod==3)?8:28);
 60.3055 -                                flags|=A_FLAG;
 60.3056 -                                break;
 60.3057 -
 60.3058 -//                                default:
 60.3059 -//                                printf("Bad D3 opcode %02X\n",rmdat&0x38);
 60.3060 -//                                dumpregs();
 60.3061 -//                                exit(-1);
 60.3062 -                        }
 60.3063 -                        break;
 60.3064 -
 60.3065 -                        case 0xD4: /*AAM*/
 60.3066 -                        tempws=FETCH();
 60.3067 -                        AH=AL/tempws;
 60.3068 -                        AL%=tempws;
 60.3069 -                        setznp168(AX);
 60.3070 -                        cycles-=83;
 60.3071 -                        break;
 60.3072 -                        case 0xD5: /*AAD*/
 60.3073 -                        tempws=FETCH();
 60.3074 -                        AL=(AH*tempws)+AL;
 60.3075 -                        AH=0;
 60.3076 -                        setznp168(AX);
 60.3077 -                        cycles-=60;
 60.3078 -                        break;
 60.3079 -                        case 0xD7: /*XLAT*/
 60.3080 -                        addr=BX+AL;
 60.3081 -                        AL=readmemb(ds+addr);
 60.3082 -                        cycles-=11;
 60.3083 -                        break;
 60.3084 -                        case 0xD9: case 0xDA: case 0xDB: case 0xDD: /*ESCAPE*/
 60.3085 -                        case 0xDC: case 0xDE: case 0xDF: case 0xD8:
 60.3086 -                        fetchea();
 60.3087 -                        geteab();
 60.3088 -                        break;
 60.3089 -
 60.3090 -                        case 0xE0: /*LOOPNE*/
 60.3091 -                        offset=(int8_t)FETCH();
 60.3092 -                        CX--;
 60.3093 -                        if (CX && !(flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.3094 -                        cycles-=6;
 60.3095 -                        break;
 60.3096 -                        case 0xE1: /*LOOPE*/
 60.3097 -                        offset=(int8_t)FETCH();
 60.3098 -                        CX--;
 60.3099 -                        if (CX && (flags&Z_FLAG)) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.3100 -                        cycles-=6;
 60.3101 -                        break;
 60.3102 -                        case 0xE2: /*LOOP*/
 60.3103 -//                        printf("LOOP start\n");
 60.3104 -                        offset=(int8_t)FETCH();
 60.3105 -                        CX--;
 60.3106 -                        if (CX) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.3107 -                        cycles-=5;
 60.3108 -//                        printf("LOOP end!\n");
 60.3109 -                        break;
 60.3110 -                        case 0xE3: /*JCXZ*/
 60.3111 -                        offset=(int8_t)FETCH();
 60.3112 -                        if (!CX) { pc+=offset; cycles-=12; FETCHCLEAR(); }
 60.3113 -                        cycles-=6;
 60.3114 -                        break;
 60.3115 -
 60.3116 -                        case 0xE4: /*IN AL*/
 60.3117 -                        temp=FETCH();
 60.3118 -                        AL=inb(temp);
 60.3119 -                        cycles-=14;
 60.3120 -                        break;
 60.3121 -                        case 0xE5: /*IN AX*/
 60.3122 -                        temp=FETCH();
 60.3123 -                        AL=inb(temp);
 60.3124 -                        AH=inb(temp+1);
 60.3125 -                        cycles-=14;
 60.3126 -                        break;
 60.3127 -                        case 0xE6: /*OUT AL*/
 60.3128 -                        temp=FETCH();
 60.3129 -                        outb(temp,AL);
 60.3130 -                        cycles-=14;
 60.3131 -                        break;
 60.3132 -                        case 0xE7: /*OUT AX*/
 60.3133 -                        temp=FETCH();
 60.3134 -                        outb(temp,AL);
 60.3135 -                        outb(temp+1,AH);
 60.3136 -                        cycles-=14;
 60.3137 -                        break;
 60.3138 -
 60.3139 -                        case 0xE8: /*CALL rel 16*/
 60.3140 -                        tempw=getword();
 60.3141 -                        if (ssegs) ss=oldss;
 60.3142 -//                        writememb(ss+((SP-1)&0xFFFF),pc>>8);
 60.3143 -                        writememw(ss,((SP-2)&0xFFFF),pc);
 60.3144 -                        SP-=2;
 60.3145 -                        pc+=tempw;
 60.3146 -                        cycles-=23;
 60.3147 -                        FETCHCLEAR();
 60.3148 -                        break;
 60.3149 -                        case 0xE9: /*JMP rel 16*/
 60.3150 -//                        printf("PC was %04X\n",pc);
 60.3151 -                        pc+=getword();
 60.3152 -//                        printf("PC now %04X\n",pc);
 60.3153 -                        cycles-=15;
 60.3154 -                        FETCHCLEAR();
 60.3155 -                        break;
 60.3156 -                        case 0xEA: /*JMP far*/
 60.3157 -                        addr=getword();
 60.3158 -                        tempw=getword();
 60.3159 -                        pc=addr;
 60.3160 -//                        printf("EA\n");
 60.3161 -                        loadcs(tempw);
 60.3162 -//                        cs=loadcs(CS);
 60.3163 -//                        cs=CS<<4;
 60.3164 -                        cycles-=15;
 60.3165 -                        FETCHCLEAR();
 60.3166 -                        break;
 60.3167 -                        case 0xEB: /*JMP rel*/
 60.3168 -                        offset=(int8_t)FETCH();
 60.3169 -                        pc+=offset;
 60.3170 -                        cycles-=15;
 60.3171 -                        FETCHCLEAR();
 60.3172 -                        break;
 60.3173 -                        case 0xEC: /*IN AL,DX*/
 60.3174 -                        AL=inb(DX);
 60.3175 -                        cycles-=12;
 60.3176 -                        break;
 60.3177 -                        case 0xED: /*IN AX,DX*/
 60.3178 -                        AL=inb(DX);
 60.3179 -                        AH=inb(DX+1);
 60.3180 -                        cycles-=12;
 60.3181 -                        break;
 60.3182 -                        case 0xEE: /*OUT DX,AL*/
 60.3183 -                        outb(DX,AL);
 60.3184 -                        cycles-=12;
 60.3185 -                        break;
 60.3186 -                        case 0xEF: /*OUT DX,AX*/
 60.3187 -                        outb(DX,AL);
 60.3188 -                        outb(DX+1,AH);
 60.3189 -                        cycles-=12;
 60.3190 -                        break;
 60.3191 -
 60.3192 -                        case 0xF0: /*LOCK*/
 60.3193 -                        cycles-=4;
 60.3194 -                        break;
 60.3195 -
 60.3196 -                        case 0xF2: /*REPNE*/
 60.3197 -                        rep(0);
 60.3198 -                        break;
 60.3199 -                        case 0xF3: /*REPE*/
 60.3200 -                        rep(1);
 60.3201 -                        break;
 60.3202 -
 60.3203 -                        case 0xF4: /*HLT*/
 60.3204 -//                        printf("IN HLT!!!! %04X:%04X %08X %08X %08X\n",oldcs,oldpc,old8,old82,old83);
 60.3205 -/*                        if (!(flags & I_FLAG))
 60.3206 -                        {
 60.3207 -                                pclog("HLT\n");
 60.3208 -                                dumpregs();
 60.3209 -                                exit(-1);
 60.3210 -                        }*/
 60.3211 -                        inhlt=1;
 60.3212 -                        pc--;
 60.3213 -                        FETCHCLEAR();
 60.3214 -                        cycles-=2;
 60.3215 -                        break;
 60.3216 -                        case 0xF5: /*CMC*/
 60.3217 -                        flags^=C_FLAG;
 60.3218 -                        cycles-=2;
 60.3219 -                        break;
 60.3220 -
 60.3221 -                        case 0xF6:
 60.3222 -                        fetchea();
 60.3223 -                        temp=geteab();
 60.3224 -                        switch (rmdat&0x38)
 60.3225 -                        {
 60.3226 -                                case 0x00: /*TEST b,#8*/
 60.3227 -                                temp2=FETCH();
 60.3228 -                                temp&=temp2;
 60.3229 -                                setznp8(temp);
 60.3230 -                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.3231 -                                cycles-=((mod==3)?5:11);
 60.3232 -                                break;
 60.3233 -                                case 0x10: /*NOT b*/
 60.3234 -                                temp=~temp;
 60.3235 -                                seteab(temp);
 60.3236 -                                cycles-=((mod==3)?3:24);
 60.3237 -                                break;
 60.3238 -                                case 0x18: /*NEG b*/
 60.3239 -                                setsub8(0,temp);
 60.3240 -                                temp=0-temp;
 60.3241 -                                seteab(temp);
 60.3242 -                                cycles-=((mod==3)?3:24);
 60.3243 -                                break;
 60.3244 -                                case 0x20: /*MUL AL,b*/
 60.3245 -                                setznp8(AL);
 60.3246 -                                AX=AL*temp;
 60.3247 -                                if (AX) flags&=~Z_FLAG;
 60.3248 -                                else    flags|=Z_FLAG;
 60.3249 -                                if (AH) flags|=(C_FLAG|V_FLAG);
 60.3250 -                                else    flags&=~(C_FLAG|V_FLAG);
 60.3251 -                                cycles-=70;
 60.3252 -                                break;
 60.3253 -                                case 0x28: /*IMUL AL,b*/
 60.3254 -                                setznp8(AL);
 60.3255 -                                tempws=(int)((int8_t)AL)*(int)((int8_t)temp);
 60.3256 -                                AX=tempws&0xFFFF;
 60.3257 -                                if (AX) flags&=~Z_FLAG;
 60.3258 -                                else    flags|=Z_FLAG;
 60.3259 -                                if (AH) flags|=(C_FLAG|V_FLAG);
 60.3260 -                                else    flags&=~(C_FLAG|V_FLAG);
 60.3261 -                                cycles-=80;
 60.3262 -                                break;
 60.3263 -                                case 0x30: /*DIV AL,b*/
 60.3264 -                                tempw=AX;
 60.3265 -                                if (temp)
 60.3266 -                                {
 60.3267 -                                        tempw2=tempw%temp;
 60.3268 -/*                                        if (!tempw)
 60.3269 -                                        {
 60.3270 -                                                writememw((ss+SP)-2,flags|0xF000);
 60.3271 -                                                writememw((ss+SP)-4,cs>>4);
 60.3272 -                                                writememw((ss+SP)-6,pc);
 60.3273 -                                                SP-=6;
 60.3274 -                                                flags&=~I_FLAG;
 60.3275 -                                                pc=readmemw(0);
 60.3276 -                                                cs=readmemw(2)<<4;
 60.3277 -                                                printf("Div by zero %04X:%04X\n",cs>>4,pc);
 60.3278 -//                                                dumpregs();
 60.3279 -//                                                exit(-1);
 60.3280 -                                        }
 60.3281 -                                        else
 60.3282 -                                        {*/
 60.3283 -                                                AH=tempw2;
 60.3284 -                                                tempw/=temp;
 60.3285 -                                                AL=tempw&0xFF;
 60.3286 -//                                        }
 60.3287 -                                }
 60.3288 -                                else
 60.3289 -                                {
 60.3290 -                                        printf("DIVb BY 0 %04X:%04X\n",cs>>4,pc);
 60.3291 -                                        writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
 60.3292 -                                        writememw(ss,(SP-4)&0xFFFF,CS);
 60.3293 -                                        writememw(ss,(SP-6)&0xFFFF,pc);
 60.3294 -                                        SP-=6;
 60.3295 -                                        flags&=~I_FLAG;
 60.3296 -                                        flags&=~T_FLAG;
 60.3297 -                                        pc=readmemw(0,0);
 60.3298 -//                        printf("F6 30\n");
 60.3299 -                                        loadcs(readmemw(0,2));
 60.3300 -                                        FETCHCLEAR();
 60.3301 -//                                                cs=loadcs(CS);
 60.3302 -//                                                cs=CS<<4;
 60.3303 -//                                        printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x30);
 60.3304 -//                                        dumpregs();
 60.3305 -//                                        exit(-1);
 60.3306 -                                }
 60.3307 -                                cycles-=80;
 60.3308 -                                break;
 60.3309 -                                case 0x38: /*IDIV AL,b*/
 60.3310 -                                tempws=(int)AX;
 60.3311 -                                if (temp)
 60.3312 -                                {
 60.3313 -                                        tempw2=tempws%(int)((int8_t)temp);
 60.3314 -/*                                        if (!tempw)
 60.3315 -                                        {
 60.3316 -                                                writememw((ss+SP)-2,flags|0xF000);
 60.3317 -                                                writememw((ss+SP)-4,cs>>4);
 60.3318 -                                                writememw((ss+SP)-6,pc);
 60.3319 -                                                SP-=6;
 60.3320 -                                                flags&=~I_FLAG;
 60.3321 -                                                pc=readmemw(0);
 60.3322 -                                                cs=readmemw(2)<<4;
 60.3323 -                                                printf("Div by zero %04X:%04X\n",cs>>4,pc);
 60.3324 -                                        }
 60.3325 -                                        else
 60.3326 -                                        {*/
 60.3327 -                                                AH=tempw2&0xFF;
 60.3328 -                                                tempws/=(int)((int8_t)temp);
 60.3329 -                                                AL=tempws&0xFF;
 60.3330 -//                                        }
 60.3331 -                                }
 60.3332 -                                else
 60.3333 -                                {
 60.3334 -                                        printf("IDIVb BY 0 %04X:%04X\n",cs>>4,pc);
 60.3335 -                                        writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
 60.3336 -                                        writememw(ss,(SP-4)&0xFFFF,CS);
 60.3337 -                                        writememw(ss,(SP-6)&0xFFFF,pc);
 60.3338 -                                        SP-=6;
 60.3339 -                                        flags&=~I_FLAG;
 60.3340 -                                        flags&=~T_FLAG;
 60.3341 -                                        pc=readmemw(0,0);
 60.3342 -//                        printf("F6 38\n");
 60.3343 -                                        loadcs(readmemw(0,2));
 60.3344 -                                        FETCHCLEAR();
 60.3345 -//                                                cs=loadcs(CS);
 60.3346 -//                                                cs=CS<<4;
 60.3347 -//                                        printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x38);
 60.3348 -                                }
 60.3349 -                                cycles-=101;
 60.3350 -                                break;
 60.3351 -
 60.3352 -//                                default:
 60.3353 -//                                printf("Bad F6 opcode %02X\n",rmdat&0x38);
 60.3354 -//                                dumpregs();
 60.3355 -//                                exit(-1);
 60.3356 -                        }
 60.3357 -                        break;
 60.3358 -
 60.3359 -                        case 0xF7:
 60.3360 -                        fetchea();
 60.3361 -                        tempw=geteaw();
 60.3362 -                        switch (rmdat&0x38)
 60.3363 -                        {
 60.3364 -                                case 0x00: /*TEST w*/
 60.3365 -                                tempw2=getword();
 60.3366 -                                setznp16(tempw&tempw2);
 60.3367 -                                flags&=~(C_FLAG|V_FLAG|A_FLAG);
 60.3368 -                                cycles-=((mod==3)?5:11);
 60.3369 -                                break;
 60.3370 -                                case 0x10: /*NOT w*/
 60.3371 -                                seteaw(~tempw);
 60.3372 -                                cycles-=((mod==3)?3:24);
 60.3373 -                                break;
 60.3374 -                                case 0x18: /*NEG w*/
 60.3375 -                                setsub16(0,tempw);
 60.3376 -                                tempw=0-tempw;
 60.3377 -                                seteaw(tempw);
 60.3378 -                                cycles-=((mod==3)?3:24);
 60.3379 -                                break;
 60.3380 -                                case 0x20: /*MUL AX,w*/
 60.3381 -                                setznp16(AX);
 60.3382 -                                templ=AX*tempw;
 60.3383 -//                                if (output) printf("%04X*%04X=%08X\n",AX,tempw,templ);
 60.3384 -                                AX=templ&0xFFFF;
 60.3385 -                                DX=templ>>16;
 60.3386 -                                if (AX|DX) flags&=~Z_FLAG;
 60.3387 -                                else       flags|=Z_FLAG;
 60.3388 -                                if (DX)    flags|=(C_FLAG|V_FLAG);
 60.3389 -                                else       flags&=~(C_FLAG|V_FLAG);
 60.3390 -                                cycles-=118;
 60.3391 -                                break;
 60.3392 -                                case 0x28: /*IMUL AX,w*/
 60.3393 -                                setznp16(AX);
 60.3394 -//                                printf("IMUL %i %i ",(int)((int16_t)AX),(int)((int16_t)tempw));
 60.3395 -                                tempws=(int)((int16_t)AX)*(int)((int16_t)tempw);
 60.3396 -                                if ((tempws>>15) && ((tempws>>15)!=-1)) flags|=(C_FLAG|V_FLAG);
 60.3397 -                                else                                    flags&=~(C_FLAG|V_FLAG);
 60.3398 -//                                printf("%i ",tempws);
 60.3399 -                                AX=tempws&0xFFFF;
 60.3400 -                                tempws=(uint16_t)(tempws>>16);
 60.3401 -                                DX=tempws&0xFFFF;
 60.3402 -//                                printf("%04X %04X\n",AX,DX);
 60.3403 -//                                dumpregs();
 60.3404 -//                                exit(-1);
 60.3405 -                                if (AX|DX) flags&=~Z_FLAG;
 60.3406 -                                else       flags|=Z_FLAG;
 60.3407 -                                cycles-=128;
 60.3408 -                                break;
 60.3409 -                                case 0x30: /*DIV AX,w*/
 60.3410 -                                templ=(DX<<16)|AX;
 60.3411 -//                                printf("DIV %08X/%04X\n",templ,tempw);
 60.3412 -                                if (tempw)
 60.3413 -                                {
 60.3414 -                                        tempw2=templ%tempw;
 60.3415 -                                        DX=tempw2;
 60.3416 -                                        templ/=tempw;
 60.3417 -                                        AX=templ&0xFFFF;
 60.3418 -                                }
 60.3419 -                                else
 60.3420 -                                {
 60.3421 -                                        printf("DIVw BY 0 %04X:%04X\n",cs>>4,pc);
 60.3422 -                                        writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
 60.3423 -                                        writememw(ss,(SP-4)&0xFFFF,CS);
 60.3424 -                                        writememw(ss,(SP-6)&0xFFFF,pc);
 60.3425 -                                        SP-=6;
 60.3426 -                                        flags&=~I_FLAG;
 60.3427 -                                        flags&=~T_FLAG;
 60.3428 -                                        pc=readmemw(0,0);
 60.3429 -//                        printf("F7 30\n");
 60.3430 -                                        loadcs(readmemw(0,2));
 60.3431 -                                        FETCHCLEAR();
 60.3432 -                                }
 60.3433 -                                cycles-=144;
 60.3434 -                                break;
 60.3435 -                                case 0x38: /*IDIV AX,w*/
 60.3436 -                                tempws=(int)((DX<<16)|AX);
 60.3437 -//                                printf("IDIV %i %i ",tempws,tempw);
 60.3438 -                                if (tempw)
 60.3439 -                                {
 60.3440 -                                        tempw2=tempws%(int)((int16_t)tempw);
 60.3441 -//                                        printf("%04X ",tempw2);
 60.3442 -                                                DX=tempw2;
 60.3443 -                                                tempws/=(int)((int16_t)tempw);
 60.3444 -                                                AX=tempws&0xFFFF;
 60.3445 -                                }
 60.3446 -                                else
 60.3447 -                                {
 60.3448 -                                        printf("IDIVw BY 0 %04X:%04X\n",cs>>4,pc);
 60.3449 -                                        writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
 60.3450 -                                        writememw(ss,(SP-4)&0xFFFF,CS);
 60.3451 -                                        writememw(ss,(SP-6)&0xFFFF,pc);
 60.3452 -                                        SP-=6;
 60.3453 -                                        flags&=~I_FLAG;
 60.3454 -                                        flags&=~T_FLAG;
 60.3455 -                                        pc=readmemw(0,0);
 60.3456 -//                        printf("F7 38\n");
 60.3457 -                                        loadcs(readmemw(0,2));
 60.3458 -                                        FETCHCLEAR();
 60.3459 -                                }
 60.3460 -                                cycles-=165;
 60.3461 -                                break;
 60.3462 -
 60.3463 -//                                default:
 60.3464 -//                                printf("Bad F7 opcode %02X\n",rmdat&0x38);
 60.3465 -//                                dumpregs();
 60.3466 -//                                exit(-1);
 60.3467 -                        }
 60.3468 -                        break;
 60.3469 -
 60.3470 -                        case 0xF8: /*CLC*/
 60.3471 -                        flags&=~C_FLAG;
 60.3472 -                        cycles-=2;
 60.3473 -                        break;
 60.3474 -                        case 0xF9: /*STC*/
 60.3475 -//                        printf("STC %04X\n",pc);
 60.3476 -                        flags|=C_FLAG;
 60.3477 -                        cycles-=2;
 60.3478 -                        break;
 60.3479 -                        case 0xFA: /*CLI*/
 60.3480 -                        flags&=~I_FLAG;
 60.3481 -//                        printf("CLI at %04X:%04X\n",cs>>4,pc);
 60.3482 -                        cycles-=3;
 60.3483 -                        break;
 60.3484 -                        case 0xFB: /*STI*/
 60.3485 -                        flags|=I_FLAG;
 60.3486 -//                        printf("STI at %04X:%04X\n",cs>>4,pc);
 60.3487 -                        cycles-=2;
 60.3488 -                        break;
 60.3489 -                        case 0xFC: /*CLD*/
 60.3490 -                        flags&=~D_FLAG;
 60.3491 -                        cycles-=2;
 60.3492 -                        break;
 60.3493 -                        case 0xFD: /*STD*/
 60.3494 -                        flags|=D_FLAG;
 60.3495 -                        cycles-=2;
 60.3496 -                        break;
 60.3497 -
 60.3498 -                        case 0xFE: /*INC/DEC b*/
 60.3499 -                        fetchea();
 60.3500 -                        temp=geteab();
 60.3501 -                        flags&=~V_FLAG;
 60.3502 -                        if (rmdat&0x38)
 60.3503 -                        {
 60.3504 -                                setsub8nc(temp,1);
 60.3505 -                                temp2=temp-1;
 60.3506 -                                if ((temp&0x80) && !(temp2&0x80)) flags|=V_FLAG;
 60.3507 -                        }
 60.3508 -                        else
 60.3509 -                        {
 60.3510 -                                setadd8nc(temp,1);
 60.3511 -                                temp2=temp+1;
 60.3512 -                                if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG;
 60.3513 -                        }
 60.3514 -//                        setznp8(temp2);
 60.3515 -                        seteab(temp2);
 60.3516 -                        cycles-=((mod==3)?3:23);
 60.3517 -                        break;
 60.3518 -
 60.3519 -                        case 0xFF:
 60.3520 -                        fetchea();
 60.3521 -                        switch (rmdat&0x38)
 60.3522 -                        {
 60.3523 -                                case 0x00: /*INC w*/
 60.3524 -                                tempw=geteaw();
 60.3525 -                                setadd16nc(tempw,1);
 60.3526 -//                                setznp16(tempw+1);
 60.3527 -                                seteaw(tempw+1);
 60.3528 -                                cycles-=((mod==3)?3:23);
 60.3529 -                                break;
 60.3530 -                                case 0x08: /*DEC w*/
 60.3531 -                                tempw=geteaw();
 60.3532 -//                                setsub16(tempw,1);
 60.3533 -                                setsub16nc(tempw,1);
 60.3534 -//                                setznp16(tempw-1);
 60.3535 -                                seteaw(tempw-1);
 60.3536 -//                                if (output) printf("DEC - %04X\n",tempw);
 60.3537 -                                cycles-=((mod==3)?3:23);
 60.3538 -                                break;
 60.3539 -                                case 0x10: /*CALL*/
 60.3540 -                                tempw=geteaw();
 60.3541 -                                if (ssegs) ss=oldss;
 60.3542 -                                writememw(ss,(SP-2)&0xFFFF,pc);
 60.3543 -                                SP-=2;
 60.3544 -                                pc=tempw;
 60.3545 -//                        printf("FF 10\n");
 60.3546 -                                cycles-=((mod==3)?20:29);
 60.3547 -                                FETCHCLEAR();
 60.3548 -                                break;
 60.3549 -                                case 0x18: /*CALL far*/
 60.3550 -                                tempw=readmemw(easeg,eaaddr);
 60.3551 -                                tempw2=readmemw(easeg,(eaaddr+2)&0xFFFF); //geteaw2();
 60.3552 -                                tempw3=CS;
 60.3553 -                                tempw4=pc;
 60.3554 -                                if (ssegs) ss=oldss;
 60.3555 -                                pc=tempw;
 60.3556 -//                        printf("FF 18\n");
 60.3557 -                                loadcs(tempw2);
 60.3558 -                                writememw(ss,(SP-2)&0xFFFF,tempw3);
 60.3559 -                                writememw(ss,((SP-4)&0xFFFF),tempw4);
 60.3560 -                                SP-=4;
 60.3561 -                                cycles-=53;
 60.3562 -                                FETCHCLEAR();
 60.3563 -                                break;
 60.3564 -                                case 0x20: /*JMP*/
 60.3565 -                                pc=geteaw();
 60.3566 -//                        printf("FF 20\n");
 60.3567 -                                cycles-=((mod==3)?11:18);
 60.3568 -                                FETCHCLEAR();
 60.3569 -                                break;
 60.3570 -                                case 0x28: /*JMP far*/
 60.3571 -                                pc=readmemw(easeg,eaaddr); //geteaw();
 60.3572 -//                        printf("FF 28\n");
 60.3573 -                                loadcs(readmemw(easeg,(eaaddr+2)&0xFFFF)); //geteaw2();
 60.3574 -//                                cs=loadcs(CS);
 60.3575 -//                                cs=CS<<4;
 60.3576 -                                cycles-=24;
 60.3577 -                                FETCHCLEAR();
 60.3578 -                                break;
 60.3579 -                                case 0x30: /*PUSH w*/
 60.3580 -                                tempw=geteaw();
 60.3581 -//                                if (output) printf("PUSH %04X %i %02X %04X %04X %02X %02X\n",tempw,rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]);
 60.3582 -                                if (ssegs) ss=oldss;
 60.3583 -                                writememw(ss,((SP-2)&0xFFFF),tempw);
 60.3584 -                                SP-=2;
 60.3585 -                                cycles-=((mod==3)?15:24);
 60.3586 -                                break;
 60.3587 -
 60.3588 -//                                default:
 60.3589 -//                                printf("Bad FF opcode %02X\n",rmdat&0x38);
 60.3590 -//                                dumpregs();
 60.3591 -//                                exit(-1);
 60.3592 -                        }
 60.3593 -                        break;
 60.3594 -
 60.3595 -                        default:
 60.3596 -                        FETCH();
 60.3597 -                        cycles-=8;
 60.3598 -                        break;
 60.3599 -
 60.3600 -/*                        printf("Bad opcode %02X at %04X:%04X from %04X:%04X %08X\n",opcode,cs>>4,pc,old8>>16,old8&0xFFFF,old82);
 60.3601 -                        dumpregs();
 60.3602 -                        exit(-1);*/
 60.3603 -                }
 60.3604 -                pc&=0xFFFF;
 60.3605 -
 60.3606 -/*                if ((CS & 0xf000) == 0xa000)
 60.3607 -                {
 60.3608 -                        dumpregs();
 60.3609 -                        exit(-1);
 60.3610 -                }*/
 60.3611 -//                output = 3;
 60.3612 -/*                if (CS == 0xf000)
 60.3613 -                {
 60.3614 -                        dumpregs();
 60.3615 -                        exit(-1);
 60.3616 -                }
 60.3617 -                output = 3;*/
 60.3618 -                if (ssegs)
 60.3619 -                {
 60.3620 -                        ds=oldds;
 60.3621 -                        ss=oldss;
 60.3622 -                        ssegs=0;
 60.3623 -                }
 60.3624 -                
 60.3625 -//                output = 3;
 60.3626 -               // if (instime) printf("%i %i %i %i\n",cycdiff,cycles,memcycs,fetchclocks);
 60.3627 -                FETCHADD(((cycdiff-cycles)-memcycs)-fetchclocks);
 60.3628 -                if ((cycdiff-cycles)<memcycs) cycles-=(memcycs-(cycdiff-cycles));
 60.3629 -                if (romset==ROM_IBMPC)
 60.3630 -                {
 60.3631 -                        if ((cs+pc)==0xFE4A7) /*You didn't seriously think I was going to emulate the cassette, did you?*/
 60.3632 -                        {
 60.3633 -                                CX=1;
 60.3634 -                                BX=0x500;
 60.3635 -                        }
 60.3636 -                }
 60.3637 -                memcycs=0;
 60.3638 -
 60.3639 -                insc++;
 60.3640 -//                output=(CS==0xEB9);
 60.3641 -                clockhardware();
 60.3642 -
 60.3643 -
 60.3644 -                if (trap && (flags&T_FLAG) && !noint)
 60.3645 -                {
 60.3646 -//                        printf("TRAP!!! %04X:%04X\n",CS,pc);
 60.3647 -                        writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
 60.3648 -                        writememw(ss,(SP-4)&0xFFFF,CS);
 60.3649 -                        writememw(ss,(SP-6)&0xFFFF,pc);
 60.3650 -                        SP-=6;
 60.3651 -                        addr=1<<2;
 60.3652 -                        flags&=~I_FLAG;
 60.3653 -                        flags&=~T_FLAG;
 60.3654 -                        pc=readmemw(0,addr);
 60.3655 -                        loadcs(readmemw(0,addr+2));
 60.3656 -                        FETCHCLEAR();
 60.3657 -                }
 60.3658 -                else if ((flags&I_FLAG) && (pic.pend&~pic.mask) && !ssegs && !noint)
 60.3659 -                {
 60.3660 -                        temp=picinterrupt();
 60.3661 -                        if (temp!=0xFF)
 60.3662 -                        {
 60.3663 -                                if (inhlt) pc++;
 60.3664 -                                writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
 60.3665 -                                writememw(ss,(SP-4)&0xFFFF,CS);
 60.3666 -                                writememw(ss,(SP-6)&0xFFFF,pc);
 60.3667 -                                SP-=6;
 60.3668 -                                addr=temp<<2;
 60.3669 -                                flags&=~I_FLAG;
 60.3670 -                                flags&=~T_FLAG;
 60.3671 -                                pc=readmemw(0,addr);
 60.3672 -//                        printf("INT INT INT\n");
 60.3673 -                                loadcs(readmemw(0,addr+2));
 60.3674 -                                FETCHCLEAR();
 60.3675 -                                inint=1;
 60.3676 -//                                printf("INTERRUPT\n");
 60.3677 -                        }
 60.3678 -                }
 60.3679 -
 60.3680 -                if (noint) noint=0;
 60.3681 -                ins++;
 60.3682 -/*                if (timetolive)
 60.3683 -                {
 60.3684 -                        timetolive--;
 60.3685 -                        if (!timetolive) exit(-1); //output=0;
 60.3686 -                }*/
 60.3687 -        }
 60.3688 -}
 60.3689 -
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/src/x86_ops.h	Mon May 27 19:56:33 2013 +0100
    61.3 @@ -0,0 +1,12 @@
    61.4 +typedef int (*OpFn)(uint32_t fetchdat);
    61.5 +
    61.6 +void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f);
    61.7 +
    61.8 +extern OpFn *x86_opcodes;
    61.9 +extern OpFn *x86_opcodes_0f;
   61.10 +
   61.11 +extern OpFn ops_286[1024];
   61.12 +extern OpFn ops_286_0f[1024];
   61.13 +
   61.14 +extern OpFn ops_386[1024];
   61.15 +extern OpFn ops_386_0f[1024];
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/src/x86_ops_arith.h	Mon May 27 19:56:33 2013 +0100
    62.3 @@ -0,0 +1,645 @@
    62.4 +#define OP_ARITH(name, operation, setflags, flagops)   \
    62.5 +        static int op ## name ## _b_rmw_a16(uint32_t fetchdat)                                         \
    62.6 +        {                                                                                       \
    62.7 +                int tempc = CF_SET();                                                           \
    62.8 +                fetch_ea_16(fetchdat);                                                          \
    62.9 +                if (mod == 3)                                                                   \
   62.10 +                {                                                                               \
   62.11 +                        uint8_t dst = getr8(rm);                                                \
   62.12 +                        uint8_t src = getr8(reg);                                               \
   62.13 +                        setflags ## 8 flagops;                                                  \
   62.14 +                        setr8(rm, operation);                                                   \
   62.15 +                        cycles -= timing_rr;                                                    \
   62.16 +                }                                                                               \
   62.17 +                else                                                                            \
   62.18 +                {                                                                               \
   62.19 +                        uint8_t dst = geteab();                         if (abrt) return 0;     \
   62.20 +                        uint8_t src = getr8(reg);                                               \
   62.21 +                        seteab(operation);                              if (abrt) return 0;     \
   62.22 +                        setflags ## 8 flagops;                                                  \
   62.23 +                        cycles -= timing_mr;                                                    \
   62.24 +                }                                                                               \
   62.25 +                return 0;                                                                       \
   62.26 +        }                                                                                       \
   62.27 +        static int op ## name ## _b_rmw_a32(uint32_t fetchdat)                                         \
   62.28 +        {                                                                                       \
   62.29 +                int tempc = CF_SET();                                                           \
   62.30 +                fetch_ea_32(fetchdat);                                                          \
   62.31 +                if (mod == 3)                                                                   \
   62.32 +                {                                                                               \
   62.33 +                        uint8_t dst = getr8(rm);                                                \
   62.34 +                        uint8_t src = getr8(reg);                                               \
   62.35 +                        setflags ## 8 flagops;                                                  \
   62.36 +                        setr8(rm, operation);                                                   \
   62.37 +                        cycles -= timing_rr;                                                    \
   62.38 +                }                                                                               \
   62.39 +                else                                                                            \
   62.40 +                {                                                                               \
   62.41 +                        uint8_t dst = geteab();                         if (abrt) return 0;     \
   62.42 +                        uint8_t src = getr8(reg);                                               \
   62.43 +                        seteab(operation);                              if (abrt) return 0;     \
   62.44 +                        setflags ## 8 flagops;                                                  \
   62.45 +                        cycles -= timing_mr;                                                    \
   62.46 +                }                                                                               \
   62.47 +                return 0;                                                                       \
   62.48 +        }                                                                                       \
   62.49 +                                                                                                \
   62.50 +        static int op ## name ## _w_rmw_a16(uint32_t fetchdat)                                         \
   62.51 +        {                                                                                       \
   62.52 +                int tempc = CF_SET();                                                           \
   62.53 +                fetch_ea_16(fetchdat);                                                          \
   62.54 +                if (mod == 3)                                                                   \
   62.55 +                {                                                                               \
   62.56 +                        uint16_t dst = regs[rm].w;                                              \
   62.57 +                        uint16_t src = regs[reg].w;                                             \
   62.58 +                        setflags ## 16 flagops;                                                 \
   62.59 +                        regs[rm].w = operation;                                                 \
   62.60 +                        cycles -= timing_rr;                                                    \
   62.61 +                }                                                                               \
   62.62 +                else                                                                            \
   62.63 +                {                                                                               \
   62.64 +                        uint16_t dst = geteaw();                        if (abrt) return 0;     \
   62.65 +                        uint16_t src = regs[reg].w;                                             \
   62.66 +                        seteaw(operation);                              if (abrt) return 0;     \
   62.67 +                        setflags ## 16 flagops;                                                 \
   62.68 +                        cycles -= timing_mr;                                                    \
   62.69 +                }                                                                               \
   62.70 +                return 0;                                                                       \
   62.71 +        }                                                                                       \
   62.72 +        static int op ## name ## _w_rmw_a32(uint32_t fetchdat)                                         \
   62.73 +        {                                                                                       \
   62.74 +                int tempc = CF_SET();                                                           \
   62.75 +                fetch_ea_32(fetchdat);                                                          \
   62.76 +                if (mod == 3)                                                                   \
   62.77 +                {                                                                               \
   62.78 +                        uint16_t dst = regs[rm].w;                                              \
   62.79 +                        uint16_t src = regs[reg].w;                                             \
   62.80 +                        setflags ## 16 flagops;                                                 \
   62.81 +                        regs[rm].w = operation;                                                 \
   62.82 +                        cycles -= timing_rr;                                                    \
   62.83 +                }                                                                               \
   62.84 +                else                                                                            \
   62.85 +                {                                                                               \
   62.86 +                        uint16_t dst = geteaw();                        if (abrt) return 0;     \
   62.87 +                        uint16_t src = regs[reg].w;                                             \
   62.88 +                        seteaw(operation);                              if (abrt) return 0;     \
   62.89 +                        setflags ## 16 flagops;                                                 \
   62.90 +                        cycles -= timing_mr;                                                    \
   62.91 +                }                                                                               \
   62.92 +                return 0;                                                                       \
   62.93 +        }                                                                                       \
   62.94 +                                                                                                \
   62.95 +        static int op ## name ## _l_rmw_a16(uint32_t fetchdat)                                         \
   62.96 +        {                                                                                       \
   62.97 +                int tempc = CF_SET();                                                           \
   62.98 +                fetch_ea_16(fetchdat);                                                          \
   62.99 +                if (mod == 3)                                                                   \
  62.100 +                {                                                                               \
  62.101 +                        uint32_t dst = regs[rm].l;                                              \
  62.102 +                        uint32_t src = regs[reg].l;                                             \
  62.103 +                        setflags ## 32 flagops;                                                 \
  62.104 +                        regs[rm].l = operation;                                                 \
  62.105 +                        cycles -= timing_rr;                                                    \
  62.106 +                }                                                                               \
  62.107 +                else                                                                            \
  62.108 +                {                                                                               \
  62.109 +                        uint32_t dst = geteal();                        if (abrt) return 0;     \
  62.110 +                        uint32_t src = regs[reg].l;                                             \
  62.111 +                        seteal(operation);                              if (abrt) return 0;     \
  62.112 +                        setflags ## 32 flagops;                                                 \
  62.113 +                        cycles -= timing_mrl;                                                   \
  62.114 +                }                                                                               \
  62.115 +                return 0;                                                                       \
  62.116 +        }                                                                                       \
  62.117 +        static int op ## name ## _l_rmw_a32(uint32_t fetchdat)                                         \
  62.118 +        {                                                                                       \
  62.119 +                int tempc = CF_SET();                                                           \
  62.120 +                fetch_ea_32(fetchdat);                                                          \
  62.121 +                if (mod == 3)                                                                   \
  62.122 +                {                                                                               \
  62.123 +                        uint32_t dst = regs[rm].l;                                              \
  62.124 +                        uint32_t src = regs[reg].l;                                             \
  62.125 +                        setflags ## 32 flagops;                                                 \
  62.126 +                        regs[rm].l = operation;                                                 \
  62.127 +                        cycles -= timing_rr;                                                    \
  62.128 +                }                                                                               \
  62.129 +                else                                                                            \
  62.130 +                {                                                                               \
  62.131 +                        uint32_t dst = geteal();                        if (abrt) return 0;     \
  62.132 +                        uint32_t src = regs[reg].l;                                             \
  62.133 +                        seteal(operation);                              if (abrt) return 0;     \
  62.134 +                        setflags ## 32 flagops;                                                 \
  62.135 +                        cycles -= timing_mrl;                                                   \
  62.136 +                }                                                                               \
  62.137 +                return 0;                                                                       \
  62.138 +        }                                                                                       \
  62.139 +                                                                                                \
  62.140 +        static int op ## name ## _b_rm_a16(uint32_t fetchdat)                                          \
  62.141 +        {                                                                                       \
  62.142 +                int tempc = CF_SET();                                                           \
  62.143 +                uint8_t dst, src;                                                               \
  62.144 +                fetch_ea_16(fetchdat);                                                          \
  62.145 +                dst = getr8(reg);                                                               \
  62.146 +                src = geteab();                                         if (abrt) return 0;     \
  62.147 +                setflags ## 8 flagops;                                                          \
  62.148 +                setr8(reg, operation);                                                          \
  62.149 +                cycles -= (mod == 3) ? timing_rr : timing_rm;                                   \
  62.150 +                return 0;                                                                       \
  62.151 +        }                                                                                       \
  62.152 +        static int op ## name ## _b_rm_a32(uint32_t fetchdat)                                          \
  62.153 +        {                                                                                       \
  62.154 +                int tempc = CF_SET();                                                           \
  62.155 +                uint8_t dst, src;                                                               \
  62.156 +                fetch_ea_32(fetchdat);                                                          \
  62.157 +                dst = getr8(reg);                                                               \
  62.158 +                src = geteab();                                         if (abrt) return 0;     \
  62.159 +                setflags ## 8 flagops;                                                          \
  62.160 +                setr8(reg, operation);                                                          \
  62.161 +                cycles -= (mod == 3) ? timing_rr : timing_rm;                                   \
  62.162 +                return 0;                                                                       \
  62.163 +        }                                                                                       \
  62.164 +                                                                                                \
  62.165 +        static int op ## name ## _w_rm_a16(uint32_t fetchdat)                                          \
  62.166 +        {                                                                                       \
  62.167 +                int tempc = CF_SET();                                                           \
  62.168 +                uint16_t dst, src;                                                              \
  62.169 +                fetch_ea_16(fetchdat);                                                          \
  62.170 +                dst = regs[reg].w;                                                              \
  62.171 +                src = geteaw();                                 if (abrt) return 0;             \
  62.172 +                setflags ## 16 flagops;                                                         \
  62.173 +                regs[reg].w = operation;                                                        \
  62.174 +                cycles -= (mod == 3) ? timing_rr : timing_rm;                                   \
  62.175 +                return 0;                                                                       \
  62.176 +        }                                                                                       \
  62.177 +        static int op ## name ## _w_rm_a32(uint32_t fetchdat)                                          \
  62.178 +        {                                                                                       \
  62.179 +                int tempc = CF_SET();                                                           \
  62.180 +                uint16_t dst, src;                                                              \
  62.181 +                fetch_ea_32(fetchdat);                                                          \
  62.182 +                dst = regs[reg].w;                                                              \
  62.183 +                src = geteaw();                                 if (abrt) return 0;             \
  62.184 +                setflags ## 16 flagops;                                                         \
  62.185 +                regs[reg].w = operation;                                                        \
  62.186 +                cycles -= (mod == 3) ? timing_rr : timing_rm;                                   \
  62.187 +                return 0;                                                                       \
  62.188 +        }                                                                                       \
  62.189 +                                                                                                \
  62.190 +        static int op ## name ## _l_rm_a16(uint32_t fetchdat)                                          \
  62.191 +        {                                                                                       \
  62.192 +                int tempc = CF_SET();                                                           \
  62.193 +                uint32_t dst, src;                                                              \
  62.194 +                fetch_ea_16(fetchdat);                                                          \
  62.195 +                dst = regs[reg].l;                                                              \
  62.196 +                src = geteal();                                 if (abrt) return 0;             \
  62.197 +                setflags ## 32 flagops;                                                         \
  62.198 +                regs[reg].l = operation;                                                        \
  62.199 +                cycles -= (mod == 3) ? timing_rr : timing_rml;                                  \
  62.200 +                return 0;                                                                       \
  62.201 +        }                                                                                       \
  62.202 +        static int op ## name ## _l_rm_a32(uint32_t fetchdat)                                          \
  62.203 +        {                                                                                       \
  62.204 +                int tempc = CF_SET();                                                           \
  62.205 +                uint32_t dst, src;                                                              \
  62.206 +                fetch_ea_32(fetchdat);                                                          \
  62.207 +                dst = regs[reg].l;                                                              \
  62.208 +                src = geteal();                                 if (abrt) return 0;             \
  62.209 +                setflags ## 32 flagops;                                                         \
  62.210 +                regs[reg].l = operation;                                                        \
  62.211 +                cycles -= (mod == 3) ? timing_rr : timing_rml;                                  \
  62.212 +                return 0;                                                                       \
  62.213 +        }                                                                                       \
  62.214 +                                                                                                \
  62.215 +        static int op ## name ## _AL_imm(uint32_t fetchdat)                                            \
  62.216 +        {                                                                                       \
  62.217 +                int tempc = CF_SET();                                                           \
  62.218 +                uint8_t dst = AL;                                                               \
  62.219 +                uint8_t src = getbytef();                                                       \
  62.220 +                setflags ## 8 flagops;                                                          \
  62.221 +                AL = operation;                                                                 \
  62.222 +                cycles -= timing_rr;                                                            \
  62.223 +                return 0;                                                                       \
  62.224 +        }                                                                                       \
  62.225 +                                                                                                \
  62.226 +        static int op ## name ## _AX_imm(uint32_t fetchdat)                                            \
  62.227 +        {                                                                                       \
  62.228 +                int tempc = CF_SET();                                                           \
  62.229 +                uint16_t dst = AX;                                                              \
  62.230 +                uint16_t src = getwordf();                                                      \
  62.231 +                setflags ## 16 flagops;                                                         \
  62.232 +                AX = operation;                                                                 \
  62.233 +                cycles -= timing_rr;                                                            \
  62.234 +                return 0;                                                                       \
  62.235 +        }                                                                                       \
  62.236 +                                                                                                \
  62.237 +        static int op ## name ## _EAX_imm(uint32_t fetchdat)                                           \
  62.238 +        {                                                                                       \
  62.239 +                int tempc = CF_SET();                                                           \
  62.240 +                uint32_t dst = EAX;                                                             \
  62.241 +                uint32_t src = getlong();                                                       \
  62.242 +                setflags ## 32 flagops;                                                         \
  62.243 +                EAX = operation;                                                                \
  62.244 +                cycles -= timing_rr;                                                            \
  62.245 +                return 0;                                                                       \
  62.246 +        }
  62.247 +
  62.248 +OP_ARITH(ADD, dst + src,           setadd, (dst, src))
  62.249 +OP_ARITH(ADC, dst + src + tempc,   setadc, (dst, src))
  62.250 +OP_ARITH(SUB, dst - src,           setsub, (dst, src))
  62.251 +OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src))
  62.252 +OP_ARITH(OR,  dst | src,           setznp, (dst | src))
  62.253 +OP_ARITH(AND, dst & src,           setznp, (dst & src))
  62.254 +OP_ARITH(XOR, dst ^ src,           setznp, (dst ^ src))
  62.255 +
  62.256 +static int opCMP_b_rmw_a16(uint32_t fetchdat)
  62.257 +{
  62.258 +        uint8_t dst;
  62.259 +        fetch_ea_16(fetchdat);
  62.260 +        dst = geteab();                                         if (abrt) return 0;
  62.261 +        setsub8(dst, getr8(reg));
  62.262 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.263 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.264 +        return 0;
  62.265 +}
  62.266 +static int opCMP_b_rmw_a32(uint32_t fetchdat)                                         
  62.267 +{                                                                                       
  62.268 +        uint8_t dst;
  62.269 +        fetch_ea_32(fetchdat);
  62.270 +        dst = geteab();                                         if (abrt) return 0;
  62.271 +        setsub8(dst, getr8(reg));
  62.272 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.273 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.274 +        return 0;
  62.275 +}                                                                                       
  62.276 +                                                                                                
  62.277 +static int opCMP_w_rmw_a16(uint32_t fetchdat)                                         
  62.278 +{                                                                                       
  62.279 +        uint16_t dst;
  62.280 +        fetch_ea_16(fetchdat);
  62.281 +        dst = geteaw();                                         if (abrt) return 0;
  62.282 +        setsub16(dst, regs[reg].w);
  62.283 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.284 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.285 +        return 0;
  62.286 +}                                                                                       
  62.287 +static int opCMP_w_rmw_a32(uint32_t fetchdat)                                         
  62.288 +{                                                                                       
  62.289 +        uint16_t dst;
  62.290 +        fetch_ea_32(fetchdat);
  62.291 +        dst = geteaw();                                         if (abrt) return 0;
  62.292 +        setsub16(dst, regs[reg].w);
  62.293 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.294 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.295 +        return 0;
  62.296 +}                                                                                       
  62.297 +                                                                                                
  62.298 +static int opCMP_l_rmw_a16(uint32_t fetchdat)                                         
  62.299 +{                                                                                       
  62.300 +        uint32_t dst;
  62.301 +        fetch_ea_16(fetchdat);
  62.302 +        dst = geteal();                                         if (abrt) return 0;
  62.303 +        setsub32(dst, regs[reg].l);
  62.304 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.305 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.306 +        return 0;
  62.307 +}                                                                                       
  62.308 +static int opCMP_l_rmw_a32(uint32_t fetchdat)                                         
  62.309 +{                                                                                       
  62.310 +        uint32_t dst;
  62.311 +        fetch_ea_32(fetchdat);
  62.312 +        dst = geteal();                                         if (abrt) return 0;
  62.313 +        setsub32(dst, regs[reg].l);
  62.314 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.315 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.316 +        return 0;
  62.317 +}                                                                                       
  62.318 +                                                                                                
  62.319 +static int opCMP_b_rm_a16(uint32_t fetchdat)                                          
  62.320 +{                                                                                       
  62.321 +        uint8_t src;                                                               
  62.322 +        fetch_ea_16(fetchdat);                                                          
  62.323 +        src = geteab();                                         if (abrt) return 0;     
  62.324 +        setsub8(getr8(reg), src);
  62.325 +        cycles -= (mod == 3) ? timing_rr : timing_rm;                                   
  62.326 +        return 0;                                                                       
  62.327 +}                                                                                       
  62.328 +static int opCMP_b_rm_a32(uint32_t fetchdat)                                          
  62.329 +{                                                                                       
  62.330 +        uint8_t src;                                                               
  62.331 +        fetch_ea_32(fetchdat);                                                          
  62.332 +        src = geteab();                                         if (abrt) return 0;     
  62.333 +        setsub8(getr8(reg), src);
  62.334 +        cycles -= (mod == 3) ? timing_rr : timing_rm;                                   
  62.335 +        return 0;                                                                       
  62.336 +}                                                                                       
  62.337 +                                                                                                
  62.338 +static int opCMP_w_rm_a16(uint32_t fetchdat)                                          
  62.339 +{                                                                                       
  62.340 +        uint16_t src;                                                              
  62.341 +        fetch_ea_16(fetchdat);                                                          
  62.342 +        src = geteaw();                                 if (abrt) return 0;             
  62.343 +        setsub16(regs[reg].w, src);
  62.344 +        cycles -= (mod == 3) ? timing_rr : timing_rm;                                   
  62.345 +        return 0;                                                                       
  62.346 +}                                                                                       
  62.347 +static int opCMP_w_rm_a32(uint32_t fetchdat)                                          
  62.348 +{                                                                                       
  62.349 +        uint16_t src;                                                              
  62.350 +        fetch_ea_32(fetchdat);                                                          
  62.351 +        src = geteaw();                                 if (abrt) return 0;             
  62.352 +        setsub16(regs[reg].w, src);
  62.353 +        cycles -= (mod == 3) ? timing_rr : timing_rm;
  62.354 +        return 0;                                                                       
  62.355 +}                                                                                       
  62.356 +                                                                                                
  62.357 +static int opCMP_l_rm_a16(uint32_t fetchdat)                                          
  62.358 +{                                                                                       
  62.359 +        uint32_t src;                                                              
  62.360 +        fetch_ea_16(fetchdat);                                                          
  62.361 +        src = geteal();                                 if (abrt) return 0;             
  62.362 +        setsub32(regs[reg].l, src);
  62.363 +        cycles -= (mod == 3) ? timing_rr : timing_rml;
  62.364 +        return 0;                                                                       
  62.365 +}                                                                                       
  62.366 +static int opCMP_l_rm_a32(uint32_t fetchdat)                                          
  62.367 +{                                                                                       
  62.368 +        uint32_t src;
  62.369 +        fetch_ea_32(fetchdat);                                                          
  62.370 +        src = geteal();                                 if (abrt) return 0;             
  62.371 +        setsub32(regs[reg].l, src);
  62.372 +        cycles -= (mod == 3) ? timing_rr : timing_rml;
  62.373 +        return 0;                                                                       
  62.374 +}                                                                                       
  62.375 +                                                                                                
  62.376 +static int opCMP_AL_imm(uint32_t fetchdat)                                            
  62.377 +{                                                                                       
  62.378 +        uint8_t src = getbytef();                                                       
  62.379 +        setsub8(AL, src);
  62.380 +        cycles -= timing_rr;                                                            
  62.381 +        return 0;                                                                       
  62.382 +}                                                                                       
  62.383 +                                                                                                
  62.384 +static int opCMP_AX_imm(uint32_t fetchdat)                                            
  62.385 +{                                                                                       
  62.386 +        uint16_t src = getwordf();                                                      
  62.387 +        setsub16(AX, src);
  62.388 +        cycles -= timing_rr;                                                            
  62.389 +        return 0;                                                                       
  62.390 +}                                                                                       
  62.391 +                                                                                                
  62.392 +static int opCMP_EAX_imm(uint32_t fetchdat)                                           
  62.393 +{                                                                                       
  62.394 +        uint32_t src = getlong();                                                       
  62.395 +        setsub32(EAX, src);
  62.396 +        cycles -= timing_rr;                                                            
  62.397 +        return 0;                                                                       
  62.398 +}
  62.399 +
  62.400 +static int opTEST_b_a16(uint32_t fetchdat)
  62.401 +{
  62.402 +        uint8_t temp, temp2;
  62.403 +        fetch_ea_16(fetchdat);
  62.404 +        temp = geteab();                                if (abrt) return 0;
  62.405 +        temp2 = getr8(reg);
  62.406 +        setznp8(temp & temp2);
  62.407 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.408 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.409 +        return 0;
  62.410 +}
  62.411 +static int opTEST_b_a32(uint32_t fetchdat)
  62.412 +{
  62.413 +        uint8_t temp, temp2;
  62.414 +        fetch_ea_32(fetchdat);
  62.415 +        temp = geteab();                                if (abrt) return 0;
  62.416 +        temp2 = getr8(reg);
  62.417 +        setznp8(temp & temp2);
  62.418 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.419 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.420 +        return 0;
  62.421 +}
  62.422 +
  62.423 +static int opTEST_w_a16(uint32_t fetchdat)
  62.424 +{
  62.425 +        uint16_t temp, temp2;
  62.426 +        fetch_ea_16(fetchdat);
  62.427 +        temp = geteaw();                                if (abrt) return 0;
  62.428 +        temp2 = regs[reg].w;
  62.429 +        setznp16(temp & temp2);
  62.430 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.431 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.432 +        return 0;
  62.433 +}
  62.434 +static int opTEST_w_a32(uint32_t fetchdat)
  62.435 +{
  62.436 +        uint16_t temp, temp2;
  62.437 +        fetch_ea_32(fetchdat);
  62.438 +        temp = geteaw();                                if (abrt) return 0;
  62.439 +        temp2 = regs[reg].w;
  62.440 +        setznp16(temp & temp2);
  62.441 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.442 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.443 +        return 0;
  62.444 +}
  62.445 +
  62.446 +static int opTEST_l_a16(uint32_t fetchdat)
  62.447 +{
  62.448 +        uint32_t temp, temp2;
  62.449 +        fetch_ea_16(fetchdat);
  62.450 +        temp = geteal();                                if (abrt) return 0;
  62.451 +        temp2 = regs[reg].l;
  62.452 +        setznp32(temp & temp2);
  62.453 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.454 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.455 +        return 0;
  62.456 +}
  62.457 +static int opTEST_l_a32(uint32_t fetchdat)
  62.458 +{
  62.459 +        uint32_t temp, temp2;
  62.460 +        fetch_ea_32(fetchdat);
  62.461 +        temp = geteal();                                if (abrt) return 0;
  62.462 +        temp2 = regs[reg].l;
  62.463 +        setznp32(temp & temp2);
  62.464 +        if (is486) cycles -= ((mod == 3) ? 1 : 2);
  62.465 +        else       cycles -= ((mod == 3) ? 2 : 5);
  62.466 +        return 0;
  62.467 +}
  62.468 +
  62.469 +static int opTEST_AL(uint32_t fetchdat)
  62.470 +{
  62.471 +        uint8_t temp = getbytef();
  62.472 +        setznp8(AL & temp);
  62.473 +        cycles -= timing_rr;
  62.474 +        return 0;
  62.475 +}
  62.476 +static int opTEST_AX(uint32_t fetchdat)
  62.477 +{
  62.478 +        uint16_t temp = getwordf();
  62.479 +        setznp16(AX & temp);
  62.480 +        cycles -= timing_rr;
  62.481 +        return 0;
  62.482 +}
  62.483 +static int opTEST_EAX(uint32_t fetchdat)
  62.484 +{
  62.485 +        uint32_t temp = getlong();                      if (abrt) return 0;
  62.486 +        setznp32(EAX & temp);
  62.487 +        cycles -= timing_rr;
  62.488 +        return 0;
  62.489 +}
  62.490 +
  62.491 +
  62.492 +#define ARITH_MULTI(ea_width, flag_width)                                       \
  62.493 +        dst = getea ## ea_width();                      if (abrt) return 0;     \
  62.494 +        switch (rmdat&0x38)                                                     \
  62.495 +        {                                                                       \
  62.496 +                case 0x00: /*ADD ea, #*/                                        \
  62.497 +                setea ## ea_width(dst + src);           if (abrt) return 0;     \
  62.498 +                setadd ## flag_width(dst, src);                                 \
  62.499 +                cycles -= (mod == 3) ? timing_rr : timing_mr;                   \
  62.500 +                break;                                                          \
  62.501 +                case 0x08: /*OR ea, #*/                                         \
  62.502 +                dst |= src;                                                     \
  62.503 +                setea ## ea_width(dst);                 if (abrt) return 0;     \
  62.504 +                setznp ## flag_width(dst);                                      \
  62.505 +                cycles -= (mod == 3) ? timing_rr : timing_mr;                   \
  62.506 +                break;                                                          \
  62.507 +                case 0x10: /*ADC ea, #*/                                        \
  62.508 +                setea ## ea_width(dst + src + tempc);   if (abrt) return 0;     \
  62.509 +                setadc ## flag_width(dst, src);                                 \
  62.510 +                cycles -= (mod == 3) ? timing_rr : timing_mr;                   \
  62.511 +                break;                                                          \
  62.512 +                case 0x18: /*SBB ea, #*/                                        \
  62.513 +                setea ## ea_width(dst - (src + tempc)); if (abrt) return 0;     \
  62.514 +                setsbc ## flag_width(dst, src);                                 \
  62.515 +                cycles -= (mod == 3) ? timing_rr : timing_mr;                   \
  62.516 +                break;                                                          \
  62.517 +                case 0x20: /*AND ea, #*/                                        \
  62.518 +                dst &= src;                                                     \
  62.519 +                setea ## ea_width(dst);                 if (abrt) return 0;     \
  62.520 +                setznp ## flag_width(dst);                                      \
  62.521 +                cycles -= (mod == 3) ? timing_rr : timing_mr;                   \
  62.522 +                break;                                                          \
  62.523 +                case 0x28: /*SUB ea, #*/                                        \
  62.524 +                setea ## ea_width(dst - src);           if (abrt) return 0;     \
  62.525 +                setsub ## flag_width(dst, src);                                 \
  62.526 +                cycles -= (mod == 3) ? timing_rr : timing_mr;                   \
  62.527 +                break;                                                          \
  62.528 +                case 0x30: /*XOR ea, #*/                                        \
  62.529 +                dst ^= src;                                                     \
  62.530 +                setea ## ea_width(dst);                 if (abrt) return 0;     \
  62.531 +                setznp ## flag_width(dst);                                      \
  62.532 +                cycles -= (mod == 3) ? timing_rr : timing_mr;                   \
  62.533 +                break;                                                          \
  62.534 +                case 0x38: /*CMP ea, #*/                                        \
  62.535 +                setsub ## flag_width(dst, src);                                 \
  62.536 +                if (is486) cycles -= ((mod == 3) ? 1 : 2);                      \
  62.537 +                else       cycles -= ((mod == 3) ? 2 : 7);                      \
  62.538 +                break;                                                          \
  62.539 +        }
  62.540 +
  62.541 +
  62.542 +static int op80_a16(uint32_t fetchdat)
  62.543 +{
  62.544 +        uint8_t src, dst;
  62.545 +        
  62.546 +        fetch_ea_16(fetchdat);
  62.547 +        src = getbyte();                        if (abrt) return 0;
  62.548 +        ARITH_MULTI(b, 8);
  62.549 +        
  62.550 +        return 0;
  62.551 +}
  62.552 +static int op80_a32(uint32_t fetchdat)
  62.553 +{
  62.554 +        uint8_t src, dst;
  62.555 +        
  62.556 +        fetch_ea_32(fetchdat);
  62.557 +        src = getbyte();                        if (abrt) return 0;
  62.558 +        ARITH_MULTI(b, 8);
  62.559 +        
  62.560 +        return 0;
  62.561 +}
  62.562 +static int op81_w_a16(uint32_t fetchdat)
  62.563 +{
  62.564 +        uint16_t src, dst;
  62.565 +        
  62.566 +        fetch_ea_16(fetchdat);
  62.567 +        src = getword();                        if (abrt) return 0;
  62.568 +        ARITH_MULTI(w, 16);
  62.569 +        
  62.570 +        return 0;
  62.571 +}
  62.572 +static int op81_w_a32(uint32_t fetchdat)
  62.573 +{
  62.574 +        uint16_t src, dst;
  62.575 +        
  62.576 +        fetch_ea_32(fetchdat);
  62.577 +        src = getword();                        if (abrt) return 0;
  62.578 +        ARITH_MULTI(w, 16);
  62.579 +        
  62.580 +        return 0;
  62.581 +}
  62.582 +static int op81_l_a16(uint32_t fetchdat)
  62.583 +{
  62.584 +        uint32_t src, dst;
  62.585 +        
  62.586 +        fetch_ea_16(fetchdat);
  62.587 +        src = getlong();                        if (abrt) return 0;
  62.588 +        ARITH_MULTI(l, 32);
  62.589 +        
  62.590 +        return 0;
  62.591 +}
  62.592 +static int op81_l_a32(uint32_t fetchdat)
  62.593 +{
  62.594 +        uint32_t src, dst;
  62.595 +        
  62.596 +        fetch_ea_32(fetchdat);
  62.597 +        src = getlong();                        if (abrt) return 0;
  62.598 +        ARITH_MULTI(l, 32);
  62.599 +        
  62.600 +        return 0;
  62.601 +}
  62.602 +
  62.603 +static int op83_w_a16(uint32_t fetchdat)
  62.604 +{
  62.605 +        uint16_t src, dst;
  62.606 +        
  62.607 +        fetch_ea_16(fetchdat);
  62.608 +        src = getbyte();                        if (abrt) return 0;
  62.609 +        if (src & 0x80) src |= 0xff00;
  62.610 +        ARITH_MULTI(w, 16);
  62.611 +        
  62.612 +        return 0;
  62.613 +}
  62.614 +static int op83_w_a32(uint32_t fetchdat)
  62.615 +{
  62.616 +        uint16_t src, dst;
  62.617 +        
  62.618 +        fetch_ea_32(fetchdat);
  62.619 +        src = getbyte();                        if (abrt) return 0;
  62.620 +        if (src & 0x80) src |= 0xff00;
  62.621 +        ARITH_MULTI(w, 16);
  62.622 +        
  62.623 +        return 0;
  62.624 +}
  62.625 +
  62.626 +static int op83_l_a16(uint32_t fetchdat)
  62.627 +{
  62.628 +        uint32_t src, dst;
  62.629 +        
  62.630 +        fetch_ea_16(fetchdat);
  62.631 +        src = getbyte();                        if (abrt) return 0;
  62.632 +        if (src & 0x80) src |= 0xffffff00;
  62.633 +        ARITH_MULTI(l, 32);
  62.634 +        
  62.635 +        return 0;
  62.636 +}
  62.637 +static int op83_l_a32(uint32_t fetchdat)
  62.638 +{
  62.639 +        uint32_t src, dst;
  62.640 +        
  62.641 +        fetch_ea_32(fetchdat);
  62.642 +        src = getbyte();                        if (abrt) return 0;
  62.643 +        if (src & 0x80) src |= 0xffffff00;
  62.644 +        ARITH_MULTI(l, 32);
  62.645 +        
  62.646 +        return 0;
  62.647 +}
  62.648 +
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/src/x86_ops_atomic.h	Mon May 27 19:56:33 2013 +0100
    63.3 @@ -0,0 +1,209 @@
    63.4 +static int opCMPXCHG_b_a16(uint32_t fetchdat)
    63.5 +{
    63.6 +        uint8_t temp, temp2 = AL;
    63.7 +        if (!is486)
    63.8 +        {
    63.9 +                pc = oldpc;
   63.10 +                x86illegal();
   63.11 +                return 0;
   63.12 +        }
   63.13 +        fetch_ea_16(fetchdat);
   63.14 +        temp = geteab();                        if (abrt) return 0;
   63.15 +        if (AL == temp) seteab(getr8(reg));
   63.16 +        else            AL = temp;
   63.17 +        if (abrt) return 0;
   63.18 +        setsub8(temp2, temp);
   63.19 +        cycles -= (mod == 3) ? 6 : 10;
   63.20 +        return 0;
   63.21 +}
   63.22 +static int opCMPXCHG_b_a32(uint32_t fetchdat)
   63.23 +{
   63.24 +        uint8_t temp, temp2 = AL;
   63.25 +        if (!is486)
   63.26 +        {
   63.27 +                pc = oldpc;
   63.28 +                x86illegal();
   63.29 +                return 0;
   63.30 +        }
   63.31 +        fetch_ea_32(fetchdat);
   63.32 +        temp = geteab();                        if (abrt) return 0;
   63.33 +        if (AL == temp) seteab(getr8(reg));
   63.34 +        else            AL = temp;
   63.35 +        if (abrt) return 0;
   63.36 +        setsub8(temp2, temp);
   63.37 +        cycles -= (mod == 3) ? 6 : 10;
   63.38 +        return 0;
   63.39 +}
   63.40 +
   63.41 +static int opCMPXCHG_w_a16(uint32_t fetchdat)
   63.42 +{
   63.43 +        uint16_t temp, temp2 = AX;
   63.44 +        if (!is486)
   63.45 +        {
   63.46 +                pc = oldpc;
   63.47 +                x86illegal();
   63.48 +                return 0;
   63.49 +        }
   63.50 +        fetch_ea_16(fetchdat);
   63.51 +        temp = geteaw();                        if (abrt) return 0;
   63.52 +        if (AX == temp) seteaw(regs[reg].w);
   63.53 +        else            AX = temp;
   63.54 +        if (abrt) return 0;
   63.55 +        setsub16(temp2, temp);
   63.56 +        cycles -= (mod == 3) ? 6 : 10;
   63.57 +        return 0;
   63.58 +}
   63.59 +static int opCMPXCHG_w_a32(uint32_t fetchdat)
   63.60 +{
   63.61 +        uint16_t temp, temp2 = AX;
   63.62 +        if (!is486)
   63.63 +        {
   63.64 +                pc = oldpc;
   63.65 +                x86illegal();
   63.66 +                return 0;
   63.67 +        }
   63.68 +        fetch_ea_32(fetchdat);
   63.69 +        temp = geteaw();                        if (abrt) return 0;
   63.70 +        if (AX == temp) seteaw(regs[reg].w);
   63.71 +        else            AX = temp;
   63.72 +        if (abrt) return 0;
   63.73 +        setsub16(temp2, temp);
   63.74 +        cycles -= (mod == 3) ? 6 : 10;
   63.75 +        return 0;
   63.76 +}
   63.77 +
   63.78 +static int opCMPXCHG_l_a16(uint32_t fetchdat)
   63.79 +{
   63.80 +        uint32_t temp, temp2 = EAX;
   63.81 +        if (!is486)
   63.82 +        {
   63.83 +                pc = oldpc;
   63.84 +                x86illegal();
   63.85 +                return 0;
   63.86 +        }
   63.87 +        fetch_ea_16(fetchdat);
   63.88 +        temp = geteal();                        if (abrt) return 0;
   63.89 +        if (EAX == temp) seteal(regs[reg].l);
   63.90 +        else             EAX = temp;
   63.91 +        if (abrt) return 0;
   63.92 +        setsub32(temp2, temp);
   63.93 +        cycles -= (mod == 3) ? 6 : 10;
   63.94 +        return 0;
   63.95 +}
   63.96 +static int opCMPXCHG_l_a32(uint32_t fetchdat)
   63.97 +{
   63.98 +        uint32_t temp, temp2 = EAX;
   63.99 +        if (!is486)
  63.100 +        {
  63.101 +                pc = oldpc;
  63.102 +                x86illegal();
  63.103 +                return 0;
  63.104 +        }
  63.105 +        fetch_ea_32(fetchdat);
  63.106 +        temp = geteal();                        if (abrt) return 0;
  63.107 +        if (EAX == temp) seteal(regs[reg].l);
  63.108 +        else             EAX = temp;
  63.109 +        if (abrt) return 0;
  63.110 +        setsub32(temp2, temp);
  63.111 +        cycles -= (mod == 3) ? 6 : 10;
  63.112 +        return 0;
  63.113 +}
  63.114 +
  63.115 +static int opXADD_b_a16(uint32_t fetchdat)
  63.116 +{
  63.117 +        uint8_t temp;
  63.118 +        if (!is486)
  63.119 +        {
  63.120 +                pc = oldpc;
  63.121 +                x86illegal();
  63.122 +                return 0;
  63.123 +        }
  63.124 +        fetch_ea_16(fetchdat);
  63.125 +        temp = geteab();                        if (abrt) return 0;
  63.126 +        seteab(temp + getr8(reg));              if (abrt) return 0;
  63.127 +        setadd8(temp, getr8(reg));
  63.128 +        setr8(reg, temp);
  63.129 +        return 0;
  63.130 +}
  63.131 +static int opXADD_b_a32(uint32_t fetchdat)
  63.132 +{
  63.133 +        uint8_t temp;
  63.134 +        if (!is486)
  63.135 +        {
  63.136 +                pc = oldpc;
  63.137 +                x86illegal();
  63.138 +                return 0;
  63.139 +        }
  63.140 +        fetch_ea_32(fetchdat);
  63.141 +        temp = geteab();                        if (abrt) return 0;
  63.142 +        seteab(temp + getr8(reg));              if (abrt) return 0;
  63.143 +        setadd8(temp, getr8(reg));
  63.144 +        setr8(reg, temp);
  63.145 +        return 0;
  63.146 +}
  63.147 +
  63.148 +static int opXADD_w_a16(uint32_t fetchdat)
  63.149 +{
  63.150 +        uint16_t temp;
  63.151 +        if (!is486)
  63.152 +        {
  63.153 +                pc = oldpc;
  63.154 +                x86illegal();
  63.155 +                return 0;
  63.156 +        }
  63.157 +        fetch_ea_16(fetchdat);
  63.158 +        temp = geteaw();                        if (abrt) return 0;
  63.159 +        seteaw(temp + regs[reg].w);             if (abrt) return 0;
  63.160 +        setadd16(temp, regs[reg].w);
  63.161 +        regs[reg].w = temp;
  63.162 +        return 0;
  63.163 +}
  63.164 +static int opXADD_w_a32(uint32_t fetchdat)
  63.165 +{
  63.166 +        uint16_t temp;
  63.167 +        if (!is486)
  63.168 +        {
  63.169 +                pc = oldpc;
  63.170 +                x86illegal();
  63.171 +                return 0;
  63.172 +        }
  63.173 +        fetch_ea_32(fetchdat);
  63.174 +        temp = geteaw();                        if (abrt) return 0;
  63.175 +        seteaw(temp + regs[reg].w);             if (abrt) return 0;
  63.176 +        setadd16(temp, regs[reg].w);
  63.177 +        regs[reg].w = temp;
  63.178 +        return 0;
  63.179 +}
  63.180 +
  63.181 +static int opXADD_l_a16(uint32_t fetchdat)
  63.182 +{
  63.183 +        uint32_t temp;
  63.184 +        if (!is486)
  63.185 +        {
  63.186 +                pc = oldpc;
  63.187 +                x86illegal();
  63.188 +                return 0;
  63.189 +        }
  63.190 +        fetch_ea_16(fetchdat);
  63.191 +        temp = geteal();                        if (abrt) return 0;
  63.192 +        seteal(temp + regs[reg].l);             if (abrt) return 0;
  63.193 +        setadd32(temp, regs[reg].l);
  63.194 +        regs[reg].l = temp;
  63.195 +        return 0;
  63.196 +}
  63.197 +static int opXADD_l_a32(uint32_t fetchdat)
  63.198 +{
  63.199 +        uint32_t temp;
  63.200 +        if (!is486)
  63.201 +        {
  63.202 +                pc = oldpc;
  63.203 +                x86illegal();
  63.204 +                return 0;
  63.205 +        }
  63.206 +        fetch_ea_32(fetchdat);
  63.207 +        temp = geteal();                        if (abrt) return 0;
  63.208 +        seteal(temp + regs[reg].l);             if (abrt) return 0;
  63.209 +        setadd32(temp, regs[reg].l);
  63.210 +        regs[reg].l = temp;
  63.211 +        return 0;
  63.212 +}
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/src/x86_ops_bcd.h	Mon May 27 19:56:33 2013 +0100
    64.3 @@ -0,0 +1,105 @@
    64.4 +static int opAAA(uint32_t fetchdat)
    64.5 +{
    64.6 +        flags_rebuild();
    64.7 +        if ((flags & A_FLAG) || ((AL & 0xF) > 9))
    64.8 +        {
    64.9 +                AL += 6;
   64.10 +                AH++;
   64.11 +                flags |= (A_FLAG | C_FLAG);
   64.12 +        }
   64.13 +        else
   64.14 +                flags &= ~(A_FLAG | C_FLAG);
   64.15 +        AL &= 0xF;
   64.16 +        cycles -= is486 ? 3 : 4;
   64.17 +        return 0;
   64.18 +}
   64.19 +
   64.20 +static int opAAD(uint32_t fetchdat)
   64.21 +{
   64.22 +        int base = getbytef();
   64.23 +        if (cpu_manufacturer != MANU_INTEL) base = 10;
   64.24 +        AL = (AH * base) + AL;
   64.25 +        AH = 0;
   64.26 +        setznp16(AX);
   64.27 +        cycles -= (is486) ? 14 : 19;
   64.28 +        return 0;
   64.29 +}
   64.30 +
   64.31 +static int opAAM(uint32_t fetchdat)
   64.32 +{
   64.33 +        int base = getbytef();
   64.34 +        if (!base || cpu_manufacturer != MANU_INTEL) base = 10;
   64.35 +        AH = AL / base;
   64.36 +        AL %= base;
   64.37 +        setznp16(AX);
   64.38 +        cycles -= (is486) ? 15 : 17;
   64.39 +        return 0;
   64.40 +}
   64.41 +
   64.42 +static int opAAS(uint32_t fetchdat)
   64.43 +{
   64.44 +        flags_rebuild();
   64.45 +        if ((flags & A_FLAG) || ((AL & 0xF) > 9))
   64.46 +        {
   64.47 +                AL -= 6;
   64.48 +                AH--;
   64.49 +                flags |= (A_FLAG | C_FLAG);
   64.50 +        }
   64.51 +        else
   64.52 +                flags &= ~(A_FLAG | C_FLAG);
   64.53 +        AL &= 0xF;
   64.54 +        cycles -= is486 ? 3 : 4;
   64.55 +        return 0;
   64.56 +}
   64.57 +
   64.58 +static int opDAA(uint32_t fetchdat)
   64.59 +{
   64.60 +        uint16_t tempw;
   64.61 +        
   64.62 +        flags_rebuild();
   64.63 +        if ((flags & A_FLAG) || ((AL & 0xf) > 9))
   64.64 +        {
   64.65 +                int tempi = ((uint16_t)AL) + 6;
   64.66 +                AL += 6;
   64.67 +                flags |= A_FLAG;
   64.68 +                if (tempi & 0x100) flags |= C_FLAG;
   64.69 +        }
   64.70 +        if ((flags & C_FLAG) || (AL > 0x9f))
   64.71 +        {
   64.72 +                AL += 0x60;
   64.73 +                flags |= C_FLAG;
   64.74 +        }
   64.75 +
   64.76 +        tempw = flags & (C_FLAG | A_FLAG);
   64.77 +        setznp8(AL);
   64.78 +        flags |= tempw;
   64.79 +        cycles -= 4;
   64.80 +        
   64.81 +        return 0;
   64.82 +}
   64.83 +
   64.84 +static int opDAS(uint32_t fetchdat)
   64.85 +{
   64.86 +        uint16_t tempw;
   64.87 +
   64.88 +        flags_rebuild();
   64.89 +        if ((flags & A_FLAG) || ((AL & 0xf) > 9))
   64.90 +        {
   64.91 +                int tempi = ((uint16_t)AL) - 6;
   64.92 +                AL -= 6;
   64.93 +                flags |= A_FLAG;
   64.94 +                if (tempi & 0x100) flags |= C_FLAG;
   64.95 +        }
   64.96 +        if ((flags & C_FLAG) || (AL > 0x9f))
   64.97 +        {
   64.98 +                AL -= 0x60;
   64.99 +                flags |= C_FLAG;
  64.100 +        }
  64.101 +
  64.102 +        tempw = flags & (C_FLAG | A_FLAG);
  64.103 +        setznp8(AL);
  64.104 +        flags |= tempw;
  64.105 +        cycles -= 4;
  64.106 +        
  64.107 +        return 0;
  64.108 +}
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/src/x86_ops_bit.h	Mon May 27 19:56:33 2013 +0100
    65.3 @@ -0,0 +1,297 @@
    65.4 +static int opBT_w_r_a16(uint32_t fetchdat)
    65.5 +{
    65.6 +        int tempc;
    65.7 +        uint16_t temp;
    65.8 +        
    65.9 +        fetch_ea_16(fetchdat);
   65.10 +        eaaddr += ((regs[reg].w / 16) * 2);     eal_r = 0;
   65.11 +        temp = geteaw();                        if (abrt) return 0;
   65.12 +        flags_rebuild();
   65.13 +        if (temp & (1 << (regs[reg].w & 15))) flags |=  C_FLAG;
   65.14 +        else                                  flags &= ~C_FLAG;
   65.15 +        
   65.16 +        cycles -= 3;
   65.17 +        return 0;
   65.18 +}
   65.19 +static int opBT_w_r_a32(uint32_t fetchdat)
   65.20 +{
   65.21 +        uint16_t temp;
   65.22 +        
   65.23 +        fetch_ea_32(fetchdat);
   65.24 +        eaaddr += ((regs[reg].w / 16) * 2);     eal_r = 0;
   65.25 +        temp = geteaw();                        if (abrt) return 0;
   65.26 +        flags_rebuild();
   65.27 +        if (temp & (1 << (regs[reg].w & 15))) flags |=  C_FLAG;
   65.28 +        else                                  flags &= ~C_FLAG;
   65.29 +        
   65.30 +        cycles -= 3;
   65.31 +        return 0;
   65.32 +}
   65.33 +static int opBT_l_r_a16(uint32_t fetchdat)
   65.34 +{
   65.35 +        uint32_t temp;
   65.36 +        
   65.37 +        fetch_ea_16(fetchdat);
   65.38 +        eaaddr += ((regs[reg].l / 32) * 4);     eal_r = 0;
   65.39 +        temp = geteal();                        if (abrt) return 0;
   65.40 +        flags_rebuild();
   65.41 +        if (temp & (1 << (regs[reg].l & 31))) flags |=  C_FLAG;
   65.42 +        else                                  flags &= ~C_FLAG;
   65.43 +        
   65.44 +        cycles -= 3;
   65.45 +        return 0;
   65.46 +}
   65.47 +static int opBT_l_r_a32(uint32_t fetchdat)
   65.48 +{
   65.49 +        uint32_t temp;
   65.50 +        
   65.51 +        fetch_ea_32(fetchdat);
   65.52 +        eaaddr += ((regs[reg].l / 32) * 4);     eal_r = 0;
   65.53 +        temp = geteal();                        if (abrt) return 0;
   65.54 +        flags_rebuild();
   65.55 +        if (temp & (1 << (regs[reg].l & 31))) flags |=  C_FLAG;
   65.56 +        else                                  flags &= ~C_FLAG;
   65.57 +        
   65.58 +        cycles -= 3;
   65.59 +        return 0;
   65.60 +}
   65.61 +
   65.62 +#define opBT(name, operation)                                                   \
   65.63 +        static int opBT ## name ## _w_r_a16(uint32_t fetchdat)                  \
   65.64 +        {                                                                       \
   65.65 +                int tempc;                                                      \
   65.66 +                uint16_t temp;                                                  \
   65.67 +                                                                                \
   65.68 +                fetch_ea_16(fetchdat);                                          \
   65.69 +                eaaddr += ((regs[reg].w / 16) * 2);     eal_r = eal_w = 0;      \
   65.70 +                temp = geteaw();                        if (abrt) return 0;     \
   65.71 +                tempc = (temp & (1 << (regs[reg].w & 15))) ? 1 : 0;             \
   65.72 +                temp operation (1 << (regs[reg].w & 15));                       \
   65.73 +                seteaw(temp);                           if (abrt) return 0;     \
   65.74 +                flags_rebuild();                                                \
   65.75 +                if (tempc) flags |=  C_FLAG;                                    \
   65.76 +                else       flags &= ~C_FLAG;                                    \
   65.77 +                                                                                \
   65.78 +                cycles -= 6;                                                    \
   65.79 +                return 0;                                                       \
   65.80 +        }                                                                       \
   65.81 +        static int opBT ## name ## _w_r_a32(uint32_t fetchdat)                  \
   65.82 +        {                                                                       \
   65.83 +                int tempc;                                                      \
   65.84 +                uint16_t temp;                                                  \
   65.85 +                                                                                \
   65.86 +                fetch_ea_32(fetchdat);                                          \
   65.87 +                eaaddr += ((regs[reg].w / 16) * 2);     eal_r = eal_w = 0;      \
   65.88 +                temp = geteaw();                        if (abrt) return 0;     \
   65.89 +                tempc = (temp & (1 << (regs[reg].w & 15))) ? 1 : 0;             \
   65.90 +                temp operation (1 << (regs[reg].w & 15));                       \
   65.91 +                seteaw(temp);                           if (abrt) return 0;     \
   65.92 +                flags_rebuild();                                                \
   65.93 +                if (tempc) flags |=  C_FLAG;                                    \
   65.94 +                else       flags &= ~C_FLAG;                                    \
   65.95 +                                                                                \
   65.96 +                cycles -= 6;                                                    \
   65.97 +                return 0;                                                       \
   65.98 +        }                                                                       \
   65.99 +        static int opBT ## name ## _l_r_a16(uint32_t fetchdat)                  \
  65.100 +        {                                                                       \
  65.101 +                int tempc;                                                      \
  65.102 +                uint32_t temp;                                                  \
  65.103 +                                                                                \
  65.104 +                fetch_ea_16(fetchdat);                                          \
  65.105 +                eaaddr += ((regs[reg].l / 32) * 4);     eal_r = eal_w = 0;      \
  65.106 +                temp = geteal();                        if (abrt) return 0;     \
  65.107 +                tempc = (temp & (1 << (regs[reg].l & 31))) ? 1 : 0;             \
  65.108 +                temp operation (1 << (regs[reg].l & 31));                       \
  65.109 +                seteal(temp);                           if (abrt) return 0;     \
  65.110 +                flags_rebuild();                                                \
  65.111 +                if (tempc) flags |=  C_FLAG;                                    \
  65.112 +                else       flags &= ~C_FLAG;                                    \
  65.113 +                                                                                \
  65.114 +                cycles -= 6;                                                    \
  65.115 +                return 0;                                                       \
  65.116 +        }                                                                       \
  65.117 +        static int opBT ## name ## _l_r_a32(uint32_t fetchdat)                  \
  65.118 +        {                                                                       \
  65.119 +                int tempc;                                                      \
  65.120 +                uint32_t temp;                                                  \
  65.121 +                                                                                \
  65.122 +                fetch_ea_32(fetchdat);                                          \
  65.123 +                eaaddr += ((regs[reg].l / 32) * 4);     eal_r = eal_w = 0;      \
  65.124 +                temp = geteal();                        if (abrt) return 0;     \
  65.125 +                tempc = (temp & (1 << (regs[reg].l & 31))) ? 1 : 0;             \
  65.126 +                temp operation (1 << (regs[reg].l & 31));                       \
  65.127 +                seteal(temp);                           if (abrt) return 0;     \
  65.128 +                flags_rebuild();                                                \
  65.129 +                if (tempc) flags |=  C_FLAG;                                    \
  65.130 +                else       flags &= ~C_FLAG;                                    \
  65.131 +                                                                                \
  65.132 +                cycles -= 6;                                                    \
  65.133 +                return 0;                                                       \
  65.134 +        }
  65.135 +
  65.136 +opBT(C, ^=)
  65.137 +opBT(R, &=~)
  65.138 +opBT(S, |=)
  65.139 +
  65.140 +static int opBA_w_a16(uint32_t fetchdat)
  65.141 +{
  65.142 +        int tempc, count;
  65.143 +        uint16_t temp;
  65.144 +
  65.145 +        fetch_ea_16(fetchdat);
  65.146 +        
  65.147 +        temp = geteaw();
  65.148 +        count = getbyte();                      if (abrt) return 0;
  65.149 +        tempc = temp & (1 << count);
  65.150 +        flags_rebuild();
  65.151 +        switch (rmdat & 0x38)
  65.152 +        {
  65.153 +                case 0x20: /*BT w,imm*/
  65.154 +                if (tempc) flags |=  C_FLAG;
  65.155 +                else       flags &= ~C_FLAG;
  65.156 +                cycles -= 3;
  65.157 +                return 0;
  65.158 +                case 0x28: /*BTS w,imm*/
  65.159 +                temp |=  (1 << count);
  65.160 +                break;
  65.161 +                case 0x30: /*BTR w,imm*/
  65.162 +                temp &= ~(1 << count);
  65.163 +                break;
  65.164 +                case 0x38: /*BTC w,imm*/
  65.165 +                temp ^=  (1 << count);
  65.166 +                break;
  65.167 +
  65.168 +                default:
  65.169 +                pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
  65.170 +                pc = oldpc;
  65.171 +                x86illegal();
  65.172 +                break;
  65.173 +        }
  65.174 +        seteaw(temp);                           if (abrt) return 0;
  65.175 +        if (tempc) flags |=  C_FLAG;
  65.176 +        else       flags &= ~C_FLAG;
  65.177 +        cycles -= 6;
  65.178 +        return 0;
  65.179 +}
  65.180 +static int opBA_w_a32(uint32_t fetchdat)
  65.181 +{
  65.182 +        int tempc, count;
  65.183 +        uint16_t temp;
  65.184 +
  65.185 +        fetch_ea_32(fetchdat);
  65.186 +        
  65.187 +        temp = geteaw();
  65.188 +        count = getbyte();                      if (abrt) return 0;
  65.189 +        tempc = temp & (1 << count);
  65.190 +        flags_rebuild();
  65.191 +        switch (rmdat & 0x38)
  65.192 +        {
  65.193 +                case 0x20: /*BT w,imm*/
  65.194 +                if (tempc) flags |=  C_FLAG;
  65.195 +                else       flags &= ~C_FLAG;
  65.196 +                cycles -= 3;
  65.197 +                return 0;
  65.198 +                case 0x28: /*BTS w,imm*/
  65.199 +                temp |=  (1 << count);
  65.200 +                break;
  65.201 +                case 0x30: /*BTR w,imm*/
  65.202 +                temp &= ~(1 << count);
  65.203 +                break;
  65.204 +                case 0x38: /*BTC w,imm*/
  65.205 +                temp ^=  (1 << count);
  65.206 +                break;
  65.207 +
  65.208 +                default:
  65.209 +                pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
  65.210 +                pc = oldpc;
  65.211 +                x86illegal();
  65.212 +                break;
  65.213 +        }
  65.214 +        seteaw(temp);                           if (abrt) return 0;
  65.215 +        if (tempc) flags |=  C_FLAG;
  65.216 +        else       flags &= ~C_FLAG;
  65.217 +        cycles -= 6;
  65.218 +        return 0;
  65.219 +}
  65.220 +
  65.221 +static int opBA_l_a16(uint32_t fetchdat)
  65.222 +{
  65.223 +        int tempc, count;
  65.224 +        uint32_t temp;
  65.225 +
  65.226 +        fetch_ea_16(fetchdat);
  65.227 +        
  65.228 +        temp = geteal();
  65.229 +        count = getbyte();                      if (abrt) return 0;
  65.230 +        tempc = temp & (1 << count);
  65.231 +        flags_rebuild();
  65.232 +        switch (rmdat & 0x38)
  65.233 +        {
  65.234 +                case 0x20: /*BT w,imm*/
  65.235 +                if (tempc) flags |=  C_FLAG;
  65.236 +                else       flags &= ~C_FLAG;
  65.237 +                cycles -= 3;
  65.238 +                return 0;
  65.239 +                case 0x28: /*BTS w,imm*/
  65.240 +                temp |=  (1 << count);
  65.241 +                break;
  65.242 +                case 0x30: /*BTR w,imm*/
  65.243 +                temp &= ~(1 << count);
  65.244 +                break;
  65.245 +                case 0x38: /*BTC w,imm*/
  65.246 +                temp ^=  (1 << count);
  65.247 +                break;
  65.248 +
  65.249 +                default:
  65.250 +                pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
  65.251 +                pc = oldpc;
  65.252 +                x86illegal();
  65.253 +                break;
  65.254 +        }
  65.255 +        seteal(temp);                           if (abrt) return 0;
  65.256 +        if (tempc) flags |=  C_FLAG;
  65.257 +        else       flags &= ~C_FLAG;
  65.258 +        cycles -= 6;
  65.259 +        return 0;
  65.260 +}
  65.261 +static int opBA_l_a32(uint32_t fetchdat)
  65.262 +{
  65.263 +        int tempc, count;
  65.264 +        uint32_t temp;
  65.265 +
  65.266 +        fetch_ea_32(fetchdat);
  65.267 +        
  65.268 +        temp = geteal();
  65.269 +        count = getbyte();                      if (abrt) return 0;
  65.270 +        tempc = temp & (1 << count);
  65.271 +        flags_rebuild();
  65.272 +        switch (rmdat & 0x38)
  65.273 +        {
  65.274 +                case 0x20: /*BT w,imm*/
  65.275 +                if (tempc) flags |=  C_FLAG;
  65.276 +                else       flags &= ~C_FLAG;
  65.277 +                cycles -= 3;
  65.278 +                return 0;
  65.279 +                case 0x28: /*BTS w,imm*/
  65.280 +                temp |=  (1 << count);
  65.281 +                break;
  65.282 +                case 0x30: /*BTR w,imm*/
  65.283 +                temp &= ~(1 << count);
  65.284 +                break;
  65.285 +                case 0x38: /*BTC w,imm*/
  65.286 +                temp ^=  (1 << count);
  65.287 +                break;
  65.288 +
  65.289 +                default:
  65.290 +                pclog("Bad 0F BA opcode %02X\n", rmdat & 0x38);
  65.291 +                pc = oldpc;
  65.292 +                x86illegal();
  65.293 +                break;
  65.294 +        }
  65.295 +        seteal(temp);                           if (abrt) return 0;
  65.296 +        if (tempc) flags |=  C_FLAG;
  65.297 +        else       flags &= ~C_FLAG;
  65.298 +        cycles -= 6;
  65.299 +        return 0;
  65.300 +}
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/src/x86_ops_bitscan.h	Mon May 27 19:56:33 2013 +0100
    66.3 @@ -0,0 +1,117 @@
    66.4 +#define BS_common(start, end, dir, dest, time)                                  \
    66.5 +        flags_rebuild();                                                        \
    66.6 +        if (temp)                                                               \
    66.7 +        {                                                                       \
    66.8 +                int c;                                                          \
    66.9 +                flags &= ~Z_FLAG;                                               \
   66.10 +                for (c = start; c != end; c += dir)                             \
   66.11 +                {                                                               \
   66.12 +                        cycles -= time;                                         \
   66.13 +                        if (temp & (1 << c))                                    \
   66.14 +                        {                                                       \
   66.15 +                                dest = c;                                       \
   66.16 +                                break;                                          \
   66.17 +                        }                                                       \
   66.18 +                }                                                               \
   66.19 +        }                                                                       \
   66.20 +        else                                                                    \
   66.21 +                flags |= Z_FLAG;
   66.22 +
   66.23 +static int opBSF_w_a16(uint32_t fetchdat)
   66.24 +{
   66.25 +        uint16_t temp;
   66.26 +        
   66.27 +        fetch_ea_16(fetchdat);
   66.28 +        temp = geteaw();                        if (abrt) return 0;
   66.29 +        
   66.30 +        BS_common(0, 16, 1, regs[reg].w, (is486) ? 1 : 3);
   66.31 +        
   66.32 +        cycles -= (is486) ? 6 : 10;
   66.33 +        return 0;
   66.34 +}
   66.35 +static int opBSF_w_a32(uint32_t fetchdat)
   66.36 +{
   66.37 +        uint16_t temp;
   66.38 +        
   66.39 +        fetch_ea_32(fetchdat);
   66.40 +        temp = geteaw();                        if (abrt) return 0;
   66.41 +        
   66.42 +        BS_common(0, 16, 1, regs[reg].w, (is486) ? 1 : 3);
   66.43 +        
   66.44 +        cycles -= (is486) ? 6 : 10;
   66.45 +        return 0;
   66.46 +}
   66.47 +static int opBSF_l_a16(uint32_t fetchdat)
   66.48 +{
   66.49 +        uint32_t temp;
   66.50 +        
   66.51 +        fetch_ea_16(fetchdat);
   66.52 +        temp = geteal();                        if (abrt) return 0;
   66.53 +        
   66.54 +        BS_common(0, 32, 1, regs[reg].l, (is486) ? 1 : 3);
   66.55 +        
   66.56 +        cycles -= (is486) ? 6 : 10;
   66.57 +        return 0;
   66.58 +}
   66.59 +static int opBSF_l_a32(uint32_t fetchdat)
   66.60 +{
   66.61 +        uint32_t temp;
   66.62 +        
   66.63 +        fetch_ea_32(fetchdat);
   66.64 +        temp = geteal();                        if (abrt) return 0;
   66.65 +        
   66.66 +        BS_common(0, 32, 1, regs[reg].l, (is486) ? 1 : 3);
   66.67 +        
   66.68 +        cycles -= (is486) ? 6 : 10;
   66.69 +        return 0;
   66.70 +}
   66.71 +
   66.72 +static int opBSR_w_a16(uint32_t fetchdat)
   66.73 +{
   66.74 +        uint16_t temp;
   66.75 +        
   66.76 +        fetch_ea_16(fetchdat);
   66.77 +        temp = geteaw();                        if (abrt) return 0;
   66.78 +        
   66.79 +        BS_common(15, -1, -1, regs[reg].w, 3);
   66.80 +        
   66.81 +        cycles -= (is486) ? 6 : 10;
   66.82 +        return 0;
   66.83 +}
   66.84 +static int opBSR_w_a32(uint32_t fetchdat)
   66.85 +{
   66.86 +        uint16_t temp;
   66.87 +        
   66.88 +        fetch_ea_32(fetchdat);
   66.89 +        temp = geteaw();                        if (abrt) return 0;
   66.90 +        
   66.91 +        BS_common(15, -1, -1, regs[reg].w, 3);
   66.92 +        
   66.93 +        cycles -= (is486) ? 6 : 10;
   66.94 +        return 0;
   66.95 +}
   66.96 +static int opBSR_l_a16(uint32_t fetchdat)
   66.97 +{
   66.98 +        uint32_t temp;
   66.99 +        
  66.100 +        fetch_ea_16(fetchdat);
  66.101 +        temp = geteal();                        if (abrt) return 0;
  66.102 +        
  66.103 +        BS_common(31, -1, -1, regs[reg].l, 3);
  66.104 +        
  66.105 +        cycles -= (is486) ? 6 : 10;
  66.106 +        return 0;
  66.107 +}
  66.108 +static int opBSR_l_a32(uint32_t fetchdat)
  66.109 +{
  66.110 +        uint32_t temp;
  66.111 +        
  66.112 +        fetch_ea_32(fetchdat);
  66.113 +        temp = geteal();                        if (abrt) return 0;
  66.114 +        
  66.115 +        BS_common(31, -1, -1, regs[reg].l, 3);
  66.116 +        
  66.117 +        cycles -= (is486) ? 6 : 10;
  66.118 +        return 0;
  66.119 +}
  66.120 +
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/src/x86_ops_call.h	Mon May 27 19:56:33 2013 +0100
    67.3 @@ -0,0 +1,366 @@
    67.4 +#define CALL_FAR_w(new_seg, new_pc)                                             \
    67.5 +        old_cs = CS;                                                            \
    67.6 +        old_pc = pc;                                                            \
    67.7 +        if (ssegs) ss = oldss;                                                  \
    67.8 +        oxpc = pc;                                                              \
    67.9 +        pc = new_pc;                                                            \
   67.10 +        optype = CALL;                                                          \
   67.11 +        cgate16 = cgate32 = 0;                                                  \
   67.12 +        if (msw & 1) loadcscall(new_seg);                                       \
   67.13 +        else         loadcs(new_seg);                                           \
   67.14 +        optype = 0;                                                             \
   67.15 +        if (abrt) { cgate16 = cgate32 = 0; return 0; }                          \
   67.16 +        oldss = ss;                                                             \
   67.17 +        if (cgate32)                                                            \
   67.18 +        {                                                                       \
   67.19 +                PUSH_L(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; return 0; }     \
   67.20 +                PUSH_L(old_pc);                                                 \
   67.21 +        }                                                                       \
   67.22 +        else                                                                    \
   67.23 +        {                                                                       \
   67.24 +                PUSH_W(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; return 0; }     \
   67.25 +                PUSH_W(old_pc);                                                 \
   67.26 +        }
   67.27 +        
   67.28 +#define CALL_FAR_l(new_seg, new_pc)                                             \
   67.29 +        old_cs = CS;                                                            \
   67.30 +        old_pc = pc;                                                            \
   67.31 +        if (ssegs) ss = oldss;                                                  \
   67.32 +        oxpc = pc;                                                              \
   67.33 +        pc = new_pc;                                                            \
   67.34 +        optype = CALL;                                                          \
   67.35 +        cgate16 = cgate32 = 0;                                                  \
   67.36 +        if (msw & 1) loadcscall(new_seg);                                       \
   67.37 +        else         loadcs(new_seg);                                           \
   67.38 +        optype = 0;                                                             \
   67.39 +        if (abrt) { cgate16 = cgate32 = 0; return 0; }                          \
   67.40 +        oldss = ss;                                                             \
   67.41 +        if (cgate16)                                                            \
   67.42 +        {                                                                       \
   67.43 +                PUSH_W(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; return 0; }     \
   67.44 +                PUSH_W(old_pc);                                                 \
   67.45 +        }                                                                       \
   67.46 +        else                                                                    \
   67.47 +        {                                                                       \
   67.48 +                PUSH_L(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; return 0; }     \
   67.49 +                PUSH_L(old_pc);                                                 \
   67.50 +        }
   67.51 +        
   67.52 +
   67.53 +#define CALL_FAR_nr(new_seg, new_pc)                                               \
   67.54 +        old_cs = CS;                                                            \
   67.55 +        old_pc = pc;                                                            \
   67.56 +        if (ssegs) ss = oldss;                                                  \
   67.57 +        oxpc = pc;                                                              \
   67.58 +        pc = new_pc;                                                            \
   67.59 +        optype = CALL;                                                          \
   67.60 +        cgate16 = cgate32 = 0;                                                  \
   67.61 +        if (msw & 1) loadcscall(new_seg);                                       \
   67.62 +        else         loadcs(new_seg);                                           \
   67.63 +        optype = 0;                                                             \
   67.64 +        if (abrt) { cgate16 = cgate32 = 0; break; }                          \
   67.65 +        oldss = ss;                                                             \
   67.66 +        if (cgate32)                                                            \
   67.67 +        {                                                                       \
   67.68 +                PUSH_L(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; break; }     \
   67.69 +                PUSH_L(old_pc);                                                 \
   67.70 +        }                                                                       \
   67.71 +        else                                                                    \
   67.72 +        {                                                                       \
   67.73 +                PUSH_W(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; break; }     \
   67.74 +                PUSH_W(old_pc);                                                 \
   67.75 +        }                                                                       \
   67.76 +        
   67.77 +static int opCALL_far_w(uint32_t fetchdat)
   67.78 +{
   67.79 +        uint32_t old_cs, old_pc;
   67.80 +        uint16_t new_cs, new_pc;
   67.81 +        
   67.82 +        new_pc = getwordf();
   67.83 +        new_cs = getword();                             if (abrt) return 0;
   67.84 +        
   67.85 +        CALL_FAR_w(new_cs, new_pc);
   67.86 +        
   67.87 +        cycles -= is486 ? 18 : 17;
   67.88 +        return 0;
   67.89 +}
   67.90 +static int opCALL_far_l(uint32_t fetchdat)
   67.91 +{
   67.92 +        uint32_t old_cs, old_pc;
   67.93 +        uint32_t new_cs, new_pc;
   67.94 +        
   67.95 +        new_pc = getlong();
   67.96 +        new_cs = getword();                             if (abrt) return 0;
   67.97 +        
   67.98 +        CALL_FAR_l(new_cs, new_pc);
   67.99 +        
  67.100 +        cycles -= is486 ? 18 : 17;
  67.101 +        return 0;
  67.102 +}
  67.103 +
  67.104 +
  67.105 +static int opFF_w_a16(uint32_t fetchdat)
  67.106 +{
  67.107 +        uint16_t old_cs, new_cs;
  67.108 +        uint32_t old_pc, new_pc;
  67.109 +        
  67.110 +        uint16_t temp;
  67.111 +        
  67.112 +        fetch_ea_16(fetchdat);
  67.113 +        
  67.114 +        switch (rmdat & 0x38)
  67.115 +        {
  67.116 +                case 0x00: /*INC w*/
  67.117 +                temp = geteaw();                        if (abrt) return 0;
  67.118 +                seteaw(temp + 1);                       if (abrt) return 0;
  67.119 +                setadd16nc(temp, 1);
  67.120 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  67.121 +                break;
  67.122 +                case 0x08: /*DEC w*/
  67.123 +                temp = geteaw();                        if (abrt) return 0;
  67.124 +                seteaw(temp - 1);                       if (abrt) return 0;
  67.125 +                setsub16nc(temp, 1);
  67.126 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  67.127 +                break;
  67.128 +                case 0x10: /*CALL*/
  67.129 +                new_pc = geteaw();                      if (abrt) return 0;
  67.130 +                if (ssegs) ss = oldss;
  67.131 +                PUSH_W(pc);
  67.132 +                pc = new_pc;
  67.133 +                if (is486) cycles -= 5;
  67.134 +                else       cycles -= ((mod == 3) ? 7 : 10);
  67.135 +                break;
  67.136 +                case 0x18: /*CALL far*/
  67.137 +                new_pc = readmemw(easeg, eaaddr);
  67.138 +                new_cs = readmemw(easeg, (eaaddr + 2)); if (abrt) return 0;
  67.139 +                
  67.140 +                CALL_FAR_w(new_cs, new_pc);
  67.141 +                
  67.142 +                cycles -= is486 ? 17 : 22;
  67.143 +                break;
  67.144 +                case 0x20: /*JMP*/
  67.145 +                new_pc = geteaw();                      if (abrt) return 0;
  67.146 +                pc = new_pc;
  67.147 +                if (is486) cycles -= 5;
  67.148 +                else       cycles -= ((mod == 3) ? 7 : 10);
  67.149 +                break;
  67.150 +                case 0x28: /*JMP far*/
  67.151 +                oxpc = pc;
  67.152 +                new_pc = readmemw(easeg, eaaddr);
  67.153 +                new_cs = readmemw(easeg, eaaddr + 2);  if (abrt) return 0;
  67.154 +                pc = new_pc;
  67.155 +                loadcsjmp(new_cs, oxpc);               if (abrt) return 0;
  67.156 +                cycles -= is486 ? 13 : 12;
  67.157 +                break;
  67.158 +                case 0x30: /*PUSH w*/
  67.159 +                temp = geteaw();                        if (abrt) return 0;
  67.160 +                if (ssegs) ss = oldss;
  67.161 +                PUSH_W(temp);
  67.162 +                cycles -= ((mod == 3) ? 2 : 5);
  67.163 +                break;
  67.164 +
  67.165 +                default:
  67.166 +                fatal("Bad FF opcode %02X\n",rmdat&0x38);
  67.167 +                x86illegal();
  67.168 +        }
  67.169 +        return 0;
  67.170 +}
  67.171 +static int opFF_w_a32(uint32_t fetchdat)
  67.172 +{
  67.173 +        uint16_t old_cs, new_cs;
  67.174 +        uint32_t old_pc, new_pc;
  67.175 +        
  67.176 +        uint16_t temp;
  67.177 +        
  67.178 +        fetch_ea_32(fetchdat);
  67.179 +        
  67.180 +        switch (rmdat & 0x38)
  67.181 +        {
  67.182 +                case 0x00: /*INC w*/
  67.183 +                temp = geteaw();                        if (abrt) return 0;
  67.184 +                seteaw(temp + 1);                       if (abrt) return 0;
  67.185 +                setadd16nc(temp, 1);
  67.186 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  67.187 +                break;
  67.188 +                case 0x08: /*DEC w*/
  67.189 +                temp = geteaw();                        if (abrt) return 0;
  67.190 +                seteaw(temp - 1);                       if (abrt) return 0;
  67.191 +                setsub16nc(temp, 1);
  67.192 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  67.193 +                break;
  67.194 +                case 0x10: /*CALL*/
  67.195 +                new_pc = geteaw();                      if (abrt) return 0;
  67.196 +                if (ssegs) ss = oldss;
  67.197 +                PUSH_W(pc);
  67.198 +                pc = new_pc;
  67.199 +                if (is486) cycles -= 5;
  67.200 +                else       cycles -= ((mod == 3) ? 7 : 10);
  67.201 +                break;
  67.202 +                case 0x18: /*CALL far*/
  67.203 +                new_pc = readmemw(easeg, eaaddr);
  67.204 +                new_cs = readmemw(easeg, (eaaddr + 2)); if (abrt) return 0;
  67.205 +                
  67.206 +                CALL_FAR_w(new_cs, new_pc);
  67.207 +
  67.208 +                cycles -= is486 ? 17 : 22;
  67.209 +                break;
  67.210 +                case 0x20: /*JMP*/
  67.211 +                new_pc = geteaw();                      if (abrt) return 0;
  67.212 +                pc = new_pc;
  67.213 +                if (is486) cycles -= 5;
  67.214 +                else       cycles -= ((mod == 3) ? 7 : 10);
  67.215 +                break;
  67.216 +                case 0x28: /*JMP far*/
  67.217 +                oxpc = pc;
  67.218 +                new_pc = readmemw(easeg, eaaddr);
  67.219 +                new_cs = readmemw(easeg, eaaddr + 2);  if (abrt) return 0;
  67.220 +                pc = new_pc;
  67.221 +                loadcsjmp(new_cs, oxpc);               if (abrt) return 0;
  67.222 +                cycles -= is486 ? 13 : 12;
  67.223 +                break;
  67.224 +                case 0x30: /*PUSH w*/
  67.225 +                temp = geteaw();                        if (abrt) return 0;
  67.226 +                if (ssegs) ss = oldss;
  67.227 +                PUSH_W(temp);
  67.228 +                cycles -= ((mod == 3) ? 2 : 5);
  67.229 +                break;
  67.230 +
  67.231 +                default:
  67.232 +                fatal("Bad FF opcode %02X\n",rmdat&0x38);
  67.233 +                x86illegal();
  67.234 +        }
  67.235 +        return 0;
  67.236 +}
  67.237 +
  67.238 +static int opFF_l_a16(uint32_t fetchdat)
  67.239 +{
  67.240 +        uint16_t old_cs, new_cs;
  67.241 +        uint32_t old_pc, new_pc;
  67.242 +        
  67.243 +        uint32_t temp;
  67.244 +        
  67.245 +        fetch_ea_16(fetchdat);
  67.246 +        
  67.247 +        switch (rmdat & 0x38)
  67.248 +        {
  67.249 +                case 0x00: /*INC l*/
  67.250 +                temp = geteal();                        if (abrt) return 0;
  67.251 +                seteal(temp + 1);                       if (abrt) return 0;
  67.252 +                setadd32nc(temp, 1);
  67.253 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  67.254 +                break;
  67.255 +                case 0x08: /*DEC l*/
  67.256 +                temp = geteal();                        if (abrt) return 0;
  67.257 +                seteal(temp - 1);                       if (abrt) return 0;
  67.258 +                setsub32nc(temp, 1);
  67.259 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  67.260 +                break;
  67.261 +                case 0x10: /*CALL*/
  67.262 +                new_pc = geteal();                      if (abrt) return 0;
  67.263 +                if (ssegs) ss = oldss;
  67.264 +                PUSH_L(pc);
  67.265 +                pc = new_pc;
  67.266 +                if (is486) cycles -= 5;
  67.267 +                else       cycles -= ((mod == 3) ? 7 : 10);
  67.268 +                break;
  67.269 +                case 0x18: /*CALL far*/
  67.270 +                new_pc = readmeml(easeg, eaaddr);
  67.271 +                new_cs = readmemw(easeg, (eaaddr + 4)); if (abrt) return 0;
  67.272 +                
  67.273 +                CALL_FAR_l(new_cs, new_pc);
  67.274 +                
  67.275 +                cycles -= is486 ? 17 : 22;
  67.276 +                break;
  67.277 +                case 0x20: /*JMP*/
  67.278 +                new_pc = geteal();                      if (abrt) return 0;
  67.279 +                pc = new_pc;
  67.280 +                if (is486) cycles -= 5;
  67.281 +                else       cycles -= ((mod == 3) ? 7 : 10);
  67.282 +                break;
  67.283 +                case 0x28: /*JMP far*/
  67.284 +                oxpc = pc;
  67.285 +                new_pc = readmeml(easeg, eaaddr);
  67.286 +                new_cs = readmemw(easeg, eaaddr + 4);   if (abrt) return 0;
  67.287 +                pc = new_pc;
  67.288 +                loadcsjmp(new_cs, oxpc);                if (abrt) return 0;
  67.289 +                cycles -= is486 ? 13 : 12;
  67.290 +                break;
  67.291 +                case 0x30: /*PUSH l*/
  67.292 +                temp = geteal();                        if (abrt) return 0;
  67.293 +                if (ssegs) ss = oldss;
  67.294 +                PUSH_L(temp);
  67.295 +                cycles -= ((mod == 3) ? 2 : 5);
  67.296 +                break;
  67.297 +
  67.298 +                default:
  67.299 +                fatal("Bad FF opcode %02X\n",rmdat&0x38);
  67.300 +                x86illegal();
  67.301 +        }
  67.302 +        return 0;
  67.303 +}
  67.304 +static int opFF_l_a32(uint32_t fetchdat)
  67.305 +{
  67.306 +        uint16_t old_cs, new_cs;
  67.307 +        uint32_t old_pc, new_pc;
  67.308 +        
  67.309 +        uint32_t temp;
  67.310 +        
  67.311 +        fetch_ea_32(fetchdat);
  67.312 +        
  67.313 +        switch (rmdat & 0x38)
  67.314 +        {
  67.315 +                case 0x00: /*INC l*/
  67.316 +                temp = geteal();                        if (abrt) return 0;
  67.317 +                seteal(temp + 1);                       if (abrt) return 0;
  67.318 +                setadd32nc(temp, 1);
  67.319 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  67.320 +                break;
  67.321 +                case 0x08: /*DEC l*/
  67.322 +                temp = geteal();                        if (abrt) return 0;
  67.323 +                seteal(temp - 1);                       if (abrt) return 0;
  67.324 +                setsub32nc(temp, 1);
  67.325 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  67.326 +                break;
  67.327 +                case 0x10: /*CALL*/
  67.328 +                new_pc = geteal();                      if (abrt) return 0;
  67.329 +                if (ssegs) ss = oldss;
  67.330 +                PUSH_L(pc);                             if (abrt) return 0;
  67.331 +                pc = new_pc;
  67.332 +                if (is486) cycles -= 5;
  67.333 +                else       cycles -= ((mod == 3) ? 7 : 10);
  67.334 +                break;
  67.335 +                case 0x18: /*CALL far*/
  67.336 +                new_pc = readmeml(easeg, eaaddr);
  67.337 +                new_cs = readmemw(easeg, (eaaddr + 4)); if (abrt) return 0;
  67.338 +                
  67.339 +                CALL_FAR_l(new_cs, new_pc);
  67.340 +                
  67.341 +                cycles -= is486 ? 17 : 22;
  67.342 +                break;
  67.343 +                case 0x20: /*JMP*/
  67.344 +                new_pc = geteal();                      if (abrt) return 0;
  67.345 +                pc = new_pc;
  67.346 +                if (is486) cycles -= 5;
  67.347 +                else       cycles -= ((mod == 3) ? 7 : 10);
  67.348 +                break;
  67.349 +                case 0x28: /*JMP far*/
  67.350 +                oxpc = pc;
  67.351 +                new_pc = readmeml(easeg, eaaddr);
  67.352 +                new_cs = readmemw(easeg, eaaddr + 4);   if (abrt) return 0;
  67.353 +                pc = new_pc;
  67.354 +                loadcsjmp(new_cs, oxpc);                if (abrt) return 0;
  67.355 +                cycles -= is486 ? 13 : 12;
  67.356 +                break;
  67.357 +                case 0x30: /*PUSH l*/
  67.358 +                temp = geteal();                        if (abrt) return 0;
  67.359 +                if (ssegs) ss = oldss;
  67.360 +                PUSH_L(temp);
  67.361 +                cycles -= ((mod == 3) ? 2 : 5);
  67.362 +                break;
  67.363 +
  67.364 +                default:
  67.365 +                fatal("Bad FF opcode %02X\n",rmdat&0x38);
  67.366 +                x86illegal();
  67.367 +        }
  67.368 +        return 0;
  67.369 +}
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/src/x86_ops_flag.h	Mon May 27 19:56:33 2013 +0100
    68.3 @@ -0,0 +1,178 @@
    68.4 +static int opCMC(uint32_t fetchdat)
    68.5 +{
    68.6 +        flags_rebuild();
    68.7 +        flags ^= C_FLAG;
    68.8 +        cycles -= 2;
    68.9 +        return 0;
   68.10 +}
   68.11 +
   68.12 +
   68.13 +static int opCLC(uint32_t fetchdat)
   68.14 +{
   68.15 +        flags_rebuild();
   68.16 +        flags &= ~C_FLAG;
   68.17 +        cycles -= 2;
   68.18 +        return 0;
   68.19 +}
   68.20 +static int opCLD(uint32_t fetchdat)
   68.21 +{
   68.22 +        flags &= ~D_FLAG;
   68.23 +        cycles -= 2;
   68.24 +        return 0;
   68.25 +}
   68.26 +static int opCLI(uint32_t fetchdat)
   68.27 +{
   68.28 +        if (!IOPLp)
   68.29 +        {
   68.30 +                x86gpf(NULL,0);
   68.31 +        }
   68.32 +        else
   68.33 +                flags &= ~I_FLAG;
   68.34 +                        
   68.35 +        cycles -= 3;
   68.36 +        return 0;
   68.37 +}
   68.38 +
   68.39 +static int opSTC(uint32_t fetchdat)
   68.40 +{
   68.41 +        flags_rebuild();
   68.42 +        flags |= C_FLAG;
   68.43 +        cycles -= 2;
   68.44 +        return 0;
   68.45 +}
   68.46 +static int opSTD(uint32_t fetchdat)
   68.47 +{
   68.48 +        flags |= D_FLAG;
   68.49 +        cycles -= 2;
   68.50 +        return 0;
   68.51 +}
   68.52 +static int opSTI(uint32_t fetchdat)
   68.53 +{
   68.54 +        if (!IOPLp)
   68.55 +        {
   68.56 +                x86gpf(NULL,0);
   68.57 +        }
   68.58 +        else
   68.59 +                flags |= I_FLAG;
   68.60 +                        
   68.61 +        cycles -= 2;
   68.62 +        return 0;
   68.63 +}
   68.64 +
   68.65 +static int opSAHF(uint32_t fetchdat)
   68.66 +{
   68.67 +        flags_rebuild();
   68.68 +        flags = (flags & 0xff00) | (AH & 0xd5) | 2;
   68.69 +        cycles -= 3;
   68.70 +        return 0;
   68.71 +}
   68.72 +static int opLAHF(uint32_t fetchdat)
   68.73 +{
   68.74 +        flags_rebuild();
   68.75 +        AH = flags & 0xff;
   68.76 +        cycles -= 3;
   68.77 +        return 0;
   68.78 +}
   68.79 +
   68.80 +static int opPUSHF(uint32_t fetchdat)
   68.81 +{
   68.82 +        if (ssegs) ss = oldss;
   68.83 +        if ((eflags & VM_FLAG) && (IOPL < 3))
   68.84 +        {
   68.85 +                x86gpf(NULL,0);
   68.86 +                return 0;
   68.87 +        }
   68.88 +        flags_rebuild();
   68.89 +        PUSH_W(flags);
   68.90 +        cycles -= 4;
   68.91 +        return 0;
   68.92 +}
   68.93 +static int opPUSHFD(uint32_t fetchdat)
   68.94 +{
   68.95 +        uint16_t tempw;
   68.96 +        if (ssegs) ss=oldss;
   68.97 +        if ((eflags & VM_FLAG) && (IOPL < 3))
   68.98 +        {
   68.99 +                x86gpf(NULL, 0);
  68.100 +                return 0;
  68.101 +        }
  68.102 +        if (CPUID) tempw = eflags & 0x24;
  68.103 +        else       tempw = eflags & 4;
  68.104 +        flags_rebuild();
  68.105 +        PUSH_L(flags | (tempw << 16));
  68.106 +        cycles -= 4;
  68.107 +        return 0;
  68.108 +}
  68.109 +
  68.110 +static int opPOPF_286(uint32_t fetchdat)
  68.111 +{
  68.112 +        uint16_t tempw;
  68.113 +        if (ssegs) ss = oldss;
  68.114 +        
  68.115 +        if ((eflags & VM_FLAG) && (IOPL < 3))
  68.116 +        {
  68.117 +                x86gpf(NULL, 0);
  68.118 +                return 0;
  68.119 +        }
  68.120 +        
  68.121 +        tempw = POP_W();                if (abrt) return 0;
  68.122 +
  68.123 +        pclog("POPF_286 %04X:%04X %04X\n", CS, pc, tempw);
  68.124 +        if (!(msw & 1))           flags = (flags & 0x7000) | (tempw & 0x0fd5) | 2;
  68.125 +        else if (!(CPL))          flags = (tempw & 0x7fd5) | 2;
  68.126 +        else if (IOPLp)           flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2;
  68.127 +        else                      flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
  68.128 +        flags_extract();
  68.129 +
  68.130 +        cycles -= 5;
  68.131 +        return 0;
  68.132 +}
  68.133 +static int opPOPF(uint32_t fetchdat)
  68.134 +{
  68.135 +        uint16_t tempw;
  68.136 +        if (ssegs) ss = oldss;
  68.137 +        
  68.138 +        if ((eflags & VM_FLAG) && (IOPL < 3))
  68.139 +        {
  68.140 +                x86gpf(NULL, 0);
  68.141 +                return 0;
  68.142 +        }
  68.143 +        
  68.144 +        tempw = POP_W();                if (abrt) return 0;
  68.145 +        
  68.146 +        if (!(CPL) || !(msw & 1)) flags = (tempw & 0xffd5) | 2;
  68.147 +        else if (IOPLp)           flags = (flags & 0x3000) | (tempw & 0xcfd5) | 2;
  68.148 +        else                      flags = (flags & 0x3200) | (tempw & 0xcdd5) | 2;
  68.149 +        flags_extract();
  68.150 +
  68.151 +        cycles -= 5;
  68.152 +        return 0;
  68.153 +}
  68.154 +static int opPOPFD(uint32_t fetchdat)
  68.155 +{
  68.156 +        uint32_t templ;
  68.157 +        if (ssegs) ss = oldss;
  68.158 +        
  68.159 +        if ((eflags & VM_FLAG) && (IOPL < 3))
  68.160 +        {
  68.161 +                x86gpf(NULL, 0);
  68.162 +                return 0;                
  68.163 +        }
  68.164 +        
  68.165 +        templ = POP_L();                if (abrt) return 0;
  68.166 +
  68.167 +        if (!(CPL) || !(msw & 1)) flags = (templ & 0xffd5) | 2;
  68.168 +        else if (IOPLp)           flags = (flags & 0x3000) | (templ & 0xcfd5) | 2;
  68.169 +        else                      flags = (flags & 0x3200) | (templ & 0xcdd5) | 2;
  68.170 +        
  68.171 +        templ &= is486 ? 0x240000 : 0;
  68.172 +        templ |= ((eflags&3) << 16);
  68.173 +        if (CPUID)      eflags = (templ >> 16) & 0x27;
  68.174 +        else if (is486) eflags = (templ >> 16) & 7;
  68.175 +        else            eflags = (templ >> 16) & 3;
  68.176 +        
  68.177 +        flags_extract();
  68.178 +
  68.179 +        cycles -= 5;
  68.180 +        return 0;
  68.181 +}
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/src/x86_ops_fpu.h	Mon May 27 19:56:33 2013 +0100
    69.3 @@ -0,0 +1,60 @@
    69.4 +#define opESCAPE(num)                                                           \
    69.5 +        static int opESCAPE_ ## num ##_a16(uint32_t fetchdat)                   \
    69.6 +        {                                                                       \
    69.7 +                flags_rebuild();                                                \
    69.8 +                if ((cr0 & 6) == 4)                                             \
    69.9 +                {                                                               \
   69.10 +                        x86_int(7);                                             \
   69.11 +                }                                                               \
   69.12 +                else                                                            \
   69.13 +                {                                                               \
   69.14 +                        fpucount++;                                             \
   69.15 +                        fetch_ea_16(fetchdat);                                  \
   69.16 +                        if (hasfpu)                                             \
   69.17 +                        {                                                       \
   69.18 +                                x87_pc_off = oldpc;                             \
   69.19 +                                x87_pc_seg = CS;                                \
   69.20 +                                x87_op_off = eaaddr;                            \
   69.21 +                                x87_op_seg = ea_rseg;                           \
   69.22 +                                x87_ ## num();                                  \
   69.23 +                        }                                                       \
   69.24 +                }                                                               \
   69.25 +                return 0;                                                       \
   69.26 +        }                                                                       \
   69.27 +        static int opESCAPE_ ## num ## _a32(uint32_t fetchdat)                  \
   69.28 +        {                                                                       \
   69.29 +                flags_rebuild();                                                \
   69.30 +                if ((cr0 & 6) == 4)                                             \
   69.31 +                {                                                               \
   69.32 +                        x86_int(7);                                             \
   69.33 +                }                                                               \
   69.34 +                else                                                            \
   69.35 +                {                                                               \
   69.36 +                        fpucount++;                                             \
   69.37 +                        fetch_ea_32(fetchdat);                                  \
   69.38 +                        if (hasfpu)                                             \
   69.39 +                        {                                                       \
   69.40 +                                x87_pc_off = oldpc;                             \
   69.41 +                                x87_pc_seg = CS;                                \
   69.42 +                                x87_op_off = eaaddr;                            \
   69.43 +                                x87_op_seg = ea_rseg;                           \
   69.44 +                                x87_ ## num();                                  \
   69.45 +                        }                                                       \
   69.46 +                }                                                               \
   69.47 +                return 0;                                                       \
   69.48 +        }
   69.49 +
   69.50 +opESCAPE(d8);
   69.51 +opESCAPE(d9);
   69.52 +opESCAPE(da);
   69.53 +opESCAPE(db);
   69.54 +opESCAPE(dc);
   69.55 +opESCAPE(dd);
   69.56 +opESCAPE(de);
   69.57 +opESCAPE(df);
   69.58 +
   69.59 +static int opWAIT(uint32_t fetchdat)
   69.60 +{
   69.61 +        cycles -= 4;
   69.62 +        return 0;
   69.63 +}
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/src/x86_ops_inc_dec.h	Mon May 27 19:56:33 2013 +0100
    70.3 @@ -0,0 +1,86 @@
    70.4 +#define INC_DEC_OP(name, reg, inc, setflags) \
    70.5 +        static int op ## name (uint32_t fetchdat)       \
    70.6 +        {                                               \
    70.7 +                setflags(reg, 1);                       \
    70.8 +                reg += inc;                             \
    70.9 +                cycles -= timing_rr;                    \
   70.10 +                return 0;                               \
   70.11 +        }
   70.12 +
   70.13 +INC_DEC_OP(INC_AX, AX, 1, setadd16nc)
   70.14 +INC_DEC_OP(INC_BX, BX, 1, setadd16nc)
   70.15 +INC_DEC_OP(INC_CX, CX, 1, setadd16nc)
   70.16 +INC_DEC_OP(INC_DX, DX, 1, setadd16nc)
   70.17 +INC_DEC_OP(INC_SI, SI, 1, setadd16nc)
   70.18 +INC_DEC_OP(INC_DI, DI, 1, setadd16nc)
   70.19 +INC_DEC_OP(INC_BP, BP, 1, setadd16nc)
   70.20 +INC_DEC_OP(INC_SP, SP, 1, setadd16nc)
   70.21 +
   70.22 +INC_DEC_OP(INC_EAX, EAX, 1, setadd32nc)
   70.23 +INC_DEC_OP(INC_EBX, EBX, 1, setadd32nc)
   70.24 +INC_DEC_OP(INC_ECX, ECX, 1, setadd32nc)
   70.25 +INC_DEC_OP(INC_EDX, EDX, 1, setadd32nc)
   70.26 +INC_DEC_OP(INC_ESI, ESI, 1, setadd32nc)
   70.27 +INC_DEC_OP(INC_EDI, EDI, 1, setadd32nc)
   70.28 +INC_DEC_OP(INC_EBP, EBP, 1, setadd32nc)
   70.29 +INC_DEC_OP(INC_ESP, ESP, 1, setadd32nc)
   70.30 +
   70.31 +INC_DEC_OP(DEC_AX, AX, -1, setsub16nc)
   70.32 +INC_DEC_OP(DEC_BX, BX, -1, setsub16nc)
   70.33 +INC_DEC_OP(DEC_CX, CX, -1, setsub16nc)
   70.34 +INC_DEC_OP(DEC_DX, DX, -1, setsub16nc)
   70.35 +INC_DEC_OP(DEC_SI, SI, -1, setsub16nc)
   70.36 +INC_DEC_OP(DEC_DI, DI, -1, setsub16nc)
   70.37 +INC_DEC_OP(DEC_BP, BP, -1, setsub16nc)
   70.38 +INC_DEC_OP(DEC_SP, SP, -1, setsub16nc)
   70.39 +
   70.40 +INC_DEC_OP(DEC_EAX, EAX, -1, setsub32nc)
   70.41 +INC_DEC_OP(DEC_EBX, EBX, -1, setsub32nc)
   70.42 +INC_DEC_OP(DEC_ECX, ECX, -1, setsub32nc)
   70.43 +INC_DEC_OP(DEC_EDX, EDX, -1, setsub32nc)
   70.44 +INC_DEC_OP(DEC_ESI, ESI, -1, setsub32nc)
   70.45 +INC_DEC_OP(DEC_EDI, EDI, -1, setsub32nc)
   70.46 +INC_DEC_OP(DEC_EBP, EBP, -1, setsub32nc)
   70.47 +INC_DEC_OP(DEC_ESP, ESP, -1, setsub32nc)
   70.48 +
   70.49 +
   70.50 +static int opINCDEC_b_a16(uint32_t fetchdat)
   70.51 +{
   70.52 +        uint8_t temp;
   70.53 +        
   70.54 +        fetch_ea_16(fetchdat);       
   70.55 +        temp=geteab();                  if (abrt) return 0;
   70.56 +
   70.57 +        if (rmdat&0x38)
   70.58 +        {
   70.59 +                seteab(temp - 1);       if (abrt) return 0;
   70.60 +                setsub8nc(temp, 1);
   70.61 +        }
   70.62 +        else
   70.63 +        {
   70.64 +                seteab(temp + 1);       if (abrt) return 0;
   70.65 +                setadd8nc(temp, 1);
   70.66 +        }
   70.67 +        cycles -= (mod == 3) ? timing_rr : timing_mm;
   70.68 +        return 0;
   70.69 +}
   70.70 +static int opINCDEC_b_a32(uint32_t fetchdat)
   70.71 +{
   70.72 +        uint8_t temp;
   70.73 +        
   70.74 +        fetch_ea_32(fetchdat);       
   70.75 +        temp=geteab();                  if (abrt) return 0;
   70.76 +
   70.77 +        if (rmdat&0x38)
   70.78 +        {
   70.79 +                seteab(temp - 1);       if (abrt) return 0;
   70.80 +                setsub8nc(temp, 1);
   70.81 +        }
   70.82 +        else
   70.83 +        {
   70.84 +                seteab(temp + 1);       if (abrt) return 0;
   70.85 +                setadd8nc(temp, 1);
   70.86 +        }
   70.87 +        cycles -= (mod == 3) ? timing_rr : timing_mm;
   70.88 +        return 0;
   70.89 +}
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/src/x86_ops_int.h	Mon May 27 19:56:33 2013 +0100
    71.3 @@ -0,0 +1,46 @@
    71.4 +static int opINT3(uint32_t fetchdat)
    71.5 +{
    71.6 +        oldpc = pc;
    71.7 +        //fatal("INT3\n");
    71.8 +        if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
    71.9 +        {
   71.10 +                x86gpf(NULL,0);
   71.11 +                return 0;
   71.12 +        }
   71.13 +        x86_int_sw(3);
   71.14 +        cycles -= (is486) ? 44 : 59;
   71.15 +        return 0;
   71.16 +}
   71.17 +
   71.18 +static int opINT(uint32_t fetchdat)
   71.19 +{
   71.20 +        uint8_t temp;
   71.21 +        
   71.22 +        /*if (msw&1) pclog("INT %i %i %i\n",cr0&1,eflags&VM_FLAG,IOPL);*/
   71.23 +        if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
   71.24 +        {
   71.25 +                x86gpf(NULL,0);
   71.26 +                return 0;
   71.27 +        }
   71.28 +        temp = getbytef();
   71.29 +        if (temp == 0x10 && AH == 0xe) pclog("INT %02X : %04X %04X %04X %04X   %c   %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc);
   71.30 +        x86_int_sw(temp);
   71.31 +        return 0;
   71.32 +}
   71.33 +
   71.34 +static int opINTO(uint32_t fetchdat)
   71.35 +{
   71.36 +        if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
   71.37 +        {
   71.38 +                x86gpf(NULL,0);
   71.39 +                return 0;
   71.40 +        }
   71.41 +        if (VF_SET())
   71.42 +        {
   71.43 +                oldpc = pc;
   71.44 +                x86_int_sw(4);
   71.45 +        }
   71.46 +        cycles -= 3;
   71.47 +        return 0;
   71.48 +}
   71.49 +
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/src/x86_ops_io.h	Mon May 27 19:56:33 2013 +0100
    72.3 @@ -0,0 +1,110 @@
    72.4 +int opIN_AL_imm(uint32_t fetchdat)
    72.5 +{       
    72.6 +        uint16_t port = (uint16_t)getbytef();
    72.7 +        check_io_perm(port);
    72.8 +        AL = inb(port);
    72.9 +        cycles -= 12;
   72.10 +        return 0;
   72.11 +}
   72.12 +int opIN_AX_imm(uint32_t fetchdat)
   72.13 +{
   72.14 +        uint16_t port = (uint16_t)getbytef();
   72.15 +        check_io_perm(port);
   72.16 +        check_io_perm(port + 1);
   72.17 +        AX = inw(port);
   72.18 +        cycles -= 12;
   72.19 +        return 0;
   72.20 +}
   72.21 +int opIN_EAX_imm(uint32_t fetchdat)
   72.22 +{
   72.23 +        uint16_t port = (uint16_t)getbytef();
   72.24 +        check_io_perm(port);
   72.25 +        check_io_perm(port + 1);
   72.26 +        check_io_perm(port + 2);
   72.27 +        check_io_perm(port + 3);
   72.28 +        EAX = inl(port);
   72.29 +        cycles -= 12;
   72.30 +        return 0;
   72.31 +}
   72.32 +
   72.33 +int opOUT_AL_imm(uint32_t fetchdat)
   72.34 +{
   72.35 +        uint16_t port = (uint16_t)getbytef();        
   72.36 +        check_io_perm(port);
   72.37 +        outb(port, AL);
   72.38 +        cycles -= 10;
   72.39 +        return 0;
   72.40 +}
   72.41 +int opOUT_AX_imm(uint32_t fetchdat)
   72.42 +{
   72.43 +        uint16_t port = (uint16_t)getbytef();        
   72.44 +        check_io_perm(port);
   72.45 +        check_io_perm(port + 1);
   72.46 +        outw(port, AX);
   72.47 +        cycles -= 10;
   72.48 +        return 0;
   72.49 +}
   72.50 +int opOUT_EAX_imm(uint32_t fetchdat)
   72.51 +{
   72.52 +        uint16_t port = (uint16_t)getbytef();        
   72.53 +        check_io_perm(port);
   72.54 +        check_io_perm(port + 1);
   72.55 +        check_io_perm(port + 2);
   72.56 +        check_io_perm(port + 3);
   72.57 +        outl(port, EAX);
   72.58 +        cycles -= 10;
   72.59 +        return 0;
   72.60 +}
   72.61 +
   72.62 +int opIN_AL_DX(uint32_t fetchdat)
   72.63 +{       
   72.64 +        check_io_perm(DX);
   72.65 +        AL = inb(DX);
   72.66 +        cycles -= 12;
   72.67 +        return 0;
   72.68 +}
   72.69 +int opIN_AX_DX(uint32_t fetchdat)
   72.70 +{
   72.71 +        check_io_perm(DX);
   72.72 +        check_io_perm(DX + 1);
   72.73 +        AX = inw(DX);
   72.74 +        cycles -= 12;
   72.75 +        return 0;
   72.76 +}
   72.77 +int opIN_EAX_DX(uint32_t fetchdat)
   72.78 +{
   72.79 +        check_io_perm(DX);
   72.80 +        check_io_perm(DX + 1);
   72.81 +        check_io_perm(DX + 2);
   72.82 +        check_io_perm(DX + 3);
   72.83 +        EAX = inl(DX);
   72.84 +        cycles -= 12;
   72.85 +        return 0;
   72.86 +}
   72.87 +
   72.88 +int opOUT_AL_DX(uint32_t fetchdat)
   72.89 +{
   72.90 +        check_io_perm(DX);
   72.91 +        outb(DX, AL);
   72.92 +        cycles -= 11;
   72.93 +        return 0;
   72.94 +}
   72.95 +int opOUT_AX_DX(uint32_t fetchdat)
   72.96 +{
   72.97 +        //pclog("OUT_AX_DX %04X %04X\n", DX, AX);
   72.98 +        check_io_perm(DX);
   72.99 +        check_io_perm(DX + 1);
  72.100 +        outw(DX, AX);
  72.101 +        cycles -= 11;
  72.102 +        return 0;
  72.103 +}
  72.104 +int opOUT_EAX_DX(uint32_t fetchdat)
  72.105 +{
  72.106 +        check_io_perm(DX);
  72.107 +        check_io_perm(DX + 1);
  72.108 +        check_io_perm(DX + 2);
  72.109 +        check_io_perm(DX + 3);
  72.110 +        outl(DX, EAX);
  72.111 +        cycles -= 11;
  72.112 +        return 0;
  72.113 +}
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/src/x86_ops_jump.h	Mon May 27 19:56:33 2013 +0100
    73.3 @@ -0,0 +1,268 @@
    73.4 +#define cond_O   ( VF_SET())
    73.5 +#define cond_NO  (!VF_SET())
    73.6 +#define cond_B   ( CF_SET())
    73.7 +#define cond_NB  (!CF_SET())
    73.8 +#define cond_E   ( ZF_SET())
    73.9 +#define cond_NE  (!ZF_SET())
   73.10 +#define cond_BE  ( CF_SET() ||  ZF_SET())
   73.11 +#define cond_NBE (!CF_SET() && !ZF_SET())
   73.12 +#define cond_S   ( NF_SET())
   73.13 +#define cond_NS  (!NF_SET())
   73.14 +#define cond_P   ( PF_SET())
   73.15 +#define cond_NP  (!PF_SET())
   73.16 +#define cond_L   (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0))
   73.17 +#define cond_NL  (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0))
   73.18 +#define cond_LE  (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) ||  (ZF_SET()))
   73.19 +#define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET()))
   73.20 +
   73.21 +#define opJ(condition)                                  \
   73.22 +        static int opJ ## condition(uint32_t fetchdat)  \
   73.23 +        {                                               \
   73.24 +                int8_t offset = (int8_t)getbytef();     \
   73.25 +                if (cond_ ## condition)                 \
   73.26 +                {                                       \
   73.27 +                        pc += offset;                   \
   73.28 +                        cycles -= timing_bt;            \
   73.29 +                }                                       \
   73.30 +                cycles -= timing_bnt;                   \
   73.31 +                return 0;                               \
   73.32 +        }                                               \
   73.33 +                                                        \
   73.34 +        static int opJ ## condition ## _w(uint32_t fetchdat)  \
   73.35 +        {                                               \
   73.36 +                int16_t offset = (int16_t)getwordf();   \
   73.37 +                if (cond_ ## condition)                 \
   73.38 +                {                                       \
   73.39 +                        pc += offset;                   \
   73.40 +                        cycles -= timing_bt;            \
   73.41 +                }                                       \
   73.42 +                cycles -= timing_bnt;                   \
   73.43 +                return 0;                               \
   73.44 +        }                                               \
   73.45 +                                                        \
   73.46 +        static int opJ ## condition ## _l(uint32_t fetchdat)  \
   73.47 +        {                                               \
   73.48 +                uint32_t offset = getlong();            \
   73.49 +                if (cond_ ## condition)                 \
   73.50 +                {                                       \
   73.51 +                        pc += offset;                   \
   73.52 +                        cycles -= timing_bt;            \
   73.53 +                }                                       \
   73.54 +                cycles -= timing_bnt;                   \
   73.55 +                return 0;                               \
   73.56 +        }                                               \
   73.57 +        
   73.58 +opJ(O)
   73.59 +opJ(NO)
   73.60 +opJ(B)
   73.61 +opJ(NB)
   73.62 +opJ(E)
   73.63 +opJ(NE)
   73.64 +opJ(BE)
   73.65 +opJ(NBE)
   73.66 +opJ(S)
   73.67 +opJ(NS)
   73.68 +opJ(P)
   73.69 +opJ(NP)
   73.70 +opJ(L)
   73.71 +opJ(NL)
   73.72 +opJ(LE)
   73.73 +opJ(NLE)
   73.74 +
   73.75 +
   73.76 +
   73.77 +static int opLOOPNE_w(uint32_t fetchdat)
   73.78 +{
   73.79 +        int8_t offset = (int8_t)getbytef();
   73.80 +        CX--;
   73.81 +        if (CX && !ZF_SET()) 
   73.82 +                pc += offset;
   73.83 +        cycles -= (is486) ? 7 : 11;
   73.84 +        return 0;
   73.85 +}
   73.86 +static int opLOOPNE_l(uint32_t fetchdat)
   73.87 +{
   73.88 +        int8_t offset = (int8_t)getbytef();
   73.89 +        ECX--;
   73.90 +        if (ECX && !ZF_SET()) 
   73.91 +                pc += offset;
   73.92 +        cycles -= (is486) ? 7 : 11;
   73.93 +        return 0;
   73.94 +}
   73.95 +
   73.96 +static int opLOOPE_w(uint32_t fetchdat)
   73.97 +{
   73.98 +        int8_t offset = (int8_t)getbytef();
   73.99 +        CX--;
  73.100 +        if (CX && ZF_SET()) 
  73.101 +                pc += offset;
  73.102 +        cycles -= (is486) ? 7 : 11;
  73.103 +        return 0;
  73.104 +}
  73.105 +static int opLOOPE_l(uint32_t fetchdat)
  73.106 +{
  73.107 +        int8_t offset = (int8_t)getbytef();
  73.108 +        ECX--;
  73.109 +        if (ECX && ZF_SET()) 
  73.110 +                pc += offset;
  73.111 +        cycles -= (is486) ? 7 : 11;
  73.112 +        return 0;
  73.113 +}
  73.114 +
  73.115 +static int opLOOP_w(uint32_t fetchdat)
  73.116 +{
  73.117 +        int8_t offset = (int8_t)getbytef();
  73.118 +        CX--;
  73.119 +        if (CX)
  73.120 +                pc += offset;
  73.121 +        cycles -= (is486) ? 7 : 11;
  73.122 +        return 0;
  73.123 +}
  73.124 +static int opLOOP_l(uint32_t fetchdat)
  73.125 +{
  73.126 +        int8_t offset = (int8_t)getbytef();
  73.127 +        ECX--;
  73.128 +        if (ECX)
  73.129 +                pc += offset;
  73.130 +        cycles -= (is486) ? 7 : 11;
  73.131 +        return 0;
  73.132 +}
  73.133 +
  73.134 +static int opJCXZ(uint32_t fetchdat)
  73.135 +{
  73.136 +        int8_t offset = (int8_t)getbytef();
  73.137 +        if (!CX)
  73.138 +        {
  73.139 +                pc += offset;
  73.140 +                cycles -= 4;
  73.141 +        }
  73.142 +        cycles -= 5;
  73.143 +        return 0;
  73.144 +}
  73.145 +static int opJECXZ(uint32_t fetchdat)
  73.146 +{
  73.147 +        int8_t offset = (int8_t)getbytef();
  73.148 +        if (!ECX)
  73.149 +        {
  73.150 +                pc += offset;
  73.151 +                cycles -= 4;
  73.152 +        }
  73.153 +        cycles -= 5;
  73.154 +        return 0;
  73.155 +}
  73.156 +
  73.157 +
  73.158 +static int opJMP_r8(uint32_t fetchdat)
  73.159 +{
  73.160 +        int8_t offset = (int8_t)getbytef();
  73.161 +        pc += offset;
  73.162 +        cycles -= (is486) ? 3 : 7;
  73.163 +        return 0;
  73.164 +}
  73.165 +static int opJMP_r16(uint32_t fetchdat)
  73.166 +{
  73.167 +        int16_t offset = (int16_t)getwordf();
  73.168 +        pc += offset;
  73.169 +        cycles -= (is486) ? 3 : 7;
  73.170 +        return 0;
  73.171 +}
  73.172 +static int opJMP_r32(uint32_t fetchdat)
  73.173 +{
  73.174 +        int32_t offset = (int32_t)getlong();            if (abrt) return 0;
  73.175 +        pc += offset;
  73.176 +        cycles -= (is486) ? 3 : 7;
  73.177 +        return 0;
  73.178 +}
  73.179 +
  73.180 +static int opJMP_far_a16(uint32_t fetchdat)
  73.181 +{
  73.182 +        uint16_t addr = getwordf();
  73.183 +        uint16_t seg = getword();                       if (abrt) return 0;
  73.184 +        uint32_t oxpc = pc;
  73.185 +        pc = addr;
  73.186 +        loadcsjmp(seg, oxpc);
  73.187 +        cycles -= (is486) ? 17 : 12;
  73.188 +        return 0;
  73.189 +}
  73.190 +static int opJMP_far_a32(uint32_t fetchdat)
  73.191 +{
  73.192 +        uint32_t addr = getlong();
  73.193 +        uint16_t seg = getword();                       if (abrt) return 0;
  73.194 +        uint32_t oxpc = pc;
  73.195 +        pc = addr;
  73.196 +        loadcsjmp(seg, oxpc);
  73.197 +        cycles -= (is486) ? 17 : 12;
  73.198 +        return 0;
  73.199 +}
  73.200 +
  73.201 +int opCALL_r16(uint32_t fetchdat)
  73.202 +{
  73.203 +        int16_t addr = (int16_t)getwordf();
  73.204 +        if (ssegs) ss=oldss;
  73.205 +        PUSH_W(pc);
  73.206 +        pc += addr;
  73.207 +        cycles -= (is486) ? 3 : 7;
  73.208 +        return 0;
  73.209 +}
  73.210 +int opCALL_r32(uint32_t fetchdat)
  73.211 +{
  73.212 +        int32_t addr = getlong();                       if (abrt) return 0;       
  73.213 +        if (ssegs) ss=oldss;
  73.214 +        PUSH_L(pc);
  73.215 +        pc += addr;
  73.216 +        cycles -= (is486) ? 3 : 7;
  73.217 +        return 0;
  73.218 +}
  73.219 +
  73.220 +int opRET_w(uint32_t fetchdat)
  73.221 +{
  73.222 +        uint16_t ret;
  73.223 +        
  73.224 +        if (ssegs) ss=oldss;        
  73.225 +        ret = POP_W();                          if (abrt) return 0;
  73.226 +        pc = ret;
  73.227 +        
  73.228 +        cycles -= (is486) ? 5 : 10;
  73.229 +        return 0;
  73.230 +}
  73.231 +int opRET_l(uint32_t fetchdat)
  73.232 +{
  73.233 +        uint32_t ret;
  73.234 +
  73.235 +        if (ssegs) ss=oldss;        
  73.236 +        ret = POP_L();                          if (abrt) return 0;
  73.237 +        pc = ret;
  73.238 +        
  73.239 +        cycles -= (is486) ? 5 : 10;
  73.240 +        return 0;
  73.241 +}
  73.242 +
  73.243 +int opRET_w_imm(uint32_t fetchdat)
  73.244 +{
  73.245 +        uint16_t offset = getwordf();
  73.246 +        uint16_t ret;
  73.247 +
  73.248 +        if (ssegs) ss=oldss;       
  73.249 +        ret = POP_W();                          if (abrt) return 0;
  73.250 +        if (stack32) ESP += offset;
  73.251 +        else          SP += offset;       
  73.252 +        pc = ret;
  73.253 +        
  73.254 +        cycles -= (is486) ? 5 : 10;
  73.255 +        return 0;
  73.256 +}
  73.257 +int opRET_l_imm(uint32_t fetchdat)
  73.258 +{
  73.259 +        uint16_t offset = getwordf();
  73.260 +        uint32_t ret;
  73.261 +
  73.262 +        if (ssegs) ss=oldss;        
  73.263 +        ret = POP_L();                          if (abrt) return 0;
  73.264 +        if (stack32) ESP += offset;
  73.265 +        else          SP += offset;       
  73.266 +        pc = ret;
  73.267 +        
  73.268 +        cycles -= (is486) ? 5 : 10;
  73.269 +        return 0;
  73.270 +}
  73.271 +
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/src/x86_ops_misc.h	Mon May 27 19:56:33 2013 +0100
    74.3 @@ -0,0 +1,678 @@
    74.4 +static int opCBW(uint32_t fetchdat)
    74.5 +{
    74.6 +        AH = (AL & 0x80) ? 0xff : 0;
    74.7 +        cycles -= 3;
    74.8 +        return 0;
    74.9 +}
   74.10 +static int opCWDE(uint32_t fetchdat)
   74.11 +{
   74.12 +        EAX = (AX & 0x8000) ? (0xffff0000 | AX) : AX;
   74.13 +        cycles -= 3;
   74.14 +        return 0;
   74.15 +}
   74.16 +static int opCWD(uint32_t fetchdat)
   74.17 +{
   74.18 +        DX = (AX & 0x8000) ? 0xFFFF : 0;
   74.19 +        cycles -= 2;
   74.20 +        return 0;
   74.21 +}
   74.22 +static int opCDQ(uint32_t fetchdat)
   74.23 +{
   74.24 +        EDX = (EAX & 0x80000000) ? 0xffffffff : 0;
   74.25 +        cycles -= 2;
   74.26 +        return 0;
   74.27 +}
   74.28 +
   74.29 +static int opNOP(uint32_t fetchdat)
   74.30 +{
   74.31 +        cycles -= (is486) ? 1 : 3;
   74.32 +        return 0;
   74.33 +}
   74.34 +
   74.35 +static int opSETALC(uint32_t fetchdat)
   74.36 +{
   74.37 +        AL = (CF_SET()) ? 0xff : 0;
   74.38 +        cycles -= timing_rr;
   74.39 +        return 0;
   74.40 +}
   74.41 +
   74.42 +
   74.43 +
   74.44 +static int opF6_a16(uint32_t fetchdat)
   74.45 +{
   74.46 +        int tempws, tempws2;
   74.47 +        uint16_t tempw, src16;
   74.48 +        uint8_t src, dst;
   74.49 +        int8_t temps;
   74.50 +        
   74.51 +        fetch_ea_16(fetchdat);
   74.52 +        dst = geteab();                 if (abrt) return 0;
   74.53 +        switch (rmdat & 0x38)
   74.54 +        {
   74.55 +                case 0x00: /*TEST b,#8*/
   74.56 +                src = readmemb(cs, pc); pc++;           if (abrt) return 0;
   74.57 +                setznp8(src & dst);
   74.58 +                if (is486) cycles -= ((mod == 3) ? 1 : 2);
   74.59 +                else       cycles -= ((mod == 3) ? 2 : 5);
   74.60 +                break;
   74.61 +                case 0x10: /*NOT b*/
   74.62 +                seteab(~dst);
   74.63 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
   74.64 +                break;
   74.65 +                case 0x18: /*NEG b*/
   74.66 +                setsub8(0, dst);
   74.67 +                seteab(0 - dst);
   74.68 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
   74.69 +                break;
   74.70 +                case 0x20: /*MUL AL,b*/
   74.71 +                AX = AL * dst;
   74.72 +                flags_rebuild();
   74.73 +                if (AH) flags |=  (C_FLAG | V_FLAG);
   74.74 +                else    flags &= ~(C_FLAG | V_FLAG);
   74.75 +                cycles -= 13;
   74.76 +                break;
   74.77 +                case 0x28: /*IMUL AL,b*/
   74.78 +                tempws = (int)((int8_t)AL) * (int)((int8_t)dst);
   74.79 +                AX = tempws & 0xffff;
   74.80 +                flags_rebuild();
   74.81 +                if (AH && AH != 0xff) flags |=  (C_FLAG | V_FLAG);
   74.82 +                else                  flags &= ~(C_FLAG | V_FLAG);
   74.83 +                cycles -= 14;
   74.84 +                break;
   74.85 +                case 0x30: /*DIV AL,b*/
   74.86 +                src16 = AX;
   74.87 +                if (dst) tempw = src16 / dst;
   74.88 +                if (dst && !(tempw & 0xff00))
   74.89 +                {
   74.90 +                        AH = src16 % dst;
   74.91 +                        AL = (src16 / dst) &0xff;
   74.92 +                        if (!cpu_iscyrix) 
   74.93 +                        {
   74.94 +                                flags_rebuild();
   74.95 +                                flags |= 0x8D5; /*Not a Cyrix*/
   74.96 +                        }
   74.97 +                }
   74.98 +                else
   74.99 +                {
  74.100 +                        x86_int(0);
  74.101 +                }
  74.102 +                cycles -= is486 ? 16 : 14;
  74.103 +                break;
  74.104 +                case 0x38: /*IDIV AL,b*/
  74.105 +                tempws = (int)(int16_t)AX;
  74.106 +                if (dst != 0) tempws2 = tempws / (int)((int8_t)dst);
  74.107 +                temps = tempws2 & 0xff;
  74.108 +                if (dst && ((int)temps == tempws2))
  74.109 +                {
  74.110 +                        AH = (tempws % (int)((int8_t)dst)) & 0xff;
  74.111 +                        AL = tempws2 & 0xff;
  74.112 +                        if (!cpu_iscyrix) 
  74.113 +                        {
  74.114 +                                flags_rebuild();
  74.115 +                                flags|=0x8D5; /*Not a Cyrix*/
  74.116 +                        }
  74.117 +                }
  74.118 +                else
  74.119 +                {
  74.120 +//                        pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2);
  74.121 +                        x86_int(0);
  74.122 +                }
  74.123 +                cycles -= 19;
  74.124 +                break;
  74.125 +
  74.126 +                default:
  74.127 +                pclog("Bad F6 opcode %02X\n", rmdat & 0x38);
  74.128 +                x86illegal();
  74.129 +        }
  74.130 +        return 0;
  74.131 +}
  74.132 +static int opF6_a32(uint32_t fetchdat)
  74.133 +{
  74.134 +        int tempws, tempws2;
  74.135 +        uint16_t tempw, src16;
  74.136 +        uint8_t src, dst;
  74.137 +        int8_t temps;
  74.138 +        
  74.139 +        fetch_ea_32(fetchdat);
  74.140 +        dst = geteab();                 if (abrt) return 0;
  74.141 +        switch (rmdat & 0x38)
  74.142 +        {
  74.143 +                case 0x00: /*TEST b,#8*/
  74.144 +                src = readmemb(cs, pc); pc++;           if (abrt) return 0;
  74.145 +                setznp8(src & dst);
  74.146 +                if (is486) cycles -= ((mod == 3) ? 1 : 2);
  74.147 +                else       cycles -= ((mod == 3) ? 2 : 5);
  74.148 +                break;
  74.149 +                case 0x10: /*NOT b*/
  74.150 +                seteab(~dst);
  74.151 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  74.152 +                break;
  74.153 +                case 0x18: /*NEG b*/
  74.154 +                setsub8(0, dst);
  74.155 +                seteab(0 - dst);
  74.156 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  74.157 +                break;
  74.158 +                case 0x20: /*MUL AL,b*/
  74.159 +                AX = AL * dst;
  74.160 +                flags_rebuild();
  74.161 +                if (AH) flags |=  (C_FLAG | V_FLAG);
  74.162 +                else    flags &= ~(C_FLAG | V_FLAG);
  74.163 +                cycles -= 13;
  74.164 +                break;
  74.165 +                case 0x28: /*IMUL AL,b*/
  74.166 +                tempws = (int)((int8_t)AL) * (int)((int8_t)dst);
  74.167 +                AX = tempws & 0xffff;
  74.168 +                flags_rebuild();
  74.169 +                if (AH && AH != 0xff) flags |=  (C_FLAG | V_FLAG);
  74.170 +                else                  flags &= ~(C_FLAG | V_FLAG);
  74.171 +                cycles -= 14;
  74.172 +                break;
  74.173 +                case 0x30: /*DIV AL,b*/
  74.174 +                src16 = AX;
  74.175 +                if (dst) tempw = src16 / dst;
  74.176 +                if (dst && !(tempw & 0xff00))
  74.177 +                {
  74.178 +                        AH = src16 % dst;
  74.179 +                        AL = (src16 / dst) &0xff;
  74.180 +                        if (!cpu_iscyrix) 
  74.181 +                        {
  74.182 +                                flags_rebuild();
  74.183 +                                flags |= 0x8D5; /*Not a Cyrix*/
  74.184 +                        }
  74.185 +                }
  74.186 +                else
  74.187 +                {
  74.188 +                        x86_int(0);
  74.189 +                }
  74.190 +                cycles -= is486 ? 16 : 14;
  74.191 +                break;
  74.192 +                case 0x38: /*IDIV AL,b*/
  74.193 +                tempws = (int)(int16_t)AX;
  74.194 +                if (dst != 0) tempws2 = tempws / (int)((int8_t)dst);
  74.195 +                temps = tempws2 & 0xff;
  74.196 +                if (dst && ((int)temps == tempws2))
  74.197 +                {
  74.198 +                        AH = (tempws % (int)((int8_t)dst)) & 0xff;
  74.199 +                        AL = tempws2 & 0xff;
  74.200 +                        if (!cpu_iscyrix) 
  74.201 +                        {
  74.202 +                                flags_rebuild();
  74.203 +                                flags|=0x8D5; /*Not a Cyrix*/
  74.204 +                        }
  74.205 +                }
  74.206 +                else
  74.207 +                {
  74.208 +//                        pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2);
  74.209 +                        x86_int(0);
  74.210 +                }
  74.211 +                cycles -= 19;
  74.212 +                break;
  74.213 +
  74.214 +                default:
  74.215 +                pclog("Bad F6 opcode %02X\n", rmdat & 0x38);
  74.216 +                x86illegal();
  74.217 +        }
  74.218 +        return 0;
  74.219 +}
  74.220 +
  74.221 +
  74.222 +
  74.223 +static int opF7_w_a16(uint32_t fetchdat)
  74.224 +{
  74.225 +        uint32_t templ, templ2;
  74.226 +        int tempws, tempws2;
  74.227 +        int16_t temps16;
  74.228 +        uint16_t src, dst;
  74.229 +        
  74.230 +        fetch_ea_16(fetchdat);
  74.231 +        dst = geteaw();        if (abrt) return 0;
  74.232 +        switch (rmdat & 0x38)
  74.233 +        {
  74.234 +                case 0x00: /*TEST w*/
  74.235 +                src = getword();        if (abrt) return 0;
  74.236 +                setznp16(src & dst);
  74.237 +                if (is486) cycles -= ((mod == 3) ? 1 : 2);
  74.238 +                else       cycles -= ((mod == 3) ? 2 : 5);
  74.239 +                break;
  74.240 +                case 0x10: /*NOT w*/
  74.241 +                seteaw(~dst);
  74.242 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  74.243 +                break;
  74.244 +                case 0x18: /*NEG w*/
  74.245 +                setsub16(0, dst);
  74.246 +                seteaw(0 - dst);
  74.247 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  74.248 +                break;
  74.249 +                case 0x20: /*MUL AX,w*/
  74.250 +                templ = AX * dst;
  74.251 +                AX = templ & 0xFFFF;
  74.252 +                DX = templ >> 16;
  74.253 +                flags_rebuild();
  74.254 +                if (DX)    flags |=  (C_FLAG | V_FLAG);
  74.255 +                else       flags &= ~(C_FLAG | V_FLAG);
  74.256 +                cycles -= 21;
  74.257 +                break;
  74.258 +                case 0x28: /*IMUL AX,w*/
  74.259 +                templ = (int)((int16_t)AX) * (int)((int16_t)dst);
  74.260 +                AX = templ & 0xFFFF;
  74.261 +                DX = templ >> 16;
  74.262 +                flags_rebuild();
  74.263 +                if (DX && DX != 0xFFFF) flags |=  (C_FLAG | V_FLAG);
  74.264 +                else                    flags &= ~(C_FLAG | V_FLAG);
  74.265 +                cycles -= 22;
  74.266 +                break;
  74.267 +                case 0x30: /*DIV AX,w*/
  74.268 +                templ = (DX << 16) | AX;
  74.269 +                if (dst) templ2 = templ / dst;
  74.270 +                if (dst && !(templ2 & 0xffff0000))
  74.271 +                {
  74.272 +                        DX = templ % dst;
  74.273 +                        AX = (templ / dst) & 0xffff;
  74.274 +                        if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/                                                
  74.275 +                }
  74.276 +                else
  74.277 +                {
  74.278 +//                        fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins);
  74.279 +                        x86_int(0);
  74.280 +                }
  74.281 +                cycles -=  is486 ? 24 : 22;
  74.282 +                break;
  74.283 +                case 0x38: /*IDIV AX,w*/
  74.284 +                tempws = (int)((DX << 16)|AX);
  74.285 +                if (dst) tempws2 = tempws / (int)((int16_t)dst);
  74.286 +                temps16 = tempws2 & 0xffff;
  74.287 +                if ((dst != 0) && ((int)temps16 == tempws2))
  74.288 +                {
  74.289 +                        DX = tempws % (int)((int16_t)dst);
  74.290 +                        AX = tempws2 & 0xffff;
  74.291 +                        if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/
  74.292 +                }
  74.293 +                else
  74.294 +                {
  74.295 +//                        pclog("IDIVw exception - %X / %08X = %X\n",tempws, dst, tempws2);
  74.296 +                        x86_int(0);
  74.297 +                }
  74.298 +                cycles -= 27;
  74.299 +                break;
  74.300 +
  74.301 +                default:
  74.302 +                pclog("Bad F7 opcode %02X\n", rmdat & 0x38);
  74.303 +                x86illegal();
  74.304 +        }
  74.305 +        return 0;
  74.306 +}
  74.307 +static int opF7_w_a32(uint32_t fetchdat)
  74.308 +{
  74.309 +        uint32_t templ, templ2;
  74.310 +        int tempws, tempws2;
  74.311 +        int16_t temps16;
  74.312 +        uint16_t src, dst;
  74.313 +
  74.314 +        fetch_ea_32(fetchdat);
  74.315 +        dst = geteaw();        if (abrt) return 0;
  74.316 +        switch (rmdat & 0x38)
  74.317 +        {
  74.318 +                case 0x00: /*TEST w*/
  74.319 +                src = getword();        if (abrt) return 0;
  74.320 +                setznp16(src & dst);
  74.321 +                if (is486) cycles -= ((mod == 3) ? 1 : 2);
  74.322 +                else       cycles -= ((mod == 3) ? 2 : 5);
  74.323 +                break;
  74.324 +                case 0x10: /*NOT w*/
  74.325 +                seteaw(~dst);
  74.326 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  74.327 +                break;
  74.328 +                case 0x18: /*NEG w*/
  74.329 +                setsub16(0, dst);
  74.330 +                seteaw(0 - dst);
  74.331 +                cycles -= (mod == 3) ? timing_rr : timing_mm;
  74.332 +                break;
  74.333 +                case 0x20: /*MUL AX,w*/
  74.334 +                templ = AX * dst;
  74.335 +                AX = templ & 0xFFFF;
  74.336 +                DX = templ >> 16;
  74.337 +                flags_rebuild();
  74.338 +                if (DX)    flags |=  (C_FLAG | V_FLAG);
  74.339 +                else       flags &= ~(C_FLAG | V_FLAG);
  74.340 +                cycles -= 21;
  74.341 +                break;
  74.342 +                case 0x28: /*IMUL AX,w*/
  74.343 +                templ = (int)((int16_t)AX) * (int)((int16_t)dst);
  74.344 +                AX = templ & 0xFFFF;
  74.345 +                DX = templ >> 16;
  74.346 +                flags_rebuild();
  74.347 +                if (DX && DX != 0xFFFF) flags |=  (C_FLAG | V_FLAG);
  74.348 +                else                    flags &= ~(C_FLAG | V_FLAG);
  74.349 +                cycles -= 22;
  74.350 +                break;
  74.351 +                case 0x30: /*DIV AX,w*/
  74.352 +                templ = (DX << 16) | AX;
  74.353 +                if (dst) templ2 = templ / dst;
  74.354 +                if (dst && !(templ2 & 0xffff0000))
  74.355 +                {
  74.356 +                        DX = templ % dst;
  74.357 +                        AX = (templ / dst) & 0xffff;
  74.358 +                        if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/                                                
  74.359 +                }
  74.360 +                else
  74.361 +                {
  74.362 +//                        fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins);
  74.363 +                        x86_int(0);
  74.364 +                }
  74.365 +                cycles -=  is486 ? 24 : 22;
  74.366 +                break;
  74.367 +                case 0x38: /*IDIV AX,w*/
  74.368 +                tempws = (int)((DX << 16)|AX);
  74.369 +                if (dst) tempws2 = tempws / (int)((int16_t)dst);
  74.370 +                temps16 = tempws2 & 0xffff;
  74.371 +                if ((dst != 0) && ((int)temps16 == tempws2))
  74.372 +                {
  74.373 +                        DX = tempws % (int)((int16_t)dst);
  74.374 +                        AX = tempws2 & 0xffff;
  74.375 +                        if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/
  74.376 +                }
  74.377 +                else
  74.378 +                {
  74.379 +//                        pclog("IDIVw exception - %X / %08X = %X\n", tempws, dst, tempws2);
  74.380 +                        x86_int(0);
  74.381 +                }
  74.382 +                cycles -= 27;
  74.383 +                break;
  74.384 +
  74.385 +                default:
  74.386 +                pclog("Bad F7 opcode %02X\n", rmdat & 0x38);
  74.387 +                x86illegal();
  74.388 +        }
  74.389 +        return 0;
  74.390 +}
  74.391 +
  74.392 +static int opF7_l_a16(uint32_t fetchdat)
  74.393 +{
  74.394 +        uint64_t temp64;
  74.395 +        uint32_t src, dst;
  74.396 +
  74.397 +        fetch_ea_16(fetchdat);
  74.398 +        dst = geteal();                 if (abrt) return 0;
  74.399 +
  74.400 +        switch (rmdat & 0x38)
  74.401 +        {
  74.402 +                case 0x00: /*TEST l*/
  74.403 +                src = getlong();        if (abrt) return 0;
  74.404 +                setznp32(src & dst);
  74.405 +                if (is486) cycles -= ((mod == 3) ? 1 : 2);
  74.406 +                else       cycles -= ((mod == 3) ? 2 : 5);
  74.407 +                break;
  74.408 +                case 0x10: /*NOT l*/
  74.409 +                seteal(~dst);
  74.410 +                cycles -= (mod == 3) ? timing_rr : timing_mml;
  74.411 +                break;
  74.412 +                case 0x18: /*NEG l*/
  74.413 +                setsub32(0, dst);
  74.414 +                seteal(0 - dst);
  74.415 +                cycles -= (mod == 3) ? timing_rr : timing_mml;
  74.416 +                break;
  74.417 +                case 0x20: /*MUL EAX,l*/
  74.418 +                temp64 = (uint64_t)EAX * (uint64_t)dst;
  74.419 +                EAX = temp64 & 0xffffffff;
  74.420 +                EDX = temp64 >> 32;
  74.421 +                flags_rebuild();
  74.422 +                if (EDX) flags |=  (C_FLAG|V_FLAG);
  74.423 +                else     flags &= ~(C_FLAG|V_FLAG);
  74.424 +                cycles -= 21;
  74.425 +                break;
  74.426 +                case 0x28: /*IMUL EAX,l*/
  74.427 +                temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst;
  74.428 +                EAX = temp64 & 0xffffffff;
  74.429 +                EDX = temp64 >> 32;
  74.430 +                flags_rebuild();
  74.431 +                if (EDX && EDX != 0xffffffff) flags |=  (C_FLAG|V_FLAG);
  74.432 +                else                          flags &= ~(C_FLAG|V_FLAG);
  74.433 +                cycles -= 38;
  74.434 +                break;
  74.435 +                case 0x30: /*DIV EAX,l*/
  74.436 +                divl(dst);
  74.437 +                if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/
  74.438 +                cycles -= (is486) ? 40 : 38;
  74.439 +                break;
  74.440 +                case 0x38: /*IDIV EAX,l*/
  74.441 +                idivl((int32_t)dst);
  74.442 +                if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/
  74.443 +                cycles -= 43;
  74.444 +                break;
  74.445 +
  74.446 +                default:
  74.447 +                pclog("Bad F7 opcode %02X\n", rmdat & 0x38);
  74.448 +                x86illegal();
  74.449 +        }
  74.450 +        return 0;
  74.451 +}
  74.452 +static int opF7_l_a32(uint32_t fetchdat)
  74.453 +{
  74.454 +        uint64_t temp64;
  74.455 +        uint32_t src, dst;
  74.456 +
  74.457 +        fetch_ea_32(fetchdat);
  74.458 +        dst = geteal();                 if (abrt) return 0;
  74.459 +
  74.460 +        switch (rmdat & 0x38)
  74.461 +        {
  74.462 +                case 0x00: /*TEST l*/
  74.463 +                src = getlong();        if (abrt) return 0;
  74.464 +                setznp32(src & dst);
  74.465 +                if (is486) cycles -= ((mod == 3) ? 1 : 2);
  74.466 +                else       cycles -= ((mod == 3) ? 2 : 5);
  74.467 +                break;
  74.468 +                case 0x10: /*NOT l*/
  74.469 +                seteal(~dst);
  74.470 +                cycles -= (mod == 3) ? timing_rr : timing_mml;
  74.471 +                break;
  74.472 +                case 0x18: /*NEG l*/
  74.473 +                setsub32(0, dst);
  74.474 +                seteal(0 - dst);
  74.475 +                cycles -= (mod == 3) ? timing_rr : timing_mml;
  74.476 +                break;
  74.477 +                case 0x20: /*MUL EAX,l*/
  74.478 +                temp64 = (uint64_t)EAX * (uint64_t)dst;
  74.479 +                EAX = temp64 & 0xffffffff;
  74.480 +                EDX = temp64 >> 32;
  74.481 +                flags_rebuild();
  74.482 +                if (EDX) flags |=  (C_FLAG|V_FLAG);
  74.483 +                else     flags &= ~(C_FLAG|V_FLAG);
  74.484 +                cycles -= 21;
  74.485 +                break;
  74.486 +                case 0x28: /*IMUL EAX,l*/
  74.487 +                temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst;
  74.488 +                EAX = temp64 & 0xffffffff;
  74.489 +                EDX = temp64 >> 32;
  74.490 +                flags_rebuild();
  74.491 +                if (EDX && EDX != 0xffffffff) flags |=  (C_FLAG|V_FLAG);
  74.492 +                else                          flags &= ~(C_FLAG|V_FLAG);
  74.493 +                cycles -= 38;
  74.494 +                break;
  74.495 +                case 0x30: /*DIV EAX,l*/
  74.496 +                divl(dst);
  74.497 +                if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/
  74.498 +                cycles -= (is486) ? 40 : 38;
  74.499 +                break;
  74.500 +                case 0x38: /*IDIV EAX,l*/
  74.501 +                idivl((int32_t)dst);
  74.502 +                if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/
  74.503 +                cycles -= 43;
  74.504 +                break;
  74.505 +
  74.506 +                default:
  74.507 +                pclog("Bad F7 opcode %02X\n", rmdat & 0x38);
  74.508 +                x86illegal();
  74.509 +        }
  74.510 +        return 0;
  74.511 +}
  74.512 +
  74.513 +
  74.514 +static int opHLT(uint32_t fetchdat)
  74.515 +{
  74.516 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
  74.517 +        {
  74.518 +                x86gpf(NULL,0);
  74.519 +                return 0;
  74.520 +        }
  74.521 +        if (!((flags&I_FLAG) && pic_intpending && !ssegs)) 
  74.522 +        {
  74.523 +                cycles -= 100;
  74.524 +                pc--;
  74.525 +        }
  74.526 +        else
  74.527 +                cycles -= 5;
  74.528 +        return 0;
  74.529 +}
  74.530 +
  74.531 +
  74.532 +static int opLOCK(uint32_t fetchdat)
  74.533 +{
  74.534 +        cycles -= 4;
  74.535 +        return 0;
  74.536 +}
  74.537 +
  74.538 +
  74.539 +
  74.540 +static int opBOUND_w_a16(uint32_t fetchdat)
  74.541 +{       
  74.542 +        int16_t low, high;
  74.543 +        
  74.544 +        fetch_ea_16(fetchdat);
  74.545 +        low = geteaw();
  74.546 +        high = readmemw(easeg, eaaddr + 2);     if (abrt) return 0;
  74.547 +        
  74.548 +        if (((int16_t)regs[reg].w < low) || ((int16_t)regs[reg].w > high))
  74.549 +        {
  74.550 +                x86_int(5);
  74.551 +        }
  74.552 +        
  74.553 +        cycles -= is486 ? 7 : 10;
  74.554 +        return 0;
  74.555 +}
  74.556 +static int opBOUND_w_a32(uint32_t fetchdat)
  74.557 +{       
  74.558 +        int16_t low, high;
  74.559 +        
  74.560 +        fetch_ea_32(fetchdat);
  74.561 +        low = geteaw();
  74.562 +        high = readmemw(easeg, eaaddr + 2);     if (abrt) return 0;
  74.563 +        
  74.564 +        if (((int16_t)regs[reg].w < low) || ((int16_t)regs[reg].w > high))
  74.565 +        {
  74.566 +                x86_int(5);
  74.567 +        }
  74.568 +        
  74.569 +        cycles -= is486 ? 7 : 10;
  74.570 +        return 0;
  74.571 +}
  74.572 +
  74.573 +static int opBOUND_l_a16(uint32_t fetchdat)
  74.574 +{       
  74.575 +        int32_t low, high;
  74.576 +        
  74.577 +        fetch_ea_16(fetchdat);
  74.578 +        low = geteal();
  74.579 +        high = readmeml(easeg, eaaddr + 4);     if (abrt) return 0;
  74.580 +        
  74.581 +        if (((int32_t)regs[reg].l < low) || ((int32_t)regs[reg].l > high))
  74.582 +        {
  74.583 +                x86_int(5);
  74.584 +        }
  74.585 +        
  74.586 +        cycles -= is486 ? 7 : 10;
  74.587 +        return 0;
  74.588 +}
  74.589 +static int opBOUND_l_a32(uint32_t fetchdat)
  74.590 +{       
  74.591 +        int32_t low, high;
  74.592 +        
  74.593 +        fetch_ea_32(fetchdat);
  74.594 +        low = geteal();
  74.595 +        high = readmeml(easeg, eaaddr + 4);     if (abrt) return 0;
  74.596 +        
  74.597 +        if (((int32_t)regs[reg].l < low) || ((int32_t)regs[reg].l > high))
  74.598 +        {
  74.599 +                x86_int(5);
  74.600 +        }
  74.601 +        
  74.602 +        cycles -= is486 ? 7 : 10;
  74.603 +        return 0;
  74.604 +}
  74.605 +
  74.606 +
  74.607 +static int opCLTS(uint32_t fetchdat)
  74.608 +{
  74.609 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
  74.610 +        {
  74.611 +                pclog("Can't CLTS\n");
  74.612 +                x86gpf(NULL,0);
  74.613 +                return 0;
  74.614 +        }
  74.615 +        cr0 &= ~8;
  74.616 +        cycles -= 5;
  74.617 +        return 0;
  74.618 +}
  74.619 +
  74.620 +static int opINVD(uint32_t fetchdat)
  74.621 +{
  74.622 +        if (!is486) 
  74.623 +        {
  74.624 +                x86illegal();
  74.625 +                return 0;
  74.626 +        }
  74.627 +        cycles -= 1000;
  74.628 +        return 0;
  74.629 +}
  74.630 +static int opWBINVD(uint32_t fetchdat)
  74.631 +{
  74.632 +        if (!is486) 
  74.633 +        {
  74.634 +                x86illegal();
  74.635 +                return 0;
  74.636 +        }
  74.637 +        cycles -= 10000;
  74.638 +        return 0;
  74.639 +}
  74.640 +
  74.641 +
  74.642 +
  74.643 +static int opLOADALL(uint32_t fetchdat)
  74.644 +{
  74.645 +        flags = (readmemw(0, 0x818) & 0xffd5) | 2;
  74.646 +        flags_extract();
  74.647 +        pc = readmemw(0, 0x81A);
  74.648 +        DS = readmemw(0, 0x81E);
  74.649 +        SS = readmemw(0, 0x820);
  74.650 +        CS = readmemw(0, 0x822);
  74.651 +        ES = readmemw(0, 0x824);
  74.652 +        DI = readmemw(0, 0x826);
  74.653 +        SI = readmemw(0, 0x828);
  74.654 +        BP = readmemw(0, 0x82A);
  74.655 +        SP = readmemw(0, 0x82C);
  74.656 +        BX = readmemw(0, 0x82E);
  74.657 +        DX = readmemw(0, 0x830);
  74.658 +        CX = readmemw(0, 0x832);
  74.659 +        AX = readmemw(0, 0x834);
  74.660 +        es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16);
  74.661 +        cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16);
  74.662 +        ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16);
  74.663 +        ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16);
  74.664 +        cycles-=195;
  74.665 +        return 0;
  74.666 +}                                
  74.667 +
  74.668 +static int opCPUID(uint32_t fetchdat)
  74.669 +{
  74.670 +        if (CPUID)
  74.671 +        {
  74.672 +                cpu_CPUID();
  74.673 +                cycles -= 9;
  74.674 +                return 0;
  74.675 +        }
  74.676 +        pc = oldpc;
  74.677 +        x86illegal();
  74.678 +        return 0;
  74.679 +}
  74.680 +
  74.681 +        
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/src/x86_ops_mov.h	Mon May 27 19:56:33 2013 +0100
    75.3 @@ -0,0 +1,559 @@
    75.4 +static int opMOV_AL_imm(uint32_t fetchdat)
    75.5 +{
    75.6 +        AL = getbytef();
    75.7 +        cycles -= timing_rr;
    75.8 +        return 0;
    75.9 +}
   75.10 +static int opMOV_AH_imm(uint32_t fetchdat)
   75.11 +{
   75.12 +        AH = getbytef();
   75.13 +        cycles -= timing_rr;
   75.14 +        return 0;
   75.15 +}
   75.16 +static int opMOV_BL_imm(uint32_t fetchdat)
   75.17 +{
   75.18 +        BL = getbytef();
   75.19 +        cycles -= timing_rr;
   75.20 +        return 0;
   75.21 +}
   75.22 +static int opMOV_BH_imm(uint32_t fetchdat)
   75.23 +{
   75.24 +        BH = getbytef();
   75.25 +        cycles -= timing_rr;
   75.26 +        return 0;
   75.27 +}
   75.28 +static int opMOV_CL_imm(uint32_t fetchdat)
   75.29 +{
   75.30 +        CL = getbytef();
   75.31 +        cycles -= timing_rr;
   75.32 +        return 0;
   75.33 +}
   75.34 +static int opMOV_CH_imm(uint32_t fetchdat)
   75.35 +{
   75.36 +        CH = getbytef();
   75.37 +        cycles -= timing_rr;
   75.38 +        return 0;
   75.39 +}
   75.40 +static int opMOV_DL_imm(uint32_t fetchdat)
   75.41 +{
   75.42 +        DL = getbytef();
   75.43 +        cycles -= timing_rr;
   75.44 +        return 0;
   75.45 +}
   75.46 +static int opMOV_DH_imm(uint32_t fetchdat)
   75.47 +{
   75.48 +        DH = getbytef();
   75.49 +        cycles -= timing_rr;
   75.50 +        return 0;
   75.51 +}
   75.52 +
   75.53 +static int opMOV_AX_imm(uint32_t fetchdat)
   75.54 +{
   75.55 +        AX = getwordf();
   75.56 +        cycles -= timing_rr;
   75.57 +        return 0;
   75.58 +}
   75.59 +static int opMOV_BX_imm(uint32_t fetchdat)
   75.60 +{
   75.61 +        BX = getwordf();
   75.62 +        cycles -= timing_rr;
   75.63 +        return 0;
   75.64 +}
   75.65 +static int opMOV_CX_imm(uint32_t fetchdat)
   75.66 +{
   75.67 +        CX = getwordf();
   75.68 +        cycles -= timing_rr;
   75.69 +        return 0;
   75.70 +}
   75.71 +static int opMOV_DX_imm(uint32_t fetchdat)
   75.72 +{
   75.73 +        DX = getwordf();
   75.74 +        cycles -= timing_rr;
   75.75 +        return 0;
   75.76 +}
   75.77 +static int opMOV_SI_imm(uint32_t fetchdat)
   75.78 +{
   75.79 +        SI = getwordf();
   75.80 +        cycles -= timing_rr;
   75.81 +        return 0;
   75.82 +}
   75.83 +static int opMOV_DI_imm(uint32_t fetchdat)
   75.84 +{
   75.85 +        DI = getwordf();
   75.86 +        cycles -= timing_rr;
   75.87 +        return 0;
   75.88 +}
   75.89 +static int opMOV_BP_imm(uint32_t fetchdat)
   75.90 +{
   75.91 +        BP = getwordf();
   75.92 +        cycles -= timing_rr;
   75.93 +        return 0;
   75.94 +}
   75.95 +static int opMOV_SP_imm(uint32_t fetchdat)
   75.96 +{
   75.97 +        SP = getwordf();
   75.98 +        cycles -= timing_rr;
   75.99 +        return 0;
  75.100 +}
  75.101 +
  75.102 +static int opMOV_EAX_imm(uint32_t fetchdat)
  75.103 +{
  75.104 +        uint32_t templ = getlong();     if (abrt) return 0;
  75.105 +        EAX = templ;
  75.106 +        cycles -= timing_rr;
  75.107 +        return 0;
  75.108 +}
  75.109 +static int opMOV_EBX_imm(uint32_t fetchdat)
  75.110 +{
  75.111 +        uint32_t templ = getlong();     if (abrt) return 0;
  75.112 +        EBX = templ;
  75.113 +        cycles -= timing_rr;
  75.114 +        return 0;
  75.115 +}
  75.116 +static int opMOV_ECX_imm(uint32_t fetchdat)
  75.117 +{
  75.118 +        uint32_t templ = getlong();     if (abrt) return 0;
  75.119 +        ECX = templ;
  75.120 +        cycles -= timing_rr;
  75.121 +        return 0;
  75.122 +}
  75.123 +static int opMOV_EDX_imm(uint32_t fetchdat)
  75.124 +{
  75.125 +        uint32_t templ = getlong();     if (abrt) return 0;
  75.126 +        EDX = templ;
  75.127 +        cycles -= timing_rr;
  75.128 +        return 0;
  75.129 +}
  75.130 +static int opMOV_ESI_imm(uint32_t fetchdat)
  75.131 +{
  75.132 +        uint32_t templ = getlong();     if (abrt) return 0;
  75.133 +        ESI = templ;
  75.134 +        cycles -= timing_rr;
  75.135 +        return 0;
  75.136 +}
  75.137 +static int opMOV_EDI_imm(uint32_t fetchdat)
  75.138 +{
  75.139 +        uint32_t templ = getlong();     if (abrt) return 0;
  75.140 +        EDI = templ;
  75.141 +        cycles -= timing_rr;
  75.142 +        return 0;
  75.143 +}
  75.144 +static int opMOV_EBP_imm(uint32_t fetchdat)
  75.145 +{
  75.146 +        uint32_t templ = getlong();     if (abrt) return 0;
  75.147 +        EBP = templ;
  75.148 +        cycles -= timing_rr;
  75.149 +        return 0;
  75.150 +}
  75.151 +static int opMOV_ESP_imm(uint32_t fetchdat)
  75.152 +{
  75.153 +        uint32_t templ = getlong();     if (abrt) return 0;
  75.154 +        ESP = templ;
  75.155 +        cycles -= timing_rr;
  75.156 +        return 0;
  75.157 +}
  75.158 +
  75.159 +static int opMOV_b_imm_a16(uint32_t fetchdat)
  75.160 +{
  75.161 +        uint8_t temp;
  75.162 +        fetch_ea_16(fetchdat);
  75.163 +        temp = readmemb(cs,pc); pc++;               if (abrt) return 0;
  75.164 +        seteab(temp);
  75.165 +        cycles -= timing_rr;
  75.166 +        return 0;
  75.167 +}
  75.168 +static int opMOV_b_imm_a32(uint32_t fetchdat)
  75.169 +{
  75.170 +        uint8_t temp;
  75.171 +        fetch_ea_32(fetchdat);
  75.172 +        temp = getbyte();               if (abrt) return 0;
  75.173 +        seteab(temp);
  75.174 +        cycles -= timing_rr;
  75.175 +        return 0;
  75.176 +}
  75.177 +
  75.178 +static int opMOV_w_imm_a16(uint32_t fetchdat)
  75.179 +{
  75.180 +        uint16_t temp;
  75.181 +        fetch_ea_16(fetchdat);
  75.182 +        temp = getword();               if (abrt) return 0;
  75.183 +        seteaw(temp);
  75.184 +        cycles -= timing_rr;
  75.185 +        return 0;
  75.186 +}
  75.187 +static int opMOV_w_imm_a32(uint32_t fetchdat)
  75.188 +{
  75.189 +        uint16_t temp;
  75.190 +        fetch_ea_32(fetchdat);
  75.191 +        temp = getword();               if (abrt) return 0;
  75.192 +        seteaw(temp);
  75.193 +        cycles -= timing_rr;
  75.194 +        return 0;
  75.195 +}
  75.196 +static int opMOV_l_imm_a16(uint32_t fetchdat)
  75.197 +{
  75.198 +        uint32_t temp;
  75.199 +        fetch_ea_16(fetchdat);
  75.200 +        temp = getlong();               if (abrt) return 0;
  75.201 +        seteal(temp);
  75.202 +        cycles -= timing_rr;
  75.203 +        return 0;
  75.204 +}
  75.205 +static int opMOV_l_imm_a32(uint32_t fetchdat)
  75.206 +{
  75.207 +        uint32_t temp;
  75.208 +        fetch_ea_32(fetchdat);
  75.209 +        temp = getlong();               if (abrt) return 0;
  75.210 +        seteal(temp);
  75.211 +        cycles -= timing_rr;
  75.212 +        return 0;
  75.213 +}
  75.214 +
  75.215 +
  75.216 +static int opMOV_AL_a16(uint32_t fetchdat)
  75.217 +{
  75.218 +        uint16_t addr = getwordf();
  75.219 +        uint8_t temp = readmemb(ds, addr);      if (abrt) return 0;
  75.220 +        AL = temp;
  75.221 +        cycles -= (is486) ? 1 : 4;
  75.222 +        return 0;        
  75.223 +}
  75.224 +static int opMOV_AL_a32(uint32_t fetchdat)
  75.225 +{
  75.226 +        uint32_t addr = getlong();
  75.227 +        uint8_t temp = readmemb(ds, addr);      if (abrt) return 0;
  75.228 +        AL = temp;
  75.229 +        cycles -= (is486) ? 1 : 4;
  75.230 +        return 0;        
  75.231 +}
  75.232 +static int opMOV_AX_a16(uint32_t fetchdat)
  75.233 +{
  75.234 +        uint16_t addr = getwordf();
  75.235 +        uint16_t temp = readmemw(ds, addr);     if (abrt) return 0;
  75.236 +        AX = temp;
  75.237 +        cycles -= (is486) ? 1 : 4;
  75.238 +        return 0;        
  75.239 +}
  75.240 +static int opMOV_AX_a32(uint32_t fetchdat)
  75.241 +{
  75.242 +        uint32_t addr = getlong();
  75.243 +        uint16_t temp = readmemw(ds, addr);     if (abrt) return 0;
  75.244 +        AX = temp;
  75.245 +        cycles -= (is486) ? 1 : 4;
  75.246 +        return 0;        
  75.247 +}
  75.248 +static int opMOV_EAX_a16(uint32_t fetchdat)
  75.249 +{
  75.250 +        uint16_t addr = getwordf();             if (abrt) return 0;
  75.251 +        uint32_t temp = readmeml(ds, addr);     if (abrt) return 0;
  75.252 +        EAX = temp;
  75.253 +        cycles -= (is486) ? 1 : 4;
  75.254 +        return 0;        
  75.255 +}
  75.256 +static int opMOV_EAX_a32(uint32_t fetchdat)
  75.257 +{
  75.258 +        uint32_t addr = getlong();              if (abrt) return 0;
  75.259 +        uint32_t temp = readmeml(ds, addr);     if (abrt) return 0;
  75.260 +        EAX = temp;
  75.261 +        cycles -= (is486) ? 1 : 4;
  75.262 +        return 0;        
  75.263 +}
  75.264 +
  75.265 +static int opMOV_a16_AL(uint32_t fetchdat)
  75.266 +{
  75.267 +        uint16_t addr = getwordf();
  75.268 +        writememb(ds, addr, AL);
  75.269 +        cycles -= (is486) ? 1 : 2;
  75.270 +        return 0;
  75.271 +}
  75.272 +static int opMOV_a32_AL(uint32_t fetchdat)
  75.273 +{
  75.274 +        uint32_t addr = getlong();
  75.275 +        writememb(ds, addr, AL);
  75.276 +        cycles -= (is486) ? 1 : 2;
  75.277 +        return 0;
  75.278 +}
  75.279 +static int opMOV_a16_AX(uint32_t fetchdat)
  75.280 +{
  75.281 +        uint16_t addr = getwordf();
  75.282 +        writememw(ds, addr, AX);
  75.283 +        cycles -= (is486) ? 1 : 2;
  75.284 +        return 0;
  75.285 +}
  75.286 +static int opMOV_a32_AX(uint32_t fetchdat)
  75.287 +{
  75.288 +        uint32_t addr = getlong();
  75.289 +        writememw(ds, addr, AX);
  75.290 +        cycles -= (is486) ? 1 : 2;
  75.291 +        return 0;
  75.292 +}
  75.293 +static int opMOV_a16_EAX(uint32_t fetchdat)
  75.294 +{
  75.295 +        uint16_t addr = getwordf();
  75.296 +        writememl(ds, addr, EAX);
  75.297 +        cycles -= (is486) ? 1 : 2;
  75.298 +        return 0;
  75.299 +}
  75.300 +static int opMOV_a32_EAX(uint32_t fetchdat)
  75.301 +{
  75.302 +        uint32_t addr = getlong();
  75.303 +        writememl(ds, addr, EAX);
  75.304 +        cycles -= (is486) ? 1 : 2;
  75.305 +        return 0;
  75.306 +}
  75.307 +
  75.308 +
  75.309 +static int opLEA_w_a16(uint32_t fetchdat)
  75.310 +{
  75.311 +        fetch_ea_16(fetchdat);
  75.312 +        regs[reg].w = eaaddr;
  75.313 +        cycles -= timing_rr;
  75.314 +        return 0;
  75.315 +}
  75.316 +static int opLEA_w_a32(uint32_t fetchdat)
  75.317 +{
  75.318 +        fetch_ea_32(fetchdat);
  75.319 +        regs[reg].w = eaaddr;
  75.320 +        cycles -= timing_rr;
  75.321 +        return 0;
  75.322 +}
  75.323 +
  75.324 +static int opLEA_l_a16(uint32_t fetchdat)
  75.325 +{
  75.326 +        fetch_ea_16(fetchdat);
  75.327 +        regs[reg].l = eaaddr & 0xffff;
  75.328 +        cycles -= timing_rr;
  75.329 +        return 0;
  75.330 +}
  75.331 +static int opLEA_l_a32(uint32_t fetchdat)
  75.332 +{
  75.333 +        fetch_ea_32(fetchdat);
  75.334 +        regs[reg].l = eaaddr;
  75.335 +        cycles -= timing_rr;
  75.336 +        return 0;
  75.337 +}
  75.338 +
  75.339 +
  75.340 +
  75.341 +int opXLAT_a16(uint32_t fetchdat)
  75.342 +{
  75.343 +        uint32_t addr = (BX + AL)&0xFFFF;
  75.344 +        uint8_t temp = readmemb(ds, addr);      if (abrt) return 0;
  75.345 +        AL = temp;
  75.346 +        cycles -= 5;
  75.347 +        return 0;
  75.348 +}
  75.349 +int opXLAT_a32(uint32_t fetchdat)
  75.350 +{
  75.351 +        uint32_t addr = EBX + AL;
  75.352 +        uint8_t temp = readmemb(ds, addr);      if (abrt) return 0;
  75.353 +        AL = temp;
  75.354 +        cycles -= 5;
  75.355 +        return 0;
  75.356 +}
  75.357 +
  75.358 +static int opMOV_b_r_a16(uint32_t fetchdat)
  75.359 +{
  75.360 +        if ((uint8_t)fetchdat >= 0xc0)
  75.361 +        {
  75.362 +                pc++;
  75.363 +                setr8(fetchdat & 7, getr8((fetchdat >> 3) & 7));
  75.364 +                cycles -= timing_rr;
  75.365 +        }
  75.366 +        else
  75.367 +        {
  75.368 +                fetch_ea_16(fetchdat);
  75.369 +                seteab(getr8(reg));
  75.370 +                cycles -= is486 ? 1 : 2;
  75.371 +        }
  75.372 +        return 0;
  75.373 +}
  75.374 +static int opMOV_b_r_a32(uint32_t fetchdat)
  75.375 +{
  75.376 +        if ((uint8_t)fetchdat >= 0xc0)
  75.377 +        {
  75.378 +                pc++;
  75.379 +                setr8(fetchdat & 7, getr8((fetchdat >> 3) & 7));
  75.380 +                cycles -= timing_rr;
  75.381 +        }
  75.382 +        else
  75.383 +        {
  75.384 +                fetch_ea_32(fetchdat);
  75.385 +                seteab(getr8(reg));
  75.386 +                cycles -= is486 ? 1 : 2;
  75.387 +        }
  75.388 +        return 0;
  75.389 +}
  75.390 +static int opMOV_w_r_a16(uint32_t fetchdat)
  75.391 +{
  75.392 +        if ((uint8_t)fetchdat >= 0xc0)
  75.393 +        {
  75.394 +                pc++;
  75.395 +                regs[fetchdat & 7].w = regs[(fetchdat >> 3) & 7].w;
  75.396 +                cycles -= timing_rr;
  75.397 +        }
  75.398 +        else
  75.399 +        { 
  75.400 +                fetch_ea_16(fetchdat);
  75.401 +                seteaw(regs[reg].w);
  75.402 +                cycles -= is486 ? 1 : 2;
  75.403 +        }
  75.404 +        return 0;
  75.405 +}
  75.406 +static int opMOV_w_r_a32(uint32_t fetchdat)
  75.407 +{
  75.408 +        if ((uint8_t)fetchdat >= 0xc0)
  75.409 +        {
  75.410 +                pc++;
  75.411 +                regs[fetchdat & 7].w = regs[(fetchdat >> 3) & 7].w;
  75.412 +                cycles -= timing_rr;
  75.413 +        }
  75.414 +        else
  75.415 +        { 
  75.416 +                fetch_ea_32(fetchdat);
  75.417 +                seteaw(regs[reg].w);
  75.418 +                cycles -= is486 ? 1 : 2;
  75.419 +        }
  75.420 +        return 0;
  75.421 +}
  75.422 +static int opMOV_l_r_a16(uint32_t fetchdat)
  75.423 +{                       
  75.424 +        if ((uint8_t)fetchdat >= 0xc0)
  75.425 +        {
  75.426 +                pc++;
  75.427 +                regs[fetchdat & 7].l = regs[(fetchdat >> 3) & 7].l;
  75.428 +                cycles -= timing_rr;
  75.429 +        }
  75.430 +        else
  75.431 +        {
  75.432 +                fetch_ea_16(fetchdat);
  75.433 +                seteal(regs[reg].l);
  75.434 +                cycles -= is486 ? 1 : 2;
  75.435 +        }
  75.436 +        return 0;
  75.437 +}
  75.438 +static int opMOV_l_r_a32(uint32_t fetchdat)
  75.439 +{                       
  75.440 +        if ((uint8_t)fetchdat >= 0xc0)
  75.441 +        {
  75.442 +                pc++;
  75.443 +                regs[fetchdat & 7].l = regs[(fetchdat >> 3) & 7].l;
  75.444 +                cycles -= timing_rr;
  75.445 +        }
  75.446 +        else
  75.447 +        {
  75.448 +                fetch_ea_32(fetchdat);
  75.449 +                seteal(regs[reg].l);
  75.450 +                cycles -= is486 ? 1 : 2;
  75.451 +        }
  75.452 +        return 0;
  75.453 +}
  75.454 +
  75.455 +static int opMOV_r_b_a16(uint32_t fetchdat)
  75.456 +{
  75.457 +        if ((uint8_t)fetchdat >= 0xc0)
  75.458 +        {
  75.459 +                pc++;
  75.460 +                setr8((fetchdat >> 3) & 7, getr8(fetchdat & 7));
  75.461 +                cycles -= timing_rr;
  75.462 +        }
  75.463 +        else
  75.464 +        {
  75.465 +                uint8_t temp;
  75.466 +                fetch_ea_16(fetchdat);
  75.467 +                temp = geteab();                if (abrt) return 0;
  75.468 +                setr8(reg, temp);
  75.469 +                cycles -= is486 ? 1 : 4;
  75.470 +        }
  75.471 +        return 0;
  75.472 +}
  75.473 +static int opMOV_r_b_a32(uint32_t fetchdat)
  75.474 +{
  75.475 +        if ((uint8_t)fetchdat >= 0xc0)
  75.476 +        {
  75.477 +                pc++;
  75.478 +                setr8((fetchdat >> 3) & 7, getr8(fetchdat & 7));
  75.479 +                cycles -= timing_rr;
  75.480 +        }
  75.481 +        else
  75.482 +        {
  75.483 +                uint8_t temp;
  75.484 +                fetch_ea_32(fetchdat);
  75.485 +                temp = geteab();                if (abrt) return 0;
  75.486 +                setr8(reg, temp);
  75.487 +                cycles -= is486 ? 1 : 4;
  75.488 +        }
  75.489 +        return 0;
  75.490 +}
  75.491 +static int opMOV_r_w_a16(uint32_t fetchdat)
  75.492 +{
  75.493 +        if ((uint8_t)fetchdat >= 0xc0)
  75.494 +        {
  75.495 +                pc++;
  75.496 +                regs[(fetchdat >> 3) & 7].w = regs[fetchdat & 7].w;
  75.497 +                cycles -= timing_rr;
  75.498 +        }
  75.499 +        else
  75.500 +        {
  75.501 +                uint16_t temp;
  75.502 +                fetch_ea_16(fetchdat);
  75.503 +                temp = geteaw();                if (abrt) return 0;
  75.504 +                regs[reg].w = temp;
  75.505 +                cycles -= (is486) ? 1 : 4;
  75.506 +        }
  75.507 +        return 0;
  75.508 +}
  75.509 +static int opMOV_r_w_a32(uint32_t fetchdat)
  75.510 +{
  75.511 +        if ((uint8_t)fetchdat >= 0xc0)
  75.512 +        {
  75.513 +                pc++;
  75.514 +                regs[(fetchdat >> 3) & 7].w = regs[fetchdat & 7].w;
  75.515 +                cycles -= timing_rr;
  75.516 +        }
  75.517 +        else
  75.518 +        {
  75.519 +                uint16_t temp;
  75.520 +                fetch_ea_32(fetchdat);
  75.521 +                temp = geteaw();                if (abrt) return 0;
  75.522 +                regs[reg].w = temp;
  75.523 +                cycles -= (is486) ? 1 : 4;
  75.524 +        }
  75.525 +        return 0;
  75.526 +}
  75.527 +static int opMOV_r_l_a16(uint32_t fetchdat)
  75.528 +{
  75.529 +        if ((uint8_t)fetchdat >= 0xc0)
  75.530 +        {
  75.531 +                pc++;
  75.532 +                regs[(fetchdat >> 3) & 7].l = regs[fetchdat & 7].l;
  75.533 +                cycles -= timing_rr;
  75.534 +        }
  75.535 +        else
  75.536 +        {
  75.537 +                uint32_t temp;
  75.538 +                fetch_ea_16(fetchdat);
  75.539 +                temp = geteal();                if (abrt) return 0;
  75.540 +                regs[reg].l = temp;
  75.541 +                cycles -= is486 ? 1 : 4;
  75.542 +        }
  75.543 +        return 0;
  75.544 +}
  75.545 +static int opMOV_r_l_a32(uint32_t fetchdat)
  75.546 +{
  75.547 +        if ((uint8_t)fetchdat >= 0xc0)
  75.548 +        {
  75.549 +                pc++;
  75.550 +                regs[(fetchdat >> 3) & 7].l = regs[fetchdat & 7].l;
  75.551 +                cycles -= timing_rr;
  75.552 +        }
  75.553 +        else
  75.554 +        {
  75.555 +                uint32_t temp;
  75.556 +                fetch_ea_32(fetchdat);
  75.557 +                temp = geteal();                if (abrt) return 0;
  75.558 +                regs[reg].l = temp;
  75.559 +                cycles -= is486 ? 1 : 4;
  75.560 +        }
  75.561 +        return 0;
  75.562 +}
    76.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.2 +++ b/src/x86_ops_mov_ctrl.h	Mon May 27 19:56:33 2013 +0100
    76.3 @@ -0,0 +1,232 @@
    76.4 +static int opMOV_r_CRx_a16(uint32_t fetchdat)
    76.5 +{
    76.6 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
    76.7 +        {
    76.8 +                pclog("Can't load from CRx\n");
    76.9 +                x86gpf(NULL, 0);
   76.10 +                return 0;
   76.11 +        }
   76.12 +        fetch_ea_16(fetchdat);
   76.13 +        switch (reg)
   76.14 +        {
   76.15 +                case 0:
   76.16 +                regs[rm].l = cr0;
   76.17 +                if (is486) regs[rm].l |= 0x10; /*ET hardwired on 486*/
   76.18 +                break;
   76.19 +                case 2:
   76.20 +                regs[rm].l = cr2;
   76.21 +                break;
   76.22 +                case 3:
   76.23 +                regs[rm].l = cr3;
   76.24 +                break;
   76.25 +                default:
   76.26 +                pclog("Bad read of CR%i %i\n",rmdat&7,reg);
   76.27 +                pc = oldpc;
   76.28 +                x86illegal();
   76.29 +                break;
   76.30 +        }
   76.31 +        cycles -= 6;
   76.32 +        return 0;
   76.33 +}
   76.34 +static int opMOV_r_CRx_a32(uint32_t fetchdat)
   76.35 +{
   76.36 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
   76.37 +        {
   76.38 +                pclog("Can't load from CRx\n");
   76.39 +                x86gpf(NULL, 0);
   76.40 +                return 0;
   76.41 +        }
   76.42 +        fetch_ea_32(fetchdat);
   76.43 +        switch (reg)
   76.44 +        {
   76.45 +                case 0:
   76.46 +                regs[rm].l = cr0;
   76.47 +                if (is486) regs[rm].l |= 0x10; /*ET hardwired on 486*/
   76.48 +                break;
   76.49 +                case 2:
   76.50 +                regs[rm].l = cr2;
   76.51 +                break;
   76.52 +                case 3:
   76.53 +                regs[rm].l = cr3;
   76.54 +                break;
   76.55 +                default:
   76.56 +                pclog("Bad read of CR%i %i\n",rmdat&7,reg);
   76.57 +                pc = oldpc;
   76.58 +                x86illegal();
   76.59 +                break;
   76.60 +        }
   76.61 +        cycles -= 6;
   76.62 +        return 0;
   76.63 +}
   76.64 +
   76.65 +static int opMOV_r_DRx_a16(uint32_t fetchdat)
   76.66 +{
   76.67 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
   76.68 +        {
   76.69 +                pclog("Can't load from DRx\n");
   76.70 +                x86gpf(NULL, 0);
   76.71 +                return 0;
   76.72 +        }
   76.73 +        fetch_ea_16(fetchdat);
   76.74 +        regs[rm].l = 0;
   76.75 +        cycles -= 6;
   76.76 +        return 0;
   76.77 +}
   76.78 +static int opMOV_r_DRx_a32(uint32_t fetchdat)
   76.79 +{
   76.80 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
   76.81 +        {
   76.82 +                pclog("Can't load from DRx\n");
   76.83 +                x86gpf(NULL, 0);
   76.84 +                return 0;
   76.85 +        }
   76.86 +        fetch_ea_32(fetchdat);
   76.87 +        regs[rm].l = 0;
   76.88 +        cycles -= 6;
   76.89 +        return 0;
   76.90 +}
   76.91 +
   76.92 +static int opMOV_CRx_r_a16(uint32_t fetchdat)
   76.93 +{
   76.94 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
   76.95 +        {
   76.96 +                pclog("Can't load CRx\n");
   76.97 +                x86gpf(NULL,0);
   76.98 +                return 0;
   76.99 +        }
  76.100 +        fetch_ea_16(fetchdat);
  76.101 +        switch (reg)
  76.102 +        {
  76.103 +                case 0:
  76.104 +                if ((regs[rm].l ^ cr0) & 0x80000001) flushmmucache();
  76.105 +                cr0 = regs[rm].l;
  76.106 +                if (cpu_16bitbus) cr0 |= 0x10;
  76.107 +                if (!(cr0 & 0x80000000)) mmu_perm=4;
  76.108 +                break;
  76.109 +                case 2:
  76.110 +                cr2 = regs[rm].l;
  76.111 +                break;
  76.112 +                case 3:
  76.113 +                cr3 = regs[rm].l & ~0xfff;
  76.114 +                flushmmucache();
  76.115 +                break;
  76.116 +                default:
  76.117 +                pclog("Bad load CR%i\n", reg);
  76.118 +                pc = oldpc;
  76.119 +                x86illegal();
  76.120 +                break;
  76.121 +        }
  76.122 +        cycles -= 10;
  76.123 +        return 0;
  76.124 +}
  76.125 +static int opMOV_CRx_r_a32(uint32_t fetchdat)
  76.126 +{
  76.127 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
  76.128 +        {
  76.129 +                pclog("Can't load CRx\n");
  76.130 +                x86gpf(NULL,0);
  76.131 +                return 0;
  76.132 +        }
  76.133 +        fetch_ea_32(fetchdat);
  76.134 +        switch (reg)
  76.135 +        {
  76.136 +                case 0:
  76.137 +                if ((regs[rm].l ^ cr0) & 0x80000001) flushmmucache();
  76.138 +                cr0 = regs[rm].l;
  76.139 +                if (cpu_16bitbus) cr0 |= 0x10;
  76.140 +                if (!(cr0 & 0x80000000)) mmu_perm=4;
  76.141 +                break;
  76.142 +                case 2:
  76.143 +                cr2 = regs[rm].l;
  76.144 +                break;
  76.145 +                case 3:
  76.146 +                cr3 = regs[rm].l & ~0xfff;
  76.147 +                flushmmucache();
  76.148 +                break;
  76.149 +                default:
  76.150 +                pclog("Bad load CR%i\n", reg);
  76.151 +                pc = oldpc;
  76.152 +                x86illegal();
  76.153 +                break;
  76.154 +        }
  76.155 +        cycles -= 10;
  76.156 +        return 0;
  76.157 +}
  76.158 +
  76.159 +static int opMOV_DRx_r_a16(uint32_t fetchdat)
  76.160 +{
  76.161 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
  76.162 +        {
  76.163 +                pclog("Can't load DRx\n");
  76.164 +                x86gpf(NULL, 0);
  76.165 +                return 0;
  76.166 +        }
  76.167 +        fetch_ea_16(fetchdat);
  76.168 +        cycles -= 6;
  76.169 +        return 0;
  76.170 +}
  76.171 +static int opMOV_DRx_r_a32(uint32_t fetchdat)
  76.172 +{
  76.173 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
  76.174 +        {
  76.175 +                pclog("Can't load DRx\n");
  76.176 +                x86gpf(NULL, 0);
  76.177 +                return 0;
  76.178 +        }
  76.179 +        fetch_ea_16(fetchdat);
  76.180 +        cycles -= 6;
  76.181 +        return 0;
  76.182 +}
  76.183 +
  76.184 +static int opMOV_r_TRx_a16(uint32_t fetchdat)
  76.185 +{
  76.186 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
  76.187 +        {
  76.188 +                pclog("Can't load from TRx\n");
  76.189 +                x86gpf(NULL, 0);
  76.190 +                return 0;
  76.191 +        }
  76.192 +        fetch_ea_16(fetchdat);
  76.193 +        regs[rm].l = 0;
  76.194 +        cycles -= 6;
  76.195 +        return 0;
  76.196 +}
  76.197 +static int opMOV_r_TRx_a32(uint32_t fetchdat)
  76.198 +{
  76.199 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
  76.200 +        {
  76.201 +                pclog("Can't load from TRx\n");
  76.202 +                x86gpf(NULL, 0);
  76.203 +                return 0;
  76.204 +        }
  76.205 +        fetch_ea_32(fetchdat);
  76.206 +        regs[rm].l = 0;
  76.207 +        cycles -= 6;
  76.208 +        return 0;
  76.209 +}
  76.210 +
  76.211 +static int opMOV_TRx_r_a16(uint32_t fetchdat)
  76.212 +{
  76.213 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
  76.214 +        {
  76.215 +                pclog("Can't load TRx\n");
  76.216 +                x86gpf(NULL, 0);
  76.217 +                return 0;
  76.218 +        }
  76.219 +        fetch_ea_16(fetchdat);
  76.220 +        cycles -= 6;
  76.221 +        return 0;
  76.222 +}
  76.223 +static int opMOV_TRx_r_a32(uint32_t fetchdat)
  76.224 +{
  76.225 +        if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
  76.226 +        {
  76.227 +                pclog("Can't load TRx\n");
  76.228 +                x86gpf(NULL, 0);
  76.229 +                return 0;
  76.230 +        }
  76.231 +        fetch_ea_16(fetchdat);
  76.232 +        cycles -= 6;
  76.233 +        return 0;
  76.234 +}
  76.235 +
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/src/x86_ops_mov_seg.h	Mon May 27 19:56:33 2013 +0100
    77.3 @@ -0,0 +1,396 @@
    77.4 +static int opMOV_w_seg_a16(uint32_t fetchdat)
    77.5 +{
    77.6 +        fetch_ea_16(fetchdat);
    77.7 +        
    77.8 +        switch (rmdat & 0x38)
    77.9 +        {
   77.10 +                case 0x00: /*ES*/
   77.11 +                seteaw(ES);
   77.12 +                break;
   77.13 +                case 0x08: /*CS*/
   77.14 +                seteaw(CS);
   77.15 +                break;
   77.16 +                case 0x18: /*DS*/
   77.17 +                if (ssegs) ds = oldds;
   77.18 +                seteaw(DS);
   77.19 +                break;
   77.20 +                case 0x10: /*SS*/
   77.21 +                if (ssegs) ss = oldss;
   77.22 +                seteaw(SS);
   77.23 +                break;
   77.24 +                case 0x20: /*FS*/
   77.25 +                seteaw(FS);
   77.26 +                break;
   77.27 +                case 0x28: /*GS*/
   77.28 +                seteaw(GS);
   77.29 +                break;
   77.30 +        }
   77.31 +                        
   77.32 +        cycles -= ((mod == 3) ? 2 : 3);
   77.33 +        return 0;
   77.34 +}
   77.35 +static int opMOV_w_seg_a32(uint32_t fetchdat)
   77.36 +{
   77.37 +        fetch_ea_32(fetchdat);
   77.38 +        
   77.39 +        switch (rmdat & 0x38)
   77.40 +        {
   77.41 +                case 0x00: /*ES*/
   77.42 +                seteaw(ES);
   77.43 +                break;
   77.44 +                case 0x08: /*CS*/
   77.45 +                seteaw(CS);
   77.46 +                break;
   77.47 +                case 0x18: /*DS*/
   77.48 +                if (ssegs) ds = oldds;
   77.49 +                seteaw(DS);
   77.50 +                break;
   77.51 +                case 0x10: /*SS*/
   77.52 +                if (ssegs) ss = oldss;
   77.53 +                seteaw(SS);
   77.54 +                break;
   77.55 +                case 0x20: /*FS*/
   77.56 +                seteaw(FS);
   77.57 +                break;
   77.58 +                case 0x28: /*GS*/
   77.59 +                seteaw(GS);
   77.60 +                break;
   77.61 +        }
   77.62 +                        
   77.63 +        cycles -= ((mod == 3) ? 2 : 3);
   77.64 +        return 0;
   77.65 +}
   77.66 +
   77.67 +static int opMOV_l_seg_a16(uint32_t fetchdat)
   77.68 +{
   77.69 +        fetch_ea_16(fetchdat);
   77.70 +        
   77.71 +        switch (rmdat & 0x38)
   77.72 +        {
   77.73 +                case 0x00: /*ES*/
   77.74 +                if (mod == 3) regs[rm].l = ES;
   77.75 +                else          seteaw(ES);
   77.76 +                break;
   77.77 +                case 0x08: /*CS*/
   77.78 +                if (mod == 3) regs[rm].l = CS;
   77.79 +                else          seteaw(CS);
   77.80 +                break;
   77.81 +                case 0x18: /*DS*/
   77.82 +                if (ssegs) ds = oldds;
   77.83 +                if (mod == 3) regs[rm].l = DS;
   77.84 +                else          seteaw(DS);
   77.85 +                break;
   77.86 +                case 0x10: /*SS*/
   77.87 +                if (ssegs) ss = oldss;
   77.88 +                if (mod == 3) regs[rm].l = SS;
   77.89 +                else          seteaw(SS);
   77.90 +                break;
   77.91 +                case 0x20: /*FS*/
   77.92 +                if (mod == 3) regs[rm].l = FS;
   77.93 +                else          seteaw(FS);
   77.94 +                break;
   77.95 +                case 0x28: /*GS*/
   77.96 +                if (mod == 3) regs[rm].l = GS;
   77.97 +                else          seteaw(GS);
   77.98 +                break;
   77.99 +        }
  77.100 +        
  77.101 +        cycles -= ((mod == 3) ? 2 : 3);
  77.102 +        return 0;
  77.103 +}
  77.104 +static int opMOV_l_seg_a32(uint32_t fetchdat)
  77.105 +{
  77.106 +        fetch_ea_32(fetchdat);
  77.107 +        
  77.108 +        switch (rmdat & 0x38)
  77.109 +        {
  77.110 +                case 0x00: /*ES*/
  77.111 +                if (mod == 3) regs[rm].l = ES;
  77.112 +                else          seteaw(ES);
  77.113 +                break;
  77.114 +                case 0x08: /*CS*/
  77.115 +                if (mod == 3) regs[rm].l = CS;
  77.116 +                else          seteaw(CS);
  77.117 +                break;
  77.118 +                case 0x18: /*DS*/
  77.119 +                if (ssegs) ds = oldds;
  77.120 +                if (mod == 3) regs[rm].l = DS;
  77.121 +                else          seteaw(DS);
  77.122 +                break;
  77.123 +                case 0x10: /*SS*/
  77.124 +                if (ssegs) ss = oldss;
  77.125 +                if (mod == 3) regs[rm].l = SS;
  77.126 +                else          seteaw(SS);
  77.127 +                break;
  77.128 +                case 0x20: /*FS*/
  77.129 +                if (mod == 3) regs[rm].l = FS;
  77.130 +                else          seteaw(FS);
  77.131 +                break;
  77.132 +                case 0x28: /*GS*/
  77.133 +                if (mod == 3) regs[rm].l = GS;
  77.134 +                else          seteaw(GS);
  77.135 +                break;
  77.136 +        }
  77.137 +        
  77.138 +        cycles -= ((mod == 3) ? 2 : 3);
  77.139 +        return 0;
  77.140 +}
  77.141 +
  77.142 +static int opMOV_seg_w_a16(uint32_t fetchdat)
  77.143 +{
  77.144 +        uint16_t new_seg;
  77.145 +        
  77.146 +        fetch_ea_16(fetchdat);
  77.147 +        
  77.148 +        new_seg=geteaw();         if (abrt) return 0;
  77.149 +        
  77.150 +        switch (rmdat & 0x38)
  77.151 +        {
  77.152 +                case 0x00: /*ES*/
  77.153 +                loadseg(new_seg, &_es);
  77.154 +                break;
  77.155 +                case 0x18: /*DS*/
  77.156 +                loadseg(new_seg, &_ds);
  77.157 +                if (ssegs) oldds = ds;
  77.158 +                break;
  77.159 +                case 0x10: /*SS*/
  77.160 +                loadseg(new_seg, &_ss);
  77.161 +                if (ssegs)
  77.162 +                {
  77.163 +                        ds = oldds;
  77.164 +                        rds = DS;
  77.165 +                        ssegs = 0;
  77.166 +                }
  77.167 +                op32 = use32;
  77.168 +                return 1;
  77.169 +                case 0x20: /*FS*/
  77.170 +                loadseg(new_seg, &_fs);
  77.171 +                break;
  77.172 +                case 0x28: /*GS*/
  77.173 +                loadseg(new_seg, &_gs);
  77.174 +                break;
  77.175 +        }
  77.176 +                        
  77.177 +        cycles -= ((mod == 3) ? 2 : 5);
  77.178 +        return 0;
  77.179 +}
  77.180 +static int opMOV_seg_w_a32(uint32_t fetchdat)
  77.181 +{
  77.182 +        uint16_t new_seg;
  77.183 +        
  77.184 +        fetch_ea_32(fetchdat);
  77.185 +        
  77.186 +        new_seg=geteaw();         if (abrt) return 0;
  77.187 +        
  77.188 +        switch (rmdat & 0x38)
  77.189 +        {
  77.190 +                case 0x00: /*ES*/
  77.191 +                loadseg(new_seg, &_es);
  77.192 +                break;
  77.193 +                case 0x18: /*DS*/
  77.194 +                loadseg(new_seg, &_ds);
  77.195 +                if (ssegs) oldds = ds;
  77.196 +                break;
  77.197 +                case 0x10: /*SS*/
  77.198 +                loadseg(new_seg, &_ss);
  77.199 +                if (ssegs)
  77.200 +                {
  77.201 +                        ds = oldds;
  77.202 +                        rds = DS;
  77.203 +                        ssegs = 0;
  77.204 +                }
  77.205 +                op32 = use32;
  77.206 +                return 1;
  77.207 +                case 0x20: /*FS*/
  77.208 +                loadseg(new_seg, &_fs);
  77.209 +                break;
  77.210 +                case 0x28: /*GS*/
  77.211 +                loadseg(new_seg, &_gs);
  77.212 +                break;
  77.213 +        }
  77.214 +                        
  77.215 +        cycles -= ((mod == 3) ? 2 : 5);
  77.216 +        return 0;
  77.217 +}
  77.218 +
  77.219 +
  77.220 +static int opLDS_w_a16(uint32_t fetchdat)
  77.221 +{
  77.222 +        uint16_t addr, seg;
  77.223 +
  77.224 +        fetch_ea_16(fetchdat);
  77.225 +        addr = readmemw(easeg, eaaddr);
  77.226 +        seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;
  77.227 +        loadseg(seg, &_ds);                     if (abrt) return 0;
  77.228 +        regs[reg].w = addr;
  77.229 +        if (ssegs) oldds = ds;
  77.230 + 
  77.231 +        cycles -= 7;       
  77.232 +        return 0;
  77.233 +}
  77.234 +static int opLDS_w_a32(uint32_t fetchdat)
  77.235 +{
  77.236 +        uint16_t addr, seg;
  77.237 +
  77.238 +        fetch_ea_32(fetchdat);
  77.239 +        addr = readmemw(easeg, eaaddr);
  77.240 +        seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;
  77.241 +        loadseg(seg, &_ds);                     if (abrt) return 0;
  77.242 +        regs[reg].w = addr;
  77.243 +        if (ssegs) oldds = ds;
  77.244 + 
  77.245 +        cycles -= 7;       
  77.246 +        return 0;
  77.247 +}
  77.248 +static int opLDS_l_a16(uint32_t fetchdat)
  77.249 +{
  77.250 +        uint32_t addr;
  77.251 +        uint16_t seg;
  77.252 +
  77.253 +        fetch_ea_16(fetchdat);
  77.254 +        addr = readmeml(easeg, eaaddr);
  77.255 +        seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;
  77.256 +        loadseg(seg, &_ds);                     if (abrt) return 0;
  77.257 +        regs[reg].l = addr;
  77.258 +        if (ssegs) oldds = ds;
  77.259 + 
  77.260 +        cycles -= 7;       
  77.261 +        return 0;
  77.262 +}
  77.263 +static int opLDS_l_a32(uint32_t fetchdat)
  77.264 +{
  77.265 +        uint32_t addr;
  77.266 +        uint16_t seg;
  77.267 +
  77.268 +        fetch_ea_32(fetchdat);
  77.269 +        addr = readmeml(easeg, eaaddr);
  77.270 +        seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;
  77.271 +        loadseg(seg, &_ds);                     if (abrt) return 0;
  77.272 +        regs[reg].l = addr;
  77.273 +        if (ssegs) oldds = ds;
  77.274 + 
  77.275 +        cycles -= 7;       
  77.276 +        return 0;
  77.277 +}
  77.278 +
  77.279 +static int opLSS_w_a16(uint32_t fetchdat)
  77.280 +{
  77.281 +        uint16_t addr, seg;
  77.282 +
  77.283 +        fetch_ea_16(fetchdat);
  77.284 +        addr = readmemw(easeg, eaaddr);
  77.285 +        seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;
  77.286 +        loadseg(seg, &_ss);                     if (abrt) return 0;
  77.287 +        regs[reg].w = addr;
  77.288 +        oldss = ss;
  77.289 + 
  77.290 +        cycles -= 7;       
  77.291 +        return 0;
  77.292 +}
  77.293 +static int opLSS_w_a32(uint32_t fetchdat)
  77.294 +{
  77.295 +        uint16_t addr, seg;
  77.296 +
  77.297 +        fetch_ea_32(fetchdat);
  77.298 +        addr = readmemw(easeg, eaaddr);
  77.299 +        seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;
  77.300 +        loadseg(seg, &_ss);                     if (abrt) return 0;
  77.301 +        regs[reg].w = addr;
  77.302 +        oldss = ss;
  77.303 + 
  77.304 +        cycles -= 7;       
  77.305 +        return 0;
  77.306 +}
  77.307 +static int opLSS_l_a16(uint32_t fetchdat)
  77.308 +{
  77.309 +        uint32_t addr;
  77.310 +        uint16_t seg;
  77.311 +
  77.312 +        fetch_ea_16(fetchdat);
  77.313 +        addr = readmeml(easeg, eaaddr);
  77.314 +        seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;
  77.315 +        loadseg(seg, &_ss);                     if (abrt) return 0;
  77.316 +        regs[reg].l = addr;
  77.317 +        oldss = ss;
  77.318 + 
  77.319 +        cycles -= 7;       
  77.320 +        return 0;
  77.321 +}
  77.322 +static int opLSS_l_a32(uint32_t fetchdat)
  77.323 +{
  77.324 +        uint32_t addr;
  77.325 +        uint16_t seg;
  77.326 +
  77.327 +        fetch_ea_32(fetchdat);
  77.328 +        addr = readmeml(easeg, eaaddr);
  77.329 +        seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;
  77.330 +        loadseg(seg, &_ss);                     if (abrt) return 0;
  77.331 +        regs[reg].l = addr;
  77.332 +        oldss = ss;
  77.333 + 
  77.334 +        cycles -= 7;       
  77.335 +        return 0;
  77.336 +}
  77.337 +
  77.338 +#define opLsel(name, sel)                                                       \
  77.339 +        static int opL ## name ## _w_a16(uint32_t fetchdat)                     \
  77.340 +        {                                                                       \
  77.341 +                uint16_t addr, seg;                                             \
  77.342 +                                                                                \
  77.343 +                fetch_ea_16(fetchdat);                                          \
  77.344 +                addr = readmemw(easeg, eaaddr);                                 \
  77.345 +                seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;     \
  77.346 +                loadseg(seg, &sel);                     if (abrt) return 0;     \
  77.347 +                regs[reg].w = addr;                                             \
  77.348 +                                                                                \
  77.349 +                cycles -= 7;                                                    \
  77.350 +                return 0;                                                       \
  77.351 +        }                                                                       \
  77.352 +                                                                                \
  77.353 +        static int opL ## name ## _w_a32(uint32_t fetchdat)                     \
  77.354 +        {                                                                       \
  77.355 +                uint16_t addr, seg;                                             \
  77.356 +                                                                                \
  77.357 +                fetch_ea_32(fetchdat);                                          \
  77.358 +                addr = readmemw(easeg, eaaddr);                                 \
  77.359 +                seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;     \
  77.360 +                loadseg(seg, &sel);                     if (abrt) return 0;     \
  77.361 +                regs[reg].w = addr;                                             \
  77.362 +                                                                                \
  77.363 +                cycles -= 7;                                                    \
  77.364 +                return 0;                                                       \
  77.365 +        }                                                                       \
  77.366 +                                                                                \
  77.367 +        static int opL ## name ## _l_a16(uint32_t fetchdat)                     \
  77.368 +        {                                                                       \
  77.369 +                uint32_t addr;                                                  \
  77.370 +                uint16_t seg;                                                   \
  77.371 +                                                                                \
  77.372 +                fetch_ea_16(fetchdat);                                          \
  77.373 +                addr = readmeml(easeg, eaaddr);                                 \
  77.374 +                seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;     \
  77.375 +                loadseg(seg, &sel);                     if (abrt) return 0;     \
  77.376 +                regs[reg].l = addr;                                             \
  77.377 +                                                                                \
  77.378 +                cycles -= 7;                                                    \
  77.379 +                return 0;                                                       \
  77.380 +        }                                                                       \
  77.381 +                                                                                \
  77.382 +        static int opL ## name ## _l_a32(uint32_t fetchdat)                     \
  77.383 +        {                                                                       \
  77.384 +                uint32_t addr;                                                  \
  77.385 +                uint16_t seg;                                                   \
  77.386 +                                                                                \
  77.387 +                fetch_ea_32(fetchdat);                                          \
  77.388 +                addr = readmeml(easeg, eaaddr);                                 \
  77.389 +                seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;     \
  77.390 +                loadseg(seg, &sel);                     if (abrt) return 0;     \
  77.391 +                regs[reg].l = addr;                                             \
  77.392 +                                                                                \
  77.393 +                cycles -= 7;                                                    \
  77.394 +                return 0;                                                       \
  77.395 +        }
  77.396 +        
  77.397 +opLsel(ES, _es)
  77.398 +opLsel(FS, _fs)
  77.399 +opLsel(GS, _gs)
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/src/x86_ops_movx.h	Mon May 27 19:56:33 2013 +0100
    78.3 @@ -0,0 +1,145 @@
    78.4 +static int opMOVZX_w_b_a16(uint32_t fetchdat)
    78.5 +{
    78.6 +        uint8_t temp;
    78.7 +        
    78.8 +        fetch_ea_16(fetchdat);
    78.9 +        temp = geteab();                        if (abrt) return 0;
   78.10 +        regs[reg].w = (uint16_t)temp;
   78.11 +        
   78.12 +        cycles -= 3;
   78.13 +        return 0;
   78.14 +}
   78.15 +static int opMOVZX_w_b_a32(uint32_t fetchdat)
   78.16 +{
   78.17 +        uint8_t temp;
   78.18 +        
   78.19 +        fetch_ea_32(fetchdat);
   78.20 +        temp = geteab();                        if (abrt) return 0;
   78.21 +        regs[reg].w = (uint16_t)temp;
   78.22 +        
   78.23 +        cycles -= 3;
   78.24 +        return 0;
   78.25 +}
   78.26 +static int opMOVZX_l_b_a16(uint32_t fetchdat)
   78.27 +{
   78.28 +        uint8_t temp;
   78.29 +        
   78.30 +        fetch_ea_16(fetchdat);
   78.31 +        temp = geteab();                        if (abrt) return 0;
   78.32 +        regs[reg].l = (uint32_t)temp;
   78.33 +        
   78.34 +        cycles -= 3;
   78.35 +        return 0;
   78.36 +}
   78.37 +static int opMOVZX_l_b_a32(uint32_t fetchdat)
   78.38 +{
   78.39 +        uint8_t temp;
   78.40 +        
   78.41 +        fetch_ea_32(fetchdat);
   78.42 +        temp = geteab();                        if (abrt) return 0;
   78.43 +        regs[reg].l = (uint32_t)temp;
   78.44 +        
   78.45 +        cycles -= 3;
   78.46 +        return 0;
   78.47 +}
   78.48 +static int opMOVZX_l_w_a16(uint32_t fetchdat)
   78.49 +{
   78.50 +        uint16_t temp;
   78.51 +        
   78.52 +        fetch_ea_16(fetchdat);
   78.53 +        temp = geteaw();                        if (abrt) return 0;
   78.54 +        regs[reg].l = (uint32_t)temp;
   78.55 +        
   78.56 +        cycles -= 3;
   78.57 +        return 0;
   78.58 +}
   78.59 +static int opMOVZX_l_w_a32(uint32_t fetchdat)
   78.60 +{
   78.61 +        uint16_t temp;
   78.62 +        
   78.63 +        fetch_ea_32(fetchdat);
   78.64 +        temp = geteaw();                        if (abrt) return 0;
   78.65 +        regs[reg].l = (uint32_t)temp;
   78.66 +        
   78.67 +        cycles -= 3;
   78.68 +        return 0;
   78.69 +}
   78.70 +
   78.71 +static int opMOVSX_w_b_a16(uint32_t fetchdat)
   78.72 +{
   78.73 +        uint8_t temp;
   78.74 +        
   78.75 +        fetch_ea_16(fetchdat);
   78.76 +        temp = geteab();                        if (abrt) return 0;
   78.77 +        regs[reg].w = (uint16_t)temp;
   78.78 +        if (temp & 0x80)        
   78.79 +                regs[reg].w |= 0xff00;
   78.80 +        
   78.81 +        cycles -= 3;
   78.82 +        return 0;
   78.83 +}
   78.84 +static int opMOVSX_w_b_a32(uint32_t fetchdat)
   78.85 +{
   78.86 +        uint8_t temp;
   78.87 +        
   78.88 +        fetch_ea_32(fetchdat);
   78.89 +        temp = geteab();                        if (abrt) return 0;
   78.90 +        regs[reg].w = (uint16_t)temp;
   78.91 +        if (temp & 0x80)        
   78.92 +                regs[reg].w |= 0xff00;
   78.93 +        
   78.94 +        cycles -= 3;
   78.95 +        return 0;
   78.96 +}
   78.97 +static int opMOVSX_l_b_a16(uint32_t fetchdat)
   78.98 +{
   78.99 +        uint8_t temp;
  78.100 +        
  78.101 +        fetch_ea_16(fetchdat);
  78.102 +        temp = geteab();                        if (abrt) return 0;
  78.103 +        regs[reg].l = (uint32_t)temp;
  78.104 +        if (temp & 0x80)        
  78.105 +                regs[reg].l |= 0xffffff00;
  78.106 +        
  78.107 +        cycles -= 3;
  78.108 +        return 0;
  78.109 +}
  78.110 +static int opMOVSX_l_b_a32(uint32_t fetchdat)
  78.111 +{
  78.112 +        uint8_t temp;
  78.113 +        
  78.114 +        fetch_ea_32(fetchdat);
  78.115 +        temp = geteab();                        if (abrt) return 0;
  78.116 +        regs[reg].l = (uint32_t)temp;
  78.117 +        if (temp & 0x80)        
  78.118 +                regs[reg].l |= 0xffffff00;
  78.119 +        
  78.120 +        cycles -= 3;
  78.121 +        return 0;
  78.122 +}
  78.123 +static int opMOVSX_l_w_a16(uint32_t fetchdat)
  78.124 +{
  78.125 +        uint16_t temp;
  78.126 +        
  78.127 +        fetch_ea_16(fetchdat);
  78.128 +        temp = geteaw();                        if (abrt) return 0;
  78.129 +        regs[reg].l = (uint32_t)temp;
  78.130 +        if (temp & 0x8000)
  78.131 +                regs[reg].l |= 0xffff0000;
  78.132 +        
  78.133 +        cycles -= 3;
  78.134 +        return 0;
  78.135 +}
  78.136 +static int opMOVSX_l_w_a32(uint32_t fetchdat)
  78.137 +{
  78.138 +        uint16_t temp;
  78.139 +        
  78.140 +        fetch_ea_32(fetchdat);
  78.141 +        temp = geteaw();                        if (abrt) return 0;
  78.142 +        regs[reg].l = (uint32_t)temp;
  78.143 +        if (temp & 0x8000)
  78.144 +                regs[reg].l |= 0xffff0000;
  78.145 +        
  78.146 +        cycles -= 3;
  78.147 +        return 0;
  78.148 +}
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/src/x86_ops_msr.h	Mon May 27 19:56:33 2013 +0100
    79.3 @@ -0,0 +1,13 @@
    79.4 +static int opRDTSC(uint32_t fetchdat)
    79.5 +{
    79.6 +        if (!cpu_hasrdtsc)
    79.7 +        {
    79.8 +                pc = oldpc;
    79.9 +                x86illegal();
   79.10 +                return 0;
   79.11 +        }
   79.12 +        EAX = tsc & 0xffffffff;
   79.13 +        EDX = tsc >> 32;
   79.14 +        cycles--;
   79.15 +        return 0;
   79.16 +}
    80.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.2 +++ b/src/x86_ops_mul.h	Mon May 27 19:56:33 2013 +0100
    80.3 @@ -0,0 +1,222 @@
    80.4 +static int opIMUL_w_iw_a16(uint32_t fetchdat)
    80.5 +{
    80.6 +        uint32_t templ;
    80.7 +        int16_t tempw, tempw2; 
    80.8 +        
    80.9 +        fetch_ea_16(fetchdat);
   80.10 +                        
   80.11 +        tempw = geteaw();               if (abrt) return 0;
   80.12 +        tempw2 = getword();             if (abrt) return 0;
   80.13 +        
   80.14 +        templ = ((int)tempw) * ((int)tempw2);
   80.15 +        flags_rebuild();
   80.16 +        if ((templ >> 16) != 0 && (templ >> 16) != 0xffff) flags |=   C_FLAG | V_FLAG;
   80.17 +        else                                               flags &= ~(C_FLAG | V_FLAG);
   80.18 +        regs[reg].w = templ & 0xffff;
   80.19 +
   80.20 +        cycles -= (mod == 3) ? 14 : 17;       
   80.21 +        return 0;
   80.22 +}
   80.23 +static int opIMUL_w_iw_a32(uint32_t fetchdat)
   80.24 +{
   80.25 +        uint32_t templ;
   80.26 +        int16_t tempw, tempw2;
   80.27 +        
   80.28 +        fetch_ea_32(fetchdat);
   80.29 +                        
   80.30 +        tempw = geteaw();               if (abrt) return 0;
   80.31 +        tempw2 = getword();             if (abrt) return 0;
   80.32 +        
   80.33 +        templ = ((int)tempw) * ((int)tempw2);
   80.34 +        flags_rebuild();
   80.35 +        if ((templ >> 16) != 0 && (templ >> 16) != 0xffff) flags |=   C_FLAG | V_FLAG;
   80.36 +        else                                               flags &= ~(C_FLAG | V_FLAG);
   80.37 +        regs[reg].w = templ & 0xffff;
   80.38 +
   80.39 +        cycles -= (mod == 3) ? 14 : 17;       
   80.40 +        return 0;
   80.41 +}
   80.42 +
   80.43 +static int opIMUL_l_il_a16(uint32_t fetchdat)
   80.44 +{
   80.45 +        int64_t temp64;
   80.46 +        int32_t templ, templ2;
   80.47 +        
   80.48 +        fetch_ea_16(fetchdat);
   80.49 +        
   80.50 +        templ = geteal();               if (abrt) return 0;
   80.51 +        templ2 = getlong();             if (abrt) return 0;
   80.52 +        
   80.53 +        temp64 = ((int64_t)templ) * ((int64_t)templ2);
   80.54 +        flags_rebuild();
   80.55 +        if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |=   C_FLAG | V_FLAG;
   80.56 +        else                                                     flags &= ~(C_FLAG | V_FLAG);
   80.57 +        regs[reg].l = temp64 & 0xffffffff;
   80.58 +        
   80.59 +        cycles-=25;
   80.60 +        return 0;
   80.61 +}
   80.62 +static int opIMUL_l_il_a32(uint32_t fetchdat)
   80.63 +{
   80.64 +        int64_t temp64;
   80.65 +        int32_t templ, templ2;
   80.66 +        
   80.67 +        fetch_ea_32(fetchdat);
   80.68 +        
   80.69 +        templ = geteal();               if (abrt) return 0;
   80.70 +        templ2 = getlong();             if (abrt) return 0;
   80.71 +        
   80.72 +        temp64 = ((int64_t)templ) * ((int64_t)templ2);
   80.73 +        flags_rebuild();
   80.74 +        if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |=   C_FLAG | V_FLAG;
   80.75 +        else                                                     flags &= ~(C_FLAG | V_FLAG);
   80.76 +        regs[reg].l = temp64 & 0xffffffff;
   80.77 +        
   80.78 +        cycles-=25;
   80.79 +        return 0;
   80.80 +}
   80.81 +
   80.82 +static int opIMUL_w_ib_a16(uint32_t fetchdat)
   80.83 +{
   80.84 +        uint32_t templ;
   80.85 +        int16_t tempw, tempw2;
   80.86 +        
   80.87 +        fetch_ea_16(fetchdat);
   80.88 +        
   80.89 +        tempw = geteaw();               if (abrt) return 0;
   80.90 +        tempw2 = getbyte();             if (abrt) return 0;
   80.91 +        if (tempw2 & 0x80) tempw2 |= 0xff00;
   80.92 +        
   80.93 +        templ = ((int)tempw) * ((int)tempw2);
   80.94 +        flags_rebuild();
   80.95 +        if ((templ >> 16) != 0 && ((templ >> 16) & 0xffff) != 0xffff) flags |=   C_FLAG | V_FLAG;
   80.96 +        else                                                          flags &= ~(C_FLAG | V_FLAG);
   80.97 +        regs[reg].w = templ & 0xffff;
   80.98 +        
   80.99 +        cycles -= (mod == 3) ? 14 : 17;
  80.100 +        return 0;
  80.101 +}
  80.102 +static int opIMUL_w_ib_a32(uint32_t fetchdat)
  80.103 +{
  80.104 +        uint32_t templ;
  80.105 +        int16_t tempw, tempw2;
  80.106 +        
  80.107 +        fetch_ea_32(fetchdat);
  80.108 +        
  80.109 +        tempw = geteaw();               if (abrt) return 0;
  80.110 +        tempw2 = getbyte();             if (abrt) return 0;
  80.111 +        if (tempw2 & 0x80) tempw2 |= 0xff00;
  80.112 +        
  80.113 +        templ = ((int)tempw) * ((int)tempw2);
  80.114 +        flags_rebuild();
  80.115 +        if ((templ >> 16) != 0 && ((templ >> 16) & 0xffff) != 0xffff) flags |=   C_FLAG | V_FLAG;
  80.116 +        else                                                          flags &= ~(C_FLAG | V_FLAG);
  80.117 +        regs[reg].w = templ & 0xffff;
  80.118 +        
  80.119 +        cycles -= (mod == 3) ? 14 : 17;
  80.120 +        return 0;
  80.121 +}
  80.122 +
  80.123 +static int opIMUL_l_ib_a16(uint32_t fetchdat)
  80.124 +{
  80.125 +        uint64_t temp64;
  80.126 +        int32_t templ, templ2;
  80.127 +
  80.128 +        fetch_ea_16(fetchdat);
  80.129 +        templ = geteal();               if (abrt) return 0;
  80.130 +        templ2 = getbyte();             if (abrt) return 0;
  80.131 +        if (templ2 & 0x80) templ2 |= 0xffffff00;
  80.132 +        
  80.133 +        temp64 = ((int64_t)templ)*((int64_t)templ2);
  80.134 +        flags_rebuild();
  80.135 +        if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |=   C_FLAG | V_FLAG;
  80.136 +        else                                                     flags &= ~(C_FLAG | V_FLAG);
  80.137 +        regs[reg].l = temp64 & 0xffffffff;
  80.138 +        
  80.139 +        cycles -= 20;
  80.140 +        return 0;
  80.141 +}
  80.142 +static int opIMUL_l_ib_a32(uint32_t fetchdat)
  80.143 +{
  80.144 +        uint64_t temp64;
  80.145 +        int32_t templ, templ2;
  80.146 +
  80.147 +        fetch_ea_32(fetchdat);
  80.148 +        templ = geteal();               if (abrt) return 0;
  80.149 +        templ2 = getbyte();             if (abrt) return 0;
  80.150 +        if (templ2 & 0x80) templ2 |= 0xffffff00;
  80.151 +        
  80.152 +        temp64 = ((int64_t)templ)*((int64_t)templ2);
  80.153 +        flags_rebuild();
  80.154 +        if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |=   C_FLAG | V_FLAG;
  80.155 +        else                                                     flags &= ~(C_FLAG | V_FLAG);
  80.156 +        regs[reg].l = temp64 & 0xffffffff;
  80.157 +        
  80.158 +        cycles -= 20;
  80.159 +        return 0;
  80.160 +}
  80.161 +
  80.162 +
  80.163 +
  80.164 +static int opIMUL_w_w_a16(uint32_t fetchdat)
  80.165 +{
  80.166 +        int32_t templ;
  80.167 +        
  80.168 +        fetch_ea_16(fetchdat);
  80.169 +        templ = (int32_t)(int16_t)regs[reg].w * (int32_t)(int16_t)geteaw();
  80.170 +        if (abrt) return 0;
  80.171 +        regs[reg].w = templ & 0xFFFF;
  80.172 +        flags_rebuild();
  80.173 +        if ((templ >> 16) && (templ >> 16) != 0xFFFF) flags |=   C_FLAG | V_FLAG;
  80.174 +        else                                          flags &= ~(C_FLAG | V_FLAG);
  80.175 +        
  80.176 +        cycles -= 18;
  80.177 +        return 0;
  80.178 +}
  80.179 +static int opIMUL_w_w_a32(uint32_t fetchdat)
  80.180 +{
  80.181 +        int32_t templ;
  80.182 +        
  80.183 +        fetch_ea_32(fetchdat);
  80.184 +        templ = (int32_t)(int16_t)regs[reg].w * (int32_t)(int16_t)geteaw();
  80.185 +        if (abrt) return 0;
  80.186 +        regs[reg].w = templ & 0xFFFF;
  80.187 +        flags_rebuild();
  80.188 +        if ((templ >> 16) && (templ >> 16) != 0xFFFF) flags |=   C_FLAG | V_FLAG;
  80.189 +        else                                          flags &= ~(C_FLAG | V_FLAG);
  80.190 +        
  80.191 +        cycles -= 18;
  80.192 +        return 0;
  80.193 +}
  80.194 +
  80.195 +static int opIMUL_l_l_a16(uint32_t fetchdat)
  80.196 +{
  80.197 +        int64_t temp64;
  80.198 +
  80.199 +        fetch_ea_16(fetchdat);
  80.200 +        temp64 = (int64_t)(int32_t)regs[reg].l * (int64_t)(int32_t)geteal();
  80.201 +        if (abrt) return 0;
  80.202 +        regs[reg].l = temp64 & 0xFFFFFFFF;
  80.203 +        flags_rebuild();
  80.204 +        if ((temp64 >> 32) && (temp64 >> 32) != 0xFFFFFFFF) flags |=   C_FLAG | V_FLAG;
  80.205 +        else                                                flags &= ~(C_FLAG | V_FLAG);
  80.206 +        
  80.207 +        cycles -= 30;
  80.208 +        return 0;
  80.209 +}
  80.210 +static int opIMUL_l_l_a32(uint32_t fetchdat)
  80.211 +{
  80.212 +        int64_t temp64;
  80.213 +
  80.214 +        fetch_ea_32(fetchdat);
  80.215 +        temp64 = (int64_t)(int32_t)regs[reg].l * (int64_t)(int32_t)geteal();
  80.216 +        if (abrt) return 0;
  80.217 +        regs[reg].l = temp64 & 0xFFFFFFFF;
  80.218 +        flags_rebuild();
  80.219 +        if ((temp64 >> 32) && (temp64 >> 32) != 0xFFFFFFFF) flags |=   C_FLAG | V_FLAG;
  80.220 +        else                                                flags &= ~(C_FLAG | V_FLAG);
  80.221 +        
  80.222 +        cycles -= 30;
  80.223 +        return 0;
  80.224 +}
  80.225 +
    81.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.2 +++ b/src/x86_ops_pmode.h	Mon May 27 19:56:33 2013 +0100
    81.3 @@ -0,0 +1,404 @@
    81.4 +static int opARPL_a16(uint32_t fetchdat)
    81.5 +{
    81.6 +        uint16_t temp_seg;
    81.7 +        
    81.8 +        NOTRM
    81.9 +        fetch_ea_16(fetchdat);
   81.10 +        
   81.11 +        temp_seg = geteaw();            if (abrt) return 0;
   81.12 +        
   81.13 +        flags_rebuild();
   81.14 +        if ((temp_seg & 3) < (regs[reg].w & 3))
   81.15 +        {
   81.16 +                temp_seg = (temp_seg & 0xfffc) | (regs[reg].w & 3);
   81.17 +                seteaw(temp_seg);       if (abrt) return 0;
   81.18 +                flags |= Z_FLAG;
   81.19 +        }
   81.20 +        else
   81.21 +                flags &= ~Z_FLAG;
   81.22 +        
   81.23 +        cycles -= is486 ? 9 : 20;
   81.24 +        return 0;
   81.25 +}
   81.26 +static int opARPL_a32(uint32_t fetchdat)
   81.27 +{
   81.28 +        uint16_t temp_seg;
   81.29 +        
   81.30 +        NOTRM
   81.31 +        fetch_ea_32(fetchdat);
   81.32 +        
   81.33 +        temp_seg = geteaw();            if (abrt) return 0;
   81.34 +        
   81.35 +        flags_rebuild();
   81.36 +        if ((temp_seg & 3) < (regs[reg].w & 3))
   81.37 +        {
   81.38 +                temp_seg = (temp_seg & 0xfffc) | (regs[reg].w & 3);
   81.39 +                seteaw(temp_seg);       if (abrt) return 0;
   81.40 +                flags |= Z_FLAG;
   81.41 +        }
   81.42 +        else
   81.43 +                flags &= ~Z_FLAG;
   81.44 +        
   81.45 +        cycles -= is486 ? 9 : 20;
   81.46 +        return 0;
   81.47 +}
   81.48 +
   81.49 +#define opLAR(name, fetch_ea, is32)                                                                             \
   81.50 +        static int opLAR_ ## name(uint32_t fetchdat)                                                            \
   81.51 +        {                                                                                                       \
   81.52 +                int valid;                                                                                      \
   81.53 +                uint16_t sel, desc;                                                                             \
   81.54 +                                                                                                                \
   81.55 +                NOTRM                                                                                           \
   81.56 +                fetch_ea(fetchdat);                                                                             \
   81.57 +                                                                                                                \
   81.58 +                sel = geteaw();                 if (abrt) return 0;                                             \
   81.59 +                                                                                                                \
   81.60 +                flags_rebuild();                                                                                \
   81.61 +                if (!(sel & 0xfffc)) { flags &= ~Z_FLAG; return 0; } /*Null selector*/                          \
   81.62 +                valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);                                       \
   81.63 +                if (valid)                                                                                      \
   81.64 +                {                                                                                               \
   81.65 +                        cpl_override = 1;                                                                       \
   81.66 +                        desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);                 \
   81.67 +                        cpl_override = 0;       if (abrt) return 0;                                             \
   81.68 +                }                                                                                               \
   81.69 +                flags &= ~Z_FLAG;                                                                               \
   81.70 +                if ((desc & 0x1f00) == 0x000) valid = 0;                                                        \
   81.71 +                if ((desc & 0x1f00) == 0x800) valid = 0;                                                        \
   81.72 +                if ((desc & 0x1f00) == 0xa00) valid = 0;                                                        \
   81.73 +                if ((desc & 0x1f00) == 0xd00) valid = 0;                                                        \
   81.74 +                if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/                              \
   81.75 +                {                                                                                               \
   81.76 +                        int dpl = (desc >> 13) & 3;                                                             \
   81.77 +                        if (dpl < CPL || dpl < (sel & 3)) valid = 0;                                            \
   81.78 +                }                                                                                               \
   81.79 +                if (valid)                                                                                      \
   81.80 +                {                                                                                               \
   81.81 +                        flags |= Z_FLAG;                                                                        \
   81.82 +                        cpl_override = 1;                                                                       \
   81.83 +                        if (is32)                                                                               \
   81.84 +                                regs[reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00;       \
   81.85 +                        else                                                                                    \
   81.86 +                                regs[reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00;         \
   81.87 +                        cpl_override = 0;                                                                       \
   81.88 +                }                                                                                               \
   81.89 +                cycles -= 11;                                                                                   \
   81.90 +                return 0;                                                                                       \
   81.91 +        }
   81.92 +
   81.93 +opLAR(w_a16, fetch_ea_16, 0)
   81.94 +opLAR(w_a32, fetch_ea_32, 0)
   81.95 +opLAR(l_a16, fetch_ea_16, 1)
   81.96 +opLAR(l_a32, fetch_ea_32, 1)
   81.97 +
   81.98 +#define opLSL(name, fetch_ea, is32)                                                                             \
   81.99 +        static int opLSL_ ## name(uint32_t fetchdat)                                                            \
  81.100 +        {                                                                                                       \
  81.101 +                int valid;                                                                                      \
  81.102 +                uint16_t sel, desc;                                                                             \
  81.103 +                                                                                                                \
  81.104 +                NOTRM                                                                                           \
  81.105 +                fetch_ea(fetchdat);                                                                             \
  81.106 +                                                                                                                \
  81.107 +                sel = geteaw();                 if (abrt) return 0;                                             \
  81.108 +                flags_rebuild();                                                                                \
  81.109 +                flags &= ~Z_FLAG;                                                                               \
  81.110 +                if (!(sel & 0xfffc)) return 0; /*Null selector*/                                                \
  81.111 +                valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);                                       \
  81.112 +                if (valid)                                                                                      \
  81.113 +                {                                                                                               \
  81.114 +                        cpl_override = 1;                                                                       \
  81.115 +                        desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);                 \
  81.116 +                        cpl_override = 0;       if (abrt) return 0;                                             \
  81.117 +                }                                                                                               \
  81.118 +                if ((desc & 0x1400) ==  0x400) valid = 0; /*Interrupt or trap or call gate*/                    \
  81.119 +                if ((desc & 0x1f00) ==  0x000) valid = 0; /*Invalid*/                                           \
  81.120 +                if ((desc & 0x1f00) ==  0xa00) valid = 0; /*Invalid*/                                           \
  81.121 +                if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/                             \
  81.122 +                {                                                                                               \
  81.123 +                        int rpl = (desc >> 13) & 3;                                                             \
  81.124 +                        if (rpl < CPL || rpl < (sel & 3)) valid = 0;                                            \
  81.125 +                }                                                                                               \
  81.126 +                if (valid)                                                                                      \
  81.127 +                {                                                                                               \
  81.128 +                        flags |= Z_FLAG;                                                                        \
  81.129 +                        cpl_override = 1;                                                                       \
  81.130 +                        if (is32)                                                                               \
  81.131 +                        {                                                                                       \
  81.132 +                                regs[reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7));      \
  81.133 +                                regs[reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16;   \
  81.134 +                                if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80)     \
  81.135 +                                {                                                                               \
  81.136 +                                        regs[reg].l <<= 12;                                                     \
  81.137 +                                        regs[reg].l |= 0xFFF;                                                   \
  81.138 +                                }                                                                               \
  81.139 +                        }                                                                                       \
  81.140 +                        else                                                                                    \
  81.141 +                                regs[reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7));      \
  81.142 +                        cpl_override = 0;                                                                       \
  81.143 +                }                                                                                               \
  81.144 +                cycles -= 10;                                                                                   \
  81.145 +                return 0;                                                                                       \
  81.146 +        }
  81.147 +
  81.148 +opLSL(w_a16, fetch_ea_16, 0)
  81.149 +opLSL(w_a32, fetch_ea_32, 0)
  81.150 +opLSL(l_a16, fetch_ea_16, 1)
  81.151 +opLSL(l_a32, fetch_ea_32, 1)
  81.152 +
  81.153 +
  81.154 +static inline int op0F00_common(uint32_t fetchdat)
  81.155 +{
  81.156 +        int dpl, valid, granularity;
  81.157 +        uint32_t addr, base, limit;
  81.158 +        uint16_t desc, sel;
  81.159 +        uint8_t access;
  81.160 +
  81.161 +//        pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc);        
  81.162 +        switch (rmdat & 0x38)
  81.163 +        {
  81.164 +                case 0x00: /*SLDT*/
  81.165 +                seteaw(ldt.seg);
  81.166 +                cycles -= 4;
  81.167 +                break;
  81.168 +                case 0x08: /*STR*/
  81.169 +                seteaw(tr.seg);
  81.170 +                cycles -= 4;
  81.171 +                break;
  81.172 +                case 0x10: /*LLDT*/
  81.173 +                if ((CPL || eflags&VM_FLAG) && (cr0&1))
  81.174 +                {
  81.175 +                        pclog("Invalid LLDT!\n");
  81.176 +                        x86gpf(NULL,0);
  81.177 +                        return 0;
  81.178 +                }
  81.179 +                sel = geteaw(); if (abrt) return 0;
  81.180 +                addr = (sel & ~7) + gdt.base;
  81.181 +                limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
  81.182 +                base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
  81.183 +                access = readmemb(0, addr + 5);
  81.184 +                granularity = readmemb(0, addr + 6) & 0x80;
  81.185 +                if (abrt) return 0;
  81.186 +                ldt.limit = limit;
  81.187 +                ldt.access = access;
  81.188 +                if (granularity)
  81.189 +                {
  81.190 +                        ldt.limit <<= 12;
  81.191 +                        ldt.limit |= 0xfff;
  81.192 +                }
  81.193 +                ldt.base = base;
  81.194 +                ldt.seg = sel;
  81.195 +                cycles -= 20;
  81.196 +                break;
  81.197 +                case 0x18: /*LTR*/
  81.198 +                if ((CPL || eflags&VM_FLAG) && (cr0&1))
  81.199 +                {
  81.200 +                        pclog("Invalid LTR!\n");
  81.201 +                        x86gpf(NULL,0);
  81.202 +                        break;
  81.203 +                }
  81.204 +                sel = geteaw(); if (abrt) return 0;
  81.205 +                addr = (sel & ~7) + gdt.base;
  81.206 +                limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
  81.207 +                base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
  81.208 +                access = readmemb(0, addr + 5);
  81.209 +                granularity = readmemb(0, addr + 6) & 0x80;
  81.210 +                if (abrt) return 0;
  81.211 +                tr.seg = sel;
  81.212 +                tr.limit = limit;
  81.213 +                tr.access = access;
  81.214 +                if (granularity)
  81.215 +                {
  81.216 +                        tr.limit <<= 12;
  81.217 +                        tr.limit |= 0xFFF;
  81.218 +                }
  81.219 +                tr.base = base;
  81.220 +                cycles -= 20;
  81.221 +                break;
  81.222 +                case 0x20: /*VERR*/
  81.223 +                sel = geteaw();                 if (abrt) return 0;
  81.224 +                flags_rebuild();
  81.225 +                flags &= ~Z_FLAG;
  81.226 +                if (!(sel & 0xfffc)) return 0; /*Null selector*/
  81.227 +                cpl_override = 1;
  81.228 +                valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
  81.229 +                desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);
  81.230 +                cpl_override = 0;               if (abrt) return 0;
  81.231 +                if (!(desc & 0x1000)) valid = 0;
  81.232 +                if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/
  81.233 +                {
  81.234 +                        dpl = (desc >> 13) & 3; /*Check permissions*/
  81.235 +                        if (dpl < CPL || dpl < (sel & 3)) valid = 0;
  81.236 +                }
  81.237 +                if ((desc & 0x0800) && !(desc & 0x0200)) valid = 0; /*Non-readable code*/
  81.238 +                if (valid) flags |= Z_FLAG;
  81.239 +                cycles -= 20;
  81.240 +                break;
  81.241 +                case 0x28: /*VERW*/
  81.242 +                sel = geteaw();                 if (abrt) return 0;
  81.243 +                flags_rebuild();
  81.244 +                flags &= ~Z_FLAG;
  81.245 +                if (!(sel & 0xfffc)) return 0; /*Null selector*/
  81.246 +                cpl_override = 1;
  81.247 +                valid  = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
  81.248 +                desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);
  81.249 +                cpl_override = 0;               if (abrt) return 0;
  81.250 +                if (!(desc & 0x1000)) valid = 0;
  81.251 +                dpl = (desc >> 13) & 3; /*Check permissions*/
  81.252 +                if (dpl < CPL || dpl < (sel & 3)) valid = 0;
  81.253 +                if (desc & 0x0800) valid = 0; /*Code*/
  81.254 +                if (!(desc & 0x0200)) valid = 0; /*Read-only data*/
  81.255 +                if (valid) flags |= Z_FLAG;
  81.256 +                cycles -= 20;
  81.257 +                break;
  81.258 +
  81.259 +                default:
  81.260 +                pclog("Bad 0F 00 opcode %02X\n", rmdat & 0x38);
  81.261 +                pc -= 3;
  81.262 +                x86illegal();
  81.263 +                break;
  81.264 +        }
  81.265 +        return 0;
  81.266 +}
  81.267 +
  81.268 +static inline op0F00_a16(uint32_t fetchdat)
  81.269 +{
  81.270 +        NOTRM
  81.271 +
  81.272 +        fetch_ea_16(fetchdat);
  81.273 +        
  81.274 +        op0F00_common(fetchdat);
  81.275 +        return 0;
  81.276 +}
  81.277 +static inline op0F00_a32(uint32_t fetchdat)
  81.278 +{
  81.279 +        NOTRM
  81.280 +
  81.281 +        fetch_ea_32(fetchdat);
  81.282 +        
  81.283 +        op0F00_common(fetchdat);
  81.284 +        return 0;
  81.285 +}
  81.286 +
  81.287 +static inline op0F01_common(uint32_t fetchdat, int is32)
  81.288 +{
  81.289 +        uint32_t base;
  81.290 +        uint16_t limit, tempw;
  81.291 +//        pclog("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc);
  81.292 +        switch (rmdat & 0x38)
  81.293 +        {
  81.294 +                case 0x00: /*SGDT*/
  81.295 +                seteaw(gdt.limit);
  81.296 +                base = is32 ? gdt.base : (gdt.base & 0xffffff);
  81.297 +                writememl(easeg, eaaddr + 2, base);
  81.298 +                cycles -= 7;
  81.299 +                break;
  81.300 +                case 0x08: /*SIDT*/
  81.301 +                seteaw(idt.limit);
  81.302 +                base = is32 ? idt.base : (idt.base & 0xffffff);
  81.303 +                writememl(easeg, eaaddr + 2, base);
  81.304 +                cycles -= 7;
  81.305 +                break;
  81.306 +                case 0x10: /*LGDT*/
  81.307 +                if ((CPL || eflags&VM_FLAG) && (cr0&1))
  81.308 +                {
  81.309 +                        pclog("Invalid LGDT!\n");
  81.310 +                        x86gpf(NULL,0);
  81.311 +                        break;
  81.312 +                }
  81.313 +//                pclog("LGDT %08X:%08X\n", easeg, eaaddr);
  81.314 +                limit = geteaw();
  81.315 +                base = readmeml(0, easeg + eaaddr + 2);         if (abrt) return 0;
  81.316 +//                pclog("     %08X %04X\n", base, limit);
  81.317 +                gdt.limit = limit;
  81.318 +                gdt.base = base;
  81.319 +                if (!is32) gdt.base &= 0xffffff;
  81.320 +                cycles -= 11;
  81.321 +                break;
  81.322 +                case 0x18: /*LIDT*/
  81.323 +                if ((CPL || eflags&VM_FLAG) && (cr0&1))
  81.324 +                {
  81.325 +                        pclog("Invalid LIDT!\n");
  81.326 +                        x86gpf(NULL,0);
  81.327 +                        break;
  81.328 +                }
  81.329 +//                pclog("LIDT %08X:%08X\n", easeg, eaaddr);
  81.330 +                limit = geteaw();
  81.331 +                base = readmeml(0, easeg + eaaddr + 2);         if (abrt) return 0;
  81.332 +//                pclog("     %08X %04X\n", base, limit);
  81.333 +                idt.limit = limit;
  81.334 +                idt.base = base;
  81.335 +                if (!is32) idt.base &= 0xffffff;
  81.336 +                cycles -= 11;
  81.337 +                break;
  81.338 +
  81.339 +                case 0x20: /*SMSW*/
  81.340 +                if (is486) seteaw(msw);
  81.341 +                else       seteaw(msw | 0xFF00);
  81.342 +                cycles -= 2;
  81.343 +                break;
  81.344 +                case 0x30: /*LMSW*/
  81.345 +                if ((CPL || eflags&VM_FLAG) && (msw&1))
  81.346 +                {
  81.347 +                        pclog("LMSW - ring not zero!\n");
  81.348 +                        x86gpf(NULL, 0);
  81.349 +                        break;
  81.350 +                }
  81.351 +                tempw = geteaw();                                       if (abrt) return 0;
  81.352 +                if (msw & 1) tempw |= 1;
  81.353 +                msw = tempw;
  81.354 +                break;
  81.355 +
  81.356 +                case 0x38: /*INVLPG*/
  81.357 +                if (is486)
  81.358 +                {
  81.359 +                        if ((CPL || eflags&VM_FLAG) && (cr0&1))
  81.360 +                        {
  81.361 +                                pclog("Invalid INVLPG!\n");
  81.362 +                                x86gpf(NULL, 0);
  81.363 +                                break;
  81.364 +                        }
  81.365 +                        mmu_invalidate(ds + eaaddr);
  81.366 +                        cycles -= 12;
  81.367 +                        break;
  81.368 +                }
  81.369 +
  81.370 +                default:
  81.371 +                pclog("Bad 0F 01 opcode %02X\n", rmdat & 0x38);
  81.372 +                pc -= 3;
  81.373 +                x86illegal();
  81.374 +                break;
  81.375 +        }
  81.376 +        return 0;
  81.377 +}
  81.378 +
  81.379 +static inline op0F01_w_a16(uint32_t fetchdat)
  81.380 +{
  81.381 +        fetch_ea_16(fetchdat);
  81.382 +        
  81.383 +        op0F01_common(fetchdat, 0);
  81.384 +        return 0;
  81.385 +}
  81.386 +static inline op0F01_w_a32(uint32_t fetchdat)
  81.387 +{
  81.388 +        fetch_ea_32(fetchdat);
  81.389 +        
  81.390 +        op0F01_common(fetchdat, 0);
  81.391 +        return 0;
  81.392 +}
  81.393 +static inline op0F01_l_a16(uint32_t fetchdat)
  81.394 +{
  81.395 +        fetch_ea_16(fetchdat);
  81.396 +        
  81.397 +        op0F01_common(fetchdat, 1);
  81.398 +        return 0;
  81.399 +}
  81.400 +static inline op0F01_l_a32(uint32_t fetchdat)
  81.401 +{
  81.402 +        fetch_ea_32(fetchdat);
  81.403 +        
  81.404 +        op0F01_common(fetchdat, 1);
  81.405 +        return 0;
  81.406 +}
  81.407 +
    82.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.2 +++ b/src/x86_ops_prefix.h	Mon May 27 19:56:33 2013 +0100
    82.3 @@ -0,0 +1,73 @@
    82.4 +static int op_CS(uint32_t fetchdat)
    82.5 +{
    82.6 +        oldss = ss;
    82.7 +        oldds = ds;
    82.8 +        ds = ss = cs;
    82.9 +        rds = CS;
   82.10 +        ssegs = 2;
   82.11 +        cycles -= 4;
   82.12 +        return 1;
   82.13 +}
   82.14 +static int op_DS(uint32_t fetchdat)
   82.15 +{
   82.16 +        oldss = ss;
   82.17 +        oldds = ds;
   82.18 +        ds = ss = ds;
   82.19 +        ssegs = 2;
   82.20 +        cycles -= 4;
   82.21 +        return 1;
   82.22 +}
   82.23 +static int op_ES(uint32_t fetchdat)
   82.24 +{
   82.25 +        oldss = ss;
   82.26 +        oldds = ds;
   82.27 +        ds = ss = es;
   82.28 +        rds = ES;
   82.29 +        ssegs = 2;
   82.30 +        cycles -= 4;
   82.31 +        return 1;
   82.32 +}      
   82.33 +static int op_FS(uint32_t fetchdat)
   82.34 +{
   82.35 +        oldss = ss;
   82.36 +        oldds = ds;
   82.37 +        rds = FS;
   82.38 +        ds = ss = fs;
   82.39 +        ssegs = 2;
   82.40 +        cycles -= 4;
   82.41 +        return 1;
   82.42 +}
   82.43 +static int op_GS(uint32_t fetchdat)
   82.44 +{
   82.45 +        oldss = ss;
   82.46 +        oldds = ds;
   82.47 +        rds = GS;
   82.48 +        ds = ss = gs;
   82.49 +        ssegs = 2;
   82.50 +        cycles -= 4;
   82.51 +        return 1;
   82.52 +}
   82.53 +static int op_SS(uint32_t fetchdat)
   82.54 +{
   82.55 +        oldss = ss;
   82.56 +        oldds = ds;
   82.57 +        ds = ss = ss;
   82.58 +        rds = SS;
   82.59 +        ssegs = 2;
   82.60 +        cycles -= 4;
   82.61 +        return 1;
   82.62 +}
   82.63 +
   82.64 +
   82.65 +static int op_66(uint32_t fetchdat) /*Data size select*/
   82.66 +{
   82.67 +        op32 = ((use32 & 0x100) ^ 0x100) | (op32 & 0x200);
   82.68 +        cycles -= 2;
   82.69 +        return 1;
   82.70 +}
   82.71 +static int op_67(uint32_t fetchdat) /*Address size select*/
   82.72 +{
   82.73 +        op32 = ((use32 & 0x200) ^ 0x200) | (op32 & 0x100);
   82.74 +        cycles -= 2;
   82.75 +        return 1;
   82.76 +}
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/src/x86_ops_rep.h	Mon May 27 19:56:33 2013 +0100
    83.3 @@ -0,0 +1,11 @@
    83.4 +static int opREPNE(uint32_t fetchdat)
    83.5 +{
    83.6 +        rep386(0);
    83.7 +        return 0;
    83.8 +}
    83.9 +static int opREPE(uint32_t fetchdat)
   83.10 +{       
   83.11 +        rep386(1);
   83.12 +        return 0;
   83.13 +}
   83.14 +
    84.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.2 +++ b/src/x86_ops_ret.h	Mon May 27 19:56:33 2013 +0100
    84.3 @@ -0,0 +1,152 @@
    84.4 +#define RETF_a16(stack_offset)                                  \
    84.5 +                if ((msw&1) && !(eflags&VM_FLAG))               \
    84.6 +                {                                               \
    84.7 +                        pmoderetf(0, stack_offset);             \
    84.8 +                        return 0;                               \
    84.9 +                }                                               \
   84.10 +                if (ssegs) ss = oldss;                          \
   84.11 +                oxpc = pc;                                      \
   84.12 +                if (stack32)                                    \
   84.13 +                {                                               \
   84.14 +                        pc = readmemw(ss, ESP);                 \
   84.15 +                        loadcs(readmemw(ss, ESP + 2));          \
   84.16 +                }                                               \
   84.17 +                else                                            \
   84.18 +                {                                               \
   84.19 +                        pc = readmemw(ss, SP);                  \
   84.20 +                        loadcs(readmemw(ss, SP + 2));           \
   84.21 +                }                                               \
   84.22 +                if (abrt) return 0;                             \
   84.23 +                if (stack32) ESP += 4 + stack_offset;           \
   84.24 +                else         SP  += 4 + stack_offset;           \
   84.25 +                cycles -= is486 ? 13 : 18;
   84.26 +
   84.27 +#define RETF_a32(stack_offset)                                  \
   84.28 +                if ((msw&1) && !(eflags&VM_FLAG))               \
   84.29 +                {                                               \
   84.30 +                        pmoderetf(1, stack_offset);             \
   84.31 +                        return 0;                               \
   84.32 +                }                                               \
   84.33 +                if (ssegs) ss = oldss;                          \
   84.34 +                oxpc = pc;                                      \
   84.35 +                if (stack32)                                    \
   84.36 +                {                                               \
   84.37 +                        pc = readmeml(ss, ESP);                 \
   84.38 +                        loadcs(readmeml(ss, ESP + 4) & 0xffff); \
   84.39 +                }                                               \
   84.40 +                else                                            \
   84.41 +                {                                               \
   84.42 +                        pc = readmeml(ss, SP);                  \
   84.43 +                        loadcs(readmeml(ss, SP + 4) & 0xffff);  \
   84.44 +                }                                               \
   84.45 +                if (abrt) return 0;                             \
   84.46 +                if (stack32) ESP += 8 + stack_offset;           \
   84.47 +                else         SP  += 8 + stack_offset;           \
   84.48 +                cycles -= is486 ? 13 : 18;
   84.49 +
   84.50 +static int opRETF_a16(uint32_t fetchdat)
   84.51 +{
   84.52 +        RETF_a16(0);
   84.53 +        return 0;
   84.54 +}
   84.55 +static int opRETF_a32(uint32_t fetchdat)
   84.56 +{
   84.57 +        RETF_a32(0);
   84.58 +        return 0;
   84.59 +}
   84.60 +
   84.61 +static int opRETF_a16_imm(uint32_t fetchdat)
   84.62 +{
   84.63 +        uint16_t offset = getwordf();
   84.64 +        RETF_a16(offset);
   84.65 +        return 0;
   84.66 +}
   84.67 +static int opRETF_a32_imm(uint32_t fetchdat)
   84.68 +{
   84.69 +        uint16_t offset = getwordf();
   84.70 +        RETF_a32(offset);
   84.71 +        return 0;
   84.72 +}
   84.73 +
   84.74 +static int opIRET(uint32_t fetchdat)
   84.75 +{
   84.76 +        if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
   84.77 +        {
   84.78 +                x86gpf(NULL,0);
   84.79 +                return 0;
   84.80 +        }
   84.81 +        if (ssegs) ss = oldss;
   84.82 +        if (msw&1)
   84.83 +        {
   84.84 +                optype = IRET;
   84.85 +                pmodeiret(0);
   84.86 +                optype = 0;
   84.87 +        }
   84.88 +        else
   84.89 +        {
   84.90 +                uint16_t new_cs;
   84.91 +                oxpc = pc;
   84.92 +                if (stack32)
   84.93 +                {
   84.94 +                        pc = readmemw(ss, ESP);
   84.95 +                        new_cs = readmemw(ss, ESP + 2);
   84.96 +                        flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
   84.97 +                        ESP += 6;
   84.98 +                }
   84.99 +                else
  84.100 +                {
  84.101 +                        pc = readmemw(ss, SP);
  84.102 +                        new_cs = readmemw(ss, ((SP + 2) & 0xffff));
  84.103 +                        flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
  84.104 +                        SP += 6;
  84.105 +                }
  84.106 +                loadcs(new_cs);
  84.107 +        }
  84.108 +        flags_extract();
  84.109 +        cycles -= is486 ? 15 : 22;
  84.110 +        nmi_enable = 1;
  84.111 +        return 0;
  84.112 +}
  84.113 +
  84.114 +static int opIRETD(uint32_t fetchdat)
  84.115 +{
  84.116 +        if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
  84.117 +        {
  84.118 +                x86gpf(NULL,0);
  84.119 +                return 0;
  84.120 +        }
  84.121 +        if (ssegs) ss = oldss;
  84.122 +        if (msw & 1)
  84.123 +        {
  84.124 +                optype = IRET;
  84.125 +                pmodeiret(1);
  84.126 +                optype = 0;
  84.127 +        }
  84.128 +        else
  84.129 +        {
  84.130 +                uint16_t new_cs;
  84.131 +                oxpc = pc;
  84.132 +                if (stack32)
  84.133 +                {
  84.134 +                        pc = readmeml(ss, ESP);
  84.135 +                        new_cs = readmemw(ss, ESP + 4);
  84.136 +                        flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
  84.137 +                        eflags = readmemw(ss, ESP + 10);
  84.138 +                        ESP += 12;
  84.139 +                }
  84.140 +                else
  84.141 +                {
  84.142 +                        pc = readmeml(ss, SP);
  84.143 +                        new_cs = readmemw(ss, ((SP + 4) & 0xffff));
  84.144 +                        flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2;
  84.145 +                        eflags = readmemw(ss, (SP + 10) & 0xffff);
  84.146 +                        SP += 12;
  84.147 +                }
  84.148 +                loadcs(new_cs);
  84.149 +        }
  84.150 +        flags_extract();
  84.151 +        cycles -= is486 ? 15 : 22;
  84.152 +        nmi_enable = 1;
  84.153 +        return 0;
  84.154 +}
  84.155 + 
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/src/x86_ops_set.h	Mon May 27 19:56:33 2013 +0100
    85.3 @@ -0,0 +1,33 @@
    85.4 +#define opSET(condition)                                                \
    85.5 +        static int opSET ## condition ## _a16(uint32_t fetchdat)        \
    85.6 +        {                                                               \
    85.7 +                fetch_ea_16(fetchdat);                                  \
    85.8 +                seteab((cond_ ## condition) ? 1 : 0);                   \
    85.9 +                cycles -= 4;                                            \
   85.10 +                return 0;                                               \
   85.11 +        }                                                               \
   85.12 +                                                                        \
   85.13 +        static int opSET ## condition ## _a32(uint32_t fetchdat)        \
   85.14 +        {                                                               \
   85.15 +                fetch_ea_32(fetchdat);                                  \
   85.16 +                seteab((cond_ ## condition) ? 1 : 0);                   \
   85.17 +                cycles -= 4;                                            \
   85.18 +                return 0;                                               \
   85.19 +        }
   85.20 +
   85.21 +opSET(O)
   85.22 +opSET(NO)
   85.23 +opSET(B)
   85.24 +opSET(NB)
   85.25 +opSET(E)
   85.26 +opSET(NE)
   85.27 +opSET(BE)
   85.28 +opSET(NBE)
   85.29 +opSET(S)
   85.30 +opSET(NS)
   85.31 +opSET(P)
   85.32 +opSET(NP)
   85.33 +opSET(L)
   85.34 +opSET(NL)
   85.35 +opSET(LE)
   85.36 +opSET(NLE)
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/src/x86_ops_shift.h	Mon May 27 19:56:33 2013 +0100
    86.3 @@ -0,0 +1,595 @@
    86.4 +#define OP_SHIFT_b(c)                                                           \
    86.5 +        if (!c) return 0;                                                       \
    86.6 +        flags_rebuild();                                                        \
    86.7 +        switch (rmdat & 0x38)                                                   \
    86.8 +        {                                                                       \
    86.9 +                case 0x00: /*ROL b, c*/                                         \
   86.10 +                while (c > 0)                                                   \
   86.11 +                {                                                               \
   86.12 +                        temp2 = (temp & 0x80) ? 1 : 0;                          \
   86.13 +                        temp = (temp << 1) | temp2;                             \
   86.14 +                        c--;                                                    \
   86.15 +                }                                                               \
   86.16 +                seteab(temp);           if (abrt) return 0;                     \
   86.17 +                flags &= ~(C_FLAG | V_FLAG);                                    \
   86.18 +                if (temp2) flags |= C_FLAG;                                     \
   86.19 +                if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG;            \
   86.20 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
   86.21 +                break;                                                          \
   86.22 +                case 0x08: /*ROR b,CL*/                                         \
   86.23 +                while (c > 0)                                                   \
   86.24 +                {                                                               \
   86.25 +                        temp2 = temp & 1;                                       \
   86.26 +                        temp >>= 1;                                             \
   86.27 +                        if (temp2) temp |= 0x80;                                \
   86.28 +                        c--;                                                    \
   86.29 +                }                                                               \
   86.30 +                seteab(temp);           if (abrt) return 0;                     \
   86.31 +                flags &= ~(C_FLAG | V_FLAG);                                    \
   86.32 +                if (temp2) flags |= C_FLAG;                                     \
   86.33 +                if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG;               \
   86.34 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
   86.35 +                break;                                                          \
   86.36 +                case 0x10: /*RCL b,CL*/                                         \
   86.37 +                temp2 = flags & C_FLAG;                                         \
   86.38 +                while (c > 0)                                                   \
   86.39 +                {                                                               \
   86.40 +                        tempc = temp2 ? 1 : 0;                                  \
   86.41 +                        temp2 = temp & 0x80;                                    \
   86.42 +                        temp = (temp << 1) | tempc;                             \
   86.43 +                        c--;                                                    \
   86.44 +                        if (is486) cycles--;                                    \
   86.45 +                }                                                               \
   86.46 +                seteab(temp);           if (abrt) return 0;                     \
   86.47 +                flags &= ~(C_FLAG | V_FLAG);                                    \
   86.48 +                if (temp2) flags |= C_FLAG;                                     \
   86.49 +                if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG;            \
   86.50 +                cycles -= ((mod == 3) ? 9 : 10);                                \
   86.51 +                break;                                                          \
   86.52 +                case 0x18: /*RCR b,CL*/                                         \
   86.53 +                temp2 = flags & C_FLAG;                                         \
   86.54 +                while (c > 0)                                                   \
   86.55 +                {                                                               \
   86.56 +                        tempc = temp2 ? 0x80 : 0;                               \
   86.57 +                        temp2 = temp & 1;                                       \
   86.58 +                        temp = (temp >> 1) | tempc;                             \
   86.59 +                        c--;                                                    \
   86.60 +                        if (is486) cycles--;                                    \
   86.61 +                }                                                               \
   86.62 +                seteab(temp);           if (abrt) return 0;                     \
   86.63 +                flags &= ~(C_FLAG | V_FLAG);                                    \
   86.64 +                if (temp2) flags |= C_FLAG;                                     \
   86.65 +                if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG;               \
   86.66 +                cycles -= ((mod == 3) ? 9 : 10);                                \
   86.67 +                break;                                                          \
   86.68 +                case 0x20: case 0x30: /*SHL b,CL*/                              \
   86.69 +                seteab(temp << c);      if (abrt) return 0;                     \
   86.70 +                setznp8(temp << c);                                             \
   86.71 +                if ((temp << (c - 1)) & 0x80) flags |= C_FLAG;                  \
   86.72 +                if (((temp << c) ^ (temp << (c - 1))) & 0x80) flags |= V_FLAG;  \
   86.73 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
   86.74 +                break;                                                          \
   86.75 +                case 0x28: /*SHR b,CL*/                                         \
   86.76 +                seteab(temp >> c);      if (abrt) return 0;                     \
   86.77 +                setznp8(temp >> c);                                             \
   86.78 +                if ((temp >> (c - 1)) & 1) flags |= C_FLAG;                     \
   86.79 +                if (c == 1 && temp & 0x80) flags |= V_FLAG;                     \
   86.80 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
   86.81 +                break;                                                          \
   86.82 +                case 0x38: /*SAR b,CL*/                                         \
   86.83 +                tempc = ((temp >> (c - 1)) & 1);                                \
   86.84 +                while (c > 0)                                                   \
   86.85 +                {                                                               \
   86.86 +                        temp >>= 1;                                             \
   86.87 +                        if (temp & 0x40) temp |= 0x80;                          \
   86.88 +                        c--;                                                    \
   86.89 +                }                                                               \
   86.90 +                seteab(temp);           if (abrt) return 0;                     \
   86.91 +                setznp8(temp);                                                  \
   86.92 +                if (tempc) flags |= C_FLAG;                                     \
   86.93 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
   86.94 +                break;                                                          \
   86.95 +        }
   86.96 +
   86.97 +#define OP_SHIFT_w(c)                                                           \
   86.98 +        if (!c) return 0;                                                       \
   86.99 +        flags_rebuild();                                                        \
  86.100 +        switch (rmdat & 0x38)                                                   \
  86.101 +        {                                                                       \
  86.102 +                case 0x00: /*ROL w, c*/                                         \
  86.103 +                while (c > 0)                                                   \
  86.104 +                {                                                               \
  86.105 +                        temp2 = (temp & 0x8000) ? 1 : 0;                        \
  86.106 +                        temp = (temp << 1) | temp2;                             \
  86.107 +                        c--;                                                    \
  86.108 +                }                                                               \
  86.109 +                seteaw(temp);           if (abrt) return 0;                     \
  86.110 +                flags &= ~(C_FLAG | V_FLAG);                                    \
  86.111 +                if (temp2) flags |= C_FLAG;                                     \
  86.112 +                if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG;           \
  86.113 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
  86.114 +                break;                                                          \
  86.115 +                case 0x08: /*ROR w, c*/                                         \
  86.116 +                while (c > 0)                                                   \
  86.117 +                {                                                               \
  86.118 +                        temp2 = temp & 1;                                       \
  86.119 +                        temp >>= 1;                                             \
  86.120 +                        if (temp2) temp |= 0x8000;                              \
  86.121 +                        c--;                                                    \
  86.122 +                }                                                               \
  86.123 +                seteaw(temp);           if (abrt) return 0;                     \
  86.124 +                flags &= ~(C_FLAG | V_FLAG);                                    \
  86.125 +                if (temp2) flags |= C_FLAG;                                     \
  86.126 +                if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG;             \
  86.127 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
  86.128 +                break;                                                          \
  86.129 +                case 0x10: /*RCL w, c*/                                         \
  86.130 +                temp2 = flags & C_FLAG;                                         \
  86.131 +                while (c > 0)                                                   \
  86.132 +                {                                                               \
  86.133 +                        tempc = temp2 ? 1 : 0;                                  \
  86.134 +                        temp2 = temp & 0x8000;                                  \
  86.135 +                        temp = (temp << 1) | tempc;                             \
  86.136 +                        c--;                                                    \
  86.137 +                        if (is486) cycles--;                                    \
  86.138 +                }                                                               \
  86.139 +                seteaw(temp);           if (abrt) return 0;                     \
  86.140 +                flags &= ~(C_FLAG | V_FLAG);                                    \
  86.141 +                if (temp2) flags |= C_FLAG;                                     \
  86.142 +                if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG;           \
  86.143 +                cycles -= ((mod == 3) ? 9 : 10);                                \
  86.144 +                break;                                                          \
  86.145 +                case 0x18: /*RCR w, c*/                                         \
  86.146 +                temp2 = flags & C_FLAG;                                         \
  86.147 +                while (c > 0)                                                   \
  86.148 +                {                                                               \
  86.149 +                        tempc = temp2 ? 0x8000 : 0;                             \
  86.150 +                        temp2 = temp & 1;                                       \
  86.151 +                        temp = (temp >> 1) | tempc;                             \
  86.152 +                        c--;                                                    \
  86.153 +                        if (is486) cycles--;                                    \
  86.154 +                }                                                               \
  86.155 +                seteaw(temp);           if (abrt) return 0;                     \
  86.156 +                flags &= ~(C_FLAG | V_FLAG);                                    \
  86.157 +                if (temp2) flags |= C_FLAG;                                     \
  86.158 +                if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG;             \
  86.159 +                cycles -= ((mod == 3) ? 9 : 10);                                \
  86.160 +                break;                                                          \
  86.161 +                case 0x20: case 0x30: /*SHL w, c*/                              \
  86.162 +                seteaw(temp << c);      if (abrt) return 0;                     \
  86.163 +                setznp16(temp << c);                                            \
  86.164 +                if ((temp << (c - 1)) & 0x8000) flags |= C_FLAG;                \
  86.165 +                if (((temp << c) ^ (temp << (c - 1))) & 0x8000) flags |= V_FLAG;\
  86.166 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
  86.167 +                break;                                                          \
  86.168 +                case 0x28: /*SHR w, c*/                                         \
  86.169 +                seteaw(temp >> c);      if (abrt) return 0;                     \
  86.170 +                setznp16(temp >> c);                                            \
  86.171 +                if ((temp >> (c - 1)) & 1) flags |= C_FLAG;                     \
  86.172 +                if (c == 1 && temp & 0x8000) flags |= V_FLAG;                   \
  86.173 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
  86.174 +                break;                                                          \
  86.175 +                case 0x38: /*SAR w, c*/                                         \
  86.176 +                tempc = ((temp >> (c - 1)) & 1);                                \
  86.177 +                while (c > 0)                                                   \
  86.178 +                {                                                               \
  86.179 +                        temp >>= 1;                                             \
  86.180 +                        if (temp & 0x4000) temp |= 0x8000;                      \
  86.181 +                        c--;                                                    \
  86.182 +                }                                                               \
  86.183 +                seteaw(temp);           if (abrt) return 0;                     \
  86.184 +                setznp16(temp);                                                 \
  86.185 +                if (tempc) flags |= C_FLAG;                                     \
  86.186 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
  86.187 +                break;                                                          \
  86.188 +        }
  86.189 +
  86.190 +#define OP_SHIFT_l(c)                                                           \
  86.191 +        if (!c) return 0;                                                       \
  86.192 +        flags_rebuild();                                                        \
  86.193 +        switch (rmdat & 0x38)                                                   \
  86.194 +        {                                                                       \
  86.195 +                case 0x00: /*ROL l, c*/                                         \
  86.196 +                while (c > 0)                                                   \
  86.197 +                {                                                               \
  86.198 +                        temp2 = (temp & 0x80000000) ? 1 : 0;                    \
  86.199 +                        temp = (temp << 1) | temp2;                             \
  86.200 +                        c--;                                                    \
  86.201 +                }                                                               \
  86.202 +                seteal(temp);           if (abrt) return 0;                     \
  86.203 +                flags &= ~(C_FLAG | V_FLAG);                                    \
  86.204 +                if (temp2) flags |= C_FLAG;                                     \
  86.205 +                if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG;           \
  86.206 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
  86.207 +                break;                                                          \
  86.208 +                case 0x08: /*ROR l, c*/                                         \
  86.209 +                while (c > 0)                                                   \
  86.210 +                {                                                               \
  86.211 +                        temp2 = temp & 1;                                       \
  86.212 +                        temp >>= 1;                                             \
  86.213 +                        if (temp2) temp |= 0x80000000;                          \
  86.214 +                        c--;                                                    \
  86.215 +                }                                                               \
  86.216 +                seteal(temp);           if (abrt) return 0;                     \
  86.217 +                flags &= ~(C_FLAG | V_FLAG);                                    \
  86.218 +                if (temp2) flags |= C_FLAG;                                     \
  86.219 +                if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG;         \
  86.220 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
  86.221 +                break;                                                          \
  86.222 +                case 0x10: /*RCL l, c*/                                         \
  86.223 +                temp2 = flags & C_FLAG;                                         \
  86.224 +                while (c > 0)                                                   \
  86.225 +                {                                                               \
  86.226 +                        tempc = temp2 ? 1 : 0;                                  \
  86.227 +                        temp2 = temp & 0x80000000;                              \
  86.228 +                        temp = (temp << 1) | tempc;                             \
  86.229 +                        c--;                                                    \
  86.230 +                        if (is486) cycles--;                                    \
  86.231 +                }                                                               \
  86.232 +                seteal(temp);           if (abrt) return 0;                     \
  86.233 +                flags &= ~(C_FLAG | V_FLAG);                                    \
  86.234 +                if (temp2) flags |= C_FLAG;                                     \
  86.235 +                if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG;           \
  86.236 +                cycles -= ((mod == 3) ? 9 : 10);                                \
  86.237 +                break;                                                          \
  86.238 +                case 0x18: /*RCR l, c*/                                         \
  86.239 +                temp2 = flags & C_FLAG;                                         \
  86.240 +                while (c > 0)                                                   \
  86.241 +                {                                                               \
  86.242 +                        tempc = temp2 ? 0x80000000 : 0;                         \
  86.243 +                        temp2 = temp & 1;                                       \
  86.244 +                        temp = (temp >> 1) | tempc;                             \
  86.245 +                        c--;                                                    \
  86.246 +                        if (is486) cycles--;                                    \
  86.247 +                }                                                               \
  86.248 +                seteal(temp);           if (abrt) return 0;                     \
  86.249 +                flags &= ~(C_FLAG | V_FLAG);                                    \
  86.250 +                if (temp2) flags |= C_FLAG;                                     \
  86.251 +                if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG;         \
  86.252 +                cycles -= ((mod == 3) ? 9 : 10);                                \
  86.253 +                break;                                                          \
  86.254 +                case 0x20: case 0x30: /*SHL l, c*/                              \
  86.255 +                seteal(temp << c);      if (abrt) return 0;                     \
  86.256 +                setznp32(temp << c);                                            \
  86.257 +                if ((temp << (c - 1)) & 0x80000000) flags |= C_FLAG;            \
  86.258 +                if (((temp << c) ^ (temp << (c - 1))) & 0x80000000) flags |= V_FLAG;\
  86.259 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
  86.260 +                break;                                                          \
  86.261 +                case 0x28: /*SHR l, c*/                                         \
  86.262 +                seteal(temp >> c);      if (abrt) return 0;                     \
  86.263 +                setznp32(temp >> c);                                            \
  86.264 +                if ((temp >> (c - 1)) & 1) flags |= C_FLAG;                     \
  86.265 +                if (c == 1 && temp & 0x80000000) flags |= V_FLAG;               \
  86.266 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
  86.267 +                break;                                                          \
  86.268 +                case 0x38: /*SAR l, c*/                                         \
  86.269 +                tempc = ((temp >> (c - 1)) & 1);                                \
  86.270 +                while (c > 0)                                                   \
  86.271 +                {                                                               \
  86.272 +                        temp >>= 1;                                             \
  86.273 +                        if (temp & 0x40000000) temp |= 0x80000000;              \
  86.274 +                        c--;                                                    \
  86.275 +                }                                                               \
  86.276 +                seteal(temp);           if (abrt) return 0;                     \
  86.277 +                setznp32(temp);                                                 \
  86.278 +                if (tempc) flags |= C_FLAG;                                     \
  86.279 +                cycles -= ((mod == 3) ? 3 : 7);                                 \
  86.280 +                break;                                                          \
  86.281 +        }
  86.282 +
  86.283 +static int opC0_a16(uint32_t fetchdat)
  86.284 +{
  86.285 +        int c;
  86.286 +        int tempc;
  86.287 +        uint8_t temp, temp2;
  86.288 +        
  86.289 +        fetch_ea_16(fetchdat);
  86.290 +        c = readmemb(cs, pc) & 31; pc++;
  86.291 +        temp = geteab();                if (abrt) return 0;
  86.292 +        OP_SHIFT_b(c);
  86.293 +        return 0;
  86.294 +}
  86.295 +static int opC0_a32(uint32_t fetchdat)
  86.296 +{
  86.297 +        int c;
  86.298 +        int tempc;
  86.299 +        uint8_t temp, temp2;
  86.300 +        
  86.301 +        fetch_ea_32(fetchdat);
  86.302 +        c = readmemb(cs, pc) & 31; pc++;
  86.303 +        temp = geteab();                if (abrt) return 0;
  86.304 +        OP_SHIFT_b(c);
  86.305 +        return 0;
  86.306 +}
  86.307 +static int opC1_w_a16(uint32_t fetchdat)
  86.308 +{
  86.309 +        int c;
  86.310 +        int tempc;
  86.311 +        uint16_t temp, temp2;
  86.312 +        
  86.313 +        fetch_ea_16(fetchdat);
  86.314 +        c = readmemb(cs, pc) & 31; pc++;
  86.315 +        temp = geteaw();                if (abrt) return 0;
  86.316 +        OP_SHIFT_w(c);
  86.317 +        return 0;
  86.318 +}
  86.319 +static int opC1_w_a32(uint32_t fetchdat)
  86.320 +{
  86.321 +        int c;
  86.322 +        int tempc;
  86.323 +        uint16_t temp, temp2;
  86.324 +        
  86.325 +        fetch_ea_32(fetchdat);
  86.326 +        c = readmemb(cs, pc) & 31; pc++;
  86.327 +        temp = geteaw();                if (abrt) return 0;
  86.328 +        OP_SHIFT_w(c);
  86.329 +        return 0;
  86.330 +}
  86.331 +static int opC1_l_a16(uint32_t fetchdat)
  86.332 +{
  86.333 +        int c;
  86.334 +        int tempc;
  86.335 +        uint32_t temp, temp2;
  86.336 +        
  86.337 +        fetch_ea_16(fetchdat);
  86.338 +        c = readmemb(cs, pc) & 31; pc++;
  86.339 +        temp = geteal();                if (abrt) return 0;
  86.340 +        OP_SHIFT_l(c);
  86.341 +        return 0;
  86.342 +}
  86.343 +static int opC1_l_a32(uint32_t fetchdat)
  86.344 +{
  86.345 +        int c;
  86.346 +        int tempc;
  86.347 +        uint32_t temp, temp2;
  86.348 +        
  86.349 +        fetch_ea_32(fetchdat);
  86.350 +        c = readmemb(cs, pc) & 31; pc++;
  86.351 +        temp = geteal();                if (abrt) return 0;
  86.352 +        OP_SHIFT_l(c);
  86.353 +        return 0;
  86.354 +}
  86.355 +
  86.356 +static int opD0_a16(uint32_t fetchdat)
  86.357 +{
  86.358 +        int c = 1;
  86.359 +        int tempc;
  86.360 +        uint8_t temp, temp2;
  86.361 +        
  86.362 +        fetch_ea_16(fetchdat);
  86.363 +        temp = geteab();                if (abrt) return 0;
  86.364 +        OP_SHIFT_b(c);
  86.365 +        return 0;
  86.366 +}
  86.367 +static int opD0_a32(uint32_t fetchdat)
  86.368 +{
  86.369 +        int c = 1;
  86.370 +        int tempc;
  86.371 +        uint8_t temp, temp2;
  86.372 +        
  86.373 +        fetch_ea_32(fetchdat);
  86.374 +        temp = geteab();                if (abrt) return 0;
  86.375 +        OP_SHIFT_b(c);
  86.376 +        return 0;
  86.377 +}
  86.378 +static int opD1_w_a16(uint32_t fetchdat)
  86.379 +{
  86.380 +        int c = 1;
  86.381 +        int tempc;
  86.382 +        uint16_t temp, temp2;
  86.383 +        
  86.384 +        fetch_ea_16(fetchdat);
  86.385 +        temp = geteaw();                if (abrt) return 0;
  86.386 +        OP_SHIFT_w(c);
  86.387 +        return 0;
  86.388 +}
  86.389 +static int opD1_w_a32(uint32_t fetchdat)
  86.390 +{
  86.391 +        int c = 1;
  86.392 +        int tempc;
  86.393 +        uint16_t temp, temp2;
  86.394 +        
  86.395 +        fetch_ea_32(fetchdat);
  86.396 +        temp = geteaw();                if (abrt) return 0;
  86.397 +        OP_SHIFT_w(c);
  86.398 +        return 0;
  86.399 +}
  86.400 +static int opD1_l_a16(uint32_t fetchdat)
  86.401 +{
  86.402 +        int c = 1;
  86.403 +        int tempc;
  86.404 +        uint32_t temp, temp2;
  86.405 +        
  86.406 +        fetch_ea_16(fetchdat);
  86.407 +        temp = geteal();                if (abrt) return 0;
  86.408 +        OP_SHIFT_l(c);
  86.409 +        return 0;
  86.410 +}
  86.411 +static int opD1_l_a32(uint32_t fetchdat)
  86.412 +{
  86.413 +        int c = 1;
  86.414 +        int tempc;
  86.415 +        uint32_t temp, temp2;
  86.416 +        
  86.417 +        fetch_ea_32(fetchdat);
  86.418 +        temp = geteal();                if (abrt) return 0;
  86.419 +        OP_SHIFT_l(c);
  86.420 +        return 0;
  86.421 +}
  86.422 +
  86.423 +static int opD2_a16(uint32_t fetchdat)
  86.424 +{
  86.425 +        int c;
  86.426 +        int tempc;
  86.427 +        uint8_t temp, temp2;
  86.428 +        
  86.429 +        fetch_ea_16(fetchdat);
  86.430 +        c = CL & 31;
  86.431 +        temp = geteab();                if (abrt) return 0;
  86.432 +        OP_SHIFT_b(c);
  86.433 +        return 0;
  86.434 +}
  86.435 +static int opD2_a32(uint32_t fetchdat)
  86.436 +{
  86.437 +        int c;
  86.438 +        int tempc;
  86.439 +        uint8_t temp, temp2;
  86.440 +        
  86.441 +        fetch_ea_32(fetchdat);
  86.442 +        c = CL & 31;
  86.443 +        temp = geteab();                if (abrt) return 0;
  86.444 +        OP_SHIFT_b(c);
  86.445 +        return 0;
  86.446 +}
  86.447 +static int opD3_w_a16(uint32_t fetchdat)
  86.448 +{
  86.449 +        int c;
  86.450 +        int tempc;
  86.451 +        uint16_t temp, temp2;
  86.452 +        
  86.453 +        fetch_ea_16(fetchdat);
  86.454 +        c = CL & 31;
  86.455 +        temp = geteaw();                if (abrt) return 0;
  86.456 +        OP_SHIFT_w(c);
  86.457 +        return 0;
  86.458 +}
  86.459 +static int opD3_w_a32(uint32_t fetchdat)
  86.460 +{
  86.461 +        int c;
  86.462 +        int tempc;
  86.463 +        uint16_t temp, temp2;
  86.464 +        
  86.465 +        fetch_ea_32(fetchdat);
  86.466 +        c = CL & 31;
  86.467 +        temp = geteaw();                if (abrt) return 0;
  86.468 +        OP_SHIFT_w(c);
  86.469 +        return 0;
  86.470 +}
  86.471 +static int opD3_l_a16(uint32_t fetchdat)
  86.472 +{
  86.473 +        int c;
  86.474 +        int tempc;
  86.475 +        uint32_t temp, temp2;
  86.476 +        
  86.477 +        fetch_ea_16(fetchdat);
  86.478 +        c = CL & 31;
  86.479 +        temp = geteal();                if (abrt) return 0;
  86.480 +        OP_SHIFT_l(c);
  86.481 +        return 0;
  86.482 +}
  86.483 +static int opD3_l_a32(uint32_t fetchdat)
  86.484 +{
  86.485 +        int c;
  86.486 +        int tempc;
  86.487 +        uint32_t temp, temp2;
  86.488 +        
  86.489 +        fetch_ea_32(fetchdat);
  86.490 +        c = CL & 31;
  86.491 +        temp = geteal();                if (abrt) return 0;
  86.492 +        OP_SHIFT_l(c);
  86.493 +        return 0;
  86.494 +}
  86.495 +
  86.496 +
  86.497 +#define SHLD_w()                                                                \
  86.498 +        if (count)                                                              \
  86.499 +        {                                                                       \
  86.500 +                uint16_t tempw = geteaw();      if (abrt) return 0;             \
  86.501 +                int tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0;       \
  86.502 +                uint32_t templ = (tempw << 16) | regs[reg].w;                   \
  86.503 +                if (count <= 16) tempw =  templ >> (16 - count);                \
  86.504 +                else             tempw = (templ << count) >> 16;                \
  86.505 +                seteaw(tempw);                  if (abrt) return 0;             \
  86.506 +                setznp16(tempw);                                                \
  86.507 +                flags_rebuild();                                                \
  86.508 +                if (tempc) flags |= C_FLAG;                                     \
  86.509 +        }
  86.510 +
  86.511 +#define SHLD_l()                                                                \
  86.512 +        if (count)                                                              \
  86.513 +        {                                                                       \
  86.514 +                uint32_t templ = geteal();      if (abrt) return 0;             \
  86.515 +                int tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0;       \
  86.516 +                templ = (templ << count) | (regs[reg].l >> (32 - count));       \
  86.517 +                seteal(templ);                  if (abrt) return 0;             \
  86.518 +                setznp32(templ);                                                \
  86.519 +                flags_rebuild();                                                \
  86.520 +                if (tempc) flags |= C_FLAG;                                     \
  86.521 +        }
  86.522 +
  86.523 +
  86.524 +#define SHRD_w()                                                                \
  86.525 +        if (count)                                                              \
  86.526 +        {                                                                       \
  86.527 +                uint16_t tempw = geteaw();      if (abrt) return 0;             \
  86.528 +                int tempc = (tempw >> (count - 1)) & 1;                         \
  86.529 +                uint32_t templ = tempw | (regs[reg].w << 16);                   \
  86.530 +                tempw = templ >> count;                                         \
  86.531 +                seteaw(tempw);                  if (abrt) return 0;             \
  86.532 +                setznp16(tempw);                                                \
  86.533 +                flags_rebuild();                                                \
  86.534 +                if (tempc) flags |= C_FLAG;                                     \
  86.535 +        }
  86.536 +
  86.537 +#define SHRD_l()                                                                \
  86.538 +        if (count)                                                              \
  86.539 +        {                                                                       \
  86.540 +                uint32_t templ = geteal();      if (abrt) return 0;             \
  86.541 +                int tempc = (templ >> (count - 1)) & 1;                         \
  86.542 +                templ = (templ >> count) | (regs[reg].l << (32 - count));       \
  86.543 +                seteal(templ);                  if (abrt) return 0;             \
  86.544 +                setznp32(templ);                                                \
  86.545 +                flags_rebuild();                                                \
  86.546 +                if (tempc) flags |= C_FLAG;                                     \
  86.547 +        }
  86.548 +
  86.549 +#define opSHxD(operation)                                                       \
  86.550 +        static int op ## operation ## _i_a16(uint32_t fetchdat)                 \
  86.551 +        {                                                                       \
  86.552 +                int count;                                                      \
  86.553 +                                                                                \
  86.554 +                fetch_ea_16(fetchdat);                                          \
  86.555 +                count = getbyte() & 31;                                         \
  86.556 +                operation();                                                    \
  86.557 +                                                                                \
  86.558 +                cycles -= 3;                                                    \
  86.559 +                return 0;                                                       \
  86.560 +        }                                                                       \
  86.561 +        static int op ## operation ## _CL_a16(uint32_t fetchdat)                \
  86.562 +        {                                                                       \
  86.563 +                int count;                                                      \
  86.564 +                                                                                \
  86.565 +                fetch_ea_16(fetchdat);                                          \
  86.566 +                count = CL & 31;                                                \
  86.567 +                operation();                                                    \
  86.568 +                                                                                \
  86.569 +                cycles -= 3;                                                    \
  86.570 +                return 0;                                                       \
  86.571 +        }                                                                       \
  86.572 +        static int op ## operation ## _i_a32(uint32_t fetchdat)                 \
  86.573 +        {                                                                       \
  86.574 +                int count;                                                      \
  86.575 +                                                                                \
  86.576 +                fetch_ea_32(fetchdat);                                          \
  86.577 +                count = getbyte() & 31;                                         \
  86.578 +                operation();                                                    \
  86.579 +                                                                                \
  86.580 +                cycles -= 3;                                                    \
  86.581 +                return 0;                                                       \
  86.582 +        }                                                                       \
  86.583 +        static int op ## operation ## _CL_a32(uint32_t fetchdat)                \
  86.584 +        {                                                                       \
  86.585 +                int count;                                                      \
  86.586 +                                                                                \
  86.587 +                fetch_ea_32(fetchdat);                                          \
  86.588 +                count = CL & 31;                                                \
  86.589 +                operation();                                                    \
  86.590 +                                                                                \
  86.591 +                cycles -= 3;                                                    \
  86.592 +                return 0;                                                       \
  86.593 +        }
  86.594 +              
  86.595 +opSHxD(SHLD_w)
  86.596 +opSHxD(SHLD_l)
  86.597 +opSHxD(SHRD_w)
  86.598 +opSHxD(SHRD_l)
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/src/x86_ops_stack.h	Mon May 27 19:56:33 2013 +0100
    87.3 @@ -0,0 +1,447 @@
    87.4 +#define PUSH_W_OP(reg)                                                                          \
    87.5 +        static int opPUSH_ ## reg (uint32_t fetchdat)                                                  \
    87.6 +        {                                                                                       \
    87.7 +                if (ssegs) ss=oldss;                                                            \
    87.8 +                PUSH_W(reg);                                                                    \
    87.9 +                cycles -= (is486) ? 1 : 2;                                                      \
   87.10 +                return 0;                                                                       \
   87.11 +        }
   87.12 +
   87.13 +#define PUSH_L_OP(reg)                                                                          \
   87.14 +        static int opPUSH_ ## reg (uint32_t fetchdat)                                                  \
   87.15 +        {                                                                                       \
   87.16 +                if (ssegs) ss=oldss;                                                            \
   87.17 +                PUSH_L(reg);                                                                    \
   87.18 +                cycles -= (is486) ? 1 : 2;                                                      \
   87.19 +                return 0;                                                                       \
   87.20 +        }
   87.21 +
   87.22 +#define POP_W_OP(reg)                                                                           \
   87.23 +        static int opPOP_ ## reg (uint32_t fetchdat)                                                   \
   87.24 +        {                                                                                       \
   87.25 +                if (ssegs) ss=oldss;                                                            \
   87.26 +                reg = POP_W();                                                                  \
   87.27 +                cycles -= (is486) ? 1 : 4;                                                      \
   87.28 +                return 0;                                                                       \
   87.29 +        }
   87.30 +
   87.31 +#define POP_L_OP(reg)                                                                           \
   87.32 +        static int opPOP_ ## reg (uint32_t fetchdat)                                                   \
   87.33 +        {                                                                                       \
   87.34 +                if (ssegs) ss=oldss;                                                            \
   87.35 +                reg = POP_L();                                                                  \
   87.36 +                cycles -= (is486) ? 1 : 4;                                                      \
   87.37 +                return 0;                                                                       \
   87.38 +        }
   87.39 +
   87.40 +PUSH_W_OP(AX)
   87.41 +PUSH_W_OP(BX)
   87.42 +PUSH_W_OP(CX)
   87.43 +PUSH_W_OP(DX)
   87.44 +PUSH_W_OP(SI)
   87.45 +PUSH_W_OP(DI)
   87.46 +PUSH_W_OP(BP)
   87.47 +PUSH_W_OP(SP)
   87.48 +
   87.49 +PUSH_L_OP(EAX)
   87.50 +PUSH_L_OP(EBX)
   87.51 +PUSH_L_OP(ECX)
   87.52 +PUSH_L_OP(EDX)
   87.53 +PUSH_L_OP(ESI)
   87.54 +PUSH_L_OP(EDI)
   87.55 +PUSH_L_OP(EBP)
   87.56 +PUSH_L_OP(ESP)
   87.57 +
   87.58 +POP_W_OP(AX)
   87.59 +POP_W_OP(BX)
   87.60 +POP_W_OP(CX)
   87.61 +POP_W_OP(DX)
   87.62 +POP_W_OP(SI)
   87.63 +POP_W_OP(DI)
   87.64 +POP_W_OP(BP)
   87.65 +POP_W_OP(SP)
   87.66 +
   87.67 +POP_L_OP(EAX)
   87.68 +POP_L_OP(EBX)
   87.69 +POP_L_OP(ECX)
   87.70 +POP_L_OP(EDX)
   87.71 +POP_L_OP(ESI)
   87.72 +POP_L_OP(EDI)
   87.73 +POP_L_OP(EBP)
   87.74 +POP_L_OP(ESP)
   87.75 +
   87.76 +
   87.77 +static int opPUSHA_w(uint32_t fetchdat)
   87.78 +{
   87.79 +        if (stack32)
   87.80 +        {
   87.81 +                writememw(ss, ESP -  2, AX);
   87.82 +                writememw(ss, ESP -  4, CX);
   87.83 +                writememw(ss, ESP -  6, DX);
   87.84 +                writememw(ss, ESP -  8, BX);
   87.85 +                writememw(ss, ESP - 10, SP);
   87.86 +                writememw(ss, ESP - 12, BP);
   87.87 +                writememw(ss, ESP - 14, SI);
   87.88 +                writememw(ss, ESP - 16, DI);
   87.89 +                if (!abrt) ESP -= 16;
   87.90 +        }
   87.91 +        else
   87.92 +        {
   87.93 +                writememw(ss, ((SP -  2) & 0xFFFF), AX);
   87.94 +                writememw(ss, ((SP -  4) & 0xFFFF), CX);
   87.95 +                writememw(ss, ((SP -  6) & 0xFFFF), DX);
   87.96 +                writememw(ss, ((SP -  8) & 0xFFFF), BX);
   87.97 +                writememw(ss, ((SP - 10) & 0xFFFF), SP);
   87.98 +                writememw(ss, ((SP - 12) & 0xFFFF), BP);
   87.99 +                writememw(ss, ((SP - 14) & 0xFFFF), SI);
  87.100 +                writememw(ss, ((SP - 16) & 0xFFFF), DI);
  87.101 +                if (!abrt) SP -= 16;
  87.102 +        }
  87.103 +        cycles -= (is486) ? 11 : 18;
  87.104 +        return 0;
  87.105 +}
  87.106 +static int opPUSHA_l(uint32_t fetchdat)
  87.107 +{
  87.108 +        if (stack32)
  87.109 +        {
  87.110 +                writememl(ss, ESP -  4, EAX);
  87.111 +                writememl(ss, ESP -  8, ECX);
  87.112 +                writememl(ss, ESP - 12, EDX);
  87.113 +                writememl(ss, ESP - 16, EBX);
  87.114 +                writememl(ss, ESP - 20, ESP);
  87.115 +                writememl(ss, ESP - 24, EBP);
  87.116 +                writememl(ss, ESP - 28, ESI);
  87.117 +                writememl(ss, ESP - 32, EDI);
  87.118 +                if (!abrt) ESP -= 32;
  87.119 +        }
  87.120 +        else
  87.121 +        {
  87.122 +                writememl(ss, ((SP -  4) & 0xFFFF), EAX);
  87.123 +                writememl(ss, ((SP -  8) & 0xFFFF), ECX);
  87.124 +                writememl(ss, ((SP - 12) & 0xFFFF), EDX);
  87.125 +                writememl(ss, ((SP - 16) & 0xFFFF), EBX);
  87.126 +                writememl(ss, ((SP - 20) & 0xFFFF), ESP);
  87.127 +                writememl(ss, ((SP - 24) & 0xFFFF), EBP);
  87.128 +                writememl(ss, ((SP - 28) & 0xFFFF), ESI);
  87.129 +                writememl(ss, ((SP - 32) & 0xFFFF), EDI);
  87.130 +                if (!abrt) SP -= 32;
  87.131 +        }
  87.132 +        cycles -= (is486) ? 11 : 18;
  87.133 +        return 0;
  87.134 +}
  87.135 +
  87.136 +static int opPOPA_w(uint32_t fetchdat)
  87.137 +{
  87.138 +        if (stack32)
  87.139 +        {
  87.140 +                DI = readmemw(ss, ESP);                         if (abrt) return 0;
  87.141 +                SI = readmemw(ss, ESP +  2);                    if (abrt) return 0;
  87.142 +                BP = readmemw(ss, ESP +  4);                    if (abrt) return 0;
  87.143 +                BX = readmemw(ss, ESP +  8);                    if (abrt) return 0;
  87.144 +                DX = readmemw(ss, ESP + 10);                    if (abrt) return 0;
  87.145 +                CX = readmemw(ss, ESP + 12);                    if (abrt) return 0;
  87.146 +                AX = readmemw(ss, ESP + 14);                    if (abrt) return 0;
  87.147 +                ESP += 16;
  87.148 +        }
  87.149 +        else
  87.150 +        {
  87.151 +                DI = readmemw(ss, ((SP)      & 0xFFFF));        if (abrt) return 0;
  87.152 +                SI = readmemw(ss, ((SP +  2) & 0xFFFF));        if (abrt) return 0;
  87.153 +                BP = readmemw(ss, ((SP +  4) & 0xFFFF));        if (abrt) return 0;
  87.154 +                BX = readmemw(ss, ((SP +  8) & 0xFFFF));        if (abrt) return 0;
  87.155 +                DX = readmemw(ss, ((SP + 10) & 0xFFFF));        if (abrt) return 0;
  87.156 +                CX = readmemw(ss, ((SP + 12) & 0xFFFF));        if (abrt) return 0;
  87.157 +                AX = readmemw(ss, ((SP + 14) & 0xFFFF));        if (abrt) return 0;
  87.158 +                SP += 16;
  87.159 +        }
  87.160 +        cycles -= (is486) ? 9 : 24;
  87.161 +        return 0;
  87.162 +}
  87.163 +static int opPOPA_l(uint32_t fetchdat)
  87.164 +{
  87.165 +        if (stack32)
  87.166 +        {
  87.167 +                EDI = readmeml(ss, ESP);                        if (abrt) return 0;
  87.168 +                ESI = readmeml(ss, ESP +  4);                   if (abrt) return 0;
  87.169 +                EBP = readmeml(ss, ESP +  8);                   if (abrt) return 0;
  87.170 +                EBX = readmeml(ss, ESP + 16);                   if (abrt) return 0;
  87.171 +                EDX = readmeml(ss, ESP + 20);                   if (abrt) return 0;
  87.172 +                ECX = readmeml(ss, ESP + 24);                   if (abrt) return 0;
  87.173 +                EAX = readmeml(ss, ESP + 28);                   if (abrt) return 0;
  87.174 +                ESP += 32;
  87.175 +        }
  87.176 +        else
  87.177 +        {
  87.178 +                EDI = readmeml(ss, ((SP)      & 0xFFFF));       if (abrt) return 0;
  87.179 +                ESI = readmeml(ss, ((SP +  4) & 0xFFFF));       if (abrt) return 0;
  87.180 +                EBP = readmeml(ss, ((SP +  8) & 0xFFFF));       if (abrt) return 0;
  87.181 +                EBX = readmeml(ss, ((SP + 16) & 0xFFFF));       if (abrt) return 0;
  87.182 +                EDX = readmeml(ss, ((SP + 20) & 0xFFFF));       if (abrt) return 0;
  87.183 +                ECX = readmeml(ss, ((SP + 24) & 0xFFFF));       if (abrt) return 0;
  87.184 +                EAX = readmeml(ss, ((SP + 28) & 0xFFFF));       if (abrt) return 0;
  87.185 +                SP += 32;
  87.186 +        }
  87.187 +        cycles -= (is486) ? 9 : 24;
  87.188 +        return 0;
  87.189 +}
  87.190 +
  87.191 +static int opPUSH_imm_w(uint32_t fetchdat)
  87.192 +{
  87.193 +        uint16_t val = getwordf(); 
  87.194 +        if (ssegs) ss=oldss;
  87.195 +        PUSH_W(val);
  87.196 +        cycles -= 2;
  87.197 +        return 0;
  87.198 +}
  87.199 +static int opPUSH_imm_l(uint32_t fetchdat)
  87.200 +{
  87.201 +        uint32_t val = getlong(); 
  87.202 +        if (ssegs) ss=oldss;
  87.203 +        PUSH_L(val);
  87.204 +        cycles -= 2;
  87.205 +        return 0;
  87.206 +}
  87.207 +
  87.208 +static int opPUSH_imm_bw(uint32_t fetchdat)
  87.209 +{
  87.210 +        uint16_t tempw = getbytef();
  87.211 +
  87.212 +        if (tempw & 0x80) tempw |= 0xFF00;
  87.213 +        PUSH_W(tempw);
  87.214 +        
  87.215 +        cycles -= 2;
  87.216 +        return 0;
  87.217 +}
  87.218 +static int opPUSH_imm_bl(uint32_t fetchdat)
  87.219 +{
  87.220 +        uint32_t templ = getbytef();
  87.221 +
  87.222 +        if (templ & 0x80) templ |= 0xFFFFFF00;
  87.223 +        PUSH_L(templ);
  87.224 +        
  87.225 +        cycles -= 2;
  87.226 +        return 0;
  87.227 +}
  87.228 +
  87.229 +static int opPOPW_a16(uint32_t fetchdat)
  87.230 +{
  87.231 +        uint16_t temp;
  87.232 +        
  87.233 +        if (ssegs) ss=oldss;
  87.234 +        temp = POP_W();                                 if (abrt) return 0;
  87.235 +        fetch_ea_16(fetchdat);
  87.236 +        seteaw(temp);
  87.237 +        if (abrt)
  87.238 +        {
  87.239 +                if (stack32) ESP -= 2;
  87.240 +                else         SP -= 2;
  87.241 +        }
  87.242 +                        
  87.243 +        if (is486) cycles -= ((mod == 3) ? 1 : 6);
  87.244 +        else       cycles -= ((mod == 3) ? 4 : 5);
  87.245 +        return 0;
  87.246 +}
  87.247 +static int opPOPW_a32(uint32_t fetchdat)
  87.248 +{
  87.249 +        uint16_t temp;
  87.250 +        
  87.251 +        if (ssegs) ss=oldss;
  87.252 +        temp = POP_W();                                 if (abrt) return 0;
  87.253 +        fetch_ea_32(fetchdat);
  87.254 +        seteaw(temp);
  87.255 +        if (abrt)
  87.256 +        {
  87.257 +                if (stack32) ESP -= 2;
  87.258 +                else         SP -= 2;
  87.259 +        }
  87.260 +                        
  87.261 +        if (is486) cycles -= ((mod == 3) ? 1 : 6);
  87.262 +        else       cycles -= ((mod == 3) ? 4 : 5);
  87.263 +        return 0;
  87.264 +}
  87.265 +
  87.266 +static int opPOPL_a16(uint32_t fetchdat)
  87.267 +{
  87.268 +        uint32_t temp;
  87.269 +
  87.270 +        if (ssegs) ss=oldss;
  87.271 +        temp = POP_L();                                 if (abrt) return 0;
  87.272 +        fetch_ea_16(fetchdat);
  87.273 +        seteal(temp);
  87.274 +        if (abrt)
  87.275 +        {
  87.276 +                if (stack32) ESP -= 4;
  87.277 +                else         SP -= 4;
  87.278 +        }
  87.279 +                        
  87.280 +        if (is486) cycles -= ((mod == 3) ? 1 : 6);
  87.281 +        else       cycles -= ((mod == 3) ? 4 : 5);
  87.282 +        return 0;
  87.283 +}
  87.284 +static int opPOPL_a32(uint32_t fetchdat)
  87.285 +{
  87.286 +        uint32_t temp;
  87.287 +
  87.288 +        if (ssegs) ss=oldss;
  87.289 +        temp = POP_L();                                 if (abrt) return 0;
  87.290 +        fetch_ea_32(fetchdat);
  87.291 +        seteal(temp);
  87.292 +        if (abrt)
  87.293 +        {
  87.294 +                if (stack32) ESP -= 4;
  87.295 +                else         SP -= 4;
  87.296 +        }
  87.297 +                        
  87.298 +        if (is486) cycles -= ((mod == 3) ? 1 : 6);
  87.299 +        else       cycles -= ((mod == 3) ? 4 : 5);
  87.300 +        return 0;
  87.301 +}
  87.302 +
  87.303 +
  87.304 +static int opENTER_w(uint32_t fetchdat)
  87.305 +{
  87.306 +        uint16_t offset = getwordf();
  87.307 +        int count = (fetchdat >> 16) & 0xff; pc++;
  87.308 +        uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr;
  87.309 +        
  87.310 +        PUSH_W(BP);
  87.311 +        frame_ptr = ESP;
  87.312 +        
  87.313 +        if (count > 0)
  87.314 +        {
  87.315 +                while (--count)
  87.316 +                {
  87.317 +                        uint16_t tempw;
  87.318 +                        
  87.319 +                        BP -= 2;
  87.320 +                        tempw = readmemw(ss, BP);
  87.321 +                        if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; }
  87.322 +                        PUSH_W(tempw);
  87.323 +                        if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; }
  87.324 +                        cycles -= (is486) ? 3 : 4;
  87.325 +                }
  87.326 +                PUSH_W(frame_ptr);
  87.327 +                if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; }
  87.328 +                cycles -= (is486) ? 3 : 5;
  87.329 +        }
  87.330 +        BP = frame_ptr;
  87.331 +        
  87.332 +        if (stack32) ESP -= offset;
  87.333 +        else          SP -= offset;
  87.334 +        cycles -= (is486) ? 14 : 10;
  87.335 +        return 0;
  87.336 +}
  87.337 +static int opENTER_l(uint32_t fetchdat)
  87.338 +{
  87.339 +        uint16_t offset = getwordf();
  87.340 +        int count = (fetchdat >> 16) & 0xff; pc++;
  87.341 +        uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr;
  87.342 +        
  87.343 +        PUSH_L(EBP);
  87.344 +        frame_ptr = ESP;
  87.345 +        
  87.346 +        if (count > 0)
  87.347 +        {
  87.348 +                while (--count)
  87.349 +                {
  87.350 +                        uint32_t templ;
  87.351 +                        
  87.352 +                        EBP -= 4;
  87.353 +                        templ = readmeml(ss, EBP);
  87.354 +                        if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; }
  87.355 +                        PUSH_L(templ);
  87.356 +                        if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; }
  87.357 +                        cycles -= (is486) ? 3 : 4;
  87.358 +                }
  87.359 +                PUSH_L(frame_ptr);
  87.360 +                if (abrt) { ESP = tempESP; EBP = tempEBP; return 0; }
  87.361 +                cycles -= (is486) ? 3 : 5;
  87.362 +        }
  87.363 +        EBP = frame_ptr;
  87.364 +        
  87.365 +        if (stack32) ESP -= offset;
  87.366 +        else          SP -= offset;
  87.367 +        cycles -= (is486) ? 14 : 10;
  87.368 +        return 0;
  87.369 +}
  87.370 +
  87.371 +
  87.372 +static int opLEAVE_w(uint32_t fetchdat)
  87.373 +{
  87.374 +        uint32_t tempESP = ESP;
  87.375 +        uint16_t temp;
  87.376 +
  87.377 +        SP = BP;       
  87.378 +        temp = POP_W();
  87.379 +        if (abrt) { ESP = tempESP; return 0; }
  87.380 +        BP = temp;
  87.381 +        
  87.382 +        cycles -= 4;        
  87.383 +        return 0;
  87.384 +}
  87.385 +static int opLEAVE_l(uint32_t fetchdat)
  87.386 +{
  87.387 +        uint32_t tempESP = ESP;
  87.388 +        uint32_t temp;
  87.389 +
  87.390 +        ESP = EBP;       
  87.391 +        temp = POP_L();
  87.392 +        if (abrt) { ESP = tempESP; return 0; }
  87.393 +        EBP = temp;
  87.394 +        
  87.395 +        cycles -= 4;        
  87.396 +        return 0;
  87.397 +}
  87.398 +
  87.399 +
  87.400 +#define PUSH_SEG_OPS(seg)                                                       \
  87.401 +        static int opPUSH_ ## seg ## _w(uint32_t fetchdat)                      \
  87.402 +        {                                                                       \
  87.403 +                if (ssegs) ss=oldss;                                            \
  87.404 +                PUSH_W(seg);                                                    \
  87.405 +                cycles -= 2;                                                    \
  87.406 +                return 0;                                                       \
  87.407 +        }                                                                       \
  87.408 +        static int opPUSH_ ## seg ## _l(uint32_t fetchdat)                      \
  87.409 +        {                                                                       \
  87.410 +                if (ssegs) ss=oldss;                                            \
  87.411 +                PUSH_L(seg);                                                    \
  87.412 +                cycles -= 2;                                                    \
  87.413 +                return 0;                                                       \
  87.414 +        }
  87.415 +        
  87.416 +#define POP_SEG_OPS(seg, realseg)                                               \
  87.417 +        static int opPOP_ ## seg ## _w(uint32_t fetchdat)                       \
  87.418 +        {                                                                       \
  87.419 +                uint16_t temp_seg;                                              \
  87.420 +                uint32_t temp_esp = ESP;                                        \
  87.421 +                if (ssegs) ss=oldss;                                            \
  87.422 +                temp_seg = POP_W();                     if (abrt) return 0;     \
  87.423 +                loadseg(temp_seg, realseg);             if (abrt) ESP = temp_esp; \
  87.424 +                cycles -= is486 ? 3 : 7;                                        \
  87.425 +                return 0;                                                       \
  87.426 +        }                                                                       \
  87.427 +        static int opPOP_ ## seg ## _l(uint32_t fetchdat)                       \
  87.428 +        {                                                                       \
  87.429 +                uint32_t temp_seg;                                              \
  87.430 +                uint32_t temp_esp = ESP;                                        \
  87.431 +                if (ssegs) ss=oldss;                                            \
  87.432 +                temp_seg = POP_L();                     if (abrt) return 0;     \
  87.433 +                loadseg(temp_seg & 0xffff, realseg);    if (abrt) ESP = temp_esp; \
  87.434 +                cycles -= is486 ? 3 : 7;                                        \
  87.435 +                return 0;                                                       \
  87.436 +        }
  87.437 +
  87.438 +                
  87.439 +PUSH_SEG_OPS(CS);
  87.440 +PUSH_SEG_OPS(DS);
  87.441 +PUSH_SEG_OPS(ES);
  87.442 +PUSH_SEG_OPS(FS);
  87.443 +PUSH_SEG_OPS(GS);
  87.444 +PUSH_SEG_OPS(SS);
  87.445 +
  87.446 +POP_SEG_OPS(DS, &_ds);
  87.447 +POP_SEG_OPS(ES, &_es);
  87.448 +POP_SEG_OPS(FS, &_fs);
  87.449 +POP_SEG_OPS(GS, &_gs);
  87.450 +POP_SEG_OPS(SS, &_ss);
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/src/x86_ops_string.h	Mon May 27 19:56:33 2013 +0100
    88.3 @@ -0,0 +1,435 @@
    88.4 +static int opMOVSB_a16(uint32_t fetchdat)
    88.5 +{
    88.6 +        uint8_t temp = readmemb(ds,SI);         if (abrt) return 0;
    88.7 +        writememb(es, DI, temp);                if (abrt) return 0;
    88.8 +        if (flags & D_FLAG) { DI--; SI--; }
    88.9 +        else                { DI++; SI++; }
   88.10 +        cycles -= 7;
   88.11 +        return 0;
   88.12 +}
   88.13 +static int opMOVSB_a32(uint32_t fetchdat)
   88.14 +{
   88.15 +        uint8_t temp = readmemb(ds,ESI);        if (abrt) return 0;
   88.16 +        writememb(es, EDI, temp);               if (abrt) return 0;
   88.17 +        if (flags & D_FLAG) { EDI--; ESI--; }
   88.18 +        else                { EDI++; ESI++; }
   88.19 +        cycles -= 7;
   88.20 +        return 0;
   88.21 +}
   88.22 +
   88.23 +static int opMOVSW_a16(uint32_t fetchdat)
   88.24 +{
   88.25 +        uint16_t temp = readmemw(ds,SI);        if (abrt) return 0;
   88.26 +        writememw(es, DI, temp);                if (abrt) return 0;
   88.27 +        if (flags & D_FLAG) { DI -= 2; SI -= 2; }
   88.28 +        else                { DI += 2; SI += 2; }
   88.29 +        cycles -= 7;
   88.30 +        return 0;
   88.31 +}
   88.32 +static int opMOVSW_a32(uint32_t fetchdat)
   88.33 +{
   88.34 +        uint16_t temp = readmemw(ds,ESI);       if (abrt) return 0;
   88.35 +        writememw(es, EDI, temp);               if (abrt) return 0;
   88.36 +        if (flags & D_FLAG) { EDI -= 2; ESI -= 2; }
   88.37 +        else                { EDI += 2; ESI += 2; }
   88.38 +        cycles -= 7;
   88.39 +        return 0;
   88.40 +}
   88.41 +
   88.42 +static int opMOVSL_a16(uint32_t fetchdat)
   88.43 +{
   88.44 +        uint32_t temp = readmeml(ds,SI);        if (abrt) return 0;
   88.45 +        writememl(es, DI, temp);                if (abrt) return 0;
   88.46 +        if (flags & D_FLAG) { DI -= 4; SI -= 4; }
   88.47 +        else                { DI += 4; SI += 4; }
   88.48 +        cycles -= 7;
   88.49 +        return 0;
   88.50 +}
   88.51 +static int opMOVSL_a32(uint32_t fetchdat)
   88.52 +{
   88.53 +        uint32_t temp = readmeml(ds,ESI);       if (abrt) return 0;
   88.54 +        writememl(es, EDI, temp);               if (abrt) return 0;
   88.55 +        if (flags & D_FLAG) { EDI -= 4; ESI -= 4; }
   88.56 +        else                { EDI += 4; ESI += 4; }
   88.57 +        cycles -= 7;
   88.58 +        return 0;
   88.59 +}
   88.60 +
   88.61 +
   88.62 +static int opCMPSB_a16(uint32_t fetchdat)
   88.63 +{
   88.64 +        uint8_t src = readmemb(ds, SI);
   88.65 +        uint8_t dst = readmemb(es, DI);         if (abrt) return 0;
   88.66 +        setsub8(src, dst);
   88.67 +        if (flags & D_FLAG) { DI--; SI--; }
   88.68 +        else                { DI++; SI++; }
   88.69 +        cycles -= (is486) ? 8 : 10;
   88.70 +        return 0;
   88.71 +}
   88.72 +static int opCMPSB_a32(uint32_t fetchdat)
   88.73 +{
   88.74 +        uint8_t src = readmemb(ds, ESI);
   88.75 +        uint8_t dst = readmemb(es, EDI);        if (abrt) return 0;
   88.76 +        setsub8(src, dst);
   88.77 +        if (flags & D_FLAG) { EDI--; ESI--; }
   88.78 +        else                { EDI++; ESI++; }
   88.79 +        cycles -= (is486) ? 8 : 10;
   88.80 +        return 0;
   88.81 +}
   88.82 +
   88.83 +static int opCMPSW_a16(uint32_t fetchdat)
   88.84 +{
   88.85 +        uint16_t src = readmemw(ds, SI);
   88.86 +        uint16_t dst = readmemw(es, DI);        if (abrt) return 0;
   88.87 +        setsub16(src, dst);
   88.88 +        if (flags & D_FLAG) { DI -= 2; SI -= 2; }
   88.89 +        else                { DI += 2; SI += 2; }
   88.90 +        cycles -= (is486) ? 8 : 10;
   88.91 +        return 0;
   88.92 +}
   88.93 +static int opCMPSW_a32(uint32_t fetchdat)
   88.94 +{
   88.95 +        uint16_t src = readmemw(ds, ESI);
   88.96 +        uint16_t dst = readmemw(es, EDI);        if (abrt) return 0;
   88.97 +        setsub16(src, dst);
   88.98 +        if (flags & D_FLAG) { EDI -= 2; ESI -= 2; }
   88.99 +        else                { EDI += 2; ESI += 2; }
  88.100 +        cycles -= (is486) ? 8 : 10;
  88.101 +        return 0;
  88.102 +}
  88.103 +
  88.104 +static int opCMPSL_a16(uint32_t fetchdat)
  88.105 +{
  88.106 +        uint32_t src = readmeml(ds, SI);
  88.107 +        uint32_t dst = readmeml(es, DI);        if (abrt) return 0;
  88.108 +        setsub32(src, dst);
  88.109 +        if (flags & D_FLAG) { DI -= 4; SI -= 4; }
  88.110 +        else                { DI += 4; SI += 4; }
  88.111 +        cycles -= (is486) ? 8 : 10;
  88.112 +        return 0;
  88.113 +}
  88.114 +static int opCMPSL_a32(uint32_t fetchdat)
  88.115 +{
  88.116 +        uint32_t src = readmeml(ds, ESI);
  88.117 +        uint32_t dst = readmeml(es, EDI);        if (abrt) return 0;
  88.118 +        setsub32(src, dst);
  88.119 +        if (flags & D_FLAG) { EDI -= 4; ESI -= 4; }
  88.120 +        else                { EDI += 4; ESI += 4; }
  88.121 +        cycles -= (is486) ? 8 : 10;
  88.122 +        return 0;
  88.123 +}
  88.124 +
  88.125 +static int opSTOSB_a16(uint32_t fetchdat)
  88.126 +{
  88.127 +        writememb(es, DI, AL);                  if (abrt) return 0;
  88.128 +        if (flags & D_FLAG) DI--;
  88.129 +        else                DI++;
  88.130 +        cycles -= 4;
  88.131 +        return 0;
  88.132 +}
  88.133 +static int opSTOSB_a32(uint32_t fetchdat)
  88.134 +{
  88.135 +        writememb(es, EDI, AL);                 if (abrt) return 0;
  88.136 +        if (flags & D_FLAG) EDI--;
  88.137 +        else                EDI++;
  88.138 +        cycles -= 4;
  88.139 +        return 0;
  88.140 +}
  88.141 +
  88.142 +static int opSTOSW_a16(uint32_t fetchdat)
  88.143 +{
  88.144 +        writememw(es, DI, AX);                  if (abrt) return 0;
  88.145 +        if (flags & D_FLAG) DI -= 2;
  88.146 +        else                DI += 2;
  88.147 +        cycles -= 4;
  88.148 +        return 0;
  88.149 +}
  88.150 +static int opSTOSW_a32(uint32_t fetchdat)
  88.151 +{
  88.152 +        writememw(es, EDI, AX);                 if (abrt) return 0;
  88.153 +        if (flags & D_FLAG) EDI -= 2;
  88.154 +        else                EDI += 2;
  88.155 +        cycles -= 4;
  88.156 +        return 0;
  88.157 +}
  88.158 +
  88.159 +static int opSTOSL_a16(uint32_t fetchdat)
  88.160 +{
  88.161 +        writememl(es, DI, EAX);                 if (abrt) return 0;
  88.162 +        if (flags & D_FLAG) DI -= 4;
  88.163 +        else                DI += 4;
  88.164 +        cycles -= 4;
  88.165 +        return 0;
  88.166 +}
  88.167 +static int opSTOSL_a32(uint32_t fetchdat)
  88.168 +{
  88.169 +        writememl(es, EDI, EAX);                if (abrt) return 0;
  88.170 +        if (flags & D_FLAG) EDI -= 4;
  88.171 +        else                EDI += 4;
  88.172 +        cycles -= 4;
  88.173 +        return 0;
  88.174 +}
  88.175 +
  88.176 +
  88.177 +static int opLODSB_a16(uint32_t fetchdat)
  88.178 +{
  88.179 +        uint8_t temp = readmemb(ds, SI);        if (abrt) return 0;
  88.180 +        AL = temp;
  88.181 +        if (flags & D_FLAG) SI--;
  88.182 +        else                SI++;
  88.183 +        cycles -= 5;
  88.184 +        return 0;
  88.185 +}
  88.186 +static int opLODSB_a32(uint32_t fetchdat)
  88.187 +{
  88.188 +        uint8_t temp = readmemb(ds, ESI);       if (abrt) return 0;
  88.189 +        AL = temp;
  88.190 +        if (flags & D_FLAG) ESI--;
  88.191 +        else                ESI++;
  88.192 +        cycles -= 5;
  88.193 +        return 0;
  88.194 +}
  88.195 +
  88.196 +static int opLODSW_a16(uint32_t fetchdat)
  88.197 +{
  88.198 +        uint16_t temp = readmemw(ds, SI);       if (abrt) return 0;
  88.199 +        AX = temp;
  88.200 +        if (flags & D_FLAG) SI -= 2;
  88.201 +        else                SI += 2;
  88.202 +        cycles -= 5;
  88.203 +        return 0;
  88.204 +}
  88.205 +static int opLODSW_a32(uint32_t fetchdat)
  88.206 +{
  88.207 +        uint16_t temp = readmemw(ds, ESI);      if (abrt) return 0;
  88.208 +        AX = temp;
  88.209 +        if (flags & D_FLAG) ESI -= 2;
  88.210 +        else                ESI += 2;
  88.211 +        cycles -= 5;
  88.212 +        return 0;
  88.213 +}
  88.214 +
  88.215 +static int opLODSL_a16(uint32_t fetchdat)
  88.216 +{
  88.217 +        uint32_t temp = readmeml(ds, SI);       if (abrt) return 0;
  88.218 +        EAX = temp;
  88.219 +        if (flags & D_FLAG) SI -= 4;
  88.220 +        else                SI += 4;
  88.221 +        cycles -= 5;
  88.222 +        return 0;
  88.223 +}
  88.224 +static int opLODSL_a32(uint32_t fetchdat)
  88.225 +{
  88.226 +        uint32_t temp = readmeml(ds, ESI);      if (abrt) return 0;
  88.227 +        EAX = temp;
  88.228 +        if (flags & D_FLAG) ESI -= 4;
  88.229 +        else                ESI += 4;
  88.230 +        cycles -= 5;
  88.231 +        return 0;
  88.232 +}
  88.233 +
  88.234 +
  88.235 +static int opSCASB_a16(uint32_t fetchdat)
  88.236 +{
  88.237 +        uint8_t temp = readmemb(es, DI);        if (abrt) return 0;
  88.238 +        setsub8(AL, temp);
  88.239 +        if (flags & D_FLAG) DI--;
  88.240 +        else                DI++;
  88.241 +        cycles -= 7;
  88.242 +        return 0;
  88.243 +}
  88.244 +static int opSCASB_a32(uint32_t fetchdat)
  88.245 +{
  88.246 +        uint8_t temp = readmemb(es, EDI);       if (abrt) return 0;
  88.247 +        setsub8(AL, temp);
  88.248 +        if (flags & D_FLAG) EDI--;
  88.249 +        else                EDI++;
  88.250 +        cycles -= 7;
  88.251 +        return 0;
  88.252 +}
  88.253 +
  88.254 +static int opSCASW_a16(uint32_t fetchdat)
  88.255 +{
  88.256 +        uint16_t temp = readmemw(es, DI);       if (abrt) return 0;
  88.257 +        setsub16(AX, temp);
  88.258 +        if (flags & D_FLAG) DI -= 2;
  88.259 +        else                DI += 2;
  88.260 +        cycles -= 7;
  88.261 +        return 0;
  88.262 +}
  88.263 +static int opSCASW_a32(uint32_t fetchdat)
  88.264 +{
  88.265 +        uint16_t temp = readmemw(es, EDI);      if (abrt) return 0;
  88.266 +        setsub16(AX, temp);
  88.267 +        if (flags & D_FLAG) EDI -= 2;
  88.268 +        else                EDI += 2;
  88.269 +        cycles -= 7;
  88.270 +        return 0;
  88.271 +}
  88.272 +
  88.273 +static int opSCASL_a16(uint32_t fetchdat)
  88.274 +{
  88.275 +        uint32_t temp = readmeml(es, DI);       if (abrt) return 0;
  88.276 +        setsub32(EAX, temp);
  88.277 +        if (flags & D_FLAG) DI -= 4;
  88.278 +        else                DI += 4;
  88.279 +        cycles -= 7;
  88.280 +        return 0;
  88.281 +}
  88.282 +static int opSCASL_a32(uint32_t fetchdat)
  88.283 +{
  88.284 +        uint32_t temp = readmeml(es, EDI);      if (abrt) return 0;
  88.285 +        setsub32(EAX, temp);
  88.286 +        if (flags & D_FLAG) EDI -= 4;
  88.287 +        else                EDI += 4;
  88.288 +        cycles -= 7;
  88.289 +        return 0;
  88.290 +}
  88.291 +
  88.292 +static int opINSB_a16(uint32_t fetchdat)
  88.293 +{
  88.294 +        uint8_t temp;
  88.295 +        check_io_perm(DX);
  88.296 +        temp = inb(DX);
  88.297 +        writememb(es, DI, temp);                if (abrt) return 0;
  88.298 +        if (flags & D_FLAG) DI--;
  88.299 +        else                DI++;
  88.300 +        cycles -= 15;
  88.301 +        return 0;
  88.302 +}
  88.303 +static int opINSB_a32(uint32_t fetchdat)
  88.304 +{
  88.305 +        uint8_t temp;
  88.306 +        check_io_perm(DX);
  88.307 +        temp = inb(DX);
  88.308 +        writememb(es, EDI, temp);               if (abrt) return 0;
  88.309 +        if (flags & D_FLAG) EDI--;
  88.310 +        else                EDI++;
  88.311 +        cycles -= 15;
  88.312 +        return 0;
  88.313 +}
  88.314 +
  88.315 +static int opINSW_a16(uint32_t fetchdat)
  88.316 +{
  88.317 +        uint16_t temp;
  88.318 +        check_io_perm(DX);
  88.319 +        check_io_perm(DX + 1);
  88.320 +        temp = inw(DX);
  88.321 +        writememw(es, DI, temp);                if (abrt) return 0;
  88.322 +        if (flags & D_FLAG) DI -= 2;
  88.323 +        else                DI += 2;
  88.324 +        cycles -= 15;
  88.325 +        return 0;
  88.326 +}
  88.327 +static int opINSW_a32(uint32_t fetchdat)
  88.328 +{
  88.329 +        uint16_t temp;
  88.330 +        check_io_perm(DX);
  88.331 +        check_io_perm(DX + 1);
  88.332 +        temp = inw(DX);
  88.333 +        writememw(es, EDI, temp);               if (abrt) return 0;
  88.334 +        if (flags & D_FLAG) EDI -= 2;
  88.335 +        else                EDI += 2;
  88.336 +        cycles -= 15;
  88.337 +        return 0;
  88.338 +}
  88.339 +
  88.340 +static int opINSL_a16(uint32_t fetchdat)
  88.341 +{
  88.342 +        uint32_t temp;
  88.343 +        check_io_perm(DX);
  88.344 +        check_io_perm(DX + 1);
  88.345 +        check_io_perm(DX + 2);
  88.346 +        check_io_perm(DX + 3);
  88.347 +        temp = inl(DX);
  88.348 +        writememl(es, DI, temp);                if (abrt) return 0;
  88.349 +        if (flags & D_FLAG) DI -= 4;
  88.350 +        else                DI += 4;
  88.351 +        cycles -= 15;
  88.352 +        return 0;
  88.353 +}
  88.354 +static int opINSL_a32(uint32_t fetchdat)
  88.355 +{
  88.356 +        uint32_t temp;
  88.357 +        check_io_perm(DX);
  88.358 +        check_io_perm(DX + 1);
  88.359 +        check_io_perm(DX + 2);
  88.360 +        check_io_perm(DX + 3);
  88.361 +        temp = inl(DX);
  88.362 +        writememl(es, EDI, temp);               if (abrt) return 0;
  88.363 +        if (flags & D_FLAG) EDI -= 4;
  88.364 +        else                EDI += 4;
  88.365 +        cycles -= 15;
  88.366 +        return 0;
  88.367 +}
  88.368 +
  88.369 +static int opOUTSB_a16(uint32_t fetchdat)
  88.370 +{
  88.371 +        uint8_t temp = readmemb(ds, SI);        if (abrt) return 0;
  88.372 +        check_io_perm(DX);
  88.373 +        if (flags & D_FLAG) SI--;
  88.374 +        else                SI++;
  88.375 +        outb(DX, temp);
  88.376 +        cycles -= 14;
  88.377 +        return 0;
  88.378 +}
  88.379 +static int opOUTSB_a32(uint32_t fetchdat)
  88.380 +{
  88.381 +        uint8_t temp = readmemb(ds, ESI);        if (abrt) return 0;
  88.382 +        check_io_perm(DX);
  88.383 +        if (flags & D_FLAG) ESI--;
  88.384 +        else                ESI++;
  88.385 +        outb(DX, temp);
  88.386 +        cycles -= 14;
  88.387 +        return 0;
  88.388 +}
  88.389 +
  88.390 +static int opOUTSW_a16(uint32_t fetchdat)
  88.391 +{
  88.392 +        uint16_t temp = readmemw(ds, SI);       if (abrt) return 0;
  88.393 +        check_io_perm(DX);
  88.394 +        check_io_perm(DX + 1);
  88.395 +        if (flags & D_FLAG) SI -= 2;
  88.396 +        else                SI += 2;
  88.397 +        outw(DX, temp);
  88.398 +        cycles -= 14;
  88.399 +        return 0;
  88.400 +}
  88.401 +static int opOUTSW_a32(uint32_t fetchdat)
  88.402 +{
  88.403 +        uint16_t temp = readmemw(ds, ESI);      if (abrt) return 0;
  88.404 +        check_io_perm(DX);
  88.405 +        check_io_perm(DX + 1);
  88.406 +        if (flags & D_FLAG) ESI -= 2;
  88.407 +        else                ESI += 2;
  88.408 +        outw(DX, temp);
  88.409 +        cycles -= 14;
  88.410 +        return 0;
  88.411 +}
  88.412 +
  88.413 +static int opOUTSL_a16(uint32_t fetchdat)
  88.414 +{
  88.415 +        uint32_t temp = readmeml(ds, SI);       if (abrt) return 0;
  88.416 +        check_io_perm(DX);
  88.417 +        check_io_perm(DX + 1);
  88.418 +        check_io_perm(DX + 2);
  88.419 +        check_io_perm(DX + 3);
  88.420 +        if (flags & D_FLAG) SI -= 4;
  88.421 +        else                SI += 4;
  88.422 +        outl(EDX, temp);
  88.423 +        cycles -= 14;
  88.424 +        return 0;
  88.425 +}
  88.426 +static int opOUTSL_a32(uint32_t fetchdat)
  88.427 +{
  88.428 +        uint32_t temp = readmeml(ds, ESI);      if (abrt) return 0;
  88.429 +        check_io_perm(DX);
  88.430 +        check_io_perm(DX + 1);
  88.431 +        check_io_perm(DX + 2);
  88.432 +        check_io_perm(DX + 3);
  88.433 +        if (flags & D_FLAG) ESI -= 4;
  88.434 +        else                ESI += 4;
  88.435 +        outl(EDX, temp);
  88.436 +        cycles -= 14;
  88.437 +        return 0;
  88.438 +}
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/src/x86_ops_xchg.h	Mon May 27 19:56:33 2013 +0100
    89.3 @@ -0,0 +1,195 @@
    89.4 +static int opXCHG_b_a16(uint32_t fetchdat)
    89.5 +{
    89.6 +        uint8_t temp;
    89.7 +        fetch_ea_16(fetchdat);
    89.8 +        temp = geteab();                        if (abrt) return 0;
    89.9 +        seteab(getr8(reg));                     if (abrt) return 0;
   89.10 +        setr8(reg, temp);
   89.11 +        cycles -= ((mod == 3) ? 3 : 5);
   89.12 +        return 0;
   89.13 +}
   89.14 +static int opXCHG_b_a32(uint32_t fetchdat)
   89.15 +{
   89.16 +        uint8_t temp;
   89.17 +        fetch_ea_32(fetchdat);
   89.18 +        temp = geteab();                        if (abrt) return 0;
   89.19 +        seteab(getr8(reg));                     if (abrt) return 0;
   89.20 +        setr8(reg, temp);
   89.21 +        cycles -= ((mod == 3) ? 3 : 5);
   89.22 +        return 0;
   89.23 +}
   89.24 +
   89.25 +static int opXCHG_w_a16(uint32_t fetchdat)
   89.26 +{
   89.27 +        uint16_t temp;
   89.28 +        fetch_ea_16(fetchdat);
   89.29 +        temp = geteaw();                        if (abrt) return 0;
   89.30 +        seteaw(regs[reg].w);                    if (abrt) return 0;
   89.31 +        regs[reg].w = temp;
   89.32 +        cycles -= ((mod == 3) ? 3 : 5);
   89.33 +        return 0;
   89.34 +}
   89.35 +static int opXCHG_w_a32(uint32_t fetchdat)
   89.36 +{
   89.37 +        uint16_t temp;
   89.38 +        fetch_ea_32(fetchdat);
   89.39 +        temp = geteaw();                        if (abrt) return 0;
   89.40 +        seteaw(regs[reg].w);                    if (abrt) return 0;
   89.41 +        regs[reg].w = temp;
   89.42 +        cycles -= ((mod == 3) ? 3 : 5);
   89.43 +        return 0;
   89.44 +}
   89.45 +
   89.46 +static int opXCHG_l_a16(uint32_t fetchdat)
   89.47 +{
   89.48 +        uint32_t temp;
   89.49 +        fetch_ea_16(fetchdat);
   89.50 +        temp = geteal();                        if (abrt) return 0;
   89.51 +        seteal(regs[reg].l);                    if (abrt) return 0;
   89.52 +        regs[reg].l = temp;
   89.53 +        cycles -= ((mod == 3) ? 3 : 5);
   89.54 +        return 0;
   89.55 +}
   89.56 +static int opXCHG_l_a32(uint32_t fetchdat)
   89.57 +{
   89.58 +        uint32_t temp;
   89.59 +        fetch_ea_32(fetchdat);
   89.60 +        temp = geteal();                        if (abrt) return 0;
   89.61 +        seteal(regs[reg].l);                    if (abrt) return 0;
   89.62 +        regs[reg].l = temp;
   89.63 +        cycles -= ((mod == 3) ? 3 : 5);
   89.64 +        return 0;
   89.65 +}
   89.66 +
   89.67 +
   89.68 +static int opXCHG_AX_BX(uint32_t fetchdat)
   89.69 +{
   89.70 +        uint16_t temp = AX;
   89.71 +        AX = BX;
   89.72 +        BX = temp;
   89.73 +        cycles -= 3;
   89.74 +        return 0;
   89.75 +}
   89.76 +static int opXCHG_AX_CX(uint32_t fetchdat)
   89.77 +{
   89.78 +        uint16_t temp = AX;
   89.79 +        AX = CX;
   89.80 +        CX = temp;
   89.81 +        cycles -= 3;
   89.82 +        return 0;
   89.83 +}
   89.84 +static int opXCHG_AX_DX(uint32_t fetchdat)
   89.85 +{
   89.86 +        uint16_t temp = AX;
   89.87 +        AX = DX;
   89.88 +        DX = temp;
   89.89 +        cycles -= 3;
   89.90 +        return 0;
   89.91 +}
   89.92 +static int opXCHG_AX_SI(uint32_t fetchdat)
   89.93 +{
   89.94 +        uint16_t temp = AX;
   89.95 +        AX = SI;
   89.96 +        SI = temp;
   89.97 +        cycles -= 3;
   89.98 +        return 0;
   89.99 +}
  89.100 +static int opXCHG_AX_DI(uint32_t fetchdat)
  89.101 +{
  89.102 +        uint16_t temp = AX;
  89.103 +        AX = DI;
  89.104 +        DI = temp;
  89.105 +        cycles -= 3;
  89.106 +        return 0;
  89.107 +}
  89.108 +static int opXCHG_AX_BP(uint32_t fetchdat)
  89.109 +{
  89.110 +        uint16_t temp = AX;
  89.111 +        AX = BP;
  89.112 +        BP = temp;
  89.113 +        cycles -= 3;
  89.114 +        return 0;
  89.115 +}
  89.116 +static int opXCHG_AX_SP(uint32_t fetchdat)
  89.117 +{
  89.118 +        uint16_t temp = AX;
  89.119 +        AX = SP;
  89.120 +        SP = temp;
  89.121 +        cycles -= 3;
  89.122 +        return 0;
  89.123 +}
  89.124 +
  89.125 +static int opXCHG_EAX_EBX(uint32_t fetchdat)
  89.126 +{
  89.127 +        uint32_t temp = EAX;
  89.128 +        EAX = EBX;
  89.129 +        EBX = temp;
  89.130 +        cycles -= 3;
  89.131 +        return 0;
  89.132 +}
  89.133 +static int opXCHG_EAX_ECX(uint32_t fetchdat)
  89.134 +{
  89.135 +        uint32_t temp = EAX;
  89.136 +        EAX = ECX;
  89.137 +        ECX = temp;
  89.138 +        cycles -= 3;
  89.139 +        return 0;
  89.140 +}
  89.141 +static int opXCHG_EAX_EDX(uint32_t fetchdat)
  89.142 +{
  89.143 +        uint32_t temp = EAX;
  89.144 +        EAX = EDX;
  89.145 +        EDX = temp;
  89.146 +        cycles -= 3;
  89.147 +        return 0;
  89.148 +}
  89.149 +static int opXCHG_EAX_ESI(uint32_t fetchdat)
  89.150 +{
  89.151 +        uint32_t temp = EAX;
  89.152 +        EAX = ESI;
  89.153 +        ESI = temp;
  89.154 +        cycles -= 3;
  89.155 +        return 0;
  89.156 +}
  89.157 +static int opXCHG_EAX_EDI(uint32_t fetchdat)
  89.158 +{
  89.159 +        uint32_t temp = EAX;
  89.160 +        EAX = EDI;
  89.161 +        EDI = temp;
  89.162 +        cycles -= 3;
  89.163 +        return 0;
  89.164 +}
  89.165 +static int opXCHG_EAX_EBP(uint32_t fetchdat)
  89.166 +{
  89.167 +        uint32_t temp = EAX;
  89.168 +        EAX = EBP;
  89.169 +        EBP = temp;
  89.170 +        cycles -= 3;
  89.171 +        return 0;
  89.172 +}
  89.173 +static int opXCHG_EAX_ESP(uint32_t fetchdat)
  89.174 +{
  89.175 +        uint32_t temp = EAX;
  89.176 +        EAX = ESP;
  89.177 +        ESP = temp;
  89.178 +        cycles -= 3;
  89.179 +        return 0;
  89.180 +}
  89.181 +
  89.182 +
  89.183 +#define opBSWAP(reg)                                                            \
  89.184 +        static int opBSWAP_ ## reg(uint32_t fetchdat)                           \
  89.185 +        {                                                                       \
  89.186 +                reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000);       \
  89.187 +                cycles--;                                                       \
  89.188 +                return 0;                                                       \
  89.189 +        }
  89.190 +
  89.191 +opBSWAP(EAX)
  89.192 +opBSWAP(EBX)
  89.193 +opBSWAP(ECX)
  89.194 +opBSWAP(EDX)
  89.195 +opBSWAP(ESI)
  89.196 +opBSWAP(EDI)
  89.197 +opBSWAP(EBP)
  89.198 +opBSWAP(ESP)