//////////////////////////////////////////////////////////////////////////////////////// // // Nestopia - NES/Famicom emulator written in C++ // // Copyright (C) 2003-2008 Martin Freij // // This file is part of Nestopia. // // Nestopia is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // Nestopia is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Nestopia; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //////////////////////////////////////////////////////////////////////////////////////// #ifndef NST_NSF_H #define NST_NSF_H #include "NstImage.hpp" #ifdef NST_PRAGMA_ONCE #pragma once #endif namespace Nes { namespace Core { class Nsf : public Image { public: explicit Nsf(Context&); void BeginFrame(); uint GetChips() const; Result SelectSong(uint); Result PlaySong(); Result StopSong(); private: ~Nsf(); void Reset(bool); bool PowerOff(); void InitSong(); Region GetDesiredRegion() const; System GetDesiredSystem(Region,CpuModel*,PpuModel*) const; inline uint FetchLast(uint) const; typedef Memory Prg; enum { JAM = 0x02, JMP = 0x4C, JSR = 0x20, SEI = 0x78, LDA = 0xA9, LDX = 0xA2, TXS = 0x9A }; NES_DECL_PEEK( 38EC ); NES_DECL_PEEK( 38ED ); NES_DECL_PEEK( 38EE ); NES_DECL_PEEK( 38EF ); NES_DECL_PEEK( 38F0 ); NES_DECL_PEEK( 38F1 ); NES_DECL_PEEK( 38F2 ); NES_DECL_PEEK( 38F3 ); NES_DECL_PEEK( 38F4 ); NES_DECL_PEEK( 38F5 ); NES_DECL_PEEK( 38F6 ); NES_DECL_PEEK( 38F7 ); NES_DECL_PEEK( 38F8 ); NES_DECL_PEEK( 38F9 ); NES_DECL_PEEK( 38FA ); NES_DECL_PEEK( 38FB ); NES_DECL_PEEK( 38FC ); NES_DECL_PEEK( 38FD ); NES_DECL_PEEK( 38FE ); NES_DECL_PEEK( 38FF ); NES_DECL_POKE( 4017 ); NES_DECL_POKE( 5FF8 ); NES_DECL_POKE( 5FF9 ); NES_DECL_POKE( 5FFA ); NES_DECL_POKE( 5FFB ); NES_DECL_POKE( 5FFC ); NES_DECL_POKE( 5FFD ); NES_DECL_POKE( 5FFE ); NES_DECL_POKE( 5FFF ); NES_DECL_PEEK( Prg_8 ); NES_DECL_PEEK( Prg_9 ); NES_DECL_PEEK( Prg_A ); NES_DECL_PEEK( Prg_B ); NES_DECL_PEEK( Prg_C ); NES_DECL_PEEK( Prg_D ); NES_DECL_PEEK( Prg_E ); NES_DECL_PEEK( Prg_F ); NES_DECL_PEEK( Wrk ); NES_DECL_POKE( Wrk ); NES_DECL_PEEK( Fds_4040 ); NES_DECL_POKE( Fds_4040 ); NES_DECL_POKE( Fds_4080 ); NES_DECL_POKE( Fds_4082 ); NES_DECL_POKE( Fds_4083 ); NES_DECL_POKE( Fds_4084 ); NES_DECL_POKE( Fds_4085 ); NES_DECL_POKE( Fds_4086 ); NES_DECL_POKE( Fds_4087 ); NES_DECL_POKE( Fds_4088 ); NES_DECL_POKE( Fds_4089 ); NES_DECL_POKE( Fds_408A ); NES_DECL_PEEK( Fds_4090 ); NES_DECL_PEEK( Fds_4092 ); NES_DECL_POKE( Fds_5FF6 ); NES_DECL_POKE( Fds_5FF7 ); NES_DECL_POKE( Fds_5FF8 ); NES_DECL_POKE( Fds_5FF9 ); NES_DECL_POKE( Fds_5FFA ); NES_DECL_POKE( Fds_5FFB ); NES_DECL_POKE( Fds_5FFC ); NES_DECL_POKE( Fds_5FFD ); NES_DECL_POKE( Fds_5FFE ); NES_DECL_POKE( Fds_5FFF ); NES_DECL_PEEK( Fds_Ram ); NES_DECL_POKE( Fds_Ram ); NES_DECL_POKE( Mmc5_5000 ); NES_DECL_POKE( Mmc5_5002 ); NES_DECL_POKE( Mmc5_5003 ); NES_DECL_POKE( Mmc5_5004 ); NES_DECL_POKE( Mmc5_5006 ); NES_DECL_POKE( Mmc5_5007 ); NES_DECL_POKE( Mmc5_5010 ); NES_DECL_POKE( Mmc5_5011 ); NES_DECL_POKE( Mmc5_5015 ); NES_DECL_PEEK( Mmc5_5015 ); NES_DECL_PEEK( Mmc5_5205 ); NES_DECL_PEEK( Mmc5_5206 ); NES_DECL_POKE( Mmc5_5205 ); NES_DECL_POKE( Mmc5_5206 ); NES_DECL_PEEK( Mmc5_5C00 ); NES_DECL_POKE( Mmc5_5C00 ); NES_DECL_POKE( Vrc6_9000 ); NES_DECL_POKE( Vrc6_9001 ); NES_DECL_POKE( Vrc6_9002 ); NES_DECL_POKE( Vrc6_A000 ); NES_DECL_POKE( Vrc6_A001 ); NES_DECL_POKE( Vrc6_A002 ); NES_DECL_POKE( Vrc6_B000 ); NES_DECL_POKE( Vrc6_B001 ); NES_DECL_POKE( Vrc6_B002 ); NES_DECL_POKE( Vrc7_9010 ); NES_DECL_POKE( Vrc7_9030 ); NES_DECL_PEEK( N163_48 ); NES_DECL_POKE( N163_48 ); NES_DECL_POKE( N163_F8 ); NES_DECL_POKE( S5b_C ); NES_DECL_POKE( S5b_E ); NES_DECL_PEEK( FFFA ); NES_DECL_PEEK( FFFB ); NES_DECL_PEEK( FFFC ); NES_DECL_PEEK( FFFD ); NES_DECL_PEEK( Nop ); NES_DECL_POKE( Nop ); enum Header { HEADER_SIZE = 128, HEADER_RESERVED_LENGTH = 4 }; class Chips; struct Songs { byte start; byte current; byte count; const byte padding; struct { char name[32]; char artist[32]; char copyright[32]; } info; Songs() : start (0), current (0), count (0), padding (0) {} }; struct Speed { word ntsc; word pal; Speed() : ntsc (0), pal (0) {} }; struct Addressing { word play; word init; word load; word bankSwitched; Addressing() : play (0x0000), init (0x0000), load (0x0000), bankSwitched (false) {} }; struct Routine { enum { RESET_A = 0x1, RESET_B = 0x2, RESET = RESET_A|RESET_B, NMI_A = 0x1, NMI_B = 0x2, NMI = NMI_A|NMI_B }; bool playing; byte nmi; byte reset; byte jmp; Routine() : playing (false), nmi (0), reset (0), jmp (0x00) {} }; Prg prg; Routine routine; Cpu& cpu; Apu& apu; Chips* chips; FavoredSystem favoredSystem; Songs songs; Addressing addressing; Speed speed; uint tuneMode; byte banks[8]; byte wrk[SIZE_8K]; public: cstring GetName() const { return songs.info.name; } cstring GetArtist() const { return songs.info.artist; } cstring GetCopyright() const { return songs.info.copyright; } uint GetTuneMode() const { return tuneMode; } uint NumSongs() const { return songs.count; } uint CurrentSong() const { return songs.current; } uint StartingSong() const { return songs.start; } bool UsesBankSwitching() const { return addressing.bankSwitched; } bool IsPlaying() const { return routine.playing; } uint GetInitAddress() const { return addressing.init; } uint GetLoadAddress() const { return addressing.load; } uint GetPlayAddress() const { return addressing.play; } }; } } #endif