move some system specific stuff out of the cdc (nw)

This commit is contained in:
David Haywood 2012-12-05 01:13:49 +00:00
parent 15b547cdfa
commit 2f85f85034
5 changed files with 373 additions and 364 deletions

View File

@ -100,7 +100,7 @@ ADDRESS_MAP_START( segacd_map, AS_PROGRAM, 16, sega_segacd_device )
AM_RANGE(0xff8004 ,0xff8005) AM_DEVREADWRITE("tempcdc",lc89510_temp_device, segacd_cdc_mode_address_r, segacd_cdc_mode_address_w)
AM_RANGE(0xff8006 ,0xff8007) AM_DEVREADWRITE("tempcdc",lc89510_temp_device,segacd_cdc_data_r, segacd_cdc_data_w)
AM_RANGE(0xff8008, 0xff8009) AM_DEVREAD("tempcdc",lc89510_temp_device, cdc_data_sub_r)
AM_RANGE(0xff800a, 0xff800b) AM_DEVREADWRITE("tempcdc",lc89510_temp_device,cdc_dmaaddr_r,cdc_dmaaddr_w) // CDC DMA Address
AM_RANGE(0xff800a, 0xff800b) AM_READWRITE(segacd_dmaaddr_r,segacd_dmaaddr_w) // DMA Address (not CDC, used in conjunction with)
AM_RANGE(0xff800c, 0xff800d) AM_READWRITE(segacd_stopwatch_timer_r, segacd_stopwatch_timer_w)// Stopwatch timer
AM_RANGE(0xff800e ,0xff800f) AM_READWRITE(segacd_comms_flags_r, segacd_comms_flags_subcpu_w)
AM_RANGE(0xff8010 ,0xff801f) AM_READWRITE(segacd_comms_sub_part1_r, segacd_comms_sub_part1_w)
@ -1678,6 +1678,16 @@ void sega_segacd_device::device_start()
// todo register save state stuff
}
READ16_MEMBER( sega_segacd_device::segacd_dmaaddr_r )
{
return m_dmaaddr;
}
WRITE16_MEMBER( sega_segacd_device::segacd_dmaaddr_w )
{
COMBINE_DATA(&m_dmaaddr);
}
void sega_segacd_device::device_reset()
{
@ -1693,6 +1703,7 @@ void sega_segacd_device::device_reset()
lc89510_temp = machine().device<lc89510_temp_device>(":segacd:tempcdc");
lc89510_temp->reset_cd();
m_dmaaddr = 0;
scd_dma_timer->adjust(attotime::zero);
stopwatch_timer = machine().device<timer_device>(":segacd:sw_timer");
@ -1753,7 +1764,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( sega_segacd_device::scd_dma_timer_callback )
}
// todo: tidy up, too many CDC internals here
void sega_segacd_device::SegaCD_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &SEGACD_DMA_ADDRESS, UINT16 &dma_addrc, UINT16 &destination )
void sega_segacd_device::SegaCD_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &dma_addrc, UINT16 &destination )
{
int length = dmacount;
UINT8 *dest;
@ -1765,12 +1776,12 @@ void sega_segacd_device::SegaCD_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UIN
if (destination==DMA_PCM)
{
dstoffset = (SEGACD_DMA_ADDRESS & 0x03FF) << 2;
dstoffset = (m_dmaaddr & 0x03FF) << 2;
PCM_DMA = true;
}
else
{
dstoffset = (SEGACD_DMA_ADDRESS & 0xFFFF) << 3;
dstoffset = (m_dmaaddr & 0xFFFF) << 3;
}
@ -1849,11 +1860,11 @@ void sega_segacd_device::SegaCD_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UIN
if (PCM_DMA)
{
SEGACD_DMA_ADDRESS += length >> 1;
m_dmaaddr += length >> 1;
}
else
{
SEGACD_DMA_ADDRESS += length >> 2;
m_dmaaddr += length >> 2;
}
}

View File

@ -272,6 +272,9 @@ public:
UINT16 segacd_1meg_mode_word_read(int offset, UINT16 mem_mask);
void segacd_1meg_mode_word_write(running_machine& machine, int offset, UINT16 data, UINT16 mem_mask, int use_pm);
DECLARE_READ16_MEMBER( segacd_dmaaddr_r );
DECLARE_WRITE16_MEMBER( segacd_dmaaddr_w );
UINT16 m_dmaaddr;
@ -365,7 +368,7 @@ public:
READ16_MEMBER( segacd_font_converted_r );
TIMER_DEVICE_CALLBACK_MEMBER( scd_dma_timer_callback );
void SegaCD_CDC_Do_DMA( int &dmacount, UINT8 *CDC_BUFFER, UINT16 &SEGACD_DMA_ADDRESS, UINT16 &dma_addrc, UINT16 &destination );
void SegaCD_CDC_Do_DMA( int &dmacount, UINT8 *CDC_BUFFER, UINT16 &dma_addrc, UINT16 &destination );
timer_device* scd_dma_timer;
protected:

View File

