mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-26 15:32:04 +00:00
Adds a hacky different guess at how register access might work.
This commit is contained in:
parent
72d7901c88
commit
5d1970d201
@ -829,3 +829,7 @@ inline int Executor::update_timer(Timer &timer, int count) {
|
||||
timer.value = uint8_t(next_value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t Executor::get_output_mask(int port) {
|
||||
return port_directions_[port];
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ class Executor: public CachingExecutor {
|
||||
void reset();
|
||||
void set_interrupt_line(bool);
|
||||
|
||||
uint8_t get_output_mask(int port);
|
||||
|
||||
/*!
|
||||
Runs, in discrete steps, the minimum number of instructions as it takes to complete at least @c cycles.
|
||||
*/
|
||||
|
@ -55,7 +55,7 @@ uint8_t GLU::get_keyboard_data() {
|
||||
// The classic Apple II serial keyboard register:
|
||||
// b7: key strobe.
|
||||
// b6–b0: ASCII code.
|
||||
return registers_[0] | (status_ & uint8_t(CPUFlags::KeyboardDataFull)) ? 0x80 : 0x00;
|
||||
return (registers_[0] & 0x7f) | (status_ & uint8_t(CPUFlags::KeyboardDataFull)) ? 0x80 : 0x00;
|
||||
}
|
||||
|
||||
void GLU::clear_key_strobe() {
|
||||
@ -175,29 +175,54 @@ void GLU::set_port_output(int port, uint8_t value) {
|
||||
|
||||
register_address_ = value & 0xf;
|
||||
|
||||
// Check the strobe; I think:
|
||||
// This is an ugly hack, I think. Per Neil Parker's Inside the Apple IIGS ADB Controller
|
||||
// http://nparker.llx.com/a2/adb.html#external:
|
||||
//
|
||||
// high -> low, read => fill latch from register;
|
||||
// low -> high => fill register from latch.
|
||||
// The protocol for reading an ADB GLU register is as follows:
|
||||
//
|
||||
// 1. Put the register number of the ADB GLU register in port P2 bits 0-3.
|
||||
// 2. Clear bit 4 of port P2, read the data from P0, and set bit 4 of P0.
|
||||
//
|
||||
// The protocol for writing a GLU register is similar:
|
||||
//
|
||||
// 1. Write the register number to port P2 bits 0-3.
|
||||
// 2. Write the data to port P0.
|
||||
// 3. Configure port P0 for output by writing $FF to $E1.
|
||||
// 4. Clear bit 4 of P2, and immediately set it again.
|
||||
// 5. Configure port P0 for input by writing 0 to $E1.
|
||||
//
|
||||
// ---
|
||||
//
|
||||
// I tried: linking a read or write to rising or falling edges of the strobe.
|
||||
// Including with hysteresis as per the "immediately" (which, in practice, seems
|
||||
// to mean "in the very next instruction", i.e. 5 cycles later). That didn't seem
|
||||
// properly to differentiate.
|
||||
//
|
||||
// So I'm focussing on the "configure port P0 for output" bit. Which I don't see
|
||||
// would be visible here unless it is actually an exposed signal, which is unlikely.
|
||||
//
|
||||
// Ergo: ugly. HACK.
|
||||
const bool strobe = value & 0x10;
|
||||
if(strobe != register_strobe_) {
|
||||
register_strobe_ = strobe;
|
||||
|
||||
if(register_strobe_) {
|
||||
registers_[register_address_] = register_latch_;
|
||||
switch(register_address_) {
|
||||
default: break;
|
||||
case 0: status_ |= uint8_t(CPUFlags::KeyboardDataFull); break;
|
||||
case 7: status_ |= uint8_t(CPUFlags::CommandDataIsValid); break;
|
||||
}
|
||||
} else {
|
||||
register_latch_ = registers_[register_address_];
|
||||
switch(register_address_) {
|
||||
default: break;
|
||||
case 1:
|
||||
registers_[4] &= ~uint8_t(MicrocontrollerFlags::CommandRegisterFull);
|
||||
status_ &= ~uint8_t(CPUFlags::CommandRegisterFull);
|
||||
break;
|
||||
if(!register_strobe_) {
|
||||
if(executor_.get_output_mask(0)) {
|
||||
registers_[register_address_] = register_latch_;
|
||||
switch(register_address_) {
|
||||
default: break;
|
||||
case 0: status_ |= uint8_t(CPUFlags::KeyboardDataFull); break;
|
||||
case 7: status_ |= uint8_t(CPUFlags::CommandDataIsValid); break;
|
||||
}
|
||||
} else {
|
||||
register_latch_ = registers_[register_address_];
|
||||
switch(register_address_) {
|
||||
default: break;
|
||||
case 1:
|
||||
registers_[4] &= ~uint8_t(MicrocontrollerFlags::CommandRegisterFull);
|
||||
status_ &= ~uint8_t(CPUFlags::CommandRegisterFull);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user