1 // MSX computer KSS music file emulator
2 
3 // Game_Music_Emu $vers
4 #ifndef KSS_CORE_H
5 #define KSS_CORE_H
6 
7 #include "Gme_Loader.h"
8 #include "Rom_Data.h"
9 #include "Z80_Cpu.h"
10 
11 class Kss_Core : public Gme_Loader {
12 public:
13 	// KSS file header
14 	struct header_t
15 	{
16 		enum { size = 0x20 };
17 		enum { base_size = 0x10 };
18 		enum { ext_size = size - base_size };
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 		// KSSX extended data, if extra_header==0x10
31 		byte data_size [4];
32 		byte unused [4];
33 		byte first_track [2];
34 		byte last_track [2]; // if no extended data, we set this to 0xFF
35 		byte psg_vol;
36 		byte scc_vol;
37 		byte msx_music_vol;
38 		byte msx_audio_vol;
39 	};
40 
41 	// Header for currently loaded file
header()42 	header_t const& header() const { return header_; }
43 
44 	// ROM data
rom_()45 	Rom_Data const& rom_() const { return rom; }
46 
47 	typedef int time_t;
set_play_period(time_t p)48 	void set_play_period( time_t p )        { play_period = p; }
49 
50 	blargg_err_t start_track( int );
51 
52 	blargg_err_t end_frame( time_t );
53 
54 protected:
55 	typedef Z80_Cpu Kss_Cpu;
56 	Kss_Cpu cpu;
57 
58 	void set_bank( int logical, int physical );
59 
60 	typedef int addr_t;
61 	virtual void cpu_write( addr_t, int ) = 0;
62 	virtual int  cpu_in(  time_t, addr_t );
63 	virtual void cpu_out( time_t, addr_t, int );
64 
65 	// Called after one frame of emulation
66 	virtual void update_gain() = 0;
67 
68 // Implementation
69 public:
70 	Kss_Core();
71 	virtual ~Kss_Core();
72 
73 protected:
74 	virtual blargg_err_t load_( Data_Reader& );
75 	virtual void unload();
76 
77 private:
78 	enum { idle_addr = 0xFFFF };
79 
80 	Rom_Data rom;
81 	header_t header_;
82 	bool gain_updated;
83 	int bank_count;
84 	time_t play_period;
85 	time_t next_play;
86 
87 	// large items
88 	enum { mem_size = 0x10000 };
89 	byte ram [mem_size + Kss_Cpu::cpu_padding];
90 	byte unmapped_read  [0x100]; // TODO: why isn't this page_size?
91 	// because CPU can't read beyond this in last page? or because it will spill into unmapped_write?
92 
93 	byte unmapped_write [Kss_Cpu::page_size];
94 
bank_size()95 	int bank_size() const { return (16 * 1024) >> (header_.bank_mode >> 7 & 1); }
96 	bool run_cpu( time_t end );
97 	void jsr( byte const (&addr) [2] );
98 };
99 
100 #endif
101