PCem

changeset 53:2ca00fb57757

Mach64: Added colour compare, X/Y destination tiling, MMIO RAMDAC access.
author TomW
date Sun Dec 15 21:30:23 2013 +0000
parents 91b90b67515a
children 5b9067076693
files src/vid_ati_mach64.c
diffstat 1 files changed, 88 insertions(+), 5 deletions(-) [+]
line diff
     1.1 --- a/src/vid_ati_mach64.c	Sun Dec 15 15:41:29 2013 +0000
     1.2 +++ b/src/vid_ati_mach64.c	Sun Dec 15 21:30:23 2013 +0000
     1.3 @@ -45,6 +45,10 @@
     1.4  
     1.5          uint32_t clock_cntl;
     1.6  
     1.7 +        uint32_t clr_cmp_clr;
     1.8 +        uint32_t clr_cmp_cntl;
     1.9 +        uint32_t clr_cmp_mask;
    1.10 +
    1.11          uint32_t cur_horz_vert_off;        
    1.12          uint32_t cur_horz_vert_posn;
    1.13          uint32_t cur_offset;
    1.14 @@ -120,6 +124,11 @@
    1.15  
    1.16                  uint32_t dp_bkgd_clr;
    1.17                  uint32_t dp_frgd_clr;
    1.18 +
    1.19 +                uint32_t clr_cmp_clr;
    1.20 +                uint32_t clr_cmp_mask;
    1.21 +                int clr_cmp_fn;
    1.22 +                int clr_cmp_src;
    1.23                  
    1.24                  int err;
    1.25          } accel;
    1.26 @@ -169,6 +178,8 @@
    1.27  
    1.28  enum
    1.29  {
    1.30 +        DST_X_TILE    = 0x08,
    1.31 +        DST_Y_TILE    = 0x10,
    1.32          DST_24_ROT_EN = 0x80
    1.33  };
    1.34  
    1.35 @@ -496,10 +507,15 @@
    1.36          
    1.37          mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr;
    1.38          mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr;        
    1.39 +
    1.40 +        mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask;
    1.41 +        mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask;
    1.42 +        mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7;
    1.43 +        mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24);
    1.44          
    1.45          mach64->accel.busy = 1;
    1.46  #ifdef MACH64_DEBUG
    1.47 -        pclog("mach64_start_fill : dst %i, %i  src %i, %i  size %i, %i  src pitch %i offset %X  dst pitch %i offset %X  scissor %i %i %i %i  src_fg %i\n", mach64->accel.dst_x, mach64->accel.dst_y, mach64->accel.src_x, mach64->accel.src_y, mach64->accel.dst_width, mach64->accel.dst_height, mach64->accel.src_pitch, mach64->accel.src_offset, mach64->accel.dst_pitch, mach64->accel.dst_offset, mach64->accel.sc_left, mach64->accel.sc_right, mach64->accel.sc_top, mach64->accel.sc_bottom, mach64->accel.source_fg);
    1.48 +        pclog("mach64_start_fill : dst %i, %i  src %i, %i  size %i, %i  src pitch %i offset %X  dst pitch %i offset %X  scissor %i %i %i %i  src_fg %i  mix %02X %02X\n", mach64->accel.dst_x_start, mach64->accel.dst_y_start, mach64->accel.src_x_start, mach64->accel.src_y_start, mach64->accel.dst_width, mach64->accel.dst_height, mach64->accel.src_pitch, mach64->accel.src_offset, mach64->accel.dst_pitch, mach64->accel.dst_offset, mach64->accel.sc_left, mach64->accel.sc_right, mach64->accel.sc_top, mach64->accel.sc_bottom, mach64->accel.source_fg, mach64->accel.mix_fg, mach64->accel.mix_bg);
    1.49  #endif
    1.50          mach64->accel.op = OP_RECT;
    1.51  }
    1.52 @@ -562,6 +578,11 @@
    1.53          mach64->accel.x_count = mach64->dst_bres_lnth & 0x7fff;
    1.54          mach64->accel.err = (mach64->dst_bres_err & 0x3ffff) | ((mach64->dst_bres_err & 0x40000) ? 0xfffc0000 : 0);
    1.55          
    1.56 +        mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask;
    1.57 +        mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask;
    1.58 +        mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7;
    1.59 +        mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24);
    1.60 +
    1.61          mach64->accel.busy = 1;
    1.62  #ifdef MACH64_DEBUG
    1.63          pclog("mach64_start_line\n");
    1.64 @@ -612,6 +633,7 @@
    1.65  void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
    1.66  {
    1.67          svga_t *svga = &mach64->svga;
    1.68 +        int cmp_clr = 0;
    1.69          
    1.70          if (!mach64->accel.busy)
    1.71          {
    1.72 @@ -694,7 +716,21 @@
    1.73                  
    1.74                                  READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, mach64->accel.dst_size);
    1.75  
    1.76 -                                MIX
    1.77 +                                switch (mach64->accel.clr_cmp_fn)
    1.78 +                                {
    1.79 +                                        case 1: /*TRUE*/
    1.80 +                                        cmp_clr = 1;
    1.81 +                                        break;
    1.82 +                                        case 4: /*DST_CLR != CLR_CMP_CLR*/
    1.83 +                                        cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr;
    1.84 +                                        break;
    1.85 +                                        case 5: /*DST_CLR == CLR_CMP_CLR*/
    1.86 +                                        cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr;
    1.87 +                                        break;
    1.88 +                                }
    1.89 +                                
    1.90 +                                if (!cmp_clr)
    1.91 +                                        MIX
    1.92  
    1.93                                  WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, mach64->accel.dst_size);
    1.94                          }
    1.95 @@ -754,6 +790,10 @@
    1.96                                          pclog("mach64 blit finished\n");
    1.97  #endif
    1.98                                          mach64->accel.busy = 0;
    1.99 +                                        if (mach64->dst_cntl & DST_X_TILE)
   1.100 +                                                mach64->dst_y_x = (mach64->dst_y_x & 0xfff) | ((mach64->dst_y_x + (mach64->accel.dst_width << 16)) & 0xfff0000);
   1.101 +                                        if (mach64->dst_cntl & DST_Y_TILE)
   1.102 +                                                mach64->dst_y_x = (mach64->dst_y_x & 0xfff0000) | ((mach64->dst_y_x + mach64->accel.dst_height) & 0xfff);
   1.103                                          return;
   1.104                                  }
   1.105                                  if (mach64->accel.source_host)
   1.106 @@ -831,7 +871,21 @@
   1.107  
   1.108  //                                pclog("Blit %i,%i %i,%i  %X %X  %i  %02X %02X %i ", mach64->accel.src_x, mach64->accel.src_y, mach64->accel.dst_x, mach64->accel.dst_y,  (mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x) & 0x7fffff, (mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix);
   1.109                                  
   1.110 -                                MIX
   1.111 +                                switch (mach64->accel.clr_cmp_fn)
   1.112 +                                {
   1.113 +                                        case 1: /*TRUE*/
   1.114 +                                        cmp_clr = 1;
   1.115 +                                        break;
   1.116 +                                        case 4: /*DST_CLR != CLR_CMP_CLR*/
   1.117 +                                        cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr;
   1.118 +                                        break;
   1.119 +                                        case 5: /*DST_CLR == CLR_CMP_CLR*/
   1.120 +                                        cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr;
   1.121 +                                        break;
   1.122 +                                }
   1.123 +                                
   1.124 +                                if (!cmp_clr)
   1.125 +                                        MIX
   1.126  
   1.127  //                                pclog("%02X  %i\n", dest_dat, mach64->accel.dst_height);
   1.128  
   1.129 @@ -1041,6 +1095,9 @@
   1.130                  READ8(addr, mach64->mem_cntl);
   1.131                  break;
   1.132  
   1.133 +                case 0xc0: case 0xc1: case 0xc2: case 0xc3:
   1.134 +                ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga);
   1.135 +                break;
   1.136                  case 0xc4: case 0xc5: case 0xc6: case 0xc7:
   1.137                  READ8(addr, mach64->dac_cntl);
   1.138                  break;
   1.139 @@ -1176,6 +1233,16 @@
   1.140                  READ8(addr, mach64->dp_src);
   1.141                  break;
   1.142  
   1.143 +                case 0x300: case 0x301: case 0x302: case 0x303:
   1.144 +                READ8(addr, mach64->clr_cmp_clr);
   1.145 +                break;
   1.146 +                case 0x304: case 0x305: case 0x306: case 0x307:
   1.147 +                READ8(addr, mach64->clr_cmp_mask);
   1.148 +                break;
   1.149 +                case 0x308: case 0x309: case 0x30a: case 0x30b:
   1.150 +                READ8(addr, mach64->clr_cmp_cntl);
   1.151 +                break;
   1.152 +
   1.153                  case 0x320: case 0x321: case 0x322: case 0x323:
   1.154                  READ8(addr, mach64->context_mask);
   1.155                  break;
   1.156 @@ -1368,6 +1435,9 @@
   1.157  #endif
   1.158                  break;
   1.159  
   1.160 +                case 0xc0: case 0xc1: case 0xc2: case 0xc3:
   1.161 +                ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga);
   1.162 +                break;
   1.163                  case 0xc4: case 0xc5: case 0xc6: case 0xc7:
   1.164                  WRITE8(addr, mach64->dac_cntl, val);
   1.165                  break;
   1.166 @@ -1394,12 +1464,15 @@
   1.167                  WRITE8(addr, mach64->dst_y_x, val);
   1.168                  break;
   1.169                  case 0x110: case 0x111:
   1.170 -                addr += 2;
   1.171 +                WRITE8(addr + 2, mach64->dst_height_width, val);
   1.172 +                break;
   1.173                  case 0x114: case 0x115:
   1.174                  case 0x118: case 0x119: case 0x11a: case 0x11b:
   1.175                  case 0x11e: case 0x11f:
   1.176                  WRITE8(addr, mach64->dst_height_width, val);
   1.177 -                if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f)
   1.178 +                case 0x113:
   1.179 +                if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f ||
   1.180 +                    ((addr & 0x3ff) == 0x113) && !(val & 0x80))
   1.181                  {
   1.182                          mach64_start_fill(mach64);
   1.183  #ifdef MACH64_DEBUG
   1.184 @@ -1545,6 +1618,16 @@
   1.185                  WRITE8(addr, mach64->dp_src, val);
   1.186                  break;
   1.187  
   1.188 +                case 0x300: case 0x301: case 0x302: case 0x303:
   1.189 +                WRITE8(addr, mach64->clr_cmp_clr, val);
   1.190 +                break;
   1.191 +                case 0x304: case 0x305: case 0x306: case 0x307:
   1.192 +                WRITE8(addr, mach64->clr_cmp_mask, val);
   1.193 +                break;
   1.194 +                case 0x308: case 0x309: case 0x30a: case 0x30b:
   1.195 +                WRITE8(addr, mach64->clr_cmp_cntl, val);
   1.196 +                break;
   1.197 +
   1.198                  case 0x320: case 0x321: case 0x322: case 0x323:
   1.199                  WRITE8(addr, mach64->context_mask, val);
   1.200                  break;