Beginnings of a pluggable peripheral card API and fix a CPU boot tracing divergence against AppleWin

- In particular, return floating_bus() for non-plugged in cards when accessing the $C100-$C700 range
This commit is contained in:
Aaron Culliney 2016-09-25 19:18:34 -07:00
parent ccd05e52fe
commit 1294485a02
7 changed files with 93 additions and 42 deletions

View File

@ -14,7 +14,7 @@
#define GLUE_EXTERN_C_READ(func)
#define GLUE_BANK_MAYBEREAD(func,pointer) \
#define GLUE_BANK_MAYBE_READ_CX(func,pointer) \
ENTRY(func) SYM(r1, softswitches); \
ldr r0, [r1]; \
SYM(r1, pointer); \
@ -28,6 +28,22 @@ ENTRY(func) SYM(r1, softswitches); \
ldrb r0, [r1, EffectiveAddr]; \
mov pc, lr;
#define GLUE_BANK_MAYBE_READ_C3(func,pointer) \
ENTRY(func) SYM(r1, softswitches); \
ldr r0, [r1]; \
SYM(r1, pointer); \
tst r0, $SS_CXROM; \
bne 1f; \
tst r0, $SS_C3ROM; \
bne 1f; \
push {EffectiveAddr, PC_Reg, /*SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg,*/ lr}; \
ldr r1, [r1]; \
blx r1; \
pop {EffectiveAddr, PC_Reg, /*SP_Reg, F_Reg, Y_Reg, X_Reg, A_Reg,*/ pc}; \
1: ldr r1, [r1]; \
ldrb r0, [r1, EffectiveAddr]; \
mov pc, lr;
#define GLUE_BANK_READ(func,pointer) \
ENTRY(func) SYM(r1, pointer); \

View File

@ -1997,6 +1997,11 @@ void MB_Reset()
#define MemReadFloatingBus floating_bus
#define nAddr ea
GLUE_C_READ(MB_Read)
{
return mb_read(ea);
}
uint8_t mb_read(uint16_t ea)
#else
static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULONG nCyclesLeft)
#endif

View File

@ -122,6 +122,7 @@ void MB_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
bool MB_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
#endif
#ifdef APPLE2IX
uint8_t mb_read(uint16_t ea);
void mb_io_initialize(unsigned int slot4, unsigned int slot5);
# if MB_TRACING
void mb_traceBegin(const char *trace_file);

View File

@ -18,7 +18,8 @@
#endif
#define GLUE_BANK_READ(func,pointer) extern void func(void)
#define GLUE_BANK_MAYBEREAD(func,pointer) extern void func(void)
#define GLUE_BANK_MAYBE_READ_C3(func,pointer) extern void func(void)
#define GLUE_BANK_MAYBE_READ_CX(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)

View File

