mirror of
https://github.com/ogoguel/activegs-ios.git
synced 2024-11-02 13:07:57 +00:00
392 lines
8.8 KiB
C
392 lines
8.8 KiB
C
|
/*
|
|||
|
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
|