]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
NCR SVGA 64-pixel wide cursor fix, 15-bit mode supported, improved RAMDAC emulation
authorToni Wilen <twilen@winuae.net>
Sat, 13 Jan 2024 10:33:29 +0000 (12:33 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 13 Jan 2024 10:33:29 +0000 (12:33 +0200)
gfxboard.cpp
pcem/vid_ncr.cpp

index 1be50c480bba3916a70e12a5d3bd990b7afdefc8..10f772722136fe679fbf1147f2e62636a6180597 100644 (file)
@@ -5575,36 +5575,13 @@ static void special_pcem_put(uaecptr addr, uae_u32 v, int size)
                        put_mem_pcem(mem + 0xa0000, v, size);
                } else if (addr & 0x8000) {
                        // RAMDAC
-                       int dac = addr & 15;
-                       if (dac == 1) {
-                               // palette index
-                               gb->extradata[0] = v;
-                               gb->extradata[1] = 0;
-                       } else if (dac == 3) {
-                               // palette data
-                               gb->extradata[2 + gb->extradata[1]] = v;
-                               gb->extradata[1]++;
-                               if (gb->extradata[1] == 3) {
-                                       put_io_pcem(0x3c8, gb->extradata[0], 0);
-                                       put_io_pcem(0x3c9, gb->extradata[2], 0);
-                                       put_io_pcem(0x3c9, gb->extradata[3], 0);
-                                       put_io_pcem(0x3c9, gb->extradata[4], 0);
-                                       gb->extradata[0]++;
-                                       gb->extradata[0] &= 255;
-                                       gb->extradata[1] = 0;
-                               }
-                       } else if (dac == 13) {
-                               // 16/24 bit mode
-                               if ((v & (0x80 | 0x40 | 0x20)) == (0x80 | 0x40 | 0x20)) {
-                                       put_io_pcem(0x3c4, 0x3f, 0);
-                                       put_io_pcem(0x3c5, 24, 0);
-                               } else if (v & 0x80) {
-                                       put_io_pcem(0x3c4, 0x3f, 0);
-                                       put_io_pcem(0x3c5, 16, 0);
-                               } else {
-                                       put_io_pcem(0x3c4, 0x3f, 0);
-                                       put_io_pcem(0x3c5, 8, 0);
-                               }
+                       int dac = (addr & 15) >> 1;
+                       if (dac == 6) {
+                               put_io_pcem(0x3c6, v, 0);
+                       } else if (dac == 0) {
+                               put_io_pcem(0x3c8, v, 0);
+                       } else if (dac == 1) {
+                               put_io_pcem(0x3c9, v, 0);
                        }
                } else {
                        // IO
@@ -5936,6 +5913,14 @@ static uae_u32 special_pcem_get(uaecptr addr, int size)
                        }
                } else if (addr & 0x8000) {
                        // RAMDAC
+                       int dac = (addr & 15) >> 1;
+                       if (dac == 6) {
+                               v = get_io_pcem(0x3c6, 0);
+                       } else if (dac == 0) {
+                               v = get_io_pcem(0x3c8, 0);
+                       } else if (dac == 1) {
+                               v = get_io_pcem(0x3c9, 0);
+                       }
                } else {
                        // IO
                        int io = addr & 0x3fff;
index 46102915eb1329bd71cd85f2092ff26786a8286b..26e15c931ddbc52211e981748e6f2899297ea3e9 100644 (file)
@@ -32,27 +32,20 @@ typedef struct ncr_t
         sdac_ramdac_t ramdac;
 
         uint8_t ma_ext;
-        int width;
-        int bpp;
-        int ramdacbpp;
 
         int chip;
         
-        uint8_t id, id_ext;
-
         uint32_t linear_base, linear_size;
         uint32_t mmio_base, mmio_size;
 
-        int card;
         uint32_t bank[4];
         uint32_t vram_mask;
         
-        uint8_t subsys_cntl, subsys_stat;
+        float (*getclock)(int clock, void *p);
+        void *getclock_p;
+
         int vblank_irq;
         
-        uint32_t hwc_fg_col, hwc_bg_col;
-        int hwc_col_stack_pos;
-
         int blitter_busy;
         uint64_t blitter_time;
         uint64_t status_time;
@@ -117,6 +110,7 @@ void ncr_hwcursor_draw(svga_t *svga, int displine)
     int xx;
     int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
     int line_offset = 0;
+    uint32_t addr = svga->hwcursor_latch.addr;
 
     offset <<= svga->horizontal_linedbl;
 
@@ -139,17 +133,20 @@ void ncr_hwcursor_draw(svga_t *svga, int displine)
         }
     }
 
