let's try to untangle a bit the knots between machine and PPU (part 1)... nw.

This commit is contained in:
Fabio Priuli 2013-03-04 09:38:04 +00:00
parent 3e79433502
commit e5f45e064d
4 changed files with 873 additions and 862 deletions

View File

@ -368,6 +368,160 @@
#define DSP_FIR_C6 0x6F #define DSP_FIR_C6 0x6F
#define DSP_FIR_C7 0x7F #define DSP_FIR_C7 0x7F
/* (PPU) Video related */
class snes_ppu_class /* once all the regs are saved in this structure, it would be better to reorganize it a bit... */
{
public:
struct
{
/* clipmasks */
UINT8 window1_enabled, window1_invert;
UINT8 window2_enabled, window2_invert;
UINT8 wlog_mask;
/* color math enabled */
UINT8 color_math;
UINT8 charmap;
UINT8 tilemap;
UINT8 tilemap_size;
UINT8 tile_size;
UINT8 mosaic_enabled; // actually used only for layers 0->3!
UINT8 main_window_enabled;
UINT8 sub_window_enabled;
UINT8 main_bg_enabled;
UINT8 sub_bg_enabled;
UINT16 hoffs;
UINT16 voffs;
} m_layer[6]; // this is for the BG1 - BG2 - BG3 - BG4 - OBJ - color layers
struct
{
UINT8 address_low;
UINT8 address_high;
UINT8 saved_address_low;
UINT8 saved_address_high;
UINT16 address;
UINT16 priority_rotation;
UINT8 next_charmap;
UINT8 next_size;
UINT8 size;
UINT32 next_name_select;
UINT32 name_select;
UINT8 first_sprite;
UINT8 flip;
UINT16 write_latch;
} m_oam;
struct
{
UINT16 horizontal[4];
UINT16 vertical[4];
} m_bgd_offset;
struct
{
UINT16 latch_horz;
UINT16 latch_vert;
UINT16 current_horz;
UINT16 current_vert;
UINT8 last_visible_line;
UINT8 interlace_count;
} m_beam;
struct
{
UINT8 repeat;
UINT8 hflip;
UINT8 vflip;
INT16 matrix_a;
INT16 matrix_b;
INT16 matrix_c;
INT16 matrix_d;
INT16 origin_x;
INT16 origin_y;
UINT16 hor_offset;
UINT16 ver_offset;
UINT8 extbg;
} m_mode7;
UINT8 m_mosaic_size;
UINT8 m_clip_to_black;
UINT8 m_prevent_color_math;
UINT8 m_sub_add_mode;
UINT8 m_bg3_priority_bit;
UINT8 m_direct_color;
UINT8 m_ppu_last_scroll; /* as per Anomie's doc and Theme Park, all scroll regs shares (but mode 7 ones) the same
'previous' scroll value */
UINT8 m_mode7_last_scroll; /* as per Anomie's doc mode 7 scroll regs use a different value, shared with mode 7 matrix! */
UINT8 m_ppu1_open_bus, m_ppu2_open_bus;
UINT8 m_ppu1_version, m_ppu2_version;
UINT8 m_window1_left, m_window1_right, m_window2_left, m_window2_right;
UINT16 m_mosaic_table[16][4096];
UINT8 m_clipmasks[6][SNES_SCR_WIDTH];
UINT8 m_update_windows;
UINT8 m_update_offsets;
UINT8 m_update_oam_list;
UINT8 m_mode;
UINT8 m_interlace; //doubles the visible resolution
UINT8 m_obj_interlace;
UINT8 m_screen_brightness;
UINT8 m_screen_disabled;
UINT8 m_pseudo_hires;
UINT8 m_color_modes;
UINT8 m_stat77_flags;
inline UINT16 snes_get_bgcolor(UINT8 direct_colors, UINT16 palette, UINT8 color);
inline void snes_set_scanline_pixel(int screen, INT16 x, UINT16 color, UINT8 priority, UINT8 layer, int blend);
inline void snes_draw_bgtile_lores(UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority);
inline void snes_draw_bgtile_hires(UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority);
inline void snes_draw_oamtile(INT16 ii, UINT8 colour, UINT16 pal, UINT8 priority);
inline void snes_draw_tile(UINT8 planes, UINT8 layer, UINT32 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT8 direct_colors, UINT16 pal, UINT8 hires);
inline UINT32 snes_get_tmap_addr(UINT8 layer, UINT8 tile_size, UINT32 base, UINT32 x, UINT32 y);
inline void snes_update_line(UINT16 curline, UINT8 layer, UINT8 priority_b, UINT8 priority_a, UINT8 color_depth, UINT8 hires, UINT8 offset_per_tile, UINT8 direct_colors);
void snes_update_line_mode7(UINT16 curline, UINT8 layer, UINT8 priority_b, UINT8 priority_a);
void snes_update_obsel(void);
void snes_oam_list_build(void);
int is_sprite_on_scanline(UINT16 curline, UINT8 sprite);
void snes_update_objects_rto(UINT16 curline);
void snes_update_objects(UINT8 priority_oam0, UINT8 priority_oam1, UINT8 priority_oam2, UINT8 priority_oam3);
void snes_update_mode_0(UINT16 curline);
void snes_update_mode_1(UINT16 curline);
void snes_update_mode_2(UINT16 curline);
void snes_update_mode_3(UINT16 curline);
void snes_update_mode_4(UINT16 curline);
void snes_update_mode_5(UINT16 curline);
void snes_update_mode_6(UINT16 curline);
void snes_update_mode_7(UINT16 curline);
void snes_draw_screens(UINT16 curline);
void snes_update_windowmasks(void);
void snes_update_offsets(void);
inline void snes_draw_blend(UINT16 offset, UINT16 *colour, UINT8 prevent_color_math, UINT8 black_pen_clip, int switch_screens);
void snes_refresh_scanline(running_machine &machine, bitmap_rgb32 &bitmap, UINT16 curline);
UINT8 snes_ppu_read(address_space &space, UINT32 offset, UINT8 *ram_ptr);
void snes_ppu_write(address_space &space, UINT32 offset, UINT8 data, UINT8 *ram_ptr);
void snes_latch_counters(running_machine &machine, UINT8 *ram_ptr);
void snes_dynamic_res_change(running_machine &machine, UINT8 *ram_ptr);
inline UINT32 snes_get_vram_address(running_machine &machine);
UINT8 snes_dbg_video(running_machine &machine, UINT16 curline, UINT8 *ram_ptr);
void ppu_start(running_machine &machine);
DECLARE_READ8_MEMBER( snes_oam_read );
DECLARE_WRITE8_MEMBER( snes_oam_write );
DECLARE_READ8_MEMBER( snes_cgram_read );
DECLARE_WRITE8_MEMBER( snes_cgram_write );
DECLARE_READ8_MEMBER( snes_vram_read );
DECLARE_WRITE8_MEMBER( snes_vram_write );
UINT16 *m_oam_ram; /* Object Attribute Memory */
UINT16 *m_cgram; /* Palette RAM */
UINT8 *m_vram; /* Video RAM (TODO: Should be 16-bit, but it's easier this way) */
};
struct snes_cart_info struct snes_cart_info
{ {
UINT8 mode; /* ROM memory mode */ UINT8 mode; /* ROM memory mode */
@ -408,7 +562,6 @@ public:
: driver_device(mconfig, type, tag) : driver_device(mconfig, type, tag)
{ } { }
/* misc */ /* misc */
UINT16 m_htmult; /* in 512 wide, we run HTOTAL double and halve it on latching */ UINT16 m_htmult; /* in 512 wide, we run HTOTAL double and halve it on latching */
UINT16 m_cgram_address; /* CGRAM address */ UINT16 m_cgram_address; /* CGRAM address */
@ -489,6 +642,9 @@ public:
UINT32 m_cart_size; UINT32 m_cart_size;
snes_cart_info m_cart[2]; // the second one is used by MESS for Sufami Turbo and, eventually, BS-X snes_cart_info m_cart[2]; // the second one is used by MESS for Sufami Turbo and, eventually, BS-X
snes_ppu_class m_ppu;
UINT32 snes_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
/* devices */ /* devices */
_5a22_device *m_maincpu; _5a22_device *m_maincpu;
spc700_device *m_soundcpu; spc700_device *m_soundcpu;
@ -504,45 +660,6 @@ public:
DECLARE_DRIVER_INIT(snes_mess); DECLARE_DRIVER_INIT(snes_mess);
DECLARE_DRIVER_INIT(snesst); DECLARE_DRIVER_INIT(snesst);
inline UINT16 snes_get_bgcolor( UINT8 direct_colors, UINT16 palette, UINT8 color );
inline void snes_set_scanline_pixel( int screen, INT16 x, UINT16 color, UINT8 priority, UINT8 layer, int blend );
inline void snes_draw_bgtile_lores( UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority );
inline void snes_draw_bgtile_hires( UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority );
inline void snes_draw_oamtile( INT16 ii, UINT8 colour, UINT16 pal, UINT8 priority );
inline void snes_draw_tile( UINT8 planes, UINT8 layer, UINT32 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT8 direct_colors, UINT16 pal, UINT8 hires );
inline UINT32 snes_get_tmap_addr( UINT8 layer, UINT8 tile_size, UINT32 base, UINT32 x, UINT32 y );
inline void snes_update_line( UINT16 curline, UINT8 layer, UINT8 priority_b, UINT8 priority_a, UINT8 color_depth, UINT8 hires, UINT8 offset_per_tile, UINT8 direct_colors );
void snes_update_line_mode7( UINT16 curline, UINT8 layer, UINT8 priority_b, UINT8 priority_a );
void snes_update_obsel( void );
void snes_oam_list_build( void );
int is_sprite_on_scanline( UINT16 curline, UINT8 sprite );
void snes_update_objects_rto( UINT16 curline );
void snes_update_objects( UINT8 priority_oam0, UINT8 priority_oam1, UINT8 priority_oam2, UINT8 priority_oam3 );
void snes_update_mode_0( UINT16 curline );
void snes_update_mode_1( UINT16 curline );
void snes_update_mode_2( UINT16 curline );
void snes_update_mode_3( UINT16 curline );
void snes_update_mode_4( UINT16 curline );
void snes_update_mode_5( UINT16 curline );
void snes_update_mode_6( UINT16 curline );
void snes_update_mode_7( UINT16 curline );
void snes_draw_screens( UINT16 curline );
void snes_update_windowmasks( void );
void snes_update_offsets( void );
inline void snes_draw_blend( UINT16 offset, UINT16 *colour, UINT8 prevent_color_math, UINT8 black_pen_clip, int switch_screens );
void snes_refresh_scanline( running_machine &machine, bitmap_rgb32 &bitmap, UINT16 curline );
UINT32 snes_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_READ8_MEMBER( snes_oam_read );
DECLARE_WRITE8_MEMBER( snes_oam_write );
DECLARE_READ8_MEMBER( snes_cgram_read );
DECLARE_WRITE8_MEMBER( snes_cgram_write );
DECLARE_READ8_MEMBER( snes_vram_read );
DECLARE_WRITE8_MEMBER( snes_vram_write );
UINT16 *m_snes_oam; /* Object Attribute Memory */
UINT16 *m_snes_cgram; /* Palette RAM */
UINT8 *m_snes_vram; /* Video RAM (TODO: Should be 16-bit, but it's easier this way) */
TIMER_CALLBACK_MEMBER(snes_nmi_tick); TIMER_CALLBACK_MEMBER(snes_nmi_tick);
TIMER_CALLBACK_MEMBER(snes_hirq_tick_callback); TIMER_CALLBACK_MEMBER(snes_hirq_tick_callback);
@ -636,125 +753,13 @@ extern DECLARE_WRITE8_HANDLER( superfx_w_bank3 );
extern UINT8 *snes_ram; /* Main 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
{
/* clipmasks */
UINT8 window1_enabled, window1_invert;
UINT8 window2_enabled, window2_invert;
UINT8 wlog_mask;
/* color math enabled */
UINT8 color_math;
UINT8 charmap;
UINT8 tilemap;
UINT8 tilemap_size;
UINT8 tile_size;
UINT8 mosaic_enabled; // actually used only for layers 0->3!
UINT8 main_window_enabled;
UINT8 sub_window_enabled;
UINT8 main_bg_enabled;
UINT8 sub_bg_enabled;
UINT16 hoffs;
UINT16 voffs;
} layer[6]; // this is for the BG1 - BG2 - BG3 - BG4 - OBJ - color layers
struct
{
UINT8 address_low;
UINT8 address_high;
UINT8 saved_address_low;
UINT8 saved_address_high;
UINT16 address;
UINT16 priority_rotation;
UINT8 next_charmap;
UINT8 next_size;
UINT8 size;
UINT32 next_name_select;
UINT32 name_select;
UINT8 first_sprite;
UINT8 flip;
UINT16 write_latch;
} oam;
struct
{
UINT16 horizontal[4];
UINT16 vertical[4];
} bgd_offset;
struct
{
UINT16 latch_horz;
UINT16 latch_vert;
UINT16 current_horz;
UINT16 current_vert;
UINT8 last_visible_line;
UINT8 interlace_count;
} beam;
struct
{
UINT8 repeat;
UINT8 hflip;
UINT8 vflip;
INT16 matrix_a;
INT16 matrix_b;
INT16 matrix_c;
INT16 matrix_d;
INT16 origin_x;
INT16 origin_y;
UINT16 hor_offset;
UINT16 ver_offset;
UINT8 extbg;
} mode7;
UINT8 mosaic_size;
UINT8 clip_to_black;
UINT8 prevent_color_math;
UINT8 sub_add_mode;
UINT8 bg3_priority_bit;
UINT8 direct_color;
UINT8 ppu_last_scroll; /* as per Anomie's doc and Theme Park, all scroll regs shares (but mode 7 ones) the same
'previous' scroll value */
UINT8 mode7_last_scroll; /* as per Anomie's doc mode 7 scroll regs use a different value, shared with mode 7 matrix! */
UINT8 ppu1_open_bus, ppu2_open_bus;
UINT8 ppu1_version, ppu2_version;
UINT8 window1_left, window1_right, window2_left, window2_right;
UINT16 mosaic_table[16][4096];
UINT8 clipmasks[6][SNES_SCR_WIDTH];
UINT8 update_windows;
UINT8 update_offsets;
UINT8 update_oam_list;
UINT8 mode;
UINT8 interlace; //doubles the visible resolution
UINT8 obj_interlace;
UINT8 screen_brightness;
UINT8 screen_disabled;
UINT8 pseudo_hires;
UINT8 color_modes;
UINT8 stat77_flags;
};
extern struct snes_cart_info snes_cart; extern struct snes_cart_info snes_cart;
/*----------- defined in video/snes.c -----------*/ /*----------- defined in video/snes.c -----------*/
extern struct SNES_PPU_STRUCT snes_ppu;
extern void snes_latch_counters(running_machine &machine);
extern VIDEO_START( snes ); extern VIDEO_START( snes );
extern SCREEN_UPDATE_RGB32( snes ); extern SCREEN_UPDATE_RGB32( snes );
extern DECLARE_READ8_HANDLER( snes_ppu_read );
extern DECLARE_WRITE8_HANDLER( snes_ppu_write );
#endif /* _SNES_H_ */ #endif /* _SNES_H_ */

