snes.c: tentative unified approach to snes sram. no whatsnew

This commit is contained in:
Fabio Priuli 2010-04-12 21:04:35 +00:00
parent e77589ac37
commit 0eb8a31957
3 changed files with 225 additions and 69 deletions

View File

@ -23,7 +23,7 @@
#define DOTCLK_NTSC (MCLK_NTSC/4)
#define DOTCLK_PAL (MCLK_PAL/4)
#define SNES_LAYER_DEBUG 1
#define SNES_LAYER_DEBUG 0
/* Debug definitions */
#ifdef MAME_DEBUG
@ -528,11 +528,10 @@ extern UINT32 snes_rom_size;
extern void snes_latch_counters(running_machine *machine);
/* (PPU) Video related */
extern UINT8 *snes_vram; /* Video RAM (Should be 16-bit, but it's easier this way) */
extern UINT16 *snes_cgram; /* Colour RAM */
extern UINT16 *snes_oam; /* Object Attribute Memory */
extern UINT8 *snes_ram; /* Main memory */
/* (PPU) Video related */
struct SNES_PPU_STRUCT /* once all the regs are saved in this structure, it would be better to reorganize it a bit... */
{
struct

View File

@ -25,9 +25,6 @@
/* -- Globals -- */
UINT8 *snes_ram = NULL; /* 65816 ram */
UINT8 *snes_vram = NULL; /* Video RAM (Should be 16-bit, but it's easier this way) */
UINT16 *snes_cgram = NULL; /* Colour RAM */
UINT16 *snes_oam = NULL; /* Object Attribute Memory */
UINT8 snes_has_addon_chip;
UINT32 snes_rom_size;
@ -994,7 +991,8 @@ READ8_HANDLER( snes_r_bank2 )
}
else if ((snes_cart.mode == SNES_MODE_21) && (snes_cart.sram > 0))
{
value = snes_ram[0x300000 + offset];
int mask = (snes_cart.sram - 1) | 0xff0000; /* Limit SRAM size to what's actually present */
value = snes_ram[0x300000 + (offset & mask)];
}
else
{
@ -1155,7 +1153,8 @@ READ8_HANDLER( snes_r_bank6 )
value = memory_read_byte(space, offset);
else if ((offset >= 0x300000) && (snes_cart.sram > 0))
{
value = snes_ram[0x800000 + offset]; /* SRAM */
int mask = (snes_cart.sram - 1) | 0xff0000; /* Limit SRAM size to what's actually present */
value = snes_ram[0x800000 + (offset & mask)];
}
else /* Area 0x6000-0x8000 with offset < 0x300000 is reserved */
{
@ -1304,7 +1303,8 @@ WRITE8_HANDLER( snes_w_bank2 )
}
else if ((snes_cart.mode == SNES_MODE_21) && (snes_cart.sram > 0))
{
snes_ram[0x300000 + offset] = data;
int mask = (snes_cart.sram - 1) | 0xff0000; /* Limit SRAM size to what's actually present */
snes_ram[0x300000 + (offset & mask)] = data;
}
else
logerror("snes_w_bank2: Attempt to write to reserved address: %X = %02x\n", offset + 0x300000, data);
@ -1399,7 +1399,8 @@ WRITE8_HANDLER( snes_w_bank6 )
memory_write_byte(space, offset, data);
else if ((offset >= 0x300000) && (snes_cart.sram > 0))
{
snes_ram[0xb00000 + offset] = data;
int mask = (snes_cart.sram - 1) | 0xff0000; /* Limit SRAM size to what's actually present */
snes_ram[0x800000 + (offset & mask)] = data;
}
else /* Area in 0x6000-0x8000 && offset < 0x300000 is Reserved! */
logerror("snes_w_bank6: Attempt to write to reserved address: %X = %02x\n", offset + 0x800000, data);
@ -1579,16 +1580,7 @@ static void snes_init_ram( running_machine *machine )
{
snes_state *state = (snes_state *)machine->driver_data;
const address_space *cpu0space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
int i, j;
/* Init VRAM */
memset(snes_vram, 0, SNES_VRAM_SIZE);
/* Init Colour RAM */
memset((UINT8 *)snes_cgram, 0, SNES_CGRAM_SIZE);
/* Init oam RAM */
memset(snes_oam, 0xff, SNES_OAM_SIZE);
int i;
/* Init work RAM - 0x55 isn't exactly right but it's close */
/* make sure it happens to the 65816 (CPU 0) */
@ -1598,16 +1590,6 @@ static void snes_init_ram( running_machine *machine )
}
/* Inititialize registers/variables */
snes_ppu.update_windows = 1;
snes_ppu.beam.latch_vert = 0;
snes_ppu.beam.latch_horz = 0;
snes_ppu.beam.current_vert = 0;
snes_ppu.beam.current_horz = 0;
snes_ppu.beam.last_visible_line = 240;
snes_ppu.mode = 0;
snes_ppu.ppu1_version = 1; // 5C77 chip version number, read by STAT77, only '1' is known
snes_ppu.ppu2_version = 3; // 5C78 chip version number, read by STAT78, only '2' & '3' encountered so far.
state->cgram_address = 0;
state->vram_read_offset = 2;
state->read_ophct = 0;
@ -1620,15 +1602,6 @@ static void snes_init_ram( running_machine *machine )
state->oldjoy1_read = nss_oldjoy1_read;
state->oldjoy2_read = nss_oldjoy2_read;
/* Inititialize mosaic table */
for (j = 0; j < 16; j++)
{
for (i = 0; i < 4096; i++)
{
snes_ppu.mosaic_table[j][i] = (i / (j + 1)) * (j + 1);
}
}
// set up some known register power-up defaults
snes_ram[WRIO] = 0xff;
snes_ram[VMAIN] = 0x80;
@ -1673,13 +1646,9 @@ static void snes_init_ram( running_machine *machine )
// init frame counter so first line is 0
if (ATTOSECONDS_TO_HZ(video_screen_get_frame_period(machine->primary_screen).attoseconds) >= 59)
{
snes_ppu.beam.current_vert = SNES_VTOTAL_NTSC;
}
else
{
snes_ppu.beam.current_vert = SNES_VTOTAL_PAL;
}
}
@ -1698,9 +1667,8 @@ static DIRECT_UPDATE_HANDLER( snes_direct )
MACHINE_START( snes )
{
snes_state *state = (snes_state *)machine->driver_data;
snes_vram = auto_alloc_array(machine, UINT8, SNES_VRAM_SIZE);
snes_cgram = auto_alloc_array(machine, UINT16, SNES_CGRAM_SIZE/2);
snes_oam = auto_alloc_array(machine, UINT16, SNES_OAM_SIZE/2);
int i;
memory_set_direct_update_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), snes_direct);
memory_set_direct_update_handler(cputag_get_address_space(machine, "soundcpu", ADDRESS_SPACE_PROGRAM), spc_direct);
@ -1715,24 +1683,6 @@ MACHINE_START( snes )
snes_ram[WRDIVL] = 0xff;
snes_ram[WRDIVH] = 0xff;
/* init DMA regs to be 0xff */
{
int i;
for(i=0;i<8;i++)
{
state->dma_channel[i].dmap = 0xff;
state->dma_channel[i].dest_addr = 0xff;
state->dma_channel[i].src_addr = 0xffff;
state->dma_channel[i].bank = 0xff;
state->dma_channel[i].trans_size = 0xffff;
state->dma_channel[i].ibank = 0xff;
state->dma_channel[i].hdma_addr = 0xffff;
state->dma_channel[i].hdma_line_counter = 0xff;
state->dma_channel[i].unk = 0xff;
}
}
switch (snes_has_addon_chip)
{
case HAS_SDD1:
@ -1750,14 +1700,93 @@ MACHINE_START( snes )
}
snes_init_timers(machine);
for (i = 0; i < 6; i++)
{
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].dmap);
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].dest_addr);
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].src_addr);
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].bank);
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].trans_size);
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].ibank);
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].hdma_addr);
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].hdma_line_counter);
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].unk);
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].do_transfer);
state_save_register_item(machine, "snes_dma", NULL, i, state->dma_channel[i].dma_disabled);
}
state_save_register_global(machine, state->htmult);
state_save_register_global(machine, state->cgram_address);
state_save_register_global(machine, state->vram_read_offset);
state_save_register_global(machine, state->read_ophct);
state_save_register_global(machine, state->read_opvct);
state_save_register_global(machine, state->hblank_offset);
state_save_register_global(machine, state->vram_fgr_high);
state_save_register_global(machine, state->vram_fgr_increment);
state_save_register_global(machine, state->vram_fgr_count);
state_save_register_global(machine, state->vram_fgr_mask);
state_save_register_global(machine, state->vram_fgr_shift);
state_save_register_global(machine, state->vram_read_buffer);
state_save_register_global(machine, state->wram_address);
state_save_register_global(machine, state->htime);
state_save_register_global(machine, state->vtime);
state_save_register_global(machine, state->vmadd);
state_save_register_global(machine, state->hdmaen);
state_save_register_global(machine, state->joy1l);
state_save_register_global(machine, state->joy1h);
state_save_register_global(machine, state->joy2l);
state_save_register_global(machine, state->joy2h);
state_save_register_global(machine, state->joy3l);
state_save_register_global(machine, state->joy3h);
state_save_register_global(machine, state->joy4l);
state_save_register_global(machine, state->joy4h);
state_save_register_global_array(machine, state->data1);
state_save_register_global_array(machine, state->data2);
state_save_register_global_array(machine, state->read_idx);
for (i = 0; i < 2; i++)
{
state_save_register_item(machine, "snes_dma", NULL, i, state->joypad[i].buttons);
state_save_register_item(machine, "snes_dma", NULL, i, state->mouse[i].x);
state_save_register_item(machine, "snes_dma", NULL, i, state->mouse[i].oldx);
state_save_register_item(machine, "snes_dma", NULL, i, state->mouse[i].y);
state_save_register_item(machine, "snes_dma", NULL, i, state->mouse[i].oldy);
state_save_register_item(machine, "snes_dma", NULL, i, state->mouse[i].buttons);
state_save_register_item(machine, "snes_dma", NULL, i, state->mouse[i].deltax);
state_save_register_item(machine, "snes_dma", NULL, i, state->mouse[i].deltay);
state_save_register_item(machine, "snes_dma", NULL, i, state->mouse[i].speed);
state_save_register_item(machine, "snes_dma", NULL, i, state->scope[i].x);
state_save_register_item(machine, "snes_dma", NULL, i, state->scope[i].y);
state_save_register_item(machine, "snes_dma", NULL, i, state->scope[i].buttons);
state_save_register_item(machine, "snes_dma", NULL, i, state->scope[i].turbo_lock);
state_save_register_item(machine, "snes_dma", NULL, i, state->scope[i].pause_lock);
state_save_register_item(machine, "snes_dma", NULL, i, state->scope[i].fire_lock);
state_save_register_item(machine, "snes_dma", NULL, i, state->scope[i].offscreen);
}
}
MACHINE_RESET( snes )
{
snes_state *state = (snes_state *)machine->driver_data;
int i;
snes_init_ram(machine);
/* init DMA regs to be 0xff */
for(i = 0; i < 8; i++)
{
state->dma_channel[i].dmap = 0xff;
state->dma_channel[i].dest_addr = 0xff;
state->dma_channel[i].src_addr = 0xffff;
state->dma_channel[i].bank = 0xff;
state->dma_channel[i].trans_size = 0xffff;
state->dma_channel[i].ibank = 0xff;
state->dma_channel[i].hdma_addr = 0xffff;
state->dma_channel[i].hdma_line_counter = 0xff;
state->dma_channel[i].unk = 0xff;
}
/* Set STAT78 to NTSC or PAL */
if (ATTOSECONDS_TO_HZ(video_screen_get_frame_period(machine->primary_screen).attoseconds) >= 59.0f)
snes_ram[STAT78] = SNES_NTSC;
@ -1780,11 +1809,10 @@ DRIVER_INIT( snes )
{
const address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
UINT16 total_blocks, read_blocks;
UINT8 *rom;
UINT8 *rom;
rom = memory_region(machine, "user3");
snes_ram = auto_alloc_array(machine, UINT8, 0x1400000);
memset(snes_ram, 0, 0x1400000);
snes_ram = auto_alloc_array_clear(machine, UINT8, 0x1400000);
/* all NSS games seem to use MODE 20 */
snes_cart.mode = SNES_MODE_20;

View File

@ -131,6 +131,10 @@ enum
SNES_COLOR_DEPTH_8BPP
};
static UINT8 *snes_vram; /* Video RAM (Should be 16-bit, but it's easier this way) */
static UINT16 *snes_cgram; /* Colour RAM */
static UINT16 *snes_oam; /* Object Attribute Memory */
/*****************************************
* snes_get_bgcolor()
*
@ -1655,9 +1659,134 @@ static void snes_refresh_scanline( running_machine *machine, bitmap_t *bitmap, U
VIDEO_START( snes )
{
int i,j;
#ifdef SNES_LAYER_DEBUG
memset(&debug_options, 0, sizeof(debug_options));
#endif
snes_vram = auto_alloc_array(machine, UINT8, SNES_VRAM_SIZE);
snes_cgram = auto_alloc_array(machine, UINT16, SNES_CGRAM_SIZE/2);
snes_oam = auto_alloc_array(machine, UINT16, SNES_OAM_SIZE/2);
/* Inititialize registers/variables */
snes_ppu.update_windows = 1;
snes_ppu.beam.latch_vert = 0;
snes_ppu.beam.latch_horz = 0;
snes_ppu.beam.current_vert = 0;
snes_ppu.beam.current_horz = 0;
snes_ppu.beam.last_visible_line = 240;
snes_ppu.mode = 0;
snes_ppu.ppu1_version = 1; // 5C77 chip version number, read by STAT77, only '1' is known
snes_ppu.ppu2_version = 3; // 5C78 chip version number, read by STAT78, only '2' & '3' encountered so far.
/* Inititialize mosaic table */
for (j = 0; j < 16; j++)
{
for (i = 0; i < 4096; i++)
snes_ppu.mosaic_table[j][i] = (i / (j + 1)) * (j + 1);
}
/* Init VRAM */
memset(snes_vram, 0, SNES_VRAM_SIZE);
/* Init Colour RAM */
memset((UINT8 *)snes_cgram, 0, SNES_CGRAM_SIZE);
/* Init oam RAM */
memset(snes_oam, 0xff, SNES_OAM_SIZE);
for (i = 0; i < 6; i++)
{
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].window1_enabled);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].window1_invert);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].window2_enabled);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].window2_invert);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].wlog_mask);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].color_math);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].charmap);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].tilemap);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].tilemap_size);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].tile_size);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].mosaic_enabled);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].main_window_enabled);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].sub_window_enabled);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].main_bg_enabled);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].sub_bg_enabled);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].hoffs);
state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].voffs);
state_save_register_item_array(machine, "snes_ppu", NULL, i, snes_ppu.clipmasks[i]);
}
state_save_register_global(machine, snes_ppu.oam.address_low);
state_save_register_global(machine, snes_ppu.oam.address_high);
state_save_register_global(machine, snes_ppu.oam.saved_address_low);
state_save_register_global(machine, snes_ppu.oam.saved_address_high);
state_save_register_global(machine, snes_ppu.oam.address);
state_save_register_global(machine, snes_ppu.oam.priority_rotation);
state_save_register_global(machine, snes_ppu.oam.next_charmap);
state_save_register_global(machine, snes_ppu.oam.next_size);
state_save_register_global(machine, snes_ppu.oam.size);
state_save_register_global(machine, snes_ppu.oam.next_name_select);
state_save_register_global(machine, snes_ppu.oam.name_select);
state_save_register_global(machine, snes_ppu.oam.first_sprite);
state_save_register_global(machine, snes_ppu.oam.flip);
state_save_register_global(machine, snes_ppu.oam.write_latch);
state_save_register_global(machine, snes_ppu.beam.latch_horz);
state_save_register_global(machine, snes_ppu.beam.latch_vert);
state_save_register_global(machine, snes_ppu.beam.current_horz);
state_save_register_global(machine, snes_ppu.beam.current_vert);
state_save_register_global(machine, snes_ppu.beam.last_visible_line);
state_save_register_global(machine, snes_ppu.beam.interlace_count);
state_save_register_global(machine, snes_ppu.mode7.repeat);
state_save_register_global(machine, snes_ppu.mode7.hflip);
state_save_register_global(machine, snes_ppu.mode7.vflip);
state_save_register_global(machine, snes_ppu.mode7.matrix_a);
state_save_register_global(machine, snes_ppu.mode7.matrix_b);
state_save_register_global(machine, snes_ppu.mode7.matrix_c);
state_save_register_global(machine, snes_ppu.mode7.matrix_d);
state_save_register_global(machine, snes_ppu.mode7.origin_x);
state_save_register_global(machine, snes_ppu.mode7.origin_y);
state_save_register_global(machine, snes_ppu.mode7.hor_offset);
state_save_register_global(machine, snes_ppu.mode7.ver_offset);
state_save_register_global(machine, snes_ppu.mode7.extbg);
state_save_register_global(machine, snes_ppu.mosaic_size);
state_save_register_global(machine, snes_ppu.clip_to_black);
state_save_register_global(machine, snes_ppu.prevent_color_math);
state_save_register_global(machine, snes_ppu.sub_add_mode);
state_save_register_global(machine, snes_ppu.bg3_priority_bit);
state_save_register_global(machine, snes_ppu.direct_color);
state_save_register_global(machine, snes_ppu.ppu_last_scroll);
state_save_register_global(machine, snes_ppu.mode7_last_scroll);
state_save_register_global(machine, snes_ppu.ppu1_open_bus);
state_save_register_global(machine, snes_ppu.ppu2_open_bus);
state_save_register_global(machine, snes_ppu.ppu1_version);
state_save_register_global(machine, snes_ppu.ppu2_version);
state_save_register_global(machine, snes_ppu.window1_left);
state_save_register_global(machine, snes_ppu.window1_right);
state_save_register_global(machine, snes_ppu.window2_left);
state_save_register_global(machine, snes_ppu.window2_right);
state_save_register_global(machine, snes_ppu.update_windows);
state_save_register_global(machine, snes_ppu.update_offsets);
state_save_register_global(machine, snes_ppu.update_oam_list);
state_save_register_global(machine, snes_ppu.mode);
state_save_register_global(machine, snes_ppu.interlace);
state_save_register_global(machine, snes_ppu.obj_interlace);
state_save_register_global(machine, snes_ppu.screen_brightness);
state_save_register_global(machine, snes_ppu.screen_disabled);
state_save_register_global(machine, snes_ppu.pseudo_hires);
state_save_register_global(machine, snes_ppu.color_modes);
state_save_register_global(machine, snes_ppu.stat77_flags);
state_save_register_global_pointer(machine, snes_vram, SNES_VRAM_SIZE);
state_save_register_global_pointer(machine, snes_cgram, SNES_CGRAM_SIZE/2);
state_save_register_global_pointer(machine, snes_oam, SNES_OAM_SIZE/2);
}
VIDEO_UPDATE( snes )