Cleaned up DMA emulation.
This commit is contained in:
parent
2c054de1f6
commit
a514d2fe4b
6 changed files with 178 additions and 440 deletions
569
src/dma.c
569
src/dma.c
|
|
@ -6,122 +6,118 @@
|
|||
#include "mem.h"
|
||||
#include "video.h"
|
||||
|
||||
extern int ins;
|
||||
int output;
|
||||
uint8_t dmaregs[16];
|
||||
int dmaon[4];
|
||||
uint8_t dma16regs[16];
|
||||
int dma16on[4];
|
||||
static uint8_t dmaregs[16];
|
||||
static int dmaon[4];
|
||||
static uint8_t dma16regs[16];
|
||||
static int dma16on[4];
|
||||
static uint8_t dmapages[16];
|
||||
|
||||
void dma_reset()
|
||||
{
|
||||
int c;
|
||||
dma.wp=0;
|
||||
for (c=0;c<16;c++) dmaregs[c]=0;
|
||||
for (c=0;c<4;c++)
|
||||
dma.wp = 0;
|
||||
for (c = 0; c < 16; c++)
|
||||
dmaregs[c] = 0;
|
||||
for (c = 0; c < 4; c++)
|
||||
{
|
||||
dma.mode[c]=0;
|
||||
dma.ac[c]=0;
|
||||
dma.cc[c]=0;
|
||||
dma.ab[c]=0;
|
||||
dma.cb[c]=0;
|
||||
dma.mode[c] = 0;
|
||||
dma.ac[c] = 0;
|
||||
dma.cc[c] = 0;
|
||||
dma.ab[c] = 0;
|
||||
dma.cb[c] = 0;
|
||||
}
|
||||
dma.m=0;
|
||||
dma.m = 0;
|
||||
|
||||
dma16.wp=0;
|
||||
for (c=0;c<16;c++) dma16regs[c]=0;
|
||||
for (c=0;c<4;c++)
|
||||
dma16.wp = 0;
|
||||
for (c = 0; c < 16; c++)
|
||||
dma16regs[c] = 0;
|
||||
for (c = 0; c < 4; c++)
|
||||
{
|
||||
dma16.mode[c]=0;
|
||||
dma16.ac[c]=0;
|
||||
dma16.cc[c]=0;
|
||||
dma16.ab[c]=0;
|
||||
dma16.cb[c]=0;
|
||||
dma16.mode[c] = 0;
|
||||
dma16.ac[c] = 0;
|
||||
dma16.cc[c] = 0;
|
||||
dma16.ab[c] = 0;
|
||||
dma16.cb[c] = 0;
|
||||
}
|
||||
dma16.m=0;
|
||||
dma16.m = 0;
|
||||
}
|
||||
|
||||
uint8_t dma_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t temp;
|
||||
// printf("Read DMA %04X %04X:%04X %i %02X\n",addr,CS,pc, pic_intpending, pic.pend);
|
||||
switch (addr&0xF)
|
||||
switch (addr & 0xf)
|
||||
{
|
||||
case 0:
|
||||
/* if (((dma.mode[0]>>2)&3)==2)
|
||||
{
|
||||
dma.ac[0]++;
|
||||
dma.cc[0]--;
|
||||
if (dma.cc[0]<0)
|
||||
{
|
||||
dma.ac[0]=dma.ab[0];
|
||||
dma.cc[0]=dma.cb[0];
|
||||
}
|
||||
}*/
|
||||
case 2: case 4: case 6: /*Address registers*/
|
||||
dma.wp^=1;
|
||||
if (dma.wp) return dma.ac[(addr>>1)&3]&0xFF;
|
||||
return dma.ac[(addr>>1)&3]>>8;
|
||||
case 0: case 2: case 4: case 6: /*Address registers*/
|
||||
dma.wp ^= 1;
|
||||
if (dma.wp)
|
||||
return dma.ac[(addr >> 1) & 3] & 0xff;
|
||||
return dma.ac[(addr >> 1) & 3] >> 8;
|
||||
|
||||
case 1: case 3: case 5: case 7: /*Count registers*/
|
||||
// printf("DMA count %i = %04X\n", (addr>>1)&3, dma.cc[(addr>>1)&3]);
|
||||
dma.wp^=1;
|
||||
if (dma.wp) temp=dma.cc[(addr>>1)&3]&0xFF;
|
||||
else temp=dma.cc[(addr>>1)&3]>>8;
|
||||
// printf("%02X\n",temp);
|
||||
dma.wp ^= 1;
|
||||
if (dma.wp) temp = dma.cc[(addr >> 1) & 3] & 0xff;
|
||||
else temp = dma.cc[(addr >> 1) & 3] >> 8;
|
||||
return temp;
|
||||
|
||||
case 8: /*Status register*/
|
||||
temp=dma.stat;
|
||||
dma.stat=0;
|
||||
// pclog("Read DMA status %02X\n", temp);
|
||||
temp = dma.stat;
|
||||
dma.stat = 0;
|
||||
return temp;
|
||||
case 0xD:
|
||||
|
||||
case 0xd:
|
||||
return 0;
|
||||
}
|
||||
// printf("Bad DMA read %04X %04X:%04X\n",addr,CS,pc);
|
||||
return dmaregs[addr&0xF];
|
||||
return dmaregs[addr & 0xf];
|
||||
}
|
||||
|
||||
void dma_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
dmaregs[addr&0xF]=val;
|
||||
switch (addr&0xF)
|
||||
// printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
dmaregs[addr & 0xf] = val;
|
||||
switch (addr & 0xf)
|
||||
{
|
||||
case 0: case 2: case 4: case 6: /*Address registers*/
|
||||
dma.wp^=1;
|
||||
if (dma.wp) dma.ab[(addr>>1)&3]=(dma.ab[(addr>>1)&3]&0xFF00)|val;
|
||||
else dma.ab[(addr>>1)&3]=(dma.ab[(addr>>1)&3]&0xFF)|(val<<8);
|
||||
dma.ac[(addr>>1)&3]=dma.ab[(addr>>1)&3];
|
||||
dmaon[(addr>>1)&3]=1;
|
||||
// printf("DMA addr %i now %04X\n",(addr>>1)&3,dma.ac[(addr>>1)&3]);
|
||||
dma.wp ^= 1;
|
||||
if (dma.wp) dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0xff00) | val;
|
||||
else dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8);
|
||||
dma.ac[(addr >> 1) & 3] = dma.ab[(addr >> 1) & 3];
|
||||
dmaon[(addr >> 1) & 3] = 1;
|
||||
return;
|
||||
|
||||
case 1: case 3: case 5: case 7: /*Count registers*/
|
||||
dma.wp^=1;
|
||||
if (dma.wp) dma.cb[(addr>>1)&3]=(dma.cb[(addr>>1)&3]&0xFF00)|val;
|
||||
else dma.cb[(addr>>1)&3]=(dma.cb[(addr>>1)&3]&0xFF)|(val<<8);
|
||||
dma.cc[(addr>>1)&3]=dma.cb[(addr>>1)&3];
|
||||
dmaon[(addr>>1)&3]=1;
|
||||
// printf("DMA count %i now %04X\n",(addr>>1)&3,dma.cc[(addr>>1)&3]);
|
||||
dma.wp ^= 1;
|
||||
if (dma.wp) dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0xff00) | val;
|
||||
else dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8);
|
||||
dma.cc[(addr >> 1) & 3] = dma.cb[(addr >> 1) & 3];
|
||||
dmaon[(addr >> 1) & 3] = 1;
|
||||
return;
|
||||
|
||||
case 8: /*Control register*/
|
||||
dma.command = val;
|
||||
return;
|
||||
case 0xA: /*Mask*/
|
||||
if (val&4) dma.m|=(1<<(val&3));
|
||||
else dma.m&=~(1<<(val&3));
|
||||
|
||||
case 0xa: /*Mask*/
|
||||
if (val & 4) dma.m |= (1 << (val & 3));
|
||||
else dma.m &= ~(1 << (val & 3));
|
||||
return;
|
||||
case 0xB: /*Mode*/
|
||||
dma.mode[val&3]=val;
|
||||
|
||||
case 0xb: /*Mode*/
|
||||
dma.mode[val & 3] = val;
|
||||
return;
|
||||
case 0xC: /*Clear FF*/
|
||||
dma.wp=0;
|
||||
|
||||
case 0xc: /*Clear FF*/
|
||||
dma.wp = 0;
|
||||
return;
|
||||
case 0xD: /*Master clear*/
|
||||
dma.wp=0;
|
||||
dma.m=0xF;
|
||||
|
||||
case 0xd: /*Master clear*/
|
||||
dma.wp = 0;
|
||||
dma.m = 0xf;
|
||||
return;
|
||||
case 0xF: /*Mask write*/
|
||||
dma.m=val&0xF;
|
||||
|
||||
case 0xf: /*Mask write*/
|
||||
dma.m = val & 0xf;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -130,116 +126,103 @@ uint8_t dma16_read(uint16_t addr, void *priv)
|
|||
{
|
||||
uint8_t temp;
|
||||
// printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc);
|
||||
addr>>=1;
|
||||
switch (addr&0xF)
|
||||
addr >>= 1;
|
||||
switch (addr & 0xf)
|
||||
{
|
||||
case 0:
|
||||
if (((dma16.mode[0]>>2)&3)==2)
|
||||
{
|
||||
dma16.ac[0]++;
|
||||
dma16.cc[0]--;
|
||||
if (dma16.cc[0]<0)
|
||||
{
|
||||
dma16.ac[0]=dma16.ab[0];
|
||||
dma16.cc[0]=dma16.cb[0];
|
||||
}
|
||||
}
|
||||
case 2: case 4: case 6: /*Address registers*/
|
||||
dma16.wp^=1;
|
||||
if (dma16.wp) return dma16.ac[(addr>>1)&3]&0xFF;
|
||||
return dma16.ac[(addr>>1)&3]>>8;
|
||||
case 0: case 2: case 4: case 6: /*Address registers*/
|
||||
dma16.wp ^= 1;
|
||||
if (dma16.wp)
|
||||
return dma16.ac[(addr >> 1) & 3] & 0xff;
|
||||
return dma16.ac[(addr >> 1) & 3] >> 8;
|
||||
|
||||
case 1: case 3: case 5: case 7: /*Count registers*/
|
||||
dma16.wp^=1;
|
||||
// printf("Read %04X\n",dma16.cc[1]);
|
||||
if (dma16.wp) temp=dma16.cc[(addr>>1)&3]&0xFF;
|
||||
else temp=dma16.cc[(addr>>1)&3]>>8;
|
||||
// printf("%02X\n",temp);
|
||||
dma16.wp ^= 1;
|
||||
if (dma16.wp) temp = dma16.cc[(addr >> 1) & 3] & 0xff;
|
||||
else temp = dma16.cc[(addr >> 1) & 3] >> 8;
|
||||
return temp;
|
||||
|
||||
case 8: /*Status register*/
|
||||
temp=dma16.stat;
|
||||
dma16.stat=0;
|
||||
temp = dma16.stat;
|
||||
dma16.stat = 0;
|
||||
return temp;
|
||||
}
|
||||
return dma16regs[addr&0xF];
|
||||
return dma16regs[addr & 0xf];
|
||||
}
|
||||
|
||||
void dma16_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
// printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
addr>>=1;
|
||||
dma16regs[addr&0xF]=val;
|
||||
switch (addr&0xF)
|
||||
addr >>= 1;
|
||||
dma16regs[addr & 0xf] = val;
|
||||
switch (addr & 0xf)
|
||||
{
|
||||
case 0: case 2: case 4: case 6: /*Address registers*/
|
||||
dma16.wp^=1;
|
||||
if (dma16.wp) dma16.ab[(addr>>1)&3]=(dma16.ab[(addr>>1)&3]&0xFF00)|val;
|
||||
else dma16.ab[(addr>>1)&3]=(dma16.ab[(addr>>1)&3]&0xFF)|(val<<8);
|
||||
dma16.ac[(addr>>1)&3]=dma16.ab[(addr>>1)&3];
|
||||
dma16on[(addr>>1)&3]=1;
|
||||
// printf("dma16 addr %i now %04X\n",(addr>>1)&3,dma16.ac[(addr>>1)&3]);
|
||||
dma16.wp ^= 1;
|
||||
if (dma16.wp) dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0xff00) | val;
|
||||
else dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8);
|
||||
dma16.ac[(addr >> 1) & 3] = dma16.ab[(addr >> 1) & 3];
|
||||
dma16on[(addr >> 1) & 3] = 1;
|
||||
return;
|
||||
|
||||
case 1: case 3: case 5: case 7: /*Count registers*/
|
||||
dma16.wp^=1;
|
||||
if (dma16.wp) dma16.cb[(addr>>1)&3]=(dma16.cb[(addr>>1)&3]&0xFF00)|val;
|
||||
else dma16.cb[(addr>>1)&3]=(dma16.cb[(addr>>1)&3]&0xFF)|(val<<8);
|
||||
dma16.cc[(addr>>1)&3]=dma16.cb[(addr>>1)&3];
|
||||
dma16on[(addr>>1)&3]=1;
|
||||
// printf("dma16 count %i now %04X\n",(addr>>1)&3,dma16.cc[(addr>>1)&3]);
|
||||
dma16.wp ^= 1;
|
||||
if (dma16.wp) dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0xff00) | val;
|
||||
else dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8);
|
||||
dma16.cc[(addr >> 1) & 3] = dma16.cb[(addr >> 1) & 3];
|
||||
dma16on[(addr >> 1) & 3] = 1;
|
||||
return;
|
||||
|
||||
case 8: /*Control register*/
|
||||
return;
|
||||
case 0xA: /*Mask*/
|
||||
if (val&4) dma16.m|=(1<<(val&3));
|
||||
else dma16.m&=~(1<<(val&3));
|
||||
|
||||
case 0xa: /*Mask*/
|
||||
if (val & 4) dma16.m |= (1 << (val & 3));
|
||||
else dma16.m &= ~(1 << (val & 3));
|
||||
return;
|
||||
case 0xB: /*Mode*/
|
||||
dma16.mode[val&3]=val;
|
||||
|
||||
case 0xb: /*Mode*/
|
||||
dma16.mode[val & 3] = val;
|
||||
return;
|
||||
case 0xC: /*Clear FF*/
|
||||
dma16.wp=0;
|
||||
|
||||
case 0xc: /*Clear FF*/
|
||||
dma16.wp = 0;
|
||||
return;
|
||||
case 0xD: /*Master clear*/
|
||||
dma16.wp=0;
|
||||
dma16.m=0xF;
|
||||
|
||||
case 0xd: /*Master clear*/
|
||||
dma16.wp = 0;
|
||||
dma16.m = 0xf;
|
||||
return;
|
||||
case 0xF: /*Mask write*/
|
||||
dma16.m=val&0xF;
|
||||
|
||||
case 0xf: /*Mask write*/
|
||||
dma16.m = val&0xf;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t dmapages[16];
|
||||
|
||||
void dma_page_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
/* if (!(addr&0xF))
|
||||
{*/
|
||||
// pclog("Write page %03X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
// if (val==0x29 && pc==0xD25) output=1;
|
||||
// }
|
||||
dmapages[addr&0xF]=val;
|
||||
switch (addr&0xF)
|
||||
dmapages[addr & 0xf] = val;
|
||||
switch (addr & 0xf)
|
||||
{
|
||||
case 1:
|
||||
dma.page[2]=(AT)?val:val&0xF;
|
||||
dma.page[2] = (AT) ? val : val & 0xf;
|
||||
break;
|
||||
case 2:
|
||||
dma.page[3]=(AT)?val:val&0xF;
|
||||
dma.page[3] = (AT) ? val : val & 0xf;
|
||||
break;
|
||||
case 3:
|
||||
dma.page[1]=(AT)?val:val&0xF;
|
||||
// pclog("DMA1 page %02X\n",val);
|
||||
dma.page[1] = (AT) ? val : val & 0xf;
|
||||
break;
|
||||
case 0xB:
|
||||
dma16.page[1]=val;
|
||||
case 0xb:
|
||||
dma16.page[1] = val;
|
||||
break;
|
||||
}
|
||||
// printf("Page write %04X %02X\n",addr,val);
|
||||
}
|
||||
|
||||
uint8_t dma_page_read(uint16_t addr, void *priv)
|
||||
{
|
||||
return dmapages[addr&0xF];
|
||||
return dmapages[addr & 0xf];
|
||||
}
|
||||
|
||||
void dma_init()
|
||||
|
|
@ -264,35 +247,23 @@ void _dma_write(uint32_t addr, uint8_t val)
|
|||
{
|
||||
mem_writeb_phys(addr, val);
|
||||
}
|
||||
/*void writedma2(uint8_t val)
|
||||
{
|
||||
// printf("Write to %05X %02X %i\n",(dma.page[2]<<16)+dma.ac[2],val,dma.m&4);
|
||||
if (!(dma.m&4))
|
||||
{
|
||||
ram[((dma.page[2]<<16)+dma.ac[2])&rammask]=val;
|
||||
dma.ac[2]++;
|
||||
dma.cc[2]--;
|
||||
if (dma.cc[2]==-1)
|
||||
{
|
||||
dma.m|=4;
|
||||
dma.stat|=4;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
int dma_channel_read(int channel)
|
||||
{
|
||||
uint16_t temp;
|
||||
|
||||
if (!AT)
|
||||
refreshread();
|
||||
|
||||
if (channel < 4)
|
||||
{
|
||||
// pclog("Read DMA channel %i\n", channel);
|
||||
if (dma.m & (1 << channel))
|
||||
return DMA_NODATA;
|
||||
if ((dma.mode[channel] & 0xC) != 8)
|
||||
return DMA_NODATA;
|
||||
|
||||
temp = _dma_read(dma.ac[channel] + (dma.page[channel] << 16)); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
|
||||
// pclog(" - %02X %05X\n", temp, dma.ac[channel] + (dma.page[channel] << 16));
|
||||
|
||||
if (dma.mode[channel] & 0x20) dma.ac[channel]--;
|
||||
else dma.ac[channel]++;
|
||||
dma.cc[channel]--;
|
||||
|
|
@ -307,6 +278,9 @@ int dma_channel_read(int channel)
|
|||
dma.m |= (1 << channel);
|
||||
dma.stat |= (1 << channel);
|
||||
}
|
||||
|
||||
if (dma.m & (1 << channel))
|
||||
return temp | DMA_OVER;
|
||||
return temp;
|
||||
}
|
||||
else
|
||||
|
|
@ -316,8 +290,10 @@ int dma_channel_read(int channel)
|
|||
return DMA_NODATA;
|
||||
if ((dma16.mode[channel] & 0xC) != 8)
|
||||
return DMA_NODATA;
|
||||
|
||||
temp = _dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16)) |
|
||||
(_dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1) << 8);
|
||||
|
||||
if (dma16.mode[channel] & 0x20) dma16.ac[channel]--;
|
||||
else dma16.ac[channel]++;
|
||||
dma16.cc[channel]--;
|
||||
|
|
@ -327,24 +303,32 @@ int dma_channel_read(int channel)
|
|||
dma16.ac[channel] = dma16.ab[channel];
|
||||
dma16.stat |= (1 << channel);
|
||||
}
|
||||
else if (dma16.cc[channel]<=-1)
|
||||
else if (dma16.cc[channel] <= -1)
|
||||
{
|
||||
dma16.m |= (1 << channel);
|
||||
dma16.stat |= (1 << channel);
|
||||
}
|
||||
|
||||
if (dma.m & (1 << channel))
|
||||
return temp | DMA_OVER;
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
int dma_channel_write(int channel, uint16_t val)
|
||||
{
|
||||
if (!AT)
|
||||
refreshread();
|
||||
|
||||
if (channel < 4)
|
||||
{
|
||||
if (dma.m & (1 << channel))
|
||||
return DMA_NODATA;
|
||||
if ((dma.mode[channel] & 0xC) != 4)
|
||||
return DMA_NODATA;
|
||||
|
||||
_dma_write(dma.ac[channel] + (dma.page[channel] << 16), val);
|
||||
|
||||
if (dma.mode[channel]&0x20) dma.ac[channel]--;
|
||||
else dma.ac[channel]++;
|
||||
dma.cc[channel]--;
|
||||
|
|
@ -359,6 +343,9 @@ int dma_channel_write(int channel, uint16_t val)
|
|||
dma.m |= (1 << channel);
|
||||
dma.stat |= (1 << channel);
|
||||
}
|
||||
|
||||
if (dma.m & (1 << channel))
|
||||
return DMA_OVER;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -367,8 +354,10 @@ int dma_channel_write(int channel, uint16_t val)
|
|||
return DMA_NODATA;
|
||||
if ((dma16.mode[channel] & 0xC) != 4)
|
||||
return DMA_NODATA;
|
||||
|
||||
_dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16), val);
|
||||
_dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1, val >> 8);
|
||||
|
||||
if (dma16.mode[channel]&0x20) dma16.ac[channel]--;
|
||||
else dma16.ac[channel]++;
|
||||
dma16.cc[channel]--;
|
||||
|
|
@ -383,257 +372,9 @@ int dma_channel_write(int channel, uint16_t val)
|
|||
dma16.m |= (1 << channel);
|
||||
dma16.stat |= (1 << channel);
|
||||
}
|
||||
|
||||
if (dma.m & (1 << channel))
|
||||
return DMA_OVER;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int sbbufferpos;
|
||||
int readdma1()
|
||||
{
|
||||
uint8_t temp;
|
||||
pclog("readdma1 : Read DMA1 %02X %02X %i\n",dma.m,dma.mode[1], dma.cc[1]);
|
||||
if (dma.m & (1 << 1))
|
||||
return DMA_NODATA;
|
||||
if ((dma.mode[1]&0xC)!=8)
|
||||
return DMA_NODATA;
|
||||
temp=_dma_read((dma.ac[1]+(dma.page[1]<<16))&rammask); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
|
||||
pclog("readdma1 : DMA1 %02X %05X\n",temp,(dma.ac[1]+(dma.page[1]<<16))&rammask);
|
||||
if (dma.mode[1]&0x20) dma.ac[1]--;
|
||||
else dma.ac[1]++;
|
||||
dma.cc[1]--;
|
||||
if (!dma.cc[1] && (dma.mode[1]&0x10))
|
||||
{
|
||||
dma.cc[1]=dma.cb[1]+1;
|
||||
dma.ac[1]=dma.ab[1];
|
||||
dma.stat |= (1 << 1);
|
||||
}
|
||||
else if (dma.cc[1]<=-1)
|
||||
{
|
||||
dma.m |= (1 << 1);
|
||||
dma.stat |= (1 << 1);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
uint8_t readdma2()
|
||||
{
|
||||
uint8_t temp;
|
||||
// pclog("Read DMA2 %02X %02X %i\n",dma.m,dma.mode[2], dma.cc[2]);
|
||||
if (dma.m&4)
|
||||
{
|
||||
fdc_abort();
|
||||
return 0xFF;
|
||||
}
|
||||
if ((dma.mode[2]&0xC)!=8)
|
||||
{
|
||||
fdc_abort();
|
||||
return 0xFF;
|
||||
}
|
||||
temp=_dma_read((dma.ac[2]+(dma.page[2]<<16))&rammask); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
|
||||
// pclog("DMA2 %02X %05X\n",temp,(dma.ac[2]+(dma.page[2]<<16))&rammask);
|
||||
if (dma.mode[2]&0x20) dma.ac[2]--;
|
||||
else dma.ac[2]++;
|
||||
dma.cc[2]--;
|
||||
if (!dma.cc[2] && (dma.mode[2]&0x10))
|
||||
{
|
||||
dma.cc[2]=dma.cb[2]+1;
|
||||
dma.ac[2]=dma.ab[2];
|
||||
dma.stat |= (1 << 2);
|
||||
}
|
||||
else if (dma.cc[2]<=-1)
|
||||
{
|
||||
dma.m|=4;
|
||||
dma.stat |= (1 << 2);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
int readdma3()
|
||||
{
|
||||
uint8_t temp;
|
||||
// pclog("Read DMA1 %02X %02X %i\n",dma.m,dma.mode[1], dma.cc[1]);
|
||||
if (dma.m & (1 << 3))
|
||||
return DMA_NODATA;
|
||||
if ((dma.mode[3]&0xC)!=8)
|
||||
return DMA_NODATA;
|
||||
temp=_dma_read((dma.ac[3]+(dma.page[3]<<16))&rammask); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask];
|
||||
//pclog("DMA3 %02X %05X\n",temp,(dma.ac[3]+(dma.page[3]<<16))&rammask);
|
||||
if (dma.mode[3]&0x20) dma.ac[3]--;
|
||||
else dma.ac[3]++;
|
||||
dma.cc[3]--;
|
||||
if (!dma.cc[3] && (dma.mode[3]&0x10))
|
||||
{
|
||||
dma.cc[3]=dma.cb[3]+1;
|
||||
dma.ac[3]=dma.ab[3];
|
||||
dma.stat |= (1 << 3);
|
||||
}
|
||||
else if (dma.cc[3]<=-1)
|
||||
{
|
||||
dma.m |= (1 << 3);
|
||||
dma.stat |= (1 << 3);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
void writedma1(uint8_t temp)
|
||||
{
|
||||
// pclog("Write DMA1 %02X %02X %04X\n",dma.m,dma.mode[1],dma.cc[1]);
|
||||
if (dma.m & (1 << 1))
|
||||
return;
|
||||
if ((dma.mode[1] & 0xC) != 4)
|
||||
return;
|
||||
// pclog("Write %05X %05X %02X\n",(dma.ac[2]+(dma.page[2]<<16)),rammask,temp);
|
||||
// ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]=temp;
|
||||
_dma_write((dma.ac[1]+(dma.page[1]<<16))&rammask,temp);
|
||||
if (dma.mode[1]&0x20) dma.ac[1]--;
|
||||
else dma.ac[1]++;
|
||||
dma.cc[1]--;
|
||||
if (!dma.cc[1] && (dma.mode[1]&0x10))
|
||||
{
|
||||
dma.cc[1]=dma.cb[1]+1;
|
||||
dma.ac[1]=dma.ab[1];
|
||||
dma.stat |= (1 << 1);
|
||||
}
|
||||
else if (dma.cc[1]<=-1)
|
||||
{
|
||||
// pclog("Reached TC\n");
|
||||
dma.m |= (1 << 1);
|
||||
dma.stat |= (1 << 1);
|
||||
}
|
||||
}
|
||||
void writedma2(uint8_t temp)
|
||||
{
|
||||
// pclog("Write DMA2 %02X %02X %04X\n",dma.m,dma.mode[2],dma.cc[2]);
|
||||
if (dma.m&4)
|
||||
{
|
||||
fdc_abort();
|
||||
return;
|
||||
}
|
||||
if ((dma.mode[2]&0xC)!=4)
|
||||
{
|
||||
fdc_abort();
|
||||
return;
|
||||
}
|
||||
// pclog("Write %05X %05X %02X\n",(dma.ac[2]+(dma.page[2]<<16)),rammask,temp);
|
||||
// ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]=temp;
|
||||
_dma_write((dma.ac[2]+(dma.page[2]<<16))&rammask,temp);
|
||||
if (dma.mode[2]&0x20) dma.ac[2]--;
|
||||
else dma.ac[2]++;
|
||||
dma.cc[2]--;
|
||||
if (!dma.cc[2] && (dma.mode[2]&0x10))
|
||||
{
|
||||
dma.cc[2]=dma.cb[2]+1;
|
||||
dma.ac[2]=dma.ab[2];
|
||||
dma.stat |= (1 << 2);
|
||||
}
|
||||
else if (dma.cc[2]<=-1)
|
||||
{
|
||||
// pclog("Reached TC\n");
|
||||
fdc_abort();
|
||||
dma.m|=4;
|
||||
dma.stat |= (1 << 2);
|
||||
}
|
||||
}
|
||||
void writedma3(uint8_t temp)
|
||||
{
|
||||
// pclog("Write DMA3 %02X %02X %04X\n",dma.m,dma.mode[3],dma.cc[3]);
|
||||
if (dma.m & (1 << 3))
|
||||
return;
|
||||
if ((dma.mode[3] & 0xC) != 4)
|
||||
return;
|
||||
// pclog("Write %05X %05X %02X\n",(dma.ac[2]+(dma.page[2]<<16)),rammask,temp);
|
||||
// ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]=temp;
|
||||
_dma_write((dma.ac[3]+(dma.page[3]<<16))&rammask,temp);
|
||||
if (dma.mode[3]&0x20) dma.ac[3]--;
|
||||
else dma.ac[3]++;
|
||||
dma.cc[3]--;
|
||||
if (!dma.cc[3] && (dma.mode[3]&0x10))
|
||||
{
|
||||
dma.cc[3]=dma.cb[3]+1;
|
||||
dma.ac[3]=dma.ab[3];
|
||||
dma.stat |= (1 << 3);
|
||||
}
|
||||
else if (dma.cc[3]<=-1)
|
||||
{
|
||||
// pclog("Reached TC\n");
|
||||
dma.m |= (1 << 3);
|
||||
dma.stat |= (1 << 3);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t readdma5()
|
||||
{
|
||||
uint16_t temp=0;
|
||||
// pclog("Read DMA5 %i %04X\n",dma16on[1],dma16.cc[1]);
|
||||
/*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);
|
||||
//readmemwl(dma16.ac[1]+(dma16.page[1]<<16));
|
||||
// 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);
|
||||
if (!dma16on[1])
|
||||
{
|
||||
// printf("DMA off!\n");
|
||||
return temp;
|
||||
}
|
||||
dma16.ac[1]++;
|
||||
dma16.cc[1]--;
|
||||
if (dma16.cc[1]<=-1 && (dma16.mode[1]&0x10))
|
||||
{
|
||||
dma16.cc[1]=dma16.cb[1];
|
||||
dma16.ac[1]=dma16.ab[1];
|
||||
dma16.stat |= (1 << 1);
|
||||
}
|
||||
else if (dma16.cc[1]<=-1)
|
||||
{
|
||||
dma16on[1]=0;
|
||||
dma16.stat |= (1 << 1);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
void writedma5(uint16_t temp)
|
||||
{
|
||||
if (!dma16on[1]) return;
|
||||
ram[((dma16.ac[1]<<1)+((dma16.page[1]&~1)<<16))&rammask]=temp;
|
||||
ram[((dma16.ac[1]<<1)+((dma16.page[1]&~1)<<16)+1)&rammask]=temp>>8;
|
||||
|
||||
dma16.ac[1]++;
|
||||
dma16.cc[1]--;
|
||||
if (dma16.cc[1]<=-1 && (dma16.mode[1]&0x10))
|
||||
{
|
||||
dma16.cc[1]=dma16.cb[1];
|
||||
dma16.ac[1]=dma16.ab[1];
|
||||
dma16.stat |= (1 << 1);
|
||||
}
|
||||
else if (dma16.cc[1]<=-1)
|
||||
{
|
||||
dma16on[1]=0;
|
||||
dma16.stat |= (1 << 1);
|
||||
}
|
||||
}
|
||||
|
||||
void readdma0()
|
||||
{
|
||||
if (AT) ppi.pb^=0x10;
|
||||
if (dma.command & 4) return;
|
||||
// if (AMSTRAD) return;
|
||||
refreshread();
|
||||
// pclog("Read refresh %02X %02X %04X %04X\n",dma.m,dma.mode[0],dma.ac[0],dma.cc[0]);
|
||||
if (dma.m&1) return;
|
||||
// readmembl((dma.page[0]<<16)+dma.ac[0]);
|
||||
// if (!(dma.m&1))
|
||||
// {
|
||||
dma.ac[0]+=2;
|
||||
dma.cc[0]--;
|
||||
if (dma.cc[0]==-1)
|
||||
{
|
||||
dma.ac[0]=dma.ab[0];
|
||||
dma.cc[0]=dma.cb[0];
|
||||
dma.stat |= 1;
|
||||
}
|
||||
// }
|
||||
// ppi.pb^=0x10;
|
||||
}
|
||||
|
||||
void dumpdma()
|
||||
{
|
||||
printf("Address : %04X %04X %04X %04X\n",dma.ac[0],dma.ac[1],dma.ac[2],dma.ac[3]);
|
||||
printf("Count : %04X %04X %04X %04X\n",dma.cc[0],dma.cc[1],dma.cc[2],dma.cc[3]);
|
||||
printf("Mask %02X Stat %02X\n",dma.m,dma.stat);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ void dma16_init();
|
|||
void dma_reset();
|
||||
|
||||
#define DMA_NODATA -1
|
||||
#define DMA_OVER 0x10000
|
||||
|
||||
void readdma0();
|
||||
int readdma1();
|
||||
|
|
|
|||
29
src/fdc.c
29
src/fdc.c
|
|
@ -104,6 +104,7 @@ void fdc_reset()
|
|||
fdc.st0=0xC0;
|
||||
fdc.lock = 0;
|
||||
fdc.head = 0;
|
||||
fdc.abort = 0;
|
||||
if (!AT)
|
||||
fdc.rate=2;
|
||||
// pclog("Reset FDC\n");
|
||||
|
|
@ -400,14 +401,6 @@ uint8_t fdc_read(uint16_t addr, void *priv)
|
|||
return temp;
|
||||
}
|
||||
|
||||
int fdc_abort_f = 0;
|
||||
|
||||
void fdc_abort()
|
||||
{
|
||||
fdc_abort_f = 1;
|
||||
// pclog("FDC ABORT\n");
|
||||
}
|
||||
|
||||
static int fdc_reset_stat = 0;
|
||||
void fdc_poll()
|
||||
{
|
||||
|
|
@ -437,7 +430,7 @@ void fdc_poll()
|
|||
{
|
||||
fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos];
|
||||
// pclog("Read %i %i %i %i %02X\n",fdc.head,fdc.track,fdc.sector,fdc.pos,fdc.dat);
|
||||
writedma2(fdc.dat);
|
||||
dma_channel_write(2, fdc.dat);
|
||||
timer_process();
|
||||
disctime = 60 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
|
|
@ -495,10 +488,9 @@ void fdc_poll()
|
|||
}
|
||||
if (fdc.pos<512)
|
||||
{
|
||||
temp=readdma2();
|
||||
if (fdc_abort_f)
|
||||
temp = dma_channel_read(2);
|
||||
if (temp == DMA_NODATA)
|
||||
{
|
||||
fdc_abort_f=0;
|
||||
discint=0xFD;
|
||||
timer_process();
|
||||
disctime = 50 * (1 << TIMER_SHIFT);
|
||||
|
|
@ -541,21 +533,22 @@ void fdc_poll()
|
|||
case 6: /*Read data*/
|
||||
if (!fdc.pos)
|
||||
{
|
||||
// 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);
|
||||
// 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]);
|
||||
}
|
||||
if (fdc.pos<512)
|
||||
{
|
||||
fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos];
|
||||
// printf("Read disc %i %i %i %i %02X\n",fdc.head,fdc.track,fdc.sector,fdc.pos,fdc.dat);
|
||||
writedma2(fdc.dat);
|
||||
if (dma_channel_write(2, fdc.dat) & DMA_OVER)
|
||||
fdc.abort = 1;
|
||||
timer_process();
|
||||
disctime = 60 * (1 << TIMER_SHIFT);
|
||||
timer_update_outstanding();
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("End of command - params to go!\n");
|
||||
fdc_abort_f = 0;
|
||||
// printf("End of command - params to go! %i %i %i\n", fdc.track[fdc.drive], fdc.head, fdc.sector);
|
||||
fdc.abort = 0;
|
||||
disctime=0;
|
||||
discint=-2;
|
||||
picint(0x40);
|
||||
|
|
@ -606,8 +599,8 @@ void fdc_poll()
|
|||
else
|
||||
fdc.pos = 512;
|
||||
}
|
||||
if (fdc_abort_f)
|
||||
fdc.pos = 512;
|
||||
if (fdc.abort)
|
||||
fdc.pos = 512;
|
||||
}
|
||||
return;
|
||||
/* printf("Read data\n");
|
||||
|
|
|
|||
|
|
@ -264,6 +264,7 @@ typedef struct FDC
|
|||
int lock;
|
||||
int perp;
|
||||
uint8_t config, pretrk;
|
||||
int abort;
|
||||
} FDC;
|
||||
|
||||
FDC fdc;
|
||||
|
|
|
|||
|
|
@ -276,7 +276,9 @@ void pit_poll()
|
|||
}
|
||||
// if (output) pclog("%f %04X %02X\n",pit.c[1],pit.l[1],pit.ctrls[1]);
|
||||
// printf("DMA0!\n");
|
||||
readdma0();
|
||||
dma_channel_read(0);
|
||||
if (AT)
|
||||
ppi.pb ^= 0x10;
|
||||
}
|
||||
if (pit.c[2]<1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -86,14 +86,14 @@ void adgold_getsamp_dma(adgold_t *adgold, int channel)
|
|||
if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127))
|
||||
return;
|
||||
|
||||
temp = readdma1();
|
||||
temp = dma_channel_read(1);
|
||||
// pclog("adgold DMA1 return %02X %i L\n", temp, channel);
|
||||
if (temp == -1) return;
|
||||
if (temp == DMA_NODATA) return;
|
||||
adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp;
|
||||
adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;
|
||||
if (adgold->adgold_mma_regs[channel][0xc] & 0x60)
|
||||
{
|
||||
temp = readdma1();
|
||||
temp = dma_channel_read(1);
|
||||
// pclog("adgold DMA1 return %02X %i H\n", temp, channel);
|
||||
adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp;
|
||||
adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;
|
||||
|
|
|
|||
Loading…
Reference in a new issue