#define HW_CLRAN2 0xc05d // RW annunciator 2 on
#define HW_SETAN3 0xc05e // RW annunciator 2 off
#define HW_CLRAN3 0xc05f // RW annunciator 3 on
+#define HW_TAPEIN 0xc060 // R
#define HW_PB0 0xc061 // R switch input 0 / open-apple (orig: BUTN0)
#define HW_PB1 0xc062 // R switch input 1 / closed-apple (orig: BUTN1)
-#define HW_PADDL0 0xc064
-#define HW_PADDL1 0xc065
+#define HW_PB2 0xc063 // R
+#define HW_PADDL0 0xc064 // R
+#define HW_PADDL1 0xc065 // R
+#define HW_PADDL2 0xc066 // R
+#define HW_PADDL3 0xc067 // R
#define HW_PTRIG 0xc070
#define HW_LC_BANK2_RAM_WP 0xc080 // RW
#define HW_LC_BANK2_ROM_WE 0xc081 // RWx2
#define C05X_SOFT_SWITCH_NOTAN3 0x80
uint8_t c05x_soft_switches = C05X_SOFT_SWITCH_TEXT;
+#define C06X_INPUT_TAPEIN 1
+#define C06X_INPUT_PB0 2
+#define C06X_INPUT_PB1 4
+#define C06X_INPUT_PB2 8
+#define C06X_INPUT_PADDL0 0x10
+#define C06X_INPUT_PADDL1 0x20
+#define C06X_INPUT_PADDL2 0x40
+#define C06X_INPUT_PADDL3 0x80
+#define C06X_INPUT_PADDLX 0xf0
+uint8_t c06x_inputs;
+
+#define JOYSTICK_COUNT 0x900 // 9 cycles per loop of ROM_PREAD
+int joystick_count = JOYSTICK_COUNT;
+int joystick_axes[4] = {
+ JOYSTICK_COUNT,
+ JOYSTICK_COUNT,
+ JOYSTICK_COUNT,
+ JOYSTICK_COUNT
+};
+
#define LC_BANK 4
#define LC_BANK2 0
#define LC_BANK1 4
}
uint8_t mem_read(uint16_t addr0, bool isDbg) {
+ // for joystick, for now count memory accesses as proxy for cycles
+ if (joystick_count < JOYSTICK_COUNT) {
+ ++joystick_count;
+ if (joystick_axes[0] < joystick_count)
+ c06x_inputs &= ~C06X_INPUT_PADDL0;
+ if (joystick_axes[1] < joystick_count)
+ c06x_inputs &= ~C06X_INPUT_PADDL1;
+ if (joystick_axes[2] < joystick_count)
+ c06x_inputs &= ~C06X_INPUT_PADDL2;
+ if (joystick_axes[3] < joystick_count)
+ c06x_inputs &= ~C06X_INPUT_PADDL3;
+ }
+
int addr = addr0;
if ((addr & 0xff00) != IO_PAGE) {
#if APPLE_IIE
case HW_CLRAN3 : // 0xc05f
c05x_soft_switches |= 1 << ((addr >> 1) & 7);
break;
- case HW_PB0:
- case HW_PB1:
- return 0; // needed for proper boot with IIe ROM
+ case HW_TAPEIN: // 0xc060
+ case HW_PB0: // 0xc061
+ case HW_PB1: // 0xc062
+ case HW_PB2: // 0xc063
+ case HW_PADDL0: // 0xc064
+ case HW_PADDL1: // 0xc065
+ case HW_PADDL2: // 0xc066
+ case HW_PADDL3: // 0xc067
+ return ((c06x_inputs & (1 << (addr & 7))) != 0) << 7;
+ case HW_PTRIG:
+ joystick_count = 0;
+ c06x_inputs |= C06X_INPUT_PADDLX;
+ break;
case HW_LC_BANK2_RAM_WP: // 0xc080
case HW_LC_BANK2_ROM_WE: // 0xc081
case HW_LC_BANK2_ROM_WP: // 0xc082
}
void mem_write(uint16_t addr0, uint8_t val) {
+ // for joystick, for now count memory accesses as proxy for cycles
+ if (joystick_count < JOYSTICK_COUNT) {
+ ++joystick_count;
+ if (joystick_axes[0] < joystick_count)
+ c06x_inputs &= ~C06X_INPUT_PADDL0;
+ if (joystick_axes[1] < joystick_count)
+ c06x_inputs &= ~C06X_INPUT_PADDL1;
+ if (joystick_axes[2] < joystick_count)
+ c06x_inputs &= ~C06X_INPUT_PADDL2;
+ if (joystick_axes[3] < joystick_count)
+ c06x_inputs &= ~C06X_INPUT_PADDL3;
+ }
+
int addr = addr0;
#if 0 // vectors
if (addr >= 4 && addr < 0x80) {
}
}
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) {
fprintf(stderr, "SDL_Init(): %s\n\n", SDL_GetError());
exit(EXIT_FAILURE);
}
//);
SDL_PauseAudioDevice(audio_device_id, 0);
+ SDL_Joystick *joystick = NULL;
+ if (SDL_NumJoysticks()) {
+ joystick = SDL_JoystickOpen(0);
+ if (joystick == NULL) {
+ fprintf(stderr, "SDL_JoystickOpen(): %s\n", SDL_GetError());
+ exit(EXIT_FAILURE);
+ }
+
+ if (SDL_JoystickEventState(SDL_ENABLE) != 1) {
+ fprintf(stderr, "SDL_JoystickEventState(): %s\n", SDL_GetError());
+ exit(EXIT_FAILURE);
+ }
+
+ // we should get the current position to use until first event,
+ // for now just centre it (no joystick is fully to right and down)
+ for (int i = 0; i < 4; ++i)
+ joystick_axes[i] = JOYSTICK_COUNT >> 1;
+ }
+
cpu = vrEmu6502New(CPU_65C02, mem_read, mem_write);
if (cpu == NULL) {
perror("malloc()");
}
}
break;
+ case SDL_JOYBUTTONUP:
+ {
+ SDL_JoyButtonEvent *e = (SDL_JoyButtonEvent *)&event;
+ if (
+ joystick &&
+ e->which == SDL_JoystickInstanceID(joystick) &&
+ e->button < 3
+ )
+ c06x_inputs &= ~(C06X_INPUT_PB0 << e->button);
+ }
+ break;
+ case SDL_JOYBUTTONDOWN:
+ {
+ SDL_JoyButtonEvent *e = (SDL_JoyButtonEvent *)&event;
+ if (
+ joystick &&
+ e->which == SDL_JoystickInstanceID(joystick) &&
+ e->button < 3
+ )
+ c06x_inputs |= C06X_INPUT_PB0 << e->button;
+ }
+ break;
+ case SDL_JOYAXISMOTION:
+ {
+ SDL_JoyAxisEvent *e = (SDL_JoyAxisEvent *)&event;
+ if (
+ joystick &&
+ e->which == SDL_JoystickInstanceID(joystick) &&
+ e->axis < 4
+ )
+ joystick_axes[e->axis] =
+ ((e->value + 0x8000) * JOYSTICK_COUNT) >> 16;
+ }
+ break;
}
// video update
quit:
vrEmu6502Destroy(cpu);
+ if (joystick)
+ SDL_JoystickClose(joystick);
SDL_CloseAudioDevice(audio_device_id);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);