cog/Frameworks/GME/gme/Kss_Core.h

101 lines
2.1 KiB
C++

// MSX computer KSS music file emulator
// Game_Music_Emu $vers
#ifndef KSS_CORE_H
#define KSS_CORE_H
#include "Gme_Loader.h"
#include "Rom_Data.h"
#include "Z80_Cpu.h"
class Kss_Core : public Gme_Loader {
public:
// KSS file header
struct header_t
{
enum { size = 0x20 };
enum { base_size = 0x10 };
enum { ext_size = size - base_size };
byte tag [4];
byte load_addr [2];
byte load_size [2];
byte init_addr [2];
byte play_addr [2];
byte first_bank;
byte bank_mode;
byte extra_header;
byte device_flags;
// KSSX extended data, if extra_header==0x10
byte data_size [4];
byte unused [4];
byte first_track [2];
byte last_track [2]; // if no extended data, we set this to 0xFF
byte psg_vol;
byte scc_vol;
byte msx_music_vol;
byte msx_audio_vol;
};
// Header for currently loaded file
header_t const& header() const { return header_; }
// ROM data
Rom_Data const& rom_() const { return rom; }
typedef int time_t;
void set_play_period( time_t p ) { play_period = p; }
blargg_err_t start_track( int );
blargg_err_t end_frame( time_t );
protected:
typedef Z80_Cpu Kss_Cpu;
Kss_Cpu cpu;
void set_bank( int logical, int physical );
typedef int addr_t;
virtual void cpu_write( addr_t, int ) = 0;
virtual int cpu_in( time_t, addr_t );
virtual void cpu_out( time_t, addr_t, int );
// Called after one frame of emulation
virtual void update_gain() = 0;
// Implementation
public:
Kss_Core();
virtual ~Kss_Core();
protected:
virtual blargg_err_t load_( Data_Reader& );
virtual void unload();
private:
enum { idle_addr = 0xFFFF };
Rom_Data rom;
header_t header_;
bool gain_updated;
int bank_count;
time_t play_period;
time_t next_play;
// large items
enum { mem_size = 0x10000 };
byte ram [mem_size + Kss_Cpu::cpu_padding];
byte unmapped_read [0x100]; // TODO: why isn't this page_size?
// because CPU can't read beyond this in last page? or because it will spill into unmapped_write?
byte unmapped_write [Kss_Cpu::page_size];
int bank_size() const { return (16 * 1024) >> (header_.bank_mode >> 7 & 1); }
bool run_cpu( time_t end );
void jsr( byte const (&addr) [2] );
};
#endif