mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
hng64 refactoring (#3860)
* hng64, refactoring (nw) * refactor (nw) * pull out the IRQC too (nw) * (nw) * more notes (nw) * move some notes around * note (nw) * note (nw)
This commit is contained in:
parent
48db4878ea
commit
4d69f34870
@ -486,54 +486,34 @@ READ8_MEMBER(hng64_state::hng64_com_share_r)
|
||||
return m_com_shared[offset];
|
||||
}
|
||||
|
||||
READ32_MEMBER(hng64_state::hng64_sysregs_r)
|
||||
|
||||
READ32_MEMBER(hng64_state::hng64_rtc_r)
|
||||
{
|
||||
uint16_t rtc_addr;
|
||||
|
||||
#if 0
|
||||
if((offset*4) != 0x1084)
|
||||
printf("HNG64 port read (PC=%08x) 0x%08x\n", m_maincpu->pc(), offset*4);
|
||||
#endif
|
||||
|
||||
rtc_addr = offset >> 1;
|
||||
|
||||
if((rtc_addr & 0xff0) == 0x420)
|
||||
if (offset & 1)
|
||||
{
|
||||
if((rtc_addr & 0xf) == 0xd)
|
||||
return m_rtc->read(space, (rtc_addr) & 0xf) | 0x10; // bit 4 disables "system log reader"
|
||||
// RTC is mapped to 1 byte (4-bits used) in every 8 bytes so we can't even install this with a umask
|
||||
int rtc_addr = offset >> 1;
|
||||
|
||||
// bit 4 disables "system log reader" (the device is 4-bit? so this bit is not from the device?)
|
||||
if ((rtc_addr & 0xf) == 0xd)
|
||||
return m_rtc->read(space, (rtc_addr) & 0xf) | 0x10;
|
||||
|
||||
return m_rtc->read(space, (rtc_addr) & 0xf);
|
||||
}
|
||||
|
||||
switch(offset*4)
|
||||
else
|
||||
{
|
||||
case 0x001c: return machine().rand(); // hng64 hangs on start-up if zero.
|
||||
//case 0x106c:
|
||||
//case 0x107c:
|
||||
case 0x1084:
|
||||
LOG("%s: HNG64 reading MCU status port (%08x)\n", machine().describe_context(), mem_mask);
|
||||
return 0x00000002; //MCU->MIPS latch port
|
||||
//case 0x108c:
|
||||
case 0x1104:
|
||||
LOG("%s: irq level READ %04x\n", machine().describe_context(),m_irq_level);
|
||||
return m_irq_level;
|
||||
case 0x111c:
|
||||
//printf("Read to IRQ ACK?\n");
|
||||
break;
|
||||
case 0x1254: return 0x00000000; //dma status, 0x800
|
||||
// shouldn't happen unless something else is mapped here too
|
||||
LOG("%s: unhandled hng64_rtc_r (%04x) (%08x)\n", machine().describe_context(), offset*4, mem_mask);
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
// printf("%08x\n",offset*4);
|
||||
|
||||
// return machine().rand()&0xffffffff;
|
||||
return m_sysregs[offset];
|
||||
}
|
||||
|
||||
/* preliminary dma code, dma is used to copy program code -> ram */
|
||||
void hng64_state::do_dma(address_space &space)
|
||||
{
|
||||
//printf("Performing DMA Start %08x Len %08x Dst %08x\n", m_dma_start, m_dma_len, m_dma_dst);
|
||||
// check if this determines how long the crosshatch is visible for, we might need to put it on a timer.
|
||||
|
||||
//printf("Performing DMA Start %08x Len %08x Dst %08x\n", m_dma_start, m_dma_len, m_dma_dst);
|
||||
while (m_dma_len >= 0)
|
||||
{
|
||||
uint32_t dat;
|
||||
@ -546,28 +526,145 @@ void hng64_state::do_dma(address_space &space)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// AM_RANGE(0x1F70100C, 0x1F70100F) AM_WRITENOP // ?? often
|
||||
// AM_RANGE(0x1F70101C, 0x1F70101F) AM_WRITENOP // ?? often
|
||||
// AM_RANGE(0x1F70106C, 0x1F70106F) AM_WRITENOP // fatfur,strange
|
||||
// AM_RANGE(0x1F701084, 0x1F701087) AM_RAM
|
||||
// AM_RANGE(0x1F70111C, 0x1F70111F) AM_WRITENOP // irq ack
|
||||
READ32_MEMBER(hng64_state::hng64_dmac_r)
|
||||
{
|
||||
// DMAC seems to be mapped as 4 bytes in every 8
|
||||
if ((offset * 4) == 0x54)
|
||||
return 0x00000000; //dma status, 0x800
|
||||
|
||||
// AM_RANGE(0x1F70124C, 0x1F70124F) AM_WRITENOP // dma related?
|
||||
// AM_RANGE(0x1F70125C, 0x1F70125F) AM_WRITENOP // dma related?
|
||||
// AM_RANGE(0x1F7021C4, 0x1F7021C7) AM_WRITENOP // ?? often
|
||||
LOG("%s: unhandled hng64_dmac_r (%04x) (%08x)\n", machine().describe_context(), offset*4, mem_mask);
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(hng64_state::hng64_dmac_w)
|
||||
{
|
||||
// DMAC seems to be mapped as 4 bytes in every 8
|
||||
switch (offset * 4)
|
||||
{
|
||||
case 0x04: COMBINE_DATA(&m_dma_start); break;
|
||||
case 0x14: COMBINE_DATA(&m_dma_dst); break;
|
||||
case 0x24: COMBINE_DATA(&m_dma_len);
|
||||
do_dma(space);
|
||||
break;
|
||||
|
||||
// these are touched during startup when setting up the DMA, maybe mode selection?
|
||||
case 0x34: // (0x0075)
|
||||
case 0x44: // (0x0000)
|
||||
|
||||
// written immediately after length, maybe one of these is the actual trigger?, 4c is explicitly set to 0 after all operations are complete
|
||||
case 0x4c: // (0x0101 - trigger) (0x0000 - after DMA)
|
||||
case 0x5c: // (0x0008 - trigger?) after 0x4c
|
||||
default:
|
||||
LOG("%s: unhandled hng64_dmac_w (%04x) %08x (%08x)\n", machine().describe_context(), offset*4, data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(hng64_state::hng64_rtc_w)
|
||||
{
|
||||
if (offset & 1)
|
||||
{
|
||||
// RTC is mapped to 1 byte (4-bits used) in every 8 bytes so we can't even install this with a umask
|
||||
m_rtc->write(space, (offset >> 1) & 0xf, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// shouldn't happen unless something else is mapped here too
|
||||
LOG("%s: unhandled hng64_rtc_w (%04x) %08x (%08x)\n", machine().describe_context(), offset*4, data, mem_mask);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(hng64_state::hng64_mips_to_iomcu_irq_w)
|
||||
{
|
||||
// guess, written after a write to 0x00 in dpram, which is where the command goes, and the IRQ onthe MCU reads the command
|
||||
LOG("%s: HNG64 writing to SYSTEM Registers %08x (%08x) (IO MCU IRQ TRIGGER?)\n", machine().describe_context(), data, mem_mask);
|
||||
if (mem_mask & 0xffff0000) m_tempio_irqon_timer->adjust(attotime::zero);
|
||||
}
|
||||
|
||||
READ32_MEMBER(hng64_state::hng64_irqc_r)
|
||||
{
|
||||
if ((offset * 4) == 0x04)
|
||||
{
|
||||
LOG("%s: irq level READ %04x\n", machine().describe_context(), m_irq_level);
|
||||
return m_irq_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("%s: unhandled hng64_irqc_r (%04x) (%08x)\n", machine().describe_context(), offset*4, mem_mask);
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(hng64_state::hng64_irqc_w)
|
||||
{
|
||||
switch (offset * 4)
|
||||
{
|
||||
//case 0x0c: // global irq mask? (probably not)
|
||||
case 0x1c:
|
||||
// IRQ ack
|
||||
m_irq_pending &= ~(data&mem_mask);
|
||||
set_irq(0x0000);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG("%s: unhandled hng64_irqc_w (%04x) %08x (%08x)\n", machine().describe_context(), offset * 4, data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
These 'sysregs' seem to be multiple sets of the same thing
|
||||
(based on xrally)
|
||||
|
||||
the 0x1084 addresses appear to be related to the IO MCU, but neither sending commands to the MCU, not controlling lines directly
|
||||
0x20 is written to 0x1084 in the MIPS IRQ handlers for the IO MCU (both 0x11 and 0x17 irq levels)
|
||||
|
||||
the 0x1074 address seems to be the same thing but for the network CPU
|
||||
0x20 is written to 0x1074 in the MIPS IRQ handlers that seem to be associated with communication (levels 0x09, 0x0a, 0x0b, 0x0c)
|
||||
|
||||
|
||||
-----
|
||||
the following notes are taken from the old 'fake IO' function, in reality it turned out that these 'commands' were not needed
|
||||
with the real IO MCU hooked up, although we still use the 0x0c one as a hack in order to provide the 'm_no_machine_error_code' value
|
||||
in order to bypass a startup check, in reality it looks like that should be written by the MCU after reading it via serial.
|
||||
|
||||
---- OUTDATED NOTES ----
|
||||
|
||||
I'm not really convinced these are commands in this sense based on code analysis, probably just a non-standard way of controlling the lines
|
||||
|
||||
command table:
|
||||
0x0b = ? mode input polling (sams64, bbust2, sams64_2 & roadedge) (*)
|
||||
0x0c = cut down connections, treats the dualport to be normal RAM
|
||||
0x11 = ? mode input polling (fatfurwa, xrally, buriki) (*)
|
||||
0x20 = asks for MCU machine code (probably not, this is also written in the function after the TLCS870 requests an interrupt on the MIPS)
|
||||
|
||||
(*) 0x11 is followed by 0x0b if the latter is used, JVS-esque indirect/direct mode?
|
||||
----
|
||||
*/
|
||||
|
||||
READ32_MEMBER(hng64_state::hng64_sysregs_r)
|
||||
{
|
||||
//LOG("%s: hng64_sysregs_r (%04x) (%08x)\n", machine().describe_context(), offset * 4, mem_mask);
|
||||
|
||||
switch(offset*4)
|
||||
{
|
||||
case 0x001c: return 0x00000000; // 0x00000040 must not be set or games won't boot
|
||||
//case 0x106c:
|
||||
//case 0x107c:
|
||||
case 0x1084:
|
||||
LOG("%s: HNG64 reading MCU status port (%08x)\n", machine().describe_context(), mem_mask);
|
||||
return 0x00000002; //MCU->MIPS latch port
|
||||
}
|
||||
|
||||
return m_sysregs[offset];
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(hng64_state::hng64_sysregs_w)
|
||||
{
|
||||
COMBINE_DATA (&m_sysregs[offset]);
|
||||
|
||||
if(((offset >> 1) & 0xff0) == 0x420)
|
||||
{
|
||||
m_rtc->write(space, (offset >> 1) & 0xf,data);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(((offset*4) & 0xff00) == 0x1100)
|
||||
printf("HNG64 writing to SYSTEM Registers 0x%08x == 0x%08x. (PC=%08x)\n", offset*4, m_sysregs[offset], m_maincpu->pc());
|
||||
@ -579,47 +676,21 @@ WRITE32_MEMBER(hng64_state::hng64_sysregs_w)
|
||||
m_mcu_en = (data & 0xff); //command-based, i.e. doesn't control halt line and such?
|
||||
LOG("%s: HNG64 writing to MCU control port %08x (%08x)\n", machine().describe_context(), data, mem_mask);
|
||||
break;
|
||||
//0x110c global irq mask?
|
||||
/* irq ack */
|
||||
case 0x111c: m_irq_pending &= ~m_sysregs[offset]; set_irq(0x0000); break;
|
||||
case 0x1204: m_dma_start = m_sysregs[offset]; break;
|
||||
case 0x1214: m_dma_dst = m_sysregs[offset]; break;
|
||||
case 0x1224:
|
||||
m_dma_len = m_sysregs[offset];
|
||||
do_dma(space);
|
||||
break;
|
||||
case 0x21c4:
|
||||
// guess, written after a write to 0x00 in dpram, which is where the command goes, and the IRQ onthe MCU reads the command
|
||||
LOG("%s: HNG64 writing to SYSTEM Registers %08x %08x (%08x) (IO MCU IRQ TRIGGER?)\n", machine().describe_context(), offset*4, data, mem_mask);
|
||||
if (mem_mask & 0xffff0000) m_tempio_irqon_timer->adjust(attotime::zero);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG("%s: HNG64 writing to SYSTEM Registers %08x %08x (%08x)\n", machine().describe_context(), offset*4, data, mem_mask);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************
|
||||
* MCU simulation / hacks
|
||||
**************************************/
|
||||
|
||||
// real IO MCU only has 8 multiplexed 8-bit digital input ports, so some of these fake inputs are probably processed representations of the same thing
|
||||
/**************************************
|
||||
* MIPS side Dual Port RAM hookup for MCU
|
||||
**************************************/
|
||||
|
||||
READ8_MEMBER(hng64_state::hng64_dualport_r)
|
||||
{
|
||||
LOG("%s: dualport R %04x\n", machine().describe_context(), offset);
|
||||
|
||||
/*
|
||||
I'm not really convinced these are commands in this sense based on code analysis, probably just a non-standard way of controlling the lines
|
||||
|
||||
command table:
|
||||
0x0b = ? mode input polling (sams64, bbust2, sams64_2 & roadedge) (*)
|
||||
0x0c = cut down connections, treats the dualport to be normal RAM
|
||||
0x11 = ? mode input polling (fatfurwa, xrally, buriki) (*)
|
||||
0x20 = asks for MCU machine code (probably not, this is also written in the function after the TLCS870 requests an interrupt on the MIPS)
|
||||
|
||||
(*) 0x11 is followed by 0x0b if the latter is used, JVS-esque indirect/direct mode?
|
||||
*/
|
||||
// hack, this should just be put in ram at 0x600 by the MCU.
|
||||
if (!(m_mcu_en == 0x0c))
|
||||
{
|
||||
switch (offset)
|
||||
@ -654,7 +725,8 @@ Beast Busters 2 outputs (all at offset == 0x1c):
|
||||
the MIPS (at least in Fatal Fury) uploads this data to shared RAM prior to the call.
|
||||
|
||||
need to work out what triggers the interrupt, as a write to 0 wouldn't as the Dual Port RAM interrupts
|
||||
are on addresses 0x7fe and 0x7ff
|
||||
are on addresses 0x7fe and 0x7ff (we're using an address near the system regs, based on code analysis
|
||||
it seems correct, see hng64_mips_to_iomcu_irq_w )
|
||||
*/
|
||||
|
||||
WRITE8_MEMBER(hng64_state::hng64_dualport_w)
|
||||
@ -761,14 +833,20 @@ void hng64_state::hng_map(address_map &map)
|
||||
map(0x00000000, 0x00ffffff).ram().share("mainram");
|
||||
map(0x04000000, 0x05ffffff).nopw().rom().region("gameprg", 0).share("cart");
|
||||
|
||||
// Ports
|
||||
map(0x1f700000, 0x1f702fff).rw(FUNC(hng64_state::hng64_sysregs_r), FUNC(hng64_state::hng64_sysregs_w)).share("sysregs");
|
||||
// Misc Peripherals
|
||||
map(0x1f700000, 0x1f7010ff).rw(FUNC(hng64_state::hng64_sysregs_r), FUNC(hng64_state::hng64_sysregs_w)).share("sysregs"); // various things
|
||||
|
||||
map(0x1f701100, 0x1f70111f).rw(FUNC(hng64_state::hng64_irqc_r), FUNC(hng64_state::hng64_irqc_w));
|
||||
map(0x1f701200, 0x1f70127f).rw(FUNC(hng64_state::hng64_dmac_r), FUNC(hng64_state::hng64_dmac_w));
|
||||
// 1f702004 used (rarely writes 01 or a random looking value as part of init sequences)
|
||||
map(0x1f702100, 0x1f70217f).rw(FUNC(hng64_state::hng64_rtc_r), FUNC(hng64_state::hng64_rtc_w));
|
||||
map(0x1f7021c4, 0x1f7021c7).w(FUNC(hng64_state::hng64_mips_to_iomcu_irq_w));
|
||||
|
||||
// SRAM. Coin data, Player Statistics, etc.
|
||||
map(0x1F800000, 0x1F803fff).ram().share("nvram");
|
||||
map(0x1f800000, 0x1f803fff).ram().share("nvram");
|
||||
|
||||
// Dualport RAM (shared with IO MCU)
|
||||
map(0x1F808000, 0x1F8087ff).rw(FUNC(hng64_state::hng64_dualport_r), FUNC(hng64_state::hng64_dualport_w)).umask32(0xffffffff);
|
||||
map(0x1f808000, 0x1f8087ff).rw(FUNC(hng64_state::hng64_dualport_r), FUNC(hng64_state::hng64_dualport_w)).umask32(0xffffffff);
|
||||
|
||||
// BIOS ROM
|
||||
map(0x1fc00000, 0x1fc7ffff).nopw().rom().region("user1", 0).share("rombase");
|
||||
|
@ -277,8 +277,14 @@ private:
|
||||
DECLARE_READ8_MEMBER(hng64_com_share_mips_r);
|
||||
DECLARE_READ32_MEMBER(hng64_sysregs_r);
|
||||
DECLARE_WRITE32_MEMBER(hng64_sysregs_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(fake_io_r);
|
||||
DECLARE_READ32_MEMBER(hng64_rtc_r);
|
||||
DECLARE_WRITE32_MEMBER(hng64_rtc_w);
|
||||
DECLARE_READ32_MEMBER(hng64_dmac_r);
|
||||
DECLARE_WRITE32_MEMBER(hng64_dmac_w);
|
||||
DECLARE_READ32_MEMBER(hng64_irqc_r);
|
||||
DECLARE_WRITE32_MEMBER(hng64_irqc_w);
|
||||
DECLARE_WRITE32_MEMBER(hng64_mips_to_iomcu_irq_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(hng64_dualport_r);
|
||||
DECLARE_WRITE8_MEMBER(hng64_dualport_w);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user