From 7fe8f9f74c8a8aca5e0ca949dafcac13504c3013 Mon Sep 17 00:00:00 2001 From: MooglyGuy Date: Tue, 10 Aug 2021 03:06:08 +0200 Subject: Assorted N64 fixes (#8415) * -rdp: Fixed incorrect channel swapping on 32-bit resampled framebuffers. [Ryan Holtz] * -rsp: Fixed LWV and VMOV behavior. Added reserved instructions V056, V057, V073, and VNULL. [Ryan Holtz, krom] * -rdp: Temporarily adjusted framebuffer resampling to not exceed screen bounds in some games. [Ryan Holtz] * -n64: Fixed SP DMA behavior based on hardware tests. [Ryan Holtz] * -rsp: Removed unused DRC and SIMD support. General code cleanup. [Ryan Holtz] * -n64: Pass K4 and K5 factors to threaded drawing code. Fixes black geometry in Conker's Bad Fur Day. [Ryan Holtz] * -aleck64: Fixed compile issue with previous commits. [Ryan Holtz] --- src/mame/machine/n64.cpp | 81 ++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 33 deletions(-) (limited to 'src/mame/machine') 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)); } -- cgit v1.2.3