Previous 199869 Revisions Next

r22898 Saturday 18th May, 2013 at 15:06:14 UTC by Fabio Priuli
(MESS) gameboy: modernized sound emulation and added save state [Fabio Priuli]
[src/mess/audio]gb.c gb.h
[src/mess/drivers]gb.c gba.c
[src/mess/includes]gb.h gba.h
[src/mess/machine]gb.c

trunk/src/mess/drivers/gba.c
r22897r22898
746746         }
747747         break;
748748      case 0x0060/4:
749         retval = gb_sound_r(m_gbsound, space, 0) | gb_sound_r(m_gbsound, space, 1)<<16 | gb_sound_r(m_gbsound, space, 2)<<24;
749         retval = m_gbsound->sound_r(space, 0) | m_gbsound->sound_r(space, 1)<<16 | m_gbsound->sound_r(space, 2)<<24;
750750         break;
751751      case 0x0064/4:
752         retval = gb_sound_r(m_gbsound, space, 3) | gb_sound_r(m_gbsound, space, 4)<<8;
752         retval = m_gbsound->sound_r(space, 3) | m_gbsound->sound_r(space, 4)<<8;
753753         break;
754754      case 0x0068/4:
755         retval = gb_sound_r(m_gbsound, space, 6) | gb_sound_r(m_gbsound, space, 7)<<8;
755         retval = m_gbsound->sound_r(space, 6) | m_gbsound->sound_r(space, 7)<<8;
756756         break;
757757      case 0x006c/4:
758         retval = gb_sound_r(m_gbsound, space, 8) | gb_sound_r(m_gbsound, space, 9)<<8;
758         retval = m_gbsound->sound_r(space, 8) | m_gbsound->sound_r(space, 9)<<8;
759759         break;
760760      case 0x0070/4:
761         retval = gb_sound_r(m_gbsound, space, 0xa) | gb_sound_r(m_gbsound, space, 0xb)<<16 | gb_sound_r(m_gbsound, space, 0xc)<<24;
761         retval = m_gbsound->sound_r(space, 0xa) | m_gbsound->sound_r(space, 0xb)<<16 | m_gbsound->sound_r(space, 0xc)<<24;
762762         break;
763763      case 0x0074/4:
764         retval = gb_sound_r(m_gbsound, space, 0xd) | gb_sound_r(m_gbsound, space, 0xe)<<8;
764         retval = m_gbsound->sound_r(space, 0xd) | m_gbsound->sound_r(space, 0xe)<<8;
765765         break;
766766      case 0x0078/4:
767         retval = gb_sound_r(m_gbsound, space, 0x10) | gb_sound_r(m_gbsound, space, 0x11)<<8;
767         retval = m_gbsound->sound_r(space, 0x10) | m_gbsound->sound_r(space, 0x11)<<8;
768768         break;
769769      case 0x007c/4:
770         retval = gb_sound_r(m_gbsound, space, 0x12) | gb_sound_r(m_gbsound, space, 0x13)<<8;
770         retval = m_gbsound->sound_r(space, 0x12) | m_gbsound->sound_r(space, 0x13)<<8;
771771         break;
772772      case 0x0080/4:
773         retval = gb_sound_r(m_gbsound, space, 0x14) | gb_sound_r(m_gbsound, space, 0x15)<<8;
773         retval = m_gbsound->sound_r(space, 0x14) | m_gbsound->sound_r(space, 0x15)<<8;
774774         if( (mem_mask) & 0xffff0000 )
775775         {
776776            verboselog(machine(), 2, "GBA IO Register Read: SOUNDCNT_H (%08x) = %04x\n", 0x04000000 + ( offset << 2 ) + 2, m_SOUNDCNT_H );
r22897r22898
778778         }
779779         break;
780780      case 0x0084/4:
781         retval = gb_sound_r(m_gbsound, space, 0x16);
781         retval = m_gbsound->sound_r(space, 0x16);
782782         break;
783783      case 0x0088/4:
784784         if( (mem_mask) & 0x0000ffff )
r22897r22898
792792         }
793793         break;
794794      case 0x0090/4:
795         retval = gb_wave_r(m_gbsound, space, 0) | gb_wave_r(m_gbsound, space, 1)<<8 | gb_wave_r(m_gbsound, space, 2)<<16 | gb_wave_r(m_gbsound, space, 3)<<24;
795         retval = m_gbsound->wave_r(space, 0) | m_gbsound->wave_r(space, 1)<<8 | m_gbsound->wave_r(space, 2)<<16 | m_gbsound->wave_r(space, 3)<<24;
796796         break;
797797      case 0x0094/4:
798         retval = gb_wave_r(m_gbsound, space, 4) | gb_wave_r(m_gbsound, space, 5)<<8 | gb_wave_r(m_gbsound, space, 6)<<16 | gb_wave_r(m_gbsound, space, 7)<<24;
798         retval = m_gbsound->wave_r(space, 4) | m_gbsound->wave_r(space, 5)<<8 | m_gbsound->wave_r(space, 6)<<16 | m_gbsound->wave_r(space, 7)<<24;
799799         break;
800800      case 0x0098/4:
801         retval = gb_wave_r(m_gbsound, space, 8) | gb_wave_r(m_gbsound, space, 9)<<8 | gb_wave_r(m_gbsound, space, 10)<<16 | gb_wave_r(m_gbsound, space, 11)<<24;
801         retval = m_gbsound->wave_r(space, 8) | m_gbsound->wave_r(space, 9)<<8 | m_gbsound->wave_r(space, 10)<<16 | m_gbsound->wave_r(space, 11)<<24;
802802         break;
803803      case 0x009c/4:
804         retval = gb_wave_r(m_gbsound, space, 12) | gb_wave_r(m_gbsound, space, 13)<<8 | gb_wave_r(m_gbsound, space, 14)<<16 | gb_wave_r(m_gbsound, space, 15)<<24;
804         retval = m_gbsound->wave_r(space, 12) | m_gbsound->wave_r(space, 13)<<8 | m_gbsound->wave_r(space, 14)<<16 | m_gbsound->wave_r(space, 15)<<24;
805805         break;
806806      case 0x00a0/4:
807807      case 0x00a4/4:
r22897r22898
13211321      case 0x0060/4:
13221322         if( (mem_mask) & 0x000000ff )   // SOUNDCNTL
13231323         {
1324            gb_sound_w(m_gbsound, space, 0, data);
1324            m_gbsound->sound_w(space, 0, data);
13251325         }
13261326         if( (mem_mask) & 0x00ff0000 )
13271327         {
1328            gb_sound_w(m_gbsound, space, 1, data>>16);  // SOUND1CNT_H
1328            m_gbsound->sound_w(space, 1, data>>16);  // SOUND1CNT_H
13291329         }
13301330         if( (mem_mask) & 0xff000000 )
13311331         {
1332            gb_sound_w(m_gbsound, space, 2, data>>24);
1332            m_gbsound->sound_w(space, 2, data>>24);
13331333         }
13341334         break;
13351335      case 0x0064/4:
13361336         if( (mem_mask) & 0x000000ff )   // SOUNDCNTL
13371337         {
1338            gb_sound_w(m_gbsound, space, 3, data);
1338            m_gbsound->sound_w(space, 3, data);
13391339         }
13401340         if( (mem_mask) & 0x0000ff00 )
13411341         {
1342            gb_sound_w(m_gbsound, space, 4, data>>8);   // SOUND1CNT_H
1342            m_gbsound->sound_w(space, 4, data>>8);   // SOUND1CNT_H
13431343         }
13441344         break;
13451345      case 0x0068/4:
13461346         if( (mem_mask) & 0x000000ff )
13471347         {
1348            gb_sound_w(m_gbsound, space, 6, data);
1348            m_gbsound->sound_w(space, 6, data);
13491349         }
13501350         if( (mem_mask) & 0x0000ff00 )
13511351         {
1352            gb_sound_w(m_gbsound, space, 7, data>>8);
1352            m_gbsound->sound_w(space, 7, data>>8);
13531353         }
13541354         break;
13551355      case 0x006c/4:
13561356         if( (mem_mask) & 0x000000ff )
13571357         {
1358            gb_sound_w(m_gbsound, space, 8, data);
1358            m_gbsound->sound_w(space, 8, data);
13591359         }
13601360         if( (mem_mask) & 0x0000ff00 )
13611361         {
1362            gb_sound_w(m_gbsound, space, 9, data>>8);
1362            m_gbsound->sound_w(space, 9, data>>8);
13631363         }
13641364         break;
13651365      case 0x0070/4:  //SND3CNTL and H
13661366         if( (mem_mask) & 0x000000ff )   // SOUNDCNTL
13671367         {
1368            gb_sound_w(m_gbsound, space, 0xa, data);
1368            m_gbsound->sound_w(space, 0xa, data);
13691369         }
13701370         if( (mem_mask) & 0x00ff0000 )
13711371         {
1372            gb_sound_w(m_gbsound, space, 0xb, data>>16);    // SOUND1CNT_H
1372            m_gbsound->sound_w(space, 0xb, data>>16);    // SOUND1CNT_H
13731373         }
13741374         if( (mem_mask) & 0xff000000 )
13751375         {
1376            gb_sound_w(m_gbsound, space, 0xc, data>>24);
1376            m_gbsound->sound_w(space, 0xc, data>>24);
13771377         }
13781378         break;
13791379      case 0x0074/4:
13801380         if( (mem_mask) & 0x000000ff )
13811381         {
1382            gb_sound_w(m_gbsound, space, 0xd, data);
1382            m_gbsound->sound_w(space, 0xd, data);
13831383         }
13841384         if( (mem_mask) & 0x0000ff00 )
13851385         {
1386            gb_sound_w(m_gbsound, space, 0xe, data>>8);
1386            m_gbsound->sound_w(space, 0xe, data>>8);
13871387         }
13881388         break;
13891389      case 0x0078/4:
13901390         if( (mem_mask) & 0x000000ff )
13911391         {
1392            gb_sound_w(m_gbsound, space, 0x10, data);
1392            m_gbsound->sound_w(space, 0x10, data);
13931393         }
13941394         if( (mem_mask) & 0x0000ff00 )
13951395         {
1396            gb_sound_w(m_gbsound, space, 0x11, data>>8);
1396            m_gbsound->sound_w(space, 0x11, data>>8);
13971397         }
13981398         break;
13991399      case 0x007c/4:
14001400         if( (mem_mask) & 0x000000ff )
14011401         {
1402            gb_sound_w(m_gbsound, space, 0x12, data);
1402            m_gbsound->sound_w(space, 0x12, data);
14031403         }
14041404         if( (mem_mask) & 0x0000ff00 )
14051405         {
1406            gb_sound_w(m_gbsound, space, 0x13, data>>8);
1406            m_gbsound->sound_w(space, 0x13, data>>8);
14071407         }
14081408         break;
14091409      case 0x0080/4:
14101410         if( (mem_mask) & 0x000000ff )
14111411         {
1412            gb_sound_w(m_gbsound, space, 0x14, data);
1412            m_gbsound->sound_w(space, 0x14, data);
14131413         }
14141414         if( (mem_mask) & 0x0000ff00 )
14151415         {
1416            gb_sound_w(m_gbsound, space, 0x15, data>>8);
1416            m_gbsound->sound_w(space, 0x15, data>>8);
14171417         }
14181418
14191419         if ((mem_mask) & 0xffff0000)
r22897r22898
14431443      case 0x0084/4:
14441444         if( (mem_mask) & 0x000000ff )
14451445         {
1446            gb_sound_w(m_gbsound, space, 0x16, data);
1446            m_gbsound->sound_w(space, 0x16, data);
14471447            if ((data & 0x80) && !(m_SOUNDCNT_X & 0x80))
14481448            {
14491449               m_fifo_a_ptr = m_fifo_a_in = 17;
r22897r22898
14701470      case 0x0090/4:
14711471         if( (mem_mask) & 0x000000ff )
14721472         {
1473            gb_wave_w(m_gbsound, space, 0, data);
1473            m_gbsound->wave_w(space, 0, data);
14741474         }
14751475         if( (mem_mask) & 0x0000ff00 )
14761476         {
1477            gb_wave_w(m_gbsound, space, 1, data>>8);
1477            m_gbsound->wave_w(space, 1, data>>8);
14781478         }
14791479         if( (mem_mask) & 0x00ff0000 )
14801480         {
1481            gb_wave_w(m_gbsound, space, 2, data>>16);
1481            m_gbsound->wave_w(space, 2, data>>16);
14821482         }
14831483         if( (mem_mask) & 0xff000000 )
14841484         {
1485            gb_wave_w(m_gbsound, space, 3, data>>24);
1485            m_gbsound->wave_w(space, 3, data>>24);
14861486         }
14871487         break;
14881488      case 0x0094/4:
14891489         if( (mem_mask) & 0x000000ff )
14901490         {
1491            gb_wave_w(m_gbsound, space, 4, data);
1491            m_gbsound->wave_w(space, 4, data);
14921492         }
14931493         if( (mem_mask) & 0x0000ff00 )
14941494         {
1495            gb_wave_w(m_gbsound, space, 5, data>>8);
1495            m_gbsound->wave_w(space, 5, data>>8);
14961496         }
14971497         if( (mem_mask) & 0x00ff0000 )
14981498         {
1499            gb_wave_w(m_gbsound, space, 6, data>>16);
1499            m_gbsound->wave_w(space, 6, data>>16);
15001500         }
15011501         if( (mem_mask) & 0xff000000 )
15021502         {
1503            gb_wave_w(m_gbsound, space, 7, data>>24);
1503            m_gbsound->wave_w(space, 7, data>>24);
15041504         }
15051505         break;
15061506      case 0x0098/4:
15071507         if( (mem_mask) & 0x000000ff )
15081508         {
1509            gb_wave_w(m_gbsound, space, 8, data);
1509            m_gbsound->wave_w(space, 8, data);
15101510         }
15111511         if( (mem_mask) & 0x0000ff00 )
15121512         {
1513            gb_wave_w(m_gbsound, space, 9, data>>8);
1513            m_gbsound->wave_w(space, 9, data>>8);
15141514         }
15151515         if( (mem_mask) & 0x00ff0000 )
15161516         {
1517            gb_wave_w(m_gbsound, space, 0xa, data>>16);
1517            m_gbsound->wave_w(space, 0xa, data>>16);
15181518         }
15191519         if( (mem_mask) & 0xff000000 )
15201520         {
1521            gb_wave_w(m_gbsound, space, 0xb, data>>24);
1521            m_gbsound->wave_w(space, 0xb, data>>24);
15221522         }
15231523         break;
15241524      case 0x009c/4:
15251525         if( (mem_mask) & 0x000000ff )
15261526         {
1527            gb_wave_w(m_gbsound, space, 0xc, data);
1527            m_gbsound->wave_w(space, 0xc, data);
15281528         }
15291529         if( (mem_mask) & 0x0000ff00 )
15301530         {
1531            gb_wave_w(m_gbsound, space, 0xd, data>>8);
1531            m_gbsound->wave_w(space, 0xd, data>>8);
15321532         }
15331533         if( (mem_mask) & 0x00ff0000 )
15341534         {
1535            gb_wave_w(m_gbsound, space, 0xe, data>>16);
1535            m_gbsound->wave_w(space, 0xe, data>>16);
15361536         }
15371537         if( (mem_mask) & 0xff000000 )
15381538         {
1539            gb_wave_w(m_gbsound, space, 0xf, data>>24);
1539            m_gbsound->wave_w(space, 0xf, data>>24);
15401540         }
15411541         break;
15421542      case 0x00a0/4:
trunk/src/mess/drivers/gb.c
r22897r22898
556556static ADDRESS_MAP_START(gameboy_map, AS_PROGRAM, 8, gb_state )
557557   ADDRESS_MAP_UNMAP_HIGH
558558   AM_RANGE(0x0000, 0x7fff) AM_READWRITE(gb_cart_r, gb_bank_w)
559   AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w )  /* 8k VRAM */
560   AM_RANGE(0xa000, 0xbfff) AM_READWRITE(gb_ram_r, gb_ram_w )    /* 8k switched RAM bank (cartridge) */
559   AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w)  /* 8k VRAM */
560   AM_RANGE(0xa000, 0xbfff) AM_READWRITE(gb_ram_r, gb_ram_w)    /* 8k switched RAM bank (cartridge) */
561561   AM_RANGE(0xc000, 0xdfff) AM_RAM                               /* 8k low RAM */
562   AM_RANGE(0xe000, 0xfdff) AM_READWRITE(gb_echo_r, gb_echo_w )  /* echo RAM */
563   AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w )    /* OAM RAM */
564   AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, gb_io_w )      /* I/O */
565   AM_RANGE(0xff10, 0xff26) AM_DEVREADWRITE_LEGACY("custom", gb_sound_r, gb_sound_w )      /* sound registers */
562   AM_RANGE(0xe000, 0xfdff) AM_READWRITE(gb_echo_r, gb_echo_w)  /* echo RAM */
563   AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w)    /* OAM RAM */
564   AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, gb_io_w)      /* I/O */
565   AM_RANGE(0xff10, 0xff26) AM_DEVREADWRITE("custom", gameboy_sound_device, sound_r, sound_w)      /* sound registers */
566566   AM_RANGE(0xff27, 0xff2f) AM_NOP                     /* unused */
567   AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE_LEGACY("custom", gb_wave_r, gb_wave_w )        /* Wave ram */
567   AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE("custom", gameboy_sound_device, wave_r, wave_w)        /* Wave ram */
568568   AM_RANGE(0xff40, 0xff7f) AM_READWRITE(gb_video_r, gb_io2_w)     /* Video controller & BIOS flip-flop */
569569   AM_RANGE(0xff80, 0xfffe) AM_RAM                     /* High RAM */
570   AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w )        /* Interrupt enable register */
570   AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w)        /* Interrupt enable register */
571571ADDRESS_MAP_END
572572
573573static ADDRESS_MAP_START(sgb_map, AS_PROGRAM, 8, gb_state )
574574   ADDRESS_MAP_UNMAP_HIGH
575575   AM_RANGE(0x0000, 0x7fff) AM_READWRITE(gb_cart_r, gb_bank_w)
576   AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w )  /* 8k VRAM */
577   AM_RANGE(0xa000, 0xbfff) AM_READWRITE(gb_ram_r, gb_ram_w )    /* 8k switched RAM bank (cartridge) */
576   AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w)  /* 8k VRAM */
577   AM_RANGE(0xa000, 0xbfff) AM_READWRITE(gb_ram_r, gb_ram_w)    /* 8k switched RAM bank (cartridge) */
578578   AM_RANGE(0xc000, 0xdfff) AM_RAM                               /* 8k low RAM */
579   AM_RANGE(0xe000, 0xfdff) AM_READWRITE(gb_echo_r, gb_echo_w )  /* echo RAM */
580   AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w )    /* OAM RAM */
581   AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, sgb_io_w )     /* I/O */
582   AM_RANGE(0xff10, 0xff26) AM_DEVREADWRITE_LEGACY("custom", gb_sound_r, gb_sound_w )      /* sound registers */
579   AM_RANGE(0xe000, 0xfdff) AM_READWRITE(gb_echo_r, gb_echo_w)  /* echo RAM */
580   AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w)    /* OAM RAM */
581   AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, sgb_io_w)     /* I/O */
582   AM_RANGE(0xff10, 0xff26) AM_DEVREADWRITE("custom", gameboy_sound_device, sound_r, sound_w)      /* sound registers */
583583   AM_RANGE(0xff27, 0xff2f) AM_NOP                     /* unused */
584   AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE_LEGACY("custom", gb_wave_r, gb_wave_w )        /* Wave RAM */
585   AM_RANGE(0xff40, 0xff7f) AM_READWRITE(gb_video_r, gb_io2_w )        /* Video controller & BIOS flip-flop */
584   AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE("custom", gameboy_sound_device, wave_r, wave_w)        /* Wave RAM */
585   AM_RANGE(0xff40, 0xff7f) AM_READWRITE(gb_video_r, gb_io2_w)        /* Video controller & BIOS flip-flop */
586586   AM_RANGE(0xff80, 0xfffe) AM_RAM                     /* High RAM */
587   AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w )        /* Interrupt enable register */
587   AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w)        /* Interrupt enable register */
588588ADDRESS_MAP_END
589589
590590static ADDRESS_MAP_START(gbc_map, AS_PROGRAM, 8, gb_state )
591591   ADDRESS_MAP_UNMAP_HIGH
592592   AM_RANGE(0x0000, 0x7fff) AM_READWRITE(gbc_cart_r, gb_bank_w)
593   AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w ) /* 8k VRAM */
594   AM_RANGE(0xa000, 0xbfff) AM_READWRITE(gb_ram_r, gb_ram_w )   /* 8k switched RAM bank (cartridge) */
593   AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w) /* 8k VRAM */
594   AM_RANGE(0xa000, 0xbfff) AM_READWRITE(gb_ram_r, gb_ram_w)   /* 8k switched RAM bank (cartridge) */
595595   AM_RANGE(0xc000, 0xcfff) AM_RAM                     /* 4k fixed RAM bank */
596596   AM_RANGE(0xd000, 0xdfff) AM_RAMBANK("cgb_ram")                    /* 4k switched RAM bank */
597   AM_RANGE(0xe000, 0xfdff) AM_READWRITE(gb_echo_r, gb_echo_w )  /* echo RAM */
598   AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w )  /* OAM RAM */
599   AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, gb_io_w )        /* I/O */
600   AM_RANGE(0xff10, 0xff26) AM_DEVREADWRITE_LEGACY("custom", gb_sound_r, gb_sound_w )      /* sound controller */
597   AM_RANGE(0xe000, 0xfdff) AM_READWRITE(gb_echo_r, gb_echo_w)  /* echo RAM */
598   AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w)  /* OAM RAM */
599   AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, gb_io_w)        /* I/O */
600   AM_RANGE(0xff10, 0xff26) AM_DEVREADWRITE("custom", gameboy_sound_device, sound_r, sound_w)      /* sound controller */
601601   AM_RANGE(0xff27, 0xff2f) AM_NOP                     /* unused */
602   AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE_LEGACY("custom", gb_wave_r, gb_wave_w )        /* Wave RAM */
603   AM_RANGE(0xff40, 0xff7f) AM_READWRITE(gbc_io2_r, gbc_io2_w )        /* Other I/O and video controller */
602   AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE("custom", gameboy_sound_device, wave_r, wave_w)        /* Wave RAM */
603   AM_RANGE(0xff40, 0xff7f) AM_READWRITE(gbc_io2_r, gbc_io2_w)        /* Other I/O and video controller */
604604   AM_RANGE(0xff80, 0xfffe) AM_RAM                     /* high RAM */
605   AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w )        /* Interrupt enable register */
605   AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w)        /* Interrupt enable register */
606606ADDRESS_MAP_END
607607
608608static ADDRESS_MAP_START(megaduck_map, AS_PROGRAM, 8, megaduck_state )
609609   ADDRESS_MAP_UNMAP_HIGH
610610   AM_RANGE(0x0000, 0x7fff) AM_READWRITE(cart_r, bank1_w)
611   AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w )        /* 8k VRAM */
611   AM_RANGE(0x8000, 0x9fff) AM_READWRITE(gb_vram_r, gb_vram_w)        /* 8k VRAM */
612612   AM_RANGE(0xa000, 0xafff) AM_NOP                         /* unused? */
613613   AM_RANGE(0xb000, 0xb000) AM_WRITE(bank2_w)
614614   AM_RANGE(0xb001, 0xbfff) AM_NOP                         /* unused? */
615615   AM_RANGE(0xc000, 0xfe9f) AM_RAM                         /* 8k low RAM, echo RAM */
616   AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w )      /* OAM RAM */
617   AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, gb_io_w )            /* I/O */
618   AM_RANGE(0xff10, 0xff1f) AM_READWRITE(megaduck_video_r, megaduck_video_w )  /* video controller */
616   AM_RANGE(0xfe00, 0xfeff) AM_READWRITE(gb_oam_r, gb_oam_w)      /* OAM RAM */
617   AM_RANGE(0xff00, 0xff0f) AM_READWRITE(gb_io_r, gb_io_w)            /* I/O */
618   AM_RANGE(0xff10, 0xff1f) AM_READWRITE(megaduck_video_r, megaduck_video_w)  /* video controller */
619619   AM_RANGE(0xff20, 0xff2f) AM_READWRITE(megaduck_sound_r1, megaduck_sound_w1) /* sound controller pt1 */
620   AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE_LEGACY("custom", gb_wave_r, gb_wave_w )            /* wave ram */
620   AM_RANGE(0xff30, 0xff3f) AM_DEVREADWRITE("custom", gameboy_sound_device, wave_r, wave_w)            /* wave ram */
621621   AM_RANGE(0xff40, 0xff46) AM_READWRITE(megaduck_sound_r2, megaduck_sound_w2) /* sound controller pt2 */
622622   AM_RANGE(0xff47, 0xff7f) AM_NOP                         /* unused */
623623   AM_RANGE(0xff80, 0xfffe) AM_RAM                         /* high RAM */
624   AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w )            /* interrupt enable register */
624   AM_RANGE(0xffff, 0xffff) AM_READWRITE(gb_ie_r, gb_ie_w)            /* interrupt enable register */
625625ADDRESS_MAP_END
626626
627627static GFXDECODE_START( gb )
trunk/src/mess/audio/gb.c
r22897r22898
8787
8888#define LEFT 1
8989#define RIGHT 2
90#define MAX_FREQUENCIES 2048
9190#define FIXED_POINT 16
9291
9392/* Represents wave duties of 12.5%, 25%, 50% and 75% */
9493static const float wave_duty_table[4] = { 8.0f, 4.0f, 2.0f, 1.33f };
9594
95// device type definition
96const device_type GAMEBOY = &device_creator<gameboy_sound_device>;
9697
97/***************************************************************************
98    TYPE DEFINITIONS
99***************************************************************************/
98//**************************************************************************
99//  LIVE DEVICE
100//**************************************************************************
100101
101struct SOUND
102{
103   /* Common */
104   UINT8  on;
105   UINT8  channel;
106   INT32  length;
107   INT32  pos;
108   UINT32 period;
109   INT32  count;
110   INT8   mode;
111   /* Mode 1, 2, 3 */
112   INT8   duty;
113   /* Mode 1, 2, 4 */
114   INT32  env_value;
115   INT8   env_direction;
116   INT32  env_length;
117   INT32  env_count;
118   INT8   signal;
119   /* Mode 1 */
120   UINT32 frequency;
121   INT32  swp_shift;
122   INT32  swp_direction;
123   INT32  swp_time;
124   INT32  swp_count;
125   /* Mode 3 */
126   INT8   level;
127   UINT8  offset;
128   UINT32 dutycount;
129   /* Mode 4 */
130   INT32  ply_step;
131   INT16  ply_value;
132};
102//-------------------------------------------------
103//  gameboy_sound_device - constructor
104//-------------------------------------------------
133105
134struct SOUNDC
106gameboy_sound_device::gameboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
107               : device_t(mconfig, GAMEBOY, "LR35902", tag, owner, clock),
108                  device_sound_interface(mconfig, *this)
135109{
136   UINT8 on;
137   UINT8 vol_left;
138   UINT8 vol_right;
139   UINT8 mode1_left;
140   UINT8 mode1_right;
141   UINT8 mode2_left;
142   UINT8 mode2_right;
143   UINT8 mode3_left;
144   UINT8 mode3_right;
145   UINT8 mode4_left;
146   UINT8 mode4_right;
147};
110}
148111
112//-------------------------------------------------
113//  device_config_complete - perform any
114//  operations now that the configuration is
115//  complete
116//-------------------------------------------------
149117
150struct gb_sound_t
118void gameboy_sound_device::device_config_complete()
151119{
152   sound_stream *channel;
153   int rate;
120}
154121
155   INT32 env_length_table[8];
156   INT32 swp_time_table[8];
157   UINT32 period_table[MAX_FREQUENCIES];
158   UINT32 period_mode3_table[MAX_FREQUENCIES];
159   UINT32 period_mode4_table[8][16];
160   UINT32 length_table[64];
161   UINT32 length_mode3_table[256];
122//-------------------------------------------------
123//  device_start - device-specific startup
124//-------------------------------------------------
162125
163   struct SOUND  snd_1;
164   struct SOUND  snd_2;
165   struct SOUND  snd_3;
166   struct SOUND  snd_4;
167   struct SOUNDC snd_control;
126void gameboy_sound_device::device_start()
127{   
128   m_channel = machine().sound().stream_alloc(*this, 0, 2, machine().sample_rate(), this);
129   m_rate = machine().sample_rate();
168130
169   UINT8 snd_regs[0x30];
170};
131   save_item(NAME(m_snd_regs));
132   // sound control
133   save_item(NAME(m_snd_control.on));
134   save_item(NAME(m_snd_control.vol_left));
135   save_item(NAME(m_snd_control.vol_right));
136   save_item(NAME(m_snd_control.mode1_left));
137   save_item(NAME(m_snd_control.mode1_right));
138   save_item(NAME(m_snd_control.mode2_left));
139   save_item(NAME(m_snd_control.mode2_right));
140   save_item(NAME(m_snd_control.mode3_left));
141   save_item(NAME(m_snd_control.mode3_right));
142   save_item(NAME(m_snd_control.mode4_left));
143   save_item(NAME(m_snd_control.mode4_right));
144   // sound 1
145   save_item(NAME(m_snd_1.on));
146   save_item(NAME(m_snd_1.channel));
147   save_item(NAME(m_snd_1.length));
148   save_item(NAME(m_snd_1.pos));
149   save_item(NAME(m_snd_1.period));
150   save_item(NAME(m_snd_1.count));
151   save_item(NAME(m_snd_1.mode));
152   save_item(NAME(m_snd_1.duty));
153   save_item(NAME(m_snd_1.env_value));
154   save_item(NAME(m_snd_1.env_direction));
155   save_item(NAME(m_snd_1.env_length));
156   save_item(NAME(m_snd_1.env_count));
157   save_item(NAME(m_snd_1.signal));
158   save_item(NAME(m_snd_1.frequency));
159   save_item(NAME(m_snd_1.swp_shift));
160   save_item(NAME(m_snd_1.swp_direction));
161   save_item(NAME(m_snd_1.swp_time));
162   save_item(NAME(m_snd_1.swp_count));
163   save_item(NAME(m_snd_1.level));
164   save_item(NAME(m_snd_1.offset));
165   save_item(NAME(m_snd_1.dutycount));
166   save_item(NAME(m_snd_1.ply_step));
167   save_item(NAME(m_snd_1.ply_value));
168   // sound 2
169   save_item(NAME(m_snd_2.on));
170   save_item(NAME(m_snd_2.channel));
171   save_item(NAME(m_snd_2.length));
172   save_item(NAME(m_snd_2.pos));
173   save_item(NAME(m_snd_2.period));
174   save_item(NAME(m_snd_2.count));
175   save_item(NAME(m_snd_2.mode));
176   save_item(NAME(m_snd_2.duty));
177   save_item(NAME(m_snd_2.env_value));
178   save_item(NAME(m_snd_2.env_direction));
179   save_item(NAME(m_snd_2.env_length));
180   save_item(NAME(m_snd_2.env_count));
181   save_item(NAME(m_snd_2.signal));
182   save_item(NAME(m_snd_2.frequency));
183   save_item(NAME(m_snd_2.swp_shift));
184   save_item(NAME(m_snd_2.swp_direction));
185   save_item(NAME(m_snd_2.swp_time));
186   save_item(NAME(m_snd_2.swp_count));
187   save_item(NAME(m_snd_2.level));
188   save_item(NAME(m_snd_2.offset));
189   save_item(NAME(m_snd_2.dutycount));
190   save_item(NAME(m_snd_2.ply_step));
191   save_item(NAME(m_snd_2.ply_value));
192   // sound 3
193   save_item(NAME(m_snd_3.on));
194   save_item(NAME(m_snd_3.channel));
195   save_item(NAME(m_snd_3.length));
196   save_item(NAME(m_snd_3.pos));
197   save_item(NAME(m_snd_3.period));
198   save_item(NAME(m_snd_3.count));
199   save_item(NAME(m_snd_3.mode));
200   save_item(NAME(m_snd_3.duty));
201   save_item(NAME(m_snd_3.env_value));
202   save_item(NAME(m_snd_3.env_direction));
203   save_item(NAME(m_snd_3.env_length));
204   save_item(NAME(m_snd_3.env_count));
205   save_item(NAME(m_snd_3.signal));
206   save_item(NAME(m_snd_3.frequency));
207   save_item(NAME(m_snd_3.swp_shift));
208   save_item(NAME(m_snd_3.swp_direction));
209   save_item(NAME(m_snd_3.swp_time));
210   save_item(NAME(m_snd_3.swp_count));
211   save_item(NAME(m_snd_3.level));
212   save_item(NAME(m_snd_3.offset));
213   save_item(NAME(m_snd_3.dutycount));
214   save_item(NAME(m_snd_3.ply_step));
215   save_item(NAME(m_snd_3.ply_value));
216   // sound 4
217   save_item(NAME(m_snd_4.on));
218   save_item(NAME(m_snd_4.channel));
219   save_item(NAME(m_snd_4.length));
220   save_item(NAME(m_snd_4.pos));
221   save_item(NAME(m_snd_4.period));
222   save_item(NAME(m_snd_4.count));
223   save_item(NAME(m_snd_4.mode));
224   save_item(NAME(m_snd_4.duty));
225   save_item(NAME(m_snd_4.env_value));
226   save_item(NAME(m_snd_4.env_direction));
227   save_item(NAME(m_snd_4.env_length));
228   save_item(NAME(m_snd_4.env_count));
229   save_item(NAME(m_snd_4.signal));
230   save_item(NAME(m_snd_4.frequency));
231   save_item(NAME(m_snd_4.swp_shift));
232   save_item(NAME(m_snd_4.swp_direction));
233   save_item(NAME(m_snd_4.swp_time));
234   save_item(NAME(m_snd_4.swp_count));
235   save_item(NAME(m_snd_4.level));
236   save_item(NAME(m_snd_4.offset));
237   save_item(NAME(m_snd_4.dutycount));
238   save_item(NAME(m_snd_4.ply_step));
239   save_item(NAME(m_snd_4.ply_value));
240}
171241
242//-------------------------------------------------
243//  device_reset
244//-------------------------------------------------
172245
173
174/***************************************************************************
175    INLINE FUNCTIONS
176***************************************************************************/
177
178INLINE gb_sound_t *get_token(device_t *device)
246void gameboy_sound_device::device_reset()
179247{
180   assert(device != NULL);
181   assert(device->type() == GAMEBOY);
182   return (gb_sound_t *) downcast<gameboy_sound_device *>(device)->token();
248   memset(&m_snd_1, 0, sizeof(m_snd_1));
249   memset(&m_snd_2, 0, sizeof(m_snd_2));
250   memset(&m_snd_3, 0, sizeof(m_snd_3));
251   memset(&m_snd_4, 0, sizeof(m_snd_4));
252   
253   /* Calculate the envelope and sweep tables */
254   for (int i = 0; i < 8; i++)
255   {
256      m_env_length_table[i] = (i * ((1 << FIXED_POINT) / 64) * m_rate) >> FIXED_POINT;
257      m_swp_time_table[i] = (((i << FIXED_POINT) / 128) * m_rate) >> (FIXED_POINT - 1);
258   }
259   
260   /* Calculate the period tables */
261   for (int i = 0; i < MAX_FREQUENCIES; i++)
262   {
263      m_period_table[i] = ((1 << FIXED_POINT) / (131072 / (2048 - i))) * m_rate;
264      m_period_mode3_table[i] = ((1 << FIXED_POINT) / (65536 / (2048 - i))) * m_rate;
265   }
266   /* Calculate the period table for mode 4 */
267   for (int i = 0; i < 8; i++)
268   {
269      for (int j = 0; j < 16; j++)
270      {
271         // i is the dividing ratio of frequencies
272         // j is the shift clock frequency
273         m_period_mode4_table[i][j] = ((1 << FIXED_POINT) / (524288 / ((i == 0) ? 0.5 : i) / (1 << (j + 1)))) * m_rate;
274      }
275   }
276   
277   /* Calculate the length table */
278   for (int i = 0; i < 64; i++)
279      m_length_table[i] = ((64 - i) * ((1 << FIXED_POINT)/256) * m_rate) >> FIXED_POINT;
280   
281   /* Calculate the length table for mode 3 */
282   for (int i = 0; i < 256; i++)
283      m_length_mode3_table[i] = ((256 - i) * ((1 << FIXED_POINT)/256) * m_rate) >> FIXED_POINT;
284   
285   sound_w_internal(NR52, 0x00);
286   m_snd_regs[AUD3W0] = 0xac;
287   m_snd_regs[AUD3W1] = 0xdd;
288   m_snd_regs[AUD3W2] = 0xda;
289   m_snd_regs[AUD3W3] = 0x48;
290   m_snd_regs[AUD3W4] = 0x36;
291   m_snd_regs[AUD3W5] = 0x02;
292   m_snd_regs[AUD3W6] = 0xcf;
293   m_snd_regs[AUD3W7] = 0x16;
294   m_snd_regs[AUD3W8] = 0x2c;
295   m_snd_regs[AUD3W9] = 0x04;
296   m_snd_regs[AUD3WA] = 0xe5;
297   m_snd_regs[AUD3WB] = 0x2c;
298   m_snd_regs[AUD3WC] = 0xac;
299   m_snd_regs[AUD3WD] = 0xdd;
300   m_snd_regs[AUD3WE] = 0xda;
301   m_snd_regs[AUD3WF] = 0x48;
183302}
184303
185304
186305/***************************************************************************
187    PROTOTYPES
188***************************************************************************/
189
190static STREAM_UPDATE( gameboy_update );
191
192
193/***************************************************************************
194306    IMPLEMENTATION
195307***************************************************************************/
196308
197READ8_DEVICE_HANDLER( gb_wave_r )
309READ8_MEMBER( gameboy_sound_device::wave_r )
198310{
199   gb_sound_t *gb = get_token(device);
200
201311   /* TODO: properly emulate scrambling of wave ram area when playback is active */
202   return ( gb->snd_regs[ AUD3W0 + offset ] | gb->snd_3.on );
312   return m_snd_regs[AUD3W0 + offset] | m_snd_3.on;
203313}
204314
205WRITE8_DEVICE_HANDLER( gb_wave_w )
315READ8_MEMBER( gameboy_sound_device::sound_r )
206316{
207   gb_sound_t *gb = get_token(device);
208   gb->snd_regs[ AUD3W0 + offset ] = data;
317   switch (offset)
318   {
319      case 0x05:
320      case 0x0f:
321         return 0xff;
322      case NR52:
323         return 0x70 | m_snd_regs[offset];
324      default:
325         return m_snd_regs[offset];
326   }
209327}
210328
211READ8_DEVICE_HANDLER( gb_sound_r )
329WRITE8_MEMBER( gameboy_sound_device::wave_w )
212330{
213   gb_sound_t *gb = get_token(device);
331   m_snd_regs[AUD3W0 + offset] = data;
332}
214333
215   switch( offset ) {
216   case 0x05:
217   case 0x0F:
218      return 0xFF;
219   case NR52:
220      return 0x70 | gb->snd_regs[offset];
221   default:
222      return gb->snd_regs[offset];
223   }
334WRITE8_MEMBER( gameboy_sound_device::sound_w )
335{
336   
337   /* change in registers so update first */
338   m_channel->update();
339   
340   /* Only register NR52 is accessible if the sound controller is disabled */
341   if (!m_snd_control.on && offset != NR52)
342      return;
343   
344   sound_w_internal(offset, data);
224345}
225346
226static void gb_sound_w_internal(device_t *device, int offset, UINT8 data )
347
348void gameboy_sound_device::sound_w_internal( int offset, UINT8 data )
227349{
228   gb_sound_t *gb = get_token(device);
229
230350   /* Store the value */
231   gb->snd_regs[offset] = data;
351   m_snd_regs[offset] = data;
232352
233   switch( offset )
353   switch (offset)
234354   {
235355   /*MODE 1 */
236356   case NR10: /* Sweep (R/W) */
237      gb->snd_1.swp_shift = data & 0x7;
238      gb->snd_1.swp_direction = (data & 0x8) >> 3;
239      gb->snd_1.swp_direction |= gb->snd_1.swp_direction - 1;
240      gb->snd_1.swp_time = gb->swp_time_table[ (data & 0x70) >> 4 ];
357      m_snd_1.swp_shift = data & 0x7;
358      m_snd_1.swp_direction = (data & 0x8) >> 3;
359      m_snd_1.swp_direction |= m_snd_1.swp_direction - 1;
360      m_snd_1.swp_time = m_swp_time_table[ (data & 0x70) >> 4 ];
241361      break;
242362   case NR11: /* Sound length/Wave pattern duty (R/W) */
243      gb->snd_1.duty = (data & 0xC0) >> 6;
244      gb->snd_1.length = gb->length_table[data & 0x3F];
363      m_snd_1.duty = (data & 0xc0) >> 6;
364      m_snd_1.length = m_length_table[data & 0x3f];
245365      break;
246366   case NR12: /* Envelope (R/W) */
247      gb->snd_1.env_value = data >> 4;
248      gb->snd_1.env_direction = (data & 0x8) >> 3;
249      gb->snd_1.env_direction |= gb->snd_1.env_direction - 1;
250      gb->snd_1.env_length = gb->env_length_table[data & 0x7];
367      m_snd_1.env_value = data >> 4;
368      m_snd_1.env_direction = (data & 0x8) >> 3;
369      m_snd_1.env_direction |= m_snd_1.env_direction - 1;
370      m_snd_1.env_length = m_env_length_table[data & 0x7];
251371      break;
252372   case NR13: /* Frequency lo (R/W) */
253      gb->snd_1.frequency = ((gb->snd_regs[NR14]&0x7)<<8) | gb->snd_regs[NR13];
254      gb->snd_1.period = gb->period_table[gb->snd_1.frequency];
373      m_snd_1.frequency = ((m_snd_regs[NR14] & 0x7) << 8) | m_snd_regs[NR13];
374      m_snd_1.period = m_period_table[m_snd_1.frequency];
255375      break;
256376   case NR14: /* Frequency hi / Initialize (R/W) */
257      gb->snd_1.mode = (data & 0x40) >> 6;
258      gb->snd_1.frequency = ((gb->snd_regs[NR14]&0x7)<<8) | gb->snd_regs[NR13];
259      gb->snd_1.period = gb->period_table[gb->snd_1.frequency];
260      if( data & 0x80 )
377      m_snd_1.mode = (data & 0x40) >> 6;
378      m_snd_1.frequency = ((m_snd_regs[NR14] & 0x7) << 8) | m_snd_regs[NR13];
379      m_snd_1.period = m_period_table[m_snd_1.frequency];
380      if (data & 0x80)
261381      {
262         if( !gb->snd_1.on )
263            gb->snd_1.pos = 0;
264         gb->snd_1.on = 1;
265         gb->snd_1.count = 0;
266         gb->snd_1.env_value = gb->snd_regs[NR12] >> 4;
267         gb->snd_1.env_count = 0;
268         gb->snd_1.swp_count = 0;
269         gb->snd_1.signal = 0x1;
270         gb->snd_regs[NR52] |= 0x1;
382         if (!m_snd_1.on)
383            m_snd_1.pos = 0;
384         m_snd_1.on = 1;
385         m_snd_1.count = 0;
386         m_snd_1.env_value = m_snd_regs[NR12] >> 4;
387         m_snd_1.env_count = 0;
388         m_snd_1.swp_count = 0;
389         m_snd_1.signal = 0x1;
390         m_snd_regs[NR52] |= 0x1;
271391      }
272392      break;
273393
274394   /*MODE 2 */
275395   case NR21: /* Sound length/Wave pattern duty (R/W) */
276      gb->snd_2.duty = (data & 0xC0) >> 6;
277      gb->snd_2.length = gb->length_table[data & 0x3F];
396      m_snd_2.duty = (data & 0xc0) >> 6;
397      m_snd_2.length = m_length_table[data & 0x3f];
278398      break;
279399   case NR22: /* Envelope (R/W) */
280      gb->snd_2.env_value = data >> 4;
281      gb->snd_2.env_direction = (data & 0x8 ) >> 3;
282      gb->snd_2.env_direction |= gb->snd_2.env_direction - 1;
283      gb->snd_2.env_length = gb->env_length_table[data & 0x7];
400      m_snd_2.env_value = data >> 4;
401      m_snd_2.env_direction = (data & 0x8) >> 3;
402      m_snd_2.env_direction |= m_snd_2.env_direction - 1;
403      m_snd_2.env_length = m_env_length_table[data & 0x7];
284404      break;
285405   case NR23: /* Frequency lo (R/W) */
286      gb->snd_2.period = gb->period_table[((gb->snd_regs[NR24]&0x7)<<8) | gb->snd_regs[NR23]];
406      m_snd_2.period = m_period_table[((m_snd_regs[NR24] & 0x7) << 8) | m_snd_regs[NR23]];
287407      break;
288408   case NR24: /* Frequency hi / Initialize (R/W) */
289      gb->snd_2.mode = (data & 0x40) >> 6;
290      gb->snd_2.period = gb->period_table[((gb->snd_regs[NR24]&0x7)<<8) | gb->snd_regs[NR23]];
291      if( data & 0x80 )
409      m_snd_2.mode = (data & 0x40) >> 6;
410      m_snd_2.period = m_period_table[((m_snd_regs[NR24] & 0x7) << 8) | m_snd_regs[NR23]];
411      if (data & 0x80)
292412      {
293         if( !gb->snd_2.on )
294            gb->snd_2.pos = 0;
295         gb->snd_2.on = 1;
296         gb->snd_2.count = 0;
297         gb->snd_2.env_value = gb->snd_regs[NR22] >> 4;
298         gb->snd_2.env_count = 0;
299         gb->snd_2.signal = 0x1;
300         gb->snd_regs[NR52] |= 0x2;
413         if (!m_snd_2.on)
414            m_snd_2.pos = 0;
415         m_snd_2.on = 1;
416         m_snd_2.count = 0;
417         m_snd_2.env_value = m_snd_regs[NR22] >> 4;
418         m_snd_2.env_count = 0;
419         m_snd_2.signal = 0x1;
420         m_snd_regs[NR52] |= 0x2;
301421      }
302422      break;
303423
304424   /*MODE 3 */
305425   case NR30: /* Sound On/Off (R/W) */
306      gb->snd_3.on = (data & 0x80) >> 7;
426      m_snd_3.on = (data & 0x80) >> 7;
307427      break;
308428   case NR31: /* Sound Length (R/W) */
309      gb->snd_3.length = gb->length_mode3_table[data];
429      m_snd_3.length = m_length_mode3_table[data];
310430      break;
311431   case NR32: /* Select Output Level */
312      gb->snd_3.level = (data & 0x60) >> 5;
432      m_snd_3.level = (data & 0x60) >> 5;
313433      break;
314434   case NR33: /* Frequency lo (W) */
315      gb->snd_3.period = gb->period_mode3_table[((gb->snd_regs[NR34]&0x7)<<8) + gb->snd_regs[NR33]];
435      m_snd_3.period = m_period_mode3_table[((m_snd_regs[NR34] & 0x7) << 8) + m_snd_regs[NR33]];
316436      break;
317437   case NR34: /* Frequency hi / Initialize (W) */
318      gb->snd_3.mode = (data & 0x40) >> 6;
319      gb->snd_3.period = gb->period_mode3_table[((gb->snd_regs[NR34]&0x7)<<8) + gb->snd_regs[NR33]];
320      if( data & 0x80 )
438      m_snd_3.mode = (data & 0x40) >> 6;
439      m_snd_3.period = m_period_mode3_table[((m_snd_regs[NR34] & 0x7) << 8) + m_snd_regs[NR33]];
440      if (data & 0x80)
321441      {
322         if( !gb->snd_3.on )
442         if (!m_snd_3.on)
323443         {
324            gb->snd_3.pos = 0;
325            gb->snd_3.offset = 0;
326            gb->snd_3.duty = 0;
444            m_snd_3.pos = 0;
445            m_snd_3.offset = 0;
446            m_snd_3.duty = 0;
327447         }
328         gb->snd_3.on = 1;
329         gb->snd_3.count = 0;
330         gb->snd_3.duty = 1;
331         gb->snd_3.dutycount = 0;
332         gb->snd_regs[NR52] |= 0x4;
448         m_snd_3.on = 1;
449         m_snd_3.count = 0;
450         m_snd_3.duty = 1;
451         m_snd_3.dutycount = 0;
452         m_snd_regs[NR52] |= 0x4;
333453      }
334454      break;
335455
336456   /*MODE 4 */
337457   case NR41: /* Sound Length (R/W) */
338      gb->snd_4.length = gb->length_table[data & 0x3F];
458      m_snd_4.length = m_length_table[data & 0x3f];
339459      break;
340460   case NR42: /* Envelope (R/W) */
341      gb->snd_4.env_value = data >> 4;
342      gb->snd_4.env_direction = (data & 0x8 ) >> 3;
343      gb->snd_4.env_direction |= gb->snd_4.env_direction - 1;
344      gb->snd_4.env_length = gb->env_length_table[data & 0x7];
461      m_snd_4.env_value = data >> 4;
462      m_snd_4.env_direction = (data & 0x8) >> 3;
463      m_snd_4.env_direction |= m_snd_4.env_direction - 1;
464      m_snd_4.env_length = m_env_length_table[data & 0x7];
345465      break;
346466   case NR43: /* Polynomial Counter/Frequency */
347      gb->snd_4.period = gb->period_mode4_table[data & 0x7][(data & 0xF0) >> 4];
348      gb->snd_4.ply_step = (data & 0x8) >> 3;
467      m_snd_4.period = m_period_mode4_table[data & 0x7][(data & 0xF0) >> 4];
468      m_snd_4.ply_step = (data & 0x8) >> 3;
349469      break;
350470   case NR44: /* Counter/Consecutive / Initialize (R/W)  */
351      gb->snd_4.mode = (data & 0x40) >> 6;
352      if( data & 0x80 )
471      m_snd_4.mode = (data & 0x40) >> 6;
472      if (data & 0x80)
353473      {
354         if( !gb->snd_4.on )
355            gb->snd_4.pos = 0;
356         gb->snd_4.on = 1;
357         gb->snd_4.count = 0;
358         gb->snd_4.env_value = gb->snd_regs[NR42] >> 4;
359         gb->snd_4.env_count = 0;
360         gb->snd_4.signal = device->machine().rand();
361         gb->snd_4.ply_value = 0x7fff;
362         gb->snd_regs[NR52] |= 0x8;
474         if (!m_snd_4.on)
475            m_snd_4.pos = 0;
476         m_snd_4.on = 1;
477         m_snd_4.count = 0;
478         m_snd_4.env_value = m_snd_regs[NR42] >> 4;
479         m_snd_4.env_count = 0;
480         m_snd_4.signal = machine().rand();
481         m_snd_4.ply_value = 0x7fff;
482         m_snd_regs[NR52] |= 0x8;
363483      }
364484      break;
365485
366486   /* CONTROL */
367487   case NR50: /* Channel Control / On/Off / Volume (R/W)  */
368      gb->snd_control.vol_left = data & 0x7;
369      gb->snd_control.vol_right = (data & 0x70) >> 4;
488      m_snd_control.vol_left = data & 0x7;
489      m_snd_control.vol_right = (data & 0x70) >> 4;
370490      break;
371491   case NR51: /* Selection of Sound Output Terminal */
372      gb->snd_control.mode1_right = data & 0x1;
373      gb->snd_control.mode1_left = (data & 0x10) >> 4;
374      gb->snd_control.mode2_right = (data & 0x2) >> 1;
375      gb->snd_control.mode2_left = (data & 0x20) >> 5;
376      gb->snd_control.mode3_right = (data & 0x4) >> 2;
377      gb->snd_control.mode3_left = (data & 0x40) >> 6;
378      gb->snd_control.mode4_right = (data & 0x8) >> 3;
379      gb->snd_control.mode4_left = (data & 0x80) >> 7;
492      m_snd_control.mode1_right = data & 0x1;
493      m_snd_control.mode1_left = (data & 0x10) >> 4;
494      m_snd_control.mode2_right = (data & 0x2) >> 1;
495      m_snd_control.mode2_left = (data & 0x20) >> 5;
496      m_snd_control.mode3_right = (data & 0x4) >> 2;
497      m_snd_control.mode3_left = (data & 0x40) >> 6;
498      m_snd_control.mode4_right = (data & 0x8) >> 3;
499      m_snd_control.mode4_left = (data & 0x80) >> 7;
380500      break;
381501   case NR52: /* Sound On/Off (R/W) */
382502      /* Only bit 7 is writable, writing to bits 0-3 does NOT enable or
383503         disable sound.  They are read-only */
384      gb->snd_control.on = (data & 0x80) >> 7;
385      if( !gb->snd_control.on )
504      m_snd_control.on = (data & 0x80) >> 7;
505      if (!m_snd_control.on)
386506      {
387         gb_sound_w_internal( device, NR10, 0x80 );
388         gb_sound_w_internal( device, NR11, 0x3F );
389         gb_sound_w_internal( device, NR12, 0x00 );
390         gb_sound_w_internal( device, NR13, 0xFE );
391         gb_sound_w_internal( device, NR14, 0xBF );
392//          gb_sound_w_internal( device, NR20, 0xFF );
393         gb_sound_w_internal( device, NR21, 0x3F );
394         gb_sound_w_internal( device, NR22, 0x00 );
395         gb_sound_w_internal( device, NR23, 0xFF );
396         gb_sound_w_internal( device, NR24, 0xBF );
397         gb_sound_w_internal( device, NR30, 0x7F );
398         gb_sound_w_internal( device, NR31, 0xFF );
399         gb_sound_w_internal( device, NR32, 0x9F );
400         gb_sound_w_internal( device, NR33, 0xFF );
401         gb_sound_w_internal( device, NR34, 0xBF );
402//          gb_sound_w_internal( device, NR40, 0xFF );
403         gb_sound_w_internal( device, NR41, 0xFF );
404         gb_sound_w_internal( device, NR42, 0x00 );
405         gb_sound_w_internal( device, NR43, 0x00 );
406         gb_sound_w_internal( device, NR44, 0xBF );
407         gb_sound_w_internal( device, NR50, 0x00 );
408         gb_sound_w_internal( device, NR51, 0x00 );
409         gb->snd_1.on = 0;
410         gb->snd_2.on = 0;
411         gb->snd_3.on = 0;
412         gb->snd_4.on = 0;
413         gb->snd_regs[offset] = 0;
507         sound_w_internal(NR10, 0x80);
508         sound_w_internal(NR11, 0x3F);
509         sound_w_internal(NR12, 0x00);
510         sound_w_internal(NR13, 0xFE);
511         sound_w_internal(NR14, 0xBF);
512//          sound_w_internal(NR20, 0xFF);
513         sound_w_internal(NR21, 0x3F);
514         sound_w_internal(NR22, 0x00);
515         sound_w_internal(NR23, 0xFF);
516         sound_w_internal(NR24, 0xBF);
517         sound_w_internal(NR30, 0x7F);
518         sound_w_internal(NR31, 0xFF);
519         sound_w_internal(NR32, 0x9F);
520         sound_w_internal(NR33, 0xFF);
521         sound_w_internal(NR34, 0xBF);
522//          sound_w_internal(NR40, 0xFF);
523         sound_w_internal(NR41, 0xFF);
524         sound_w_internal(NR42, 0x00);
525         sound_w_internal(NR43, 0x00);
526         sound_w_internal(NR44, 0xBF);
527         sound_w_internal(NR50, 0x00);
528         sound_w_internal(NR51, 0x00);
529         m_snd_1.on = 0;
530         m_snd_2.on = 0;
531         m_snd_3.on = 0;
532         m_snd_4.on = 0;
533         m_snd_regs[offset] = 0;
414534      }
415535      break;
416536   }
417537}
418538
419WRITE8_DEVICE_HANDLER( gb_sound_w )
420{
421   gb_sound_t *gb = get_token(device);
539   
540//-------------------------------------------------
541//  sound_stream_update - handle a stream update
542//-------------------------------------------------
422543
423   /* change in registers so update first */
424   gb->channel->update();
425
426   /* Only register NR52 is accessible if the sound controller is disabled */
427   if( !gb->snd_control.on && offset != NR52 )
428   {
429      return;
430   }
431
432   gb_sound_w_internal( device, offset, data );
433}
434
435
436
437static STREAM_UPDATE( gameboy_update )
544void gameboy_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
438545{
439   gb_sound_t *gb = get_token(device);
440546   stream_sample_t sample, left, right, mode4_mask;
441
442   while( samples-- > 0 )
547   
548   while (samples-- > 0)
443549   {
444550      left = right = 0;
445
551     
446552      /* Mode 1 - Wave with Envelope and Sweep */
447      if( gb->snd_1.on )
553      if (m_snd_1.on)
448554      {
449         sample = gb->snd_1.signal * gb->snd_1.env_value;
450         gb->snd_1.pos++;
451         if( gb->snd_1.pos == (UINT32)(gb->snd_1.period / wave_duty_table[gb->snd_1.duty]) >> FIXED_POINT)
555         sample = m_snd_1.signal * m_snd_1.env_value;
556         m_snd_1.pos++;
557         if (m_snd_1.pos == (UINT32)(m_snd_1.period / wave_duty_table[m_snd_1.duty]) >> FIXED_POINT)
452558         {
453            gb->snd_1.signal = -gb->snd_1.signal;
559            m_snd_1.signal = -m_snd_1.signal;
454560         }
455         else if( gb->snd_1.pos > (gb->snd_1.period >> FIXED_POINT) )
561         else if (m_snd_1.pos > (m_snd_1.period >> FIXED_POINT))
456562         {
457            gb->snd_1.pos = 0;
458            gb->snd_1.signal = -gb->snd_1.signal;
563            m_snd_1.pos = 0;
564            m_snd_1.signal = -m_snd_1.signal;
459565         }
460
461         if( gb->snd_1.length && gb->snd_1.mode )
566         
567         if (m_snd_1.length && m_snd_1.mode)
462568         {
463            gb->snd_1.count++;
464            if( gb->snd_1.count >= gb->snd_1.length )
569            m_snd_1.count++;
570            if (m_snd_1.count >= m_snd_1.length)
465571            {
466               gb->snd_1.on = 0;
467               gb->snd_regs[NR52] &= 0xFE;
572               m_snd_1.on = 0;
573               m_snd_regs[NR52] &= 0xFE;
468574            }
469575         }
470
471         if( gb->snd_1.env_length )
576         
577         if (m_snd_1.env_length)
472578         {
473            gb->snd_1.env_count++;
474            if( gb->snd_1.env_count >= gb->snd_1.env_length )
579            m_snd_1.env_count++;
580            if (m_snd_1.env_count >= m_snd_1.env_length)
475581            {
476               gb->snd_1.env_count = 0;
477               gb->snd_1.env_value += gb->snd_1.env_direction;
478               if( gb->snd_1.env_value < 0 )
479                  gb->snd_1.env_value = 0;
480               if( gb->snd_1.env_value > 15 )
481                  gb->snd_1.env_value = 15;
582               m_snd_1.env_count = 0;
583               m_snd_1.env_value += m_snd_1.env_direction;
584               if (m_snd_1.env_value < 0)
585                  m_snd_1.env_value = 0;
586               if (m_snd_1.env_value > 15)
587                  m_snd_1.env_value = 15;
482588            }
483589         }
484
485         if( gb->snd_1.swp_time )
590         
591         if (m_snd_1.swp_time)
486592         {
487            gb->snd_1.swp_count++;
488            if( gb->snd_1.swp_count >= gb->snd_1.swp_time )
593            m_snd_1.swp_count++;
594            if (m_snd_1.swp_count >= m_snd_1.swp_time)
489595            {
490               gb->snd_1.swp_count = 0;
491               if( gb->snd_1.swp_direction > 0 )
596               m_snd_1.swp_count = 0;
597               if (m_snd_1.swp_direction > 0)
492598               {
493                  gb->snd_1.frequency -= gb->snd_1.frequency / (1 << gb->snd_1.swp_shift );
494                  if( gb->snd_1.frequency <= 0 )
599                  m_snd_1.frequency -= m_snd_1.frequency / (1 << m_snd_1.swp_shift);
600                  if (m_snd_1.frequency <= 0)
495601                  {
496                     gb->snd_1.on = 0;
497                     gb->snd_regs[NR52] &= 0xFE;
602                     m_snd_1.on = 0;
603                     m_snd_regs[NR52] &= 0xFE;
498604                  }
499605               }
500606               else
501607               {
502                  gb->snd_1.frequency += gb->snd_1.frequency / (1 << gb->snd_1.swp_shift );
503                  if( gb->snd_1.frequency >= MAX_FREQUENCIES )
608                  m_snd_1.frequency += m_snd_1.frequency / (1 << m_snd_1.swp_shift);
609                  if (m_snd_1.frequency >= MAX_FREQUENCIES)
504610                  {
505                     gb->snd_1.frequency = MAX_FREQUENCIES - 1;
611                     m_snd_1.frequency = MAX_FREQUENCIES - 1;
506612                  }
507613               }
508
509               gb->snd_1.period = gb->period_table[gb->snd_1.frequency];
614               
615               m_snd_1.period = m_period_table[m_snd_1.frequency];
510616            }
511617         }
512
513         if( gb->snd_control.mode1_left )
618         
619         if (m_snd_control.mode1_left)
514620            left += sample;
515         if( gb->snd_control.mode1_right )
621         if (m_snd_control.mode1_right)
516622            right += sample;
517623      }
518
624     
519625      /* Mode 2 - Wave with Envelope */
520      if( gb->snd_2.on )
626      if (m_snd_2.on)
521627      {
522         sample = gb->snd_2.signal * gb->snd_2.env_value;
523         gb->snd_2.pos++;
524         if( gb->snd_2.pos == (UINT32)(gb->snd_2.period / wave_duty_table[gb->snd_2.duty]) >> FIXED_POINT)
628         sample = m_snd_2.signal * m_snd_2.env_value;
629         m_snd_2.pos++;
630         if( m_snd_2.pos == (UINT32)(m_snd_2.period / wave_duty_table[m_snd_2.duty]) >> FIXED_POINT)
525631         {
526            gb->snd_2.signal = -gb->snd_2.signal;
632            m_snd_2.signal = -m_snd_2.signal;
527633         }
528         else if( gb->snd_2.pos > (gb->snd_2.period >> FIXED_POINT) )
634         else if (m_snd_2.pos > (m_snd_2.period >> FIXED_POINT))
529635         {
530            gb->snd_2.pos = 0;
531            gb->snd_2.signal = -gb->snd_2.signal;
636            m_snd_2.pos = 0;
637            m_snd_2.signal = -m_snd_2.signal;
532638         }
533
534         if( gb->snd_2.length && gb->snd_2.mode )
639         
640         if (m_snd_2.length && m_snd_2.mode)
535641         {
536            gb->snd_2.count++;
537            if( gb->snd_2.count >= gb->snd_2.length )
642            m_snd_2.count++;
643            if (m_snd_2.count >= m_snd_2.length)
538644            {
539               gb->snd_2.on = 0;
540               gb->snd_regs[NR52] &= 0xFD;
645               m_snd_2.on = 0;
646               m_snd_regs[NR52] &= 0xFD;
541647            }
542648         }
543
544         if( gb->snd_2.env_length )
649         
650         if (m_snd_2.env_length)
545651         {
546            gb->snd_2.env_count++;
547            if( gb->snd_2.env_count >= gb->snd_2.env_length )
652            m_snd_2.env_count++;
653            if (m_snd_2.env_count >= m_snd_2.env_length)
548654            {
549               gb->snd_2.env_count = 0;
550               gb->snd_2.env_value += gb->snd_2.env_direction;
551               if( gb->snd_2.env_value < 0 )
552                  gb->snd_2.env_value = 0;
553               if( gb->snd_2.env_value > 15 )
554                  gb->snd_2.env_value = 15;
655               m_snd_2.env_count = 0;
656               m_snd_2.env_value += m_snd_2.env_direction;
657               if (m_snd_2.env_value < 0)
658                  m_snd_2.env_value = 0;
659               if (m_snd_2.env_value > 15)
660                  m_snd_2.env_value = 15;
555661            }
556662         }
557
558         if( gb->snd_control.mode2_left )
663         
664         if (m_snd_control.mode2_left)
559665            left += sample;
560         if( gb->snd_control.mode2_right )
666         if (m_snd_control.mode2_right)
561667            right += sample;
562668      }
563
669     
564670      /* Mode 3 - Wave patterns from WaveRAM */
565      if( gb->snd_3.on )
671      if (m_snd_3.on)
566672      {
567673         /* NOTE: This is extremely close, but not quite right.
568            The problem is for GB frequencies above 2000 the frequency gets
569            clipped. This is caused because gb->snd_3.pos is never 0 at the test.*/
570         sample = gb->snd_regs[AUD3W0 + (gb->snd_3.offset/2)];
571         if( !(gb->snd_3.offset % 2) )
674          The problem is for GB frequencies above 2000 the frequency gets
675          clipped. This is caused because m_snd_3.pos is never 0 at the test.*/
676         sample = m_snd_regs[AUD3W0 + (m_snd_3.offset/2)];
677         if (!(m_snd_3.offset % 2))
572678         {
573679            sample >>= 4;
574680         }
575681         sample = (sample & 0xF) - 8;
576
577         if( gb->snd_3.level )
578            sample >>= (gb->snd_3.level - 1);
682         
683         if (m_snd_3.level)
684            sample >>= (m_snd_3.level - 1);
579685         else
580686            sample = 0;
581
582         gb->snd_3.pos++;
583         if( gb->snd_3.pos >= ((UINT32)(((gb->snd_3.period ) >> 21)) + gb->snd_3.duty) )
687         
688         m_snd_3.pos++;
689         if (m_snd_3.pos >= ((UINT32)(((m_snd_3.period) >> 21)) + m_snd_3.duty))
584690         {
585            gb->snd_3.pos = 0;
586            if( gb->snd_3.dutycount == ((UINT32)(((gb->snd_3.period ) >> FIXED_POINT)) % 32) )
691            m_snd_3.pos = 0;
692            if (m_snd_3.dutycount == ((UINT32)(((m_snd_3.period) >> FIXED_POINT)) % 32))
587693            {
588               gb->snd_3.duty--;
694               m_snd_3.duty--;
589695            }
590            gb->snd_3.dutycount++;
591            gb->snd_3.offset++;
592            if( gb->snd_3.offset > 31 )
696            m_snd_3.dutycount++;
697            m_snd_3.offset++;
698            if (m_snd_3.offset > 31)
593699            {
594               gb->snd_3.offset = 0;
595               gb->snd_3.duty = 1;
596               gb->snd_3.dutycount = 0;
700               m_snd_3.offset = 0;
701               m_snd_3.duty = 1;
702               m_snd_3.dutycount = 0;
597703            }
598704         }
599
600         if( gb->snd_3.length && gb->snd_3.mode )
705         
706         if (m_snd_3.length && m_snd_3.mode)
601707         {
602            gb->snd_3.count++;
603            if( gb->snd_3.count >= gb->snd_3.length )
708            m_snd_3.count++;
709            if (m_snd_3.count >= m_snd_3.length)
604710            {
605               gb->snd_3.on = 0;
606               gb->snd_regs[NR52] &= 0xFB;
711               m_snd_3.on = 0;
712               m_snd_regs[NR52] &= 0xFB;
607713            }
608714         }
609
610         if( gb->snd_control.mode3_left )
715         
716         if (m_snd_control.mode3_left)
611717            left += sample;
612         if( gb->snd_control.mode3_right )
718         if (m_snd_control.mode3_right)
613719            right += sample;
614720      }
615
721     
616722      /* Mode 4 - Noise with Envelope */
617      if( gb->snd_4.on )
723      if (m_snd_4.on)
618724      {
619725         /* Similar problem to Mode 3, we seem to miss some notes */
620         sample = gb->snd_4.signal & gb->snd_4.env_value;
621         gb->snd_4.pos++;
622         if( gb->snd_4.pos == (gb->snd_4.period >> (FIXED_POINT + 1)) )
726         sample = m_snd_4.signal & m_snd_4.env_value;
727         m_snd_4.pos++;
728         if (m_snd_4.pos == (m_snd_4.period >> (FIXED_POINT + 1)))
623729         {
624730            /* Using a Polynomial Counter (aka Linear Feedback Shift Register)
625               Mode 4 has a 7 bit and 15 bit counter so we need to shift the
626               bits around accordingly */
627            mode4_mask = (((gb->snd_4.ply_value & 0x2) >> 1) ^ (gb->snd_4.ply_value & 0x1)) << (gb->snd_4.ply_step ? 6 : 14);
628            gb->snd_4.ply_value >>= 1;
629            gb->snd_4.ply_value |= mode4_mask;
630            gb->snd_4.ply_value &= (gb->snd_4.ply_step ? 0x7f : 0x7fff);
631            gb->snd_4.signal = (INT8)gb->snd_4.ply_value;
731             Mode 4 has a 7 bit and 15 bit counter so we need to shift the
732             bits around accordingly */
733            mode4_mask = (((m_snd_4.ply_value & 0x2) >> 1) ^ (m_snd_4.ply_value & 0x1)) << (m_snd_4.ply_step ? 6 : 14);
734            m_snd_4.ply_value >>= 1;
735            m_snd_4.ply_value |= mode4_mask;
736            m_snd_4.ply_value &= (m_snd_4.ply_step ? 0x7f : 0x7fff);
737            m_snd_4.signal = (INT8)m_snd_4.ply_value;
632738         }
633         else if( gb->snd_4.pos > (gb->snd_4.period >> FIXED_POINT) )
739         else if (m_snd_4.pos > (m_snd_4.period >> FIXED_POINT))
634740         {
635            gb->snd_4.pos = 0;
636            mode4_mask = (((gb->snd_4.ply_value & 0x2) >> 1) ^ (gb->snd_4.ply_value & 0x1)) << (gb->snd_4.ply_step ? 6 : 14);
637            gb->snd_4.ply_value >>= 1;
638            gb->snd_4.ply_value |= mode4_mask;
639            gb->snd_4.ply_value &= (gb->snd_4.ply_step ? 0x7f : 0x7fff);
640            gb->snd_4.signal = (INT8)gb->snd_4.ply_value;
741            m_snd_4.pos = 0;
742            mode4_mask = (((m_snd_4.ply_value & 0x2) >> 1) ^ (m_snd_4.ply_value & 0x1)) << (m_snd_4.ply_step ? 6 : 14);
743            m_snd_4.ply_value >>= 1;
744            m_snd_4.ply_value |= mode4_mask;
745            m_snd_4.ply_value &= (m_snd_4.ply_step ? 0x7f : 0x7fff);
746            m_snd_4.signal = (INT8)m_snd_4.ply_value;
641747         }
642
643         if( gb->snd_4.length && gb->snd_4.mode )
748         
749         if (m_snd_4.length && m_snd_4.mode)
644750         {
645            gb->snd_4.count++;
646            if( gb->snd_4.count >= gb->snd_4.length )
751            m_snd_4.count++;
752            if (m_snd_4.count >= m_snd_4.length)
647753            {
648               gb->snd_4.on = 0;
649               gb->snd_regs[NR52] &= 0xF7;
754               m_snd_4.on = 0;
755               m_snd_regs[NR52] &= 0xF7;
650756            }
651757         }
652
653         if( gb->snd_4.env_length )
758         
759         if (m_snd_4.env_length)
654760         {
655            gb->snd_4.env_count++;
656            if( gb->snd_4.env_count >= gb->snd_4.env_length )
761            m_snd_4.env_count++;
762            if (m_snd_4.env_count >= m_snd_4.env_length)
657763            {
658               gb->snd_4.env_count = 0;
659               gb->snd_4.env_value += gb->snd_4.env_direction;
660               if( gb->snd_4.env_value < 0 )
661                  gb->snd_4.env_value = 0;
662               if( gb->snd_4.env_value > 15 )
663                  gb->snd_4.env_value = 15;
764               m_snd_4.env_count = 0;
765               m_snd_4.env_value += m_snd_4.env_direction;
766               if (m_snd_4.env_value < 0)
767                  m_snd_4.env_value = 0;
768               if (m_snd_4.env_value > 15)
769                  m_snd_4.env_value = 15;
664770            }
665771         }
666
667         if( gb->snd_control.mode4_left )
772         
773         if (m_snd_control.mode4_left)
668774            left += sample;
669         if( gb->snd_control.mode4_right )
775         if (m_snd_control.mode4_right)
670776            right += sample;
671777      }
672
778     
673779      /* Adjust for master volume */
674      left *= gb->snd_control.vol_left;
675      right *= gb->snd_control.vol_right;
676
780      left *= m_snd_control.vol_left;
781      right *= m_snd_control.vol_right;
782     
677783      /* pump up the volume */
678784      left <<= 6;
679785      right <<= 6;
680
786     
681787      /* Update the buffers */
682788      *(outputs[0]++) = left;
683789      *(outputs[1]++) = right;
684790   }
791   
792   m_snd_regs[NR52] = (m_snd_regs[NR52]&0xf0) | m_snd_1.on | (m_snd_2.on << 1) | (m_snd_3.on << 2) | (m_snd_4.on << 3);
685793
686   gb->snd_regs[NR52] = (gb->snd_regs[NR52]&0xf0) | gb->snd_1.on | (gb->snd_2.on << 1) | (gb->snd_3.on << 2) | (gb->snd_4.on << 3);
687794}
688
689
690static DEVICE_START( gameboy_sound )
691{
692   gb_sound_t *gb = get_token(device);
693   int I, J;
694
695   memset(&gb->snd_1, 0, sizeof(gb->snd_1));
696   memset(&gb->snd_2, 0, sizeof(gb->snd_2));
697   memset(&gb->snd_3, 0, sizeof(gb->snd_3));
698   memset(&gb->snd_4, 0, sizeof(gb->snd_4));
699
700   gb->channel = device->machine().sound().stream_alloc(*device, 0, 2, device->machine().sample_rate(), 0, gameboy_update);
701   gb->rate = device->machine().sample_rate();
702
703   /* Calculate the envelope and sweep tables */
704   for( I = 0; I < 8; I++ )
705   {
706      gb->env_length_table[I] = (I * ((1 << FIXED_POINT) / 64) * gb->rate) >> FIXED_POINT;
707      gb->swp_time_table[I] = (((I << FIXED_POINT) / 128) * gb->rate) >> (FIXED_POINT - 1);
708   }
709
710   /* Calculate the period tables */
711   for( I = 0; I < MAX_FREQUENCIES; I++ )
712   {
713      gb->period_table[I] = ((1 << FIXED_POINT) / (131072 / (2048 - I))) * gb->rate;
714      gb->period_mode3_table[I] = ((1 << FIXED_POINT) / (65536 / (2048 - I))) * gb->rate;
715   }
716   /* Calculate the period table for mode 4 */
717   for( I = 0; I < 8; I++ )
718   {
719      for( J = 0; J < 16; J++ )
720      {
721         /* I is the dividing ratio of frequencies
722            J is the shift clock frequency */
723         gb->period_mode4_table[I][J] = ((1 << FIXED_POINT) / (524288 / ((I == 0)?0.5:I) / (1 << (J + 1)))) * gb->rate;
724      }
725   }
726
727   /* Calculate the length table */
728   for( I = 0; I < 64; I++ )
729   {
730      gb->length_table[I] = ((64 - I) * ((1 << FIXED_POINT)/256) * gb->rate) >> FIXED_POINT;
731   }
732   /* Calculate the length table for mode 3 */
733   for( I = 0; I < 256; I++ )
734   {
735      gb->length_mode3_table[I] = ((256 - I) * ((1 << FIXED_POINT)/256) * gb->rate) >> FIXED_POINT;
736   }
737
738   gb_sound_w_internal( device, NR52, 0x00 );
739   gb->snd_regs[AUD3W0] = 0xac;
740   gb->snd_regs[AUD3W1] = 0xdd;
741   gb->snd_regs[AUD3W2] = 0xda;
742   gb->snd_regs[AUD3W3] = 0x48;
743   gb->snd_regs[AUD3W4] = 0x36;
744   gb->snd_regs[AUD3W5] = 0x02;
745   gb->snd_regs[AUD3W6] = 0xcf;
746   gb->snd_regs[AUD3W7] = 0x16;
747   gb->snd_regs[AUD3W8] = 0x2c;
748   gb->snd_regs[AUD3W9] = 0x04;
749   gb->snd_regs[AUD3WA] = 0xe5;
750   gb->snd_regs[AUD3WB] = 0x2c;
751   gb->snd_regs[AUD3WC] = 0xac;
752   gb->snd_regs[AUD3WD] = 0xdd;
753   gb->snd_regs[AUD3WE] = 0xda;
754   gb->snd_regs[AUD3WF] = 0x48;
755}
756
757
758const device_type GAMEBOY = &device_creator<gameboy_sound_device>;
759
760gameboy_sound_device::gameboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
761   : device_t(mconfig, GAMEBOY, "LR35902", tag, owner, clock),
762      device_sound_interface(mconfig, *this)
763{
764   m_token = global_alloc_clear(gb_sound_t);
765}
766
767//-------------------------------------------------
768//  device_config_complete - perform any
769//  operations now that the configuration is
770//  complete
771//-------------------------------------------------
772
773void gameboy_sound_device::device_config_complete()
774{
775}
776
777//-------------------------------------------------
778//  device_start - device-specific startup
779//-------------------------------------------------
780
781void gameboy_sound_device::device_start()
782{
783   DEVICE_START_NAME( gameboy_sound )(this);
784}
785
786//-------------------------------------------------
787//  sound_stream_update - handle a stream update
788//-------------------------------------------------
789
790void gameboy_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
791{
792   // should never get here
793   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
794}
trunk/src/mess/audio/gb.h
r22897r22898
1#ifndef __GBSOUND_H__
2#define __GBSOUND_H__
3
4
5#define MAX_FREQUENCIES 2048
6
7
8struct SOUND
9{
10   /* Common */
11   UINT8  on;
12   UINT8  channel;
13   INT32  length;
14   INT32  pos;
15   UINT32 period;
16   INT32  count;
17   INT8   mode;
18   /* Mode 1, 2, 3 */
19   INT8   duty;
20   /* Mode 1, 2, 4 */
21   INT32  env_value;
22   INT8   env_direction;
23   INT32  env_length;
24   INT32  env_count;
25   INT8   signal;
26   /* Mode 1 */
27   UINT32 frequency;
28   INT32  swp_shift;
29   INT32  swp_direction;
30   INT32  swp_time;
31   INT32  swp_count;
32   /* Mode 3 */
33   INT8   level;
34   UINT8  offset;
35   UINT32 dutycount;
36   /* Mode 4 */
37   INT32  ply_step;
38   INT16  ply_value;
39};
40
41struct SOUNDC
42{
43   UINT8 on;
44   UINT8 vol_left;
45   UINT8 vol_right;
46   UINT8 mode1_left;
47   UINT8 mode1_right;
48   UINT8 mode2_left;
49   UINT8 mode2_right;
50   UINT8 mode3_left;
51   UINT8 mode3_right;
52   UINT8 mode4_left;
53   UINT8 mode4_right;
54};
55
56
157class gameboy_sound_device : public device_t,
258                           public device_sound_interface
359{
r22897r22898
359public:
460   gameboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
5   ~gameboy_sound_device() { global_free(m_token); }
661
7   // access to legacy token
8   void *token() const { assert(m_token != NULL); return m_token; }
62   DECLARE_READ8_MEMBER(sound_r);
63   DECLARE_READ8_MEMBER(wave_r);
64   DECLARE_WRITE8_MEMBER(sound_w);
65   DECLARE_WRITE8_MEMBER(wave_w);
66   
967protected:
1068   // device-level overrides
1169   virtual void device_config_complete();
1270   virtual void device_start();
1371
72   virtual void device_reset();
73
1474   // sound stream update overrides
1575   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
76
1677private:
17   // internal state
18   void *m_token;
78   void sound_w_internal(int offset, UINT8 data);
79
80   sound_stream *m_channel;
81   int m_rate;
82   
83   INT32 m_env_length_table[8];
84   INT32 m_swp_time_table[8];
85   UINT32 m_period_table[MAX_FREQUENCIES];
86   UINT32 m_period_mode3_table[MAX_FREQUENCIES];
87   UINT32 m_period_mode4_table[8][16];
88   UINT32 m_length_table[64];
89   UINT32 m_length_mode3_table[256];
90   
91   struct SOUND  m_snd_1;
92   struct SOUND  m_snd_2;
93   struct SOUND  m_snd_3;
94   struct SOUND  m_snd_4;
95   struct SOUNDC m_snd_control;
96   
97   UINT8 m_snd_regs[0x30];
1998};
2099
21100extern const device_type GAMEBOY;
22101
23
24DECLARE_READ8_DEVICE_HANDLER( gb_sound_r );
25DECLARE_WRITE8_DEVICE_HANDLER( gb_sound_w );
26DECLARE_READ8_DEVICE_HANDLER( gb_wave_r );
27DECLARE_WRITE8_DEVICE_HANDLER( gb_wave_w );
102#endif
trunk/src/mess/machine/gb.c
r22897r22898
171171void gb_state::gb_init()
172172{
173173   address_space &space = m_maincpu->space(AS_PROGRAM);
174   m_custom->sound_w(space, 0x16, 0x00);       /* Initialize sound hardware */
174175
175   gb_sound_w(m_custom, space, 0x16, 0x00);       /* Initialize sound hardware */
176
177176   m_divcount = 0;
178177   m_triggering_irq = 0;
179178   m_gb_io[0x07] = 0xF8;        /* Upper bits of TIMEFRQ register are set to 1 */
r22897r22898
252251   m_bios_disable = 0;
253252
254253   /* Initialize the Sound registers */
255   gb_sound_w(m_custom, generic_space(), 0x16,0x80);
256   gb_sound_w(m_custom, generic_space(), 0x15,0xF3);
257   gb_sound_w(m_custom, generic_space(), 0x14,0x77);
254   m_custom->sound_w(generic_space(), 0x16, 0x80);
255   m_custom->sound_w(generic_space(), 0x15, 0xF3);
256   m_custom->sound_w(generic_space(), 0x14, 0x77);
258257
259258   m_divcount = 0xABC8;
260259}
r22897r22898
11571156
11581157WRITE8_MEMBER(megaduck_state::megaduck_sound_w1)
11591158{
1160   gb_sound_w(m_custom, space, megaduck_sound_offsets[offset], data );
1159   m_custom->sound_w(space, megaduck_sound_offsets[offset], data);
11611160}
11621161
11631162READ8_MEMBER(megaduck_state::megaduck_sound_r1)
11641163{
1165   return gb_sound_r( m_custom, space, megaduck_sound_offsets[offset] );
1164   return m_custom->sound_r(space, megaduck_sound_offsets[offset]);
11661165}
11671166
11681167WRITE8_MEMBER(megaduck_state::megaduck_sound_w2)
11691168{
11701169   switch(offset)
11711170   {
1172      case 0x00:  gb_sound_w(m_custom, space, 0x10, data ); break;
1173      case 0x01:  gb_sound_w(m_custom, space, 0x12, data ); break;
1174      case 0x02:  gb_sound_w(m_custom, space, 0x11, data ); break;
1175      case 0x03:  gb_sound_w(m_custom, space, 0x13, data ); break;
1176      case 0x04:  gb_sound_w(m_custom, space, 0x14, data ); break;
1177      case 0x05:  gb_sound_w(m_custom, space, 0x16, data ); break;
1178      case 0x06:  gb_sound_w(m_custom, space, 0x15, data ); break;
1171      case 0x00:  m_custom->sound_w(space, 0x10, data); break;
1172      case 0x01:  m_custom->sound_w(space, 0x12, data); break;
1173      case 0x02:  m_custom->sound_w(space, 0x11, data); break;
1174      case 0x03:  m_custom->sound_w(space, 0x13, data); break;
1175      case 0x04:  m_custom->sound_w(space, 0x14, data); break;
1176      case 0x05:  m_custom->sound_w(space, 0x16, data); break;
1177      case 0x06:  m_custom->sound_w(space, 0x15, data); break;
11791178      case 0x07:
11801179      case 0x08:
11811180      case 0x09:
r22897r22898
11911190
11921191READ8_MEMBER(megaduck_state::megaduck_sound_r2)
11931192{
1194   return gb_sound_r(m_custom, space, 0x10 + megaduck_sound_offsets[offset]);
1193   return m_custom->sound_r(space, 0x10 + megaduck_sound_offsets[offset]);
11951194}
trunk/src/mess/includes/gba.h
r22897r22898
11#ifndef _GBA_H_
22#define _GBA_H_
33
4#include "audio/gb.h"
45#include "machine/intelfsh.h"
56#include "sound/dac.h"
67
r22897r22898
160161   required_device<dac_device> m_radac;
161162   required_device<dac_device> m_lbdac;
162163   required_device<dac_device> m_rbdac;
163   required_device<device_t> m_gbsound;
164   required_device<gameboy_sound_device> m_gbsound;
164165
165166   void request_irq(UINT32 int_type);
166167   void dma_exec(FPTR ch);
trunk/src/mess/includes/gb.h
r22897r22898
77#ifndef GB_H_
88#define GB_H_
99
10#include "audio/gb.h"
1011#include "machine/gb_slot.h"
1112#include "machine/ram.h"
1213
r22897r22898
209210
210211protected:
211212   required_device<lr35902_cpu_device> m_maincpu;
212   required_device<device_t> m_custom;
213   required_device<gameboy_sound_device> m_custom;
213214   required_memory_region m_region_maincpu;
214215   optional_memory_bank m_rambank;   // cgb
215216   required_ioport m_inputs;

Previous 199869 Revisions Next


© 1997-2024 The MAME Team