Implemented software-requested DMA block transfers, fixes #405, and also fixes UMBPCI's DMACHK ISA DMA tests;

Reworked a few things and re-implemented memory write protection in the SCAT emulation, to require less unusual mappings;
Removed two files that should not be there;
Made sure all graphics cards' memory mappings are mapped as MEM_MAPPING_EXTERNAL;
Added MEM_MAPPING_ROMCS flag to signal that a mapping responds to MEMCS* and made the BIOS and Intel flash mappings use it.
This commit is contained in:
OBattler
2019-09-28 17:32:05 +02:00
parent b1f91ff54a
commit 6627282efb
13 changed files with 147 additions and 1943 deletions

View File

@@ -8,7 +8,7 @@
*
* Implementation of the Intel DMA controllers.
*
* Version: @(#)dma.c 1.0.6 2019/09/21
* Version: @(#)dma.c 1.0.7 2019/09/28
*
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
* Miran Grca, <mgrca8@gmail.com>
@@ -51,6 +51,10 @@ static uint8_t dma_stat_rq;
static uint8_t dma_stat_rq_pc;
static uint8_t dma_command,
dma16_command;
static uint8_t dma_req_is_soft;
static uint8_t dma_buffer[65536];
static uint16_t dma16_buffer[65536];
static struct {
int xfr_command,
xfr_channel;
@@ -87,6 +91,31 @@ dma_set_drq(int channel, int set)
}
static void
dma_block_transfer(int channel)
{
int i, bit16;
bit16 = (channel >= 4);
dma_req_is_soft = 1;
for (i = 0; i <= dma[channel].cb; i++) {
if ((dma[channel].mode & 0x8c) == 0x84) {
if (bit16)
dma_channel_write(channel, dma16_buffer[i]);
else
dma_channel_write(channel, dma_buffer[i]);
} else if ((dma[channel].mode & 0x8c) == 0x88) {
if (bit16)
dma16_buffer[i] = dma_channel_read(channel);
else
dma_buffer[i] = dma_channel_read(channel);
}
}
dma_req_is_soft = 0;
}
static uint8_t
dma_read(uint16_t addr, void *priv)
{
@@ -168,17 +197,19 @@ dma_write(uint16_t addr, uint8_t val, void *priv)
case 9: /*Request register */
channel = (val & 3);
if (val & 4)
if (val & 4) {
dma_stat_rq_pc |= (1 << channel);
else
dma_block_transfer(channel);
} else
dma_stat_rq_pc &= ~(1 << channel);
break;
case 0xa: /*Mask*/
channel = (val & 3);
if (val & 4)
dma_m |= (1 << (val & 3));
else
dma_m &= ~(1 << (val & 3));
dma_m |= (1 << channel);
else
dma_m &= ~(1 << channel);
return;
case 0xb: /*Mode*/
@@ -462,17 +493,19 @@ dma16_write(uint16_t addr, uint8_t val, void *priv)
case 9: /*Request register */
channel = (val & 3) + 4;
if (val & 4)
if (val & 4) {
dma_stat_rq_pc |= (1 << channel);
else
dma_block_transfer(channel);
} else
dma_stat_rq_pc &= ~(1 << channel);
break;
case 0xa: /*Mask*/
channel = (val & 3);
if (val & 4)
dma_m |= (0x10 << (val & 3));
else
dma_m &= ~(0x10 << (val & 3));
dma_m |= (0x10 << channel);
else
dma_m &= ~(0x10 << channel);
return;
case 0xb: /*Mode*/
@@ -582,8 +615,8 @@ dma_reset(void)
dma_wp = dma16_wp = 0;
dma_m = 0;
for (c = 0; c < 16; c++)
dmaregs[c] = 0;
for (c = 0; c < 16; c++)
dmaregs[c] = dma16regs[c] = 0;
for (c = 0; c < 8; c++) {
dma[c].mode = 0;
dma[c].ac = 0;
@@ -596,6 +629,10 @@ dma_reset(void)
dma_stat = 0x00;
dma_stat_rq = 0x00;
dma_stat_rq_pc = 0x00;
dma_req_is_soft = 0;
memset(dma_buffer, 0x00, sizeof(dma_buffer));
memset(dma16_buffer, 0x00, sizeof(dma16_buffer));
}
@@ -699,7 +736,7 @@ dma_channel_read(int channel)
return(DMA_NODATA);
}
if (dma_m & (1 << channel))
if ((dma_m & (1 << channel)) && !dma_req_is_soft)
return(DMA_NODATA);
if ((dma_c->mode & 0xC) != 8)
return(DMA_NODATA);
@@ -772,7 +809,7 @@ dma_channel_write(int channel, uint16_t val)
return(DMA_NODATA);
}
if (dma_m & (1 << channel))
if ((dma_m & (1 << channel)) && !dma_req_is_soft)
return(DMA_NODATA);
if ((dma_c->mode & 0xC) != 4)
return(DMA_NODATA);