summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Ryan Holtz <rholtz@batcountryentertainment.com>2012-02-16 22:10:34 +0000
committer Ryan Holtz <rholtz@batcountryentertainment.com>2012-02-16 22:10:34 +0000
commit9812116f2b114e9390b994bcb893f7be4969c162 (patch)
tree2371b9a32cd2471f36d7654b18fcfd3816907969
parente055a551c19a2f5e67472faaf16e1131fa36a6ce (diff)
- Fixed an issue with text being missing in some Aleck 64 games. [Ryan Holtz]
- Reduced memory usage in the N64 driver. [Ryan Holtz]
-rw-r--r--src/mame/includes/n64.h7
-rw-r--r--src/mame/machine/n64.c305
-rw-r--r--src/mame/video/n64.c164
-rw-r--r--src/mame/video/n64.h50
-rw-r--r--src/mame/video/rdptpipe.c2
5 files changed, 353 insertions, 175 deletions
diff --git a/src/mame/includes/n64.h b/src/mame/includes/n64.h
index 27bfda10baa..8ec079e1f39 100644
--- a/src/mame/includes/n64.h
+++ b/src/mame/includes/n64.h
@@ -65,6 +65,8 @@ public:
DECLARE_WRITE32_MEMBER( ri_reg_w );
DECLARE_READ32_MEMBER( si_reg_r );
DECLARE_WRITE32_MEMBER( si_reg_w );
+ DECLARE_READ32_MEMBER( dd_reg_r );
+ DECLARE_WRITE32_MEMBER( dd_reg_w );
DECLARE_READ32_MEMBER( pif_ram_r );
DECLARE_WRITE32_MEMBER( pif_ram_w );
@@ -73,6 +75,7 @@ public:
void sp_set_status(UINT32 status);
void signal_rcp_interrupt(int interrupt);
+ void check_interrupts();
void ai_timer_tick();
void pi_dma_tick();
@@ -99,6 +102,10 @@ public:
n64_savable_data_t m_save_data;
+ UINT32 cart_length;
+
+ bool dd_present;
+
protected:
// device-level overrides
virtual void device_start();
diff --git a/src/mame/machine/n64.c b/src/mame/machine/n64.c
index e084338c797..1b3ce38bf20 100644
--- a/src/mame/machine/n64.c
+++ b/src/mame/machine/n64.c
@@ -41,7 +41,7 @@ void n64_periphs::device_reset()
rspcpu = machine().device("rsp");
mem_map = maincpu->memory().space(AS_PROGRAM);
- mi_version = 0;
+ mi_version = 0x02020102;
mi_interrupt = 0;
mi_intr_mask = 0;
mi_mode = 0;
@@ -115,21 +115,26 @@ void n64_periphs::device_reset()
boot_checksum += cart[i/4]+i;
}
- if (boot_checksum == U64(0x000000d057e84864))
- {
- // CIC-NUS-6101
- printf("CIC-NUS-6102 detected\n");
- pif_ram[0x24] = 0x00;
- pif_ram[0x25] = 0x02;
- pif_ram[0x26] = 0x3f;
- pif_ram[0x27] = 0x3f;
- // crc_seed = 0x3f;
- }
+ // CIC-NUS-6102 (default)
+ pif_ram[0x24] = 0x00;
+ pif_ram[0x25] = 0x02;
+ pif_ram[0x26] = 0x3f;
+ pif_ram[0x27] = 0x3f;
+ dd_present = false;
+
+ if (boot_checksum == U64(0x00000000001ff230))
+ {
+ //printf("64DD detected\n");
+ pif_ram[0x24] = 0x00;
+ pif_ram[0x25] = 0x0a;
+ pif_ram[0x26] = 0xdd; // How utterly predictable
+ pif_ram[0x27] = 0x3f;
+ dd_present = true;
+ }
else if (boot_checksum == U64(0x000000cffb830843) || boot_checksum == U64(0x000000d0027fdf31))
{
- // CIC-NUS-6103
- printf("CIC-NUS-6101 detected\n");
- // crc_seed = 0x78;
+ // CIC-NUS-6101
+ //printf("CIC-NUS-6101 detected\n");
pif_ram[0x24] = 0x00;
pif_ram[0x25] = 0x06;
pif_ram[0x26] = 0x3f;
@@ -138,8 +143,7 @@ void n64_periphs::device_reset()
else if (boot_checksum == U64(0x000000d6499e376b))
{
// CIC-NUS-6103
- printf("CIC-NUS-6103 detected\n");
- // crc_seed = 0x78;
+ //printf("CIC-NUS-6103 detected\n");
pif_ram[0x24] = 0x00;
pif_ram[0x25] = 0x02;
pif_ram[0x26] = 0x78;
@@ -148,10 +152,8 @@ void n64_periphs::device_reset()
else if (boot_checksum == U64(0x0000011a4a1604b6))
{
// CIC-NUS-6105
- printf("CIC-NUS-6105 detected\n");
- // crc_seed = 0x91;
+ //printf("CIC-NUS-6105 detected\n");
- // first_rsp = 0;
pif_ram[0x24] = 0x00;
pif_ram[0x25] = 0x02;
pif_ram[0x26] = 0x91;
@@ -160,8 +162,7 @@ void n64_periphs::device_reset()
else if (boot_checksum == U64(0x000000d6d5de4ba0))
{
// CIC-NUS-6106
- printf("CIC-NUS-6106 detected\n");
- // crc_seed = 0x85;
+ //printf("CIC-NUS-6106 detected\n");
pif_ram[0x24] = 0x00;
pif_ram[0x25] = 0x02;
pif_ram[0x26] = 0x85;
@@ -169,7 +170,7 @@ void n64_periphs::device_reset()
}
else
{
- printf("Unknown BootCode Checksum %08X%08X\n", (UINT32)(boot_checksum>>32),(UINT32)(boot_checksum));
+ //printf("Unknown BootCode Checksum %08X%08X\n", (UINT32)(boot_checksum>>32),(UINT32)(boot_checksum));
}
}
@@ -188,27 +189,32 @@ void n64_periphs::device_reset()
READ32_MEMBER( n64_periphs::mi_reg_r )
{
- //printf("mi_reg_r %08x\n", offset * 4);
+ UINT32 ret = 0;
switch (offset)
{
case 0x00/4: // MI_MODE_REG
- return mi_mode;
+ ret = mi_mode;
+ break;
case 0x04/4: // MI_VERSION_REG
- return mi_version;
+ ret = mi_version;
+ break;
case 0x08/4: // MI_INTR_REG
- return mi_interrupt;
+ ret = mi_interrupt;
+ break;
case 0x0c/4: // MI_INTR_MASK_REG
- return mi_intr_mask;
+ ret = mi_intr_mask;
+ break;
default:
logerror("mi_reg_r: %08X, %08X at %08X\n", offset, mem_mask, cpu_get_pc(&mem_map->device()));
break;
}
- return 0;
+ //printf("mi_reg_r %08x = %08x\n", offset * 4, ret);
+ return ret;
}
WRITE32_MEMBER( n64_periphs::mi_reg_w )
@@ -227,6 +233,8 @@ WRITE32_MEMBER( n64_periphs::mi_reg_w )
{
clear_rcp_interrupt(DP_INTERRUPT);
}
+ mi_mode &= ~0x7f;
+ mi_mode |= data & 0x7f;
break;
case 0x04/4: // MI_VERSION_REG
@@ -283,6 +291,7 @@ WRITE32_MEMBER( n64_periphs::mi_reg_w )
{
mi_intr_mask |= 0x20; // set DP mask
}
+ check_interrupts();
break;
}
@@ -297,24 +306,30 @@ void signal_rcp_interrupt(running_machine &machine, int interrupt)
machine.device<n64_periphs>("rcp")->signal_rcp_interrupt(interrupt);
}
-void n64_periphs::signal_rcp_interrupt(int interrupt)
+void n64_periphs::check_interrupts()
{
- if (mi_intr_mask & interrupt)
+ if (mi_intr_mask & mi_interrupt)
{
- mi_interrupt |= interrupt;
-
cputag_set_input_line(machine(), "maincpu", INPUT_LINE_IRQ0, ASSERT_LINE);
}
+ else
+ {
+ cputag_set_input_line(machine(), "maincpu", INPUT_LINE_IRQ0, CLEAR_LINE);
+ }
+}
+
+void n64_periphs::signal_rcp_interrupt(int interrupt)
+{
+ mi_interrupt |= interrupt;
+
+ check_interrupts();
}
void n64_periphs::clear_rcp_interrupt(int interrupt)
{
mi_interrupt &= ~interrupt;
- if (!mi_interrupt)
- {
- cputag_set_input_line(machine(), "maincpu", INPUT_LINE_IRQ0, CLEAR_LINE);
- }
+ check_interrupts();
}
READ32_MEMBER( n64_periphs::is64_r )
@@ -350,10 +365,10 @@ WRITE32_MEMBER( n64_periphs::is64_w )
case 0x0014/4:
for(i = 0x20; i < (0x20 + data); i++)
{
- printf( "%c", is64_buffer[i] );
+ //printf( "%c", is64_buffer[i] );
if(is64_buffer[i] == 0x0a)
{
- printf( "%c", 0x0d );
+ //printf( "%c", 0x0d );
}
is64_buffer[i] = 0;
}
@@ -371,7 +386,7 @@ WRITE32_MEMBER( n64_periphs::is64_w )
READ32_MEMBER( n64_periphs::open_r )
{
UINT32 retval = (offset << 2) & 0x0000ffff;
- retval = (retval << 16) | retval;
+ retval = ((retval + 2) << 16) | retval;
return retval;
}
@@ -395,7 +410,7 @@ WRITE32_MEMBER( n64_periphs::open_w )
READ32_MEMBER( n64_periphs::rdram_reg_r )
{
- //printf("rdram_reg_r %08x\n", offset * 4);
+ //printf("rdram_reg_r %08x = %08x\n", offset * 4, rdram_regs[offset]);
if(offset > 0x24/4)
{
logerror("rdram_reg_r: %08X, %08X at %08X\n", offset, mem_mask, cpu_get_pc(maincpu));
@@ -409,7 +424,7 @@ WRITE32_MEMBER( n64_periphs::rdram_reg_w )
//printf("rdram_reg_w %08x %08x %08x\n", offset * 4, data, mem_mask);
if(offset > 0x24/4)
{
- logerror("mi_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, cpu_get_pc(maincpu));
+ logerror("rdram_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, cpu_get_pc(maincpu));
return;
}
COMBINE_DATA(&rdram_regs[offset]);
@@ -436,7 +451,7 @@ void n64_periphs::sp_dma(int direction)
if ((sp_mem_addr & 0xfff) + (sp_dma_length) > 0x1000)
{
- printf("sp_dma: dma out of memory area: %08X, %08X\n", sp_mem_addr, sp_dma_length);
+ //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);
}
@@ -508,37 +523,47 @@ void n64_periphs::sp_set_status(UINT32 status)
UINT32 n64_periphs::sp_reg_r(UINT32 offset)
{
- //printf("sp_reg_r %08x\n", offset * 4);
+ UINT32 ret = 0;
switch (offset)
{
case 0x00/4: // SP_MEM_ADDR_REG
- return sp_mem_addr;
+ ret = sp_mem_addr;
+ break;
case 0x04/4: // SP_DRAM_ADDR_REG
- return sp_dram_addr;
+ ret = sp_dram_addr;
+ break;
case 0x08/4: // SP_RD_LEN_REG
- return (sp_dma_skip << 20) | (sp_dma_count << 12) | sp_dma_length;
+ ret = (sp_dma_skip << 20) | (sp_dma_count << 12) | sp_dma_length;
+ break;
case 0x10/4: // SP_STATUS_REG
- return cpu_get_reg(rspcpu, RSP_SR);
+ //machine().scheduler().synchronize();
+ //machine().scheduler().boost_interleave(attotime::from_msec(1), attotime::from_msec(m));
+ ret = cpu_get_reg(rspcpu, RSP_SR);
+ break;
case 0x14/4: // SP_DMA_FULL_REG
- return 0;
+ ret = 0;
+ break;
case 0x18/4: // SP_DMA_BUSY_REG
- return 0;
+ ret = 0;
+ break;
case 0x1c/4: // SP_SEMAPHORE_REG
+ //machine().scheduler().boost_interleave(attotime::from_usec(1), attotime::from_usec(1));
if( sp_semaphore )
{
- return 1;
+ ret = 1;
}
else
{
sp_semaphore = 1;
- return 0;
+ ret = 0;
}
+ break;
case 0x20/4: // DP_CMD_START
case 0x24/4: // DP_CMD_END
@@ -546,23 +571,27 @@ UINT32 n64_periphs::sp_reg_r(UINT32 offset)
case 0x34/4: // DP_CMD_BUSY
case 0x38/4: // DP_CMD_PIPE_BUSY
case 0x3c/4: // DP_CMD_TMEM_BUSY
- return 0;
+ break;
case 0x2c/4: // DP_CMD_STATUS
- return 0x88;
+ ret = 0x88;
+ break;
case 0x30/4: // DP_CMD_CLOCK
- return ++dp_clock;
+ ret = ++dp_clock;
+ break;
case 0x40000/4: // PC
- return cpu_get_reg(rspcpu, RSP_PC) & 0x00000fff;
+ ret = cpu_get_reg(rspcpu, RSP_PC) & 0x00000fff;
+ break;
default:
logerror("sp_reg_r: %08X at %08X\n", offset, cpu_get_pc(maincpu));
break;
}
- return 0;
+ //printf("sp_reg_r %08x = %08x\n", offset * 4, ret);
+ return ret;
}
READ32_DEVICE_HANDLER( n64_sp_reg_r )
@@ -573,6 +602,8 @@ 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"));
+
if ((offset & 0x10000) == 0)
{
switch (offset & 0xffff)
@@ -716,6 +747,7 @@ void n64_periphs::sp_reg_w(UINT32 offset, UINT32 data, UINT32 mem_mask)
}
case 0x1c/4: // SP_SEMAPHORE_REG
+ //machine().scheduler().boost_interleave(attotime::from_usec(1), attotime::from_usec(1));
if(data == 0)
{
sp_semaphore = 0;
@@ -764,28 +796,32 @@ void dp_full_sync(running_machine &machine)
READ32_DEVICE_HANDLER( n64_dp_reg_r )
{
n64_state *state = device->machine().driver_data<n64_state>();
-
- //printf("dp_reg_r %08x\n", offset);
+ UINT32 ret = 0;
switch (offset)
{
case 0x00/4: // DP_START_REG
- return state->m_rdp->GetStartReg();
+ ret = state->m_rdp->GetStartReg();
+ break;
case 0x04/4: // DP_END_REG
- return state->m_rdp->GetEndReg();
+ ret = state->m_rdp->GetEndReg();
+ break;
case 0x08/4: // DP_CURRENT_REG
- return state->m_rdp->GetCurrentReg();
+ ret = state->m_rdp->GetCurrentReg();
+ break;
case 0x0c/4: // DP_STATUS_REG
- return state->m_rdp->GetStatusReg();
+ ret = state->m_rdp->GetStatusReg();
+ break;
default:
logerror("dp_reg_r: %08X, %08X at %08X\n", offset, mem_mask, cpu_get_pc(device));
break;
}
- return 0;
+ //printf("dp_reg_r %08x = %08x\n", offset, ret);
+ return ret;
}
WRITE32_DEVICE_HANDLER( n64_dp_reg_w )
@@ -893,56 +929,72 @@ void n64_periphs::vi_recalculate_resolution()
READ32_MEMBER( n64_periphs::vi_reg_r )
{
- //printf("vi_reg_r %08x\n", offset * 4);
+ UINT32 ret = 0;
switch (offset)
{
case 0x00/4: // VI_CONTROL_REG
- return vi_control;
+ ret = vi_control;
+ break;
case 0x04/4: // VI_ORIGIN_REG
- return vi_origin;
+ ret = vi_origin;
+ break;
case 0x08/4: // VI_WIDTH_REG
- return vi_width;
+ ret = vi_width;
+ break;
case 0x0c/4:
- return vi_intr;
+ ret = vi_intr;
+ break;
case 0x10/4: // VI_CURRENT_REG
- return machine().primary_screen->vpos() << 1;
+ ret = machine().primary_screen->vpos() << 1;
+ break;
case 0x14/4: // VI_BURST_REG
- return vi_burst;
+ ret = vi_burst;
+ break;
case 0x18/4: // VI_V_SYNC_REG
- return vi_vsync;
+ ret = vi_vsync;
+ break;
case 0x1c/4: // VI_H_SYNC_REG
- return vi_hsync;
+ ret = vi_hsync;
+ break;
case 0x20/4: // VI_LEAP_REG
- return vi_leap;
+ ret = vi_leap;
+ break;
case 0x24/4: // VI_H_START_REG
- return vi_hstart;
+ ret = vi_hstart;
+ break;
case 0x28/4: // VI_V_START_REG
- return vi_vstart;
+ ret = vi_vstart;
+ break;
case 0x2c/4: // VI_V_BURST_REG
- return vi_vburst;
+ ret = vi_vburst;
+ break;
case 0x30/4: // VI_X_SCALE_REG
- return vi_xscale;
+ ret = vi_xscale;
+ break;
case 0x34/4: // VI_Y_SCALE_REG
- return vi_yscale;
+ ret = vi_yscale;
+ break;
default:
logerror("vi_reg_r: %08X, %08X at %08X\n", offset, mem_mask, cpu_get_pc(maincpu));
break;
}
- return 0;
+
+ //printf("vi_reg_r %08x = %08x\n", offset * 4, ret);
+ return ret;
}
WRITE32_MEMBER( n64_periphs::vi_reg_w )
@@ -1149,33 +1201,39 @@ void n64_periphs::ai_timer_tick()
READ32_MEMBER( n64_periphs::ai_reg_r )
{
- //printf("ai_reg_r %08x\n", offset * 4);
+ UINT32 ret = 0;
switch (offset)
{
case 0x04/4: // AI_LEN_REG
{
if (ai_status & 0x80000001)
{
- return ai_len;
+ ret = ai_len;
}
else if (ai_status & 0x40000000)
{
double secs_left = (ai_timer->expire() - machine().time()).as_double();
unsigned int samples_left = secs_left * DACRATE_NTSC / (ai_dacrate + 1);
- return samples_left * 4;
+ ret = samples_left * 4;
}
- else return 0;
+ else
+ {
+ ret = 0;
+ }
+ break;
}
case 0x0c/4: // AI_STATUS_REG
- return ai_status;
+ ret = ai_status;
+ break;
default:
logerror("ai_reg_r: %08X, %08X at %08X\n", offset, mem_mask, cpu_get_pc(maincpu));
break;
}
- return 0;
+ //printf("ai_reg_r %08x = %08x\n", offset * 4, ret);
+ return ret;
}
WRITE32_MEMBER( n64_periphs::ai_reg_w )
@@ -1230,18 +1288,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)
+ if((cart_addr & 0x04000000) == 0x04000000)
{
cart16 = (UINT16*)n64_sram;
cart_addr = (pi_cart_addr & 0x0001ffff) >> 1;
}
+ else if((cart_addr & 0x03000000) == 0x03000000 && dd_present)
+ {
+ cart16 = (UINT16*)machine().region("ddipl")->base();
+ cart_addr = (pi_cart_addr & 0x003fffff) >> 1;
+ }
+ else
+ {
+ cart_addr &= ((machine().region("user2")->bytes() >> 1) - 1);
+ }
- cart_addr &= ((machine().region("user2")->bytes() >> 1) - 1);
+ //printf("%08x Cart, %08x Dram\n", cart_addr << 1, dram_addr << 1);
if(pi_dma_dir == 1)
{
@@ -1300,47 +1365,60 @@ void n64_periphs::pi_dma_tick()
READ32_MEMBER( n64_periphs::pi_reg_r )
{
- //printf("pi_reg_r %08x\n", offset * 4);
+ UINT32 ret = 0;
switch (offset)
{
case 0x00/4: // PI_DRAM_ADDR_REG
- return pi_dram_addr;
+ ret = pi_dram_addr;
+ break;
case 0x04/4: // PI_CART_ADDR_REG
- return pi_cart_addr;
+ ret = pi_cart_addr;
+ break;
case 0x10/4: // PI_STATUS_REG
- return pi_status;
+ ret = pi_status;
+ break;
case 0x14/4: // PI_BSD_DOM1_LAT
- return pi_bsd_dom1_lat;
+ ret = pi_bsd_dom1_lat;
+ break;
case 0x18/4: // PI_BSD_DOM1_PWD
- return pi_bsd_dom1_pwd;
+ ret = pi_bsd_dom1_pwd;
+ break;
case 0x1c/4: // PI_BSD_DOM1_PGS
- return pi_bsd_dom1_pgs;
+ ret = pi_bsd_dom1_pgs;
+ break;
case 0x20/4: // PI_BSD_DOM1_RLS
- return pi_bsd_dom1_rls;
+ ret = pi_bsd_dom1_rls;
+ break;
case 0x24/4: // PI_BSD_DOM2_LAT
- return pi_bsd_dom2_lat;
+ ret = pi_bsd_dom2_lat;
+ break;
case 0x28/4: // PI_BSD_DOM2_PWD
- return pi_bsd_dom2_pwd;
+ ret = pi_bsd_dom2_pwd;
+ break;
case 0x2c/4: // PI_BSD_DOM2_PGS
- return pi_bsd_dom2_pgs;
+ ret = pi_bsd_dom2_pgs;
+ break;
case 0x30/4: // PI_BSD_DOM2_RLS
- return pi_bsd_dom2_rls;
+ ret = pi_bsd_dom2_rls;
+ break;
default:
logerror("pi_reg_r: %08X, %08X at %08X\n", offset, mem_mask, cpu_get_pc(maincpu));
break;
}
- return 0;
+
+ //printf("pi_reg_r %08x = %08x\n", offset * 4, ret);
+ return ret;
}
WRITE32_MEMBER( n64_periphs::pi_reg_w )
@@ -1438,7 +1516,7 @@ WRITE32_MEMBER( n64_periphs::pi_reg_w )
READ32_MEMBER( n64_periphs::ri_reg_r )
{
- //printf("ri_reg_r %08x\n", offset * 4);
+ //printf("ri_reg_r %08x = %08x\n", offset * 4, ri_regs[offset]);
if(offset > 0x1c/4)
{
logerror("ri_reg_r: %08X, %08X at %08X\n", offset, mem_mask, cpu_get_pc(maincpu));
@@ -1891,16 +1969,18 @@ void n64_periphs::pif_dma(int direction)
READ32_MEMBER( n64_periphs::si_reg_r )
{
- //printf("si_reg_r %08x\n", offset * 4);
+ UINT32 ret = 0;
switch (offset)
{
//case 0x00/4: // SI_DRAM_ADDR_REG
//return si_dram_addr;
case 0x18/4: // SI_STATUS_REG
- return si_status;
+ ret = si_status;
}
- return 0;
+
+ //printf("si_reg_r %08x = %08x\n", offset * 4, ret);
+ return ret;
}
WRITE32_MEMBER( n64_periphs::si_reg_w )
@@ -1937,6 +2017,17 @@ WRITE32_MEMBER( n64_periphs::si_reg_w )
}
}
+READ32_MEMBER( n64_periphs::dd_reg_r )
+{
+ logerror("dd_reg_r: %08X\n", offset << 2);
+ return 0;
+}
+
+WRITE32_MEMBER( n64_periphs::dd_reg_w )
+{
+ logerror("dd_reg_w: %08X, %08X, %08X\n", data, offset << 2, mem_mask);
+}
+
READ32_MEMBER( n64_periphs::pif_ram_r )
{
if(!space.debugger_access())
@@ -1980,7 +2071,7 @@ static void n64_machine_stop(running_machine &machine)
n64_periphs *periphs = machine.device<n64_periphs>("rcp");
device_image_interface *image = dynamic_cast<device_image_interface *>(periphs->m_nvram_image);
- //printf("Saving\n");
+ //printf("Saving stuff\n");
UINT8 data[0x30800];
memcpy(data, n64_sram, 0x20000);
memcpy(data + 0x20000, periphs->m_save_data.eeprom, 0x800);
diff --git a/src/mame/video/n64.c b/src/mame/video/n64.c
index dcc1f114aeb..22813baccd3 100644
--- a/src/mame/video/n64.c
+++ b/src/mame/video/n64.c
@@ -31,6 +31,28 @@ TODO:
static FILE *rdp_exec;
+bool n64_rdp::rdp_range_check(UINT32 addr)
+{
+ if(MiscState.FBSize == 0) return false;
+
+ int fbcount = ((MiscState.FBWidth * Scissor.m_yl) << (MiscState.FBSize - 1)) * 3;
+ int zbcount = MiscState.FBWidth * Scissor.m_yl * 2;
+ int fbaddr = MiscState.FBAddress & 0x007fffff;
+ int zbaddr = MiscState.ZBAddress & 0x007fffff;
+ if ((addr >= fbaddr) && (addr < (fbaddr + fbcount)))
+ {
+ return false;
+ }
+ if ((addr >= zbaddr) && (addr < (zbaddr + zbcount)))
+ {
+ return false;
+ }
+
+ printf("Check failed: %08x vs. %08x-%08x, %08x-%08x (%d, %d)\n", addr, fbaddr, fbaddr + fbcount, zbaddr, zbaddr + zbcount, MiscState.FBWidth, Scissor.m_yl);
+ fflush(stdout);
+ return true;
+}
+
/*****************************************************************************/
// The functions in this file should be moved into the parent Processor class.
@@ -113,7 +135,12 @@ void n64_rdp::VideoUpdate16(n64_periphs *n64, bitmap_rgb32 &bitmap)
hres = 640;
}
- UINT32 pixels = 0;
+ if (vres > bitmap.height()) // makes Perfect Dark boot w/o crashing
+ {
+ vres = bitmap.height();
+ }
+
+ UINT32 pixels = 0;
if (frame_buffer)
{
@@ -909,12 +936,14 @@ INT32 n64_rdp::NormalizeDZPix(INT32 sum)
UINT32 n64_rdp::ZDecompress(UINT32 zcurpixel)
{
UINT32 zb = RREADIDX16(zcurpixel);
+ CHECK16(zcurpixel);
return z_complete_dec_table[(zb >> 2) & 0x3fff];
}
UINT32 n64_rdp::DZDecompress(UINT32 zcurpixel, UINT32 dzcurpixel)
{
UINT16 zval = RREADIDX16(zcurpixel);
+ CHECK16(zcurpixel);
UINT8 dzval = (((dzcurpixel) <= 0x7fffff) ? (HiddenBits[(dzcurpixel) ^ BYTE_ADDR_XOR]) : 0);
UINT32 dz_compressed = ((zval & 3) << 2) | (dzval & 3);
return (1 << dz_compressed);
@@ -1018,6 +1047,7 @@ bool n64_rdp::ZCompare(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 sz, UINT16 dz
oz = ZDecompress(zcurpixel);
dzmem = DZDecompress(zcurpixel, dzcurpixel);
zval = RREADIDX16(zcurpixel);
+ CHECK16(zcurpixel);
rawdzmem = ((zval & 3) << 2) | ((((dzcurpixel) <= 0x3fffff) ? (HiddenBits[(dzcurpixel) ^ BYTE_ADDR_XOR]) : 0) & 3);
}
else
@@ -2121,8 +2151,14 @@ void n64_rdp::DrawTriangle(bool shade, bool texture, bool zbuffer, bool rect)
if (spix == 0)
{
- Spans[j - (ycur >> 2)].userdata = (void*)((UINT8*)AuxBuf[AuxBufIndex] + AuxBufPtr[AuxBufIndex]);
- AuxBufPtr[AuxBufIndex] += sizeof(rdp_span_aux);
+ Spans[j - (ycur >> 2)].userdata = (void*)((UINT8*)AuxBuf + AuxBufPtr);
+ AuxBufPtr += sizeof(rdp_span_aux);
+
+ if(AuxBufPtr >= EXTENT_AUX_COUNT)
+ {
+ fatalerror("n64_rdp::DrawTriangle: span aux buffer overflow\n");
+ }
+
rdp_span_aux *userdata = (rdp_span_aux*)Spans[j - (ycur >> 2)].userdata;
userdata->m_tmem = object.m_tmem;
@@ -2273,8 +2309,13 @@ void n64_rdp::DrawTriangle(bool shade, bool texture, bool zbuffer, bool rect)
if (spix == 0)
{
- Spans[j - (ycur >> 2)].userdata = (void*)((UINT8*)AuxBuf[AuxBufIndex] + AuxBufPtr[AuxBufIndex]);
- AuxBufPtr[AuxBufIndex] += sizeof(rdp_span_aux);
+ Spans[j - (ycur >> 2)].userdata = (void*)((UINT8*)AuxBuf + AuxBufPtr);
+ AuxBufPtr += sizeof(rdp_span_aux);
+
+ if(AuxBufPtr >= EXTENT_AUX_COUNT)
+ {
+ fatalerror("n64_rdp::DrawTriangle: span aux buffer overflow\n");
+ }
rdp_span_aux *userdata = (rdp_span_aux*)Spans[j - (ycur >> 2)].userdata;
userdata->m_tmem = object.m_tmem;
@@ -2409,6 +2450,7 @@ void n64_rdp::_Write16Bit_Cvg0_Blend(UINT32 curpixel, UINT32 r, UINT32 g, UINT32
if (object.OtherModes.color_on_cvg && !userdata->PreWrap)
{
finalcolor = RREADIDX16(fb) & 0xfffe;
+ CHECK16(fb);
}
finalcvg = userdata->CurrentPixCvg + userdata->CurrentMemCvg;
@@ -2431,6 +2473,7 @@ void n64_rdp::_Write16Bit_Cvg0_NoBlend(UINT32 curpixel, UINT32 r, UINT32 g, UINT
if (object.OtherModes.color_on_cvg && !userdata->PreWrap)
{
finalcolor = RREADIDX16(fb) & 0xfffe;
+ CHECK16(fb);
}
finalcvg = (userdata->CurrentPixCvg - 1) & 7;
@@ -2449,6 +2492,7 @@ void n64_rdp::_Write16Bit_Cvg1(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rd
if (object.OtherModes.color_on_cvg && !userdata->PreWrap)
{
finalcolor = RREADIDX16(fb) & 0xfffe;
+ CHECK16(fb);
}
finalcvg = (userdata->CurrentPixCvg + userdata->CurrentMemCvg) & 7;
@@ -2466,6 +2510,7 @@ void n64_rdp::_Write16Bit_Cvg2(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rd
if (object.OtherModes.color_on_cvg && !userdata->PreWrap)
{
finalcolor = RREADIDX16(fb) & 0xfffe;
+ CHECK16(fb);
}
RWRITEIDX16(fb, finalcolor | 1);
@@ -2482,6 +2527,7 @@ void n64_rdp::_Write16Bit_Cvg3(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rd
if (object.OtherModes.color_on_cvg && !userdata->PreWrap)
{
finalcolor = RREADIDX16(fb) & 0xfffe;
+ CHECK16(fb);
}
RWRITEIDX16(fb, finalcolor | ((userdata->CurrentMemCvg >> 2) & 1));
@@ -2497,6 +2543,7 @@ void n64_rdp::_Write32Bit_Cvg0_Blend(UINT32 curpixel, UINT32 r, UINT32 g, UINT32
if (object.OtherModes.color_on_cvg && !userdata->PreWrap)
{
finalcolor = RREADIDX32(fb) & 0xffffff00;
+ CHECK32(fb);
}
finalcvg = userdata->CurrentPixCvg + userdata->CurrentMemCvg;
@@ -2516,6 +2563,7 @@ void n64_rdp::_Write32Bit_Cvg0_NoBlend(UINT32 curpixel, UINT32 r, UINT32 g, UINT
if (object.OtherModes.color_on_cvg && !userdata->PreWrap)
{
finalcolor = RREADIDX32(fb) & 0xffffff00;
+ CHECK32(fb);
}
finalcvg = (userdata->CurrentPixCvg - 1) & 7;
@@ -2531,6 +2579,7 @@ void n64_rdp::_Write32Bit_Cvg1(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rd
if (object.OtherModes.color_on_cvg && !userdata->PreWrap)
{
finalcolor = RREADIDX32(fb) & 0xffffff00;
+ CHECK32(fb);
}
finalcvg = (userdata->CurrentPixCvg + userdata->CurrentMemCvg) & 7;
@@ -2546,6 +2595,7 @@ void n64_rdp::_Write32Bit_Cvg2(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rd
if (object.OtherModes.color_on_cvg && !userdata->PreWrap)
{
finalcolor = RREADIDX32(fb) & 0xffffff00;
+ CHECK32(fb);
}
RWRITEIDX32(fb, finalcolor | 0xE0);
@@ -2559,6 +2609,7 @@ void n64_rdp::_Write32Bit_Cvg3(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rd
if (object.OtherModes.color_on_cvg && !userdata->PreWrap)
{
finalcolor = RREADIDX32(fb) & 0xffffff00;
+ CHECK32(fb);
}
RWRITEIDX32(fb, finalcolor | (userdata->CurrentMemCvg << 5));
@@ -2568,6 +2619,7 @@ void n64_rdp::_Write32Bit_Cvg3(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rd
void n64_rdp::_Read16Bit_ImgRead0(UINT32 curpixel, rdp_span_aux *userdata, const rdp_poly_state &object)
{
UINT16 fword = RREADIDX16((object.MiscState.FBAddress >> 1) + curpixel);
+ CHECK16((object.MiscState.FBAddress >> 1) + curpixel);
userdata->MemoryColor.i.r = GETHICOL(fword);
userdata->MemoryColor.i.g = GETMEDCOL(fword);
userdata->MemoryColor.i.b = GETLOWCOL(fword);
@@ -2578,6 +2630,7 @@ void n64_rdp::_Read16Bit_ImgRead0(UINT32 curpixel, rdp_span_aux *userdata, const
void n64_rdp::_Read16Bit_ImgRead1(UINT32 curpixel, rdp_span_aux *userdata, const rdp_poly_state &object)
{
UINT16 fword = RREADIDX16((object.MiscState.FBAddress >> 1) + curpixel);
+ CHECK16((object.MiscState.FBAddress >> 1) + curpixel);
UINT8 hbyte = HREADADDR8((object.MiscState.FBAddress >> 1) + curpixel);
userdata->MemoryColor.i.r = GETHICOL(fword);
userdata->MemoryColor.i.g = GETMEDCOL(fword);
@@ -2589,6 +2642,7 @@ void n64_rdp::_Read16Bit_ImgRead1(UINT32 curpixel, rdp_span_aux *userdata, const
void n64_rdp::_Read32Bit_ImgRead0(UINT32 curpixel, rdp_span_aux *userdata, const rdp_poly_state &object)
{
UINT32 mem = RREADIDX32((object.MiscState.FBAddress >> 2) + curpixel);
+ CHECK32((object.MiscState.FBAddress >> 2) + curpixel);
userdata->MemoryColor.i.r = (mem >> 24) & 0xff;
userdata->MemoryColor.i.g = (mem >> 16) & 0xff;
userdata->MemoryColor.i.b = (mem >> 8) & 0xff;
@@ -2599,6 +2653,7 @@ void n64_rdp::_Read32Bit_ImgRead0(UINT32 curpixel, rdp_span_aux *userdata, const
void n64_rdp::_Read32Bit_ImgRead1(UINT32 curpixel, rdp_span_aux *userdata, const rdp_poly_state &object)
{
UINT32 mem = RREADIDX32((object.MiscState.FBAddress >> 2) + curpixel);
+ CHECK32((object.MiscState.FBAddress >> 2) + curpixel);
userdata->MemoryColor.i.r = (mem >> 24) & 0xff;
userdata->MemoryColor.i.g = (mem >> 16) & 0xff;
userdata->MemoryColor.i.b = (mem >> 8) & 0xff;
@@ -2611,12 +2666,14 @@ void n64_rdp::_Copy16Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, int Curr
UINT16 val = ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1) | ((CurrentPixCvg >> 2) & 1);
RWRITEIDX16((object.MiscState.FBAddress >> 1) + curpixel, val);
HWRITEADDR8((object.MiscState.FBAddress >> 1) + curpixel, CurrentPixCvg & 3);
+ CHECK16((object.MiscState.FBAddress >> 1) + curpixel);
}
void n64_rdp::_Copy32Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, int CurrentPixCvg, const rdp_poly_state &object)
{
UINT32 val = (r << 24) | (g << 16) | (b << 8) | (CurrentPixCvg << 5);
RWRITEIDX32((object.MiscState.FBAddress >> 2) + curpixel, val);
+ CHECK32((object.MiscState.FBAddress >> 2) + curpixel);
}
@@ -2632,6 +2689,7 @@ void n64_rdp::_Fill16Bit(UINT32 curpixel, const rdp_poly_state &object)
val = (object.FillColor >> 16) & 0xffff;
}
RWRITEIDX16((object.MiscState.FBAddress >> 1) + curpixel, val);
+ CHECK16((object.MiscState.FBAddress >> 1) + curpixel);
HWRITEADDR8((object.MiscState.FBAddress >> 1) + curpixel, ((val & 1) << 1) | (val & 1));
}
@@ -2639,6 +2697,7 @@ void n64_rdp::_Fill32Bit(UINT32 curpixel, const rdp_poly_state &object)
{
UINT32 FillColor = object.FillColor;
RWRITEIDX32((object.MiscState.FBAddress >> 2) + curpixel, FillColor);
+ CHECK32((object.MiscState.FBAddress >> 2) + curpixel);
HWRITEADDR8((object.MiscState.FBAddress >> 1) + (curpixel << 1), (FillColor & 0x10000) ? 3 : 0);
HWRITEADDR8((object.MiscState.FBAddress >> 1) + (curpixel << 1) + 1, (FillColor & 0x1) ? 3 : 0);
}
@@ -2650,6 +2709,7 @@ void n64_rdp::Triangle(bool shade, bool texture, bool zbuffer)
{
DrawTriangle(shade, texture, zbuffer, false);
m_pipe_clean = false;
+ //wait();
}
void n64_rdp::CmdTriangle(UINT32 w1, UINT32 w2)
@@ -2831,7 +2891,7 @@ void n64_rdp::CmdSyncTile(UINT32 w1, UINT32 w2)
void n64_rdp::CmdSyncFull(UINT32 w1, UINT32 w2)
{
- //wait("SyncFull");
+ wait("SyncFull");
dp_full_sync(*m_machine);
}
@@ -2962,7 +3022,7 @@ void n64_rdp::CmdLoadTLUT(UINT32 w1, UINT32 w2)
{
if (dststart < 2048)
{
- dst[dststart] = RREADIDX16(srcstart);
+ dst[dststart] = U_RREADIDX16(srcstart);
dst[dststart + 1] = dst[dststart];
dst[dststart + 2] = dst[dststart];
dst[dststart + 3] = dst[dststart];
@@ -3048,10 +3108,10 @@ void n64_rdp::CmdLoadBlock(UINT32 w1, UINT32 w2)
ptr = tb + (i << 2);
srcptr = src + (i << 2);
- tc[(ptr ^ t) & 0x7ff] = RREADIDX16(srcptr);
- tc[((ptr + 1) ^ t) & 0x7ff] = RREADIDX16(srcptr + 1);
- tc[((ptr + 2) ^ t) & 0x7ff] = RREADIDX16(srcptr + 2);
- tc[((ptr + 3) ^ t) & 0x7ff] = RREADIDX16(srcptr + 3);
+ tc[(ptr ^ t) & 0x7ff] = U_RREADIDX16(srcptr);
+ tc[((ptr + 1) ^ t) & 0x7ff] = U_RREADIDX16(srcptr + 1);
+ tc[((ptr + 2) ^ t) & 0x7ff] = U_RREADIDX16(srcptr + 2);
+ tc[((ptr + 3) ^ t) & 0x7ff] = U_RREADIDX16(srcptr + 3);
j += dxt;
}
}
@@ -3069,14 +3129,14 @@ void n64_rdp::CmdLoadBlock(UINT32 w1, UINT32 w2)
ptr = ((tb + (i << 1)) ^ t) & 0x3ff;
srcptr = src + (i << 2);
- first = RREADIDX16(srcptr);
- sec = RREADIDX16(srcptr + 1);
+ first = U_RREADIDX16(srcptr);
+ sec = U_RREADIDX16(srcptr + 1);
tc[ptr] = ((first >> 8) << 8) | (sec >> 8);
tc[ptr | 0x400] = ((first & 0xff) << 8) | (sec & 0xff);
ptr = ((tb + (i << 1) + 1) ^ t) & 0x3ff;
- first = RREADIDX16(srcptr + 2);
- sec = RREADIDX16(srcptr + 3);
+ first = U_RREADIDX16(srcptr + 2);
+ sec = U_RREADIDX16(srcptr + 3);
tc[ptr] = ((first >> 8) << 8) | (sec >> 8);
tc[ptr | 0x400] = ((first & 0xff) << 8) | (sec & 0xff);
@@ -3094,12 +3154,12 @@ void n64_rdp::CmdLoadBlock(UINT32 w1, UINT32 w2)
ptr = ((tb + (i << 1)) ^ t) & 0x3ff;
srcptr = src + (i << 2);
- tc[ptr] = RREADIDX16(srcptr);
- tc[ptr | 0x400] = RREADIDX16(srcptr + 1);
+ tc[ptr] = U_RREADIDX16(srcptr);
+ tc[ptr | 0x400] = U_RREADIDX16(srcptr + 1);
ptr = ((tb + (i << 1) + 1) ^ t) & 0x3ff;
- tc[ptr] = RREADIDX16(srcptr + 2);
- tc[ptr | 0x400] = RREADIDX16(srcptr + 3);
+ tc[ptr] = U_RREADIDX16(srcptr + 2);
+ tc[ptr | 0x400] = U_RREADIDX16(srcptr + 3);
j += dxt;
}
@@ -3114,10 +3174,10 @@ void n64_rdp::CmdLoadBlock(UINT32 w1, UINT32 w2)
{
ptr = tb + (i << 2);
srcptr = src + (i << 2);
- tc[(ptr ^ WORD_ADDR_XOR) & 0x7ff] = RREADIDX16(srcptr);
- tc[((ptr + 1) ^ WORD_ADDR_XOR) & 0x7ff] = RREADIDX16(srcptr + 1);
- tc[((ptr + 2) ^ WORD_ADDR_XOR) & 0x7ff] = RREADIDX16(srcptr + 2);
- tc[((ptr + 3) ^ WORD_ADDR_XOR) & 0x7ff] = RREADIDX16(srcptr + 3);
+ tc[(ptr ^ WORD_ADDR_XOR) & 0x7ff] = U_RREADIDX16(srcptr);
+ tc[((ptr + 1) ^ WORD_ADDR_XOR) & 0x7ff] = U_RREADIDX16(srcptr + 1);
+ tc[((ptr + 2) ^ WORD_ADDR_XOR) & 0x7ff] = U_RREADIDX16(srcptr + 2);
+ tc[((ptr + 3) ^ WORD_ADDR_XOR) & 0x7ff] = U_RREADIDX16(srcptr + 3);
}
}
else if (tile[tilenum].format == FORMAT_YUV)
@@ -3126,14 +3186,14 @@ void n64_rdp::CmdLoadBlock(UINT32 w1, UINT32 w2)
{
ptr = ((tb + (i << 1)) ^ WORD_ADDR_XOR) & 0x3ff;
srcptr = src + (i << 2);
- first = RREADIDX16(srcptr);
- sec = RREADIDX16(srcptr + 1);
+ first = U_RREADIDX16(srcptr);
+ sec = U_RREADIDX16(srcptr + 1);
tc[ptr] = ((first >> 8) << 8) | (sec >> 8);//UV pair
tc[ptr | 0x400] = ((first & 0xff) << 8) | (sec & 0xff);
ptr = ((tb + (i << 1) + 1) ^ WORD_ADDR_XOR) & 0x3ff;
- first = RREADIDX16(srcptr + 2);
- sec = RREADIDX16(srcptr + 3);
+ first = U_RREADIDX16(srcptr + 2);
+ sec = U_RREADIDX16(srcptr + 3);
tc[ptr] = ((first >> 8) << 8) | (sec >> 8);
tc[ptr | 0x400] = ((first & 0xff) << 8) | (sec & 0xff);
}
@@ -3144,12 +3204,12 @@ void n64_rdp::CmdLoadBlock(UINT32 w1, UINT32 w2)
{
ptr = ((tb + (i << 1)) ^ WORD_ADDR_XOR) & 0x3ff;
srcptr = src + (i << 2);
- tc[ptr] = RREADIDX16(srcptr);
- tc[ptr | 0x400] = RREADIDX16(srcptr + 1);
+ tc[ptr] = U_RREADIDX16(srcptr);
+ tc[ptr | 0x400] = U_RREADIDX16(srcptr + 1);
ptr = ((tb + (i << 1) + 1) ^ WORD_ADDR_XOR) & 0x3ff;
- tc[ptr] = RREADIDX16(srcptr + 2);
- tc[ptr | 0x400] = RREADIDX16(srcptr + 3);
+ tc[ptr] = U_RREADIDX16(srcptr + 2);
+ tc[ptr | 0x400] = U_RREADIDX16(srcptr + 3);
}
}
tile[tilenum].th = tl;
@@ -3202,7 +3262,7 @@ void n64_rdp::CmdLoadTile(UINT32 w1, UINT32 w2)
int xorval8 = ((j & 1) ? BYTE_XOR_DWORD_SWAP : BYTE_ADDR_XOR);
for (int i = 0; i < width; i++)
{
- tc[((tline + i) ^ xorval8) & 0xfff] = RREADADDR8(src + s + i);
+ tc[((tline + i) ^ xorval8) & 0xfff] = U_RREADADDR8(src + s + i);
}
}
break;
@@ -3225,7 +3285,7 @@ void n64_rdp::CmdLoadTile(UINT32 w1, UINT32 w2)
for (int i = 0; i < width; i++)
{
UINT32 taddr = (tline + i) ^ xorval16;
- tc[taddr & 0x7ff] = RREADIDX16(src + s + i);
+ tc[taddr & 0x7ff] = U_RREADIDX16(src + s + i);
}
}
}
@@ -3241,7 +3301,7 @@ void n64_rdp::CmdLoadTile(UINT32 w1, UINT32 w2)
for (int i = 0; i < width; i++)
{
UINT32 taddr = ((tline + i) ^ xorval8) & 0x7ff;
- yuvword = RREADIDX16(src + s + i);
+ yuvword = U_RREADIDX16(src + s + i);
GetTMEM()[taddr] = yuvword >> 8;
GetTMEM()[taddr | 0x800] = yuvword & 0xff;
}
@@ -3263,7 +3323,7 @@ void n64_rdp::CmdLoadTile(UINT32 w1, UINT32 w2)
int xorval32cur = (j & 1) ? WORD_XOR_DWORD_SWAP : WORD_ADDR_XOR;
for (int i = 0; i < width; i++)
{
- UINT32 c = RREADIDX32(src + s + i);
+ UINT32 c = U_RREADIDX32(src + s + i);
UINT32 ptr = ((tline + i) ^ xorval32cur) & 0x3ff;
tc16[ptr] = c >> 16;
tc16[ptr | 0x400] = c & 0xffff;
@@ -3398,31 +3458,23 @@ void n64_rdp::CmdSetTextureImage(UINT32 w1, UINT32 w2)
void n64_rdp::CmdSetMaskImage(UINT32 w1, UINT32 w2)
{
+ wait("SetMaskImage");
+
MiscState.ZBAddress = w2 & 0x01ffffff;
}
void n64_rdp::CmdSetColorImage(UINT32 w1, UINT32 w2)
{
+ wait("SetColorImage");
+
MiscState.FBFormat = (w1 >> 21) & 0x7;
MiscState.FBSize = (w1 >> 19) & 0x3;
MiscState.FBWidth = (w1 & 0x3ff) + 1;
MiscState.FBAddress = w2 & 0x01ffffff;
- if (MiscState.FBFormat && MiscState.FBFormat != 2) // Jet Force Gemini sets the format to 4, Intensity. Protection?
- {
- if (MiscState.FBSize == 1)
- {
- MiscState.FBFormat = 2;
- }
- else
- {
- MiscState.FBFormat = 0;
- }
- }
-
- if (MiscState.FBFormat != 0)
+ if (MiscState.FBFormat < 2 || MiscState.FBFormat > 32) // Jet Force Gemini sets the format to 4, Intensity. Protection?
{
- MiscState.FBFormat = 0;
+ MiscState.FBFormat = 2;
}
}
@@ -3634,9 +3686,8 @@ void n64_rdp::ProcessList()
n64_rdp::n64_rdp(n64_state &state) : poly_manager<UINT32, rdp_poly_state, 8, 32000>(state.machine())
{
- AuxBufIndex = 0;
- AuxBufPtr[0] = AuxBufPtr[1] = 0;
- AuxBuf[0] = AuxBuf[1] = NULL;
+ AuxBufPtr = 0;
+ AuxBuf = NULL;
m_pipe_clean = true;
m_pending_mode_block = false;
@@ -3753,8 +3804,7 @@ VIDEO_START(n64)
state->m_rdp->TexPipe.SetMachine(machine);
- state->m_rdp->AuxBuf[0] = auto_alloc_array_clear(machine, UINT8, EXTENT_AUX_COUNT);
- state->m_rdp->AuxBuf[1] = auto_alloc_array_clear(machine, UINT8, EXTENT_AUX_COUNT);
+ state->m_rdp->AuxBuf = auto_alloc_array_clear(machine, UINT8, EXTENT_AUX_COUNT);
if (LOG_RDP_EXECUTION)
{
@@ -3768,7 +3818,6 @@ SCREEN_UPDATE_RGB32(n64)
n64_periphs *n64 = screen.machine().device<n64_periphs>("rcp");
state->m_rdp->visarea = screen.visible_area();
- int height = state->m_rdp->MiscState.FBHeight;
//UINT16 *frame_buffer = (UINT16*)&rdram[(n64->vi_origin & 0xffffff) >> 2];
//UINT8 *cvg_buffer = &state->m_rdp.HiddenBits[((n64->vi_origin & 0xffffff) >> 2) >> 1];
//int vibuffering = ((n64->vi_control & 2) && fsaa && divot);
@@ -3808,12 +3857,11 @@ SCREEN_UPDATE_RGB32(n64)
*/
state->m_rdp->wait();
- state->m_rdp->AuxBufPtr[state->m_rdp->AuxBufIndex] = 0;
- state->m_rdp->AuxBufIndex ^= 1;
+ state->m_rdp->AuxBufPtr = 0;
if (n64->vi_blank)
{
- for (int j = 0; j <height; j++)
+ 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++)
diff --git a/src/mame/video/n64.h b/src/mame/video/n64.h
index aec4afe4ea8..c2956a9eca9 100644
--- a/src/mame/video/n64.h
+++ b/src/mame/video/n64.h
@@ -56,13 +56,43 @@
#define MEM16_LIMIT 0x3fffff
#define MEM32_LIMIT 0x1fffff
-#define RREADADDR8(in) /*(((in) <= MEM8_LIMIT) ? */(((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR]) /*: 0)*/
-#define RREADIDX16(in) /*(((in) <= MEM16_LIMIT) ? */(((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR]) /*: 0)*/
-#define RREADIDX32(in) /*(((in) <= MEM32_LIMIT) ? */(rdram[(in)]) /*: 0)*/
+#define RDP_RANGE_CHECK (0)
-#define RWRITEADDR8(in, val) {/*if ((in) <= MEM8_LIMIT) */((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR] = val;}
-#define RWRITEIDX16(in, val) {/*if ((in) <= MEM16_LIMIT)*/ ((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR] = val;}
-#define RWRITEIDX32(in, val) {/*if ((in) <= MEM32_LIMIT)*/ rdram[(in)] = val;}
+#if RDP_RANGE_CHECK
+#define CHECK8(in) if(rdp_range_check((in))) { printf("Check8: Address %08x out of range!\n", (in)); fflush(stdout); fatalerror("Address %08x out of range!\n", (in)); }
+#define CHECK16(in) if(rdp_range_check((in) << 1)) { printf("Check16: Address %08x out of range!\n", (in) << 1); fflush(stdout); fatalerror("Address %08x out of range!\n", (in) << 1); }
+#define CHECK32(in) if(rdp_range_check((in) << 2)) { printf("Check32: Address %08x out of range!\n", (in) << 2); fflush(stdout); fatalerror("Address %08x out of range!\n", (in) << 2); }
+#else
+#define CHECK8(in) { }
+#define CHECK16(in) { }
+#define CHECK32(in) { }
+#endif
+
+#if RDP_RANGE_CHECK
+#define RREADADDR8(in) ((rdp_range_check((in))) ? 0 : (((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR]))
+#define RREADIDX16(in) ((rdp_range_check((in) << 1)) ? 0 : (((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR]))
+#define RREADIDX32(in) ((rdp_range_check((in) << 2)) ? 0 : rdram[(in)])
+
+#define RWRITEADDR8(in, val) if(rdp_range_check((in))) { printf("Write8: Address %08x out of range!\n", (in)); fflush(stdout); fatalerror("Address %08x out of range!\n", (in)); } else { ((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR] = val;}
+#define RWRITEIDX16(in, val) if(rdp_range_check((in) << 1)) { printf("Write16: Address %08x out of range!\n", (in) << 1); fflush(stdout); fatalerror("Address %08x out of range!\n", (in) << 1); } else { ((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR] = val;}
+#define RWRITEIDX32(in, val) if(rdp_range_check((in) << 2)) { printf("Write32: Address %08x out of range!\n", (in) << 2); fflush(stdout); fatalerror("Address %08x out of range!\n", (in) << 2); } else { rdram[(in)] = val;}
+#else
+#define RREADADDR8(in) (((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR])
+#define RREADIDX16(in) (((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR])
+#define RREADIDX32(in) (rdram[(in)])
+
+#define RWRITEADDR8(in, val) ((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR] = val;
+#define RWRITEIDX16(in, val) ((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR] = val;
+#define RWRITEIDX32(in, val) rdram[(in)] = val
+#endif
+
+#define U_RREADADDR8(in) (((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR])
+#define U_RREADIDX16(in) (((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR])
+#define U_RREADIDX32(in) (rdram[(in)])
+
+#define U_RWRITEADDR8(in, val) ((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR] = val;
+#define U_RWRITEIDX16(in, val) ((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR] = val;
+#define U_RWRITEIDX32(in, val) rdram[(in)] = val
#define GETLOWCOL(x) (((x) & 0x3e) << 2)
#define GETMEDCOL(x) (((x) & 0x7c0) >> 3)
@@ -93,7 +123,7 @@
#define RDP_CVG_SPAN_MAX (1024)
-#define EXTENT_AUX_COUNT (sizeof(rdp_span_aux)*(480*256)) // Screen coverage *128, more or less
+#define EXTENT_AUX_COUNT (sizeof(rdp_span_aux)*(480*192)) // Screen coverage *192, more or less
/*****************************************************************************/
@@ -307,6 +337,7 @@ struct ColorInputsT
UINT8 *blender2b_a[2];
};
+// This is enormous and horrible
struct rdp_span_aux
{
UINT32 m_unscissored_rx;
@@ -568,14 +599,15 @@ class n64_rdp : public poly_manager<UINT32, rdp_poly_state, 8, 32000>
void compute_cvg_noflip(extent_t *Spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base);
void compute_cvg_flip(extent_t *Spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base);
- void* AuxBuf[2];
- UINT32 AuxBufPtr[2];
+ void* AuxBuf;
+ UINT32 AuxBufPtr;
UINT32 AuxBufIndex;
void* ExtentBuf[2];
UINT32 ExtentBufPtr[2];
UINT32 ExtentBufIndex;
+ bool rdp_range_check(UINT32 addr);
protected:
CombineModesT m_combine;
bool m_pending_mode_block;
diff --git a/src/mame/video/rdptpipe.c b/src/mame/video/rdptpipe.c
index fabb70c978b..d6e0ba3e0c2 100644
--- a/src/mame/video/rdptpipe.c
+++ b/src/mame/video/rdptpipe.c
@@ -1122,7 +1122,7 @@ UINT32 N64TexturePipeT::_FetchIA_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal
color.i.r = i;
color.i.g = i;
color.i.b = i;
- color.i.a = (p & 1) & 0xff;
+ color.i.a = (p & 1) * 0xff;
return color.c;
}