@ -28,12 +28,6 @@ lc89510_temp_device::lc89510_temp_device(const machine_config &mconfig, const ch
for (int i=0;i<2352;i++)
NeoCDSectorData[i] = 0;
bNeoCDLoadSector = false;
NeoCDDMAAddress1 = 0;
NeoCDDMAAddress2 = 0;
NeoCDDMAValue1 = 0;
NeoCDDMAValue2 = 0;
NeoCDDMACount = 0;
NeoCDDMAMode = 0;
CDC_REG0 = 0;
nNeoCDIRQVectorAck = 0;
nNeoCDIRQVector = 0;
@ -53,7 +47,7 @@ void lc89510_temp_device::set_is_neoCD(device_t &device, bool is_neoCD)
}
// HACK for DMA handling, this gets replaced
void lc89510_temp_device::Fake_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &SEGACD_DMA_ADDRESS, UINT16 &dma_addrc, UINT16 &destination )
void lc89510_temp_device::Fake_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &dma_addrc, UINT16 &destination )
{
fatalerror("Fake_CDC_Do_DMA\n");
}
@ -455,7 +449,7 @@ void lc89510_temp_device::lc89510_Reset(void)
CDD_Reset();
CDC_Reset();
CDC_REG0 = CDC_REG1 = SEGACD_DMA_ADDRESS = SCD_STATUS_CDC = CDD_DONE = 0;
CDC_REG0 = CDC_REG1 = SCD_STATUS_CDC = CDD_DONE = 0;
}
void lc89510_temp_device::CDC_End_Transfer(running_machine& machine)
@ -504,7 +498,7 @@ void lc89510_temp_device::CDC_Do_DMA(running_machine& machine, int rate)
UINT16 dma_addrc = LC8951RegistersW[REG_W_DACL] | (LC8951RegistersW[REG_W_DACH]<<8);
// HACK
segacd_dma_callback(dmacount, CDC_BUFFER, SEGACD_DMA_ADDRESS, dma_addrc, destination );
segacd_dma_callback(dmacount, CDC_BUFFER, dma_addrc, destination );
dma_addrc += length*2;
@ -894,15 +888,7 @@ WRITE8_MEMBER( lc89510_temp_device::segacd_cdd_tx_w )
READ16_MEMBER( lc89510_temp_device::cdc_dmaaddr_r )
{
return SEGACD_DMA_ADDRESS;
}
WRITE16_MEMBER( lc89510_temp_device::cdc_dmaaddr_w )
{
COMBINE_DATA(&SEGACD_DMA_ADDRESS);
}
READ16_MEMBER( lc89510_temp_device::segacd_cdfader_r )
{
@ -1061,252 +1047,6 @@ void lc89510_temp_device::NeoCDCommsReset()
nff0016 = 0;
}
static INT32 SekIdle(INT32 nCycles)
{
return nCycles;
}
void lc89510_temp_device::NeoCDDoDMA()
{
// The LC8953 chip has a programmable DMA controller, which is not properly emulated.
// Since the software only uses it in a limited way, we can apply a simple heuristic
// to determnine the requested operation.
// Additionally, we don't know how many cycles DMA operations take.
// Here, only bus access is used to get a rough approximation --
// each read/write takes a single cycle, setup and everything else is ignored.
// bprintf(PRINT_IMPORTANT, _T(" - DMA controller transfer started (PC: 0x%06X)\n"), SekGetPC(-1));
switch (NeoCDDMAMode) {
case 0xCFFD: {
// bprintf(PRINT_NORMAL, _T(" adr : 0x%08X - 0x%08X <- address, skip odd bytes\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 8);
// - DMA controller 0x7E -> 0xCFFD (PC: 0xC07CE2)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8)
// - DMA controller program[02] -> 0xE8DA (PC: 0xC07CEE)
// - DMA controller program[04] -> 0x92DA (PC: 0xC07CF4)
// - DMA controller program[06] -> 0x92DB (PC: 0xC07CFA)
// - DMA controller program[08] -> 0x96DB (PC: 0xC07D00)
// - DMA controller program[10] -> 0x96F6 (PC: 0xC07D06)
// - DMA controller program[12] -> 0x2E02 (PC: 0xC07D0C)
// - DMA controller program[14] -> 0xFDFF (PC: 0xC07D12)
SekIdle(NeoCDDMACount * 4);
while (NeoCDDMACount--) {
SekWriteWord(NeoCDDMAAddress1 + 0, NeoCDDMAAddress1 >> 24);
SekWriteWord(NeoCDDMAAddress1 + 2, NeoCDDMAAddress1 >> 16);
SekWriteWord(NeoCDDMAAddress1 + 4, NeoCDDMAAddress1 >> 8);
SekWriteWord(NeoCDDMAAddress1 + 6, NeoCDDMAAddress1 >> 0);
NeoCDDMAAddress1 += 8;
}
break;
}
case 0xE2DD: {
// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- 0x%08X - 0x%08X, skip odd bytes\n"), NeoCDDMAAddress2, NeoCDDMAAddress2 + NeoCDDMACount * 2, NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4);
// - DMA controller 0x7E -> 0xE2DD (PC: 0xC0A190)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192)
// - DMA controller program[02] -> 0x82BE (PC: 0xC0A194)
// - DMA controller program[04] -> 0x93DA (PC: 0xC0A196)
// - DMA controller program[06] -> 0xBE93 (PC: 0xC0A198)
// - DMA controller program[08] -> 0xDABE (PC: 0xC0A19A)
// - DMA controller program[10] -> 0xF62D (PC: 0xC0A19C)
// - DMA controller program[12] -> 0x02FD (PC: 0xC0A19E)
// - DMA controller program[14] -> 0xFFFF (PC: 0xC0A1A0)
SekIdle(NeoCDDMACount * 1);
while (NeoCDDMACount--) {
SekWriteWord(NeoCDDMAAddress2 + 0, SekReadByte(NeoCDDMAAddress1 + 0));
SekWriteWord(NeoCDDMAAddress2 + 2, SekReadByte(NeoCDDMAAddress1 + 1));
NeoCDDMAAddress1 += 2;
NeoCDDMAAddress2 += 4;
}
break;
}
case 0xFC2D: {
// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- LC8951 external buffer, skip odd bytes\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4);
// - DMA controller 0x7E -> 0xFC2D (PC: 0xC0A190)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192)
// - DMA controller program[02] -> 0x8492 (PC: 0xC0A194)
// - DMA controller program[04] -> 0xDA92 (PC: 0xC0A196)
// - DMA controller program[06] -> 0xDAF6 (PC: 0xC0A198)
// - DMA controller program[08] -> 0x2A02 (PC: 0xC0A19A)
// - DMA controller program[10] -> 0xFDFF (PC: 0xC0A19C)
// - DMA controller program[12] -> 0x48E7 (PC: 0xC0A19E)
// - DMA controller program[14] -> 0xFFFE (PC: 0xC0A1A0)
char* data = LC8915InitTransfer();
if (data == NULL) {
break;
}
SekIdle(NeoCDDMACount * 4);
while (NeoCDDMACount--) {
SekWriteByte(NeoCDDMAAddress1 + 0, data[0]);
SekWriteByte(NeoCDDMAAddress1 + 2, data[1]);
NeoCDDMAAddress1 += 4;
data += 2;
}
LC8915EndTransfer();
break;
}
case 0xFE3D:
// - DMA controller 0x7E -> 0xFE3D (PC: 0xC0A190)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192)
// - DMA controller program[02] -> 0x82BF (PC: 0xC0A194)
// - DMA controller program[04] -> 0x93BF (PC: 0xC0A196)
// - DMA controller program[06] -> 0xF629 (PC: 0xC0A198)
// - DMA controller program[08] -> 0x02FD (PC: 0xC0A19A)
// - DMA controller program[10] -> 0xFFFF (PC: 0xC0A19C)
// - DMA controller program[12] -> 0xF17D (PC: 0xC0A19E)
// - DMA controller program[14] -> 0xFCF5 (PC: 0xC0A1A0)
case 0xFE6D: {
// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- 0x%08X - 0x%08X\n"), NeoCDDMAAddress2, NeoCDDMAAddress2 + NeoCDDMACount * 2, NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2);
// - DMA controller 0x7E -> 0xFE6D (PC: 0xC0FD7A)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0FD7C)
// - DMA controller program[02] -> 0x82BF (PC: 0xC0FD7E)
// - DMA controller program[04] -> 0xF693 (PC: 0xC0FD80)
// - DMA controller program[06] -> 0xBF29 (PC: 0xC0FD82)
// - DMA controller program[08] -> 0x02FD (PC: 0xC0FD84)
// - DMA controller program[10] -> 0xFFFF (PC: 0xC0FD86)
// - DMA controller program[12] -> 0xC515 (PC: 0xC0FD88)
// - DMA controller program[14] -> 0xFCF5 (PC: 0xC0FD8A)
SekIdle(NeoCDDMACount * 1);
while (NeoCDDMACount--) {
SekWriteWord(NeoCDDMAAddress2, SekReadWord(NeoCDDMAAddress1));
NeoCDDMAAddress1 += 2;
NeoCDDMAAddress2 += 2;
}
if (NeoCDDMAAddress2 == 0x0800) {
// MapVectorTable(false);
// bprintf(PRINT_ERROR, _T(" RAM vectors mapped (PC = 0x%08X\n"), SekGetPC(0));
// extern INT32 bRunPause;
// bRunPause = 1;
}
break;
}
case 0xFEF5: {
// bprintf(PRINT_NORMAL, _T(" adr : 0x%08X - 0x%08X <- address\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4);
// - DMA controller 0x7E -> 0xFEF5 (PC: 0xC07CE2)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8)
// - DMA controller program[02] -> 0x92E8 (PC: 0xC07CEE)
// - DMA controller program[04] -> 0xBE96 (PC: 0xC07CF4)
// - DMA controller program[06] -> 0xF629 (PC: 0xC07CFA)
// - DMA controller program[08] -> 0x02FD (PC: 0xC07D00)
// - DMA controller program[10] -> 0xFFFF (PC: 0xC07D06)
// - DMA controller program[12] -> 0xFC3D (PC: 0xC07D0C)
// - DMA controller program[14] -> 0xFCF5 (PC: 0xC07D12)
SekIdle(NeoCDDMACount * 2);
while (NeoCDDMACount--) {
SekWriteWord(NeoCDDMAAddress1 + 0, NeoCDDMAAddress1 >> 16);
SekWriteWord(NeoCDDMAAddress1 + 2, NeoCDDMAAddress1 >> 0);
NeoCDDMAAddress1 += 4;
}
break;
}
case 0xFFC5: {
// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- LC8951 external buffer\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2);
// - DMA controller 0x7E -> 0xFFC5 (PC: 0xC0A190)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192)
// - DMA controller program[02] -> 0xA6F6 (PC: 0xC0A194)
// - DMA controller program[04] -> 0x2602 (PC: 0xC0A196)
// - DMA controller program[06] -> 0xFDFF (PC: 0xC0A198)
// - DMA controller program[08] -> 0xFC2D (PC: 0xC0A19A)
// - DMA controller program[10] -> 0xFCF5 (PC: 0xC0A19C)
// - DMA controller program[12] -> 0x8492 (PC: 0xC0A19E)
// - DMA controller program[14] -> 0xDA92 (PC: 0xC0A1A0)
char* data = LC8915InitTransfer();
if (data == NULL) {
break;
}
SekIdle(NeoCDDMACount * 4);
while (NeoCDDMACount--) {
SekWriteByte(NeoCDDMAAddress1 + 0, data[0]);
SekWriteByte(NeoCDDMAAddress1 + 1, data[1]);
NeoCDDMAAddress1 += 2;
data += 2;
}
LC8915EndTransfer();
break;
}
case 0xFFCD:
// - DMA controller 0x7E -> 0xFFCD (PC: 0xC0A190)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192)
// - DMA controller program[02] -> 0x92F6 (PC: 0xC0A194)
// - DMA controller program[04] -> 0x2602 (PC: 0xC0A196)
// - DMA controller program[06] -> 0xFDFF (PC: 0xC0A198)
// - DMA controller program[08] -> 0x7006 (PC: 0xC0A19A)
// - DMA controller program[10] -> 0x6100 (PC: 0xC0A19C)
// - DMA controller program[12] -> 0x2412 (PC: 0xC0A19E)
// - DMA controller program[14] -> 0x13FC (PC: 0xC0A1A0)
case 0xFFDD: {
// bprintf(PRINT_NORMAL, _T(" Fill: 0x%08X - 0x%08X <- 0x%04X\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2, NeoCDDMAValue1);
// - DMA controller 0x7E -> 0xFFDD (PC: 0xC07CE2)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8)
// - DMA controller program[02] -> 0x92F6 (PC: 0xC07CEE)
// - DMA controller program[04] -> 0x2602 (PC: 0xC07CF4)
// - DMA controller program[06] -> 0xFDFF (PC: 0xC07CFA)
// - DMA controller program[08] -> 0xFFFF (PC: 0xC07D00)
// - DMA controller program[10] -> 0xFCF5 (PC: 0xC07D06)
// - DMA controller program[12] -> 0x8AF0 (PC: 0xC07D0C)
// - DMA controller program[14] -> 0x1609 (PC: 0xC07D12)
SekIdle(NeoCDDMACount * 1);
while (NeoCDDMACount--) {
SekWriteWord(NeoCDDMAAddress1, NeoCDDMAValue1);
NeoCDDMAAddress1 += 2;
}
break;
}
default: {
//bprintf(PRINT_ERROR, _T(" Unknown transfer type 0x%04X (PC: 0x%06X)\n"), NeoCDDMAMode, SekGetPC(-1));
//bprintf(PRINT_NORMAL, _T(" ??? : 0x%08X 0x%08X 0x%04X 0x%04X 0x%08X\n"), NeoCDDMAAddress1, NeoCDDMAAddress2, NeoCDDMAValue1, NeoCDDMAValue2, NeoCDDMACount);
//extern INT32 bRunPause;
//bRunPause = 1;
}
}
}
void lc89510_temp_device::NeoCDProcessCommand()
{
@ -1506,7 +1246,7 @@ void lc89510_temp_device::LC8951UpdateHeader() // neocd
}
}
char* lc89510_temp_device::LC8915InitTransfer()
char* lc89510_temp_device::LC8915InitTransfer(int NeoCDDMACount)
{
if (!LC8951RegistersW[REG_W_DTTRG]) {
//bprintf(PRINT_ERROR, _T(" LC8951 DTTRG status invalid\n"));
@ -1550,49 +1290,6 @@ void lc89510_temp_device::LC8951Reset()
LC8951UpdateHeader();
}
void lc89510_temp_device::set_DMA_regs(int offset, UINT16 wordValue)
{
switch (offset)
{
case 0x0064:
NeoCDDMAAddress1 &= 0x0000FFFF;
NeoCDDMAAddress1 |= wordValue << 16;
break;
case 0x0066:
NeoCDDMAAddress1 &= 0xFFFF0000;
NeoCDDMAAddress1 |= wordValue;
break;
case 0x0068:
NeoCDDMAAddress2 &= 0x0000FFFF;
NeoCDDMAAddress2 |= wordValue << 16;
break;
case 0x006A:
NeoCDDMAAddress2 &= 0xFFFF0000;
NeoCDDMAAddress2 |= wordValue;
break;
case 0x006C:
NeoCDDMAValue1 = wordValue;
break;
case 0x006E:
NeoCDDMAValue2 = wordValue;
break;
case 0x0070:
NeoCDDMACount &= 0x0000FFFF;
NeoCDDMACount |= wordValue << 16;
break;
case 0x0072:
NeoCDDMACount &= 0xFFFF0000;
NeoCDDMACount |= wordValue;
break;
case 0x007E:
NeoCDDMAMode = wordValue;
// bprintf(PRINT_NORMAL, _T(" - DMA controller 0x%2X -> 0x%04X (PC: 0x%06X)\n"), sekAddress & 0xFF, wordValue, SekGetPC(-1));
break;
}
}
void lc89510_temp_device::reset_NeoCd(void)
{
{
@ -1787,32 +1484,6 @@ int lc89510_temp_device::Read_LBA_To_Buffer(running_machine& machine)
void lc89510_temp_device::SekWriteWord(UINT32 a, UINT16 d)
{
// printf("write word %08x %04x\n", a, d);
dma_space->write_word(a,d);
}
void lc89510_temp_device::SekWriteByte(UINT32 a, UINT8 d)
{
// printf("write byte %08x %02x\n", a, d);
dma_space->write_byte(a,d);
}
UINT32 lc89510_temp_device::SekReadByte(UINT32 a)
{
// printf("read byte %08x\n", a);
return dma_space->read_byte(a);
}
UINT32 lc89510_temp_device::SekReadWord(UINT32 a)
{
// printf("read WORD %08x\n", a);
return dma_space->read_word(a);
}
void lc89510_temp_device::NeoCDIRQUpdate(UINT8 byteValue)
{
// do we also need to check the regular interrupts like FBA?

View File

@ -3,7 +3,7 @@
#include "imagedev/chd_cd.h"
typedef device_delegate<void (int&, UINT8*, UINT16&, UINT16&, UINT16&)> segacd_dma_delegate;
typedef device_delegate<void (int&, UINT8*, UINT16&, UINT16&)> segacd_dma_delegate;
@ -150,7 +150,7 @@ public:
// HACK for DMA handling
segacd_dma_delegate segacd_dma_callback;
void Fake_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &SEGACD_DMA_ADDRESS, UINT16 &dma_addrc, UINT16 &destination );
void Fake_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &dma_addrc, UINT16 &destination );
static void set_CDC_Do_DMA(device_t &device,segacd_dma_delegate new_segacd_dma_callback);
static void set_is_neoCD(device_t &device, bool is_neoCD);
@ -182,7 +182,6 @@ public:
UINT16 CDC_DECODE;
UINT16 CDC_REG0;
UINT16 CDC_REG1;
UINT16 SEGACD_DMA_ADDRESS;
UINT8 CDC_BUFFER[(32 * 1024 * 2) + SECTOR_SIZE];
@ -245,8 +244,6 @@ public:
WRITE16_MEMBER( segacd_cdd_ctrl_w );
READ8_MEMBER( segacd_cdd_rx_r );
WRITE8_MEMBER( segacd_cdd_tx_w );
READ16_MEMBER( cdc_dmaaddr_r );
WRITE16_MEMBER( cdc_dmaaddr_w );
READ16_MEMBER( segacd_cdfader_r );
WRITE16_MEMBER( segacd_cdfader_w );
@ -285,13 +282,7 @@ public:
bool bNeoCDLoadSector;
INT32 NeoCDDMAAddress1;
INT32 NeoCDDMAAddress2;
INT32 NeoCDDMAValue1;
INT32 NeoCDDMAValue2;
INT32 NeoCDDMACount;
INT32 NeoCDDMAMode;
int nNeoCDIRQVectorAck;
int get_nNeoCDIRQVectorAck(void) { return nNeoCDIRQVectorAck; }
void set_nNeoCDIRQVectorAck(int val) { nNeoCDIRQVectorAck = val; }
@ -303,22 +294,15 @@ public:
void NeoCDCommsControl(UINT8 clock, UINT8 send);
void NeoCDProcessCommand();
void LC8951UpdateHeader();
char* LC8915InitTransfer();
char* LC8915InitTransfer(int NeoCDDMACount);
void LC8915EndTransfer();
void LC8951Reset();
void neocd_cdd_tx_w(UINT8 data);
UINT8 neocd_cdd_rx_r();
void NeoCDCommsReset();
void NeoCDDoDMA();
void SekWriteWord(UINT32 a, UINT16 d);
void SekWriteByte(UINT32 a, UINT8 d);
UINT32 SekReadByte(UINT32 a);
UINT32 SekReadWord(UINT32 a);
INT32 CDEmuLoadSector(INT32 LBA, char* pBuffer);
void set_DMA_regs(int offset, UINT16 wordValue);
void reset_NeoCd(void);
address_space* dma_space;
void nLC8951_w(UINT16 byteValue);
UINT16 nLC8951_r(void);

View File

@ -87,12 +87,22 @@ public:
: neogeo_state(mconfig, type, tag),
m_tempcdc(*this,"tempcdc")
{
NeoCDDMAAddress1 = 0;
NeoCDDMAAddress2 = 0;
NeoCDDMAValue1 = 0;
NeoCDDMAValue2 = 0;
NeoCDDMACount = 0;
NeoCDDMAMode = 0;
}
required_device<lc89510_temp_device> m_tempcdc;
optional_device<lc89510_temp_device> m_tempcdc;
void NeoCDDoDMA();
void set_DMA_regs(int offset, UINT16 wordValue);
UINT8 *m_memcard_data;
DECLARE_WRITE8_MEMBER(audio_cpu_clear_nmi_w);
DECLARE_WRITE16_MEMBER(io_control_w);
@ -134,6 +144,16 @@ public:
INT32 nActiveTransferArea;
INT32 nSpriteTransferBank;
INT32 nADPCMTransferBank;
INT32 NeoCDDMAAddress1;
INT32 NeoCDDMAAddress2;
INT32 NeoCDDMAValue1;
INT32 NeoCDDMAValue2;
INT32 NeoCDDMACount;
INT32 NeoCDDMAMode;
void SekWriteWord(UINT32 a, UINT16 d);
void SekWriteByte(UINT32 a, UINT8 d);
UINT32 SekReadByte(UINT32 a);
UINT32 SekReadWord(UINT32 a);
UINT8 nTransferWriteEnable;
@ -655,7 +675,6 @@ void ng_aes_state::neogeoWriteTransfer(UINT32 sekAddress, UINT8 byteValue, int i
case 0: // Sprites
address = (nSpriteTransferBank + (sekAddress & 0x0FFFFF));
// wtf? is this just due to how we decode the sprite gfx or is something bad happening?
if ((address&3)==0) NeoSpriteRAM[address] = byteValue;
if ((address&3)==1) NeoSpriteRAM[address^3] = byteValue;
if ((address&3)==2) NeoSpriteRAM[address^3] = byteValue;
@ -740,7 +759,7 @@ void ng_aes_state::neogeoWriteWordCDROM(UINT32 sekAddress, UINT16 wordValue)
// DMA controller
case 0x0060:
if (byteValue & 0x40) {
m_tempcdc->NeoCDDoDMA();
NeoCDDoDMA();
}
break;
@ -753,7 +772,7 @@ void ng_aes_state::neogeoWriteWordCDROM(UINT32 sekAddress, UINT16 wordValue)
case 0x0070:
case 0x0072:
case 0x007E:
m_tempcdc->set_DMA_regs(sekAddress & 0xFFFE, wordValue);
set_DMA_regs(sekAddress & 0xFFFE, wordValue);
break;
// upload DMA controller program
@ -934,6 +953,328 @@ WRITE16_MEMBER(ng_aes_state::neocd_transfer_w)
}
void ng_aes_state::set_DMA_regs(int offset, UINT16 wordValue)
{
switch (offset)
{
case 0x0064:
NeoCDDMAAddress1 &= 0x0000FFFF;
NeoCDDMAAddress1 |= wordValue << 16;
break;
case 0x0066:
NeoCDDMAAddress1 &= 0xFFFF0000;
NeoCDDMAAddress1 |= wordValue;
break;
case 0x0068:
NeoCDDMAAddress2 &= 0x0000FFFF;
NeoCDDMAAddress2 |= wordValue << 16;
break;
case 0x006A:
NeoCDDMAAddress2 &= 0xFFFF0000;
NeoCDDMAAddress2 |= wordValue;
break;
case 0x006C:
NeoCDDMAValue1 = wordValue;
break;
case 0x006E:
NeoCDDMAValue2 = wordValue;
break;
case 0x0070:
NeoCDDMACount &= 0x0000FFFF;
NeoCDDMACount |= wordValue << 16;
break;
case 0x0072:
NeoCDDMACount &= 0xFFFF0000;
NeoCDDMACount |= wordValue;
break;
case 0x007E:
NeoCDDMAMode = wordValue;
// bprintf(PRINT_NORMAL, _T(" - DMA controller 0x%2X -> 0x%04X (PC: 0x%06X)\n"), sekAddress & 0xFF, wordValue, SekGetPC(-1));
break;
}
}
void ng_aes_state::SekWriteWord(UINT32 a, UINT16 d)
{
// printf("write word %08x %04x\n", a, d);
curr_space->write_word(a,d);
}
void ng_aes_state::SekWriteByte(UINT32 a, UINT8 d)
{
// printf("write byte %08x %02x\n", a, d);
curr_space->write_byte(a,d);
}
UINT32 ng_aes_state::SekReadByte(UINT32 a)
{
// printf("read byte %08x\n", a);
return curr_space->read_byte(a);
}
UINT32 ng_aes_state::SekReadWord(UINT32 a)
{
// printf("read WORD %08x\n", a);
return curr_space->read_word(a);
}
static INT32 SekIdle(INT32 nCycles)
{
return nCycles;
}
void ng_aes_state::NeoCDDoDMA()
{
// The LC8953 chip has a programmable DMA controller, which is not properly emulated.
// Since the software only uses it in a limited way, we can apply a simple heuristic
// to determnine the requested operation.
// Additionally, we don't know how many cycles DMA operations take.
// Here, only bus access is used to get a rough approximation --
// each read/write takes a single cycle, setup and everything else is ignored.
// bprintf(PRINT_IMPORTANT, _T(" - DMA controller transfer started (PC: 0x%06X)\n"), SekGetPC(-1));
switch (NeoCDDMAMode) {
case 0xCFFD: {
// bprintf(PRINT_NORMAL, _T(" adr : 0x%08X - 0x%08X <- address, skip odd bytes\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 8);
// - DMA controller 0x7E -> 0xCFFD (PC: 0xC07CE2)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8)
// - DMA controller program[02] -> 0xE8DA (PC: 0xC07CEE)
// - DMA controller program[04] -> 0x92DA (PC: 0xC07CF4)
// - DMA controller program[06] -> 0x92DB (PC: 0xC07CFA)
// - DMA controller program[08] -> 0x96DB (PC: 0xC07D00)
// - DMA controller program[10] -> 0x96F6 (PC: 0xC07D06)
// - DMA controller program[12] -> 0x2E02 (PC: 0xC07D0C)
// - DMA controller program[14] -> 0xFDFF (PC: 0xC07D12)
SekIdle(NeoCDDMACount * 4);
while (NeoCDDMACount--) {
SekWriteWord(NeoCDDMAAddress1 + 0, NeoCDDMAAddress1 >> 24);
SekWriteWord(NeoCDDMAAddress1 + 2, NeoCDDMAAddress1 >> 16);
SekWriteWord(NeoCDDMAAddress1 + 4, NeoCDDMAAddress1 >> 8);
SekWriteWord(NeoCDDMAAddress1 + 6, NeoCDDMAAddress1 >> 0);
NeoCDDMAAddress1 += 8;
}
break;
}
case 0xE2DD: {
// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- 0x%08X - 0x%08X, skip odd bytes\n"), NeoCDDMAAddress2, NeoCDDMAAddress2 + NeoCDDMACount * 2, NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4);
// - DMA controller 0x7E -> 0xE2DD (PC: 0xC0A190)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192)
// - DMA controller program[02] -> 0x82BE (PC: 0xC0A194)
// - DMA controller program[04] -> 0x93DA (PC: 0xC0A196)
// - DMA controller program[06] -> 0xBE93 (PC: 0xC0A198)
// - DMA controller program[08] -> 0xDABE (PC: 0xC0A19A)
// - DMA controller program[10] -> 0xF62D (PC: 0xC0A19C)
// - DMA controller program[12] -> 0x02FD (PC: 0xC0A19E)
// - DMA controller program[14] -> 0xFFFF (PC: 0xC0A1A0)
SekIdle(NeoCDDMACount * 1);
while (NeoCDDMACount--) {
SekWriteWord(NeoCDDMAAddress2 + 0, SekReadByte(NeoCDDMAAddress1 + 0));
SekWriteWord(NeoCDDMAAddress2 + 2, SekReadByte(NeoCDDMAAddress1 + 1));
NeoCDDMAAddress1 += 2;
NeoCDDMAAddress2 += 4;
}
break;
}
case 0xFC2D: {
// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- LC8951 external buffer, skip odd bytes\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4);
// - DMA controller 0x7E -> 0xFC2D (PC: 0xC0A190)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192)
// - DMA controller program[02] -> 0x8492 (PC: 0xC0A194)
// - DMA controller program[04] -> 0xDA92 (PC: 0xC0A196)
// - DMA controller program[06] -> 0xDAF6 (PC: 0xC0A198)
// - DMA controller program[08] -> 0x2A02 (PC: 0xC0A19A)
// - DMA controller program[10] -> 0xFDFF (PC: 0xC0A19C)
// - DMA controller program[12] -> 0x48E7 (PC: 0xC0A19E)
// - DMA controller program[14] -> 0xFFFE (PC: 0xC0A1A0)
char* data = m_tempcdc->LC8915InitTransfer(NeoCDDMACount);
if (data == NULL) {
break;
}
SekIdle(NeoCDDMACount * 4);
while (NeoCDDMACount--) {
SekWriteByte(NeoCDDMAAddress1 + 0, data[0]);
SekWriteByte(NeoCDDMAAddress1 + 2, data[1]);
NeoCDDMAAddress1 += 4;
data += 2;
}
m_tempcdc->LC8915EndTransfer();
break;
}
case 0xFE3D:
// - DMA controller 0x7E -> 0xFE3D (PC: 0xC0A190)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192)
// - DMA controller program[02] -> 0x82BF (PC: 0xC0A194)
// - DMA controller program[04] -> 0x93BF (PC: 0xC0A196)
// - DMA controller program[06] -> 0xF629 (PC: 0xC0A198)
// - DMA controller program[08] -> 0x02FD (PC: 0xC0A19A)
// - DMA controller program[10] -> 0xFFFF (PC: 0xC0A19C)
// - DMA controller program[12] -> 0xF17D (PC: 0xC0A19E)
// - DMA controller program[14] -> 0xFCF5 (PC: 0xC0A1A0)
case 0xFE6D: {
// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- 0x%08X - 0x%08X\n"), NeoCDDMAAddress2, NeoCDDMAAddress2 + NeoCDDMACount * 2, NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2);
// - DMA controller 0x7E -> 0xFE6D (PC: 0xC0FD7A)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0FD7C)
// - DMA controller program[02] -> 0x82BF (PC: 0xC0FD7E)
// - DMA controller program[04] -> 0xF693 (PC: 0xC0FD80)
// - DMA controller program[06] -> 0xBF29 (PC: 0xC0FD82)
// - DMA controller program[08] -> 0x02FD (PC: 0xC0FD84)
// - DMA controller program[10] -> 0xFFFF (PC: 0xC0FD86)
// - DMA controller program[12] -> 0xC515 (PC: 0xC0FD88)
// - DMA controller program[14] -> 0xFCF5 (PC: 0xC0FD8A)
SekIdle(NeoCDDMACount * 1);
while (NeoCDDMACount--) {
SekWriteWord(NeoCDDMAAddress2, SekReadWord(NeoCDDMAAddress1));
NeoCDDMAAddress1 += 2;
NeoCDDMAAddress2 += 2;
}
if (NeoCDDMAAddress2 == 0x0800) {
// MapVectorTable(false);
// bprintf(PRINT_ERROR, _T(" RAM vectors mapped (PC = 0x%08X\n"), SekGetPC(0));
// extern INT32 bRunPause;
// bRunPause = 1;
}
break;
}
case 0xFEF5: {
// bprintf(PRINT_NORMAL, _T(" adr : 0x%08X - 0x%08X <- address\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4);
// - DMA controller 0x7E -> 0xFEF5 (PC: 0xC07CE2)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8)
// - DMA controller program[02] -> 0x92E8 (PC: 0xC07CEE)
// - DMA controller program[04] -> 0xBE96 (PC: 0xC07CF4)
// - DMA controller program[06] -> 0xF629 (PC: 0xC07CFA)
// - DMA controller program[08] -> 0x02FD (PC: 0xC07D00)
// - DMA controller program[10] -> 0xFFFF (PC: 0xC07D06)
// - DMA controller program[12] -> 0xFC3D (PC: 0xC07D0C)
// - DMA controller program[14] -> 0xFCF5 (PC: 0xC07D12)
SekIdle(NeoCDDMACount * 2);
while (NeoCDDMACount--) {
SekWriteWord(NeoCDDMAAddress1 + 0, NeoCDDMAAddress1 >> 16);
SekWriteWord(NeoCDDMAAddress1 + 2, NeoCDDMAAddress1 >> 0);
NeoCDDMAAddress1 += 4;
}
break;
}
case 0xFFC5: {
// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- LC8951 external buffer\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2);
// - DMA controller 0x7E -> 0xFFC5 (PC: 0xC0A190)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192)
// - DMA controller program[02] -> 0xA6F6 (PC: 0xC0A194)
// - DMA controller program[04] -> 0x2602 (PC: 0xC0A196)
// - DMA controller program[06] -> 0xFDFF (PC: 0xC0A198)
// - DMA controller program[08] -> 0xFC2D (PC: 0xC0A19A)
// - DMA controller program[10] -> 0xFCF5 (PC: 0xC0A19C)
// - DMA controller program[12] -> 0x8492 (PC: 0xC0A19E)
// - DMA controller program[14] -> 0xDA92 (PC: 0xC0A1A0)
char* data = m_tempcdc->LC8915InitTransfer(NeoCDDMACount);
if (data == NULL) {
break;
}
SekIdle(NeoCDDMACount * 4);
while (NeoCDDMACount--) {
SekWriteByte(NeoCDDMAAddress1 + 0, data[0]);
SekWriteByte(NeoCDDMAAddress1 + 1, data[1]);
NeoCDDMAAddress1 += 2;
data += 2;
}
m_tempcdc->LC8915EndTransfer();
break;
}
case 0xFFCD:
// - DMA controller 0x7E -> 0xFFCD (PC: 0xC0A190)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192)
// - DMA controller program[02] -> 0x92F6 (PC: 0xC0A194)
// - DMA controller program[04] -> 0x2602 (PC: 0xC0A196)
// - DMA controller program[06] -> 0xFDFF (PC: 0xC0A198)
// - DMA controller program[08] -> 0x7006 (PC: 0xC0A19A)
// - DMA controller program[10] -> 0x6100 (PC: 0xC0A19C)
// - DMA controller program[12] -> 0x2412 (PC: 0xC0A19E)
// - DMA controller program[14] -> 0x13FC (PC: 0xC0A1A0)
case 0xFFDD: {
// bprintf(PRINT_NORMAL, _T(" Fill: 0x%08X - 0x%08X <- 0x%04X\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2, NeoCDDMAValue1);
// - DMA controller 0x7E -> 0xFFDD (PC: 0xC07CE2)
// - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8)
// - DMA controller program[02] -> 0x92F6 (PC: 0xC07CEE)
// - DMA controller program[04] -> 0x2602 (PC: 0xC07CF4)
// - DMA controller program[06] -> 0xFDFF (PC: 0xC07CFA)
// - DMA controller program[08] -> 0xFFFF (PC: 0xC07D00)
// - DMA controller program[10] -> 0xFCF5 (PC: 0xC07D06)
// - DMA controller program[12] -> 0x8AF0 (PC: 0xC07D0C)
// - DMA controller program[14] -> 0x1609 (PC: 0xC07D12)
SekIdle(NeoCDDMACount * 1);
while (NeoCDDMACount--) {
SekWriteWord(NeoCDDMAAddress1, NeoCDDMAValue1);
NeoCDDMAAddress1 += 2;
}
break;
}
default: {
//bprintf(PRINT_ERROR, _T(" Unknown transfer type 0x%04X (PC: 0x%06X)\n"), NeoCDDMAMode, SekGetPC(-1));
//bprintf(PRINT_NORMAL, _T(" ??? : 0x%08X 0x%08X 0x%04X 0x%04X 0x%08X\n"), NeoCDDMAAddress1, NeoCDDMAAddress2, NeoCDDMAValue1, NeoCDDMAValue2, NeoCDDMACount);
//extern INT32 bRunPause;
//bRunPause = 1;
}
}
}
/*
* Handling selectable controller types
*/
@ -1170,7 +1511,6 @@ MACHINE_RESET_MEMBER(ng_aes_state,neogeo)
NeoZ80ROMActive = memregion("audiocpu")->base();
NeoTextRAM = memregion("fixed")->base();
curr_space = &machine().device("maincpu")->memory().space(AS_PROGRAM);
m_tempcdc->dma_space = curr_space;
m_tempcdc->NeoCDCommsReset();