mirror of
https://github.com/holub/mame
synced 2025-06-01 18:41:47 +03:00
- Various N64 stability fixes. [Ryan Holtz]
This commit is contained in:
parent
b03f10bd40
commit
f91cdc62dc
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user