#define MAX_LINES 1024
#define MAX_EVENT 64
#define NO_EVENT -1
+#if !defined(MAX_SOUND_IN_BUFFERS)
+ #define MAX_SOUND_IN_BUFFERS 8
+#else
+ #if (MAX_SOUND_IN_BUFFERS <= 0)
+ #define MAX_SOUND_IN_BUFFERS 8
+ #endif
+#endif
enum {
EVENT_CPUTYPE_GENERIC = 0,
EVENT_CPUTYPE_MCS48,
EVENT_CPUTYPE_TMS9995,
EVENT_CPUTYPE_UPD7801,
- EVENT_CPUTYPE_Z80
+ EVENT_CPUTYPE_Z80,
+ EVENT_CPUTYPE_I86,
+ EVENT_CPUTYPE_V30,
+ EVENT_CPUTYPE_UPD7810,
+ EVENT_CPUTYPE_UPD7907,
};
+
+
class EVENT : public DEVICE
{
private:
cpu_t d_cpu[MAX_CPU];
uint32_t cpu_update_clocks[MAX_CPU][6];
- uint32_t cpu_type[MAX_CPU];
-
int dcount_cpu;
- int vclocks[MAX_LINES];
+ int frame_clocks;
+ int vline_clocks[MAX_LINES];
int power;
- int event_remain;
+ int event_remain, event_extra;
int cpu_remain, cpu_accum, cpu_done;
uint64_t event_clocks;
int buffer_ptr;
int sound_samples;
int sound_tmp_samples;
+
+ int16_t* sound_in_tmp_buffer[MAX_SOUND_IN_BUFFERS]; // This is buffer from recording devices.
+ int sound_in_rate[MAX_SOUND_IN_BUFFERS];
+ int sound_in_samples[MAX_SOUND_IN_BUFFERS];
+ int sound_in_channels[MAX_SOUND_IN_BUFFERS];
+ int sound_in_writeptr[MAX_SOUND_IN_BUFFERS];
+ int sound_in_readptr[MAX_SOUND_IN_BUFFERS];
+ int sound_in_write_size[MAX_SOUND_IN_BUFFERS];
+ int sound_in_read_size[MAX_SOUND_IN_BUFFERS];
+ int sound_in_read_mod[MAX_SOUND_IN_BUFFERS];
int dont_skip_frames;
bool prev_skip, next_skip;
void mix_sound(int samples);
void* get_event(int index);
- int run_cpu(uint32_t num, int cycles);
#ifdef _DEBUG_LOG
bool initialize_done;
#endif
- template <class T>
- void set_cpu_type(T *p, int num)
- {
- if((num < 0) || (num >= MAX_CPU)) return;
-#if defined(USE_CPU_HD6301)
- if(typeid(T) == typeid(HD6301)) {
- cpu_type[num] = EVENT_CPUTYPE_HD6301;
- } else
-#endif
-#if defined(USE_CPU_HUC6280)
- if(typeid(T) == typeid(HUC6280)) {
- cpu_type[num] = EVENT_CPUTYPE_HUC6280;
- } else
-#endif
-#if defined(USE_CPU_I86) || defined(USE_CPU_I286) || defined(USE_CPU_I186) || defined(USE_CPU_V30)
- if(typeid(T) == typeid(I286)) {
- cpu_type[num] = EVENT_CPUTYPE_I286;
- } else
-#endif
-#if defined(USE_CPU_I386) || defined(USE_CPU_I486) || defined(USE_CPU_PENTIUM)
- if(typeid(T) == typeid(I386)) {
- cpu_type[num] = EVENT_CPUTYPE_I386;
- } else
-#endif
-#if defined(USE_CPU_I8080)
- if(typeid(T) == typeid(I8080)) {
- cpu_type[num] = EVENT_CPUTYPE_I8080;
- } else
-#endif
-#if defined(USE_CPU_M6502)
- if(typeid(T) == typeid(M6502)) {
- cpu_type[num] = EVENT_CPUTYPE_M6502;
- } else
-#endif
-#if defined(USE_CPU_N2A03)
- if(typeid(T) == typeid(N2A03)) {
- cpu_type[num] = EVENT_CPUTYPE_N2A03;
- } else
-#endif
-#if defined(USE_CPU_MB8861)
- if(typeid(T) == typeid(MB8861)) {
- cpu_type[num] = EVENT_CPUTYPE_MB8861;
- } else
-#endif
-#if defined(USE_CPU_MC6800)
- if(typeid(T) == typeid(MC6800)) {
- cpu_type[num] = EVENT_CPUTYPE_MC6800;
- } else
-#endif
-#if defined(USE_CPU_MC6801)
- if(typeid(T) == typeid(MC6801)) {
- cpu_type[num] = EVENT_CPUTYPE_MC6801;
- } else
-#endif
-#if defined(USE_CPU_MC6809)
- if(typeid(T) == typeid(MC6809)) {
- cpu_type[num] = EVENT_CPUTYPE_MC6809;
- } else
-#endif
-#if defined(USE_CPU_MCS48)
- if(typeid(T) == typeid(MCS48)) {
- cpu_type[num] = EVENT_CPUTYPE_MCS48;
- } else
-#endif
-#if defined(USE_CPU_TMS9995)
- if(typeid(T) == typeid(TMS9995)) {
- cpu_type[num] = EVENT_CPUTYPE_TMS9995;
- } else
-#endif
-#if defined(USE_CPU_UPD7801)
- if(typeid(T) == typeid(UPD7801)) {
- cpu_type[num] = EVENT_CPUTYPE_UPD7801;
- } else
-#endif
-#if defined(USE_CPU_Z80)
- if(typeid(T) == typeid(Z80)) {
- cpu_type[num] = EVENT_CPUTYPE_Z80;
- } else
-#endif
- {
- cpu_type[num] = EVENT_CPUTYPE_GENERIC;
- }
- }
public:
- EVENT(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
+ EVENT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
{
dcount_cpu = dcount_sound = 0;
frame_event_count = vline_event_count = 0;
memset(dev_need_mix, 0, sizeof(dev_need_mix));
need_mix = 0;
+ for(int i = 0; i < MAX_SOUND_IN_BUFFERS; i++) {
+ sound_in_tmp_buffer[i] = NULL;
+ sound_in_rate[i] = 0;
+ sound_in_samples[i] = 0;
+ sound_in_channels[i] = 0;
+ sound_in_readptr[i] = 0;
+ sound_in_writeptr[i] = 0;
+ sound_in_read_size[i] = 0;
+ sound_in_write_size[i] = 0;
+ sound_in_read_mod[i] = 0;
+ }
#ifdef _DEBUG_LOG
initialize_done = false;
#endif
- for(int i = 0; i < MAX_CPU; i++) {
- cpu_type[i] = EVENT_CPUTYPE_GENERIC;
- }
set_device_name(_T("Event Manager"));
}
~EVENT() {}
void reset();
void event_callback(int event_id, int err);
void update_config();
- void decl_state();
- void save_state(FILEIO* state_fio);
- bool load_state(FILEIO* state_fio);
+ bool process_state(FILEIO* state_fio, bool loading);
// common event functions
int get_event_manager_id()
{
return next_lines_per_frame;
}
+ bool is_primary_cpu(DEVICE* device)
+ {
+ return (d_cpu[0].device == device);
+ }
+ void update_extra_event(int clock);
void register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id);
void register_event_by_clock(DEVICE* device, int event_id, uint64_t clock, bool loop, int* register_id);
void cancel_event(DEVICE* device, int register_id);
}
int get_cur_vline_clocks()
{
- return vclocks[cur_vline];
+ return vline_clocks[cur_vline];
}
uint32_t get_cpu_pc(int index);
void request_skip_frames();
void touch_sound();
void set_realtime_render(DEVICE* device, bool flag);
-
+ uint64_t get_current_clock_uint64();
+ uint32_t get_cpu_clock(int index);
// unique functions
double get_frame_rate()
{
void initialize_sound(int rate, int samples);
uint16_t* create_sound(int* extra_frames);
int get_sound_buffer_ptr();
- template <class T>
- void set_context_cpu(T* device, uint32_t clocks = CPU_CLOCKS)
+ // Sound input functions
+ void clear_sound_in_source(int bank);
+ int add_sound_in_source(int rate, int samples, int channels);
+ int release_sound_in_source(int bank);
+
+ bool is_sound_in_source_exists(int bank);
+ int increment_sound_in_passed_data(int bank, double passed_usec);
+ int get_sound_in_buffers_count();
+ int get_sound_in_samples(int bank);
+ int get_sound_in_rate(int bank);
+ int get_sound_in_channels(int bank);
+ int16_t* get_sound_in_buf_ptr(int bank);
+ int write_sound_in_buffer(int bank, int32_t* src, int samples);
+ // Add sampled values to sample buffer;value may be -32768 to +32767.
+ int get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels);
+ int get_sound_in_data(int bank, int32_t* dst, int expect_samples, int expect_rate, int expect_channels);
+ int rechannel_sound_in_data(int32_t*dst, int16_t* src, int dst_channels, int src_channels, int samples);
+
+ int set_context_cpu(DEVICE* device, uint32_t clocks = CPU_CLOCKS)
{
assert(dcount_cpu < MAX_CPU);
int index = dcount_cpu++;
d_cpu[index].device = (DEVICE *)device;
d_cpu[index].cpu_clocks = clocks;
d_cpu[index].accum_clocks = 0;
- set_cpu_type(device, index);
for(int k = 0; k < 6; k++) cpu_update_clocks[index][k] = d_cpu[index].update_clocks * k;
+ return index;
+ }
+ bool remove_context_cpu(DEVICE* device, int num)
+ {
+ if(num <= 0) return false; // Number one must not be removed.
+ if(num >= MAX_CPU) return false;
+ if(num >= dcount_cpu) return false;
+ if(dcount_cpu <= 1) return false;
+ // Note: This function is dangerous.
+ if(d_cpu[num].device != device) return false;
+ if(d_cpu[num].device == NULL) return false;
+ if(dcount_cpu == 2) {
+ d_cpu[1].device = (DEVICE *)NULL;
+ d_cpu[1].cpu_clocks = 0;
+ d_cpu[1].accum_clocks = 0;
+ dcount_cpu = 1;
+ for(int k = 0; k < 6; k++) cpu_update_clocks[1][k] = d_cpu[1].update_clocks * k;
+ } else {
+ for(int i = num; i < (dcount_cpu - 1); i++) {
+ d_cpu[i].device = d_cpu[i + 1].device;
+ d_cpu[i].cpu_clocks = d_cpu[i + 1].cpu_clocks;
+ d_cpu[i].accum_clocks = d_cpu[i + 1].accum_clocks;
+ }
+ int n = dcount_cpu - 1;
+ d_cpu[n].device = (DEVICE *)NULL;
+ d_cpu[n].cpu_clocks = 0;
+ d_cpu[n].accum_clocks = 0;
+ for(int i = 1; i < dcount_cpu; i++) {
+ for(int k = 0; k < 6; k++) cpu_update_clocks[i][k] = d_cpu[i].update_clocks * k;
+ }
+ dcount_cpu = dcount_cpu - 1;
+ }
+ return true;
}
void set_secondary_cpu_clock(DEVICE* device, uint32_t clocks)
{