Previous 199869 Revisions Next

r21559 Monday 4th March, 2013 at 09:38:04 UTC by Fabio Priuli
let's try to untangle a bit the knots between machine and PPU (part 1)... nw.
[src/mame/includes]snes.h
[src/mame/machine]snes.c
[src/mame/video]snes.c
[src/mess/drivers]snes.c

trunk/src/mame/machine/snes.c
r21558r21559
116116
117117   // latch the counters and pull IRQ
118118   // (don't need to switch to the 65816 context, we don't do anything dependant on it)
119   snes_latch_counters(machine);
119   state->m_ppu.snes_latch_counters(machine, snes_ram);
120120   snes_ram[TIMEUP] = 0x80;    /* Indicate that irq occurred */
121121   state->m_maincpu->set_input_line(G65816_LINE_IRQ, ASSERT_LINE);
122122
r21558r21559
134134   // make sure we're in the 65816's context since we're messing with the OAM and stuff
135135   address_space &space = m_maincpu->space(AS_PROGRAM);
136136
137   if (!(snes_ppu.screen_disabled)) //Reset OAM address, byuu says it happens at H=10
137   if (!(m_ppu.m_screen_disabled)) //Reset OAM address, byuu says it happens at H=10
138138   {
139      space.write_byte(OAMADDL, snes_ppu.oam.saved_address_low); /* Reset oam address */
140      space.write_byte(OAMADDH, snes_ppu.oam.saved_address_high);
141      snes_ppu.oam.first_sprite = snes_ppu.oam.priority_rotation ? (snes_ppu.oam.address >> 1) & 127 : 0;
139      space.write_byte(OAMADDL, m_ppu.m_oam.saved_address_low); /* Reset oam address */
140      space.write_byte(OAMADDH, m_ppu.m_oam.saved_address_high);
141      m_ppu.m_oam.first_sprite = m_ppu.m_oam.priority_rotation ? (m_ppu.m_oam.address >> 1) & 127 : 0;
142142   }
143143}
144144
r21558r21559
160160TIMER_CALLBACK_MEMBER(snes_state::snes_scanline_tick)
161161{
162162   /* Increase current line - we want to latch on this line during it, not after it */
163   snes_ppu.beam.current_vert = machine().primary_screen->vpos();
163   m_ppu.m_beam.current_vert = machine().primary_screen->vpos();
164164
165165   // not in hblank
166166   snes_ram[HVBJOY] &= ~0x40;
r21558r21559
168168   /* Vertical IRQ timer - only if horizontal isn't also enabled! */
169169   if ((snes_ram[NMITIMEN] & 0x20) && !(snes_ram[NMITIMEN] & 0x10))
170170   {
171      if (snes_ppu.beam.current_vert == m_vtime)
171      if (m_ppu.m_beam.current_vert == m_vtime)
172172      {
173173         snes_ram[TIMEUP] = 0x80;    /* Indicate that irq occurred */
174174         // IRQ latches the counters, do it now
175         snes_latch_counters(machine());
175         m_ppu.snes_latch_counters(machine(), snes_ram);
176176         m_maincpu->set_input_line(G65816_LINE_IRQ, ASSERT_LINE );
177177      }
178178   }
r21558r21559
185185      // is the HIRQ on a specific scanline?
186186      if (snes_ram[NMITIMEN] & 0x20)
187187      {
188         if (snes_ppu.beam.current_vert != m_vtime)
188         if (m_ppu.m_beam.current_vert != m_vtime)
189189         {
190190            setirq = 0;
191191         }
r21558r21559
193193
194194      if (setirq)
195195      {
196//          printf("HIRQ @ %d, %d\n", pixel * m_htmult, snes_ppu.beam.current_vert);
196//          printf("HIRQ @ %d, %d\n", pixel * m_htmult, m_ppu.m_beam.current_vert);
197197         if (pixel == 0)
198198         {
199199            snes_hirq_tick(machine());
200200         }
201201         else
202202         {
203            m_hirq_timer->adjust(machine().primary_screen->time_until_pos(snes_ppu.beam.current_vert, pixel * m_htmult));
203            m_hirq_timer->adjust(machine().primary_screen->time_until_pos(m_ppu.m_beam.current_vert, pixel * m_htmult));
204204         }
205205      }
206206   }
207207
208208   /* Start of VBlank */
209   if (snes_ppu.beam.current_vert == snes_ppu.beam.last_visible_line)
209   if (m_ppu.m_beam.current_vert == m_ppu.m_beam.last_visible_line)
210210   {
211      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));
211      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));
212212
213213      snes_ram[HVBJOY] |= 0x81;       /* Set vblank bit to on & indicate controllers being read */
214214      snes_ram[RDNMI] |= 0x80;        /* Set NMI occurred bit */
r21558r21559
220220      }
221221
222222      /* three lines after start of vblank we update the controllers (value from snes9x) */
223      m_io_timer->adjust(machine().primary_screen->time_until_pos(snes_ppu.beam.current_vert + 2, m_hblank_offset * m_htmult));
223      m_io_timer->adjust(machine().primary_screen->time_until_pos(m_ppu.m_beam.current_vert + 2, m_hblank_offset * m_htmult));
224224   }
225225
226226   // hdma reset happens at scanline 0, H=~6
227   if (snes_ppu.beam.current_vert == 0)
227   if (m_ppu.m_beam.current_vert == 0)
228228   {
229229      address_space &cpu0space = m_maincpu->space(AS_PROGRAM);
230230      snes_hdma_init(cpu0space);
231231   }
232232
233   if (snes_ppu.beam.current_vert == 0)
233   if (m_ppu.m_beam.current_vert == 0)
234234   {   /* VBlank is over, time for a new frame */
235235      snes_ram[HVBJOY] &= 0x7f;       /* Clear vblank bit */
236236      snes_ram[RDNMI]  &= 0x7f;       /* Clear nmi occurred bit */
237237      snes_ram[STAT78] ^= 0x80;       /* Toggle field flag */
238      snes_ppu.stat77_flags &= 0x3f;  /* Clear Time Over and Range Over bits */
238      m_ppu.m_stat77_flags &= 0x3f;  /* Clear Time Over and Range Over bits */
239239
240240      m_maincpu->set_input_line(G65816_LINE_NMI, CLEAR_LINE );
241241   }
242242
243243   m_scanline_timer->adjust(attotime::never);
244   m_hblank_timer->adjust(machine().primary_screen->time_until_pos(snes_ppu.beam.current_vert, m_hblank_offset * m_htmult));
244   m_hblank_timer->adjust(machine().primary_screen->time_until_pos(m_ppu.m_beam.current_vert, m_hblank_offset * m_htmult));
245245
246//  printf("%02x %d\n",snes_ram[HVBJOY],snes_ppu.beam.current_vert);
246//  printf("%02x %d\n",snes_ram[HVBJOY],m_ppu.m_beam.current_vert);
247247}
248248
249249/* This is called at the start of hblank *before* the scanline indicated in current_vert! */
r21558r21559
252252   address_space &cpu0space = m_maincpu->space(AS_PROGRAM);
253253   int nextscan;
254254
255   snes_ppu.beam.current_vert = machine().primary_screen->vpos();
255   m_ppu.m_beam.current_vert = machine().primary_screen->vpos();
256256
257257   /* make sure we halt */
258258   m_hblank_timer->adjust(attotime::never);
259259
260260   /* draw a scanline */
261   if (snes_ppu.beam.current_vert <= snes_ppu.beam.last_visible_line)
261   if (m_ppu.m_beam.current_vert <= m_ppu.m_beam.last_visible_line)
262262   {
263263      if (machine().primary_screen->vpos() > 0)
264264      {
r21558r21559
266266         if (snes_ram[HDMAEN])
267267            snes_hdma(cpu0space);
268268
269         machine().primary_screen->update_partial((snes_ppu.interlace == 2) ? (snes_ppu.beam.current_vert * snes_ppu.interlace) : snes_ppu.beam.current_vert - 1);
269         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);
270270      }
271271   }
272272
r21558r21559
274274   snes_ram[HVBJOY] |= 0x40;
275275
276276   /* kick off the start of scanline timer */
277   nextscan = snes_ppu.beam.current_vert + 1;
277   nextscan = m_ppu.m_beam.current_vert + 1;
278278   if (nextscan >= (((snes_ram[STAT78] & 0x10) == SNES_NTSC) ? SNES_VTOTAL_NTSC : SNES_VTOTAL_PAL))
279279   {
280280      nextscan = 0;
r21558r21559
428428   // PPU accesses are from 2100 to 213f
429429   if (offset >= INIDISP && offset < APU00)
430430   {
431      return snes_ppu_read(space, offset);
431      return state->m_ppu.snes_ppu_read(space, offset, snes_ram);
432432   }
433433
434434   // APU is mirrored from 2140 to 217f
r21558r21559
589589   // PPU accesses are from 2100 to 213f
590590   if (offset >= INIDISP && offset < APU00)
591591   {
592      snes_ppu_write(space, offset, data);
592      state->m_ppu.snes_ppu_write(space, offset, data, snes_ram);
593593      return;
594594   }
595595
r21558r21559
690690         if (!(snes_ram[WRIO] & 0x80) && (data & 0x80))
691691         {
692692            // external latch
693            snes_latch_counters(space.machine());
693            state->m_ppu.snes_latch_counters(space.machine(), snes_ram);
694694         }
695695         break;
696696      case HTIMEL:    /* H-Count timer settings (low)  */
r21558r21559
715715         break;
716716      case HDMAEN:    /* HDMA channel designation */
717717         if (data) //if a HDMA is enabled, data is inited at the next scanline
718            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));
718            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));
719719         break;
720720      case TIMEUP:    // IRQ Flag is cleared on both read and write
721721         state->m_maincpu->set_input_line(G65816_LINE_IRQ, CLEAR_LINE );
r21558r21559
16561656
16571657   // init frame counter so first line is 0
16581658   if (ATTOSECONDS_TO_HZ(machine.primary_screen->frame_period().attoseconds) >= 59)
1659      snes_ppu.beam.current_vert = SNES_VTOTAL_NTSC;
1659      state->m_ppu.m_beam.current_vert = SNES_VTOTAL_NTSC;
16601660   else
1661      snes_ppu.beam.current_vert = SNES_VTOTAL_PAL;
1661      state->m_ppu.m_beam.current_vert = SNES_VTOTAL_PAL;
16621662}
16631663
16641664#if 0
r21558r21559
18131813   state->m_vtime = 0x1ff;
18141814
18151815   state->m_htmult = 1;
1816   snes_ppu.interlace = 1;
1817   snes_ppu.obj_interlace = 1;
1816   state->m_ppu.m_interlace = 1;
1817   state->m_ppu.m_obj_interlace = 1;
18181818}
18191819
18201820
trunk/src/mame/includes/snes.h
r21558r21559
368368#define DSP_FIR_C6      0x6F
369369#define DSP_FIR_C7      0x7F
370370
371/* (PPU) Video related */
372class snes_ppu_class  /* once all the regs are saved in this structure, it would be better to reorganize it a bit... */
373{
374public:
375   struct
376   {
377      /* clipmasks */
378      UINT8 window1_enabled, window1_invert;
379      UINT8 window2_enabled, window2_invert;
380      UINT8 wlog_mask;
381      /* color math enabled */
382      UINT8 color_math;
383     
384      UINT8 charmap;
385      UINT8 tilemap;
386      UINT8 tilemap_size;
387     
388      UINT8 tile_size;
389      UINT8 mosaic_enabled;   // actually used only for layers 0->3!
390     
391      UINT8 main_window_enabled;
392      UINT8 sub_window_enabled;
393      UINT8 main_bg_enabled;
394      UINT8 sub_bg_enabled;
395     
396      UINT16 hoffs;
397      UINT16 voffs;
398   } m_layer[6]; // this is for the BG1 - BG2 - BG3 - BG4 - OBJ - color layers
399   
400   struct
401   {
402      UINT8 address_low;
403      UINT8 address_high;
404      UINT8 saved_address_low;
405      UINT8 saved_address_high;
406      UINT16 address;
407      UINT16 priority_rotation;
408      UINT8 next_charmap;
409      UINT8 next_size;
410      UINT8 size;
411      UINT32 next_name_select;
412      UINT32 name_select;
413      UINT8 first_sprite;
414      UINT8 flip;
415      UINT16 write_latch;
416   } m_oam;
417   
418   struct
419   {
420      UINT16 horizontal[4];
421      UINT16 vertical[4];
422   } m_bgd_offset;
423   
424   struct
425   {
426      UINT16 latch_horz;
427      UINT16 latch_vert;
428      UINT16 current_horz;
429      UINT16 current_vert;
430      UINT8 last_visible_line;
431      UINT8 interlace_count;
432   } m_beam;
433   
434   struct
435   {
436      UINT8 repeat;
437      UINT8 hflip;
438      UINT8 vflip;
439      INT16 matrix_a;
440      INT16 matrix_b;
441      INT16 matrix_c;
442      INT16 matrix_d;
443      INT16 origin_x;
444      INT16 origin_y;
445      UINT16 hor_offset;
446      UINT16 ver_offset;
447      UINT8 extbg;
448   } m_mode7;
449   
450   UINT8 m_mosaic_size;
451   UINT8 m_clip_to_black;
452   UINT8 m_prevent_color_math;
453   UINT8 m_sub_add_mode;
454   UINT8 m_bg3_priority_bit;
455   UINT8 m_direct_color;
456   UINT8 m_ppu_last_scroll;      /* as per Anomie's doc and Theme Park, all scroll regs shares (but mode 7 ones) the same
457                         'previous' scroll value */
458   UINT8 m_mode7_last_scroll;    /* as per Anomie's doc mode 7 scroll regs use a different value, shared with mode 7 matrix! */
459   
460   UINT8 m_ppu1_open_bus, m_ppu2_open_bus;
461   UINT8 m_ppu1_version, m_ppu2_version;
462   UINT8 m_window1_left, m_window1_right, m_window2_left, m_window2_right;
463   
464   UINT16 m_mosaic_table[16][4096];
465   UINT8 m_clipmasks[6][SNES_SCR_WIDTH];
466   UINT8 m_update_windows;
467   UINT8 m_update_offsets;
468   UINT8 m_update_oam_list;
469   UINT8 m_mode;
470   UINT8 m_interlace; //doubles the visible resolution
471   UINT8 m_obj_interlace;
472   UINT8 m_screen_brightness;
473   UINT8 m_screen_disabled;
474   UINT8 m_pseudo_hires;
475   UINT8 m_color_modes;
476   UINT8 m_stat77_flags;
477
478   inline UINT16 snes_get_bgcolor(UINT8 direct_colors, UINT16 palette, UINT8 color);
479   inline void snes_set_scanline_pixel(int screen, INT16 x, UINT16 color, UINT8 priority, UINT8 layer, int blend);
480   inline void snes_draw_bgtile_lores(UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority);
481   inline void snes_draw_bgtile_hires(UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority);
482   inline void snes_draw_oamtile(INT16 ii, UINT8 colour, UINT16 pal, UINT8 priority);
483   inline void snes_draw_tile(UINT8 planes, UINT8 layer, UINT32 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT8 direct_colors, UINT16 pal, UINT8 hires);
484   inline UINT32 snes_get_tmap_addr(UINT8 layer, UINT8 tile_size, UINT32 base, UINT32 x, UINT32 y);
485   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);
486   void snes_update_line_mode7(UINT16 curline, UINT8 layer, UINT8 priority_b, UINT8 priority_a);
487   void snes_update_obsel(void);
488   void snes_oam_list_build(void);
489   int is_sprite_on_scanline(UINT16 curline, UINT8 sprite);
490   void snes_update_objects_rto(UINT16 curline);
491   void snes_update_objects(UINT8 priority_oam0, UINT8 priority_oam1, UINT8 priority_oam2, UINT8 priority_oam3);
492   void snes_update_mode_0(UINT16 curline);
493   void snes_update_mode_1(UINT16 curline);
494   void snes_update_mode_2(UINT16 curline);
495   void snes_update_mode_3(UINT16 curline);
496   void snes_update_mode_4(UINT16 curline);
497   void snes_update_mode_5(UINT16 curline);
498   void snes_update_mode_6(UINT16 curline);
499   void snes_update_mode_7(UINT16 curline);
500   void snes_draw_screens(UINT16 curline);
501   void snes_update_windowmasks(void);
502   void snes_update_offsets(void);
503   inline void snes_draw_blend(UINT16 offset, UINT16 *colour, UINT8 prevent_color_math, UINT8 black_pen_clip, int switch_screens);
504   void snes_refresh_scanline(running_machine &machine, bitmap_rgb32 &bitmap, UINT16 curline);
505   
506   UINT8 snes_ppu_read(address_space &space, UINT32 offset, UINT8 *ram_ptr);
507   void snes_ppu_write(address_space &space, UINT32 offset, UINT8 data, UINT8 *ram_ptr);
508   void snes_latch_counters(running_machine &machine, UINT8 *ram_ptr);
509   void snes_dynamic_res_change(running_machine &machine, UINT8 *ram_ptr);
510   inline UINT32 snes_get_vram_address(running_machine &machine);
511   UINT8 snes_dbg_video(running_machine &machine, UINT16 curline, UINT8 *ram_ptr);
512
513   void ppu_start(running_machine &machine);
514   DECLARE_READ8_MEMBER( snes_oam_read );
515   DECLARE_WRITE8_MEMBER( snes_oam_write );
516   DECLARE_READ8_MEMBER( snes_cgram_read );
517   DECLARE_WRITE8_MEMBER( snes_cgram_write );
518   DECLARE_READ8_MEMBER( snes_vram_read );
519   DECLARE_WRITE8_MEMBER( snes_vram_write );
520   UINT16 *m_oam_ram;     /* Object Attribute Memory */
521   UINT16 *m_cgram;   /* Palette RAM */
522   UINT8  *m_vram;    /* Video RAM (TODO: Should be 16-bit, but it's easier this way) */
523};
524
371525struct snes_cart_info
372526{
373527   UINT8  mode;        /* ROM memory mode */
r21558r21559
408562      : driver_device(mconfig, type, tag)
409563      { }
410564
411
412565   /* misc */
413566   UINT16                m_htmult;     /* in 512 wide, we run HTOTAL double and halve it on latching */
414567   UINT16                m_cgram_address;  /* CGRAM address */
r21558r21559
489642   UINT32 m_cart_size;
490643   snes_cart_info m_cart[2];   // the second one is used by MESS for Sufami Turbo and, eventually, BS-X
491644
645   snes_ppu_class        m_ppu;
646   UINT32 snes_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
647
492648   /* devices */
493649   _5a22_device *m_maincpu;
494650   spc700_device *m_soundcpu;
r21558r21559
504660   DECLARE_DRIVER_INIT(snes_mess);
505661   DECLARE_DRIVER_INIT(snesst);
506662
507   inline UINT16 snes_get_bgcolor( UINT8 direct_colors, UINT16 palette, UINT8 color );
508   inline void snes_set_scanline_pixel( int screen, INT16 x, UINT16 color, UINT8 priority, UINT8 layer, int blend );
509   inline void snes_draw_bgtile_lores( UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority );
510   inline void snes_draw_bgtile_hires( UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority );
511   inline void snes_draw_oamtile( INT16 ii, UINT8 colour, UINT16 pal, UINT8 priority );
512   inline void snes_draw_tile( UINT8 planes, UINT8 layer, UINT32 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT8 direct_colors, UINT16 pal, UINT8 hires );
513   inline UINT32 snes_get_tmap_addr( UINT8 layer, UINT8 tile_size, UINT32 base, UINT32 x, UINT32 y );
514   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 );
515   void snes_update_line_mode7( UINT16 curline, UINT8 layer, UINT8 priority_b, UINT8 priority_a );
516   void snes_update_obsel( void );
517   void snes_oam_list_build( void );
518   int is_sprite_on_scanline( UINT16 curline, UINT8 sprite );
519   void snes_update_objects_rto( UINT16 curline );
520   void snes_update_objects( UINT8 priority_oam0, UINT8 priority_oam1, UINT8 priority_oam2, UINT8 priority_oam3 );
521   void snes_update_mode_0( UINT16 curline );
522   void snes_update_mode_1( UINT16 curline );
523   void snes_update_mode_2( UINT16 curline );
524   void snes_update_mode_3( UINT16 curline );
525   void snes_update_mode_4( UINT16 curline );
526   void snes_update_mode_5( UINT16 curline );
527   void snes_update_mode_6( UINT16 curline );
528   void snes_update_mode_7( UINT16 curline );
529   void snes_draw_screens( UINT16 curline );
530   void snes_update_windowmasks( void );
531   void snes_update_offsets( void );
532   inline void snes_draw_blend( UINT16 offset, UINT16 *colour, UINT8 prevent_color_math, UINT8 black_pen_clip, int switch_screens );
533   void snes_refresh_scanline( running_machine &machine, bitmap_rgb32 &bitmap, UINT16 curline );
534663
535   UINT32 snes_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
536
537   DECLARE_READ8_MEMBER( snes_oam_read );
538   DECLARE_WRITE8_MEMBER( snes_oam_write );
539   DECLARE_READ8_MEMBER( snes_cgram_read );
540   DECLARE_WRITE8_MEMBER( snes_cgram_write );
541   DECLARE_READ8_MEMBER( snes_vram_read );
542   DECLARE_WRITE8_MEMBER( snes_vram_write );
543   UINT16 *m_snes_oam;     /* Object Attribute Memory */
544   UINT16 *m_snes_cgram;   /* Palette RAM */
545   UINT8  *m_snes_vram;    /* Video RAM (TODO: Should be 16-bit, but it's easier this way) */
546
547664   TIMER_CALLBACK_MEMBER(snes_nmi_tick);
548665   TIMER_CALLBACK_MEMBER(snes_hirq_tick_callback);
549666   TIMER_CALLBACK_MEMBER(snes_reset_oam_address);
r21558r21559
636753extern UINT8  *snes_ram;            /* Main memory */
637754
638755
639/* (PPU) Video related */
640struct SNES_PPU_STRUCT  /* once all the regs are saved in this structure, it would be better to reorganize it a bit... */
641{
642   struct
643   {
644      /* clipmasks */
645      UINT8 window1_enabled, window1_invert;
646      UINT8 window2_enabled, window2_invert;
647      UINT8 wlog_mask;
648      /* color math enabled */
649      UINT8 color_math;
650756
651      UINT8 charmap;
652      UINT8 tilemap;
653      UINT8 tilemap_size;
654
655      UINT8 tile_size;
656      UINT8 mosaic_enabled;   // actually used only for layers 0->3!
657
658      UINT8 main_window_enabled;
659      UINT8 sub_window_enabled;
660      UINT8 main_bg_enabled;
661      UINT8 sub_bg_enabled;
662
663      UINT16 hoffs;
664      UINT16 voffs;
665   } layer[6]; // this is for the BG1 - BG2 - BG3 - BG4 - OBJ - color layers
666
667   struct
668   {
669      UINT8 address_low;
670      UINT8 address_high;
671      UINT8 saved_address_low;
672      UINT8 saved_address_high;
673      UINT16 address;
674      UINT16 priority_rotation;
675      UINT8 next_charmap;
676      UINT8 next_size;
677      UINT8 size;
678      UINT32 next_name_select;
679      UINT32 name_select;
680      UINT8 first_sprite;
681      UINT8 flip;
682      UINT16 write_latch;
683   } oam;
684
685   struct
686   {
687      UINT16 horizontal[4];
688      UINT16 vertical[4];
689   } bgd_offset;
690
691   struct
692   {
693      UINT16 latch_horz;
694      UINT16 latch_vert;
695      UINT16 current_horz;
696      UINT16 current_vert;
697      UINT8 last_visible_line;
698      UINT8 interlace_count;
699   } beam;
700
701   struct
702   {
703      UINT8 repeat;
704      UINT8 hflip;
705      UINT8 vflip;
706      INT16 matrix_a;
707      INT16 matrix_b;
708      INT16 matrix_c;
709      INT16 matrix_d;
710      INT16 origin_x;
711      INT16 origin_y;
712      UINT16 hor_offset;
713      UINT16 ver_offset;
714      UINT8 extbg;
715   } mode7;
716
717   UINT8 mosaic_size;
718   UINT8 clip_to_black;
719   UINT8 prevent_color_math;
720   UINT8 sub_add_mode;
721   UINT8 bg3_priority_bit;
722   UINT8 direct_color;
723   UINT8 ppu_last_scroll;      /* as per Anomie's doc and Theme Park, all scroll regs shares (but mode 7 ones) the same
724                                    'previous' scroll value */
725   UINT8 mode7_last_scroll;    /* as per Anomie's doc mode 7 scroll regs use a different value, shared with mode 7 matrix! */
726
727   UINT8 ppu1_open_bus, ppu2_open_bus;
728   UINT8 ppu1_version, ppu2_version;
729   UINT8 window1_left, window1_right, window2_left, window2_right;
730
731   UINT16 mosaic_table[16][4096];
732   UINT8 clipmasks[6][SNES_SCR_WIDTH];
733   UINT8 update_windows;
734   UINT8 update_offsets;
735   UINT8 update_oam_list;
736   UINT8 mode;
737   UINT8 interlace; //doubles the visible resolution
738   UINT8 obj_interlace;
739   UINT8 screen_brightness;
740   UINT8 screen_disabled;
741   UINT8 pseudo_hires;
742   UINT8 color_modes;
743   UINT8 stat77_flags;
744};
745
746757extern struct snes_cart_info snes_cart;
747758
748759/*----------- defined in video/snes.c -----------*/
749760
750extern struct SNES_PPU_STRUCT snes_ppu;
751
752extern void snes_latch_counters(running_machine &machine);
753
754761extern VIDEO_START( snes );
755762extern SCREEN_UPDATE_RGB32( snes );
756763
757extern DECLARE_READ8_HANDLER( snes_ppu_read );
758extern DECLARE_WRITE8_HANDLER( snes_ppu_write );
759764
760765#endif /* _SNES_H_ */
trunk/src/mame/video/snes.c
r21558r21559
9595static struct DEBUGOPTS debug_options;
9696/*                                    red   green  blue    purple  yellow cyan    grey    white */
9797static const UINT16 dbg_mode_colours[8] = { 0x1f, 0x3e0, 0x7c00, 0x7c1f, 0x3ff, 0x7fe0, 0x4210, 0x7fff };
98static UINT8 snes_dbg_video(running_machine &machine, UINT16 curline);
9998#endif /* SNES_LAYER_DEBUG */
10099
101100static const UINT16 table_obj_offset[8][8] =
r21558r21559
121120};
122121
123122static struct SCANLINE scanlines[2];
124struct SNES_PPU_STRUCT snes_ppu;
123//struct SNES_PPU_STRUCT snes_ppu;
125124
126125enum
127126{
r21558r21559
136135 * Get the proper color (direct or from cgram)
137136 *****************************************/
138137
139inline UINT16 snes_state::snes_get_bgcolor( UINT8 direct_colors, UINT16 palette, UINT8 color )
138inline UINT16 snes_ppu_class::snes_get_bgcolor( UINT8 direct_colors, UINT16 palette, UINT8 color )
140139{
141140   UINT16 c = 0;
142141
r21558r21559
147146      c |= ((palette & 0x04) >> 1) | ((palette & 0x08) << 3) | ((palette & 0x10) << 8);
148147   }
149148   else
150      c = m_snes_cgram[(palette + color) % FIXED_COLOUR];
149      c = m_cgram[(palette + color) % FIXED_COLOUR];
151150
152151   return c;
153152}
r21558r21559
160159 * proper scanline
161160 *****************************************/
162161
163inline void snes_state::snes_set_scanline_pixel( int screen, INT16 x, UINT16 color, UINT8 priority, UINT8 layer, int blend )
162inline void snes_ppu_class::snes_set_scanline_pixel( int screen, INT16 x, UINT16 color, UINT8 priority, UINT8 layer, int blend )
164163{
165164   scanlines[screen].buffer[x] = color;
166165   scanlines[screen].priority[x] = priority;
r21558r21559
191190 * or lores)
192191 *****************************************/
193192
194inline void snes_state::snes_draw_bgtile_lores( UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority )
193inline void snes_ppu_class::snes_draw_bgtile_lores( UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority )
195194{
196195   int screen;
197196   UINT16 c;
r21558r21559
203202         if (scanlines[screen].priority[ii] <= priority)
204203         {
205204            UINT8 clr = colour;
206            UINT8 clipmask = snes_ppu.clipmasks[layer][ii];
205            UINT8 clipmask = m_clipmasks[layer][ii];
207206
208207#if SNES_LAYER_DEBUG
209208            if (debug_options.windows_disabled)
r21558r21559
225224   }
226225}
227226
228inline void snes_state::snes_draw_bgtile_hires( UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority )
227inline void snes_ppu_class::snes_draw_bgtile_hires( UINT8 layer, INT16 ii, UINT8 colour, UINT16 pal, UINT8 direct_colors, UINT8 priority )
229228{
230229   int screen;
231230   UINT16 c;
r21558r21559
238237         if (scanlines[screen].priority[ii >> 1] <= priority)
239238         {
240239            UINT8 clr = colour;
241            UINT8 clipmask = snes_ppu.clipmasks[layer][ii >> 1];
240            UINT8 clipmask = m_clipmasks[layer][ii >> 1];
242241
243242#if SNES_LAYER_DEBUG
244243            if (debug_options.windows_disabled)
r21558r21559
260259   }
261260}
262261
263inline void snes_state::snes_draw_oamtile( INT16 ii, UINT8 colour, UINT16 pal, UINT8 priority )
262inline void snes_ppu_class::snes_draw_oamtile( INT16 ii, UINT8 colour, UINT16 pal, UINT8 priority )
264263{
265264   int screen;
266265   int blend;
r21558r21559
272271      if (pos >= 0 && pos < SNES_SCR_WIDTH && scanlines[screen].enable)
273272      {
274273         UINT8 clr = colour;
275         UINT8 clipmask = snes_ppu.clipmasks[SNES_OAM][pos];
274         UINT8 clipmask = m_clipmasks[SNES_OAM][pos];
276275
277276#if SNES_LAYER_DEBUG
278277         if (debug_options.windows_disabled)
r21558r21559
286285         /* Only draw if we have a colour (0 == transparent) */
287286         if (clr)
288287         {
289            c = m_snes_cgram[(pal + clr) % FIXED_COLOUR];
288            c = m_cgram[(pal + clr) % FIXED_COLOUR];
290289            blend = (pal + clr < 192) ? 1 : 0;
291290            snes_set_scanline_pixel(screen, pos, c, priority, SNES_OAM, blend);
292291         }
r21558r21559
303302 * (depending on layer and resolution)
304303 *****************************************/
305304
306inline void snes_state::snes_draw_tile( UINT8 planes, UINT8 layer, UINT32 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT8 direct_colors, UINT16 pal, UINT8 hires )
305inline void snes_ppu_class::snes_draw_tile( UINT8 planes, UINT8 layer, UINT32 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT8 direct_colors, UINT16 pal, UINT8 hires )
307306{
308307   UINT8 plane[8];
309308   INT16 ii, jj;
r21558r21559
311310
312311   for (ii = 0; ii < planes / 2; ii++)
313312   {
314      plane[2 * ii + 0] = m_snes_vram[(tileaddr + 16 * ii + 0) % SNES_VRAM_SIZE];
315      plane[2 * ii + 1] = m_snes_vram[(tileaddr + 16 * ii + 1) % SNES_VRAM_SIZE];
313      plane[2 * ii + 0] = m_vram[(tileaddr + 16 * ii + 0) % SNES_VRAM_SIZE];
314      plane[2 * ii + 1] = m_vram[(tileaddr + 16 * ii + 1) % SNES_VRAM_SIZE];
316315   }
317316
318317   for (ii = x; ii < (x + 8); ii++)
319318   {
320319      UINT8 colour = 0;
321      UINT8 mosaic = snes_ppu.layer[layer].mosaic_enabled;
320      UINT8 mosaic = m_layer[layer].mosaic_enabled;
322321
323322#if SNES_LAYER_DEBUG
324323      if (debug_options.mosaic_disabled)
r21558r21559
342341      {
343342         if (mosaic)
344343         {
345            for (x_mos = 0; x_mos < (snes_ppu.mosaic_size + 1); x_mos++)
344            for (x_mos = 0; x_mos < (m_mosaic_size + 1); x_mos++)
346345               snes_draw_bgtile_lores(layer, ii + x_mos, colour, pal, direct_colors, priority);
347346            ii += x_mos - 1;
348347         }
r21558r21559
353352      {
354353         if (mosaic)
355354         {
356            for (x_mos = 0; x_mos < (snes_ppu.mosaic_size + 1); x_mos++)
355            for (x_mos = 0; x_mos < (m_mosaic_size + 1); x_mos++)
357356               snes_draw_bgtile_hires(layer, ii + x_mos, colour, pal, direct_colors, priority);
358357            ii += x_mos - 1;
359358         }
r21558r21559
369368 * BG drawing theory of each scanline is quite easy: depending on the graphics Mode (0-7), there
370369 * are up to 4 background layers. Pixels for each BG layer can have two different priorities.
371370 * Depending on the line and on the BGHOFS and BGVOFS PPU registers, we first determine the tile
372 * address in m_snes_vram (by determining x,y coord and tile size and by calling snes_get_tmap_addr).
371 * address in m_vram (by determining x,y coord and tile size and by calling snes_get_tmap_addr).
373372 * Then, we load the correspondent data and we determine the tile properties: which priority to
374373 * use, which palette etc. Finally, for each pixel of the tile appearing on screen, we check if
375374 * the tile priority is higher than the BG/OAM already stored in that pixel for that line. If so
r21558r21559
386385 * Find the address in VRAM of the tile (x,y)
387386 *********************************************/
388387
389inline UINT32 snes_state::snes_get_tmap_addr( UINT8 layer, UINT8 tile_size, UINT32 base, UINT32 x, UINT32 y )
388inline UINT32 snes_ppu_class::snes_get_tmap_addr( UINT8 layer, UINT8 tile_size, UINT32 base, UINT32 x, UINT32 y )
390389{
391390   UINT32 res = base;
392391   x  >>= (3 + tile_size);
393392   y  >>= (3 + tile_size);
394393
395   res += (snes_ppu.layer[layer].tilemap_size & 2) ? ((y & 0x20) << ((snes_ppu.layer[layer].tilemap_size & 1) ? 7 : 6)) : 0;
394   res += (m_layer[layer].tilemap_size & 2) ? ((y & 0x20) << ((m_layer[layer].tilemap_size & 1) ? 7 : 6)) : 0;
396395   /* Scroll vertically */
397396   res += (y & 0x1f) << 6;
398397   /* Offset horizontally */
399   res += (snes_ppu.layer[layer].tilemap_size & 1) ? ((x & 0x20) << 6) : 0;
398   res += (m_layer[layer].tilemap_size & 1) ? ((x & 0x20) << 6) : 0;
400399   /* Scroll horizontally */
401400   res += (x & 0x1f) << 1;
402401
r21558r21559
409408 * Update an entire line of tiles.
410409 *********************************************/
411410
412inline void snes_state::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 )
411inline void snes_ppu_class::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 )
413412{
414413   UINT32 tmap, tile, xoff, yoff, charaddr, addr;
415414   UINT16 ii = 0, vflip, hflip, pal, pal_direct, tilemap;
r21558r21559
428427      return;
429428#endif /* SNES_LAYER_DEBUG */
430429
431   scanlines[SNES_MAINSCREEN].enable = snes_ppu.layer[layer].main_bg_enabled;
432   scanlines[SNES_SUBSCREEN].enable = snes_ppu.layer[layer].sub_bg_enabled;
433   scanlines[SNES_MAINSCREEN].clip = snes_ppu.layer[layer].main_window_enabled;
434   scanlines[SNES_SUBSCREEN].clip = snes_ppu.layer[layer].sub_window_enabled;
430   scanlines[SNES_MAINSCREEN].enable = m_layer[layer].main_bg_enabled;
431   scanlines[SNES_SUBSCREEN].enable = m_layer[layer].sub_bg_enabled;
432   scanlines[SNES_MAINSCREEN].clip = m_layer[layer].main_window_enabled;
433   scanlines[SNES_SUBSCREEN].clip = m_layer[layer].sub_window_enabled;
435434
436435   if (!scanlines[SNES_MAINSCREEN].enable && !scanlines[SNES_SUBSCREEN].enable)
437436      return;
438437
439438   /* Handle Mosaic effects */
440   if (snes_ppu.layer[layer].mosaic_enabled)
441      curline -= (curline % (snes_ppu.mosaic_size + 1));
439   if (m_layer[layer].mosaic_enabled)
440      curline -= (curline % (m_mosaic_size + 1));
442441
443   if ((snes_ppu.interlace == 2) && !hires && !snes_ppu.pseudo_hires)
442   if ((m_interlace == 2) && !hires && !m_pseudo_hires)
444443      curline /= 2;
445444
446445   /* Find the size of the tiles (8x8 or 16x16) */
447   tile_size = snes_ppu.layer[layer].tile_size;
446   tile_size = m_layer[layer].tile_size;
448447
449448   /* Find scroll info */
450   xoff = snes_ppu.layer[layer].hoffs;
451   yoff = snes_ppu.layer[layer].voffs;
449   xoff = m_layer[layer].hoffs;
450   yoff = m_layer[layer].voffs;
452451
453452   xscroll = xoff & ((1 << (3 + tile_size)) - 1);
454453
455454   /* Jump to base map address */
456   tmap = snes_ppu.layer[layer].tilemap << 9;
457   charaddr = snes_ppu.layer[layer].charmap << 13;
455   tmap = m_layer[layer].tilemap << 9;
456   charaddr = m_layer[layer].charmap << 13;
458457
459458   while (ii < 256 + (8 << tile_size))
460459   {
r21558r21559
474473            {
475474            case SNES_OPT_MODE2:
476475            case SNES_OPT_MODE6:
477               haddr = snes_get_tmap_addr(SNES_BG3, snes_ppu.layer[SNES_BG3].tile_size, snes_ppu.layer[SNES_BG3].tilemap << 9, (opt_x - 8) + ((snes_ppu.layer[SNES_BG3].hoffs & 0x3ff) & ~7), (snes_ppu.layer[SNES_BG3].voffs & 0x3ff));
478               vaddr = snes_get_tmap_addr(SNES_BG3, snes_ppu.layer[SNES_BG3].tile_size, snes_ppu.layer[SNES_BG3].tilemap << 9, (opt_x - 8) + ((snes_ppu.layer[SNES_BG3].hoffs & 0x3ff) & ~7), (snes_ppu.layer[SNES_BG3].voffs & 0x3ff) + 8);
479               hval = m_snes_vram[haddr % SNES_VRAM_SIZE] | (m_snes_vram[(haddr + 1) % SNES_VRAM_SIZE] << 8);
480               vval = m_snes_vram[vaddr % SNES_VRAM_SIZE] | (m_snes_vram[(vaddr + 1) % SNES_VRAM_SIZE] << 8);
476               haddr = snes_get_tmap_addr(SNES_BG3, m_layer[SNES_BG3].tile_size, m_layer[SNES_BG3].tilemap << 9, (opt_x - 8) + ((m_layer[SNES_BG3].hoffs & 0x3ff) & ~7), (m_layer[SNES_BG3].voffs & 0x3ff));
477               vaddr = snes_get_tmap_addr(SNES_BG3, m_layer[SNES_BG3].tile_size, m_layer[SNES_BG3].tilemap << 9, (opt_x - 8) + ((m_layer[SNES_BG3].hoffs & 0x3ff) & ~7), (m_layer[SNES_BG3].voffs & 0x3ff) + 8);
478               hval = m_vram[haddr % SNES_VRAM_SIZE] | (m_vram[(haddr + 1) % SNES_VRAM_SIZE] << 8);
479               vval = m_vram[vaddr % SNES_VRAM_SIZE] | (m_vram[(vaddr + 1) % SNES_VRAM_SIZE] << 8);
481480               if (BIT(hval, opt_bit))
482481                  xpos = opt_x + (hval & ~7);
483482               if (BIT(vval, opt_bit))
484483                  ypos = curline + vval;
485484               break;
486485            case SNES_OPT_MODE4:
487               haddr = snes_get_tmap_addr(SNES_BG3, snes_ppu.layer[SNES_BG3].tile_size, snes_ppu.layer[SNES_BG3].tilemap << 9, (opt_x - 8) + ((snes_ppu.layer[SNES_BG3].hoffs & 0x3ff) & ~7), (snes_ppu.layer[SNES_BG3].voffs & 0x3ff));
488               hval = m_snes_vram[haddr % SNES_VRAM_SIZE] | (m_snes_vram[(haddr + 1) % SNES_VRAM_SIZE] << 8);
486               haddr = snes_get_tmap_addr(SNES_BG3, m_layer[SNES_BG3].tile_size, m_layer[SNES_BG3].tilemap << 9, (opt_x - 8) + ((m_layer[SNES_BG3].hoffs & 0x3ff) & ~7), (m_layer[SNES_BG3].voffs & 0x3ff));
487               hval = m_vram[haddr % SNES_VRAM_SIZE] | (m_vram[(haddr + 1) % SNES_VRAM_SIZE] << 8);
489488               if (BIT(hval, opt_bit))
490489               {
491490                  if (!BIT(hval, 15))
r21558r21559
509508        ppp  = Tile palette. The number of entries in the palette depends on the Mode and the BG.
510509        cccccccccc = Tile number.
511510      */
512      tilemap = m_snes_vram[addr % SNES_VRAM_SIZE] | (m_snes_vram[(addr + 1) % SNES_VRAM_SIZE] << 8);
511      tilemap = m_vram[addr % SNES_VRAM_SIZE] | (m_vram[(addr + 1) % SNES_VRAM_SIZE] << 8);
513512      vflip = BIT(tilemap, 15);
514513      hflip = BIT(tilemap, 14);
515514      priority = BIT(tilemap, 13) ? priority_a : priority_b;
r21558r21559
519518      pal = ((pal_direct >> 2) << color_shift);
520519
521520      /* Mode 0 palettes are layer specific */
522      if (snes_ppu.mode == 0)
521      if (m_mode == 0)
523522      {
524523         pal += (layer << 5);
525524      }
r21558r21559
594593
595594#define MODE7_CLIP(x) (((x) & 0x2000) ? ((x) | ~0x03ff) : ((x) & 0x03ff))
596595
597void snes_state::snes_update_line_mode7( UINT16 curline, UINT8 layer, UINT8 priority_b, UINT8 priority_a )
596void snes_ppu_class::snes_update_line_mode7( UINT16 curline, UINT8 layer, UINT8 priority_b, UINT8 priority_a )
598597{
599598   UINT32 tiled;
600599   INT16 ma, mb, mc, md;
r21558r21559
610609      return;
611610#endif /* SNES_LAYER_DEBUG */
612611
613   scanlines[SNES_MAINSCREEN].enable = snes_ppu.layer[layer].main_bg_enabled;
614   scanlines[SNES_SUBSCREEN].enable = snes_ppu.layer[layer].sub_bg_enabled;
615   scanlines[SNES_MAINSCREEN].clip = snes_ppu.layer[layer].main_window_enabled;
616   scanlines[SNES_SUBSCREEN].clip = snes_ppu.layer[layer].sub_window_enabled;
612   scanlines[SNES_MAINSCREEN].enable = m_layer[layer].main_bg_enabled;
613   scanlines[SNES_SUBSCREEN].enable = m_layer[layer].sub_bg_enabled;
614   scanlines[SNES_MAINSCREEN].clip = m_layer[layer].main_window_enabled;
615   scanlines[SNES_SUBSCREEN].clip = m_layer[layer].sub_window_enabled;
617616
618617   if (!scanlines[SNES_MAINSCREEN].enable && !scanlines[SNES_SUBSCREEN].enable)
619618      return;
620619
621   ma = snes_ppu.mode7.matrix_a;
622   mb = snes_ppu.mode7.matrix_b;
623   mc = snes_ppu.mode7.matrix_c;
624   md = snes_ppu.mode7.matrix_d;
625   xc = snes_ppu.mode7.origin_x;
626   yc = snes_ppu.mode7.origin_y;
627   hs = snes_ppu.mode7.hor_offset;
628   vs = snes_ppu.mode7.ver_offset;
620   ma = m_mode7.matrix_a;
621   mb = m_mode7.matrix_b;
622   mc = m_mode7.matrix_c;
623   md = m_mode7.matrix_d;
624   xc = m_mode7.origin_x;
625   yc = m_mode7.origin_y;
626   hs = m_mode7.hor_offset;
627   vs = m_mode7.ver_offset;
629628
630629   /* Sign extend */
631630   xc <<= 19;
r21558r21559
638637   vs >>= 19;
639638
640639   /* Vertical flip */
641   if (snes_ppu.mode7.vflip)
640   if (m_mode7.vflip)
642641      sy = 255 - curline;
643642   else
644643      sy = curline;
645644
646645   /* Horizontal flip */
647   if (snes_ppu.mode7.hflip)
646   if (m_mode7.hflip)
648647   {
649648      xpos = 255;
650649      xdir = -1;
r21558r21559
658657   /* MOSAIC - to be verified */
659658   if (layer == SNES_BG2)  // BG2 use two different bits for horizontal and vertical mosaic
660659   {
661      mosaic_x = snes_ppu.mosaic_table[snes_ppu.layer[SNES_BG2].mosaic_enabled ? snes_ppu.mosaic_size : 0];
662      mosaic_y = snes_ppu.mosaic_table[snes_ppu.layer[SNES_BG1].mosaic_enabled ? snes_ppu.mosaic_size : 0];
660      mosaic_x = m_mosaic_table[m_layer[SNES_BG2].mosaic_enabled ? m_mosaic_size : 0];
661      mosaic_y = m_mosaic_table[m_layer[SNES_BG1].mosaic_enabled ? m_mosaic_size : 0];
663662   }
664663   else    // BG1 works as usual
665664   {
666      mosaic_x =  snes_ppu.mosaic_table[snes_ppu.layer[SNES_BG1].mosaic_enabled ? snes_ppu.mosaic_size : 0];
667      mosaic_y =  snes_ppu.mosaic_table[snes_ppu.layer[SNES_BG1].mosaic_enabled ? snes_ppu.mosaic_size : 0];
665      mosaic_x =  m_mosaic_table[m_layer[SNES_BG1].mosaic_enabled ? m_mosaic_size : 0];
666      mosaic_y =  m_mosaic_table[m_layer[SNES_BG1].mosaic_enabled ? m_mosaic_size : 0];
668667   }
669668
670669#if SNES_LAYER_DEBUG
671670   if (debug_options.mosaic_disabled)
672671   {
673      mosaic_x =  snes_ppu.mosaic_table[0];
674      mosaic_y =  snes_ppu.mosaic_table[0];
672      mosaic_x =  m_mosaic_table[0];
673      mosaic_y =  m_mosaic_table[0];
675674   }
676675#endif /* SNES_LAYER_DEBUG */
677676
r21558r21559
685684      tx = (x0 + (ma * mosaic_x[sx])) >> 8;
686685      ty = (y0 + (mc * mosaic_x[sx])) >> 8;
687686
688      switch (snes_ppu.mode7.repeat)
687      switch (m_mode7.repeat)
689688      {
690689         case 0x00:  /* Repeat if outside screen area */
691690         case 0x01:  /* Repeat if outside screen area */
692691            tx &= 0x3ff;
693692            ty &= 0x3ff;
694            tiled = m_snes_vram[((((tx >> 3) & 0x7f) + (((ty >> 3) & 0x7f) * 128)) * 2) % SNES_VRAM_SIZE] << 7;
695            colour = m_snes_vram[(tiled + ((tx & 0x07) * 2) + ((ty & 0x07) * 16) + 1) % SNES_VRAM_SIZE];
693            tiled = m_vram[((((tx >> 3) & 0x7f) + (((ty >> 3) & 0x7f) * 128)) * 2) % SNES_VRAM_SIZE] << 7;
694            colour = m_vram[(tiled + ((tx & 0x07) * 2) + ((ty & 0x07) * 16) + 1) % SNES_VRAM_SIZE];
696695            break;
697696         case 0x02:  /* Single colour backdrop screen if outside screen area */
698697            if ((tx >= 0) && (tx < 1024) && (ty >= 0) && (ty < 1024))
699698            {
700               tiled = m_snes_vram[((((tx >> 3) & 0x7f) + (((ty >> 3) & 0x7f) * 128)) * 2) % SNES_VRAM_SIZE] << 7;
701               colour = m_snes_vram[(tiled + ((tx & 0x07) * 2) + ((ty & 0x07) * 16) + 1) % SNES_VRAM_SIZE];
699               tiled = m_vram[((((tx >> 3) & 0x7f) + (((ty >> 3) & 0x7f) * 128)) * 2) % SNES_VRAM_SIZE] << 7;
700               colour = m_vram[(tiled + ((tx & 0x07) * 2) + ((ty & 0x07) * 16) + 1) % SNES_VRAM_SIZE];
702701            }
703702            else
704703               colour = 0;
705704            break;
706705         case 0x03:  /* Character 0x00 repeat if outside screen area */
707706            if ((tx >= 0) && (tx < 1024) && (ty >= 0) && (ty < 1024))
708               tiled = m_snes_vram[((((tx >> 3) & 0x7f) + (((ty >> 3) & 0x7f) * 128)) * 2) % SNES_VRAM_SIZE] << 7;
707               tiled = m_vram[((((tx >> 3) & 0x7f) + (((ty >> 3) & 0x7f) * 128)) * 2) % SNES_VRAM_SIZE] << 7;
709708            else
710709               tiled = 0;
711710
712            colour = m_snes_vram[(tiled + ((tx & 0x07) * 2) + ((ty & 0x07) * 16) + 1) % SNES_VRAM_SIZE];
711            colour = m_vram[(tiled + ((tx & 0x07) * 2) + ((ty & 0x07) * 16) + 1) % SNES_VRAM_SIZE];
713712            break;
714713      }
715714
r21558r21559
732731         if (scanlines[screen].enable)
733732         {
734733            UINT8 clr = colour;
735            UINT8 clipmask = snes_ppu.clipmasks[layer][xpos];
734            UINT8 clipmask = m_clipmasks[layer][xpos];
736735
737736#if SNES_LAYER_DEBUG
738737            if (debug_options.windows_disabled)
r21558r21559
749748               /* Direct select, but only outside EXTBG! */
750749               // Direct color format is: 0 | BB000 | GGG00 | RRR00, HW confirms that the data is zero padded.
751750               // In other words, like normal direct color, with pal = 0
752               c = snes_get_bgcolor(snes_ppu.direct_color && layer == SNES_BG1, 0, clr);
751               c = snes_get_bgcolor(m_direct_color && layer == SNES_BG1, 0, clr);
753752               snes_set_scanline_pixel(screen, xpos, c, priority, layer, 0);
754753            }
755754         }
r21558r21559
819818 * Update sprite settings for next line.
820819 *********************************************/
821820
822void snes_state::snes_update_obsel( void )
821void snes_ppu_class::snes_update_obsel( void )
823822{
824   snes_ppu.layer[SNES_OAM].charmap = snes_ppu.oam.next_charmap;
825   snes_ppu.oam.name_select = snes_ppu.oam.next_name_select;
823   m_layer[SNES_OAM].charmap = m_oam.next_charmap;
824   m_oam.name_select = m_oam.next_name_select;
826825
827   if (snes_ppu.oam.size != snes_ppu.oam.next_size)
826   if (m_oam.size != m_oam.next_size)
828827   {
829      snes_ppu.oam.size = snes_ppu.oam.next_size;
830      snes_ppu.update_oam_list = 1;
828      m_oam.size = m_oam.next_size;
829      m_update_oam_list = 1;
831830   }
832831}
833832
r21558r21559
837836 * Build a list of the available obj in OAM ram.
838837 *********************************************/
839838
840void snes_state::snes_oam_list_build( void )
839void snes_ppu_class::snes_oam_list_build( void )
841840{
842   UINT8 *oamram = (UINT8 *)m_snes_oam;
841   UINT8 *oamram = (UINT8 *)m_oam_ram;
843842   INT16 oam = 0x1ff;
844843   UINT16 oam_extra = oam + 0x20;
845844   UINT16 extra = 0;
846845   int ii;
847846
848   snes_ppu.update_oam_list = 0;       // eventually, we can optimize the code by only calling this function when there is a change in size
847   m_update_oam_list = 0;       // eventually, we can optimize the code by only calling this function when there is a change in size
849848
850849   for (ii = 127; ii >= 0; ii--)
851850   {
r21558r21559
865864      oam_spritelist[ii].x |= ((extra & 0x80) << 1);
866865      extra <<= 1;
867866
868      oam_spritelist[ii].y *= snes_ppu.obj_interlace;
867      oam_spritelist[ii].y *= m_obj_interlace;
869868      oam_spritelist[ii].y &= 0x1ff;
870869
871870      oam_spritelist[ii].x &= 0x1ff;
872871
873872      /* Determine object size */
874      switch (snes_ppu.oam.size)
873      switch (m_oam.size)
875874      {
876875      case 0:         /* 8x8 or 16x16 */
877876         oam_spritelist[ii].width  = oam_spritelist[ii].size ? 2 : 1;
r21558r21559
900899      case 6:         /* undocumented: 16x32 or 32x64 */
901900         oam_spritelist[ii].width  = oam_spritelist[ii].size ? 4 : 2;
902901         oam_spritelist[ii].height = oam_spritelist[ii].size ? 8 : 4;
903         if (snes_ppu.obj_interlace && !oam_spritelist[ii].size)
902         if (m_obj_interlace && !oam_spritelist[ii].size)
904903            oam_spritelist[ii].height = 2;
905904         break;
906905      case 7:         /* undocumented: 16x32 or 32x32 */
907906         oam_spritelist[ii].width  = oam_spritelist[ii].size ? 4 : 2;
908907         oam_spritelist[ii].height = oam_spritelist[ii].size ? 4 : 4;
909         if (snes_ppu.obj_interlace && !oam_spritelist[ii].size)
908         if (m_obj_interlace && !oam_spritelist[ii].size)
910909            oam_spritelist[ii].height = 2;
911910         break;
912911      default:
913912         /* we should never enter here... */
914         logerror("Object size unsupported: %d\n", snes_ppu.oam.size);
913         logerror("Object size unsupported: %d\n", m_oam.size);
915914         break;
916915      }
917916   }
r21558r21559
924923 * scanline
925924 *********************************************/
926925
927int snes_state::is_sprite_on_scanline( UINT16 curline, UINT8 sprite )
926int snes_ppu_class::is_sprite_on_scanline( UINT16 curline, UINT8 sprite )
928927{
929928   //if sprite is entirely offscreen and doesn't wrap around to the left side of the screen,
930929   //then it is not counted. this *should* be 256, and not 255, even though dot 256 is offscreen.
r21558r21559
949948 * scanline.
950949 *********************************************/
951950
952void snes_state::snes_update_objects_rto( UINT16 curline )
951void snes_ppu_class::snes_update_objects_rto( UINT16 curline )
953952{
954953   int ii, jj, active_sprite;
955954   UINT8 range_over, time_over;
r21558r21559
967966   time_over = 0;
968967
969968   /* setup the proper line */
970   curline /= snes_ppu.interlace;
971   curline *= snes_ppu.obj_interlace;
969   curline /= m_interlace;
970   curline *= m_obj_interlace;
972971
973972   /* reset the list of first 32 objects which intersect current scanline */
974973   memset(oam_itemlist, 0xff, 32);
r21558r21559
976975   /* populate the list of 32 objects */
977976   for (ii = 0; ii < 128; ii++)
978977   {
979      active_sprite = (ii + snes_ppu.oam.first_sprite) & 0x7f;
978      active_sprite = (ii + m_oam.first_sprite) & 0x7f;
980979
981980      if (!is_sprite_on_scanline(curline, active_sprite))
982981         continue;
r21558r21559
10101009      pal = oam_spritelist[active_sprite].pal;
10111010
10121011      /* Adjust y, if past maximum position (for sprites which overlap between top & bottom) */
1013      if (y >= (0x100 - 16) * snes_ppu.interlace)
1014         y -= (0x100) * snes_ppu.interlace;
1012      if (y >= (0x100 - 16) * m_interlace)
1013         y -= (0x100) * m_interlace;
10151014
10161015      if (curline >= y && curline < (y + (height << 3)))
10171016      {
10181017         /* Only objects using tiles over 255 use name select */
1019         name_sel = (tile < 256) ? 0 : snes_ppu.oam.name_select;
1018         name_sel = (tile < 256) ? 0 : m_oam.name_select;
10201019
10211020         ys = (curline - y) >> 3;
10221021         line = (curline - y) % 8;
r21558r21559
10501049
10511050   /* set Range Over flag if necessary */
10521051   if (range_over > 32)
1053      snes_ppu.stat77_flags |= 0x40;
1052      m_stat77_flags |= 0x40;
10541053
10551054   /* set Time Over flag if necessary */
10561055   if (time_over > 34)
1057      snes_ppu.stat77_flags |= 0x80;
1056      m_stat77_flags |= 0x80;
10581057}
10591058
10601059/*********************************************
r21558r21559
10631062 * Update an entire line of sprites.
10641063 *********************************************/
10651064
1066void snes_state::snes_update_objects( UINT8 priority_oam0, UINT8 priority_oam1, UINT8 priority_oam2, UINT8 priority_oam3 )
1065void snes_ppu_class::snes_update_objects( UINT8 priority_oam0, UINT8 priority_oam1, UINT8 priority_oam2, UINT8 priority_oam3 )
10671066{
10681067   UINT8 pri, priority[4];
10691068   UINT32 charaddr;
r21558r21559
10741073      return;
10751074#endif /* SNES_LAYER_DEBUG */
10761075
1077   scanlines[SNES_MAINSCREEN].enable = snes_ppu.layer[SNES_OAM].main_bg_enabled;
1078   scanlines[SNES_SUBSCREEN].enable = snes_ppu.layer[SNES_OAM].sub_bg_enabled;
1079   scanlines[SNES_MAINSCREEN].clip = snes_ppu.layer[SNES_OAM].main_window_enabled;
1080   scanlines[SNES_SUBSCREEN].clip = snes_ppu.layer[SNES_OAM].sub_window_enabled;
1076   scanlines[SNES_MAINSCREEN].enable = m_layer[SNES_OAM].main_bg_enabled;
1077   scanlines[SNES_SUBSCREEN].enable = m_layer[SNES_OAM].sub_bg_enabled;
1078   scanlines[SNES_MAINSCREEN].clip = m_layer[SNES_OAM].main_window_enabled;
1079   scanlines[SNES_SUBSCREEN].clip = m_layer[SNES_OAM].sub_window_enabled;
10811080
10821081   if (!scanlines[SNES_MAINSCREEN].enable && !scanlines[SNES_SUBSCREEN].enable)
10831082      return;
10841083
1085   charaddr = snes_ppu.layer[SNES_OAM].charmap << 13;
1084   charaddr = m_layer[SNES_OAM].charmap << 13;
10861085
10871086   priority[0] = priority_oam0;
10881087   priority[1] = priority_oam1;
r21558r21559
11241123 * Update Mode X line.
11251124 *********************************************/
11261125
1127void snes_state::snes_update_mode_0( UINT16 curline )
1126void snes_ppu_class::snes_update_mode_0( UINT16 curline )
11281127{
11291128#if SNES_LAYER_DEBUG
11301129   if (debug_options.mode_disabled[0])
r21558r21559
11381137   snes_update_line(curline, SNES_BG4, 1, 4,  SNES_COLOR_DEPTH_2BPP, 0, SNES_OPT_NONE, 0);
11391138}
11401139
1141void snes_state::snes_update_mode_1( UINT16 curline )
1140void snes_ppu_class::snes_update_mode_1( UINT16 curline )
11421141{
11431142#if SNES_LAYER_DEBUG
11441143   if (debug_options.mode_disabled[1])
11451144      return;
11461145#endif /* SNES_LAYER_DEBUG */
11471146
1148   if (!snes_ppu.bg3_priority_bit)
1147   if (!m_bg3_priority_bit)
11491148   {
11501149      snes_update_objects(2, 4, 7, 10);
11511150      snes_update_line(curline, SNES_BG1, 6, 9, SNES_COLOR_DEPTH_4BPP, 0, SNES_OPT_NONE, 0);
r21558r21559
11611160   }
11621161}
11631162
1164void snes_state::snes_update_mode_2( UINT16 curline )
1163void snes_ppu_class::snes_update_mode_2( UINT16 curline )
11651164{
11661165#if SNES_LAYER_DEBUG
11671166   if (debug_options.mode_disabled[2])
r21558r21559
11731172   snes_update_line(curline, SNES_BG2, 1, 5, SNES_COLOR_DEPTH_4BPP, 0, SNES_OPT_MODE2, 0);
11741173}
11751174
1176void snes_state::snes_update_mode_3( UINT16 curline )
1175void snes_ppu_class::snes_update_mode_3( UINT16 curline )
11771176{
11781177#if SNES_LAYER_DEBUG
11791178   if (debug_options.mode_disabled[3])
r21558r21559
11811180#endif /* SNES_LAYER_DEBUG */
11821181
11831182   snes_update_objects(2, 4, 6, 8);
1184   snes_update_line(curline, SNES_BG1, 3, 7, SNES_COLOR_DEPTH_8BPP, 0, SNES_OPT_NONE, snes_ppu.direct_color);
1183   snes_update_line(curline, SNES_BG1, 3, 7, SNES_COLOR_DEPTH_8BPP, 0, SNES_OPT_NONE, m_direct_color);
11851184   snes_update_line(curline, SNES_BG2, 1, 5, SNES_COLOR_DEPTH_4BPP, 0, SNES_OPT_NONE, 0);
11861185}
11871186
1188void snes_state::snes_update_mode_4( UINT16 curline )
1187void snes_ppu_class::snes_update_mode_4( UINT16 curline )
11891188{
11901189#if SNES_LAYER_DEBUG
11911190   if (debug_options.mode_disabled[4])
r21558r21559
11931192#endif /* SNES_LAYER_DEBUG */
11941193
11951194   snes_update_objects(2, 4, 6, 8);
1196   snes_update_line(curline, SNES_BG1, 3, 7, SNES_COLOR_DEPTH_8BPP, 0, SNES_OPT_MODE4, snes_ppu.direct_color);
1195   snes_update_line(curline, SNES_BG1, 3, 7, SNES_COLOR_DEPTH_8BPP, 0, SNES_OPT_MODE4, m_direct_color);
11971196   snes_update_line(curline, SNES_BG2, 1, 5, SNES_COLOR_DEPTH_2BPP, 0, SNES_OPT_MODE4, 0);
11981197}
11991198
1200void snes_state::snes_update_mode_5( UINT16 curline )
1199void snes_ppu_class::snes_update_mode_5( UINT16 curline )
12011200{
12021201#if SNES_LAYER_DEBUG
12031202   if (debug_options.mode_disabled[5])
r21558r21559
12091208   snes_update_line(curline, SNES_BG2, 1, 5, SNES_COLOR_DEPTH_2BPP, 1, SNES_OPT_NONE, 0);
12101209}
12111210
1212void snes_state::snes_update_mode_6( UINT16 curline )
1211void snes_ppu_class::snes_update_mode_6( UINT16 curline )
12131212{
12141213#if SNES_LAYER_DEBUG
12151214   if (debug_options.mode_disabled[6])
r21558r21559
12201219   snes_update_line(curline, SNES_BG1, 2, 5, SNES_COLOR_DEPTH_4BPP, 1, SNES_OPT_MODE6, 0);
12211220}
12221221
1223void snes_state::snes_update_mode_7( UINT16 curline )
1222void snes_ppu_class::snes_update_mode_7( UINT16 curline )
12241223{
12251224#if SNES_LAYER_DEBUG
12261225   if (debug_options.mode_disabled[7])
12271226      return;
12281227#endif /* SNES_LAYER_DEBUG */
12291228
1230   if (!snes_ppu.mode7.extbg)
1229   if (!m_mode7.extbg)
12311230   {
12321231      snes_update_objects(1, 3, 4, 5);
12331232      snes_update_line_mode7(curline, SNES_BG1, 2, 2);
r21558r21559
12461245 * Draw the whole screen (Mode 0 -> 7).
12471246 *********************************************/
12481247
1249void snes_state::snes_draw_screens( UINT16 curline )
1248void snes_ppu_class::snes_draw_screens( UINT16 curline )
12501249{
1251   switch (snes_ppu.mode)
1250   switch (m_mode)
12521251   {
12531252      case 0: snes_update_mode_0(curline); break;     /* Mode 0 */
12541253      case 1: snes_update_mode_1(curline); break;     /* Mode 1 */
r21558r21559
12741273 * XNOR: ###...##...###     ...###..###...
12751274 *********************************************/
12761275
1277void snes_state::snes_update_windowmasks( void )
1276void snes_ppu_class::snes_update_windowmasks( void )
12781277{
12791278   UINT16 ii, jj;
12801279   INT8 w1, w2;
12811280
1282   snes_ppu.update_windows = 0;        /* reset the flag */
1281   m_update_windows = 0;        /* reset the flag */
12831282
12841283   for (ii = 0; ii < SNES_SCR_WIDTH; ii++)
12851284   {
r21558r21559
12871286      /* jj = layer */
12881287      for (jj = 0; jj < 6; jj++)
12891288      {
1290         snes_ppu.clipmasks[jj][ii] = 0xff;  /* let's start from un-masked */
1289         m_clipmasks[jj][ii] = 0xff;  /* let's start from un-masked */
12911290         w1 = w2 = -1;
12921291
1293         if (snes_ppu.layer[jj].window1_enabled)
1292         if (m_layer[jj].window1_enabled)
12941293         {
12951294            /* Default to mask area inside */
1296            if ((ii < snes_ppu.window1_left) || (ii > snes_ppu.window1_right))
1295            if ((ii < m_window1_left) || (ii > m_window1_right))
12971296               w1 = 0;
12981297            else
12991298               w1 = 1;
13001299
13011300            /* If mask area is outside then swap */
1302            if (snes_ppu.layer[jj].window1_invert)
1301            if (m_layer[jj].window1_invert)
13031302               w1 = !w1;
13041303         }
13051304
1306         if (snes_ppu.layer[jj].window2_enabled)
1305         if (m_layer[jj].window2_enabled)
13071306         {
1308            if ((ii < snes_ppu.window2_left) || (ii > snes_ppu.window2_right))
1307            if ((ii < m_window2_left) || (ii > m_window2_right))
13091308               w2 = 0;
13101309            else
13111310               w2 = 1;
1312            if (snes_ppu.layer[jj].window2_invert)
1311            if (m_layer[jj].window2_invert)
13131312               w2 = !w2;
13141313         }
13151314
13161315         /* mask if the appropriate expression is true */
13171316         if (w1 >= 0 && w2 >= 0)
13181317         {
1319            switch (snes_ppu.layer[jj].wlog_mask)
1318            switch (m_layer[jj].wlog_mask)
13201319            {
13211320               case 0x00:  /* OR */
1322                  snes_ppu.clipmasks[jj][ii] = (w1 | w2) ? 0x00 : 0xff;
1321                  m_clipmasks[jj][ii] = (w1 | w2) ? 0x00 : 0xff;
13231322                  break;
13241323               case 0x01:  /* AND */
1325                  snes_ppu.clipmasks[jj][ii] = (w1 & w2) ? 0x00 : 0xff;
1324                  m_clipmasks[jj][ii] = (w1 & w2) ? 0x00 : 0xff;
13261325                  break;
13271326               case 0x02:  /* XOR */
1328                  snes_ppu.clipmasks[jj][ii] = (w1 ^ w2) ? 0x00 : 0xff;
1327                  m_clipmasks[jj][ii] = (w1 ^ w2) ? 0x00 : 0xff;
13291328                  break;
13301329               case 0x03:  /* XNOR */
1331                  snes_ppu.clipmasks[jj][ii] = !(w1 ^ w2) ? 0x00 : 0xff;
1330                  m_clipmasks[jj][ii] = !(w1 ^ w2) ? 0x00 : 0xff;
13321331                  break;
13331332            }
13341333         }
13351334         else if (w1 >= 0)
1336            snes_ppu.clipmasks[jj][ii] = w1 ? 0x00 : 0xff;
1335            m_clipmasks[jj][ii] = w1 ? 0x00 : 0xff;
13371336         else if (w2 >= 0)
1338            snes_ppu.clipmasks[jj][ii] = w2 ? 0x00 : 0xff;
1337            m_clipmasks[jj][ii] = w2 ? 0x00 : 0xff;
13391338      }
13401339   }
13411340}
r21558r21559
13481347 * possibly be handy for some minor optimization
13491348 *********************************************/
13501349
1351void snes_state::snes_update_offsets( void )
1350void snes_ppu_class::snes_update_offsets( void )
13521351{
13531352   int ii;
13541353   for (ii = 0; ii < 4; ii++)
13551354   {
13561355   }
1357   snes_ppu.update_offsets = 0;
1356   m_update_offsets = 0;
13581357}
13591358
13601359/*****************************************
r21558r21559
13651364 * color math.
13661365 *****************************************/
13671366
1368inline void snes_state::snes_draw_blend( UINT16 offset, UINT16 *colour, UINT8 prevent_color_math, UINT8 black_pen_clip, int switch_screens )
1367inline void snes_ppu_class::snes_draw_blend( UINT16 offset, UINT16 *colour, UINT8 prevent_color_math, UINT8 black_pen_clip, int switch_screens )
13691368{
13701369#if SNES_LAYER_DEBUG
13711370   if (debug_options.colormath_disabled)
r21558r21559
13781377      offset -= 1;
13791378
13801379   if ((black_pen_clip == SNES_CLIP_ALWAYS) ||
1381      (black_pen_clip == SNES_CLIP_IN && snes_ppu.clipmasks[SNES_COLOR][offset]) ||
1382      (black_pen_clip == SNES_CLIP_OUT && !snes_ppu.clipmasks[SNES_COLOR][offset]))
1380      (black_pen_clip == SNES_CLIP_IN && m_clipmasks[SNES_COLOR][offset]) ||
1381      (black_pen_clip == SNES_CLIP_OUT && !m_clipmasks[SNES_COLOR][offset]))
13831382      *colour = 0; //clip to black before color math
13841383
13851384   if (prevent_color_math == SNES_CLIP_ALWAYS) // blending mode 3 == always OFF
13861385      return;
13871386
13881387   if ((prevent_color_math == SNES_CLIP_NEVER) ||
1389      (prevent_color_math == SNES_CLIP_IN  && !snes_ppu.clipmasks[SNES_COLOR][offset]) ||
1390      (prevent_color_math == SNES_CLIP_OUT && snes_ppu.clipmasks[SNES_COLOR][offset]))
1388      (prevent_color_math == SNES_CLIP_IN  && !m_clipmasks[SNES_COLOR][offset]) ||
1389      (prevent_color_math == SNES_CLIP_OUT && m_clipmasks[SNES_COLOR][offset]))
13911390   {
13921391      UINT16 r, g, b;
13931392      struct SCANLINE *subscreen;
r21558r21559
14051404         subscreen = switch_screens ? &scanlines[SNES_MAINSCREEN] : &scanlines[SNES_SUBSCREEN];
14061405      }
14071406
1408      if (snes_ppu.sub_add_mode) /* SNES_SUBSCREEN*/
1407      if (m_sub_add_mode) /* SNES_SUBSCREEN*/
14091408      {
1410         if (!BIT(snes_ppu.color_modes, 7))
1409         if (!BIT(m_color_modes, 7))
14111410         {
14121411            /* 0x00 add */
14131412            r = (*colour & 0x1f) + (subscreen->buffer[offset] & 0x1f);
r21558r21559
14261425            if (b > 0x1f) b = 0;
14271426         }
14281427         /* only halve if the color is not the back colour */
1429         if (BIT(snes_ppu.color_modes, 6) && (subscreen->buffer[offset] != m_snes_cgram[FIXED_COLOUR]))
1428         if (BIT(m_color_modes, 6) && (subscreen->buffer[offset] != m_cgram[FIXED_COLOUR]))
14301429         {
14311430            r >>= 1;
14321431            g >>= 1;
r21558r21559
14351434      }
14361435      else /* Fixed colour */
14371436      {
1438         if (!BIT(snes_ppu.color_modes, 7))
1437         if (!BIT(m_color_modes, 7))
14391438         {
14401439            /* 0x00 add */
1441            r = (*colour & 0x1f) + (m_snes_cgram[FIXED_COLOUR] & 0x1f);
1442            g = ((*colour & 0x3e0) >> 5) + ((m_snes_cgram[FIXED_COLOUR] & 0x3e0) >> 5);
1443            b = ((*colour & 0x7c00) >> 10) + ((m_snes_cgram[FIXED_COLOUR] & 0x7c00) >> 10);
1440            r = (*colour & 0x1f) + (m_cgram[FIXED_COLOUR] & 0x1f);
1441            g = ((*colour & 0x3e0) >> 5) + ((m_cgram[FIXED_COLOUR] & 0x3e0) >> 5);
1442            b = ((*colour & 0x7c00) >> 10) + ((m_cgram[FIXED_COLOUR] & 0x7c00) >> 10);
14441443            clip_max = 1;
14451444         }
14461445         else
14471446         {
14481447            /* 0x80: sub */
1449            r = (*colour & 0x1f) - (m_snes_cgram[FIXED_COLOUR] & 0x1f);
1450            g = ((*colour & 0x3e0) >> 5) - ((m_snes_cgram[FIXED_COLOUR] & 0x3e0) >> 5);
1451            b = ((*colour & 0x7c00) >> 10) - ((m_snes_cgram[FIXED_COLOUR] & 0x7c00) >> 10);
1448            r = (*colour & 0x1f) - (m_cgram[FIXED_COLOUR] & 0x1f);
1449            g = ((*colour & 0x3e0) >> 5) - ((m_cgram[FIXED_COLOUR] & 0x3e0) >> 5);
1450            b = ((*colour & 0x7c00) >> 10) - ((m_cgram[FIXED_COLOUR] & 0x7c00) >> 10);
14521451            if (r > 0x1f) r = 0;
14531452            if (g > 0x1f) g = 0;
14541453            if (b > 0x1f) b = 0;
14551454         }
14561455         /* halve if necessary */
1457         if (BIT(snes_ppu.color_modes, 6))
1456         if (BIT(m_color_modes, 6))
14581457         {
14591458            r >>= 1;
14601459            g >>= 1;
r21558r21559
14931492 * the optimized averaging algorithm.
14941493 *********************************************/
14951494
1496void snes_state::snes_refresh_scanline( running_machine &machine, bitmap_rgb32 &bitmap, UINT16 curline )
1495void snes_ppu_class::snes_refresh_scanline( running_machine &machine, bitmap_rgb32 &bitmap, UINT16 curline )
14971496{
14981497   UINT16 ii;
14991498   int x;
r21558r21559
15051504
15061505   g_profiler.start(PROFILER_VIDEO);
15071506
1508   if (snes_ppu.screen_disabled) /* screen is forced blank */
1507   if (m_screen_disabled) /* screen is forced blank */
15091508      for (x = 0; x < SNES_SCR_WIDTH * 2; x++)
15101509         bitmap.pix32(curline, x) = RGB_BLACK;
15111510   else
15121511   {
15131512      /* Update clip window masks if necessary */
1514      if (snes_ppu.update_windows)
1513      if (m_update_windows)
15151514         snes_update_windowmasks();
15161515      /* Update the offsets if necessary */
1517      if (snes_ppu.update_offsets)
1516      if (m_update_offsets)
15181517         snes_update_offsets();
15191518
15201519      /* Clear priority */
r21558r21559
15321531      /* Draw back colour */
15331532      for (ii = 0; ii < SNES_SCR_WIDTH; ii++)
15341533      {
1535         if (snes_ppu.mode == 5 || snes_ppu.mode == 6 || snes_ppu.pseudo_hires)
1536            scanlines[SNES_SUBSCREEN].buffer[ii] = m_snes_cgram[0];
1534         if (m_mode == 5 || m_mode == 6 || m_pseudo_hires)
1535            scanlines[SNES_SUBSCREEN].buffer[ii] = m_cgram[0];
15371536         else
1538            scanlines[SNES_SUBSCREEN].buffer[ii] = m_snes_cgram[FIXED_COLOUR];
1537            scanlines[SNES_SUBSCREEN].buffer[ii] = m_cgram[FIXED_COLOUR];
15391538
1540         scanlines[SNES_MAINSCREEN].buffer[ii] = m_snes_cgram[0];
1539         scanlines[SNES_MAINSCREEN].buffer[ii] = m_cgram[0];
15411540      }
15421541
15431542      /* Prepare OAM for this scanline */
r21558r21559
15491548      snes_update_obsel();
15501549
15511550#if SNES_LAYER_DEBUG
1552      if (snes_dbg_video(machine, curline))
1551      if (snes_dbg_video(machine, curline, snes_ram))
15531552      {
15541553         g_profiler.stop();
15551554         return;
r21558r21559
15701569
15711570      /* Draw the scanline to screen */
15721571
1573      fade = snes_ppu.screen_brightness;
1572      fade = m_screen_brightness;
15741573
15751574      for (x = 0; x < SNES_SCR_WIDTH; x++)
15761575      {
15771576         int r, g, b, hires;
15781577         UINT16 tmp_col[2];
1579         hires = (snes_ppu.mode != 5 && snes_ppu.mode != 6 && !snes_ppu.pseudo_hires) ? 0 : 1;
1578         hires = (m_mode != 5 && m_mode != 6 && !m_pseudo_hires) ? 0 : 1;
15801579
15811580         /* in hires, the first pixel (of 512) is subscreen pixel, then the first mainscreen pixel follows, and so on... */
15821581         if (!hires)
r21558r21559
15841583            c = scanline1->buffer[x];
15851584
15861585            /* perform color math if the layer wants it (except if it's an object > 192) */
1587            if (!scanline1->blend_exception[x] && snes_ppu.layer[scanline1->layer[x]].color_math)
1588               snes_draw_blend(x, &c, snes_ppu.prevent_color_math, snes_ppu.clip_to_black, 0);
1586            if (!scanline1->blend_exception[x] && m_layer[scanline1->layer[x]].color_math)
1587               snes_draw_blend(x, &c, m_prevent_color_math, m_clip_to_black, 0);
15891588
15901589            r = ((c & 0x1f) * fade) >> 4;
15911590            g = (((c & 0x3e0) >> 5) * fade) >> 4;
r21558r21559
16001599            c = scanline1->buffer[x];
16011600
16021601            /* perform color math if the layer wants it (except if it's an object > 192) */
1603            if (!scanline1->blend_exception[x] && snes_ppu.layer[scanline1->layer[x]].color_math)
1604               snes_draw_blend(x, &c, snes_ppu.prevent_color_math, snes_ppu.clip_to_black, 0);
1602            if (!scanline1->blend_exception[x] && m_layer[scanline1->layer[x]].color_math)
1603               snes_draw_blend(x, &c, m_prevent_color_math, m_clip_to_black, 0);
16051604
16061605            tmp_col[1] = c;
16071606
r21558r21559
16131612            (which has no previous mainscreen pixel) is undocumented. Until more info are discovered, we (arbitrarily)
16141613            apply to it the same color math as the *next* mainscreen pixel (i.e. mainscreen pixel 0), which seems as good as
16151614            any other choice */
1616            if (x == 0 && !scanline1->blend_exception[0] && snes_ppu.layer[scanline1->layer[0]].color_math)
1617               snes_draw_blend(0, &c, snes_ppu.prevent_color_math, snes_ppu.clip_to_black, 1);
1618            else if (x > 0  && !scanline1->blend_exception[x - 1] && snes_ppu.layer[scanline1->layer[x - 1]].color_math)
1619               snes_draw_blend(x, &c, snes_ppu.prevent_color_math, snes_ppu.clip_to_black, 1);
1615            if (x == 0 && !scanline1->blend_exception[0] && m_layer[scanline1->layer[0]].color_math)
1616               snes_draw_blend(0, &c, m_prevent_color_math, m_clip_to_black, 1);
1617            else if (x > 0  && !scanline1->blend_exception[x - 1] && m_layer[scanline1->layer[x - 1]].color_math)
1618               snes_draw_blend(x, &c, m_prevent_color_math, m_clip_to_black, 1);
16201619
16211620            tmp_col[0] = c;
16221621
r21558r21559
16521651   g_profiler.stop();
16531652}
16541653
1655VIDEO_START( snes )
1654void snes_ppu_class::ppu_start(running_machine &machine)
16561655{
1657   snes_state *state = machine.driver_data<snes_state>();
1658   int i,j;
1659
1660#if SNES_LAYER_DEBUG
1661   memset(&debug_options, 0, sizeof(debug_options));
1662#endif
1663
1664   state->m_snes_vram = auto_alloc_array(machine, UINT8, SNES_VRAM_SIZE);
1665   state->m_snes_cgram = auto_alloc_array(machine, UINT16, SNES_CGRAM_SIZE/2);
1666   state->m_snes_oam = auto_alloc_array(machine, UINT16, SNES_OAM_SIZE/2);
1667
1656   m_vram = auto_alloc_array(machine, UINT8, SNES_VRAM_SIZE);
1657   m_cgram = auto_alloc_array(machine, UINT16, SNES_CGRAM_SIZE/2);
1658   m_oam_ram = auto_alloc_array(machine, UINT16, SNES_OAM_SIZE/2);
1659   
16681660   /* Inititialize registers/variables */
1669   snes_ppu.update_windows = 1;
1670   snes_ppu.beam.latch_vert = 0;
1671   snes_ppu.beam.latch_horz = 0;
1672   snes_ppu.beam.current_vert = 0;
1673   snes_ppu.beam.current_horz = 0;
1674   snes_ppu.beam.last_visible_line = 225; /* TODO: PAL setting */
1675   snes_ppu.mode = 0;
1676   snes_ppu.ppu1_version = 1;  // 5C77 chip version number, read by STAT77, only '1' is known
1677   snes_ppu.ppu2_version = 3;  // 5C78 chip version number, read by STAT78, only '2' & '3' encountered so far.
1678
1661   m_update_windows = 1;
1662   m_beam.latch_vert = 0;
1663   m_beam.latch_horz = 0;
1664   m_beam.current_vert = 0;
1665   m_beam.current_horz = 0;
1666   m_beam.last_visible_line = 225; /* TODO: PAL setting */
1667   m_mode = 0;
1668   m_ppu1_version = 1;  // 5C77 chip version number, read by STAT77, only '1' is known
1669   m_ppu2_version = 3;  // 5C78 chip version number, read by STAT78, only '2' & '3' encountered so far.
1670   
1671   
16791672   /* Inititialize mosaic table */
1680   for (j = 0; j < 16; j++)
1673   for (int j = 0; j < 16; j++)
16811674   {
1682      for (i = 0; i < 4096; i++)
1683         snes_ppu.mosaic_table[j][i] = (i / (j + 1)) * (j + 1);
1675      for (int i = 0; i < 4096; i++)
1676         m_mosaic_table[j][i] = (i / (j + 1)) * (j + 1);
16841677   }
1685
1678   
16861679   /* Init VRAM */
1687   memset(state->m_snes_vram, 0, SNES_VRAM_SIZE);
1688
1680   memset(m_vram, 0, SNES_VRAM_SIZE);
1681   
16891682   /* Init Palette RAM */
1690   memset((UINT8 *)state->m_snes_cgram, 0, SNES_CGRAM_SIZE);
1691
1683   memset((UINT8 *)m_cgram, 0, SNES_CGRAM_SIZE);
1684   
16921685   /* Init oam RAM */
1693   memset((UINT8 *)state->m_snes_oam, 0xff, SNES_OAM_SIZE);
1694
1695   for (i = 0; i < 6; i++)
1686   memset((UINT8 *)m_oam_ram, 0xff, SNES_OAM_SIZE);
1687   
1688   for (int i = 0; i < 6; i++)
16961689   {
1697      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].window1_enabled);
1698      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].window1_invert);
1699      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].window2_enabled);
1700      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].window2_invert);
1701      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].wlog_mask);
1702      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].color_math);
1703      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].charmap);
1704      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].tilemap);
1705      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].tilemap_size);
1706      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].tile_size);
1707      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].mosaic_enabled);
1708      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].main_window_enabled);
1709      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].sub_window_enabled);
1710      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].main_bg_enabled);
1711      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].sub_bg_enabled);
1712      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].hoffs);
1713      state_save_register_item(machine, "snes_ppu", NULL, i, snes_ppu.layer[i].voffs);
1714
1715      state_save_register_item_array(machine, "snes_ppu", NULL, i, snes_ppu.clipmasks[i]);
1690      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].window1_enabled);
1691      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].window1_invert);
1692      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].window2_enabled);
1693      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].window2_invert);
1694      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].wlog_mask);
1695      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].color_math);
1696      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].charmap);
1697      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].tilemap);
1698      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].tilemap_size);
1699      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].tile_size);
1700      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].mosaic_enabled);
1701      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].main_window_enabled);
1702      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].sub_window_enabled);
1703      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].main_bg_enabled);
1704      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].sub_bg_enabled);
1705      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].hoffs);
1706      state_save_register_item(machine, "snes_ppu", NULL, i, m_layer[i].voffs);
1707     
1708      state_save_register_item_array(machine, "snes_ppu", NULL, i, m_clipmasks[i]);
17161709   }
1710   
1711   state_save_register_global(machine, m_oam.address_low);
1712   state_save_register_global(machine, m_oam.address_high);
1713   state_save_register_global(machine, m_oam.saved_address_low);
1714   state_save_register_global(machine, m_oam.saved_address_high);
1715   state_save_register_global(machine, m_oam.address);
1716   state_save_register_global(machine, m_oam.priority_rotation);
1717   state_save_register_global(machine, m_oam.next_charmap);
1718   state_save_register_global(machine, m_oam.next_size);
1719   state_save_register_global(machine, m_oam.size);
1720   state_save_register_global(machine, m_oam.next_name_select);
1721   state_save_register_global(machine, m_oam.name_select);
1722   state_save_register_global(machine, m_oam.first_sprite);
1723   state_save_register_global(machine, m_oam.flip);
1724   state_save_register_global(machine, m_oam.write_latch);
1725   
1726   state_save_register_global(machine, m_beam.latch_horz);
1727   state_save_register_global(machine, m_beam.latch_vert);
1728   state_save_register_global(machine, m_beam.current_horz);
1729   state_save_register_global(machine, m_beam.current_vert);
1730   state_save_register_global(machine, m_beam.last_visible_line);
1731   state_save_register_global(machine, m_beam.interlace_count);
1732   
1733   state_save_register_global(machine, m_mode7.repeat);
1734   state_save_register_global(machine, m_mode7.hflip);
1735   state_save_register_global(machine, m_mode7.vflip);
1736   state_save_register_global(machine, m_mode7.matrix_a);
1737   state_save_register_global(machine, m_mode7.matrix_b);
1738   state_save_register_global(machine, m_mode7.matrix_c);
1739   state_save_register_global(machine, m_mode7.matrix_d);
1740   state_save_register_global(machine, m_mode7.origin_x);
1741   state_save_register_global(machine, m_mode7.origin_y);
1742   state_save_register_global(machine, m_mode7.hor_offset);
1743   state_save_register_global(machine, m_mode7.ver_offset);
1744   state_save_register_global(machine, m_mode7.extbg);
1745   
1746   state_save_register_global(machine, m_mosaic_size);
1747   state_save_register_global(machine, m_clip_to_black);
1748   state_save_register_global(machine, m_prevent_color_math);
1749   state_save_register_global(machine, m_sub_add_mode);
1750   state_save_register_global(machine, m_bg3_priority_bit);
1751   state_save_register_global(machine, m_direct_color);
1752   state_save_register_global(machine, m_ppu_last_scroll);
1753   state_save_register_global(machine, m_mode7_last_scroll);
1754   
1755   state_save_register_global(machine, m_ppu1_open_bus);
1756   state_save_register_global(machine, m_ppu2_open_bus);
1757   state_save_register_global(machine, m_ppu1_version);
1758   state_save_register_global(machine, m_ppu2_version);
1759   state_save_register_global(machine, m_window1_left);
1760   state_save_register_global(machine, m_window1_right);
1761   state_save_register_global(machine, m_window2_left);
1762   state_save_register_global(machine, m_window2_right);
1763   
1764   state_save_register_global(machine, m_update_windows);
1765   state_save_register_global(machine, m_update_offsets);
1766   state_save_register_global(machine, m_update_oam_list);
1767   state_save_register_global(machine, m_mode);
1768   state_save_register_global(machine, m_interlace);
1769   state_save_register_global(machine, m_obj_interlace);
1770   state_save_register_global(machine, m_screen_brightness);
1771   state_save_register_global(machine, m_screen_disabled);
1772   state_save_register_global(machine, m_pseudo_hires);
1773   state_save_register_global(machine, m_color_modes);
1774   state_save_register_global(machine, m_stat77_flags);
1775   
1776   state_save_register_global_pointer(machine, m_vram, SNES_VRAM_SIZE);
1777   state_save_register_global_pointer(machine, m_cgram, SNES_CGRAM_SIZE/2);
1778   state_save_register_global_pointer(machine, m_oam_ram, SNES_OAM_SIZE/2);   
1779}
17171780
1718   state_save_register_global(machine, snes_ppu.oam.address_low);
1719   state_save_register_global(machine, snes_ppu.oam.address_high);
1720   state_save_register_global(machine, snes_ppu.oam.saved_address_low);
1721   state_save_register_global(machine, snes_ppu.oam.saved_address_high);
1722   state_save_register_global(machine, snes_ppu.oam.address);
1723   state_save_register_global(machine, snes_ppu.oam.priority_rotation);
1724   state_save_register_global(machine, snes_ppu.oam.next_charmap);
1725   state_save_register_global(machine, snes_ppu.oam.next_size);
1726   state_save_register_global(machine, snes_ppu.oam.size);
1727   state_save_register_global(machine, snes_ppu.oam.next_name_select);
1728   state_save_register_global(machine, snes_ppu.oam.name_select);
1729   state_save_register_global(machine, snes_ppu.oam.first_sprite);
1730   state_save_register_global(machine, snes_ppu.oam.flip);
1731   state_save_register_global(machine, snes_ppu.oam.write_latch);
1781VIDEO_START( snes )
1782{
1783   snes_state *state = machine.driver_data<snes_state>();
17321784
1733   state_save_register_global(machine, snes_ppu.beam.latch_horz);
1734   state_save_register_global(machine, snes_ppu.beam.latch_vert);
1735   state_save_register_global(machine, snes_ppu.beam.current_horz);
1736   state_save_register_global(machine, snes_ppu.beam.current_vert);
1737   state_save_register_global(machine, snes_ppu.beam.last_visible_line);
1738   state_save_register_global(machine, snes_ppu.beam.interlace_count);
1785#if SNES_LAYER_DEBUG
1786   memset(&debug_options, 0, sizeof(debug_options));
1787#endif
17391788
1740   state_save_register_global(machine, snes_ppu.mode7.repeat);
1741   state_save_register_global(machine, snes_ppu.mode7.hflip);
1742   state_save_register_global(machine, snes_ppu.mode7.vflip);
1743   state_save_register_global(machine, snes_ppu.mode7.matrix_a);
1744   state_save_register_global(machine, snes_ppu.mode7.matrix_b);
1745   state_save_register_global(machine, snes_ppu.mode7.matrix_c);
1746   state_save_register_global(machine, snes_ppu.mode7.matrix_d);
1747   state_save_register_global(machine, snes_ppu.mode7.origin_x);
1748   state_save_register_global(machine, snes_ppu.mode7.origin_y);
1749   state_save_register_global(machine, snes_ppu.mode7.hor_offset);
1750   state_save_register_global(machine, snes_ppu.mode7.ver_offset);
1751   state_save_register_global(machine, snes_ppu.mode7.extbg);
1752
1753   state_save_register_global(machine, snes_ppu.mosaic_size);
1754   state_save_register_global(machine, snes_ppu.clip_to_black);
1755   state_save_register_global(machine, snes_ppu.prevent_color_math);
1756   state_save_register_global(machine, snes_ppu.sub_add_mode);
1757   state_save_register_global(machine, snes_ppu.bg3_priority_bit);
1758   state_save_register_global(machine, snes_ppu.direct_color);
1759   state_save_register_global(machine, snes_ppu.ppu_last_scroll);
1760   state_save_register_global(machine, snes_ppu.mode7_last_scroll);
1761
1762   state_save_register_global(machine, snes_ppu.ppu1_open_bus);
1763   state_save_register_global(machine, snes_ppu.ppu2_open_bus);
1764   state_save_register_global(machine, snes_ppu.ppu1_version);
1765   state_save_register_global(machine, snes_ppu.ppu2_version);
1766   state_save_register_global(machine, snes_ppu.window1_left);
1767   state_save_register_global(machine, snes_ppu.window1_right);
1768   state_save_register_global(machine, snes_ppu.window2_left);
1769   state_save_register_global(machine, snes_ppu.window2_right);
1770
1771   state_save_register_global(machine, snes_ppu.update_windows);
1772   state_save_register_global(machine, snes_ppu.update_offsets);
1773   state_save_register_global(machine, snes_ppu.update_oam_list);
1774   state_save_register_global(machine, snes_ppu.mode);
1775   state_save_register_global(machine, snes_ppu.interlace);
1776   state_save_register_global(machine, snes_ppu.obj_interlace);
1777   state_save_register_global(machine, snes_ppu.screen_brightness);
1778   state_save_register_global(machine, snes_ppu.screen_disabled);
1779   state_save_register_global(machine, snes_ppu.pseudo_hires);
1780   state_save_register_global(machine, snes_ppu.color_modes);
1781   state_save_register_global(machine, snes_ppu.stat77_flags);
1782
1783   state_save_register_global_pointer(machine, state->m_snes_vram, SNES_VRAM_SIZE);
1784   state_save_register_global_pointer(machine, state->m_snes_cgram, SNES_CGRAM_SIZE/2);
1785   state_save_register_global_pointer(machine, state->m_snes_oam, SNES_OAM_SIZE/2);
1789   state->m_ppu.ppu_start(machine);
17861790}
17871791
17881792UINT32 snes_state::snes_screen_update( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
17891793{
1794   snes_state *state = machine().driver_data<snes_state>();
17901795   int y;
17911796
17921797   /*NTSC SNES draw range is 1-225. */
17931798   for (y = cliprect.min_y; y <= cliprect.max_y; y++)
17941799   {
1795      snes_refresh_scanline(machine(), bitmap, y + 1);
1800      state->m_ppu.snes_refresh_scanline(machine(), bitmap, y + 1);
17961801   }
17971802   return 0;
17981803}
r21558r21559
18061811static const UINT16 vram_fgr_shiftab[4] = { 0, 5, 6, 7 };
18071812
18081813// utility function - latches the H/V counters.  Used by IRQ, writes to WRIO, etc.
1809void snes_latch_counters( running_machine &machine )
1814void snes_ppu_class::snes_latch_counters( running_machine &machine, UINT8 *ram_ptr )
18101815{
18111816   snes_state *state = machine.driver_data<snes_state>();
18121817
1813   snes_ppu.beam.current_horz = machine.primary_screen->hpos() / state->m_htmult;
1814   snes_ppu.beam.latch_vert = machine.primary_screen->vpos();
1815   snes_ppu.beam.latch_horz = snes_ppu.beam.current_horz;
1816   snes_ram[STAT78] |= 0x40;   // indicate we latched
1818   m_beam.current_horz = machine.primary_screen->hpos() / state->m_htmult;
1819   m_beam.latch_vert = machine.primary_screen->vpos();
1820   m_beam.latch_horz = m_beam.current_horz;
1821   ram_ptr[STAT78] |= 0x40;   // indicate we latched
18171822//  state->m_read_ophct = state->m_read_opvct = 0;    // clear read flags - 2009-08: I think we must clear these when STAT78 is read...
18181823
1819//  printf("latched @ H %d V %d\n", snes_ppu.beam.latch_horz, snes_ppu.beam.latch_vert);
1824//  printf("latched @ H %d V %d\n", m_beam.latch_horz, m_beam.latch_vert);
18201825}
18211826
1822static void snes_dynamic_res_change( running_machine &machine )
1827void snes_ppu_class::snes_dynamic_res_change( running_machine &machine, UINT8 *ram_ptr )
18231828{
18241829   snes_state *state = machine.driver_data<snes_state>();
18251830   rectangle visarea = machine.primary_screen->visible_area();
18261831   attoseconds_t refresh;
18271832
18281833   visarea.min_x = visarea.min_y = 0;
1829   visarea.max_y = snes_ppu.beam.last_visible_line * snes_ppu.interlace - 1;
1834   visarea.max_y = m_beam.last_visible_line * m_interlace - 1;
18301835   visarea.max_x = (SNES_SCR_WIDTH * 2) - 1;
18311836
1832   // fixme: should compensate for SNES_DBG_video
1833   if (snes_ppu.mode == 5 || snes_ppu.mode == 6 || snes_ppu.pseudo_hires)
1837   // fixme: should compensate for SNES_DBG_VIDEO
1838   if (m_mode == 5 || m_mode == 6 || m_pseudo_hires)
18341839      state->m_htmult = 2;
18351840   else
18361841      state->m_htmult = 1;
18371842
18381843   /* FIXME: does the timing changes when the gfx mode is equal to 5 or 6? */
1839   if ((snes_ram[STAT78] & 0x10) == SNES_NTSC)
1844   if ((ram_ptr[STAT78] & 0x10) == SNES_NTSC)
18401845      refresh = HZ_TO_ATTOSECONDS(DOTCLK_NTSC) * SNES_HTOTAL * SNES_VTOTAL_NTSC;
18411846   else
18421847      refresh = HZ_TO_ATTOSECONDS(DOTCLK_PAL) * SNES_HTOTAL * SNES_VTOTAL_PAL;
18431848
1844   if ((snes_ram[STAT78] & 0x10) == SNES_NTSC)
1845      machine.primary_screen->configure(SNES_HTOTAL * 2, SNES_VTOTAL_NTSC * snes_ppu.interlace, visarea, refresh);
1849   if ((ram_ptr[STAT78] & 0x10) == SNES_NTSC)
1850      machine.primary_screen->configure(SNES_HTOTAL * 2, SNES_VTOTAL_NTSC * m_interlace, visarea, refresh);
18461851   else
1847      machine.primary_screen->configure(SNES_HTOTAL * 2, SNES_VTOTAL_PAL * snes_ppu.interlace, visarea, refresh);
1852      machine.primary_screen->configure(SNES_HTOTAL * 2, SNES_VTOTAL_PAL * m_interlace, visarea, refresh);
18481853}
18491854
18501855/*************************************************
r21558r21559
18631868 when interlace is active.
18641869*************************************************/
18651870
1866inline UINT32 snes_get_vram_address( running_machine &machine )
1871inline UINT32 snes_ppu_class::snes_get_vram_address( running_machine &machine )
18671872{
18681873   snes_state *state = machine.driver_data<snes_state>();
18691874   UINT32 addr = state->m_vmadd;
r21558r21559
18781883   return addr << 1;
18791884}
18801885
1881READ8_MEMBER( snes_state::snes_vram_read )
1886READ8_MEMBER( snes_ppu_class::snes_vram_read )
18821887{
18831888   UINT8 res = 0;
18841889   offset &= 0xffff; // only 64KB are present on SNES
18851890
1886   if (snes_ppu.screen_disabled)
1887      res = m_snes_vram[offset];
1891   if (m_screen_disabled)
1892      res = m_vram[offset];
18881893   else
18891894   {
1890      UINT16 v = machine().primary_screen->vpos();
1891      UINT16 h = machine().primary_screen->hpos();
1895      UINT16 v = space.machine().primary_screen->vpos();
1896      UINT16 h = space.machine().primary_screen->hpos();
18921897      UINT16 ls = (((snes_ram[STAT78] & 0x10) == SNES_NTSC ? 525 : 625) >> 1) - 1;
18931898
1894      if (snes_ppu.interlace == 2)
1899      if (m_interlace == 2)
18951900         ls++;
18961901
18971902      if (v == ls && h == 1362)
18981903         res = 0;
1899      else if (v < snes_ppu.beam.last_visible_line - 1)
1904      else if (v < m_beam.last_visible_line - 1)
19001905         res = 0;
1901      else if (v == snes_ppu.beam.last_visible_line - 1)
1906      else if (v == m_beam.last_visible_line - 1)
19021907      {
19031908         if (h == 1362)
1904            res = m_snes_vram[offset];
1909            res = m_vram[offset];
19051910         else
19061911         {
19071912            //printf("%d %d VRAM read, CHECK!\n",h,v);
r21558r21559
19091914         }
19101915      }
19111916      else
1912         res = m_snes_vram[offset];
1917         res = m_vram[offset];
19131918   }
19141919   return res;
19151920}
19161921
1917WRITE8_MEMBER( snes_state::snes_vram_write )
1922WRITE8_MEMBER( snes_ppu_class::snes_vram_write )
19181923{
19191924   offset &= 0xffff; // only 64KB are present on SNES, Robocop 3 relies on this
19201925
1921   if (snes_ppu.screen_disabled)
1922      m_snes_vram[offset] = data;
1926   if (m_screen_disabled)
1927      m_vram[offset] = data;
19231928   else
19241929   {
1925      UINT16 v = machine().primary_screen->vpos();
1926      UINT16 h = machine().primary_screen->hpos();
1930      UINT16 v = space.machine().primary_screen->vpos();
1931      UINT16 h = space.machine().primary_screen->hpos();
19271932      if (v == 0)
19281933      {
19291934         if (h <= 4)
1930            m_snes_vram[offset] = data;
1935            m_vram[offset] = data;
19311936         else if (h == 6)
1932            m_snes_vram[offset] = snes_open_bus_r(space, 0);
1937            m_vram[offset] = snes_open_bus_r(space, 0);
19331938         else
19341939         {
19351940            //printf("%d %d VRAM write, CHECK!\n",h,v);
19361941            //no write
19371942         }
19381943      }
1939      else if (v < snes_ppu.beam.last_visible_line)
1944      else if (v < m_beam.last_visible_line)
19401945      {
19411946         //printf("%d %d VRAM write, CHECK!\n",h,v);
19421947         //no write
19431948      }
1944      else if (v == snes_ppu.beam.last_visible_line)
1949      else if (v == m_beam.last_visible_line)
19451950      {
19461951         if (h <= 4)
19471952         {
r21558r21559
19491954            //no write
19501955         }
19511956         else
1952            m_snes_vram[offset] = data;
1957            m_vram[offset] = data;
19531958      }
19541959      else
1955         m_snes_vram[offset] = data;
1960         m_vram[offset] = data;
19561961   }
19571962}
19581963
r21558r21559
19791984 to choose the high/low byte of the snes_oam word.
19801985*************************************************/
19811986
1982READ8_MEMBER( snes_state::snes_oam_read )
1987READ8_MEMBER( snes_ppu_class::snes_oam_read )
19831988{
19841989   offset &= 0x1ff;
19851990
19861991   if (offset & 0x100)
19871992      offset &= 0x10f;
19881993
1989   if (!snes_ppu.screen_disabled)
1994   if (!m_screen_disabled)
19901995   {
1991      UINT16 v = machine().primary_screen->vpos();
1996      UINT16 v = space.machine().primary_screen->vpos();
19921997
1993      if (v < snes_ppu.beam.last_visible_line)
1998      if (v < m_beam.last_visible_line)
19941999         offset = 0x010c;
19952000   }
19962001
1997   return (m_snes_oam[offset] >> (snes_ram[OAMDATA] << 3)) & 0xff;
2002   return (m_oam_ram[offset] >> (snes_ram[OAMDATA] << 3)) & 0xff;
19982003}
19992004
2000WRITE8_MEMBER( snes_state::snes_oam_write )
2005WRITE8_MEMBER( snes_ppu_class::snes_oam_write )
20012006{
20022007   offset &= 0x1ff;
20032008
20042009   if (offset & 0x100)
20052010      offset &= 0x10f;
20062011
2007   if (!snes_ppu.screen_disabled)
2012   if (!m_screen_disabled)
20082013   {
2009      UINT16 v = machine().primary_screen->vpos();
2014      UINT16 v = space.machine().primary_screen->vpos();
20102015
2011      if (v < snes_ppu.beam.last_visible_line)
2016      if (v < m_beam.last_visible_line)
20122017         offset = 0x010c;
20132018   }
20142019
20152020   if (!(snes_ram[OAMDATA]))
2016      m_snes_oam[offset] = (m_snes_oam[offset] & 0xff00) | (data << 0);
2021      m_oam_ram[offset] = (m_oam_ram[offset] & 0xff00) | (data << 0);
20172022   else
2018      m_snes_oam[offset] = (m_snes_oam[offset] & 0x00ff) | (data << 8);
2023      m_oam_ram[offset] = (m_oam_ram[offset] & 0x00ff) | (data << 8);
20192024}
20202025
20212026/*************************************************
r21558r21559
20392044 solution adopted by BSNES without enabling it.
20402045*************************************************/
20412046
2042READ8_MEMBER( snes_state::snes_cgram_read )
2047READ8_MEMBER( snes_ppu_class::snes_cgram_read )
20432048{
20442049   UINT8 res = 0;
20452050   offset &= 0x1ff;
20462051
20472052#if 0
2048   if (!snes_ppu.screen_disabled)
2053   if (!m_screen_disabled)
20492054   {
20502055      UINT16 v = space.machine().primary_screen->vpos();
20512056      UINT16 h = space.machine().primary_screen->hpos();
20522057
2053      if (v < snes_ppu.beam.last_visible_line && h >= 128 && h < 1096)
2058      if (v < m_beam.last_visible_line && h >= 128 && h < 1096)
20542059         offset = 0x1ff;
20552060   }
20562061#endif
20572062
2058   res = ((UINT8 *)m_snes_cgram)[offset];
2063   res = ((UINT8 *)m_cgram)[offset];
20592064
20602065   // CGRAM palette data format is 15-bits (0,bbbbb,ggggg,rrrrr).
20612066   // Highest bit is simply ignored.
r21558r21559
20652070   return res;
20662071}
20672072
2068WRITE8_MEMBER( snes_state::snes_cgram_write )
2073WRITE8_MEMBER( snes_ppu_class::snes_cgram_write )
20692074{
20702075   offset &= 0x1ff;
20712076
r21558r21559
20732078   // FIXME: this currently breaks some games (e.g. Tokimeki Memorial),
20742079   // even if it's expected to be more accurate than allowing for
20752080   // writes to the cgram address
2076   if (!snes_ppu.screen_disabled)
2081   if (!m_screen_disabled)
20772082   {
20782083      UINT16 v = space.machine().primary_screen->vpos();
20792084      UINT16 h = space.machine().primary_screen->hpos();
20802085
2081      if (v < snes_ppu.beam.last_visible_line && h >= 128 && h < 1096)
2086      if (v < m_beam.last_visible_line && h >= 128 && h < 1096)
20822087         offset = 0x1ff;
20832088   }
20842089#endif
r21558r21559
20882093   if (offset & 0x01)
20892094      data &= 0x7f;
20902095
2091   ((UINT8 *)m_snes_cgram)[offset] = data;
2096   ((UINT8 *)m_cgram)[offset] = data;
20922097}
20932098
2094READ8_HANDLER( snes_ppu_read )
2099UINT8 snes_ppu_class::snes_ppu_read(address_space &space, UINT32 offset, UINT8 *ram_ptr)
20952100{
20962101   snes_state *state = space.machine().driver_data<snes_state>();
20972102   UINT8 value;
r21558r21559
21162121      case WH2:
21172122      case WH3:
21182123      case WBGLOG:
2119         return snes_ppu.ppu1_open_bus;
2124         return m_ppu1_open_bus;
21202125
21212126      case MPYL:      /* Multiplication result (low) */
21222127         {
21232128            /* Perform 16bit * 8bit multiply */
2124            UINT32 c = (INT16)snes_ppu.mode7.matrix_a * (INT8)(snes_ppu.mode7.matrix_b >> 8);
2125            snes_ppu.ppu1_open_bus = c & 0xff;
2126            return snes_ppu.ppu1_open_bus;
2129            UINT32 c = (INT16)m_mode7.matrix_a * (INT8)(m_mode7.matrix_b >> 8);
2130            m_ppu1_open_bus = c & 0xff;
2131            return m_ppu1_open_bus;
21272132         }
21282133      case MPYM:      /* Multiplication result (mid) */
21292134         {
21302135            /* Perform 16bit * 8bit multiply */
2131            UINT32 c = (INT16)snes_ppu.mode7.matrix_a * (INT8)(snes_ppu.mode7.matrix_b >> 8);
2132            snes_ppu.ppu1_open_bus = (c >> 8) & 0xff;
2133            return snes_ppu.ppu1_open_bus;
2136            UINT32 c = (INT16)m_mode7.matrix_a * (INT8)(m_mode7.matrix_b >> 8);
2137            m_ppu1_open_bus = (c >> 8) & 0xff;
2138            return m_ppu1_open_bus;
21342139         }
21352140      case MPYH:      /* Multiplication result (high) */
21362141         {
21372142            /* Perform 16bit * 8bit multiply */
2138            UINT32 c = (INT16)snes_ppu.mode7.matrix_a * (INT8)(snes_ppu.mode7.matrix_b >> 8);
2139            snes_ppu.ppu1_open_bus = (c >> 16) & 0xff;
2140            return snes_ppu.ppu1_open_bus;
2143            UINT32 c = (INT16)m_mode7.matrix_a * (INT8)(m_mode7.matrix_b >> 8);
2144            m_ppu1_open_bus = (c >> 16) & 0xff;
2145            return m_ppu1_open_bus;
21412146         }
21422147      case SLHV:      /* Software latch for H/V counter */
2143         snes_latch_counters(space.machine());
2148         snes_latch_counters(space.machine(), ram_ptr);
21442149         return snes_open_bus_r(space, 0);       /* Return value is meaningless */
21452150      case ROAMDATA:  /* Read data from OAM (DR) */
2146         snes_ppu.ppu1_open_bus = state->snes_oam_read(space, snes_ppu.oam.address);
2147         snes_ram[OAMDATA] = (snes_ram[OAMDATA] + 1) % 2;
2148         if (!snes_ram[OAMDATA])
2151         m_ppu1_open_bus = snes_oam_read(space, m_oam.address);
2152         ram_ptr[OAMDATA] = (ram_ptr[OAMDATA] + 1) % 2;
2153         if (!ram_ptr[OAMDATA])
21492154         {
2150            snes_ppu.oam.address++;
2151            snes_ppu.oam.address &= 0x1ff;
2152            snes_ppu.oam.first_sprite = snes_ppu.oam.priority_rotation ? (snes_ppu.oam.address >> 1) & 127 : 0;
2155            m_oam.address++;
2156            m_oam.address &= 0x1ff;
2157            m_oam.first_sprite = m_oam.priority_rotation ? (m_oam.address >> 1) & 127 : 0;
21532158         }
2154         return snes_ppu.ppu1_open_bus;
2159         return m_ppu1_open_bus;
21552160      case RVMDATAL:  /* Read data from VRAM (low) */
21562161         {
21572162            UINT32 addr = snes_get_vram_address(space.machine());
2158            snes_ppu.ppu1_open_bus = state->m_vram_read_buffer & 0xff;
2163            m_ppu1_open_bus = state->m_vram_read_buffer & 0xff;
21592164
21602165            if (!state->m_vram_fgr_high)
21612166            {
2162               state->m_vram_read_buffer = state->snes_vram_read(space, addr);
2163               state->m_vram_read_buffer |= (state->snes_vram_read(space, addr + 1) << 8);
2167               state->m_vram_read_buffer = snes_vram_read(space, addr);
2168               state->m_vram_read_buffer |= (snes_vram_read(space, addr + 1) << 8);
21642169
21652170               state->m_vmadd = (state->m_vmadd + state->m_vram_fgr_increment) & 0xffff;
21662171            }
21672172
2168            return snes_ppu.ppu1_open_bus;
2173            return m_ppu1_open_bus;
21692174         }
21702175      case RVMDATAH:  /* Read data from VRAM (high) */
21712176         {
21722177            UINT32 addr = snes_get_vram_address(space.machine());
2173            snes_ppu.ppu1_open_bus = (state->m_vram_read_buffer >> 8) & 0xff;
2178            m_ppu1_open_bus = (state->m_vram_read_buffer >> 8) & 0xff;
21742179
21752180            if (state->m_vram_fgr_high)
21762181            {
2177               state->m_vram_read_buffer = state->snes_vram_read(space, addr);
2178               state->m_vram_read_buffer |= (state->snes_vram_read(space, addr + 1) << 8);
2182               state->m_vram_read_buffer = snes_vram_read(space, addr);
2183               state->m_vram_read_buffer |= (snes_vram_read(space, addr + 1) << 8);
21792184
21802185               state->m_vmadd = (state->m_vmadd + state->m_vram_fgr_increment) & 0xffff;
21812186            }
21822187
2183            return snes_ppu.ppu1_open_bus;
2188            return m_ppu1_open_bus;
21842189         }
21852190      case RCGDATA:   /* Read data from CGRAM */
21862191         if (!(state->m_cgram_address & 0x01))
2187            snes_ppu.ppu2_open_bus = state->snes_cgram_read(space, state->m_cgram_address);
2192            m_ppu2_open_bus = snes_cgram_read(space, state->m_cgram_address);
21882193         else
21892194         {
2190            snes_ppu.ppu2_open_bus &= 0x80;
2191            snes_ppu.ppu2_open_bus |= state->snes_cgram_read(space, state->m_cgram_address) & 0x7f;
2195            m_ppu2_open_bus &= 0x80;
2196            m_ppu2_open_bus |= snes_cgram_read(space, state->m_cgram_address) & 0x7f;
21922197         }
21932198
21942199         state->m_cgram_address = (state->m_cgram_address + 1) % (SNES_CGRAM_SIZE - 2);
2195         return snes_ppu.ppu2_open_bus;
2200         return m_ppu2_open_bus;
21962201      case OPHCT:     /* Horizontal counter data by ext/soft latch */
21972202         if (state->m_read_ophct)
21982203         {
2199            snes_ppu.ppu2_open_bus &= 0xfe;
2200            snes_ppu.ppu2_open_bus |= (snes_ppu.beam.latch_horz >> 8) & 0x01;
2204            m_ppu2_open_bus &= 0xfe;
2205            m_ppu2_open_bus |= (m_beam.latch_horz >> 8) & 0x01;
22012206         }
22022207         else
22032208         {
2204            snes_ppu.ppu2_open_bus = snes_ppu.beam.latch_horz & 0xff;
2209            m_ppu2_open_bus = m_beam.latch_horz & 0xff;
22052210         }
22062211         state->m_read_ophct ^= 1;
2207         return snes_ppu.ppu2_open_bus;
2212         return m_ppu2_open_bus;
22082213      case OPVCT:     /* Vertical counter data by ext/soft latch */
22092214         if (state->m_read_opvct)
22102215         {
2211            snes_ppu.ppu2_open_bus &= 0xfe;
2212            snes_ppu.ppu2_open_bus |= (snes_ppu.beam.latch_vert >> 8) & 0x01;
2216            m_ppu2_open_bus &= 0xfe;
2217            m_ppu2_open_bus |= (m_beam.latch_vert >> 8) & 0x01;
22132218         }
22142219         else
22152220         {
2216            snes_ppu.ppu2_open_bus = snes_ppu.beam.latch_vert & 0xff;
2221            m_ppu2_open_bus = m_beam.latch_vert & 0xff;
22172222         }
22182223         state->m_read_opvct ^= 1;
2219         return snes_ppu.ppu2_open_bus;
2224         return m_ppu2_open_bus;
22202225      case STAT77:    /* PPU status flag and version number */
2221         value = snes_ppu.stat77_flags & 0xc0; // 0x80 & 0x40 are Time Over / Range Over Sprite flags, set by the video code
2226         value = m_stat77_flags & 0xc0; // 0x80 & 0x40 are Time Over / Range Over Sprite flags, set by the video code
22222227         // 0x20 - Master/slave mode select. Little is known about this bit. We always seem to read back 0 here.
2223         value |= (snes_ppu.ppu1_open_bus & 0x10);
2224         value |= (snes_ppu.ppu1_version & 0x0f);
2225         snes_ppu.stat77_flags = value;  // not sure if this is needed...
2226         snes_ppu.ppu1_open_bus = value;
2227         return snes_ppu.ppu1_open_bus;
2228         value |= (m_ppu1_open_bus & 0x10);
2229         value |= (m_ppu1_version & 0x0f);
2230         m_stat77_flags = value;  // not sure if this is needed...
2231         m_ppu1_open_bus = value;
2232         return m_ppu1_open_bus;
22282233      case STAT78:    /* PPU status flag and version number */
22292234         state->m_read_ophct = 0;
22302235         state->m_read_opvct = 0;
2231         if(snes_ram[WRIO] & 0x80)
2232            snes_ram[STAT78] &= ~0x40; //clear ext latch if bit 7 of WRIO is set
2233         snes_ram[STAT78] = (snes_ram[STAT78] & ~0x2f) | (snes_ppu.ppu2_open_bus & 0x20) | (snes_ppu.ppu2_version & 0x0f);
2234         snes_ppu.ppu2_open_bus = snes_ram[STAT78];
2235         return snes_ppu.ppu2_open_bus;
2236         if(ram_ptr[WRIO] & 0x80)
2237            ram_ptr[STAT78] &= ~0x40; //clear ext latch if bit 7 of WRIO is set
2238         ram_ptr[STAT78] = (ram_ptr[STAT78] & ~0x2f) | (m_ppu2_open_bus & 0x20) | (m_ppu2_version & 0x0f);
2239         m_ppu2_open_bus = ram_ptr[STAT78];
2240         return m_ppu2_open_bus;
22362241   }
22372242
22382243   /* note: remaining registers (Namely TM in Super Kick Boxing) returns MDR open bus, not PPU Open Bus! */
r21558r21559
22402245}
22412246
22422247
2243WRITE8_HANDLER( snes_ppu_write )
2248void snes_ppu_class::snes_ppu_write(address_space &space, UINT32 offset, UINT8 data, UINT8 *ram_ptr)
22442249{
22452250   snes_state *state = space.machine().driver_data<snes_state>();
22462251
22472252   switch (offset)
22482253   {
22492254      case INIDISP:   /* Initial settings for screen */
2250         if ((snes_ppu.screen_disabled & 0x80) && (!(data & 0x80))) //a 1->0 force blank transition causes a reset OAM address
2255         if ((m_screen_disabled & 0x80) && (!(data & 0x80))) //a 1->0 force blank transition causes a reset OAM address
22512256         {
2252            space.write_byte(OAMADDL, snes_ppu.oam.saved_address_low);
2253            space.write_byte(OAMADDH, snes_ppu.oam.saved_address_high);
2254            snes_ppu.oam.first_sprite = snes_ppu.oam.priority_rotation ? (snes_ppu.oam.address >> 1) & 127 : 0;
2257            space.write_byte(OAMADDL, m_oam.saved_address_low);
2258            space.write_byte(OAMADDH, m_oam.saved_address_high);
2259            m_oam.first_sprite = m_oam.priority_rotation ? (m_oam.address >> 1) & 127 : 0;
22552260         }
2256         snes_ppu.screen_disabled = data & 0x80;
2257         snes_ppu.screen_brightness = (data & 0x0f) + 1;
2261         m_screen_disabled = data & 0x80;
2262         m_screen_brightness = (data & 0x0f) + 1;
22582263         break;
22592264      case OBSEL:     /* Object size and data area designation */
2260         snes_ppu.oam.next_charmap = (data & 0x03) << 1;
2261         snes_ppu.oam.next_name_select = (((data & 0x18) >> 3) * 0x1000) << 1;
2262         snes_ppu.oam.next_size = (data & 0xe0) >> 5;
2265         m_oam.next_charmap = (data & 0x03) << 1;
2266         m_oam.next_name_select = (((data & 0x18) >> 3) * 0x1000) << 1;
2267         m_oam.next_size = (data & 0xe0) >> 5;
22632268         break;
22642269      case OAMADDL:   /* Address for accessing OAM (low) */
2265         snes_ppu.oam.saved_address_low = data;
2266         snes_ppu.oam.address = (snes_ppu.oam.address & 0xff00) + data;
2267         snes_ppu.oam.first_sprite = snes_ppu.oam.priority_rotation ? (snes_ppu.oam.address >> 1) & 127 : 0;
2268         snes_ram[OAMDATA] = 0;
2270         m_oam.saved_address_low = data;
2271         m_oam.address = (m_oam.address & 0xff00) + data;
2272         m_oam.first_sprite = m_oam.priority_rotation ? (m_oam.address >> 1) & 127 : 0;
2273         ram_ptr[OAMDATA] = 0;
22692274         break;
22702275      case OAMADDH:   /* Address for accessing OAM (high) */
2271         snes_ppu.oam.saved_address_high = data;
2272         snes_ppu.oam.address = (snes_ppu.oam.address & 0x00ff) | ((data & 0x01) << 8);
2273         snes_ppu.oam.priority_rotation = BIT(data, 7);
2274         snes_ppu.oam.first_sprite = snes_ppu.oam.priority_rotation ? (snes_ppu.oam.address >> 1) & 127 : 0;
2275         snes_ram[OAMDATA] = 0;
2276         m_oam.saved_address_high = data;
2277         m_oam.address = (m_oam.address & 0x00ff) | ((data & 0x01) << 8);
2278         m_oam.priority_rotation = BIT(data, 7);
2279         m_oam.first_sprite = m_oam.priority_rotation ? (m_oam.address >> 1) & 127 : 0;
2280         ram_ptr[OAMDATA] = 0;
22762281         break;
22772282      case OAMDATA:   /* Data for OAM write (DW) */
2278         if (snes_ppu.oam.address >= 0x100)
2279            state->snes_oam_write(space, snes_ppu.oam.address, data);
2283         if (m_oam.address >= 0x100)
2284            snes_oam_write(space, m_oam.address, data);
22802285         else
22812286         {
2282            if (!snes_ram[OAMDATA])
2283               snes_ppu.oam.write_latch = data;
2287            if (!ram_ptr[OAMDATA])
2288               m_oam.write_latch = data;
22842289            else
22852290            {
22862291               // in this case, we not only write data to the upper byte of the word,
2287               // but also snes_ppu.oam.write_latch to the lower byte (recall that
2288               // snes_ram[OAMDATA] is used to select high/low byte)
2289               state->snes_oam_write(space, snes_ppu.oam.address, data);
2290               snes_ram[OAMDATA] = 0;
2291               state->snes_oam_write(space, snes_ppu.oam.address, snes_ppu.oam.write_latch);
2292               snes_ram[OAMDATA] = 1;
2292               // but also m_oam.write_latch to the lower byte (recall that
2293               // ram_ptr[OAMDATA] is used to select high/low byte)
2294               snes_oam_write(space, m_oam.address, data);
2295               ram_ptr[OAMDATA] = 0;
2296               snes_oam_write(space, m_oam.address, m_oam.write_latch);
2297               ram_ptr[OAMDATA] = 1;
22932298            }
22942299         }
2295         snes_ram[OAMDATA] = (snes_ram[OAMDATA] + 1) % 2;
2296         if (!snes_ram[OAMDATA])
2300         ram_ptr[OAMDATA] = (ram_ptr[OAMDATA] + 1) % 2;
2301         if (!ram_ptr[OAMDATA])
22972302         {
2298            snes_ppu.oam.address++;
2299            snes_ppu.oam.address &= 0x1ff;
2300            snes_ppu.oam.first_sprite = snes_ppu.oam.priority_rotation ? (snes_ppu.oam.address >> 1) & 127 : 0;
2303            m_oam.address++;
2304            m_oam.address &= 0x1ff;
2305            m_oam.first_sprite = m_oam.priority_rotation ? (m_oam.address >> 1) & 127 : 0;
23012306         }
23022307         return;
23032308      case BGMODE:    /* BG mode and character size settings */
2304         snes_ppu.mode = data & 0x07;
2305         snes_dynamic_res_change(space.machine());
2306         snes_ppu.bg3_priority_bit = BIT(data, 3);
2307         snes_ppu.layer[SNES_BG1].tile_size = BIT(data, 4);
2308         snes_ppu.layer[SNES_BG2].tile_size = BIT(data, 5);
2309         snes_ppu.layer[SNES_BG3].tile_size = BIT(data, 6);
2310         snes_ppu.layer[SNES_BG4].tile_size = BIT(data, 7);
2311         snes_ppu.update_offsets = 1;
2309         m_mode = data & 0x07;
2310         snes_dynamic_res_change(space.machine(), ram_ptr);
2311         m_bg3_priority_bit = BIT(data, 3);
2312         m_layer[SNES_BG1].tile_size = BIT(data, 4);
2313         m_layer[SNES_BG2].tile_size = BIT(data, 5);
2314         m_layer[SNES_BG3].tile_size = BIT(data, 6);
2315         m_layer[SNES_BG4].tile_size = BIT(data, 7);
2316         m_update_offsets = 1;
23122317         break;
23132318      case MOSAIC:    /* Size and screen designation for mosaic */
2314         snes_ppu.mosaic_size = (data & 0xf0) >> 4;
2315         snes_ppu.layer[SNES_BG1].mosaic_enabled = BIT(data, 0);
2316         snes_ppu.layer[SNES_BG2].mosaic_enabled = BIT(data, 1);
2317         snes_ppu.layer[SNES_BG3].mosaic_enabled = BIT(data, 2);
2318         snes_ppu.layer[SNES_BG4].mosaic_enabled = BIT(data, 3);
2319         m_mosaic_size = (data & 0xf0) >> 4;
2320         m_layer[SNES_BG1].mosaic_enabled = BIT(data, 0);
2321         m_layer[SNES_BG2].mosaic_enabled = BIT(data, 1);
2322         m_layer[SNES_BG3].mosaic_enabled = BIT(data, 2);
2323         m_layer[SNES_BG4].mosaic_enabled = BIT(data, 3);
23192324         break;
23202325      case BG1SC:     /* Address for storing SC data BG1 SC size designation */
23212326      case BG2SC:     /* Address for storing SC data BG2 SC size designation  */
23222327      case BG3SC:     /* Address for storing SC data BG3 SC size designation  */
23232328      case BG4SC:     /* Address for storing SC data BG4 SC size designation  */
2324         snes_ppu.layer[offset - BG1SC].tilemap = data & 0xfc;
2325         snes_ppu.layer[offset - BG1SC].tilemap_size = data & 0x3;
2329         m_layer[offset - BG1SC].tilemap = data & 0xfc;
2330         m_layer[offset - BG1SC].tilemap_size = data & 0x3;
23262331         break;
23272332      case BG12NBA:   /* Address for BG 1 and 2 character data */
2328         snes_ppu.layer[SNES_BG1].charmap = (data & 0x0f);
2329         snes_ppu.layer[SNES_BG2].charmap = (data & 0xf0) >> 4;
2333         m_layer[SNES_BG1].charmap = (data & 0x0f);
2334         m_layer[SNES_BG2].charmap = (data & 0xf0) >> 4;
23302335         break;
23312336      case BG34NBA:   /* Address for BG 3 and 4 character data */
2332         snes_ppu.layer[SNES_BG3].charmap = (data & 0x0f);
2333         snes_ppu.layer[SNES_BG4].charmap = (data & 0xf0) >> 4;
2337         m_layer[SNES_BG3].charmap = (data & 0x0f);
2338         m_layer[SNES_BG4].charmap = (data & 0xf0) >> 4;
23342339         break;
23352340
23362341      // Anomie says "H Current = (Byte<<8) | (Prev&~7) | ((Current>>8)&7); V Current = (Current<<8) | Prev;" and Prev is shared by all scrolls but in Mode 7!
23372342      case BG1HOFS:   /* BG1 - horizontal scroll (DW) */
23382343         /* In Mode 0->6 we use ppu_last_scroll as Prev */
2339         snes_ppu.layer[SNES_BG1].hoffs = (data << 8) | (snes_ppu.ppu_last_scroll & ~7) | ((snes_ppu.layer[SNES_BG1].hoffs >> 8) & 7);
2340         snes_ppu.ppu_last_scroll = data;
2344         m_layer[SNES_BG1].hoffs = (data << 8) | (m_ppu_last_scroll & ~7) | ((m_layer[SNES_BG1].hoffs >> 8) & 7);
2345         m_ppu_last_scroll = data;
23412346         /* In Mode 7 we use mode7_last_scroll as Prev */
2342         snes_ppu.mode7.hor_offset = (data << 8) | (snes_ppu.mode7_last_scroll & ~7) | ((snes_ppu.mode7.hor_offset >> 8) & 7);
2343         snes_ppu.mode7_last_scroll = data;
2344         snes_ppu.update_offsets = 1;
2347         m_mode7.hor_offset = (data << 8) | (m_mode7_last_scroll & ~7) | ((m_mode7.hor_offset >> 8) & 7);
2348         m_mode7_last_scroll = data;
2349         m_update_offsets = 1;
23452350         return;
23462351      case BG1VOFS:   /* BG1 - vertical scroll (DW) */
23472352         /* In Mode 0->6 we use ppu_last_scroll as Prev */
2348         snes_ppu.layer[SNES_BG1].voffs = (data << 8) | snes_ppu.ppu_last_scroll;
2349         snes_ppu.ppu_last_scroll = data;
2353         m_layer[SNES_BG1].voffs = (data << 8) | m_ppu_last_scroll;
2354         m_ppu_last_scroll = data;
23502355         /* In Mode 7 we use mode7_last_scroll as Prev */
2351         snes_ppu.mode7.ver_offset = (data << 8) | snes_ppu.mode7_last_scroll;
2352         snes_ppu.mode7_last_scroll = data;
2353         snes_ppu.update_offsets = 1;
2356         m_mode7.ver_offset = (data << 8) | m_mode7_last_scroll;
2357         m_mode7_last_scroll = data;
2358         m_update_offsets = 1;
23542359         return;
23552360      case BG2HOFS:   /* BG2 - horizontal scroll (DW) */
2356         snes_ppu.layer[SNES_BG2].hoffs = (data << 8) | (snes_ppu.ppu_last_scroll & ~7) | ((snes_ppu.layer[SNES_BG2].hoffs >> 8) & 7);
2357         snes_ppu.ppu_last_scroll = data;
2358         snes_ppu.update_offsets = 1;
2361         m_layer[SNES_BG2].hoffs = (data << 8) | (m_ppu_last_scroll & ~7) | ((m_layer[SNES_BG2].hoffs >> 8) & 7);
2362         m_ppu_last_scroll = data;
2363         m_update_offsets = 1;
23592364         return;
23602365      case BG2VOFS:   /* BG2 - vertical scroll (DW) */
2361         snes_ppu.layer[SNES_BG2].voffs = (data << 8) | (snes_ppu.ppu_last_scroll);
2362         snes_ppu.ppu_last_scroll = data;
2363         snes_ppu.update_offsets = 1;
2366         m_layer[SNES_BG2].voffs = (data << 8) | (m_ppu_last_scroll);
2367         m_ppu_last_scroll = data;
2368         m_update_offsets = 1;
23642369         return;
23652370      case BG3HOFS:   /* BG3 - horizontal scroll (DW) */
2366         snes_ppu.layer[SNES_BG3].hoffs = (data << 8) | (snes_ppu.ppu_last_scroll & ~7) | ((snes_ppu.layer[SNES_BG3].hoffs >> 8) & 7);
2367         snes_ppu.ppu_last_scroll = data;
2368         snes_ppu.update_offsets = 1;
2371         m_layer[SNES_BG3].hoffs = (data << 8) | (m_ppu_last_scroll & ~7) | ((m_layer[SNES_BG3].hoffs >> 8) & 7);
2372         m_ppu_last_scroll = data;
2373         m_update_offsets = 1;
23692374         return;
23702375      case BG3VOFS:   /* BG3 - vertical scroll (DW) */
2371         snes_ppu.layer[SNES_BG3].voffs = (data << 8) | (snes_ppu.ppu_last_scroll);
2372         snes_ppu.ppu_last_scroll = data;
2373         snes_ppu.update_offsets = 1;
2376         m_layer[SNES_BG3].voffs = (data << 8) | (m_ppu_last_scroll);
2377         m_ppu_last_scroll = data;
2378         m_update_offsets = 1;
23742379         return;
23752380      case BG4HOFS:   /* BG4 - horizontal scroll (DW) */
2376         snes_ppu.layer[SNES_BG4].hoffs = (data << 8) | (snes_ppu.ppu_last_scroll & ~7) | ((snes_ppu.layer[SNES_BG4].hoffs >> 8) & 7);
2377         snes_ppu.ppu_last_scroll = data;
2378         snes_ppu.update_offsets = 1;
2381         m_layer[SNES_BG4].hoffs = (data << 8) | (m_ppu_last_scroll & ~7) | ((m_layer[SNES_BG4].hoffs >> 8) & 7);
2382         m_ppu_last_scroll = data;
2383         m_update_offsets = 1;
23792384         return;
23802385      case BG4VOFS:   /* BG4 - vertical scroll (DW) */
2381         snes_ppu.layer[SNES_BG4].voffs = (data << 8) | (snes_ppu.ppu_last_scroll);
2382         snes_ppu.ppu_last_scroll = data;
2383         snes_ppu.update_offsets = 1;
2386         m_layer[SNES_BG4].voffs = (data << 8) | (m_ppu_last_scroll);
2387         m_ppu_last_scroll = data;
2388         m_update_offsets = 1;
23842389         return;
23852390      case VMAIN:     /* VRAM address increment value designation */
23862391         state->m_vram_fgr_high = (data & 0x80);
r21558r21559
24052410            UINT32 addr;
24062411            state->m_vmadd = (state->m_vmadd & 0xff00) | (data << 0);
24072412            addr = snes_get_vram_address(space.machine());
2408            state->m_vram_read_buffer = state->snes_vram_read(space, addr);
2409            state->m_vram_read_buffer |= (state->snes_vram_read(space, addr + 1) << 8);
2413            state->m_vram_read_buffer = snes_vram_read(space, addr);
2414            state->m_vram_read_buffer |= (snes_vram_read(space, addr + 1) << 8);
24102415         }
24112416         break;
24122417      case VMADDH:    /* Address for VRAM read/write (high) */
r21558r21559
24142419            UINT32 addr;
24152420            state->m_vmadd = (state->m_vmadd & 0x00ff) | (data << 8);
24162421            addr = snes_get_vram_address(space.machine());
2417            state->m_vram_read_buffer = state->snes_vram_read(space, addr);
2418            state->m_vram_read_buffer |= (state->snes_vram_read(space, addr + 1) << 8);
2422            state->m_vram_read_buffer = snes_vram_read(space, addr);
2423            state->m_vram_read_buffer |= (snes_vram_read(space, addr + 1) << 8);
24192424         }
24202425         break;
24212426      case VMDATAL:   /* 2118: Data for VRAM write (low) */
24222427         {
24232428            UINT32 addr = snes_get_vram_address(space.machine());
2424            state->snes_vram_write(space, addr, data);
2429            snes_vram_write(space, addr, data);
24252430
24262431            if (!state->m_vram_fgr_high)
24272432               state->m_vmadd = (state->m_vmadd + state->m_vram_fgr_increment) & 0xffff;
r21558r21559
24302435      case VMDATAH:   /* 2119: Data for VRAM write (high) */
24312436         {
24322437            UINT32 addr = snes_get_vram_address(space.machine());
2433            state->snes_vram_write(space, addr + 1, data);
2438            snes_vram_write(space, addr + 1, data);
24342439
24352440            if (state->m_vram_fgr_high)
24362441               state->m_vmadd = (state->m_vmadd + state->m_vram_fgr_increment) & 0xffff;
24372442         }
24382443         return;
24392444      case M7SEL:     /* Mode 7 initial settings */
2440         snes_ppu.mode7.repeat = (data >> 6) & 3;
2441         snes_ppu.mode7.vflip  = BIT(data, 1);
2442         snes_ppu.mode7.hflip  = BIT(data, 0);
2445         m_mode7.repeat = (data >> 6) & 3;
2446         m_mode7.vflip  = BIT(data, 1);
2447         m_mode7.hflip  = BIT(data, 0);
24432448         break;
24442449      /* As per Anomie's doc: Reg = (Current<<8) | Prev; and there is only one Prev, shared by these matrix regs and Mode 7 scroll regs */
24452450      case M7A:       /* Mode 7 COS angle/x expansion (DW) */
2446         snes_ppu.mode7.matrix_a = snes_ppu.mode7_last_scroll + (data << 8);
2447         snes_ppu.mode7_last_scroll = data;
2451         m_mode7.matrix_a = m_mode7_last_scroll + (data << 8);
2452         m_mode7_last_scroll = data;
24482453         break;
24492454      case M7B:       /* Mode 7 SIN angle/ x expansion (DW) */
2450         snes_ppu.mode7.matrix_b = snes_ppu.mode7_last_scroll + (data << 8);
2451         snes_ppu.mode7_last_scroll = data;
2455         m_mode7.matrix_b = m_mode7_last_scroll + (data << 8);
2456         m_mode7_last_scroll = data;
24522457         break;
24532458      case M7C:       /* Mode 7 SIN angle/y expansion (DW) */
2454         snes_ppu.mode7.matrix_c = snes_ppu.mode7_last_scroll + (data << 8);
2455         snes_ppu.mode7_last_scroll = data;
2459         m_mode7.matrix_c = m_mode7_last_scroll + (data << 8);
2460         m_mode7_last_scroll = data;
24562461         break;
24572462      case M7D:       /* Mode 7 COS angle/y expansion (DW) */
2458         snes_ppu.mode7.matrix_d = snes_ppu.mode7_last_scroll + (data << 8);
2459         snes_ppu.mode7_last_scroll = data;
2463         m_mode7.matrix_d = m_mode7_last_scroll + (data << 8);
2464         m_mode7_last_scroll = data;
24602465         break;
24612466      case M7X:       /* Mode 7 x center position (DW) */
2462         snes_ppu.mode7.origin_x = snes_ppu.mode7_last_scroll + (data << 8);
2463         snes_ppu.mode7_last_scroll = data;
2467         m_mode7.origin_x = m_mode7_last_scroll + (data << 8);
2468         m_mode7_last_scroll = data;
24642469         break;
24652470      case M7Y:       /* Mode 7 y center position (DW) */
2466         snes_ppu.mode7.origin_y = snes_ppu.mode7_last_scroll + (data << 8);
2467         snes_ppu.mode7_last_scroll = data;
2471         m_mode7.origin_y = m_mode7_last_scroll + (data << 8);
2472         m_mode7_last_scroll = data;
24682473         break;
24692474      case CGADD:     /* Initial address for colour RAM writing */
24702475         /* CGRAM is 16-bit, but when reading/writing we treat it as 8-bit, so we need to double the address */
24712476         state->m_cgram_address = data << 1;
24722477         break;
24732478      case CGDATA:    /* Data for colour RAM */
2474         state->snes_cgram_write(space, state->m_cgram_address, data);
2479         snes_cgram_write(space, state->m_cgram_address, data);
24752480         state->m_cgram_address = (state->m_cgram_address + 1) % (SNES_CGRAM_SIZE - 2);
24762481         break;
24772482      case W12SEL:    /* Window mask settings for BG1-2 */
2478         if (data != snes_ram[offset])
2483         if (data != ram_ptr[offset])
24792484         {
2480            snes_ppu.layer[SNES_BG1].window1_invert  = BIT(data, 0);
2481            snes_ppu.layer[SNES_BG1].window1_enabled = BIT(data, 1);
2482            snes_ppu.layer[SNES_BG1].window2_invert  = BIT(data, 2);
2483            snes_ppu.layer[SNES_BG1].window2_enabled = BIT(data, 3);
2484            snes_ppu.layer[SNES_BG2].window1_invert  = BIT(data, 4);
2485            snes_ppu.layer[SNES_BG2].window1_enabled = BIT(data, 5);
2486            snes_ppu.layer[SNES_BG2].window2_invert  = BIT(data, 6);
2487            snes_ppu.layer[SNES_BG2].window2_enabled = BIT(data, 7);
2488            snes_ppu.update_windows = 1;
2485            m_layer[SNES_BG1].window1_invert  = BIT(data, 0);
2486            m_layer[SNES_BG1].window1_enabled = BIT(data, 1);
2487            m_layer[SNES_BG1].window2_invert  = BIT(data, 2);
2488            m_layer[SNES_BG1].window2_enabled = BIT(data, 3);
2489            m_layer[SNES_BG2].window1_invert  = BIT(data, 4);
2490            m_layer[SNES_BG2].window1_enabled = BIT(data, 5);
2491            m_layer[SNES_BG2].window2_invert  = BIT(data, 6);
2492            m_layer[SNES_BG2].window2_enabled = BIT(data, 7);
2493            m_update_windows = 1;
24892494         }
24902495         break;
24912496      case W34SEL:    /* Window mask settings for BG3-4 */
2492         if (data != snes_ram[offset])
2497         if (data != ram_ptr[offset])
24932498         {
2494            snes_ppu.layer[SNES_BG3].window1_invert  = BIT(data, 0);
2495            snes_ppu.layer[SNES_BG3].window1_enabled = BIT(data, 1);
2496            snes_ppu.layer[SNES_BG3].window2_invert  = BIT(data, 2);
2497            snes_ppu.layer[SNES_BG3].window2_enabled = BIT(data, 3);
2498            snes_ppu.layer[SNES_BG4].window1_invert  = BIT(data, 4);
2499            snes_ppu.layer[SNES_BG4].window1_enabled = BIT(data, 5);
2500            snes_ppu.layer[SNES_BG4].window2_invert  = BIT(data, 6);
2501            snes_ppu.layer[SNES_BG4].window2_enabled = BIT(data, 7);
2502            snes_ppu.update_windows = 1;
2499            m_layer[SNES_BG3].window1_invert  = BIT(data, 0);
2500            m_layer[SNES_BG3].window1_enabled = BIT(data, 1);
2501            m_layer[SNES_BG3].window2_invert  = BIT(data, 2);
2502            m_layer[SNES_BG3].window2_enabled = BIT(data, 3);
2503            m_layer[SNES_BG4].window1_invert  = BIT(data, 4);
2504            m_layer[SNES_BG4].window1_enabled = BIT(data, 5);
2505            m_layer[SNES_BG4].window2_invert  = BIT(data, 6);
2506            m_layer[SNES_BG4].window2_enabled = BIT(data, 7);
2507            m_update_windows = 1;
25032508         }
25042509         break;
25052510      case WOBJSEL:   /* Window mask settings for objects */
2506         if (data != snes_ram[offset])
2511         if (data != ram_ptr[offset])
25072512         {
2508            snes_ppu.layer[SNES_OAM].window1_invert  = BIT(data, 0);
2509            snes_ppu.layer[SNES_OAM].window1_enabled = BIT(data, 1);
2510            snes_ppu.layer[SNES_OAM].window2_invert  = BIT(data, 2);
2511            snes_ppu.layer[SNES_OAM].window2_enabled = BIT(data, 3);
2512            snes_ppu.layer[SNES_COLOR].window1_invert  = BIT(data, 4);
2513            snes_ppu.layer[SNES_COLOR].window1_enabled = BIT(data, 5);
2514            snes_ppu.layer[SNES_COLOR].window2_invert  = BIT(data, 6);
2515            snes_ppu.layer[SNES_COLOR].window2_enabled = BIT(data, 7);
2516            snes_ppu.update_windows = 1;
2513            m_layer[SNES_OAM].window1_invert  = BIT(data, 0);
2514            m_layer[SNES_OAM].window1_enabled = BIT(data, 1);
2515            m_layer[SNES_OAM].window2_invert  = BIT(data, 2);
2516            m_layer[SNES_OAM].window2_enabled = BIT(data, 3);
2517            m_layer[SNES_COLOR].window1_invert  = BIT(data, 4);
2518            m_layer[SNES_COLOR].window1_enabled = BIT(data, 5);
2519            m_layer[SNES_COLOR].window2_invert  = BIT(data, 6);
2520            m_layer[SNES_COLOR].window2_enabled = BIT(data, 7);
2521            m_update_windows = 1;
25172522         }
25182523         break;
25192524      case WH0:       /* Window 1 left position */
2520         if (data != snes_ram[offset])
2525         if (data != ram_ptr[offset])
25212526         {
2522            snes_ppu.window1_left = data;
2523            snes_ppu.update_windows = 1;
2527            m_window1_left = data;
2528            m_update_windows = 1;
25242529         }
25252530         break;
25262531      case WH1:       /* Window 1 right position */
2527         if (data != snes_ram[offset])
2532         if (data != ram_ptr[offset])
25282533         {
2529            snes_ppu.window1_right = data;
2530            snes_ppu.update_windows = 1;
2534            m_window1_right = data;
2535            m_update_windows = 1;
25312536         }
25322537         break;
25332538      case WH2:       /* Window 2 left position */
2534         if (data != snes_ram[offset])
2539         if (data != ram_ptr[offset])
25352540         {
2536            snes_ppu.window2_left = data;
2537            snes_ppu.update_windows = 1;
2541            m_window2_left = data;
2542            m_update_windows = 1;
25382543         }
25392544         break;
25402545      case WH3:       /* Window 2 right position */
2541         if (data != snes_ram[offset])
2546         if (data != ram_ptr[offset])
25422547         {
2543            snes_ppu.window2_right = data;
2544            snes_ppu.update_windows = 1;
2548            m_window2_right = data;
2549            m_update_windows = 1;
25452550         }
25462551         break;
25472552      case WBGLOG:    /* Window mask logic for BG's */
2548         if (data != snes_ram[offset])
2553         if (data != ram_ptr[offset])
25492554         {
2550            snes_ppu.layer[SNES_BG1].wlog_mask = data & 0x03;
2551            snes_ppu.layer[SNES_BG2].wlog_mask = (data & 0x0c) >> 2;
2552            snes_ppu.layer[SNES_BG3].wlog_mask = (data & 0x30) >> 4;
2553            snes_ppu.layer[SNES_BG4].wlog_mask = (data & 0xc0) >> 6;
2554            snes_ppu.update_windows = 1;
2555            m_layer[SNES_BG1].wlog_mask = data & 0x03;
2556            m_layer[SNES_BG2].wlog_mask = (data & 0x0c) >> 2;
2557            m_layer[SNES_BG3].wlog_mask = (data & 0x30) >> 4;
2558            m_layer[SNES_BG4].wlog_mask = (data & 0xc0) >> 6;
2559            m_update_windows = 1;
25552560         }
25562561         break;
25572562      case WOBJLOG:   /* Window mask logic for objects */
2558         if (data != snes_ram[offset])
2563         if (data != ram_ptr[offset])
25592564         {
2560            snes_ppu.layer[SNES_OAM].wlog_mask = data & 0x03;
2561            snes_ppu.layer[SNES_COLOR].wlog_mask = (data & 0x0c) >> 2;
2562            snes_ppu.update_windows = 1;
2565            m_layer[SNES_OAM].wlog_mask = data & 0x03;
2566            m_layer[SNES_COLOR].wlog_mask = (data & 0x0c) >> 2;
2567            m_update_windows = 1;
25632568         }
25642569         break;
25652570      case TM:        /* Main screen designation */
2566         snes_ppu.layer[SNES_BG1].main_bg_enabled = BIT(data, 0);
2567         snes_ppu.layer[SNES_BG2].main_bg_enabled = BIT(data, 1);
2568         snes_ppu.layer[SNES_BG3].main_bg_enabled = BIT(data, 2);
2569         snes_ppu.layer[SNES_BG4].main_bg_enabled = BIT(data, 3);
2570         snes_ppu.layer[SNES_OAM].main_bg_enabled = BIT(data, 4);
2571         m_layer[SNES_BG1].main_bg_enabled = BIT(data, 0);
2572         m_layer[SNES_BG2].main_bg_enabled = BIT(data, 1);
2573         m_layer[SNES_BG3].main_bg_enabled = BIT(data, 2);
2574         m_layer[SNES_BG4].main_bg_enabled = BIT(data, 3);
2575         m_layer[SNES_OAM].main_bg_enabled = BIT(data, 4);
25712576         break;
25722577      case TS:        /* Subscreen designation */
2573         snes_ppu.layer[SNES_BG1].sub_bg_enabled = BIT(data, 0);
2574         snes_ppu.layer[SNES_BG2].sub_bg_enabled = BIT(data, 1);
2575         snes_ppu.layer[SNES_BG3].sub_bg_enabled = BIT(data, 2);
2576         snes_ppu.layer[SNES_BG4].sub_bg_enabled = BIT(data, 3);
2577         snes_ppu.layer[SNES_OAM].sub_bg_enabled = BIT(data, 4);
2578         m_layer[SNES_BG1].sub_bg_enabled = BIT(data, 0);
2579         m_layer[SNES_BG2].sub_bg_enabled = BIT(data, 1);
2580         m_layer[SNES_BG3].sub_bg_enabled = BIT(data, 2);
2581         m_layer[SNES_BG4].sub_bg_enabled = BIT(data, 3);
2582         m_layer[SNES_OAM].sub_bg_enabled = BIT(data, 4);
25782583         break;
25792584      case TMW:       /* Window mask for main screen designation */
2580         snes_ppu.layer[SNES_BG1].main_window_enabled = BIT(data, 0);
2581         snes_ppu.layer[SNES_BG2].main_window_enabled = BIT(data, 1);
2582         snes_ppu.layer[SNES_BG3].main_window_enabled = BIT(data, 2);
2583         snes_ppu.layer[SNES_BG4].main_window_enabled = BIT(data, 3);
2584         snes_ppu.layer[SNES_OAM].main_window_enabled = BIT(data, 4);
2585         m_layer[SNES_BG1].main_window_enabled = BIT(data, 0);
2586         m_layer[SNES_BG2].main_window_enabled = BIT(data, 1);
2587         m_layer[SNES_BG3].main_window_enabled = BIT(data, 2);
2588         m_layer[SNES_BG4].main_window_enabled = BIT(data, 3);
2589         m_layer[SNES_OAM].main_window_enabled = BIT(data, 4);
25852590         break;
25862591      case TSW:       /* Window mask for subscreen designation */
2587         snes_ppu.layer[SNES_BG1].sub_window_enabled = BIT(data, 0);
2588         snes_ppu.layer[SNES_BG2].sub_window_enabled = BIT(data, 1);
2589         snes_ppu.layer[SNES_BG3].sub_window_enabled = BIT(data, 2);
2590         snes_ppu.layer[SNES_BG4].sub_window_enabled = BIT(data, 3);
2591         snes_ppu.layer[SNES_OAM].sub_window_enabled = BIT(data, 4);
2592         m_layer[SNES_BG1].sub_window_enabled = BIT(data, 0);
2593         m_layer[SNES_BG2].sub_window_enabled = BIT(data, 1);
2594         m_layer[SNES_BG3].sub_window_enabled = BIT(data, 2);
2595         m_layer[SNES_BG4].sub_window_enabled = BIT(data, 3);
2596         m_layer[SNES_OAM].sub_window_enabled = BIT(data, 4);
25922597         break;
25932598      case CGWSEL:    /* Initial settings for Fixed colour addition or screen addition */
2594         snes_ppu.clip_to_black = (data >> 6) & 0x03;
2595         snes_ppu.prevent_color_math = (data >> 4) & 0x03;
2596         snes_ppu.sub_add_mode = BIT(data, 1);
2597         snes_ppu.direct_color = BIT(data, 0);
2599         m_clip_to_black = (data >> 6) & 0x03;
2600         m_prevent_color_math = (data >> 4) & 0x03;
2601         m_sub_add_mode = BIT(data, 1);
2602         m_direct_color = BIT(data, 0);
25982603#ifdef SNES_DBG_REG_W
2599         if ((data & 0x2) != (snes_ram[CGWSEL] & 0x2))
2600            mame_printf_debug( "Add/Sub Layer: %s\n", ((data & 0x2) >> 1) ? "Subscreen" : "Fixed colour" );
2604         if ((data & 0x2) != (ram_ptr[CGWSEL] & 0x2))
2605            mame_printf_debug("Add/Sub Layer: %s\n", ((data & 0x2) >> 1) ? "Subscreen" : "Fixed colour");
26012606#endif
26022607         break;
26032608      case CGADSUB:   /* Addition/Subtraction designation for each screen */
2604         snes_ppu.color_modes = data & 0xc0;
2605         snes_ppu.layer[SNES_BG1].color_math = BIT(data, 0);
2606         snes_ppu.layer[SNES_BG2].color_math = BIT(data, 1);
2607         snes_ppu.layer[SNES_BG3].color_math = BIT(data, 2);
2608         snes_ppu.layer[SNES_BG4].color_math = BIT(data, 3);
2609         snes_ppu.layer[SNES_OAM].color_math = BIT(data, 4);
2610         snes_ppu.layer[SNES_COLOR].color_math = BIT(data, 5);
2609         m_color_modes = data & 0xc0;
2610         m_layer[SNES_BG1].color_math = BIT(data, 0);
2611         m_layer[SNES_BG2].color_math = BIT(data, 1);
2612         m_layer[SNES_BG3].color_math = BIT(data, 2);
2613         m_layer[SNES_BG4].color_math = BIT(data, 3);
2614         m_layer[SNES_OAM].color_math = BIT(data, 4);
2615         m_layer[SNES_COLOR].color_math = BIT(data, 5);
26112616         break;
26122617      case COLDATA:   /* Fixed colour data for fixed colour addition/subtraction */
26132618         {
r21558r21559
26152620            UINT8 r, g, b;
26162621
26172622            /* Get existing value. */
2618            r = state->m_snes_cgram[FIXED_COLOUR] & 0x1f;
2619            g = (state->m_snes_cgram[FIXED_COLOUR] & 0x3e0) >> 5;
2620            b = (state->m_snes_cgram[FIXED_COLOUR] & 0x7c00) >> 10;
2623            r = m_cgram[FIXED_COLOUR] & 0x1f;
2624            g = (m_cgram[FIXED_COLOUR] & 0x3e0) >> 5;
2625            b = (m_cgram[FIXED_COLOUR] & 0x7c00) >> 10;
26212626            /* Set new value */
26222627            if (data & 0x20)
26232628               r = data & 0x1f;
r21558r21559
26252630               g = data & 0x1f;
26262631            if (data & 0x80)
26272632               b = data & 0x1f;
2628            state->m_snes_cgram[FIXED_COLOUR] = (r | (g << 5) | (b << 10));
2633            m_cgram[FIXED_COLOUR] = (r | (g << 5) | (b << 10));
26292634         } break;
26302635      case SETINI:    /* Screen mode/video select */
2631         snes_ppu.interlace = (data & 0x01) ? 2 : 1;
2632         snes_ppu.obj_interlace = (data & 0x02) ? 2 : 1;
2633         snes_ppu.beam.last_visible_line = (data & 0x04) ? 240 : 225;
2634         snes_ppu.pseudo_hires = BIT(data, 3);
2635         snes_ppu.mode7.extbg = BIT(data, 6);
2636         snes_dynamic_res_change(space.machine());
2636         m_interlace = (data & 0x01) ? 2 : 1;
2637         m_obj_interlace = (data & 0x02) ? 2 : 1;
2638         m_beam.last_visible_line = (data & 0x04) ? 240 : 225;
2639         m_pseudo_hires = BIT(data, 3);
2640         m_mode7.extbg = BIT(data, 6);
2641         snes_dynamic_res_change(space.machine(), ram_ptr);
26372642#ifdef SNES_DBG_REG_W
2638         if ((data & 0x8) != (snes_ram[SETINI] & 0x8))
2639            mame_printf_debug( "Pseudo 512 mode: %s\n", (data & 0x8) ? "on" : "off" );
2643         if ((data & 0x8) != (ram_ptr[SETINI] & 0x8))
2644            mame_printf_debug("Pseudo 512 mode: %s\n", (data & 0x8) ? "on" : "off");
26402645#endif
26412646         break;
26422647      }
26432648
2644   snes_ram[offset] = data;
2649   ram_ptr[offset] = data;
26452650}
26462651
26472652/***** Debug Functions *****/
r21558r21559
26602665      popmessage MSG2;                          \
26612666   }
26622667
2663static UINT8 snes_dbg_video( running_machine &machine, UINT16 curline )
2668static UINT8 snes_dbg_video( running_machine &machine, UINT16 curline, UINT8 *ram_ptr )
26642669{
26652670   int i;
26662671   UINT8 toggles = machine.root_device().ioport("DEBUG1")->read_safe(0);
r21558r21559
26952700      logerror("%s", debug_options.windows_disabled?" ":"W");
26962701      logerror("%s1 %s%s%s%s%s%c%s%s%d%s %d %4X %4X",
26972702            debug_options.bg_disabled[0]?" ":"*",
2698            (snes_ram[TM] & 0x1)?"M":" ",
2699            (snes_ram[TS] & 0x1)?"S":" ",
2700            (snes_ram[CGADSUB] & 0x1)?"B":" ",
2701            (snes_ram[TMW] & 0x1)?"m":" ",
2702            (snes_ram[TSW] & 0x1)?"s":" ",
2703            WINLOGIC[(snes_ram[WBGLOG] & 0x3)],
2704            (snes_ram[W12SEL] & 0x2)?((snes_ram[W12SEL] & 0x1)?"o":"i"):" ",
2705            (snes_ram[W12SEL] & 0x8)?((snes_ram[W12SEL] & 0x4)?"o":"i"):" ",
2706            snes_ppu.layer[SNES_BG1].tile_size + 1,
2707            (snes_ram[MOSAIC] & 0x1)?"m":" ",
2708            snes_ram[BG1SC] & 0x3,
2709            (snes_ram[BG1SC] & 0xfc) << 9,
2710            snes_ppu.layer[SNES_BG1].charmap << 13);
2703            (ram_ptr[TM] & 0x1)?"M":" ",
2704            (ram_ptr[TS] & 0x1)?"S":" ",
2705            (ram_ptr[CGADSUB] & 0x1)?"B":" ",
2706            (ram_ptr[TMW] & 0x1)?"m":" ",
2707            (ram_ptr[TSW] & 0x1)?"s":" ",
2708            WINLOGIC[(ram_ptr[WBGLOG] & 0x3)],
2709            (ram_ptr[W12SEL] & 0x2)?((ram_ptr[W12SEL] & 0x1)?"o":"i"):" ",
2710            (ram_ptr[W12SEL] & 0x8)?((ram_ptr[W12SEL] & 0x4)?"o":"i"):" ",
2711            m_layer[SNES_BG1].tile_size + 1,
2712            (ram_ptr[MOSAIC] & 0x1)?"m":" ",
2713            ram_ptr[BG1SC] & 0x3,
2714            (ram_ptr[BG1SC] & 0xfc) << 9,
2715            m_layer[SNES_BG1].charmap << 13);
27112716      logerror("%s2 %s%s%s%s%s%c%s%s%d%s %d %4X %4X",
27122717            debug_options.bg_disabled[1]?" ":"*",
2713            (snes_ram[TM] & 0x2)?"M":" ",
2714            (snes_ram[TS] & 0x2)?"S":" ",
2715            (snes_ram[CGADSUB] & 0x2)?"B":" ",
2716            (snes_ram[TMW] & 0x2)?"m":" ",
2717            (snes_ram[TSW] & 0x2)?"s":" ",
2718            WINLOGIC[(snes_ram[WBGLOG] & 0xc) >> 2],
2719            (snes_ram[W12SEL] & 0x20)?((snes_ram[W12SEL] & 0x10)?"o":"i"):" ",
2720            (snes_ram[W12SEL] & 0x80)?((snes_ram[W12SEL] & 0x40)?"o":"i"):" ",
2721            snes_ppu.layer[SNES_BG2].tile_size + 1,
2722            (snes_ram[MOSAIC] & 0x2)?"m":" ",
2723            snes_ram[BG2SC] & 0x3,
2724            (snes_ram[BG2SC] & 0xfc) << 9,
2725            snes_ppu.layer[SNES_BG2].charmap << 13);
2718            (ram_ptr[TM] & 0x2)?"M":" ",
2719            (ram_ptr[TS] & 0x2)?"S":" ",
2720            (ram_ptr[CGADSUB] & 0x2)?"B":" ",
2721            (ram_ptr[TMW] & 0x2)?"m":" ",
2722            (ram_ptr[TSW] & 0x2)?"s":" ",
2723            WINLOGIC[(ram_ptr[WBGLOG] & 0xc) >> 2],
2724            (ram_ptr[W12SEL] & 0x20)?((ram_ptr[W12SEL] & 0x10)?"o":"i"):" ",
2725            (ram_ptr[W12SEL] & 0x80)?((ram_ptr[W12SEL] & 0x40)?"o":"i"):" ",
2726            m_layer[SNES_BG2].tile_size + 1,
2727            (ram_ptr[MOSAIC] & 0x2)?"m":" ",
2728            ram_ptr[BG2SC] & 0x3,
2729            (ram_ptr[BG2SC] & 0xfc) << 9,
2730            m_layer[SNES_BG2].charmap << 13);
27262731      logerror("%s3 %s%s%s%s%s%c%s%s%d%s%s%d %4X %4X",
27272732            debug_options.bg_disabled[2]?" ":"*",
2728            (snes_ram[TM] & 0x4)?"M":" ",
2729            (snes_ram[TS] & 0x4)?"S":" ",
2730            (snes_ram[CGADSUB] & 0x4)?"B":" ",
2731            (snes_ram[TMW] & 0x4)?"m":" ",
2732            (snes_ram[TSW] & 0x4)?"s":" ",
2733            WINLOGIC[(snes_ram[WBGLOG] & 0x30)>>4],
2734            (snes_ram[W34SEL] & 0x2)?((snes_ram[W34SEL] & 0x1)?"o":"i"):" ",
2735            (snes_ram[W34SEL] & 0x8)?((snes_ram[W34SEL] & 0x4)?"o":"i"):" ",
2736            snes_ppu.layer[SNES_BG3].tile_size + 1,
2737            (snes_ram[MOSAIC] & 0x4)?"m":" ",
2738            (snes_ram[BGMODE] & 0x8)?"P":" ",
2739            snes_ram[BG3SC] & 0x3,
2740            (snes_ram[BG3SC] & 0xfc) << 9,
2741            snes_ppu.layer[SNES_BG3].charmap << 13);
2733            (ram_ptr[TM] & 0x4)?"M":" ",
2734            (ram_ptr[TS] & 0x4)?"S":" ",
2735            (ram_ptr[CGADSUB] & 0x4)?"B":" ",
2736            (ram_ptr[TMW] & 0x4)?"m":" ",
2737            (ram_ptr[TSW] & 0x4)?"s":" ",
2738            WINLOGIC[(ram_ptr[WBGLOG] & 0x30)>>4],
2739            (ram_ptr[W34SEL] & 0x2)?((ram_ptr[W34SEL] & 0x1)?"o":"i"):" ",
2740            (ram_ptr[W34SEL] & 0x8)?((ram_ptr[W34SEL] & 0x4)?"o":"i"):" ",
2741            m_layer[SNES_BG3].tile_size + 1,
2742            (ram_ptr[MOSAIC] & 0x4)?"m":" ",
2743            (ram_ptr[BGMODE] & 0x8)?"P":" ",
2744            ram_ptr[BG3SC] & 0x3,
2745            (ram_ptr[BG3SC] & 0xfc) << 9,
2746            m_layer[SNES_BG3].charmap << 13);
27422747      logerror("%s4 %s%s%s%s%s%c%s%s%d%s %d %4X %4X",
27432748            debug_options.bg_disabled[3]?" ":"*",
2744            (snes_ram[TM] & 0x8)?"M":" ",
2745            (snes_ram[TS] & 0x8)?"S":" ",
2746            (snes_ram[CGADSUB] & 0x8)?"B":" ",
2747            (snes_ram[TMW] & 0x8)?"m":" ",
2748            (snes_ram[TSW] & 0x8)?"s":" ",
2749            WINLOGIC[(snes_ram[WBGLOG] & 0xc0)>>6],
2750            (snes_ram[W34SEL] & 0x20)?((snes_ram[W34SEL] & 0x10)?"o":"i"):" ",
2751            (snes_ram[W34SEL] & 0x80)?((snes_ram[W34SEL] & 0x40)?"o":"i"):" ",
2752            snes_ppu.layer[SNES_BG4].tile_size + 1,
2753            (snes_ram[MOSAIC] & 0x8)?"m":" ",
2754            snes_ram[BG4SC] & 0x3,
2755            (snes_ram[BG4SC] & 0xfc) << 9,
2756            snes_ppu.layer[SNES_BG4].charmap << 13 );
2749            (ram_ptr[TM] & 0x8)?"M":" ",
2750            (ram_ptr[TS] & 0x8)?"S":" ",
2751            (ram_ptr[CGADSUB] & 0x8)?"B":" ",
2752            (ram_ptr[TMW] & 0x8)?"m":" ",
2753            (ram_ptr[TSW] & 0x8)?"s":" ",
2754            WINLOGIC[(ram_ptr[WBGLOG] & 0xc0)>>6],
2755            (ram_ptr[W34SEL] & 0x20)?((ram_ptr[W34SEL] & 0x10)?"o":"i"):" ",
2756            (ram_ptr[W34SEL] & 0x80)?((ram_ptr[W34SEL] & 0x40)?"o":"i"):" ",
2757            m_layer[SNES_BG4].tile_size + 1,
2758            (ram_ptr[MOSAIC] & 0x8)?"m":" ",
2759            ram_ptr[BG4SC] & 0x3,
2760            (ram_ptr[BG4SC] & 0xfc) << 9,
2761            m_layer[SNES_BG4].charmap << 13 );
27572762      logerror("%sO %s%s%s%s%s%c%s%s       %4X",
27582763            debug_options.bg_disabled[4]?" ":"*",
2759            (snes_ram[TM] & 0x10)?"M":" ",
2760            (snes_ram[TS] & 0x10)?"S":" ",
2761            (snes_ram[CGADSUB] & 0x10)?"B":" ",
2762            (snes_ram[TMW] & 0x10)?"m":" ",
2763            (snes_ram[TSW] & 0x10)?"s":" ",
2764            WINLOGIC[(snes_ram[WOBJLOG] & 0x3)],
2765            (snes_ram[WOBJSEL] & 0x2)?((snes_ram[WOBJSEL] & 0x1)?"o":"i"):" ",
2766            (snes_ram[WOBJSEL] & 0x8)?((snes_ram[WOBJSEL] & 0x4)?"o":"i"):" ",
2767            snes_ppu.layer[SNES_OAM].charmap << 13 );
2764            (ram_ptr[TM] & 0x10)?"M":" ",
2765            (ram_ptr[TS] & 0x10)?"S":" ",
2766            (ram_ptr[CGADSUB] & 0x10)?"B":" ",
2767            (ram_ptr[TMW] & 0x10)?"m":" ",
2768            (ram_ptr[TSW] & 0x10)?"s":" ",
2769            WINLOGIC[(ram_ptr[WOBJLOG] & 0x3)],
2770            (ram_ptr[WOBJSEL] & 0x2)?((ram_ptr[WOBJSEL] & 0x1)?"o":"i"):" ",
2771            (ram_ptr[WOBJSEL] & 0x8)?((ram_ptr[WOBJSEL] & 0x4)?"o":"i"):" ",
2772            m_layer[SNES_OAM].charmap << 13 );
27682773      logerror("%sB   %s  %c%s%s",
27692774            debug_options.colormath_disabled?" ":"*",
2770            (snes_ram[CGADSUB] & 0x20)?"B":" ",
2771            WINLOGIC[(snes_ram[WOBJLOG] & 0xc)>>2],
2772            (snes_ram[WOBJSEL] & 0x20)?((snes_ram[WOBJSEL] & 0x10)?"o":"i"):" ",
2773            (snes_ram[WOBJSEL] & 0x80)?((snes_ram[WOBJSEL] & 0x40)?"o":"i"):" " );
2774      logerror("1) %3d %3d   2) %3d %3d", (snes_ppu.bgd_offset.horizontal[0] & 0x3ff) >> 3, (snes_ppu.bgd_offset.vertical[0] & 0x3ff) >> 3, (snes_ppu.bgd_offset.horizontal[1] & 0x3ff) >> 3, (snes_ppu.bgd_offset.vertical[1] & 0x3ff) >> 3 );
2775      logerror("3) %3d %3d   4) %3d %3d", (snes_ppu.bgd_offset.horizontal[2] & 0x3ff) >> 3, (snes_ppu.bgd_offset.vertical[2] & 0x3ff) >> 3, (snes_ppu.bgd_offset.horizontal[3] & 0x3ff) >> 3, (snes_ppu.bgd_offset.vertical[3] & 0x3ff) >> 3 );
2776      logerror("Flags: %s%s%s %s %2d", (snes_ram[CGWSEL] & 0x2)?"S":"F", (snes_ram[CGADSUB] & 0x80)?"-":"+", (snes_ram[CGADSUB] & 0x40)?" 50%":"100%",(snes_ram[CGWSEL] & 0x1)?"D":"P", (snes_ram[MOSAIC] & 0xf0) >> 4 );
2777      logerror("SetINI: %s %s %s %s %s %s", (snes_ram[SETINI] & 0x1)?" I":"NI", (snes_ram[SETINI] & 0x2)?"P":"R", (snes_ram[SETINI] & 0x4)?"240":"225",(snes_ram[SETINI] & 0x8)?"512":"256",(snes_ram[SETINI] & 0x40)?"E":"N",(snes_ram[SETINI] & 0x80)?"ES":"NS" );
2778      logerror("Mode7: A %5d B %5d", snes_ppu.mode7.matrix_a, snes_ppu.mode7.matrix_b );
2779      logerror(" %s%s%s   C %5d D %5d", (snes_ram[M7SEL] & 0xc0)?((snes_ram[M7SEL] & 0x40)?"0":"C"):"R", (snes_ram[M7SEL] & 0x1)?"H":" ", (snes_ram[M7SEL] & 0x2)?"V":" ", snes_ppu.mode7.matrix_c, snes_ppu.mode7.matrix_d );
2780      logerror("       X %5d Y %5d", snes_ppu.mode7.origin_x, snes_ppu.mode7.origin_y );
2775            (ram_ptr[CGADSUB] & 0x20)?"B":" ",
2776            WINLOGIC[(ram_ptr[WOBJLOG] & 0xc)>>2],
2777            (ram_ptr[WOBJSEL] & 0x20)?((ram_ptr[WOBJSEL] & 0x10)?"o":"i"):" ",
2778            (ram_ptr[WOBJSEL] & 0x80)?((ram_ptr[WOBJSEL] & 0x40)?"o":"i"):" " );
2779      logerror("1) %3d %3d   2) %3d %3d", (m_bgd_offset.horizontal[0] & 0x3ff) >> 3, (m_bgd_offset.vertical[0] & 0x3ff) >> 3, (m_bgd_offset.horizontal[1] & 0x3ff) >> 3, (m_bgd_offset.vertical[1] & 0x3ff) >> 3 );
2780      logerror("3) %3d %3d   4) %3d %3d", (m_bgd_offset.horizontal[2] & 0x3ff) >> 3, (m_bgd_offset.vertical[2] & 0x3ff) >> 3, (m_bgd_offset.horizontal[3] & 0x3ff) >> 3, (m_bgd_offset.vertical[3] & 0x3ff) >> 3 );
2781      logerror("Flags: %s%s%s %s %2d", (ram_ptr[CGWSEL] & 0x2)?"S":"F", (ram_ptr[CGADSUB] & 0x80)?"-":"+", (ram_ptr[CGADSUB] & 0x40)?" 50%":"100%",(ram_ptr[CGWSEL] & 0x1)?"D":"P", (ram_ptr[MOSAIC] & 0xf0) >> 4 );
2782      logerror("SetINI: %s %s %s %s %s %s", (ram_ptr[SETINI] & 0x1)?" I":"NI", (ram_ptr[SETINI] & 0x2)?"P":"R", (ram_ptr[SETINI] & 0x4)?"240":"225",(ram_ptr[SETINI] & 0x8)?"512":"256",(ram_ptr[SETINI] & 0x40)?"E":"N",(ram_ptr[SETINI] & 0x80)?"ES":"NS" );
2783      logerror("Mode7: A %5d B %5d", m_mode7.matrix_a, m_mode7.matrix_b );
2784      logerror(" %s%s%s   C %5d D %5d", (ram_ptr[M7SEL] & 0xc0)?((ram_ptr[M7SEL] & 0x40)?"0":"C"):"R", (ram_ptr[M7SEL] & 0x1)?"H":" ", (ram_ptr[M7SEL] & 0x2)?"V":" ", m_mode7.matrix_c, m_mode7.matrix_d );
2785      logerror("       X %5d Y %5d", m_mode7.origin_x, m_mode7.origin_y );
27812786   }
27822787#endif
27832788
trunk/src/mess/drivers/snes.c
r21558r21559
142142   INT16 y = field.machine().root_device().ioport(portnames[port][2])->read();
143143
144144   /* these are the theoretical boundaries, but we currently are always onscreen... */
145   if (x < 0 || x >= SNES_SCR_WIDTH || y < 0 || y >= snes_ppu.beam.last_visible_line)
145   if (x < 0 || x >= SNES_SCR_WIDTH || y < 0 || y >= state->m_ppu.m_beam.last_visible_line)
146146      state->m_scope[port].offscreen = 1;
147147   else
148148      state->m_scope[port].offscreen = 0;
r21558r21559
377377
378378static void snes_gun_latch( running_machine &machine, INT16 x, INT16 y )
379379{
380   snes_state *state = machine.driver_data<snes_state>();
380381   /* these are the theoretical boundaries */
381382   if (x < 0)
382383      x = 0;
r21558r21559
385386
386387   if (y < 0)
387388      y = 0;
388   if (y > (snes_ppu.beam.last_visible_line - 1))
389      y = snes_ppu.beam.last_visible_line - 1;
389   if (y > (state->m_ppu.m_beam.last_visible_line - 1))
390      y = state->m_ppu.m_beam.last_visible_line - 1;
390391
391   snes_ppu.beam.latch_horz = x;
392   snes_ppu.beam.latch_vert = y;
392   state->m_ppu.m_beam.latch_horz = x;
393   state->m_ppu.m_beam.latch_vert = y;
393394   snes_ram[STAT78] |= 0x40;
394395}
395396

Previous 199869 Revisions Next


© 1997-2024 The MAME Team