summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Ryan Holtz <rholtz@batcountryentertainment.com>2012-02-19 00:44:19 +0000
committer Ryan Holtz <rholtz@batcountryentertainment.com>2012-02-19 00:44:19 +0000
commita286574bb15f99a7ae9d25e2ad0fbf2852c25f27 (patch)
treeaac6f88cd518861a3a56280d5955658563017df4
parent444ded201654ad9235f879ecb5068fda798b3f8a (diff)
- Assorted N64 SP/DP/CPU comms accuracy fixes. [Ryan Holtz]
-rw-r--r--src/mame/includes/n64.h3
-rw-r--r--src/mame/machine/n64.c87
-rw-r--r--src/mame/video/n64.c19
-rw-r--r--src/mame/video/n64.h10
4 files changed, 84 insertions, 35 deletions
diff --git a/src/mame/includes/n64.h b/src/mame/includes/n64.h
index 454719ed253..cb64c7b25c2 100644
--- a/src/mame/includes/n64.h
+++ b/src/mame/includes/n64.h
@@ -109,6 +109,8 @@ public:
void poll_reset_button(bool button);
+ UINT32 dp_clock;
+
protected:
// device-level overrides
virtual void device_start();
@@ -169,7 +171,6 @@ private:
int sp_dma_count;
int sp_dma_skip;
UINT32 sp_semaphore;
- UINT32 dp_clock;
// Disk Drive (DD) registers and functions
UINT32 dd_buffer[256];
diff --git a/src/mame/machine/n64.c b/src/mame/machine/n64.c
index 148aa7e9fbf..8aed17384c2 100644
--- a/src/mame/machine/n64.c
+++ b/src/mame/machine/n64.c
@@ -204,7 +204,6 @@ void n64_periphs::device_reset()
{
// CIC-NUS-6105
//printf("CIC-NUS-6105 detected\n");
-
pif_ram[0x24] = 0x00;
pif_ram[0x25] = 0x02;
pif_ram[0x26] = 0x91;
@@ -361,10 +360,12 @@ void n64_periphs::check_interrupts()
{
if (mi_intr_mask & mi_interrupt)
{
+ //printf("Asserting IRQ, %02x : %02x\n", mi_intr_mask, mi_interrupt);
cputag_set_input_line(machine(), "maincpu", INPUT_LINE_IRQ0, ASSERT_LINE);
}
else
{
+ //printf("Deasserting IRQ, %02x : %02x\n", mi_intr_mask, mi_interrupt);
cputag_set_input_line(machine(), "maincpu", INPUT_LINE_IRQ0, CLEAR_LINE);
}
}
@@ -485,12 +486,14 @@ WRITE32_MEMBER( n64_periphs::rdram_reg_w )
void n64_periphs::sp_dma(int direction)
{
- sp_dma_length++;
- if ((sp_dma_length & 7) != 0)
+ UINT32 length = sp_dma_length + 1;
+
+ if ((length & 7) != 0)
{
- sp_dma_length = (sp_dma_length + 7) & ~7;
+ length = (length + 7) & ~7;
}
+ //printf("Length %08x Skip %08x Count %08x\n", length, sp_dma_skip, sp_dma_count);
if (sp_mem_addr & 0x3)
{
sp_mem_addr = sp_mem_addr & ~3;
@@ -500,11 +503,11 @@ void n64_periphs::sp_dma(int direction)
sp_dram_addr = sp_dram_addr & ~7;
}
- if ((sp_mem_addr & 0xfff) + (sp_dma_length) > 0x1000)
+ if ((sp_mem_addr & 0xfff) + (length) > 0x1000)
{
- //printf("sp_dma: dma out of memory area: %08X, %08X\n", sp_mem_addr, sp_dma_length);
- //fatalerror("sp_dma: dma out of memory area: %08X, %08X\n", sp_mem_addr, sp_dma_length);
- sp_dma_length = 0x1000 - (sp_mem_addr & 0xfff);
+ //printf("sp_dma: dma out of memory area: %08X, %08X, %08X\n", sp_mem_addr, sp_dram_addr, length);
+ //fatalerror("sp_dma: dma out of memory area: %08X, %08X\n", sp_mem_addr, length);
+ length = 0x1000 - (sp_mem_addr & 0xfff);
}
UINT32 *sp_mem[2] = { rsp_dmem, rsp_imem };
@@ -516,13 +519,13 @@ void n64_periphs::sp_dma(int direction)
UINT32 src = (sp_dram_addr & 0x007fffff) >> 2;
UINT32 dst = (sp_mem_addr & 0x1fff) >> 2;
- for(int i = 0; i < sp_dma_length / 4; i++)
+ for(int i = 0; i < length / 4; i++)
{
sp_mem[(dst + i) >> 10][(dst + i) & 0x3ff] = rdram[src + i];
}
- sp_mem_addr += sp_dma_length;
- sp_dram_addr += sp_dma_length;
+ sp_mem_addr += length;
+ sp_dram_addr += length;
sp_mem_addr += sp_dma_skip;
}
@@ -534,13 +537,13 @@ void n64_periphs::sp_dma(int direction)
UINT32 src = (sp_mem_addr & 0x1fff) >> 2;
UINT32 dst = (sp_dram_addr & 0x007fffff) >> 2;
- for(int i = 0; i < sp_dma_length / 4; i++)
+ for(int i = 0; i < length / 4; i++)
{
rdram[dst + i] = sp_mem[(src + i) >> 10][(src + i) & 0x3ff];
}
- sp_mem_addr += sp_dma_length;
- sp_dram_addr += sp_dma_length;
+ sp_mem_addr += length;
+ sp_dram_addr += length;
sp_dram_addr += sp_dma_skip;
}
@@ -617,20 +620,47 @@ UINT32 n64_periphs::sp_reg_r(UINT32 offset)
break;
case 0x20/4: // DP_CMD_START
+ {
+ n64_state *state = machine().driver_data<n64_state>();
+ ret = state->m_rdp->GetStartReg();
+ break;
+ }
+
case 0x24/4: // DP_CMD_END
+ {
+ n64_state *state = machine().driver_data<n64_state>();
+ ret = state->m_rdp->GetEndReg();
+ break;
+ }
+
case 0x28/4: // DP_CMD_CURRENT
+ {
+ n64_state *state = machine().driver_data<n64_state>();
+ ret = state->m_rdp->GetCurrentReg();
+ break;
+ }
+
case 0x34/4: // DP_CMD_BUSY
case 0x38/4: // DP_CMD_PIPE_BUSY
case 0x3c/4: // DP_CMD_TMEM_BUSY
break;
case 0x2c/4: // DP_CMD_STATUS
- ret = 0x88;
+ {
+ n64_state *state = machine().driver_data<n64_state>();
+ ret = state->m_rdp->GetStatusReg();
break;
+ }
case 0x30/4: // DP_CMD_CLOCK
- ret = ++dp_clock;
+ {
+ if(!(machine().driver_data<n64_state>()->m_rdp->GetStatusReg() & DP_STATUS_FREEZE))
+ {
+ dp_clock += 13;
+ ret = dp_clock;
+ }
break;
+ }
case 0x40000/4: // PC
ret = cpu_get_reg(rspcpu, RSP_PC) & 0x00000fff;
@@ -641,7 +671,7 @@ UINT32 n64_periphs::sp_reg_r(UINT32 offset)
break;
}
- //printf("sp_reg_r %08x = %08x\n", offset * 4, ret);
+ //printf("%08x sp_reg_r %08x = %08x\n", (UINT32)cpu_get_reg(maincpu, MIPS3_PC), offset * 4, ret);
return ret;
}
@@ -652,8 +682,7 @@ READ32_DEVICE_HANDLER( n64_sp_reg_r )
void n64_periphs::sp_reg_w(UINT32 offset, UINT32 data, UINT32 mem_mask)
{
- //printf("sp_reg_w %08x %08x %08x\n", offset * 4, data, mem_mask);
- //device_yield(machine().device("maincpu"));
+ //printf("%08x sp_reg_w %08x %08x %08x\n", (UINT32)cpu_get_reg(maincpu, MIPS3_PC), offset * 4, data, mem_mask);
if ((offset & 0x10000) == 0)
{
@@ -719,6 +748,7 @@ void n64_periphs::sp_reg_w(UINT32 offset, UINT32 data, UINT32 mem_mask)
if(!(oldstatus & (RSP_STATUS_BROKE | RSP_STATUS_HALT)))
{
cpu_set_reg(rspcpu, RSP_STEPCNT, 1 );
+ device_yield(machine().device("maincpu"));
}
}
if (data & 0x00000080)
@@ -847,6 +877,7 @@ void dp_full_sync(running_machine &machine)
READ32_DEVICE_HANDLER( n64_dp_reg_r )
{
n64_state *state = device->machine().driver_data<n64_state>();
+ n64_periphs *periphs = device->machine().device<n64_periphs>("rcp");
UINT32 ret = 0;
switch (offset)
{
@@ -866,20 +897,31 @@ READ32_DEVICE_HANDLER( n64_dp_reg_r )
ret = state->m_rdp->GetStatusReg();
break;
+ case 0x10/4: // DP_CLOCK_REG
+ {
+ if(!(state->m_rdp->GetStatusReg() & DP_STATUS_FREEZE))
+ {
+ periphs->dp_clock += 13;
+ ret = periphs->dp_clock;
+ }
+ break;
+ }
+
default:
logerror("dp_reg_r: %08X, %08X at %08X\n", offset, mem_mask, cpu_get_pc(device));
break;
}
- //printf("dp_reg_r %08x = %08x\n", offset, ret);
+ //printf("%08x dp_reg_r %08x = %08x\n", (UINT32)cpu_get_reg(device->machine().device("rsp"), RSP_PC), offset, ret);
return ret;
}
WRITE32_DEVICE_HANDLER( n64_dp_reg_w )
{
n64_state *state = device->machine().driver_data<n64_state>();
+ n64_periphs *periphs = device->machine().device<n64_periphs>("rcp");
- //printf("dp_reg_w %08x %08x %08x\n", offset, data, mem_mask);
+ //printf("%08x dp_reg_w %08x %08x %08x\n", (UINT32)cpu_get_reg(device->machine().device("rsp"), RSP_PC), offset, data, mem_mask);
switch (offset)
{
case 0x00/4: // DP_START_REG
@@ -903,7 +945,8 @@ WRITE32_DEVICE_HANDLER( n64_dp_reg_w )
if (data & 0x00000004) current_status &= ~DP_STATUS_FREEZE;
if (data & 0x00000008) current_status |= DP_STATUS_FREEZE;
if (data & 0x00000010) current_status &= ~DP_STATUS_FLUSH;
- if (data & 0x00000020) current_status |= DP_STATUS_FLUSH;
+ if (data & 0x00000020) current_status |= DP_STATUS_FLUSH;
+ if (data & 0x00000200) periphs->dp_clock = 0;
state->m_rdp->SetStatusReg(current_status);
break;
}
diff --git a/src/mame/video/n64.c b/src/mame/video/n64.c
index 22813baccd3..ffcd01c477b 100644
--- a/src/mame/video/n64.c
+++ b/src/mame/video/n64.c
@@ -1169,6 +1169,7 @@ UINT32 n64_rdp::ReadData(UINT32 address)
{
if (m_status & 0x1) // XBUS_DMEM_DMA enabled
{
+ //printf("%08x\n", rsp_dmem[(address & 0xfff) / 4]);
return rsp_dmem[(address & 0xfff) / 4];
}
else
@@ -3579,9 +3580,14 @@ void n64_rdp::CmdNoOp(UINT32 w1, UINT32 w2)
void n64_rdp::ProcessList()
{
- UINT32 length = m_end - m_current;
+ INT32 length = m_end - m_current;
+
+ if(length < 0)
+ {
+ m_current = m_end;
+ return;
+ }
- //printf("%08x %d\n", m_end, length);
// load command data
for(int i = 0; i < length; i += 4)
{
@@ -3861,14 +3867,7 @@ SCREEN_UPDATE_RGB32(n64)
if (n64->vi_blank)
{
- for (int j = 0; j < state->m_rdp->visarea.max_y; j++)
- {
- UINT32 *d = &bitmap.pix32(j);
- for (int i = 0; i < state->m_rdp->MiscState.FBWidth; i++)
- {
- d[BYTE_XOR_BE(i)] = 0;
- }
- }
+ bitmap.fill(0, state->m_rdp->visarea);
return 0;
}
diff --git a/src/mame/video/n64.h b/src/mame/video/n64.h
index c2956a9eca9..d56ab66dd55 100644
--- a/src/mame/video/n64.h
+++ b/src/mame/video/n64.h
@@ -437,10 +437,16 @@ class n64_rdp : public poly_manager<UINT32, rdp_poly_state, 8, 32000>
void SetMachine(running_machine& machine) { m_machine = &machine; }
// CPU-visible registers
- void SetStartReg(UINT32 val) { m_start = val; }
+ void SetStartReg(UINT32 val)
+ {
+ m_start = val;
+ }
UINT32 GetStartReg() const { return m_start; }
- void SetEndReg(UINT32 val) { m_end = val; }
+ void SetEndReg(UINT32 val)
+ {
+ m_end = val;
+ }
UINT32 GetEndReg() const { return m_end; }
void SetCurrentReg(UINT32 val) { m_current = val; }