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)
{
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;
nff0002 = 0;
nIRQAcknowledge = ~0;
for (int i=0;i<10;i++)
CDD_TX[i] = 0;
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;
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)
{
@ -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;
}
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)
{
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()
{
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");
}
@ -1019,8 +1045,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( lc89510_temp_device::segacd_access_timer_callback
{
if (nff0002 & 0x0050)
{
nIRQAcknowledge &= ~0x10;
NeoCDIRQUpdate(0);
type2_interrupt_callback();
}
}
@ -1192,14 +1217,13 @@ void lc89510_temp_device::scd_ctrl_checks(running_machine& machine)
if (LC8951RegistersW[REG_W_IFCTRL] & 0x20)
{
// todo: handle as interrupt callback
if (is_neoCD)
{
nIRQAcknowledge &= ~0x20;
NeoCDIRQUpdate(0);
type1_interrupt_callback();
}
else
{
// todo: make callback
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)
{

View File

@ -5,6 +5,7 @@
typedef device_delegate<void (int&, UINT8*, UINT16&, UINT16&)> segacd_dma_delegate;
typedef device_delegate<void (void)> interrupt_delegate;
#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 \
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 */
@ -156,8 +165,18 @@ public:
// HACK for DMA handling
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 );
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);
@ -268,7 +287,6 @@ public:
cdda_device* m_cdda;
/* NeoCD */
INT32 nIRQAcknowledge;
UINT16 nff0002;
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 LC8951UpdateHeader();
char* LC8915InitTransfer(int NeoCDDMACount);

View File

@ -107,6 +107,9 @@ public:
NeoCDDMAValue2 = 0;
NeoCDDMACount = 0;
NeoCDDMAMode = 0;
nIRQAcknowledge = ~0;
nNeoCDIRQVectorAck = 0;
nNeoCDIRQVector = 0;
}
@ -152,6 +155,19 @@ public:
INT32 NeoCDDMAValue2;
INT32 NeoCDDMACount;
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;
@ -323,7 +339,7 @@ WRITE16_MEMBER(ng_aes_state::neocd_control_w)
break;
case 0x000E:
m_tempcdc->NeoCDIRQUpdate(wordValue); // irqack
NeoCDIRQUpdate(wordValue); // irqack
break;
case 0x0016:
@ -447,12 +463,16 @@ WRITE16_MEMBER(ng_aes_state::neocd_control_w)
break;
case 0x0180: {
static UINT8 clara = 0;
if (!byteValue && clara) {
// bprintf(PRINT_IMPORTANT, _T(" - NGCD CD communication reset (PC: 0x%06X)\n"), SekGetPC(-1));
// NeoCDCommsReset();
// 1 during CD access, 0 otherwise, written frequently
//printf("reset cdc %04x %04x\n",data, mem_mask);
if (ACCESSING_BITS_0_7)
{
if (data==0x00)
{
m_tempcdc->NeoCDCommsReset();
}
}
clara = byteValue;
break;
}
case 0x0182: {
@ -1509,16 +1529,59 @@ static IRQ_CALLBACK(neocd_int_callback)
if (irqline==4)
{
if (state->m_tempcdc->get_nNeoCDIRQVectorAck()) {
state->m_tempcdc->set_nNeoCDIRQVectorAck(0);
return state->m_tempcdc->get_nNeoCDIRQVector();
if (state->get_nNeoCDIRQVectorAck()) {
state->set_nNeoCDIRQVectorAck(0);
return state->get_nNeoCDIRQVector();
}
}
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 =
{
@ -1538,6 +1601,10 @@ static MACHINE_CONFIG_DERIVED_CLASS( neocd, neogeo_base, ng_aes_state )
// temporary until things are cleaned up
MCFG_DEVICE_ADD("tempcdc", LC89510_TEMP, 0) // cd controller
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)