-    svga->hwcursor_latch.addr += (svga->hwcursor.xsize / 8);
+    addr += (32 / 8);
     int xdbl = 1 << svga->hwcursor.h_acc;
-    if (svga->bpp == 16 && svga->hwcursor.h_acc > 0) {
+    if ((svga->bpp == 16 || svga->bpp == 15) && svga->hwcursor.h_acc > 0) {
         xdbl = 1 << (svga->hwcursor.h_acc - 1);
     }
     for (x = 0; x < svga->hwcursor.xsize; x += 8)
     {
-            svga->hwcursor_latch.addr--;
-            uint32_t addroffset = svga->hwcursor_latch.addr & svga->vram_display_mask;
+            if (x == 32) {
+                addr += (64 / 8);
+            }
+            addr--;
+            uint32_t addroffset = addr & svga->vram_display_mask;
             dat[0] = svga->vram[addroffset];
-            addroffset = (svga->hwcursor_latch.addr + (svga->hwcursor.xsize / 8)) & svga->vram_display_mask;
+            addroffset = (addr + (svga->hwcursor.xsize / 8)) & svga->vram_display_mask;
             dat[1] = svga->vram[addroffset];
             for (xx = 0; xx < 8; xx++)
             {
@@ -187,9 +184,14 @@ void ncr_out(uint16_t addr, uint8_t val, void *p)
         
         switch (addr)
         {
-                case 0x3c6:
-                ncr->ramdacbpp = val;
-                break;
+                case 0x3C6:
+                    val &= ~0x10;
+                    sdac_ramdac_out((addr & 3) | 4, val, &ncr->ramdac, svga);
+                    return;
+                case 0x3C7: case 0x3C8: case 0x3C9:
+                    sdac_ramdac_out(addr & 3, val, &ncr->ramdac, svga);
+                    return;
+
                 case 0x3c4:
                 svga->seqaddr = val & 0x3f;
                 break;
@@ -222,7 +224,7 @@ void ncr_out(uint16_t addr, uint8_t val, void *p)
                             svga->hwcursor.y = (svga->seqregs[0x0f] << 8) | svga->seqregs[0x10];
                             return;
                         case 0x11:
-                            svga->hwcursor.xoff = val & 31;
+                            svga->hwcursor.xoff = val & (ncr->chip == NCR_TYPE_32BLT ? 0x3f : 0x1f);
                             return;
                         case 0x12:
                             svga->hwcursor.yoff = val & 127;
@@ -231,19 +233,8 @@ void ncr_out(uint16_t addr, uint8_t val, void *p)
                         case 0x14:
                         case 0x15:
                         case 0x16:
-                        {
-                            int offset = 0;
-                            if (ncr->chip == NCR_TYPE_32BLT) {
-                                if (svga->seqregs[0x1e] & 0x10) {
-                                    offset = (svga->seqregs[0x15] << 8) | svga->seqregs[0x16];
-                                }
-                                svga->hwcursor.addr = (svga->seqregs[0x13] << 8) | svga->seqregs[0x14];
-                                svga->hwcursor.addr += offset << 6;
-                            } else {
-                                svga->hwcursor.addr = (svga->seqregs[0x15] << 16) | (svga->seqregs[0x16] << 8) | svga->seqregs[0x14];
-                                svga->hwcursor.addr >>= 2;
-                            }
-                        }
+                            svga->hwcursor.addr = (svga->seqregs[0x15] << 16) | (svga->seqregs[0x16] << 8) | svga->seqregs[0x14];
+                            svga->hwcursor.addr >>= 2;
                         break;
                         case 0x18:
                         case 0x19:
@@ -258,13 +249,13 @@ void ncr_out(uint16_t addr, uint8_t val, void *p)
                         break;
                         case 0x21:
                         if (val & 1) {
-                            svga->bpp = 8;
-                            svga->bpp = 8 << ((val >> 4) & 3);
-                            if (svga->bpp > 24) {
-                                svga->bpp = 24;
+                            ncr->blt_bpp = 8;
+                            ncr->blt_bpp = 8 << ((val >> 4) & 3);
+                            if (ncr->blt_bpp > 24) {
+                                ncr->blt_bpp = 24;
                             }
                         } else {
-                            svga->bpp = 4;
+                            ncr->blt_bpp = 8;
                         }
                         break;
                         case 0x30:
@@ -273,9 +264,6 @@ void ncr_out(uint16_t addr, uint8_t val, void *p)
                         case 0x33:
                             ncr_updatemapping(ncr);
                         break;
-                        case 0x3f: // ram dac fake
-                        ncr->ramdacbpp = val;
-                        break;
                     }
                     if (old != val)
                     {
@@ -351,6 +339,11 @@ uint8_t ncr_in(uint16_t addr, void *p)
                         return svga->seqregs[svga->seqaddr];
                 break;
 
+                case 0x3c6:
+                return sdac_ramdac_in((addr & 3) | 4, &ncr->ramdac, svga);
+                case 0x3c7: case 0x3c8: case 0x3c9:
+                return sdac_ramdac_in(addr & 3, &ncr->ramdac, svga);
+
                 case 0x3d4:
                 return svga->crtcreg;
                 case 0x3d5:
@@ -417,17 +410,6 @@ void ncr_recalctimings(svga_t *svga)
             svga->hdisp /= 2;
         }
 
-        svga->bpp = 8;
-        if (svga->seqregs[0x21] & 0x01)
-        {
-            if (ncr->chip < NCR_TYPE_32BLT) {
-                svga->bpp = ncr->ramdacbpp;
-            } else {
-                if (ncr->ramdacbpp & 0x40) {
-                    svga->bpp = (ncr->ramdacbpp & 0x20) ? 16 : 24;
-                }
-            }
-        }
         switch (svga->bpp)
         {
             case 4:
@@ -436,6 +418,10 @@ void ncr_recalctimings(svga_t *svga)
             case 8:
                 svga->render = svga_render_8bpp_highres;
                 break;
+            case 15:
+                svga->render = svga_render_15bpp_highres;
+                svga->hdisp /= 2;
+                break;
             case 16:
                 svga->render = svga_render_16bpp_highres;
                 svga->hdisp /= 2;
@@ -751,7 +737,6 @@ static void blitter_start(ncr_t *ncr)
     ncr->blt_h = 0;
     ncr->blt_xdir = (ncr->blt_control & (1 << 7)) ? 1 : -1;
     ncr->blt_ydir = (ncr->blt_control & (1 << 6)) ? 1 : -1;
-    ncr->blt_bpp = ncr->svga.bpp;
     ncr->blt_bppdiv8 = ncr->blt_bpp / 8;
     ncr->blt_bpp_cnt = 0;
     if (ncr->blt_xdir < 0) {
@@ -765,7 +750,7 @@ static void blitter_start(ncr_t *ncr)
     ncr->blt_patbak = ncr->blt_pat;
     ncr->blt_patbak2 = ncr->blt_pat;
 
-    if (ncr->svga.bpp == 24) {
+    if (ncr->blt_bpp == 24) {
         // strange pattern offset in 24-bit mode
         uint32_t dst = ncr->blt_dst;
         dst >>= 3;
@@ -1075,6 +1060,7 @@ static void ncr_adjust_panning(svga_t *svga)
 
     switch (svga->bpp)
     {
+        case 15:
         case 16:
             dst = (ar11 & 4) ? 7 : 8;
             break;
@@ -1166,6 +1152,7 @@ static void *ncr_init(char *bios_fn, int chip)
 
         ncr->chip = chip;
         ncr->blt_status = 1;
+        ncr->blt_bpp = 8;
 
         ncr_updatemapping(ncr);
 
@@ -1176,9 +1163,11 @@ void *ncr_retina_z2_init()
 {
     ncr_t *ncr = (ncr_t *)ncr_init("ncr.bin", NCR_TYPE_22EP);
 
-    //ncr->getclock = ncr_getclock;
-    //ncr->getclock_p = ncr;
     ncr->svga.fb_only = 0;
+
+    ncr->getclock = sdac_getclock;
+    ncr->getclock_p = &ncr->ramdac;
+    sdac_init(&ncr->ramdac);
     svga_set_ramdac_type(&ncr->svga, RAMDAC_8BIT);
 
     return ncr;
@@ -1188,10 +1177,12 @@ void *ncr_retina_z3_init()
 {
     ncr_t *ncr = (ncr_t *)ncr_init("ncr.bin", NCR_TYPE_32BLT);
 
-    //ncr->getclock = ncr_getclock;
-    //ncr->getclock_p = ncr;
     ncr->svga.fb_only = -1;
 
+    ncr->getclock = sdac_getclock;
+    ncr->getclock_p = &ncr->ramdac;
+    sdac_init(&ncr->ramdac);
+
     return ncr;
 }