1 // TurboGrafx-16/PC Engine HES music file emulator core
2 
3 // Game_Music_Emu $vers
4 #ifndef HES_CORE_H
5 #define HES_CORE_H
6 
7 #include "Gme_Loader.h"
8 #include "Rom_Data.h"
9 #include "Hes_Apu.h"
10 #include "Hes_Apu_Adpcm.h"
11 #include "Hes_Cpu.h"
12 
13 class Hes_Core : public Gme_Loader {
14 public:
15 
16 	// HES file header
17 	enum { info_offset = 0x20 };
18 	struct header_t
19 	{
20 		enum { size = 0x20 };
21 
22 		byte tag       [4];
23 		byte vers;
24 		byte first_track;
25 		byte init_addr [2];
26 		byte banks     [8];
27 		byte data_tag  [4];
28 		byte data_size [4];
29 		byte addr      [4];
30 		byte unused    [4];
31 
32 		// True if header has valid file signature
33 		bool valid_tag() const;
34 	};
35 
36 	// Header for currently loaded file
header()37 	header_t const& header() const      { return header_; }
38 
39 	// Pointer to ROM data, for getting track information from
data()40 	byte const* data() const            { return rom.begin(); }
data_size()41 	int data_size() const               { return rom.file_size(); }
42 
43 	// Adjusts rate play routine is called at, where 1.0 is normal.
44 	// Can be changed while track is playing.
45 	void set_tempo( double );
46 
47 	// Sound chip
apu()48 	Hes_Apu& apu()                      { return apu_; }
49 
adpcm()50 	Hes_Apu_Adpcm& adpcm()              { return adpcm_; }
51 
52 	// Starts track
53 	blargg_err_t start_track( int );
54 
55 	// Ends time frame at time t
56 	typedef int time_t;
57 	blargg_err_t end_frame( time_t );
58 
59 // Implementation
60 public:
61 	Hes_Core();
62 	~Hes_Core();
63 	virtual void unload();
64 
65 protected:
66 	virtual blargg_err_t load_( Data_Reader& );
67 
68 private:
69 	enum { idle_addr = 0x1FFF };
70 
71 	typedef int addr_t;
72 	Hes_Cpu  cpu;
73 	Rom_Data rom;
74 	header_t header_;
75 	time_t   play_period;
76 	int      timer_base;
77 
78 	struct {
79 		time_t last_time;
80 		int    count;
81 		int    load;
82 		int    raw_load;
83 		byte   enabled;
84 		byte   fired;
85 	} timer;
86 
87 	struct {
88 		time_t next_vbl;
89 		byte   latch;
90 		byte   control;
91 	} vdp;
92 
93 	struct {
94 		time_t timer;
95 		time_t vdp;
96 		byte   disables;
97 	} irq;
98 
99 	void recalc_timer_load();
100 
101 	// large items
102 	byte*   write_pages [Hes_Cpu::page_count + 1]; // 0 if unmapped or I/O space
103 	Hes_Apu apu_;
104 	Hes_Apu_Adpcm adpcm_;
105 	byte    ram [Hes_Cpu::page_size];
106 	byte    sgx [3 * Hes_Cpu::page_size + Hes_Cpu::cpu_padding];
107 
108 	void irq_changed();
109 	void run_until( time_t );
110 	bool run_cpu( time_t end );
111 	int  read_mem_( addr_t );
112 	int  read_mem( addr_t );
113 	void write_mem_( addr_t, int data );
114 	void write_mem( addr_t, int );
115 	void write_vdp( int addr, int data );
116 	void set_mmr( int reg, int bank );
117 	int  cpu_done();
118 };
119 
120 #endif
121