Cleaned up DMA emulation.

This commit is contained in:
TomW 2013-10-27 14:37:01 +00:00
commit a514d2fe4b
6 changed files with 178 additions and 440 deletions

569
src/dma.c
View file

@ -6,122 +6,118 @@
#include "mem.h" #include "mem.h"
#include "video.h" #include "video.h"
extern int ins; static uint8_t dmaregs[16];
int output; static int dmaon[4];
uint8_t dmaregs[16]; static uint8_t dma16regs[16];
int dmaon[4]; static int dma16on[4];
uint8_t dma16regs[16]; static uint8_t dmapages[16];
int dma16on[4];
void dma_reset() void dma_reset()
{ {
int c; int c;
dma.wp=0; dma.wp = 0;
for (c=0;c<16;c++) dmaregs[c]=0; for (c = 0; c < 16; c++)
for (c=0;c<4;c++) dmaregs[c] = 0;
for (c = 0; c < 4; c++)
{ {
dma.mode[c]=0; dma.mode[c] = 0;
dma.ac[c]=0; dma.ac[c] = 0;
dma.cc[c]=0; dma.cc[c] = 0;
dma.ab[c]=0; dma.ab[c] = 0;
dma.cb[c]=0; dma.cb[c] = 0;
} }
dma.m=0; dma.m = 0;
dma16.wp=0; dma16.wp = 0;
for (c=0;c<16;c++) dma16regs[c]=0; for (c = 0; c < 16; c++)
for (c=0;c<4;c++) dma16regs[c] = 0;
for (c = 0; c < 4; c++)
{ {
dma16.mode[c]=0; dma16.mode[c] = 0;
dma16.ac[c]=0; dma16.ac[c] = 0;
dma16.cc[c]=0; dma16.cc[c] = 0;
dma16.ab[c]=0; dma16.ab[c] = 0;
dma16.cb[c]=0; dma16.cb[c] = 0;
} }
dma16.m=0; dma16.m = 0;
} }
uint8_t dma_read(uint16_t addr, void *priv) uint8_t dma_read(uint16_t addr, void *priv)
{ {
uint8_t temp; uint8_t temp;
// printf("Read DMA %04X %04X:%04X %i %02X\n",addr,CS,pc, pic_intpending, pic.pend); // printf("Read DMA %04X %04X:%04X %i %02X\n",addr,CS,pc, pic_intpending, pic.pend);
switch (addr&0xF) switch (addr & 0xf)
{ {
case 0: case 0: case 2: case 4: case 6: /*Address registers*/
/* if (((dma.mode[0]>>2)&3)==2) dma.wp ^= 1;
{ if (dma.wp)
dma.ac[0]++; return dma.ac[(addr >> 1) & 3] & 0xff;
dma.cc[0]--; return dma.ac[(addr >> 1) & 3] >> 8;
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 1: case 3: case 5: case 7: /*Count registers*/ 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;
dma.wp^=1; if (dma.wp) temp = dma.cc[(addr >> 1) & 3] & 0xff;
if (dma.wp) temp=dma.cc[(addr>>1)&3]&0xFF; else temp = dma.cc[(addr >> 1) & 3] >> 8;
else temp=dma.cc[(addr>>1)&3]>>8;
// printf("%02X\n",temp);
return temp; return temp;
case 8: /*Status register*/ case 8: /*Status register*/
temp=dma.stat; temp = dma.stat;
dma.stat=0; dma.stat = 0;
// pclog("Read DMA status %02X\n", temp);
return temp; return temp;
case 0xD:
case 0xd:
return 0; return 0;
} }
// printf("Bad DMA read %04X %04X:%04X\n",addr,CS,pc); // 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) void dma_write(uint16_t addr, uint8_t val, void *priv)
{ {
printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc); // printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc);
dmaregs[addr&0xF]=val; dmaregs[addr & 0xf] = val;
switch (addr&0xF) switch (addr & 0xf)
{ {
case 0: case 2: case 4: case 6: /*Address registers*/ case 0: case 2: case 4: case 6: /*Address registers*/
dma.wp^=1; dma.wp ^= 1;
if (dma.wp) dma.ab[(addr>>1)&3]=(dma.ab[(addr>>1)&3]&0xFF00)|val; 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); else dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8);
dma.ac[(addr>>1)&3]=dma.ab[(addr>>1)&3]; dma.ac[(addr >> 1) & 3] = dma.ab[(addr >> 1) & 3];
dmaon[(addr>>1)&3]=1; dmaon[(addr >> 1) & 3] = 1;
// printf("DMA addr %i now %04X\n",(addr>>1)&3,dma.ac[(addr>>1)&3]);
return; return;
case 1: case 3: case 5: case 7: /*Count registers*/ case 1: case 3: case 5: case 7: /*Count registers*/
dma.wp^=1; dma.wp ^= 1;
if (dma.wp) dma.cb[(addr>>1)&3]=(dma.cb[(addr>>1)&3]&0xFF00)|val; 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); else dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8);
dma.cc[(addr>>1)&3]=dma.cb[(addr>>1)&3]; dma.cc[(addr >> 1) & 3] = dma.cb[(addr >> 1) & 3];
dmaon[(addr>>1)&3]=1; dmaon[(addr >> 1) & 3] = 1;
// printf("DMA count %i now %04X\n",(addr>>1)&3,dma.cc[(addr>>1)&3]);
return; return;
case 8: /*Control register*/ case 8: /*Control register*/
dma.command = val; dma.command = val;
return; return;
case 0xA: /*Mask*/
if (val&4) dma.m|=(1<<(val&3)); case 0xa: /*Mask*/
else dma.m&=~(1<<(val&3)); if (val & 4) dma.m |= (1 << (val & 3));
else dma.m &= ~(1 << (val & 3));
return; return;
case 0xB: /*Mode*/
dma.mode[val&3]=val; case 0xb: /*Mode*/
dma.mode[val & 3] = val;
return; return;
case 0xC: /*Clear FF*/
dma.wp=0; case 0xc: /*Clear FF*/
dma.wp = 0;
return; return;
case 0xD: /*Master clear*/
dma.wp=0; case 0xd: /*Master clear*/
dma.m=0xF; dma.wp = 0;
dma.m = 0xf;
return; return;
case 0xF: /*Mask write*/
dma.m=val&0xF; case 0xf: /*Mask write*/
dma.m = val & 0xf;
return; return;
} }
} }
@ -130,116 +126,103 @@ uint8_t dma16_read(uint16_t addr, void *priv)
{ {
uint8_t temp; uint8_t temp;
// printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc); // printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc);
addr>>=1; addr >>= 1;
switch (addr&0xF) switch (addr & 0xf)
{ {
case 0: case 0: case 2: case 4: case 6: /*Address registers*/
if (((dma16.mode[0]>>2)&3)==2) dma16.wp ^= 1;
{ if (dma16.wp)
dma16.ac[0]++; return dma16.ac[(addr >> 1) & 3] & 0xff;
dma16.cc[0]--; return dma16.ac[(addr >> 1) & 3] >> 8;
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 1: case 3: case 5: case 7: /*Count registers*/ case 1: case 3: case 5: case 7: /*Count registers*/
dma16.wp^=1; dma16.wp ^= 1;
// printf("Read %04X\n",dma16.cc[1]); if (dma16.wp) temp = dma16.cc[(addr >> 1) & 3] & 0xff;
if (dma16.wp) temp=dma16.cc[(addr>>1)&3]&0xFF; else temp = dma16.cc[(addr >> 1) & 3] >> 8;
else temp=dma16.cc[(addr>>1)&3]>>8;
// printf("%02X\n",temp);
return temp; return temp;
case 8: /*Status register*/ case 8: /*Status register*/
temp=dma16.stat; temp = dma16.stat;
dma16.stat=0; dma16.stat = 0;
return temp; return temp;
} }
return dma16regs[addr&0xF]; return dma16regs[addr & 0xf];
} }
void dma16_write(uint16_t addr, uint8_t val, void *priv) void dma16_write(uint16_t addr, uint8_t val, void *priv)
{ {
// printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc); // printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc);
addr>>=1; addr >>= 1;
dma16regs[addr&0xF]=val; dma16regs[addr & 0xf] = val;
switch (addr&0xF) switch (addr & 0xf)
{ {
case 0: case 2: case 4: case 6: /*Address registers*/ case 0: case 2: case 4: case 6: /*Address registers*/
dma16.wp^=1; dma16.wp ^= 1;
if (dma16.wp) dma16.ab[(addr>>1)&3]=(dma16.ab[(addr>>1)&3]&0xFF00)|val; 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); else dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8);
dma16.ac[(addr>>1)&3]=dma16.ab[(addr>>1)&3]; dma16.ac[(addr >> 1) & 3] = dma16.ab[(addr >> 1) & 3];
dma16on[(addr>>1)&3]=1; dma16on[(addr >> 1) & 3] = 1;
// printf("dma16 addr %i now %04X\n",(addr>>1)&3,dma16.ac[(addr>>1)&3]);
return; return;
case 1: case 3: case 5: case 7: /*Count registers*/ case 1: case 3: case 5: case 7: /*Count registers*/
dma16.wp^=1; dma16.wp ^= 1;
if (dma16.wp) dma16.cb[(addr>>1)&3]=(dma16.cb[(addr>>1)&3]&0xFF00)|val; 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); else dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8);
dma16.cc[(addr>>1)&3]=dma16.cb[(addr>>1)&3]; dma16.cc[(addr >> 1) & 3] = dma16.cb[(addr >> 1) & 3];
dma16on[(addr>>1)&3]=1; dma16on[(addr >> 1) & 3] = 1;
// printf("dma16 count %i now %04X\n",(addr>>1)&3,dma16.cc[(addr>>1)&3]);
return; return;
case 8: /*Control register*/ case 8: /*Control register*/
return; return;
case 0xA: /*Mask*/
if (val&4) dma16.m|=(1<<(val&3)); case 0xa: /*Mask*/
else dma16.m&=~(1<<(val&3)); if (val & 4) dma16.m |= (1 << (val & 3));
else dma16.m &= ~(1 << (val & 3));
return; return;
case 0xB: /*Mode*/
dma16.mode[val&3]=val; case 0xb: /*Mode*/
dma16.mode[val & 3] = val;
return; return;
case 0xC: /*Clear FF*/
dma16.wp=0; case 0xc: /*Clear FF*/
dma16.wp = 0;
return; return;
case 0xD: /*Master clear*/
dma16.wp=0; case 0xd: /*Master clear*/
dma16.m=0xF; dma16.wp = 0;
dma16.m = 0xf;
return; return;
case 0xF: /*Mask write*/
dma16.m=val&0xF; case 0xf: /*Mask write*/
dma16.m = val&0xf;
return; return;
} }
} }
uint8_t dmapages[16];
void dma_page_write(uint16_t addr, uint8_t val, void *priv) void dma_page_write(uint16_t addr, uint8_t val, void *priv)
{ {
/* if (!(addr&0xF)) dmapages[addr & 0xf] = val;
{*/ switch (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)
{ {
case 1: case 1:
dma.page[2]=(AT)?val:val&0xF; dma.page[2] = (AT) ? val : val & 0xf;
break; break;
case 2: case 2:
dma.page[3]=(AT)?val:val&0xF; dma.page[3] = (AT) ? val : val & 0xf;
break; break;
case 3: case 3:
dma.page[1]=(AT)?val:val&0xF; dma.page[1] = (AT) ? val : val & 0xf;
// pclog("DMA1 page %02X\n",val);
break; break;
case 0xB: case 0xb:
dma16.page[1]=val; dma16.page[1] = val;
break; break;
} }
// printf("Page write %04X %02X\n",addr,val);
} }
uint8_t dma_page_read(uint16_t addr, void *priv) uint8_t dma_page_read(uint16_t addr, void *priv)
{ {
return dmapages[addr&0xF]; return dmapages[addr & 0xf];
} }
void dma_init() void dma_init()
@ -264,35 +247,23 @@ void _dma_write(uint32_t addr, uint8_t val)
{ {
mem_writeb_phys(addr, 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) int dma_channel_read(int channel)
{ {
uint16_t temp; uint16_t temp;
if (!AT)
refreshread();
if (channel < 4) if (channel < 4)
{ {
// pclog("Read DMA channel %i\n", channel);
if (dma.m & (1 << channel)) if (dma.m & (1 << channel))
return DMA_NODATA; return DMA_NODATA;
if ((dma.mode[channel] & 0xC) != 8) if ((dma.mode[channel] & 0xC) != 8)
return DMA_NODATA; return DMA_NODATA;
temp = _dma_read(dma.ac[channel] + (dma.page[channel] << 16)); //ram[(dma.ac[2]+(dma.page[2]<<16))&rammask]; 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]--; if (dma.mode[channel] & 0x20) dma.ac[channel]--;
else dma.ac[channel]++; else dma.ac[channel]++;
dma.cc[channel]--; dma.cc[channel]--;
@ -307,6 +278,9 @@ int dma_channel_read(int channel)
dma.m |= (1 << channel); dma.m |= (1 << channel);
dma.stat |= (1 << channel); dma.stat |= (1 << channel);
} }
if (dma.m & (1 << channel))
return temp | DMA_OVER;
return temp; return temp;
} }
else else
@ -316,8 +290,10 @@ int dma_channel_read(int channel)
return DMA_NODATA; return DMA_NODATA;
if ((dma16.mode[channel] & 0xC) != 8) if ((dma16.mode[channel] & 0xC) != 8)
return DMA_NODATA; return DMA_NODATA;
temp = _dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16)) | 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); (_dma_read((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1) << 8);
if (dma16.mode[channel] & 0x20) dma16.ac[channel]--; if (dma16.mode[channel] & 0x20) dma16.ac[channel]--;
else dma16.ac[channel]++; else dma16.ac[channel]++;
dma16.cc[channel]--; dma16.cc[channel]--;
@ -327,24 +303,32 @@ int dma_channel_read(int channel)
dma16.ac[channel] = dma16.ab[channel]; dma16.ac[channel] = dma16.ab[channel];
dma16.stat |= (1 << channel); dma16.stat |= (1 << channel);
} }
else if (dma16.cc[channel]<=-1) else if (dma16.cc[channel] <= -1)
{ {
dma16.m |= (1 << channel); dma16.m |= (1 << channel);
dma16.stat |= (1 << channel); dma16.stat |= (1 << channel);
} }
if (dma.m & (1 << channel))
return temp | DMA_OVER;
return temp; return temp;
} }
} }
int dma_channel_write(int channel, uint16_t val) int dma_channel_write(int channel, uint16_t val)
{ {
if (!AT)
refreshread();
if (channel < 4) if (channel < 4)
{ {
if (dma.m & (1 << channel)) if (dma.m & (1 << channel))
return DMA_NODATA; return DMA_NODATA;
if ((dma.mode[channel] & 0xC) != 4) if ((dma.mode[channel] & 0xC) != 4)
return DMA_NODATA; return DMA_NODATA;
_dma_write(dma.ac[channel] + (dma.page[channel] << 16), val); _dma_write(dma.ac[channel] + (dma.page[channel] << 16), val);
if (dma.mode[channel]&0x20) dma.ac[channel]--; if (dma.mode[channel]&0x20) dma.ac[channel]--;
else dma.ac[channel]++; else dma.ac[channel]++;
dma.cc[channel]--; dma.cc[channel]--;
@ -359,6 +343,9 @@ int dma_channel_write(int channel, uint16_t val)
dma.m |= (1 << channel); dma.m |= (1 << channel);
dma.stat |= (1 << channel); dma.stat |= (1 << channel);
} }
if (dma.m & (1 << channel))
return DMA_OVER;
} }
else else
{ {
@ -367,8 +354,10 @@ int dma_channel_write(int channel, uint16_t val)
return DMA_NODATA; return DMA_NODATA;
if ((dma16.mode[channel] & 0xC) != 4) if ((dma16.mode[channel] & 0xC) != 4)
return DMA_NODATA; 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), val);
_dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1, val >> 8); _dma_write((dma16.ac[channel] << 1) + ((dma16.page[channel] & ~1) << 16) + 1, val >> 8);
if (dma16.mode[channel]&0x20) dma16.ac[channel]--; if (dma16.mode[channel]&0x20) dma16.ac[channel]--;
else dma16.ac[channel]++; else dma16.ac[channel]++;
dma16.cc[channel]--; dma16.cc[channel]--;
@ -383,257 +372,9 @@ int dma_channel_write(int channel, uint16_t val)
dma16.m |= (1 << channel); dma16.m |= (1 << channel);
dma16.stat |= (1 << channel); dma16.stat |= (1 << channel);
} }
if (dma.m & (1 << channel))
return DMA_OVER;
} }
return 0; 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);
}

