Previous 199869 Revisions Next

r26013 Tuesday 5th November, 2013 at 20:38:57 UTC by Osso
Modernize nes_apu device. (nw)
Needs merging with N2A03 cpu core.
[src/emu/sound]nes_apu.c nes_apu.h nes_defs.h sound.mak
[src/mame]mame.mak
[src/mame/audio]dkong.c
[src/mame/drivers]cham24.c famibox.c multigam.c playch10.c punchout.c vsnes.c
[src/mame/includes]playch10.h vsnes.h
[src/mess]mess.mak
[src/mess/drivers]nes.c
[src/mess/includes]nes.h
[src/mess/machine]nes_mmc5.c nes_mmc5.h

trunk/src/mame/mame.mak
r26012r26013
176176SOUNDS += SN76496
177177SOUNDS += POKEY
178178SOUNDS += TIA
179SOUNDS += NES
179SOUNDS += NES_APU
180180SOUNDS += ASTROCADE
181181SOUNDS += NAMCO
182182SOUNDS += NAMCO_15XX
trunk/src/mame/includes/vsnes.h
r26012r26013
1#include "sound/nes_apu.h"
2#include "video/ppu2c0x.h"
3
14class vsnes_state : public driver_device
25{
36public:
r26012r26013
58      : driver_device(mconfig, type, tag),
69      m_maincpu(*this, "maincpu"),
710      m_subcpu(*this, "sub"),
11      m_nesapu1(*this, "nesapu1"),
12      m_nesapu2(*this, "nesapu2"),
13      m_ppu1(*this, "ppu1"),     
14      m_ppu2(*this, "ppu2"),     
815      m_work_ram(*this, "work_ram"),
916      m_work_ram_1(*this, "work_ram_1")
1017      { }
1118
1219   required_device<cpu_device> m_maincpu;
1320   optional_device<cpu_device> m_subcpu;
21   required_device<nesapu_device> m_nesapu1;
22   optional_device<nesapu_device> m_nesapu2;
23   required_device<ppu2c0x_device> m_ppu1;
24   optional_device<ppu2c0x_device> m_ppu2;
1425
1526   required_shared_ptr<UINT8> m_work_ram;
1627   optional_shared_ptr<UINT8> m_work_ram_1;
trunk/src/mame/includes/playch10.h
r26012r26013
11#include "machine/rp5h01.h"
2#include "sound/nes_apu.h"
3#include "video/ppu2c0x.h"
24
35struct chr_bank
46{
r26012r26013
1214   playch10_state(const machine_config &mconfig, device_type type, const char *tag)
1315      : driver_device(mconfig, type, tag),
1416      m_maincpu(*this, "maincpu"),
17      m_nesapu(*this, "nesapu"),
18      m_ppu(*this, "ppu"),
1519      m_rp5h01(*this, "rp5h01"),
1620      m_ram_8w(*this, "ram_8w"),
1721      m_videoram(*this, "videoram"),
r26012r26013
2024      { }
2125
2226   required_device<cpu_device> m_maincpu;
27   required_device<nesapu_device> m_nesapu;
28   required_device<ppu2c0x_device> m_ppu;
2329   optional_device<rp5h01_device> m_rp5h01;
2430
2531   required_shared_ptr<UINT8> m_ram_8w;
trunk/src/mame/drivers/multigam.c
r26012r26013
116116public:
117117   multigam_state(const machine_config &mconfig, device_type type, const char *tag)
118118      : driver_device(mconfig, type, tag),
119      m_maincpu(*this, "maincpu") { }
120
119      m_maincpu(*this, "maincpu"),
120      m_nesapu(*this, "nesapu"),
121      m_ppu(*this, "ppu") { }
122     
123   required_device<cpu_device> m_maincpu;
124   required_device<nesapu_device> m_nesapu;
125   required_device<ppu2c0x_device> m_ppu;
126   
121127   UINT8* m_nt_ram;
122128   UINT8* m_vram;
123129   UINT8* m_nt_page[4];
r26012r26013
195201   void multigm3_decrypt(UINT8* mem, int memsize, const UINT8* decode_nibble);
196202   void multigam3_mmc3_scanline_cb(int scanline, int vblank, int blanked);
197203   void ppu_irq(int *ppu_regs);
198   required_device<cpu_device> m_maincpu;
199204};
200205
201206
r26012r26013
286291WRITE8_MEMBER(multigam_state::sprite_dma_w)
287292{
288293   int source = (data & 7);
289   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
290   ppu->spriteram_dma(space, source);
294   m_ppu->spriteram_dma(space, source);
291295}
292296
293297READ8_MEMBER(multigam_state::psg_4015_r)
294298{
295   device_t *device = machine().device("nes");
296   return nes_psg_r(device, space, 0x15);
299   return m_nesapu->read(space, 0x15);
297300}
298301
299302WRITE8_MEMBER(multigam_state::psg_4015_w)
300303{
301   device_t *device = machine().device("nes");
302   nes_psg_w(device, space, 0x15, data);
304   m_nesapu->write(space, 0x15, data);
303305}
304306
305307WRITE8_MEMBER(multigam_state::psg_4017_w)
306308{
307   device_t *device = machine().device("nes");
308   nes_psg_w(device, space, 0x17, data);
309   m_nesapu->write(space, 0x17, data);
309310}
310311
311312/******************************************************
r26012r26013
408409   AM_RANGE(0x0000, 0x07ff) AM_RAM /* NES RAM */
409410   AM_RANGE(0x0800, 0x0fff) AM_RAM /* additional RAM */
410411   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write)
411   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nes", nes_psg_r, nes_psg_w)            /* PSG primary registers */
412   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nesapu", nesapu_device, read, write)            /* PSG primary registers */
412413   AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w)
413414   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg_4015_r, psg_4015_w)           /* PSG status / first control register */
414415   AM_RANGE(0x4016, 0x4016) AM_READWRITE(multigam_IN0_r, multigam_IN0_w)   /* IN0 - input port 1 */
r26012r26013
428429   AM_RANGE(0x3000, 0x3000) AM_WRITE(multigam_switch_prg_rom)
429430   AM_RANGE(0x3fff, 0x3fff) AM_WRITE(multigam_switch_gfx_rom)
430431   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write)
431   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nes", nes_psg_r, nes_psg_w)            /* PSG primary registers */
432   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nesapu", nesapu_device, read, write)            /* PSG primary registers */
432433   AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w)
433434   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg_4015_r, psg_4015_w)           /* PSG status / first control register */
434435   AM_RANGE(0x4016, 0x4016) AM_READWRITE(multigam_IN0_r, multigam_IN0_w)   /* IN0 - input port 1 */
r26012r26013
461462
462463WRITE8_MEMBER(multigam_state::multigam3_mmc3_rom_switch_w)
463464{
464   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
465
466465   /* basically, a MMC3 mapper from the nes */
467466   int bankmask = m_multigam3_mmc3_prg_size == 0x40000 ? 0x1f : 0x0f;
468467
r26012r26013
599598
600599      case 0x6000: /* disable irqs */
601600         machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, CLEAR_LINE);
602         ppu->set_scanline_callback(ppu2c0x_scanline_delegate());
601         m_ppu->set_scanline_callback(ppu2c0x_scanline_delegate());
603602      break;
604603
605604      case 0x6001: /* enable irqs */
606         ppu->set_scanline_callback(ppu2c0x_scanline_delegate(FUNC(multigam_state::multigam3_mmc3_scanline_cb),this));
605         m_ppu->set_scanline_callback(ppu2c0x_scanline_delegate(FUNC(multigam_state::multigam3_mmc3_scanline_cb),this));
607606      break;
608607   }
609608}
r26012r26013
693692   AM_RANGE(0x0000, 0x07ff) AM_RAM /* NES RAM */
694693   AM_RANGE(0x0800, 0x0fff) AM_RAM /* additional RAM */
695694   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write)
696   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nes", nes_psg_r, nes_psg_w)            /* PSG primary registers */
695   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nesapu", nesapu_device, read, write)            /* PSG primary registers */
697696   AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w)
698697   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg_4015_r, psg_4015_w)           /* PSG status / first control register */
699698   AM_RANGE(0x4016, 0x4016) AM_READWRITE(multigam_IN0_r, multigam_IN0_w)   /* IN0 - input port 1 */
r26012r26013
724723
725724void multigam_state::multigam_init_mapper02(UINT8* prg_base, int prg_size)
726725{
727   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
728726   UINT8* mem = memregion("maincpu")->base();
729727   memcpy(mem + 0x8000, prg_base + prg_size - 0x8000, 0x8000);
730728   m_maincpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(multigam_state::multigam3_mapper02_rom_switch_w),this));
731729
732730   m_mapper02_prg_base = prg_base;
733731   m_mapper02_prg_size = prg_size;
734   ppu->set_scanline_callback(ppu2c0x_scanline_delegate());
732   m_ppu->set_scanline_callback(ppu2c0x_scanline_delegate());
735733}
736734
737735/******************************************************
r26012r26013
877875void multigam_state::multigam_init_mmc1(UINT8 *prg_base, int prg_size, int chr_bank_base)
878876{
879877   UINT8* dst = memregion("maincpu")->base();
880   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
881
878   
882879   memcpy(&dst[0x8000], prg_base + (prg_size - 0x8000), 0x8000);
883880
884881   m_maincpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(multigam_state::mmc1_rom_switch_w),this));
r26012r26013
889886   m_mmc1_prg_size = prg_size;
890887   m_mmc1_chr_bank_base = chr_bank_base;
891888
892   ppu->set_scanline_callback(ppu2c0x_scanline_delegate());
889   m_ppu->set_scanline_callback(ppu2c0x_scanline_delegate());
893890};
894891
895892
r26012r26013
917914
918915void multigam_state::supergm3_set_bank()
919916{
920   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
921917   UINT8* mem = memregion("maincpu")->base();
922918
923919   // video bank
r26012r26013
925921      m_supergm3_chr_bank == 0x40 )
926922   {
927923      // VRAM
928      ppu->space(AS_PROGRAM).install_read_bank(0x0000, 0x1fff, "bank1");
929      ppu->space(AS_PROGRAM).install_write_bank(0x0000, 0x1fff, "bank1");
924      m_ppu->space(AS_PROGRAM).install_read_bank(0x0000, 0x1fff, "bank1");
925      m_ppu->space(AS_PROGRAM).install_write_bank(0x0000, 0x1fff, "bank1");
930926      membank("bank1")->set_base(m_vram);
931927
932928      if (m_supergm3_chr_bank == 0x40)
r26012r26013
934930   }
935931   else
936932   {
937      ppu->space(AS_PROGRAM).install_read_bank(0x0000, 0x03ff, "bank2");
938      ppu->space(AS_PROGRAM).install_read_bank(0x0400, 0x07ff, "bank3");
939      ppu->space(AS_PROGRAM).install_read_bank(0x0800, 0x0bff, "bank4");
940      ppu->space(AS_PROGRAM).install_read_bank(0x0c00, 0x0fff, "bank5");
941      ppu->space(AS_PROGRAM).install_read_bank(0x1000, 0x13ff, "bank6");
942      ppu->space(AS_PROGRAM).install_read_bank(0x1400, 0x17ff, "bank7");
943      ppu->space(AS_PROGRAM).install_read_bank(0x1800, 0x1bff, "bank8");
944      ppu->space(AS_PROGRAM).install_read_bank(0x1c00, 0x1fff, "bank9");
945      ppu->space(AS_PROGRAM).unmap_write(0x0000, 0x1fff);
933      m_ppu->space(AS_PROGRAM).install_read_bank(0x0000, 0x03ff, "bank2");
934      m_ppu->space(AS_PROGRAM).install_read_bank(0x0400, 0x07ff, "bank3");
935      m_ppu->space(AS_PROGRAM).install_read_bank(0x0800, 0x0bff, "bank4");
936      m_ppu->space(AS_PROGRAM).install_read_bank(0x0c00, 0x0fff, "bank5");
937      m_ppu->space(AS_PROGRAM).install_read_bank(0x1000, 0x13ff, "bank6");
938      m_ppu->space(AS_PROGRAM).install_read_bank(0x1400, 0x17ff, "bank7");
939      m_ppu->space(AS_PROGRAM).install_read_bank(0x1800, 0x1bff, "bank8");
940      m_ppu->space(AS_PROGRAM).install_read_bank(0x1c00, 0x1fff, "bank9");
941      m_ppu->space(AS_PROGRAM).unmap_write(0x0000, 0x1fff);
946942
947943      set_videorom_bank(0, 8, 0, 8);
948944   }
r26012r26013
953949      // title screen
954950      memcpy(mem + 0x8000, mem + 0x18000, 0x8000);
955951      membank("bank10")->set_base(mem + 0x6000);
956      ppu->set_scanline_callback(ppu2c0x_scanline_delegate());
952      m_ppu->set_scanline_callback(ppu2c0x_scanline_delegate());
957953   }
958954   else if ((m_supergm3_prg_bank & 0x40) == 0)
959955   {
r26012r26013
998994   AM_RANGE(0x0000, 0x07ff) AM_RAM /* NES RAM */
999995   AM_RANGE(0x0800, 0x0fff) AM_RAM /* additional RAM */
1000996   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write)
1001   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nes", nes_psg_r, nes_psg_w)            /* PSG primary registers */
997   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nesapu", nesapu_device, read, write)            /* PSG primary registers */
1002998   AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w)
1003999   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg_4015_r, psg_4015_w)           /* PSG status / first control register */
10041000   AM_RANGE(0x4016, 0x4016) AM_READWRITE(multigam_IN0_r, multigam_IN0_w)   /* IN0 - input port 1 */
r26012r26013
11441140
11451141*******************************************************/
11461142
1147static const nes_interface multigam_interface_1 =
1143static const nesapu_interface multigam_interface_1 =
11481144{
11491145   "maincpu"
11501146};
11511147
11521148void multigam_state::palette_init()
11531149{
1154   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
1155   ppu->init_palette(machine(), 0);
1150   m_ppu->init_palette(machine(), 0);
11561151}
11571152
11581153void multigam_state::ppu_irq(int *ppu_regs)
r26012r26013
11761171UINT32 multigam_state::screen_update_multigam(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
11771172{
11781173   /* render the ppu */
1179   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
1180   ppu->render(bitmap, 0, 0, 0, 0);
1174   m_ppu->render(bitmap, 0, 0, 0, 0);
11811175   return 0;
11821176}
11831177
r26012r26013
12101204   m_nt_page[2] = m_nt_ram + 0x800;
12111205   m_nt_page[3] = m_nt_ram + 0xc00;
12121206
1213   machine().device("ppu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(multigam_state::multigam_nt_r),this), write8_delegate(FUNC(multigam_state::multigam_nt_w),this));
1214   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x0000, 0x1fff, "bank1");
1207   m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(multigam_state::multigam_nt_r),this), write8_delegate(FUNC(multigam_state::multigam_nt_w),this));
1208   m_ppu->space(AS_PROGRAM).install_read_bank(0x0000, 0x1fff, "bank1");
12151209   membank("bank1")->set_base(memregion("gfx1")->base());
12161210}
12171211
r26012r26013
12231217   m_nt_page[2] = m_nt_ram + 0x800;
12241218   m_nt_page[3] = m_nt_ram + 0xc00;
12251219
1226   machine().device("ppu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(multigam_state::multigam_nt_r),this), write8_delegate(FUNC(multigam_state::multigam_nt_w),this));
1220   m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(multigam_state::multigam_nt_r),this), write8_delegate(FUNC(multigam_state::multigam_nt_w),this));
12271221
1228   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x0000, 0x03ff, "bank2");
1229   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x0400, 0x07ff, "bank3");
1230   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x0800, 0x0bff, "bank4");
1231   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x0c00, 0x0fff, "bank5");
1232   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x1000, 0x13ff, "bank6");
1233   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x1400, 0x17ff, "bank7");
1234   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x1800, 0x1bff, "bank8");
1235   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x1c00, 0x1fff, "bank9");
1222   m_ppu->space(AS_PROGRAM).install_read_bank(0x0000, 0x03ff, "bank2");
1223   m_ppu->space(AS_PROGRAM).install_read_bank(0x0400, 0x07ff, "bank3");
1224   m_ppu->space(AS_PROGRAM).install_read_bank(0x0800, 0x0bff, "bank4");
1225   m_ppu->space(AS_PROGRAM).install_read_bank(0x0c00, 0x0fff, "bank5");
1226   m_ppu->space(AS_PROGRAM).install_read_bank(0x1000, 0x13ff, "bank6");
1227   m_ppu->space(AS_PROGRAM).install_read_bank(0x1400, 0x17ff, "bank7");
1228   m_ppu->space(AS_PROGRAM).install_read_bank(0x1800, 0x1bff, "bank8");
1229   m_ppu->space(AS_PROGRAM).install_read_bank(0x1c00, 0x1fff, "bank9");
12361230
12371231   set_videorom_bank(0, 8, 0, 8);
12381232};
r26012r26013
12451239   m_nt_page[2] = m_nt_ram + 0x800;
12461240   m_nt_page[3] = m_nt_ram + 0xc00;
12471241
1248   machine().device("ppu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(multigam_state::multigam_nt_r),this), write8_delegate(FUNC(multigam_state::multigam_nt_w),this));
1242   m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(multigam_state::multigam_nt_r),this), write8_delegate(FUNC(multigam_state::multigam_nt_w),this));
12491243
12501244   m_vram = auto_alloc_array(machine(), UINT8, 0x2000);
12511245   m_multigmc_mmc3_6000_ram = auto_alloc_array(machine(), UINT8, 0x2000);
r26012r26013
12741268   /* sound hardware */
12751269   MCFG_SPEAKER_STANDARD_MONO("mono")
12761270
1277   MCFG_SOUND_ADD("nes", NES, N2A03_DEFAULTCLOCK)
1271   MCFG_SOUND_ADD("nesapu", NES_APU, N2A03_DEFAULTCLOCK)
12781272   MCFG_SOUND_CONFIG(multigam_interface_1)
12791273   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
12801274
trunk/src/mame/drivers/famibox.c
r26012r26013
7171public:
7272   famibox_state(const machine_config &mconfig, device_type type, const char *tag)
7373      : driver_device(mconfig, type, tag),
74      m_maincpu(*this, "maincpu") { }
74      m_maincpu(*this, "maincpu"),
75      m_nesapu(*this, "nesapu"),
76      m_ppu(*this, "ppu") { }
7577
78
79   required_device<cpu_device> m_maincpu;
80   required_device<nesapu_device> m_nesapu;
81   required_device<ppu2c0x_device> m_ppu;
82   
7683   UINT8* m_nt_ram;
7784   UINT8* m_nt_page[4];
7885
r26012r26013
117124   void famicombox_bankswitch(UINT8 bank);
118125   void famicombox_reset();
119126   void ppu_irq(int *ppu_regs);
120   required_device<cpu_device> m_maincpu;
121127};
122128
123129/******************************************************
r26012r26013
181187
182188WRITE8_MEMBER(famibox_state::sprite_dma_w)
183189{
184   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
185190   int source = (data & 7);
186   ppu->spriteram_dma(space, source);
191   m_ppu->spriteram_dma(space, source);
187192}
188193
189194READ8_MEMBER(famibox_state::psg_4015_r)
190195{
191   device_t *device = machine().device("nes");
192   return nes_psg_r(device, space, 0x15);
196   return m_nesapu->read(space, 0x15);
193197}
194198
195199WRITE8_MEMBER(famibox_state::psg_4015_w)
196200{
197   device_t *device = machine().device("nes");
198   nes_psg_w(device, space, 0x15, data);
201   m_nesapu->write(space, 0x15, data);
199202}
200203
201204WRITE8_MEMBER(famibox_state::psg_4017_w)
202205{
203   device_t *device = machine().device("nes");
204   nes_psg_w(device, space, 0x17, data);
206   m_nesapu->write(space, 0x17, data);
205207}
206208
207209/******************************************************
r26012r26013
393395static ADDRESS_MAP_START( famibox_map, AS_PROGRAM, 8, famibox_state )
394396   AM_RANGE(0x0000, 0x1fff) AM_RAM
395397   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write)
396   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nes", nes_psg_r, nes_psg_w)            /* PSG primary registers */
398   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nesapu", nesapu_device, read, write)            /* PSG primary registers */
397399   AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w)
398400   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg_4015_r, psg_4015_w)           /* PSG status / first control register */
399401   AM_RANGE(0x4016, 0x4016) AM_READWRITE(famibox_IN0_r, famibox_IN0_w) /* IN0 - input port 1 */
r26012r26013
509511
510512*******************************************************/
511513
512static const nes_interface famibox_interface_1 =
514static const nesapu_interface famibox_interface_1 =
513515{
514516   "maincpu"
515517};
516518
517519void famibox_state::palette_init()
518520{
519   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
520   ppu->init_palette(machine(), 0);
521   m_ppu->init_palette(machine(), 0);
521522}
522523
523524void famibox_state::ppu_irq(int *ppu_regs)
r26012r26013
541542UINT32 famibox_state::screen_update_famibox(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
542543{
543544   /* render the ppu */
544   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
545   ppu->render(bitmap, 0, 0, 0, 0);
545   m_ppu->render(bitmap, 0, 0, 0, 0);
546546   return 0;
547547}
548548
r26012r26013
563563   m_nt_page[2] = m_nt_ram + 0x800;
564564   m_nt_page[3] = m_nt_ram + 0xc00;
565565
566   machine().device("ppu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(famibox_state::famibox_nt_r), this), write8_delegate(FUNC(famibox_state::famibox_nt_w), this));
567   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x0000, 0x1fff, "ppubank1");
566   m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(famibox_state::famibox_nt_r), this), write8_delegate(FUNC(famibox_state::famibox_nt_w), this));
567   m_ppu->space(AS_PROGRAM).install_read_bank(0x0000, 0x1fff, "ppubank1");
568568
569569   famicombox_bankswitch(0);
570570
r26012r26013
601601   /* sound hardware */
602602   MCFG_SPEAKER_STANDARD_MONO("mono")
603603
604   MCFG_SOUND_ADD("nes", NES, N2A03_DEFAULTCLOCK)
604   MCFG_SOUND_ADD("nesapu", NES_APU, N2A03_DEFAULTCLOCK)
605605   MCFG_SOUND_CONFIG(famibox_interface_1)
606606   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
607607
trunk/src/mame/drivers/playch10.c
r26012r26013
291291
292292#include "emu.h"
293293#include "cpu/m6502/n2a03.h"
294#include "video/ppu2c0x.h"
295294#include "cpu/z80/z80.h"
296295#include "machine/rp5h01.h"
297296#include "machine/nvram.h"
298297#include "sound/dac.h"
299#include "sound/nes_apu.h"
300298
301299#include "rendlay.h"
302300#include "includes/playch10.h"
r26012r26013
331329WRITE8_MEMBER(playch10_state::sprite_dma_w)
332330{
333331   int source = ( data & 7 );
334   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
335   ppu->spriteram_dma(space, source);
332   m_ppu->spriteram_dma(space, source);
336333}
337334
338335/* Only used in single monitor bios */
r26012r26013
349346
350347READ8_MEMBER(playch10_state::psg_4015_r)
351348{
352   device_t *device = machine().device("nes");
353   return nes_psg_r(device, space, 0x15);
349   return m_nesapu->read(space, 0x15);
354350}
355351
356352WRITE8_MEMBER(playch10_state::psg_4015_w)
357353{
358   device_t *device = machine().device("nes");
359   nes_psg_w(device, space, 0x15, data);
354   m_nesapu->write(space, 0x15, data);
360355}
361356
362357WRITE8_MEMBER(playch10_state::psg_4017_w)
363358{
364   device_t *device = machine().device("nes");
365   nes_psg_w(device, space, 0x17, data);
359   m_nesapu->write(space, 0x17, data);
366360}
367361
368362/******************************************************************************/
r26012r26013
398392   AM_RANGE(0x0000, 0x07ff) AM_RAM AM_MIRROR(0x1800) AM_SHARE("work_ram")
399393   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write)
400394   AM_RANGE(0x4011, 0x4011) AM_DEVWRITE("dac", dac_device, write_unsigned8)
401   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nes", nes_psg_r, nes_psg_w)
395   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nesapu", nesapu_device, read, write)
402396   AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w)
403397   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg_4015_r, psg_4015_w)  /* PSG status / first control register */
404398   AM_RANGE(0x4016, 0x4016) AM_READWRITE(pc10_in0_r, pc10_in0_w)
r26012r26013
666660      device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
667661}
668662
669static const nes_interface nes_config =
663static const nesapu_interface nes_config =
670664{
671665   "cart"
672666};
r26012r26013
707701
708702   // sound hardware
709703   MCFG_SPEAKER_STANDARD_MONO("mono")
710   MCFG_SOUND_ADD("nes", NES, N2A03_DEFAULTCLOCK)
704   MCFG_SOUND_ADD("nesapu", NES_APU, N2A03_DEFAULTCLOCK)
711705   MCFG_SOUND_CONFIG(nes_config)
712706   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
713707
trunk/src/mame/drivers/vsnes.c
r26012r26013
142142#include "cpu/z80/z80.h"
143143#include "sound/sn76496.h"
144144#include "rendlay.h"
145#include "video/ppu2c0x.h"
146145#include "sound/dac.h"
147#include "sound/nes_apu.h"
148146#include "includes/vsnes.h"
149147
150148/******************************************************************************/
r26012r26013
153151WRITE8_MEMBER(vsnes_state::sprite_dma_0_w)
154152{
155153   int source = ( data & 7 );
156   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu1");
157   ppu->spriteram_dma( space, source );
154   m_ppu1->spriteram_dma( space, source );
158155}
159156
160157WRITE8_MEMBER(vsnes_state::sprite_dma_1_w)
161158{
162159   int source = ( data & 7 );
163   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu2");
164   ppu->spriteram_dma( space, source );
160   m_ppu2->spriteram_dma( space, source );
165161}
166162
167163WRITE8_MEMBER(vsnes_state::vsnes_coin_counter_w)
r26012r26013
196192
197193READ8_MEMBER(vsnes_state::psg1_4015_r)
198194{
199   device_t *device = machine().device("nes1");
200   return nes_psg_r(device, space, 0x15);
195   return m_nesapu1->read(space, 0x15);
201196}
202197
203198WRITE8_MEMBER(vsnes_state::psg1_4015_w)
204199{
205   device_t *device = machine().device("nes1");
206   nes_psg_w(device, space, 0x15, data);
200   m_nesapu1->write(space, 0x15, data);
207201}
208202
209203WRITE8_MEMBER(vsnes_state::psg1_4017_w)
210204{
211   device_t *device = machine().device("nes1");
212   nes_psg_w(device, space, 0x17, data);
205   m_nesapu1->write(space, 0x17, data);
213206}
214207
215208READ8_MEMBER(vsnes_state::psg2_4015_r)
216209{
217   device_t *device = machine().device("nes2");
218   return nes_psg_r(device, space, 0x15);
210   return m_nesapu2->read(space, 0x15);
219211}
220212
221213WRITE8_MEMBER(vsnes_state::psg2_4015_w)
222214{
223   device_t *device = machine().device("nes2");
224   nes_psg_w(device, space, 0x15, data);
215   m_nesapu2->write(space, 0x15, data);
225216}
226217
227218WRITE8_MEMBER(vsnes_state::psg2_4017_w)
228219{
229   device_t *device = machine().device("nes2");
230   nes_psg_w(device, space, 0x17, data);
220   m_nesapu2->write(space, 0x17, data);
231221}
232222static ADDRESS_MAP_START( vsnes_cpu1_map, AS_PROGRAM, 8, vsnes_state )
233223   AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x1800) AM_RAM AM_SHARE("work_ram")
234224   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu1", ppu2c0x_device, read, write)
235225   AM_RANGE(0x4011, 0x4011) AM_DEVWRITE("dac1", dac_device, write_unsigned8)
236   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nes1", nes_psg_r, nes_psg_w)
226   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nesapu1", nesapu_device, read, write)
237227   AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_0_w)
238228   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg1_4015_r, psg1_4015_w) /* PSG status / first control register */
239229   AM_RANGE(0x4016, 0x4016) AM_READWRITE(vsnes_in0_r, vsnes_in0_w)
r26012r26013
247237   AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x1800) AM_RAM AM_SHARE("work_ram_1")
248238   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu2", ppu2c0x_device, read, write)
249239   AM_RANGE(0x4011, 0x4011) AM_DEVWRITE("dac2", dac_device, write_unsigned8)
250   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nes2", nes_psg_r, nes_psg_w)
240   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nesapu2", nesapu_device, read, write)
251241   AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_1_w)
252242   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg2_4015_r, psg2_4015_w) /* PSG status / first control register */
253243   AM_RANGE(0x4016, 0x4016) AM_READWRITE(vsnes_in0_1_r, vsnes_in0_1_w)
r26012r26013
264254   AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x1800) AM_RAM AM_SHARE("work_ram")
265255   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu1", ppu2c0x_device, read, write)
266256   AM_RANGE(0x4011, 0x4011) AM_DEVWRITE("dac1", dac_device, write_unsigned8)
267   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nes1", nes_psg_r, nes_psg_w)
257   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nesapu1", nesapu_device, read, write)
268258   AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_0_w)
269259   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg1_4015_r, psg1_4015_w) /* PSG status / first control register */
270260   AM_RANGE(0x4016, 0x4016) AM_READWRITE(vsnes_in0_r, vsnes_in0_w)
r26012r26013
17061696   PORT_DIPSETTING(    0xc0, "RP2C04-0004" )
17071697INPUT_PORTS_END
17081698
1709static const nes_interface nes_interface_1 =
1699static const nesapu_interface nes_interface_1 =
17101700{
17111701   "maincpu"
17121702};
17131703
1714static const nes_interface nes_interface_2 =
1704static const nesapu_interface nes_interface_2 =
17151705{
17161706   "sub"
17171707};
r26012r26013
17441734   /* sound hardware */
17451735   MCFG_SPEAKER_STANDARD_MONO("mono")
17461736
1747   MCFG_SOUND_ADD("nes1", NES, N2A03_DEFAULTCLOCK)
1737   MCFG_SOUND_ADD("nesapu1", NES_APU, N2A03_DEFAULTCLOCK)
17481738   MCFG_SOUND_CONFIG(nes_interface_1)
17491739   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
17501740
r26012r26013
18251815   /* sound hardware */
18261816   MCFG_SPEAKER_STANDARD_MONO("mono")
18271817
1828   MCFG_SOUND_ADD("nes1", NES, N2A03_DEFAULTCLOCK)
1818   MCFG_SOUND_ADD("nesapu1", NES_APU, N2A03_DEFAULTCLOCK)
18291819   MCFG_SOUND_CONFIG(nes_interface_1)
18301820   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
18311821
1832   MCFG_SOUND_ADD("nes2", NES, N2A03_DEFAULTCLOCK)
1822   MCFG_SOUND_ADD("nesapu2", NES_APU, N2A03_DEFAULTCLOCK)
18331823   MCFG_SOUND_CONFIG(nes_interface_2)
18341824   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
18351825
r26012r26013
18811871   /* sound hardware */
18821872   MCFG_SPEAKER_STANDARD_MONO("mono")
18831873
1884   MCFG_SOUND_ADD("nes1", NES, N2A03_DEFAULTCLOCK)
1874   MCFG_SOUND_ADD("nesapu1", NES_APU, N2A03_DEFAULTCLOCK)
18851875   MCFG_SOUND_CONFIG(nes_interface_1)
18861876   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
18871877
trunk/src/mame/drivers/punchout.c
r26012r26013
370370   AM_RANGE(0x0000, 0x07ff) AM_RAM
371371   AM_RANGE(0x4016, 0x4016) AM_READ(soundlatch_byte_r)
372372   AM_RANGE(0x4017, 0x4017) AM_READ(soundlatch2_byte_r)
373   AM_RANGE(0x4000, 0x4017) AM_DEVREADWRITE_LEGACY("nes", nes_psg_r,nes_psg_w)
373   AM_RANGE(0x4000, 0x4017) AM_DEVREADWRITE("nesapu", nesapu_device, read, write)
374374   AM_RANGE(0xe000, 0xffff) AM_ROM
375375ADDRESS_MAP_END
376376
r26012r26013
912912
913913
914914
915static const nes_interface nes_config =
915static const nesapu_interface nes_config =
916916{
917917   "audiocpu"
918918};
r26012r26013
968968   /* sound hardware */
969969   MCFG_SPEAKER_STANDARD_MONO("mono")
970970
971   MCFG_SOUND_ADD("nes", NES, N2A03_DEFAULTCLOCK)
971   MCFG_SOUND_ADD("nesapu", NES_APU, N2A03_DEFAULTCLOCK)
972972   MCFG_SOUND_CONFIG(nes_config)
973973   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
974974
trunk/src/mame/drivers/cham24.c
r26012r26013
6666public:
6767   cham24_state(const machine_config &mconfig, device_type type, const char *tag)
6868      : driver_device(mconfig, type, tag),
69      m_maincpu(*this, "maincpu") { }
69      m_maincpu(*this, "maincpu"),
70      m_nesapu(*this, "nesapu"),
71      m_ppu(*this, "ppu") { }
7072
73   required_device<cpu_device> m_maincpu;
74   required_device<nesapu_device> m_nesapu;
75   required_device<ppu2c0x_device> m_ppu;
76   
7177   UINT8* m_nt_ram;
7278   UINT8* m_nt_page[4];
7379   UINT32 m_in_0;
r26012r26013
9298   UINT32 screen_update_cham24(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
9399   void cham24_set_mirroring( int mirroring );
94100   void ppu_irq(int *ppu_regs);
95   required_device<cpu_device> m_maincpu;
96101};
97102
98103
r26012r26013
145150WRITE8_MEMBER(cham24_state::sprite_dma_w)
146151{
147152   int source = (data & 7);
148   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
149   ppu->spriteram_dma(space, source);
153   m_ppu->spriteram_dma(space, source);
150154}
151155
152156READ8_MEMBER(cham24_state::psg_4015_r)
153157{
154   device_t *device = machine().device("nes");
155   return nes_psg_r(device,space,0x15);
158   return m_nesapu->read(space,0x15);
156159}
157160
158161WRITE8_MEMBER(cham24_state::psg_4015_w)
159162{
160   device_t *device = machine().device("nes");
161   nes_psg_w(device,space,0x15, data);
163   m_nesapu->write(space,0x15, data);
162164}
163165
164166WRITE8_MEMBER(cham24_state::psg_4017_w)
165167{
166   device_t *device = machine().device("nes");
167   nes_psg_w(device,space,0x17, data);
168   m_nesapu->write(space,0x17, data);
168169}
169170
170171
r26012r26013
241242static ADDRESS_MAP_START( cham24_map, AS_PROGRAM, 8, cham24_state )
242243   AM_RANGE(0x0000, 0x07ff) AM_RAM /* NES RAM */
243244   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write)
244   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nes", nes_psg_r, nes_psg_w)            /* PSG primary registers */
245   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nesapu", nesapu_device, read, write)            /* PSG primary registers */
245246   AM_RANGE(0x4014, 0x4014) AM_WRITE(sprite_dma_w)
246247   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg_4015_r, psg_4015_w)           /* PSG status / first control register */
247248   AM_RANGE(0x4016, 0x4016) AM_READWRITE(cham24_IN0_r,        cham24_IN0_w)            /* IN0 - input port 1 */
r26012r26013
271272   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
272273INPUT_PORTS_END
273274
274static const nes_interface cham24_interface_1 =
275static const nesapu_interface cham24_interface_1 =
275276{
276277   "maincpu"
277278};
r26012r26013
282283
283284void cham24_state::palette_init()
284285{
285   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
286   ppu->init_palette(machine(), 0);
286   m_ppu->init_palette(machine(), 0);
287287}
288288
289289void cham24_state::ppu_irq(int *ppu_regs)
r26012r26013
307307UINT32 cham24_state::screen_update_cham24(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
308308{
309309   /* render the ppu */
310   ppu2c0x_device *ppu = machine().device<ppu2c0x_device>("ppu");
311   ppu->render(bitmap, 0, 0, 0, 0);
310   m_ppu->render(bitmap, 0, 0, 0, 0);
312311   return 0;
313312}
314313
r26012r26013
323322   memcpy(&dst[0xc000], &src[0x0f8000], 0x4000);
324323
325324   /* uses 8K swapping, all ROM!*/
326   machine().device("ppu")->memory().space(AS_PROGRAM).install_read_bank(0x0000, 0x1fff, "bank1");
325   m_ppu->space(AS_PROGRAM).install_read_bank(0x0000, 0x1fff, "bank1");
327326   membank("bank1")->set_base(memregion("gfx1")->base());
328327
329328   /* need nametable ram, though. I doubt this uses more than 2k, but it starts up configured for 4 */
r26012r26013
334333   m_nt_page[3] = m_nt_ram + 0xc00;
335334
336335   /* and read/write handlers */
337   machine().device("ppu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff,read8_delegate(FUNC(cham24_state::nt_r), this), write8_delegate(FUNC(cham24_state::nt_w), this));
336   m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff,read8_delegate(FUNC(cham24_state::nt_r), this), write8_delegate(FUNC(cham24_state::nt_w), this));
338337}
339338
340339DRIVER_INIT_MEMBER(cham24_state,cham24)
r26012r26013
368367   /* sound hardware */
369368   MCFG_SPEAKER_STANDARD_MONO("mono")
370369
371   MCFG_SOUND_ADD("nes", NES, N2A03_DEFAULTCLOCK)
370   MCFG_SOUND_ADD("nesapu", NES_APU, N2A03_DEFAULTCLOCK)
372371   MCFG_SOUND_CONFIG(cham24_interface_1)
373372   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
374373
trunk/src/mame/audio/dkong.c
r26012r26013
13131313   AM_RANGE(0x0000, 0x01ff) AM_RAM
13141314   AM_RANGE(0x4016, 0x4016) AM_LATCH8_READ("latch1")       /* overwrite default */
13151315   AM_RANGE(0x4017, 0x4017) AM_LATCH8_READ("latch2")
1316   AM_RANGE(0x4000, 0x4017) AM_DEVREAD_LEGACY("nes1", nes_psg_r)
1317   AM_RANGE(0x4000, 0x4017) AM_DEVWRITE_LEGACY("nes1", nes_psg_w)
1316   AM_RANGE(0x4000, 0x4017) AM_DEVREAD("nesapu1", nesapu_device, read)
1317   AM_RANGE(0x4000, 0x4017) AM_DEVWRITE("nesapu1", nesapu_device, write)
13181318   AM_RANGE(0xe000, 0xffff) AM_ROM
13191319ADDRESS_MAP_END
13201320
13211321static ADDRESS_MAP_START( dkong3_sound2_map, AS_PROGRAM, 8, dkong_state )
13221322   AM_RANGE(0x0000, 0x01ff) AM_RAM
13231323   AM_RANGE(0x4016, 0x4016) AM_LATCH8_READ("latch3")       /* overwrite default */
1324   AM_RANGE(0x4000, 0x4017) AM_DEVREAD_LEGACY("nes2", nes_psg_r)
1325   AM_RANGE(0x4000, 0x4017) AM_DEVWRITE_LEGACY("nes2", nes_psg_w)
1324   AM_RANGE(0x4000, 0x4017) AM_DEVREAD("nesapu2", nesapu_device, read)
1325   AM_RANGE(0x4000, 0x4017) AM_DEVWRITE("nesapu2", nesapu_device, write)
13261326   AM_RANGE(0xe000, 0xffff) AM_ROM
13271327ADDRESS_MAP_END
13281328
r26012r26013
13321332 *
13331333 *************************************/
13341334
1335static const nes_interface nes_interface_1 = { "n2a03a" };
1336static const nes_interface nes_interface_2 = { "n2a03b" };
1335static const nesapu_interface nes_interface_1 = { "n2a03a" };
1336static const nesapu_interface nes_interface_2 = { "n2a03b" };
13371337
13381338const tms5110_interface tms_interface = {
13391339   NULL,
r26012r26013
14661466   MCFG_LATCH8_ADD( "latch3")
14671467
14681468   MCFG_SPEAKER_STANDARD_MONO("mono")
1469   MCFG_SOUND_ADD("nes1", NES, N2A03_DEFAULTCLOCK)
1469   MCFG_SOUND_ADD("nesapu1", NES_APU, N2A03_DEFAULTCLOCK)
14701470   MCFG_SOUND_CONFIG(nes_interface_1)
14711471   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
14721472
1473   MCFG_SOUND_ADD("nes2", NES, N2A03_DEFAULTCLOCK)
1473   MCFG_SOUND_ADD("nesapu2", NES_APU, N2A03_DEFAULTCLOCK)
14741474   MCFG_SOUND_CONFIG(nes_interface_2)
14751475   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
14761476
trunk/src/emu/sound/sound.mak
r26012r26013
403403
404404#-------------------------------------------------
405405# Nintendo custom sound chips
406#@src/emu/sound/nes_apu.h,SOUNDS += NES
406#@src/emu/sound/nes_apu.h,SOUNDS += NES_APU
407407#-------------------------------------------------
408408
409ifneq ($(filter NES,$(SOUNDS)),)
409ifneq ($(filter NES_APU,$(SOUNDS)),)
410410SOUNDOBJS += $(SOUNDOBJ)/nes_apu.o
411411endif
412412
trunk/src/emu/sound/nes_apu.c
r26012r26013
4747#include "emu.h"
4848#include "nes_apu.h"
4949#include "cpu/m6502/n2a03.h"
50#include "devlegcy.h"
5150
52#include "nes_defs.h"
5351
54/* GLOBAL CONSTANTS */
55#define  SYNCS_MAX1     0x20
56#define  SYNCS_MAX2     0x80
5752
58/* GLOBAL VARIABLES */
59struct nesapu_state
60{
61   apu_t   APU;                   /* Actual APUs */
62   float   apu_incsize;           /* Adjustment increment */
63   uint32  samps_per_sync;        /* Number of samples per vsync */
64   uint32  buffer_size;           /* Actual buffer size in bytes */
65   uint32  real_rate;             /* Actual playback rate */
66   uint8   noise_lut[NOISE_LONG]; /* Noise sample lookup table */
67   uint32  vbl_times[0x20];       /* VBL durations in samples */
68   uint32  sync_times1[SYNCS_MAX1]; /* Samples per sync table */
69   uint32  sync_times2[SYNCS_MAX2]; /* Samples per sync table */
70   sound_stream *stream;
71};
72
73
74INLINE nesapu_state *get_safe_token(device_t *device)
75{
76   assert(device != NULL);
77   assert(device->type() == NES);
78   return (nesapu_state *)downcast<nesapu_device *>(device)->token();
79}
80
8153/* INTERNAL FUNCTIONS */
8254
8355/* INITIALIZE WAVE TIMES RELATIVE TO SAMPLE RATE */
r26012r26013
9062}
9163
9264/* INITIALIZE SAMPLE TIMES IN TERMS OF VSYNCS */
93static void create_syncs(nesapu_state *info, unsigned long sps)
65void nesapu_device::create_syncs(unsigned long sps)
9466{
9567   int i;
9668   unsigned long val = sps;
9769
9870   for (i = 0; i < SYNCS_MAX1; i++)
9971   {
100      info->sync_times1[i] = val;
72      m_sync_times1[i] = val;
10173      val += sps;
10274   }
10375
10476   val = 0;
10577   for (i = 0; i < SYNCS_MAX2; i++)
10678   {
107      info->sync_times2[i] = val;
108      info->sync_times2[i] >>= 2;
79      m_sync_times2[i] = val;
80      m_sync_times2[i] >>= 2;
10981      val += sps;
11082   }
11183}
r26012r26013
12799   }
128100}
129101
102const device_type NES_APU = &device_creator<nesapu_device>;
103
104nesapu_device::nesapu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
105   : device_t(mconfig, NES_APU, "N2A03 APU", tag, owner, clock, "nesapu", __FILE__),
106      device_sound_interface(mconfig, *this),
107      m_apu_incsize(0.0d),
108      m_samps_per_sync(0),
109      m_buffer_size(0),
110      m_real_rate(0),
111      m_stream(NULL)
112{
113   for (int i = 0; i < NOISE_LONG; i++)
114   {
115      m_noise_lut[i] = 0;
116   }
117   
118   for (int i = 0; i < 0X20; i++)
119   {
120      m_vbl_times[i] = 0;
121   }
122   
123   for (int i = 0; i < SYNCS_MAX1; i++)
124   {
125      m_sync_times1[i] = 0;
126   }
127   
128   for (int i = 0; i < SYNCS_MAX2; i++)
129   {
130      m_sync_times2[i] = 0;
131   }
132}
133
134//-------------------------------------------------
135//  device_config_complete - perform any
136//  operations now that the configuration is
137//  complete
138//-------------------------------------------------
139
140void nesapu_device::device_config_complete()
141{
142   // inherit a copy of the static data
143   const nesapu_interface *intf = reinterpret_cast<const nesapu_interface *>(static_config());
144   if (intf != NULL)
145   *static_cast<nesapu_interface *>(this) = *intf;
146
147   // or initialize to defaults if none provided
148   else
149   {
150      m_cpu_tag = "";
151   }
152}
153
154//-------------------------------------------------
155//  device_start - device-specific startup
156//-------------------------------------------------
157
158void nesapu_device::device_start()
159{
160   int rate = clock() / 4;
161   int i;
162
163   /* Initialize global variables */
164   m_samps_per_sync = rate / ATTOSECONDS_TO_HZ(machine().primary_screen->frame_period().attoseconds);
165   m_buffer_size = m_samps_per_sync;
166   m_real_rate = m_samps_per_sync * ATTOSECONDS_TO_HZ(machine().primary_screen->frame_period().attoseconds);
167   m_apu_incsize = (float) (clock() / (float) m_real_rate);
168
169   /* Use initializer calls */
170   create_noise(m_noise_lut, 13, NOISE_LONG);
171   create_vbltimes(m_vbl_times,vbl_length,m_samps_per_sync);
172   create_syncs(m_samps_per_sync);
173
174   /* Adjust buffer size if 16 bits */
175   m_buffer_size+=m_samps_per_sync;
176
177   /* Initialize individual chips */
178   (m_APU.dpcm).memory = &machine().device(m_cpu_tag)->memory().space(AS_PROGRAM);
179
180   m_stream = machine().sound().stream_alloc(*this, 0, 1, rate, this);
181
182   /* register for save */
183   for (i = 0; i < 2; i++)
184   {
185      save_item(NAME(m_APU.squ[i].regs), i);
186      save_item(NAME(m_APU.squ[i].vbl_length), i);
187      save_item(NAME(m_APU.squ[i].freq), i);
188      save_item(NAME(m_APU.squ[i].phaseacc), i);
189      save_item(NAME(m_APU.squ[i].output_vol), i);
190      save_item(NAME(m_APU.squ[i].env_phase), i);
191      save_item(NAME(m_APU.squ[i].sweep_phase), i);
192      save_item(NAME(m_APU.squ[i].adder), i);
193      save_item(NAME(m_APU.squ[i].env_vol), i);
194      save_item(NAME(m_APU.squ[i].enabled), i);
195   }
196
197   save_item(NAME(m_APU.tri.regs));
198   save_item(NAME(m_APU.tri.linear_length));
199   save_item(NAME(m_APU.tri.vbl_length));
200   save_item(NAME(m_APU.tri.write_latency));
201   save_item(NAME(m_APU.tri.phaseacc));
202   save_item(NAME(m_APU.tri.output_vol));
203   save_item(NAME(m_APU.tri.adder));
204   save_item(NAME(m_APU.tri.counter_started));
205   save_item(NAME(m_APU.tri.enabled));
206
207   save_item(NAME(m_APU.noi.regs));
208   save_item(NAME(m_APU.noi.cur_pos));
209   save_item(NAME(m_APU.noi.vbl_length));
210   save_item(NAME(m_APU.noi.phaseacc));
211   save_item(NAME(m_APU.noi.output_vol));
212   save_item(NAME(m_APU.noi.env_phase));
213   save_item(NAME(m_APU.noi.env_vol));
214   save_item(NAME(m_APU.noi.enabled));
215
216   save_item(NAME(m_APU.dpcm.regs));
217   save_item(NAME(m_APU.dpcm.address));
218   save_item(NAME(m_APU.dpcm.length));
219   save_item(NAME(m_APU.dpcm.bits_left));
220   save_item(NAME(m_APU.dpcm.phaseacc));
221   save_item(NAME(m_APU.dpcm.output_vol));
222   save_item(NAME(m_APU.dpcm.cur_byte));
223   save_item(NAME(m_APU.dpcm.enabled));
224   save_item(NAME(m_APU.dpcm.irq_occurred));
225   save_item(NAME(m_APU.dpcm.vol));
226
227   save_item(NAME(m_APU.regs));
228
229   #ifdef USE_QUEUE
230   save_item(NAME(m_APU.queue));
231   save_item(NAME(m_APU.head));
232   save_item(NAME(m_APU.tail));
233   #else
234   save_item(NAME(m_APU.buf_pos));
235   save_item(NAME(m_APU.step_mode));
236   #endif   
237}
238
130239/* TODO: sound channels should *ALL* have DC volume decay */
131240
132241/* OUTPUT SQUARE WAVE SAMPLE (VALUES FROM -16 to +15) */
133static int8 apu_square(nesapu_state *info, square_t *chan)
242int8 nesapu_device::apu_square(square_t *chan)
134243{
135244   int env_delay;
136245   int sweep_delay;
r26012r26013
146255      return 0;
147256
148257   /* enveloping */
149   env_delay = info->sync_times1[chan->regs[0] & 0x0F];
258   env_delay = m_sync_times1[chan->regs[0] & 0x0F];
150259
151260   /* decay is at a rate of (env_regs + 1) / 240 secs */
152261   chan->env_phase -= 4;
r26012r26013
169278   /* freqsweeps */
170279   if ((chan->regs[1] & 0x80) && (chan->regs[1] & 7))
171280   {
172      sweep_delay = info->sync_times1[(chan->regs[1] >> 4) & 7];
281      sweep_delay = m_sync_times1[(chan->regs[1] >> 4) & 7];
173282      chan->sweep_phase -= 2;
174283      while (chan->sweep_phase < 0)
175284      {
r26012r26013
185294         || (chan->freq >> 16) < 4)
186295      return 0;
187296
188   chan->phaseacc -= (float) info->apu_incsize; /* # of cycles per sample */
297   chan->phaseacc -= (float) m_apu_incsize; /* # of cycles per sample */
189298
190299   while (chan->phaseacc < 0)
191300   {
r26012r26013
205314}
206315
207316/* OUTPUT TRIANGLE WAVE SAMPLE (VALUES FROM -16 to +15) */
208static int8 apu_triangle(nesapu_state *info, triangle_t *chan)
317int8 nesapu_device::apu_triangle(triangle_t *chan)
209318{
210319   int freq;
211320   int8 output;
r26012r26013
244353   if (freq < 4) /* inaudible */
245354      return 0;
246355
247   chan->phaseacc -= (float) info->apu_incsize; /* # of cycles per sample */
356   chan->phaseacc -= (float) m_apu_incsize; /* # of cycles per sample */
248357   while (chan->phaseacc < 0)
249358   {
250359      chan->phaseacc += freq;
r26012r26013
263372}
264373
265374/* OUTPUT NOISE WAVE SAMPLE (VALUES FROM -16 to +15) */
266static int8 apu_noise(nesapu_state *info, noise_t *chan)
375int8 nesapu_device::apu_noise(noise_t *chan)
267376{
268377   int freq, env_delay;
269378   uint8 outvol;
r26012r26013
278387      return 0;
279388
280389   /* enveloping */
281   env_delay = info->sync_times1[chan->regs[0] & 0x0F];
390   env_delay = m_sync_times1[chan->regs[0] & 0x0F];
282391
283392   /* decay is at a rate of (env_regs + 1) / 240 secs */
284393   chan->env_phase -= 4;
r26012r26013
302411      return 0;
303412
304413   freq = noise_freq[chan->regs[2] & 0x0F];
305   chan->phaseacc -= (float) info->apu_incsize; /* # of cycles per sample */
414   chan->phaseacc -= (float) m_apu_incsize; /* # of cycles per sample */
306415   while (chan->phaseacc < 0)
307416   {
308417      chan->phaseacc += freq;
r26012r26013
319428   else
320429      outvol = 0x0F - chan->env_vol;
321430
322   output = info->noise_lut[chan->cur_pos];
431   output = m_noise_lut[chan->cur_pos];
323432   if (output > outvol)
324433      output = outvol;
325434
326   if (info->noise_lut[chan->cur_pos] & 0x80) /* make it negative */
435   if (m_noise_lut[chan->cur_pos] & 0x80) /* make it negative */
327436      output = -output;
328437
329438   return (int8) output;
r26012r26013
342451
343452/* OUTPUT DPCM WAVE SAMPLE (VALUES FROM -64 to +63) */
344453/* TODO: centerline naughtiness */
345static int8 apu_dpcm(nesapu_state *info, dpcm_t *chan)
454int8 nesapu_device::apu_dpcm(dpcm_t *chan)
346455{
347456   int freq, bit_pos;
348457
r26012r26013
355464   if (chan->enabled)
356465   {
357466      freq = dpcm_clocks[chan->regs[0] & 0x0F];
358      chan->phaseacc -= (float) info->apu_incsize; /* # of cycles per sample */
467      chan->phaseacc -= (float) m_apu_incsize; /* # of cycles per sample */
359468
360469      while (chan->phaseacc < 0)
361470      {
r26012r26013
372481               if (chan->regs[0] & 0x80) /* IRQ Generator */
373482               {
374483                  chan->irq_occurred = TRUE;
375                  downcast<n2a03_device &>(info->APU.dpcm.memory->device()).set_input_line(N2A03_APU_IRQ_LINE, ASSERT_LINE);
484                  downcast<n2a03_device &>(m_APU.dpcm.memory->device()).set_input_line(N2A03_APU_IRQ_LINE, ASSERT_LINE);
376485               }
377486               break;
378487            }
r26012r26013
383492         bit_pos = 7 - (chan->bits_left & 7);
384493         if (7 == bit_pos)
385494         {
386            chan->cur_byte = info->APU.dpcm.memory->read_byte(chan->address);
495            chan->cur_byte = m_APU.dpcm.memory->read_byte(chan->address);
387496            chan->address++;
388497            chan->length--;
389498         }
r26012r26013
406515}
407516
408517/* WRITE REGISTER VALUE */
409INLINE void apu_regwrite(nesapu_state *info,int address, uint8 value)
518inline void nesapu_device::apu_regwrite(int address, uint8 value)
410519{
411520   int chan = (address & 4) ? 1 : 0;
412521
r26012r26013
415524   /* squares */
416525   case APU_WRA0:
417526   case APU_WRB0:
418      info->APU.squ[chan].regs[0] = value;
527      m_APU.squ[chan].regs[0] = value;
419528      break;
420529
421530   case APU_WRA1:
422531   case APU_WRB1:
423      info->APU.squ[chan].regs[1] = value;
532      m_APU.squ[chan].regs[1] = value;
424533      break;
425534
426535   case APU_WRA2:
427536   case APU_WRB2:
428      info->APU.squ[chan].regs[2] = value;
429      if (info->APU.squ[chan].enabled)
430         info->APU.squ[chan].freq = ((((info->APU.squ[chan].regs[3] & 7) << 8) + value) + 1) << 16;
537      m_APU.squ[chan].regs[2] = value;
538      if (m_APU.squ[chan].enabled)
539         m_APU.squ[chan].freq = ((((m_APU.squ[chan].regs[3] & 7) << 8) + value) + 1) << 16;
431540      break;
432541
433542   case APU_WRA3:
434543   case APU_WRB3:
435      info->APU.squ[chan].regs[3] = value;
544      m_APU.squ[chan].regs[3] = value;
436545
437      if (info->APU.squ[chan].enabled)
546      if (m_APU.squ[chan].enabled)
438547      {
439         info->APU.squ[chan].vbl_length = info->vbl_times[value >> 3];
440         info->APU.squ[chan].env_vol = 0;
441         info->APU.squ[chan].freq = ((((value & 7) << 8) + info->APU.squ[chan].regs[2]) + 1) << 16;
548         m_APU.squ[chan].vbl_length = m_vbl_times[value >> 3];
549         m_APU.squ[chan].env_vol = 0;
550         m_APU.squ[chan].freq = ((((value & 7) << 8) + m_APU.squ[chan].regs[2]) + 1) << 16;
442551      }
443552
444553      break;
445554
446555   /* triangle */
447556   case APU_WRC0:
448      info->APU.tri.regs[0] = value;
557      m_APU.tri.regs[0] = value;
449558
450      if (info->APU.tri.enabled)
559      if (m_APU.tri.enabled)
451560      {                                          /* ??? */
452         if (FALSE == info->APU.tri.counter_started)
453            info->APU.tri.linear_length = info->sync_times2[value & 0x7F];
561         if (FALSE == m_APU.tri.counter_started)
562            m_APU.tri.linear_length = m_sync_times2[value & 0x7F];
454563      }
455564
456565      break;
457566
458567   case 0x4009:
459568      /* unused */
460      info->APU.tri.regs[1] = value;
569      m_APU.tri.regs[1] = value;
461570      break;
462571
463572   case APU_WRC2:
464      info->APU.tri.regs[2] = value;
573      m_APU.tri.regs[2] = value;
465574      break;
466575
467576   case APU_WRC3:
468      info->APU.tri.regs[3] = value;
577      m_APU.tri.regs[3] = value;
469578
470579      /* this is somewhat of a hack.  there is some latency on the Real
471580      ** Thing between when trireg0 is written to and when the linear
r26012r26013
483592      */
484593
485594   /* used to be 3, but now we run the clock faster, so base it on samples/sync */
486      info->APU.tri.write_latency = (info->samps_per_sync + 239) / 240;
595      m_APU.tri.write_latency = (m_samps_per_sync + 239) / 240;
487596
488      if (info->APU.tri.enabled)
597      if (m_APU.tri.enabled)
489598      {
490         info->APU.tri.counter_started = FALSE;
491         info->APU.tri.vbl_length = info->vbl_times[value >> 3];
492         info->APU.tri.linear_length = info->sync_times2[info->APU.tri.regs[0] & 0x7F];
599         m_APU.tri.counter_started = FALSE;
600         m_APU.tri.vbl_length = m_vbl_times[value >> 3];
601         m_APU.tri.linear_length = m_sync_times2[m_APU.tri.regs[0] & 0x7F];
493602      }
494603
495604      break;
496605
497606   /* noise */
498607   case APU_WRD0:
499      info->APU.noi.regs[0] = value;
608      m_APU.noi.regs[0] = value;
500609      break;
501610
502611   case 0x400D:
503612      /* unused */
504      info->APU.noi.regs[1] = value;
613      m_APU.noi.regs[1] = value;
505614      break;
506615
507616   case APU_WRD2:
508      info->APU.noi.regs[2] = value;
617      m_APU.noi.regs[2] = value;
509618      break;
510619
511620   case APU_WRD3:
512      info->APU.noi.regs[3] = value;
621      m_APU.noi.regs[3] = value;
513622
514      if (info->APU.noi.enabled)
623      if (m_APU.noi.enabled)
515624      {
516         info->APU.noi.vbl_length = info->vbl_times[value >> 3];
517         info->APU.noi.env_vol = 0; /* reset envelope */
625         m_APU.noi.vbl_length = m_vbl_times[value >> 3];
626         m_APU.noi.env_vol = 0; /* reset envelope */
518627      }
519628      break;
520629
521630   /* DMC */
522631   case APU_WRE0:
523      info->APU.dpcm.regs[0] = value;
632      m_APU.dpcm.regs[0] = value;
524633      if (0 == (value & 0x80)) {
525         downcast<n2a03_device &>(info->APU.dpcm.memory->device()).set_input_line(N2A03_APU_IRQ_LINE, CLEAR_LINE);
526         info->APU.dpcm.irq_occurred = FALSE;
634         downcast<n2a03_device &>(m_APU.dpcm.memory->device()).set_input_line(N2A03_APU_IRQ_LINE, CLEAR_LINE);
635         m_APU.dpcm.irq_occurred = FALSE;
527636      }
528637      break;
529638
530639   case APU_WRE1: /* 7-bit DAC */
531      //info->APU.dpcm.regs[1] = value - 0x40;
532      info->APU.dpcm.regs[1] = value & 0x7F;
533      info->APU.dpcm.vol = (info->APU.dpcm.regs[1]-64);
640      //m_APU.dpcm.regs[1] = value - 0x40;
641      m_APU.dpcm.regs[1] = value & 0x7F;
642      m_APU.dpcm.vol = (m_APU.dpcm.regs[1]-64);
534643      break;
535644
536645   case APU_WRE2:
537      info->APU.dpcm.regs[2] = value;
538      //apu_dpcmreset(info->APU.dpcm);
646      m_APU.dpcm.regs[2] = value;
647      //apu_dpcmreset(m_APU.dpcm);
539648      break;
540649
541650   case APU_WRE3:
542      info->APU.dpcm.regs[3] = value;
651      m_APU.dpcm.regs[3] = value;
543652      break;
544653
545654   case APU_IRQCTRL:
546655      if(value & 0x80)
547         info->APU.step_mode = 5;
656         m_APU.step_mode = 5;
548657      else
549         info->APU.step_mode = 4;
658         m_APU.step_mode = 4;
550659      break;
551660
552661   case APU_SMASK:
553662      if (value & 0x01)
554         info->APU.squ[0].enabled = TRUE;
663         m_APU.squ[0].enabled = TRUE;
555664      else
556665      {
557         info->APU.squ[0].enabled = FALSE;
558         info->APU.squ[0].vbl_length = 0;
666         m_APU.squ[0].enabled = FALSE;
667         m_APU.squ[0].vbl_length = 0;
559668      }
560669
561670      if (value & 0x02)
562         info->APU.squ[1].enabled = TRUE;
671         m_APU.squ[1].enabled = TRUE;
563672      else
564673      {
565         info->APU.squ[1].enabled = FALSE;
566         info->APU.squ[1].vbl_length = 0;
674         m_APU.squ[1].enabled = FALSE;
675         m_APU.squ[1].vbl_length = 0;
567676      }
568677
569678      if (value & 0x04)
570         info->APU.tri.enabled = TRUE;
679         m_APU.tri.enabled = TRUE;
571680      else
572681      {
573         info->APU.tri.enabled = FALSE;
574         info->APU.tri.vbl_length = 0;
575         info->APU.tri.linear_length = 0;
576         info->APU.tri.counter_started = FALSE;
577         info->APU.tri.write_latency = 0;
682         m_APU.tri.enabled = FALSE;
683         m_APU.tri.vbl_length = 0;
684         m_APU.tri.linear_length = 0;
685         m_APU.tri.counter_started = FALSE;
686         m_APU.tri.write_latency = 0;
578687      }
579688
580689      if (value & 0x08)
581         info->APU.noi.enabled = TRUE;
690         m_APU.noi.enabled = TRUE;
582691      else
583692      {
584         info->APU.noi.enabled = FALSE;
585         info->APU.noi.vbl_length = 0;
693         m_APU.noi.enabled = FALSE;
694         m_APU.noi.vbl_length = 0;
586695      }
587696
588697      if (value & 0x10)
589698      {
590699         /* only reset dpcm values if DMA is finished */
591         if (FALSE == info->APU.dpcm.enabled)
700         if (FALSE == m_APU.dpcm.enabled)
592701         {
593            info->APU.dpcm.enabled = TRUE;
594            apu_dpcmreset(&info->APU.dpcm);
702            m_APU.dpcm.enabled = TRUE;
703            apu_dpcmreset(&m_APU.dpcm);
595704         }
596705      }
597706      else
598         info->APU.dpcm.enabled = FALSE;
707         m_APU.dpcm.enabled = FALSE;
599708
600      info->APU.dpcm.irq_occurred = FALSE;
709      m_APU.dpcm.irq_occurred = FALSE;
601710
602711      break;
603712   default:
r26012r26013
608717   }
609718}
610719
611/* UPDATE SOUND BUFFER USING CURRENT DATA */
612INLINE void apu_update(nesapu_state *info, stream_sample_t *buffer16, int samples)
613{
614   int accum;
615720
616   while (samples--)
617   {
618      accum = apu_square(info, &info->APU.squ[0]);
619      accum += apu_square(info, &info->APU.squ[1]);
620      accum += apu_triangle(info, &info->APU.tri);
621      accum += apu_noise(info, &info->APU.noi);
622      accum += apu_dpcm(info, &info->APU.dpcm);
623721
624      /* 8-bit clamps */
625      if (accum > 127)
626         accum = 127;
627      else if (accum < -128)
628         accum = -128;
629
630      *(buffer16++)=accum<<8;
631   }
632}
633
634722/* READ VALUES FROM REGISTERS */
635INLINE uint8 apu_read(nesapu_state *info,int address)
723inline uint8 nesapu_device::apu_read(int address)
636724{
637725   if (address == 0x15) /*FIXED* Address $4015 has different behaviour*/
638726   {
639727      int readval = 0;
640      if (info->APU.squ[0].vbl_length > 0)
728      if (m_APU.squ[0].vbl_length > 0)
641729         readval |= 0x01;
642730
643      if (info->APU.squ[1].vbl_length > 0)
731      if (m_APU.squ[1].vbl_length > 0)
644732         readval |= 0x02;
645733
646      if (info->APU.tri.vbl_length > 0)
734      if (m_APU.tri.vbl_length > 0)
647735         readval |= 0x04;
648736
649      if (info->APU.noi.vbl_length > 0)
737      if (m_APU.noi.vbl_length > 0)
650738         readval |= 0x08;
651739
652      if (info->APU.dpcm.enabled == TRUE)
740      if (m_APU.dpcm.enabled == TRUE)
653741         readval |= 0x10;
654742
655      if (info->APU.dpcm.irq_occurred == TRUE)
743      if (m_APU.dpcm.irq_occurred == TRUE)
656744         readval |= 0x80;
657745
658746      return readval;
659747   }
660748   else
661      return info->APU.regs[address];
749      return m_APU.regs[address];
662750}
663751
664752/* WRITE VALUE TO TEMP REGISTRY AND QUEUE EVENT */
665INLINE void apu_write(nesapu_state *info,int address, uint8 value)
753inline void nesapu_device::apu_write(int address, uint8 value)
666754{
667   info->APU.regs[address]=value;
668   info->stream->update();
669   apu_regwrite(info,address,value);
755   m_APU.regs[address]=value;
756   m_stream->update();
757   apu_regwrite(address,value);
670758}
671759
672760/* EXTERNAL INTERFACE FUNCTIONS */
673761
674762/* REGISTER READ/WRITE FUNCTIONS */
675READ8_DEVICE_HANDLER( nes_psg_r ) {return apu_read(get_safe_token(device),offset);}
676WRITE8_DEVICE_HANDLER( nes_psg_w ) {apu_write(get_safe_token(device),offset,data);}
763READ8_MEMBER( nesapu_device::read ) {return apu_read(offset);}
764WRITE8_MEMBER( nesapu_device::write ) {apu_write(offset,data);}
677765
678/* UPDATE APU SYSTEM */
679static STREAM_UPDATE( nes_psg_update_sound )
680{
681   nesapu_state *info = (nesapu_state *)param;
682   apu_update(info, outputs[0], samples);
683}
684766
685
686/* INITIALIZE APU SYSTEM */
687static DEVICE_START( nesapu )
688{
689   const nes_interface *intf = (const nes_interface *)device->static_config();
690   nesapu_state *info = get_safe_token(device);
691   int rate = device->clock() / 4;
692   int i;
693
694   /* Initialize global variables */
695   info->samps_per_sync = rate / ATTOSECONDS_TO_HZ(device->machine().primary_screen->frame_period().attoseconds);
696   info->buffer_size = info->samps_per_sync;
697   info->real_rate = info->samps_per_sync * ATTOSECONDS_TO_HZ(device->machine().primary_screen->frame_period().attoseconds);
698   info->apu_incsize = (float) (device->clock() / (float) info->real_rate);
699
700   /* Use initializer calls */
701   create_noise(info->noise_lut, 13, NOISE_LONG);
702   create_vbltimes(info->vbl_times,vbl_length,info->samps_per_sync);
703   create_syncs(info, info->samps_per_sync);
704
705   /* Adjust buffer size if 16 bits */
706   info->buffer_size+=info->samps_per_sync;
707
708   /* Initialize individual chips */
709   (info->APU.dpcm).memory = &device->machine().device(intf->cpu_tag)->memory().space(AS_PROGRAM);
710
711   info->stream = device->machine().sound().stream_alloc(*device, 0, 1, rate, info, nes_psg_update_sound);
712
713   /* register for save */
714   for (i = 0; i < 2; i++)
715   {
716      device->save_item(NAME(info->APU.squ[i].regs), i);
717      device->save_item(NAME(info->APU.squ[i].vbl_length), i);
718      device->save_item(NAME(info->APU.squ[i].freq), i);
719      device->save_item(NAME(info->APU.squ[i].phaseacc), i);
720      device->save_item(NAME(info->APU.squ[i].output_vol), i);
721      device->save_item(NAME(info->APU.squ[i].env_phase), i);
722      device->save_item(NAME(info->APU.squ[i].sweep_phase), i);
723      device->save_item(NAME(info->APU.squ[i].adder), i);
724      device->save_item(NAME(info->APU.squ[i].env_vol), i);
725      device->save_item(NAME(info->APU.squ[i].enabled), i);
726   }
727
728   device->save_item(NAME(info->APU.tri.regs));
729   device->save_item(NAME(info->APU.tri.linear_length));
730   device->save_item(NAME(info->APU.tri.vbl_length));
731   device->save_item(NAME(info->APU.tri.write_latency));
732   device->save_item(NAME(info->APU.tri.phaseacc));
733   device->save_item(NAME(info->APU.tri.output_vol));
734   device->save_item(NAME(info->APU.tri.adder));
735   device->save_item(NAME(info->APU.tri.counter_started));
736   device->save_item(NAME(info->APU.tri.enabled));
737
738   device->save_item(NAME(info->APU.noi.regs));
739   device->save_item(NAME(info->APU.noi.cur_pos));
740   device->save_item(NAME(info->APU.noi.vbl_length));
741   device->save_item(NAME(info->APU.noi.phaseacc));
742   device->save_item(NAME(info->APU.noi.output_vol));
743   device->save_item(NAME(info->APU.noi.env_phase));
744   device->save_item(NAME(info->APU.noi.env_vol));
745   device->save_item(NAME(info->APU.noi.enabled));
746
747   device->save_item(NAME(info->APU.dpcm.regs));
748   device->save_item(NAME(info->APU.dpcm.address));
749   device->save_item(NAME(info->APU.dpcm.length));
750   device->save_item(NAME(info->APU.dpcm.bits_left));
751   device->save_item(NAME(info->APU.dpcm.phaseacc));
752   device->save_item(NAME(info->APU.dpcm.output_vol));
753   device->save_item(NAME(info->APU.dpcm.cur_byte));
754   device->save_item(NAME(info->APU.dpcm.enabled));
755   device->save_item(NAME(info->APU.dpcm.irq_occurred));
756   device->save_item(NAME(info->APU.dpcm.vol));
757
758   device->save_item(NAME(info->APU.regs));
759
760#ifdef USE_QUEUE
761   device->save_item(NAME(info->APU.queue));
762   device->save_item(NAME(info->APU.head));
763   device->save_item(NAME(info->APU.tail));
764#else
765   device->save_item(NAME(info->APU.buf_pos));
766   device->save_item(NAME(info->APU.step_mode));
767#endif
768}
769
770const device_type NES = &device_creator<nesapu_device>;
771
772nesapu_device::nesapu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
773   : device_t(mconfig, NES, "N2A03 APU", tag, owner, clock, "nesapu", __FILE__),
774      device_sound_interface(mconfig, *this)
775{
776   m_token = global_alloc_clear(nesapu_state);
777}
778
779767//-------------------------------------------------
780//  device_config_complete - perform any
781//  operations now that the configuration is
782//  complete
768//  sound_stream_update - handle a stream update
783769//-------------------------------------------------
784770
785void nesapu_device::device_config_complete()
771void nesapu_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
786772{
787}
773   int accum;
774   memset( outputs[0], 0, samples*sizeof(*outputs[0]) );
788775
789//-------------------------------------------------
790//  device_start - device-specific startup
791//-------------------------------------------------
776   while (samples--)
777   {
778      accum = apu_square(&m_APU.squ[0]);
779      accum += apu_square(&m_APU.squ[1]);
780      accum += apu_triangle(&m_APU.tri);
781      accum += apu_noise(&m_APU.noi);
782      accum += apu_dpcm(&m_APU.dpcm);
792783
793void nesapu_device::device_start()
794{
795   DEVICE_START_NAME( nesapu )(this);
796}
784      /* 8-bit clamps */
785      if (accum > 127)
786         accum = 127;
787      else if (accum < -128)
788         accum = -128;
797789
798//-------------------------------------------------
799//  sound_stream_update - handle a stream update
800//-------------------------------------------------
801
802void nesapu_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
803{
804   // should never get here
805   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
790      *(outputs[0]++)=accum<<8;
791   }
806792}
trunk/src/emu/sound/nes_apu.h
r26012r26013
2727#define __NES_APU_H__
2828
2929
30
3130/* AN EXPLANATION
3231 *
3332 * The NES APU is actually integrated into the Nintendo processor.
r26012r26013
3534 * Also make sure to correspond the memory regions to those used in the
3635 * processor, as each is shared.
3736 */
37 
38#include "nes_defs.h"
39 
40/* GLOBAL CONSTANTS */
41#define  SYNCS_MAX1     0x20
42#define  SYNCS_MAX2     0x80
3843
39struct nes_interface
44struct nesapu_interface
4045{
41   const char *cpu_tag;  /* CPU tag */
46   const char *m_cpu_tag;  /* CPU tag */
4247};
4348
44DECLARE_READ8_DEVICE_HANDLER( nes_psg_r );
45DECLARE_WRITE8_DEVICE_HANDLER( nes_psg_w );
46
4749class nesapu_device : public device_t,
48                           public device_sound_interface
50                           public device_sound_interface,
51                           public nesapu_interface
4952{
5053public:
5154   nesapu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
52   ~nesapu_device() { global_free(m_token); }
55   ~nesapu_device() {}
5356
54   // access to legacy token
55   void *token() const { assert(m_token != NULL); return m_token; }
57   DECLARE_READ8_MEMBER( read );
58   DECLARE_WRITE8_MEMBER( write );
59   
5660protected:
5761   // device-level overrides
5862   virtual void device_config_complete();
r26012r26013
6064
6165   // sound stream update overrides
6266   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
67
6368private:
6469   // internal state
65   void *m_token;
70   apu_t   m_APU;                   /* Actual APUs */
71   float   m_apu_incsize;           /* Adjustment increment */
72   uint32  m_samps_per_sync;        /* Number of samples per vsync */
73   uint32  m_buffer_size;           /* Actual buffer size in bytes */
74   uint32  m_real_rate;             /* Actual playback rate */
75   uint8   m_noise_lut[NOISE_LONG]; /* Noise sample lookup table */
76   uint32  m_vbl_times[0x20];       /* VBL durations in samples */
77   uint32  m_sync_times1[SYNCS_MAX1]; /* Samples per sync table */
78   uint32  m_sync_times2[SYNCS_MAX2]; /* Samples per sync table */
79   sound_stream *m_stream;
80   
81   void create_syncs(unsigned long sps);
82   int8 apu_square(square_t *chan);
83   int8 apu_triangle(triangle_t *chan);
84   int8 apu_noise(noise_t *chan);
85   int8 apu_dpcm(dpcm_t *chan);
86   inline void apu_regwrite(int address, uint8 value);
87   inline uint8 apu_read(int address);
88   inline void apu_write(int address, uint8 value);
6689};
6790
68extern const device_type NES;
91extern const device_type NES_APU;
6992
7093
7194#endif /* __NES_APU_H__ */
trunk/src/emu/sound/nes_defs.h
r26012r26013
2626#ifndef __NES_DEFS_H__
2727#define __NES_DEFS_H__
2828
29#include "nes_defs.h"
30
2931/* BOOLEAN CONSTANTS */
3032#ifndef TRUE
3133#define TRUE   1
r26012r26013
5052
5153struct queue_t
5254{
55      queue_t():
56      pos(0),
57      reg(""),val("") {}
58   
5359   int pos;
54   unsigned char reg,val;
60   unsigned char reg, val;
5561};
5662
5763#endif
r26012r26013
8692/* Square Wave */
8793struct square_t
8894{
95      square_t()
96      {
97         for (int i = 0; i < 4; i++)
98         {
99            regs[i] = 0;
100         }
101         vbl_length =0;
102         freq = 0;
103         phaseacc = 0.0d;
104         output_vol = 0.0d;
105         env_phase = 0.0d;
106         sweep_phase = 0.0d;
107         adder = 0;
108         env_vol = 0;
109         enabled = false;
110      }
111         
89112   uint8 regs[4];
90113   int vbl_length;
91114   int freq;
r26012r26013
101124/* Triangle Wave */
102125struct triangle_t
103126{
127      triangle_t()
128      {
129         for (int i = 0; i < 4; i++)
130         {
131            regs[i] = 0;
132         }
133         linear_length =0;
134         vbl_length =0;
135         write_latency = 0;
136         phaseacc = 0.0d;
137         output_vol = 0.0d;
138         adder = 0;
139         counter_started = false;
140         enabled = false;
141      }
142   
104143   uint8 regs[4]; /* regs[1] unused */
105144   int linear_length;
106145   int vbl_length;
r26012r26013
115154/* Noise Wave */
116155struct noise_t
117156{
157      noise_t()
158      {
159         for (int i = 0; i < 4; i++)
160         {
161            regs[i] = 0;
162         }
163         cur_pos =0;
164         vbl_length =0;
165         phaseacc = 0.0d;
166         output_vol = 0.0d;
167         env_phase = 0.0d;
168         env_vol = 0;
169         enabled = false;
170      }
171
118172   uint8 regs[4]; /* regs[1] unused */
119173   int cur_pos;
120174   int vbl_length;
r26012r26013
128182/* DPCM Wave */
129183struct dpcm_t
130184{
185      dpcm_t()
186      {
187      for (int i = 0; i < 4; i++)
188      {
189         regs[i] = 0;
190      }
191      address = 0;
192      length = 0;
193      bits_left = 0;
194      phaseacc = 0.0d;
195      output_vol = 0.0d;
196      cur_byte = 0;
197      enabled = false;
198      irq_occurred = false;
199      memory = NULL;
200      vol = '\u0000';
201      }
202     
131203   uint8 regs[4];
132204   uint32 address;
133205   uint32 length;
r26012r26013
144216/* APU type */
145217struct apu_t
146218{
219      apu_t()
220      {
221      memset(regs, 0, sizeof(regs));
222      buffer = NULL;
223      buf_pos = 0;
224      step_mode = 0;
225      }
226     
147227   /* Sound channels */
148228   square_t   squ[2];
149229   triangle_t tri;
trunk/src/mess/drivers/nes.c
r26012r26013
1313#include "emu.h"
1414#include "includes/nes.h"
1515#include "cpu/m6502/n2a03.h"
16#include "sound/nes_apu.h"
1716#include "imagedev/flopdrv.h"
1817#include "formats/nes_dsk.h"
1918
r26012r26013
2221
2322READ8_MEMBER(nes_state::psg_4015_r)
2423{
25   device_t *device = machine().device("nessound");
26   return nes_psg_r(device, space, 0x15);
24   return m_sound->read(space, 0x15);
2725}
2826
2927WRITE8_MEMBER(nes_state::psg_4015_w)
3028{
31   device_t *device = machine().device("nessound");
32   nes_psg_w(device, space, 0x15, data);
29   m_sound->write(space, 0x15, data);
3330}
3431
3532WRITE8_MEMBER(nes_state::psg_4017_w)
3633{
37   device_t *device = machine().device("nessound");
38   nes_psg_w(device, space, 0x17, data);
34   m_sound->write(space, 0x17, data);
3935}
4036
4137WRITE8_MEMBER(nes_state::nes_vh_sprite_dma_w)
r26012r26013
4642static ADDRESS_MAP_START( nes_map, AS_PROGRAM, 8, nes_state )
4743   AM_RANGE(0x0000, 0x07ff) AM_RAM AM_MIRROR(0x1800)                   /* RAM */
4844   AM_RANGE(0x2000, 0x3fff) AM_DEVREADWRITE("ppu", ppu2c0x_device, read, write)        /* PPU registers */
49   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE_LEGACY("nessound", nes_psg_r, nes_psg_w)       /* PSG primary registers */
45   AM_RANGE(0x4000, 0x4013) AM_DEVREADWRITE("nessound", nesapu_device, read, write)       /* PSG primary registers */
5046   AM_RANGE(0x4014, 0x4014) AM_WRITE(nes_vh_sprite_dma_w)              /* stupid address space hole */
5147   AM_RANGE(0x4015, 0x4015) AM_READWRITE(psg_4015_r, psg_4015_w)       /* PSG status / first control register */
5248   AM_RANGE(0x4016, 0x4016) AM_READWRITE(nes_in0_r, nes_in0_w)         /* IN0 - input port 1 */
r26012r26013
647643INPUT_PORTS_END
648644
649645
650static const nes_interface nes_apu_interface =
646static const nesapu_interface nes_apu_interface =
651647{
652648   "maincpu"
653649};
r26012r26013
721717
722718   /* sound hardware */
723719   MCFG_SPEAKER_STANDARD_MONO("mono")
724   MCFG_SOUND_ADD("nessound", NES, NTSC_CLOCK)
720   MCFG_SOUND_ADD("nessound", NES_APU, NTSC_CLOCK)
725721   MCFG_SOUND_CONFIG(nes_apu_interface)
726722   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.90)
727723
r26012r26013
748744   MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 30*8-1)
749745
750746   /* sound hardware */
751   MCFG_SOUND_REPLACE("nessound", NES, PAL_CLOCK)
747   MCFG_SOUND_REPLACE("nessound", NES_APU, PAL_CLOCK)
752748   MCFG_SOUND_CONFIG(nes_apu_interface)
753749   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.90)
754750MACHINE_CONFIG_END
r26012r26013
769765   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC((106.53/(PAL_CLOCK/1000000)) * (PPU_VBLANK_LAST_SCANLINE_PAL-PPU_VBLANK_FIRST_SCANLINE+1+2)))
770766
771767   /* sound hardware */
772   MCFG_SOUND_REPLACE("nessound", NES, 26601712/15) /* 26.601712MHz / 15 == 1.77344746666... MHz */
768   MCFG_SOUND_REPLACE("nessound", NES_APU, 26601712/15) /* 26.601712MHz / 15 == 1.77344746666... MHz */
773769   MCFG_SOUND_CONFIG(nes_apu_interface)
774770   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.90)
775771MACHINE_CONFIG_END
trunk/src/mess/mess.mak
r26012r26013
161161SOUNDS += SN76496
162162SOUNDS += POKEY
163163SOUNDS += TIA
164SOUNDS += NES
164SOUNDS += NES_APU
165165SOUNDS += ASTROCADE
166166#SOUNDS += NAMCO
167167#SOUNDS += NAMCO_15XX
trunk/src/mess/machine/nes_mmc5.c
r26012r26013
4141
4242
4343nes_exrom_device::nes_exrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
44               : nes_nrom_device(mconfig, NES_EXROM, "NES Cart ExROM (MMC-5) PCB", tag, owner, clock, "nes_exrom", __FILE__)
44               : nes_nrom_device(mconfig, NES_EXROM, "NES Cart ExROM (MMC-5) PCB", tag, owner, clock, "nes_exrom", __FILE__)               
4545{
4646}
4747
4848
49
50
5149void nes_exrom_device::device_start()
5250{
5351   common_start();
r26012r26013
333331   /* Send $5000-$5015 to the sound chip */
334332   if ((offset >= 0xf00) && (offset <= 0xf15))
335333   {
336      device_t *m_sound = machine().device("nessound");
337      nes_psg_w(m_sound, space, offset & 0x1f, data);
334      nesapu_device *m_sound = machine().device<nesapu_device>("nessound");
335      m_sound->write(space, offset & 0x1f, data);
338336      return;
339337   }
340338
trunk/src/mess/machine/nes_mmc5.h
r26012r26013
6363   // MMC-5 contains 1K of internal ram
6464   UINT8 *m_exram;
6565
66//  int m_nes_vram_sprite[8];
66   //  int m_nes_vram_sprite[8];
6767};
6868
6969
trunk/src/mess/includes/nes.h
r26012r26013
1212
1313#include "video/ppu2c0x.h"
1414#include "machine/nes_slot.h"
15#include "sound/nes_apu.h"
1516#include "imagedev/cassette.h"
1617
1718// official PCBs
r26012r26013
490491
491492   required_device<cpu_device> m_maincpu;
492493   required_device<ppu2c0x_device> m_ppu;
493   required_device<device_t> m_sound;
494   required_device<nesapu_device> m_sound;
494495   optional_device<nes_cart_slot_device> m_cartslot;
495496   optional_device<cassette_image_device> m_cassette;
496497

Previous 199869 Revisions Next


© 1997-2024 The MAME Team