mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +00:00
Ensures analogue channels which are already charging don't abide by c070
.
This commit is contained in:
parent
f26e4734b3
commit
0be19d8de7
@ -202,8 +202,25 @@ class ConcreteMachine:
|
|||||||
bool buttons[3] = {false, false, false};
|
bool buttons[3] = {false, false, false};
|
||||||
float axes[2] = {0.5f, 0.5f};
|
float axes[2] = {0.5f, 0.5f};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// On an Apple II, the programmer strobes 0xc070 and that causes each analogue input
|
||||||
|
// to begin a charge and discharge cycle **if they are not already charging**.
|
||||||
|
// The greater the analogue input, the faster they will charge and therefore the sooner
|
||||||
|
// they will discharge.
|
||||||
|
//
|
||||||
|
// This emulator models that with analogue_charge_ being essentially the amount of time,
|
||||||
|
// in charge threshold units, since 0xc070 was last strobed. But if any of the analogue
|
||||||
|
// inputs were already partially charged then they gain a bias in analogue_biases_.
|
||||||
|
//
|
||||||
|
// It's a little indirect, but it means only having to increment the one value in the
|
||||||
|
// main loop.
|
||||||
float analogue_charge_ = 0.0f;
|
float analogue_charge_ = 0.0f;
|
||||||
|
float analogue_biases_[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
|
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
|
||||||
|
bool analogue_channel_is_discharged(size_t channel) {
|
||||||
|
return static_cast<Joystick *>(joysticks_[channel >> 1].get())->axes[channel & 1] < analogue_charge_ + analogue_biases_[channel];
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConcreteMachine():
|
ConcreteMachine():
|
||||||
@ -431,7 +448,7 @@ class ConcreteMachine:
|
|||||||
case 0xc067: { // Analogue input 3.
|
case 0xc067: { // Analogue input 3.
|
||||||
const size_t input = address - 0xc064;
|
const size_t input = address - 0xc064;
|
||||||
*value &= 0x7f;
|
*value &= 0x7f;
|
||||||
if(static_cast<Joystick *>(joysticks_[input >> 1].get())->axes[input & 1] < analogue_charge_) {
|
if(analogue_channel_is_discharged(input)) {
|
||||||
*value |= 0x80;
|
*value |= 0x80;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -441,6 +458,18 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xc070: { // Permit analogue inputs that are currently discharged to begin a charge cycle.
|
||||||
|
// Ensure those that were still charging retain that state.
|
||||||
|
for(size_t c = 0; c < 4; ++c) {
|
||||||
|
if(analogue_channel_is_discharged(c)) {
|
||||||
|
analogue_biases_[c] = 0.0f;
|
||||||
|
} else {
|
||||||
|
analogue_biases_[c] += analogue_charge_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
analogue_charge_ = 0.0f;
|
||||||
|
} break;
|
||||||
|
|
||||||
/* Read-write switches. */
|
/* Read-write switches. */
|
||||||
case 0xc050: update_video(); video_->set_graphics_mode(); break;
|
case 0xc050: update_video(); video_->set_graphics_mode(); break;
|
||||||
case 0xc051: update_video(); video_->set_text_mode(); break;
|
case 0xc051: update_video(); video_->set_text_mode(); break;
|
||||||
@ -451,10 +480,6 @@ class ConcreteMachine:
|
|||||||
case 0xc056: update_video(); video_->set_low_resolution(); break;
|
case 0xc056: update_video(); video_->set_low_resolution(); break;
|
||||||
case 0xc057: update_video(); video_->set_high_resolution(); break;
|
case 0xc057: update_video(); video_->set_high_resolution(); break;
|
||||||
|
|
||||||
case 0xc070: // Reset analogue inputs.
|
|
||||||
analogue_charge_ = 0.0f;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xc010:
|
case 0xc010:
|
||||||
keyboard_input_ &= 0x7f;
|
keyboard_input_ &= 0x7f;
|
||||||
if(string_serialiser_) {
|
if(string_serialiser_) {
|
||||||
|
Loading…
Reference in New Issue
Block a user