View file

@ -3,6 +3,7 @@ void dma16_init();
void dma_reset(); void dma_reset();
#define DMA_NODATA -1 #define DMA_NODATA -1
#define DMA_OVER 0x10000
void readdma0(); void readdma0();
int readdma1(); int readdma1();

View file

@ -104,6 +104,7 @@ void fdc_reset()
fdc.st0=0xC0; fdc.st0=0xC0;
fdc.lock = 0; fdc.lock = 0;
fdc.head = 0; fdc.head = 0;
fdc.abort = 0;
if (!AT) if (!AT)
fdc.rate=2; fdc.rate=2;
// pclog("Reset FDC\n"); // pclog("Reset FDC\n");
@ -400,14 +401,6 @@ uint8_t fdc_read(uint16_t addr, void *priv)
return temp; return temp;
} }
int fdc_abort_f = 0;
void fdc_abort()
{
fdc_abort_f = 1;
// pclog("FDC ABORT\n");
}
static int fdc_reset_stat = 0; static int fdc_reset_stat = 0;
void fdc_poll() 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]; 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); // 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(); timer_process();
disctime = 60 * (1 << TIMER_SHIFT); disctime = 60 * (1 << TIMER_SHIFT);
timer_update_outstanding(); timer_update_outstanding();
@ -495,10 +488,9 @@ void fdc_poll()
} }
if (fdc.pos<512) if (fdc.pos<512)
{ {
temp=readdma2(); temp = dma_channel_read(2);
if (fdc_abort_f) if (temp == DMA_NODATA)
{ {
fdc_abort_f=0;
discint=0xFD; discint=0xFD;
timer_process(); timer_process();
disctime = 50 * (1 << TIMER_SHIFT); disctime = 50 * (1 << TIMER_SHIFT);
@ -541,21 +533,22 @@ void fdc_poll()
case 6: /*Read data*/ case 6: /*Read data*/
if (!fdc.pos) 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) if (fdc.pos<512)
{ {
fdc.dat=disc[fdc.drive][fdc.head][fdc.track[fdc.drive]][fdc.sector-1][fdc.pos]; 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); // 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(); timer_process();
disctime = 60 * (1 << TIMER_SHIFT); disctime = 60 * (1 << TIMER_SHIFT);
timer_update_outstanding(); timer_update_outstanding();
} }
else else
{ {
// printf("End of command - params to go!\n"); // printf("End of command - params to go! %i %i %i\n", fdc.track[fdc.drive], fdc.head, fdc.sector);
fdc_abort_f = 0; fdc.abort = 0;
disctime=0; disctime=0;
discint=-2; discint=-2;
picint(0x40); picint(0x40);
@ -606,8 +599,8 @@ void fdc_poll()
else else
fdc.pos = 512; fdc.pos = 512;
} }
if (fdc_abort_f) if (fdc.abort)
fdc.pos = 512; fdc.pos = 512;
} }
return; return;
/* printf("Read data\n"); /* printf("Read data\n");

View file

@ -264,6 +264,7 @@ typedef struct FDC
int lock; int lock;
int perp; int perp;
uint8_t config, pretrk; uint8_t config, pretrk;
int abort;
} FDC; } FDC;
FDC fdc; FDC fdc;

View file

@ -276,7 +276,9 @@ void pit_poll()
} }
// if (output) pclog("%f %04X %02X\n",pit.c[1],pit.l[1],pit.ctrls[1]); // if (output) pclog("%f %04X %02X\n",pit.c[1],pit.l[1],pit.ctrls[1]);
// printf("DMA0!\n"); // printf("DMA0!\n");
readdma0(); dma_channel_read(0);
if (AT)
ppi.pb ^= 0x10;
} }
if (pit.c[2]<1) if (pit.c[2]<1)
{ {

View file

@ -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)) if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127))
return; return;
temp = readdma1(); temp = dma_channel_read(1);
// pclog("adgold DMA1 return %02X %i L\n", temp, channel); // 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[channel][adgold->adgold_mma_fifo_end[channel]] = temp;
adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;
if (adgold->adgold_mma_regs[channel][0xc] & 0x60) 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); // 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[channel][adgold->adgold_mma_fifo_end[channel]] = temp;
adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255;