View File

@ -116,7 +116,7 @@ static void snes_hirq_tick( running_machine &machine )
// latch the counters and pull IRQ // latch the counters and pull IRQ
// (don't need to switch to the 65816 context, we don't do anything dependant on it) // (don't need to switch to the 65816 context, we don't do anything dependant on it)
snes_latch_counters(machine); state->m_ppu.snes_latch_counters(machine, snes_ram);
snes_ram[TIMEUP] = 0x80; /* Indicate that irq occurred */ snes_ram[TIMEUP] = 0x80; /* Indicate that irq occurred */
state->m_maincpu->set_input_line(G65816_LINE_IRQ, ASSERT_LINE); state->m_maincpu->set_input_line(G65816_LINE_IRQ, ASSERT_LINE);
@ -134,11 +134,11 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_reset_oam_address)
// make sure we're in the 65816's context since we're messing with the OAM and stuff // make sure we're in the 65816's context since we're messing with the OAM and stuff
address_space &space = m_maincpu->space(AS_PROGRAM); address_space &space = m_maincpu->space(AS_PROGRAM);
if (!(snes_ppu.screen_disabled)) //Reset OAM address, byuu says it happens at H=10 if (!(m_ppu.m_screen_disabled)) //Reset OAM address, byuu says it happens at H=10
{ {
space.write_byte(OAMADDL, snes_ppu.oam.saved_address_low); /* Reset oam address */ space.write_byte(OAMADDL, m_ppu.m_oam.saved_address_low); /* Reset oam address */
space.write_byte(OAMADDH, snes_ppu.oam.saved_address_high); space.write_byte(OAMADDH, m_ppu.m_oam.saved_address_high);
snes_ppu.oam.first_sprite = snes_ppu.oam.priority_rotation ? (snes_ppu.oam.address >> 1) & 127 : 0; m_ppu.m_oam.first_sprite = m_ppu.m_oam.priority_rotation ? (m_ppu.m_oam.address >> 1) & 127 : 0;
} }
} }
@ -160,7 +160,7 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_update_io)
TIMER_CALLBACK_MEMBER(snes_state::snes_scanline_tick) TIMER_CALLBACK_MEMBER(snes_state::snes_scanline_tick)
{ {
/* Increase current line - we want to latch on this line during it, not after it */ /* Increase current line - we want to latch on this line during it, not after it */
snes_ppu.beam.current_vert = machine().primary_screen->vpos(); m_ppu.m_beam.current_vert = machine().primary_screen->vpos();
// not in hblank // not in hblank
snes_ram[HVBJOY] &= ~0x40; snes_ram[HVBJOY] &= ~0x40;
@ -168,11 +168,11 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_scanline_tick)
/* Vertical IRQ timer - only if horizontal isn't also enabled! */ /* Vertical IRQ timer - only if horizontal isn't also enabled! */
if ((snes_ram[NMITIMEN] & 0x20) && !(snes_ram[NMITIMEN] & 0x10)) if ((snes_ram[NMITIMEN] & 0x20) && !(snes_ram[NMITIMEN] & 0x10))
{ {
if (snes_ppu.beam.current_vert == m_vtime) if (m_ppu.m_beam.current_vert == m_vtime)
{ {
snes_ram[TIMEUP] = 0x80; /* Indicate that irq occurred */ snes_ram[TIMEUP] = 0x80; /* Indicate that irq occurred */
// IRQ latches the counters, do it now // IRQ latches the counters, do it now
snes_latch_counters(machine()); m_ppu.snes_latch_counters(machine(), snes_ram);
m_maincpu->set_input_line(G65816_LINE_IRQ, ASSERT_LINE ); m_maincpu->set_input_line(G65816_LINE_IRQ, ASSERT_LINE );
} }
} }
@ -185,7 +185,7 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_scanline_tick)
// is the HIRQ on a specific scanline? // is the HIRQ on a specific scanline?
if (snes_ram[NMITIMEN] & 0x20) if (snes_ram[NMITIMEN] & 0x20)
{ {
if (snes_ppu.beam.current_vert != m_vtime) if (m_ppu.m_beam.current_vert != m_vtime)
{ {
setirq = 0; setirq = 0;
} }
@ -193,22 +193,22 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_scanline_tick)
if (setirq) if (setirq)
{ {
// printf("HIRQ @ %d, %d\n", pixel * m_htmult, snes_ppu.beam.current_vert); // printf("HIRQ @ %d, %d\n", pixel * m_htmult, m_ppu.m_beam.current_vert);
if (pixel == 0) if (pixel == 0)
{ {
snes_hirq_tick(machine()); snes_hirq_tick(machine());
} }
else else
{ {
m_hirq_timer->adjust(machine().primary_screen->time_until_pos(snes_ppu.beam.current_vert, pixel * m_htmult)); m_hirq_timer->adjust(machine().primary_screen->time_until_pos(m_ppu.m_beam.current_vert, pixel * m_htmult));
} }
} }
} }
/* Start of VBlank */ /* Start of VBlank */
if (snes_ppu.beam.current_vert == snes_ppu.beam.last_visible_line) if (m_ppu.m_beam.current_vert == m_ppu.m_beam.last_visible_line)
{ {
machine().scheduler().timer_set(machine().primary_screen->time_until_pos(snes_ppu.beam.current_vert, 10), timer_expired_delegate(FUNC(snes_state::snes_reset_oam_address),this)); machine().scheduler().timer_set(machine().primary_screen->time_until_pos(m_ppu.m_beam.current_vert, 10), timer_expired_delegate(FUNC(snes_state::snes_reset_oam_address),this));
snes_ram[HVBJOY] |= 0x81; /* Set vblank bit to on & indicate controllers being read */ snes_ram[HVBJOY] |= 0x81; /* Set vblank bit to on & indicate controllers being read */
snes_ram[RDNMI] |= 0x80; /* Set NMI occurred bit */ snes_ram[RDNMI] |= 0x80; /* Set NMI occurred bit */
@ -220,30 +220,30 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_scanline_tick)
} }
/* three lines after start of vblank we update the controllers (value from snes9x) */ /* three lines after start of vblank we update the controllers (value from snes9x) */
m_io_timer->adjust(machine().primary_screen->time_until_pos(snes_ppu.beam.current_vert + 2, m_hblank_offset * m_htmult)); m_io_timer->adjust(machine().primary_screen->time_until_pos(m_ppu.m_beam.current_vert + 2, m_hblank_offset * m_htmult));
} }
// hdma reset happens at scanline 0, H=~6 // hdma reset happens at scanline 0, H=~6
if (snes_ppu.beam.current_vert == 0) if (m_ppu.m_beam.current_vert == 0)
{ {
address_space &cpu0space = m_maincpu->space(AS_PROGRAM); address_space &cpu0space = m_maincpu->space(AS_PROGRAM);
snes_hdma_init(cpu0space); snes_hdma_init(cpu0space);
} }
if (snes_ppu.beam.current_vert == 0) if (m_ppu.m_beam.current_vert == 0)
{ /* VBlank is over, time for a new frame */ { /* VBlank is over, time for a new frame */
snes_ram[HVBJOY] &= 0x7f; /* Clear vblank bit */ snes_ram[HVBJOY] &= 0x7f; /* Clear vblank bit */
snes_ram[RDNMI] &= 0x7f; /* Clear nmi occurred bit */ snes_ram[RDNMI] &= 0x7f; /* Clear nmi occurred bit */
snes_ram[STAT78] ^= 0x80; /* Toggle field flag */ snes_ram[STAT78] ^= 0x80; /* Toggle field flag */
snes_ppu.stat77_flags &= 0x3f; /* Clear Time Over and Range Over bits */ m_ppu.m_stat77_flags &= 0x3f; /* Clear Time Over and Range Over bits */
m_maincpu->set_input_line(G65816_LINE_NMI, CLEAR_LINE ); m_maincpu->set_input_line(G65816_LINE_NMI, CLEAR_LINE );
} }
m_scanline_timer->adjust(attotime::never); m_scanline_timer->adjust(attotime::never);
m_hblank_timer->adjust(machine().primary_screen->time_until_pos(snes_ppu.beam.current_vert, m_hblank_offset * m_htmult)); m_hblank_timer->adjust(machine().primary_screen->time_until_pos(m_ppu.m_beam.current_vert, m_hblank_offset * m_htmult));
// printf("%02x %d\n",snes_ram[HVBJOY],snes_ppu.beam.current_vert); // printf("%02x %d\n",snes_ram[HVBJOY],m_ppu.m_beam.current_vert);
} }
/* This is called at the start of hblank *before* the scanline indicated in current_vert! */ /* This is called at the start of hblank *before* the scanline indicated in current_vert! */
@ -252,13 +252,13 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_hblank_tick)
address_space &cpu0space = m_maincpu->space(AS_PROGRAM); address_space &cpu0space = m_maincpu->space(AS_PROGRAM);
int nextscan; int nextscan;
snes_ppu.beam.current_vert = machine().primary_screen->vpos(); m_ppu.m_beam.current_vert = machine().primary_screen->vpos();
/* make sure we halt */ /* make sure we halt */
m_hblank_timer->adjust(attotime::never); m_hblank_timer->adjust(attotime::never);
/* draw a scanline */ /* draw a scanline */
if (snes_ppu.beam.current_vert <= snes_ppu.beam.last_visible_line) if (m_ppu.m_beam.current_vert <= m_ppu.m_beam.last_visible_line)
{ {
if (machine().primary_screen->vpos() > 0) if (machine().primary_screen->vpos() > 0)
{ {
@ -266,7 +266,7 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_hblank_tick)
if (snes_ram[HDMAEN]) if (snes_ram[HDMAEN])
snes_hdma(cpu0space); snes_hdma(cpu0space);
machine().primary_screen->update_partial((snes_ppu.interlace == 2) ? (snes_ppu.beam.current_vert * snes_ppu.interlace) : snes_ppu.beam.current_vert - 1); machine().primary_screen->update_partial((m_ppu.m_interlace == 2) ? (m_ppu.m_beam.current_vert * m_ppu.m_interlace) : m_ppu.m_beam.current_vert - 1);
} }
} }
@ -274,7 +274,7 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_hblank_tick)
snes_ram[HVBJOY] |= 0x40; snes_ram[HVBJOY] |= 0x40;
/* kick off the start of scanline timer */ /* kick off the start of scanline timer */
nextscan = snes_ppu.beam.current_vert + 1; nextscan = m_ppu.m_beam.current_vert + 1;
if (nextscan >= (((snes_ram[STAT78] & 0x10) == SNES_NTSC) ? SNES_VTOTAL_NTSC : SNES_VTOTAL_PAL)) if (nextscan >= (((snes_ram[STAT78] & 0x10) == SNES_NTSC) ? SNES_VTOTAL_NTSC : SNES_VTOTAL_PAL))
{ {
nextscan = 0; nextscan = 0;
@ -428,7 +428,7 @@ READ8_HANDLER( snes_r_io )
// PPU accesses are from 2100 to 213f // PPU accesses are from 2100 to 213f
if (offset >= INIDISP && offset < APU00) if (offset >= INIDISP && offset < APU00)
{ {
return snes_ppu_read(space, offset); return state->m_ppu.snes_ppu_read(space, offset, snes_ram);
} }
// APU is mirrored from 2140 to 217f // APU is mirrored from 2140 to 217f
@ -589,7 +589,7 @@ WRITE8_HANDLER( snes_w_io )
// PPU accesses are from 2100 to 213f // PPU accesses are from 2100 to 213f
if (offset >= INIDISP && offset < APU00) if (offset >= INIDISP && offset < APU00)
{ {
snes_ppu_write(space, offset, data); state->m_ppu.snes_ppu_write(space, offset, data, snes_ram);
return; return;
} }
@ -690,7 +690,7 @@ WRITE8_HANDLER( snes_w_io )
if (!(snes_ram[WRIO] & 0x80) && (data & 0x80)) if (!(snes_ram[WRIO] & 0x80) && (data & 0x80))
{ {
// external latch // external latch
snes_latch_counters(space.machine()); state->m_ppu.snes_latch_counters(space.machine(), snes_ram);
} }
break; break;
case HTIMEL: /* H-Count timer settings (low) */ case HTIMEL: /* H-Count timer settings (low) */
@ -715,7 +715,7 @@ WRITE8_HANDLER( snes_w_io )
break; break;
case HDMAEN: /* HDMA channel designation */ case HDMAEN: /* HDMA channel designation */
if (data) //if a HDMA is enabled, data is inited at the next scanline if (data) //if a HDMA is enabled, data is inited at the next scanline
space.machine().scheduler().timer_set(space.machine().primary_screen->time_until_pos(snes_ppu.beam.current_vert + 1), timer_expired_delegate(FUNC(snes_state::snes_reset_hdma),state)); space.machine().scheduler().timer_set(space.machine().primary_screen->time_until_pos(state->m_ppu.m_beam.current_vert + 1), timer_expired_delegate(FUNC(snes_state::snes_reset_hdma),state));
break; break;
case TIMEUP: // IRQ Flag is cleared on both read and write case TIMEUP: // IRQ Flag is cleared on both read and write
state->m_maincpu->set_input_line(G65816_LINE_IRQ, CLEAR_LINE ); state->m_maincpu->set_input_line(G65816_LINE_IRQ, CLEAR_LINE );
@ -1656,9 +1656,9 @@ static void snes_init_ram( running_machine &machine )
// init frame counter so first line is 0 // init frame counter so first line is 0
if (ATTOSECONDS_TO_HZ(machine.primary_screen->frame_period().attoseconds) >= 59) if (ATTOSECONDS_TO_HZ(machine.primary_screen->frame_period().attoseconds) >= 59)
snes_ppu.beam.current_vert = SNES_VTOTAL_NTSC; state->m_ppu.m_beam.current_vert = SNES_VTOTAL_NTSC;
else else
snes_ppu.beam.current_vert = SNES_VTOTAL_PAL; state->m_ppu.m_beam.current_vert = SNES_VTOTAL_PAL;
} }
#if 0 #if 0
@ -1813,8 +1813,8 @@ MACHINE_RESET( snes )
state->m_vtime = 0x1ff; state->m_vtime = 0x1ff;
state->m_htmult = 1; state->m_htmult = 1;
snes_ppu.interlace = 1; state->m_ppu.m_interlace = 1;
snes_ppu.obj_interlace = 1; state->m_ppu.m_obj_interlace = 1;
} }

