Previous 199869 Revisions Next

r17589 Sunday 2nd September, 2012 at 11:14:20 UTC by Tafoid
littlerb.c:  Things are starting to make a little more sense now.. still too many hacks and things to figure out, but it looks almost reasonable in places now.  Game is playable to a degree as you can finally see scores, "ROBIN" and more.  From Haze (nw)
[src/mame/drivers]littlerb.c

trunk/src/mame/drivers/littlerb.c
r17588r17589
55David Haywood
66*/
77
8
9#define littlerb_printf logerror
10#define littlerb_alt_printf logerror
11
812/*
913
1014strange vdp/memory access chip..
11at the moment gfx / palettes etc. get drawn then erased
15at the moment gfx / palettes etc. get drawn then erased, I think it's a blitter, with multiple layers
16some of the 'sprite entries' seem a different size, or alignment, hence the bad sprites on the title
17screen.  no idea how layers are seleced / cleared right now either
1218
19
1320maybe it needs read commands working so it knows how many sprites are in
1421the list?
1522
r17588r17589
7077#include "video/ramdac.h"
7178#include "sound/dac.h"
7279
80static void littlerb_draw_sprites(running_machine &machine);
81
7382class littlerb_state : public driver_device
7483{
7584public:
r17588r17589
7887        m_maincpu(*this, "maincpu"),
7988        m_dacl(*this, "dacl"),
8089         m_dacr(*this, "dacr"),
81      m_region4(*this, "region4"){ }
90      m_region4(*this, "region4")
91   {
92      m_1ff80804 = -1;
93   }
8294
8395   required_device<cpu_device> m_maincpu;
8496   required_device<dac_device> m_dacl;
r17588r17589
99111   UINT32 m_lasttype2pc;
100112   UINT8 m_sound_index_l,m_sound_index_r;
101113   UINT16 m_sound_pointer_l,m_sound_pointer_r;
114   
115   bitmap_ind16 m_temp_bitmap_sprites;
116   bitmap_ind16 m_temp_bitmap_sprites_back; // not currently used
102117
118
119   DECLARE_WRITE16_MEMBER(spritelist_w);
103120   DECLARE_WRITE16_MEMBER(region4_w);
104121   DECLARE_READ16_MEMBER(buffer_status_r);
105122   DECLARE_READ16_MEMBER(littlerb_vdp_r);
r17588r17589
107124   DECLARE_WRITE16_MEMBER(littlerb_l_sound_w);
108125   DECLARE_WRITE16_MEMBER(littlerb_r_sound_w);
109126   DECLARE_CUSTOM_INPUT_MEMBER(littlerb_frame_step_r);
127
128   int m_1ff80804;
129   int m_listoffset;
130   UINT16* m_spritelist;
131
132   DECLARE_READ16_MEMBER( littlerb_1ff80800_r )
133   {
134      littlerb_printf("littlerb_1ff80800_r\n");
135      return 0x0000;
136   }
137
138   DECLARE_WRITE16_MEMBER( littlerb_1ff80800_w )
139   {
140      littlerb_printf("littlerb_1ff80800_w %04x\n", data);
141   }
142
143   DECLARE_READ16_MEMBER( littlerb_1ff80802_r )
144   {
145      littlerb_printf("littlerb_1ff80802_r\n");
146      return 0x0000;
147   }
148
149   DECLARE_WRITE16_MEMBER( littlerb_1ff80802_w )
150   {
151      littlerb_printf("littlerb_1ff80802_w %04x\n", data);
152   }
153
154   DECLARE_WRITE16_MEMBER( littlerb_1ff80804_w )
155   {
156      littlerb_printf("littlerb_1ff80804_w %04x\n", data);
157
158      if ((!(m_spritelist[2] & 0x1000)) && (!(m_spritelist[1] & 0x1000)))
159      {
160
161      }
162      else
163      {
164         if (!(m_spritelist[2] & 0x1000))
165            m_temp_bitmap_sprites_back.fill(0, m_temp_bitmap_sprites_back.cliprect());
166
167      }
168     
169      littlerb_draw_sprites(space.machine());
170
171
172      m_listoffset = 0;
173      memset(m_spritelist, 0x00, 0x20000); // clear out the list.. I think it's commands anyway?
174
175   }
176
177   DECLARE_WRITE16_MEMBER( littlerb_18000012_w )
178   {
179      littlerb_printf("littlerb_18000012_w %04x\n", data);
180      // edfc / fffc alternating (select double buffering?)
181   }
182
183   DECLARE_WRITE16_MEMBER( littlerb_18000014_w )
184   {
185      littlerb_printf("littlerb_18000014_w %04x\n", data);
186      // dosen't seem to be the draw trigger, or you get broken platforms..
187
188
189   }
190
191   DECLARE_WRITE16_MEMBER( littlerb_1800003c_w )
192   {
193      littlerb_printf("littlerb_1800003c_w %04x\n", data);
194      // edfc / fffc alternating (display double buffering?)
195   }
110196};
111197
112198
r17588r17589
120206   return 0;
121207}
122208
209
210WRITE16_MEMBER(littlerb_state::spritelist_w)
211{
212   littlerb_printf("spritelist_w %04x\n",  data);
213
214   COMBINE_DATA(&m_spritelist[m_listoffset]);
215   m_listoffset++;
216}
217
218
219
123220/* this map is wrong because our VDP access is wrong! */
124221static ADDRESS_MAP_START( littlerb_vdp_map8, AS_0, 16, littlerb_state )
125222   // it ends up writing some gfx here (the bubbles when you shoot an enemy)
r17588r17589
130227   AM_RANGE(0x00800000, 0x00800001) AM_DEVWRITE8("^ramdac", ramdac_device, index_w, 0x00ff)
131228   AM_RANGE(0x00800002 ,0x00800003) AM_DEVWRITE8("^ramdac", ramdac_device, pal_w,   0x00ff)
132229   AM_RANGE(0x00800004 ,0x00800005) AM_DEVWRITE8("^ramdac", ramdac_device, mask_w,  0x00ff)
230   AM_RANGE(0x18000012, 0x18000013) AM_DEVWRITE("^", littlerb_state, littlerb_18000012_w)
231   AM_RANGE(0x18000014, 0x18000015) AM_DEVWRITE("^", littlerb_state, littlerb_18000014_w)
232   AM_RANGE(0x1800003c, 0x1800003d) AM_DEVWRITE("^", littlerb_state, littlerb_1800003c_w)
233   AM_RANGE(0x1ff80800, 0x1ff80801) AM_DEVREADWRITE("^", littlerb_state, littlerb_1ff80800_r, littlerb_1ff80800_w)
234   AM_RANGE(0x1ff80802, 0x1ff80803) AM_DEVREADWRITE("^", littlerb_state, littlerb_1ff80802_r, littlerb_1ff80802_w)
235   AM_RANGE(0x1ff80804, 0x1ff80805) AM_DEVREADWRITE("^", littlerb_state, buffer_status_r, littlerb_1ff80804_w)
236   AM_RANGE(0x1ff80806, 0x1ff80807) AM_RAM AM_DEVWRITE("^", littlerb_state, spritelist_w)
133237
134   AM_RANGE(0x1ff80804, 0x1ff80805) AM_DEVREAD("^", littlerb_state, buffer_status_r)
135238   // most gfx end up here including the sprite list
136239   AM_RANGE(0x1ff80000, 0x1fffffff) AM_RAM AM_DEVWRITE("^", littlerb_state, region4_w)  AM_SHARE("region4")
137240ADDRESS_MAP_END
r17588r17589
200303   littlerb_state *state = machine.driver_data<littlerb_state>();
201304   UINT32 addr = state->m_write_address >> 3; // almost surely raw addresses are actually shifted by 3
202305   address_space *vdp_space = machine.device<littlerb_vdp_device>("littlerbvdp")->space();
306   int mode = state->m_vdp_writemode;
203307
204   int mode = state->m_vdp_writemode;
308
309   logerror("mode %04x, data %04x, mem_mask %04x (address %08x)\n", mode,  data, mem_mask, state->m_write_address >> 3);
310
205311   if ((mode!=0x3800) && (mode !=0x2000) && (mode != 0xe000) && (mode != 0xf800))
206312   {
207      printf("mode %04x, data %04x, mem_mask %04x (address %08x)\n", mode,  data, mem_mask, state->m_write_address >> 3);
208313   }
209314   else
210315   {
211316      vdp_space->write_word(addr, data, mem_mask);
212317
213318      // 2000 is used for palette writes which appears to be a RAMDAC, no auto-inc.
214      if (mode!=0x2000 && mode != 0xe000) state->m_write_address+=0x10;
319      //  1ff80806 is our 'spritelist'
320      if (mode!=0x2000 && mode != 0xe000 && addr != 0x1ff80806) state->m_write_address+=0x10;
215321      littlerb_recalc_regs(machine);
216322   }
217323
r17588r17589
245351   return res;
246352}
247353
248#define LOG_VDP
354#define LOG_VDP 1
249355WRITE16_MEMBER(littlerb_state::littlerb_vdp_w)
250356{
251357
r17588r17589
256362         if (m_type2_writes>2)
257363         {
258364            if (LOG_VDP) logerror("******************************* BIG WRITE OCCURRED BEFORE THIS!!! ****************************\n");
259            printf("big write occured with start %08x end %08x\n", m_write_address_laststart >> 3, m_write_address_lastend >> 3);
260365         }
261366
367         littlerb_printf("~%06x big write occured with start %08x end %08x (size %04x bytes)\n", m_lasttype2pc, m_write_address_laststart >> 3, m_write_address_lastend >> 3, m_type2_writes*2);
368
262369         if (LOG_VDP) logerror("~%06x previously wrote %08x data bytes\n", m_lasttype2pc, m_type2_writes*2);
263370         m_type2_writes = 0;
264371      }
r17588r17589
305412      case 3:
306413         COMBINE_DATA(&m_vdp_writemode);
307414         int mode = m_vdp_writemode;
308         if ((mode!=0x3800) && (mode !=0x2000)) printf("WRITE MODE CHANGED TO %04x\n",mode);
415         if ((mode!=0x3800) && (mode !=0x2000)) logerror("WRITE MODE CHANGED TO %04x\n",mode);
309416      break;
310417
311418   }
r17588r17589
438545INPUT_PORTS_END
439546
440547
548
549/* sprite format / offset could be completely wrong, this is just based on our (currently incorrect) vram access */
550static SCREEN_UPDATE_IND16(littlerb)
551{
552   littlerb_state *state = screen.machine().driver_data<littlerb_state>();
553   bitmap.fill(0, cliprect);
554
555   copybitmap_trans(bitmap, state->m_temp_bitmap_sprites_back, 0, 0, 0, 0, cliprect, 0);
556   copybitmap_trans(bitmap, state->m_temp_bitmap_sprites, 0, 0, 0, 0, cliprect, 0);
557
558   return 0;
559}
560
561static TIMER_DEVICE_CALLBACK( littlerb_scanline )
562{
563   littlerb_state *state = timer.machine().driver_data<littlerb_state>();
564   int scanline = param;
565
566   if((scanline % 2) == 0)
567   {
568      UINT8 res;
569      UINT8 *sample_rom = state->memregion("samples")->base();
570
571      res = sample_rom[state->m_sound_pointer_l|(state->m_sound_index_l<<10)|0x40000];
572      state->m_dacl->write_signed8(res);
573      res = sample_rom[state->m_sound_pointer_r|(state->m_sound_index_r<<10)|0x00000];
574      state->m_dacr->write_signed8(res);
575      state->m_sound_pointer_l++;
576      state->m_sound_pointer_l&=0x3ff;
577      state->m_sound_pointer_r++;
578      state->m_sound_pointer_r&=0x3ff;
579   }
580
581//  logerror("IRQ\n");
582   if(scanline == 256)
583   {
584      device_set_input_line(state->m_maincpu, 4, HOLD_LINE);
585   }
586}
587
588VIDEO_START( littlerb )
589{
590   littlerb_state *state = machine.driver_data<littlerb_state>();
591
592
593   machine.primary_screen->register_screen_bitmap(state->m_temp_bitmap_sprites_back);
594   machine.primary_screen->register_screen_bitmap(state->m_temp_bitmap_sprites);
595   state->m_spritelist = (UINT16*)auto_alloc_array_clear(machine, UINT16, 0x20000);
596
597}
598
599
600
601
441602static void draw_sprite(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int xsize,int ysize, UINT32 fulloffs, int xpos, int ypos )
442603{
443604   int x,y;
r17588r17589
466627   }
467628}
468629
469/* sprite format / offset could be completely wrong, this is just based on our (currently incorrect) vram access */
470static SCREEN_UPDATE_IND16(littlerb)
630static void littlerb_draw_sprites(running_machine &machine)
471631{
472   littlerb_state *state = screen.machine().driver_data<littlerb_state>();
632   littlerb_state *state = machine.driver_data<littlerb_state>();
473633   int x,y,offs;
474634   int xsize,ysize;
475   UINT16* spriteregion = &state->m_region4[0x400];
476   bitmap.fill(get_black_pen(screen.machine()), cliprect);
477   //printf("frame\n");
635   UINT16* spriteregion = state->m_spritelist;
636   //littlerb_printf("frame\n");
478637   /* the spriteram format is something like this .. */
479   for (offs=0x26/2;offs<0xc00;offs+=6) // start at 00x26?
638//   for (offs=2;offs<0xc00;offs+=6) // this will draw different hud gfx.. meaning not ALL entries are 6 words(?!) command based blitter rather than RAM? (but MODE is 3800 when both the sprite 'list' is written, and gfx data?,
639
640   int layer = 0;
641
642
643   littlerb_printf("m_listoffset %04x\n", state->m_listoffset );
644
645   littlerb_printf("%04x %04x %04x %04x\n", spriteregion[0], spriteregion[1], spriteregion[2], spriteregion[3]);
646
647   littlerb_alt_printf("start\n");
648
649   for (offs=0;offs<(state->m_listoffset);)
480650   {
481      x = spriteregion[offs+2] & 0x01ff;
482      ysize = (spriteregion[offs+5] & 0x007f);
483      y = (spriteregion[offs+3] & 0x01ff); // 1?
484      xsize = (spriteregion[offs+4] & 0x00ff);
485651
486      UINT32 fullcode = ((spriteregion[offs+1])<<16)+ (spriteregion[offs+0]);
487652
488      //printf( "sprite %08x\n", fullcode);
653      UINT32 read_dword = ((spriteregion[offs+1])<<16)+ (spriteregion[offs+0]);
489654
490      //if (code!=0) printf("%04x %04x %04x %04x %04x %04x\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5]);
655      littlerb_printf("read %08x\n", read_dword);
491656
492      draw_sprite(screen.machine(),bitmap, cliprect,xsize,ysize,fullcode,x-8,y-16);
493   }
657      // some kind of control words?? (layer selection, layer scrolls?, layer clears?)
658      // but the low bits are the sprite offset??? how can this work
659      if (spriteregion[offs+0] == 0x0060)
660      {
661         offs += 6;
494662
495   return 0;
496}
663      }
664      else if (spriteregion[offs+0] == 0x0040)
665      {
666         littlerb_alt_printf("Control Word %04x %04x %04x %04x %04x %04x ---- ---- ---- ----\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5]);
667         
668         // some scroll stuff is here (title -> high score transition)
669         // maybe also copy area operations?
497670
498static TIMER_DEVICE_CALLBACK( littlerb_scanline )
499{
500   littlerb_state *state = timer.machine().driver_data<littlerb_state>();
501   int scanline = param;
671         // probably wrong
672         if ((spriteregion[offs+4]==0x6000) && (spriteregion[offs+3] & 0x1000))
673            state->m_temp_bitmap_sprites_back.fill(0, state->m_temp_bitmap_sprites_back.cliprect());
674         else
675            state->m_temp_bitmap_sprites.fill(0, state->m_temp_bitmap_sprites.cliprect());
502676
503   if((scanline % 2) == 0)
504   {
505      UINT8 res;
506      UINT8 *sample_rom = state->memregion("samples")->base();
507677
508      res = sample_rom[state->m_sound_pointer_l|(state->m_sound_index_l<<10)|0x40000];
509      state->m_dacl->write_signed8(res);
510      res = sample_rom[state->m_sound_pointer_r|(state->m_sound_index_r<<10)|0x00000];
511      state->m_dacr->write_signed8(res);
512      state->m_sound_pointer_l++;
513      state->m_sound_pointer_l&=0x3ff;
514      state->m_sound_pointer_r++;
515      state->m_sound_pointer_r&=0x3ff;
516   }
678         offs += 6;
679      }
680      else if (read_dword == 0x00e40020)
681      {
682         littlerb_alt_printf("Control Word %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5], spriteregion[offs+6], spriteregion[offs+7], spriteregion[offs+8], spriteregion[offs+9]);
683     
684         if (spriteregion[offs+4]==0x6000)
685            layer = 1;
686         else
687            layer = 0;
517688
518//  logerror("IRQ\n");
519   if(scanline == 256)
520   {
521      device_set_input_line(state->m_maincpu, 4, HOLD_LINE);
689
690         offs += 10;
691      }
692      else if (read_dword == 0x00e40000)
693      {
694         littlerb_alt_printf("Control Word %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5], spriteregion[offs+6], spriteregion[offs+7], spriteregion[offs+8], spriteregion[offs+9]);
695   
696         if (spriteregion[offs+4]==0x6000)
697            layer = 1;
698         else
699            layer = 0;
700         
701         offs += 10;
702      }
703      else if (read_dword == 0x00000000)
704      {
705         offs += 1;
706      }
707      else
708      {
709         UINT32 fullcode = ((spriteregion[offs+1])<<16)+ (spriteregion[offs+0]);
710
711         x = spriteregion[offs+2] & 0x07ff;
712         y = (spriteregion[offs+3] & 0x03ff); // 1?
713
714         if (x&0x400) x-=0x800;
715         if (y&0x200) y-=0x400;
716
717         xsize = (spriteregion[offs+4] & 0x01ff); // background gfx for many places at 0x1ff wide
718         ysize = (spriteregion[offs+5] & 0x00ff); // player1/player2 texts in service mode sides are 0xff high
719
720
721         littlerb_alt_printf("%04x %04x %04x %04x %04x %04x\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5]);
722
723         if (layer==0) draw_sprite(machine, state->m_temp_bitmap_sprites, state->m_temp_bitmap_sprites.cliprect(),xsize,ysize,fullcode,x,y);
724         else draw_sprite(machine, state->m_temp_bitmap_sprites_back, state->m_temp_bitmap_sprites_back.cliprect(),xsize,ysize,fullcode,x,y);
725
726           
727         offs += 6;
728      }
522729   }
523730}
524731
732
733
525734static MACHINE_CONFIG_START( littlerb, littlerb_state )
526735   MCFG_CPU_ADD("maincpu", M68000, 12000000)
527736   MCFG_CPU_PROGRAM_MAP(littlerb_main)
528737   MCFG_TIMER_ADD_SCANLINE("scantimer", littlerb_scanline, "screen", 0, 1)
529738
530739   MCFG_SCREEN_ADD("screen", RASTER)
531   MCFG_SCREEN_REFRESH_RATE(60)
740   MCFG_SCREEN_REFRESH_RATE(50) // guess based on high vertical resolution
532741   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
533   MCFG_SCREEN_SIZE(512, 262)
534   MCFG_SCREEN_VISIBLE_AREA(0*8, 320-1, 0*8, 256-1)
742   MCFG_SCREEN_SIZE(512, 288)
743   MCFG_SCREEN_VISIBLE_AREA(0*8, 336-1, 0*8, 288-1)
535744   MCFG_SCREEN_UPDATE_STATIC(littlerb)
536745
746   MCFG_VIDEO_START(littlerb)
747
537748   MCFG_PALETTE_LENGTH(0x100)
538749
539750   MCFG_DEVICE_ADD("littlerbvdp", LITTLERBVDP, 0)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team