@ -3005,6 +3005,8 @@ TEST test_c3rom_internal() {
PASS();
}
extern uint8_t (*iie_read_peripheral_card)(uint16_t);
#warning WARNING TODO FIXME ... these are poor tests ... really we should be testing small assembly programs that read/write/check banked memory
TEST test_c3rom_peripheral(bool flag_cxrom) {
BOOT_TO_DOS();
@ -3047,7 +3049,7 @@ TEST test_c3rom_peripheral(bool flag_cxrom) {
ASSERT((base_c3rom == save_base_c3rom));
} else {
ASSERT(!(softswitches & SS_CXROM));
ASSERT((base_c3rom == apple_ii_64k[0]));
ASSERT((base_c3rom == (void *)&iie_read_peripheral_card));
}
ASSERT((softswitches ^ switch_save) == 0);
@ -3171,10 +3173,10 @@ TEST test_cxrom_peripheral(bool flag_c3rom) {
ASSERT((base_c3rom == save_base_c3rom));
} else {
ASSERT(!(softswitches & SS_C3ROM));
ASSERT((base_c3rom == apple_ii_64k[0]));
ASSERT((base_c3rom == (void *)&iie_read_peripheral_card));
}
ASSERT(base_cxrom == apple_ii_64k[0]);
ASSERT((base_cxrom == (void *)&iie_read_peripheral_card));
// TODO FIXME ... test other peripherals base_xxx here ...

View File

@ -71,10 +71,10 @@ 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_BANK_MAYBE_READ_C3(iie_read_slot3,base_c3rom);
GLUE_BANK_MAYBE_READ_CX(iie_read_slot4,base_c4rom);
GLUE_BANK_MAYBE_READ_CX(iie_read_slot5,base_c5rom);
GLUE_BANK_MAYBE_READ_CX(iie_read_slotx,base_cxrom);
GLUE_EXTERN_C_READ(speaker_toggle);
@ -93,6 +93,37 @@ GLUE_C_WRITE(write_unmapped_softswitch)
// ...
}
GLUE_C_READ(iie_read_peripheral_card)
{
assert(((ea >> 12) & 0xf) == 0xC && "should only be called for 0xC100-0xC7FF");
uint8_t slot = ((ea >> 8) & 0xf);
// TODO FIXME : route to correct peripheral card
switch (slot) {
case 0x1:
case 0x2:
case 0x3:
case 0x7:
break;
case 0x4:
case 0x5:
return mb_read(ea); // FIXME : hardcoded Mockingboards ...
break;
case 0x6:
return apple_ii_64k[0][ea];
break;
default:
assert(false && "internal configuration error!");
break;
}
// no card in slot
return floating_bus();
}
GLUE_C_READ(read_keyboard)
{
uint8_t b = apple_ii_64k[0][0xC000];
@ -849,7 +880,7 @@ GLUE_C_READ(iie_c3rom_peripheral)
{
softswitches &= ~SS_C3ROM;
if (!(softswitches & SS_CXROM)) {
base_c3rom = apple_ii_64k[0];
base_c3rom = (void *)iie_read_peripheral_card;
}
return 0x0;
}
@ -866,23 +897,14 @@ GLUE_C_READ(iie_check_c3rom)
return (softswitches & SS_C3ROM) ? 0x00 : 0x80; // reversed pattern
}
typedef uint8_t *(VMFunc)(uint16_t);
GLUE_C_READ(iie_cxrom_peripheral)
{
softswitches &= ~SS_CXROM;
base_cxrom = apple_ii_64k[0];
// FIXME TODO : implement pluggable peripheral API
//if (mockingboard_inserted) {
extern VMFunc MB_Read;
base_c4rom = (void*)MB_Read;
base_c5rom = (void*)MB_Read;
//} else {
// base_c4rom = (void*)ram_nop;
// base_c5rom = (void*)ram_nop;
//}
base_cxrom = (void *)iie_read_peripheral_card;
base_c4rom = (void *)iie_read_peripheral_card;
base_c5rom = (void *)iie_read_peripheral_card;
if (!(softswitches & SS_C3ROM)) {
base_c3rom = apple_ii_64k[0];
base_c3rom = (void *)iie_read_peripheral_card;
}
return 0x0;
}
@ -944,7 +966,7 @@ static void _initialize_iie_switches(void) {
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
base_cxrom = (void *)iie_read_peripheral_card; // cxrom peripheral
}
static void _initialize_font(void) {
@ -1193,8 +1215,6 @@ static void _initialize_tables(void) {
cpu65_vmem_r[i] = iie_read_slot_expansion;
}
cpu65_vmem_w[0xCFFF] = iie_read_slot_expansion;
video_reset();
// Peripheral card slot initializations ...
@ -1292,12 +1312,13 @@ bool vm_saveState(StateHelper_s *helper) {
if (!helper->save(fd, (base_stackzp == apple_ii_64k[0]) ? &serialized[0] : &serialized[1], 1)) {
break;
}
LOG("SAVE base_c3rom = %d", (base_c3rom == apple_ii_64k[0]) ? serialized[0] : serialized[1]);
if (!helper->save(fd, (base_c3rom == apple_ii_64k[0]) ? &serialized[0] : &serialized[1], 1)) {
LOG("SAVE base_c3rom = %d", (base_c3rom == (void *)iie_read_peripheral_card) ? serialized[0] : serialized[1]);
if (!helper->save(fd, (base_c3rom == (void *)iie_read_peripheral_card) ? &serialized[0] : &serialized[1], 1)) {
break;
}
LOG("SAVE base_cxrom = %d", (base_cxrom == apple_ii_64k[0]) ? serialized[0] : serialized[1]);
if (!helper->save(fd, (base_cxrom == apple_ii_64k[0]) ? &serialized[0] : &serialized[1], 1)) {
LOG("SAVE base_cxrom = %d", (base_cxrom == (void *)iie_read_peripheral_card) ? serialized[0] : serialized[1]);
if (!helper->save(fd, (base_cxrom == (void *)iie_read_peripheral_card) ? &serialized[0] : &serialized[1], 1)) {
break;
}
@ -1487,23 +1508,16 @@ bool vm_loadState(StateHelper_s *helper) {
break;
}
LOG("LOAD base_c3rom = %d", state);
base_c3rom = state == 0x0 ? apple_ii_64k[0] : apple_ii_64k[1];
base_c3rom = state == 0x0 ? (void *)iie_read_peripheral_card : apple_ii_64k[1];
if (!helper->load(fd, &state, 1)) {
break;
}
LOG("LOAD base_cxrom = %d", state);
if (state == 0) {
base_cxrom = apple_ii_64k[0];
// FIXME TODO : implement pluggable peripheral API
//if (mockingboard_inserted) {
extern VMFunc MB_Read;
base_c4rom = (void *)MB_Read;
base_c5rom = (void *)MB_Read;
//} else {
// base_c4rom = (void *)ram_nop;
// base_c5rom = (void *)ram_nop;
//}
base_cxrom = (void *)iie_read_peripheral_card;
base_c4rom = (void *)iie_read_peripheral_card;
base_c5rom = (void *)iie_read_peripheral_card;
} else {
base_cxrom = apple_ii_64k[1];
base_c4rom = apple_ii_64k[1];

View File

@ -28,7 +28,7 @@
#define GLUE_EXTERN_C_READ(func)
#define GLUE_BANK_MAYBEREAD(func,pointer) \
#define GLUE_BANK_MAYBE_READ_CX(func,pointer) \
ENTRY(func) REG2MEM(testLQ, $SS_CXROM, softswitches); \
jnz 1f; \
CALL_IND0(pointer); \
@ -38,6 +38,18 @@ ENTRY(func) REG2MEM(testLQ, $SS_CXROM, softswitches); \
MEM2REG(subLQ, pointer, EffectiveAddr_X); \
ret;
#define GLUE_BANK_MAYBE_READ_C3(func,pointer) \
ENTRY(func) REG2MEM(testLQ, $SS_CXROM, softswitches); \
jnz 1f; \
REG2MEM(testLQ, $SS_C3ROM, softswitches); \
jnz 1f; \
CALL_IND0(pointer); \
ret; \
1: MEM2REG(addLQ, pointer, EffectiveAddr_X); \
movb (EffectiveAddr_X),%al; \
MEM2REG(subLQ, pointer, EffectiveAddr_X); \
ret;
#define GLUE_BANK_READ(func,pointer) \
ENTRY(func) MEM2REG(addLQ, pointer, EffectiveAddr_X); \
movb (EffectiveAddr_X),%al; \