1 // MSX computer KSS music file emulator
2 
3 // Game_Music_Emu 0.5.5
4 #ifndef KSS_EMU_H
5 #define KSS_EMU_H
6 
7 #include "Classic_Emu.h"
8 #include "Kss_Scc_Apu.h"
9 #include "Kss_Cpu.h"
10 #include "Sms_Apu.h"
11 #include "Ay_Apu.h"
12 
13 class Kss_Emu : private Kss_Cpu, public Classic_Emu {
14 	typedef Kss_Cpu cpu;
15 public:
16 	// KSS file header
17 	enum { header_size = 0x10 };
18 	struct header_t
19 	{
20 		byte tag [4];
21 		byte load_addr [2];
22 		byte load_size [2];
23 		byte init_addr [2];
24 		byte play_addr [2];
25 		byte first_bank;
26 		byte bank_mode;
27 		byte extra_header;
28 		byte device_flags;
29 	};
30 
31 	enum { ext_header_size = 0x10 };
32 	struct ext_header_t
33 	{
34 		byte data_size [4];
35 		byte unused [4];
36 		byte first_track [2];
37 		byte last_tack [2];
38 		byte psg_vol;
39 		byte scc_vol;
40 		byte msx_music_vol;
41 		byte msx_audio_vol;
42 	};
43 
44 	struct composite_header_t : header_t, ext_header_t { };
45 
46 	// Header for currently loaded file
header()47 	composite_header_t const& header() const { return header_; }
48 
static_type()49 	static gme_type_t static_type() { return gme_kss_type; }
50 public:
51 	Kss_Emu();
52 	~Kss_Emu();
53 protected:
54 	blargg_err_t track_info_( track_info_t*, int track ) const;
55 	blargg_err_t load_( Data_Reader& );
56 	blargg_err_t start_track_( int );
57 	blargg_err_t run_clocks( blip_time_t&, int );
58 	void set_tempo_( double );
59 	void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
60 	void update_eq( blip_eq_t const& );
61 	void unload();
62 private:
63 	Rom_Data<page_size> rom;
64 	composite_header_t header_;
65 
66 	bool scc_accessed;
67 	bool gain_updated;
68 	void update_gain();
69 
70 	unsigned scc_enabled; // 0 or 0xC000
71 	int bank_count;
72 	void set_bank( int logical, int physical );
bank_size()73 	blargg_long bank_size() const { return (16 * 1024L) >> (header_.bank_mode >> 7 & 1); }
74 
75 	blip_time_t play_period;
76 	blip_time_t next_play;
77 	int ay_latch;
78 
79 	friend void kss_cpu_out( class Kss_Cpu*, cpu_time_t, unsigned addr, int data );
80 	friend int  kss_cpu_in( class Kss_Cpu*, cpu_time_t, unsigned addr );
81 	void cpu_write( unsigned addr, int data );
82 	friend void kss_cpu_write( class Kss_Cpu*, unsigned addr, int data );
83 
84 	// large items
85 	enum { mem_size = 0x10000 };
86 	byte ram [mem_size + cpu_padding];
87 
88 	Ay_Apu ay;
89 	Scc_Apu scc;
90 	Sms_Apu* sn;
91 	byte unmapped_read  [0x100];
92 	byte unmapped_write [page_size];
93 };
94 
95 #endif
96