PCem

changeset 84:b53e148867e5

Implemented preliminary S3 ViRGE 2D blitter emulation. Misc ViRGE fixes. Changes to memory mapping. Changes to PCI handling. Disabled 'AMI WinBIOS 486 PCI' due to incomplete chipset emulation. Invalid GUS register reads no longer kill the emulator.
author TomW
date Thu Mar 20 14:03:55 2014 +0000
parents a887728dc348
children 3b1a61addfa4
files src/386.c src/808x.c src/Makefile.mingw src/ali1429.c src/ega.c src/headland.c src/i430vx.c src/mem.c src/mem.h src/model.c src/model.h src/pc.c src/pc.rc src/pci.h src/rom.c src/rom.h src/sis496.c src/sound_gus.c src/um8881f.c src/vid_ati18800.c src/vid_ati28800.c src/vid_ati_mach64.c src/vid_cga.c src/vid_cl5429.c src/vid_ega.c src/vid_ega.h src/vid_et4000.c src/vid_et4000w32.c src/vid_hercules.c src/vid_mda.c src/vid_olivetti_m24.c src/vid_oti067.c src/vid_oti067.h src/vid_paradise.c src/vid_paradise.h src/vid_pc1512.c src/vid_pc1640.c src/vid_pc200.c src/vid_pcjr.c src/vid_s3.c src/vid_s3_virge.c src/vid_svga.c src/vid_tandy.c src/vid_tgui9440.c src/vid_tvga.c src/vid_vga.c src/vid_voodoo.c src/video.c src/win.c
diffstat 49 files changed, 2111 insertions(+), 733 deletions(-) [+]
line diff
     1.1 --- a/src/386.c	Sun Mar 09 11:24:58 2014 +0000
     1.2 +++ b/src/386.c	Thu Mar 20 14:03:55 2014 +0000
     1.3 @@ -64,7 +64,7 @@
     1.4  uint32_t mmucache[0x100000];
     1.5  
     1.6  uint8_t romext[32768];
     1.7 -uint8_t *ram,*rom,*vram,*vrom;
     1.8 +uint8_t *ram,*rom;
     1.9  uint16_t biosmask;
    1.10  
    1.11  uint32_t rmdat32;
     2.1 --- a/src/808x.c	Sun Mar 09 11:24:58 2014 +0000
     2.2 +++ b/src/808x.c	Thu Mar 20 14:03:55 2014 +0000
     2.3 @@ -561,14 +561,8 @@
     2.4          f=fopen("ram8.bin","wb");
     2.5          fwrite(ram+0x3D210,0x200,1,f);
     2.6          fclose(f);        */
     2.7 -        f=fopen("vram.dmp","wb");
     2.8 -        fwrite(vram,0x400000,1,f);
     2.9 -        fclose(f);
    2.10  /*        f=fopen("bios.dmp","wb");
    2.11          fwrite(rom,0x20000,1,f);
    2.12 -        fclose(f);
    2.13 -        f=fopen("vbios.dmp","wb");
    2.14 -        fwrite(vrom,0x8000,1,f);
    2.15          fclose(f);*/
    2.16  /*        f=fopen("kernel.dmp","wb");
    2.17          for (c=0;c<0x200000;c++) putc(readmemb(c+0xC0000000),f);
     3.1 --- a/src/Makefile.mingw	Sun Mar 09 11:24:58 2014 +0000
     3.2 +++ b/src/Makefile.mingw	Thu Mar 20 14:03:55 2014 +0000
     3.3 @@ -4,7 +4,7 @@
     3.4  WINDRES = windres.exe
     3.5  CFLAGS = -O3 -march=i686 -fomit-frame-pointer
     3.6  OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \
     3.7 -	config.o cpu.o dac.o device.o dma.o ega.o fdc.o \
     3.8 +	config.o cpu.o dac.o device.o dma.o fdc.o \
     3.9  	headland.o i430vx.o ide.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \
    3.10  	keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o \
    3.11  	mouse.o mouse_ps2.o mouse_serial.o neat.o nvr.o olivetti_m24.o \
     4.1 --- a/src/ali1429.c	Sun Mar 09 11:24:58 2014 +0000
     4.2 +++ b/src/ali1429.c	Thu Mar 20 14:03:55 2014 +0000
     4.3 @@ -9,9 +9,42 @@
     4.4  static int ali1429_index;
     4.5  static uint8_t ali1429_regs[256];
     4.6  
     4.7 +static void ali1429_recalc()
     4.8 +{
     4.9 +        int c;
    4.10 +        
    4.11 +        for (c = 0; c < 8; c++)
    4.12 +        {
    4.13 +                uint32_t base = 0xc0000 + (c << 15);
    4.14 +                if (ali1429_regs[0x13] & (1 << c))
    4.15 +                {
    4.16 +                        switch (ali1429_regs[0x14] & 3)
    4.17 +                        {
    4.18 +                                case 0:
    4.19 +                                mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
    4.20 +                                break;
    4.21 +                                case 1: 
    4.22 +                                mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
    4.23 +                                break;
    4.24 +                                case 2:
    4.25 +                                mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
    4.26 +                                break;
    4.27 +                                case 3:
    4.28 +                                mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
    4.29 +                                break;
    4.30 +                        }
    4.31 +                }
    4.32 +                else
    4.33 +                        mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
    4.34 +        }
    4.35 +        
    4.36 +        flushmmucache();
    4.37 +}
    4.38 +
    4.39  void ali1429_write(uint16_t port, uint8_t val, void *priv)
    4.40  {
    4.41 -//        return;
    4.42 +        int c;
    4.43 +        
    4.44          if (!(port & 1)) 
    4.45                  ali1429_index = val;
    4.46          else
    4.47 @@ -21,35 +54,12 @@
    4.48                  switch (ali1429_index)
    4.49                  {
    4.50                          case 0x13:
    4.51 -                        if (!(val & 0xc0)) 
    4.52 -                        {
    4.53 -                                shadowbios = 0;
    4.54 -                                if (!shadowbios_write)
    4.55 -                                        mem_bios_set_state(0xf0000, 0x10000, 0, 0);
    4.56 -                                else
    4.57 -                                        mem_bios_set_state(0xf0000, 0x10000, 0, 1);
    4.58 -                                flushmmucache();
    4.59 -                        }                                        
    4.60 +                        ali1429_recalc();
    4.61                          break;
    4.62                          case 0x14:
    4.63                          shadowbios = val & 1;
    4.64                          shadowbios_write = val & 2;
    4.65 -                        switch (val & 3)
    4.66 -                        {
    4.67 -                                case 0: 
    4.68 -                                mem_bios_set_state(0xf0000, 0x10000, 0, 0);
    4.69 -                                break;
    4.70 -                                case 1: 
    4.71 -                                mem_bios_set_state(0xf0000, 0x10000, 1, 0);
    4.72 -                                break;
    4.73 -                                case 2:
    4.74 -                                mem_bios_set_state(0xf0000, 0x10000, 0, 1);
    4.75 -                                break;
    4.76 -                                case 3:
    4.77 -                                mem_bios_set_state(0xf0000, 0x10000, 1, 1);
    4.78 -                                break;
    4.79 -                        }                                                                                                
    4.80 -                        flushmmucache();
    4.81 +                        ali1429_recalc();
    4.82                          break;
    4.83                  }
    4.84          }
     5.1 --- a/src/ega.c	Sun Mar 09 11:24:58 2014 +0000
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,32 +0,0 @@
     5.4 -#include "ibm.h"
     5.5 -#include "video.h"
     5.6 -
     5.7 -
     5.8 -void dumpegaregs()
     5.9 -{
    5.10 -/*        int c;
    5.11 -        printf("CRTC :");
    5.12 -        for (c=0;c<0x20;c++) printf(" %02X",crtc[c]);
    5.13 -        printf("\n");
    5.14 -        printf(" EXT :");
    5.15 -        for (c=0;c<0x20;c++) printf(" %02X",crtc[c+32]);
    5.16 -        printf("\n");
    5.17 -        printf(" EXT2:");
    5.18 -        for (c=0;c<0x20;c++) printf(" %02X",crtc[c+64]);
    5.19 -        printf("\n");
    5.20 -        printf("SEQ  :");
    5.21 -        for (c=0;c<0x10;c++) printf(" %02X",seqregs[c]);
    5.22 -        printf("\n");
    5.23 -        printf(" EXT :");
    5.24 -        for (c=0;c<0x10;c++) printf(" %02X",seqregs[c + 0x10]);
    5.25 -        printf("\n");
    5.26 -        printf("ATTR :");
    5.27 -        for (c=0;c<0x20;c++) printf(" %02X",attrregs[c]);
    5.28 -        printf("\n");
    5.29 -        printf("GDC  :");
    5.30 -        for (c=0;c<0x10;c++) printf(" %02X",gdcreg[c]);
    5.31 -        printf("\n");
    5.32 -//        printf("OLD CTRL2 = %02X  NEW CTRL2 = %02X  DAC = %02X  3C2 = %02X\n",tridentoldctrl2,tridentnewctrl2,tridentdac,ega3c2);
    5.33 -        printf("BPP = %02X\n",bpp);*/
    5.34 -}
    5.35 -
     6.1 --- a/src/headland.c	Sun Mar 09 11:24:58 2014 +0000
     6.2 +++ b/src/headland.c	Thu Mar 20 14:03:55 2014 +0000
     6.3 @@ -20,9 +20,9 @@
     6.4                          shadowbios = val & 0x10;
     6.5                          shadowbios_write = !(val & 0x10);
     6.6                          if (shadowbios)
     6.7 -                                mem_bios_set_state(0xf0000, 0x10000, 1, 0);
     6.8 +                                mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
     6.9                          else
    6.10 -                                mem_bios_set_state(0xf0000, 0x10000, 0, 1);
    6.11 +                                mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
    6.12                  }
    6.13          }
    6.14          else
     7.1 --- a/src/i430vx.c	Sun Mar 09 11:24:58 2014 +0000
     7.2 +++ b/src/i430vx.c	Thu Mar 20 14:03:55 2014 +0000
     7.3 @@ -13,16 +13,22 @@
     7.4  {
     7.5          switch (state & 3)
     7.6          {
     7.7 -                case 0x0: mem_bios_set_state(addr, size, 0, 0); break; /*DRAM disabled, accesses directed to PCI bus*/
     7.8 -                case 0x1: mem_bios_set_state(addr, size, 1, 0); break; /*Read only, DRAM write protected, non-cacheable*/
     7.9 -                case 0x2: mem_bios_set_state(addr, size, 0, 1); break; /*Write only*/
    7.10 -                case 0x3: mem_bios_set_state(addr, size, 1, 1); break; /*Read/write, non-cacheable*/
    7.11 -                /*Below are redundant*/
    7.12 -//                case 0x5: mem_sethandler(addr, size, mem_read_ram,    mem_read_ramw,    mem_read_raml,    NULL,          NULL,           NULL          ); break; /*Read only, DRAM write protected, cacheable*/
    7.13 -//                case 0x7: mem_sethandler(addr, size, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml); break; /*Read/write, non-cacheable*/                
    7.14 +                case 0:
    7.15 +                mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
    7.16 +                break;
    7.17 +                case 1:
    7.18 +                mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
    7.19 +                break;
    7.20 +                case 2:
    7.21 +                mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
    7.22 +                break;
    7.23 +                case 3:
    7.24 +                mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
    7.25 +                break;
    7.26          }
    7.27          flushmmucache_nopc();        
    7.28  }
    7.29 +
    7.30  void i430vx_write(int func, int addr, uint8_t val, void *priv)
    7.31  {
    7.32          if (func)
    7.33 @@ -43,18 +49,42 @@
    7.34                  }
    7.35                  pclog("i430vx_write : PAM0 write %02X\n", val);
    7.36                  break;
    7.37 +                case 0x5a: /*PAM1*/
    7.38 +                if ((card_i430vx[0x5a] ^ val) & 0x0f)
    7.39 +                        i430vx_map(0xc0000, 0x04000, val & 0xf);
    7.40 +                if ((card_i430vx[0x5a] ^ val) & 0xf0)
    7.41 +                        i430vx_map(0xc4000, 0x04000, val >> 4);
    7.42 +                break;
    7.43 +                case 0x5b: /*PAM2*/
    7.44 +                if ((card_i430vx[0x5b] ^ val) & 0x0f)
    7.45 +                        i430vx_map(0xc8000, 0x04000, val & 0xf);
    7.46 +                if ((card_i430vx[0x5b] ^ val) & 0xf0)
    7.47 +                        i430vx_map(0xcc000, 0x04000, val >> 4);
    7.48 +                break;
    7.49 +                case 0x5c: /*PAM3*/
    7.50 +                if ((card_i430vx[0x5c] ^ val) & 0x0f)
    7.51 +                        i430vx_map(0xd0000, 0x04000, val & 0xf);
    7.52 +                if ((card_i430vx[0x5c] ^ val) & 0xf0)
    7.53 +                        i430vx_map(0xd4000, 0x04000, val >> 4);
    7.54 +                break;
    7.55 +                case 0x5d: /*PAM4*/
    7.56 +                if ((card_i430vx[0x5d] ^ val) & 0x0f)
    7.57 +                        i430vx_map(0xd8000, 0x04000, val & 0xf);
    7.58 +                if ((card_i430vx[0x5d] ^ val) & 0xf0)
    7.59 +                        i430vx_map(0xdc000, 0x04000, val >> 4);
    7.60 +                break;
    7.61                  case 0x5e: /*PAM5*/
    7.62                  if ((card_i430vx[0x5e] ^ val) & 0x0f)
    7.63 -                   i430vx_map(0xe0000, 0x04000, val & 0xf);
    7.64 +                        i430vx_map(0xe0000, 0x04000, val & 0xf);
    7.65                  if ((card_i430vx[0x5e] ^ val) & 0xf0)
    7.66 -                   i430vx_map(0xe4000, 0x04000, val >> 4);
    7.67 +                        i430vx_map(0xe4000, 0x04000, val >> 4);
    7.68                  pclog("i430vx_write : PAM5 write %02X\n", val);
    7.69                  break;
    7.70                  case 0x5f: /*PAM6*/
    7.71                  if ((card_i430vx[0x5f] ^ val) & 0x0f)
    7.72 -                   i430vx_map(0xe8000, 0x04000, val & 0xf);
    7.73 +                        i430vx_map(0xe8000, 0x04000, val & 0xf);
    7.74                  if ((card_i430vx[0x5f] ^ val) & 0xf0)
    7.75 -                   i430vx_map(0xec000, 0x04000, val >> 4);
    7.76 +                        i430vx_map(0xec000, 0x04000, val >> 4);
    7.77                  pclog("i430vx_write : PAM6 write %02X\n", val);
    7.78                  break;
    7.79          }
     8.1 --- a/src/mem.c	Sun Mar 09 11:24:58 2014 +0000
     8.2 +++ b/src/mem.c	Thu Mar 20 14:03:55 2014 +0000
     8.3 @@ -16,20 +16,25 @@
     8.4  #include "cpu.h"
     8.5  #include "rom.h"
     8.6  
     8.7 -static uint8_t       (*_mem_read_b[0x40000])(uint32_t addr, void *priv);
     8.8 -static uint16_t      (*_mem_read_w[0x40000])(uint32_t addr, void *priv);
     8.9 -static uint32_t      (*_mem_read_l[0x40000])(uint32_t addr, void *priv);
    8.10 -static void         (*_mem_write_b[0x40000])(uint32_t addr, uint8_t  val, void *priv);
    8.11 -static void         (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv);
    8.12 -static void         (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv);
    8.13 -static void             *_mem_priv[0x40000];
    8.14 -static mem_mapping_t *_mem_mapping[0x40000];
    8.15 +static uint8_t         (*_mem_read_b[0x40000])(uint32_t addr, void *priv);
    8.16 +static uint16_t        (*_mem_read_w[0x40000])(uint32_t addr, void *priv);
    8.17 +static uint32_t        (*_mem_read_l[0x40000])(uint32_t addr, void *priv);
    8.18 +static void           (*_mem_write_b[0x40000])(uint32_t addr, uint8_t  val, void *priv);
    8.19 +static void           (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv);
    8.20 +static void           (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv);
    8.21 +static uint8_t            *_mem_exec[0x40000];
    8.22 +static void             *_mem_priv_r[0x40000];
    8.23 +static void             *_mem_priv_w[0x40000];
    8.24 +static mem_mapping_t *_mem_mapping_r[0x40000];
    8.25 +static mem_mapping_t *_mem_mapping_w[0x40000];
    8.26 +static int                _mem_state[0x40000];
    8.27  
    8.28  static mem_mapping_t base_mapping;
    8.29  static mem_mapping_t ram_low_mapping;
    8.30  static mem_mapping_t ram_high_mapping;
    8.31 +static mem_mapping_t ram_mid_mapping;
    8.32  static mem_mapping_t bios_mapping[8];
    8.33 -static mem_mapping_t vrom_mapping;
    8.34 +static mem_mapping_t bios_high_mapping[8];
    8.35  static mem_mapping_t romext_mapping;
    8.36  
    8.37  int shadowbios,shadowbios_write;
    8.38 @@ -42,7 +47,7 @@
    8.39  int readlnum=0,writelnum=0;
    8.40  int cachesize=256;
    8.41  
    8.42 -uint8_t *ram,*rom,*vram,*vrom;
    8.43 +uint8_t *ram,*rom,*vram;
    8.44  uint8_t romext[32768];
    8.45  
    8.46  static void mem_load_xtide_bios()
    8.47 @@ -71,179 +76,6 @@
    8.48          }
    8.49  }
    8.50  
    8.51 -int mem_load_video_bios()
    8.52 -{
    8.53 -        FILE *f = NULL;
    8.54 -        int c;
    8.55 -        switch (gfxcard)
    8.56 -        {
    8.57 -                case GFX_EGA:
    8.58 -                f=romfopen("roms/ibm_6277356_ega_card_u44_27128.bin","rb");
    8.59 -                if (f)
    8.60 -                {
    8.61 -                        pclog("Read EGA ROM!\n");
    8.62 -                        fread(vrom,16384,1,f);
    8.63 -                        if (vrom[0x3FFE]==0xAA && vrom[0x3FFF]==0x55)
    8.64 -                        {
    8.65 -                                pclog("Read EGA ROM in reverse\n");
    8.66 -                                fseek(f,0,SEEK_SET);
    8.67 -                                for (c=0x3FFF;c>=0;c--)
    8.68 -                                    vrom[c]=getc(f);
    8.69 -                        }
    8.70 -                        fclose(f);
    8.71 -                        return 1;
    8.72 -                }
    8.73 -                break;
    8.74 -                
    8.75 -                case GFX_TVGA:
    8.76 -                f=romfopen("roms/trident.bin","rb");
    8.77 -                if (f)
    8.78 -                {
    8.79 -                        fread(vrom,32768,1,f);
    8.80 -                        fclose(f);
    8.81 -                        return 1;
    8.82 -                }
    8.83 -                break;
    8.84 -                
    8.85 -                case GFX_ET4000:
    8.86 -                f=romfopen("roms/et4000.bin","rb");
    8.87 -                if (f)
    8.88 -                {
    8.89 -                        fread(vrom,32768,1,f);
    8.90 -                        fclose(f);
    8.91 -                        return 1;
    8.92 -                }
    8.93 -                break;
    8.94 -
    8.95 -                case GFX_ET4000W32:
    8.96 -                f=romfopen("roms/et4000w32.bin","rb");
    8.97 -                if (f)
    8.98 -                {
    8.99 -                        fread(vrom,32768,1,f);
   8.100 -                        fclose(f);
   8.101 -                        return 1;
   8.102 -                }
   8.103 -                break;
   8.104 -                
   8.105 -                case GFX_BAHAMAS64:
   8.106 -                f=romfopen("roms/bahamas64.bin","rb");
   8.107 -                if (f)
   8.108 -                {
   8.109 -                        fread(vrom,32768,1,f);
   8.110 -                        fclose(f);
   8.111 -                        return 1;
   8.112 -                }
   8.113 -                break;
   8.114 -                
   8.115 -                case GFX_N9_9FX:
   8.116 -                f=romfopen("roms/s3_764.bin","rb");
   8.117 -                if (f)
   8.118 -                {
   8.119 -                        fread(vrom,32768,1,f);
   8.120 -                        fclose(f);
   8.121 -                        return 1;
   8.122 -                }
   8.123 -                break;
   8.124 -                
   8.125 -                case GFX_STEALTH64:
   8.126 -                f=romfopen("roms/TRIO64 (Ver. 1.5-07) [VGA] (S3 Incorporated).bin","rb");
   8.127 -                if (f)
   8.128 -                {
   8.129 -                        fread(vrom,32768,1,f);
   8.130 -                        fclose(f);
   8.131 -                        return 1;
   8.132 -                }
   8.133 -                break;
   8.134 -                
   8.135 -                case GFX_VIRGE:
   8.136 -                f=romfopen("roms/s3virge.bin","rb");
   8.137 -                if (f)
   8.138 -                {
   8.139 -                        fread(vrom,32768,1,f);
   8.140 -                        fclose(f);
   8.141 -                        return 1;
   8.142 -                }
   8.143 -                break;
   8.144 -
   8.145 -                case GFX_TGUI9440:
   8.146 -                f=romfopen("roms/9440.vbi","rb");
   8.147 -                if (f)
   8.148 -                {
   8.149 -                        fread(vrom,32768,1,f);
   8.150 -                        fclose(f);
   8.151 -                        return 1;
   8.152 -                }
   8.153 -                break;
   8.154 -                
   8.155 -                case GFX_VGA:
   8.156 -                f=romfopen("roms/ibm_vga.bin","rb");
   8.157 -                if (f)
   8.158 -                {
   8.159 -                        fread(vrom,32768,1,f);
   8.160 -                        fclose(f);
   8.161 -                        return 1;
   8.162 -                }
   8.163 -                break;
   8.164 -
   8.165 -                case GFX_VGAEDGE16:
   8.166 -                f=romfopen("roms/vgaedge16.vbi","rb");
   8.167 -                if (f)
   8.168 -                {
   8.169 -                        fread(vrom,32768,1,f);
   8.170 -                        fclose(f);
   8.171 -                        return 1;
   8.172 -                }
   8.173 -                break;
   8.174 -
   8.175 -                case GFX_VGACHARGER:
   8.176 -                f=romfopen("roms/bios.bin","rb");
   8.177 -                if (f)
   8.178 -                {
   8.179 -                        fread(vrom,32768,1,f);
   8.180 -                        fclose(f);
   8.181 -                        return 1;
   8.182 -                }
   8.183 -                break;
   8.184 -
   8.185 -                case GFX_OTI067:
   8.186 -                f=romfopen("roms/oti067/bios.bin","rb");
   8.187 -                if (f)
   8.188 -                {
   8.189 -                        fread(vrom,32768,1,f);
   8.190 -                        fclose(f);
   8.191 -                        return 1;
   8.192 -                }
   8.193 -                break;
   8.194 -
   8.195 -                case GFX_MACH64GX:
   8.196 -                f=romfopen("roms/mach64gx/bios.bin","rb");
   8.197 -                if (f)
   8.198 -                {
   8.199 -                        fread(vrom,32768,1,f);
   8.200 -                        fclose(f);
   8.201 -                        return 1;
   8.202 -                }
   8.203 -                break;
   8.204 -
   8.205 -                case GFX_CL_GD5429:
   8.206 -                f=romfopen("roms/5429.vbi","rb");
   8.207 -                if (f)
   8.208 -                {
   8.209 -                        fread(vrom,32768,1,f);
   8.210 -                        fclose(f);
   8.211 -                        return 1;
   8.212 -                }
   8.213 -                break;
   8.214 -
   8.215 -                default:
   8.216 -                memset(vrom,0x63,0x8000);
   8.217 -                return 1;
   8.218 -        }
   8.219 -        pclog("mem_load_video_bios : failed to load video BIOS for gfxcard %i\n", gfxcard);
   8.220 -        memset(vrom,0x63,0x8000);
   8.221 -        return 0;
   8.222 -}
   8.223 -        
   8.224  int loadbios()
   8.225  {
   8.226          FILE *f=NULL,*ff=NULL;
   8.227 @@ -270,7 +102,6 @@
   8.228                  }
   8.229                  fclose(ff);
   8.230                  fclose(f);
   8.231 -                memset(vrom,0x63,0x8000);
   8.232                  mem_load_xtide_bios();
   8.233                  loadfont("roms/pc1512/40078.ic127", 2);
   8.234                  return 1;
   8.235 @@ -287,7 +118,6 @@
   8.236                  fclose(f);
   8.237                  f=romfopen("roms/pc1640/40100","rb");
   8.238                  if (!f) break;
   8.239 -                fread(vrom,0x8000,1,f);
   8.240                  fclose(f);
   8.241                  mem_load_xtide_bios();
   8.242                  return 1;
   8.243 @@ -302,7 +132,6 @@
   8.244                  }
   8.245                  fclose(ff);
   8.246                  fclose(f);
   8.247 -                memset(vrom,0x63,0x8000);
   8.248                  mem_load_xtide_bios();
   8.249                  loadfont("roms/pc200/40109.bin", 1);
   8.250                  return 1;
   8.251 @@ -311,7 +140,6 @@
   8.252                  if (!f) break;
   8.253                  fread(rom,65536,1,f);
   8.254                  fclose(f);
   8.255 -                memset(vrom,0x63,0x8000);
   8.256                  mem_load_xtide_bios();
   8.257                  return 1;
   8.258  /*                case ROM_IBMPCJR:
   8.259 @@ -350,7 +178,6 @@
   8.260                  if (!f) break;
   8.261                  fread(rom, 0x10000, 1, f);
   8.262                  fclose(f);
   8.263 -                memset(vrom,0x63,0x8000);
   8.264                  return 1;
   8.265                  
   8.266                  case ROM_GENXT:
   8.267 @@ -396,11 +223,8 @@
   8.268                  fclose(f);
   8.269                  f = romfopen("roms/pc2086/40186.ic171", "rb");
   8.270                  if (!f) break;
   8.271 -                pclog("Loading VBIOS\n");
   8.272 -                fread(vrom, 32768, 1, f);
   8.273                  fclose(f);
   8.274                  mem_load_xtide_bios();
   8.275 -                pclog("%02X %02X %02X\n", rom[0xfff0], rom[0xfff1], rom[0xfff2]);
   8.276                  biosmask = 0x3fff;
   8.277                  return 1;
   8.278  
   8.279 @@ -411,11 +235,8 @@
   8.280                  fclose(f);
   8.281                  f = romfopen("roms/pc3086/c000.bin", "rb");
   8.282                  if (!f) break;
   8.283 -                pclog("Loading VBIOS\n");
   8.284 -                fread(vrom, 32768, 1, f);
   8.285                  fclose(f);
   8.286                  mem_load_xtide_bios();
   8.287 -                pclog("%02X %02X %02X\n", rom[0xfff0], rom[0xfff1], rom[0xfff2]);
   8.288                  biosmask = 0x3fff;                
   8.289                  return 1;
   8.290  
   8.291 @@ -488,9 +309,7 @@
   8.292                  rom[0x40d4]=0x51; /*PUSH CX*/
   8.293                  f=romfopen("roms/acer386/oti067.bin","rb");
   8.294                  if (!f) break;
   8.295 -                fread(vrom,0x8000,1,f);
   8.296                  fclose(f);
   8.297 -                vrom[0x5D]=0x74;
   8.298                  return 1;
   8.299  
   8.300                  case ROM_AMI286:
   8.301 @@ -536,15 +355,9 @@
   8.302                  return 1;
   8.303  
   8.304                  case ROM_MEGAPC:
   8.305 -                        pclog("Loading MegaPC\n");
   8.306                  f  = romfopen("roms/megapc/41651-bios lo.u18",  "rb");
   8.307                  ff = romfopen("roms/megapc/211253-bios hi.u19", "rb");
   8.308                  if (!f || !ff) break;
   8.309 -                for (c = 0x0000; c < 0x8000; c+=2)
   8.310 -                {
   8.311 -                        vrom[c]=getc(f);
   8.312 -                        vrom[c+1]=getc(ff);
   8.313 -                }
   8.314                  fseek(f,  0x8000, SEEK_SET);
   8.315                  fseek(ff, 0x8000, SEEK_SET);                
   8.316                  for (c = 0x0000; c < 0x10000; c+=2)
   8.317 @@ -567,7 +380,6 @@
   8.318                  case ROM_WIN486:
   8.319  //                f=romfopen("roms/win486/win486.bin","rb");
   8.320                  f=romfopen("roms/win486/ALI1429G.AMW","rb");
   8.321 -                
   8.322                  if (!f) break;
   8.323                  fread(rom,65536,1,f);
   8.324                  fclose(f);
   8.325 @@ -589,6 +401,7 @@
   8.326                  fread(rom,           0x20000, 1, f);                
   8.327                  fclose(f);
   8.328                  biosmask = 0x1ffff;
   8.329 +                pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]);
   8.330                  return 1;
   8.331                  
   8.332                  case ROM_430VX:
   8.333 @@ -970,10 +783,17 @@
   8.334                     addreadlookup(a2,a);
   8.335  //                if (a > 0xc0000000)
   8.336  //                   printf("%016X %016X %016X\n", ((long)a&0xFFFFF000), ((long)a2&~0xFFF), (uint8_t *)(a&0xFFFFF000) - (uint8_t *)(a2&~0xFFF));
   8.337 +//                pclog("getpccache: virt=%08x phys=%08x RAM\n", a2, a);
   8.338                  return &ram[(uint8_t *)(a&0xFFFFF000) - (uint8_t *)(a2&~0xFFF)];
   8.339          }
   8.340  //        if (logit) printf("PCCACHE - %08X -> %08X\n",a2,a);
   8.341 -        switch (a>>16)
   8.342 +        if (_mem_exec[a >> 14])
   8.343 +        {
   8.344 +//                pclog("getpccache: %p %p %p\n", ram, rom, &_mem_exec[a >> 14][(a & 0x3000) - (a2 & ~0xFFF)]);
   8.345 +//                pclog("getpccache: virt=%08x phys=%08x %08x %08x %08x %08x\n", a2, a, _mem_exec[a >> 14], &_mem_exec[a >> 14][(a & 0x3000) - (a2 & ~0xFFF)], &_mem_exec[a >> 14][(a & 0x3000) - (a2 & ~0xFFF)] + 0xf0000, rom);
   8.346 +                return &_mem_exec[a >> 14][(a & 0x3000) - (a2 & ~0xFFF)];
   8.347 +        }
   8.348 +/*        switch (a>>16)
   8.349          {
   8.350                  case 0xC: if (a&0x8000) return &romext[(uint8_t *)(a&0x7000) - (uint8_t *)(a2&~0xFFF)];
   8.351                  return &vrom[(uint8_t *)(a&0x7000) - (uint8_t *)(a2&~0xFFF)];
   8.352 @@ -982,7 +802,8 @@
   8.353                  case 0xF: if (shadowbios) return &ram[(uint8_t *)(a&0xFFF000) - (uint8_t *)(a2&~0xFFF)];
   8.354                  return &rom[(uint8_t *)((a & biosmask) & ~ 0xfff) - (uint8_t *)(a2 & ~0xFFF)];
   8.355          }
   8.356 -        return &rom[(long)(a&0xF000) - (long)(a2&~0xFFF)];
   8.357 +        return &rom[(long)(a&0xF000) - (long)(a2&~0xFFF)];*/
   8.358 +        fatal("Bad getpccache %08X\n", a);
   8.359                          /*printf("Bad getpccache %08X\n",a);
   8.360                          dumpregs();
   8.361                          exit(-1);*/
   8.362 @@ -1000,7 +821,7 @@
   8.363          }
   8.364          addr &= rammask;
   8.365  
   8.366 -        if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv[addr >> 14]);
   8.367 +        if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
   8.368  //        pclog("Bad readmembl %08X %04X:%08X\n", addr, CS, pc);
   8.369          return 0xFF;
   8.370  }
   8.371 @@ -1016,8 +837,8 @@
   8.372          }
   8.373          addr &= rammask;
   8.374  
   8.375 -        if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv[addr >> 14]);
   8.376 -//        else                          pclog("Bad write %08X %02X  %04X:%08X\n", addr, val, CS, pc);
   8.377 +        if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
   8.378 +//        else                          pclog("Bad writemembl %08X %02X  %04X:%08X\n", addr, val, CS, pc);
   8.379  }
   8.380  
   8.381  uint8_t readmemb386l(uint32_t seg, uint32_t addr)
   8.382 @@ -1042,7 +863,7 @@
   8.383  
   8.384          addr &= rammask;
   8.385  
   8.386 -        if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv[addr >> 14]);
   8.387 +        if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
   8.388  //        pclog("Bad readmemb386l %08X %04X:%08X\n", addr, CS, pc);
   8.389          return 0xFF;
   8.390  }
   8.391 @@ -1068,8 +889,8 @@
   8.392  /*        if (addr >= 0xa0000 && addr < 0xc0000)
   8.393             pclog("writemembl %08X %02X\n", addr, val);*/
   8.394  
   8.395 -        if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv[addr >> 14]);
   8.396 -//        else                          pclog("Bad write %08X %02X %04X:%08X\n", addr, val, CS, pc);
   8.397 +        if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
   8.398 +//        else                          pclog("Bad writememb386l %08X %02X %04X:%08X\n", addr, val, CS, pc);
   8.399  }
   8.400  
   8.401  uint16_t readmemwl(uint32_t seg, uint32_t addr)
   8.402 @@ -1099,13 +920,14 @@
   8.403  
   8.404          addr2 &= rammask;
   8.405  
   8.406 -        if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]);
   8.407 +        if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]);
   8.408  
   8.409          if (_mem_read_b[addr2 >> 14])
   8.410          {
   8.411 -                if (AT) return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv[addr2 >> 14]) << 8);
   8.412 -                else    return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv[addr2 >> 14]) << 8);
   8.413 +                if (AT) return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8);
   8.414 +                else    return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv_r[addr2 >> 14]) << 8);
   8.415          }
   8.416 +//        pclog("Bad readmemwl %08X\n", addr2);
   8.417          return 0xffff;
   8.418  }
   8.419  
   8.420 @@ -1151,17 +973,17 @@
   8.421          
   8.422          if (_mem_write_w[addr2 >> 14]) 
   8.423          {
   8.424 -                _mem_write_w[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]);
   8.425 +                _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
   8.426                  return;
   8.427          }
   8.428  
   8.429          if (_mem_write_b[addr2 >> 14]) 
   8.430          {
   8.431 -                _mem_write_b[addr2 >> 14](addr2, val, _mem_priv[addr2 >> 14]);
   8.432 -                _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv[addr2 >> 14]);
   8.433 +                _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]);
   8.434 +                _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]);
   8.435                  return;
   8.436          }
   8.437 -//        pclog("Bad write %08X %04X\n", addr2, val);
   8.438 +//        pclog("Bad writememwl %08X %04X\n", addr2, val);
   8.439  }
   8.440  
   8.441  uint32_t readmemll(uint32_t seg, uint32_t addr)
   8.442 @@ -1192,12 +1014,13 @@
   8.443  
   8.444          addr2&=rammask;
   8.445  
   8.446 -        if (_mem_read_l[addr2 >> 14]) return _mem_read_l[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]);
   8.447 +        if (_mem_read_l[addr2 >> 14]) return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]);
   8.448  
   8.449 -        if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv[addr2 >> 14]) << 16);
   8.450 +        if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16);
   8.451          
   8.452 -        if (_mem_read_b[addr2 >> 14]) return _mem_read_b[addr2 >> 14](addr2, _mem_priv[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv[addr2 >> 14]) << 24);
   8.453 +        if (_mem_read_b[addr2 >> 14]) return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv_r[addr2 >> 14]) << 24);
   8.454  
   8.455 +//        pclog("Bad readmemll %08X\n", addr2);
   8.456          return 0xffffffff;
   8.457  }
   8.458  
   8.459 @@ -1235,24 +1058,24 @@
   8.460  
   8.461          if (_mem_write_l[addr2 >> 14]) 
   8.462          {
   8.463 -                _mem_write_l[addr2 >> 14](addr2, val,           _mem_priv[addr2 >> 14]);
   8.464 +                _mem_write_l[addr2 >> 14](addr2, val,           _mem_priv_w[addr2 >> 14]);
   8.465                  return;
   8.466          }
   8.467          if (_mem_write_w[addr2 >> 14]) 
   8.468          {
   8.469 -                _mem_write_w[addr2 >> 14](addr2,     val,       _mem_priv[addr2 >> 14]);
   8.470 -                _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv[addr2 >> 14]);
   8.471 +                _mem_write_w[addr2 >> 14](addr2,     val,       _mem_priv_w[addr2 >> 14]);
   8.472 +                _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]);
   8.473                  return;
   8.474          }
   8.475          if (_mem_write_b[addr2 >> 14]) 
   8.476          {
   8.477 -                _mem_write_b[addr2 >> 14](addr2,     val,       _mem_priv[addr2 >> 14]);
   8.478 -                _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8,  _mem_priv[addr2 >> 14]);
   8.479 -                _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv[addr2 >> 14]);
   8.480 -                _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv[addr2 >> 14]);
   8.481 +                _mem_write_b[addr2 >> 14](addr2,     val,       _mem_priv_w[addr2 >> 14]);
   8.482 +                _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8,  _mem_priv_w[addr2 >> 14]);
   8.483 +                _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]);
   8.484 +                _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]);
   8.485                  return;
   8.486          }
   8.487 -//        pclog("Bad write %08X %08X\n", addr2, val);
   8.488 +//        pclog("Bad writememll %08X %08X\n", addr2, val);
   8.489  }
   8.490  
   8.491  uint8_t mem_readb_phys(uint32_t addr)
   8.492 @@ -1260,7 +1083,7 @@
   8.493          mem_logical_addr = 0xffffffff;
   8.494          
   8.495          if (_mem_read_b[addr >> 14]) 
   8.496 -                return _mem_read_b[addr >> 14](addr, _mem_priv[addr >> 14]);
   8.497 +                return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]);
   8.498                  
   8.499          return 0xff;
   8.500  }
   8.501 @@ -1270,24 +1093,24 @@
   8.502          mem_logical_addr = 0xffffffff;
   8.503          
   8.504          if (_mem_write_b[addr >> 14]) 
   8.505 -                _mem_write_b[addr >> 14](addr, val, _mem_priv[addr >> 14]);
   8.506 +                _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]);
   8.507  }
   8.508  
   8.509  uint8_t mem_read_ram(uint32_t addr, void *priv)
   8.510  {
   8.511 -//        if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMb %08X\n", addr);
   8.512 +//        if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMb %08X\n", addr);
   8.513          addreadlookup(mem_logical_addr, addr);
   8.514          return ram[addr];
   8.515  }
   8.516  uint16_t mem_read_ramw(uint32_t addr, void *priv)
   8.517  {
   8.518 -//        if (addr >= 0xe0000 && addr < 0x100000)  pclog("Read RAMw %08X\n", addr);
   8.519 +//        if (addr >= 0xc0000 && addr < 0x0c8000)  pclog("Read RAMw %08X\n", addr);
   8.520          addreadlookup(mem_logical_addr, addr);
   8.521          return *(uint16_t *)&ram[addr];
   8.522  }
   8.523  uint32_t mem_read_raml(uint32_t addr, void *priv)
   8.524  {
   8.525 -//        if (addr >= 0xe0000 && addr < 0x100000) pclog("Read RAMl %08X\n", addr);
   8.526 +//        if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMl %08X\n", addr);
   8.527          addreadlookup(mem_logical_addr, addr);
   8.528          return *(uint32_t *)&ram[addr];
   8.529  }
   8.530 @@ -1296,19 +1119,19 @@
   8.531  {
   8.532          addwritelookup(mem_logical_addr, addr);
   8.533          ram[addr] = val;
   8.534 -//        if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMb %08X\n", addr);
   8.535 +//        if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Write RAMb %08X\n", addr);
   8.536  }
   8.537  void mem_write_ramw(uint32_t addr, uint16_t val, void *priv)
   8.538  {
   8.539          addwritelookup(mem_logical_addr, addr);
   8.540          *(uint16_t *)&ram[addr] = val;
   8.541 -//        if (addr >= 0xe0000 && addr < 0x100000)  pclog("Write RAMw %08X %04X:%04X %i %04X  %04X:%04X  %04X:%04X\n", addr, CS, pc, ins, val, DS,SI, ES,DI);
   8.542 +//        if (addr >= 0xc0000 && addr < 0x0c8000)  pclog("Write RAMw %08X %04X:%04X %i %04X  %04X:%04X  %04X:%04X\n", addr, CS, pc, ins, val, DS,SI, ES,DI);
   8.543  }
   8.544  void mem_write_raml(uint32_t addr, uint32_t val, void *priv)
   8.545  {
   8.546          addwritelookup(mem_logical_addr, addr);
   8.547          *(uint32_t *)&ram[addr] = val;
   8.548 -//        if (addr >= 0xe0000 && addr < 0x100000) pclog("Write RAMl %08X  %04X:%04X  %04X:%04X  %04X:%04X\n", addr, CS, pc, DS,SI, ES,DI);
   8.549 +//        if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Write RAMl %08X  %04X:%04X  %04X:%04X  %04X:%04X\n", addr, CS, pc, DS,SI, ES,DI);
   8.550  }
   8.551  
   8.552  uint8_t mem_read_bios(uint32_t addr, void *priv)
   8.553 @@ -1333,19 +1156,6 @@
   8.554          return *(uint32_t *)&rom[addr & biosmask];
   8.555  }
   8.556  
   8.557 -uint8_t mem_read_vrom(uint32_t addr, void *priv)
   8.558 -{
   8.559 -        return vrom[addr & 0x7fff];
   8.560 -}
   8.561 -uint16_t mem_read_vromw(uint32_t addr, void *priv)
   8.562 -{
   8.563 -        return *(uint16_t *)&vrom[addr & 0x7fff];
   8.564 -}
   8.565 -uint32_t mem_read_vroml(uint32_t addr, void *priv)
   8.566 -{
   8.567 -        return *(uint32_t *)&vrom[addr & 0x7fff];
   8.568 -}
   8.569 -
   8.570  uint8_t mem_read_romext(uint32_t addr, void *priv)
   8.571  {
   8.572          return romext[addr & 0x7fff];
   8.573 @@ -1359,6 +1169,15 @@
   8.574          return *(uint32_t *)&romext[addr & 0x7fff];
   8.575  }
   8.576  
   8.577 +void mem_write_null(uint32_t addr, uint8_t val, void *p)
   8.578 +{
   8.579 +}
   8.580 +void mem_write_nullw(uint32_t addr, uint16_t val, void *p)
   8.581 +{
   8.582 +}
   8.583 +void mem_write_nulll(uint32_t addr, uint32_t val, void *p)
   8.584 +{
   8.585 +}
   8.586  
   8.587  void mem_updatecache()
   8.588  {
   8.589 @@ -1383,50 +1202,88 @@
   8.590          }
   8.591  }
   8.592  
   8.593 -static void mem_mapping_recalc(uint32_t base, uint32_t size)
   8.594 +static inline int mem_mapping_read_allowed(uint32_t flags, int state)
   8.595  {
   8.596 -        uint32_t c;
   8.597 +//        pclog("mem_mapping_read_allowed: flags=%x state=%x\n", flags, state);
   8.598 +        switch (state & MEM_READ_MASK)
   8.599 +        {
   8.600 +                case MEM_READ_ANY:
   8.601 +                return 1;
   8.602 +                case MEM_READ_EXTERNAL:
   8.603 +                return !(flags & MEM_MAPPING_INTERNAL);
   8.604 +                case MEM_READ_INTERNAL:
   8.605 +                return !(flags & MEM_MAPPING_EXTERNAL);
   8.606 +                default:
   8.607 +                fatal("mem_mapping_read_allowed : bad state %x\n", state);
   8.608 +        }
   8.609 +}
   8.610 +
   8.611 +static inline int mem_mapping_write_allowed(uint32_t flags, int state)
   8.612 +{
   8.613 +        switch (state & MEM_WRITE_MASK)
   8.614 +        {
   8.615 +                case MEM_WRITE_DISABLED:
   8.616 +                return 0;
   8.617 +                case MEM_WRITE_ANY:
   8.618 +                return 1;
   8.619 +                case MEM_WRITE_EXTERNAL:
   8.620 +                return !(flags & MEM_MAPPING_INTERNAL);
   8.621 +                case MEM_WRITE_INTERNAL:
   8.622 +                return !(flags & MEM_MAPPING_EXTERNAL);
   8.623 +                default:
   8.624 +                fatal("mem_mapping_write_allowed : bad state %x\n", state);
   8.625 +        }
   8.626 +}
   8.627 +
   8.628 +static void mem_mapping_recalc(uint64_t base, uint64_t size)
   8.629 +{
   8.630 +        uint64_t c;
   8.631          mem_mapping_t *mapping = base_mapping.next;
   8.632          
   8.633 -        if ((base + size) > 0xffff8000)
   8.634 -           size = 0xffff0000 - base;
   8.635 -        
   8.636          /*Clear out old mappings*/
   8.637          for (c = base; c < base + size; c += 0x4000)
   8.638          {
   8.639                  _mem_read_b[c >> 14] = NULL;
   8.640                  _mem_read_w[c >> 14] = NULL;
   8.641                  _mem_read_l[c >> 14] = NULL;
   8.642 +                _mem_priv_r[c >> 14] = NULL;
   8.643 +                _mem_mapping_r[c >> 14] = NULL;
   8.644                  _mem_write_b[c >> 14] = NULL;
   8.645                  _mem_write_w[c >> 14] = NULL;
   8.646                  _mem_write_l[c >> 14] = NULL;
   8.647 -                _mem_priv[c >> 14] = NULL;
   8.648 -                _mem_mapping[c >> 14] = NULL;
   8.649 +                _mem_priv_w[c >> 14] = NULL;
   8.650 +                _mem_mapping_w[c >> 14] = NULL;
   8.651          }
   8.652 -//        pclog("mem_mapping_recalc %08X %08X\n", base, size);
   8.653 +
   8.654          /*Walk mapping list*/
   8.655          while (mapping != NULL)
   8.656          {
   8.657 -//                pclog("mapping=%p next=%p base=%08X size=%08X enable=%i\n", mapping, mapping->next, mapping->base, mapping->size, mapping->enable);
   8.658                  /*In range?*/
   8.659 -                if (mapping->enable && mapping->base < (base + size) && (mapping->base + mapping->size) >= base)
   8.660 +                if (mapping->enable && (uint64_t)mapping->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)mapping->base + (uint64_t)mapping->size) > (uint64_t)base)
   8.661                  {
   8.662 -                        uint32_t start = (mapping->base < base) ? mapping->base : base;
   8.663 -                        uint32_t end   = ((mapping->base + mapping->size) < (base + size)) ? (mapping->base + mapping->size) : (base + size);
   8.664 -
   8.665 +                        uint64_t start = (mapping->base < base) ? mapping->base : base;
   8.666 +                        uint64_t end   = (((uint64_t)mapping->base + (uint64_t)mapping->size) < (base + size)) ? ((uint64_t)mapping->base + (uint64_t)mapping->size) : (base + size);
   8.667 +                        
   8.668                          for (c = start; c < end; c += 0x4000)
   8.669                          {
   8.670 -                                if (_mem_mapping[c >> 14] == NULL)
   8.671 +                                if ((mapping->read_b || mapping->read_w || mapping->read_l) &&
   8.672 +                                     mem_mapping_read_allowed(mapping->flags, _mem_state[c >> 14]))
   8.673                                  {
   8.674 -//                                        pclog(" Add %08X\n", c);
   8.675                                          _mem_read_b[c >> 14] = mapping->read_b;
   8.676                                          _mem_read_w[c >> 14] = mapping->read_w;
   8.677                                          _mem_read_l[c >> 14] = mapping->read_l;
   8.678 +                                        _mem_exec[c >> 14] = mapping->exec + (c - mapping->base);
   8.679 +                                        _mem_priv_r[c >> 14] = mapping->p;
   8.680 +                                        _mem_mapping_r[c >> 14] = mapping;
   8.681 +                                }
   8.682 +                                if ((mapping->write_b || mapping->write_w || mapping->write_l) &&
   8.683 +                                     mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14]))
   8.684 +                                {
   8.685                                          _mem_write_b[c >> 14] = mapping->write_b;
   8.686                                          _mem_write_w[c >> 14] = mapping->write_w;
   8.687                                          _mem_write_l[c >> 14] = mapping->write_l;
   8.688 -                                        _mem_priv[c >> 14] = mapping->p;
   8.689 -                                        _mem_mapping[c >> 14] = mapping;
   8.690 +                                        _mem_priv_w[c >> 14] = mapping->p;
   8.691 +                                        _mem_mapping_w[c >> 14] = mapping;
   8.692                                  }
   8.693                          }
   8.694                  }
   8.695 @@ -1443,6 +1300,8 @@
   8.696                      void (*write_b)(uint32_t addr, uint8_t  val, void *p),
   8.697                      void (*write_w)(uint32_t addr, uint16_t val, void *p),
   8.698                      void (*write_l)(uint32_t addr, uint32_t val, void *p),
   8.699 +                    uint8_t *exec,
   8.700 +                    uint32_t flags,
   8.701                      void *p)
   8.702  {
   8.703          mem_mapping_t *dest = &base_mapping;
   8.704 @@ -1464,6 +1323,8 @@
   8.705          mapping->write_b = write_b;
   8.706          mapping->write_w = write_w;
   8.707          mapping->write_l = write_l;
   8.708 +        mapping->exec    = exec;
   8.709 +        mapping->flags   = flags;
   8.710          mapping->p       = p;
   8.711          mapping->next    = NULL;
   8.712          
   8.713 @@ -1502,6 +1363,13 @@
   8.714          mem_mapping_recalc(mapping->base, mapping->size);
   8.715  }
   8.716  
   8.717 +void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec)
   8.718 +{
   8.719 +        mapping->exec = exec;
   8.720 +        
   8.721 +        mem_mapping_recalc(mapping->base, mapping->size);
   8.722 +}
   8.723 +
   8.724  void mem_mapping_set_p(mem_mapping_t *mapping, void *p)
   8.725  {
   8.726          mapping->p = p;
   8.727 @@ -1521,6 +1389,38 @@
   8.728          mem_mapping_recalc(mapping->base, mapping->size);
   8.729  }
   8.730  
   8.731 +void mem_set_mem_state(uint32_t base, uint32_t size, int state)
   8.732 +{
   8.733 +        uint32_t c;
   8.734 +
   8.735 +//        pclog("mem_set_pci_enable: base=%08x size=%08x\n", base, size);
   8.736 +        for (c = 0; c < size; c += 0x4000)
   8.737 +                _mem_state[(c + base) >> 14] = state;
   8.738 +
   8.739 +        mem_mapping_recalc(base, size);
   8.740 +}
   8.741 +
   8.742 +void mem_add_bios()
   8.743 +{
   8.744 +        mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom,                        MEM_MAPPING_EXTERNAL, 0);
   8.745 +        mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000  & biosmask), MEM_MAPPING_EXTERNAL, 0);
   8.746 +        mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000  & biosmask), MEM_MAPPING_EXTERNAL, 0);
   8.747 +        mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000  & biosmask), MEM_MAPPING_EXTERNAL, 0);
   8.748 +        mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_EXTERNAL, 0);
   8.749 +        mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_EXTERNAL, 0);
   8.750 +        mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL, 0);
   8.751 +        mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_EXTERNAL, 0);
   8.752 +
   8.753 +        mem_mapping_add(&bios_high_mapping[0], 0xfffe0000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom,                        0, 0);
   8.754 +        mem_mapping_add(&bios_high_mapping[1], 0xfffe4000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000  & biosmask), 0, 0);
   8.755 +        mem_mapping_add(&bios_high_mapping[2], 0xfffe8000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000  & biosmask), 0, 0);
   8.756 +        mem_mapping_add(&bios_high_mapping[3], 0xfffec000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000  & biosmask), 0, 0);
   8.757 +        mem_mapping_add(&bios_high_mapping[4], 0xffff0000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), 0, 0);
   8.758 +        mem_mapping_add(&bios_high_mapping[5], 0xffff4000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), 0, 0);
   8.759 +        mem_mapping_add(&bios_high_mapping[6], 0xffff8000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), 0, 0);
   8.760 +        mem_mapping_add(&bios_high_mapping[7], 0xffffc000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), 0, 0);
   8.761 +}
   8.762 +
   8.763  void mem_init()
   8.764  {
   8.765          int c;
   8.766 @@ -1528,7 +1428,6 @@
   8.767          ram = malloc(mem_size * 1024 * 1024);
   8.768          rom = malloc(0x20000);
   8.769          vram = malloc(0x800000);
   8.770 -        vrom = malloc(0x8000);
   8.771          readlookup2  = malloc(1024 * 1024 * 4);
   8.772          writelookup2 = malloc(1024 * 1024 * 4);
   8.773          cachelookup2 = malloc(1024 * 1024);
   8.774 @@ -1553,21 +1452,16 @@
   8.775  
   8.776          memset(&base_mapping, 0, sizeof(base_mapping));
   8.777  
   8.778 -        mem_mapping_add(&ram_low_mapping, 0x00000, 0xa0000, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.779 +        memset(_mem_state, 0, sizeof(_mem_state));
   8.780 +
   8.781 +        mem_set_mem_state(0xc0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
   8.782 +
   8.783 +        mem_mapping_add(&ram_low_mapping, 0x00000, 0xa0000, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml,   ram,  0, NULL);
   8.784          if (mem_size > 1)
   8.785 -                mem_mapping_add(&ram_low_mapping, 0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.786 +                mem_mapping_add(&ram_high_mapping, 0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml,   ram + 0x100000, 0, NULL);
   8.787 +        mem_mapping_add(&ram_mid_mapping,   0xc0000, 0x40000, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml,   ram + 0xc0000,  MEM_MAPPING_INTERNAL, NULL);
   8.788  
   8.789 -        mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.790 -        mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.791 -        mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.792 -        mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.793 -        mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.794 -        mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.795 -        mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.796 -        mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.797 -
   8.798 -        mem_mapping_add(&vrom_mapping,    0xc0000, 0x08000, mem_read_vrom,   mem_read_vromw,   mem_read_vroml,   NULL, NULL, NULL,   NULL);
   8.799 -        mem_mapping_add(&romext_mapping,  0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL,   NULL);
   8.800 +        mem_mapping_add(&romext_mapping,  0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL,   romext, 0, NULL);
   8.801  //        pclog("Mem resize %i %i\n",mem_size,c);
   8.802  }
   8.803  
   8.804 @@ -1595,57 +1489,23 @@
   8.805          memset(_mem_write_l, 0, sizeof(_mem_write_l));
   8.806  
   8.807          memset(&base_mapping, 0, sizeof(base_mapping));
   8.808 +        
   8.809 +        memset(_mem_state, 0, sizeof(_mem_state));
   8.810  
   8.811 -        mem_mapping_add(&ram_low_mapping, 0x00000, 0xa0000, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.812 +        mem_set_mem_state(0xc0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
   8.813 +
   8.814 +        mem_mapping_add(&ram_low_mapping, 0x00000, 0xa0000, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml,   ram,  0, NULL);
   8.815          if (mem_size > 1)
   8.816 -                mem_mapping_add(&ram_low_mapping, 0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.817 -           
   8.818 -        mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.819 -        mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.820 -        mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.821 -        mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.822 -        mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.823 -        mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.824 -        mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.825 -        mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios,   mem_read_biosw,   mem_read_biosl,   mem_write_ram, mem_write_ramw, mem_write_raml,   NULL);
   8.826 +                mem_mapping_add(&ram_high_mapping, 0x100000, (mem_size - 1) * 1024 * 1024, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml,   ram + 0x100000, 0, NULL);
   8.827 +        mem_mapping_add(&ram_mid_mapping,   0xc0000, 0x40000, mem_read_ram,    mem_read_ramw,    mem_read_raml,    mem_write_ram, mem_write_ramw, mem_write_raml,   ram + 0xc0000,  MEM_MAPPING_INTERNAL, NULL);
   8.828  
   8.829 -        mem_mapping_add(&vrom_mapping,    0xc0000, 0x08000, mem_read_vrom,   mem_read_vromw,   mem_read_vroml,   NULL, NULL, NULL,   NULL);
   8.830 -        mem_mapping_add(&romext_mapping,  0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL,   NULL);
   8.831 +        mem_add_bios();
   8.832 +
   8.833 +        mem_mapping_add(&romext_mapping,  0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL,   romext, 0, NULL);
   8.834  
   8.835  //        pclog("Mem resize %i %i\n",mem_size,c);
   8.836  }
   8.837  
   8.838 -void mem_bios_set_state(uint32_t base, uint32_t size, int read_ram, int write_ram)
   8.839 -{
   8.840 -        uint32_t c;
   8.841 -        int state = (read_ram ? 1 : 0) | (write_ram ? 2: 0);
   8.842 -        
   8.843 -        if (base < 0xe0000 || base > 0xfffff)
   8.844 -                return;
   8.845 -        if ((base + size) > 0x100000)
   8.846 -                size = 0x100000 - base;
   8.847 -        
   8.848 -        for (c = base; c < (base + size); c+= 0x4000)
   8.849 -        {
   8.850 -//                pclog("mem_bios_set_state: c=%08X base=%08X size=%08X bios=%i\n", c, base, size, (c - 0xe0000) >> 14);
   8.851 -                switch (state)
   8.852 -                {
   8.853 -                        case 0:
   8.854 -                        mem_mapping_set_handler(&bios_mapping[(c - 0xe0000) >> 14], mem_read_bios, mem_read_biosw, mem_read_biosl, NULL, NULL, NULL);
   8.855 -                        break;
   8.856 -                        case 1:
   8.857 -                        mem_mapping_set_handler(&bios_mapping[(c - 0xe0000) >> 14], mem_read_ram,  mem_read_ramw,  mem_read_raml,  NULL, NULL, NULL);
   8.858 -                        break;
   8.859 -                        case 2:
   8.860 -                        mem_mapping_set_handler(&bios_mapping[(c - 0xe0000) >> 14], mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_ram, mem_write_ramw, mem_write_raml);
   8.861 -                        break;
   8.862 -                        case 3:
   8.863 -                        mem_mapping_set_handler(&bios_mapping[(c - 0xe0000) >> 14], mem_read_ram,  mem_read_ramw,  mem_read_raml,  mem_write_ram, mem_write_ramw, mem_write_raml);
   8.864 -                        break;
   8.865 -                }
   8.866 -        }
   8.867 -}
   8.868 -
   8.869  int mem_a20_key = 0, mem_a20_alt = 0;
   8.870  static int mem_a20_state = 0;
   8.871  
     9.1 --- a/src/mem.h	Sun Mar 09 11:24:58 2014 +0000
     9.2 +++ b/src/mem.h	Thu Mar 20 14:03:55 2014 +0000
     9.3 @@ -14,10 +14,19 @@
     9.4          void (*write_w)(uint32_t addr, uint16_t val, void *priv);
     9.5          void (*write_l)(uint32_t addr, uint32_t val, void *priv);
     9.6          
     9.7 +        uint8_t *exec;
     9.8 +        
     9.9 +        uint32_t flags;
    9.10 +        
    9.11          void *p;
    9.12  } mem_mapping_t;
    9.13  
    9.14 -extern uint8_t *ram,*rom,*vram,*vrom;
    9.15 +/*Only present on external bus (ISA/PCI)*/
    9.16 +#define MEM_MAPPING_EXTERNAL 1
    9.17 +/*Only present on internal bus (RAM)*/
    9.18 +#define MEM_MAPPING_INTERNAL 2
    9.19 +
    9.20 +extern uint8_t *ram,*rom;
    9.21  extern uint8_t romext[32768];
    9.22  extern int readlnum,writelnum;
    9.23  extern int memspeed[11];
    9.24 @@ -34,6 +43,8 @@
    9.25                      void (*write_b)(uint32_t addr, uint8_t  val, void *p),
    9.26                      void (*write_w)(uint32_t addr, uint16_t val, void *p),
    9.27                      void (*write_l)(uint32_t addr, uint32_t val, void *p),
    9.28 +                    uint8_t *exec,
    9.29 +                    uint32_t flags,
    9.30                      void *p);
    9.31  void mem_mapping_set_handler(mem_mapping_t *mapping,
    9.32                      uint8_t  (*read_b)(uint32_t addr, void *p),
    9.33 @@ -44,10 +55,22 @@
    9.34                      void (*write_l)(uint32_t addr, uint32_t val, void *p));
    9.35  void mem_mapping_set_p(mem_mapping_t *mapping, void *p);
    9.36  void mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size);
    9.37 +void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec);
    9.38  void mem_mapping_disable(mem_mapping_t *mapping);
    9.39  void mem_mapping_enable(mem_mapping_t *mapping);
    9.40  
    9.41 -void mem_bios_set_state(uint32_t base, uint32_t size, int read_ram, int write_ram);
    9.42 +void mem_set_mem_state(uint32_t base, uint32_t size, int state);
    9.43 +
    9.44 +#define MEM_READ_ANY       0x00
    9.45 +#define MEM_READ_INTERNAL  0x10
    9.46 +#define MEM_READ_EXTERNAL  0x20
    9.47 +#define MEM_READ_MASK      0xf0
    9.48 +
    9.49 +#define MEM_WRITE_ANY      0x00
    9.50 +#define MEM_WRITE_INTERNAL 0x01
    9.51 +#define MEM_WRITE_EXTERNAL 0x02
    9.52 +#define MEM_WRITE_DISABLED 0x03
    9.53 +#define MEM_WRITE_MASK     0x0f
    9.54  
    9.55  extern int mem_a20_alt;
    9.56  extern int mem_a20_key;
    9.57 @@ -68,6 +91,8 @@
    9.58  uint16_t mem_read_biosw(uint32_t addr, void *priv);
    9.59  uint32_t mem_read_biosl(uint32_t addr, void *priv);
    9.60  
    9.61 +void mem_write_null(uint32_t addr, uint8_t val, void *p);
    9.62 +void mem_write_nullw(uint32_t addr, uint16_t val, void *p);
    9.63 +void mem_write_nulll(uint32_t addr, uint32_t val, void *p);
    9.64 +
    9.65  FILE *romfopen(char *fn, char *mode);
    9.66 -
    9.67 -int mem_load_video_bios();
    10.1 --- a/src/model.c	Sun Mar 09 11:24:58 2014 +0000
    10.2 +++ b/src/model.c	Thu Mar 20 14:03:55 2014 +0000
    10.3 @@ -78,12 +78,17 @@
    10.4          {"AMI 386 clone",       ROM_AMI386,    { "Intel", cpus_i386,    "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0,  at_headland_init},
    10.5          {"AMI 486 clone",       ROM_AMI486,    { "Intel", cpus_i486,    "AMD", cpus_Am486, "Cyrix", cpus_Cx486},   0,   at_ali1429_init},
    10.6          {"AMI WinBIOS 486",     ROM_WIN486,    { "Intel", cpus_i486,    "AMD", cpus_Am486, "Cyrix", cpus_Cx486},   0,   at_ali1429_init},
    10.7 -        {"AMI WinBIOS 486 PCI", ROM_PCI486,    { "Intel", cpus_i486,    "AMD", cpus_Am486, "Cyrix", cpus_Cx486},   0,   at_um8881f_init},
    10.8 +/*        {"AMI WinBIOS 486 PCI", ROM_PCI486,    { "Intel", cpus_i486,    "AMD", cpus_Am486, "Cyrix", cpus_Cx486},   0,   at_um8881f_init},*/
    10.9          {"Award SiS 496/497",   ROM_SIS496,    { "Intel", cpus_i486,    "AMD", cpus_Am486, "Cyrix", cpus_Cx486},   0,    at_sis496_init},
   10.10          {"Award 430VX PCI",     ROM_430VX,     { "IDT",   cpus_WinChip, "",    NULL,       "",      NULL},         0,    at_i430vx_init},
   10.11          {"", -1, {"", 0, "", 0, "", 0}, 0}
   10.12  };
   10.13  
   10.14 +int model_count()
   10.15 +{
   10.16 +        return (sizeof(models) / sizeof(MODEL)) - 1;
   10.17 +}
   10.18 +
   10.19  int model_getromset()
   10.20  {
   10.21          return models[model].id;
    11.1 --- a/src/model.h	Sun Mar 09 11:24:58 2014 +0000
    11.2 +++ b/src/model.h	Thu Mar 20 14:03:55 2014 +0000
    11.3 @@ -15,6 +15,7 @@
    11.4  
    11.5  extern int model;
    11.6  
    11.7 +int model_count();
    11.8  int model_getromset();
    11.9  int model_getmodel(int romset);
   11.10  char *model_getname();
    12.1 --- a/src/pc.c	Sun Mar 09 11:24:58 2014 +0000
    12.2 +++ b/src/pc.c	Thu Mar 20 14:03:55 2014 +0000
    12.3 @@ -85,6 +85,7 @@
    12.4     va_end(ap);
    12.5     fputs(buf,pclogf);
    12.6     fflush(pclogf);
    12.7 +   dumppic();
    12.8     dumpregs();
    12.9     exit(-1);
   12.10  }
   12.11 @@ -206,9 +207,9 @@
   12.12          
   12.13          initvideo();
   12.14          mem_init();
   12.15 -        mem_load_video_bios();
   12.16          loadbios();
   12.17 -
   12.18 +        mem_add_bios();
   12.19 +                
   12.20          loaddisc(0,discfns[0]);
   12.21          loaddisc(1,discfns[1]);
   12.22          
   12.23 @@ -436,6 +437,9 @@
   12.24          
   12.25          model = get_config_int(NULL, "model", 14);
   12.26  
   12.27 +        if (model >= model_count())
   12.28 +                model = model_count() - 1;
   12.29 +
   12.30          romset = model_getromset();
   12.31          cpu_manufacturer = get_config_int(NULL, "cpu_manufacturer", 0);
   12.32          cpu = get_config_int(NULL, "cpu", 0);
    13.1 --- a/src/pc.rc	Sun Mar 09 11:24:58 2014 +0000
    13.2 +++ b/src/pc.rc	Thu Mar 20 14:03:55 2014 +0000
    13.3 @@ -47,20 +47,20 @@
    13.4          END
    13.5  END
    13.6  
    13.7 -ConfigureDlg DIALOGEX 0, 0, 182, 240
    13.8 +ConfigureDlg DIALOGEX 0, 0, 232, 240
    13.9  STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
   13.10  CAPTION "Configure PCem"
   13.11  FONT 8, "MS Sans Serif"
   13.12  BEGIN
   13.13 -    DEFPUSHBUTTON   "OK",IDOK,17,216,50,14, WS_TABSTOP
   13.14 -    PUSHBUTTON      "Cancel",IDCANCEL,71,216,50,14, WS_TABSTOP
   13.15 -    COMBOBOX        IDC_COMBO1,62,16,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.16 -    COMBOBOX        IDC_COMBOVID,62,36,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.17 -    COMBOBOX        IDC_COMBOCPUM,62,56,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.18 -    COMBOBOX        IDC_COMBO3,62,76,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.19 -    COMBOBOX        IDC_COMBOCHC,62,96,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.20 -    COMBOBOX        IDC_COMBOSPD,62,116,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.21 -    COMBOBOX        IDC_COMBOSND,62,136,107,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.22 +    DEFPUSHBUTTON   "OK",IDOK,64,216,50,14, WS_TABSTOP
   13.23 +    PUSHBUTTON      "Cancel",IDCANCEL,128,216,50,14, WS_TABSTOP
   13.24 +    COMBOBOX        IDC_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.25 +    COMBOBOX        IDC_COMBOVID,62,36,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.26 +    COMBOBOX        IDC_COMBOCPUM,62,56,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.27 +    COMBOBOX        IDC_COMBO3,62,76,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.28 +    COMBOBOX        IDC_COMBOCHC,62,96,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.29 +    COMBOBOX        IDC_COMBOSPD,62,116,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.30 +    COMBOBOX        IDC_COMBOSND,62,136,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
   13.31      EDITTEXT        IDC_MEMTEXT, 62, 152, 36, 14, ES_AUTOHSCROLL | ES_NUMBER
   13.32      CONTROL         "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 152, 12, 14
   13.33      LTEXT           "MB", IDC_STATIC, 98, 152, 40, 10
    14.1 --- a/src/pci.h	Sun Mar 09 11:24:58 2014 +0000
    14.2 +++ b/src/pci.h	Thu Mar 20 14:03:55 2014 +0000
    14.3 @@ -1,3 +1,8 @@
    14.4  void pci_init();
    14.5  void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
    14.6  void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
    14.7 +
    14.8 +#define PCI_REG_COMMAND 0x04
    14.9 +
   14.10 +#define PCI_COMMAND_IO  0x01
   14.11 +#define PCI_COMMAND_MEM 0x02
    15.1 --- a/src/rom.c	Sun Mar 09 11:24:58 2014 +0000
    15.2 +++ b/src/rom.c	Thu Mar 20 14:03:55 2014 +0000
    15.3 @@ -1,5 +1,7 @@
    15.4 +#include <stdlib.h>
    15.5  #include <stdio.h>
    15.6  #include "ibm.h"
    15.7 +#include "mem.h"
    15.8  #include "rom.h"
    15.9  
   15.10  FILE *romfopen(char *fn, char *mode)
   15.11 @@ -27,3 +29,97 @@
   15.12          }
   15.13          return 0;
   15.14  }
   15.15 +
   15.16 +static uint8_t rom_read(uint32_t addr, void *p)
   15.17 +{
   15.18 +        rom_t *rom = (rom_t *)p;
   15.19 +//        pclog("rom_read : %08x %08x %02x\n", addr, rom->mask, rom->rom[addr & rom->mask]);
   15.20 +        return rom->rom[addr & rom->mask];
   15.21 +}
   15.22 +uint16_t rom_readw(uint32_t addr, void *p)
   15.23 +{
   15.24 +        rom_t *rom = (rom_t *)p;
   15.25 +//        pclog("rom_readw: %08x %08x %04x\n", addr, rom->mask, *(uint16_t *)&rom->rom[addr & rom->mask]);
   15.26 +        return *(uint16_t *)&rom->rom[addr & rom->mask];
   15.27 +}
   15.28 +uint32_t rom_readl(uint32_t addr, void *p)
   15.29 +{
   15.30 +        rom_t *rom = (rom_t *)p;
   15.31 +//        pclog("rom_readl: %08x %08x %08x\n", addr, rom->mask, *(uint32_t *)&rom->rom[addr & rom->mask]);
   15.32 +        return *(uint32_t *)&rom->rom[addr & rom->mask];
   15.33 +}
   15.34 +
   15.35 +int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags)
   15.36 +{
   15.37 +        FILE *f = romfopen(fn, "rb");
   15.38 +        
   15.39 +        if (!f)
   15.40 +        {
   15.41 +                pclog("ROM image not found : %s\n", fn);
   15.42 +                return -1;
   15.43 +        }
   15.44 +        
   15.45 +        rom->rom = malloc(size);
   15.46 +        fseek(f, file_offset, SEEK_SET);
   15.47 +        fread(rom->rom, size, 1, f);
   15.48 +        fclose(f);
   15.49 +        
   15.50 +        rom->mask = mask;
   15.51 +        
   15.52 +        mem_mapping_add(&rom->mapping, address, size, rom_read,
   15.53 +                                                      rom_readw,
   15.54 +                                                      rom_readl,
   15.55 +                                                      mem_write_null,
   15.56 +                                                      mem_write_nullw,
   15.57 +                                                      mem_write_nulll,
   15.58 +                                                      rom->rom,
   15.59 +                                                      flags,
   15.60 +                                                      rom);
   15.61 +
   15.62 +        return 0;
   15.63 +}
   15.64 +
   15.65 +int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags)
   15.66 +{
   15.67 +        FILE *f_low  = romfopen(fn_low, "rb");
   15.68 +        FILE *f_high = romfopen(fn_high, "rb");
   15.69 +        int c;
   15.70 +        
   15.71 +        if (!f_low || !f_high)
   15.72 +        {
   15.73 +                if (!f_low)
   15.74 +                        pclog("ROM image not found : %s\n", fn_low);
   15.75 +                else
   15.76 +                        fclose(f_low);
   15.77 +                if (!f_high)
   15.78 +                        pclog("ROM image not found : %s\n", fn_high);
   15.79 +                else
   15.80 +                        fclose(f_high);
   15.81 +                return -1;
   15.82 +        }
   15.83 +        
   15.84 +        rom->rom = malloc(size);
   15.85 +        fseek(f_low, file_offset, SEEK_SET);
   15.86 +        fseek(f_high, file_offset, SEEK_SET);
   15.87 +        for (c = 0; c < size; c += 2)
   15.88 +        {
   15.89 +                rom->rom[c]     = getc(f_low);
   15.90 +                rom->rom[c + 1] = getc(f_high);
   15.91 +        }
   15.92 +        fclose(f_high);
   15.93 +        fclose(f_low);
   15.94 +        
   15.95 +        rom->mask = mask;
   15.96 +        
   15.97 +        mem_mapping_add(&rom->mapping, address, size, rom_read,
   15.98 +                                                      rom_readw,
   15.99 +                                                      rom_readl,
  15.100 +                                                      mem_write_null,
  15.101 +                                                      mem_write_nullw,
  15.102 +                                                      mem_write_nulll,
  15.103 +                                                      rom->rom,
  15.104 +                                                      flags,
  15.105 +                                                      rom);
  15.106 +
  15.107 +        return 0;
  15.108 +}
    16.1 --- a/src/rom.h	Sun Mar 09 11:24:58 2014 +0000
    16.2 +++ b/src/rom.h	Thu Mar 20 14:03:55 2014 +0000
    16.3 @@ -1,2 +1,12 @@
    16.4  FILE *romfopen(char *fn, char *mode);
    16.5  int rom_present(char *fn);
    16.6 +
    16.7 +typedef struct rom_t
    16.8 +{
    16.9 +        uint8_t *rom;
   16.10 +        uint32_t mask;
   16.11 +        mem_mapping_t mapping;
   16.12 +} rom_t;
   16.13 +
   16.14 +int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags);
   16.15 +int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags);
    17.1 --- a/src/sis496.c	Sun Mar 09 11:24:58 2014 +0000
    17.2 +++ b/src/sis496.c	Thu Mar 20 14:03:55 2014 +0000
    17.3 @@ -14,45 +14,32 @@
    17.4  
    17.5  void sis496_recalcmapping(sis496_t *sis496)
    17.6  {
    17.7 -        if (sis496->pci_conf[0x44] & 0x10)
    17.8 +        int c;
    17.9 +        
   17.10 +        for (c = 0; c < 8; c++)
   17.11          {
   17.12 -                if (sis496->pci_conf[0x45] & 0x01)
   17.13 -                        mem_bios_set_state(0xe0000, 0x08000, 1, 0);
   17.14 +                uint32_t base = 0xc0000 + (c << 15);
   17.15 +                if (sis496->pci_conf[0x44] & (1 << c))
   17.16 +                {
   17.17 +                        switch (sis496->pci_conf[0x45] & 3)
   17.18 +                        {
   17.19 +                                case 0:
   17.20 +                                mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
   17.21 +                                break;
   17.22 +                                case 1:
   17.23 +                                mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
   17.24 +                                break;
   17.25 +                                case 2:
   17.26 +                                mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
   17.27 +                                break;
   17.28 +                                case 3:
   17.29 +                                mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
   17.30 +                                break;
   17.31 +                        }
   17.32 +                }
   17.33                  else
   17.34 -                        mem_bios_set_state(0xe0000, 0x08000, 1, 1);
   17.35 +                        mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
   17.36          }
   17.37 -        else
   17.38 -                mem_bios_set_state(0xe0000, 0x08000, 0, 1);
   17.39 -
   17.40 -        if (sis496->pci_conf[0x44] & 0x20)
   17.41 -        {
   17.42 -                if (sis496->pci_conf[0x45] & 0x01)
   17.43 -                        mem_bios_set_state(0xe8000, 0x08000, 1, 0);
   17.44 -                else
   17.45 -                        mem_bios_set_state(0xe8000, 0x08000, 1, 1);
   17.46 -        }
   17.47 -        else
   17.48 -                mem_bios_set_state(0xe8000, 0x08000, 0, 1);
   17.49 -                
   17.50 -        if (sis496->pci_conf[0x44] & 0x40)
   17.51 -        {
   17.52 -                if (sis496->pci_conf[0x45] & 0x01)
   17.53 -                        mem_bios_set_state(0xf0000, 0x08000, 1, 0);
   17.54 -                else
   17.55 -                        mem_bios_set_state(0xf0000, 0x08000, 1, 1);
   17.56 -        }
   17.57 -        else
   17.58 -                mem_bios_set_state(0xf0000, 0x08000, 0, 1);
   17.59 -                
   17.60 -        if (sis496->pci_conf[0x44] & 0x80)
   17.61 -        {
   17.62 -                if (sis496->pci_conf[0x45] & 0x01)
   17.63 -                        mem_bios_set_state(0xf8000, 0x08000, 1, 0);
   17.64 -                else
   17.65 -                        mem_bios_set_state(0xf8000, 0x08000, 1, 1);
   17.66 -        }
   17.67 -        else
   17.68 -                mem_bios_set_state(0xf8000, 0x08000, 0, 1);
   17.69  
   17.70          flushmmucache();
   17.71          shadowbios = (sis496->pci_conf[0x44] & 0xf0);
   17.72 @@ -61,7 +48,7 @@
   17.73  void sis496_write(int func, int addr, uint8_t val, void *p)
   17.74  {
   17.75          sis496_t *sis496 = (sis496_t *)p;
   17.76 -//pclog("sis496_write : addr=%02x val=%02x\n", addr, val);
   17.77 +        //pclog("sis496_write : addr=%02x val=%02x\n", addr, val);
   17.78          switch (addr)
   17.79          {
   17.80                  case 0x44: /*Shadow configure*/
   17.81 @@ -72,8 +59,6 @@
   17.82                  }
   17.83                  break;
   17.84                  case 0x45: /*Shadow configure*/
   17.85 -                //if (val == 3)
   17.86 -                //        output = 3;
   17.87                  if ((sis496->pci_conf[0x45] & val) ^ 0x01)
   17.88                  {
   17.89                          sis496->pci_conf[0x45] = val;
    18.1 --- a/src/sound_gus.c	Sun Mar 09 11:24:58 2014 +0000
    18.2 +++ b/src/sound_gus.c	Thu Mar 20 14:03:55 2014 +0000
    18.3 @@ -638,8 +638,8 @@
    18.4                          val = 0xff;
    18.5                          break;
    18.6                          
    18.7 -                        default:
    18.8 -                        fatal("Bad GUS global low read %02X\n",gus->global);
    18.9 +//                        default:
   18.10 +//                        fatal("Bad GUS global low read %02X\n",gus->global);
   18.11                  }
   18.12                  break;
   18.13                  case 0x345: /*Global high*/
   18.14 @@ -693,8 +693,8 @@
   18.15                          val = 0xff;
   18.16                          break;
   18.17                          
   18.18 -                        default:
   18.19 -                        fatal("Bad GUS global high read %02X\n",gus->global);
   18.20 +//                        default:
   18.21 +//                        fatal("Bad GUS global high read %02X\n",gus->global);
   18.22                  }                
   18.23                  break;
   18.24                  case 0x346: return 0xff;
    19.1 --- a/src/um8881f.c	Sun Mar 09 11:24:58 2014 +0000
    19.2 +++ b/src/um8881f.c	Thu Mar 20 14:03:55 2014 +0000
    19.3 @@ -10,28 +10,29 @@
    19.4  
    19.5  void um8881f_write(int func, int addr, uint8_t val, void *priv)
    19.6  {
    19.7 +//        pclog("um8881f_write : addr=%02x val=%02x %04x:%04x\n", addr, val, CS, pc);
    19.8          if (addr == 0x54)
    19.9          {
   19.10 -                if ((card_16[0x54] ^ val) & 0x01)
   19.11 +/*                if ((card_16[0x54] ^ val) & 0x01)
   19.12                  {
   19.13                          if (val & 1)
   19.14                                  mem_bios_set_state(0xe0000, 0x10000, 1, 1);
   19.15                          else
   19.16                                  mem_bios_set_state(0xe0000, 0x10000, 0, 0);
   19.17 -                }
   19.18 +                }*/
   19.19                  flushmmucache_nopc();
   19.20          }
   19.21          if (addr == 0x55)
   19.22          {
   19.23                  if ((card_16[0x55] ^ val) & 0xc0)
   19.24                  {
   19.25 -                        switch (val & 0xc0)
   19.26 +/*                        switch (val & 0xc0)
   19.27                          {
   19.28                                  case 0x00: mem_bios_set_state(0xf0000, 0x10000, 0, 1); break;
   19.29                                  case 0x40: mem_bios_set_state(0xf0000, 0x10000, 0, 0); break;
   19.30                                  case 0x80: mem_bios_set_state(0xf0000, 0x10000, 1, 1); break;
   19.31                                  case 0xc0: mem_bios_set_state(0xf0000, 0x10000, 1, 0); break;
   19.32 -                        }
   19.33 +                        }*/
   19.34                          shadowbios = val & 0x80;
   19.35                          shadowbios_write = !(val & 0x40);
   19.36                          flushmmucache_nopc();
    20.1 --- a/src/vid_ati18800.c	Sun Mar 09 11:24:58 2014 +0000
    20.2 +++ b/src/vid_ati18800.c	Thu Mar 20 14:03:55 2014 +0000
    20.3 @@ -4,6 +4,7 @@
    20.4  #include "device.h"
    20.5  #include "io.h"
    20.6  #include "mem.h"
    20.7 +#include "rom.h"
    20.8  #include "video.h"
    20.9  #include "vid_ati18800.h"
   20.10  #include "vid_ati_eeprom.h"
   20.11 @@ -13,6 +14,8 @@
   20.12  {
   20.13          svga_t svga;
   20.14          ati_eeprom_t eeprom;
   20.15 +
   20.16 +        rom_t bios_rom;
   20.17          
   20.18          uint8_t regs[256];
   20.19          int index;
   20.20 @@ -122,6 +125,8 @@
   20.21          ati18800_t *ati18800 = malloc(sizeof(ati18800_t));
   20.22          memset(ati18800, 0, sizeof(ati18800_t));
   20.23          
   20.24 +        rom_init(&ati18800->bios_rom, "roms/vgaedge16.vbi", 0xc0000, 0x8000, 0x7fff, 0, 0);
   20.25 +        
   20.26          svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/
   20.27                     NULL,
   20.28                     ati18800_in, ati18800_out,
   20.29 @@ -137,6 +142,11 @@
   20.30          return ati18800;
   20.31  }
   20.32  
   20.33 +static int ati18800_available()
   20.34 +{
   20.35 +        return rom_present("roms/vgaedge16.vbi");
   20.36 +}
   20.37 +
   20.38  void ati18800_close(void *p)
   20.39  {
   20.40          ati18800_t *ati18800 = (ati18800_t *)p;
   20.41 @@ -173,7 +183,7 @@
   20.42          0,
   20.43          ati18800_init,
   20.44          ati18800_close,
   20.45 -        NULL,
   20.46 +        ati18800_available,
   20.47          ati18800_speed_changed,
   20.48          ati18800_force_redraw,
   20.49          ati18800_add_status_info
    21.1 --- a/src/vid_ati28800.c	Sun Mar 09 11:24:58 2014 +0000
    21.2 +++ b/src/vid_ati28800.c	Thu Mar 20 14:03:55 2014 +0000
    21.3 @@ -4,6 +4,7 @@
    21.4  #include "device.h"
    21.5  #include "io.h"
    21.6  #include "mem.h"
    21.7 +#include "rom.h"
    21.8  #include "video.h"
    21.9  #include "vid_ati28800.h"
   21.10  #include "vid_ati_eeprom.h"
   21.11 @@ -15,6 +16,8 @@
   21.12          svga_t svga;
   21.13          ati_eeprom_t eeprom;
   21.14          
   21.15 +        rom_t bios_rom;
   21.16 +        
   21.17          uint8_t regs[256];
   21.18          int index;
   21.19  } ati28800_t;
   21.20 @@ -143,6 +146,8 @@
   21.21          ati28800_t *ati28800 = malloc(sizeof(ati28800_t));
   21.22          memset(ati28800, 0, sizeof(ati28800_t));
   21.23          
   21.24 +        rom_init(&ati28800->bios_rom, "roms/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, 0);
   21.25 +        
   21.26          svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/
   21.27                     ati28800_recalctimings,
   21.28                     ati28800_in, ati28800_out,
   21.29 @@ -158,6 +163,11 @@
   21.30          return ati28800;
   21.31  }
   21.32  
   21.33 +static int ati28800_available()
   21.34 +{
   21.35 +        return rom_present("roms/bios.bin");
   21.36 +}
   21.37 +
   21.38  void ati28800_close(void *p)
   21.39  {
   21.40          ati28800_t *ati28800 = (ati28800_t *)p;
   21.41 @@ -194,7 +204,7 @@
   21.42          0,
   21.43          ati28800_init,
   21.44          ati28800_close,
   21.45 -        NULL,
   21.46 +        ati28800_available,
   21.47          ati28800_speed_changed,
   21.48          ati28800_force_redraw,
   21.49          ati28800_add_status_info
    22.1 --- a/src/vid_ati_mach64.c	Sun Mar 09 11:24:58 2014 +0000
    22.2 +++ b/src/vid_ati_mach64.c	Thu Mar 20 14:03:55 2014 +0000
    22.3 @@ -5,6 +5,7 @@
    22.4  #include "io.h"
    22.5  #include "mem.h"
    22.6  #include "pci.h"
    22.7 +#include "rom.h"
    22.8  #include "video.h"
    22.9  #include "vid_svga.h"
   22.10  #include "vid_ati68860_ramdac.h"
   22.11 @@ -25,8 +26,12 @@
   22.12          ics2595_t ics2595;
   22.13          svga_t svga;
   22.14          
   22.15 +        rom_t bios_rom;
   22.16 +        
   22.17          uint8_t regs[256];
   22.18          int index;
   22.19 +        
   22.20 +        uint8_t pci_regs[256];
   22.21  
   22.22          int bank_r[2];
   22.23          int bank_w[2];
   22.24 @@ -338,6 +343,16 @@
   22.25  {
   22.26          svga_t *svga = &mach64->svga;
   22.27  
   22.28 +        if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))
   22.29 +        {
   22.30 +                pclog("Update mapping - PCI disabled\n");
   22.31 +                mem_mapping_disable(&svga->mapping);
   22.32 +                mem_mapping_disable(&mach64->linear_mapping);
   22.33 +                mem_mapping_disable(&mach64->mmio_mapping);
   22.34 +                mem_mapping_disable(&mach64->mmio_linear_mapping);
   22.35 +                return;
   22.36 +        }
   22.37 +
   22.38          mem_mapping_disable(&mach64->mmio_mapping);
   22.39  //        pclog("Write mapping %02X\n", val);
   22.40          switch (svga->gdcreg[6] & 0xc)
   22.41 @@ -1835,9 +1850,13 @@
   22.42          switch (port)
   22.43          {
   22.44                  default:
   22.45 +#ifdef MACH64_DEBUG
   22.46                  pclog("  ");
   22.47 +#endif
   22.48                  ret = mach64_ext_inb(port, p);
   22.49 +#ifdef MACH64_DEBUG
   22.50                  pclog("  ");
   22.51 +#endif
   22.52                  ret |= (mach64_ext_inb(port + 1, p) << 8);
   22.53                  break;
   22.54          }
   22.55 @@ -1860,9 +1879,13 @@
   22.56                  break;
   22.57  
   22.58                  default:
   22.59 +#ifdef MACH64_DEBUG
   22.60                  pclog("  ");
   22.61 +#endif
   22.62                  ret = mach64_ext_inw(port, p);
   22.63 +#ifdef MACH64_DEBUG
   22.64                  pclog("  ");
   22.65 +#endif
   22.66                  ret |= (mach64_ext_inw(port + 2, p) << 16);
   22.67                  break;
   22.68          }
   22.69 @@ -2053,6 +2076,42 @@
   22.70          svga->hwcursor_latch.addr += 16;
   22.71  }
   22.72  
   22.73 +static void mach64_io_remove(mach64_t *mach64)
   22.74 +{
   22.75 +        int c;
   22.76 +
   22.77 +        io_removehandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
   22.78 +        
   22.79 +        for (c = 0; c < 8; c++)
   22.80 +        {
   22.81 +                io_removehandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
   22.82 +                io_removehandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
   22.83 +                io_removehandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
   22.84 +                io_removehandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64);
   22.85 +        }
   22.86 +
   22.87 +        io_removehandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
   22.88 +}
   22.89 +
   22.90 +static void mach64_io_set(mach64_t *mach64)
   22.91 +{
   22.92 +        int c;
   22.93 +        
   22.94 +        mach64_io_remove(mach64);
   22.95 +        
   22.96 +        io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
   22.97 +        
   22.98 +        for (c = 0; c < 8; c++)
   22.99 +        {
  22.100 +                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);
  22.101 +                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);
  22.102 +                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);
  22.103 +                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);
  22.104 +        }
  22.105 +
  22.106 +        io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
  22.107 +}
  22.108 +
  22.109  uint8_t mach64_pci_read(int func, int addr, void *p)
  22.110  {
  22.111          mach64_t *mach64 = (mach64_t *)p;
  22.112 @@ -2068,7 +2127,8 @@
  22.113                  case 0x02: return 'X'; /*88800GX*/
  22.114                  case 0x03: return 'G';
  22.115                  
  22.116 -                case 0x04: return 0x03; /*Respond to IO and memory accesses*/
  22.117 +                case PCI_REG_COMMAND:
  22.118 +                return mach64->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/
  22.119  
  22.120                  case 0x07: return 1 << 1; /*Medium DEVSEL timing*/
  22.121                  
  22.122 @@ -2083,10 +2143,10 @@
  22.123                  case 0x12: return mach64->linear_base >> 16;
  22.124                  case 0x13: return mach64->linear_base >> 24;
  22.125  
  22.126 -                case 0x30: return 0x01; /*BIOS ROM address*/
  22.127 +                case 0x30: return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/
  22.128                  case 0x31: return 0x00;
  22.129 -                case 0x32: return 0x0C;
  22.130 -                case 0x33: return 0x00;
  22.131 +                case 0x32: return mach64->pci_regs[0x32];
  22.132 +                case 0x33: return mach64->pci_regs[0x33];
  22.133          }
  22.134          return 0;
  22.135  }
  22.136 @@ -2099,6 +2159,15 @@
  22.137          
  22.138          switch (addr)
  22.139          {
  22.140 +                case PCI_REG_COMMAND:
  22.141 +                mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27;
  22.142 +                if (val & PCI_COMMAND_IO)
  22.143 +                        mach64_io_set(mach64);
  22.144 +                else
  22.145 +                        mach64_io_remove(mach64);
  22.146 +                mach64_updatemapping(mach64);
  22.147 +                break;
  22.148 +
  22.149                  case 0x12:
  22.150                  mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16);
  22.151                  mach64_updatemapping(mach64);
  22.152 @@ -2107,6 +2176,21 @@
  22.153                  mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24);
  22.154                  mach64_updatemapping(mach64);
  22.155                  break;
  22.156 +
  22.157 +                case 0x30: case 0x32: case 0x33:
  22.158 +                mach64->pci_regs[addr] = val;
  22.159 +                if (mach64->pci_regs[0x30] & 0x01)
  22.160 +                {
  22.161 +                        uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24);
  22.162 +                        pclog("Mach64 bios_rom enabled at %08x\n", addr);
  22.163 +                        mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000);
  22.164 +                }
  22.165 +                else
  22.166 +                {
  22.167 +                        pclog("Mach64 bios_rom disabled\n");
  22.168 +                        mem_mapping_disable(&mach64->bios_rom.mapping);
  22.169 +                }
  22.170 +                return;
  22.171          }
  22.172  }
  22.173  
  22.174 @@ -2121,24 +2205,23 @@
  22.175                     mach64_in, mach64_out,
  22.176                     mach64_hwcursor_draw); 
  22.177  
  22.178 -        mem_mapping_add(&mach64->linear_mapping,      0,       0,       svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &mach64->svga);
  22.179 -        mem_mapping_add(&mach64->mmio_linear_mapping, 0,       0,       mach64_ext_readb, mach64_ext_readw,  mach64_ext_readl,  mach64_ext_writeb, mach64_ext_writew,  mach64_ext_writel,   mach64);
  22.180 -        mem_mapping_add(&mach64->mmio_mapping,        0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw,  mach64_ext_readl,  mach64_ext_writeb, mach64_ext_writew,  mach64_ext_writel,   mach64);
  22.181 +        rom_init(&mach64->bios_rom, "roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
  22.182 +        if (PCI)
  22.183 +                mem_mapping_disable(&mach64->bios_rom.mapping);
  22.184 +
  22.185 +        mem_mapping_add(&mach64->linear_mapping,      0,       0,       svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &mach64->svga);
  22.186 +        mem_mapping_add(&mach64->mmio_linear_mapping, 0,       0,       mach64_ext_readb, mach64_ext_readw,  mach64_ext_readl,  mach64_ext_writeb, mach64_ext_writew,  mach64_ext_writel,  NULL, 0,  mach64);
  22.187 +        mem_mapping_add(&mach64->mmio_mapping,        0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw,  mach64_ext_readl,  mach64_ext_writeb, mach64_ext_writew,  mach64_ext_writel,  NULL, 0,  mach64);
  22.188          mem_mapping_disable(&mach64->mmio_mapping);
  22.189  
  22.190 -        io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
  22.191 -        
  22.192 -        for (c = 0; c < 8; c++)
  22.193 -        {
  22.194 -                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);
  22.195 -                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);
  22.196 -                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);
  22.197 -                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);
  22.198 -        }
  22.199 -
  22.200 -        io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64);
  22.201 +        mach64_io_set(mach64);
  22.202  
  22.203          pci_add(mach64_pci_read, mach64_pci_write, mach64);
  22.204 +
  22.205 +        mach64->pci_regs[PCI_REG_COMMAND] = 3;
  22.206 +        mach64->pci_regs[0x30] = 0x00;
  22.207 +        mach64->pci_regs[0x32] = 0x0c;
  22.208 +        mach64->pci_regs[0x33] = 0x00;
  22.209                  
  22.210          ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1);
  22.211  
  22.212 @@ -2149,6 +2232,11 @@
  22.213          return mach64;
  22.214  }
  22.215  
  22.216 +int mach64gx_available()
  22.217 +{
  22.218 +        return rom_present("roms/mach64gx/bios.bin");
  22.219 +}
  22.220 +
  22.221  void mach64_close(void *p)
  22.222  {
  22.223          mach64_t *mach64 = (mach64_t *)p;
  22.224 @@ -2225,7 +2313,7 @@
  22.225          0,
  22.226          mach64gx_init,
  22.227          mach64_close,
  22.228 -        NULL,
  22.229 +        mach64gx_available,
  22.230          mach64_speed_changed,
  22.231          mach64_force_redraw,
  22.232          mach64_add_status_info
    23.1 --- a/src/vid_cga.c	Sun Mar 09 11:24:58 2014 +0000
    23.2 +++ b/src/vid_cga.c	Thu Mar 20 14:03:55 2014 +0000
    23.3 @@ -499,7 +499,7 @@
    23.4                  q_filt[c] = 512.0 * sin((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0);
    23.5          }
    23.6          timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
    23.7 -        mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  cga);
    23.8 +        mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  NULL, 0, cga);
    23.9          io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);
   23.10          return cga;
   23.11  }
    24.1 --- a/src/vid_cl5429.c	Sun Mar 09 11:24:58 2014 +0000
    24.2 +++ b/src/vid_cl5429.c	Thu Mar 20 14:03:55 2014 +0000
    24.3 @@ -4,6 +4,7 @@
    24.4  #include "device.h"
    24.5  #include "io.h"
    24.6  #include "mem.h"
    24.7 +#include "rom.h"
    24.8  #include "video.h"
    24.9  #include "vid_cl5429.h"
   24.10  #include "vid_svga.h"
   24.11 @@ -16,6 +17,8 @@
   24.12          
   24.13          svga_t svga;
   24.14          
   24.15 +        rom_t bios_rom;
   24.16 +        
   24.17          uint32_t bank[2];
   24.18          uint32_t mask;
   24.19  
   24.20 @@ -816,6 +819,8 @@
   24.21          svga_t *svga = &gd5429->svga;
   24.22          memset(gd5429, 0, sizeof(gd5429_t));
   24.23  
   24.24 +        rom_init(&gd5429->bios_rom, "roms/5429.vbi", 0xc0000, 0x8000, 0x7fff, 0, 0);
   24.25 +        
   24.26          svga_init(&gd5429->svga, gd5429, 1 << 21, /*2mb*/
   24.27                     gd5429_recalctimings,
   24.28                     gd5429_in, gd5429_out,
   24.29 @@ -824,7 +829,7 @@
   24.30          mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL);
   24.31          mem_mapping_set_p(&gd5429->svga.mapping, gd5429);
   24.32  
   24.33 -        mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL,  gd5429);
   24.34 +        mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL,  NULL, 0, gd5429);
   24.35  
   24.36          io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429);
   24.37  
   24.38 @@ -836,6 +841,11 @@
   24.39          return gd5429;
   24.40  }
   24.41  
   24.42 +static int gd5429_available()
   24.43 +{
   24.44 +        return rom_present("roms/5429.vbi");
   24.45 +}
   24.46 +
   24.47  void gd5429_close(void *p)
   24.48  {
   24.49          gd5429_t *gd5429 = (gd5429_t *)p;
   24.50 @@ -872,7 +882,7 @@
   24.51          DEVICE_NOT_WORKING,
   24.52          gd5429_init,
   24.53          gd5429_close,
   24.54 -        NULL,
   24.55 +        gd5429_available,
   24.56          gd5429_speed_changed,
   24.57          gd5429_force_redraw,
   24.58          gd5429_add_status_info
    25.1 --- a/src/vid_ega.c	Sun Mar 09 11:24:58 2014 +0000
    25.2 +++ b/src/vid_ega.c	Thu Mar 20 14:03:55 2014 +0000
    25.3 @@ -4,6 +4,7 @@
    25.4  #include "device.h"
    25.5  #include "io.h"
    25.6  #include "mem.h"
    25.7 +#include "rom.h"
    25.8  #include "timer.h"
    25.9  #include "video.h"
   25.10  #include "vid_ega.h"
   25.11 @@ -810,15 +811,35 @@
   25.12          int c, d, e;
   25.13          ega_t *ega = malloc(sizeof(ega_t));
   25.14          memset(ega, 0, sizeof(ega_t));
   25.15 +        
   25.16 +        rom_init(&ega->bios_rom, "roms/ibm_6277356_ega_card_u44_27128.bin", 0xc0000, 0x8000, 0x7fff, 0, 0);
   25.17 +
   25.18 +        if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55)
   25.19 +        {
   25.20 +                int c;
   25.21 +                pclog("Read EGA ROM in reverse\n");
   25.22 +
   25.23 +                for (c = 0; c < 0x2000; c++)
   25.24 +                {
   25.25 +                        uint8_t temp = ega->bios_rom.rom[c];
   25.26 +                        ega->bios_rom.rom[c] = ega->bios_rom.rom[0x3fff - c];
   25.27 +                        ega->bios_rom.rom[0x3fff - c] = temp;
   25.28 +                }
   25.29 +        }
   25.30  
   25.31          ega_init(ega);        
   25.32  
   25.33 -        mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, ega);
   25.34 +        mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega);
   25.35          timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega);
   25.36          io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
   25.37          return ega;
   25.38  }
   25.39  
   25.40 +static int ega_standalone_available()
   25.41 +{
   25.42 +        return rom_present("roms/ibm_6277356_ega_card_u44_27128.bin");
   25.43 +}
   25.44 +
   25.45  void ega_close(void *p)
   25.46  {
   25.47          ega_t *ega = (ega_t *)p;
   25.48 @@ -840,7 +861,7 @@
   25.49          0,
   25.50          ega_standalone_init,
   25.51          ega_close,
   25.52 -        NULL,
   25.53 +        ega_standalone_available,
   25.54          ega_speed_changed,
   25.55          NULL,
   25.56          NULL
    26.1 --- a/src/vid_ega.h	Sun Mar 09 11:24:58 2014 +0000
    26.2 +++ b/src/vid_ega.h	Thu Mar 20 14:03:55 2014 +0000
    26.3 @@ -2,6 +2,8 @@
    26.4  {
    26.5          mem_mapping_t mapping;
    26.6          
    26.7 +        rom_t bios_rom;
    26.8 +        
    26.9          uint8_t crtcreg;
   26.10          uint8_t crtc[32];
   26.11          uint8_t gdcreg[16];
    27.1 --- a/src/vid_et4000.c	Sun Mar 09 11:24:58 2014 +0000
    27.2 +++ b/src/vid_et4000.c	Thu Mar 20 14:03:55 2014 +0000
    27.3 @@ -4,6 +4,7 @@
    27.4  #include "device.h"
    27.5  #include "io.h"
    27.6  #include "mem.h"
    27.7 +#include "rom.h"
    27.8  #include "video.h"
    27.9  #include "vid_svga.h"
   27.10  #include "vid_unk_ramdac.h"
   27.11 @@ -15,6 +16,8 @@
   27.12          svga_t svga;
   27.13          unk_ramdac_t ramdac;
   27.14          
   27.15 +        rom_t bios_rom;
   27.16 +        
   27.17          uint8_t banking;
   27.18  } et4000_t;
   27.19  
   27.20 @@ -129,7 +132,9 @@
   27.21  {
   27.22          et4000_t *et4000 = malloc(sizeof(et4000_t));
   27.23          memset(et4000, 0, sizeof(et4000_t));
   27.24 -        
   27.25 +
   27.26 +        rom_init(&et4000->bios_rom, "roms/et4000.bin", 0xc0000, 0x8000, 0x7fff, 0, 0);
   27.27 +                
   27.28          io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
   27.29  
   27.30          svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/
   27.31 @@ -140,6 +145,11 @@
   27.32          return et4000;
   27.33  }
   27.34  
   27.35 +static int et4000_available()
   27.36 +{
   27.37 +        return rom_present("roms/et4000.bin");
   27.38 +}
   27.39 +
   27.40  void et4000_close(void *p)
   27.41  {
   27.42          et4000_t *et4000 = (et4000_t *)p;
    28.1 --- a/src/vid_et4000w32.c	Sun Mar 09 11:24:58 2014 +0000
    28.2 +++ b/src/vid_et4000w32.c	Thu Mar 20 14:03:55 2014 +0000
    28.3 @@ -9,6 +9,7 @@
    28.4  #include "io.h"
    28.5  #include "mem.h"
    28.6  #include "pci.h"
    28.7 +#include "rom.h"
    28.8  #include "video.h"
    28.9  #include "vid_svga.h"
   28.10  #include "vid_icd2061.h"
   28.11 @@ -19,6 +20,8 @@
   28.12          mem_mapping_t linear_mapping;
   28.13          mem_mapping_t    mmu_mapping;
   28.14          
   28.15 +        rom_t bios_rom;
   28.16 +        
   28.17          svga_t svga;
   28.18          stg_ramdac_t ramdac;
   28.19          icd2061_t icd2061;
   28.20 @@ -28,7 +31,9 @@
   28.21          uint32_t linearbase, linearbase_old;
   28.22  
   28.23          uint8_t banking, banking2;
   28.24 -        
   28.25 +
   28.26 +        uint8_t pci_regs[256];
   28.27 +
   28.28          /*Accelerator*/
   28.29          struct
   28.30          {
   28.31 @@ -260,6 +265,15 @@
   28.32  {
   28.33          svga_t *svga = &et4000->svga;
   28.34          
   28.35 +        if (!(et4000->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))
   28.36 +        {
   28.37 +                pclog("Update mapping - PCI disabled\n");
   28.38 +                mem_mapping_disable(&svga->mapping);
   28.39 +                mem_mapping_disable(&et4000->linear_mapping);
   28.40 +                mem_mapping_disable(&et4000->mmu_mapping);
   28.41 +                return;
   28.42 +        }
   28.43 +
   28.44          pclog("recalcmapping %p\n", svga);
   28.45          if (svga->crtc[0x36] & 0x10) /*Linear frame buffer*/
   28.46          {
   28.47 @@ -887,6 +901,36 @@
   28.48          svga->hwcursor_latch.addr += 16;
   28.49  }
   28.50  
   28.51 +static void et4000w32p_io_remove(et4000w32p_t *et4000)
   28.52 +{
   28.53 +        io_removehandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.54 +
   28.55 +        io_removehandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.56 +        io_removehandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.57 +        io_removehandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.58 +        io_removehandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.59 +        io_removehandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.60 +        io_removehandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.61 +        io_removehandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.62 +        io_removehandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.63 +}
   28.64 +
   28.65 +static void et4000w32p_io_set(et4000w32p_t *et4000)
   28.66 +{
   28.67 +        et4000w32p_io_remove(et4000);
   28.68 +        
   28.69 +        io_sethandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.70 +
   28.71 +        io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.72 +        io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.73 +        io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.74 +        io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.75 +        io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.76 +        io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.77 +        io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.78 +        io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
   28.79 +}
   28.80 +
   28.81  uint8_t et4000w32p_pci_read(int func, int addr, void *p)
   28.82  {
   28.83          et4000w32p_t *et4000 = (et4000w32p_t *)p;
   28.84 @@ -902,7 +946,8 @@
   28.85                  case 0x02: return 0x06; /*ET4000W32p Rev D*/
   28.86                  case 0x03: return 0x32;
   28.87                  
   28.88 -                case 0x04: return 0x03; /*Respond to IO and memory accesses*/
   28.89 +                case PCI_REG_COMMAND:
   28.90 +                return et4000->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/
   28.91  
   28.92                  case 0x07: return 1 << 1; /*Medium DEVSEL timing*/
   28.93                  
   28.94 @@ -917,10 +962,10 @@
   28.95                  case 0x12: return svga->crtc[0x5a] & 0x80;
   28.96                  case 0x13: return svga->crtc[0x59];
   28.97  
   28.98 -                case 0x30: return 0x01; /*BIOS ROM address*/
   28.99 +                case 0x30: return et4000->pci_regs[0x30] & 0x01; /*BIOS ROM address*/
  28.100                  case 0x31: return 0x00;
  28.101 -                case 0x32: return 0x0C;
  28.102 -                case 0x33: return 0x00;
  28.103 +                case 0x32: return et4000->pci_regs[0x32];
  28.104 +                case 0x33: return et4000->pci_regs[0x33];
  28.105          }
  28.106          return 0;
  28.107  }
  28.108 @@ -931,10 +976,34 @@
  28.109  
  28.110          switch (addr)
  28.111          {
  28.112 +                case PCI_REG_COMMAND:
  28.113 +                et4000->pci_regs[PCI_REG_COMMAND] = val & 0x27;
  28.114 +                if (val & PCI_COMMAND_IO)
  28.115 +                        et4000w32p_io_set(et4000);
  28.116 +                else
  28.117 +                        et4000w32p_io_remove(et4000);
  28.118 +                et4000w32p_recalcmapping(et4000);
  28.119 +                break;
  28.120 +
  28.121                  case 0x13: 
  28.122                  et4000->linearbase = val << 24; 
  28.123                  et4000w32p_recalcmapping(et4000); 
  28.124                  break;
  28.125 +
  28.126 +                case 0x30: case 0x32: case 0x33:
  28.127 +                et4000->pci_regs[addr] = val;
  28.128 +                if (et4000->pci_regs[0x30] & 0x01)
  28.129 +                {
  28.130 +                        uint32_t addr = (et4000->pci_regs[0x32] << 16) | (et4000->pci_regs[0x33] << 24);
  28.131 +                        pclog("ET4000 bios_rom enabled at %08x\n", addr);
  28.132 +                        mem_mapping_set_addr(&et4000->bios_rom.mapping, addr, 0x8000);
  28.133 +                }
  28.134 +                else
  28.135 +                {
  28.136 +                        pclog("ET4000 bios_rom disabled\n");
  28.137 +                        mem_mapping_disable(&et4000->bios_rom.mapping);
  28.138 +                }
  28.139 +                return;
  28.140          }
  28.141  }
  28.142  
  28.143 @@ -948,25 +1017,31 @@
  28.144                     et4000w32p_in, et4000w32p_out,
  28.145                     et4000w32p_hwcursor_draw); 
  28.146  
  28.147 -        mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &et4000->svga);
  28.148 -        mem_mapping_add(&et4000->mmu_mapping,    0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, et4000);
  28.149 +        rom_init(&et4000->bios_rom, "roms/et4000w32.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
  28.150 +        if (PCI)
  28.151 +                mem_mapping_disable(&et4000->bios_rom.mapping);
  28.152  
  28.153 -        io_sethandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
  28.154 +        mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &et4000->svga);
  28.155 +        mem_mapping_add(&et4000->mmu_mapping,    0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL, 0, et4000);
  28.156  
  28.157 -        io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
  28.158 -        io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
  28.159 -        io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
  28.160 -        io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
  28.161 -        io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
  28.162 -        io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
  28.163 -        io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
  28.164 -        io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000);
  28.165 +        et4000w32p_io_set(et4000);
  28.166          
  28.167          pci_add(et4000w32p_pci_read, et4000w32p_pci_write, et4000);
  28.168 +
  28.169 +        et4000->pci_regs[0x04] = 7;
  28.170 +        
  28.171 +        et4000->pci_regs[0x30] = 0x00;
  28.172 +        et4000->pci_regs[0x32] = 0x0c;
  28.173 +        et4000->pci_regs[0x33] = 0x00;
  28.174          
  28.175          return et4000;
  28.176  }
  28.177  
  28.178 +int et4000w32p_available()
  28.179 +{
  28.180 +        return rom_present("roms/et4000w32.bin");
  28.181 +}
  28.182 +
  28.183  void et4000w32p_close(void *p)
  28.184  {
  28.185          et4000w32p_t *et4000 = (et4000w32p_t *)p;
  28.186 @@ -1003,7 +1078,7 @@
  28.187          0,
  28.188          et4000w32p_init,
  28.189          et4000w32p_close,
  28.190 -        NULL,
  28.191 +        et4000w32p_available,
  28.192          et4000w32p_speed_changed,
  28.193          et4000w32p_force_redraw,
  28.194          et4000w32p_add_status_info
    29.1 --- a/src/vid_hercules.c	Sun Mar 09 11:24:58 2014 +0000
    29.2 +++ b/src/vid_hercules.c	Thu Mar 20 14:03:55 2014 +0000
    29.3 @@ -313,7 +313,7 @@
    29.4          hercules->vram = malloc(0x10000);
    29.5  
    29.6          timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules);
    29.7 -        mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL,  hercules);
    29.8 +        mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL,  NULL, 0, hercules);
    29.9          io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules);
   29.10  
   29.11          for (c = 0; c < 256; c++)
    30.1 --- a/src/vid_mda.c	Sun Mar 09 11:24:58 2014 +0000
    30.2 +++ b/src/vid_mda.c	Thu Mar 20 14:03:55 2014 +0000
    30.3 @@ -270,7 +270,7 @@
    30.4          mda->vram = malloc(0x1000);
    30.5  
    30.6          timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda);
    30.7 -        mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL,  mda);
    30.8 +        mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL,  NULL, 0, mda);
    30.9          io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda);
   30.10  
   30.11          for (c = 0; c < 256; c++)
    31.1 --- a/src/vid_olivetti_m24.c	Sun Mar 09 11:24:58 2014 +0000
    31.2 +++ b/src/vid_olivetti_m24.c	Thu Mar 20 14:03:55 2014 +0000
    31.3 @@ -459,7 +459,7 @@
    31.4          m24->vram = malloc(0x8000);
    31.5                  
    31.6          timer_add(m24_poll, &m24->vidtime, TIMER_ALWAYS_ENABLED, m24);
    31.7 -        mem_mapping_add(&m24->mapping, 0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL,  m24);
    31.8 +        mem_mapping_add(&m24->mapping, 0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL,  NULL, 0, m24);
    31.9          io_sethandler(0x03d0, 0x0010, m24_in, NULL, NULL, m24_out, NULL, NULL, m24);
   31.10          return m24;
   31.11  }
    32.1 --- a/src/vid_oti067.c	Sun Mar 09 11:24:58 2014 +0000
    32.2 +++ b/src/vid_oti067.c	Thu Mar 20 14:03:55 2014 +0000
    32.3 @@ -4,6 +4,7 @@
    32.4  #include "device.h"
    32.5  #include "io.h"
    32.6  #include "mem.h"
    32.7 +#include "rom.h"
    32.8  #include "video.h"
    32.9  #include "vid_oti067.h"
   32.10  #include "vid_svga.h"
   32.11 @@ -12,6 +13,8 @@
   32.12  {
   32.13          svga_t svga;
   32.14          
   32.15 +        rom_t bios_rom;
   32.16 +        
   32.17          int index;
   32.18          uint8_t regs[32];
   32.19  } oti067_t;
   32.20 @@ -110,11 +113,13 @@
   32.21          svga->interlace = oti067->regs[0x14] & 0x80;
   32.22  }
   32.23  
   32.24 -void *oti067_init()
   32.25 +void *oti067_common_init(char *bios_fn)
   32.26  {
   32.27          oti067_t *oti067 = malloc(sizeof(oti067_t));
   32.28          memset(oti067, 0, sizeof(oti067_t));
   32.29          
   32.30 +        rom_init(&oti067->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, 0);
   32.31 +
   32.32          svga_init(&oti067->svga, oti067, 1 << 19, /*512kb*/
   32.33                     oti067_recalctimings,
   32.34                     oti067_in, oti067_out,
   32.35 @@ -126,6 +131,26 @@
   32.36          return oti067;
   32.37  }
   32.38  
   32.39 +void *oti067_init()
   32.40 +{
   32.41 +        return oti067_common_init("roms/oti067/bios.bin");
   32.42 +}
   32.43 +
   32.44 +void *oti067_acer386_init()
   32.45 +{
   32.46 +        oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin");
   32.47 +        
   32.48 +        if (oti067)
   32.49 +                oti067->bios_rom.rom[0x5d] = 0x74;
   32.50 +                
   32.51 +        return oti067;
   32.52 +}
   32.53 +
   32.54 +static int oti067_available()
   32.55 +{
   32.56 +        return rom_present("roms/oti067/bios.bin");
   32.57 +}
   32.58 +
   32.59  void oti067_close(void *p)
   32.60  {
   32.61          oti067_t *oti067 = (oti067_t *)p;
   32.62 @@ -162,8 +187,19 @@
   32.63          0,
   32.64          oti067_init,
   32.65          oti067_close,
   32.66 -        NULL,
   32.67 +        oti067_available,
   32.68          oti067_speed_changed,
   32.69          oti067_force_redraw,
   32.70          oti067_add_status_info
   32.71  };
   32.72 +device_t oti067_acer386_device =
   32.73 +{
   32.74 +        "Oak OTI-067 (Acermate 386SX/25N)",
   32.75 +        0,
   32.76 +        oti067_acer386_init,
   32.77 +        oti067_close,
   32.78 +        oti067_available,
   32.79 +        oti067_speed_changed,
   32.80 +        oti067_force_redraw,
   32.81 +        oti067_add_status_info
   32.82 +};
    33.1 --- a/src/vid_oti067.h	Sun Mar 09 11:24:58 2014 +0000
    33.2 +++ b/src/vid_oti067.h	Thu Mar 20 14:03:55 2014 +0000
    33.3 @@ -1,1 +1,2 @@
    33.4  extern device_t oti067_device;
    33.5 +extern device_t oti067_acer386_device;
    34.1 --- a/src/vid_paradise.c	Sun Mar 09 11:24:58 2014 +0000
    34.2 +++ b/src/vid_paradise.c	Thu Mar 20 14:03:55 2014 +0000
    34.3 @@ -7,6 +7,7 @@
    34.4  #include "ibm.h"
    34.5  #include "device.h"
    34.6  #include "mem.h"
    34.7 +#include "rom.h"
    34.8  #include "video.h"
    34.9  #include "vid_paradise.h"
   34.10  #include "vid_svga.h"
   34.11 @@ -17,6 +18,8 @@
   34.12  {
   34.13          svga_t svga;
   34.14          
   34.15 +        rom_t bios_rom;
   34.16 +        
   34.17          enum
   34.18          {
   34.19                  PVGA1A = 0,
   34.20 @@ -312,6 +315,38 @@
   34.21          return paradise;
   34.22  }
   34.23  
   34.24 +static void *paradise_pvga1a_pc2086_init()
   34.25 +{
   34.26 +        paradise_t *paradise = paradise_pvga1a_init();
   34.27 +        
   34.28 +        if (paradise)
   34.29 +                rom_init(&paradise->bios_rom, "roms/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, 0);
   34.30 +                
   34.31 +        return paradise;
   34.32 +}
   34.33 +static void *paradise_pvga1a_pc3086_init()
   34.34 +{
   34.35 +        paradise_t *paradise = paradise_pvga1a_init();
   34.36 +
   34.37 +        if (paradise)
   34.38 +                rom_init(&paradise->bios_rom, "roms/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, 0);
   34.39 +                
   34.40 +        return paradise;
   34.41 +}
   34.42 +
   34.43 +static void *paradise_wd90c11_megapc_init()
   34.44 +{
   34.45 +        paradise_t *paradise = paradise_wd90c11_init();
   34.46 +        
   34.47 +        if (paradise)
   34.48 +                rom_init_interleaved(&paradise->bios_rom,
   34.49 +                                     "roms/megapc/41651-bios lo.u18",
   34.50 +                                     "roms/megapc/211253-bios hi.u19",
   34.51 +                                     0xc0000, 0x8000, 0x7fff, 0, 0);
   34.52 +        
   34.53 +        return paradise;
   34.54 +}
   34.55 +
   34.56  void paradise_close(void *p)
   34.57  {
   34.58          paradise_t *paradise = (paradise_t *)p;
   34.59 @@ -342,25 +377,36 @@
   34.60          return svga_add_status_info(s, max_len, &paradise->svga);
   34.61  }
   34.62  
   34.63 -device_t paradise_pvga1a_device =
   34.64 +device_t paradise_pvga1a_pc2086_device =
   34.65  {
   34.66 -        "Paradise PVGA1A",
   34.67 +        "Paradise PVGA1A (Amstrad PC2086)",
   34.68          0,
   34.69 -        paradise_pvga1a_init,
   34.70 +        paradise_pvga1a_pc2086_init,
   34.71          paradise_close,
   34.72          NULL,
   34.73          paradise_speed_changed,
   34.74          paradise_force_redraw,
   34.75          paradise_add_status_info
   34.76  };
   34.77 -device_t paradise_wd90c11_device =
   34.78 +device_t paradise_pvga1a_pc3086_device =
   34.79  {
   34.80 -        "Paradise WD90C11",
   34.81 +        "Paradise PVGA1A (Amstrad PC3086)",
   34.82          0,
   34.83 -        paradise_wd90c11_init,
   34.84 +        paradise_pvga1a_pc3086_init,
   34.85          paradise_close,
   34.86          NULL,
   34.87          paradise_speed_changed,
   34.88          paradise_force_redraw,
   34.89          paradise_add_status_info
   34.90  };
   34.91 +device_t paradise_wd90c11_megapc_device =
   34.92 +{
   34.93 +        "Paradise WD90C11 (Amstrad MegaPC)",
   34.94 +        0,
   34.95 +        paradise_wd90c11_megapc_init,
   34.96 +        paradise_close,
   34.97 +        NULL,
   34.98 +        paradise_speed_changed,
   34.99 +        paradise_force_redraw,
  34.100 +        paradise_add_status_info
  34.101 +};
    35.1 --- a/src/vid_paradise.h	Sun Mar 09 11:24:58 2014 +0000
    35.2 +++ b/src/vid_paradise.h	Thu Mar 20 14:03:55 2014 +0000
    35.3 @@ -1,2 +1,3 @@
    35.4 -extern device_t paradise_pvga1a_device;
    35.5 -extern device_t paradise_wd90c11_device;
    35.6 +extern device_t paradise_pvga1a_pc2086_device;
    35.7 +extern device_t paradise_pvga1a_pc3086_device;
    35.8 +extern device_t paradise_wd90c11_megapc_device;
    36.1 --- a/src/vid_pc1512.c	Sun Mar 09 11:24:58 2014 +0000
    36.2 +++ b/src/vid_pc1512.c	Thu Mar 20 14:03:55 2014 +0000
    36.3 @@ -460,7 +460,7 @@
    36.4          pc1512->cgamode = 0x12;
    36.5                  
    36.6          timer_add(pc1512_poll, &pc1512->vidtime, TIMER_ALWAYS_ENABLED, pc1512);
    36.7 -        mem_mapping_add(&pc1512->mapping, 0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL,  pc1512);
    36.8 +        mem_mapping_add(&pc1512->mapping, 0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL,  NULL, 0, pc1512);
    36.9          io_sethandler(0x03d0, 0x0010, pc1512_in, NULL, NULL, pc1512_out, NULL, NULL, pc1512);
   36.10          return pc1512;
   36.11  }
    37.1 --- a/src/vid_pc1640.c	Sun Mar 09 11:24:58 2014 +0000
    37.2 +++ b/src/vid_pc1640.c	Thu Mar 20 14:03:55 2014 +0000
    37.3 @@ -5,6 +5,7 @@
    37.4  #include "device.h"
    37.5  #include "io.h"
    37.6  #include "mem.h"
    37.7 +#include "rom.h"
    37.8  #include "timer.h"
    37.9  #include "video.h"
   37.10  #include "vid_cga.h"
   37.11 @@ -19,6 +20,8 @@
   37.12          cga_t cga;
   37.13          ega_t ega;
   37.14          
   37.15 +        rom_t bios_rom;
   37.16 +        
   37.17          int cga_enabled;
   37.18          int dispontime, dispofftime, vidtime;
   37.19  } pc1640_t;
   37.20 @@ -114,14 +117,16 @@
   37.21          ega_t *ega = &pc1640->ega;
   37.22          memset(pc1640, 0, sizeof(pc1640_t));
   37.23  
   37.24 +        rom_init(&pc1640->bios_rom, "roms/pc1640/40100", 0xc0000, 0x8000, 0x7fff, 0, 0);
   37.25 +        
   37.26          ega_init(&pc1640->ega);
   37.27          pc1640->cga.vram = pc1640->ega.vram;
   37.28          pc1640->cga_enabled = 1;
   37.29          cga_init(&pc1640->cga);
   37.30                          
   37.31          timer_add(pc1640_poll, &pc1640->vidtime, TIMER_ALWAYS_ENABLED, pc1640);
   37.32 -        mem_mapping_add(&pc1640->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  cga);
   37.33 -        mem_mapping_add(&pc1640->ega_mapping, 0,       0,       ega_read, NULL, NULL, ega_write, NULL, NULL,  ega);
   37.34 +        mem_mapping_add(&pc1640->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  NULL, 0, cga);
   37.35 +        mem_mapping_add(&pc1640->ega_mapping, 0,       0,       ega_read, NULL, NULL, ega_write, NULL, NULL,  NULL, 0, ega);
   37.36          io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640);
   37.37          return pc1640;
   37.38  }
    38.1 --- a/src/vid_pc200.c	Sun Mar 09 11:24:58 2014 +0000
    38.2 +++ b/src/vid_pc200.c	Thu Mar 20 14:03:55 2014 +0000
    38.3 @@ -111,7 +111,7 @@
    38.4          cga_init(&pc200->cga);
    38.5                          
    38.6          timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
    38.7 -        mem_mapping_add(&pc200->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  cga);
    38.8 +        mem_mapping_add(&pc200->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL,  NULL, 0, cga);
    38.9          io_sethandler(0x03d0, 0x0010, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200);
   38.10          return cga;
   38.11  }
    39.1 --- a/src/vid_pcjr.c	Sun Mar 09 11:24:58 2014 +0000
    39.2 +++ b/src/vid_pcjr.c	Thu Mar 20 14:03:55 2014 +0000
    39.3 @@ -615,7 +615,7 @@
    39.4                  q_filt[c] = 512.0 * sin((3.14 * (pcjr_tint + c * 4) / 16.0) - 33.0 / 180.0);
    39.5          }
    39.6          timer_add(pcjr_poll, &pcjr->vidtime, TIMER_ALWAYS_ENABLED, pcjr);
    39.7 -        mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, pcjr_read, NULL, NULL, pcjr_write, NULL, NULL,  pcjr);
    39.8 +        mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, pcjr_read, NULL, NULL, pcjr_write, NULL, NULL,  NULL, 0, pcjr);
    39.9          io_sethandler(0x03d0, 0x0010, pcjr_in, NULL, NULL, pcjr_out, NULL, NULL, pcjr);
   39.10          return pcjr;
   39.11  }
    40.1 --- a/src/vid_s3.c	Sun Mar 09 11:24:58 2014 +0000
    40.2 +++ b/src/vid_s3.c	Thu Mar 20 14:03:55 2014 +0000
    40.3 @@ -5,6 +5,7 @@
    40.4  #include "io.h"
    40.5  #include "mem.h"
    40.6  #include "pci.h"
    40.7 +#include "rom.h"
    40.8  #include "video.h"
    40.9  #include "vid_s3.h"
   40.10  #include "vid_svga.h"
   40.11 @@ -16,6 +17,8 @@
   40.12          mem_mapping_t linear_mapping;
   40.13          mem_mapping_t mmio_mapping;
   40.14          
   40.15 +        rom_t bios_rom;
   40.16 +        
   40.17          svga_t svga;
   40.18          sdac_ramdac_t ramdac;
   40.19  
   40.20 @@ -25,8 +28,12 @@
   40.21          int bpp;
   40.22  
   40.23          uint8_t id, id_ext;
   40.24 +        
   40.25 +        int packed_mmio;
   40.26  
   40.27          uint32_t linear_base, linear_size;
   40.28 +        
   40.29 +        uint8_t pci_regs[256];
   40.30  
   40.31          float (*getclock)(int clock, void *p);
   40.32          void *getclock_p;
   40.33 @@ -238,7 +245,7 @@
   40.34                  case 0x3d4:
   40.35                  return svga->crtcreg;
   40.36                  case 0x3d5:
   40.37 -//                pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc);
   40.38 +//                pclog("Read CRTC R%02X %04X:%04X\n", svga->crtcreg, CS, pc);
   40.39                  switch (svga->crtcreg)
   40.40                  {
   40.41                          case 0x2d: return 0x88;       /*Extended chip ID*/
   40.42 @@ -322,6 +329,14 @@
   40.43          
   40.44  //        video_write_a000_w = video_write_a000_l = NULL;
   40.45  
   40.46 +        if (!(s3->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))
   40.47 +        {
   40.48 +//                pclog("Update mapping - PCI disabled\n");
   40.49 +                mem_mapping_disable(&svga->mapping);
   40.50 +                mem_mapping_disable(&s3->linear_mapping);
   40.51 +                mem_mapping_disable(&s3->mmio_mapping);
   40.52 +                return;
   40.53 +        }
   40.54  
   40.55  //        pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc);
   40.56          switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/
   40.57 @@ -371,8 +386,11 @@
   40.58                  if (s3->linear_base == 0xa0000)
   40.59                  {
   40.60                          mem_mapping_disable(&s3->linear_mapping);
   40.61 -                        mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
   40.62 -                        svga->banked_mask = 0xffff;
   40.63 +                        if (!(svga->crtc[0x53] & 0x10))
   40.64 +                        {
   40.65 +                                mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
   40.66 +                                svga->banked_mask = 0xffff;
   40.67 +                        }
   40.68  //                        mem_mapping_set_addr(&s3->linear_mapping, 0xa0000, 0x10000);
   40.69                  }
   40.70                  else
   40.71 @@ -383,7 +401,10 @@
   40.72          
   40.73  //        pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x10);
   40.74          if (svga->crtc[0x53] & 0x10) /*Memory mapped IO*/
   40.75 +        {
   40.76 +                mem_mapping_disable(&svga->mapping);
   40.77                  mem_mapping_enable(&s3->mmio_mapping);
   40.78 +        }
   40.79          else
   40.80                  mem_mapping_disable(&s3->mmio_mapping);
   40.81  }
   40.82 @@ -412,6 +433,7 @@
   40.83  {
   40.84          s3_t *s3 = (s3_t *)p;
   40.85  //        pclog("Accel out %04X %02X\n", port, val);
   40.86 +        
   40.87          switch (port)
   40.88          {
   40.89                  case 0x42e8:
   40.90 @@ -795,12 +817,109 @@
   40.91          return 0;
   40.92  }
   40.93  
   40.94 +#define WRITE8(addr, var, val)  switch ((addr) & 3)                                             \
   40.95 +                                {                                                               \
   40.96 +                                        case 0: var = (var & 0xffffff00) | (val);         break;  \
   40.97 +                                        case 1: var = (var & 0xffff00ff) | ((val) << 8);  break;  \
   40.98 +                                        case 2: var = (var & 0xff00ffff) | ((val) << 16); break;  \
   40.99 +                                        case 3: var = (var & 0x00ffffff) | ((val) << 24); break;  \
  40.100 +                                }
  40.101 +
  40.102  void s3_accel_write(uint32_t addr, uint8_t val, void *p)
  40.103  {
  40.104          s3_t *s3 = (s3_t *)p;
  40.105  //        pclog("Write S3 accel %08X %02X\n", addr, val);
  40.106 +        if (s3->packed_mmio)
  40.107 +        {
  40.108 +                int addr_lo = addr & 1;
  40.109 +                switch (addr & 0xfffe)
  40.110 +                {
  40.111 +                        case 0x8100: addr = 0x82e8; break; /*ALT_CURXY*/
  40.112 +                        case 0x8102: addr = 0x86e8; break;
  40.113 +                        
  40.114 +                        case 0x8104: addr = 0x82ea; break; /*ALT_CURXY2*/
  40.115 +                        case 0x8106: addr = 0x86ea; break;
  40.116 +                        
  40.117 +                        case 0x8108: addr = 0x8ae8; break; /*ALT_STEP*/
  40.118 +                        case 0x810a: addr = 0x8ee8; break;
  40.119 +                        
  40.120 +                        case 0x810c: addr = 0x8aea; break; /*ALT_STEP2*/
  40.121 +                        case 0x810e: addr = 0x8eea; break;
  40.122 +
  40.123 +                        case 0x8110: addr = 0x92e8; break; /*ALT_ERR*/
  40.124 +                        case 0x8112: addr = 0x92ee; break;
  40.125 +
  40.126 +                        case 0x8118: addr = 0x9ae8; break; /*ALT_CMD*/
  40.127 +                        case 0x811a: addr = 0x9aea; break;
  40.128 +                        
  40.129 +                        case 0x811c: addr = 0x9ee8; break; /*SHORT_STROKE*/
  40.130 +                        
  40.131 +                        case 0x8120: case 0x8122:          /*BKGD_COLOR*/
  40.132 +                        WRITE8(addr, s3->accel.bkgd_color, val);
  40.133 +                        return;
  40.134 +                        
  40.135 +                        case 0x8124: case 0x8126:          /*FRGD_COLOR*/
  40.136 +                        WRITE8(addr, s3->accel.frgd_color, val);
  40.137 +                        return;
  40.138 +
  40.139 +                        case 0x8128: case 0x812a:          /*WRT_MASK*/
  40.140 +                        WRITE8(addr, s3->accel.wrt_mask, val);
  40.141 +                        return;
  40.142 +
  40.143 +                        case 0x812c: case 0x812e:          /*RD_MASK*/
  40.144 +                        WRITE8(addr, s3->accel.rd_mask, val);
  40.145 +                        return;
  40.146 +
  40.147 +                        case 0x8130: case 0x8132:          /*COLOR_CMP*/
  40.148 +                        WRITE8(addr, s3->accel.color_cmp, val);
  40.149 +                        return;
  40.150 +
  40.151 +                        case 0x8134: addr = 0xb6e8; break; /*ALT_MIX*/
  40.152 +                        case 0x8136: addr = 0xbae8; break;
  40.153 +                        
  40.154 +                        case 0x8138:                       /*SCISSORS_T*/
  40.155 +                        WRITE8(addr & 1, s3->accel.multifunc[1], val);
  40.156 +                        return;
  40.157 +                        case 0x813a:                       /*SCISSORS_L*/
  40.158 +                        WRITE8(addr & 1, s3->accel.multifunc[2], val);
  40.159 +                        return;
  40.160 +                        case 0x813c:                       /*SCISSORS_B*/
  40.161 +                        WRITE8(addr & 1, s3->accel.multifunc[3], val);
  40.162 +                        return;
  40.163 +                        case 0x813e:                       /*SCISSORS_R*/
  40.164 +                        WRITE8(addr & 1, s3->accel.multifunc[4], val);
  40.165 +                        return;
  40.166 +
  40.167 +                        case 0x8140:                       /*PIX_CNTL*/
  40.168 +                        WRITE8(addr & 1, s3->accel.multifunc[0xa], val);
  40.169 +                        return;
  40.170 +                        case 0x8142:                       /*MULT_MISC2*/
  40.171 +                        WRITE8(addr & 1, s3->accel.multifunc[0xd], val);
  40.172 +                        return;
  40.173 +                        case 0x8144:                       /*MULT_MISC*/
  40.174 +                        WRITE8(addr & 1, s3->accel.multifunc[0xe], val);
  40.175 +                        return;
  40.176 +                        case 0x8146:                       /*READ_SEL*/
  40.177 +                        WRITE8(addr & 1, s3->accel.multifunc[0xf], val);
  40.178 +                        return;
  40.179 +
  40.180 +                        case 0x8148:                       /*ALT_PCNT*/
  40.181 +                        WRITE8(addr & 1, s3->accel.multifunc[0], val);
  40.182 +                        return;
  40.183 +                        case 0x814a: addr = 0x96e8; break;
  40.184 +                        case 0x814c: addr = 0x96ea; break;
  40.185 +
  40.186 +                        case 0x8168: addr = 0xeae8; break;
  40.187 +                        case 0x816a: addr = 0xeaea; break;
  40.188 +                }
  40.189 +                addr |= addr_lo;
  40.190 +        }
  40.191 +        
  40.192 +
  40.193          if (addr & 0x8000)
  40.194 -           s3_accel_out(addr & 0xffff, val, p);
  40.195 +        {
  40.196 +                s3_accel_out(addr & 0xffff, val, p);
  40.197 +        }
  40.198          else
  40.199          {
  40.200                  if (s3->accel.cmd & 0x100)
  40.201 @@ -819,8 +938,8 @@
  40.202  //        pclog("Write S3 accel w %08X %04X\n", addr, val);
  40.203          if (addr & 0x8000)
  40.204          {
  40.205 -                s3_accel_out( addr & 0xffff,      val, p);
  40.206 -                s3_accel_out((addr & 0xffff) + 1, val >> 8, p);
  40.207 +                s3_accel_write(addr,     val,      p);
  40.208 +                s3_accel_write(addr + 1, val >> 8, p);
  40.209          }
  40.210          else
  40.211          {
  40.212 @@ -844,10 +963,10 @@
  40.213  //        pclog("Write S3 accel l %08X %08X\n", addr, val);
  40.214          if (addr & 0x8000)
  40.215          {
  40.216 -                s3_accel_out( addr & 0xffff,      val,       p);
  40.217 -                s3_accel_out((addr & 0xffff) + 1, val >> 8,  p);
  40.218 -                s3_accel_out((addr & 0xffff) + 2, val >> 16, p);
  40.219 -                s3_accel_out((addr & 0xffff) + 3, val >> 24, p);
  40.220 +                s3_accel_write(addr,     val,        p);
  40.221 +                s3_accel_write(addr + 1, val >> 8,   p);
  40.222 +                s3_accel_write(addr + 2, val >> 16,  p);
  40.223 +                s3_accel_write(addr + 3, val >> 24,  p);
  40.224          }
  40.225          else
  40.226          {
  40.227 @@ -1531,78 +1650,37 @@
  40.228  }
  40.229  
  40.230  
  40.231 -uint8_t s3_pci_read(int func, int addr, void *p)
  40.232 +static void s3_io_remove(s3_t *s3)
  40.233  {
  40.234 -        s3_t *s3 = (s3_t *)p;
  40.235 -        svga_t *svga = &s3->svga;
  40.236 -//        pclog("S3 PCI read %08X\n", addr);
  40.237 -        switch (addr)
  40.238 -        {
  40.239 -                case 0x00: return 0x33; /*'S3'*/
  40.240 -                case 0x01: return 0x53;
  40.241 -                
  40.242 -                case 0x02: return s3->id_ext;
  40.243 -                case 0x03: return 0x88;
  40.244 -                
  40.245 -                case 0x04: return 0x03; /*Respond to IO and memory accesses*/
  40.246 -
  40.247 -                case 0x07: return 1 << 1; /*Medium DEVSEL timing*/
  40.248 -                
  40.249 -                case 0x08: return 0; /*Revision ID*/
  40.250 -                case 0x09: return 0; /*Programming interface*/
  40.251 -                
  40.252 -                case 0x0a: return 0x01; /*Supports VGA interface*/
  40.253 -                case 0x0b: return 0x03;
  40.254 -                
  40.255 -                case 0x10: return 0x00; /*Linear frame buffer address*/
  40.256 -                case 0x11: return 0x00;
  40.257 -                case 0x12: return svga->crtc[0x5a] & 0x80;
  40.258 -                case 0x13: return svga->crtc[0x59];
  40.259 -
  40.260 -                case 0x30: return 0x01; /*BIOS ROM address*/
  40.261 -                case 0x31: return 0x00;
  40.262 -                case 0x32: return 0x0C;
  40.263 -                case 0x33: return 0x00;
  40.264 -        }
  40.265 -        return 0;
  40.266 +        io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3);
  40.267 +        
  40.268 +        io_removehandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.269 +        io_removehandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.270 +        io_removehandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.271 +        io_removehandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.272 +        io_removehandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.273 +        io_removehandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.274 +        io_removehandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.275 +        io_removehandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.276 +        io_removehandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.277 +        io_removehandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.278 +        io_removehandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.279 +        io_removehandler(0xa2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.280 +        io_removehandler(0xa6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.281 +        io_removehandler(0xaae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.282 +        io_removehandler(0xaee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.283 +        io_removehandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.284 +        io_removehandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.285 +        io_removehandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.286 +        io_removehandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.287 +        io_removehandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l,  s3);
  40.288  }
  40.289  
  40.290 -void s3_pci_write(int func, int addr, uint8_t val, void *p)
  40.291 +static void s3_io_set(s3_t *s3)
  40.292  {
  40.293 -        s3_t *s3 = (s3_t *)p;
  40.294 -        svga_t *svga = &s3->svga;
  40.295 -        switch (addr)
  40.296 -        {
  40.297 -                case 0x12: 
  40.298 -                svga->crtc[0x5a] = val & 0x80; 
  40.299 -                s3_updatemapping(s3); 
  40.300 -                break;
  40.301 -                case 0x13: 
  40.302 -                svga->crtc[0x59] = val;        
  40.303 -                s3_updatemapping(s3); 
  40.304 -                break;                
  40.305 -        }
  40.306 -}
  40.307 -
  40.308 -static void *s3_init()
  40.309 -{
  40.310 -        s3_t *s3 = malloc(sizeof(s3_t));
  40.311 -        svga_t *svga = &s3->svga;
  40.312 -        memset(s3, 0, sizeof(s3_t));
  40.313 -        
  40.314 -        mem_mapping_add(&s3->linear_mapping, 0,       0,       svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &s3->svga);
  40.315 -        mem_mapping_add(&s3->mmio_mapping,   0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, s3);
  40.316 -        mem_mapping_disable(&s3->mmio_mapping);
  40.317 -
  40.318 -        svga_init(&s3->svga, s3, 1 << 22, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/
  40.319 -                   s3_recalctimings,
  40.320 -                   s3_in, s3_out,
  40.321 -                   s3_hwcursor_draw);
  40.322 +        s3_io_remove(s3);
  40.323  
  40.324          io_sethandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3);
  40.325 -
  40.326 -        svga->crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
  40.327 -        svga->crtc[0x37] = 1 | (7 << 5);
  40.328          
  40.329          io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.330          io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.331 @@ -1624,31 +1702,149 @@
  40.332          io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.333          io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL,  s3);
  40.334          io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l,  s3);
  40.335 +}
  40.336 +
  40.337 +        
  40.338 +uint8_t s3_pci_read(int func, int addr, void *p)
  40.339 +{
  40.340 +        s3_t *s3 = (s3_t *)p;
  40.341 +        svga_t *svga = &s3->svga;
  40.342 +//        pclog("S3 PCI read %08X\n", addr);
  40.343 +        switch (addr)
  40.344 +        {
  40.345 +                case 0x00: return 0x33; /*'S3'*/
  40.346 +                case 0x01: return 0x53;
  40.347 +                
  40.348 +                case 0x02: return s3->id_ext;
  40.349 +                case 0x03: return 0x88;
  40.350 +                
  40.351 +                case PCI_REG_COMMAND:
  40.352 +                return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/
  40.353 +
  40.354 +                case 0x07: return 1 << 1; /*Medium DEVSEL timing*/
  40.355 +                
  40.356 +                case 0x08: return 0; /*Revision ID*/
  40.357 +                case 0x09: return 0; /*Programming interface*/
  40.358 +                
  40.359 +                case 0x0a: return 0x01; /*Supports VGA interface*/
  40.360 +                case 0x0b: return 0x03;
  40.361 +                
  40.362 +                case 0x10: return 0x00; /*Linear frame buffer address*/
  40.363 +                case 0x11: return 0x00;
  40.364 +                case 0x12: return svga->crtc[0x5a] & 0x80;
  40.365 +                case 0x13: return svga->crtc[0x59];
  40.366 +
  40.367 +                case 0x30: return s3->pci_regs[0x30] & 0x01; /*BIOS ROM address*/
  40.368 +                case 0x31: return 0x00;
  40.369 +                case 0x32: return s3->pci_regs[0x32];
  40.370 +                case 0x33: return s3->pci_regs[0x33];
  40.371 +        }
  40.372 +        return 0;
  40.373 +}
  40.374 +
  40.375 +void s3_pci_write(int func, int addr, uint8_t val, void *p)
  40.376 +{
  40.377 +        s3_t *s3 = (s3_t *)p;
  40.378 +        svga_t *svga = &s3->svga;
  40.379 +        pclog("s3_pci_write: addr=%02x val=%02x\n", addr, val);
  40.380 +        switch (addr)
  40.381 +        {
  40.382 +                case PCI_REG_COMMAND:
  40.383 +                s3->pci_regs[PCI_REG_COMMAND] = val & 0x27;
  40.384 +                if (val & PCI_COMMAND_IO)
  40.385 +                        s3_io_set(s3);
  40.386 +                else
  40.387 +                        s3_io_remove(s3);
  40.388 +                s3_updatemapping(s3);
  40.389 +                break;
  40.390 +                
  40.391 +                case 0x12: 
  40.392 +                svga->crtc[0x5a] = val & 0x80; 
  40.393 +                s3_updatemapping(s3); 
  40.394 +                break;
  40.395 +                case 0x13: 
  40.396 +                svga->crtc[0x59] = val;        
  40.397 +                s3_updatemapping(s3); 
  40.398 +                break;                
  40.399 +
  40.400 +                case 0x30: case 0x32: case 0x33:
  40.401 +                s3->pci_regs[addr] = val;
  40.402 +                if (s3->pci_regs[0x30] & 0x01)
  40.403 +                {
  40.404 +                        uint32_t addr = (s3->pci_regs[0x32] << 16) | (s3->pci_regs[0x33] << 24);
  40.405 +                        pclog("S3 bios_rom enabled at %08x\n", addr);
  40.406 +                        mem_mapping_set_addr(&s3->bios_rom.mapping, addr, 0x8000);
  40.407 +                }
  40.408 +                else
  40.409 +                {
  40.410 +                        pclog("S3 bios_rom disabled\n");
  40.411 +                        mem_mapping_disable(&s3->bios_rom.mapping);
  40.412 +                }
  40.413 +                return;
  40.414 +        }
  40.415 +}
  40.416 +
  40.417 +static void *s3_init(char *bios_fn)
  40.418 +{
  40.419 +        s3_t *s3 = malloc(sizeof(s3_t));
  40.420 +        svga_t *svga = &s3->svga;
  40.421 +        memset(s3, 0, sizeof(s3_t));
  40.422 +
  40.423 +        rom_init(&s3->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
  40.424 +        if (PCI)
  40.425 +                mem_mapping_disable(&s3->bios_rom.mapping);
  40.426 +
  40.427 +        mem_mapping_add(&s3->linear_mapping, 0,       0,       svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &s3->svga);
  40.428 +        mem_mapping_add(&s3->mmio_mapping,   0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, NULL, 0, s3);
  40.429 +        mem_mapping_disable(&s3->mmio_mapping);
  40.430 +
  40.431 +        svga_init(&s3->svga, s3, 1 << 22, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/
  40.432 +                   s3_recalctimings,
  40.433 +                   s3_in, s3_out,
  40.434 +                   s3_hwcursor_draw);
  40.435 +
  40.436 +        svga->crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
  40.437 +        svga->crtc[0x37] = 1 | (7 << 5);
  40.438 +
  40.439 +        s3_io_set(s3);
  40.440  
  40.441          pci_add(s3_pci_read, s3_pci_write, s3);
  40.442 +        
  40.443 +        s3->pci_regs[0x04] = 7;
  40.444 +        
  40.445 +        s3->pci_regs[0x30] = 0x00;
  40.446 +        s3->pci_regs[0x32] = 0x0c;
  40.447 +        s3->pci_regs[0x33] = 0x00;
  40.448   
  40.449          return s3;
  40.450  }
  40.451  
  40.452  void *s3_bahamas64_init()
  40.453  {
  40.454 -        s3_t *s3 = s3_init();
  40.455 +        s3_t *s3 = s3_init("roms/bahamas64.bin");
  40.456  
  40.457          s3->id = 0xc1; /*Vision864P*/
  40.458 -        s3->id_ext = 0xc1; /*Trio64*/
  40.459 -
  40.460 +        s3->id_ext = 0xc1;
  40.461 +        s3->packed_mmio = 0;
  40.462 +        
  40.463          s3->getclock = sdac_getclock;
  40.464          s3->getclock_p = &s3->ramdac;
  40.465  
  40.466          return s3;
  40.467  }
  40.468  
  40.469 +int s3_bahamas64_available()
  40.470 +{
  40.471 +        return rom_present("roms/bahamas64.bin");
  40.472 +}
  40.473 +
  40.474  void *s3_9fx_init()
  40.475  {
  40.476 -        s3_t *s3 = s3_init();
  40.477 +        s3_t *s3 = s3_init("roms/s3_764.bin");
  40.478  
  40.479 -        s3->id = 0xe1;
  40.480 -        s3->id_ext = 0x11; /*Trio64*/
  40.481 +        s3->id = 0xe1; /*Trio64*/
  40.482 +        s3->id_ext = 0x11;
  40.483 +        s3->packed_mmio = 1;
  40.484  
  40.485          s3->getclock = s3_trio64_getclock;
  40.486          s3->getclock_p = s3;
  40.487 @@ -1656,6 +1852,12 @@
  40.488          return s3;
  40.489  }
  40.490  
  40.491 +int s3_9fx_available()
  40.492 +{
  40.493 +        return rom_present("roms/s3_764.bin");
  40.494 +}
  40.495 +
  40.496 +
  40.497  void s3_close(void *p)
  40.498  {
  40.499          s3_t *s3 = (s3_t *)p;
  40.500 @@ -1692,7 +1894,7 @@
  40.501          0,
  40.502          s3_bahamas64_init,
  40.503          s3_close,
  40.504 -        NULL,
  40.505 +        s3_bahamas64_available,
  40.506          s3_speed_changed,
  40.507          s3_force_redraw,
  40.508          s3_add_status_info
  40.509 @@ -1704,7 +1906,7 @@
  40.510          0,
  40.511          s3_9fx_init,
  40.512          s3_close,
  40.513 -        NULL,
  40.514 +        s3_9fx_available,
  40.515          s3_speed_changed,
  40.516          s3_force_redraw,
  40.517          s3_add_status_info
    41.1 --- a/src/vid_s3_virge.c	Sun Mar 09 11:24:58 2014 +0000
    41.2 +++ b/src/vid_s3_virge.c	Thu Mar 20 14:03:55 2014 +0000
    41.3 @@ -7,6 +7,7 @@
    41.4  #include "io.h"
    41.5  #include "mem.h"
    41.6  #include "pci.h"
    41.7 +#include "rom.h"
    41.8  #include "video.h"
    41.9  #include "vid_s3_virge.h"
   41.10  #include "vid_svga.h"
   41.11 @@ -15,8 +16,11 @@
   41.12  
   41.13  typedef struct virge_t
   41.14  {
   41.15 -        mem_mapping_t linear_mapping;
   41.16 -        mem_mapping_t   mmio_mapping;
   41.17 +        mem_mapping_t   linear_mapping;
   41.18 +        mem_mapping_t     mmio_mapping;
   41.19 +        mem_mapping_t new_mmio_mapping;
   41.20 +        
   41.21 +        rom_t bios_rom;
   41.22          
   41.23          svga_t svga;
   41.24          
   41.25 @@ -30,18 +34,97 @@
   41.26          uint32_t linear_base, linear_size;
   41.27  
   41.28          uint8_t pci_regs[256];
   41.29 +        
   41.30 +        struct
   41.31 +        {
   41.32 +                uint32_t src_base;
   41.33 +                uint32_t dest_base;
   41.34 +                int clip_l, clip_r, clip_t, clip_b;
   41.35 +                int dest_str, src_str;
   41.36 +                uint32_t mono_pat_0;
   41.37 +                uint32_t mono_pat_1;
   41.38 +                uint32_t pat_bg_clr;
   41.39 +                uint32_t pat_fg_clr;
   41.40 +                uint32_t src_bg_clr;
   41.41 +                uint32_t src_fg_clr;
   41.42 +                uint32_t cmd_set;
   41.43 +                int r_width, r_height;
   41.44 +                int rsrc_x, rsrc_y;
   41.45 +                int rdest_x, rdest_y;
   41.46 +                
   41.47 +                int lxend0, lxend1;
   41.48 +                int32_t ldx;
   41.49 +                uint32_t lxstart, lystart;
   41.50 +                int lycnt;
   41.51 +                int line_dir;
   41.52 +                
   41.53 +                int src_x, src_y;
   41.54 +                int dest_x, dest_y;
   41.55 +                int w, h;
   41.56 +                uint8_t rop;
   41.57 +                
   41.58 +                int data_left_count;
   41.59 +                uint32_t data_left;
   41.60 +                
   41.61 +                uint32_t pattern_8[8*8];
   41.62 +                uint32_t pattern_16[8*8];
   41.63 +                uint32_t pattern_32[8*8];
   41.64 +        } s3d;
   41.65  } virge_t;
   41.66  
   41.67 -void s3_virge_updatemapping(virge_t *virge);
   41.68 +static void s3_virge_updatemapping(virge_t *virge);
   41.69  
   41.70 -uint8_t  s3_virge_mmio_read(uint32_t addr, void *p);
   41.71 -uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p);
   41.72 -uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p);
   41.73 -void     s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p);
   41.74 -void     s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p);
   41.75 -void     s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p);
   41.76 +static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat);
   41.77  
   41.78 -void s3_virge_out(uint16_t addr, uint8_t val, void *p)
   41.79 +static uint8_t  s3_virge_mmio_read(uint32_t addr, void *p);
   41.80 +static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p);
   41.81 +static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p);
   41.82 +static void     s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p);
   41.83 +static void     s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p);
   41.84 +static void     s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p);
   41.85 +
   41.86 +static uint8_t  s3_virge_new_mmio_read(uint32_t addr, void *p);
   41.87 +static uint16_t s3_virge_new_mmio_read_w(uint32_t addr, void *p);
   41.88 +static uint32_t s3_virge_new_mmio_read_l(uint32_t addr, void *p);
   41.89 +static void     s3_virge_new_mmio_write(uint32_t addr, uint8_t val, void *p);
   41.90 +static void     s3_virge_new_mmio_write_w(uint32_t addr, uint16_t val, void *p);
   41.91 +static void     s3_virge_new_mmio_write_l(uint32_t addr, uint32_t val, void *p);
   41.92 +
   41.93 +enum
   41.94 +{
   41.95 +        CMD_SET_AE = 1,
   41.96 +        CMD_SET_HC = (1 << 1),
   41.97 +        
   41.98 +        CMD_SET_FORMAT_MASK = (7 << 2),
   41.99 +        CMD_SET_FORMAT_8 = (0 << 2),
  41.100 +        CMD_SET_FORMAT_16 = (1 << 2),
  41.101 +        CMD_SET_FORMAT_24 = (2 << 2),
  41.102 +        
  41.103 +        CMD_SET_MS = (1 << 6),
  41.104 +        CMD_SET_IDS = (1 << 7),
  41.105 +        CMD_SET_MP = (1 << 8),
  41.106 +        CMD_SET_TP = (1 << 9),
  41.107 +        
  41.108 +        CMD_SET_ITA_MASK = (3 << 10),
  41.109 +        CMD_SET_ITA_BYTE = (0 << 10),
  41.110 +        CMD_SET_ITA_WORD = (1 << 10),
  41.111 +        CMD_SET_ITA_DWORD = (2 << 10),
  41.112 +
  41.113 +        CMD_SET_XP = (1 << 25),
  41.114 +        CMD_SET_YP = (1 << 26),
  41.115 +        
  41.116 +        CMD_SET_COMMAND_MASK = (15 << 27)
  41.117 +};
  41.118 +
  41.119 +enum
  41.120 +{
  41.121 +        CMD_SET_COMMAND_BITBLT = (0 << 27),
  41.122 +        CMD_SET_COMMAND_RECTFILL = (2 << 27),
  41.123 +        CMD_SET_COMMAND_LINE = (3 << 27),
  41.124 +        CMD_SET_COMMAND_NOP = (15 << 27)
  41.125 +};
  41.126 +
  41.127 +static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
  41.128  {
  41.129          virge_t *virge = (virge_t *)p;
  41.130          svga_t *svga = &virge->svga;
  41.131 @@ -49,7 +132,7 @@
  41.132  
  41.133          if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 
  41.134                  addr ^= 0x60;
  41.135 -        
  41.136 +       
  41.137  //        pclog("S3 out %04X %02X %04X:%08X  %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins);
  41.138  
  41.139          switch (addr)
  41.140 @@ -76,7 +159,7 @@
  41.141                  svga->crtcreg = val & 0x7f;
  41.142                  return;
  41.143                  case 0x3d5:
  41.144 -//                        if (crtcreg == 0x67) pclog("Write CRTC R%02X %02X\n", crtcreg, val);
  41.145 +                //pclog("Write CRTC R%02X %02X\n", svga->crtcreg, val);
  41.146                  if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) 
  41.147                          return;
  41.148                  if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) 
  41.149 @@ -132,7 +215,8 @@
  41.150                          case 0x45:
  41.151                          svga->hwcursor.ena = val & 1;
  41.152                          break;
  41.153 -                        case 0x48:
  41.154 +                        case 0x46: case 0x47: case 0x48: case 0x49:
  41.155 +                        case 0x4c: case 0x4d: case 0x4e: case 0x4f:
  41.156                          svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff;
  41.157                          if (svga->bpp == 32) svga->hwcursor.x >>= 1;
  41.158                          svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff;
  41.159 @@ -151,8 +235,8 @@
  41.160                          {
  41.161                                  case 3:  svga->bpp = 15; break;
  41.162                                  case 5:  svga->bpp = 16; break;
  41.163 -                                case 7:  svga->bpp = 24; break;
  41.164 -                                case 13: svga->bpp = 32; break;
  41.165 +//                                case 7:  svga->bpp = 24; break;
  41.166 +                                case 13: svga->bpp = 24; break;
  41.167                                  default: svga->bpp = 8;  break;
  41.168                          }
  41.169                          break;
  41.170 @@ -172,7 +256,7 @@
  41.171          svga_out(addr, val, svga);
  41.172  }
  41.173  
  41.174 -uint8_t s3_virge_in(uint16_t addr, void *p)
  41.175 +static uint8_t s3_virge_in(uint16_t addr, void *p)
  41.176  {
  41.177          virge_t *virge = (virge_t *)p;
  41.178          svga_t *svga = &virge->svga;
  41.179 @@ -195,7 +279,7 @@
  41.180                  case 0x3D4:
  41.181                  return svga->crtcreg;
  41.182                  case 0x3D5:
  41.183 -//                pclog("Read CRTC R%02X %04X:%04X\n", crtcreg, CS, pc);
  41.184 +//                pclog("Read CRTC R%02X %04X:%04X (%02x)\n", svga->crtcreg, CS, pc, svga->crtc[svga->crtcreg]);
  41.185                  switch (svga->crtcreg)
  41.186                  {
  41.187                          case 0x2d: return virge->virge_id_high; /*Extended chip ID*/
  41.188 @@ -204,6 +288,7 @@
  41.189                          case 0x30: return virge->virge_id;      /*Chip ID*/
  41.190                          case 0x31: return (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4);
  41.191                          case 0x35: return (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf);
  41.192 +                        case 0x36: return (svga->crtc[0x36] & 0xfc) | 2; /*PCI bus*/
  41.193                          case 0x51: return (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3);
  41.194                          case 0x69: return virge->ma_ext;
  41.195                          case 0x6a: return virge->bank;
  41.196 @@ -213,7 +298,7 @@
  41.197          return svga_in(addr, svga);
  41.198  }
  41.199  
  41.200 -void s3_virge_recalctimings(svga_t *svga)
  41.201 +static void s3_virge_recalctimings(svga_t *svga)
  41.202  {
  41.203          virge_t *virge = (virge_t *)svga->p;
  41.204  //        pclog("recalctimings\n");
  41.205 @@ -252,20 +337,41 @@
  41.206          else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
  41.207          if (!svga->rowoffset) svga->rowoffset = 256;
  41.208          svga->interlace = svga->crtc[0x42] & 0x20;
  41.209 -        if (svga->bpp == 32)
  41.210 +//        pclog("svga->rowoffset = %i bpp=%i\n", svga->rowoffset, svga->bpp);
  41.211 +        if (svga->bpp == 15 || svga->bpp == 16)
  41.212 +        {
  41.213 +                svga->htotal >>= 1;
  41.214 +                svga->hdisp >>= 1;
  41.215 +        }
  41.216 +        if (svga->bpp == 24)
  41.217 +        {
  41.218 +                svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/
  41.219 +        }
  41.220 +
  41.221 +/*        if (svga->bpp == 32)
  41.222          {
  41.223                  svga->htotal <<= 2;
  41.224                  svga->hdisp <<= 2;
  41.225 -        }
  41.226 +        }*/
  41.227          //svga_clock = cpuclock / sdac_getclock((svga_miscout >> 2) & 3);
  41.228  //        pclog("SVGA_CLOCK = %f  %02X  %f\n", svga_clock, svga_miscout, cpuclock);
  41.229          //if (bpp > 8) svga_clock /= 2;
  41.230  }
  41.231  
  41.232 -void s3_virge_updatemapping(virge_t *virge)
  41.233 +static void s3_virge_updatemapping(virge_t *virge)
  41.234  {
  41.235          svga_t *svga = &virge->svga;
  41.236 -        
  41.237 +
  41.238 +        if (!(virge->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))
  41.239 +        {
  41.240 +//                pclog("Update mapping - PCI disabled\n");
  41.241 +                mem_mapping_disable(&svga->mapping);
  41.242 +                mem_mapping_disable(&virge->linear_mapping);
  41.243 +                mem_mapping_disable(&virge->mmio_mapping);
  41.244 +                mem_mapping_disable(&virge->new_mmio_mapping);
  41.245 +                return;
  41.246 +        }
  41.247 +
  41.248          pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc);        
  41.249          switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/
  41.250          {
  41.251 @@ -287,10 +393,11 @@
  41.252                  break;
  41.253          }
  41.254          
  41.255 +        virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
  41.256 +        
  41.257          pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10);
  41.258          if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/
  41.259          {
  41.260 -                virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
  41.261                  switch (svga->crtc[0x58] & 3)
  41.262                  {
  41.263                          case 0: /*64k*/
  41.264 @@ -315,13 +422,13 @@
  41.265                          mem_mapping_disable(&virge->linear_mapping);
  41.266                  }
  41.267                  else
  41.268 -                        mem_mapping_set_addr(&svga->mapping, virge->linear_base, virge->linear_size);
  41.269 +                        mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size);
  41.270          }
  41.271          else
  41.272                  mem_mapping_disable(&virge->linear_mapping);
  41.273          
  41.274          pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18);
  41.275 -        if ((svga->crtc[0x53] & 0x18) == 0x10) /*Memory mapped IO*/
  41.276 +        if (svga->crtc[0x53] & 0x10) /*Old MMIO*/
  41.277          {
  41.278                  if (svga->crtc[0x53] & 0x20)
  41.279                          mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000);
  41.280 @@ -330,47 +437,707 @@
  41.281          }
  41.282          else
  41.283                  mem_mapping_disable(&virge->mmio_mapping);
  41.284 +
  41.285 +        if (svga->crtc[0x53] & 0x08) /*New MMIO*/
  41.286 +                mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000);
  41.287 +        else
  41.288 +                mem_mapping_disable(&virge->new_mmio_mapping);
  41.289 +
  41.290  }
  41.291  
  41.292  
  41.293 -uint8_t s3_virge_mmio_read(uint32_t addr, void *p)
  41.294 +static uint8_t s3_virge_mmio_read(uint32_t addr, void *p)
  41.295  {
  41.296 -        pclog("MMIO readb %08X\n", addr);
  41.297 +//        pclog("MMIO readb %08X\n", addr);
  41.298          return 0xff;
  41.299  }
  41.300 -uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p)
  41.301 +static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p)
  41.302  {
  41.303 -        pclog("MMIO readw %08X\n", addr);
  41.304 +//        pclog("MMIO readw %08X\n", addr);
  41.305          return 0xffff;
  41.306  }
  41.307 -uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p)
  41.308 +static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p)
  41.309  {
  41.310 -        pclog("MMIO readl %08X\n", addr);
  41.311 +//        pclog("MMIO readl %08X\n", addr);
  41.312          return 0xffffffff;
  41.313  }
  41.314 -void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p)
  41.315 +static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p)
  41.316  {
  41.317 -        pclog("MMIO writeb %08X %02X\n", addr, val);
  41.318 +//        pclog("MMIO writeb %08X %02X\n", addr, val);
  41.319  }
  41.320 -void     s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
  41.321 +static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
  41.322  {
  41.323 -        pclog("MMIO writew %08X %04X\n", addr, val);
  41.324 +//        pclog("MMIO writew %08X %04X\n", addr, val);
  41.325  }
  41.326 -void     s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
  41.327 +static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
  41.328  {
  41.329 -        pclog("MMIO writel %08X %08X\n", addr, val);
  41.330 +//        pclog("MMIO writel %08X %08X\n", addr, val);
  41.331  }
  41.332  
  41.333 +static uint8_t s3_virge_new_mmio_read(uint32_t addr, void *p)
  41.334 +{
  41.335 +//        pclog("New MMIO readb %08X\n", addr);
  41.336 +        switch (addr & 0xffff)
  41.337 +        {
  41.338 +                case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3:
  41.339 +                case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7:
  41.340 +                case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb:
  41.341 +                case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf:
  41.342 +                case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3:
  41.343 +                case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7:
  41.344 +                case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb:
  41.345 +                case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf:
  41.346 +                case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3:
  41.347 +                case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7:
  41.348 +                case 0x83d8: case 0x83d9: case 0x83da: case 0x83db:
  41.349 +                case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
  41.350 +                return s3_virge_in(addr & 0x3ff, p);
  41.351 +        }
  41.352 +        return 0xff;
  41.353 +}
  41.354 +static uint16_t s3_virge_new_mmio_read_w(uint32_t addr, void *p)
  41.355 +{
  41.356 +//        pclog("New MMIO readw %08X\n", addr);
  41.357 +        switch (addr & 0xfffe)
  41.358 +        {
  41.359 +                default:
  41.360 +                return s3_virge_new_mmio_read(addr, p) | (s3_virge_new_mmio_read(addr + 1, p) << 8);
  41.361 +        }
  41.362 +        return 0xffff;
  41.363 +}
  41.364 +static uint32_t s3_virge_new_mmio_read_l(uint32_t addr, void *p)
  41.365 +{
  41.366 +        virge_t *virge = (virge_t *)p;
  41.367 +        uint32_t ret = 0xffffffff;
  41.368 +//        pclog("New MMIO readl %08X\n", addr);
  41.369 +        switch (addr & 0xfffc)
  41.370 +        {
  41.371 +                case 0x8504:
  41.372 +                ret = (0x1f << 8) | (1 << 13);
  41.373 +                break;
  41.374 +                case 0xa4d4:
  41.375 +                ret = virge->s3d.src_base;
  41.376 +                break;
  41.377 +                case 0xa4d8:
  41.378 +                ret = virge->s3d.dest_base;
  41.379 +                break;
  41.380 +                case 0xa4dc:
  41.381 +                ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r;
  41.382 +                break;
  41.383 +                case 0xa4e0:
  41.384 +                ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b;
  41.385 +                break;
  41.386 +                case 0xa4e4:
  41.387 +                ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str;
  41.388 +                break;
  41.389 +                case 0xa4e8:
  41.390 +                ret = virge->s3d.mono_pat_0;
  41.391 +                break;
  41.392 +                case 0xa4ec:
  41.393 +                ret = virge->s3d.mono_pat_1;
  41.394 +                break;
  41.395 +                case 0xa4f0:
  41.396 +                ret = virge->s3d.pat_bg_clr;
  41.397 +                break;
  41.398 +                case 0xa4f4:
  41.399 +                ret = virge->s3d.pat_fg_clr;
  41.400 +                break;
  41.401 +                case 0xa4f8:
  41.402 +                ret = virge->s3d.src_bg_clr;
  41.403 +                break;
  41.404 +                case 0xa4fc:
  41.405 +                ret = virge->s3d.src_fg_clr;
  41.406 +                break;
  41.407 +                case 0xa500:
  41.408 +                ret = virge->s3d.cmd_set;
  41.409 +                break;
  41.410 +                case 0xa504:
  41.411 +                ret = (virge->s3d.r_width << 16) | virge->s3d.r_height;
  41.412 +                break;
  41.413 +                case 0xa508:
  41.414 +                ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y;
  41.415 +                break;
  41.416 +                case 0xa50c:
  41.417 +                ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y;
  41.418 +                break;
  41.419 +                
  41.420 +                default:
  41.421 +                return s3_virge_new_mmio_read_w(addr, p) | (s3_virge_new_mmio_read_w(addr + 2, p) << 16);
  41.422 +        }
  41.423 +        return ret;
  41.424 +}
  41.425 +static void s3_virge_new_mmio_write(uint32_t addr, uint8_t val, void *p)
  41.426 +{
  41.427 +        virge_t *virge = (virge_t *)p;
  41.428 +        svga_t *svga = &virge->svga;
  41.429 +        
  41.430 +//        pclog("New MMIO writeb %08X %02X\n", addr, val);
  41.431 +        
  41.432 +        if ((addr & 0xfffc) < 0x8000)
  41.433 +                s3_virge_bitblt(virge, 8, val);
  41.434 +        else switch (addr & 0xffff)
  41.435 +        {
  41.436 +                case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3:
  41.437 +                case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7:
  41.438 +                case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb:
  41.439 +                case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf:
  41.440 +                case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3:
  41.441 +                case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7:
  41.442 +                case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb:
  41.443 +                case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf:
  41.444 +                case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3:
  41.445 +                case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7:
  41.446 +                case 0x83d8: case 0x83d9: case 0x83da: case 0x83db:
  41.447 +                case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
  41.448 +                s3_virge_out(addr & 0x3ff, val, p);
  41.449 +                break;
  41.450 +        }
  41.451  
  41.452 +                
  41.453 +}
  41.454 +static void s3_virge_new_mmio_write_w(uint32_t addr, uint16_t val, void *p)
  41.455 +{
  41.456 +        virge_t *virge = (virge_t *)p;
  41.457 +//        pclog("New MMIO writew %08X %04X\n", addr, val);
  41.458 +        if ((addr & 0xfffc) < 0x8000)
  41.459 +        {
  41.460 +                if (virge->s3d.cmd_set & CMD_SET_MS)
  41.461 +                        s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16);
  41.462 +                else
  41.463 +                        s3_virge_bitblt(virge, 16, val);
  41.464 +        } 
  41.465 +        else switch (addr & 0xfffe)
  41.466 +        {
  41.467 +                case 0x83d4:
  41.468 +                s3_virge_new_mmio_write(addr, val, p);
  41.469 +                s3_virge_new_mmio_write(addr + 1, val >> 8, p);
  41.470 +                break;
  41.471 +        }
  41.472 +}
  41.473 +static void s3_virge_new_mmio_write_l(uint32_t addr, uint32_t val, void *p)
  41.474 +{
  41.475 +        virge_t *virge = (virge_t *)p;
  41.476  
  41.477 -void s3_virge_hwcursor_draw(svga_t *svga, int displine)
  41.478 +//        if ((addr & 0xfffc) >= 0x8000)
  41.479 +//                pclog("New MMIO writel %08X %08X\n", addr, val);
  41.480 +
  41.481 +        if ((addr & 0xfffc) < 0x8000)
  41.482 +        {
  41.483 +                if (virge->s3d.cmd_set & CMD_SET_MS)
  41.484 +                        s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
  41.485 +                else
  41.486 +                        s3_virge_bitblt(virge, 32, val);
  41.487 +        }
  41.488 +        else switch (addr & 0xfffc)
  41.489 +        {
  41.490 +                case 0xa000: case 0xa004: case 0xa008: case 0xa00c:
  41.491 +                case 0xa010: case 0xa014: case 0xa018: case 0xa01c:
  41.492 +                case 0xa020: case 0xa024: case 0xa028: case 0xa02c:
  41.493 +                case 0xa030: case 0xa034: case 0xa038: case 0xa03c:
  41.494 +                case 0xa040: case 0xa044: case 0xa048: case 0xa04c:
  41.495 +                case 0xa050: case 0xa054: case 0xa058: case 0xa05c:
  41.496 +                case 0xa060: case 0xa064: case 0xa068: case 0xa06c:
  41.497 +                case 0xa070: case 0xa074: case 0xa078: case 0xa07c:
  41.498 +                case 0xa080: case 0xa084: case 0xa088: case 0xa08c:
  41.499 +                case 0xa090: case 0xa094: case 0xa098: case 0xa09c:
  41.500 +                case 0xa0a0: case 0xa0a4: case 0xa0a8: case 0xa0ac:
  41.501 +                case 0xa0b0: case 0xa0b4: case 0xa0b8: case 0xa0bc:
  41.502 +                case 0xa0c0: case 0xa0c4: case 0xa0c8: case 0xa0cc:
  41.503 +                case 0xa0d0: case 0xa0d4: case 0xa0d8: case 0xa0dc:
  41.504 +                case 0xa0e0: case 0xa0e4: case 0xa0e8: case 0xa0ec:
  41.505 +                case 0xa0f0: case 0xa0f4: case 0xa0f8: case 0xa0fc:
  41.506 +                case 0xa100: case 0xa104: case 0xa108: case 0xa10c:
  41.507 +                case 0xa110: case 0xa114: case 0xa118: case 0xa11c:
  41.508 +                case 0xa120: case 0xa124: case 0xa128: case 0xa12c:
  41.509 +                case 0xa130: case 0xa134: case 0xa138: case 0xa13c:
  41.510 +                case 0xa140: case 0xa144: case 0xa148: case 0xa14c:
  41.511 +                case 0xa150: case 0xa154: case 0xa158: case 0xa15c:
  41.512 +                case 0xa160: case 0xa164: case 0xa168: case 0xa16c:
  41.513 +                case 0xa170: case 0xa174: case 0xa178: case 0xa17c:
  41.514 +                case 0xa180: case 0xa184: case 0xa188: case 0xa18c:
  41.515 +                case 0xa190: case 0xa194: case 0xa198: case 0xa19c:
  41.516 +                case 0xa1a0: case 0xa1a4: case 0xa1a8: case 0xa1ac:
  41.517 +                case 0xa1b0: case 0xa1b4: case 0xa1b8: case 0xa1bc:
  41.518 +                case 0xa1c0: case 0xa1c4: case 0xa1c8: case 0xa1cc:
  41.519 +                case 0xa1d0: case 0xa1d4: case 0xa1d8: case 0xa1dc:
  41.520 +                case 0xa1e0: case 0xa1e4: case 0xa1e8: case 0xa1ec:
  41.521 +                case 0xa1f0: case 0xa1f4: case 0xa1f8: case 0xa1fc:
  41.522 +                {
  41.523 +                        int x = addr & 4;
  41.524 +                        int y = (addr >> 3) & 7;
  41.525 +                        virge->s3d.pattern_8[y*8 + x]     = val & 0xff;
  41.526 +                        virge->s3d.pattern_8[y*8 + x + 1] = val >> 8;
  41.527 +                        virge->s3d.pattern_8[y*8 + x + 2] = val >> 16;
  41.528 +                        virge->s3d.pattern_8[y*8 + x + 3] = val >> 24;
  41.529 +                        
  41.530 +                        x = (addr >> 1) & 6;
  41.531 +                        y = (addr >> 4) & 7;
  41.532 +                        virge->s3d.pattern_16[y*8 + x]     = val & 0xffff;
  41.533 +                        virge->s3d.pattern_16[y*8 + x + 1] = val >> 16;
  41.534 +
  41.535 +                        x = (addr >> 2) & 7;
  41.536 +                        y = (addr >> 5) & 7;
  41.537 +                        virge->s3d.pattern_32[y*8 + x] = val & 0xffffff;
  41.538 +                }
  41.539 +                break;
  41.540 +
  41.541 +
  41.542 +                case 0xa4d4: case 0xa8d4:
  41.543 +                virge->s3d.src_base = val & 0x3ffff8;
  41.544 +                break;
  41.545 +                case 0xa4d8: case 0xa8d8:
  41.546 +                virge->s3d.dest_base = val & 0x3ffff8;
  41.547 +                break;
  41.548 +                case 0xa4dc: case 0xa8dc:
  41.549 +                virge->s3d.clip_l = (val >> 16) & 0x7ff;
  41.550 +                virge->s3d.clip_r = val & 0x7ff;
  41.551 +                break;
  41.552 +                case 0xa4e0: case 0xa8e0:
  41.553 +                virge->s3d.clip_t = (val >> 16) & 0x7ff;
  41.554 +                virge->s3d.clip_b = val & 0x7ff;
  41.555 +                break;
  41.556 +                case 0xa4e4: case 0xa8e4:
  41.557 +                virge->s3d.dest_str = (val >> 16) & 0xff8;
  41.558 +                virge->s3d.src_str = val & 0xff8;
  41.559 +                break;
  41.560 +                case 0xa4e8:
  41.561 +                virge->s3d.mono_pat_0 = val;
  41.562 +                break;
  41.563 +                case 0xa4ec:
  41.564 +                virge->s3d.mono_pat_1 = val;
  41.565 +                break;
  41.566 +                case 0xa4f0:
  41.567 +                virge->s3d.pat_bg_clr = val;
  41.568 +                break;
  41.569 +                case 0xa4f4: case 0xa8f4:
  41.570 +                virge->s3d.pat_fg_clr = val;
  41.571 +                break;
  41.572 +                case 0xa4f8:
  41.573 +                virge->s3d.src_bg_clr = val;
  41.574 +                break;
  41.575 +                case 0xa4fc:
  41.576 +                virge->s3d.src_fg_clr = val;
  41.577 +                break;
  41.578 +                case 0xa500: case 0xa900:
  41.579 +                virge->s3d.cmd_set = val;
  41.580 +                if (!(val & CMD_SET_AE))
  41.581 +                        s3_virge_bitblt(virge, -1, 0);
  41.582 +                break;
  41.583 +                case 0xa504:
  41.584 +                virge->s3d.r_width = (val >> 16) & 0x7ff;
  41.585 +                virge->s3d.r_height = val & 0x7ff;
  41.586 +                break;
  41.587 +                case 0xa508:
  41.588 +                virge->s3d.rsrc_x = (val >> 16) & 0x7ff;
  41.589 +                virge->s3d.rsrc_y = val & 0x7ff;
  41.590 +                break;
  41.591 +                case 0xa50c:
  41.592 +                virge->s3d.rdest_x = (val >> 16) & 0x7ff;
  41.593 +                virge->s3d.rdest_y = val & 0x7ff;
  41.594 +                if (virge->s3d.cmd_set & CMD_SET_AE)
  41.595 +                        s3_virge_bitblt(virge, -1, 0);
  41.596 +                break;
  41.597 +                case 0xa96c:
  41.598 +                virge->s3d.lxend0 = (val >> 16) & 0x7ff;
  41.599 +                virge->s3d.lxend1 = val & 0x7ff;
  41.600 +                break;
  41.601 +                case 0xa970:
  41.602 +                virge->s3d.ldx = (int32_t)val;
  41.603 +                break;
  41.604 +                case 0xa974:
  41.605 +                virge->s3d.lxstart = val;
  41.606 +                break;
  41.607 +                case 0xa978:
  41.608 +                virge->s3d.lystart = val & 0x7ff;
  41.609 +                break;
  41.610 +                case 0xa97c:
  41.611 +                virge->s3d.lycnt = val & 0x7ff;
  41.612 +                virge->s3d.line_dir = val >> 31;
  41.613 +                if (virge->s3d.cmd_set & CMD_SET_AE)
  41.614 +                        s3_virge_bitblt(virge, -1, 0);
  41.615 +                break;
  41.616 +        }
  41.617 +}
  41.618 +
  41.619 +#define READ(addr, val)                                                                         \
  41.620 +        do                                                                                      \
  41.621 +        {                                                                                       \
  41.622 +                switch (bpp)                                                                    \
  41.623 +                {                                                                               \
  41.624 +                        case 0: /*8 bpp*/                                                       \
  41.625 +                        val = vram[addr & 0x3fffff];                                            \
  41.626 +                        break;                                                                  \
  41.627 +                        case 1: /*16 bpp*/                                                      \
  41.628 +                        val = *(uint16_t *)&vram[addr & 0x3fffff];                              \
  41.629 +                        break;                                                                  \
  41.630 +                        case 2: /*24 bpp*/                                                      \
  41.631 +                        val = (*(uint32_t *)&vram[addr & 0x3fffff]) & 0xffffff;                 \
  41.632 +                        break;                                                                  \
  41.633 +                }                                                                               \
  41.634 +        } while (0)
  41.635 +
  41.636 +#define CLIP(x, y)                                              \
  41.637 +        do                                                      \
  41.638 +        {                                                       \
  41.639 +                if ((virge->s3d.cmd_set & CMD_SET_HC) &&        \
  41.640 +                    (x < virge->s3d.clip_l ||                   \
  41.641 +                     x > virge->s3d.clip_r ||                   \
  41.642 +                     y < virge->s3d.clip_t ||                   \
  41.643 +                     y > virge->s3d.clip_b))                    \
  41.644 +                        update = 0;                             \
  41.645 +        } while (0)
  41.646 +
  41.647 +#define MIX()                                                   \
  41.648 +        do                                                      \
  41.649 +        {                                                       \
  41.650 +                int c;                                          \
  41.651 +                for (c = 0; c < 24; c++)                        \
  41.652 +                {                                               \
  41.653 +                        int d = (dest & (1 << c)) ? 1 : 0;      \
  41.654 +                        if (source & (1 << c))  d |= 2;         \
  41.655 +                        if (pattern & (1 << c)) d |= 4;         \
  41.656 +                        if (virge->s3d.rop & (1 << d)) out |= (1 << c);    \
  41.657 +                }                                               \
  41.658 +        } while (0)
  41.659 +
  41.660 +#define WRITE(addr, val)                                                                        \
  41.661 +        do                                                                                      \
  41.662 +        {                                                                                       \
  41.663 +                switch (bpp)                                                                    \
  41.664 +                {                                                                               \
  41.665 +                        case 0: /*8 bpp*/                                                       \
  41.666 +                        vram[addr & 0x3fffff] = val;                                            \
  41.667 +                        virge->svga.changedvram[(addr & 0x3fffff) >> 10] = changeframecount;    \
  41.668 +                        break;                                                                  \
  41.669 +                        case 1: /*16 bpp*/                                                      \
  41.670 +                        *(uint16_t *)&vram[addr & 0x3fffff] = val;                              \
  41.671 +                        virge->svga.changedvram[(addr & 0x3fffff) >> 10] = changeframecount;    \
  41.672 +                        break;                                                                  \
  41.673 +                        case 2: /*24 bpp*/                                                      \
  41.674 +                        *(uint32_t *)&vram[addr & 0x3fffff] = (val & 0xffffff) |                \
  41.675 +                                                              (vram[(addr + 3) & 0x3fffff] << 24);  \
  41.676 +                        virge->svga.changedvram[(addr & 0x3fffff) >> 10] = changeframecount;    \
  41.677 +                        break;                                                                  \
  41.678 +                }                                                                               \
  41.679 +        } while (0)
  41.680 +
  41.681 +static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
  41.682 +{
  41.683 +        int cpu_input = (count != -1);
  41.684 +        uint8_t *vram = virge->svga.vram;
  41.685 +        uint32_t mono_pattern[64];
  41.686 +        int count_mask;
  41.687 +        int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1;
  41.688 +        int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1;
  41.689 +        int bpp;
  41.690 +        int x_mul;
  41.691 +        int cpu_dat_shift;
  41.692 +        uint32_t *pattern_data;
  41.693 +        
  41.694 +        switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK)
  41.695 +        {
  41.696 +                case CMD_SET_FORMAT_8:
  41.697 +                bpp = 0;
  41.698 +                x_mul = 1;
  41.699 +                cpu_dat_shift = 8;
  41.700 +                pattern_data = virge->s3d.pattern_8;
  41.701 +                break;
  41.702 +                case CMD_SET_FORMAT_16:
  41.703 +                bpp = 1;
  41.704 +                x_mul = 2;
  41.705 +                cpu_dat_shift = 16;
  41.706 +                pattern_data = virge->s3d.pattern_16;
  41.707 +                break;
  41.708 +                case CMD_SET_FORMAT_24:
  41.709 +                default:
  41.710 +                bpp = 2;
  41.711 +                x_mul = 3;
  41.712 +                cpu_dat_shift = 24;
  41.713 +                pattern_data = virge->s3d.pattern_32;
  41.714 +                break;
  41.715 +        }
  41.716 +        if (virge->s3d.cmd_set & CMD_SET_MP)
  41.717 +                pattern_data = mono_pattern;
  41.718 +        
  41.719 +        switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK)
  41.720 +        {
  41.721 +                case CMD_SET_ITA_BYTE:
  41.722 +                count_mask = ~0x7;
  41.723 +                break;
  41.724 +                case CMD_SET_ITA_WORD:
  41.725 +                count_mask = ~0xf;
  41.726 +                break;
  41.727 +                case CMD_SET_ITA_DWORD:
  41.728 +                default:
  41.729 +                count_mask = ~0x1f;
  41.730 +                break;
  41.731 +        }
  41.732 +        if (virge->s3d.cmd_set & CMD_SET_MP)
  41.733 +        {
  41.734 +                int x, y;
  41.735 +                for (y = 0; y < 4; y++)
  41.736 +                {
  41.737 +                        for (x = 0; x < 8; x++)
  41.738 +                        {
  41.739 +                                if (virge->s3d.mono_pat_0 & (1 << (x + y*8)))
  41.740 +                                        mono_pattern[y*8 + x] = virge->s3d.pat_fg_clr;
  41.741 +                                else
  41.742 +                                        mono_pattern[y*8 + x] = virge->s3d.pat_bg_clr;
  41.743 +                                if (virge->s3d.mono_pat_1 & (1 << (x + y*8)))
  41.744 +                                        mono_pattern[(y+4)*8 + x] = virge->s3d.pat_fg_clr;
  41.745 +                                else
  41.746 +                                        mono_pattern[(y+4)*8 + x] = virge->s3d.pat_bg_clr;
  41.747 +                        }
  41.748 +                }
  41.749 +        }
  41.750 +        switch (virge->s3d.cmd_set & CMD_SET_COMMAND_MASK)
  41.751 +        {
  41.752 +                case CMD_SET_COMMAND_NOP:
  41.753 +                break;
  41.754 +                
  41.755 +                case CMD_SET_COMMAND_BITBLT:
  41.756 +                if (count == -1)
  41.757 +                {
  41.758 +                        virge->s3d.src_x = virge->s3d.rsrc_x;
  41.759 +                        virge->s3d.src_y = virge->s3d.rsrc_y;
  41.760 +                        virge->s3d.dest_x = virge->s3d.rdest_x;
  41.761 +                        virge->s3d.dest_y = virge->s3d.rdest_y;
  41.762 +                        virge->s3d.w = virge->s3d.r_width;
  41.763 +                        virge->s3d.h = virge->s3d.r_height;
  41.764 +                        virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff;
  41.765 +                        virge->s3d.data_left_count = 0;
  41.766 +                        
  41.767 +  /*                      pclog("BitBlt start %i,%i %i,%i %02X\n", virge->s3d.dest_x,
  41.768 +                                                                 virge->s3d.dest_y,
  41.769 +                                                                 virge->s3d.w,
  41.770 +                                                                 virge->s3d.h,
  41.771 +                                                                 virge->s3d.rop);*/
  41.772 +                        
  41.773 +                        if (virge->s3d.cmd_set & CMD_SET_IDS)
  41.774 +                                return;
  41.775 +                }
  41.776 +                if (!virge->s3d.h)
  41.777 +                        return;
  41.778 +                while (count)
  41.779 +                {
  41.780 +                        uint32_t src_addr = virge->s3d.src_base + (virge->s3d.src_x * x_mul) + (virge->s3d.src_y * virge->s3d.src_str);
  41.781 +                        uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str);
  41.782 +                        uint32_t source, dest, pattern;
  41.783 +                        uint32_t out = 0;
  41.784 +                        int update = 1;
  41.785 +
  41.786 +                        switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS))
  41.787 +                        {
  41.788 +                                case 0:
  41.789 +                                case CMD_SET_MS:
  41.790 +                                READ(src_addr, source);
  41.791 +                                break;
  41.792 +                                case CMD_SET_IDS:
  41.793 +                                if (virge->s3d.data_left_count)
  41.794 +                                {
  41.795 +                                        /*Handle shifting for 24-bit data*/
  41.796 +                                        source = virge->s3d.data_left;
  41.797 +                                        source |= ((cpu_dat << virge->s3d.data_left_count) & ~0xff000000);
  41.798 +                                        cpu_dat >>= (cpu_dat_shift - virge->s3d.data_left_count);
  41.799 +                                        count -= (cpu_dat_shift - virge->s3d.data_left_count);
  41.800 +                                        virge->s3d.data_left_count = 0;
  41.801 +                                        if (count < cpu_dat_shift)
  41.802 +                                        {
  41.803 +                                                virge->s3d.data_left = cpu_dat;
  41.804 +                                                virge->s3d.data_left_count = count;
  41.805 +                                                count = 0;
  41.806 +                                        }
  41.807 +                                }
  41.808 +                                else
  41.809 +                                {
  41.810 +                                        source = cpu_dat;
  41.811 +                                        cpu_dat >>= cpu_dat_shift;
  41.812 +                                        count -= cpu_dat_shift;
  41.813 +                                        if (count < cpu_dat_shift)
  41.814 +                                        {
  41.815 +                                                virge->s3d.data_left = cpu_dat;
  41.816 +                                                virge->s3d.data_left_count = count;
  41.817 +                                                count = 0;
  41.818 +                                        }
  41.819 +                                }
  41.820 +                                break;
  41.821 +                                case CMD_SET_IDS | CMD_SET_MS:
  41.822 +                                source = (cpu_dat & (1 << 31)) ? virge->s3d.src_fg_clr : virge->s3d.src_bg_clr;
  41.823 +                                if ((virge->s3d.cmd_set & CMD_SET_TP) && !(cpu_dat & (1 << 31)))
  41.824 +                                        update = 0;
  41.825 +                                cpu_dat <<= 1;
  41.826 +                                count--;
  41.827 +                                break;
  41.828 +                        }
  41.829 +
  41.830 +                        CLIP(virge->s3d.dest_x, virge->s3d.dest_y);
  41.831 +
  41.832 +                        if (update)
  41.833 +                        {
  41.834 +                                READ(dest_addr, dest);
  41.835 +                                pattern = pattern_data[(virge->s3d.dest_y & 7)*8 + (virge->s3d.dest_x & 7)];
  41.836 +                                MIX();
  41.837 +
  41.838 +                                WRITE(dest_addr, out);
  41.839 +                        }
  41.840 +                
  41.841 +                        virge->s3d.src_x += x_inc;
  41.842 +                        virge->s3d.dest_x += x_inc;
  41.843 +                        if (!virge->s3d.w)
  41.844 +                        {
  41.845 +                                virge->s3d.src_x = virge->s3d.rsrc_x;
  41.846 +                                virge->s3d.dest_x = virge->s3d.rdest_x;
  41.847 +                                virge->s3d.w = virge->s3d.r_width;
  41.848 +
  41.849 +                                virge->s3d.src_y += y_inc;
  41.850 +                                virge->s3d.dest_y += y_inc;
  41.851 +                                virge->s3d.h--;
  41.852 +                                
  41.853 +                                switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS))
  41.854 +                                {
  41.855 +                                        case CMD_SET_IDS:
  41.856 +                                        cpu_dat >>= (count - (count & count_mask));
  41.857 +                                        count &= count_mask;
  41.858 +                                        virge->s3d.data_left_count = 0;
  41.859 +                                        break;
  41.860 +
  41.861 +                                        case CMD_SET_IDS | CMD_SET_MS:
  41.862 +                                        cpu_dat <<= (count - (count & count_mask));
  41.863 +                                        count &= count_mask;
  41.864 +                                        break;
  41.865 +                                }
  41.866 +                                if (!virge->s3d.h)
  41.867 +                                {
  41.868 +                                        return;
  41.869 +                                }
  41.870 +                        }
  41.871 +                        else
  41.872 +                                virge->s3d.w--;                        
  41.873 +                }
  41.874 +                break;
  41.875 +                
  41.876 +                case CMD_SET_COMMAND_RECTFILL:
  41.877 +                /*No source, pattern = pat_fg_clr*/
  41.878 +                if (count == -1)
  41.879 +                {
  41.880 +                        virge->s3d.src_x = virge->s3d.rsrc_x;
  41.881 +                        virge->s3d.src_y = virge->s3d.rsrc_y;
  41.882 +                        virge->s3d.dest_x = virge->s3d.rdest_x;
  41.883 +                        virge->s3d.dest_y = virge->s3d.rdest_y;
  41.884 +                        virge->s3d.w = virge->s3d.r_width;
  41.885 +                        virge->s3d.h = virge->s3d.r_height;
  41.886 +                        virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff;
  41.887 +                        
  41.888 +/*                        pclog("RctFll start %i,%i %i,%i %02X\n", virge->s3d.dest_x,
  41.889 +                                                                 virge->s3d.dest_y,
  41.890 +                                                                 virge->s3d.w,
  41.891 +                                                                 virge->s3d.h,
  41.892 +                                                                 virge->s3d.rop);*/
  41.893 +                }
  41.894 +
  41.895 +                while (count)
  41.896 +                {
  41.897 +                        uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str);
  41.898 +                        uint32_t source = 0, dest, pattern = virge->s3d.pat_fg_clr;
  41.899 +                        uint32_t out = 0;
  41.900 +                        int update = 1;
  41.901 +
  41.902 +                        CLIP(virge->s3d.dest_x, virge->s3d.dest_y);
  41.903 +
  41.904 +                        if (update)
  41.905 +                        {
  41.906 +                                READ(dest_addr, dest);
  41.907 +
  41.908 +                                MIX();
  41.909 +
  41.910 +                                WRITE(dest_addr, out);
  41.911 +                        }
  41.912 +
  41.913 +                        virge->s3d.src_x += x_inc;
  41.914 +                        virge->s3d.dest_x += x_inc;
  41.915 +                        if (!virge->s3d.w)
  41.916 +                        {
  41.917 +                                virge->s3d.src_x = virge->s3d.rsrc_x;
  41.918 +                                virge->s3d.dest_x = virge->s3d.rdest_x;
  41.919 +                                virge->s3d.w = virge->s3d.r_width;
  41.920 +
  41.921 +                                virge->s3d.src_y += y_inc;
  41.922 +                                virge->s3d.dest_y += y_inc;
  41.923 +                                virge->s3d.h--;
  41.924 +                                if (!virge->s3d.h)
  41.925 +                                {
  41.926 +                                        return;
  41.927 +                                }
  41.928 +                        }
  41.929 +                        else
  41.930 +                                virge->s3d.w--;                        
  41.931 +                        count--;
  41.932 +                }
  41.933 +                break;
  41.934 +                
  41.935 +                case CMD_SET_COMMAND_LINE:
  41.936 +                if (count == -1)
  41.937 +                {
  41.938 +                        virge->s3d.dest_x = virge->s3d.lxstart;
  41.939 +                        virge->s3d.dest_y = virge->s3d.lystart;
  41.940 +                        virge->s3d.h = virge->s3d.lycnt;
  41.941 +                        virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff;
  41.942 +                        if (virge->s3d.ldx >= 0)
  41.943 +                                virge->s3d.dest_x -= virge->s3d.ldx / 2;
  41.944 +                        else
  41.945 +                                virge->s3d.dest_x += virge->s3d.ldx / 2;
  41.946 +                        //virge->s3d.dest_dest_x = virge->s3d.dest_x + virge->s3d.ldx;
  41.947 +                }
  41.948 +                while (virge->s3d.h)
  41.949 +                {
  41.950 +                        int x = virge->s3d.dest_x >> 20;
  41.951 +                        int new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20;
  41.952 +                        
  41.953 +                        do
  41.954 +                        {
  41.955 +                                uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str);
  41.956 +                                uint32_t source = 0, dest, pattern;
  41.957 +                                uint32_t out = 0;
  41.958 +                                int update = 1;
  41.959 +
  41.960 +                                CLIP(x, virge->s3d.dest_y);
  41.961 +
  41.962 +                                if (update)
  41.963 +                                {
  41.964 +                                        READ(dest_addr, dest);
  41.965 +                                        pattern = virge->s3d.pat_fg_clr;
  41.966 +
  41.967 +                                        MIX();
  41.968 +
  41.969 +                                        WRITE(dest_addr, out);
  41.970 +                                }
  41.971 +                                
  41.972 +                                if (x < new_x)
  41.973 +                                        x++;
  41.974 +                                else if (x > new_x)
  41.975 +                                        x--;
  41.976 +                        } while (x != new_x);
  41.977 +
  41.978 +                        virge->s3d.dest_x += virge->s3d.ldx;
  41.979 +                        virge->s3d.dest_y--;
  41.980 +                        virge->s3d.h--;
  41.981 +                }
  41.982 +                break;
  41.983 +
  41.984 +                default:
  41.985 +                fatal("s3_virge_bitblt : blit command %i %08x\n", (virge->s3d.cmd_set >> 27) & 0xf, virge->s3d.cmd_set);
  41.986 +        }
  41.987 +}
  41.988 +
  41.989 +
  41.990 +static void s3_virge_hwcursor_draw(svga_t *svga, int displine)
  41.991  {
  41.992          int x;
  41.993          uint16_t dat[2];
  41.994          int xx;
  41.995          int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
  41.996          
  41.997 -        pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y);
  41.998 +//        pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y);
  41.999          for (x = 0; x < 64; x += 16)
 41.1000          {
 41.1001                  dat[0] = (svga->vram[svga->hwcursor_latch.addr]     << 8) | svga->vram[svga->hwcursor_latch.addr + 1];
 41.1002 @@ -394,72 +1161,150 @@
 41.1003          }
 41.1004  }
 41.1005  
 41.1006 -
 41.1007 -uint8_t s3_virge_pci_read(int func, int addr, void *p)
 41.1008 +static uint8_t s3_virge_pci_read(int func, int addr, void *p)
 41.1009  {
 41.1010          virge_t *virge = (virge_t *)p;
 41.1011          svga_t *svga = &virge->svga;
 41.1012 -//        pclog("S3 PCI read %08X\n", addr);
 41.1013 +        uint8_t ret = 0;
 41.1014 +//        pclog("S3 PCI read %08X  ", addr);
 41.1015          switch (addr)
 41.1016          {
 41.1017 -                case 0x00: return 0x33; /*'S3'*/
 41.1018 -                case 0x01: return 0x53;
 41.1019 +                case 0x00: ret = 0x33; break; /*'S3'*/
 41.1020 +                case 0x01: ret = 0x53; break;
 41.1021                  
 41.1022 -                case 0x02: return virge->virge_id_low;
 41.1023 -                case 0x03: return virge->virge_id_high;
 41.1024 +                case 0x02: ret = virge->virge_id_low; break;
 41.1025 +                case 0x03: ret = virge->virge_id_high; break;
 41.1026 +
 41.1027 +                case 0x04: ret = virge->pci_regs[0x04] & 0x27; break;
 41.1028                  
 41.1029 -                case 0x08: return 0; /*Revision ID*/
 41.1030 -                case 0x09: return 0; /*Programming interface*/
 41.1031 +                case 0x07: ret = virge->pci_regs[0x07] & 0x36; break;
 41.1032 +                                
 41.1033 +                case 0x08: ret = 0; break; /*Revision ID*/
 41.1034 +                case 0x09: ret = 0; break; /*Programming interface*/
 41.1035                  
 41.1036 -                case 0x0a: return 0x00; /*Supports VGA interface*/
 41.1037 -                case 0x0b: return 0x03;
 41.1038 +                case 0x0a: ret = 0x00; break; /*Supports VGA interface*/
 41.1039 +                case 0x0b: ret = 0x03; /*output = 3; */break;
 41.1040 +
 41.1041 +                case 0x0d: ret = virge->pci_regs[0x0d] & 0xf8; break;
 41.1042 +                                
 41.1043 +                case 0x10: ret = 0x00; break;/*Linear frame buffer address*/
 41.1044 +                case 0x11: ret = 0x00; break;
 41.1045 +                case 0x12: ret = 0x00; break;
 41.1046 +                case 0x13: ret = svga->crtc[0x59] & 0xfc; break;
 41.1047 +
 41.1048 +                case 0x30: ret = virge->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/
 41.1049 +                case 0x31: ret = 0x00; break;
 41.1050 +                case 0x32: ret = virge->pci_regs[0x32]; break;
 41.1051 +                case 0x33: ret = virge->pci_regs[0x33]; break;
 41.1052 +
 41.1053 +                case 0x3c: ret = virge->pci_regs[0x3c]; break;
 41.1054 +                                
 41.1055 +                case 0x3d: ret = 0x01; break; /*INTA*/
 41.1056                  
 41.1057 -                case 0x10: return 0x00; /*Linear frame buffer address*/
 41.1058 -                case 0x11: return 0x00;
 41.1059 -                case 0x12: return 0x00;
 41.1060 -                case 0x13: return svga->crtc[0x59] & 0xfc;
 41.1061 -
 41.1062 -                case 0x30: return 0x01; /*BIOS ROM address*/
 41.1063 -                case 0x31: return 0x00;
 41.1064 -                case 0x32: return 0x0C;
 41.1065 -                case 0x33: return 0x00;
 41.1066 +                case 0x3e: ret = 0x04; break;
 41.1067 +                case 0x3f: ret = 0xff; break;
 41.1068                  
 41.1069          }
 41.1070 -        return virge->pci_regs[addr];
 41.1071 +//        pclog("%02X\n", ret);
 41.1072 +        return ret;
 41.1073  }
 41.1074  
 41.1075 -void s3_virge_pci_write(int func, int addr, uint8_t val, void *p)
 41.1076 +static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p)
 41.1077  {
 41.1078          virge_t *virge = (virge_t *)p;
 41.1079          svga_t *svga = &virge->svga;
 41.1080 -
 41.1081 +//        pclog("S3 PCI write %08X %02X %04X:%08X\n", addr, val, CS, pc);
 41.1082          switch (addr)
 41.1083          {
 41.1084                  case 0x00: case 0x01: case 0x02: case 0x03:
 41.1085                  case 0x08: case 0x09: case 0x0a: case 0x0b:
 41.1086                  case 0x3d: case 0x3e: case 0x3f:
 41.1087 -                break;
 41.1088 +                return;
 41.1089 +                
 41.1090 +                case PCI_REG_COMMAND:
 41.1091 +                if (val & PCI_COMMAND_IO)
 41.1092 +                {
 41.1093 +                        io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
 41.1094 +                        io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
 41.1095 +                }
 41.1096 +                else
 41.1097 +                        io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
 41.1098 +                virge->pci_regs[PCI_REG_COMMAND] = val & 0x27;
 41.1099 +                return;
 41.1100 +                case 0x07:
 41.1101 +                virge->pci_regs[0x07] = val & 0x3e;
 41.1102 +                return;
 41.1103 +                case 0x0d: 
 41.1104 +                virge->pci_regs[0x0d] = val & 0xf8;
 41.1105 +                return;
 41.1106                  
 41.1107                  case 0x13: 
 41.1108                  svga->crtc[0x59] = val & 0xfc; 
 41.1109                  s3_virge_updatemapping(virge); 
 41.1110 -                break;
 41.1111 +                return;
 41.1112 +
 41.1113 +                case 0x30: case 0x32: case 0x33:
 41.1114 +                virge->pci_regs[addr] = val;
 41.1115 +                if (virge->pci_regs[0x30] & 0x01)
 41.1116 +                {
 41.1117 +                        uint32_t addr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24);
 41.1118 +                        pclog("Virge bios_rom enabled at %08x\n", addr);
 41.1119 +                        mem_mapping_set_addr(&virge->bios_rom.mapping, addr, 0x8000);
 41.1120 +                        mem_mapping_enable(&virge->bios_rom.mapping);
 41.1121 +                }
 41.1122 +                else
 41.1123 +                {
 41.1124 +                        pclog("Virge bios_rom disabled\n");
 41.1125 +                        mem_mapping_disable(&virge->bios_rom.mapping);
 41.1126 +                }
 41.1127 +                return;
 41.1128 +                case 0x3c: 
 41.1129 +                virge->pci_regs[0x3c] = val;
 41.1130 +                return;
 41.1131          }
 41.1132 -        virge->pci_regs[addr] = val;
 41.1133  }
 41.1134  
 41.1135 -void *s3_virge_init()
 41.1136 +static void *s3_virge_init()
 41.1137  {
 41.1138          virge_t *virge = malloc(sizeof(virge_t));
 41.1139          memset(virge, 0, sizeof(virge_t));
 41.1140 -
 41.1141 +        
 41.1142          svga_init(&virge->svga, virge, 1 << 22, /*4mb*/
 41.1143                     s3_virge_recalctimings,
 41.1144                     s3_virge_in, s3_virge_out,
 41.1145                     s3_virge_hwcursor_draw);
 41.1146  
 41.1147 -        mem_mapping_add(&virge->mmio_mapping,   0, 0, 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);
 41.1148 -        mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &virge->svga);
 41.1149 +        rom_init(&virge->bios_rom, "roms/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
 41.1150 +        if (PCI)
 41.1151 +                mem_mapping_disable(&virge->bios_rom.mapping);
 41.1152 +
 41.1153 +        mem_mapping_add(&virge->mmio_mapping,     0, 0, s3_virge_mmio_read,
 41.1154 +                                                        s3_virge_mmio_read_w,
 41.1155 +                                                        s3_virge_mmio_read_l,
 41.1156 +                                                        s3_virge_mmio_write,
 41.1157 +                                                        s3_virge_mmio_write_w,
 41.1158 +                                                        s3_virge_mmio_write_l,
 41.1159 +                                                        NULL,
 41.1160 +                                                        0,
 41.1161 +                                                        virge);
 41.1162 +        mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_new_mmio_read,
 41.1163 +                                                        s3_virge_new_mmio_read_w,
 41.1164 +                                                        s3_virge_new_mmio_read_l,
 41.1165 +                                                        s3_virge_new_mmio_write,
 41.1166 +                                                        s3_virge_new_mmio_write_w,
 41.1167 +                                                        s3_virge_new_mmio_write_l,
 41.1168 +                                                        NULL,
 41.1169 +                                                        0,
 41.1170 +                                                        virge);
 41.1171 +        mem_mapping_add(&virge->linear_mapping,   0, 0, svga_read_linear,
 41.1172 +                                                        svga_readw_linear,
 41.1173 +                                                        svga_readl_linear,
 41.1174 +                                                        svga_write_linear,
 41.1175 +                                                        svga_writew_linear,
 41.1176 +                                                        svga_writel_linear,
 41.1177 +                                                        NULL,
 41.1178 +                                                        0,
 41.1179 +                                                        &virge->svga);
 41.1180  
 41.1181          io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
 41.1182  
 41.1183 @@ -467,6 +1312,7 @@
 41.1184          virge->pci_regs[5] = 0;        
 41.1185          virge->pci_regs[6] = 0;
 41.1186          virge->pci_regs[7] = 2;
 41.1187 +        virge->pci_regs[0x32] = 0x0c;
 41.1188          virge->pci_regs[0x3d] = 1; 
 41.1189          virge->pci_regs[0x3e] = 4;
 41.1190          virge->pci_regs[0x3f] = 0xff;
 41.1191 @@ -476,15 +1322,17 @@
 41.1192          virge->virge_rev = 0;
 41.1193          virge->virge_id = 0xe1;
 41.1194  
 41.1195 -        virge->svga.crtc[0x36] = 1 | (2 << 2) | (1 << 4) | (4 << 5);
 41.1196 -        virge->svga.crtc[0x37] = 1 | (7 << 5);
 41.1197 +        virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4);
 41.1198 +        virge->svga.crtc[0x37] = 1;// | (7 << 5);
 41.1199 +        virge->svga.crtc[0x53] = 1 << 3;
 41.1200 +        virge->svga.crtc[0x59] = 0x70;
 41.1201          
 41.1202          pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
 41.1203   
 41.1204          return virge;
 41.1205  }
 41.1206  
 41.1207 -void s3_virge_close(void *p)
 41.1208 +static void s3_virge_close(void *p)
 41.1209  {
 41.1210          virge_t *virge = (virge_t *)p;
 41.1211  
 41.1212 @@ -493,21 +1341,26 @@
 41.1213          free(virge);
 41.1214  }
 41.1215  
 41.1216 -void s3_virge_speed_changed(void *p)
 41.1217 +static int s3_virge_available()
 41.1218 +{
 41.1219 +        return rom_present("roms/s3virge.bin");
 41.1220 +}
 41.1221 +
 41.1222 +static void s3_virge_speed_changed(void *p)
 41.1223  {
 41.1224          virge_t *virge = (virge_t *)p;
 41.1225          
 41.1226          svga_recalctimings(&virge->svga);
 41.1227  }
 41.1228  
 41.1229 -void s3_virge_force_redraw(void *p)
 41.1230 +static void s3_virge_force_redraw(void *p)
 41.1231  {
 41.1232          virge_t *virge = (virge_t *)p;
 41.1233  
 41.1234          virge->svga.fullchange = changeframecount;
 41.1235  }
 41.1236  
 41.1237 -int s3_virge_add_status_info(char *s, int max_len, void *p)
 41.1238 +static int s3_virge_add_status_info(char *s, int max_len, void *p)
 41.1239  {
 41.1240          virge_t *virge = (virge_t *)p;
 41.1241          
 41.1242 @@ -520,7 +1373,7 @@
 41.1243          DEVICE_NOT_WORKING,
 41.1244          s3_virge_init,
 41.1245          s3_virge_close,
 41.1246 -        NULL,
 41.1247 +        s3_virge_available,
 41.1248          s3_virge_speed_changed,
 41.1249          s3_virge_force_redraw,
 41.1250          s3_virge_add_status_info
    42.1 --- a/src/vid_svga.c	Sun Mar 09 11:24:58 2014 +0000
    42.2 +++ b/src/vid_svga.c	Thu Mar 20 14:03:55 2014 +0000
    42.3 @@ -641,7 +641,7 @@
    42.4          svga->hwcursor_draw = hwcursor_draw;
    42.5  //        _svga_recalctimings(svga);
    42.6  
    42.7 -        mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, svga);
    42.8 +        mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, 0, svga);
    42.9  
   42.10          timer_add(svga_poll, &svga->vidtime, TIMER_ALWAYS_ENABLED, svga);
   42.11          vramp = svga->vram;
    43.1 --- a/src/vid_tandy.c	Sun Mar 09 11:24:58 2014 +0000
    43.2 +++ b/src/vid_tandy.c	Thu Mar 20 14:03:55 2014 +0000
    43.3 @@ -667,7 +667,7 @@
    43.4                  q_filt[c] = 512.0 * sin((3.14 * (tandy_tint + c * 4) / 16.0) - 33.0 / 180.0);
    43.5          }
    43.6          timer_add(tandy_poll, &tandy->vidtime, TIMER_ALWAYS_ENABLED, tandy);
    43.7 -        mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL,  tandy);
    43.8 +        mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL,  NULL, 0, tandy);
    43.9          io_sethandler(0x03d0, 0x0010, tandy_in, NULL, NULL, tandy_out, NULL, NULL, tandy);
   43.10          io_sethandler(0x00a0, 0x0001, tandy_in, NULL, NULL, tandy_out, NULL, NULL, tandy);
   43.11          return tandy;
    44.1 --- a/src/vid_tgui9440.c	Sun Mar 09 11:24:58 2014 +0000
    44.2 +++ b/src/vid_tgui9440.c	Thu Mar 20 14:03:55 2014 +0000
    44.3 @@ -4,6 +4,7 @@
    44.4  #include "device.h"
    44.5  #include "io.h"
    44.6  #include "mem.h"
    44.7 +#include "rom.h"
    44.8  #include "video.h"
    44.9  #include "vid_svga.h"
   44.10  #include "vid_svga_render.h"
   44.11 @@ -15,6 +16,8 @@
   44.12          mem_mapping_t linear_mapping;
   44.13          mem_mapping_t accel_mapping;
   44.14  
   44.15 +        rom_t bios_rom;
   44.16 +        
   44.17          svga_t svga;
   44.18  
   44.19          struct
   44.20 @@ -462,37 +465,20 @@
   44.21          }
   44.22  }
   44.23  
   44.24 -void *tgui8900d_init()
   44.25 -{
   44.26 -        tgui_t *tgui = malloc(sizeof(tgui_t));
   44.27 -        memset(tgui, 0, sizeof(tgui_t));
   44.28 -        
   44.29 -        svga_init(&tgui->svga, tgui, 1 << 20, /*1mb - chip supports 2mb, but drivers are buggy*/
   44.30 -                   tgui_recalctimings,
   44.31 -                   tgui_in, tgui_out,
   44.32 -                   NULL);
   44.33 -
   44.34 -        mem_mapping_add(&tgui->linear_mapping, 0,       0,      svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &tgui->svga);
   44.35 -        mem_mapping_add(&tgui->accel_mapping,  0xbc000, 0x4000, tgui_accel_read,  tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write,  tgui_accel_write_w, tgui_accel_write_l,  tgui);
   44.36 -        mem_mapping_disable(&tgui->linear_mapping);
   44.37 -        mem_mapping_disable(&tgui->accel_mapping);
   44.38 -        
   44.39 -        io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui);
   44.40 -
   44.41 -        return tgui;
   44.42 -}
   44.43  void *tgui9440_init()
   44.44  {
   44.45          tgui_t *tgui = malloc(sizeof(tgui_t));
   44.46          memset(tgui, 0, sizeof(tgui_t));
   44.47          
   44.48 +        rom_init(&tgui->bios_rom, "roms/9440.vbi", 0xc0000, 0x8000, 0x7fff, 0, 0);
   44.49 +
   44.50          svga_init(&tgui->svga, tgui, 1 << 21, /*2mb*/
   44.51                     tgui_recalctimings,
   44.52                     tgui_in, tgui_out,
   44.53                     tgui_hwcursor_draw);
   44.54  
   44.55 -        mem_mapping_add(&tgui->linear_mapping, 0,       0,      svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &tgui->svga);
   44.56 -        mem_mapping_add(&tgui->accel_mapping,  0xbc000, 0x4000, tgui_accel_read,  tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write,  tgui_accel_write_w, tgui_accel_write_l,  tgui);
   44.57 +        mem_mapping_add(&tgui->linear_mapping, 0,       0,      svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &tgui->svga);
   44.58 +        mem_mapping_add(&tgui->accel_mapping,  0xbc000, 0x4000, tgui_accel_read,  tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write,  tgui_accel_write_w, tgui_accel_write_l, NULL, 0,  tgui);
   44.59          mem_mapping_disable(&tgui->accel_mapping);
   44.60  
   44.61          io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui);
   44.62 @@ -503,6 +489,11 @@
   44.63          return tgui;
   44.64  }
   44.65  
   44.66 +static int tgui9440_available()
   44.67 +{
   44.68 +        return rom_present("roms/9440.vbi");
   44.69 +}
   44.70 +
   44.71  void tgui_close(void *p)
   44.72  {
   44.73          tgui_t *tgui = (tgui_t *)p;
   44.74 @@ -1127,7 +1118,7 @@
   44.75          0,
   44.76          tgui9440_init,
   44.77          tgui_close,
   44.78 -        NULL,
   44.79 +        tgui9440_available,
   44.80          tgui_speed_changed,
   44.81          tgui_force_redraw,
   44.82          tgui_add_status_info
    45.1 --- a/src/vid_tvga.c	Sun Mar 09 11:24:58 2014 +0000
    45.2 +++ b/src/vid_tvga.c	Thu Mar 20 14:03:55 2014 +0000
    45.3 @@ -4,6 +4,7 @@
    45.4  #include "device.h"
    45.5  #include "io.h"
    45.6  #include "mem.h"
    45.7 +#include "rom.h"
    45.8  #include "video.h"
    45.9  #include "vid_svga.h"
   45.10  #include "vid_svga_render.h"
   45.11 @@ -17,6 +18,8 @@
   45.12  
   45.13          svga_t svga;
   45.14          tkd8001_ramdac_t ramdac;
   45.15 +        
   45.16 +        rom_t bios_rom;
   45.17  
   45.18          uint8_t tvga_3d8, tvga_3d9;
   45.19          int oldmode;
   45.20 @@ -48,7 +51,10 @@
   45.21                          break;
   45.22                          case 0xd: 
   45.23                          if (tvga->oldmode) 
   45.24 -                                tvga->oldctrl2 = val; 
   45.25 +                        {
   45.26 +                                tvga->oldctrl2 = val;
   45.27 +                                svga->vrammask = (val & 0x10) ? 0xfffff : 0x3ffff;
   45.28 +                        }
   45.29                          else 
   45.30                                  tvga->newctrl2 = val; 
   45.31                          break;
   45.32 @@ -92,7 +98,7 @@
   45.33                  if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
   45.34                  old = svga->crtc[svga->crtcreg];
   45.35                  svga->crtc[svga->crtcreg] = val;
   45.36 -//                if (svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X\n", svga->crtcreg, val);
   45.37 +//                if (svga->crtcreg != 0xC && svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X %04X:%04X\n", svga->crtcreg, val, CS, pc);
   45.38                  if (old != val)
   45.39                  {
   45.40                          if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
   45.41 @@ -240,6 +246,8 @@
   45.42  {
   45.43          tvga_t *tvga = malloc(sizeof(tvga_t));
   45.44          memset(tvga, 0, sizeof(tvga_t));
   45.45 +
   45.46 +        rom_init(&tvga->bios_rom, "roms/trident.bin", 0xc0000, 0x8000, 0x7fff, 0, 0);
   45.47          
   45.48          svga_init(&tvga->svga, tvga, 1 << 20, /*1mb - chip supports 2mb, but drivers are buggy*/
   45.49                     tvga_recalctimings,
   45.50 @@ -251,6 +259,11 @@
   45.51          return tvga;
   45.52  }
   45.53  
   45.54 +static int tvga8900d_available()
   45.55 +{
   45.56 +        return rom_present("roms/trident.bin");
   45.57 +}
   45.58 +
   45.59  void tvga_close(void *p)
   45.60  {
   45.61          tvga_t *tvga = (tvga_t *)p;
   45.62 @@ -287,7 +300,7 @@
   45.63          0,
   45.64          tvga8900d_init,
   45.65          tvga_close,
   45.66 -        NULL,
   45.67 +        tvga8900d_available,
   45.68          tvga_speed_changed,
   45.69          tvga_force_redraw,
   45.70          tvga_add_status_info
    46.1 --- a/src/vid_vga.c	Sun Mar 09 11:24:58 2014 +0000
    46.2 +++ b/src/vid_vga.c	Thu Mar 20 14:03:55 2014 +0000
    46.3 @@ -4,6 +4,7 @@
    46.4  #include "device.h"
    46.5  #include "io.h"
    46.6  #include "mem.h"
    46.7 +#include "rom.h"
    46.8  #include "video.h"
    46.9  #include "vid_svga.h"
   46.10  #include "vid_vga.h"
   46.11 @@ -11,6 +12,8 @@
   46.12  typedef struct vga_t
   46.13  {
   46.14          svga_t svga;
   46.15 +        
   46.16 +        rom_t bios_rom;
   46.17  } vga_t;
   46.18  
   46.19  void vga_out(uint16_t addr, uint8_t val, void *p)
   46.20 @@ -78,6 +81,8 @@
   46.21          vga_t *vga = malloc(sizeof(vga_t));
   46.22          memset(vga, 0, sizeof(vga_t));
   46.23  
   46.24 +        rom_init(&vga->bios_rom, "roms/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0, 0);
   46.25 +
   46.26          svga_init(&vga->svga, vga, 1 << 18, /*256kb*/
   46.27                     NULL,
   46.28                     vga_in, vga_out,
   46.29 @@ -91,6 +96,11 @@
   46.30          return vga;
   46.31  }
   46.32  
   46.33 +static int vga_available()
   46.34 +{
   46.35 +        return rom_present("roms/ibm_vga.bin");
   46.36 +}
   46.37 +
   46.38  void vga_close(void *p)
   46.39  {
   46.40          vga_t *vga = (vga_t *)p;
   46.41 @@ -127,7 +137,7 @@
   46.42          DEVICE_NOT_WORKING,
   46.43          vga_init,
   46.44          vga_close,
   46.45 -        NULL,
   46.46 +        vga_available,
   46.47          vga_speed_changed,
   46.48          vga_force_redraw,
   46.49          vga_add_status_info
    47.1 --- a/src/vid_voodoo.c	Sun Mar 09 11:24:58 2014 +0000
    47.2 +++ b/src/vid_voodoo.c	Thu Mar 20 14:03:55 2014 +0000
    47.3 @@ -734,9 +734,9 @@
    47.4          voodoo_make_dither();
    47.5          pci_add(voodoo_pci_read, voodoo_pci_write, NULL);
    47.6  
    47.7 -        mem_mapping_add(&voodoo.mmio_mapping, 0, 0, NULL, NULL,            voodoo_readl,    NULL,       NULL,              voodoo_writel,     NULL);
    47.8 -        mem_mapping_add(&voodoo.fb_mapping,   0, 0, NULL, voodoo_fb_readw, voodoo_fb_readl, NULL,       voodoo_fb_writew,  voodoo_fb_writel,  NULL);
    47.9 -        mem_mapping_add(&voodoo.tex_mapping,  0, 0, NULL, NULL,            NULL,            NULL,       voodoo_tex_writew, voodoo_tex_writel, NULL);
   47.10 +        mem_mapping_add(&voodoo.mmio_mapping, 0, 0, NULL, NULL,            voodoo_readl,    NULL,       NULL,              voodoo_writel,     NULL, 0, NULL);
   47.11 +        mem_mapping_add(&voodoo.fb_mapping,   0, 0, NULL, voodoo_fb_readw, voodoo_fb_readl, NULL,       voodoo_fb_writew,  voodoo_fb_writel,  NULL, 0, NULL);
   47.12 +        mem_mapping_add(&voodoo.tex_mapping,  0, 0, NULL, NULL,            NULL,            NULL,       voodoo_tex_writew, voodoo_tex_writel, NULL, 0, NULL);
   47.13  
   47.14          voodoo.fb_mem = malloc(2 * 1024 * 1024);
   47.15          voodoo.tex_mem = malloc(2 * 1024 * 1024);        
    48.1 --- a/src/video.c	Sun Mar 09 11:24:58 2014 +0000
    48.2 +++ b/src/video.c	Thu Mar 20 14:03:55 2014 +0000
    48.3 @@ -8,6 +8,7 @@
    48.4  #include "vid_svga.h"
    48.5  #include "io.h"
    48.6  #include "cpu.h"
    48.7 +#include "rom.h"
    48.8  #include "timer.h"
    48.9  
   48.10  #include "vid_ati18800.h"
   48.11 @@ -229,11 +230,15 @@
   48.12                  return;
   48.13  
   48.14                  case ROM_PC2086:
   48.15 +                device_add(&paradise_pvga1a_pc2086_device);
   48.16 +                return;
   48.17 +
   48.18                  case ROM_PC3086:
   48.19 -                device_add(&paradise_pvga1a_device);
   48.20 +                device_add(&paradise_pvga1a_pc3086_device);
   48.21                  return;
   48.22 +
   48.23                  case ROM_MEGAPC:
   48.24 -                device_add(&paradise_wd90c11_device);
   48.25 +                device_add(&paradise_wd90c11_megapc_device);
   48.26                  return;
   48.27                          
   48.28                  case ROM_ACER386:
    49.1 --- a/src/win.c	Sun Mar 09 11:24:58 2014 +0000
    49.2 +++ b/src/win.c	Thu Mar 20 14:03:55 2014 +0000
    49.3 @@ -386,18 +386,14 @@
    49.4                  }
    49.5          }
    49.6          
    49.7 -        d = gfxcard;
    49.8 +
    49.9          for (c = 0; c < 18; c++)
   49.10 -        {
   49.11 -                gfxcard = c;
   49.12 -                gfx_present[c] = mem_load_video_bios();
   49.13 -        }
   49.14 -        gfxcard = d;
   49.15 -        c = mem_load_video_bios();
   49.16 -        if (!c)
   49.17 +                gfx_present[c] = video_card_available(video_old_to_new(c));
   49.18 +
   49.19 +        if (!video_card_available(video_old_to_new(gfxcard)))
   49.20          {
   49.21                  if (romset!=-1) MessageBox(hwnd,"Configured video BIOS not available.\nDefaulting to available romset.","PCem error",MB_OK);
   49.22 -                for (c=0;c<18;c++)
   49.23 +                for (c = 17; c >= 0; c--)
   49.24                  {
   49.25                          if (gfx_present[c])
   49.26                          {
   49.27 @@ -783,7 +779,6 @@
   49.28                                          sound_card_current = temp_sound_card_current;
   49.29                                          
   49.30                                          mem_resize();
   49.31 -                                        mem_load_video_bios();
   49.32                                          loadbios();
   49.33                                          resetpchard();
   49.34                                  }