mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-09-29 08:55:06 +00:00
Refactor VM initialization and shutdown
This commit is contained in:
parent
bc5559c1b0
commit
ed60b2ea73
@ -295,7 +295,7 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// shut down common OpenGL stuff AFTER display link has been released
|
// shut down common OpenGL stuff AFTER display link has been released
|
||||||
video_backend->shutdown();
|
emulator_shutdown();
|
||||||
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ AM_LFLAGS = -i
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
# No install
|
# No install
|
||||||
|
|
||||||
noinst_HEADERS = src/common.h src/cpu.h src/disk.h src/glue.h \
|
noinst_HEADERS = src/common.h src/cpu.h src/disk.h src/glue.h src/vm.h \
|
||||||
src/interface.h src/joystick.h src/keys.h src/misc.h src/prefs.h \
|
src/interface.h src/joystick.h src/keys.h src/misc.h src/prefs.h \
|
||||||
src/timing.h src/uthash.h src/video/video.h src/zlib-helpers.h \
|
src/timing.h src/uthash.h src/video/video.h src/zlib-helpers.h \
|
||||||
\
|
\
|
||||||
@ -81,7 +81,7 @@ src/font.c: src/font.txt genfont
|
|||||||
src/rom.c: genrom
|
src/rom.c: genrom
|
||||||
./genrom src/rom/apple_IIe.rom src/rom/slot6.rom > $@
|
./genrom src/rom/apple_IIe.rom src/rom/slot6.rom > $@
|
||||||
|
|
||||||
src/x86/glue.S: src/disk.c src/misc.c src/display.c src/vm.c src/cpu-supp.c @AUDIO_GLUE_C@
|
src/x86/glue.S: src/disk.c src/vm.c src/display.c src/vm.c src/cpu-supp.c @AUDIO_GLUE_C@
|
||||||
./src/x86/genglue $^ > $@
|
./src/x86/genglue $^ > $@
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cpu-regs.h"
|
#include "cpu-regs.h"
|
||||||
#include "misc.h"
|
#include "vm.h"
|
||||||
|
|
||||||
|
|
||||||
#define DecodeFlags \
|
#define DecodeFlags \
|
||||||
|
@ -9,9 +9,11 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "misc.h"
|
#include "vm.h"
|
||||||
#include "cpu-regs.h"
|
#include "cpu-regs.h"
|
||||||
|
|
||||||
|
#define GLUE_EXTERN_C_READ(func)
|
||||||
|
|
||||||
#define GLUE_BANK_MAYBEREAD(func,pointer) \
|
#define GLUE_BANK_MAYBEREAD(func,pointer) \
|
||||||
ENTRY(func) ldr r1, SYM(softswitches); \
|
ENTRY(func) ldr r1, SYM(softswitches); \
|
||||||
ldr r0, [r1]; \
|
ldr r0, [r1]; \
|
||||||
|
@ -2040,11 +2040,6 @@ void MB_InitializeIO(char *unused_pCxRomPeripheral, unsigned int uSlot4, unsigne
|
|||||||
// Phasor : Slot 4
|
// Phasor : Slot 4
|
||||||
// <other> : Slot 4 & 5
|
// <other> : Slot 4 & 5
|
||||||
|
|
||||||
#ifdef APPLE2IX
|
|
||||||
extern void MB_Read();
|
|
||||||
extern void MB_Write();
|
|
||||||
extern void PhasorIO();
|
|
||||||
#endif
|
|
||||||
if (g_Slot4 != CT_MockingboardC && g_Slot4 != CT_Phasor)
|
if (g_Slot4 != CT_MockingboardC && g_Slot4 != CT_Phasor)
|
||||||
{
|
{
|
||||||
MB_SetSoundcardType(CT_Empty);
|
MB_SetSoundcardType(CT_Empty);
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "vm.h"
|
||||||
#include "timing.h"
|
#include "timing.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "video/video.h"
|
#include "video/video.h"
|
||||||
|
@ -653,7 +653,6 @@ void cpu65_reboot(void) {
|
|||||||
video_reset();
|
video_reset();
|
||||||
joy_button0 = 0xff; // OpenApple
|
joy_button0 = 0xff; // OpenApple
|
||||||
cpu65_interrupt(ResetSig);
|
cpu65_interrupt(ResetSig);
|
||||||
c_initialize_sound_hooks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CPU_TRACING
|
#if CPU_TRACING
|
||||||
|
@ -96,18 +96,18 @@ uint8_t video__dhires2[256] = {
|
|||||||
|
|
||||||
// forward decls of VM entry points
|
// forward decls of VM entry points
|
||||||
|
|
||||||
void video__write_2e_text0(void);
|
void video__write_2e_text0(uint16_t, uint8_t);
|
||||||
void video__write_2e_text0_mixed(void);
|
void video__write_2e_text0_mixed(uint16_t, uint8_t);
|
||||||
void video__write_2e_text1(void);
|
void video__write_2e_text1(uint16_t, uint8_t);
|
||||||
void video__write_2e_text1_mixed(void);
|
void video__write_2e_text1_mixed(uint16_t, uint8_t);
|
||||||
void video__write_2e_odd0(void);
|
void video__write_2e_odd0(uint16_t, uint8_t);
|
||||||
void video__write_2e_even0(void);
|
void video__write_2e_even0(uint16_t, uint8_t);
|
||||||
void video__write_2e_odd0_mixed(void);
|
void video__write_2e_odd0_mixed(uint16_t, uint8_t);
|
||||||
void video__write_2e_even0_mixed(void);
|
void video__write_2e_even0_mixed(uint16_t, uint8_t);
|
||||||
void video__write_2e_odd1(void);
|
void video__write_2e_odd1(uint16_t, uint8_t);
|
||||||
void video__write_2e_even1(void);
|
void video__write_2e_even1(uint16_t, uint8_t);
|
||||||
void video__write_2e_odd1_mixed(void);
|
void video__write_2e_odd1_mixed(uint16_t, uint8_t);
|
||||||
void video__write_2e_even1_mixed(void);
|
void video__write_2e_even1_mixed(uint16_t, uint8_t);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Initialization routines
|
// Initialization routines
|
||||||
|
22
src/glue.h
22
src/glue.h
@ -14,15 +14,21 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLUE_BANK_READ(func,pointer)
|
#if defined(__ASSEMBLER__)
|
||||||
#define GLUE_BANK_MAYBEREAD(func,pointer)
|
# error assembler-specific glue code should be in the arch-specific area
|
||||||
#define GLUE_BANK_WRITE(func,pointer)
|
#endif
|
||||||
#define GLUE_BANK_MAYBEWRITE(func,pointer)
|
|
||||||
|
#define GLUE_BANK_READ(func,pointer) extern void func(void)
|
||||||
|
#define GLUE_BANK_MAYBEREAD(func,pointer) extern void func(void)
|
||||||
|
#define GLUE_BANK_WRITE(func,pointer) extern void func(void)
|
||||||
|
#define GLUE_BANK_MAYBEWRITE(func,pointer) extern void func(void)
|
||||||
|
|
||||||
|
#define GLUE_EXTERN_C_READ(func) extern uint8_t func(uint16_t)
|
||||||
|
|
||||||
#if VM_TRACING
|
#if VM_TRACING
|
||||||
|
|
||||||
#define GLUE_C_WRITE(func) \
|
#define GLUE_C_WRITE(func) \
|
||||||
extern void func(void); \
|
extern void func(uint16_t, uint8_t); \
|
||||||
void c__##func(uint16_t ea, uint8_t b); \
|
void c__##func(uint16_t ea, uint8_t b); \
|
||||||
void c_##func(uint16_t ea, uint8_t b) { \
|
void c_##func(uint16_t ea, uint8_t b) { \
|
||||||
c__##func(ea, b); \
|
c__##func(ea, b); \
|
||||||
@ -35,7 +41,7 @@
|
|||||||
void c__##func(uint16_t ea, uint8_t b)
|
void c__##func(uint16_t ea, uint8_t b)
|
||||||
|
|
||||||
#define GLUE_C_READ(func) \
|
#define GLUE_C_READ(func) \
|
||||||
extern void func(void); \
|
extern uint8_t func(uint16_t); \
|
||||||
uint8_t c__##func(uint16_t ea); \
|
uint8_t c__##func(uint16_t ea); \
|
||||||
uint8_t c_##func(uint16_t ea) { \
|
uint8_t c_##func(uint16_t ea) { \
|
||||||
uint8_t b = c__##func(ea); \
|
uint8_t b = c__##func(ea); \
|
||||||
@ -51,11 +57,11 @@
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#define GLUE_C_WRITE(func) \
|
#define GLUE_C_WRITE(func) \
|
||||||
extern void func(void); \
|
extern void func(uint16_t, uint8_t); \
|
||||||
void c_##func(uint16_t ea, uint8_t b)
|
void c_##func(uint16_t ea, uint8_t b)
|
||||||
|
|
||||||
#define GLUE_C_READ(func) \
|
#define GLUE_C_READ(func) \
|
||||||
extern void func(void); \
|
extern uint8_t func(uint16_t); \
|
||||||
uint8_t c_##func(uint16_t ea)
|
uint8_t c_##func(uint16_t ea)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1160,7 +1160,7 @@ void c_interface_parameters()
|
|||||||
{
|
{
|
||||||
timing_initialize();
|
timing_initialize();
|
||||||
video_reset();
|
video_reset();
|
||||||
c_initialize_sound_hooks();
|
vm_reinitializeAudio();
|
||||||
c_joystick_reset();
|
c_joystick_reset();
|
||||||
c_interface_exit(ch);
|
c_interface_exit(ch);
|
||||||
return;
|
return;
|
||||||
|
@ -448,10 +448,6 @@ int c_mygetch(int block)
|
|||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
if (emulator_shutting_down) {
|
|
||||||
next_key = kESC;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (next_key == -1 && block)
|
while (next_key == -1 && block)
|
||||||
{
|
{
|
||||||
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
|
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
|
||||||
|
582
src/misc.c
582
src/misc.c
@ -16,19 +16,13 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
/* ----------------------------------
|
|
||||||
internal apple2 variables
|
|
||||||
---------------------------------- */
|
|
||||||
|
|
||||||
extern uint8_t apple_iie_rom[32768];
|
|
||||||
|
|
||||||
bool emulator_shutting_down = false;
|
|
||||||
bool do_logging = true; // also controlled by NDEBUG
|
bool do_logging = true; // also controlled by NDEBUG
|
||||||
FILE *error_log = NULL;
|
FILE *error_log = NULL;
|
||||||
|
|
||||||
int sound_volume = 2;
|
int sound_volume = 2;
|
||||||
color_mode_t color_mode = COLOR;
|
color_mode_t color_mode = COLOR;
|
||||||
const char *data_dir = NULL;
|
const char *data_dir = NULL;
|
||||||
|
char **argv = NULL;
|
||||||
|
int argc = 0;
|
||||||
|
|
||||||
__attribute__((constructor(CTOR_PRIORITY_FIRST)))
|
__attribute__((constructor(CTOR_PRIORITY_FIRST)))
|
||||||
static void _init_common() {
|
static void _init_common() {
|
||||||
@ -36,544 +30,18 @@ static void _init_common() {
|
|||||||
#if defined(CONFIG_DATADIR)
|
#if defined(CONFIG_DATADIR)
|
||||||
data_dir = strdup(CONFIG_DATADIR PATH_SEPARATOR PACKAGE_NAME);
|
data_dir = strdup(CONFIG_DATADIR PATH_SEPARATOR PACKAGE_NAME);
|
||||||
#elif defined(ANDROID)
|
#elif defined(ANDROID)
|
||||||
// data_dir is set up in JNI nativeOnCreate()
|
// data_dir is set up in JNI
|
||||||
#elif !defined(__APPLE__)
|
#elif !defined(__APPLE__)
|
||||||
#error "Specify a CONFIG_DATADIR and PACKAGE_NAME"
|
# error "Specify a CONFIG_DATADIR and PACKAGE_NAME"
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GLUE_BANK_READ(read_ram_bank,base_d000_rd)
|
|
||||||
GLUE_BANK_MAYBEWRITE(write_ram_bank,base_d000_wrt)
|
|
||||||
GLUE_BANK_READ(read_ram_lc,base_e000_rd)
|
|
||||||
GLUE_BANK_MAYBEWRITE(write_ram_lc,base_e000_wrt)
|
|
||||||
|
|
||||||
GLUE_BANK_READ(iie_read_ram_default,base_ramrd)
|
|
||||||
GLUE_BANK_WRITE(iie_write_ram_default,base_ramwrt)
|
|
||||||
GLUE_BANK_READ(iie_read_ram_text_page0,base_textrd)
|
|
||||||
GLUE_BANK_WRITE(iie_write_screen_hole_text_page0,base_textwrt)
|
|
||||||
GLUE_BANK_READ(iie_read_ram_hires_page0,base_hgrrd)
|
|
||||||
GLUE_BANK_WRITE(iie_write_screen_hole_hires_page0,base_hgrwrt)
|
|
||||||
|
|
||||||
GLUE_BANK_READ(iie_read_ram_zpage_and_stack,base_stackzp)
|
|
||||||
GLUE_BANK_WRITE(iie_write_ram_zpage_and_stack,base_stackzp)
|
|
||||||
|
|
||||||
GLUE_BANK_READ(iie_read_slot3,base_c3rom)
|
|
||||||
GLUE_BANK_MAYBEREAD(iie_read_slot4,base_c4rom)
|
|
||||||
GLUE_BANK_MAYBEREAD(iie_read_slot5,base_c5rom)
|
|
||||||
GLUE_BANK_READ(iie_read_slotx,base_cxrom)
|
|
||||||
|
|
||||||
uint32_t softswitches;
|
|
||||||
|
|
||||||
const uint8_t *base_vmem = apple_ii_64k[0];
|
|
||||||
uint8_t *base_ramrd;
|
|
||||||
uint8_t *base_ramwrt;
|
|
||||||
uint8_t *base_textrd;
|
|
||||||
uint8_t *base_textwrt;
|
|
||||||
uint8_t *base_hgrrd;
|
|
||||||
uint8_t *base_hgrwrt;
|
|
||||||
|
|
||||||
uint8_t *base_stackzp;
|
|
||||||
uint8_t *base_d000_rd;
|
|
||||||
uint8_t *base_e000_rd;
|
|
||||||
uint8_t *base_d000_wrt;
|
|
||||||
uint8_t *base_e000_wrt;
|
|
||||||
|
|
||||||
uint8_t *base_c3rom;
|
|
||||||
uint8_t *base_c4rom;
|
|
||||||
uint8_t *base_c5rom;
|
|
||||||
uint8_t *base_cxrom;
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
c_debug_illegal_bcd - illegal BCD (decimal mode) computation
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
GLUE_C_READ(debug_illegal_bcd)
|
|
||||||
{
|
|
||||||
RELEASE_LOG("Illegal/undefined BCD operation encountered, debug break on c_debug_illegal_bcd to debug...");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
c_set_altchar() - set alternate character set
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
void c_set_altchar()
|
|
||||||
{
|
|
||||||
video_loadfont(0x40,0x20,mousetext_glyphs,1);
|
|
||||||
video_loadfont(0x60,0x20,lcase_glyphs,2);
|
|
||||||
|
|
||||||
video_redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
c_set_primary_char() - set primary character set
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
void c_set_primary_char()
|
|
||||||
{
|
|
||||||
video_loadfont(0x40,0x40,ucase_glyphs,3);
|
|
||||||
|
|
||||||
video_redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
c_initialize_font(): Initialize ROM character table to primary char set
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
void c_initialize_font()
|
|
||||||
{
|
|
||||||
video_loadfont(0x00,0x40,ucase_glyphs,2);
|
|
||||||
video_loadfont(0x40,0x40,ucase_glyphs,3);
|
|
||||||
video_loadfont(0x80,0x40,ucase_glyphs,0);
|
|
||||||
video_loadfont(0xC0,0x20,ucase_glyphs,0);
|
|
||||||
video_loadfont(0xE0,0x20,lcase_glyphs,0);
|
|
||||||
video_redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
c_initialize_tables()
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
void c_initialize_tables() {
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* reset everything */
|
|
||||||
for (i = 0; i < 0x10000; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] = iie_read_ram_default;
|
|
||||||
cpu65_vmem_w[i] = iie_write_ram_default;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* language card read/write area */
|
|
||||||
for (i = 0xD000; i < 0xE000; i++)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
cpu65_vmem_w[i] =
|
|
||||||
write_ram_bank;
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
read_ram_bank;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0xE000; i < 0x10000; i++)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
cpu65_vmem_w[i] =
|
|
||||||
write_ram_lc;
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
read_ram_lc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* done common initialization */
|
|
||||||
|
|
||||||
/* initialize zero-page, //e specific */
|
|
||||||
for (i = 0; i < 0x200; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
iie_read_ram_zpage_and_stack;
|
|
||||||
cpu65_vmem_w[i] =
|
|
||||||
iie_write_ram_zpage_and_stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize first text & hires page, which are specially bank switched
|
|
||||||
*
|
|
||||||
* video_reset() substitutes it's own hooks for all visible write locations
|
|
||||||
* affect the display, leaving our write-functions in place only at the
|
|
||||||
* `screen holes', hence the name.
|
|
||||||
*/
|
|
||||||
for (i = 0x400; i < 0x800; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
iie_read_ram_text_page0;
|
|
||||||
cpu65_vmem_w[i] =
|
|
||||||
iie_write_screen_hole_text_page0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0x2000; i < 0x4000; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
iie_read_ram_hires_page0;
|
|
||||||
cpu65_vmem_w[i] =
|
|
||||||
iie_write_screen_hole_hires_page0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* softswich rom */
|
|
||||||
for (i = 0xC000; i < 0xC100; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
read_unmapped_softswitch;
|
|
||||||
cpu65_vmem_w[i] =
|
|
||||||
write_unmapped_softswitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* slot rom defaults */
|
|
||||||
for (i = 0xC100; i < 0xD000; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
iie_read_ram_default;
|
|
||||||
cpu65_vmem_w[i] =
|
|
||||||
ram_nop;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* keyboard data and strobe (READ) */
|
|
||||||
for (i = 0xC000; i < 0xC010; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
read_keyboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0xC010; i < 0xC020; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
cpu65_vmem_w[i] =
|
|
||||||
read_keyboard_strobe;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RDBNK2 switch */
|
|
||||||
cpu65_vmem_r[0xC011] =
|
|
||||||
iie_check_bank;
|
|
||||||
|
|
||||||
/* RDLCRAM switch */
|
|
||||||
cpu65_vmem_r[0xC012] =
|
|
||||||
iie_check_lcram;
|
|
||||||
|
|
||||||
/* 80STORE switch */
|
|
||||||
cpu65_vmem_w[0xC000] = iie_80store_off;
|
|
||||||
cpu65_vmem_w[0xC001] = iie_80store_on;
|
|
||||||
cpu65_vmem_r[0xC018] = iie_check_80store;
|
|
||||||
|
|
||||||
/* RAMRD switch */
|
|
||||||
cpu65_vmem_w[0xC002] = iie_ramrd_main;
|
|
||||||
cpu65_vmem_w[0xC003] = iie_ramrd_aux;
|
|
||||||
cpu65_vmem_r[0xC013] = iie_check_ramrd;
|
|
||||||
|
|
||||||
/* RAMWRT switch */
|
|
||||||
cpu65_vmem_w[0xC004] = iie_ramwrt_main;
|
|
||||||
cpu65_vmem_w[0xC005] = iie_ramwrt_aux;
|
|
||||||
cpu65_vmem_r[0xC014] = iie_check_ramwrt;
|
|
||||||
|
|
||||||
/* ALTZP switch */
|
|
||||||
cpu65_vmem_w[0xC008] = iie_altzp_main;
|
|
||||||
cpu65_vmem_w[0xC009] = iie_altzp_aux;
|
|
||||||
cpu65_vmem_r[0xC016] = iie_check_altzp;
|
|
||||||
|
|
||||||
/* 80COL switch */
|
|
||||||
cpu65_vmem_w[0xC00C] = iie_80col_off;
|
|
||||||
cpu65_vmem_w[0xC00D] = iie_80col_on;
|
|
||||||
cpu65_vmem_r[0xC01F] = iie_check_80col;
|
|
||||||
|
|
||||||
/* ALTCHAR switch */
|
|
||||||
cpu65_vmem_w[0xC00E] = iie_altchar_off;
|
|
||||||
cpu65_vmem_w[0xC00F] = iie_altchar_on;
|
|
||||||
cpu65_vmem_r[0xC01E] = iie_check_altchar;
|
|
||||||
|
|
||||||
/* SLOTC3ROM switch */
|
|
||||||
cpu65_vmem_w[0xC00A] = iie_c3rom_internal;
|
|
||||||
cpu65_vmem_w[0xC00B] = iie_c3rom_peripheral;
|
|
||||||
cpu65_vmem_r[0xC017] = iie_check_c3rom;
|
|
||||||
|
|
||||||
/* SLOTCXROM switch */
|
|
||||||
cpu65_vmem_w[0xC006] = iie_cxrom_peripheral;
|
|
||||||
cpu65_vmem_w[0xC007] = iie_cxrom_internal;
|
|
||||||
cpu65_vmem_r[0xC015] = iie_check_cxrom;
|
|
||||||
|
|
||||||
/* RDVBLBAR switch */
|
|
||||||
cpu65_vmem_r[0xC019] = iie_check_vbl;
|
|
||||||
|
|
||||||
/* TEXT switch */
|
|
||||||
cpu65_vmem_r[0xC050] =
|
|
||||||
cpu65_vmem_w[0xC050] =
|
|
||||||
read_switch_graphics;
|
|
||||||
cpu65_vmem_r[0xC051] =
|
|
||||||
cpu65_vmem_w[0xC051] =
|
|
||||||
read_switch_text;
|
|
||||||
|
|
||||||
cpu65_vmem_r[0xC01A] =
|
|
||||||
iie_check_text;
|
|
||||||
|
|
||||||
/* MIXED switch */
|
|
||||||
cpu65_vmem_r[0xC052] =
|
|
||||||
cpu65_vmem_w[0xC052] =
|
|
||||||
read_switch_no_mixed;
|
|
||||||
cpu65_vmem_r[0xC053] =
|
|
||||||
cpu65_vmem_w[0xC053] =
|
|
||||||
read_switch_mixed;
|
|
||||||
|
|
||||||
cpu65_vmem_r[0xC01B] =
|
|
||||||
iie_check_mixed;
|
|
||||||
|
|
||||||
/* PAGE2 switch */
|
|
||||||
cpu65_vmem_r[0xC054] =
|
|
||||||
cpu65_vmem_w[0xC054] =
|
|
||||||
iie_page2_off;
|
|
||||||
|
|
||||||
cpu65_vmem_r[0xC01C] =
|
|
||||||
iie_check_page2;
|
|
||||||
|
|
||||||
/* PAGE2 switch */
|
|
||||||
cpu65_vmem_r[0xC055] =
|
|
||||||
cpu65_vmem_w[0xC055] =
|
|
||||||
iie_page2_on;
|
|
||||||
|
|
||||||
/* HIRES switch */
|
|
||||||
cpu65_vmem_r[0xC01D] =
|
|
||||||
iie_check_hires;
|
|
||||||
cpu65_vmem_r[0xC056] =
|
|
||||||
cpu65_vmem_w[0xC056] =
|
|
||||||
iie_hires_off;
|
|
||||||
cpu65_vmem_r[0xC057] =
|
|
||||||
cpu65_vmem_w[0xC057] =
|
|
||||||
iie_hires_on;
|
|
||||||
|
|
||||||
/* game I/O switches */
|
|
||||||
cpu65_vmem_r[0xC061] =
|
|
||||||
cpu65_vmem_r[0xC069] =
|
|
||||||
read_button0;
|
|
||||||
cpu65_vmem_r[0xC062] =
|
|
||||||
cpu65_vmem_r[0xC06A] =
|
|
||||||
read_button1;
|
|
||||||
cpu65_vmem_r[0xC063] =
|
|
||||||
cpu65_vmem_r[0xC06B] =
|
|
||||||
read_button2;
|
|
||||||
cpu65_vmem_r[0xC064] =
|
|
||||||
cpu65_vmem_r[0xC06C] =
|
|
||||||
read_gc0;
|
|
||||||
cpu65_vmem_r[0xC065] =
|
|
||||||
cpu65_vmem_r[0xC06D] =
|
|
||||||
read_gc1;
|
|
||||||
cpu65_vmem_r[0xC066] =
|
|
||||||
iie_read_gc2;
|
|
||||||
cpu65_vmem_r[0xC067] =
|
|
||||||
iie_read_gc3;
|
|
||||||
|
|
||||||
for (i = 0xC070; i < 0xC080; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
cpu65_vmem_w[i] =
|
|
||||||
read_gc_strobe;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IOUDIS switch & read_gc_strobe */
|
|
||||||
cpu65_vmem_w[0xC07E] =
|
|
||||||
iie_ioudis_on;
|
|
||||||
cpu65_vmem_w[0xC07F] =
|
|
||||||
iie_ioudis_off; // HACK FIXME TODO : double-check this stuff against AWin...
|
|
||||||
cpu65_vmem_r[0xC07E] =
|
|
||||||
iie_check_ioudis;
|
|
||||||
cpu65_vmem_r[0xC07F] =
|
|
||||||
iie_check_dhires;
|
|
||||||
|
|
||||||
/* Annunciator */
|
|
||||||
for (i = 0xC058; i <= 0xC05D; i++) {
|
|
||||||
cpu65_vmem_w[i] = cpu65_vmem_r[i] = iie_annunciator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DHIRES */
|
|
||||||
cpu65_vmem_w[0xC05E] =
|
|
||||||
cpu65_vmem_r[0xC05E] =
|
|
||||||
iie_dhires_on;
|
|
||||||
cpu65_vmem_w[0xC05F] =
|
|
||||||
cpu65_vmem_r[0xC05F] =
|
|
||||||
iie_dhires_off;
|
|
||||||
|
|
||||||
/* language card softswitches */
|
|
||||||
cpu65_vmem_r[0xC080] = cpu65_vmem_w[0xC080] =
|
|
||||||
cpu65_vmem_r[0xC084] = cpu65_vmem_w[0xC084] = iie_c080;
|
|
||||||
cpu65_vmem_r[0xC081] = cpu65_vmem_w[0xC081] =
|
|
||||||
cpu65_vmem_r[0xC085] = cpu65_vmem_w[0xC085] = iie_c081;
|
|
||||||
cpu65_vmem_r[0xC082] = cpu65_vmem_w[0xC082] =
|
|
||||||
cpu65_vmem_r[0xC086] = cpu65_vmem_w[0xC086] = lc_c082;
|
|
||||||
cpu65_vmem_r[0xC083] = cpu65_vmem_w[0xC083] =
|
|
||||||
cpu65_vmem_r[0xC087] = cpu65_vmem_w[0xC087] = iie_c083;
|
|
||||||
|
|
||||||
cpu65_vmem_r[0xC088] = cpu65_vmem_w[0xC088] =
|
|
||||||
cpu65_vmem_r[0xC08C] = cpu65_vmem_w[0xC08C] = iie_c088;
|
|
||||||
cpu65_vmem_r[0xC089] = cpu65_vmem_w[0xC089] =
|
|
||||||
cpu65_vmem_r[0xC08D] = cpu65_vmem_w[0xC08D] = iie_c089;
|
|
||||||
cpu65_vmem_r[0xC08A] = cpu65_vmem_w[0xC08A] =
|
|
||||||
cpu65_vmem_r[0xC08E] = cpu65_vmem_w[0xC08E] = lc_c08a;
|
|
||||||
cpu65_vmem_r[0xC08B] = cpu65_vmem_w[0xC08B] =
|
|
||||||
cpu65_vmem_r[0xC08F] = cpu65_vmem_w[0xC08F] = iie_c08b;
|
|
||||||
|
|
||||||
/* slot i/o area */
|
|
||||||
for (i = 0xC100; i < 0xC300; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
iie_read_slotx; /* slots 1 & 2 (x) */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0xC300; i < 0xC400; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
iie_read_slot3; /* slot 3 (80col) */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0xC400; i < 0xC500; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
iie_read_slot4; /* slot 4 - MB or Phasor */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0xC500; i < 0xC600; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
iie_read_slot5; /* slot 5 - MB #2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0xC600; i < 0xC800; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] =
|
|
||||||
iie_read_slotx; /* slots 6 - 7 (x) */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0xC800; i < 0xD000; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] = iie_read_slot_expansion;
|
|
||||||
}
|
|
||||||
cpu65_vmem_w[0xCFFF] = iie_read_slot_expansion;
|
|
||||||
|
|
||||||
video_reset();
|
|
||||||
|
|
||||||
// Peripheral card slot initializations ...
|
|
||||||
|
|
||||||
// HACK TODO FIXME : this needs to be tied to the UI/configuration system (once we have more/conflicting options)
|
|
||||||
|
|
||||||
#ifdef AUDIO_ENABLED
|
|
||||||
mb_io_initialize(4, 5); /* Mockingboard(s) and/or Phasor in slots 4 & 5 */
|
|
||||||
#endif
|
|
||||||
disk_io_initialize(6); /* Put a Disk ][ Controller in slot 6 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
c_initialize_apple_ii_memory()
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
void c_initialize_apple_ii_memory()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 0x10000; i++)
|
|
||||||
{
|
|
||||||
apple_ii_64k[0][i] = 0;
|
|
||||||
apple_ii_64k[1][i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stripe words of main memory on machine reset ...
|
|
||||||
// NOTE: cracked version of J---- will lock up without this
|
|
||||||
for (i = 0; i < 0xC000;) {
|
|
||||||
apple_ii_64k[0][i++] = 0xFF;
|
|
||||||
apple_ii_64k[0][i++] = 0xFF;
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 8192; i++)
|
|
||||||
{
|
|
||||||
language_card[0][i] = language_card[1][i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 8192; i++)
|
|
||||||
{
|
|
||||||
language_banks[0][i] = language_banks[1][i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* load the rom from 0xC000, slot rom main, internal rom aux */
|
|
||||||
for (i = 0xC000; i < 0x10000; i++)
|
|
||||||
{
|
|
||||||
apple_ii_64k[0][i] = apple_iie_rom[i - 0xC000];
|
|
||||||
apple_ii_64k[1][i] = apple_iie_rom[i - 0x8000];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 0x1000; i++)
|
|
||||||
{
|
|
||||||
language_banks[0][i] = apple_iie_rom[i + 0x1000];
|
|
||||||
language_banks[1][i] = apple_iie_rom[i + 0x5000];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 0x2000; i++)
|
|
||||||
{
|
|
||||||
language_card[0][i] = apple_iie_rom[i + 0x2000];
|
|
||||||
language_card[1][i] = apple_iie_rom[i + 0x6000];
|
|
||||||
}
|
|
||||||
|
|
||||||
apple_ii_64k[0][0xC000] = 0x00;
|
|
||||||
apple_ii_64k[1][0xC000] = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
void c_initialize_sound_hooks()
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
void c_initialize_sound_hooks()
|
|
||||||
{
|
|
||||||
#ifdef AUDIO_ENABLED
|
|
||||||
speaker_setVolumeZeroToTen(sound_volume);
|
|
||||||
MB_SetVolumeZeroToTen(sound_volume);
|
|
||||||
#endif
|
|
||||||
for (int i = 0xC030; i < 0xC040; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] = cpu65_vmem_w[i] =
|
|
||||||
#ifdef AUDIO_ENABLED
|
|
||||||
(sound_volume > 0) ? speaker_toggle :
|
|
||||||
#endif
|
|
||||||
ram_nop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void c_disable_sound_hooks()
|
|
||||||
{
|
|
||||||
for (int i = 0xC030; i < 0xC040; i++)
|
|
||||||
{
|
|
||||||
cpu65_vmem_r[i] = ram_nop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
c_initialize_iie_switches
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
void c_initialize_iie_switches() {
|
|
||||||
|
|
||||||
base_stackzp = apple_ii_64k[0];
|
|
||||||
base_d000_rd = apple_ii_64k[0];
|
|
||||||
base_d000_wrt = language_banks[0] - 0xD000;
|
|
||||||
base_e000_rd = apple_ii_64k[0];
|
|
||||||
base_e000_wrt = language_card[0] - 0xE000;
|
|
||||||
|
|
||||||
base_ramrd = apple_ii_64k[0];
|
|
||||||
base_ramwrt = apple_ii_64k[0];
|
|
||||||
base_textrd = apple_ii_64k[0];
|
|
||||||
base_textwrt = apple_ii_64k[0];
|
|
||||||
base_hgrrd = apple_ii_64k[0];
|
|
||||||
base_hgrwrt= apple_ii_64k[0];
|
|
||||||
|
|
||||||
base_c3rom = apple_ii_64k[1]; /* c3rom internal */
|
|
||||||
base_c4rom = apple_ii_64k[1]; /* c4rom internal */
|
|
||||||
base_c5rom = apple_ii_64k[1]; /* c5rom internal */
|
|
||||||
base_cxrom = apple_ii_64k[0]; /* cxrom peripheral */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
void c_initialize_vm()
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
void c_initialize_vm() {
|
|
||||||
c_initialize_font(); /* font already read in */
|
|
||||||
c_initialize_apple_ii_memory(); /* read in rom memory */
|
|
||||||
c_initialize_tables(); /* read/write memory jump tables */
|
|
||||||
c_initialize_sound_hooks(); /* sound system */
|
|
||||||
c_init_6(); /* drive ][, slot 6 */
|
|
||||||
c_initialize_iie_switches(); /* set the //e softswitches */
|
|
||||||
c_joystick_reset(); /* reset joystick */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !TESTING && !defined(__APPLE__) && !defined(ANDROID)
|
|
||||||
extern void *cpu_thread(void *dummyptr);
|
|
||||||
|
|
||||||
static void _shutdown_threads(void) {
|
static void _shutdown_threads(void) {
|
||||||
|
#if !TESTING
|
||||||
LOG("Emulator waiting for other threads to clean up...");
|
LOG("Emulator waiting for other threads to clean up...");
|
||||||
#if !__linux__
|
# if !__linux__
|
||||||
#warning FIXME TODO ideally we have a more deterministic thread waiting routine ...
|
# error FIXME TODO on Darwin ...
|
||||||
sleep(2); // =P
|
# else
|
||||||
#else
|
|
||||||
do {
|
do {
|
||||||
DIR *dir = opendir("/proc/self/task");
|
DIR *dir = opendir("/proc/self/task");
|
||||||
if (!dir) {
|
if (!dir) {
|
||||||
@ -603,29 +71,33 @@ static void _shutdown_threads(void) {
|
|||||||
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
|
static struct timespec ts = { .tv_sec=0, .tv_nsec=33333333 };
|
||||||
nanosleep(&ts, NULL); // 30Hz framerate
|
nanosleep(&ts, NULL); // 30Hz framerate
|
||||||
} while (1);
|
} while (1);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emulator_start(void) {
|
||||||
|
#ifdef INTERFACE_CLASSIC
|
||||||
|
load_settings(); // user prefs
|
||||||
|
c_keys_set_key(kF8); // show credits before emulation start
|
||||||
|
#endif
|
||||||
|
timing_startCPU();
|
||||||
|
video_main_loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void emulator_shutdown(void) {
|
||||||
|
video_shutdown();
|
||||||
|
timing_stopCPU();
|
||||||
|
_shutdown_threads();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !TESTING && !defined(__APPLE__) && !defined(ANDROID)
|
||||||
int main(int _argc, char **_argv) {
|
int main(int _argc, char **_argv) {
|
||||||
argc = _argc;
|
argc = _argc;
|
||||||
argv = _argv;
|
argv = _argv;
|
||||||
|
|
||||||
load_settings(); // user prefs
|
emulator_start();
|
||||||
#ifdef INTERFACE_CLASSIC
|
|
||||||
c_keys_set_key(kF8); // show credits before emulation start
|
|
||||||
#endif
|
|
||||||
|
|
||||||
timing_startCPU();
|
|
||||||
video_main_loop();
|
video_main_loop();
|
||||||
|
emulator_shutdown();
|
||||||
assert(emulator_shutting_down && "emulator is properly shutting down");
|
|
||||||
|
|
||||||
LOG("Emulator waiting for CPU thread clean up...");
|
|
||||||
if (pthread_join(cpu_thread_id, NULL)) {
|
|
||||||
ERRLOG("OOPS: pthread_join of CPU thread ...");
|
|
||||||
}
|
|
||||||
|
|
||||||
_shutdown_threads();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
211
src/misc.h
211
src/misc.h
@ -14,211 +14,20 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MISC_H
|
#ifndef _MISC_H_
|
||||||
#define MISC_H
|
#define _MISC_H_
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
|
||||||
|
|
||||||
|
// top installation directory
|
||||||
extern const char *data_dir;
|
extern const char *data_dir;
|
||||||
|
|
||||||
/* Text characters */
|
// global ref to CLI args
|
||||||
extern const unsigned char ucase_glyphs[0x200];
|
extern char **argv;
|
||||||
extern const unsigned char lcase_glyphs[0x100];
|
extern int argc;
|
||||||
extern const unsigned char mousetext_glyphs[0x100];
|
|
||||||
extern const unsigned char interface_glyphs[88];
|
|
||||||
|
|
||||||
uint8_t apple_ii_64k[2][65536]; /* 128k memory */
|
// start emulator (CPU, audio, and video)
|
||||||
|
void emulator_start(void);
|
||||||
|
|
||||||
/* language card memory and settings */
|
// shutdown emulator in preparation for app exit
|
||||||
uint8_t language_card[2][8192], language_banks[2][8192];
|
void emulator_shutdown(void);
|
||||||
|
|
||||||
/* global ref to commandline args */
|
|
||||||
char **argv;
|
|
||||||
int argc;
|
|
||||||
|
|
||||||
extern uint8_t *base_ramrd;
|
|
||||||
extern uint8_t *base_ramwrt;
|
|
||||||
extern uint8_t *base_textrd;
|
|
||||||
extern uint8_t *base_textwrt;
|
|
||||||
extern uint8_t *base_hgrrd;
|
|
||||||
extern uint8_t *base_hgrwrt;
|
|
||||||
|
|
||||||
extern uint8_t *base_stackzp;
|
|
||||||
extern uint8_t *base_d000_rd;
|
|
||||||
extern uint8_t *base_e000_rd;
|
|
||||||
extern uint8_t *base_d000_wrt;
|
|
||||||
extern uint8_t *base_e000_wrt;
|
|
||||||
|
|
||||||
extern uint8_t *base_c3rom;
|
|
||||||
extern uint8_t *base_c4rom; // points to function or memory vector
|
|
||||||
extern uint8_t *base_c5rom; // points to function or memory vector
|
|
||||||
extern uint8_t *base_cxrom;
|
|
||||||
|
|
||||||
/* softswitches */
|
|
||||||
|
|
||||||
extern uint32_t softswitches;
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLER__ */
|
|
||||||
|
|
||||||
#define SS_TEXT 0x00000001
|
|
||||||
#define SS_MIXED 0x00000002
|
|
||||||
#define SS_HIRES 0x00000004
|
|
||||||
#define SS_PAGE2 0x00000008
|
|
||||||
#define SS_BANK2 0x00000010
|
|
||||||
#define SS_LCRAM 0x00000020
|
|
||||||
#define SS_LCSEC 0x00000040 /* Pseudo-softswitch : enabled if 2+ reads have occurred */
|
|
||||||
#define SS_LCWRT 0x00000080 /* Pseudo-softswitch : LC write enable */
|
|
||||||
#define SS_80STORE 0x00000100
|
|
||||||
#define SS_80COL 0x00000200
|
|
||||||
#define SS_RAMRD 0x00000400
|
|
||||||
#define SS_RAMWRT 0x00000800
|
|
||||||
#define SS_ALTZP 0x00001000
|
|
||||||
#define SS_DHIRES 0x00002000
|
|
||||||
#define SS_IOUDIS 0x00004000
|
|
||||||
#define SS_CXROM 0x00008000
|
|
||||||
#define SS_C3ROM 0x00010000
|
|
||||||
#define SS_ALTCHAR 0x00020000
|
|
||||||
|
|
||||||
/* Pseudo soft switches. These are actually functions of other SSes, but are
|
|
||||||
* tiresome to calculate as needed.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define SS_SCREEN 0x00040000 /* PAGE2 && !80STORE */
|
|
||||||
#define SS_TEXTRD 0x00080000 /* (PAGE2 && 80STORE) ||
|
|
||||||
(RAMRD && !80STORE) */
|
|
||||||
#define SS_TEXTWRT 0x00100000 /* (PAGE2 && 80STORE) ||
|
|
||||||
(RAMWRT && !80STORE) */
|
|
||||||
#define SS_HGRRD 0x00200000 /* (PAGE2 && 80STORE && HIRES) ||
|
|
||||||
(RAMRD && !(80STORE && HIRES) */
|
|
||||||
#define SS_HGRWRT 0x00400000 /* (PAGE2 && 80STORE && HIRES) ||
|
|
||||||
(RAMWRT && !(80STORE && HIRES)) */
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
misc.c functions
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
extern bool emulator_shutting_down;
|
|
||||||
|
|
||||||
void c_initialize_sound_hooks();
|
|
||||||
void c_disable_sound_hooks();
|
|
||||||
void c_set_primary_char();
|
|
||||||
void c_set_altchar();
|
|
||||||
void c_initialize_font();
|
|
||||||
void c_initialize_vm();
|
|
||||||
|
|
||||||
/* vm hooks */
|
|
||||||
|
|
||||||
#if VM_TRACING
|
|
||||||
void vm_trace_begin(const char *vm_file);
|
|
||||||
void vm_trace_end(void);
|
|
||||||
void vm_trace_toggle(const char *vm_file);
|
|
||||||
bool vm_trace_is_ignored(uint16_t ea);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ram_nop(),
|
|
||||||
|
|
||||||
write_unmapped_softswitch(),
|
|
||||||
|
|
||||||
read_rand(),
|
|
||||||
read_unmapped_softswitch(),
|
|
||||||
read_keyboard(),
|
|
||||||
read_keyboard_strobe(),
|
|
||||||
speaker_toggle(),
|
|
||||||
read_switch_graphics(),
|
|
||||||
read_switch_text(),
|
|
||||||
read_switch_no_mixed(),
|
|
||||||
read_switch_mixed(),
|
|
||||||
|
|
||||||
read_button0(),
|
|
||||||
read_button1(),
|
|
||||||
read_button2(),
|
|
||||||
read_gc0(),
|
|
||||||
read_gc1(),
|
|
||||||
read_gc_strobe(),
|
|
||||||
|
|
||||||
lc_c082(),
|
|
||||||
lc_c08a(),
|
|
||||||
write_ram_bank(),
|
|
||||||
read_ram_bank(),
|
|
||||||
write_ram_lc(),
|
|
||||||
read_ram_lc();
|
|
||||||
|
|
||||||
void iie_write_ram_default(),
|
|
||||||
iie_read_ram_default(),
|
|
||||||
|
|
||||||
/* //e text pages */
|
|
||||||
iie_read_ram_text_page0(),
|
|
||||||
iie_write_screen_hole_text_page0(),
|
|
||||||
|
|
||||||
/* //e hires page 0 */
|
|
||||||
iie_read_ram_hires_page0(),
|
|
||||||
iie_write_screen_hole_hires_page0(),
|
|
||||||
|
|
||||||
/* //e zpage,stack, ram banks */
|
|
||||||
iie_read_ram_zpage_and_stack(),
|
|
||||||
iie_write_ram_zpage_and_stack(),
|
|
||||||
iie_read_slot3(),
|
|
||||||
iie_read_slot4(),
|
|
||||||
iie_read_slot5(),
|
|
||||||
iie_read_slotx(),
|
|
||||||
iie_read_slot_expansion(),
|
|
||||||
iie_disable_slot_expansion(),
|
|
||||||
iie_read_gc2(),
|
|
||||||
iie_read_gc3(),
|
|
||||||
|
|
||||||
iie_c080(),
|
|
||||||
iie_c081(),
|
|
||||||
iie_c083(),
|
|
||||||
iie_c088(),
|
|
||||||
iie_c089(),
|
|
||||||
iie_c08b(),
|
|
||||||
|
|
||||||
/* //e toggle softswitches */
|
|
||||||
iie_ramrd_main(),
|
|
||||||
iie_ramrd_aux(),
|
|
||||||
iie_ramwrt_main(),
|
|
||||||
iie_ramwrt_aux(),
|
|
||||||
iie_80store_off(),
|
|
||||||
iie_80store_on(),
|
|
||||||
iie_altzp_main(),
|
|
||||||
iie_altzp_aux(),
|
|
||||||
iie_80col_off(),
|
|
||||||
iie_80col_on(),
|
|
||||||
iie_altchar_off(),
|
|
||||||
iie_altchar_on(),
|
|
||||||
iie_c3rom_peripheral(),
|
|
||||||
iie_c3rom_internal(),
|
|
||||||
iie_cxrom_peripheral(),
|
|
||||||
iie_cxrom_internal(),
|
|
||||||
iie_ioudis_on(),
|
|
||||||
iie_ioudis_off(),
|
|
||||||
iie_annunciator(),
|
|
||||||
iie_dhires_on(),
|
|
||||||
iie_dhires_off(),
|
|
||||||
iie_hires_off(),
|
|
||||||
iie_hires_on(),
|
|
||||||
iie_page2_on(),
|
|
||||||
iie_page2_off(),
|
|
||||||
|
|
||||||
/* //e check softswitche settings */
|
|
||||||
iie_check_80store(),
|
|
||||||
iie_check_bank(),
|
|
||||||
iie_check_lcram(),
|
|
||||||
iie_check_ramrd(),
|
|
||||||
iie_check_ramwrt(),
|
|
||||||
iie_check_altzp(),
|
|
||||||
iie_check_c3rom(),
|
|
||||||
iie_check_cxrom(),
|
|
||||||
iie_check_80col(),
|
|
||||||
iie_check_altchar(),
|
|
||||||
iie_check_text(),
|
|
||||||
iie_check_mixed(),
|
|
||||||
iie_check_hires(),
|
|
||||||
iie_check_page2(),
|
|
||||||
iie_check_ioudis(),
|
|
||||||
iie_check_dhires(),
|
|
||||||
iie_check_vbl();
|
|
||||||
#endif /* !__ASSEMBLER__ */
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
17
src/timing.c
17
src/timing.c
@ -87,6 +87,7 @@ bool emul_reinitialize_audio = true;
|
|||||||
#if MOBILE_DEVICE
|
#if MOBILE_DEVICE
|
||||||
static bool emul_reinitialize_background = true;
|
static bool emul_reinitialize_background = true;
|
||||||
#endif
|
#endif
|
||||||
|
static bool cpu_shutting_down = false;
|
||||||
pthread_t cpu_thread_id = 0;
|
pthread_t cpu_thread_id = 0;
|
||||||
pthread_mutex_t interface_mutex = { 0 };
|
pthread_mutex_t interface_mutex = { 0 };
|
||||||
pthread_cond_t dbg_thread_cond = PTHREAD_COND_INITIALIZER;
|
pthread_cond_t dbg_thread_cond = PTHREAD_COND_INITIALIZER;
|
||||||
@ -169,7 +170,7 @@ void reinitialize(void) {
|
|||||||
|
|
||||||
cycles_count_total = 0;
|
cycles_count_total = 0;
|
||||||
|
|
||||||
c_initialize_vm();
|
vm_initialize();
|
||||||
|
|
||||||
softswitches = SS_TEXT | SS_IOUDIS | SS_C3ROM | SS_LCWRT | SS_LCSEC;
|
softswitches = SS_TEXT | SS_IOUDIS | SS_C3ROM | SS_LCWRT | SS_LCSEC;
|
||||||
|
|
||||||
@ -542,12 +543,12 @@ static void *cpu_thread(void *dummyptr) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (UNLIKELY(emulator_shutting_down)) {
|
if (UNLIKELY(cpu_shutting_down)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
if (UNLIKELY(emulator_shutting_down)) {
|
if (UNLIKELY(cpu_shutting_down)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (1);
|
} while (1);
|
||||||
@ -562,10 +563,20 @@ static void *cpu_thread(void *dummyptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void timing_startCPU(void) {
|
void timing_startCPU(void) {
|
||||||
|
cpu_shutting_down = false;
|
||||||
video_init();
|
video_init();
|
||||||
pthread_create(&cpu_thread_id, NULL, (void *)&cpu_thread, (void *)NULL);
|
pthread_create(&cpu_thread_id, NULL, (void *)&cpu_thread, (void *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void timing_stopCPU(void) {
|
||||||
|
cpu_shutting_down = true;
|
||||||
|
|
||||||
|
LOG("Emulator waiting for CPU thread clean up...");
|
||||||
|
if (pthread_join(cpu_thread_id, NULL)) {
|
||||||
|
ERRLOG("OOPS: pthread_join of CPU thread ...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int CpuGetCyclesThisVideoFrame(void) {
|
unsigned int CpuGetCyclesThisVideoFrame(void) {
|
||||||
timing_checkpoint_cycles();
|
timing_checkpoint_cycles();
|
||||||
return g_dwCyclesThisFrame + cycles_checkpoint_count;
|
return g_dwCyclesThisFrame + cycles_checkpoint_count;
|
||||||
|
@ -70,10 +70,15 @@ extern READONLY pthread_t cpu_thread_id;
|
|||||||
struct timespec timespec_diff(struct timespec start, struct timespec end, bool *negative);
|
struct timespec timespec_diff(struct timespec start, struct timespec end, bool *negative);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start CPU thread
|
* start CPU thread
|
||||||
*/
|
*/
|
||||||
void timing_startCPU(void);
|
void timing_startCPU(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* stop CPU thread
|
||||||
|
*/
|
||||||
|
void timing_stopCPU(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* toggles CPU speed between configured values
|
* toggles CPU speed between configured values
|
||||||
*/
|
*/
|
||||||
|
@ -631,15 +631,9 @@ static void _gldriver_shutdown(void) {
|
|||||||
static void gldriver_shutdown(void) {
|
static void gldriver_shutdown(void) {
|
||||||
#if USE_GLUT
|
#if USE_GLUT
|
||||||
glutLeaveMainLoop();
|
glutLeaveMainLoop();
|
||||||
#else
|
#endif
|
||||||
# if MOBILE_DEVICE
|
|
||||||
renderer_shutting_down = true;
|
renderer_shutting_down = true;
|
||||||
_gldriver_shutdown();
|
_gldriver_shutdown();
|
||||||
# else
|
|
||||||
# error this codepath untested ...
|
|
||||||
emulator_shutting_down = true;
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -677,11 +671,9 @@ static void gldriver_render(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MOBILE_DEVICE
|
|
||||||
if (UNLIKELY(renderer_shutting_down)) {
|
if (UNLIKELY(renderer_shutting_down)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
#if MOBILE_DEVICE
|
#if MOBILE_DEVICE
|
||||||
@ -893,8 +885,6 @@ static void gldriver_main_loop(void) {
|
|||||||
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
|
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
|
||||||
glutMainLoop();
|
glutMainLoop();
|
||||||
LOG("GLUT main loop finished...");
|
LOG("GLUT main loop finished...");
|
||||||
emulator_shutting_down = true;
|
|
||||||
_gldriver_shutdown();
|
|
||||||
#endif
|
#endif
|
||||||
// fall through if not GLUT
|
// fall through if not GLUT
|
||||||
}
|
}
|
||||||
|
@ -283,5 +283,13 @@ extern uint8_t *video__fb2;
|
|||||||
*/
|
*/
|
||||||
extern READONLY int video__current_page;
|
extern READONLY int video__current_page;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* font glyph data
|
||||||
|
*/
|
||||||
|
extern const unsigned char ucase_glyphs[0x200];
|
||||||
|
extern const unsigned char lcase_glyphs[0x100];
|
||||||
|
extern const unsigned char mousetext_glyphs[0x100];
|
||||||
|
extern const unsigned char interface_glyphs[88];
|
||||||
|
|
||||||
#endif /* !A2_VIDEO_H */
|
#endif /* !A2_VIDEO_H */
|
||||||
|
|
||||||
|
478
src/vm.c
478
src/vm.c
@ -9,110 +9,35 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
Apple //e 64K VM
|
|
||||||
|
|
||||||
(Two byte addresses are represented with least significant
|
|
||||||
byte first, e.g. address FA59 is represented as 59 FA)
|
|
||||||
|
|
||||||
This is not meant to be definitive.
|
|
||||||
Verify against _Understanding the Apple IIe_ by Jim Sather
|
|
||||||
|
|
||||||
Address Description
|
|
||||||
----------- -----------
|
|
||||||
0000 - 00FF Zero page RAM
|
|
||||||
0100 - 01FF Stack
|
|
||||||
0200 - 03EF RAM
|
|
||||||
03F0 - 03F1 Address for BRK instruction (normally 59 FA = FA59)
|
|
||||||
03F2 - 03F3 Soft entry vector (normally BF 9D = 9DBF)
|
|
||||||
03F4 Power-up byte
|
|
||||||
03F5 - 03F7 Jump instruction to the subroutine which handles
|
|
||||||
Applesoft II &-commands (normally 4C 58 FF = JMP FF58)
|
|
||||||
03F8 - 03FA Jump instruction to the subroutine which handles User
|
|
||||||
CTRL-Y commands (normally 4C 65 FF = JMP FF65)
|
|
||||||
03FB - 03FD Jump instruction to the subroutine which handles
|
|
||||||
Non-Maskable Interrupts (NMI) (normally 4C 65 FF = JMP FF65)
|
|
||||||
03FE - 03FF Address of the subroutine which handles Interrupt
|
|
||||||
ReQuests (IRQ) (normally 65 FF = FF65)
|
|
||||||
0400 - 07FF Basically primary video text page
|
|
||||||
0478 - 047F I/O Scratchpad RAM Addresses for Slot 0 - 7
|
|
||||||
04F8 - 04FF - " " -
|
|
||||||
0578 - 057F - " " -
|
|
||||||
05F8 - 05FF - " " -
|
|
||||||
0678 - 067F - " " -
|
|
||||||
06F8 - 06FF - " " -
|
|
||||||
0778 - 077F - " " -
|
|
||||||
07F8 - 07FF - " " -
|
|
||||||
05F8 Holds the slot number of the disk controller card from
|
|
||||||
which DOS was booted. ??? VERIFY...
|
|
||||||
07F8 Holds the slot number (CX, X = Slot #) of the slot that
|
|
||||||
is currently active. ??? VERIFY...
|
|
||||||
0800 - 0BFF Secondary video text page
|
|
||||||
0C00 - 1FFF Plain RAM
|
|
||||||
2000 - 3FFF Primary video hires page (RAM)
|
|
||||||
4000 - 5FFF Secondary video hires page (RAM)
|
|
||||||
6000 - BFFF Plain RAM (Normally the OS is loaded into ~9C00 - BFFF)
|
|
||||||
C000 - C00F Keyboard data (C00X contains the character ASCII code of
|
|
||||||
the pressed key. The value is available at any C00X address)
|
|
||||||
C010 - C01F Clear Keyboard strobe
|
|
||||||
C020 - C02F Cassette output toggle
|
|
||||||
C030 - C03F Speaker toggle
|
|
||||||
C040 - C04F Utility strobe
|
|
||||||
C050 Set graphics mode
|
|
||||||
C051 Set text mode
|
|
||||||
C052 Set all text or graphics
|
|
||||||
C053 Mix text and graphics
|
|
||||||
C054 Display primary page
|
|
||||||
C055 Display secondary page
|
|
||||||
C056 Display low-res graphics
|
|
||||||
C057 Display hi-res graphics
|
|
||||||
C058 - C05F Annunciator outputs
|
|
||||||
C060 Cassette input
|
|
||||||
C061 - C063 Pushbutton inputs (button 1, 2 and 3)
|
|
||||||
C064 - C067 Game controller inputs
|
|
||||||
C068 - C06F Same as C060 - C067
|
|
||||||
C070 - C07F Game controller strobe
|
|
||||||
C080 - C08F Slot 0 I/O space (usually a language card)
|
|
||||||
C080 Reset language card
|
|
||||||
* Read enabled
|
|
||||||
* Write disabled
|
|
||||||
* Read from language card
|
|
||||||
C081 --- First access
|
|
||||||
* Read mode disabled
|
|
||||||
* Read from ROM
|
|
||||||
--- On second+ access
|
|
||||||
* Write mode enabled
|
|
||||||
* Write to language card
|
|
||||||
C082 --- (Disable language card)
|
|
||||||
* Read mode disabled
|
|
||||||
* Write mode disabled
|
|
||||||
* Read from ROM
|
|
||||||
C083 --- First access
|
|
||||||
* Read mode enabled
|
|
||||||
* Read from language card
|
|
||||||
--- On second+ access
|
|
||||||
* Write mode enabled
|
|
||||||
* Write to language card
|
|
||||||
C088 - C08B Same as C080 - C083, but switch to second bank, i.e.
|
|
||||||
map addresses D000-DFFF to other 4K area.
|
|
||||||
C100 - C1FF Slot 1 PROM
|
|
||||||
C200 - C2FF Slot 2 PROM
|
|
||||||
C300 - C3FF Slot 3 PROM
|
|
||||||
C400 - C4FF Slot 4 PROM
|
|
||||||
C500 - C5FF Slot 5 PROM
|
|
||||||
C600 - C6FF Slot 6 PROM
|
|
||||||
C700 - C7FF Slot 7 PROM
|
|
||||||
C800 - CFFF Expansion ROM (for peripheral cards)
|
|
||||||
CFFF Disable access to expansion ROM for
|
|
||||||
ALL peripheral cards.
|
|
||||||
D000 - DFFF ROM or 4K RAM if language card is enabled. However,
|
|
||||||
there are TWO 4K banks that can be mapped onto addresses
|
|
||||||
D000 - DFFF. See C088 - C08B.
|
|
||||||
E000 - FFFF ROM or 8K RAM if language card is enabled.
|
|
||||||
---------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
extern const uint8_t apple_iie_rom[32768]; // rom.c
|
||||||
|
|
||||||
|
uint8_t apple_ii_64k[2][65536] = { { 0 } };
|
||||||
|
uint8_t language_card[2][8192] = { { 0 } };
|
||||||
|
uint8_t language_banks[2][8192] = { { 0 } };
|
||||||
|
|
||||||
|
uint32_t softswitches = 0x0;
|
||||||
|
|
||||||
|
const uint8_t *base_vmem = apple_ii_64k[0];
|
||||||
|
uint8_t *base_ramrd = NULL;
|
||||||
|
uint8_t *base_ramwrt = NULL;
|
||||||
|
uint8_t *base_textrd = NULL;
|
||||||
|
uint8_t *base_textwrt = NULL;
|
||||||
|
uint8_t *base_hgrrd = NULL;
|
||||||
|
uint8_t *base_hgrwrt = NULL;
|
||||||
|
|
||||||
|
uint8_t *base_stackzp = NULL;
|
||||||
|
uint8_t *base_d000_rd = NULL;
|
||||||
|
uint8_t *base_e000_rd = NULL;
|
||||||
|
uint8_t *base_d000_wrt = NULL;
|
||||||
|
uint8_t *base_e000_wrt = NULL;
|
||||||
|
|
||||||
|
uint8_t *base_c3rom = NULL;
|
||||||
|
uint8_t *base_c4rom = NULL;
|
||||||
|
uint8_t *base_c5rom = NULL;
|
||||||
|
uint8_t *base_cxrom = NULL;
|
||||||
|
|
||||||
// joystick timer values
|
// joystick timer values
|
||||||
int gc_cycles_timer_0 = 0;
|
int gc_cycles_timer_0 = 0;
|
||||||
int gc_cycles_timer_1 = 0;
|
int gc_cycles_timer_1 = 0;
|
||||||
@ -126,6 +51,33 @@ typedef struct vm_trace_range_t {
|
|||||||
} vm_trace_range_t;
|
} vm_trace_range_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
GLUE_BANK_READ(iie_read_ram_default,base_ramrd);
|
||||||
|
GLUE_BANK_WRITE(iie_write_ram_default,base_ramwrt);
|
||||||
|
|
||||||
|
GLUE_BANK_READ(read_ram_bank,base_d000_rd);
|
||||||
|
GLUE_BANK_MAYBEWRITE(write_ram_bank,base_d000_wrt);
|
||||||
|
|
||||||
|
GLUE_BANK_READ(read_ram_lc,base_e000_rd);
|
||||||
|
GLUE_BANK_MAYBEWRITE(write_ram_lc,base_e000_wrt);
|
||||||
|
|
||||||
|
GLUE_BANK_READ(iie_read_ram_text_page0,base_textrd);
|
||||||
|
GLUE_BANK_WRITE(iie_write_screen_hole_text_page0,base_textwrt);
|
||||||
|
|
||||||
|
GLUE_BANK_READ(iie_read_ram_hires_page0,base_hgrrd);
|
||||||
|
GLUE_BANK_WRITE(iie_write_screen_hole_hires_page0,base_hgrwrt);
|
||||||
|
|
||||||
|
GLUE_BANK_READ(iie_read_ram_zpage_and_stack,base_stackzp);
|
||||||
|
GLUE_BANK_WRITE(iie_write_ram_zpage_and_stack,base_stackzp);
|
||||||
|
|
||||||
|
GLUE_BANK_READ(iie_read_slot3,base_c3rom);
|
||||||
|
GLUE_BANK_MAYBEREAD(iie_read_slot4,base_c4rom);
|
||||||
|
GLUE_BANK_MAYBEREAD(iie_read_slot5,base_c5rom);
|
||||||
|
GLUE_BANK_READ(iie_read_slotx,base_cxrom);
|
||||||
|
|
||||||
|
GLUE_EXTERN_C_READ(speaker_toggle);
|
||||||
|
|
||||||
GLUE_C_READ(ram_nop)
|
GLUE_C_READ(ram_nop)
|
||||||
{
|
{
|
||||||
return (cpu65_rw&MEM_WRITE_FLAG) ? 0x0 : floating_bus();
|
return (cpu65_rw&MEM_WRITE_FLAG) ? 0x0 : floating_bus();
|
||||||
@ -818,7 +770,8 @@ GLUE_C_READ(iie_altchar_off)
|
|||||||
{
|
{
|
||||||
if (softswitches & SS_ALTCHAR) {
|
if (softswitches & SS_ALTCHAR) {
|
||||||
softswitches &= ~SS_ALTCHAR;
|
softswitches &= ~SS_ALTCHAR;
|
||||||
c_set_primary_char();
|
video_loadfont(0x40,0x40,ucase_glyphs,3);
|
||||||
|
video_redraw();
|
||||||
}
|
}
|
||||||
return floating_bus();
|
return floating_bus();
|
||||||
}
|
}
|
||||||
@ -827,7 +780,9 @@ GLUE_C_READ(iie_altchar_on)
|
|||||||
{
|
{
|
||||||
if (!(softswitches & SS_ALTCHAR)) {
|
if (!(softswitches & SS_ALTCHAR)) {
|
||||||
softswitches |= SS_ALTCHAR;
|
softswitches |= SS_ALTCHAR;
|
||||||
c_set_altchar();
|
video_loadfont(0x40,0x20,mousetext_glyphs,1);
|
||||||
|
video_loadfont(0x60,0x20,lcase_glyphs,2);
|
||||||
|
video_redraw();
|
||||||
}
|
}
|
||||||
return floating_bus();
|
return floating_bus();
|
||||||
}
|
}
|
||||||
@ -953,8 +908,323 @@ GLUE_C_READ(iie_read_slot_expansion)
|
|||||||
return apple_ii_64k[1][ea];
|
return apple_ii_64k[1][ea];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLUE_C_READ(debug_illegal_bcd)
|
||||||
|
{
|
||||||
|
RELEASE_LOG("Illegal/undefined BCD operation encountered, debug break on c_debug_illegal_bcd to debug...");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void _initialize_iie_switches(void) {
|
||||||
|
|
||||||
|
base_stackzp = apple_ii_64k[0];
|
||||||
|
base_d000_rd = apple_ii_64k[0];
|
||||||
|
base_d000_wrt = language_banks[0] - 0xD000;
|
||||||
|
base_e000_rd = apple_ii_64k[0];
|
||||||
|
base_e000_wrt = language_card[0] - 0xE000;
|
||||||
|
|
||||||
|
base_ramrd = apple_ii_64k[0];
|
||||||
|
base_ramwrt = apple_ii_64k[0];
|
||||||
|
base_textrd = apple_ii_64k[0];
|
||||||
|
base_textwrt = apple_ii_64k[0];
|
||||||
|
base_hgrrd = apple_ii_64k[0];
|
||||||
|
base_hgrwrt= apple_ii_64k[0];
|
||||||
|
|
||||||
|
base_c3rom = apple_ii_64k[1]; // c3rom internal
|
||||||
|
base_c4rom = apple_ii_64k[1]; // c4rom internal
|
||||||
|
base_c5rom = apple_ii_64k[1]; // c5rom internal
|
||||||
|
base_cxrom = apple_ii_64k[0]; // cxrom peripheral
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _initialize_font(void) {
|
||||||
|
video_loadfont(0x00,0x40,ucase_glyphs,2);
|
||||||
|
video_loadfont(0x40,0x40,ucase_glyphs,3);
|
||||||
|
video_loadfont(0x80,0x40,ucase_glyphs,0);
|
||||||
|
video_loadfont(0xC0,0x20,ucase_glyphs,0);
|
||||||
|
video_loadfont(0xE0,0x20,lcase_glyphs,0);
|
||||||
|
video_redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _initialize_apple_ii_memory(void) {
|
||||||
|
for (unsigned int i = 0; i < 0x10000; i++) {
|
||||||
|
apple_ii_64k[0][i] = 0;
|
||||||
|
apple_ii_64k[1][i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stripe words of main memory on machine reset ...
|
||||||
|
// NOTE: cracked version of J---- will lock up without this
|
||||||
|
for (unsigned int i = 0; i < 0xC000;) {
|
||||||
|
apple_ii_64k[0][i++] = 0xFF;
|
||||||
|
apple_ii_64k[0][i++] = 0xFF;
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 8192; i++) {
|
||||||
|
language_card[0][i] = language_card[1][i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 8192; i++) {
|
||||||
|
language_banks[0][i] = language_banks[1][i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the rom from 0xC000, slot rom main, internal rom aux
|
||||||
|
|
||||||
|
for (unsigned int i = 0xC000; i < 0x10000; i++) {
|
||||||
|
apple_ii_64k[0][i] = apple_iie_rom[i - 0xC000];
|
||||||
|
apple_ii_64k[1][i] = apple_iie_rom[i - 0x8000];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 0x1000; i++) {
|
||||||
|
language_banks[0][i] = apple_iie_rom[i + 0x1000];
|
||||||
|
language_banks[1][i] = apple_iie_rom[i + 0x5000];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 0x2000; i++) {
|
||||||
|
language_card[0][i] = apple_iie_rom[i + 0x2000];
|
||||||
|
language_card[1][i] = apple_iie_rom[i + 0x6000];
|
||||||
|
}
|
||||||
|
|
||||||
|
apple_ii_64k[0][0xC000] = 0x00;
|
||||||
|
apple_ii_64k[1][0xC000] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _initialize_tables(void) {
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 0x10000; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_ram_default;
|
||||||
|
cpu65_vmem_w[i] = iie_write_ram_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
// language card read/write area
|
||||||
|
|
||||||
|
for (unsigned int i = 0xD000; i < 0xE000; i++) {
|
||||||
|
cpu65_vmem_w[i] = write_ram_bank;
|
||||||
|
cpu65_vmem_r[i] = read_ram_bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0xE000; i < 0x10000; i++) {
|
||||||
|
cpu65_vmem_w[i] = write_ram_lc;
|
||||||
|
cpu65_vmem_r[i] = read_ram_lc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// done common initialization
|
||||||
|
|
||||||
|
// initialize zero-page, //e specific
|
||||||
|
for (unsigned int i = 0; i < 0x200; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_ram_zpage_and_stack;
|
||||||
|
cpu65_vmem_w[i] = iie_write_ram_zpage_and_stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize first text & hires page, which are specially bank switched
|
||||||
|
//
|
||||||
|
// video_reset() below substitutes it's own hooks for all visible write locations affect the display, leaving our
|
||||||
|
// write-functions in place only at the `screen holes', hence the name.
|
||||||
|
for (unsigned int i = 0x400; i < 0x800; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_ram_text_page0;
|
||||||
|
cpu65_vmem_w[i] = iie_write_screen_hole_text_page0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0x2000; i < 0x4000; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_ram_hires_page0;
|
||||||
|
cpu65_vmem_w[i] = iie_write_screen_hole_hires_page0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// softswich rom
|
||||||
|
for (unsigned int i = 0xC000; i < 0xC100; i++) {
|
||||||
|
cpu65_vmem_r[i] = read_unmapped_softswitch;
|
||||||
|
cpu65_vmem_w[i] = write_unmapped_softswitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
// slot rom defaults
|
||||||
|
for (unsigned int i = 0xC100; i < 0xD000; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_ram_default;
|
||||||
|
cpu65_vmem_w[i] = ram_nop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// keyboard data and strobe (READ)
|
||||||
|
for (unsigned int i = 0xC000; i < 0xC010; i++) {
|
||||||
|
cpu65_vmem_r[i] = read_keyboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0xC010; i < 0xC020; i++) {
|
||||||
|
cpu65_vmem_r[i] = cpu65_vmem_w[i] = read_keyboard_strobe;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RDBNK2 switch
|
||||||
|
cpu65_vmem_r[0xC011] = iie_check_bank;
|
||||||
|
|
||||||
|
// RDLCRAM switch
|
||||||
|
cpu65_vmem_r[0xC012] = iie_check_lcram;
|
||||||
|
|
||||||
|
// 80STORE switch
|
||||||
|
cpu65_vmem_w[0xC000] = iie_80store_off;
|
||||||
|
cpu65_vmem_w[0xC001] = iie_80store_on;
|
||||||
|
cpu65_vmem_r[0xC018] = iie_check_80store;
|
||||||
|
|
||||||
|
// RAMRD switch
|
||||||
|
cpu65_vmem_w[0xC002] = iie_ramrd_main;
|
||||||
|
cpu65_vmem_w[0xC003] = iie_ramrd_aux;
|
||||||
|
cpu65_vmem_r[0xC013] = iie_check_ramrd;
|
||||||
|
|
||||||
|
// RAMWRT switch
|
||||||
|
cpu65_vmem_w[0xC004] = iie_ramwrt_main;
|
||||||
|
cpu65_vmem_w[0xC005] = iie_ramwrt_aux;
|
||||||
|
cpu65_vmem_r[0xC014] = iie_check_ramwrt;
|
||||||
|
|
||||||
|
// ALTZP switch
|
||||||
|
cpu65_vmem_w[0xC008] = iie_altzp_main;
|
||||||
|
cpu65_vmem_w[0xC009] = iie_altzp_aux;
|
||||||
|
cpu65_vmem_r[0xC016] = iie_check_altzp;
|
||||||
|
|
||||||
|
// 80COL switch
|
||||||
|
cpu65_vmem_w[0xC00C] = iie_80col_off;
|
||||||
|
cpu65_vmem_w[0xC00D] = iie_80col_on;
|
||||||
|
cpu65_vmem_r[0xC01F] = iie_check_80col;
|
||||||
|
|
||||||
|
// ALTCHAR switch
|
||||||
|
cpu65_vmem_w[0xC00E] = iie_altchar_off;
|
||||||
|
cpu65_vmem_w[0xC00F] = iie_altchar_on;
|
||||||
|
cpu65_vmem_r[0xC01E] = iie_check_altchar;
|
||||||
|
|
||||||
|
// SLOTC3ROM switch
|
||||||
|
cpu65_vmem_w[0xC00A] = iie_c3rom_internal;
|
||||||
|
cpu65_vmem_w[0xC00B] = iie_c3rom_peripheral;
|
||||||
|
cpu65_vmem_r[0xC017] = iie_check_c3rom;
|
||||||
|
|
||||||
|
// SLOTCXROM switch
|
||||||
|
cpu65_vmem_w[0xC006] = iie_cxrom_peripheral;
|
||||||
|
cpu65_vmem_w[0xC007] = iie_cxrom_internal;
|
||||||
|
cpu65_vmem_r[0xC015] = iie_check_cxrom;
|
||||||
|
|
||||||
|
// RDVBLBAR switch
|
||||||
|
cpu65_vmem_r[0xC019] = iie_check_vbl;
|
||||||
|
|
||||||
|
// TEXT switch
|
||||||
|
cpu65_vmem_r[0xC050] = cpu65_vmem_w[0xC050] = read_switch_graphics;
|
||||||
|
cpu65_vmem_r[0xC051] = cpu65_vmem_w[0xC051] = read_switch_text;
|
||||||
|
cpu65_vmem_r[0xC01A] = iie_check_text;
|
||||||
|
|
||||||
|
// MIXED switch
|
||||||
|
cpu65_vmem_r[0xC052] = cpu65_vmem_w[0xC052] = read_switch_no_mixed;
|
||||||
|
cpu65_vmem_r[0xC053] = cpu65_vmem_w[0xC053] = read_switch_mixed;
|
||||||
|
cpu65_vmem_r[0xC01B] = iie_check_mixed;
|
||||||
|
|
||||||
|
// PAGE2 switch
|
||||||
|
cpu65_vmem_r[0xC054] = cpu65_vmem_w[0xC054] = iie_page2_off;
|
||||||
|
cpu65_vmem_r[0xC01C] = iie_check_page2;
|
||||||
|
cpu65_vmem_r[0xC055] = cpu65_vmem_w[0xC055] = iie_page2_on;
|
||||||
|
|
||||||
|
// HIRES switch
|
||||||
|
cpu65_vmem_r[0xC01D] = iie_check_hires;
|
||||||
|
cpu65_vmem_r[0xC056] = cpu65_vmem_w[0xC056] = iie_hires_off;
|
||||||
|
cpu65_vmem_r[0xC057] = cpu65_vmem_w[0xC057] = iie_hires_on;
|
||||||
|
|
||||||
|
// game I/O switches
|
||||||
|
cpu65_vmem_r[0xC061] = cpu65_vmem_r[0xC069] = read_button0;
|
||||||
|
cpu65_vmem_r[0xC062] = cpu65_vmem_r[0xC06A] = read_button1;
|
||||||
|
cpu65_vmem_r[0xC063] = cpu65_vmem_r[0xC06B] = read_button2;
|
||||||
|
cpu65_vmem_r[0xC064] = cpu65_vmem_r[0xC06C] = read_gc0;
|
||||||
|
cpu65_vmem_r[0xC065] = cpu65_vmem_r[0xC06D] = read_gc1;
|
||||||
|
cpu65_vmem_r[0xC066] = iie_read_gc2;
|
||||||
|
cpu65_vmem_r[0xC067] = iie_read_gc3;
|
||||||
|
|
||||||
|
for (unsigned int i = 0xC070; i < 0xC080; i++) {
|
||||||
|
cpu65_vmem_r[i] = cpu65_vmem_w[i] = read_gc_strobe;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IOUDIS switch & read_gc_strobe
|
||||||
|
cpu65_vmem_w[0xC07E] = iie_ioudis_on;
|
||||||
|
cpu65_vmem_w[0xC07F] = iie_ioudis_off; // HACK FIXME TODO : double-check this stuff against AWin...
|
||||||
|
cpu65_vmem_r[0xC07E] = iie_check_ioudis;
|
||||||
|
cpu65_vmem_r[0xC07F] = iie_check_dhires;
|
||||||
|
|
||||||
|
// Annunciator
|
||||||
|
for (unsigned int i = 0xC058; i <= 0xC05D; i++) {
|
||||||
|
cpu65_vmem_w[i] = cpu65_vmem_r[i] = iie_annunciator;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHIRES
|
||||||
|
cpu65_vmem_w[0xC05E] = cpu65_vmem_r[0xC05E] = iie_dhires_on;
|
||||||
|
cpu65_vmem_w[0xC05F] = cpu65_vmem_r[0xC05F] = iie_dhires_off;
|
||||||
|
|
||||||
|
// language card softswitches
|
||||||
|
cpu65_vmem_r[0xC080] = cpu65_vmem_w[0xC080] = cpu65_vmem_r[0xC084] = cpu65_vmem_w[0xC084] = iie_c080;
|
||||||
|
cpu65_vmem_r[0xC081] = cpu65_vmem_w[0xC081] = cpu65_vmem_r[0xC085] = cpu65_vmem_w[0xC085] = iie_c081;
|
||||||
|
cpu65_vmem_r[0xC082] = cpu65_vmem_w[0xC082] = cpu65_vmem_r[0xC086] = cpu65_vmem_w[0xC086] = lc_c082;
|
||||||
|
cpu65_vmem_r[0xC083] = cpu65_vmem_w[0xC083] = cpu65_vmem_r[0xC087] = cpu65_vmem_w[0xC087] = iie_c083;
|
||||||
|
|
||||||
|
cpu65_vmem_r[0xC088] = cpu65_vmem_w[0xC088] = cpu65_vmem_r[0xC08C] = cpu65_vmem_w[0xC08C] = iie_c088;
|
||||||
|
cpu65_vmem_r[0xC089] = cpu65_vmem_w[0xC089] = cpu65_vmem_r[0xC08D] = cpu65_vmem_w[0xC08D] = iie_c089;
|
||||||
|
cpu65_vmem_r[0xC08A] = cpu65_vmem_w[0xC08A] = cpu65_vmem_r[0xC08E] = cpu65_vmem_w[0xC08E] = lc_c08a;
|
||||||
|
cpu65_vmem_r[0xC08B] = cpu65_vmem_w[0xC08B] = cpu65_vmem_r[0xC08F] = cpu65_vmem_w[0xC08F] = iie_c08b;
|
||||||
|
|
||||||
|
// slot i/o area
|
||||||
|
for (unsigned int i = 0xC100; i < 0xC300; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_slotx; // slots 1 & 2 (x)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0xC300; i < 0xC400; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_slot3; // slot 3 (80col)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0xC400; i < 0xC500; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_slot4; // slot 4 - MB or Phasor
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0xC500; i < 0xC600; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_slot5; // slot 5 - MB #2
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0xC600; i < 0xC800; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_slotx; // slots 6 - 7 (x)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0xC800; i < 0xD000; i++) {
|
||||||
|
cpu65_vmem_r[i] = iie_read_slot_expansion;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu65_vmem_w[0xCFFF] = iie_read_slot_expansion;
|
||||||
|
|
||||||
|
video_reset();
|
||||||
|
|
||||||
|
// Peripheral card slot initializations ...
|
||||||
|
|
||||||
|
// HACK TODO FIXME : this needs to be tied to the UI/configuration system (once we have more/conflicting options)
|
||||||
|
|
||||||
|
#ifdef AUDIO_ENABLED
|
||||||
|
mb_io_initialize(4, 5); /* Mockingboard(s) and/or Phasor in slots 4 & 5 */
|
||||||
|
#endif
|
||||||
|
disk_io_initialize(6); /* Put a Disk ][ Controller in slot 6 */
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void vm_initialize(void) {
|
||||||
|
_initialize_font();
|
||||||
|
_initialize_apple_ii_memory();
|
||||||
|
_initialize_tables();
|
||||||
|
vm_reinitializeAudio();
|
||||||
|
c_init_6();
|
||||||
|
_initialize_iie_switches();
|
||||||
|
c_joystick_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void vm_reinitializeAudio(void) {
|
||||||
|
#ifdef AUDIO_ENABLED
|
||||||
|
speaker_setVolumeZeroToTen(sound_volume);
|
||||||
|
MB_SetVolumeZeroToTen(sound_volume);
|
||||||
|
#endif
|
||||||
|
for (unsigned int i = 0xC030; i < 0xC040; i++) {
|
||||||
|
cpu65_vmem_r[i] = cpu65_vmem_w[i] =
|
||||||
|
#ifdef AUDIO_ENABLED
|
||||||
|
(sound_volume > 0) ? speaker_toggle :
|
||||||
|
#endif
|
||||||
|
ram_nop;
|
||||||
|
}
|
||||||
|
#warning TODO FIXME ... should unset MB/Phasor hooks if volume is zero ...
|
||||||
|
}
|
||||||
|
|
||||||
void debug_print_softwitches(void) {
|
void debug_print_softwitches(void) {
|
||||||
// useful from GDB ...
|
// useful from GDB ...
|
||||||
|
|
||||||
|
191
src/vm.h
Normal file
191
src/vm.h
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* Apple // emulator for *nix
|
||||||
|
*
|
||||||
|
* This software package is subject to the GNU General Public License
|
||||||
|
* version 2 or later (your choice) as published by the Free Software
|
||||||
|
* Foundation.
|
||||||
|
*
|
||||||
|
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VM_H_
|
||||||
|
#define _VM_H_
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
Apple //e 64K VM
|
||||||
|
|
||||||
|
(Two byte addresses are represented with least significant
|
||||||
|
byte first, e.g. address FA59 is represented as 59 FA)
|
||||||
|
|
||||||
|
This is not meant to be definitive.
|
||||||
|
Verify against _Understanding the Apple IIe_ by Jim Sather
|
||||||
|
|
||||||
|
Address Description
|
||||||
|
----------- -----------
|
||||||
|
0000 - 00FF Zero page RAM
|
||||||
|
0100 - 01FF Stack
|
||||||
|
0200 - 03EF RAM
|
||||||
|
03F0 - 03F1 Address for BRK instruction (normally 59 FA = FA59)
|
||||||
|
03F2 - 03F3 Soft entry vector (normally BF 9D = 9DBF)
|
||||||
|
03F4 Power-up byte
|
||||||
|
03F5 - 03F7 Jump instruction to the subroutine which handles
|
||||||
|
Applesoft II &-commands (normally 4C 58 FF = JMP FF58)
|
||||||
|
03F8 - 03FA Jump instruction to the subroutine which handles User
|
||||||
|
CTRL-Y commands (normally 4C 65 FF = JMP FF65)
|
||||||
|
03FB - 03FD Jump instruction to the subroutine which handles
|
||||||
|
Non-Maskable Interrupts (NMI) (normally 4C 65 FF = JMP FF65)
|
||||||
|
03FE - 03FF Address of the subroutine which handles Interrupt
|
||||||
|
ReQuests (IRQ) (normally 65 FF = FF65)
|
||||||
|
0400 - 07FF Basically primary video text page
|
||||||
|
0478 - 047F I/O Scratchpad RAM Addresses for Slot 0 - 7
|
||||||
|
04F8 - 04FF - " " -
|
||||||
|
0578 - 057F - " " -
|
||||||
|
05F8 - 05FF - " " -
|
||||||
|
0678 - 067F - " " -
|
||||||
|
06F8 - 06FF - " " -
|
||||||
|
0778 - 077F - " " -
|
||||||
|
07F8 - 07FF - " " -
|
||||||
|
05F8 Holds the slot number of the disk controller card from
|
||||||
|
which DOS was booted. ??? VERIFY...
|
||||||
|
07F8 Holds the slot number (CX, X = Slot #) of the slot that
|
||||||
|
is currently active. ??? VERIFY...
|
||||||
|
0800 - 0BFF Secondary video text page
|
||||||
|
0C00 - 1FFF Plain RAM
|
||||||
|
2000 - 3FFF Primary video hires page (RAM)
|
||||||
|
4000 - 5FFF Secondary video hires page (RAM)
|
||||||
|
6000 - BFFF Plain RAM (Normally the OS is loaded into ~9C00 - BFFF)
|
||||||
|
C000 - C00F Keyboard data (C00X contains the character ASCII code of
|
||||||
|
the pressed key. The value is available at any C00X address)
|
||||||
|
C010 - C01F Clear Keyboard strobe
|
||||||
|
C020 - C02F Cassette output toggle
|
||||||
|
C030 - C03F Speaker toggle
|
||||||
|
C040 - C04F Utility strobe
|
||||||
|
C050 Set graphics mode
|
||||||
|
C051 Set text mode
|
||||||
|
C052 Set all text or graphics
|
||||||
|
C053 Mix text and graphics
|
||||||
|
C054 Display primary page
|
||||||
|
C055 Display secondary page
|
||||||
|
C056 Display low-res graphics
|
||||||
|
C057 Display hi-res graphics
|
||||||
|
C058 - C05F Annunciator outputs
|
||||||
|
C060 Cassette input
|
||||||
|
C061 - C063 Pushbutton inputs (button 1, 2 and 3)
|
||||||
|
C064 - C067 Game controller inputs
|
||||||
|
C068 - C06F Same as C060 - C067
|
||||||
|
C070 - C07F Game controller strobe
|
||||||
|
C080 - C08F Slot 0 I/O space (usually a language card)
|
||||||
|
C080 Reset language card
|
||||||
|
* Read enabled
|
||||||
|
* Write disabled
|
||||||
|
* Read from language card
|
||||||
|
C081 --- First access
|
||||||
|
* Read mode disabled
|
||||||
|
* Read from ROM
|
||||||
|
--- On second+ access
|
||||||
|
* Write mode enabled
|
||||||
|
* Write to language card
|
||||||
|
C082 --- (Disable language card)
|
||||||
|
* Read mode disabled
|
||||||
|
* Write mode disabled
|
||||||
|
* Read from ROM
|
||||||
|
C083 --- First access
|
||||||
|
* Read mode enabled
|
||||||
|
* Read from language card
|
||||||
|
--- On second+ access
|
||||||
|
* Write mode enabled
|
||||||
|
* Write to language card
|
||||||
|
C088 - C08B Same as C080 - C083, but switch to second bank, i.e.
|
||||||
|
map addresses D000-DFFF to other 4K area.
|
||||||
|
C100 - C1FF Slot 1 PROM
|
||||||
|
C200 - C2FF Slot 2 PROM
|
||||||
|
C300 - C3FF Slot 3 PROM
|
||||||
|
C400 - C4FF Slot 4 PROM
|
||||||
|
C500 - C5FF Slot 5 PROM
|
||||||
|
C600 - C6FF Slot 6 PROM
|
||||||
|
C700 - C7FF Slot 7 PROM
|
||||||
|
C800 - CFFF Expansion ROM (for peripheral cards)
|
||||||
|
CFFF Disable access to expansion ROM for
|
||||||
|
ALL peripheral cards.
|
||||||
|
D000 - DFFF ROM or 4K RAM if language card is enabled. However,
|
||||||
|
there are TWO 4K banks that can be mapped onto addresses
|
||||||
|
D000 - DFFF. See C088 - C08B.
|
||||||
|
E000 - FFFF ROM or 8K RAM if language card is enabled.
|
||||||
|
---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if !defined(__ASSEMBLER__)
|
||||||
|
|
||||||
|
// 128k bank-switched main memory
|
||||||
|
extern uint8_t apple_ii_64k[2][65536];
|
||||||
|
|
||||||
|
// language card memory and settings
|
||||||
|
extern uint8_t language_card[2][8192];
|
||||||
|
extern uint8_t language_banks[2][8192];
|
||||||
|
|
||||||
|
extern uint32_t softswitches;
|
||||||
|
|
||||||
|
extern uint8_t *base_ramrd;
|
||||||
|
extern uint8_t *base_ramwrt;
|
||||||
|
extern uint8_t *base_textrd;
|
||||||
|
extern uint8_t *base_textwrt;
|
||||||
|
extern uint8_t *base_hgrrd;
|
||||||
|
extern uint8_t *base_hgrwrt;
|
||||||
|
|
||||||
|
extern uint8_t *base_stackzp;
|
||||||
|
extern uint8_t *base_d000_rd;
|
||||||
|
extern uint8_t *base_e000_rd;
|
||||||
|
extern uint8_t *base_d000_wrt;
|
||||||
|
extern uint8_t *base_e000_wrt;
|
||||||
|
|
||||||
|
extern uint8_t *base_c3rom;
|
||||||
|
extern uint8_t *base_c4rom; // points to function or memory vector
|
||||||
|
extern uint8_t *base_c5rom; // points to function or memory vector
|
||||||
|
extern uint8_t *base_cxrom;
|
||||||
|
|
||||||
|
void vm_initialize(void);
|
||||||
|
|
||||||
|
void vm_reinitializeAudio(void);
|
||||||
|
|
||||||
|
#if VM_TRACING
|
||||||
|
void vm_trace_begin(const char *vm_file);
|
||||||
|
void vm_trace_end(void);
|
||||||
|
void vm_trace_toggle(const char *vm_file);
|
||||||
|
bool vm_trace_is_ignored(uint16_t ea);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !defined(__ASSEMBLER__)
|
||||||
|
|
||||||
|
// softswitch flag bits
|
||||||
|
|
||||||
|
#define SS_TEXT 0x00000001
|
||||||
|
#define SS_MIXED 0x00000002
|
||||||
|
#define SS_HIRES 0x00000004
|
||||||
|
#define SS_PAGE2 0x00000008
|
||||||
|
#define SS_BANK2 0x00000010
|
||||||
|
#define SS_LCRAM 0x00000020
|
||||||
|
#define SS_LCSEC 0x00000040 // Pseudo-softswitch : enabled if 2+ reads have occurred
|
||||||
|
#define SS_LCWRT 0x00000080 // Pseudo-softswitch : LC write enable
|
||||||
|
#define SS_80STORE 0x00000100
|
||||||
|
#define SS_80COL 0x00000200
|
||||||
|
#define SS_RAMRD 0x00000400
|
||||||
|
#define SS_RAMWRT 0x00000800
|
||||||
|
#define SS_ALTZP 0x00001000
|
||||||
|
#define SS_DHIRES 0x00002000
|
||||||
|
#define SS_IOUDIS 0x00004000
|
||||||
|
#define SS_CXROM 0x00008000
|
||||||
|
#define SS_C3ROM 0x00010000
|
||||||
|
#define SS_ALTCHAR 0x00020000
|
||||||
|
|
||||||
|
// Pseudo soft switches. These are actually functions of other SSes, but are tiresome to calculate as needed.
|
||||||
|
#define SS_SCREEN 0x00040000 /* PAGE2 && !80STORE */
|
||||||
|
#define SS_TEXTRD 0x00080000 /* (PAGE2 && 80STORE) ||
|
||||||
|
(RAMRD && !80STORE) */
|
||||||
|
#define SS_TEXTWRT 0x00100000 /* (PAGE2 && 80STORE) ||
|
||||||
|
(RAMWRT && !80STORE) */
|
||||||
|
#define SS_HGRRD 0x00200000 /* (PAGE2 && 80STORE && HIRES) ||
|
||||||
|
(RAMRD && !(80STORE && HIRES) */
|
||||||
|
#define SS_HGRWRT 0x00400000 /* (PAGE2 && 80STORE && HIRES) ||
|
||||||
|
(RAMWRT && !(80STORE && HIRES)) */
|
||||||
|
|
||||||
|
#endif // whole file
|
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cpu-regs.h"
|
#include "cpu-regs.h"
|
||||||
#include "misc.h"
|
#include "vm.h"
|
||||||
|
|
||||||
#define CommonSaveCPUState \
|
#define CommonSaveCPUState \
|
||||||
movw EffectiveAddr, SYM(cpu65_ea); \
|
movw EffectiveAddr, SYM(cpu65_ea); \
|
||||||
|
@ -14,9 +14,11 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "misc.h"
|
#include "vm.h"
|
||||||
#include "cpu-regs.h"
|
#include "cpu-regs.h"
|
||||||
|
|
||||||
|
#define GLUE_EXTERN_C_READ(func)
|
||||||
|
|
||||||
#define GLUE_BANK_MAYBEREAD(func,pointer) \
|
#define GLUE_BANK_MAYBEREAD(func,pointer) \
|
||||||
ENTRY(func) testLQ $SS_CXROM, SYM(softswitches); \
|
ENTRY(func) testLQ $SS_CXROM, SYM(softswitches); \
|
||||||
jnz 1f; \
|
jnz 1f; \
|
||||||
|
Loading…
Reference in New Issue
Block a user