summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/n64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/n64.cpp')
-rw-r--r--src/mame/machine/n64.cpp81
1 files changed, 48 insertions, 33 deletions
diff --git a/src/mame/machine/n64.cpp b/src/mame/machine/n64.cpp
index 1db37e4fe72..376a3b6162f 100644
--- a/src/mame/machine/n64.cpp
+++ b/src/mame/machine/n64.cpp
@@ -22,6 +22,8 @@ n64_periphs::n64_periphs(const machine_config &mconfig, const char *tag, device_
, cart_present(false)
, m_vr4300(*this, "^maincpu")
, m_rsp(*this, "^rsp")
+ , m_rsp_imem(*this, "^rsp_imem")
+ , m_rsp_dmem(*this, "^rsp_dmem")
, ai_dac(*this, "^dac%u", 1U)
{
for (int32_t i = 0; i < 256; i++)
@@ -130,8 +132,6 @@ void n64_periphs::device_reset()
m_mem_map = &m_vr4300->space(AS_PROGRAM);
m_rdram = m_n64->rdram();
- m_rsp_imem = m_n64->rsp_imem();
- m_rsp_dmem = m_n64->rsp_dmem();
m_sram = m_n64->sram();
mi_version = 0x01010101;
@@ -141,6 +141,8 @@ void n64_periphs::device_reset()
sp_mem_addr = 0;
sp_dram_addr = 0;
+ sp_mem_addr_start = 0;
+ sp_dram_addr_start = 0;
sp_dma_length = 0;
sp_dma_count = 0;
sp_dma_skip = 0;
@@ -546,6 +548,9 @@ void n64_periphs::rdram_reg_w(offs_t offset, uint32_t data, uint32_t mem_mask)
void n64_periphs::sp_dma(int direction)
{
+ sp_mem_addr = sp_mem_addr_start;
+ sp_dram_addr = sp_dram_addr_start;
+
uint32_t length = sp_dma_length + 1;
if ((length & 7) != 0)
@@ -571,17 +576,16 @@ void n64_periphs::sp_dma(int direction)
int sp_mem_page = (sp_mem_addr >> 12) & 1;
- if(sp_mem_page == 1)
- m_rsp->rspdrc_flush_drc_cache();
+ //printf("DMA %s RSP: mem %08x, dram %08x, sp_dma_length: %03x, length: %04x, count: %02x, skip: %03x\n", direction ? "from" : "to", sp_mem_addr, sp_dram_addr, sp_dma_length, length, sp_dma_count, sp_dma_skip);
- if(direction == 0)// RDRAM -> I/DMEM
+ if (direction == 0)// RDRAM -> I/DMEM
{
- for(int c = 0; c <= sp_dma_count; c++)
+ for (int c = 0; c <= sp_dma_count; c++)
{
- uint32_t src = (sp_dram_addr & 0x007fffff) >> 2;
+ uint32_t src = sp_dram_addr >> 2;
uint32_t dst = (sp_mem_addr & 0xfff) >> 2;
- for(int i = 0; i < length / 4; i++)
+ for (int i = 0; i < length / 4; i++)
{
sp_mem[sp_mem_page][(dst + i) & 0x3ff] = m_rdram[src + i];
}
@@ -589,17 +593,18 @@ void n64_periphs::sp_dma(int direction)
sp_mem_addr += length;
sp_dram_addr += length;
- sp_dram_addr += sp_dma_skip;
+ if (c != sp_dma_count)
+ sp_dram_addr += sp_dma_skip;
}
}
else // I/DMEM -> RDRAM
{
- for(int c = 0; c <= sp_dma_count; c++)
+ for (int c = 0; c <= sp_dma_count; c++)
{
uint32_t src = (sp_mem_addr & 0xfff) >> 2;
- uint32_t dst = (sp_dram_addr & 0x007fffff) >> 2;
+ uint32_t dst = sp_dram_addr >> 2;
- for(int i = 0; i < length / 4; i++)
+ for (int i = 0; i < length / 4; i++)
{
m_rdram[dst + i] = sp_mem[sp_mem_page][(src + i) & 0x3ff];
}
@@ -607,9 +612,13 @@ void n64_periphs::sp_dma(int direction)
sp_mem_addr += length;
sp_dram_addr += length;
- sp_dram_addr += sp_dma_skip;
+ if (c != sp_dma_count)
+ sp_dram_addr += sp_dma_skip;
}
}
+
+ sp_dma_count = 0;
+ sp_dma_length = 0xff8;
}
void n64_periphs::sp_set_status(uint32_t data)
@@ -642,6 +651,7 @@ uint32_t n64_periphs::sp_reg_r(offs_t offset)
return sp_dram_addr;
case 0x08/4: // SP_RD_LEN_REG
+ case 0x0c/4: // SP_WR_LEN_REG
return (sp_dma_skip << 20) | (sp_dma_count << 12) | sp_dma_length;
case 0x10/4: // SP_STATUS_REG
@@ -710,24 +720,24 @@ void n64_periphs::sp_reg_w(offs_t offset, uint32_t data, uint32_t mem_mask)
switch (offset & 0xffff)
{
case 0x00/4: // SP_MEM_ADDR_REG
- sp_mem_addr = data;
+ sp_mem_addr_start = data & 0x00001fff;
break;
case 0x04/4: // SP_DRAM_ADDR_REG
- sp_dram_addr = data & 0xffffff;
+ sp_dram_addr_start = data & 0x007fffff;
break;
case 0x08/4: // SP_RD_LEN_REG
sp_dma_length = data & 0xfff;
sp_dma_count = (data >> 12) & 0xff;
- sp_dma_skip = (data >> 20) & 0xfff;
+ sp_dma_skip = (data >> 20) & 0xff8;
sp_dma(0);
break;
case 0x0c/4: // SP_WR_LEN_REG
sp_dma_length = data & 0xfff;
sp_dma_count = (data >> 12) & 0xff;
- sp_dma_skip = (data >> 20) & 0xfff;
+ sp_dma_skip = (data >> 20) & 0xff8;
sp_dma(1);
break;
@@ -864,13 +874,13 @@ void n64_periphs::sp_reg_w(offs_t offset, uint32_t data, uint32_t mem_mask)
switch (offset & 0xffff)
{
case 0x00/4: // SP_PC_REG
- if( m_rsp->state_int(RSP_NEXTPC) != 0xffffffff )
+ if (m_rsp->state_int(RSP_NEXTPC) != 0xffff)
{
- m_rsp->set_state_int(RSP_NEXTPC, 0x1000 | (data & 0xfff));
+ m_rsp->set_state_int(RSP_NEXTPC, data & 0xfff);
}
else
{
- m_rsp->set_state_int(RSP_PC, 0x1000 | (data & 0xfff));
+ m_rsp->set_state_int(RSP_PC, data & 0xfff);
}
break;
@@ -998,8 +1008,10 @@ void n64_periphs::vi_recalculate_resolution()
int x_end = vi_hstart & 0x000003ff;
int y_start = ((vi_vstart & 0x03ff0000) >> 16) >> 1;
int y_end = (vi_vstart & 0x000003ff) >> 1;
- int width = x_end - x_start;
- int height = y_end - y_start;
+ const float hcoeff = ((float)(vi_xscale & 0xfff) / (1 << 10));
+ const float vcoeff = ((float)(vi_yscale & 0xfff) / (1 << 10));
+ int width = (x_end - x_start) * hcoeff;
+ int height = (y_end - y_start) * vcoeff;
rectangle visarea = screen().visible_area();
// DACRATE is the quarter pixel clock and period will be for a field, not a frame
@@ -1494,6 +1506,14 @@ uint32_t n64_periphs::pi_reg_r(offs_t offset, uint32_t mem_mask)
ret = pi_cart_addr;
break;
+ case 0x08/4: // PI_RD_LEN_REG
+ ret = pi_rd_len;
+ break;
+
+ case 0x0c/4: // PI_WR_LEN_REG
+ ret = pi_wr_len;
+ break;
+
case 0x10/4: // PI_STATUS_REG
ret = pi_status;
break;
@@ -1543,13 +1563,10 @@ void n64_periphs::pi_reg_w(offs_t offset, uint32_t data, uint32_t mem_mask)
switch (offset)
{
case 0x00/4: // PI_DRAM_ADDR_REG
- {
pi_dram_addr = data;
break;
- }
case 0x04/4: // PI_CART_ADDR_REG
- {
pi_cart_addr = data;
if(pi_cart_addr == 0x05000400 && dd_present)
{
@@ -1566,15 +1583,15 @@ void n64_periphs::pi_reg_w(offs_t offset, uint32_t data, uint32_t mem_mask)
m_vr4300->set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE);
}
break;
- }
case 0x08/4: // PI_RD_LEN_REG
{
+ //printf("pi_rd_len_reg: %08x\n", data);
//logerror("Start PI Read\n");
pi_rd_len = data;
pi_dma_dir = 0;
pi_status |= 1;
-
+ //pi_dma_tick();
attotime dma_period = attotime::from_hz(93750000) * (int)((float)(pi_rd_len + 1) * 5.08f); // Measured as between 2.53 cycles per byte and 2.55 cycles per byte
pi_dma_timer->adjust(dma_period);
break;
@@ -1582,11 +1599,12 @@ void n64_periphs::pi_reg_w(offs_t offset, uint32_t data, uint32_t mem_mask)
case 0x0c/4: // PI_WR_LEN_REG
{
+ //printf("pi_wr_len_reg: %08x\n", data);
//logerror("Start PI Write\n");
pi_wr_len = data;
pi_dma_dir = 1;
pi_status |= 1;
-
+ //pi_dma_tick();
attotime dma_period = attotime::from_hz(93750000) * (int)((float)(pi_wr_len + 1) * 5.08f); // Measured as between 2.53 cycles per byte and 2.55 cycles per byte
pi_dma_timer->adjust(dma_period);
break;
@@ -1762,6 +1780,7 @@ int n64_periphs::pif_channel_handle_command(int channel, int slength, uint8_t *s
}
case 4:
{
+ //printf("Read EEPROM status, type: %02x\n", (machine().root_device().ioport("input")->read() >> 8) & 0xC0);
// Read EEPROM status
rdata[0] = 0x00;
rdata[1] = (machine().root_device().ioport("input")->read() >> 8) & 0xC0;
@@ -1928,6 +1947,7 @@ int n64_periphs::pif_channel_handle_command(int channel, int slength, uint8_t *s
case 0x04: // Read from EEPROM
{
+ //printf("Read from EEPROM, channel %d: slength %d, rlength %d, sdata[1] %02x\n", channel, slength, rlength, sdata[1]);
if (channel != 4)
{
return 1;
@@ -2752,11 +2772,6 @@ void n64_state::machine_start()
/* configure fast RAM regions */
//m_vr4300->add_fastram(0x00000000, 0x007fffff, false, m_rdram);
- m_rsp->rspdrc_set_options(RSPDRC_STRICT_VERIFY);
- m_rsp->rspdrc_flush_drc_cache();
- m_rsp->rsp_add_dmem(m_rsp_dmem);
- m_rsp->rsp_add_imem(m_rsp_imem);
-
/* add a hook for battery save */
machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&n64_state::n64_machine_stop,this));
}