Previous 199869 Revisions Next

r20641 Thursday 31st January, 2013 at 21:40:26 UTC by Wilbert Pol
Changed LR35902 configuration and tagmap lookup reduction for gameboy.c (nw)
[src/emu/cpu/lr35902]lr35902.c lr35902.h
[src/mess/drivers]gb.c
[src/mess/includes]gb.h
[src/mess/machine]gb.c
[src/mess/video]gb.c

trunk/src/mess/machine/gb.c
r20640r20641
130130
131131
132132static void gb_machine_stop(running_machine &machine);
133static void gb_timer_increment( running_machine &machine );
134133
135134#ifdef MAME_DEBUG
136135/* #define V_GENERAL*/      /* Display general debug information */
137136/* #define V_BANK*/         /* Display bank switching debug information */
138137#endif
139138
140static void gb_init_regs(running_machine &machine)
139void gb_state::gb_init_regs()
141140{
142   gb_state *state = machine.driver_data<gb_state>();
143141   /* Initialize the registers */
144   state->SIODATA = 0x00;
145   state->SIOCONT = 0x7E;
142   SIODATA = 0x00;
143   SIOCONT = 0x7E;
146144
147   state->gb_io_w( machine.device("maincpu")->memory().space(AS_PROGRAM ), 0x05, 0x00 );       /* TIMECNT */
148   state->gb_io_w( machine.device("maincpu")->memory().space(AS_PROGRAM ), 0x06, 0x00 );       /* TIMEMOD */
145   gb_io_w( m_maincpu->space(AS_PROGRAM ), 0x05, 0x00 );       /* TIMECNT */
146   gb_io_w( m_maincpu->space(AS_PROGRAM ), 0x06, 0x00 );       /* TIMEMOD */
149147}
150148
151static void gb_rom16_0000( running_machine &machine, UINT8 *addr )
149
150void gb_state::gb_rom16_0000( UINT8 *addr )
152151{
153   gb_state *state = machine.driver_data<gb_state>();
154   state->membank( "bank5" )->set_base( addr );
155   state->membank( "bank10" )->set_base( addr + 0x0100 );
156   state->membank( "bank6" )->set_base( addr + 0x0200 );
157   state->membank( "bank11" )->set_base( addr + 0x0900 );
152   m_bank5->set_base( addr );
153   m_bank10->set_base( addr + 0x0100 );
154   m_bank6->set_base( addr + 0x0200 );
155   m_bank11->set_base( addr + 0x0900 );
158156}
159157
160static void gb_rom16_4000( running_machine &machine, UINT8 *addr )
158
159void gb_state::gb_rom16_4000( UINT8 *addr )
161160{
162   gb_state *state = machine.driver_data<gb_state>();
163   state->membank( "bank1" )->set_base( addr );
164   state->membank( "bank4" )->set_base( addr + 0x2000 );
161   m_bank1->set_base( addr );
162   m_bank4->set_base( addr + 0x2000 );
165163}
166164
167static void gb_rom8_4000( running_machine &machine, UINT8 *addr )
165
166void gb_state::gb_rom8_4000( UINT8 *addr )
168167{
169   gb_state *state = machine.driver_data<gb_state>();
170   state->membank( "bank1" )->set_base( addr );
168   m_bank1->set_base( addr );
171169}
172170
173static void gb_rom8_6000( running_machine &machine, UINT8 *addr )
171
172void gb_state::gb_rom8_6000( UINT8 *addr )
174173{
175   gb_state *state = machine.driver_data<gb_state>();
176   state->membank( "bank4" )->set_base( addr );
174   m_bank4->set_base( addr );
177175}
178176
179static void gb_init(running_machine &machine)
177
178void gb_state::gb_init()
180179{
181   gb_state *state = machine.driver_data<gb_state>();
182   address_space &space = machine.device( "maincpu")->memory().space( AS_PROGRAM );
180   address_space &space = m_maincpu->space( AS_PROGRAM );
183181
184182   /* Initialize the memory banks */
185   state->m_MBC1Mode = 0;
186   state->m_MBC3RTCBank = 0;
187   state->m_ROMBank = state->m_ROMBank00 + 1;
188   state->m_RAMBank = 0;
183   m_MBC1Mode = 0;
184   m_MBC3RTCBank = 0;
185   m_ROMBank = m_ROMBank00 + 1;
186   m_RAMBank = 0;
189187
190   if (state->m_gb_cart)
188   if (m_gb_cart)
191189   {
192      if ( state->m_MBCType != MBC_MEGADUCK )
190      if ( m_MBCType != MBC_MEGADUCK )
193191      {
194         gb_rom16_4000( machine, state->m_ROMMap[state->m_ROMBank] );
195         state->membank ("bank2")->set_base (state->m_RAMMap[state->m_RAMBank] ? state->m_RAMMap[state->m_RAMBank] : state->m_gb_dummy_ram_bank);
192         gb_rom16_4000( m_ROMMap[m_ROMBank] );
193         m_bank2->set_base( m_RAMMap[m_RAMBank] ? m_RAMMap[m_RAMBank] : m_gb_dummy_ram_bank);
196194      }
197195      else
198196      {
199         state->membank( "bank1" )->set_base( state->m_ROMMap[state->m_ROMBank] );
200         state->membank( "bank10" )->set_base( state->m_ROMMap[0] );
197         m_bank1->set_base( m_ROMMap[m_ROMBank] );
198         m_bank10->set_base( m_ROMMap[0] );
201199      }
202200   }
203201
204202   /* Set handlers based on the Memory Bank Controller in the cart */
205   switch( state->m_MBCType )
203   switch( m_MBCType )
206204   {
207205      case MBC_NONE:
208206         break;
209207      case MBC_MMM01:
210         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_rom_bank_mmm01_0000_w),state) );
211         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_mmm01_2000_w),state));
212         space.install_write_handler( 0x4000, 0x5fff, write8_delegate(FUNC(gb_state::gb_rom_bank_mmm01_4000_w),state));
213         space.install_write_handler( 0x6000, 0x7fff, write8_delegate(FUNC(gb_state::gb_rom_bank_mmm01_6000_w),state));
208         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_rom_bank_mmm01_0000_w),this) );
209         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_mmm01_2000_w),this));
210         space.install_write_handler( 0x4000, 0x5fff, write8_delegate(FUNC(gb_state::gb_rom_bank_mmm01_4000_w),this));
211         space.install_write_handler( 0x6000, 0x7fff, write8_delegate(FUNC(gb_state::gb_rom_bank_mmm01_6000_w),this));
214212         break;
215213      case MBC_MBC1:
216         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_enable),state) );    /* We don't emulate RAM enable yet */
217         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc1),state) );
218         space.install_write_handler( 0x4000, 0x5fff, write8_delegate(FUNC(gb_state::gb_ram_bank_select_mbc1),state) );
219         space.install_write_handler( 0x6000, 0x7fff, write8_delegate(FUNC(gb_state::gb_mem_mode_select_mbc1),state) );
214         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_enable),this) );    /* We don't emulate RAM enable yet */
215         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc1),this) );
216         space.install_write_handler( 0x4000, 0x5fff, write8_delegate(FUNC(gb_state::gb_ram_bank_select_mbc1),this) );
217         space.install_write_handler( 0x6000, 0x7fff, write8_delegate(FUNC(gb_state::gb_mem_mode_select_mbc1),this) );
220218         break;
221219      case MBC_MBC2:
222         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc2),state) );
220         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc2),this) );
223221         break;
224222      case MBC_MBC3:
225223      case MBC_HUC1:  /* Possibly wrong */
226224      case MBC_HUC3:  /* Possibly wrong */
227         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_enable),state) );    /* We don't emulate RAM enable yet */
228         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc3),state) );
229         space.install_write_handler( 0x4000, 0x5fff, write8_delegate(FUNC(gb_state::gb_ram_bank_select_mbc3),state) );
230         space.install_write_handler( 0x6000, 0x7fff, write8_delegate(FUNC(gb_state::gb_mem_mode_select_mbc3),state) );
225         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_enable),this) );    /* We don't emulate RAM enable yet */
226         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc3),this) );
227         space.install_write_handler( 0x4000, 0x5fff, write8_delegate(FUNC(gb_state::gb_ram_bank_select_mbc3),this) );
228         space.install_write_handler( 0x6000, 0x7fff, write8_delegate(FUNC(gb_state::gb_mem_mode_select_mbc3),this) );
231229         break;
232230      case MBC_MBC5:
233         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_enable),state) );
234         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc5),state) );
235         space.install_write_handler( 0x4000, 0x5fff, write8_delegate(FUNC(gb_state::gb_ram_bank_select_mbc5),state) );
231         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_enable),this) );
232         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc5),this) );
233         space.install_write_handler( 0x4000, 0x5fff, write8_delegate(FUNC(gb_state::gb_ram_bank_select_mbc5),this) );
236234         break;
237235      case MBC_MBC6:
238         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_bank_select_mbc6),state) );
239         space.install_write_handler( 0x2000, 0x2fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc6_1),state) );
240         space.install_write_handler( 0x3000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc6_2),state) );
236         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_bank_select_mbc6),this) );
237         space.install_write_handler( 0x2000, 0x2fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc6_1),this) );
238         space.install_write_handler( 0x3000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc6_2),this) );
241239         break;
242240      case MBC_MBC7:
243         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_enable),state) );
244         space.install_write_handler( 0x2000, 0x2fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc7),state) );
245         space.install_write_handler( 0x3000, 0x7fff, write8_delegate(FUNC(gb_state::gb_rom_bank_unknown_mbc7),state) );
241         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_enable),this) );
242         space.install_write_handler( 0x2000, 0x2fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc7),this) );
243         space.install_write_handler( 0x3000, 0x7fff, write8_delegate(FUNC(gb_state::gb_rom_bank_unknown_mbc7),this) );
246244         break;
247245      case MBC_TAMA5:
248         space.install_write_handler( 0xA000, 0xBFFF, write8_delegate(FUNC(gb_state::gb_ram_tama5),state) );
246         space.install_write_handler( 0xA000, 0xBFFF, write8_delegate(FUNC(gb_state::gb_ram_tama5),this) );
249247         break;
250248      case MBC_WISDOM:
251         space.install_write_handler( 0x0000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_wisdom),state) );
249         space.install_write_handler( 0x0000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_wisdom),this) );
252250         break;
253251      case MBC_MBC1_KOR:
254         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_enable),state) ); /* We don't emulate RAM enable yet */
255         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc1_kor),state) );
256         space.install_write_handler( 0x4000, 0x5fff, write8_delegate(FUNC(gb_state::gb_ram_bank_select_mbc1_kor),state) );
257         space.install_write_handler( 0x6000, 0x7fff, write8_delegate(FUNC(gb_state::gb_mem_mode_select_mbc1_kor),state) );
252         space.install_write_handler( 0x0000, 0x1fff, write8_delegate(FUNC(gb_state::gb_ram_enable),this) ); /* We don't emulate RAM enable yet */
253         space.install_write_handler( 0x2000, 0x3fff, write8_delegate(FUNC(gb_state::gb_rom_bank_select_mbc1_kor),this) );
254         space.install_write_handler( 0x4000, 0x5fff, write8_delegate(FUNC(gb_state::gb_ram_bank_select_mbc1_kor),this) );
255         space.install_write_handler( 0x6000, 0x7fff, write8_delegate(FUNC(gb_state::gb_mem_mode_select_mbc1_kor),this) );
258256         break;
259257      case MBC_YONGYONG:
260         space.install_write_handler( 0x2000, 0x2000, write8_delegate(FUNC(gb_state::gb_rom_bank_yongyong_2000),state) );
261         //space.install_write_handler( 0x5000, 0x5003, write8_delegate(FUNC(gb_state::gb_rom_back_yongyong_5000),state) );
258         space.install_write_handler( 0x2000, 0x2000, write8_delegate(FUNC(gb_state::gb_rom_bank_yongyong_2000),this) );
259         //space.install_write_handler( 0x5000, 0x5003, write8_delegate(FUNC(gb_state::gb_rom_back_yongyong_5000),this) );
262260         break;
263261      case MBC_LASAMA:
264         space.install_write_handler( 0x2080, 0x2080, write8_delegate(FUNC(gb_state::gb_rom_bank_lasama_2080),state) );
265         space.install_write_handler( 0x6000, 0x6000, write8_delegate(FUNC(gb_state::gb_rom_bank_lasama_6000),state) );
262         space.install_write_handler( 0x2080, 0x2080, write8_delegate(FUNC(gb_state::gb_rom_bank_lasama_2080),this) );
263         space.install_write_handler( 0x6000, 0x6000, write8_delegate(FUNC(gb_state::gb_rom_bank_lasama_6000),this) );
266264         break;
267265      case MBC_ATVRACIN:
268         space.install_write_handler( 0x3F00, 0x3F00, write8_delegate(FUNC(gb_state::gb_rom_bank_atvracin_3f00),state) );
269         space.install_write_handler( 0x3FC0, 0x3FC0, write8_delegate(FUNC(gb_state::gb_rom_bank_atvracin_3fc0),state) );
266         space.install_write_handler( 0x3F00, 0x3F00, write8_delegate(FUNC(gb_state::gb_rom_bank_atvracin_3f00),this) );
267         space.install_write_handler( 0x3FC0, 0x3FC0, write8_delegate(FUNC(gb_state::gb_rom_bank_atvracin_3fc0),this) );
270268         break;
271269
272270      case MBC_MEGADUCK:
273         space.install_write_handler( 0x0001, 0x0001, write8_delegate(FUNC(gb_state::megaduck_rom_bank_select_type1),state) );
274         space.install_write_handler( 0xB000, 0xB000, write8_delegate(FUNC(gb_state::megaduck_rom_bank_select_type2),state) );
271         space.install_write_handler( 0x0001, 0x0001, write8_delegate(FUNC(gb_state::megaduck_rom_bank_select_type1),this) );
272         space.install_write_handler( 0xB000, 0xB000, write8_delegate(FUNC(gb_state::megaduck_rom_bank_select_type2),this) );
275273         break;
276274   }
277275
278   gb_sound_w(space.machine().device("custom"), space, 0x16, 0x00 );       /* Initialize sound hardware */
276   gb_sound_w(machine().device("custom"), space, 0x16, 0x00 );       /* Initialize sound hardware */
279277
280   state->m_divcount = 0;
281   state->m_triggering_irq = 0;
282   state->m_gb_io[0x07] = 0xF8;        /* Upper bits of TIMEFRQ register are set to 1 */
278   m_divcount = 0;
279   m_triggering_irq = 0;
280   m_gb_io[0x07] = 0xF8;        /* Upper bits of TIMEFRQ register are set to 1 */
283281}
284282
283
285284MACHINE_START_MEMBER(gb_state,gb)
286285{
287286   machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(gb_machine_stop),&machine()));
r20640r20641
306305
307306MACHINE_RESET_MEMBER(gb_state,gb)
308307{
309   gb_init(machine());
308   gb_init();
310309
311   gb_video_reset( machine(), GB_VIDEO_DMG );
310   gb_video_reset( GB_VIDEO_DMG );
312311
313   gb_rom16_0000( machine(), m_ROMMap[m_ROMBank00] );
312   gb_rom16_0000( m_ROMMap[m_ROMBank00] );
314313
315314   /* Enable BIOS rom */
316   membank("bank5")->set_base(memregion("maincpu")->base() );
315   m_bank5->set_base(memregion("maincpu")->base() );
317316
318317   m_divcount = 0x0004;
319318}
r20640r20641
335334
336335MACHINE_RESET_MEMBER(gb_state,sgb)
337336{
338   gb_init(machine());
337   gb_init();
339338
340   gb_video_reset( machine(), GB_VIDEO_SGB );
339   gb_video_reset( GB_VIDEO_SGB );
341340
342   gb_init_regs(machine());
341   gb_init_regs();
343342
344   gb_rom16_0000( machine(), m_ROMMap[m_ROMBank00] ? m_ROMMap[m_ROMBank00] : m_gb_dummy_rom_bank );
343   gb_rom16_0000( m_ROMMap[m_ROMBank00] ? m_ROMMap[m_ROMBank00] : m_gb_dummy_rom_bank );
345344
346345   /* Enable BIOS rom */
347   membank("bank5")->set_base(memregion("maincpu")->base() );
346   m_bank5->set_base(memregion("maincpu")->base() );
348347
349348   memset( m_sgb_tile_data, 0, 0x2000 );
350349
r20640r20641
369368
370369MACHINE_RESET_MEMBER(gb_state,gbpocket)
371370{
372   gb_init(machine());
371   gb_init();
373372
374   gb_video_reset( machine(), GB_VIDEO_MGB );
373   gb_video_reset( GB_VIDEO_MGB );
375374
376   gb_init_regs(machine());
375   gb_init_regs();
377376
378377   /* Initialize the Sound registers */
379378   gb_sound_w(machine().device("custom"), generic_space(), 0x16,0x80);
r20640r20641
381380   gb_sound_w(machine().device("custom"), generic_space(), 0x14,0x77);
382381
383382   /* Enable BIOS rom if we have one */
384   gb_rom16_0000( machine(), m_ROMMap[m_ROMBank00] ? m_ROMMap[m_ROMBank00] : m_gb_dummy_rom_bank );
383   gb_rom16_0000( m_ROMMap[m_ROMBank00] ? m_ROMMap[m_ROMBank00] : m_gb_dummy_rom_bank );
385384
386385   m_divcount = 0xABC8;
387386}
r20640r20641
390389{
391390   int ii;
392391
393   gb_init(machine());
392   gb_init();
394393
395   gb_video_reset( machine(), GB_VIDEO_CGB );
394   gb_video_reset( GB_VIDEO_CGB );
396395
397   gb_init_regs(machine());
396   gb_init_regs();
398397
399   gb_rom16_0000( machine(), m_ROMMap[m_ROMBank00] ? m_ROMMap[m_ROMBank00] : m_gb_dummy_rom_bank );
398   gb_rom16_0000( m_ROMMap[m_ROMBank00] ? m_ROMMap[m_ROMBank00] : m_gb_dummy_rom_bank );
400399
401400   /* Enable BIOS rom */
402   membank("bank5")->set_base(machine().root_device().memregion("maincpu")->base() );
403   membank("bank6")->set_base(memregion("maincpu")->base() + 0x100 );
401   m_bank5->set_base(memregion("maincpu")->base() );
402   m_bank6->set_base(memregion("maincpu")->base() + 0x100 );
404403
405404   /* Allocate memory for internal ram */
406405   for( ii = 0; ii < 8; ii++ )
r20640r20641
424423   image->battery_save(state->m_gb_cart_ram, state->m_RAMBanks * 0x2000);
425424}
426425
427static void gb_set_mbc1_banks( running_machine &machine )
426void gb_state::gb_set_mbc1_banks()
428427{
429   gb_state *state = machine.driver_data<gb_state>();
430   gb_rom16_4000( machine, state->m_ROMMap[ state->m_ROMBank ] );
431   state->membank( "bank2" )->set_base( state->m_RAMMap[ state->m_MBC1Mode ? ( state->m_ROMBank >> 5 ) : 0 ] );
428   gb_rom16_4000( m_ROMMap[ m_ROMBank ] );
429   m_bank2->set_base( m_RAMMap[ m_MBC1Mode ? ( m_ROMBank >> 5 ) : 0 ] );
432430}
433431
434432WRITE8_MEMBER(gb_state::gb_rom_bank_select_mbc1)
r20640r20641
440438
441439   m_ROMBank = ( m_ROMBank & 0x01E0 ) | data;
442440   /* Switch banks */
443   gb_set_mbc1_banks(machine());
441   gb_set_mbc1_banks();
444442}
445443
446444WRITE8_MEMBER(gb_state::gb_rom_bank_select_mbc2)
r20640r20641
454452   if( offset & 0x0100 )
455453      m_ROMBank = ( m_ROMBank & 0x100 ) | data;
456454   /* Switch banks */
457   gb_rom16_4000( machine(), m_ROMMap[m_ROMBank] );
455   gb_rom16_4000( m_ROMMap[m_ROMBank] );
458456}
459457
460458WRITE8_MEMBER(gb_state::gb_rom_bank_select_mbc3)
r20640r20641
467465
468466   m_ROMBank = ( m_ROMBank & 0x0100 ) | data;
469467   /* Switch banks */
470   gb_rom16_4000( machine(), m_ROMMap[m_ROMBank] );
468   gb_rom16_4000( m_ROMMap[m_ROMBank] );
471469}
472470
473471WRITE8_MEMBER(gb_state::gb_rom_bank_select_mbc5)
r20640r20641
486484      m_ROMBank = (m_ROMBank & 0x100 ) | data;
487485   }
488486   /* Switch banks */
489   gb_rom16_4000( machine(), m_ROMMap[m_ROMBank] );
487   gb_rom16_4000( m_ROMMap[m_ROMBank] );
490488}
491489
492490WRITE8_MEMBER(gb_state::gb_ram_bank_select_mbc6)
r20640r20641
501499   {
502500      if ( data == 0x00 )
503501      {
504         gb_rom8_4000( machine(), m_ROMMap[m_ROMBank>>1] + ( ( m_ROMBank & 0x01 ) ? 0x2000 : 0x0000 ) );
502         gb_rom8_4000( m_ROMMap[m_ROMBank>>1] + ( ( m_ROMBank & 0x01 ) ? 0x2000 : 0x0000 ) );
505503      }
506504   }
507505   else
r20640r20641
517515   {
518516      if ( data == 0x00 )
519517      {
520         gb_rom8_6000( machine(), m_ROMMap[m_ROMBank00>>1] + ( ( m_ROMBank00 & 0x01 ) ? 0x2000 : 0x0000 ) );
518         gb_rom8_6000( m_ROMMap[m_ROMBank00>>1] + ( ( m_ROMBank00 & 0x01 ) ? 0x2000 : 0x0000 ) );
521519      }
522520   }
523521   else
r20640r20641
533531   if ( offset & 0x0100 )
534532   {
535533      m_ROMBank = data;
536      gb_rom16_4000( machine(), m_ROMMap[m_ROMBank] );
534      gb_rom16_4000( m_ROMMap[m_ROMBank] );
537535   }
538536}
539537
r20640r20641
560558   logerror( "0x%04X: wisdom tree mapper write to address 0x%04X\n", space.device() .safe_pc( ), offset );
561559   /* The address determines the bank to select */
562560   m_ROMBank = ( offset << 1 ) & 0x1FF;
563   membank( "bank5" )->set_base( m_ROMMap[ m_ROMBank ] );
564   membank( "bank10" )->set_base( m_ROMMap[ m_ROMBank ] + 0x0100 );
565   membank( "bank6" )->set_base( m_ROMMap[ m_ROMBank ] + 0x0200 );
566   membank( "bank11" )->set_base( m_ROMMap[ m_ROMBank ] + 0x0900 );
567   membank( "bank1" )->set_base( m_ROMMap[ m_ROMBank + 1 ] );
568   membank( "bank4" )->set_base( m_ROMMap[ m_ROMBank + 1 ] + 0x2000 );
561   m_bank5->set_base( m_ROMMap[ m_ROMBank ] );
562   m_bank10->set_base( m_ROMMap[ m_ROMBank ] + 0x0100 );
563   m_bank6->set_base( m_ROMMap[ m_ROMBank ] + 0x0200 );
564   m_bank11->set_base( m_ROMMap[ m_ROMBank ] + 0x0900 );
565   m_bank1->set_base( m_ROMMap[ m_ROMBank + 1 ] );
566   m_bank4->set_base( m_ROMMap[ m_ROMBank + 1 ] + 0x2000 );
569567}
570568
571569WRITE8_MEMBER(gb_state::gb_ram_bank_select_mbc1)
r20640r20641
576574   m_ROMBank = ( m_ROMBank & 0x1F ) | ( data << 5 );
577575
578576   /* Switch banks */
579   gb_set_mbc1_banks(machine());
577   gb_set_mbc1_banks();
580578}
581579
582580WRITE8_MEMBER(gb_state::gb_ram_bank_select_mbc3)
r20640r20641
590588         if ( data < 5 )
591589         {
592590            memset( m_MBC3RTCData, m_MBC3RTCMap[m_MBC3RTCBank], 0x2000 );
593            membank( "bank2" )->set_base( m_MBC3RTCData );
591            m_bank2->set_base( m_MBC3RTCData );
594592         }
595593      }
596594   }
r20640r20641
599597      m_RAMBank = data & 0x3;
600598      m_MBC3RTCBank = 0xFF;
601599      /* Switch banks */
602      membank( "bank2" )->set_base( m_RAMMap[m_RAMBank] );
600      m_bank2->set_base( m_RAMMap[m_RAMBank] );
603601   }
604602}
605603
r20640r20641
613611   }
614612   m_RAMBank = data;
615613   /* Switch banks */
616   membank ("bank2")->set_base (m_RAMMap[m_RAMBank] );
614   m_bank2->set_base( m_RAMMap[m_RAMBank] );
617615}
618616
619617WRITE8_MEMBER(gb_state::gb_ram_enable)
r20640r20641
626624WRITE8_MEMBER(gb_state::gb_mem_mode_select_mbc1)
627625{
628626   m_MBC1Mode = data & 0x1;
629   gb_set_mbc1_banks(machine());
627   gb_set_mbc1_banks();
630628}
631629
632630WRITE8_MEMBER(gb_state::gb_mem_mode_select_mbc3)
r20640r20641
653651      {
654652      case 0x00:      /* Bits 0-3 for rom bank selection */
655653         m_ROMBank = ( m_ROMBank & 0xF0 ) | ( data & 0x0F );
656         gb_rom16_4000( machine(), m_ROMMap[m_ROMBank] );
654         gb_rom16_4000( m_ROMMap[m_ROMBank] );
657655         break;
658656      case 0x01:      /* Bit 4(-7?) for rom bank selection */
659657         m_ROMBank = ( m_ROMBank & 0x0F ) | ( ( data & 0x0F ) << 4 );
660         gb_rom16_4000( machine(), m_ROMMap[m_ROMBank] );
658         gb_rom16_4000( m_ROMMap[m_ROMBank] );
661659         break;
662660      case 0x04:      /* Data to write lo */
663661         m_gbTama5Byte = ( m_gbTama5Byte & 0xF0 ) | ( data & 0x0F );
r20640r20641
707705         break;
708706      case 0x0A:      /* Are we ready for the next command? */
709707         m_MBC3RTCData[0] = 0x01;
710         membank( "bank2" )->set_base( m_MBC3RTCData );
708         m_bank2->set_base( m_MBC3RTCData );
711709         break;
712710      case 0x0C:      /* Data read register lo */
713711         m_MBC3RTCData[0] = m_gbTama5Byte & 0x0F;
r20640r20641
733731   if ( data & 0x40 )
734732   {
735733      m_mmm01_bank_offset = m_mmm01_reg1;
736      membank( "bank5" )->set_base( m_ROMMap[ m_mmm01_bank_offset ] );
737      membank( "bank10" )->set_base( m_ROMMap[ m_mmm01_bank_offset ] + 0x0100 );
738      gb_rom16_4000( machine(), m_ROMMap[ m_mmm01_bank_offset + m_mmm01_bank ] );
734      m_bank5->set_base( m_ROMMap[ m_mmm01_bank_offset ] );
735      m_bank10->set_base( m_ROMMap[ m_mmm01_bank_offset ] + 0x0100 );
736      gb_rom16_4000( m_ROMMap[ m_mmm01_bank_offset + m_mmm01_bank ] );
739737   }
740738}
741739
r20640r20641
749747   {
750748      m_mmm01_bank = 1;
751749   }
752   gb_rom16_4000( machine(), m_ROMMap[ m_mmm01_bank_offset + m_mmm01_bank ] );
750   gb_rom16_4000( m_ROMMap[ m_mmm01_bank_offset + m_mmm01_bank ] );
753751}
754752
755753WRITE8_MEMBER(gb_state::gb_rom_bank_mmm01_4000_w)
r20640r20641
772770
773771/* Korean MBC1 variant mapping */
774772
775static void gb_set_mbc1_kor_banks( running_machine &machine )
773void gb_state::gb_set_mbc1_kor_banks()
776774{
777   gb_state *state = machine.driver_data<gb_state>();
778   if ( state->m_ROMBank & 0x30 )
775   if ( m_ROMBank & 0x30 )
779776   {
780      gb_rom16_0000( machine, state->m_ROMMap[ state->m_ROMBank & 0x30 ] );
777      gb_rom16_0000( m_ROMMap[ m_ROMBank & 0x30 ] );
781778   }
782   gb_rom16_4000( machine, state->m_ROMMap[ state->m_ROMBank ] );
783   state->membank( "bank2" )->set_base( state->m_RAMMap[ state->m_MBC1Mode ? ( state->m_ROMBank >> 5 ) : 0 ] );
779   gb_rom16_4000( m_ROMMap[ m_ROMBank ] );
780   m_bank2->set_base( m_RAMMap[ m_MBC1Mode ? ( m_ROMBank >> 5 ) : 0 ] );
784781}
785782
786783WRITE8_MEMBER(gb_state::gb_rom_bank_select_mbc1_kor)
r20640r20641
792789
793790   m_ROMBank = ( m_ROMBank & 0x01F0 ) | data;
794791   /* Switch banks */
795   gb_set_mbc1_kor_banks(machine());
792   gb_set_mbc1_kor_banks();
796793}
797794
798795WRITE8_MEMBER(gb_state::gb_ram_bank_select_mbc1_kor)
r20640r20641
803800   m_ROMBank = ( m_ROMBank & 0x0F ) | ( data << 4 );
804801
805802   /* Switch banks */
806   gb_set_mbc1_kor_banks(machine());
803   gb_set_mbc1_kor_banks();
807804}
808805
809806WRITE8_MEMBER(gb_state::gb_mem_mode_select_mbc1_kor)
810807{
811808   m_MBC1Mode = data & 0x1;
812   gb_set_mbc1_kor_banks(machine());
809   gb_set_mbc1_kor_banks();
813810}
814811
815812WRITE8_MEMBER(gb_state::gb_rom_bank_yongyong_2000)
816813{
817814   m_ROMBank = data;
818   gb_rom16_4000( machine(), m_ROMMap[m_ROMBank] );
815   gb_rom16_4000( m_ROMMap[m_ROMBank] );
819816}
820817
821818WRITE8_MEMBER(gb_state::gb_rom_bank_lasama_2080)
822819{
823820   // Actual banking?
824821   m_ROMBank = m_ROMBank00 | ( data & 0x03 );
825   gb_rom16_4000( machine(), m_ROMMap[m_ROMBank] );
822   gb_rom16_4000( m_ROMMap[m_ROMBank] );
826823}
827824
828825WRITE8_MEMBER(gb_state::gb_rom_bank_lasama_6000)
r20640r20641
834831   if ( ! ( data & 0x80 ) )
835832   {
836833      m_ROMBank00 = ( data & 0x02 ) << 1;
837      gb_rom16_0000( machine(), m_ROMMap[m_ROMBank00] );
834      gb_rom16_0000( m_ROMMap[m_ROMBank00] );
838835   }
839836}
840837
r20640r20641
845842      data = 1;
846843   }
847844   m_ROMBank = m_ROMBank00 | data;
848   gb_rom16_4000( machine(), m_ROMMap[m_ROMBank] );
845   gb_rom16_4000( m_ROMMap[m_ROMBank] );
849846}
850847
851848WRITE8_MEMBER(gb_state::gb_rom_bank_atvracin_3fc0)
852849{
853850   m_ROMBank00 = data * 16;
854   gb_rom16_0000( machine(), m_ROMMap[m_ROMBank00] );
851   gb_rom16_0000( m_ROMMap[m_ROMBank00] );
855852}
856853
857854WRITE8_MEMBER(gb_state::gb_io_w)
r20640r20641
863860   case 0x00:                      /* JOYP - Joypad */
864861      JOYPAD = 0xCF | data;
865862      if (!(data & 0x20))
866         JOYPAD &= (ioport("INPUTS")->read() >> 4) | 0xF0;
863         JOYPAD &= (m_inputs->read() >> 4) | 0xF0;
867864      if (!(data & 0x10))
868         JOYPAD &= ioport("INPUTS")->read() | 0xF0;
865         JOYPAD &= m_inputs->read() | 0xF0;
869866      return;
870867   case 0x01:                      /* SB - Serial transfer data */
871868      break;
r20640r20641
880877      case 0x81:              /* enabled & internal clock */
881878         SIODATA = 0xFF;
882879         m_SIOCount = 8;
883         m_gb_serial_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(512), 0, machine().device<cpu_device>("maincpu")->cycles_to_attotime(512));
880         m_gb_serial_timer->adjust(m_maincpu->cycles_to_attotime(512), 0, m_maincpu->cycles_to_attotime(512));
884881         m_gb_serial_timer->enable( 1 );
885882         break;
886883      }
r20640r20641
888885   case 0x04:                      /* DIV - Divider register */
889886      /* Force increment of TIMECNT register */
890887      if ( m_divcount >= 16 )
891         gb_timer_increment(machine());
888         gb_timer_increment();
892889      m_divcount = 0;
893890      return;
894891   case 0x05:                      /* TIMA - Timer counter */
r20640r20641
913910         /* Check if TIMECNT should be incremented */
914911         if ( ( m_divcount & ( m_shift_cycles - 1 ) ) >= ( m_shift_cycles >> 1 ) )
915912         {
916            gb_timer_increment(machine());
913            gb_timer_increment();
917914         }
918915      }
919916      m_shift = timer_shifts[data & 0x03];
r20640r20641
933930   if ( offset == 0x10 )
934931   {
935932      /* disable BIOS ROM */
936      gb_rom16_0000( machine(), m_ROMMap[m_ROMBank00] );
933      gb_rom16_0000( m_ROMMap[m_ROMBank00] );
937934   }
938935   else
939936   {
r20640r20641
988985            m_sgb_bitcount = 0;
989986            m_sgb_start = 1;
990987            m_sgb_rest = 0;
991            JOYPAD = 0x0F & ((ioport("INPUTS")->read() >> 4) | ioport("INPUTS")->read() | 0xF0);
988            JOYPAD = 0x0F & ((m_inputs->read() >> 4) | m_inputs->read() | 0xF0);
992989            break;
993990         case 0x10:                 /* data true */
994991            if (m_sgb_rest)
r20640r20641
10121009               }
10131010               m_sgb_rest = 0;
10141011            }
1015            JOYPAD = 0x1F & ((ioport("INPUTS")->read() >> 4) | 0xF0);
1012            JOYPAD = 0x1F & ((m_inputs->read() >> 4) | 0xF0);
10161013            break;
10171014         case 0x20:              /* data false */
10181015            if (m_sgb_rest)
r20640r20641
13161313                        break;
13171314                     case 0x0B:  /* PAL_TRN */
13181315                        {
1319                           UINT8 *gb_vram = gb_get_vram_ptr(machine());
13201316                           UINT16 I, col;
13211317
13221318                           for( I = 0; I < 2048; I++ )
13231319                           {
1324                              col = ( gb_vram[ 0x0800 + (I*2) + 1 ] << 8 ) | gb_vram[ 0x0800 + (I*2) ];
1320                              col = ( m_lcd.gb_vram_ptr[ 0x0800 + (I*2) + 1 ] << 8 ) | m_lcd.gb_vram_ptr[ 0x0800 + (I*2) ];
13251321                              m_sgb_pal_data[I] = col;
13261322                           }
13271323                        }
r20640r20641
13521348                        break;
13531349                     case 0x13:  /* CHR_TRN */
13541350                        if( sgb_data[1] & 0x1 )
1355                           memcpy( m_sgb_tile_data + 4096, gb_get_vram_ptr(machine()) + 0x0800, 4096 );
1351                           memcpy( m_sgb_tile_data + 4096, m_lcd.gb_vram_ptr + 0x0800, 4096 );
13561352                        else
1357                           memcpy( m_sgb_tile_data, gb_get_vram_ptr(machine()) + 0x0800, 4096 );
1353                           memcpy( m_sgb_tile_data, m_lcd.gb_vram_ptr + 0x0800, 4096 );
13581354                        break;
13591355                     case 0x14:  /* PCT_TRN */
13601356                        {
13611357                           int I;
13621358                           UINT16 col;
1363                           UINT8 *gb_vram = gb_get_vram_ptr(machine());
13641359                           if( m_sgb_hack )
13651360                           {
1366                              memcpy( m_sgb_tile_map, gb_vram + 0x1000, 2048 );
1361                              memcpy( m_sgb_tile_map, m_lcd.gb_vram_ptr + 0x1000, 2048 );
13671362                              for( I = 0; I < 64; I++ )
13681363                              {
1369                                 col = ( gb_vram[ 0x0800 + (I*2) + 1 ] << 8 ) | gb_vram[ 0x0800 + (I*2) ];
1364                                 col = ( m_lcd.gb_vram_ptr[ 0x0800 + (I*2) + 1 ] << 8 ) | m_lcd.gb_vram_ptr[ 0x0800 + (I*2) ];
13701365                                 m_sgb_pal[SGB_BORDER_PAL_OFFSET + I] = col;
13711366                              }
13721367                           }
13731368                           else /* Do things normally */
13741369                           {
1375                              memcpy( m_sgb_tile_map, gb_vram + 0x0800, 2048 );
1370                              memcpy( m_sgb_tile_map, m_lcd.gb_vram_ptr + 0x0800, 2048 );
13761371                              for( I = 0; I < 64; I++ )
13771372                              {
1378                                 col = ( gb_vram[ 0x1000 + (I*2) + 1 ] << 8 ) | gb_vram[ 0x1000 + (I*2) ];
1373                                 col = ( m_lcd.gb_vram_ptr[ 0x1000 + (I*2) + 1 ] << 8 ) | m_lcd.gb_vram_ptr[ 0x1000 + (I*2) ];
13791374                                 m_sgb_pal[SGB_BORDER_PAL_OFFSET + I] = col;
13801375                              }
13811376                           }
13821377                        }
13831378                        break;
13841379                     case 0x15:  /* ATTR_TRN */
1385                        memcpy( m_sgb_atf_data, gb_get_vram_ptr(machine()) + 0x0800, 4050 );
1380                        memcpy( m_sgb_atf_data, m_lcd.gb_vram_ptr + 0x0800, 4050 );
13861381                        break;
13871382                     case 0x16:  /* ATTR_SET */
13881383                        {
r20640r20641
14391434               }
14401435               m_sgb_rest = 0;
14411436            }
1442            JOYPAD = 0x2F & (ioport("INPUTS")->read() | 0xF0);
1437            JOYPAD = 0x2F & (m_inputs->read() | 0xF0);
14431438            break;
14441439         case 0x30:                 /* rest condition */
14451440            if (m_sgb_start)
r20640r20641
20442039   {
20452040      SIOCONT &= 0x7F;
20462041      m_gb_serial_timer->enable( 0 );
2047      machine().device("maincpu")->execute().set_input_line(SIO_INT, ASSERT_LINE);
2042      m_maincpu->set_input_line(SIO_INT, ASSERT_LINE);
20482043   }
20492044}
20502045
2051INLINE void gb_timer_check_irq( running_machine &machine )
2046void gb_state::gb_timer_check_irq()
20522047{
2053   gb_state *state = machine.driver_data<gb_state>();
2054   state->m_reloading = 0;
2055   if ( state->m_triggering_irq )
2048   m_reloading = 0;
2049   if ( m_triggering_irq )
20562050   {
2057      state->m_triggering_irq = 0;
2058      if ( state->TIMECNT == 0 )
2051      m_triggering_irq = 0;
2052      if ( TIMECNT == 0 )
20592053      {
2060         state->TIMECNT = state->TIMEMOD;
2061         machine.device("maincpu")->execute().set_input_line(TIM_INT, ASSERT_LINE );
2062         state->m_reloading = 1;
2054         TIMECNT = TIMEMOD;
2055         m_maincpu->set_input_line(TIM_INT, ASSERT_LINE );
2056         m_reloading = 1;
20632057      }
20642058   }
20652059}
20662060
2067static void gb_timer_increment( running_machine &machine )
2061void gb_state::gb_timer_increment()
20682062{
2069   gb_state *state = machine.driver_data<gb_state>();
2070   gb_timer_check_irq(machine);
2063   gb_timer_check_irq();
20712064
2072   state->TIMECNT += 1;
2073   if ( state->TIMECNT == 0 )
2065   TIMECNT += 1;
2066   if ( TIMECNT == 0 )
20742067   {
2075      state->m_triggering_irq = 1;
2068      m_triggering_irq = 1;
20762069   }
20772070}
20782071
2079void gb_timer_callback(lr35902_cpu_device *device, int cycles)
2072WRITE8_MEMBER( gb_state::gb_timer_callback )
20802073{
2081   gb_state *state = device->machine().driver_data<gb_state>();
2082   UINT16 old_gb_divcount = state->m_divcount;
2083   state->m_divcount += cycles;
2074   UINT16 old_gb_divcount = m_divcount;
2075   m_divcount += data;
20842076
2085   gb_timer_check_irq(device->machine());
2077   gb_timer_check_irq();
20862078
2087   if ( state->TIMEFRQ & 0x04 )
2079   if ( TIMEFRQ & 0x04 )
20882080   {
2089      UINT16 old_count = old_gb_divcount >> state->m_shift;
2090      UINT16 new_count = state->m_divcount >> state->m_shift;
2091      if ( cycles > state->m_shift_cycles )
2081      UINT16 old_count = old_gb_divcount >> m_shift;
2082      UINT16 new_count = m_divcount >> m_shift;
2083      if ( data > m_shift_cycles )
20922084      {
2093         gb_timer_increment(device->machine());
2085         gb_timer_increment();
20942086         old_count++;
20952087      }
20962088      if ( new_count != old_count )
20972089      {
2098         gb_timer_increment(device->machine());
2090         gb_timer_increment();
20992091      }
2100      if ( new_count << state->m_shift < state->m_divcount )
2092      if ( new_count << m_shift < m_divcount )
21012093      {
2102         gb_timer_check_irq(device->machine());
2094         gb_timer_check_irq();
21032095      }
21042096   }
21052097}
r20640r20641
21122104         machine().device<lr35902_cpu_device>(":maincpu")->set_speed( data );
21132105         return;
21142106      case 0x10:  /* BFF - Bios disable */
2115         gb_rom16_0000( machine(), m_ROMMap[m_ROMBank00] );
2107         gb_rom16_0000( m_ROMMap[m_ROMBank00] );
21162108         return;
21172109      case 0x16:  /* RP - Infrared port */
21182110         break;
r20640r20641
21202112         m_GBC_RAMBank = data & 0x7;
21212113         if ( ! m_GBC_RAMBank )
21222114            m_GBC_RAMBank = 1;
2123         membank ("bank3")->set_base (m_GBC_RAMMap[m_GBC_RAMBank]);
2115         m_bank3->set_base(m_GBC_RAMMap[m_GBC_RAMBank]);
21242116         break;
21252117      default:
21262118         break;
r20640r20641
21622154MACHINE_RESET_MEMBER(gb_state,megaduck)
21632155{
21642156   /* We may have to add some more stuff here, if not then it can be merged back into gb */
2165   gb_init(machine());
2157   gb_init();
21662158
2167   gb_video_reset( machine(), GB_VIDEO_DMG );
2159   gb_video_reset( GB_VIDEO_DMG );
21682160}
21692161
21702162/*
r20640r20641
22802272      m_ROMBank = data & m_ROMMask;
22812273
22822274      /* Switch banks */
2283      membank ("bank1")->set_base (m_ROMMap[m_ROMBank]);
2275      m_bank1->set_base(m_ROMMap[m_ROMBank]);
22842276   }
22852277}
22862278
r20640r20641
22912283      m_ROMBank = (data << 1) & m_ROMMask;
22922284
22932285      /* Switch banks */
2294      membank( "bank10" )->set_base( m_ROMMap[m_ROMBank]);
2295      membank( "bank1" )->set_base( m_ROMMap[m_ROMBank + 1]);
2286      m_bank10->set_base( m_ROMMap[m_ROMBank]);
2287      m_bank1->set_base( m_ROMMap[m_ROMBank + 1]);
22962288   }
22972289}
22982290
trunk/src/mess/includes/gb.h
r20640r20641
109109{
110110public:
111111   gb_state(const machine_config &mconfig, device_type type, const char *tag)
112      : driver_device(mconfig, type, tag) { }
112      : driver_device(mconfig, type, tag)
113      , m_maincpu(*this, "maincpu")
114      , m_bank1(*this, "bank1")
115      , m_bank2(*this, "bank2")
116      , m_bank3(*this, "bank3")
117      , m_bank4(*this, "bank4")
118      , m_bank5(*this, "bank5")
119      , m_bank6(*this, "bank6")
120      , m_bank10(*this, "bank10")
121      , m_bank11(*this, "bank11")
122      , m_inputs(*this, "INPUTS")
123   { }
113124
114125   UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
115126
r20640r20641
178189   UINT8 m_mmm01_bank;
179190   UINT8 m_mmm01_bank_mask;
180191   gb_lcd_t m_lcd;
181   void (*update_scanline)( running_machine &machine );
192   void (gb_state::*update_scanline) ();
182193
183194   bitmap_ind16 m_bitmap;
184195   DECLARE_WRITE8_MEMBER(gb_rom_bank_select_mbc1);
r20640r20641
255266   TIMER_CALLBACK_MEMBER(gb_video_init_vbl);
256267   TIMER_CALLBACK_MEMBER(gb_lcd_timer_proc);
257268   TIMER_CALLBACK_MEMBER(gbc_lcd_timer_proc);
269   DECLARE_WRITE8_MEMBER(gb_timer_callback);
270
271protected:
272   required_device<lr35902_cpu_device> m_maincpu;
273   required_memory_bank m_bank1;   // all
274   optional_memory_bank m_bank2;   // dmg, sgb, cgb
275   optional_memory_bank m_bank3;   // cgb
276   optional_memory_bank m_bank4;   // dmg, sgb, cgb
277   optional_memory_bank m_bank5;   // dmg, sgb, cgb
278   optional_memory_bank m_bank6;   // dmg, sgb, cgb
279   required_memory_bank m_bank10;  // all
280   optional_memory_bank m_bank11;  // dmg, sgb, cgb
281   required_ioport m_inputs;
282
283   void gb_timer_increment();
284   void gb_timer_check_irq();
285   void gb_init_regs();
286   void gb_rom16_0000( UINT8 *addr );
287   void gb_rom16_4000( UINT8 *addr );
288   void gb_rom8_4000( UINT8 *addr );
289   void gb_rom8_6000( UINT8 *addr );
290   void gb_init();
291   void gb_set_mbc1_banks();
292   void gb_set_mbc1_kor_banks();
293   void gb_select_sprites();
294   void gb_update_sprites();
295   void gb_update_scanline();
296   void sgb_update_sprites();
297   void sgb_refresh_border();
298   void sgb_update_scanline();
299   void cgb_update_sprites();
300   void cgb_update_scanline();
301   void gb_video_reset( int mode );
302   void gbc_hdma(UINT16 length);
303   void gb_increment_scanline();
304   void gb_lcd_switch_on();
258305};
259306
260307
r20640r20641
262309
263310DEVICE_START(gb_cart);
264311DEVICE_IMAGE_LOAD(gb_cart);
265void gb_timer_callback(lr35902_cpu_device *device, int cycles);
266312
267313
268
269
270314/* -- Super Game Boy specific -- */
271315#define SGB_BORDER_PAL_OFFSET   64  /* Border colours stored from pal 4-7   */
272316#define SGB_XOFFSET             48  /* GB screen starts at column 48        */
r20640r20641
288332   GB_VIDEO_CGB
289333};
290334
291void gb_video_reset( running_machine &machine, int mode );
292UINT8 *gb_get_vram_ptr(running_machine &machine);
293335
294
295336#endif /* GB_H_ */
trunk/src/mess/video/gb.c
r20640r20641
1818#include "cpu/lr35902/lr35902.h"
1919#include "includes/gb.h"
2020
21#define LCDCONT     state->m_lcd.gb_vid_regs[0x00]  /* LCD control register                       */
22#define LCDSTAT     state->m_lcd.gb_vid_regs[0x01]  /* LCD status register                        */
23#define SCROLLY     state->m_lcd.gb_vid_regs[0x02]  /* Starting Y position of the background      */
24#define SCROLLX     state->m_lcd.gb_vid_regs[0x03]  /* Starting X position of the background      */
25#define CURLINE     state->m_lcd.gb_vid_regs[0x04]  /* Current screen line being scanned          */
26#define CMPLINE     state->m_lcd.gb_vid_regs[0x05]  /* Gen. int. when scan reaches this line      */
27#define BGRDPAL     state->m_lcd.gb_vid_regs[0x07]  /* Background palette                         */
28#define SPR0PAL     state->m_lcd.gb_vid_regs[0x08]  /* Sprite palette #0                          */
29#define SPR1PAL     state->m_lcd.gb_vid_regs[0x09]  /* Sprite palette #1                          */
30#define WNDPOSY     state->m_lcd.gb_vid_regs[0x0A]  /* Window Y position                          */
31#define WNDPOSX     state->m_lcd.gb_vid_regs[0x0B]  /* Window X position                          */
32#define KEY1        state->m_lcd.gb_vid_regs[0x0D]  /* Prepare speed switch                       */
33#define HDMA1       state->m_lcd.gb_vid_regs[0x11]  /* HDMA source high byte                      */
34#define HDMA2       state->m_lcd.gb_vid_regs[0x12]  /* HDMA source low byte                       */
35#define HDMA3       state->m_lcd.gb_vid_regs[0x13]  /* HDMA destination high byte                 */
36#define HDMA4       state->m_lcd.gb_vid_regs[0x14]  /* HDMA destination low byte                  */
37#define HDMA5       state->m_lcd.gb_vid_regs[0x15]  /* HDMA length/mode/start                     */
38#define GBCBCPS     state->m_lcd.gb_vid_regs[0x28]  /* Backgound palette spec                     */
39#define GBCBCPD     state->m_lcd.gb_vid_regs[0x29]  /* Backgound palette data                     */
40#define GBCOCPS     state->m_lcd.gb_vid_regs[0x2A]  /* Object palette spec                        */
41#define GBCOCPD     state->m_lcd.gb_vid_regs[0x2B]  /* Object palette data                        */
21#define LCDCONT     m_lcd.gb_vid_regs[0x00]  /* LCD control register                       */
22#define LCDSTAT     m_lcd.gb_vid_regs[0x01]  /* LCD status register                        */
23#define SCROLLY     m_lcd.gb_vid_regs[0x02]  /* Starting Y position of the background      */
24#define SCROLLX     m_lcd.gb_vid_regs[0x03]  /* Starting X position of the background      */
25#define CURLINE     m_lcd.gb_vid_regs[0x04]  /* Current screen line being scanned          */
26#define CMPLINE     m_lcd.gb_vid_regs[0x05]  /* Gen. int. when scan reaches this line      */
27#define BGRDPAL     m_lcd.gb_vid_regs[0x07]  /* Background palette                         */
28#define SPR0PAL     m_lcd.gb_vid_regs[0x08]  /* Sprite palette #0                          */
29#define SPR1PAL     m_lcd.gb_vid_regs[0x09]  /* Sprite palette #1                          */
30#define WNDPOSY     m_lcd.gb_vid_regs[0x0A]  /* Window Y position                          */
31#define WNDPOSX     m_lcd.gb_vid_regs[0x0B]  /* Window X position                          */
32#define KEY1        m_lcd.gb_vid_regs[0x0D]  /* Prepare speed switch                       */
33#define HDMA1       m_lcd.gb_vid_regs[0x11]  /* HDMA source high byte                      */
34#define HDMA2       m_lcd.gb_vid_regs[0x12]  /* HDMA source low byte                       */
35#define HDMA3       m_lcd.gb_vid_regs[0x13]  /* HDMA destination high byte                 */
36#define HDMA4       m_lcd.gb_vid_regs[0x14]  /* HDMA destination low byte                  */
37#define HDMA5       m_lcd.gb_vid_regs[0x15]  /* HDMA length/mode/start                     */
38#define GBCBCPS     m_lcd.gb_vid_regs[0x28]  /* Backgound palette spec                     */
39#define GBCBCPD     m_lcd.gb_vid_regs[0x29]  /* Backgound palette data                     */
40#define GBCOCPS     m_lcd.gb_vid_regs[0x2A]  /* Object palette spec                        */
41#define GBCOCPD     m_lcd.gb_vid_regs[0x2B]  /* Object palette data                        */
4242
4343enum {
4444   UNLOCKED=0,
r20640r20641
4646};
4747
4848
49/* Prototypes */
50
51
52static void gb_lcd_switch_on( running_machine &machine );
53
5449static const unsigned char palette[] =
5550{
5651/* Simple black and white palette */
r20640r20641
156151  Select which sprites should be drawn for the current scanline and return the
157152  number of sprites selected.
158153 */
159static void gb_select_sprites( gb_state *state )
154void gb_state::gb_select_sprites()
160155{
161156   int i, /*yindex,*/ line, height;
162   UINT8   *oam = state->m_lcd.gb_oam->base() + 39 * 4;
157   UINT8   *oam = m_lcd.gb_oam->base() + 39 * 4;
163158
164   state->m_lcd.sprCount = 0;
159   m_lcd.sprCount = 0;
165160
166161   /* If video hardware is enabled and sprites are enabled */
167162   if ( ( LCDCONT & 0x80 ) && ( LCDCONT & 0x02 ) )
r20640r20641
176171         height = 8;
177172      }
178173
179      //yindex = state->m_lcd.current_line;
180      line = state->m_lcd.current_line + 16;
174      //yindex = m_lcd.current_line;
175      line = m_lcd.current_line + 16;
181176
182177      for( i = 39; i >= 0; i-- )
183178      {
r20640r20641
185180         {
186181            /* We limit the sprite count to max 10 here;
187182               proper games should not exceed this... */
188            if ( state->m_lcd.sprCount < 10 )
183            if ( m_lcd.sprCount < 10 )
189184            {
190               state->m_lcd.sprite[state->m_lcd.sprCount] = i;
191               state->m_lcd.sprCount++;
185               m_lcd.sprite[m_lcd.sprCount] = i;
186               m_lcd.sprCount++;
192187            }
193188         }
194189         oam -= 4;
r20640r20641
196191   }
197192}
198193
199INLINE void gb_update_sprites ( running_machine &machine )
194void gb_state::gb_update_sprites()
200195{
201   gb_state *state = machine.driver_data<gb_state>();
202   bitmap_ind16 &bitmap = state->m_bitmap;
196   bitmap_ind16 &bitmap = m_bitmap;
203197   UINT8 height, tilemask, line, *oam, *vram;
204198   int i, yindex;
205199
r20640r20641
214208      tilemask = 0xFF;
215209   }
216210
217   yindex = state->m_lcd.current_line;
218   line = state->m_lcd.current_line + 16;
211   yindex = m_lcd.current_line;
212   line = m_lcd.current_line + 16;
219213
220   oam = state->m_lcd.gb_oam->base() + 39 * 4;
221   vram = state->m_lcd.gb_vram->base();
214   oam = m_lcd.gb_oam->base() + 39 * 4;
215   vram = m_lcd.gb_vram->base();
222216   for (i = 39; i >= 0; i--)
223217   {
224218      /* if sprite is on current line && x-coordinate && x-coordinate is < 168 */
r20640r20641
228222         UINT8 bit, *spal;
229223         int xindex, adr;
230224
231         spal = (oam[3] & 0x10) ? state->m_lcd.gb_spal1 : state->m_lcd.gb_spal0;
225         spal = (oam[3] & 0x10) ? m_lcd.gb_spal1 : m_lcd.gb_spal0;
232226         xindex = oam[1] - 8;
233227         if (oam[3] & 0x40)         /* flip y ? */
234228         {
r20640r20641
246240            for (bit = 0; bit < 8; bit++, xindex++)
247241            {
248242               register int colour = ((data & 0x0100) ? 2 : 0) | ((data & 0x0001) ? 1 : 0);
249               if (colour && !state->m_lcd.bg_zbuf[xindex] && xindex >= 0 && xindex < 160)
243               if (colour && !m_lcd.bg_zbuf[xindex] && xindex >= 0 && xindex < 160)
250244                  gb_plot_pixel(bitmap, xindex, yindex, spal[colour]);
251245               data >>= 1;
252246            }
r20640r20641
264258            for (bit = 0; bit < 8 && xindex < 160; bit++, xindex++)
265259            {
266260               register int colour = ((data & 0x8000) ? 2 : 0) | ((data & 0x0080) ? 1 : 0);
267               if (colour && !state->m_lcd.bg_zbuf[xindex] && xindex >= 0 && xindex < 160)
261               if (colour && !m_lcd.bg_zbuf[xindex] && xindex >= 0 && xindex < 160)
268262                  gb_plot_pixel(bitmap, xindex, yindex, spal[colour]);
269263               data <<= 1;
270264            }
r20640r20641
284278   }
285279}
286280
287static void gb_update_scanline( running_machine &machine )
281void gb_state::gb_update_scanline()
288282{
289   gb_state *state = machine.driver_data<gb_state>();
290   bitmap_ind16 &bitmap = state->m_bitmap;
283   bitmap_ind16 &bitmap = m_bitmap;
291284
292285   g_profiler.start(PROFILER_VIDEO);
293286
r20640r20641
295288   if ( ( LCDSTAT & 0x03 ) == 0x03 )
296289   {
297290      /* Calculate number of pixels to render based on time still left on the timer */
298      UINT32 cycles_to_go = machine.device<cpu_device>("maincpu")->attotime_to_cycles(state->m_lcd.lcd_timer ->remaining( ) );
291      UINT32 cycles_to_go = m_maincpu->attotime_to_cycles(m_lcd.lcd_timer->remaining( ) );
299292      int l = 0;
300293
301      if ( state->m_lcd.start_x < 0 )
294      if ( m_lcd.start_x < 0 )
302295      {
303296         /* Window is enabled if the hardware says so AND the current scanline is
304297          * within the window AND the window X coordinate is <=166 */
305         state->m_lcd.layer[1].enabled = ( ( LCDCONT & 0x20 ) && ( state->m_lcd.current_line >= WNDPOSY ) && ( WNDPOSX <= 166 ) ) ? 1 : 0;
298         m_lcd.layer[1].enabled = ( ( LCDCONT & 0x20 ) && ( m_lcd.current_line >= WNDPOSY ) && ( WNDPOSX <= 166 ) ) ? 1 : 0;
306299
307300         /* BG is enabled if the hardware says so AND (window_off OR (window_on
308301         * AND window's X position is >=7 ) ) */
309         state->m_lcd.layer[0].enabled = ( ( LCDCONT & 0x01 ) && ( ( ! state->m_lcd.layer[1].enabled ) || ( state->m_lcd.layer[1].enabled && ( WNDPOSX >= 7 ) ) ) ) ? 1 : 0;
302         m_lcd.layer[0].enabled = ( ( LCDCONT & 0x01 ) && ( ( ! m_lcd.layer[1].enabled ) || ( m_lcd.layer[1].enabled && ( WNDPOSX >= 7 ) ) ) ) ? 1 : 0;
310303
311         if ( state->m_lcd.layer[0].enabled )
304         if ( m_lcd.layer[0].enabled )
312305         {
313            state->m_lcd.layer[0].bgline = ( SCROLLY + state->m_lcd.current_line ) & 0xFF;
314            state->m_lcd.layer[0].bg_map = state->m_lcd.gb_bgdtab;
315            state->m_lcd.layer[0].bg_tiles = state->m_lcd.gb_chrgen;
316            state->m_lcd.layer[0].xindex = SCROLLX >> 3;
317            state->m_lcd.layer[0].xshift = SCROLLX & 7;
318            state->m_lcd.layer[0].xstart = 0;
319            state->m_lcd.layer[0].xend = 160;
306            m_lcd.layer[0].bgline = ( SCROLLY + m_lcd.current_line ) & 0xFF;
307            m_lcd.layer[0].bg_map = m_lcd.gb_bgdtab;
308            m_lcd.layer[0].bg_tiles = m_lcd.gb_chrgen;
309            m_lcd.layer[0].xindex = SCROLLX >> 3;
310            m_lcd.layer[0].xshift = SCROLLX & 7;
311            m_lcd.layer[0].xstart = 0;
312            m_lcd.layer[0].xend = 160;
320313         }
321314
322         if ( state->m_lcd.layer[1].enabled )
315         if ( m_lcd.layer[1].enabled )
323316         {
324317            int xpos;
325318
r20640r20641
327320            if ( xpos < 0 )
328321               xpos = 0;
329322
330            state->m_lcd.layer[1].bgline = state->m_lcd.window_lines_drawn;
331            state->m_lcd.layer[1].bg_map = state->m_lcd.gb_wndtab;
332            state->m_lcd.layer[1].bg_tiles = state->m_lcd.gb_chrgen;
333            state->m_lcd.layer[1].xindex = 0;
334            state->m_lcd.layer[1].xshift = 0;
335            state->m_lcd.layer[1].xstart = xpos;
336            state->m_lcd.layer[1].xend = 160;
337            state->m_lcd.layer[0].xend = xpos;
323            m_lcd.layer[1].bgline = m_lcd.window_lines_drawn;
324            m_lcd.layer[1].bg_map = m_lcd.gb_wndtab;
325            m_lcd.layer[1].bg_tiles = m_lcd.gb_chrgen;
326            m_lcd.layer[1].xindex = 0;
327            m_lcd.layer[1].xshift = 0;
328            m_lcd.layer[1].xstart = xpos;
329            m_lcd.layer[1].xend = 160;
330            m_lcd.layer[0].xend = xpos;
338331         }
339         state->m_lcd.start_x = 0;
332         m_lcd.start_x = 0;
340333      }
341334
342335      if ( cycles_to_go < 160 )
343336      {
344         state->m_lcd.end_x = MIN(160 - cycles_to_go,160);
337         m_lcd.end_x = MIN(160 - cycles_to_go,160);
345338         /* Draw empty pixels when the background is disabled */
346339         if ( ! ( LCDCONT & 0x01 ) )
347340         {
348            rectangle r(state->m_lcd.start_x, state->m_lcd.end_x - 1, state->m_lcd.current_line, state->m_lcd.current_line);
349            bitmap.fill(state->m_lcd.gb_bpal[0], r );
341            rectangle r(m_lcd.start_x, m_lcd.end_x - 1, m_lcd.current_line, m_lcd.current_line);
342            bitmap.fill(m_lcd.gb_bpal[0], r );
350343         }
351344         while ( l < 2 )
352345         {
r20640r20641
354347            UINT16  data;
355348            int i, tile_index;
356349
357            if ( ! state->m_lcd.layer[l].enabled )
350            if ( ! m_lcd.layer[l].enabled )
358351            {
359352               l++;
360353               continue;
361354            }
362            map = state->m_lcd.layer[l].bg_map + ( ( state->m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
363            tiles = state->m_lcd.layer[l].bg_tiles + ( ( state->m_lcd.layer[l].bgline & 7 ) << 1 );
364            xindex = state->m_lcd.start_x;
365            if ( xindex < state->m_lcd.layer[l].xstart )
366               xindex = state->m_lcd.layer[l].xstart;
367            i = state->m_lcd.end_x;
368            if ( i > state->m_lcd.layer[l].xend )
369               i = state->m_lcd.layer[l].xend;
355            map = m_lcd.layer[l].bg_map + ( ( m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
356            tiles = m_lcd.layer[l].bg_tiles + ( ( m_lcd.layer[l].bgline & 7 ) << 1 );
357            xindex = m_lcd.start_x;
358            if ( xindex < m_lcd.layer[l].xstart )
359               xindex = m_lcd.layer[l].xstart;
360            i = m_lcd.end_x;
361            if ( i > m_lcd.layer[l].xend )
362               i = m_lcd.layer[l].xend;
370363            i = i - xindex;
371364
372            tile_index = ( map[ state->m_lcd.layer[l].xindex ] ^ state->m_lcd.gb_tile_no_mod ) * 16;
365            tile_index = ( map[ m_lcd.layer[l].xindex ] ^ m_lcd.gb_tile_no_mod ) * 16;
373366            data = tiles[ tile_index ] | ( tiles[ tile_index+1 ] << 8 );
374            data <<= state->m_lcd.layer[l].xshift;
367            data <<= m_lcd.layer[l].xshift;
375368
376369            while ( i > 0 )
377370            {
378               while ( ( state->m_lcd.layer[l].xshift < 8 ) && i )
371               while ( ( m_lcd.layer[l].xshift < 8 ) && i )
379372               {
380373                  register int colour = ( ( data & 0x8000 ) ? 2 : 0 ) | ( ( data & 0x0080 ) ? 1 : 0 );
381                  gb_plot_pixel( bitmap, xindex, state->m_lcd.current_line, state->m_lcd.gb_bpal[ colour ] );
382                  state->m_lcd.bg_zbuf[ xindex ] = colour;
374                  gb_plot_pixel( bitmap, xindex, m_lcd.current_line, m_lcd.gb_bpal[ colour ] );
375                  m_lcd.bg_zbuf[ xindex ] = colour;
383376                  xindex++;
384377                  data <<= 1;
385                  state->m_lcd.layer[l].xshift++;
378                  m_lcd.layer[l].xshift++;
386379                  i--;
387380               }
388               if ( state->m_lcd.layer[l].xshift == 8 )
381               if ( m_lcd.layer[l].xshift == 8 )
389382               {
390383                  /* Take possible changes to SCROLLY into account */
391384                  if ( l == 0 )
392385                  {
393                     state->m_lcd.layer[0].bgline = ( SCROLLY + state->m_lcd.current_line ) & 0xFF;
394                     map = state->m_lcd.layer[l].bg_map + ( ( state->m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
395                     tiles = state->m_lcd.layer[l].bg_tiles + ( ( state->m_lcd.layer[l].bgline & 7 ) << 1 );
386                     m_lcd.layer[0].bgline = ( SCROLLY + m_lcd.current_line ) & 0xFF;
387                     map = m_lcd.layer[l].bg_map + ( ( m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
388                     tiles = m_lcd.layer[l].bg_tiles + ( ( m_lcd.layer[l].bgline & 7 ) << 1 );
396389                  }
397390
398                  state->m_lcd.layer[l].xindex = ( state->m_lcd.layer[l].xindex + 1 ) & 31;
399                  state->m_lcd.layer[l].xshift = 0;
400                  tile_index = ( map[ state->m_lcd.layer[l].xindex ] ^ state->m_lcd.gb_tile_no_mod ) * 16;
391                  m_lcd.layer[l].xindex = ( m_lcd.layer[l].xindex + 1 ) & 31;
392                  m_lcd.layer[l].xshift = 0;
393                  tile_index = ( map[ m_lcd.layer[l].xindex ] ^ m_lcd.gb_tile_no_mod ) * 16;
401394                  data = tiles[ tile_index ] | ( tiles[ tile_index+1 ] << 8 );
402395               }
403396            }
404397            l++;
405398         }
406         if ( state->m_lcd.end_x == 160 && LCDCONT & 0x02 )
399         if ( m_lcd.end_x == 160 && LCDCONT & 0x02 )
407400         {
408            gb_update_sprites(machine);
401            gb_update_sprites();
409402         }
410         state->m_lcd.start_x = state->m_lcd.end_x;
403         m_lcd.start_x = m_lcd.end_x;
411404      }
412405   }
413406   else
r20640r20641
415408      if ( ! ( LCDCONT & 0x80 ) )
416409      {
417410         /* Draw an empty line when LCD is disabled */
418         if ( state->m_lcd.previous_line != state->m_lcd.current_line )
411         if ( m_lcd.previous_line != m_lcd.current_line )
419412         {
420            if ( state->m_lcd.current_line < 144 )
413            if ( m_lcd.current_line < 144 )
421414            {
422               screen_device *screen = machine.first_screen();
415               screen_device *screen = machine().first_screen();
423416               const rectangle &r = screen->visible_area();
424               rectangle r1(r.min_x, r.max_x, state->m_lcd.current_line, state->m_lcd.current_line);
417               rectangle r1(r.min_x, r.max_x, m_lcd.current_line, m_lcd.current_line);
425418               bitmap.fill(0, r1 );
426419            }
427            state->m_lcd.previous_line = state->m_lcd.current_line;
420            m_lcd.previous_line = m_lcd.current_line;
428421         }
429422      }
430423   }
r20640r20641
434427
435428/* --- Super Game Boy Specific --- */
436429
437INLINE void sgb_update_sprites (running_machine &machine)
430void gb_state::sgb_update_sprites()
438431{
439   gb_state *state = machine.driver_data<gb_state>();
440   bitmap_ind16 &bitmap = state->m_bitmap;
432   bitmap_ind16 &bitmap = m_bitmap;
441433   UINT8 height, tilemask, line, *oam, *vram, pal;
442434   INT16 i, yindex;
443435
r20640r20641
453445   }
454446
455447   /* Offset to center of screen */
456   yindex = state->m_lcd.current_line + SGB_YOFFSET;
457   line = state->m_lcd.current_line + 16;
448   yindex = m_lcd.current_line + SGB_YOFFSET;
449   line = m_lcd.current_line + 16;
458450
459   oam = state->m_lcd.gb_oam->base() + 39 * 4;
460   vram = state->m_lcd.gb_vram->base();
451   oam = m_lcd.gb_oam->base() + 39 * 4;
452   vram = m_lcd.gb_vram->base();
461453   for (i = 39; i >= 0; i--)
462454   {
463455      /* if sprite is on current line && x-coordinate && x-coordinate is < 168 */
r20640r20641
468460         INT16 xindex;
469461         int adr;
470462
471         spal = (oam[3] & 0x10) ? state->m_lcd.gb_spal1 : state->m_lcd.gb_spal0;
463         spal = (oam[3] & 0x10) ? m_lcd.gb_spal1 : m_lcd.gb_spal0;
472464         xindex = oam[1] - 8;
473465         if (oam[3] & 0x40)         /* flip y ? */
474466         {
r20640r20641
481473         data = (vram[adr + 1] << 8) | vram[adr];
482474
483475         /* Find the palette to use */
484         pal = state->m_sgb_pal_map[(xindex >> 3)][((yindex - SGB_YOFFSET) >> 3)] << 2;
476         pal = m_sgb_pal_map[(xindex >> 3)][((yindex - SGB_YOFFSET) >> 3)] << 2;
485477
486478         /* Offset to center of screen */
487479         xindex += SGB_XOFFSET;
r20640r20641
492484            for (bit = 0; bit < 8; bit++, xindex++)
493485            {
494486               register int colour = ((data & 0x0100) ? 2 : 0) | ((data & 0x0001) ? 1 : 0);
495               if ((xindex >= SGB_XOFFSET && xindex < SGB_XOFFSET + 160) && colour && !state->m_lcd.bg_zbuf[xindex - SGB_XOFFSET])
496                  gb_plot_pixel(bitmap, xindex, yindex, state->m_sgb_pal[pal + spal[colour]]);
487               if ((xindex >= SGB_XOFFSET && xindex < SGB_XOFFSET + 160) && colour && !m_lcd.bg_zbuf[xindex - SGB_XOFFSET])
488                  gb_plot_pixel(bitmap, xindex, yindex, m_sgb_pal[pal + spal[colour]]);
497489               data >>= 1;
498490            }
499491            break;
r20640r20641
502494            {
503495               register int colour = ((data & 0x0100) ? 2 : 0) | ((data & 0x0001) ? 1 : 0);
504496               if ((xindex >= SGB_XOFFSET && xindex < SGB_XOFFSET + 160) && colour)
505                  gb_plot_pixel(bitmap, xindex, yindex, state->m_sgb_pal[pal + spal[colour]]);
497                  gb_plot_pixel(bitmap, xindex, yindex, m_sgb_pal[pal + spal[colour]]);
506498               data >>= 1;
507499            }
508500            break;
r20640r20641
510502            for (bit = 0; bit < 8; bit++, xindex++)
511503            {
512504               register int colour = ((data & 0x8000) ? 2 : 0) | ((data & 0x0080) ? 1 : 0);
513               if ((xindex >= SGB_XOFFSET && xindex < SGB_XOFFSET + 160) && colour && !state->m_lcd.bg_zbuf[xindex - SGB_XOFFSET])
514                  gb_plot_pixel(bitmap, xindex, yindex, state->m_sgb_pal[pal + spal[colour]]);
505               if ((xindex >= SGB_XOFFSET && xindex < SGB_XOFFSET + 160) && colour && !m_lcd.bg_zbuf[xindex - SGB_XOFFSET])
506                  gb_plot_pixel(bitmap, xindex, yindex, m_sgb_pal[pal + spal[colour]]);
515507               data <<= 1;
516508            }
517509            break;
r20640r20641
520512            {
521513               register int colour = ((data & 0x8000) ? 2 : 0) | ((data & 0x0080) ? 1 : 0);
522514               if ((xindex >= SGB_XOFFSET && xindex < SGB_XOFFSET + 160) && colour)
523                  gb_plot_pixel(bitmap, xindex, yindex, state->m_sgb_pal[pal + spal[colour]]);
515                  gb_plot_pixel(bitmap, xindex, yindex, m_sgb_pal[pal + spal[colour]]);
524516               data <<= 1;
525517            }
526518            break;
r20640r20641
530522   }
531523}
532524
533static void sgb_refresh_border(running_machine &machine)
525
526void gb_state::sgb_refresh_border()
534527{
535   gb_state *state = machine.driver_data<gb_state>();
536528   UINT16 data, data2;
537529   UINT16 yidx, xidx, xindex;
538530   UINT8 *map, *tiles, *tiles2;
539531   UINT8 pal, i;
540   bitmap_ind16 &bitmap = state->m_bitmap;
532   bitmap_ind16 &bitmap = m_bitmap;
541533
542   map = state->m_sgb_tile_map - 64;
534   map = m_sgb_tile_map - 64;
543535
544536   for( yidx = 0; yidx < 224; yidx++ )
545537   {
r20640r20641
548540      for( xidx = 0; xidx < 64; xidx+=2 )
549541      {
550542         if( map[xidx+1] & 0x80 ) /* Vertical flip */
551            tiles = state->m_sgb_tile_data + ( ( 7 - ( yidx % 8 ) ) << 1 );
543            tiles = m_sgb_tile_data + ( ( 7 - ( yidx % 8 ) ) << 1 );
552544         else /* No vertical flip */
553            tiles = state->m_sgb_tile_data + ( ( yidx % 8 ) << 1 );
545            tiles = m_sgb_tile_data + ( ( yidx % 8 ) << 1 );
554546         tiles2 = tiles + 16;
555547
556548         pal = (map[xidx+1] & 0x1C) >> 2;
r20640r20641
558550            pal = 1;
559551         pal <<= 4;
560552
561         if( state->m_sgb_hack )
553         if( m_sgb_hack )
562554         { /* A few games do weird stuff */
563555            UINT8 tileno = map[xidx];
564556            if( tileno >= 128 ) tileno = ((64 + tileno) % 128) + 128;
r20640r20641
596588            if( !((yidx >= SGB_YOFFSET && yidx < SGB_YOFFSET + 144) &&
597589               (xindex >= SGB_XOFFSET && xindex < SGB_XOFFSET + 160)) )
598590            {
599               gb_plot_pixel(bitmap, xindex, yidx, state->m_sgb_pal[pal + colour]);
591               gb_plot_pixel(bitmap, xindex, yidx, m_sgb_pal[pal + colour]);
600592            }
601593            xindex++;
602594         }
r20640r20641
604596   }
605597}
606598
607static void sgb_update_scanline( running_machine &machine )
599void gb_state::sgb_update_scanline()
608600{
609   gb_state *state = machine.driver_data<gb_state>();
610   bitmap_ind16 &bitmap = state->m_bitmap;
601   bitmap_ind16 &bitmap = m_bitmap;
611602
612603   g_profiler.start(PROFILER_VIDEO);
613604
614605   if ( ( LCDSTAT & 0x03 ) == 0x03 )
615606   {
616607      /* Calcuate number of pixels to render based on time still left on the timer */
617      UINT32 cycles_to_go = machine.device<cpu_device>("maincpu")->attotime_to_cycles(state->m_lcd.lcd_timer ->remaining( ) );
608      UINT32 cycles_to_go = m_maincpu->attotime_to_cycles(m_lcd.lcd_timer->remaining( ) );
618609      int l = 0;
619610
620      if ( state->m_lcd.start_x < 0 )
611      if ( m_lcd.start_x < 0 )
621612      {
622613         /* Window is enabled if the hardware says so AND the current scanline is
623614          * within the window AND the window X coordinate is <=166 */
624         state->m_lcd.layer[1].enabled = ((LCDCONT & 0x20) && state->m_lcd.current_line >= WNDPOSY && WNDPOSX <= 166) ? 1 : 0;
615         m_lcd.layer[1].enabled = ((LCDCONT & 0x20) && m_lcd.current_line >= WNDPOSY && WNDPOSX <= 166) ? 1 : 0;
625616
626617         /* BG is enabled if the hardware says so AND (window_off OR (window_on
627618          * AND window's X position is >=7 ) ) */
628         state->m_lcd.layer[0].enabled = ((LCDCONT & 0x01) && ((!state->m_lcd.layer[1].enabled) || (state->m_lcd.layer[1].enabled && WNDPOSX >= 7))) ? 1 : 0;
619         m_lcd.layer[0].enabled = ((LCDCONT & 0x01) && ((!m_lcd.layer[1].enabled) || (m_lcd.layer[1].enabled && WNDPOSX >= 7))) ? 1 : 0;
629620
630         if ( state->m_lcd.layer[0].enabled )
621         if ( m_lcd.layer[0].enabled )
631622         {
632            state->m_lcd.layer[0].bgline = ( SCROLLY + state->m_lcd.current_line ) & 0xFF;
633            state->m_lcd.layer[0].bg_map = state->m_lcd.gb_bgdtab;
634            state->m_lcd.layer[0].bg_tiles = state->m_lcd.gb_chrgen;
635            state->m_lcd.layer[0].xindex = SCROLLX >> 3;
636            state->m_lcd.layer[0].xshift = SCROLLX & 7;
637            state->m_lcd.layer[0].xstart = 0;
638            state->m_lcd.layer[0].xend = 160;
623            m_lcd.layer[0].bgline = ( SCROLLY + m_lcd.current_line ) & 0xFF;
624            m_lcd.layer[0].bg_map = m_lcd.gb_bgdtab;
625            m_lcd.layer[0].bg_tiles = m_lcd.gb_chrgen;
626            m_lcd.layer[0].xindex = SCROLLX >> 3;
627            m_lcd.layer[0].xshift = SCROLLX & 7;
628            m_lcd.layer[0].xstart = 0;
629            m_lcd.layer[0].xend = 160;
639630         }
640631
641         if ( state->m_lcd.layer[1].enabled )
632         if ( m_lcd.layer[1].enabled )
642633         {
643634            int xpos;
644635
r20640r20641
647638            if (xpos < 0)
648639               xpos = 0;
649640
650            state->m_lcd.layer[1].bgline = state->m_lcd.window_lines_drawn;
651            state->m_lcd.layer[1].bg_map = state->m_lcd.gb_wndtab;
652            state->m_lcd.layer[1].bg_tiles = state->m_lcd.gb_chrgen;
653            state->m_lcd.layer[1].xindex = 0;
654            state->m_lcd.layer[1].xshift = 0;
655            state->m_lcd.layer[1].xstart = xpos;
656            state->m_lcd.layer[1].xend = 160;
657            state->m_lcd.layer[0].xend = xpos;
641            m_lcd.layer[1].bgline = m_lcd.window_lines_drawn;
642            m_lcd.layer[1].bg_map = m_lcd.gb_wndtab;
643            m_lcd.layer[1].bg_tiles = m_lcd.gb_chrgen;
644            m_lcd.layer[1].xindex = 0;
645            m_lcd.layer[1].xshift = 0;
646            m_lcd.layer[1].xstart = xpos;
647            m_lcd.layer[1].xend = 160;
648            m_lcd.layer[0].xend = xpos;
658649         }
659         state->m_lcd.start_x = 0;
650         m_lcd.start_x = 0;
660651      }
661652
662653      if ( cycles_to_go == 0 )
663654      {
664655         /* Does this belong here? or should it be moved to the else block */
665656         /* Handle SGB mask */
666         switch( state->m_sgb_window_mask )
657         switch( m_sgb_window_mask )
667658         {
668659         case 1: /* Freeze screen */
669660            return;
r20640r20641
680671         }
681672
682673         /* Draw the "border" if we're on the first line */
683         if ( state->m_lcd.current_line == 0 )
674         if ( m_lcd.current_line == 0 )
684675         {
685            sgb_refresh_border(machine);
676            sgb_refresh_border();
686677         }
687678      }
688679      if ( cycles_to_go < 160 )
689680      {
690         state->m_lcd.end_x = MIN(160 - cycles_to_go,160);
681         m_lcd.end_x = MIN(160 - cycles_to_go,160);
691682
692683         /* if background or screen disabled clear line */
693684         if ( ! ( LCDCONT & 0x01 ) )
694685         {
695            rectangle r(SGB_XOFFSET, SGB_XOFFSET + 160 - 1, state->m_lcd.current_line + SGB_YOFFSET, state->m_lcd.current_line + SGB_YOFFSET);
686            rectangle r(SGB_XOFFSET, SGB_XOFFSET + 160 - 1, m_lcd.current_line + SGB_YOFFSET, m_lcd.current_line + SGB_YOFFSET);
696687            bitmap.fill(0, r );
697688         }
698689         while( l < 2 )
r20640r20641
701692            UINT16  data;
702693            int i, tile_index;
703694
704            if ( ! state->m_lcd.layer[l].enabled )
695            if ( ! m_lcd.layer[l].enabled )
705696            {
706697               l++;
707698               continue;
708699            }
709            map = state->m_lcd.layer[l].bg_map + ( ( state->m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
710            tiles = state->m_lcd.layer[l].bg_tiles + ( ( state->m_lcd.layer[l].bgline & 7 ) << 1 );
711            xindex = state->m_lcd.start_x;
712            if ( xindex < state->m_lcd.layer[l].xstart )
713               xindex = state->m_lcd.layer[l].xstart;
714            i = state->m_lcd.end_x;
715            if ( i > state->m_lcd.layer[l].xend )
716               i = state->m_lcd.layer[l].xend;
700            map = m_lcd.layer[l].bg_map + ( ( m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
701            tiles = m_lcd.layer[l].bg_tiles + ( ( m_lcd.layer[l].bgline & 7 ) << 1 );
702            xindex = m_lcd.start_x;
703            if ( xindex < m_lcd.layer[l].xstart )
704               xindex = m_lcd.layer[l].xstart;
705            i = m_lcd.end_x;
706            if ( i > m_lcd.layer[l].xend )
707               i = m_lcd.layer[l].xend;
717708            i = i - xindex;
718709
719            tile_index = (map[state->m_lcd.layer[l].xindex] ^ state->m_lcd.gb_tile_no_mod) * 16;
710            tile_index = (map[m_lcd.layer[l].xindex] ^ m_lcd.gb_tile_no_mod) * 16;
720711            data = tiles[tile_index] | ( tiles[tile_index + 1] << 8 );
721            data <<= state->m_lcd.layer[l].xshift;
712            data <<= m_lcd.layer[l].xshift;
722713
723714            /* Figure out which palette we're using */
724            sgb_palette = state->m_sgb_pal_map[ ( state->m_lcd.end_x - i ) >> 3 ][ state->m_lcd.current_line >> 3 ] << 2;
715            sgb_palette = m_sgb_pal_map[ ( m_lcd.end_x - i ) >> 3 ][ m_lcd.current_line >> 3 ] << 2;
725716
726717            while( i > 0 )
727718            {
728               while( ( state->m_lcd.layer[l].xshift < 8 ) && i )
719               while( ( m_lcd.layer[l].xshift < 8 ) && i )
729720               {
730721                  register int colour = ( ( data & 0x8000 ) ? 2 : 0 ) | ( ( data & 0x0080 ) ? 1 : 0 );
731                  gb_plot_pixel( bitmap, xindex + SGB_XOFFSET, state->m_lcd.current_line + SGB_YOFFSET, state->m_sgb_pal[ sgb_palette + state->m_lcd.gb_bpal[colour]] );
732                  state->m_lcd.bg_zbuf[xindex] = colour;
722                  gb_plot_pixel( bitmap, xindex + SGB_XOFFSET, m_lcd.current_line + SGB_YOFFSET, m_sgb_pal[ sgb_palette + m_lcd.gb_bpal[colour]] );
723                  m_lcd.bg_zbuf[xindex] = colour;
733724                  xindex++;
734725                  data <<= 1;
735                  state->m_lcd.layer[l].xshift++;
726                  m_lcd.layer[l].xshift++;
736727                  i--;
737728               }
738               if ( state->m_lcd.layer[l].xshift == 8 )
729               if ( m_lcd.layer[l].xshift == 8 )
739730               {
740731                  /* Take possible changes to SCROLLY into account */
741732                  if ( l == 0 )
742733                  {
743                     state->m_lcd.layer[0].bgline = ( SCROLLY + state->m_lcd.current_line ) & 0xFF;
744                     map = state->m_lcd.layer[l].bg_map + ( ( state->m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
745                     tiles = state->m_lcd.layer[l].bg_tiles + ( ( state->m_lcd.layer[l].bgline & 7 ) << 1 );
734                     m_lcd.layer[0].bgline = ( SCROLLY + m_lcd.current_line ) & 0xFF;
735                     map = m_lcd.layer[l].bg_map + ( ( m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
736                     tiles = m_lcd.layer[l].bg_tiles + ( ( m_lcd.layer[l].bgline & 7 ) << 1 );
746737                  }
747738
748                  state->m_lcd.layer[l].xindex = ( state->m_lcd.layer[l].xindex + 1 ) & 31;
749                  state->m_lcd.layer[l].xshift = 0;
750                  tile_index = ( map[ state->m_lcd.layer[l].xindex ] ^ state->m_lcd.gb_tile_no_mod ) * 16;
739                  m_lcd.layer[l].xindex = ( m_lcd.layer[l].xindex + 1 ) & 31;
740                  m_lcd.layer[l].xshift = 0;
741                  tile_index = ( map[ m_lcd.layer[l].xindex ] ^ m_lcd.gb_tile_no_mod ) * 16;
751742                  data = tiles[ tile_index ] | ( tiles[ tile_index + 1 ] << 8 );
752                  sgb_palette = state->m_sgb_pal_map[ ( state->m_lcd.end_x - i ) >> 3 ][ state->m_lcd.current_line >> 3 ] << 2;
743                  sgb_palette = m_sgb_pal_map[ ( m_lcd.end_x - i ) >> 3 ][ m_lcd.current_line >> 3 ] << 2;
753744               }
754745            }
755746            l++;
756747         }
757         if ( ( state->m_lcd.end_x == 160 ) && ( LCDCONT & 0x02 ) )
748         if ( ( m_lcd.end_x == 160 ) && ( LCDCONT & 0x02 ) )
758749         {
759            sgb_update_sprites(machine);
750            sgb_update_sprites();
760751         }
761         state->m_lcd.start_x = state->m_lcd.end_x;
752         m_lcd.start_x = m_lcd.end_x;
762753      }
763754   }
764755   else
r20640r20641
766757      if ( ! ( LCDCONT * 0x80 ) )
767758      {
768759         /* if screen disabled clear line */
769         if ( state->m_lcd.previous_line != state->m_lcd.current_line )
760         if ( m_lcd.previous_line != m_lcd.current_line )
770761         {
771762            /* Also refresh border here??? */
772            if ( state->m_lcd.current_line < 144 )
763            if ( m_lcd.current_line < 144 )
773764            {
774               rectangle r(SGB_XOFFSET, SGB_XOFFSET + 160 - 1, state->m_lcd.current_line + SGB_YOFFSET, state->m_lcd.current_line + SGB_YOFFSET);
765               rectangle r(SGB_XOFFSET, SGB_XOFFSET + 160 - 1, m_lcd.current_line + SGB_YOFFSET, m_lcd.current_line + SGB_YOFFSET);
775766               bitmap.fill(0, r);
776767            }
777            state->m_lcd.previous_line = state->m_lcd.current_line;
768            m_lcd.previous_line = m_lcd.current_line;
778769         }
779770      }
780771   }
r20640r20641
784775
785776/* --- Game Boy Color Specific --- */
786777
787INLINE void cgb_update_sprites ( running_machine &machine )
778void gb_state::cgb_update_sprites()
788779{
789   gb_state *state = machine.driver_data<gb_state>();
790   bitmap_ind16 &bitmap = state->m_bitmap;
780   bitmap_ind16 &bitmap = m_bitmap;
791781   UINT8 height, tilemask, line, *oam;
792782   int i, xindex, yindex;
793783
r20640r20641
802792      tilemask = 0xFF;
803793   }
804794
805   yindex = state->m_lcd.current_line;
806   line = state->m_lcd.current_line + 16;
795   yindex = m_lcd.current_line;
796   line = m_lcd.current_line + 16;
807797
808   oam = state->m_lcd.gb_oam->base() + 39 * 4;
798   oam = m_lcd.gb_oam->base() + 39 * 4;
809799   for (i = 39; i >= 0; i--)
810800   {
811801      /* if sprite is on current line && x-coordinate && x-coordinate is < 168 */
r20640r20641
815805         UINT8 bit, pal;
816806
817807         /* Handle mono mode for GB games */
818         if( ! state->m_lcd.gbc_mode )
808         if( ! m_lcd.gbc_mode )
819809            pal = (oam[3] & 0x10) ? 4 : 0;
820810         else
821811            pal = ((oam[3] & 0x7) * 4);
r20640r20641
823813         xindex = oam[1] - 8;
824814         if (oam[3] & 0x40)         /* flip y ? */
825815         {
826            data = *((UINT16 *) &state->m_lcd.gb_vram->base()[ ((oam[3] & 0x8)<<10) + (oam[2] & tilemask) * 16 + (height - 1 - line + oam[0]) * 2]);
816            data = *((UINT16 *) &m_lcd.gb_vram->base()[ ((oam[3] & 0x8)<<10) + (oam[2] & tilemask) * 16 + (height - 1 - line + oam[0]) * 2]);
827817         }
828818         else
829819         {
830            data = *((UINT16 *) &state->m_lcd.gb_vram->base()[ ((oam[3] & 0x8)<<10) + (oam[2] & tilemask) * 16 + (line - oam[0]) * 2]);
820            data = *((UINT16 *) &m_lcd.gb_vram->base()[ ((oam[3] & 0x8)<<10) + (oam[2] & tilemask) * 16 + (line - oam[0]) * 2]);
831821         }
832822#ifndef LSB_FIRST
833823         data = (data << 8) | (data >> 8);
r20640r20641
839829            for (bit = 0; bit < 8; bit++, xindex++)
840830            {
841831               register int colour = ((data & 0x0100) ? 2 : 0) | ((data & 0x0001) ? 1 : 0);
842               if (colour && !state->m_lcd.bg_zbuf[xindex] && xindex >= 0 && xindex < 160)
832               if (colour && !m_lcd.bg_zbuf[xindex] && xindex >= 0 && xindex < 160)
843833               {
844                  if ( ! state->m_lcd.gbc_mode )
845                     colour = pal ? state->m_lcd.gb_spal1[colour] : state->m_lcd.gb_spal0[colour];
846                  gb_plot_pixel(bitmap, xindex, yindex, state->m_lcd.cgb_spal[pal + colour]);
834                  if ( ! m_lcd.gbc_mode )
835                     colour = pal ? m_lcd.gb_spal1[colour] : m_lcd.gb_spal0[colour];
836                  gb_plot_pixel(bitmap, xindex, yindex, m_lcd.cgb_spal[pal + colour]);
847837               }
848838               data >>= 1;
849839            }
r20640r20641
852842            for (bit = 0; bit < 8; bit++, xindex++)
853843            {
854844               register int colour = ((data & 0x0100) ? 2 : 0) | ((data & 0x0001) ? 1 : 0);
855               if((state->m_lcd.bg_zbuf[xindex] & 0x80) && (state->m_lcd.bg_zbuf[xindex] & 0x7f) && (LCDCONT & 0x1))
845               if((m_lcd.bg_zbuf[xindex] & 0x80) && (m_lcd.bg_zbuf[xindex] & 0x7f) && (LCDCONT & 0x1))
856846                  colour = 0;
857847               if (colour && xindex >= 0 && xindex < 160)
858848               {
859                  if ( ! state->m_lcd.gbc_mode )
860                     colour = pal ? state->m_lcd.gb_spal1[colour] : state->m_lcd.gb_spal0[colour];
861                  gb_plot_pixel(bitmap, xindex, yindex, state->m_lcd.cgb_spal[pal + colour]);
849                  if ( ! m_lcd.gbc_mode )
850                     colour = pal ? m_lcd.gb_spal1[colour] : m_lcd.gb_spal0[colour];
851                  gb_plot_pixel(bitmap, xindex, yindex, m_lcd.cgb_spal[pal + colour]);
862852               }
863853               data >>= 1;
864854            }
r20640r20641
867857            for (bit = 0; bit < 8; bit++, xindex++)
868858            {
869859               register int colour = ((data & 0x8000) ? 2 : 0) | ((data & 0x0080) ? 1 : 0);
870               if (colour && !state->m_lcd.bg_zbuf[xindex] && xindex >= 0 && xindex < 160)
860               if (colour && !m_lcd.bg_zbuf[xindex] && xindex >= 0 && xindex < 160)
871861               {
872                  if ( ! state->m_lcd.gbc_mode )
873                     colour = pal ? state->m_lcd.gb_spal1[colour] : state->m_lcd.gb_spal0[colour];
874                  gb_plot_pixel(bitmap, xindex, yindex, state->m_lcd.cgb_spal[pal + colour]);
862                  if ( ! m_lcd.gbc_mode )
863                     colour = pal ? m_lcd.gb_spal1[colour] : m_lcd.gb_spal0[colour];
864                  gb_plot_pixel(bitmap, xindex, yindex, m_lcd.cgb_spal[pal + colour]);
875865               }
876866               data <<= 1;
877867            }
r20640r20641
880870            for (bit = 0; bit < 8; bit++, xindex++)
881871            {
882872               register int colour = ((data & 0x8000) ? 2 : 0) | ((data & 0x0080) ? 1 : 0);
883               if((state->m_lcd.bg_zbuf[xindex] & 0x80) && (state->m_lcd.bg_zbuf[xindex] & 0x7f) && (LCDCONT & 0x1))
873               if((m_lcd.bg_zbuf[xindex] & 0x80) && (m_lcd.bg_zbuf[xindex] & 0x7f) && (LCDCONT & 0x1))
884874                  colour = 0;
885875               if (colour && xindex >= 0 && xindex < 160)
886876               {
887                  if ( ! state->m_lcd.gbc_mode )
888                     colour = pal ? state->m_lcd.gb_spal1[colour] : state->m_lcd.gb_spal0[colour];
889                  gb_plot_pixel(bitmap, xindex, yindex, state->m_lcd.cgb_spal[pal + colour]);
877                  if ( ! m_lcd.gbc_mode )
878                     colour = pal ? m_lcd.gb_spal1[colour] : m_lcd.gb_spal0[colour];
879                  gb_plot_pixel(bitmap, xindex, yindex, m_lcd.cgb_spal[pal + colour]);
890880               }
891881               data <<= 1;
892882            }
r20640r20641
897887   }
898888}
899889
900static void cgb_update_scanline ( running_machine &machine )
890void gb_state::cgb_update_scanline()
901891{
902   gb_state *state = machine.driver_data<gb_state>();
903   bitmap_ind16 &bitmap = state->m_bitmap;
892   bitmap_ind16 &bitmap = m_bitmap;
904893
905894   g_profiler.start(PROFILER_VIDEO);
906895
907896   if ( ( LCDSTAT & 0x03 ) == 0x03 )
908897   {
909898      /* Calcuate number of pixels to render based on time still left on the timer */
910      UINT32 cycles_to_go = machine.device<cpu_device>("maincpu")->attotime_to_cycles(state->m_lcd.lcd_timer ->remaining( ) );
899      UINT32 cycles_to_go = m_maincpu->attotime_to_cycles(m_lcd.lcd_timer->remaining( ) );
911900      int l = 0;
912901
913      if ( state->m_lcd.start_x < 0 )
902      if ( m_lcd.start_x < 0 )
914903      {
915904         /* Window is enabled if the hardware says so AND the current scanline is
916905          * within the window AND the window X coordinate is <=166 */
917         state->m_lcd.layer[1].enabled = ( ( LCDCONT & 0x20 ) && ( state->m_lcd.current_line >= WNDPOSY ) && ( WNDPOSX <= 166 ) ) ? 1 : 0;
906         m_lcd.layer[1].enabled = ( ( LCDCONT & 0x20 ) && ( m_lcd.current_line >= WNDPOSY ) && ( WNDPOSX <= 166 ) ) ? 1 : 0;
918907
919908         /* BG is enabled if the hardware says so AND (window_off OR (window_on
920909          * AND window's X position is >=7 ) ) */
921         state->m_lcd.layer[0].enabled = ( ( LCDCONT & 0x01 ) && ( ( ! state->m_lcd.layer[1].enabled ) || ( state->m_lcd.layer[1].enabled && ( WNDPOSX >= 7 ) ) ) ) ? 1 : 0;
910         m_lcd.layer[0].enabled = ( ( LCDCONT & 0x01 ) && ( ( ! m_lcd.layer[1].enabled ) || ( m_lcd.layer[1].enabled && ( WNDPOSX >= 7 ) ) ) ) ? 1 : 0;
922911
923         if ( state->m_lcd.layer[0].enabled )
912         if ( m_lcd.layer[0].enabled )
924913         {
925            state->m_lcd.layer[0].bgline = ( SCROLLY + state->m_lcd.current_line ) & 0xFF;
926            state->m_lcd.layer[0].bg_map = state->m_lcd.gb_bgdtab;
927            state->m_lcd.layer[0].gbc_map = state->m_lcd.gbc_bgdtab;
928            state->m_lcd.layer[0].xindex = SCROLLX >> 3;
929            state->m_lcd.layer[0].xshift = SCROLLX & 7;
930            state->m_lcd.layer[0].xstart = 0;
931            state->m_lcd.layer[0].xend = 160;
914            m_lcd.layer[0].bgline = ( SCROLLY + m_lcd.current_line ) & 0xFF;
915            m_lcd.layer[0].bg_map = m_lcd.gb_bgdtab;
916            m_lcd.layer[0].gbc_map = m_lcd.gbc_bgdtab;
917            m_lcd.layer[0].xindex = SCROLLX >> 3;
918            m_lcd.layer[0].xshift = SCROLLX & 7;
919            m_lcd.layer[0].xstart = 0;
920            m_lcd.layer[0].xend = 160;
932921         }
933922
934         if ( state->m_lcd.layer[1].enabled )
923         if ( m_lcd.layer[1].enabled )
935924         {
936925            int xpos;
937926
r20640r20641
940929            if (xpos < 0)
941930               xpos = 0;
942931
943            state->m_lcd.layer[1].bgline = state->m_lcd.window_lines_drawn;
944            state->m_lcd.layer[1].bg_map = state->m_lcd.gb_wndtab;
945            state->m_lcd.layer[1].gbc_map = state->m_lcd.gbc_wndtab;
946            state->m_lcd.layer[1].xindex = 0;
947            state->m_lcd.layer[1].xshift = 0;
948            state->m_lcd.layer[1].xstart = xpos;
949            state->m_lcd.layer[1].xend = 160;
950            state->m_lcd.layer[0].xend = xpos;
932            m_lcd.layer[1].bgline = m_lcd.window_lines_drawn;
933            m_lcd.layer[1].bg_map = m_lcd.gb_wndtab;
934            m_lcd.layer[1].gbc_map = m_lcd.gbc_wndtab;
935            m_lcd.layer[1].xindex = 0;
936            m_lcd.layer[1].xshift = 0;
937            m_lcd.layer[1].xstart = xpos;
938            m_lcd.layer[1].xend = 160;
939            m_lcd.layer[0].xend = xpos;
951940         }
952         state->m_lcd.start_x = 0;
941         m_lcd.start_x = 0;
953942      }
954943
955944      if ( cycles_to_go < 160 )
956945      {
957         state->m_lcd.end_x = MIN(160 - cycles_to_go,160);
946         m_lcd.end_x = MIN(160 - cycles_to_go,160);
958947         /* Draw empty line when the background is disabled */
959948         if ( ! ( LCDCONT & 0x01 ) )
960949         {
961            rectangle r(state->m_lcd.start_x, state->m_lcd.end_x - 1, state->m_lcd.current_line, state->m_lcd.current_line);
962            bitmap.fill(( ! state->m_lcd.gbc_mode ) ? 0 : 32767 , r);
950            rectangle r(m_lcd.start_x, m_lcd.end_x - 1, m_lcd.current_line, m_lcd.current_line);
951            bitmap.fill(( ! m_lcd.gbc_mode ) ? 0 : 32767 , r);
963952         }
964953         while ( l < 2 )
965954         {
r20640r20641
967956            UINT16  data;
968957            int i, tile_index;
969958
970            if ( ! state->m_lcd.layer[l].enabled )
959            if ( ! m_lcd.layer[l].enabled )
971960            {
972961               l++;
973962               continue;
974963            }
975            map = state->m_lcd.layer[l].bg_map + ( ( state->m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
976            gbcmap = state->m_lcd.layer[l].gbc_map + ( ( state->m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
977            tiles = ( gbcmap[ state->m_lcd.layer[l].xindex ] & 0x08 ) ? state->m_lcd.gbc_chrgen : state->m_lcd.gb_chrgen;
964            map = m_lcd.layer[l].bg_map + ( ( m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
965            gbcmap = m_lcd.layer[l].gbc_map + ( ( m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
966            tiles = ( gbcmap[ m_lcd.layer[l].xindex ] & 0x08 ) ? m_lcd.gbc_chrgen : m_lcd.gb_chrgen;
978967
979968            /* Check for vertical flip */
980            if ( gbcmap[ state->m_lcd.layer[l].xindex ] & 0x40 )
969            if ( gbcmap[ m_lcd.layer[l].xindex ] & 0x40 )
981970            {
982               tiles += ( ( 7 - ( state->m_lcd.layer[l].bgline & 0x07 ) ) << 1 );
971               tiles += ( ( 7 - ( m_lcd.layer[l].bgline & 0x07 ) ) << 1 );
983972            }
984973            else
985974            {
986               tiles += ( ( state->m_lcd.layer[l].bgline & 0x07 ) << 1 );
975               tiles += ( ( m_lcd.layer[l].bgline & 0x07 ) << 1 );
987976            }
988            xindex = state->m_lcd.start_x;
989            if ( xindex < state->m_lcd.layer[l].xstart )
990               xindex = state->m_lcd.layer[l].xstart;
991            i = state->m_lcd.end_x;
992            if ( i > state->m_lcd.layer[l].xend )
993               i = state->m_lcd.layer[l].xend;
977            xindex = m_lcd.start_x;
978            if ( xindex < m_lcd.layer[l].xstart )
979               xindex = m_lcd.layer[l].xstart;
980            i = m_lcd.end_x;
981            if ( i > m_lcd.layer[l].xend )
982               i = m_lcd.layer[l].xend;
994983            i = i - xindex;
995984
996            tile_index = ( map[ state->m_lcd.layer[l].xindex ] ^ state->m_lcd.gb_tile_no_mod ) * 16;
985            tile_index = ( map[ m_lcd.layer[l].xindex ] ^ m_lcd.gb_tile_no_mod ) * 16;
997986            data = tiles[ tile_index ] | ( tiles[ tile_index + 1 ] << 8 );
998987            /* Check for horinzontal flip */
999            if ( gbcmap[ state->m_lcd.layer[l].xindex ] & 0x20 )
988            if ( gbcmap[ m_lcd.layer[l].xindex ] & 0x20 )
1000989            {
1001               data >>= state->m_lcd.layer[l].xshift;
990               data >>= m_lcd.layer[l].xshift;
1002991            }
1003992            else
1004993            {
1005               data <<= state->m_lcd.layer[l].xshift;
994               data <<= m_lcd.layer[l].xshift;
1006995            }
1007996
1008997            while ( i > 0 )
1009998            {
1010               while ( ( state->m_lcd.layer[l].xshift < 8 ) && i )
999               while ( ( m_lcd.layer[l].xshift < 8 ) && i )
10111000               {
10121001                  int colour;
10131002                  /* Check for horinzontal flip */
1014                  if ( gbcmap[ state->m_lcd.layer[l].xindex ] & 0x20 )
1003                  if ( gbcmap[ m_lcd.layer[l].xindex ] & 0x20 )
10151004                  {
10161005                     colour = ( ( data & 0x0100 ) ? 2 : 0 ) | ( ( data & 0x0001 ) ? 1 : 0 );
10171006                     data >>= 1;
r20640r20641
10211010                     colour = ( ( data & 0x8000 ) ? 2 : 0 ) | ( ( data & 0x0080 ) ? 1 : 0 );
10221011                     data <<= 1;
10231012                  }
1024                  gb_plot_pixel( bitmap, xindex, state->m_lcd.current_line, state->m_lcd.cgb_bpal[ ( ! state->m_lcd.gbc_mode ) ? state->m_lcd.gb_bpal[colour] : ( ( ( gbcmap[ state->m_lcd.layer[l].xindex ] & 0x07 ) * 4 ) + colour ) ] );
1025                  state->m_lcd.bg_zbuf[ xindex ] = colour + ( gbcmap[ state->m_lcd.layer[l].xindex ] & 0x80 );
1013                  gb_plot_pixel( bitmap, xindex, m_lcd.current_line, m_lcd.cgb_bpal[ ( ! m_lcd.gbc_mode ) ? m_lcd.gb_bpal[colour] : ( ( ( gbcmap[ m_lcd.layer[l].xindex ] & 0x07 ) * 4 ) + colour ) ] );
1014                  m_lcd.bg_zbuf[ xindex ] = colour + ( gbcmap[ m_lcd.layer[l].xindex ] & 0x80 );
10261015                  xindex++;
1027                  state->m_lcd.layer[l].xshift++;
1016                  m_lcd.layer[l].xshift++;
10281017                  i--;
10291018               }
1030               if ( state->m_lcd.layer[l].xshift == 8 )
1019               if ( m_lcd.layer[l].xshift == 8 )
10311020               {
10321021                  /* Take possible changes to SCROLLY into account */
10331022                  if ( l == 0 )
10341023                  {
1035                     state->m_lcd.layer[0].bgline = ( SCROLLY + state->m_lcd.current_line ) & 0xFF;
1036                     map = state->m_lcd.layer[l].bg_map + ( ( state->m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
1037                     gbcmap = state->m_lcd.layer[l].gbc_map + ( ( state->m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
1024                     m_lcd.layer[0].bgline = ( SCROLLY + m_lcd.current_line ) & 0xFF;
1025                     map = m_lcd.layer[l].bg_map + ( ( m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
1026                     gbcmap = m_lcd.layer[l].gbc_map + ( ( m_lcd.layer[l].bgline << 2 ) & 0x3E0 );
10381027                  }
10391028
1040                  state->m_lcd.layer[l].xindex = ( state->m_lcd.layer[l].xindex + 1 ) & 31;
1041                  state->m_lcd.layer[l].xshift = 0;
1042                  tiles = ( gbcmap[ state->m_lcd.layer[l].xindex ] & 0x08 ) ? state->m_lcd.gbc_chrgen : state->m_lcd.gb_chrgen;
1029                  m_lcd.layer[l].xindex = ( m_lcd.layer[l].xindex + 1 ) & 31;
1030                  m_lcd.layer[l].xshift = 0;
1031                  tiles = ( gbcmap[ m_lcd.layer[l].xindex ] & 0x08 ) ? m_lcd.gbc_chrgen : m_lcd.gb_chrgen;
10431032
10441033                  /* Check for vertical flip */
1045                  if ( gbcmap[ state->m_lcd.layer[l].xindex ] & 0x40 )
1034                  if ( gbcmap[ m_lcd.layer[l].xindex ] & 0x40 )
10461035                  {
1047                     tiles += ( ( 7 - ( state->m_lcd.layer[l].bgline & 0x07 ) ) << 1 );
1036                     tiles += ( ( 7 - ( m_lcd.layer[l].bgline & 0x07 ) ) << 1 );
10481037                  }
10491038                  else
10501039                  {
1051                     tiles += ( ( state->m_lcd.layer[l].bgline & 0x07 ) << 1 );
1040                     tiles += ( ( m_lcd.layer[l].bgline & 0x07 ) << 1 );
10521041                  }
1053                  tile_index = ( map[ state->m_lcd.layer[l].xindex ] ^ state->m_lcd.gb_tile_no_mod ) * 16;
1042                  tile_index = ( map[ m_lcd.layer[l].xindex ] ^ m_lcd.gb_tile_no_mod ) * 16;
10541043                  data = tiles[ tile_index ] | ( tiles[ tile_index + 1 ] << 8 );
10551044               }
10561045            }
10571046            l++;
10581047         }
1059         if ( state->m_lcd.end_x == 160 && ( LCDCONT & 0x02 ) )
1048         if ( m_lcd.end_x == 160 && ( LCDCONT & 0x02 ) )
10601049         {
1061            cgb_update_sprites( machine );
1050            cgb_update_sprites();
10621051         }
1063         state->m_lcd.start_x = state->m_lcd.end_x;
1052         m_lcd.start_x = m_lcd.end_x;
10641053      }
10651054   }
10661055   else
r20640r20641
10681057      if ( ! ( LCDCONT & 0x80 ) )
10691058      {
10701059         /* Draw an empty line when LCD is disabled */
1071         if ( state->m_lcd.previous_line != state->m_lcd.current_line )
1060         if ( m_lcd.previous_line != m_lcd.current_line )
10721061         {
1073            if ( state->m_lcd.current_line < 144 )
1062            if ( m_lcd.current_line < 144 )
10741063            {
1075               screen_device *screen = machine.first_screen();
1064               screen_device *screen = machine().first_screen();
10761065               const rectangle &r1 = screen->visible_area();
1077               rectangle r(r1.min_x, r1.max_x, state->m_lcd.current_line, state->m_lcd.current_line);
1078               bitmap.fill(( ! state->m_lcd.gbc_mode ) ? 0 : 32767 , r);
1066               rectangle r(r1.min_x, r1.max_x, m_lcd.current_line, m_lcd.current_line);
1067               bitmap.fill(( ! m_lcd.gbc_mode ) ? 0 : 32767 , r);
10791068            }
1080            state->m_lcd.previous_line = state->m_lcd.current_line;
1069            m_lcd.previous_line = m_lcd.current_line;
10811070         }
10821071      }
10831072   }
r20640r20641
11951184
11961185TIMER_CALLBACK_MEMBER(gb_state::gb_video_init_vbl)
11971186{
1198   machine().device("maincpu")->execute().set_input_line(VBL_INT, ASSERT_LINE );
1187   m_maincpu->set_input_line(VBL_INT, ASSERT_LINE );
11991188}
12001189
12011190MACHINE_START_MEMBER(gb_state,gb_video)
r20640r20641
12161205   return 0;
12171206}
12181207
1219void gb_video_reset( running_machine &machine, int mode )
1208void gb_state::gb_video_reset( int mode )
12201209{
1221   gb_state *state = machine.driver_data<gb_state>();
12221210   int i;
12231211   int vram_size = 0x2000;
1224   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1225   emu_timer *old_timer = state->m_lcd.lcd_timer;
1212   address_space &space = m_maincpu->space(AS_PROGRAM);
1213   emu_timer *old_timer = m_lcd.lcd_timer;
12261214
1227   memset( &state->m_lcd, 0, sizeof(state->m_lcd) );
1228   state->m_lcd.lcd_timer = old_timer;
1215   memset( &m_lcd, 0, sizeof(m_lcd) );
1216   m_lcd.lcd_timer = old_timer;
12291217
12301218   if (mode == GB_VIDEO_CGB) vram_size = 0x4000;
12311219
12321220   /* free regions if already allocated */
1233   if (state->memregion("gfx1")->base())       machine.memory().region_free(":gfx1");
1234   if (state->memregion("gfx2")->base())       machine.memory().region_free(":gfx2");
1221   if (memregion("gfx1")->base())       machine().memory().region_free(":gfx1");
1222   if (memregion("gfx2")->base())       machine().memory().region_free(":gfx2");
12351223
1236   state->m_lcd.gb_vram = machine.memory().region_alloc(":gfx1", vram_size, 1, ENDIANNESS_LITTLE );
1237   state->m_lcd.gb_oam = machine.memory().region_alloc(":gfx2", 0x100, 1, ENDIANNESS_LITTLE );
1238   memset( state->m_lcd.gb_vram->base(), 0, vram_size );
1224   m_lcd.gb_vram = machine().memory().region_alloc(":gfx1", vram_size, 1, ENDIANNESS_LITTLE );
1225   m_lcd.gb_oam = machine().memory().region_alloc(":gfx2", 0x100, 1, ENDIANNESS_LITTLE );
1226   memset( m_lcd.gb_vram->base(), 0, vram_size );
12391227
1240   state->m_lcd.gb_vram_ptr = state->m_lcd.gb_vram->base();
1241   state->m_lcd.gb_chrgen = state->m_lcd.gb_vram->base();
1242   state->m_lcd.gb_bgdtab = state->m_lcd.gb_vram->base() + 0x1C00;
1243   state->m_lcd.gb_wndtab = state->m_lcd.gb_vram->base() + 0x1C00;
1228   m_lcd.gb_vram_ptr = m_lcd.gb_vram->base();
1229   m_lcd.gb_chrgen = m_lcd.gb_vram->base();
1230   m_lcd.gb_bgdtab = m_lcd.gb_vram->base() + 0x1C00;
1231   m_lcd.gb_wndtab = m_lcd.gb_vram->base() + 0x1C00;
12441232
1245   state->m_lcd.gb_vid_regs[0x06] = 0xFF;
1233   m_lcd.gb_vid_regs[0x06] = 0xFF;
12461234   for( i = 0x0c; i < _NR_GB_VID_REGS; i++ )
12471235   {
1248      state->m_lcd.gb_vid_regs[i] = 0xFF;
1236      m_lcd.gb_vid_regs[i] = 0xFF;
12491237   }
12501238
12511239   LCDSTAT = 0x80;
12521240   LCDCONT = 0x00;     /* Video hardware is turned off at boot time */
1253   state->m_lcd.current_line = CURLINE = CMPLINE = 0x00;
1241   m_lcd.current_line = CURLINE = CMPLINE = 0x00;
12541242   SCROLLX = SCROLLY = 0x00;
12551243   SPR0PAL = SPR1PAL = 0xFF;
12561244   WNDPOSX = WNDPOSY = 0x00;
r20640r20641
12581246   /* Initialize palette arrays */
12591247   for( i = 0; i < 4; i++ )
12601248   {
1261      state->m_lcd.gb_bpal[i] = state->m_lcd.gb_spal0[i] = state->m_lcd.gb_spal1[i] = i;
1249      m_lcd.gb_bpal[i] = m_lcd.gb_spal0[i] = m_lcd.gb_spal1[i] = i;
12621250   }
12631251
12641252   switch( mode )
12651253   {
12661254   case GB_VIDEO_DMG:
1267      state->m_lcd.lcd_timer->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(456));
1255      m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(456));
12681256
12691257      /* set the scanline update function */
1270      state->update_scanline = gb_update_scanline;
1258      update_scanline = &gb_state::gb_update_scanline;
12711259
1272      memcpy( state->m_lcd.gb_oam->base(), dmg_oam_fingerprint, 0x100 );
1260      memcpy( m_lcd.gb_oam->base(), dmg_oam_fingerprint, 0x100 );
12731261
12741262      break;
12751263   case GB_VIDEO_MGB:
12761264      /* set the scanline update function */
1277      state->update_scanline = gb_update_scanline;
1265      update_scanline = &gb_state::gb_update_scanline;
12781266      /* Initialize part of VRAM. This code must be deleted when we have added the bios dump */
12791267      for( i = 1; i < 0x0D; i++ )
12801268      {
1281         state->m_lcd.gb_vram->base()[ 0x1903 + i ] = i;
1282         state->m_lcd.gb_vram->base()[ 0x1923 + i ] = i + 0x0C;
1269         m_lcd.gb_vram->base()[ 0x1903 + i ] = i;
1270         m_lcd.gb_vram->base()[ 0x1923 + i ] = i + 0x0C;
12831271      }
1284      state->m_lcd.gb_vram->base()[ 0x1910 ] = 0x19;
1272      m_lcd.gb_vram->base()[ 0x1910 ] = 0x19;
12851273
12861274
1287      memcpy( state->m_lcd.gb_oam->base(), mgb_oam_fingerprint, 0x100 );
1275      memcpy( m_lcd.gb_oam->base(), mgb_oam_fingerprint, 0x100 );
12881276
12891277      /* Make sure the VBlank interrupt is set when the first instruction gets executed */
1290      machine.scheduler().timer_set(machine.device<cpu_device>("maincpu")->cycles_to_attotime(1), timer_expired_delegate(FUNC(gb_state::gb_video_init_vbl),state));
1278      machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(1), timer_expired_delegate(FUNC(gb_state::gb_video_init_vbl),this));
12911279
12921280      /* Initialize some video registers */
1293      state->gb_video_w( space, 0x0, 0x91 );    /* LCDCONT */
1294      state->gb_video_w( space, 0x7, 0xFC );    /* BGRDPAL */
1295      state->gb_video_w( space, 0x8, 0xFC );    /* SPR0PAL */
1296      state->gb_video_w( space, 0x9, 0xFC );    /* SPR1PAL */
1281      gb_video_w( space, 0x0, 0x91 );    /* LCDCONT */
1282      gb_video_w( space, 0x7, 0xFC );    /* BGRDPAL */
1283      gb_video_w( space, 0x8, 0xFC );    /* SPR0PAL */
1284      gb_video_w( space, 0x9, 0xFC );    /* SPR1PAL */
12971285
1298      CURLINE = state->m_lcd.current_line = 0;
1286      CURLINE = m_lcd.current_line = 0;
12991287      LCDSTAT = ( LCDSTAT & 0xF8 ) | 0x05;
1300      state->m_lcd.mode = 1;
1301      state->m_lcd.lcd_timer->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(60), GB_LCD_STATE_LY00_M0);
1288      m_lcd.mode = 1;
1289      m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(60), GB_LCD_STATE_LY00_M0);
13021290
13031291      break;
13041292   case GB_VIDEO_SGB:
13051293      /* set the scanline update function */
1306      state->update_scanline = sgb_update_scanline;
1294      update_scanline = &gb_state::sgb_update_scanline;
13071295
13081296      break;
13091297
13101298   case GB_VIDEO_CGB:
13111299      /* set the scanline update function */
1312      state->update_scanline = cgb_update_scanline;
1300      update_scanline = &gb_state::cgb_update_scanline;
13131301
1314      memcpy( state->m_lcd.gb_oam->base(), cgb_oam_fingerprint, 0x100 );
1302      memcpy( m_lcd.gb_oam->base(), cgb_oam_fingerprint, 0x100 );
13151303
1316      state->m_lcd.gb_chrgen = state->m_lcd.gb_vram->base();
1317      state->m_lcd.gbc_chrgen = state->m_lcd.gb_vram->base() + 0x2000;
1318      state->m_lcd.gb_bgdtab = state->m_lcd.gb_wndtab = state->m_lcd.gb_vram->base() + 0x1C00;
1319      state->m_lcd.gbc_bgdtab = state->m_lcd.gbc_wndtab = state->m_lcd.gb_vram->base() + 0x3C00;
1304      m_lcd.gb_chrgen = m_lcd.gb_vram->base();
1305      m_lcd.gbc_chrgen = m_lcd.gb_vram->base() + 0x2000;
1306      m_lcd.gb_bgdtab = m_lcd.gb_wndtab = m_lcd.gb_vram->base() + 0x1C00;
1307      m_lcd.gbc_bgdtab = m_lcd.gbc_wndtab = m_lcd.gb_vram->base() + 0x3C00;
13201308
13211309      /* HDMA disabled */
1322      state->m_lcd.hdma_enabled = 0;
1323      state->m_lcd.hdma_possible = 0;
1310      m_lcd.hdma_enabled = 0;
1311      m_lcd.hdma_possible = 0;
13241312
1325      state->m_lcd.gbc_mode = 1;
1313      m_lcd.gbc_mode = 1;
13261314      break;
13271315   }
13281316}
13291317
1330static void gbc_hdma(running_machine &machine, UINT16 length)
1318
1319void gb_state::gbc_hdma(UINT16 length)
13311320{
1332   gb_state *state = machine.driver_data<gb_state>();
13331321   UINT16 src, dst;
1334   address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1322   address_space &space = m_maincpu->space(AS_PROGRAM);
13351323
13361324   src = ((UINT16)HDMA1 << 8) | (HDMA2 & 0xF0);
13371325   dst = ((UINT16)(HDMA3 & 0x1F) << 8) | (HDMA4 & 0xF0);
r20640r20641
13491337   if( (HDMA5 & 0x7f) == 0x7f )
13501338   {
13511339      HDMA5 = 0xff;
1352      state->m_lcd.hdma_enabled = 0;
1340      m_lcd.hdma_enabled = 0;
13531341   }
13541342}
13551343
1356static void gb_increment_scanline( gb_state *state )
1344
1345void gb_state::gb_increment_scanline()
13571346{
1358   state->m_lcd.current_line = ( state->m_lcd.current_line + 1 ) % 154;
1347   m_lcd.current_line = ( m_lcd.current_line + 1 ) % 154;
13591348   if ( LCDCONT & 0x80 )
13601349   {
1361      CURLINE = state->m_lcd.current_line;
1350      CURLINE = m_lcd.current_line;
13621351   }
1363   if ( state->m_lcd.current_line == 0 )
1352   if ( m_lcd.current_line == 0 )
13641353   {
1365      state->m_lcd.window_lines_drawn = 0;
1354      m_lcd.window_lines_drawn = 0;
13661355   }
13671356}
13681357
13691358TIMER_CALLBACK_MEMBER(gb_state::gb_lcd_timer_proc)
13701359{
1371   gb_state *state = machine().driver_data<gb_state>();
13721360   static const int sprite_cycles[] = { 0, 8, 20, 32, 44, 52, 64, 76, 88, 96, 108 };
13731361
13741362   m_lcd.state = param;
r20640r20641
13861374               if ( ! m_lcd.line_irq && ! m_lcd.delayed_line_irq )
13871375               {
13881376                  m_lcd.mode_irq = 1;
1389                  machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1377                  m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
13901378               }
13911379            }
13921380            else
r20640r20641
13941382               m_lcd.mode_irq = 0;
13951383            }
13961384         }
1397         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0);
1385         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0);
13981386         break;
13991387      case GB_LCD_STATE_LYXX_M0:      /* Switch to mode 0 */
14001388         /* update current scanline */
1401         (*update_scanline)( machine() );
1389         (this->*update_scanline)();
14021390         /* Increment the number of window lines drawn if enabled */
14031391         if ( m_lcd.layer[1].enabled )
14041392         {
r20640r20641
14191407         if ( ( SCROLLX & 0x03 ) == 0x03 )
14201408         {
14211409            m_lcd.scrollx_adjust += 4;
1422            m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_SCX3);
1410            m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_SCX3);
14231411            break;
14241412         }
14251413      case GB_LCD_STATE_LYXX_M0_SCX3:
r20640r20641
14271415         if ( ! m_lcd.mode_irq && ( LCDSTAT & 0x08 ) &&
14281416               ( ( ! m_lcd.line_irq && m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) )
14291417         {
1430            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1418            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
14311419         }
1432         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(196 - m_lcd.scrollx_adjust - m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_M0_PRE_INC);
1420         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(196 - m_lcd.scrollx_adjust - m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_M0_PRE_INC);
14331421         break;
14341422      case GB_LCD_STATE_LYXX_M0_PRE_INC:  /* Just before incrementing the line counter go to mode 2 internally */
14351423         if ( CURLINE < 143 )
r20640r20641
14431431                  if ( ! m_lcd.line_irq && ! m_lcd.delayed_line_irq )
14441432                  {
14451433                     m_lcd.mode_irq = 1;
1446                     machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1434                     m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
14471435                  }
14481436               }
14491437               else
r20640r20641
14521440               }
14531441            }
14541442         }
1455         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_INC);
1443         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_INC);
14561444         break;
14571445      case GB_LCD_STATE_LYXX_M0_INC:  /* Increment LY, stay in M0 for 4 more cycles */
1458         gb_increment_scanline(this);
1446         gb_increment_scanline();
14591447         m_lcd.delayed_line_irq = m_lcd.line_irq;
14601448         m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0;
14611449         m_lcd.line_irq = 0;
14621450         if ( ! m_lcd.mode_irq && ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq && ! m_lcd.triggering_mode_irq )
14631451         {
14641452            m_lcd.line_irq = m_lcd.triggering_line_irq;
1465            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1453            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
14661454         }
14671455         /* Reset LY==LYC STAT bit */
14681456         LCDSTAT &= 0xFB;
14691457         /* Check if we're going into VBlank next */
14701458         if ( CURLINE == 144 )
14711459         {
1472            m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1);
1460            m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1);
14731461         }
14741462         else
14751463         {
r20640r20641
14801468                  ( ( ! m_lcd.triggering_line_irq && ! m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) )
14811469            {
14821470               m_lcd.mode_irq = 1;
1483               machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1471               m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
14841472            }
1485            m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M2);
1473            m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M2);
14861474         }
14871475         break;
14881476      case GB_LCD_STATE_LY00_M2:      /* Switch to mode 2 on line #0 */
r20640r20641
14931481         /* Generate lcd interrupt if requested */
14941482         if ( ( LCDSTAT & 0x20 ) && ! m_lcd.line_irq )
14951483         {
1496            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1484            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
14971485         }
14981486         /* Check for regular compensation of x-scroll register */
14991487         m_lcd.scrollx_adjust = ( SCROLLX & 0x04 ) ? 4 : 0;
15001488         /* Mode 2 lasts approximately 80 clock cycles */
1501         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3);
1489         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3);
15021490         break;
15031491      case GB_LCD_STATE_LYXX_M2:      /* Switch to mode 2 */
15041492         /* Update STAT register to the correct state */
r20640r20641
15081496         if ( ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq && ! ( LCDSTAT & 0x20 ) ) ||
15091497               ( ! m_lcd.mode_irq && ! m_lcd.line_irq && ! m_lcd.delayed_line_irq && m_lcd.triggering_mode_irq ) )
15101498         {
1511            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1499            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
15121500         }
15131501         m_lcd.line_irq = m_lcd.triggering_line_irq;
15141502         m_lcd.triggering_mode_irq = 0;
r20640r20641
15201508         /* Check for regular compensation of x-scroll register */
15211509         m_lcd.scrollx_adjust = ( SCROLLX & 0x04 ) ? 4 : 0;
15221510         /* Mode 2 last for approximately 80 clock cycles */
1523         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3);
1511         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3);
15241512         break;
15251513      case GB_LCD_STATE_LYXX_M3:      /* Switch to mode 3 */
1526         gb_select_sprites(this);
1514         gb_select_sprites();
15271515         m_lcd.sprite_cycles = sprite_cycles[ m_lcd.sprCount ];
15281516         /* Set Mode 3 lcdstate */
15291517         m_lcd.mode = 3;
r20640r20641
15311519         m_lcd.vram_locked = LOCKED;
15321520         /* Check for compensations of x-scroll register */
15331521         /* Mode 3 lasts for approximately 172+cycles needed to handle sprites clock cycles */
1534         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(168 + m_lcd.scrollx_adjust + m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_PRE_M0);
1522         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(168 + m_lcd.scrollx_adjust + m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_PRE_M0);
15351523         m_lcd.start_x = -1;
15361524         break;
15371525      case GB_LCD_STATE_LY9X_M1:      /* Switch to or stay in mode 1 */
15381526         if ( CURLINE == 144 )
15391527         {
15401528            /* Trigger VBlank interrupt */
1541            machine().device("maincpu")->execute().set_input_line(VBL_INT, ASSERT_LINE );
1529            m_maincpu->set_input_line(VBL_INT, ASSERT_LINE );
15421530            /* Set VBlank lcdstate */
15431531            m_lcd.mode = 1;
15441532            LCDSTAT = (LCDSTAT & 0xFC) | 0x01;
15451533            /* Trigger LCD interrupt if requested */
15461534            if ( LCDSTAT & 0x10 )
15471535            {
1548               machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1536               m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
15491537            }
15501538         }
15511539         /* Check if LY==LYC STAT bit should be set */
r20640r20641
15551543         }
15561544         if ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq )
15571545         {
1558            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1546            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
15591547         }
1560         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(452), GB_LCD_STATE_LY9X_M1_INC);
1548         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(452), GB_LCD_STATE_LY9X_M1_INC);
15611549         break;
15621550      case GB_LCD_STATE_LY9X_M1_INC:      /* Increment scanline counter */
1563         gb_increment_scanline(this);
1551         gb_increment_scanline();
15641552         m_lcd.delayed_line_irq = m_lcd.line_irq;
15651553         m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0;
15661554         m_lcd.line_irq = 0;
15671555         if ( ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq )
15681556         {
15691557            m_lcd.line_irq = m_lcd.triggering_line_irq;
1570            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1558            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
15711559         }
15721560         /* Reset LY==LYC STAT bit */
15731561         LCDSTAT &= 0xFB;
15741562         if ( m_lcd.current_line == 153 )
15751563         {
1576            m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1);
1564            m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1);
15771565         }
15781566         else
15791567         {
1580            m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1);
1568            m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1);
15811569         }
15821570         break;
15831571      case GB_LCD_STATE_LY00_M1:      /* we stay in VBlank but current line counter should already be incremented */
r20640r20641
15861574         {
15871575            if ( m_lcd.triggering_line_irq )
15881576            {
1589               machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1577               m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
15901578            }
15911579         }
15921580         m_lcd.delayed_line_irq = m_lcd.delayed_line_irq | m_lcd.line_irq;
r20640r20641
15941582         {
15951583            LCDSTAT |= 0x04;
15961584         }
1597         gb_increment_scanline(this);
1585         gb_increment_scanline();
15981586         m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0;
15991587         m_lcd.line_irq = 0;
16001588         LCDSTAT &= 0xFB;
1601         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4/*8*/), GB_LCD_STATE_LY00_M1_1);
1589         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4/*8*/), GB_LCD_STATE_LY00_M1_1);
16021590         break;
16031591      case GB_LCD_STATE_LY00_M1_1:
16041592         if ( ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq )
16051593         {
16061594            m_lcd.line_irq = m_lcd.triggering_line_irq;
1607            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1595            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
16081596         }
1609         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1_2);
1597         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1_2);
16101598         break;
16111599      case GB_LCD_STATE_LY00_M1_2:    /* Rest of line #0 during VBlank */
16121600         if ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq )
16131601         {
16141602            m_lcd.line_irq = m_lcd.triggering_line_irq;
1615            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1603            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
16161604         }
16171605         if ( CURLINE == CMPLINE )
16181606         {
16191607            LCDSTAT |= 0x04;
16201608         }
1621         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(444), GB_LCD_STATE_LY00_M0);
1609         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(444), GB_LCD_STATE_LY00_M0);
16221610         break;
16231611      case GB_LCD_STATE_LY00_M0:      /* The STAT register seems to go to 0 for about 4 cycles */
16241612         /* Set Mode 0 lcdstat */
16251613         m_lcd.mode = 0;
16261614         LCDSTAT = ( LCDSTAT & 0xFC );
1627         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M2);
1615         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY00_M2);
16281616         break;
16291617      }
16301618   }
16311619   else
16321620   {
1633      gb_increment_scanline(this);
1621      gb_increment_scanline();
16341622      if ( m_lcd.current_line < 144 )
16351623      {
1636         (*update_scanline)( machine() );
1624         (this->*update_scanline)();
16371625      }
1638      m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(456));
1626      m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(456));
16391627   }
16401628}
16411629
16421630TIMER_CALLBACK_MEMBER(gb_state::gbc_lcd_timer_proc)
16431631{
1644   gb_state *state = machine().driver_data<gb_state>();
16451632   static const int sprite_cycles[] = { 0, 8, 20, 32, 44, 52, 64, 76, 88, 96, 108 };
16461633
16471634   m_lcd.state = param;
r20640r20641
16591646               if ( ! m_lcd.line_irq && ! m_lcd.delayed_line_irq )
16601647               {
16611648                  m_lcd.mode_irq = 1;
1662                  machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1649                  m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
16631650               }
16641651            }
16651652            else
r20640r20641
16671654               m_lcd.mode_irq = 0;
16681655            }
16691656         }
1670         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0);
1657         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0);
16711658         break;
16721659      case GB_LCD_STATE_LYXX_M0:      /* Switch to mode 0 */
16731660         /* update current scanline */
1674         (*update_scanline)( machine() );
1661         (this->*update_scanline)();
16751662         /* Increment the number of window lines drawn if enabled */
16761663         if ( m_lcd.layer[1].enabled )
16771664         {
r20640r20641
16931680         if ( ( SCROLLX & 0x03 ) == 0x03 )
16941681         {
16951682            m_lcd.scrollx_adjust += 4;
1696            m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_SCX3);
1683            m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_SCX3);
16971684            break;
16981685         }
16991686      case GB_LCD_STATE_LYXX_M0_SCX3:
r20640r20641
17011688         if ( ! m_lcd.mode_irq && m_lcd.triggering_mode_irq &&
17021689               ( ( ! m_lcd.line_irq && m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) )
17031690         {
1704            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1691            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
17051692            m_lcd.triggering_mode_irq = 0;
17061693         }
17071694         if ( ( SCROLLX & 0x03 ) == 0x03 )
17081695         {
17091696            m_lcd.pal_locked = UNLOCKED;
17101697         }
1711         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_GBC_PAL);
1698         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_GBC_PAL);
17121699         break;
17131700      case GB_LCD_STATE_LYXX_M0_GBC_PAL:
17141701         m_lcd.pal_locked = UNLOCKED;
17151702         /* Check for HBLANK DMA */
17161703         if( m_lcd.hdma_enabled )
17171704         {
1718            gbc_hdma(machine(), 0x10);
1705            gbc_hdma(0x10);
17191706//              cpunum_set_reg( 0, LR35902_DMA_CYCLES, 36 );
17201707         }
17211708         else
17221709         {
17231710            m_lcd.hdma_possible = 1;
17241711         }
1725         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(192 - m_lcd.scrollx_adjust - m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_M0_PRE_INC);
1712         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(192 - m_lcd.scrollx_adjust - m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_M0_PRE_INC);
17261713         break;
17271714      case GB_LCD_STATE_LYXX_M0_PRE_INC:  /* Just before incrementing the line counter go to mode 2 internally */
17281715         m_lcd.cmp_line = CMPLINE;
r20640r20641
17361723                  if ( ! m_lcd.line_irq && ! m_lcd.delayed_line_irq )
17371724                  {
17381725                     m_lcd.mode_irq = 1;
1739                     machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1726                     m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
17401727                  }
17411728               }
17421729               else
r20640r20641
17451732               }
17461733            }
17471734         }
1748         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_INC);
1735         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M0_INC);
17491736         break;
17501737      case GB_LCD_STATE_LYXX_M0_INC:  /* Increment LY, stay in M0 for 4 more cycles */
1751         gb_increment_scanline(this);
1738         gb_increment_scanline();
17521739         m_lcd.delayed_line_irq = m_lcd.line_irq;
17531740         m_lcd.triggering_line_irq = ( ( m_lcd.cmp_line == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0;
17541741         m_lcd.line_irq = 0;
17551742         if ( ! m_lcd.mode_irq && ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq && ! ( LCDSTAT & 0x20 ) )
17561743         {
17571744            m_lcd.line_irq = m_lcd.triggering_line_irq;
1758            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1745            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
17591746         }
17601747         m_lcd.hdma_possible = 0;
17611748         /* Check if we're going into VBlank next */
17621749         if ( CURLINE == 144 )
17631750         {
1764            m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1);
1751            m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1);
17651752         }
17661753         else
17671754         {
r20640r20641
17721759                  ( ( ! m_lcd.triggering_line_irq && ! m_lcd.delayed_line_irq ) || ! ( LCDSTAT & 0x40 ) ) )
17731760            {
17741761               m_lcd.mode_irq = 1;
1775               machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1762               m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
17761763            }
1777            m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M2);
1764            m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LYXX_M2);
17781765         }
17791766         break;
17801767      case GB_LCD_STATE_LY00_M2:      /* Switch to mode 2 on line #0 */
r20640r20641
17851772         /* Generate lcd interrupt if requested */
17861773         if ( ( LCDSTAT & 0x20 ) && ! m_lcd.line_irq )
17871774         {
1788            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1775            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
17891776         }
17901777         /* Check for regular compensation of x-scroll register */
17911778         m_lcd.scrollx_adjust = ( SCROLLX & 0x04 ) ? 4 : 0;
17921779         /* Mode 2 lasts approximately 80 clock cycles */
1793         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3);
1780         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3);
17941781         break;
17951782      case GB_LCD_STATE_LYXX_M2:      /* Switch to mode 2 */
17961783         /* Update STAT register to the correct state */
r20640r20641
18001787         if ( ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq && ! ( LCDSTAT & 0x20 ) ) ||
18011788               ( !m_lcd.mode_irq && ! m_lcd.line_irq && ! m_lcd.delayed_line_irq && ( LCDSTAT & 0x20 ) ) )
18021789         {
1803            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1790            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
18041791         }
18051792         m_lcd.line_irq = m_lcd.triggering_line_irq;
18061793         /* Check if LY==LYC STAT bit should be set */
r20640r20641
18151802         /* Check for regular compensation of x-scroll register */
18161803         m_lcd.scrollx_adjust = ( SCROLLX & 0x04 ) ? 4 : 0;
18171804         /* Mode 2 last for approximately 80 clock cycles */
1818         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3);
1805         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3);
18191806         break;
18201807      case GB_LCD_STATE_LYXX_M3:      /* Switch to mode 3 */
1821         gb_select_sprites(this);
1808         gb_select_sprites();
18221809         m_lcd.sprite_cycles = sprite_cycles[ m_lcd.sprCount ];
18231810         /* Set Mode 3 lcdstate */
18241811         m_lcd.mode = 3;
r20640r20641
18271814         m_lcd.pal_locked = LOCKED;
18281815         /* Check for compensations of x-scroll register */
18291816         /* Mode 3 lasts for approximately 172+cycles needed to handle sprites clock cycles */
1830         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(168 + m_lcd.scrollx_adjust + m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_PRE_M0);
1817         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(168 + m_lcd.scrollx_adjust + m_lcd.sprite_cycles), GB_LCD_STATE_LYXX_PRE_M0);
18311818         m_lcd.start_x = -1;
18321819         break;
18331820      case GB_LCD_STATE_LY9X_M1:      /* Switch to or stay in mode 1 */
18341821         if ( CURLINE == 144 )
18351822         {
18361823            /* Trigger VBlank interrupt */
1837            machine().device("maincpu")->execute().set_input_line(VBL_INT, ASSERT_LINE );
1824            m_maincpu->set_input_line(VBL_INT, ASSERT_LINE );
18381825            /* Set VBlank lcdstate */
18391826            m_lcd.mode = 1;
18401827            LCDSTAT = (LCDSTAT & 0xFC) | 0x01;
18411828            /* Trigger LCD interrupt if requested */
18421829            if ( LCDSTAT & 0x10 )
18431830            {
1844               machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1831               m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
18451832            }
18461833         }
18471834         /* Check if LY==LYC STAT bit should be set */
r20640r20641
18551842         }
18561843         if ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq )
18571844         {
1858            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1845            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
18591846         }
1860         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(452), GB_LCD_STATE_LY9X_M1_INC);
1847         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(452), GB_LCD_STATE_LY9X_M1_INC);
18611848         break;
18621849      case GB_LCD_STATE_LY9X_M1_INC:      /* Increment scanline counter */
1863         gb_increment_scanline(this);
1850         gb_increment_scanline();
18641851         m_lcd.delayed_line_irq = m_lcd.line_irq;
18651852         m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0;
18661853         m_lcd.line_irq = 0;
18671854         if ( ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq )
18681855         {
18691856            m_lcd.line_irq = m_lcd.triggering_line_irq;
1870            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1857            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
18711858         }
18721859         if ( m_lcd.current_line == 153 )
18731860         {
1874            m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1);
1861            m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1);
18751862         }
18761863         else
18771864         {
1878            m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1);
1865            m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY9X_M1);
18791866         }
18801867         break;
18811868      case GB_LCD_STATE_LY00_M1:      /* we stay in VBlank but current line counter should already be incremented */
r20640r20641
18841871         {
18851872            if ( m_lcd.triggering_line_irq )
18861873            {
1887               machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1874               m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
18881875            }
18891876         }
18901877         m_lcd.delayed_line_irq = m_lcd.delayed_line_irq | m_lcd.line_irq;
r20640r20641
18961883         {
18971884            LCDSTAT &= ~0x04;
18981885         }
1899         gb_increment_scanline(this);
1886         gb_increment_scanline();
19001887         m_lcd.triggering_line_irq = ( ( CMPLINE == CURLINE ) && ( LCDSTAT & 0x40 ) ) ? 1 : 0;
19011888         m_lcd.line_irq = 0;
19021889         LCDSTAT &= 0xFB;
1903         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1_1);
1890         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1_1);
19041891         break;
19051892      case GB_LCD_STATE_LY00_M1_1:
19061893         if ( ! m_lcd.delayed_line_irq && m_lcd.triggering_line_irq )
19071894         {
19081895            m_lcd.line_irq = m_lcd.triggering_line_irq;
1909            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1896            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
19101897         }
1911         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1_2);
1898         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY00_M1_2);
19121899         break;
19131900      case GB_LCD_STATE_LY00_M1_2:    /* Rest of line #0 during VBlank */
19141901         if ( m_lcd.delayed_line_irq && m_lcd.triggering_line_irq )
19151902         {
19161903            m_lcd.line_irq = m_lcd.triggering_line_irq;
1917            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1904            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
19181905         }
19191906         if ( CURLINE == CMPLINE )
19201907         {
r20640r20641
19241911         {
19251912            LCDSTAT &= ~0x04;
19261913         }
1927         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(444), GB_LCD_STATE_LY00_M0);
1914         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(444), GB_LCD_STATE_LY00_M0);
19281915         break;
19291916      case GB_LCD_STATE_LY00_M0:      /* The STAT register seems to go to 0 for about 4 cycles */
19301917         /* Set Mode 0 lcdstat */
19311918         m_lcd.mode = 0;
1932         m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(4), GB_LCD_STATE_LY00_M2);
1919         m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(4), GB_LCD_STATE_LY00_M2);
19331920         break;
19341921      }
19351922   }
19361923   else
19371924   {
1938      gb_increment_scanline(this);
1925      gb_increment_scanline();
19391926      if ( m_lcd.current_line < 144 )
19401927      {
1941         (*update_scanline)( machine() );
1928         (this->*update_scanline)();
19421929      }
1943      m_lcd.lcd_timer->adjust(machine().device<cpu_device>("maincpu")->cycles_to_attotime(456));
1930      m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(456));
19441931   }
19451932}
19461933
1947static void gb_lcd_switch_on( running_machine &machine )
1934
1935void gb_state::gb_lcd_switch_on()
19481936{
1949   gb_state *state = machine.driver_data<gb_state>();
1950   state->m_lcd.current_line = 0;
1951   state->m_lcd.previous_line = 153;
1952   state->m_lcd.window_lines_drawn = 0;
1953   state->m_lcd.line_irq = 0;
1954   state->m_lcd.delayed_line_irq = 0;
1955   state->m_lcd.mode = 0;
1956   state->m_lcd.oam_locked = LOCKED;   /* TODO: Investigate whether this OAM locking is correct. */
1937   m_lcd.current_line = 0;
1938   m_lcd.previous_line = 153;
1939   m_lcd.window_lines_drawn = 0;
1940   m_lcd.line_irq = 0;
1941   m_lcd.delayed_line_irq = 0;
1942   m_lcd.mode = 0;
1943   m_lcd.oam_locked = LOCKED;   /* TODO: Investigate whether this OAM locking is correct. */
19571944   /* Check for LY=LYC coincidence */
19581945   if ( CURLINE == CMPLINE )
19591946   {
r20640r20641
19611948      /* Generate lcd interrupt if requested */
19621949      if ( LCDSTAT & 0x40 )
19631950      {
1964         machine.device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
1951         m_maincpu->set_input_line( LCD_INT, ASSERT_LINE );
19651952      }
19661953   }
1967   state->m_lcd.state = GB_LCD_STATE_LY00_M2;
1968   state->m_lcd.lcd_timer->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3);
1954   m_lcd.state = GB_LCD_STATE_LY00_M2;
1955   m_lcd.lcd_timer->adjust(m_maincpu->cycles_to_attotime(80), GB_LCD_STATE_LYXX_M3);
19691956}
19701957
19711958READ8_MEMBER(gb_state::gb_video_r)
r20640r20641
20031990
20041991WRITE8_MEMBER(gb_state::gb_video_w)
20051992{
2006   gb_state *state = machine().driver_data<gb_state>();
20071993   switch (offset)
20081994   {
20091995   case 0x00:                      /* LCDC - LCD Control */
r20640r20641
20222008      /* If LCD is being switched on */
20232009      if ( !( LCDCONT & 0x80 ) && ( data & 0x80 ) )
20242010      {
2025         gb_lcd_switch_on(machine());
2011         gb_lcd_switch_on();
20262012      }
20272013      break;
20282014   case 0x01:                      /* STAT - LCD Status */
r20640r20641
20562042            ( ( LCDSTAT & 0x60 ) == 0x20 && ( data & 0x40 ) )
20572043            ) )
20582044         {
2059               machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
2045               m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
20602046         }
20612047         /*
20622048            - 0x20 -> 0x08/0x18/0x28/0x48 (mode 0, after m2int) - trigger
r20640r20641
20652051         */
20662052         if ( m_lcd.mode_irq && m_lcd.mode == 0 )
20672053         {
2068            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
2054            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
20692055         }
20702056      }
20712057      break;
r20640r20641
20822068               /* Generate lcd interrupt if requested */
20832069               if ( LCDSTAT & 0x40 )
20842070               {
2085                  machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
2071                  m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
20862072               }
20872073            }
20882074         }
r20640r20641
21022088      }
21032089      return;
21042090   case 0x07:                      /* BGP - Background Palette */
2105      (*update_scanline)(machine());
2091      (this->*update_scanline)();
21062092      m_lcd.gb_bpal[0] = data & 0x3;
21072093      m_lcd.gb_bpal[1] = (data & 0xC) >> 2;
21082094      m_lcd.gb_bpal[2] = (data & 0x30) >> 4;
21092095      m_lcd.gb_bpal[3] = (data & 0xC0) >> 6;
21102096      break;
21112097   case 0x08:                      /* OBP0 - Object Palette 0 */
2112//      (*update_scanline)( machine );
2098//      (this->*update_scanline)();
21132099      m_lcd.gb_spal0[0] = data & 0x3;
21142100      m_lcd.gb_spal0[1] = (data & 0xC) >> 2;
21152101      m_lcd.gb_spal0[2] = (data & 0x30) >> 4;
21162102      m_lcd.gb_spal0[3] = (data & 0xC0) >> 6;
21172103      break;
21182104   case 0x09:                      /* OBP1 - Object Palette 1 */
2119//      (*update_scanline)( machine );
2105//      (this->*update_scanline)();
21202106      m_lcd.gb_spal1[0] = data & 0x3;
21212107      m_lcd.gb_spal1[1] = (data & 0xC) >> 2;
21222108      m_lcd.gb_spal1[2] = (data & 0x30) >> 4;
r20640r20641
21242110      break;
21252111   case 0x02:                      /* SCY - Scroll Y */
21262112   case 0x03:                      /* SCX - Scroll X */
2127      (*update_scanline)(machine());
2113      (this->*update_scanline)();
21282114   case 0x0A:                      /* WY - Window Y position */
21292115   case 0x0B:                      /* WX - Window X position */
21302116      break;
r20640r20641
21562142
21572143WRITE8_MEMBER(gb_state::gbc_video_w)
21582144{
2159   gb_state *state = machine().driver_data<gb_state>();
21602145   switch( offset )
21612146   {
21622147   case 0x00:      /* LCDC - LCD Control */
r20640r20641
21792164      /* If LCD is being switched on */
21802165      if ( !( LCDCONT & 0x80 ) && ( data & 0x80 ) )
21812166      {
2182         gb_lcd_switch_on(machine());
2167         gb_lcd_switch_on();
21832168      }
21842169      break;
21852170   case 0x01:      /* STAT - LCD Status */
r20640r20641
21912176         */
21922177         if ( m_lcd.mode_irq && m_lcd.mode == 0 && ( LCDSTAT & 0x28 ) == 0x20 && ( data & 0x08 ) )
21932178         {
2194            machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
2179            m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
21952180         }
21962181         /* Check if line irqs are being disabled */
21972182         if ( ! ( data & 0x40 ) )
r20640r20641
22042189            if ( CMPLINE == CURLINE )
22052190            {
22062191               m_lcd.line_irq = 1;
2207               machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
2192               m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
22082193            }
22092194         }
22102195      }
r20640r20641
22192204            /* Generate lcd interrupt if requested */
22202205            if ( LCDSTAT & 0x40 )
22212206            {
2222               machine().device("maincpu")->execute().set_input_line(LCD_INT, ASSERT_LINE );
2207               m_maincpu->set_input_line(LCD_INT, ASSERT_LINE );
22232208            }
22242209         }
22252210         else
r20640r20641
22312216      }
22322217      break;
22332218   case 0x07:      /* BGP - GB background palette */
2234      (*update_scanline)(machine());
2219      (this->*update_scanline)();
22352220      m_lcd.gb_bpal[0] = data & 0x3;
22362221      m_lcd.gb_bpal[1] = (data & 0xC) >> 2;
22372222      m_lcd.gb_bpal[2] = (data & 0x30) >> 4;
r20640r20641
22782263         else
22792264         {
22802265            /* General DMA */
2281            gbc_hdma( machine(), ((data & 0x7F) + 1) * 0x10 );
2266            gbc_hdma( ((data & 0x7F) + 1) * 0x10 );
22822267//              cpunum_set_reg( 0, LR35902_DMA_CYCLES, 4 + ( ( ( data & 0x7F ) + 1 ) * 32 ) );
22832268            data = 0xff;
22842269         }
r20640r20641
22922277         /* Check if HDMA should be immediately performed */
22932278         if ( m_lcd.hdma_possible )
22942279         {
2295            gbc_hdma( machine(), 0x10 );
2280            gbc_hdma( 0x10 );
22962281//              cpunum_set_reg( 0, LR35902_DMA_CYCLES, 36 );
22972282            m_lcd.hdma_possible = 0;
22982283         }
r20640r20641
23782363   m_lcd.gb_vid_regs[offset] = data;
23792364}
23802365
2381
2382UINT8 *gb_get_vram_ptr(running_machine &machine)
2383{
2384   gb_state *state = machine.driver_data<gb_state>();
2385   return state->m_lcd.gb_vram_ptr;
2386}
trunk/src/mess/drivers/gb.c
r20640r20641
453453static const UINT16 mgb_cpu_regs[6] = { 0xFFB0, 0x0013, 0x00D8, 0x014D, 0xFFFE, 0x0100 };   /* Game Boy Pocket / Super Game Boy 2 */
454454static const UINT16 megaduck_cpu_regs[6] = { 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFE, 0x0000 };  /* Megaduck */
455455
456static const struct lr35902_config dmg_cpu_reset = { NULL, LR35902_FEATURE_HALT_BUG, gb_timer_callback };
457static const struct lr35902_config sgb_cpu_reset = { NULL, LR35902_FEATURE_HALT_BUG, gb_timer_callback };
458static const struct lr35902_config mgb_cpu_reset = { mgb_cpu_regs, LR35902_FEATURE_HALT_BUG, gb_timer_callback };
459static const struct lr35902_config cgb_cpu_reset = { NULL, 0, gb_timer_callback };
460static const struct lr35902_config megaduck_cpu_reset = { megaduck_cpu_regs, LR35902_FEATURE_HALT_BUG, gb_timer_callback };
461
462456static ADDRESS_MAP_START(gb_map, AS_PROGRAM, 8, gb_state )
463457   ADDRESS_MAP_UNMAP_HIGH
464458   AM_RANGE(0x0000, 0x00ff) AM_ROMBANK("bank5")                    /* BIOS or ROM */
r20640r20641
561555   /* basic machine hardware */
562556   MCFG_CPU_ADD("maincpu", LR35902, 4194304)           /* 4.194304 MHz */
563557   MCFG_CPU_PROGRAM_MAP(gb_map)
564   MCFG_LR35902_CONFIG(dmg_cpu_reset)
558   MCFG_LR35902_TIMER_CB( WRITE8( gb_state, gb_timer_callback ) )
559   MCFG_LR35902_HALT_BUG
565560   MCFG_CPU_VBLANK_INT_DRIVER("screen", gb_state,  gb_scanline_interrupt)  /* 1 dummy int each frame */
566561
567562   MCFG_QUANTUM_TIME(attotime::from_hz(60))
r20640r20641
606601   MCFG_CPU_PROGRAM_MAP(sgb_map)
607602
608603   MCFG_CPU_MODIFY("maincpu")
609   MCFG_LR35902_CONFIG(sgb_cpu_reset)
604   MCFG_LR35902_TIMER_CB( WRITE8( gb_state, gb_timer_callback ) )
605   MCFG_LR35902_HALT_BUG
610606
611607   MCFG_MACHINE_START_OVERRIDE(gb_state, sgb )
612608   MCFG_MACHINE_RESET_OVERRIDE(gb_state, sgb )
r20640r20641
622618
623619static MACHINE_CONFIG_DERIVED( gbpocket, gameboy )
624620   MCFG_CPU_MODIFY("maincpu")
625   MCFG_LR35902_CONFIG(mgb_cpu_reset)
621   MCFG_LR35902_TIMER_CB( WRITE8( gb_state, gb_timer_callback ) )
622   MCFG_LR35902_HALT_BUG
623   MCFG_LR35902_RESET_VALUES(mgb_cpu_regs)
624
626625   MCFG_MACHINE_RESET_OVERRIDE(gb_state, gbpocket )
627626   MCFG_PALETTE_INIT_OVERRIDE(gb_state,gbp)
628627
r20640r20641
633632static MACHINE_CONFIG_DERIVED( gbcolor, gb_common )
634633   MCFG_CPU_MODIFY("maincpu")
635634   MCFG_CPU_PROGRAM_MAP( gbc_map)
636   MCFG_LR35902_CONFIG(cgb_cpu_reset)
635   MCFG_LR35902_TIMER_CB( WRITE8( gb_state, gb_timer_callback ) )
637636
638637   MCFG_MACHINE_START_OVERRIDE(gb_state,gbc)
639638   MCFG_MACHINE_RESET_OVERRIDE(gb_state,gbc)
r20640r20641
659658   /* basic machine hardware */
660659   MCFG_CPU_ADD("maincpu", LR35902, 4194304)           /* 4.194304 MHz */
661660   MCFG_CPU_PROGRAM_MAP( megaduck_map)
661   MCFG_LR35902_TIMER_CB( WRITE8( gb_state, gb_timer_callback ) )
662   MCFG_LR35902_HALT_BUG
663   MCFG_LR35902_RESET_VALUES(megaduck_cpu_regs)
662664   MCFG_CPU_VBLANK_INT_DRIVER("screen", gb_state,  gb_scanline_interrupt)  /* 1 int each scanline ! */
663   MCFG_LR35902_CONFIG(megaduck_cpu_reset)
664665
665666   MCFG_SCREEN_ADD("screen", LCD)
666667   MCFG_SCREEN_REFRESH_RATE(DMG_FRAMES_PER_SECOND)
trunk/src/emu/cpu/lr35902/lr35902.c
r20640r20641
5454
5555
5656lr35902_cpu_device::lr35902_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
57   : cpu_device(mconfig, LR35902, "LR35902", tag, owner, clock),
58      m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0)
57   : cpu_device(mconfig, LR35902, "LR35902", tag, owner, clock)
58   , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0)
59   , m_timer_func(*this)
60   , m_features(0)
61   , c_regs(NULL)
5962{
60   c_regs = NULL;
61   c_features = 0;
62   c_timer_expired_func = NULL;
6363}
6464
6565
66void lr35902_cpu_device::static_set_config(device_t &device, const lr35902_config &config)
67{
68   lr35902_cpu_device &conf = downcast<lr35902_cpu_device &>(device);
69   static_cast<lr35902_config &>(conf) = config;
70}
71
72
7366/****************************************************************************/
7467/* Memory functions                                                         */
7568/****************************************************************************/
r20640r20641
7770inline void lr35902_cpu_device::cycles_passed(UINT8 cycles)
7871{
7972   m_icount -= cycles / m_gb_speed;
80   if ( m_timer_expired_func )
81   {
82      m_timer_expired_func( this, cycles );
83   }
73   m_timer_func( cycles );
8474}
8575
8676
r20640r20641
119109   m_device = this;
120110   m_program = &space(AS_PROGRAM);
121111
112   m_timer_func.resolve_safe();
113
122114   save_item(NAME(m_A));
123115   save_item(NAME(m_F));
124116   save_item(NAME(m_B));
r20640r20641
210202      m_SP = c_regs[4];
211203      m_PC = c_regs[5];
212204   }
213   m_timer_expired_func = c_timer_expired_func;
214   m_features = c_features;
215205
216206   m_enable = 0;
217207   m_IE = 0;
trunk/src/emu/cpu/lr35902/lr35902.h
r20640r20641
44#define __LR35902_H__
55
66
7#define MCFG_LR35902_CONFIG(_config) \
8   lr35902_cpu_device::static_set_config(*device, _config);
7#define MCFG_LR35902_TIMER_CB(_devcb) \
8   lr35902_cpu_device::set_timer_cb(*device, DEVCB2_##_devcb); \
99
10class lr35902_cpu_device;
10#define MCFG_LR35902_HALT_BUG \
11   lr35902_cpu_device::set_halt_bug(*device); \
1112
12// Perhaps replace this with a standard device callback
13typedef void (*lr35902_timer_fired_func)(lr35902_cpu_device *device, int cycles);
13// This should be removed/improved once all gameboy boot roms have been dumped
14#define MCFG_LR35902_RESET_VALUES(_regs) \
15   lr35902_cpu_device::set_reset_values(*device, _regs); \
1416
15struct lr35902_config
16{
17   const UINT16    *c_regs;
18   UINT8           c_features;
19   lr35902_timer_fired_func c_timer_expired_func;
20};
2117
2218enum
2319{
r20640r20641
2925   LR35902_SPEED,
3026};
3127
32// This and the features configuration could be removed if we introduce proper subclasses
33#define LR35902_FEATURE_HALT_BUG    0x01
3428
35
36class lr35902_cpu_device :  public cpu_device,
37                     public lr35902_config
29class lr35902_cpu_device :  public cpu_device
3830{
3931public:
4032   // construction/destruction
4133   lr35902_cpu_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
4234
43   static void static_set_config(device_t &device, const lr35902_config &config);
35   // static configuration helpers
36   template<class _Object> static devcb2_base &set_timer_cb(device_t &device, _Object object) { return downcast<lr35902_cpu_device &>(device).m_timer_func.set_callback(object); }
37   static void set_halt_bug(device_t &device) { downcast<lr35902_cpu_device &>(device).m_features |= LR35902_FEATURE_HALT_BUG; }
38   static void set_reset_values(device_t &device, const UINT16 *regs) { downcast<lr35902_cpu_device &>(device).c_regs = regs; }
4439
4540   UINT8 get_speed();
4641   void set_speed( UINT8 speed_request );
r20640r20641
5247   void set_if( UINT8 data ) { m_IF = data; }
5348
5449protected:
50   static const UINT8 LR35902_FEATURE_HALT_BUG = 0x01;
51
5552   // device-level overrides
5653   virtual void device_start();
5754   virtual void device_reset();
r20640r20641
103100   lr35902_cpu_device *m_device;
104101   address_space *m_program;
105102   int m_icount;
106   /* Timer stuff */
107   lr35902_timer_fired_func m_timer_expired_func;
103   /* Timer callback */
104   devcb2_write8 m_timer_func;
108105   /* Fetch & execute related */
109106   int     m_execution_state;
110107   UINT8   m_op;
r20640r20641
114111   int m_enable;
115112   int m_doHALTbug;
116113   UINT8   m_features;
114   const UINT16 *c_regs;
117115   const struct lr35902_config *m_config;
118116
119117   /* Flag bit definitions */

Previous 199869 Revisions Next


© 1997-2024 The MAME Team