PCem

changeset 41:ed02b0da1714

Added correct clock support for S3 Trio64 (Number Nine 9FX). Seperated TGUI9440 and TVGA8900D implementations. Modes > 8 bpp now handled more logically in SVGA core. Fixed broken status window for most SVGA cards. Masking of address on 'legacy' VGA memory ranges now handled better.
author TomW
date Wed Nov 20 21:34:09 2013 +0000
parents 83b75538c211
children 2dc5624aebab
files src/Makefile.mingw src/vid_ati18800.c src/vid_ati28800.c src/vid_ati_mach64.c src/vid_cl5429.c src/vid_et4000.c src/vid_et4000w32.c src/vid_oti067.c src/vid_paradise.c src/vid_s3.c src/vid_s3_virge.c src/vid_sdac_ramdac.c src/vid_sdac_ramdac.h src/vid_svga.c src/vid_svga.h src/vid_tgui9440.c src/vid_tgui9440.h src/vid_tvga.c src/vid_tvga.h src/vid_vga.c src/video.c
diffstat 21 files changed, 1383 insertions(+), 938 deletions(-) [+]
line diff
     1.1 --- a/src/Makefile.mingw	Sat Nov 16 20:48:51 2013 +0000
     1.2 +++ b/src/Makefile.mingw	Wed Nov 20 21:34:09 2013 +0000
     1.3 @@ -17,7 +17,7 @@
     1.4  	vid_hercules.o vid_icd2061.o vid_ics2595.o vid_mda.o vid_olivetti_m24.o \
     1.5  	vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o \
     1.6  	vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
     1.7 -	vid_tandy.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
     1.8 +	vid_tandy.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
     1.9  	vid_voodoo.o video.o wd76c10.o win.o win-d3d.o win-ddraw.o win-keyboard.o win-midi.o \
    1.10  	win-mouse.o win-timer.o win-video.o x86seg.o x87.o xtide.o pc.res
    1.11  FMOBJ = fmopl.o ymf262.o
     2.1 --- a/src/vid_ati18800.c	Sat Nov 16 20:48:51 2013 +0000
     2.2 +++ b/src/vid_ati18800.c	Wed Nov 20 21:34:09 2013 +0000
     2.3 @@ -160,6 +160,13 @@
     2.4          ati18800->svga.fullchange = changeframecount;
     2.5  }
     2.6  
     2.7 +int ati18800_add_status_info(char *s, int max_len, void *p)
     2.8 +{
     2.9 +        ati18800_t *ati18800 = (ati18800_t *)p;
    2.10 +        
    2.11 +        return svga_add_status_info(s, max_len, &ati18800->svga);
    2.12 +}
    2.13 +
    2.14  device_t ati18800_device =
    2.15  {
    2.16          "ATI-18800",
    2.17 @@ -168,6 +175,6 @@
    2.18          NULL,
    2.19          ati18800_speed_changed,
    2.20          ati18800_force_redraw,
    2.21 -        svga_add_status_info
    2.22 +        ati18800_add_status_info
    2.23  };
    2.24  
     3.1 --- a/src/vid_ati28800.c	Sat Nov 16 20:48:51 2013 +0000
     3.2 +++ b/src/vid_ati28800.c	Wed Nov 20 21:34:09 2013 +0000
     3.3 @@ -181,6 +181,13 @@
     3.4          ati28800->svga.fullchange = changeframecount;
     3.5  }
     3.6  
     3.7 +int ati28800_add_status_info(char *s, int max_len, void *p)
     3.8 +{
     3.9 +        ati28800_t *ati28800 = (ati28800_t *)p;
    3.10 +        
    3.11 +        return svga_add_status_info(s, max_len, &ati28800->svga);
    3.12 +}
    3.13 +
    3.14  device_t ati28800_device =
    3.15  {
    3.16          "ATI-28800",
    3.17 @@ -189,5 +196,5 @@
    3.18          NULL,
    3.19          ati28800_speed_changed,
    3.20          ati28800_force_redraw,
    3.21 -        svga_add_status_info
    3.22 +        ati28800_add_status_info
    3.23  };
     4.1 --- a/src/vid_ati_mach64.c	Sat Nov 16 20:48:51 2013 +0000
     4.2 +++ b/src/vid_ati_mach64.c	Wed Nov 20 21:34:09 2013 +0000
     4.3 @@ -336,21 +336,25 @@
     4.4                  mem_mapping_set_p(&mach64->svga.mapping, mach64);
     4.5                  mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
     4.6                  mem_mapping_enable(&mach64->mmio_mapping);
     4.7 +                svga->banked_mask = 0xffff;
     4.8                  break;
     4.9                  case 0x4: /*64k at A0000*/
    4.10                  mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL);
    4.11                  mem_mapping_set_p(&mach64->svga.mapping, mach64);
    4.12                  mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
    4.13 +                svga->banked_mask = 0xffff;
    4.14                  break;
    4.15                  case 0x8: /*32k at B0000*/
    4.16                  mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
    4.17                  mem_mapping_set_p(&mach64->svga.mapping, svga);
    4.18                  mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
    4.19 +                svga->banked_mask = 0x7fff;
    4.20                  break;
    4.21                  case 0xC: /*32k at B8000*/
    4.22                  mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
    4.23                  mem_mapping_set_p(&mach64->svga.mapping, svga);
    4.24                  mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
    4.25 +                svga->banked_mask = 0x7fff;
    4.26                  break;
    4.27          }
    4.28          if (mach64->linear_base)
    4.29 @@ -2081,6 +2085,13 @@
    4.30          mach64->svga.fullchange = changeframecount;
    4.31  }
    4.32  
    4.33 +int mach64_add_status_info(char *s, int max_len, void *p)
    4.34 +{
    4.35 +        mach64_t *mach64 = (mach64_t *)p;
    4.36 +        
    4.37 +        return svga_add_status_info(s, max_len, &mach64->svga);
    4.38 +}
    4.39 +
    4.40  device_t mach64gx_device =
    4.41  {
    4.42          "ATI Mach64GX",
    4.43 @@ -2089,5 +2100,5 @@
    4.44          NULL,
    4.45          mach64_speed_changed,
    4.46          mach64_force_redraw,
    4.47 -        svga_add_status_info
    4.48 +        mach64_add_status_info
    4.49  };
     5.1 --- a/src/vid_cl5429.c	Sat Nov 16 20:48:51 2013 +0000
     5.2 +++ b/src/vid_cl5429.c	Wed Nov 20 21:34:09 2013 +0000
     5.3 @@ -17,6 +17,7 @@
     5.4          svga_t svga;
     5.5          
     5.6          uint32_t bank[2];
     5.7 +        uint32_t mask;
     5.8  
     5.9          struct
    5.10          {
    5.11 @@ -228,19 +229,23 @@
    5.12                  case 0x0: /*128k at A0000*/
    5.13                  mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
    5.14                  mem_mapping_disable(&gd5429->mmio_mapping);
    5.15 +                svga->banked_mask = 0xffff;
    5.16                  break;
    5.17                  case 0x4: /*64k at A0000*/
    5.18                  mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
    5.19                  if (svga->seqregs[0x17] & 0x04)
    5.20                          mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100);
    5.21 +                svga->banked_mask = 0xffff;
    5.22                  break;
    5.23                  case 0x8: /*32k at B0000*/
    5.24                  mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
    5.25                  mem_mapping_disable(&gd5429->mmio_mapping);
    5.26 +                svga->banked_mask = 0x7fff;
    5.27                  break;
    5.28                  case 0xC: /*32k at B8000*/
    5.29                  mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
    5.30                  mem_mapping_disable(&gd5429->mmio_mapping);
    5.31 +                svga->banked_mask = 0x7fff;
    5.32                  break;
    5.33          }
    5.34  }
    5.35 @@ -294,7 +299,9 @@
    5.36  void gd5429_write(uint32_t addr, uint8_t val, void *p)
    5.37  {
    5.38          gd5429_t *gd5429 = (gd5429_t *)p;
    5.39 +        svga_t *svga = &gd5429->svga;
    5.40  //        pclog("gd5429_write : %05X %02X  ", addr, val);
    5.41 +        addr &= svga->banked_mask;
    5.42          addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
    5.43  //        pclog("%08X\n", addr);
    5.44          gd5429_write_linear(addr, val, p);
    5.45 @@ -303,8 +310,10 @@
    5.46  uint8_t gd5429_read(uint32_t addr, void *p)
    5.47  {
    5.48          gd5429_t *gd5429 = (gd5429_t *)p;
    5.49 +        svga_t *svga = &gd5429->svga;
    5.50          uint8_t ret;
    5.51  //        pclog("gd5429_read : %05X ", addr);
    5.52 +        addr &= svga->banked_mask;
    5.53          addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1];
    5.54          ret = svga_read_linear(addr, &gd5429->svga);
    5.55  //        pclog("%08X %02X\n", addr, ret);  
    5.56 @@ -850,6 +859,13 @@
    5.57          gd5429->svga.fullchange = changeframecount;
    5.58  }
    5.59  
    5.60 +int gd5429_add_status_info(char *s, int max_len, void *p)
    5.61 +{
    5.62 +        gd5429_t *gd5429 = (gd5429_t *)p;
    5.63 +        
    5.64 +        return svga_add_status_info(s, max_len, &gd5429->svga);
    5.65 +}
    5.66 +
    5.67  device_t gd5429_device =
    5.68  {
    5.69          "Cirrus Logic GD5429",
    5.70 @@ -858,5 +874,5 @@
    5.71          NULL,
    5.72          gd5429_speed_changed,
    5.73          gd5429_force_redraw,
    5.74 -        svga_add_status_info
    5.75 +        gd5429_add_status_info
    5.76  };
     6.1 --- a/src/vid_et4000.c	Sat Nov 16 20:48:51 2013 +0000
     6.2 +++ b/src/vid_et4000.c	Wed Nov 20 21:34:09 2013 +0000
     6.3 @@ -113,7 +113,16 @@
     6.4                  case 5: svga->clock = cpuclock / 65000000.0; break;
     6.5                  default: svga->clock = cpuclock / 36000000.0; break;
     6.6          }
     6.7 -
     6.8 +        
     6.9 +        switch (svga->bpp)
    6.10 +        {
    6.11 +                case 15: case 16:
    6.12 +                svga->hdisp /= 2;
    6.13 +                break;
    6.14 +                case 24:
    6.15 +                svga->hdisp /= 3;
    6.16 +                break;
    6.17 +        }
    6.18  }
    6.19  
    6.20  void *et4000_init()
    6.21 @@ -154,6 +163,13 @@
    6.22          et4000->svga.fullchange = changeframecount;
    6.23  }
    6.24  
    6.25 +int et4000_add_status_info(char *s, int max_len, void *p)
    6.26 +{
    6.27 +        et4000_t *et4000 = (et4000_t *)p;
    6.28 +        
    6.29 +        return svga_add_status_info(s, max_len, &et4000->svga);
    6.30 +}
    6.31 +
    6.32  device_t et4000_device =
    6.33  {
    6.34          "Tseng Labs ET4000AX",
    6.35 @@ -162,5 +178,5 @@
    6.36          NULL,
    6.37          et4000_speed_changed,
    6.38          et4000_force_redraw,
    6.39 -        svga_add_status_info
    6.40 +        et4000_add_status_info
    6.41  };
     7.1 --- a/src/vid_et4000w32.c	Sat Nov 16 20:48:51 2013 +0000
     7.2 +++ b/src/vid_et4000w32.c	Wed Nov 20 21:34:09 2013 +0000
     7.3 @@ -251,7 +251,7 @@
     7.4                  svga->hdisp >>= 1;
     7.5                  break;
     7.6                  case 24:
     7.7 -                svga->hdisp /= 8;
     7.8 +                svga->hdisp /= 3;
     7.9                  break;
    7.10          }
    7.11  }
    7.12 @@ -277,30 +277,37 @@
    7.13                          case 0x0: case 0x4: case 0x8: case 0xC: /*128k at A0000*/
    7.14                          mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
    7.15                          mem_mapping_disable(&et4000->mmu_mapping);
    7.16 +                        svga->banked_mask = 0xffff;
    7.17                          break;
    7.18                          case 0x1: /*64k at A0000*/
    7.19                          mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
    7.20                          mem_mapping_disable(&et4000->mmu_mapping);
    7.21 +                        svga->banked_mask = 0xffff;
    7.22                          break;
    7.23                          case 0x2: /*32k at B0000*/
    7.24                          mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
    7.25                          mem_mapping_disable(&et4000->mmu_mapping);
    7.26 +                        svga->banked_mask = 0x7fff;
    7.27                          break;
    7.28                          case 0x3: /*32k at B8000*/
    7.29                          mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
    7.30                          mem_mapping_disable(&et4000->mmu_mapping);
    7.31 +                        svga->banked_mask = 0x7fff;
    7.32                          break;
    7.33                          case 0x5: case 0x9: case 0xD: /*64k at A0000, MMU at B8000*/
    7.34                          mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
    7.35                          mem_mapping_set_addr(&et4000->mmu_mapping, 0xb8000, 0x08000);
    7.36 +                        svga->banked_mask = 0xffff;
    7.37                          break;
    7.38                          case 0x6: case 0xA: case 0xE: /*32k at B0000, MMU at A8000*/
    7.39                          mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
    7.40                          mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000);
    7.41 +                        svga->banked_mask = 0x7fff;
    7.42                          break;
    7.43                          case 0x7: case 0xB: case 0xF: /*32k at B8000, MMU at A8000*/
    7.44                          mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
    7.45                          mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000);
    7.46 +                        svga->banked_mask = 0x7fff;
    7.47                          break;
    7.48                  }
    7.49                  
    7.50 @@ -983,6 +990,13 @@
    7.51          et4000w32p->svga.fullchange = changeframecount;
    7.52  }
    7.53  
    7.54 +int et4000w32p_add_status_info(char *s, int max_len, void *p)
    7.55 +{
    7.56 +        et4000w32p_t *et4000w32p = (et4000w32p_t *)p;
    7.57 +        
    7.58 +        return svga_add_status_info(s, max_len, &et4000w32p->svga);
    7.59 +}
    7.60 +
    7.61  device_t et4000w32p_device =
    7.62  {
    7.63          "Tseng Labs ET4000/w32p",
    7.64 @@ -991,5 +1005,5 @@
    7.65          NULL,
    7.66          et4000w32p_speed_changed,
    7.67          et4000w32p_force_redraw,
    7.68 -        svga_add_status_info
    7.69 +        et4000w32p_add_status_info
    7.70  };
     8.1 --- a/src/vid_oti067.c	Sat Nov 16 20:48:51 2013 +0000
     8.2 +++ b/src/vid_oti067.c	Wed Nov 20 21:34:09 2013 +0000
     8.3 @@ -149,6 +149,13 @@
     8.4          oti067->svga.fullchange = changeframecount;
     8.5  }
     8.6  
     8.7 +int oti067_add_status_info(char *s, int max_len, void *p)
     8.8 +{
     8.9 +        oti067_t *oti067 = (oti067_t *)p;
    8.10 +        
    8.11 +        return svga_add_status_info(s, max_len, &oti067->svga);
    8.12 +}
    8.13 +
    8.14  device_t oti067_device =
    8.15  {
    8.16          "Oak OTI-067",
    8.17 @@ -157,5 +164,5 @@
    8.18          NULL,
    8.19          oti067_speed_changed,
    8.20          oti067_force_redraw,
    8.21 -        svga_add_status_info
    8.22 +        oti067_add_status_info
    8.23  };
     9.1 --- a/src/vid_paradise.c	Sat Nov 16 20:48:51 2013 +0000
     9.2 +++ b/src/vid_paradise.c	Wed Nov 20 21:34:09 2013 +0000
     9.3 @@ -70,15 +70,19 @@
     9.4                                  {
     9.5                                          case 0x0: /*128k at A0000*/
     9.6                                          mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
     9.7 +                                        svga->banked_mask = 0xffff;
     9.8                                          break;
     9.9                                          case 0x4: /*64k at A0000*/
    9.10                                          mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
    9.11 +                                        svga->banked_mask = 0xffff;
    9.12                                          break;
    9.13                                          case 0x8: /*32k at B0000*/
    9.14                                          mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
    9.15 +                                        svga->banked_mask = 0x7fff;
    9.16                                          break;
    9.17                                          case 0xC: /*32k at B8000*/
    9.18                                          mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
    9.19 +                                        svga->banked_mask = 0x7fff;
    9.20                                          break;
    9.21                                  }
    9.22                          }
    9.23 @@ -331,6 +335,13 @@
    9.24          paradise->svga.fullchange = changeframecount;
    9.25  }
    9.26  
    9.27 +int paradise_add_status_info(char *s, int max_len, void *p)
    9.28 +{
    9.29 +        paradise_t *paradise = (paradise_t *)p;
    9.30 +        
    9.31 +        return svga_add_status_info(s, max_len, &paradise->svga);
    9.32 +}
    9.33 +
    9.34  device_t paradise_pvga1a_device =
    9.35  {
    9.36          "Paradise PVGA1A",
    9.37 @@ -339,7 +350,7 @@
    9.38          NULL,
    9.39          paradise_speed_changed,
    9.40          paradise_force_redraw,
    9.41 -        svga_add_status_info
    9.42 +        paradise_add_status_info
    9.43  };
    9.44  device_t paradise_wd90c11_device =
    9.45  {
    9.46 @@ -349,5 +360,5 @@
    9.47          NULL,
    9.48          paradise_speed_changed,
    9.49          paradise_force_redraw,
    9.50 -        svga_add_status_info
    9.51 +        paradise_add_status_info
    9.52  };
    10.1 --- a/src/vid_s3.c	Sat Nov 16 20:48:51 2013 +0000
    10.2 +++ b/src/vid_s3.c	Wed Nov 20 21:34:09 2013 +0000
    10.3 @@ -28,6 +28,9 @@
    10.4  
    10.5          uint32_t linear_base, linear_size;
    10.6  
    10.7 +        float (*getclock)(int clock, void *p);
    10.8 +        void *getclock_p;
    10.9 +
   10.10          struct
   10.11          {
   10.12                  uint8_t subsys_cntl;
   10.13 @@ -85,6 +88,16 @@
   10.14          switch (addr)
   10.15          {
   10.16                  case 0x3c5:
   10.17 +                if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20)
   10.18 +                {
   10.19 +                        svga->seqregs[svga->seqaddr] = val;
   10.20 +                        switch (svga->seqaddr)
   10.21 +                        {
   10.22 +                                case 0x12: case 0x13:
   10.23 +                                svga_recalctimings(svga);
   10.24 +                                return;
   10.25 +                        }
   10.26 +                }
   10.27                  if (svga->seqaddr == 4) /*Chain-4 - update banking*/
   10.28                  {
   10.29                          if (val & 8) svga->write_bank = svga->read_bank = s3->bank << 16;
   10.30 @@ -213,6 +226,11 @@
   10.31  //        if (addr != 0x3da) pclog("S3 in %04X\n", addr);
   10.32          switch (addr)
   10.33          {
   10.34 +                case 0x3c5:
   10.35 +                if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20)
   10.36 +                        return svga->seqregs[svga->seqaddr];
   10.37 +                break;
   10.38 +                
   10.39                  case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9:
   10.40  //                pclog("Read RAMDAC %04X  %04X:%04X\n", addr, CS, pc);
   10.41                  return sdac_ramdac_in(addr, &s3->ramdac, svga);
   10.42 @@ -260,9 +278,14 @@
   10.43          else if (svga->crtc[0x43] & 0x04) svga->rowoffset  += 0x100;
   10.44          if (!svga->rowoffset) svga->rowoffset = 256;
   10.45          svga->interlace = svga->crtc[0x42] & 0x20;
   10.46 -        svga->clock = cpuclock / sdac_getclock((svga->miscout >> 2) & 3, &s3->ramdac);
   10.47 -//        pclog("SVGA_CLOCK = %f  %02X  %f\n", svga_clock, svga_miscout, cpuclock);
   10.48 -        if (svga->bpp > 8) svga->clock /= 2;
   10.49 +        svga->clock = cpuclock / s3->getclock((svga->miscout >> 2) & 3, s3->getclock_p);
   10.50 +
   10.51 +        switch (svga->crtc[0x67] >> 4)
   10.52 +        {
   10.53 +                case 3: case 5: case 7:
   10.54 +                svga->clock /= 2;
   10.55 +                break;
   10.56 +        }                
   10.57  
   10.58          svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10));
   10.59          if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10))
   10.60 @@ -274,23 +297,23 @@
   10.61                          break;
   10.62                          case 15: 
   10.63                          svga->render = svga_render_15bpp_highres; 
   10.64 +                        svga->hdisp /= 2;
   10.65                          break;
   10.66                          case 16: 
   10.67                          svga->render = svga_render_16bpp_highres; 
   10.68 +                        svga->hdisp /= 2;
   10.69                          break;
   10.70                          case 24: 
   10.71                          svga->render = svga_render_24bpp_highres; 
   10.72 +                        svga->hdisp /= 3;
   10.73                          break;
   10.74                          case 32:
   10.75                          svga->render = svga_render_32bpp_highres; 
   10.76 -                        if (gfxcard == GFX_N9_9FX) /*Trio64*/
   10.77 -                                svga->hdisp *= 4;
   10.78 +                        if (gfxcard != GFX_N9_9FX) /*Trio64*/
   10.79 +                                svga->hdisp /= 4;
   10.80                          break;
   10.81                  }
   10.82          }
   10.83 -
   10.84 -       // if (svga->bpp == 32) svga->hdisp *= 3;
   10.85 -//        pclog("svga->hdisp %i %02X %i\n", svga->hdisp, svga->crtc[0x5d], svga->hdisp_time);
   10.86  }
   10.87  
   10.88  void s3_updatemapping(s3_t *s3)
   10.89 @@ -305,15 +328,19 @@
   10.90          {
   10.91                  case 0x0: /*128k at A0000*/
   10.92                  mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
   10.93 +                svga->banked_mask = 0xffff;
   10.94                  break;
   10.95                  case 0x4: /*64k at A0000*/
   10.96                  mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
   10.97 +                svga->banked_mask = 0xffff;
   10.98                  break;
   10.99                  case 0x8: /*32k at B0000*/
  10.100                  mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
  10.101 +                svga->banked_mask = 0x7fff;
  10.102                  break;
  10.103                  case 0xC: /*32k at B8000*/
  10.104                  mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
  10.105 +                svga->banked_mask = 0x7fff;
  10.106                  break;
  10.107          }
  10.108          
  10.109 @@ -345,6 +372,7 @@
  10.110                  {
  10.111                          mem_mapping_disable(&s3->linear_mapping);
  10.112                          mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
  10.113 +                        svga->banked_mask = 0xffff;
  10.114  //                        mem_mapping_set_addr(&s3->linear_mapping, 0xa0000, 0x10000);
  10.115                  }
  10.116                  else
  10.117 @@ -360,6 +388,23 @@
  10.118                  mem_mapping_disable(&s3->mmio_mapping);
  10.119  }
  10.120  
  10.121 +static float s3_trio64_getclock(int clock, void *p)
  10.122 +{
  10.123 +        s3_t *s3 = (s3_t *)p;
  10.124 +        svga_t *svga = &s3->svga;
  10.125 +        float t;
  10.126 +        int m, n1, n2;
  10.127 +//        pclog("Trio64_getclock %i %02X %02X\n", clock, svga->seqregs[0x13], svga->seqregs[0x12]);
  10.128 +        if (clock == 0) return 25175000.0;
  10.129 +        if (clock == 1) return 28322000.0;
  10.130 +        m  = svga->seqregs[0x13] + 2;
  10.131 +        n1 = (svga->seqregs[0x12] & 0x1f) + 2;
  10.132 +        n2 = ((svga->seqregs[0x12] >> 5) & 0x07);
  10.133 +        t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2);
  10.134 +//        pclog("TRIO64 clock %i %i %i %f  %f %i\n", m, n1, n2, t, 14318184.0 * ((float)m / (float)n1), 1 << n2);
  10.135 +        return t;
  10.136 +}
  10.137 +
  10.138  
  10.139  void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3);
  10.140  
  10.141 @@ -1591,7 +1636,10 @@
  10.142  
  10.143          s3->id = 0xc1; /*Vision864P*/
  10.144          s3->id_ext = 0xc1; /*Trio64*/
  10.145 -        
  10.146 +
  10.147 +        s3->getclock = sdac_getclock;
  10.148 +        s3->getclock_p = &s3->ramdac;
  10.149 +
  10.150          return s3;
  10.151  }
  10.152  
  10.153 @@ -1601,7 +1649,10 @@
  10.154  
  10.155          s3->id = 0xe1;
  10.156          s3->id_ext = 0x11; /*Trio64*/
  10.157 -        
  10.158 +
  10.159 +        s3->getclock = s3_trio64_getclock;
  10.160 +        s3->getclock_p = s3;
  10.161 +
  10.162          return s3;
  10.163  }
  10.164  
  10.165 @@ -1628,6 +1679,13 @@
  10.166          s3->svga.fullchange = changeframecount;
  10.167  }
  10.168  
  10.169 +int s3_add_status_info(char *s, int max_len, void *p)
  10.170 +{
  10.171 +        s3_t *s3 = (s3_t *)p;
  10.172 +        
  10.173 +        return svga_add_status_info(s, max_len, &s3->svga);
  10.174 +}
  10.175 +
  10.176  device_t s3_bahamas64_device =
  10.177  {
  10.178          "Paradise Bahamas 64 (S3 Vision864)",
  10.179 @@ -1636,7 +1694,7 @@
  10.180          NULL,
  10.181          s3_speed_changed,
  10.182          s3_force_redraw,
  10.183 -        svga_add_status_info
  10.184 +        s3_add_status_info
  10.185  };
  10.186  
  10.187  device_t s3_9fx_device =
  10.188 @@ -1647,5 +1705,5 @@
  10.189          NULL,
  10.190          s3_speed_changed,
  10.191          s3_force_redraw,
  10.192 -        svga_add_status_info
  10.193 +        s3_add_status_info
  10.194  };
    11.1 --- a/src/vid_s3_virge.c	Sat Nov 16 20:48:51 2013 +0000
    11.2 +++ b/src/vid_s3_virge.c	Wed Nov 20 21:34:09 2013 +0000
    11.3 @@ -271,15 +271,19 @@
    11.4          {
    11.5                  case 0x0: /*128k at A0000*/
    11.6                  mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
    11.7 +                svga->banked_mask = 0xffff;
    11.8                  break;
    11.9                  case 0x4: /*64k at A0000*/
   11.10                  mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
   11.11 +                svga->banked_mask = 0xffff;
   11.12                  break;
   11.13                  case 0x8: /*32k at B0000*/
   11.14                  mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
   11.15 +                svga->banked_mask = 0x7fff;
   11.16                  break;
   11.17                  case 0xC: /*32k at B8000*/
   11.18                  mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
   11.19 +                svga->banked_mask = 0x7fff;
   11.20                  break;
   11.21          }
   11.22          
   11.23 @@ -503,6 +507,13 @@
   11.24          virge->svga.fullchange = changeframecount;
   11.25  }
   11.26  
   11.27 +int s3_virge_add_status_info(char *s, int max_len, void *p)
   11.28 +{
   11.29 +        virge_t *virge = (virge_t *)p;
   11.30 +        
   11.31 +        return svga_add_status_info(s, max_len, &virge->svga);
   11.32 +}
   11.33 +
   11.34  device_t s3_virge_device =
   11.35  {
   11.36          "Diamond Stealth 3D 2000 (S3 VIRGE)",
   11.37 @@ -511,5 +522,5 @@
   11.38          NULL,
   11.39          s3_virge_speed_changed,
   11.40          s3_virge_force_redraw,
   11.41 -        svga_add_status_info
   11.42 +        s3_virge_add_status_info
   11.43  };
    12.1 --- a/src/vid_sdac_ramdac.c	Sat Nov 16 20:48:51 2013 +0000
    12.2 +++ b/src/vid_sdac_ramdac.c	Wed Nov 20 21:34:09 2013 +0000
    12.3 @@ -121,8 +121,9 @@
    12.4          return svga_in(addr, svga);
    12.5  }
    12.6  
    12.7 -float sdac_getclock(int clock, sdac_ramdac_t *ramdac)
    12.8 +float sdac_getclock(int clock, void *p)
    12.9  {
   12.10 +        sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p;
   12.11          float t;
   12.12          int m, n1, n2;
   12.13  //        pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]);
    13.1 --- a/src/vid_sdac_ramdac.h	Sat Nov 16 20:48:51 2013 +0000
    13.2 +++ b/src/vid_sdac_ramdac.h	Wed Nov 20 21:34:09 2013 +0000
    13.3 @@ -11,4 +11,4 @@
    13.4  void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga);
    13.5  uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga);
    13.6  
    13.7 -float sdac_getclock(int clock, sdac_ramdac_t *ramdac);
    13.8 +float sdac_getclock(int clock, void *p);
    14.1 --- a/src/vid_svga.c	Sat Nov 16 20:48:51 2013 +0000
    14.2 +++ b/src/vid_svga.c	Wed Nov 20 21:34:09 2013 +0000
    14.3 @@ -136,23 +136,27 @@
    14.4                          case 4: svga->readplane=val&3; break;
    14.5                          case 5: svga->writemode=val&3; svga->readmode=val&8; break;
    14.6                          case 6:
    14.7 -                                pclog("svga_out recalcmapping %p\n", svga);
    14.8 +//                                pclog("svga_out recalcmapping %p\n", svga);
    14.9                          if ((svga->gdcreg[6] & 0xc) != (val & 0xc))
   14.10                          {
   14.11 -                                pclog("Write mapping %02X\n", val);
   14.12 +//                                pclog("Write mapping %02X\n", val);
   14.13                                  switch (val&0xC)
   14.14                                  {
   14.15                                          case 0x0: /*128k at A0000*/
   14.16                                          mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
   14.17 +                                        svga->banked_mask = 0xffff;
   14.18                                          break;
   14.19                                          case 0x4: /*64k at A0000*/
   14.20                                          mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
   14.21 +                                        svga->banked_mask = 0xffff;
   14.22                                          break;
   14.23                                          case 0x8: /*32k at B0000*/
   14.24                                          mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
   14.25 +                                        svga->banked_mask = 0x7fff;
   14.26                                          break;
   14.27                                          case 0xC: /*32k at B8000*/
   14.28                                          mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
   14.29 +                                        svga->banked_mask = 0x7fff;
   14.30                                          break;
   14.31                                  }
   14.32                          }
   14.33 @@ -309,49 +313,31 @@
   14.34                                          if (svga->lowres)
   14.35                                                  svga->render = svga_render_8bpp_lowres;
   14.36                                          else
   14.37 -                                        {
   14.38                                                  svga->render = svga_render_8bpp_highres;
   14.39 -//                                                svga_hdisp <<= 1;
   14.40 -                                        }
   14.41                                          break;
   14.42                                          case 15:
   14.43                                          if (svga->lowres)
   14.44                                                  svga->render = svga_render_15bpp_lowres;
   14.45                                          else
   14.46 -                                        {
   14.47                                                  svga->render = svga_render_15bpp_highres;
   14.48 -                                                svga->hdisp <<= 1;
   14.49 -                                        }
   14.50                                          break;
   14.51                                          case 16:
   14.52                                          if (svga->lowres)
   14.53                                                  svga->render = svga_render_16bpp_lowres;
   14.54                                          else
   14.55 -                                        {
   14.56                                                  svga->render = svga_render_16bpp_highres;
   14.57 -                                                svga->hdisp <<= 1;
   14.58 -                                        }
   14.59                                          break;
   14.60                                          case 24:
   14.61                                          if (svga->lowres)
   14.62 -                                        {
   14.63                                                  svga->render = svga_render_24bpp_lowres;
   14.64 -                                                svga->hdisp = ((svga->hdisp << 3) / 3);
   14.65 -                                        }
   14.66                                          else
   14.67 -                                        {
   14.68                                                  svga->render = svga_render_24bpp_highres;
   14.69 -                                                svga->hdisp = ((svga->hdisp << 3) / 3);
   14.70 -                                        }
   14.71                                          break;
   14.72                                          case 32:
   14.73                                          if (svga->lowres)
   14.74                                                  svga->render = svga_render_32bpp_lowres;
   14.75                                          else
   14.76 -                                        {
   14.77                                                  svga->render = svga_render_32bpp_highres;
   14.78 -                                                svga->hdisp <<= 1;
   14.79 -                                        }
   14.80                                          break;
   14.81                                  }
   14.82                                  break;
   14.83 @@ -516,15 +502,12 @@
   14.84                          svga->cgastat |= 8;
   14.85                          x = svga->hdisp;
   14.86  
   14.87 -                        if (svga->bpp == 16 || svga->bpp == 15) x /= 2;
   14.88 -                        if (svga->bpp == 32)                    x /= 4;
   14.89                          if (svga->interlace && !svga->oddeven) svga->lastline++;
   14.90                          if (svga->interlace &&  svga->oddeven) svga->firstline--;
   14.91  
   14.92                          wx = x;
   14.93                          wy = svga->lastline - svga->firstline;
   14.94  
   14.95 -
   14.96                          svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga);
   14.97  
   14.98                          readflash = 0;
   14.99 @@ -548,7 +531,6 @@
  14.100                          svga->maback <<= 2;
  14.101                          svga->ca <<= 2;
  14.102  
  14.103 -
  14.104                          svga->video_res_x = wx;
  14.105                          svga->video_res_y = wy + 1;
  14.106  //                        pclog("%i %i %i\n", svga->video_res_x, svga->video_res_y, svga->lowres);
  14.107 @@ -668,13 +650,8 @@
  14.108          cycles_lost += video_timing_b;
  14.109  
  14.110          if (svga_output) pclog("Writeega %06X   ",addr);
  14.111 -        if (addr>=0xB0000) addr&=0x7FFF;
  14.112 -        else
  14.113 -        {
  14.114 -                //if (gdcreg[6]&8) return;
  14.115 -                addr &= 0xFFFF;
  14.116 -                addr += svga->write_bank;
  14.117 -        }
  14.118 +        addr &= svga->banked_mask;
  14.119 +        addr += svga->write_bank;
  14.120  
  14.121          if (!(svga->gdcreg[6] & 1)) svga->fullchange=2;
  14.122          if (svga->chain4)
  14.123 @@ -848,12 +825,9 @@
  14.124          
  14.125          egareads++;
  14.126  //        pclog("Readega %06X   ",addr);
  14.127 -        if (addr>=0xB0000) addr&=0x7FFF;
  14.128 -        else
  14.129 -        {
  14.130 -                addr &= 0xFFFF;
  14.131 -                addr += svga->read_bank;
  14.132 -        }
  14.133 +        addr &= svga->banked_mask;
  14.134 +        addr += svga->read_bank;
  14.135 +
  14.136  //        pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode);
  14.137  //        pclog("%i\n", svga->readmode);
  14.138          if (svga->chain4) 
  14.139 @@ -1120,6 +1094,7 @@
  14.140  //        pclog("svga_doblit start\n");
  14.141          svga->frames++;
  14.142  //        pclog("doblit %i %i\n", y1, y2);
  14.143 +//        pclog("svga_doblit %i %i\n", wx, svga->hdisp);
  14.144          if (y1 > y2) 
  14.145          {
  14.146                  video_blit_memtoscreen(32, 0, 0, 0, xsize, ysize);
  14.147 @@ -1163,7 +1138,7 @@
  14.148          cycles_lost += video_timing_w;
  14.149  
  14.150          if (svga_output) pclog("svga_writew: %05X ", addr);
  14.151 -        addr = (addr & 0xffff) + svga->write_bank;
  14.152 +        addr = (addr & svga->banked_mask) + svga->write_bank;
  14.153          addr &= 0x7FFFFF;        
  14.154          if (addr >= svga->vram_limit)
  14.155                  return;
  14.156 @@ -1191,7 +1166,7 @@
  14.157          cycles_lost += video_timing_l;
  14.158  
  14.159          if (svga_output) pclog("svga_writel: %05X ", addr);
  14.160 -        addr = (addr & 0xffff) + svga->write_bank;
  14.161 +        addr = (addr & svga->banked_mask) + svga->write_bank;
  14.162          addr &= 0x7FFFFF;
  14.163          if (addr >= svga->vram_limit)
  14.164                  return;
  14.165 @@ -1214,7 +1189,7 @@
  14.166          cycles_lost += video_timing_w;
  14.167  
  14.168  //        pclog("Readw %05X ", addr);
  14.169 -        addr = (addr & 0xffff) + svga->read_bank;
  14.170 +        addr = (addr & svga->banked_mask) + svga->read_bank;
  14.171          addr &= 0x7FFFFF;
  14.172  //        pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]);
  14.173          if (addr >= svga->vram_limit) return 0xffff;
  14.174 @@ -1235,7 +1210,7 @@
  14.175          cycles_lost += video_timing_l;
  14.176  
  14.177  //        pclog("Readl %05X ", addr);
  14.178 -        addr = (addr & 0xffff) + svga->read_bank;
  14.179 +        addr = (addr & svga->banked_mask) + svga->read_bank;
  14.180          addr &= 0x7FFFFF;
  14.181  //        pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]);
  14.182          if (addr >= svga->vram_limit) return 0xffffffff;
    15.1 --- a/src/vid_svga.h	Sat Nov 16 20:48:51 2013 +0000
    15.2 +++ b/src/vid_svga.h	Wed Nov 20 21:34:09 2013 +0000
    15.3 @@ -64,6 +64,7 @@
    15.4          uint8_t *vram;
    15.5          uint8_t *changedvram;
    15.6          int vrammask;
    15.7 +        uint32_t banked_mask;
    15.8  
    15.9          uint32_t write_bank, read_bank;
   15.10                  
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/vid_tgui9440.c	Wed Nov 20 21:34:09 2013 +0000
    16.3 @@ -0,0 +1,1133 @@
    16.4 +/*Trident TGUI9440 emulation*/
    16.5 +#include <stdlib.h>
    16.6 +#include "ibm.h"
    16.7 +#include "device.h"
    16.8 +#include "io.h"
    16.9 +#include "mem.h"
   16.10 +#include "video.h"
   16.11 +#include "vid_svga.h"
   16.12 +#include "vid_svga_render.h"
   16.13 +#include "vid_tkd8001_ramdac.h"
   16.14 +#include "vid_tgui9440.h"
   16.15 +
   16.16 +typedef struct tgui_t
   16.17 +{
   16.18 +        mem_mapping_t linear_mapping;
   16.19 +        mem_mapping_t accel_mapping;
   16.20 +
   16.21 +        svga_t svga;
   16.22 +
   16.23 +        struct
   16.24 +        {
   16.25 +        	uint16_t src_x, src_y;
   16.26 +        	uint16_t dst_x, dst_y;
   16.27 +        	uint16_t size_x, size_y;
   16.28 +        	uint16_t fg_col, bg_col;
   16.29 +        	uint8_t rop;
   16.30 +        	uint16_t flags;
   16.31 +        	uint8_t pattern[0x80];
   16.32 +        	int command;
   16.33 +        	int offset;
   16.34 +        	uint8_t ger22;
   16.35 +	
   16.36 +        	int x, y;
   16.37 +        	uint32_t src, dst, src_old, dst_old;
   16.38 +        	int pat_x, pat_y;
   16.39 +        	int use_src;
   16.40 +	
   16.41 +        	int pitch, bpp;
   16.42 +
   16.43 +                uint16_t tgui_pattern[8][8];
   16.44 +        } accel;
   16.45 +
   16.46 +        uint8_t tgui_3d8, tgui_3d9;
   16.47 +        int oldmode;
   16.48 +        uint8_t oldctrl2,newctrl2;
   16.49 +
   16.50 +        uint32_t linear_base, linear_size;
   16.51 +        
   16.52 +        int ramdac_state;
   16.53 +        uint8_t ramdac_ctrl;
   16.54 +        
   16.55 +        int clock_m, clock_n, clock_k;
   16.56 +} tgui_t;
   16.57 +
   16.58 +void tgui_recalcmapping(tgui_t *tgui);
   16.59 +
   16.60 +
   16.61 +uint8_t tgui_accel_read(uint32_t addr, void *priv);
   16.62 +uint16_t tgui_accel_read_w(uint32_t addr, void *priv);
   16.63 +uint32_t tgui_accel_read_l(uint32_t addr, void *priv);
   16.64 +
   16.65 +void tgui_accel_write(uint32_t addr, uint8_t val, void *priv);
   16.66 +void tgui_accel_write_w(uint32_t addr, uint16_t val, void *priv);
   16.67 +void tgui_accel_write_l(uint32_t addr, uint32_t val, void *priv);
   16.68 +
   16.69 +
   16.70 +void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv);
   16.71 +
   16.72 +void tgui_out(uint16_t addr, uint8_t val, void *p)
   16.73 +{
   16.74 +        tgui_t *tgui = (tgui_t *)p;
   16.75 +        svga_t *svga = &tgui->svga;
   16.76 +
   16.77 +        uint8_t old;
   16.78 +
   16.79 +//	pclog("tgui_out : %04X %02X  %04X:%04X  %i\n", addr, val, CS,pc, svga->bpp);
   16.80 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60;
   16.81 +
   16.82 +        switch (addr)
   16.83 +        {
   16.84 +                case 0x3C5:
   16.85 +                switch (svga->seqaddr & 0xf)
   16.86 +                {
   16.87 +                        case 0xB: 
   16.88 +                        tgui->oldmode=1; 
   16.89 +                        break;
   16.90 +                        case 0xC: 
   16.91 +                        if (svga->seqregs[0xe] & 0x80) 
   16.92 +                        svga->seqregs[0xc] = val; 
   16.93 +                        break;
   16.94 +                        case 0xd: 
   16.95 +                        if (tgui->oldmode) 
   16.96 +                                tgui->oldctrl2 = val; 
   16.97 +                        else 
   16.98 +                                tgui->newctrl2=val; 
   16.99 +                        break;
  16.100 +                        case 0xE:
  16.101 +                        svga->seqregs[0xe] = val ^ 2;
  16.102 +                        svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
  16.103 +                        if (!(svga->gdcreg[0xf] & 1)) 
  16.104 +                                svga->read_bank = svga->write_bank;
  16.105 +                        return;
  16.106 +                }
  16.107 +                break;
  16.108 +
  16.109 +                case 0x3C6:
  16.110 +                if (tgui->ramdac_state == 4)
  16.111 +                {
  16.112 +                        tgui->ramdac_state = 0;
  16.113 +                        tgui->ramdac_ctrl = val;
  16.114 +                        switch (tgui->ramdac_ctrl & 0xf0)
  16.115 +                        {
  16.116 +                                case 0x10:
  16.117 +                                svga->bpp = 15;
  16.118 +                                break;
  16.119 +                                case 0x30:
  16.120 +                                svga->bpp = 16;
  16.121 +                                break;
  16.122 +                                case 0xd0:
  16.123 +                                svga->bpp = 24;
  16.124 +                                break;
  16.125 +                                default:
  16.126 +                                svga->bpp = 8;
  16.127 +                                break;
  16.128 +                        }
  16.129 +                        return;
  16.130 +                }
  16.131 +                case 0x3C7: case 0x3C8: case 0x3C9:
  16.132 +                tgui->ramdac_state = 0;
  16.133 +		break;
  16.134 +
  16.135 +                case 0x3CF:
  16.136 +                switch (svga->gdcaddr & 15)
  16.137 +                {
  16.138 +			case 0x6:
  16.139 +			if (svga->gdcreg[6] != val)
  16.140 +			{
  16.141 +				svga->gdcreg[6] = val;
  16.142 +				tgui_recalcmapping(tgui);
  16.143 +			}
  16.144 +			return;
  16.145 +			
  16.146 +                        case 0xE:
  16.147 +                        svga->gdcreg[0xe] = val ^ 2;
  16.148 +                        if ((svga->gdcreg[0xf] & 1) == 1)
  16.149 +                           svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 65536;
  16.150 +                        break;
  16.151 +                        case 0xF:
  16.152 +                        if (val & 1) svga->read_bank = (svga->gdcreg[0xe]  & 0xf)  *65536;
  16.153 +                        else         svga->read_bank = (svga->seqregs[0xe] & 0xf)  *65536;
  16.154 +                        svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
  16.155 +                        break;
  16.156 +                }
  16.157 +                break;
  16.158 +                case 0x3D4:
  16.159 +		svga->crtcreg = val & 0x7f;
  16.160 +                return;
  16.161 +                case 0x3D5:
  16.162 +                if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
  16.163 +                old = svga->crtc[svga->crtcreg];
  16.164 +                svga->crtc[svga->crtcreg] = val;
  16.165 +//                if (svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X\n", svga->crtcreg, val);
  16.166 +                if (old != val)
  16.167 +                {
  16.168 +                        if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
  16.169 +                        {
  16.170 +                                svga->fullchange = changeframecount;
  16.171 +                                svga_recalctimings(svga);
  16.172 +                        }
  16.173 +                }
  16.174 +                switch (svga->crtcreg)
  16.175 +                {
  16.176 +			case 0x21:
  16.177 +			if (old != val)
  16.178 +			{
  16.179 +                                if (!PCI)
  16.180 +                                {
  16.181 +                                        tgui->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20;
  16.182 +                                        tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000;
  16.183 +                                }
  16.184 +        			tgui_recalcmapping(tgui);
  16.185 +                        }
  16.186 +			break;
  16.187 +
  16.188 +			case 0x40: case 0x41: case 0x42: case 0x43:
  16.189 +			case 0x44: case 0x45: case 0x46: case 0x47:
  16.190 +			svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff;
  16.191 +			svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff;
  16.192 +			svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f;
  16.193 +			svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f;
  16.194 +			svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x7) << 18) | (svga->hwcursor.yoff * 8);
  16.195 +			break;
  16.196 +			
  16.197 +			case 0x50:
  16.198 +			svga->hwcursor.ena = val & 0x80;
  16.199 +			break;
  16.200 +		}
  16.201 +                return;
  16.202 +                case 0x3D8:
  16.203 +                tgui->tgui_3d8 = val;
  16.204 +                if (svga->gdcreg[0xf] & 4)
  16.205 +                {
  16.206 +                        svga->write_bank = (val & 0x1f) * 65536;
  16.207 +//                                pclog("SVGAWBANK 3D8 %08X %04X:%04X\n",svgawbank,CS,pc);
  16.208 +                        if (!(svga->gdcreg[0xf] & 1))
  16.209 +                        {
  16.210 +                                svga->read_bank = (val & 0x1f) * 65536;
  16.211 +//                                        pclog("SVGARBANK 3D8 %08X %04X:%04X\n",svgarbank,CS,pc);
  16.212 +                        }
  16.213 +                }
  16.214 +                return;
  16.215 +                case 0x3D9:
  16.216 +                tgui->tgui_3d9 = val;
  16.217 +                if ((svga->gdcreg[0xf] & 5) == 5)
  16.218 +                {
  16.219 +                        svga->read_bank = (val & 0x1F) * 65536;
  16.220 +//                                pclog("SVGARBANK 3D9 %08X %04X:%04X\n",svgarbank,CS,pc);
  16.221 +                }
  16.222 +                return;
  16.223 +                
  16.224 +                case 0x43c8:
  16.225 +                tgui->clock_n = val & 0x7f;
  16.226 +                tgui->clock_m = (tgui->clock_m & ~1) | (val >> 7);
  16.227 +                break;
  16.228 +                case 0x43c9:
  16.229 +                tgui->clock_m = (tgui->clock_m & ~0x1e) | ((val << 1) & 0x1e);
  16.230 +                tgui->clock_k = (val & 0x10) >> 4;
  16.231 +                break;
  16.232 +        }
  16.233 +        svga_out(addr, val, svga);
  16.234 +}
  16.235 +
  16.236 +uint8_t tgui_in(uint16_t addr, void *p)
  16.237 +{
  16.238 +        tgui_t *tgui = (tgui_t *)p;
  16.239 +        svga_t *svga = &tgui->svga;
  16.240 +
  16.241 +//        if (addr != 0x3da) pclog("tgui_in : %04X  %04X:%04X\n", addr, CS,pc);
  16.242 +        
  16.243 +        if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60;
  16.244 +        
  16.245 +        switch (addr)
  16.246 +        {
  16.247 +                case 0x3C5:
  16.248 +                if ((svga->seqaddr & 0xf) == 0xb)
  16.249 +                {
  16.250 +//                        printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP));
  16.251 +                        tgui->oldmode = 0;
  16.252 +                        return 0xe3; /*TGUI9440AGi*/
  16.253 +                }
  16.254 +                if ((svga->seqaddr & 0xf) == 0xc)
  16.255 +                {
  16.256 +//                        printf("Read Trident Power Up 1 %04X:%04X %04X\n",CS,pc,readmemw(ss,SP));
  16.257 +//                        return 0x20; /*2 DRAM banks*/
  16.258 +                }
  16.259 +                if ((svga->seqaddr & 0xf) == 0xd)
  16.260 +                {
  16.261 +                        if (tgui->oldmode) return tgui->oldctrl2;
  16.262 +                        return tgui->newctrl2;
  16.263 +                }
  16.264 +                break;
  16.265 +                case 0x3C6:
  16.266 +                if (tgui->ramdac_state == 4)
  16.267 +                        return tgui->ramdac_ctrl;
  16.268 +                tgui->ramdac_state++;
  16.269 +                break;
  16.270 +                case 0x3C7: case 0x3C8: case 0x3C9:
  16.271 +                tgui->ramdac_state = 0;
  16.272 +                break;
  16.273 +                case 0x3D4:
  16.274 +                return svga->crtcreg;
  16.275 +                case 0x3D5:
  16.276 +                return svga->crtc[svga->crtcreg];
  16.277 +                case 0x3d8:
  16.278 +		return tgui->tgui_3d8;
  16.279 +		case 0x3d9:
  16.280 +		return tgui->tgui_3d9;
  16.281 +        }
  16.282 +        return svga_in(addr, svga);
  16.283 +}
  16.284 +
  16.285 +void tgui_recalctimings(svga_t *svga)
  16.286 +{
  16.287 +        tgui_t *tgui = (tgui_t *)svga->p;
  16.288 +
  16.289 +        if (svga->crtc[0x29] & 0x10)
  16.290 +                svga->rowoffset += 0x100;
  16.291 +
  16.292 +        if (svga->bpp == 24)
  16.293 +                svga->hdisp = (svga->crtc[1] + 1) * 8;
  16.294 +        
  16.295 +        if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000;
  16.296 +        if ((svga->crtc[0x27] & 0x01) == 0x01) svga->ma_latch |= 0x20000;
  16.297 +        if ((svga->crtc[0x27] & 0x02) == 0x02) svga->ma_latch |= 0x40000;
  16.298 +        
  16.299 +        if (tgui->oldctrl2 & 0x10)
  16.300 +        {
  16.301 +                svga->rowoffset <<= 1;
  16.302 +                svga->ma_latch <<= 1;
  16.303 +        }
  16.304 +        if (tgui->oldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/
  16.305 +           svga->lowres=0;
  16.306 +
  16.307 +	svga->lowres = !(svga->crtc[0x2a] & 0x40); 
  16.308 +
  16.309 +        svga->interlace = svga->crtc[0x1e] & 4;
  16.310 +        
  16.311 +        if (svga->miscout & 8)
  16.312 +                svga->clock = cpuclock / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k)));
  16.313 +
  16.314 +        if (svga->gdcreg[0xf] & 0x08)
  16.315 +                svga->clock *= 2;
  16.316 +        else if (svga->gdcreg[0xf] & 0x40)
  16.317 +                svga->clock *= 3;
  16.318 +                                
  16.319 +        if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40))
  16.320 +        {
  16.321 +                switch (svga->bpp)
  16.322 +                {
  16.323 +                        case 8: 
  16.324 +                        svga->render = svga_render_8bpp_highres; 
  16.325 +                        break;
  16.326 +                        case 15: 
  16.327 +                        svga->render = svga_render_15bpp_highres; 
  16.328 +                        break;
  16.329 +                        case 16: 
  16.330 +                        svga->render = svga_render_16bpp_highres; 
  16.331 +                        break;
  16.332 +                        case 24: 
  16.333 +                        svga->render = svga_render_24bpp_highres;
  16.334 +                        break;
  16.335 +                }
  16.336 +        }
  16.337 +}
  16.338 +
  16.339 +void tgui_recalcmapping(tgui_t *tgui)
  16.340 +{
  16.341 +        svga_t *svga = &tgui->svga;
  16.342 +        
  16.343 +//	pclog("tgui_recalcmapping : %02X %02X\n", svga->crtc[0x21], svga->gdcreg[6]);
  16.344 +
  16.345 +	if (svga->crtc[0x21] & 0x20)
  16.346 +	{
  16.347 +                mem_mapping_disable(&svga->mapping);
  16.348 +                mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size);
  16.349 +//		pclog("Trident linear framebuffer at %08X - size %06X\n", tgui->linear_base, tgui->linear_size);
  16.350 +                mem_mapping_enable(&tgui->accel_mapping);
  16.351 +	}
  16.352 +	else
  16.353 +	{
  16.354 +//                                pclog("Write mapping %02X\n", val);
  16.355 +                mem_mapping_disable(&tgui->linear_mapping);
  16.356 +                mem_mapping_disable(&tgui->accel_mapping);
  16.357 +                switch (svga->gdcreg[6] & 0xC)
  16.358 +                {
  16.359 +                        case 0x0: /*128k at A0000*/
  16.360 +                        mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
  16.361 +                        svga->banked_mask = 0xffff;
  16.362 +                        break;
  16.363 +                        case 0x4: /*64k at A0000*/
  16.364 +                        mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
  16.365 +                        mem_mapping_enable(&tgui->accel_mapping);
  16.366 +                        svga->banked_mask = 0xffff;
  16.367 +                        break;
  16.368 +                        case 0x8: /*32k at B0000*/
  16.369 +                        mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
  16.370 +                        svga->banked_mask = 0x7fff;
  16.371 +                        break;
  16.372 +                        case 0xC: /*32k at B8000*/
  16.373 +                        mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
  16.374 +                        svga->banked_mask = 0x7fff;
  16.375 +                        break;
  16.376 +		}
  16.377 +        }
  16.378 +}
  16.379 +
  16.380 +void tgui_hwcursor_draw(svga_t *svga, int displine)
  16.381 +{
  16.382 +        uint32_t dat[2];
  16.383 +        int xx;
  16.384 +        int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
  16.385 +        
  16.386 +        dat[0] = (svga->vram[svga->hwcursor_latch.addr]     << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
  16.387 +        dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7];
  16.388 +        for (xx = 0; xx < 32; xx++)
  16.389 +        {
  16.390 +                if (offset >= svga->hwcursor_latch.x)
  16.391 +                {
  16.392 +                        if (!(dat[0] & 0x80000000))
  16.393 +                                ((uint32_t *)buffer32->line[displine])[offset + 32]  = (dat[1] & 0x80000000) ? 0xffffff : 0;
  16.394 +                        else if (dat[1] & 0x80000000)
  16.395 +                                ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
  16.396 +//                        pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]);
  16.397 +                }
  16.398 +                           
  16.399 +                offset++;
  16.400 +                dat[0] <<= 1;
  16.401 +                dat[1] <<= 1;
  16.402 +        }
  16.403 +        svga->hwcursor_latch.addr += 8;
  16.404 +}
  16.405 +
  16.406 +uint8_t tgui_pci_read(int func, int addr, void *p)
  16.407 +{
  16.408 +        tgui_t *tgui = (tgui_t *)p;
  16.409 +        svga_t *svga = &tgui->svga;
  16.410 +
  16.411 +//        pclog("Trident PCI read %08X\n", addr);
  16.412 +
  16.413 +        switch (addr)
  16.414 +        {
  16.415 +                case 0x00: return 0x23; /*Trident*/
  16.416 +                case 0x01: return 0x10;
  16.417 +                
  16.418 +                case 0x02: return 0x40; /*TGUI9440 (9682)*/
  16.419 +                case 0x03: return 0x94;
  16.420 +                
  16.421 +                case 0x04: return 0x03; /*Respond to IO and memory accesses*/
  16.422 +
  16.423 +                case 0x07: return 1 << 1; /*Medium DEVSEL timing*/
  16.424 +                
  16.425 +                case 0x08: return 0; /*Revision ID*/
  16.426 +                case 0x09: return 0; /*Programming interface*/
  16.427 +                
  16.428 +                case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/
  16.429 +                case 0x0b: return 0x03;
  16.430 +                
  16.431 +                case 0x10: return 0x00; /*Linear frame buffer address*/
  16.432 +                case 0x11: return 0x00;
  16.433 +                case 0x12: return tgui->linear_base >> 16;
  16.434 +                case 0x13: return tgui->linear_base >> 24;
  16.435 +
  16.436 +                case 0x30: return 0x01; /*BIOS ROM address*/
  16.437 +                case 0x31: return 0x00;
  16.438 +                case 0x32: return 0x0C;
  16.439 +                case 0x33: return 0x00;
  16.440 +        }
  16.441 +        return 0;
  16.442 +}
  16.443 +
  16.444 +void tgui_pci_write(int func, int addr, uint8_t val, void *p)
  16.445 +{
  16.446 +        tgui_t *tgui = (tgui_t *)p;
  16.447 +        svga_t *svga = &tgui->svga;
  16.448 +
  16.449 +//        pclog("Trident PCI write %08X %02X\n", addr, val);
  16.450 +        
  16.451 +        switch (addr)
  16.452 +        {
  16.453 +                case 0x12:
  16.454 +                tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16);
  16.455 +                tgui->linear_size = 2 << 20;
  16.456 +                svga->crtc[0x21] = (svga->crtc[0x21] & ~0xf) | (val >> 4);
  16.457 +                tgui_recalcmapping(tgui);
  16.458 +                break;
  16.459 +                case 0x13:
  16.460 +                tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24);
  16.461 +                tgui->linear_size = 2 << 20;
  16.462 +                svga->crtc[0x21] = (svga->crtc[0x21] & ~0xc0) | (val >> 6);
  16.463 +                tgui_recalcmapping(tgui);
  16.464 +                break;
  16.465 +        }
  16.466 +}
  16.467 +
  16.468 +void *tgui8900d_init()
  16.469 +{
  16.470 +        tgui_t *tgui = malloc(sizeof(tgui_t));
  16.471 +        memset(tgui, 0, sizeof(tgui_t));
  16.472 +        
  16.473 +        svga_init(&tgui->svga, tgui, 1 << 20, /*1mb - chip supports 2mb, but drivers are buggy*/
  16.474 +                   tgui_recalctimings,
  16.475 +                   tgui_in, tgui_out,
  16.476 +                   NULL);
  16.477 +
  16.478 +        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);
  16.479 +        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);
  16.480 +        mem_mapping_disable(&tgui->linear_mapping);
  16.481 +        mem_mapping_disable(&tgui->accel_mapping);
  16.482 +        
  16.483 +        io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui);
  16.484 +
  16.485 +        return tgui;
  16.486 +}
  16.487 +void *tgui9440_init()
  16.488 +{
  16.489 +        tgui_t *tgui = malloc(sizeof(tgui_t));
  16.490 +        memset(tgui, 0, sizeof(tgui_t));
  16.491 +        
  16.492 +        svga_init(&tgui->svga, tgui, 1 << 21, /*2mb*/
  16.493 +                   tgui_recalctimings,
  16.494 +                   tgui_in, tgui_out,
  16.495 +                   tgui_hwcursor_draw);
  16.496 +
  16.497 +        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);
  16.498 +        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);
  16.499 +        mem_mapping_disable(&tgui->accel_mapping);
  16.500 +
  16.501 +        io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui);
  16.502 +        io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui);
  16.503 +
  16.504 +        pci_add(tgui_pci_read, tgui_pci_write, tgui);
  16.505 +
  16.506 +        return tgui;
  16.507 +}
  16.508 +
  16.509 +void tgui_close(void *p)
  16.510 +{
  16.511 +        tgui_t *tgui = (tgui_t *)p;
  16.512 +        
  16.513 +        svga_close(&tgui->svga);
  16.514 +        
  16.515 +        free(tgui);
  16.516 +}
  16.517 +
  16.518 +void tgui_speed_changed(void *p)
  16.519 +{
  16.520 +        tgui_t *tgui = (tgui_t *)p;
  16.521 +        
  16.522 +        svga_recalctimings(&tgui->svga);
  16.523 +}
  16.524 +
  16.525 +void tgui_force_redraw(void *p)
  16.526 +{
  16.527 +        tgui_t *tgui = (tgui_t *)p;
  16.528 +
  16.529 +        tgui->svga.fullchange = changeframecount;
  16.530 +}
  16.531 +
  16.532 +enum
  16.533 +{
  16.534 +	TGUI_BITBLT = 1
  16.535 +};
  16.536 +
  16.537 +enum
  16.538 +{
  16.539 +        TGUI_SRCCPU = 0,
  16.540 +        
  16.541 +	TGUI_SRCDISP = 0x04,	/*Source is from display*/
  16.542 +	TGUI_PATMONO = 0x20,	/*Pattern is monochrome and needs expansion*/
  16.543 +	TGUI_SRCMONO = 0x40,	/*Source is monochrome from CPU and needs expansion*/
  16.544 +	TGUI_TRANSENA  = 0x1000, /*Transparent (no draw when source == bg col)*/
  16.545 +	TGUI_TRANSREV  = 0x2000, /*Reverse fg/bg for transparent*/
  16.546 +	TGUI_SOLIDFILL = 0x4000	/*Pattern all zero?*/
  16.547 +};
  16.548 +
  16.549 +#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[addr & 0x1fffff]; \
  16.550 +                        else                     dat = vram_w[addr & 0xfffff];
  16.551 +                        
  16.552 +#define MIX() do \
  16.553 +	{								\
  16.554 +		out = 0;						\
  16.555 +        	for (c=0;c<16;c++)					\
  16.556 +	        {							\
  16.557 +			d=(dst_dat & (1<<c)) ? 1:0;			\
  16.558 +                       	if (src_dat & (1<<c)) d|=2;			\
  16.559 +               	        if (pat_dat & (1<<c)) d|=4;			\
  16.560 +                        if (tgui->accel.rop & (1<<d)) out|=(1<<c);	\
  16.561 +	        }							\
  16.562 +	} while (0)
  16.563 +
  16.564 +#define WRITE(addr, dat)        if (tgui->accel.bpp == 0)                                                \
  16.565 +                                {                                                                       \
  16.566 +                                        svga->vram[addr & 0x1fffff] = dat;                                    \
  16.567 +                                        svga->changedvram[((addr) & 0x1fffff) >> 10] = changeframecount;      \
  16.568 +                                }                                                                       \
  16.569 +                                else                                                                    \
  16.570 +                                {                                                                       \
  16.571 +                                        vram_w[addr & 0xfffff] = dat;                                   \
  16.572 +                                        svga->changedvram[((addr) & 0xfffff) >> 9] = changeframecount;        \
  16.573 +                                }
  16.574 +                                
  16.575 +void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv);
  16.576 +void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv);
  16.577 +
  16.578 +void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
  16.579 +{
  16.580 +        svga_t *svga = &tgui->svga;
  16.581 +	int x, y;
  16.582 +	int c, d;
  16.583 +	uint16_t src_dat, dst_dat, pat_dat;
  16.584 +	uint16_t out;
  16.585 +	int xdir = (tgui->accel.flags & 0x200) ? -1 : 1;
  16.586 +	int ydir = (tgui->accel.flags & 0x100) ? -1 : 1;
  16.587 +	uint16_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col;
  16.588 +        uint16_t *vram_w = (uint16_t *)svga->vram;
  16.589 +        
  16.590 +	if (tgui->accel.bpp == 0)
  16.591 +                trans_col &= 0xff;
  16.592 +	
  16.593 +	if (count != -1 && !tgui->accel.x)
  16.594 +	{
  16.595 +		count -= tgui->accel.offset;
  16.596 +		cpu_dat <<= tgui->accel.offset;
  16.597 +	}
  16.598 +	if (count == -1)
  16.599 +	{
  16.600 +		tgui->accel.x = tgui->accel.y = 0;
  16.601 +	}
  16.602 +	if (tgui->accel.flags & TGUI_SOLIDFILL)
  16.603 +	{
  16.604 +//		pclog("SOLIDFILL\n");
  16.605 +		for (y = 0; y < 8; y++)
  16.606 +		{
  16.607 +			for (x = 0; x < 8; x++)
  16.608 +			{
  16.609 +				tgui->accel.tgui_pattern[y][x] = tgui->accel.fg_col;
  16.610 +			}
  16.611 +		}
  16.612 +	}
  16.613 +	else if (tgui->accel.flags & TGUI_PATMONO)
  16.614 +	{
  16.615 +//		pclog("PATMONO\n");
  16.616 +		for (y = 0; y < 8; y++)
  16.617 +		{
  16.618 +			for (x = 0; x < 8; x++)
  16.619 +			{
  16.620 +				tgui->accel.tgui_pattern[y][x] = (tgui->accel.pattern[y] & (1 << x)) ? tgui->accel.fg_col : tgui->accel.bg_col;
  16.621 +			}
  16.622 +		}
  16.623 +	}
  16.624 +	else
  16.625 +	{
  16.626 +                if (tgui->accel.bpp == 0)
  16.627 +                {
  16.628 +//        		pclog("OTHER 8-bit\n");
  16.629 +        		for (y = 0; y < 8; y++)
  16.630 +        		{
  16.631 +        			for (x = 0; x < 8; x++)
  16.632 +        			{
  16.633 +        				tgui->accel.tgui_pattern[y][x] = tgui->accel.pattern[x + y*8];
  16.634 +        			}
  16.635 +                        }
  16.636 +		}
  16.637 +		else
  16.638 +                {
  16.639 +//        		pclog("OTHER 16-bit\n");
  16.640 +        		for (y = 0; y < 8; y++)
  16.641 +        		{
  16.642 +        			for (x = 0; x < 8; x++)
  16.643 +        			{
  16.644 +        				tgui->accel.tgui_pattern[y][x] = tgui->accel.pattern[x*2 + y*16] | (tgui->accel.pattern[x*2 + y*16 + 1] << 8);
  16.645 +        			}
  16.646 +                        }
  16.647 +		}
  16.648 +	}
  16.649 +/*	for (y = 0; y < 8; y++)
  16.650 +	{
  16.651 +		if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tgui->accel.tgui_pattern[y][0], tgui->accel.tgui_pattern[y][1], tgui->accel.tgui_pattern[y][2], tgui->accel.tgui_pattern[y][3], tgui->accel.tgui_pattern[y][4], tgui->accel.tgui_pattern[y][5], tgui->accel.tgui_pattern[y][6], tgui->accel.tgui_pattern[y][7]);
  16.652 +	}*/
  16.653 +//	if (count == -1) pclog("Command %i %i %p\n", tgui->accel.command, TGUI_BITBLT, tgui);
  16.654 +        switch (tgui->accel.command)
  16.655 +	{
  16.656 +		case TGUI_BITBLT:
  16.657 +//		if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tgui->accel.src_x, tgui->accel.src_y, tgui->accel.dst_x, tgui->accel.dst_y, tgui->accel.size_x, tgui->accel.size_y, tgui->accel.flags);
  16.658 +		if (count == -1)
  16.659 +		{
  16.660 +			tgui->accel.src = tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch);
  16.661 +			tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch);
  16.662 +			tgui->accel.pat_x = tgui->accel.dst_x;
  16.663 +			tgui->accel.pat_y = tgui->accel.dst_y;
  16.664 +		}
  16.665 +
  16.666 +		switch (tgui->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP))
  16.667 +		{
  16.668 +			case TGUI_SRCCPU:
  16.669 +			if (count == -1)
  16.670 +			{
  16.671 +//				pclog("Blit start  TGUI_SRCCPU\n");
  16.672 +				if (svga->crtc[0x21] & 0x20)
  16.673 +                                        mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l);
  16.674 +
  16.675 +				if (tgui->accel.use_src)
  16.676 +                                        return;
  16.677 +			}
  16.678 +			else
  16.679 +			     count >>= 3;
  16.680 +//			pclog("TGUI_SRCCPU\n");
  16.681 +			while (count)
  16.682 +			{
  16.683 +				if (tgui->accel.bpp == 0)
  16.684 +				{
  16.685 +                                        src_dat = cpu_dat >> 24;
  16.686 +                                        cpu_dat <<= 8;
  16.687 +                                }
  16.688 +                                else
  16.689 +                                {
  16.690 +                                        src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00);
  16.691 +                                        cpu_dat <<= 16;
  16.692 +                                        count--;
  16.693 +                                }
  16.694 +				READ(tgui->accel.dst, dst_dat);
  16.695 +				pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7];
  16.696 +	
  16.697 +                                if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  16.698 +                                {
  16.699 +        				MIX();
  16.700 +	
  16.701 +                                        WRITE(tgui->accel.dst, out);
  16.702 +                                }
  16.703 +
  16.704 +//				pclog("  %i,%i  %02X %02X %02X  %02X\n", tgui->accel.x, tgui->accel.y, src_dat,dst_dat,pat_dat, out);
  16.705 +                                	
  16.706 +				tgui->accel.src += xdir;
  16.707 +				tgui->accel.dst += xdir;
  16.708 +				tgui->accel.pat_x += xdir;
  16.709 +	
  16.710 +				tgui->accel.x++;
  16.711 +				if (tgui->accel.x > tgui->accel.size_x)
  16.712 +				{
  16.713 +					tgui->accel.x = 0;
  16.714 +					tgui->accel.y++;
  16.715 +					
  16.716 +					tgui->accel.pat_x = tgui->accel.dst_x;
  16.717 +	
  16.718 +					tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch);
  16.719 +					tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch);
  16.720 +					tgui->accel.pat_y += ydir;
  16.721 +					
  16.722 +					if (tgui->accel.y > tgui->accel.size_y)
  16.723 +					{
  16.724 +						if (svga->crtc[0x21] & 0x20)
  16.725 +						{
  16.726 +//							pclog("Blit end\n");
  16.727 +                                                        mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear);
  16.728 +						}
  16.729 +						return;
  16.730 +					}
  16.731 +					if (tgui->accel.use_src)
  16.732 +                                                return;
  16.733 +				}
  16.734 +				count--;
  16.735 +			}
  16.736 +			break;
  16.737 +						
  16.738 +			case TGUI_SRCMONO | TGUI_SRCCPU:
  16.739 +			if (count == -1)
  16.740 +			{
  16.741 +//				pclog("Blit start  TGUI_SRCMONO | TGUI_SRCCPU\n");
  16.742 +				if (svga->crtc[0x21] & 0x20)
  16.743 +                                        mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l);
  16.744 +
  16.745 +//                                pclog(" %i\n", tgui->accel.command);
  16.746 +				if (tgui->accel.use_src)
  16.747 +                                        return;
  16.748 +			}
  16.749 +//			pclog("TGUI_SRCMONO | TGUI_SRCCPU\n");
  16.750 +			while (count)
  16.751 +			{
  16.752 +				src_dat = ((cpu_dat >> 31) ? tgui->accel.fg_col : tgui->accel.bg_col);
  16.753 +				if (tgui->accel.bpp == 0)
  16.754 +				    src_dat &= 0xff;
  16.755 +				    
  16.756 +				READ(tgui->accel.dst, dst_dat);
  16.757 +				pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7];
  16.758 +
  16.759 +                                if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  16.760 +                                {
  16.761 +        				MIX();
  16.762 +
  16.763 +				        WRITE(tgui->accel.dst, out);
  16.764 +                                }
  16.765 +//				pclog("  %i,%i  %02X %02X %02X  %02X %i\n", tgui->accel.x, tgui->accel.y, src_dat,dst_dat,pat_dat, out, (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col));
  16.766 +				cpu_dat <<= 1;
  16.767 +				tgui->accel.src += xdir;
  16.768 +				tgui->accel.dst += xdir;
  16.769 +				tgui->accel.pat_x += xdir;
  16.770 +	
  16.771 +				tgui->accel.x++;
  16.772 +				if (tgui->accel.x > tgui->accel.size_x)
  16.773 +				{
  16.774 +					tgui->accel.x = 0;
  16.775 +					tgui->accel.y++;
  16.776 +					
  16.777 +					tgui->accel.pat_x = tgui->accel.dst_x;
  16.778 +	
  16.779 +					tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch);
  16.780 +					tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch);
  16.781 +					tgui->accel.pat_y += ydir;
  16.782 +					
  16.783 +					if (tgui->accel.y > tgui->accel.size_y)
  16.784 +					{
  16.785 +						if (svga->crtc[0x21] & 0x20)
  16.786 +						{
  16.787 +//							pclog("Blit end\n");
  16.788 +                                                        mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear);
  16.789 +						}
  16.790 +						return;
  16.791 +					}
  16.792 +					if (tgui->accel.use_src)
  16.793 +                                                return;
  16.794 +				}
  16.795 +				count--;
  16.796 +			}
  16.797 +			break;
  16.798 +
  16.799 +			default:
  16.800 +			while (count)
  16.801 +			{
  16.802 +				READ(tgui->accel.src, src_dat);
  16.803 +				READ(tgui->accel.dst, dst_dat);                                                                
  16.804 +				pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7];
  16.805 +	
  16.806 +                                if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  16.807 +                                {
  16.808 +        				MIX();
  16.809 +	
  16.810 +                                        WRITE(tgui->accel.dst, out);
  16.811 +                                }
  16.812 +//                                pclog("  %i,%i  %02X %02X %02X  %02X\n", tgui->accel.x, tgui->accel.y, src_dat,dst_dat,pat_dat, out);
  16.813 +	
  16.814 +				tgui->accel.src += xdir;
  16.815 +				tgui->accel.dst += xdir;
  16.816 +				tgui->accel.pat_x += xdir;
  16.817 +	
  16.818 +				tgui->accel.x++;
  16.819 +				if (tgui->accel.x > tgui->accel.size_x)
  16.820 +				{
  16.821 +					tgui->accel.x = 0;
  16.822 +					tgui->accel.y++;
  16.823 +					
  16.824 +					tgui->accel.pat_x = tgui->accel.dst_x;
  16.825 +	
  16.826 +					tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch);
  16.827 +					tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch);
  16.828 +					tgui->accel.pat_y += ydir;
  16.829 +					
  16.830 +					if (tgui->accel.y > tgui->accel.size_y)
  16.831 +						return;
  16.832 +				}
  16.833 +				count--;
  16.834 +			}
  16.835 +			break;
  16.836 +		}
  16.837 +		break;
  16.838 +	}
  16.839 +}
  16.840 +
  16.841 +void tgui_accel_write(uint32_t addr, uint8_t val, void *p)
  16.842 +{
  16.843 +        tgui_t *tgui = (tgui_t *)p;
  16.844 +//	pclog("tgui_accel_write : %08X %02X  %04X(%08X):%08X %02X\n", addr, val, CS,cs,pc, opcode);
  16.845 +	if ((addr & ~0xff) != 0xbff00)
  16.846 +		return;
  16.847 +	switch (addr & 0xff)
  16.848 +	{
  16.849 +                case 0x22:
  16.850 +                tgui->accel.ger22 = val;
  16.851 +                tgui->accel.pitch = 512 << ((val >> 2) & 3);
  16.852 +                tgui->accel.bpp = (val & 3) ? 1 : 0;
  16.853 +                tgui->accel.pitch >>= tgui->accel.bpp;
  16.854 +                break;
  16.855 +                
  16.856 +		case 0x24: /*Command*/
  16.857 +		tgui->accel.command = val;
  16.858 +		tgui_accel_command(-1, 0, tgui);
  16.859 +		break;
  16.860 +		
  16.861 +		case 0x27: /*ROP*/
  16.862 +		tgui->accel.rop = val;
  16.863 +		tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33);
  16.864 +//		pclog("Write ROP %02X %i\n", val, tgui->accel.use_src);
  16.865 +		break;
  16.866 +		
  16.867 +		case 0x28: /*Flags*/
  16.868 +		tgui->accel.flags = (tgui->accel.flags & 0xff00) | val;
  16.869 +		break;
  16.870 +		case 0x29: /*Flags*/
  16.871 +		tgui->accel.flags = (tgui->accel.flags & 0xff) | (val << 8);
  16.872 +		break;
  16.873 +
  16.874 +		case 0x2b:
  16.875 +		tgui->accel.offset = val & 7;
  16.876 +		break;
  16.877 +		
  16.878 +		case 0x2c: /*Foreground colour*/
  16.879 +		tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00) | val;
  16.880 +		break;
  16.881 +		case 0x2d: /*Foreground colour*/
  16.882 +		tgui->accel.fg_col = (tgui->accel.fg_col & 0xff) | (val << 8);
  16.883 +		break;
  16.884 +
  16.885 +		case 0x30: /*Background colour*/
  16.886 +		tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00) | val;
  16.887 +		break;
  16.888 +		case 0x31: /*Background colour*/
  16.889 +		tgui->accel.bg_col = (tgui->accel.bg_col & 0xff) | (val << 8);
  16.890 +		break;
  16.891 +
  16.892 +		case 0x38: /*Dest X*/
  16.893 +		tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val;
  16.894 +		break;
  16.895 +		case 0x39: /*Dest X*/
  16.896 +		tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8);
  16.897 +		break;
  16.898 +		case 0x3a: /*Dest Y*/
  16.899 +		tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val;
  16.900 +		break;
  16.901 +		case 0x3b: /*Dest Y*/
  16.902 +		tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8);
  16.903 +		break;
  16.904 +
  16.905 +		case 0x3c: /*Src X*/
  16.906 +		tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val;
  16.907 +		break;
  16.908 +		case 0x3d: /*Src X*/
  16.909 +		tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8);
  16.910 +		break;
  16.911 +		case 0x3e: /*Src Y*/
  16.912 +		tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val;
  16.913 +		break;
  16.914 +		case 0x3f: /*Src Y*/
  16.915 +		tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8);
  16.916 +		break;
  16.917 +
  16.918 +		case 0x40: /*Size X*/
  16.919 +		tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val;
  16.920 +		break;
  16.921 +		case 0x41: /*Size X*/
  16.922 +		tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8);
  16.923 +		break;
  16.924 +		case 0x42: /*Size Y*/
  16.925 +		tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val;
  16.926 +		break;
  16.927 +		case 0x43: /*Size Y*/
  16.928 +		tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8);
  16.929 +		break;
  16.930 +		
  16.931 +		case 0x80: case 0x81: case 0x82: case 0x83:
  16.932 +		case 0x84: case 0x85: case 0x86: case 0x87:
  16.933 +		case 0x88: case 0x89: case 0x8a: case 0x8b:
  16.934 +		case 0x8c: case 0x8d: case 0x8e: case 0x8f:
  16.935 +		case 0x90: case 0x91: case 0x92: case 0x93:
  16.936 +		case 0x94: case 0x95: case 0x96: case 0x97:
  16.937 +		case 0x98: case 0x99: case 0x9a: case 0x9b:
  16.938 +		case 0x9c: case 0x9d: case 0x9e: case 0x9f:
  16.939 +		case 0xa0: case 0xa1: case 0xa2: case 0xa3:
  16.940 +		case 0xa4: case 0xa5: case 0xa6: case 0xa7:
  16.941 +		case 0xa8: case 0xa9: case 0xaa: case 0xab:
  16.942 +		case 0xac: case 0xad: case 0xae: case 0xaf:
  16.943 +		case 0xb0: case 0xb1: case 0xb2: case 0xb3:
  16.944 +		case 0xb4: case 0xb5: case 0xb6: case 0xb7:
  16.945 +		case 0xb8: case 0xb9: case 0xba: case 0xbb:
  16.946 +		case 0xbc: case 0xbd: case 0xbe: case 0xbf:
  16.947 +		case 0xc0: case 0xc1: case 0xc2: case 0xc3:
  16.948 +		case 0xc4: case 0xc5: case 0xc6: case 0xc7:
  16.949 +		case 0xc8: case 0xc9: case 0xca: case 0xcb:
  16.950 +		case 0xcc: case 0xcd: case 0xce: case 0xcf:
  16.951 +		case 0xd0: case 0xd1: case 0xd2: case 0xd3:
  16.952 +		case 0xd4: case 0xd5: case 0xd6: case 0xd7:
  16.953 +		case 0xd8: case 0xd9: case 0xda: case 0xdb:
  16.954 +		case 0xdc: case 0xdd: case 0xde: case 0xdf:
  16.955 +		case 0xe0: case 0xe1: case 0xe2: case 0xe3:
  16.956 +		case 0xe4: case 0xe5: case 0xe6: case 0xe7:
  16.957 +		case 0xe8: case 0xe9: case 0xea: case 0xeb:
  16.958 +		case 0xec: case 0xed: case 0xee: case 0xef:
  16.959 +		case 0xf0: case 0xf1: case 0xf2: case 0xf3:
  16.960 +		case 0xf4: case 0xf5: case 0xf6: case 0xf7:
  16.961 +		case 0xf8: case 0xf9: case 0xfa: case 0xfb:
  16.962 +		case 0xfc: case 0xfd: case 0xfe: case 0xff:
  16.963 +		tgui->accel.pattern[addr & 0x7f] = val;
  16.964 +		break;
  16.965 +	}
  16.966 +}
  16.967 +
  16.968 +void tgui_accel_write_w(uint32_t addr, uint16_t val, void *p)
  16.969 +{
  16.970 +        tgui_t *tgui = (tgui_t *)p;
  16.971 +//	pclog("tgui_accel_write_w %08X %04X\n", addr, val);
  16.972 +	tgui_accel_write(addr, val, tgui);
  16.973 +	tgui_accel_write(addr + 1, val >> 8, tgui);
  16.974 +}
  16.975 +
  16.976 +void tgui_accel_write_l(uint32_t addr, uint32_t val, void *p)
  16.977 +{
  16.978 +        tgui_t *tgui = (tgui_t *)p;
  16.979 +//	pclog("tgui_accel_write_l %08X %08X\n", addr, val);
  16.980 +	tgui_accel_write(addr, val, tgui);
  16.981 +	tgui_accel_write(addr + 1, val >> 8, tgui);
  16.982 +	tgui_accel_write(addr + 2, val >> 16, tgui);
  16.983 +	tgui_accel_write(addr + 3, val >> 24, tgui);
  16.984 +}
  16.985 +
  16.986 +uint8_t tgui_accel_read(uint32_t addr, void *p)
  16.987 +{
  16.988 +        tgui_t *tgui = (tgui_t *)p;
  16.989 +//	pclog("tgui_accel_read : %08X\n", addr);
  16.990 +	if ((addr & ~0xff) != 0xbff00)
  16.991 +		return 0xff;
  16.992 +	switch (addr & 0xff)
  16.993 +	{
  16.994 +		case 0x20: /*Status*/
  16.995 +		return 0;
  16.996 +		
  16.997 +		case 0x27: /*ROP*/
  16.998 +		return tgui->accel.rop;
  16.999 +		
 16.1000 +		case 0x28: /*Flags*/
 16.1001 +		return tgui->accel.flags & 0xff;
 16.1002 +		case 0x29: /*Flags*/
 16.1003 +		return tgui->accel.flags >> 8;
 16.1004 +
 16.1005 +		case 0x2b:
 16.1006 +		return tgui->accel.offset;
 16.1007 +		
 16.1008 +		case 0x2c: /*Background colour*/
 16.1009 +		return tgui->accel.bg_col & 0xff;
 16.1010 +		case 0x2d: /*Background colour*/
 16.1011 +		return tgui->accel.bg_col >> 8;
 16.1012 +
 16.1013 +		case 0x30: /*Foreground colour*/
 16.1014 +		return tgui->accel.fg_col & 0xff;
 16.1015 +		case 0x31: /*Foreground colour*/
 16.1016 +		return tgui->accel.fg_col >> 8;
 16.1017 +
 16.1018 +		case 0x38: /*Dest X*/
 16.1019 +		return tgui->accel.dst_x & 0xff;
 16.1020 +		case 0x39: /*Dest X*/
 16.1021 +		return tgui->accel.dst_x >> 8;
 16.1022 +		case 0x3a: /*Dest Y*/
 16.1023 +		return tgui->accel.dst_y & 0xff;
 16.1024 +		case 0x3b: /*Dest Y*/
 16.1025 +		return tgui->accel.dst_y >> 8;
 16.1026 +
 16.1027 +		case 0x3c: /*Src X*/
 16.1028 +		return tgui->accel.src_x & 0xff;
 16.1029 +		case 0x3d: /*Src X*/
 16.1030 +		return tgui->accel.src_x >> 8;
 16.1031 +		case 0x3e: /*Src Y*/
 16.1032 +		return tgui->accel.src_y & 0xff;
 16.1033 +		case 0x3f: /*Src Y*/
 16.1034 +		return tgui->accel.src_y >> 8;
 16.1035 +
 16.1036 +		case 0x40: /*Size X*/
 16.1037 +		return tgui->accel.size_x & 0xff;
 16.1038 +		case 0x41: /*Size X*/
 16.1039 +		return tgui->accel.size_x >> 8;
 16.1040 +		case 0x42: /*Size Y*/
 16.1041 +		return tgui->accel.size_y & 0xff;
 16.1042 +		case 0x43: /*Size Y*/
 16.1043 +		return tgui->accel.size_y >> 8;
 16.1044 +		
 16.1045 +		case 0x80: case 0x81: case 0x82: case 0x83:
 16.1046 +		case 0x84: case 0x85: case 0x86: case 0x87:
 16.1047 +		case 0x88: case 0x89: case 0x8a: case 0x8b:
 16.1048 +		case 0x8c: case 0x8d: case 0x8e: case 0x8f:
 16.1049 +		case 0x90: case 0x91: case 0x92: case 0x93:
 16.1050 +		case 0x94: case 0x95: case 0x96: case 0x97:
 16.1051 +		case 0x98: case 0x99: case 0x9a: case 0x9b:
 16.1052 +		case 0x9c: case 0x9d: case 0x9e: case 0x9f:
 16.1053 +		case 0xa0: case 0xa1: case 0xa2: case 0xa3:
 16.1054 +		case 0xa4: case 0xa5: case 0xa6: case 0xa7:
 16.1055 +		case 0xa8: case 0xa9: case 0xaa: case 0xab:
 16.1056 +		case 0xac: case 0xad: case 0xae: case 0xaf:
 16.1057 +		case 0xb0: case 0xb1: case 0xb2: case 0xb3:
 16.1058 +		case 0xb4: case 0xb5: case 0xb6: case 0xb7:
 16.1059 +		case 0xb8: case 0xb9: case 0xba: case 0xbb:
 16.1060 +		case 0xbc: case 0xbd: case 0xbe: case 0xbf:
 16.1061 +		case 0xc0: case 0xc1: case 0xc2: case 0xc3:
 16.1062 +		case 0xc4: case 0xc5: case 0xc6: case 0xc7:
 16.1063 +		case 0xc8: case 0xc9: case 0xca: case 0xcb:
 16.1064 +		case 0xcc: case 0xcd: case 0xce: case 0xcf:
 16.1065 +		case 0xd0: case 0xd1: case 0xd2: case 0xd3:
 16.1066 +		case 0xd4: case 0xd5: case 0xd6: case 0xd7:
 16.1067 +		case 0xd8: case 0xd9: case 0xda: case 0xdb:
 16.1068 +		case 0xdc: case 0xdd: case 0xde: case 0xdf:
 16.1069 +		case 0xe0: case 0xe1: case 0xe2: case 0xe3:
 16.1070 +		case 0xe4: case 0xe5: case 0xe6: case 0xe7:
 16.1071 +		case 0xe8: case 0xe9: case 0xea: case 0xeb:
 16.1072 +		case 0xec: case 0xed: case 0xee: case 0xef:
 16.1073 +		case 0xf0: case 0xf1: case 0xf2: case 0xf3:
 16.1074 +		case 0xf4: case 0xf5: case 0xf6: case 0xf7:
 16.1075 +		case 0xf8: case 0xf9: case 0xfa: case 0xfb:
 16.1076 +		case 0xfc: case 0xfd: case 0xfe: case 0xff:
 16.1077 +		return tgui->accel.pattern[addr & 0x7f];
 16.1078 +	}
 16.1079 +	return 0xff;
 16.1080 +}
 16.1081 +
 16.1082 +uint16_t tgui_accel_read_w(uint32_t addr, void *p)
 16.1083 +{
 16.1084 +        tgui_t *tgui = (tgui_t *)p;
 16.1085 +//	pclog("tgui_accel_read_w %08X\n", addr);
 16.1086 +	return tgui_accel_read(addr, tgui) | (tgui_accel_read(addr + 1, tgui) << 8);
 16.1087 +}
 16.1088 +
 16.1089 +uint32_t tgui_accel_read_l(uint32_t addr, void *p)
 16.1090 +{
 16.1091 +        tgui_t *tgui = (tgui_t *)p;
 16.1092 +//	pclog("tgui_accel_read_l %08X\n", addr);
 16.1093 +	return tgui_accel_read_w(addr, tgui) | (tgui_accel_read_w(addr + 2, tgui) << 16);
 16.1094 +}
 16.1095 +
 16.1096 +void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *p)
 16.1097 +{
 16.1098 +        svga_t *svga = (svga_t *)p;
 16.1099 +        tgui_t *tgui = (tgui_t *)svga->p;
 16.1100 +//	pclog("tgui_accel_write_fb_b %08X %02X\n", addr, val);
 16.1101 +	tgui_accel_command(8, val << 24, tgui);
 16.1102 +}
 16.1103 +
 16.1104 +void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *p)
 16.1105 +{
 16.1106 +        svga_t *svga = (svga_t *)p;
 16.1107 +        tgui_t *tgui = (tgui_t *)svga->p;
 16.1108 +//	pclog("tgui_accel_write_fb_w %08X %04X\n", addr, val);
 16.1109 +	tgui_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tgui);
 16.1110 +}
 16.1111 +
 16.1112 +void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p)
 16.1113 +{
 16.1114 +        svga_t *svga = (svga_t *)p;
 16.1115 +        tgui_t *tgui = (tgui_t *)svga->p;
 16.1116 +//	pclog("tgui_accel_write_fb_l %08X %08X\n", addr, val);
 16.1117 +	tgui_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tgui);
 16.1118 +}
 16.1119 +
 16.1120 +int tgui_add_status_info(char *s, int max_len, void *p)
 16.1121 +{
 16.1122 +        tgui_t *tgui = (tgui_t *)p;
 16.1123 +        
 16.1124 +        return svga_add_status_info(s, max_len, &tgui->svga);
 16.1125 +}
 16.1126 +
 16.1127 +device_t tgui9440_device =
 16.1128 +{
 16.1129 +        "Trident TGUI 9440",
 16.1130 +        tgui9440_init,
 16.1131 +        tgui_close,
 16.1132 +        NULL,
 16.1133 +        tgui_speed_changed,
 16.1134 +        tgui_force_redraw,
 16.1135 +        tgui_add_status_info
 16.1136 +};
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/vid_tgui9440.h	Wed Nov 20 21:34:09 2013 +0000
    17.3 @@ -0,0 +1,1 @@
    17.4 +extern device_t tgui9440_device;
    18.1 --- a/src/vid_tvga.c	Sat Nov 16 20:48:51 2013 +0000
    18.2 +++ b/src/vid_tvga.c	Wed Nov 20 21:34:09 2013 +0000
    18.3 @@ -18,50 +18,12 @@
    18.4          svga_t svga;
    18.5          tkd8001_ramdac_t ramdac;
    18.6  
    18.7 -        struct
    18.8 -        {
    18.9 -        	uint16_t src_x, src_y;
   18.10 -        	uint16_t dst_x, dst_y;
   18.11 -        	uint16_t size_x, size_y;
   18.12 -        	uint16_t fg_col, bg_col;
   18.13 -        	uint8_t rop;
   18.14 -        	uint16_t flags;
   18.15 -        	uint8_t pattern[0x80];
   18.16 -        	int command;
   18.17 -        	int offset;
   18.18 -        	uint8_t ger22;
   18.19 -	
   18.20 -        	int x, y;
   18.21 -        	uint32_t src, dst, src_old, dst_old;
   18.22 -        	int pat_x, pat_y;
   18.23 -        	int use_src;
   18.24 -	
   18.25 -        	int pitch, bpp;
   18.26 -
   18.27 -                uint16_t tvga_pattern[8][8];
   18.28 -        } accel;
   18.29 -
   18.30          uint8_t tvga_3d8, tvga_3d9;
   18.31          int oldmode;
   18.32 -        uint8_t oldctrl2,newctrl2;
   18.33 -
   18.34 -        uint32_t linear_base, linear_size;
   18.35 +        uint8_t oldctrl1;
   18.36 +        uint8_t oldctrl2, newctrl2;
   18.37  } tvga_t;
   18.38  
   18.39 -void tvga_recalcmapping(tvga_t *tvga);
   18.40 -
   18.41 -
   18.42 -uint8_t tvga_accel_read(uint32_t addr, void *priv);
   18.43 -uint16_t tvga_accel_read_w(uint32_t addr, void *priv);
   18.44 -uint32_t tvga_accel_read_l(uint32_t addr, void *priv);
   18.45 -
   18.46 -void tvga_accel_write(uint32_t addr, uint8_t val, void *priv);
   18.47 -void tvga_accel_write_w(uint32_t addr, uint16_t val, void *priv);
   18.48 -void tvga_accel_write_l(uint32_t addr, uint32_t val, void *priv);
   18.49 -
   18.50 -
   18.51 -void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv);
   18.52 -
   18.53  void tvga_out(uint16_t addr, uint8_t val, void *p)
   18.54  {
   18.55          tvga_t *tvga = (tvga_t *)p;
   18.56 @@ -88,36 +50,29 @@
   18.57                          if (tvga->oldmode) 
   18.58                                  tvga->oldctrl2 = val; 
   18.59                          else 
   18.60 -                                tvga->newctrl2=val; 
   18.61 +                                tvga->newctrl2 = val; 
   18.62                          break;
   18.63                          case 0xE:
   18.64 -                        svga->seqregs[0xe] = val ^ 2;
   18.65 -                        svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
   18.66 -                        if (!(svga->gdcreg[0xf] & 1)) 
   18.67 -                                svga->read_bank = svga->write_bank;
   18.68 +                        if (tvga->oldmode) 
   18.69 +                                tvga->oldctrl1 = val; 
   18.70 +                        else 
   18.71 +                        {
   18.72 +                                svga->seqregs[0xe] = val ^ 2;
   18.73 +                                svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
   18.74 +                                if (!(svga->gdcreg[0xf] & 1)) 
   18.75 +                                        svga->read_bank = svga->write_bank;
   18.76 +                        }
   18.77                          return;
   18.78                  }
   18.79                  break;
   18.80  
   18.81                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
   18.82 -		if (gfxcard != GFX_TGUI9440)
   18.83 -		{
   18.84 -                	tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga);
   18.85 -                	return;
   18.86 -		}
   18.87 -		break;
   18.88 +                tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga);
   18.89 +                return;
   18.90  
   18.91                  case 0x3CF:
   18.92                  switch (svga->gdcaddr & 15)
   18.93                  {
   18.94 -			case 0x6:
   18.95 -			if (svga->gdcreg[6] != val)
   18.96 -			{
   18.97 -				svga->gdcreg[6] = val;
   18.98 -				tvga_recalcmapping(tvga);
   18.99 -			}
  18.100 -			return;
  18.101 -			
  18.102                          case 0xE:
  18.103                          svga->gdcreg[0xe] = val ^ 2;
  18.104                          if ((svga->gdcreg[0xf] & 1) == 1)
  18.105 @@ -131,8 +86,7 @@
  18.106                  }
  18.107                  break;
  18.108                  case 0x3D4:
  18.109 -		if (gfxcard == GFX_TGUI9440)	svga->crtcreg = val & 0x7f;
  18.110 -		else				svga->crtcreg = val & 0x3f;
  18.111 +		svga->crtcreg = val & 0x3f;
  18.112                  return;
  18.113                  case 0x3D5:
  18.114                  if (svga->crtcreg <= 7 && svga->crtc[0x11] & 0x80) return;
  18.115 @@ -147,44 +101,6 @@
  18.116                                  svga_recalctimings(svga);
  18.117                          }
  18.118                  }
  18.119 -                switch (svga->crtcreg)
  18.120 -                {
  18.121 -			case 0x21:
  18.122 -			if (old != val)
  18.123 -			{
  18.124 -                                if (!PCI)
  18.125 -                                {
  18.126 -                                        tvga->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20;
  18.127 -                                        tvga->linear_size = (val & 0x10) ? 0x200000 : 0x100000;
  18.128 -                                }
  18.129 -        			tvga_recalcmapping(tvga);
  18.130 -                        }
  18.131 -			break;
  18.132 -
  18.133 -
  18.134 -			case 0x38: /*Pixel bus register*/
  18.135 -//			pclog("Pixel bus register %02X\n", val);
  18.136 -			if (gfxcard != GFX_TGUI9440)
  18.137 -				break;
  18.138 -			
  18.139 -			if ((val & 0xc) == 4)	svga->bpp = 16;
  18.140 -			else if (!(val & 0xc))	svga->bpp = 8;
  18.141 -			else			svga->bpp = 24;
  18.142 -			break;
  18.143 -
  18.144 -			case 0x40: case 0x41: case 0x42: case 0x43:
  18.145 -			case 0x44: case 0x45: case 0x46: case 0x47:
  18.146 -			svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff;
  18.147 -			svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff;
  18.148 -			svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f;
  18.149 -			svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f;
  18.150 -			svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x7) << 18) | (svga->hwcursor.yoff * 8);
  18.151 -			break;
  18.152 -			
  18.153 -			case 0x50:
  18.154 -			svga->hwcursor.ena = val & 0x80;
  18.155 -			break;
  18.156 -		}
  18.157                  return;
  18.158                  case 0x3D8:
  18.159                  tvga->tvga_3d8 = val;
  18.160 @@ -227,8 +143,7 @@
  18.161                  {
  18.162  //                        printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP));
  18.163                          tvga->oldmode = 0;
  18.164 -                        if (gfxcard == GFX_TVGA) return 0x33; /*TVGA8900D*/
  18.165 -                        else                     return 0xe3; /*TGUI9440AGi*/
  18.166 +                        return 0x33; /*TVGA8900D*/
  18.167                  }
  18.168                  if ((svga->seqaddr & 0xf) == 0xc)
  18.169                  {
  18.170 @@ -242,9 +157,7 @@
  18.171                  }
  18.172                  break;
  18.173                  case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
  18.174 -		if (gfxcard != GFX_TGUI9440)
  18.175 -                	return tkd8001_ramdac_in(addr, &tvga->ramdac, svga);
  18.176 -                break;
  18.177 +                return tkd8001_ramdac_in(addr, &tvga->ramdac, svga);
  18.178                  case 0x3D4:
  18.179                  return svga->crtcreg;
  18.180                  case 0x3D5:
  18.181 @@ -266,7 +179,7 @@
  18.182          if (svga->crtc[0x29] & 0x10)
  18.183                  svga->rowoffset += 0x100;
  18.184  
  18.185 -        if (gfxcard == GFX_TGUI9440 && svga->bpp == 24)
  18.186 +        if (svga->bpp == 24)
  18.187                  svga->hdisp = (svga->crtc[1] + 1) * 8;
  18.188          
  18.189          if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000;
  18.190 @@ -278,19 +191,16 @@
  18.191                  svga->rowoffset <<= 1;
  18.192                  svga->ma_latch <<= 1;
  18.193          }
  18.194 -        if (tvga->oldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/
  18.195 -           svga->lowres=0;
  18.196 -        if (gfxcard == GFX_TGUI9440)
  18.197 -	   svga->lowres = !(svga->crtc[0x2a] & 0x40); 
  18.198 +        if (svga->gdcreg[0xf] & 0x08)
  18.199 +        {
  18.200 +                svga->htotal *= 2;
  18.201 +                svga->hdisp *= 2;
  18.202 +                svga->hdisp_time *= 2;
  18.203 +        }
  18.204  	   
  18.205 -        if (svga->gdcreg[0xf] & 8)
  18.206 -        {
  18.207 -                svga->htotal <<= 1;
  18.208 -                svga->hdisp <<= 1;
  18.209 -        }
  18.210          svga->interlace = svga->crtc[0x1e] & 4;
  18.211          if (svga->interlace)
  18.212 -           svga->rowoffset >>= 1;
  18.213 +                svga->rowoffset >>= 1;
  18.214          
  18.215          switch (((svga->miscout >> 2) & 3) | ((tvga->newctrl2 << 2) & 4))
  18.216          {
  18.217 @@ -302,7 +212,7 @@
  18.218                  case 7: svga->clock = cpuclock/40000000.0; break;
  18.219          }
  18.220  
  18.221 -        if ((tvga->oldctrl2 & 0x10) || (gfxcard == GFX_TGUI9440 && (svga->crtc[0x2a] & 0x40)))
  18.222 +        if (tvga->oldctrl2 & 0x10)
  18.223          {
  18.224                  switch (svga->bpp)
  18.225                  {
  18.226 @@ -311,142 +221,18 @@
  18.227                          break;
  18.228                          case 15: 
  18.229                          svga->render = svga_render_15bpp_highres; 
  18.230 +                        svga->hdisp /= 2;
  18.231                          break;
  18.232                          case 16: 
  18.233                          svga->render = svga_render_16bpp_highres; 
  18.234 +                        svga->hdisp /= 2;
  18.235                          break;
  18.236                          case 24: 
  18.237 -                        svga->render = svga_render_24bpp_highres; 
  18.238 -                        break;
  18.239 -                        case 32: 
  18.240 -                        svga->render = svga_render_32bpp_highres; 
  18.241 +                        svga->render = svga_render_24bpp_highres;
  18.242 +                        svga->hdisp /= 3;
  18.243                          break;
  18.244                  }
  18.245 -        }
  18.246 -}
  18.247 -
  18.248 -void tvga_recalcmapping(tvga_t *tvga)
  18.249 -{
  18.250 -        svga_t *svga = &tvga->svga;
  18.251 -        
  18.252 -//	pclog("tvga_recalcmapping : %02X %02X\n", svga->crtc[0x21], svga->gdcreg[6]);
  18.253 -
  18.254 -	if (svga->crtc[0x21] & 0x20)
  18.255 -	{
  18.256 -                mem_mapping_disable(&svga->mapping);
  18.257 -                mem_mapping_set_addr(&tvga->linear_mapping, tvga->linear_base, tvga->linear_size);
  18.258 -//		pclog("Trident linear framebuffer at %08X - size %06X\n", tvga->linear_base, tvga->linear_size);
  18.259 -                mem_mapping_enable(&tvga->accel_mapping);
  18.260 -	}
  18.261 -	else
  18.262 -	{
  18.263 -//                                pclog("Write mapping %02X\n", val);
  18.264 -                mem_mapping_disable(&tvga->linear_mapping);
  18.265 -                mem_mapping_disable(&tvga->accel_mapping);
  18.266 -                switch (svga->gdcreg[6] & 0xC)
  18.267 -                {
  18.268 -                        case 0x0: /*128k at A0000*/
  18.269 -                        mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
  18.270 -                        break;
  18.271 -                        case 0x4: /*64k at A0000*/
  18.272 -                        mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
  18.273 -                        mem_mapping_enable(&tvga->accel_mapping);
  18.274 -                        break;
  18.275 -                        case 0x8: /*32k at B0000*/
  18.276 -                        mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
  18.277 -                        break;
  18.278 -                        case 0xC: /*32k at B8000*/
  18.279 -                        mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
  18.280 -                        break;
  18.281 -		}
  18.282 -        }
  18.283 -}
  18.284 -
  18.285 -void tvga_hwcursor_draw(svga_t *svga, int displine)
  18.286 -{
  18.287 -        uint32_t dat[2];
  18.288 -        int xx;
  18.289 -        int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
  18.290 -        
  18.291 -        dat[0] = (svga->vram[svga->hwcursor_latch.addr]     << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
  18.292 -        dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7];
  18.293 -        for (xx = 0; xx < 32; xx++)
  18.294 -        {
  18.295 -                if (offset >= svga->hwcursor_latch.x)
  18.296 -                {
  18.297 -                        if (!(dat[0] & 0x80000000))
  18.298 -                                ((uint32_t *)buffer32->line[displine])[offset + 32]  = (dat[1] & 0x80000000) ? 0xffffff : 0;
  18.299 -                        else if (dat[1] & 0x80000000)
  18.300 -                                ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff;
  18.301 -//                        pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]);
  18.302 -                }
  18.303 -                           
  18.304 -                offset++;
  18.305 -                dat[0] <<= 1;
  18.306 -                dat[1] <<= 1;
  18.307 -        }
  18.308 -        svga->hwcursor_latch.addr += 8;
  18.309 -}
  18.310 -
  18.311 -uint8_t tvga_pci_read(int func, int addr, void *p)
  18.312 -{
  18.313 -        tvga_t *tvga = (tvga_t *)p;
  18.314 -        svga_t *svga = &tvga->svga;
  18.315 -
  18.316 -//        pclog("Trident PCI read %08X\n", addr);
  18.317 -
  18.318 -        switch (addr)
  18.319 -        {
  18.320 -                case 0x00: return 0x23; /*Trident*/
  18.321 -                case 0x01: return 0x10;
  18.322 -                
  18.323 -                case 0x02: return 0x40; /*TGUI9440 (9682)*/
  18.324 -                case 0x03: return 0x94;
  18.325 -                
  18.326 -                case 0x04: return 0x03; /*Respond to IO and memory accesses*/
  18.327 -
  18.328 -                case 0x07: return 1 << 1; /*Medium DEVSEL timing*/
  18.329 -                
  18.330 -                case 0x08: return 0; /*Revision ID*/
  18.331 -                case 0x09: return 0; /*Programming interface*/
  18.332 -                
  18.333 -                case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/
  18.334 -                case 0x0b: return 0x03;
  18.335 -                
  18.336 -                case 0x10: return 0x00; /*Linear frame buffer address*/
  18.337 -                case 0x11: return 0x00;
  18.338 -                case 0x12: return tvga->linear_base >> 16;
  18.339 -                case 0x13: return tvga->linear_base >> 24;
  18.340 -
  18.341 -                case 0x30: return 0x01; /*BIOS ROM address*/
  18.342 -                case 0x31: return 0x00;
  18.343 -                case 0x32: return 0x0C;
  18.344 -                case 0x33: return 0x00;
  18.345 -        }
  18.346 -        return 0;
  18.347 -}
  18.348 -
  18.349 -void tvga_pci_write(int func, int addr, uint8_t val, void *p)
  18.350 -{
  18.351 -        tvga_t *tvga = (tvga_t *)p;
  18.352 -        svga_t *svga = &tvga->svga;
  18.353 -
  18.354 -//        pclog("Trident PCI write %08X %02X\n", addr, val);
  18.355 -        
  18.356 -        switch (addr)
  18.357 -        {
  18.358 -                case 0x12:
  18.359 -                tvga->linear_base = (tvga->linear_base & 0xff000000) | ((val & 0xe0) << 16);
  18.360 -                tvga->linear_size = 2 << 20;
  18.361 -                svga->crtc[0x21] = (svga->crtc[0x21] & ~0xf) | (val >> 4);
  18.362 -                tvga_recalcmapping(tvga);
  18.363 -                break;
  18.364 -                case 0x13:
  18.365 -                tvga->linear_base = (tvga->linear_base & 0xe00000) | (val << 24);
  18.366 -                tvga->linear_size = 2 << 20;
  18.367 -                svga->crtc[0x21] = (svga->crtc[0x21] & ~0xc0) | (val >> 6);
  18.368 -                tvga_recalcmapping(tvga);
  18.369 -                break;
  18.370 +                svga->lowres = 0;
  18.371          }
  18.372  }
  18.373  
  18.374 @@ -459,41 +245,16 @@
  18.375                     tvga_recalctimings,
  18.376                     tvga_in, tvga_out,
  18.377                     NULL);
  18.378 -
  18.379 -        mem_mapping_add(&tvga->linear_mapping, 0,       0,      svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &tvga->svga);
  18.380 -        mem_mapping_add(&tvga->accel_mapping,  0xbc000, 0x4000, tvga_accel_read,  tvga_accel_read_w, tvga_accel_read_l, tvga_accel_write,  tvga_accel_write_w, tvga_accel_write_l,  tvga);
  18.381 -        mem_mapping_disable(&tvga->linear_mapping);
  18.382 -        mem_mapping_disable(&tvga->accel_mapping);
  18.383 -        
  18.384 +       
  18.385          io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga);
  18.386  
  18.387          return tvga;
  18.388  }
  18.389 -void *tgui9440_init()
  18.390 -{
  18.391 -        tvga_t *tvga = malloc(sizeof(tvga_t));
  18.392 -        memset(tvga, 0, sizeof(tvga_t));
  18.393 -        
  18.394 -        svga_init(&tvga->svga, tvga, 1 << 21, /*2mb*/
  18.395 -                   tvga_recalctimings,
  18.396 -                   tvga_in, tvga_out,
  18.397 -                   tvga_hwcursor_draw);
  18.398 -
  18.399 -        mem_mapping_add(&tvga->linear_mapping, 0,       0,      svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, &tvga->svga);
  18.400 -        mem_mapping_add(&tvga->accel_mapping,  0xbc000, 0x4000, tvga_accel_read,  tvga_accel_read_w, tvga_accel_read_l, tvga_accel_write,  tvga_accel_write_w, tvga_accel_write_l,  tvga);
  18.401 -        mem_mapping_disable(&tvga->accel_mapping);
  18.402 -
  18.403 -        io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga);
  18.404 -
  18.405 -        pci_add(tvga_pci_read, tvga_pci_write, tvga);
  18.406 -
  18.407 -        return tvga;
  18.408 -}
  18.409  
  18.410  void tvga_close(void *p)
  18.411  {
  18.412          tvga_t *tvga = (tvga_t *)p;
  18.413 -
  18.414 +        
  18.415          svga_close(&tvga->svga);
  18.416          
  18.417          free(tvga);
  18.418 @@ -513,592 +274,11 @@
  18.419          tvga->svga.fullchange = changeframecount;
  18.420  }
  18.421  
  18.422 -enum
  18.423 -{
  18.424 -	TGUI_BITBLT = 1
  18.425 -};
  18.426 -
  18.427 -enum
  18.428 -{
  18.429 -        TGUI_SRCCPU = 0,
  18.430 -        
  18.431 -	TGUI_SRCDISP = 0x04,	/*Source is from display*/
  18.432 -	TGUI_PATMONO = 0x20,	/*Pattern is monochrome and needs expansion*/
  18.433 -	TGUI_SRCMONO = 0x40,	/*Source is monochrome from CPU and needs expansion*/
  18.434 -	TGUI_TRANSENA  = 0x1000, /*Transparent (no draw when source == bg col)*/
  18.435 -	TGUI_TRANSREV  = 0x2000, /*Reverse fg/bg for transparent*/
  18.436 -	TGUI_SOLIDFILL = 0x4000	/*Pattern all zero?*/
  18.437 -};
  18.438 -
  18.439 -#define READ(addr, dat) if (tvga->accel.bpp == 0) dat = svga->vram[addr & 0x1fffff]; \
  18.440 -                        else                     dat = vram_w[addr & 0xfffff];
  18.441 -                        
  18.442 -#define MIX() do \
  18.443 -	{								\
  18.444 -		out = 0;						\
  18.445 -        	for (c=0;c<16;c++)					\
  18.446 -	        {							\
  18.447 -			d=(dst_dat & (1<<c)) ? 1:0;			\
  18.448 -                       	if (src_dat & (1<<c)) d|=2;			\
  18.449 -               	        if (pat_dat & (1<<c)) d|=4;			\
  18.450 -                        if (tvga->accel.rop & (1<<d)) out|=(1<<c);	\
  18.451 -	        }							\
  18.452 -	} while (0)
  18.453 -
  18.454 -#define WRITE(addr, dat)        if (tvga->accel.bpp == 0)                                                \
  18.455 -                                {                                                                       \
  18.456 -                                        svga->vram[addr & 0x1fffff] = dat;                                    \
  18.457 -                                        svga->changedvram[((addr) & 0x1fffff) >> 10] = changeframecount;      \
  18.458 -                                }                                                                       \
  18.459 -                                else                                                                    \
  18.460 -                                {                                                                       \
  18.461 -                                        vram_w[addr & 0xfffff] = dat;                                   \
  18.462 -                                        svga->changedvram[((addr) & 0xfffff) >> 9] = changeframecount;        \
  18.463 -                                }
  18.464 -                                
  18.465 -void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv);
  18.466 -void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv);
  18.467 -
  18.468 -void tvga_accel_command(int count, uint32_t cpu_dat, tvga_t *tvga)
  18.469 -{
  18.470 -        svga_t *svga = &tvga->svga;
  18.471 -	int x, y;
  18.472 -	int c, d;
  18.473 -	uint16_t src_dat, dst_dat, pat_dat;
  18.474 -	uint16_t out;
  18.475 -	int xdir = (tvga->accel.flags & 0x200) ? -1 : 1;
  18.476 -	int ydir = (tvga->accel.flags & 0x100) ? -1 : 1;
  18.477 -	uint16_t trans_col = (tvga->accel.flags & TGUI_TRANSREV) ? tvga->accel.fg_col : tvga->accel.bg_col;
  18.478 -        uint16_t *vram_w = (uint16_t *)svga->vram;
  18.479 -        
  18.480 -	if (tvga->accel.bpp == 0)
  18.481 -                trans_col &= 0xff;
  18.482 -	
  18.483 -	if (count != -1 && !tvga->accel.x)
  18.484 -	{
  18.485 -		count -= tvga->accel.offset;
  18.486 -		cpu_dat <<= tvga->accel.offset;
  18.487 -	}
  18.488 -	if (count == -1)
  18.489 -	{
  18.490 -		tvga->accel.x = tvga->accel.y = 0;
  18.491 -	}
  18.492 -	if (tvga->accel.flags & TGUI_SOLIDFILL)
  18.493 -	{
  18.494 -//		pclog("SOLIDFILL\n");
  18.495 -		for (y = 0; y < 8; y++)
  18.496 -		{
  18.497 -			for (x = 0; x < 8; x++)
  18.498 -			{
  18.499 -				tvga->accel.tvga_pattern[y][x] = tvga->accel.fg_col;
  18.500 -			}
  18.501 -		}
  18.502 -	}
  18.503 -	else if (tvga->accel.flags & TGUI_PATMONO)
  18.504 -	{
  18.505 -//		pclog("PATMONO\n");
  18.506 -		for (y = 0; y < 8; y++)
  18.507 -		{
  18.508 -			for (x = 0; x < 8; x++)
  18.509 -			{
  18.510 -				tvga->accel.tvga_pattern[y][x] = (tvga->accel.pattern[y] & (1 << x)) ? tvga->accel.fg_col : tvga->accel.bg_col;
  18.511 -			}
  18.512 -		}
  18.513 -	}
  18.514 -	else
  18.515 -	{
  18.516 -                if (tvga->accel.bpp == 0)
  18.517 -                {
  18.518 -//        		pclog("OTHER 8-bit\n");
  18.519 -        		for (y = 0; y < 8; y++)
  18.520 -        		{
  18.521 -        			for (x = 0; x < 8; x++)
  18.522 -        			{
  18.523 -        				tvga->accel.tvga_pattern[y][x] = tvga->accel.pattern[x + y*8];
  18.524 -        			}
  18.525 -                        }
  18.526 -		}
  18.527 -		else
  18.528 -                {
  18.529 -//        		pclog("OTHER 16-bit\n");
  18.530 -        		for (y = 0; y < 8; y++)
  18.531 -        		{
  18.532 -        			for (x = 0; x < 8; x++)
  18.533 -        			{
  18.534 -        				tvga->accel.tvga_pattern[y][x] = tvga->accel.pattern[x*2 + y*16] | (tvga->accel.pattern[x*2 + y*16 + 1] << 8);
  18.535 -        			}
  18.536 -                        }
  18.537 -		}
  18.538 -	}
  18.539 -/*	for (y = 0; y < 8; y++)
  18.540 -	{
  18.541 -		if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tvga->accel.tvga_pattern[y][0], tvga->accel.tvga_pattern[y][1], tvga->accel.tvga_pattern[y][2], tvga->accel.tvga_pattern[y][3], tvga->accel.tvga_pattern[y][4], tvga->accel.tvga_pattern[y][5], tvga->accel.tvga_pattern[y][6], tvga->accel.tvga_pattern[y][7]);
  18.542 -	}*/
  18.543 -//	if (count == -1) pclog("Command %i %i %p\n", tvga->accel.command, TGUI_BITBLT, tvga);
  18.544 -        switch (tvga->accel.command)
  18.545 -	{
  18.546 -		case TGUI_BITBLT:
  18.547 -//		if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tvga->accel.src_x, tvga->accel.src_y, tvga->accel.dst_x, tvga->accel.dst_y, tvga->accel.size_x, tvga->accel.size_y, tvga->accel.flags);
  18.548 -		if (count == -1)
  18.549 -		{
  18.550 -			tvga->accel.src = tvga->accel.src_old = tvga->accel.src_x + (tvga->accel.src_y * tvga->accel.pitch);
  18.551 -			tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_x + (tvga->accel.dst_y * tvga->accel.pitch);
  18.552 -			tvga->accel.pat_x = tvga->accel.dst_x;
  18.553 -			tvga->accel.pat_y = tvga->accel.dst_y;
  18.554 -		}
  18.555 -
  18.556 -		switch (tvga->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP))
  18.557 -		{
  18.558 -			case TGUI_SRCCPU:
  18.559 -			if (count == -1)
  18.560 -			{
  18.561 -//				pclog("Blit start  TGUI_SRCCPU\n");
  18.562 -				if (svga->crtc[0x21] & 0x20)
  18.563 -                                        mem_mapping_set_handler(&tvga->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l);
  18.564 -
  18.565 -				if (tvga->accel.use_src)
  18.566 -                                        return;
  18.567 -			}
  18.568 -			else
  18.569 -			     count >>= 3;
  18.570 -//			pclog("TGUI_SRCCPU\n");
  18.571 -			while (count)
  18.572 -			{
  18.573 -				if (tvga->accel.bpp == 0)
  18.574 -				{
  18.575 -                                        src_dat = cpu_dat >> 24;
  18.576 -                                        cpu_dat <<= 8;
  18.577 -                                }
  18.578 -                                else
  18.579 -                                {
  18.580 -                                        src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00);
  18.581 -                                        cpu_dat <<= 16;
  18.582 -                                        count--;
  18.583 -                                }
  18.584 -				READ(tvga->accel.dst, dst_dat);
  18.585 -				pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7];
  18.586 -	
  18.587 -                                if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  18.588 -                                {
  18.589 -        				MIX();
  18.590 -	
  18.591 -                                        WRITE(tvga->accel.dst, out);
  18.592 -                                }
  18.593 -
  18.594 -//				pclog("  %i,%i  %02X %02X %02X  %02X\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out);
  18.595 -                                	
  18.596 -				tvga->accel.src += xdir;
  18.597 -				tvga->accel.dst += xdir;
  18.598 -				tvga->accel.pat_x += xdir;
  18.599 -	
  18.600 -				tvga->accel.x++;
  18.601 -				if (tvga->accel.x > tvga->accel.size_x)
  18.602 -				{
  18.603 -					tvga->accel.x = 0;
  18.604 -					tvga->accel.y++;
  18.605 -					
  18.606 -					tvga->accel.pat_x = tvga->accel.dst_x;
  18.607 -	
  18.608 -					tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch);
  18.609 -					tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch);
  18.610 -					tvga->accel.pat_y += ydir;
  18.611 -					
  18.612 -					if (tvga->accel.y > tvga->accel.size_y)
  18.613 -					{
  18.614 -						if (svga->crtc[0x21] & 0x20)
  18.615 -						{
  18.616 -//							pclog("Blit end\n");
  18.617 -                                                        mem_mapping_set_handler(&tvga->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear);
  18.618 -						}
  18.619 -						return;
  18.620 -					}
  18.621 -					if (tvga->accel.use_src)
  18.622 -                                                return;
  18.623 -				}
  18.624 -				count--;
  18.625 -			}
  18.626 -			break;
  18.627 -						
  18.628 -			case TGUI_SRCMONO | TGUI_SRCCPU:
  18.629 -			if (count == -1)
  18.630 -			{
  18.631 -//				pclog("Blit start  TGUI_SRCMONO | TGUI_SRCCPU\n");
  18.632 -				if (svga->crtc[0x21] & 0x20)
  18.633 -                                        mem_mapping_set_handler(&tvga->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, tvga_accel_write_fb_b, tvga_accel_write_fb_w, tvga_accel_write_fb_l);
  18.634 -
  18.635 -//                                pclog(" %i\n", tvga->accel.command);
  18.636 -				if (tvga->accel.use_src)
  18.637 -                                        return;
  18.638 -			}
  18.639 -//			pclog("TGUI_SRCMONO | TGUI_SRCCPU\n");
  18.640 -			while (count)
  18.641 -			{
  18.642 -				src_dat = ((cpu_dat >> 31) ? tvga->accel.fg_col : tvga->accel.bg_col);
  18.643 -				if (tvga->accel.bpp == 0)
  18.644 -				    src_dat &= 0xff;
  18.645 -				    
  18.646 -				READ(tvga->accel.dst, dst_dat);
  18.647 -				pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7];
  18.648 -
  18.649 -                                if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  18.650 -                                {
  18.651 -        				MIX();
  18.652 -
  18.653 -				        WRITE(tvga->accel.dst, out);
  18.654 -                                }
  18.655 -//				pclog("  %i,%i  %02X %02X %02X  %02X %i\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out, (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col));
  18.656 -				cpu_dat <<= 1;
  18.657 -				tvga->accel.src += xdir;
  18.658 -				tvga->accel.dst += xdir;
  18.659 -				tvga->accel.pat_x += xdir;
  18.660 -	
  18.661 -				tvga->accel.x++;
  18.662 -				if (tvga->accel.x > tvga->accel.size_x)
  18.663 -				{
  18.664 -					tvga->accel.x = 0;
  18.665 -					tvga->accel.y++;
  18.666 -					
  18.667 -					tvga->accel.pat_x = tvga->accel.dst_x;
  18.668 -	
  18.669 -					tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch);
  18.670 -					tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch);
  18.671 -					tvga->accel.pat_y += ydir;
  18.672 -					
  18.673 -					if (tvga->accel.y > tvga->accel.size_y)
  18.674 -					{
  18.675 -						if (svga->crtc[0x21] & 0x20)
  18.676 -						{
  18.677 -//							pclog("Blit end\n");
  18.678 -                                                        mem_mapping_set_handler(&tvga->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear);
  18.679 -						}
  18.680 -						return;
  18.681 -					}
  18.682 -					if (tvga->accel.use_src)
  18.683 -                                                return;
  18.684 -				}
  18.685 -				count--;
  18.686 -			}
  18.687 -			break;
  18.688 -
  18.689 -			default:
  18.690 -			while (count)
  18.691 -			{
  18.692 -				READ(tvga->accel.src, src_dat);
  18.693 -				READ(tvga->accel.dst, dst_dat);                                                                
  18.694 -				pat_dat = tvga->accel.tvga_pattern[tvga->accel.pat_y & 7][tvga->accel.pat_x & 7];
  18.695 -	
  18.696 -                                if (!(tvga->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)
  18.697 -                                {
  18.698 -        				MIX();
  18.699 -	
  18.700 -                                        WRITE(tvga->accel.dst, out);
  18.701 -                                }
  18.702 -//                                pclog("  %i,%i  %02X %02X %02X  %02X\n", tvga->accel.x, tvga->accel.y, src_dat,dst_dat,pat_dat, out);
  18.703 -	
  18.704 -				tvga->accel.src += xdir;
  18.705 -				tvga->accel.dst += xdir;
  18.706 -				tvga->accel.pat_x += xdir;
  18.707 -	
  18.708 -				tvga->accel.x++;
  18.709 -				if (tvga->accel.x > tvga->accel.size_x)
  18.710 -				{
  18.711 -					tvga->accel.x = 0;
  18.712 -					tvga->accel.y++;
  18.713 -					
  18.714 -					tvga->accel.pat_x = tvga->accel.dst_x;
  18.715 -	
  18.716 -					tvga->accel.src = tvga->accel.src_old = tvga->accel.src_old + (ydir * tvga->accel.pitch);
  18.717 -					tvga->accel.dst = tvga->accel.dst_old = tvga->accel.dst_old + (ydir * tvga->accel.pitch);
  18.718 -					tvga->accel.pat_y += ydir;
  18.719 -					
  18.720 -					if (tvga->accel.y > tvga->accel.size_y)
  18.721 -						return;
  18.722 -				}
  18.723 -				count--;
  18.724 -			}
  18.725 -			break;
  18.726 -		}
  18.727 -		break;
  18.728 -	}
  18.729 -}
  18.730 -
  18.731 -void tvga_accel_write(uint32_t addr, uint8_t val, void *p)
  18.732 +int tvga_add_status_info(char *s, int max_len, void *p)
  18.733  {
  18.734          tvga_t *tvga = (tvga_t *)p;
  18.735 -//	pclog("tvga_accel_write : %08X %02X  %04X(%08X):%08X %02X\n", addr, val, CS,cs,pc, opcode);
  18.736 -	if ((addr & ~0xff) != 0xbff00)
  18.737 -		return;
  18.738 -	switch (addr & 0xff)
  18.739 -	{
  18.740 -                case 0x22:
  18.741 -                tvga->accel.ger22 = val;
  18.742 -                tvga->accel.pitch = 512 << ((val >> 2) & 3);
  18.743 -                tvga->accel.bpp = (val & 3) ? 1 : 0;
  18.744 -                tvga->accel.pitch >>= tvga->accel.bpp;
  18.745 -                break;
  18.746 -                
  18.747 -		case 0x24: /*Command*/
  18.748 -		tvga->accel.command = val;
  18.749 -		tvga_accel_command(-1, 0, tvga);
  18.750 -		break;
  18.751 -		
  18.752 -		case 0x27: /*ROP*/
  18.753 -		tvga->accel.rop = val;
  18.754 -		tvga->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33);
  18.755 -//		pclog("Write ROP %02X %i\n", val, tvga->accel.use_src);
  18.756 -		break;
  18.757 -		
  18.758 -		case 0x28: /*Flags*/
  18.759 -		tvga->accel.flags = (tvga->accel.flags & 0xff00) | val;
  18.760 -		break;
  18.761 -		case 0x29: /*Flags*/
  18.762 -		tvga->accel.flags = (tvga->accel.flags & 0xff) | (val << 8);
  18.763 -		break;
  18.764 -
  18.765 -		case 0x2b:
  18.766 -		tvga->accel.offset = val & 7;
  18.767 -		break;
  18.768 -		
  18.769 -		case 0x2c: /*Foreground colour*/
  18.770 -		tvga->accel.fg_col = (tvga->accel.fg_col & 0xff00) | val;
  18.771 -		break;
  18.772 -		case 0x2d: /*Foreground colour*/
  18.773 -		tvga->accel.fg_col = (tvga->accel.fg_col & 0xff) | (val << 8);
  18.774 -		break;
  18.775 -
  18.776 -		case 0x30: /*Background colour*/
  18.777 -		tvga->accel.bg_col = (tvga->accel.bg_col & 0xff00) | val;
  18.778 -		break;
  18.779 -		case 0x31: /*Background colour*/
  18.780 -		tvga->accel.bg_col = (tvga->accel.bg_col & 0xff) | (val << 8);
  18.781 -		break;
  18.782 -
  18.783 -		case 0x38: /*Dest X*/
  18.784 -		tvga->accel.dst_x = (tvga->accel.dst_x & 0xff00) | val;
  18.785 -		break;
  18.786 -		case 0x39: /*Dest X*/
  18.787 -		tvga->accel.dst_x = (tvga->accel.dst_x & 0xff) | (val << 8);
  18.788 -		break;
  18.789 -		case 0x3a: /*Dest Y*/
  18.790 -		tvga->accel.dst_y = (tvga->accel.dst_y & 0xff00) | val;
  18.791 -		break;
  18.792 -		case 0x3b: /*Dest Y*/
  18.793 -		tvga->accel.dst_y = (tvga->accel.dst_y & 0xff) | (val << 8);
  18.794 -		break;
  18.795 -
  18.796 -		case 0x3c: /*Src X*/
  18.797 -		tvga->accel.src_x = (tvga->accel.src_x & 0xff00) | val;
  18.798 -		break;
  18.799 -		case 0x3d: /*Src X*/
  18.800 -		tvga->accel.src_x = (tvga->accel.src_x & 0xff) | (val << 8);
  18.801 -		break;
  18.802 -		case 0x3e: /*Src Y*/
  18.803 -		tvga->accel.src_y = (tvga->accel.src_y & 0xff00) | val;
  18.804 -		break;
  18.805 -		case 0x3f: /*Src Y*/
  18.806 -		tvga->accel.src_y = (tvga->accel.src_y & 0xff) | (val << 8);
  18.807 -		break;
  18.808 -
  18.809 -		case 0x40: /*Size X*/
  18.810 -		tvga->accel.size_x = (tvga->accel.size_x & 0xff00) | val;
  18.811 -		break;
  18.812 -		case 0x41: /*Size X*/
  18.813 -		tvga->accel.size_x = (tvga->accel.size_x & 0xff) | (val << 8);
  18.814 -		break;
  18.815 -		case 0x42: /*Size Y*/
  18.816 -		tvga->accel.size_y = (tvga->accel.size_y & 0xff00) | val;
  18.817 -		break;
  18.818 -		case 0x43: /*Size Y*/
  18.819 -		tvga->accel.size_y = (tvga->accel.size_y & 0xff) | (val << 8);
  18.820 -		break;
  18.821 -		
  18.822 -		case 0x80: case 0x81: case 0x82: case 0x83:
  18.823 -		case 0x84: case 0x85: case 0x86: case 0x87:
  18.824 -		case 0x88: case 0x89: case 0x8a: case 0x8b:
  18.825 -		case 0x8c: case 0x8d: case 0x8e: case 0x8f:
  18.826 -		case 0x90: case 0x91: case 0x92: case 0x93:
  18.827 -		case 0x94: case 0x95: case 0x96: case 0x97:
  18.828 -		case 0x98: case 0x99: case 0x9a: case 0x9b:
  18.829 -		case 0x9c: case 0x9d: case 0x9e: case 0x9f:
  18.830 -		case 0xa0: case 0xa1: case 0xa2: case 0xa3:
  18.831 -		case 0xa4: case 0xa5: case 0xa6: case 0xa7:
  18.832 -		case 0xa8: case 0xa9: case 0xaa: case 0xab:
  18.833 -		case 0xac: case 0xad: case 0xae: case 0xaf:
  18.834 -		case 0xb0: case 0xb1: case 0xb2: case 0xb3:
  18.835 -		case 0xb4: case 0xb5: case 0xb6: case 0xb7:
  18.836 -		case 0xb8: case 0xb9: case 0xba: case 0xbb:
  18.837 -		case 0xbc: case 0xbd: case 0xbe: case 0xbf:
  18.838 -		case 0xc0: case 0xc1: case 0xc2: case 0xc3:
  18.839 -		case 0xc4: case 0xc5: case 0xc6: case 0xc7:
  18.840 -		case 0xc8: case 0xc9: case 0xca: case 0xcb:
  18.841 -		case 0xcc: case 0xcd: case 0xce: case 0xcf:
  18.842 -		case 0xd0: case 0xd1: case 0xd2: case 0xd3:
  18.843 -		case 0xd4: case 0xd5: case 0xd6: case 0xd7:
  18.844 -		case 0xd8: case 0xd9: case 0xda: case 0xdb:
  18.845 -		case 0xdc: case 0xdd: case 0xde: case 0xdf:
  18.846 -		case 0xe0: case 0xe1: case 0xe2: case 0xe3:
  18.847 -		case 0xe4: case 0xe5: case 0xe6: case 0xe7:
  18.848 -		case 0xe8: case 0xe9: case 0xea: case 0xeb:
  18.849 -		case 0xec: case 0xed: case 0xee: case 0xef:
  18.850 -		case 0xf0: case 0xf1: case 0xf2: case 0xf3:
  18.851 -		case 0xf4: case 0xf5: case 0xf6: case 0xf7:
  18.852 -		case 0xf8: case 0xf9: case 0xfa: case 0xfb:
  18.853 -		case 0xfc: case 0xfd: case 0xfe: case 0xff:
  18.854 -		tvga->accel.pattern[addr & 0x7f] = val;
  18.855 -		break;
  18.856 -	}
  18.857 -}
  18.858 -
  18.859 -void tvga_accel_write_w(uint32_t addr, uint16_t val, void *p)
  18.860 -{
  18.861 -        tvga_t *tvga = (tvga_t *)p;
  18.862 -//	pclog("tvga_accel_write_w %08X %04X\n", addr, val);
  18.863 -	tvga_accel_write(addr, val, tvga);
  18.864 -	tvga_accel_write(addr + 1, val >> 8, tvga);
  18.865 -}
  18.866 -
  18.867 -void tvga_accel_write_l(uint32_t addr, uint32_t val, void *p)
  18.868 -{
  18.869 -        tvga_t *tvga = (tvga_t *)p;
  18.870 -//	pclog("tvga_accel_write_l %08X %08X\n", addr, val);
  18.871 -	tvga_accel_write(addr, val, tvga);
  18.872 -	tvga_accel_write(addr + 1, val >> 8, tvga);
  18.873 -	tvga_accel_write(addr + 2, val >> 16, tvga);
  18.874 -	tvga_accel_write(addr + 3, val >> 24, tvga);
  18.875 -}
  18.876 -
  18.877 -uint8_t tvga_accel_read(uint32_t addr, void *p)
  18.878 -{
  18.879 -        tvga_t *tvga = (tvga_t *)p;
  18.880 -//	pclog("tvga_accel_read : %08X\n", addr);
  18.881 -	if ((addr & ~0xff) != 0xbff00)
  18.882 -		return 0xff;
  18.883 -	switch (addr & 0xff)
  18.884 -	{
  18.885 -		case 0x20: /*Status*/
  18.886 -		return 0;
  18.887 -		
  18.888 -		case 0x27: /*ROP*/
  18.889 -		return tvga->accel.rop;
  18.890 -		
  18.891 -		case 0x28: /*Flags*/
  18.892 -		return tvga->accel.flags & 0xff;
  18.893 -		case 0x29: /*Flags*/
  18.894 -		return tvga->accel.flags >> 8;
  18.895 -
  18.896 -		case 0x2b:
  18.897 -		return tvga->accel.offset;
  18.898 -		
  18.899 -		case 0x2c: /*Background colour*/
  18.900 -		return tvga->accel.bg_col & 0xff;
  18.901 -		case 0x2d: /*Background colour*/
  18.902 -		return tvga->accel.bg_col >> 8;
  18.903 -
  18.904 -		case 0x30: /*Foreground colour*/
  18.905 -		return tvga->accel.fg_col & 0xff;
  18.906 -		case 0x31: /*Foreground colour*/
  18.907 -		return tvga->accel.fg_col >> 8;
  18.908 -
  18.909 -		case 0x38: /*Dest X*/
  18.910 -		return tvga->accel.dst_x & 0xff;
  18.911 -		case 0x39: /*Dest X*/
  18.912 -		return tvga->accel.dst_x >> 8;
  18.913 -		case 0x3a: /*Dest Y*/
  18.914 -		return tvga->accel.dst_y & 0xff;
  18.915 -		case 0x3b: /*Dest Y*/
  18.916 -		return tvga->accel.dst_y >> 8;
  18.917 -
  18.918 -		case 0x3c: /*Src X*/
  18.919 -		return tvga->accel.src_x & 0xff;
  18.920 -		case 0x3d: /*Src X*/
  18.921 -		return tvga->accel.src_x >> 8;
  18.922 -		case 0x3e: /*Src Y*/
  18.923 -		return tvga->accel.src_y & 0xff;
  18.924 -		case 0x3f: /*Src Y*/
  18.925 -		return tvga->accel.src_y >> 8;
  18.926 -
  18.927 -		case 0x40: /*Size X*/
  18.928 -		return tvga->accel.size_x & 0xff;
  18.929 -		case 0x41: /*Size X*/
  18.930 -		return tvga->accel.size_x >> 8;
  18.931 -		case 0x42: /*Size Y*/
  18.932 -		return tvga->accel.size_y & 0xff;
  18.933 -		case 0x43: /*Size Y*/
  18.934 -		return tvga->accel.size_y >> 8;
  18.935 -		
  18.936 -		case 0x80: case 0x81: case 0x82: case 0x83:
  18.937 -		case 0x84: case 0x85: case 0x86: case 0x87:
  18.938 -		case 0x88: case 0x89: case 0x8a: case 0x8b:
  18.939 -		case 0x8c: case 0x8d: case 0x8e: case 0x8f:
  18.940 -		case 0x90: case 0x91: case 0x92: case 0x93:
  18.941 -		case 0x94: case 0x95: case 0x96: case 0x97:
  18.942 -		case 0x98: case 0x99: case 0x9a: case 0x9b:
  18.943 -		case 0x9c: case 0x9d: case 0x9e: case 0x9f:
  18.944 -		case 0xa0: case 0xa1: case 0xa2: case 0xa3:
  18.945 -		case 0xa4: case 0xa5: case 0xa6: case 0xa7:
  18.946 -		case 0xa8: case 0xa9: case 0xaa: case 0xab:
  18.947 -		case 0xac: case 0xad: case 0xae: case 0xaf:
  18.948 -		case 0xb0: case 0xb1: case 0xb2: case 0xb3:
  18.949 -		case 0xb4: case 0xb5: case 0xb6: case 0xb7:
  18.950 -		case 0xb8: case 0xb9: case 0xba: case 0xbb:
  18.951 -		case 0xbc: case 0xbd: case 0xbe: case 0xbf:
  18.952 -		case 0xc0: case 0xc1: case 0xc2: case 0xc3:
  18.953 -		case 0xc4: case 0xc5: case 0xc6: case 0xc7:
  18.954 -		case 0xc8: case 0xc9: case 0xca: case 0xcb:
  18.955 -		case 0xcc: case 0xcd: case 0xce: case 0xcf:
  18.956 -		case 0xd0: case 0xd1: case 0xd2: case 0xd3:
  18.957 -		case 0xd4: case 0xd5: case 0xd6: case 0xd7:
  18.958 -		case 0xd8: case 0xd9: case 0xda: case 0xdb:
  18.959 -		case 0xdc: case 0xdd: case 0xde: case 0xdf:
  18.960 -		case 0xe0: case 0xe1: case 0xe2: case 0xe3:
  18.961 -		case 0xe4: case 0xe5: case 0xe6: case 0xe7:
  18.962 -		case 0xe8: case 0xe9: case 0xea: case 0xeb:
  18.963 -		case 0xec: case 0xed: case 0xee: case 0xef:
  18.964 -		case 0xf0: case 0xf1: case 0xf2: case 0xf3:
  18.965 -		case 0xf4: case 0xf5: case 0xf6: case 0xf7:
  18.966 -		case 0xf8: case 0xf9: case 0xfa: case 0xfb:
  18.967 -		case 0xfc: case 0xfd: case 0xfe: case 0xff:
  18.968 -		return tvga->accel.pattern[addr & 0x7f];
  18.969 -	}
  18.970 -	return 0xff;
  18.971 -}
  18.972 -
  18.973 -uint16_t tvga_accel_read_w(uint32_t addr, void *p)
  18.974 -{
  18.975 -        tvga_t *tvga = (tvga_t *)p;
  18.976 -//	pclog("tvga_accel_read_w %08X\n", addr);
  18.977 -	return tvga_accel_read(addr, tvga) | (tvga_accel_read(addr + 1, tvga) << 8);
  18.978 -}
  18.979 -
  18.980 -uint32_t tvga_accel_read_l(uint32_t addr, void *p)
  18.981 -{
  18.982 -        tvga_t *tvga = (tvga_t *)p;
  18.983 -//	pclog("tvga_accel_read_l %08X\n", addr);
  18.984 -	return tvga_accel_read_w(addr, tvga) | (tvga_accel_read_w(addr + 2, tvga) << 16);
  18.985 -}
  18.986 -
  18.987 -void tvga_accel_write_fb_b(uint32_t addr, uint8_t val, void *p)
  18.988 -{
  18.989 -        svga_t *svga = (svga_t *)p;
  18.990 -        tvga_t *tvga = (tvga_t *)svga->p;
  18.991 -//	pclog("tvga_accel_write_fb_b %08X %02X\n", addr, val);
  18.992 -	tvga_accel_command(8, val << 24, tvga);
  18.993 -}
  18.994 -
  18.995 -void tvga_accel_write_fb_w(uint32_t addr, uint16_t val, void *p)
  18.996 -{
  18.997 -        svga_t *svga = (svga_t *)p;
  18.998 -        tvga_t *tvga = (tvga_t *)svga->p;
  18.999 -//	pclog("tvga_accel_write_fb_w %08X %04X\n", addr, val);
 18.1000 -	tvga_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tvga);
 18.1001 -}
 18.1002 -
 18.1003 -void tvga_accel_write_fb_l(uint32_t addr, uint32_t val, void *p)
 18.1004 -{
 18.1005 -        svga_t *svga = (svga_t *)p;
 18.1006 -        tvga_t *tvga = (tvga_t *)svga->p;
 18.1007 -//	pclog("tvga_accel_write_fb_l %08X %08X\n", addr, val);
 18.1008 -	tvga_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tvga);
 18.1009 +        
 18.1010 +        return svga_add_status_info(s, max_len, &tvga->svga);
 18.1011  }
 18.1012  
 18.1013  device_t tvga8900d_device =
 18.1014 @@ -1109,16 +289,5 @@
 18.1015          NULL,
 18.1016          tvga_speed_changed,
 18.1017          tvga_force_redraw,
 18.1018 -        svga_add_status_info
 18.1019 +        tvga_add_status_info
 18.1020  };
 18.1021 -
 18.1022 -device_t tgui9440_device =
 18.1023 -{
 18.1024 -        "Trident TGUI 9440",
 18.1025 -        tgui9440_init,
 18.1026 -        tvga_close,
 18.1027 -        NULL,
 18.1028 -        tvga_speed_changed,
 18.1029 -        tvga_force_redraw,
 18.1030 -        svga_add_status_info
 18.1031 -};
    19.1 --- a/src/vid_tvga.h	Sat Nov 16 20:48:51 2013 +0000
    19.2 +++ b/src/vid_tvga.h	Wed Nov 20 21:34:09 2013 +0000
    19.3 @@ -1,2 +1,1 @@
    19.4  extern device_t tvga8900d_device;
    19.5 -extern device_t tgui9440_device;
    20.1 --- a/src/vid_vga.c	Sat Nov 16 20:48:51 2013 +0000
    20.2 +++ b/src/vid_vga.c	Wed Nov 20 21:34:09 2013 +0000
    20.3 @@ -114,6 +114,13 @@
    20.4          vga->svga.fullchange = changeframecount;
    20.5  }
    20.6  
    20.7 +int vga_add_status_info(char *s, int max_len, void *p)
    20.8 +{
    20.9 +        vga_t *vga = (vga_t *)p;
   20.10 +        
   20.11 +        return svga_add_status_info(s, max_len, &vga->svga);
   20.12 +}
   20.13 +
   20.14  device_t vga_device =
   20.15  {
   20.16          "VGA",
   20.17 @@ -122,5 +129,5 @@
   20.18          NULL,
   20.19          vga_speed_changed,
   20.20          vga_force_redraw,
   20.21 -        svga_add_status_info
   20.22 +        vga_add_status_info
   20.23  };
    21.1 --- a/src/video.c	Sat Nov 16 20:48:51 2013 +0000
    21.2 +++ b/src/video.c	Wed Nov 20 21:34:09 2013 +0000
    21.3 @@ -29,6 +29,7 @@
    21.4  #include "vid_s3.h"
    21.5  #include "vid_s3_virge.h"
    21.6  #include "vid_tandy.h"
    21.7 +#include "vid_tgui9440.h"
    21.8  #include "vid_tvga.h"
    21.9  #include "vid_vga.h"
   21.10