activegs-ios/kegs/Src/sim65816.h

392 lines
8.8 KiB
C
Raw Normal View History

2016-03-26 16:16:01 +00:00
/*
ActiveGS, Copyright 2004-2016 Olivier Goguel, https://github.com/ogoguel/ActiveGS
Based on Kegs, Copyright 2004 Kent Dickey, https://kegs.sourceforge.net
This code is covered by the GNU GPL licence
*/
#pragma once
#define START_DCYCS (0.0)
#define MAX_EVENTS 64
extern byte *g_memory_ptr;
extern byte *g_slow_memory_ptr;
enum {
OFFSCREEN_AVAILABLE=256,
NO_INITIALIZED = 0,
INITIALIZING = 1,
RUNNING = 2 + OFFSCREEN_AVAILABLE,
// IN_REWIND = 3 + OFFSCREEN_AVAILABLE,
IN_PAUSE = 4 + OFFSCREEN_AVAILABLE,
PAUSE_REQUESTED = 5 + OFFSCREEN_AVAILABLE,
SHUTTING_DOWN = 5
};
typedef enum _colormode
{
COLORMODE_AUTO = 100,
COLORMODE_BW,
COLORMODE_AMBER,
COLORMODE_GREEN,
COLORMODE_MONO
} colormodeenum;
typedef enum _videofx
{
VIDEOFX_LCD = 200,
VIDEOFX_CRT
} videofxenum;
enum speedenum
{
SPEED_UNLIMITED = 0,
SPEED_1MHZ = 1,
SPEED_GS = 2, // 2.8 Mhz
SPEED_ZIP = 3, // 8 Mhz Zip speed
SPEED_ENUMSIZE=4,
SPEED_AUTO = 4,
};
class run_sim65816
{
int g_savestate_enable;
public:
int emulator_state;
int quit_requested;
int restart_requested;
colormodeenum color_mode;
videofxenum video_fx;
int g_user_halt_bad ;
int g_halt_on_bad_read ;
int g_ignore_bad_acc;
int g_ignore_halts ;
Page_info page_info_rd_wr[2*65536 + PAGE_INFO_PAD_SIZE];
run_sim65816()
{
memset(this,0,sizeof(*this));
emulator_state = NO_INITIALIZED;
color_mode = COLORMODE_AUTO;
video_fx = VIDEOFX_LCD;
g_ignore_bad_acc = 1;
g_ignore_halts = 1;
}
// Emulator COnfig
videofxenum get_video_fx() { return video_fx; }
void set_video_fx(videofxenum _vfx);
colormodeenum get_color_mode() { return color_mode; }
void set_color_mode(colormodeenum _cm);
int is_emulator_initialized();
int emulator_config_requested;
void request_update_emulator_runtime_config();
void check_update_emulator_runtime_config();
// Emulator State
void set_rewind_enable(int _onoff);
int get_rewind_enable() { return g_savestate_enable; };
void set_state(int _newstate);
int get_state();
void quit_emulator() ;
void restart_emulator();
void reset_quit();
void reset_restart();
int pause();
int resume();
// Emulator Info
int is_emulator_in_640mode();
int is_emulator_offscreen_available();
int should_emulator_terminate();
};
extern run_sim65816 r_sim65816;
extern void unserialize_engine(Engine_reg& engine);
extern void serialize_engine(Engine_reg& engine);
#ifdef _WIN32
#pragma pack(push,PRAGMA_PACK_SIZE)
#endif
class s_sim65816 : public serialized
{
public:
enum speedenum g_limit_speed ;
int get_limit_speed() { return (int)g_limit_speed; }
enum speedenum set_limit_speed(enum speedenum _speed);
int g_speed_fast ; // OG Expose fast parameter
Engine_reg engine;
_ALIGNED(8) double g_fcycles_stop;
volatile int halt_sim ;
int enter_debug;
int g_rom_version ;
int g_code_red ;
int g_code_yellow ;
int g_use_alib ;
int g_raw_serial ;
int g_iw2_emul ;
int g_serial_out_masking ;
int g_serial_modem[2];
int g_config_iwm_vbl_count;
_ALIGNED(8) double g_last_vbl_dcycs ;
_ALIGNED(8) double g_cur_dcycs ;
_ALIGNED(8) double g_last_vbl_dadjcycs ;
_ALIGNED(8) double g_dadjcycs;
int g_wait_pending ;
int g_stp_pending ;
int g_num_irq ;
int g_num_brk ;
int g_num_cop ;
int g_num_enter_engine ;
int g_io_amt ;
int g_engine_action ;
int g_engine_halt_event;
int g_engine_scan_int ;
int g_engine_doc_int ;
int g_testing ;
int g_testing_enabled ;
word32 stop_run_at;
int g_25sec_cntr ;
int g_1sec_cntr ;
_ALIGNED(8) double g_dnatcycs_1sec ;
word32 g_natcycs_lastvbl ;
// int Verbose ;
int Halt_on ;
word32 g_mem_size_base ;
word32 g_mem_size_exp ;
word32 g_mem_size_total ;
word32 g_vbl_count;
word32 g_vbl_count_since_lastvblank;
int g_fixed_vblank;
void set_fixed_vblank(int _nbframe,speedenum _defaultspeed);
int g_vbl_index_count;
_ALIGNED(8) double dtime_array[60];
_ALIGNED(8) double g_dadjcycs_array[60];
_ALIGNED(8) double g_dtime_diff3_array[60];
_ALIGNED(8) double g_dtime_this_vbl_array[60];
_ALIGNED(8) double g_dtime_exp_array[60];
_ALIGNED(8) double g_dtime_pmhz_array[60];
_ALIGNED(8) double g_dtime_eff_pmhz_array[60];
_ALIGNED(8) double sim_time[60];
_ALIGNED(8) double g_sim_sum ;
_ALIGNED(8) double g_cur_sim_dtime ;
_ALIGNED(8) double g_projected_pmhz;
_ALIGNED(8) double g_zip_pmhz ;
_ALIGNED(8) double g_sim_mhz ;
int g_line_ref_amt ;
int g_video_line_update_interval ;
Fplus g_recip_projected_pmhz_slow;
Fplus g_recip_projected_pmhz_fast;
Fplus g_recip_projected_pmhz_zip;
Fplus g_recip_projected_pmhz_unl;
_ALIGNED(8) double g_dtime_last_vbl ;
_ALIGNED(8) double g_dtime_expected ;
int g_scan_int_events ;
char g_display_env[512];
int g_force_depth;
Event g_event_list[MAX_EVENTS];
Event g_event_free;
Event g_event_start;
// Page_info page_info_rd_wr[2*65536 + PAGE_INFO_PAD_SIZE];
// OG unsupported 6502 opcodes are turned into NOP
int g_6502_emulation ;
int g_use_apple2e_rom ;
int g_enable_disk_sound;
s_sim65816()
{
INIT_SERIALIZED();
g_rom_version = -1;
// g_ignore_bad_acc = 1;
// g_ignore_halts = 1;
g_raw_serial = 1;
g_serial_modem[1] = 1;
g_last_vbl_dcycs = START_DCYCS;
g_cur_dcycs = START_DCYCS;
g_mem_size_base = 256*1024; /* size of motherboard memory */
g_mem_size_exp = 2*1024*1024; /* size of expansion RAM card */
g_mem_size_total = 256*1024; /* Total contiguous RAM from 0 */
g_projected_pmhz = 1.0;
g_zip_pmhz = 8.0;
g_sim_mhz = 100.0;
g_line_ref_amt = 1;
g_dtime_expected = (1.0/60.0);
g_force_depth = -1;
g_limit_speed = SPEED_GS;
}
#define RECALC_BASE_EVENT_PTR(X,BASE) \
if (X) \
{ \
X = (Event*)( (intptr_t)X + (intptr_t)BASE ) ; \
}
void in(serialize* _s)
{
extern byte* g_dummy_memory1_ptr;
byte* ptr = (byte*)_s->data;
int ssize = *(int*)ptr;
if (ssize!=sizeof(*this))
ALIGNMENT_ERROR("sim65816",ssize,sizeof(*this));
ptr+=4;
memcpy(this,_s->data,sizeof(*this));
unserialize_engine(engine);
ptr += sizeof(*this);
memcpy(g_slow_memory_ptr,ptr,128*1024);
ptr+=128*1024;
memcpy(g_dummy_memory1_ptr,ptr,256);
ptr+=256;
memcpy(g_memory_ptr,ptr,g_mem_size_total);
intptr_t base = (intptr_t)g_event_list +1; // pour ne pas commencer <20> zero!
for(int i = 1; i < MAX_EVENTS; i++)
{
RECALC_BASE_EVENT_PTR(g_event_list[i-1].next,+base);
}
RECALC_BASE_EVENT_PTR(g_event_free.next,+base);
RECALC_BASE_EVENT_PTR(g_event_start.next,+base);
g_dtime_last_vbl += get_dtime();
g_dtime_expected += get_dtime();
}
int out(serialize* _s,int _fastalloc)
{
extern byte* g_dummy_memory1_ptr;
int ssize = sizeof(*this);
int size = sizeof(ssize);
size += ssize;
size += 128*1024; // slow memory
size += 256; // dummy
size += g_mem_size_total;
_s->size = size;
_s->fastalloc = _fastalloc;
_s->data = (void*)x_malloc(size,_fastalloc);
intptr_t base = (intptr_t)g_event_list +1; // pour ne pas commencer <20> zero!
// reinitialize les event avant de les copier
for(int i = 1; i < MAX_EVENTS; i++)
{
RECALC_BASE_EVENT_PTR(g_event_list[i-1].next,-base);
}
RECALC_BASE_EVENT_PTR(g_event_free.next,-base);
RECALC_BASE_EVENT_PTR(g_event_start.next,-base);
serialize_engine(engine);
double old_g_dtime_last_vbl = g_dtime_last_vbl;
g_dtime_last_vbl -= get_dtime();
double old_g_dtime_expected = g_dtime_expected;
g_dtime_expected -= get_dtime();
byte* ptr = (byte*)_s->data;
memcpy(ptr,&ssize,sizeof(ssize));
ptr+=sizeof(ssize);
memcpy(_s->data,this,sizeof(*this));
ptr += sizeof(*this);
unserialize_engine(engine);
g_dtime_last_vbl = old_g_dtime_last_vbl;
g_dtime_expected = old_g_dtime_expected;
memcpy(ptr,g_slow_memory_ptr,128*1024);
ptr+= 128*1024;
memcpy(ptr,g_dummy_memory1_ptr,256);
ptr+=256;
memcpy(ptr,g_memory_ptr,g_mem_size_total);
// reinitialize les event avant de les copier
for(int i = 1; i < MAX_EVENTS; i++)
{
RECALC_BASE_EVENT_PTR(g_event_list[i-1].next,base);
}
RECALC_BASE_EVENT_PTR(g_event_free.next,base);
RECALC_BASE_EVENT_PTR(g_event_start.next,base);
g_dtime_last_vbl += get_dtime();
return size;
}
} XCODE_PRAGMA_PACK;
#ifdef _WIN32
#pragma pack(pop)
#endif
extern void x_update_info(const char* total_mhz_ptr);
extern s_sim65816 g_sim65816;
extern int Verbose;
//extern int g_pause;
/* All EV_* must be less than 256, since upper bits reserved for other use */
/* e.g., DOC_INT uses upper bits to encode oscillator */
#define EV_60HZ 1
#define EV_STOP 2
#define EV_SCAN_INT 3
#define EV_DOC_INT 4
#define EV_VBL_INT 5
#define EV_SCC 6
#define EV_VID_UPD 7
#define EV_SCC_ENABLE 8