File diff suppressed because it is too large Load Diff

View File

@ -142,7 +142,7 @@ static CUSTOM_INPUT( snes_superscope_offscreen_input )
INT16 y = field.machine().root_device().ioport(portnames[port][2])->read(); INT16 y = field.machine().root_device().ioport(portnames[port][2])->read();
/* these are the theoretical boundaries, but we currently are always onscreen... */ /* these are the theoretical boundaries, but we currently are always onscreen... */
if (x < 0 || x >= SNES_SCR_WIDTH || y < 0 || y >= snes_ppu.beam.last_visible_line) if (x < 0 || x >= SNES_SCR_WIDTH || y < 0 || y >= state->m_ppu.m_beam.last_visible_line)
state->m_scope[port].offscreen = 1; state->m_scope[port].offscreen = 1;
else else
state->m_scope[port].offscreen = 0; state->m_scope[port].offscreen = 0;
@ -377,6 +377,7 @@ INPUT_PORTS_END
static void snes_gun_latch( running_machine &machine, INT16 x, INT16 y ) static void snes_gun_latch( running_machine &machine, INT16 x, INT16 y )
{ {
snes_state *state = machine.driver_data<snes_state>();
/* these are the theoretical boundaries */ /* these are the theoretical boundaries */
if (x < 0) if (x < 0)
x = 0; x = 0;
@ -385,11 +386,11 @@ static void snes_gun_latch( running_machine &machine, INT16 x, INT16 y )
if (y < 0) if (y < 0)
y = 0; y = 0;
if (y > (snes_ppu.beam.last_visible_line - 1)) if (y > (state->m_ppu.m_beam.last_visible_line - 1))
y = snes_ppu.beam.last_visible_line - 1; y = state->m_ppu.m_beam.last_visible_line - 1;
snes_ppu.beam.latch_horz = x; state->m_ppu.m_beam.latch_horz = x;
snes_ppu.beam.latch_vert = y; state->m_ppu.m_beam.latch_vert = y;
snes_ram[STAT78] |= 0x40; snes_ram[STAT78] |= 0x40;
} }