From fc5399e329dcf232362dce2528094a62080b0f03 Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Tue, 6 Sep 2016 22:55:05 -0400 Subject: [PATCH] Disable interrupts while reading from the joystick. By doing this, we can have the mouse and joystick drivers both enabled at the same time. Do not disable the mouse driver when mouse input is disabled. Register a "show" callback with the mouse driver and use that as a way to be notified of a VBL interval on the //c. --- a2bejwld/joystick.c | 4 ++++ a2bejwld/mouseWrapper.c | 20 +++++++++++++++++++- a2bejwld/ui.c | 25 +++++++++++-------------- a2bejwld/vbl.h | 2 ++ a2bejwld/vbl.s | 20 ++++++++++++++++++-- 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/a2bejwld/joystick.c b/a2bejwld/joystick.c index 3221c1d..8e302f8 100644 --- a/a2bejwld/joystick.c +++ b/a2bejwld/joystick.c @@ -71,7 +71,9 @@ static uint8_t joystickLeftRight(void) { __asm__("BIT %w", ROM_SWITCH); __asm__("LDX #0"); + __asm__("SEI"); __asm__("JSR %w", PREAD); + __asm__("CLI"); __asm__("STY %v", gJoystickTemp); __asm__("BIT %w", RAM_SWITCH); return gJoystickTemp; @@ -82,7 +84,9 @@ static uint8_t joystickUpDown(void) { __asm__("BIT %w", ROM_SWITCH); __asm__("LDX #1"); + __asm__("SEI"); __asm__("JSR %w", PREAD); + __asm__("CLI"); __asm__("STY %v", gJoystickTemp); __asm__("BIT %w", RAM_SWITCH); return gJoystickTemp; diff --git a/a2bejwld/mouseWrapper.c b/a2bejwld/mouseWrapper.c index df2d498..81aaadc 100644 --- a/a2bejwld/mouseWrapper.c +++ b/a2bejwld/mouseWrapper.c @@ -13,6 +13,7 @@ #include "mouseWrapper.h" #include "game.h" +#include "vbl.h" // Extern to mouse driver @@ -26,12 +27,29 @@ static tMouseCallbacks *gMouseCallbacks = NULL; static bool gMouseInstalled = false; static bool gMouseInPoll = false; +static struct mouse_callbacks gMouseDrvCallbacks; + bool initMouse(tMouseCallbacks *callbacks) { if (!gMouseInstalled) { - if (mouse_install(&mouse_def_callbacks, &a2e_stdmou_mou) == 0) { + gMouseDrvCallbacks.hide = mouse_def_callbacks.hide; + // This callback is here for the //c VBL which is only detectable + // through the mouse interrupt. By registering this as our "show" + // function, we can ensure that we get called on our VBL interrupt + // and can unblock our VBL wait function. + gMouseDrvCallbacks.show = vblIRQCallback; + gMouseDrvCallbacks.movex = mouse_def_callbacks.movex; + gMouseDrvCallbacks.movey = mouse_def_callbacks.movey; + + if (mouse_install(&gMouseDrvCallbacks, &a2e_stdmou_mou) == 0) { gMouseInstalled = true; + + // This is required to ensure that the show callback is called + // by the interrupt handler. This whole thing is a bit of a + // hack to get the default mouse interrupt handler to do what + // we want on the //c to detect the VBL but it works for now. + mouse_show(); } } diff --git a/a2bejwld/ui.c b/a2bejwld/ui.c index 18a78f5..2d7d778 100644 --- a/a2bejwld/ui.c +++ b/a2bejwld/ui.c @@ -24,7 +24,7 @@ // Defines #define SAVE_OPTIONS_FILE "a2bejwld.opts" -#define VERSION "v1.2b3" +#define VERSION "v1.2b4" // Typedefs @@ -180,8 +180,6 @@ void applyNewOptions(tGameOptions *newOptions) if (oldEnableMouse != gGameOptions.enableMouse) { if (gGameOptions.enableMouse) { gGameOptions.enableMouse = initMouse(&gMouseCallbacks); - } else { - shutdownMouse(); } } saveOptions(); @@ -564,25 +562,24 @@ static void getHint(void) void initUI(void) { bool optionsLoaded; + bool mouseInitialized; initMachine(); optionsLoaded = loadOptions(); initGameEngine(&gCallbacks); + mouseInitialized = initMouse(&gMouseCallbacks); - if ((!optionsLoaded) || + // If we couldn't initialize a mouse and it was enabled on the options, then disable it. + if ((!mouseInitialized) && (gGameOptions.enableMouse)) { - // If we didn't load any options or the saved options had the mouse enabled, then try to init a mouse. - gGameOptions.enableMouse = initMouse(&gMouseCallbacks); - if (!gGameOptions.enableMouse) { - // If we didn't init a mouse, then let's mark the options as not saved. - gGameOptions.optionsSaved = false; - - // If we didn't load an options file, then let's turn on the joystick instead. - if (!optionsLoaded) { - gGameOptions.enableJoystick = true; - } + gGameOptions.enableMouse = false; + gGameOptions.optionsSaved = false; + + // If there were no options loaded, then let's turn on the joystick instead. + if (!optionsLoaded) { + gGameOptions.enableJoystick = true; } } diff --git a/a2bejwld/vbl.h b/a2bejwld/vbl.h index 06aa4f7..c5fc8fa 100644 --- a/a2bejwld/vbl.h +++ b/a2bejwld/vbl.h @@ -16,5 +16,7 @@ extern void __fastcall__ vblInit2gs(void); extern void __fastcall__ vblWait(void); extern void __fastcall__ vblWait2c(void); +extern void __fastcall__ vblIRQCallback(void); + #endif /* defined(__a2bejwld__vbl__) */ diff --git a/a2bejwld/vbl.s b/a2bejwld/vbl.s index bc65e3d..875736b 100644 --- a/a2bejwld/vbl.s +++ b/a2bejwld/vbl.s @@ -9,6 +9,7 @@ .export _vblWait, _vblWait2c, _vblInit2gs + .export _vblIRQCallback .include "apple2.inc" @@ -36,8 +37,20 @@ RDVBLBAR := $C019 .endproc +.proc _vblIRQCallback + stz vbl2cByte + rts +.endproc + + .proc _vblWait2c - ; TODO - write a routine for VBL detection on //c + lda #$ff + sta vbl2cByte + +@L1: + lda vbl2cByte + bne @L1 + rts .endproc @@ -45,4 +58,7 @@ RDVBLBAR := $C019 .data compType: - .BYTE $7e \ No newline at end of file + .BYTE $7e + +vbl2cByte: + .BYTE $00 \ No newline at end of file