- Various N64 stability fixes. [Ryan Holtz]

This commit is contained in:
Ryan Holtz 2012-02-13 16:12:01 +00:00
parent b03f10bd40
commit f91cdc62dc
5 changed files with 45 additions and 16 deletions

View File

@ -800,18 +800,12 @@ static const mips3_config vr4300_config =
62500000 /* system clock */
};
static INTERRUPT_GEN( n64_vblank )
{
signal_rcp_interrupt(device->machine(), VI_INTERRUPT);
}
static MACHINE_CONFIG_START( aleck64, n64_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", VR4300BE, 93750000)
MCFG_CPU_CONFIG(vr4300_config)
MCFG_CPU_PROGRAM_MAP(n64_map)
MCFG_CPU_VBLANK_INT("screen", n64_vblank)
MCFG_CPU_ADD("rsp", RSP, 62500000)
MCFG_CPU_CONFIG(n64_rsp_config)

View File

@ -69,6 +69,7 @@ public:
void ai_timer_tick();
void pi_dma_tick();
void vi_scanline_tick();
// Video Interface (VI) registers
UINT32 vi_width;
@ -100,6 +101,9 @@ private:
UINT8 is64_buffer[0x10000];
// Video interface (VI) registers and functions
emu_timer *vi_scanline_timer;
// Audio Interface (AI) registers and functions
void ai_dma();
AUDIO_DMA *ai_fifo_get_top();
@ -224,6 +228,7 @@ extern SCREEN_UPDATE_RGB32( n64 );
extern const rsp_config n64_rsp_config;
extern UINT32 *n64_sram;
extern UINT32 *rdram;
extern UINT32 *rsp_imem;
extern UINT32 *rsp_dmem;

View File

@ -8,6 +8,7 @@
#include "video/n64.h"
#include "profiler.h"
UINT32 *n64_sram;
UINT32 *rdram;
UINT32 *rsp_imem;
UINT32 *rsp_dmem;
@ -17,6 +18,7 @@ const device_type N64PERIPH = &device_creator<n64_periphs>;
static TIMER_CALLBACK(ai_timer_callback);
static TIMER_CALLBACK(pi_dma_callback);
static TIMER_CALLBACK(vi_scanline_callback);
n64_periphs::n64_periphs(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, N64PERIPH, "N64 Periphal Chips", tag, owner, clock)
@ -28,6 +30,7 @@ void n64_periphs::device_start()
{
ai_timer = machine().scheduler().timer_alloc(FUNC(ai_timer_callback));
pi_dma_timer = machine().scheduler().timer_alloc(FUNC(pi_dma_callback));
vi_scanline_timer = machine().scheduler().timer_alloc(FUNC(vi_scanline_callback));
}
void n64_periphs::device_reset()
@ -309,7 +312,7 @@ void n64_periphs::clear_rcp_interrupt(int interrupt)
{
mi_interrupt &= ~interrupt;
//if (!mi_interrupt)
if (!mi_interrupt)
{
cputag_set_input_line(machine(), "maincpu", INPUT_LINE_IRQ0, CLEAR_LINE);
}
@ -486,6 +489,7 @@ static void sp_set_status(device_t *device, UINT32 status)
void n64_periphs::sp_set_status(UINT32 status)
{
//printf("sp_set_status: %08x\n", status);
if (status & 0x1)
{
device_set_input_line(rspcpu, INPUT_LINE_HALT, ASSERT_LINE);
@ -798,6 +802,7 @@ WRITE32_DEVICE_HANDLER( n64_dp_reg_w )
break;
case 0x04/4: // DP_END_REG
//printf("dp_end_reg %08x\n", data);
state->m_rdp->SetEndReg(data);
g_profiler.start(PROFILER_USER1);
state->m_rdp->ProcessList();
@ -833,6 +838,16 @@ const rsp_config n64_rsp_config =
sp_set_status
};
static TIMER_CALLBACK(vi_scanline_callback)
{
machine.device<n64_periphs>("rcp")->vi_scanline_tick();
}
void n64_periphs::vi_scanline_tick()
{
signal_rcp_interrupt(VI_INTERRUPT);
vi_scanline_timer->adjust(machine().primary_screen->time_until_pos(vi_intr >> 1));
}
// Video Interface
void n64_periphs::vi_recalculate_resolution()
@ -845,6 +860,7 @@ void n64_periphs::vi_recalculate_resolution()
int y_end = (vi_vstart & 0x000003ff) / 2;
int width = ((vi_xscale & 0x00000fff) * (x_end - x_start)) / 0x400;
int height = ((vi_yscale & 0x00000fff) * (y_end - y_start)) / 0x400;
//printf("%04x | %02x | ", vi_xscale >> 16, vi_burst & 0x000000ff);
rectangle visarea = machine().primary_screen->visible_area();
attoseconds_t period = machine().primary_screen->frame_period().attoseconds;
@ -872,6 +888,7 @@ void n64_periphs::vi_recalculate_resolution()
visarea.max_x = width - 1;
visarea.max_y = height - 1;
//printf("Reconfig %d, %d (%d - %d), %08x, %08x, %08x, %08x, %08x\n", width, height, x_start, x_end, vi_width, vi_xscale, vi_hsync, vi_hstart, vi_burst);
machine().primary_screen->configure(width, 525, visarea, period);
}
@ -893,7 +910,7 @@ READ32_MEMBER( n64_periphs::vi_reg_r )
return vi_intr;
case 0x10/4: // VI_CURRENT_REG
return machine().primary_screen->vpos();
return machine().primary_screen->vpos() << 1;
case 0x14/4: // VI_BURST_REG
return vi_burst;
@ -956,6 +973,7 @@ WRITE32_MEMBER( n64_periphs::vi_reg_w )
case 0x0c/4: // VI_INTR_REG
vi_intr = data;
vi_scanline_timer->adjust(machine().primary_screen->time_until_pos(vi_intr >> 1));
break;
case 0x10/4: // VI_CURRENT_REG
@ -1098,7 +1116,7 @@ void n64_periphs::ai_dma()
ram = &ram[current->address/2];
// mame_printf_debug("DACDMA: %x for %x bytes\n", current->address, current->length);
//mame_printf_debug("DACDMA: %x for %x bytes\n", current->address, current->length);
dmadac_transfer(&ai_dac[0], 2, 1, 2, current->length/4, ram);
@ -1213,17 +1231,25 @@ void n64_periphs::pi_dma_tick()
UINT16 *cart16 = (UINT16*)machine().region("user2")->base();
UINT16 *dram16 = (UINT16*)rdram;
//printf("%08x Cart, %08x Dram\n", pi_cart_addr, pi_dram_addr);
UINT32 cart_addr = (pi_cart_addr & 0x0fffffff) >> 1;
UINT32 dram_addr = (pi_dram_addr & 0x007fffff) >> 1;
if(cart_addr & 0x04000000)
{
cart16 = (UINT16*)n64_sram;
cart_addr = (pi_cart_addr & 0x00007fff) >> 1;
}
cart_addr &= ((machine().region("user2")->bytes() >> 1) - 1);
if(pi_dma_dir == 1)
{
UINT32 dma_length = pi_wr_len + 1;
if (dma_length & 3)
if (dma_length & 7)
{
dma_length = (dma_length + 3) & ~3;
dma_length = (dma_length + 7) & ~7;
}
if (pi_dram_addr != 0xffffffff)
@ -1248,9 +1274,9 @@ void n64_periphs::pi_dma_tick()
else
{
UINT32 dma_length = pi_rd_len + 1;
if (dma_length & 3)
if (dma_length & 7)
{
dma_length = (dma_length + 3) & ~3;
dma_length = (dma_length + 7) & ~7;
}
if (pi_dram_addr != 0xffffffff)
@ -1344,6 +1370,7 @@ WRITE32_MEMBER( n64_periphs::pi_reg_w )
attotime dma_period = attotime::from_hz(93750000) * (pi_rd_len + 1) * 3;
//printf("want read dma in %d\n", (pi_rd_len + 1));
pi_dma_timer->adjust(dma_period);
//pi_dma_tick();
break;
}
@ -1356,6 +1383,7 @@ WRITE32_MEMBER( n64_periphs::pi_reg_w )
attotime dma_period = attotime::from_hz(93750000) * (pi_wr_len + 1) * 3;
//printf("want write dma in %d\n", (pi_wr_len + 1));
pi_dma_timer->adjust(dma_period);
//pi_dma_tick();
break;
}

View File

@ -97,6 +97,7 @@ void n64_rdp::VideoUpdate16(n64_periphs *n64, bitmap_rgb32 &bitmap)
UINT32 hres = ((float)hdiff * hcoeff);
INT32 invisiblewidth = n64->vi_width - hres;
//printf("%d, %f, %d, %d\n", hdiff, hcoeff, hres, invisiblewidth);
INT32 vdiff = ((n64->vi_vstart & 0x3ff) - ((n64->vi_vstart >> 16) & 0x3ff)) >> 1;
float vcoeff = ((float)(n64->vi_yscale & 0xfff) / (1 << 10));
UINT32 vres = ((float)vdiff * vcoeff);
@ -2006,7 +2007,7 @@ void n64_rdp::DrawTriangle(bool shade, bool texture, bool zbuffer, bool rect)
int dzdy_dz = (dzdy >> 16) & 0xffff;
int dzdx_dz = (dzdx >> 16) & 0xffff;
extent_t Spans[512];
extent_t Spans[1024];
SpanBase.m_span_drdy = drdy;
SpanBase.m_span_dgdy = dgdy;
@ -3528,6 +3529,7 @@ void n64_rdp::ProcessList()
{
UINT32 length = m_end - m_current;
//printf("%08x %d\n", m_end, length);
// load command data
for(int i = 0; i < length; i += 4)
{
@ -3805,6 +3807,7 @@ SCREEN_UPDATE_RGB32(n64)
}
*/
state->m_rdp->wait();
state->m_rdp->AuxBufPtr[state->m_rdp->AuxBufIndex] = 0;
state->m_rdp->AuxBufIndex ^= 1;
@ -3821,7 +3824,6 @@ SCREEN_UPDATE_RGB32(n64)
return 0;
}
state->m_rdp->wait();
state->m_rdp->VideoUpdate(n64, bitmap);
return 0;

View File

@ -93,7 +93,7 @@
#define RDP_CVG_SPAN_MAX (1024)
#define EXTENT_AUX_COUNT (sizeof(rdp_span_aux)*(480*128)) // Screen coverage *128, more or less
#define EXTENT_AUX_COUNT (sizeof(rdp_span_aux)*(480*256)) // Screen coverage *128, more or less
/*****************************************************************************/