PCem

changeset 4:342c3f6cee85

Re-organisation of video emulation.
author TomW
date Mon Jun 24 20:42:35 2013 +0100
parents ee7a3f8ad75d
children fe9cf232a465
files src/808x.c src/device.c src/device.h src/dma.c src/ega.c src/ibm.h src/keyboard_amstrad.c src/keyboard_olim24.c src/pc.c src/pc.rc src/pit.c src/resources.h src/sound_adlib.c src/sound_adlibgold.c src/sound_cms.c src/sound_gus.c src/sound_pas16.c src/sound_sb.c src/sound_sb_dsp.c src/sound_sn76489.c src/sound_wss.c src/vid_ati18800.c src/vid_ati18800.h src/vid_ati28800.c src/vid_ati28800.h 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_ati_mach64.h src/vid_cga.c src/vid_cga.h src/vid_cl5429.c src/vid_cl5429.h src/vid_ega.c src/vid_ega.h src/vid_et4000.c src/vid_et4000.h src/vid_et4000w32.c src/vid_et4000w32.h src/vid_hercules.c src/vid_hercules.h src/vid_icd2061.c src/vid_icd2061.h src/vid_ics2595.c src/vid_ics2595.h src/vid_mda.c src/vid_mda.h src/vid_olivetti_m24.c src/vid_olivetti_m24.h src/vid_oti067.c src/vid_oti067.h src/vid_paradise.c src/vid_paradise.h src/vid_pc1512.c src/vid_pc1512.h src/vid_pc1640.c src/vid_pc1640.h src/vid_pc200.c src/vid_pc200.h src/vid_s3.c src/vid_s3.h src/vid_s3_virge.c src/vid_s3_virge.h src/vid_sdac_ramdac.c src/vid_sdac_ramdac.h src/vid_stg_ramdac.c src/vid_stg_ramdac.h src/vid_svga.c src/vid_svga.h src/vid_svga_render.c src/vid_svga_render.h src/vid_tandy.c src/vid_tandy.h src/vid_tkd8001_ramdac.c src/vid_tkd8001_ramdac.h src/vid_tvga.c src/vid_tvga.h src/vid_unk_ramdac.c src/vid_unk_ramdac.h src/vid_vga.c src/vid_vga.h src/video.c src/video.h src/win.c
diffstat 86 files changed, 8092 insertions(+), 7234 deletions(-) [+]
line diff
     1.1 --- a/src/808x.c	Tue Jun 04 20:52:17 2013 +0100
     1.2 +++ b/src/808x.c	Mon Jun 24 20:42:35 2013 +0100
     1.3 @@ -19,6 +19,8 @@
     1.4  #include "timer.h"
     1.5  #include "x86.h"
     1.6  
     1.7 +int nmi = 0;
     1.8 +
     1.9  int nextcyc=0;
    1.10  int cycdiff;
    1.11  int is8086=0;
     2.1 --- a/src/device.c	Tue Jun 04 20:52:17 2013 +0100
     2.2 +++ b/src/device.c	Mon Jun 24 20:42:35 2013 +0100
     2.3 @@ -57,3 +57,23 @@
     2.4                  }
     2.5          }
     2.6  }
     2.7 +
     2.8 +char *device_add_status_info(char *s, int max_len)
     2.9 +{
    2.10 +        int c;
    2.11 +        
    2.12 +        s[0] = 0;
    2.13 +        
    2.14 +        for (c = 0; c < 256; c++)
    2.15 +        {
    2.16 +                if (devices[c] != NULL)
    2.17 +                {
    2.18 +                        if (devices[c]->add_status_info != NULL)
    2.19 +                        {
    2.20 +                                int len = devices[c]->add_status_info(s, max_len, device_priv[c]);
    2.21 +                                s += len;
    2.22 +                                max_len -= len;
    2.23 +                        }
    2.24 +                }
    2.25 +        }
    2.26 +}
     3.1 --- a/src/device.h	Tue Jun 04 20:52:17 2013 +0100
     3.2 +++ b/src/device.h	Mon Jun 24 20:42:35 2013 +0100
     3.3 @@ -2,11 +2,13 @@
     3.4  {
     3.5          char name[50];
     3.6          void *(*init)();
     3.7 -        void (*close)(void *priv);
     3.8 -        void (*speed_changed)(void *priv);
     3.9 +        void (*close)(void *p);
    3.10 +        void (*speed_changed)(void *p);
    3.11 +        int  (*add_status_info)(char *s, int max_len, void *p);
    3.12  } device_t;
    3.13  
    3.14  void device_init();
    3.15  void device_add(device_t *d);
    3.16  void device_close_all();
    3.17  void device_speed_changed();
    3.18 +char *device_add_status_info(char *s, int max_len);
     4.1 --- a/src/dma.c	Tue Jun 04 20:52:17 2013 +0100
     4.2 +++ b/src/dma.c	Mon Jun 24 20:42:35 2013 +0100
     4.3 @@ -213,7 +213,7 @@
     4.4  {
     4.5  /*        if (!(addr&0xF))
     4.6          {*/
     4.7 -                pclog("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc);
     4.8 +//                pclog("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc);
     4.9  //                if (val==0x29 && pc==0xD25) output=1;
    4.10  //        }
    4.11          dmapages[addr&0xF]=val;
    4.12 @@ -258,12 +258,12 @@
    4.13  {
    4.14          switch (addr&0xFFFF8000)
    4.15          {
    4.16 -                case 0xA0000: case 0xA8000:
    4.17 +/*                case 0xA0000: case 0xA8000:
    4.18                  return video_read_a000(addr, NULL);
    4.19                  case 0xB0000:
    4.20                  return video_read_b000(addr, NULL);
    4.21                  case 0xB8000:
    4.22 -                return video_read_b800(addr, NULL);
    4.23 +                return video_read_b800(addr, NULL);*/
    4.24          }
    4.25          if (isram[addr>>16]) return ram[addr];
    4.26          return 0xff;
    4.27 @@ -271,9 +271,10 @@
    4.28  
    4.29  void _dma_write(uint32_t addr, uint8_t val)
    4.30  {
    4.31 +        pclog("_dma_write %08X %02X\n", addr, val);
    4.32          switch (addr&0xFFFF8000)
    4.33          {
    4.34 -                case 0xA0000: case 0xA8000:
    4.35 +/*                case 0xA0000: case 0xA8000:
    4.36                  video_write_a000(addr,val, NULL);
    4.37                  return;
    4.38                  case 0xB0000:
    4.39 @@ -284,7 +285,7 @@
    4.40                  return;
    4.41                  case 0xC0000: case 0xC8000: case 0xD0000: case 0xD8000:
    4.42                  case 0xE0000: case 0xE8000: case 0xF0000: case 0xF8000:
    4.43 -                return;
    4.44 +                return;*/
    4.45          }
    4.46          if (isram[addr >> 16]) 
    4.47                  ram[addr] = val;
     5.1 --- a/src/ega.c	Tue Jun 04 20:52:17 2013 +0100
     5.2 +++ b/src/ega.c	Mon Jun 24 20:42:35 2013 +0100
     5.3 @@ -1,217 +1,10 @@
     5.4  #include "ibm.h"
     5.5  #include "video.h"
     5.6  
     5.7 -void doblit();
     5.8 -
     5.9 -int egareads=0,egawrites=0;
    5.10 -int framecount=0;
    5.11 -int changeframecount=2;
    5.12 -
    5.13 -void redotextlookup();
    5.14 -int output;
    5.15 -int svgaon=0;
    5.16 -uint32_t svgarbank,svgawbank;
    5.17 -uint8_t svgaseg,svgaseg2;
    5.18 -uint8_t svga3d8;
    5.19 -
    5.20 -uint8_t oldvram=0;
    5.21 -int frames;
    5.22 -int hsync;
    5.23 -uint8_t cgastat;
    5.24 -
    5.25 -uint8_t gdcreg[16];
    5.26 -int gdcaddr;
    5.27 -uint8_t attrregs[32];
    5.28 -int attraddr,attrff=0;
    5.29 -uint8_t ega3c2;
    5.30 -
    5.31 -uint8_t rotatevga[8][256];
    5.32 -uint8_t writemask,charset;
    5.33 -int writemode,readmode,readplane,chain4;
    5.34 -uint8_t colourcompare,colournocare;
    5.35 -uint8_t la,lb,lc,ld;
    5.36 -
    5.37 -uint8_t *vram;
    5.38 -
    5.39 -int egares;
    5.40 -
    5.41 -uint8_t seqregs[64];
    5.42 -int seqaddr;
    5.43 -
    5.44 -uint8_t oak_regs[32];
    5.45 -int oak_index;
    5.46 -
    5.47 -
    5.48 -extern int egaswitchread,egaswitches;
    5.49 -/*For VGA non-interlace colour, ID bits should be 1 1 0 or 6*/
    5.50 -int vres=0;
    5.51 -
    5.52 -PALETTE vgapal;
    5.53 -uint32_t *pallook,pallook16[256],pallook64[256],pallook256[256];
    5.54 -int dacread,dacwrite,dacpos=0;
    5.55 -int palchange=1;
    5.56 -
    5.57 -int fullchange;
    5.58 -
    5.59 -int dispontime,dispofftime;
    5.60 -double disptime;
    5.61 -
    5.62 -int ega_vtotal,ega_dispend,ega_vsyncstart,ega_split,ega_hdisp,ega_rowoffset;
    5.63 -int vidclock;
    5.64 -float cpuclock;
    5.65 -
    5.66 -int bpp;
    5.67 -
    5.68 -uint32_t vrammask;
    5.69 -
    5.70 -uint8_t changedvram[(8192*1024)/1024];
    5.71 -
    5.72 -
    5.73 -int charseta,charsetb;
    5.74 -
    5.75 -int egapal[16];
    5.76 -
    5.77 -int displine;
    5.78 -
    5.79 -int rowdbl=0;
    5.80 -int scrblank=0;
    5.81 -
    5.82 -
    5.83 -
    5.84 -
    5.85 -uint8_t edatlookup[4][4];
    5.86 -
    5.87 -uint32_t textlookup[256][2][16][16];
    5.88 -
    5.89 -/*void redotextlookup()
    5.90 -{
    5.91 -        int c,d,e;
    5.92 -        uint32_t temp;
    5.93 -        int coffset=(VGA)?0:64;
    5.94 -        for (c=0;c<256;c++)
    5.95 -        {
    5.96 -                for (d=0;d<16;d++)
    5.97 -                {
    5.98 -//                        printf("ATTR %i=%02X+%02X\n",d,attrregs[d],coffset);
    5.99 -                        for (e=0;e<16;e++)
   5.100 -                        {
   5.101 -                                temp=0;
   5.102 -                                if (c&0x80) temp|=(attrregs[d]+coffset);
   5.103 -                                else        temp|=(attrregs[e]+coffset);
   5.104 -                                if (c&0x40) temp|=(attrregs[d]+coffset)<<8;
   5.105 -                                else        temp|=(attrregs[e]+coffset)<<8;
   5.106 -                                if (c&0x20) temp|=(attrregs[d]+coffset)<<16;
   5.107 -                                else        temp|=(attrregs[e]+coffset)<<16;
   5.108 -                                if (c&0x10) temp|=(attrregs[d]+coffset)<<24;
   5.109 -                                else        temp|=(attrregs[e]+coffset)<<24;
   5.110 -//                                if (c==0x5) printf("%08X %i %i %02X %02X\n",temp,d,e,attrregs[d],attrregs[e]);
   5.111 -                                textlookup[c][0][d][e]=temp;
   5.112 -                                temp=0;
   5.113 -                                if (c&0x08) temp|=(attrregs[d]+coffset);
   5.114 -                                else        temp|=(attrregs[e]+coffset);
   5.115 -                                if (c&0x04) temp|=(attrregs[d]+coffset)<<8;
   5.116 -                                else        temp|=(attrregs[e]+coffset)<<8;
   5.117 -                                if (c&0x02) temp|=(attrregs[d]+coffset)<<16;
   5.118 -                                else        temp|=(attrregs[e]+coffset)<<16;
   5.119 -                                if (c&0x01) temp|=(attrregs[d]+coffset)<<24;
   5.120 -                                else        temp|=(attrregs[e]+coffset)<<24;
   5.121 -                                textlookup[c][1][d][e]=temp;
   5.122 -                        }
   5.123 -                }
   5.124 -        }
   5.125 -}*/
   5.126 -
   5.127 -void initega()
   5.128 -{
   5.129 -        int c,d,e;
   5.130 -        bpp=8;
   5.131 -        for (c=0;c<256;c++)
   5.132 -        {
   5.133 -                e=c;
   5.134 -                for (d=0;d<8;d++)
   5.135 -                {
   5.136 -                        rotatevga[d][c]=e;
   5.137 -                        e=(e>>1)|((e&1)?0x80:0);
   5.138 -                }
   5.139 -        }
   5.140 -        crtc[0xC]=crtc[0xD]=0;
   5.141 -        for (c=0;c<4;c++)
   5.142 -        {
   5.143 -                for (d=0;d<4;d++)
   5.144 -                {
   5.145 -                        edatlookup[c][d]=0;
   5.146 -                        if (c&1) edatlookup[c][d]|=1;
   5.147 -                        if (d&1) edatlookup[c][d]|=2;
   5.148 -                        if (c&2) edatlookup[c][d]|=0x10;
   5.149 -                        if (d&2) edatlookup[c][d]|=0x20;
   5.150 -//                        printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]);
   5.151 -                }
   5.152 -        }
   5.153 -        /*redotextlookup();*/
   5.154 -        for (c=0;c<256;c++)
   5.155 -        {
   5.156 -                pallook64[c]=makecol32(((c>>2)&1)*0xAA,((c>>1)&1)*0xAA,(c&1)*0xAA);
   5.157 -                pallook64[c]+=makecol32(((c>>5)&1)*0x55,((c>>4)&1)*0x55,((c>>3)&1)*0x55);
   5.158 -                pallook16[c]=makecol32(((c>>2)&1)*0xAA,((c>>1)&1)*0xAA,(c&1)*0xAA);
   5.159 -                pallook16[c]+=makecol32(((c>>4)&1)*0x55,((c>>4)&1)*0x55,((c>>4)&1)*0x55);
   5.160 -                if ((c&0x17)==6) pallook16[c]=makecol32(0xAA,0x55,0);
   5.161 -//                printf("%03i %08X\n",c,pallook[c]);
   5.162 -        }
   5.163 -        pallook=pallook16;
   5.164 -        seqregs[0xC]=0x20;
   5.165 -        vrammask=(ET4000)?0xFFFFF:0x1FFFFF;
   5.166 -//        writeega_func=writeega;
   5.167 -        gdcreg[6]=8;
   5.168 -        gdcreg[8]=0xFF;
   5.169 -        writemode=0;
   5.170 -        chain4=0;
   5.171 -        writemask=3;
   5.172 -        
   5.173 -        et4k_b8000=0;
   5.174 -        
   5.175 -        svgarbank=svgawbank=0;
   5.176 -}
   5.177 -uint32_t egabase,egaoffset;
   5.178 -
   5.179 -void cacheega()
   5.180 -{
   5.181 -        egabase=(crtc[0xC]<<8)|crtc[0xD];
   5.182 -        if (ET4000 || ET4000W32 || TRIDENT)
   5.183 -           egabase|=((crtc[0x33]&3)<<18);
   5.184 -//        printf("EGABASE %05X\n",egabase);
   5.185 -//        egaoffset=8-((attrregs[0x13])&7);
   5.186 -//        printf("Cache base!\n");
   5.187 -}
   5.188 -void cacheega2()
   5.189 -{
   5.190 -//        egabase=(crtc[0xC]<<8)|crtc[0xD];
   5.191 -        if (gdcreg[5]&0x40) egaoffset=8-(((attrregs[0x13])&7)>>1);
   5.192 -        else                egaoffset=8-((attrregs[0x13])&7);
   5.193 -//        printf("Cache offset!\n");
   5.194 -}
   5.195 -
   5.196 -int olddisplines,oldxsize;
   5.197 -
   5.198 -int oldreadflash;
   5.199 -int oldegaaddr,oldegasplit;
   5.200 -
   5.201 -int vc,sc;
   5.202 -int egadispon=0;
   5.203 -int linepos;
   5.204 -int displine;
   5.205 -uint32_t ma,maback,ca;
   5.206 -int firstline,lastline;
   5.207 -int xsize,ysize;
   5.208 -int scrollcache;
   5.209 -int con,cursoron,cgablink;
   5.210 -
   5.211 -BITMAP *buffer,*vbuf,*buffer32;
   5.212 -
   5.213 -int linecountff=0;
   5.214  
   5.215  void dumpegaregs()
   5.216  {
   5.217 -        int c;
   5.218 +/*        int c;
   5.219          printf("CRTC :");
   5.220          for (c=0;c<0x20;c++) printf(" %02X",crtc[c]);
   5.221          printf("\n");
   5.222 @@ -234,64 +27,6 @@
   5.223          for (c=0;c<0x10;c++) printf(" %02X",gdcreg[c]);
   5.224          printf("\n");
   5.225  //        printf("OLD CTRL2 = %02X  NEW CTRL2 = %02X  DAC = %02X  3C2 = %02X\n",tridentoldctrl2,tridentnewctrl2,tridentdac,ega3c2);
   5.226 -        printf("BPP = %02X\n",bpp);
   5.227 +        printf("BPP = %02X\n",bpp);*/
   5.228  }
   5.229  
   5.230 -int oddeven;
   5.231 -
   5.232 -int wx,wy;
   5.233 -int vslines;
   5.234 -
   5.235 -int frames = 0;
   5.236 -
   5.237 -void doblit()
   5.238 -{
   5.239 -        startblit();
   5.240 -        if ((wx!=xsize || wy!=ysize) && !vid_resize)
   5.241 -        {
   5.242 -                xsize=wx;
   5.243 -                ysize=wy+1;
   5.244 -                if (xsize<64) xsize=656;
   5.245 -                if (ysize<32) ysize=200;
   5.246 -                if (vres) updatewindowsize(xsize,ysize<<1);
   5.247 -                else      updatewindowsize(xsize,ysize);
   5.248 -        }
   5.249 -        video_blit_memtoscreen(32, 0, 0, ysize, xsize, ysize);
   5.250 -        if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
   5.251 -        endblit();
   5.252 -        frames++;
   5.253 -}
   5.254 -
   5.255 -int ega_getdepth()
   5.256 -{
   5.257 -        if (!(gdcreg[6]&1)) return 0;
   5.258 -        switch (gdcreg[5]&0x60)
   5.259 -        {
   5.260 -                case 0x00:
   5.261 -                return 4;
   5.262 -                case 0x20:
   5.263 -                return 2;
   5.264 -                case 0x40: case 0x60:
   5.265 -                if (TRIDENT || ET4000W32) return bpp;
   5.266 -                return 8;
   5.267 -        }
   5.268 -        return 0;
   5.269 -}
   5.270 -
   5.271 -int ega_getx()
   5.272 -{
   5.273 -        int x;
   5.274 -        if (!(gdcreg[6]&1)) return (crtc[1]+1);
   5.275 -        if ((attrregs[0x10]&0x40) && !(tridentoldctrl2&0x10)) x=(crtc[1]+1)*4;
   5.276 -        else                                                  x=(crtc[1]+1)*8;
   5.277 -        if (TRIDENT && (bpp==15 || bpp==16)) x>>=1;
   5.278 -        if (TRIDENT && bpp==24) x=(x<<1)/3;
   5.279 -        return x;
   5.280 -}
   5.281 -
   5.282 -int ega_gety()
   5.283 -{
   5.284 -        if (crtc[0x1E]&4) return (ega_dispend/((crtc[9]&31)+1))<<1;
   5.285 -        if (crtc[9]&0x80) return (ega_dispend/((crtc[9]&31)+1))>>1;
   5.286 -        return ega_dispend/((crtc[9]&31)+1);
   5.287 -}
     6.1 --- a/src/ibm.h	Tue Jun 04 20:52:17 2013 +0100
     6.2 +++ b/src/ibm.h	Mon Jun 24 20:42:35 2013 +0100
     6.3 @@ -458,3 +458,6 @@
     6.4  extern float isa_timing, bus_timing;
     6.5  
     6.6  extern int frame;
     6.7 +
     6.8 +
     6.9 +uint8_t *vramp;
     7.1 --- a/src/keyboard_amstrad.c	Tue Jun 04 20:52:17 2013 +0100
     7.2 +++ b/src/keyboard_amstrad.c	Mon Jun 24 20:42:35 2013 +0100
     7.3 @@ -3,6 +3,7 @@
     7.4  #include "mem.h"
     7.5  #include "pic.h"
     7.6  #include "sound.h"
     7.7 +#include "timer.h"
     7.8  
     7.9  #include "keyboard.h"
    7.10  #include "keyboard_amstrad.h"
    7.11 @@ -31,6 +32,7 @@
    7.12  
    7.13  void keyboard_amstrad_poll()
    7.14  {
    7.15 +        keybsenddelay += (1000 * TIMER_USEC);
    7.16          if (keyboard_amstrad.wantirq)
    7.17          {
    7.18                  keyboard_amstrad.wantirq = 0;
    7.19 @@ -166,4 +168,6 @@
    7.20          keyboard_amstrad_reset();
    7.21          keyboard_send = keyboard_amstrad_adddata;
    7.22          keyboard_poll = keyboard_amstrad_poll;
    7.23 +
    7.24 +        timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED,  NULL);
    7.25  }
     8.1 --- a/src/keyboard_olim24.c	Tue Jun 04 20:52:17 2013 +0100
     8.2 +++ b/src/keyboard_olim24.c	Mon Jun 24 20:42:35 2013 +0100
     8.3 @@ -3,6 +3,7 @@
     8.4  #include "mem.h"
     8.5  #include "mouse.h"
     8.6  #include "pic.h"
     8.7 +#include "timer.h"
     8.8  
     8.9  #include "keyboard.h"
    8.10  #include "keyboard_olim24.h"
    8.11 @@ -38,6 +39,7 @@
    8.12  
    8.13  void keyboard_olim24_poll()
    8.14  {
    8.15 +        keybsenddelay += (1000 * TIMER_USEC);
    8.16          //pclog("poll %i\n", keyboard_olim24.wantirq);
    8.17          if (keyboard_olim24.wantirq)
    8.18          {
    8.19 @@ -283,4 +285,6 @@
    8.20          keyboard_send = keyboard_olim24_adddata;
    8.21          keyboard_poll = keyboard_olim24_poll;
    8.22          mouse_poll    = mouse_olim24_poll;
    8.23 +        
    8.24 +        timer_add(keyboard_olim24_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED,  NULL);
    8.25  }
     9.1 --- a/src/pc.c	Tue Jun 04 20:52:17 2013 +0100
     9.2 +++ b/src/pc.c	Mon Jun 24 20:42:35 2013 +0100
     9.3 @@ -179,8 +179,6 @@
     9.4  //        sb_reset();
     9.5  
     9.6          ali1429_reset();
     9.7 -        et4000w32_reset();
     9.8 -        
     9.9  //        video_init();
    9.10  }
    9.11  
    9.12 @@ -209,8 +207,8 @@
    9.13          
    9.14          initvideo();
    9.15          mem_init();
    9.16 +        mem_load_video_bios();
    9.17          loadbios();
    9.18 -        mem_load_video_bios();
    9.19  
    9.20          loaddisc(0,discfns[0]);
    9.21          loaddisc(1,discfns[1]);
    9.22 @@ -221,10 +219,8 @@
    9.23          
    9.24          //loadfont();
    9.25          loadnvr();
    9.26 -        resetvideo();
    9.27          sound_init();
    9.28          inithdc();
    9.29 -        initega();
    9.30          resetide();
    9.31          ioctl_open(cdrom_drive);
    9.32          model_init();        
    9.33 @@ -244,7 +240,6 @@
    9.34  /*        if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed();
    9.35          mem_updatecache();
    9.36          ali1429_reset();
    9.37 -        et4000w32_reset();
    9.38  //        CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9));
    9.39  //        pclog("Init - CPUID %i %i\n",CPUID,cpuspeed);
    9.40          shadowbios=0;
    9.41 @@ -330,6 +325,7 @@
    9.42                  framecount++;
    9.43                  if (framecountx>=100)
    9.44                  {
    9.45 +                        pclog("onesec\n");
    9.46                          framecountx=0;
    9.47                          mips=(float)insc/1000000.0f;
    9.48                          insc=0;
    9.49 @@ -404,7 +400,6 @@
    9.50  {
    9.51          atapi->exit();
    9.52  //        ioctl_close();
    9.53 -        dumpegaregs();
    9.54          dumppic();
    9.55  //        output=7;
    9.56  //        setpitclock(clocks[0][0][0]);
    10.1 --- a/src/pc.rc	Tue Jun 04 20:52:17 2013 +0100
    10.2 +++ b/src/pc.rc	Mon Jun 24 20:42:35 2013 +0100
    10.3 @@ -50,8 +50,9 @@
    10.4      COMBOBOX        IDC_COMBOSPD,62,116,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
    10.5      COMBOBOX        IDC_COMBOSND,62,136,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
    10.6      COMBOBOX        IDC_COMBOMEM,62,152,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
    10.7 -    CONTROL         "Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,172,118,10
    10.8 -    CONTROL         "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,188,118,10
    10.9 +    CONTROL         "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,172,118,10
   10.10 +    CONTROL         "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,188,118,10    
   10.11 +    CONTROL         "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,204,118,10
   10.12      LTEXT           "Machine :",IDC_STATIC,15,16,40,10
   10.13      LTEXT           "Video :",IDC_STATIC,15,36,34,10
   10.14      LTEXT           "CPU type :",IDC_STATIC,15,56,34,10
   10.15 @@ -150,9 +151,5 @@
   10.16      LTEXT           "6",IDC_STEXT6,16,76,180,10
   10.17      LTEXT           "7",IDC_STEXT7,16,88,180,10
   10.18      LTEXT           "8",IDC_STEXT8,16,100,180,10
   10.19 -    LTEXT           "9",IDC_STEXT9,16,112,180,10
   10.20 -    LTEXT           "10",IDC_STEXT10,16,124,180,10
   10.21 -    LTEXT           "11",IDC_STEXT11,16,136,180,10
   10.22 -    LTEXT           "12",IDC_STEXT12,16,148,180,10
   10.23 -    LTEXT           "13",IDC_STEXT13,16,160,180,10
   10.24 +    LTEXT           "9",IDC_STEXT_DEVICE,16,112,180,1000
   10.25  END
    11.1 --- a/src/pit.c	Tue Jun 04 20:52:17 2013 +0100
    11.2 +++ b/src/pit.c	Mon Jun 24 20:42:35 2013 +0100
    11.3 @@ -31,14 +31,15 @@
    11.4          cpuclock=clock;
    11.5          PITCONST=clock/1193182.0;
    11.6          CGACONST=(clock/(19687500.0/11.0));
    11.7 -        MDACONST=(clock/1813000.0);
    11.8 +        MDACONST=(clock/2032125.0);
    11.9          VGACONST1=(clock/25175000.0);
   11.10          VGACONST2=(clock/28322000.0);
   11.11          isa_timing = clock/8000000.0;
   11.12          bus_timing = clock/(double)cpu_busspeed;
   11.13          video_updatetiming();
   11.14  //        pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock);
   11.15 -        video_recalctimings();
   11.16 +/*        if (video_recalctimings)
   11.17 +                video_recalctimings();*/
   11.18          RTCCONST=clock/32768.0;
   11.19          TIMER_USEC = (int)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT));
   11.20          device_speed_changed();
    12.1 --- a/src/resources.h	Tue Jun 04 20:52:17 2013 +0100
    12.2 +++ b/src/resources.h	Mon Jun 24 20:42:35 2013 +0100
    12.3 @@ -56,8 +56,4 @@
    12.4  #define IDC_STEXT6 1105
    12.5  #define IDC_STEXT7 1106
    12.6  #define IDC_STEXT8 1107
    12.7 -#define IDC_STEXT9 1108
    12.8 -#define IDC_STEXT10 1109
    12.9 -#define IDC_STEXT11 1110
   12.10 -#define IDC_STEXT12 1111
   12.11 -#define IDC_STEXT13 1112
   12.12 +#define IDC_STEXT_DEVICE 1108
    13.1 --- a/src/sound_adlib.c	Tue Jun 04 20:52:17 2013 +0100
    13.2 +++ b/src/sound_adlib.c	Mon Jun 24 20:42:35 2013 +0100
    13.3 @@ -58,5 +58,6 @@
    13.4          "AdLib",
    13.5          adlib_init,
    13.6          adlib_close,
    13.7 +        NULL,
    13.8          NULL
    13.9  };
    14.1 --- a/src/sound_adlibgold.c	Tue Jun 04 20:52:17 2013 +0100
    14.2 +++ b/src/sound_adlibgold.c	Mon Jun 24 20:42:35 2013 +0100
    14.3 @@ -593,5 +593,6 @@
    14.4          "AdLib Gold",
    14.5          adgold_init,
    14.6          adgold_close,
    14.7 +        NULL,
    14.8          NULL
    14.9  };
    15.1 --- a/src/sound_cms.c	Tue Jun 04 20:52:17 2013 +0100
    15.2 +++ b/src/sound_cms.c	Mon Jun 24 20:42:35 2013 +0100
    15.3 @@ -175,5 +175,6 @@
    15.4          "Creative Music System / Game Blaster",
    15.5          cms_init,
    15.6          cms_close,
    15.7 +        NULL,
    15.8          NULL
    15.9  };
    16.1 --- a/src/sound_gus.c	Tue Jun 04 20:52:17 2013 +0100
    16.2 +++ b/src/sound_gus.c	Mon Jun 24 20:42:35 2013 +0100
    16.3 @@ -1103,5 +1103,6 @@
    16.4          "Gravis UltraSound",
    16.5          gus_init,
    16.6          gus_close,
    16.7 -        gus_speed_changed
    16.8 +        gus_speed_changed,
    16.9 +        NULL
   16.10  };
    17.1 --- a/src/sound_pas16.c	Tue Jun 04 20:52:17 2013 +0100
    17.2 +++ b/src/sound_pas16.c	Mon Jun 24 20:42:35 2013 +0100
    17.3 @@ -749,5 +749,6 @@
    17.4          "Pro Audio Spectrum 16",
    17.5          pas16_init,
    17.6          pas16_close,
    17.7 +        NULL,
    17.8          NULL
    17.9  };
    18.1 --- a/src/sound_sb.c	Tue Jun 04 20:52:17 2013 +0100
    18.2 +++ b/src/sound_sb.c	Mon Jun 24 20:42:35 2013 +0100
    18.3 @@ -376,40 +376,46 @@
    18.4          "Sound Blaster v1.0",
    18.5          sb_1_init,
    18.6          sb_close,
    18.7 -        sb_speed_changed
    18.8 +        sb_speed_changed,
    18.9 +        NULL
   18.10  };
   18.11  device_t sb_15_device =
   18.12  {
   18.13          "Sound Blaster v1.5",
   18.14          sb_15_init,
   18.15          sb_close,
   18.16 -        sb_speed_changed
   18.17 +        sb_speed_changed,
   18.18 +        NULL
   18.19  };
   18.20  device_t sb_2_device =
   18.21  {
   18.22          "Sound Blaster v2.0",
   18.23          sb_2_init,
   18.24          sb_close,
   18.25 -        sb_speed_changed
   18.26 +        sb_speed_changed,
   18.27 +        NULL
   18.28  };
   18.29  device_t sb_pro_v1_device =
   18.30  {
   18.31          "Sound Blaster Pro v1",
   18.32          sb_pro_v1_init,
   18.33          sb_close,
   18.34 -        sb_speed_changed
   18.35 +        sb_speed_changed,
   18.36 +        NULL
   18.37  };
   18.38  device_t sb_pro_v2_device =
   18.39  {
   18.40          "Sound Blaster Pro v2",
   18.41          sb_pro_v2_init,
   18.42          sb_close,
   18.43 -        sb_speed_changed
   18.44 +        sb_speed_changed,
   18.45 +        NULL
   18.46  };
   18.47  device_t sb_16_device =
   18.48  {
   18.49          "Sound Blaster 16",
   18.50          sb_16_init,
   18.51          sb_close,
   18.52 -        sb_speed_changed
   18.53 +        sb_speed_changed,
   18.54 +        NULL
   18.55  };
    19.1 --- a/src/sound_sb_dsp.c	Tue Jun 04 20:52:17 2013 +0100
    19.2 +++ b/src/sound_sb_dsp.c	Mon Jun 24 20:42:35 2013 +0100
    19.3 @@ -272,6 +272,12 @@
    19.4          pclog("sb_exec_command : SB command %02X\n", dsp->sb_command);
    19.5          switch (dsp->sb_command)
    19.6          {
    19.7 +                case 0x01: /*???*/
    19.8 +                sb_add_data(dsp, 0);
    19.9 +                break;
   19.10 +                case 0x03: /*ASP status*/
   19.11 +                sb_add_data(dsp, 0);
   19.12 +                break;
   19.13                  case 0x10: /*8-bit direct mode*/
   19.14                  dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8;
   19.15                  break;
    20.1 --- a/src/sound_sn76489.c	Tue Jun 04 20:52:17 2013 +0100
    20.2 +++ b/src/sound_sn76489.c	Mon Jun 24 20:42:35 2013 +0100
    20.3 @@ -194,5 +194,6 @@
    20.4          "TI SN74689 PSG",
    20.5          sn76489_init,
    20.6          sn76489_close,
    20.7 +        NULL,
    20.8          NULL
    20.9  };
    21.1 --- a/src/sound_wss.c	Tue Jun 04 20:52:17 2013 +0100
    21.2 +++ b/src/sound_wss.c	Mon Jun 24 20:42:35 2013 +0100
    21.3 @@ -303,5 +303,6 @@
    21.4          "Windows Sound System",
    21.5          wss_init,
    21.6          wss_close,
    21.7 +        NULL,
    21.8          NULL
    21.9  };
    22.1 --- a/src/vid_ati18800.c	Tue Jun 04 20:52:17 2013 +0100
    22.2 +++ b/src/vid_ati18800.c	Mon Jun 24 20:42:35 2013 +0100
    22.3 @@ -1,142 +1,163 @@
    22.4  /*ATI 18800 emulation (VGA Edge-16)*/
    22.5 +#include <stdlib.h>
    22.6  #include "ibm.h"
    22.7 +#include "device.h"
    22.8  #include "io.h"
    22.9  #include "video.h"
   22.10 +#include "vid_ati18800.h"
   22.11  #include "vid_ati_eeprom.h"
   22.12  #include "vid_svga.h"
   22.13  
   22.14 -static uint8_t ati_regs[256];
   22.15 -static int ati_index;
   22.16 +typedef struct ati18800_t
   22.17 +{
   22.18 +        svga_t svga;
   22.19 +        ati_eeprom_t eeprom;
   22.20 +        
   22.21 +        uint8_t regs[256];
   22.22 +        int index;
   22.23 +} ati18800_t;
   22.24  
   22.25 -void ati18800_out(uint16_t addr, uint8_t val, void *priv)
   22.26 +void ati18800_out(uint16_t addr, uint8_t val, void *p)
   22.27  {
   22.28 +        ati18800_t *ati18800 = (ati18800_t *)p;
   22.29 +        svga_t *svga = &ati18800->svga;
   22.30          uint8_t old;
   22.31          
   22.32          pclog("ati18800_out : %04X %02X  %04X:%04X\n", addr, val, CS,pc);
   22.33                  
   22.34 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   22.35 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60;
   22.36  
   22.37          switch (addr)
   22.38          {
   22.39                  case 0x1ce:
   22.40 -                ati_index = val;
   22.41 +                ati18800->index = val;
   22.42                  break;
   22.43                  case 0x1cf:
   22.44 -                ati_regs[ati_index] = val;
   22.45 -                switch (ati_index)
   22.46 +                ati18800->regs[ati18800->index] = val;
   22.47 +                switch (ati18800->index)
   22.48                  {
   22.49                          case 0xb2:
   22.50                          case 0xbe:
   22.51 -                        if (ati_regs[0xbe] & 8) /*Read/write bank mode*/
   22.52 +                        if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/
   22.53                          {
   22.54 -                                svgarbank = ((ati_regs[0xb2] >> 5) & 7) * 0x10000;
   22.55 -                                svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
   22.56 +                                svga->read_bank  = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000;
   22.57 +                                svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
   22.58                          }
   22.59                          else                    /*Single bank mode*/
   22.60 -                                svgarbank = svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
   22.61 +                                svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
   22.62                          break;
   22.63                          case 0xb3:
   22.64 -                        ati_eeprom_write(val & 8, val & 2, val & 1);
   22.65 +                        ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1);
   22.66                          break;
   22.67                  }
   22.68                  break;
   22.69                  
   22.70                  case 0x3D4:
   22.71 -                crtcreg = val & 0x3f;
   22.72 +                svga->crtcreg = val & 0x3f;
   22.73                  return;
   22.74                  case 0x3D5:
   22.75 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
   22.76 -                old=crtc[crtcreg];
   22.77 -                crtc[crtcreg]=val;
   22.78 -                if (old!=val)
   22.79 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
   22.80 +                old = svga->crtc[svga->crtcreg];
   22.81 +                svga->crtc[svga->crtcreg] = val;
   22.82 +                if (old != val)
   22.83                  {
   22.84 -                        if (crtcreg<0xE || crtcreg>0x10)
   22.85 +                        if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
   22.86                          {
   22.87 -                                fullchange=changeframecount;
   22.88 -                                svga_recalctimings();
   22.89 +                                fullchange = changeframecount;
   22.90 +                                svga_recalctimings(svga);
   22.91                          }
   22.92                  }
   22.93                  break;
   22.94          }
   22.95 -        svga_out(addr, val, NULL);
   22.96 +        svga_out(addr, val, svga);
   22.97  }
   22.98  
   22.99 -uint8_t ati18800_in(uint16_t addr, void *priv)
  22.100 +uint8_t ati18800_in(uint16_t addr, void *p)
  22.101  {
  22.102 +        ati18800_t *ati18800 = (ati18800_t *)p;
  22.103 +        svga_t *svga = &ati18800->svga;
  22.104          uint8_t temp;
  22.105  
  22.106          if (addr != 0x3da) pclog("ati18800_in : %04X ", addr);
  22.107                  
  22.108 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  22.109 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60;
  22.110               
  22.111          switch (addr)
  22.112          {
  22.113                  case 0x1ce:
  22.114 -                temp = ati_index;
  22.115 +                temp = ati18800->index;
  22.116                  break;
  22.117                  case 0x1cf:
  22.118 -                switch (ati_index)
  22.119 +                switch (ati18800->index)
  22.120                  {
  22.121                          case 0xb7:
  22.122 -                        temp = ati_regs[ati_index] & ~8;
  22.123 -                        if (ati_eeprom_read())
  22.124 +                        temp = ati18800->regs[ati18800->index] & ~8;
  22.125 +                        if (ati_eeprom_read(&ati18800->eeprom))
  22.126                                  temp |= 8;
  22.127                          break;
  22.128                          
  22.129                          default:
  22.130 -                        temp = ati_regs[ati_index];
  22.131 +                        temp = ati18800->regs[ati18800->index];
  22.132                          break;
  22.133                  }
  22.134                  break;
  22.135  
  22.136                  case 0x3D4:
  22.137 -                temp = crtcreg;
  22.138 +                temp = svga->crtcreg;
  22.139                  break;
  22.140                  case 0x3D5:
  22.141 -                temp = crtc[crtcreg];
  22.142 +                temp = svga->crtc[svga->crtcreg];
  22.143                  break;
  22.144                  default:
  22.145 -                temp = svga_in(addr, NULL);
  22.146 +                temp = svga_in(addr, svga);
  22.147                  break;
  22.148          }
  22.149          if (addr != 0x3da) pclog("%02X  %04X:%04X\n", temp, CS,pc);
  22.150          return temp;
  22.151  }
  22.152  
  22.153 -int ati18800_init()
  22.154 +void *ati18800_init()
  22.155  {
  22.156 -        svga_recalctimings_ex = NULL;
  22.157 -        svga_vram_limit = 1 << 19; /*512kb*/
  22.158 -        vrammask = 0x7ffff;
  22.159 -        svgawbank = svgarbank = 0;
  22.160 -        bpp = 8;
  22.161 -        svga_miscout = 1;
  22.162 +        ati18800_t *ati18800 = malloc(sizeof(ati18800_t));
  22.163 +        memset(ati18800, 0, sizeof(ati18800_t));
  22.164          
  22.165 -        io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL,  NULL);
  22.166 -        
  22.167 -        ati_eeprom_load("ati18800.nvr", 0);
  22.168 -        
  22.169 -        return svga_init();
  22.170 +        svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/
  22.171 +                   NULL,
  22.172 +                   ati18800_in, ati18800_out,
  22.173 +                   NULL);
  22.174 +
  22.175 +        io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);
  22.176 +        io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);
  22.177 +
  22.178 +        ati18800->svga.miscout = 1;
  22.179 +
  22.180 +        ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0);
  22.181 +
  22.182 +        return ati18800;
  22.183  }
  22.184  
  22.185 -GFXCARD vid_ati18800 =
  22.186 +void ati18800_close(void *p)
  22.187  {
  22.188 +        ati18800_t *ati18800 = (ati18800_t *)p;
  22.189 +
  22.190 +        svga_close(&ati18800->svga);
  22.191 +        
  22.192 +        free(ati18800);
  22.193 +}
  22.194 +
  22.195 +void ati18800_speed_changed(void *p)
  22.196 +{
  22.197 +        ati18800_t *ati18800 = (ati18800_t *)p;
  22.198 +        
  22.199 +        svga_recalctimings(&ati18800->svga);
  22.200 +}
  22.201 +
  22.202 +device_t ati18800_device =
  22.203 +{
  22.204 +        "ATI-18800",
  22.205          ati18800_init,
  22.206 -        /*IO at 3Cx/3Dx*/
  22.207 -        ati18800_out,
  22.208 -        ati18800_in,
  22.209 -        /*IO at 3Ax/3Bx*/
  22.210 -        video_out_null,
  22.211 -        video_in_null,
  22.212 +        ati18800_close,
  22.213 +        ati18800_speed_changed,
  22.214 +        svga_add_status_info
  22.215 +};
  22.216  
  22.217 -        svga_poll,
  22.218 -        svga_recalctimings,
  22.219 -
  22.220 -        svga_write,
  22.221 -        video_write_null,
  22.222 -        video_write_null,
  22.223 -
  22.224 -        svga_read,
  22.225 -        video_read_null,
  22.226 -        video_read_null
  22.227 -};
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/src/vid_ati18800.h	Mon Jun 24 20:42:35 2013 +0100
    23.3 @@ -0,0 +1,1 @@
    23.4 +extern device_t ati18800_device;
    24.1 --- a/src/vid_ati28800.c	Tue Jun 04 20:52:17 2013 +0100
    24.2 +++ b/src/vid_ati28800.c	Mon Jun 24 20:42:35 2013 +0100
    24.3 @@ -1,161 +1,183 @@
    24.4  /*ATI 28800 emulation (VGA Charger)*/
    24.5 +#include <stdlib.h>
    24.6  #include "ibm.h"
    24.7 +#include "device.h"
    24.8  #include "io.h"
    24.9  #include "video.h"
   24.10 +#include "vid_ati28800.h"
   24.11  #include "vid_ati_eeprom.h"
   24.12  #include "vid_svga.h"
   24.13  #include "vid_svga_render.h"
   24.14  
   24.15 -static uint8_t ati_regs[256];
   24.16 -static int ati_index;
   24.17 +typedef struct ati28800_t
   24.18 +{
   24.19 +        svga_t svga;
   24.20 +        ati_eeprom_t eeprom;
   24.21 +        
   24.22 +        uint8_t regs[256];
   24.23 +        int index;
   24.24 +} ati28800_t;
   24.25  
   24.26 -void ati28800_out(uint16_t addr, uint8_t val, void *priv)
   24.27 +void ati28800_out(uint16_t addr, uint8_t val, void *p)
   24.28  {
   24.29 +        ati28800_t *ati28800 = (ati28800_t *)p;
   24.30 +        svga_t *svga = &ati28800->svga;
   24.31          uint8_t old;
   24.32          
   24.33          pclog("ati28800_out : %04X %02X  %04X:%04X\n", addr, val, CS,pc);
   24.34                  
   24.35 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   24.36 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) 
   24.37 +                addr ^= 0x60;
   24.38  
   24.39          switch (addr)
   24.40          {
   24.41                  case 0x1ce:
   24.42 -                ati_index = val;
   24.43 +                ati28800->index = val;
   24.44                  break;
   24.45                  case 0x1cf:
   24.46 -                ati_regs[ati_index] = val;
   24.47 -                switch (ati_index)
   24.48 +                ati28800->regs[ati28800->index] = val;
   24.49 +                switch (ati28800->index)
   24.50                  {
   24.51                          case 0xb2:
   24.52                          case 0xbe:
   24.53 -                        if (ati_regs[0xbe] & 8) /*Read/write bank mode*/
   24.54 +                        if (ati28800->regs[0xbe] & 8) /*Read/write bank mode*/
   24.55                          {
   24.56 -                                svgarbank = ((ati_regs[0xb2] >> 5) & 7) * 0x10000;
   24.57 -                                svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
   24.58 +                                svga->read_bank  = ((ati28800->regs[0xb2] >> 5) & 7) * 0x10000;
   24.59 +                                svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000;
   24.60                          }
   24.61                          else                    /*Single bank mode*/
   24.62 -                                svgarbank = svgawbank = ((ati_regs[0xb2] >> 1) & 7) * 0x10000;
   24.63 +                                svga->read_bank = svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000;
   24.64                          break;
   24.65                          case 0xb3:
   24.66 -                        ati_eeprom_write(val & 8, val & 2, val & 1);
   24.67 +                        ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1);
   24.68                          break;
   24.69                  }
   24.70                  break;
   24.71                  
   24.72                  case 0x3D4:
   24.73 -                crtcreg = val & 0x3f;
   24.74 +                svga->crtcreg = val & 0x3f;
   24.75                  return;
   24.76                  case 0x3D5:
   24.77 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
   24.78 -                old=crtc[crtcreg];
   24.79 -                crtc[crtcreg]=val;
   24.80 -                if (old!=val)
   24.81 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
   24.82 +                old = svga->crtc[svga->crtcreg];
   24.83 +                svga->crtc[svga->crtcreg] = val;
   24.84 +                if (old != val)
   24.85                  {
   24.86 -                        if (crtcreg<0xE || crtcreg>0x10)
   24.87 +                        if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
   24.88                          {
   24.89 -                                fullchange=changeframecount;
   24.90 -                                svga_recalctimings();
   24.91 +                                fullchange = changeframecount;
   24.92 +                                svga_recalctimings(svga);
   24.93                          }
   24.94                  }
   24.95                  break;
   24.96          }
   24.97 -        svga_out(addr, val, NULL);
   24.98 +        svga_out(addr, val, svga);
   24.99  }
  24.100  
  24.101 -uint8_t ati28800_in(uint16_t addr, void *priv)
  24.102 +uint8_t ati28800_in(uint16_t addr, void *p)
  24.103  {
  24.104 +        ati28800_t *ati28800 = (ati28800_t *)p;
  24.105 +        svga_t *svga = &ati28800->svga;
  24.106          uint8_t temp;
  24.107  
  24.108          if (addr != 0x3da) pclog("ati28800_in : %04X ", addr);
  24.109                  
  24.110 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  24.111 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60;
  24.112               
  24.113          switch (addr)
  24.114          {
  24.115                  case 0x1ce:
  24.116 -                temp = ati_index;
  24.117 +                temp = ati28800->index;
  24.118                  break;
  24.119                  case 0x1cf:
  24.120 -                switch (ati_index)
  24.121 +                switch (ati28800->index)
  24.122                  {
  24.123                          case 0xb7:
  24.124 -                        temp = ati_regs[ati_index] & ~8;
  24.125 -                        if (ati_eeprom_read())
  24.126 +                        temp = ati28800->regs[ati28800->index] & ~8;
  24.127 +                        if (ati_eeprom_read(&ati28800->eeprom))
  24.128                                  temp |= 8;
  24.129                          break;
  24.130                          
  24.131                          default:
  24.132 -                        temp = ati_regs[ati_index];
  24.133 +                        temp = ati28800->regs[ati28800->index];
  24.134                          break;
  24.135                  }
  24.136                  break;
  24.137  
  24.138                  case 0x3c2:
  24.139 -                if ((vgapal[0].r + vgapal[0].g + vgapal[0].b) >= 0x50)
  24.140 +                if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50)
  24.141                          temp = 0;
  24.142                  else
  24.143                          temp = 0x10;
  24.144                  break;
  24.145                  case 0x3D4:
  24.146 -                temp = crtcreg;
  24.147 +                temp = svga->crtcreg;
  24.148                  break;
  24.149                  case 0x3D5:
  24.150 -                temp = crtc[crtcreg];
  24.151 +                temp = svga->crtc[svga->crtcreg];
  24.152                  break;
  24.153                  default:
  24.154 -                temp = svga_in(addr, NULL);
  24.155 +                temp = svga_in(addr, svga);
  24.156                  break;
  24.157          }
  24.158          if (addr != 0x3da) pclog("%02X  %04X:%04X\n", temp, CS,pc);
  24.159          return temp;
  24.160  }
  24.161  
  24.162 -void ati28800_recalctimings()
  24.163 +void ati28800_recalctimings(svga_t *svga)
  24.164  {
  24.165 +        ati28800_t *ati28800 = (ati28800_t *)svga->p;
  24.166          pclog("ati28800_recalctimings\n");
  24.167 -        if (!scrblank && (ati_regs[0xb0] & 0x20)) /*Extended 256 colour modes*/
  24.168 +        if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/
  24.169          {
  24.170                  pclog("8bpp_highres\n");
  24.171 -                svga_render = svga_render_8bpp_highres;
  24.172 -                svga_rowoffset <<= 1;
  24.173 -                svga_ma <<= 1;
  24.174 +                svga->render = svga_render_8bpp_highres;
  24.175 +                svga->rowoffset <<= 1;
  24.176 +                svga->ma <<= 1;
  24.177          }
  24.178  }               
  24.179  
  24.180 -int ati28800_init()
  24.181 +void *ati28800_init()
  24.182  {
  24.183 -        svga_recalctimings_ex = ati28800_recalctimings;
  24.184 -        svga_vram_limit = 1 << 19; /*512kb*/
  24.185 -        vrammask = 0x7ffff;
  24.186 -        svgawbank = svgarbank = 0;
  24.187 -        bpp = 8;
  24.188 -        svga_miscout = 1;
  24.189 +        ati28800_t *ati28800 = malloc(sizeof(ati28800_t));
  24.190 +        memset(ati28800, 0, sizeof(ati28800_t));
  24.191          
  24.192 -        io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL,  NULL);
  24.193 -        
  24.194 -        ati_eeprom_load("ati28800.nvr", 0);
  24.195 -        
  24.196 -        return svga_init();
  24.197 +        svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/
  24.198 +                   ati28800_recalctimings,
  24.199 +                   ati28800_in, ati28800_out,
  24.200 +                   NULL);
  24.201 +
  24.202 +        io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800);
  24.203 +        io_sethandler(0x03c0, 0x0020, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800);
  24.204 +
  24.205 +        ati28800->svga.miscout = 1;
  24.206 +
  24.207 +        ati_eeprom_load(&ati28800->eeprom, "ati28800.nvr", 0);
  24.208 +
  24.209 +        return ati28800;
  24.210  }
  24.211  
  24.212 -GFXCARD vid_ati28800 =
  24.213 +void ati28800_close(void *p)
  24.214  {
  24.215 +        ati28800_t *ati28800 = (ati28800_t *)p;
  24.216 +
  24.217 +        svga_close(&ati28800->svga);
  24.218 +        
  24.219 +        free(ati28800);
  24.220 +}
  24.221 +
  24.222 +void ati28800_speed_changed(void *p)
  24.223 +{
  24.224 +        ati28800_t *ati28800 = (ati28800_t *)p;
  24.225 +        
  24.226 +        svga_recalctimings(&ati28800->svga);
  24.227 +}
  24.228 +
  24.229 +device_t ati28800_device =
  24.230 +{
  24.231 +        "ATI-28800",
  24.232          ati28800_init,
  24.233 -        /*IO at 3Cx/3Dx*/
  24.234 -        ati28800_out,
  24.235 -        ati28800_in,
  24.236 -        /*IO at 3Ax/3Bx*/
  24.237 -        video_out_null,
  24.238 -        video_in_null,
  24.239 -
  24.240 -        svga_poll,
  24.241 -        svga_recalctimings,
  24.242 -
  24.243 -        svga_write,
  24.244 -        video_write_null,
  24.245 -        video_write_null,
  24.246 -
  24.247 -        svga_read,
  24.248 -        video_read_null,
  24.249 -        video_read_null
  24.250 +        ati28800_close,
  24.251 +        ati28800_speed_changed,
  24.252 +        svga_add_status_info
  24.253  };
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/src/vid_ati28800.h	Mon Jun 24 20:42:35 2013 +0100
    25.3 @@ -0,0 +1,1 @@
    25.4 +extern device_t ati28800_device;
    26.1 --- a/src/vid_ati68860_ramdac.c	Tue Jun 04 20:52:17 2013 +0100
    26.2 +++ b/src/vid_ati68860_ramdac.c	Mon Jun 24 20:42:35 2013 +0100
    26.3 @@ -23,46 +23,45 @@
    26.4  #include "vid_svga.h"
    26.5  #include "vid_ati68860_ramdac.h"
    26.6  
    26.7 -static uint8_t ramdac_regs[16];
    26.8 -void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv)
    26.9 +void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga)
   26.10  {
   26.11  //        pclog("ati68860_out : addr %04X val %02X  %04X:%04X\n", addr, val, CS,pc);
   26.12          switch (addr)
   26.13          {
   26.14                  case 0: 
   26.15 -                svga_out(0x3c8, val, NULL); 
   26.16 +                svga_out(0x3c8, val, svga);
   26.17                  break;
   26.18                  case 1: 
   26.19 -                svga_out(0x3c9, val, NULL); 
   26.20 +                svga_out(0x3c9, val, svga); 
   26.21                  break;
   26.22                  case 2: 
   26.23 -                svga_out(0x3c6, val, NULL); 
   26.24 +                svga_out(0x3c6, val, svga); 
   26.25                  break;
   26.26                  case 3: 
   26.27 -                svga_out(0x3c7, val, NULL); 
   26.28 +                svga_out(0x3c7, val, svga); 
   26.29                  break;
   26.30                  default:
   26.31 -                ramdac_regs[addr & 0xf] = val;
   26.32 +                ramdac->regs[addr & 0xf] = val;
   26.33                  break;
   26.34          }
   26.35  }
   26.36  
   26.37 -uint8_t ati68860_ramdac_in(uint16_t addr, void *priv)
   26.38 +uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga)
   26.39  {
   26.40          uint8_t ret = 0;
   26.41          switch (addr)
   26.42          {
   26.43                  case 0:
   26.44 -                ret = svga_in(0x3c8, NULL);
   26.45 +                ret = svga_in(0x3c8, svga);
   26.46                  break;
   26.47                  case 1:
   26.48 -                ret = svga_in(0x3c9, NULL);
   26.49 +                ret = svga_in(0x3c9, svga);
   26.50                  break;
   26.51                  case 2:
   26.52 -                ret = svga_in(0x3c6, NULL);
   26.53 +                ret = svga_in(0x3c6, svga);
   26.54                  break;
   26.55                  case 3:
   26.56 -                ret = svga_in(0x3c7, NULL);
   26.57 +                ret = svga_in(0x3c7, svga);
   26.58                  break;
   26.59                  case 4: case 8:
   26.60                  ret = 2; 
   26.61 @@ -75,7 +74,7 @@
   26.62                  break;
   26.63                  
   26.64                  default:
   26.65 -                ret = ramdac_regs[addr & 0xf];
   26.66 +                ret = ramdac->regs[addr & 0xf];
   26.67                  break;
   26.68          }
   26.69  //        pclog("ati68860_in  : addr %04X ret %02X  %04X:%04X\n", addr, ret, CS,pc);
    27.1 --- a/src/vid_ati68860_ramdac.h	Tue Jun 04 20:52:17 2013 +0100
    27.2 +++ b/src/vid_ati68860_ramdac.h	Mon Jun 24 20:42:35 2013 +0100
    27.3 @@ -1,2 +1,7 @@
    27.4 -void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv);
    27.5 -uint8_t ati68860_ramdac_in(uint16_t addr, void *priv);
    27.6 +typedef struct ati68860_ramdac_t
    27.7 +{
    27.8 +        uint8_t regs[16];
    27.9 +} ati68860_ramdac_t;
   27.10 +
   27.11 +void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga);
   27.12 +uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga);
    28.1 --- a/src/vid_ati_eeprom.c	Tue Jun 04 20:52:17 2013 +0100
    28.2 +++ b/src/vid_ati_eeprom.c	Mon Jun 24 20:42:35 2013 +0100
    28.3 @@ -1,7 +1,6 @@
    28.4  #include "ibm.h"
    28.5  #include "vid_ati_eeprom.h"
    28.6  
    28.7 -static uint16_t eeprom[256];
    28.8  enum
    28.9  {
   28.10          EEPROM_IDLE,
   28.11 @@ -29,201 +28,193 @@
   28.12          EEPROM_OP_EWEN = 3
   28.13  };
   28.14  
   28.15 -static int oldclk, oldena;
   28.16 -static int eeprom_opcode, eeprom_state, eeprom_count, eeprom_out;
   28.17 -static int eeprom_wp;
   28.18 -static uint32_t eeprom_dat;
   28.19 -static int eeprom_type;
   28.20 -
   28.21 -static char eeprom_fn[256] = {0};
   28.22 -
   28.23 -void ati_eeprom_load(char *fn, int type)
   28.24 +void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type)
   28.25  {
   28.26          FILE *f;
   28.27 -        eeprom_type = type;
   28.28 -        strcpy(eeprom_fn, fn);
   28.29 -        f = romfopen(eeprom_fn, "rb");
   28.30 +        eeprom->type = type;
   28.31 +        strcpy(eeprom->fn, fn);
   28.32 +        f = romfopen(eeprom->fn, "rb");
   28.33          if (!f)
   28.34          {
   28.35 -                memset(eeprom, 0, type ? 512 : 128);
   28.36 +                memset(eeprom->data, 0, eeprom->type ? 512 : 128);
   28.37                  return;
   28.38          }
   28.39 -        fread(eeprom, 1, type ? 512 : 128, f);
   28.40 +        fread(eeprom->data, 1, eeprom->type ? 512 : 128, f);
   28.41          fclose(f);
   28.42  }
   28.43  
   28.44 -void ati_eeprom_save()
   28.45 +void ati_eeprom_save(ati_eeprom_t *eeprom)
   28.46  {
   28.47 -        FILE *f = romfopen(eeprom_fn, "wb");
   28.48 +        FILE *f = romfopen(eeprom->fn, "wb");
   28.49          if (!f) return;
   28.50 -        fwrite(eeprom, 1, eeprom_type ? 512 : 128, f);
   28.51 +        fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f);
   28.52          fclose(f);
   28.53  }
   28.54  
   28.55 -void ati_eeprom_write(int ena, int clk, int dat)
   28.56 +void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat)
   28.57  {
   28.58          int c;
   28.59          pclog("EEPROM write %i %i %i\n", ena, clk, dat);
   28.60          if (!ena)
   28.61          {
   28.62 -                eeprom_out = 1;
   28.63 +                eeprom->out = 1;
   28.64          }
   28.65 -        if (clk && !oldclk)
   28.66 +        if (clk && !eeprom->oldclk)
   28.67          {
   28.68 -                if (ena && !oldena)
   28.69 +                if (ena && !eeprom->oldena)
   28.70                  {
   28.71 -                        eeprom_state = EEPROM_WAIT;
   28.72 -                        eeprom_opcode = 0;
   28.73 -                        eeprom_count = 3;
   28.74 -                        eeprom_out = 1;
   28.75 +                        eeprom->state = EEPROM_WAIT;
   28.76 +                        eeprom->opcode = 0;
   28.77 +                        eeprom->count = 3;
   28.78 +                        eeprom->out = 1;
   28.79                  }
   28.80                  else if (ena)
   28.81                  {
   28.82                          pclog("EEPROM receive %i %i %i\n", ena, clk, dat);
   28.83 -                        switch (eeprom_state)
   28.84 +                        switch (eeprom->state)
   28.85                          {
   28.86                                  case EEPROM_WAIT:
   28.87                                  if (!dat)
   28.88                                          break;
   28.89 -                                eeprom_state = EEPROM_OPCODE;
   28.90 +                                eeprom->state = EEPROM_OPCODE;
   28.91                                  /* fall through */
   28.92                                  case EEPROM_OPCODE:
   28.93 -                                eeprom_opcode = (eeprom_opcode << 1) | (dat ? 1 : 0);
   28.94 -                                eeprom_count--;
   28.95 -                                if (!eeprom_count)
   28.96 +                                eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0);
   28.97 +                                eeprom->count--;
   28.98 +                                if (!eeprom->count)
   28.99                                  {
  28.100 -                                        pclog("EEPROM opcode - %i\n", eeprom_opcode);
  28.101 -                                        switch (eeprom_opcode)
  28.102 +                                        pclog("EEPROM opcode - %i\n", eeprom->opcode);
  28.103 +                                        switch (eeprom->opcode)
  28.104                                          {
  28.105                                                  case EEPROM_OP_WRITE:
  28.106 -                                                eeprom_count = eeprom_type ? 24 : 22;
  28.107 -                                                eeprom_state = EEPROM_INPUT;
  28.108 -                                                eeprom_dat = 0;
  28.109 +                                                eeprom->count = eeprom->type ? 24 : 22;
  28.110 +                                                eeprom->state = EEPROM_INPUT;
  28.111 +                                                eeprom->dat = 0;
  28.112                                                  break;
  28.113                                                  case EEPROM_OP_READ:
  28.114 -                                                eeprom_count = eeprom_type ? 8 : 6;
  28.115 -                                                eeprom_state = EEPROM_INPUT;
  28.116 -                                                eeprom_dat = 0;
  28.117 +                                                eeprom->count = eeprom->type ? 8 : 6;
  28.118 +                                                eeprom->state = EEPROM_INPUT;
  28.119 +                                                eeprom->dat = 0;
  28.120                                                  break;
  28.121                                                  case EEPROM_OP_EW:
  28.122 -                                                eeprom_count = 2;
  28.123 -                                                eeprom_state = EEPROM_INPUT;
  28.124 -                                                eeprom_dat = 0;
  28.125 +                                                eeprom->count = 2;
  28.126 +                                                eeprom->state = EEPROM_INPUT;
  28.127 +                                                eeprom->dat = 0;
  28.128                                                  break;
  28.129                                                  case EEPROM_OP_ERASE:
  28.130 -                                                eeprom_count = eeprom_type ? 8 : 6;
  28.131 -                                                eeprom_state = EEPROM_INPUT;
  28.132 -                                                eeprom_dat = 0;
  28.133 +                                                eeprom->count = eeprom->type ? 8 : 6;
  28.134 +                                                eeprom->state = EEPROM_INPUT;
  28.135 +                                                eeprom->dat = 0;
  28.136                                                  break;
  28.137                                          }
  28.138                                  }
  28.139                                  break;
  28.140                                  
  28.141                                  case EEPROM_INPUT:
  28.142 -                                eeprom_dat = (eeprom_dat << 1) | (dat ? 1 : 0);
  28.143 -                                eeprom_count--;
  28.144 -                                if (!eeprom_count)
  28.145 +                                eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0);
  28.146 +                                eeprom->count--;
  28.147 +                                if (!eeprom->count)
  28.148                                  {
  28.149 -                                        pclog("EEPROM dat - %02X\n", eeprom_dat);
  28.150 -                                        switch (eeprom_opcode)
  28.151 +                                        pclog("EEPROM dat - %02X\n", eeprom->dat);
  28.152 +                                        switch (eeprom->opcode)
  28.153                                          {
  28.154                                                  case EEPROM_OP_WRITE:
  28.155 -                                                pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom_dat >> 16) & (eeprom_type ? 255 : 63), eeprom_dat & 0xffff);
  28.156 -                                                if (!eeprom_wp)
  28.157 +                                                pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom->dat >> 16) & (eeprom->type ? 255 : 63), eeprom->dat & 0xffff);
  28.158 +                                                if (!eeprom->wp)
  28.159                                                  {
  28.160 -                                                        eeprom[(eeprom_dat >> 16) & (eeprom_type ? 255 : 63)] = eeprom_dat & 0xffff;
  28.161 -                                                        ati_eeprom_save();
  28.162 +                                                        eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff;
  28.163 +                                                        ati_eeprom_save(eeprom);
  28.164                                                  }
  28.165 -                                                eeprom_state = EEPROM_IDLE;
  28.166 -                                                eeprom_out = 1;
  28.167 +                                                eeprom->state = EEPROM_IDLE;
  28.168 +                                                eeprom->out = 1;
  28.169                                                  break;
  28.170  
  28.171                                                  case EEPROM_OP_READ:
  28.172 -                                                eeprom_count = 17;
  28.173 -                                                eeprom_state = EEPROM_OUTPUT;
  28.174 -                                                eeprom_dat = eeprom[eeprom_dat];
  28.175 -                                                pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom_dat);
  28.176 +                                                eeprom->count = 17;
  28.177 +                                                eeprom->state = EEPROM_OUTPUT;
  28.178 +                                                eeprom->dat = eeprom->data[eeprom->dat];
  28.179 +                                                pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom->dat);
  28.180                                                  break;
  28.181                                                  case EEPROM_OP_EW:
  28.182 -                                                pclog("EEPROM_OP_EW %i\n", eeprom_dat);
  28.183 -                                                switch (eeprom_dat)
  28.184 +                                                pclog("EEPROM_OP_EW %i\n", eeprom->dat);
  28.185 +                                                switch (eeprom->dat)
  28.186                                                  {
  28.187                                                          case EEPROM_OP_EWDS:
  28.188 -                                                        eeprom_wp = 1;
  28.189 +                                                        eeprom->wp = 1;
  28.190                                                          break;
  28.191                                                          case EEPROM_OP_WRAL:
  28.192 -                                                        opcode = EEPROM_OP_WRALMAIN;
  28.193 -                                                        eeprom_count = 20;
  28.194 +                                                        eeprom->opcode = EEPROM_OP_WRALMAIN;
  28.195 +                                                        eeprom->count = 20;
  28.196                                                          break;
  28.197                                                          case EEPROM_OP_ERAL:
  28.198 -                                                        if (!eeprom_wp)
  28.199 +                                                        if (!eeprom->wp)
  28.200                                                          {
  28.201 -                                                                memset(eeprom, 0xff, 128);
  28.202 -                                                                ati_eeprom_save();
  28.203 +                                                                memset(eeprom->data, 0xff, 128);
  28.204 +                                                                ati_eeprom_save(eeprom);
  28.205                                                          }
  28.206                                                          break;
  28.207                                                          case EEPROM_OP_EWEN:
  28.208 -                                                        eeprom_wp = 0;
  28.209 +                                                        eeprom->wp = 0;
  28.210                                                          break;
  28.211                                                  }
  28.212 -                                                eeprom_state = EEPROM_IDLE;
  28.213 -                                                eeprom_out = 1;
  28.214 +                                                eeprom->state = EEPROM_IDLE;
  28.215 +                                                eeprom->out = 1;
  28.216                                                  break;
  28.217  
  28.218                                                  case EEPROM_OP_ERASE:
  28.219 -                                                pclog("EEPROM_OP_ERASE %i\n", eeprom_dat);
  28.220 -                                                if (!eeprom_wp)
  28.221 +                                                pclog("EEPROM_OP_ERASE %i\n", eeprom->dat);
  28.222 +                                                if (!eeprom->wp)
  28.223                                                  {
  28.224 -                                                        eeprom[eeprom_dat] = 0xffff;
  28.225 -                                                        ati_eeprom_save();
  28.226 +                                                        eeprom->data[eeprom->dat] = 0xffff;
  28.227 +                                                        ati_eeprom_save(eeprom);
  28.228                                                  }
  28.229 -                                                eeprom_state = EEPROM_IDLE;
  28.230 -                                                eeprom_out = 1;
  28.231 +                                                eeprom->state = EEPROM_IDLE;
  28.232 +                                                eeprom->out = 1;
  28.233                                                  break;
  28.234  
  28.235                                                  case EEPROM_OP_WRALMAIN:
  28.236 -                                                pclog("EEPROM_OP_WRAL %04X\n", eeprom_dat);
  28.237 -                                                if (!eeprom_wp)
  28.238 +                                                pclog("EEPROM_OP_WRAL %04X\n", eeprom->dat);
  28.239 +                                                if (!eeprom->wp)
  28.240                                                  {
  28.241                                                          for (c = 0; c < 256; c++)
  28.242 -                                                                eeprom[c] = eeprom_dat;
  28.243 -                                                        ati_eeprom_save();
  28.244 +                                                                eeprom->data[c] = eeprom->dat;
  28.245 +                                                        ati_eeprom_save(eeprom);
  28.246                                                  }
  28.247 -                                                eeprom_state = EEPROM_IDLE;
  28.248 -                                                eeprom_out = 1;
  28.249 +                                                eeprom->state = EEPROM_IDLE;
  28.250 +                                                eeprom->out = 1;
  28.251                                                  break;
  28.252                                          }
  28.253                                  }
  28.254                                  break;
  28.255                          }
  28.256                  }                
  28.257 -                oldena = ena;
  28.258 +                eeprom->oldena = ena;
  28.259          }
  28.260 -        else if (!clk && oldclk)
  28.261 +        else if (!clk && eeprom->oldclk)
  28.262          {
  28.263                  if (ena)
  28.264                  {
  28.265 -                        switch (eeprom_state)
  28.266 +                        switch (eeprom->state)
  28.267                          {
  28.268                                  case EEPROM_OUTPUT:
  28.269 -                                eeprom_out = (eeprom_dat & 0x10000) ? 1 : 0;
  28.270 -                                eeprom_dat <<= 1;
  28.271 -                                pclog("EEPROM_OUTPUT - data %i\n", eeprom_out);                                
  28.272 -                                eeprom_count--;
  28.273 -                                if (!eeprom_count)
  28.274 +                                eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0;
  28.275 +                                eeprom->dat <<= 1;
  28.276 +                                pclog("EEPROM_OUTPUT - data %i\n", eeprom->out);
  28.277 +                                eeprom->count--;
  28.278 +                                if (!eeprom->count)
  28.279                                  {
  28.280                                          pclog("EEPROM_OUTPUT complete\n");
  28.281 -                                        eeprom_state = EEPROM_IDLE;
  28.282 +                                        eeprom->state = EEPROM_IDLE;
  28.283                                  }
  28.284                                  break;
  28.285                          }
  28.286                  }
  28.287          }
  28.288 -        oldclk = clk;
  28.289 +        eeprom->oldclk = clk;
  28.290  }
  28.291  
  28.292 -int ati_eeprom_read()
  28.293 +int ati_eeprom_read(ati_eeprom_t *eeprom)
  28.294  {
  28.295 -        return eeprom_out;
  28.296 +        return eeprom->out;
  28.297  }
  28.298  
    29.1 --- a/src/vid_ati_eeprom.h	Tue Jun 04 20:52:17 2013 +0100
    29.2 +++ b/src/vid_ati_eeprom.h	Mon Jun 24 20:42:35 2013 +0100
    29.3 @@ -1,3 +1,16 @@
    29.4 -void ati_eeprom_load(char *fn, int type);
    29.5 -void ati_eeprom_write(int ena, int clk, int dat);
    29.6 -int ati_eeprom_read();
    29.7 +typedef struct ati_eeprom_t
    29.8 +{
    29.9 +        uint16_t data[256];
   29.10 +
   29.11 +        int oldclk, oldena;
   29.12 +        int opcode, state, count, out;
   29.13 +        int wp;
   29.14 +        uint32_t dat;
   29.15 +        int type;
   29.16 +
   29.17 +        char fn[256];
   29.18 +} ati_eeprom_t;
   29.19 +
   29.20 +void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type);
   29.21 +void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat);
   29.22 +int ati_eeprom_read(ati_eeprom_t *eeprom);
    30.1 --- a/src/vid_ati_mach64.c	Tue Jun 04 20:52:17 2013 +0100
    30.2 +++ b/src/vid_ati_mach64.c	Mon Jun 24 20:42:35 2013 +0100
    30.3 @@ -1,5 +1,7 @@
    30.4  /*ATI Mach64 emulation*/
    30.5 +#include <stdlib.h>
    30.6  #include "ibm.h"
    30.7 +#include "device.h"
    30.8  #include "io.h"
    30.9  #include "mem.h"
   30.10  #include "video.h"
   30.11 @@ -10,16 +12,22 @@
   30.12  #include "vid_svga_render.h"
   30.13  
   30.14  //#define MACH64_DEBUG
   30.15 -static int mach64_bank_r[2] = {0, 0};
   30.16 -static int mach64_bank_w[2] = {0, 0};
   30.17  void mach64_write(uint32_t addr, uint8_t val, void *priv);
   30.18  uint8_t mach64_read(uint32_t addr, void *priv);
   30.19  
   30.20 -static uint8_t ati_regs[256];
   30.21 -static int ati_index;
   30.22 +typedef struct mach64_t
   30.23 +{
   30.24 +        svga_t svga;
   30.25 +        ati68860_ramdac_t ramdac;
   30.26 +        ati_eeprom_t eeprom;
   30.27 +        ics2595_t ics2595;
   30.28  
   30.29 -struct
   30.30 -{
   30.31 +        uint8_t regs[256];
   30.32 +        int index;
   30.33 +
   30.34 +        int bank_r[2];
   30.35 +        int bank_w[2];
   30.36 +        
   30.37          uint32_t config_cntl;
   30.38  
   30.39          uint32_t context_load_cntl;
   30.40 @@ -62,6 +70,10 @@
   30.41                  
   30.42          uint32_t mem_cntl;
   30.43  
   30.44 +        uint32_t ovr_clr;
   30.45 +        uint32_t ovr_wid_left_right;
   30.46 +        uint32_t ovr_wid_top_bottom;
   30.47 +        
   30.48          uint32_t pat_cntl;        
   30.49          uint32_t pat_reg0, pat_reg1;
   30.50          
   30.51 @@ -73,6 +85,8 @@
   30.52          uint32_t src_off_pitch;
   30.53          uint32_t src_y_x;
   30.54  
   30.55 +        uint8_t stat;
   30.56 +        
   30.57          struct
   30.58          {
   30.59                  int op;
   30.60 @@ -100,7 +114,7 @@
   30.61                  
   30.62                  int err;
   30.63          } accel;
   30.64 -} mach64;
   30.65 +} mach64_t;
   30.66  
   30.67  enum
   30.68  {
   30.69 @@ -149,152 +163,161 @@
   30.70  void     mach64_ext_writew(uint32_t addr, uint16_t val, void *priv);
   30.71  void     mach64_ext_writel(uint32_t addr, uint32_t val, void *priv);
   30.72  
   30.73 -void mach64_out(uint16_t addr, uint8_t val, void *priv)
   30.74 +void mach64_out(uint16_t addr, uint8_t val, void *p)
   30.75  {
   30.76 +        mach64_t *mach64 = p;
   30.77 +        svga_t *svga = &mach64->svga;
   30.78          uint8_t old;
   30.79          
   30.80 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   30.81 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) 
   30.82 +                addr ^= 0x60;
   30.83  
   30.84  //        pclog("mach64 out %04X %02X\n", addr, val);
   30.85                  
   30.86          switch (addr)
   30.87          {
   30.88                  case 0x1ce:
   30.89 -                ati_index = val;
   30.90 +                mach64->index = val;
   30.91                  break;
   30.92                  case 0x1cf:
   30.93 -                ati_regs[ati_index] = val;
   30.94 +                mach64->regs[mach64->index] = val;
   30.95                  break;
   30.96                  
   30.97                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
   30.98 -                ati68860_ramdac_out((addr & 3) | ((mach64.dac_cntl & 3) << 2), val, NULL);
   30.99 +                ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, svga);
  30.100                  return;
  30.101                  
  30.102                  case 0x3cf:
  30.103 -                if (gdcaddr == 6)
  30.104 +                if (svga->gdcaddr == 6)
  30.105                  {
  30.106 -                        if ((gdcreg[6] & 0xc) != (val & 0xc))
  30.107 +                        if ((svga->gdcreg[6] & 0xc) != (val & 0xc))
  30.108                          {
  30.109 -                                mem_removehandler(0xa0000, 0x20000, mach64_read, NULL, NULL, mach64_write, NULL, NULL,  NULL);
  30.110 -                                mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  30.111 -                                mem_removehandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel,  NULL);
  30.112 -                                pclog("Write mapping %02X\n", val);
  30.113 -                                switch (val&0xC)
  30.114 +                                mem_removehandler(0xa0000, 0x20000, mach64_read, NULL, NULL, mach64_write, NULL, NULL,  mach64);
  30.115 +                                mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  svga);
  30.116 +                                mem_removehandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel,  mach64);
  30.117 +//                                pclog("Write mapping %02X\n", val);
  30.118 +                                switch (val & 0xc)
  30.119                                  {
  30.120                                          case 0x0: /*128k at A0000*/
  30.121 -                                        mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL,  NULL);
  30.122 -                                        mem_sethandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel,  NULL);
  30.123 +                                        mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL,  mach64);
  30.124 +                                        mem_sethandler(0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel,  mach64);
  30.125                                          break;
  30.126                                          case 0x4: /*64k at A0000*/
  30.127 -                                        mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL,  NULL);
  30.128 +                                        mem_sethandler(0xa0000, 0x10000, mach64_read, NULL, NULL, mach64_write, NULL, NULL,  mach64);
  30.129                                          break;
  30.130                                          case 0x8: /*32k at B0000*/
  30.131 -                                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  30.132 +                                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  svga);
  30.133                                          break;
  30.134                                          case 0xC: /*32k at B8000*/
  30.135 -                                        mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  30.136 +                                        mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  svga);
  30.137                                          break;
  30.138                                  }
  30.139                          }
  30.140 -                        gdcreg[6] = val;
  30.141 +                        svga->gdcreg[6] = val;
  30.142                          return;
  30.143                  }
  30.144                  break;
  30.145                  
  30.146                  case 0x3D4:
  30.147 -                crtcreg = val & 0x3f;
  30.148 +                svga->crtcreg = val & 0x3f;
  30.149                  return;
  30.150                  case 0x3D5:
  30.151 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
  30.152 -                old=crtc[crtcreg];
  30.153 -                crtc[crtcreg]=val;
  30.154 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
  30.155 +                old = svga->crtc[svga->crtcreg];
  30.156 +                svga->crtc[svga->crtcreg] = val;
  30.157  
  30.158                  if (old!=val)
  30.159                  {
  30.160 -                        if (crtcreg<0xE || crtcreg>0x10)
  30.161 +                        if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
  30.162                          {
  30.163 -                                fullchange=changeframecount;
  30.164 -                                svga_recalctimings();
  30.165 +                                fullchange = changeframecount;
  30.166 +                                svga_recalctimings(svga);
  30.167                          }
  30.168                  }
  30.169                  break;
  30.170          }
  30.171 -        svga_out(addr, val, NULL);
  30.172 +        svga_out(addr, val, svga);
  30.173  }
  30.174  
  30.175 -uint8_t mach64_in(uint16_t addr, void *priv)
  30.176 +uint8_t mach64_in(uint16_t addr, void *p)
  30.177  {
  30.178 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  30.179 +        mach64_t *mach64 = p;
  30.180 +        svga_t *svga = &mach64->svga;
  30.181 +
  30.182 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) 
  30.183 +                addr ^= 0x60;
  30.184          
  30.185  //        pclog("IN mach64 %04X\n", addr);
  30.186          
  30.187          switch (addr)
  30.188          {
  30.189                  case 0x1ce:
  30.190 -                return ati_index;
  30.191 +                return mach64->index;
  30.192                  case 0x1cf:
  30.193 -                return ati_regs[ati_index];
  30.194 +                return mach64->regs[mach64->index];
  30.195  
  30.196                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  30.197 -                return ati68860_ramdac_in((addr & 3) | ((mach64.dac_cntl & 3) << 2), NULL);
  30.198 +                return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, svga);
  30.199                  
  30.200                  case 0x3D4:
  30.201 -                return crtcreg;
  30.202 +                return svga->crtcreg;
  30.203                  case 0x3D5:
  30.204 -                return crtc[crtcreg];
  30.205 +                return svga->crtc[svga->crtcreg];
  30.206          }
  30.207 -        return svga_in(addr, NULL);
  30.208 +        return svga_in(addr, svga);
  30.209  }
  30.210  
  30.211 -void mach64_recalctimings()
  30.212 +void mach64_recalctimings(svga_t *svga)
  30.213  {
  30.214 -        if (((mach64.crtc_gen_cntl >> 24) & 3) == 3)
  30.215 +        mach64_t *mach64 = (mach64_t *)svga->p;
  30.216 +        
  30.217 +        if (((mach64->crtc_gen_cntl >> 24) & 3) == 3)
  30.218          {
  30.219 -                svga_vtotal = (mach64.crtc_v_total_disp & 2047) + 1;
  30.220 -                svga_dispend = ((mach64.crtc_v_total_disp >> 16) & 2047) + 1;
  30.221 -                svga_htotal = (mach64.crtc_h_total_disp & 255) + 1;
  30.222 -                svga_hdisp_time = svga_hdisp = ((mach64.crtc_h_total_disp >> 16) & 255) + 1;
  30.223 -                svga_vsyncstart = (mach64.crtc_v_sync_strt_wid & 2047) + 1;
  30.224 -                svga_rowoffset = (mach64.crtc_off_pitch >> 22);
  30.225 -                svga_clock = cpuclock / ics2595_output_clock;
  30.226 -                svga_ma = (mach64.crtc_off_pitch & 0x1fffff) * 2;
  30.227 -                svga_linedbl = svga_rowcount = 0;
  30.228 +                svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1;
  30.229 +                svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1;
  30.230 +                svga->htotal = (mach64->crtc_h_total_disp & 255) + 1;
  30.231 +                svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1;
  30.232 +                svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1;
  30.233 +                svga->rowoffset = (mach64->crtc_off_pitch >> 22);
  30.234 +                svga->clock = cpuclock / mach64->ics2595.output_clock;
  30.235 +                svga->ma = (mach64->crtc_off_pitch & 0x1fffff) * 2;
  30.236 +                svga->linedbl = svga->rowcount = 0;
  30.237  //                svga_htotal <<= 1;
  30.238  //                svga_hdisp <<= 1;
  30.239 -                svga_rowoffset <<= 1;
  30.240 -                switch ((mach64.crtc_gen_cntl >> 8) & 7)
  30.241 +                svga->rowoffset <<= 1;                
  30.242 +                switch ((mach64->crtc_gen_cntl >> 8) & 7)
  30.243                  {
  30.244                          case 1: 
  30.245 -                        svga_render = svga_render_4bpp_highres; 
  30.246 -                        svga_hdisp *= 8;
  30.247 +                        svga->render = svga_render_4bpp_highres; 
  30.248 +                        svga->hdisp *= 8;
  30.249                          break;
  30.250                          case 2: 
  30.251 -                        svga_render = svga_render_8bpp_highres; 
  30.252 -                        svga_hdisp *= 8;
  30.253 -                        svga_rowoffset /= 2;
  30.254 +                        svga->render = svga_render_8bpp_highres; 
  30.255 +                        svga->hdisp *= 8;
  30.256 +                        svga->rowoffset /= 2;
  30.257                          break;
  30.258                          case 3: 
  30.259 -                        svga_render = svga_render_15bpp_highres; 
  30.260 -                        svga_hdisp *= 8;
  30.261 +                        svga->render = svga_render_15bpp_highres; 
  30.262 +                        svga->hdisp *= 8;
  30.263                          //svga_rowoffset *= 2;
  30.264                          break;
  30.265                          case 4: 
  30.266 -                        svga_render = svga_render_16bpp_highres; 
  30.267 -                        svga_hdisp *= 8;
  30.268 +                        svga->render = svga_render_16bpp_highres; 
  30.269 +                        svga->hdisp *= 8;
  30.270                          //svga_rowoffset *= 2;
  30.271                          break;
  30.272                          case 5: 
  30.273 -                        svga_render = svga_render_24bpp_highres; 
  30.274 -                        svga_hdisp *= 8;
  30.275 -                        svga_rowoffset = (svga_rowoffset * 3) / 2;
  30.276 +                        svga->render = svga_render_24bpp_highres; 
  30.277 +                        svga->hdisp *= 8;
  30.278 +                        svga->rowoffset = (svga->rowoffset * 3) / 2;
  30.279                          break;
  30.280                          case 6: 
  30.281 -                        svga_render = svga_render_32bpp_highres; 
  30.282 -                        svga_hdisp *= 8;
  30.283 +                        svga->render = svga_render_32bpp_highres; 
  30.284 +                        svga->hdisp *= 8;
  30.285                          break;
  30.286                  }
  30.287                  
  30.288 -                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);
  30.289 +  //              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);
  30.290          }
  30.291  }
  30.292  
  30.293 @@ -314,171 +337,172 @@
  30.294                                          case 3: var = (var & 0x00ffffff) | ((val) << 24); break;  \
  30.295                                  }
  30.296  
  30.297 -void mach64_cursor_dump()
  30.298 +void mach64_cursor_dump(mach64_t *mach64)
  30.299  {
  30.300 +        svga_t *svga = &mach64->svga;
  30.301          pclog("Mach64 cursor :\n");
  30.302 -        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);
  30.303 +        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);
  30.304  }
  30.305  
  30.306 -void mach64_start_fill()
  30.307 +void mach64_start_fill(mach64_t *mach64)
  30.308  {
  30.309          int x, y;
  30.310          
  30.311 -        mach64.accel.dst_x = (mach64.dst_y_x >> 16) & 0xfff;
  30.312 -        mach64.accel.dst_y =  mach64.dst_y_x        & 0xfff;
  30.313 +        mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff;
  30.314 +        mach64->accel.dst_y =  mach64->dst_y_x        & 0xfff;
  30.315  
  30.316 -        mach64.accel.dst_width  = (mach64.dst_height_width >> 16) & 0x1fff;
  30.317 -        mach64.accel.dst_height =  mach64.dst_height_width        & 0x1fff;        
  30.318 -        mach64.accel.x_count = mach64.accel.dst_width;
  30.319 +        mach64->accel.dst_width  = (mach64->dst_height_width >> 16) & 0x1fff;
  30.320 +        mach64->accel.dst_height =  mach64->dst_height_width        & 0x1fff;        
  30.321 +        mach64->accel.x_count = mach64->accel.dst_width;
  30.322          
  30.323 -        mach64.accel.src_x = (mach64.src_y_x >> 16) & 0xfff;
  30.324 -        mach64.accel.src_y =  mach64.src_y_x        & 0xfff;
  30.325 +        mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff;
  30.326 +        mach64->accel.src_y =  mach64->src_y_x        & 0xfff;
  30.327  
  30.328 -        mach64.accel.src_pitch  = (mach64.src_off_pitch >> 22) * 8;
  30.329 -        mach64.accel.src_offset = (mach64.src_off_pitch & 0xfffff) * 8;
  30.330 +        mach64->accel.src_pitch  = (mach64->src_off_pitch >> 22) * 8;
  30.331 +        mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8;
  30.332  
  30.333 -        mach64.accel.dst_pitch  = (mach64.dst_off_pitch >> 22) * 8;
  30.334 -        mach64.accel.dst_offset = (mach64.dst_off_pitch & 0xfffff) * 8;
  30.335 +        mach64->accel.dst_pitch  = (mach64->dst_off_pitch >> 22) * 8;
  30.336 +        mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8;
  30.337          
  30.338 -        mach64.accel.mix_fg = (mach64.dp_mix >> 16) & 0x1f;
  30.339 -        mach64.accel.mix_bg = mach64.dp_mix & 0x1f;
  30.340 +        mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f;
  30.341 +        mach64->accel.mix_bg = mach64->dp_mix & 0x1f;
  30.342          
  30.343 -        mach64.accel.source_bg  =  mach64.dp_src & 7;
  30.344 -        mach64.accel.source_fg  = (mach64.dp_src >> 8) & 7;
  30.345 -        mach64.accel.source_mix = (mach64.dp_src >> 16) & 7;
  30.346 +        mach64->accel.source_bg  =  mach64->dp_src & 7;
  30.347 +        mach64->accel.source_fg  = (mach64->dp_src >> 8) & 7;
  30.348 +        mach64->accel.source_mix = (mach64->dp_src >> 16) & 7;
  30.349          
  30.350 -        mach64.accel.dst_pix_width  =  mach64.dp_pix_width        & 7;
  30.351 -        mach64.accel.src_pix_width  = (mach64.dp_pix_width >>  8) & 7;
  30.352 -        mach64.accel.host_pix_width = (mach64.dp_pix_width >> 16) & 7;
  30.353 +        mach64->accel.dst_pix_width  =  mach64->dp_pix_width        & 7;
  30.354 +        mach64->accel.src_pix_width  = (mach64->dp_pix_width >>  8) & 7;
  30.355 +        mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7;
  30.356          
  30.357 -        mach64.accel.dst_size = mach64_width[mach64.accel.dst_pix_width];
  30.358 -        mach64.accel.src_size = mach64_width[mach64.accel.src_pix_width];
  30.359 +        mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width];
  30.360 +        mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width];
  30.361  
  30.362 -/*        mach64.accel.src_x     *= mach64_inc[mach64.accel.src_pix_width];
  30.363 -        mach64.accel.src_pitch *= mach64_inc[mach64.accel.src_pix_width];
  30.364 -        mach64.accel.dst_x     *= mach64_inc[mach64.accel.dst_pix_width];
  30.365 -        mach64.accel.dst_pitch *= mach64_inc[mach64.accel.dst_pix_width];*/
  30.366 +/*        mach64->accel.src_x     *= mach64_inc[mach64->accel.src_pix_width];
  30.367 +        mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width];
  30.368 +        mach64->accel.dst_x     *= mach64_inc[mach64->accel.dst_pix_width];
  30.369 +        mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/
  30.370          
  30.371 -        mach64.accel.src_offset >>= mach64.accel.src_size;
  30.372 -        mach64.accel.dst_offset >>= mach64.accel.dst_size;
  30.373 +        mach64->accel.src_offset >>= mach64->accel.src_size;
  30.374 +        mach64->accel.dst_offset >>= mach64->accel.dst_size;
  30.375  
  30.376 -        mach64.accel.src_x_start = mach64.accel.src_x;
  30.377 -        mach64.accel.dst_x_start = mach64.accel.dst_x;
  30.378 +        mach64->accel.src_x_start = mach64->accel.src_x;
  30.379 +        mach64->accel.dst_x_start = mach64->accel.dst_x;
  30.380                  
  30.381 -/*        if (mach64.accel.source_fg == SRC_BLITSRC || mach64.accel.source_bg == SRC_BLITSRC)
  30.382 +/*        if (mach64->accel.source_fg == SRC_BLITSRC || mach64->accel.source_bg == SRC_BLITSRC)
  30.383          {*/
  30.384 -                mach64.accel.xinc = (mach64.dst_cntl & 1) ? 1 : -1;
  30.385 -                mach64.accel.yinc = (mach64.dst_cntl & 2) ? 1 : -1;        
  30.386 +                mach64->accel.xinc = (mach64->dst_cntl & 1) ? 1 : -1;
  30.387 +                mach64->accel.yinc = (mach64->dst_cntl & 2) ? 1 : -1;        
  30.388  /*        }
  30.389          else
  30.390          {
  30.391 -                mach64.accel.xinc = mach64_inc[mach64.accel.src_pix_width];
  30.392 -                mach64.accel.yinc = 1;
  30.393 +                mach64->accel.xinc = mach64_inc[mach64->accel.src_pix_width];
  30.394 +                mach64->accel.yinc = 1;
  30.395          }*/
  30.396          
  30.397 -        mach64.accel.source_host = ((mach64.dp_src & 7) == SRC_HOST) || (((mach64.dp_src >> 8) & 7) == SRC_HOST);
  30.398 +        mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST);
  30.399          
  30.400          
  30.401 -//        pclog("mach64_start_fill : pattern %08X %08X\n", mach64.pat_reg0, mach64.pat_reg1);
  30.402 +//        pclog("mach64_start_fill : pattern %08X %08X\n", mach64->pat_reg0, mach64->pat_reg1);
  30.403          for (y = 0; y < 8; y++)
  30.404          {
  30.405                  for (x = 0; x < 8; x++)
  30.406                  {
  30.407 -                        uint32_t temp = (y & 4) ? mach64.pat_reg1 : mach64.pat_reg0;
  30.408 -                        mach64.accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1;
  30.409 -//                        pclog("%i ", mach64.accel.pattern[y][x]);                        
  30.410 +                        uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0;
  30.411 +                        mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1;
  30.412 +//                        pclog("%i ", mach64->accel.pattern[y][x]);                        
  30.413                  }
  30.414  //                pclog("\n");
  30.415          }
  30.416          
  30.417 -        mach64.accel.sc_left   =  mach64.sc_left_right & 0x1fff;
  30.418 -        mach64.accel.sc_right  = (mach64.sc_left_right >> 16) & 0x1fff;
  30.419 -        mach64.accel.sc_top    =  mach64.sc_top_bottom & 0x7fff;
  30.420 -        mach64.accel.sc_bottom = (mach64.sc_top_bottom >> 16) & 0x7fff;
  30.421 +        mach64->accel.sc_left   =  mach64->sc_left_right & 0x1fff;
  30.422 +        mach64->accel.sc_right  = (mach64->sc_left_right >> 16) & 0x1fff;
  30.423 +        mach64->accel.sc_top    =  mach64->sc_top_bottom & 0x7fff;
  30.424 +        mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff;
  30.425  
  30.426 -/*        mach64.accel.sc_left   *= mach64_inc[mach64.accel.dst_pix_width];
  30.427 -        mach64.accel.sc_right  *= mach64_inc[mach64.accel.dst_pix_width];*/
  30.428 +/*        mach64->accel.sc_left   *= mach64_inc[mach64->accel.dst_pix_width];
  30.429 +        mach64->accel.sc_right  *= mach64_inc[mach64->accel.dst_pix_width];*/
  30.430          
  30.431 -        mach64.accel.dp_frgd_clr = mach64.dp_frgd_clr;
  30.432 -        mach64.accel.dp_bkgd_clr = mach64.dp_bkgd_clr;        
  30.433 +        mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr;
  30.434 +        mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr;        
  30.435          
  30.436 -        mach64.accel.busy = 1;
  30.437 +        mach64->accel.busy = 1;
  30.438  #ifdef MACH64_DEBUG
  30.439 -        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);
  30.440 +        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);
  30.441  #endif
  30.442 -        mach64.accel.op = OP_RECT;
  30.443 +        mach64->accel.op = OP_RECT;
  30.444  }
  30.445  
  30.446 -void mach64_start_line()
  30.447 +void mach64_start_line(mach64_t *mach64)
  30.448  {
  30.449          int x, y;
  30.450          
  30.451 -        mach64.accel.dst_x = (mach64.dst_y_x >> 16) & 0xfff;
  30.452 -        mach64.accel.dst_y =  mach64.dst_y_x        & 0xfff;
  30.453 +        mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff;
  30.454 +        mach64->accel.dst_y =  mach64->dst_y_x        & 0xfff;
  30.455  
  30.456 -        mach64.accel.src_x = (mach64.src_y_x >> 16) & 0xfff;
  30.457 -        mach64.accel.src_y =  mach64.src_y_x        & 0xfff;
  30.458 +        mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff;
  30.459 +        mach64->accel.src_y =  mach64->src_y_x        & 0xfff;
  30.460  
  30.461 -        mach64.accel.src_pitch  = (mach64.src_off_pitch >> 22) * 8;
  30.462 -        mach64.accel.src_offset = (mach64.src_off_pitch & 0xfffff) * 8;
  30.463 +        mach64->accel.src_pitch  = (mach64->src_off_pitch >> 22) * 8;
  30.464 +        mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8;
  30.465  
  30.466 -        mach64.accel.dst_pitch  = (mach64.dst_off_pitch >> 22) * 8;
  30.467 -        mach64.accel.dst_offset = (mach64.dst_off_pitch & 0xfffff) * 8;
  30.468 +        mach64->accel.dst_pitch  = (mach64->dst_off_pitch >> 22) * 8;
  30.469 +        mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8;
  30.470          
  30.471 -        mach64.accel.mix_fg = (mach64.dp_mix >> 16) & 0x1f;
  30.472 -        mach64.accel.mix_bg = mach64.dp_mix & 0x1f;
  30.473 +        mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f;
  30.474 +        mach64->accel.mix_bg = mach64->dp_mix & 0x1f;
  30.475          
  30.476 -        mach64.accel.source_bg  =  mach64.dp_src & 7;
  30.477 -        mach64.accel.source_fg  = (mach64.dp_src >> 8) & 7;
  30.478 -        mach64.accel.source_mix = (mach64.dp_src >> 16) & 7;
  30.479 +        mach64->accel.source_bg  =  mach64->dp_src & 7;
  30.480 +        mach64->accel.source_fg  = (mach64->dp_src >> 8) & 7;
  30.481 +        mach64->accel.source_mix = (mach64->dp_src >> 16) & 7;
  30.482          
  30.483 -        mach64.accel.dst_pix_width  =  mach64.dp_pix_width        & 7;
  30.484 -        mach64.accel.src_pix_width  = (mach64.dp_pix_width >>  8) & 7;
  30.485 -        mach64.accel.host_pix_width = (mach64.dp_pix_width >> 16) & 7;
  30.486 +        mach64->accel.dst_pix_width  =  mach64->dp_pix_width        & 7;
  30.487 +        mach64->accel.src_pix_width  = (mach64->dp_pix_width >>  8) & 7;
  30.488 +        mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7;
  30.489          
  30.490 -        mach64.accel.dst_size = mach64_width[mach64.accel.dst_pix_width];
  30.491 -        mach64.accel.src_size = mach64_width[mach64.accel.src_pix_width];
  30.492 +        mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width];
  30.493 +        mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width];
  30.494  
  30.495 -        mach64.accel.src_offset >>= mach64.accel.src_size;
  30.496 -        mach64.accel.dst_offset >>= mach64.accel.dst_size;
  30.497 +        mach64->accel.src_offset >>= mach64->accel.src_size;
  30.498 +        mach64->accel.dst_offset >>= mach64->accel.dst_size;
  30.499  
  30.500 -/*        mach64.accel.src_pitch *= mach64_inc[mach64.accel.src_pix_width];
  30.501 -        mach64.accel.dst_pitch *= mach64_inc[mach64.accel.dst_pix_width];*/
  30.502 +/*        mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width];
  30.503 +        mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/
  30.504        
  30.505 -        mach64.accel.source_host = ((mach64.dp_src & 7) == SRC_HOST) || (((mach64.dp_src >> 8) & 7) == SRC_HOST);
  30.506 +        mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST);
  30.507          
  30.508          for (y = 0; y < 8; y++)
  30.509          {
  30.510                  for (x = 0; x < 8; x++)
  30.511                  {
  30.512 -                        uint32_t temp = (y & 4) ? mach64.pat_reg1 : mach64.pat_reg0;
  30.513 -                        mach64.accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1;
  30.514 +                        uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0;
  30.515 +                        mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1;
  30.516                  }
  30.517          }
  30.518          
  30.519 -        mach64.accel.sc_left   =  mach64.sc_left_right & 0x1fff;
  30.520 -        mach64.accel.sc_right  = (mach64.sc_left_right >> 16) & 0x1fff;
  30.521 -        mach64.accel.sc_top    =  mach64.sc_top_bottom & 0x7fff;
  30.522 -        mach64.accel.sc_bottom = (mach64.sc_top_bottom >> 16) & 0x7fff;
  30.523 +        mach64->accel.sc_left   =  mach64->sc_left_right & 0x1fff;
  30.524 +        mach64->accel.sc_right  = (mach64->sc_left_right >> 16) & 0x1fff;
  30.525 +        mach64->accel.sc_top    =  mach64->sc_top_bottom & 0x7fff;
  30.526 +        mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff;
  30.527          
  30.528 -        mach64.accel.dp_frgd_clr = mach64.dp_frgd_clr;
  30.529 -        mach64.accel.dp_bkgd_clr = mach64.dp_bkgd_clr;        
  30.530 +        mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr;
  30.531 +        mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr;        
  30.532          
  30.533 -        mach64.accel.x_count = mach64.dst_bres_lnth & 0x7fff;
  30.534 -        mach64.accel.err = (mach64.dst_bres_err & 0x3ffff) | ((mach64.dst_bres_err & 0x40000) ? 0xfffc0000 : 0);
  30.535 +        mach64->accel.x_count = mach64->dst_bres_lnth & 0x7fff;
  30.536 +        mach64->accel.err = (mach64->dst_bres_err & 0x3ffff) | ((mach64->dst_bres_err & 0x40000) ? 0xfffc0000 : 0);
  30.537          
  30.538 -        mach64.accel.busy = 1;
  30.539 +        mach64->accel.busy = 1;
  30.540  #ifdef MACH64_DEBUG
  30.541          pclog("mach64_start_line\n");
  30.542  #endif
  30.543 -        mach64.accel.op = OP_LINE;
  30.544 +        mach64->accel.op = OP_LINE;
  30.545  }
  30.546  
  30.547 -#define READ(addr, dat, width) if (width == 0)      dat =               vram[((addr))      & 0x7fffff]; \
  30.548 -                               else if (width == 1) dat = *(uint16_t *)&vram[((addr) << 1) & 0x7fffff]; \
  30.549 -                               else                 dat = *(uint32_t *)&vram[((addr) << 2) & 0x7fffff];
  30.550 +#define READ(addr, dat, width) if (width == 0)      dat =               svga->vram[((addr))      & 0x7fffff]; \
  30.551 +                               else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & 0x7fffff]; \
  30.552 +                               else                 dat = *(uint32_t *)&svga->vram[((addr) << 2) & 0x7fffff];
  30.553  
  30.554 -#define MIX     switch (mix ? mach64.accel.mix_fg : mach64.accel.mix_bg)                                \
  30.555 +#define MIX     switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg)                                \
  30.556                  {                                                                                       \
  30.557                          case 0x0: dest_dat =             ~dest_dat;  break;                             \
  30.558                          case 0x1: dest_dat =  0;                     break;                             \
  30.559 @@ -500,30 +524,32 @@
  30.560  
  30.561  #define WRITE(addr, width)      if (width == 0)                                                         \
  30.562                                  {                                                                       \
  30.563 -                                        vram[(addr) & 0x7fffff] = dest_dat;                             \
  30.564 -                                        changedvram[((addr) & 0x7fffff) >> 10] = changeframecount;      \
  30.565 +                                        svga->vram[(addr) & 0x7fffff] = dest_dat;                             \
  30.566 +                                        svga->changedvram[((addr) & 0x7fffff) >> 10] = changeframecount;      \
  30.567                                  }                                                                       \
  30.568                                  else if (width == 1)                                                    \
  30.569                                  {                                                                       \
  30.570 -                                        *(uint16_t *)&vram[((addr) << 1) & 0x7fffff] = dest_dat;          \
  30.571 -                                        changedvram[(((addr) << 1) & 0x7fffff) >> 10] = changeframecount; \
  30.572 +                                        *(uint16_t *)&svga->vram[((addr) << 1) & 0x7fffff] = dest_dat;          \
  30.573 +                                        svga->changedvram[(((addr) << 1) & 0x7fffff) >> 10] = changeframecount; \
  30.574                                  }                                                                       \
  30.575                                  else                                                                    \
  30.576                                  {                                                                       \
  30.577 -                                        *(uint32_t *)&vram[((addr) << 2) & 0x7fffff] = dest_dat;          \
  30.578 -                                        changedvram[(((addr) << 2) & 0x7fffff) >> 10] = changeframecount; \
  30.579 +                                        *(uint32_t *)&svga->vram[((addr) << 2) & 0x7fffff] = dest_dat;          \
  30.580 +                                        svga->changedvram[(((addr) << 2) & 0x7fffff) >> 10] = changeframecount; \
  30.581                                  }
  30.582  
  30.583 -void mach64_blit(uint32_t cpu_dat, int count)
  30.584 +void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
  30.585  {
  30.586 -        if (!mach64.accel.busy)
  30.587 +        svga_t *svga = &mach64->svga;
  30.588 +        
  30.589 +        if (!mach64->accel.busy)
  30.590          {
  30.591  #ifdef MACH64_DEBUG
  30.592                  pclog("mach64_blit : return as not busy\n");
  30.593  #endif
  30.594                  return;
  30.595          }
  30.596 -        switch (mach64.accel.op)
  30.597 +        switch (mach64->accel.op)
  30.598          {
  30.599                  case OP_RECT:
  30.600                  while (count)
  30.601 @@ -532,10 +558,10 @@
  30.602                          uint32_t host_dat;
  30.603                          int mix;
  30.604                  
  30.605 -                        if (mach64.accel.source_host)
  30.606 +                        if (mach64->accel.source_host)
  30.607                          {
  30.608                                  host_dat = cpu_dat;
  30.609 -                                switch (mach64.accel.src_size)
  30.610 +                                switch (mach64->accel.src_size)
  30.611                                  {
  30.612                                          case 0:
  30.613                                          cpu_dat >>= 8;
  30.614 @@ -553,14 +579,14 @@
  30.615                          else
  30.616                             count--;
  30.617  
  30.618 -                        switch (mach64.accel.source_mix)
  30.619 +                        switch (mach64->accel.source_mix)
  30.620                          {
  30.621                                  case MONO_SRC_HOST:
  30.622                                  mix = cpu_dat >> 31;
  30.623                                  cpu_dat <<= 1;
  30.624                                  break;
  30.625                                  case MONO_SRC_PAT:
  30.626 -                                mix = mach64.accel.pattern[mach64.accel.dst_y & 7][mach64.accel.dst_x & 7];
  30.627 +                                mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7];
  30.628                                  break;
  30.629                                  case MONO_SRC_1:
  30.630                                  default:
  30.631 @@ -568,69 +594,69 @@
  30.632                                  break;
  30.633                          }
  30.634                  
  30.635 -                        if (mach64.accel.dst_x >= mach64.accel.sc_left && mach64.accel.dst_x <= mach64.accel.sc_right &&
  30.636 -                            mach64.accel.dst_y >= mach64.accel.sc_top  && mach64.accel.dst_y <= mach64.accel.sc_bottom)
  30.637 +                        if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right &&
  30.638 +                            mach64->accel.dst_y >= mach64->accel.sc_top  && mach64->accel.dst_y <= mach64->accel.sc_bottom)
  30.639                          {
  30.640 -                                switch (mix ? mach64.accel.source_fg : mach64.accel.source_bg)
  30.641 +                                switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg)
  30.642                                  {
  30.643                                          case SRC_HOST:
  30.644                                          src_dat = host_dat;
  30.645                                          break;
  30.646                                          case SRC_BLITSRC:
  30.647 -                                        READ(mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x, src_dat, mach64.accel.src_size);
  30.648 +                                        READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size);
  30.649                                          break;
  30.650                                          case SRC_FG:
  30.651 -                                        src_dat = mach64.accel.dp_frgd_clr;
  30.652 +                                        src_dat = mach64->accel.dp_frgd_clr;
  30.653                                          break;
  30.654                                          case SRC_BG:
  30.655 -                                        src_dat = mach64.accel.dp_bkgd_clr;
  30.656 +                                        src_dat = mach64->accel.dp_bkgd_clr;
  30.657                                          break;
  30.658                                          default:
  30.659                                          src_dat = 0;
  30.660                                          break;
  30.661                                  }
  30.662                  
  30.663 -                                READ(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, dest_dat, mach64.accel.dst_size);
  30.664 +                                READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size);
  30.665  
  30.666 -//                                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);
  30.667 +//                                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);
  30.668                                  
  30.669                                  MIX
  30.670  
  30.671 -//                                pclog("%02X  %i\n", dest_dat, mach64.accel.dst_height);
  30.672 +//                                pclog("%02X  %i\n", dest_dat, mach64->accel.dst_height);
  30.673  
  30.674 -                                WRITE(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, mach64.accel.dst_size);
  30.675 +                                WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size);
  30.676                          }
  30.677                  
  30.678 -                        if (mach64.dst_cntl & DST_24_ROT_EN)
  30.679 +                        if (mach64->dst_cntl & DST_24_ROT_EN)
  30.680                          {
  30.681 -                                mach64.accel.dp_frgd_clr = ((mach64.accel.dp_frgd_clr >> 8) & 0xffff) | (mach64.accel.dp_frgd_clr << 16);
  30.682 -                                mach64.accel.dp_bkgd_clr = ((mach64.accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64.accel.dp_bkgd_clr << 16);
  30.683 +                                mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16);
  30.684 +                                mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16);
  30.685                          }
  30.686                  
  30.687 -                        mach64.accel.src_x += mach64.accel.xinc;
  30.688 -                        mach64.accel.dst_x += mach64.accel.xinc;
  30.689 -                        mach64.accel.x_count--;
  30.690 +                        mach64->accel.src_x += mach64->accel.xinc;
  30.691 +                        mach64->accel.dst_x += mach64->accel.xinc;
  30.692 +                        mach64->accel.x_count--;
  30.693                          
  30.694 -                        if (mach64.accel.x_count <= 0)
  30.695 +                        if (mach64->accel.x_count <= 0)
  30.696                          {
  30.697 -                                mach64.accel.x_count = mach64.accel.dst_width;
  30.698 -                                mach64.accel.src_x = mach64.accel.src_x_start;
  30.699 -                                mach64.accel.dst_x = mach64.accel.dst_x_start;
  30.700 +                                mach64->accel.x_count = mach64->accel.dst_width;
  30.701 +                                mach64->accel.src_x = mach64->accel.src_x_start;
  30.702 +                                mach64->accel.dst_x = mach64->accel.dst_x_start;
  30.703  
  30.704 -                                mach64.accel.src_y += mach64.accel.yinc;                        
  30.705 -                                mach64.accel.dst_y += mach64.accel.yinc;
  30.706 -                                mach64.accel.dst_height--;
  30.707 +                                mach64->accel.src_y += mach64->accel.yinc;                        
  30.708 +                                mach64->accel.dst_y += mach64->accel.yinc;
  30.709 +                                mach64->accel.dst_height--;
  30.710                  
  30.711 -                                if (mach64.accel.dst_height <= 0)
  30.712 +                                if (mach64->accel.dst_height <= 0)
  30.713                                  {
  30.714                                          /*Blit finished*/
  30.715  #ifdef MACH64_DEBUG
  30.716                                          pclog("mach64 blit finished\n");
  30.717  #endif
  30.718 -                                        mach64.accel.busy = 0;
  30.719 +                                        mach64->accel.busy = 0;
  30.720                                          return;
  30.721                                  }
  30.722 -                                if (mach64.accel.source_host)
  30.723 +                                if (mach64->accel.source_host)
  30.724                                          return;
  30.725                          }
  30.726                  }        
  30.727 @@ -643,10 +669,10 @@
  30.728                          uint32_t host_dat;
  30.729                          int mix;
  30.730                  
  30.731 -                        if (mach64.accel.source_host)
  30.732 +                        if (mach64->accel.source_host)
  30.733                          {
  30.734                                  host_dat = cpu_dat;
  30.735 -                                switch (mach64.accel.src_size)
  30.736 +                                switch (mach64->accel.src_size)
  30.737                                  {
  30.738                                          case 0:
  30.739                                          cpu_dat >>= 8;
  30.740 @@ -664,14 +690,14 @@
  30.741                          else
  30.742                             count--;
  30.743  
  30.744 -                        switch (mach64.accel.source_mix)
  30.745 +                        switch (mach64->accel.source_mix)
  30.746                          {
  30.747                                  case MONO_SRC_HOST:
  30.748                                  mix = cpu_dat >> 31;
  30.749                                  cpu_dat <<= 1;
  30.750                                  break;
  30.751                                  case MONO_SRC_PAT:
  30.752 -                                mix = mach64.accel.pattern[mach64.accel.dst_y & 7][mach64.accel.dst_x & 7];
  30.753 +                                mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7];
  30.754                                  break;
  30.755                                  case MONO_SRC_1:
  30.756                                  default:
  30.757 @@ -679,232 +705,244 @@
  30.758                                  break;
  30.759                          }
  30.760                  
  30.761 -                        if (mach64.accel.dst_x >= mach64.accel.sc_left && mach64.accel.dst_x <= mach64.accel.sc_right &&
  30.762 -                            mach64.accel.dst_y >= mach64.accel.sc_top  && mach64.accel.dst_y <= mach64.accel.sc_bottom)
  30.763 +                        if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right &&
  30.764 +                            mach64->accel.dst_y >= mach64->accel.sc_top  && mach64->accel.dst_y <= mach64->accel.sc_bottom)
  30.765                          {
  30.766 -                                switch (mix ? mach64.accel.source_fg : mach64.accel.source_bg)
  30.767 +                                switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg)
  30.768                                  {
  30.769                                          case SRC_HOST:
  30.770                                          src_dat = host_dat;
  30.771                                          break;
  30.772                                          case SRC_BLITSRC:
  30.773 -                                        READ(mach64.accel.src_offset + (mach64.accel.src_y * mach64.accel.src_pitch) + mach64.accel.src_x, src_dat, mach64.accel.src_size);
  30.774 +                                        READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size);
  30.775                                          break;
  30.776                                          case SRC_FG:
  30.777 -                                        src_dat = mach64.accel.dp_frgd_clr;
  30.778 +                                        src_dat = mach64->accel.dp_frgd_clr;
  30.779                                          break;
  30.780                                          case SRC_BG:
  30.781 -                                        src_dat = mach64.accel.dp_bkgd_clr;
  30.782 +                                        src_dat = mach64->accel.dp_bkgd_clr;
  30.783                                          break;
  30.784                                          default:
  30.785                                          src_dat = 0;
  30.786                                          break;
  30.787                                  }
  30.788                  
  30.789 -                                READ(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, dest_dat, mach64.accel.dst_size);
  30.790 +                                READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size);
  30.791  
  30.792 -//                                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);
  30.793 +//                                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);
  30.794                                  
  30.795                                  MIX
  30.796  
  30.797 -//                                pclog("%02X  %i\n", dest_dat, mach64.accel.dst_height);
  30.798 +//                                pclog("%02X  %i\n", dest_dat, mach64->accel.dst_height);
  30.799  
  30.800 -                                WRITE(mach64.accel.dst_offset + (mach64.accel.dst_y * mach64.accel.dst_pitch) + mach64.accel.dst_x, mach64.accel.dst_size);
  30.801 +                                WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size);
  30.802                          }
  30.803                  
  30.804 -                        mach64.accel.x_count--;                
  30.805 -                        if (mach64.accel.x_count <= 0)
  30.806 +                        mach64->accel.x_count--;                
  30.807 +                        if (mach64->accel.x_count <= 0)
  30.808                          {
  30.809                                  /*Blit finished*/
  30.810  #ifdef MACH64_DEBUG
  30.811                                  pclog("mach64 blit finished\n");
  30.812  #endif
  30.813 -                                mach64.accel.busy = 0;
  30.814 +                                mach64->accel.busy = 0;
  30.815                                  return;
  30.816                          }
  30.817                          
  30.818 -                        switch (mach64.dst_cntl & 7)
  30.819 +                        switch (mach64->dst_cntl & 7)
  30.820                          {
  30.821                                  case 0: case 2: 
  30.822 -                                mach64.accel.src_x--;
  30.823 -                                mach64.accel.dst_x--;
  30.824 +                                mach64->accel.src_x--;
  30.825 +                                mach64->accel.dst_x--;
  30.826                                  break;
  30.827                                  case 1: case 3:
  30.828 -                                mach64.accel.src_x++;
  30.829 -                                mach64.accel.dst_x++;
  30.830 +                                mach64->accel.src_x++;
  30.831 +                                mach64->accel.dst_x++;
  30.832                                  break;
  30.833                                  case 4: case 5: 
  30.834 -                                mach64.accel.src_y--;
  30.835 -                                mach64.accel.dst_y--;
  30.836 +                                mach64->accel.src_y--;
  30.837 +                                mach64->accel.dst_y--;
  30.838                                  break;
  30.839                                  case 6: case 7:
  30.840 -                                mach64.accel.src_y++;
  30.841 -                                mach64.accel.dst_y++;
  30.842 +                                mach64->accel.src_y++;
  30.843 +                                mach64->accel.dst_y++;
  30.844                                  break;
  30.845                          }
  30.846  #ifdef MACH64_DEBUG
  30.847 -                        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);
  30.848 +                        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);
  30.849  #endif
  30.850 -                        if (mach64.accel.err >= 0)
  30.851 +                        if (mach64->accel.err >= 0)
  30.852                          {
  30.853 -                                mach64.accel.err += mach64.dst_bres_dec;
  30.854 +                                mach64->accel.err += mach64->dst_bres_dec;
  30.855                                  
  30.856 -                                switch (mach64.dst_cntl & 7)
  30.857 +                                switch (mach64->dst_cntl & 7)
  30.858                                  {
  30.859                                          case 0: case 1: 
  30.860 -                                        mach64.accel.src_y--;
  30.861 -                                        mach64.accel.dst_y--;
  30.862 +                                        mach64->accel.src_y--;
  30.863 +                                        mach64->accel.dst_y--;
  30.864                                          break;
  30.865                                          case 2: case 3:
  30.866 -                                        mach64.accel.src_y++;
  30.867 -                                        mach64.accel.dst_y++;
  30.868 +                                        mach64->accel.src_y++;
  30.869 +                                        mach64->accel.dst_y++;
  30.870                                          break;
  30.871                                          case 4: case 6: 
  30.872 -                                        mach64.accel.src_x--;
  30.873 -                                        mach64.accel.dst_x--;
  30.874 +                                        mach64->accel.src_x--;
  30.875 +                                        mach64->accel.dst_x--;
  30.876                                          break;
  30.877                                          case 5: case 7:
  30.878 -                                        mach64.accel.src_x++;
  30.879 -                                        mach64.accel.dst_x++;
  30.880 +                                        mach64->accel.src_x++;
  30.881 +                                        mach64->accel.dst_x++;
  30.882                                          break;
  30.883                                  }
  30.884                          }
  30.885                          else
  30.886 -                                mach64.accel.err += mach64.dst_bres_inc;
  30.887 +                                mach64->accel.err += mach64->dst_bres_inc;
  30.888                  }
  30.889                  break;
  30.890          }
  30.891  }
  30.892  
  30.893 -void mach64_load_context()
  30.894 +void mach64_load_context(mach64_t *mach64)
  30.895  {
  30.896 +        svga_t *svga = &mach64->svga;
  30.897          uint32_t addr;
  30.898          
  30.899 -        while (mach64.context_load_cntl & 0x30000)
  30.900 +        while (mach64->context_load_cntl & 0x30000)
  30.901          {
  30.902 -                addr = (0x3fff - (mach64.context_load_cntl & 0x3fff)) * 256;
  30.903 -                mach64.context_mask = *(uint32_t *)&vram[addr];
  30.904 +                addr = (0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256;
  30.905 +                mach64->context_mask = *(uint32_t *)&svga->vram[addr];
  30.906  #ifdef MACH64_DEBUG
  30.907 -                pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64.context_load_cntl, addr, mach64.context_mask);
  30.908 +                pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask);
  30.909  #endif
  30.910   
  30.911 -                if (mach64.context_mask & (1 << 2))
  30.912 -                        mach64_ext_writel(0x100, *(uint32_t *)&vram[addr + 0x08], NULL);
  30.913 -                if (mach64.context_mask & (1 << 3))
  30.914 -                        mach64_ext_writel(0x10c, *(uint32_t *)&vram[addr + 0x0c], NULL);
  30.915 -                if (mach64.context_mask & (1 << 4))
  30.916 -                        mach64_ext_writel(0x118, *(uint32_t *)&vram[addr + 0x10], NULL);
  30.917 -                if (mach64.context_mask & (1 << 5))
  30.918 -                        mach64_ext_writel(0x124, *(uint32_t *)&vram[addr + 0x14], NULL);
  30.919 -                if (mach64.context_mask & (1 << 6))
  30.920 -                        mach64_ext_writel(0x128, *(uint32_t *)&vram[addr + 0x18], NULL);
  30.921 -                if (mach64.context_mask & (1 << 7))
  30.922 -                        mach64_ext_writel(0x12c, *(uint32_t *)&vram[addr + 0x1c], NULL);
  30.923 -                if (mach64.context_mask & (1 << 8))
  30.924 -                        mach64_ext_writel(0x180, *(uint32_t *)&vram[addr + 0x20], NULL);
  30.925 -                if (mach64.context_mask & (1 << 9))
  30.926 -                        mach64_ext_writel(0x18c, *(uint32_t *)&vram[addr + 0x24], NULL);
  30.927 -                if (mach64.context_mask & (1 << 10))
  30.928 -                        mach64_ext_writel(0x198, *(uint32_t *)&vram[addr + 0x28], NULL);
  30.929 -                if (mach64.context_mask & (1 << 11))
  30.930 -                        mach64_ext_writel(0x1a4, *(uint32_t *)&vram[addr + 0x2c], NULL);
  30.931 -                if (mach64.context_mask & (1 << 12))
  30.932 -                        mach64_ext_writel(0x1b0, *(uint32_t *)&vram[addr + 0x30], NULL);
  30.933 -                if (mach64.context_mask & (1 << 13))
  30.934 -                        mach64_ext_writel(0x280, *(uint32_t *)&vram[addr + 0x34], NULL);
  30.935 -                if (mach64.context_mask & (1 << 14))
  30.936 -                        mach64_ext_writel(0x284, *(uint32_t *)&vram[addr + 0x38], NULL);
  30.937 -                if (mach64.context_mask & (1 << 15))
  30.938 -                        mach64_ext_writel(0x2a8, *(uint32_t *)&vram[addr + 0x3c], NULL);
  30.939 -                if (mach64.context_mask & (1 << 16))
  30.940 -                        mach64_ext_writel(0x2b4, *(uint32_t *)&vram[addr + 0x40], NULL);
  30.941 -                if (mach64.context_mask & (1 << 17))
  30.942 -                        mach64_ext_writel(0x2c0, *(uint32_t *)&vram[addr + 0x44], NULL);
  30.943 -                if (mach64.context_mask & (1 << 18))
  30.944 -                        mach64_ext_writel(0x2c4, *(uint32_t *)&vram[addr + 0x48], NULL);
  30.945 -                if (mach64.context_mask & (1 << 19))
  30.946 -                        mach64_ext_writel(0x2c8, *(uint32_t *)&vram[addr + 0x4c], NULL);
  30.947 -                if (mach64.context_mask & (1 << 20))
  30.948 -                        mach64_ext_writel(0x2cc, *(uint32_t *)&vram[addr + 0x50], NULL);
  30.949 -                if (mach64.context_mask & (1 << 21))
  30.950 -                        mach64_ext_writel(0x2d0, *(uint32_t *)&vram[addr + 0x54], NULL);
  30.951 -                if (mach64.context_mask & (1 << 22))
  30.952 -                        mach64_ext_writel(0x2d4, *(uint32_t *)&vram[addr + 0x58], NULL);
  30.953 -                if (mach64.context_mask & (1 << 23))
  30.954 -                        mach64_ext_writel(0x2d8, *(uint32_t *)&vram[addr + 0x5c], NULL);
  30.955 -                if (mach64.context_mask & (1 << 24))
  30.956 -                        mach64_ext_writel(0x300, *(uint32_t *)&vram[addr + 0x60], NULL);
  30.957 -                if (mach64.context_mask & (1 << 25))
  30.958 -                        mach64_ext_writel(0x304, *(uint32_t *)&vram[addr + 0x64], NULL);
  30.959 -                if (mach64.context_mask & (1 << 26))
  30.960 -                        mach64_ext_writel(0x308, *(uint32_t *)&vram[addr + 0x68], NULL);
  30.961 -                if (mach64.context_mask & (1 << 27))
  30.962 -                        mach64_ext_writel(0x330, *(uint32_t *)&vram[addr + 0x6c], NULL);
  30.963 +                if (mach64->context_mask & (1 << 2))
  30.964 +                        mach64_ext_writel(0x100, *(uint32_t *)&svga->vram[addr + 0x08], mach64);
  30.965 +                if (mach64->context_mask & (1 << 3))
  30.966 +                        mach64_ext_writel(0x10c, *(uint32_t *)&svga->vram[addr + 0x0c], mach64);
  30.967 +                if (mach64->context_mask & (1 << 4))
  30.968 +                        mach64_ext_writel(0x118, *(uint32_t *)&svga->vram[addr + 0x10], mach64);
  30.969 +                if (mach64->context_mask & (1 << 5))
  30.970 +                        mach64_ext_writel(0x124, *(uint32_t *)&svga->vram[addr + 0x14], mach64);
  30.971 +                if (mach64->context_mask & (1 << 6))
  30.972 +                        mach64_ext_writel(0x128, *(uint32_t *)&svga->vram[addr + 0x18], mach64);
  30.973 +                if (mach64->context_mask & (1 << 7))
  30.974 +                        mach64_ext_writel(0x12c, *(uint32_t *)&svga->vram[addr + 0x1c], mach64);
  30.975 +                if (mach64->context_mask & (1 << 8))
  30.976 +                        mach64_ext_writel(0x180, *(uint32_t *)&svga->vram[addr + 0x20], mach64);
  30.977 +                if (mach64->context_mask & (1 << 9))
  30.978 +                        mach64_ext_writel(0x18c, *(uint32_t *)&svga->vram[addr + 0x24], mach64);
  30.979 +                if (mach64->context_mask & (1 << 10))
  30.980 +                        mach64_ext_writel(0x198, *(uint32_t *)&svga->vram[addr + 0x28], mach64);
  30.981 +                if (mach64->context_mask & (1 << 11))
  30.982 +                        mach64_ext_writel(0x1a4, *(uint32_t *)&svga->vram[addr + 0x2c], mach64);
  30.983 +                if (mach64->context_mask & (1 << 12))
  30.984 +                        mach64_ext_writel(0x1b0, *(uint32_t *)&svga->vram[addr + 0x30], mach64);
  30.985 +                if (mach64->context_mask & (1 << 13))
  30.986 +                        mach64_ext_writel(0x280, *(uint32_t *)&svga->vram[addr + 0x34], mach64);
  30.987 +                if (mach64->context_mask & (1 << 14))
  30.988 +                        mach64_ext_writel(0x284, *(uint32_t *)&svga->vram[addr + 0x38], mach64);
  30.989 +                if (mach64->context_mask & (1 << 15))
  30.990 +                        mach64_ext_writel(0x2a8, *(uint32_t *)&svga->vram[addr + 0x3c], mach64);
  30.991 +                if (mach64->context_mask & (1 << 16))
  30.992 +                        mach64_ext_writel(0x2b4, *(uint32_t *)&svga->vram[addr + 0x40], mach64);
  30.993 +                if (mach64->context_mask & (1 << 17))
  30.994 +                        mach64_ext_writel(0x2c0, *(uint32_t *)&svga->vram[addr + 0x44], mach64);
  30.995 +                if (mach64->context_mask & (1 << 18))
  30.996 +                        mach64_ext_writel(0x2c4, *(uint32_t *)&svga->vram[addr + 0x48], mach64);
  30.997 +                if (mach64->context_mask & (1 << 19))
  30.998 +                        mach64_ext_writel(0x2c8, *(uint32_t *)&svga->vram[addr + 0x4c], mach64);
  30.999 +                if (mach64->context_mask & (1 << 20))
 30.1000 +                        mach64_ext_writel(0x2cc, *(uint32_t *)&svga->vram[addr + 0x50], mach64);
 30.1001 +                if (mach64->context_mask & (1 << 21))
 30.1002 +                        mach64_ext_writel(0x2d0, *(uint32_t *)&svga->vram[addr + 0x54], mach64);
 30.1003 +                if (mach64->context_mask & (1 << 22))
 30.1004 +                        mach64_ext_writel(0x2d4, *(uint32_t *)&svga->vram[addr + 0x58], mach64);
 30.1005 +                if (mach64->context_mask & (1 << 23))
 30.1006 +                        mach64_ext_writel(0x2d8, *(uint32_t *)&svga->vram[addr + 0x5c], mach64);
 30.1007 +                if (mach64->context_mask & (1 << 24))
 30.1008 +                        mach64_ext_writel(0x300, *(uint32_t *)&svga->vram[addr + 0x60], mach64);
 30.1009 +                if (mach64->context_mask & (1 << 25))
 30.1010 +                        mach64_ext_writel(0x304, *(uint32_t *)&svga->vram[addr + 0x64], mach64);
 30.1011 +                if (mach64->context_mask & (1 << 26))
 30.1012 +                        mach64_ext_writel(0x308, *(uint32_t *)&svga->vram[addr + 0x68], mach64);
 30.1013 +                if (mach64->context_mask & (1 << 27))
 30.1014 +                        mach64_ext_writel(0x330, *(uint32_t *)&svga->vram[addr + 0x6c], mach64);
 30.1015                  
 30.1016 -                mach64.context_load_cntl = *(uint32_t *)&vram[addr + 0x70];
 30.1017 +                mach64->context_load_cntl = *(uint32_t *)&svga->vram[addr + 0x70];
 30.1018          }
 30.1019  }
 30.1020  
 30.1021 -uint8_t mach64_ext_readb(uint32_t addr, void *priv)
 30.1022 +uint8_t mach64_ext_readb(uint32_t addr, void *p)
 30.1023  {
 30.1024 +        mach64_t *mach64 = (mach64_t *)p;
 30.1025          uint8_t ret;
 30.1026          switch (addr & 0x3ff)
 30.1027          {
 30.1028                  case 0x00: case 0x01: case 0x02: case 0x03:
 30.1029 -                READ8(addr, mach64.crtc_h_total_disp);
 30.1030 +                READ8(addr, mach64->crtc_h_total_disp);
 30.1031                  break;
 30.1032                  case 0x08: case 0x09: case 0x0a: case 0x0b:
 30.1033 -                READ8(addr, mach64.crtc_v_total_disp);
 30.1034 +                READ8(addr, mach64->crtc_v_total_disp);
 30.1035                  break;
 30.1036                  case 0x0c: case 0x0d: case 0x0e: case 0x0f:
 30.1037 -                READ8(addr, mach64.crtc_v_sync_strt_wid);
 30.1038 +                READ8(addr, mach64->crtc_v_sync_strt_wid);
 30.1039                  break;
 30.1040  
 30.1041                  case 0x14: case 0x15: case 0x16: case 0x17:
 30.1042 -                READ8(addr, mach64.crtc_off_pitch);
 30.1043 +                READ8(addr, mach64->crtc_off_pitch);
 30.1044                  break;
 30.1045                  
 30.1046                  case 0x18:
 30.1047 -                ret = mach64.crtc_int_cntl & ~1;
 30.1048 -                if (cgastat & 8)
 30.1049 +                ret = mach64->crtc_int_cntl & ~1;
 30.1050 +                if (mach64->stat & 8)
 30.1051                          ret |= 1;
 30.1052                  break;
 30.1053  
 30.1054                  case 0x1c: case 0x1d: case 0x1e: case 0x1f:
 30.1055 -                READ8(addr, mach64.crtc_gen_cntl);
 30.1056 +                READ8(addr, mach64->crtc_gen_cntl);
 30.1057 +                break;
 30.1058 +
 30.1059 +                case 0x40: case 0x41: case 0x42: case 0x43:
 30.1060 +                READ8(addr, mach64->ovr_clr);
 30.1061 +                break;
 30.1062 +                case 0x44: case 0x45: case 0x46: case 0x47:
 30.1063 +                READ8(addr, mach64->ovr_wid_left_right);
 30.1064 +                break;
 30.1065 +                case 0x48: case 0x49: case 0x4a: case 0x4b:
 30.1066 +                READ8(addr, mach64->ovr_wid_top_bottom);
 30.1067                  break;
 30.1068  
 30.1069                  case 0x68: case 0x69: case 0x6a: case 0x6b:
 30.1070 -                READ8(addr, mach64.cur_offset);
 30.1071 +                READ8(addr, mach64->cur_offset);
 30.1072                  break;
 30.1073                  case 0x6c: case 0x6d: case 0x6e: case 0x6f:
 30.1074 -                READ8(addr, mach64.cur_horz_vert_posn);
 30.1075 +                READ8(addr, mach64->cur_horz_vert_posn);
 30.1076                  break;
 30.1077                  case 0x70: case 0x71: case 0x72: case 0x73:
 30.1078 -                READ8(addr, mach64.cur_horz_vert_off);
 30.1079 +                READ8(addr, mach64->cur_horz_vert_off);
 30.1080                  break;
 30.1081  
 30.1082                  case 0x80: case 0x81: case 0x82: case 0x83:
 30.1083 -                READ8(addr, mach64.scratch_reg0);
 30.1084 +                READ8(addr, mach64->scratch_reg0);
 30.1085                  break;
 30.1086                  case 0x84: case 0x85: case 0x86: case 0x87:
 30.1087 -                READ8(addr, mach64.scratch_reg1);
 30.1088 +                READ8(addr, mach64->scratch_reg1);
 30.1089                  break;
 30.1090  
 30.1091                  case 0x90: case 0x91: case 0x92: case 0x93:
 30.1092 -                READ8(addr, mach64.clock_cntl);
 30.1093 +                READ8(addr, mach64->clock_cntl);
 30.1094                  break;
 30.1095  
 30.1096                  case 0xb0: case 0xb1: case 0xb2: case 0xb3:
 30.1097 -                READ8(addr, mach64.mem_cntl);
 30.1098 +                READ8(addr, mach64->mem_cntl);
 30.1099                  break;
 30.1100  
 30.1101                  case 0xc4: case 0xc5: case 0xc6: case 0xc7:
 30.1102 -                READ8(addr, mach64.dac_cntl);
 30.1103 +                READ8(addr, mach64->dac_cntl);
 30.1104                  break;
 30.1105  
 30.1106                  case 0xd0: case 0xd1: case 0xd2: case 0xd3:
 30.1107 -                READ8(addr, mach64.gen_test_cntl);
 30.1108 +                READ8(addr, mach64->gen_test_cntl);
 30.1109                  break;
 30.1110                  
 30.1111                  case 0xe0: case 0xe1: case 0xe2: case 0xe3:
 30.1112 @@ -912,113 +950,113 @@
 30.1113                  break;
 30.1114                  
 30.1115                  case 0x100: case 0x101: case 0x102: case 0x103:
 30.1116 -                READ8(addr, mach64.dst_off_pitch);
 30.1117 +                READ8(addr, mach64->dst_off_pitch);
 30.1118                  break;
 30.1119                  case 0x104: case 0x105:
 30.1120 -                READ8(addr, mach64.dst_y_x);
 30.1121 +                READ8(addr, mach64->dst_y_x);
 30.1122                  break;
 30.1123                  case 0x108: case 0x109: case 0x11c: case 0x11d:
 30.1124 -                READ8(addr + 2, mach64.dst_y_x);
 30.1125 +                READ8(addr + 2, mach64->dst_y_x);
 30.1126                  break;
 30.1127                  case 0x10c: case 0x10d: case 0x10e: case 0x10f:
 30.1128 -                READ8(addr, mach64.dst_y_x);
 30.1129 +                READ8(addr, mach64->dst_y_x);
 30.1130                  break;
 30.1131                  case 0x110: case 0x111:
 30.1132                  addr += 2;
 30.1133                  case 0x114: case 0x115:
 30.1134                  case 0x118: case 0x119: case 0x11a: case 0x11b:
 30.1135                  case 0x11e: case 0x11f:
 30.1136 -                READ8(addr, mach64.dst_height_width);
 30.1137 +                READ8(addr, mach64->dst_height_width);
 30.1138                  break;
 30.1139  
 30.1140                  case 0x120: case 0x121: case 0x122: case 0x123:
 30.1141 -                READ8(addr, mach64.dst_bres_lnth);
 30.1142 +                READ8(addr, mach64->dst_bres_lnth);
 30.1143                  break;
 30.1144                  case 0x124: case 0x125: case 0x126: case 0x127:
 30.1145 -                READ8(addr, mach64.dst_bres_err);
 30.1146 +                READ8(addr, mach64->dst_bres_err);
 30.1147                  break;
 30.1148                  case 0x128: case 0x129: case 0x12a: case 0x12b:
 30.1149 -                READ8(addr, mach64.dst_bres_inc);
 30.1150 +                READ8(addr, mach64->dst_bres_inc);
 30.1151                  break;
 30.1152                  case 0x12c: case 0x12d: case 0x12e: case 0x12f:
 30.1153 -                READ8(addr, mach64.dst_bres_dec);
 30.1154 +                READ8(addr, mach64->dst_bres_dec);
 30.1155                  break;
 30.1156  
 30.1157                  case 0x130: case 0x131: case 0x132: case 0x133:
 30.1158 -                READ8(addr, mach64.dst_cntl);
 30.1159 +                READ8(addr, mach64->dst_cntl);
 30.1160                  break;
 30.1161  
 30.1162                  case 0x180: case 0x181: case 0x182: case 0x183:
 30.1163 -                READ8(addr, mach64.src_off_pitch);
 30.1164 +                READ8(addr, mach64->src_off_pitch);
 30.1165                  break;
 30.1166                  case 0x184: case 0x185:
 30.1167 -                READ8(addr, mach64.src_y_x);
 30.1168 +                READ8(addr, mach64->src_y_x);
 30.1169                  break;
 30.1170                  case 0x188: case 0x189:
 30.1171 -                READ8(addr + 2, mach64.src_y_x);
 30.1172 +                READ8(addr + 2, mach64->src_y_x);
 30.1173                  break;
 30.1174                  case 0x18c: case 0x18d: case 0x18e: case 0x18f:
 30.1175 -                READ8(addr, mach64.src_y_x);
 30.1176 +                READ8(addr, mach64->src_y_x);
 30.1177                  break;
 30.1178  
 30.1179                  case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7:
 30.1180 -                READ8(addr, mach64.src_cntl);
 30.1181 +                READ8(addr, mach64->src_cntl);
 30.1182                  break;
 30.1183  
 30.1184                  case 0x280: case 0x281: case 0x282: case 0x283:
 30.1185 -                READ8(addr, mach64.pat_reg0);
 30.1186 +                READ8(addr, mach64->pat_reg0);
 30.1187                  break;
 30.1188                  case 0x284: case 0x285: case 0x286: case 0x287:
 30.1189 -                READ8(addr, mach64.pat_reg1);
 30.1190 +                READ8(addr, mach64->pat_reg1);
 30.1191                  break;
 30.1192  
 30.1193                  case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9:
 30.1194 -                READ8(addr, mach64.sc_left_right);
 30.1195 +                READ8(addr, mach64->sc_left_right);
 30.1196                  break;
 30.1197                  case 0x2a4: case 0x2a5:
 30.1198                  addr += 2;
 30.1199                  case 0x2aa: case 0x2ab:                       
 30.1200 -                READ8(addr, mach64.sc_left_right);
 30.1201 +                READ8(addr, mach64->sc_left_right);
 30.1202                  break;
 30.1203  
 30.1204                  case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5:
 30.1205 -                READ8(addr, mach64.sc_top_bottom);
 30.1206 +                READ8(addr, mach64->sc_top_bottom);
 30.1207                  break;
 30.1208                  case 0x2b0: case 0x2b1:
 30.1209                  addr += 2;
 30.1210                  case 0x2b6: case 0x2b7:
 30.1211 -                READ8(addr, mach64.sc_top_bottom);
 30.1212 +                READ8(addr, mach64->sc_top_bottom);
 30.1213                  break;
 30.1214  
 30.1215                  case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3:
 30.1216 -                READ8(addr, mach64.dp_bkgd_clr);
 30.1217 +                READ8(addr, mach64->dp_bkgd_clr);
 30.1218                  break;
 30.1219                  case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7:
 30.1220 -                READ8(addr, mach64.dp_frgd_clr);
 30.1221 +                READ8(addr, mach64->dp_frgd_clr);
 30.1222                  break;
 30.1223                          
 30.1224                  case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3:
 30.1225 -                READ8(addr, mach64.dp_pix_width);
 30.1226 +                READ8(addr, mach64->dp_pix_width);
 30.1227                  break;
 30.1228                  case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7:
 30.1229 -                READ8(addr, mach64.dp_mix);
 30.1230 +                READ8(addr, mach64->dp_mix);
 30.1231                  break;
 30.1232                  case 0x2d8: case 0x2d9: case 0x2da: case 0x2db:
 30.1233 -                READ8(addr, mach64.dp_src);
 30.1234 +                READ8(addr, mach64->dp_src);
 30.1235                  break;
 30.1236  
 30.1237                  case 0x320: case 0x321: case 0x322: case 0x323:
 30.1238 -                READ8(addr, mach64.context_mask);
 30.1239 +                READ8(addr, mach64->context_mask);
 30.1240                  break;
 30.1241  
 30.1242                  case 0x330: case 0x331:
 30.1243 -                READ8(addr, mach64.dst_cntl);
 30.1244 +                READ8(addr, mach64->dst_cntl);
 30.1245                  break;
 30.1246                  case 0x332:
 30.1247 -                READ8(addr - 2, mach64.src_cntl);
 30.1248 +                READ8(addr - 2, mach64->src_cntl);
 30.1249                  break;
 30.1250                  case 0x333:
 30.1251 -                READ8(addr - 3, mach64.pat_cntl);
 30.1252 +                READ8(addr - 3, mach64->pat_cntl);
 30.1253                  break;
 30.1254  
 30.1255                  default:
 30.1256 @@ -1030,8 +1068,9 @@
 30.1257  #endif
 30.1258          return ret;
 30.1259  }
 30.1260 -uint16_t mach64_ext_readw(uint32_t addr, void *priv)
 30.1261 +uint16_t mach64_ext_readw(uint32_t addr, void *p)
 30.1262  {
 30.1263 +        mach64_t *mach64 = (mach64_t *)p;
 30.1264          uint16_t ret;
 30.1265          switch (addr & 0x3ff)
 30.1266          {
 30.1267 @@ -1039,11 +1078,11 @@
 30.1268  #ifdef MACH64_DEBUG
 30.1269                  pclog("  ");
 30.1270  #endif
 30.1271 -                ret = mach64_ext_readb(addr, priv);
 30.1272 +                ret = mach64_ext_readb(addr, p);
 30.1273  #ifdef MACH64_DEBUG
 30.1274                  pclog("  ");
 30.1275  #endif
 30.1276 -                ret |= mach64_ext_readb(addr + 1, priv) << 8;
 30.1277 +                ret |= mach64_ext_readb(addr + 1, p) << 8;
 30.1278                  break;
 30.1279          }
 30.1280  #ifdef MACH64_DEBUG
 30.1281 @@ -1051,33 +1090,34 @@
 30.1282  #endif
 30.1283          return ret;        
 30.1284  }
 30.1285 -uint32_t mach64_ext_readl(uint32_t addr, void *priv)
 30.1286 +uint32_t mach64_ext_readl(uint32_t addr, void *p)
 30.1287  {
 30.1288 +        mach64_t *mach64 = (mach64_t *)p;
 30.1289          uint32_t ret;
 30.1290          switch (addr & 0x3ff)
 30.1291          {
 30.1292                  case 0x18:
 30.1293 -                ret = mach64.crtc_int_cntl & ~1;
 30.1294 -                if (cgastat & 8)
 30.1295 +                ret = mach64->crtc_int_cntl & ~1;
 30.1296 +                if (mach64->stat & 8)
 30.1297                          ret |= 1;
 30.1298                  break;
 30.1299  
 30.1300                  case 0xb4:
 30.1301 -                ret = (mach64_bank_w[0] >> 15) | ((mach64_bank_w[1] >> 15) << 16);
 30.1302 +                ret = (mach64->bank_w[0] >> 15) | ((mach64->bank_w[1] >> 15) << 16);
 30.1303                  break;
 30.1304                  case 0xb8:
 30.1305 -                ret = (mach64_bank_r[0] >> 15) | ((mach64_bank_r[1] >> 15) << 16);
 30.1306 +                ret = (mach64->bank_r[0] >> 15) | ((mach64->bank_r[1] >> 15) << 16);
 30.1307                  break;
 30.1308                  
 30.1309                  default:
 30.1310  #ifdef MACH64_DEBUG
 30.1311                  pclog("  ");
 30.1312  #endif
 30.1313 -                ret = mach64_ext_readw(addr, priv);
 30.1314 +                ret = mach64_ext_readw(addr, p);
 30.1315  #ifdef MACH64_DEBUG
 30.1316                  pclog("  ");
 30.1317  #endif
 30.1318 -                ret |= mach64_ext_readw(addr + 2, priv) << 16;
 30.1319 +                ret |= mach64_ext_readw(addr + 2, p) << 16;
 30.1320                  break;
 30.1321          }
 30.1322  #ifdef MACH64_DEBUG
 30.1323 @@ -1086,187 +1126,200 @@
 30.1324          return ret;
 30.1325  }
 30.1326  
 30.1327 -void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv)
 30.1328 +void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p)
 30.1329  {
 30.1330 +        mach64_t *mach64 = (mach64_t *)p;
 30.1331 +        svga_t *svga = &mach64->svga;
 30.1332  #ifdef MACH64_DEBUG
 30.1333          pclog("mach64_ext_writeb : addr %08X val %02X\n", addr, val);
 30.1334  #endif
 30.1335          switch (addr & 0x3ff)
 30.1336          {
 30.1337                  case 0x00: case 0x01: case 0x02: case 0x03:
 30.1338 -                WRITE8(addr, mach64.crtc_h_total_disp, val);
 30.1339 -                svga_recalctimings();
 30.1340 +                WRITE8(addr, mach64->crtc_h_total_disp, val);
 30.1341 +                svga_recalctimings(&mach64->svga);
 30.1342                  break;
 30.1343                  case 0x08: case 0x09: case 0x0a: case 0x0b:
 30.1344 -                WRITE8(addr, mach64.crtc_v_total_disp, val);
 30.1345 -                svga_recalctimings();
 30.1346 +                WRITE8(addr, mach64->crtc_v_total_disp, val);
 30.1347 +                svga_recalctimings(&mach64->svga);
 30.1348                  break;
 30.1349                  case 0x0c: case 0x0d: case 0x0e: case 0x0f:
 30.1350 -                WRITE8(addr, mach64.crtc_v_sync_strt_wid, val);
 30.1351 -                svga_recalctimings();
 30.1352 +                WRITE8(addr, mach64->crtc_v_sync_strt_wid, val);
 30.1353 +                svga_recalctimings(&mach64->svga);
 30.1354                  break;
 30.1355  
 30.1356                  case 0x14: case 0x15: case 0x16: case 0x17:
 30.1357 -                WRITE8(addr, mach64.crtc_off_pitch, val);
 30.1358 -                svga_recalctimings();
 30.1359 +                WRITE8(addr, mach64->crtc_off_pitch, val);
 30.1360 +                svga_recalctimings(&mach64->svga);
 30.1361                  fullchange = changeframecount;
 30.1362                  break;
 30.1363                  
 30.1364                  case 0x18:
 30.1365 -                mach64.crtc_int_cntl = val;
 30.1366 +                mach64->crtc_int_cntl = val;
 30.1367                  break;
 30.1368  
 30.1369                  case 0x1c: case 0x1d: case 0x1e: case 0x1f:
 30.1370 -                WRITE8(addr, mach64.crtc_gen_cntl, val);
 30.1371 -                svga_recalctimings();
 30.1372 +                WRITE8(addr, mach64->crtc_gen_cntl, val);
 30.1373 +                svga_recalctimings(&mach64->svga);
 30.1374 +                break;
 30.1375 +
 30.1376 +                case 0x40: case 0x41: case 0x42: case 0x43:
 30.1377 +                WRITE8(addr, mach64->ovr_clr, val);
 30.1378 +                break;
 30.1379 +                case 0x44: case 0x45: case 0x46: case 0x47:
 30.1380 +                WRITE8(addr, mach64->ovr_wid_left_right, val);
 30.1381 +                break;
 30.1382 +                case 0x48: case 0x49: case 0x4a: case 0x4b:
 30.1383 +                WRITE8(addr, mach64->ovr_wid_top_bottom, val);
 30.1384                  break;
 30.1385  
 30.1386                  case 0x68: case 0x69: case 0x6a: case 0x6b:
 30.1387 -                WRITE8(addr, mach64.cur_offset, val);
 30.1388 -                svga_hwcursor.addr = (mach64.cur_offset & 0xfffff) * 8;
 30.1389 -                mach64_cursor_dump();
 30.1390 +                WRITE8(addr, mach64->cur_offset, val);
 30.1391 +                svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8;
 30.1392 +                mach64_cursor_dump(mach64);
 30.1393                  break;
 30.1394                  case 0x6c: case 0x6d: case 0x6e: case 0x6f:
 30.1395 -                WRITE8(addr, mach64.cur_horz_vert_posn, val);
 30.1396 -                svga_hwcursor.x = mach64.cur_horz_vert_posn & 0x7ff;
 30.1397 -                svga_hwcursor.y = (mach64.cur_horz_vert_posn >> 16) & 0x7ff;
 30.1398 -                mach64_cursor_dump();
 30.1399 +                WRITE8(addr, mach64->cur_horz_vert_posn, val);
 30.1400 +                svga->hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff;
 30.1401 +                svga->hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff;
 30.1402 +                mach64_cursor_dump(mach64);
 30.1403                  break;
 30.1404                  case 0x70: case 0x71: case 0x72: case 0x73:
 30.1405 -                WRITE8(addr, mach64.cur_horz_vert_off, val);
 30.1406 -                svga_hwcursor.xoff = mach64.cur_horz_vert_off & 0x3f;
 30.1407 -                svga_hwcursor.yoff = (mach64.cur_horz_vert_off >> 16) & 0x3f;
 30.1408 -                mach64_cursor_dump();
 30.1409 +                WRITE8(addr, mach64->cur_horz_vert_off, val);
 30.1410 +                svga->hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f;
 30.1411 +                svga->hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f;
 30.1412 +                mach64_cursor_dump(mach64);
 30.1413                  break;
 30.1414  
 30.1415                  case 0x80: case 0x81: case 0x82: case 0x83:
 30.1416 -                WRITE8(addr, mach64.scratch_reg0, val);
 30.1417 +                WRITE8(addr, mach64->scratch_reg0, val);
 30.1418                  break;
 30.1419                  case 0x84: case 0x85: case 0x86: case 0x87:
 30.1420 -                WRITE8(addr, mach64.scratch_reg1, val);
 30.1421 +                WRITE8(addr, mach64->scratch_reg1, val);
 30.1422                  break;
 30.1423  
 30.1424                  case 0x90: case 0x91: case 0x92: case 0x93:
 30.1425 -                WRITE8(addr, mach64.clock_cntl, val);
 30.1426 -                ics2595_write(val & 0x40, val & 0xf);
 30.1427 +                WRITE8(addr, mach64->clock_cntl, val);
 30.1428 +                ics2595_write(&mach64->ics2595, val & 0x40, val & 0xf);
 30.1429 +                svga_recalctimings(&mach64->svga);
 30.1430                  break;
 30.1431  
 30.1432                  case 0xb0: case 0xb1: case 0xb2: case 0xb3:
 30.1433 -                WRITE8(addr, mach64.mem_cntl, val);
 30.1434 +                WRITE8(addr, mach64->mem_cntl, val);
 30.1435                  break;
 30.1436  
 30.1437                  case 0xb4:
 30.1438 -                mach64_bank_w[0] = val * 32768;
 30.1439 +                mach64->bank_w[0] = val * 32768;
 30.1440  #ifdef MACH64_DEBUG
 30.1441 -                pclog("mach64 : write bank A0000-A7FFF set to %08X\n", mach64_bank_w[0]);
 30.1442 +                pclog("mach64 : write bank A0000-A7FFF set to %08X\n", mach64->bank_w[0]);
 30.1443  #endif
 30.1444                  break;
 30.1445                  case 0xb5: case 0xb6:
 30.1446 -                mach64_bank_w[1] = val * 32768;
 30.1447 +                mach64->bank_w[1] = val * 32768;
 30.1448  #ifdef MACH64_DEBUG
 30.1449 -                pclog("mach64 : write bank A8000-AFFFF set to %08X\n", mach64_bank_w[1]);
 30.1450 +                pclog("mach64 : write bank A8000-AFFFF set to %08X\n", mach64->bank_w[1]);
 30.1451  #endif
 30.1452                  break;
 30.1453                  case 0xb8:
 30.1454 -                mach64_bank_r[0] = val * 32768;
 30.1455 +                mach64->bank_r[0] = val * 32768;
 30.1456  #ifdef MACH64_DEBUG
 30.1457 -                pclog("mach64 :  read bank A0000-A7FFF set to %08X\n", mach64_bank_r[0]);
 30.1458 +                pclog("mach64 :  read bank A0000-A7FFF set to %08X\n", mach64->bank_r[0]);
 30.1459  #endif
 30.1460                  break;
 30.1461                  case 0xb9: case 0xba:
 30.1462 -                mach64_bank_r[1] = val * 32768;
 30.1463 +                mach64->bank_r[1] = val * 32768;
 30.1464  #ifdef MACH64_DEBUG
 30.1465 -                pclog("mach64 :  read bank A8000-AFFFF set to %08X\n", mach64_bank_r[1]);
 30.1466 +                pclog("mach64 :  read bank A8000-AFFFF set to %08X\n", mach64->bank_r[1]);
 30.1467  #endif
 30.1468                  break;
 30.1469  
 30.1470                  case 0xc4: case 0xc5: case 0xc6: case 0xc7:
 30.1471 -                WRITE8(addr, mach64.dac_cntl, val);
 30.1472 +                WRITE8(addr, mach64->dac_cntl, val);
 30.1473                  break;
 30.1474  
 30.1475                  case 0xd0: case 0xd1: case 0xd2: case 0xd3:
 30.1476 -                WRITE8(addr, mach64.gen_test_cntl, val);
 30.1477 +                WRITE8(addr, mach64->gen_test_cntl, val);
 30.1478  //                if (val == 2) output = 3;
 30.1479 -                ati_eeprom_write(mach64.gen_test_cntl & 0x10, mach64.gen_test_cntl & 2, mach64.gen_test_cntl & 1);
 30.1480 -                mach64.gen_test_cntl = (mach64.gen_test_cntl & ~8) | (ati_eeprom_read() ? 8 : 0);
 30.1481 -                svga_hwcursor.ena = mach64.gen_test_cntl & 0x80;
 30.1482 -                mach64_cursor_dump();
 30.1483 +                ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1);
 30.1484 +                mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0);
 30.1485 +                svga->hwcursor.ena = mach64->gen_test_cntl & 0x80;
 30.1486 +                mach64_cursor_dump(mach64);
 30.1487                  break;
 30.1488  
 30.1489                  case 0x100: case 0x101: case 0x102: case 0x103:
 30.1490 -                WRITE8(addr, mach64.dst_off_pitch, val);
 30.1491 +                WRITE8(addr, mach64->dst_off_pitch, val);
 30.1492                  break;
 30.1493                  case 0x104: case 0x105: case 0x11c: case 0x11d:
 30.1494 -                WRITE8(addr + 2, mach64.dst_y_x, val);
 30.1495 +                WRITE8(addr + 2, mach64->dst_y_x, val);
 30.1496                  break;
 30.1497                  case 0x108: case 0x109:
 30.1498 -                WRITE8(addr, mach64.dst_y_x, val);
 30.1499 +                WRITE8(addr, mach64->dst_y_x, val);
 30.1500                  break;
 30.1501                  case 0x10c: case 0x10d: case 0x10e: case 0x10f:
 30.1502 -                WRITE8(addr, mach64.dst_y_x, val);
 30.1503 +                WRITE8(addr, mach64->dst_y_x, val);
 30.1504                  break;
 30.1505                  case 0x110: case 0x111:
 30.1506                  addr += 2;
 30.1507                  case 0x114: case 0x115:
 30.1508                  case 0x118: case 0x119: case 0x11a: case 0x11b:
 30.1509                  case 0x11e: case 0x11f:
 30.1510 -                WRITE8(addr, mach64.dst_height_width, val);
 30.1511 +                WRITE8(addr, mach64->dst_height_width, val);
 30.1512                  if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f)
 30.1513                  {
 30.1514 -                        mach64_start_fill();
 30.1515 +                        mach64_start_fill(mach64);
 30.1516  #ifdef MACH64_DEBUG
 30.1517 -                        pclog("%i %i %i %i %i\n", (mach64.dst_height_width & 0x7ff), (mach64.dst_height_width & 0x7ff0000),
 30.1518 -                            ((mach64.dp_src & 7) != SRC_HOST), (((mach64.dp_src >> 8) & 7) != SRC_HOST),
 30.1519 -                            (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST));
 30.1520 +                        pclog("%i %i %i %i %i\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000),
 30.1521 +                            ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST),
 30.1522 +                            (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST));
 30.1523  #endif                            
 30.1524 -                        if ((mach64.dst_height_width & 0x7ff) && (mach64.dst_height_width & 0x7ff0000) && 
 30.1525 -                            ((mach64.dp_src & 7) != SRC_HOST) && (((mach64.dp_src >> 8) & 7) != SRC_HOST) && 
 30.1526 -                            (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST))
 30.1527 -                                mach64_blit(0, -1);
 30.1528 +                        if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) && 
 30.1529 +                            ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && 
 30.1530 +                            (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST))
 30.1531 +                                mach64_blit(0, -1, mach64);
 30.1532                  }
 30.1533                  break;
 30.1534  
 30.1535                  case 0x120: case 0x121: case 0x122: case 0x123:
 30.1536 -                WRITE8(addr, mach64.dst_bres_lnth, val);
 30.1537 +                WRITE8(addr, mach64->dst_bres_lnth, val);
 30.1538                  if ((addr & 0x3ff) == 0x123 && !(val & 0x80))
 30.1539                  {
 30.1540 -                        mach64_start_line();
 30.1541 +                        mach64_start_line(mach64);
 30.1542  
 30.1543 -                        if ((mach64.dst_bres_lnth & 0x7fff) &&
 30.1544 -                            ((mach64.dp_src & 7) != SRC_HOST) && (((mach64.dp_src >> 8) & 7) != SRC_HOST) && 
 30.1545 -                            (((mach64.dp_src >> 16) & 3) != MONO_SRC_HOST))
 30.1546 -                                mach64_blit(0, -1);
 30.1547 +                        if ((mach64->dst_bres_lnth & 0x7fff) &&
 30.1548 +                            ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && 
 30.1549 +                            (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST))
 30.1550 +                                mach64_blit(0, -1, mach64);
 30.1551                  }
 30.1552                  break;
 30.1553                  case 0x124: case 0x125: case 0x126: case 0x127:
 30.1554 -                WRITE8(addr, mach64.dst_bres_err, val);
 30.1555 +                WRITE8(addr, mach64->dst_bres_err, val);
 30.1556                  break;
 30.1557                  case 0x128: case 0x129: case 0x12a: case 0x12b:
 30.1558 -                WRITE8(addr, mach64.dst_bres_inc, val);
 30.1559 +                WRITE8(addr, mach64->dst_bres_inc, val);
 30.1560                  break;
 30.1561                  case 0x12c: case 0x12d: case 0x12e: case 0x12f:
 30.1562 -                WRITE8(addr, mach64.dst_bres_dec, val);
 30.1563 +                WRITE8(addr, mach64->dst_bres_dec, val);
 30.1564                  break;
 30.1565  
 30.1566                  case 0x130: case 0x131: case 0x132: case 0x133:
 30.1567 -                WRITE8(addr, mach64.dst_cntl, val);
 30.1568 +                WRITE8(addr, mach64->dst_cntl, val);
 30.1569                  break;
 30.1570  
 30.1571                  case 0x180: case 0x181: case 0x182: case 0x183:
 30.1572 -                WRITE8(addr, mach64.src_off_pitch, val);
 30.1573 +                WRITE8(addr, mach64->src_off_pitch, val);
 30.1574                  break;
 30.1575                  case 0x184: case 0x185:
 30.1576 -                WRITE8(addr, mach64.src_y_x, val);
 30.1577 +                WRITE8(addr, mach64->src_y_x, val);
 30.1578                  break;
 30.1579                  case 0x188: case 0x189:
 30.1580 -                WRITE8(addr + 2, mach64.src_y_x, val);
 30.1581 +                WRITE8(addr + 2, mach64->src_y_x, val);
 30.1582                  break;
 30.1583                  case 0x18c: case 0x18d: case 0x18e: case 0x18f:
 30.1584 -                WRITE8(addr, mach64.src_y_x, val);
 30.1585 +                WRITE8(addr, mach64->src_y_x, val);
 30.1586                  break;
 30.1587  
 30.1588                  case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7:
 30.1589 -                WRITE8(addr, mach64.src_cntl, val);
 30.1590 +                WRITE8(addr, mach64->src_cntl, val);
 30.1591                  break;
 30.1592  
 30.1593                  case 0x200: case 0x201: case 0x202: case 0x203:
 30.1594 @@ -1285,68 +1338,69 @@
 30.1595                  case 0x234: case 0x235: case 0x236: case 0x237:
 30.1596                  case 0x238: case 0x239: case 0x23a: case 0x23b:
 30.1597                  case 0x23c: case 0x23d: case 0x23e: case 0x23f:
 30.1598 -                mach64_blit(val, 8);
 30.1599 +                mach64_blit(val, 8, mach64);
 30.1600                  break;
 30.1601  
 30.1602                  case 0x280: case 0x281: case 0x282: case 0x283:
 30.1603 -                WRITE8(addr, mach64.pat_reg0, val);
 30.1604 +                WRITE8(addr, mach64->pat_reg0, val);
 30.1605                  break;
 30.1606                  case 0x284: case 0x285: case 0x286: case 0x287:
 30.1607 -                WRITE8(addr, mach64.pat_reg1, val);
 30.1608 +                WRITE8(addr, mach64->pat_reg1, val);
 30.1609                  break;
 30.1610  
 30.1611                  case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9:
 30.1612 -                WRITE8(addr, mach64.sc_left_right, val);
 30.1613 +                WRITE8(addr, mach64->sc_left_right, val);
 30.1614                  break;
 30.1615                  case 0x2a4: case 0x2a5:
 30.1616                  addr += 2;
 30.1617                  case 0x2aa: case 0x2ab:                       
 30.1618 -                WRITE8(addr, mach64.sc_left_right, val);
 30.1619 +                WRITE8(addr, mach64->sc_left_right, val);
 30.1620                  break;
 30.1621  
 30.1622                  case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5:
 30.1623 -                WRITE8(addr, mach64.sc_top_bottom, val);
 30.1624 +                WRITE8(addr, mach64->sc_top_bottom, val);
 30.1625                  break;
 30.1626                  case 0x2b0: case 0x2b1:
 30.1627                  addr += 2;
 30.1628                  case 0x2b6: case 0x2b7:
 30.1629 -                WRITE8(addr, mach64.sc_top_bottom, val);
 30.1630 +                WRITE8(addr, mach64->sc_top_bottom, val);
 30.1631                  break;
 30.1632  
 30.1633                  case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3:
 30.1634 -                WRITE8(addr, mach64.dp_bkgd_clr, val);
 30.1635 +                WRITE8(addr, mach64->dp_bkgd_clr, val);
 30.1636                  break;
 30.1637                  case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7:
 30.1638 -                WRITE8(addr, mach64.dp_frgd_clr, val);
 30.1639 +                WRITE8(addr, mach64->dp_frgd_clr, val);
 30.1640                  break;
 30.1641  
 30.1642                  case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3:
 30.1643 -                WRITE8(addr, mach64.dp_pix_width, val);
 30.1644 +                WRITE8(addr, mach64->dp_pix_width, val);
 30.1645                  break;
 30.1646                  case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7:
 30.1647 -                WRITE8(addr, mach64.dp_mix, val);
 30.1648 +                WRITE8(addr, mach64->dp_mix, val);
 30.1649                  break;
 30.1650                  case 0x2d8: case 0x2d9: case 0x2da: case 0x2db:
 30.1651 -                WRITE8(addr, mach64.dp_src, val);
 30.1652 +                WRITE8(addr, mach64->dp_src, val);
 30.1653                  break;
 30.1654  
 30.1655                  case 0x320: case 0x321: case 0x322: case 0x323:
 30.1656 -                WRITE8(addr, mach64.context_mask, val);
 30.1657 +                WRITE8(addr, mach64->context_mask, val);
 30.1658                  break;
 30.1659  
 30.1660                  case 0x330: case 0x331:
 30.1661 -                WRITE8(addr, mach64.dst_cntl, val);
 30.1662 +                WRITE8(addr, mach64->dst_cntl, val);
 30.1663                  break;
 30.1664                  case 0x332:
 30.1665 -                WRITE8(addr - 2, mach64.src_cntl, val);
 30.1666 +                WRITE8(addr - 2, mach64->src_cntl, val);
 30.1667                  break;
 30.1668                  case 0x333:
 30.1669 -                WRITE8(addr - 3, mach64.pat_cntl, val & 7);
 30.1670 +                WRITE8(addr - 3, mach64->pat_cntl, val & 7);
 30.1671                  break;
 30.1672          }
 30.1673  }
 30.1674 -void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv)
 30.1675 +void mach64_ext_writew(uint32_t addr, uint16_t val, void *p)
 30.1676  {
 30.1677 +        mach64_t *mach64 = (mach64_t *)p;
 30.1678  #ifdef MACH64_DEBUG
 30.1679          pclog("mach64_ext_writew : addr %08X val %04X\n", addr, val);
 30.1680  #endif
 30.1681 @@ -1360,23 +1414,24 @@
 30.1682                  case 0x228: case 0x22a: case 0x22c: case 0x22e:
 30.1683                  case 0x230: case 0x232: case 0x234: case 0x236:
 30.1684                  case 0x238: case 0x23a: case 0x23c: case 0x23e:
 30.1685 -                mach64_blit(val, 16);
 30.1686 +                mach64_blit(val, 16, mach64);
 30.1687                  break;
 30.1688  
 30.1689                  default:
 30.1690  #ifdef MACH64_DEBUG
 30.1691                  pclog("  ");
 30.1692  #endif
 30.1693 -                mach64_ext_writeb(addr, val, priv);
 30.1694 +                mach64_ext_writeb(addr, val, p);
 30.1695  #ifdef MACH64_DEBUG
 30.1696                  pclog("  ");
 30.1697  #endif
 30.1698 -                mach64_ext_writeb(addr + 1, val >> 8, priv);
 30.1699 +                mach64_ext_writeb(addr + 1, val >> 8, p);
 30.1700                  break;
 30.1701          }
 30.1702  }
 30.1703 -void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv)
 30.1704 +void mach64_ext_writel(uint32_t addr, uint32_t val, void *p)
 30.1705  {
 30.1706 +        mach64_t *mach64 = (mach64_t *)p;
 30.1707  #ifdef MACH64_DEBUG
 30.1708          if ((addr & 0x3c0) != 0x200)
 30.1709                  pclog("mach64_ext_writel : addr %08X val %08X\n", addr, val);
 30.1710 @@ -1384,123 +1439,135 @@
 30.1711          switch (addr & 0x3fc)
 30.1712          {
 30.1713                  case 0x32c:
 30.1714 -                mach64.context_load_cntl = val;
 30.1715 +                mach64->context_load_cntl = val;
 30.1716                  if (val & 0x30000)
 30.1717 -                        mach64_load_context();
 30.1718 +                        mach64_load_context(mach64);
 30.1719                  break;
 30.1720                  
 30.1721                  case 0x200: case 0x204: case 0x208: case 0x20c:
 30.1722                  case 0x210: case 0x214: case 0x218: case 0x21c:
 30.1723                  case 0x220: case 0x224: case 0x228: case 0x22c:
 30.1724                  case 0x230: case 0x234: case 0x238: case 0x23c:
 30.1725 -                if (mach64.accel.source_host)
 30.1726 -                        mach64_blit(val, 32);
 30.1727 +                if (mach64->accel.source_host)
 30.1728 +                        mach64_blit(val, 32, mach64);
 30.1729                  else
 30.1730 -                        mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32);                
 30.1731 +                        mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32, mach64);
 30.1732                  break;
 30.1733                  
 30.1734                  default:
 30.1735  #ifdef MACH64_DEBUG
 30.1736                  pclog("  ");
 30.1737  #endif
 30.1738 -                mach64_ext_writew(addr, val, priv);
 30.1739 +                mach64_ext_writew(addr, val, p);
 30.1740  #ifdef MACH64_DEBUG
 30.1741                  pclog("  ");
 30.1742  #endif
 30.1743 -                mach64_ext_writew(addr + 2, val >> 16, priv);
 30.1744 +                mach64_ext_writew(addr + 2, val >> 16, p);
 30.1745                  break;
 30.1746          }
 30.1747  }
 30.1748  
 30.1749 -uint8_t mach64_ext_inb(uint16_t port, void *priv)
 30.1750 +uint8_t mach64_ext_inb(uint16_t port, void *p)
 30.1751  {
 30.1752 +        mach64_t *mach64 = (mach64_t *)p;        
 30.1753          uint8_t ret;
 30.1754  //        if (CS == 0x2be7) output = 3;
 30.1755          switch (port)
 30.1756          {
 30.1757                  case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef:
 30.1758 -                ret = mach64_ext_readb(0x00 | (port & 3), NULL);
 30.1759 +                case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef:
 30.1760 +                ret = mach64_ext_readb(0x00 | (port & 3), p);
 30.1761                  break;
 30.1762                  case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef:
 30.1763 -                ret = mach64_ext_readb(0x08 | (port & 3), NULL);
 30.1764 +                ret = mach64_ext_readb(0x08 | (port & 3), p);
 30.1765                  break;
 30.1766                  case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef:
 30.1767 -                ret = mach64_ext_readb(0x0c | (port & 3), NULL);
 30.1768 +                ret = mach64_ext_readb(0x0c | (port & 3), p);
 30.1769                  break;
 30.1770  
 30.1771                  case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef:
 30.1772 -                ret = mach64_ext_readb(0x14 | (port & 3), NULL);
 30.1773 +                ret = mach64_ext_readb(0x14 | (port & 3), p);
 30.1774                  break;
 30.1775  
 30.1776                  case 0x1aec:
 30.1777 -                ret = mach64_ext_readb(0x18, NULL);
 30.1778 +                ret = mach64_ext_readb(0x18, p);
 30.1779                  break;
 30.1780  
 30.1781                  case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef:
 30.1782 -                ret = mach64_ext_readb(0x1c | (port & 3), NULL);
 30.1783 +                ret = mach64_ext_readb(0x1c | (port & 3), p);
 30.1784 +                break;
 30.1785 +
 30.1786 +                case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef:
 30.1787 +                ret = mach64_ext_readb(0x40 | (port & 3), p);
 30.1788 +                break;
 30.1789 +                case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef:
 30.1790 +                ret = mach64_ext_readb(0x44 | (port & 3), p);
 30.1791 +                break;
 30.1792 +                case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef:
 30.1793 +                ret = mach64_ext_readb(0x48 | (port & 3), p);
 30.1794                  break;
 30.1795  
 30.1796                  case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef:
 30.1797 -                ret = mach64_ext_readb(0x68 | (port & 3), NULL);
 30.1798 +                ret = mach64_ext_readb(0x68 | (port & 3), p);
 30.1799                  break;
 30.1800                  case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef:
 30.1801 -                ret = mach64_ext_readb(0x6c | (port & 3), NULL);
 30.1802 +                ret = mach64_ext_readb(0x6c | (port & 3), p);
 30.1803                  break;
 30.1804                  case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef:
 30.1805 -                ret = mach64_ext_readb(0x70 | (port & 3), NULL);
 30.1806 +                ret = mach64_ext_readb(0x70 | (port & 3), p);
 30.1807                  break;
 30.1808  
 30.1809                  case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef:
 30.1810 -                ret = mach64_ext_readb(0x80 | (port & 3), NULL);
 30.1811 +                ret = mach64_ext_readb(0x80 | (port & 3), p);
 30.1812                  break;
 30.1813                  case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef:
 30.1814 -                ret = mach64_ext_readb(0x84 | (port & 3), NULL);
 30.1815 +                ret = mach64_ext_readb(0x84 | (port & 3), p);
 30.1816                  break;
 30.1817                  case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef:
 30.1818 -                ret = mach64_ext_readb(0x90 | (port & 3), NULL);
 30.1819 +                ret = mach64_ext_readb(0x90 | (port & 3), p);
 30.1820                  break;
 30.1821  
 30.1822                  case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef:
 30.1823 -                ret = mach64_ext_readb(0xb0 | (port & 3), NULL);
 30.1824 +                ret = mach64_ext_readb(0xb0 | (port & 3), p);
 30.1825                  break;
 30.1826                          
 30.1827                  case 0x56ec:
 30.1828 -                ret = mach64_ext_readb(0xb4, NULL);
 30.1829 +                ret = mach64_ext_readb(0xb4, p);
 30.1830                  break;
 30.1831                  case 0x56ed: case 0x56ee:
 30.1832 -                ret = mach64_ext_readb(0xb5, NULL);
 30.1833 +                ret = mach64_ext_readb(0xb5, p);
 30.1834                  break;
 30.1835                  case 0x5aec:
 30.1836 -                ret = mach64_ext_readb(0xb8, NULL);
 30.1837 +                ret = mach64_ext_readb(0xb8, p);
 30.1838                  break;
 30.1839                  case 0x5aed: case 0x5aee:
 30.1840 -                ret = mach64_ext_readb(0xb9, NULL);
 30.1841 +                ret = mach64_ext_readb(0xb9, p);
 30.1842                  break;
 30.1843  
 30.1844                  case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef:
 30.1845 -                ret = ati68860_ramdac_in((port & 3) | ((mach64.dac_cntl & 3) << 2), NULL);
 30.1846 +                ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga);
 30.1847                  break;
 30.1848                  
 30.1849                  case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef:
 30.1850 -                ret = mach64_ext_readb(0xc4 | (port & 3), NULL);
 30.1851 +                ret = mach64_ext_readb(0xc4 | (port & 3), p);
 30.1852                  break;
 30.1853                          
 30.1854                  case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef:
 30.1855 -                ret = mach64_ext_readb(0xd0 | (port & 3), NULL);
 30.1856 +                ret = mach64_ext_readb(0xd0 | (port & 3), p);
 30.1857                  break;
 30.1858  
 30.1859                  case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef:
 30.1860 -                READ8(port, mach64.config_cntl);
 30.1861 +                READ8(port, mach64->config_cntl);
 30.1862                  break;
 30.1863                  
 30.1864                  case 0x6eec: case 0x6eed: case 0x6eee: case 0x6eef:
 30.1865 -                ret = mach64_ext_readb(0xe0 | (port & 3), NULL);
 30.1866 +                ret = mach64_ext_readb(0xe0 | (port & 3), p);
 30.1867                  break;
 30.1868  
 30.1869                  case 0x72ec:
 30.1870                  ret = 6 | (3 << 3); /*VLB, 256Kx16 DRAM*/
 30.1871                  break;
 30.1872 -                
 30.1873 +
 30.1874                  default:
 30.1875                  ret = 0;
 30.1876                  break;
 30.1877 @@ -1510,16 +1577,17 @@
 30.1878  #endif
 30.1879          return ret;
 30.1880  }
 30.1881 -uint16_t mach64_ext_inw(uint16_t port, void *priv)
 30.1882 +uint16_t mach64_ext_inw(uint16_t port, void *p)
 30.1883  {
 30.1884 +        mach64_t *mach64 = (mach64_t *)p;        
 30.1885          uint16_t ret;
 30.1886          switch (port)
 30.1887          {
 30.1888                  default:
 30.1889                  pclog("  ");
 30.1890 -                ret = mach64_ext_inb(port, priv);
 30.1891 +                ret = mach64_ext_inb(port, p);
 30.1892                  pclog("  ");
 30.1893 -                ret |= (mach64_ext_inb(port + 1, priv) << 8);
 30.1894 +                ret |= (mach64_ext_inb(port + 1, p) << 8);
 30.1895                  break;
 30.1896          }
 30.1897  #ifdef MACH64_DEBUG
 30.1898 @@ -1527,23 +1595,24 @@
 30.1899  #endif
 30.1900          return ret;        
 30.1901  }
 30.1902 -uint32_t mach64_ext_inl(uint16_t port, void *priv)
 30.1903 +uint32_t mach64_ext_inl(uint16_t port, void *p)
 30.1904  {
 30.1905 +        mach64_t *mach64 = (mach64_t *)p;
 30.1906          uint32_t ret;
 30.1907          switch (port)
 30.1908          {
 30.1909                  case 0x56ec:
 30.1910 -                ret = mach64_ext_readl(0xb4, NULL);
 30.1911 +                ret = mach64_ext_readl(0xb4, p);
 30.1912                  break;
 30.1913                  case 0x5aec:
 30.1914 -                ret = mach64_ext_readl(0xb8, NULL);
 30.1915 +                ret = mach64_ext_readl(0xb8, p);
 30.1916                  break;
 30.1917  
 30.1918                  default:
 30.1919                  pclog("  ");
 30.1920 -                ret = mach64_ext_inw(port, priv);
 30.1921 +                ret = mach64_ext_inw(port, p);
 30.1922                  pclog("  ");
 30.1923 -                ret |= (mach64_ext_inw(port + 2, priv) << 16);
 30.1924 +                ret |= (mach64_ext_inw(port + 2, p) << 16);
 30.1925                  break;
 30.1926          }
 30.1927  #ifdef MACH64_DEBUG
 30.1928 @@ -1552,8 +1621,9 @@
 30.1929          return ret;
 30.1930  }
 30.1931  
 30.1932 -void mach64_ext_outb(uint16_t port, uint8_t val, void *priv)
 30.1933 +void mach64_ext_outb(uint16_t port, uint8_t val, void *p)
 30.1934  {
 30.1935 +        mach64_t *mach64 = (mach64_t *)p;
 30.1936  #ifdef MACH64_DEBUG
 30.1937          pclog("mach64_ext_outb : port %04X val %02X  %04X:%04X\n", port, val, CS,pc);
 30.1938  #endif
 30.1939 @@ -1561,83 +1631,94 @@
 30.1940          {
 30.1941                  case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef:
 30.1942                  case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef:
 30.1943 -                mach64_ext_writeb(0x00 | (port & 3), val, NULL);
 30.1944 +                mach64_ext_writeb(0x00 | (port & 3), val, p);
 30.1945                  break;
 30.1946                  case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef:
 30.1947 -                mach64_ext_writeb(0x08 | (port & 3), val, NULL);
 30.1948 +                mach64_ext_writeb(0x08 | (port & 3), val, p);
 30.1949                  break;
 30.1950                  case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef:
 30.1951 -                mach64_ext_writeb(0x0c | (port & 3), val, NULL);
 30.1952 +                mach64_ext_writeb(0x0c | (port & 3), val, p);
 30.1953                  break;
 30.1954  
 30.1955                  case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef:
 30.1956 -                mach64_ext_writeb(0x14 | (port & 3), val, NULL);
 30.1957 +                mach64_ext_writeb(0x14 | (port & 3), val, p);
 30.1958                  break;
 30.1959                  
 30.1960                  case 0x1aec:
 30.1961 -                mach64_ext_writeb(0x18, val, NULL);
 30.1962 +                mach64_ext_writeb(0x18, val, p);
 30.1963                  break;
 30.1964  
 30.1965                  case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef:
 30.1966 -                mach64_ext_writeb(0x1c | (port & 3), val, NULL);
 30.1967 +                mach64_ext_writeb(0x1c | (port & 3), val, p);
 30.1968 +                break;
 30.1969 +
 30.1970 +                case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef:
 30.1971 +                mach64_ext_writeb(0x40 | (port & 3), val, p);
 30.1972 +                break;
 30.1973 +                case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef:
 30.1974 +                mach64_ext_writeb(0x44 | (port & 3), val, p);
 30.1975 +                break;
 30.1976 +                case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef:
 30.1977 +                mach64_ext_writeb(0x48 | (port & 3), val, p);
 30.1978                  break;
 30.1979  
 30.1980                  case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef:
 30.1981 -                mach64_ext_writeb(0x68 | (port & 3), val, NULL);
 30.1982 +                mach64_ext_writeb(0x68 | (port & 3), val, p);
 30.1983                  break;
 30.1984                  case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef:
 30.1985 -                mach64_ext_writeb(0x6c | (port & 3), val, NULL);
 30.1986 +                mach64_ext_writeb(0x6c | (port & 3), val, p);
 30.1987                  break;
 30.1988                  case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef:
 30.1989 -                mach64_ext_writeb(0x70 | (port & 3), val, NULL);
 30.1990 +                mach64_ext_writeb(0x70 | (port & 3), val, p);
 30.1991                  break;
 30.1992  
 30.1993                  case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef:
 30.1994 -                mach64_ext_writeb(0x80 | (port & 3), val, NULL);
 30.1995 +                mach64_ext_writeb(0x80 | (port & 3), val, p);
 30.1996                  break;
 30.1997                  case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef:
 30.1998 -                mach64_ext_writeb(0x84 | (port & 3), val, NULL);
 30.1999 +                mach64_ext_writeb(0x84 | (port & 3), val, p);
 30.2000                  break;
 30.2001                  case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef:
 30.2002 -                mach64_ext_writeb(0x90 | (port & 3), val, NULL);
 30.2003 +                mach64_ext_writeb(0x90 | (port & 3), val, p);
 30.2004                  break;
 30.2005  
 30.2006                  case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef:
 30.2007 -                mach64_ext_writeb(0xb0 | (port & 3), val, NULL);
 30.2008 +                mach64_ext_writeb(0xb0 | (port & 3), val, p);
 30.2009                  break;
 30.2010  
 30.2011                  case 0x56ec:
 30.2012 -                mach64_ext_writeb(0xb4, val, NULL);
 30.2013 +                mach64_ext_writeb(0xb4, val, p);
 30.2014                  break;
 30.2015                  case 0x56ed: case 0x56ee:
 30.2016 -                mach64_ext_writeb(0xb5, val, NULL);
 30.2017 +                mach64_ext_writeb(0xb5, val, p);
 30.2018                  break;
 30.2019                  case 0x5aec:
 30.2020 -                mach64_ext_writeb(0xb8, val, NULL);
 30.2021 +                mach64_ext_writeb(0xb8, val, p);
 30.2022                  break;
 30.2023                  case 0x5aed: case 0x5aee:
 30.2024 -                mach64_ext_writeb(0xb9, val, NULL);
 30.2025 +                mach64_ext_writeb(0xb9, val, p);
 30.2026                  break;
 30.2027  
 30.2028                  case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef:
 30.2029 -                ati68860_ramdac_out((port & 3) | ((mach64.dac_cntl & 3) << 2), val, NULL);
 30.2030 +                ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga);
 30.2031                  break;
 30.2032  
 30.2033                  case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef:
 30.2034 -                mach64_ext_writeb(0xc4 | (port & 3), val, NULL);
 30.2035 +                mach64_ext_writeb(0xc4 | (port & 3), val, p);
 30.2036                  break;
 30.2037  
 30.2038                  case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef:
 30.2039 -                mach64_ext_writeb(0xd0 | (port & 3), val, NULL);
 30.2040 +                mach64_ext_writeb(0xd0 | (port & 3), val, p);
 30.2041                  break;
 30.2042  
 30.2043                  case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef:
 30.2044 -                WRITE8(port, mach64.config_cntl, val);
 30.2045 +                WRITE8(port, mach64->config_cntl, val);
 30.2046                  break;
 30.2047          }
 30.2048  }
 30.2049 -void mach64_ext_outw(uint16_t port, uint16_t val, void *priv)
 30.2050 +void mach64_ext_outw(uint16_t port, uint16_t val, void *p)
 30.2051  {
 30.2052 +        mach64_t *mach64 = (mach64_t *)p;
 30.2053  #ifdef MACH64_DEBUG
 30.2054          pclog("mach64_ext_outw : port %04X val %04X\n", port, val);
 30.2055  #endif
 30.2056 @@ -1647,16 +1728,17 @@
 30.2057  #ifdef MACH64_DEBUG
 30.2058                  pclog("  ");
 30.2059  #endif
 30.2060 -                mach64_ext_outb(port, val, priv);
 30.2061 +                mach64_ext_outb(port, val, p);
 30.2062  #ifdef MACH64_DEBUG
 30.2063                  pclog("  ");
 30.2064  #endif
 30.2065 -                mach64_ext_outb(port + 1, val >> 8, priv);
 30.2066 +                mach64_ext_outb(port + 1, val >> 8, p);
 30.2067                  break;
 30.2068          }
 30.2069  }
 30.2070 -void mach64_ext_outl(uint16_t port, uint32_t val, void *priv)
 30.2071 +void mach64_ext_outl(uint16_t port, uint32_t val, void *p)
 30.2072  {
 30.2073 +        mach64_t *mach64 = (mach64_t *)p;
 30.2074          pclog("mach64_ext_outl : port %04X val %08X\n", port, val);
 30.2075          switch (port)
 30.2076          {
 30.2077 @@ -1664,104 +1746,113 @@
 30.2078  #ifdef MACH64_DEBUG
 30.2079                  pclog("  ");
 30.2080  #endif
 30.2081 -                mach64_ext_outw(port, val, priv);
 30.2082 +                mach64_ext_outw(port, val, p);
 30.2083  #ifdef MACH64_DEBUG
 30.2084                  pclog("  ");
 30.2085  #endif
 30.2086 -                mach64_ext_outw(port + 2, val >> 16, priv);
 30.2087 +                mach64_ext_outw(port + 2, val >> 16, p);
 30.2088                  break;
 30.2089          }
 30.2090  }
 30.2091  
 30.2092 -void mach64_write(uint32_t addr, uint8_t val, void *priv)
 30.2093 +void mach64_write(uint32_t addr, uint8_t val, void *p)
 30.2094  {
 30.2095 +        mach64_t *mach64 = (mach64_t *)p;
 30.2096  //        pclog("mach64_write : %05X %02X  ", addr, val);
 30.2097 -        addr = (addr & 0x7fff) + mach64_bank_w[(addr >> 15) & 1];
 30.2098 +        addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1];
 30.2099  //        pclog("%08X\n", addr);
 30.2100 -        svga_write_linear(addr, val, priv);
 30.2101 +        svga_write_linear(addr, val, p);
 30.2102  }
 30.2103  
 30.2104 -uint8_t mach64_read(uint32_t addr, void *priv)
 30.2105 +uint8_t mach64_read(uint32_t addr, void *p)
 30.2106  {
 30.2107 +        mach64_t *mach64 = (mach64_t *)p;
 30.2108          uint8_t ret;
 30.2109  //        pclog("mach64_read : %05X ", addr);
 30.2110 -        addr = (addr & 0x7fff) + mach64_bank_r[(addr >> 15) & 1];
 30.2111 -        ret = svga_read_linear(addr, priv);
 30.2112 +        addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1];
 30.2113 +        ret = svga_read_linear(addr, p);
 30.2114  //        pclog("%08X %02X\n", addr, ret);  
 30.2115          return ret;      
 30.2116  }
 30.2117  
 30.2118 -void mach64_hwcursor_draw(int displine)
 30.2119 +void mach64_hwcursor_draw(svga_t *svga, int displine)
 30.2120  {
 30.2121          int x, offset;
 30.2122          uint8_t dat;
 30.2123 -        offset = svga_hwcursor_latch.xoff;
 30.2124 -        for (x = 0; x < 64 - svga_hwcursor_latch.xoff; x += 4)
 30.2125 +        offset = svga->hwcursor_latch.xoff;
 30.2126 +        for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4)
 30.2127          {
 30.2128 -                dat = vram[svga_hwcursor_latch.addr + (offset >> 2)];
 30.2129 -                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32]  = (dat & 1) ? 0xFFFFFF : 0;
 30.2130 -                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32] ^= 0xFFFFFF;
 30.2131 +                dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)];
 30.2132 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32]  = (dat & 1) ? 0xFFFFFF : 0;
 30.2133 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF;
 30.2134                  dat >>= 2;
 30.2135 -                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33]  = (dat & 1) ? 0xFFFFFF : 0;
 30.2136 -                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33] ^= 0xFFFFFF;
 30.2137 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33]  = (dat & 1) ? 0xFFFFFF : 0;
 30.2138 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF;
 30.2139                  dat >>= 2;
 30.2140 -                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34]  = (dat & 1) ? 0xFFFFFF : 0;
 30.2141 -                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34] ^= 0xFFFFFF;
 30.2142 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34]  = (dat & 1) ? 0xFFFFFF : 0;
 30.2143 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF;
 30.2144                  dat >>= 2;
 30.2145 -                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35]  = (dat & 1) ? 0xFFFFFF : 0;
 30.2146 -                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35] ^= 0xFFFFFF;
 30.2147 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35]  = (dat & 1) ? 0xFFFFFF : 0;
 30.2148 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF;
 30.2149                  dat >>= 2;
 30.2150                  offset += 4;
 30.2151          }
 30.2152 -        svga_hwcursor_latch.addr += 16;
 30.2153 +        svga->hwcursor_latch.addr += 16;
 30.2154  }
 30.2155  
 30.2156 -int mach64_init()
 30.2157 +void *mach64gx_init()
 30.2158  {
 30.2159          int c;
 30.2160 +        mach64_t *mach64 = malloc(sizeof(mach64_t));
 30.2161 +        memset(mach64, 0, sizeof(mach64_t));
 30.2162          
 30.2163 -        svga_recalctimings_ex = mach64_recalctimings;
 30.2164 -        svga_hwcursor_draw    = mach64_hwcursor_draw;
 30.2165 -                
 30.2166 -        svga_vram_limit       = 1 << 22; /*4mb*/
 30.2167 -        vrammask = 0x3fffff;
 30.2168 +        svga_init(&mach64->svga, mach64, 1 << 22, /*4mb*/
 30.2169 +                   mach64_recalctimings,
 30.2170 +                   mach64_in, mach64_out,
 30.2171 +                   mach64_hwcursor_draw); 
 30.2172 +
 30.2173 +        io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
 30.2174          
 30.2175          for (c = 0; c < 8; c++)
 30.2176          {
 30.2177 -                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);
 30.2178 -                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);
 30.2179 -                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);
 30.2180 -                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);                                                
 30.2181 +                io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
 30.2182 +                io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
 30.2183 +                io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
 30.2184 +                io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);                                                
 30.2185          }
 30.2186  
 30.2187 -        io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, NULL);
 30.2188 +        io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
 30.2189          
 30.2190 -        ati_eeprom_load("mach64.nvr", 1);
 30.2191 +        ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1);
 30.2192  
 30.2193 -        mach64.dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/        
 30.2194 +        mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/        
 30.2195          
 30.2196 -        mach64.dst_cntl = 3;
 30.2197 -        return svga_init();
 30.2198 +        mach64->dst_cntl = 3;
 30.2199 +        
 30.2200 +        return mach64;
 30.2201  }
 30.2202  
 30.2203 -GFXCARD vid_mach64 =
 30.2204 +void mach64_close(void *p)
 30.2205  {
 30.2206 -        mach64_init,
 30.2207 -        /*IO at 3Cx/3Dx*/
 30.2208 -        mach64_out,
 30.2209 -        mach64_in,
 30.2210 -        /*IO at 3Ax/3Bx*/
 30.2211 -        video_out_null,
 30.2212 -        video_in_null,
 30.2213 +        mach64_t *mach64 = (mach64_t *)p;
 30.2214  
 30.2215 -        svga_poll,
 30.2216 -        svga_recalctimings,
 30.2217 +        svga_close(&mach64->svga);
 30.2218 +        
 30.2219 +        free(mach64);
 30.2220 +}
 30.2221  
 30.2222 -        svga_write,
 30.2223 -        video_write_null,
 30.2224 -        video_write_null,
 30.2225 +void mach64_speed_changed(void *p)
 30.2226 +{
 30.2227 +        mach64_t *mach64 = (mach64_t *)p;
 30.2228 +        
 30.2229 +        svga_recalctimings(&mach64->svga);
 30.2230 +}
 30.2231  
 30.2232 -        svga_read,
 30.2233 -        video_read_null,
 30.2234 -        video_read_null
 30.2235 +device_t mach64gx_device =
 30.2236 +{
 30.2237 +        "ATI Mach64GX",
 30.2238 +        mach64gx_init,
 30.2239 +        mach64_close,
 30.2240 +        mach64_speed_changed,
 30.2241 +        svga_add_status_info
 30.2242  };
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/src/vid_ati_mach64.h	Mon Jun 24 20:42:35 2013 +0100
    31.3 @@ -0,0 +1,1 @@
    31.4 +extern device_t mach64gx_device;
    32.1 --- a/src/vid_cga.c	Tue Jun 04 20:52:17 2013 +0100
    32.2 +++ b/src/vid_cga.c	Mon Jun 24 20:42:35 2013 +0100
    32.3 @@ -1,110 +1,115 @@
    32.4  /*CGA emulation*/
    32.5 +#include <stdlib.h>
    32.6  #include <math.h>
    32.7  #include "ibm.h"
    32.8 +#include "device.h"
    32.9  #include "io.h"
   32.10  #include "mem.h"
   32.11  #include "timer.h"
   32.12  #include "video.h"
   32.13  #include "vid_cga.h"
   32.14  
   32.15 -void cga_recalctimings();
   32.16 +static int i_filt[8],q_filt[8];
   32.17  
   32.18 -void cga_out(uint16_t addr, uint8_t val, void *priv)
   32.19 +static uint8_t crtcmask[32] = 
   32.20  {
   32.21 +        0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
   32.22 +        0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   32.23 +};
   32.24 +
   32.25 +void cga_recalctimings(cga_t *cga);
   32.26 +
   32.27 +void cga_out(uint16_t addr, uint8_t val, void *p)
   32.28 +{
   32.29 +        cga_t *cga = (cga_t *)p;
   32.30          uint8_t old;
   32.31  //        pclog("CGA_OUT %04X %02X\n", addr, val);
   32.32          switch (addr)
   32.33          {
   32.34                  case 0x3D4:
   32.35 -                crtcreg=val&31;
   32.36 +                cga->crtcreg = val & 31;
   32.37                  return;
   32.38                  case 0x3D5:
   32.39 -                old=crtc[crtcreg];
   32.40 -                crtc[crtcreg]=val&crtcmask[crtcreg];
   32.41 -                if (old!=val)
   32.42 +                old = cga->crtc[cga->crtcreg];
   32.43 +                cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
   32.44 +                if (old != val)
   32.45                  {
   32.46 -                        if (crtcreg<0xE || crtcreg>0x10)
   32.47 +                        if (cga->crtcreg < 0xe || cga->crtcreg > 0x10)
   32.48                          {
   32.49 -                                fullchange=changeframecount;
   32.50 -                                cga_recalctimings();
   32.51 +                                fullchange = changeframecount;
   32.52 +                                cga_recalctimings(cga);
   32.53                          }
   32.54                  }
   32.55                  return;
   32.56                  case 0x3D8:
   32.57 -                cgamode=val;
   32.58 +                cga->cgamode = val;
   32.59                  return;
   32.60                  case 0x3D9:
   32.61 -                cgacol=val;
   32.62 +                cga->cgacol = val;
   32.63                  return;
   32.64          }
   32.65  }
   32.66  
   32.67 -uint8_t cga_in(uint16_t addr, void *priv)
   32.68 +uint8_t cga_in(uint16_t addr, void *p)
   32.69  {
   32.70 +        cga_t *cga = (cga_t *)p;
   32.71  //        pclog("CGA_IN %04X\n", addr);
   32.72          switch (addr)
   32.73          {
   32.74                  case 0x3D4:
   32.75 -                return crtcreg;
   32.76 +                return cga->crtcreg;
   32.77                  case 0x3D5:
   32.78 -                return crtc[crtcreg];
   32.79 +                return cga->crtc[cga->crtcreg];
   32.80                  case 0x3DA:
   32.81 -                return cgastat;
   32.82 +                return cga->cgastat;
   32.83          }
   32.84          return 0xFF;
   32.85  }
   32.86  
   32.87 -extern uint8_t charbuffer[256];
   32.88 -
   32.89 -void cga_write(uint32_t addr, uint8_t val, void *priv)
   32.90 +void cga_write(uint32_t addr, uint8_t val, void *p)
   32.91  {
   32.92 +        cga_t *cga = (cga_t *)p;
   32.93  //        pclog("CGA_WRITE %04X %02X\n", addr, val);
   32.94 -        vram[addr&0x3FFF]=val;
   32.95 -        charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = val;
   32.96 -        charbuffer[(((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val;
   32.97 +        cga->vram[addr & 0x3fff] = val;
   32.98 +        cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = val;
   32.99 +        cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val;
  32.100          cycles -= 4;
  32.101  }
  32.102  
  32.103 -uint8_t cga_read(uint32_t addr, void *priv)
  32.104 +uint8_t cga_read(uint32_t addr, void *p)
  32.105  {
  32.106 +        cga_t *cga = (cga_t *)p;
  32.107          cycles -= 4;        
  32.108 -        charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = vram[addr&0x3FFF];
  32.109 -        charbuffer[(((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc) | 1] = vram[addr&0x3FFF];
  32.110 +        cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = cga->vram[addr & 0x3fff];
  32.111 +        cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = cga->vram[addr & 0x3fff];
  32.112  //        pclog("CGA_READ %04X\n", addr);
  32.113 -        return vram[addr&0x3FFF];
  32.114 +        return cga->vram[addr & 0x3fff];
  32.115  }
  32.116  
  32.117 -void cga_recalctimings()
  32.118 +void cga_recalctimings(cga_t *cga)
  32.119  {
  32.120 +        double disptime;
  32.121  	double _dispontime, _dispofftime;
  32.122 -        pclog("Recalc - %i %i %i\n", crtc[0], crtc[1], cgamode & 1);
  32.123 -        if (cgamode&1)
  32.124 +        pclog("Recalc - %i %i %i\n", cga->crtc[0], cga->crtc[1], cga->cgamode & 1);
  32.125 +        if (cga->cgamode & 1)
  32.126          {
  32.127 -                disptime=crtc[0]+1;
  32.128 -                _dispontime=crtc[1];
  32.129 +                disptime = cga->crtc[0] + 1;
  32.130 +                _dispontime = cga->crtc[1];
  32.131          }
  32.132          else
  32.133          {
  32.134 -                disptime=(crtc[0]+1)<<1;
  32.135 -                _dispontime=crtc[1]<<1;
  32.136 +                disptime = (cga->crtc[0] + 1) << 1;
  32.137 +                _dispontime = cga->crtc[1] << 1;
  32.138          }
  32.139 -        _dispofftime=disptime-_dispontime;
  32.140 +        _dispofftime = disptime - _dispontime;
  32.141  //        printf("%i %f %f %f  %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
  32.142 -        _dispontime*=CGACONST;
  32.143 -        _dispofftime*=CGACONST;
  32.144 +        _dispontime *= CGACONST;
  32.145 +        _dispofftime *= CGACONST;
  32.146  //        printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
  32.147 -	dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  32.148 -	dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  32.149 +	cga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  32.150 +	cga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  32.151  }
  32.152  
  32.153 -static int linepos,displine;
  32.154 -static int sc,vc;
  32.155 -static int cgadispon;
  32.156 -static int con,coff,cursoron,cgablink;
  32.157 -static int vsynctime,vadj;
  32.158 -static uint16_t ma,maback;
  32.159 -static int oddeven = 0;
  32.160 -
  32.161  static int ntsc_col[8][8]=
  32.162  {
  32.163          {0,0,0,0,0,0,0,0}, /*Black*/
  32.164 @@ -117,326 +122,331 @@
  32.165          {1,1,1,1,1,1,1,1}  /*White*/
  32.166  };
  32.167  
  32.168 -int i_filt[8],q_filt[8];
  32.169 -
  32.170 -
  32.171 -void cga_poll()
  32.172 +void cga_poll(void *p)
  32.173  {
  32.174 -        uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF;
  32.175 +        cga_t *cga = (cga_t *)p;
  32.176 +        uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff;
  32.177          int drawcursor;
  32.178 -        int x,c;
  32.179 +        int x, c;
  32.180          int oldvc;
  32.181 -        uint8_t chr,attr;
  32.182 +        uint8_t chr, attr;
  32.183          uint16_t dat;
  32.184          int cols[4];
  32.185          int col;
  32.186          int oldsc;
  32.187 -        int y_buf[8]={0,0,0,0,0,0,0,0},y_val,y_tot;
  32.188 -        int i_buf[8]={0,0,0,0,0,0,0,0},i_val,i_tot;
  32.189 -        int q_buf[8]={0,0,0,0,0,0,0,0},q_val,q_tot;
  32.190 -        int r,g,b;
  32.191 -        if (!linepos)
  32.192 +        int y_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, y_val, y_tot;
  32.193 +        int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_tot;
  32.194 +        int q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot;
  32.195 +        int r, g, b;
  32.196 +        if (!cga->linepos)
  32.197          {
  32.198 -                vidtime+=dispofftime;
  32.199 -                cgastat|=1;
  32.200 -                linepos=1;
  32.201 -                oldsc=sc;
  32.202 -                if ((crtc[8] & 3) == 3) 
  32.203 -                   sc = ((sc << 1) + oddeven) & 7;
  32.204 -                if (cgadispon)
  32.205 +                cga->vidtime += cga->dispofftime;
  32.206 +                cga->cgastat |= 1;
  32.207 +                cga->linepos = 1;
  32.208 +                oldsc = cga->sc;
  32.209 +                if ((cga->crtc[8] & 3) == 3) 
  32.210 +                   cga->sc = ((cga->sc << 1) + cga->oddeven) & 7;
  32.211 +                if (cga->cgadispon)
  32.212                  {
  32.213 -                        if (displine<firstline)
  32.214 +                        if (cga->displine < cga->firstline)
  32.215                          {
  32.216 -                                firstline=displine;
  32.217 +                                cga->firstline = cga->displine;
  32.218  //                                printf("Firstline %i\n",firstline);
  32.219                          }
  32.220 -                        lastline=displine;
  32.221 -                        for (c=0;c<8;c++)
  32.222 +                        cga->lastline = cga->displine;
  32.223 +                        for (c = 0; c < 8; c++)
  32.224                          {
  32.225 -                                if ((cgamode&0x12)==0x12)
  32.226 +                                if ((cga->cgamode & 0x12) == 0x12)
  32.227                                  {
  32.228 -                                        buffer->line[displine][c]=0;
  32.229 -                                        if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
  32.230 -                                        else           buffer->line[displine][c+(crtc[1]<<4)+8]=0;
  32.231 +                                        buffer->line[cga->displine][c] = 0;
  32.232 +                                        if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = 0;
  32.233 +                                        else                  buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = 0;
  32.234                                  }
  32.235                                  else
  32.236                                  {
  32.237 -                                        buffer->line[displine][c]=(cgacol&15)+16;
  32.238 -                                        if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16;
  32.239 -                                        else           buffer->line[displine][c+(crtc[1]<<4)+8]=(cgacol&15)+16;
  32.240 +                                        buffer->line[cga->displine][c] = (cga->cgacol & 15) + 16;
  32.241 +                                        if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16;
  32.242 +                                        else                  buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16;
  32.243                                  }
  32.244                          }
  32.245 -                        if (cgamode&1)
  32.246 +                        if (cga->cgamode & 1)
  32.247                          {
  32.248 -                                for (x=0;x<crtc[1];x++)
  32.249 +                                for (x = 0; x < cga->crtc[1]; x++)
  32.250                                  {
  32.251 -                                        chr=charbuffer[x<<1];
  32.252 -                                        attr=charbuffer[(x<<1)+1];
  32.253 -                                        drawcursor=((ma==ca) && con && cursoron);
  32.254 -                                        if (cgamode&0x20)
  32.255 +                                        chr = cga->charbuffer[x << 1];
  32.256 +                                        attr = cga->charbuffer[(x << 1) + 1];
  32.257 +                                        drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
  32.258 +                                        if (cga->cgamode & 0x20)
  32.259                                          {
  32.260 -                                                cols[1]=(attr&15)+16;
  32.261 -                                                cols[0]=((attr>>4)&7)+16;
  32.262 -                                                if ((cgablink&8) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
  32.263 +                                                cols[1] = (attr & 15) + 16;
  32.264 +                                                cols[0] = ((attr >> 4) & 7) + 16;
  32.265 +                                                if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) 
  32.266 +                                                        cols[1] = cols[0];
  32.267                                          }
  32.268                                          else
  32.269                                          {
  32.270 -                                                cols[1]=(attr&15)+16;
  32.271 -                                                cols[0]=(attr>>4)+16;
  32.272 +                                                cols[1] = (attr & 15) + 16;
  32.273 +                                                cols[0] = (attr >> 4) + 16;
  32.274                                          }
  32.275                                          if (drawcursor)
  32.276                                          {
  32.277 -                                                for (c=0;c<8;c++)
  32.278 -                                                    buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15;
  32.279 +                                                for (c = 0; c < 8; c++)
  32.280 +                                                    buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
  32.281                                          }
  32.282                                          else
  32.283                                          {
  32.284 -                                                for (c=0;c<8;c++)
  32.285 -                                                    buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
  32.286 +                                                for (c = 0; c < 8; c++)
  32.287 +                                                    buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
  32.288                                          }
  32.289 -                                        ma++;
  32.290 +                                        cga->ma++;
  32.291                                  }
  32.292                          }
  32.293 -                        else if (!(cgamode&2))
  32.294 +                        else if (!(cga->cgamode & 2))
  32.295                          {
  32.296 -                                for (x=0;x<crtc[1];x++)
  32.297 +                                for (x = 0; x < cga->crtc[1]; x++)
  32.298                                  {
  32.299 -                                        chr=vram[((ma<<1)&0x3FFF)];
  32.300 -                                        attr=vram[(((ma<<1)+1)&0x3FFF)];
  32.301 -                                        drawcursor=((ma==ca) && con && cursoron);
  32.302 -                                        if (cgamode&0x20)
  32.303 +                                        chr  = cga->vram[((cga->ma << 1) & 0x3fff)];
  32.304 +                                        attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)];
  32.305 +                                        drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
  32.306 +                                        if (cga->cgamode & 0x20)
  32.307                                          {
  32.308 -                                                cols[1]=(attr&15)+16;
  32.309 -                                                cols[0]=((attr>>4)&7)+16;
  32.310 -                                                if ((cgablink&8) && (attr&0x80)) cols[1]=cols[0];
  32.311 +                                                cols[1] = (attr & 15) + 16;
  32.312 +                                                cols[0] = ((attr >> 4) & 7) + 16;
  32.313 +                                                if ((cga->cgablink & 8) && (attr & 0x80)) cols[1] = cols[0];
  32.314                                          }
  32.315                                          else
  32.316                                          {
  32.317 -                                                cols[1]=(attr&15)+16;
  32.318 -                                                cols[0]=(attr>>4)+16;
  32.319 +                                                cols[1] = (attr & 15) + 16;
  32.320 +                                                cols[0] = (attr >> 4) + 16;
  32.321                                          }
  32.322 -                                        ma++;
  32.323 +                                        cga->ma++;
  32.324                                          if (drawcursor)
  32.325                                          {
  32.326 -                                                for (c=0;c<8;c++)
  32.327 -                                                    buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15;
  32.328 +                                                for (c = 0; c < 8; c++)
  32.329 +                                                    buffer->line[cga->displine][(x << 4)+(c << 1) + 8] = buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
  32.330                                          }
  32.331                                          else
  32.332                                          {
  32.333 -                                                for (c=0;c<8;c++)
  32.334 -                                                    buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
  32.335 +                                                for (c = 0; c < 8; c++)
  32.336 +                                                    buffer->line[cga->displine][(x << 4) + (c << 1) + 8] = buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
  32.337                                          }
  32.338                                  }
  32.339                          }
  32.340 -                        else if (!(cgamode&16))
  32.341 +                        else if (!(cga->cgamode & 16))
  32.342                          {
  32.343 -                                cols[0]=(cgacol&15)|16;
  32.344 -                                col=(cgacol&16)?24:16;
  32.345 -                                if (cgamode&4)
  32.346 +                                cols[0] = (cga->cgacol & 15) | 16;
  32.347 +                                col = (cga->cgacol & 16) ? 24 : 16;
  32.348 +                                if (cga->cgamode & 4)
  32.349                                  {
  32.350 -                                        cols[1]=col|3;
  32.351 -                                        cols[2]=col|4;
  32.352 -                                        cols[3]=col|7;
  32.353 +                                        cols[1] = col | 3;
  32.354 +                                        cols[2] = col | 4;
  32.355 +                                        cols[3] = col | 7;
  32.356                                  }
  32.357 -                                else if (cgacol&32)
  32.358 +                                else if (cga->cgacol & 32)
  32.359                                  {
  32.360 -                                        cols[1]=col|3;
  32.361 -                                        cols[2]=col|5;
  32.362 -                                        cols[3]=col|7;
  32.363 +                                        cols[1] = col | 3;
  32.364 +                                        cols[2] = col | 5;
  32.365 +                                        cols[3] = col | 7;
  32.366                                  }
  32.367                                  else
  32.368                                  {
  32.369 -                                        cols[1]=col|2;
  32.370 -                                        cols[2]=col|4;
  32.371 -                                        cols[3]=col|6;
  32.372 +                                        cols[1] = col | 2;
  32.373 +                                        cols[2] = col | 4;
  32.374 +                                        cols[3] = col | 6;
  32.375                                  }
  32.376 -                                for (x=0;x<crtc[1];x++)
  32.377 +                                for (x = 0; x < cga->crtc[1]; x++)
  32.378                                  {
  32.379 -                                        dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
  32.380 -                                        ma++;
  32.381 -                                        for (c=0;c<8;c++)
  32.382 +                                        dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
  32.383 +                                        cga->ma++;
  32.384 +                                        for (c = 0; c < 8; c++)
  32.385                                          {
  32.386 -                                                buffer->line[displine][(x<<4)+(c<<1)+8]=
  32.387 -                                                  buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
  32.388 -                                                dat<<=2;
  32.389 +                                                buffer->line[cga->displine][(x << 4) + (c << 1) + 8] =
  32.390 +                                                  buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
  32.391 +                                                dat <<= 2;
  32.392                                          }
  32.393                                  }
  32.394                          }
  32.395                          else
  32.396                          {
  32.397 -                                cols[0]=0; cols[1]=(cgacol&15)+16;
  32.398 -                                for (x=0;x<crtc[1];x++)
  32.399 +                                cols[0] = 0; cols[1] = (cga->cgacol & 15) + 16;
  32.400 +                                for (x = 0; x < cga->crtc[1]; x++)
  32.401                                  {
  32.402 -                                        dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
  32.403 -                                        ma++;
  32.404 -                                        for (c=0;c<16;c++)
  32.405 +                                        dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
  32.406 +                                        cga->ma++;
  32.407 +                                        for (c = 0; c < 16; c++)
  32.408                                          {
  32.409 -                                                buffer->line[displine][(x<<4)+c+8]=cols[dat>>15];
  32.410 -                                                dat<<=1;
  32.411 +                                                buffer->line[cga->displine][(x << 4) + c + 8] = cols[dat >> 15];
  32.412 +                                                dat <<= 1;
  32.413                                          }
  32.414                                  }
  32.415                          }
  32.416                  }
  32.417                  else
  32.418                  {
  32.419 -                        cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16;
  32.420 -                        if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
  32.421 -                        else           hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
  32.422 +                        cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16;
  32.423 +                        if (cga->cgamode & 1) hline(buffer, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]);
  32.424 +                        else                  hline(buffer, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]);
  32.425                  }
  32.426  
  32.427 -                if (cgamode&1) x=(crtc[1]<<3)+16;
  32.428 -                else           x=(crtc[1]<<4)+16;
  32.429 +                if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
  32.430 +                else                  x = (cga->crtc[1] << 4) + 16;
  32.431                  if (cga_comp)
  32.432                  {
  32.433 -                        for (c=0;c<x;c++)
  32.434 +                        for (c = 0; c < x; c++)
  32.435                          {
  32.436 -                                y_buf[(c<<1)&6]=ntsc_col[buffer->line[displine][c]&7][(c<<1)&6]?0x6000:0;
  32.437 -                                y_buf[(c<<1)&6]+=(buffer->line[displine][c]&8)?0x3000:0;
  32.438 -                                i_buf[(c<<1)&6]=y_buf[(c<<1)&6]*i_filt[(c<<1)&6];
  32.439 -                                q_buf[(c<<1)&6]=y_buf[(c<<1)&6]*q_filt[(c<<1)&6];
  32.440 -                                y_tot=y_buf[0]+y_buf[1]+y_buf[2]+y_buf[3]+y_buf[4]+y_buf[5]+y_buf[6]+y_buf[7];
  32.441 -                                i_tot=i_buf[0]+i_buf[1]+i_buf[2]+i_buf[3]+i_buf[4]+i_buf[5]+i_buf[6]+i_buf[7];
  32.442 -                                q_tot=q_buf[0]+q_buf[1]+q_buf[2]+q_buf[3]+q_buf[4]+q_buf[5]+q_buf[6]+q_buf[7];
  32.443 +                                y_buf[(c << 1) & 6] = ntsc_col[buffer->line[cga->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 0;
  32.444 +                                y_buf[(c << 1) & 6] += (buffer->line[cga->displine][c] & 8) ? 0x3000 : 0;
  32.445 +                                i_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * i_filt[(c << 1) & 6];
  32.446 +                                q_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * q_filt[(c << 1) & 6];
  32.447 +                                y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
  32.448 +                                i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
  32.449 +                                q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
  32.450  
  32.451 -                                y_val=y_tot>>10;
  32.452 -                                if (y_val>255) y_val=255;
  32.453 -                                y_val<<=16;
  32.454 -                                i_val=i_tot>>12;
  32.455 -                                if (i_val>39041) i_val=39041;
  32.456 -                                if (i_val<-39041) i_val=-39041;
  32.457 -                                q_val=q_tot>>12;
  32.458 -                                if (q_val>34249) q_val=34249;
  32.459 -                                if (q_val<-34249) q_val=-34249;
  32.460 +                                y_val = y_tot >> 10;
  32.461 +                                if (y_val > 255) y_val = 255;
  32.462 +                                y_val <<= 16;
  32.463 +                                i_val = i_tot >> 12;
  32.464 +                                if (i_val >  39041) i_val =  39041;
  32.465 +                                if (i_val < -39041) i_val = -39041;
  32.466 +                                q_val = q_tot >> 12;
  32.467 +                                if (q_val >  34249) q_val =  34249;
  32.468 +                                if (q_val < -34249) q_val = -34249;
  32.469  
  32.470 -                                r=(y_val+249*i_val+159*q_val)>>16;
  32.471 -                                g=(y_val-70*i_val-166*q_val)>>16;
  32.472 -                                b=(y_val-283*i_val+436*q_val)>>16;
  32.473 +                                r = (y_val + 249*i_val + 159*q_val) >> 16;
  32.474 +                                g = (y_val -  70*i_val - 166*q_val) >> 16;
  32.475 +                                b = (y_val - 283*i_val + 436*q_val) >> 16;
  32.476  
  32.477 -                                y_buf[((c<<1)&6)+1]=ntsc_col[buffer->line[displine][c]&7][((c<<1)&6)+1]?0x6000:0;
  32.478 -                                y_buf[((c<<1)&6)+1]+=(buffer->line[displine][c]&8)?0x3000:0;
  32.479 -                                i_buf[((c<<1)&6)+1]=y_buf[((c<<1)&6)+1]*i_filt[((c<<1)&6)+1];
  32.480 -                                q_buf[((c<<1)&6)+1]=y_buf[((c<<1)&6)+1]*q_filt[((c<<1)&6)+1];
  32.481 -                                y_tot=y_buf[0]+y_buf[1]+y_buf[2]+y_buf[3]+y_buf[4]+y_buf[5]+y_buf[6]+y_buf[7];
  32.482 -                                i_tot=i_buf[0]+i_buf[1]+i_buf[2]+i_buf[3]+i_buf[4]+i_buf[5]+i_buf[6]+i_buf[7];
  32.483 -                                q_tot=q_buf[0]+q_buf[1]+q_buf[2]+q_buf[3]+q_buf[4]+q_buf[5]+q_buf[6]+q_buf[7];
  32.484 +                                y_buf[((c << 1) & 6) + 1] = ntsc_col[buffer->line[cga->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 0;
  32.485 +                                y_buf[((c << 1) & 6) + 1] += (buffer->line[cga->displine][c] & 8) ? 0x3000 : 0;
  32.486 +                                i_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * i_filt[((c << 1) & 6) + 1];
  32.487 +                                q_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * q_filt[((c << 1) & 6) + 1];
  32.488 +                                y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
  32.489 +                                i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
  32.490 +                                q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
  32.491  
  32.492 -                                y_val=y_tot>>10;
  32.493 -                                if (y_val>255) y_val=255;
  32.494 -                                y_val<<=16;
  32.495 -                                i_val=i_tot>>12;
  32.496 -                                if (i_val>39041) i_val=39041;
  32.497 -                                if (i_val<-39041) i_val=-39041;
  32.498 -                                q_val=q_tot>>12;
  32.499 -                                if (q_val>34249) q_val=34249;
  32.500 -                                if (q_val<-34249) q_val=-34249;
  32.501 +                                y_val = y_tot >> 10;
  32.502 +                                if (y_val > 255) y_val = 255;
  32.503 +                                y_val <<= 16;
  32.504 +                                i_val = i_tot >> 12;
  32.505 +                                if (i_val >  39041) i_val =  39041;
  32.506 +                                if (i_val < -39041) i_val = -39041;
  32.507 +                                q_val = q_tot >> 12;
  32.508 +                                if (q_val >  34249) q_val =  34249;
  32.509 +                                if (q_val < -34249) q_val = -34249;
  32.510  
  32.511 -                                r+=(y_val+249*i_val+159*q_val)>>16;
  32.512 -                                g+=(y_val-70*i_val-166*q_val)>>16;
  32.513 -                                b+=(y_val-283*i_val+436*q_val)>>16;
  32.514 -                                if (r>511) r=511;
  32.515 -                                if (g>511) g=511;
  32.516 -                                if (b>511) b=511;
  32.517 +                                r = (y_val + 249*i_val + 159*q_val) >> 16;
  32.518 +                                g = (y_val -  70*i_val - 166*q_val) >> 16;
  32.519 +                                b = (y_val - 283*i_val + 436*q_val) >> 16;
  32.520 +                                if (r > 511) r = 511;
  32.521 +                                if (g > 511) g = 511;
  32.522 +                                if (b > 511) b = 511;
  32.523  
  32.524 -                                ((uint32_t *)buffer32->line[displine])[c]=makecol32(r/2,g/2,b/2);
  32.525 +                                ((uint32_t *)buffer32->line[cga->displine])[c] = makecol32(r / 2, g / 2, b / 2);
  32.526                          }
  32.527                  }
  32.528  
  32.529 -                sc=oldsc;
  32.530 -                if (vc==crtc[7] && !sc)
  32.531 -                   cgastat|=8;
  32.532 -                displine++;
  32.533 -                if (displine>=360) displine=0;
  32.534 +                cga->sc = oldsc;
  32.535 +                if (cga->vc == cga->crtc[7] && !cga->sc)
  32.536 +                   cga->cgastat |= 8;
  32.537 +                cga->displine++;
  32.538 +                if (cga->displine >= 360) 
  32.539 +                        cga->displine = 0;
  32.540          }
  32.541          else
  32.542          {
  32.543 -                vidtime+=dispontime;
  32.544 -                if (cgadispon) cgastat&=~1;
  32.545 -                linepos=0;
  32.546 -                if (vsynctime)
  32.547 +                cga->vidtime += cga->dispontime;
  32.548 +                if (cga->cgadispon) cga->cgastat &= ~1;
  32.549 +                cga->linepos = 0;
  32.550 +                if (cga->vsynctime)
  32.551                  {
  32.552 -                        vsynctime--;
  32.553 -                        if (!vsynctime)
  32.554 -                           cgastat&=~8;
  32.555 +                        cga->vsynctime--;
  32.556 +                        if (!cga->vsynctime)
  32.557 +                           cga->cgastat &= ~8;
  32.558                  }
  32.559 -                if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; }
  32.560 -                if ((crtc[8] & 3) == 3 && sc == (crtc[9] >> 1))
  32.561 -                   maback = ma;
  32.562 -                if (vadj)
  32.563 +                if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) 
  32.564 +                { 
  32.565 +                        cga->con = 0; 
  32.566 +                        cga->coff = 1; 
  32.567 +                }
  32.568 +                if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1))
  32.569 +                   cga->maback = cga->ma;
  32.570 +                if (cga->vadj)
  32.571                  {
  32.572 -                        sc++;
  32.573 -                        sc&=31;
  32.574 -                        ma=maback;
  32.575 -                        vadj--;
  32.576 -                        if (!vadj)
  32.577 +                        cga->sc++;
  32.578 +                        cga->sc &= 31;
  32.579 +                        cga->ma = cga->maback;
  32.580 +                        cga->vadj--;
  32.581 +                        if (!cga->vadj)
  32.582                          {
  32.583 -                                cgadispon=1;
  32.584 -                                ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
  32.585 -                                sc=0;
  32.586 +                                cga->cgadispon = 1;
  32.587 +                                cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
  32.588 +                                cga->sc = 0;
  32.589                          }
  32.590                  }
  32.591 -                else if (sc==crtc[9])
  32.592 +                else if (cga->sc == cga->crtc[9])
  32.593                  {
  32.594 -                        maback=ma;
  32.595 -                        sc=0;
  32.596 -                        oldvc=vc;
  32.597 -                        vc++;
  32.598 -                        vc&=127;
  32.599 +                        cga->maback = cga->ma;
  32.600 +                        cga->sc = 0;
  32.601 +                        oldvc = cga->vc;
  32.602 +                        cga->vc++;
  32.603 +                        cga->vc &= 127;
  32.604  
  32.605 -                        if (vc==crtc[6]) cgadispon=0;
  32.606 +                        if (cga->vc == cga->crtc[6]) 
  32.607 +                                cga->cgadispon = 0;
  32.608  
  32.609 -                        if (oldvc==crtc[4])
  32.610 +                        if (oldvc == cga->crtc[4])
  32.611                          {
  32.612 -                                vc=0;
  32.613 -                                vadj=crtc[5];
  32.614 -                                if (!vadj) cgadispon=1;
  32.615 -                                if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
  32.616 -                                if ((crtc[10]&0x60)==0x20) cursoron=0;
  32.617 -                                else                       cursoron=cgablink&8;
  32.618 +                                cga->vc = 0;
  32.619 +                                cga->vadj = cga->crtc[5];
  32.620 +                                if (!cga->vadj) cga->cgadispon = 1;
  32.621 +                                if (!cga->vadj) cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
  32.622 +                                if ((cga->crtc[10] & 0x60) == 0x20) cga->cursoron = 0;
  32.623 +                                else                                cga->cursoron = cga->cgablink & 8;
  32.624                          }
  32.625  
  32.626 -                        if (vc==crtc[7])
  32.627 +                        if (cga->vc == cga->crtc[7])
  32.628                          {
  32.629 -                                cgadispon=0;
  32.630 -                                displine=0;
  32.631 -                                vsynctime=(crtc[3]>>4)+1;
  32.632 -                                if (crtc[7])
  32.633 +                                cga->cgadispon = 0;
  32.634 +                                cga->displine = 0;
  32.635 +                                cga->vsynctime = (cga->crtc[3] >> 4) + 1;
  32.636 +                                if (cga->crtc[7])
  32.637                                  {
  32.638 -                                        if (cgamode&1) x=(crtc[1]<<3)+16;
  32.639 -                                        else           x=(crtc[1]<<4)+16;
  32.640 -                                        lastline++;
  32.641 -                                        if (x!=xsize || (lastline-firstline)!=ysize)
  32.642 +                                        if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
  32.643 +                                        else                  x = (cga->crtc[1] << 4) + 16;
  32.644 +                                        cga->lastline++;
  32.645 +                                        if (x != xsize || (cga->lastline - cga->firstline) != ysize)
  32.646                                          {
  32.647 -                                                xsize=x;
  32.648 -                                                ysize=lastline-firstline;
  32.649 -                                                if (xsize<64) xsize=656;
  32.650 -                                                if (ysize<32) ysize=200;
  32.651 -                                                updatewindowsize(xsize,(ysize<<1)+16);
  32.652 +                                                xsize = x;
  32.653 +                                                ysize = cga->lastline - cga->firstline;
  32.654 +                                                if (xsize < 64) xsize = 656;
  32.655 +                                                if (ysize < 32) ysize = 200;
  32.656 +                                                updatewindowsize(xsize, (ysize << 1) + 16);
  32.657                                          }
  32.658                                          
  32.659  startblit();
  32.660                                          if (cga_comp) 
  32.661 -                                           video_blit_memtoscreen(0, firstline-4, 0, (lastline-firstline)+8, xsize, (lastline-firstline)+8);
  32.662 +                                           video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8);
  32.663                                          else          
  32.664 -                                           video_blit_memtoscreen_8(0, firstline-4, xsize, (lastline-firstline)+8);
  32.665 -                                        if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
  32.666 -                                        readflash=0;
  32.667 +                                           video_blit_memtoscreen_8(0, cga->firstline - 4, xsize, (cga->lastline - cga->firstline) + 8);
  32.668 +                                        if (readflash) rectfill(screen, winsizex - 40, 8, winsizex - 8, 14, 0xffffffff);
  32.669 +                                        readflash = 0;
  32.670                                          frames++;
  32.671  endblit();
  32.672                                          video_res_x = xsize - 16;
  32.673                                          video_res_y = ysize;
  32.674 -                                        if (cgamode & 1)
  32.675 +                                        if (cga->cgamode & 1)
  32.676                                          {
  32.677                                                  video_res_x /= 8;
  32.678 -                                                video_res_y /= crtc[9] + 1;
  32.679 +                                                video_res_y /= cga->crtc[9] + 1;
  32.680                                                  video_bpp = 0;
  32.681                                          }
  32.682 -                                        else if (!(cgamode & 2))
  32.683 +                                        else if (!(cga->cgamode & 2))
  32.684                                          {
  32.685                                                  video_res_x /= 16;
  32.686 -                                                video_res_y /= crtc[9] + 1;
  32.687 +                                                video_res_y /= cga->crtc[9] + 1;
  32.688                                                  video_bpp = 0;
  32.689                                          }
  32.690 -                                        else if (!(cgamode&16))
  32.691 +                                        else if (!(cga->cgamode & 16))
  32.692                                          {
  32.693                                                  video_res_x /= 2;
  32.694                                                  video_bpp = 2;
  32.695 @@ -446,59 +456,72 @@
  32.696                                                  video_bpp = 1;
  32.697                                          }
  32.698                                  }
  32.699 -                                firstline=1000;
  32.700 -                                lastline=0;
  32.701 -                                cgablink++;
  32.702 -                                oddeven ^= 1;
  32.703 +                                cga->firstline = 1000;
  32.704 +                                cga->lastline = 0;
  32.705 +                                cga->cgablink++;
  32.706 +                                cga->oddeven ^= 1;
  32.707                          }
  32.708                  }
  32.709                  else
  32.710                  {
  32.711 -                        sc++;
  32.712 -                        sc&=31;
  32.713 -                        ma=maback;
  32.714 +                        cga->sc++;
  32.715 +                        cga->sc &= 31;
  32.716 +                        cga->ma = cga->maback;
  32.717                  }
  32.718 -                if ((sc==(crtc[10]&31) || ((crtc[8]&3)==3 && sc==((crtc[10]&31)>>1)))) con=1;
  32.719 -                if (cgadispon && (cgamode&1))
  32.720 +                if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) 
  32.721 +                        cga->con = 1;
  32.722 +                if (cga->cgadispon && (cga->cgamode & 1))
  32.723                  {
  32.724 -                        for (x=0;x<(crtc[1]<<1);x++)
  32.725 -                            charbuffer[x]=vram[(((ma<<1)+x)&0x3FFF)];
  32.726 +                        for (x = 0; x < (cga->crtc[1] << 1); x++)
  32.727 +                            cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)];
  32.728                  }
  32.729          }
  32.730  }
  32.731  
  32.732 +void cga_init(cga_t *cga)
  32.733 +{
  32.734 +}
  32.735  
  32.736 -int cga_init()
  32.737 +void *cga_standalone_init()
  32.738  {
  32.739          int c;
  32.740          int cga_tint = -2;
  32.741 -        for (c=0;c<8;c++)
  32.742 +        cga_t *cga = malloc(sizeof(cga_t));
  32.743 +        memset(cga, 0, sizeof(cga_t));
  32.744 +
  32.745 +        cga->vram = malloc(0x4000);
  32.746 +                
  32.747 +        for (c = 0; c < 8; c++)
  32.748          {
  32.749 -                i_filt[c]=512.0*cos((3.14*(cga_tint+c*4)/16.0) - 33.0/180.0);
  32.750 -                q_filt[c]=512.0*sin((3.14*(cga_tint+c*4)/16.0) - 33.0/180.0);
  32.751 +                i_filt[c] = 512.0 * cos((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0);
  32.752 +                q_filt[c] = 512.0 * sin((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0);
  32.753          }
  32.754 -        mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  NULL);
  32.755 -        return 0;
  32.756 +        timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
  32.757 +        mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  cga);
  32.758 +        io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);
  32.759 +        return cga;
  32.760  }
  32.761  
  32.762 -GFXCARD vid_cga =
  32.763 +void cga_close(void *p)
  32.764  {
  32.765 -        cga_init,
  32.766 -        /*IO at 3Cx/3Dx*/
  32.767 -        cga_out,
  32.768 -        cga_in,
  32.769 -        /*IO at 3Ax/3Bx*/
  32.770 -        video_out_null,
  32.771 -        video_in_null,
  32.772 +        cga_t *cga = (cga_t *)p;
  32.773  
  32.774 -        cga_poll,
  32.775 -        cga_recalctimings,
  32.776 +        free(cga->vram);
  32.777 +        free(cga);
  32.778 +}
  32.779  
  32.780 -        video_write_null,
  32.781 -        video_write_null,
  32.782 -        cga_write,
  32.783 +void cga_speed_changed(void *p)
  32.784 +{
  32.785 +        cga_t *cga = (cga_t *)p;
  32.786 +        
  32.787 +        cga_recalctimings(cga);
  32.788 +}
  32.789  
  32.790 -        video_read_null,
  32.791 -        video_read_null,
  32.792 -        cga_read
  32.793 +device_t cga_device =
  32.794 +{
  32.795 +        "CGA",
  32.796 +        cga_standalone_init,
  32.797 +        cga_close,
  32.798 +        cga_speed_changed,
  32.799 +        NULL
  32.800  };
    33.1 --- a/src/vid_cga.h	Tue Jun 04 20:52:17 2013 +0100
    33.2 +++ b/src/vid_cga.h	Mon Jun 24 20:42:35 2013 +0100
    33.3 @@ -1,7 +1,38 @@
    33.4 -int     cga_init();
    33.5 -void    cga_out(uint16_t addr, uint8_t val, void *priv);
    33.6 -uint8_t cga_in(uint16_t addr, void *priv);
    33.7 -void    cga_poll();
    33.8 -void    cga_write(uint32_t addr, uint8_t val, void *priv);
    33.9 -uint8_t cga_read(uint32_t addr, void *priv);
   33.10 -void    cga_recalctimings();
   33.11 +typedef struct cga_t
   33.12 +{
   33.13 +        int crtcreg;
   33.14 +        uint8_t crtc[32];
   33.15 +        
   33.16 +        uint8_t cgastat;
   33.17 +        
   33.18 +        uint8_t cgamode, cgacol;
   33.19 +
   33.20 +        int linepos, displine;
   33.21 +        int sc, vc;
   33.22 +        int cgadispon;
   33.23 +        int con, coff, cursoron, cgablink;
   33.24 +        int vsynctime, vadj;
   33.25 +        uint16_t ma, maback;
   33.26 +        int oddeven;
   33.27 +
   33.28 +        int dispontime, dispofftime;
   33.29 +        int vidtime;
   33.30 +        
   33.31 +        int firstline, lastline;
   33.32 +        
   33.33 +        int drawcursor;
   33.34 +        
   33.35 +        uint8_t *vram;
   33.36 +        
   33.37 +        uint8_t charbuffer[256];
   33.38 +} cga_t;
   33.39 +
   33.40 +void    cga_init(cga_t *cga);
   33.41 +void    cga_out(uint16_t addr, uint8_t val, void *p);
   33.42 +uint8_t cga_in(uint16_t addr, void *p);
   33.43 +void    cga_write(uint32_t addr, uint8_t val, void *p);
   33.44 +uint8_t cga_read(uint32_t addr, void *p);
   33.45 +void    cga_recalctimings(cga_t *cga);
   33.46 +void    cga_poll(void *p);
   33.47 +
   33.48 +extern device_t cga_device;
    34.1 --- a/src/vid_cl5429.c	Tue Jun 04 20:52:17 2013 +0100
    34.2 +++ b/src/vid_cl5429.c	Mon Jun 24 20:42:35 2013 +0100
    34.3 @@ -1,14 +1,19 @@
    34.4  /*Cirrus Logic CL-GD5429 emulation*/
    34.5 +#include <stdlib.h>
    34.6  #include "ibm.h"
    34.7 +#include "device.h"
    34.8  #include "io.h"
    34.9  #include "mem.h"
   34.10  #include "video.h"
   34.11 +#include "vid_cl5429.h"
   34.12  #include "vid_svga.h"
   34.13  #include "vid_svga_render.h"
   34.14  #include "vid_unk_ramdac.h"
   34.15  
   34.16 -struct
   34.17 +typedef struct gd5429_t
   34.18  {
   34.19 +        svga_t svga;
   34.20 +        
   34.21          uint32_t bank[2];
   34.22  
   34.23          struct
   34.24 @@ -24,60 +29,63 @@
   34.25                  int x_count;
   34.26          } blt;
   34.27  
   34.28 -} gd5429;
   34.29 +} gd5429_t;
   34.30  
   34.31 -void gd5429_write(uint32_t addr, uint8_t val, void *priv);
   34.32 -uint8_t gd5429_read(uint32_t addr, void *priv);
   34.33 +void gd5429_write(uint32_t addr, uint8_t val, void *p);
   34.34 +uint8_t gd5429_read(uint32_t addr, void *p);
   34.35  
   34.36 -void gd5429_mmio_write(uint32_t addr, uint8_t val, void *priv);
   34.37 -uint8_t gd5429_mmio_read(uint32_t addr, void *priv);
   34.38 +void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p);
   34.39 +uint8_t gd5429_mmio_read(uint32_t addr, void *p);
   34.40  
   34.41 -void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *priv);
   34.42 -void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *priv);
   34.43 +void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p);
   34.44 +void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p);
   34.45  
   34.46 -void gd5429_recalc_banking();
   34.47 -void gd5429_recalc_mapping();
   34.48 +void gd5429_recalc_banking(gd5429_t *gd5429);
   34.49 +void gd5429_recalc_mapping(gd5429_t *gd5429);
   34.50  
   34.51 -void gd5429_out(uint16_t addr, uint8_t val, void *priv)
   34.52 +void gd5429_out(uint16_t addr, uint8_t val, void *p)
   34.53  {
   34.54 +        gd5429_t *gd5429 = (gd5429_t *)p;
   34.55 +        svga_t *svga = &gd5429->svga;
   34.56          uint8_t old;
   34.57          
   34.58 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   34.59 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
   34.60 +                addr ^= 0x60;
   34.61  
   34.62          pclog("gd5429 out %04X %02X\n", addr, val);
   34.63                  
   34.64          switch (addr)
   34.65          {
   34.66                  case 0x3c4:
   34.67 -                seqaddr = val;
   34.68 +                svga->seqaddr = val;
   34.69                  break;
   34.70                  case 0x3c5:
   34.71 -                if (seqaddr > 5)
   34.72 +                if (svga->seqaddr > 5)
   34.73                  {
   34.74 -                        seqregs[seqaddr & 0x1f] = val;
   34.75 -                        switch (seqaddr & 0x1f)
   34.76 +                        svga->seqregs[svga->seqaddr & 0x1f] = val;
   34.77 +                        switch (svga->seqaddr & 0x1f)
   34.78                          {
   34.79                                  case 0x10: case 0x30: case 0x50: case 0x70:
   34.80                                  case 0x90: case 0xb0: case 0xd0: case 0xf0:
   34.81 -                                svga_hwcursor.x = (val << 3) | ((seqaddr >> 5) & 7);
   34.82 -                                pclog("svga_hwcursor.x = %i\n", svga_hwcursor.x);
   34.83 +                                svga->hwcursor.x = (val << 3) | ((svga->seqaddr >> 5) & 7);
   34.84 +                                pclog("svga->hwcursor.x = %i\n", svga->hwcursor.x);
   34.85                                  break;
   34.86                                  case 0x11: case 0x31: case 0x51: case 0x71:
   34.87                                  case 0x91: case 0xb1: case 0xd1: case 0xf1:
   34.88 -                                svga_hwcursor.y = (val << 3) | ((seqaddr >> 5) & 7);
   34.89 -                                pclog("svga_hwcursor.y = %i\n", svga_hwcursor.y);
   34.90 +                                svga->hwcursor.y = (val << 3) | ((svga->seqaddr >> 5) & 7);
   34.91 +                                pclog("svga->hwcursor.y = %i\n", svga->hwcursor.y);
   34.92                                  break;
   34.93                                  case 0x12:
   34.94 -                                svga_hwcursor.ena = val & 1;
   34.95 -                                pclog("svga_hwcursor.ena = %i\n", svga_hwcursor.ena);
   34.96 +                                svga->hwcursor.ena = val & 1;
   34.97 +                                pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena);
   34.98                                  break;                               
   34.99                                  case 0x13:
  34.100 -                                svga_hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256);
  34.101 -                                pclog("svga_hwcursor.addr = %x\n", svga_hwcursor.addr);
  34.102 +                                svga->hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256);
  34.103 +                                pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr);
  34.104                                  break;                                
  34.105                                  
  34.106                                  case 0x17:
  34.107 -                                gd5429_recalc_mapping();
  34.108 +                                gd5429_recalc_mapping(gd5429);
  34.109                                  break;
  34.110                          }
  34.111                          return;
  34.112 @@ -85,38 +93,38 @@
  34.113                  break;
  34.114  
  34.115                  case 0x3cf:
  34.116 -                if (gdcaddr == 5)
  34.117 +                if (svga->gdcaddr == 5)
  34.118                  {
  34.119 -                        gdcreg[5] = val;
  34.120 -                        if (gdcreg[0xb] & 0x04)
  34.121 -                                writemode = gdcreg[5] & 7;
  34.122 +                        svga->gdcreg[5] = val;
  34.123 +                        if (svga->gdcreg[0xb] & 0x04)
  34.124 +                                svga->writemode = svga->gdcreg[5] & 7;
  34.125                          else
  34.126 -                                writemode = gdcreg[5] & 3;
  34.127 -                        readmode = val & 8;
  34.128 -                        pclog("writemode = %i\n", writemode);
  34.129 +                                svga->writemode = svga->gdcreg[5] & 3;
  34.130 +                        svga->readmode = val & 8;
  34.131 +                        pclog("writemode = %i\n", svga->writemode);
  34.132                          return;
  34.133                  }
  34.134 -                if (gdcaddr == 6)
  34.135 +                if (svga->gdcaddr == 6)
  34.136                  {
  34.137 -                        if ((gdcreg[6] & 0xc) != (val & 0xc))
  34.138 +                        if ((svga->gdcreg[6] & 0xc) != (val & 0xc))
  34.139                          {
  34.140 -                                gdcreg[6] = val;
  34.141 -                                gd5429_recalc_mapping();
  34.142 +                                svga->gdcreg[6] = val;
  34.143 +                                gd5429_recalc_mapping(gd5429);
  34.144                          }
  34.145 -                        gdcreg[6] = val;
  34.146 +                        svga->gdcreg[6] = val;
  34.147                          return;
  34.148                  }
  34.149 -                if (gdcaddr > 8)
  34.150 +                if (svga->gdcaddr > 8)
  34.151                  {
  34.152 -                        gdcreg[gdcaddr & 0x3f] = val;
  34.153 -                        switch (gdcaddr)
  34.154 +                        svga->gdcreg[svga->gdcaddr & 0x3f] = val;
  34.155 +                        switch (svga->gdcaddr)
  34.156                          {
  34.157                                  case 0x09: case 0x0a: case 0x0b:
  34.158 -                                gd5429_recalc_banking();
  34.159 -                                if (gdcreg[0xb] & 0x04)
  34.160 -                                        writemode = gdcreg[5] & 7;
  34.161 +                                gd5429_recalc_banking(gd5429);
  34.162 +                                if (svga->gdcreg[0xb] & 0x04)
  34.163 +                                        svga->writemode = svga->gdcreg[5] & 7;
  34.164                                  else
  34.165 -                                        writemode = gdcreg[5] & 3;
  34.166 +                                        svga->writemode = svga->gdcreg[5] & 3;
  34.167                                  break;
  34.168                          }                        
  34.169                          return;
  34.170 @@ -124,135 +132,145 @@
  34.171                  break;
  34.172                  
  34.173                  case 0x3D4:
  34.174 -                crtcreg = val & 0x3f;
  34.175 +                svga->crtcreg = val & 0x3f;
  34.176                  return;
  34.177                  case 0x3D5:
  34.178 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
  34.179 -                old=crtc[crtcreg];
  34.180 -                crtc[crtcreg]=val;
  34.181 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
  34.182 +                old = svga->crtc[svga->crtcreg];
  34.183 +                svga->crtc[svga->crtcreg] = val;
  34.184  
  34.185 -                if (old!=val)
  34.186 +                if (old != val)
  34.187                  {
  34.188 -                        if (crtcreg<0xE || crtcreg>0x10)
  34.189 +                        if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
  34.190                          {
  34.191 -                                fullchange=changeframecount;
  34.192 -                                svga_recalctimings();
  34.193 +                                fullchange = changeframecount;
  34.194 +                                svga_recalctimings(svga);
  34.195                          }
  34.196                  }
  34.197                  break;
  34.198          }
  34.199 -        svga_out(addr, val, NULL);
  34.200 +        svga_out(addr, val, svga);
  34.201  }
  34.202  
  34.203 -uint8_t gd5429_in(uint16_t addr, void *priv)
  34.204 +uint8_t gd5429_in(uint16_t addr, void *p)
  34.205  {
  34.206 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  34.207 +        gd5429_t *gd5429 = (gd5429_t *)p;
  34.208 +        svga_t *svga = &gd5429->svga;
  34.209 +
  34.210 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3d0) && !(svga->miscout & 1)) 
  34.211 +                addr ^= 0x60;
  34.212          
  34.213          if (addr != 0x3da) pclog("IN gd5429 %04X\n", addr);
  34.214          
  34.215          switch (addr)
  34.216          {
  34.217                  case 0x3c5:
  34.218 -                if (seqaddr > 5)
  34.219 +                if (svga->seqaddr > 5)
  34.220                  {
  34.221 -                        switch (seqaddr)
  34.222 +                        switch (svga->seqaddr)
  34.223                          {
  34.224                                  case 6:
  34.225 -                                return ((seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f;
  34.226 +                                return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f;
  34.227                          }
  34.228 -                        return seqregs[seqaddr & 0x3f];
  34.229 +                        return svga->seqregs[svga->seqaddr & 0x3f];
  34.230                  }
  34.231                  break;
  34.232  
  34.233                  case 0x3cf:
  34.234 -                if (gdcaddr > 8)
  34.235 +                if (svga->gdcaddr > 8)
  34.236                  {
  34.237 -                        return gdcreg[seqaddr & 0x3f];
  34.238 +                        return svga->gdcreg[svga->gdcaddr & 0x3f];
  34.239                  }
  34.240                  break;
  34.241  
  34.242                  case 0x3D4:
  34.243 -                return crtcreg;
  34.244 +                return svga->crtcreg;
  34.245                  case 0x3D5:
  34.246 -                switch (crtcreg)
  34.247 +                switch (svga->crtcreg)
  34.248                  {
  34.249                          case 0x27: /*ID*/
  34.250                          return 0x9c; /*GD5429*/
  34.251                  }
  34.252 -                return crtc[crtcreg];
  34.253 +                return svga->crtc[svga->crtcreg];
  34.254          }
  34.255 -        return svga_in(addr, NULL);
  34.256 +        return svga_in(addr, svga);
  34.257  }
  34.258  
  34.259 -void gd5429_recalc_banking()
  34.260 +void gd5429_recalc_banking(gd5429_t *gd5429)
  34.261  {
  34.262 -        if (gdcreg[0xb] & 0x20)
  34.263 -                gd5429.bank[0] = (gdcreg[0x09] & 0x7f) << 14;
  34.264 +        svga_t *svga = &gd5429->svga;
  34.265 +        
  34.266 +        if (svga->gdcreg[0xb] & 0x20)
  34.267 +                gd5429->bank[0] = (svga->gdcreg[0x09] & 0x7f) << 14;
  34.268          else
  34.269 -                gd5429.bank[0] = gdcreg[0x09] << 12;
  34.270 +                gd5429->bank[0] = svga->gdcreg[0x09] << 12;
  34.271                                  
  34.272 -        if (gdcreg[0xb] & 0x01)
  34.273 +        if (svga->gdcreg[0xb] & 0x01)
  34.274          {
  34.275 -                if (gdcreg[0xb] & 0x20)
  34.276 -                        gd5429.bank[1] = (gdcreg[0x0a] & 0x7f) << 14;
  34.277 +                if (svga->gdcreg[0xb] & 0x20)
  34.278 +                        gd5429->bank[1] = (svga->gdcreg[0x0a] & 0x7f) << 14;
  34.279                  else
  34.280 -                        gd5429.bank[1] = gdcreg[0x0a] << 12;
  34.281 +                        gd5429->bank[1] = svga->gdcreg[0x0a] << 12;
  34.282          }
  34.283          else
  34.284 -                gd5429.bank[1] = gd5429.bank[0] + 0x8000;
  34.285 +                gd5429->bank[1] = gd5429->bank[0] + 0x8000;
  34.286  }
  34.287  
  34.288 -void gd5429_recalc_mapping()
  34.289 +void gd5429_recalc_mapping(gd5429_t *gd5429)
  34.290  {
  34.291 -        mem_removehandler(0xa0000, 0x20000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  NULL);
  34.292 -        mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  34.293 -        mem_removehandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL,  NULL);
  34.294 -        pclog("Write mapping %02X %i\n", gdcreg[6], seqregs[0x17] & 0x04);
  34.295 -        switch (gdcreg[6] & 0x0C)
  34.296 +        svga_t *svga = &gd5429->svga;
  34.297 +        
  34.298 +        mem_removehandler(0xa0000, 0x20000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  gd5429);
  34.299 +        mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  svga);
  34.300 +        mem_removehandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL,  gd5429);
  34.301 +        pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04);
  34.302 +        switch (svga->gdcreg[6] & 0x0C)
  34.303          {
  34.304                  case 0x0: /*128k at A0000*/
  34.305 -                mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  NULL);
  34.306 +                mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  gd5429);
  34.307                  break;
  34.308                  case 0x4: /*64k at A0000*/
  34.309 -                mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  NULL);
  34.310 -                if (seqregs[0x17] & 0x04)
  34.311 -                        mem_sethandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL,  NULL);
  34.312 +                mem_sethandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  gd5429);
  34.313 +                if (svga->seqregs[0x17] & 0x04)
  34.314 +                        mem_sethandler(0xb8000, 0x00100, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL,  gd5429);
  34.315                  break;
  34.316                  case 0x8: /*32k at B0000*/
  34.317 -                mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  34.318 +                mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  svga);
  34.319                  break;
  34.320                  case 0xC: /*32k at B8000*/
  34.321 -                mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  NULL);
  34.322 +                mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,  svga);
  34.323                  break;
  34.324          }
  34.325  }
  34.326          
  34.327 -void gd5429_recalctimings()
  34.328 +void gd5429_recalctimings(svga_t *svga)
  34.329  {
  34.330 -        if (seqregs[7] & 0x01)
  34.331 +        gd5429_t *gd5429 = (gd5429_t *)svga->p;
  34.332 +        
  34.333 +        if (svga->seqregs[7] & 0x01)
  34.334          {
  34.335 -                svga_render = svga_render_8bpp_highres;
  34.336 +                svga->render = svga_render_8bpp_highres;
  34.337          }
  34.338          
  34.339 -        svga_ma |= ((crtc[0x1b] & 0x01) << 16) | ((crtc[0x1b] & 0xc) << 15);
  34.340 -        pclog("MA now %05X %02X\n", svga_ma, crtc[0x1b]);
  34.341 +        svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15);
  34.342 +        pclog("MA now %05X %02X\n", svga->ma_latch, svga->crtc[0x1b]);
  34.343  }
  34.344  
  34.345 -void gd5429_hwcursor_draw(int displine)
  34.346 +void gd5429_hwcursor_draw(svga_t *svga, int displine)
  34.347  {
  34.348          int x;
  34.349          uint8_t dat[2];
  34.350          int xx;
  34.351 -        int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff;
  34.352 +        int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
  34.353          
  34.354 -        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]);
  34.355 +        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]);
  34.356          for (x = 0; x < 32; x += 8)
  34.357          {
  34.358 -                dat[0] = vram[svga_hwcursor_latch.addr];
  34.359 -                dat[1] = vram[svga_hwcursor_latch.addr + 0x80];
  34.360 +                dat[0] = svga->vram[svga->hwcursor_latch.addr];
  34.361 +                dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80];
  34.362                  for (xx = 0; xx < 8; xx++)
  34.363                  {
  34.364 -                        if (offset >= svga_hwcursor_latch.x)
  34.365 +                        if (offset >= svga->hwcursor_latch.x)
  34.366                          {
  34.367                                  if (dat[1] & 0x80)
  34.368                                          ((uint32_t *)buffer32->line[displine])[offset + 32] = 0;
  34.369 @@ -264,54 +282,39 @@
  34.370                          dat[0] <<= 1;
  34.371                          dat[1] <<= 1;
  34.372                  }
  34.373 -                svga_hwcursor_latch.addr++;
  34.374 +                svga->hwcursor_latch.addr++;
  34.375          }
  34.376  }
  34.377  
  34.378 -int gd5429_init()
  34.379 +
  34.380 +void gd5429_write_linear(uint32_t addr, uint8_t val, void *p);
  34.381 +
  34.382 +void gd5429_write(uint32_t addr, uint8_t val, void *p)
  34.383  {
  34.384 -        svga_recalctimings_ex = gd5429_recalctimings;
  34.385 -        svga_hwcursor_draw    = gd5429_hwcursor_draw;
  34.386 -        svga_vram_limit = 2 << 20; /*2mb*/
  34.387 -        vrammask = 0x1fffff;
  34.388 -
  34.389 -        svga_hwcursor.yoff = 32;
  34.390 -        svga_hwcursor.xoff = 0;
  34.391 -
  34.392 -        memset(&gd5429, 0, sizeof(gd5429));
  34.393 -        
  34.394 -        gd5429.bank[1] = 0x8000;
  34.395 -        
  34.396 -        return svga_init();
  34.397 +        gd5429_t *gd5429 = (gd5429_t *)p;
  34.398 +//        pclog("gd5429_write : %05X %02X  ", addr, val);
  34.399 +        addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
  34.400 +//        pclog("%08X\n", addr);
  34.401 +        gd5429_write_linear(addr, val, p);
  34.402  }
  34.403  
  34.404 -static uint8_t la, lb, lc, ld;
  34.405 -
  34.406 -uint8_t gd5429_read_linear(uint32_t addr, void *priv);
  34.407 -void gd5429_write_linear(uint32_t addr, uint8_t val, void *priv);
  34.408 -
  34.409 -void gd5429_write(uint32_t addr, uint8_t val, void *priv)
  34.410 +uint8_t gd5429_read(uint32_t addr, void *p)
  34.411  {
  34.412 -//        pclog("gd5429_write : %05X %02X  ", addr, val);
  34.413 -        addr = (addr & 0x7fff) + gd5429.bank[(addr >> 15) & 1];
  34.414 -//        pclog("%08X\n", addr);
  34.415 -        gd5429_write_linear(addr, val, priv);
  34.416 -}
  34.417 -
  34.418 -uint8_t gd5429_read(uint32_t addr, void *priv)
  34.419 -{
  34.420 +        gd5429_t *gd5429 = (gd5429_t *)p;
  34.421          uint8_t ret;
  34.422  //        pclog("gd5429_read : %05X ", addr);
  34.423 -        addr = (addr & 0x7fff) + gd5429.bank[(addr >> 15) & 1];
  34.424 -        ret = gd5429_read_linear(addr, priv);
  34.425 +        addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
  34.426 +        ret = svga_read_linear(addr, &gd5429->svga);
  34.427  //        pclog("%08X %02X\n", addr, ret);  
  34.428          return ret;      
  34.429  }
  34.430  
  34.431 -void gd5429_write_linear(uint32_t addr, uint8_t val, void *priv)
  34.432 +void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
  34.433  {
  34.434 -        uint8_t vala,valb,valc,vald,wm=writemask;
  34.435 -        int writemask2 = writemask;
  34.436 +        gd5429_t *gd5429 = (gd5429_t *)p;
  34.437 +        svga_t *svga = &gd5429->svga;
  34.438 +        uint8_t vala, valb, valc, vald, wm = svga->writemask;
  34.439 +        int writemask2 = svga->writemask;
  34.440  
  34.441          cycles -= video_timing_b;
  34.442          cycles_lost += video_timing_b;
  34.443 @@ -319,270 +322,231 @@
  34.444          egawrites++;
  34.445          
  34.446  //        if (svga_output) pclog("Write LFB %08X %02X ", addr, val);
  34.447 -        if (!(gdcreg[6]&1)) fullchange=2;
  34.448 -        if (chain4 && (writemode < 4))
  34.449 +        if (!(svga->gdcreg[6] & 1)) 
  34.450 +                fullchange = 2;
  34.451 +        if (svga->chain4 && (svga->writemode < 4))
  34.452          {
  34.453 -                writemask2=1<<(addr&3);
  34.454 -                addr&=~3;
  34.455 +                writemask2 = 1 << (addr & 3);
  34.456 +                addr &= ~3;
  34.457          }
  34.458          else
  34.459          {
  34.460 -                addr<<=2;
  34.461 +                addr <<= 2;
  34.462          }
  34.463          addr &= 0x7fffff;
  34.464 +        if (addr >= svga->vram_limit)
  34.465 +                return;
  34.466  //        if (svga_output) pclog("%08X\n", addr);
  34.467 -        changedvram[addr>>10]=changeframecount;
  34.468 +        svga->changedvram[addr >> 10] = changeframecount;
  34.469          
  34.470 -        switch (writemode)
  34.471 +        switch (svga->writemode)
  34.472          {
  34.473                  case 4:
  34.474                  pclog("Writemode 4 : %X ", addr);
  34.475                  addr <<= 1;
  34.476 -                changedvram[addr>>10]=changeframecount;
  34.477 +                svga->changedvram[addr >> 10] = changeframecount;
  34.478                  pclog("%X %X\n", addr, val);
  34.479                  if (val & 0x80)
  34.480 -                        vram[addr + 0] = gdcreg[1];
  34.481 +                        svga->vram[addr + 0] = svga->gdcreg[1];
  34.482                  if (val & 0x40)
  34.483 -                        vram[addr + 1] = gdcreg[1];
  34.484 +                        svga->vram[addr + 1] = svga->gdcreg[1];
  34.485                  if (val & 0x20)
  34.486 -                        vram[addr + 2] = gdcreg[1];
  34.487 +                        svga->vram[addr + 2] = svga->gdcreg[1];
  34.488                  if (val & 0x10)
  34.489 -                        vram[addr + 3] = gdcreg[1];
  34.490 +                        svga->vram[addr + 3] = svga->gdcreg[1];
  34.491                  if (val & 0x08)
  34.492 -                        vram[addr + 4] = gdcreg[1];
  34.493 +                        svga->vram[addr + 4] = svga->gdcreg[1];
  34.494                  if (val & 0x04)
  34.495 -                        vram[addr + 5] = gdcreg[1];
  34.496 +                        svga->vram[addr + 5] = svga->gdcreg[1];
  34.497                  if (val & 0x02)
  34.498 -                        vram[addr + 6] = gdcreg[1];
  34.499 +                        svga->vram[addr + 6] = svga->gdcreg[1];
  34.500                  if (val & 0x01)
  34.501 -                        vram[addr + 7] = gdcreg[1];
  34.502 +                        svga->vram[addr + 7] = svga->gdcreg[1];
  34.503                  break;
  34.504                          
  34.505                  case 5:
  34.506                  pclog("Writemode 5 : %X ", addr);
  34.507                  addr <<= 1;
  34.508 -                changedvram[addr>>10]=changeframecount;
  34.509 +                svga->changedvram[addr >> 10] = changeframecount;
  34.510                  pclog("%X %X\n", addr, val);
  34.511 -                vram[addr + 0] = (val & 0x80) ? gdcreg[1] : gdcreg[0];
  34.512 -                vram[addr + 1] = (val & 0x40) ? gdcreg[1] : gdcreg[0];
  34.513 -                vram[addr + 2] = (val & 0x20) ? gdcreg[1] : gdcreg[0];
  34.514 -                vram[addr + 3] = (val & 0x10) ? gdcreg[1] : gdcreg[0];
  34.515 -                vram[addr + 4] = (val & 0x08) ? gdcreg[1] : gdcreg[0];
  34.516 -                vram[addr + 5] = (val & 0x04) ? gdcreg[1] : gdcreg[0];
  34.517 -                vram[addr + 6] = (val & 0x02) ? gdcreg[1] : gdcreg[0];
  34.518 -                vram[addr + 7] = (val & 0x01) ? gdcreg[1] : gdcreg[0];
  34.519 +                svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0];
  34.520 +                svga->vram[addr + 1] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0];
  34.521 +                svga->vram[addr + 2] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0];
  34.522 +                svga->vram[addr + 3] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0];
  34.523 +                svga->vram[addr + 4] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0];
  34.524 +                svga->vram[addr + 5] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0];
  34.525 +                svga->vram[addr + 6] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0];
  34.526 +                svga->vram[addr + 7] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0];
  34.527                  break;
  34.528                  
  34.529                  case 1:
  34.530 -                if (writemask2&1) vram[addr]=la;
  34.531 -                if (writemask2&2) vram[addr|0x1]=lb;
  34.532 -                if (writemask2&4) vram[addr|0x2]=lc;
  34.533 -                if (writemask2&8) vram[addr|0x3]=ld;
  34.534 +                if (writemask2 & 1) svga->vram[addr]       = svga->la;
  34.535 +                if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb;
  34.536 +                if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc;
  34.537 +                if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld;
  34.538                  break;
  34.539                  case 0:
  34.540 -                if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val];
  34.541 -                if (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1])
  34.542 +                if (svga->gdcreg[3] & 7) 
  34.543 +                        val = svga_rotate[svga->gdcreg[3] & 7][val];
  34.544 +                if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1])
  34.545                  {
  34.546 -                        if (writemask2&1) vram[addr]=val;
  34.547 -                        if (writemask2&2) vram[addr|0x1]=val;
  34.548 -                        if (writemask2&4) vram[addr|0x2]=val;
  34.549 -                        if (writemask2&8) vram[addr|0x3]=val;
  34.550 +                        if (writemask2 & 1) svga->vram[addr]       = val;
  34.551 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = val;
  34.552 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = val;
  34.553 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = val;
  34.554                  }
  34.555                  else
  34.556                  {
  34.557 -                        if (gdcreg[1]&1) vala=(gdcreg[0]&1)?0xFF:0;
  34.558 -                        else             vala=val;
  34.559 -                        if (gdcreg[1]&2) valb=(gdcreg[0]&2)?0xFF:0;
  34.560 -                        else             valb=val;
  34.561 -                        if (gdcreg[1]&4) valc=(gdcreg[0]&4)?0xFF:0;
  34.562 -                        else             valc=val;
  34.563 -                        if (gdcreg[1]&8) vald=(gdcreg[0]&8)?0xFF:0;
  34.564 -                        else             vald=val;
  34.565 +                        if (svga->gdcreg[1] & 1) vala = (svga->gdcreg[0] & 1) ? 0xff : 0;
  34.566 +                        else                     vala = val;
  34.567 +                        if (svga->gdcreg[1] & 2) valb = (svga->gdcreg[0] & 2) ? 0xff : 0;
  34.568 +                        else                     valb = val;
  34.569 +                        if (svga->gdcreg[1] & 4) valc = (svga->gdcreg[0] & 4) ? 0xff : 0;
  34.570 +                        else                     valc = val;
  34.571 +                        if (svga->gdcreg[1] & 8) vald = (svga->gdcreg[0] & 8) ? 0xff : 0;
  34.572 +                        else                     vald = val;
  34.573  
  34.574 -                        switch (gdcreg[3]&0x18)
  34.575 +                        switch (svga->gdcreg[3] & 0x18)
  34.576                          {
  34.577                                  case 0: /*Set*/
  34.578 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
  34.579 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
  34.580 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
  34.581 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
  34.582 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
  34.583 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
  34.584 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
  34.585 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
  34.586                                  break;
  34.587                                  case 8: /*AND*/
  34.588 -                                if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
  34.589 -                                if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
  34.590 -                                if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
  34.591 -                                if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
  34.592 +                                if (writemask2 & 1) svga->vram[addr]       = (vala | ~svga->gdcreg[8]) & svga->la;
  34.593 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb;
  34.594 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc;
  34.595 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld;
  34.596                                  break;
  34.597                                  case 0x10: /*OR*/
  34.598 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
  34.599 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
  34.600 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
  34.601 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
  34.602 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | svga->la;
  34.603 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb;
  34.604 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc;
  34.605 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld;
  34.606                                  break;
  34.607                                  case 0x18: /*XOR*/
  34.608 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
  34.609 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
  34.610 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
  34.611 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
  34.612 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) ^ svga->la;
  34.613 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb;
  34.614 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc;
  34.615 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld;
  34.616                                  break;
  34.617                          }
  34.618  //                        pclog("- %02X %02X %02X %02X   %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr);
  34.619                  }
  34.620                  break;
  34.621                  case 2:
  34.622 -                if (!(gdcreg[3]&0x18) && !gdcreg[1])
  34.623 +                if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1])
  34.624                  {
  34.625 -                        if (writemask2&1) vram[addr]=(((val&1)?0xFF:0)&gdcreg[8])|(la&~gdcreg[8]);
  34.626 -                        if (writemask2&2) vram[addr|0x1]=(((val&2)?0xFF:0)&gdcreg[8])|(lb&~gdcreg[8]);
  34.627 -                        if (writemask2&4) vram[addr|0x2]=(((val&4)?0xFF:0)&gdcreg[8])|(lc&~gdcreg[8]);
  34.628 -                        if (writemask2&8) vram[addr|0x3]=(((val&8)?0xFF:0)&gdcreg[8])|(ld&~gdcreg[8]);
  34.629 +                        if (writemask2 & 1) svga->vram[addr]       = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
  34.630 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
  34.631 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
  34.632 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
  34.633                  }
  34.634                  else
  34.635                  {
  34.636 -                        vala=((val&1)?0xFF:0);
  34.637 -                        valb=((val&2)?0xFF:0);
  34.638 -                        valc=((val&4)?0xFF:0);
  34.639 -                        vald=((val&8)?0xFF:0);
  34.640 -                        switch (gdcreg[3]&0x18)
  34.641 +                        vala = ((val & 1) ? 0xff : 0);
  34.642 +                        valb = ((val & 2) ? 0xff : 0);
  34.643 +                        valc = ((val & 4) ? 0xff : 0);
  34.644 +                        vald = ((val & 8) ? 0xff : 0);
  34.645 +                        switch (svga->gdcreg[3] & 0x18)
  34.646                          {
  34.647                                  case 0: /*Set*/
  34.648 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
  34.649 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
  34.650 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
  34.651 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
  34.652 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
  34.653 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
  34.654 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
  34.655 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
  34.656                                  break;
  34.657                                  case 8: /*AND*/
  34.658 -                                if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
  34.659 -                                if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
  34.660 -                                if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
  34.661 -                                if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
  34.662 +                                if (writemask2 & 1) svga->vram[addr]       = (vala | ~svga->gdcreg[8]) & svga->la;
  34.663 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb;
  34.664 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc;
  34.665 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld;
  34.666                                  break;
  34.667                                  case 0x10: /*OR*/
  34.668 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
  34.669 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
  34.670 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
  34.671 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
  34.672 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | svga->la;
  34.673 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb;
  34.674 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc;
  34.675 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld;
  34.676                                  break;
  34.677                                  case 0x18: /*XOR*/
  34.678 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
  34.679 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
  34.680 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
  34.681 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
  34.682 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) ^ svga->la;
  34.683 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb;
  34.684 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc;
  34.685 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld;
  34.686                                  break;
  34.687                          }
  34.688                  }
  34.689                  break;
  34.690                  case 3:
  34.691 -                if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val];
  34.692 -                wm=gdcreg[8];
  34.693 -                gdcreg[8]&=val;
  34.694 +                if (svga->gdcreg[3] & 7) 
  34.695 +                        val = svga_rotate[svga->gdcreg[3] & 7][val];
  34.696 +                wm = svga->gdcreg[8];
  34.697 +                svga->gdcreg[8] &= val;
  34.698  
  34.699 -                vala=(gdcreg[0]&1)?0xFF:0;
  34.700 -                valb=(gdcreg[0]&2)?0xFF:0;
  34.701 -                valc=(gdcreg[0]&4)?0xFF:0;
  34.702 -                vald=(gdcreg[0]&8)?0xFF:0;
  34.703 -                switch (gdcreg[3]&0x18)
  34.704 +                vala = (svga->gdcreg[0] & 1) ? 0xff : 0;
  34.705 +                valb = (svga->gdcreg[0] & 2) ? 0xff : 0;
  34.706 +                valc = (svga->gdcreg[0] & 4) ? 0xff : 0;
  34.707 +                vald = (svga->gdcreg[0] & 8) ? 0xff : 0;
  34.708 +                switch (svga->gdcreg[3] & 0x18)
  34.709                  {
  34.710                          case 0: /*Set*/
  34.711 -                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
  34.712 -                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
  34.713 -                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
  34.714 -                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
  34.715 +                        if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
  34.716 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
  34.717 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
  34.718 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
  34.719                          break;
  34.720                          case 8: /*AND*/
  34.721 -                        if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
  34.722 -                        if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
  34.723 -                        if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
  34.724 -                        if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
  34.725 +                        if (writemask2 & 1) svga->vram[addr]       = (vala | ~svga->gdcreg[8]) & svga->la;
  34.726 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb;
  34.727 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc;
  34.728 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld;
  34.729                          break;
  34.730                          case 0x10: /*OR*/
  34.731 -                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
  34.732 -                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
  34.733 -                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
  34.734 -                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
  34.735 +                        if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | svga->la;
  34.736 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb;
  34.737 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc;
  34.738 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld;
  34.739                          break;
  34.740                          case 0x18: /*XOR*/
  34.741 -                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
  34.742 -                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
  34.743 -                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
  34.744 -                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
  34.745 +                        if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) ^ svga->la;
  34.746 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb;
  34.747 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc;
  34.748 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld;
  34.749                          break;
  34.750                  }
  34.751 -                gdcreg[8]=wm;
  34.752 +                svga->gdcreg[8] = wm;
  34.753                  break;
  34.754          }
  34.755  }
  34.756  
  34.757 -uint8_t gd5429_read_linear(uint32_t addr, void *priv)
  34.758 +void gd5429_start_blit(uint32_t cpu_dat, int count, void *p)
  34.759  {
  34.760 -        uint8_t temp,temp2,temp3,temp4;
  34.761 -  
  34.762 -        cycles -= video_timing_b;
  34.763 -        cycles_lost += video_timing_b;
  34.764 +        gd5429_t *gd5429 = (gd5429_t *)p;
  34.765 +        svga_t *svga = &gd5429->svga;
  34.766  
  34.767 -        egareads++;
  34.768 -        
  34.769 -        if (chain4) 
  34.770 -        { 
  34.771 -                addr &= 0x7fffff;
  34.772 -                if (addr >= svga_vram_limit)
  34.773 -                   return 0xff;
  34.774 -                return vram[addr & 0x7fffff]; 
  34.775 -        }
  34.776 -        else        addr<<=2;
  34.777 -
  34.778 -        addr &= 0x7fffff;
  34.779 -        
  34.780 -        if (addr >= svga_vram_limit)
  34.781 -           return 0xff;
  34.782 -
  34.783 -        la=vram[addr];
  34.784 -        lb=vram[addr|0x1];
  34.785 -        lc=vram[addr|0x2];
  34.786 -        ld=vram[addr|0x3];
  34.787 -        if (readmode)
  34.788 -        {
  34.789 -                temp= (colournocare&1) ?0xFF:0;
  34.790 -                temp&=la;
  34.791 -                temp^=(colourcompare&1)?0xFF:0;
  34.792 -                temp2= (colournocare&2) ?0xFF:0;
  34.793 -                temp2&=lb;
  34.794 -                temp2^=(colourcompare&2)?0xFF:0;
  34.795 -                temp3= (colournocare&4) ?0xFF:0;
  34.796 -                temp3&=lc;
  34.797 -                temp3^=(colourcompare&4)?0xFF:0;
  34.798 -                temp4= (colournocare&8) ?0xFF:0;
  34.799 -                temp4&=ld;
  34.800 -                temp4^=(colourcompare&8)?0xFF:0;
  34.801 -                return ~(temp|temp2|temp3|temp4);
  34.802 -        }
  34.803 -//printf("Read %02X %04X %04X\n",vram[addr|readplane],addr,readplane);
  34.804 -        return vram[addr|readplane];
  34.805 -}
  34.806 -
  34.807 -void gd5429_start_blit(uint32_t cpu_dat, int count)
  34.808 -{
  34.809          pclog("gd5429_start_blit %i\n", count);
  34.810          if (count == -1)
  34.811          {
  34.812 -                gd5429.blt.dst_addr_backup = gd5429.blt.dst_addr;
  34.813 -                gd5429.blt.src_addr_backup = gd5429.blt.src_addr;
  34.814 -                gd5429.blt.width_backup    = gd5429.blt.width;
  34.815 -                gd5429.blt.height_internal = gd5429.blt.height;
  34.816 -                gd5429.blt.x_count         = gd5429.blt.mask & 7;
  34.817 -                pclog("gd5429_start_blit : size %i, %i\n", gd5429.blt.width, gd5429.blt.height);
  34.818 +                gd5429->blt.dst_addr_backup = gd5429->blt.dst_addr;
  34.819 +                gd5429->blt.src_addr_backup = gd5429->blt.src_addr;
  34.820 +                gd5429->blt.width_backup    = gd5429->blt.width;
  34.821 +                gd5429->blt.height_internal = gd5429->blt.height;
  34.822 +                gd5429->blt.x_count         = gd5429->blt.mask & 7;
  34.823 +                pclog("gd5429_start_blit : size %i, %i\n", gd5429->blt.width, gd5429->blt.height);
  34.824                  
  34.825 -                if (gd5429.blt.mode & 0x04)
  34.826 +                if (gd5429->blt.mode & 0x04)
  34.827                  {
  34.828  //                        pclog("blt.mode & 0x04\n");
  34.829 -                        mem_removehandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  NULL);
  34.830 -                        mem_sethandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l,  NULL);
  34.831 +                        mem_removehandler(0xa0000, 0x10000, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL,  gd5429);
  34.832 +                        mem_sethandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l,  gd5429);
  34.833                          return;
  34.834                  }
  34.835                  else
  34.836                  {
  34.837 -                        mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l,  NULL);
  34.838 -                        gd5429_recalc_mapping();
  34.839 +                        mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l,  gd5429);
  34.840 +                        gd5429_recalc_mapping(gd5429);
  34.841                  }                
  34.842          }
  34.843          
  34.844 @@ -591,11 +555,11 @@
  34.845                  uint8_t src, dst;
  34.846                  int mask;
  34.847                  
  34.848 -                if (gd5429.blt.mode & 0x04)
  34.849 +                if (gd5429->blt.mode & 0x04)
  34.850                  {
  34.851 -                        if (gd5429.blt.mode & 0x80)
  34.852 +                        if (gd5429->blt.mode & 0x80)
  34.853                          {
  34.854 -                                src = (cpu_dat & 0x80) ? gd5429.blt.fg_col : gd5429.blt.bg_col;
  34.855 +                                src = (cpu_dat & 0x80) ? gd5429->blt.fg_col : gd5429->blt.bg_col;
  34.856                                  mask = cpu_dat & 0x80;
  34.857                                  cpu_dat <<= 1;
  34.858                                  count--;
  34.859 @@ -610,39 +574,39 @@
  34.860                  }
  34.861                  else
  34.862                  {
  34.863 -                        switch (gd5429.blt.mode & 0xc0)
  34.864 +                        switch (gd5429->blt.mode & 0xc0)
  34.865                          {
  34.866                                  case 0x00:
  34.867 -                                src = vram[gd5429.blt.src_addr & vrammask];
  34.868 -                                gd5429.blt.src_addr += ((gd5429.blt.mode & 0x01) ? -1 : 1);
  34.869 +                                src = svga->vram[gd5429->blt.src_addr & svga->vrammask];
  34.870 +                                gd5429->blt.src_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1);
  34.871                                  mask = 1;
  34.872                                  break;
  34.873                                  case 0x40:
  34.874 -                                src = vram[(gd5429.blt.src_addr & (vrammask & ~7)) | (gd5429.blt.dst_addr & 7)];
  34.875 +                                src = svga->vram[(gd5429->blt.src_addr & (svga->vrammask & ~7)) | (gd5429->blt.dst_addr & 7)];
  34.876                                  mask = 1;
  34.877                                  break;
  34.878                                  case 0x80:
  34.879 -                                mask = vram[gd5429.blt.src_addr & vrammask] & (0x80 >> gd5429.blt.x_count);
  34.880 -                                src = mask ? gd5429.blt.fg_col : gd5429.blt.bg_col;
  34.881 -                                gd5429.blt.x_count++;
  34.882 -                                if (gd5429.blt.x_count == 8)
  34.883 +                                mask = svga->vram[gd5429->blt.src_addr & svga->vrammask] & (0x80 >> gd5429->blt.x_count);
  34.884 +                                src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col;
  34.885 +                                gd5429->blt.x_count++;
  34.886 +                                if (gd5429->blt.x_count == 8)
  34.887                                  {
  34.888 -                                        gd5429.blt.x_count = 0;
  34.889 -                                        gd5429.blt.src_addr++;
  34.890 +                                        gd5429->blt.x_count = 0;
  34.891 +                                        gd5429->blt.src_addr++;
  34.892                                  }
  34.893                                  break;
  34.894                                  case 0xc0:
  34.895 -                                mask = vram[gd5429.blt.src_addr & vrammask] & (0x80 >> (gd5429.blt.dst_addr & 7));
  34.896 -                                src = mask ? gd5429.blt.fg_col : gd5429.blt.bg_col;
  34.897 +                                mask = svga->vram[gd5429->blt.src_addr & svga->vrammask] & (0x80 >> (gd5429->blt.dst_addr & 7));
  34.898 +                                src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col;
  34.899                                  break;
  34.900                          }
  34.901                          count--;                        
  34.902                  }
  34.903 -                dst = vram[gd5429.blt.dst_addr & vrammask];
  34.904 -                changedvram[(gd5429.blt.dst_addr & vrammask) >> 10] = changeframecount;
  34.905 +                dst = svga->vram[gd5429->blt.dst_addr & svga->vrammask];
  34.906 +                svga->changedvram[(gd5429->blt.dst_addr & svga->vrammask) >> 10] = changeframecount;
  34.907                 
  34.908 -                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);
  34.909 -                switch (gd5429.blt.rop)
  34.910 +                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 & svga->vrammask, svga->vram[gd5429->blt.src_addr & svga->vrammask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst);
  34.911 +                switch (gd5429->blt.rop)
  34.912                  {
  34.913                          case 0x00: dst = 0;             break;
  34.914                          case 0x05: dst =   src &  dst;  break;
  34.915 @@ -663,141 +627,145 @@
  34.916                  }
  34.917                  pclog("%02X  %02X\n", dst, mask);
  34.918                  
  34.919 -                if ((gd5429.blt.width_backup - gd5429.blt.width) >= (gd5429.blt.mask & 7) &&
  34.920 -                    !((gd5429.blt.mode & 0x08) && !mask))
  34.921 -                        vram[gd5429.blt.dst_addr & vrammask] = dst;
  34.922 +                if ((gd5429->blt.width_backup - gd5429->blt.width) >= (gd5429->blt.mask & 7) &&
  34.923 +                    !((gd5429->blt.mode & 0x08) && !mask))
  34.924 +                        svga->vram[gd5429->blt.dst_addr & svga->vrammask] = dst;
  34.925                  
  34.926 -                gd5429.blt.dst_addr += ((gd5429.blt.mode & 0x01) ? -1 : 1);
  34.927 +                gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1);
  34.928                  
  34.929 -                gd5429.blt.width--;
  34.930 +                gd5429->blt.width--;
  34.931                  
  34.932 -                if (gd5429.blt.width == 0xffff)
  34.933 +                if (gd5429->blt.width == 0xffff)
  34.934                  {
  34.935 -                        gd5429.blt.width = gd5429.blt.width_backup;
  34.936 +                        gd5429->blt.width = gd5429->blt.width_backup;
  34.937  
  34.938 -                        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);                        
  34.939 +                        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);
  34.940                          
  34.941 -                        switch (gd5429.blt.mode & 0xc0)
  34.942 +                        switch (gd5429->blt.mode & 0xc0)
  34.943                          {
  34.944                                  case 0x00:
  34.945 -                                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);
  34.946 +                                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);
  34.947                                  break;
  34.948                                  case 0x40:
  34.949 -                                gd5429.blt.src_addr = ((gd5429.blt.src_addr + ((gd5429.blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429.blt.src_addr & ~0x38);
  34.950 +                                gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429->blt.src_addr & ~0x38);
  34.951                                  break;
  34.952                                  case 0x80:
  34.953 -                                if (gd5429.blt.x_count != 0)
  34.954 +                                if (gd5429->blt.x_count != 0)
  34.955                                  {
  34.956 -                                        gd5429.blt.x_count = 0;
  34.957 -                                        gd5429.blt.src_addr++;
  34.958 +                                        gd5429->blt.x_count = 0;
  34.959 +                                        gd5429->blt.src_addr++;
  34.960                                  }
  34.961                                  break;
  34.962                                  case 0xc0:
  34.963 -                                gd5429.blt.src_addr = ((gd5429.blt.src_addr + ((gd5429.blt.mode & 0x01) ? -1 : 1)) & 7) | (gd5429.blt.src_addr & ~7);
  34.964 +                                gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -1 : 1)) & 7) | (gd5429->blt.src_addr & ~7);
  34.965                                  break;
  34.966                          }
  34.967                          
  34.968 -                        gd5429.blt.height_internal--;
  34.969 -                        if (gd5429.blt.height_internal == 0xffff)
  34.970 +                        gd5429->blt.height_internal--;
  34.971 +                        if (gd5429->blt.height_internal == 0xffff)
  34.972                          {
  34.973 -                                if (gd5429.blt.mode & 0x04)
  34.974 +                                if (gd5429->blt.mode & 0x04)
  34.975                                  {
  34.976 -                                        mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l,  NULL);
  34.977 -                                        gd5429_recalc_mapping();
  34.978 +                                        mem_removehandler(0xa0000, 0x10000, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l,  gd5429);
  34.979 +                                        gd5429_recalc_mapping(gd5429);
  34.980                                  }
  34.981                                  return;
  34.982                          }
  34.983                                  
  34.984 -                        if (gd5429.blt.mode & 0x04)
  34.985 +                        if (gd5429->blt.mode & 0x04)
  34.986                                  return;
  34.987                  }                        
  34.988          }
  34.989  }
  34.990  
  34.991 -void gd5429_mmio_write(uint32_t addr, uint8_t val, void *priv)
  34.992 +void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p)
  34.993  {
  34.994 +        gd5429_t *gd5429 = (gd5429_t *)p;
  34.995 +
  34.996          pclog("MMIO write %08X %02X\n", addr, val);
  34.997          switch (addr & 0xff)
  34.998          {
  34.999                  case 0x00:
 34.1000 -                gd5429.blt.bg_col = (gd5429.blt.bg_col & 0xff00) | val;
 34.1001 +                gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00) | val;
 34.1002                  break;
 34.1003                  case 0x01:
 34.1004 -                gd5429.blt.bg_col = (gd5429.blt.bg_col & 0x00ff) | (val << 8);
 34.1005 +                gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ff) | (val << 8);
 34.1006                  break;
 34.1007  
 34.1008                  case 0x04:
 34.1009 -                gd5429.blt.fg_col = (gd5429.blt.fg_col & 0xff00) | val;
 34.1010 +                gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00) | val;
 34.1011                  break;
 34.1012                  case 0x05:
 34.1013 -                gd5429.blt.fg_col = (gd5429.blt.fg_col & 0x00ff) | (val << 8);
 34.1014 +                gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ff) | (val << 8);
 34.1015                  break;
 34.1016  
 34.1017                  case 0x08:
 34.1018 -                gd5429.blt.width = (gd5429.blt.width & 0xff00) | val;
 34.1019 +                gd5429->blt.width = (gd5429->blt.width & 0xff00) | val;
 34.1020                  break;
 34.1021                  case 0x09:
 34.1022 -                gd5429.blt.width = (gd5429.blt.width & 0x00ff) | (val << 8);
 34.1023 +                gd5429->blt.width = (gd5429->blt.width & 0x00ff) | (val << 8);
 34.1024                  break;
 34.1025                  case 0x0a:
 34.1026 -                gd5429.blt.height = (gd5429.blt.height & 0xff00) | val;
 34.1027 +                gd5429->blt.height = (gd5429->blt.height & 0xff00) | val;
 34.1028                  break;
 34.1029                  case 0x0b:
 34.1030 -                gd5429.blt.height = (gd5429.blt.height & 0x00ff) | (val << 8);
 34.1031 +                gd5429->blt.height = (gd5429->blt.height & 0x00ff) | (val << 8);
 34.1032                  break;
 34.1033                  case 0x0c:
 34.1034 -                gd5429.blt.dst_pitch = (gd5429.blt.dst_pitch & 0xff00) | val;
 34.1035 +                gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0xff00) | val;
 34.1036                  break;
 34.1037                  case 0x0d:
 34.1038 -                gd5429.blt.dst_pitch = (gd5429.blt.dst_pitch & 0x00ff) | (val << 8);
 34.1039 +                gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0x00ff) | (val << 8);
 34.1040                  break;
 34.1041                  case 0x0e:
 34.1042 -                gd5429.blt.src_pitch = (gd5429.blt.src_pitch & 0xff00) | val;
 34.1043 +                gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0xff00) | val;
 34.1044                  break;
 34.1045                  case 0x0f:
 34.1046 -                gd5429.blt.src_pitch = (gd5429.blt.src_pitch & 0x00ff) | (val << 8);
 34.1047 +                gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0x00ff) | (val << 8);
 34.1048                  break;
 34.1049                  
 34.1050                  case 0x10:
 34.1051 -                gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0xffff00) | val;
 34.1052 +                gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xffff00) | val;
 34.1053                  break;
 34.1054                  case 0x11:
 34.1055 -                gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0xff00ff) | (val << 8);
 34.1056 +                gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xff00ff) | (val << 8);
 34.1057                  break;
 34.1058                  case 0x12:
 34.1059 -                gd5429.blt.dst_addr = (gd5429.blt.dst_addr & 0x00ffff) | (val << 16);
 34.1060 +                gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0x00ffff) | (val << 16);
 34.1061                  break;
 34.1062  
 34.1063                  case 0x14:
 34.1064 -                gd5429.blt.src_addr = (gd5429.blt.src_addr & 0xffff00) | val;
 34.1065 +                gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xffff00) | val;
 34.1066                  break;
 34.1067                  case 0x15:
 34.1068 -                gd5429.blt.src_addr = (gd5429.blt.src_addr & 0xff00ff) | (val << 8);
 34.1069 +                gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xff00ff) | (val << 8);
 34.1070                  break;
 34.1071                  case 0x16:
 34.1072 -                gd5429.blt.src_addr = (gd5429.blt.src_addr & 0x00ffff) | (val << 16);
 34.1073 +                gd5429->blt.src_addr = (gd5429->blt.src_addr & 0x00ffff) | (val << 16);
 34.1074                  break;
 34.1075  
 34.1076                  case 0x17:
 34.1077 -                gd5429.blt.mask = val;
 34.1078 +                gd5429->blt.mask = val;
 34.1079                  break;
 34.1080                  case 0x18:
 34.1081 -                gd5429.blt.mode = val;
 34.1082 +                gd5429->blt.mode = val;
 34.1083                  break;
 34.1084                  
 34.1085                  case 0x1a:
 34.1086 -                gd5429.blt.rop = val;
 34.1087 +                gd5429->blt.rop = val;
 34.1088                  break;
 34.1089                  
 34.1090                  case 0x40:
 34.1091                  if (val & 0x02)
 34.1092 -                        gd5429_start_blit(0, -1);
 34.1093 +                        gd5429_start_blit(0, -1, gd5429);
 34.1094                  break;
 34.1095          }
 34.1096  }
 34.1097  
 34.1098 -uint8_t gd5429_mmio_read(uint32_t addr, void *priv)
 34.1099 +uint8_t gd5429_mmio_read(uint32_t addr, void *p)
 34.1100  {
 34.1101 +        gd5429_t *gd5429 = (gd5429_t *)p;
 34.1102 +
 34.1103          pclog("MMIO read %08X\n", addr);
 34.1104          switch (addr & 0xff)
 34.1105          {
 34.1106 @@ -807,44 +775,70 @@
 34.1107          return 0xff; /*All other registers read-only*/
 34.1108  }
 34.1109  
 34.1110 -void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *priv)
 34.1111 +void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p)
 34.1112  {
 34.1113          pclog("gd5429_blt_write_w %08X %08X\n", addr, val);
 34.1114 -        gd5429_start_blit(val, 16);
 34.1115 +        gd5429_start_blit(val, 16, p);
 34.1116  }
 34.1117  
 34.1118 -void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *priv)
 34.1119 +void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p)
 34.1120  {
 34.1121 +        gd5429_t *gd5429 = (gd5429_t *)p;
 34.1122 +        
 34.1123          pclog("gd5429_blt_write_l %08X %08X  %04X %04X\n", addr, val,  ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00));
 34.1124 -        if ((gd5429.blt.mode & 0x84) == 0x84)
 34.1125 +        if ((gd5429->blt.mode & 0x84) == 0x84)
 34.1126          {
 34.1127 -                gd5429_start_blit( val        & 0xff, 8);
 34.1128 -                gd5429_start_blit((val >> 8)  & 0xff, 8);
 34.1129 -                gd5429_start_blit((val >> 16) & 0xff, 8);
 34.1130 -                gd5429_start_blit((val >> 24) & 0xff, 8);
 34.1131 +                gd5429_start_blit( val        & 0xff, 8, p);
 34.1132 +                gd5429_start_blit((val >> 8)  & 0xff, 8, p);
 34.1133 +                gd5429_start_blit((val >> 16) & 0xff, 8, p);
 34.1134 +                gd5429_start_blit((val >> 24) & 0xff, 8, p);
 34.1135          }
 34.1136          else
 34.1137 -                gd5429_start_blit(val, 32);
 34.1138 +                gd5429_start_blit(val, 32, p);
 34.1139  }
 34.1140  
 34.1141 -GFXCARD vid_gd5429 =
 34.1142 +void *gd5429_init()
 34.1143  {
 34.1144 +        gd5429_t *gd5429 = malloc(sizeof(gd5429_t));
 34.1145 +        svga_t *svga = &gd5429->svga;
 34.1146 +        memset(gd5429, 0, sizeof(gd5429_t));
 34.1147 +
 34.1148 +        svga_init(&gd5429->svga, gd5429, 1 << 21, /*2mb*/
 34.1149 +                   gd5429_recalctimings,
 34.1150 +                   gd5429_in, gd5429_out,
 34.1151 +                   gd5429_hwcursor_draw);
 34.1152 +
 34.1153 +        io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
 34.1154 +
 34.1155 +        svga->hwcursor.yoff = 32;
 34.1156 +        svga->hwcursor.xoff = 0;
 34.1157 +
 34.1158 +        gd5429->bank[1] = 0x8000;
 34.1159 +        
 34.1160 +        return gd5429;
 34.1161 +}
 34.1162 +
 34.1163 +void gd5429_close(void *p)
 34.1164 +{
 34.1165 +        gd5429_t *gd5429 = (gd5429_t *)p;
 34.1166 +
 34.1167 +        svga_close(&gd5429->svga);
 34.1168 +        
 34.1169 +        free(gd5429);
 34.1170 +}
 34.1171 +
 34.1172 +void gd5429_speed_changed(void *p)
 34.1173 +{
 34.1174 +        gd5429_t *gd5429 = (gd5429_t *)p;
 34.1175 +        
 34.1176 +        svga_recalctimings(&gd5429->svga);
 34.1177 +}
 34.1178 +
 34.1179 +device_t gd5429_device =
 34.1180 +{
 34.1181 +        "Cirrus Logic GD5429",
 34.1182          gd5429_init,
 34.1183 -        /*IO at 3Cx/3Dx*/
 34.1184 -        gd5429_out,
 34.1185 -        gd5429_in,
 34.1186 -        /*IO at 3Ax/3Bx*/
 34.1187 -        video_out_null,
 34.1188 -        video_in_null,
 34.1189 -
 34.1190 -        svga_poll,
 34.1191 -        svga_recalctimings,
 34.1192 -
 34.1193 -        svga_write,
 34.1194 -        video_write_null,
 34.1195 -        video_write_null,
 34.1196 -
 34.1197 -        svga_read,
 34.1198 -        video_read_null,
 34.1199 -        video_read_null
 34.1200 +        gd5429_close,
 34.1201 +        gd5429_speed_changed,
 34.1202 +        svga_add_status_info
 34.1203  };
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/src/vid_cl5429.h	Mon Jun 24 20:42:35 2013 +0100
    35.3 @@ -0,0 +1,1 @@
    35.4 +extern device_t gd5429_device;
    36.1 --- a/src/vid_ega.c	Tue Jun 04 20:52:17 2013 +0100
    36.2 +++ b/src/vid_ega.c	Mon Jun 24 20:42:35 2013 +0100
    36.3 @@ -1,689 +1,777 @@
    36.4  /*EGA emulation*/
    36.5 +#include <stdlib.h>
    36.6  #include "ibm.h"
    36.7 +#include "device.h"
    36.8  #include "io.h"
    36.9  #include "mem.h"
   36.10  #include "timer.h"
   36.11  #include "video.h"
   36.12  #include "vid_ega.h"
   36.13 -#include "vid_svga.h"
   36.14  
   36.15  extern uint8_t edatlookup[4][4];
   36.16  
   36.17 -uint8_t ega_3c2;
   36.18 +static uint8_t ega_rotate[8][256];
   36.19  
   36.20 -static uint8_t la, lb, lc, ld;
   36.21 -static uint8_t ega_rotate[8][256];
   36.22 +static uint32_t pallook16[256], pallook64[256];
   36.23  
   36.24  /*3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour)*/
   36.25  int egaswitchread,egaswitches=9; /*7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines)*/
   36.26  
   36.27 -void ega_out(uint16_t addr, uint8_t val, void *priv)
   36.28 +void ega_out(uint16_t addr, uint8_t val, void *p)
   36.29  {
   36.30 +        ega_t *ega = (ega_t *)p;
   36.31          int c;
   36.32 -        uint8_t o,old;
   36.33 -        if ((addr&0xFFF0) == 0x3B0) addr |= 0x20;
   36.34 +        uint8_t o, old;
   36.35 +        
   36.36 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) 
   36.37 +                addr ^= 0x60;
   36.38 +        
   36.39          switch (addr)
   36.40          {
   36.41 -                case 0x3C0:
   36.42 -                if (!attrff)
   36.43 -                   attraddr=val&31;
   36.44 +                case 0x3c0:
   36.45 +                if (!ega->attrff)
   36.46 +                   ega->attraddr = val & 31;
   36.47                  else
   36.48                  {
   36.49 -                        attrregs[attraddr&31]=val;
   36.50 -                        if (attraddr<16) fullchange=changeframecount;
   36.51 -                        if (attraddr==0x10 || attraddr==0x14 || attraddr<0x10)
   36.52 +                        ega->attrregs[ega->attraddr & 31] = val;
   36.53 +                        if (ega->attraddr < 16) 
   36.54 +                                fullchange = changeframecount;
   36.55 +                        if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10)
   36.56                          {
   36.57 -                                for (c=0;c<16;c++)
   36.58 +                                for (c = 0; c < 16; c++)
   36.59                                  {
   36.60 -                                        if (attrregs[0x10]&0x80) egapal[c]=(attrregs[c]&0xF)|((attrregs[0x14]&0xF)<<4);
   36.61 -                                        else                     egapal[c]=(attrregs[c]&0x3F)|((attrregs[0x14]&0xC)<<4);
   36.62 +                                        if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] &  0xf) | ((ega->attrregs[0x14] & 0xf) << 4);
   36.63 +                                        else                            ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4);
   36.64                                  }
   36.65                          }
   36.66                  }
   36.67 -                attrff^=1;
   36.68 +                ega->attrff ^= 1;
   36.69                  break;
   36.70 -                case 0x3C2:
   36.71 -                egaswitchread=val&0xC;
   36.72 -                vres=!(val&0x80);
   36.73 -                pallook=(vres)?pallook16:pallook64;
   36.74 -                vidclock=val&4; /*printf("3C2 write %02X\n",val);*/
   36.75 -                ega_3c2=val;
   36.76 +                case 0x3c2:
   36.77 +                egaswitchread = val & 0xc;
   36.78 +                ega->vres = !(val & 0x80);
   36.79 +                ega->pallook = ega->vres ? pallook16 : pallook64;
   36.80 +                ega->vidclock = val & 4; /*printf("3C2 write %02X\n",val);*/
   36.81 +                ega->miscout=val;
   36.82                  break;
   36.83 -                case 0x3C4: seqaddr=val; break;
   36.84 -                case 0x3C5:
   36.85 -                o=seqregs[seqaddr&0xF];
   36.86 -                seqregs[seqaddr&0xF]=val;
   36.87 -                if (o!=val && (seqaddr&0xF)==1) ega_recalctimings();
   36.88 -                switch (seqaddr&0xF)
   36.89 +                case 0x3c4: 
   36.90 +                ega->seqaddr = val; 
   36.91 +                break;
   36.92 +                case 0x3c5:
   36.93 +                o = ega->seqregs[ega->seqaddr & 0xf];
   36.94 +                ega->seqregs[ega->seqaddr & 0xf] = val;
   36.95 +                if (o != val && (ega->seqaddr & 0xf) == 1) 
   36.96 +                        ega_recalctimings(ega);
   36.97 +                switch (ega->seqaddr & 0xf)
   36.98                  {
   36.99 -                        case 1: if (scrblank && !(val&0x20)) fullchange=3; scrblank=(scrblank&~0x20)|(val&0x20); break;
  36.100 -                        case 2: writemask=val&0xF; break;
  36.101 +                        case 1: 
  36.102 +                        if (ega->scrblank && !(val & 0x20)) 
  36.103 +                                fullchange = 3; 
  36.104 +                        ega->scrblank = (ega->scrblank & ~0x20) | (val & 0x20); 
  36.105 +                        break;
  36.106 +                        case 2: 
  36.107 +                        ega->writemask = val & 0xf; 
  36.108 +                        break;
  36.109                          case 3:
  36.110 -                        charset=val&0xF;
  36.111 -                        charseta=((charset>>2)*0x10000)+2;
  36.112 -                        charsetb=((charset&3) *0x10000)+2;
  36.113 +                        ega->charseta = (((val >> 2) & 3) * 0x10000) + 2;
  36.114 +                        ega->charsetb = ((val & 3)        * 0x10000) + 2;
  36.115                          break;
  36.116                  }
  36.117                  break;
  36.118 -                case 0x3CE: gdcaddr=val; break;
  36.119 -                case 0x3CF:
  36.120 -                gdcreg[gdcaddr&15]=val;
  36.121 -                switch (gdcaddr&15)
  36.122 +                case 0x3ce: 
  36.123 +                ega->gdcaddr = val; 
  36.124 +                break;
  36.125 +                case 0x3cf:
  36.126 +                ega->gdcreg[ega->gdcaddr & 15] = val;
  36.127 +                switch (ega->gdcaddr & 15)
  36.128                  {
  36.129 -                        case 2: colourcompare=val; break;
  36.130 -                        case 4: readplane=val&3; break;
  36.131 -                        case 5: writemode=val&3; readmode=val&8; break;
  36.132 +                        case 2: 
  36.133 +                        ega->colourcompare = val; 
  36.134 +                        break;
  36.135 +                        case 4: 
  36.136 +                        ega->readplane = val & 3; 
  36.137 +                        break;
  36.138 +                        case 5: 
  36.139 +                        ega->writemode = val & 3;
  36.140 +                        ega->readmode = val & 8; 
  36.141 +                        break;
  36.142                          case 6:
  36.143 -                        mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL,        NULL);
  36.144 +                        mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega);
  36.145  //                                pclog("Write mapping %02X\n", val);
  36.146 -                        switch (val&0xC)
  36.147 +                        switch (val & 0xc)
  36.148                          {
  36.149                                  case 0x0: /*128k at A0000*/
  36.150 -                                mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL,   NULL);
  36.151 +                                mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega);
  36.152                                  break;
  36.153                                  case 0x4: /*64k at A0000*/
  36.154 -                                mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL,   NULL);
  36.155 +                                mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega);
  36.156                                  break;
  36.157                                  case 0x8: /*32k at B0000*/
  36.158 -                                mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL,   NULL);
  36.159 +                                mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega);
  36.160                                  break;
  36.161                                  case 0xC: /*32k at B8000*/
  36.162 -                                mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL,   NULL);
  36.163 +                                mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega);
  36.164                                  break;
  36.165                          }
  36.166 -
  36.167                          break;
  36.168 -                        case 7: colournocare=val; break;
  36.169 +                        case 7: 
  36.170 +                        ega->colournocare = val; 
  36.171 +                        break;
  36.172                  }
  36.173                  break;
  36.174 -                case 0x3D4:
  36.175 -                crtcreg=val;
  36.176 +                case 0x3d4:
  36.177 +                        pclog("Write 3d4 %02X  %04X:%04X\n", val, CS, pc);
  36.178 +                ega->crtcreg = val & 31;
  36.179                  return;
  36.180 -                case 0x3D5:
  36.181 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
  36.182 -                old=crtc[crtcreg];
  36.183 -                crtc[crtcreg]=val;
  36.184 -                if (old!=val)
  36.185 +                case 0x3d5:
  36.186 +                        pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]);
  36.187 +//                if (ega->crtcreg == 1 && val == 0x14)
  36.188 +//                        fatal("Here\n");
  36.189 +                if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) return;
  36.190 +                old = ega->crtc[ega->crtcreg];
  36.191 +                ega->crtc[ega->crtcreg] = val;
  36.192 +                if (old != val)
  36.193                  {
  36.194 -                        if (crtcreg<0xE || crtcreg>0x10)
  36.195 +                        if (ega->crtcreg < 0xe || ega->crtcreg > 0x10)
  36.196                          {
  36.197 -                                fullchange=changeframecount;
  36.198 -                                ega_recalctimings();
  36.199 +                                fullchange = changeframecount;
  36.200 +                                ega_recalctimings(ega);
  36.201                          }
  36.202                  }
  36.203                  break;
  36.204          }
  36.205  }
  36.206  
  36.207 -uint8_t ega_in(uint16_t addr, void *priv)
  36.208 +uint8_t ega_in(uint16_t addr, void *p)
  36.209  {
  36.210 -        if ((addr&0xFFF0) == 0x3B0) addr |= 0x20;
  36.211 +        ega_t *ega = (ega_t *)p;
  36.212 +
  36.213 +if (addr != 0x3da && addr != 0x3ba)
  36.214 +        pclog("ega_in %04X\n", addr);
  36.215 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) 
  36.216 +                addr ^= 0x60;
  36.217 +
  36.218          switch (addr)
  36.219          {
  36.220 -                case 0x3C0: return attraddr;
  36.221 -                case 0x3C1: return attrregs[attraddr];
  36.222 -                case 0x3C2:
  36.223 +                case 0x3c0: 
  36.224 +                return ega->attraddr;
  36.225 +                case 0x3c1: 
  36.226 +                return ega->attrregs[ega->attraddr];
  36.227 +                case 0x3c2:
  36.228  //                printf("Read egaswitch %02X %02X %i\n",egaswitchread,egaswitches,VGA);
  36.229                  switch (egaswitchread)
  36.230                  {
  36.231 -                        case 0xC: return (egaswitches&1)?0x10:0;
  36.232 -                        case 0x8: return (egaswitches&2)?0x10:0;
  36.233 -                        case 0x4: return (egaswitches&4)?0x10:0;
  36.234 -                        case 0x0: return (egaswitches&8)?0x10:0;
  36.235 +                        case 0xc: return (egaswitches & 1) ? 0x10 : 0;
  36.236 +                        case 0x8: return (egaswitches & 2) ? 0x10 : 0;
  36.237 +                        case 0x4: return (egaswitches & 4) ? 0x10 : 0;
  36.238 +                        case 0x0: return (egaswitches & 8) ? 0x10 : 0;
  36.239                  }
  36.240                  break;
  36.241 -                case 0x3C4: return seqaddr;
  36.242 -                case 0x3C5:
  36.243 -                return seqregs[seqaddr&0xF];
  36.244 -                case 0x3CE: return gdcaddr;
  36.245 -                case 0x3CF:
  36.246 -                return gdcreg[gdcaddr&0xF];
  36.247 -                case 0x3D4:
  36.248 -                return crtcreg;
  36.249 -                case 0x3D5:
  36.250 -                return crtc[crtcreg];
  36.251 -                case 0x3DA:
  36.252 -                attrff=0;
  36.253 -                cgastat^=0x30; /*Fools IBM EGA video BIOS self-test*/
  36.254 -                return cgastat;
  36.255 +                case 0x3c4: 
  36.256 +                return ega->seqaddr;
  36.257 +                case 0x3c5:
  36.258 +                return ega->seqregs[ega->seqaddr & 0xf];
  36.259 +                case 0x3ce: 
  36.260 +                return ega->gdcaddr;
  36.261 +                case 0x3cf:
  36.262 +                return ega->gdcreg[ega->gdcaddr & 0xf];
  36.263 +                case 0x3d4:
  36.264 +                return ega->crtcreg;
  36.265 +                case 0x3d5:
  36.266 +                return ega->crtc[ega->crtcreg];
  36.267 +                case 0x3da:
  36.268 +                ega->attrff = 0;
  36.269 +                ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/
  36.270 +                return ega->stat;
  36.271          }
  36.272  //        printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc);
  36.273 -        return 0xFF;
  36.274 +        return 0xff;
  36.275  }
  36.276  
  36.277 -static int linepos,displine,vslines;
  36.278 -static int egadispon;
  36.279 -static uint32_t ma,ca,maback;
  36.280 -static int vc,sc;
  36.281 -static int con,cursoron,cgablink;
  36.282 -static int scrollcache;
  36.283 -#define vrammask 0x3FFFF
  36.284 -
  36.285 -void ega_recalctimings()
  36.286 +void ega_recalctimings(ega_t *ega)
  36.287  {
  36.288 -	double _dispontime, _dispofftime;
  36.289 +	double _dispontime, _dispofftime, disptime;
  36.290          double crtcconst;
  36.291  
  36.292 -        ega_vtotal=crtc[6];
  36.293 -        ega_dispend=crtc[0x12];
  36.294 -        ega_vsyncstart=crtc[0x10];
  36.295 -        ega_split=crtc[0x18];
  36.296 +        ega->vtotal = ega->crtc[6];
  36.297 +        ega->dispend = ega->crtc[0x12];
  36.298 +        ega->vsyncstart = ega->crtc[0x10];
  36.299 +        ega->split = ega->crtc[0x18];
  36.300  
  36.301 -        if (crtc[7]&1) ega_vtotal|=0x100;
  36.302 -        if (crtc[7]&32) ega_vtotal|=0x200;
  36.303 -        ega_vtotal++;
  36.304 +        if (ega->crtc[7] & 1)  ega->vtotal |= 0x100;
  36.305 +        if (ega->crtc[7] & 32) ega->vtotal |= 0x200;
  36.306 +        ega->vtotal++;
  36.307  
  36.308 -        if (crtc[7]&2) ega_dispend|=0x100;
  36.309 -        if (crtc[7]&64) ega_dispend|=0x200;
  36.310 -        ega_dispend++;
  36.311 +        if (ega->crtc[7] & 2)  ega->dispend |= 0x100;
  36.312 +        if (ega->crtc[7] & 64) ega->dispend |= 0x200;
  36.313 +        ega->dispend++;
  36.314  
  36.315 -        if (crtc[7]&4) ega_vsyncstart|=0x100;
  36.316 -        if (crtc[7]&128) ega_vsyncstart|=0x200;
  36.317 -        ega_vsyncstart++;
  36.318 +        if (ega->crtc[7] & 4)   ega->vsyncstart |= 0x100;
  36.319 +        if (ega->crtc[7] & 128) ega->vsyncstart |= 0x200;
  36.320 +        ega->vsyncstart++;
  36.321  
  36.322 -        if (crtc[7]&0x10)    ega_split|=0x100;
  36.323 -        if (crtc[9]&0x40)    ega_split|=0x200;
  36.324 -        ega_split+=2;
  36.325 +        if (ega->crtc[7] & 0x10) ega->split |= 0x100;
  36.326 +        if (ega->crtc[9] & 0x40) ega->split |= 0x200;
  36.327 +        ega->split+=2;
  36.328  
  36.329 -        ega_hdisp=crtc[1];
  36.330 -        ega_hdisp++;
  36.331 +        ega->hdisp = ega->crtc[1];
  36.332 +        ega->hdisp++;
  36.333  
  36.334 -        ega_rowoffset=crtc[0x13];
  36.335 +        ega->rowoffset = ega->crtc[0x13];
  36.336  
  36.337 -        printf("Recalc! %i %i %i %i   %i %02X\n",ega_vtotal,ega_dispend,ega_vsyncstart,ega_split,ega_hdisp,attrregs[0x16]);
  36.338 +        printf("Recalc! %i %i %i %i   %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, ega->attrregs[0x16]);
  36.339  
  36.340 -        if (vidclock) crtcconst=(seqregs[1]&1)?(MDACONST*(8.0/9.0)):MDACONST;
  36.341 -        else          crtcconst=(seqregs[1]&1)?(CGACONST*(8.0/9.0)):CGACONST;
  36.342 +        if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0));
  36.343 +        else               crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0));
  36.344  
  36.345 -        disptime=crtc[0]+2;
  36.346 -        _dispontime=crtc[1]+1;
  36.347 +        disptime = ega->crtc[0] + 2;
  36.348 +        _dispontime = ega->crtc[1] + 1;
  36.349  
  36.350 -        printf("Disptime %f dispontime %f hdisp %i\n",disptime,_dispontime,crtc[1]*8);
  36.351 -        if (seqregs[1]&8) { disptime*=2; _dispontime*=2; }
  36.352 -        _dispofftime=disptime-_dispontime;
  36.353 -        _dispontime*=crtcconst;
  36.354 -        _dispofftime*=crtcconst;
  36.355 +        printf("Disptime %f dispontime %f hdisp %i\n", disptime, _dispontime, ega->crtc[1] * 8);
  36.356 +        if (ega->seqregs[1] & 8) 
  36.357 +        { 
  36.358 +                disptime*=2; 
  36.359 +                _dispontime*=2; 
  36.360 +        }
  36.361 +        _dispofftime = disptime - _dispontime;
  36.362 +        _dispontime  *= crtcconst;
  36.363 +        _dispofftime *= crtcconst;
  36.364  
  36.365 -	dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  36.366 -	dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  36.367 -
  36.368 +	ega->dispontime  = (int)(_dispontime  * (1 << TIMER_SHIFT));
  36.369 +	ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  36.370 +        pclog("dispontime %i (%f)  dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime / (1 << TIMER_SHIFT),
  36.371 +                                                           ega->dispofftime, (float)ega->dispofftime / (1 << TIMER_SHIFT));
  36.372  //        printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4));
  36.373  //        printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart);
  36.374  //        printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*ega_vtotal,(dispontime+dispofftime)*ega_vtotal*70,seqregs[1]);
  36.375  }
  36.376  
  36.377 -void ega_poll()
  36.378 +void ega_poll(void *p)
  36.379  {
  36.380 -        uint8_t chr,dat,attr;
  36.381 +        ega_t *ega = (ega_t *)p;
  36.382 +        uint8_t chr, dat, attr;
  36.383          uint32_t charaddr;
  36.384 -        int x,xx;
  36.385 -        uint32_t fg,bg;
  36.386 +        int x, xx;
  36.387 +        uint32_t fg, bg;
  36.388          int offset;
  36.389          uint8_t edat[4];
  36.390 -        int drawcursor=0;
  36.391 +        int drawcursor = 0;
  36.392  
  36.393 -        if (!linepos)
  36.394 +        if (!ega->linepos)
  36.395          {
  36.396 -                vidtime+=dispofftime;
  36.397 +                ega->vidtime += ega->dispofftime;
  36.398  
  36.399 -                cgastat|=1;
  36.400 -                linepos=1;
  36.401 +                ega->stat |= 1;
  36.402 +                ega->linepos = 1;
  36.403  
  36.404 -                if (egadispon)
  36.405 +                if (ega->dispon)
  36.406                  {
  36.407 -                        if (firstline==2000) firstline=displine;
  36.408 +                        if (ega->firstline == 2000) 
  36.409 +                                ega->firstline = ega->displine;
  36.410  
  36.411 -                        if (scrblank)
  36.412 +                        if (ega->scrblank)
  36.413                          {
  36.414 -                                for (x=0;x<ega_hdisp;x++)
  36.415 +                                for (x = 0; x < ega->hdisp; x++)
  36.416                                  {
  36.417 -                                        switch (seqregs[1]&9)
  36.418 +                                        switch (ega->seqregs[1] & 9)
  36.419                                          {
  36.420                                                  case 0:
  36.421 -                                                for (xx=0;xx<9;xx++) ((uint32_t *)buffer32->line[displine])[(x*9)+xx+32]=0;
  36.422 +                                                for (xx = 0; xx < 9; xx++)  ((uint32_t *)buffer32->line[ega->displine])[(x * 9) + xx + 32] = 0;
  36.423                                                  break;
  36.424                                                  case 1:
  36.425 -                                                for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[(x*8)+xx+32]=0;
  36.426 +                                                for (xx = 0; xx < 8; xx++)  ((uint32_t *)buffer32->line[ega->displine])[(x * 8) + xx + 32] = 0;
  36.427                                                  break;
  36.428                                                  case 8:
  36.429 -                                                for (xx=0;xx<18;xx++) ((uint32_t *)buffer32->line[displine])[(x*18)+xx+32]=0;
  36.430 +                                                for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[ega->displine])[(x * 18) + xx + 32] = 0;
  36.431                                                  break;
  36.432                                                  case 9:
  36.433 -                                                for (xx=0;xx<16;xx++) ((uint32_t *)buffer32->line[displine])[(x*16)+xx+32]=0;
  36.434 +                                                for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[ega->displine])[(x * 16) + xx + 32] = 0;
  36.435                                                  break;
  36.436                                          }
  36.437                                  }
  36.438                          }
  36.439 -                        else if (!(gdcreg[6]&1))
  36.440 +                        else if (!(ega->gdcreg[6] & 1))
  36.441                          {
  36.442                                  if (fullchange)
  36.443                                  {
  36.444 -                                        for (x=0;x<ega_hdisp;x++)
  36.445 +                                        for (x = 0; x < ega->hdisp; x++)
  36.446                                          {
  36.447 -                                                drawcursor=((ma==ca) && con && cursoron);
  36.448 -                                                chr=vram[(ma<<1)];
  36.449 -                                                attr=vram[(ma<<1)+4];
  36.450 +                                                drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
  36.451 +                                                chr  = ega->vram[(ega->ma << 1) & ega->vrammask];
  36.452 +                                                attr = ega->vram[((ega->ma << 1) + 4) & ega->vrammask];
  36.453  
  36.454 -                                                if (attr&8) charaddr=charsetb+(chr*128);
  36.455 -                                                else        charaddr=charseta+(chr*128);
  36.456 +                                                if (attr & 8) charaddr = ega->charsetb + (chr * 128);
  36.457 +                                                else          charaddr = ega->charseta + (chr * 128);
  36.458  
  36.459 -                                                if (drawcursor) { bg=pallook[egapal[attr&15]]; fg=pallook[egapal[attr>>4]]; }
  36.460 +                                                if (drawcursor) 
  36.461 +                                                { 
  36.462 +                                                        bg = ega->pallook[ega->egapal[attr & 15]]; 
  36.463 +                                                        fg = ega->pallook[ega->egapal[attr >> 4]]; 
  36.464 +                                                }
  36.465                                                  else
  36.466                                                  {
  36.467 -                                                        fg=pallook[egapal[attr&15]];
  36.468 -                                                        bg=pallook[egapal[attr>>4]];
  36.469 -                                                        if (attr&0x80 && attrregs[0x10]&8)
  36.470 +                                                        fg = ega->pallook[ega->egapal[attr & 15]];
  36.471 +                                                        bg = ega->pallook[ega->egapal[attr >> 4]];
  36.472 +                                                        if (attr & 0x80 && ega->attrregs[0x10] & 8)
  36.473                                                          {
  36.474 -                                                                bg=pallook[egapal[(attr>>4)&7]];
  36.475 -                                                                if (cgablink&16) fg=bg;
  36.476 +                                                                bg = ega->pallook[ega->egapal[(attr >> 4) & 7]];
  36.477 +                                                                if (ega->blink & 16) 
  36.478 +                                                                        fg = bg;
  36.479                                                          }
  36.480                                                  }
  36.481  
  36.482 -                                                dat=vram[charaddr+(sc<<2)];
  36.483 -                                                if (seqregs[1]&8)
  36.484 +                                                dat = ega->vram[charaddr + (ega->sc << 2)];
  36.485 +                                                if (ega->seqregs[1] & 8)
  36.486                                                  {
  36.487 -                                                        if (seqregs[1]&1) { for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x<<4)+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[((x<<4)+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg; }
  36.488 +                                                        if (ega->seqregs[1] & 1) 
  36.489 +                                                        { 
  36.490 +                                                                for (xx = 0; xx < 8; xx++) 
  36.491 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 32 + (xx << 1)) & 2047] =
  36.492 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; 
  36.493 +                                                        }
  36.494                                                          else
  36.495                                                          {
  36.496 -                                                                for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x*18)+32+(xx<<1))&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+33+(xx<<1))&2047]=(dat&(0x80>>xx))?fg:bg;
  36.497 -                                                                if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) ((uint32_t *)buffer32->line[displine])[((x*18)+32+16)&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+32+17)&2047]=bg;
  36.498 -                                                                else                  ((uint32_t *)buffer32->line[displine])[((x*18)+32+16)&2047]=((uint32_t *)buffer32->line[displine])[((x*18)+32+17)&2047]=(dat&1)?fg:bg;
  36.499 +                                                                for (xx = 0; xx < 8; xx++) 
  36.500 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + (xx << 1)) & 2047] = 
  36.501 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
  36.502 +                                                                if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) 
  36.503 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = 
  36.504 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = bg;
  36.505 +                                                                else                  
  36.506 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = 
  36.507 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = (dat & 1) ? fg : bg;
  36.508                                                          }
  36.509                                                  }
  36.510                                                  else
  36.511                                                  {
  36.512 -                                                        if (seqregs[1]&1) { for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x<<3)+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; }
  36.513 +                                                        if (ega->seqregs[1] & 1) 
  36.514 +                                                        { 
  36.515 +                                                                for (xx = 0; xx < 8; xx++) 
  36.516 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x << 3) + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; 
  36.517 +                                                        }
  36.518                                                          else
  36.519                                                          {
  36.520 -                                                                for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[((x*9)+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg;
  36.521 -                                                                if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) ((uint32_t *)buffer32->line[displine])[((x*9)+32+8)&2047]=bg;
  36.522 -                                                                else                  ((uint32_t *)buffer32->line[displine])[((x*9)+32+8)&2047]=(dat&1)?fg:bg;
  36.523 +                                                                for (xx = 0; xx < 8; xx++) 
  36.524 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
  36.525 +                                                                if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) 
  36.526 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = bg;
  36.527 +                                                                else                  
  36.528 +                                                                        ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = (dat & 1) ? fg : bg;
  36.529                                                          }
  36.530                                                  }
  36.531 -                                                ma+=4; ma&=vrammask;
  36.532 +                                                ega->ma += 4; 
  36.533 +                                                ega->ma &= ega->vrammask;
  36.534                                          }
  36.535                                  }
  36.536                          }
  36.537                          else
  36.538                          {
  36.539 -                                switch (gdcreg[5]&0x20)
  36.540 +                                switch (ega->gdcreg[5] & 0x20)
  36.541                                  {
  36.542                                          case 0x00:
  36.543 -                                        if (seqregs[1]&8)
  36.544 +                                        if (ega->seqregs[1] & 8)
  36.545                                          {
  36.546 -                                                offset=((8-scrollcache)<<1)+16;
  36.547 -                                                for (x=0;x<=ega_hdisp;x++)
  36.548 +                                                offset = ((8 - ega->scrollcache) << 1) + 16;
  36.549 +                                                for (x = 0; x <= ega->hdisp; x++)
  36.550                                                  {
  36.551 -                                                        if (sc&1 && !(crtc[0x17]&1))
  36.552 +                                                        if (ega->sc & 1 && !(ega->crtc[0x17] & 1))
  36.553                                                          {
  36.554 -                                                                edat[0] = vram[ma | 0x8000];
  36.555 -                                                                edat[1] = vram[ma | 0x8001];
  36.556 -                                                                edat[2] = vram[ma | 0x8002];
  36.557 -                                                                edat[3] = vram[ma | 0x8003];
  36.558 +                                                                edat[0] = ega->vram[ega->ma | 0x8000];
  36.559 +                                                                edat[1] = ega->vram[ega->ma | 0x8001];
  36.560 +                                                                edat[2] = ega->vram[ega->ma | 0x8002];
  36.561 +                                                                edat[3] = ega->vram[ega->ma | 0x8003];
  36.562                                                          }
  36.563                                                          else
  36.564                                                          {
  36.565 -                                                                edat[0] = vram[ma];
  36.566 -                                                                edat[1] = vram[ma | 0x1];
  36.567 -                                                                edat[2] = vram[ma | 0x2];
  36.568 -                                                                edat[3] = vram[ma | 0x3];
  36.569 +                                                                edat[0] = ega->vram[ega->ma];
  36.570 +                                                                edat[1] = ega->vram[ega->ma | 0x1];
  36.571 +                                                                edat[2] = ega->vram[ega->ma | 0x2];
  36.572 +                                                                edat[3] = ega->vram[ega->ma | 0x3];
  36.573                                                          }
  36.574 -                                                        ma+=4; ma&=vrammask;
  36.575 +                                                        ega->ma += 4; 
  36.576 +                                                        ega->ma &= ega->vrammask;
  36.577  
  36.578 -                                                        dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
  36.579 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<4)+14+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+15+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]];
  36.580 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<4)+12+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+13+offset]=pallook[egapal[(dat >> 4)  & attrregs[0x12]]];
  36.581 -                                                        dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
  36.582 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<4)+10+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+11+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]];
  36.583 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<4)+8+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+9+offset]=pallook[egapal[(dat >> 4)  & attrregs[0x12]]];
  36.584 -                                                        dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
  36.585 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<4)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+7+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]];
  36.586 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<4)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+5+offset]=pallook[egapal[(dat >> 4)  & attrregs[0x12]]];
  36.587 -                                                        dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
  36.588 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<4)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+3+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]];
  36.589 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<4)+offset]=   ((uint32_t *)buffer32->line[displine])[(x<<4)+1+offset]=pallook[egapal[(dat >> 4)  & attrregs[0x12]]];
  36.590 +                                                        dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
  36.591 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 14 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
  36.592 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = ega->pallook[ega->egapal[(dat >> 4)  & ega->attrregs[0x12]]];
  36.593 +                                                        dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
  36.594 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
  36.595 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  9 + offset] = ega->pallook[ega->egapal[(dat >> 4)  & ega->attrregs[0x12]]];
  36.596 +                                                        dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
  36.597 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  7 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
  36.598 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  5 + offset] = ega->pallook[ega->egapal[(dat >> 4)  & ega->attrregs[0x12]]];
  36.599 +                                                        dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
  36.600 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  3 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
  36.601 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +      offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  1 + offset] = ega->pallook[ega->egapal[(dat >> 4)  & ega->attrregs[0x12]]];
  36.602                                                  }
  36.603                                          }
  36.604                                          else
  36.605                                          {
  36.606 -                                                offset=(8-scrollcache)+24;
  36.607 -                                                for (x=0;x<=ega_hdisp;x++)
  36.608 +                                                offset = (8 - ega->scrollcache) + 24;
  36.609 +                                                for (x = 0; x <= ega->hdisp; x++)
  36.610                                                  {
  36.611 -                                                        if (sc&1 && !(crtc[0x17]&1))
  36.612 +                                                        if (ega->sc & 1 && !(ega->crtc[0x17] & 1))
  36.613                                                          {
  36.614 -                                                                edat[0] = vram[ma | 0x8000];
  36.615 -                                                                edat[1] = vram[ma | 0x8001];
  36.616 -                                                                edat[2] = vram[ma | 0x8002];
  36.617 -                                                                edat[3] = vram[ma | 0x8003];
  36.618 +                                                                edat[0] = ega->vram[ega->ma | 0x8000];
  36.619 +                                                                edat[1] = ega->vram[ega->ma | 0x8001];
  36.620 +                                                                edat[2] = ega->vram[ega->ma | 0x8002];
  36.621 +                                                                edat[3] = ega->vram[ega->ma | 0x8003];
  36.622                                                          }
  36.623                                                          else
  36.624                                                          {
  36.625 -                                                                edat[0] = vram[ma];
  36.626 -                                                                edat[1] = vram[ma | 0x1];
  36.627 -                                                                edat[2] = vram[ma | 0x2];
  36.628 -                                                                edat[3] = vram[ma | 0x3];
  36.629 +                                                                edat[0] = ega->vram[ega->ma];
  36.630 +                                                                edat[1] = ega->vram[ega->ma | 0x1];
  36.631 +                                                                edat[2] = ega->vram[ega->ma | 0x2];
  36.632 +                                                                edat[3] = ega->vram[ega->ma | 0x3];
  36.633                                                          }
  36.634 -                                                        ma+=4; ma&=vrammask;
  36.635 +                                                        ega->ma += 4; 
  36.636 +                                                        ega->ma &= ega->vrammask;
  36.637  
  36.638 -                                                        dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
  36.639 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<3)+7+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]];
  36.640 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<3)+6+offset]=pallook[egapal[(dat >> 4)  & attrregs[0x12]]];
  36.641 -                                                        dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
  36.642 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<3)+5+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]];
  36.643 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<3)+4+offset]=pallook[egapal[(dat >> 4)  & attrregs[0x12]]];
  36.644 -                                                        dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
  36.645 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<3)+3+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]];
  36.646 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<3)+2+offset]=pallook[egapal[(dat >> 4)  & attrregs[0x12]]];
  36.647 -                                                        dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
  36.648 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<3)+1+offset]=pallook[egapal[(dat & 0xF) & attrregs[0x12]]];
  36.649 -                                                        ((uint32_t *)buffer32->line[displine])[(x<<3)+offset]=  pallook[egapal[(dat >> 4)  & attrregs[0x12]]];
  36.650 +                                                        dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
  36.651 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 7 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
  36.652 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 6 + offset] = ega->pallook[ega->egapal[(dat >> 4)  & ega->attrregs[0x12]]];
  36.653 +                                                        dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
  36.654 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 5 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
  36.655 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 4 + offset] = ega->pallook[ega->egapal[(dat >> 4)  & ega->attrregs[0x12]]];
  36.656 +                                                        dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
  36.657 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 3 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
  36.658 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 2 + offset] = ega->pallook[ega->egapal[(dat >> 4)  & ega->attrregs[0x12]]];
  36.659 +                                                        dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
  36.660 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 1 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]];
  36.661 +                                                        ((uint32_t *)buffer32->line[ega->displine])[(x << 3) +     offset] = ega->pallook[ega->egapal[(dat >> 4)  & ega->attrregs[0x12]]];
  36.662                                                  }
  36.663                                          }
  36.664                                          break;
  36.665                                          case 0x20:
  36.666 -                                        offset=((8-scrollcache)<<1)+16;
  36.667 -                                        for (x=0;x<=ega_hdisp;x++)
  36.668 +                                        offset = ((8 - ega->scrollcache) << 1) + 16;
  36.669 +                                        for (x = 0; x <= ega->hdisp; x++)
  36.670                                          {
  36.671 -                                                if (sc&1 && !(crtc[0x17]&1))
  36.672 +                                                if (ega->sc & 1 && !(ega->crtc[0x17] & 1))
  36.673                                                  {
  36.674 -                                                        edat[0]=vram[(ma<<1)+0x8000];
  36.675 -                                                        edat[1]=vram[(ma<<1)+0x8004];
  36.676 +                                                        edat[0] = ega->vram[(ega->ma << 1) + 0x8000];
  36.677 +                                                        edat[1] = ega->vram[(ega->ma << 1) + 0x8004];
  36.678                                                  }
  36.679                                                  else
  36.680                                                  {
  36.681 -                                                        edat[0]=vram[(ma<<1)];
  36.682 -                                                        edat[1]=vram[(ma<<1)+4];
  36.683 +                                                        edat[0] = ega->vram[(ega->ma << 1)];
  36.684 +                                                        edat[1] = ega->vram[(ega->ma << 1) + 4];
  36.685                                                  }
  36.686 -                                                ma+=4; ma&=vrammask;
  36.687 +                                                ega->ma += 4; 
  36.688 +                                                ega->ma &= ega->vrammask;
  36.689  
  36.690 -                                                ((uint32_t *)buffer32->line[displine])[(x<<4)+14+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+15+offset]=pallook[egapal[edat[1]&3]];
  36.691 -                                                ((uint32_t *)buffer32->line[displine])[(x<<4)+12+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+13+offset]=pallook[egapal[(edat[1]>>2)&3]];
  36.692 -                                                dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
  36.693 -                                                ((uint32_t *)buffer32->line[displine])[(x<<4)+10+offset]=((uint32_t *)buffer32->line[displine])[(x<<4)+11+offset]=pallook[egapal[(edat[1]>>4)&3]];
  36.694 -                                                ((uint32_t *)buffer32->line[displine])[(x<<4)+8+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+9+offset]=pallook[egapal[(edat[1]>>6)&3]];
  36.695 -                                                dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
  36.696 -                                                ((uint32_t *)buffer32->line[displine])[(x<<4)+6+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+7+offset]=pallook[egapal[(edat[0]>>0)&3]];
  36.697 -                                                ((uint32_t *)buffer32->line[displine])[(x<<4)+4+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+5+offset]=pallook[egapal[(edat[0]>>2)&3]];
  36.698 -                                                dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
  36.699 -                                                ((uint32_t *)buffer32->line[displine])[(x<<4)+2+offset]= ((uint32_t *)buffer32->line[displine])[(x<<4)+3+offset]=pallook[egapal[(edat[0]>>4)&3]];
  36.700 -                                                ((uint32_t *)buffer32->line[displine])[(x<<4)+offset]=   ((uint32_t *)buffer32->line[displine])[(x<<4)+1+offset]=pallook[egapal[(edat[0]>>6)&3]];
  36.701 +                                                ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 14 + offset]=  ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[edat[1] & 3]];
  36.702 +                                                ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]];
  36.703 +                                                ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]];
  36.704 +                                                ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  9 + offset] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]];
  36.705 +                                                ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  7 + offset] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]];
  36.706 +                                                ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  5 + offset] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]];
  36.707 +                                                ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  3 + offset] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]];
  36.708 +                                                ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +      offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) +  1 + offset] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]];
  36.709                                          }
  36.710                                          break;
  36.711                                  }
  36.712                          }
  36.713 -                        if (lastline<displine) lastline=displine;
  36.714 +                        if (ega->lastline < ega->displine) 
  36.715 +                                ega->lastline = ega->displine;
  36.716                  }
  36.717  
  36.718 -                displine++;
  36.719 -                if ((cgastat&8) && ((displine&15)==(crtc[0x11]&15)) && vslines)
  36.720 -                   cgastat&=~8;
  36.721 -                vslines++;
  36.722 -                if (displine>500) displine=0;
  36.723 +                ega->displine++;
  36.724 +                if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines)
  36.725 +                        ega->stat &= ~8;
  36.726 +                ega->vslines++;
  36.727 +                if (ega->displine > 500) 
  36.728 +                        ega->displine = 0;
  36.729          }
  36.730          else
  36.731          {
  36.732 -                vidtime+=dispontime;
  36.733 +                ega->vidtime += ega->dispontime;
  36.734  //                if (output) printf("Display on %f\n",vidtime);
  36.735 -                if (egadispon) cgastat&=~1;
  36.736 -                linepos=0;
  36.737 -                if (sc==(crtc[11]&31)) 
  36.738 -                   con=0; 
  36.739 -                if (egadispon)
  36.740 +                if (ega->dispon) 
  36.741 +                        ega->stat &= ~1;
  36.742 +                ega->linepos = 0;
  36.743 +                if (ega->sc == (ega->crtc[11] & 31)) 
  36.744 +                   ega->con = 0; 
  36.745 +                if (ega->dispon)
  36.746                  {
  36.747 -                        if (sc==(crtc[9]&31))
  36.748 +                        if (ega->sc == (ega->crtc[9] & 31))
  36.749                          {
  36.750 -                                sc=0;
  36.751 +                                ega->sc = 0;
  36.752  
  36.753 -                                maback+=(ega_rowoffset<<3);
  36.754 -                                maback&=vrammask;
  36.755 -                                ma=maback;
  36.756 +                                ega->maback += (ega->rowoffset << 3);
  36.757 +                                ega->maback &= ega->vrammask;
  36.758 +                                ega->ma = ega->maback;
  36.759                          }
  36.760                          else
  36.761                          {
  36.762 -                                sc++;
  36.763 -                                sc&=31;
  36.764 -                                ma=maback;
  36.765 +                                ega->sc++;
  36.766 +                                ega->sc &= 31;
  36.767 +                                ega->ma = ega->maback;
  36.768                          }
  36.769                  }
  36.770 -                vc++;
  36.771 -                vc&=1023;
  36.772 +                ega->vc++;
  36.773 +                ega->vc &= 1023;
  36.774  //                printf("Line now %i %i ma %05X\n",vc,displine,ma);
  36.775 -                if (vc==ega_split)
  36.776 +                if (ega->vc == ega->split)
  36.777                  {
  36.778  //                        printf("Split at line %i %i\n",displine,vc);
  36.779 -                        ma=maback=0;
  36.780 -                        if (attrregs[0x10]&0x20) scrollcache=0;
  36.781 +                        ega->ma = ega->maback = 0;
  36.782 +                        if (ega->attrregs[0x10] & 0x20)
  36.783 +                                ega->scrollcache = 0;
  36.784                  }
  36.785 -                if (vc==ega_dispend)
  36.786 +                if (ega->vc == ega->dispend)
  36.787                  {
  36.788  //                        printf("Display over at line %i %i\n",displine,vc);
  36.789 -                        egadispon=0;
  36.790 -                        if (crtc[10] & 0x20) cursoron=0;
  36.791 -                        else                 cursoron=cgablink&16;
  36.792 -                        if (!(gdcreg[6]&1) && !(cgablink&15)) fullchange=2;
  36.793 -                        cgablink++;
  36.794 +                        ega->dispon=0;
  36.795 +                        if (ega->crtc[10] & 0x20) ega->cursoron = 0;
  36.796 +                        else                      ega->cursoron = ega->blink & 16;
  36.797 +                        if (!(ega->gdcreg[6] & 1) && !(ega->blink & 15)) 
  36.798 +                                fullchange = 2;
  36.799 +                        ega->blink++;
  36.800  
  36.801 -                        for (x=0;x<2048;x++) if (changedvram[x]) changedvram[x]--;
  36.802 -//                        memset(changedvram,0,2048);
  36.803 -                        if (fullchange) fullchange--;
  36.804 +                        if (fullchange) 
  36.805 +                                fullchange--;
  36.806                  }
  36.807 -                if (vc==ega_vsyncstart)
  36.808 +                if (ega->vc == ega->vsyncstart)
  36.809                  {
  36.810 -                        egadispon=0;
  36.811 +                        int wx, wy;
  36.812 +                        ega->dispon = 0;
  36.813  //                        printf("Vsync on at line %i %i\n",displine,vc);
  36.814 -                        cgastat|=8;
  36.815 -                        if (seqregs[1]&8) x=ega_hdisp*((seqregs[1]&1)?8:9)*2;
  36.816 -                        else              x=ega_hdisp*((seqregs[1]&1)?8:9);
  36.817 -                        wx=x;
  36.818 -                        wy=lastline-firstline;
  36.819 +                        ega->stat |= 8;
  36.820 +                        if (ega->seqregs[1] & 8) x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9) * 2;
  36.821 +                        else                     x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9);
  36.822  //                        pclog("Cursor %02X %02X\n",crtc[10],crtc[11]);
  36.823  //                        pclog("Firstline %i Lastline %i wx %i %i\n",firstline,lastline,wx,oddeven);
  36.824  //                        doblit();
  36.825 -                        svga_doblit(firstline, lastline + 1);
  36.826 +                        if (x != xsize || (ega->lastline - ega->firstline) != ysize)
  36.827 +                        {
  36.828 +                                xsize = x;
  36.829 +                                ysize = ega->lastline - ega->firstline;
  36.830 +                                if (xsize < 64) xsize = 656;
  36.831 +                                if (ysize < 32) ysize = 200;
  36.832 +                                if (ega->vres)
  36.833 +                                        updatewindowsize(xsize, ysize << 1);
  36.834 +                                else
  36.835 +                                        updatewindowsize(xsize, ysize);
  36.836 +                        }
  36.837 +                                        
  36.838 +startblit();
  36.839 +                        video_blit_memtoscreen(32, 0, ega->firstline, ega->lastline, xsize, ega->lastline - ega->firstline);
  36.840 +endblit();
  36.841  
  36.842 -                        video_res_x = wx;
  36.843 -                        video_res_y = wy + 1;
  36.844 -                        if (!(gdcreg[6]&1)) /*Text mode*/
  36.845 +                        frames++;
  36.846 +                        
  36.847 +                        ega->video_res_x = wx;
  36.848 +                        ega->video_res_y = wy + 1;
  36.849 +                        if (!(ega->gdcreg[6] & 1)) /*Text mode*/
  36.850                          {
  36.851 -                                video_res_x /= (seqregs[1] & 1) ? 8 : 9;
  36.852 -                                video_res_y /= (crtc[9] & 31) + 1;
  36.853 -                                video_bpp = 0;
  36.854 +                                ega->video_res_x /= (ega->seqregs[1] & 1) ? 8 : 9;
  36.855 +                                ega->video_res_y /= (ega->crtc[9] & 31) + 1;
  36.856 +                                ega->video_bpp = 0;
  36.857                          }
  36.858                          else
  36.859                          {
  36.860 -                                if (crtc[9] & 0x80)
  36.861 -                                   video_res_y /= 2;
  36.862 -                                if (!(crtc[0x17] & 1))
  36.863 -                                   video_res_y *= 2;
  36.864 -                                video_res_y /= (crtc[9] & 31) + 1;                                   
  36.865 -                                if (seqregs[1] & 8)
  36.866 -                                   video_res_x /= 2;
  36.867 -                                video_bpp = (gdcreg[5] & 0x20) ? 2 : 4;
  36.868 +                                if (ega->crtc[9] & 0x80)
  36.869 +                                   ega->video_res_y /= 2;
  36.870 +                                if (!(ega->crtc[0x17] & 1))
  36.871 +                                   ega->video_res_y *= 2;
  36.872 +                                ega->video_res_y /= (ega->crtc[9] & 31) + 1;                                   
  36.873 +                                if (ega->seqregs[1] & 8)
  36.874 +                                   ega->video_res_x /= 2;
  36.875 +                                ega->video_bpp = (ega->gdcreg[5] & 0x20) ? 2 : 4;
  36.876                          }
  36.877  
  36.878  //                        wakeupblit();
  36.879                          readflash=0;
  36.880                          //framecount++;
  36.881 -                        firstline=2000;
  36.882 -                        lastline=0;
  36.883 +                        ega->firstline = 2000;
  36.884 +                        ega->lastline = 0;
  36.885  
  36.886 -                        maback=ma=(crtc[0xC]<<8)|crtc[0xD];
  36.887 -                        ca=(crtc[0xE]<<8)|crtc[0xF];
  36.888 -                        ma<<=2;
  36.889 -                        maback<<=2;
  36.890 -                        ca<<=2;
  36.891 -                        changeframecount=2;
  36.892 -                        vslines=0;
  36.893 +                        ega->maback = ega->ma = (ega->crtc[0xc] << 8)| ega->crtc[0xd];
  36.894 +                        ega->ca = (ega->crtc[0xe] << 8) | ega->crtc[0xf];
  36.895 +                        ega->ma <<= 2;
  36.896 +                        ega->maback <<= 2;
  36.897 +                        ega->ca <<= 2;
  36.898 +                        changeframecount = 2;
  36.899 +                        ega->vslines = 0;
  36.900                  }
  36.901 -                if (vc==ega_vtotal)
  36.902 +                if (ega->vc == ega->vtotal)
  36.903                  {
  36.904 -                        vc=0;
  36.905 -                        sc=0;
  36.906 -                        egadispon=1;
  36.907 -                        displine=0;
  36.908 -                        scrollcache=attrregs[0x13]&7;
  36.909 +                        ega->vc = 0;
  36.910 +                        ega->sc = 0;
  36.911 +                        ega->dispon = 1;
  36.912 +                        ega->displine = 0;
  36.913 +                        ega->scrollcache = ega->attrregs[0x13] & 7;
  36.914                  }
  36.915 -                if (sc == (crtc[10] & 31)) con=1;
  36.916 +                if (ega->sc == (ega->crtc[10] & 31)) 
  36.917 +                        ega->con = 1;
  36.918          }
  36.919  }
  36.920  
  36.921  
  36.922 -void ega_write(uint32_t addr, uint8_t val, void *priv)
  36.923 +void ega_write(uint32_t addr, uint8_t val, void *p)
  36.924  {
  36.925 -        uint8_t vala,valb,valc,vald;
  36.926 +        ega_t *ega = (ega_t *)p;
  36.927 +        uint8_t vala, valb, valc, vald;
  36.928  
  36.929          egawrites++;
  36.930          cycles -= video_timing_b;
  36.931          cycles_lost += video_timing_b;
  36.932          
  36.933 -        if (addr>=0xB0000) addr &= 0x7fff;
  36.934 -        else               addr &= 0xffff;
  36.935 +        if (addr >= 0xB0000) addr &= 0x7fff;
  36.936 +        else                 addr &= 0xffff;
  36.937  
  36.938 -        if (!(gdcreg[6]&1)) fullchange=2;
  36.939 +        if (!(ega->gdcreg[6] & 1)) 
  36.940 +                fullchange = 2;
  36.941          addr <<= 2;
  36.942  
  36.943  //        pclog("%i %08X %i %i %02X   %02X %02X %02X %02X\n",chain4,addr,writemode,writemask,gdcreg[8],vram[0],vram[1],vram[2],vram[3]);
  36.944 -        switch (writemode)
  36.945 +        switch (ega->writemode)
  36.946 +        {
  36.947 +                case 1:
  36.948 +                if (ega->writemask & 1) ega->vram[addr]       = ega->la;
  36.949 +                if (ega->writemask & 2) ega->vram[addr | 0x1] = ega->lb;
  36.950 +                if (ega->writemask & 4) ega->vram[addr | 0x2] = ega->lc;
  36.951 +                if (ega->writemask & 8) ega->vram[addr | 0x3] = ega->ld;
  36.952 +                break;
  36.953 +                case 0:
  36.954 +                if (ega->gdcreg[3] & 7) 
  36.955 +                        val = ega_rotate[ega->gdcreg[3] & 7][val];
  36.956 +                        
  36.957 +                if (ega->gdcreg[8] == 0xff && !(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1])
  36.958                  {
  36.959 -                        case 1:
  36.960 -                        if (writemask&1) vram[addr]=la;
  36.961 -                        if (writemask&2) vram[addr|0x1]=lb;
  36.962 -                        if (writemask&4) vram[addr|0x2]=lc;
  36.963 -                        if (writemask&8) vram[addr|0x3]=ld;
  36.964 -                        break;
  36.965 -                        case 0:
  36.966 -                        if (gdcreg[3]&7) val=ega_rotate[gdcreg[3]&7][val];
  36.967 -                        if (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1])
  36.968 +                        if (ega->writemask & 1) ega->vram[addr]       = val;
  36.969 +                        if (ega->writemask & 2) ega->vram[addr | 0x1] = val;
  36.970 +                        if (ega->writemask & 4) ega->vram[addr | 0x2] = val;
  36.971 +                        if (ega->writemask & 8) ega->vram[addr | 0x3] = val;
  36.972 +                }
  36.973 +                else
  36.974 +                {
  36.975 +                        if (ega->gdcreg[1] & 1) vala = (ega->gdcreg[0] & 1) ? 0xff : 0;
  36.976 +                        else                    vala = val;
  36.977 +                        if (ega->gdcreg[1] & 2) valb = (ega->gdcreg[0] & 2) ? 0xff : 0;
  36.978 +                        else                    valb = val;
  36.979 +                        if (ega->gdcreg[1] & 4) valc = (ega->gdcreg[0] & 4) ? 0xff : 0;
  36.980 +                        else                    valc = val;
  36.981 +                        if (ega->gdcreg[1] & 8) vald = (ega->gdcreg[0] & 8) ? 0xff : 0;
  36.982 +                        else                    vald = val;
  36.983 +//                                pclog("Write %02X %01X %02X %02X %02X %02X  %02X\n",gdcreg[3]&0x18,writemask,vala,valb,valc,vald,gdcreg[8]);
  36.984 +                        switch (ega->gdcreg[3] & 0x18)
  36.985                          {
  36.986 -//                                pclog("Easy write %05X %02X\n",addr,val);
  36.987 -                                if (writemask&1) vram[addr]=val;
  36.988 -                                if (writemask&2) vram[addr|0x1]=val;
  36.989 -                                if (writemask&4) vram[addr|0x2]=val;
  36.990 -                                if (writemask&8) vram[addr|0x3]=val;
  36.991 +                                case 0: /*Set*/
  36.992 +                                if (ega->writemask & 1) ega->vram[addr]       = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]);
  36.993 +                                if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]);
  36.994 +                                if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]);
  36.995 +                                if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]);
  36.996 +                                break;
  36.997 +                                case 8: /*AND*/
  36.998 +                                if (ega->writemask & 1) ega->vram[addr]       = (vala | ~ega->gdcreg[8]) & ega->la;
  36.999 +                                if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb;
 36.1000 +                                if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc;
 36.1001 +                                if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld;
 36.1002 +                                break;
 36.1003 +                                case 0x10: /*OR*/
 36.1004 +                                if (ega->writemask & 1) ega->vram[addr]       = (vala & ega->gdcreg[8]) | ega->la;
 36.1005 +                                if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb;
 36.1006 +                                if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc;
 36.1007 +                                if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld;
 36.1008 +                                break;
 36.1009 +                                case 0x18: /*XOR*/
 36.1010 +                                if (ega->writemask & 1) ega->vram[addr]       = (vala & ega->gdcreg[8]) ^ ega->la;
 36.1011 +                                if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb;
 36.1012 +                                if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc;
 36.1013 +                                if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld;
 36.1014 +                                break;
 36.1015                          }
 36.1016 -                        else
 36.1017 +//                                pclog("- %02X %02X %02X %02X   %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr);
 36.1018 +                }
 36.1019 +                break;
 36.1020 +                case 2:
 36.1021 +                if (!(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1])
 36.1022 +                {
 36.1023 +                        if (ega->writemask & 1) ega->vram[addr]       = (((val & 1) ? 0xff : 0) & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]);
 36.1024 +                        if (ega->writemask & 2) ega->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]);
 36.1025 +                        if (ega->writemask & 4) ega->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]);
 36.1026 +                        if (ega->writemask & 8) ega->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]);
 36.1027 +                }
 36.1028 +                else
 36.1029 +                {
 36.1030 +                        vala = ((val & 1) ? 0xff : 0);
 36.1031 +                        valb = ((val & 2) ? 0xff : 0);
 36.1032 +                        valc = ((val & 4) ? 0xff : 0);
 36.1033 +                        vald = ((val & 8) ? 0xff : 0);
 36.1034 +                        switch (ega->gdcreg[3] & 0x18)
 36.1035                          {
 36.1036 -                                if (gdcreg[1]&1) vala=(gdcreg[0]&1)?0xFF:0;
 36.1037 -                                else             vala=val;
 36.1038 -                                if (gdcreg[1]&2) valb=(gdcreg[0]&2)?0xFF:0;
 36.1039 -                                else             valb=val;
 36.1040 -                                if (gdcreg[1]&4) valc=(gdcreg[0]&4)?0xFF:0;
 36.1041 -                                else             valc=val;
 36.1042 -                                if (gdcreg[1]&8) vald=(gdcreg[0]&8)?0xFF:0;
 36.1043 -                                else             vald=val;
 36.1044 -//                                pclog("Write %02X %01X %02X %02X %02X %02X  %02X\n",gdcreg[3]&0x18,writemask,vala,valb,valc,vald,gdcreg[8]);
 36.1045 -                                switch (gdcreg[3]&0x18)
 36.1046 -                                {
 36.1047 -                                        case 0: /*Set*/
 36.1048 -                                        if (writemask&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
 36.1049 -                                        if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
 36.1050 -                                        if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
 36.1051 -                                        if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
 36.1052 -                                        break;
 36.1053 -                                        case 8: /*AND*/
 36.1054 -                                        if (writemask&1) vram[addr]=(vala|~gdcreg[8])&la;
 36.1055 -                                        if (writemask&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
 36.1056 -                                        if (writemask&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
 36.1057 -                                        if (writemask&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
 36.1058 -                                        break;
 36.1059 -                                        case 0x10: /*OR*/
 36.1060 -                                        if (writemask&1) vram[addr]=(vala&gdcreg[8])|la;
 36.1061 -                                        if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
 36.1062 -                                        if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
 36.1063 -                                        if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
 36.1064 -                                        break;
 36.1065 -                                        case 0x18: /*XOR*/
 36.1066 -                                        if (writemask&1) vram[addr]=(vala&gdcreg[8])^la;
 36.1067 -                                        if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
 36.1068 -                                        if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
 36.1069 -                                        if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
 36.1070 -                                        break;
 36.1071 -                                }
 36.1072 -//                                pclog("- %02X %02X %02X %02X   %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr);
 36.1073 +                                case 0: /*Set*/
 36.1074 +                                if (ega->writemask & 1) ega->vram[addr]       = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]);
 36.1075 +                                if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]);
 36.1076 +                                if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]);
 36.1077 +                                if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]);
 36.1078 +                                break;
 36.1079 +                                case 8: /*AND*/
 36.1080 +                                if (ega->writemask & 1) ega->vram[addr]       = (vala | ~ega->gdcreg[8]) & ega->la;
 36.1081 +                                if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb;
 36.1082 +                                if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc;
 36.1083 +                                if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld;
 36.1084 +                                break;
 36.1085 +                                case 0x10: /*OR*/
 36.1086 +                                if (ega->writemask & 1) ega->vram[addr]       = (vala & ega->gdcreg[8]) | ega->la;
 36.1087 +                                if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb;
 36.1088 +                                if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc;
 36.1089 +                                if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld;
 36.1090 +                                break;
 36.1091 +                                case 0x18: /*XOR*/
 36.1092 +                                if (ega->writemask & 1) ega->vram[addr]       = (vala & ega->gdcreg[8]) ^ ega->la;
 36.1093 +                                if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb;
 36.1094 +                                if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc;
 36.1095 +                                if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld;
 36.1096 +                                break;
 36.1097                          }
 36.1098 -                        break;
 36.1099 -                        case 2:
 36.1100 -                        if (!(gdcreg[3]&0x18) && !gdcreg[1])
 36.1101 -                        {
 36.1102 -                                if (writemask&1) vram[addr]=(((val&1)?0xFF:0)&gdcreg[8])|(la&~gdcreg[8]);
 36.1103 -                                if (writemask&2) vram[addr|0x1]=(((val&2)?0xFF:0)&gdcreg[8])|(lb&~gdcreg[8]);
 36.1104 -                                if (writemask&4) vram[addr|0x2]=(((val&4)?0xFF:0)&gdcreg[8])|(lc&~gdcreg[8]);
 36.1105 -                                if (writemask&8) vram[addr|0x3]=(((val&8)?0xFF:0)&gdcreg[8])|(ld&~gdcreg[8]);
 36.1106 -                        }
 36.1107 -                        else
 36.1108 -                        {
 36.1109 -                                vala=((val&1)?0xFF:0);
 36.1110 -                                valb=((val&2)?0xFF:0);
 36.1111 -                                valc=((val&4)?0xFF:0);
 36.1112 -                                vald=((val&8)?0xFF:0);
 36.1113 -                                switch (gdcreg[3]&0x18)
 36.1114 -                                {
 36.1115 -                                        case 0: /*Set*/
 36.1116 -                                        if (writemask&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
 36.1117 -                                        if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
 36.1118 -                                        if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
 36.1119 -                                        if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
 36.1120 -                                        break;
 36.1121 -                                        case 8: /*AND*/
 36.1122 -                                        if (writemask&1) vram[addr]=(vala|~gdcreg[8])&la;
 36.1123 -                                        if (writemask&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
 36.1124 -                                        if (writemask&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
 36.1125 -                                        if (writemask&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
 36.1126 -                                        break;
 36.1127 -                                        case 0x10: /*OR*/
 36.1128 -                                        if (writemask&1) vram[addr]=(vala&gdcreg[8])|la;
 36.1129 -                                        if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
 36.1130 -                                        if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
 36.1131 -                                        if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
 36.1132 -                                        break;
 36.1133 -                                        case 0x18: /*XOR*/
 36.1134 -                                        if (writemask&1) vram[addr]=(vala&gdcreg[8])^la;
 36.1135 -                                        if (writemask&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
 36.1136 -                                        if (writemask&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
 36.1137 -                                        if (writemask&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
 36.1138 -                                        break;
 36.1139 -                                }
 36.1140 -                        }
 36.1141 -                        break;
 36.1142                  }
 36.1143 +                break;
 36.1144 +        }
 36.1145  }
 36.1146  
 36.1147 -uint8_t ega_read(uint32_t addr, void *priv)
 36.1148 +uint8_t ega_read(uint32_t addr, void *p)
 36.1149  {
 36.1150 -        uint8_t temp,temp2,temp3,temp4;
 36.1151 +        ega_t *ega = (ega_t *)p;
 36.1152 +        uint8_t temp, temp2, temp3, temp4;
 36.1153          egareads++;
 36.1154          cycles -= video_timing_b;
 36.1155          cycles_lost += video_timing_b;
 36.1156  //        pclog("Readega %06X   ",addr);
 36.1157 -        if (addr>=0xB0000) addr &= 0x7fff;
 36.1158 -        else               addr &= 0xffff;
 36.1159 -        addr<<=2;
 36.1160 -        la=vram[addr];
 36.1161 -        lb=vram[addr|0x1];
 36.1162 -        lc=vram[addr|0x2];
 36.1163 -        ld=vram[addr|0x3];
 36.1164 -        if (readmode)
 36.1165 +        if (addr >= 0xb0000) addr &= 0x7fff;
 36.1166 +        else                 addr &= 0xffff;
 36.1167 +        addr <<= 2;
 36.1168 +        ega->la = ega->vram[addr];
 36.1169 +        ega->lb = ega->vram[addr | 0x1];
 36.1170 +        ega->lc = ega->vram[addr | 0x2];
 36.1171 +        ega->ld = ega->vram[addr | 0x3];
 36.1172 +        if (ega->readmode)
 36.1173          {
 36.1174 -                temp= (colournocare&1) ?0xFF:0;
 36.1175 -                temp&=la;
 36.1176 -                temp^=(colourcompare&1)?0xFF:0;
 36.1177 -                temp2= (colournocare&2) ?0xFF:0;
 36.1178 -                temp2&=lb;
 36.1179 -                temp2^=(colourcompare&2)?0xFF:0;
 36.1180 -                temp3= (colournocare&4) ?0xFF:0;
 36.1181 -                temp3&=lc;
 36.1182 -                temp3^=(colourcompare&4)?0xFF:0;
 36.1183 -                temp4= (colournocare&8) ?0xFF:0;
 36.1184 -                temp4&=ld;
 36.1185 -                temp4^=(colourcompare&8)?0xFF:0;
 36.1186 -                return ~(temp|temp2|temp3|temp4);
 36.1187 +                temp   = (ega->colournocare & 1)  ? 0xff : 0;
 36.1188 +                temp  &= ega->la;
 36.1189 +                temp  ^= (ega->colourcompare & 1) ? 0xff : 0;
 36.1190 +                temp2  = (ega->colournocare & 2)  ? 0xff : 0;
 36.1191 +                temp2 &= ega->lb;
 36.1192 +                temp2 ^= (ega->colourcompare & 2) ? 0xff : 0;
 36.1193 +                temp3  = (ega->colournocare & 4)  ? 0xff : 0;
 36.1194 +                temp3 &= ega->lc;
 36.1195 +                temp3 ^= (ega->colourcompare & 4) ? 0xff : 0;
 36.1196 +                temp4  = (ega->colournocare & 8)  ? 0xff : 0;
 36.1197 +                temp4 &= ega->ld;
 36.1198 +                temp4 ^= (ega->colourcompare & 8) ? 0xff : 0;
 36.1199 +                return ~(temp | temp2 | temp3 | temp4);
 36.1200          }
 36.1201 -        return vram[addr|readplane];
 36.1202 +        return ega->vram[addr | ega->readplane];
 36.1203  }
 36.1204  
 36.1205 -int ega_init()
 36.1206 +void ega_init(ega_t *ega)
 36.1207  {
 36.1208          int c, d, e;
 36.1209 +        
 36.1210 +        ega->vram = malloc(0x40000);
 36.1211 +        ega->vrammask = 0x3ffff;
 36.1212 +        
 36.1213          for (c = 0; c < 256; c++)
 36.1214          {
 36.1215                  e = c;
 36.1216 @@ -693,28 +781,64 @@
 36.1217                          e = (e >> 1) | ((e & 1) ? 0x80 : 0);
 36.1218                  }
 36.1219          }
 36.1220 -        return 0;
 36.1221 +
 36.1222 +        for (c = 0; c < 4; c++)
 36.1223 +        {
 36.1224 +                for (d = 0; d < 4; d++)
 36.1225 +                {
 36.1226 +                        edatlookup[c][d] = 0;
 36.1227 +                        if (c & 1) edatlookup[c][d] |= 1;
 36.1228 +                        if (d & 1) edatlookup[c][d] |= 2;
 36.1229 +                        if (c & 2) edatlookup[c][d] |= 0x10;
 36.1230 +                        if (d & 2) edatlookup[c][d] |= 0x20;
 36.1231 +                }
 36.1232 +        }
 36.1233 +
 36.1234 +        for (c = 0; c < 256; c++)
 36.1235 +        {
 36.1236 +                pallook64[c]  = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa);
 36.1237 +                pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55);
 36.1238 +                pallook16[c]  = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa);
 36.1239 +                pallook16[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55);
 36.1240 +                if ((c & 0x17) == 6) 
 36.1241 +                        pallook16[c] = makecol32(0xaa, 0x55, 0);
 36.1242 +        }
 36.1243 +        ega->pallook = pallook16;
 36.1244  }
 36.1245  
 36.1246 -GFXCARD vid_ega =
 36.1247 +void *ega_standalone_init()
 36.1248  {
 36.1249 -        ega_init,
 36.1250 -        /*IO at 3Cx/3Dx*/
 36.1251 -        ega_out,
 36.1252 -        ega_in,
 36.1253 -        /*IO at 3Ax/3Bx*/
 36.1254 -        video_out_null,
 36.1255 -        video_in_null,
 36.1256 +        int c, d, e;
 36.1257 +        ega_t *ega = malloc(sizeof(ega_t));
 36.1258 +        memset(ega, 0, sizeof(ega_t));
 36.1259  
 36.1260 -        ega_poll,
 36.1261 -        ega_recalctimings,
 36.1262 +        ega_init(ega);        
 36.1263  
 36.1264 -        ega_write,
 36.1265 -        video_write_null,
 36.1266 -        video_write_null,
 36.1267 +        timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega);
 36.1268 +        io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
 36.1269 +        return ega;
 36.1270 +}
 36.1271  
 36.1272 -        ega_read,
 36.1273 -        video_read_null,
 36.1274 -        video_read_null
 36.1275 +void ega_close(void *p)
 36.1276 +{
 36.1277 +        ega_t *ega = (ega_t *)p;
 36.1278 +
 36.1279 +        free(ega->vram);
 36.1280 +        free(ega);
 36.1281 +}
 36.1282 +
 36.1283 +void ega_speed_changed(void *p)
 36.1284 +{
 36.1285 +        ega_t *ega = (ega_t *)p;
 36.1286 +        
 36.1287 +        ega_recalctimings(ega);
 36.1288 +}
 36.1289 +
 36.1290 +device_t ega_device =
 36.1291 +{
 36.1292 +        "EGA",
 36.1293 +        ega_standalone_init,
 36.1294 +        ega_close,
 36.1295 +        ega_speed_changed,
 36.1296 +        NULL
 36.1297  };
 36.1298 -
    37.1 --- a/src/vid_ega.h	Tue Jun 04 20:52:17 2013 +0100
    37.2 +++ b/src/vid_ega.h	Mon Jun 24 20:42:35 2013 +0100
    37.3 @@ -1,7 +1,71 @@
    37.4 -int     ega_init();
    37.5 -void    ega_out(uint16_t addr, uint8_t val, void *priv);
    37.6 -uint8_t ega_in(uint16_t addr, void *priv);
    37.7 -void    ega_poll();
    37.8 -void    ega_recalctimings();
    37.9 -void    ega_write(uint32_t addr, uint8_t val, void *priv);
   37.10 -uint8_t ega_read(uint32_t addr, void *priv);
   37.11 +typedef struct ega_t
   37.12 +{
   37.13 +        uint8_t crtcreg;
   37.14 +        uint8_t crtc[32];
   37.15 +        uint8_t gdcreg[16];
   37.16 +        int gdcaddr;
   37.17 +        uint8_t attrregs[32];
   37.18 +        int attraddr, attrff;
   37.19 +        uint8_t seqregs[64];
   37.20 +        int seqaddr;
   37.21 +        
   37.22 +        uint8_t miscout;
   37.23 +        int vidclock;
   37.24 +
   37.25 +        uint8_t la, lb, lc, ld;
   37.26 +        
   37.27 +        uint8_t stat;
   37.28 +        
   37.29 +        int fast;
   37.30 +        uint8_t colourcompare, colournocare;
   37.31 +        int readmode, writemode, readplane;
   37.32 +        int chain4;
   37.33 +        uint8_t writemask;
   37.34 +        uint32_t charseta, charsetb;
   37.35 +        
   37.36 +        uint8_t egapal[16];
   37.37 +        uint32_t *pallook;
   37.38 +
   37.39 +        int vtotal, dispend, vsyncstart, split;
   37.40 +        int hdisp,  htotal,  hdisp_time, rowoffset;
   37.41 +        int lowres, interlace;
   37.42 +        int linedbl, rowcount;
   37.43 +        double clock;
   37.44 +        uint32_t ma_latch;
   37.45 +        
   37.46 +        int vres;
   37.47 +        
   37.48 +        int dispontime, dispofftime;
   37.49 +        int vidtime;
   37.50 +        
   37.51 +        uint8_t scrblank;
   37.52 +        
   37.53 +        int dispon;
   37.54 +        int hdisp_on;
   37.55 +
   37.56 +        uint32_t ma, maback, ca;
   37.57 +        int vc;
   37.58 +        int sc;
   37.59 +        int linepos, vslines, linecountff, oddeven;
   37.60 +        int con, cursoron, blink;
   37.61 +        int scrollcache;
   37.62 +        
   37.63 +        int firstline, lastline;
   37.64 +        int firstline_draw, lastline_draw;
   37.65 +        int displine;
   37.66 +        
   37.67 +        uint8_t *vram;
   37.68 +        int vrammask;
   37.69 +
   37.70 +        int video_res_x, video_res_y, video_bpp;
   37.71 +} ega_t;
   37.72 +
   37.73 +void   *ega_standalone_init();
   37.74 +void    ega_out(uint16_t addr, uint8_t val, void *p);
   37.75 +uint8_t ega_in(uint16_t addr, void *p);
   37.76 +void    ega_poll(void *p);
   37.77 +void    ega_recalctimings(struct ega_t *ega);
   37.78 +void    ega_write(uint32_t addr, uint8_t val, void *p);
   37.79 +uint8_t ega_read(uint32_t addr, void *p);
   37.80 +
   37.81 +extern device_t ega_device;
    38.1 --- a/src/vid_et4000.c	Tue Jun 04 20:52:17 2013 +0100
    38.2 +++ b/src/vid_et4000.c	Mon Jun 24 20:42:35 2013 +0100
    38.3 @@ -1,141 +1,156 @@
    38.4  /*ET4000 emulation*/
    38.5 +#include <stdlib.h>
    38.6  #include "ibm.h"
    38.7 +#include "device.h"
    38.8  #include "io.h"
    38.9  #include "video.h"
   38.10  #include "vid_svga.h"
   38.11  #include "vid_unk_ramdac.h"
   38.12  
   38.13 -int et4k_b8000;
   38.14 +#include "vid_et4000.h"
   38.15  
   38.16 +typedef struct et4000_t
   38.17 +{
   38.18 +        svga_t svga;
   38.19 +        unk_ramdac_t ramdac;
   38.20 +        
   38.21 +        uint8_t banking;
   38.22 +} et4000_t;
   38.23  
   38.24 -void et4000_out(uint16_t addr, uint8_t val, void *priv)
   38.25 +void et4000_out(uint16_t addr, uint8_t val, void *p)
   38.26  {
   38.27 +        et4000_t *et4000 = (et4000_t *)p;
   38.28 +        svga_t *svga = &et4000->svga;
   38.29 +                
   38.30          uint8_t old;
   38.31          
   38.32 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   38.33 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) 
   38.34 +                addr ^= 0x60;
   38.35  
   38.36          pclog("ET4000 out %04X %02X\n", addr, val);
   38.37                  
   38.38          switch (addr)
   38.39          {
   38.40                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
   38.41 -                unk_ramdac_out(addr, val, NULL);
   38.42 +                unk_ramdac_out(addr, val, &et4000->ramdac, svga);
   38.43                  return;
   38.44                  
   38.45                  case 0x3CD: /*Banking*/
   38.46 -                svgawbank=(val&0xF)*65536;
   38.47 -                svgarbank=((val>>4)&0xF)*65536;
   38.48 -                svgaseg=val;
   38.49 -                pclog("Banking write %08X %08X %02X\n", svgawbank, svgarbank, val);
   38.50 +                svga->write_bank = (val & 0xf) * 0x10000;
   38.51 +                svga->read_bank = ((val >> 4) & 0xf) * 0x10000;
   38.52 +                et4000->banking = val;
   38.53 +                pclog("Banking write %08X %08X %02X\n", svga->write_bank, svga->read_bank, val);
   38.54                  return;
   38.55 -                case 0x3CF:
   38.56 -                switch (gdcaddr&15)
   38.57 -                {
   38.58 -                        case 6:
   38.59 -                        et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4);
   38.60 -                        break;
   38.61 -                }
   38.62 -                break;
   38.63                  case 0x3D4:
   38.64 -                crtcreg = val & 0x3f;
   38.65 +                svga->crtcreg = val & 0x3f;
   38.66                  return;
   38.67                  case 0x3D5:
   38.68 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
   38.69 -                old=crtc[crtcreg];
   38.70 -                crtc[crtcreg]=val;
   38.71 -                et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4);
   38.72 -                if (old!=val)
   38.73 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
   38.74 +                old = svga->crtc[svga->crtcreg];
   38.75 +                svga->crtc[svga->crtcreg] = val;
   38.76 +                if (old != val)
   38.77                  {
   38.78 -                        if (crtcreg<0xE || crtcreg>0x10)
   38.79 +                        if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
   38.80                          {
   38.81 -                                fullchange=changeframecount;
   38.82 -                                svga_recalctimings();
   38.83 +                                fullchange = changeframecount;
   38.84 +                                svga_recalctimings(svga);
   38.85                          }
   38.86                  }
   38.87                  break;
   38.88 -                case 0x3D8:
   38.89 -                if (val==0xA0) svgaon=1;
   38.90 -                if (val==0x29) svgaon=0;
   38.91 -                break;
   38.92          }
   38.93 -        svga_out(addr, val, priv);
   38.94 +        svga_out(addr, val, svga);
   38.95  }
   38.96  
   38.97 -uint8_t et4000_in(uint16_t addr, void *priv)
   38.98 +uint8_t et4000_in(uint16_t addr, void *p)
   38.99  {
  38.100 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  38.101 +        et4000_t *et4000 = (et4000_t *)p;
  38.102 +        svga_t *svga = &et4000->svga;
  38.103 +
  38.104 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) 
  38.105 +                addr ^= 0x60;
  38.106          
  38.107          if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr);
  38.108          
  38.109          switch (addr)
  38.110          {
  38.111                  case 0x3C5:
  38.112 -                if ((seqaddr&0xF)==7) return seqregs[seqaddr&0xF]|4;
  38.113 +                if ((svga->seqaddr & 0xf) == 7) return svga->seqregs[svga->seqaddr & 0xf] | 4;
  38.114                  break;
  38.115  
  38.116                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  38.117 -                return unk_ramdac_in(addr, NULL);
  38.118 +                return unk_ramdac_in(addr, &et4000->ramdac, svga);
  38.119                  
  38.120                  case 0x3CD: /*Banking*/
  38.121 -                return svgaseg;
  38.122 +                return et4000->banking;
  38.123                  case 0x3D4:
  38.124 -                return crtcreg;
  38.125 +                return svga->crtcreg;
  38.126                  case 0x3D5:
  38.127 -                return crtc[crtcreg];
  38.128 +                return svga->crtc[svga->crtcreg];
  38.129          }
  38.130 -        return svga_in(addr, priv);
  38.131 +        return svga_in(addr, svga);
  38.132  }
  38.133  
  38.134 -void et4000_recalctimings()
  38.135 +void et4000_recalctimings(svga_t *svga)
  38.136  {
  38.137 -        svga_ma|=(crtc[0x33]&3)<<16;
  38.138 -        if (crtc[0x35]&2)    svga_vtotal+=0x400;
  38.139 -        if (crtc[0x35]&4)    svga_dispend+=0x400;
  38.140 -        if (crtc[0x35]&8)    svga_vsyncstart+=0x400;
  38.141 -        if (crtc[0x35]&0x10) svga_split+=0x400;
  38.142 -        if (!svga_rowoffset) svga_rowoffset=0x100;
  38.143 -//        if (crtc[0x3F]&0x80) svga_rowoffset+=0x100;
  38.144 -        if (crtc[0x3F]&1)    svga_htotal+=256;
  38.145 -        if (attrregs[0x16]&0x20) svga_hdisp<<=1;
  38.146 +        et4000_t *et4000 = (et4000_t *)svga->p;
  38.147 +
  38.148 +        svga->ma_latch |= (svga->crtc[0x33]&3)<<16;
  38.149 +        if (svga->crtc[0x35] & 2)    svga->vtotal += 0x400;
  38.150 +        if (svga->crtc[0x35] & 4)    svga->dispend += 0x400;
  38.151 +        if (svga->crtc[0x35] & 8)    svga->vsyncstart += 0x400;
  38.152 +        if (svga->crtc[0x35] & 0x10) svga->split += 0x400;
  38.153 +        if (!svga->rowoffset)        svga->rowoffset = 0x100;
  38.154 +        if (svga->crtc[0x3f] & 1)    svga->htotal += 256;
  38.155 +        if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1;
  38.156  
  38.157  //        pclog("Rowoffset %i\n",svga_rowoffset);
  38.158  
  38.159 -        switch (((svga_miscout >> 2) & 3) | ((crtc[0x34] << 1) & 4))
  38.160 +        switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4))
  38.161          {
  38.162                  case 0: case 1: break;
  38.163 -                case 3: svga_clock = cpuclock/40000000.0; break;
  38.164 -                case 5: svga_clock = cpuclock/65000000.0; break;
  38.165 -                default: svga_clock = cpuclock/36000000.0; break;
  38.166 +                case 3: svga->clock = cpuclock / 40000000.0; break;
  38.167 +                case 5: svga->clock = cpuclock / 65000000.0; break;
  38.168 +                default: svga->clock = cpuclock / 36000000.0; break;
  38.169          }
  38.170  
  38.171  }
  38.172  
  38.173 -int et4000_init()
  38.174 +void *et4000_init()
  38.175  {
  38.176 -        svga_recalctimings_ex = et4000_recalctimings;
  38.177 -        svga_vram_limit = 1 << 20; /*1mb*/
  38.178 -        vrammask = 0xfffff;
  38.179 -        return svga_init();
  38.180 +        et4000_t *et4000 = malloc(sizeof(et4000_t));
  38.181 +        memset(et4000, 0, sizeof(et4000_t));
  38.182 +        
  38.183 +        io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
  38.184 +
  38.185 +        svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/
  38.186 +                   et4000_recalctimings,
  38.187 +                   et4000_in, et4000_out,
  38.188 +                   NULL);
  38.189 +        
  38.190 +        return et4000;
  38.191  }
  38.192  
  38.193 -GFXCARD vid_et4000 =
  38.194 +void et4000_close(void *p)
  38.195  {
  38.196 +        et4000_t *et4000 = (et4000_t *)p;
  38.197 +
  38.198 +        svga_close(&et4000->svga);
  38.199 +        
  38.200 +        free(et4000);
  38.201 +}
  38.202 +
  38.203 +void et4000_speed_changed(void *p)
  38.204 +{
  38.205 +        et4000_t *et4000 = (et4000_t *)p;
  38.206 +        
  38.207 +        svga_recalctimings(&et4000->svga);
  38.208 +}
  38.209 +
  38.210 +device_t et4000_device =
  38.211 +{
  38.212 +        "Tseng Labs ET4000AX",
  38.213          et4000_init,
  38.214 -        /*IO at 3Cx/3Dx*/
  38.215 -        et4000_out,
  38.216 -        et4000_in,
  38.217 -        /*IO at 3Ax/3Bx*/
  38.218 -        video_out_null,
  38.219 -        video_in_null,
  38.220 -
  38.221 -        svga_poll,
  38.222 -        svga_recalctimings,
  38.223 -
  38.224 -        svga_write,
  38.225 -        video_write_null,
  38.226 -        video_write_null,
  38.227 -
  38.228 -        svga_read,
  38.229 -        video_read_null,
  38.230 -        video_read_null
  38.231 +        et4000_close,
  38.232 +        et4000_speed_changed,
  38.233 +        svga_add_status_info
  38.234  };
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/src/vid_et4000.h	Mon Jun 24 20:42:35 2013 +0100
    39.3 @@ -0,0 +1,1 @@
    39.4 +extern device_t et4000_device;
    40.1 --- a/src/vid_et4000w32.c	Tue Jun 04 20:52:17 2013 +0100
    40.2 +++ b/src/vid_et4000w32.c	Mon Jun 24 20:42:35 2013 +0100
    40.3 @@ -3,8 +3,9 @@
    40.4  
    40.5    - Accelerator doesn't work in planar modes
    40.6  */
    40.7 -
    40.8 +#include <stdlib.h>
    40.9  #include "ibm.h"
   40.10 +#include "device.h"
   40.11  #include "io.h"
   40.12  #include "pci.h"
   40.13  #include "video.h"
   40.14 @@ -13,719 +14,740 @@
   40.15  #include "vid_stg_ramdac.h"
   40.16  #include "mem.h"
   40.17  
   40.18 -int et4k_b8000;
   40.19 +typedef struct et4000w32p_t
   40.20 +{
   40.21 +        svga_t svga;
   40.22 +        stg_ramdac_t ramdac;
   40.23 +        icd2061_t icd2061;
   40.24  
   40.25 -void et4000w32p_recalcmapping();
   40.26 +        int index;
   40.27 +        uint8_t regs[256];
   40.28 +        uint32_t linearbase, linearbase_old;
   40.29  
   40.30 -uint8_t et4000w32p_mmu_read(uint32_t addr, void *priv);
   40.31 -void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv);
   40.32 +        uint8_t banking, banking2;
   40.33 +        
   40.34 +        /*Accelerator*/
   40.35 +        struct
   40.36 +        {
   40.37 +                struct
   40.38 +                {
   40.39 +                        uint32_t pattern_addr,source_addr,dest_addr,mix_addr;
   40.40 +                        uint16_t pattern_off,source_off,dest_off,mix_off;
   40.41 +                        uint8_t pixel_depth,xy_dir;
   40.42 +                        uint8_t pattern_wrap,source_wrap;
   40.43 +                        uint16_t count_x,count_y;
   40.44 +                        uint8_t ctrl_routing,ctrl_reload;
   40.45 +                        uint8_t rop_fg,rop_bg;
   40.46 +                        uint16_t pos_x,pos_y;
   40.47 +                        uint16_t error;
   40.48 +                        uint16_t dmin,dmaj;
   40.49 +                } queued,internal;
   40.50 +                uint32_t pattern_addr,source_addr,dest_addr,mix_addr;
   40.51 +                uint32_t pattern_back,source_back,dest_back,mix_back;
   40.52 +                int pattern_x,source_x;
   40.53 +                int pattern_x_back,source_x_back;
   40.54 +                int pattern_y,source_y;
   40.55 +                uint8_t status;
   40.56 +                uint64_t cpu_dat;
   40.57 +                int cpu_dat_pos;
   40.58 +                int pix_pos;
   40.59 +        } acl;
   40.60  
   40.61 -static int et4000w32p_index;
   40.62 -static uint8_t et4000w32p_regs[256];
   40.63 -static uint32_t et4000w32p_linearbase, et4000w32p_linearbase_old;
   40.64 +        struct
   40.65 +        {
   40.66 +                uint32_t base[3];
   40.67 +                uint8_t ctrl;
   40.68 +        } mmu;
   40.69 +} et4000w32p_t;
   40.70  
   40.71 -void et4000w32p_out(uint16_t addr, uint8_t val, void *priv)
   40.72 +void et4000w32p_recalcmapping(et4000w32p_t *et4000);
   40.73 +
   40.74 +uint8_t et4000w32p_mmu_read(uint32_t addr, void *p);
   40.75 +void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p);
   40.76 +
   40.77 +void et4000w32p_out(uint16_t addr, uint8_t val, void *p)
   40.78  {
   40.79 +        et4000w32p_t *et4000 = (et4000w32p_t *)p;
   40.80 +        svga_t *svga = &et4000->svga;
   40.81          uint8_t old;
   40.82  
   40.83 +        pclog("et4000w32p_out: addr %04X val %02X %04X:%04X  %02X %02X\n", addr, val, CS, pc, ram[0x487], ram[0x488]);
   40.84 +        
   40.85 +/*        if (ram[0x487] == 0x62)
   40.86 +                fatal("mono\n");*/
   40.87  //        if (!(addr==0x3D4 && (val&~1)==0xE) && !(addr==0x3D5 && (crtcreg&~1)==0xE)) pclog("ET4000W32p out %04X %02X  %04X:%04X  ",addr,val,CS,pc);
   40.88          
   40.89 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   40.90 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
   40.91 +                addr ^= 0x60;
   40.92          
   40.93  //        if (!(addr==0x3D4 && (val&~1)==0xE) && !(addr==0x3D5 && (crtcreg&~1)==0xE)) pclog("%04X\n",addr);
   40.94          
   40.95          switch (addr)
   40.96          {
   40.97                  case 0x3c2:
   40.98 -                icd2061_write((val >> 2) & 3);
   40.99 +                icd2061_write(&et4000->icd2061, (val >> 2) & 3);
  40.100                  break;
  40.101                  
  40.102                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  40.103 -                stg_ramdac_out(addr, val, NULL);
  40.104 +                stg_ramdac_out(addr, val, &et4000->ramdac, svga);
  40.105                  return;
  40.106                  
  40.107                  case 0x3CB: /*Banking extension*/
  40.108 -                svgawbank=(svgawbank&0xFFFFF)|((val&1)<<20);
  40.109 -                svgarbank=(svgarbank&0xFFFFF)|((val&0x10)<<16);
  40.110 -                svgaseg2=val;
  40.111 +                svga->write_bank = (svga->write_bank & 0xfffff) | ((val & 1) << 20);
  40.112 +                svga->read_bank  = (svga->read_bank  & 0xfffff) | ((val & 0x10) << 16);
  40.113 +                et4000->banking2 = val;
  40.114                  return;
  40.115                  case 0x3CD: /*Banking*/
  40.116 -                svgawbank=(svgawbank&0x100000)|((val&0xF)*65536);
  40.117 -                svgarbank=(svgarbank&0x100000)|(((val>>4)&0xF)*65536);
  40.118 -                svgaseg=val;
  40.119 +                svga->write_bank = (svga->write_bank & 0x100000) | ((val & 0xf) * 65536);
  40.120 +                svga->read_bank  = (svga->read_bank  & 0x100000) | (((val >> 4) & 0xf) * 65536);
  40.121 +                et4000->banking = val;
  40.122                  return;
  40.123                  case 0x3CF:
  40.124 -                switch (gdcaddr&15)
  40.125 +                switch (svga->gdcaddr & 15)
  40.126                  {
  40.127                          case 6:
  40.128 -                        gdcreg[gdcaddr&15]=val;
  40.129 +                        svga->gdcreg[svga->gdcaddr & 15] = val;
  40.130                          //et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4);
  40.131 -                        et4000w32p_recalcmapping();
  40.132 +                        et4000w32p_recalcmapping(et4000);
  40.133                          return;
  40.134                  }
  40.135                  break;
  40.136                  case 0x3D4:
  40.137 -                crtcreg=val&63;
  40.138 +                svga->crtcreg = val & 63;
  40.139                  return;
  40.140                  case 0x3D5:
  40.141  //                pclog("Write CRTC R%02X %02X\n", crtcreg, val);
  40.142 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
  40.143 -                old=crtc[crtcreg];
  40.144 -                crtc[crtcreg]=val;
  40.145 -                et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4);
  40.146 -//                if (crtcreg!=0xE && crtcreg!=0xF) pclog("CRTC R%02X = %02X\n",crtcreg,val);
  40.147 -                if (old!=val)
  40.148 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
  40.149 +                old = svga->crtc[svga->crtcreg];
  40.150 +                svga->crtc[svga->crtcreg] = val;
  40.151 +                if (old != val)
  40.152                  {
  40.153 -                        if (crtcreg<0xE || crtcreg>0x10)
  40.154 +                        if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
  40.155                          {
  40.156 -                                fullchange=changeframecount;
  40.157 -                                svga_recalctimings();
  40.158 +                                fullchange = changeframecount;
  40.159 +                                svga_recalctimings(svga);
  40.160                          }
  40.161                  }
  40.162 -                if (crtcreg == 0x30)
  40.163 +                if (svga->crtcreg == 0x30)
  40.164                  {
  40.165 -                        et4000w32p_linearbase = val * 0x400000;
  40.166 +                        et4000->linearbase = val * 0x400000;
  40.167  //                        pclog("Linear base now at %08X %02X\n", et4000w32p_linearbase, val);
  40.168 -                        et4000w32p_recalcmapping();
  40.169 +                        et4000w32p_recalcmapping(et4000);
  40.170                  }
  40.171 -                if (crtcreg == 0x36) et4000w32p_recalcmapping();
  40.172 -                break;
  40.173 -                case 0x3D8:
  40.174 -                if (val==0xA0) svgaon=1;
  40.175 -                if (val==0x29) svgaon=0;
  40.176 +                if (svga->crtcreg == 0x36) 
  40.177 +                        et4000w32p_recalcmapping(et4000);
  40.178                  break;
  40.179  
  40.180                  case 0x210A: case 0x211A: case 0x212A: case 0x213A:
  40.181                  case 0x214A: case 0x215A: case 0x216A: case 0x217A:
  40.182 -                et4000w32p_index=val;
  40.183 +                et4000->index=val;
  40.184                  return;
  40.185                  case 0x210B: case 0x211B: case 0x212B: case 0x213B:
  40.186                  case 0x214B: case 0x215B: case 0x216B: case 0x217B:
  40.187 -                et4000w32p_regs[et4000w32p_index] = val;
  40.188 -                svga_hwcursor.x     = et4000w32p_regs[0xE0] | ((et4000w32p_regs[0xE1] & 7) << 8);
  40.189 -                svga_hwcursor.y     = et4000w32p_regs[0xE4] | ((et4000w32p_regs[0xE5] & 7) << 8);
  40.190 -                svga_hwcursor.addr  = (et4000w32p_regs[0xE8] | (et4000w32p_regs[0xE9] << 8) | ((et4000w32p_regs[0xEA] & 7) << 16)) << 2;
  40.191 -                svga_hwcursor.addr += (et4000w32p_regs[0xE6] & 63) * 16;
  40.192 -                svga_hwcursor.ena   = et4000w32p_regs[0xF7] & 0x80;
  40.193 -                svga_hwcursor.xoff  = et4000w32p_regs[0xE2] & 63;
  40.194 -                svga_hwcursor.yoff  = et4000w32p_regs[0xE6] & 63;
  40.195 -//                pclog("HWCURSOR X %i Y %i\n",svga_hwcursor_x,svga_hwcursor_y);
  40.196 +                et4000->regs[et4000->index] = val;
  40.197 +                svga->hwcursor.x     = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8);
  40.198 +                svga->hwcursor.y     = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8);
  40.199 +                svga->hwcursor.addr  = (et4000->regs[0xE8] | (et4000->regs[0xE9] << 8) | ((et4000->regs[0xEA] & 7) << 16)) << 2;
  40.200 +                svga->hwcursor.addr += (et4000->regs[0xE6] & 63) * 16;
  40.201 +                svga->hwcursor.ena   = et4000->regs[0xF7] & 0x80;
  40.202 +                svga->hwcursor.xoff  = et4000->regs[0xE2] & 63;
  40.203 +                svga->hwcursor.yoff  = et4000->regs[0xE6] & 63;
  40.204 +//                pclog("HWCURSOR X %i Y %i\n",svga->hwcursor_x,svga->hwcursor_y);
  40.205                  return;
  40.206  
  40.207          }
  40.208 -        svga_out(addr, val, NULL);
  40.209 +        svga_out(addr, val, svga);
  40.210  }
  40.211  
  40.212 -uint8_t et4000w32p_in(uint16_t addr, void *priv)
  40.213 +uint8_t et4000w32p_in(uint16_t addr, void *p)
  40.214  {
  40.215 +        et4000w32p_t *et4000 = (et4000w32p_t *)p;
  40.216 +        svga_t *svga = &et4000->svga;
  40.217          uint8_t temp;
  40.218  //        if (addr==0x3DA) pclog("In 3DA %04X(%06X):%04X\n",CS,cs,pc);
  40.219          
  40.220  //        pclog("ET4000W32p in  %04X  %04X:%04X  ",addr,CS,pc);
  40.221  
  40.222 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  40.223 +        if (addr != 0x3da && addr != 0x3ba)
  40.224 +                pclog("et4000w32p_in: addr %04X %04X:%04X %02X %02X\n", addr, CS, pc, ram[0x487], ram[0x488]);
  40.225 +        
  40.226 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
  40.227 +                addr ^= 0x60;
  40.228          
  40.229  //        pclog("%04X\n",addr);
  40.230          
  40.231          switch (addr)
  40.232          {
  40.233 -                case 0x3C5:
  40.234 -                if ((seqaddr&0xF)==7) return seqregs[seqaddr&0xF]|4;
  40.235 +                case 0x3c5:
  40.236 +                if ((svga->seqaddr & 0xf) == 7) 
  40.237 +                        return svga->seqregs[svga->seqaddr & 0xf] | 4;
  40.238                  break;
  40.239  
  40.240                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  40.241 -                return stg_ramdac_in(addr, NULL);
  40.242 +                return stg_ramdac_in(addr, &et4000->ramdac, svga);
  40.243  
  40.244                  case 0x3CB:
  40.245 -                return svgaseg2;
  40.246 +                return et4000->banking2;
  40.247                  case 0x3CD:
  40.248 -                return svgaseg;
  40.249 +                return et4000->banking;
  40.250                  case 0x3D4:
  40.251 -                return crtcreg;
  40.252 +                return svga->crtcreg;
  40.253                  case 0x3D5:
  40.254  //                pclog("Read CRTC R%02X %02X\n", crtcreg, crtc[crtcreg]);
  40.255 -                return crtc[crtcreg];
  40.256 +                return svga->crtc[svga->crtcreg];
  40.257                  
  40.258                  case 0x3DA:
  40.259 -                attrff=0;
  40.260 -                cgastat^=0x30;
  40.261 -                temp = cgastat & 0x39;
  40.262 -                if (svga_hdisp_on) temp |= 2;
  40.263 -                if (!(cgastat & 8)) temp |= 0x80;
  40.264 +                svga->attrff = 0;
  40.265 +                svga->cgastat ^= 0x30;
  40.266 +                temp = svga->cgastat & 0x39;
  40.267 +                if (svga->hdisp_on) temp |= 2;
  40.268 +                if (!(svga->cgastat & 8)) temp |= 0x80;
  40.269  //                pclog("3DA in %02X\n",temp);
  40.270                  return temp;
  40.271  
  40.272                  case 0x210A: case 0x211A: case 0x212A: case 0x213A:
  40.273                  case 0x214A: case 0x215A: case 0x216A: case 0x217A:
  40.274 -                return et4000w32p_index;
  40.275 +                return et4000->index;
  40.276                  case 0x210B: case 0x211B: case 0x212B: case 0x213B:
  40.277                  case 0x214B: case 0x215B: case 0x216B: case 0x217B:
  40.278 -                if (et4000w32p_index==0xEC) return (et4000w32p_regs[0xEC]&0xF)|0x60; /*ET4000/W32p rev D*/
  40.279 -                if (et4000w32p_index == 0xEF) 
  40.280 +                if (et4000->index==0xec) 
  40.281 +                        return (et4000->regs[0xec] & 0xf) | 0x60; /*ET4000/W32p rev D*/
  40.282 +                if (et4000->index == 0xef) 
  40.283                  {
  40.284 -                        if (PCI) return et4000w32p_regs[0xEF] | 0xe0;       /*PCI*/
  40.285 -                        else     return et4000w32p_regs[0xEF] | 0x60;       /*VESA local bus*/
  40.286 +                        if (PCI) return et4000->regs[0xef] | 0xe0;       /*PCI*/
  40.287 +                        else     return et4000->regs[0xef] | 0x60;       /*VESA local bus*/
  40.288                  }
  40.289 -                return et4000w32p_regs[et4000w32p_index];
  40.290 +                return et4000->regs[et4000->index];
  40.291          }
  40.292 -        return svga_in(addr, NULL);
  40.293 +        return svga_in(addr, svga);
  40.294  }
  40.295  
  40.296 -void et4000w32p_recalctimings()
  40.297 +void et4000w32p_recalctimings(svga_t *svga)
  40.298  {
  40.299 +        et4000w32p_t *et4000 = (et4000w32p_t *)svga->p;
  40.300  //        pclog("Recalc %08X  ",svga_ma);
  40.301 -        svga_ma|=(crtc[0x33]&0x7)<<16;
  40.302 +        svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16;
  40.303  //        pclog("SVGA_MA %08X %i\n", svga_ma, (svga_miscout >> 2) & 3);
  40.304 -        if (crtc[0x35]&2)    svga_vtotal+=0x400;
  40.305 -        if (crtc[0x35]&4)    svga_dispend+=0x400;
  40.306 -        if (crtc[0x35]&8)    svga_vsyncstart+=0x400;
  40.307 -        if (crtc[0x35]&0x10) svga_split+=0x400;
  40.308 -        if (crtc[0x3F]&0x80) svga_rowoffset+=0x100;
  40.309 -        if (crtc[0x3F]&1)    svga_htotal+=256;
  40.310 -        if (attrregs[0x16]&0x20) svga_hdisp<<=1;
  40.311 +        if (svga->crtc[0x35] & 0x02)     svga->vtotal     += 0x400;
  40.312 +        if (svga->crtc[0x35] & 0x04)     svga->dispend    += 0x400;
  40.313 +        if (svga->crtc[0x35] & 0x08)     svga->vsyncstart += 0x400;
  40.314 +        if (svga->crtc[0x35] & 0x10)     svga->split      += 0x400;
  40.315 +        if (svga->crtc[0x3F] & 0x80)     svga->rowoffset  += 0x100;
  40.316 +        if (svga->crtc[0x3F] & 0x01)     svga->htotal     += 256;
  40.317 +        if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1;
  40.318          
  40.319 -        switch ((svga_miscout >> 2) & 3)
  40.320 +        switch ((svga->miscout >> 2) & 3)
  40.321          {
  40.322                  case 0: case 1: break;
  40.323 -                case 2: case 3: svga_clock = cpuclock/icd2061_getfreq(2); break;
  40.324 -/*                default: 
  40.325 -                        pclog("Unknown clock %i\n", ((svga_miscout >> 2) & 3) | ((crtc[0x34] << 1) & 4) | ((crtc[0x31] & 0xc0) >> 3));
  40.326 -                        svga_clock = cpuclock/36000000.0; break;*/
  40.327 +                case 2: case 3: svga->clock = cpuclock / icd2061_getfreq(&et4000->icd2061, 2); break;
  40.328          }
  40.329          
  40.330 -//        pclog("Recalctimings - %02X %02X %02X\n", crtc[6], crtc[7], crtc[0x35]);
  40.331 +        switch (svga->bpp)
  40.332 +        {
  40.333 +                case 15: case 16:
  40.334 +                svga->hdisp >>= 1;
  40.335 +                break;
  40.336 +                case 24:
  40.337 +                svga->hdisp /= 8;
  40.338 +                break;
  40.339 +        }
  40.340  }
  40.341  
  40.342 -int et4000w32p_getclock()
  40.343 +void et4000w32p_recalcmapping(et4000w32p_t *et4000)
  40.344  {
  40.345 -        return ((svga_miscout >> 2) & 3) | ((crtc[0x34] << 1) & 4) | ((crtc[0x31] & 0xc0) >> 3);
  40.346 -}
  40.347 -
  40.348 -
  40.349 -void et4000w32p_recalcmapping()
  40.350 -{
  40.351 -        int map;
  40.352 +        svga_t *svga = &et4000->svga;
  40.353          
  40.354 -        mem_removehandler(et4000w32p_linearbase_old, 0x200000,    svga_read_linear, svga_readw_linear, svga_readl_linear,    svga_write_linear, svga_writew_linear, svga_writel_linear,         NULL);
  40.355 -        mem_removehandler(                  0xa0000,  0x20000,           svga_read,        svga_readw,        svga_readl,           svga_write,        svga_writew,        svga_writel,         NULL);
  40.356 -        mem_removehandler(                  0xb0000,  0x10000, et4000w32p_mmu_read,              NULL,              NULL, et4000w32p_mmu_write,               NULL,               NULL,         NULL);    
  40.357 -        if (crtc[0x36] & 0x10) /*Linear frame buffer*/
  40.358 +        pclog("recalcmapping %p\n", svga);
  40.359 +        mem_removehandler(et4000->linearbase_old, 0x200000,    svga_read_linear, svga_readw_linear, svga_readl_linear,    svga_write_linear, svga_writew_linear, svga_writel_linear, svga);
  40.360 +        mem_removehandler(               0xa0000,  0x20000,           svga_read,        svga_readw,        svga_readl,           svga_write,        svga_writew,        svga_writel, svga);
  40.361 +        mem_removehandler(               0xb0000,  0x10000, et4000w32p_mmu_read,              NULL,              NULL, et4000w32p_mmu_write,               NULL,               NULL, et4000);
  40.362 +        if (svga->crtc[0x36] & 0x10) /*Linear frame buffer*/
  40.363          {
  40.364 -                mem_sethandler(et4000w32p_linearbase, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,      NULL);
  40.365 +                mem_sethandler(et4000->linearbase, 0x200000, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga);
  40.366          }
  40.367          else
  40.368          {
  40.369 -                map = (gdcreg[6] & 0xC) >> 2;
  40.370 -                if (crtc[0x36] & 0x20) map |= 4;
  40.371 -                if (crtc[0x36] & 0x08) map |= 8;
  40.372 +                int map = (svga->gdcreg[6] & 0xc) >> 2;
  40.373 +                if (svga->crtc[0x36] & 0x20) map |= 4;
  40.374 +                if (svga->crtc[0x36] & 0x08) map |= 8;
  40.375                  switch (map)
  40.376                  {
  40.377                          case 0x0: case 0x4: case 0x8: case 0xC: /*128k at A0000*/
  40.378 -                        mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  40.379 +                        mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  40.380                          break;
  40.381                          case 0x1: /*64k at A0000*/
  40.382 -                        mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  40.383 +                        mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  40.384                          break;
  40.385                          case 0x2: /*32k at B0000*/
  40.386 -                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  40.387 +                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  40.388                          break;
  40.389                          case 0x3: /*32k at B8000*/
  40.390 -                        mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  40.391 +                        mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  40.392                          break;
  40.393                          case 0x5: case 0x9: case 0xD: /*64k at A0000, MMU at B8000*/
  40.394 -                        mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  40.395 -                        mem_sethandler(0xb8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL,       NULL);                        
  40.396 +                        mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  40.397 +                        mem_sethandler(0xb8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, et4000);
  40.398                          break;
  40.399                          case 0x6: case 0xA: case 0xE: /*32k at B0000, MMU at A8000*/
  40.400 -                        mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL,       NULL);
  40.401 -                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  40.402 +                        mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, et4000);
  40.403 +                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  40.404                          break;
  40.405                          case 0x7: case 0xB: case 0xF: /*32k at B8000, MMU at A8000*/
  40.406 -                        mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL,       NULL);
  40.407 -                        mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  40.408 +                        mem_sethandler(0xa8000, 0x08000, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, et4000);
  40.409 +                        mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  40.410                          break;
  40.411                  }
  40.412  //                pclog("ET4K map %02X\n", map);
  40.413          }
  40.414 -        et4000w32p_linearbase_old = et4000w32p_linearbase;
  40.415 +        et4000->linearbase_old = et4000->linearbase;
  40.416  }
  40.417  
  40.418 -/*Accelerator*/
  40.419 -struct
  40.420 -{
  40.421 -        struct
  40.422 -        {
  40.423 -                uint32_t pattern_addr,source_addr,dest_addr,mix_addr;
  40.424 -                uint16_t pattern_off,source_off,dest_off,mix_off;
  40.425 -                uint8_t pixel_depth,xy_dir;
  40.426 -                uint8_t pattern_wrap,source_wrap;
  40.427 -                uint16_t count_x,count_y;
  40.428 -                uint8_t ctrl_routing,ctrl_reload;
  40.429 -                uint8_t rop_fg,rop_bg;
  40.430 -                uint16_t pos_x,pos_y;
  40.431 -                uint16_t error;
  40.432 -                uint16_t dmin,dmaj;
  40.433 -        } queued,internal;
  40.434 -        uint32_t pattern_addr,source_addr,dest_addr,mix_addr;
  40.435 -        uint32_t pattern_back,source_back,dest_back,mix_back;
  40.436 -        int pattern_x,source_x;
  40.437 -        int pattern_x_back,source_x_back;
  40.438 -        int pattern_y,source_y;
  40.439 -        uint8_t status;
  40.440 -        uint64_t cpu_dat;
  40.441 -        int cpu_dat_pos;
  40.442 -        int pix_pos;
  40.443 -} acl;
  40.444 -
  40.445  #define ACL_WRST 1
  40.446  #define ACL_RDST 2
  40.447  #define ACL_XYST 4
  40.448  #define ACL_SSO  8
  40.449  
  40.450 -struct
  40.451 +void et4000w32_blit_start(et4000w32p_t *et4000);
  40.452 +void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000);
  40.453 +
  40.454 +void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
  40.455  {
  40.456 -        uint32_t base[3];
  40.457 -        uint8_t ctrl;
  40.458 -} mmu;
  40.459 -
  40.460 -void et4000w32_reset()
  40.461 -{
  40.462 -        acl.status=0;
  40.463 -}
  40.464 -
  40.465 -void et4000w32_blit_start();
  40.466 -void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input);
  40.467 -
  40.468 -void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv)
  40.469 -{
  40.470 +        et4000w32p_t *et4000 = (et4000w32p_t *)p;
  40.471 +        svga_t *svga = &et4000->svga;
  40.472          int bank;
  40.473 -//        pclog("ET4K write %08X %02X %02X %04X(%08X):%08X\n",addr,val,acl.status,acl.internal.ctrl_routing,CS,cs,pc);
  40.474 -        switch (addr&0x6000)
  40.475 +//        pclog("ET4K write %08X %02X %02X %04X(%08X):%08X\n",addr,val,et4000->acl.status,et4000->acl.internal.ctrl_routing,CS,cs,pc);
  40.476 +        switch (addr & 0x6000)
  40.477          {
  40.478                  case 0x0000: /*MMU 0*/
  40.479                  case 0x2000: /*MMU 1*/
  40.480                  case 0x4000: /*MMU 2*/
  40.481 -                bank=(addr>>13)&3;
  40.482 -                if (mmu.ctrl&(1<<bank))
  40.483 +                bank = (addr >> 13) & 3;
  40.484 +                if (et4000->mmu.ctrl & (1 << bank))
  40.485                  {
  40.486 -                        if (!(acl.status&ACL_XYST)) return;
  40.487 -                        if (acl.internal.ctrl_routing&3)
  40.488 +                        if (!(et4000->acl.status & ACL_XYST)) return;
  40.489 +                        if (et4000->acl.internal.ctrl_routing & 3)
  40.490                          {
  40.491 -                                if ((acl.internal.ctrl_routing&3)==2)
  40.492 +                                if ((et4000->acl.internal.ctrl_routing & 3) == 2)
  40.493                                  {
  40.494 -                                        if (acl.mix_addr&7)
  40.495 -                                           et4000w32_blit(8-(acl.mix_addr&7), val>>(acl.mix_addr&7), 0, 1);
  40.496 +                                        if (et4000->acl.mix_addr & 7)
  40.497 +                                           et4000w32_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000);
  40.498                                          else
  40.499 -                                           et4000w32_blit(8, val, 0, 1);
  40.500 +                                           et4000w32_blit(8, val, 0, 1, et4000);
  40.501                                  }
  40.502 -                                else if ((acl.internal.ctrl_routing&3)==1)
  40.503 -                                   et4000w32_blit(1, ~0, val, 2);
  40.504 -//                                else
  40.505 -//                                   pclog("Bad ET4K routing %i\n",acl.internal.ctrl_routing&7);
  40.506 +                                else if ((et4000->acl.internal.ctrl_routing & 3) == 1)
  40.507 +                                   et4000w32_blit(1, ~0, val, 2, et4000);
  40.508                          }
  40.509                  }
  40.510                  else
  40.511                  {
  40.512 -                        vram[(addr&0x1FFF)+mmu.base[bank]]=val;
  40.513 -                        changedvram[((addr&0x1FFF)+mmu.base[bank])>>10]=changeframecount;
  40.514 +                        svga->vram[(addr & 0x1fff) + et4000->mmu.base[bank]] = val;
  40.515 +                        svga->changedvram[((addr & 0x1fff) + et4000->mmu.base[bank]) >> 10] = changeframecount;
  40.516                  }
  40.517                  break;
  40.518                  case 0x6000:
  40.519 -                switch (addr&0x7FFF)
  40.520 +                switch (addr & 0x7fff)
  40.521                  {
  40.522 -                        case 0x7F00: mmu.base[0]=(mmu.base[0]&0xFFFFFF00)|val;       break;
  40.523 -                        case 0x7F01: mmu.base[0]=(mmu.base[0]&0xFFFF00FF)|(val<<8);  break;
  40.524 -                        case 0x7F02: mmu.base[0]=(mmu.base[0]&0xFF00FFFF)|(val<<16); break;
  40.525 -                        case 0x7F03: mmu.base[0]=(mmu.base[0]&0x00FFFFFF)|(val<<24); break;
  40.526 -                        case 0x7F04: mmu.base[1]=(mmu.base[1]&0xFFFFFF00)|val;       break;
  40.527 -                        case 0x7F05: mmu.base[1]=(mmu.base[1]&0xFFFF00FF)|(val<<8);  break;
  40.528 -                        case 0x7F06: mmu.base[1]=(mmu.base[1]&0xFF00FFFF)|(val<<16); break;
  40.529 -                        case 0x7F07: mmu.base[1]=(mmu.base[1]&0x00FFFFFF)|(val<<24); break;
  40.530 -                        case 0x7F08: mmu.base[2]=(mmu.base[2]&0xFFFFFF00)|val;       break;
  40.531 -                        case 0x7F09: mmu.base[2]=(mmu.base[2]&0xFFFF00FF)|(val<<8);  break;
  40.532 -                        case 0x7F0A: mmu.base[2]=(mmu.base[2]&0xFF00FFFF)|(val<<16); break;
  40.533 -                        case 0x7F0B: mmu.base[2]=(mmu.base[2]&0x00FFFFFF)|(val<<24); break;
  40.534 -                        case 0x7F13: mmu.ctrl=val; break;
  40.535 +                        case 0x7f00: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFFFF00) | val;         break;
  40.536 +                        case 0x7f01: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFF00FF) | (val << 8);  break;
  40.537 +                        case 0x7f02: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFF00FFFF) | (val << 16); break;
  40.538 +                        case 0x7f03: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00FFFFFF) | (val << 24); break;
  40.539 +                        case 0x7f04: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFFFF00) | val;         break;
  40.540 +                        case 0x7f05: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFF00FF) | (val << 8);  break;
  40.541 +                        case 0x7f06: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFF00FFFF) | (val << 16); break;
  40.542 +                        case 0x7f07: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00FFFFFF) | (val << 24); break;
  40.543 +                        case 0x7f08: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFFFF00) | val;         break;
  40.544 +                        case 0x7f09: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFF00FF) | (val << 8);  break;
  40.545 +                        case 0x7f0a: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFF00FFFF) | (val << 16); break;
  40.546 +                        case 0x7f0d: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00FFFFFF) | (val << 24); break;
  40.547 +                        case 0x7f13: et4000->mmu.ctrl=val; break;
  40.548  
  40.549 -                        case 0x7F80: acl.queued.pattern_addr=(acl.queued.pattern_addr&0xFFFFFF00)|val;       break;
  40.550 -                        case 0x7F81: acl.queued.pattern_addr=(acl.queued.pattern_addr&0xFFFF00FF)|(val<<8);  break;
  40.551 -                        case 0x7F82: acl.queued.pattern_addr=(acl.queued.pattern_addr&0xFF00FFFF)|(val<<16); break;
  40.552 -                        case 0x7F83: acl.queued.pattern_addr=(acl.queued.pattern_addr&0x00FFFFFF)|(val<<24); break;
  40.553 -                        case 0x7F84: acl.queued.source_addr =(acl.queued.source_addr &0xFFFFFF00)|val;       break;
  40.554 -                        case 0x7F85: acl.queued.source_addr =(acl.queued.source_addr &0xFFFF00FF)|(val<<8);  break;
  40.555 -                        case 0x7F86: acl.queued.source_addr =(acl.queued.source_addr &0xFF00FFFF)|(val<<16); break;
  40.556 -                        case 0x7F87: acl.queued.source_addr =(acl.queued.source_addr &0x00FFFFFF)|(val<<24); break;
  40.557 -                        case 0x7F88: acl.queued.pattern_off=(acl.queued.pattern_off&0xFF00)|val;      break;
  40.558 -                        case 0x7F89: acl.queued.pattern_off=(acl.queued.pattern_off&0x00FF)|(val<<8); break;
  40.559 -                        case 0x7F8A: acl.queued.source_off =(acl.queued.source_off &0xFF00)|val;      break;
  40.560 -                        case 0x7F8B: acl.queued.source_off =(acl.queued.source_off &0x00FF)|(val<<8); break;
  40.561 -                        case 0x7F8C: acl.queued.dest_off   =(acl.queued.dest_off   &0xFF00)|val;      break;
  40.562 -                        case 0x7F8D: acl.queued.dest_off   =(acl.queued.dest_off   &0x00FF)|(val<<8); break;
  40.563 -                        case 0x7F8E: acl.queued.pixel_depth=val; break;
  40.564 -                        case 0x7F8F: acl.queued.xy_dir=val; break;
  40.565 -                        case 0x7F90: acl.queued.pattern_wrap=val; break;
  40.566 -                        case 0x7F92: acl.queued.source_wrap=val; break;
  40.567 -                        case 0x7F98: acl.queued.count_x    =(acl.queued.count_x    &0xFF00)|val;      break;
  40.568 -                        case 0x7F99: acl.queued.count_x    =(acl.queued.count_x    &0x00FF)|(val<<8); break;
  40.569 -                        case 0x7F9A: acl.queued.count_y    =(acl.queued.count_y    &0xFF00)|val;      break;
  40.570 -                        case 0x7F9B: acl.queued.count_y    =(acl.queued.count_y    &0x00FF)|(val<<8); break;
  40.571 -                        case 0x7F9C: acl.queued.ctrl_routing=val; break;
  40.572 -                        case 0x7F9D: acl.queued.ctrl_reload =val; break;
  40.573 -                        case 0x7F9E: acl.queued.rop_bg      =val; break;
  40.574 -                        case 0x7F9F: acl.queued.rop_fg      =val; break;
  40.575 -                        case 0x7FA0: acl.queued.dest_addr   =(acl.queued.dest_addr   &0xFFFFFF00)|val;       break;
  40.576 -                        case 0x7FA1: acl.queued.dest_addr   =(acl.queued.dest_addr   &0xFFFF00FF)|(val<<8);  break;
  40.577 -                        case 0x7FA2: acl.queued.dest_addr   =(acl.queued.dest_addr   &0xFF00FFFF)|(val<<16); break;
  40.578 -                        case 0x7FA3: acl.queued.dest_addr   =(acl.queued.dest_addr   &0x00FFFFFF)|(val<<24);
  40.579 -                        acl.internal=acl.queued;
  40.580 -                        et4000w32_blit_start();
  40.581 -                        if (!(acl.queued.ctrl_routing&0x43))
  40.582 +                        case 0x7f80: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFFFF00) | val;         break;
  40.583 +                        case 0x7f81: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFF00FF) | (val << 8);  break;
  40.584 +                        case 0x7f82: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFF00FFFF) | (val << 16); break;
  40.585 +                        case 0x7f83: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00FFFFFF) | (val << 24); break;
  40.586 +                        case 0x7f84: et4000->acl.queued.source_addr  = (et4000->acl.queued.source_addr  & 0xFFFFFF00) | val;         break;
  40.587 +                        case 0x7f85: et4000->acl.queued.source_addr  = (et4000->acl.queued.source_addr  & 0xFFFF00FF) | (val << 8);  break;
  40.588 +                        case 0x7f86: et4000->acl.queued.source_addr  = (et4000->acl.queued.source_addr  & 0xFF00FFFF) | (val << 16); break;
  40.589 +                        case 0x7f87: et4000->acl.queued.source_addr  = (et4000->acl.queued.source_addr  & 0x00FFFFFF) | (val << 24); break;
  40.590 +                        case 0x7f88: et4000->acl.queued.pattern_off  = (et4000->acl.queued.pattern_off  & 0xFF00) | val;        break;
  40.591 +                        case 0x7f89: et4000->acl.queued.pattern_off  = (et4000->acl.queued.pattern_off  & 0x00FF) | (val << 8); break;
  40.592 +                        case 0x7f8a: et4000->acl.queued.source_off   = (et4000->acl.queued.source_off   & 0xFF00) | val;        break;
  40.593 +                        case 0x7f8b: et4000->acl.queued.source_off   = (et4000->acl.queued.source_off   & 0x00FF) | (val << 8); break;
  40.594 +                        case 0x7f8c: et4000->acl.queued.dest_off     = (et4000->acl.queued.dest_off     & 0xFF00) | val;        break;
  40.595 +                        case 0x7f8d: et4000->acl.queued.dest_off     = (et4000->acl.queued.dest_off     & 0x00FF) | (val << 8); break;
  40.596 +                        case 0x7f8e: et4000->acl.queued.pixel_depth = val; break;
  40.597 +                        case 0x7f8f: et4000->acl.queued.xy_dir = val; break;
  40.598 +                        case 0x7f90: et4000->acl.queued.pattern_wrap = val; break;
  40.599 +                        case 0x7f92: et4000->acl.queued.source_wrap = val; break;
  40.600 +                        case 0x7f98: et4000->acl.queued.count_x    = (et4000->acl.queued.count_x & 0xFF00) | val;        break;
  40.601 +                        case 0x7f99: et4000->acl.queued.count_x    = (et4000->acl.queued.count_x & 0x00FF) | (val << 8); break;
  40.602 +                        case 0x7f9a: et4000->acl.queued.count_y    = (et4000->acl.queued.count_y & 0xFF00) | val;        break;
  40.603 +                        case 0x7f9b: et4000->acl.queued.count_y    = (et4000->acl.queued.count_y & 0x00FF) | (val << 8); break;
  40.604 +                        case 0x7f9c: et4000->acl.queued.ctrl_routing = val; break;
  40.605 +                        case 0x7f9d: et4000->acl.queued.ctrl_reload  = val; break;
  40.606 +                        case 0x7f9e: et4000->acl.queued.rop_bg       = val; break;
  40.607 +                        case 0x7f9f: et4000->acl.queued.rop_fg       = val; break;
  40.608 +                        case 0x7fa0: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFFFF00) | val;         break;
  40.609 +                        case 0x7fa1: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFF00FF) | (val << 8);  break;
  40.610 +                        case 0x7fa2: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFF00FFFF) | (val << 16); break;
  40.611 +                        case 0x7fa3: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00FFFFFF) | (val << 24);
  40.612 +                        et4000->acl.internal = et4000->acl.queued;
  40.613 +                        et4000w32_blit_start(et4000);
  40.614 +                        if (!(et4000->acl.queued.ctrl_routing & 0x43))
  40.615                          {
  40.616 -                                et4000w32_blit(0xFFFFFF, ~0, 0, 0);
  40.617 +                                et4000w32_blit(0xFFFFFF, ~0, 0, 0, et4000);
  40.618                          }
  40.619 -                        if ((acl.queued.ctrl_routing&0x40) && !(acl.internal.ctrl_routing&3))
  40.620 -                           et4000w32_blit(4, ~0, 0, 0);
  40.621 +                        if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3))
  40.622 +                           et4000w32_blit(4, ~0, 0, 0, et4000);
  40.623                          break;
  40.624 -                        case 0x7FA4: acl.queued.mix_addr=(acl.queued.mix_addr&0xFFFFFF00)|val;       break;
  40.625 -                        case 0x7FA5: acl.queued.mix_addr=(acl.queued.mix_addr&0xFFFF00FF)|(val<<8);  break;
  40.626 -                        case 0x7FA6: acl.queued.mix_addr=(acl.queued.mix_addr&0xFF00FFFF)|(val<<16); break;
  40.627 -                        case 0x7FA7: acl.queued.mix_addr=(acl.queued.mix_addr&0x00FFFFFF)|(val<<24); break;
  40.628 -                        case 0x7FA8: acl.queued.mix_off    =(acl.queued.mix_off    &0xFF00)|val;      break;
  40.629 -                        case 0x7FA9: acl.queued.mix_off    =(acl.queued.mix_off    &0x00FF)|(val<<8); break;
  40.630 -                        case 0x7FAA: acl.queued.error      =(acl.queued.error      &0xFF00)|val;      break;
  40.631 -                        case 0x7FAB: acl.queued.error      =(acl.queued.error      &0x00FF)|(val<<8); break;
  40.632 -                        case 0x7FAC: acl.queued.dmin       =(acl.queued.dmin       &0xFF00)|val;      break;
  40.633 -                        case 0x7FAD: acl.queued.dmin       =(acl.queued.dmin       &0x00FF)|(val<<8); break;
  40.634 -                        case 0x7FAE: acl.queued.dmaj       =(acl.queued.dmaj       &0xFF00)|val;      break;
  40.635 -                        case 0x7FAF: acl.queued.dmaj       =(acl.queued.dmaj       &0x00FF)|(val<<8); break;
  40.636 +                        case 0x7fa4: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val;         break;
  40.637 +                        case 0x7fa5: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8);  break;
  40.638 +                        case 0x7fa6: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); break;
  40.639 +                        case 0x7fa7: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); break;
  40.640 +                        case 0x7fa8: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val;        break;
  40.641 +                        case 0x7fa9: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); break;
  40.642 +                        case 0x7faa: et4000->acl.queued.error   = (et4000->acl.queued.error   & 0xFF00) | val;        break;
  40.643 +                        case 0x7fab: et4000->acl.queued.error   = (et4000->acl.queued.error   & 0x00FF) | (val << 8); break;
  40.644 +                        case 0x7fac: et4000->acl.queued.dmin    = (et4000->acl.queued.dmin    & 0xFF00) | val;        break;
  40.645 +                        case 0x7fad: et4000->acl.queued.dmin    = (et4000->acl.queued.dmin    & 0x00FF) | (val << 8); break;
  40.646 +                        case 0x7fae: et4000->acl.queued.dmaj    = (et4000->acl.queued.dmaj    & 0xFF00) | val;        break;
  40.647 +                        case 0x7faf: et4000->acl.queued.dmaj    = (et4000->acl.queued.dmaj    & 0x00FF) | (val << 8); break;
  40.648                  }
  40.649                  break;
  40.650          }
  40.651  }
  40.652  
  40.653 -uint8_t et4000w32p_mmu_read(uint32_t addr, void *priv)
  40.654 +uint8_t et4000w32p_mmu_read(uint32_t addr, void *p)
  40.655  {
  40.656 +        et4000w32p_t *et4000 = (et4000w32p_t *)p;
  40.657 +        svga_t *svga = &et4000->svga;
  40.658          int bank;
  40.659          uint8_t temp;
  40.660  //        pclog("ET4K read %08X %04X(%08X):%08X\n",addr,CS,cs,pc);
  40.661 -        switch (addr&0x6000)
  40.662 +        switch (addr & 0x6000)
  40.663          {
  40.664                  case 0x0000: /*MMU 0*/
  40.665                  case 0x2000: /*MMU 1*/
  40.666                  case 0x4000: /*MMU 2*/
  40.667 -                bank=(addr>>13)&3;
  40.668 -                if (mmu.ctrl&(1<<bank))
  40.669 +                bank = (addr >> 13) & 3;
  40.670 +                if (et4000->mmu.ctrl & (1 << bank))
  40.671                  {
  40.672 -                        temp=0xFF;
  40.673 -                        if (acl.cpu_dat_pos)
  40.674 +                        temp = 0xff;
  40.675 +                        if (et4000->acl.cpu_dat_pos)
  40.676                          {
  40.677 -                                acl.cpu_dat_pos--;
  40.678 -                                temp=acl.cpu_dat&0xFF;
  40.679 -                                acl.cpu_dat>>=8;
  40.680 +                                et4000->acl.cpu_dat_pos--;
  40.681 +                                temp = et4000->acl.cpu_dat & 0xff;
  40.682 +                                et4000->acl.cpu_dat >>= 8;
  40.683                          }
  40.684 -                        if ((acl.queued.ctrl_routing&0x40) && !acl.cpu_dat_pos && !(acl.internal.ctrl_routing&3))
  40.685 -                           et4000w32_blit(4, ~0, 0, 0);
  40.686 +                        if ((et4000->acl.queued.ctrl_routing & 0x40) && !et4000->acl.cpu_dat_pos && !(et4000->acl.internal.ctrl_routing & 3))
  40.687 +                           et4000w32_blit(4, ~0, 0, 0, et4000);
  40.688                          /*???*/
  40.689                          return temp;
  40.690                  }
  40.691 -                return vram[(addr&0x1FFF)+mmu.base[bank]];
  40.692 +                return svga->vram[(addr&0x1fff) + et4000->mmu.base[bank]];
  40.693 +                
  40.694                  case 0x6000:
  40.695 -                switch (addr&0x7FFF)
  40.696 +                switch (addr&0x7fff)
  40.697                  {
  40.698 -                        case 0x7F00: return mmu.base[0];
  40.699 -                        case 0x7F01: return mmu.base[0]>>8;
  40.700 -                        case 0x7F02: return mmu.base[0]>>16;
  40.701 -                        case 0x7F03: return mmu.base[0]>>24;
  40.702 -                        case 0x7F04: return mmu.base[1];
  40.703 -                        case 0x7F05: return mmu.base[1]>>8;
  40.704 -                        case 0x7F06: return mmu.base[1]>>16;
  40.705 -                        case 0x7F07: return mmu.base[1]>>24;
  40.706 -                        case 0x7F08: return mmu.base[2];
  40.707 -                        case 0x7F09: return mmu.base[2]>>8;
  40.708 -                        case 0x7F0A: return mmu.base[2]>>16;
  40.709 -                        case 0x7F0B: return mmu.base[2]>>24;
  40.710 -                        case 0x7F13: return mmu.ctrl;
  40.711 +                        case 0x7f00: return et4000->mmu.base[0];
  40.712 +                        case 0x7f01: return et4000->mmu.base[0] >> 8;
  40.713 +                        case 0x7f02: return et4000->mmu.base[0] >> 16;
  40.714 +                        case 0x7f03: return et4000->mmu.base[0] >> 24;
  40.715 +                        case 0x7f04: return et4000->mmu.base[1];
  40.716 +                        case 0x7f05: return et4000->mmu.base[1] >> 8;
  40.717 +                        case 0x7f06: return et4000->mmu.base[1] >> 16;
  40.718 +                        case 0x7f07: return et4000->mmu.base[1] >> 24;
  40.719 +                        case 0x7f08: return et4000->mmu.base[2];
  40.720 +                        case 0x7f09: return et4000->mmu.base[2] >> 8;
  40.721 +                        case 0x7f0a: return et4000->mmu.base[2] >> 16;
  40.722 +                        case 0x7f0b: return et4000->mmu.base[2] >> 24;
  40.723 +                        case 0x7f13: return et4000->mmu.ctrl;
  40.724  
  40.725 -                        case 0x7F36:
  40.726 -//                                pclog("Read ACL status %02X\n",acl.status);
  40.727 -//                        if (acl.internal.pos_x!=acl.internal.count_x || acl.internal.pos_y!=acl.internal.count_y) return acl.status | ACL_XYST;
  40.728 -                        return acl.status;
  40.729 -                        case 0x7F80: return acl.internal.pattern_addr;
  40.730 -                        case 0x7F81: return acl.internal.pattern_addr>>8;
  40.731 -                        case 0x7F82: return acl.internal.pattern_addr>>16;
  40.732 -                        case 0x7F83: return acl.internal.pattern_addr>>24;
  40.733 -                        case 0x7F84: return acl.internal.source_addr;
  40.734 -                        case 0x7F85: return acl.internal.source_addr>>8;
  40.735 -                        case 0x7F86: return acl.internal.source_addr>>16;
  40.736 -                        case 0x7F87: return acl.internal.source_addr>>24;
  40.737 -                        case 0x7F88: return acl.internal.pattern_off;
  40.738 -                        case 0x7F89: return acl.internal.pattern_off>>8;
  40.739 -                        case 0x7F8A: return acl.internal.source_off;
  40.740 -                        case 0x7F8B: return acl.internal.source_off>>8;
  40.741 -                        case 0x7F8C: return acl.internal.dest_off;
  40.742 -                        case 0x7F8D: return acl.internal.dest_off>>8;
  40.743 -                        case 0x7F8E: return acl.internal.pixel_depth;
  40.744 -                        case 0x7F8F: return acl.internal.xy_dir;
  40.745 -                        case 0x7F90: return acl.internal.pattern_wrap;
  40.746 -                        case 0x7F92: return acl.internal.source_wrap;
  40.747 -                        case 0x7F98: return acl.internal.count_x;
  40.748 -                        case 0x7F99: return acl.internal.count_x>>8;
  40.749 -                        case 0x7F9A: return acl.internal.count_y;
  40.750 -                        case 0x7F9B: return acl.internal.count_y>>8;
  40.751 -                        case 0x7F9C: return acl.internal.ctrl_routing;
  40.752 -                        case 0x7F9D: return acl.internal.ctrl_reload;
  40.753 -                        case 0x7F9E: return acl.internal.rop_bg;
  40.754 -                        case 0x7F9F: return acl.internal.rop_fg;
  40.755 -                        case 0x7FA0: return acl.internal.dest_addr;
  40.756 -                        case 0x7FA1: return acl.internal.dest_addr>>8;
  40.757 -                        case 0x7FA2: return acl.internal.dest_addr>>16;
  40.758 -                        case 0x7FA3: return acl.internal.dest_addr>>24;
  40.759 +                        case 0x7f36:
  40.760 +//                                pclog("Read ACL status %02X\n",et4000->acl.status);
  40.761 +//                        if (et4000->acl.internal.pos_x!=et4000->acl.internal.count_x || et4000->acl.internal.pos_y!=et4000->acl.internal.count_y) return et4000->acl.status | ACL_XYST;
  40.762 +                        return et4000->acl.status;
  40.763 +                        case 0x7f80: return et4000->acl.internal.pattern_addr;
  40.764 +                        case 0x7f81: return et4000->acl.internal.pattern_addr >> 8;
  40.765 +                        case 0x7f82: return et4000->acl.internal.pattern_addr >> 16;
  40.766 +                        case 0x7f83: return et4000->acl.internal.pattern_addr >> 24;
  40.767 +                        case 0x7f84: return et4000->acl.internal.source_addr;
  40.768 +                        case 0x7f85: return et4000->acl.internal.source_addr >> 8;
  40.769 +                        case 0x7f86: return et4000->acl.internal.source_addr >> 16;
  40.770 +                        case 0x7f87: return et4000->acl.internal.source_addr >> 24;
  40.771 +                        case 0x7f88: return et4000->acl.internal.pattern_off;
  40.772 +                        case 0x7f89: return et4000->acl.internal.pattern_off >> 8;
  40.773 +                        case 0x7f8a: return et4000->acl.internal.source_off;
  40.774 +                        case 0x7f8b: return et4000->acl.internal.source_off >> 8;
  40.775 +                        case 0x7f8c: return et4000->acl.internal.dest_off;
  40.776 +                        case 0x7f8d: return et4000->acl.internal.dest_off >> 8;
  40.777 +                        case 0x7f8e: return et4000->acl.internal.pixel_depth;
  40.778 +                        case 0x7f8f: return et4000->acl.internal.xy_dir;
  40.779 +                        case 0x7f90: return et4000->acl.internal.pattern_wrap;
  40.780 +                        case 0x7f92: return et4000->acl.internal.source_wrap;
  40.781 +                        case 0x7f98: return et4000->acl.internal.count_x;
  40.782 +                        case 0x7f99: return et4000->acl.internal.count_x >> 8;
  40.783 +                        case 0x7f9a: return et4000->acl.internal.count_y;
  40.784 +                        case 0x7f9b: return et4000->acl.internal.count_y >> 8;
  40.785 +                        case 0x7f9c: return et4000->acl.internal.ctrl_routing;
  40.786 +                        case 0x7f9d: return et4000->acl.internal.ctrl_reload;
  40.787 +                        case 0x7f9e: return et4000->acl.internal.rop_bg;
  40.788 +                        case 0x7f9f: return et4000->acl.internal.rop_fg;
  40.789 +                        case 0x7fa0: return et4000->acl.internal.dest_addr;
  40.790 +                        case 0x7fa1: return et4000->acl.internal.dest_addr >> 8;
  40.791 +                        case 0x7fa2: return et4000->acl.internal.dest_addr >> 16;
  40.792 +                        case 0x7fa3: return et4000->acl.internal.dest_addr >> 24;
  40.793                  }
  40.794 -                return 0xFF;
  40.795 +                return 0xff;
  40.796          }
  40.797          return 0xff;
  40.798  }
  40.799  
  40.800 -int et4000w32_max_x[8]={0,0,4,8,16,32,64,0x70000000};
  40.801 -int et4000w32_wrap_x[8]={0,0,3,7,15,31,63,0xFFFFFFFF};
  40.802 -int et4000w32_wrap_y[8]={1,2,4,8,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
  40.803 +static int et4000w32_max_x[8]={0,0,4,8,16,32,64,0x70000000};
  40.804 +static int et4000w32_wrap_x[8]={0,0,3,7,15,31,63,0xFFFFFFFF};
  40.805 +static int et4000w32_wrap_y[8]={1,2,4,8,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
  40.806  
  40.807  int bltout=0;
  40.808 -void et4000w32_blit_start()
  40.809 +void et4000w32_blit_start(et4000w32p_t *et4000)
  40.810  {
  40.811 -//        if (acl.queued.xy_dir&0x80)
  40.812 -//           pclog("Blit - %02X %08X (%i,%i) %08X (%i,%i) %08X (%i,%i) %i  %i %i  %02X %02X  %02X\n",acl.queued.xy_dir,acl.internal.pattern_addr,(acl.internal.pattern_addr/3)%640,(acl.internal.pattern_addr/3)/640,acl.internal.source_addr,(acl.internal.source_addr/3)%640,(acl.internal.source_addr/3)/640,acl.internal.dest_addr,(acl.internal.dest_addr/3)%640,(acl.internal.dest_addr/3)/640,acl.internal.xy_dir,acl.internal.count_x,acl.internal.count_y,acl.internal.rop_fg,acl.internal.rop_bg, acl.internal.ctrl_routing);
  40.813 +//        if (et4000->acl.queued.xy_dir&0x80)
  40.814 +//           pclog("Blit - %02X %08X (%i,%i) %08X (%i,%i) %08X (%i,%i) %i  %i %i  %02X %02X  %02X\n",et4000->acl.queued.xy_dir,et4000->acl.internal.pattern_addr,(et4000->acl.internal.pattern_addr/3)%640,(et4000->acl.internal.pattern_addr/3)/640,et4000->acl.internal.source_addr,(et4000->acl.internal.source_addr/3)%640,(et4000->acl.internal.source_addr/3)/640,et4000->acl.internal.dest_addr,(et4000->acl.internal.dest_addr/3)%640,(et4000->acl.internal.dest_addr/3)/640,et4000->acl.internal.xy_dir,et4000->acl.internal.count_x,et4000->acl.internal.count_y,et4000->acl.internal.rop_fg,et4000->acl.internal.rop_bg, et4000->acl.internal.ctrl_routing);
  40.815  //           bltout=1;
  40.816 -//        bltout=(acl.internal.count_x==1541);
  40.817 -        if (!(acl.queued.xy_dir&0x20))
  40.818 -           acl.internal.error = acl.internal.dmaj/2;
  40.819 -        acl.pattern_addr=acl.internal.pattern_addr;
  40.820 -        acl.source_addr =acl.internal.source_addr;
  40.821 -        acl.mix_addr    =acl.internal.mix_addr;
  40.822 -        acl.mix_back    =acl.mix_addr;
  40.823 -        acl.dest_addr   =acl.internal.dest_addr;
  40.824 -        acl.dest_back   =acl.dest_addr;
  40.825 -        acl.internal.pos_x=acl.internal.pos_y=0;
  40.826 -        acl.pattern_x=acl.source_x=acl.pattern_y=acl.source_y=0;
  40.827 -        acl.status = ACL_XYST;
  40.828 -        if ((!(acl.internal.ctrl_routing&7) || (acl.internal.ctrl_routing&4)) && !(acl.internal.ctrl_routing&0x40)) acl.status |= ACL_SSO;
  40.829 +//        bltout=(et4000->acl.internal.count_x==1541);
  40.830 +        if (!(et4000->acl.queued.xy_dir & 0x20))
  40.831 +           et4000->acl.internal.error = et4000->acl.internal.dmaj / 2;
  40.832 +        et4000->acl.pattern_addr= et4000->acl.internal.pattern_addr;
  40.833 +        et4000->acl.source_addr = et4000->acl.internal.source_addr;
  40.834 +        et4000->acl.mix_addr    = et4000->acl.internal.mix_addr;
  40.835 +        et4000->acl.mix_back    = et4000->acl.mix_addr;
  40.836 +        et4000->acl.dest_addr   = et4000->acl.internal.dest_addr;
  40.837 +        et4000->acl.dest_back   = et4000->acl.dest_addr;
  40.838 +        et4000->acl.internal.pos_x = et4000->acl.internal.pos_y = 0;
  40.839 +        et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0;
  40.840 +        et4000->acl.status = ACL_XYST;
  40.841 +        if ((!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) && !(et4000->acl.internal.ctrl_routing & 0x40)) 
  40.842 +                et4000->acl.status |= ACL_SSO;
  40.843          
  40.844 -        if (et4000w32_wrap_x[acl.internal.pattern_wrap&7])
  40.845 +        if (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7])
  40.846          {
  40.847 -                acl.pattern_x=acl.pattern_addr&et4000w32_wrap_x[acl.internal.pattern_wrap&7];
  40.848 -                acl.pattern_addr&=~et4000w32_wrap_x[acl.internal.pattern_wrap&7];
  40.849 +                et4000->acl.pattern_x = et4000->acl.pattern_addr & et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7];
  40.850 +                et4000->acl.pattern_addr &= ~et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7];
  40.851          }
  40.852 -        acl.pattern_back=acl.pattern_addr;
  40.853 -        if (!(acl.internal.pattern_wrap&0x40))
  40.854 +        et4000->acl.pattern_back = et4000->acl.pattern_addr;
  40.855 +        if (!(et4000->acl.internal.pattern_wrap & 0x40))
  40.856          {
  40.857 -                acl.pattern_y=(acl.pattern_addr/(et4000w32_wrap_x[acl.internal.pattern_wrap&7]+1))&(et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7]-1);
  40.858 -                acl.pattern_back&=~(((et4000w32_wrap_x[acl.internal.pattern_wrap&7]+1)*et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7])-1);
  40.859 +                et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1);
  40.860 +                et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1);
  40.861          }
  40.862 -        acl.pattern_x_back=acl.pattern_x;
  40.863 +        et4000->acl.pattern_x_back = et4000->acl.pattern_x;
  40.864          
  40.865 -        if (et4000w32_wrap_x[acl.internal.source_wrap&7])
  40.866 +        if (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7])
  40.867          {
  40.868 -                acl.source_x=acl.source_addr&et4000w32_wrap_x[acl.internal.source_wrap&7];
  40.869 -                acl.source_addr&=~et4000w32_wrap_x[acl.internal.source_wrap&7];
  40.870 +                et4000->acl.source_x = et4000->acl.source_addr & et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7];
  40.871 +                et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7];
  40.872          }
  40.873 -        acl.source_back=acl.source_addr;
  40.874 -        if (!(acl.internal.source_wrap&0x40))
  40.875 +        et4000->acl.source_back = et4000->acl.source_addr;
  40.876 +        if (!(et4000->acl.internal.source_wrap & 0x40))
  40.877          {
  40.878 -                acl.source_y=(acl.source_addr/(et4000w32_wrap_x[acl.internal.source_wrap&7]+1))&(et4000w32_wrap_y[(acl.internal.source_wrap>>4)&7]-1);
  40.879 -                acl.source_back&=~(((et4000w32_wrap_x[acl.internal.source_wrap&7]+1)*et4000w32_wrap_y[(acl.internal.source_wrap>>4)&7])-1);
  40.880 +                et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1);
  40.881 +                et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1);
  40.882          }
  40.883 -        acl.source_x_back=acl.source_x;
  40.884 +        et4000->acl.source_x_back = et4000->acl.source_x;
  40.885  
  40.886 -        et4000w32_max_x[2]=((acl.internal.pixel_depth&0x30)==0x20)?3:4;
  40.887 +        et4000w32_max_x[2] = ((et4000->acl.internal.pixel_depth & 0x30) == 0x20) ? 3 : 4;
  40.888          
  40.889 -        acl.internal.count_x += (acl.internal.pixel_depth>>4)&3;
  40.890 -        acl.cpu_dat_pos=0;
  40.891 -        acl.cpu_dat=0;
  40.892 +        et4000->acl.internal.count_x += (et4000->acl.internal.pixel_depth >> 4) & 3;
  40.893 +        et4000->acl.cpu_dat_pos = 0;
  40.894 +        et4000->acl.cpu_dat = 0;
  40.895          
  40.896 -        acl.pix_pos=0;
  40.897 +        et4000->acl.pix_pos = 0;
  40.898  }
  40.899  
  40.900 -void et4000w32_incx(int c)
  40.901 +void et4000w32_incx(int c, et4000w32p_t *et4000)
  40.902  {
  40.903 -        acl.dest_addr+=c;
  40.904 -        acl.pattern_x+=c;
  40.905 -        acl.source_x +=c;
  40.906 -        acl.mix_addr +=c;
  40.907 -        if (acl.pattern_x>=et4000w32_max_x[acl.internal.pattern_wrap&7])
  40.908 -           acl.pattern_x -=et4000w32_max_x[acl.internal.pattern_wrap&7];
  40.909 -        if (acl.source_x >=et4000w32_max_x[acl.internal.source_wrap &7])
  40.910 -           acl.source_x  -=et4000w32_max_x[acl.internal.source_wrap &7];
  40.911 +        et4000->acl.dest_addr += c;
  40.912 +        et4000->acl.pattern_x += c;
  40.913 +        et4000->acl.source_x  += c;
  40.914 +        et4000->acl.mix_addr  += c;
  40.915 +        if (et4000->acl.pattern_x >= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7])
  40.916 +           et4000->acl.pattern_x  -= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7];
  40.917 +        if (et4000->acl.source_x  >= et4000w32_max_x[et4000->acl.internal.source_wrap  & 7])
  40.918 +           et4000->acl.source_x   -= et4000w32_max_x[et4000->acl.internal.source_wrap  & 7];
  40.919  }
  40.920 -void et4000w32_decx(int c)
  40.921 +void et4000w32_decx(int c, et4000w32p_t *et4000)
  40.922  {
  40.923 -        acl.dest_addr-=c;
  40.924 -        acl.pattern_x-=c;
  40.925 -        acl.source_x -=c;
  40.926 -        acl.mix_addr -=c;
  40.927 -        if (acl.pattern_x<0)
  40.928 -           acl.pattern_x +=et4000w32_max_x[acl.internal.pattern_wrap&7];
  40.929 -        if (acl.source_x <0)
  40.930 -           acl.source_x  +=et4000w32_max_x[acl.internal.source_wrap &7];
  40.931 +        et4000->acl.dest_addr -= c;
  40.932 +        et4000->acl.pattern_x -= c;
  40.933 +        et4000->acl.source_x  -= c;
  40.934 +        et4000->acl.mix_addr  -= c;
  40.935 +        if (et4000->acl.pattern_x < 0)
  40.936 +           et4000->acl.pattern_x  += et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7];
  40.937 +        if (et4000->acl.source_x  < 0)
  40.938 +           et4000->acl.source_x   += et4000w32_max_x[et4000->acl.internal.source_wrap  & 7];
  40.939  }
  40.940 -void et4000w32_incy()
  40.941 +void et4000w32_incy(et4000w32p_t *et4000)
  40.942  {
  40.943 -        acl.pattern_addr+=acl.internal.pattern_off+1;
  40.944 -        acl.source_addr +=acl.internal.source_off +1;
  40.945 -        acl.mix_addr    +=acl.internal.mix_off    +1;
  40.946 -        acl.dest_addr   +=acl.internal.dest_off   +1;
  40.947 -        acl.pattern_y++;
  40.948 -        if (acl.pattern_y == et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7])
  40.949 +        et4000->acl.pattern_addr += et4000->acl.internal.pattern_off + 1;
  40.950 +        et4000->acl.source_addr  += et4000->acl.internal.source_off  + 1;
  40.951 +        et4000->acl.mix_addr     += et4000->acl.internal.mix_off     + 1;
  40.952 +        et4000->acl.dest_addr    += et4000->acl.internal.dest_off    + 1;
  40.953 +        et4000->acl.pattern_y++;
  40.954 +        if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7])
  40.955          {
  40.956 -                acl.pattern_y = 0;
  40.957 -                acl.pattern_addr = acl.pattern_back;
  40.958 +                et4000->acl.pattern_y = 0;
  40.959 +                et4000->acl.pattern_addr = et4000->acl.pattern_back;
  40.960          }
  40.961 -        acl.source_y++;
  40.962 -        if (acl.source_y == et4000w32_wrap_y[(acl.internal.source_wrap >>4)&7])
  40.963 +        et4000->acl.source_y++;
  40.964 +        if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7])
  40.965          {
  40.966 -                acl.source_y = 0;
  40.967 -                acl.source_addr = acl.source_back;
  40.968 +                et4000->acl.source_y = 0;
  40.969 +                et4000->acl.source_addr = et4000->acl.source_back;
  40.970          }
  40.971  }
  40.972 -void et4000w32_decy()
  40.973 +void et4000w32_decy(et4000w32p_t *et4000)
  40.974  {
  40.975 -        acl.pattern_addr-=acl.internal.pattern_off+1;
  40.976 -        acl.source_addr -=acl.internal.source_off +1;
  40.977 -        acl.mix_addr    -=acl.internal.mix_off    +1;
  40.978 -        acl.dest_addr   -=acl.internal.dest_off   +1;
  40.979 -        acl.pattern_y--;
  40.980 -        if (acl.pattern_y<0 && !(acl.internal.pattern_wrap&0x40))
  40.981 +        et4000->acl.pattern_addr -= et4000->acl.internal.pattern_off + 1;
  40.982 +        et4000->acl.source_addr  -= et4000->acl.internal.source_off  + 1;
  40.983 +        et4000->acl.mix_addr     -= et4000->acl.internal.mix_off     + 1;
  40.984 +        et4000->acl.dest_addr    -= et4000->acl.internal.dest_off    + 1;
  40.985 +        et4000->acl.pattern_y--;
  40.986 +        if (et4000->acl.pattern_y < 0 && !(et4000->acl.internal.pattern_wrap & 0x40))
  40.987          {
  40.988 -                acl.pattern_y=et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7]-1;
  40.989 -                acl.pattern_addr=acl.pattern_back+(et4000w32_wrap_x[acl.internal.pattern_wrap&7]*(et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7]-1));
  40.990 +                et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1;
  40.991 +                et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1));
  40.992          }
  40.993 -        acl.source_y--;
  40.994 -        if (acl.source_y<0 && !(acl.internal.source_wrap&0x40))
  40.995 +        et4000->acl.source_y--;
  40.996 +        if (et4000->acl.source_y < 0 && !(et4000->acl.internal.source_wrap & 0x40))
  40.997          {
  40.998 -                acl.source_y =et4000w32_wrap_y[(acl.internal.source_wrap >>4)&7]-1;
  40.999 -                acl.source_addr =acl.source_back +(et4000w32_wrap_x[acl.internal.source_wrap&7] *(et4000w32_wrap_y[(acl.internal.source_wrap>>4)&7]-1));;
 40.1000 +                et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1;
 40.1001 +                et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] *(et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1));;
 40.1002          }
 40.1003  }
 40.1004  
 40.1005 -void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input)
 40.1006 +void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000)
 40.1007  {
 40.1008 +        svga_t *svga = &et4000->svga;
 40.1009          int c,d;
 40.1010 -        uint8_t pattern,source,dest,out;
 40.1011 +        uint8_t pattern, source, dest, out;
 40.1012          uint8_t rop;
 40.1013          int mixdat;
 40.1014  
 40.1015 -        if (!(acl.status & ACL_XYST)) return;
 40.1016 -//        if (count>400) pclog("New blit - %i,%i %06X (%i,%i) %06X %06X\n",acl.internal.count_x,acl.internal.count_y,acl.dest_addr,acl.dest_addr%640,acl.dest_addr/640,acl.source_addr,acl.pattern_addr);
 40.1017 -        //pclog("Blit exec - %i %i %i\n",count,acl.internal.pos_x,acl.internal.pos_y);
 40.1018 -        if (acl.internal.xy_dir&0x80) /*Line draw*/
 40.1019 +        if (!(et4000->acl.status & ACL_XYST)) return;
 40.1020 +//        if (count>400) pclog("New blit - %i,%i %06X (%i,%i) %06X %06X\n",et4000->acl.internal.count_x,et4000->acl.internal.count_y,et4000->acl.dest_addr,et4000->acl.dest_addr%640,et4000->acl.dest_addr/640,et4000->acl.source_addr,et4000->acl.pattern_addr);
 40.1021 +        //pclog("Blit exec - %i %i %i\n",count,et4000->acl.internal.pos_x,et4000->acl.internal.pos_y);
 40.1022 +        if (et4000->acl.internal.xy_dir & 0x80) /*Line draw*/
 40.1023          {
 40.1024                  while (count--)
 40.1025                  {
 40.1026 -                        if (bltout) pclog("%i,%i : ",acl.internal.pos_x,acl.internal.pos_y);
 40.1027 -                        pattern=vram[(acl.pattern_addr+acl.pattern_x)&0x1FFFFF];
 40.1028 -                        source =vram[(acl.source_addr +acl.source_x) &0x1FFFFF];
 40.1029 -                        if (bltout) pclog("%06X %06X ",(acl.pattern_addr+acl.pattern_x)&0x1FFFFF,(acl.source_addr +acl.source_x) &0x1FFFFF);
 40.1030 -                        if (cpu_input==2)
 40.1031 +                        if (bltout) pclog("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y);
 40.1032 +                        pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff];
 40.1033 +                        source  = svga->vram[(et4000->acl.source_addr  + et4000->acl.source_x)  & 0x1fffff];
 40.1034 +                        if (bltout) pclog("%06X %06X ", (et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff, (et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff);
 40.1035 +                        if (cpu_input == 2)
 40.1036                          {
 40.1037 -                                source=sdat&0xFF;
 40.1038 -                                sdat>>=8;
 40.1039 +                                source = sdat & 0xff;
 40.1040 +                                sdat >>= 8;
 40.1041                          }
 40.1042 -                        dest=vram[acl.dest_addr   &0x1FFFFF];
 40.1043 -                        out=0;
 40.1044 -                        if (bltout) pclog("%06X   ",acl.dest_addr);
 40.1045 -                        if ((acl.internal.ctrl_routing&0xA)==8)
 40.1046 +                        dest = svga->vram[et4000->acl.dest_addr & 0x1fffff];
 40.1047 +                        out = 0;
 40.1048 +                        if (bltout) pclog("%06X   ", et4000->acl.dest_addr);
 40.1049 +                        if ((et4000->acl.internal.ctrl_routing & 0xa) == 8)
 40.1050                          {
 40.1051 -                                mixdat = vram[(acl.mix_addr>>3)&0x1FFFFF] & (1<<(acl.mix_addr&7));
 40.1052 -                                if (bltout) pclog("%06X %02X  ",acl.mix_addr,vram[(acl.mix_addr>>3)&0x1FFFFF]);
 40.1053 +                                mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff] & (1 << (et4000->acl.mix_addr & 7));
 40.1054 +                                if (bltout) pclog("%06X %02X  ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff]);
 40.1055                          }
 40.1056                          else
 40.1057                          {
 40.1058                                  mixdat = mix & 1;
 40.1059 -                                mix>>=1; mix|=0x80000000;
 40.1060 +                                mix >>= 1; 
 40.1061 +                                mix |= 0x80000000;
 40.1062                          }
 40.1063 -                        acl.mix_addr++;
 40.1064 -                        rop = (mixdat) ? acl.internal.rop_fg:acl.internal.rop_bg;
 40.1065 -                        for (c=0;c<8;c++)
 40.1066 +                        et4000->acl.mix_addr++;
 40.1067 +                        rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg;
 40.1068 +                        for (c = 0; c < 8; c++)
 40.1069                          {
 40.1070 -                                d=(dest & (1<<c)) ? 1:0;
 40.1071 -                                if (source & (1<<c))  d|=2;
 40.1072 -                                if (pattern & (1<<c)) d|=4;
 40.1073 -                                if (rop & (1<<d)) out|=(1<<c);
 40.1074 +                                d = (dest & (1 << c)) ? 1 : 0;
 40.1075 +                                if (source & (1 << c))  d |= 2;
 40.1076 +                                if (pattern & (1 << c)) d |= 4;
 40.1077 +                                if (rop & (1 << d)) out |= (1 << c);
 40.1078                          }
 40.1079 -                        if (bltout) pclog("%06X = %02X\n",acl.dest_addr&0x1FFFFF,out);
 40.1080 -                        if (!(acl.internal.ctrl_routing&0x40))
 40.1081 +                        if (bltout) pclog("%06X = %02X\n", et4000->acl.dest_addr & 0x1fffff, out);
 40.1082 +                        if (!(et4000->acl.internal.ctrl_routing & 0x40))
 40.1083                          {
 40.1084 -                                vram[acl.dest_addr&0x1FFFFF]=out;
 40.1085 -                                changedvram[(acl.dest_addr&0x1FFFFF)>>10]=changeframecount;
 40.1086 +                                svga->vram[et4000->acl.dest_addr & 0x1fffff] = out;
 40.1087 +                                svga->changedvram[(et4000->acl.dest_addr & 0x1fffff) >> 10] = changeframecount;
 40.1088                          }
 40.1089                          else
 40.1090                          {
 40.1091 -                                acl.cpu_dat|=((uint64_t)out<<(acl.cpu_dat_pos*8));
 40.1092 -                                acl.cpu_dat_pos++;
 40.1093 +                                et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8));
 40.1094 +                                et4000->acl.cpu_dat_pos++;
 40.1095                          }
 40.1096                          
 40.1097 -//                        pclog("%i %i\n",acl.pix_pos,(acl.internal.pixel_depth>>4)&3);
 40.1098 -                        acl.pix_pos++;
 40.1099 -                        acl.internal.pos_x++;
 40.1100 -                        if (acl.pix_pos<=((acl.internal.pixel_depth>>4)&3))
 40.1101 +//                        pclog("%i %i\n",et4000->acl.pix_pos,(et4000->acl.internal.pixel_depth>>4)&3);
 40.1102 +                        et4000->acl.pix_pos++;
 40.1103 +                        et4000->acl.internal.pos_x++;
 40.1104 +                        if (et4000->acl.pix_pos <= ((et4000->acl.internal.pixel_depth >> 4) & 3))
 40.1105                          {
 40.1106 -                                if (acl.internal.xy_dir&1) et4000w32_decx(1);
 40.1107 -                                else                       et4000w32_incx(1);
 40.1108 +                                if (et4000->acl.internal.xy_dir & 1) et4000w32_decx(1, et4000);
 40.1109 +                                else                                 et4000w32_incx(1, et4000);
 40.1110                          }
 40.1111                          else
 40.1112                          {
 40.1113 -                                if (acl.internal.xy_dir&1) et4000w32_incx((acl.internal.pixel_depth>>4)&3);
 40.1114 -                                else                       et4000w32_decx((acl.internal.pixel_depth>>4)&3);
 40.1115 -                                acl.pix_pos=0;
 40.1116 +                                if (et4000->acl.internal.xy_dir & 1) 
 40.1117 +                                        et4000w32_incx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000);
 40.1118 +                                else                       
 40.1119 +                                        et4000w32_decx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000);
 40.1120 +                                et4000->acl.pix_pos = 0;
 40.1121                                  /*Next pixel*/
 40.1122 -                                switch (acl.internal.xy_dir&7)
 40.1123 +                                switch (et4000->acl.internal.xy_dir & 7)
 40.1124                                  {
 40.1125                                          case 0: case 1: /*Y+*/
 40.1126 -                                        et4000w32_incy();
 40.1127 -                                        acl.internal.pos_y++;
 40.1128 -                                        acl.internal.pos_x-=((acl.internal.pixel_depth>>4)&3)+1;
 40.1129 +                                        et4000w32_incy(et4000);
 40.1130 +                                        et4000->acl.internal.pos_y++;
 40.1131 +                                        et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1;
 40.1132                                          break;
 40.1133                                          case 2: case 3: /*Y-*/
 40.1134 -                                        et4000w32_decy();
 40.1135 -                                        acl.internal.pos_y++;
 40.1136 -                                        acl.internal.pos_x-=((acl.internal.pixel_depth>>4)&3)+1;
 40.1137 +                                        et4000w32_decy(et4000);
 40.1138 +                                        et4000->acl.internal.pos_y++;
 40.1139 +                                        et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1;
 40.1140                                          break;
 40.1141                                          case 4: case 6: /*X+*/
 40.1142 -                                        et4000w32_incx(((acl.internal.pixel_depth>>4)&3)+1);
 40.1143 -                                        //acl.internal.pos_x++;
 40.1144 +                                        et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000);
 40.1145 +                                        //et4000->acl.internal.pos_x++;
 40.1146                                          break;
 40.1147                                          case 5: case 7: /*X-*/
 40.1148 -                                        et4000w32_decx(((acl.internal.pixel_depth>>4)&3)+1);
 40.1149 -                                        //acl.internal.pos_x++;
 40.1150 +                                        et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000);
 40.1151 +                                        //et4000->acl.internal.pos_x++;
 40.1152                                          break;
 40.1153                                  }
 40.1154 -                                acl.internal.error+=acl.internal.dmin;
 40.1155 -                                if (acl.internal.error > acl.internal.dmaj)
 40.1156 +                                et4000->acl.internal.error += et4000->acl.internal.dmin;
 40.1157 +                                if (et4000->acl.internal.error > et4000->acl.internal.dmaj)
 40.1158                                  {
 40.1159 -                                        acl.internal.error-=acl.internal.dmaj;
 40.1160 -                                        switch (acl.internal.xy_dir&7)
 40.1161 +                                        et4000->acl.internal.error -= et4000->acl.internal.dmaj;
 40.1162 +                                        switch (et4000->acl.internal.xy_dir & 7)
 40.1163                                          {
 40.1164                                                  case 0: case 2: /*X+*/
 40.1165 -                                                et4000w32_incx(((acl.internal.pixel_depth>>4)&3)+1);
 40.1166 -                                                acl.internal.pos_x++;
 40.1167 +                                                et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000);
 40.1168 +                                                et4000->acl.internal.pos_x++;
 40.1169                                                  break;
 40.1170                                                  case 1: case 3: /*X-*/
 40.1171 -                                                et4000w32_decx(((acl.internal.pixel_depth>>4)&3)+1);
 40.1172 -                                                acl.internal.pos_x++;
 40.1173 +                                                et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000);
 40.1174 +                                                et4000->acl.internal.pos_x++;
 40.1175                                                  break;
 40.1176                                                  case 4: case 5: /*Y+*/
 40.1177 -                                                et4000w32_incy();
 40.1178 -                                                acl.internal.pos_y++;
 40.1179 +                                                et4000w32_incy(et4000);
 40.1180 +                                                et4000->acl.internal.pos_y++;
 40.1181                                                  break;
 40.1182                                                  case 6: case 7: /*Y-*/
 40.1183 -                                                et4000w32_decy();
 40.1184 -                                                acl.internal.pos_y++;
 40.1185 +                                                et4000w32_decy(et4000);
 40.1186 +                                                et4000->acl.internal.pos_y++;
 40.1187                                                  break;
 40.1188                                          }
 40.1189                                  }
 40.1190 -                                if (acl.internal.pos_x > acl.internal.count_x ||
 40.1191 -                                    acl.internal.pos_y > acl.internal.count_y)
 40.1192 +                                if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x ||
 40.1193 +                                    et4000->acl.internal.pos_y > et4000->acl.internal.count_y)
 40.1194                                  {
 40.1195 -                                        acl.status = 0;
 40.1196 +                                        et4000->acl.status = 0;
 40.1197  //                                        pclog("Blit line over\n");
 40.1198                                          return;
 40.1199                                  }
 40.1200 @@ -736,85 +758,87 @@
 40.1201          {
 40.1202                  while (count--)
 40.1203                  {
 40.1204 -                        if (bltout) pclog("%i,%i : ",acl.internal.pos_x,acl.internal.pos_y);
 40.1205 +                        if (bltout) pclog("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y);
 40.1206                          
 40.1207 -                        pattern=vram[(acl.pattern_addr+acl.pattern_x)&0x1FFFFF];
 40.1208 -                        source =vram[(acl.source_addr +acl.source_x) &0x1FFFFF];
 40.1209 -                        if (bltout) pclog("%i %06X %06X %02X %02X  ",acl.pattern_y,(acl.pattern_addr+acl.pattern_x)&0x1FFFFF,(acl.source_addr +acl.source_x) &0x1FFFFF,pattern,source);
 40.1210 +                        pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff];
 40.1211 +                        source  = svga->vram[(et4000->acl.source_addr  + et4000->acl.source_x)  & 0x1fffff];
 40.1212 +                        if (bltout) pclog("%i %06X %06X %02X %02X  ", et4000->acl.pattern_y, (et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff, (et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff, pattern, source);
 40.1213  
 40.1214 -                        if (cpu_input==2)
 40.1215 +                        if (cpu_input == 2)
 40.1216                          {
 40.1217 -                                source=sdat&0xFF;
 40.1218 -                                sdat>>=8;
 40.1219 +                                source = sdat & 0xff;
 40.1220 +                                sdat >>= 8;
 40.1221                          }
 40.1222 -                        dest=vram[acl.dest_addr   &0x1FFFFF];
 40.1223 -                        out=0;
 40.1224 -                        if (bltout) pclog("%06X %02X  %i %08X %08X  ",dest,acl.dest_addr,mix&1,mix,acl.mix_addr);
 40.1225 -                        if ((acl.internal.ctrl_routing&0xA)==8)
 40.1226 +                        dest = svga->vram[et4000->acl.dest_addr & 0x1fffff];
 40.1227 +                        out = 0;
 40.1228 +                        if (bltout) pclog("%06X %02X  %i %08X %08X  ", dest, et4000->acl.dest_addr, mix & 1, mix, et4000->acl.mix_addr);
 40.1229 +                        if ((et4000->acl.internal.ctrl_routing & 0xa) == 8)
 40.1230                          {
 40.1231 -                                mixdat = vram[(acl.mix_addr>>3)&0x1FFFFF] & (1<<(acl.mix_addr&7));
 40.1232 -                                if (bltout) pclog("%06X %02X  ",acl.mix_addr,vram[(acl.mix_addr>>3)&0x1FFFFF]);
 40.1233 +                                mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff] & (1 << (et4000->acl.mix_addr & 7));
 40.1234 +                                if (bltout) pclog("%06X %02X  ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff]);
 40.1235                          }
 40.1236                          else
 40.1237                          {
 40.1238                                  mixdat = mix & 1;
 40.1239 -                                mix>>=1; mix|=0x80000000;
 40.1240 +                                mix >>= 1; 
 40.1241 +                                mix |= 0x80000000;
 40.1242                          }
 40.1243  
 40.1244 -                        rop = (mixdat) ? acl.internal.rop_fg:acl.internal.rop_bg;
 40.1245 -                        for (c=0;c<8;c++)
 40.1246 +                        rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg;
 40.1247 +                        for (c = 0; c < 8; c++)
 40.1248                          {
 40.1249 -                                d=(dest & (1<<c)) ? 1:0;
 40.1250 -                                if (source & (1<<c))  d|=2;
 40.1251 -                                if (pattern & (1<<c)) d|=4;
 40.1252 -                                if (rop & (1<<d)) out|=(1<<c);
 40.1253 +                                d = (dest & (1 << c)) ? 1 : 0;
 40.1254 +                                if (source & (1 << c))  d |= 2;
 40.1255 +                                if (pattern & (1 << c)) d |= 4;
 40.1256 +                                if (rop & (1 << d)) out |= (1 << c);
 40.1257                          }
 40.1258 -                        if (bltout) pclog("%06X = %02X\n",acl.dest_addr&0x1FFFFF,out);
 40.1259 -                        if (!(acl.internal.ctrl_routing&0x40))
 40.1260 +                        if (bltout) pclog("%06X = %02X\n", et4000->acl.dest_addr & 0x1fffff, out);
 40.1261 +                        if (!(et4000->acl.internal.ctrl_routing & 0x40))
 40.1262                          {
 40.1263 -                                vram[acl.dest_addr&0x1FFFFF]=out;
 40.1264 -                                changedvram[(acl.dest_addr&0x1FFFFF)>>10]=changeframecount;
 40.1265 +                                svga->vram[et4000->acl.dest_addr & 0x1fffff] = out;
 40.1266 +                                svga->changedvram[(et4000->acl.dest_addr & 0x1fffff) >> 10] = changeframecount;
 40.1267                          }
 40.1268                          else
 40.1269                          {
 40.1270 -                                acl.cpu_dat|=((uint64_t)out<<(acl.cpu_dat_pos*8));
 40.1271 -                                acl.cpu_dat_pos++;
 40.1272 +                                et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8));
 40.1273 +                                et4000->acl.cpu_dat_pos++;
 40.1274                          }
 40.1275  
 40.1276 -                        if (acl.internal.xy_dir&1) et4000w32_decx(1);
 40.1277 -                        else                       et4000w32_incx(1);
 40.1278 +                        if (et4000->acl.internal.xy_dir & 1) et4000w32_decx(1, et4000);
 40.1279 +                        else                                 et4000w32_incx(1, et4000);
 40.1280  
 40.1281 -                        acl.internal.pos_x++;
 40.1282 -                        if (acl.internal.pos_x>acl.internal.count_x)
 40.1283 +                        et4000->acl.internal.pos_x++;
 40.1284 +                        if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x)
 40.1285                          {
 40.1286 -                                if (acl.internal.xy_dir&2)
 40.1287 +                                if (et4000->acl.internal.xy_dir & 2)
 40.1288                                  {
 40.1289 -                                        et4000w32_decy();
 40.1290 -                                        acl.mix_back =acl.mix_addr =acl.mix_back -(acl.internal.mix_off +1);
 40.1291 -                                        acl.dest_back=acl.dest_addr=acl.dest_back-(acl.internal.dest_off+1);
 40.1292 +                                        et4000w32_decy(et4000);
 40.1293 +                                        et4000->acl.mix_back  = et4000->acl.mix_addr  = et4000->acl.mix_back  - (et4000->acl.internal.mix_off  + 1);
 40.1294 +                                        et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1);
 40.1295                                  }
 40.1296                                  else
 40.1297                                  {
 40.1298 -                                        et4000w32_incy();
 40.1299 -                                        acl.mix_back =acl.mix_addr =acl.mix_back +acl.internal.mix_off +1;
 40.1300 -                                        acl.dest_back=acl.dest_addr=acl.dest_back+acl.internal.dest_off+1;
 40.1301 +                                        et4000w32_incy(et4000);
 40.1302 +                                        et4000->acl.mix_back  = et4000->acl.mix_addr  = et4000->acl.mix_back  + et4000->acl.internal.mix_off  + 1;
 40.1303 +                                        et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1;
 40.1304                                  }
 40.1305  
 40.1306 -                                acl.pattern_x = acl.pattern_x_back;
 40.1307 -                                acl.source_x  = acl.source_x_back;
 40.1308 +                                et4000->acl.pattern_x = et4000->acl.pattern_x_back;
 40.1309 +                                et4000->acl.source_x  = et4000->acl.source_x_back;
 40.1310  
 40.1311 -                                acl.internal.pos_y++;
 40.1312 -                                acl.internal.pos_x=0;
 40.1313 -                                if (acl.internal.pos_y>acl.internal.count_y)
 40.1314 +                                et4000->acl.internal.pos_y++;
 40.1315 +                                et4000->acl.internal.pos_x = 0;
 40.1316 +                                if (et4000->acl.internal.pos_y > et4000->acl.internal.count_y)
 40.1317                                  {
 40.1318 -                                        acl.status = 0;
 40.1319 +                                        et4000->acl.status = 0;
 40.1320  //                                        pclog("Blit over\n");
 40.1321                                          return;
 40.1322                                  }
 40.1323                                  if (cpu_input) return;
 40.1324 -                                if (acl.internal.ctrl_routing&0x40)
 40.1325 +                                if (et4000->acl.internal.ctrl_routing & 0x40)
 40.1326                                  {
 40.1327 -                                        if (acl.cpu_dat_pos&3) acl.cpu_dat_pos+=4-(acl.cpu_dat_pos&3);
 40.1328 +                                        if (et4000->acl.cpu_dat_pos & 3) 
 40.1329 +                                                et4000->acl.cpu_dat_pos += 4 - (et4000->acl.cpu_dat_pos & 3);
 40.1330                                          return;
 40.1331                                  }
 40.1332                          }
 40.1333 @@ -823,34 +847,38 @@
 40.1334  }
 40.1335  
 40.1336  
 40.1337 -void et4000w32p_cursor_draw(int displine)
 40.1338 +void et4000w32p_hwcursor_draw(svga_t *svga, int displine)
 40.1339  {
 40.1340          int x, offset;
 40.1341          uint8_t dat;
 40.1342 -        offset = svga_hwcursor_latch.xoff;
 40.1343 -        for (x = 0; x < 64 - svga_hwcursor_latch.xoff; x += 4)
 40.1344 +        offset = svga->hwcursor_latch.xoff;
 40.1345 +        for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4)
 40.1346          {
 40.1347 -                dat = vram[svga_hwcursor_latch.addr + (offset >> 2)];
 40.1348 -                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32]  = (dat & 1) ? 0xFFFFFF : 0;
 40.1349 -                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 32] ^= 0xFFFFFF;
 40.1350 +                dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)];
 40.1351 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32]  = (dat & 1) ? 0xFFFFFF : 0;
 40.1352 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF;
 40.1353                  dat >>= 2;
 40.1354 -                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33]  = (dat & 1) ? 0xFFFFFF : 0;
 40.1355 -                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 33] ^= 0xFFFFFF;
 40.1356 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33]  = (dat & 1) ? 0xFFFFFF : 0;
 40.1357 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF;
 40.1358                  dat >>= 2;
 40.1359 -                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34]  = (dat & 1) ? 0xFFFFFF : 0;
 40.1360 -                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 34] ^= 0xFFFFFF;
 40.1361 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34]  = (dat & 1) ? 0xFFFFFF : 0;
 40.1362 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF;
 40.1363                  dat >>= 2;
 40.1364 -                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35]  = (dat & 1) ? 0xFFFFFF : 0;
 40.1365 -                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga_hwcursor_latch.x + x + 35] ^= 0xFFFFFF;
 40.1366 +                if (!(dat & 2))          ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35]  = (dat & 1) ? 0xFFFFFF : 0;
 40.1367 +                else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF;
 40.1368                  dat >>= 2;
 40.1369                  offset += 4;
 40.1370          }
 40.1371 -        svga_hwcursor_latch.addr += 16;
 40.1372 +        svga->hwcursor_latch.addr += 16;
 40.1373  }
 40.1374  
 40.1375 -uint8_t et4000w32p_pci_read(int func, int addr, void *priv)
 40.1376 +uint8_t et4000w32p_pci_read(int func, int addr, void *p)
 40.1377  {
 40.1378 +        et4000w32p_t *et4000 = (et4000w32p_t *)p;
 40.1379 +        svga_t *svga = &et4000->svga;
 40.1380 +
 40.1381          pclog("ET4000 PCI read %08X\n", addr);
 40.1382 +
 40.1383          switch (addr)
 40.1384          {
 40.1385                  case 0x00: return 0x0c; /*Tseng Labs*/
 40.1386 @@ -871,8 +899,8 @@
 40.1387                  
 40.1388                  case 0x10: return 0x00; /*Linear frame buffer address*/
 40.1389                  case 0x11: return 0x00;
 40.1390 -                case 0x12: return crtc[0x5a] & 0x80;
 40.1391 -                case 0x13: return crtc[0x59];
 40.1392 +                case 0x12: return svga->crtc[0x5a] & 0x80;
 40.1393 +                case 0x13: return svga->crtc[0x59];
 40.1394  
 40.1395                  case 0x30: return 0x01; /*BIOS ROM address*/
 40.1396                  case 0x31: return 0x00;
 40.1397 @@ -882,57 +910,66 @@
 40.1398          return 0;
 40.1399  }
 40.1400  
 40.1401 -void et4000w32p_pci_write(int func, int addr, uint8_t val, void *priv)
 40.1402 +void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p)
 40.1403  {
 40.1404 +        et4000w32p_t *et4000 = (et4000w32p_t *)p;
 40.1405 +
 40.1406          switch (addr)
 40.1407          {
 40.1408 -                case 0x13: et4000w32p_linearbase = val << 24; et4000w32p_recalcmapping(); break;
 40.1409 +                case 0x13: 
 40.1410 +                et4000->linearbase = val << 24; 
 40.1411 +                et4000w32p_recalcmapping(et4000); 
 40.1412 +                break;
 40.1413          }
 40.1414  }
 40.1415  
 40.1416 -int et4000w32p_init()
 40.1417 +void *et4000w32p_init()
 40.1418  {
 40.1419 -        svga_recalctimings_ex = et4000w32p_recalctimings;
 40.1420 -        svga_hwcursor_draw    = et4000w32p_cursor_draw;
 40.1421 +        et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t));
 40.1422 +        memset(et4000, 0, sizeof(et4000w32p_t));
 40.1423 +
 40.1424 +        svga_init(&et4000->svga, et4000, 1 << 21, /*2mb*/
 40.1425 +                   et4000w32p_recalctimings,
 40.1426 +                   et4000w32p_in, et4000w32p_out,
 40.1427 +                   et4000w32p_hwcursor_draw); 
 40.1428 +
 40.1429 +        io_sethandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
 40.1430 +
 40.1431 +        io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
 40.1432 +        io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
 40.1433 +        io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
 40.1434 +        io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
 40.1435 +        io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
 40.1436 +        io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
 40.1437 +        io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
 40.1438 +        io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
 40.1439          
 40.1440 -        io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
 40.1441 -        io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
 40.1442 -        io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
 40.1443 -        io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
 40.1444 -        io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
 40.1445 -        io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
 40.1446 -        io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
 40.1447 -        io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, NULL);
 40.1448 +        pci_add(et4000w32p_pci_read, et4000w32p_pci_write, et4000);
 40.1449          
 40.1450 -        pci_add(et4000w32p_pci_read, et4000w32p_pci_write, NULL);
 40.1451 -        
 40.1452 -        svga_vram_limit = 2 << 20; /*2mb - chip supports 4mb but can't map both 4mb linear frame buffer and accelerator registers*/
 40.1453 -        
 40.1454 -        vrammask = 0x1fffff;
 40.1455 -
 40.1456 -        return svga_init();
 40.1457 +        return et4000;
 40.1458  }
 40.1459  
 40.1460 -GFXCARD vid_et4000w32p =
 40.1461 +void et4000w32p_close(void *p)
 40.1462  {
 40.1463 +        et4000w32p_t *et4000 = (et4000w32p_t *)p;
 40.1464 +
 40.1465 +        svga_close(&et4000->svga);
 40.1466 +        
 40.1467 +        free(et4000);
 40.1468 +}
 40.1469 +
 40.1470 +void et4000w32p_speed_changed(void *p)
 40.1471 +{
 40.1472 +        et4000w32p_t *et4000 = (et4000w32p_t *)p;
 40.1473 +        
 40.1474 +        svga_recalctimings(&et4000->svga);
 40.1475 +}
 40.1476 +
 40.1477 +device_t et4000w32p_device =
 40.1478 +{
 40.1479 +        "Tseng Labs ET4000/w32p",
 40.1480          et4000w32p_init,
 40.1481 -        /*IO at 3Cx/3Dx*/
 40.1482 -        et4000w32p_out,
 40.1483 -        et4000w32p_in,
 40.1484 -        /*IO at 3Ax/3Bx*/
 40.1485 -        video_out_null,
 40.1486 -        video_in_null,
 40.1487 -
 40.1488 -        svga_poll,
 40.1489 -        svga_recalctimings,
 40.1490 -
 40.1491 -        svga_write,
 40.1492 -        video_write_null,
 40.1493 -        video_write_null,
 40.1494 -
 40.1495 -        svga_read,
 40.1496 -        video_read_null,
 40.1497 -        video_read_null
 40.1498 +        et4000w32p_close,
 40.1499 +        et4000w32p_speed_changed,
 40.1500 +        svga_add_status_info
 40.1501  };
 40.1502 -
 40.1503 -
    41.1 --- a/src/vid_et4000w32.h	Tue Jun 04 20:52:17 2013 +0100
    41.2 +++ b/src/vid_et4000w32.h	Mon Jun 24 20:42:35 2013 +0100
    41.3 @@ -0,0 +1,1 @@
    41.4 +extern device_t et4000w32p_device;
    42.1 --- a/src/vid_hercules.c	Tue Jun 04 20:52:17 2013 +0100
    42.2 +++ b/src/vid_hercules.c	Mon Jun 24 20:42:35 2013 +0100
    42.3 @@ -1,296 +1,358 @@
    42.4  /*Hercules emulation*/
    42.5 +#include <stdlib.h>
    42.6  #include "ibm.h"
    42.7 +#include "device.h"
    42.8  #include "mem.h"
    42.9  #include "timer.h"
   42.10  #include "video.h"
   42.11 +#include "vid_hercules.h"
   42.12  
   42.13 -void hercules_recalctimings();
   42.14 -void hercules_write(uint32_t addr, uint8_t val, void *priv);
   42.15 -uint8_t hercules_read(uint32_t addr, void *priv);
   42.16 +typedef struct hercules_t
   42.17 +{
   42.18 +        uint8_t crtc[32];
   42.19 +        int crtcreg;
   42.20  
   42.21 -static uint8_t hercules_ctrl, hercules_ctrl2, hercules_stat;
   42.22 -uint8_t crtcm[32],crtcmreg;
   42.23 +        uint8_t ctrl, ctrl2, stat;
   42.24  
   42.25 -void hercules_out(uint16_t addr, uint8_t val, void *priv)
   42.26 +        int dispontime, dispofftime;
   42.27 +        int vidtime;
   42.28 +        
   42.29 +        int firstline, lastline;
   42.30 +
   42.31 +        int linepos, displine;
   42.32 +        int vc, sc;
   42.33 +        uint16_t ma, maback;
   42.34 +        int con, coff, cursoron;
   42.35 +        int dispon, blink;
   42.36 +        int vsynctime, vadj;
   42.37 +
   42.38 +        uint8_t *vram;
   42.39 +} hercules_t;
   42.40 +
   42.41 +static int mdacols[256][2][2];
   42.42 +
   42.43 +void hercules_recalctimings(hercules_t *hercules);
   42.44 +void hercules_write(uint32_t addr, uint8_t val, void *p);
   42.45 +uint8_t hercules_read(uint32_t addr, void *p);
   42.46 +
   42.47 +
   42.48 +void hercules_out(uint16_t addr, uint8_t val, void *p)
   42.49  {
   42.50 +        hercules_t *hercules = (hercules_t *)p;
   42.51  //        pclog("Herc out %04X %02X\n",addr,val);
   42.52          switch (addr)
   42.53          {
   42.54 -                case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
   42.55 -                crtcmreg = val & 31;
   42.56 +                case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
   42.57 +                hercules->crtcreg = val & 31;
   42.58                  return;
   42.59 -                case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
   42.60 -                crtcm[crtcmreg] = val;
   42.61 -                if (crtcm[10]==6 && crtcm[11]==7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
   42.62 +                case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
   42.63 +                hercules->crtc[hercules->crtcreg] = val;
   42.64 +                if (hercules->crtc[10] == 6 && hercules->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
   42.65                  {
   42.66 -                        crtcm[10]=0xB;
   42.67 -                        crtcm[11]=0xC;
   42.68 +                        hercules->crtc[10] = 0xb;
   42.69 +                        hercules->crtc[11] = 0xc;
   42.70                  }
   42.71 -                hercules_recalctimings();
   42.72 +                hercules_recalctimings(hercules);
   42.73                  return;
   42.74 -                case 0x3B8:
   42.75 -                hercules_ctrl = val;
   42.76 +                case 0x3b8:
   42.77 +                hercules->ctrl = val;
   42.78                  return;
   42.79 -                case 0x3BF:
   42.80 -                hercules_ctrl2 = val;
   42.81 -                video_write_b800 = (val&2) ? hercules_write : video_write_null;
   42.82 -                video_read_b800  = (val&2) ? hercules_read  : video_read_null;
   42.83 +                case 0x3bf:
   42.84 +                hercules->ctrl2 = val;
   42.85 +                mem_removehandler(0xb8000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL,  hercules);
   42.86 +                if (val & 2)
   42.87 +                        mem_sethandler(0xb8000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL,  hercules);
   42.88                  return;
   42.89          }
   42.90  }
   42.91  
   42.92 -uint8_t hercules_in(uint16_t addr, void *priv)
   42.93 +uint8_t hercules_in(uint16_t addr, void *p)
   42.94  {
   42.95 +        hercules_t *hercules = (hercules_t *)p;
   42.96   //       pclog("Herc in %04X %02X %04X:%04X %04X\n",addr,(hercules_stat & 0xF) | ((hercules_stat & 8) << 4),CS,pc,CX);
   42.97          switch (addr)
   42.98          {
   42.99 -                case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
  42.100 -                return crtcmreg;
  42.101 -                case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
  42.102 -                return crtcm[crtcmreg];
  42.103 -                case 0x3BA:
  42.104 -                return (hercules_stat & 0xF) | ((hercules_stat & 8) << 4);
  42.105 +                case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
  42.106 +                return hercules->crtcreg;
  42.107 +                case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
  42.108 +                return hercules->crtc[hercules->crtcreg];
  42.109 +                case 0x3ba:
  42.110 +                return (hercules->stat & 0xf) | ((hercules->stat & 8) << 4);
  42.111          }
  42.112          return 0xff;
  42.113  }
  42.114  
  42.115 -void hercules_write(uint32_t addr, uint8_t val, void *priv)
  42.116 +void hercules_write(uint32_t addr, uint8_t val, void *p)
  42.117  {
  42.118 +        hercules_t *hercules = (hercules_t *)p;
  42.119  //        pclog("Herc write %08X %02X\n",addr,val);
  42.120 -        vram[addr&0xFFFF]=val;
  42.121 +        hercules->vram[addr & 0xffff] = val;
  42.122  }
  42.123  
  42.124 -uint8_t hercules_read(uint32_t addr, void *priv)
  42.125 +uint8_t hercules_read(uint32_t addr, void *p)
  42.126  {
  42.127 -        return vram[addr&0xFFFF];
  42.128 +        hercules_t *hercules = (hercules_t *)p;
  42.129 +        return hercules->vram[addr & 0xffff];
  42.130  }
  42.131  
  42.132 -void hercules_recalctimings()
  42.133 +void hercules_recalctimings(hercules_t *hercules)
  42.134  {
  42.135 +        double disptime;
  42.136  	double _dispontime, _dispofftime;
  42.137 -        disptime=crtc[0]+1;
  42.138 -        _dispontime=crtc[1];
  42.139 -        _dispofftime=disptime-_dispontime;
  42.140 -        _dispontime*=MDACONST;
  42.141 -        _dispofftime*=MDACONST;
  42.142 -	dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  42.143 -	dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  42.144 +        disptime = hercules->crtc[0] + 1;
  42.145 +        _dispontime  = hercules->crtc[1];
  42.146 +        _dispofftime = disptime - _dispontime;
  42.147 +        _dispontime  *= MDACONST;
  42.148 +        _dispofftime *= MDACONST;
  42.149 +	hercules->dispontime  = (int)(_dispontime  * (1 << TIMER_SHIFT));
  42.150 +	hercules->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  42.151  }
  42.152  
  42.153 -int mdacols[256][2][2];
  42.154 -
  42.155 -static int linepos,displine;
  42.156 -static int vc,sc;
  42.157 -static uint16_t ma,maback;
  42.158 -static int con,coff,cursoron;
  42.159 -static int cgadispon,cgablink;
  42.160 -static int vsynctime,vadj;
  42.161 -
  42.162 -void hercules_poll()
  42.163 +void hercules_poll(void *p)
  42.164  {
  42.165 -        uint16_t ca=(crtcm[15]|(crtcm[14]<<8))&0x3FFF;
  42.166 +        hercules_t *hercules = (hercules_t *)p;
  42.167 +        uint16_t ca = (hercules->crtc[15] | (hercules->crtc[14] << 8)) & 0x3fff;
  42.168          int drawcursor;
  42.169 -        int x,c;
  42.170 +        int x, c;
  42.171          int oldvc;
  42.172 -        uint8_t chr,attr;
  42.173 +        uint8_t chr, attr;
  42.174          uint16_t dat;
  42.175          int cols[4];
  42.176          int oldsc;
  42.177          int blink;
  42.178 -        if (!linepos)
  42.179 +        if (!hercules->linepos)
  42.180          {
  42.181                  //pclog("Poll %i %i\n",vc,sc);
  42.182 -                vidtime+=dispofftime;
  42.183 -                hercules_stat|=1;
  42.184 -                linepos=1;
  42.185 -                oldsc=sc;
  42.186 -                if ((crtcm[8]&3)==3) sc=(sc<<1)&7;
  42.187 -                if (cgadispon)
  42.188 +                hercules->vidtime += hercules->dispofftime;
  42.189 +                hercules->stat |= 1;
  42.190 +                hercules->linepos = 1;
  42.191 +                oldsc = hercules->sc;
  42.192 +                if ((hercules->crtc[8] & 3) == 3) 
  42.193 +                        hercules->sc = (hercules->sc << 1) & 7;
  42.194 +                if (hercules->dispon)
  42.195                  {
  42.196 -                        if (displine<firstline)
  42.197 +                        if (hercules->displine < hercules->firstline)
  42.198                          {
  42.199 -                                firstline=displine;
  42.200 +                                hercules->firstline = hercules->displine;
  42.201                          }
  42.202 -                        lastline=displine;
  42.203 -                        cols[0]=0;
  42.204 -                        cols[1]=7;
  42.205 -                        if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1))
  42.206 +                        hercules->lastline = hercules->displine;
  42.207 +                        cols[0] = 0;
  42.208 +                        cols[1] = 7;
  42.209 +                        if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1))
  42.210                          {
  42.211 -                                ca=(sc&3)*0x2000;
  42.212 -                                if ((hercules_ctrl & 0x80) && (hercules_ctrl2 & 2)) ca+=0x8000;
  42.213 +                                ca = (hercules->sc & 3) * 0x2000;
  42.214 +                                if ((hercules->ctrl & 0x80) && (hercules->ctrl2 & 2)) 
  42.215 +                                        ca += 0x8000;
  42.216  //                                printf("Draw herc %04X\n",ca);
  42.217 -                                for (x=0;x<crtcm[1];x++)
  42.218 +                                for (x = 0; x < hercules->crtc[1]; x++)
  42.219                                  {
  42.220 -                                        dat=(vram[((ma<<1)&0x1FFF)+ca]<<8)|vram[((ma<<1)&0x1FFF)+ca+1];
  42.221 -                                        ma++;
  42.222 -                                        for (c=0;c<16;c++)
  42.223 -                                            buffer->line[displine][(x<<4)+c]=(dat&(32768>>c))?7:0;
  42.224 +                                        dat = (hercules->vram[((hercules->ma << 1) & 0x1fff) + ca] << 8) | hercules->vram[((hercules->ma << 1) & 0x1fff) + ca + 1];
  42.225 +                                        hercules->ma++;
  42.226 +                                        for (c = 0; c < 16; c++)
  42.227 +                                            buffer->line[hercules->displine][(x << 4) + c] = (dat & (32768 >> c)) ? 7 : 0;
  42.228                                  }
  42.229                          }
  42.230                          else
  42.231                          {
  42.232 -                                for (x=0;x<crtcm[1];x++)
  42.233 +                                for (x = 0; x < hercules->crtc[1]; x++)
  42.234                                  {
  42.235 -                                        chr=vram[(ma<<1)&0x3FFF];
  42.236 -                                        attr=vram[((ma<<1)+1)&0x3FFF];
  42.237 -                                        drawcursor=((ma==ca) && con && cursoron);
  42.238 -                                        blink=((cgablink&16) && (hercules_ctrl&0x20) && (attr&0x80) && !drawcursor);
  42.239 -                                        if (sc==12 && ((attr&7)==1))
  42.240 +                                        chr  = hercules->vram[(hercules->ma << 1) & 0x3fff];
  42.241 +                                        attr = hercules->vram[((hercules->ma << 1) + 1) & 0x3fff];
  42.242 +                                        drawcursor = ((hercules->ma == ca) && hercules->con && hercules->cursoron);
  42.243 +                                        blink = ((hercules->blink & 16) && (hercules->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
  42.244 +                                        if (hercules->sc == 12 && ((attr & 7) == 1))
  42.245                                          {
  42.246 -                                                for (c=0;c<9;c++)
  42.247 -                                                    buffer->line[displine][(x*9)+c]=mdacols[attr][blink][1];
  42.248 +                                                for (c = 0; c < 9; c++)
  42.249 +                                                    buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][1];
  42.250                                          }
  42.251                                          else
  42.252                                          {
  42.253 -                                                for (c=0;c<8;c++)
  42.254 -                                                    buffer->line[displine][(x*9)+c]=mdacols[attr][blink][(fontdatm[chr][sc]&(1<<(c^7)))?1:0];
  42.255 -                                                if ((chr&~0x1F)==0xC0) buffer->line[displine][(x*9)+8]=mdacols[attr][blink][fontdatm[chr][sc]&1];
  42.256 -                                                else                   buffer->line[displine][(x*9)+8]=mdacols[attr][blink][0];
  42.257 +                                                for (c = 0; c < 8; c++)
  42.258 +                                                    buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][hercules->sc] & (1 << (c ^ 7))) ? 1 : 0];
  42.259 +                                                if ((chr & ~0x1f) == 0xc0) buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][hercules->sc] & 1];
  42.260 +                                                else                       buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][0];
  42.261                                          }
  42.262 -                                        ma++;
  42.263 +                                        hercules->ma++;
  42.264                                          if (drawcursor)
  42.265                                          {
  42.266 -                                                for (c=0;c<9;c++)
  42.267 -                                                    buffer->line[displine][(x*9)+c]^=mdacols[attr][0][1];
  42.268 +                                                for (c = 0; c < 9; c++)
  42.269 +                                                    buffer->line[hercules->displine][(x * 9) + c] ^= mdacols[attr][0][1];
  42.270                                          }
  42.271                                  }
  42.272                          }
  42.273                  }
  42.274 -                sc=oldsc;
  42.275 -                if (vc==crtcm[7] && !sc)
  42.276 +                hercules->sc = oldsc;
  42.277 +                if (hercules->vc == hercules->crtc[7] && !hercules->sc)
  42.278                  {
  42.279 -                        hercules_stat|=8;
  42.280 +                        hercules->stat |= 8;
  42.281  //                        printf("VSYNC on %i %i\n",vc,sc);
  42.282                  }
  42.283 -                displine++;
  42.284 -                if (displine>=500) displine=0;
  42.285 +                hercules->displine++;
  42.286 +                if (hercules->displine >= 500) 
  42.287 +                        hercules->displine = 0;
  42.288          }
  42.289          else
  42.290          {
  42.291 -                vidtime+=dispontime;
  42.292 -                if (cgadispon) hercules_stat&=~1;
  42.293 -                linepos=0;
  42.294 -                if (vsynctime)
  42.295 +                hercules->vidtime += hercules->dispontime;
  42.296 +                if (hercules->dispon) 
  42.297 +                        hercules->stat &= ~1;
  42.298 +                hercules->linepos = 0;
  42.299 +                if (hercules->vsynctime)
  42.300                  {
  42.301 -                        vsynctime--;
  42.302 -                        if (!vsynctime)
  42.303 +                        hercules->vsynctime--;
  42.304 +                        if (!hercules->vsynctime)
  42.305                          {
  42.306 -                                hercules_stat&=~8;
  42.307 +                                hercules->stat &= ~8;
  42.308  //                                printf("VSYNC off %i %i\n",vc,sc);
  42.309                          }
  42.310                  }
  42.311 -                if (sc==(crtcm[11]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[11]&31)>>1))) { con=0; coff=1; }
  42.312 -                if (vadj)
  42.313 +                if (hercules->sc == (hercules->crtc[11] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[11] & 31) >> 1))) 
  42.314 +                { 
  42.315 +                        hercules->con = 0; 
  42.316 +                        hercules->coff = 1; 
  42.317 +                }
  42.318 +                if (hercules->vadj)
  42.319                  {
  42.320 -                        sc++;
  42.321 -                        sc&=31;
  42.322 -                        ma=maback;
  42.323 -                        vadj--;
  42.324 -                        if (!vadj)
  42.325 +                        hercules->sc++;
  42.326 +                        hercules->sc &= 31;
  42.327 +                        hercules->ma = hercules->maback;
  42.328 +                        hercules->vadj--;
  42.329 +                        if (!hercules->vadj)
  42.330                          {
  42.331 -                                cgadispon=1;
  42.332 -                                ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
  42.333 -                                sc=0;
  42.334 +                                hercules->dispon = 1;
  42.335 +                                hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff;
  42.336 +                                hercules->sc = 0;
  42.337                          }
  42.338                  }
  42.339 -                else if (sc==crtcm[9] || ((crtcm[8]&3)==3 && sc==(crtcm[9]>>1)))
  42.340 +                else if (hercules->sc == hercules->crtc[9] || ((hercules->crtc[8] & 3) == 3 && hercules->sc == (hercules->crtc[9] >> 1)))
  42.341                  {
  42.342 -                        maback=ma;
  42.343 -                        sc=0;
  42.344 -                        oldvc=vc;
  42.345 -                        vc++;
  42.346 -                        vc&=127;
  42.347 -                        if (vc==crtcm[6]) cgadispon=0;
  42.348 -                        if (oldvc==crtcm[4])
  42.349 +                        hercules->maback = hercules->ma;
  42.350 +                        hercules->sc = 0;
  42.351 +                        oldvc = hercules->vc;
  42.352 +                        hercules->vc++;
  42.353 +                        hercules->vc &= 127;
  42.354 +                        if (hercules->vc == hercules->crtc[6]) 
  42.355 +                                hercules->dispon = 0;
  42.356 +                        if (oldvc == hercules->crtc[4])
  42.357                          {
  42.358  //                                printf("Display over at %i\n",displine);
  42.359 -                                vc=0;
  42.360 -                                vadj=crtcm[5];
  42.361 -                                if (!vadj) cgadispon=1;
  42.362 -                                if (!vadj) ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
  42.363 -                                if ((crtcm[10]&0x60)==0x20) cursoron=0;
  42.364 -                                else                        cursoron=cgablink&16;
  42.365 +                                hercules->vc = 0;
  42.366 +                                hercules->vadj = hercules->crtc[5];
  42.367 +                                if (!hercules->vadj) hercules->dispon=1;
  42.368 +                                if (!hercules->vadj) hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff;
  42.369 +                                if ((hercules->crtc[10] & 0x60) == 0x20) hercules->cursoron = 0;
  42.370 +                                else                                     hercules->cursoron = hercules->blink & 16;
  42.371                          }
  42.372 -                        if (vc==crtcm[7])
  42.373 +                        if (hercules->vc == hercules->crtc[7])
  42.374                          {
  42.375 -                                cgadispon=0;
  42.376 -                                displine=0;
  42.377 -                                vsynctime=16;//(crtcm[3]>>4)+1;
  42.378 -                                if (crtcm[7])
  42.379 +                                hercules->dispon = 0;
  42.380 +                                hercules->displine = 0;
  42.381 +                                hercules->vsynctime = 16;//(crtcm[3]>>4)+1;
  42.382 +                                if (hercules->crtc[7])
  42.383                                  {
  42.384  //                                        printf("Lastline %i Firstline %i  %i\n",lastline,firstline,lastline-firstline);
  42.385 -                                        if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1)) x = crtcm[1] << 4;
  42.386 -                                        else                                             x = crtcm[1] * 9;
  42.387 -                                        lastline++;
  42.388 -                                        if (x!=xsize || (lastline-firstline)!=ysize)
  42.389 +                                        if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) x = hercules->crtc[1] << 4;
  42.390 +                                        else                                               x = hercules->crtc[1] * 9;
  42.391 +                                        hercules->lastline++;
  42.392 +                                        if (x != xsize || (hercules->lastline - hercules->firstline) != ysize)
  42.393                                          {
  42.394 -                                                xsize=x;
  42.395 -                                                ysize=lastline-firstline;
  42.396 +                                                xsize = x;
  42.397 +                                                ysize = hercules->lastline - hercules->firstline;
  42.398  //                                                printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]);
  42.399 -                                                if (xsize<64) xsize=656;
  42.400 -                                                if (ysize<32) ysize=200;
  42.401 -                                                updatewindowsize(xsize,ysize);
  42.402 +                                                if (xsize < 64) xsize = 656;
  42.403 +                                                if (ysize < 32) ysize = 200;
  42.404 +                                                updatewindowsize(xsize, ysize);
  42.405                                          }
  42.406                                  startblit();
  42.407 -                                        video_blit_memtoscreen_8(0, firstline, xsize, ysize);
  42.408 +                                        video_blit_memtoscreen_8(0, hercules->firstline, xsize, ysize);
  42.409                                  endblit();
  42.410                                          frames++;
  42.411 -                                        if ((hercules_ctrl & 2) && (hercules_ctrl2 & 1))
  42.412 +                                        if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1))
  42.413                                          {
  42.414 -                                                video_res_x = crtcm[1] * 16;
  42.415 -                                                video_res_y = crtcm[6] * 4;
  42.416 +                                                video_res_x = hercules->crtc[1] * 16;
  42.417 +                                                video_res_y = hercules->crtc[6] * 4;
  42.418                                                  video_bpp = 1;
  42.419                                          }
  42.420                                          else
  42.421                                          {
  42.422 -                                                video_res_x = crtcm[1];
  42.423 -                                                video_res_y = crtcm[6];
  42.424 +                                                video_res_x = hercules->crtc[1];
  42.425 +                                                video_res_y = hercules->crtc[6];
  42.426                                                  video_bpp = 0;
  42.427                                          }
  42.428                                  }
  42.429 -                                firstline=1000;
  42.430 -                                lastline=0;
  42.431 -                                cgablink++;
  42.432 +                                hercules->firstline = 1000;
  42.433 +                                hercules->lastline = 0;
  42.434 +                                hercules->blink++;
  42.435                          }
  42.436                  }
  42.437                  else
  42.438                  {
  42.439 -                        sc++;
  42.440 -                        sc&=31;
  42.441 -                        ma=maback;
  42.442 +                        hercules->sc++;
  42.443 +                        hercules->sc &= 31;
  42.444 +                        hercules->ma = hercules->maback;
  42.445                  }
  42.446 -                if ((sc==(crtcm[10]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[10]&31)>>1))))
  42.447 +                if ((hercules->sc == (hercules->crtc[10] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[10] & 31) >> 1))))
  42.448                  {
  42.449 -                        con=1;
  42.450 +                        hercules->con = 1;
  42.451  //                        printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]);
  42.452                  }
  42.453          }
  42.454  }
  42.455  
  42.456 -int hercules_init()
  42.457 +void *hercules_init()
  42.458  {
  42.459 -        mem_sethandler(0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL,  NULL);
  42.460 -        return 0;
  42.461 +        int c;
  42.462 +        hercules_t *hercules = malloc(sizeof(hercules_t));
  42.463 +        memset(hercules, 0, sizeof(hercules_t));
  42.464 +
  42.465 +        hercules->vram = malloc(0x10000);
  42.466 +
  42.467 +        timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules);
  42.468 +        mem_sethandler(0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL,  hercules);
  42.469 +        io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules);
  42.470 +
  42.471 +        for (c = 0; c < 256; c++)
  42.472 +        {
  42.473 +                mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16;
  42.474 +                if (c & 8) mdacols[c][0][1] = 15 + 16;
  42.475 +                else       mdacols[c][0][1] =  7 + 16;
  42.476 +        }
  42.477 +        mdacols[0x70][0][1] = 16;
  42.478 +        mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15;
  42.479 +        mdacols[0xF0][0][1] = 16;
  42.480 +        mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15;
  42.481 +        mdacols[0x78][0][1] = 16 + 7;
  42.482 +        mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15;
  42.483 +        mdacols[0xF8][0][1] = 16 + 7;
  42.484 +        mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15;
  42.485 +        mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16;
  42.486 +        mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16;
  42.487 +        mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16;
  42.488 +        mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
  42.489 +
  42.490 +        return hercules;
  42.491  }
  42.492  
  42.493 -GFXCARD vid_hercules =
  42.494 +void hercules_close(void *p)
  42.495  {
  42.496 +        hercules_t *hercules = (hercules_t *)p;
  42.497 +
  42.498 +        free(hercules->vram);
  42.499 +        free(hercules);
  42.500 +}
  42.501 +
  42.502 +void hercules_speed_changed(void *p)
  42.503 +{
  42.504 +        hercules_t *hercules = (hercules_t *)p;
  42.505 +        
  42.506 +        hercules_recalctimings(hercules);
  42.507 +}
  42.508 +
  42.509 +device_t hercules_device =
  42.510 +{
  42.511 +        "Hercules",
  42.512          hercules_init,
  42.513 -        /*IO at 3Cx/3Dx*/
  42.514 -        video_out_null,
  42.515 -        video_in_null,
  42.516 -        /*IO at 3Ax/3Bx*/
  42.517 -        hercules_out,
  42.518 -        hercules_in,
  42.519 -
  42.520 -        hercules_poll,
  42.521 -        hercules_recalctimings,
  42.522 -
  42.523 -        video_write_null,
  42.524 -        hercules_write,
  42.525 -        video_write_null,
  42.526 -
  42.527 -        video_read_null,
  42.528 -        hercules_read,
  42.529 -        video_read_null
  42.530 +        hercules_close,
  42.531 +        hercules_speed_changed,
  42.532 +        NULL
  42.533  };
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/src/vid_hercules.h	Mon Jun 24 20:42:35 2013 +0100
    43.3 @@ -0,0 +1,1 @@
    43.4 +extern device_t hercules_device;
    44.1 --- a/src/vid_icd2061.c	Tue Jun 04 20:52:17 2013 +0100
    44.2 +++ b/src/vid_icd2061.c	Mon Jun 24 20:42:35 2013 +0100
    44.3 @@ -5,70 +5,62 @@
    44.4  #include "ibm.h"
    44.5  #include "vid_icd2061.h"
    44.6  
    44.7 -static int icd2061_state;
    44.8 -static int icd2061_status = 0;
    44.9 -static int icd2061_pos = 0;
   44.10 -static int icd2061_unlock = 0;
   44.11 -static uint32_t icd2061_data;
   44.12 -
   44.13 -static double icd2061_freq[4];
   44.14 -static uint32_t icd2061_ctrl;
   44.15 -
   44.16 -void icd2061_write(int val)
   44.17 +void icd2061_write(icd2061_t *icd2061, int val)
   44.18  {
   44.19          int q, p, m, i, a;
   44.20 -        if ((val & 1) && !(icd2061_state & 1))
   44.21 +        if ((val & 1) && !(icd2061->state & 1))
   44.22          {
   44.23 -                pclog("ICD2061 write %02X %i %08X %i\n", val, icd2061_unlock, icd2061_data, icd2061_pos);
   44.24 -                if (!icd2061_status)
   44.25 +                pclog("ICD2061 write %02X %i %08X %i\n", val, icd2061->unlock, icd2061->data, icd2061->pos);
   44.26 +                if (!icd2061->status)
   44.27                  {
   44.28 -                        if (val & 2) icd2061_unlock++;
   44.29 +                        if (val & 2) 
   44.30 +                                icd2061->unlock++;
   44.31                          else         
   44.32                          {
   44.33 -                                if (icd2061_unlock >= 5)
   44.34 +                                if (icd2061->unlock >= 5)
   44.35                                  {
   44.36 -                                        icd2061_status = 1;
   44.37 -                                        icd2061_pos = 0;
   44.38 +                                        icd2061->status = 1;
   44.39 +                                        icd2061->pos = 0;
   44.40                                  }
   44.41                                  else
   44.42 -                                   icd2061_unlock = 0;
   44.43 +                                   icd2061->unlock = 0;
   44.44                          }
   44.45                  }
   44.46                  else if (val & 1)
   44.47                  {
   44.48 -                        icd2061_data = (icd2061_data >> 1) | (((val & 2) ? 1 : 0) << 24);
   44.49 -                        icd2061_pos++;
   44.50 -                        if (icd2061_pos == 26)
   44.51 +                        icd2061->data = (icd2061->data >> 1) | (((val & 2) ? 1 : 0) << 24);
   44.52 +                        icd2061->pos++;
   44.53 +                        if (icd2061->pos == 26)
   44.54                          {
   44.55 -                                pclog("ICD2061 data - %08X\n", icd2061_data);
   44.56 -                                a = (icd2061_data >> 21) & 0x7;                                
   44.57 +                                pclog("ICD2061 data - %08X\n", icd2061->data);
   44.58 +                                a = (icd2061->data >> 21) & 0x7;
   44.59                                  if (!(a & 4))
   44.60                                  {
   44.61 -                                        q = (icd2061_data & 0x7f) - 2;
   44.62 -                                        m = 1 << ((icd2061_data >> 7) & 0x7);
   44.63 -                                        p = ((icd2061_data >> 10) & 0x7f) - 3;
   44.64 -                                        i = (icd2061_data >> 17) & 0xf;
   44.65 +                                        q = (icd2061->data & 0x7f) - 2;
   44.66 +                                        m = 1 << ((icd2061->data >> 7) & 0x7);
   44.67 +                                        p = ((icd2061->data >> 10) & 0x7f) - 3;
   44.68 +                                        i = (icd2061->data >> 17) & 0xf;
   44.69                                          pclog("p %i q %i m %i\n", p, q, m);
   44.70 -                                        if (icd2061_ctrl & (1 << a))
   44.71 +                                        if (icd2061->ctrl & (1 << a))
   44.72                                             p <<= 1;
   44.73 -                                        icd2061_freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m;
   44.74 -                                        pclog("ICD2061 freq %i = %f\n", a, icd2061_freq[a]);
   44.75 +                                        icd2061->freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m;
   44.76 +                                        pclog("ICD2061 freq %i = %f\n", a, icd2061->freq[a]);
   44.77                                  }
   44.78                                  else if (a == 6)
   44.79                                  {
   44.80 -                                        icd2061_ctrl = val;
   44.81 +                                        icd2061->ctrl = val;
   44.82                                          pclog("ICD2061 ctrl = %08X\n", val);
   44.83                                  }
   44.84 -                                icd2061_unlock = icd2061_data = 0;
   44.85 -                                icd2061_status = 0;
   44.86 +                                icd2061->unlock = icd2061->data = 0;
   44.87 +                                icd2061->status = 0;
   44.88                          }
   44.89                  }
   44.90          }
   44.91 -        icd2061_state = val;
   44.92 +        icd2061->state = val;
   44.93  }
   44.94  
   44.95 -double icd2061_getfreq(int i)
   44.96 +double icd2061_getfreq(icd2061_t *icd2061, int i)
   44.97  {
   44.98 -        pclog("Return freq %f\n", icd2061_freq[i]);
   44.99 -        return icd2061_freq[i];
  44.100 +        pclog("Return freq %f\n", icd2061->freq[i]);
  44.101 +        return icd2061->freq[i];
  44.102  }
    45.1 --- a/src/vid_icd2061.h	Tue Jun 04 20:52:17 2013 +0100
    45.2 +++ b/src/vid_icd2061.h	Mon Jun 24 20:42:35 2013 +0100
    45.3 @@ -1,2 +1,14 @@
    45.4 -void icd2061_write(int val);
    45.5 -double icd2061_getfreq(int i);
    45.6 +typedef struct icd2061_t
    45.7 +{
    45.8 +        int state;
    45.9 +        int status;
   45.10 +        int pos;
   45.11 +        int unlock;
   45.12 +        uint32_t data;
   45.13 +
   45.14 +        double freq[4];
   45.15 +        uint32_t ctrl;
   45.16 +} icd2061_t;
   45.17 +
   45.18 +void icd2061_write(icd2061_t *icd2061, int val);
   45.19 +double icd2061_getfreq(icd2061_t *icd2061, int i);
    46.1 --- a/src/vid_ics2595.c	Tue Jun 04 20:52:17 2013 +0100
    46.2 +++ b/src/vid_ics2595.c	Mon Jun 24 20:42:35 2013 +0100
    46.3 @@ -6,58 +6,50 @@
    46.4  
    46.5  enum
    46.6  {
    46.7 -        ICS2595_IDLE,
    46.8 +        ICS2595_IDLE = 0,
    46.9          ICS2595_WRITE,
   46.10          ICS2595_READ
   46.11  };
   46.12  
   46.13 -static int ics2595_oldfs3, ics2595_oldfs2;
   46.14 -static int ics2595_dat;
   46.15 -static int ics2595_pos;
   46.16 -static int ics2595_state = ICS2595_IDLE;
   46.17 -
   46.18  static int ics2595_div[4] = {8, 4, 2, 1};
   46.19  
   46.20 -static double ics2595_clocks[16];
   46.21 -double ics2595_output_clock;
   46.22 -
   46.23 -void ics2595_write(int strobe, int dat)
   46.24 +void ics2595_write(ics2595_t *ics2595, int strobe, int dat)
   46.25  {
   46.26          pclog("ics2595_write : %i %i\n", strobe, dat);
   46.27          if (strobe)
   46.28          {
   46.29 -                if ((dat & 8) && !ics2595_oldfs3) /*Data clock*/
   46.30 +                if ((dat & 8) && !ics2595->oldfs3) /*Data clock*/
   46.31                  {
   46.32                          pclog(" - new dat %i\n", dat & 4);
   46.33 -                        switch (ics2595_state)
   46.34 +                        switch (ics2595->state)
   46.35                          {
   46.36                                  case ICS2595_IDLE:
   46.37 -                                ics2595_state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE;
   46.38 -                                ics2595_pos = 0;
   46.39 +                                ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE;
   46.40 +                                ics2595->pos = 0;
   46.41                                  break;
   46.42                                  case ICS2595_WRITE:
   46.43 -                                ics2595_dat = (ics2595_dat >> 1);
   46.44 +                                ics2595->dat = (ics2595->dat >> 1);
   46.45                                  if (dat & 4)
   46.46 -                                        ics2595_dat |= (1 << 19);
   46.47 -                                ics2595_pos++;
   46.48 -                                if (ics2595_pos == 20)
   46.49 +                                        ics2595->dat |= (1 << 19);
   46.50 +                                ics2595->pos++;
   46.51 +                                if (ics2595->pos == 20)
   46.52                                  {
   46.53                                          int d, n, l;
   46.54 -                                        pclog("ICS2595_WRITE : dat %08X\n", ics2595_dat);
   46.55 -                                        l = (ics2595_dat >> 2) & 31;
   46.56 -                                        n = ((ics2595_dat >> 7) & 255) + 257;
   46.57 -                                        d = ics2595_div[(ics2595_dat >> 16) & 3];
   46.58 +                                        pclog("ICS2595_WRITE : dat %08X\n", ics2595->dat);
   46.59 +                                        l = (ics2595->dat >> 2) & 0xf;
   46.60 +                                        n = ((ics2595->dat >> 7) & 255) + 257;
   46.61 +                                        d = ics2595_div[(ics2595->dat >> 16) & 3];
   46.62  
   46.63 -                                        ics2595_clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d;
   46.64 +                                        ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d;
   46.65                                          pclog("ICS2595 clock set - L %i N %i D %i freq = %f\n", l, n, d, (14318181.8 * ((double)n / 46.0)) / (double)d);
   46.66 -                                        ics2595_state = ICS2595_IDLE;
   46.67 +                                        ics2595->state = ICS2595_IDLE;
   46.68                                  }
   46.69                                  break;                                                
   46.70                          }
   46.71                  }
   46.72                          
   46.73 -                ics2595_oldfs2 = dat & 4;
   46.74 -                ics2595_oldfs3 = dat & 8;
   46.75 +                ics2595->oldfs2 = dat & 4;
   46.76 +                ics2595->oldfs3 = dat & 8;
   46.77          }
   46.78 -        ics2595_output_clock = ics2595_clocks[dat];
   46.79 +        ics2595->output_clock = ics2595->clocks[dat];
   46.80  }
    47.1 --- a/src/vid_ics2595.h	Tue Jun 04 20:52:17 2013 +0100
    47.2 +++ b/src/vid_ics2595.h	Mon Jun 24 20:42:35 2013 +0100
    47.3 @@ -1,2 +1,12 @@
    47.4 -void ics2595_write(int strobe, int dat);
    47.5 -extern double ics2595_output_clock;
    47.6 +typedef struct ics2595_t
    47.7 +{
    47.8 +        int oldfs3, oldfs2;
    47.9 +        int dat;
   47.10 +        int pos;
   47.11 +        int state;
   47.12 +
   47.13 +        double clocks[16];
   47.14 +        double output_clock;
   47.15 +} ics2595_t;
   47.16 +
   47.17 +void ics2595_write(ics2595_t *ics2595, int strobe, int dat);
    48.1 --- a/src/vid_mda.c	Tue Jun 04 20:52:17 2013 +0100
    48.2 +++ b/src/vid_mda.c	Mon Jun 24 20:42:35 2013 +0100
    48.3 @@ -1,259 +1,316 @@
    48.4  /*MDA emulation*/
    48.5 +#include <stdlib.h>
    48.6  #include "ibm.h"
    48.7 +#include "device.h"
    48.8  #include "io.h"
    48.9  #include "mem.h"
   48.10  #include "timer.h"
   48.11  #include "video.h"
   48.12 +#include "vid_mda.h"
   48.13  
   48.14 -void mda_recalctimings();
   48.15 +typedef struct mda_t
   48.16 +{
   48.17 +        uint8_t crtc[32];
   48.18 +        int crtcreg;
   48.19 +        
   48.20 +        uint8_t ctrl, stat;
   48.21 +        
   48.22 +        int dispontime, dispofftime;
   48.23 +        int vidtime;
   48.24 +        
   48.25 +        int firstline, lastline;
   48.26  
   48.27 -static uint8_t mda_ctrl,mda_stat;
   48.28 -uint8_t crtcm[32],crtcmreg;
   48.29 +        int linepos, displine;
   48.30 +        int vc, sc;
   48.31 +        uint16_t ma, maback;
   48.32 +        int con, coff, cursoron;
   48.33 +        int dispon, blink;
   48.34 +        int vsynctime, vadj;
   48.35  
   48.36 -void mda_out(uint16_t addr, uint8_t val, void *priv)
   48.37 +        uint8_t *vram;
   48.38 +} mda_t;
   48.39 +
   48.40 +static int mdacols[256][2][2];
   48.41 +
   48.42 +void mda_recalctimings(mda_t *mda);
   48.43 +
   48.44 +void mda_out(uint16_t addr, uint8_t val, void *p)
   48.45  {
   48.46 +        mda_t *mda = (mda_t *)p;
   48.47          switch (addr)
   48.48          {
   48.49 -                case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
   48.50 -                crtcmreg = val & 31;
   48.51 +                case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
   48.52 +                mda->crtcreg = val & 31;
   48.53                  return;
   48.54 -                case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
   48.55 -                crtcm[crtcmreg] = val;
   48.56 -                if (crtcm[10]==6 && crtcm[11]==7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
   48.57 +                case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
   48.58 +                mda->crtc[mda->crtcreg] = val;
   48.59 +                if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
   48.60                  {
   48.61 -                        crtcm[10]=0xB;
   48.62 -                        crtcm[11]=0xC;
   48.63 +                        mda->crtc[10] = 0xb;
   48.64 +                        mda->crtc[11] = 0xc;
   48.65                  }
   48.66 -                mda_recalctimings();
   48.67 +                mda_recalctimings(mda);
   48.68                  return;
   48.69 -                case 0x3B8:
   48.70 -                mda_ctrl = val;
   48.71 +                case 0x3b8:
   48.72 +                mda->ctrl = val;
   48.73                  return;
   48.74          }
   48.75  }
   48.76  
   48.77 -uint8_t mda_in(uint16_t addr, void *priv)
   48.78 +uint8_t mda_in(uint16_t addr, void *p)
   48.79  {
   48.80 +        mda_t *mda = (mda_t *)p;
   48.81          switch (addr)
   48.82          {
   48.83 -                case 0x3B0: case 0x3B2: case 0x3B4: case 0x3B6:
   48.84 -                return crtcmreg;
   48.85 -                case 0x3B1: case 0x3B3: case 0x3B5: case 0x3B7:
   48.86 -                return crtcm[crtcmreg];
   48.87 -                case 0x3BA:
   48.88 -                return mda_stat | 0xF0;
   48.89 +                case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
   48.90 +                return mda->crtcreg;
   48.91 +                case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
   48.92 +                return mda->crtc[mda->crtcreg];
   48.93 +                case 0x3ba:
   48.94 +                return mda->stat | 0xF0;
   48.95          }
   48.96          return 0xff;
   48.97  }
   48.98  
   48.99 -void mda_write(uint32_t addr, uint8_t val, void *priv)
  48.100 +void mda_write(uint32_t addr, uint8_t val, void *p)
  48.101  {
  48.102 -        vram[addr&0xFFF]=val;
  48.103 +        mda_t *mda = (mda_t *)p;
  48.104 +        mda->vram[addr & 0xfff] = val;
  48.105  }
  48.106  
  48.107 -uint8_t mda_read(uint32_t addr, void *priv)
  48.108 +uint8_t mda_read(uint32_t addr, void *p)
  48.109  {
  48.110 -        return vram[addr&0xFFF];
  48.111 +        mda_t *mda = (mda_t *)p;
  48.112 +        return mda->vram[addr & 0xfff];
  48.113  }
  48.114  
  48.115 -void mda_recalctimings()
  48.116 +void mda_recalctimings(mda_t *mda)
  48.117  {
  48.118 -	double _dispontime, _dispofftime;
  48.119 -        disptime=crtc[0]+1;
  48.120 -        _dispontime=crtc[1];
  48.121 -        _dispofftime=disptime-_dispontime;
  48.122 -        _dispontime*=MDACONST;
  48.123 -        _dispofftime*=MDACONST;
  48.124 -	dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  48.125 -	dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  48.126 +	double _dispontime, _dispofftime, disptime;
  48.127 +        disptime = mda->crtc[0] + 1;
  48.128 +        _dispontime = mda->crtc[1];
  48.129 +        _dispofftime = disptime - _dispontime;
  48.130 +        _dispontime *= MDACONST;
  48.131 +        _dispofftime *= MDACONST;
  48.132 +	mda->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  48.133 +	mda->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  48.134  }
  48.135  
  48.136 -int mdacols[256][2][2];
  48.137 -
  48.138 -static int linepos,displine;
  48.139 -static int vc,sc;
  48.140 -static uint16_t ma,maback;
  48.141 -static int con,coff,cursoron;
  48.142 -static int cgadispon,cgablink;
  48.143 -static int vsynctime,vadj;
  48.144 -
  48.145 -void mda_poll()
  48.146 +void mda_poll(void *p)
  48.147  {
  48.148 -        uint16_t ca=(crtcm[15]|(crtcm[14]<<8))&0x3FFF;
  48.149 +        mda_t *mda = (mda_t *)p;
  48.150 +        uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff;
  48.151          int drawcursor;
  48.152 -        int x,c;
  48.153 +        int x, c;
  48.154          int oldvc;
  48.155 -        uint8_t chr,attr;
  48.156 +        uint8_t chr, attr;
  48.157          int cols[4];
  48.158          int oldsc;
  48.159          int blink;
  48.160 -        if (!linepos)
  48.161 +        if (!mda->linepos)
  48.162          {
  48.163 -                vidtime+=dispofftime;
  48.164 -                mda_stat|=1;
  48.165 -                linepos=1;
  48.166 -                oldsc=sc;
  48.167 -                if ((crtcm[8]&3)==3) sc=(sc<<1)&7;
  48.168 -                if (cgadispon)
  48.169 +                mda->vidtime += mda->dispofftime;
  48.170 +                mda->stat |= 1;
  48.171 +                mda->linepos = 1;
  48.172 +                oldsc = mda->sc;
  48.173 +                if ((mda->crtc[8] & 3) == 3) 
  48.174 +                        mda->sc = (mda->sc << 1) & 7;
  48.175 +                if (mda->dispon)
  48.176                  {
  48.177 -                        if (displine<firstline)
  48.178 +                        if (mda->displine < mda->firstline)
  48.179                          {
  48.180 -                                firstline=displine;
  48.181 +                                mda->firstline = mda->displine;
  48.182                          }
  48.183 -                        lastline=displine;
  48.184 -                        cols[0]=0;
  48.185 -                        cols[1]=7;
  48.186 -                        for (x=0;x<crtcm[1];x++)
  48.187 +                        mda->lastline = mda->displine;
  48.188 +                        cols[0] = 0;
  48.189 +                        cols[1] = 7;
  48.190 +                        for (x = 0; x < mda->crtc[1]; x++)
  48.191                          {
  48.192 -                                chr=vram[(ma<<1)&0x3FFF];
  48.193 -                                attr=vram[((ma<<1)+1)&0x3FFF];
  48.194 -                                drawcursor=((ma==ca) && con && cursoron);
  48.195 -                                blink=((cgablink&16) && (mda_ctrl&0x20) && (attr&0x80) && !drawcursor);
  48.196 -                                if (sc==12 && ((attr&7)==1))
  48.197 +                                chr  = mda->vram[(mda->ma << 1) & 0x3fff];
  48.198 +                                attr = mda->vram[((mda->ma << 1) + 1) & 0x3fff];
  48.199 +                                drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron);
  48.200 +                                blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
  48.201 +                                if (mda->sc == 12 && ((attr & 7) == 1))
  48.202                                  {
  48.203 -                                        for (c=0;c<9;c++)
  48.204 -                                            buffer->line[displine][(x*9)+c]=mdacols[attr][blink][1];
  48.205 +                                        for (c = 0; c < 9; c++)
  48.206 +                                            buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1];
  48.207                                  }
  48.208                                  else
  48.209                                  {
  48.210 -                                        for (c=0;c<8;c++)
  48.211 -                                            buffer->line[displine][(x*9)+c]=mdacols[attr][blink][(fontdatm[chr][sc]&(1<<(c^7)))?1:0];
  48.212 -                                        if ((chr&~0x1F)==0xC0) buffer->line[displine][(x*9)+8]=mdacols[attr][blink][fontdatm[chr][sc]&1];
  48.213 -                                        else                   buffer->line[displine][(x*9)+8]=mdacols[attr][blink][0];
  48.214 +                                        for (c = 0; c < 8; c++)
  48.215 +                                            buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0];
  48.216 +                                        if ((chr & ~0x1f) == 0xc0) buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1];
  48.217 +                                        else                       buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0];
  48.218                                  }
  48.219 -                                ma++;
  48.220 +                                mda->ma++;
  48.221                                  if (drawcursor)
  48.222                                  {
  48.223 -                                        for (c=0;c<9;c++)
  48.224 -                                            buffer->line[displine][(x*9)+c]^=mdacols[attr][0][1];
  48.225 +                                        for (c = 0; c < 9; c++)
  48.226 +                                            buffer->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1];
  48.227                                  }
  48.228                          }
  48.229                  }
  48.230 -                sc=oldsc;
  48.231 -                if (vc==crtcm[7] && !sc)
  48.232 +                mda->sc = oldsc;
  48.233 +                if (mda->vc == mda->crtc[7] && !mda->sc)
  48.234                  {
  48.235 -                        mda_stat|=8;
  48.236 +                        mda->stat |= 8;
  48.237  //                        printf("VSYNC on %i %i\n",vc,sc);
  48.238                  }
  48.239 -                displine++;
  48.240 -                if (displine>=500) displine=0;
  48.241 +                mda->displine++;
  48.242 +                if (mda->displine >= 500) 
  48.243 +                        mda->displine=0;
  48.244          }
  48.245          else
  48.246          {
  48.247 -                vidtime+=dispontime;
  48.248 -                if (cgadispon) mda_stat&=~1;
  48.249 -                linepos=0;
  48.250 -                if (vsynctime)
  48.251 +                mda->vidtime += mda->dispontime;
  48.252 +                if (mda->dispon) mda->stat&=~1;
  48.253 +                mda->linepos=0;
  48.254 +                if (mda->vsynctime)
  48.255                  {
  48.256 -                        vsynctime--;
  48.257 -                        if (!vsynctime)
  48.258 +                        mda->vsynctime--;
  48.259 +                        if (!mda->vsynctime)
  48.260                          {
  48.261 -                                mda_stat&=~8;
  48.262 +                                mda->stat&=~8;
  48.263  //                                printf("VSYNC off %i %i\n",vc,sc);
  48.264                          }
  48.265                  }
  48.266 -                if (sc==(crtcm[11]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[11]&31)>>1))) { con=0; coff=1; }
  48.267 -                if (vadj)
  48.268 +                if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) 
  48.269 +                { 
  48.270 +                        mda->con = 0; 
  48.271 +                        mda->coff = 1; 
  48.272 +                }
  48.273 +                if (mda->vadj)
  48.274                  {
  48.275 -                        sc++;
  48.276 -                        sc&=31;
  48.277 -                        ma=maback;
  48.278 -                        vadj--;
  48.279 -                        if (!vadj)
  48.280 +                        mda->sc++;
  48.281 +                        mda->sc &= 31;
  48.282 +                        mda->ma = mda->maback;
  48.283 +                        mda->vadj--;
  48.284 +                        if (!mda->vadj)
  48.285                          {
  48.286 -                                cgadispon=1;
  48.287 -                                ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
  48.288 -                                sc=0;
  48.289 +                                mda->dispon = 1;
  48.290 +                                mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
  48.291 +                                mda->sc = 0;
  48.292                          }
  48.293                  }
  48.294 -                else if (sc==crtcm[9] || ((crtcm[8]&3)==3 && sc==(crtcm[9]>>1)))
  48.295 +                else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1)))
  48.296                  {
  48.297 -                        maback=ma;
  48.298 -                        sc=0;
  48.299 -                        oldvc=vc;
  48.300 -                        vc++;
  48.301 -                        vc&=127;
  48.302 -                        if (vc==crtcm[6]) cgadispon=0;
  48.303 -                        if (oldvc==crtcm[4])
  48.304 +                        mda->maback = mda->ma;
  48.305 +                        mda->sc = 0;
  48.306 +                        oldvc = mda->vc;
  48.307 +                        mda->vc++;
  48.308 +                        mda->vc &= 127;
  48.309 +                        if (mda->vc == mda->crtc[6]) 
  48.310 +                                mda->dispon=0;
  48.311 +                        if (oldvc == mda->crtc[4])
  48.312                          {
  48.313  //                                printf("Display over at %i\n",displine);
  48.314 -                                vc=0;
  48.315 -                                vadj=crtcm[5];
  48.316 -                                if (!vadj) cgadispon=1;
  48.317 -                                if (!vadj) ma=maback=(crtcm[13]|(crtcm[12]<<8))&0x3FFF;
  48.318 -                                if ((crtcm[10]&0x60)==0x20) cursoron=0;
  48.319 -                                else                        cursoron=cgablink&16;
  48.320 +                                mda->vc = 0;
  48.321 +                                mda->vadj = mda->crtc[5];
  48.322 +                                if (!mda->vadj) mda->dispon = 1;
  48.323 +                                if (!mda->vadj) mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
  48.324 +                                if ((mda->crtc[10] & 0x60) == 0x20) mda->cursoron = 0;
  48.325 +                                else                                mda->cursoron = mda->blink & 16;
  48.326                          }
  48.327 -                        if (vc==crtcm[7])
  48.328 +                        if (mda->vc == mda->crtc[7])
  48.329                          {
  48.330 -                                cgadispon=0;
  48.331 -                                displine=0;
  48.332 -                                vsynctime=16;//(crtcm[3]>>4)+1;
  48.333 -                                if (crtcm[7])
  48.334 +                                mda->dispon = 0;
  48.335 +                                mda->displine = 0;
  48.336 +                                mda->vsynctime = 16;
  48.337 +                                if (mda->crtc[7])
  48.338                                  {
  48.339  //                                        printf("Lastline %i Firstline %i  %i\n",lastline,firstline,lastline-firstline);
  48.340 -                                        x=crtcm[1]*9;
  48.341 -                                        lastline++;
  48.342 -                                        if (x!=xsize || (lastline-firstline)!=ysize)
  48.343 +                                        x = mda->crtc[1] * 9;
  48.344 +                                        mda->lastline++;
  48.345 +                                        if (x != xsize || (mda->lastline - mda->firstline) != ysize)
  48.346                                          {
  48.347 -                                                xsize=x;
  48.348 -                                                ysize=lastline-firstline;
  48.349 +                                                xsize = x;
  48.350 +                                                ysize = mda->lastline - mda->firstline;
  48.351  //                                                printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]);
  48.352 -                                                if (xsize<64) xsize=656;
  48.353 -                                                if (ysize<32) ysize=200;
  48.354 -                                                updatewindowsize(xsize,ysize);
  48.355 +                                                if (xsize < 64) xsize = 656;
  48.356 +                                                if (ysize < 32) ysize = 200;
  48.357 +                                                updatewindowsize(xsize, ysize);
  48.358                                          }
  48.359                                  startblit();
  48.360 -                                        video_blit_memtoscreen_8(0, firstline, xsize, lastline - firstline);
  48.361 +                                        video_blit_memtoscreen_8(0, mda->firstline, xsize, mda->lastline - mda->firstline);
  48.362                                  endblit();
  48.363                                          frames++;
  48.364 -                                        video_res_x = crtcm[1];
  48.365 -                                        video_res_y = crtcm[6];
  48.366 +                                        video_res_x = mda->crtc[1];
  48.367 +                                        video_res_y = mda->crtc[6];
  48.368                                          video_bpp = 0;
  48.369                                  }
  48.370 -                                firstline=1000;
  48.371 -                                lastline=0;
  48.372 -                                cgablink++;
  48.373 +                                mda->firstline = 1000;
  48.374 +                                mda->lastline = 0;
  48.375 +                                mda->blink++;
  48.376                          }
  48.377                  }
  48.378                  else
  48.379                  {
  48.380 -                        sc++;
  48.381 -                        sc&=31;
  48.382 -                        ma=maback;
  48.383 +                        mda->sc++;
  48.384 +                        mda->sc &= 31;
  48.385 +                        mda->ma = mda->maback;
  48.386                  }
  48.387 -                if ((sc==(crtcm[10]&31) || ((crtcm[8]&3)==3 && sc==((crtcm[10]&31)>>1))))
  48.388 +                if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1))))
  48.389                  {
  48.390 -                        con=1;
  48.391 +                        mda->con = 1;
  48.392  //                        printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]);
  48.393                  }
  48.394          }
  48.395  }
  48.396  
  48.397 -int mda_init()
  48.398 +void *mda_init()
  48.399  {
  48.400 -        mem_sethandler(0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL,  NULL);
  48.401 -        return 0;
  48.402 +        int c;
  48.403 +        mda_t *mda = malloc(sizeof(mda_t));
  48.404 +        memset(mda, 0, sizeof(mda_t));
  48.405 +
  48.406 +        mda->vram = malloc(0x1000);
  48.407 +
  48.408 +        timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda);
  48.409 +        mem_sethandler(0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL,  mda);
  48.410 +        io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda);
  48.411 +
  48.412 +        for (c = 0; c < 256; c++)
  48.413 +        {
  48.414 +                mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16;
  48.415 +                if (c & 8) mdacols[c][0][1] = 15 + 16;
  48.416 +                else       mdacols[c][0][1] =  7 + 16;
  48.417 +        }
  48.418 +        mdacols[0x70][0][1] = 16;
  48.419 +        mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15;
  48.420 +        mdacols[0xF0][0][1] = 16;
  48.421 +        mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15;
  48.422 +        mdacols[0x78][0][1] = 16 + 7;
  48.423 +        mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15;
  48.424 +        mdacols[0xF8][0][1] = 16 + 7;
  48.425 +        mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15;
  48.426 +        mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16;
  48.427 +        mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16;
  48.428 +        mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16;
  48.429 +        mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
  48.430 +
  48.431 +        return mda;
  48.432  }
  48.433  
  48.434 -GFXCARD vid_mda =
  48.435 +void mda_close(void *p)
  48.436  {
  48.437 +        mda_t *mda = (mda_t *)p;
  48.438 +
  48.439 +        free(mda->vram);
  48.440 +        free(mda);
  48.441 +}
  48.442 +
  48.443 +void mda_speed_changed(void *p)
  48.444 +{
  48.445 +        mda_t *mda = (mda_t *)p;
  48.446 +        
  48.447 +        mda_recalctimings(mda);
  48.448 +}
  48.449 +
  48.450 +device_t mda_device =
  48.451 +{
  48.452 +        "MDA",
  48.453          mda_init,
  48.454 -        /*IO at 3Cx/3Dx*/
  48.455 -        video_out_null,
  48.456 -        video_in_null,
  48.457 -        /*IO at 3Ax/3Bx*/
  48.458 -        mda_out,
  48.459 -        mda_in,
  48.460 -
  48.461 -        mda_poll,
  48.462 -        mda_recalctimings,
  48.463 -
  48.464 -        video_write_null,
  48.465 -        mda_write,
  48.466 -        video_write_null,
  48.467 -
  48.468 -        video_read_null,
  48.469 -        mda_read,
  48.470 -        video_read_null
  48.471 +        mda_close,
  48.472 +        mda_speed_changed,
  48.473 +        NULL
  48.474  };
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/src/vid_mda.h	Mon Jun 24 20:42:35 2013 +0100
    49.3 @@ -0,0 +1,1 @@
    49.4 +extern device_t mda_device;
    50.1 --- a/src/vid_olivetti_m24.c	Tue Jun 04 20:52:17 2013 +0100
    50.2 +++ b/src/vid_olivetti_m24.c	Mon Jun 24 20:42:35 2013 +0100
    50.3 @@ -1,436 +1,487 @@
    50.4  /*Olivetti M24 video emulation
    50.5    Essentially double-res CGA*/
    50.6 +#include <stdlib.h>
    50.7  #include "ibm.h"
    50.8 +#include "device.h"
    50.9  #include "io.h"
   50.10  #include "mem.h"
   50.11  #include "timer.h"
   50.12  #include "video.h"
   50.13 +#include "vid_olivetti_m24.h"
   50.14  
   50.15 -void m24_recalctimings();
   50.16 +typedef struct m24_t
   50.17 +{
   50.18 +        uint8_t crtc[32];
   50.19 +        int crtcreg;
   50.20 +        
   50.21 +        uint8_t *vram;
   50.22 +        uint8_t charbuffer[256];
   50.23 +        
   50.24 +        uint8_t  ctrl;
   50.25 +        uint32_t base;
   50.26 +        
   50.27 +        uint8_t cgamode, cgacol;
   50.28 +        uint8_t stat;
   50.29 +        
   50.30 +        int linepos, displine;
   50.31 +        int sc, vc;
   50.32 +        int con, coff, cursoron, blink;
   50.33 +        int vsynctime, vadj;
   50.34 +        int lineff;
   50.35 +        uint16_t ma, maback;
   50.36 +        int dispon;
   50.37 +        
   50.38 +        int dispontime, dispofftime, vidtime;
   50.39 +        
   50.40 +        int firstline, lastline;
   50.41 +} m24_t;
   50.42  
   50.43 -static uint8_t  m24_ctrl;
   50.44 -static uint32_t m24_base;
   50.45 +static uint8_t crtcmask[32] = 
   50.46 +{
   50.47 +        0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
   50.48 +        0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   50.49 +};
   50.50  
   50.51 -void m24_out(uint16_t addr, uint8_t val, void *priv)
   50.52 +void m24_recalctimings(m24_t *m24);
   50.53 +
   50.54 +
   50.55 +void m24_out(uint16_t addr, uint8_t val, void *p)
   50.56  {
   50.57 +        m24_t *m24 = (m24_t *)p;
   50.58          uint8_t old;
   50.59 +        pclog("m24_out %04X %02X\n", addr, val);
   50.60          switch (addr)
   50.61          {
   50.62 -                case 0x3D4:
   50.63 -                crtcreg = val & 31;
   50.64 +                case 0x3d4:
   50.65 +                m24->crtcreg = val & 31;
   50.66                  return;
   50.67 -                case 0x3D5:
   50.68 -                old = crtc[crtcreg];
   50.69 -                crtc[crtcreg] = val & crtcmask[crtcreg];
   50.70 +                case 0x3d5:
   50.71 +                old = m24->crtc[m24->crtcreg];
   50.72 +                m24->crtc[m24->crtcreg] = val & crtcmask[m24->crtcreg];
   50.73                  if (old != val)
   50.74                  {
   50.75 -                        if (crtcreg < 0xE || crtcreg > 0x10)
   50.76 +                        if (m24->crtcreg < 0xe || m24->crtcreg > 0x10)
   50.77                          {
   50.78                                  fullchange = changeframecount;
   50.79 -                                m24_recalctimings();
   50.80 +                                m24_recalctimings(m24);
   50.81                          }
   50.82                  }
   50.83                  return;
   50.84 -                case 0x3D8:
   50.85 -                cgamode = val;
   50.86 +                case 0x3d8:
   50.87 +                m24->cgamode = val;
   50.88                  return;
   50.89 -                case 0x3D9:
   50.90 -                cgacol = val;
   50.91 +                case 0x3d9:
   50.92 +                m24->cgacol = val;
   50.93                  return;
   50.94                  case 0x3de:
   50.95 -                m24_ctrl = val;
   50.96 -                m24_base = (val & 0x08) ? 0x4000 : 0;
   50.97 +                m24->ctrl = val;
   50.98 +                m24->base = (val & 0x08) ? 0x4000 : 0;
   50.99                  return;
  50.100          }
  50.101  }
  50.102  
  50.103 -uint8_t m24_in(uint16_t addr, void *priv)
  50.104 +uint8_t m24_in(uint16_t addr, void *p)
  50.105  {
  50.106 +        m24_t *m24 = (m24_t *)p;
  50.107          switch (addr)
  50.108          {
  50.109 -                case 0x3D4:
  50.110 -                return crtcreg;
  50.111 -                case 0x3D5:
  50.112 -                return crtc[crtcreg];
  50.113 -                case 0x3DA:
  50.114 -                return cgastat;
  50.115 +                case 0x3d4:
  50.116 +                return m24->crtcreg;
  50.117 +                case 0x3d5:
  50.118 +                return m24->crtc[m24->crtcreg];
  50.119 +                case 0x3da:
  50.120 +                return m24->stat;
  50.121          }
  50.122 -        return 0xFF;
  50.123 +        return 0xff;
  50.124  }
  50.125  
  50.126 -static uint8_t charbuffer[256];
  50.127 -
  50.128 -void m24_write(uint32_t addr, uint8_t val, void *priv)
  50.129 +void m24_write(uint32_t addr, uint8_t val, void *p)
  50.130  {
  50.131 -        vram[addr & 0x7FFF]=val;
  50.132 -        charbuffer[ ((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val;
  50.133 -        charbuffer[(((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val;        
  50.134 +        m24_t *m24 = (m24_t *)p;
  50.135 +        m24->vram[addr & 0x7FFF]=val;
  50.136 +        m24->charbuffer[ ((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val;
  50.137 +        m24->charbuffer[(((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val;        
  50.138  }
  50.139  
  50.140 -uint8_t m24_read(uint32_t addr, void *priv)
  50.141 +uint8_t m24_read(uint32_t addr, void *p)
  50.142  {
  50.143 -        return vram[addr & 0x7FFF];
  50.144 +        m24_t *m24 = (m24_t *)p;
  50.145 +        return m24->vram[addr & 0x7FFF];
  50.146  }
  50.147  
  50.148 -void m24_recalctimings()
  50.149 +void m24_recalctimings(m24_t *m24)
  50.150  {
  50.151 -	double _dispontime, _dispofftime;
  50.152 -        if (cgamode & 1)
  50.153 +	double _dispontime, _dispofftime, disptime;
  50.154 +        if (m24->cgamode & 1)
  50.155          {
  50.156 -                disptime   = crtc[0] + 1;
  50.157 -                _dispontime = crtc[1];
  50.158 +                disptime    = m24->crtc[0] + 1;
  50.159 +                _dispontime = m24->crtc[1];
  50.160          }
  50.161          else
  50.162          {
  50.163 -                disptime   = (crtc[0] + 1) << 1;
  50.164 -                _dispontime = crtc[1] << 1;
  50.165 +                disptime    = (m24->crtc[0] + 1) << 1;
  50.166 +                _dispontime = m24->crtc[1] << 1;
  50.167          }
  50.168          _dispofftime = disptime - _dispontime;
  50.169  //        printf("%i %f %f %f  %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
  50.170          _dispontime  *= CGACONST / 2;
  50.171          _dispofftime *= CGACONST / 2;
  50.172  //        printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
  50.173 -	dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  50.174 -	dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  50.175 +	m24->dispontime  = (int)(_dispontime  * (1 << TIMER_SHIFT));
  50.176 +	m24->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  50.177  }
  50.178  
  50.179 -static int linepos,displine;
  50.180 -static int sc,vc;
  50.181 -static int cgadispon;
  50.182 -static int con,coff,cursoron,cgablink;
  50.183 -static int vsynctime,vadj;
  50.184 -static int m24_lineff = 0;
  50.185 -static uint16_t ma,maback;
  50.186 -
  50.187 -void m24_poll()
  50.188 +void m24_poll(void *p)
  50.189  {
  50.190 -        uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF;
  50.191 +        m24_t *m24 = (m24_t *)p;
  50.192 +        uint16_t ca = (m24->crtc[15] | (m24->crtc[14] << 8)) & 0x3fff;
  50.193          int drawcursor;
  50.194 -        int x,c;
  50.195 +        int x, c;
  50.196          int oldvc;
  50.197 -        uint8_t chr,attr;
  50.198 -        uint16_t dat,dat2;
  50.199 +        uint8_t chr, attr;
  50.200 +        uint16_t dat, dat2;
  50.201          int cols[4];
  50.202          int col;
  50.203          int oldsc;
  50.204 -        if (!linepos)
  50.205 +        if (!m24->linepos)
  50.206          {
  50.207  //                pclog("Line poll  %i %i %i %i - %04X %i %i %i\n", m24_lineff, vc, sc, vadj, ma, firstline, lastline, displine);
  50.208 -                vidtime+=dispofftime;
  50.209 -                cgastat|=1;
  50.210 -                linepos=1;
  50.211 -                oldsc=sc;
  50.212 -                if ((crtc[8]&3)==3) sc=(sc<<1)&7;
  50.213 -                if (cgadispon)
  50.214 +                m24->vidtime += m24->dispofftime;
  50.215 +                m24->stat |= 1;
  50.216 +                m24->linepos = 1;
  50.217 +                oldsc = m24->sc;
  50.218 +                if ((m24->crtc[8] & 3) == 3) 
  50.219 +                        m24->sc = (m24->sc << 1) & 7;
  50.220 +                if (m24->dispon)
  50.221                  {
  50.222 -                        if (displine<firstline)
  50.223 +                        pclog("dispon %i\n", m24->linepos);
  50.224 +                        if (m24->displine < m24->firstline)
  50.225                          {
  50.226 -                                firstline=displine;
  50.227 +                                m24->firstline = m24->displine;
  50.228  //                                printf("Firstline %i\n",firstline);
  50.229                          }
  50.230 -                        lastline=displine;
  50.231 -                        for (c=0;c<8;c++)
  50.232 +                        m24->lastline = m24->displine;
  50.233 +                        for (c = 0; c < 8; c++)
  50.234                          {
  50.235 -                                if ((cgamode&0x12)==0x12)
  50.236 +                                if ((m24->cgamode & 0x12) == 0x12)
  50.237                                  {
  50.238 -                                        buffer->line[displine][c]=0;
  50.239 -                                        if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
  50.240 -                                        else           buffer->line[displine][c+(crtc[1]<<4)+8]=0;
  50.241 +                                        buffer->line[m24->displine][c] = 0;
  50.242 +                                        if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = 0;
  50.243 +                                        else                  buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = 0;
  50.244                                  }
  50.245                                  else
  50.246                                  {
  50.247 -                                        buffer->line[displine][c]=(cgacol&15)+16;
  50.248 -                                        if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16;
  50.249 -                                        else           buffer->line[displine][c+(crtc[1]<<4)+8]=(cgacol&15)+16;
  50.250 +                                        buffer->line[m24->displine][c] = (m24->cgacol & 15) + 16;
  50.251 +                                        if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = (m24->cgacol & 15) + 16;
  50.252 +                                        else                  buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = (m24->cgacol & 15) + 16;
  50.253                                  }
  50.254                          }
  50.255 -                        if (cgamode&1)
  50.256 +                        if (m24->cgamode & 1)
  50.257                          {
  50.258 -                                for (x=0;x<crtc[1];x++)
  50.259 +                                for (x = 0; x < m24->crtc[1]; x++)
  50.260                                  {
  50.261 -                                        chr  = charbuffer[ x << 1];
  50.262 -                                        attr = charbuffer[(x << 1) + 1];
  50.263 -                                        drawcursor=((ma==ca) && con && cursoron);
  50.264 -                                        if (cgamode&0x20)
  50.265 +                                        chr  = m24->charbuffer[ x << 1];
  50.266 +                                        attr = m24->charbuffer[(x << 1) + 1];
  50.267 +                                        drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron);
  50.268 +                                        if (m24->cgamode & 0x20)
  50.269                                          {
  50.270 -                                                cols[1]=(attr&15)+16;
  50.271 -                                                cols[0]=((attr>>4)&7)+16;
  50.272 -                                                if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
  50.273 +                                                cols[1] = (attr & 15) + 16;
  50.274 +                                                cols[0] = ((attr >> 4) & 7) + 16;
  50.275 +                                                if ((m24->blink & 16) && (attr & 0x80) && !drawcursor) 
  50.276 +                                                        cols[1] = cols[0];
  50.277                                          }
  50.278                                          else
  50.279                                          {
  50.280 -                                                cols[1]=(attr&15)+16;
  50.281 -                                                cols[0]=(attr>>4)+16;
  50.282 +                                                cols[1] = (attr & 15) + 16;
  50.283 +                                                cols[0] = (attr >> 4) + 16;
  50.284                                          }
  50.285                                          if (drawcursor)
  50.286                                          {
  50.287 -                                                for (c=0;c<8;c++)
  50.288 -                                                    buffer->line[displine][(x<<3)+c+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0]^15;
  50.289 +                                                for (c = 0; c < 8; c++)
  50.290 +                                                    buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
  50.291                                          }
  50.292                                          else
  50.293                                          {
  50.294 -                                                for (c=0;c<8;c++)
  50.295 -                                                    buffer->line[displine][(x<<3)+c+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0];
  50.296 +                                                for (c = 0; c < 8; c++)
  50.297 +                                                    buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0];
  50.298                                          }
  50.299 -                                        ma++;
  50.300 +                                        m24->ma++;
  50.301                                  }
  50.302                          }
  50.303 -                        else if (!(cgamode&2))
  50.304 +                        else if (!(m24->cgamode & 2))
  50.305                          {
  50.306 -                                for (x=0;x<crtc[1];x++)
  50.307 +                                for (x = 0; x < m24->crtc[1]; x++)
  50.308                                  {
  50.309 -                                        chr=vram[((ma<<1)&0x3FFF) + m24_base];
  50.310 -                                        attr=vram[(((ma<<1)+1)&0x3FFF) + m24_base];
  50.311 -                                        drawcursor=((ma==ca) && con && cursoron);
  50.312 -                                        if (cgamode&0x20)
  50.313 +                                        chr  = m24->vram[((m24->ma << 1) & 0x3fff) + m24->base];
  50.314 +                                        attr = m24->vram[(((m24->ma << 1) + 1) & 0x3fff) + m24->base];
  50.315 +                                        drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron);
  50.316 +                                        if (m24->cgamode & 0x20)
  50.317                                          {
  50.318 -                                                cols[1]=(attr&15)+16;
  50.319 -                                                cols[0]=((attr>>4)&7)+16;
  50.320 -                                                if ((cgablink&16) && (attr&0x80)) cols[1]=cols[0];
  50.321 +                                                cols[1] = (attr & 15) + 16;
  50.322 +                                                cols[0] = ((attr >> 4) & 7) + 16;
  50.323 +                                                if ((m24->blink & 16) && (attr & 0x80)) 
  50.324 +                                                        cols[1] = cols[0];
  50.325                                          }
  50.326                                          else
  50.327                                          {
  50.328 -                                                cols[1]=(attr&15)+16;
  50.329 -                                                cols[0]=(attr>>4)+16;
  50.330 +                                                cols[1] = (attr & 15) + 16;
  50.331 +                                                cols[0] = (attr >> 4) + 16;
  50.332                                          }
  50.333 -                                        ma++;
  50.334 +                                        m24->ma++;
  50.335                                          if (drawcursor)
  50.336                                          {
  50.337 -                                                for (c=0;c<8;c++)
  50.338 -                                                    buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0]^15;
  50.339 +                                                for (c = 0; c < 8; c++)
  50.340 +                                                    buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = 
  50.341 +                                                    buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
  50.342                                          }
  50.343                                          else
  50.344                                          {
  50.345 -                                                for (c=0;c<8;c++)
  50.346 -                                                    buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0];
  50.347 +                                                for (c = 0; c < 8; c++)
  50.348 +                                                    buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = 
  50.349 +                                                    buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0];
  50.350                                          }
  50.351                                  }
  50.352                          }
  50.353 -                        else if (!(cgamode&16))
  50.354 +                        else if (!(m24->cgamode & 16))
  50.355                          {
  50.356 -                                cols[0]=(cgacol&15)|16;
  50.357 -                                col=(cgacol&16)?24:16;
  50.358 -                                if (cgamode&4)
  50.359 +                                cols[0] = (m24->cgacol & 15) | 16;
  50.360 +                                col = (m24->cgacol & 16) ? 24 : 16;
  50.361 +                                if (m24->cgamode & 4)
  50.362                                  {
  50.363 -                                        cols[1]=col|3;
  50.364 -                                        cols[2]=col|4;
  50.365 -                                        cols[3]=col|7;
  50.366 +                                        cols[1] = col | 3;
  50.367 +                                        cols[2] = col | 4;
  50.368 +                                        cols[3] = col | 7;
  50.369                                  }
  50.370 -                                else if (cgacol&32)
  50.371 +                                else if (m24->cgacol & 32)
  50.372                                  {
  50.373 -                                        cols[1]=col|3;
  50.374 -                                        cols[2]=col|5;
  50.375 -                                        cols[3]=col|7;
  50.376 +                                        cols[1] = col | 3;
  50.377 +                                        cols[2] = col | 5;
  50.378 +                                        cols[3] = col | 7;
  50.379                                  }
  50.380                                  else
  50.381                                  {
  50.382 -                                        cols[1]=col|2;
  50.383 -                                        cols[2]=col|4;
  50.384 -                                        cols[3]=col|6;
  50.385 +                                        cols[1] = col | 2;
  50.386 +                                        cols[2] = col | 4;
  50.387 +                                        cols[3] = col | 6;
  50.388                                  }
  50.389 -                                for (x=0;x<crtc[1];x++)
  50.390 +                                for (x = 0; x < m24->crtc[1]; x++)
  50.391                                  {
  50.392 -                                        dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000) + m24_base]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1 + m24_base];
  50.393 -                                        ma++;
  50.394 -                                        for (c=0;c<8;c++)
  50.395 +                                        dat = (m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + m24->base] << 8) | 
  50.396 +                                               m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + 1 + m24->base];
  50.397 +                                        m24->ma++;
  50.398 +                                        for (c = 0; c < 8; c++)
  50.399                                          {
  50.400 -                                                buffer->line[displine][(x<<4)+(c<<1)+8]=
  50.401 -                                                  buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
  50.402 -                                                dat<<=2;
  50.403 +                                                buffer->line[m24->displine][(x << 4) + (c << 1) + 8] =
  50.404 +                                                buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
  50.405 +                                                dat <<= 2;
  50.406                                          }
  50.407                                  }
  50.408                          }
  50.409                          else
  50.410                          {
  50.411 -                                
  50.412 -                                if (m24_ctrl & 1)
  50.413 +                                if (m24->ctrl & 1)
  50.414                                  {                                        
  50.415 -                                        dat2 = ((sc & 1) * 0x4000) | (m24_lineff * 0x2000);
  50.416 -                                        cols[0]=0; cols[1]=/*(cgacol&15)*/15+16;
  50.417 +                                        dat2 = ((m24->sc & 1) * 0x4000) | (m24->lineff * 0x2000);
  50.418 +                                        cols[0] = 0; cols[1] = /*(m24->cgacol & 15)*/15 + 16;
  50.419                                  }
  50.420                                  else
  50.421                                  {
  50.422 -                                        dat2 =  (sc & 1) * 0x2000;
  50.423 -                                        cols[0]=0; cols[1]=(cgacol&15)+16;
  50.424 +                                        dat2 = (m24->sc & 1) * 0x2000;
  50.425 +                                        cols[0] = 0; cols[1] = (m24->cgacol & 15) + 16;
  50.426                                  }
  50.427 -                                for (x=0;x<crtc[1];x++)
  50.428 +                                for (x = 0; x < m24->crtc[1]; x++)
  50.429                                  {
  50.430 -                                        dat=(vram[((ma<<1)&0x1FFF) + dat2]<<8) | vram[((ma<<1)&0x1FFF) + dat2 + 1];
  50.431 -                                        ma++;
  50.432 -                                        for (c=0;c<16;c++)
  50.433 +                                        dat = (m24->vram[((m24->ma << 1) & 0x1fff) + dat2] << 8) | m24->vram[((m24->ma << 1) & 0x1fff) + dat2 + 1];
  50.434 +                                        m24->ma++;
  50.435 +                                        for (c = 0; c < 16; c++)
  50.436                                          {
  50.437 -                                                buffer->line[displine][(x<<4)+c+8]=cols[dat>>15];
  50.438 -                                                dat<<=1;
  50.439 +                                                buffer->line[m24->displine][(x << 4) + c + 8] = cols[dat >> 15];
  50.440 +                                                dat <<= 1;
  50.441                                          }
  50.442                                  }
  50.443                          }
  50.444                  }
  50.445                  else
  50.446                  {
  50.447 -                        cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16;
  50.448 -                        if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
  50.449 -                        else           hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
  50.450 +                        cols[0] = ((m24->cgamode & 0x12) == 0x12) ? 0 : (m24->cgacol & 15) + 16;
  50.451 +                        if (m24->cgamode & 1) hline(buffer, 0, m24->displine, (m24->crtc[1] << 3) + 16, cols[0]);
  50.452 +                        else                  hline(buffer, 0, m24->displine, (m24->crtc[1] << 4) + 16, cols[0]);
  50.453                  }
  50.454  
  50.455 -                if (cgamode&1) x=(crtc[1]<<3)+16;
  50.456 -                else           x=(crtc[1]<<4)+16;
  50.457 +                if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16;
  50.458 +                else                  x = (m24->crtc[1] << 4) + 16;
  50.459  
  50.460 -                sc=oldsc;
  50.461 -                if (vc==crtc[7] && !sc)
  50.462 -                   cgastat|=8;
  50.463 -                displine++;
  50.464 -                if (displine>=720) displine=0;
  50.465 +                m24->sc = oldsc;
  50.466 +                if (m24->vc == m24->crtc[7] && !m24->sc)
  50.467 +                        m24->stat |= 8;
  50.468 +                m24->displine++;
  50.469 +                if (m24->displine >= 720) m24->displine = 0;
  50.470          }
  50.471          else
  50.472          {
  50.473  //                pclog("Line poll  %i %i %i %i\n", m24_lineff, vc, sc, vadj);
  50.474 -                vidtime+=dispontime;
  50.475 -                if (cgadispon) cgastat&=~1;
  50.476 -                linepos=0;
  50.477 -                m24_lineff ^= 1;
  50.478 -                if (m24_lineff)
  50.479 +                m24->vidtime += m24->dispontime;
  50.480 +                if (m24->dispon) m24->stat &= ~1;
  50.481 +                m24->linepos = 0;
  50.482 +                m24->lineff ^= 1;
  50.483 +                if (m24->lineff)
  50.484                  {
  50.485 -                        ma = maback;
  50.486 +                        m24->ma = m24->maback;
  50.487                  }                
  50.488                  else
  50.489                  {
  50.490 -                        if (vsynctime)
  50.491 +                        if (m24->vsynctime)
  50.492                          {
  50.493 -                                vsynctime--;
  50.494 -                                if (!vsynctime)
  50.495 -                                   cgastat&=~8;
  50.496 +                                m24->vsynctime--;
  50.497 +                                if (!m24->vsynctime)
  50.498 +                                   m24->stat &= ~8;
  50.499                          }
  50.500 -                        if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; }
  50.501 -                        if (vadj)
  50.502 +                        if (m24->sc == (m24->crtc[11] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[11] & 31) >> 1))) 
  50.503 +                        { 
  50.504 +                                m24->con = 0; 
  50.505 +                                m24->coff = 1; 
  50.506 +                        }
  50.507 +                        if (m24->vadj)
  50.508                          {
  50.509 -                                sc++;
  50.510 -                                sc&=31;
  50.511 -                                ma=maback;
  50.512 -                                vadj--;
  50.513 -                                if (!vadj)
  50.514 +                                m24->sc++;
  50.515 +                                m24->sc &= 31;
  50.516 +                                m24->ma = m24->maback;
  50.517 +                                m24->vadj--;
  50.518 +                                if (!m24->vadj)
  50.519                                  {
  50.520 -                                        cgadispon=1;
  50.521 -                                        ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
  50.522 -                                        sc=0;
  50.523 +                                        m24->dispon = 1;
  50.524 +                                        m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff;
  50.525 +                                        m24->sc = 0;
  50.526                                  }
  50.527                          }
  50.528 -                        else if (sc==crtc[9] || ((crtc[8]&3)==3 && sc==(crtc[9]>>1)))
  50.529 +                        else if (m24->sc == m24->crtc[9] || ((m24->crtc[8] & 3) == 3 && m24->sc == (m24->crtc[9] >> 1)))
  50.530                          {
  50.531 -                                maback=ma;
  50.532 -                                sc=0;
  50.533 -                                oldvc=vc;
  50.534 -                                vc++;
  50.535 -                                vc&=127;
  50.536 +                                m24->maback = m24->ma;
  50.537 +                                m24->sc = 0;
  50.538 +                                oldvc = m24->vc;
  50.539 +                                m24->vc++;
  50.540 +                                m24->vc &= 127;
  50.541  
  50.542 -                                if (vc==crtc[6]) 
  50.543 -                                   cgadispon=0;
  50.544 +                                if (m24->vc == m24->crtc[6]) 
  50.545 +                                        m24->dispon=0;
  50.546                                     
  50.547 -                                if (oldvc==crtc[4])
  50.548 +                                if (oldvc == m24->crtc[4])
  50.549                                  {
  50.550 -                                        vc=0;
  50.551 -                                        vadj=crtc[5];
  50.552 -                                        if (!vadj) cgadispon=1;
  50.553 -                                        if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
  50.554 -                                        if ((crtc[10]&0x60)==0x20) cursoron=0;
  50.555 -                                        else                       cursoron=cgablink&16;
  50.556 +                                        m24->vc = 0;
  50.557 +                                        m24->vadj = m24->crtc[5];
  50.558 +                                        if (!m24->vadj) m24->dispon = 1;
  50.559 +                                        if (!m24->vadj) m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff;
  50.560 +                                        if ((m24->crtc[10] & 0x60) == 0x20) m24->cursoron = 0;
  50.561 +                                        else                                m24->cursoron = m24->blink & 16;
  50.562                                  }
  50.563  
  50.564 -                                if (vc==crtc[7])
  50.565 +                                if (m24->vc == m24->crtc[7])
  50.566                                  {
  50.567 -                                        cgadispon=0;
  50.568 -                                        displine=0;
  50.569 -                                        vsynctime=(crtc[3]>>4)+1;
  50.570 -                                        if (crtc[7])
  50.571 +                                        m24->dispon = 0;
  50.572 +                                        m24->displine = 0;
  50.573 +                                        m24->vsynctime = (m24->crtc[3] >> 4) + 1;
  50.574 +                                        if (m24->crtc[7])
  50.575                                          {
  50.576 -                                                if (cgamode&1) x=(crtc[1]<<3)+16;
  50.577 -                                                else           x=(crtc[1]<<4)+16;
  50.578 -                                                lastline++;
  50.579 -                                                if (x!=xsize || (lastline-firstline)!=ysize)
  50.580 +                                                if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16;
  50.581 +                                                else                  x = (m24->crtc[1] << 4) + 16;
  50.582 +                                                m24->lastline++;
  50.583 +                                                if (x != xsize || (m24->lastline - m24->firstline) != ysize)
  50.584                                                  {
  50.585 -                                                        xsize=x;
  50.586 -                                                        ysize=lastline-firstline;
  50.587 -                                                        if (xsize<64) xsize=656;
  50.588 -                                                        if (ysize<32) ysize=200;
  50.589 +                                                        xsize = x;
  50.590 +                                                        ysize = m24->lastline - m24->firstline;
  50.591 +                                                        if (xsize < 64) xsize = 656;
  50.592 +                                                        if (ysize < 32) ysize = 200;
  50.593                                                          updatewindowsize(xsize, ysize + 16);
  50.594                                                  }
  50.595  startblit();
  50.596 -                                                video_blit_memtoscreen_8(0, firstline - 8, xsize, (lastline - firstline) + 16);
  50.597 -                                                if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
  50.598 -                                                readflash=0;
  50.599 +pclog("m24 blit %i %i\n", m24->firstline, m24->lastline);
  50.600 +                                                video_blit_memtoscreen_8(0, m24->firstline - 8, xsize, (m24->lastline - m24->firstline) + 16);
  50.601 +                                                if (readflash) rectfill(screen, winsizex - 40, 8, winsizex - 8, 14, 0xFFFFFFFF);
  50.602 +                                                readflash = 0;
  50.603                                                  frames++;
  50.604  endblit();
  50.605                                                  video_res_x = xsize - 16;
  50.606                                                  video_res_y = ysize;
  50.607 -                                                if (cgamode & 1)
  50.608 +                                                if (m24->cgamode & 1)
  50.609                                                  {
  50.610                                                          video_res_x /= 8;
  50.611 -                                                        video_res_y /= (crtc[9] + 1) * 2;
  50.612 +                                                        video_res_y /= (m24->crtc[9] + 1) * 2;
  50.613                                                          video_bpp = 0;
  50.614                                                  }
  50.615 -                                                else if (!(cgamode & 2))
  50.616 +                                                else if (!(m24->cgamode & 2))
  50.617                                                  {
  50.618                                                          video_res_x /= 16;
  50.619 -                                                        video_res_y /= (crtc[9] + 1) * 2;
  50.620 +                                                        video_res_y /= (m24->crtc[9] + 1) * 2;
  50.621                                                          video_bpp = 0;
  50.622                                                  }
  50.623 -                                                else if (!(cgamode&16))
  50.624 +                                                else if (!(m24->cgamode & 16))
  50.625                                                  {
  50.626                                                          video_res_x /= 2;
  50.627                                                          video_res_y /= 2;
  50.628                                                          video_bpp = 2;
  50.629                                                  }
  50.630 -                                                else if (!(m24_ctrl & 1))
  50.631 +                                                else if (!(m24->ctrl & 1))
  50.632                                                  {
  50.633                                                          video_res_y /= 2;
  50.634                                                          video_bpp = 1;
  50.635                                                  }
  50.636                                          }
  50.637 -                                        firstline=1000;
  50.638 -                                        lastline=0;
  50.639 -                                        cgablink++;
  50.640 +                                        m24->firstline = 1000;
  50.641 +                                        m24->lastline = 0;
  50.642 +                                        m24->blink++;
  50.643                                  }
  50.644                          }
  50.645                          else
  50.646                          {
  50.647 -                                sc++;
  50.648 -                                sc&=31;
  50.649 -                                ma=maback;
  50.650 +                                m24->sc++;
  50.651 +                                m24->sc &= 31;
  50.652 +                                m24->ma = m24->maback;
  50.653                          }
  50.654 -                        if ((sc==(crtc[10]&31) || ((crtc[8]&3)==3 && sc==((crtc[10]&31)>>1)))) con=1;
  50.655 +                        if ((m24->sc == (m24->crtc[10] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[10] & 31) >> 1)))) 
  50.656 +                                m24->con = 1;
  50.657                  }
  50.658 -                if (cgadispon && (cgamode&1))
  50.659 +                if (m24->dispon && (m24->cgamode & 1))
  50.660                  {
  50.661 -                        for (x=0;x<(crtc[1]<<1);x++)
  50.662 -                            charbuffer[x]=vram[(((ma<<1)+x)&0x3FFF) + m24_base];
  50.663 +                        for (x = 0; x < (m24->crtc[1] << 1); x++)
  50.664 +                            m24->charbuffer[x] = m24->vram[(((m24->ma << 1) + x) & 0x3fff) + m24->base];
  50.665                  }
  50.666          }
  50.667  }
  50.668  
  50.669 +void *m24_init()
  50.670 +{
  50.671 +        int c;
  50.672 +        m24_t *m24 = malloc(sizeof(m24_t));
  50.673 +        memset(m24, 0, sizeof(m24_t));
  50.674  
  50.675 -int m24_init()
  50.676 -{
  50.677 -        mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL,  NULL);
  50.678 -        return 0;
  50.679 +        m24->vram = malloc(0x8000);
  50.680 +                
  50.681 +        timer_add(m24_poll, &m24->vidtime, TIMER_ALWAYS_ENABLED, m24);
  50.682 +        mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL,  m24);
  50.683 +        io_sethandler(0x03d0, 0x0010, m24_in, NULL, NULL, m24_out, NULL, NULL, m24);
  50.684 +        return m24;
  50.685  }
  50.686  
  50.687 -GFXCARD vid_m24 =
  50.688 +void m24_close(void *p)
  50.689  {
  50.690 +        m24_t *m24 = (m24_t *)p;
  50.691 +
  50.692 +        free(m24->vram);
  50.693 +        free(m24);
  50.694 +}
  50.695 +
  50.696 +void m24_speed_changed(void *p)
  50.697 +{
  50.698 +        m24_t *m24 = (m24_t *)p;
  50.699 +        
  50.700 +        m24_recalctimings(m24);
  50.701 +}
  50.702 +
  50.703 +device_t m24_device =
  50.704 +{
  50.705 +        "Olivetti M24 (video)",
  50.706          m24_init,
  50.707 -        /*IO at 3Cx/3Dx*/
  50.708 -        m24_out,
  50.709 -        m24_in,
  50.710 -        /*IO at 3Ax/3Bx*/
  50.711 -        video_out_null,
  50.712 -        video_in_null,
  50.713 -
  50.714 -        m24_poll,
  50.715 -        m24_recalctimings,
  50.716 -
  50.717 -        video_write_null,
  50.718 -        video_write_null,
  50.719 -        m24_write,
  50.720 -
  50.721 -        video_read_null,
  50.722 -        video_read_null,
  50.723 -        m24_read
  50.724 +        m24_close,
  50.725 +        m24_speed_changed,
  50.726 +        NULL
  50.727  };
    51.1 --- a/src/vid_olivetti_m24.h	Tue Jun 04 20:52:17 2013 +0100
    51.2 +++ b/src/vid_olivetti_m24.h	Mon Jun 24 20:42:35 2013 +0100
    51.3 @@ -0,0 +1,1 @@
    51.4 +extern device_t m24_device;
    52.1 --- a/src/vid_oti067.c	Tue Jun 04 20:52:17 2013 +0100
    52.2 +++ b/src/vid_oti067.c	Mon Jun 24 20:42:35 2013 +0100
    52.3 @@ -1,126 +1,151 @@
    52.4  /*Oak OTI067 emulation*/
    52.5 +#include <stdlib.h>
    52.6  #include "ibm.h"
    52.7 +#include "device.h"
    52.8  #include "io.h"
    52.9  #include "video.h"
   52.10 +#include "vid_oti067.h"
   52.11  #include "vid_svga.h"
   52.12  
   52.13 -static int oti067_index;
   52.14 -static uint8_t oti067_regs[32];
   52.15 +typedef struct oti067_t
   52.16 +{
   52.17 +        svga_t svga;
   52.18 +        
   52.19 +        int index;
   52.20 +        uint8_t regs[32];
   52.21 +} oti067_t;
   52.22  
   52.23 -void oti067_out(uint16_t addr, uint8_t val, void *priv)
   52.24 +void oti067_out(uint16_t addr, uint8_t val, void *p)
   52.25  {
   52.26 +        oti067_t *oti067 = (oti067_t *)p;
   52.27 +        svga_t *svga = &oti067->svga;
   52.28          uint8_t old;
   52.29  
   52.30  //        pclog("oti067_out : %04X %02X  %02X %i\n", addr, val, ram[0x489], ins);
   52.31                  
   52.32 -        if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga_miscout&1)) addr ^= 0x60;
   52.33 +        if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60;
   52.34  
   52.35          switch (addr)
   52.36          {
   52.37                  case 0x3D4:
   52.38 -                crtcreg=val&31;
   52.39 +                svga->crtcreg = val & 31;
   52.40                  return;
   52.41                  case 0x3D5:
   52.42 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
   52.43 -                old=crtc[crtcreg];
   52.44 -                crtc[crtcreg]=val;
   52.45 -                if (old!=val)
   52.46 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
   52.47 +                old = svga->crtc[svga->crtcreg];
   52.48 +                svga->crtc[svga->crtcreg] = val;
   52.49 +                if (old != val)
   52.50                  {
   52.51 -                        if (crtcreg<0xE || crtcreg>0x10)
   52.52 +                        if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
   52.53                          {
   52.54 -                                fullchange=changeframecount;
   52.55 -                                svga_recalctimings();
   52.56 +                                fullchange = changeframecount;
   52.57 +                                svga_recalctimings(svga);
   52.58                          }
   52.59                  }
   52.60                  break;
   52.61  
   52.62 -                case 0x3DE: oti067_index=val&0x1F; return;
   52.63 +                case 0x3DE: 
   52.64 +                oti067->index = val & 0x1f; 
   52.65 +                return;
   52.66                  case 0x3DF:
   52.67 -                oti067_regs[oti067_index]=val;
   52.68 -                switch (oti067_index)
   52.69 +                oti067->regs[oti067->index] = val;
   52.70 +                switch (oti067->index)
   52.71                  {
   52.72                          case 0xD:
   52.73 -                        vrammask=(val&0xC)?0x7FFFF:0x3FFFF;
   52.74 +                        svga->vrammask = (val & 0xc) ? 0x7ffff : 0x3ffff;
   52.75                          break;
   52.76                          case 0x11:
   52.77 -                        svgarbank=(val&0xF)*65536;
   52.78 -                        svgawbank=(val>>4)*65536;
   52.79 +                        svga->read_bank = (val & 0xf) * 65536;
   52.80 +                        svga->write_bank = (val >> 4) * 65536;
   52.81                          break;
   52.82                  }
   52.83                  return;
   52.84          }
   52.85 -        svga_out(addr, val, NULL);
   52.86 +        svga_out(addr, val, svga);
   52.87  }
   52.88  
   52.89 -uint8_t oti067_in(uint16_t addr, void *priv)
   52.90 +uint8_t oti067_in(uint16_t addr, void *p)
   52.91  {
   52.92 +        oti067_t *oti067 = (oti067_t *)p;
   52.93 +        svga_t *svga = &oti067->svga;
   52.94          uint8_t temp;
   52.95          
   52.96  //        if (addr != 0x3da && addr != 0x3ba) pclog("oti067_in : %04X ", addr);
   52.97          
   52.98 -        if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga_miscout&1)) addr ^= 0x60;
   52.99 +        if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60;
  52.100          
  52.101          switch (addr)
  52.102          {
  52.103                  case 0x3D4:
  52.104 -                temp = crtcreg;
  52.105 +                temp = svga->crtcreg;
  52.106                  break;
  52.107                  case 0x3D5:
  52.108 -                temp = crtc[crtcreg];
  52.109 +                temp = svga->crtc[svga->crtcreg];
  52.110                  break;
  52.111                  
  52.112                  case 0x3DE: 
  52.113 -                temp = oti067_index|(2<<5);
  52.114 +                temp = oti067->index | (2 << 5);
  52.115                  break;               
  52.116                  case 0x3DF: 
  52.117 -                if (oti067_index==0x10) temp = 0x18;
  52.118 -                else if (oti067_index==0xD) temp = oti067_regs[oti067_index]|0xC0;
  52.119 -                else                            temp = oti067_regs[oti067_index];
  52.120 +                if (oti067->index==0x10)     temp = 0x18;
  52.121 +                else if (oti067->index==0xD) temp = oti067->regs[oti067->index]|0xC0;
  52.122 +                else                         temp = oti067->regs[oti067->index];
  52.123                  break;
  52.124  
  52.125                  default:
  52.126 -                temp = svga_in(addr, NULL);
  52.127 +                temp = svga_in(addr, svga);
  52.128                  break;
  52.129          }
  52.130  //        if (addr != 0x3da && addr != 0x3ba) pclog("%02X  %04X:%04X\n", temp, CS,pc);        
  52.131          return temp;
  52.132  }
  52.133  
  52.134 -void oti067_recalctimings()
  52.135 +void oti067_recalctimings(svga_t *svga)
  52.136  {
  52.137 -        if (oti067_regs[0x14]&0x08) svga_ma|=0x10000;
  52.138 -        if (oti067_regs[0x0D]&0x0C) svga_rowoffset<<=1;
  52.139 -        svga_interlace = oti067_regs[0x14]&0x80;
  52.140 +        oti067_t *oti067 = (oti067_t *)svga->p;
  52.141 +        
  52.142 +        if (oti067->regs[0x14] & 0x08) svga->ma_latch |= 0x10000;
  52.143 +        if (oti067->regs[0x0d] & 0x0c) svga->rowoffset <<= 1;
  52.144 +        svga->interlace = oti067->regs[0x14] & 0x80;
  52.145  }
  52.146  
  52.147 -int oti067_init()
  52.148 +void *oti067_init()
  52.149  {
  52.150 -        svga_recalctimings_ex = oti067_recalctimings;
  52.151 -        svga_vram_limit = 1 << 19; /*512kb*/
  52.152 -        vrammask = 0x7ffff;
  52.153 -        bpp = 8;
  52.154 -        svga_miscout = 1;
  52.155 -        return svga_init();
  52.156 +        oti067_t *oti067 = malloc(sizeof(oti067_t));
  52.157 +        memset(oti067, 0, sizeof(oti067_t));
  52.158 +        
  52.159 +        svga_init(&oti067->svga, oti067, 1 << 19, /*512kb*/
  52.160 +                   oti067_recalctimings,
  52.161 +                   oti067_in, oti067_out,
  52.162 +                   NULL);
  52.163 +
  52.164 +        io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067);
  52.165 +
  52.166 +        oti067->svga.miscout = 1;
  52.167 +        return oti067;
  52.168  }
  52.169  
  52.170 -GFXCARD vid_oti067 =
  52.171 +void oti067_close(void *p)
  52.172  {
  52.173 +        oti067_t *oti067 = (oti067_t *)p;
  52.174 +
  52.175 +        svga_close(&oti067->svga);
  52.176 +        
  52.177 +        free(oti067);
  52.178 +}
  52.179 +
  52.180 +void oti067_speed_changed(void *p)
  52.181 +{
  52.182 +        oti067_t *oti067 = (oti067_t *)p;
  52.183 +        
  52.184 +        svga_recalctimings(&oti067->svga);
  52.185 +}
  52.186 +        
  52.187 +device_t oti067_device =
  52.188 +{
  52.189 +        "Oak OTI-067",
  52.190          oti067_init,
  52.191 -        /*IO at 3Cx/3Dx*/
  52.192 -        oti067_out,
  52.193 -        oti067_in,
  52.194 -        /*IO at 3Ax/3Bx*/
  52.195 -        video_out_null,
  52.196 -        video_in_null,
  52.197 -
  52.198 -        svga_poll,
  52.199 -        svga_recalctimings,
  52.200 -
  52.201 -        svga_write,
  52.202 -        video_write_null,
  52.203 -        video_write_null,
  52.204 -
  52.205 -        svga_read,
  52.206 -        video_read_null,
  52.207 -        video_read_null
  52.208 +        oti067_close,
  52.209 +        oti067_speed_changed,
  52.210 +        svga_add_status_info
  52.211  };
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/src/vid_oti067.h	Mon Jun 24 20:42:35 2013 +0100
    53.3 @@ -0,0 +1,1 @@
    53.4 +extern device_t oti067_device;
    54.1 --- a/src/vid_paradise.c	Tue Jun 04 20:52:17 2013 +0100
    54.2 +++ b/src/vid_paradise.c	Mon Jun 24 20:42:35 2013 +0100
    54.3 @@ -3,271 +3,335 @@
    54.4    PC2086, PC3086 use PVGA1A
    54.5    MegaPC uses W90C11A
    54.6    */
    54.7 +#include <stdlib.h>
    54.8  #include "ibm.h"
    54.9 +#include "device.h"
   54.10  #include "mem.h"
   54.11  #include "video.h"
   54.12 +#include "vid_paradise.h"
   54.13  #include "vid_svga.h"
   54.14 +#include "vid_svga_render.h"
   54.15  #include "vid_unk_ramdac.h"
   54.16  
   54.17 -void    paradise_write(uint32_t addr, uint8_t val, void *priv);
   54.18 -uint8_t paradise_read(uint32_t addr, void *priv);
   54.19 -void paradise_remap();
   54.20 +typedef struct paradise_t
   54.21 +{
   54.22 +        svga_t svga;
   54.23 +        
   54.24 +        enum
   54.25 +        {
   54.26 +                PVGA1A = 0,
   54.27 +                WD90C11
   54.28 +        } type;
   54.29  
   54.30 -enum
   54.31 +        uint32_t read_bank[4], write_bank[4];
   54.32 +} paradise_t;
   54.33 +
   54.34 +void    paradise_write(uint32_t addr, uint8_t val, void *p);
   54.35 +uint8_t paradise_read(uint32_t addr, void *p);
   54.36 +void paradise_remap(paradise_t *paradise);
   54.37 +
   54.38 +
   54.39 +void paradise_out(uint16_t addr, uint8_t val, void *p)
   54.40  {
   54.41 -        PVGA1A = 0,
   54.42 -        WD90C11
   54.43 -};
   54.44 -
   54.45 -static int paradise_type;
   54.46 -
   54.47 -static uint32_t paradise_bank_r[4], paradise_bank_w[4];
   54.48 -
   54.49 -void paradise_out(uint16_t addr, uint8_t val, void *priv)
   54.50 -{
   54.51 +        paradise_t *paradise = (paradise_t *)p;
   54.52 +        svga_t *svga = &paradise->svga;
   54.53          uint8_t old;
   54.54          
   54.55 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   54.56 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
   54.57 +                addr ^= 0x60;
   54.58  //        output = 3;
   54.59          pclog("Paradise out %04X %02X %04X:%04X\n", addr, val, CS, pc);
   54.60          switch (addr)
   54.61          {
   54.62                  case 0x3c5:
   54.63 -                if (seqaddr > 7)                        
   54.64 +                if (svga->seqaddr > 7)                        
   54.65                  {
   54.66 -                        if (paradise_type < WD90C11 || seqregs[6] != 0x48) 
   54.67 +                        if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) 
   54.68                             return;
   54.69 -                        seqregs[seqaddr & 0x1f] = val;
   54.70 -                        if (seqaddr == 0x11)
   54.71 -                           paradise_remap();
   54.72 +                        svga->seqregs[svga->seqaddr & 0x1f] = val;
   54.73 +                        if (svga->seqaddr == 0x11)
   54.74 +                           paradise_remap(paradise);
   54.75                          return;
   54.76                  }
   54.77                  break;
   54.78  
   54.79                  case 0x3cf:
   54.80 -                if (gdcaddr >= 0x9 && gdcaddr < 0xf)
   54.81 +                if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf)
   54.82                  {
   54.83 -                        if ((gdcreg[0xf] & 7) != 5)
   54.84 +                        if ((svga->gdcreg[0xf] & 7) != 5)
   54.85                             return;
   54.86                  }
   54.87 -                if (gdcaddr == 6)
   54.88 +                if (svga->gdcaddr == 6)
   54.89                  {
   54.90 -                        if ((gdcreg[6] & 0xc) != (val & 0xc))
   54.91 +                        if ((svga->gdcreg[6] & 0xc) != (val & 0xc))
   54.92                          {
   54.93 -                                mem_removehandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL,  NULL);
   54.94 +                                mem_removehandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL,  paradise);
   54.95  //                                pclog("Write mapping %02X\n", val);
   54.96                                  switch (val&0xC)
   54.97                                  {
   54.98                                          case 0x0: /*128k at A0000*/
   54.99 -                                        mem_sethandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL,  NULL);
  54.100 +                                        mem_sethandler(0xa0000, 0x20000, paradise_read, NULL, NULL, paradise_write, NULL, NULL,  paradise);
  54.101                                          break;
  54.102                                          case 0x4: /*64k at A0000*/
  54.103 -                                        mem_sethandler(0xa0000, 0x10000, paradise_read, NULL, NULL, paradise_write, NULL, NULL,  NULL);
  54.104 +                                        mem_sethandler(0xa0000, 0x10000, paradise_read, NULL, NULL, paradise_write, NULL, NULL,  paradise);
  54.105                                          break;
  54.106                                          case 0x8: /*32k at B0000*/
  54.107 -                                        mem_sethandler(0xb0000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL,  NULL);
  54.108 +                                        mem_sethandler(0xb0000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL,  paradise);
  54.109                                          break;
  54.110                                          case 0xC: /*32k at B8000*/
  54.111 -                                        mem_sethandler(0xb8000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL,  NULL);
  54.112 +                                        mem_sethandler(0xb8000, 0x08000, paradise_read, NULL, NULL, paradise_write, NULL, NULL,  paradise);
  54.113                                          break;
  54.114                                  }
  54.115                          }
  54.116 -                        gdcreg[6] = val;
  54.117 -                        paradise_remap();
  54.118 +                        svga->gdcreg[6] = val;
  54.119 +                        paradise_remap(paradise);
  54.120                          return;
  54.121                  }
  54.122 -                if (gdcaddr == 0x9 || gdcaddr == 0xa)
  54.123 +                if (svga->gdcaddr == 0x9 || svga->gdcaddr == 0xa)
  54.124                  {
  54.125 -                        gdcreg[gdcaddr] = val;
  54.126 -                        paradise_remap();
  54.127 +                        svga->gdcreg[svga->gdcaddr] = val;
  54.128 +                        paradise_remap(paradise);
  54.129                          return;
  54.130                  }
  54.131 -                if (gdcaddr == 0xe)
  54.132 +                if (svga->gdcaddr == 0xe)
  54.133                  {
  54.134 -                        gdcreg[0xe] = val;
  54.135 -                        paradise_remap();
  54.136 +                        svga->gdcreg[0xe] = val;
  54.137 +                        paradise_remap(paradise);
  54.138                          return;
  54.139                  }
  54.140                  break;
  54.141                  
  54.142                  case 0x3D4:
  54.143 -                if (paradise_type == PVGA1A)
  54.144 -                   crtcreg = val & 0x1f;
  54.145 +                if (paradise->type == PVGA1A)
  54.146 +                   svga->crtcreg = val & 0x1f;
  54.147                  else
  54.148 -                   crtcreg = val & 0x3f;
  54.149 +                   svga->crtcreg = val & 0x3f;
  54.150                  return;
  54.151                  case 0x3D5:
  54.152 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) 
  54.153 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) 
  54.154                     return;
  54.155 -                if (crtcreg > 0x29 && (crtc[0x29] & 7) != 5)
  54.156 +                if (svga->crtcreg > 0x29 && (svga->crtc[0x29] & 7) != 5)
  54.157                     return;
  54.158 -                if (crtcreg >= 0x31 && crtcreg <= 0x37)
  54.159 +                if (svga->crtcreg >= 0x31 && svga->crtcreg <= 0x37)
  54.160                     return;
  54.161 -                old=crtc[crtcreg];
  54.162 -                crtc[crtcreg]=val;
  54.163 +                old = svga->crtc[svga->crtcreg];
  54.164 +                svga->crtc[svga->crtcreg] = val;
  54.165  
  54.166 -                if (old!=val)
  54.167 +                if (old != val)
  54.168                  {
  54.169 -                        if (crtcreg<0xE || crtcreg>0x10)
  54.170 +                        if (svga->crtcreg < 0xe ||  svga->crtcreg > 0x10)
  54.171                          {
  54.172 -                                fullchange=changeframecount;
  54.173 -                                svga_recalctimings();
  54.174 +                                fullchange = changeframecount;
  54.175 +                                svga_recalctimings(&paradise->svga);
  54.176                          }
  54.177                  }
  54.178                  break;
  54.179          }
  54.180 -        svga_out(addr, val, NULL);
  54.181 +        svga_out(addr, val, svga);
  54.182  }
  54.183  
  54.184 -uint8_t paradise_in(uint16_t addr, void *priv)
  54.185 +uint8_t paradise_in(uint16_t addr, void *p)
  54.186  {
  54.187 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  54.188 +        paradise_t *paradise = (paradise_t *)p;
  54.189 +        svga_t *svga = &paradise->svga;
  54.190          
  54.191 -//        if (addr != 0x3da) pclog("Paradise in %04X\n", addr);
  54.192 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
  54.193 +                addr ^= 0x60;
  54.194 +        
  54.195 +        if (addr != 0x3da) pclog("Paradise in %04X\n", addr);
  54.196          switch (addr)
  54.197          {
  54.198 +                case 0x3c2:
  54.199 +                return 0x10;
  54.200 +                
  54.201                  case 0x3c5:
  54.202 -                if (seqaddr > 7)
  54.203 +                if (svga->seqaddr > 7)
  54.204                  {
  54.205 -                        if (paradise_type < WD90C11 || seqregs[6] != 0x48) 
  54.206 +                        if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) 
  54.207                             return 0xff;
  54.208 -                        if (seqaddr > 0x12) 
  54.209 +                        if (svga->seqaddr > 0x12) 
  54.210                             return 0xff;
  54.211 -                        return seqregs[seqaddr & 0x1f];
  54.212 +                        return svga->seqregs[svga->seqaddr & 0x1f];
  54.213                  }
  54.214                  break;
  54.215                          
  54.216                  case 0x3cf:
  54.217 -                if (gdcaddr >= 0x9 && gdcaddr < 0xf)
  54.218 +                if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf)
  54.219                  {
  54.220 -                        if (gdcreg[0xf] & 0x10)
  54.221 +                        if (svga->gdcreg[0xf] & 0x10)
  54.222                             return 0xff;
  54.223 -                        switch (gdcaddr)
  54.224 +                        switch (svga->gdcaddr)
  54.225                          {
  54.226                                  case 0xf:
  54.227 -                                return (gdcreg[0xf] & 0x17) | 0x80;
  54.228 +                                return (svga->gdcreg[0xf] & 0x17) | 0x80;
  54.229                          }
  54.230                  }
  54.231                  break;
  54.232  
  54.233                  case 0x3D4:
  54.234 -                return crtcreg;
  54.235 +                return svga->crtcreg;
  54.236                  case 0x3D5:
  54.237 -                if (crtcreg > 0x29 && crtcreg < 0x30 && (crtc[0x29] & 0x88) != 0x80)
  54.238 +                if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80)
  54.239                     return 0xff;
  54.240 -                return crtc[crtcreg];
  54.241 +                return svga->crtc[svga->crtcreg];
  54.242          }
  54.243 -        return svga_in(addr, NULL);
  54.244 +        return svga_in(addr, svga);
  54.245  }
  54.246  
  54.247 -void paradise_remap()
  54.248 +void paradise_remap(paradise_t *paradise)
  54.249  {
  54.250 -        if (seqregs[0x11] & 0x80)
  54.251 +        svga_t *svga = &paradise->svga;
  54.252 +        
  54.253 +        if (svga->seqregs[0x11] & 0x80)
  54.254          {
  54.255  //                pclog("Remap 1\n");
  54.256 -                paradise_bank_r[0] = paradise_bank_r[2] =  (gdcreg[0x9] & 0x7f) << 12;
  54.257 -                paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.258 -                paradise_bank_w[0] = paradise_bank_w[2] =  (gdcreg[0xa] & 0x7f) << 12;
  54.259 -                paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0xa] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.260 +                paradise->read_bank[0]  = paradise->read_bank[2]  =  (svga->gdcreg[0x9] & 0x7f) << 12;
  54.261 +                paradise->read_bank[1]  = paradise->read_bank[3]  = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.262 +                paradise->write_bank[0] = paradise->write_bank[2] =  (svga->gdcreg[0xa] & 0x7f) << 12;
  54.263 +                paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.264          }
  54.265 -        else if (gdcreg[0xe] & 0x08)
  54.266 +        else if (svga->gdcreg[0xe] & 0x08)
  54.267          {
  54.268 -                if (gdcreg[0x6] & 0xc)
  54.269 +                if (svga->gdcreg[0x6] & 0xc)
  54.270                  {
  54.271  //                pclog("Remap 2\n");                        
  54.272 -                        paradise_bank_r[0] = paradise_bank_r[2] =  (gdcreg[0xa] & 0x7f) << 12;
  54.273 -                        paradise_bank_w[0] = paradise_bank_w[2] =  (gdcreg[0xa] & 0x7f) << 12;
  54.274 -                        paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.275 -                        paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.276 +                        paradise->read_bank[0]  = paradise->read_bank[2]  =  (svga->gdcreg[0xa] & 0x7f) << 12;
  54.277 +                        paradise->write_bank[0] = paradise->write_bank[2] =  (svga->gdcreg[0xa] & 0x7f) << 12;
  54.278 +                        paradise->read_bank[1]  = paradise->read_bank[3]  = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.279 +                        paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.280                  }
  54.281                  else
  54.282                  {
  54.283  //                pclog("Remap 3\n");
  54.284 -                        paradise_bank_r[0] = paradise_bank_w[0] =  (gdcreg[0xa] & 0x7f) << 12;
  54.285 -                        paradise_bank_r[1] = paradise_bank_w[1] = ((gdcreg[0xa] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.286 -                        paradise_bank_r[2] = paradise_bank_w[2] =  (gdcreg[0x9] & 0x7f) << 12;
  54.287 -                        paradise_bank_r[3] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.288 +                        paradise->read_bank[0] = paradise->write_bank[0] =  (svga->gdcreg[0xa] & 0x7f) << 12;
  54.289 +                        paradise->read_bank[1] = paradise->write_bank[1] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.290 +                        paradise->read_bank[2] = paradise->write_bank[2] =  (svga->gdcreg[0x9] & 0x7f) << 12;
  54.291 +                        paradise->read_bank[3] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.292                  }
  54.293          }
  54.294          else
  54.295          {
  54.296    //              pclog("Remap 4\n");
  54.297 -                paradise_bank_r[0] = paradise_bank_r[2] =  (gdcreg[0x9] & 0x7f) << 12;
  54.298 -                paradise_bank_r[1] = paradise_bank_r[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.299 -                paradise_bank_w[0] = paradise_bank_w[2] =  (gdcreg[0x9] & 0x7f) << 12;
  54.300 -                paradise_bank_w[1] = paradise_bank_w[3] = ((gdcreg[0x9] & 0x7f) << 12) + ((gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.301 +                paradise->read_bank[0]  = paradise->read_bank[2]  =  (svga->gdcreg[0x9] & 0x7f) << 12;
  54.302 +                paradise->read_bank[1]  = paradise->read_bank[3]  = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.303 +                paradise->write_bank[0] = paradise->write_bank[2] =  (svga->gdcreg[0x9] & 0x7f) << 12;
  54.304 +                paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
  54.305          }
  54.306 -//        pclog("Remap - %04X %04X\n", paradise_bank_r[0], paradise_bank_w[0]);
  54.307 +//        pclog("Remap - %04X %04X\n", paradise->read_bank[0], paradise->write_bank[0]);
  54.308  }
  54.309  
  54.310 -void paradise_recalctimings()
  54.311 +void paradise_recalctimings(svga_t *svga)
  54.312  {
  54.313 -        svga_lowres = !(gdcreg[0xe] & 0x01);
  54.314 +        svga->lowres = !(svga->gdcreg[0xe] & 0x01);
  54.315 +        if (svga->bpp == 8 && !svga->lowres)
  54.316 +                svga->render = svga_render_8bpp_highres;
  54.317  }
  54.318  
  54.319  #define egacycles 1
  54.320  #define egacycles2 1
  54.321 -void paradise_write(uint32_t addr, uint8_t val, void *priv)
  54.322 +void paradise_write(uint32_t addr, uint8_t val, void *p)
  54.323  {
  54.324 +        paradise_t *paradise = (paradise_t *)p;
  54.325  //        pclog("paradise_write : %05X %02X  ", addr, val);
  54.326 -        addr = (addr & 0x7fff) + paradise_bank_w[(addr >> 15) & 3];
  54.327 +        addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
  54.328  //        pclog("%08X\n", addr);
  54.329 -        svga_write_linear(addr, val, priv);
  54.330 +        svga_write_linear(addr, val, &paradise->svga);
  54.331  }
  54.332  
  54.333 -uint8_t paradise_read(uint32_t addr, void *priv)
  54.334 +uint8_t paradise_read(uint32_t addr, void *p)
  54.335  {
  54.336 +        paradise_t *paradise = (paradise_t *)p;
  54.337  //        pclog("paradise_read : %05X ", addr);
  54.338 -        addr = (addr & 0x7fff) + paradise_bank_r[(addr >> 15) & 3];
  54.339 +        addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
  54.340  //        pclog("%08X\n", addr);
  54.341 -        return svga_read_linear(addr, priv);
  54.342 +        return svga_read_linear(addr, &paradise->svga);
  54.343  }
  54.344  
  54.345 -int paradise_init()
  54.346 +void *paradise_pvga1a_init()
  54.347  {
  54.348 -        if (romset == ROM_PC2086 || romset == ROM_PC3086)
  54.349 -        {
  54.350 -                paradise_type = PVGA1A;               
  54.351 -                vrammask = 0x3ffff;
  54.352 -                pclog("Init PVGA1A\n");
  54.353 -                svga_vram_limit = 1 << 18; /*256kb*/
  54.354 -        }
  54.355 -        if (romset == ROM_MEGAPC)
  54.356 -        {
  54.357 -                paradise_type = WD90C11;
  54.358 -                vrammask = 0x7ffff;
  54.359 -                crtc[0x36] = '1';
  54.360 -                crtc[0x37] = '1';
  54.361 -                pclog("Init WD90C11\n");
  54.362 -                svga_vram_limit = 1 << 19; /*512kb*/
  54.363 -        }
  54.364 -        crtc[0x31] = 'W';
  54.365 -        crtc[0x32] = 'D';
  54.366 -        crtc[0x33] = '9';
  54.367 -        crtc[0x34] = '0';
  54.368 -        crtc[0x35] = 'C';                                
  54.369 -        svga_recalctimings_ex = paradise_recalctimings;
  54.370 -        return svga_init();
  54.371 +        paradise_t *paradise = malloc(sizeof(paradise_t));
  54.372 +        svga_t *svga = &paradise->svga;
  54.373 +        memset(paradise, 0, sizeof(paradise_t));
  54.374 +        
  54.375 +        io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise);
  54.376 +
  54.377 +        svga_init(&paradise->svga, paradise, 1 << 18, /*256kb*/
  54.378 +                   NULL,
  54.379 +                   paradise_in, paradise_out,
  54.380 +                   NULL);
  54.381 +
  54.382 +        svga->crtc[0x31] = 'W';
  54.383 +        svga->crtc[0x32] = 'D';
  54.384 +        svga->crtc[0x33] = '9';
  54.385 +        svga->crtc[0x34] = '0';
  54.386 +        svga->crtc[0x35] = 'C';
  54.387 +
  54.388 +        svga->bpp = 8;
  54.389 +        svga->miscout = 1;
  54.390 +        
  54.391 +        paradise->type = PVGA1A;               
  54.392 +        
  54.393 +        return paradise;
  54.394  }
  54.395  
  54.396 -GFXCARD vid_paradise =
  54.397 +void *paradise_wd90c11_init()
  54.398  {
  54.399 -        paradise_init,
  54.400 -        /*IO at 3Cx/3Dx*/
  54.401 -        paradise_out,
  54.402 -        paradise_in,
  54.403 -        /*IO at 3Ax/3Bx*/
  54.404 -        video_out_null,
  54.405 -        video_in_null,
  54.406 +        paradise_t *paradise = malloc(sizeof(paradise_t));
  54.407 +        svga_t *svga = &paradise->svga;
  54.408 +        memset(paradise, 0, sizeof(paradise_t));
  54.409 +        
  54.410 +        io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise);
  54.411  
  54.412 -        svga_poll,
  54.413 -        svga_recalctimings,
  54.414 +        svga_init(&paradise->svga, paradise, 1 << 19, /*512kb*/
  54.415 +                   paradise_recalctimings,
  54.416 +                   paradise_in, paradise_out,
  54.417 +                   NULL);
  54.418  
  54.419 -        paradise_write,
  54.420 -        video_write_null,
  54.421 -        video_write_null,
  54.422 +        svga->crtc[0x31] = 'W';
  54.423 +        svga->crtc[0x32] = 'D';
  54.424 +        svga->crtc[0x33] = '9';
  54.425 +        svga->crtc[0x34] = '0';
  54.426 +        svga->crtc[0x35] = 'C';
  54.427 +        svga->crtc[0x36] = '1';
  54.428 +        svga->crtc[0x37] = '1';
  54.429  
  54.430 -        paradise_read,
  54.431 -        video_read_null,
  54.432 -        video_read_null
  54.433 +        svga->bpp = 8;
  54.434 +        svga->miscout = 1;
  54.435 +        
  54.436 +        paradise->type = WD90C11;               
  54.437 +        
  54.438 +        return paradise;
  54.439 +}
  54.440 +
  54.441 +void paradise_close(void *p)
  54.442 +{
  54.443 +        paradise_t *paradise = (paradise_t *)p;
  54.444 +
  54.445 +        svga_close(&paradise->svga);
  54.446 +        
  54.447 +        free(paradise);
  54.448 +}
  54.449 +
  54.450 +void paradise_speed_changed(void *p)
  54.451 +{
  54.452 +        paradise_t *paradise = (paradise_t *)p;
  54.453 +        
  54.454 +        svga_recalctimings(&paradise->svga);
  54.455 +}
  54.456 +
  54.457 +device_t paradise_pvga1a_device =
  54.458 +{
  54.459 +        "Paradise PVGA1A",
  54.460 +        paradise_pvga1a_init,
  54.461 +        paradise_close,
  54.462 +        paradise_speed_changed,
  54.463 +        svga_add_status_info
  54.464  };
  54.465 +device_t paradise_wd90c11_device =
  54.466 +{
  54.467 +        "Paradise WD90C11",
  54.468 +        paradise_wd90c11_init,
  54.469 +        paradise_close,
  54.470 +        paradise_speed_changed,
  54.471 +        svga_add_status_info
  54.472 +};
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/src/vid_paradise.h	Mon Jun 24 20:42:35 2013 +0100
    55.3 @@ -0,0 +1,2 @@
    55.4 +extern device_t paradise_pvga1a_device;
    55.5 +extern device_t paradise_wd90c11_device;
    56.1 --- a/src/vid_pc1512.c	Tue Jun 04 20:52:17 2013 +0100
    56.2 +++ b/src/vid_pc1512.c	Mon Jun 24 20:42:35 2013 +0100
    56.3 @@ -6,263 +6,289 @@
    56.4    
    56.5    The Technical Reference Manual lists the video waitstate time as between 12 
    56.6    and 46 cycles. PCem currently always uses the lower number.*/
    56.7 -
    56.8 +#include <stdlib.h>
    56.9  #include "ibm.h"
   56.10 +#include "device.h"
   56.11  #include "io.h"
   56.12  #include "mem.h"
   56.13  #include "timer.h"
   56.14  #include "video.h"
   56.15 -#include "vid_cga.h"
   56.16 +#include "vid_pc1512.h"
   56.17  
   56.18 -static uint8_t pc1512_plane_write,pc1512_plane_read,pc1512_border;
   56.19 +typedef struct pc1512_t
   56.20 +{
   56.21 +        uint8_t crtc[32];
   56.22 +        int crtcreg;
   56.23  
   56.24 -void pc1512_recalctimings();
   56.25 +        uint8_t cgacol, cgamode, stat;
   56.26 +        
   56.27 +        uint8_t plane_write, plane_read, border;
   56.28  
   56.29 -void pc1512_out(uint16_t addr, uint8_t val, void *priv)
   56.30 +        int linepos, displine;
   56.31 +        int sc, vc;
   56.32 +        int cgadispon;
   56.33 +        int con, coff, cursoron, cgablink;
   56.34 +        int vsynctime, vadj;
   56.35 +        uint16_t ma, maback;
   56.36 +        int dispon;
   56.37 +        int blink;
   56.38 +        
   56.39 +        int dispontime, dispofftime, vidtime;
   56.40 +        int firstline, lastline;
   56.41 +        
   56.42 +        uint8_t *vram;
   56.43 +} pc1512_t;
   56.44 +
   56.45 +static uint8_t crtcmask[32] = 
   56.46  {
   56.47 +        0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
   56.48 +        0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   56.49 +};
   56.50 +
   56.51 +static void pc1512_recalctimings(pc1512_t *pc1512);
   56.52 +
   56.53 +static void pc1512_out(uint16_t addr, uint8_t val, void *p)
   56.54 +{
   56.55 +        pc1512_t *pc1512 = (pc1512_t *)p;
   56.56          uint8_t old;
   56.57 -//        pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc);
   56.58 +        pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc);
   56.59          switch (addr)
   56.60          {
   56.61 -                case 0x3D4:
   56.62 -                crtcreg=val&31;
   56.63 +                case 0x3d4:
   56.64 +                pc1512->crtcreg = val & 31;
   56.65                  return;
   56.66 -                case 0x3D5:
   56.67 -                old=crtc[crtcreg];
   56.68 -                crtc[crtcreg]=val&crtcmask[crtcreg];
   56.69 -                if (old!=val)
   56.70 +                case 0x3d5:
   56.71 +                old = pc1512->crtc[pc1512->crtcreg];
   56.72 +                pc1512->crtc[pc1512->crtcreg] = val & crtcmask[pc1512->crtcreg];
   56.73 +                if (old != val)
   56.74                  {
   56.75 -                        if (crtcreg<0xE || crtcreg>0x10)
   56.76 +                        if (pc1512->crtcreg < 0xe || pc1512->crtcreg > 0x10)
   56.77                          {
   56.78 -                                fullchange=changeframecount;
   56.79 -                                pc1512_recalctimings();
   56.80 +                                fullchange = changeframecount;
   56.81 +                                pc1512_recalctimings(pc1512);
   56.82                          }
   56.83                  }
   56.84                  return;
   56.85 -                case 0x3D8:
   56.86 -                if ((val&0x12)==0x12 && (cgamode&0x12)!=0x12)
   56.87 +                case 0x3d8:
   56.88 +                if ((val & 0x12) == 0x12 && (pc1512->cgamode & 0x12) != 0x12)
   56.89                  {
   56.90 -                        pc1512_plane_write=0xF;
   56.91 -                        pc1512_plane_read =0;
   56.92 +                        pc1512->plane_write = 0xf;
   56.93 +                        pc1512->plane_read  = 0;
   56.94                  }
   56.95 -                cgamode=val;
   56.96 +                pc1512->cgamode = val;
   56.97                  return;
   56.98 -                case 0x3D9:
   56.99 -                cgacol=val;
  56.100 +                case 0x3d9:
  56.101 +                pc1512->cgacol = val;
  56.102                  return;
  56.103 -                case 0x3DD:
  56.104 -                pc1512_plane_write=val;
  56.105 +                case 0x3dd:
  56.106 +                pc1512->plane_write = val;
  56.107                  return;
  56.108 -                case 0x3DE:
  56.109 -                pc1512_plane_read=val&3;
  56.110 +                case 0x3de:
  56.111 +                pc1512->plane_read = val & 3;
  56.112                  return;
  56.113 -                case 0x3DF:
  56.114 -                pc1512_border=val;
  56.115 +                case 0x3df:
  56.116 +                pc1512->border = val;
  56.117                  return;
  56.118          }
  56.119  }
  56.120  
  56.121 -uint8_t pc1512_in(uint16_t addr, void *priv)
  56.122 +static uint8_t pc1512_in(uint16_t addr, void *p)
  56.123  {
  56.124 +        pc1512_t *pc1512 = (pc1512_t *)p;
  56.125  //        pclog("PC1512 in %04X %02X %04X:%04X\n",addr,CS,pc);
  56.126          switch (addr)
  56.127          {
  56.128 -                case 0x3D4:
  56.129 -                return crtcreg;
  56.130 -                case 0x3D5:
  56.131 -                return crtc[crtcreg];
  56.132 -                case 0x3DA:
  56.133 -                return cgastat;
  56.134 +                case 0x3d4:
  56.135 +                return pc1512->crtcreg;
  56.136 +                case 0x3d5:
  56.137 +                return pc1512->crtc[pc1512->crtcreg];
  56.138 +                case 0x3da:
  56.139 +                return pc1512->stat;
  56.140          }
  56.141 -        return 0xFF;
  56.142 +        return 0xff;
  56.143  }
  56.144  
  56.145 -void pc1512_write(uint32_t addr, uint8_t val, void *priv)
  56.146 +static void pc1512_write(uint32_t addr, uint8_t val, void *p)
  56.147  {
  56.148 -/*        if (CS==0x023E && pc==0x524E)
  56.149 +        pc1512_t *pc1512 = (pc1512_t *)p;
  56.150 +
  56.151 +        cycles -= 12;
  56.152 +        addr &= 0x3fff;
  56.153 +
  56.154 +        if ((pc1512->cgamode & 0x12) == 0x12)
  56.155          {
  56.156 -                dumpregs();
  56.157 -                exit(-1);
  56.158 -        }
  56.159 -       pclog("PC1512 write %08X %02X %02X %01X  %04X:%04X\n",addr,val,cgamode&0x12,pc1512_plane_write,CS,pc);*/
  56.160 -        cycles-=12;
  56.161 -        addr&=0x7FFF;
  56.162 -        if ((cgamode&0x12)==0x12)
  56.163 -        {
  56.164 -                if (pc1512_plane_write&1) vram[addr]=val;
  56.165 -                if (pc1512_plane_write&2) vram[addr|0x10000]=val;
  56.166 -                if (pc1512_plane_write&4) vram[addr|0x20000]=val;
  56.167 -                if (pc1512_plane_write&8) vram[addr|0x30000]=val;
  56.168 +                if (pc1512->plane_write & 1) pc1512->vram[addr]          = val;
  56.169 +                if (pc1512->plane_write & 2) pc1512->vram[addr | 0x4000] = val;
  56.170 +                if (pc1512->plane_write & 4) pc1512->vram[addr | 0x8000] = val;
  56.171 +                if (pc1512->plane_write & 8) pc1512->vram[addr | 0xc000] = val;
  56.172          }
  56.173          else
  56.174 -           vram[addr]=val;
  56.175 +           pc1512->vram[addr] = val;
  56.176  }
  56.177  
  56.178 -uint8_t pc1512_read(uint32_t addr, void *priv)
  56.179 +static uint8_t pc1512_read(uint32_t addr, void *p)
  56.180  {
  56.181 -//        pclog("PC1512 read %08X %02X %01X\n",addr,cgamode&0x12,pc1512_plane_read);
  56.182 -        cycles-=12;
  56.183 -        addr&=0x7FFF;
  56.184 -        if ((cgamode&0x12)==0x12)
  56.185 -           return vram[addr|(pc1512_plane_read<<16)];
  56.186 -        return vram[addr];
  56.187 +        pc1512_t *pc1512 = (pc1512_t *)p;
  56.188 +
  56.189 +        cycles -= 12;
  56.190 +        addr &= 0x3fff;
  56.191 +
  56.192 +        if ((pc1512->cgamode & 0x12) == 0x12)
  56.193 +           return pc1512->vram[addr | (pc1512->plane_read << 14)];
  56.194 +        return pc1512->vram[addr];
  56.195  }
  56.196  
  56.197  
  56.198 -static int linepos,displine;
  56.199 -static int sc,vc;
  56.200 -static int cgadispon;
  56.201 -static int con,coff,cursoron,cgablink;
  56.202 -static int vsynctime,vadj;
  56.203 -static uint16_t ma,maback;
  56.204 -
  56.205 -int i_filt[8],q_filt[8];
  56.206 -
  56.207 -
  56.208 -void pc1512_recalctimings()
  56.209 +static void pc1512_recalctimings(pc1512_t *pc1512)
  56.210  {
  56.211 -	double _dispontime, _dispofftime;
  56.212 +	double _dispontime, _dispofftime, disptime;
  56.213          disptime = 128; /*Fixed on PC1512*/
  56.214          _dispontime = 80;
  56.215 -        _dispofftime=disptime-_dispontime;
  56.216 +        _dispofftime = disptime - _dispontime;
  56.217  //        printf("%i %f %f %f  %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
  56.218 -        _dispontime*=CGACONST;
  56.219 -        _dispofftime*=CGACONST;
  56.220 +        _dispontime  *= CGACONST;
  56.221 +        _dispofftime *= CGACONST;
  56.222  //        printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
  56.223 -	dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  56.224 -	dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  56.225 +	pc1512->dispontime  = (int)(_dispontime * (1 << TIMER_SHIFT));
  56.226 +	pc1512->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  56.227  }
  56.228  
  56.229 -void pc1512_poll()
  56.230 +static void pc1512_poll(void *p)
  56.231  {
  56.232 -        uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF;
  56.233 +        pc1512_t *pc1512 = (pc1512_t *)p;
  56.234 +        uint16_t ca = (pc1512->crtc[15] | (pc1512->crtc[14] << 8)) & 0x3fff;
  56.235          int drawcursor;
  56.236 -        int x,c;
  56.237 +        int x, c;
  56.238          int oldvc;
  56.239 -        uint8_t chr,attr;
  56.240 -        uint16_t dat,dat2,dat3,dat4;
  56.241 +        uint8_t chr, attr;
  56.242 +        uint16_t dat, dat2, dat3, dat4;
  56.243          int cols[4];
  56.244          int col;
  56.245          int oldsc;
  56.246  
  56.247 -        if (!linepos)
  56.248 +        if (!pc1512->linepos)
  56.249          {
  56.250 -                vidtime+=dispofftime;
  56.251 -                cgastat|=1;
  56.252 -                linepos=1;
  56.253 -                oldsc=sc;
  56.254 -                if (cgadispon)
  56.255 +                pc1512->vidtime += pc1512->dispofftime;
  56.256 +                pc1512->stat |= 1;
  56.257 +                pc1512->linepos = 1;
  56.258 +                oldsc = pc1512->sc;
  56.259 +                if (pc1512->dispon)
  56.260                  {
  56.261 -                        if (displine<firstline) firstline=displine;
  56.262 -                        lastline=displine;
  56.263 -                        for (c=0;c<8;c++)
  56.264 +                        if (pc1512->displine < pc1512->firstline) 
  56.265 +                                pc1512->firstline = pc1512->displine;
  56.266 +                        pc1512->lastline = pc1512->displine;
  56.267 +                        for (c = 0; c < 8; c++)
  56.268                          {
  56.269 -                                if ((cgamode&0x12)==0x12)
  56.270 +                                if ((pc1512->cgamode & 0x12) == 0x12)
  56.271                                  {
  56.272 -                                        buffer->line[displine][c]=(pc1512_border&15)+16;
  56.273 -                                        if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
  56.274 -                                        else           buffer->line[displine][c+(crtc[1]<<4)+8]=0;
  56.275 +                                        buffer->line[pc1512->displine][c] = (pc1512->border & 15) + 16;
  56.276 +                                        if (pc1512->cgamode & 1) buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 3) + 8] = 0;
  56.277 +                                        else                     buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 4) + 8] = 0;
  56.278                                  }
  56.279                                  else
  56.280                                  {
  56.281 -                                        buffer->line[displine][c]=(cgacol&15)+16;
  56.282 -                                        if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16;
  56.283 -                                        else           buffer->line[displine][c+(crtc[1]<<4)+8]=(cgacol&15)+16;
  56.284 +                                        buffer->line[pc1512->displine][c] = (pc1512->cgacol & 15) + 16;
  56.285 +                                        if (pc1512->cgamode & 1) buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 3) + 8] = (pc1512->cgacol & 15) + 16;
  56.286 +                                        else                     buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 4) + 8] = (pc1512->cgacol & 15) + 16;
  56.287                                  }
  56.288                          }
  56.289 -                        if (cgamode&1)
  56.290 +                        if (pc1512->cgamode & 1)
  56.291                          {
  56.292                                  for (x = 0; x < 80; x++)
  56.293                                  {
  56.294 -                                        chr=vram[((ma<<1)&0x3FFF)];
  56.295 -                                        attr=vram[(((ma<<1)+1)&0x3FFF)];
  56.296 -                                        drawcursor=((ma==ca) && con && cursoron);
  56.297 -                                        if (cgamode&0x20)
  56.298 +                                        chr  = pc1512->vram[ ((pc1512->ma << 1)      & 0x3fff)];
  56.299 +                                        attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)];
  56.300 +                                        drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron);
  56.301 +                                        if (pc1512->cgamode & 0x20)
  56.302                                          {
  56.303 -                                                cols[1]=(attr&15)+16;
  56.304 -                                                cols[0]=((attr>>4)&7)+16;
  56.305 -                                                if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
  56.306 +                                                cols[1] = (attr & 15) + 16;
  56.307 +                                                cols[0] = ((attr >> 4) & 7) + 16;
  56.308 +                                                if ((pc1512->blink & 16) && (attr & 0x80) && !drawcursor) 
  56.309 +                                                        cols[1] = cols[0];
  56.310                                          }
  56.311                                          else
  56.312                                          {
  56.313 -                                                cols[1]=(attr&15)+16;
  56.314 -                                                cols[0]=(attr>>4)+16;
  56.315 +                                                cols[1] = (attr & 15) + 16;
  56.316 +                                                cols[0] = (attr >> 4) + 16;
  56.317                                          }
  56.318                                          if (drawcursor)
  56.319                                          {
  56.320 -                                                for (c=0;c<8;c++)
  56.321 -                                                    buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15;
  56.322 +                                                for (c = 0; c < 8; c++)
  56.323 +                                                    buffer->line[pc1512->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
  56.324                                          }
  56.325                                          else
  56.326                                          {
  56.327 -                                                for (c=0;c<8;c++)
  56.328 -                                                    buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
  56.329 +                                                for (c = 0; c < 8; c++)
  56.330 +                                                    buffer->line[pc1512->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
  56.331                                          }
  56.332 -                                        ma++;
  56.333 +                                        pc1512->ma++;
  56.334                                  }
  56.335                          }
  56.336 -                        else if (!(cgamode&2))
  56.337 +                        else if (!(pc1512->cgamode & 2))
  56.338                          {
  56.339                                  for (x = 0; x < 40; x++)
  56.340                                  {
  56.341 -                                        chr=vram[((ma<<1)&0x3FFF)];
  56.342 -                                        attr=vram[(((ma<<1)+1)&0x3FFF)];
  56.343 -                                        drawcursor=((ma==ca) && con && cursoron);
  56.344 -                                        if (cgamode&0x20)
  56.345 +                                        chr  = pc1512->vram[ ((pc1512->ma << 1)      & 0x3fff)];
  56.346 +                                        attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)];
  56.347 +                                        drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron);
  56.348 +                                        if (pc1512->cgamode & 0x20)
  56.349                                          {
  56.350 -                                                cols[1]=(attr&15)+16;
  56.351 -                                                cols[0]=((attr>>4)&7)+16;
  56.352 -                                                if ((cgablink&16) && (attr&0x80)) cols[1]=cols[0];
  56.353 +                                                cols[1] = (attr & 15) + 16;
  56.354 +                                                cols[0] = ((attr >> 4) & 7) + 16;
  56.355 +                                                if ((pc1512->blink & 16) && (attr & 0x80)) 
  56.356 +                                                        cols[1] = cols[0];
  56.357                                          }
  56.358                                          else
  56.359                                          {
  56.360 -                                                cols[1]=(attr&15)+16;
  56.361 -                                                cols[0]=(attr>>4)+16;
  56.362 +                                                cols[1] = (attr & 15) + 16;
  56.363 +                                                cols[0] = (attr >> 4) + 16;
  56.364                                          }
  56.365 -                                        ma++;
  56.366 +                                        pc1512->ma++;
  56.367                                          if (drawcursor)
  56.368                                          {
  56.369 -                                                for (c=0;c<8;c++)
  56.370 -                                                    buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0]^15;
  56.371 +                                                for (c = 0; c < 8; c++)
  56.372 +                                                    buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] = 
  56.373 +                                                    buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
  56.374                                          }
  56.375                                          else
  56.376                                          {
  56.377 -                                                for (c=0;c<8;c++)
  56.378 -                                                    buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
  56.379 +                                                for (c = 0; c < 8; c++)
  56.380 +                                                    buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] = 
  56.381 +                                                    buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
  56.382                                          }
  56.383                                  }
  56.384                          }
  56.385 -                        else if (!(cgamode&16))
  56.386 +                        else if (!(pc1512->cgamode&16))
  56.387                          {
  56.388 -                                cols[0]=(cgacol&15)|16;
  56.389 -                                col=(cgacol&16)?24:16;
  56.390 -                                if (cgamode&4)
  56.391 +                                cols[0] = (pc1512->cgacol & 15) | 16;
  56.392 +                                col = (pc1512->cgacol & 16) ? 24 : 16;
  56.393 +                                if (pc1512->cgamode & 4)
  56.394                                  {
  56.395 -                                        cols[1]=col|3;
  56.396 -                                        cols[2]=col|4;
  56.397 -                                        cols[3]=col|7;
  56.398 +                                        cols[1] = col | 3;
  56.399 +                                        cols[2] = col | 4;
  56.400 +                                        cols[3] = col | 7;
  56.401                                  }
  56.402 -                                else if (cgacol&32)
  56.403 +                                else if (pc1512->cgacol & 32)
  56.404                                  {
  56.405 -                                        cols[1]=col|3;
  56.406 -                                        cols[2]=col|5;
  56.407 -                                        cols[3]=col|7;
  56.408 +                                        cols[1] = col | 3;
  56.409 +                                        cols[2] = col | 5;
  56.410 +                                        cols[3] = col | 7;
  56.411                                  }
  56.412                                  else
  56.413                                  {
  56.414 -                                        cols[1]=col|2;
  56.415 -                                        cols[2]=col|4;
  56.416 -                                        cols[3]=col|6;
  56.417 +                                        cols[1] = col | 2;
  56.418 +                                        cols[2] = col | 4;
  56.419 +                                        cols[3] = col | 6;
  56.420                                  }
  56.421                                  for (x = 0; x < 40; x++)
  56.422                                  {
  56.423 -                                        dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
  56.424 -                                        ma++;
  56.425 -                                        for (c=0;c<8;c++)
  56.426 +                                        dat = (pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000)] << 8) | pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000) + 1];
  56.427 +                                        pc1512->ma++;
  56.428 +                                        for (c = 0; c < 8; c++)
  56.429                                          {
  56.430 -                                                buffer->line[displine][(x<<4)+(c<<1)+8]=
  56.431 -                                                  buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
  56.432 -                                                dat<<=2;
  56.433 +                                                buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] =
  56.434 +                                                buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
  56.435 +                                                dat <<= 2;
  56.436                                          }
  56.437                                  }
  56.438                          }
  56.439 @@ -270,169 +296,191 @@
  56.440                          {
  56.441                                  for (x = 0; x < 40; x++)
  56.442                                  {
  56.443 -                                        ca=((ma<<1)&0x1FFF)+((sc&1)*0x2000);
  56.444 -                                        dat=(vram[ca]<<8)|vram[ca+1];
  56.445 -                                        dat2=(vram[ca+0x10000]<<8)|vram[ca+0x10001];
  56.446 -                                        dat3=(vram[ca+0x20000]<<8)|vram[ca+0x20001];
  56.447 -                                        dat4=(vram[ca+0x30000]<<8)|vram[ca+0x30001];
  56.448 +                                        ca = ((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000);
  56.449 +                                        dat  = (pc1512->vram[ca]          << 8) | pc1512->vram[ca + 1];
  56.450 +                                        dat2 = (pc1512->vram[ca + 0x4000] << 8) | pc1512->vram[ca + 0x4001];
  56.451 +                                        dat3 = (pc1512->vram[ca + 0x8000] << 8) | pc1512->vram[ca + 0x8001];
  56.452 +                                        dat4 = (pc1512->vram[ca + 0xc000] << 8) | pc1512->vram[ca + 0xc001];
  56.453  
  56.454 -                                        ma++;
  56.455 -                                        for (c=0;c<16;c++)
  56.456 +                                        pc1512->ma++;
  56.457 +                                        for (c = 0; c < 16; c++)
  56.458                                          {
  56.459 -                                                buffer->line[displine][(x<<4)+c+8]=(((dat>>15)|((dat2>>15)<<1)|((dat3>>15)<<2)|((dat4>>15)<<3))&(cgacol&15))+16;
  56.460 -                                                dat<<=1;
  56.461 -                                                dat2<<=1;
  56.462 -                                                dat3<<=1;
  56.463 -                                                dat4<<=1;
  56.464 +                                                buffer->line[pc1512->displine][(x << 4) + c + 8] = (((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | ((dat4 >> 15) << 3)) & (pc1512->cgacol & 15)) + 16;
  56.465 +                                                dat  <<= 1;
  56.466 +                                                dat2 <<= 1;
  56.467 +                                                dat3 <<= 1;
  56.468 +                                                dat4 <<= 1;
  56.469                                          }
  56.470                                  }
  56.471                          }
  56.472                  }
  56.473                  else
  56.474                  {
  56.475 -                        cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16;
  56.476 -                        if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
  56.477 -                        else           hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
  56.478 +                        cols[0] = ((pc1512->cgamode & 0x12) == 0x12) ? 0 : (pc1512->cgacol & 15) + 16;
  56.479 +                        if (pc1512->cgamode & 1) hline(buffer, 0, pc1512->displine, (pc1512->crtc[1] << 3) + 16, cols[0]);
  56.480 +                        else                     hline(buffer, 0, pc1512->displine, (pc1512->crtc[1] << 4) + 16, cols[0]);
  56.481                  }
  56.482  
  56.483 -                sc=oldsc;
  56.484 -                if (vsynctime)
  56.485 -                   cgastat|=8;
  56.486 -                displine++;
  56.487 -                if (displine>=360) displine=0;
  56.488 +                pc1512->sc = oldsc;
  56.489 +                if (pc1512->vsynctime)
  56.490 +                   pc1512->stat |= 8;
  56.491 +                pc1512->displine++;
  56.492 +                if (pc1512->displine >= 360) 
  56.493 +                        pc1512->displine = 0;
  56.494  //                pclog("Line %i %i %i %i  %i %i\n",displine,cgadispon,firstline,lastline,vc,sc);
  56.495          }
  56.496          else
  56.497          {
  56.498 -                vidtime+=dispontime;
  56.499 -                if ((lastline-firstline)==199) cgadispon=0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/
  56.500 -                if (cgadispon) cgastat&=~1;
  56.501 -                linepos=0;
  56.502 -                if (vsynctime)
  56.503 +                pc1512->vidtime += pc1512->dispontime;
  56.504 +                if ((pc1512->lastline - pc1512->firstline) == 199) 
  56.505 +                        pc1512->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/
  56.506 +                if (pc1512->dispon) 
  56.507 +                        pc1512->stat &= ~1;
  56.508 +                pc1512->linepos = 0;
  56.509 +                if (pc1512->vsynctime)
  56.510                  {
  56.511 -                        vsynctime--;
  56.512 -                        if (!vsynctime)
  56.513 -                           cgastat&=~8;
  56.514 +                        pc1512->vsynctime--;
  56.515 +                        if (!pc1512->vsynctime)
  56.516 +                           pc1512->stat &= ~8;
  56.517                  }
  56.518 -                if (sc==(crtc[11]&31)) { con=0; coff=1; }
  56.519 -                if (vadj)
  56.520 +                if (pc1512->sc == (pc1512->crtc[11] & 31)) 
  56.521 +                { 
  56.522 +                        pc1512->con = 0; 
  56.523 +                        pc1512->coff = 1; 
  56.524 +                }
  56.525 +                if (pc1512->vadj)
  56.526                  {
  56.527 -                        sc++;
  56.528 -                        sc&=31;
  56.529 -                        ma=maback;
  56.530 -                        vadj--;
  56.531 -                        if (!vadj)
  56.532 +                        pc1512->sc++;
  56.533 +                        pc1512->sc &= 31;
  56.534 +                        pc1512->ma = pc1512->maback;
  56.535 +                        pc1512->vadj--;
  56.536 +                        if (!pc1512->vadj)
  56.537                          {
  56.538 -                                cgadispon=1;
  56.539 -                                ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
  56.540 -                                sc=0;
  56.541 +                                pc1512->dispon = 1;
  56.542 +                                pc1512->ma = pc1512->maback = (pc1512->crtc[13] | (pc1512->crtc[12] << 8)) & 0x3fff;
  56.543 +                                pc1512->sc = 0;
  56.544                          }
  56.545                  }
  56.546 -                else if (sc==crtc[9])
  56.547 +                else if (pc1512->sc == pc1512->crtc[9])
  56.548                  {
  56.549 -                        maback=ma;
  56.550 -                        sc=0;
  56.551 -                        oldvc=vc;
  56.552 -                        vc++;
  56.553 -                        vc&=127;
  56.554 +                        pc1512->maback = pc1512->ma;
  56.555 +                        pc1512->sc = 0;
  56.556 +                        oldvc = pc1512->vc;
  56.557 +                        pc1512->vc++;
  56.558 +                        pc1512->vc &= 127;
  56.559  
  56.560 -                        if (displine == 32)//oldvc == (cgamode & 2) ? 127 : 31)
  56.561 +                        if (pc1512->displine == 32)//oldvc == (cgamode & 2) ? 127 : 31)
  56.562                          {
  56.563 -                                vc=0;
  56.564 -                                vadj=6;
  56.565 -                                if ((crtc[10]&0x60)==0x20) cursoron=0;
  56.566 -                                else                       cursoron=cgablink&16;
  56.567 +                                pc1512->vc = 0;
  56.568 +                                pc1512->vadj = 6;
  56.569 +                                if ((pc1512->crtc[10] & 0x60) == 0x20) pc1512->cursoron = 0;
  56.570 +                                else                                   pc1512->cursoron = pc1512->blink & 16;
  56.571                          }
  56.572  
  56.573 -                        if (displine >= 262)//vc == (cgamode & 2) ? 111 : 27)
  56.574 +                        if (pc1512->displine >= 262)//vc == (cgamode & 2) ? 111 : 27)
  56.575                          {
  56.576 -                                cgadispon=0;
  56.577 -                                displine=0;
  56.578 -                                vsynctime=46;
  56.579 +                                pc1512->dispon = 0;
  56.580 +                                pc1512->displine = 0;
  56.581 +                                pc1512->vsynctime = 46;
  56.582  
  56.583 -                                        if (cgamode&1) x=(crtc[1]<<3)+16;
  56.584 -                                        else           x=(crtc[1]<<4)+16;
  56.585 -                                        x = 640 + 16;
  56.586 -                                        lastline++;
  56.587 -                                        if (x!=xsize || (lastline-firstline)!=ysize)
  56.588 -                                        {
  56.589 -                                                xsize=x;
  56.590 -                                                ysize=lastline-firstline;
  56.591 -                                                if (xsize<64) xsize=656;
  56.592 -                                                if (ysize<32) ysize=200;
  56.593 -                                                updatewindowsize(xsize,(ysize<<1)+16);
  56.594 -                                        }
  56.595 +                                if (pc1512->cgamode&1) x = (pc1512->crtc[1] << 3) + 16;
  56.596 +                                else                   x = (pc1512->crtc[1] << 4) + 16;
  56.597 +                                x = 640 + 16;
  56.598 +                                pc1512->lastline++;
  56.599 +                                
  56.600 +                                if (x != xsize || (pc1512->lastline - pc1512->firstline) != ysize)
  56.601 +                                {
  56.602 +                                        xsize = x;
  56.603 +                                        ysize = pc1512->lastline - pc1512->firstline;
  56.604 +                                        if (xsize < 64) xsize = 656;
  56.605 +                                        if (ysize < 32) ysize = 200;
  56.606 +                                        updatewindowsize(xsize, (ysize << 1) + 16);
  56.607 +                                }
  56.608  startblit();
  56.609 -                                        video_blit_memtoscreen_8(0, firstline - 4, xsize, (lastline - firstline) + 8);
  56.610 +                                video_blit_memtoscreen_8(0, pc1512->firstline - 4, xsize, (pc1512->lastline - pc1512->firstline) + 8);
  56.611  //                                        blit(buffer,vbuf,0,firstline-4,0,0,xsize,(lastline-firstline)+8+1);
  56.612  //                                        if (vid_resize) stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,winsizex,winsizey);
  56.613  //                                        else            stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,xsize,((lastline-firstline)<<1)+16+2);
  56.614  //                                        if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
  56.615  //                                        readflash=0;
  56.616  endblit();
  56.617 -                                        video_res_x = xsize - 16;
  56.618 -                                        video_res_y = ysize;
  56.619 -                                        if (cgamode & 1)
  56.620 -                                        {
  56.621 -                                                video_res_x /= 8;
  56.622 -                                                video_res_y /= crtc[9] + 1;
  56.623 -                                                video_bpp = 0;
  56.624 -                                        }
  56.625 -                                        else if (!(cgamode & 2))
  56.626 -                                        {
  56.627 -                                                video_res_x /= 16;
  56.628 -                                                video_res_y /= crtc[9] + 1;
  56.629 -                                                video_bpp = 0;
  56.630 -                                        }
  56.631 -                                        else if (!(cgamode&16))
  56.632 -                                        {
  56.633 -                                                video_res_x /= 2;
  56.634 -                                                video_bpp = 2;
  56.635 -                                        }
  56.636 -                                        else
  56.637 -                                        {
  56.638 -                                                video_bpp = 4;
  56.639 -                                        }
  56.640 +                                video_res_x = xsize - 16;
  56.641 +                                video_res_y = ysize;
  56.642 +                                if (pc1512->cgamode & 1)
  56.643 +                                {
  56.644 +                                        video_res_x /= 8;
  56.645 +                                        video_res_y /= pc1512->crtc[9] + 1;
  56.646 +                                        video_bpp = 0;
  56.647 +                                }
  56.648 +                                else if (!(pc1512->cgamode & 2))
  56.649 +                                {
  56.650 +                                        video_res_x /= 16;
  56.651 +                                        video_res_y /= pc1512->crtc[9] + 1;
  56.652 +                                        video_bpp = 0;
  56.653 +                                }
  56.654 +                                else if (!(pc1512->cgamode & 16))
  56.655 +                                {
  56.656 +                                        video_res_x /= 2;
  56.657 +                                        video_bpp = 2;
  56.658 +                                }
  56.659 +                                else
  56.660 +                                {
  56.661 +                                        video_bpp = 4;
  56.662 +                                }
  56.663  
  56.664 -                                firstline=1000;
  56.665 -                                lastline=0;
  56.666 -                                cgablink++;
  56.667 +                                pc1512->firstline = 1000;
  56.668 +                                pc1512->lastline = 0;
  56.669 +                                pc1512->blink++;
  56.670                          }
  56.671                  }
  56.672                  else
  56.673                  {
  56.674 -                        sc++;
  56.675 -                        sc&=31;
  56.676 -                        ma=maback;
  56.677 +                        pc1512->sc++;
  56.678 +                        pc1512->sc &= 31;
  56.679 +                        pc1512->ma = pc1512->maback;
  56.680                  }
  56.681 -                if (sc==(crtc[10]&31)) con=1;
  56.682 +                if (pc1512->sc == (pc1512->crtc[10] & 31)) 
  56.683 +                        pc1512->con = 1;
  56.684          }
  56.685  }
  56.686  
  56.687 -int pc1512_init()
  56.688 +static void *pc1512_init()
  56.689  {
  56.690 -        mem_sethandler(0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL,  NULL);
  56.691 -        return 0;
  56.692 +        int c;
  56.693 +        pc1512_t *pc1512 = malloc(sizeof(pc1512_t));
  56.694 +        memset(pc1512, 0, sizeof(pc1512_t));
  56.695 +
  56.696 +        pc1512->vram = malloc(0x10000);
  56.697 +        
  56.698 +        pc1512->cgacol = 7;
  56.699 +        pc1512->cgamode = 0x12;
  56.700 +                
  56.701 +        timer_add(pc1512_poll, &pc1512->vidtime, TIMER_ALWAYS_ENABLED, pc1512);
  56.702 +        mem_sethandler(0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL,  pc1512);
  56.703 +        io_sethandler(0x03d0, 0x0010, pc1512_in, NULL, NULL, pc1512_out, NULL, NULL, pc1512);
  56.704 +        return pc1512;
  56.705  }
  56.706  
  56.707 -GFXCARD vid_pc1512 =
  56.708 +static void pc1512_close(void *p)
  56.709  {
  56.710 +        pc1512_t *pc1512 = (pc1512_t *)p;
  56.711 +
  56.712 +        free(pc1512->vram);
  56.713 +        free(pc1512);
  56.714 +}
  56.715 +
  56.716 +static void pc1512_speed_changed(void *p)
  56.717 +{
  56.718 +        pc1512_t *pc1512 = (pc1512_t *)p;
  56.719 +        
  56.720 +        pc1512_recalctimings(pc1512);
  56.721 +}
  56.722 +
  56.723 +device_t pc1512_device =
  56.724 +{
  56.725 +        "Amstrad PC1512 (video)",
  56.726          pc1512_init,
  56.727 -        /*IO at 3Cx/3Dx*/
  56.728 -        pc1512_out,
  56.729 -        pc1512_in,
  56.730 -        /*IO at 3Ax/3Bx*/
  56.731 -        video_out_null,
  56.732 -        video_in_null,
  56.733 -
  56.734 -        pc1512_poll,
  56.735 -        pc1512_recalctimings,
  56.736 -
  56.737 -        video_write_null,
  56.738 -        video_write_null,
  56.739 -        pc1512_write,
  56.740 -
  56.741 -        video_read_null,
  56.742 -        video_read_null,
  56.743 -        pc1512_read
  56.744 +        pc1512_close,
  56.745 +        pc1512_speed_changed,
  56.746 +        NULL
  56.747  };
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/src/vid_pc1512.h	Mon Jun 24 20:42:35 2013 +0100
    57.3 @@ -0,0 +1,1 @@
    57.4 +extern device_t pc1512_device;
    58.1 --- a/src/vid_pc1640.c	Tue Jun 04 20:52:17 2013 +0100
    58.2 +++ b/src/vid_pc1640.c	Mon Jun 24 20:42:35 2013 +0100
    58.3 @@ -1,99 +1,145 @@
    58.4  /*PC1640 video emulation.
    58.5    Mostly standard EGA, but with CGA & Hercules emulation*/
    58.6 +#include <stdlib.h>
    58.7  #include "ibm.h"
    58.8 +#include "device.h"
    58.9  #include "io.h"
   58.10  #include "mem.h"
   58.11 +#include "timer.h"
   58.12  #include "video.h"
   58.13  #include "vid_cga.h"
   58.14  #include "vid_ega.h"
   58.15 +#include "vid_pc1640.h"
   58.16  
   58.17 -static int pc1640_cga=1;
   58.18 +typedef struct pc1640_t
   58.19 +{
   58.20 +        cga_t cga;
   58.21 +        ega_t ega;
   58.22 +        
   58.23 +        int cga_enabled;
   58.24 +        int dispontime, dispofftime, vidtime;
   58.25 +} pc1640_t;
   58.26  
   58.27 -void pc1640_out(uint16_t addr, uint8_t val, void *priv)
   58.28 +void pc1640_out(uint16_t addr, uint8_t val, void *p)
   58.29  {
   58.30 +        pc1640_t *pc1640 = (pc1640_t *)p;
   58.31 +        
   58.32          switch (addr)
   58.33          {
   58.34 -                case 0x3DB:
   58.35 -                pc1640_cga=val&0x40;
   58.36 -                mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL,  NULL);
   58.37 -                mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  NULL);
   58.38 -                if (pc1640_cga)
   58.39 -                   mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  NULL);
   58.40 +                case 0x3db:
   58.41 +                pc1640->cga_enabled = val & 0x40;
   58.42 +                mem_removehandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL,  &pc1640->ega);
   58.43 +                mem_removehandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  &pc1640->cga);
   58.44 +                if (pc1640->cga_enabled)
   58.45 +                   mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  &pc1640->cga);
   58.46                  else
   58.47                  {                
   58.48 -                        switch (gdcreg[6] & 0xC)
   58.49 +                        switch (pc1640->ega.gdcreg[6] & 0xc)
   58.50                          {
   58.51                                  case 0x0: /*128k at A0000*/
   58.52 -                                mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL,  NULL);
   58.53 +                                mem_sethandler(0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL,  &pc1640->ega);
   58.54                                  break;
   58.55                                  case 0x4: /*64k at A0000*/
   58.56 -                                mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL,  NULL);
   58.57 +                                mem_sethandler(0xa0000, 0x10000, ega_read, NULL, NULL, ega_write, NULL, NULL,  &pc1640->ega);
   58.58                                  break;
   58.59                                  case 0x8: /*32k at B0000*/
   58.60 -                                mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL,  NULL);
   58.61 +                                mem_sethandler(0xb0000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL,  &pc1640->ega);
   58.62                                  break;
   58.63                                  case 0xC: /*32k at B8000*/
   58.64 -                                mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL,  NULL);
   58.65 +                                mem_sethandler(0xb8000, 0x08000, ega_read, NULL, NULL, ega_write, NULL, NULL,  &pc1640->ega);
   58.66                                  break;
   58.67                          }
   58.68                  }                
   58.69                  pclog("3DB write %02X\n", val);
   58.70                  return;
   58.71          }
   58.72 -        if (pc1640_cga) cga_out(addr, val, NULL);
   58.73 -        else            ega_out(addr, val, NULL);
   58.74 +        if (pc1640->cga_enabled) cga_out(addr, val, &pc1640->cga);
   58.75 +        else                     ega_out(addr, val, &pc1640->ega);
   58.76  }
   58.77  
   58.78 -uint8_t pc1640_in(uint16_t addr, void *priv)
   58.79 +uint8_t pc1640_in(uint16_t addr, void *p)
   58.80  {
   58.81 +        pc1640_t *pc1640 = (pc1640_t *)p;
   58.82 +        
   58.83          switch (addr)
   58.84          {
   58.85          }
   58.86 -        if (pc1640_cga) return cga_in(addr, NULL);
   58.87 -        else            return ega_in(addr, NULL);
   58.88 +        
   58.89 +        if (pc1640->cga_enabled) return cga_in(addr, &pc1640->cga);
   58.90 +        else                     return ega_in(addr, &pc1640->ega);
   58.91  }
   58.92  
   58.93 -void pc1640_recalctimings()
   58.94 +void pc1640_recalctimings(pc1640_t *pc1640)
   58.95  {
   58.96 -        if (pc1640_cga) cga_recalctimings();
   58.97 -        else            ega_recalctimings();
   58.98 +        if (pc1640->cga_enabled) 
   58.99 +        {
  58.100 +                cga_recalctimings(&pc1640->cga);
  58.101 +                pc1640->dispontime  = pc1640->cga.dispontime;
  58.102 +                pc1640->dispofftime = pc1640->cga.dispofftime;
  58.103 +        }
  58.104 +        else            
  58.105 +        {
  58.106 +                ega_recalctimings(&pc1640->ega);
  58.107 +                pc1640->dispontime  = pc1640->ega.dispontime;
  58.108 +                pc1640->dispofftime = pc1640->ega.dispofftime;
  58.109 +        }
  58.110  }
  58.111  
  58.112 -void pc1640_poll()
  58.113 +void pc1640_poll(void *p)
  58.114  {
  58.115 -        if (pc1640_cga) cga_poll();
  58.116 -        else            ega_poll();
  58.117 +        pc1640_t *pc1640 = (pc1640_t *)p;
  58.118 +        if (pc1640->cga_enabled) 
  58.119 +        {
  58.120 +                pc1640->cga.vidtime = pc1640->vidtime;
  58.121 +                cga_poll(&pc1640->cga);
  58.122 +                pc1640->vidtime = pc1640->cga.vidtime;
  58.123 +        }
  58.124 +        else                     
  58.125 +        {
  58.126 +                pc1640->ega.vidtime = pc1640->vidtime;
  58.127 +                ega_poll(&pc1640->ega);
  58.128 +                pc1640->vidtime = pc1640->ega.vidtime;
  58.129 +        }
  58.130  }
  58.131  
  58.132 -int pc1640_init()
  58.133 +void *pc1640_init()
  58.134  {
  58.135 -        int r = ega_init();
  58.136 -        
  58.137 -        pc1640_cga = 1;
  58.138 -        
  58.139 -        mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  NULL);
  58.140 -        
  58.141 -        return r;
  58.142 +        pc1640_t *pc1640 = malloc(sizeof(pc1640_t));
  58.143 +        cga_t *cga = &pc1640->cga;
  58.144 +        ega_t *ega = &pc1640->ega;
  58.145 +        memset(pc1640, 0, sizeof(pc1640_t));
  58.146 +
  58.147 +        ega_init(&pc1640->ega);
  58.148 +        pc1640->cga.vram = pc1640->ega.vram;
  58.149 +        pc1640->cga_enabled = 1;
  58.150 +        cga_init(&pc1640->cga);
  58.151 +                        
  58.152 +        timer_add(pc1640_poll, &pc1640->vidtime, TIMER_ALWAYS_ENABLED, pc1640);
  58.153 +        mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  cga);
  58.154 +        io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640);
  58.155 +        return cga;
  58.156  }
  58.157  
  58.158 -GFXCARD vid_pc1640 =
  58.159 +void pc1640_close(void *p)
  58.160  {
  58.161 +        pc1640_t *pc1640 = (pc1640_t *)p;
  58.162 +
  58.163 +        free(pc1640->ega.vram);
  58.164 +        free(pc1640);
  58.165 +}
  58.166 +
  58.167 +void pc1640_speed_changed(void *p)
  58.168 +{
  58.169 +        pc1640_t *pc1640 = (pc1640_t *)p;
  58.170 +        
  58.171 +        pc1640_recalctimings(pc1640);
  58.172 +}
  58.173 +
  58.174 +device_t pc1640_device =
  58.175 +{
  58.176 +        "Amstrad PC1640 (video)",
  58.177          pc1640_init,
  58.178 -        /*IO at 3Cx/3Dx*/
  58.179 -        pc1640_out,
  58.180 -        pc1640_in,
  58.181 -        /*IO at 3Ax/3Bx*/
  58.182 -        video_out_null,
  58.183 -        video_in_null,
  58.184 -
  58.185 -        pc1640_poll,
  58.186 -        pc1640_recalctimings,
  58.187 -
  58.188 -        ega_write,
  58.189 -        video_write_null,
  58.190 -        video_write_null,
  58.191 -
  58.192 -        ega_read,
  58.193 -        video_read_null,
  58.194 -        video_read_null
  58.195 +        pc1640_close,
  58.196 +        pc1640_speed_changed,
  58.197 +        NULL
  58.198  };
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/src/vid_pc1640.h	Mon Jun 24 20:42:35 2013 +0100
    59.3 @@ -0,0 +1,1 @@
    59.4 +extern device_t pc1640_device;
    60.1 --- a/src/vid_pc200.c	Tue Jun 04 20:52:17 2013 +0100
    60.2 +++ b/src/vid_pc200.c	Mon Jun 24 20:42:35 2013 +0100
    60.3 @@ -1,104 +1,139 @@
    60.4  /*PC200 video emulation.
    60.5    CGA with some NMI stuff. But we don't need that as it's only used for TV and
    60.6    LCD displays, and we're emulating a CRT*/
    60.7 +#include <stdlib.h>
    60.8  #include "ibm.h"
    60.9 +#include "device.h"
   60.10  #include "io.h"
   60.11  #include "mem.h"
   60.12 +#include "timer.h"
   60.13  #include "video.h"
   60.14  #include "vid_cga.h"
   60.15 +#include "vid_pc200.h"
   60.16  
   60.17 -uint8_t pc200_3dd, pc200_3de, pc200_3df;
   60.18 +typedef struct pc200_t
   60.19 +{
   60.20 +        cga_t cga;
   60.21  
   60.22 -void pc200_out(uint16_t addr, uint8_t val, void *priv)
   60.23 +        uint8_t reg_3dd, reg_3de, reg_3df;
   60.24 +} pc200_t;
   60.25 +
   60.26 +static uint8_t crtcmask[32] = 
   60.27  {
   60.28 +        0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
   60.29 +        0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   60.30 +};
   60.31 +
   60.32 +void pc200_out(uint16_t addr, uint8_t val, void *p)
   60.33 +{
   60.34 +        pc200_t *pc200 = (pc200_t *)p;
   60.35 +        cga_t *cga = &pc200->cga;
   60.36          uint8_t old;
   60.37 +        
   60.38          switch (addr)
   60.39          {
   60.40 -                case 0x3D5:
   60.41 -                if (!(pc200_3de&0x40) && crtcreg<=11)
   60.42 +                case 0x3d5:
   60.43 +                if (!(pc200->reg_3de & 0x40) && cga->crtcreg <= 11)
   60.44                  {
   60.45 -                        if (pc200_3de&0x80) nmi=1;
   60.46 -                        pc200_3dd=0x20|(crtcreg&0x1F);
   60.47 -                        pc200_3df=val;
   60.48 +                        if (pc200->reg_3de & 0x80) 
   60.49 +                                nmi = 1;
   60.50 +                                
   60.51 +                        pc200->reg_3dd = 0x20 | (cga->crtcreg & 0x1f);
   60.52 +                        pc200->reg_3df = val;
   60.53                          return;
   60.54                  }
   60.55 -                old=crtc[crtcreg];
   60.56 -                crtc[crtcreg]=val&crtcmask[crtcreg];
   60.57 -                if (old!=val)
   60.58 +                old = cga->crtc[cga->crtcreg];
   60.59 +                cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
   60.60 +                if (old != val)
   60.61                  {
   60.62 -                        if (crtcreg<0xE || crtcreg>0x10)
   60.63 +                        if (cga->crtcreg < 0xe || cga->crtcreg > 0x10)
   60.64                          {
   60.65 -                                fullchange=changeframecount;
   60.66 -                                cga_recalctimings();
   60.67 +                                fullchange = changeframecount;
   60.68 +                                cga_recalctimings(cga);
   60.69                          }
   60.70                  }
   60.71                  return;
   60.72                  
   60.73 -                case 0x3D8:
   60.74 -                old = cgamode;
   60.75 -                cgamode=val;
   60.76 -                if ((cgamode ^ old) & 3)
   60.77 -                   cga_recalctimings();
   60.78 -                pc200_3dd|=0x80;
   60.79 -                if (pc200_3de&0x80)
   60.80 -                   nmi=1;
   60.81 +                case 0x3d8:
   60.82 +                old = cga->cgamode;
   60.83 +                cga->cgamode = val;
   60.84 +                if ((cga->cgamode ^ old) & 3)
   60.85 +                   cga_recalctimings(cga);
   60.86 +                pc200->reg_3dd |= 0x80;
   60.87 +                if (pc200->reg_3de & 0x80)
   60.88 +                   nmi = 1;
   60.89                  return;
   60.90                  
   60.91 -                case 0x3DE:
   60.92 -                pc200_3de=val;
   60.93 -                pc200_3dd=0x1F;
   60.94 -                if (val&0x80) pc200_3dd|=0x40;
   60.95 +                case 0x3de:
   60.96 +                pc200->reg_3de = val;
   60.97 +                pc200->reg_3dd = 0x1f;
   60.98 +                if (val & 0x80) 
   60.99 +                        pc200->reg_3dd |= 0x40;
  60.100                  return;
  60.101          }
  60.102 -        cga_out(addr, val, NULL);
  60.103 +        cga_out(addr, val, cga);
  60.104  }
  60.105  
  60.106 -uint8_t pc200_in(uint16_t addr, void *priv)
  60.107 +uint8_t pc200_in(uint16_t addr, void *p)
  60.108  {
  60.109 +        pc200_t *pc200 = (pc200_t *)p;
  60.110 +        cga_t *cga = &pc200->cga;
  60.111          uint8_t temp;
  60.112 +
  60.113          switch (addr)
  60.114          {
  60.115                  case 0x3D8:
  60.116 -                return cgamode;
  60.117 +                return cga->cgamode;
  60.118                  
  60.119                  case 0x3DD:
  60.120 -                temp = pc200_3dd;
  60.121 -                pc200_3dd &= 0x1F;
  60.122 +                temp = pc200->reg_3dd;
  60.123 +                pc200->reg_3dd &= 0x1f;
  60.124                  return temp;
  60.125                  
  60.126                  case 0x3DE:
  60.127 -                return (pc200_3de&0xC7)| 0x18; /*External CGA*/
  60.128 +                return (pc200->reg_3de & 0xc7) | 0x18; /*External CGA*/
  60.129                  
  60.130                  case 0x3DF:
  60.131 -                return pc200_3df;
  60.132 +                return pc200->reg_3df;
  60.133          }
  60.134 -        return cga_in(addr, NULL);
  60.135 +        return cga_in(addr, cga);
  60.136  }
  60.137  
  60.138 -int pc200_init()
  60.139 +void *pc200_init()
  60.140  {
  60.141 -        mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  NULL);
  60.142 -        return cga_init();
  60.143 +        pc200_t *pc200 = malloc(sizeof(pc200_t));
  60.144 +        cga_t *cga = &pc200->cga;
  60.145 +        memset(pc200, 0, sizeof(pc200_t));
  60.146 +
  60.147 +        pc200->cga.vram = malloc(0x4000);
  60.148 +        cga_init(&pc200->cga);
  60.149 +                        
  60.150 +        timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
  60.151 +        mem_sethandler(0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  cga);
  60.152 +        io_sethandler(0x03d0, 0x0010, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200);
  60.153 +        return cga;
  60.154  }
  60.155  
  60.156 -GFXCARD vid_pc200 =
  60.157 +void pc200_close(void *p)
  60.158  {
  60.159 +        pc200_t *pc200 = (pc200_t *)p;
  60.160 +
  60.161 +        free(pc200->cga.vram);
  60.162 +        free(pc200);
  60.163 +}
  60.164 +
  60.165 +void pc200_speed_changed(void *p)
  60.166 +{
  60.167 +        pc200_t *pc200 = (pc200_t *)p;
  60.168 +        
  60.169 +        cga_recalctimings(&pc200->cga);
  60.170 +}
  60.171 +
  60.172 +device_t pc200_device =
  60.173 +{
  60.174 +        "Amstrad PC200 (video)",
  60.175          pc200_init,
  60.176 -        /*IO at 3Cx/3Dx*/
  60.177 -        pc200_out,
  60.178 -        pc200_in,
  60.179 -        /*IO at 3Ax/3Bx*/
  60.180 -        video_out_null,
  60.181 -        video_in_null,
  60.182 -
  60.183 -        cga_poll,
  60.184 -        cga_recalctimings,
  60.185 -
  60.186 -        video_write_null,
  60.187 -        video_write_null,
  60.188 -        cga_write,
  60.189 -
  60.190 -        video_read_null,
  60.191 -        video_read_null,
  60.192 -        cga_read
  60.193 +        pc200_close,
  60.194 +        pc200_speed_changed,
  60.195 +        NULL
  60.196  };
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/src/vid_pc200.h	Mon Jun 24 20:42:35 2013 +0100
    61.3 @@ -0,0 +1,1 @@
    61.4 +extern device_t pc200_device;
    62.1 --- a/src/vid_s3.c	Tue Jun 04 20:52:17 2013 +0100
    62.2 +++ b/src/vid_s3.c	Mon Jun 24 20:42:35 2013 +0100
    62.3 @@ -1,120 +1,172 @@
    62.4  /*S3 emulation*/
    62.5 +#include <stdlib.h>
    62.6  #include "ibm.h"
    62.7 +#include "device.h"
    62.8  #include "io.h"
    62.9  #include "mem.h"
   62.10  #include "pci.h"
   62.11  #include "video.h"
   62.12 +#include "vid_s3.h"
   62.13  #include "vid_svga.h"
   62.14  #include "vid_svga_render.h"
   62.15  #include "vid_sdac_ramdac.h"
   62.16  
   62.17 +typedef struct s3_t
   62.18 +{
   62.19 +        svga_t svga;
   62.20 +        sdac_ramdac_t ramdac;
   62.21 +
   62.22 +        uint8_t bank;
   62.23 +        uint8_t ma_ext;
   62.24 +        int width;
   62.25 +        int bpp;
   62.26 +
   62.27 +        uint8_t id, id_ext;
   62.28 +
   62.29 +        uint32_t linear_base, linear_size;
   62.30 +
   62.31 +        struct
   62.32 +        {
   62.33 +                uint8_t subsys_cntl;
   62.34 +                uint8_t setup_md;
   62.35 +                uint8_t advfunc_cntl;
   62.36 +                uint16_t cur_y;
   62.37 +                uint16_t cur_x;
   62.38 +                 int16_t desty_axstp;
   62.39 +                 int16_t destx_distp;
   62.40 +                 int16_t err_term;
   62.41 +                 int16_t maj_axis_pcnt;
   62.42 +                uint16_t cmd;
   62.43 +                uint16_t short_stroke;
   62.44 +                uint32_t bkgd_color;
   62.45 +                uint32_t frgd_color;
   62.46 +                uint32_t wrt_mask;
   62.47 +                uint32_t rd_mask;
   62.48 +                uint32_t color_cmp;
   62.49 +                uint8_t bkgd_mix;
   62.50 +                uint8_t frgd_mix;
   62.51 +                uint16_t multifunc_cntl;
   62.52 +                uint16_t multifunc[16];
   62.53 +                uint8_t pix_trans[4];
   62.54 +        
   62.55 +                int cx, cy;
   62.56 +                int sx, sy;
   62.57 +                int dx, dy;
   62.58 +                uint32_t src, dest, pattern;
   62.59 +                int pix_trans_count;
   62.60 +        
   62.61 +                uint32_t dat_buf;
   62.62 +                int dat_count;
   62.63 +        } accel;
   62.64 +} s3_t;
   62.65 +
   62.66  void s3_updatemapping();
   62.67  
   62.68 -void s3_accel_write(uint32_t addr, uint8_t val, void *priv);
   62.69 -void s3_accel_write_w(uint32_t addr, uint16_t val, void *priv);
   62.70 -void s3_accel_write_l(uint32_t addr, uint32_t val, void *priv);
   62.71 -uint8_t s3_accel_read(uint32_t addr, void *priv);
   62.72 +void s3_accel_write(uint32_t addr, uint8_t val, void *p);
   62.73 +void s3_accel_write_w(uint32_t addr, uint16_t val, void *p);
   62.74 +void s3_accel_write_l(uint32_t addr, uint32_t val, void *p);
   62.75 +uint8_t s3_accel_read(uint32_t addr, void *p);
   62.76  
   62.77 -static uint8_t s3_bank;
   62.78 -static uint8_t s3_ma_ext;
   62.79 -static int s3_width = 1024;
   62.80 -static int s3_bpp = 0;
   62.81  
   62.82 -static uint8_t s3_id, s3_id_ext;
   62.83 -
   62.84 -void s3_out(uint16_t addr, uint8_t val, void *priv)
   62.85 +void s3_out(uint16_t addr, uint8_t val, void *p)
   62.86  {
   62.87 +        s3_t *s3 = (s3_t *)p;
   62.88 +        svga_t *svga = &s3->svga;
   62.89          uint8_t old;
   62.90  
   62.91 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   62.92 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
   62.93 +                addr ^= 0x60;
   62.94          
   62.95  //        pclog("S3 out %04X %02X\n", addr, val);
   62.96  
   62.97          switch (addr)
   62.98          {
   62.99                  case 0x3c5:
  62.100 -                if (seqaddr == 4) /*Chain-4 - update banking*/
  62.101 +                if (svga->seqaddr == 4) /*Chain-4 - update banking*/
  62.102                  {
  62.103 -                        if (val & 8) svgawbank = svgarbank = s3_bank << 16;
  62.104 -                        else         svgawbank = svgarbank = s3_bank << 14;
  62.105 +                        if (val & 8) svga->write_bank = svga->read_bank = s3->bank << 16;
  62.106 +                        else         svga->write_bank = svga->read_bank = s3->bank << 14;
  62.107                  }
  62.108                  break;
  62.109                  
  62.110                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  62.111  //                pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc);
  62.112 -                sdac_ramdac_out(addr, val, NULL);
  62.113 +                sdac_ramdac_out(addr, val, &s3->ramdac, svga);
  62.114                  return;
  62.115  
  62.116                  case 0x3D4:
  62.117 -                crtcreg=val&0x7f;
  62.118 +                svga->crtcreg = val & 0x7f;
  62.119                  return;
  62.120                  case 0x3D5:
  62.121  //                        if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val);
  62.122 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
  62.123 -                if (crtcreg >= 0x20 && crtcreg != 0x38 && (crtc[0x38] & 0xcc) != 0x48) return;
  62.124 -                old=crtc[crtcreg];
  62.125 -                crtc[crtcreg]=val;
  62.126 -                switch (crtcreg)
  62.127 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
  62.128 +                if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) return;
  62.129 +                old = svga->crtc[svga->crtcreg];
  62.130 +                svga->crtc[svga->crtcreg] = val;
  62.131 +                switch (svga->crtcreg)
  62.132                  {
  62.133                          case 0x31:
  62.134 -                        s3_ma_ext = (s3_ma_ext & 0x1c) | ((val & 0x30) >> 4);
  62.135 -                        vrammask = (val & 8) ? 0x3fffff : 0x3ffff;
  62.136 +                        s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4);
  62.137 +                        svga->vrammask = (val & 8) ? 0x3fffff : 0x3ffff;
  62.138                          break;
  62.139                          
  62.140                          case 0x50:
  62.141 -                        switch (crtc[0x50] & 0xc1)
  62.142 +                        switch (svga->crtc[0x50] & 0xc1)
  62.143                          {
  62.144 -                                case 0x00: s3_width = (crtc[0x31] & 2) ? 2048 : 1024; break;
  62.145 -                                case 0x01: s3_width = 1152; break;
  62.146 -                                case 0x40: s3_width = 640;  break;
  62.147 -                                case 0x80: s3_width = 800;  break;
  62.148 -                                case 0x81: s3_width = 1600; break;
  62.149 -                                case 0xc0: s3_width = 1280; break;
  62.150 +                                case 0x00: s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; break;
  62.151 +                                case 0x01: s3->width = 1152; break;
  62.152 +                                case 0x40: s3->width = 640;  break;
  62.153 +                                case 0x80: s3->width = 800;  break;
  62.154 +                                case 0x81: s3->width = 1600; break;
  62.155 +                                case 0xc0: s3->width = 1280; break;
  62.156                          }
  62.157 -                        s3_bpp = (crtc[0x50] >> 4) & 3;
  62.158 +                        s3->bpp = (svga->crtc[0x50] >> 4) & 3;
  62.159                          break;
  62.160                          case 0x69:
  62.161 -                        s3_ma_ext = val & 0x1f;
  62.162 +                        s3->ma_ext = val & 0x1f;
  62.163                          break;
  62.164                          
  62.165                          case 0x35:
  62.166 -                        s3_bank = (s3_bank & 0x70) | (val & 0xf);
  62.167 +                        s3->bank = (s3->bank & 0x70) | (val & 0xf);
  62.168  //                        pclog("CRTC write R35 %02X\n", val);
  62.169 -                        if (chain4) svgawbank = svgarbank = s3_bank << 16;
  62.170 -                        else        svgawbank = svgarbank = s3_bank << 14;
  62.171 +                        if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16;
  62.172 +                        else              svga->write_bank = svga->read_bank = s3->bank << 14;
  62.173                          break;
  62.174                          case 0x51:
  62.175 -                        s3_bank = (s3_bank & 0x4f) | ((val & 0xc) << 2);
  62.176 -                        if (chain4) svgawbank = svgarbank = s3_bank << 16;
  62.177 -                        else        svgawbank = svgarbank = s3_bank << 14;
  62.178 -                        s3_ma_ext = (s3_ma_ext & ~0xc) | ((val & 3) << 2);
  62.179 +                        s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2);
  62.180 +                        if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16;
  62.181 +                        else              svga->write_bank = svga->read_bank = s3->bank << 14;
  62.182 +                        s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2);
  62.183                          break;
  62.184                          case 0x6a:
  62.185 -                        s3_bank = val;
  62.186 +                        s3->bank = val;
  62.187  //                        pclog("CRTC write R6a %02X\n", val);
  62.188 -                        if (chain4) svgawbank = svgarbank = s3_bank << 16;
  62.189 -                        else        svgawbank = svgarbank = s3_bank << 14;
  62.190 +                        if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16;
  62.191 +                        else              svga->write_bank = svga->read_bank = s3->bank << 14;
  62.192                          break;
  62.193                          
  62.194                          case 0x3a:
  62.195 -                        if (val & 0x10) gdcreg[5] |= 0x40; /*Horrible cheat*/
  62.196 +                        if (val & 0x10) 
  62.197 +                                svga->gdcreg[5] |= 0x40; /*Horrible cheat*/
  62.198                          break;
  62.199                          
  62.200                          case 0x45:
  62.201 -                        svga_hwcursor.ena = val & 1;
  62.202 +                        svga->hwcursor.ena = val & 1;
  62.203                          break;
  62.204                          case 0x48:
  62.205 -                        svga_hwcursor.x = ((crtc[0x46] << 8) | crtc[0x47]) & 0x7ff;
  62.206 -                        if (bpp == 32) svga_hwcursor.x >>= 1;
  62.207 -                        svga_hwcursor.y = ((crtc[0x48] << 8) | crtc[0x49]) & 0x7ff;
  62.208 -                        svga_hwcursor.xoff = crtc[0x4e] & 63;
  62.209 -                        svga_hwcursor.yoff = crtc[0x4f] & 63;
  62.210 -                        svga_hwcursor.addr = ((((crtc[0x4c] << 8) | crtc[0x4d]) & 0xfff) * 1024) + (svga_hwcursor.yoff * 16);
  62.211 +                        svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff;
  62.212 +                        if (svga->bpp == 32) svga->hwcursor.x >>= 1;
  62.213 +                        svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff;
  62.214 +                        svga->hwcursor.xoff = svga->crtc[0x4e] & 63;
  62.215 +                        svga->hwcursor.yoff = svga->crtc[0x4f] & 63;
  62.216 +                        svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16);
  62.217 +                        if (gfxcard == GFX_N9_9FX && svga->bpp == 32) /*Trio64*/
  62.218 +                                svga->hwcursor.x <<= 1;
  62.219                          break;
  62.220  
  62.221                          case 0x53:
  62.222                          case 0x58: case 0x59: case 0x5a:
  62.223 -                        s3_updatemapping();
  62.224 +                        s3_updatemapping(s3);
  62.225                          break;
  62.226                          
  62.227                          case 0x67:
  62.228 @@ -122,469 +174,456 @@
  62.229                          {
  62.230                                  switch (val >> 4)
  62.231                                  {
  62.232 -                                        case 3:  bpp = 15; break;
  62.233 -                                        case 5:  bpp = 16; break;
  62.234 -                                        case 7:  bpp = 24; break;
  62.235 -                                        case 13: bpp = 32; break;
  62.236 -                                        default: bpp = 8;  break;
  62.237 +                                        case 3:  svga->bpp = 15; break;
  62.238 +                                        case 5:  svga->bpp = 16; break;
  62.239 +                                        case 7:  svga->bpp = 24; break;
  62.240 +                                        case 13: svga->bpp = 32; break;
  62.241 +                                        default: svga->bpp = 8;  break;
  62.242                                  }
  62.243                          }
  62.244                          break;
  62.245                          //case 0x55: case 0x43:
  62.246  //                                pclog("Write CRTC R%02X %02X\n", crtcreg, val);
  62.247                  }
  62.248 -                if (old!=val)
  62.249 +                if (old != val)
  62.250                  {
  62.251 -                        if (crtcreg<0xE || crtcreg>0x10)
  62.252 +                        if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
  62.253                          {
  62.254 -                                fullchange=changeframecount;
  62.255 -                                svga_recalctimings();
  62.256 +                                fullchange = changeframecount;
  62.257 +                                svga_recalctimings(svga);
  62.258                          }
  62.259                  }
  62.260                  break;
  62.261          }
  62.262 -        svga_out(addr, val, NULL);
  62.263 +        svga_out(addr, val, svga);
  62.264  }
  62.265  
  62.266 -uint8_t s3_in(uint16_t addr, void *priv)
  62.267 +uint8_t s3_in(uint16_t addr, void *p)
  62.268  {
  62.269 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  62.270 +        s3_t *s3 = (s3_t *)p;
  62.271 +        svga_t *svga = &s3->svga;
  62.272 +
  62.273 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
  62.274 +                addr ^= 0x60;
  62.275  
  62.276  //        if (addr != 0x3da) pclog("S3 in %04X\n", addr);
  62.277          switch (addr)
  62.278          {
  62.279 -                case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  62.280 +                case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9:
  62.281  //                pclog("Read RAMDAC %04X  %04X:%04X\n", addr, CS, pc);
  62.282 -                return sdac_ramdac_in(addr, NULL);
  62.283 +                return sdac_ramdac_in(addr, &s3->ramdac, svga);
  62.284  
  62.285 -                case 0x3D4:
  62.286 -                return crtcreg;
  62.287 -                case 0x3D5:
  62.288 +                case 0x3d4:
  62.289 +                return svga->crtcreg;
  62.290 +                case 0x3d5:
  62.291  //                pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc);
  62.292 -                switch (crtcreg)
  62.293 +                switch (svga->crtcreg)
  62.294                  {
  62.295 -                        case 0x2d: return 0x88;      /*Extended chip ID*/
  62.296 -                        case 0x2e: return s3_id_ext; /*New chip ID*/
  62.297 -                        case 0x30: return s3_id;     /*Chip ID*/
  62.298 -                        case 0x31: return (crtc[0x31] & 0xcf) | ((s3_ma_ext & 3) << 4);
  62.299 -                        case 0x35: return (crtc[0x35] & 0xf0) | (s3_bank & 0xf);
  62.300 -                        case 0x51: return (crtc[0x51] & 0xf0) | ((s3_bank >> 2) & 0xc) | ((s3_ma_ext >> 2) & 3);
  62.301 -                        case 0x69: return s3_ma_ext;
  62.302 -                        case 0x6a: return s3_bank;
  62.303 +                        case 0x2d: return 0x88;       /*Extended chip ID*/
  62.304 +                        case 0x2e: return s3->id_ext; /*New chip ID*/
  62.305 +                        case 0x30: return s3->id;     /*Chip ID*/
  62.306 +                        case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4);
  62.307 +                        case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf);
  62.308 +                        case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3);
  62.309 +                        case 0x69: return s3->ma_ext;
  62.310 +                        case 0x6a: return s3->bank;
  62.311                  }
  62.312 -                return crtc[crtcreg];
  62.313 +                return svga->crtc[svga->crtcreg];
  62.314          }
  62.315 -        return svga_in(addr, NULL);
  62.316 +        return svga_in(addr, svga);
  62.317  }
  62.318  
  62.319 -void s3_recalctimings()
  62.320 +void s3_recalctimings(svga_t *svga)
  62.321  {
  62.322 +        s3_t *s3 = (s3_t *)svga->p;
  62.323 +        svga->hdisp = svga->hdisp_old;
  62.324 +
  62.325 +        pclog("%i %i\n", svga->hdisp, svga->hdisp_time);
  62.326  //        pclog("recalctimings\n");
  62.327 -        svga_ma |= (s3_ma_ext << 16);
  62.328 +        svga->ma_latch |= (s3->ma_ext << 16);
  62.329  //        pclog("SVGA_MA %08X\n", svga_ma);
  62.330 -        if ((gdcreg[5] & 0x40) && (crtc[0x3a] & 0x10))
  62.331 +        if (svga->crtc[0x5d] & 0x01) svga->htotal     += 0x100;
  62.332 +        if (svga->crtc[0x5d] & 0x02) 
  62.333          {
  62.334 -                switch (bpp)
  62.335 +                svga->hdisp_time += 0x100;
  62.336 +                svga->hdisp += 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8);
  62.337 +        }
  62.338 +        if (svga->crtc[0x5e] & 0x01) svga->vtotal     += 0x400;
  62.339 +        if (svga->crtc[0x5e] & 0x02) svga->dispend    += 0x400;
  62.340 +        if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400;
  62.341 +        if (svga->crtc[0x5e] & 0x40) svga->split      += 0x400;
  62.342 +        if (svga->crtc[0x51] & 0x30)      svga->rowoffset  += (svga->crtc[0x51] & 0x30) << 4;
  62.343 +        else if (svga->crtc[0x43] & 0x04) svga->rowoffset  += 0x100;
  62.344 +        if (!svga->rowoffset) svga->rowoffset = 256;
  62.345 +        svga->interlace = svga->crtc[0x42] & 0x20;
  62.346 +        svga->clock = cpuclock / sdac_getclock((svga->miscout >> 2) & 3, &s3->ramdac);
  62.347 +//        pclog("SVGA_CLOCK = %f  %02X  %f\n", svga_clock, svga_miscout, cpuclock);
  62.348 +        if (svga->bpp > 8) svga->clock /= 2;
  62.349 +
  62.350 +        svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10));
  62.351 +        if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10))
  62.352 +        {
  62.353 +                switch (svga->bpp)
  62.354                  {
  62.355                          case 8: 
  62.356 -                        svga_render = svga_render_8bpp_highres; 
  62.357 +                        svga->render = svga_render_8bpp_highres; 
  62.358                          break;
  62.359                          case 15: 
  62.360 -                        svga_render = svga_render_15bpp_highres; 
  62.361 +                        svga->render = svga_render_15bpp_highres; 
  62.362                          break;
  62.363                          case 16: 
  62.364 -                        svga_render = svga_render_16bpp_highres; 
  62.365 +                        svga->render = svga_render_16bpp_highres; 
  62.366                          break;
  62.367                          case 24: 
  62.368 -                        svga_render = svga_render_24bpp_highres; 
  62.369 +                        svga->render = svga_render_24bpp_highres; 
  62.370                          break;
  62.371 -                        case 32: 
  62.372 -                        svga_render = svga_render_32bpp_highres; 
  62.373 +                        case 32:
  62.374 +                        svga->render = svga_render_32bpp_highres; 
  62.375 +                        if (gfxcard == GFX_N9_9FX) /*Trio64*/
  62.376 +                                svga->hdisp *= 4;
  62.377                          break;
  62.378                  }
  62.379          }
  62.380 -        if (crtc[0x5d] & 0x01) svga_htotal     += 0x100;
  62.381 -        if (crtc[0x5d] & 0x02) svga_hdisp      += 0x100;
  62.382 -        if (crtc[0x5e] & 0x01) svga_vtotal     += 0x400;
  62.383 -        if (crtc[0x5e] & 0x02) svga_dispend    += 0x400;
  62.384 -        if (crtc[0x5e] & 0x10) svga_vsyncstart += 0x400;
  62.385 -        if (crtc[0x5e] & 0x40) svga_split      += 0x400;
  62.386 -        if (crtc[0x51] & 0x30)      svga_rowoffset  += (crtc[0x51] & 0x30) << 4;
  62.387 -        else if (crtc[0x43] & 0x04) svga_rowoffset  += 0x100;
  62.388 -        if (!svga_rowoffset) svga_rowoffset = 256;
  62.389 -        svga_interlace = crtc[0x42] & 0x20;
  62.390 -        svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3);
  62.391 -//        pclog("SVGA_CLOCK = %f  %02X  %f\n", svga_clock, svga_miscout, cpuclock);
  62.392 -        if (bpp > 8) svga_clock /= 2;
  62.393 +
  62.394 +       // if (svga->bpp == 32) svga->hdisp *= 3;
  62.395 +        pclog("svga->hdisp %i %02X %i\n", svga->hdisp, svga->crtc[0x5d], svga->hdisp_time);
  62.396  }
  62.397  
  62.398 -static uint32_t s3_linear_base = 0, s3_linear_size = 0;
  62.399 -void s3_updatemapping()
  62.400 +void s3_updatemapping(s3_t *s3)
  62.401  {
  62.402 -        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);
  62.403 +        svga_t *svga = &s3->svga;
  62.404 +        
  62.405 +        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, svga);
  62.406          
  62.407  //        video_write_a000_w = video_write_a000_l = NULL;
  62.408  
  62.409 -        mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,            NULL);
  62.410 +        mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  62.411 +
  62.412 +        mem_removehandler(0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, s3);
  62.413 +
  62.414  //        pclog("Update mapping - bank %02X ", gdcreg[6] & 0xc);        
  62.415 -        switch (gdcreg[6] & 0xc) /*Banked framebuffer*/
  62.416 +        switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/
  62.417          {
  62.418                  case 0x0: /*128k at A0000*/
  62.419 -                mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  62.420 +                mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  62.421                  break;
  62.422                  case 0x4: /*64k at A0000*/
  62.423 -                mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  62.424 +                mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  62.425                  break;
  62.426                  case 0x8: /*32k at B0000*/
  62.427 -                mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  62.428 +                mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  62.429                  break;
  62.430                  case 0xC: /*32k at B8000*/
  62.431 -                mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,       NULL);
  62.432 +                mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  62.433                  break;
  62.434          }
  62.435          
  62.436  //        pclog("Linear framebuffer %02X ", crtc[0x58] & 0x10);
  62.437 -        if (crtc[0x58] & 0x10) /*Linear framebuffer*/
  62.438 +        if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/
  62.439          {
  62.440 -                s3_linear_base = (crtc[0x5a] << 16) | (crtc[0x59] << 24);
  62.441 -                switch (crtc[0x58] & 3)
  62.442 +                s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
  62.443 +                switch (svga->crtc[0x58] & 3)
  62.444                  {
  62.445                          case 0: /*64k*/
  62.446 -                        s3_linear_size = 0x10000;
  62.447 +                        s3->linear_size = 0x10000;
  62.448                          break;
  62.449                          case 1: /*1mb*/
  62.450 -                        s3_linear_size = 0x100000;
  62.451 +                        s3->linear_size = 0x100000;
  62.452                          break;
  62.453                          case 2: /*2mb*/
  62.454 -                        s3_linear_size = 0x200000;
  62.455 +                        s3->linear_size = 0x200000;
  62.456                          break;
  62.457                          case 3: /*8mb*/
  62.458 -                        s3_linear_size = 0x800000;
  62.459 +                        s3->linear_size = 0x800000;
  62.460                          break;
  62.461                  }
  62.462 -                s3_linear_base &= ~(s3_linear_size - 1);
  62.463 +                s3->linear_base &= ~(s3->linear_size - 1);
  62.464  //                pclog("%08X %08X  %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]);
  62.465  //                pclog("Linear framebuffer at %08X size %08X\n", linear_base, linear_size);
  62.466 -                if (s3_linear_base == 0xa0000)
  62.467 -                   mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    NULL);
  62.468 +                if (s3->linear_base == 0xa0000)
  62.469 +                   mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  62.470                  else
  62.471 -                   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);
  62.472 +                   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, svga);
  62.473          }
  62.474          
  62.475  //        pclog("Memory mapped IO %02X\n", crtc[0x53] & 0x10);
  62.476 -        if (crtc[0x53] & 0x10) /*Memory mapped IO*/
  62.477 -        {
  62.478 -                mem_sethandler(0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, NULL);
  62.479 -/*                video_write_a000   = s3_accel_write;
  62.480 -                video_write_a000_w = s3_accel_write_w;
  62.481 -                video_write_a000_l = s3_accel_write_l;
  62.482 -                video_read_a000    = s3_accel_read;*/
  62.483 -        }
  62.484 +        if (svga->crtc[0x53] & 0x10) /*Memory mapped IO*/
  62.485 +                mem_sethandler(0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, s3);
  62.486  }
  62.487  
  62.488  
  62.489 -struct
  62.490 +void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3);
  62.491 +
  62.492 +void s3_accel_out(uint16_t port, uint8_t val, void *p)
  62.493  {
  62.494 -        uint8_t subsys_cntl;
  62.495 -        uint8_t setup_md;
  62.496 -        uint8_t advfunc_cntl;
  62.497 -        uint16_t cur_y;
  62.498 -        uint16_t cur_x;
  62.499 -         int16_t desty_axstp;
  62.500 -         int16_t destx_distp;
  62.501 -         int16_t err_term;
  62.502 -         int16_t maj_axis_pcnt;
  62.503 -        uint16_t cmd;
  62.504 -        uint16_t short_stroke;
  62.505 -        uint32_t bkgd_color;
  62.506 -        uint32_t frgd_color;
  62.507 -        uint32_t wrt_mask;
  62.508 -        uint32_t rd_mask;
  62.509 -        uint32_t color_cmp;
  62.510 -        uint8_t bkgd_mix;
  62.511 -        uint8_t frgd_mix;
  62.512 -        uint16_t multifunc_cntl;
  62.513 -        uint16_t multifunc[16];
  62.514 -        uint8_t pix_trans[4];
  62.515 -        
  62.516 -        int cx, cy;
  62.517 -        int sx, sy;
  62.518 -        int dx, dy;
  62.519 -        uint32_t src, dest, pattern;
  62.520 -        int pix_trans_count;
  62.521 -        
  62.522 -        uint32_t dat_buf;
  62.523 -        int dat_count;
  62.524 -} s3_accel;
  62.525 -
  62.526 -void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat);
  62.527 -
  62.528 -void s3_accel_out(uint16_t port, uint8_t val, void *priv)
  62.529 -{
  62.530 +        s3_t *s3 = (s3_t *)p;
  62.531  //        pclog("Accel out %04X %02X\n", port, val);
  62.532          switch (port)
  62.533          {
  62.534                  case 0x42e8:
  62.535                  break;
  62.536                  case 0x42e9:
  62.537 -                s3_accel.subsys_cntl = val;
  62.538 +                s3->accel.subsys_cntl = val;
  62.539                  break;
  62.540                  case 0x46e8:
  62.541 -                s3_accel.setup_md = val;
  62.542 +                s3->accel.setup_md = val;
  62.543                  break;
  62.544                  case 0x4ae8:
  62.545 -                s3_accel.advfunc_cntl = val;
  62.546 +                s3->accel.advfunc_cntl = val;
  62.547                  break;
  62.548                  
  62.549                  case 0x82e8:
  62.550 -                s3_accel.cur_y = (s3_accel.cur_y & 0xf00) | val;
  62.551 +                s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val;
  62.552                  break;
  62.553                  case 0x82e9:
  62.554 -                s3_accel.cur_y = (s3_accel.cur_y & 0xff) | ((val & 0x1f) << 8);
  62.555 +                s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x1f) << 8);
  62.556                  break;
  62.557                  
  62.558                  case 0x86e8:
  62.559 -                s3_accel.cur_x = (s3_accel.cur_x & 0xf00) | val;
  62.560 +                s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val;
  62.561                  break;
  62.562                  case 0x86e9:
  62.563 -                s3_accel.cur_x = (s3_accel.cur_x & 0xff) | ((val & 0x1f) << 8);
  62.564 +                s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x1f) << 8);
  62.565                  break;
  62.566                  
  62.567                  case 0x8ae8:
  62.568 -                s3_accel.desty_axstp = (s3_accel.desty_axstp & 0x3f00) | val;
  62.569 +                s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val;
  62.570                  break;
  62.571                  case 0x8ae9:
  62.572 -                s3_accel.desty_axstp = (s3_accel.desty_axstp & 0xff) | ((val & 0x3f) << 8);
  62.573 +                s3->accel.desty_axstp = (s3->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8);
  62.574                  if (val & 0x20)
  62.575 -                   s3_accel.desty_axstp |= ~0x3fff;
  62.576 +                   s3->accel.desty_axstp |= ~0x3fff;
  62.577                  break;
  62.578                  
  62.579                  case 0x8ee8:
  62.580 -                s3_accel.destx_distp = (s3_accel.destx_distp & 0x3f00) | val;
  62.581 +                s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val;
  62.582                  break;
  62.583                  case 0x8ee9:
  62.584 -                s3_accel.destx_distp = (s3_accel.destx_distp & 0xff) | ((val & 0x3f) << 8);
  62.585 +                s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8);
  62.586                  if (val & 0x20)
  62.587 -                   s3_accel.destx_distp |= ~0x3fff;
  62.588 +                   s3->accel.destx_distp |= ~0x3fff;
  62.589                  break;
  62.590                  
  62.591                  case 0x92e8:
  62.592 -                s3_accel.err_term = (s3_accel.err_term & 0x3f00) | val;
  62.593 +                s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val;
  62.594                  break;
  62.595                  case 0x92e9:
  62.596 -                s3_accel.err_term = (s3_accel.err_term & 0xff) | ((val & 0x3f) << 8);
  62.597 +                s3->accel.err_term = (s3->accel.err_term & 0xff) | ((val & 0x3f) << 8);
  62.598                  if (val & 0x20)
  62.599 -                   s3_accel.err_term |= ~0x3fff;
  62.600 +                   s3->accel.err_term |= ~0x3fff;
  62.601                  break;
  62.602  
  62.603                  case 0x96e8:
  62.604 -                s3_accel.maj_axis_pcnt = (s3_accel.maj_axis_pcnt & 0x3f00) | val;
  62.605 +                s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0x3f00) | val;
  62.606                  break;
  62.607                  case 0x96e9:
  62.608 -                s3_accel.maj_axis_pcnt = (s3_accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8);
  62.609 +                s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8);
  62.610                  if (val & 0x08)
  62.611 -                   s3_accel.maj_axis_pcnt |= ~0x0fff;
  62.612 +                   s3->accel.maj_axis_pcnt |= ~0x0fff;
  62.613                  break;
  62.614  
  62.615                  case 0x9ae8:
  62.616 -                s3_accel.cmd = (s3_accel.cmd & 0xff00) | val;
  62.617 +                s3->accel.cmd = (s3->accel.cmd & 0xff00) | val;
  62.618                  break;
  62.619                  case 0x9ae9:
  62.620 -                s3_accel.cmd = (s3_accel.cmd & 0xff) | (val << 8);
  62.621 -                s3_accel_start(-1, 0, 0xffffffff, 0);
  62.622 -                s3_accel.pix_trans_count = 0;
  62.623 +                s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8);
  62.624 +                s3_accel_start(-1, 0, 0xffffffff, 0, s3);
  62.625 +                s3->accel.pix_trans_count = 0;
  62.626                  break;
  62.627  
  62.628                  case 0x9ee8:
  62.629 -                s3_accel.short_stroke = (s3_accel.short_stroke & 0xff00) | val;
  62.630 +                s3->accel.short_stroke = (s3->accel.short_stroke & 0xff00) | val;
  62.631                  break;
  62.632                  case 0x9ee9:
  62.633 -                s3_accel.short_stroke = (s3_accel.short_stroke & 0xff) | (val << 8);
  62.634 +                s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8);
  62.635                  break;
  62.636  
  62.637                  case 0xa2e8:
  62.638 -                if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10)
  62.639 -                   s3_accel.bkgd_color = (s3_accel.bkgd_color & ~0x00ff0000) | (val << 16);
  62.640 +                if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10)
  62.641 +                   s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16);
  62.642                  else
  62.643 -                   s3_accel.bkgd_color = (s3_accel.bkgd_color & ~0x000000ff) | val;
  62.644 +                   s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val;
  62.645                  break;
  62.646                  case 0xa2e9:
  62.647 -                if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10)
  62.648 -                   s3_accel.bkgd_color = (s3_accel.bkgd_color & ~0xff000000) | (val << 24);
  62.649 +                if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10)
  62.650 +                   s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24);
  62.651                  else
  62.652 -                   s3_accel.bkgd_color = (s3_accel.bkgd_color & ~0x0000ff00) | (val << 8);
  62.653 -                s3_accel.multifunc[0xe] ^= 0x10;
  62.654 +                   s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8);
  62.655 +                s3->accel.multifunc[0xe] ^= 0x10;
  62.656                  break;
  62.657  
  62.658                  case 0xa6e8:
  62.659 -                if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10)
  62.660 -                   s3_accel.frgd_color = (s3_accel.frgd_color & ~0x00ff0000) | (val << 16);
  62.661 +                if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10)
  62.662 +                   s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16);
  62.663                  else
  62.664 -                   s3_accel.frgd_color = (s3_accel.frgd_color & ~0x000000ff) | val;
  62.665 -//                pclog("Foreground colour now %08X %i\n", s3_accel.frgd_color, s3_bpp);
  62.666 +                   s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val;
  62.667 +//                pclog("Foreground colour now %08X %i\n", s3->accel.frgd_color, s3->bpp);
  62.668                  break;
  62.669                  case 0xa6e9:
  62.670 -                if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10)
  62.671 -                   s3_accel.frgd_color = (s3_accel.frgd_color & ~0xff000000) | (val << 24);
  62.672 +                if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10)
  62.673 +                   s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24);
  62.674                  else
  62.675 -                   s3_accel.frgd_color = (s3_accel.frgd_color & ~0x0000ff00) | (val << 8);
  62.676 -                s3_accel.multifunc[0xe] ^= 0x10;
  62.677 -//                pclog("Foreground colour now %08X\n", s3_accel.frgd_color);
  62.678 +                   s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8);
  62.679 +                s3->accel.multifunc[0xe] ^= 0x10;
  62.680 +//                pclog("Foreground colour now %08X\n", s3->accel.frgd_color);
  62.681                  break;
  62.682  
  62.683                  case 0xaae8:
  62.684 -                if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10)
  62.685 -                   s3_accel.wrt_mask = (s3_accel.wrt_mask & ~0x00ff0000) | (val << 16);
  62.686 +                if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10)
  62.687 +                   s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16);
  62.688                  else
  62.689 -                   s3_accel.wrt_mask = (s3_accel.wrt_mask & ~0x000000ff) | val;
  62.690 +                   s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val;
  62.691                  break;
  62.692                  case 0xaae9:
  62.693 -                if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10)
  62.694 -                   s3_accel.wrt_mask = (s3_accel.wrt_mask & ~0xff000000) | (val << 24);
  62.695 +                if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10)
  62.696 +                   s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24);
  62.697                  else
  62.698 -                   s3_accel.wrt_mask = (s3_accel.wrt_mask & ~0x0000ff00) | (val << 8);
  62.699 -                s3_accel.multifunc[0xe] ^= 0x10;
  62.700 +                   s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8);
  62.701 +                s3->accel.multifunc[0xe] ^= 0x10;
  62.702                  break;
  62.703  
  62.704                  case 0xaee8:
  62.705 -                if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10)
  62.706 -                   s3_accel.rd_mask = (s3_accel.rd_mask & ~0x00ff0000) | (val << 16);
  62.707 +                if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10)
  62.708 +                   s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16);
  62.709                  else
  62.710 -                   s3_accel.rd_mask = (s3_accel.rd_mask & ~0x000000ff) | val;
  62.711 +                   s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val;
  62.712                  break;
  62.713                  case 0xaee9:
  62.714 -                if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10)
  62.715 -                   s3_accel.rd_mask = (s3_accel.rd_mask & ~0xff000000) | (val << 24);
  62.716 +                if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10)
  62.717 +                   s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24);
  62.718                  else
  62.719 -                   s3_accel.rd_mask = (s3_accel.rd_mask & ~0x0000ff00) | (val << 8);
  62.720 -                s3_accel.multifunc[0xe] ^= 0x10;
  62.721 +                   s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8);
  62.722 +                s3->accel.multifunc[0xe] ^= 0x10;
  62.723                  break;
  62.724  
  62.725                  case 0xb2e8:
  62.726 -                if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10)
  62.727 -                   s3_accel.color_cmp = (s3_accel.color_cmp & ~0x00ff0000) | (val << 16);
  62.728 +                if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10)
  62.729 +                   s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16);
  62.730                  else
  62.731 -                   s3_accel.color_cmp = (s3_accel.color_cmp & ~0x000000ff) | val;
  62.732 +                   s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val;
  62.733                  break;
  62.734                  case 0xb2e9:
  62.735 -                if (s3_bpp == 3 && s3_accel.multifunc[0xe] & 0x10)
  62.736 -                   s3_accel.color_cmp = (s3_accel.color_cmp & ~0xff000000) | (val << 24);
  62.737 +                if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10)
  62.738 +                   s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24);
  62.739                  else
  62.740 -                   s3_accel.color_cmp = (s3_accel.color_cmp & ~0x0000ff00) | (val << 8);
  62.741 -                s3_accel.multifunc[0xe] ^= 0x10;
  62.742 +                   s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8);
  62.743 +                s3->accel.multifunc[0xe] ^= 0x10;
  62.744                  break;
  62.745  
  62.746                  case 0xb6e8:
  62.747 -                s3_accel.bkgd_mix = val;
  62.748 +                s3->accel.bkgd_mix = val;
  62.749                  break;
  62.750  
  62.751                  case 0xbae8:
  62.752 -                s3_accel.frgd_mix = val;
  62.753 +                s3->accel.frgd_mix = val;
  62.754                  break;
  62.755                  
  62.756                  case 0xbee8:
  62.757 -                s3_accel.multifunc_cntl = (s3_accel.multifunc_cntl & 0xff00) | val;
  62.758 +                s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff00) | val;
  62.759                  break;
  62.760                  case 0xbee9:
  62.761 -                s3_accel.multifunc_cntl = (s3_accel.multifunc_cntl & 0xff) | (val << 8);
  62.762 -                s3_accel.multifunc[s3_accel.multifunc_cntl >> 12] = s3_accel.multifunc_cntl & 0xfff;
  62.763 +                s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8);
  62.764 +                s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff;
  62.765                  break;
  62.766  
  62.767                  case 0xe2e8:
  62.768 -                s3_accel.pix_trans[0] = val;
  62.769 -                if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3_accel.cmd & 0x600) && (s3_accel.cmd & 0x100))
  62.770 -                   s3_accel_start(8, 1, s3_accel.pix_trans[0], 0);
  62.771 -                else if (!(s3_accel.cmd & 0x600) && (s3_accel.cmd & 0x100))
  62.772 -                   s3_accel_start(1, 1, 0xffffffff, s3_accel.pix_trans[0]);
  62.773 +                s3->accel.pix_trans[0] = val;
  62.774 +                if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100))
  62.775 +                        s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3);
  62.776 +                else if (!(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100))
  62.777 +                        s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3);
  62.778                  break;
  62.779                  case 0xe2e9:
  62.780 -                s3_accel.pix_trans[1] = val;
  62.781 -                if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && (s3_accel.cmd & 0x600) == 0x200 && (s3_accel.cmd & 0x100))
  62.782 +                s3->accel.pix_trans[1] = val;
  62.783 +                if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100))
  62.784                  {
  62.785 -                        if (s3_accel.cmd & 0x1000) s3_accel_start(16, 1, s3_accel.pix_trans[1] | (s3_accel.pix_trans[0] << 8), 0);
  62.786 -                        else                       s3_accel_start(16, 1, s3_accel.pix_trans[0] | (s3_accel.pix_trans[1] << 8), 0);
  62.787 +                        if (s3->accel.cmd & 0x1000) s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3);
  62.788 +                        else                        s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3);
  62.789                  }
  62.790 -                else if ((s3_accel.cmd & 0x600) == 0x200 && (s3_accel.cmd & 0x100))
  62.791 +                else if ((s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100))
  62.792                  {
  62.793 -                        if (s3_accel.cmd & 0x1000) s3_accel_start(2, 1, 0xffffffff, s3_accel.pix_trans[1] | (s3_accel.pix_trans[0] << 8));
  62.794 -                        else                       s3_accel_start(2, 1, 0xffffffff, s3_accel.pix_trans[0] | (s3_accel.pix_trans[1] << 8));
  62.795 +                        if (s3->accel.cmd & 0x1000) s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3);
  62.796 +                        else                        s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3);
  62.797                  }
  62.798                  break;
  62.799                  case 0xe2ea:
  62.800 -                s3_accel.pix_trans[2] = val;
  62.801 +                s3->accel.pix_trans[2] = val;
  62.802                  break;
  62.803                  case 0xe2eb:
  62.804 -                s3_accel.pix_trans[3] = val;
  62.805 -                if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && (s3_accel.cmd & 0x600) == 0x400 && (s3_accel.cmd & 0x100))
  62.806 -                   s3_accel_start(32, 1, s3_accel.pix_trans[0] | (s3_accel.pix_trans[1] << 8) | (s3_accel.pix_trans[2] << 16) | (s3_accel.pix_trans[3] << 24), 0);
  62.807 -                else if ((s3_accel.cmd & 0x600) == 0x400 && (s3_accel.cmd & 0x100))
  62.808 -                   s3_accel_start(4, 1, 0xffffffff, s3_accel.pix_trans[0] | (s3_accel.pix_trans[1] << 8) | (s3_accel.pix_trans[2] << 16) | (s3_accel.pix_trans[3] << 24));
  62.809 +                s3->accel.pix_trans[3] = val;
  62.810 +                if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x400 && (s3->accel.cmd & 0x100))
  62.811 +                        s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3);
  62.812 +                else if ((s3->accel.cmd & 0x600) == 0x400 && (s3->accel.cmd & 0x100))
  62.813 +                        s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3);
  62.814                  break;
  62.815          }
  62.816  }
  62.817  
  62.818 -void s3_accel_out_w(uint16_t port, uint16_t val, void *priv)
  62.819 +void s3_accel_out_w(uint16_t port, uint16_t val, void *p)
  62.820  {
  62.821 +        s3_t *s3 = (s3_t *)p;
  62.822  //        pclog("Accel out w %04X %04X\n", port, val);
  62.823 -        if (s3_accel.cmd & 0x100)
  62.824 +        if (s3->accel.cmd & 0x100)
  62.825          {
  62.826 -                if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80)
  62.827 +                if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80)
  62.828                  {
  62.829 -                        if (s3_accel.cmd & 0x1000)
  62.830 +                        if (s3->accel.cmd & 0x1000)
  62.831                             val = (val >> 8) | (val << 8);
  62.832 -                        s3_accel_start(16, 1, val | (val << 16), 0);
  62.833 +                        s3_accel_start(16, 1, val | (val << 16), 0, s3);
  62.834                  }
  62.835                  else
  62.836 -                   s3_accel_start(2, 1, 0xffffffff, val | (val << 16));
  62.837 +                   s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3);
  62.838          }
  62.839  }
  62.840  
  62.841 -void s3_accel_out_l(uint16_t port, uint32_t val, void *priv)
  62.842 +void s3_accel_out_l(uint16_t port, uint32_t val, void *p)
  62.843  {
  62.844 +        s3_t *s3 = (s3_t *)p;
  62.845  //        pclog("Accel out l %04X %08X\n", port, val);
  62.846 -        if (s3_accel.cmd & 0x100)
  62.847 +        if (s3->accel.cmd & 0x100)
  62.848          {
  62.849 -                if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80)
  62.850 +                if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80)
  62.851                  {
  62.852 -                        if (s3_accel.cmd & 0x1000)
  62.853 -                           val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24);
  62.854 -                        if ((s3_accel.cmd & 0x600) == 0x400)
  62.855 -                           s3_accel_start(32, 1, val, 0);
  62.856 -                        else if ((s3_accel.cmd & 0x600) == 0x200)
  62.857 +                        if (s3->accel.cmd & 0x1000)
  62.858 +                                val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24);
  62.859 +                        if ((s3->accel.cmd & 0x600) == 0x400)
  62.860 +                                s3_accel_start(32, 1, val, 0, s3);
  62.861 +                        else if ((s3->accel.cmd & 0x600) == 0x200)
  62.862                          {
  62.863 -                                s3_accel_start(16, 1, val >> 16, 0);
  62.864 -                                s3_accel_start(16, 1, val, 0);
  62.865 +                                s3_accel_start(16, 1, val >> 16, 0, s3);
  62.866 +                                s3_accel_start(16, 1, val, 0, s3);
  62.867                          }
  62.868 -                        else if (!(s3_accel.cmd & 0x600))
  62.869 +                        else if (!(s3->accel.cmd & 0x600))
  62.870                          {
  62.871 -                                s3_accel_start(8, 1, val >> 24, 0);
  62.872 -                                s3_accel_start(8, 1, val >> 16, 0);
  62.873 -                                s3_accel_start(8, 1, val >> 8,  0);
  62.874 -                                s3_accel_start(8, 1, val,       0);
  62.875 +                                s3_accel_start(8, 1, val >> 24, 0, s3);
  62.876 +                                s3_accel_start(8, 1, val >> 16, 0, s3);
  62.877 +                                s3_accel_start(8, 1, val >> 8,  0, s3);
  62.878 +                                s3_accel_start(8, 1, val,       0, s3);
  62.879                          }
  62.880                  }
  62.881                  else
  62.882                  {
  62.883 -                        if ((s3_accel.cmd & 0x600) == 0x400)
  62.884 -                           s3_accel_start(4, 1, 0xffffffff, val);
  62.885 -                        else if ((s3_accel.cmd & 0x600) == 0x200)
  62.886 +                        if ((s3->accel.cmd & 0x600) == 0x400)
  62.887 +                                s3_accel_start(4, 1, 0xffffffff, val, s3);
  62.888 +                        else if ((s3->accel.cmd & 0x600) == 0x200)
  62.889                          {
  62.890 -                                s3_accel_start(2, 1, 0xffffffff, val >> 16);
  62.891 -                                s3_accel_start(2, 1, 0xffffffff, val);
  62.892 +                                s3_accel_start(2, 1, 0xffffffff, val >> 16, s3);
  62.893 +                                s3_accel_start(2, 1, 0xffffffff, val, s3);
  62.894                          }
  62.895 -                        else if (!(s3_accel.cmd & 0x600))
  62.896 +                        else if (!(s3->accel.cmd & 0x600))
  62.897                          {
  62.898 -                                s3_accel_start(1, 1, 0xffffffff, val >> 24);
  62.899 -                                s3_accel_start(1, 1, 0xffffffff, val >> 16);
  62.900 -                                s3_accel_start(1, 1, 0xffffffff, val >> 8);
  62.901 -                                s3_accel_start(1, 1, 0xffffffff, val);
  62.902 +                                s3_accel_start(1, 1, 0xffffffff, val >> 24, s3);
  62.903 +                                s3_accel_start(1, 1, 0xffffffff, val >> 16, s3);
  62.904 +                                s3_accel_start(1, 1, 0xffffffff, val >> 8, s3);
  62.905 +                                s3_accel_start(1, 1, 0xffffffff, val, s3);
  62.906                          }
  62.907                  }
  62.908          }
  62.909  }
  62.910  
  62.911 -uint8_t s3_accel_in(uint16_t port, void *priv)
  62.912 +uint8_t s3_accel_in(uint16_t port, void *p)
  62.913  {
  62.914 +        s3_t *s3 = (s3_t *)p;
  62.915          int temp;
  62.916  //        pclog("Accel in  %04X\n", port);
  62.917          switch (port)
  62.918 @@ -595,34 +634,34 @@
  62.919                  return 0;
  62.920  
  62.921                  case 0x82e8:
  62.922 -                return s3_accel.cur_y & 0xff;
  62.923 +                return s3->accel.cur_y & 0xff;
  62.924                  case 0x82e9:
  62.925 -                return s3_accel.cur_y  >> 8;
  62.926 +                return s3->accel.cur_y  >> 8;
  62.927  
  62.928                  case 0x86e8:
  62.929 -                return s3_accel.cur_x & 0xff;
  62.930 +                return s3->accel.cur_x & 0xff;
  62.931                  case 0x86e9:
  62.932 -                return s3_accel.cur_x  >> 8;
  62.933 +                return s3->accel.cur_x  >> 8;
  62.934  
  62.935                  case 0x8ae8:
  62.936 -                return s3_accel.desty_axstp & 0xff;
  62.937 +                return s3->accel.desty_axstp & 0xff;
  62.938                  case 0x8ae9:
  62.939 -                return s3_accel.desty_axstp >> 8;
  62.940 +                return s3->accel.desty_axstp >> 8;
  62.941  
  62.942                  case 0x8ee8:
  62.943 -                return s3_accel.destx_distp & 0xff;
  62.944 +                return s3->accel.destx_distp & 0xff;
  62.945                  case 0x8ee9:
  62.946 -                return s3_accel.destx_distp >> 8;
  62.947 +                return s3->accel.destx_distp >> 8;
  62.948  
  62.949                  case 0x92e8:
  62.950 -                return s3_accel.err_term & 0xff;
  62.951 +                return s3->accel.err_term & 0xff;
  62.952                  case 0x92e9:
  62.953 -                return s3_accel.err_term >> 8;
  62.954 +                return s3->accel.err_term >> 8;
  62.955  
  62.956                  case 0x96e8:
  62.957 -                return s3_accel.maj_axis_pcnt & 0xff;
  62.958 +                return s3->accel.maj_axis_pcnt & 0xff;
  62.959                  case 0x96e9:
  62.960 -                return s3_accel.maj_axis_pcnt >> 8;
  62.961 +                return s3->accel.maj_axis_pcnt >> 8;
  62.962  
  62.963                  case 0x9ae8:
  62.964                  return 0;
  62.965 @@ -630,69 +669,69 @@
  62.966                  return 0;
  62.967  
  62.968                  case 0xa2e8:
  62.969 -                return s3_accel.bkgd_color & 0xff;
  62.970 +                return s3->accel.bkgd_color & 0xff;
  62.971                  case 0xa2e9:
  62.972 -                return s3_accel.bkgd_color >> 8;
  62.973 +                return s3->accel.bkgd_color >> 8;
  62.974  
  62.975                  case 0xa6e8:
  62.976 -                return s3_accel.frgd_color & 0xff;
  62.977 +                return s3->accel.frgd_color & 0xff;
  62.978                  case 0xa6e9:
  62.979 -                return s3_accel.frgd_color >> 8;
  62.980 +                return s3->accel.frgd_color >> 8;
  62.981  
  62.982                  case 0xaae8:
  62.983 -                return s3_accel.wrt_mask & 0xff;
  62.984 +                return s3->accel.wrt_mask & 0xff;
  62.985                  case 0xaae9:
  62.986 -                return s3_accel.wrt_mask >> 8;
  62.987 +                return s3->accel.wrt_mask >> 8;
  62.988  
  62.989                  case 0xaee8:
  62.990 -                return s3_accel.rd_mask & 0xff;
  62.991 +                return s3->accel.rd_mask & 0xff;
  62.992                  case 0xaee9:
  62.993 -                return s3_accel.rd_mask >> 8;
  62.994 +                return s3->accel.rd_mask >> 8;
  62.995  
  62.996                  case 0xb2e8:
  62.997 -                return s3_accel.color_cmp & 0xff;
  62.998 +                return s3->accel.color_cmp & 0xff;
  62.999                  case 0xb2e9:
 62.1000 -                return s3_accel.color_cmp >> 8;
 62.1001 +                return s3->accel.color_cmp >> 8;
 62.1002  
 62.1003                  case 0xb6e8:
 62.1004 -                return s3_accel.bkgd_mix;
 62.1005 +                return s3->accel.bkgd_mix;
 62.1006  
 62.1007                  case 0xbae8:
 62.1008 -                return s3_accel.frgd_mix;
 62.1009 +                return s3->accel.frgd_mix;
 62.1010  
 62.1011                  case 0xbee8:
 62.1012 -                temp = s3_accel.multifunc[0xf] & 0xf;
 62.1013 +                temp = s3->accel.multifunc[0xf] & 0xf;
 62.1014                  switch (temp)
 62.1015                  {
 62.1016 -                        case 0x0: return s3_accel.multifunc[0x0] & 0xff;
 62.1017 -                        case 0x1: return s3_accel.multifunc[0x1] & 0xff;
 62.1018 -                        case 0x2: return s3_accel.multifunc[0x2] & 0xff;
 62.1019 -                        case 0x3: return s3_accel.multifunc[0x3] & 0xff;
 62.1020 -                        case 0x4: return s3_accel.multifunc[0x4] & 0xff;
 62.1021 -                        case 0x5: return s3_accel.multifunc[0xa] & 0xff;
 62.1022 -                        case 0x6: return s3_accel.multifunc[0xe] & 0xff;
 62.1023 -                        case 0x7: return s3_accel.cmd            & 0xff;
 62.1024 -                        case 0x8: return s3_accel.subsys_cntl    & 0xff;
 62.1025 -                        case 0x9: return s3_accel.setup_md       & 0xff;
 62.1026 -                        case 0xa: return s3_accel.multifunc[0xd] & 0xff;
 62.1027 +                        case 0x0: return s3->accel.multifunc[0x0] & 0xff;
 62.1028 +                        case 0x1: return s3->accel.multifunc[0x1] & 0xff;
 62.1029 +                        case 0x2: return s3->accel.multifunc[0x2] & 0xff;
 62.1030 +                        case 0x3: return s3->accel.multifunc[0x3] & 0xff;
 62.1031 +                        case 0x4: return s3->accel.multifunc[0x4] & 0xff;
 62.1032 +                        case 0x5: return s3->accel.multifunc[0xa] & 0xff;
 62.1033 +                        case 0x6: return s3->accel.multifunc[0xe] & 0xff;
 62.1034 +                        case 0x7: return s3->accel.cmd            & 0xff;
 62.1035 +                        case 0x8: return s3->accel.subsys_cntl    & 0xff;
 62.1036 +                        case 0x9: return s3->accel.setup_md       & 0xff;
 62.1037 +                        case 0xa: return s3->accel.multifunc[0xd] & 0xff;
 62.1038                  }
 62.1039                  return 0xff;
 62.1040                  case 0xbee9:
 62.1041 -                temp = s3_accel.multifunc[0xf] & 0xf;
 62.1042 -                s3_accel.multifunc[0xf]++;
 62.1043 +                temp = s3->accel.multifunc[0xf] & 0xf;
 62.1044 +                s3->accel.multifunc[0xf]++;
 62.1045                  switch (temp)
 62.1046                  {
 62.1047 -                        case 0x0: return  s3_accel.multifunc[0x0] >> 8;
 62.1048 -                        case 0x1: return  s3_accel.multifunc[0x1] >> 8;
 62.1049 -                        case 0x2: return  s3_accel.multifunc[0x2] >> 8;
 62.1050 -                        case 0x3: return  s3_accel.multifunc[0x3] >> 8;
 62.1051 -                        case 0x4: return  s3_accel.multifunc[0x4] >> 8;
 62.1052 -                        case 0x5: return  s3_accel.multifunc[0xa] >> 8;
 62.1053 -                        case 0x6: return  s3_accel.multifunc[0xe] >> 8;
 62.1054 -                        case 0x7: return  s3_accel.cmd            >> 8;
 62.1055 -                        case 0x8: return (s3_accel.subsys_cntl    >> 8) & ~0xe000;
 62.1056 -                        case 0x9: return (s3_accel.setup_md       >> 8) & ~0xf000;
 62.1057 -                        case 0xa: return  s3_accel.multifunc[0xd] >> 8;
 62.1058 +                        case 0x0: return  s3->accel.multifunc[0x0] >> 8;
 62.1059 +                        case 0x1: return  s3->accel.multifunc[0x1] >> 8;
 62.1060 +                        case 0x2: return  s3->accel.multifunc[0x2] >> 8;
 62.1061 +                        case 0x3: return  s3->accel.multifunc[0x3] >> 8;
 62.1062 +                        case 0x4: return  s3->accel.multifunc[0x4] >> 8;
 62.1063 +                        case 0x5: return  s3->accel.multifunc[0xa] >> 8;
 62.1064 +                        case 0x6: return  s3->accel.multifunc[0xe] >> 8;
 62.1065 +                        case 0x7: return  s3->accel.cmd            >> 8;
 62.1066 +                        case 0x8: return (s3->accel.subsys_cntl    >> 8) & ~0xe000;
 62.1067 +                        case 0x9: return (s3->accel.setup_md       >> 8) & ~0xf000;
 62.1068 +                        case 0xa: return  s3->accel.multifunc[0xd] >> 8;
 62.1069                  }
 62.1070                  return 0xff;
 62.1071  
 62.1072 @@ -702,114 +741,116 @@
 62.1073          return 0;
 62.1074  }
 62.1075  
 62.1076 -void s3_accel_write(uint32_t addr, uint8_t val, void *priv)
 62.1077 +void s3_accel_write(uint32_t addr, uint8_t val, void *p)
 62.1078  {
 62.1079 +        s3_t *s3 = (s3_t *)p;
 62.1080  //        pclog("Write S3 accel %08X %02X\n", addr, val);
 62.1081          if (addr & 0x8000)
 62.1082 -           s3_accel_out(addr & 0xffff, val, priv);
 62.1083 +           s3_accel_out(addr & 0xffff, val, p);
 62.1084          else
 62.1085          {
 62.1086 -                if (s3_accel.cmd & 0x100)
 62.1087 +                if (s3->accel.cmd & 0x100)
 62.1088                  {
 62.1089 -                        if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80)
 62.1090 -                           s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0);
 62.1091 +                        if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80)
 62.1092 +                                s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3);
 62.1093                          else
 62.1094 -                           s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24));
 62.1095 +                                s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3);
 62.1096                  }
 62.1097          }
 62.1098  }
 62.1099  
 62.1100 -void s3_accel_write_w(uint32_t addr, uint16_t val, void *priv)
 62.1101 +void s3_accel_write_w(uint32_t addr, uint16_t val, void *p)
 62.1102  {
 62.1103 +        s3_t *s3 = (s3_t *)p;
 62.1104  //        pclog("Write S3 accel w %08X %04X\n", addr, val);
 62.1105          if (addr & 0x8000)
 62.1106          {
 62.1107 -                s3_accel_out( addr & 0xffff,      val, priv);
 62.1108 -                s3_accel_out((addr & 0xffff) + 1, val >> 8, priv);
 62.1109 +                s3_accel_out( addr & 0xffff,      val, p);
 62.1110 +                s3_accel_out((addr & 0xffff) + 1, val >> 8, p);
 62.1111          }
 62.1112          else
 62.1113          {
 62.1114 -                if (s3_accel.cmd & 0x100)
 62.1115 +                if (s3->accel.cmd & 0x100)
 62.1116                  {
 62.1117 -                        if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80)
 62.1118 +                        if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80)
 62.1119                          {
 62.1120 -                                if (s3_accel.cmd & 0x1000)
 62.1121 -                                   val = (val >> 8) | (val << 8);
 62.1122 -                                s3_accel_start(16, 1, val | (val << 16), 0);
 62.1123 +                                if (s3->accel.cmd & 0x1000)
 62.1124 +                                        val = (val >> 8) | (val << 8);
 62.1125 +                                s3_accel_start(16, 1, val | (val << 16), 0, s3);
 62.1126                          }
 62.1127                          else
 62.1128 -                           s3_accel_start(2, 1, 0xffffffff, val | (val << 16));
 62.1129 +                           s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3);
 62.1130                  }
 62.1131          }
 62.1132  }
 62.1133  
 62.1134 -void s3_accel_write_l(uint32_t addr, uint32_t val, void *priv)
 62.1135 +void s3_accel_write_l(uint32_t addr, uint32_t val, void *p)
 62.1136  {
 62.1137 +        s3_t *s3 = (s3_t *)p;
 62.1138  //        pclog("Write S3 accel l %08X %08X\n", addr, val);
 62.1139          if (addr & 0x8000)
 62.1140          {
 62.1141 -                s3_accel_out( addr & 0xffff,      val, priv);
 62.1142 -                s3_accel_out((addr & 0xffff) + 1, val >> 8, priv);
 62.1143 -                s3_accel_out((addr & 0xffff) + 2, val >> 16, priv);
 62.1144 -                s3_accel_out((addr & 0xffff) + 3, val >> 24, priv);
 62.1145 +                s3_accel_out( addr & 0xffff,      val,       p);
 62.1146 +                s3_accel_out((addr & 0xffff) + 1, val >> 8,  p);
 62.1147 +                s3_accel_out((addr & 0xffff) + 2, val >> 16, p);
 62.1148 +                s3_accel_out((addr & 0xffff) + 3, val >> 24, p);
 62.1149          }
 62.1150          else
 62.1151          {
 62.1152 -                if (s3_accel.cmd & 0x100)
 62.1153 +                if (s3->accel.cmd & 0x100)
 62.1154                  {
 62.1155 -                        if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80)
 62.1156 +                        if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80)
 62.1157                          {
 62.1158 -                                if (s3_accel.cmd & 0x1000)
 62.1159 -                                   val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24);
 62.1160 -                                if ((s3_accel.cmd & 0x600) == 0x400)
 62.1161 -                                   s3_accel_start(32, 1, val, 0);
 62.1162 -                                else if ((s3_accel.cmd & 0x600) == 0x200)
 62.1163 +                                if (s3->accel.cmd & 0x1000)
 62.1164 +                                        val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24);
 62.1165 +                                if ((s3->accel.cmd & 0x600) == 0x400)
 62.1166 +                                        s3_accel_start(32, 1, val, 0, s3);
 62.1167 +                                else if ((s3->accel.cmd & 0x600) == 0x200)
 62.1168                                  {
 62.1169 -                                        s3_accel_start(16, 1, val >> 16, 0);
 62.1170 -                                        s3_accel_start(16, 1, val, 0);
 62.1171 +                                        s3_accel_start(16, 1, val >> 16, 0, s3);
 62.1172 +                                        s3_accel_start(16, 1, val, 0,       s3);
 62.1173                                  }
 62.1174 -                                else if (!(s3_accel.cmd & 0x600))
 62.1175 +                                else if (!(s3->accel.cmd & 0x600))
 62.1176                                  {
 62.1177 -                                        s3_accel_start(8, 1, val >> 24, 0);
 62.1178 -                                        s3_accel_start(8, 1, val >> 16, 0);
 62.1179 -                                        s3_accel_start(8, 1, val >> 8,  0);
 62.1180 -                                        s3_accel_start(8, 1, val,       0);
 62.1181 +                                        s3_accel_start(8, 1, val >> 24, 0, s3);
 62.1182 +                                        s3_accel_start(8, 1, val >> 16, 0, s3);
 62.1183 +                                        s3_accel_start(8, 1, val >> 8,  0, s3);
 62.1184 +                                        s3_accel_start(8, 1, val,       0, s3);
 62.1185                                  }
 62.1186                          }
 62.1187                          else
 62.1188                          {
 62.1189 -                                if ((s3_accel.cmd & 0x600) == 0x400)
 62.1190 -                                   s3_accel_start(4, 1, 0xffffffff, val);
 62.1191 -                                else if ((s3_accel.cmd & 0x600) == 0x200)
 62.1192 +                                if ((s3->accel.cmd & 0x600) == 0x400)
 62.1193 +                                        s3_accel_start(4, 1, 0xffffffff, val, s3);
 62.1194 +                                else if ((s3->accel.cmd & 0x600) == 0x200)
 62.1195                                  {
 62.1196 -                                        s3_accel_start(2, 1, 0xffffffff, val >> 16);
 62.1197 -                                        s3_accel_start(2, 1, 0xffffffff, val);
 62.1198 +                                        s3_accel_start(2, 1, 0xffffffff, val >> 16, s3);
 62.1199 +                                        s3_accel_start(2, 1, 0xffffffff, val,       s3);
 62.1200                                  }
 62.1201 -                                else if (!(s3_accel.cmd & 0x600))
 62.1202 +                                else if (!(s3->accel.cmd & 0x600))
 62.1203                                  {
 62.1204 -                                        s3_accel_start(1, 1, 0xffffffff, val >> 24);
 62.1205 -                                        s3_accel_start(1, 1, 0xffffffff, val >> 16);
 62.1206 -                                        s3_accel_start(1, 1, 0xffffffff, val >> 8);
 62.1207 -                                        s3_accel_start(1, 1, 0xffffffff, val);
 62.1208 +                                        s3_accel_start(1, 1, 0xffffffff, val >> 24, s3);
 62.1209 +                                        s3_accel_start(1, 1, 0xffffffff, val >> 16, s3);
 62.1210 +                                        s3_accel_start(1, 1, 0xffffffff, val >> 8,  s3);
 62.1211 +                                        s3_accel_start(1, 1, 0xffffffff, val,       s3);
 62.1212                                  }
 62.1213                          }
 62.1214                  }
 62.1215          }
 62.1216  }
 62.1217  
 62.1218 -uint8_t s3_accel_read(uint32_t addr, void *priv)
 62.1219 +uint8_t s3_accel_read(uint32_t addr, void *p)
 62.1220  {
 62.1221 -//        pclog("Read S3 accel %08X\n", addr);
 62.1222          if (addr & 0x8000)
 62.1223 -           return s3_accel_in(addr & 0xffff, priv);
 62.1224 +           return s3_accel_in(addr & 0xffff, p);
 62.1225          return 0;
 62.1226  }
 62.1227  
 62.1228 -#define READ(addr, dat) if (s3_bpp == 0)      dat = vram[  (addr) & 0x3fffff]; \
 62.1229 -                        else if (s3_bpp == 1) dat = vram_w[(addr) & 0x1fffff]; \
 62.1230 -                        else                  dat = vram_l[(addr) & 0x0fffff];
 62.1231 +#define READ(addr, dat) if (s3->bpp == 0)      dat = svga->vram[  (addr) & 0x3fffff]; \
 62.1232 +                        else if (s3->bpp == 1) dat = vram_w[(addr) & 0x1fffff]; \
 62.1233 +                        else                   dat = vram_l[(addr) & 0x0fffff];
 62.1234  
 62.1235 -#define MIX     switch ((mix_dat & mix_mask) ? (s3_accel.frgd_mix & 0xf) : (s3_accel.bkgd_mix & 0xf))   \
 62.1236 +#define MIX     switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf))   \
 62.1237                  {                                                                                       \
 62.1238                          case 0x0: dest_dat =             ~dest_dat;  break;                             \
 62.1239                          case 0x1: dest_dat =  0;                     break;                             \
 62.1240 @@ -830,62 +871,63 @@
 62.1241                  }
 62.1242  
 62.1243  
 62.1244 -#define WRITE(addr)     if (s3_bpp == 0)                                                                                \
 62.1245 +#define WRITE(addr)     if (s3->bpp == 0)                                                                                \
 62.1246                          {                                                                                               \
 62.1247 -                                vram[(addr) & 0x3fffff] = dest_dat;                              \
 62.1248 -                                changedvram[((addr) & 0x3fffff) >> 10] = changeframecount;       \
 62.1249 +                                svga->vram[(addr) & 0x3fffff] = dest_dat;                              \
 62.1250 +                                svga->changedvram[((addr) & 0x3fffff) >> 10] = changeframecount;       \
 62.1251                          }                                                                                               \
 62.1252 -                        else if (s3_bpp == 1)                                                                           \
 62.1253 +                        else if (s3->bpp == 1)                                                                           \
 62.1254                          {                                                                                               \
 62.1255                                  vram_w[(addr) & 0x1fffff] = dest_dat;                            \
 62.1256 -                                changedvram[((addr) & 0x1fffff) >> 9] = changeframecount;        \
 62.1257 +                                svga->changedvram[((addr) & 0x1fffff) >> 9] = changeframecount;        \
 62.1258                          }                                                                                               \
 62.1259                          else                                                                                            \
 62.1260                          {                                                                                               \
 62.1261                                  vram_l[(addr) & 0xfffff] = dest_dat;                             \
 62.1262 -                                changedvram[((addr) & 0xfffff) >> 8] = changeframecount;         \
 62.1263 +                                svga->changedvram[((addr) & 0xfffff) >> 8] = changeframecount;         \
 62.1264                          }
 62.1265  
 62.1266 -void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat)
 62.1267 +void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3)
 62.1268  {
 62.1269 +        svga_t *svga = &s3->svga;
 62.1270          uint32_t src_dat, dest_dat;
 62.1271          int frgd_mix, bkgd_mix;
 62.1272 -        int clip_t = s3_accel.multifunc[1] & 0xfff;
 62.1273 -        int clip_l = s3_accel.multifunc[2] & 0xfff;
 62.1274 -        int clip_b = s3_accel.multifunc[3] & 0xfff;
 62.1275 -        int clip_r = s3_accel.multifunc[4] & 0xfff;
 62.1276 -        int vram_mask = (s3_accel.multifunc[0xa] & 0xc0) == 0xc0;
 62.1277 +        int clip_t = s3->accel.multifunc[1] & 0xfff;
 62.1278 +        int clip_l = s3->accel.multifunc[2] & 0xfff;
 62.1279 +        int clip_b = s3->accel.multifunc[3] & 0xfff;
 62.1280 +        int clip_r = s3->accel.multifunc[4] & 0xfff;
 62.1281 +        int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0;
 62.1282          uint32_t mix_mask;
 62.1283 -        uint16_t *vram_w = (uint16_t *)vram;
 62.1284 -        uint32_t *vram_l = (uint32_t *)vram;
 62.1285 -        uint32_t compare = s3_accel.color_cmp;
 62.1286 -        int compare_mode = (s3_accel.multifunc[0xe] >> 7) & 3;
 62.1287 +        uint16_t *vram_w = (uint16_t *)svga->vram;
 62.1288 +        uint32_t *vram_l = (uint32_t *)svga->vram;
 62.1289 +        uint32_t compare = s3->accel.color_cmp;
 62.1290 +        int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3;
 62.1291  //return;
 62.1292 -//        if (!cpu_input) pclog("Start S3 command %i  %i, %i  %i, %i (clip %i, %i to %i, %i  %i)\n", s3_accel.cmd >> 13, s3_accel.cur_x, s3_accel.cur_y, s3_accel.maj_axis_pcnt & 0xfff, s3_accel.multifunc[0]  & 0xfff, clip_l, clip_t, clip_r, clip_b, s3_accel.multifunc[0xe] & 0x20);
 62.1293 -//        else            pclog("      S3 command %i, %i, %08x %08x\n", s3_accel.cmd >> 13, count, mix_dat, cpu_dat);
 62.1294 +//        if (!cpu_input) pclog("Start S3 command %i  %i, %i  %i, %i (clip %i, %i to %i, %i  %i)\n", s3->accel.cmd >> 13, s3->accel.cur_x, s3->accel.cur_y, s3->accel.maj_axis_pcnt & 0xfff, s3->accel.multifunc[0]  & 0xfff, clip_l, clip_t, clip_r, clip_b, s3->accel.multifunc[0xe] & 0x20);
 62.1295 +//        else            pclog("      S3 command %i, %i, %08x %08x\n", s3->accel.cmd >> 13, count, mix_dat, cpu_dat);
 62.1296  
 62.1297 -        if (!cpu_input) s3_accel.dat_count = 0;
 62.1298 -        if (cpu_input && (s3_accel.multifunc[0xa] & 0xc0) != 0x80)
 62.1299 +        if (!cpu_input) s3->accel.dat_count = 0;
 62.1300 +        if (cpu_input && (s3->accel.multifunc[0xa] & 0xc0) != 0x80)
 62.1301          {
 62.1302 -                if (s3_bpp == 3 && count == 2)
 62.1303 +                if (s3->bpp == 3 && count == 2)
 62.1304                  {
 62.1305 -                        if (s3_accel.dat_count)
 62.1306 +                        if (s3->accel.dat_count)
 62.1307                          {
 62.1308 -                                cpu_dat = (cpu_dat & 0xffff) | (s3_accel.dat_buf << 16);
 62.1309 +                                cpu_dat = (cpu_dat & 0xffff) | (s3->accel.dat_buf << 16);
 62.1310                                  count = 4;
 62.1311 -                                s3_accel.dat_count = 0;
 62.1312 +                                s3->accel.dat_count = 0;
 62.1313                          }
 62.1314                          else
 62.1315                          {
 62.1316 -                                s3_accel.dat_buf = cpu_dat & 0xffff;
 62.1317 -                                s3_accel.dat_count = 1;
 62.1318 +                                s3->accel.dat_buf = cpu_dat & 0xffff;
 62.1319 +                                s3->accel.dat_count = 1;
 62.1320                          }
 62.1321                  }
 62.1322 -                if (s3_bpp == 1) count >>= 1;
 62.1323 -                if (s3_bpp == 3) count >>= 2;
 62.1324 +                if (s3->bpp == 1) count >>= 1;
 62.1325 +                if (s3->bpp == 3) count >>= 2;
 62.1326          }
 62.1327          
 62.1328 -        switch (s3_accel.cmd & 0x600)
 62.1329 +        switch (s3->accel.cmd & 0x600)
 62.1330          {
 62.1331                  case 0x000: mix_mask = 0x80; break;
 62.1332                  case 0x200: mix_mask = 0x8000; break;
 62.1333 @@ -893,32 +935,32 @@
 62.1334                  case 0x600: mix_mask = 0x80000000; break;
 62.1335          }
 62.1336  
 62.1337 -        if (s3_bpp == 0) compare &=   0xff;
 62.1338 -        if (s3_bpp == 1) compare &= 0xffff;
 62.1339 -        switch (s3_accel.cmd >> 13)
 62.1340 +        if (s3->bpp == 0) compare &=   0xff;
 62.1341 +        if (s3->bpp == 1) compare &= 0xffff;
 62.1342 +        switch (s3->accel.cmd >> 13)
 62.1343          {
 62.1344                  case 1: /*Draw line*/
 62.1345                  if (!cpu_input) /*!cpu_input is trigger to start operation*/
 62.1346                  {
 62.1347 -                        s3_accel.cx   = s3_accel.cur_x;
 62.1348 -                        if (s3_accel.cur_x & 0x1000) s3_accel.cx |= ~0xfff;
 62.1349 -                        s3_accel.cy   = s3_accel.cur_y;
 62.1350 -                        if (s3_accel.cur_y & 0x1000) s3_accel.cy |= ~0xfff;
 62.1351 +                        s3->accel.cx   = s3->accel.cur_x;
 62.1352 +                        if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff;
 62.1353 +                        s3->accel.cy   = s3->accel.cur_y;
 62.1354 +                        if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff;
 62.1355                          
 62.1356 -                        s3_accel.sy = s3_accel.maj_axis_pcnt;
 62.1357 +                        s3->accel.sy = s3->accel.maj_axis_pcnt;
 62.1358                  }
 62.1359 -                if ((s3_accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
 62.1360 -                if (s3_accel.cmd & 8) /*Radial*/
 62.1361 +                if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
 62.1362 +                if (s3->accel.cmd & 8) /*Radial*/
 62.1363                  {
 62.1364 -                        while (count-- && s3_accel.sy >= 0)
 62.1365 +                        while (count-- && s3->accel.sy >= 0)
 62.1366                          {
 62.1367 -                                if (s3_accel.cx >= clip_l && s3_accel.cx <= clip_r &&
 62.1368 -                                    s3_accel.cy >= clip_t && s3_accel.cy <= clip_b)
 62.1369 +                                if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r &&
 62.1370 +                                    s3->accel.cy >= clip_t && s3->accel.cy <= clip_b)
 62.1371                                  {
 62.1372                                          switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix)
 62.1373                                          {
 62.1374 -                                                case 0: src_dat = s3_accel.bkgd_color; break;
 62.1375 -                                                case 1: src_dat = s3_accel.frgd_color; break;
 62.1376 +                                                case 0: src_dat = s3->accel.bkgd_color; break;
 62.1377 +                                                case 1: src_dat = s3->accel.frgd_color; break;
 62.1378                                                  case 2: src_dat = cpu_dat; break;
 62.1379                                                  case 3: src_dat = 0; break;
 62.1380                                          }
 62.1381 @@ -927,44 +969,44 @@
 62.1382                                              (compare_mode == 3 && src_dat == compare) ||
 62.1383                                               compare_mode < 2)
 62.1384                                          {
 62.1385 -                                                READ((s3_accel.cy * s3_width) + s3_accel.cx, dest_dat);
 62.1386 +                                                READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat);
 62.1387                                          
 62.1388                                                  MIX
 62.1389  
 62.1390 -                                                WRITE((s3_accel.cy * s3_width) + s3_accel.cx);
 62.1391 +                                                WRITE((s3->accel.cy * s3->width) + s3->accel.cx);
 62.1392                                          }
 62.1393                                  }
 62.1394  
 62.1395                                  mix_dat <<= 1;
 62.1396                                  mix_dat |= 1;
 62.1397 -                                if (s3_bpp == 0) cpu_dat >>= 8;
 62.1398 +                                if (s3->bpp == 0) cpu_dat >>= 8;
 62.1399                                  else             cpu_dat >>= 16;
 62.1400  
 62.1401 -                                switch (s3_accel.cmd & 0xe0)
 62.1402 +                                switch (s3->accel.cmd & 0xe0)
 62.1403                                  {
 62.1404 -                                        case 0x00: s3_accel.cx++;                break;
 62.1405 -                                        case 0x20: s3_accel.cx++; s3_accel.cy--; break;
 62.1406 -                                        case 0x40:                s3_accel.cy--; break;
 62.1407 -                                        case 0x60: s3_accel.cx--; s3_accel.cy--; break;
 62.1408 -                                        case 0x80: s3_accel.cx--;                break;
 62.1409 -                                        case 0xa0: s3_accel.cx--; s3_accel.cy++; break;
 62.1410 -                                        case 0xc0:                s3_accel.cy++; break;
 62.1411 -                                        case 0xe0: s3_accel.cx++; s3_accel.cy++; break;
 62.1412 +                                        case 0x00: s3->accel.cx++;                break;
 62.1413 +                                        case 0x20: s3->accel.cx++; s3->accel.cy--; break;
 62.1414 +                                        case 0x40:                s3->accel.cy--; break;
 62.1415 +                                        case 0x60: s3->accel.cx--; s3->accel.cy--; break;
 62.1416 +                                        case 0x80: s3->accel.cx--;                break;
 62.1417 +                                        case 0xa0: s3->accel.cx--; s3->accel.cy++; break;
 62.1418 +                                        case 0xc0:                s3->accel.cy++; break;
 62.1419 +                                        case 0xe0: s3->accel.cx++; s3->accel.cy++; break;
 62.1420                                  }
 62.1421 -                                s3_accel.sy--;
 62.1422 +                                s3->accel.sy--;
 62.1423                          }
 62.1424                  }
 62.1425                  else /*Bresenham*/
 62.1426                  {
 62.1427 -                        while (count-- && s3_accel.sy >= 0)
 62.1428 +                        while (count-- && s3->accel.sy >= 0)
 62.1429                          {
 62.1430 -                                if (s3_accel.cx >= clip_l && s3_accel.cx <= clip_r &&
 62.1431 -                                    s3_accel.cy >= clip_t && s3_accel.cy <= clip_b)
 62.1432 +                                if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r &&
 62.1433 +                                    s3->accel.cy >= clip_t && s3->accel.cy <= clip_b)
 62.1434                                  {
 62.1435                                          switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix)
 62.1436                                          {
 62.1437 -                                                case 0: src_dat = s3_accel.bkgd_color; break;
 62.1438 -                                                case 1: src_dat = s3_accel.frgd_color; break;
 62.1439 +                                                case 0: src_dat = s3->accel.bkgd_color; break;
 62.1440 +                                                case 1: src_dat = s3->accel.frgd_color; break;
 62.1441                                                  case 2: src_dat = cpu_dat; break;
 62.1442                                                  case 3: src_dat = 0; break;
 62.1443                                          }
 62.1444 @@ -973,57 +1015,57 @@
 62.1445                                              (compare_mode == 3 && src_dat == compare) ||
 62.1446                                               compare_mode < 2)
 62.1447                                          {
 62.1448 -                                                READ((s3_accel.cy * s3_width) + s3_accel.cx, dest_dat);
 62.1449 +                                                READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat);
 62.1450  
 62.1451 -//                                        pclog("Line : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X (%02X %02X)  ", s3_accel.cx, s3_accel.cy, s3_accel.dest + s3_accel.cx, src_dat, vram[s3_accel.src + s3_accel.cx], mix_dat & mix_mask, s3_accel.src + s3_accel.cx, dest_dat, s3_accel.frgd_color, s3_accel.bkgd_color);
 62.1452 +//                                        pclog("Line : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X (%02X %02X)  ", s3->accel.cx, s3->accel.cy, s3->accel.dest + s3->accel.cx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat & mix_mask, s3->accel.src + s3->accel.cx, dest_dat, s3->accel.frgd_color, s3->accel.bkgd_color);
 62.1453                                          
 62.1454                                                  MIX
 62.1455  
 62.1456  //                                        pclog("%02X\n", dest_dat);
 62.1457                                          
 62.1458 -                                                WRITE((s3_accel.cy * s3_width) + s3_accel.cx);
 62.1459 +                                                WRITE((s3->accel.cy * s3->width) + s3->accel.cx);
 62.1460                                          }
 62.1461                                  }
 62.1462  
 62.1463                                  mix_dat <<= 1;
 62.1464                                  mix_dat |= 1;
 62.1465 -                                if (s3_bpp == 0) cpu_dat >>= 8;
 62.1466 +                                if (s3->bpp == 0) cpu_dat >>= 8;
 62.1467                                  else             cpu_dat >>= 16;
 62.1468  
 62.1469 -//                                pclog("%i, %i - %i %i  %i %i\n", s3_accel.cx, s3_accel.cy, s3_accel.err_term, s3_accel.maj_axis_pcnt, s3_accel.desty_axstp, s3_accel.destx_distp);
 62.1470 +//                                pclog("%i, %i - %i %i  %i %i\n", s3->accel.cx, s3->accel.cy, s3->accel.err_term, s3->accel.maj_axis_pcnt, s3->accel.desty_axstp, s3->accel.destx_distp);
 62.1471  
 62.1472 -                                if (s3_accel.err_term >= s3_accel.maj_axis_pcnt)
 62.1473 +                                if (s3->accel.err_term >= s3->accel.maj_axis_pcnt)
 62.1474                                  {
 62.1475 -                                        s3_accel.err_term += s3_accel.destx_distp;
 62.1476 +                                        s3->accel.err_term += s3->accel.destx_distp;
 62.1477                                          /*Step minor axis*/
 62.1478 -                                        switch (s3_accel.cmd & 0xe0)
 62.1479 +                                        switch (s3->accel.cmd & 0xe0)
 62.1480                                          {
 62.1481 -                                                case 0x00: s3_accel.cy--; break;
 62.1482 -                                                case 0x20: s3_accel.cy--; break;
 62.1483 -                                                case 0x40: s3_accel.cx--; break;
 62.1484 -                                                case 0x60: s3_accel.cx++; break;
 62.1485 -                                                case 0x80: s3_accel.cy++; break;
 62.1486 -                                                case 0xa0: s3_accel.cy++; break;
 62.1487 -                                                case 0xc0: s3_accel.cx--; break;
 62.1488 -                                                case 0xe0: s3_accel.cx++; break;
 62.1489 +                                                case 0x00: s3->accel.cy--; break;
 62.1490 +                                                case 0x20: s3->accel.cy--; break;
 62.1491 +                                                case 0x40: s3->accel.cx--; break;
 62.1492 +                                                case 0x60: s3->accel.cx++; break;
 62.1493 +                                                case 0x80: s3->accel.cy++; break;
 62.1494 +                                                case 0xa0: s3->accel.cy++; break;
 62.1495 +                                                case 0xc0: s3->accel.cx--; break;
 62.1496 +                                                case 0xe0: s3->accel.cx++; break;
 62.1497                                          }
 62.1498                                  }
 62.1499                                  else
 62.1500 -                                   s3_accel.err_term += s3_accel.desty_axstp;
 62.1501 +                                   s3->accel.err_term += s3->accel.desty_axstp;
 62.1502  
 62.1503                                  /*Step major axis*/
 62.1504 -                                switch (s3_accel.cmd & 0xe0)
 62.1505 +                                switch (s3->accel.cmd & 0xe0)
 62.1506                                  {
 62.1507 -                                        case 0x00: s3_accel.cx--; break;
 62.1508 -                                        case 0x20: s3_accel.cx++; break;
 62.1509 -                                        case 0x40: s3_accel.cy--; break;
 62.1510 -                                        case 0x60: s3_accel.cy--; break;
 62.1511 -                                        case 0x80: s3_accel.cx--; break;
 62.1512 -                                        case 0xa0: s3_accel.cx++; break;
 62.1513 -                                        case 0xc0: s3_accel.cy++; break;
 62.1514 -                                        case 0xe0: s3_accel.cy++; break;
 62.1515 +                                        case 0x00: s3->accel.cx--; break;
 62.1516 +                                        case 0x20: s3->accel.cx++; break;
 62.1517 +                                        case 0x40: s3->accel.cy--; break;
 62.1518 +                                        case 0x60: s3->accel.cy--; break;
 62.1519 +                                        case 0x80: s3->accel.cx--; break;
 62.1520 +                                        case 0xa0: s3->accel.cx++; break;
 62.1521 +                                        case 0xc0: s3->accel.cy++; break;
 62.1522 +                                        case 0xe0: s3->accel.cy++; break;
 62.1523                                  }
 62.1524 -                                s3_accel.sy--;
 62.1525 +                                s3->accel.sy--;
 62.1526                          }
 62.1527                  }
 62.1528                  break;
 62.1529 @@ -1031,33 +1073,33 @@
 62.1530                  case 2: /*Rectangle fill*/
 62.1531                  if (!cpu_input) /*!cpu_input is trigger to start operation*/
 62.1532                  {
 62.1533 -                        s3_accel.sx   = s3_accel.maj_axis_pcnt & 0xfff;
 62.1534 -                        s3_accel.sy   = s3_accel.multifunc[0]  & 0xfff;
 62.1535 -                        s3_accel.cx   = s3_accel.cur_x;
 62.1536 -                        if (s3_accel.cur_x & 0x1000) s3_accel.cx |= ~0xfff;
 62.1537 -                        s3_accel.cy   = s3_accel.cur_y;
 62.1538 -                        if (s3_accel.cur_y & 0x1000) s3_accel.cy |= ~0xfff;
 62.1539 +                        s3->accel.sx   = s3->accel.maj_axis_pcnt & 0xfff;
 62.1540 +                        s3->accel.sy   = s3->accel.multifunc[0]  & 0xfff;
 62.1541 +                        s3->accel.cx   = s3->accel.cur_x;
 62.1542 +                        if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff;
 62.1543 +                        s3->accel.cy   = s3->accel.cur_y;
 62.1544 +                        if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff;
 62.1545                          
 62.1546 -                        s3_accel.dest = s3_accel.cy * s3_width;
 62.1547 +                        s3->accel.dest = s3->accel.cy * s3->width;
 62.1548  
 62.1549 -//                        pclog("Dest %08X  (%i, %i) %04X %04X\n", s3_accel.dest, s3_accel.cx, s3_accel.cy, s3_accel.cur_x, s3_accel.cur_x & 0x1000);
 62.1550 +//                        pclog("Dest %08X  (%i, %i) %04X %04X\n", s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.cur_x, s3->accel.cur_x & 0x1000);
 62.1551                  }
 62.1552 -                if ((s3_accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
 62.1553 -//                if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/
 62.1554 +                if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
 62.1555 +//                if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/
 62.1556  //                   return;
 62.1557  
 62.1558 -                frgd_mix = (s3_accel.frgd_mix >> 5) & 3;
 62.1559 -                bkgd_mix = (s3_accel.bkgd_mix >> 5) & 3;
 62.1560 +                frgd_mix = (s3->accel.frgd_mix >> 5) & 3;
 62.1561 +                bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3;
 62.1562                  
 62.1563 -                while (count-- && s3_accel.sy >= 0)
 62.1564 +                while (count-- && s3->accel.sy >= 0)
 62.1565                  {
 62.1566 -                        if (s3_accel.cx >= clip_l && s3_accel.cx <= clip_r &&
 62.1567 -                            s3_accel.cy >= clip_t && s3_accel.cy <= clip_b)
 62.1568 +                        if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r &&
 62.1569 +                            s3->accel.cy >= clip_t && s3->accel.cy <= clip_b)
 62.1570                          {
 62.1571                                  switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix)
 62.1572                                  {
 62.1573 -                                        case 0: src_dat = s3_accel.bkgd_color; break;
 62.1574 -                                        case 1: src_dat = s3_accel.frgd_color; break;
 62.1575 +                                        case 0: src_dat = s3->accel.bkgd_color; break;
 62.1576 +                                        case 1: src_dat = s3->accel.frgd_color; break;
 62.1577                                          case 2: src_dat = cpu_dat; break;
 62.1578                                          case 3: src_dat = 0; break;
 62.1579                                  }
 62.1580 @@ -1066,42 +1108,42 @@
 62.1581                                      (compare_mode == 3 && src_dat == compare) ||
 62.1582                                       compare_mode < 2)
 62.1583                                  {
 62.1584 -                                        READ(s3_accel.dest + s3_accel.cx, dest_dat);
 62.1585 +                                        READ(s3->accel.dest + s3->accel.cx, dest_dat);
 62.1586                                  
 62.1587 -//                                if (CS != 0xc000) pclog("Write %05X  %02X %02X  %04X (%02X %02X)  ", s3_accel.dest + s3_accel.cx, src_dat, dest_dat, mix_dat, s3_accel.frgd_mix, s3_accel.bkgd_mix);
 62.1588 +//                                if (CS != 0xc000) pclog("Write %05X  %02X %02X  %04X (%02X %02X)  ", s3->accel.dest + s3->accel.cx, src_dat, dest_dat, mix_dat, s3->accel.frgd_mix, s3->accel.bkgd_mix);
 62.1589  
 62.1590                                          MIX
 62.1591                                  
 62.1592  //                                if (CS != 0xc000) pclog("%02X\n", dest_dat);
 62.1593                                  
 62.1594 -                                        WRITE(s3_accel.dest + s3_accel.cx);
 62.1595 +                                        WRITE(s3->accel.dest + s3->accel.cx);
 62.1596                                  }
 62.1597                          }
 62.1598                  
 62.1599                          mix_dat <<= 1;
 62.1600                          mix_dat |= 1;
 62.1601 -                        if (s3_bpp == 0) cpu_dat >>= 8;
 62.1602 +                        if (s3->bpp == 0) cpu_dat >>= 8;
 62.1603                          else             cpu_dat >>= 16;
 62.1604                          
 62.1605 -                        if (s3_accel.cmd & 0x20) s3_accel.cx++;
 62.1606 -                        else                     s3_accel.cx--;
 62.1607 -                        s3_accel.sx--;
 62.1608 -                        if (s3_accel.sx < 0)
 62.1609 +                        if (s3->accel.cmd & 0x20) s3->accel.cx++;
 62.1610 +                        else                     s3->accel.cx--;
 62.1611 +                        s3->accel.sx--;
 62.1612 +                        if (s3->accel.sx < 0)
 62.1613                          {
 62.1614 -                                if (s3_accel.cmd & 0x20) s3_accel.cx   -= (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.1615 -                                else                     s3_accel.cx   += (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.1616 -//                                s3_accel.dest -= (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.1617 -                                s3_accel.sx    = s3_accel.maj_axis_pcnt & 0xfff;
 62.1618 +                                if (s3->accel.cmd & 0x20) s3->accel.cx   -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.1619 +                                else                     s3->accel.cx   += (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.1620 +//                                s3->accel.dest -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.1621 +                                s3->accel.sx    = s3->accel.maj_axis_pcnt & 0xfff;
 62.1622                                  
 62.1623 -//                                s3_accel.dest  += s3_width;
 62.1624 -                                if (s3_accel.cmd & 0x80) s3_accel.cy++;
 62.1625 -                                else                     s3_accel.cy--;
 62.1626 +//                                s3->accel.dest  += s3_width;
 62.1627 +                                if (s3->accel.cmd & 0x80) s3->accel.cy++;
 62.1628 +                                else                     s3->accel.cy--;
 62.1629                                  
 62.1630 -                                s3_accel.dest = s3_accel.cy * s3_width;
 62.1631 -                                s3_accel.sy--;
 62.1632 +                                s3->accel.dest = s3->accel.cy * s3->width;
 62.1633 +                                s3->accel.sy--;
 62.1634  
 62.1635 -                                if (cpu_input/* && (s3_accel.multifunc[0xa] & 0xc0) == 0x80*/) return;
 62.1636 -                                if (s3_accel.sy < 0)
 62.1637 +                                if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return;
 62.1638 +                                if (s3->accel.sy < 0)
 62.1639                                  {
 62.1640                                          return;
 62.1641                                  }
 62.1642 @@ -1112,155 +1154,155 @@
 62.1643                  case 6: /*BitBlt*/
 62.1644                  if (!cpu_input) /*!cpu_input is trigger to start operation*/
 62.1645                  {
 62.1646 -                        s3_accel.sx   = s3_accel.maj_axis_pcnt & 0xfff;
 62.1647 -                        s3_accel.sy   = s3_accel.multifunc[0]  & 0xfff;
 62.1648 +                        s3->accel.sx   = s3->accel.maj_axis_pcnt & 0xfff;
 62.1649 +                        s3->accel.sy   = s3->accel.multifunc[0]  & 0xfff;
 62.1650  
 62.1651 -                        s3_accel.dx   = s3_accel.destx_distp & 0xfff;
 62.1652 -                        if (s3_accel.destx_distp & 0x1000) s3_accel.dx |= ~0xfff;
 62.1653 -                        s3_accel.dy   = s3_accel.desty_axstp & 0xfff;
 62.1654 -                        if (s3_accel.desty_axstp & 0x1000) s3_accel.dy |= ~0xfff;
 62.1655 +                        s3->accel.dx   = s3->accel.destx_distp & 0xfff;
 62.1656 +                        if (s3->accel.destx_distp & 0x1000) s3->accel.dx |= ~0xfff;
 62.1657 +                        s3->accel.dy   = s3->accel.desty_axstp & 0xfff;
 62.1658 +                        if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff;
 62.1659  
 62.1660 -                        s3_accel.cx   = s3_accel.cur_x & 0xfff;
 62.1661 -                        if (s3_accel.cur_x & 0x1000) s3_accel.cx |= ~0xfff;
 62.1662 -                        s3_accel.cy   = s3_accel.cur_y & 0xfff;
 62.1663 -                        if (s3_accel.cur_y & 0x1000) s3_accel.cy |= ~0xfff;
 62.1664 +                        s3->accel.cx   = s3->accel.cur_x & 0xfff;
 62.1665 +                        if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff;
 62.1666 +                        s3->accel.cy   = s3->accel.cur_y & 0xfff;
 62.1667 +                        if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff;
 62.1668  
 62.1669 -                        s3_accel.src  = s3_accel.cy * s3_width;
 62.1670 -                        s3_accel.dest = s3_accel.dy * s3_width;
 62.1671 +                        s3->accel.src  = s3->accel.cy * s3->width;
 62.1672 +                        s3->accel.dest = s3->accel.dy * s3->width;
 62.1673                          
 62.1674 -//                        pclog("Source %08X Dest %08X  (%i, %i) - (%i, %i)\n", s3_accel.src, s3_accel.dest, s3_accel.cx, s3_accel.cy, s3_accel.dx, s3_accel.dy);
 62.1675 +//                        pclog("Source %08X Dest %08X  (%i, %i) - (%i, %i)\n", s3->accel.src, s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy);
 62.1676                  }
 62.1677 -                if ((s3_accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
 62.1678 -//                if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/
 62.1679 +                if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
 62.1680 +//                if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/
 62.1681  //                  return;
 62.1682  
 62.1683 -                if (s3_accel.sy < 0)
 62.1684 +                if (s3->accel.sy < 0)
 62.1685                     return;
 62.1686  
 62.1687 -                frgd_mix = (s3_accel.frgd_mix >> 5) & 3;
 62.1688 -                bkgd_mix = (s3_accel.bkgd_mix >> 5) & 3;
 62.1689 +                frgd_mix = (s3->accel.frgd_mix >> 5) & 3;
 62.1690 +                bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3;
 62.1691                  
 62.1692                  if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode &&
 62.1693 -                    (s3_accel.cmd & 0xa0) == 0xa0 && (s3_accel.frgd_mix & 0xf) == 7) 
 62.1694 +                    (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7) 
 62.1695                  {
 62.1696                          while (1)
 62.1697                          {
 62.1698 -                                if (s3_accel.dx >= clip_l && s3_accel.dx <= clip_r &&
 62.1699 -                                    s3_accel.dy >= clip_t && s3_accel.dy <= clip_b)
 62.1700 +                                if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r &&
 62.1701 +                                    s3->accel.dy >= clip_t && s3->accel.dy <= clip_b)
 62.1702                                  {
 62.1703 -                                        READ(s3_accel.src + s3_accel.cx, src_dat);
 62.1704 +                                        READ(s3->accel.src + s3->accel.cx, src_dat);
 62.1705          
 62.1706                                          dest_dat = src_dat;
 62.1707                                          
 62.1708 -                                        WRITE(s3_accel.dest + s3_accel.dx);
 62.1709 +                                        WRITE(s3->accel.dest + s3->accel.dx);
 62.1710                                  }
 62.1711          
 62.1712 -                                s3_accel.cx++;
 62.1713 -                                s3_accel.dx++;
 62.1714 -                                s3_accel.sx--;
 62.1715 -                                if (s3_accel.sx < 0)
 62.1716 +                                s3->accel.cx++;
 62.1717 +                                s3->accel.dx++;
 62.1718 +                                s3->accel.sx--;
 62.1719 +                                if (s3->accel.sx < 0)
 62.1720                                  {
 62.1721 -                                        s3_accel.cx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.1722 -                                        s3_accel.dx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.1723 -                                        s3_accel.sx  =  s3_accel.maj_axis_pcnt & 0xfff;
 62.1724 +                                        s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.1725 +                                        s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.1726 +                                        s3->accel.sx  =  s3->accel.maj_axis_pcnt & 0xfff;
 62.1727          
 62.1728 -                                        s3_accel.cy++;
 62.1729 -                                        s3_accel.dy++;
 62.1730 +                                        s3->accel.cy++;
 62.1731 +                                        s3->accel.dy++;
 62.1732          
 62.1733 -                                        s3_accel.src  = s3_accel.cy * s3_width;
 62.1734 -                                        s3_accel.dest = s3_accel.dy * s3_width;
 62.1735 +                                        s3->accel.src  = s3->accel.cy * s3->width;
 62.1736 +                                        s3->accel.dest = s3->accel.dy * s3->width;
 62.1737          
 62.1738 -                                        s3_accel.sy--;
 62.1739 +                                        s3->accel.sy--;
 62.1740          
 62.1741 -                                        if (s3_accel.sy < 0)
 62.1742 +                                        if (s3->accel.sy < 0)
 62.1743                                             return;
 62.1744                                  }
 62.1745                          }
 62.1746                  }
 62.1747                  else
 62.1748                  {                     
 62.1749 -                        while (count-- && s3_accel.sy >= 0)
 62.1750 +                        while (count-- && s3->accel.sy >= 0)
 62.1751                          {
 62.1752 -                                if (s3_accel.dx >= clip_l && s3_accel.dx <= clip_r &&
 62.1753 -                                    s3_accel.dy >= clip_t && s3_accel.dy <= clip_b)
 62.1754 +                                if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r &&
 62.1755 +                                    s3->accel.dy >= clip_t && s3->accel.dy <= clip_b)
 62.1756                                  {
 62.1757                                          if (vram_mask)
 62.1758                                          {
 62.1759 -                                                READ(s3_accel.src + s3_accel.cx, mix_dat)
 62.1760 +                                                READ(s3->accel.src + s3->accel.cx, mix_dat)
 62.1761                                                  mix_dat = mix_dat ? mix_mask : 0;
 62.1762                                          }
 62.1763                                          switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix)
 62.1764                                          {
 62.1765 -                                                case 0: src_dat = s3_accel.bkgd_color;                  break;
 62.1766 -                                                case 1: src_dat = s3_accel.frgd_color;                  break;
 62.1767 +                                                case 0: src_dat = s3->accel.bkgd_color;                  break;
 62.1768 +                                                case 1: src_dat = s3->accel.frgd_color;                  break;
 62.1769                                                  case 2: src_dat = cpu_dat;                              break;
 62.1770 -                                                case 3: READ(s3_accel.src + s3_accel.cx, src_dat);      break;
 62.1771 +                                                case 3: READ(s3->accel.src + s3->accel.cx, src_dat);      break;
 62.1772                                          }
 62.1773  
 62.1774                                          if ((compare_mode == 2 && src_dat != compare) ||
 62.1775                                              (compare_mode == 3 && src_dat == compare) ||
 62.1776                                               compare_mode < 2)
 62.1777                                          {
 62.1778 -                                                READ(s3_accel.dest + s3_accel.dx, dest_dat);
 62.1779 +                                                READ(s3->accel.dest + s3->accel.dx, dest_dat);
 62.1780                                                                                  
 62.1781 -//                                pclog("BitBlt : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X   ", s3_accel.dx, s3_accel.dy, s3_accel.dest + s3_accel.dx, src_dat, vram[s3_accel.src + s3_accel.cx], mix_dat, s3_accel.src + s3_accel.cx, dest_dat);
 62.1782 +//                                pclog("BitBlt : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X   ", s3->accel.dx, s3->accel.dy, s3->accel.dest + s3->accel.dx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat, s3->accel.src + s3->accel.cx, dest_dat);
 62.1783                                  
 62.1784                                                  MIX
 62.1785  
 62.1786  //                                pclog("%02X\n", dest_dat);
 62.1787  
 62.1788 -                                                WRITE(s3_accel.dest + s3_accel.dx);
 62.1789 +                                                WRITE(s3->accel.dest + s3->accel.dx);
 62.1790                                          }
 62.1791                                  }
 62.1792  
 62.1793                                  mix_dat <<= 1;
 62.1794                                  mix_dat |= 1;
 62.1795 -                                if (s3_bpp == 0) cpu_dat >>= 8;
 62.1796 +                                if (s3->bpp == 0) cpu_dat >>= 8;
 62.1797                                  else             cpu_dat >>= 16;
 62.1798  
 62.1799 -                                if (s3_accel.cmd & 0x20)
 62.1800 +                                if (s3->accel.cmd & 0x20)
 62.1801                                  {
 62.1802 -                                        s3_accel.cx++;
 62.1803 -                                        s3_accel.dx++;
 62.1804 +                                        s3->accel.cx++;
 62.1805 +                                        s3->accel.dx++;
 62.1806                                  }
 62.1807                                  else
 62.1808                                  {
 62.1809 -                                        s3_accel.cx--;
 62.1810 -                                        s3_accel.dx--;
 62.1811 +                                        s3->accel.cx--;
 62.1812 +                                        s3->accel.dx--;
 62.1813                                  }
 62.1814 -                                s3_accel.sx--;
 62.1815 -                                if (s3_accel.sx < 0)
 62.1816 +                                s3->accel.sx--;
 62.1817 +                                if (s3->accel.sx < 0)
 62.1818                                  {
 62.1819 -                                        if (s3_accel.cmd & 0x20)
 62.1820 +                                        if (s3->accel.cmd & 0x20)
 62.1821                                          {
 62.1822 -                                                s3_accel.cx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.1823 -                                                s3_accel.dx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.1824 +                                                s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.1825 +                                                s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.1826                                          }
 62.1827                                          else
 62.1828                                          {
 62.1829 -                                                s3_accel.cx += (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.1830 -                                                s3_accel.dx += (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.1831 +                                                s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.1832 +                                                s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.1833                                          }
 62.1834 -                                        s3_accel.sx    =  s3_accel.maj_axis_pcnt & 0xfff;
 62.1835 +                                        s3->accel.sx    =  s3->accel.maj_axis_pcnt & 0xfff;
 62.1836  
 62.1837 -                                        if (s3_accel.cmd & 0x80)
 62.1838 +                                        if (s3->accel.cmd & 0x80)
 62.1839                                          {
 62.1840 -                                                s3_accel.cy++;
 62.1841 -                                                s3_accel.dy++;
 62.1842 +                                                s3->accel.cy++;
 62.1843 +                                                s3->accel.dy++;
 62.1844                                          }
 62.1845                                          else
 62.1846                                          {
 62.1847 -                                                s3_accel.cy--;
 62.1848 -                                                s3_accel.dy--;
 62.1849 +                                                s3->accel.cy--;
 62.1850 +                                                s3->accel.dy--;
 62.1851                                          }
 62.1852  
 62.1853 -                                        s3_accel.src  = s3_accel.cy * s3_width;
 62.1854 -                                        s3_accel.dest = s3_accel.dy * s3_width;
 62.1855 +                                        s3->accel.src  = s3->accel.cy * s3->width;
 62.1856 +                                        s3->accel.dest = s3->accel.dy * s3->width;
 62.1857  
 62.1858 -                                        s3_accel.sy--;
 62.1859 +                                        s3->accel.sy--;
 62.1860  
 62.1861 -                                        if (cpu_input/* && (s3_accel.multifunc[0xa] & 0xc0) == 0x80*/) return;
 62.1862 -                                        if (s3_accel.sy < 0)
 62.1863 +                                        if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return;
 62.1864 +                                        if (s3->accel.sy < 0)
 62.1865                                          {
 62.1866                                                  return;
 62.1867                                          }
 62.1868 @@ -1272,124 +1314,124 @@
 62.1869                  case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/
 62.1870                  if (!cpu_input) /*!cpu_input is trigger to start operation*/
 62.1871                  {
 62.1872 -                        s3_accel.sx   = s3_accel.maj_axis_pcnt & 0xfff;
 62.1873 -                        s3_accel.sy   = s3_accel.multifunc[0]  & 0xfff;
 62.1874 +                        s3->accel.sx   = s3->accel.maj_axis_pcnt & 0xfff;
 62.1875 +                        s3->accel.sy   = s3->accel.multifunc[0]  & 0xfff;
 62.1876  
 62.1877 -                        s3_accel.dx   = s3_accel.destx_distp & 0xfff;
 62.1878 -                        if (s3_accel.destx_distp & 0x1000) s3_accel.dx |= ~0xfff;
 62.1879 -                        s3_accel.dy   = s3_accel.desty_axstp & 0xfff;
 62.1880 -                        if (s3_accel.desty_axstp & 0x1000) s3_accel.dy |= ~0xfff;
 62.1881 +                        s3->accel.dx   = s3->accel.destx_distp & 0xfff;
 62.1882 +                        if (s3->accel.destx_distp & 0x1000) s3->accel.dx |= ~0xfff;
 62.1883 +                        s3->accel.dy   = s3->accel.desty_axstp & 0xfff;
 62.1884 +                        if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff;
 62.1885  
 62.1886 -                        s3_accel.cx   = s3_accel.cur_x & 0xfff;
 62.1887 -                        if (s3_accel.cur_x & 0x1000) s3_accel.cx |= ~0xfff;
 62.1888 -                        s3_accel.cy   = s3_accel.cur_y & 0xfff;
 62.1889 -                        if (s3_accel.cur_y & 0x1000) s3_accel.cy |= ~0xfff;
 62.1890 +                        s3->accel.cx   = s3->accel.cur_x & 0xfff;
 62.1891 +                        if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff;
 62.1892 +                        s3->accel.cy   = s3->accel.cur_y & 0xfff;
 62.1893 +                        if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff;
 62.1894                          
 62.1895                          /*Align source with destination*/
 62.1896 -//                        s3_accel.cx = (s3_accel.cx & ~7) | (s3_accel.dx & 7);
 62.1897 -//                        s3_accel.cy = (s3_accel.cy & ~7) | (s3_accel.dy & 7);
 62.1898 +//                        s3->accel.cx = (s3->accel.cx & ~7) | (s3->accel.dx & 7);
 62.1899 +//                        s3->accel.cy = (s3->accel.cy & ~7) | (s3->accel.dy & 7);
 62.1900  
 62.1901 -                        s3_accel.pattern  = (s3_accel.cy * s3_width) + s3_accel.cx;
 62.1902 -                        s3_accel.dest     = s3_accel.dy * s3_width;
 62.1903 +                        s3->accel.pattern  = (s3->accel.cy * s3->width) + s3->accel.cx;
 62.1904 +                        s3->accel.dest     = s3->accel.dy * s3->width;
 62.1905                          
 62.1906 -                        s3_accel.cx = s3_accel.dx & 7;
 62.1907 -                        s3_accel.cy = s3_accel.dy & 7;
 62.1908 +                        s3->accel.cx = s3->accel.dx & 7;
 62.1909 +                        s3->accel.cy = s3->accel.dy & 7;
 62.1910                          
 62.1911 -                        s3_accel.src  = s3_accel.pattern + (s3_accel.cy * s3_width);
 62.1912 +                        s3->accel.src  = s3->accel.pattern + (s3->accel.cy * s3->width);
 62.1913  
 62.1914 -//                        pclog("Source %08X Dest %08X  (%i, %i) - (%i, %i)\n", s3_accel.src, s3_accel.dest, s3_accel.cx, s3_accel.cy, s3_accel.dx, s3_accel.dy);
 62.1915 +//                        pclog("Source %08X Dest %08X  (%i, %i) - (%i, %i)\n", s3->accel.src, s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy);
 62.1916  //                        dumpregs();
 62.1917  //                        exit(-1);
 62.1918                  }
 62.1919 -                if ((s3_accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
 62.1920 -//                if ((s3_accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/
 62.1921 +                if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/
 62.1922 +//                if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/
 62.1923  //                   return;
 62.1924  
 62.1925 -                frgd_mix = (s3_accel.frgd_mix >> 5) & 3;
 62.1926 -                bkgd_mix = (s3_accel.bkgd_mix >> 5) & 3;
 62.1927 +                frgd_mix = (s3->accel.frgd_mix >> 5) & 3;
 62.1928 +                bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3;
 62.1929  
 62.1930 -                while (count-- && s3_accel.sy >= 0)
 62.1931 +                while (count-- && s3->accel.sy >= 0)
 62.1932                  {
 62.1933 -                        if (s3_accel.dx >= clip_l && s3_accel.dx <= clip_r &&
 62.1934 -                            s3_accel.dy >= clip_t && s3_accel.dy <= clip_b)
 62.1935 +                        if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r &&
 62.1936 +                            s3->accel.dy >= clip_t && s3->accel.dy <= clip_b)
 62.1937                          {
 62.1938                                  if (vram_mask)
 62.1939                                  {
 62.1940 -                                        READ(s3_accel.src + s3_accel.cx, mix_dat)
 62.1941 +                                        READ(s3->accel.src + s3->accel.cx, mix_dat)
 62.1942                                          mix_dat = mix_dat ? mix_mask : 0;
 62.1943                                  }
 62.1944                                  switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix)
 62.1945                                  {
 62.1946 -                                        case 0: src_dat = s3_accel.bkgd_color;                  break;
 62.1947 -                                        case 1: src_dat = s3_accel.frgd_color;                  break;
 62.1948 +                                        case 0: src_dat = s3->accel.bkgd_color;                  break;
 62.1949 +                                        case 1: src_dat = s3->accel.frgd_color;                  break;
 62.1950                                          case 2: src_dat = cpu_dat;                              break;
 62.1951 -                                        case 3: READ(s3_accel.src + s3_accel.cx, src_dat);      break;
 62.1952 +                                        case 3: READ(s3->accel.src + s3->accel.cx, src_dat);      break;
 62.1953                                  }
 62.1954  
 62.1955                                  if ((compare_mode == 2 && src_dat != compare) ||
 62.1956                                      (compare_mode == 3 && src_dat == compare) ||
 62.1957                                       compare_mode < 2)
 62.1958                                  {
 62.1959 -                                        READ(s3_accel.dest + s3_accel.dx, dest_dat);
 62.1960 +                                        READ(s3->accel.dest + s3->accel.dx, dest_dat);
 62.1961                                  
 62.1962 -//                                pclog("Pattern fill : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X   ", s3_accel.dx, s3_accel.dy, s3_accel.dest + s3_accel.dx, src_dat, vram[s3_accel.src + s3_accel.cx], mix_dat, s3_accel.src + s3_accel.cx, dest_dat);
 62.1963 +//                                pclog("Pattern fill : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X   ", s3->accel.dx, s3->accel.dy, s3->accel.dest + s3->accel.dx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat, s3->accel.src + s3->accel.cx, dest_dat);
 62.1964  
 62.1965                                          MIX
 62.1966  
 62.1967  //                                pclog("%02X\n", dest_dat);
 62.1968  
 62.1969 -                                        WRITE(s3_accel.dest + s3_accel.dx);
 62.1970 +                                        WRITE(s3->accel.dest + s3->accel.dx);
 62.1971                                  }
 62.1972                          }
 62.1973  
 62.1974                          mix_dat <<= 1;
 62.1975                          mix_dat |= 1;
 62.1976 -                        if (s3_bpp == 0) cpu_dat >>= 8;
 62.1977 +                        if (s3->bpp == 0) cpu_dat >>= 8;
 62.1978                          else             cpu_dat >>= 16;
 62.1979  
 62.1980 -                        if (s3_accel.cmd & 0x20)
 62.1981 +                        if (s3->accel.cmd & 0x20)
 62.1982                          {
 62.1983 -                                s3_accel.cx = ((s3_accel.cx + 1) & 7) | (s3_accel.cx & ~7);
 62.1984 -                                s3_accel.dx++;
 62.1985 +                                s3->accel.cx = ((s3->accel.cx + 1) & 7) | (s3->accel.cx & ~7);
 62.1986 +                                s3->accel.dx++;
 62.1987                          }
 62.1988                          else
 62.1989                          {
 62.1990 -                                s3_accel.cx = ((s3_accel.cx - 1) & 7) | (s3_accel.cx & ~7);
 62.1991 -                                s3_accel.dx--;
 62.1992 +                                s3->accel.cx = ((s3->accel.cx - 1) & 7) | (s3->accel.cx & ~7);
 62.1993 +                                s3->accel.dx--;
 62.1994                          }
 62.1995 -                        s3_accel.sx--;
 62.1996 -                        if (s3_accel.sx < 0)
 62.1997 +                        s3->accel.sx--;
 62.1998 +                        if (s3->accel.sx < 0)
 62.1999                          {
 62.2000 -                                if (s3_accel.cmd & 0x20)
 62.2001 +                                if (s3->accel.cmd & 0x20)
 62.2002                                  {
 62.2003 -                                        s3_accel.cx = ((s3_accel.cx - ((s3_accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3_accel.cx & ~7);
 62.2004 -                                        s3_accel.dx -= (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.2005 +                                        s3->accel.cx = ((s3->accel.cx - ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7);
 62.2006 +                                        s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.2007                                  }
 62.2008                                  else
 62.2009                                  {
 62.2010 -                                        s3_accel.cx = ((s3_accel.cx + ((s3_accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3_accel.cx & ~7);
 62.2011 -                                        s3_accel.dx += (s3_accel.maj_axis_pcnt & 0xfff) + 1;
 62.2012 +                                        s3->accel.cx = ((s3->accel.cx + ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7);
 62.2013 +                                        s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1;
 62.2014                                  }
 62.2015 -                                s3_accel.sx    =  s3_accel.maj_axis_pcnt & 0xfff;
 62.2016 +                                s3->accel.sx    =  s3->accel.maj_axis_pcnt & 0xfff;
 62.2017  
 62.2018 -                                if (s3_accel.cmd & 0x80)
 62.2019 +                                if (s3->accel.cmd & 0x80)
 62.2020                                  {
 62.2021 -                                        s3_accel.cy = ((s3_accel.cy + 1) & 7) | (s3_accel.cy & ~7);
 62.2022 -                                        s3_accel.dy++;
 62.2023 +                                        s3->accel.cy = ((s3->accel.cy + 1) & 7) | (s3->accel.cy & ~7);
 62.2024 +                                        s3->accel.dy++;
 62.2025                                  }
 62.2026                                  else
 62.2027                                  {
 62.2028 -                                        s3_accel.cy = ((s3_accel.cy - 1) & 7) | (s3_accel.cy & ~7);
 62.2029 -                                        s3_accel.dy--;
 62.2030 +                                        s3->accel.cy = ((s3->accel.cy - 1) & 7) | (s3->accel.cy & ~7);
 62.2031 +                                        s3->accel.dy--;
 62.2032                                  }
 62.2033  
 62.2034 -                                s3_accel.src  = s3_accel.pattern + (s3_accel.cy * s3_width);
 62.2035 -                                s3_accel.dest = s3_accel.dy * s3_width;
 62.2036 +                                s3->accel.src  = s3->accel.pattern + (s3->accel.cy * s3->width);
 62.2037 +                                s3->accel.dest = s3->accel.dy * s3->width;
 62.2038  
 62.2039 -                                s3_accel.sy--;
 62.2040 +                                s3->accel.sy--;
 62.2041  
 62.2042 -                                if (cpu_input/* && (s3_accel.multifunc[0xa] & 0xc0) == 0x80*/) return;
 62.2043 -                                if (s3_accel.sy < 0)
 62.2044 +                                if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return;
 62.2045 +                                if (s3->accel.sy < 0)
 62.2046                                  {
 62.2047                                          return;
 62.2048                                  }
 62.2049 @@ -1399,21 +1441,21 @@
 62.2050          }
 62.2051  }
 62.2052  
 62.2053 -void s3_hwcursor_draw(int displine)
 62.2054 +void s3_hwcursor_draw(svga_t *svga, int displine)
 62.2055  {
 62.2056          int x;
 62.2057          uint16_t dat[2];
 62.2058          int xx;
 62.2059 -        int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff;
 62.2060 +        int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
 62.2061          
 62.2062 -        pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y);
 62.2063 +        pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y);
 62.2064          for (x = 0; x < 64; x += 16)
 62.2065          {
 62.2066 -                dat[0] = (vram[svga_hwcursor_latch.addr]     << 8) | vram[svga_hwcursor_latch.addr + 1];
 62.2067 -                dat[1] = (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3];
 62.2068 +                dat[0] = (svga->vram[svga->hwcursor_latch.addr]     << 8) | svga->vram[svga->hwcursor_latch.addr + 1];
 62.2069 +                dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
 62.2070                  for (xx = 0; xx < 16; xx++)
 62.2071                  {
 62.2072 -                        if (offset >= svga_hwcursor_latch.x)
 62.2073 +                        if (offset >= svga->hwcursor_latch.x)
 62.2074                          {
 62.2075                                  if (!(dat[0] & 0x8000))
 62.2076                                     ((uint32_t *)buffer32->line[displine])[offset + 32]  = (dat[1] & 0x8000) ? 0xffffff : 0;
 62.2077 @@ -1426,20 +1468,22 @@
 62.2078                          dat[0] <<= 1;
 62.2079                          dat[1] <<= 1;
 62.2080                  }
 62.2081 -                svga_hwcursor_latch.addr += 4;
 62.2082 +                svga->hwcursor_latch.addr += 4;
 62.2083          }
 62.2084  }
 62.2085  
 62.2086  
 62.2087 -uint8_t s3_pci_read(int func, int addr, void *priv)
 62.2088 +uint8_t s3_pci_read(int func, int addr, void *p)
 62.2089  {
 62.2090 +        s3_t *s3 = (s3_t *)p;
 62.2091 +        svga_t *svga = &s3->svga;
 62.2092  //        pclog("S3 PCI read %08X\n", addr);
 62.2093          switch (addr)
 62.2094          {
 62.2095                  case 0x00: return 0x33; /*'S3'*/
 62.2096                  case 0x01: return 0x53;
 62.2097                  
 62.2098 -                case 0x02: return s3_id_ext;
 62.2099 +                case 0x02: return s3->id_ext;
 62.2100                  case 0x03: return 0x88;
 62.2101                  
 62.2102                  case 0x04: return 0x03; /*Respond to IO and memory accesses*/
 62.2103 @@ -1454,8 +1498,8 @@
 62.2104                  
 62.2105                  case 0x10: return 0x00; /*Linear frame buffer address*/
 62.2106                  case 0x11: return 0x00;
 62.2107 -                case 0x12: return crtc[0x5a] & 0x80;
 62.2108 -                case 0x13: return crtc[0x59];
 62.2109 +                case 0x12: return svga->crtc[0x5a] & 0x80;
 62.2110 +                case 0x13: return svga->crtc[0x59];
 62.2111  
 62.2112                  case 0x30: return 0x01; /*BIOS ROM address*/
 62.2113                  case 0x31: return 0x00;
 62.2114 @@ -1465,86 +1509,115 @@
 62.2115          return 0;
 62.2116  }
 62.2117  
 62.2118 -void s3_pci_write(int func, int addr, uint8_t val, void *priv)
 62.2119 +void s3_pci_write(int func, int addr, uint8_t val, void *p)
 62.2120  {
 62.2121 +        s3_t *s3 = (s3_t *)p;
 62.2122 +        svga_t *svga = &s3->svga;
 62.2123          switch (addr)
 62.2124          {
 62.2125 -                case 0x12: crtc[0x5a] = val & 0x80; s3_updatemapping(); break;
 62.2126 -                case 0x13: crtc[0x59] = val;        s3_updatemapping(); break;                
 62.2127 +                case 0x12: 
 62.2128 +                svga->crtc[0x5a] = val & 0x80; 
 62.2129 +                s3_updatemapping(s3); 
 62.2130 +                break;
 62.2131 +                case 0x13: 
 62.2132 +                svga->crtc[0x59] = val;        
 62.2133 +                s3_updatemapping(s3); 
 62.2134 +                break;                
 62.2135          }
 62.2136  }
 62.2137  
 62.2138 -int s3_init()
 62.2139 +static void *s3_init()
 62.2140  {
 62.2141 -        if (gfxcard == GFX_BAHAMAS64)
 62.2142 -        {
 62.2143 -                s3_id = 0xc1; /*Vision864P*/
 62.2144 -                s3_id_ext = 0xc1; /*Trio64*/
 62.2145 -        }
 62.2146 -        if (gfxcard == GFX_N9_9FX)
 62.2147 -        {
 62.2148 -                s3_id = 0xe1;
 62.2149 -                s3_id_ext = 0x11; /*Trio64*/
 62.2150 -        }
 62.2151 -        if (gfxcard == GFX_STEALTH64)
 62.2152 -        {
 62.2153 -                s3_id = 0xe1; /*Trio64*/
 62.2154 -                s3_id_ext = 0x11;
 62.2155 -        }
 62.2156 -        svga_recalctimings_ex = s3_recalctimings;
 62.2157 -        svga_hwcursor_draw    = s3_hwcursor_draw;
 62.2158 +        s3_t *s3 = malloc(sizeof(s3_t));
 62.2159 +        svga_t *svga = &s3->svga;
 62.2160 +        memset(s3, 0, sizeof(s3_t));
 62.2161 +        
 62.2162 +        svga_init(&s3->svga, s3, 1 << 22, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/
 62.2163 +                   s3_recalctimings,
 62.2164 +                   s3_in, s3_out,
 62.2165 +                   s3_hwcursor_draw);
 62.2166  
 62.2167 -        crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
 62.2168 -        crtc[0x37] = 1 | (7 << 5);
 62.2169 +        io_sethandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3);
 62.2170 +
 62.2171 +        svga->crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
 62.2172 +        svga->crtc[0x37] = 1 | (7 << 5);
 62.2173          
 62.2174 -        vrammask = 0x3fffff;
 62.2175 +        io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2176 +        io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2177 +        io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2178 +        io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2179 +        io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2180 +        io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2181 +        io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2182 +        io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2183 +        io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2184 +        io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2185 +        io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2186 +        io_sethandler(0xa2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2187 +        io_sethandler(0xa6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2188 +        io_sethandler(0xaae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2189 +        io_sethandler(0xaee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2190 +        io_sethandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2191 +        io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2192 +        io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2193 +        io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
 62.2194 +        io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l,  s3);
 62.2195  
 62.2196 -        io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2197 -        io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2198 -        io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2199 -        io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2200 -        io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2201 -        io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2202 -        io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2203 -        io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2204 -        io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2205 -        io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2206 -        io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2207 -        io_sethandler(0xa2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2208 -        io_sethandler(0xa6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2209 -        io_sethandler(0xaae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2210 -        io_sethandler(0xaee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2211 -        io_sethandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2212 -        io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2213 -        io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2214 -        io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  NULL);
 62.2215 -        io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l,  NULL);
 62.2216 -
 62.2217 -        pci_add(s3_pci_read, s3_pci_write, NULL);
 62.2218 +        pci_add(s3_pci_read, s3_pci_write, s3);
 62.2219   
 62.2220 -        svga_vram_limit = 4 << 20; /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/
 62.2221 -        return svga_init();
 62.2222 +        return s3;
 62.2223  }
 62.2224  
 62.2225 -GFXCARD vid_s3 =
 62.2226 +void *s3_bahamas64_init()
 62.2227  {
 62.2228 -        s3_init,
 62.2229 -        /*IO at 3Cx/3Dx*/
 62.2230 -        s3_out,
 62.2231 -        s3_in,
 62.2232 -        /*IO at 3Ax/3Bx*/
 62.2233 -        video_out_null,
 62.2234 -        video_in_null,
 62.2235 +        s3_t *s3 = s3_init();
 62.2236  
 62.2237 -        svga_poll,
 62.2238 -        svga_recalctimings,
 62.2239 +        s3->id = 0xc1; /*Vision864P*/
 62.2240 +        s3->id_ext = 0xc1; /*Trio64*/
 62.2241 +        
 62.2242 +        return s3;
 62.2243 +}
 62.2244  
 62.2245 -        svga_write,
 62.2246 -        video_write_null,
 62.2247 -        video_write_null,
 62.2248 +void *s3_9fx_init()
 62.2249 +{
 62.2250 +        s3_t *s3 = s3_init();
 62.2251  
 62.2252 -        svga_read,
 62.2253 -        video_read_null,
 62.2254 -        video_read_null
 62.2255 +        s3->id = 0xe1;
 62.2256 +        s3->id_ext = 0x11; /*Trio64*/
 62.2257 +        
 62.2258 +        return s3;
 62.2259 +}
 62.2260 +
 62.2261 +void s3_close(void *p)
 62.2262 +{
 62.2263 +        s3_t *s3 = (s3_t *)p;
 62.2264 +
 62.2265 +        svga_close(&s3->svga);
 62.2266 +        
 62.2267 +        free(s3);
 62.2268 +}
 62.2269 +
 62.2270 +void s3_speed_changed(void *p)
 62.2271 +{
 62.2272 +        s3_t *s3 = (s3_t *)p;
 62.2273 +        
 62.2274 +        svga_recalctimings(&s3->svga);
 62.2275 +}
 62.2276 +
 62.2277 +device_t s3_bahamas64_device =
 62.2278 +{
 62.2279 +        "Paradise Bahamas 64 (S3 Vision864)",
 62.2280 +        s3_bahamas64_init,
 62.2281 +        s3_close,
 62.2282 +        s3_speed_changed,
 62.2283 +        svga_add_status_info
 62.2284  };
 62.2285  
 62.2286 +device_t s3_9fx_device =
 62.2287 +{
 62.2288 +        "Number 9 9FX (S3 Trio64)",
 62.2289 +        s3_9fx_init,
 62.2290 +        s3_close,
 62.2291 +        s3_speed_changed,
 62.2292 +        svga_add_status_info
 62.2293 +};
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/src/vid_s3.h	Mon Jun 24 20:42:35 2013 +0100
    63.3 @@ -0,0 +1,2 @@
    63.4 +device_t s3_bahamas64_device;
    63.5 +device_t s3_9fx_device;
    64.1 --- a/src/vid_s3_virge.c	Tue Jun 04 20:52:17 2013 +0100
    64.2 +++ b/src/vid_s3_virge.c	Mon Jun 24 20:42:35 2013 +0100
    64.3 @@ -1,51 +1,66 @@
    64.4  /*S3 ViRGE emulation
    64.5  
    64.6    The SVGA core is largely the same as older S3 chips, but the blitter is totally different*/
    64.7 +#include <stdlib.h>
    64.8  #include "ibm.h"
    64.9 +#include "device.h"
   64.10  #include "io.h"
   64.11  #include "mem.h"
   64.12  #include "pci.h"
   64.13  #include "video.h"
   64.14 +#include "vid_s3_virge.h"
   64.15  #include "vid_svga.h"
   64.16  #include "vid_svga_render.h"
   64.17  //#include "vid_sdac_ramdac.h"
   64.18  
   64.19 -void s3_virge_updatemapping();
   64.20 +typedef struct virge_t
   64.21 +{
   64.22 +        svga_t svga;
   64.23 +        
   64.24 +        uint8_t bank;
   64.25 +        uint8_t ma_ext;
   64.26 +        int width;
   64.27 +        int bpp;
   64.28  
   64.29 -static uint8_t s3_bank;
   64.30 -static uint8_t s3_ma_ext;
   64.31 -static int s3_width = 1024;
   64.32 -static int s3_bpp = 0;
   64.33 +        uint8_t virge_id, virge_id_high, virge_id_low, virge_rev;
   64.34  
   64.35 -static uint8_t s3_virge_id, s3_virge_id_high, s3_virge_id_low, s3_virge_rev;
   64.36 +        uint32_t linear_base, linear_size;
   64.37  
   64.38 -uint8_t  s3_virge_mmio_read(uint32_t addr, void *priv);
   64.39 -uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv);
   64.40 -uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv);
   64.41 -void     s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv);
   64.42 -void     s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv);
   64.43 -void     s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv);
   64.44 +        uint8_t pci_regs[256];
   64.45 +} virge_t;
   64.46  
   64.47 -void s3_virge_out(uint16_t addr, uint8_t val, void *priv)
   64.48 +void s3_virge_updatemapping(virge_t *virge);
   64.49 +
   64.50 +uint8_t  s3_virge_mmio_read(uint32_t addr, void *p);
   64.51 +uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p);
   64.52 +uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p);
   64.53 +void     s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p);
   64.54 +void     s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p);
   64.55 +void     s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p);
   64.56 +
   64.57 +void s3_virge_out(uint16_t addr, uint8_t val, void *p)
   64.58  {
   64.59 +        virge_t *virge = (virge_t *)p;
   64.60 +        svga_t *svga = &virge->svga;
   64.61          uint8_t old;
   64.62  
   64.63 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   64.64 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
   64.65 +                addr ^= 0x60;
   64.66          
   64.67          pclog("S3 out %04X %02X %04X:%08X  %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins);
   64.68  
   64.69          switch (addr)
   64.70          {
   64.71                  case 0x3c5:
   64.72 -                if (seqaddr >= 0x10)
   64.73 +                if (svga->seqaddr >= 0x10)
   64.74                  {
   64.75 -                        seqregs[seqaddr&0x1F]=val;
   64.76 +                        svga->seqregs[svga->seqaddr & 0x1f]=val;
   64.77                          return;
   64.78                  }
   64.79 -                if (seqaddr == 4) /*Chain-4 - update banking*/
   64.80 +                if (svga->seqaddr == 4) /*Chain-4 - update banking*/
   64.81                  {
   64.82 -                        if (val & 8) svgawbank = svgarbank = s3_bank << 16;
   64.83 -                        else         svgawbank = svgarbank = s3_bank << 14;
   64.84 +                        if (val & 8) svga->write_bank = svga->read_bank = virge->bank << 16;
   64.85 +                        else         svga->write_bank = svga->read_bank = virge->bank << 14;
   64.86                  }
   64.87                  break;
   64.88                  
   64.89 @@ -54,107 +69,113 @@
   64.90                  //sdac_ramdac_out(addr,val);
   64.91                  //return;
   64.92  
   64.93 -                case 0x3D4:
   64.94 -                crtcreg=val&0x7f;
   64.95 +                case 0x3d4:
   64.96 +                svga->crtcreg = val & 0x7f;
   64.97                  return;
   64.98 -                case 0x3D5:
   64.99 +                case 0x3d5:
  64.100  //                        if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val);
  64.101 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
  64.102 -                if (crtcreg >= 0x20 && crtcreg != 0x38 && (crtc[0x38] & 0xcc) != 0x48) return;
  64.103 -                old=crtc[crtcreg];
  64.104 -                crtc[crtcreg]=val;
  64.105 -                switch (crtcreg)
  64.106 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) 
  64.107 +                        return;
  64.108 +                if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) 
  64.109 +                        return;
  64.110 +                old = svga->crtc[svga->crtcreg];
  64.111 +                svga->crtc[svga->crtcreg] = val;
  64.112 +                switch (svga->crtcreg)
  64.113                  {
  64.114                          case 0x31:
  64.115 -                        s3_ma_ext = (s3_ma_ext & 0x1c) | ((val & 0x30) >> 4);
  64.116 -                        vrammask = (val & 8) ? 0x3fffff : 0x3ffff;
  64.117 +                        virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4);
  64.118 +                        svga->vrammask = (val & 8) ? 0x3fffff : 0x3ffff;
  64.119                          break;
  64.120                          
  64.121                          case 0x50:
  64.122 -                        switch (crtc[0x50] & 0xc1)
  64.123 +                        switch (svga->crtc[0x50] & 0xc1)
  64.124                          {
  64.125 -                                case 0x00: s3_width = (crtc[0x31] & 2) ? 2048 : 1024; break;
  64.126 -                                case 0x01: s3_width = 1152; break;
  64.127 -                                case 0x40: s3_width = 640;  break;
  64.128 -                                case 0x80: s3_width = 800;  break;
  64.129 -                                case 0x81: s3_width = 1600; break;
  64.130 -                                case 0xc0: s3_width = 1280; break;
  64.131 +                                case 0x00: virge->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; break;
  64.132 +                                case 0x01: virge->width = 1152; break;
  64.133 +                                case 0x40: virge->width = 640;  break;
  64.134 +                                case 0x80: virge->width = 800;  break;
  64.135 +                                case 0x81: virge->width = 1600; break;
  64.136 +                                case 0xc0: virge->width = 1280; break;
  64.137                          }
  64.138 -                        s3_bpp = (crtc[0x50] >> 4) & 3;
  64.139 +                        virge->bpp = (svga->crtc[0x50] >> 4) & 3;
  64.140                          break;
  64.141                          case 0x69:
  64.142 -                        s3_ma_ext = val & 0x1f;
  64.143 +                        virge->ma_ext = val & 0x1f;
  64.144                          break;
  64.145                          
  64.146                          case 0x35:
  64.147 -                        s3_bank = (s3_bank & 0x70) | (val & 0xf);
  64.148 +                        virge->bank = (virge->bank & 0x70) | (val & 0xf);
  64.149  //                        pclog("CRTC write R35 %02X\n", val);
  64.150 -                        if (chain4) svgawbank = svgarbank = s3_bank << 16;
  64.151 -                        else        svgawbank = svgarbank = s3_bank << 14;
  64.152 +                        if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16;
  64.153 +                        else              svga->write_bank = svga->read_bank = virge->bank << 14;
  64.154                          break;
  64.155                          case 0x51:
  64.156 -                        s3_bank = (s3_bank & 0x4f) | ((val & 0xc) << 2);
  64.157 -                        if (chain4) svgawbank = svgarbank = s3_bank << 16;
  64.158 -                        else        svgawbank = svgarbank = s3_bank << 14;
  64.159 -                        s3_ma_ext = (s3_ma_ext & ~0xc) | ((val & 3) << 2);
  64.160 +                        virge->bank = (virge->bank & 0x4f) | ((val & 0xc) << 2);
  64.161 +                        if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16;
  64.162 +                        else              svga->write_bank = svga->read_bank = virge->bank << 14;
  64.163 +                        virge->ma_ext = (virge->ma_ext & ~0xc) | ((val & 3) << 2);
  64.164                          break;
  64.165                          case 0x6a:
  64.166 -                        s3_bank = val;
  64.167 +                        virge->bank = val;
  64.168  //                        pclog("CRTC write R6a %02X\n", val);
  64.169 -                        if (chain4) svgawbank = svgarbank = s3_bank << 16;
  64.170 -                        else        svgawbank = svgarbank = s3_bank << 14;
  64.171 +                        if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16;
  64.172 +                        else              svga->write_bank = svga->read_bank = virge->bank << 14;
  64.173                          break;
  64.174                          
  64.175                          case 0x3a:
  64.176 -                        if (val & 0x10) gdcreg[5] |= 0x40; /*Horrible cheat*/
  64.177 +                        if (val & 0x10) svga->gdcreg[5] |= 0x40; /*Horrible cheat*/
  64.178                          break;
  64.179                          
  64.180                          case 0x45:
  64.181 -                        svga_hwcursor.ena = val & 1;
  64.182 +                        svga->hwcursor.ena = val & 1;
  64.183                          break;
  64.184                          case 0x48:
  64.185 -                        svga_hwcursor.x = ((crtc[0x46] << 8) | crtc[0x47]) & 0x7ff;
  64.186 -                        if (bpp == 32) svga_hwcursor.x >>= 1;
  64.187 -                        svga_hwcursor.y = ((crtc[0x48] << 8) | crtc[0x49]) & 0x7ff;
  64.188 -                        svga_hwcursor.xoff = crtc[0x4e] & 63;
  64.189 -                        svga_hwcursor.yoff = crtc[0x4f] & 63;
  64.190 -                        svga_hwcursor.addr = ((((crtc[0x4c] << 8) | crtc[0x4d]) & 0xfff) * 1024) + (svga_hwcursor.yoff * 16);
  64.191 +                        svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff;
  64.192 +                        if (svga->bpp == 32) svga->hwcursor.x >>= 1;
  64.193 +                        svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff;
  64.194 +                        svga->hwcursor.xoff = svga->crtc[0x4e] & 63;
  64.195 +                        svga->hwcursor.yoff = svga->crtc[0x4f] & 63;
  64.196 +                        svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16);
  64.197                          break;
  64.198  
  64.199                          case 0x53:
  64.200                          case 0x58: case 0x59: case 0x5a:
  64.201 -                        s3_virge_updatemapping();
  64.202 +                        s3_virge_updatemapping(virge);
  64.203                          break;
  64.204                          
  64.205                          case 0x67:
  64.206                          switch (val >> 4)
  64.207                          {
  64.208 -                                case 3:  bpp = 15; break;
  64.209 -                                case 5:  bpp = 16; break;
  64.210 -                                case 7:  bpp = 24; break;
  64.211 -                                case 13: bpp = 32; break;
  64.212 -                                default: bpp = 8;  break;
  64.213 +                                case 3:  svga->bpp = 15; break;
  64.214 +                                case 5:  svga->bpp = 16; break;
  64.215 +                                case 7:  svga->bpp = 24; break;
  64.216 +                                case 13: svga->bpp = 32; break;
  64.217 +                                default: svga->bpp = 8;  break;
  64.218                          }
  64.219                          break;
  64.220                          //case 0x55: case 0x43:
  64.221  //                                pclog("Write CRTC R%02X %02X\n", crtcreg, val);
  64.222                  }
  64.223 -                if (old!=val)
  64.224 +                if (old != val)
  64.225                  {
  64.226 -                        if (crtcreg<0xE || crtcreg>0x10)
  64.227 +                        if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
  64.228                          {
  64.229 -                                fullchange=changeframecount;
  64.230 -                                svga_recalctimings();
  64.231 +                                fullchange = changeframecount;
  64.232 +                                svga_recalctimings(svga);
  64.233                          }
  64.234                  }
  64.235                  break;
  64.236          }
  64.237 -        svga_out(addr, val, NULL);
  64.238 +        svga_out(addr, val, svga);
  64.239  }
  64.240  
  64.241 -uint8_t s3_virge_in(uint16_t addr, void *priv)
  64.242 +uint8_t s3_virge_in(uint16_t addr, void *p)
  64.243  {
  64.244 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  64.245 +        virge_t *virge = (virge_t *)p;
  64.246 +        svga_t *svga = &virge->svga;
  64.247 +        
  64.248 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
  64.249 +                addr ^= 0x60;
  64.250  
  64.251          if (addr != 0x3da) pclog("S3 in %04X %04X:%08X\n", addr, CS, pc);
  64.252          switch (addr)
  64.253 @@ -164,221 +185,221 @@
  64.254                  //return sdac_ramdac_in(addr);
  64.255  
  64.256                  case 0x3c5:
  64.257 -                if (seqaddr >= 0x10)
  64.258 -                   return seqregs[seqaddr&0x1F];
  64.259 +                if (svga->seqaddr >= 0x10)
  64.260 +                   return svga->seqregs[svga->seqaddr & 0x1f];
  64.261                  break;
  64.262  
  64.263                  case 0x3D4:
  64.264 -                return crtcreg;
  64.265 +                return svga->crtcreg;
  64.266                  case 0x3D5:
  64.267  //                pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc);
  64.268 -                switch (crtcreg)
  64.269 +                switch (svga->crtcreg)
  64.270                  {
  64.271 -                        case 0x2d: return s3_virge_id_high; /*Extended chip ID*/
  64.272 -                        case 0x2e: return s3_virge_id_low;  /*New chip ID*/
  64.273 -                        case 0x2f: return s3_virge_rev;
  64.274 -                        case 0x30: return s3_virge_id;      /*Chip ID*/
  64.275 -                        case 0x31: return (crtc[0x31] & 0xcf) | ((s3_ma_ext & 3) << 4);
  64.276 -                        case 0x35: return (crtc[0x35] & 0xf0) | (s3_bank & 0xf);
  64.277 -                        case 0x51: return (crtc[0x51] & 0xf0) | ((s3_bank >> 2) & 0xc) | ((s3_ma_ext >> 2) & 3);
  64.278 -                        case 0x69: return s3_ma_ext;
  64.279 -                        case 0x6a: return s3_bank;
  64.280 +                        case 0x2d: return virge->virge_id_high; /*Extended chip ID*/
  64.281 +                        case 0x2e: return virge->virge_id_low;  /*New chip ID*/
  64.282 +                        case 0x2f: return virge->virge_rev;
  64.283 +                        case 0x30: return virge->virge_id;      /*Chip ID*/
  64.284 +                        case 0x31: return (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4);
  64.285 +                        case 0x35: return (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf);
  64.286 +                        case 0x51: return (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3);
  64.287 +                        case 0x69: return virge->ma_ext;
  64.288 +                        case 0x6a: return virge->bank;
  64.289                  }
  64.290 -                return crtc[crtcreg];
  64.291 +                return svga->crtc[svga->crtcreg];
  64.292          }
  64.293 -        return svga_in(addr, NULL);
  64.294 +        return svga_in(addr, svga);
  64.295  }
  64.296  
  64.297 -void s3_virge_recalctimings()
  64.298 +void s3_virge_recalctimings(svga_t *svga)
  64.299  {
  64.300 +        virge_t *virge = (virge_t *)svga->p;
  64.301  //        pclog("recalctimings\n");
  64.302 -        svga_ma |= (s3_ma_ext << 16);
  64.303 +        svga->ma_latch |= (virge->ma_ext << 16);
  64.304  //        pclog("SVGA_MA %08X\n", svga_ma);
  64.305  //        if (gdcreg[5] & 0x40) svga_lowres = !(crtc[0x3a] & 0x10);
  64.306 -        if ((gdcreg[5] & 0x40) && (crtc[0x3a] & 0x10))
  64.307 +        if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10))
  64.308          {
  64.309 -                switch (bpp)
  64.310 +                switch (svga->bpp)
  64.311                  {
  64.312                          case 8: 
  64.313 -                        svga_render = svga_render_8bpp_highres; 
  64.314 +                        svga->render = svga_render_8bpp_highres; 
  64.315                          break;
  64.316                          case 15: 
  64.317 -                        svga_render = svga_render_15bpp_highres; 
  64.318 +                        svga->render = svga_render_15bpp_highres; 
  64.319                          break;
  64.320                          case 16: 
  64.321 -                        svga_render = svga_render_16bpp_highres; 
  64.322 +                        svga->render = svga_render_16bpp_highres; 
  64.323                          break;
  64.324                          case 24: 
  64.325 -                        svga_render = svga_render_24bpp_highres; 
  64.326 +                        svga->render = svga_render_24bpp_highres; 
  64.327                          break;
  64.328                          case 32: 
  64.329 -                        svga_render = svga_render_32bpp_highres; 
  64.330 +                        svga->render = svga_render_32bpp_highres; 
  64.331                          break;
  64.332                  }
  64.333          }
  64.334          
  64.335 -        if (crtc[0x5d] & 0x01) svga_htotal     += 0x100;
  64.336 -        if (crtc[0x5d] & 0x02) svga_hdisp      += 0x100;
  64.337 -        if (crtc[0x5e] & 0x01) svga_vtotal     += 0x400;
  64.338 -        if (crtc[0x5e] & 0x02) svga_dispend    += 0x400;
  64.339 -        if (crtc[0x5e] & 0x10) svga_vsyncstart += 0x400;
  64.340 -        if (crtc[0x5e] & 0x40) svga_split      += 0x400;
  64.341 -        if (crtc[0x51] & 0x30)      svga_rowoffset  += (crtc[0x51] & 0x30) << 4;
  64.342 -        else if (crtc[0x43] & 0x04) svga_rowoffset  += 0x100;
  64.343 -        if (!svga_rowoffset) svga_rowoffset = 256;
  64.344 -        svga_interlace = crtc[0x42] & 0x20;
  64.345 -        if (bpp == 32)
  64.346 +        if (svga->crtc[0x5d] & 0x01) svga->htotal     += 0x100;
  64.347 +        if (svga->crtc[0x5d] & 0x02) svga->hdisp      += 0x100;
  64.348 +        if (svga->crtc[0x5e] & 0x01) svga->vtotal     += 0x400;
  64.349 +        if (svga->crtc[0x5e] & 0x02) svga->dispend    += 0x400;
  64.350 +        if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400;
  64.351 +        if (svga->crtc[0x5e] & 0x40) svga->split      += 0x400;
  64.352 +        if (svga->crtc[0x51] & 0x30)      svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4;
  64.353 +        else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
  64.354 +        if (!svga->rowoffset) svga->rowoffset = 256;
  64.355 +        svga->interlace = svga->crtc[0x42] & 0x20;
  64.356 +        if (svga->bpp == 32)
  64.357          {
  64.358 -                svga_htotal <<= 2;
  64.359 -                svga_hdisp <<= 2;
  64.360 +                svga->htotal <<= 2;
  64.361 +                svga->hdisp <<= 2;
  64.362          }
  64.363          //svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3);
  64.364  //        pclog("SVGA_CLOCK = %f  %02X  %f\n", svga_clock, svga_miscout, cpuclock);
  64.365          //if (bpp > 8) svga_clock /= 2;
  64.366  }
  64.367  
  64.368 -static uint32_t s3_linear_base = 0, s3_linear_size = 0;
  64.369 -void s3_virge_updatemapping()
  64.370 +void s3_virge_updatemapping(virge_t *virge)
  64.371  {
  64.372 -        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);
  64.373 +        svga_t *svga = &virge->svga;
  64.374 +        
  64.375 +        mem_removehandler(virge->linear_base, virge->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga);
  64.376          
  64.377  //        video_write_a000_w = video_write_a000_l = NULL;
  64.378  
  64.379 -        mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  64.380 -        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);
  64.381 -        pclog("Update mapping - bank %02X ", gdcreg[6] & 0xc);        
  64.382 -        switch (gdcreg[6] & 0xc) /*Banked framebuffer*/
  64.383 +        mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  64.384 +        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, virge);
  64.385 +        pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc);        
  64.386 +        switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/
  64.387          {
  64.388                  case 0x0: /*128k at A0000*/
  64.389 -                mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  64.390 +                mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  64.391                  break;
  64.392                  case 0x4: /*64k at A0000*/
  64.393 -                mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  64.394 +                mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  64.395                  break;
  64.396                  case 0x8: /*32k at B0000*/
  64.397 -                mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  64.398 +                mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  64.399                  break;
  64.400                  case 0xC: /*32k at B8000*/
  64.401 -                mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  64.402 +                mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  64.403                  break;
  64.404          }
  64.405          
  64.406 -        pclog("Linear framebuffer %02X ", crtc[0x58] & 0x10);
  64.407 -        if (crtc[0x58] & 0x10) /*Linear framebuffer*/
  64.408 +        pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10);
  64.409 +        if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/
  64.410          {
  64.411 -                s3_linear_base = (crtc[0x5a] << 16) | (crtc[0x59] << 24);
  64.412 -                switch (crtc[0x58] & 3)
  64.413 +                virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
  64.414 +                switch (svga->crtc[0x58] & 3)
  64.415                  {
  64.416                          case 0: /*64k*/
  64.417 -                        s3_linear_size = 0x10000;
  64.418 +                        virge->linear_size = 0x10000;
  64.419                          break;
  64.420                          case 1: /*1mb*/
  64.421 -                        s3_linear_size = 0x100000;
  64.422 +                        virge->linear_size = 0x100000;
  64.423                          break;
  64.424                          case 2: /*2mb*/
  64.425 -                        s3_linear_size = 0x200000;
  64.426 +                        virge->linear_size = 0x200000;
  64.427                          break;
  64.428                          case 3: /*8mb*/
  64.429 -                        s3_linear_size = 0x400000;
  64.430 +                        virge->linear_size = 0x400000;
  64.431                          break;
  64.432                  }
  64.433 -                s3_linear_base &= ~(s3_linear_size - 1);
  64.434 +                virge->linear_base &= ~(virge->linear_size - 1);
  64.435  //                pclog("%08X %08X  %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]);
  64.436 -                pclog("Linear framebuffer at %08X size %08X\n", s3_linear_base, s3_linear_size);
  64.437 -                if (s3_linear_base == 0xa0000)
  64.438 -                   mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  64.439 +                pclog("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size);
  64.440 +                if (virge->linear_base == 0xa0000)
  64.441 +                   mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
  64.442                  else
  64.443 -                   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);
  64.444 +                   mem_sethandler(virge->linear_base, virge->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, svga);
  64.445          }
  64.446          
  64.447 -        pclog("Memory mapped IO %02X\n", crtc[0x53] & 0x18);
  64.448 -        output = 0;
  64.449 -        if ((crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/
  64.450 +        pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18);
  64.451 +        if ((svga->crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/
  64.452          {
  64.453 -                output = 3;
  64.454 -                if (crtc[0x53] & 0x20)
  64.455 -                   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);
  64.456 +                if (svga->crtc[0x53] & 0x20)
  64.457 +                   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, virge);
  64.458                  else
  64.459 -                   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);
  64.460 +                   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, virge);
  64.461          }
  64.462  
  64.463  }
  64.464  
  64.465  
  64.466 -uint8_t s3_virge_mmio_read(uint32_t addr, void *priv)
  64.467 +uint8_t s3_virge_mmio_read(uint32_t addr, void *p)
  64.468  {
  64.469          pclog("MMIO readb %08X\n", addr);
  64.470          return 0xff;
  64.471  }
  64.472 -uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv)
  64.473 +uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p)
  64.474  {
  64.475          pclog("MMIO readw %08X\n", addr);
  64.476          return 0xffff;
  64.477  }
  64.478 -uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv)
  64.479 +uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p)
  64.480  {
  64.481          pclog("MMIO readl %08X\n", addr);
  64.482          return 0xffffffff;
  64.483  }
  64.484 -void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv)
  64.485 +void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p)
  64.486  {
  64.487          pclog("MMIO writeb %08X %02X\n", addr, val);
  64.488  }
  64.489 -void     s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv)
  64.490 +void     s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
  64.491  {
  64.492          pclog("MMIO writew %08X %04X\n", addr, val);
  64.493  }
  64.494 -void     s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv)
  64.495 +void     s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
  64.496  {
  64.497          pclog("MMIO writel %08X %08X\n", addr, val);
  64.498  }
  64.499  
  64.500  
  64.501  
  64.502 -void s3_virge_hwcursor_draw(int displine)
  64.503 +void s3_virge_hwcursor_draw(svga_t *svga, int displine)
  64.504  {
  64.505          int x;
  64.506          uint16_t dat[2];
  64.507          int xx;
  64.508 -        int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff;
  64.509 +        int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
  64.510          
  64.511 -        pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y);
  64.512 +        pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y);
  64.513          for (x = 0; x < 64; x += 16)
  64.514          {
  64.515 -                dat[0] = (vram[svga_hwcursor_latch.addr]     << 8) | vram[svga_hwcursor_latch.addr + 1];
  64.516 -                dat[1] = (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3];
  64.517 +                dat[0] = (svga->vram[svga->hwcursor_latch.addr]     << 8) | svga->vram[svga->hwcursor_latch.addr + 1];
  64.518 +                dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
  64.519                  for (xx = 0; xx < 16; xx++)
  64.520                  {
  64.521 -                        if (offset >= svga_hwcursor_latch.x)
  64.522 +                        if (offset >= svga->hwcursor_latch.x)
  64.523                          {
  64.524                                  if (!(dat[0] & 0x8000))
  64.525                                     ((uint32_t *)buffer32->line[displine])[offset + 32]  = (dat[1] & 0x8000) ? 0xffffff : 0;
  64.526                                  else if (dat[1] & 0x8000)
  64.527                                     ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
  64.528 -//                                pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]);
  64.529 +//                                pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga->hwcursor_on, dat[0], dat[1]);
  64.530                          }
  64.531                             
  64.532                          offset++;
  64.533                          dat[0] <<= 1;
  64.534                          dat[1] <<= 1;
  64.535                  }
  64.536 -                svga_hwcursor_latch.addr += 4;
  64.537 +                svga->hwcursor_latch.addr += 4;
  64.538          }
  64.539  }
  64.540  
  64.541  
  64.542 -static uint8_t s3_virge_pci_regs[256];
  64.543 -
  64.544 -uint8_t s3_virge_pci_read(int func, int addr, void *priv)
  64.545 +uint8_t s3_virge_pci_read(int func, int addr, void *p)
  64.546  {
  64.547 +        virge_t *virge = (virge_t *)p;
  64.548 +        svga_t *svga = &virge->svga;
  64.549  //        pclog("S3 PCI read %08X\n", addr);
  64.550          switch (addr)
  64.551          {
  64.552                  case 0x00: return 0x33; /*'S3'*/
  64.553                  case 0x01: return 0x53;
  64.554                  
  64.555 -                case 0x02: return s3_virge_id_low;
  64.556 -                case 0x03: return s3_virge_id_high;
  64.557 +                case 0x02: return virge->virge_id_low;
  64.558 +                case 0x03: return virge->virge_id_high;
  64.559                  
  64.560                  case 0x08: return 0; /*Revision ID*/
  64.561                  case 0x09: return 0; /*Programming interface*/
  64.562 @@ -389,7 +410,7 @@
  64.563                  case 0x10: return 0x00; /*Linear frame buffer address*/
  64.564                  case 0x11: return 0x00;
  64.565                  case 0x12: return 0x00;
  64.566 -                case 0x13: return crtc[0x59] & 0xfc;
  64.567 +                case 0x13: return svga->crtc[0x59] & 0xfc;
  64.568  
  64.569                  case 0x30: return 0x01; /*BIOS ROM address*/
  64.570                  case 0x31: return 0x00;
  64.571 @@ -397,11 +418,14 @@
  64.572                  case 0x33: return 0x00;
  64.573                  
  64.574          }
  64.575 -        return s3_virge_pci_regs[addr];
  64.576 +        return virge->pci_regs[addr];
  64.577  }
  64.578  
  64.579 -void s3_virge_pci_write(int func, int addr, uint8_t val, void *priv)
  64.580 +void s3_virge_pci_write(int func, int addr, uint8_t val, void *p)
  64.581  {
  64.582 +        virge_t *virge = (virge_t *)p;
  64.583 +        svga_t *svga = &virge->svga;
  64.584 +
  64.585          switch (addr)
  64.586          {
  64.587                  case 0x00: case 0x01: case 0x02: case 0x03:
  64.588 @@ -409,59 +433,68 @@
  64.589                  case 0x3d: case 0x3e: case 0x3f:
  64.590                  break;
  64.591                  
  64.592 -                case 0x13: crtc[0x59] = val & 0xfc; s3_virge_updatemapping(); break;                
  64.593 +                case 0x13: 
  64.594 +                svga->crtc[0x59] = val & 0xfc; 
  64.595 +                s3_virge_updatemapping(virge); 
  64.596 +                break;
  64.597          }
  64.598 -        s3_virge_pci_regs[addr] = val;
  64.599 +        virge->pci_regs[addr] = val;
  64.600  }
  64.601  
  64.602 -int s3_virge_init()
  64.603 +void *s3_virge_init()
  64.604  {
  64.605 -        s3_virge_pci_regs[4] = 3;
  64.606 -        s3_virge_pci_regs[5] = 0;        
  64.607 -        s3_virge_pci_regs[6] = 0;
  64.608 -        s3_virge_pci_regs[7] = 2;
  64.609 -        s3_virge_pci_regs[0x3d] = 1; 
  64.610 -        s3_virge_pci_regs[0x3e] = 4;
  64.611 -        s3_virge_pci_regs[0x3f] = 0xff;
  64.612 +        virge_t *virge = malloc(sizeof(virge_t));
  64.613 +        memset(virge, 0, sizeof(virge_t));
  64.614 +
  64.615 +        svga_init(&virge->svga, virge, 1 << 22, /*4mb*/
  64.616 +                   s3_virge_recalctimings,
  64.617 +                   s3_virge_in, s3_virge_out,
  64.618 +                   s3_virge_hwcursor_draw);
  64.619 +
  64.620 +        io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
  64.621 +
  64.622 +        virge->pci_regs[4] = 3;
  64.623 +        virge->pci_regs[5] = 0;        
  64.624 +        virge->pci_regs[6] = 0;
  64.625 +        virge->pci_regs[7] = 2;
  64.626 +        virge->pci_regs[0x3d] = 1; 
  64.627 +        virge->pci_regs[0x3e] = 4;
  64.628 +        virge->pci_regs[0x3f] = 0xff;
  64.629          
  64.630 -        s3_virge_id_high = 0x56;
  64.631 -        s3_virge_id_low = 0x31;
  64.632 -        s3_virge_rev = 0;
  64.633 -        s3_virge_id = 0xe1;
  64.634 +        virge->virge_id_high = 0x56;
  64.635 +        virge->virge_id_low = 0x31;
  64.636 +        virge->virge_rev = 0;
  64.637 +        virge->virge_id = 0xe1;
  64.638  
  64.639 -        svga_recalctimings_ex = s3_virge_recalctimings;
  64.640 -        svga_hwcursor_draw    = s3_virge_hwcursor_draw;
  64.641 -
  64.642 -        crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
  64.643 -        crtc[0x37] = 1 | (7 << 5);
  64.644 +        virge->svga.crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
  64.645 +        virge->svga.crtc[0x37] = 1 | (7 << 5);
  64.646          
  64.647 -        vrammask = 0x3fffff;
  64.648 -
  64.649 -        pci_add(s3_virge_pci_read, s3_virge_pci_write, NULL);
  64.650 +        pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
  64.651   
  64.652 -        svga_vram_limit = 4 << 20; /*4mb*/
  64.653 -        return svga_init();
  64.654 +        return virge;
  64.655  }
  64.656  
  64.657 -GFXCARD vid_s3_virge =
  64.658 +void s3_virge_close(void *p)
  64.659  {
  64.660 +        virge_t *virge = (virge_t *)p;
  64.661 +
  64.662 +        svga_close(&virge->svga);
  64.663 +        
  64.664 +        free(virge);
  64.665 +}
  64.666 +
  64.667 +void s3_virge_speed_changed(void *p)
  64.668 +{
  64.669 +        virge_t *virge = (virge_t *)p;
  64.670 +        
  64.671 +        svga_recalctimings(&virge->svga);
  64.672 +}
  64.673 +
  64.674 +device_t s3_virge_device =
  64.675 +{
  64.676 +        "Diamond Stealth 3D 2000 (S3 VIRGE)",
  64.677          s3_virge_init,
  64.678 -        /*IO at 3Cx/3Dx*/
  64.679 -        s3_virge_out,
  64.680 -        s3_virge_in,
  64.681 -        /*IO at 3Ax/3Bx*/
  64.682 -        video_out_null,
  64.683 -        video_in_null,
  64.684 -
  64.685 -        svga_poll,
  64.686 -        svga_recalctimings,
  64.687 -
  64.688 -        svga_write,
  64.689 -        video_write_null,
  64.690 -        video_write_null,
  64.691 -
  64.692 -        svga_read,
  64.693 -        video_read_null,
  64.694 -        video_read_null
  64.695 +        s3_virge_close,
  64.696 +        s3_virge_speed_changed,
  64.697 +        svga_add_status_info
  64.698  };
  64.699 -
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/src/vid_s3_virge.h	Mon Jun 24 20:42:35 2013 +0100
    65.3 @@ -0,0 +1,1 @@
    65.4 +extern device_t s3_virge_device;
    66.1 --- a/src/vid_sdac_ramdac.c	Tue Jun 04 20:52:17 2013 +0100
    66.2 +++ b/src/vid_sdac_ramdac.c	Mon Jun 24 20:42:35 2013 +0100
    66.3 @@ -5,17 +5,7 @@
    66.4  #include "vid_svga.h"
    66.5  #include "vid_sdac_ramdac.h"
    66.6  
    66.7 -struct
    66.8 -{
    66.9 -        int magic_count;
   66.10 -        uint8_t command;
   66.11 -        int windex, rindex;
   66.12 -        uint16_t regs[256];
   66.13 -        int reg_ff;
   66.14 -        int rs2;
   66.15 -} sdac_ramdac;
   66.16 -
   66.17 -void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv)
   66.18 +void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga)
   66.19  {
   66.20  //        /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X  %i\n",addr,val,sdac_ramdac.magic_count,CS,pc, sdac_ramdac.rs2);
   66.21          switch (addr)
   66.22 @@ -23,125 +13,125 @@
   66.23                  case 0x3C6:
   66.24                  if (val == 0xff)
   66.25                  {
   66.26 -                        sdac_ramdac.rs2 = 0;
   66.27 -                        sdac_ramdac.magic_count = 0;
   66.28 +                        ramdac->rs2 = 0;
   66.29 +                        ramdac->magic_count = 0;
   66.30                          break;
   66.31                  }
   66.32 -                if (sdac_ramdac.magic_count < 4) break;
   66.33 -                if (sdac_ramdac.magic_count == 4)
   66.34 +                if (ramdac->magic_count < 4) break;
   66.35 +                if (ramdac->magic_count == 4)
   66.36                  {
   66.37 -                        sdac_ramdac.command = val;
   66.38 +                        ramdac->command = val;
   66.39  //                        pclog("RAMDAC command reg now %02X\n", val);
   66.40                          switch (val >> 4)
   66.41                          {
   66.42 -                                case 2: case 3: case 0xa: bpp = 15; break;
   66.43 -                                case 4: case 0xe: bpp = 24; break;
   66.44 -                                case 5: case 6: case 0xc: bpp = 16; break;
   66.45 -                                case 7: bpp = 32; break;
   66.46 +                                case 0x2: case 0x3: case 0xa: svga->bpp = 15; break;
   66.47 +                                case 0x4: case 0xe:           svga->bpp = 24; break;
   66.48 +                                case 0x5: case 0x6: case 0xc: svga->bpp = 16; break;
   66.49 +                                case 0x7:                     svga->bpp = 32; break;
   66.50  
   66.51 -                                case 0: case 1: default: bpp = 8; break;
   66.52 +                                case 0: case 1: default: svga->bpp = 8; break;
   66.53                          }
   66.54                  }
   66.55 -                //sdac_ramdac.magic_count = 0;
   66.56 +                //ramdac->magic_count = 0;
   66.57                  break;
   66.58                  
   66.59                  case 0x3C7:
   66.60 -                sdac_ramdac.magic_count = 0;
   66.61 -                if (sdac_ramdac.rs2)
   66.62 -                   sdac_ramdac.rindex = val;
   66.63 +                ramdac->magic_count = 0;
   66.64 +                if (ramdac->rs2)
   66.65 +                   ramdac->rindex = val;
   66.66                  break;
   66.67                  case 0x3C8:
   66.68 -                sdac_ramdac.magic_count = 0;
   66.69 -                if (sdac_ramdac.rs2)
   66.70 -                   sdac_ramdac.windex = val;
   66.71 +                ramdac->magic_count = 0;
   66.72 +                if (ramdac->rs2)
   66.73 +                   ramdac->windex = val;
   66.74                  break;
   66.75                  case 0x3C9:
   66.76 -                sdac_ramdac.magic_count = 0;
   66.77 -                if (sdac_ramdac.rs2)
   66.78 +                ramdac->magic_count = 0;
   66.79 +                if (ramdac->rs2)
   66.80                  {
   66.81 -                        if (!sdac_ramdac.reg_ff) sdac_ramdac.regs[sdac_ramdac.windex] = (sdac_ramdac.regs[sdac_ramdac.windex] & 0xff00) | val;
   66.82 -                        else                    sdac_ramdac.regs[sdac_ramdac.windex] = (sdac_ramdac.regs[sdac_ramdac.windex] & 0x00ff) | (val << 8);
   66.83 -                        sdac_ramdac.reg_ff = !sdac_ramdac.reg_ff;
   66.84 -//                        pclog("RAMDAC reg %02X now %04X\n", sdac_ramdac.windex, sdac_ramdac.regs[sdac_ramdac.windex]);
   66.85 -                        if (!sdac_ramdac.reg_ff) sdac_ramdac.windex++;
   66.86 +                        if (!ramdac->reg_ff) ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0xff00) | val;
   66.87 +                        else                 ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0x00ff) | (val << 8);
   66.88 +                        ramdac->reg_ff = !ramdac->reg_ff;
   66.89 +//                        pclog("RAMDAC reg %02X now %04X\n", ramdac->windex, ramdac->regs[ramdac->windex]);
   66.90 +                        if (!ramdac->reg_ff) ramdac->windex++;
   66.91                  }
   66.92                  break;
   66.93          }
   66.94 -        svga_out(addr, val, NULL);
   66.95 +        svga_out(addr, val, svga);
   66.96  }
   66.97  
   66.98 -uint8_t sdac_ramdac_in(uint16_t addr, void *priv)
   66.99 +uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga)
  66.100  {
  66.101          uint8_t temp;
  66.102 -//        /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, sdac_ramdac.rs2);
  66.103 +//        /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, ramdac->rs2);
  66.104          switch (addr)
  66.105          {
  66.106                  case 0x3C6:
  66.107 -                sdac_ramdac.reg_ff = 0;
  66.108 -                if (sdac_ramdac.magic_count < 5)
  66.109 -                   sdac_ramdac.magic_count++;
  66.110 -                if (sdac_ramdac.magic_count == 4)
  66.111 +                ramdac->reg_ff = 0;
  66.112 +                if (ramdac->magic_count < 5)
  66.113 +                   ramdac->magic_count++;
  66.114 +                if (ramdac->magic_count == 4)
  66.115                  {
  66.116                          temp = 0x70; /*SDAC ID*/
  66.117 -                        sdac_ramdac.rs2 = 1;
  66.118 +                        ramdac->rs2 = 1;
  66.119                  }
  66.120 -                if (sdac_ramdac.magic_count == 5)
  66.121 +                if (ramdac->magic_count == 5)
  66.122                  {
  66.123 -                        temp = sdac_ramdac.command;
  66.124 -                        sdac_ramdac.magic_count = 0;
  66.125 +                        temp = ramdac->command;
  66.126 +                        ramdac->magic_count = 0;
  66.127                  }
  66.128                  return temp;
  66.129                  case 0x3C7:
  66.130 -//                if (sdac_ramdac.magic_count < 4)
  66.131 +//                if (ramdac->magic_count < 4)
  66.132  //                {
  66.133 -                        sdac_ramdac.magic_count=0;
  66.134 +                        ramdac->magic_count=0;
  66.135  //                        break;
  66.136  //                }
  66.137 -                if (sdac_ramdac.rs2) return sdac_ramdac.rindex;
  66.138 +                if (ramdac->rs2) return ramdac->rindex;
  66.139                  break;
  66.140                  case 0x3C8:
  66.141 -//                if (sdac_ramdac.magic_count < 4)
  66.142 +//                if (ramdac->magic_count < 4)
  66.143  //                {
  66.144 -                        sdac_ramdac.magic_count=0;
  66.145 +                        ramdac->magic_count=0;
  66.146  //                        break;
  66.147  //                }
  66.148 -                if (sdac_ramdac.rs2) return sdac_ramdac.windex;
  66.149 +                if (ramdac->rs2) return ramdac->windex;
  66.150                  break;
  66.151                  case 0x3C9:
  66.152 -//                if (sdac_ramdac.magic_count < 4)
  66.153 +//                if (ramdac->magic_count < 4)
  66.154  //                {
  66.155 -                        sdac_ramdac.magic_count=0;
  66.156 +                        ramdac->magic_count=0;
  66.157  //                        break;
  66.158  //                }
  66.159 -                if (sdac_ramdac.rs2)
  66.160 +                if (ramdac->rs2)
  66.161                  {
  66.162 -                        if (!sdac_ramdac.reg_ff) temp = sdac_ramdac.regs[sdac_ramdac.rindex] & 0xff;
  66.163 -                        else                     temp = sdac_ramdac.regs[sdac_ramdac.rindex] >> 8;
  66.164 -                        sdac_ramdac.reg_ff = !sdac_ramdac.reg_ff;
  66.165 -                        if (!sdac_ramdac.reg_ff)
  66.166 +                        if (!ramdac->reg_ff) temp = ramdac->regs[ramdac->rindex] & 0xff;
  66.167 +                        else                 temp = ramdac->regs[ramdac->rindex] >> 8;
  66.168 +                        ramdac->reg_ff = !ramdac->reg_ff;
  66.169 +                        if (!ramdac->reg_ff)
  66.170                          {
  66.171 -                                sdac_ramdac.rindex++;
  66.172 -                                sdac_ramdac.magic_count = 0;
  66.173 +                                ramdac->rindex++;
  66.174 +                                ramdac->magic_count = 0;
  66.175                          }
  66.176                          return temp;
  66.177                  }
  66.178                  break;
  66.179          }
  66.180 -        return svga_in(addr, NULL);
  66.181 +        return svga_in(addr, svga);
  66.182  }
  66.183  
  66.184 -float sdac_getclock(int clock)
  66.185 +float sdac_getclock(int clock, sdac_ramdac_t *ramdac)
  66.186  {
  66.187          float t;
  66.188          int m, n1, n2;
  66.189 -//        pclog("SDAC_Getclock %i %04X\n", clock, sdac_ramdac.regs[clock]);
  66.190 +//        pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]);
  66.191          if (clock == 0) return 25175000.0;
  66.192          if (clock == 1) return 28322000.0;
  66.193          clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/
  66.194 -        m  =  (sdac_ramdac.regs[clock] & 0x7f) + 2;
  66.195 -        n1 = ((sdac_ramdac.regs[clock] >>  8) & 0x1f) + 2;
  66.196 -        n2 = ((sdac_ramdac.regs[clock] >> 13) & 0x07);
  66.197 +        m  =  (ramdac->regs[clock] & 0x7f) + 2;
  66.198 +        n1 = ((ramdac->regs[clock] >>  8) & 0x1f) + 2;
  66.199 +        n2 = ((ramdac->regs[clock] >> 13) & 0x07);
  66.200          t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2);
  66.201 -//        pclog("SDAC clock %i %i %i %f %04X  %f %i\n", m, n1, n2, t, sdac_ramdac.regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2);
  66.202 +//        pclog("SDAC clock %i %i %i %f %04X  %f %i\n", m, n1, n2, t, ramdac->regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2);
  66.203          return t;
  66.204  }
    67.1 --- a/src/vid_sdac_ramdac.h	Tue Jun 04 20:52:17 2013 +0100
    67.2 +++ b/src/vid_sdac_ramdac.h	Mon Jun 24 20:42:35 2013 +0100
    67.3 @@ -1,4 +1,14 @@
    67.4 -void sdac_ramdac_out(uint16_t addr, uint8_t val, void *priv);
    67.5 -uint8_t sdac_ramdac_in(uint16_t addr, void *priv);
    67.6 +typedef struct sdac_ramdac_t
    67.7 +{
    67.8 +        int magic_count;
    67.9 +        uint8_t command;
   67.10 +        int windex, rindex;
   67.11 +        uint16_t regs[256];
   67.12 +        int reg_ff;
   67.13 +        int rs2;
   67.14 +} sdac_ramdac_t;
   67.15  
   67.16 -float sdac_getclock(int clock);
   67.17 +void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga);
   67.18 +uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga);
   67.19 +
   67.20 +float sdac_getclock(int clock, sdac_ramdac_t *ramdac);
    68.1 --- a/src/vid_stg_ramdac.c	Tue Jun 04 20:52:17 2013 +0100
    68.2 +++ b/src/vid_stg_ramdac.c	Mon Jun 24 20:42:35 2013 +0100
    68.3 @@ -4,101 +4,114 @@
    68.4  #include "vid_svga.h"
    68.5  #include "vid_stg_ramdac.h"
    68.6  
    68.7 -struct
    68.8 -{
    68.9 -        int magic_count;
   68.10 -        uint8_t command;
   68.11 -        int index;
   68.12 -        uint8_t regs[256];
   68.13 -} stg_ramdac;
   68.14 +static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}};
   68.15 +static int stg_state_write[8] = {0,0,0,0,0,6,7,7};
   68.16  
   68.17 -int stg_state_read[2][8]={{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}};
   68.18 -int stg_state_write[8]={0,0,0,0,0,6,7,7};
   68.19 -
   68.20 -void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv)
   68.21 +void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga)
   68.22  {
   68.23          int didwrite;
   68.24          //if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc);
   68.25          switch (addr)
   68.26          {
   68.27 -                case 0x3C6:
   68.28 -                switch (stg_ramdac.magic_count)
   68.29 +                case 0x3c6:
   68.30 +                switch (ramdac->magic_count)
   68.31                  {
   68.32 -                        case 0: case 1: case 2: case 3: break;
   68.33 -                        case 4: stg_ramdac.command=val; /*pclog("Write RAMDAC command %02X\n",val);*/ break;
   68.34 -                        case 5: stg_ramdac.index=(stg_ramdac.index&0xFF00)|val; break;
   68.35 -                        case 6: stg_ramdac.index=(stg_ramdac.index&0xFF)|(val<<8); break;
   68.36 +                        case 0: case 1: case 2: case 3: 
   68.37 +                        break;
   68.38 +                        case 4: 
   68.39 +                        ramdac->command = val; 
   68.40 +                        /*pclog("Write RAMDAC command %02X\n",val);*/ 
   68.41 +                        break;
   68.42 +                        case 5: 
   68.43 +                        ramdac->index = (ramdac->index & 0xff00) | val; 
   68.44 +                        break;
   68.45 +                        case 6: 
   68.46 +                        ramdac->index = (ramdac->index & 0xff) | (val << 8); 
   68.47 +                        break;
   68.48                          case 7:
   68.49 -                                pclog("Write RAMDAC reg %02X %02X\n", stg_ramdac.index, val);
   68.50 -                        if (stg_ramdac.index<0x100) stg_ramdac.regs[stg_ramdac.index]=val;
   68.51 -                        stg_ramdac.index++;
   68.52 +                        pclog("Write RAMDAC reg %02X %02X\n", ramdac->index, val);
   68.53 +                        if (ramdac->index < 0x100) 
   68.54 +                                ramdac->regs[ramdac->index] = val;
   68.55 +                        ramdac->index++;
   68.56                          break;
   68.57                  }
   68.58 -                didwrite = (stg_ramdac.magic_count>=4);
   68.59 -                stg_ramdac.magic_count=stg_state_write[stg_ramdac.magic_count&7];
   68.60 -                if (stg_ramdac.command&8)
   68.61 +                didwrite = (ramdac->magic_count >= 4);
   68.62 +                ramdac->magic_count = stg_state_write[ramdac->magic_count & 7];
   68.63 +                if (ramdac->command & 8)
   68.64                  {
   68.65 -                        switch (stg_ramdac.regs[3])
   68.66 +                        switch (ramdac->regs[3])
   68.67                          {
   68.68 -                                case 0: case 5: case 7: bpp=8; break;
   68.69 -                                case 1: case 2: case 8: bpp=15; break;
   68.70 -                                case 3: case 6: bpp=16; break;
   68.71 -                                case 4: case 9: bpp=24; break;
   68.72 -                                default: bpp=8; break;
   68.73 +                                case 0: case 5: case 7: svga->bpp = 8;  break;
   68.74 +                                case 1: case 2: case 8: svga->bpp = 15; break;
   68.75 +                                case 3: case 6:         svga->bpp = 16; break;
   68.76 +                                case 4: case 9:         svga->bpp = 24; break;
   68.77 +                                default:                svga->bpp = 8; break;
   68.78                          }
   68.79                  }
   68.80                  else
   68.81                  {
   68.82 -                        switch (stg_ramdac.command>>5)
   68.83 +                        switch (ramdac->command >> 5)
   68.84                          {
   68.85 -                                case 0: bpp=8;  break;
   68.86 -                                case 5: bpp=15; break;
   68.87 -                                case 6: bpp=16; break;
   68.88 -                                case 7: bpp=24; break;
   68.89 -                                default: bpp=8; break;
   68.90 +                                case 0:  svga->bpp =  8; break;
   68.91 +                                case 5:  svga->bpp = 15; break;
   68.92 +                                case 6:  svga->bpp = 16; break;
   68.93 +                                case 7:  svga->bpp = 24; break;
   68.94 +                                default: svga->bpp =  8; break;
   68.95                          }
   68.96                  }
   68.97                  if (didwrite) return;
   68.98                  break;
   68.99 -                case 0x3C7: case 0x3C8: case 0x3C9:
  68.100 -                stg_ramdac.magic_count=0;
  68.101 +                case 0x3c7: case 0x3c8: case 0x3c9:
  68.102 +                ramdac->magic_count=0;
  68.103                  break;
  68.104          }
  68.105 -        svga_out(addr, val, NULL);
  68.106 +        svga_out(addr, val, svga);
  68.107  }
  68.108  
  68.109 -uint8_t stg_ramdac_in(uint16_t addr, void *priv)
  68.110 +uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga)
  68.111  {
  68.112          uint8_t temp;
  68.113          //if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc);
  68.114          switch (addr)
  68.115          {
  68.116 -                case 0x3C6:
  68.117 -                switch (stg_ramdac.magic_count)
  68.118 +                case 0x3c6:
  68.119 +                switch (ramdac->magic_count)
  68.120                  {
  68.121 -                        case 0: case 1: case 2: case 3: temp=0xFF; break;
  68.122 -                        case 4: temp=stg_ramdac.command; break;
  68.123 -                        case 5: temp=stg_ramdac.index&0xFF; break;
  68.124 -                        case 6: temp=stg_ramdac.index>>8; break;
  68.125 +                        case 0: case 1: case 2: case 3: 
  68.126 +                        temp = 0xff;
  68.127 +                        break;
  68.128 +                        case 4: 
  68.129 +                        temp = ramdac->command; 
  68.130 +                        break;
  68.131 +                        case 5: 
  68.132 +                        temp = ramdac->index & 0xff; 
  68.133 +                        break;
  68.134 +                        case 6: 
  68.135 +                        temp = ramdac->index >> 8; 
  68.136 +                        break;
  68.137                          case 7:
  68.138  //                                pclog("Read RAMDAC index %04X\n",stg_ramdac.index);
  68.139 -                        switch (stg_ramdac.index)
  68.140 +                        switch (ramdac->index)
  68.141                          {
  68.142 -                                case 0: temp=0x44; break;
  68.143 -                                case 1: temp=0x02; break;
  68.144 +                                case 0: 
  68.145 +                                temp = 0x44; 
  68.146 +                                break;
  68.147 +                                case 1: 
  68.148 +                                temp = 0x02; 
  68.149 +                                break;
  68.150                                  default:
  68.151 -                                if (stg_ramdac.index<0x100) temp=stg_ramdac.regs[stg_ramdac.index];
  68.152 -                                else                        temp=0xFF;
  68.153 +                                if (ramdac->index < 0x100) temp = ramdac->regs[ramdac->index];
  68.154 +                                else                       temp = 0xff;
  68.155                                  break;
  68.156                          }
  68.157 -                        stg_ramdac.index++;
  68.158 +                        ramdac->index++;
  68.159                          break;
  68.160                  }
  68.161 -                stg_ramdac.magic_count=stg_state_read[(stg_ramdac.command&0x10)?1:0][stg_ramdac.magic_count&7];
  68.162 +                ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7];
  68.163                  return temp;
  68.164 -                case 0x3C8: case 0x3C9:
  68.165 -                stg_ramdac.magic_count=0;
  68.166 +                case 0x3c8: case 0x3c9:
  68.167 +                ramdac->magic_count=0;
  68.168                  break;
  68.169          }
  68.170 -        return svga_in(addr, NULL);
  68.171 +        return svga_in(addr, svga);
  68.172  }
    69.1 --- a/src/vid_stg_ramdac.h	Tue Jun 04 20:52:17 2013 +0100
    69.2 +++ b/src/vid_stg_ramdac.h	Mon Jun 24 20:42:35 2013 +0100
    69.3 @@ -1,2 +1,10 @@
    69.4 -void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv);
    69.5 -uint8_t stg_ramdac_in(uint16_t addr, void *priv);
    69.6 +typedef struct stg_ramdac_t
    69.7 +{
    69.8 +        int magic_count;
    69.9 +        uint8_t command;
   69.10 +        int index;
   69.11 +        uint8_t regs[256];
   69.12 +} stg_ramdac_t;
   69.13 +
   69.14 +void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga);
   69.15 +uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga);
    70.1 --- a/src/vid_svga.c	Tue Jun 04 20:52:17 2013 +0100
    70.2 +++ b/src/vid_svga.c	Mon Jun 24 20:42:35 2013 +0100
    70.3 @@ -1,5 +1,6 @@
    70.4  /*Generic SVGA handling*/
    70.5  /*This is intended to be used by another SVGA driver, and not as a card in it's own right*/
    70.6 +#include <stdlib.h>
    70.7  #include "ibm.h"
    70.8  #include "mem.h"
    70.9  #include "video.h"
   70.10 @@ -10,322 +11,344 @@
   70.11  
   70.12  #define svga_output 0
   70.13  
   70.14 -uint32_t svga_vram_limit;
   70.15 +void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga);
   70.16  
   70.17  extern uint8_t edatlookup[4][4];
   70.18 -uint8_t svga_miscout;
   70.19  
   70.20 -static uint8_t la, lb, lc, ld;
   70.21  uint8_t svga_rotate[8][256];
   70.22  
   70.23 -static int svga_fast;
   70.24  
   70.25 -void (*svga_render)();
   70.26 -
   70.27 -static uint8_t dacmask, dacstatus;
   70.28 -
   70.29 -void svga_out(uint16_t addr, uint8_t val, void *priv)
   70.30 +void svga_out(uint16_t addr, uint8_t val, void *p)
   70.31  {
   70.32 +        svga_t *svga = (svga_t *)p;
   70.33          int c;
   70.34          uint8_t o;
   70.35  //        printf("OUT SVGA %03X %02X %04X:%04X %i %08X\n",addr,val,CS,pc,TRIDENT,svgawbank);
   70.36          switch (addr)
   70.37          {
   70.38                  case 0x3C0:
   70.39 -                if (!attrff)
   70.40 -                   attraddr=val&31;
   70.41 +                if (!svga->attrff)
   70.42 +                   svga->attraddr = val & 31;
   70.43                  else
   70.44                  {
   70.45 -                        attrregs[attraddr&31]=val;
   70.46 -                        if (attraddr<16) fullchange=changeframecount;
   70.47 -                        if (attraddr==0x10 || attraddr==0x14 || attraddr<0x10)
   70.48 +                        svga->attrregs[svga->attraddr & 31] = val;
   70.49 +                        if (svga->attraddr < 16) 
   70.50 +                                svga->fullchange = changeframecount;
   70.51 +                        if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10)
   70.52                          {
   70.53 -                                for (c=0;c<16;c++)
   70.54 +                                for (c = 0; c < 16; c++)
   70.55                                  {
   70.56 -                                        if (attrregs[0x10]&0x80) egapal[c]=(attrregs[c]&0xF)|((attrregs[0x14]&0xF)<<4);
   70.57 -                                        else                     egapal[c]=(attrregs[c]&0x3F)|((attrregs[0x14]&0xC)<<4);
   70.58 +                                        if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] &  0xf) | ((svga->attrregs[0x14] & 0xf) << 4);
   70.59 +                                        else                             svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4);
   70.60                                  }
   70.61                          }
   70.62 -                        if (attraddr == 0x10) svga_recalctimings();
   70.63 +                        if (svga->attraddr == 0x10) 
   70.64 +                                svga_recalctimings(svga);
   70.65                  }
   70.66 -                attrff^=1;
   70.67 +                svga->attrff ^= 1;
   70.68                  break;
   70.69                  case 0x3C2:
   70.70 -                svga_miscout = val;
   70.71 -                vres = 0; pallook = pallook256;
   70.72 -                vidclock = val & 4; printf("3C2 write %02X\n",val);
   70.73 +                svga->miscout = val;
   70.74 +                svga->vidclock = val & 4; printf("3C2 write %02X\n",val);
   70.75                  if (val & 1)
   70.76                  {
   70.77                          pclog("Remove mono handler\n");
   70.78 -                        io_removehandler(0x03a0, 0x0020, video_in,      NULL, NULL, video_out,      NULL, NULL, NULL);
   70.79 +                        io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p);
   70.80                  }
   70.81                  else
   70.82                  {
   70.83                          pclog("Set mono handler\n");
   70.84 -                        io_sethandler(0x03a0, 0x0020, video_in, NULL, NULL, video_out, NULL, NULL, NULL);
   70.85 +                        io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p);
   70.86                  }
   70.87                  break;
   70.88 -                case 0x3C4: seqaddr=val; break;
   70.89 +                case 0x3C4: 
   70.90 +                svga->seqaddr = val; 
   70.91 +                break;
   70.92                  case 0x3C5:
   70.93 -                if (seqaddr > 0xf) return;
   70.94 -                o=seqregs[seqaddr&0xF];
   70.95 -                seqregs[seqaddr&0xF]=val;
   70.96 -                if (o!=val && (seqaddr&0xF)==1) svga_recalctimings();
   70.97 -                switch (seqaddr&0xF)
   70.98 +                if (svga->seqaddr > 0xf) return;
   70.99 +                o = svga->seqregs[svga->seqaddr & 0xf];
  70.100 +                svga->seqregs[svga->seqaddr & 0xf] = val;
  70.101 +                if (o != val && (svga->seqaddr & 0xf) == 1)
  70.102 +                        svga_recalctimings(svga);
  70.103 +                switch (svga->seqaddr & 0xf)
  70.104                  {
  70.105                          case 1: 
  70.106 -                        if (scrblank && !(val&0x20)) 
  70.107 -                                fullchange=3; 
  70.108 -                        scrblank=(scrblank&~0x20)|(val&0x20); 
  70.109 -                        svga_recalctimings();
  70.110 +                        if (svga->scrblank && !(val & 0x20)) 
  70.111 +                                svga->fullchange = 3; 
  70.112 +                        svga->scrblank = (svga->scrblank & ~0x20) | (val & 0x20); 
  70.113 +                        svga_recalctimings(svga);
  70.114                          break;
  70.115 -                        case 2: writemask=val&0xF; break;
  70.116 +                        case 2: 
  70.117 +                        svga->writemask = val & 0xf; 
  70.118 +                        break;
  70.119                          case 3:
  70.120 -                        charset=val&0xF;
  70.121 -                        charseta=((charset>>2)*0x10000)+2;
  70.122 -                        charsetb=((charset&3) *0x10000)+2;
  70.123 +                        svga->charseta = (((val >> 2) & 3) * 0x10000) + 2;
  70.124 +                        svga->charsetb = ((val & 3)  * 0x10000) + 2;
  70.125                          break;
  70.126                          case 4: 
  70.127 -                        chain4=val&8; /*printf("Chain4 %i %02X\n",val&8,gdcreg[5]&0x60); */
  70.128 -                        svga_fast = (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) && chain4;
  70.129 +                        svga->chain4 = val & 8;
  70.130 +                        svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4;
  70.131                          break;
  70.132                  }
  70.133                  break;
  70.134 -                case 0x3c6: dacmask=val; break;
  70.135 -                case 0x3C7: dacread=val; dacpos=0; break;
  70.136 -                case 0x3C8: dacwrite=val; dacpos=0; break;
  70.137 +                case 0x3c6: 
  70.138 +                svga->dac_mask = val; 
  70.139 +                break;
  70.140 +                case 0x3C7: 
  70.141 +                svga->dac_read = val; 
  70.142 +                svga->dac_pos = 0; 
  70.143 +                break;
  70.144 +                case 0x3C8: 
  70.145 +                svga->dac_write = val; 
  70.146 +                svga->dac_pos = 0; 
  70.147 +                break;
  70.148                  case 0x3C9:
  70.149 -                dacstatus = 0;
  70.150 -/*                if (pc == 0x68AD)
  70.151 +                svga->dac_status = 0;
  70.152 +                svga->fullchange = changeframecount;
  70.153 +                switch (svga->dac_pos)
  70.154                  {
  70.155 -                        dumpregs();
  70.156 -                        exit(-1);
  70.157 -                }*/
  70.158 -                palchange=1;
  70.159 -                fullchange=changeframecount;
  70.160 -                switch (dacpos)
  70.161 -                {
  70.162 -                        case 0: vgapal[dacwrite].r=val&63; pallook256[dacwrite]=makecol32(vgapal[dacwrite].r*4,vgapal[dacwrite].g*4,vgapal[dacwrite].b*4); dacpos++; break;
  70.163 -                        case 1: vgapal[dacwrite].g=val&63; pallook256[dacwrite]=makecol32(vgapal[dacwrite].r*4,vgapal[dacwrite].g*4,vgapal[dacwrite].b*4); dacpos++; break;
  70.164 -                        case 2: vgapal[dacwrite].b=val&63; pallook256[dacwrite]=makecol32(vgapal[dacwrite].r*4,vgapal[dacwrite].g*4,vgapal[dacwrite].b*4); dacpos=0; dacwrite=(dacwrite+1)&255; break;
  70.165 +                        case 0: 
  70.166 +                        svga->vgapal[svga->dac_write].r = val & 63;
  70.167 +                        svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r * 4, svga->vgapal[svga->dac_write].g * 4, svga->vgapal[svga->dac_write].b * 4); 
  70.168 +                        svga->dac_pos++; 
  70.169 +                        break;
  70.170 +                        case 1: 
  70.171 +                        svga->vgapal[svga->dac_write].g = val & 63; 
  70.172 +                        svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r * 4, svga->vgapal[svga->dac_write].g * 4, svga->vgapal[svga->dac_write].b * 4); 
  70.173 +                        svga->dac_pos++; 
  70.174 +                        break;
  70.175 +                        case 2: 
  70.176 +                        svga->vgapal[svga->dac_write].b = val & 63; 
  70.177 +                        svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r * 4, svga->vgapal[svga->dac_write].g * 4, svga->vgapal[svga->dac_write].b * 4); 
  70.178 +                        svga->dac_pos = 0; 
  70.179 +                        svga->dac_write = (svga->dac_write + 1) & 255; 
  70.180 +                        break;
  70.181                  }
  70.182                  break;
  70.183 -                case 0x3CE: gdcaddr=val; break;
  70.184 +                case 0x3CE: 
  70.185 +                svga->gdcaddr = val; 
  70.186 +                break;
  70.187                  case 0x3CF:
  70.188 -                o = gdcreg[gdcaddr & 15];
  70.189 -                switch (gdcaddr&15)
  70.190 +                o = svga->gdcreg[svga->gdcaddr & 15];
  70.191 +                switch (svga->gdcaddr & 15)
  70.192                  {
  70.193 -                        case 2: colourcompare=val; break;
  70.194 -                        case 4: readplane=val&3; break;
  70.195 -                        case 5: writemode=val&3; readmode=val&8; break;
  70.196 +                        case 2: svga->colourcompare=val; break;
  70.197 +                        case 4: svga->readplane=val&3; break;
  70.198 +                        case 5: svga->writemode=val&3; svga->readmode=val&8; break;
  70.199                          case 6:
  70.200 -                        if ((gdcreg[6] & 0xc) != (val & 0xc))
  70.201 +                                pclog("svga_out recalcmapping %p\n", svga);
  70.202 +                        if ((svga->gdcreg[6] & 0xc) != (val & 0xc))
  70.203                          {
  70.204 -                                mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  70.205 +                                mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, p);
  70.206                                  pclog("Write mapping %02X\n", val);
  70.207                                  switch (val&0xC)
  70.208                                  {
  70.209                                          case 0x0: /*128k at A0000*/
  70.210 -                                        mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  70.211 +                                        mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, p);
  70.212                                          break;
  70.213                                          case 0x4: /*64k at A0000*/
  70.214 -                                        mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  70.215 +                                        mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, p);
  70.216                                          break;
  70.217                                          case 0x8: /*32k at B0000*/
  70.218 -                                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  70.219 +                                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, p);
  70.220                                          break;
  70.221                                          case 0xC: /*32k at B8000*/
  70.222 -                                        mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL);
  70.223 +                                        mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, p);
  70.224                                          break;
  70.225                                  }
  70.226                          }
  70.227                          break;
  70.228 -                        case 7: colournocare=val; break;
  70.229 +                        case 7: svga->colournocare=val; break;
  70.230                  }
  70.231 -                gdcreg[gdcaddr&15]=val;                
  70.232 -                svga_fast = (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1]) && chain4;
  70.233 -                if (((gdcaddr & 15) == 5  && (val ^ o) & 0x70) || ((gdcaddr & 15) == 6 && (val ^ o) & 1))
  70.234 -                        svga_recalctimings();
  70.235 +                svga->gdcreg[svga->gdcaddr & 15] = val;                
  70.236 +                svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4;
  70.237 +                if (((svga->gdcaddr & 15) == 5  && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1))
  70.238 +                        svga_recalctimings(svga);
  70.239                  break;
  70.240          }
  70.241  }
  70.242  
  70.243 -uint8_t svga_in(uint16_t addr, void *priv)
  70.244 +uint8_t svga_in(uint16_t addr, void *p)
  70.245  {
  70.246 +        svga_t *svga = (svga_t *)p;
  70.247          uint8_t temp;
  70.248  //        if (addr!=0x3da) pclog("Read port %04X\n",addr);
  70.249          switch (addr)
  70.250          {
  70.251 -                case 0x3C0: return attraddr;
  70.252 -                case 0x3C1: return attrregs[attraddr];
  70.253 +                case 0x3C0: 
  70.254 +                return svga->attraddr;
  70.255 +                case 0x3C1: 
  70.256 +                return svga->attrregs[svga->attraddr];
  70.257                  case 0x3c2:
  70.258 -                if ((vgapal[0].r + vgapal[0].g + vgapal[0].b) >= 0x50)
  70.259 +                if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50)
  70.260                          temp = 0;
  70.261                  else
  70.262                          temp = 0x10;
  70.263                  return temp;
  70.264 -                case 0x3C4: return seqaddr;
  70.265 +                case 0x3C4: 
  70.266 +                return svga->seqaddr;
  70.267                  case 0x3C5:
  70.268 -                return seqregs[seqaddr&0xF];
  70.269 -                case 0x3c6: return dacmask;
  70.270 -                case 0x3c7: return dacstatus;
  70.271 -                case 0x3C8: return dacwrite;
  70.272 -                case 0x3C9:
  70.273 -                dacstatus=3;
  70.274 -                palchange=1;
  70.275 -                switch (dacpos)
  70.276 +                return svga->seqregs[svga->seqaddr & 0xF];
  70.277 +                case 0x3c6: return svga->dac_mask;
  70.278 +                case 0x3c7: return svga->dac_status;
  70.279 +                case 0x3c8: return svga->dac_write;
  70.280 +                case 0x3c9:
  70.281 +                svga->dac_status = 3;
  70.282 +                switch (svga->dac_pos)
  70.283                  {
  70.284 -                        case 0: dacpos++; return vgapal[dacread].r;
  70.285 -                        case 1: dacpos++; return vgapal[dacread].g;
  70.286 -                        case 2: dacpos=0; dacread=(dacread+1)&255; return vgapal[(dacread-1)&255].b;
  70.287 +                        case 0: 
  70.288 +                        svga->dac_pos++; 
  70.289 +                        return svga->vgapal[svga->dac_read].r;
  70.290 +                        case 1: 
  70.291 +                        svga->dac_pos++; 
  70.292 +                        return svga->vgapal[svga->dac_read].g;
  70.293 +                        case 2: 
  70.294 +                        svga->dac_pos=0; 
  70.295 +                        svga->dac_read = (svga->dac_read + 1) & 255; 
  70.296 +                        return svga->vgapal[(svga->dac_read - 1) & 255].b;
  70.297                  }
  70.298                  break;
  70.299 -                case 0x3CC: return svga_miscout;
  70.300 -                case 0x3CE: return gdcaddr;
  70.301 +                case 0x3CC: 
  70.302 +                return svga->miscout;
  70.303 +                case 0x3CE: 
  70.304 +                return svga->gdcaddr;
  70.305                  case 0x3CF:
  70.306 -                return gdcreg[gdcaddr&0xF];
  70.307 +                return svga->gdcreg[svga->gdcaddr & 0xf];
  70.308                  case 0x3DA:
  70.309 -                attrff=0;
  70.310 -                cgastat^=0x30;
  70.311 -                return cgastat;
  70.312 +                svga->attrff = 0;
  70.313 +                svga->cgastat ^= 0x30;
  70.314 +                return svga->cgastat;
  70.315          }
  70.316  //        printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc);
  70.317          return 0xFF;
  70.318  }
  70.319  
  70.320 -int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split;
  70.321 -int svga_hdisp,  svga_htotal,  svga_hdisp_time, svga_rowoffset;
  70.322 -int svga_lowres, svga_interlace;
  70.323 -int svga_linedbl, svga_rowcount;
  70.324 -double svga_clock;
  70.325 -uint32_t svga_ma;
  70.326 -void (*svga_recalctimings_ex)() = NULL;
  70.327 -void (*svga_hwcursor_draw)(int displine) = NULL;
  70.328 -
  70.329 -void svga_recalctimings()
  70.330 +void svga_recalctimings(svga_t *svga)
  70.331  {
  70.332          double crtcconst;
  70.333 -        double _dispontime, _dispofftime;
  70.334 +        double _dispontime, _dispofftime, disptime;
  70.335 +        int hdisp_old;
  70.336  
  70.337 -        svga_vtotal=crtc[6];
  70.338 -        svga_dispend=crtc[0x12];
  70.339 -        svga_vsyncstart=crtc[0x10];
  70.340 -        svga_split=crtc[0x18];
  70.341 +        svga->vtotal = svga->crtc[6];
  70.342 +        svga->dispend = svga->crtc[0x12];
  70.343 +        svga->vsyncstart = svga->crtc[0x10];
  70.344 +        svga->split = svga->crtc[0x18];
  70.345  
  70.346 -        if (crtc[7]&1)    svga_vtotal|=0x100;
  70.347 -        if (crtc[7]&32)   svga_vtotal|=0x200;
  70.348 -        svga_vtotal+=2;
  70.349 +        if (svga->crtc[7] & 1)  svga->vtotal |= 0x100;
  70.350 +        if (svga->crtc[7] & 32) svga->vtotal |= 0x200;
  70.351 +        svga->vtotal += 2;
  70.352  
  70.353 +        if (svga->crtc[7] & 2)  svga->dispend |= 0x100;
  70.354 +        if (svga->crtc[7] & 64) svga->dispend |= 0x200;
  70.355 +        svga->dispend++;
  70.356  
  70.357 -        if (crtc[7]&2)    svga_dispend|=0x100;
  70.358 -        if (crtc[7]&64)   svga_dispend|=0x200;
  70.359 -        svga_dispend++;
  70.360 +        if (svga->crtc[7] & 4)   svga->vsyncstart |= 0x100;
  70.361 +        if (svga->crtc[7] & 128) svga->vsyncstart |= 0x200;
  70.362 +        svga->vsyncstart++;
  70.363  
  70.364 -        if (crtc[7]&4)    svga_vsyncstart|=0x100;
  70.365 -        if (crtc[7]&128)  svga_vsyncstart|=0x200;
  70.366 -        svga_vsyncstart++;
  70.367 +        if (svga->crtc[7] & 0x10) svga->split|=0x100;
  70.368 +        if (svga->crtc[9] & 0x40) svga->split|=0x200;
  70.369 +        svga->split++;
  70.370  
  70.371 -        if (crtc[7]&0x10) svga_split|=0x100;
  70.372 -        if (crtc[9]&0x40) svga_split|=0x200;
  70.373 -        svga_split++;
  70.374 +        svga->hdisp = svga->crtc[1];
  70.375 +        svga->hdisp++;
  70.376  
  70.377 -        svga_hdisp=crtc[1];
  70.378 -        svga_hdisp++;
  70.379 +        svga->htotal = svga->crtc[0];
  70.380 +        svga->htotal += 6; /*+6 is required for Tyrian*/
  70.381  
  70.382 -        svga_htotal=crtc[0];
  70.383 -        svga_htotal+=6; /*+6 is required for Tyrian*/
  70.384 +        svga->rowoffset = svga->crtc[0x13];
  70.385  
  70.386 -        svga_rowoffset=crtc[0x13];
  70.387 +        svga->clock = (svga->vidclock) ? VGACONST2 : VGACONST1;
  70.388 +        
  70.389 +        svga->lowres = svga->attrregs[0x10] & 0x40;
  70.390 +        
  70.391 +        svga->interlace = 0;
  70.392 +        
  70.393 +        svga->ma_latch = (svga->crtc[0xc] << 8) | svga->crtc[0xd];
  70.394  
  70.395 -        svga_clock = (vidclock) ? VGACONST2 : VGACONST1;
  70.396 -        
  70.397 -        svga_lowres = attrregs[0x10]&0x40;
  70.398 -        
  70.399 -        svga_interlace = 0;
  70.400 -        
  70.401 -        svga_ma = (crtc[0xC]<<8)|crtc[0xD];
  70.402 -
  70.403 -        svga_hdisp_time = svga_hdisp;
  70.404 -        svga_render = svga_render_blank;
  70.405 -        if (!scrblank)
  70.406 +        svga->hdisp_time = svga->hdisp;
  70.407 +        svga->render = svga_render_blank;
  70.408 +        if (!svga->scrblank)
  70.409          {
  70.410 -                if (!(gdcreg[6]&1)) /*Text mode*/
  70.411 +                if (!(svga->gdcreg[6] & 1)) /*Text mode*/
  70.412                  {
  70.413 -                        if (seqregs[1]&8) /*40 column*/
  70.414 +                        if (svga->seqregs[1] & 8) /*40 column*/
  70.415                          {
  70.416 -                                svga_render = svga_render_text_40;
  70.417 -                                svga_hdisp *= (seqregs[1] & 1) ? 16 : 18;
  70.418 +                                svga->render = svga_render_text_40;
  70.419 +                                svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18;
  70.420                          }
  70.421                          else
  70.422                          {
  70.423 -                                svga_render = svga_render_text_80;
  70.424 -                                svga_hdisp *= (seqregs[1] & 1) ? 8 : 9;
  70.425 +                                svga->render = svga_render_text_80;
  70.426 +                                svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9;
  70.427                          }
  70.428 +                        svga->hdisp_old = svga->hdisp;
  70.429                  }
  70.430                  else 
  70.431                  {
  70.432 -                        svga_hdisp *= (seqregs[1] & 8) ? 16 : 8;
  70.433 +                        svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8;
  70.434 +                        svga->hdisp_old = svga->hdisp;                        
  70.435                          
  70.436 -                        switch (gdcreg[5]&0x60)
  70.437 +                        switch (svga->gdcreg[5] & 0x60)
  70.438                          {
  70.439                                  case 0x00: /*16 colours*/
  70.440 -                                if (seqregs[1]&8) /*Low res (320)*/
  70.441 -                                        svga_render = svga_render_4bpp_lowres;
  70.442 +                                if (svga->seqregs[1] & 8) /*Low res (320)*/
  70.443 +                                        svga->render = svga_render_4bpp_lowres;
  70.444                                  else
  70.445 -                                        svga_render = svga_render_4bpp_highres;
  70.446 +                                        svga->render = svga_render_4bpp_highres;
  70.447                                  break;
  70.448                                  case 0x20: /*4 colours*/
  70.449 -                                svga_render = svga_render_2bpp_lowres;
  70.450 +                                svga->render = svga_render_2bpp_lowres;
  70.451                                  break;
  70.452                                  case 0x40: case 0x60: /*256+ colours*/
  70.453 -                                switch (bpp)
  70.454 +                                switch (svga->bpp)
  70.455                                  {
  70.456                                          case 8:
  70.457 -                                        if (svga_lowres)
  70.458 -                                                svga_render = svga_render_8bpp_lowres;
  70.459 +                                        if (svga->lowres)
  70.460 +                                                svga->render = svga_render_8bpp_lowres;
  70.461                                          else
  70.462                                          {
  70.463 -                                                svga_render = svga_render_8bpp_highres;
  70.464 +                                                svga->render = svga_render_8bpp_highres;
  70.465  //                                                svga_hdisp <<= 1;
  70.466                                          }
  70.467                                          break;
  70.468                                          case 15:
  70.469 -                                        if (svga_lowres)
  70.470 -                                                svga_render = svga_render_15bpp_lowres;
  70.471 +                                        if (svga->lowres)
  70.472 +                                                svga->render = svga_render_15bpp_lowres;
  70.473                                          else
  70.474                                          {
  70.475 -                                                svga_render = svga_render_15bpp_highres;
  70.476 -                                                svga_hdisp <<= 1;
  70.477 +                                                svga->render = svga_render_15bpp_highres;
  70.478 +                                                svga->hdisp <<= 1;
  70.479                                          }
  70.480                                          break;
  70.481                                          case 16:
  70.482 -                                        if (svga_lowres)
  70.483 -                                                svga_render = svga_render_16bpp_lowres;
  70.484 +                                        if (svga->lowres)
  70.485 +                                                svga->render = svga_render_16bpp_lowres;
  70.486                                          else
  70.487                                          {
  70.488 -                                                svga_render = svga_render_16bpp_highres;
  70.489 -                                                svga_hdisp <<= 1;
  70.490 +                                                svga->render = svga_render_16bpp_highres;
  70.491 +                                                svga->hdisp <<= 1;
  70.492                                          }
  70.493                                          break;
  70.494                                          case 24:
  70.495 -                                        if (svga_lowres)
  70.496 +                                        if (svga->lowres)
  70.497                                          {
  70.498 -                                                svga_render = svga_render_24bpp_lowres;
  70.499 -                                                svga_hdisp = ((svga_hdisp<<3)/3);
  70.500 +                                                svga->render = svga_render_24bpp_lowres;
  70.501 +                                                svga->hdisp = ((svga->hdisp << 3) / 3);
  70.502                                          }
  70.503                                          else
  70.504                                          {
  70.505 -                                                svga_render = svga_render_24bpp_highres;
  70.506 -                                                svga_hdisp = ((svga_hdisp<<3)/3);
  70.507 +                                                svga->render = svga_render_24bpp_highres;
  70.508 +                                                svga->hdisp = ((svga->hdisp << 3) / 3);
  70.509                                          }
  70.510                                          break;
  70.511                                          case 32:
  70.512 -                                        if (svga_lowres)
  70.513 -                                                svga_render = svga_render_32bpp_lowres;
  70.514 +                                        if (svga->lowres)
  70.515 +                                                svga->render = svga_render_32bpp_lowres;
  70.516                                          else
  70.517                                          {
  70.518 -                                                svga_render = svga_render_32bpp_highres;
  70.519 -                                                svga_hdisp <<= 1;
  70.520 +                                                svga->render = svga_render_32bpp_highres;
  70.521 +                                                svga->hdisp <<= 1;
  70.522                                          }
  70.523                                          break;
  70.524                                  }
  70.525 @@ -336,253 +359,260 @@
  70.526  
  70.527  //        pclog("svga_render %08X : %08X %08X %08X %08X %08X  %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8);
  70.528          
  70.529 -        svga_linedbl = crtc[9] & 0x80;
  70.530 -        svga_rowcount = crtc[9] & 31;
  70.531 -        if (svga_recalctimings_ex) svga_recalctimings_ex();
  70.532 +        svga->linedbl = svga->crtc[9] & 0x80;
  70.533 +        svga->rowcount = svga->crtc[9] & 31;
  70.534 +        if (svga->recalctimings_ex) 
  70.535 +                svga->recalctimings_ex(svga);
  70.536          
  70.537 -        crtcconst=(seqregs[1]&1)?(svga_clock*8.0):(svga_clock*9.0);
  70.538 +        crtcconst = (svga->seqregs[1] & 1) ? (svga->clock * 8.0) : (svga->clock * 9.0);
  70.539  
  70.540 -        disptime  =svga_htotal;
  70.541 -        _dispontime = svga_hdisp_time;
  70.542 +        disptime  = svga->htotal;
  70.543 +        _dispontime = svga->hdisp_time;
  70.544          
  70.545  //        printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8);
  70.546 -        if (seqregs[1]&8) { disptime*=2; _dispontime*=2; }
  70.547 -        _dispofftime=disptime-_dispontime;
  70.548 -        _dispontime*=crtcconst;
  70.549 -        _dispofftime*=crtcconst;
  70.550 +        if (svga->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; }
  70.551 +        _dispofftime = disptime - _dispontime;
  70.552 +        _dispontime *= crtcconst;
  70.553 +        _dispofftime *= crtcconst;
  70.554  
  70.555 -	dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  70.556 -	dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  70.557 -//        printf("SVGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4));
  70.558 -//        printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga_vtotal,svga_dispend,(crtc[9]&31)+1,svga_vsyncstart);
  70.559 -//        printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*svga_vtotal,(dispontime+dispofftime)*svga_vtotal*70,seqregs[1]);
  70.560 +	svga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  70.561 +	svga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  70.562 +/*        printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock);
  70.563 +        printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart);
  70.564 +        printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]);
  70.565  
  70.566 -//        pclog("svga_render %08X\n", svga_render);
  70.567 +        pclog("svga->render %08X\n", svga->render);*/
  70.568  }
  70.569  
  70.570 -void (*svga_render)();
  70.571 -
  70.572 -uint32_t ma, maback, ca;
  70.573 -static int vc;
  70.574 -int sc;
  70.575 -static int linepos, vslines, linecountff, oddeven;
  70.576 -static int svga_dispon;
  70.577 -int con, coff, cursoron, cgablink;
  70.578 -int scrollcache;
  70.579 -
  70.580 -int svga_hwcursor_on;
  70.581 -
  70.582 -SVGA_HWCURSOR svga_hwcursor, svga_hwcursor_latch;
  70.583 -
  70.584 -int svga_hdisp_on;
  70.585 -
  70.586 -int firstline_draw = 2000, lastline_draw = 0;
  70.587 -int displine;
  70.588 -
  70.589 -void svga_poll()
  70.590 +extern int cyc_total;
  70.591 +void svga_poll(void *p)
  70.592  {
  70.593 +        svga_t *svga = (svga_t *)p;
  70.594          int x;
  70.595  
  70.596 -        if (!linepos)
  70.597 +        if (!svga->linepos)
  70.598          {
  70.599  //                if (!(vc & 15)) pclog("VC %i %i\n", vc, GetTickCount());
  70.600 -                if (displine == svga_hwcursor_latch.y && svga_hwcursor_latch.ena)
  70.601 -                   svga_hwcursor_on = 64 - svga_hwcursor_latch.yoff;
  70.602 -                vidtime+=dispofftime;
  70.603 +                if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena)
  70.604 +                   svga->hwcursor_on = 64 - svga->hwcursor_latch.yoff;
  70.605 +                svga->vidtime += svga->dispofftime;
  70.606  //                if (output) printf("Display off %f\n",vidtime);
  70.607 -                cgastat|=1;
  70.608 -                linepos=1;
  70.609 +                svga->cgastat |= 1;
  70.610 +                svga->linepos = 1;
  70.611  
  70.612 -                if (svga_dispon)
  70.613 +                if (svga->dispon)
  70.614                  {
  70.615 -                        svga_hdisp_on=1;
  70.616 +                        svga->hdisp_on=1;
  70.617                          
  70.618 -                        ma&=vrammask;
  70.619 -                        if (firstline==2000) firstline=displine;
  70.620 +                        svga->ma &= svga->vrammask;
  70.621 +                        if (svga->firstline == 2000) 
  70.622 +                                svga->firstline = svga->displine;
  70.623                          
  70.624 -                        if (svga_hwcursor_on) changedvram[ma >> 10] = changedvram[(ma >> 10) + 1] = 2;
  70.625 +                        if (svga->hwcursor_on) 
  70.626 +                                svga->changedvram[svga->ma >> 10] = svga->changedvram[(svga->ma >> 10) + 1] = 2;
  70.627                          
  70.628 -                        svga_render();
  70.629 +                        svga->render(svga);
  70.630                          
  70.631 -                                if (svga_hwcursor_on)
  70.632 -                                {
  70.633 -                                        svga_hwcursor_draw(displine);
  70.634 -                                        svga_hwcursor_on--;
  70.635 -                                }
  70.636 +                        if (svga->hwcursor_on)
  70.637 +                        {
  70.638 +                                svga->hwcursor_draw(svga, svga->displine);
  70.639 +                                svga->hwcursor_on--;
  70.640 +                        }
  70.641  
  70.642 -                        if (lastline<displine) lastline=displine;
  70.643 +                        if (svga->lastline < svga->displine) 
  70.644 +                                svga->lastline = svga->displine;
  70.645                  }
  70.646  
  70.647  //                pclog("%03i %06X %06X\n",displine,ma,vrammask);
  70.648 -                displine++;
  70.649 -                if (svga_interlace) displine++;
  70.650 -                if ((cgastat&8) && ((displine&15)==(crtc[0x11]&15)) && vslines)
  70.651 +                svga->displine++;
  70.652 +                if (svga->interlace) 
  70.653 +                        svga->displine++;
  70.654 +                if ((svga->cgastat & 8) && ((svga->displine & 15) == (svga->crtc[0x11] & 15)) && svga->vslines)
  70.655                  {
  70.656  //                        printf("Vsync off at line %i\n",displine);
  70.657 -                        cgastat&=~8;
  70.658 +                        svga->cgastat &= ~8;
  70.659                  }
  70.660 -                vslines++;
  70.661 -                if (displine>1500) displine=0;
  70.662 +                svga->vslines++;
  70.663 +                if (svga->displine > 1500)
  70.664 +                        svga->displine = 0;
  70.665  //                pclog("Col is %08X %08X %08X   %i %i  %08X\n",((uint32_t *)buffer32->line[displine])[320],((uint32_t *)buffer32->line[displine])[321],((uint32_t *)buffer32->line[displine])[322],
  70.666  //                                                                displine, vc, ma);
  70.667          }
  70.668          else
  70.669          {
  70.670  //                pclog("VC %i ma %05X\n", vc, ma);
  70.671 -                vidtime+=dispontime;
  70.672 +                svga->vidtime += svga->dispontime;
  70.673 +
  70.674 +//                if (output) printf("Display on %f\n",vidtime);
  70.675 +                if (svga->dispon) 
  70.676 +                        svga->cgastat &= ~1;
  70.677 +                svga->hdisp_on = 0;
  70.678                  
  70.679 -//                if (output) printf("Display on %f\n",vidtime);
  70.680 -                if (svga_dispon) cgastat&=~1;
  70.681 -                svga_hdisp_on=0;
  70.682 -                
  70.683 -                linepos=0;
  70.684 -                if (sc==(crtc[11]&31)) con = 0;
  70.685 -                if (svga_dispon)
  70.686 +                svga->linepos = 0;
  70.687 +                if (svga->sc == (svga->crtc[11] & 31)) 
  70.688 +                        svga->con = 0;
  70.689 +                if (svga->dispon)
  70.690                  {
  70.691 -                        if (svga_linedbl && !linecountff)
  70.692 +                        if (svga->linedbl && !svga->linecountff)
  70.693                          {
  70.694 -                                linecountff=1;
  70.695 -                                ma=maback;
  70.696 +                                svga->linecountff = 1;
  70.697 +                                svga->ma = svga->maback;
  70.698                          }
  70.699 -                        else if (sc == svga_rowcount)
  70.700 +                        else if (svga->sc == svga->rowcount)
  70.701                          {
  70.702 -                                linecountff=0;
  70.703 -                                sc=0;
  70.704 +                                svga->linecountff = 0;
  70.705 +                                svga->sc = 0;
  70.706  
  70.707 -                                maback += (svga_rowoffset<<3);
  70.708 -                                if (svga_interlace) maback += (svga_rowoffset<<3);
  70.709 -                                maback&=vrammask;
  70.710 -                                ma=maback;
  70.711 +                                svga->maback += (svga->rowoffset << 3);
  70.712 +                                if (svga->interlace)
  70.713 +                                        svga->maback += (svga->rowoffset << 3);
  70.714 +                                svga->maback &= svga->vrammask;
  70.715 +                                svga->ma = svga->maback;
  70.716                          }
  70.717                          else
  70.718                          {
  70.719 -                                linecountff=0;
  70.720 -                                sc++;
  70.721 -                                sc&=31;
  70.722 -                                ma=maback;
  70.723 +                                svga->linecountff = 0;
  70.724 +                                svga->sc++;
  70.725 +                                svga->sc &= 31;
  70.726 +                                svga->ma = svga->maback;
  70.727                          }
  70.728                  }
  70.729 -                vc++;
  70.730 -                vc&=2047;
  70.731 +                svga->vc++;
  70.732 +                svga->vc &= 2047;
  70.733  
  70.734 -                if (vc==svga_split)
  70.735 +                if (svga->vc == svga->split)
  70.736                  {
  70.737  //                        pclog("VC split\n");
  70.738 -                        ma=maback=0;
  70.739 -                        if (attrregs[0x10]&0x20) scrollcache=0;
  70.740 +                        svga->ma = svga->maback = 0;
  70.741 +                        if (svga->attrregs[0x10] & 0x20) 
  70.742 +                                svga->scrollcache = 0;
  70.743                  }
  70.744 -                if (vc==svga_dispend)
  70.745 +                if (svga->vc == svga->dispend)
  70.746                  {
  70.747  //                        pclog("VC dispend\n");
  70.748 -                        svga_dispon=0;
  70.749 -                        if (crtc[10] & 0x20) cursoron=0;
  70.750 -                        else                 cursoron=cgablink&16;
  70.751 -                        if (!(gdcreg[6]&1) && !(cgablink&15)) fullchange=2;
  70.752 -                        cgablink++;
  70.753 +                        svga->dispon=0;
  70.754 +                        if (svga->crtc[10] & 0x20) svga->cursoron = 0;
  70.755 +                        else                       svga->cursoron = svga->blink & 16;
  70.756 +                        if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15)) 
  70.757 +                                svga->fullchange = 2;
  70.758 +                        svga->blink++;
  70.759  
  70.760 -                        for (x=0;x<2048;x++) if (changedvram[x]) changedvram[x]--;
  70.761 +                        for (x = 0; x < 2048; x++) 
  70.762 +                        {
  70.763 +                                if (svga->changedvram[x]) 
  70.764 +                                        svga->changedvram[x]--;
  70.765 +                        }
  70.766  //                        memset(changedvram,0,2048);
  70.767 -                        if (fullchange) fullchange--;
  70.768 +                        if (svga->fullchange) 
  70.769 +                                svga->fullchange--;
  70.770                  }
  70.771 -                if (vc==svga_vsyncstart)
  70.772 +                if (svga->vc == svga->vsyncstart)
  70.773                  {
  70.774 +                        int wx, wy;
  70.775  //                        pclog("VC vsync  %i %i\n", firstline_draw, lastline_draw);
  70.776 -                        svga_dispon=0;
  70.777 -                        cgastat|=8;
  70.778 -                        /*if (seqregs[1]&8) x=(svga_hdisp*((seqregs[1]&1)?8:9))*2;
  70.779 -                        else              */x = svga_hdisp;//*((seqregs[1]&1)?8:9);
  70.780 +                        svga->dispon=0;
  70.781 +                        svga->cgastat |= 8;
  70.782 +                        x = svga->hdisp;
  70.783  
  70.784 -                        if (bpp == 16 || bpp == 15) x /= 2;
  70.785 -//                        if (bpp == 24)              x /= 3;
  70.786 -                        if (bpp == 32)              x /= 4;
  70.787 -                        if (svga_interlace && !oddeven) lastline++;
  70.788 -                        if (svga_interlace &&  oddeven) firstline--;
  70.789 +                        if (svga->bpp == 16 || svga->bpp == 15) x /= 2;
  70.790 +                        if (svga->bpp == 32)                    x /= 4;
  70.791 +                        if (svga->interlace && !svga->oddeven) svga->lastline++;
  70.792 +                        if (svga->interlace &&  svga->oddeven) svga->firstline--;
  70.793  
  70.794 -                        wx=x;
  70.795 -                        wy=lastline-firstline;
  70.796 +                        wx = x;
  70.797 +                        wy = svga->lastline - svga->firstline;
  70.798  
  70.799  
  70.800 -                        svga_doblit(firstline_draw, lastline_draw + 1);
  70.801 +                        svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga);
  70.802  
  70.803 -                        readflash=0;
  70.804 +                        readflash = 0;
  70.805  
  70.806 -                        firstline=2000;
  70.807 -                        lastline=0;
  70.808 +                        svga->firstline = 2000;
  70.809 +                        svga->lastline = 0;
  70.810                          
  70.811 -                        firstline_draw = 2000;
  70.812 -                        lastline_draw = 0;
  70.813 +                        svga->firstline_draw = 2000;
  70.814 +                        svga->lastline_draw = 0;
  70.815                          
  70.816 -                        oddeven^=1;
  70.817 +                        svga->oddeven ^= 1;
  70.818  
  70.819 -                        changeframecount=(svga_interlace)?3:2;
  70.820 -                        vslines=0;
  70.821 +                        changeframecount = svga->interlace ? 3 : 2;
  70.822 +                        svga->vslines = 0;
  70.823                          
  70.824 -                        if (svga_interlace && oddeven) ma = maback = svga_ma + (svga_rowoffset << 1);
  70.825 -                        else                           ma = maback = svga_ma;
  70.826 -                        ca=(crtc[0xE]<<8)|crtc[0xF];
  70.827 +                        if (svga->interlace && svga->oddeven) svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1);
  70.828 +                        else                                  svga->ma = svga->maback = svga->ma_latch;
  70.829 +                        svga->ca = (svga->crtc[0xe] << 8) | svga->crtc[0xf];
  70.830  
  70.831 -                        ma <<= 2;
  70.832 -                        maback <<= 2;
  70.833 -                        ca <<= 2;
  70.834 +                        svga->ma <<= 2;
  70.835 +                        svga->maback <<= 2;
  70.836 +                        svga->ca <<= 2;
  70.837  
  70.838  
  70.839 -                        video_res_x = wx;
  70.840 -                        video_res_y = wy + 1;
  70.841 -                        
  70.842 -                        if (!(gdcreg[6]&1)) /*Text mode*/
  70.843 +                        svga->video_res_x = wx;
  70.844 +                        svga->video_res_y = wy + 1;
  70.845 +                        pclog("%i %i %i\n", svga->video_res_x, svga->video_res_y, svga->lowres);
  70.846 +                        if (!(svga->gdcreg[6] & 1)) /*Text mode*/
  70.847                          {
  70.848 -                                video_res_x /= (seqregs[1] & 1) ? 8 : 9;
  70.849 -                                video_res_y /= (crtc[9] & 31) + 1;
  70.850 -                                video_bpp = 0;
  70.851 +                                svga->video_res_x /= (svga->seqregs[1] & 1) ? 8 : 9;
  70.852 +                                svga->video_res_y /= (svga->crtc[9] & 31) + 1;
  70.853 +                                svga->video_bpp = 0;
  70.854                          }
  70.855                          else
  70.856                          {
  70.857 -                                if (crtc[9] & 0x80)
  70.858 -                                   video_res_y /= 2;
  70.859 -                                if (!(crtc[0x17] & 1))
  70.860 -                                   video_res_y *= 2;
  70.861 -                                video_res_y /= (crtc[9] & 31) + 1;                                   
  70.862 -                                if ((seqregs[1] & 8) || svga_lowres)
  70.863 -                                   video_res_x /= 2;
  70.864 -                                switch (gdcreg[5]&0x60)
  70.865 +                                if (svga->crtc[9] & 0x80)
  70.866 +                                   svga->video_res_y /= 2;
  70.867 +                                if (!(svga->crtc[0x17] & 1))
  70.868 +                                   svga->video_res_y *= 2;
  70.869 +                                svga->video_res_y /= (svga->crtc[9] & 31) + 1;                                   
  70.870 +                                if (svga->lowres)
  70.871 +                                   svga->video_res_x /= 2;
  70.872 +
  70.873 +                                switch (svga->gdcreg[5] & 0x60)
  70.874                                  {
  70.875 -                                        case 0x00:            video_bpp = 4;   break;
  70.876 -                                        case 0x20:            video_bpp = 2;   break;
  70.877 -                                        case 0x40: case 0x60: video_bpp = bpp; break;
  70.878 +                                        case 0x00:            svga->video_bpp = 4;   break;
  70.879 +                                        case 0x20:            svga->video_bpp = 2;   break;
  70.880 +                                        case 0x40: case 0x60: svga->video_bpp = svga->bpp; break;
  70.881                                  }
  70.882                          }
  70.883 -                        video_bpp = bpp;
  70.884  //                        if (svga_interlace && oddeven) ma=maback=ma+(svga_rowoffset<<2);
  70.885                          
  70.886  //                        pclog("Addr %08X vson %03X vsoff %01X  %02X %02X %02X %i %i\n",ma,svga_vsyncstart,crtc[0x11]&0xF,crtc[0xD],crtc[0xC],crtc[0x33], svga_interlace, oddeven);
  70.887                  }
  70.888 -                if (vc==svga_vtotal)
  70.889 +                if (svga->vc == svga->vtotal)
  70.890                  {
  70.891  //                        pclog("VC vtotal\n");
  70.892  
  70.893  
  70.894  //                        printf("Frame over at line %i %i  %i %i\n",displine,vc,svga_vsyncstart,svga_dispend);
  70.895 -                        vc=0;
  70.896 -                        sc=0;
  70.897 -                        svga_dispon=1;
  70.898 -                        displine=(svga_interlace && oddeven) ? 1 : 0; //(TRIDENT && (crtc[0x1E]&4) && oddeven)?1:0;
  70.899 -                        scrollcache=attrregs[0x13]&7;
  70.900 -                        linecountff=0;
  70.901 +                        svga->vc = 0;
  70.902 +                        svga->sc = 0;
  70.903 +                        svga->dispon = 1;
  70.904 +                        svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0;
  70.905 +                        svga->scrollcache = svga->attrregs[0x13] & 7;
  70.906 +                        svga->linecountff = 0;
  70.907                          
  70.908 -                        svga_hwcursor_on=0;
  70.909 -                        svga_hwcursor_latch = svga_hwcursor;
  70.910 +                        svga->hwcursor_on = 0;
  70.911 +                        svga->hwcursor_latch = svga->hwcursor;
  70.912  //                        pclog("Latch HWcursor addr %08X\n", svga_hwcursor_latch.addr);
  70.913                          
  70.914  //                        pclog("ADDR %08X\n",hwcursor_addr);
  70.915                  }
  70.916 -                if (sc==(crtc[10]&31)) con=1;
  70.917 +                if (svga->sc == (svga->crtc[10] & 31)) 
  70.918 +                        svga->con = 1;
  70.919          }
  70.920  //        printf("2 %i\n",svga_vsyncstart);
  70.921 +//pclog("svga_poll %i %i %i %i %i  %i %i\n", ins, svga->dispofftime, svga->dispontime, svga->vidtime, cyc_total, svga->linepos, svga->vc);
  70.922  }
  70.923  
  70.924 -int svga_init()
  70.925 +int svga_init(svga_t *svga, void *p, int memsize, 
  70.926 +               void (*recalctimings_ex)(struct svga_t *svga),
  70.927 +               uint8_t (*video_in) (uint16_t addr, void *p),
  70.928 +               void    (*video_out)(uint16_t addr, uint8_t val, void *p),
  70.929 +               void (*hwcursor_draw)(struct svga_t *svga, int displine))
  70.930  {
  70.931          int c, d, e;
  70.932 +        
  70.933 +        svga->p = p;
  70.934 +        
  70.935          for (c = 0; c < 256; c++)
  70.936          {
  70.937                  e = c;
  70.938 @@ -592,16 +622,41 @@
  70.939                          e = (e >> 1) | ((e & 1) ? 0x80 : 0);
  70.940                  }
  70.941          }
  70.942 -        readmode = 0;
  70.943 +        svga->readmode = 0;
  70.944 +
  70.945 +        svga->crtc[0] = 63;
  70.946 +        svga->crtc[6] = 255;
  70.947 +        svga->dispontime = 1000 * (1 << TIMER_SHIFT);
  70.948 +        svga->dispofftime = 1000 * (1 << TIMER_SHIFT);        
  70.949 +        svga->bpp = 8;
  70.950 +        svga->vram = malloc(memsize);
  70.951 +        svga->vram_limit = memsize;
  70.952 +        svga->vrammask = memsize - 1;
  70.953 +        svga->changedvram = malloc(/*(memsize >> 10) << 1*/0x800000 >> 10);
  70.954 +        svga->recalctimings_ex = recalctimings_ex;
  70.955 +        svga->video_in  = video_in;
  70.956 +        svga->video_out = video_out;
  70.957 +        svga->hwcursor_draw = hwcursor_draw;
  70.958 +//        _svga_recalctimings(svga);
  70.959 +        
  70.960 +        timer_add(svga_poll, &svga->vidtime, TIMER_ALWAYS_ENABLED, svga);
  70.961 +        vramp = svga->vram;
  70.962          return 0;
  70.963  }
  70.964  
  70.965 +void svga_close(svga_t *svga)
  70.966 +{
  70.967 +        free(svga->changedvram);
  70.968 +        free(svga->vram);
  70.969 +}
  70.970 +
  70.971  #define egacycles 1
  70.972  #define egacycles2 1
  70.973 -void svga_write(uint32_t addr, uint8_t val, void *priv)
  70.974 +void svga_write(uint32_t addr, uint8_t val, void *p)
  70.975  {
  70.976 -        uint8_t vala,valb,valc,vald,wm=writemask;
  70.977 -        int writemask2 = writemask;
  70.978 +        svga_t *svga = (svga_t *)p;
  70.979 +        uint8_t vala, valb, valc, vald, wm = svga->writemask;
  70.980 +        int writemask2 = svga->writemask;
  70.981  
  70.982          egawrites++;
  70.983  
  70.984 @@ -614,11 +669,11 @@
  70.985          {
  70.986                  //if (gdcreg[6]&8) return;
  70.987                  addr &= 0xFFFF;
  70.988 -                addr += svgawbank;
  70.989 +                addr += svga->write_bank;
  70.990          }
  70.991  
  70.992 -        if (!(gdcreg[6]&1)) fullchange=2;
  70.993 -        if (chain4)
  70.994 +        if (!(svga->gdcreg[6] & 1)) svga->fullchange=2;
  70.995 +        if (svga->chain4)
  70.996          {
  70.997                  writemask2=1<<(addr&3);
  70.998                  addr&=~3;
  70.999 @@ -627,155 +682,162 @@
 70.1000          {
 70.1001                  addr<<=2;
 70.1002          }
 70.1003 -        addr&=0x7FFFFF;
 70.1004 -        if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i\n", addr, addr & 1023, addr >> 10, val, writemask2, writemode, chain4);
 70.1005 -        changedvram[addr>>10]=changeframecount;
 70.1006 +        addr &= 0x7fffff;
 70.1007  
 70.1008 -        switch (writemode)
 70.1009 +        if (addr >= svga->vram_limit)
 70.1010 +                return;
 70.1011 +
 70.1012 +        if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i %02X\n", addr, addr & 1023, addr >> 10, val, writemask2, svga->writemode, svga->chain4, svga->gdcreg[8]);
 70.1013 +        svga->changedvram[addr >> 10] = changeframecount;
 70.1014 +
 70.1015 +        switch (svga->writemode)
 70.1016          {
 70.1017                  case 1:
 70.1018 -                if (writemask2&1) vram[addr]=la;
 70.1019 -                if (writemask2&2) vram[addr|0x1]=lb;
 70.1020 -                if (writemask2&4) vram[addr|0x2]=lc;
 70.1021 -                if (writemask2&8) vram[addr|0x3]=ld;
 70.1022 +                if (writemask2 & 1) svga->vram[addr]       = svga->la;
 70.1023 +                if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb;
 70.1024 +                if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc;
 70.1025 +                if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld;
 70.1026                  break;
 70.1027                  case 0:
 70.1028 -                if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val];
 70.1029 -                if (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1])
 70.1030 +                if (svga->gdcreg[3] & 7) 
 70.1031 +                        val = svga_rotate[svga->gdcreg[3] & 7][val];
 70.1032 +                if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1])
 70.1033                  {
 70.1034 -                        if (writemask2&1) vram[addr]=val;
 70.1035 -                        if (writemask2&2) vram[addr|0x1]=val;
 70.1036 -                        if (writemask2&4) vram[addr|0x2]=val;
 70.1037 -                        if (writemask2&8) vram[addr|0x3]=val;
 70.1038 +                        if (writemask2 & 1) svga->vram[addr]       = val;
 70.1039 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = val;
 70.1040 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = val;
 70.1041 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = val;
 70.1042                  }
 70.1043                  else
 70.1044                  {
 70.1045 -                        if (gdcreg[1]&1) vala=(gdcreg[0]&1)?0xFF:0;
 70.1046 -                        else             vala=val;
 70.1047 -                        if (gdcreg[1]&2) valb=(gdcreg[0]&2)?0xFF:0;
 70.1048 -                        else             valb=val;
 70.1049 -                        if (gdcreg[1]&4) valc=(gdcreg[0]&4)?0xFF:0;
 70.1050 -                        else             valc=val;
 70.1051 -                        if (gdcreg[1]&8) vald=(gdcreg[0]&8)?0xFF:0;
 70.1052 -                        else             vald=val;
 70.1053 +                        if (svga->gdcreg[1] & 1) vala = (svga->gdcreg[0] & 1) ? 0xff : 0;
 70.1054 +                        else                     vala = val;
 70.1055 +                        if (svga->gdcreg[1] & 2) valb = (svga->gdcreg[0] & 2) ? 0xff : 0;
 70.1056 +                        else                     valb = val;
 70.1057 +                        if (svga->gdcreg[1] & 4) valc = (svga->gdcreg[0] & 4) ? 0xff : 0;
 70.1058 +                        else                     valc = val;
 70.1059 +                        if (svga->gdcreg[1] & 8) vald = (svga->gdcreg[0] & 8) ? 0xff : 0;
 70.1060 +                        else                     vald = val;
 70.1061  
 70.1062 -                        switch (gdcreg[3]&0x18)
 70.1063 +                        switch (svga->gdcreg[3] & 0x18)
 70.1064                          {
 70.1065                                  case 0: /*Set*/
 70.1066 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
 70.1067 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
 70.1068 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
 70.1069 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
 70.1070 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
 70.1071 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
 70.1072 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
 70.1073 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
 70.1074                                  break;
 70.1075                                  case 8: /*AND*/
 70.1076 -                                if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
 70.1077 -                                if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
 70.1078 -                                if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
 70.1079 -                                if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
 70.1080 +                                if (writemask2 & 1) svga->vram[addr]       = (vala | ~svga->gdcreg[8]) & svga->la;
 70.1081 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb;
 70.1082 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc;
 70.1083 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld;
 70.1084                                  break;
 70.1085                                  case 0x10: /*OR*/
 70.1086 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
 70.1087 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
 70.1088 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
 70.1089 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
 70.1090 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | svga->la;
 70.1091 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb;
 70.1092 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc;
 70.1093 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld;
 70.1094                                  break;
 70.1095                                  case 0x18: /*XOR*/
 70.1096 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
 70.1097 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
 70.1098 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
 70.1099 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
 70.1100 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) ^ svga->la;
 70.1101 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb;
 70.1102 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc;
 70.1103 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld;
 70.1104                                  break;
 70.1105                          }
 70.1106  //                        pclog("- %02X %02X %02X %02X   %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr);
 70.1107                  }
 70.1108                  break;
 70.1109                  case 2:
 70.1110 -                if (!(gdcreg[3]&0x18) && !gdcreg[1])
 70.1111 +                if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1])
 70.1112                  {
 70.1113 -                        if (writemask2&1) vram[addr]=(((val&1)?0xFF:0)&gdcreg[8])|(la&~gdcreg[8]);
 70.1114 -                        if (writemask2&2) vram[addr|0x1]=(((val&2)?0xFF:0)&gdcreg[8])|(lb&~gdcreg[8]);
 70.1115 -                        if (writemask2&4) vram[addr|0x2]=(((val&4)?0xFF:0)&gdcreg[8])|(lc&~gdcreg[8]);
 70.1116 -                        if (writemask2&8) vram[addr|0x3]=(((val&8)?0xFF:0)&gdcreg[8])|(ld&~gdcreg[8]);
 70.1117 +                        if (writemask2 & 1) svga->vram[addr]       = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
 70.1118 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
 70.1119 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
 70.1120 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
 70.1121                  }
 70.1122                  else
 70.1123                  {
 70.1124 -                        vala=((val&1)?0xFF:0);
 70.1125 -                        valb=((val&2)?0xFF:0);
 70.1126 -                        valc=((val&4)?0xFF:0);
 70.1127 -                        vald=((val&8)?0xFF:0);
 70.1128 -                        switch (gdcreg[3]&0x18)
 70.1129 +                        vala = ((val & 1) ? 0xff : 0);
 70.1130 +                        valb = ((val & 2) ? 0xff : 0);
 70.1131 +                        valc = ((val & 4) ? 0xff : 0);
 70.1132 +                        vald = ((val & 8) ? 0xff : 0);
 70.1133 +                        switch (svga->gdcreg[3] & 0x18)
 70.1134                          {
 70.1135                                  case 0: /*Set*/
 70.1136 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
 70.1137 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
 70.1138 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
 70.1139 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
 70.1140 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
 70.1141 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
 70.1142 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
 70.1143 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
 70.1144                                  break;
 70.1145                                  case 8: /*AND*/
 70.1146 -                                if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
 70.1147 -                                if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
 70.1148 -                                if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
 70.1149 -                                if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
 70.1150 +                                if (writemask2 & 1) svga->vram[addr]       = (vala | ~svga->gdcreg[8]) & svga->la;
 70.1151 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb;
 70.1152 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc;
 70.1153 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld;
 70.1154                                  break;
 70.1155                                  case 0x10: /*OR*/
 70.1156 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
 70.1157 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
 70.1158 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
 70.1159 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
 70.1160 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | svga->la;
 70.1161 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb;
 70.1162 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc;
 70.1163 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld;
 70.1164                                  break;
 70.1165                                  case 0x18: /*XOR*/
 70.1166 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
 70.1167 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
 70.1168 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
 70.1169 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
 70.1170 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) ^ svga->la;
 70.1171 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb;
 70.1172 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc;
 70.1173 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld;
 70.1174                                  break;
 70.1175                          }
 70.1176                  }
 70.1177                  break;
 70.1178                  case 3:
 70.1179 -                if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val];
 70.1180 -                wm=gdcreg[8];
 70.1181 -                gdcreg[8]&=val;
 70.1182 +                if (svga->gdcreg[3] & 7) 
 70.1183 +                        val = svga_rotate[svga->gdcreg[3] & 7][val];
 70.1184 +                wm = svga->gdcreg[8];
 70.1185 +                svga->gdcreg[8] &= val;
 70.1186  
 70.1187 -                vala=(gdcreg[0]&1)?0xFF:0;
 70.1188 -                valb=(gdcreg[0]&2)?0xFF:0;
 70.1189 -                valc=(gdcreg[0]&4)?0xFF:0;
 70.1190 -                vald=(gdcreg[0]&8)?0xFF:0;
 70.1191 -                switch (gdcreg[3]&0x18)
 70.1192 +                vala = (svga->gdcreg[0] & 1) ? 0xff : 0;
 70.1193 +                valb = (svga->gdcreg[0] & 2) ? 0xff : 0;
 70.1194 +                valc = (svga->gdcreg[0] & 4) ? 0xff : 0;
 70.1195 +                vald = (svga->gdcreg[0] & 8) ? 0xff : 0;
 70.1196 +                switch (svga->gdcreg[3] & 0x18)
 70.1197                  {
 70.1198                          case 0: /*Set*/
 70.1199 -                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
 70.1200 -                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
 70.1201 -                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
 70.1202 -                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
 70.1203 +                        if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
 70.1204 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
 70.1205 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
 70.1206 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
 70.1207                          break;
 70.1208                          case 8: /*AND*/
 70.1209 -                        if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
 70.1210 -                        if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
 70.1211 -                        if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
 70.1212 -                        if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
 70.1213 +                        if (writemask2 & 1) svga->vram[addr]       = (vala | ~svga->gdcreg[8]) & svga->la;
 70.1214 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb;
 70.1215 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc;
 70.1216 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld;
 70.1217                          break;
 70.1218                          case 0x10: /*OR*/
 70.1219 -                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
 70.1220 -                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
 70.1221 -                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
 70.1222 -                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
 70.1223 +                        if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | svga->la;
 70.1224 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb;
 70.1225 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc;
 70.1226 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld;
 70.1227                          break;
 70.1228                          case 0x18: /*XOR*/
 70.1229 -                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
 70.1230 -                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
 70.1231 -                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
 70.1232 -                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
 70.1233 +                        if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) ^ svga->la;
 70.1234 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb;
 70.1235 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc;
 70.1236 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld;
 70.1237                          break;
 70.1238                  }
 70.1239 -                gdcreg[8]=wm;
 70.1240 +                svga->gdcreg[8] = wm;
 70.1241                  break;
 70.1242          }
 70.1243  }
 70.1244  
 70.1245 -uint8_t svga_read(uint32_t addr, void *priv)
 70.1246 +uint8_t svga_read(uint32_t addr, void *p)
 70.1247  {
 70.1248 -        uint8_t temp,temp2,temp3,temp4;
 70.1249 +        svga_t *svga = (svga_t *)p;
 70.1250 +        uint8_t temp, temp2, temp3, temp4;
 70.1251          
 70.1252          cycles -= video_timing_b;
 70.1253          cycles_lost += video_timing_b;
 70.1254 @@ -786,52 +848,53 @@
 70.1255          else
 70.1256          {
 70.1257                  addr &= 0xFFFF;
 70.1258 -                addr += svgarbank;
 70.1259 +                addr += svga->read_bank;
 70.1260          }
 70.1261 -//        pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], readmode);
 70.1262 -//        pclog("%i\n", readmode);
 70.1263 -        if (chain4) 
 70.1264 +//        pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode);
 70.1265 +//        pclog("%i\n", svga->readmode);
 70.1266 +        if (svga->chain4) 
 70.1267          { 
 70.1268                  addr &= 0x7fffff;
 70.1269 -                if (addr >= svga_vram_limit)
 70.1270 +                if (addr >= svga->vram_limit)
 70.1271                     return 0xff;
 70.1272 -                return vram[addr];
 70.1273 +                return svga->vram[addr];
 70.1274          }
 70.1275          else        addr<<=2;
 70.1276          
 70.1277          addr &= 0x7fffff;
 70.1278          
 70.1279 -        if (addr >= svga_vram_limit)
 70.1280 +        if (addr >= svga->vram_limit)
 70.1281             return 0xff;
 70.1282             
 70.1283 -        la=vram[addr];
 70.1284 -        lb=vram[addr|0x1];
 70.1285 -        lc=vram[addr|0x2];
 70.1286 -        ld=vram[addr|0x3];
 70.1287 -        if (readmode)
 70.1288 +        svga->la = svga->vram[addr];
 70.1289 +        svga->lb = svga->vram[addr | 0x1];
 70.1290 +        svga->lc = svga->vram[addr | 0x2];
 70.1291 +        svga->ld = svga->vram[addr | 0x3];
 70.1292 +        if (svga->readmode)
 70.1293          {
 70.1294 -                temp= (colournocare&1) ?0xFF:0;
 70.1295 -                temp&=la;
 70.1296 -                temp^=(colourcompare&1)?0xFF:0;
 70.1297 -                temp2= (colournocare&2) ?0xFF:0;
 70.1298 -                temp2&=lb;
 70.1299 -                temp2^=(colourcompare&2)?0xFF:0;
 70.1300 -                temp3= (colournocare&4) ?0xFF:0;
 70.1301 -                temp3&=lc;
 70.1302 -                temp3^=(colourcompare&4)?0xFF:0;
 70.1303 -                temp4= (colournocare&8) ?0xFF:0;
 70.1304 -                temp4&=ld;
 70.1305 -                temp4^=(colourcompare&8)?0xFF:0;
 70.1306 -                return ~(temp|temp2|temp3|temp4);
 70.1307 +                temp   = (svga->colournocare & 1)  ? 0xff : 0;
 70.1308 +                temp  &= svga->la;
 70.1309 +                temp  ^= (svga->colourcompare & 1) ? 0xff : 0;
 70.1310 +                temp2  = (svga->colournocare & 2)  ? 0xff : 0;
 70.1311 +                temp2 &= svga->lb;
 70.1312 +                temp2 ^= (svga->colourcompare & 2) ? 0xff : 0;
 70.1313 +                temp3  = (svga->colournocare & 4)  ? 0xff : 0;
 70.1314 +                temp3 &= svga->lc;
 70.1315 +                temp3 ^= (svga->colourcompare & 4) ? 0xff : 0;
 70.1316 +                temp4  = (svga->colournocare & 8)  ? 0xff : 0;
 70.1317 +                temp4 &= svga->ld;
 70.1318 +                temp4 ^= (svga->colourcompare & 8) ? 0xff : 0;
 70.1319 +                return ~(temp | temp2 | temp3 | temp4);
 70.1320          }
 70.1321 -//pclog("Read %02X %04X %04X\n",vram[addr|readplane],addr,readplane);
 70.1322 -        return vram[addr|readplane];
 70.1323 +//pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane);
 70.1324 +        return svga->vram[addr | svga->readplane];
 70.1325  }
 70.1326  
 70.1327 -void svga_write_linear(uint32_t addr, uint8_t val, void *priv)
 70.1328 +void svga_write_linear(uint32_t addr, uint8_t val, void *p)
 70.1329  {
 70.1330 -        uint8_t vala,valb,valc,vald,wm=writemask;
 70.1331 -        int writemask2 = writemask;
 70.1332 +        svga_t *svga = (svga_t *)p;
 70.1333 +        uint8_t vala, valb, valc, vald, wm = svga->writemask;
 70.1334 +        int writemask2 = svga->writemask;
 70.1335  
 70.1336          cycles -= video_timing_b;
 70.1337          cycles_lost += video_timing_b;
 70.1338 @@ -839,8 +902,9 @@
 70.1339          egawrites++;
 70.1340          
 70.1341          if (svga_output) pclog("Write LFB %08X %02X ", addr, val);
 70.1342 -        if (!(gdcreg[6]&1)) fullchange=2;
 70.1343 -        if (chain4)
 70.1344 +        if (!(svga->gdcreg[6] & 1)) 
 70.1345 +                svga->fullchange = 2;
 70.1346 +        if (svga->chain4)
 70.1347          {
 70.1348                  writemask2=1<<(addr&3);
 70.1349                  addr&=~3;
 70.1350 @@ -850,201 +914,206 @@
 70.1351                  addr<<=2;
 70.1352          }
 70.1353          addr &= 0x7fffff;
 70.1354 +        if (addr >= svga->vram_limit)
 70.1355 +                return;
 70.1356          if (svga_output) pclog("%08X\n", addr);
 70.1357 -        changedvram[addr>>10]=changeframecount;
 70.1358 +        svga->changedvram[addr>>10]=changeframecount;
 70.1359          
 70.1360 -        switch (writemode)
 70.1361 +        switch (svga->writemode)
 70.1362          {
 70.1363                  case 1:
 70.1364 -                if (writemask2&1) vram[addr]=la;
 70.1365 -                if (writemask2&2) vram[addr|0x1]=lb;
 70.1366 -                if (writemask2&4) vram[addr|0x2]=lc;
 70.1367 -                if (writemask2&8) vram[addr|0x3]=ld;
 70.1368 +                if (writemask2 & 1) svga->vram[addr]       = svga->la;
 70.1369 +                if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb;
 70.1370 +                if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc;
 70.1371 +                if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld;
 70.1372                  break;
 70.1373                  case 0:
 70.1374 -                if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val];
 70.1375 -                if (gdcreg[8]==0xFF && !(gdcreg[3]&0x18) && !gdcreg[1])
 70.1376 +                if (svga->gdcreg[3] & 7) 
 70.1377 +                        val = svga_rotate[svga->gdcreg[3] & 7][val];
 70.1378 +                if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1])
 70.1379                  {
 70.1380 -                        if (writemask2&1) vram[addr]=val;
 70.1381 -                        if (writemask2&2) vram[addr|0x1]=val;
 70.1382 -                        if (writemask2&4) vram[addr|0x2]=val;
 70.1383 -                        if (writemask2&8) vram[addr|0x3]=val;
 70.1384 +                        if (writemask2 & 1) svga->vram[addr]       = val;
 70.1385 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = val;
 70.1386 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = val;
 70.1387 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = val;
 70.1388                  }
 70.1389                  else
 70.1390                  {
 70.1391 -                        if (gdcreg[1]&1) vala=(gdcreg[0]&1)?0xFF:0;
 70.1392 -                        else             vala=val;
 70.1393 -                        if (gdcreg[1]&2) valb=(gdcreg[0]&2)?0xFF:0;
 70.1394 -                        else             valb=val;
 70.1395 -                        if (gdcreg[1]&4) valc=(gdcreg[0]&4)?0xFF:0;
 70.1396 -                        else             valc=val;
 70.1397 -                        if (gdcreg[1]&8) vald=(gdcreg[0]&8)?0xFF:0;
 70.1398 -                        else             vald=val;
 70.1399 +                        if (svga->gdcreg[1] & 1) vala = (svga->gdcreg[0] & 1) ? 0xff : 0;
 70.1400 +                        else                     vala = val;
 70.1401 +                        if (svga->gdcreg[1] & 2) valb = (svga->gdcreg[0] & 2) ? 0xff : 0;
 70.1402 +                        else                     valb = val;
 70.1403 +                        if (svga->gdcreg[1] & 4) valc = (svga->gdcreg[0] & 4) ? 0xff : 0;
 70.1404 +                        else                     valc = val;
 70.1405 +                        if (svga->gdcreg[1] & 8) vald = (svga->gdcreg[0] & 8) ? 0xff : 0;
 70.1406 +                        else                     vald = val;
 70.1407  
 70.1408 -                        switch (gdcreg[3]&0x18)
 70.1409 +                        switch (svga->gdcreg[3] & 0x18)
 70.1410                          {
 70.1411                                  case 0: /*Set*/
 70.1412 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
 70.1413 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
 70.1414 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
 70.1415 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
 70.1416 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
 70.1417 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
 70.1418 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
 70.1419 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
 70.1420                                  break;
 70.1421                                  case 8: /*AND*/
 70.1422 -                                if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
 70.1423 -                                if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
 70.1424 -                                if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
 70.1425 -                                if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
 70.1426 +                                if (writemask2 & 1) svga->vram[addr]       = (vala | ~svga->gdcreg[8]) & svga->la;
 70.1427 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb;
 70.1428 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc;
 70.1429 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld;
 70.1430                                  break;
 70.1431                                  case 0x10: /*OR*/
 70.1432 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
 70.1433 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
 70.1434 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
 70.1435 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
 70.1436 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | svga->la;
 70.1437 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb;
 70.1438 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc;
 70.1439 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld;
 70.1440                                  break;
 70.1441                                  case 0x18: /*XOR*/
 70.1442 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
 70.1443 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
 70.1444 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
 70.1445 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
 70.1446 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) ^ svga->la;
 70.1447 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb;
 70.1448 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc;
 70.1449 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld;
 70.1450                                  break;
 70.1451                          }
 70.1452  //                        pclog("- %02X %02X %02X %02X   %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr);
 70.1453                  }
 70.1454                  break;
 70.1455                  case 2:
 70.1456 -                if (!(gdcreg[3]&0x18) && !gdcreg[1])
 70.1457 +                if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1])
 70.1458                  {
 70.1459 -                        if (writemask2&1) vram[addr]=(((val&1)?0xFF:0)&gdcreg[8])|(la&~gdcreg[8]);
 70.1460 -                        if (writemask2&2) vram[addr|0x1]=(((val&2)?0xFF:0)&gdcreg[8])|(lb&~gdcreg[8]);
 70.1461 -                        if (writemask2&4) vram[addr|0x2]=(((val&4)?0xFF:0)&gdcreg[8])|(lc&~gdcreg[8]);
 70.1462 -                        if (writemask2&8) vram[addr|0x3]=(((val&8)?0xFF:0)&gdcreg[8])|(ld&~gdcreg[8]);
 70.1463 +                        if (writemask2 & 1) svga->vram[addr]       = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
 70.1464 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
 70.1465 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
 70.1466 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
 70.1467                  }
 70.1468                  else
 70.1469                  {
 70.1470 -                        vala=((val&1)?0xFF:0);
 70.1471 -                        valb=((val&2)?0xFF:0);
 70.1472 -                        valc=((val&4)?0xFF:0);
 70.1473 -                        vald=((val&8)?0xFF:0);
 70.1474 -                        switch (gdcreg[3]&0x18)
 70.1475 +                        vala = ((val & 1) ? 0xff : 0);
 70.1476 +                        valb = ((val & 2) ? 0xff : 0);
 70.1477 +                        valc = ((val & 4) ? 0xff : 0);
 70.1478 +                        vald = ((val & 8) ? 0xff : 0);
 70.1479 +                        switch (svga->gdcreg[3] & 0x18)
 70.1480                          {
 70.1481                                  case 0: /*Set*/
 70.1482 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
 70.1483 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
 70.1484 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
 70.1485 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
 70.1486 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
 70.1487 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
 70.1488 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
 70.1489 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
 70.1490                                  break;
 70.1491                                  case 8: /*AND*/
 70.1492 -                                if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
 70.1493 -                                if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
 70.1494 -                                if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
 70.1495 -                                if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
 70.1496 +                                if (writemask2 & 1) svga->vram[addr]       = (vala | ~svga->gdcreg[8]) & svga->la;
 70.1497 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb;
 70.1498 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc;
 70.1499 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld;
 70.1500                                  break;
 70.1501                                  case 0x10: /*OR*/
 70.1502 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
 70.1503 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
 70.1504 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
 70.1505 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
 70.1506 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | svga->la;
 70.1507 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb;
 70.1508 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc;
 70.1509 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld;
 70.1510                                  break;
 70.1511                                  case 0x18: /*XOR*/
 70.1512 -                                if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
 70.1513 -                                if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
 70.1514 -                                if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
 70.1515 -                                if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
 70.1516 +                                if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) ^ svga->la;
 70.1517 +                                if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb;
 70.1518 +                                if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc;
 70.1519 +                                if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld;
 70.1520                                  break;
 70.1521                          }
 70.1522                  }
 70.1523                  break;
 70.1524                  case 3:
 70.1525 -                if (gdcreg[3]&7) val=svga_rotate[gdcreg[3]&7][val];
 70.1526 -                wm=gdcreg[8];
 70.1527 -                gdcreg[8]&=val;
 70.1528 +                if (svga->gdcreg[3] & 7) 
 70.1529 +                        val = svga_rotate[svga->gdcreg[3] & 7][val];
 70.1530 +                wm = svga->gdcreg[8];
 70.1531 +                svga->gdcreg[8] &= val;
 70.1532  
 70.1533 -                vala=(gdcreg[0]&1)?0xFF:0;
 70.1534 -                valb=(gdcreg[0]&2)?0xFF:0;
 70.1535 -                valc=(gdcreg[0]&4)?0xFF:0;
 70.1536 -                vald=(gdcreg[0]&8)?0xFF:0;
 70.1537 -                switch (gdcreg[3]&0x18)
 70.1538 +                vala = (svga->gdcreg[0] & 1) ? 0xff : 0;
 70.1539 +                valb = (svga->gdcreg[0] & 2) ? 0xff : 0;
 70.1540 +                valc = (svga->gdcreg[0] & 4) ? 0xff : 0;
 70.1541 +                vald = (svga->gdcreg[0] & 8) ? 0xff : 0;
 70.1542 +                switch (svga->gdcreg[3] & 0x18)
 70.1543                  {
 70.1544                          case 0: /*Set*/
 70.1545 -                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])|(la&~gdcreg[8]);
 70.1546 -                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|(lb&~gdcreg[8]);
 70.1547 -                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|(lc&~gdcreg[8]);
 70.1548 -                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|(ld&~gdcreg[8]);
 70.1549 +                        if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]);
 70.1550 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]);
 70.1551 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]);
 70.1552 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]);
 70.1553                          break;
 70.1554                          case 8: /*AND*/
 70.1555 -                        if (writemask2&1) vram[addr]=(vala|~gdcreg[8])&la;
 70.1556 -                        if (writemask2&2) vram[addr|0x1]=(valb|~gdcreg[8])&lb;
 70.1557 -                        if (writemask2&4) vram[addr|0x2]=(valc|~gdcreg[8])&lc;
 70.1558 -                        if (writemask2&8) vram[addr|0x3]=(vald|~gdcreg[8])&ld;
 70.1559 +                        if (writemask2 & 1) svga->vram[addr]       = (vala | ~svga->gdcreg[8]) & svga->la;
 70.1560 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb;
 70.1561 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc;
 70.1562 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld;
 70.1563                          break;
 70.1564                          case 0x10: /*OR*/
 70.1565 -                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])|la;
 70.1566 -                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])|lb;
 70.1567 -                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])|lc;
 70.1568 -                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])|ld;
 70.1569 +                        if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) | svga->la;
 70.1570 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb;
 70.1571 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc;
 70.1572 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld;
 70.1573                          break;
 70.1574                          case 0x18: /*XOR*/
 70.1575 -                        if (writemask2&1) vram[addr]=(vala&gdcreg[8])^la;
 70.1576 -                        if (writemask2&2) vram[addr|0x1]=(valb&gdcreg[8])^lb;
 70.1577 -                        if (writemask2&4) vram[addr|0x2]=(valc&gdcreg[8])^lc;
 70.1578 -                        if (writemask2&8) vram[addr|0x3]=(vald&gdcreg[8])^ld;
 70.1579 +                        if (writemask2 & 1) svga->vram[addr]       = (vala & svga->gdcreg[8]) ^ svga->la;
 70.1580 +                        if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb;
 70.1581 +                        if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc;
 70.1582 +                        if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld;
 70.1583                          break;
 70.1584                  }
 70.1585 -                gdcreg[8]=wm;
 70.1586 +                svga->gdcreg[8] = wm;
 70.1587                  break;
 70.1588          }
 70.1589  }
 70.1590  
 70.1591 -uint8_t svga_read_linear(uint32_t addr, void *priv)
 70.1592 +uint8_t svga_read_linear(uint32_t addr, void *p)
 70.1593  {
 70.1594 -        uint8_t temp,temp2,temp3,temp4;
 70.1595 +        svga_t *svga = (svga_t *)p;
 70.1596 +        uint8_t temp, temp2, temp3, temp4;
 70.1597    
 70.1598          cycles -= video_timing_b;
 70.1599          cycles_lost += video_timing_b;
 70.1600  
 70.1601          egareads++;
 70.1602          
 70.1603 -        if (chain4) 
 70.1604 +        if (svga->chain4) 
 70.1605          { 
 70.1606                  addr &= 0x7fffff;
 70.1607 -                if (addr >= svga_vram_limit)
 70.1608 +                if (addr >= svga->vram_limit)
 70.1609                     return 0xff;
 70.1610 -                return vram[addr & 0x7fffff]; 
 70.1611 +                return svga->vram[addr & 0x7fffff]; 
 70.1612          }
 70.1613          else        addr<<=2;
 70.1614  
 70.1615          addr &= 0x7fffff;
 70.1616          
 70.1617 -        if (addr >= svga_vram_limit)
 70.1618 +        if (addr >= svga->vram_limit)
 70.1619             return 0xff;
 70.1620  
 70.1621 -        la=vram[addr];
 70.1622 -        lb=vram[addr|0x1];
 70.1623 -        lc=vram[addr|0x2];
 70.1624 -        ld=vram[addr|0x3];
 70.1625 -        if (readmode)
 70.1626 +        svga->la = svga->vram[addr];
 70.1627 +        svga->lb = svga->vram[addr | 0x1];
 70.1628 +        svga->lc = svga->vram[addr | 0x2];
 70.1629 +        svga->ld = svga->vram[addr | 0x3];
 70.1630 +        if (svga->readmode)
 70.1631          {
 70.1632 -                temp= (colournocare&1) ?0xFF:0;
 70.1633 -                temp&=la;
 70.1634 -                temp^=(colourcompare&1)?0xFF:0;
 70.1635 -                temp2= (colournocare&2) ?0xFF:0;
 70.1636 -                temp2&=lb;
 70.1637 -                temp2^=(colourcompare&2)?0xFF:0;
 70.1638 -                temp3= (colournocare&4) ?0xFF:0;
 70.1639 -                temp3&=lc;
 70.1640 -                temp3^=(colourcompare&4)?0xFF:0;
 70.1641 -                temp4= (colournocare&8) ?0xFF:0;
 70.1642 -                temp4&=ld;
 70.1643 -                temp4^=(colourcompare&8)?0xFF:0;
 70.1644 -                return ~(temp|temp2|temp3|temp4);
 70.1645 +                temp   = (svga->colournocare & 1)  ? 0xff : 0;
 70.1646 +                temp  &= svga->la;
 70.1647 +                temp  ^= (svga->colourcompare & 1) ? 0xff : 0;
 70.1648 +                temp2  = (svga->colournocare & 2)  ? 0xff : 0;
 70.1649 +                temp2 &= svga->lb;
 70.1650 +                temp2 ^= (svga->colourcompare & 2) ? 0xff : 0;
 70.1651 +                temp3  = (svga->colournocare & 4)  ? 0xff : 0;
 70.1652 +                temp3 &= svga->lc;
 70.1653 +                temp3 ^= (svga->colourcompare & 4) ? 0xff : 0;
 70.1654 +                temp4  = (svga->colournocare & 8)  ? 0xff : 0;
 70.1655 +                temp4 &= svga->ld;
 70.1656 +                temp4 ^= (svga->colourcompare & 8) ? 0xff : 0;
 70.1657 +                return ~(temp | temp2 | temp3 | temp4);
 70.1658          }
 70.1659 -//printf("Read %02X %04X %04X\n",vram[addr|readplane],addr,readplane);
 70.1660 -        return vram[addr|readplane];
 70.1661 +//printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane);
 70.1662 +        return svga->vram[addr | svga->readplane];
 70.1663  }
 70.1664  
 70.1665 -void svga_doblit(int y1, int y2)
 70.1666 +void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
 70.1667  {
 70.1668 -        frames++;
 70.1669 +        svga->frames++;
 70.1670  //        pclog("doblit %i %i\n", y1, y2);
 70.1671          if (y1 > y2) 
 70.1672          {
 70.1673 @@ -1060,16 +1129,8 @@
 70.1674                  ysize=wy+1;
 70.1675                  if (xsize<64) xsize=656;
 70.1676                  if (ysize<32) ysize=200;
 70.1677 -/*                if (bpp > 8)
 70.1678 -                {
 70.1679 -                        if (vres) updatewindowsize(xsize<<1,ysize<<1);
 70.1680 -                        else      updatewindowsize(xsize<<1,ysize);
 70.1681 -                }
 70.1682 -                else
 70.1683 -                {*/
 70.1684 -                        if (vres) updatewindowsize(xsize,ysize<<1);
 70.1685 -                        else      updatewindowsize(xsize,ysize);
 70.1686 -//                }
 70.1687 +
 70.1688 +                updatewindowsize(xsize,ysize);
 70.1689          }
 70.1690          if (vid_resize)
 70.1691          {
 70.1692 @@ -1082,12 +1143,15 @@
 70.1693          
 70.1694  }
 70.1695  
 70.1696 -void svga_writew(uint32_t addr, uint16_t val, void *priv)
 70.1697 +void svga_writew(uint32_t addr, uint16_t val, void *p)
 70.1698  {
 70.1699 -        if (!svga_fast)
 70.1700 +        svga_t *svga = (svga_t *)p;
 70.1701 +        if (!svga)
 70.1702 +                exit(-1);
 70.1703 +        if (!svga->fast)
 70.1704          {
 70.1705 -                svga_write(addr, val, priv);
 70.1706 -                svga_write(addr + 1, val >> 8, priv);
 70.1707 +                svga_write(addr, val, p);
 70.1708 +                svga_write(addr + 1, val >> 8, p);
 70.1709                  return;
 70.1710          }
 70.1711          
 70.1712 @@ -1097,21 +1161,25 @@
 70.1713          cycles_lost += video_timing_w;
 70.1714  
 70.1715          if (svga_output) pclog("Writew %05X ", addr);
 70.1716 -        addr = (addr & 0xffff) + svgawbank;
 70.1717 +        addr = (addr & 0xffff) + svga->write_bank;
 70.1718          addr &= 0x7FFFFF;        
 70.1719 +        if (addr >= svga->vram_limit)
 70.1720 +                return;
 70.1721          if (svga_output) pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val);
 70.1722 -        changedvram[addr >> 10] = changeframecount;
 70.1723 -        *(uint16_t *)&vram[addr] = val;
 70.1724 +        svga->changedvram[addr >> 10] = changeframecount;
 70.1725 +        *(uint16_t *)&svga->vram[addr] = val;
 70.1726  }
 70.1727  
 70.1728 -void svga_writel(uint32_t addr, uint32_t val, void *priv)
 70.1729 +void svga_writel(uint32_t addr, uint32_t val, void *p)
 70.1730  {
 70.1731 -        if (!svga_fast)
 70.1732 +        svga_t *svga = (svga_t *)p;
 70.1733 +        
 70.1734 +        if (!svga->fast)
 70.1735          {
 70.1736 -                svga_write(addr, val, priv);
 70.1737 -                svga_write(addr + 1, val >> 8, priv);
 70.1738 -                svga_write(addr + 2, val >> 16, priv);
 70.1739 -                svga_write(addr + 3, val >> 24, priv);
 70.1740 +                svga_write(addr, val, p);
 70.1741 +                svga_write(addr + 1, val >> 8, p);
 70.1742 +                svga_write(addr + 2, val >> 16, p);
 70.1743 +                svga_write(addr + 3, val >> 24, p);
 70.1744                  return;
 70.1745          }
 70.1746          
 70.1747 @@ -1121,18 +1189,22 @@
 70.1748          cycles_lost += video_timing_l;
 70.1749  
 70.1750          if (svga_output) pclog("Writel %05X ", addr);
 70.1751 -        addr = (addr & 0xffff) + svgawbank;
 70.1752 +        addr = (addr & 0xffff) + svga->write_bank;
 70.1753          addr &= 0x7FFFFF;
 70.1754 +        if (addr >= svga->vram_limit)
 70.1755 +                return;
 70.1756          if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val);
 70.1757          
 70.1758 -        changedvram[addr >> 10] = changeframecount;
 70.1759 -        *(uint32_t *)&vram[addr] = val;
 70.1760 +        svga->changedvram[addr >> 10] = changeframecount;
 70.1761 +        *(uint32_t *)&svga->vram[addr] = val;
 70.1762  }
 70.1763  
 70.1764 -uint16_t svga_readw(uint32_t addr, void *priv)
 70.1765 +uint16_t svga_readw(uint32_t addr, void *p)
 70.1766  {
 70.1767 -        if (!svga_fast)
 70.1768 -           return svga_read(addr, priv) | (svga_read(addr + 1, priv) << 8);
 70.1769 +        svga_t *svga = (svga_t *)p;
 70.1770 +        
 70.1771 +        if (!svga->fast)
 70.1772 +           return svga_read(addr, p) | (svga_read(addr + 1, p) << 8);
 70.1773          
 70.1774          egareads += 2;
 70.1775  
 70.1776 @@ -1140,18 +1212,20 @@
 70.1777          cycles_lost += video_timing_w;
 70.1778  
 70.1779  //        pclog("Readw %05X ", addr);
 70.1780 -        addr = (addr & 0xffff) + svgarbank;
 70.1781 +        addr = (addr & 0xffff) + svga->read_bank;
 70.1782          addr &= 0x7FFFFF;
 70.1783  //        pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]);
 70.1784 -        if (addr >= svga_vram_limit) return 0xffff;
 70.1785 +        if (addr >= svga->vram_limit) return 0xffff;
 70.1786          
 70.1787 -        return *(uint16_t *)&vram[addr];
 70.1788 +        return *(uint16_t *)&svga->vram[addr];
 70.1789  }
 70.1790  
 70.1791 -uint32_t svga_readl(uint32_t addr, void *priv)
 70.1792 +uint32_t svga_readl(uint32_t addr, void *p)
 70.1793  {
 70.1794 -        if (!svga_fast)
 70.1795 -           return svga_read(addr, priv) | (svga_read(addr + 1, priv) << 8) | (svga_read(addr + 2, priv) << 16) | (svga_read(addr + 3, priv) << 24);
 70.1796 +        svga_t *svga = (svga_t *)p;
 70.1797 +        
 70.1798 +        if (!svga->fast)
 70.1799 +           return svga_read(addr, p) | (svga_read(addr + 1, p) << 8) | (svga_read(addr + 2, p) << 16) | (svga_read(addr + 3, p) << 24);
 70.1800          
 70.1801          egareads += 4;
 70.1802  
 70.1803 @@ -1159,20 +1233,22 @@
 70.1804          cycles_lost += video_timing_l;
 70.1805  
 70.1806  //        pclog("Readl %05X ", addr);
 70.1807 -        addr = (addr & 0xffff) + svgarbank;
 70.1808 +        addr = (addr & 0xffff) + svga->read_bank;
 70.1809          addr &= 0x7FFFFF;
 70.1810  //        pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]);
 70.1811 -        if (addr >= svga_vram_limit) return 0xffffffff;
 70.1812 +        if (addr >= svga->vram_limit) return 0xffffffff;
 70.1813          
 70.1814 -        return *(uint32_t *)&vram[addr];
 70.1815 +        return *(uint32_t *)&svga->vram[addr];
 70.1816  }
 70.1817  
 70.1818 -void svga_writew_linear(uint32_t addr, uint16_t val, void *priv)
 70.1819 +void svga_writew_linear(uint32_t addr, uint16_t val, void *p)
 70.1820  {
 70.1821 -        if (!svga_fast)
 70.1822 +        svga_t *svga = (svga_t *)p;
 70.1823 +        
 70.1824 +        if (!svga->fast)
 70.1825          {
 70.1826 -                svga_write_linear(addr, val, priv);
 70.1827 -                svga_write_linear(addr + 1, val >> 8, priv);
 70.1828 +                svga_write_linear(addr, val, p);
 70.1829 +                svga_write_linear(addr + 1, val >> 8, p);
 70.1830                  return;
 70.1831          }
 70.1832          
 70.1833 @@ -1183,18 +1259,22 @@
 70.1834  
 70.1835  	if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val);
 70.1836          addr &= 0x7FFFFF;
 70.1837 -        changedvram[addr >> 10] = changeframecount;
 70.1838 -        *(uint16_t *)&vram[addr] = val;
 70.1839 +        if (addr >= svga->vram_limit)
 70.1840 +                return;
 70.1841 +        svga->changedvram[addr >> 10] = changeframecount;
 70.1842 +        *(uint16_t *)&svga->vram[addr] = val;
 70.1843  }
 70.1844  
 70.1845 -void svga_writel_linear(uint32_t addr, uint32_t val, void *priv)
 70.1846 +void svga_writel_linear(uint32_t addr, uint32_t val, void *p)
 70.1847  {
 70.1848 -        if (!svga_fast)
 70.1849 +        svga_t *svga = (svga_t *)p;
 70.1850 +        
 70.1851 +        if (!svga->fast)
 70.1852          {
 70.1853 -                svga_write_linear(addr, val, priv);
 70.1854 -                svga_write_linear(addr + 1, val >> 8, priv);
 70.1855 -                svga_write_linear(addr + 2, val >> 16, priv);
 70.1856 -                svga_write_linear(addr + 3, val >> 24, priv);
 70.1857 +                svga_write_linear(addr, val, p);
 70.1858 +                svga_write_linear(addr + 1, val >> 8, p);
 70.1859 +                svga_write_linear(addr + 2, val >> 16, p);
 70.1860 +                svga_write_linear(addr + 3, val >> 24, p);
 70.1861                  return;
 70.1862          }
 70.1863          
 70.1864 @@ -1205,14 +1285,18 @@
 70.1865  
 70.1866  	if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val);
 70.1867          addr &= 0x7fffff;
 70.1868 -        changedvram[addr >> 10] = changeframecount;
 70.1869 -        *(uint32_t *)&vram[addr] = val;
 70.1870 +        if (addr >= svga->vram_limit)
 70.1871 +                return;
 70.1872 +        svga->changedvram[addr >> 10] = changeframecount;
 70.1873 +        *(uint32_t *)&svga->vram[addr] = val;
 70.1874  }
 70.1875  
 70.1876 -uint16_t svga_readw_linear(uint32_t addr, void *priv)
 70.1877 +uint16_t svga_readw_linear(uint32_t addr, void *p)
 70.1878  {
 70.1879 -        if (!svga_fast)
 70.1880 -           return svga_read_linear(addr, priv) | (svga_read_linear(addr + 1, priv) << 8);
 70.1881 +        svga_t *svga = (svga_t *)p;
 70.1882 +        
 70.1883 +        if (!svga->fast)
 70.1884 +           return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8);
 70.1885          
 70.1886          egareads += 2;
 70.1887  
 70.1888 @@ -1220,15 +1304,17 @@
 70.1889          cycles_lost += video_timing_w;
 70.1890  
 70.1891          addr &= 0x7FFFFF;
 70.1892 -        if (addr >= svga_vram_limit) return 0xffff;
 70.1893 +        if (addr >= svga->vram_limit) return 0xffff;
 70.1894          
 70.1895 -        return *(uint16_t *)&vram[addr];
 70.1896 +        return *(uint16_t *)&svga->vram[addr];
 70.1897  }
 70.1898  
 70.1899 -uint32_t svga_readl_linear(uint32_t addr, void *priv)
 70.1900 +uint32_t svga_readl_linear(uint32_t addr, void *p)
 70.1901  {
 70.1902 -        if (!svga_fast)
 70.1903 -           return svga_read_linear(addr, priv) | (svga_read_linear(addr + 1, priv) << 8) | (svga_read_linear(addr + 2, priv) << 16) | (svga_read_linear(addr + 3, priv) << 24);
 70.1904 +        svga_t *svga = (svga_t *)p;
 70.1905 +        
 70.1906 +        if (!svga->fast)
 70.1907 +           return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8) | (svga_read_linear(addr + 2, p) << 16) | (svga_read_linear(addr + 3, p) << 24);
 70.1908          
 70.1909          egareads += 4;
 70.1910  
 70.1911 @@ -1236,7 +1322,37 @@
 70.1912          cycles_lost += video_timing_l;
 70.1913  
 70.1914          addr &= 0x7FFFFF;
 70.1915 -        if (addr >= svga_vram_limit) return 0xffffffff;
 70.1916 +        if (addr >= svga->vram_limit) return 0xffffffff;
 70.1917  
 70.1918 -        return *(uint32_t *)&vram[addr];
 70.1919 +        return *(uint32_t *)&svga->vram[addr];
 70.1920  }
 70.1921 +
 70.1922 +
 70.1923 +int svga_add_status_info(char *s, int max_len, void *p)
 70.1924 +{
 70.1925 +        svga_t *svga = (svga_t *)p;
 70.1926 +        char temps[128];
 70.1927 +        int cur_len = max_len;
 70.1928 +        int len;
 70.1929 +        
 70.1930 +        if (svga->chain4) len = snprintf(s, max_len, "SVGA chained (possibly mode 13h)\n");
 70.1931 +        else              len = snprintf(s, max_len, "SVGA unchained (possibly mode-X)\n");
 70.1932 +        if (len < 0) return;
 70.1933 +        cur_len -= len;
 70.1934 +
 70.1935 +        if (!svga->video_bpp) strcpy(temps, "SVGA in text mode\n");
 70.1936 +        else                  sprintf(temps, "SVGA colour depth : %i bpp\n", svga->video_bpp);
 70.1937 +        strncat(s, temps, cur_len);
 70.1938 +        cur_len -= strlen(temps);
 70.1939 +        
 70.1940 +        sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y);
 70.1941 +        strncat(s, temps, cur_len);
 70.1942 +        cur_len -= strlen(temps);
 70.1943 +        
 70.1944 +        sprintf(temps, "SVGA refresh rate : %i Hz\n\n", svga->frames);
 70.1945 +        svga->frames = 0;
 70.1946 +        strncat(s, temps, cur_len);
 70.1947 +        cur_len -= strlen(temps);
 70.1948 +        
 70.1949 +        return max_len - cur_len;
 70.1950 +}
    71.1 --- a/src/vid_svga.h	Tue Jun 04 20:52:17 2013 +0100
    71.2 +++ b/src/vid_svga.h	Mon Jun 24 20:42:35 2013 +0100
    71.3 @@ -1,60 +1,123 @@
    71.4 -/*Vertical timings*/
    71.5 -extern int svga_vtotal, svga_dispend, svga_vsyncstart, svga_split;
    71.6 -/*Horizontal timings*/
    71.7 -extern int svga_hdisp, svga_htotal, svga_hdisp_time, svga_rowoffset;
    71.8 -/*Flags - svga_lowres = 1/2 clock in 256+ colour modes, svga_interlace = interlace mode enabled*/
    71.9 -extern int svga_lowres, svga_interlace;
   71.10 +typedef struct svga_t
   71.11 +{
   71.12 +        uint8_t crtcreg;
   71.13 +        uint8_t crtc[128];
   71.14 +        uint8_t gdcreg[16];
   71.15 +        int gdcaddr;
   71.16 +        uint8_t attrregs[32];
   71.17 +        int attraddr, attrff;
   71.18 +        uint8_t seqregs[64];
   71.19 +        int seqaddr;
   71.20 +        
   71.21 +        uint8_t miscout;
   71.22 +        int vidclock;
   71.23  
   71.24 -extern int svga_linedbl, svga_rowcount;
   71.25 +        uint32_t vram_limit;
   71.26 +        
   71.27 +        uint8_t la, lb, lc, ld;
   71.28 +        
   71.29 +        uint8_t dac_mask, dac_status;
   71.30 +        int dac_read, dac_write, dac_pos;
   71.31 +        
   71.32 +        uint8_t cgastat;
   71.33 +        
   71.34 +        int fast;
   71.35 +        uint8_t colourcompare, colournocare;
   71.36 +        int readmode, writemode, readplane;
   71.37 +        int chain4;
   71.38 +        uint8_t writemask;
   71.39 +        uint32_t charseta, charsetb;
   71.40 +        
   71.41 +        uint8_t egapal[16];
   71.42 +        uint32_t pallook[256];
   71.43 +        PALETTE vgapal;
   71.44  
   71.45 -/*Status of display on*/
   71.46 -extern int svga_hdisp_on;
   71.47 +        int vtotal, dispend, vsyncstart, split;
   71.48 +        int hdisp,  hdisp_old, htotal,  hdisp_time, rowoffset;
   71.49 +        int lowres, interlace;
   71.50 +        int linedbl, rowcount;
   71.51 +        double clock;
   71.52 +        uint32_t ma_latch;
   71.53 +        int bpp;
   71.54 +        
   71.55 +        int dispontime, dispofftime;
   71.56 +        int vidtime;
   71.57 +        
   71.58 +        uint8_t scrblank;
   71.59 +        
   71.60 +        int dispon;
   71.61 +        int hdisp_on;
   71.62  
   71.63 -extern double svga_clock;
   71.64 -extern uint32_t svga_ma;
   71.65 -extern void (*svga_recalctimings_ex)();
   71.66 +        uint32_t ma, maback, ca;
   71.67 +        int vc;
   71.68 +        int sc;
   71.69 +        int linepos, vslines, linecountff, oddeven;
   71.70 +        int con, cursoron, blink;
   71.71 +        int scrollcache;
   71.72 +        
   71.73 +        int firstline, lastline;
   71.74 +        int firstline_draw, lastline_draw;
   71.75 +        int displine;
   71.76 +        
   71.77 +        uint8_t *vram;
   71.78 +        uint8_t *changedvram;
   71.79 +        int vrammask;
   71.80  
   71.81 -extern uint8_t svga_miscout;
   71.82 +        uint32_t write_bank, read_bank;
   71.83 +                
   71.84 +        int fullchange;
   71.85 +        
   71.86 +        int video_res_x, video_res_y, video_bpp;
   71.87 +        int frames, fps;
   71.88  
   71.89 -extern int  svga_init();
   71.90 -extern void svga_poll();
   71.91 -extern void svga_recalctimings();
   71.92 +        struct
   71.93 +        {
   71.94 +                int ena;
   71.95 +                int x, y;
   71.96 +                int xoff, yoff;
   71.97 +                uint32_t addr;
   71.98 +        } hwcursor, hwcursor_latch;
   71.99 +        
  71.100 +        int hwcursor_on;
  71.101 +        
  71.102 +        void (*render)(struct svga_t *svga);
  71.103 +        void (*recalctimings_ex)(struct svga_t *svga);
  71.104  
  71.105 -typedef struct
  71.106 -{
  71.107 -        int ena;
  71.108 -        int x, y;
  71.109 -        int xoff, yoff;
  71.110 -        uint32_t addr;
  71.111 -} SVGA_HWCURSOR;
  71.112 +        void    (*video_out)(uint16_t addr, uint8_t val, void *p);
  71.113 +        uint8_t (*video_in) (uint16_t addr, void *p);
  71.114  
  71.115 -extern SVGA_HWCURSOR svga_hwcursor, svga_hwcursor_latch;
  71.116 +        void (*hwcursor_draw)(struct svga_t *svga, int displine);
  71.117 +        
  71.118 +        void *p;
  71.119 +} svga_t;
  71.120  
  71.121 -//extern int      svga_hwcursor_x,    svga_hwcursor_y;
  71.122 -//extern int      svga_hwcursor_xoff, svga_hwcursor_yoff;
  71.123 -//extern uint32_t /*svga_hwcursor_addr, */svga_hwcursor_addr_cur;
  71.124 -//extern int      svga_hwcursor_ena;
  71.125 +extern int svga_init(svga_t *svga, void *p, int memsize, 
  71.126 +               void (*recalctimings_ex)(struct svga_t *svga),
  71.127 +               uint8_t (*video_in) (uint16_t addr, void *p),
  71.128 +               void    (*video_out)(uint16_t addr, uint8_t val, void *p),
  71.129 +               void (*hwcursor_draw)(struct svga_t *svga, int displine));
  71.130 +extern void svga_recalctimings(svga_t *svga);
  71.131 +
  71.132 +
  71.133  extern int      svga_hwcursor_on;
  71.134  extern void   (*svga_hwcursor_draw)(int displine);
  71.135  
  71.136 -uint8_t  svga_read(uint32_t addr, void *priv);
  71.137 -uint16_t svga_readw(uint32_t addr, void *priv);
  71.138 -uint32_t svga_readl(uint32_t addr, void *priv);
  71.139 -void     svga_write(uint32_t addr, uint8_t val, void *priv);
  71.140 -void     svga_writew(uint32_t addr, uint16_t val, void *priv);
  71.141 -void     svga_writel(uint32_t addr, uint32_t val, void *priv);
  71.142 -uint8_t  svga_read_linear(uint32_t addr, void *priv);
  71.143 -uint16_t svga_readw_linear(uint32_t addr, void *priv);
  71.144 -uint32_t svga_readl_linear(uint32_t addr, void *priv);
  71.145 -void     svga_write_linear(uint32_t addr, uint8_t val, void *priv);
  71.146 -void     svga_writew_linear(uint32_t addr, uint16_t val, void *priv);
  71.147 -void     svga_writel_linear(uint32_t addr, uint32_t val, void *priv);
  71.148 +uint8_t  svga_read(uint32_t addr, void *p);
  71.149 +uint16_t svga_readw(uint32_t addr, void *p);
  71.150 +uint32_t svga_readl(uint32_t addr, void *p);
  71.151 +void     svga_write(uint32_t addr, uint8_t val, void *p);
  71.152 +void     svga_writew(uint32_t addr, uint16_t val, void *p);
  71.153 +void     svga_writel(uint32_t addr, uint32_t val, void *p);
  71.154 +uint8_t  svga_read_linear(uint32_t addr, void *p);
  71.155 +uint16_t svga_readw_linear(uint32_t addr, void *p);
  71.156 +uint32_t svga_readl_linear(uint32_t addr, void *p);
  71.157 +void     svga_write_linear(uint32_t addr, uint8_t val, void *p);
  71.158 +void     svga_writew_linear(uint32_t addr, uint16_t val, void *p);
  71.159 +void     svga_writel_linear(uint32_t addr, uint32_t val, void *p);
  71.160  
  71.161 -void svga_doblit(int y1, int y2);
  71.162 -
  71.163 -extern uint32_t svga_vram_limit;
  71.164 +int svga_add_status_info(char *s, int max_len, void *p);
  71.165  
  71.166  extern uint8_t svga_rotate[8][256];
  71.167  
  71.168 -void svga_out(uint16_t addr, uint8_t val, void *priv);
  71.169 -uint8_t svga_in(uint16_t addr, void *priv);
  71.170 +void svga_out(uint16_t addr, uint8_t val, void *p);
  71.171 +uint8_t svga_in(uint16_t addr, void *p);
    72.1 --- a/src/vid_svga_render.c	Tue Jun 04 20:52:17 2013 +0100
    72.2 +++ b/src/vid_svga_render.c	Mon Jun 24 20:42:35 2013 +0100
    72.3 @@ -3,36 +3,39 @@
    72.4  #include "vid_svga.h"
    72.5  #include "vid_svga_render.h"
    72.6  
    72.7 -void svga_render_blank()
    72.8 +void svga_render_blank(svga_t *svga)
    72.9  {
   72.10          int x, xx;
   72.11          
   72.12 -        if (firstline_draw == 2000) firstline_draw = displine;
   72.13 -        lastline_draw = displine;
   72.14 -        for (x=0;x<svga_hdisp;x++)
   72.15 +        if (svga->firstline_draw == 2000) 
   72.16 +                svga->firstline_draw = svga->displine;
   72.17 +        svga->lastline_draw = svga->displine;
   72.18 +        
   72.19 +        for (x = 0; x < svga->hdisp; x++)
   72.20          {
   72.21 -                switch (seqregs[1]&9)
   72.22 +                switch (svga->seqregs[1] & 9)
   72.23                  {
   72.24                          case 0:
   72.25 -                        for (xx=0;xx<9;xx++) ((uint32_t *)buffer32->line[displine])[(x*9)+xx+32]=0;
   72.26 +                        for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 9) + xx + 32] = 0;
   72.27                          break;
   72.28                          case 1:
   72.29 -                        for (xx=0;xx<8;xx++) ((uint32_t *)buffer32->line[displine])[(x*8)+xx+32]=0;
   72.30 +                        for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 8) + xx + 32] = 0;
   72.31                          break;
   72.32                          case 8:
   72.33 -                        for (xx=0;xx<18;xx++) ((uint32_t *)buffer32->line[displine])[(x*18)+xx+32]=0;
   72.34 +                        for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 18) + xx + 32] = 0;
   72.35                          break;
   72.36                          case 9:
   72.37 -                        for (xx=0;xx<16;xx++) ((uint32_t *)buffer32->line[displine])[(x*16)+xx+32]=0;
   72.38 +                        for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine])[(x * 16) + xx + 32] = 0;
   72.39                          break;
   72.40                  }
   72.41          }
   72.42  }
   72.43  
   72.44 -void svga_render_text_40()
   72.45 +void svga_render_text_40(svga_t *svga)
   72.46  {     
   72.47 -        if (firstline_draw == 2000) firstline_draw = displine;
   72.48 -        lastline_draw = displine;
   72.49 +        if (svga->firstline_draw == 2000) 
   72.50 +                svga->firstline_draw = svga->displine;
   72.51 +        svga->lastline_draw = svga->displine;
   72.52          
   72.53          if (fullchange)
   72.54          {
   72.55 @@ -41,56 +44,59 @@
   72.56                  uint8_t chr, attr, dat;
   72.57                  uint32_t charaddr;
   72.58                  int fg, bg;
   72.59 -                int xinc = (seqregs[1] & 1) ? 16 : 18;
   72.60 +                int xinc = (svga->seqregs[1] & 1) ? 16 : 18;
   72.61                  
   72.62 -                for (x=0;x<svga_hdisp;x+=xinc)
   72.63 +                for (x = 0; x < svga->hdisp; x += xinc)
   72.64                  {
   72.65 -                        drawcursor=((ma==ca) && con && cursoron);
   72.66 -                        chr=vram[(ma<<1)];
   72.67 -                        attr=vram[(ma<<1)+4];
   72.68 -                        if (attr&8) charaddr=charsetb+(chr*128);
   72.69 -                        else        charaddr=charseta+(chr*128);
   72.70 +                        drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
   72.71 +                        chr  = svga->vram[(svga->ma << 1) & svga->vrammask];
   72.72 +                        attr = svga->vram[((svga->ma << 1) + 4) & svga->vrammask];
   72.73 +                        if (attr & 8) charaddr = svga->charsetb + (chr * 128);
   72.74 +                        else          charaddr = svga->charseta + (chr * 128);
   72.75  
   72.76                          if (drawcursor) 
   72.77                          { 
   72.78 -                                bg=pallook[egapal[attr&15]]; 
   72.79 -                                fg=pallook[egapal[attr>>4]]; 
   72.80 +                                bg = svga->pallook[svga->egapal[attr & 15]]; 
   72.81 +                                fg = svga->pallook[svga->egapal[attr >> 4]]; 
   72.82                          }
   72.83                          else
   72.84                          {
   72.85 -                                fg=pallook[egapal[attr&15]];
   72.86 -                                bg=pallook[egapal[attr>>4]];
   72.87 -                                if (attr&0x80 && attrregs[0x10]&8)
   72.88 +                                fg = svga->pallook[svga->egapal[attr & 15]];
   72.89 +                                bg = svga->pallook[svga->egapal[attr >> 4]];
   72.90 +                                if (attr & 0x80 && svga->attrregs[0x10] & 8)
   72.91                                  {
   72.92 -                                        bg=pallook[egapal[(attr>>4)&7]];
   72.93 -                                        if (cgablink&16) fg=bg;
   72.94 +                                        bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
   72.95 +                                        if (svga->blink & 16) 
   72.96 +                                                fg = bg;
   72.97                                  }
   72.98                          }
   72.99  
  72.100 -                        dat=vram[charaddr+(sc<<2)];
  72.101 -                        if (seqregs[1]&1) 
  72.102 +                        dat = svga->vram[charaddr + (svga->sc << 2)];
  72.103 +                        if (svga->seqregs[1] & 1) 
  72.104                          { 
  72.105 -                                for (xx=0;xx<8;xx++) 
  72.106 -                                        ((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; 
  72.107 +                                for (xx = 0; xx < 8; xx++) 
  72.108 +                                        ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + (xx << 1)) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
  72.109                          }
  72.110                          else
  72.111                          {
  72.112 -                                for (xx=0;xx<8;xx++) 
  72.113 -                                        ((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;
  72.114 -                                if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) 
  72.115 -                                        ((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=bg;
  72.116 +                                for (xx = 0; xx < 8; xx++) 
  72.117 +                                        ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + (xx << 1)) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
  72.118 +                                if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) 
  72.119 +                                        ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 16) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 17) & 2047] = bg;
  72.120                                  else                  
  72.121 -                                        ((uint32_t *)buffer32->line[displine])[(x+32+16)&2047]=((uint32_t *)buffer32->line[displine])[(x+32+17)&2047]=(dat&1)?fg:bg;
  72.122 +                                        ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 16) & 2047] = ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 17) & 2047] = (dat & 1) ? fg : bg;
  72.123                          }
  72.124 -                        ma+=4; ma&=vrammask;
  72.125 +                        svga->ma += 4; 
  72.126 +                        svga->ma &= svga->vrammask;
  72.127                  }
  72.128          }
  72.129  }
  72.130  
  72.131 -void svga_render_text_80()
  72.132 +void svga_render_text_80(svga_t *svga)
  72.133  {
  72.134 -        if (firstline_draw == 2000) firstline_draw = displine;
  72.135 -        lastline_draw = displine;
  72.136 +        if (svga->firstline_draw == 2000) 
  72.137 +                svga->firstline_draw = svga->displine;
  72.138 +        svga->lastline_draw = svga->displine;
  72.139          
  72.140          if (fullchange)
  72.141          {
  72.142 @@ -99,388 +105,415 @@
  72.143                  uint8_t chr, attr, dat;
  72.144                  uint32_t charaddr;
  72.145                  int fg, bg;
  72.146 -                int xinc = (seqregs[1] & 1) ? 8 : 9;
  72.147 +                int xinc = (svga->seqregs[1] & 1) ? 8 : 9;
  72.148  
  72.149 -                for (x=0;x<svga_hdisp;x+=xinc)
  72.150 +                for (x = 0; x < svga->hdisp; x += xinc)
  72.151                  {
  72.152 -                        drawcursor=((ma==ca) && con && cursoron);
  72.153 -                        chr=vram[(ma<<1)];
  72.154 -                        attr=vram[(ma<<1)+4];
  72.155 -                        if (attr&8) charaddr=charsetb+(chr*128);
  72.156 -                        else        charaddr=charseta+(chr*128);
  72.157 +                        drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
  72.158 +                        chr  = svga->vram[(svga->ma << 1) & svga->vrammask];
  72.159 +                        attr = svga->vram[((svga->ma << 1) + 4) & svga->vrammask];
  72.160 +                        if (attr & 8) charaddr = svga->charsetb + (chr * 128);
  72.161 +                        else          charaddr = svga->charseta + (chr * 128);
  72.162  
  72.163                          if (drawcursor) 
  72.164                          { 
  72.165 -                                bg=pallook[egapal[attr&15]]; 
  72.166 -                                fg=pallook[egapal[attr>>4]]; 
  72.167 +                                bg = svga->pallook[svga->egapal[attr & 15]]; 
  72.168 +                                fg = svga->pallook[svga->egapal[attr >> 4]]; 
  72.169                          }
  72.170                          else
  72.171                          {
  72.172 -                                fg=pallook[egapal[attr&15]];
  72.173 -                                bg=pallook[egapal[attr>>4]];
  72.174 -                                if (attr&0x80 && attrregs[0x10]&8)
  72.175 +                                fg = svga->pallook[svga->egapal[attr & 15]];
  72.176 +                                bg = svga->pallook[svga->egapal[attr >> 4]];
  72.177 +                                if (attr & 0x80 && svga->attrregs[0x10] & 8)
  72.178                                  {
  72.179 -                                        bg=pallook[egapal[(attr>>4)&7]];
  72.180 -                                        if (cgablink&16) fg=bg;
  72.181 +                                        bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
  72.182 +                                        if (svga->blink & 16) 
  72.183 +                                                fg = bg;
  72.184                                  }
  72.185                          }
  72.186  
  72.187 -                        dat=vram[charaddr+(sc<<2)];
  72.188 -                        if (seqregs[1]&1) 
  72.189 +                        dat = svga->vram[charaddr + (svga->sc << 2)];
  72.190 +                        if (svga->seqregs[1] & 1) 
  72.191                          { 
  72.192 -                                for (xx=0;xx<8;xx++) 
  72.193 -                                        ((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg; 
  72.194 +                                for (xx = 0; xx < 8; xx++) 
  72.195 +                                        ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
  72.196                          }
  72.197                          else
  72.198                          {
  72.199 -                                for (xx=0;xx<8;xx++) 
  72.200 -                                        ((uint32_t *)buffer32->line[displine])[(x+32+xx)&2047]=(dat&(0x80>>xx))?fg:bg;
  72.201 -                                if ((chr&~0x1F)!=0xC0 || !(attrregs[0x10]&4)) 
  72.202 -                                        ((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=bg;
  72.203 +                                for (xx = 0; xx < 8; xx++) 
  72.204 +                                        ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg;
  72.205 +                                if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) 
  72.206 +                                        ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 8) & 2047] = bg;
  72.207                                  else                  
  72.208 -                                        ((uint32_t *)buffer32->line[displine])[(x+32+8)&2047]=(dat&1)?fg:bg;
  72.209 +                                        ((uint32_t *)buffer32->line[svga->displine])[(x + 32 + 8) & 2047] = (dat & 1) ? fg : bg;
  72.210                          }
  72.211 -                        ma+=4; ma&=vrammask;
  72.212 +                        svga->ma += 4; 
  72.213 +                        svga->ma &= svga->vrammask;
  72.214                  }
  72.215          }
  72.216  }
  72.217  
  72.218 -void svga_render_4bpp_lowres()
  72.219 +void svga_render_4bpp_lowres(svga_t *svga)
  72.220  {
  72.221          int x, offset;
  72.222          uint8_t edat[4], dat;
  72.223          
  72.224 -        if (firstline_draw == 2000) firstline_draw = displine;
  72.225 -        lastline_draw = displine;
  72.226 +        if (svga->firstline_draw == 2000) 
  72.227 +                svga->firstline_draw = svga->displine;
  72.228 +        svga->lastline_draw = svga->displine;
  72.229  
  72.230 -        offset=((8-scrollcache)<<1)+16;
  72.231 -        for (x = 0; x <= svga_hdisp; x += 16)
  72.232 +        offset = ((8 - svga->scrollcache) << 1) + 16;
  72.233 +        for (x = 0; x <= svga->hdisp; x += 16)
  72.234          {
  72.235 -                edat[0]=vram[ma];
  72.236 -                edat[1]=vram[ma|0x1];
  72.237 -                edat[2]=vram[ma|0x2];
  72.238 -                edat[3]=vram[ma|0x3];
  72.239 -                ma+=4; ma&=vrammask;
  72.240 +                edat[0] = svga->vram[svga->ma];
  72.241 +                edat[1] = svga->vram[svga->ma | 0x1];
  72.242 +                edat[2] = svga->vram[svga->ma | 0x2];
  72.243 +                edat[3] = svga->vram[svga->ma | 0x3];
  72.244 +                svga->ma += 4; 
  72.245 +                svga->ma &= svga->vrammask;
  72.246  
  72.247 -                dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
  72.248 -                ((uint32_t *)buffer32->line[displine])[x+14+offset]=((uint32_t *)buffer32->line[displine])[x+15+offset]=pallook[egapal[dat&0xF]];
  72.249 -                ((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[dat>>4]];
  72.250 -                dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
  72.251 -                ((uint32_t *)buffer32->line[displine])[x+10+offset]=((uint32_t *)buffer32->line[displine])[x+11+offset]=pallook[egapal[dat&0xF]];
  72.252 -                ((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[dat>>4]];
  72.253 -                dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
  72.254 -                ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[dat&0xF]];
  72.255 -                ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat>>4]];
  72.256 -                dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
  72.257 -                ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[dat&0xF]];
  72.258 -                ((uint32_t *)buffer32->line[displine])[x+offset]=   ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat>>4]];
  72.259 +                dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
  72.260 +                ((uint32_t *)buffer32->line[svga->displine])[x + 14 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 15 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
  72.261 +                ((uint32_t *)buffer32->line[svga->displine])[x + 12 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 13 + offset] = svga->pallook[svga->egapal[dat >> 4]];
  72.262 +                dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
  72.263 +                ((uint32_t *)buffer32->line[svga->displine])[x + 10 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 11 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
  72.264 +                ((uint32_t *)buffer32->line[svga->displine])[x +  8 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x +  9 + offset] = svga->pallook[svga->egapal[dat >> 4]];
  72.265 +                dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
  72.266 +                ((uint32_t *)buffer32->line[svga->displine])[x +  6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x +  7 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
  72.267 +                ((uint32_t *)buffer32->line[svga->displine])[x +  4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x +  5 + offset] = svga->pallook[svga->egapal[dat >> 4]];
  72.268 +                dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
  72.269 +                ((uint32_t *)buffer32->line[svga->displine])[x +  2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x +  3 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
  72.270 +                ((uint32_t *)buffer32->line[svga->displine])[x      + offset] = ((uint32_t *)buffer32->line[svga->displine])[x +  1 + offset] = svga->pallook[svga->egapal[dat >> 4]];
  72.271          }
  72.272  }
  72.273  
  72.274 -void svga_render_4bpp_highres()
  72.275 +void svga_render_4bpp_highres(svga_t *svga)
  72.276  {
  72.277          int x, offset;
  72.278          uint8_t edat[4], dat;
  72.279          
  72.280 -        if (firstline_draw == 2000) firstline_draw = displine;
  72.281 -        lastline_draw = displine;
  72.282 +        if (svga->firstline_draw == 2000) 
  72.283 +                svga->firstline_draw = svga->displine;
  72.284 +        svga->lastline_draw = svga->displine;
  72.285  
  72.286 -        offset=(8-scrollcache)+24;
  72.287 -        for (x = 0; x <= svga_hdisp; x += 8)
  72.288 +        offset = (8 - svga->scrollcache) + 24;
  72.289 +        for (x = 0; x <= svga->hdisp; x += 8)
  72.290          {
  72.291 -                edat[0]=vram[ma];
  72.292 -                edat[1]=vram[ma|0x1];
  72.293 -                edat[2]=vram[ma|0x2];
  72.294 -                edat[3]=vram[ma|0x3];
  72.295 -                ma+=4; ma&=vrammask;
  72.296 +                edat[0] = svga->vram[svga->ma];
  72.297 +                edat[1] = svga->vram[svga->ma | 0x1];
  72.298 +                edat[2] = svga->vram[svga->ma | 0x2];
  72.299 +                edat[3] = svga->vram[svga->ma | 0x3];
  72.300 +                svga->ma += 4;
  72.301 +                svga->ma &= svga->vrammask;
  72.302  
  72.303 -                dat=edatlookup[edat[0]&3][edat[1]&3]|(edatlookup[edat[2]&3][edat[3]&3]<<2);
  72.304 -                ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[dat&0xF]];
  72.305 -                ((uint32_t *)buffer32->line[displine])[x+6+offset]=pallook[egapal[dat>>4]];
  72.306 -                dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
  72.307 -                ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[dat&0xF]];
  72.308 -                ((uint32_t *)buffer32->line[displine])[x+4+offset]=pallook[egapal[dat>>4]];
  72.309 -                dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
  72.310 -                ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[dat&0xF]];
  72.311 -                ((uint32_t *)buffer32->line[displine])[x+2+offset]=pallook[egapal[dat>>4]];
  72.312 -                dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
  72.313 -                ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[dat&0xF]];
  72.314 -                ((uint32_t *)buffer32->line[displine])[x+offset]=  pallook[egapal[dat>>4]];
  72.315 +                dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
  72.316 +                ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
  72.317 +                ((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = svga->pallook[svga->egapal[dat >> 4]];
  72.318 +                dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
  72.319 +                ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
  72.320 +                ((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = svga->pallook[svga->egapal[dat >> 4]];
  72.321 +                dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
  72.322 +                ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
  72.323 +                ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = svga->pallook[svga->egapal[dat >> 4]];
  72.324 +                dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
  72.325 +                ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[svga->egapal[dat & 0xf]];
  72.326 +                ((uint32_t *)buffer32->line[svga->displine])[x +     offset] = svga->pallook[svga->egapal[dat >> 4]];
  72.327          }
  72.328  }
  72.329  
  72.330 -void svga_render_2bpp_lowres()
  72.331 +void svga_render_2bpp_lowres(svga_t *svga)
  72.332  {
  72.333          int x, offset;
  72.334 -        uint8_t edat[4], dat;
  72.335 +        uint8_t edat[2], dat;
  72.336                  
  72.337 -        if (firstline_draw == 2000) firstline_draw = displine;
  72.338 -        lastline_draw = displine;
  72.339 -        offset=((8-scrollcache)<<1)+16;
  72.340 +        if (svga->firstline_draw == 2000) 
  72.341 +                svga->firstline_draw = svga->displine;
  72.342 +        svga->lastline_draw = svga->displine;
  72.343 +        offset = ((8 - svga->scrollcache) << 1) + 16;
  72.344 +        
  72.345          /*Low res (320) only, though high res (640) should be possible*/
  72.346 -        for (x = 0; x <= svga_hdisp; x += 16)
  72.347 +        for (x = 0; x <= svga->hdisp; x += 16)
  72.348          {
  72.349 -                if (sc&1 && !(crtc[0x17]&1))
  72.350 +                if (svga->sc & 1 && !(svga->crtc[0x17] & 1))
  72.351                  {
  72.352 -                        edat[0]=vram[(ma<<1)+0x8000];
  72.353 -                        edat[1]=vram[(ma<<1)+0x8004];
  72.354 +                        edat[0] = svga->vram[(svga->ma << 1) + 0x8000];
  72.355 +                        edat[1] = svga->vram[(svga->ma << 1) + 0x8004];
  72.356                  }
  72.357                  else
  72.358                  {
  72.359 -                        edat[0]=vram[(ma<<1)];
  72.360 -                        edat[1]=vram[(ma<<1)+4];
  72.361 +                        edat[0] = svga->vram[(svga->ma << 1)];
  72.362 +                        edat[1] = svga->vram[(svga->ma << 1) + 4];
  72.363                  }
  72.364 -                ma+=4; ma&=vrammask;
  72.365 +                svga->ma += 4; svga->ma &= svga->vrammask;
  72.366  
  72.367 -                ((uint32_t *)buffer32->line[displine])[x+14+offset]=((uint32_t *)buffer32->line[displine])[x+15+offset]=pallook[egapal[edat[1]&3]];
  72.368 -                ((uint32_t *)buffer32->line[displine])[x+12+offset]=((uint32_t *)buffer32->line[displine])[x+13+offset]=pallook[egapal[(edat[1]>>2)&3]];
  72.369 -                dat=edatlookup[(edat[0]>>2)&3][(edat[1]>>2)&3]|(edatlookup[(edat[2]>>2)&3][(edat[3]>>2)&3]<<2);
  72.370 -                ((uint32_t *)buffer32->line[displine])[x+10+offset]=((uint32_t *)buffer32->line[displine])[x+11+offset]=pallook[egapal[(edat[1]>>4)&3]];
  72.371 -                ((uint32_t *)buffer32->line[displine])[x+8+offset]= ((uint32_t *)buffer32->line[displine])[x+9+offset]=pallook[egapal[(edat[1]>>6)&3]];
  72.372 -                dat=edatlookup[(edat[0]>>4)&3][(edat[1]>>4)&3]|(edatlookup[(edat[2]>>4)&3][(edat[3]>>4)&3]<<2);
  72.373 -                ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[egapal[(edat[0]>>0)&3]];
  72.374 -                ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[egapal[(edat[0]>>2)&3]];
  72.375 -                dat=edatlookup[edat[0]>>6][edat[1]>>6]|(edatlookup[edat[2]>>6][edat[3]>>6]<<2);
  72.376 -                ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[egapal[(edat[0]>>4)&3]];
  72.377 -                ((uint32_t *)buffer32->line[displine])[x+offset]=   ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[egapal[(edat[0]>>6)&3]];
  72.378 +                ((uint32_t *)buffer32->line[svga->displine])[x + 14 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 15 + offset] = svga->pallook[svga->egapal[edat[1] & 3]];
  72.379 +                ((uint32_t *)buffer32->line[svga->displine])[x + 12 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 13 + offset] = svga->pallook[svga->egapal[(edat[1] >> 2) & 3]];
  72.380 +                ((uint32_t *)buffer32->line[svga->displine])[x + 10 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 11 + offset] = svga->pallook[svga->egapal[(edat[1] >> 4) & 3]];
  72.381 +                ((uint32_t *)buffer32->line[svga->displine])[x +  8 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x +  9 + offset] = svga->pallook[svga->egapal[(edat[1] >> 6) & 3]];
  72.382 +                ((uint32_t *)buffer32->line[svga->displine])[x +  6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x +  7 + offset] = svga->pallook[svga->egapal[edat[0] & 3]];
  72.383 +                ((uint32_t *)buffer32->line[svga->displine])[x +  4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x +  5 + offset] = svga->pallook[svga->egapal[(edat[0] >> 2) & 3]];
  72.384 +                ((uint32_t *)buffer32->line[svga->displine])[x +  2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x +  3 + offset] = svga->pallook[svga->egapal[(edat[0] >> 4) & 3]];
  72.385 +                ((uint32_t *)buffer32->line[svga->displine])[x +      offset] = ((uint32_t *)buffer32->line[svga->displine])[x +  1 + offset] = svga->pallook[svga->egapal[(edat[0] >> 6) & 3]];
  72.386          }
  72.387  }
  72.388  
  72.389 -void svga_render_8bpp_lowres()
  72.390 +void svga_render_8bpp_lowres(svga_t *svga)
  72.391  {
  72.392          int x, offset;
  72.393          uint8_t edat[4];
  72.394                  
  72.395 -        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  72.396 +        if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
  72.397          {
  72.398 -                if (firstline_draw == 2000) firstline_draw = displine;
  72.399 -                lastline_draw = displine;
  72.400 +                if (svga->firstline_draw == 2000) 
  72.401 +                        svga->firstline_draw = svga->displine;
  72.402 +                svga->lastline_draw = svga->displine;
  72.403  
  72.404 -                offset=(8-(scrollcache&6))+24;
  72.405 +                offset = (8 - (svga->scrollcache & 6)) + 24;
  72.406                                                                  
  72.407 -                for (x = 0; x <= svga_hdisp; x += 8)
  72.408 +                for (x = 0; x <= svga->hdisp; x += 8)
  72.409                  {
  72.410 -                        edat[0]=vram[ma];
  72.411 -                        edat[1]=vram[ma|0x1];
  72.412 -                        edat[2]=vram[ma|0x2];
  72.413 -                        edat[3]=vram[ma|0x3];
  72.414 -                        ma+=4; ma&=vrammask;
  72.415 -                        ((uint32_t *)buffer32->line[displine])[x+6+offset]= ((uint32_t *)buffer32->line[displine])[x+7+offset]=pallook[edat[3]];
  72.416 -                        ((uint32_t *)buffer32->line[displine])[x+4+offset]= ((uint32_t *)buffer32->line[displine])[x+5+offset]=pallook[edat[2]];
  72.417 -                        ((uint32_t *)buffer32->line[displine])[x+2+offset]= ((uint32_t *)buffer32->line[displine])[x+3+offset]=pallook[edat[1]];
  72.418 -                        ((uint32_t *)buffer32->line[displine])[x+offset]=   ((uint32_t *)buffer32->line[displine])[x+1+offset]=pallook[edat[0]];
  72.419 +                        edat[0] = svga->vram[svga->ma];
  72.420 +                        edat[1] = svga->vram[svga->ma | 0x1];
  72.421 +                        edat[2] = svga->vram[svga->ma | 0x2];
  72.422 +                        edat[3] = svga->vram[svga->ma | 0x3];
  72.423 +                        svga->ma += 4; 
  72.424 +                        svga->ma &= svga->vrammask;                       
  72.425 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[edat[3]];
  72.426 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[edat[2]];
  72.427 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[edat[1]];
  72.428 +                        ((uint32_t *)buffer32->line[svga->displine])[x +     offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[edat[0]];
  72.429                  }
  72.430          }
  72.431  }
  72.432  
  72.433 -void svga_render_8bpp_highres()
  72.434 +void svga_render_8bpp_highres(svga_t *svga)
  72.435  {
  72.436          int x, offset;
  72.437          uint8_t edat[4];
  72.438                  
  72.439 -        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  72.440 +        if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
  72.441          {
  72.442 -                if (firstline_draw == 2000) firstline_draw = displine;
  72.443 -                lastline_draw = displine;
  72.444 +                if (svga->firstline_draw == 2000) 
  72.445 +                        svga->firstline_draw = svga->displine;
  72.446 +                svga->lastline_draw = svga->displine;
  72.447  
  72.448 -                offset = (8 - ((scrollcache & 6) >> 1)) + 24;
  72.449 +                offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
  72.450                                                                  
  72.451 -                for (x = 0; x <= svga_hdisp; x += 8)
  72.452 +                for (x = 0; x <= svga->hdisp; x += 8)
  72.453                  {
  72.454 -                        edat[0]=vram[ma];
  72.455 -                        edat[1]=vram[ma|0x1];
  72.456 -                        edat[2]=vram[ma|0x2];
  72.457 -                        edat[3]=vram[ma|0x3];
  72.458 -                        ma+=4; ma&=vrammask;
  72.459 -                        ((uint32_t *)buffer32->line[displine])[x+3+offset] = pallook[edat[3]];
  72.460 -                        ((uint32_t *)buffer32->line[displine])[x+2+offset] = pallook[edat[2]];
  72.461 -                        ((uint32_t *)buffer32->line[displine])[x+1+offset] = pallook[edat[1]];
  72.462 -                        ((uint32_t *)buffer32->line[displine])[x+offset]   = pallook[edat[0]];
  72.463 -                        edat[0]=vram[ma];
  72.464 -                        edat[1]=vram[ma|0x1];
  72.465 -                        edat[2]=vram[ma|0x2];
  72.466 -                        edat[3]=vram[ma|0x3];
  72.467 -                        ma+=4; ma&=vrammask;
  72.468 -                        ((uint32_t *)buffer32->line[displine])[x+7+offset] = pallook[edat[3]];
  72.469 -                        ((uint32_t *)buffer32->line[displine])[x+6+offset] = pallook[edat[2]];
  72.470 -                        ((uint32_t *)buffer32->line[displine])[x+5+offset] = pallook[edat[1]];
  72.471 -                        ((uint32_t *)buffer32->line[displine])[x+4+offset] = pallook[edat[0]];
  72.472 +                        edat[0] = svga->vram[svga->ma];
  72.473 +                        edat[1] = svga->vram[svga->ma | 0x1];
  72.474 +                        edat[2] = svga->vram[svga->ma | 0x2];
  72.475 +                        edat[3] = svga->vram[svga->ma | 0x3];
  72.476 +                        svga->ma += 4; 
  72.477 +                        svga->ma &= svga->vrammask;
  72.478 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = svga->pallook[edat[3]];
  72.479 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = svga->pallook[edat[2]];
  72.480 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = svga->pallook[edat[1]];
  72.481 +                        ((uint32_t *)buffer32->line[svga->displine])[x +     offset] = svga->pallook[edat[0]];
  72.482 +                        
  72.483 +                        edat[0] = svga->vram[svga->ma];
  72.484 +                        edat[1] = svga->vram[svga->ma | 0x1];
  72.485 +                        edat[2] = svga->vram[svga->ma | 0x2];
  72.486 +                        edat[3] = svga->vram[svga->ma | 0x3];
  72.487 +                        svga->ma += 4; 
  72.488 +                        svga->ma &= svga->vrammask;
  72.489 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 7 + offset] = svga->pallook[edat[3]];
  72.490 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 6 + offset] = svga->pallook[edat[2]];
  72.491 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 5 + offset] = svga->pallook[edat[1]];
  72.492 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 4 + offset] = svga->pallook[edat[0]];
  72.493                  }
  72.494          }
  72.495  }
  72.496  
  72.497 -void svga_render_15bpp_lowres()
  72.498 +void svga_render_15bpp_lowres(svga_t *svga)
  72.499  {
  72.500          int x, offset;
  72.501          uint16_t fg, bg;
  72.502          
  72.503 -        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  72.504 +        if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
  72.505          {
  72.506 -                if (firstline_draw == 2000) firstline_draw = displine;
  72.507 -                lastline_draw = displine;
  72.508 +                if (svga->firstline_draw == 2000) 
  72.509 +                        svga->firstline_draw = svga->displine;
  72.510 +                svga->lastline_draw = svga->displine;
  72.511  
  72.512 -                offset=(8-(scrollcache&6))+24;
  72.513 +                offset = (8 - (svga->scrollcache & 6)) + 24;
  72.514  
  72.515 -                for (x = 0; x <= svga_hdisp; x += 4)
  72.516 +                for (x = 0; x <= svga->hdisp; x += 4)
  72.517                  {
  72.518 -                        fg=vram[ma]|(vram[ma|0x1]<<8);
  72.519 -                        bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
  72.520 -                        ma+=4; ma&=vrammask;
  72.521 -                        ((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);
  72.522 -                        ((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);
  72.523 +                        fg = svga->vram[svga->ma]       | (svga->vram[svga->ma | 0x1] << 8);
  72.524 +                        bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
  72.525 +                        svga->ma += 4; 
  72.526 +                        svga->ma &= svga->vrammask;
  72.527 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 31) << 11) | (((bg >> 10) & 31) << 19);
  72.528 +                        ((uint32_t *)buffer32->line[svga->displine])[x +     offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((fg & 31) << 3) | (((fg >> 5) & 31) << 11) | (((fg >> 10) & 31) << 19);
  72.529                  }
  72.530          }
  72.531  }
  72.532  
  72.533 -void svga_render_15bpp_highres()
  72.534 +void svga_render_15bpp_highres(svga_t *svga)
  72.535  {
  72.536          int x, offset;
  72.537          uint16_t fg, bg;
  72.538          
  72.539 -        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  72.540 +        if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
  72.541          {
  72.542 -                if (firstline_draw == 2000) firstline_draw = displine;
  72.543 -                lastline_draw = displine;
  72.544 +                if (svga->firstline_draw == 2000) 
  72.545 +                        svga->firstline_draw = svga->displine;
  72.546 +                svga->lastline_draw = svga->displine;
  72.547  
  72.548 -                offset = (8 - ((scrollcache & 6) >> 1)) + 24;
  72.549 -                                                                
  72.550 -                for (x = 0; x <= svga_hdisp; x += 2)
  72.551 +                offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
  72.552 +
  72.553 +                for (x = 0; x <= svga->hdisp; x += 2)
  72.554                  {
  72.555 -                        fg=vram[ma]|(vram[ma|0x1]<<8);
  72.556 -                        bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
  72.557 -                        ma+=4; ma&=vrammask;
  72.558 -                        ((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&31)<<11)|(((bg>>10)&31)<<19);
  72.559 -                        ((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&31)<<11)|(((fg>>10)&31)<<19);
  72.560 +                        fg = svga->vram[svga->ma]       | (svga->vram[svga->ma | 0x1] << 8);
  72.561 +                        bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
  72.562 +                        svga->ma += 4; 
  72.563 +                        svga->ma &= svga->vrammask;
  72.564 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 31) << 11) | (((bg >> 10) & 31) << 19);
  72.565 +                        ((uint32_t *)buffer32->line[svga->displine])[x +     offset] = ((fg & 31) << 3) | (((fg >> 5) & 31) << 11) | (((fg >> 10) & 31) << 19);
  72.566                  }
  72.567          }
  72.568  }
  72.569  
  72.570 -void svga_render_16bpp_lowres()
  72.571 +void svga_render_16bpp_lowres(svga_t *svga)
  72.572  {
  72.573          int x, offset;
  72.574          uint16_t fg, bg;
  72.575          
  72.576 -        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  72.577 +        if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
  72.578          {
  72.579 -                if (firstline_draw == 2000) firstline_draw = displine;
  72.580 -                lastline_draw = displine;
  72.581 +                if (svga->firstline_draw == 2000) 
  72.582 +                        svga->firstline_draw = svga->displine;
  72.583 +                svga->lastline_draw = svga->displine;
  72.584  
  72.585 -                offset=(8-(scrollcache&6))+24;
  72.586 +                offset = (8 - (svga->scrollcache & 6)) + 24;
  72.587  
  72.588 -                for (x = 0; x <= svga_hdisp; x += 4)
  72.589 +                for (x = 0; x <= svga->hdisp; x += 4)
  72.590                  {
  72.591 -                        fg=vram[ma]|(vram[ma|0x1]<<8);
  72.592 -                        bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
  72.593 -                        ma+=4; ma&=vrammask;
  72.594 -                        ((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);
  72.595 -                        ((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);
  72.596 +                        fg = svga->vram[svga->ma]       | (svga->vram[svga->ma | 0x1] << 8);
  72.597 +                        bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
  72.598 +                        svga->ma += 4; 
  72.599 +                        svga->ma &= svga->vrammask;
  72.600 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 2 + offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 3 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 63) << 10) | (((bg >> 11) & 31) << 19);
  72.601 +                        ((uint32_t *)buffer32->line[svga->displine])[x +     offset] = ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((fg & 31) << 3) | (((fg >> 5) & 63) << 10) | (((fg >> 11) & 31) << 19);
  72.602                  }
  72.603          }
  72.604  }
  72.605  
  72.606 -void svga_render_16bpp_highres()
  72.607 +void svga_render_16bpp_highres(svga_t *svga)
  72.608  {
  72.609          int x, offset;
  72.610          uint16_t fg, bg;
  72.611          
  72.612 -        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  72.613 +        if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
  72.614          {
  72.615 -                if (firstline_draw == 2000) firstline_draw = displine;
  72.616 -                lastline_draw = displine;
  72.617 +                if (svga->firstline_draw == 2000) 
  72.618 +                        svga->firstline_draw = svga->displine;
  72.619 +                svga->lastline_draw = svga->displine;
  72.620  
  72.621 -                offset = (8 - ((scrollcache & 6) >> 1)) + 24;
  72.622 +                offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
  72.623                                                                  
  72.624 -                for (x = 0; x <= svga_hdisp; x += 2)
  72.625 +                for (x = 0; x <= svga->hdisp; x += 2)
  72.626                  {
  72.627 -                        fg=vram[ma]|(vram[ma|0x1]<<8);
  72.628 -                        bg=vram[ma|0x2]|(vram[ma|0x3]<<8);
  72.629 -                        ma+=4; ma&=vrammask;
  72.630 -                        ((uint32_t *)buffer32->line[displine])[x + 1 + offset] = ((bg&31)<<3)|(((bg>>5)&63)<<10)|(((bg>>11)&31)<<19);
  72.631 -                        ((uint32_t *)buffer32->line[displine])[x + 0 + offset] = ((fg&31)<<3)|(((fg>>5)&63)<<10)|(((fg>>11)&31)<<19);
  72.632 +                        fg = svga->vram[svga->ma]       | (svga->vram[svga->ma | 0x1] << 8);
  72.633 +                        bg = svga->vram[svga->ma | 0x2] | (svga->vram[svga->ma | 0x3] << 8);
  72.634 +                        svga->ma += 4; 
  72.635 +                        svga->ma &= svga->vrammask;
  72.636 +                        ((uint32_t *)buffer32->line[svga->displine])[x + 1 + offset] = ((bg & 31) << 3) | (((bg >> 5) & 63) << 10) | (((bg >> 11) & 31) << 19);
  72.637 +                        ((uint32_t *)buffer32->line[svga->displine])[x +     offset] = ((fg & 31) << 3) | (((fg >> 5) & 63) << 10) | (((fg >> 11) & 31) << 19);
  72.638                  }
  72.639          }
  72.640  }
  72.641  
  72.642 -void svga_render_24bpp_lowres()
  72.643 +void svga_render_24bpp_lowres(svga_t *svga)
  72.644  {
  72.645          int x, offset;
  72.646          uint32_t fg;
  72.647          
  72.648 -        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  72.649 +        if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
  72.650          {
  72.651 -                if (firstline_draw == 2000) firstline_draw = displine;
  72.652 -                lastline_draw = displine;
  72.653 +                if (svga->firstline_draw == 2000) 
  72.654 +                        svga->firstline_draw = svga->displine;
  72.655 +                svga->lastline_draw = svga->displine;
  72.656  
  72.657 -                offset=(8-(scrollcache&6))+24;
  72.658 +                offset = (8 - (svga->scrollcache & 6)) + 24;
  72.659  
  72.660 -                for (x = 0; x <= svga_hdisp; x++)
  72.661 +                for (x = 0; x <= svga->hdisp; x++)
  72.662                  {
  72.663 -                        fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
  72.664 -                        ma+=3; ma&=vrammask;
  72.665 -                        ((uint32_t *)buffer32->line[displine])[(x<<1)+offset]=((uint32_t *)buffer32->line[displine])[(x<<1)+1+offset]=fg;
  72.666 +                        fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
  72.667 +                        svga->ma += 3; 
  72.668 +                        svga->ma &= svga->vrammask;
  72.669 +                        ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
  72.670                  }
  72.671          }
  72.672  }
  72.673  
  72.674 -void svga_render_24bpp_highres()
  72.675 +void svga_render_24bpp_highres(svga_t *svga)
  72.676  {
  72.677          int x, offset;
  72.678          uint32_t fg;
  72.679          
  72.680 -        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  72.681 +        if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
  72.682          {
  72.683 -                if (firstline_draw == 2000) firstline_draw = displine;
  72.684 -                lastline_draw = displine;
  72.685 +                if (svga->firstline_draw == 2000) 
  72.686 +                        svga->firstline_draw = svga->displine;
  72.687 +                svga->lastline_draw = svga->displine;
  72.688  
  72.689 -                offset = (8 - ((scrollcache & 6) >> 1)) + 24;
  72.690 +                offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
  72.691  
  72.692 -                for (x = 0; x <= svga_hdisp; x++)
  72.693 +                for (x = 0; x <= svga->hdisp; x++)
  72.694                  {
  72.695 -                        fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
  72.696 -                        ma+=3; ma&=vrammask;
  72.697 -                        ((uint32_t *)buffer32->line[displine])[x + offset] = fg;
  72.698 +                        fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
  72.699 +                        svga->ma += 3; 
  72.700 +                        svga->ma &= svga->vrammask;
  72.701 +                        ((uint32_t *)buffer32->line[svga->displine])[x + offset] = fg;
  72.702                  }
  72.703          }
  72.704  }
  72.705  
  72.706 -void svga_render_32bpp_lowres()
  72.707 +void svga_render_32bpp_lowres(svga_t *svga)
  72.708  {
  72.709          int x, offset;
  72.710          uint32_t fg;
  72.711          
  72.712 -        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  72.713 +        if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
  72.714          {
  72.715 -                if (firstline_draw == 2000) firstline_draw = displine;
  72.716 -                lastline_draw = displine;
  72.717 +                if (svga->firstline_draw == 2000) 
  72.718 +                        svga->firstline_draw = svga->displine;
  72.719 +                svga->lastline_draw = svga->displine;
  72.720  
  72.721 -                offset=(8-(scrollcache&6))+24;
  72.722 +                offset = (8 - (svga->scrollcache & 6)) + 24;
  72.723  
  72.724 -                for (x = 0; x <= svga_hdisp; x++)
  72.725 +                for (x = 0; x <= svga->hdisp; x++)
  72.726                  {
  72.727 -                        fg = vram[ma] | (vram[ma + 1] << 8) | (vram[ma + 2] << 16);
  72.728 -                        ma += 4; ma &= vrammask;
  72.729 -                        ((uint32_t *)buffer32->line[displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[displine])[(x << 1) + 1 + offset] = fg;
  72.730 +                        fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
  72.731 +                        svga->ma += 4; 
  72.732 +                        svga->ma &= svga->vrammask;
  72.733 +                        ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
  72.734                  }
  72.735          }
  72.736  }
  72.737  
  72.738 -void svga_render_32bpp_highres()
  72.739 +void svga_render_32bpp_highres(svga_t *svga)
  72.740  {
  72.741          int x, offset;
  72.742          uint32_t fg;
  72.743          
  72.744 -        if (changedvram[ma>>10] || changedvram[(ma>>10)+1] || changedvram[(ma>>10)+2] || fullchange)
  72.745 +        if (svga->changedvram[svga->ma >> 10] || svga->changedvram[(svga->ma >> 10) + 1] || svga->changedvram[(svga->ma >> 10) + 2] || fullchange)
  72.746          {
  72.747 -                if (firstline_draw == 2000) firstline_draw = displine;
  72.748 -                lastline_draw = displine;
  72.749 +                if (svga->firstline_draw == 2000) 
  72.750 +                        svga->firstline_draw = svga->displine;
  72.751 +                svga->lastline_draw = svga->displine;
  72.752  
  72.753 -                offset = (8 - ((scrollcache & 6) >> 1)) + 24;
  72.754 +                offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
  72.755  
  72.756 -                for (x = 0; x <= svga_hdisp; x++)
  72.757 +                for (x = 0; x <= svga->hdisp; x++)
  72.758                  {
  72.759 -                        fg=vram[ma]|(vram[ma+1]<<8)|(vram[ma+2]<<16);
  72.760 -                        ma+=4; ma&=vrammask;
  72.761 -                        ((uint32_t *)buffer32->line[displine])[x + offset] = fg;
  72.762 +                        fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
  72.763 +                        svga->ma += 4; 
  72.764 +                        svga->ma &= svga->vrammask;
  72.765 +                        ((uint32_t *)buffer32->line[svga->displine])[x + offset] = fg;
  72.766                  }
  72.767          }
  72.768  }
    73.1 --- a/src/vid_svga_render.h	Tue Jun 04 20:52:17 2013 +0100
    73.2 +++ b/src/vid_svga_render.h	Mon Jun 24 20:42:35 2013 +0100
    73.3 @@ -9,22 +9,22 @@
    73.4  
    73.5  extern uint8_t edatlookup[4][4];
    73.6  
    73.7 -void svga_render_blank();
    73.8 -void svga_render_text_40();
    73.9 -void svga_render_text_80();
   73.10 +void svga_render_blank(svga_t *svga);
   73.11 +void svga_render_text_40(svga_t *svga);
   73.12 +void svga_render_text_80(svga_t *svga);
   73.13  
   73.14 -void svga_render_2bpp_lowres();
   73.15 -void svga_render_4bpp_lowres();
   73.16 -void svga_render_4bpp_highres();
   73.17 -void svga_render_8bpp_lowres();
   73.18 -void svga_render_8bpp_highres();
   73.19 -void svga_render_15bpp_lowres();
   73.20 -void svga_render_15bpp_highres();
   73.21 -void svga_render_16bpp_lowres();
   73.22 -void svga_render_16bpp_highres();
   73.23 -void svga_render_24bpp_lowres();
   73.24 -void svga_render_24bpp_highres();
   73.25 -void svga_render_32bpp_lowres();
   73.26 -void svga_render_32bpp_highres();
   73.27 +void svga_render_2bpp_lowres(svga_t *svga);
   73.28 +void svga_render_4bpp_lowres(svga_t *svga);
   73.29 +void svga_render_4bpp_highres(svga_t *svga);
   73.30 +void svga_render_8bpp_lowres(svga_t *svga);
   73.31 +void svga_render_8bpp_highres(svga_t *svga);
   73.32 +void svga_render_15bpp_lowres(svga_t *svga);
   73.33 +void svga_render_15bpp_highres(svga_t *svga);
   73.34 +void svga_render_16bpp_lowres(svga_t *svga);
   73.35 +void svga_render_16bpp_highres(svga_t *svga);
   73.36 +void svga_render_24bpp_lowres(svga_t *svga);
   73.37 +void svga_render_24bpp_highres(svga_t *svga);
   73.38 +void svga_render_32bpp_lowres(svga_t *svga);
   73.39 +void svga_render_32bpp_highres(svga_t *svga);
   73.40  
   73.41 -extern void (*svga_render)();
   73.42 +extern void (*svga_render)(svga_t *svga);
    74.1 --- a/src/vid_tandy.c	Tue Jun 04 20:52:17 2013 +0100
    74.2 +++ b/src/vid_tandy.c	Mon Jun 24 20:42:35 2013 +0100
    74.3 @@ -1,138 +1,171 @@
    74.4 +#include <stdlib.h>
    74.5 +#include <math.h>
    74.6  #include "ibm.h"
    74.7 -#include "video.h"
    74.8 +#include "device.h"
    74.9  #include "io.h"
   74.10  #include "mem.h"
   74.11  #include "timer.h"
   74.12 +#include "video.h"
   74.13 +#include "vid_tandy.h"
   74.14  
   74.15 -static int      tandy_array_index;
   74.16 -static uint8_t  tandy_array[32];
   74.17 -static int      tandy_memctrl=-1;
   74.18 -static uint32_t tandy_base;
   74.19 -static uint8_t  tandy_mode,tandy_col;
   74.20 +static int i_filt[8],q_filt[8];
   74.21  
   74.22 -static uint8_t *tandy_vram, *tandy_b8000;
   74.23 +typedef struct tandy_t
   74.24 +{
   74.25 +        uint8_t crtc[32];
   74.26 +        int crtcreg;
   74.27 +        
   74.28 +        int      array_index;
   74.29 +        uint8_t  array[32];
   74.30 +        int      memctrl;//=-1;
   74.31 +        uint32_t base;
   74.32 +        uint8_t  mode, col;
   74.33 +        uint8_t  stat;
   74.34 +        
   74.35 +        uint8_t *vram, *b8000;
   74.36  
   74.37 -void tandy_recalcaddress();
   74.38 -void tandy_recalctimings();
   74.39 +        int linepos, displine;
   74.40 +        int sc, vc;
   74.41 +        int dispon;
   74.42 +        int con, coff, cursoron, blink;
   74.43 +        int vsynctime, vadj;
   74.44 +        uint16_t ma, maback;
   74.45          
   74.46 -void tandy_out(uint16_t addr, uint8_t val, void *priv)
   74.47 +        int dispontime, dispofftime, vidtime;
   74.48 +        int firstline, lastline;
   74.49 +} tandy_t;
   74.50 +
   74.51 +static uint8_t crtcmask[32] = 
   74.52  {
   74.53 +        0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
   74.54 +        0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   74.55 +};
   74.56 +
   74.57 +void tandy_recalcaddress(tandy_t *tandy);
   74.58 +void tandy_recalctimings(tandy_t *tandy);
   74.59 +        
   74.60 +void tandy_out(uint16_t addr, uint8_t val, void *p)
   74.61 +{
   74.62 +        tandy_t *tandy = (tandy_t *)p;
   74.63          uint8_t old;
   74.64  //        pclog("Tandy OUT %04X %02X\n",addr,val);
   74.65          switch (addr)
   74.66          {
   74.67 -                case 0x3D4:
   74.68 -                crtcreg=val&31;
   74.69 +                case 0x3d4:
   74.70 +                tandy->crtcreg = val & 0x1f;
   74.71                  return;
   74.72 -                case 0x3D5:
   74.73 -                old=crtc[crtcreg];
   74.74 -                crtc[crtcreg]=val&crtcmask[crtcreg];
   74.75 -                if (old!=val)
   74.76 +                case 0x3d5:
   74.77 +                old = tandy->crtc[tandy->crtcreg];
   74.78 +                tandy->crtc[tandy->crtcreg] = val & crtcmask[tandy->crtcreg];
   74.79 +                if (old != val)
   74.80                  {
   74.81 -                        if (crtcreg<0xE || crtcreg>0x10)
   74.82 +                        if (tandy->crtcreg < 0xe || tandy->crtcreg > 0x10)
   74.83                          {
   74.84 -                                fullchange=changeframecount;
   74.85 -                                tandy_recalctimings();
   74.86 +                                fullchange = changeframecount;
   74.87 +                                tandy_recalctimings(tandy);
   74.88                          }
   74.89                  }
   74.90                  return;
   74.91 -                case 0x3D8:
   74.92 -                tandy_mode=val;
   74.93 +                case 0x3d8:
   74.94 +                tandy->mode = val;
   74.95                  return;
   74.96 -                case 0x3D9:
   74.97 -                tandy_col=val;
   74.98 +                case 0x3d9:
   74.99 +                tandy->col = val;
  74.100                  return;
  74.101 -                case 0x3DA:
  74.102 -                tandy_array_index = val & 31;
  74.103 +                case 0x3da:
  74.104 +                tandy->array_index = val & 0x1f;
  74.105                  break;
  74.106 -                case 0x3DE:
  74.107 -                if (tandy_array_index & 16) val &= 0xF;
  74.108 -                tandy_array[tandy_array_index & 31] = val;
  74.109 +                case 0x3de:
  74.110 +                if (tandy->array_index & 16) 
  74.111 +                        val &= 0xf;
  74.112 +                tandy->array[tandy->array_index & 0x1f] = val;
  74.113                  break;
  74.114 -                case 0x3DF:
  74.115 -                tandy_memctrl=val;
  74.116 -                tandy_recalcaddress();
  74.117 +                case 0x3df:
  74.118 +                tandy->memctrl = val;
  74.119 +                tandy_recalcaddress(tandy);
  74.120                  break;
  74.121 -                case 0xA0:
  74.122 -                tandy_base=((val>>1)&7)*128*1024;
  74.123 -                tandy_recalcaddress();
  74.124 +                case 0xa0:
  74.125 +                tandy->base = ((val >> 1) & 7) * 128 * 1024;
  74.126 +                tandy_recalcaddress(tandy);
  74.127                  break;
  74.128          }
  74.129  }
  74.130  
  74.131 -uint8_t tandy_in(uint16_t addr, void *priv)
  74.132 +uint8_t tandy_in(uint16_t addr, void *p)
  74.133  {
  74.134 +        tandy_t *tandy = (tandy_t *)p;
  74.135  //        if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr);
  74.136          switch (addr)
  74.137          {
  74.138 -                case 0x3D4:
  74.139 -                return crtcreg;
  74.140 -                case 0x3D5:
  74.141 -                return crtc[crtcreg];
  74.142 -                case 0x3DA:
  74.143 -                return cgastat;
  74.144 +                case 0x3d4:
  74.145 +                return tandy->crtcreg;
  74.146 +                case 0x3d5:
  74.147 +                return tandy->crtc[tandy->crtcreg];
  74.148 +                case 0x3da:
  74.149 +                return tandy->stat;
  74.150          }
  74.151          return 0xFF;
  74.152  }
  74.153  
  74.154 -void tandy_recalcaddress()
  74.155 +void tandy_recalcaddress(tandy_t *tandy)
  74.156  {
  74.157 -        if ((tandy_memctrl&0xC0)==0xC0)
  74.158 +        if ((tandy->memctrl & 0xc0) == 0xc0)
  74.159          {
  74.160 -                tandy_vram =&ram[((tandy_memctrl&0x6)<<14) +tandy_base];
  74.161 -                tandy_b8000=&ram[((tandy_memctrl&0x30)<<11)+tandy_base];
  74.162 -//                printf("VRAM at %05X B8000 at %05X\n",((tandy_memctrl&0x6)<<14)+tandy_base,((tandy_memctrl&0x30)<<11)+tandy_base);
  74.163 +                tandy->vram  = &ram[((tandy->memctrl & 0x06) << 14) + tandy->base];
  74.164 +                tandy->b8000 = &ram[((tandy->memctrl & 0x30) << 11) + tandy->base];
  74.165 +//                printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x6)<<14)+tandy->base,((tandy->memctrl&0x30)<<11)+tandy->base);
  74.166          }
  74.167          else
  74.168          {
  74.169 -                tandy_vram =&ram[((tandy_memctrl&0x7)<<14) +tandy_base];
  74.170 -                tandy_b8000=&ram[((tandy_memctrl&0x38)<<11)+tandy_base];
  74.171 -//                printf("VRAM at %05X B8000 at %05X\n",((tandy_memctrl&0x7)<<14)+tandy_base,((tandy_memctrl&0x38)<<11)+tandy_base);
  74.172 +                tandy->vram  = &ram[((tandy->memctrl & 0x07) << 14) + tandy->base];
  74.173 +                tandy->b8000 = &ram[((tandy->memctrl & 0x38) << 11) + tandy->base];
  74.174 +//                printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x7)<<14)+tandy->base,((tandy->memctrl&0x38)<<11)+tandy->base);
  74.175          }
  74.176  }
  74.177  
  74.178 -void tandy_write(uint32_t addr, uint8_t val, void *priv)
  74.179 +void tandy_write(uint32_t addr, uint8_t val, void *p)
  74.180  {
  74.181 -        if (tandy_memctrl==-1) return;
  74.182 +        tandy_t *tandy = (tandy_t *)p;
  74.183 +        if (tandy->memctrl == -1) 
  74.184 +                return;
  74.185 +                
  74.186 +        egawrites++;
  74.187  //        pclog("Tandy VRAM write %05X %02X %04X:%04X  %04X:%04X\n",addr,val,CS,pc,DS,SI);
  74.188 -        tandy_b8000[addr&0x7FFF]=val;
  74.189 +        tandy->b8000[addr & 0x7fff] = val;
  74.190  }
  74.191  
  74.192 -uint8_t tandy_read(uint32_t addr, void *priv)
  74.193 +uint8_t tandy_read(uint32_t addr, void *p)
  74.194  {
  74.195 -        if (tandy_memctrl==-1) return 0xFF;
  74.196 -//        pclog("Tandy VRAM read  %05X %02X %04X:%04X\n",addr,tandy_b8000[addr&0x7FFF],CS,pc);
  74.197 -        return tandy_b8000[addr&0x7FFF];
  74.198 +        tandy_t *tandy = (tandy_t *)p;
  74.199 +        if (tandy->memctrl == -1) 
  74.200 +                return 0xff;
  74.201 +                
  74.202 +        egareads++;
  74.203 +//        pclog("Tandy VRAM read  %05X %02X %04X:%04X\n",addr,tandy->b8000[addr&0x7FFF],CS,pc);
  74.204 +        return tandy->b8000[addr & 0x7fff];
  74.205  }
  74.206  
  74.207 -void tandy_recalctimings()
  74.208 +void tandy_recalctimings(tandy_t *tandy)
  74.209  {
  74.210 -	double _dispontime, _dispofftime;
  74.211 -        if (tandy_mode&1)
  74.212 +	double _dispontime, _dispofftime, disptime;
  74.213 +        if (tandy->mode & 1)
  74.214          {
  74.215 -                disptime=crtc[0]+1;
  74.216 -                _dispontime=crtc[1];
  74.217 +                disptime = tandy->crtc[0] + 1;
  74.218 +                _dispontime = tandy->crtc[1];
  74.219          }
  74.220          else
  74.221          {
  74.222 -                disptime=(crtc[0]+1)<<1;
  74.223 -                _dispontime=crtc[1]<<1;
  74.224 +                disptime = (tandy->crtc[0] + 1) << 1;
  74.225 +                _dispontime = tandy->crtc[1] << 1;
  74.226          }
  74.227 -        _dispofftime=disptime-_dispontime;
  74.228 -        _dispontime*=CGACONST;
  74.229 -        _dispofftime*=CGACONST;
  74.230 -	dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
  74.231 -	dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  74.232 +        _dispofftime = disptime - _dispontime;
  74.233 +        _dispontime  *= CGACONST;
  74.234 +        _dispofftime *= CGACONST;
  74.235 +	tandy->dispontime  = (int)(_dispontime  * (1 << TIMER_SHIFT));
  74.236 +	tandy->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
  74.237  }
  74.238  
  74.239  
  74.240 -static int linepos,displine;
  74.241 -static int sc,vc;
  74.242 -static int cgadispon;
  74.243 -static int con,coff,cursoron,cgablink;
  74.244 -static int vsynctime,vadj;
  74.245 -static uint16_t ma,maback;
  74.246 -
  74.247  static int ntsc_col[8][8]=
  74.248  {
  74.249          {0,0,0,0,0,0,0,0}, /*Black*/
  74.250 @@ -145,423 +178,455 @@
  74.251          {1,1,1,1,1,1,1,1}  /*White*/
  74.252  };
  74.253  
  74.254 -int i_filt[8],q_filt[8];
  74.255 -
  74.256  /*static int cga4pal[8][4]=
  74.257  {
  74.258          {0,2,4,6},{0,3,5,7},{0,3,4,7},{0,3,4,7},
  74.259          {0,10,12,14},{0,11,13,15},{0,11,12,15},{0,11,12,15}
  74.260  };*/
  74.261  
  74.262 -void tandy_poll()
  74.263 +void tandy_poll(void *p)
  74.264  {
  74.265 -//        int *cgapal=cga4pal[((tandy_col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)];
  74.266 -        uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF;
  74.267 +//        int *cgapal=cga4pal[((tandy->col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)];
  74.268 +        tandy_t *tandy = (tandy_t *)p;
  74.269 +        uint16_t ca = (tandy->crtc[15] | (tandy->crtc[14] << 8)) & 0x3fff;
  74.270          int drawcursor;
  74.271 -        int x,c;
  74.272 +        int x, c;
  74.273          int oldvc;
  74.274 -        uint8_t chr,attr;
  74.275 +        uint8_t chr, attr;
  74.276          uint16_t dat;
  74.277          int cols[4];
  74.278          int col;
  74.279          int oldsc;
  74.280 -        int y_buf[8]={0,0,0,0,0,0,0,0},y_val,y_tot;
  74.281 -        int i_buf[8]={0,0,0,0,0,0,0,0},i_val,i_tot;
  74.282 -        int q_buf[8]={0,0,0,0,0,0,0,0},q_val,q_tot;
  74.283 -        int r,g,b;
  74.284 -        if (!linepos)
  74.285 +        int y_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, y_val, y_tot;
  74.286 +        int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_tot;
  74.287 +        int q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot;
  74.288 +        int r, g, b;
  74.289 +        if (!tandy->linepos)
  74.290          {
  74.291 -//                cgapal[0]=tandy_col&15;
  74.292 -//                printf("Firstline %i Lastline %i Displine %i\n",firstline,lastline,displine);
  74.293 -                vidtime+=dispofftime;
  74.294 -                cgastat|=1;
  74.295 -                linepos=1;
  74.296 -                oldsc=sc;
  74.297 -                if ((crtc[8]&3)==3) sc=(sc<<1)&7;
  74.298 -                if (cgadispon)
  74.299 +//                cgapal[0]=tandy->col&15;
  74.300 +//                printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine);
  74.301 +                tandy->vidtime += tandy->dispofftime;
  74.302 +                tandy->stat |= 1;
  74.303 +                tandy->linepos = 1;
  74.304 +                oldsc = tandy->sc;
  74.305 +                if ((tandy->crtc[8] & 3) == 3) 
  74.306 +                        tandy->sc = (tandy->sc << 1) & 7;
  74.307 +                if (tandy->dispon)
  74.308                  {
  74.309 -                        if (displine<firstline)
  74.310 +                        if (tandy->displine < tandy->firstline)
  74.311                          {
  74.312 -                                firstline=displine;
  74.313 +                                tandy->firstline = tandy->displine;
  74.314  //                                printf("Firstline %i\n",firstline);
  74.315                          }
  74.316 -                        lastline=displine;
  74.317 -                        cols[0]=(tandy_array[2]&0xF)+16;
  74.318 -                        for (c=0;c<8;c++)
  74.319 +                        tandy->lastline = tandy->displine;
  74.320 +                        cols[0] = (tandy->array[2] & 0xf) + 16;
  74.321 +                        for (c = 0; c < 8; c++)
  74.322                          {
  74.323 -                                if (tandy_array[3]&4)
  74.324 +                                if (tandy->array[3] & 4)
  74.325                                  {
  74.326 -                                        buffer->line[displine][c]=cols[0];
  74.327 -                                        if (tandy_mode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=cols[0];
  74.328 -                                        else              buffer->line[displine][c+(crtc[1]<<4)+8]=cols[0];
  74.329 +                                        buffer->line[tandy->displine][c] = cols[0];
  74.330 +                                        if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = cols[0];
  74.331 +                                        else                 buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = cols[0];
  74.332                                  }
  74.333 -                                else if ((tandy_mode&0x12)==0x12)
  74.334 +                                else if ((tandy->mode & 0x12) == 0x12)
  74.335                                  {
  74.336 -                                        buffer->line[displine][c]=0;
  74.337 -                                        if (tandy_mode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
  74.338 -                                        else              buffer->line[displine][c+(crtc[1]<<4)+8]=0;
  74.339 +                                        buffer->line[tandy->displine][c] = 0;
  74.340 +                                        if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = 0;
  74.341 +                                        else                 buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = 0;
  74.342                                  }
  74.343                                  else
  74.344                                  {
  74.345 -                                        buffer->line[displine][c]=(tandy_col&15)+16;
  74.346 -                                        if (tandy_mode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(tandy_col&15)+16;
  74.347 -                                        else              buffer->line[displine][c+(crtc[1]<<4)+8]=(tandy_col&15)+16;
  74.348 +                                        buffer->line[tandy->displine][c] = (tandy->col & 15) + 16;
  74.349 +                                        if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = (tandy->col & 15) + 16;
  74.350 +                                        else                 buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = (tandy->col & 15) + 16;
  74.351                                  }
  74.352                          }
  74.353  //                        printf("X %i %i\n",c+(crtc[1]<<4)+8,c+(crtc[1]<<3)+8);
  74.354 -//                        printf("Drawing %i %i %i\n",displine,vc,sc);
  74.355 -                        if ((tandy_array[3]&0x10) && (tandy_mode&1)) /*320x200x16*/
  74.356 +//                        printf("Drawing %i %i %i\n",tandy->displine,vc,sc);
  74.357 +                        if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/
  74.358                          {
  74.359 -                                for (x=0;x<crtc[1];x++)
  74.360 +                                for (x = 0; x < tandy->crtc[1]; x++)
  74.361                                  {
  74.362 -                                        dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)+1];
  74.363 -                                        ma++;
  74.364 -                                        buffer->line[displine][(x<<3)+8]=buffer->line[displine][(x<<3)+9]  =tandy_array[((dat>>12)&tandy_array[1])+16]+16;
  74.365 -                                        buffer->line[displine][(x<<3)+10]=buffer->line[displine][(x<<3)+11]=tandy_array[((dat>>8)&tandy_array[1])+16]+16;
  74.366 -                                        buffer->line[displine][(x<<3)+12]=buffer->line[displine][(x<<3)+13]=tandy_array[((dat>>4)&tandy_array[1])+16]+16;
  74.367 -                                        buffer->line[displine][(x<<3)+14]=buffer->line[displine][(x<<3)+15]=tandy_array[(dat&tandy_array[1])+16]+16;
  74.368 +                                        dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | 
  74.369 +                                               tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1];
  74.370 +                                        tandy->ma++;
  74.371 +                                        buffer->line[tandy->displine][(x << 3) + 8]  = 
  74.372 +                                        buffer->line[tandy->displine][(x << 3) + 9]  = tandy->array[((dat >> 12) & tandy->array[1]) + 16] + 16;
  74.373 +                                        buffer->line[tandy->displine][(x << 3) + 10] = 
  74.374 +                                        buffer->line[tandy->displine][(x << 3) + 11] = tandy->array[((dat >>  8) & tandy->array[1]) + 16] + 16;
  74.375 +                                        buffer->line[tandy->displine][(x << 3) + 12] = 
  74.376 +                                        buffer->line[tandy->displine][(x << 3) + 13] = tandy->array[((dat >>  4) & tandy->array[1]) + 16] + 16;
  74.377 +                                        buffer->line[tandy->displine][(x << 3) + 14] = 
  74.378 +                                        buffer->line[tandy->displine][(x << 3) + 15] = tandy->array[(dat         & tandy->array[1]) + 16] + 16;
  74.379                                  }
  74.380                          }
  74.381 -                        else if (tandy_array[3]&0x10) /*160x200x16*/
  74.382 +                        else if (tandy->array[3] & 0x10) /*160x200x16*/
  74.383                          {
  74.384 -                                for (x=0;x<crtc[1];x++)
  74.385 +                                for (x = 0; x < tandy->crtc[1]; x++)
  74.386                                  {
  74.387 -                                        dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)+1];
  74.388 -                                        ma++;
  74.389 -                                        buffer->line[displine][(x<<4)+8]= buffer->line[displine][(x<<4)+9]= buffer->line[displine][(x<<4)+10]=buffer->line[displine][(x<<4)+11]=tandy_array[((dat>>12)&tandy_array[1])+16]+16;
  74.390 -                                        buffer->line[displine][(x<<4)+12]=buffer->line[displine][(x<<4)+13]=buffer->line[displine][(x<<4)+14]=buffer->line[displine][(x<<4)+15]=tandy_array[((dat>>8)&tandy_array[1])+16]+16;
  74.391 -                                        buffer->line[displine][(x<<4)+16]=buffer->line[displine][(x<<4)+17]=buffer->line[displine][(x<<4)+18]=buffer->line[displine][(x<<4)+19]=tandy_array[((dat>>4)&tandy_array[1])+16]+16;
  74.392 -                                        buffer->line[displine][(x<<4)+20]=buffer->line[displine][(x<<4)+21]=buffer->line[displine][(x<<4)+22]=buffer->line[displine][(x<<4)+23]=tandy_array[(dat&tandy_array[1])+16]+16;
  74.393 +                                        dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | 
  74.394 +                                               tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1];
  74.395 +                                        tandy->ma++;
  74.396 +                                        buffer->line[tandy->displine][(x << 4) + 8]  = 
  74.397 +                                        buffer->line[tandy->displine][(x << 4) + 9]  = 
  74.398 +                                        buffer->line[tandy->displine][(x << 4) + 10] =
  74.399 +                                        buffer->line[tandy->displine][(x << 4) + 11] = tandy->array[((dat >> 12) & tandy->array[1]) + 16] + 16;
  74.400 +                                        buffer->line[tandy->displine][(x << 4) + 12] = 
  74.401 +                                        buffer->line[tandy->displine][(x << 4) + 13] =
  74.402 +                                        buffer->line[tandy->displine][(x << 4) + 14] =
  74.403 +                                        buffer->line[tandy->displine][(x << 4) + 15] = tandy->array[((dat >>  8) & tandy->array[1]) + 16] + 16;
  74.404 +                                        buffer->line[tandy->displine][(x << 4) + 16] = 
  74.405 +                                        buffer->line[tandy->displine][(x << 4) + 17] =
  74.406 +                                        buffer->line[tandy->displine][(x << 4) + 18] =
  74.407 +                                        buffer->line[tandy->displine][(x << 4) + 19] = tandy->array[((dat >>  4) & tandy->array[1]) + 16] + 16;
  74.408 +                                        buffer->line[tandy->displine][(x << 4) + 20] = 
  74.409 +                                        buffer->line[tandy->displine][(x << 4) + 21] =
  74.410 +                                        buffer->line[tandy->displine][(x << 4) + 22] =
  74.411 +                                        buffer->line[tandy->displine][(x << 4) + 23] = tandy->array[(dat         & tandy->array[1]) + 16] + 16;
  74.412                                  }
  74.413                          }
  74.414 -                        else if (tandy_array[3]&0x08) /*640x200x4 - this implementation is a complete guess!*/
  74.415 +                        else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/
  74.416                          {
  74.417 -                                for (x=0;x<crtc[1];x++)
  74.418 +                                for (x = 0; x < tandy->crtc[1]; x++)
  74.419                                  {
  74.420 -                                        dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&3)*0x2000)+1];
  74.421 -                                        ma++;
  74.422 -                                        for (c=0;c<8;c++)
  74.423 +                                        dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) |
  74.424 +                                               tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1];
  74.425 +                                        tandy->ma++;
  74.426 +                                        for (c = 0; c < 8; c++)
  74.427                                          {
  74.428 -                                                chr=(dat>>7)&1;
  74.429 -                                                chr|=((dat>>14)&2);
  74.430 -                                                buffer->line[displine][(x<<3)+8+c]=tandy_array[(chr&tandy_array[1])+16]+16;
  74.431 -                                                dat<<=1;
  74.432 +                                                chr  =  (dat >>  7) & 1;
  74.433 +                                                chr |= ((dat >> 14) & 2);
  74.434 +                                                buffer->line[tandy->displine][(x << 3) + 8 + c] = tandy->array[(chr & tandy->array[1]) + 16] + 16;
  74.435 +                                                dat <<= 1;
  74.436                                          }
  74.437                                  }
  74.438                          }
  74.439 -                        else if (tandy_mode&1)
  74.440 +                        else if (tandy->mode & 1)
  74.441                          {
  74.442 -                                for (x=0;x<crtc[1];x++)
  74.443 +                                for (x = 0; x < tandy->crtc[1]; x++)
  74.444                                  {
  74.445 -                                        chr=tandy_vram[(ma<<1)&0x3FFF];
  74.446 -                                        attr=tandy_vram[((ma<<1)+1)&0x3FFF];
  74.447 -                                        drawcursor=((ma==ca) && con && cursoron);
  74.448 -                                        if (tandy_mode&0x20)
  74.449 +                                        chr  = tandy->vram[ (tandy->ma << 1)      & 0x3fff];
  74.450 +                                        attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff];
  74.451 +                                        drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron);
  74.452 +                                        if (tandy->mode & 0x20)
  74.453                                          {
  74.454 -                                                cols[1]=tandy_array[((attr&15)&tandy_array[1])+16]+16;
  74.455 -                                                cols[0]=tandy_array[(((attr>>4)&7)&tandy_array[1])+16]+16;
  74.456 -                                                if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
  74.457 +                                                cols[1] = tandy->array[ ((attr & 15)      & tandy->array[1]) + 16] + 16;
  74.458 +                                                cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16] + 16;
  74.459 +                                                if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) 
  74.460 +                                                        cols[1] = cols[0];
  74.461                                          }
  74.462                                          else
  74.463                                          {
  74.464 -                                                cols[1]=tandy_array[((attr&15)&tandy_array[1])+16]+16;
  74.465 -                                                cols[0]=tandy_array[((attr>>4)&tandy_array[1])+16]+16;
  74.466 +                                                cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16] + 16;
  74.467 +                                                cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16] + 16;
  74.468                                          }
  74.469 -                                        if (sc&8)
  74.470 +                                        if (tandy->sc & 8)
  74.471                                          {
  74.472 -                                                for (c=0;c<8;c++)
  74.473 -                                                    buffer->line[displine][(x<<3)+c+8]=cols[0];
  74.474 +                                                for (c = 0; c < 8; c++)
  74.475 +                                                    buffer->line[tandy->displine][(x << 3) + c + 8] = cols[0];
  74.476                                          }
  74.477                                          else
  74.478                                          {
  74.479 -                                                for (c=0;c<8;c++)
  74.480 -                                                    buffer->line[displine][(x<<3)+c+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
  74.481 +                                                for (c = 0; c < 8; c++)
  74.482 +                                                    buffer->line[tandy->displine][(x << 3) + c + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
  74.483                                          }
  74.484  //                                        if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) printf("Cursor match! %04X\n",ma);
  74.485                                          if (drawcursor)
  74.486                                          {
  74.487 -                                                for (c=0;c<8;c++)
  74.488 -                                                    buffer->line[displine][(x<<3)+c+8]^=15;
  74.489 +                                                for (c = 0; c < 8; c++)
  74.490 +                                                    buffer->line[tandy->displine][(x << 3) + c + 8] ^= 15;
  74.491                                          }
  74.492 -                                        ma++;
  74.493 +                                        tandy->ma++;
  74.494                                  }
  74.495                          }
  74.496 -                        else if (!(tandy_mode&2))
  74.497 +                        else if (!(tandy->mode & 2))
  74.498                          {
  74.499 -                                for (x=0;x<crtc[1];x++)
  74.500 +                                for (x = 0; x < tandy->crtc[1]; x++)
  74.501                                  {
  74.502 -                                        chr=tandy_vram[(ma<<1)&0x3FFF];
  74.503 -                                        attr=tandy_vram[((ma<<1)+1)&0x3FFF];
  74.504 -                                        drawcursor=((ma==ca) && con && cursoron);
  74.505 -                                        if (tandy_mode&0x20)
  74.506 +                                        chr  = tandy->vram[ (tandy->ma << 1)      & 0x3fff];
  74.507 +                                        attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff];
  74.508 +                                        drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron);
  74.509 +                                        if (tandy->mode & 0x20)
  74.510                                          {
  74.511 -                                                cols[1]=tandy_array[((attr&15)&tandy_array[1])+16]+16;
  74.512 -                                                cols[0]=tandy_array[(((attr>>4)&7)&tandy_array[1])+16]+16;
  74.513 -                                                if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
  74.514 +                                                cols[1] = tandy->array[ ((attr & 15)      & tandy->array[1]) + 16] + 16;
  74.515 +                                                cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16] + 16;
  74.516 +                                                if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) 
  74.517 +                                                        cols[1] = cols[0];
  74.518                                          }
  74.519                                          else
  74.520                                          {
  74.521 -                                                cols[1]=tandy_array[((attr&15)&tandy_array[1])+16]+16;
  74.522 -                                                cols[0]=tandy_array[((attr>>4)&tandy_array[1])+16]+16;
  74.523 +                                                cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16] + 16;
  74.524 +                                                cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16] + 16;
  74.525                                          }
  74.526 -                                        ma++;
  74.527 -                                        if (sc&8)
  74.528 +                                        tandy->ma++;
  74.529 +                                        if (tandy->sc & 8)
  74.530                                          {
  74.531 -                                                for (c=0;c<8;c++)
  74.532 -                                                    buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[0];
  74.533 +                                                for (c = 0; c < 8; c++)
  74.534 +                                                    buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] = 
  74.535 +                                                    buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[0];
  74.536                                          }
  74.537                                          else
  74.538                                          {
  74.539 -                                                for (c=0;c<8;c++)
  74.540 -                                                    buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdat[chr][sc&7]&(1<<(c^7)))?1:0];
  74.541 +                                                for (c = 0; c < 8; c++)
  74.542 +                                                    buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] = 
  74.543 +                                                    buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
  74.544                                          }
  74.545                                          if (drawcursor)
  74.546                                          {
  74.547 -                                                for (c=0;c<16;c++)
  74.548 -                                                    buffer->line[displine][(x<<4)+c+8]^=15;
  74.549 +                                                for (c = 0; c < 16; c++)
  74.550 +                                                    buffer->line[tandy->displine][(x << 4) + c + 8] ^= 15;
  74.551                                          }
  74.552                                  }
  74.553                          }
  74.554 -                        else if (!(tandy_mode&16))
  74.555 +                        else if (!(tandy->mode& 16))
  74.556                          {
  74.557 -                                cols[0]=(tandy_col&15)|16;
  74.558 -                                col=(tandy_col&16)?24:16;
  74.559 -                                if (tandy_mode&4)
  74.560 +                                cols[0] = (tandy->col & 15) | 16;
  74.561 +                                col = (tandy->col & 16) ? 24 : 16;
  74.562 +                                if (tandy->mode & 4)
  74.563                                  {
  74.564 -                                        cols[1]=col|3;
  74.565 -                                        cols[2]=col|4;
  74.566 -                                        cols[3]=col|7;
  74.567 +                                        cols[1] = col | 3;
  74.568 +                                        cols[2] = col | 4;
  74.569 +                                        cols[3] = col | 7;
  74.570                                  }
  74.571 -                                else if (tandy_col&32)
  74.572 +                                else if (tandy->col & 32)
  74.573                                  {
  74.574 -                                        cols[1]=col|3;
  74.575 -                                        cols[2]=col|5;
  74.576 -                                        cols[3]=col|7;
  74.577 +                                        cols[1] = col | 3;
  74.578 +                                        cols[2] = col | 5;
  74.579 +                                        cols[3] = col | 7;
  74.580                                  }
  74.581                                  else
  74.582                                  {
  74.583 -                                        cols[1]=col|2;
  74.584 -                                        cols[2]=col|4;
  74.585 -                                        cols[3]=col|6;
  74.586 +                                        cols[1] = col | 2;
  74.587 +                                        cols[2] = col | 4;
  74.588 +                                        cols[3] = col | 6;
  74.589                                  }
  74.590 -                                for (x=0;x<crtc[1];x++)
  74.591 +                                for (x = 0; x < tandy->crtc[1]; x++)
  74.592                                  {
  74.593 -                                        dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
  74.594 -                                        ma++;
  74.595 -                                        for (c=0;c<8;c++)
  74.596 +                                        dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | 
  74.597 +                                               tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1];
  74.598 +                                        tandy->ma++;
  74.599 +                                        for (c = 0; c < 8; c++)
  74.600                                          {
  74.601 -                                                buffer->line[displine][(x<<4)+(c<<1)+8]=
  74.602 -                                                  buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
  74.603 -                                                dat<<=2;
  74.604 +                                                buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] =
  74.605 +                                                buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
  74.606 +                                                dat <<= 2;
  74.607                                          }
  74.608                                  }
  74.609                          }
  74.610                          else
  74.611                          {
  74.612 -                                cols[0]=0; cols[1]=tandy_array[(tandy_col&tandy_array[1])+16]+16;
  74.613 -                                for (x=0;x<crtc[1];x++)
  74.614 +                                cols[0] = 0; 
  74.615 +                                cols[1] = tandy->array[(tandy->col & tandy->array[1]) + 16] + 16;
  74.616 +                                for (x = 0; x < tandy->crtc[1]; x++)
  74.617                                  {
  74.618 -                                        dat=(tandy_vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)]<<8)|tandy_vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1];
  74.619 -                                        ma++;
  74.620 -                                        for (c=0;c<16;c++)
  74.621 +                                        dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) |
  74.622 +                                               tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1];
  74.623 +                                        tandy->ma++;
  74.624 +                                        for (c = 0; c < 16; c++)
  74.625                                          {
  74.626 -                                                buffer->line[displine][(x<<4)+c+8]=cols[dat>>15];
  74.627 -                                                dat<<=1;
  74.628 +                                                buffer->line[tandy->displine][(x << 4) + c + 8] = cols[dat >> 15];
  74.629 +                                                dat <<= 1;
  74.630                                          }
  74.631                                  }
  74.632                          }
  74.633                  }
  74.634                  else
  74.635                  {
  74.636 -                        if (tandy_array[3]&4)
  74.637 +                        if (tandy->array[3] & 4)
  74.638                          {
  74.639 -                                if (tandy_mode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,(tandy_array[2]&0xF)+16);
  74.640 -                                else              hline(buffer,0,displine,(crtc[1]<<4)+16,(tandy_array[2]&0xF)+16);
  74.641 +                                if (tandy->mode & 1) hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, (tandy->array[2] & 0xf) + 16);
  74.642 +                                else                 hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, (tandy->array[2] & 0xf) + 16);
  74.643                          }
  74.644                          else
  74.645                          {
  74.646 -                                cols[0]=((tandy_mode&0x12)==0x12)?0:(tandy_col&15)+16;
  74.647 -                                if (tandy_mode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
  74.648 -                                else              hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
  74.649 +                                cols[0] = ((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf) + 16;
  74.650 +                                if (tandy->mode & 1) hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cols[0]);
  74.651 +                                else                 hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cols[0]);
  74.652                          }
  74.653                  }
  74.654 -                if (tandy_mode&1) x=(crtc[1]<<3)+16;
  74.655 -                else              x=(crtc[1]<<4)+16;
  74.656 +                if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16;
  74.657 +                else                 x = (tandy->crtc[1] << 4) + 16;
  74.658                  if (cga_comp)
  74.659                  {
  74.660 -                        for (c=0;c<x;c++)
  74.661 +                        for (c = 0; c < x; c++)
  74.662                          {
  74.663 -                                y_buf[(c<<1)&6]=ntsc_col[buffer->line[displine][c]&7][(c<<1)&6]?0x6000:0;
  74.664 -                                y_buf[(c<<1)&6]+=(buffer->line[displine][c]&8)?0x3000:0;
  74.665 -                                i_buf[(c<<1)&6]=y_buf[(c<<1)&6]*i_filt[(c<<1)&6];
  74.666 -                                q_buf[(c<<1)&6]=y_buf[(c<<1)&6]*q_filt[(c<<1)&6];
  74.667 -                                y_tot=y_buf[0]+y_buf[1]+y_buf[2]+y_buf[3]+y_buf[4]+y_buf[5]+y_buf[6]+y_buf[7];
  74.668 -                                i_tot=i_buf[0]+i_buf[1]+i_buf[2]+i_buf[3]+i_buf[4]+i_buf[5]+i_buf[6]+i_buf[7];
  74.669 -                                q_tot=q_buf[0]+q_buf[1]+q_buf[2]+q_buf[3]+q_buf[4]+q_buf[5]+q_buf[6]+q_buf[7];
  74.670 +                                y_buf[(c << 1) & 6] = ntsc_col[buffer->line[tandy->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 0;
  74.671 +                                y_buf[(c << 1) & 6] += (buffer->line[tandy->displine][c] & 8) ? 0x3000 : 0;
  74.672 +                                i_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * i_filt[(c << 1) & 6];
  74.673 +                                q_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * q_filt[(c << 1) & 6];
  74.674 +                                y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
  74.675 +                                i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
  74.676 +                                q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
  74.677  
  74.678 -                                y_val=y_tot>>10;
  74.679 -                                if (y_val>255) y_val=255;
  74.680 -                                y_val<<=16;
  74.681 -                                i_val=i_tot>>12;
  74.682 -                                if (i_val>39041) i_val=39041;
  74.683 -                                if (i_val<-39041) i_val=-39041;
  74.684 -                                q_val=q_tot>>12;
  74.685 -                                if (q_val>34249) q_val=34249;
  74.686 -                                if (q_val<-34249) q_val=-34249;
  74.687 +                                y_val = y_tot >> 10;
  74.688 +                                if (y_val > 255) y_val = 255;
  74.689 +                                y_val <<= 16;
  74.690 +                                i_val = i_tot >> 12;
  74.691 +                                if (i_val >  39041) i_val =  39041;
  74.692 +                                if (i_val < -39041) i_val = -39041;
  74.693 +                                q_val = q_tot >> 12;
  74.694 +                                if (q_val >  34249) q_val =  34249;
  74.695 +                                if (q_val < -34249) q_val = -34249;
  74.696  
  74.697 -                                r=(y_val+249*i_val+159*q_val)>>16;
  74.698 -                                g=(y_val-70*i_val-166*q_val)>>16;
  74.699 -                                b=(y_val-283*i_val+436*q_val)>>16;
  74.700 -//                                if (r>255) r=255;
  74.701 -//                                if (g>255) g=255;
  74.702 -//                              if (b>255) b=255;
  74.703 +                                r = (y_val + 249*i_val + 159*q_val) >> 16;
  74.704 +                                g = (y_val -  70*i_val - 166*q_val) >> 16;
  74.705 +                                b = (y_val - 283*i_val + 436*q_val) >> 16;
  74.706  
  74.707 -                                y_buf[((c<<1)&6)+1]=ntsc_col[buffer->line[displine][c]&7][((c<<1)&6)+1]?0x6000:0;
  74.708 -                                y_buf[((c<<1)&6)+1]+=(buffer->line[displine][c]&8)?0x3000:0;
  74.709 -                                i_buf[((c<<1)&6)+1]=y_buf[((c<<1)&6)+1]*i_filt[((c<<1)&6)+1];
  74.710 -                                q_buf[((c<<1)&6)+1]=y_buf[((c<<1)&6)+1]*q_filt[((c<<1)&6)+1];
  74.711 -                                y_tot=y_buf[0]+y_buf[1]+y_buf[2]+y_buf[3]+y_buf[4]+y_buf[5]+y_buf[6]+y_buf[7];
  74.712 -                                i_tot=i_buf[0]+i_buf[1]+i_buf[2]+i_buf[3]+i_buf[4]+i_buf[5]+i_buf[6]+i_buf[7];
  74.713 -                                q_tot=q_buf[0]+q_buf[1]+q_buf[2]+q_buf[3]+q_buf[4]+q_buf[5]+q_buf[6]+q_buf[7];
  74.714 +                                y_buf[((c << 1) & 6) + 1] = ntsc_col[buffer->line[tandy->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 0;
  74.715 +                                y_buf[((c << 1) & 6) + 1] += (buffer->line[tandy->displine][c] & 8) ? 0x3000 : 0;
  74.716 +                                i_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * i_filt[((c << 1) & 6) + 1];
  74.717 +                                q_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * q_filt[((c << 1) & 6) + 1];
  74.718 +                                y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
  74.719 +                                i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
  74.720 +                                q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
  74.721  
  74.722 -                                y_val=y_tot>>10;
  74.723 -                                if (y_val>255) y_val=255;
  74.724 -                                y_val<<=16;
  74.725 -                                i_val=i_tot>>12;
  74.726 -                                if (i_val>39041) i_val=39041;
  74.727 -                                if (i_val<-39041) i_val=-39041;
  74.728 -                                q_val=q_tot>>12;
  74.729 -                                if (q_val>34249) q_val=34249;
  74.730 -                                if (q_val<-34249) q_val=-34249;
  74.731 +                                y_val = y_tot >> 10;
  74.732 +                                if (y_val > 255) y_val = 255;
  74.733 +                                y_val <<= 16;
  74.734 +                                i_val = i_tot >> 12;
  74.735 +                                if (i_val >  39041) i_val =  39041;
  74.736 +                                if (i_val < -39041) i_val = -39041;
  74.737 +                                q_val = q_tot >> 12;
  74.738 +                                if (q_val >  34249) q_val =  34249;
  74.739 +                                if (q_val < -34249) q_val = -34249;
  74.740  
  74.741 -                                r+=(y_val+249*i_val+159*q_val)>>16;
  74.742 -                                g+=(y_val-70*i_val-166*q_val)>>16;
  74.743 -                                b+=(y_val-283*i_val+436*q_val)>>16;
  74.744 -                                if (r>511) r=511;
  74.745 -                                if (g>511) g=511;
  74.746 -                                if (b>511) b=511;
  74.747 +                                r = (y_val + 249*i_val + 159*q_val) >> 16;
  74.748 +                                g = (y_val -  70*i_val - 166*q_val) >> 16;
  74.749 +                                b = (y_val - 283*i_val + 436*q_val) >> 16;
  74.750 +                                if (r > 511) r = 511;
  74.751 +                                if (g > 511) g = 511;
  74.752 +                                if (b > 511) b = 511;
  74.753  
  74.754 -                                ((uint32_t *)buffer32->line[displine])[c]=makecol32(r/2,g/2,b/2);
  74.755 +                                ((uint32_t *)buffer32->line[tandy->displine])[c] = makecol32(r / 2, g / 2, b / 2);
  74.756                          }
  74.757                  }
  74.758 -                sc=oldsc;
  74.759 -                if (vc==crtc[7] && !sc)
  74.760 +                tandy->sc = oldsc;
  74.761 +                if (tandy->vc == tandy->crtc[7] && !tandy->sc)
  74.762                  {
  74.763 -                        cgastat|=8;
  74.764 +                        tandy->stat |= 8;
  74.765  //                        printf("VSYNC on %i %i\n",vc,sc);
  74.766                  }
  74.767 -                displine++;
  74.768 -                if (displine>=360) displine=0;
  74.769 +                tandy->displine++;
  74.770 +                if (tandy->displine >= 360) 
  74.771 +                        tandy->displine = 0;
  74.772          }
  74.773          else
  74.774          {
  74.775 -                vidtime+=dispontime;
  74.776 -                if (cgadispon) cgastat&=~1;
  74.777 -                linepos=0;
  74.778 -                if (vsynctime)
  74.779 +                tandy->vidtime += tandy->dispontime;
  74.780 +                if (tandy->dispon) 
  74.781 +                        tandy->stat &= ~1;
  74.782 +                tandy->linepos = 0;
  74.783 +                if (tandy->vsynctime)
  74.784                  {
  74.785 -                        vsynctime--;
  74.786 -                        if (!vsynctime)
  74.787 +                        tandy->vsynctime--;
  74.788 +                        if (!tandy->vsynctime)
  74.789                          {
  74.790 -                                cgastat&=~8;
  74.791 +                                tandy->stat &= ~8;
  74.792  //                                printf("VSYNC off %i %i\n",vc,sc);
  74.793                          }
  74.794                  }
  74.795 -                if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; }
  74.796 -                if (vadj)
  74.797 +                if (tandy->sc == (tandy->crtc[11] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[11] & 31) >> 1))) 
  74.798 +                { 
  74.799 +                        tandy->con = 0; 
  74.800 +                        tandy->coff = 1; 
  74.801 +                }
  74.802 +                if (tandy->vadj)
  74.803                  {
  74.804 -                        sc++;
  74.805 -                        sc&=31;
  74.806 -                        ma=maback;
  74.807 -                        vadj--;
  74.808 -                        if (!vadj)
  74.809 +                        tandy->sc++;
  74.810 +                        tandy->sc &= 31;
  74.811 +                        tandy->ma = tandy->maback;
  74.812 +                        tandy->vadj--;
  74.813 +                        if (!tandy->vadj)
  74.814                          {
  74.815 -                                cgadispon=1;
  74.816 -                                ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
  74.817 -                                sc=0;
  74.818 +                                tandy->dispon = 1;
  74.819 +                                tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff;
  74.820 +                                tandy->sc = 0;
  74.821  //                                printf("Display on!\n");
  74.822                          }
  74.823                  }
  74.824 -                else if (sc==crtc[9] || ((crtc[8]&3)==3 && sc==(crtc[9]>>1)))
  74.825 +                else if (tandy->sc == tandy->crtc[9] || ((tandy->crtc[8] & 3) == 3 && tandy->sc == (tandy->crtc[9] >> 1)))
  74.826                  {
  74.827 -                        maback=ma;
  74.828 +                        tandy->maback = tandy->ma;
  74.829  //                        con=0;
  74.830  //                        coff=0;
  74.831 -                        sc=0;
  74.832 -                        oldvc=vc;
  74.833 -                        vc++;
  74.834 -                        vc&=127;
  74.835 -//                        printf("VC %i %i %i %i  %i\n",vc,crtc[4],crtc[6],crtc[7],cgadispon);
  74.836 -                        if (vc==crtc[6]) cgadispon=0;
  74.837 -                        if (oldvc==crtc[4])
  74.838 +                        tandy->sc = 0;
  74.839 +                        oldvc = tandy->vc;
  74.840 +                        tandy->vc++;
  74.841 +                        tandy->vc &= 127;
  74.842 +//                        printf("VC %i %i %i %i  %i\n",vc,crtc[4],crtc[6],crtc[7],tandy->dispon);
  74.843 +                        if (tandy->vc == tandy->crtc[6]) 
  74.844 +                                tandy->dispon = 0;
  74.845 +                        if (oldvc == tandy->crtc[4])
  74.846                          {
  74.847 -//                                printf("Display over at %i\n",displine);
  74.848 -                                vc=0;
  74.849 -                                vadj=crtc[5];
  74.850 -                                if (!vadj) cgadispon=1;
  74.851 -                                if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
  74.852 -                                if ((crtc[10]&0x60)==0x20) cursoron=0;
  74.853 -                                else                       cursoron=cgablink&16;
  74.854 +//                                printf("Display over at %i\n",tandy->displine);
  74.855 +                                tandy->vc = 0;
  74.856 +                                tandy->vadj = tandy->crtc[5];
  74.857 +                                if (!tandy->vadj) 
  74.858 +                                        tandy->dispon = 1;
  74.859 +                                if (!tandy->vadj) 
  74.860 +                                        tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff;
  74.861 +                                if ((tandy->crtc[10] & 0x60) == 0x20) tandy->cursoron = 0;
  74.862 +                                else                                  tandy->cursoron = tandy->blink & 16;
  74.863  //                                printf("CRTC10 %02X %i\n",crtc[10],cursoron);
  74.864                          }
  74.865 -                        if (vc==crtc[7])
  74.866 +                        if (tandy->vc == tandy->crtc[7])
  74.867                          {
  74.868 -                                cgadispon=0;
  74.869 -                                displine=0;
  74.870 -                                vsynctime=16;//(crtc[3]>>4)+1;
  74.871 -//                                printf("Vsynctime %i %02X\n",vsynctime,crtc[3]);
  74.872 -//                                cgastat|=8;
  74.873 -                                if (crtc[7])
  74.874 +                                tandy->dispon = 0;
  74.875 +                                tandy->displine = 0;
  74.876 +                                tandy->vsynctime = 16;//(crtc[3]>>4)+1;
  74.877 +//                                printf("tandy->vsynctime %i %02X\n",tandy->vsynctime,crtc[3]);
  74.878 +//                                tandy->stat|=8;
  74.879 +                                if (tandy->crtc[7])
  74.880                                  {
  74.881  //                                        printf("Lastline %i Firstline %i  %i   %i %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize);
  74.882 -                                        if (tandy_mode&1) x=(crtc[1]<<3)+16;
  74.883 -                                        else              x=(crtc[1]<<4)+16;
  74.884 -                                        lastline++;
  74.885 -                                        if (x!=xsize || (lastline-firstline)!=ysize)
  74.886 +                                        if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16;
  74.887 +                                        else                 x = (tandy->crtc[1] << 4) + 16;
  74.888 +                                        tandy->lastline++;
  74.889 +                                        if (x != xsize || (tandy->lastline - tandy->firstline) != ysize)
  74.890                                          {
  74.891 -                                                xsize=x;
  74.892 -                                                ysize=lastline-firstline;
  74.893 +                                                xsize = x;
  74.894 +                                                ysize = tandy->lastline - tandy->firstline;
  74.895  //                                                printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtc[1]);
  74.896 -                                                if (xsize<64) xsize=656;
  74.897 -                                                if (ysize<32) ysize=200;
  74.898 -                                                updatewindowsize(xsize,(ysize<<1)+16);
  74.899 +                                                if (xsize < 64) xsize = 656;
  74.900 +                                                if (ysize < 32) ysize = 200;
  74.901 +                                                updatewindowsize(xsize, (ysize << 1) + 16);
  74.902                                          }
  74.903  //                                        printf("Blit %i %i\n",firstline,lastline);
  74.904  //printf("Xsize is %i\n",xsize);
  74.905                                  startblit();
  74.906                                          if (cga_comp) 
  74.907 -                                           video_blit_memtoscreen(0, firstline-4, 0, (lastline-firstline)+8, xsize, (lastline-firstline)+8);
  74.908 +                                           video_blit_memtoscreen(0, tandy->firstline-4, 0, (tandy->lastline - tandy->firstline) + 8, xsize, (tandy->lastline - tandy->firstline) + 8);
  74.909                                          else          
  74.910 -                                           video_blit_memtoscreen_8(0, firstline-4, xsize, (lastline-firstline)+8);
  74.911 +                                           video_blit_memtoscreen_8(0, tandy->firstline-4, xsize, (tandy->lastline - tandy->firstline) + 8);
  74.912                                  endblit();
  74.913                                          frames++;
  74.914                                          video_res_x = xsize - 16;
  74.915                                          video_res_y = ysize;
  74.916 -                                        if ((tandy_array[3]&0x10) && (tandy_mode&1)) /*320x200x16*/
  74.917 +                                        if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/
  74.918                                          {
  74.919                                                  video_res_x /= 2;
  74.920                                                  video_bpp = 4;
  74.921                                          }
  74.922 -                                        else if (tandy_array[3]&0x10) /*160x200x16*/
  74.923 +                                        else if (tandy->array[3] & 0x10) /*160x200x16*/
  74.924                                          {
  74.925                                                  video_res_x /= 4;
  74.926                                                  video_bpp = 4;
  74.927                                          }
  74.928 -                                        else if (tandy_array[3]&0x08) /*640x200x4 - this implementation is a complete guess!*/
  74.929 +                                        else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/
  74.930                                             video_bpp = 2;
  74.931 -                                        else if (tandy_mode&1)
  74.932 +                                        else if (tandy->mode & 1)
  74.933                                          {
  74.934                                                  video_res_x /= 8;
  74.935 -                                                video_res_y /= crtc[9] + 1;
  74.936 +                                                video_res_y /= tandy->crtc[9] + 1;
  74.937                                                  video_bpp = 0;
  74.938                                          }
  74.939 -                                        else if (!(tandy_mode&2))
  74.940 +                                        else if (!(tandy->mode & 2))
  74.941                                          {
  74.942                                                  video_res_x /= 16;
  74.943 -                                                video_res_y /= crtc[9] + 1;
  74.944 +                                                video_res_y /= tandy->crtc[9] + 1;
  74.945                                                  video_bpp = 0;
  74.946                                          }
  74.947 -                                        else if (!(tandy_mode&16))
  74.948 +                                        else if (!(tandy->mode & 16))
  74.949                                          {
  74.950                                                  video_res_x /= 2;
  74.951                                                  video_bpp = 2;
  74.952 @@ -569,47 +634,63 @@
  74.953                                          else
  74.954                                             video_bpp = 1;                                                
  74.955                                  }
  74.956 -                                firstline=1000;
  74.957 -                                lastline=0;
  74.958 -                                cgablink++;
  74.959 +                                tandy->firstline = 1000;
  74.960 +                                tandy->lastline = 0;
  74.961 +                                tandy->blink++;
  74.962                          }
  74.963                  }
  74.964                  else
  74.965                  {
  74.966 -                        sc++;
  74.967 -                        sc&=31;
  74.968 -                        ma=maback;
  74.969 +                        tandy->sc++;
  74.970 +                        tandy->sc &= 31;
  74.971 +                        tandy->ma = tandy->maback;
  74.972                  }
  74.973 -                if ((sc==(crtc[10]&31) || ((crtc[8]&3)==3 && sc==((crtc[10]&31)>>1)))) con=1;
  74.974 +                if ((tandy->sc == (tandy->crtc[10] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[10] & 31) >> 1)))) 
  74.975 +                        tandy->con = 1;
  74.976          }
  74.977  }
  74.978  
  74.979 -int tandy_init()
  74.980 +void *tandy_init()
  74.981  {
  74.982 -        mem_sethandler(0xb8000, 0x8000, tandy_read, NULL, NULL, tandy_write, NULL, NULL,        NULL);
  74.983 -        io_sethandler(0x00a0, 0x0002, tandy_in, NULL, NULL, tandy_out, NULL, NULL, NULL);
  74.984 -        tandy_memctrl = -1;
  74.985 -        return 0;
  74.986 +        int c;
  74.987 +        int tandy_tint = -2;
  74.988 +        tandy_t *tandy = malloc(sizeof(tandy_t));
  74.989 +        memset(tandy, 0, sizeof(tandy_t));
  74.990 +
  74.991 +        tandy->memctrl = -1;
  74.992 +        
  74.993 +        for (c = 0; c < 8; c++)
  74.994 +        {
  74.995 +                i_filt[c] = 512.0 * cos((3.14 * (tandy_tint + c * 4) / 16.0) - 33.0 / 180.0);
  74.996 +                q_filt[c] = 512.0 * sin((3.14 * (tandy_tint + c * 4) / 16.0) - 33.0 / 180.0);
  74.997 +        }
  74.998 +        timer_add(tandy_poll, &tandy->vidtime, TIMER_ALWAYS_ENABLED, tandy);
  74.999 +        mem_sethandler(0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL,  tandy);
 74.1000 +        io_sethandler(0x03d0, 0x0010, tandy_in, NULL, NULL, tandy_out, NULL, NULL, tandy);
 74.1001 +        io_sethandler(0x00a0, 0x0001, tandy_in, NULL, NULL, tandy_out, NULL, NULL, tandy);
 74.1002 +        return tandy;
 74.1003  }
 74.1004  
 74.1005 -GFXCARD vid_tandy =
 74.1006 +void tandy_close(void *p)
 74.1007  {
 74.1008 +        tandy_t *tandy = (tandy_t *)p;
 74.1009 +
 74.1010 +        free(tandy->vram);
 74.1011 +        free(tandy);
 74.1012 +}
 74.1013 +
 74.1014 +void tandy_speed_changed(void *p)
 74.1015 +{
 74.1016 +        tandy_t *tandy = (tandy_t *)p;
 74.1017 +        
 74.1018 +        tandy_recalctimings(tandy);
 74.1019 +}
 74.1020 +
 74.1021 +device_t tandy_device =
 74.1022 +{
 74.1023 +        "Tandy 1000 (video)",
 74.1024          tandy_init,
 74.1025 -        /*IO at 3Cx/3Dx*/
 74.1026 -        tandy_out,
 74.1027 -        tandy_in,
 74.1028 -        /*IO at 3Ax/3Bx*/
 74.1029 -        video_out_null,
 74.1030 -        video_in_null,
 74.1031 -
 74.1032 -        tandy_poll,
 74.1033 -        tandy_recalctimings,
 74.1034 -
 74.1035 -        video_write_null,
 74.1036 -        video_write_null,
 74.1037 -        tandy_write,
 74.1038 -
 74.1039 -        video_read_null,
 74.1040 -        video_read_null,
 74.1041 -        tandy_read
 74.1042 +        tandy_close,
 74.1043 +        tandy_speed_changed,
 74.1044 +        NULL
 74.1045  };
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/src/vid_tandy.h	Mon Jun 24 20:42:35 2013 +0100
    75.3 @@ -0,0 +1,1 @@
    75.4 +extern device_t tandy_device;
    76.1 --- a/src/vid_tkd8001_ramdac.c	Tue Jun 04 20:52:17 2013 +0100
    76.2 +++ b/src/vid_tkd8001_ramdac.c	Mon Jun 24 20:42:35 2013 +0100
    76.3 @@ -7,29 +7,29 @@
    76.4  static int tkd8001_state=0;
    76.5  static uint8_t tkd8001_ctrl;
    76.6  
    76.7 -void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv)
    76.8 +void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga)
    76.9  {
   76.10  //        pclog("OUT RAMDAC %04X %02X %04X:%04X\n",addr,val,CS,pc);
   76.11          switch (addr)
   76.12          {
   76.13                  case 0x3C6:
   76.14 -                if (tkd8001_state == 4)
   76.15 +                if (ramdac->state == 4)
   76.16                  {
   76.17 -                        tkd8001_state = 0;
   76.18 -                        tkd8001_ctrl = val;
   76.19 -                        switch (val>>5)
   76.20 +                        ramdac->state = 0;
   76.21 +                        ramdac->ctrl = val;
   76.22 +                        switch (val >> 5)
   76.23                          {
   76.24                                  case 0: case 1: case 2: case 3:
   76.25 -                                bpp = 8;
   76.26 +                                svga->bpp = 8;
   76.27                                  break;
   76.28                                  case 5:
   76.29 -                                bpp = 15;
   76.30 +                                svga->bpp = 15;
   76.31                                  break;
   76.32                                  case 6:
   76.33 -                                bpp = 24;
   76.34 +                                svga->bpp = 24;
   76.35                                  break;
   76.36                                  case 7:
   76.37 -                                bpp = 16;
   76.38 +                                svga->bpp = 16;
   76.39                                  break;
   76.40                          }
   76.41                          return;
   76.42 @@ -37,28 +37,28 @@
   76.43                 // tkd8001_state = 0;
   76.44                  break;
   76.45                  case 0x3C7: case 0x3C8: case 0x3C9:
   76.46 -                tkd8001_state = 0;
   76.47 +                ramdac->state = 0;
   76.48                  break;
   76.49          }
   76.50 -        svga_out(addr, val, NULL);
   76.51 +        svga_out(addr, val, svga);
   76.52  }
   76.53  
   76.54 -uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv)
   76.55 +uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga)
   76.56  {
   76.57  //        pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc);
   76.58          switch (addr)
   76.59          {
   76.60                  case 0x3C6:
   76.61 -                if (tkd8001_state == 4)
   76.62 +                if (ramdac->state == 4)
   76.63                  {
   76.64                          //tkd8001_state = 0;
   76.65 -                        return tkd8001_ctrl;
   76.66 +                        return ramdac->ctrl;
   76.67                  }
   76.68 -                tkd8001_state++;
   76.69 +                ramdac->state++;
   76.70                  break;
   76.71                  case 0x3C7: case 0x3C8: case 0x3C9:
   76.72 -                tkd8001_state = 0;
   76.73 +                ramdac->state = 0;
   76.74                  break;
   76.75          }
   76.76 -        return svga_in(addr, NULL);
   76.77 +        return svga_in(addr, svga);
   76.78  }
    77.1 --- a/src/vid_tkd8001_ramdac.h	Tue Jun 04 20:52:17 2013 +0100
    77.2 +++ b/src/vid_tkd8001_ramdac.h	Mon Jun 24 20:42:35 2013 +0100
    77.3 @@ -1,2 +1,8 @@
    77.4 -void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv);
    77.5 -uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv);
    77.6 +typedef struct tkd8001_ramdac_t
    77.7 +{
    77.8 +        int state;
    77.9 +        uint8_t ctrl;
   77.10 +} tkd8001_ramdac_t;
   77.11 +
   77.12 +void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga);
   77.13 +uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga);
    78.1 --- a/src/vid_tvga.c	Tue Jun 04 20:52:17 2013 +0100
    78.2 +++ b/src/vid_tvga.c	Mon Jun 24 20:42:35 2013 +0100
    78.3 @@ -1,20 +1,52 @@
    78.4  /*Trident TVGA (8900D) emulation*/
    78.5 +#include <stdlib.h>
    78.6  #include "ibm.h"
    78.7 +#include "device.h"
    78.8  #include "io.h"
    78.9  #include "mem.h"
   78.10  #include "video.h"
   78.11  #include "vid_svga.h"
   78.12  #include "vid_svga_render.h"
   78.13  #include "vid_tkd8001_ramdac.h"
   78.14 +#include "vid_tvga.h"
   78.15  
   78.16 -void tvga_recalcmapping();
   78.17 +typedef struct tvga_t
   78.18 +{
   78.19 +        svga_t svga;
   78.20 +        tkd8001_ramdac_t ramdac;
   78.21  
   78.22 -uint8_t trident3d8,trident3d9;
   78.23 -int tridentoldmode;
   78.24 -uint8_t tridentoldctrl2,tridentnewctrl2;
   78.25 -uint8_t tridentdac;
   78.26 +        struct
   78.27 +        {
   78.28 +        	uint16_t src_x, src_y;
   78.29 +        	uint16_t dst_x, dst_y;
   78.30 +        	uint16_t size_x, size_y;
   78.31 +        	uint16_t fg_col, bg_col;
   78.32 +        	uint8_t rop;
   78.33 +        	uint16_t flags;
   78.34 +        	uint8_t pattern[0x80];
   78.35 +        	int command;
   78.36 +        	int offset;
   78.37 +        	uint8_t ger22;
   78.38 +	
   78.39 +        	int x, y;
   78.40 +        	uint32_t src, dst, src_old, dst_old;
   78.41 +        	int pat_x, pat_y;
   78.42 +        	int use_src;
   78.43 +	
   78.44 +        	int pitch, bpp;
   78.45  
   78.46 -uint32_t tvga_linear_base, tvga_linear_size;
   78.47 +                uint16_t tvga_pattern[8][8];
   78.48 +        } accel;
   78.49 +
   78.50 +        uint8_t tvga_3d8, tvga_3d9;
   78.51 +        int oldmode;
   78.52 +        uint8_t oldctrl2,newctrl2;
   78.53 +
   78.54 +        uint32_t linear_base, linear_size;
   78.55 +} tvga_t;
   78.56 +
   78.57 +void tvga_recalcmapping(tvga_t *tvga);
   78.58 +
   78.59  
   78.60  uint8_t tvga_accel_read(uint32_t addr, void *priv);
   78.61  uint16_t tvga_accel_read_w(uint32_t addr, void *priv);
   78.62 @@ -27,25 +59,39 @@
   78.63  
   78.64  void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv);
   78.65  
   78.66 -void tvga_out(uint16_t addr, uint8_t val, void *priv)
   78.67 +void tvga_out(uint16_t addr, uint8_t val, void *p)
   78.68  {
   78.69 +        tvga_t *tvga = (tvga_t *)p;
   78.70 +        svga_t *svga = &tvga->svga;
   78.71 +
   78.72          uint8_t old;
   78.73  
   78.74  //	pclog("tvga_out : %04X %02X  %04X:%04X  %i\n", addr, val, CS,pc, bpp);
   78.75 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   78.76 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60;
   78.77  
   78.78          switch (addr)
   78.79          {
   78.80                  case 0x3C5:
   78.81 -                switch (seqaddr&0xF)
   78.82 +                switch (svga->seqaddr & 0xf)
   78.83                  {
   78.84 -                        case 0xB: tridentoldmode=1; break;
   78.85 -                        case 0xC: if (seqregs[0xE]&0x80) seqregs[0xC]=val; break;
   78.86 -                        case 0xD: if (tridentoldmode) { tridentoldctrl2=val; rowdbl=val&0x10; } else tridentnewctrl2=val; break;
   78.87 +                        case 0xB: 
   78.88 +                        tvga->oldmode=1; 
   78.89 +                        break;
   78.90 +                        case 0xC: 
   78.91 +                        if (svga->seqregs[0xe] & 0x80) 
   78.92 +                        svga->seqregs[0xc] = val; 
   78.93 +                        break;
   78.94 +                        case 0xd: 
   78.95 +                        if (tvga->oldmode) 
   78.96 +                                tvga->oldctrl2 = val; 
   78.97 +                        else 
   78.98 +                                tvga->newctrl2=val; 
   78.99 +                        break;
  78.100                          case 0xE:
  78.101 -                        seqregs[0xE]=val^2;
  78.102 -                        svgawbank=(seqregs[0xE]&0xF)*65536;
  78.103 -                        if (!(gdcreg[0xF]&1)) svgarbank=svgawbank;
  78.104 +                        svga->seqregs[0xe] = val ^ 2;
  78.105 +                        svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
  78.106 +                        if (!(svga->gdcreg[0xf] & 1)) 
  78.107 +                                svga->read_bank = svga->write_bank;
  78.108                          return;
  78.109                  }
  78.110                  break;
  78.111 @@ -53,56 +99,56 @@
  78.112                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  78.113  		if (gfxcard != GFX_TGUI9440)
  78.114  		{
  78.115 -                	tkd8001_ramdac_out(addr, val, NULL);
  78.116 +                	tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga);
  78.117                  	return;
  78.118  		}
  78.119  		break;
  78.120  
  78.121                  case 0x3CF:
  78.122 -                switch (gdcaddr&15)
  78.123 +                switch (svga->gdcaddr & 15)
  78.124                  {
  78.125  			case 0x6:
  78.126 -			if (gdcreg[6] != val)
  78.127 +			if (svga->gdcreg[6] != val)
  78.128  			{
  78.129 -				gdcreg[6] = val;
  78.130 -				tvga_recalcmapping();
  78.131 +				svga->gdcreg[6] = val;
  78.132 +				tvga_recalcmapping(tvga);
  78.133  			}
  78.134  			return;
  78.135  			
  78.136                          case 0xE:
  78.137 -                        gdcreg[0xE]=val^2;
  78.138 -                        if ((gdcreg[0xF]&1)==1)
  78.139 -                           svgarbank=(gdcreg[0xE]&0xF)*65536;
  78.140 +                        svga->gdcreg[0xe] = val ^ 2;
  78.141 +                        if ((svga->gdcreg[0xf] & 1) == 1)
  78.142 +                           svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 65536;
  78.143                          break;
  78.144                          case 0xF:
  78.145 -                        if (val&1) svgarbank=(gdcreg[0xE] &0xF)*65536;
  78.146 -                        else       svgarbank=(seqregs[0xE]&0xF)*65536;
  78.147 -                        svgawbank=(seqregs[0xE]&0xF)*65536;
  78.148 +                        if (val & 1) svga->read_bank = (svga->gdcreg[0xe]  & 0xf)  *65536;
  78.149 +                        else         svga->read_bank = (svga->seqregs[0xe] & 0xf)  *65536;
  78.150 +                        svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
  78.151                          break;
  78.152                  }
  78.153                  break;
  78.154                  case 0x3D4:
  78.155 -		if (gfxcard == GFX_TGUI9440)	crtcreg = val & 0x7f;
  78.156 -		else				crtcreg = val & 0x3f;
  78.157 +		if (gfxcard == GFX_TGUI9440)	svga->crtcreg = val & 0x7f;
  78.158 +		else				svga->crtcreg = val & 0x3f;
  78.159                  return;
  78.160                  case 0x3D5:
  78.161 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
  78.162 -                old=crtc[crtcreg];
  78.163 -                crtc[crtcreg]=val;
  78.164 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
  78.165 +                old = svga->crtc[svga->crtcreg];
  78.166 +                svga->crtc[svga->crtcreg] = val;
  78.167                  //if (crtcreg!=0xE && crtcreg!=0xF) pclog("CRTC R%02X = %02X\n",crtcreg,val);
  78.168 -                if (old!=val)
  78.169 +                if (old != val)
  78.170                  {
  78.171 -                        if (crtcreg<0xE || crtcreg>0x10)
  78.172 +                        if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
  78.173                          {
  78.174 -                                fullchange=changeframecount;
  78.175 -                                svga_recalctimings();
  78.176 +                                fullchange = changeframecount;
  78.177 +                                svga_recalctimings(svga);
  78.178                          }
  78.179                  }
  78.180 -                switch (crtcreg)
  78.181 +                switch (svga->crtcreg)
  78.182                  {
  78.183  			case 0x21:
  78.184  			if (old != val)
  78.185 -				tvga_recalcmapping();
  78.186 +				tvga_recalcmapping(tvga);
  78.187  			break;
  78.188  
  78.189  
  78.190 @@ -111,262 +157,285 @@
  78.191  			if (gfxcard != GFX_TGUI9440)
  78.192  				break;
  78.193  			
  78.194 -			if ((val & 0xc) == 4)	bpp = 16;
  78.195 -			else if (!(val & 0xc))	bpp = 8;
  78.196 -			else			bpp = 24;
  78.197 +			if ((val & 0xc) == 4)	svga->bpp = 16;
  78.198 +			else if (!(val & 0xc))	svga->bpp = 8;
  78.199 +			else			svga->bpp = 24;
  78.200  			break;
  78.201  
  78.202  			case 0x40: case 0x41: case 0x42: case 0x43:
  78.203  			case 0x44: case 0x45: case 0x46: case 0x47:
  78.204 -			svga_hwcursor.x = (crtc[0x40] | (crtc[0x41] << 8)) & 0x7ff;
  78.205 -			svga_hwcursor.y = (crtc[0x42] | (crtc[0x43] << 8)) & 0x7ff;
  78.206 -			svga_hwcursor.xoff = crtc[0x46] & 0x3f;
  78.207 -			svga_hwcursor.yoff = crtc[0x47] & 0x3f;
  78.208 -			svga_hwcursor.addr = (crtc[0x44] << 10) | ((crtc[0x45] & 0x7) << 18) | (svga_hwcursor.yoff * 8);
  78.209 +			svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff;
  78.210 +			svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff;
  78.211 +			svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f;
  78.212 +			svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f;
  78.213 +			svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x7) << 18) | (svga->hwcursor.yoff * 8);
  78.214  			break;
  78.215  			
  78.216  			case 0x50:
  78.217 -			svga_hwcursor.ena = val & 0x80;
  78.218 +			svga->hwcursor.ena = val & 0x80;
  78.219  			break;
  78.220  		}
  78.221                  return;
  78.222                  case 0x3D8:
  78.223 -                trident3d8=val;
  78.224 -                if (gdcreg[0xF]&4)
  78.225 +                tvga->tvga_3d8 = val;
  78.226 +                if (svga->gdcreg[0xf] & 4)
  78.227                  {
  78.228 -                        svgawbank=(val&0x1F)*65536;
  78.229 +                        svga->write_bank = (val & 0x1f) * 65536;
  78.230  //                                pclog("SVGAWBANK 3D8 %08X %04X:%04X\n",svgawbank,CS,pc);
  78.231 -                        if (!(gdcreg[0xF]&1))
  78.232 +                        if (!(svga->gdcreg[0xf] & 1))
  78.233                          {
  78.234 -                                svgarbank=(val&0x1F)*65536;
  78.235 +                                svga->read_bank = (val & 0x1f) * 65536;
  78.236  //                                        pclog("SVGARBANK 3D8 %08X %04X:%04X\n",svgarbank,CS,pc);
  78.237                          }
  78.238                  }
  78.239                  return;
  78.240                  case 0x3D9:
  78.241 -                trident3d9=val;
  78.242 -                if ((gdcreg[0xF]&5)==5)
  78.243 +                tvga->tvga_3d9=val;
  78.244 +                if ((svga->gdcreg[0xf] & 5) == 5)
  78.245                  {
  78.246 -                        svgarbank=(val&0x1F)*65536;
  78.247 +                        svga->read_bank = (val & 0x1F) * 65536;
  78.248  //                                pclog("SVGARBANK 3D9 %08X %04X:%04X\n",svgarbank,CS,pc);
  78.249                  }
  78.250                  return;
  78.251          }
  78.252 -        svga_out(addr, val, priv);
  78.253 +        svga_out(addr, val, svga);
  78.254  }
  78.255  
  78.256 -uint8_t tvga_in(uint16_t addr, void *priv)
  78.257 +uint8_t tvga_in(uint16_t addr, void *p)
  78.258  {
  78.259 +        tvga_t *tvga = (tvga_t *)p;
  78.260 +        svga_t *svga = &tvga->svga;
  78.261 +
  78.262  //        if (addr != 0x3da) pclog("tvga_in : %04X  %04X:%04X\n", addr, CS,pc);
  78.263          
  78.264 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
  78.265 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60;
  78.266          
  78.267          switch (addr)
  78.268          {
  78.269                  case 0x3C5:
  78.270 -                if ((seqaddr&0xF)==0xB)
  78.271 +                if ((svga->seqaddr & 0xf) == 0xb)
  78.272                  {
  78.273  //                        printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP));
  78.274 -                        tridentoldmode=0;
  78.275 +                        tvga->oldmode = 0;
  78.276                          if (gfxcard == GFX_TVGA) return 0x33; /*TVGA8900D*/
  78.277                          else                     return 0xe3; /*TGUI9440AGi*/
  78.278                  }
  78.279 -                if ((seqaddr&0xF)==0xC)
  78.280 +                if ((svga->seqaddr & 0xf) == 0xc)
  78.281                  {
  78.282  //                        printf("Read Trident Power Up 1 %04X:%04X %04X\n",CS,pc,readmemw(ss,SP));
  78.283  //                        return 0x20; /*2 DRAM banks*/
  78.284                  }
  78.285 -                if ((seqaddr&0xF)==0xD)
  78.286 +                if ((svga->seqaddr & 0xf) == 0xd)
  78.287                  {
  78.288 -                        if (tridentoldmode) return tridentoldctrl2;
  78.289 -                        return tridentnewctrl2;
  78.290 +                        if (tvga->oldmode) return tvga->oldctrl2;
  78.291 +                        return tvga->newctrl2;
  78.292                  }
  78.293                  break;
  78.294                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  78.295  		if (gfxcard != GFX_TGUI9440)
  78.296 -                	return tkd8001_ramdac_in(addr, NULL);
  78.297 +                	return tkd8001_ramdac_in(addr, &tvga->ramdac, svga);
  78.298                  break;
  78.299 -                case 0x3CD: /*Banking*/
  78.300 -                return svgaseg;
  78.301                  case 0x3D4:
  78.302 -                return crtcreg;
  78.303 +                return svga->crtcreg;
  78.304                  case 0x3D5:
  78.305 -                return crtc[crtcreg];
  78.306 +                return svga->crtc[svga->crtcreg];
  78.307                  case 0x3d8:
  78.308 -		return trident3d8;
  78.309 +		return tvga->tvga_3d8;
  78.310  		case 0x3d9:
  78.311 -		return trident3d9;
  78.312 +		return tvga->tvga_3d9;
  78.313          }
  78.314 -        return svga_in(addr, priv);
  78.315 +        return svga_in(addr, svga);
  78.316  }
  78.317  
  78.318 -void tvga_recalctimings()
  78.319 +void tvga_recalctimings(svga_t *svga)
  78.320  {
  78.321 -        if (!svga_rowoffset) svga_rowoffset=0x100; /*This is the only sensible way I can see this being handled,
  78.322 -                                                     given that TVGA8900D has no overflow bits.
  78.323 -                                                     Some sort of overflow is required for 320x200x24 and 1024x768x16*/
  78.324 +        tvga_t *tvga = (tvga_t *)svga->p;
  78.325 +        if (!svga->rowoffset) svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled,
  78.326 +                                                         given that TVGA8900D has no overflow bits.
  78.327 +                                                         Some sort of overflow is required for 320x200x24 and 1024x768x16*/
  78.328  
  78.329 -        if ((crtc[0x1E]&0xA0)==0xA0) svga_ma|=0x10000;
  78.330 -        if ((crtc[0x27]&0x01)==0x01) svga_ma|=0x20000;
  78.331 -        if ((crtc[0x27]&0x02)==0x02) svga_ma|=0x40000;
  78.332 +        if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000;
  78.333 +        if ((svga->crtc[0x27] & 0x01) == 0x01) svga->ma_latch |= 0x20000;
  78.334 +        if ((svga->crtc[0x27] & 0x02) == 0x02) svga->ma_latch |= 0x40000;
  78.335          
  78.336 -        if (tridentoldctrl2 & 0x10)
  78.337 +        if (tvga->oldctrl2 & 0x10)
  78.338          {
  78.339 -                svga_rowoffset<<=1;
  78.340 -                svga_ma<<=1;
  78.341 +                svga->rowoffset <<= 1;
  78.342 +                svga->ma_latch <<= 1;
  78.343          }
  78.344 -        if (tridentoldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/
  78.345 -           svga_lowres=0;
  78.346 +        if (tvga->oldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/
  78.347 +           svga->lowres=0;
  78.348          if (gfxcard == GFX_TGUI9440)
  78.349 -	   svga_lowres = !(crtc[0x2a] & 0x40); 
  78.350 +	   svga->lowres = !(svga->crtc[0x2a] & 0x40); 
  78.351  	   
  78.352 -        if (gdcreg[0xF] & 8)
  78.353 +        if (svga->gdcreg[0xf] & 8)
  78.354          {
  78.355 -                svga_htotal<<=1;
  78.356 -                svga_hdisp<<=1;
  78.357 +                svga->htotal <<= 1;
  78.358 +                svga->hdisp <<= 1;
  78.359          }
  78.360 -        svga_interlace = crtc[0x1E] & 4;
  78.361 -        if (svga_interlace)
  78.362 -           svga_rowoffset >>= 1;
  78.363 +        svga->interlace = svga->crtc[0x1e] & 4;
  78.364 +        if (svga->interlace)
  78.365 +           svga->rowoffset >>= 1;
  78.366          
  78.367 -        switch (((svga_miscout>>2)&3) | ((tridentnewctrl2<<2)&4))
  78.368 +        switch (((svga->miscout >> 2) & 3) | ((tvga->newctrl2 << 2) & 4))
  78.369          {
  78.370 -                case 2: svga_clock = cpuclock/44900000.0; break;
  78.371 -                case 3: svga_clock = cpuclock/36000000.0; break;
  78.372 -                case 4: svga_clock = cpuclock/57272000.0; break;
  78.373 -                case 5: svga_clock = cpuclock/65000000.0; break;
  78.374 -                case 6: svga_clock = cpuclock/50350000.0; break;
  78.375 -                case 7: svga_clock = cpuclock/40000000.0; break;
  78.376 +                case 2: svga->clock = cpuclock/44900000.0; break;
  78.377 +                case 3: svga->clock = cpuclock/36000000.0; break;
  78.378 +                case 4: svga->clock = cpuclock/57272000.0; break;
  78.379 +                case 5: svga->clock = cpuclock/65000000.0; break;
  78.380 +                case 6: svga->clock = cpuclock/50350000.0; break;
  78.381 +                case 7: svga->clock = cpuclock/40000000.0; break;
  78.382          }
  78.383  
  78.384 -        if ((tridentoldctrl2 & 0x10) || (gfxcard == GFX_TGUI9440 && (crtc[0x2a] & 0x40)))
  78.385 +        if ((tvga->oldctrl2 & 0x10) || (gfxcard == GFX_TGUI9440 && (svga->crtc[0x2a] & 0x40)))
  78.386          {
  78.387 -                switch (bpp)
  78.388 +                switch (svga->bpp)
  78.389                  {
  78.390                          case 8: 
  78.391 -                        svga_render = svga_render_8bpp_highres; 
  78.392 +                        svga->render = svga_render_8bpp_highres; 
  78.393                          break;
  78.394                          case 15: 
  78.395 -                        svga_render = svga_render_15bpp_highres; 
  78.396 +                        svga->render = svga_render_15bpp_highres; 
  78.397                          break;
  78.398                          case 16: 
  78.399 -                        svga_render = svga_render_16bpp_highres; 
  78.400 +                        svga->render = svga_render_16bpp_highres; 
  78.401                          break;
  78.402                          case 24: 
  78.403 -                        svga_render = svga_render_24bpp_highres; 
  78.404 +                        svga->render = svga_render_24bpp_highres; 
  78.405                          break;
  78.406                          case 32: 
  78.407 -                        svga_render = svga_render_32bpp_highres; 
  78.408 +                        svga->render = svga_render_32bpp_highres; 
  78.409                          break;
  78.410                  }
  78.411          }
  78.412  }
  78.413  
  78.414 -void tvga_recalcmapping()
  78.415 +void tvga_recalcmapping(tvga_t *tvga)
  78.416  {
  78.417 -	pclog("tvga_recalcmapping : %02X %02X\n", crtc[0x21], gdcreg[6]);
  78.418 -        mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    NULL);
  78.419 -	mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    NULL);
  78.420 -	mem_removehandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL,    NULL);
  78.421 +        svga_t *svga = &tvga->svga;
  78.422 +        
  78.423 +	pclog("tvga_recalcmapping : %02X %02X\n", svga->crtc[0x21], svga->gdcreg[6]);
  78.424 +        mem_removehandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    svga);
  78.425 +	mem_removehandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    svga);
  78.426 +	mem_removehandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL,    tvga);
  78.427  
  78.428 -	if (crtc[0x21] & 0x20)
  78.429 +	if (svga->crtc[0x21] & 0x20)
  78.430  	{
  78.431 -		tvga_linear_base = ((crtc[0x21] & 0xf) | ((crtc[0x21] >> 2) & 0x30)) << 20;
  78.432 -		tvga_linear_size = (crtc[0x21] & 0x10) ? 0x200000 : 0x100000;
  78.433 -		mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    NULL);
  78.434 -		pclog("Trident linear framebuffer at %08X - size %06X\n", tvga_linear_base, tvga_linear_size);
  78.435 -		mem_sethandler(0xbc000, 0x4000, tvga_accel_read, tvga_accel_read_w, tvga_accel_read_l, tvga_accel_write, tvga_accel_write_w, tvga_accel_write_l,    NULL);
  78.436 +		tvga->linear_base = ((svga->crtc[0x21] & 0xf) | ((svga->crtc[0x21] >> 2) & 0x30)) << 20;
  78.437 +		tvga->linear_size = (svga->crtc[0x21] & 0x10) ? 0x200000 : 0x100000;
  78.438 +		mem_sethandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    svga);
  78.439 +		pclog("Trident linear framebuffer at %08X - size %06X\n", tvga->linear_base, tvga->linear_size);
  78.440 +		mem_sethandler(0xbc000, 0x4000, tvga_accel_read, tvga_accel_read_w, tvga_accel_read_l, tvga_accel_write, tvga_accel_write_w, tvga_accel_write_l,    tvga);
  78.441  	}
  78.442  	else
  78.443  	{
  78.444  //                                pclog("Write mapping %02X\n", val);
  78.445 -                switch (gdcreg[6] & 0xC)
  78.446 +                switch (svga->gdcreg[6] & 0xC)
  78.447                  {
  78.448                          case 0x0: /*128k at A0000*/
  78.449 -                        mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    NULL);
  78.450 +                        mem_sethandler(0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    svga);
  78.451                          break;
  78.452                          case 0x4: /*64k at A0000*/
  78.453 -                        mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    NULL);
  78.454 -                        mem_sethandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL,    NULL);
  78.455 +                        mem_sethandler(0xa0000, 0x10000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    svga);
  78.456 +                        mem_sethandler(0xbc000, 0x4000, tvga_accel_read, NULL, NULL, tvga_accel_write, NULL, NULL,    tvga);
  78.457                          break;
  78.458                          case 0x8: /*32k at B0000*/
  78.459 -                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    NULL);
  78.460 +                        mem_sethandler(0xb0000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    svga);
  78.461                          break;
  78.462                          case 0xC: /*32k at B8000*/
  78.463 -                	mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    NULL);
  78.464 +                	mem_sethandler(0xb8000, 0x08000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel,    svga);
  78.465                  	break;
  78.466  		}
  78.467          }
  78.468  }
  78.469  
  78.470 -void tvga_hwcursor_draw(int displine)
  78.471 +void tvga_hwcursor_draw(svga_t *svga, int displine)
  78.472  {
  78.473 -//        int x;
  78.474          uint32_t dat[2];
  78.475          int xx;
  78.476 -        int offset = svga_hwcursor_latch.x - svga_hwcursor_latch.xoff;
  78.477 +        int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
  78.478          
  78.479 -//        pclog("HWcursor %i %i\n", svga_hwcursor_latch.x, svga_hwcursor_latch.y);
  78.480 -//        for (x = 0; x < 32; x += 32)
  78.481 -//        {
  78.482 -                dat[0] = (vram[svga_hwcursor_latch.addr]     << 24) | (vram[svga_hwcursor_latch.addr + 1] << 16) | (vram[svga_hwcursor_latch.addr + 2] << 8) | vram[svga_hwcursor_latch.addr + 3];
  78.483 -                dat[1] = (vram[svga_hwcursor_latch.addr + 4] << 24) | (vram[svga_hwcursor_latch.addr + 5] << 16) | (vram[svga_hwcursor_latch.addr + 6] << 8) | vram[svga_hwcursor_latch.addr + 7];
  78.484 -                for (xx = 0; xx < 32; xx++)
  78.485 +        dat[0] = (svga->vram[svga->hwcursor_latch.addr]     << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
  78.486 +        dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7];
  78.487 +        for (xx = 0; xx < 32; xx++)
  78.488 +        {
  78.489 +                if (offset >= svga->hwcursor_latch.x)
  78.490                  {
  78.491 -                        if (offset >= svga_hwcursor_latch.x)
  78.492 -                        {
  78.493 -                                if (!(dat[0] & 0x80000000))
  78.494 -                                   ((uint32_t *)buffer32->line[displine])[offset + 32]  = (dat[1] & 0x80000000) ? 0xffffff : 0;
  78.495 -                                else if (dat[1] & 0x80000000)
  78.496 -                                   ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
  78.497 -//                                pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]);
  78.498 -                        }
  78.499 +                        if (!(dat[0] & 0x80000000))
  78.500 +                                ((uint32_t *)buffer32->line[displine])[offset + 32]  = (dat[1] & 0x80000000) ? 0xffffff : 0;
  78.501 +                        else if (dat[1] & 0x80000000)
  78.502 +                                ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
  78.503 +//                        pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]);
  78.504 +                }
  78.505                             
  78.506 -                        offset++;
  78.507 -                        dat[0] <<= 1;
  78.508 -                        dat[1] <<= 1;
  78.509 -                }
  78.510 -                svga_hwcursor_latch.addr += 8;
  78.511 -//        }
  78.512 +                offset++;
  78.513 +                dat[0] <<= 1;
  78.514 +                dat[1] <<= 1;
  78.515 +        }
  78.516 +        svga->hwcursor_latch.addr += 8;
  78.517  }
  78.518  
  78.519 -int tvga_init()
  78.520 +void *tvga8900d_init()
  78.521  {
  78.522 -        svga_recalctimings_ex = tvga_recalctimings;
  78.523 -        svga_hwcursor_draw    = tvga_hwcursor_draw;
  78.524 -        if (gfxcard == GFX_TVGA) 
  78.525 -	{
  78.526 -		vrammask = 0xfffff;
  78.527 -		svga_vram_limit = 1 << 20; /*1mb - chip supports 2mb, but drivers are buggy*/
  78.528 -	}
  78.529 -        else
  78.530 -	{
  78.531 -		vrammask = 0x1fffff;
  78.532 -		svga_vram_limit = 1 << 21; /*2mb*/
  78.533 -	}
  78.534 -        return svga_init();
  78.535 +        tvga_t *tvga = malloc(sizeof(tvga_t));
  78.536 +        memset(tvga, 0, sizeof(tvga_t));
  78.537 +        
  78.538 +        svga_init(&tvga->svga, tvga, 1 << 20, /*1mb - chip supports 2mb, but drivers are buggy*/
  78.539 +                   tvga_recalctimings,
  78.540 +                   tvga_in, tvga_out,
  78.541 +                   NULL);
  78.542 +
  78.543 +        io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga);
  78.544 +
  78.545 +        return tvga;
  78.546 +}
  78.547 +void *tgui9440_init()
  78.548 +{
  78.549 +        tvga_t *tvga = malloc(sizeof(tvga_t));
  78.550 +        memset(tvga, 0, sizeof(tvga_t));
  78.551 +        
  78.552 +        svga_init(&tvga->svga, tvga, 1 << 21, /*2mb*/
  78.553 +                   tvga_recalctimings,
  78.554 +                   tvga_in, tvga_out,
  78.555 +                   tvga_hwcursor_draw);
  78.556 +
  78.557 +        io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga);
  78.558 +
  78.559 +        return tvga;
  78.560  }
  78.561  
  78.562 -struct tvga_accel
  78.563 +void tvga_close(void *p)
  78.564  {
  78.565 -	uint16_t src_x, src_y;
  78.566 -	uint16_t dst_x, dst_y;
  78.567 -	uint16_t size_x, size_y;
  78.568 -	uint16_t fg_col, bg_col;
  78.569 -	uint8_t rop;
  78.570 -	uint16_t flags;
  78.571 -	uint8_t pattern[0x80];
  78.572 -	int command;
  78.573 -	int offset;
  78.574 -	uint8_t ger22;
  78.575 -	
  78.576 -	int x, y;
  78.577 -	uint32_t src, dst, src_old, dst_old;
  78.578 -	int pat_x, pat_y;
  78.579 -	int use_src;
  78.580 -	
  78.581 -	int pitch, bpp;
  78.582 -} tvga_accel;
  78.583 +        tvga_t *tvga = (tvga_t *)p;
  78.584 +
  78.585 +        svga_close(&tvga->svga);
  78.586 +        
  78.587 +        free(tvga);
  78.588 +}
  78.589 +
  78.590 +void tvga_speed_changed(void *p)
  78.591 +{
  78.592 +        tvga_t *tvga = (tvga_t *)p;
  78.593 +        
  78.594 +        svga_recalctimings(&tvga->svga);
  78.595 +}
  78.596 +
  78.597 +device_t tvga8900d_device =
  78.598 +{
  78.599 +        "Trident TVGA 8900D",
  78.600 +        tvga8900d_init,
  78.601 +        tvga_close,
  78.602 +        tvga_speed_changed,
  78.603 +        svga_add_status_info
  78.604 +};
  78.605 +device_t tgui9440_device =
  78.606 +{
  78.607 +        "Trident TGUI 9440",
  78.608 +        tgui9440_init,
  78.609 +        tvga_close,
  78.610 +        tvga_speed_changed,
  78.611 +        svga_add_status_info
  78.612 +};
  78.613  
  78.614  enum
  78.615  {
  78.616 @@ -385,7 +454,7 @@
  78.617  	TGUI_SOLIDFILL = 0x4000	/*Pattern all zero?*/
  78.618  };
  78.619  
  78.620 -#define READ(addr, dat) if (tvga_accel.bpp == 0) dat = vram[addr & 0x1fffff]; \
  78.621 +#define READ(addr, dat) if (tvga->accel.bpp == 0) dat = svga->vram[addr & 0x1fffff]; \
  78.622                          else                     dat = vram_w[addr & 0xfffff];
  78.623                          
  78.624  #define MIX() do \
  78.625 @@ -396,68 +465,67 @@
  78.626  			d=(dst_dat & (1<<c)) ? 1:0;			\
  78.627                         	if (src_dat & (1<<c)) d|=2;			\
  78.628                 	        if (pat_dat & (1<<c)) d|=4;			\
  78.629 -                        if (tvga_accel.rop & (1<<d)) out|=(1<<c);	\
  78.630 +                        if (tvga->accel.rop & (1<<d)) out|=(1<<c);	\
  78.631  	        }							\
  78.632  	} while (0)
  78.633  
  78.634 -#define WRITE(addr, dat)        if (tvga_accel.bpp == 0)                                                \
  78.635 +#define WRITE(addr, dat)        if (tvga->accel.bpp == 0)                                                \
  78.636                                  {                                                                       \
  78.637 -                                        vram[addr & 0x1fffff] = dat;                                    \
  78.638 -                                        changedvram[((addr) & 0x1fffff) >> 10] = changeframecount;      \
  78.639 +                                        svga->vram[addr & 0x1fffff] = dat;                                    \
  78.640 +                                        svga->changedvram[((addr) & 0x1fffff) >> 10] = changeframecount;      \
  78.641                                  }                                                                       \
  78.642                                  else                                                                    \
  78.643                                  {                                                                       \
  78.644                                          vram_w[addr & 0xfffff] = dat;                                   \
  78.645 -                                        changedvram[((addr) & 0xfffff) >> 9] = changeframecount;        \
  78.646 +                                        svga->changedvram[((addr) & 0xfffff) >> 9] = changeframecount;        \
  78.647                                  }
  78.648                                  
  78.649 -static uint16_t tvga_pattern[8][8];
  78.650 -
  78.651  void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv);
  78.652  void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv);
  78.653  
  78.654 -void tvga_accel_command(int count, uint32_t cpu_dat)
  78.655 +void tvga_accel_command(int count, uint32_t cpu_dat, tvga_t *tvga)
  78.656  {
  78.657 +        svga_t *svga = &tvga->svga;
  78.658  	int x, y;
  78.659  	int c, d;
  78.660  	uint16_t src_dat, dst_dat, pat_dat;
  78.661  	uint16_t out;
  78.662 -	int xdir = (tvga_accel.flags & 0x200) ? -1 : 1;
  78.663 -	int ydir = (tvga_accel.flags & 0x100) ? -1 : 1;
  78.664 -	uint16_t trans_col = (tvga_accel.flags & TGUI_TRANSREV) ? tvga_accel.fg_col : tvga_accel.bg_col;
  78.665 -        uint16_t *vram_w = (uint16_t *)vram;
  78.666 +	int xdir = (tvga->accel.flags & 0x200) ? -1 : 1;
  78.667 +	int ydir = (tvga->accel.flags & 0x100) ? -1 : 1;
  78.668 +	uint16_t trans_col = (tvga->accel.flags & TGUI_TRANSREV) ? tvga->accel.fg_col : tvga->accel.bg_col;
  78.669 +        uint16_t *vram_w = (uint16_t *)svga->vram;
  78.670          
  78.671 -	if (tvga_accel.bpp == 0)
  78.672 +	if (tvga->accel.bpp == 0)
  78.673                  trans_col &= 0xff;
  78.674  	
  78.675 -	if (count != -1 && !tvga_accel.x)
  78.676 +	if (count != -1 && !tvga->accel.x)
  78.677  	{
  78.678 -		count -= tvga_accel.offset;
  78.679 -		cpu_dat <<= tvga_accel.offset;
  78.680 +		count -= tvga->accel.offset;
  78.681 +		cpu_dat <<= tvga->accel.offset;
  78.682  	}
  78.683  	if (count == -1)
  78.684  	{
  78.685 -		tvga_accel.x = tvga_accel.y = 0;
  78.686 +		tvga->accel.x = tvga->accel.y = 0;
  78.687  	}
  78.688 -	if (tvga_accel.flags & TGUI_SOLIDFILL)
  78.689 +	if (tvga->accel.flags & TGUI_SOLIDFILL)
  78.690  	{
  78.691  //		pclog("SOLIDFILL\n");
  78.692  		for (y = 0; y < 8; y++)
  78.693  		{
  78.694  			for (x = 0; x < 8; x++)
  78.695  			{
  78.696 -				tvga_pattern[y][x] = tvga_accel.fg_col;
  78.697 +				tvga->accel.tvga_pattern[y][x] = tvga->accel.fg_col;
  78.698  			}
  78.699  		}
  78.700  	}
  78.701 -	else if (tvga_accel.flags & TGUI_PATMONO)
  78.702 +	else if (tvga->accel.flags & TGUI_PATMONO)
  78.703  	{
  78.704  //		pclog("PATMONO\n");
  78.705  		for (y = 0; y < 8; y++)
  78.706  		{
  78.707  			for (x = 0; x < 8; x++)
  78.708  			{
  78.709 -				tvga_pattern[y][x] = (tvga_accel.pattern[y] & (1 << x)) ? tvga_accel.fg_col : tvga_accel.bg_col;
  78.710 +				tvga->accel.tvga_pattern[y][x] = (tvga->accel.pattern[y] & (1 << x)) ? tvga->accel.fg_col : tvga->accel.bg_col;
  78.711  			}
  78.712  		}
  78.713  	}
  78.714 @@ -468,46 +536,46 @@
  78.715  		{
  78.716  			for (x = 0; x < 8; x++)
  78.717  			{
  78.718 -				tvga_pattern[y][x] = tvga_accel.pattern[x + y*8];
  78.719 +				tvga->accel.tvga_pattern[y][x] = tvga->accel.pattern[x + y*8];
  78.720  			}
  78.721  		}
  78.722  	}
  78.723  	for (y = 0; y < 8; y++)
  78.724  	{
  78.725 -		if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tvga_pattern[y][0], tvga_pattern[y][1], tvga_pattern[y][2], tvga_pattern[y][3], tvga_pattern[y][4], tvga_pattern[y][5], tvga_pattern[y][6], tvga_pattern[y][7]);
  78.726 +		if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tvga->accel.tvga_pattern[y][0], tvga->accel.tvga_pattern[y][1], tvga->accel.tvga_pattern[y][2], tvga->accel.tvga_pattern[y][3], tvga->accel.tvga_pattern[y][4], tvga->accel.tvga_pattern[y][5], tvga->accel.tvga_pattern[y][6], tvga->accel.tvga_pattern[y][7]);
  78.727  	}
  78.728 -	if (count == -1) pclog("Command %i %i\n", tvga_accel.command, TGUI_BITBLT);
  78.729 -	switch (tvga_accel.command)
  78.730 +	if (count == -1) pclog("Command %i %i\n", tvga->accel.command, TGUI_BITBLT);
  78.731 +	switch (tvga->accel.command)
  78.732  	{
  78.733  		case TGUI_BITBLT:
  78.734 -		if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tvga_accel.src_x, tvga_accel.src_y, tvga_accel.dst_x, tvga_accel.dst_y, tvga_accel.size_x, tvga_accel.size_y, tvga_accel.flags);
  78.735 +		if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tvga->accel.src_x, tvga->accel.src_y, tvga->accel.dst_x, tvga->accel.dst_y, tvga->accel.size_x, tvga->accel.size_y, tvga->accel.flags);
  78.736  		if (count == -1)
  78.737  		{
  78.738 -			tvga_accel.src = tvga_accel.src_old = tvga_accel.src_x + (tvga_accel.src_y * tvga_accel.pitch);
  78.739 -			tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_x + (tvga_accel.dst_y * tvga_accel.pitch);
  78.740 -			tvga_accel.pat_x = tvga_accel.dst_x;
  78.741 -			tvga_accel.pat_y = tvga_accel.dst_y;
  78.742 +			tvga->accel.src = tvga->accel.src_old = tvga->accel.src_x + (tvga->accel.src_y * tvga->accel.pitch);
  78.743 +			tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_x + (tvga->accel.dst_y * tvga->accel.pitch);
  78.744 +			tvga->accel.pat_x = tvga->accel.dst_x;
  78.745 +			tvga->accel.pat_y = tvga->accel.dst_y;
  78.746  		}
  78.747  
  78.748 -		switch (tvga_accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP))
  78.749 +		switch (tvga->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP))
  78.750  		{
  78.751  			case TGUI_SRCCPU:
  78.752  			if (count == -1)
  78.753  			{
  78.754  //				pclog("Blit start\n");
  78.755 -				if (crtc[0x21] & 0x20)
  78.756 +				if (svga->crtc[0x21] & 0x20)
  78.757  				{
  78.758 -					mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    NULL);
  78.759 -					mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l,    NULL);
  78.760 +					mem_removehandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    NULL);
  78.761 +					mem_sethandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l,    NULL);
  78.762  				}
  78.763 -				if (tvga_accel.use_src)
  78.764 +				if (tvga->accel.use_src)
  78.765                                          return;
  78.766  			}
  78.767  			else
  78.768  			     count >>= 3;
  78.769  			while (count)
  78.770  			{
  78.771 -				if (tvga_accel.bpp == 0)
  78.772 +				if (tvga->accel.bpp == 0)
  78.773  				{
  78.774                                          src_dat = cpu_dat >> 24;
  78.775                                          cpu_dat <<= 8;
  78.776 @@ -518,45 +586,45 @@
  78.777                                          cpu_dat <<= 16;
  78.778                                          count--;
  78.779                                  }
  78.780 -				READ(tvga_accel.dst, dst_dat);
  78.781 -				pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7];
  78.782 +				READ(tvga->accel.dst, dst_dat);
  78.783 +				pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7];
  78.784  	
  78.785 -                                if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  78.786 +                                if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  78.787                                  {
  78.788          				MIX();
  78.789  	
  78.790 -                                        WRITE(tvga_accel.dst, out);
  78.791 +                                        WRITE(tvga->accel.dst, out);
  78.792                                  }
  78.793  
  78.794 -//				pclog("  %i,%i  %02X %02X %02X  %02X\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out);
  78.795 +//				pclog("  %i,%i  %02X %02X %02X  %02X\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out);
  78.796                                  	
  78.797 -				tvga_accel.src += xdir;
  78.798 -				tvga_accel.dst += xdir;
  78.799 -				tvga_accel.pat_x += xdir;
  78.800 +				tvga->accel.src += xdir;
  78.801 +				tvga->accel.dst += xdir;
  78.802 +				tvga->accel.pat_x += xdir;
  78.803  	
  78.804 -				tvga_accel.x++;
  78.805 -				if (tvga_accel.x > tvga_accel.size_x)
  78.806 +				tvga->accel.x++;
  78.807 +				if (tvga->accel.x > tvga->accel.size_x)
  78.808  				{
  78.809 -					tvga_accel.x = 0;
  78.810 -					tvga_accel.y++;
  78.811 +					tvga->accel.x = 0;
  78.812 +					tvga->accel.y++;
  78.813  					
  78.814 -					tvga_accel.pat_x = tvga_accel.dst_x;
  78.815 +					tvga->accel.pat_x = tvga->accel.dst_x;
  78.816  	
  78.817 -					tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch);
  78.818 -					tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch);
  78.819 -					tvga_accel.pat_y += ydir;
  78.820 +					tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch);
  78.821 +					tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch);
  78.822 +					tvga->accel.pat_y += ydir;
  78.823  					
  78.824 -					if (tvga_accel.y > tvga_accel.size_y)
  78.825 +					if (tvga->accel.y > tvga->accel.size_y)
  78.826  					{
  78.827 -						if (crtc[0x21] & 0x20)
  78.828 +						if (svga->crtc[0x21] & 0x20)
  78.829  						{
  78.830  //							pclog("Blit end\n");
  78.831 -							mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l,    NULL);
  78.832 -							mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    NULL);
  78.833 +							mem_removehandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l,    NULL);
  78.834 +							mem_sethandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    NULL);
  78.835  						}
  78.836  						return;
  78.837  					}
  78.838 -					if (tvga_accel.use_src)
  78.839 +					if (tvga->accel.use_src)
  78.840                                                  return;
  78.841  				}
  78.842  				count--;
  78.843 @@ -567,59 +635,59 @@
  78.844  			if (count == -1)
  78.845  			{
  78.846  //				pclog("Blit start\n");
  78.847 -				if (crtc[0x21] & 0x20)
  78.848 +				if (svga->crtc[0x21] & 0x20)
  78.849  				{
  78.850 -					mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    NULL);
  78.851 -					mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l,    NULL);
  78.852 +					mem_removehandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    NULL);
  78.853 +					mem_sethandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l,    NULL);
  78.854  				}
  78.855 -				if (tvga_accel.use_src)
  78.856 +				if (tvga->accel.use_src)
  78.857                                          return;
  78.858  			}
  78.859  //			pclog("TGUI_SRCMONO | TGUI_SRCCPU\n");
  78.860  			while (count)
  78.861  			{
  78.862 -				src_dat = ((cpu_dat >> 31) ? tvga_accel.fg_col : tvga_accel.bg_col);
  78.863 -				if (tvga_accel.bpp == 0)
  78.864 +				src_dat = ((cpu_dat >> 31) ? tvga->accel.fg_col : tvga->accel.bg_col);
  78.865 +				if (tvga->accel.bpp == 0)
  78.866  				    src_dat &= 0xff;
  78.867  				    
  78.868 -				READ(tvga_accel.dst, dst_dat);
  78.869 -				pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7];
  78.870 +				READ(tvga->accel.dst, dst_dat);
  78.871 +				pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7];
  78.872  
  78.873 -                                if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  78.874 +                                if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  78.875                                  {
  78.876          				MIX();
  78.877  
  78.878 -				        WRITE(tvga_accel.dst, out);
  78.879 +				        WRITE(tvga->accel.dst, out);
  78.880                                  }
  78.881 -//				pclog("  %i,%i  %02X %02X %02X  %02X %i\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out, (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col));
  78.882 +//				pclog("  %i,%i  %02X %02X %02X  %02X %i\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out, (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col));
  78.883  				cpu_dat <<= 1;
  78.884 -				tvga_accel.src += xdir;
  78.885 -				tvga_accel.dst += xdir;
  78.886 -				tvga_accel.pat_x += xdir;
  78.887 +				tvga->accel.src += xdir;
  78.888 +				tvga->accel.dst += xdir;
  78.889 +				tvga->accel.pat_x += xdir;
  78.890  	
  78.891 -				tvga_accel.x++;
  78.892 -				if (tvga_accel.x > tvga_accel.size_x)
  78.893 +				tvga->accel.x++;
  78.894 +				if (tvga->accel.x > tvga->accel.size_x)
  78.895  				{
  78.896 -					tvga_accel.x = 0;
  78.897 -					tvga_accel.y++;
  78.898 +					tvga->accel.x = 0;
  78.899 +					tvga->accel.y++;
  78.900  					
  78.901 -					tvga_accel.pat_x = tvga_accel.dst_x;
  78.902 +					tvga->accel.pat_x = tvga->accel.dst_x;
  78.903  	
  78.904 -					tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch);
  78.905 -					tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch);
  78.906 -					tvga_accel.pat_y += ydir;
  78.907 +					tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch);
  78.908 +					tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch);
  78.909 +					tvga->accel.pat_y += ydir;
  78.910  					
  78.911 -					if (tvga_accel.y > tvga_accel.size_y)
  78.912 +					if (tvga->accel.y > tvga->accel.size_y)
  78.913  					{
  78.914 -						if (crtc[0x21] & 0x20)
  78.915 +						if (svga->crtc[0x21] & 0x20)
  78.916  						{
  78.917  //							pclog("Blit end\n");
  78.918 -							mem_removehandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l,    NULL);
  78.919 -							mem_sethandler(tvga_linear_base, tvga_linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    NULL);
  78.920 +							mem_removehandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l,    NULL);
  78.921 +							mem_sethandler(tvga->linear_base, tvga->linear_size, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear,    NULL);
  78.922  						}
  78.923  						return;
  78.924  					}
  78.925 -					if (tvga_accel.use_src)
  78.926 +					if (tvga->accel.use_src)
  78.927                                                  return;
  78.928  				}
  78.929  				count--;
  78.930 @@ -629,35 +697,35 @@
  78.931  			default:
  78.932  			while (count)
  78.933  			{
  78.934 -				READ(tvga_accel.src, src_dat);
  78.935 -				READ(tvga_accel.dst, dst_dat);                                                                
  78.936 -				pat_dat = tvga_pattern[tvga_accel.pat_y & 7][tvga_accel.pat_x & 7];
  78.937 +				READ(tvga->accel.src, src_dat);
  78.938 +				READ(tvga->accel.dst, dst_dat);                                                                
  78.939 +				pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7];
  78.940  	
  78.941 -                                if (!(tvga_accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  78.942 +                                if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  78.943                                  {
  78.944          				MIX();
  78.945  	
  78.946 -                                        WRITE(tvga_accel.dst, out);
  78.947 +                                        WRITE(tvga->accel.dst, out);
  78.948                                  }
  78.949 -//                                pclog("  %i,%i  %02X %02X %02X  %02X\n", tvga_accel.x, tvga_accel.y, src_dat,dst_dat,pat_dat, out);
  78.950 +//                                pclog("  %i,%i  %02X %02X %02X  %02X\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out);
  78.951  	
  78.952 -				tvga_accel.src += xdir;
  78.953 -				tvga_accel.dst += xdir;
  78.954 -				tvga_accel.pat_x += xdir;
  78.955 +				tvga->accel.src += xdir;
  78.956 +				tvga->accel.dst += xdir;
  78.957 +				tvga->accel.pat_x += xdir;
  78.958  	
  78.959 -				tvga_accel.x++;
  78.960 -				if (tvga_accel.x > tvga_accel.size_x)
  78.961 +				tvga->accel.x++;
  78.962 +				if (tvga->accel.x > tvga->accel.size_x)
  78.963  				{
  78.964 -					tvga_accel.x = 0;
  78.965 -					tvga_accel.y++;
  78.966 +					tvga->accel.x = 0;
  78.967 +					tvga->accel.y++;
  78.968  					
  78.969 -					tvga_accel.pat_x = tvga_accel.dst_x;
  78.970 +					tvga->accel.pat_x = tvga->accel.dst_x;
  78.971  	
  78.972 -					tvga_accel.src = tvga_accel.src_old = tvga_accel.src_old + (ydir * tvga_accel.pitch);
  78.973 -					tvga_accel.dst = tvga_accel.dst_old = tvga_accel.dst_old + (ydir * tvga_accel.pitch);
  78.974 -					tvga_accel.pat_y += ydir;
  78.975 +					tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch);
  78.976 +					tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch);
  78.977 +					tvga->accel.pat_y += ydir;
  78.978  					
  78.979 -					if (tvga_accel.y > tvga_accel.size_y)
  78.980 +					if (tvga->accel.y > tvga->accel.size_y)
  78.981  						return;
  78.982  				}
  78.983  				count--;
  78.984 @@ -668,93 +736,94 @@
  78.985  	}
  78.986  }
  78.987  
  78.988 -void tvga_accel_write(uint32_t addr, uint8_t val, void *priv)
  78.989 +void tvga_accel_write(uint32_t addr, uint8_t val, void *p)
  78.990  {
  78.991 +        tvga_t *tvga = (tvga_t *)p;
  78.992  	pclog("tvga_accel_write : %08X %02X  %04X(%08X):%08X %02X\n", addr, val, CS,cs,pc, opcode);
  78.993  	if ((addr & ~0xff) != 0xbff00)
  78.994  		return;
  78.995  	switch (addr & 0xff)
  78.996  	{
  78.997                  case 0x22:
  78.998 -                tvga_accel.ger22 = val;
  78.999 -                tvga_accel.pitch = 512 << ((val >> 2) & 3);
 78.1000 -                tvga_accel.bpp = (val & 3) ? 1 : 0;
 78.1001 -                tvga_accel.pitch >>= tvga_accel.bpp;
 78.1002 +                tvga->accel.ger22 = val;
 78.1003 +                tvga->accel.pitch = 512 << ((val >> 2) & 3);
 78.1004 +                tvga->accel.bpp = (val & 3) ? 1 : 0;
 78.1005 +                tvga->accel.pitch >>= tvga->accel.bpp;
 78.1006                  break;
 78.1007                  
 78.1008  		case 0x24: /*Command*/
 78.1009 -		tvga_accel.command = val;
 78.1010 -		tvga_accel_command(-1, 0);
 78.1011 +		tvga->accel.command = val;
 78.1012 +		tvga_accel_command(-1, 0, tvga);
 78.1013  		break;
 78.1014  		
 78.1015  		case 0x27: /*ROP*/
 78.1016 -		tvga_accel.rop = val;
 78.1017 -		tvga_accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33);
 78.1018 -		pclog("Write ROP %02X %i\n", val, tvga_accel.use_src);
 78.1019 +		tvga->accel.rop = val;
 78.1020 +		tvga->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33);
 78.1021 +		pclog("Write ROP %02X %i\n", val, tvga->accel.use_src);
 78.1022  		break;
 78.1023  		
 78.1024  		case 0x28: /*Flags*/
 78.1025 -		tvga_accel.flags = (tvga_accel.flags & 0xff00) | val;
 78.1026 +		tvga->accel.flags = (tvga->accel.flags & 0xff00) | val;
 78.1027  		break;
 78.1028  		case 0x29: /*Flags*/
 78.1029 -		tvga_accel.flags = (tvga_accel.flags & 0xff) | (val << 8);
 78.1030 +		tvga->accel.flags = (tvga->accel.flags & 0xff) | (val << 8);
 78.1031  		break;
 78.1032  
 78.1033  		case 0x2b:
 78.1034 -		tvga_accel.offset = val & 7;
 78.1035 +		tvga->accel.offset = val & 7;
 78.1036  		break;
 78.1037  		
 78.1038  		case 0x2c: /*Foreground colour*/
 78.1039 -		tvga_accel.fg_col = (tvga_accel.fg_col & 0xff00) | val;
 78.1040 +		tvga->accel.fg_col = (tvga->accel.fg_col & 0xff00) | val;
 78.1041  		break;
 78.1042  		case 0x2d: /*Foreground colour*/
 78.1043 -		tvga_accel.fg_col = (tvga_accel.fg_col & 0xff) | (val << 8);
 78.1044 +		tvga->accel.fg_col = (tvga->accel.fg_col & 0xff) | (val << 8);
 78.1045  		break;
 78.1046  
 78.1047  		case 0x30: /*Background colour*/
 78.1048 -		tvga_accel.bg_col = (tvga_accel.bg_col & 0xff00) | val;
 78.1049 +		tvga->accel.bg_col = (tvga->accel.bg_col & 0xff00) | val;
 78.1050  		break;
 78.1051  		case 0x31: /*Background colour*/
 78.1052 -		tvga_accel.bg_col = (tvga_accel.bg_col & 0xff) | (val << 8);
 78.1053 +		tvga->accel.bg_col = (tvga->accel.bg_col & 0xff) | (val << 8);
 78.1054  		break;
 78.1055  
 78.1056  		case 0x38: /*Dest X*/
 78.1057 -		tvga_accel.dst_x = (tvga_accel.dst_x & 0xff00) | val;
 78.1058 +		tvga->accel.dst_x = (tvga->accel.dst_x & 0xff00) | val;
 78.1059  		break;
 78.1060  		case 0x39: /*Dest X*/
 78.1061 -		tvga_accel.dst_x = (tvga_accel.dst_x & 0xff) | (val << 8);
 78.1062 +		tvga->accel.dst_x = (tvga->accel.dst_x & 0xff) | (val << 8);
 78.1063  		break;
 78.1064  		case 0x3a: /*Dest Y*/
 78.1065 -		tvga_accel.dst_y = (tvga_accel.dst_y & 0xff00) | val;
 78.1066 +		tvga->accel.dst_y = (tvga->accel.dst_y & 0xff00) | val;
 78.1067  		break;
 78.1068  		case 0x3b: /*Dest Y*/
 78.1069 -		tvga_accel.dst_y = (tvga_accel.dst_y & 0xff) | (val << 8);
 78.1070 +		tvga->accel.dst_y = (tvga->accel.dst_y & 0xff) | (val << 8);
 78.1071  		break;
 78.1072  
 78.1073  		case 0x3c: /*Src X*/
 78.1074 -		tvga_accel.src_x = (tvga_accel.src_x & 0xff00) | val;
 78.1075 +		tvga->accel.src_x = (tvga->accel.src_x & 0xff00) | val;
 78.1076  		break;
 78.1077  		case 0x3d: /*Src X*/
 78.1078 -		tvga_accel.src_x = (tvga_accel.src_x & 0xff) | (val << 8);
 78.1079 +		tvga->accel.src_x = (tvga->accel.src_x & 0xff) | (val << 8);
 78.1080  		break;
 78.1081  		case 0x3e: /*Src Y*/
 78.1082 -		tvga_accel.src_y = (tvga_accel.src_y & 0xff00) | val;
 78.1083 +		tvga->accel.src_y = (tvga->accel.src_y & 0xff00) | val;
 78.1084  		break;
 78.1085  		case 0x3f: /*Src Y*/
 78.1086 -		tvga_accel.src_y = (tvga_accel.src_y & 0xff) | (val << 8);
 78.1087 +		tvga->accel.src_y = (tvga->accel.src_y & 0xff) | (val << 8);
 78.1088  		break;
 78.1089  
 78.1090  		case 0x40: /*Size X*/
 78.1091 -		tvga_accel.size_x = (tvga_accel.size_x & 0xff00) | val;
 78.1092 +		tvga->accel.size_x = (tvga->accel.size_x & 0xff00) | val;
 78.1093  		break;
 78.1094  		case 0x41: /*Size X*/
 78.1095 -		tvga_accel.size_x = (tvga_accel.size_x & 0xff) | (val << 8);
 78.1096 +		tvga->accel.size_x = (tvga->accel.size_x & 0xff) | (val << 8);
 78.1097  		break;
 78.1098  		case 0x42: /*Size Y*/
 78.1099 -		tvga_accel.size_y = (tvga_accel.size_y & 0xff00) | val;
 78.1100 +		tvga->accel.size_y = (tvga->accel.size_y & 0xff00) | val;
 78.1101  		break;
 78.1102  		case 0x43: /*Size Y*/
 78.1103 -		tvga_accel.size_y = (tvga_accel.size_y & 0xff) | (val << 8);
 78.1104 +		tvga->accel.size_y = (tvga->accel.size_y & 0xff) | (val << 8);
 78.1105  		break;
 78.1106  		
 78.1107  		case 0x80: case 0x81: case 0x82: case 0x83:
 78.1108 @@ -789,29 +858,32 @@
 78.1109  		case 0xf4: case 0xf5: case 0xf6: case 0xf7:
 78.1110  		case 0xf8: case 0xf9: case 0xfa: case 0xfb:
 78.1111  		case 0xfc: case 0xfd: case 0xfe: case 0xff:
 78.1112 -		tvga_accel.pattern[addr & 0x7f] = val;
 78.1113 +		tvga->accel.pattern[addr & 0x7f] = val;
 78.1114  		break;
 78.1115  	}
 78.1116  }
 78.1117  
 78.1118 -void tvga_accel_write_w(uint32_t addr, uint16_t val, void *priv)
 78.1119 +void tvga_accel_write_w(uint32_t addr, uint16_t val, void *p)
 78.1120  {
 78.1121 +        tvga_t *tvga = (tvga_t *)p;
 78.1122  	pclog("tvga_accel_write_w %08X %04X\n", addr, val);
 78.1123 -	tvga_accel_write(addr, val, NULL);
 78.1124 -	tvga_accel_write(addr + 1, val >> 8, NULL);
 78.1125 +	tvga_accel_write(addr, val, tvga);
 78.1126 +	tvga_accel_write(addr + 1, val >> 8, tvga);
 78.1127  }
 78.1128  
 78.1129 -void tvga_accel_write_l(uint32_t addr, uint32_t val, void *priv)
 78.1130 +void tvga_accel_write_l(uint32_t addr, uint32_t val, void *p)
 78.1131  {
 78.1132 +        tvga_t *tvga = (tvga_t *)p;
 78.1133  	pclog("tvga_accel_write_l %08X %08X\n", addr, val);
 78.1134 -	tvga_accel_write(addr, val, NULL);
 78.1135 -	tvga_accel_write(addr + 1, val >> 8, NULL);
 78.1136 -	tvga_accel_write(addr + 2, val >> 16, NULL);
 78.1137 -	tvga_accel_write(addr + 3, val >> 24, NULL);
 78.1138 +	tvga_accel_write(addr, val, tvga);
 78.1139 +	tvga_accel_write(addr + 1, val >> 8, tvga);
 78.1140 +	tvga_accel_write(addr + 2, val >> 16, tvga);
 78.1141 +	tvga_accel_write(addr + 3, val >> 24, tvga);
 78.1142  }
 78.1143  
 78.1144 -uint8_t tvga_accel_read(uint32_t addr, void *priv)
 78.1145 +uint8_t tvga_accel_read(uint32_t addr, void *p)
 78.1146  {
 78.1147 +        tvga_t *tvga = (tvga_t *)p;
 78.1148  //	pclog("tvga_accel_read : %08X\n", addr);
 78.1149  	if ((addr & ~0xff) != 0xbff00)
 78.1150  		return 0xff;
 78.1151 @@ -821,52 +893,52 @@
 78.1152  		return 0;
 78.1153  		
 78.1154  		case 0x27: /*ROP*/
 78.1155 -		return tvga_accel.rop;
 78.1156 +		return tvga->accel.rop;
 78.1157  		
 78.1158  		case 0x28: /*Flags*/
 78.1159 -		return tvga_accel.flags & 0xff;
 78.1160 +		return tvga->accel.flags & 0xff;
 78.1161  		case 0x29: /*Flags*/
 78.1162 -		return tvga_accel.flags >> 8;
 78.1163 +		return tvga->accel.flags >> 8;
 78.1164  
 78.1165  		case 0x2b:
 78.1166 -		return tvga_accel.offset;
 78.1167 +		return tvga->accel.offset;
 78.1168  		
 78.1169  		case 0x2c: /*Background colour*/
 78.1170 -		return tvga_accel.bg_col & 0xff;
 78.1171 +		return tvga->accel.bg_col & 0xff;
 78.1172  		case 0x2d: /*Background colour*/
 78.1173 -		return tvga_accel.bg_col >> 8;
 78.1174 +		return tvga->accel.bg_col >> 8;
 78.1175  
 78.1176  		case 0x30: /*Foreground colour*/
 78.1177 -		return tvga_accel.fg_col & 0xff;
 78.1178 +		return tvga->accel.fg_col & 0xff;
 78.1179  		case 0x31: /*Foreground colour*/
 78.1180 -		return tvga_accel.fg_col >> 8;
 78.1181 +		return tvga->accel.fg_col >> 8;
 78.1182  
 78.1183  		case 0x38: /*Dest X*/
 78.1184 -		return tvga_accel.dst_x & 0xff;
 78.1185 +		return tvga->accel.dst_x & 0xff;
 78.1186  		case 0x39: /*Dest X*/
 78.1187 -		return tvga_accel.dst_x >> 8;
 78.1188 +		return tvga->accel.dst_x >> 8;
 78.1189  		case 0x3a: /*Dest Y*/
 78.1190 -		return tvga_accel.dst_y & 0xff;
 78.1191 +		return tvga->accel.dst_y & 0xff;
 78.1192  		case 0x3b: /*Dest Y*/
 78.1193 -		return tvga_accel.dst_y >> 8;
 78.1194 +		return tvga->accel.dst_y >> 8;
 78.1195  
 78.1196  		case 0x3c: /*Src X*/
 78.1197 -		return tvga_accel.src_x & 0xff;
 78.1198 +		return tvga->accel.src_x & 0xff;
 78.1199  		case 0x3d: /*Src X*/
 78.1200 -		return tvga_accel.src_x >> 8;
 78.1201 +		return tvga->accel.src_x >> 8;
 78.1202  		case 0x3e: /*Src Y*/
 78.1203 -		return tvga_accel.src_y & 0xff;
 78.1204 +		return tvga->accel.src_y & 0xff;
 78.1205  		case 0x3f: /*Src Y*/
 78.1206 -		return tvga_accel.src_y >> 8;
 78.1207 +		return tvga->accel.src_y >> 8;
 78.1208  
 78.1209  		case 0x40: /*Size X*/
 78.1210 -		return tvga_accel.size_x & 0xff;
 78.1211 +		return tvga->accel.size_x & 0xff;
 78.1212  		case 0x41: /*Size X*/
 78.1213 -		return tvga_accel.size_x >> 8;
 78.1214 +		return tvga->accel.size_x >> 8;
 78.1215  		case 0x42: /*Size Y*/
 78.1216 -		return tvga_accel.size_y & 0xff;
 78.1217 +		return tvga->accel.size_y & 0xff;
 78.1218  		case 0x43: /*Size Y*/
 78.1219 -		return tvga_accel.size_y >> 8;
 78.1220 +		return tvga->accel.size_y >> 8;
 78.1221  		
 78.1222  		case 0x80: case 0x81: case 0x82: case 0x83:
 78.1223  		case 0x84: case 0x85: case 0x86: case 0x87:
 78.1224 @@ -900,83 +972,42 @@
 78.1225  		case 0xf4: case 0xf5: case 0xf6: case 0xf7:
 78.1226  		case 0xf8: case 0xf9: case 0xfa: case 0xfb:
 78.1227  		case 0xfc: case 0xfd: case 0xfe: case 0xff:
 78.1228 -		return tvga_accel.pattern[addr & 0x7f];
 78.1229 +		return tvga->accel.pattern[addr & 0x7f];
 78.1230  	}
 78.1231  	return 0xff;
 78.1232  }
 78.1233  
 78.1234 -uint16_t tvga_accel_read_w(uint32_t addr, void *priv)
 78.1235 +uint16_t tvga_accel_read_w(uint32_t addr, void *p)
 78.1236  {
 78.1237 +        tvga_t *tvga = (tvga_t *)p;
 78.1238  	pclog("tvga_accel_read_w %08X\n", addr);
 78.1239 -	return tvga_accel_read(addr, NULL) | (tvga_accel_read(addr + 1, NULL) << 8);
 78.1240 +	return tvga_accel_read(addr, tvga) | (tvga_accel_read(addr + 1, tvga) << 8);
 78.1241  }
 78.1242  
 78.1243 -uint32_t tvga_accel_read_l(uint32_t addr, void *priv)
 78.1244 +uint32_t tvga_accel_read_l(uint32_t addr, void *p)
 78.1245  {
 78.1246 +        tvga_t *tvga = (tvga_t *)p;
 78.1247  	pclog("tvga_accel_read_l %08X\n", addr);
 78.1248 -	return tvga_accel_read_w(addr, NULL) | (tvga_accel_read_w(addr + 2, NULL) << 16);
 78.1249 +	return tvga_accel_read_w(addr, tvga) | (tvga_accel_read_w(addr + 2, tvga) << 16);
 78.1250  }
 78.1251  
 78.1252 -void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv)
 78.1253 +void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *p)
 78.1254  {
 78.1255 +        tvga_t *tvga = (tvga_t *)p;
 78.1256  //	pclog("tvga_accel_write_fb_b %08X %02X\n", addr, val);
 78.1257 -	tvga_accel_command(8, val << 24);
 78.1258 +	tvga_accel_command(8, val << 24, tvga);
 78.1259  }
 78.1260  
 78.1261 -void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv)
 78.1262 +void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *p)
 78.1263  {
 78.1264 +        tvga_t *tvga = (tvga_t *)p;
 78.1265  //	pclog("tvga_accel_write_fb_w %08X %04X\n", addr, val);
 78.1266 -	tvga_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16);
 78.1267 +	tvga_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tvga);
 78.1268  }
 78.1269  
 78.1270 -void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv)
 78.1271 +void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *p)
 78.1272  {
 78.1273 +        tvga_t *tvga = (tvga_t *)p;
 78.1274  //	pclog("tvga_accel_write_fb_l %08X %08X\n", addr, val);
 78.1275 -	tvga_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
 78.1276 +	tvga_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tvga);
 78.1277  }
 78.1278 -
 78.1279 -GFXCARD vid_tvga =
 78.1280 -{
 78.1281 -        tvga_init,
 78.1282 -        /*IO at 3Cx/3Dx*/
 78.1283 -        tvga_out,
 78.1284 -        tvga_in,
 78.1285 -        /*IO at 3Ax/3Bx*/
 78.1286 -        video_out_null,
 78.1287 -        video_in_null,
 78.1288 -        
 78.1289 -        svga_poll,
 78.1290 -        svga_recalctimings,
 78.1291 -        
 78.1292 -        svga_write,
 78.1293 -        video_write_null,
 78.1294 -        video_write_null,
 78.1295 -        
 78.1296 -        svga_read,
 78.1297 -        video_read_null,
 78.1298 -        video_read_null
 78.1299 -};
 78.1300 -
 78.1301 -GFXCARD vid_tgui9440 =
 78.1302 -{
 78.1303 -        tvga_init,
 78.1304 -        /*IO at 3Cx/3Dx*/
 78.1305 -        tvga_out,
 78.1306 -        tvga_in,
 78.1307 -        /*IO at 3Ax/3Bx*/
 78.1308 -        video_out_null,
 78.1309 -        video_in_null,
 78.1310 -        
 78.1311 -        svga_poll,
 78.1312 -        svga_recalctimings,
 78.1313 -        
 78.1314 -        svga_write,
 78.1315 -        video_write_null,
 78.1316 -        video_write_null,
 78.1317 -        
 78.1318 -        svga_read,
 78.1319 -        video_read_null,
 78.1320 -        video_read_null
 78.1321 -};
 78.1322 -
 78.1323 -
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/src/vid_tvga.h	Mon Jun 24 20:42:35 2013 +0100
    79.3 @@ -0,0 +1,2 @@
    79.4 +extern device_t tvga8900d_device;
    79.5 +extern device_t tgui9440_device;
    80.1 --- a/src/vid_unk_ramdac.c	Tue Jun 04 20:52:17 2013 +0100
    80.2 +++ b/src/vid_unk_ramdac.c	Mon Jun 24 20:42:35 2013 +0100
    80.3 @@ -6,61 +6,58 @@
    80.4  #include "vid_svga.h"
    80.5  #include "vid_unk_ramdac.h"
    80.6  
    80.7 -static int unk_state=0;
    80.8 -static uint8_t unk_ctrl;
    80.9 -
   80.10 -void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv)
   80.11 +void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga)
   80.12  {
   80.13          //pclog("OUT RAMDAC %04X %02X\n",addr,val);
   80.14          switch (addr)
   80.15          {
   80.16                  case 0x3C6:
   80.17 -                if (unk_state == 4)
   80.18 +                if (ramdac->state == 4)
   80.19                  {
   80.20 -                        unk_state = 0;
   80.21 -                        unk_ctrl = val;
   80.22 +                        ramdac->state = 0;
   80.23 +                        ramdac->ctrl = val;
   80.24                          switch ((val&1)|((val&0xE0)>>4))
   80.25                          {
   80.26                                  case 0: case 1: case 2: case 3:
   80.27 -                                bpp = 8;
   80.28 +                                svga->bpp = 8;
   80.29                                  break;
   80.30                                  case 6: case 7:
   80.31 -                                bpp = 24;
   80.32 +                                svga->bpp = 24;
   80.33                                  break;
   80.34                                  case 8: case 9: case 0xA: case 0xB:
   80.35 -                                bpp = 15;
   80.36 +                                svga->bpp = 15;
   80.37                                  break;
   80.38                                  case 0xC: case 0xD: case 0xE: case 0xF:
   80.39 -                                bpp = 16;
   80.40 +                                svga->bpp = 16;
   80.41                                  break;
   80.42                          }
   80.43                          return;
   80.44                  }
   80.45 -                unk_state = 0;
   80.46 +                ramdac->state = 0;
   80.47                  break;
   80.48                  case 0x3C7: case 0x3C8: case 0x3C9:
   80.49 -                unk_state = 0;
   80.50 +                ramdac->state = 0;
   80.51                  break;
   80.52          }
   80.53 -        svga_out(addr, val, NULL);
   80.54 +        svga_out(addr, val, svga);
   80.55  }
   80.56  
   80.57 -uint8_t unk_ramdac_in(uint16_t addr, void *priv)
   80.58 +uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga)
   80.59  {
   80.60          //pclog("IN RAMDAC %04X\n",addr);
   80.61          switch (addr)
   80.62          {
   80.63                  case 0x3C6:
   80.64 -                if (unk_state == 4)
   80.65 +                if (ramdac->state == 4)
   80.66                  {
   80.67 -                        unk_state = 0;
   80.68 -                        return unk_ctrl;
   80.69 +                        ramdac->state = 0;
   80.70 +                        return ramdac->ctrl;
   80.71                  }
   80.72 -                unk_state++;
   80.73 +                ramdac->state++;
   80.74                  break;
   80.75                  case 0x3C7: case 0x3C8: case 0x3C9:
   80.76 -                unk_state = 0;
   80.77 +                ramdac->state = 0;
   80.78                  break;
   80.79          }
   80.80 -        return svga_in(addr, NULL);
   80.81 +        return svga_in(addr, svga);
   80.82  }
    81.1 --- a/src/vid_unk_ramdac.h	Tue Jun 04 20:52:17 2013 +0100
    81.2 +++ b/src/vid_unk_ramdac.h	Mon Jun 24 20:42:35 2013 +0100
    81.3 @@ -1,2 +1,8 @@
    81.4 -void unk_ramdac_out(uint16_t addr, uint8_t val, void *priv);
    81.5 -uint8_t unk_ramdac_in(uint16_t addr, void *priv);
    81.6 +typedef struct unk_ramdac_t
    81.7 +{
    81.8 +        int state;
    81.9 +        uint8_t ctrl;
   81.10 +} unk_ramdac_t;
   81.11 +
   81.12 +void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga);
   81.13 +uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga);
    82.1 --- a/src/vid_vga.c	Tue Jun 04 20:52:17 2013 +0100
    82.2 +++ b/src/vid_vga.c	Mon Jun 24 20:42:35 2013 +0100
    82.3 @@ -1,92 +1,116 @@
    82.4  /*IBM VGA emulation*/
    82.5 +#include <stdlib.h>
    82.6  #include "ibm.h"
    82.7 +#include "device.h"
    82.8  #include "io.h"
    82.9  #include "video.h"
   82.10  #include "vid_svga.h"
   82.11 +#include "vid_vga.h"
   82.12  
   82.13 -void vga_out(uint16_t addr, uint8_t val, void *priv)
   82.14 +typedef struct vga_t
   82.15  {
   82.16 +        svga_t svga;
   82.17 +} vga_t;
   82.18 +
   82.19 +void vga_out(uint16_t addr, uint8_t val, void *p)
   82.20 +{
   82.21 +        vga_t *vga = (vga_t *)p;
   82.22 +        svga_t *svga = &vga->svga;
   82.23          uint8_t old;
   82.24          
   82.25          pclog("vga_out : %04X %02X  %04X:%04X  %02X  %i\n", addr, val, CS,pc, ram[0x489], ins);
   82.26                  
   82.27 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   82.28 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
   82.29 +                addr ^= 0x60;
   82.30  
   82.31          switch (addr)
   82.32          {
   82.33                  case 0x3D4:
   82.34 -                crtcreg = val & 0x1f;
   82.35 +                svga->crtcreg = val & 0x1f;
   82.36                  return;
   82.37                  case 0x3D5:
   82.38 -                if (crtcreg <= 7 && crtc[0x11] & 0x80) return;
   82.39 -                old=crtc[crtcreg];
   82.40 -                crtc[crtcreg]=val;
   82.41 -                if (old!=val)
   82.42 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
   82.43 +                old = svga->crtc[svga->crtcreg];
   82.44 +                svga->crtc[svga->crtcreg] = val;
   82.45 +                if (old != val)
   82.46                  {
   82.47 -                        if (crtcreg<0xE || crtcreg>0x10)
   82.48 +                        if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
   82.49                          {
   82.50 -                                fullchange=changeframecount;
   82.51 -                                svga_recalctimings();
   82.52 +                                fullchange = changeframecount;
   82.53 +                                svga_recalctimings(svga);
   82.54                          }
   82.55                  }
   82.56                  break;
   82.57          }
   82.58 -        svga_out(addr, val, NULL);
   82.59 +        svga_out(addr, val, svga);
   82.60  }
   82.61  
   82.62 -uint8_t vga_in(uint16_t addr, void *priv)
   82.63 +uint8_t vga_in(uint16_t addr, void *p)
   82.64  {
   82.65 +        vga_t *vga = (vga_t *)p;
   82.66 +        svga_t *svga = &vga->svga;
   82.67          uint8_t temp;
   82.68  
   82.69          if (addr != 0x3da) pclog("vga_in : %04X ", addr);
   82.70                  
   82.71 -        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga_miscout&1)) addr ^= 0x60;
   82.72 +        if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
   82.73 +                addr ^= 0x60;
   82.74               
   82.75          switch (addr)
   82.76          {
   82.77                  case 0x3D4:
   82.78 -                temp = crtcreg;
   82.79 +                temp = svga->crtcreg;
   82.80                  break;
   82.81                  case 0x3D5:
   82.82 -                temp = crtc[crtcreg];
   82.83 +                temp = svga->crtc[svga->crtcreg];
   82.84                  break;
   82.85                  default:
   82.86 -                temp = svga_in(addr, NULL);
   82.87 +                temp = svga_in(addr, svga);
   82.88                  break;
   82.89          }
   82.90          if (addr != 0x3da) pclog("%02X  %04X:%04X\n", temp, CS,pc);
   82.91          return temp;
   82.92  }
   82.93  
   82.94 -int vga_init()
   82.95 +void *vga_init()
   82.96  {
   82.97 -        svga_recalctimings_ex = NULL;
   82.98 -        svga_vram_limit = 1 << 18; /*256kb*/
   82.99 -        vrammask = 0x3ffff;
  82.100 -        svgawbank = svgarbank = 0;
  82.101 -        bpp = 8;
  82.102 -        svga_miscout = 1;
  82.103 -        return svga_init();
  82.104 +        vga_t *vga = malloc(sizeof(vga_t));
  82.105 +        memset(vga, 0, sizeof(vga_t));
  82.106 +
  82.107 +        svga_init(&vga->svga, vga, 1 << 18, /*256kb*/
  82.108 +                   NULL,
  82.109 +                   vga_in, vga_out,
  82.110 +                   NULL);
  82.111 +
  82.112 +        io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
  82.113 +
  82.114 +        vga->svga.bpp = 8;
  82.115 +        vga->svga.miscout = 1;
  82.116 +        
  82.117 +        return vga;
  82.118  }
  82.119  
  82.120 -GFXCARD vid_vga =
  82.121 +void vga_close(void *p)
  82.122  {
  82.123 +        vga_t *vga = (vga_t *)p;
  82.124 +
  82.125 +        svga_close(&vga->svga);
  82.126 +        
  82.127 +        free(vga);
  82.128 +}
  82.129 +
  82.130 +void vga_speed_changed(void *p)
  82.131 +{
  82.132 +        vga_t *vga = (vga_t *)p;
  82.133 +        
  82.134 +        svga_recalctimings(&vga->svga);
  82.135 +}
  82.136 +
  82.137 +device_t vga_device =
  82.138 +{
  82.139 +        "VGA",
  82.140          vga_init,
  82.141 -        /*IO at 3Cx/3Dx*/
  82.142 -        vga_out,
  82.143 -        vga_in,
  82.144 -        /*IO at 3Ax/3Bx*/
  82.145 -        video_out_null,
  82.146 -        video_in_null,
  82.147 -
  82.148 -        svga_poll,
  82.149 -        svga_recalctimings,
  82.150 -
  82.151 -        svga_write,
  82.152 -        video_write_null,
  82.153 -        video_write_null,
  82.154 -
  82.155 -        svga_read,
  82.156 -        video_read_null,
  82.157 -        video_read_null
  82.158 +        vga_close,
  82.159 +        vga_speed_changed,
  82.160 +        svga_add_status_info
  82.161  };
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/src/vid_vga.h	Mon Jun 24 20:42:35 2013 +0100
    83.3 @@ -0,0 +1,1 @@
    83.4 +extern device_t vga_device;
    84.1 --- a/src/video.c	Tue Jun 04 20:52:17 2013 +0100
    84.2 +++ b/src/video.c	Mon Jun 24 20:42:35 2013 +0100
    84.3 @@ -1,13 +1,45 @@
    84.4  #include <stdio.h>
    84.5  #include <math.h>
    84.6  #include "ibm.h"
    84.7 +#include "device.h"
    84.8  #include "video.h"
    84.9  #include "vid_svga.h"
   84.10  #include "io.h"
   84.11  #include "cpu.h"
   84.12  #include "timer.h"
   84.13  
   84.14 -int video_timer;
   84.15 +#include "vid_ati18800.h"
   84.16 +#include "vid_ati28800.h"
   84.17 +#include "vid_ati_mach64.h"
   84.18 +#include "vid_cga.h"
   84.19 +#include "vid_cl5429.h"
   84.20 +#include "vid_ega.h"
   84.21 +#include "vid_et4000.h"
   84.22 +#include "vid_et4000w32.h"
   84.23 +#include "vid_hercules.h"
   84.24 +#include "vid_mda.h"
   84.25 +#include "vid_olivetti_m24.h"
   84.26 +#include "vid_oti067.h"
   84.27 +#include "vid_paradise.h"
   84.28 +#include "vid_pc1512.h"
   84.29 +#include "vid_pc1640.h"
   84.30 +#include "vid_pc200.h"
   84.31 +#include "vid_s3.h"
   84.32 +#include "vid_s3_virge.h"
   84.33 +#include "vid_tandy.h"
   84.34 +#include "vid_tvga.h"
   84.35 +#include "vid_vga.h"
   84.36 +
   84.37 +int egareads=0,egawrites=0;
   84.38 +int changeframecount=2;
   84.39 +
   84.40 +uint8_t rotatevga[8][256];
   84.41 +
   84.42 +int frames = 0;
   84.43 +
   84.44 +int fullchange;
   84.45 +
   84.46 +uint8_t edatlookup[4][4];
   84.47  
   84.48  /*Video timing settings -
   84.49  
   84.50 @@ -84,70 +116,6 @@
   84.51  void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h);
   84.52  void (*video_blit_memtoscreen_8)(int x, int y, int w, int h);
   84.53  
   84.54 -void (*video_out)     (uint16_t addr, uint8_t val, void *priv);
   84.55 -void (*video_mono_out)(uint16_t addr, uint8_t val, void *priv);
   84.56 -uint8_t (*video_in)     (uint16_t addr, void *priv);
   84.57 -uint8_t (*video_mono_in)(uint16_t addr, void *priv);
   84.58 -
   84.59 -void (*video_write_a000)(uint32_t addr, uint8_t val, void *priv);
   84.60 -void (*video_write_b000)(uint32_t addr, uint8_t val, void *priv);
   84.61 -void (*video_write_b800)(uint32_t addr, uint8_t val, void *priv);
   84.62 -
   84.63 -void (*video_write_a000_w)(uint32_t addr, uint16_t val, void *priv);
   84.64 -void (*video_write_a000_l)(uint32_t addr, uint32_t val, void *priv);
   84.65 -
   84.66 -uint8_t (*video_read_a000)(uint32_t addr, void *priv);
   84.67 -uint8_t (*video_read_b000)(uint32_t addr, void *priv);
   84.68 -uint8_t (*video_read_b800)(uint32_t addr, void *priv);
   84.69 -
   84.70 -void (*video_recalctimings)();
   84.71 -
   84.72 -void video_out_null(uint16_t addr, uint8_t val, void *priv)
   84.73 -{
   84.74 -}
   84.75 -
   84.76 -uint8_t video_in_null(uint16_t addr, void *priv)
   84.77 -{
   84.78 -        return 0xFF;
   84.79 -}
   84.80 -
   84.81 -void video_write_null(uint32_t addr, uint8_t val, void *priv)
   84.82 -{
   84.83 -}
   84.84 -
   84.85 -uint8_t video_read_null(uint32_t addr, void *priv)
   84.86 -{
   84.87 -        return 0xff;
   84.88 -}
   84.89 -
   84.90 -void video_load(GFXCARD g)
   84.91 -{
   84.92 -        io_sethandler(0x03a0, 0x0020, g.mono_in, NULL, NULL, g.mono_out, NULL, NULL, NULL);
   84.93 -        io_sethandler(0x03c0, 0x0020, g.in,      NULL, NULL, g.out,      NULL, NULL, NULL);        
   84.94 -        
   84.95 -        video_out      = g.out;
   84.96 -        video_in       = g.in;
   84.97 -        video_mono_out = g.mono_out;
   84.98 -        video_mono_in  = g.mono_in;
   84.99 -        
  84.100 -        pollvideo = g.poll;
  84.101 -        video_recalctimings = g.recalctimings;
  84.102 -        
  84.103 -        video_write_a000 = g.write_a000;
  84.104 -        video_write_b000 = g.write_b000;
  84.105 -        video_write_b800 = g.write_b800;
  84.106 -
  84.107 -        video_read_a000  = g.read_a000;
  84.108 -        video_read_b000  = g.read_b000;
  84.109 -        video_read_b800  = g.read_b800;
  84.110 -        
  84.111 -        video_write_a000_w = video_write_a000_l = NULL;
  84.112 -        
  84.113 -        g.init();
  84.114 -        
  84.115 -        video_timer = timer_add(pollvideo, &vidtime, TIMER_ALWAYS_ENABLED, NULL);
  84.116 -}
  84.117 -
  84.118  void video_init()
  84.119  {
  84.120          pclog("Video_init %i %i\n",romset,gfxcard);
  84.121 @@ -155,107 +123,108 @@
  84.122          switch (romset)
  84.123          {
  84.124                  case ROM_TANDY:
  84.125 -                video_load(vid_tandy);
  84.126 +                device_add(&tandy_device);
  84.127                  return;
  84.128  
  84.129                  case ROM_PC1512:
  84.130 -                video_load(vid_pc1512);
  84.131 +                device_add(&pc1512_device);
  84.132                  return;
  84.133                  
  84.134                  case ROM_PC1640:
  84.135 -                video_load(vid_pc1640);
  84.136 +                device_add(&pc1640_device);
  84.137                  return;
  84.138                  
  84.139                  case ROM_PC200:
  84.140 -                video_load(vid_pc200);
  84.141 +                device_add(&pc200_device);
  84.142                  return;
  84.143                  
  84.144                  case ROM_OLIM24:
  84.145 -                video_load(vid_m24);
  84.146 +                device_add(&m24_device);
  84.147                  return;
  84.148  
  84.149                  case ROM_PC2086:
  84.150                  case ROM_PC3086:
  84.151 +                device_add(&paradise_pvga1a_device);
  84.152 +                return;
  84.153                  case ROM_MEGAPC:
  84.154 -                video_load(vid_paradise);
  84.155 +                device_add(&paradise_wd90c11_device);
  84.156                  return;
  84.157                          
  84.158                  case ROM_ACER386:
  84.159 -                video_load(vid_oti067);
  84.160 +                device_add(&oti067_device);
  84.161                  return;
  84.162          }
  84.163          switch (gfxcard)
  84.164          {
  84.165                  case GFX_MDA:
  84.166 -                video_load(vid_mda);
  84.167 +                device_add(&mda_device);
  84.168                  break;
  84.169  
  84.170                  case GFX_HERCULES:
  84.171 -                video_load(vid_hercules);
  84.172 +                device_add(&hercules_device);
  84.173                  break;
  84.174                  
  84.175                  case GFX_CGA:
  84.176 -                video_load(vid_cga);
  84.177 +                device_add(&cga_device);
  84.178                  break;
  84.179                  
  84.180                  case GFX_EGA:
  84.181 -                video_load(vid_ega);
  84.182 +                device_add(&ega_device);
  84.183                  break;
  84.184                  
  84.185                  case GFX_TVGA:
  84.186 -                video_load(vid_tvga);
  84.187 +                device_add(&tvga8900d_device);
  84.188                  break;
  84.189                  
  84.190                  case GFX_ET4000:
  84.191 -                video_load(vid_et4000);
  84.192 +                device_add(&et4000_device);
  84.193                  break;
  84.194                  
  84.195                  case GFX_ET4000W32:
  84.196 -                video_load(vid_et4000w32p);
  84.197 +                device_add(&et4000w32p_device);
  84.198                  break;
  84.199  
  84.200                  case GFX_BAHAMAS64:
  84.201 -                video_load(vid_s3);
  84.202 +                device_add(&s3_bahamas64_device);
  84.203                  break;
  84.204  
  84.205                  case GFX_N9_9FX:
  84.206 -                video_load(vid_s3);
  84.207 +                device_add(&s3_9fx_device);
  84.208                  break;
  84.209                  
  84.210                  case GFX_STEALTH64:
  84.211 -                video_load(vid_s3);
  84.212                  break;
  84.213                  
  84.214                  case GFX_VIRGE:
  84.215 -                video_load(vid_s3_virge);
  84.216 +                device_add(&s3_virge_device);
  84.217                  break;
  84.218                  
  84.219                  case GFX_TGUI9440:
  84.220 -                video_load(vid_tgui9440);
  84.221 +                device_add(&tgui9440_device);
  84.222                  break;
  84.223                  
  84.224                  case GFX_VGA:
  84.225 -                video_load(vid_vga);
  84.226 +                device_add(&vga_device);
  84.227                  break;
  84.228  
  84.229                  case GFX_VGAEDGE16:
  84.230 -                video_load(vid_ati18800);
  84.231 +                device_add(&ati18800_device);
  84.232                  break;
  84.233  
  84.234                  case GFX_VGACHARGER:
  84.235 -                video_load(vid_ati28800);
  84.236 +                device_add(&ati18800_device);
  84.237                  break;
  84.238                                  
  84.239                  case GFX_OTI067:
  84.240 -                video_load(vid_oti067);
  84.241 +                device_add(&oti067_device);
  84.242                  return;
  84.243  
  84.244                  case GFX_MACH64GX:
  84.245 -                video_load(vid_mach64);
  84.246 +                device_add(&mach64gx_device);
  84.247                  return;
  84.248  
  84.249                  case GFX_CL_GD5429:
  84.250 -                video_load(vid_gd5429);
  84.251 +                device_add(&gd5429_device);
  84.252                  return;
  84.253  
  84.254                  default:
  84.255 @@ -263,78 +232,26 @@
  84.256          }
  84.257  }
  84.258  
  84.259 -uint32_t cga32[256];
  84.260  
  84.261 -BITMAP *buffer,*vbuf;//,*vbuf2;
  84.262 -BITMAP *buffer32;
  84.263 -int speshul=0;
  84.264 +BITMAP *buffer, *buffer32;
  84.265  
  84.266  uint8_t fontdat[256][8];
  84.267  uint8_t fontdatm[256][16];
  84.268  
  84.269 -int dispontime,dispofftime;
  84.270 -double disptime;
  84.271 -int svgaon;
  84.272 -uint8_t cgamode=1,cgastat,cgacol=7,ocgamode;
  84.273 -int linepos=0;
  84.274 -int output;
  84.275 -uint8_t *vram,*ram;
  84.276 +int xsize=1,ysize=1;
  84.277  
  84.278 -int cgadispon=0;
  84.279 -int cgablink;
  84.280  
  84.281 -uint8_t port3de,port3dd,port3df;
  84.282 +PALETTE cgapal;/* =
  84.283 +{
  84.284 +        { 0,  0,  0},{0,42,0},{42,0,0},{42,21,0},
  84.285 +        { 0,  0,  0},{0,42,42},{42,0,42},{42,42,42},
  84.286 +        { 0,  0,  0},{21,63,21},{63,21,21},{63,63,21},
  84.287 +        { 0,  0,  0},{21,63,63},{63,21,63},{63,63,63},
  84.288  
  84.289 -uint8_t crtc[128],crtcreg;
  84.290 -uint8_t crtcmask[128]={0xFF,0xFF,0xFF,0xFF,0x7F,0x1F,0x7F,0x7F,0xF3,0x1F,0x7F,0x1F,0x3F,0xFF,0x3F,0xFF,0xFF,0xFF};
  84.291 -uint8_t charbuffer[256];
  84.292 -int crtcams[64]={0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1};
  84.293 -int nmi=0;
  84.294 -
  84.295 -
  84.296 -int xsize=1,ysize=1;
  84.297 -int firstline=1000,lastline=0;
  84.298 -
  84.299 -int ntsc_col[8][8]=
  84.300 -{
  84.301 -        {0,0,0,0,0,0,0,0}, /*Black*/
  84.302 -        {0,0,1,1,1,1,0,0}, /*Blue*/
  84.303 -        {1,0,0,0,0,1,1,1}, /*Green*/
  84.304 -        {0,0,0,0,1,1,1,1}, /*Cyan*/
  84.305 -        {1,1,1,1,0,0,0,0}, /*Red*/
  84.306 -        {0,1,1,1,1,0,0,0}, /*Magenta*/
  84.307 -        {1,1,0,0,0,0,1,1}, /*Yellow*/
  84.308 -        {1,1,1,1,1,1,1,1}  /*White*/
  84.309 -};
  84.310 -
  84.311 -
  84.312 -extern int fullchange;
  84.313 -
  84.314 -extern uint32_t vrammask;
  84.315 -
  84.316 -
  84.317 -int mdacols[256][2][2];
  84.318 -uint8_t gdcreg[16];
  84.319 -
  84.320 -
  84.321 -int cga4pal[8][4]=
  84.322 -{
  84.323 -        {0,2,4,6},{0,3,5,7},{0,3,4,7},{0,3,4,7},
  84.324 -        {0,10,12,14},{0,11,13,15},{0,11,12,15},{0,11,12,15}
  84.325 -};
  84.326 -
  84.327 -
  84.328 -PALETTE cgapal=
  84.329 -{
  84.330 -        {0,0,0},{0,42,0},{42,0,0},{42,21,0},
  84.331 -        {0,0,0},{0,42,42},{42,0,42},{42,42,42},
  84.332 -        {0,0,0},{21,63,21},{63,21,21},{63,63,21},
  84.333 -        {0,0,0},{21,63,63},{63,21,63},{63,63,63},
  84.334 -
  84.335 -        {0,0,0},{0,0,42},{0,42,0},{0,42,42},
  84.336 -        {42,0,0},{42,0,42},{42,21,00},{42,42,42},
  84.337 -        {21,21,21},{21,21,63},{21,63,21},{21,63,63},
  84.338 -        {63,21,21},{63,21,63},{63,63,21},{63,63,63},
  84.339 +        {0,   0,  0}, { 0,  0, 42}, { 0, 42,  0}, { 0, 42, 42},
  84.340 +        {42,  0,  0}, {42,  0, 42}, {42, 21, 00}, {42, 42, 42},
  84.341 +        {21, 21, 21}, {21, 21, 63}, {21, 63, 21}, {21, 63, 63},
  84.342 +        {63, 21, 21}, {63, 21, 63}, {63, 63, 21}, {63, 63, 63},
  84.343  
  84.344          {0,0,0},{0,21,0},{0,0,42},{0,42,42},
  84.345          {42,0,21},{21,10,21},{42,0,42},{42,0,63},
  84.346 @@ -345,7 +262,7 @@
  84.347          {0,0,0},{0,42,42},{42,0,0},{42,42,42},
  84.348          {0,0,0},{0,63,63},{63,0,0},{63,63,63},
  84.349          {0,0,0},{0,63,63},{63,0,0},{63,63,63},
  84.350 -};
  84.351 +};*/
  84.352  
  84.353  void loadfont(char *s, int format)
  84.354  {
  84.355 @@ -419,102 +336,53 @@
  84.356  }
  84.357  
  84.358  
  84.359 -void drawscreen()
  84.360 -{
  84.361 -//        printf("Drawscreen %i %i %i %i\n",gfxcard,MDA,EGA,TANDY);
  84.362 -//        if (EGA) drawscreenega(buffer,vbuf);
  84.363 -/*        else if (MDA) {}//drawscreenmda();
  84.364 -        else if (TANDY)
  84.365 -        {
  84.366 -                if ((cgamode&3)==3 || array[3]&0x10) drawscreentandy(tandyvram);
  84.367 -                else                drawscreencga(tandyvram);
  84.368 -        }*/
  84.369 -//        else            drawscreencga(&vram[0x8000]);
  84.370 -}
  84.371 -
  84.372 -PALETTE comppal=
  84.373 -{
  84.374 -        {0,0,0},{0,21,0},{0,0,42},{0,42,42},
  84.375 -        {42,0,21},{21,10,21},{42,0,42},{42,0,63},
  84.376 -        {21,21,21},{21,63,21},{42,21,42},{21,63,31},
  84.377 -        {63,0,0},{42,42,0},{63,21,42},{41,41,41}
  84.378 -};
  84.379 -
  84.380  void initvideo()
  84.381  {
  84.382 -        int c;
  84.383 -//        set_color_depth(desktop_color_depth());
  84.384 -//        if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,2048,2048,0,0))
  84.385 -//           set_gfx_mode(GFX_AUTODETECT_WINDOWED,1024,768,0,0);
  84.386 -//        vbuf=create_video_bitmap(1280+32,1024+32);
  84.387 -//        set_color_depth(32);
  84.388 -        buffer32=create_bitmap(2048,2048);
  84.389 -//        set_color_depth(8);
  84.390 -        buffer=create_bitmap(2048,2048);
  84.391 -//        set_color_depth(32);
  84.392 -        for (c=0;c<64;c++)
  84.393 +        int c, d, e;
  84.394 +
  84.395 +        buffer32 = create_bitmap(2048, 2048);
  84.396 +
  84.397 +        buffer = create_bitmap(2048, 2048);
  84.398 +
  84.399 +        for (c = 0; c < 64; c++)
  84.400          {
  84.401 -                cgapal[c+64].r=(((c&4)?2:0)|((c&0x10)?1:0))*21;
  84.402 -                cgapal[c+64].g=(((c&2)?2:0)|((c&0x10)?1:0))*21;
  84.403 -                cgapal[c+64].b=(((c&1)?2:0)|((c&0x10)?1:0))*21;
  84.404 -                if ((c&0x17)==6) cgapal[c+64].g>>=1;
  84.405 +                cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
  84.406 +                cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
  84.407 +                cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
  84.408 +                if ((c & 0x17) == 6) 
  84.409 +                        cgapal[c + 64].g >>= 1;
  84.410          }
  84.411 -        for (c=0;c<64;c++)
  84.412 +        for (c = 0; c < 64; c++)
  84.413          {
  84.414 -                cgapal[c+128].r=(((c&4)?2:0)|((c&0x20)?1:0))*21;
  84.415 -                cgapal[c+128].g=(((c&2)?2:0)|((c&0x10)?1:0))*21;
  84.416 -                cgapal[c+128].b=(((c&1)?2:0)|((c&0x08)?1:0))*21;
  84.417 +                cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21;
  84.418 +                cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
  84.419 +                cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21;
  84.420          }
  84.421 -        for (c=0;c<256;c++) cga32[c]=makecol(cgapal[c].r<<2,cgapal[c].g<<2,cgapal[c].b<<2);
  84.422 -//        for (c=0;c<16;c++) cgapal[c+192]=comppal[c];
  84.423 -//        set_palette(cgapal);
  84.424 -        if (MDA && !TANDY && !AMSTRAD && romset!=ROM_PC200) updatewindowsize(720,350);
  84.425 -        else                                                updatewindowsize(656,416);
  84.426 -        for (c=17;c<64;c++) crtcmask[c]=0xFF;
  84.427 -}
  84.428  
  84.429 -void resetvideo()
  84.430 -{
  84.431 -        int c;
  84.432 -        if (MDA && !TANDY && !AMSTRAD && romset!=ROM_PC200) updatewindowsize(720,350);
  84.433 -        else                                                updatewindowsize(656,416);
  84.434 -        cgastat=0;
  84.435 -        set_palette(cgapal);
  84.436 -
  84.437 -        for (c=18;c<64;c++) crtcmask[c]=0xFF;
  84.438 -        crtc[0]=0x38;
  84.439 -        crtc[1]=0x28;
  84.440 -//        crtc[3]=0xFA;
  84.441 -        crtc[4]=0x7F;
  84.442 -        crtc[5]=0x06;
  84.443 -        crtc[6]=0x64;
  84.444 -        crtc[7]=0x70;
  84.445 -        crtc[8]=0x02;
  84.446 -        crtc[9]=1;
  84.447 -
  84.448 -        cgacol=7;
  84.449 -        for (c=0;c<256;c++)
  84.450 +        for (c = 0; c < 256; c++)
  84.451          {
  84.452 -                mdacols[c][0][0]=mdacols[c][1][0]=mdacols[c][1][1]=16;
  84.453 -                if (c&8) mdacols[c][0][1]=15+16;
  84.454 -                else     mdacols[c][0][1]=7+16;
  84.455 +                e = c;
  84.456 +                for (d = 0; d < 8; d++)
  84.457 +                {
  84.458 +                        rotatevga[d][c] = e;
  84.459 +                        e = (e >> 1) | ((e & 1) ? 0x80 : 0);
  84.460 +                }
  84.461          }
  84.462 -        mdacols[0x70][0][1]=16;
  84.463 -        mdacols[0x70][0][0]=mdacols[0x70][1][0]=mdacols[0x70][1][1]=16+15;
  84.464 -        mdacols[0xF0][0][1]=16;
  84.465 -        mdacols[0xF0][0][0]=mdacols[0xF0][1][0]=mdacols[0xF0][1][1]=16+15;
  84.466 -        mdacols[0x78][0][1]=16+7;
  84.467 -        mdacols[0x78][0][0]=mdacols[0x78][1][0]=mdacols[0x78][1][1]=16+15;
  84.468 -        mdacols[0xF8][0][1]=16+7;
  84.469 -        mdacols[0xF8][0][0]=mdacols[0xF8][1][0]=mdacols[0xF8][1][1]=16+15;
  84.470 -        mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16;
  84.471 -        mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16;
  84.472 -        mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16;
  84.473 -        mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
  84.474 +        for (c = 0; c < 4; c++)
  84.475 +        {
  84.476 +                for (d = 0; d < 4; d++)
  84.477 +                {
  84.478 +                        edatlookup[c][d] = 0;
  84.479 +                        if (c & 1) edatlookup[c][d] |= 1;
  84.480 +                        if (d & 1) edatlookup[c][d] |= 2;
  84.481 +                        if (c & 2) edatlookup[c][d] |= 0x10;
  84.482 +                        if (d & 2) edatlookup[c][d] |= 0x20;
  84.483 +//                        printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]);
  84.484 +                }
  84.485 +        }
  84.486  }
  84.487  
  84.488  void closevideo()
  84.489  {
  84.490          destroy_bitmap(buffer);
  84.491 -        destroy_bitmap(vbuf);
  84.492  }
    85.1 --- a/src/video.h	Tue Jun 04 20:52:17 2013 +0100
    85.2 +++ b/src/video.h	Mon Jun 24 20:42:35 2013 +0100
    85.3 @@ -1,70 +1,8 @@
    85.4  extern int egareads,egawrites;
    85.5  
    85.6 -extern int bpp;
    85.7 -extern uint8_t svgaseg,svgaseg2;
    85.8 -
    85.9 -extern uint8_t crtcreg;
   85.10 -extern uint8_t crtc[128];
   85.11 -extern uint8_t crtcmask[128];
   85.12 -extern uint8_t gdcreg[16];
   85.13 -extern int gdcaddr;
   85.14 -extern uint8_t attrregs[32];
   85.15 -extern int attraddr,attrff;
   85.16 -extern uint8_t seqregs[64];
   85.17 -extern int seqaddr;
   85.18 -extern int svgaon;
   85.19 -
   85.20 -extern uint8_t cgamode,cgacol,cgastat;
   85.21 -extern int egapal[16];
   85.22 -
   85.23 -extern int scrblank;
   85.24 -
   85.25 -extern uint8_t writemask,charset;
   85.26 -extern int charseta,charsetb;
   85.27 -extern uint8_t colourcompare,colournocare;
   85.28 -extern int readplane,readmode,writemode;
   85.29 -
   85.30 -extern int vidclock;
   85.31 -extern int vres;
   85.32 -
   85.33 -extern uint32_t *pallook,pallook16[256],pallook64[256],pallook256[256];
   85.34 -
   85.35  extern int fullchange;
   85.36  extern int changeframecount;
   85.37  
   85.38 -extern int firstline,lastline;
   85.39 -extern int ega_hdisp,ega_rowoffset,ega_split,ega_dispend,ega_vsyncstart,ega_vtotal;
   85.40 -extern int dispontime,dispofftime;
   85.41 -extern double disptime;
   85.42 -
   85.43 -extern void (*video_out)     (uint16_t addr, uint8_t val, void *priv);
   85.44 -extern void (*video_mono_out)(uint16_t addr, uint8_t val, void *priv);
   85.45 -extern uint8_t (*video_in)     (uint16_t addr, void *priv);
   85.46 -extern uint8_t (*video_mono_in)(uint16_t addr, void *priv);
   85.47 -
   85.48 -extern void (*video_write_a000)(uint32_t addr, uint8_t val, void *priv);
   85.49 -extern void (*video_write_b000)(uint32_t addr, uint8_t val, void *priv);
   85.50 -extern void (*video_write_b800)(uint32_t addr, uint8_t val, void *priv);
   85.51 -
   85.52 -extern uint8_t (*video_read_a000)(uint32_t addr, void *priv);
   85.53 -extern uint8_t (*video_read_b000)(uint32_t addr, void *priv);
   85.54 -extern uint8_t (*video_read_b800)(uint32_t addr, void *priv);
   85.55 -
   85.56 -extern void (*video_write_a000_w)(uint32_t addr, uint16_t val, void *priv);
   85.57 -extern void (*video_write_a000_l)(uint32_t addr, uint32_t val, void *priv);
   85.58 -
   85.59 -extern void    video_out_null(uint16_t addr, uint8_t val, void *priv);
   85.60 -extern uint8_t video_in_null(uint16_t addr, void *priv);
   85.61 -
   85.62 -extern void    video_write_null(uint32_t addr, uint8_t val, void *priv);
   85.63 -extern uint8_t video_read_null (uint32_t addr, void *priv);
   85.64 -
   85.65 -
   85.66 -extern int video_timer;
   85.67 -
   85.68 -extern uint8_t tridentoldctrl2,tridentnewctrl2;
   85.69 -extern int rowdbl;
   85.70 -
   85.71  typedef struct
   85.72  {
   85.73          int w, h;
   85.74 @@ -72,73 +10,23 @@
   85.75          uint8_t *line[0];
   85.76  } BITMAP;
   85.77  
   85.78 -extern BITMAP *buffer,*buffer32,*vbuf;
   85.79 +extern BITMAP *buffer, *buffer32;
   85.80  
   85.81  extern BITMAP *screen;
   85.82  
   85.83  BITMAP *create_bitmap(int w, int h);
   85.84  
   85.85 -extern int wx,wy;
   85.86 -
   85.87  extern uint8_t fontdat[256][8];
   85.88  extern uint8_t fontdatm[256][16];
   85.89  
   85.90 -
   85.91  extern int xsize,ysize;
   85.92  
   85.93 -extern int dacread,dacwrite,dacpos;
   85.94 -
   85.95  typedef struct
   85.96  {
   85.97          uint8_t r, g, b;
   85.98  } RGB;
   85.99          
  85.100  typedef RGB PALETTE[256];
  85.101 -extern PALETTE vgapal;
  85.102 -extern int palchange;
  85.103 -
  85.104 -
  85.105 -extern uint32_t vrammask;
  85.106 -
  85.107 -typedef struct
  85.108 -{
  85.109 -        int     (*init)();
  85.110 -        void    (*out)(uint16_t addr, uint8_t val, void *priv);
  85.111 -        uint8_t (*in)(uint16_t addr, void *priv);
  85.112 -        void    (*mono_out)(uint16_t addr, uint8_t val, void *priv);
  85.113 -        uint8_t (*mono_in)(uint16_t addr, void *priv);
  85.114 -        void    (*poll)();
  85.115 -        void    (*recalctimings)();
  85.116 -        void    (*write_a000)(uint32_t addr, uint8_t val, void *priv);
  85.117 -        void    (*write_b000)(uint32_t addr, uint8_t val, void *priv);
  85.118 -        void    (*write_b800)(uint32_t addr, uint8_t val, void *priv);
  85.119 -        uint8_t (*read_a000)(uint32_t addr, void *priv);
  85.120 -        uint8_t (*read_b000)(uint32_t addr, void *priv);
  85.121 -        uint8_t (*read_b800)(uint32_t addr, void *priv);
  85.122 -} GFXCARD;
  85.123 -
  85.124 -extern GFXCARD vid_cga;
  85.125 -extern GFXCARD vid_mda;
  85.126 -extern GFXCARD vid_hercules;
  85.127 -extern GFXCARD vid_pc1512;
  85.128 -extern GFXCARD vid_pc1640;
  85.129 -extern GFXCARD vid_pc200;
  85.130 -extern GFXCARD vid_m24;
  85.131 -extern GFXCARD vid_paradise;
  85.132 -extern GFXCARD vid_tandy;
  85.133 -extern GFXCARD vid_ega;
  85.134 -extern GFXCARD vid_oti067;
  85.135 -extern GFXCARD vid_tvga;
  85.136 -extern GFXCARD vid_et4000;
  85.137 -extern GFXCARD vid_et4000w32p;
  85.138 -extern GFXCARD vid_s3;
  85.139 -extern GFXCARD vid_s3_virge;
  85.140 -extern GFXCARD vid_tgui9440;
  85.141 -extern GFXCARD vid_vga;
  85.142 -extern GFXCARD vid_ati18800;
  85.143 -extern GFXCARD vid_ati28800;
  85.144 -extern GFXCARD vid_mach64;
  85.145 -extern GFXCARD vid_gd5429;
  85.146  
  85.147  extern float cpuclock;
  85.148  
  85.149 @@ -154,7 +42,6 @@
  85.150  extern void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h);
  85.151  extern void (*video_blit_memtoscreen_8)(int x, int y, int w, int h);
  85.152  
  85.153 -
  85.154  extern int video_timing_b, video_timing_w, video_timing_l;
  85.155  extern int video_speed;
  85.156  
    86.1 --- a/src/win.c	Tue Jun 04 20:52:17 2013 +0100
    86.2 +++ b/src/win.c	Mon Jun 24 20:42:35 2013 +0100
    86.3 @@ -377,6 +377,9 @@
    86.4                          }
    86.5                  }
    86.6          }
    86.7 +
    86.8 +        loadbios();
    86.9 +
   86.10          timeBeginPeriod(1);
   86.11  //        soundobject=CreateEvent(NULL, FALSE, FALSE, NULL);
   86.12  //        soundthreadh=CreateThread(NULL,0,soundthread,NULL,NULL,NULL);
   86.13 @@ -758,8 +761,8 @@
   86.14                                          sound_card_current = temp_sound_card_current;
   86.15                                          
   86.16                                          mem_resize();
   86.17 +                                        mem_load_video_bios();
   86.18                                          loadbios();
   86.19 -                                        mem_load_video_bios();
   86.20                                          resetpchard();
   86.21                                  }
   86.22                                  else
   86.23 @@ -1327,6 +1330,7 @@
   86.24  {
   86.25          int egasp;
   86.26          char s[256];
   86.27 +        char device_s[4096];
   86.28          switch (message)
   86.29          {
   86.30                  case WM_INITDIALOG:
   86.31 @@ -1350,18 +1354,8 @@
   86.32                  SendDlgItemMessage(hdlg,IDC_STEXT7,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
   86.33                  sprintf(s,"Timer 0 frequency : %fHz",pit_timer0_freq());
   86.34                  SendDlgItemMessage(hdlg,IDC_STEXT8,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
   86.35 -                if (chain4) sprintf(s,"VGA chained (possibly mode 13h)");
   86.36 -                else        sprintf(s,"VGA unchained (possibly mode-X)");
   86.37 -                SendDlgItemMessage(hdlg,IDC_STEXT9,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
   86.38 -/*                if (!video_bpp) sprintf(s,"VGA in text mode");
   86.39 -                else            */sprintf(s,"VGA colour depth : %i bpp", video_bpp);
   86.40 -                SendDlgItemMessage(hdlg,IDC_STEXT10,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
   86.41 -                sprintf(s,"VGA resolution : %i x %i", video_res_x, video_res_y);
   86.42 -                SendDlgItemMessage(hdlg,IDC_STEXT11,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
   86.43 -                sprintf(s,"SB frequency : %i Hz",0);
   86.44 -                SendDlgItemMessage(hdlg,IDC_STEXT12,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
   86.45 -                sprintf(s,"Video refresh rate : %i Hz", emu_fps);
   86.46 -                SendDlgItemMessage(hdlg,IDC_STEXT13,WM_SETTEXT,(WPARAM)NULL,(LPARAM)s);
   86.47 +                device_add_status_info(device_s, 4096);
   86.48 +                SendDlgItemMessage(hdlg,IDC_STEXT_DEVICE,WM_SETTEXT,(WPARAM)NULL,(LPARAM)device_s);
   86.49                  return TRUE;
   86.50                  case WM_COMMAND:
   86.51                  switch (LOWORD(wParam))