Fix the game controller routines to use proper timers

* Add proper timers according to spec mentioned in _Understanding the Apple IIe_
    * This will allow us to refactor/eliminate all the hackish joystick adjustment routines
This commit is contained in:
Aaron Culliney 2013-12-21 13:55:40 -08:00
parent e0bd3e4017
commit d0ea2d654e
5 changed files with 52 additions and 42 deletions

View File

@ -2693,6 +2693,8 @@ continue:
movb SN(cpu65__opcycles)(,%eax,1), %al
addb DebugCycleCount, %al
addw %ax, SN(cpu65_cycle_count) // TODO: cycle counting is slightly incorrect, it should be done earlier per instruction ...
subl %eax, SN(gc_cycles_timer_0)
subl %eax, SN(gc_cycles_timer_1)
subw %ax, SN(cpu65_cycles_to_execute) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ orly?
jle exit_cpu65_run
xorl %eax, %eax

View File

@ -352,9 +352,6 @@ iie_hires_on_80store_off:
/*****************************************************************************/
.comm joy_trigger0, 2
.comm joy_trigger1, 2
E(read_button0)
movb SN(joy_button0), %al
ret
@ -367,40 +364,6 @@ E(read_button2)
movb SN(joy_button2), %al
ret
E(read_gc0)
cmpw $0xFF, joy_trigger0
jle read_gc0_cont
read_gc0_lo:
movb $0, %al
ret
read_gc0_cont:
incw joy_trigger0
movw joy_trigger0, %ax
cmpw %ax, SN(joy_x)
jl read_gc0_reset
movb $0xFF, %al
ret
read_gc0_reset:
movw $0xFF, joy_trigger0
jmp read_gc0_lo
E(read_gc1)
cmpw $0xFF, joy_trigger1
jle read_gc1_cont
read_gc1_lo:
movb $0, %al
ret
read_gc1_cont:
incw joy_trigger1
movw joy_trigger1, %ax
cmpw %ax, SN(joy_y)
jl read_gc1_reset
movb $0xFF, %al
ret
read_gc1_reset:
movw $0xFF, joy_trigger0
jmp read_gc1_lo
/* NOTE : Game Controller axis 2 & 3 is not hooked up on a normal //e */
E(iie_read_gc2)
movb $0, %al
@ -410,11 +373,6 @@ E(iie_read_gc3)
movb $0, %al
ret
E(read_gc_strobe)
movw $0, joy_trigger0
movw $0, joy_trigger1
ret
E(iie_c080)
testl $SS_ALTZP, SN(softswitches)
jz lc_c080

View File

@ -762,6 +762,50 @@ static void c_initialize_firsttime()
reinitialize();
}
// Read Game Controller (paddle) strobe ...
// From _Understanding the Apple IIe_ :
// * 7-29, discussing PREAD : "The timer duration will vary between 2 and 3302 usecs"
// * 7-30, timer reset : "But the timer pulse may still be high from the previous [strobe access] and the timers are
// not retriggered by C07X' if they have not yet reset from the previous trigger"
#define JOY_STEP_USEC (3300.0 / 256.0)
#define CYCLES_PER_USEC (CLK_6502 / 1000000)
#define JOY_STEP_CYCLES (JOY_STEP_USEC / CYCLES_PER_USEC)
extern short joy_x;
extern short joy_y;
GLUE_C_READ(read_gc_strobe)
{
if (gc_cycles_timer_0 <= 0)
{
gc_cycles_timer_0 = (int)(joy_x * JOY_STEP_CYCLES) + 2;
}
if (gc_cycles_timer_1 <= 0)
{
gc_cycles_timer_1 = (int)(joy_y * JOY_STEP_CYCLES) + 2;
}
// NOTE: unimplemented GC2 and GC3 timers since they were not wired on the //e ...
return 0;
}
GLUE_C_READ(read_gc0)
{
if (gc_cycles_timer_0 <= 0)
{
gc_cycles_timer_0 = 0;
return 0;
}
return 0xFF;
}
GLUE_C_READ(read_gc1)
{
if (gc_cycles_timer_1 <= 0)
{
gc_cycles_timer_1 = 0;
return 0;
}
return 0xFF;
}
// HACK FIXME TODO : candidate for GLUE_C_READ(...)
void c_read_random() {
static unsigned int seed=0;

View File

@ -34,6 +34,9 @@ static bool alt_speed_enabled = false;
double cpu_scale_factor = 1.0;
double cpu_altscale_factor = 1.0;
int gc_cycles_timer_0 = 0;
int gc_cycles_timer_1 = 0;
uint8_t emul_reinitialize;
static unsigned int g_nCyclesExecuted; // # of cycles executed up to last IO access

View File

@ -45,6 +45,9 @@ extern int g_nCpuCyclesFeedback;
extern double cpu_scale_factor;
extern double cpu_altscale_factor;
extern int gc_cycles_timer_0;
extern int gc_cycles_timer_1;
struct timespec timespec_diff(struct timespec start, struct timespec end, bool *negative);
void timing_toggle_cpu_speed();