mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-09-10 16:53:15 +02:00
.fixed SUB-CPU access to unmapped areas using PC-relative instructions (Final Fight CD first boss crash)
.fixed SUB-CPU idle loop false detection when using BSET/BCLR on memory mode register (Pugsy CD first boss slowdowns) .fixed Word-RAM default mode switching on soft reset .optimized VDP DMA processing
This commit is contained in:
parent
e53d6e8aa4
commit
2b8656c27f
@ -412,6 +412,7 @@ INLINE void word_ram_switch(uint8 mode)
|
||||
|
||||
if (mode & 0x04)
|
||||
{
|
||||
/* 2M -> 1M mode */
|
||||
for (i=0; i<0x10000; i++)
|
||||
{
|
||||
*ptr2++=*ptr1++;
|
||||
@ -420,11 +421,43 @@ INLINE void word_ram_switch(uint8 mode)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 1M -> 2M mode */
|
||||
for (i=0; i<0x10000; i++)
|
||||
{
|
||||
*ptr1++=*ptr2++;
|
||||
*ptr1++=*ptr3++;
|
||||
}
|
||||
|
||||
/* allow Word-RAM access from both CPU in 2M mode (fixes sync issues in Mortal Kombat) */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
/* MAIN-CPU: $200000-$23FFFF is mapped to 256K Word-RAM */
|
||||
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 0x03) << 16);
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
/* SUB-CPU: $080000-$0BFFFF is mapped to 256K Word-RAM */
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
}
|
||||
|
||||
for (i=0x0c; i<0x0e; i++)
|
||||
{
|
||||
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
|
||||
s68k.memory_map[i].read8 = s68k_read_bus_8;
|
||||
s68k.memory_map[i].read16 = s68k_read_bus_16;
|
||||
s68k.memory_map[i].write8 = s68k_unused_8_w;
|
||||
s68k.memory_map[i].write16 = s68k_unused_16_w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,12 +504,12 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
||||
|
||||
case 0x03: /* Memory Mode */
|
||||
{
|
||||
s68k_poll_sync(0x02);
|
||||
|
||||
/* detect MODE & RET bits modifications */
|
||||
if ((data ^ scd.regs[0x03 >> 1].byte.l) & 0x05)
|
||||
{
|
||||
int i;
|
||||
|
||||
s68k_poll_sync(0x02);
|
||||
|
||||
/* MODE bit */
|
||||
if (data & 0x04)
|
||||
@ -485,7 +518,7 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
||||
if (!(scd.regs[0x03 >> 1].byte.l & 0x04))
|
||||
{
|
||||
/* re-arrange Word-RAM banks */
|
||||
word_ram_switch(data);
|
||||
word_ram_switch(0x04);
|
||||
}
|
||||
|
||||
/* RET bit in 1M Mode */
|
||||
@ -501,7 +534,6 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
||||
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
/* VRAM cell image mapped at $220000-$23FFFF */
|
||||
m68k.memory_map[i].base = NULL;
|
||||
m68k.memory_map[i].read8 = cell_ram_1_read8;
|
||||
m68k.memory_map[i].read16 = cell_ram_1_read16;
|
||||
m68k.memory_map[i].write8 = cell_ram_1_write8;
|
||||
@ -545,7 +577,6 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
||||
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
/* VRAM cell image mapped at $220000-$23FFFF */
|
||||
m68k.memory_map[i].base = NULL;
|
||||
m68k.memory_map[i].read8 = cell_ram_0_read8;
|
||||
m68k.memory_map[i].read16 = cell_ram_0_read16;
|
||||
m68k.memory_map[i].write8 = cell_ram_0_write8;
|
||||
@ -585,38 +616,7 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
||||
if (scd.regs[0x02 >> 1].byte.l & 0x04)
|
||||
{
|
||||
/* re-arrange Word-RAM banks */
|
||||
word_ram_switch(data);
|
||||
|
||||
/* allow Word-RAM access from both CPU in 2M mode (fixes sync issues in Mortal Kombat) */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
/* MAIN-CPU: $200000-$23FFFF is mapped to 256K Word-RAM */
|
||||
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 0x03) << 16);
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
/* SUB-CPU: $080000-$0BFFFF is mapped to 256K Word-RAM */
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
}
|
||||
|
||||
for (i=0x0c; i<0x0e; i++)
|
||||
{
|
||||
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
|
||||
s68k.memory_map[i].read8 = s68k_read_bus_8;
|
||||
s68k.memory_map[i].read16 = s68k_read_bus_16;
|
||||
s68k.memory_map[i].write8 = s68k_unused_8_w;
|
||||
s68k.memory_map[i].write16 = s68k_unused_16_w;
|
||||
}
|
||||
word_ram_switch(0x00);
|
||||
|
||||
/* RET bit set during 1M mode ? */
|
||||
data |= ~scd.dmna & 0x01;
|
||||
@ -777,12 +777,12 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
||||
|
||||
case 0x02: /* Memory Mode */
|
||||
{
|
||||
s68k_poll_sync(0x02);
|
||||
|
||||
/* detect MODE & RET bits modifications */
|
||||
if ((data ^ scd.regs[0x03>>1].byte.l) & 0x05)
|
||||
{
|
||||
int i;
|
||||
|
||||
s68k_poll_sync(0x02);
|
||||
|
||||
/* MODE bit */
|
||||
if (data & 0x04)
|
||||
@ -791,7 +791,7 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
||||
if (!(scd.regs[0x03 >> 1].byte.l & 0x04))
|
||||
{
|
||||
/* re-arrange Word-RAM banks */
|
||||
word_ram_switch(data);
|
||||
word_ram_switch(0x04);
|
||||
}
|
||||
|
||||
/* RET bit in 1M Mode */
|
||||
@ -807,7 +807,6 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
||||
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
/* VRAM cell image mapped at $220000-$23FFFF */
|
||||
m68k.memory_map[i].base = NULL;
|
||||
m68k.memory_map[i].read8 = cell_ram_1_read8;
|
||||
m68k.memory_map[i].read16 = cell_ram_1_read16;
|
||||
m68k.memory_map[i].write8 = cell_ram_1_write8;
|
||||
@ -851,7 +850,6 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
||||
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
/* VRAM cell image mapped at $220000-$23FFFF */
|
||||
m68k.memory_map[i].base = NULL;
|
||||
m68k.memory_map[i].read8 = cell_ram_0_read8;
|
||||
m68k.memory_map[i].read16 = cell_ram_0_read16;
|
||||
m68k.memory_map[i].write8 = cell_ram_0_write8;
|
||||
@ -891,38 +889,7 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
||||
if (scd.regs[0x03>>1].byte.l & 0x04)
|
||||
{
|
||||
/* re-arrange Word-RAM banks */
|
||||
word_ram_switch(data);
|
||||
|
||||
/* allow Word-RAM access from both CPU in 2M mode (fixes sync issues in Mortal Kombat) */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
/* MAIN-CPU: $200000-$23FFFF is mapped to 256K Word-RAM */
|
||||
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 0x03) << 16);
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
/* SUB-CPU: $080000-$0BFFFF is mapped to 256K Word-RAM */
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
}
|
||||
|
||||
for (i=0x0c; i<0x0e; i++)
|
||||
{
|
||||
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
|
||||
s68k.memory_map[i].read8 = s68k_read_bus_8;
|
||||
s68k.memory_map[i].read16 = s68k_read_bus_16;
|
||||
s68k.memory_map[i].write8 = s68k_unused_8_w;
|
||||
s68k.memory_map[i].write16 = s68k_unused_16_w;
|
||||
}
|
||||
word_ram_switch(0x00);
|
||||
|
||||
/* RET bit set during 1M mode ? */
|
||||
data |= ~scd.dmna & 0x01;
|
||||
@ -1104,7 +1071,7 @@ void scd_init(void)
|
||||
/* $240000-$3FFFFF (resp. $400000-$7FFFFF): unused area (Word-RAM mirrored ?) */
|
||||
for (i=base+0x24; i<base+0x40; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = NULL;
|
||||
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 3) << 16);
|
||||
m68k.memory_map[i].read8 = m68k_read_bus_8;
|
||||
m68k.memory_map[i].read16 = m68k_read_bus_16;
|
||||
m68k.memory_map[i].write8 = m68k_unused_8_w;
|
||||
@ -1143,10 +1110,10 @@ void scd_init(void)
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
}
|
||||
|
||||
/* $0C0000-$FD0000: Unused area */
|
||||
/* $0C0000-$FD0000: Unused area (Word-RAM mirrored ?) */
|
||||
for (i=0x0c; i<0xfd; i++)
|
||||
{
|
||||
s68k.memory_map[i].base = NULL;
|
||||
s68k.memory_map[i].base = scd.word_ram_2M + ((i & 3) << 16);
|
||||
s68k.memory_map[i].read8 = s68k_read_bus_8;
|
||||
s68k.memory_map[i].read16 = s68k_read_bus_16;
|
||||
s68k.memory_map[i].write8 = s68k_unused_8_w;
|
||||
@ -1205,6 +1172,9 @@ void scd_reset(int hard)
|
||||
/* Power ON initial values (MAIN-CPU side) */
|
||||
scd.regs[0x00>>1].w = 0x0002;
|
||||
scd.regs[0x02>>1].w = 0x0001;
|
||||
|
||||
/* 2M mode */
|
||||
word_ram_switch(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -96,6 +96,27 @@ void (*vdp_z80_data_w)(unsigned int data);
|
||||
unsigned int (*vdp_68k_data_r)(void);
|
||||
unsigned int (*vdp_z80_data_r)(void);
|
||||
|
||||
/* Function prototypes */
|
||||
static void vdp_68k_data_w_m4(unsigned int data);
|
||||
static void vdp_68k_data_w_m5(unsigned int data);
|
||||
static unsigned int vdp_68k_data_r_m4(void);
|
||||
static unsigned int vdp_68k_data_r_m5(void);
|
||||
static void vdp_z80_data_w_m4(unsigned int data);
|
||||
static void vdp_z80_data_w_m5(unsigned int data);
|
||||
static unsigned int vdp_z80_data_r_m4(void);
|
||||
static unsigned int vdp_z80_data_r_m5(void);
|
||||
static void vdp_z80_data_w_ms(unsigned int data);
|
||||
static void vdp_z80_data_w_gg(unsigned int data);
|
||||
static void vdp_z80_data_w_sg(unsigned int data);
|
||||
static void vdp_bus_w(unsigned int data);
|
||||
static void vdp_fifo_update(unsigned int cycles);
|
||||
static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles);
|
||||
static void vdp_dma_68k_ext(unsigned int length);
|
||||
static void vdp_dma_68k_ram(unsigned int length);
|
||||
static void vdp_dma_68k_io(unsigned int length);
|
||||
static void vdp_dma_copy(unsigned int length);
|
||||
static void vdp_dma_fill(unsigned int length);
|
||||
|
||||
/* Tables that define the playfield layout */
|
||||
static const uint8 hscroll_mask_table[] = { 0x00, 0x07, 0xF8, 0xFF };
|
||||
static const uint8 shift_table[] = { 6, 7, 0, 8 };
|
||||
@ -121,14 +142,6 @@ static uint16 fifo[4]; /* FIFO buffer */
|
||||
static void (*set_irq_line)(unsigned int level);
|
||||
static void (*set_irq_line_delay)(unsigned int level);
|
||||
|
||||
/* DMA Timings */
|
||||
static const uint8 dma_timing[2][2] =
|
||||
{
|
||||
/* H32, H40 */
|
||||
{16 , 18}, /* active display */
|
||||
{167, 205} /* blank display */
|
||||
};
|
||||
|
||||
/* Vertical counter overflow values (see hvc.h) */
|
||||
static const uint16 vc_table[4][2] =
|
||||
{
|
||||
@ -139,27 +152,30 @@ static const uint16 vc_table[4][2] =
|
||||
{0x106, 0x10A} /* Mode 5 (240 lines) */
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Function prototypes */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* DMA Timings (number of access slots per line) */
|
||||
static const uint8 dma_timing[2][2] =
|
||||
{
|
||||
/* H32, H40 */
|
||||
{16 , 18}, /* active display */
|
||||
{167, 205} /* blank display */
|
||||
};
|
||||
|
||||
/* DMA processing functions (set by VDP register 23 high nibble) */
|
||||
static void (*const dma_func[16])(unsigned int length) =
|
||||
{
|
||||
/* 0x0-0x3 : DMA from 68k bus $000000-$7FFFFF (external area) */
|
||||
vdp_dma_68k_ext,vdp_dma_68k_ext,vdp_dma_68k_ext,vdp_dma_68k_ext,
|
||||
|
||||
/* 0x4-0x7 : DMA from 68k bus $800000-$FFFFFF (internal RAM & I/O) */
|
||||
vdp_dma_68k_ram, vdp_dma_68k_io,vdp_dma_68k_ram,vdp_dma_68k_ram,
|
||||
|
||||
/* 0x8-0xB : DMA Fill */
|
||||
vdp_dma_fill,vdp_dma_fill,vdp_dma_fill,vdp_dma_fill,
|
||||
|
||||
/* 0xC-0xF : DMA Copy */
|
||||
vdp_dma_copy,vdp_dma_copy,vdp_dma_copy,vdp_dma_copy
|
||||
};
|
||||
|
||||
static void vdp_68k_data_w_m4(unsigned int data);
|
||||
static void vdp_68k_data_w_m5(unsigned int data);
|
||||
static unsigned int vdp_68k_data_r_m4(void);
|
||||
static unsigned int vdp_68k_data_r_m5(void);
|
||||
static void vdp_z80_data_w_m4(unsigned int data);
|
||||
static void vdp_z80_data_w_m5(unsigned int data);
|
||||
static unsigned int vdp_z80_data_r_m4(void);
|
||||
static unsigned int vdp_z80_data_r_m5(void);
|
||||
static void vdp_z80_data_w_ms(unsigned int data);
|
||||
static void vdp_z80_data_w_gg(unsigned int data);
|
||||
static void vdp_z80_data_w_sg(unsigned int data);
|
||||
static void vdp_bus_w(unsigned int data);
|
||||
static void vdp_fifo_update(unsigned int cycles);
|
||||
static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles);
|
||||
static void vdp_dma_copy(unsigned int length);
|
||||
static void vdp_dma_vbus(unsigned int length);
|
||||
static void vdp_dma_fill(unsigned char data, unsigned int length);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Init, reset, context functions */
|
||||
@ -608,30 +624,8 @@ void vdp_dma_update(unsigned int cycles)
|
||||
/* Update DMA length */
|
||||
dma_length -= dma_bytes;
|
||||
|
||||
/* Select DMA operation */
|
||||
switch (dma_type)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
/* VRAM Fill */
|
||||
vdp_dma_fill(dmafill, dma_bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
/* VRAM Copy */
|
||||
vdp_dma_copy(dma_bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
/* 68K bus to VRAM, CRAM or VSRAM */
|
||||
vdp_dma_vbus(dma_bytes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Process DMA operation */
|
||||
dma_func[reg[23] >> 4](dma_bytes);
|
||||
|
||||
/* Check if DMA is finished */
|
||||
if (!dma_length)
|
||||
@ -2868,78 +2862,112 @@ static void vdp_z80_data_w_sg(unsigned int data)
|
||||
/* DMA operations */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/* 68K bus to VRAM, VSRAM or CRAM */
|
||||
static void vdp_dma_vbus(unsigned int length)
|
||||
/* DMA from 68K bus: $000000-$7FFFFF (external area) */
|
||||
static void vdp_dma_68k_ext(unsigned int length)
|
||||
{
|
||||
uint16 data;
|
||||
|
||||
/* 68k bus source address */
|
||||
uint32 source = (reg[23] << 17) | (dma_src << 1);
|
||||
|
||||
/* Z80 & I/O area ($A00000-$A1FFFF) specific */
|
||||
if (reg[23] == 0x50)
|
||||
do
|
||||
{
|
||||
do
|
||||
/* Read data word from 68k bus */
|
||||
if (m68k.memory_map[source>>16].read16)
|
||||
{
|
||||
/* Z80 area */
|
||||
if (source <= 0xA0FFFF)
|
||||
{
|
||||
/* Return $FFFF only when the Z80 isn't hogging the Z-bus.
|
||||
(e.g. Z80 isn't reset and 68000 has the bus) */
|
||||
data = ((zstate ^ 3) ? *(uint16 *)(work_ram + (source & 0xFFFF)) : 0xFFFF);
|
||||
}
|
||||
|
||||
/* The I/O chip and work RAM try to drive the data bus which results
|
||||
in both values being combined in random ways when read.
|
||||
We return the I/O chip values which seem to have precedence, */
|
||||
else if (source <= 0xA1001F)
|
||||
{
|
||||
data = io_68k_read((source >> 1) & 0x0F);
|
||||
data = (data << 8 | data);
|
||||
}
|
||||
|
||||
/* All remaining locations access work RAM */
|
||||
else
|
||||
{
|
||||
data = *(uint16 *)(work_ram + (source & 0xFFFF));
|
||||
}
|
||||
|
||||
/* Increment source address */
|
||||
source += 2;
|
||||
|
||||
/* 128k DMA window */
|
||||
source = (reg[23] << 17) | (source & 0x1FFFF);
|
||||
|
||||
/* Write data to VRAM, CRAM or VSRAM */
|
||||
vdp_bus_w(data);
|
||||
data = m68k.memory_map[source>>16].read16(source);
|
||||
}
|
||||
while (--length);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
else
|
||||
{
|
||||
/* Read data word from 68k bus */
|
||||
if (m68k.memory_map[source>>16].base)
|
||||
{
|
||||
data = *(uint16 *)(m68k.memory_map[source>>16].base + (source & 0xFFFF));
|
||||
}
|
||||
else
|
||||
{
|
||||
data = m68k.memory_map[source>>16].read16(source);
|
||||
}
|
||||
data = *(uint16 *)(m68k.memory_map[source>>16].base + (source & 0xFFFF));
|
||||
}
|
||||
|
||||
/* Increment source address */
|
||||
source += 2;
|
||||
/* Increment source address */
|
||||
source += 2;
|
||||
|
||||
/* 128k DMA window */
|
||||
source = (reg[23] << 17) | (source & 0x1FFFF);
|
||||
/* 128k DMA window */
|
||||
source = (reg[23] << 17) | (source & 0x1FFFF);
|
||||
|
||||
/* Write data word to VRAM, CRAM or VSRAM */
|
||||
vdp_bus_w(data);
|
||||
}
|
||||
while (--length);
|
||||
/* Write data word to VRAM, CRAM or VSRAM */
|
||||
vdp_bus_w(data);
|
||||
}
|
||||
while (--length);
|
||||
|
||||
/* Update DMA source address */
|
||||
dma_src = (source >> 1) & 0xffff;
|
||||
}
|
||||
|
||||
/* DMA from 68K bus: $800000-$FFFFFF (internal area) except I/O area */
|
||||
static void vdp_dma_68k_ram(unsigned int length)
|
||||
{
|
||||
uint16 data;
|
||||
|
||||
/* 68k bus source address */
|
||||
uint32 source = (reg[23] << 17) | (dma_src << 1);
|
||||
|
||||
do
|
||||
{
|
||||
/* access Work-RAM by default */
|
||||
data = *(uint16 *)(work_ram + (source & 0xFFFF));
|
||||
|
||||
/* Increment source address */
|
||||
source += 2;
|
||||
|
||||
/* 128k DMA window */
|
||||
source = (reg[23] << 17) | (source & 0x1FFFF);
|
||||
|
||||
/* Write data word to VRAM, CRAM or VSRAM */
|
||||
vdp_bus_w(data);
|
||||
}
|
||||
while (--length);
|
||||
|
||||
/* Update DMA source address */
|
||||
dma_src = (source >> 1) & 0xffff;
|
||||
}
|
||||
|
||||
/* DMA from 68K bus: $A00000-$A1FFFF (I/O area) specific */
|
||||
static void vdp_dma_68k_io(unsigned int length)
|
||||
{
|
||||
uint16 data;
|
||||
|
||||
/* 68k bus source address */
|
||||
uint32 source = (reg[23] << 17) | (dma_src << 1);
|
||||
|
||||
do
|
||||
{
|
||||
/* Z80 area */
|
||||
if (source <= 0xA0FFFF)
|
||||
{
|
||||
/* Return $FFFF only when the Z80 isn't hogging the Z-bus.
|
||||
(e.g. Z80 isn't reset and 68000 has the bus) */
|
||||
data = ((zstate ^ 3) ? *(uint16 *)(work_ram + (source & 0xFFFF)) : 0xFFFF);
|
||||
}
|
||||
|
||||
/* The I/O chip and work RAM try to drive the data bus which results
|
||||
in both values being combined in random ways when read.
|
||||
We return the I/O chip values which seem to have precedence, */
|
||||
else if (source <= 0xA1001F)
|
||||
{
|
||||
data = io_68k_read((source >> 1) & 0x0F);
|
||||
data = (data << 8 | data);
|
||||
}
|
||||
|
||||
/* All remaining locations access work RAM */
|
||||
else
|
||||
{
|
||||
data = *(uint16 *)(work_ram + (source & 0xFFFF));
|
||||
}
|
||||
|
||||
/* Increment source address */
|
||||
source += 2;
|
||||
|
||||
/* 128k DMA window */
|
||||
source = (reg[23] << 17) | (source & 0x1FFFF);
|
||||
|
||||
/* Write data to VRAM, CRAM or VSRAM */
|
||||
vdp_bus_w(data);
|
||||
}
|
||||
while (--length);
|
||||
|
||||
/* Update DMA source address */
|
||||
dma_src = (source >> 1) & 0xffff;
|
||||
@ -2989,12 +3017,14 @@ static void vdp_dma_copy(unsigned int length)
|
||||
}
|
||||
|
||||
/* VRAM Fill (TODO: check if CRAM or VSRAM fill is possible) */
|
||||
static void vdp_dma_fill(unsigned char data, unsigned int length)
|
||||
static void vdp_dma_fill(unsigned int length)
|
||||
{
|
||||
/* VRAM write operation only (Williams Greatest Hits after soft reset) */
|
||||
if ((code & 0x1F) == 0x01)
|
||||
{
|
||||
int name;
|
||||
uint8 data = dmafill;
|
||||
|
||||
do
|
||||
{
|
||||
/* Intercept writes to Sprite Attribute Table */
|
||||
|
Loading…
Reference in New Issue
Block a user