PCem

changeset 28:22e575515a51

Cleaned up DMA emulation.
author TomW
date Sun Oct 27 14:37:01 2013 +0000
parents 7f6eb2f86a87
children 626d3074b545
files src/dma.c src/dma.h src/fdc.c src/ibm.h src/pit.c src/sound_adlibgold.c
diffstat 6 files changed, 174 insertions(+), 436 deletions(-) [+]
line diff
     1.1 --- a/src/dma.c	Tue Oct 22 19:52:46 2013 +0100
     1.2 +++ b/src/dma.c	Sun Oct 27 14:37:01 2013 +0000
     1.3 @@ -6,122 +6,118 @@
     1.4  #include "mem.h"
     1.5  #include "video.h"
     1.6  
     1.7 -extern int ins;
     1.8 -int output;
     1.9 -uint8_t dmaregs[16];
    1.10 -int dmaon[4];
    1.11 -uint8_t dma16regs[16];
    1.12 -int dma16on[4];
    1.13 +static uint8_t dmaregs[16];
    1.14 +static int dmaon[4];
    1.15 +static uint8_t dma16regs[16];
    1.16 +static int dma16on[4];
    1.17 +static uint8_t dmapages[16];
    1.18  
    1.19  void dma_reset()
    1.20  {
    1.21          int c;
    1.22 -        dma.wp=0;
    1.23 -        for (c=0;c<16;c++) dmaregs[c]=0;
    1.24 -        for (c=0;c<4;c++)
    1.25 +        dma.wp = 0;
    1.26 +        for (c = 0; c < 16; c++) 
    1.27 +                dmaregs[c] = 0;
    1.28 +        for (c = 0; c < 4; c++)
    1.29          {
    1.30 -                dma.mode[c]=0;
    1.31 -                dma.ac[c]=0;
    1.32 -                dma.cc[c]=0;
    1.33 -                dma.ab[c]=0;
    1.34 -                dma.cb[c]=0;
    1.35 +                dma.mode[c] = 0;
    1.36 +                dma.ac[c] = 0;
    1.37 +                dma.cc[c] = 0;
    1.38 +                dma.ab[c] = 0;
    1.39 +                dma.cb[c] = 0;
    1.40          }
    1.41 -        dma.m=0;
    1.42 +        dma.m = 0;
    1.43          
    1.44 -        dma16.wp=0;
    1.45 -        for (c=0;c<16;c++) dma16regs[c]=0;
    1.46 -        for (c=0;c<4;c++)
    1.47 +        dma16.wp = 0;
    1.48 +        for (c = 0; c < 16; c++) 
    1.49 +                dma16regs[c] = 0;
    1.50 +        for (c = 0; c < 4; c++)
    1.51          {
    1.52 -                dma16.mode[c]=0;
    1.53 -                dma16.ac[c]=0;
    1.54 -                dma16.cc[c]=0;
    1.55 -                dma16.ab[c]=0;
    1.56 -                dma16.cb[c]=0;
    1.57 +                dma16.mode[c] = 0;
    1.58 +                dma16.ac[c] = 0;
    1.59 +                dma16.cc[c] = 0;
    1.60 +                dma16.ab[c] = 0;
    1.61 +                dma16.cb[c] = 0;
    1.62          }
    1.63 -        dma16.m=0;
    1.64 +        dma16.m = 0;
    1.65  }
    1.66  
    1.67  uint8_t dma_read(uint16_t addr, void *priv)
    1.68  {
    1.69          uint8_t temp;
    1.70  //        printf("Read DMA %04X %04X:%04X %i %02X\n",addr,CS,pc, pic_intpending, pic.pend);
    1.71 -        switch (addr&0xF)
    1.72 +        switch (addr & 0xf)
    1.73          {
    1.74 -                case 0:
    1.75 -/*                if (((dma.mode[0]>>2)&3)==2)
    1.76 -                {
    1.77 -                        dma.ac[0]++;
    1.78 -                        dma.cc[0]--;
    1.79 -                        if (dma.cc[0]<0)
    1.80 -                        {
    1.81 -                                dma.ac[0]=dma.ab[0];
    1.82 -                                dma.cc[0]=dma.cb[0];
    1.83 -                        }
    1.84 -                }*/
    1.85 -                case 2: case 4: case 6: /*Address registers*/
    1.86 -                dma.wp^=1;
    1.87 -                if (dma.wp) return dma.ac[(addr>>1)&3]&0xFF;
    1.88 -                return dma.ac[(addr>>1)&3]>>8;
    1.89 +                case 0: case 2: case 4: case 6: /*Address registers*/
    1.90 +                dma.wp ^= 1;
    1.91 +                if (dma.wp) 
    1.92 +                        return dma.ac[(addr >> 1) & 3] & 0xff;
    1.93 +                return dma.ac[(addr >> 1) & 3] >> 8;
    1.94 +                
    1.95                  case 1: case 3: case 5: case 7: /*Count registers*/
    1.96 -//                printf("DMA count %i = %04X\n", (addr>>1)&3, dma.cc[(addr>>1)&3]);
    1.97 -                dma.wp^=1;
    1.98 -                if (dma.wp) temp=dma.cc[(addr>>1)&3]&0xFF;
    1.99 -                else        temp=dma.cc[(addr>>1)&3]>>8;
   1.100 -//                printf("%02X\n",temp);
   1.101 +                dma.wp ^= 1;
   1.102 +                if (dma.wp) temp = dma.cc[(addr >> 1) & 3] & 0xff;
   1.103 +                else        temp = dma.cc[(addr >> 1) & 3] >> 8;
   1.104                  return temp;
   1.105 +                
   1.106                  case 8: /*Status register*/
   1.107 -                temp=dma.stat;
   1.108 -                dma.stat=0;
   1.109 -//                pclog("Read DMA status %02X\n", temp);
   1.110 +                temp = dma.stat;
   1.111 +                dma.stat = 0;
   1.112                  return temp;
   1.113 -                case 0xD:
   1.114 +                
   1.115 +                case 0xd:
   1.116                  return 0;
   1.117          }
   1.118  //        printf("Bad DMA read %04X %04X:%04X\n",addr,CS,pc);
   1.119 -        return dmaregs[addr&0xF];
   1.120 +        return dmaregs[addr & 0xf];
   1.121  }
   1.122  
   1.123  void dma_write(uint16_t addr, uint8_t val, void *priv)
   1.124  {
   1.125 -        printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc);
   1.126 -        dmaregs[addr&0xF]=val;
   1.127 -        switch (addr&0xF)
   1.128 +//        printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc);
   1.129 +        dmaregs[addr & 0xf] = val;
   1.130 +        switch (addr & 0xf)
   1.131          {
   1.132                  case 0: case 2: case 4: case 6: /*Address registers*/
   1.133 -                dma.wp^=1;
   1.134 -                if (dma.wp) dma.ab[(addr>>1)&3]=(dma.ab[(addr>>1)&3]&0xFF00)|val;
   1.135 -                else        dma.ab[(addr>>1)&3]=(dma.ab[(addr>>1)&3]&0xFF)|(val<<8);
   1.136 -                dma.ac[(addr>>1)&3]=dma.ab[(addr>>1)&3];
   1.137 -                dmaon[(addr>>1)&3]=1;
   1.138 -//                printf("DMA addr %i now %04X\n",(addr>>1)&3,dma.ac[(addr>>1)&3]);
   1.139 +                dma.wp ^= 1;
   1.140 +                if (dma.wp) dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0xff00) | val;
   1.141 +                else        dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8);
   1.142 +                dma.ac[(addr >> 1) & 3] = dma.ab[(addr >> 1) & 3];
   1.143 +                dmaon[(addr >> 1) & 3] = 1;
   1.144                  return;
   1.145 +                
   1.146                  case 1: case 3: case 5: case 7: /*Count registers*/
   1.147 -                dma.wp^=1;
   1.148 -                if (dma.wp) dma.cb[(addr>>1)&3]=(dma.cb[(addr>>1)&3]&0xFF00)|val;
   1.149 -                else        dma.cb[(addr>>1)&3]=(dma.cb[(addr>>1)&3]&0xFF)|(val<<8);
   1.150 -                dma.cc[(addr>>1)&3]=dma.cb[(addr>>1)&3];
   1.151 -                dmaon[(addr>>1)&3]=1;
   1.152 -//                printf("DMA count %i now %04X\n",(addr>>1)&3,dma.cc[(addr>>1)&3]);
   1.153 +                dma.wp ^= 1;
   1.154 +                if (dma.wp) dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0xff00) | val;
   1.155 +                else        dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8);
   1.156 +                dma.cc[(addr >> 1) & 3] = dma.cb[(addr >> 1) & 3];
   1.157 +                dmaon[(addr >> 1) & 3] = 1;
   1.158                  return;
   1.159 +                
   1.160                  case 8: /*Control register*/
   1.161                  dma.command = val;
   1.162                  return;
   1.163 -                case 0xA: /*Mask*/
   1.164 -                if (val&4) dma.m|=(1<<(val&3));
   1.165 -                else       dma.m&=~(1<<(val&3));
   1.166 +                
   1.167 +                case 0xa: /*Mask*/
   1.168 +                if (val & 4) dma.m |=  (1 << (val & 3));
   1.169 +                else         dma.m &= ~(1 << (val & 3));
   1.170                  return;
   1.171 -                case 0xB: /*Mode*/
   1.172 -                dma.mode[val&3]=val;
   1.173 +                
   1.174 +                case 0xb: /*Mode*/
   1.175 +                dma.mode[val & 3] = val;
   1.176                  return;
   1.177 -                case 0xC: /*Clear FF*/
   1.178 -                dma.wp=0;
   1.179 +                
   1.180 +                case 0xc: /*Clear FF*/
   1.181 +                dma.wp = 0;
   1.182                  return;
   1.183 -                case 0xD: /*Master clear*/
   1.184 -                dma.wp=0;
   1.185 -                dma.m=0xF;
   1.186 +                
   1.187 +                case 0xd: /*Master clear*/
   1.188 +                dma.wp = 0;
   1.189 +                dma.m = 0xf;
   1.190                  return;
   1.191 -                case 0xF: /*Mask write*/
   1.192 -                dma.m=val&0xF;
   1.193 +                
   1.194 +                case 0xf: /*Mask write*/
   1.195 +                dma.m = val & 0xf;
   1.196                  return;
   1.197          }
   1.198  }
   1.199 @@ -130,116 +126,103 @@
   1.200  {
   1.201          uint8_t temp;
   1.202  //        printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc);
   1.203 -        addr>>=1;
   1.204 -        switch (addr&0xF)
   1.205 +        addr >>= 1;
   1.206 +        switch (addr & 0xf)
   1.207          {
   1.208 -                case 0:
   1.209 -                if (((dma16.mode[0]>>2)&3)==2)
   1.210 -                {
   1.211 -                        dma16.ac[0]++;
   1.212 -                        dma16.cc[0]--;
   1.213 -                        if (dma16.cc[0]<0)
   1.214 -                        {
   1.215 -                                dma16.ac[0]=dma16.ab[0];
   1.216 -                                dma16.cc[0]=dma16.cb[0];
   1.217 -                        }
   1.218 -                }
   1.219 -                case 2: case 4: case 6: /*Address registers*/
   1.220 -                dma16.wp^=1;
   1.221 -                if (dma16.wp) return dma16.ac[(addr>>1)&3]&0xFF;
   1.222 -                return dma16.ac[(addr>>1)&3]>>8;
   1.223 +                case 0: case 2: case 4: case 6: /*Address registers*/
   1.224 +                dma16.wp ^= 1;
   1.225 +                if (dma16.wp) 
   1.226 +                        return dma16.ac[(addr >> 1) & 3] & 0xff;
   1.227 +                return dma16.ac[(addr >> 1) & 3] >> 8;
   1.228 +                
   1.229                  case 1: case 3: case 5: case 7: /*Count registers*/
   1.230 -                dma16.wp^=1;
   1.231 -//                printf("Read %04X\n",dma16.cc[1]);
   1.232 -                if (dma16.wp) temp=dma16.cc[(addr>>1)&3]&0xFF;
   1.233 -                else        temp=dma16.cc[(addr>>1)&3]>>8;
   1.234 -//                printf("%02X\n",temp);
   1.235 +                dma16.wp ^= 1;
   1.236 +                if (dma16.wp) temp = dma16.cc[(addr >> 1) & 3] & 0xff;
   1.237 +                else          temp = dma16.cc[(addr >> 1) & 3] >> 8;
   1.238                  return temp;
   1.239 +                
   1.240                  case 8: /*Status register*/
   1.241 -                temp=dma16.stat;
   1.242 -                dma16.stat=0;
   1.243 +                temp = dma16.stat;
   1.244 +                dma16.stat = 0;
   1.245                  return temp;
   1.246          }
   1.247 -        return dma16regs[addr&0xF];
   1.248 +        return dma16regs[addr & 0xf];
   1.249  }
   1.250  
   1.251  void dma16_write(uint16_t addr, uint8_t val, void *priv)
   1.252  {
   1.253  //        printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc);
   1.254 -        addr>>=1;
   1.255 -        dma16regs[addr&0xF]=val;
   1.256 -        switch (addr&0xF)
   1.257 +        addr >>= 1;
   1.258 +        dma16regs[addr & 0xf] = val;
   1.259 +        switch (addr & 0xf)
   1.260          {
   1.261                  case 0: case 2: case 4: case 6: /*Address registers*/
   1.262 -                dma16.wp^=1;
   1.263 -                if (dma16.wp) dma16.ab[(addr>>1)&3]=(dma16.ab[(addr>>1)&3]&0xFF00)|val;
   1.264 -                else        dma16.ab[(addr>>1)&3]=(dma16.ab[(addr>>1)&3]&0xFF)|(val<<8);
   1.265 -                dma16.ac[(addr>>1)&3]=dma16.ab[(addr>>1)&3];
   1.266 -                dma16on[(addr>>1)&3]=1;
   1.267 -//                printf("dma16 addr %i now %04X\n",(addr>>1)&3,dma16.ac[(addr>>1)&3]);
   1.268 +                dma16.wp ^= 1;
   1.269 +                if (dma16.wp) dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0xff00) | val;
   1.270 +                else          dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8);
   1.271 +                dma16.ac[(addr >> 1) & 3] = dma16.ab[(addr >> 1) & 3];
   1.272 +                dma16on[(addr >> 1) & 3] = 1;
   1.273                  return;
   1.274 +                
   1.275                  case 1: case 3: case 5: case 7: /*Count registers*/
   1.276 -                dma16.wp^=1;
   1.277 -                if (dma16.wp) dma16.cb[(addr>>1)&3]=(dma16.cb[(addr>>1)&3]&0xFF00)|val;
   1.278 -                else        dma16.cb[(addr>>1)&3]=(dma16.cb[(addr>>1)&3]&0xFF)|(val<<8);
   1.279 -                dma16.cc[(addr>>1)&3]=dma16.cb[(addr>>1)&3];
   1.280 -                dma16on[(addr>>1)&3]=1;
   1.281 -//                printf("dma16 count %i now %04X\n",(addr>>1)&3,dma16.cc[(addr>>1)&3]);
   1.282 +                dma16.wp ^= 1;
   1.283 +                if (dma16.wp) dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0xff00) | val;
   1.284 +                else          dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8);
   1.285 +                dma16.cc[(addr >> 1) & 3] = dma16.cb[(addr >> 1) & 3];
   1.286 +                dma16on[(addr >> 1) & 3] = 1;
   1.287                  return;
   1.288 +                
   1.289                  case 8: /*Control register*/
   1.290                  return;
   1.291 -                case 0xA: /*Mask*/
   1.292 -                if (val&4) dma16.m|=(1<<(val&3));
   1.293 -                else       dma16.m&=~(1<<(val&3));
   1.294 +                
   1.295 +                case 0xa: /*Mask*/
   1.296 +                if (val & 4) dma16.m |=  (1 << (val & 3));
   1.297 +                else         dma16.m &= ~(1 << (val & 3));
   1.298                  return;
   1.299 -                case 0xB: /*Mode*/
   1.300 -                dma16.mode[val&3]=val;
   1.301 +                
   1.302 +                case 0xb: /*Mode*/
   1.303 +                dma16.mode[val & 3] = val;
   1.304                  return;
   1.305 -                case 0xC: /*Clear FF*/
   1.306 -                dma16.wp=0;
   1.307 +                
   1.308 +                case 0xc: /*Clear FF*/
   1.309 +                dma16.wp = 0;
   1.310                  return;
   1.311 -                case 0xD: /*Master clear*/
   1.312 -                dma16.wp=0;
   1.313 -                dma16.m=0xF;
   1.314 +                
   1.315 +                case 0xd: /*Master clear*/
   1.316 +                dma16.wp = 0;
   1.317 +                dma16.m = 0xf;
   1.318                  return;
   1.319 -                case 0xF: /*Mask write*/
   1.320 -                dma16.m=val&0xF;
   1.321 +                
   1.322 +                case 0xf: /*Mask write*/
   1.323 +                dma16.m = val&0xf;
   1.324                  return;
   1.325          }
   1.326  }
   1.327  
   1.328 -uint8_t dmapages[16];
   1.329  
   1.330  void dma_page_write(uint16_t addr, uint8_t val, void *priv)
   1.331  {
   1.332 -/*        if (!(addr&0xF))
   1.333 -        {*/
   1.334 -//                pclog("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc);
   1.335 -//                if (val==0x29 && pc==0xD25) output=1;
   1.336 -//        }
   1.337 -        dmapages[addr&0xF]=val;
   1.338 -        switch (addr&0xF)
   1.339 +        dmapages[addr & 0xf] = val;
   1.340 +        switch (addr & 0xf)
   1.341          {
   1.342                  case 1:
   1.343 -                dma.page[2]=(AT)?val:val&0xF;
   1.344 +                dma.page[2] = (AT) ? val : val & 0xf;
   1.345                  break;
   1.346                  case 2:
   1.347 -                dma.page[3]=(AT)?val:val&0xF;
   1.348 +                dma.page[3] = (AT) ? val : val & 0xf;
   1.349                  break;
   1.350                  case 3:
   1.351 -                dma.page[1]=(AT)?val:val&0xF;
   1.352 -//                pclog("DMA1 page %02X\n",val);
   1.353 +                dma.page[1] = (AT) ? val : val & 0xf;
   1.354                  break;
   1.355 -                case 0xB:
   1.356 -                dma16.page[1]=val;
   1.357 +                case 0xb:
   1.358 +                dma16.page[1] = val;
   1.359                  break;
   1.360          }
   1.361 -//        printf("Page write %04X %02X\n",addr,val);
   1.362  }
   1.363  
   1.364  uint8_t dma_page_read(uint16_t addr, void *priv)
   1.365  {
   1.366 -        return dmapages[addr&0xF];
   1.367 +        return dmapages[addr & 0xf];
   1.368  }
   1.369  
   1.370  void dma_init()
   1.371 @@ -264,35 +247,23 @@
   1.372  {
   1.373          mem_writeb_phys(addr, val);
   1.374  }
   1.375 -/*void writedma2(uint8_t val)
   1.376 -{
   1.377 -//        printf("Write to %05X %02X %i\n",(dma.page[2]<<16)+dma.ac[2],val,dma.m&4);
   1.378 -        if (!(dma.m&4))
   1.379 -        {
   1.380 -                ram[((dma.page[2]<<16)+dma.ac[2])&rammask]=val;
   1.381 -                dma.ac[2]++;
   1.382 -                dma.cc[2]--;
   1.383 -                if (dma.cc[2]==-1)
   1.384 -                {
   1.385 -                        dma.m|=4;
   1.386 -                        dma.stat|=4;
   1.387 -                }
   1.388 -        }
   1.389 -}*/
   1.390  
   1.391  int dma_channel_read(int channel)
   1.392  {
   1.393          uint16_t temp;
   1.394  
   1.395 +        if (!AT)
   1.396 +                refreshread();
   1.397 +        
   1.398          if (channel < 4)
   1.399          {
   1.400 -//                pclog("Read DMA channel %i\n", channel);
   1.401                  if (dma.m & (1 << channel))
   1.402                          return DMA_NODATA;
   1.403                  if ((dma.mode[channel] & 0xC) != 8)
   1.404                          return DMA_NODATA;
   1.405 +
   1.406                  temp = _dma_read(dma.ac[channel] + (dma.page[channel] << 16)); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
   1.407 -//                pclog("                - %02X %05X\n", temp, dma.ac[channel] + (dma.page[channel] << 16));
   1.408 +
   1.409                  if (dma.mode[channel] & 0x20) dma.ac[channel]--;
   1.410                  else                          dma.ac[channel]++;
   1.411                  dma.cc[channel]--;
   1.412 @@ -307,6 +278,9 @@
   1.413                          dma.m |= (1 << channel);
   1.414                          dma.stat |= (1 << channel);
   1.415                  }
   1.416 +
   1.417 +                if (dma.m & (1 << channel))
   1.418 +                        return temp | DMA_OVER;
   1.419                  return temp;
   1.420          }
   1.421          else
   1.422 @@ -316,8 +290,10 @@
   1.423                          return DMA_NODATA;
   1.424                  if ((dma16.mode[channel] & 0xC) != 8)
   1.425                          return DMA_NODATA;
   1.426 +
   1.427                  temp =  _dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16)) |
   1.428                         (_dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1) << 8);
   1.429 +
   1.430                  if (dma16.mode[channel] & 0x20) dma16.ac[channel]--;
   1.431                  else                            dma16.ac[channel]++;
   1.432                  dma16.cc[channel]--;
   1.433 @@ -327,24 +303,32 @@
   1.434                          dma16.ac[channel] = dma16.ab[channel];
   1.435                          dma16.stat |= (1 << channel);
   1.436                  }
   1.437 -                else if (dma16.cc[channel]<=-1)
   1.438 +                else if (dma16.cc[channel] <= -1)
   1.439                  {
   1.440                          dma16.m |= (1 << channel);
   1.441                          dma16.stat |= (1 << channel);
   1.442                  }
   1.443 +
   1.444 +                if (dma.m & (1 << channel))
   1.445 +                        return temp | DMA_OVER;
   1.446                  return temp;
   1.447          }
   1.448  }
   1.449  
   1.450  int dma_channel_write(int channel, uint16_t val)
   1.451  {
   1.452 +        if (!AT)
   1.453 +                refreshread();
   1.454 +
   1.455          if (channel < 4)
   1.456          {
   1.457                  if (dma.m & (1 << channel))
   1.458                          return DMA_NODATA;
   1.459                  if ((dma.mode[channel] & 0xC) != 4)
   1.460                          return DMA_NODATA;
   1.461 +
   1.462                  _dma_write(dma.ac[channel] + (dma.page[channel] << 16), val);
   1.463 +
   1.464                  if (dma.mode[channel]&0x20) dma.ac[channel]--;
   1.465                  else                        dma.ac[channel]++;
   1.466                  dma.cc[channel]--;
   1.467 @@ -359,6 +343,9 @@
   1.468                          dma.m    |= (1 << channel);
   1.469                          dma.stat |= (1 << channel);
   1.470                  }
   1.471 +
   1.472 +                if (dma.m & (1 << channel))
   1.473 +                        return DMA_OVER;
   1.474          }
   1.475          else
   1.476          {
   1.477 @@ -367,8 +354,10 @@
   1.478                          return DMA_NODATA;
   1.479                  if ((dma16.mode[channel] & 0xC) != 4)
   1.480                          return DMA_NODATA;
   1.481 +
   1.482                  _dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16),     val);
   1.483                  _dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1, val >> 8);                
   1.484 +
   1.485                  if (dma16.mode[channel]&0x20) dma16.ac[channel]--;
   1.486                  else                          dma16.ac[channel]++;
   1.487                  dma16.cc[channel]--;
   1.488 @@ -383,257 +372,9 @@
   1.489                          dma16.m    |= (1 << channel);
   1.490                          dma16.stat |= (1 << channel);
   1.491                  }
   1.492 +
   1.493 +                if (dma.m & (1 << channel))
   1.494 +                        return DMA_OVER;
   1.495          }
   1.496          return 0;
   1.497  }
   1.498 -
   1.499 -extern int sbbufferpos;
   1.500 -int readdma1()
   1.501 -{
   1.502 -        uint8_t temp;
   1.503 -        pclog("readdma1 : Read DMA1 %02X %02X %i\n",dma.m,dma.mode[1], dma.cc[1]);
   1.504 -        if (dma.m & (1 << 1))
   1.505 -                return DMA_NODATA;
   1.506 -        if ((dma.mode[1]&0xC)!=8)
   1.507 -                return DMA_NODATA;
   1.508 -        temp=_dma_read((dma.ac[1]+(dma.page[1]<<16))&rammask); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
   1.509 -        pclog("readdma1 : DMA1 %02X %05X\n",temp,(dma.ac[1]+(dma.page[1]<<16))&rammask);
   1.510 -        if (dma.mode[1]&0x20) dma.ac[1]--;
   1.511 -        else                  dma.ac[1]++;
   1.512 -        dma.cc[1]--;
   1.513 -        if (!dma.cc[1] && (dma.mode[1]&0x10))
   1.514 -        {
   1.515 -                dma.cc[1]=dma.cb[1]+1;
   1.516 -                dma.ac[1]=dma.ab[1];
   1.517 -                dma.stat |= (1 << 1);
   1.518 -        }
   1.519 -        else if (dma.cc[1]<=-1)
   1.520 -        {
   1.521 -                dma.m |= (1 << 1);
   1.522 -                dma.stat |= (1 << 1);
   1.523 -        }
   1.524 -        return temp;
   1.525 -}
   1.526 -uint8_t readdma2()
   1.527 -{
   1.528 -        uint8_t temp;
   1.529 -//        pclog("Read DMA2 %02X %02X %i\n",dma.m,dma.mode[2], dma.cc[2]);
   1.530 -        if (dma.m&4)
   1.531 -        {
   1.532 -                fdc_abort();
   1.533 -                return 0xFF;
   1.534 -        }
   1.535 -        if ((dma.mode[2]&0xC)!=8)
   1.536 -        {
   1.537 -                fdc_abort();
   1.538 -                return 0xFF;
   1.539 -        }
   1.540 -        temp=_dma_read((dma.ac[2]+(dma.page[2]<<16))&rammask); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
   1.541 -//        pclog("DMA2 %02X %05X\n",temp,(dma.ac[2]+(dma.page[2]<<16))&rammask);
   1.542 -        if (dma.mode[2]&0x20) dma.ac[2]--;
   1.543 -        else                  dma.ac[2]++;
   1.544 -        dma.cc[2]--;
   1.545 -        if (!dma.cc[2] && (dma.mode[2]&0x10))
   1.546 -        {
   1.547 -                dma.cc[2]=dma.cb[2]+1;
   1.548 -                dma.ac[2]=dma.ab[2];
   1.549 -                dma.stat |= (1 << 2);
   1.550 -        }
   1.551 -        else if (dma.cc[2]<=-1)
   1.552 -        {
   1.553 -                dma.m|=4;
   1.554 -                dma.stat |= (1 << 2);
   1.555 -        }
   1.556 -        return temp;
   1.557 -}
   1.558 -int readdma3()
   1.559 -{
   1.560 -        uint8_t temp;
   1.561 -//        pclog("Read DMA1 %02X %02X %i\n",dma.m,dma.mode[1], dma.cc[1]);
   1.562 -        if (dma.m & (1 << 3))
   1.563 -                return DMA_NODATA;
   1.564 -        if ((dma.mode[3]&0xC)!=8)
   1.565 -                return DMA_NODATA;
   1.566 -        temp=_dma_read((dma.ac[3]+(dma.page[3]<<16))&rammask); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
   1.567 -        //pclog("DMA3 %02X %05X\n",temp,(dma.ac[3]+(dma.page[3]<<16))&rammask);
   1.568 -        if (dma.mode[3]&0x20) dma.ac[3]--;
   1.569 -        else                  dma.ac[3]++;
   1.570 -        dma.cc[3]--;
   1.571 -        if (!dma.cc[3] && (dma.mode[3]&0x10))
   1.572 -        {
   1.573 -                dma.cc[3]=dma.cb[3]+1;
   1.574 -                dma.ac[3]=dma.ab[3];
   1.575 -                dma.stat |= (1 << 3);
   1.576 -        }
   1.577 -        else if (dma.cc[3]<=-1)
   1.578 -        {
   1.579 -                dma.m |= (1 << 3);
   1.580 -                dma.stat |= (1 << 3);
   1.581 -        }
   1.582 -        return temp;
   1.583 -}
   1.584 -
   1.585 -void writedma1(uint8_t temp)
   1.586 -{
   1.587 -//        pclog("Write DMA1 %02X %02X %04X\n",dma.m,dma.mode[1],dma.cc[1]);
   1.588 -        if (dma.m & (1 << 1))
   1.589 -                return;
   1.590 -        if ((dma.mode[1] & 0xC) != 4)
   1.591 -                return;
   1.592 -//        pclog("Write %05X %05X %02X\n",(dma.ac[2]+(dma.page[2]<<16)),rammask,temp);
   1.593 -//        ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]=temp;
   1.594 -        _dma_write((dma.ac[1]+(dma.page[1]<<16))&rammask,temp);
   1.595 -        if (dma.mode[1]&0x20) dma.ac[1]--;
   1.596 -        else                  dma.ac[1]++;
   1.597 -        dma.cc[1]--;
   1.598 -        if (!dma.cc[1] && (dma.mode[1]&0x10))
   1.599 -        {
   1.600 -                dma.cc[1]=dma.cb[1]+1;
   1.601 -                dma.ac[1]=dma.ab[1];
   1.602 -                dma.stat |= (1 << 1);
   1.603 -        }
   1.604 -        else if (dma.cc[1]<=-1)
   1.605 -        {
   1.606 -//                pclog("Reached TC\n");
   1.607 -                dma.m |= (1 << 1);
   1.608 -                dma.stat |= (1 << 1);
   1.609 -        }
   1.610 -}
   1.611 -void writedma2(uint8_t temp)
   1.612 -{
   1.613 -//        pclog("Write DMA2 %02X %02X %04X\n",dma.m,dma.mode[2],dma.cc[2]);
   1.614 -        if (dma.m&4)
   1.615 -        {
   1.616 -                fdc_abort();
   1.617 -                return;
   1.618 -        }
   1.619 -        if ((dma.mode[2]&0xC)!=4)
   1.620 -        {
   1.621 -                fdc_abort();
   1.622 -                return;
   1.623 -        }
   1.624 -//        pclog("Write %05X %05X %02X\n",(dma.ac[2]+(dma.page[2]<<16)),rammask,temp);
   1.625 -//        ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]=temp;
   1.626 -        _dma_write((dma.ac[2]+(dma.page[2]<<16))&rammask,temp);
   1.627 -        if (dma.mode[2]&0x20) dma.ac[2]--;
   1.628 -        else                  dma.ac[2]++;
   1.629 -        dma.cc[2]--;
   1.630 -        if (!dma.cc[2] && (dma.mode[2]&0x10))
   1.631 -        {
   1.632 -                dma.cc[2]=dma.cb[2]+1;
   1.633 -                dma.ac[2]=dma.ab[2];
   1.634 -                dma.stat |= (1 << 2);
   1.635 -        }
   1.636 -        else if (dma.cc[2]<=-1)
   1.637 -        {
   1.638 -//                pclog("Reached TC\n");
   1.639 -                fdc_abort();
   1.640 -                dma.m|=4;
   1.641 -                dma.stat |= (1 << 2);
   1.642 -        }
   1.643 -}
   1.644 -void writedma3(uint8_t temp)
   1.645 -{
   1.646 -//        pclog("Write DMA3 %02X %02X %04X\n",dma.m,dma.mode[3],dma.cc[3]);
   1.647 -        if (dma.m & (1 << 3))
   1.648 -                return;
   1.649 -        if ((dma.mode[3] & 0xC) != 4)
   1.650 -                return;
   1.651 -//        pclog("Write %05X %05X %02X\n",(dma.ac[2]+(dma.page[2]<<16)),rammask,temp);
   1.652 -//        ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]=temp;
   1.653 -        _dma_write((dma.ac[3]+(dma.page[3]<<16))&rammask,temp);
   1.654 -        if (dma.mode[3]&0x20) dma.ac[3]--;
   1.655 -        else                  dma.ac[3]++;
   1.656 -        dma.cc[3]--;
   1.657 -        if (!dma.cc[3] && (dma.mode[3]&0x10))
   1.658 -        {
   1.659 -                dma.cc[3]=dma.cb[3]+1;
   1.660 -                dma.ac[3]=dma.ab[3];
   1.661 -                dma.stat |= (1 << 3);
   1.662 -        }
   1.663 -        else if (dma.cc[3]<=-1)
   1.664 -        {
   1.665 -//                pclog("Reached TC\n");
   1.666 -                dma.m |= (1 << 3);
   1.667 -                dma.stat |= (1 << 3);
   1.668 -        }
   1.669 -}
   1.670 -
   1.671 -uint16_t readdma5()
   1.672 -{
   1.673 -        uint16_t temp=0;
   1.674 -//        pclog("Read DMA5 %i %04X\n",dma16on[1],dma16.cc[1]);
   1.675 -        /*if ((dma16.ac[1]+(dma16.page[1]<<16))<0x800000)  */temp=ram[((dma16.ac[1]<<1)+((dma16.page[1]&~1)<<16))&rammask]|(ram[((dma16.ac[1]<<1)+((dma16.page[1]&~1)<<16)+1)&rammask]<<8);
   1.676 -        //readmemwl(dma16.ac[1]+(dma16.page[1]<<16));
   1.677 -//        printf("Read DMA1 from %05X %05X %02X %04X\n",dma.ac[1]+(dma.page[1]<<16),(dma16.ac[1]<<1)+((dma16.page[1]&~1)<<16),dma16.mode[1],temp);
   1.678 -        if (!dma16on[1])
   1.679 -        {
   1.680 -//                printf("DMA off!\n");
   1.681 -                return temp;
   1.682 -        }
   1.683 -        dma16.ac[1]++;
   1.684 -        dma16.cc[1]--;
   1.685 -        if (dma16.cc[1]<=-1 && (dma16.mode[1]&0x10))
   1.686 -        {
   1.687 -                dma16.cc[1]=dma16.cb[1];
   1.688 -                dma16.ac[1]=dma16.ab[1];
   1.689 -                dma16.stat |= (1 << 1);
   1.690 -        }
   1.691 -        else if (dma16.cc[1]<=-1)
   1.692 -        {
   1.693 -                dma16on[1]=0;
   1.694 -                dma16.stat |= (1 << 1);
   1.695 -        }
   1.696 -        return temp;
   1.697 -}
   1.698 -
   1.699 -void writedma5(uint16_t temp)
   1.700 -{
   1.701 -        if (!dma16on[1]) return;
   1.702 -        ram[((dma16.ac[1]<<1)+((dma16.page[1]&~1)<<16))&rammask]=temp;
   1.703 -        ram[((dma16.ac[1]<<1)+((dma16.page[1]&~1)<<16)+1)&rammask]=temp>>8;
   1.704 -
   1.705 -        dma16.ac[1]++;
   1.706 -        dma16.cc[1]--;
   1.707 -        if (dma16.cc[1]<=-1 && (dma16.mode[1]&0x10))
   1.708 -        {
   1.709 -                dma16.cc[1]=dma16.cb[1];
   1.710 -                dma16.ac[1]=dma16.ab[1];
   1.711 -                dma16.stat |= (1 << 1);
   1.712 -        }
   1.713 -        else if (dma16.cc[1]<=-1)
   1.714 -        {
   1.715 -                dma16on[1]=0;
   1.716 -                dma16.stat |= (1 << 1);
   1.717 -        }
   1.718 -}
   1.719 -
   1.720 -void readdma0()
   1.721 -{
   1.722 -        if (AT) ppi.pb^=0x10;        
   1.723 -        if (dma.command & 4) return;
   1.724 -//        if (AMSTRAD) return;
   1.725 -        refreshread();
   1.726 -//        pclog("Read refresh %02X %02X %04X %04X\n",dma.m,dma.mode[0],dma.ac[0],dma.cc[0]);
   1.727 -        if (dma.m&1) return;
   1.728 -//        readmembl((dma.page[0]<<16)+dma.ac[0]);
   1.729 -//        if (!(dma.m&1))
   1.730 -//        {
   1.731 -                dma.ac[0]+=2;
   1.732 -                dma.cc[0]--;
   1.733 -                if (dma.cc[0]==-1)
   1.734 -                {
   1.735 -                        dma.ac[0]=dma.ab[0];
   1.736 -                        dma.cc[0]=dma.cb[0];
   1.737 -                        dma.stat |= 1;
   1.738 -                }
   1.739 -//        }
   1.740 -//        ppi.pb^=0x10;
   1.741 -}
   1.742 -
   1.743 -void dumpdma()
   1.744 -{
   1.745 -        printf("Address : %04X %04X %04X %04X\n",dma.ac[0],dma.ac[1],dma.ac[2],dma.ac[3]);
   1.746 -        printf("Count   : %04X %04X %04X %04X\n",dma.cc[0],dma.cc[1],dma.cc[2],dma.cc[3]);
   1.747 -        printf("Mask %02X Stat %02X\n",dma.m,dma.stat);
   1.748 -}
     2.1 --- a/src/dma.h	Tue Oct 22 19:52:46 2013 +0100
     2.2 +++ b/src/dma.h	Sun Oct 27 14:37:01 2013 +0000
     2.3 @@ -3,6 +3,7 @@
     2.4  void dma_reset();
     2.5  
     2.6  #define DMA_NODATA -1
     2.7 +#define DMA_OVER 0x10000
     2.8  
     2.9  void readdma0();
    2.10  int readdma1();
     3.1 --- a/src/fdc.c	Tue Oct 22 19:52:46 2013 +0100
     3.2 +++ b/src/fdc.c	Sun Oct 27 14:37:01 2013 +0000
     3.3 @@ -104,6 +104,7 @@
     3.4          fdc.st0=0xC0;
     3.5          fdc.lock = 0;
     3.6          fdc.head = 0;
     3.7 +        fdc.abort = 0;
     3.8          if (!AT)
     3.9             fdc.rate=2;
    3.10  //        pclog("Reset FDC\n");
    3.11 @@ -400,14 +401,6 @@
    3.12          return temp;
    3.13  }
    3.14  
    3.15 -int fdc_abort_f = 0;
    3.16 -
    3.17 -void fdc_abort()
    3.18 -{
    3.19 -        fdc_abort_f = 1;
    3.20 -//        pclog("FDC ABORT\n");
    3.21 -}
    3.22 -
    3.23  static int fdc_reset_stat = 0;
    3.24  void fdc_poll()
    3.25  {
    3.26 @@ -437,7 +430,7 @@
    3.27                  {
    3.28                          fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos];
    3.29  //                        pclog("Read %i %i %i %i %02X\n",fdc.head,fdc.track,fdc.sector,fdc.pos,fdc.dat);
    3.30 -                        writedma2(fdc.dat);
    3.31 +                        dma_channel_write(2, fdc.dat);
    3.32                          timer_process();
    3.33                          disctime = 60 * (1 << TIMER_SHIFT);
    3.34                          timer_update_outstanding();
    3.35 @@ -495,10 +488,9 @@
    3.36                  }
    3.37                  if (fdc.pos<512)
    3.38                  {
    3.39 -                        temp=readdma2();
    3.40 -                        if (fdc_abort_f)
    3.41 +                        temp = dma_channel_read(2);
    3.42 +                        if (temp == DMA_NODATA)
    3.43                          {
    3.44 -                                fdc_abort_f=0;
    3.45                                  discint=0xFD;
    3.46                                  timer_process();
    3.47                                  disctime = 50 * (1 << TIMER_SHIFT);
    3.48 @@ -541,21 +533,22 @@
    3.49                  case 6: /*Read data*/
    3.50                  if (!fdc.pos)
    3.51                  {
    3.52 -//                        printf("Reading sector %i track %i side %i drive %i %02X to %05X\n",fdc.sector,fdc.track[fdc.drive],fdc.head,fdc.drive,fdc.params[5],(dma.ac[2]+(dma.page[2]<<16))&rammask);
    3.53 +//                        printf("Reading sector %i track %i side %i drive %i %02X to %05X %04X\n",fdc.sector,fdc.track[fdc.drive],fdc.head,fdc.drive,fdc.params[5],(dma.ac[2]+(dma.page[2]<<16))&rammask, dma.cc[2]);
    3.54                  }
    3.55                  if (fdc.pos<512)
    3.56                  {
    3.57                          fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos];
    3.58  //                        printf("Read disc %i %i %i %i %02X\n",fdc.head,fdc.track,fdc.sector,fdc.pos,fdc.dat);
    3.59 -                        writedma2(fdc.dat);
    3.60 +                        if (dma_channel_write(2, fdc.dat) & DMA_OVER)
    3.61 +                                fdc.abort = 1;
    3.62                          timer_process();
    3.63                          disctime = 60 * (1 << TIMER_SHIFT);
    3.64                          timer_update_outstanding();
    3.65                  }
    3.66                  else
    3.67                  {
    3.68 -//                        printf("End of command - params to go!\n");
    3.69 -                        fdc_abort_f = 0;
    3.70 +//                        printf("End of command - params to go! %i %i %i\n", fdc.track[fdc.drive], fdc.head, fdc.sector);
    3.71 +                        fdc.abort = 0;
    3.72                          disctime=0;
    3.73                          discint=-2;
    3.74                          picint(0x40);
    3.75 @@ -606,8 +599,8 @@
    3.76                                  else
    3.77                                     fdc.pos = 512;
    3.78                          }
    3.79 -                        if (fdc_abort_f)
    3.80 -                           fdc.pos = 512;
    3.81 +                        if (fdc.abort)
    3.82 +                                fdc.pos = 512;
    3.83                  }
    3.84                  return;
    3.85  /*                printf("Read data\n");
     4.1 --- a/src/ibm.h	Tue Oct 22 19:52:46 2013 +0100
     4.2 +++ b/src/ibm.h	Sun Oct 27 14:37:01 2013 +0000
     4.3 @@ -264,6 +264,7 @@
     4.4          int lock;
     4.5          int perp;
     4.6          uint8_t config, pretrk;
     4.7 +        int abort;
     4.8  } FDC;
     4.9  
    4.10  FDC fdc;
     5.1 --- a/src/pit.c	Tue Oct 22 19:52:46 2013 +0100
     5.2 +++ b/src/pit.c	Sun Oct 27 14:37:01 2013 +0000
     5.3 @@ -276,7 +276,9 @@
     5.4                  }
     5.5  //                if (output) pclog("%f %04X %02X\n",pit.c[1],pit.l[1],pit.ctrls[1]);
     5.6  //                printf("DMA0!\n");
     5.7 -                readdma0();
     5.8 +                dma_channel_read(0);
     5.9 +                if (AT) 
    5.10 +                        ppi.pb ^= 0x10;
    5.11          }
    5.12          if (pit.c[2]<1)
    5.13          {
     6.1 --- a/src/sound_adlibgold.c	Tue Oct 22 19:52:46 2013 +0100
     6.2 +++ b/src/sound_adlibgold.c	Sun Oct 27 14:37:01 2013 +0000
     6.3 @@ -86,14 +86,14 @@
     6.4          if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127))
     6.5                  return;
     6.6                  
     6.7 -        temp = readdma1();
     6.8 +        temp = dma_channel_read(1);
     6.9  //        pclog("adgold DMA1 return %02X %i L\n", temp, channel);
    6.10 -        if (temp == -1) return;
    6.11 +        if (temp == DMA_NODATA) return;
    6.12          adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp;
    6.13          adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;
    6.14          if (adgold->adgold_mma_regs[channel][0xc] & 0x60)
    6.15          {
    6.16 -                temp = readdma1();
    6.17 +                temp = dma_channel_read(1);
    6.18  //                pclog("adgold DMA1 return %02X %i H\n", temp, channel);
    6.19                  adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp;
    6.20                  adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;