move some ngcd specific code back into the actual driver (nw)

This commit is contained in:
David Haywood 2012-12-07 14:39:33 +00:00
parent 44dcd0d39c
commit 35ee2c5603
3 changed files with 127 additions and 48 deletions

View File

@ -14,10 +14,13 @@ lc89510_temp_device::lc89510_temp_device(const machine_config &mconfig, const ch
: device_t(mconfig, LC89510_TEMP, "lc89510_temp_device", tag, owner, clock) : device_t(mconfig, LC89510_TEMP, "lc89510_temp_device", tag, owner, clock)
{ {
segacd_dma_callback = segacd_dma_delegate(FUNC(lc89510_temp_device::Fake_CDC_Do_DMA), this); segacd_dma_callback = segacd_dma_delegate(FUNC(lc89510_temp_device::Fake_CDC_Do_DMA), this);
type1_interrupt_callback = interrupt_delegate(FUNC(lc89510_temp_device::dummy_interrupt_callback), this);
type2_interrupt_callback = interrupt_delegate(FUNC(lc89510_temp_device::dummy_interrupt_callback), this);
type3_interrupt_callback = interrupt_delegate(FUNC(lc89510_temp_device::dummy_interrupt_callback), this);
is_neoCD = false; is_neoCD = false;
nff0002 = 0; nff0002 = 0;
nIRQAcknowledge = ~0;
for (int i=0;i<10;i++) for (int i=0;i<10;i++)
CDD_TX[i] = 0; CDD_TX[i] = 0;
for (int i=0;i<10;i++) for (int i=0;i<10;i++)
@ -27,11 +30,12 @@ lc89510_temp_device::lc89510_temp_device(const machine_config &mconfig, const ch
SCD_CURLBA = 0; SCD_CURLBA = 0;
CDC_REG0 = 0; CDC_REG0 = 0;
nNeoCDIRQVectorAck = 0;
nNeoCDIRQVector = 0;
} }
void lc89510_temp_device::dummy_interrupt_callback(void)
{
}
void lc89510_temp_device::set_CDC_Do_DMA(device_t &device,segacd_dma_delegate new_segacd_dma_callback) void lc89510_temp_device::set_CDC_Do_DMA(device_t &device,segacd_dma_delegate new_segacd_dma_callback)
{ {
@ -39,6 +43,24 @@ void lc89510_temp_device::set_CDC_Do_DMA(device_t &device,segacd_dma_delegate ne
dev.segacd_dma_callback = new_segacd_dma_callback; dev.segacd_dma_callback = new_segacd_dma_callback;
} }
void lc89510_temp_device::set_type1_interrupt_callback(device_t &device,interrupt_delegate interrupt_callback)
{
lc89510_temp_device &dev = downcast<lc89510_temp_device &>(device);
dev.type1_interrupt_callback = interrupt_callback;
}
void lc89510_temp_device::set_type2_interrupt_callback(device_t &device,interrupt_delegate interrupt_callback)
{
lc89510_temp_device &dev = downcast<lc89510_temp_device &>(device);
dev.type2_interrupt_callback = interrupt_callback;
}
void lc89510_temp_device::set_type3_interrupt_callback(device_t &device,interrupt_delegate interrupt_callback)
{
lc89510_temp_device &dev = downcast<lc89510_temp_device &>(device);
dev.type3_interrupt_callback = interrupt_callback;
}
void lc89510_temp_device::set_is_neoCD(device_t &device, bool is_neoCD) void lc89510_temp_device::set_is_neoCD(device_t &device, bool is_neoCD)
{ {
lc89510_temp_device &dev = downcast<lc89510_temp_device &>(device); lc89510_temp_device &dev = downcast<lc89510_temp_device &>(device);
@ -54,6 +76,10 @@ void lc89510_temp_device::Fake_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT
void lc89510_temp_device::device_start() void lc89510_temp_device::device_start()
{ {
segacd_dma_callback.bind_relative_to(*owner()); segacd_dma_callback.bind_relative_to(*owner());
type1_interrupt_callback.bind_relative_to(*owner());
type2_interrupt_callback.bind_relative_to(*owner());
type3_interrupt_callback.bind_relative_to(*owner());
m_cdda = (cdda_device*)subdevice("cdda"); m_cdda = (cdda_device*)subdevice("cdda");
} }
@ -1019,8 +1045,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( lc89510_temp_device::segacd_access_timer_callback
{ {
if (nff0002 & 0x0050) if (nff0002 & 0x0050)
{ {
nIRQAcknowledge &= ~0x10; type2_interrupt_callback();
NeoCDIRQUpdate(0);
} }
} }
@ -1192,14 +1217,13 @@ void lc89510_temp_device::scd_ctrl_checks(running_machine& machine)
if (LC8951RegistersW[REG_W_IFCTRL] & 0x20) if (LC8951RegistersW[REG_W_IFCTRL] & 0x20)
{ {
// todo: handle as interrupt callback
if (is_neoCD) if (is_neoCD)
{ {
nIRQAcknowledge &= ~0x20; type1_interrupt_callback();
NeoCDIRQUpdate(0);
} }
else else
{ {
// todo: make callback
CHECK_SCD_LV5_INTERRUPT CHECK_SCD_LV5_INTERRUPT
} }
@ -1293,31 +1317,7 @@ int lc89510_temp_device::Read_LBA_To_Buffer(running_machine& machine)
void lc89510_temp_device::NeoCDIRQUpdate(UINT8 byteValue)
{
// do we also need to check the regular interrupts like FBA?
nIRQAcknowledge |= (byteValue & 0x38);
if ((nIRQAcknowledge & 0x08) == 0) {
nNeoCDIRQVector = 0x17;
nNeoCDIRQVectorAck = 1;
machine().device("maincpu")->execute().set_input_line(4, HOLD_LINE);
return;
}
if ((nIRQAcknowledge & 0x10) == 0) {
nNeoCDIRQVector = 0x16;
nNeoCDIRQVectorAck = 1;
machine().device("maincpu")->execute().set_input_line(4, HOLD_LINE);
return;
}
if ((nIRQAcknowledge & 0x20) == 0) {
nNeoCDIRQVector = 0x15;
nNeoCDIRQVectorAck = 1;
machine().device("maincpu")->execute().set_input_line(4, HOLD_LINE);
return;
}
}
void lc89510_temp_device::nff0002_set(UINT16 wordValue) void lc89510_temp_device::nff0002_set(UINT16 wordValue)
{ {

View File

@ -5,6 +5,7 @@
typedef device_delegate<void (int&, UINT8*, UINT16&, UINT16&)> segacd_dma_delegate; typedef device_delegate<void (int&, UINT8*, UINT16&, UINT16&)> segacd_dma_delegate;
typedef device_delegate<void (void)> interrupt_delegate;
#define READ_MAIN (0x0200) #define READ_MAIN (0x0200)
@ -136,6 +137,14 @@ typedef device_delegate<void (int&, UINT8*, UINT16&, UINT16&)> segacd_dma_delega
#define MCFG_SEGACD_HACK_SET_NEOCD \ #define MCFG_SEGACD_HACK_SET_NEOCD \
lc89510_temp_device::set_is_neoCD(*device, true); \ lc89510_temp_device::set_is_neoCD(*device, true); \
#define MCFG_SET_TYPE1_INTERRUPT_CALLBACK( _class, _method) \
lc89510_temp_device::set_type1_interrupt_callback(*device, interrupt_delegate(&_class::_method, #_class "::" #_method, NULL, (_class *)0)); \
#define MCFG_SET_TYPE2_INTERRUPT_CALLBACK( _class, _method) \
lc89510_temp_device::set_type2_interrupt_callback(*device, interrupt_delegate(&_class::_method, #_class "::" #_method, NULL, (_class *)0)); \
#define MCFG_SET_TYPE3_INTERRUPT_CALLBACK( _class, _method) \
lc89510_temp_device::set_type3_interrupt_callback(*device, interrupt_delegate(&_class::_method, #_class "::" #_method, NULL, (_class *)0)); \
/* neocd */ /* neocd */
@ -156,8 +165,18 @@ public:
// HACK for DMA handling // HACK for DMA handling
segacd_dma_delegate segacd_dma_callback; segacd_dma_delegate segacd_dma_callback;
interrupt_delegate type1_interrupt_callback;
interrupt_delegate type2_interrupt_callback;
interrupt_delegate type3_interrupt_callback;
void Fake_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, 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_CDC_Do_DMA(device_t &device,segacd_dma_delegate new_segacd_dma_callback);
void dummy_interrupt_callback(void);
static void set_type1_interrupt_callback(device_t &device,interrupt_delegate interrupt_callback);
static void set_type2_interrupt_callback(device_t &device,interrupt_delegate interrupt_callback);
static void set_type3_interrupt_callback(device_t &device,interrupt_delegate interrupt_callback);
static void set_is_neoCD(device_t &device, bool is_neoCD); static void set_is_neoCD(device_t &device, bool is_neoCD);
@ -268,7 +287,6 @@ public:
cdda_device* m_cdda; cdda_device* m_cdda;
/* NeoCD */ /* NeoCD */
INT32 nIRQAcknowledge;
UINT16 nff0002; UINT16 nff0002;
UINT16 nff0016; UINT16 nff0016;
@ -286,13 +304,7 @@ public:
int nNeoCDIRQVectorAck;
int get_nNeoCDIRQVectorAck(void) { return nNeoCDIRQVectorAck; }
void set_nNeoCDIRQVectorAck(int val) { nNeoCDIRQVectorAck = val; }
int nNeoCDIRQVector;
int get_nNeoCDIRQVector(void) { return nNeoCDIRQVector; }
void NeoCDIRQUpdate(UINT8 byteValue);
void NeoCDCommsControl(UINT8 clock, UINT8 send); void NeoCDCommsControl(UINT8 clock, UINT8 send);
void LC8951UpdateHeader(); void LC8951UpdateHeader();
char* LC8915InitTransfer(int NeoCDDMACount); char* LC8915InitTransfer(int NeoCDDMACount);

View File

@ -107,6 +107,9 @@ public:
NeoCDDMAValue2 = 0; NeoCDDMAValue2 = 0;
NeoCDDMACount = 0; NeoCDDMACount = 0;
NeoCDDMAMode = 0; NeoCDDMAMode = 0;
nIRQAcknowledge = ~0;
nNeoCDIRQVectorAck = 0;
nNeoCDIRQVector = 0;
} }
@ -152,6 +155,19 @@ public:
INT32 NeoCDDMAValue2; INT32 NeoCDDMAValue2;
INT32 NeoCDDMACount; INT32 NeoCDDMACount;
INT32 NeoCDDMAMode; INT32 NeoCDDMAMode;
INT32 nIRQAcknowledge;
int nNeoCDIRQVectorAck;
int nNeoCDIRQVector;
int get_nNeoCDIRQVectorAck(void) { return nNeoCDIRQVectorAck; }
void set_nNeoCDIRQVectorAck(int val) { nNeoCDIRQVectorAck = val; }
int get_nNeoCDIRQVector(void) { return nNeoCDIRQVector; }
void NeoCDIRQUpdate(UINT8 byteValue);
// from the CDC
void interrupt_callback_type1(void);
void interrupt_callback_type2(void);
void interrupt_callback_type3(void);
UINT8 nTransferWriteEnable; UINT8 nTransferWriteEnable;
@ -323,7 +339,7 @@ WRITE16_MEMBER(ng_aes_state::neocd_control_w)
break; break;
case 0x000E: case 0x000E:
m_tempcdc->NeoCDIRQUpdate(wordValue); // irqack NeoCDIRQUpdate(wordValue); // irqack
break; break;
case 0x0016: case 0x0016:
@ -447,12 +463,16 @@ WRITE16_MEMBER(ng_aes_state::neocd_control_w)
break; break;
case 0x0180: { case 0x0180: {
static UINT8 clara = 0; // 1 during CD access, 0 otherwise, written frequently
if (!byteValue && clara) { //printf("reset cdc %04x %04x\n",data, mem_mask);
// bprintf(PRINT_IMPORTANT, _T(" - NGCD CD communication reset (PC: 0x%06X)\n"), SekGetPC(-1));
// NeoCDCommsReset(); if (ACCESSING_BITS_0_7)
{
if (data==0x00)
{
m_tempcdc->NeoCDCommsReset();
}
} }
clara = byteValue;
break; break;
} }
case 0x0182: { case 0x0182: {
@ -1509,16 +1529,59 @@ static IRQ_CALLBACK(neocd_int_callback)
if (irqline==4) if (irqline==4)
{ {
if (state->m_tempcdc->get_nNeoCDIRQVectorAck()) { if (state->get_nNeoCDIRQVectorAck()) {
state->m_tempcdc->set_nNeoCDIRQVectorAck(0); state->set_nNeoCDIRQVectorAck(0);
return state->m_tempcdc->get_nNeoCDIRQVector(); return state->get_nNeoCDIRQVector();
} }
} }
return (0x60+irqline*4)/4; return (0x60+irqline*4)/4;
} }
void ng_aes_state::interrupt_callback_type1(void)
{
nIRQAcknowledge &= ~0x20;
NeoCDIRQUpdate(0);
}
void ng_aes_state::interrupt_callback_type2(void)
{
nIRQAcknowledge &= ~0x10;
NeoCDIRQUpdate(0);
}
void ng_aes_state::interrupt_callback_type3(void)
{
nIRQAcknowledge &= ~0x08;
NeoCDIRQUpdate(0);
}
void ng_aes_state::NeoCDIRQUpdate(UINT8 byteValue)
{
// do we also need to check the regular interrupts like FBA?
nIRQAcknowledge |= (byteValue & 0x38);
if ((nIRQAcknowledge & 0x08) == 0) {
nNeoCDIRQVector = 0x17;
nNeoCDIRQVectorAck = 1;
machine().device("maincpu")->execute().set_input_line(4, HOLD_LINE);
return;
}
if ((nIRQAcknowledge & 0x10) == 0) {
nNeoCDIRQVector = 0x16;
nNeoCDIRQVectorAck = 1;
machine().device("maincpu")->execute().set_input_line(4, HOLD_LINE);
return;
}
if ((nIRQAcknowledge & 0x20) == 0) {
nNeoCDIRQVector = 0x15;
nNeoCDIRQVectorAck = 1;
machine().device("maincpu")->execute().set_input_line(4, HOLD_LINE);
return;
}
}
struct cdrom_interface neocd_cdrom = struct cdrom_interface neocd_cdrom =
{ {
@ -1538,6 +1601,10 @@ static MACHINE_CONFIG_DERIVED_CLASS( neocd, neogeo_base, ng_aes_state )
// temporary until things are cleaned up // temporary until things are cleaned up
MCFG_DEVICE_ADD("tempcdc", LC89510_TEMP, 0) // cd controller MCFG_DEVICE_ADD("tempcdc", LC89510_TEMP, 0) // cd controller
MCFG_SEGACD_HACK_SET_NEOCD MCFG_SEGACD_HACK_SET_NEOCD
MCFG_SET_TYPE1_INTERRUPT_CALLBACK( ng_aes_state, interrupt_callback_type1 )
MCFG_SET_TYPE2_INTERRUPT_CALLBACK( ng_aes_state, interrupt_callback_type2 )
MCFG_SET_TYPE3_INTERRUPT_CALLBACK( ng_aes_state, interrupt_callback_type3 )
MCFG_MEMCARD_HANDLER(neogeo_aes) MCFG_MEMCARD_HANDLER(neogeo_aes)