From 745afd217fe803a0b2bb73d7e76b908b6570e473 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 7 Aug 2017 19:01:18 -0400 Subject: [PATCH 1/5] The port input/output flags are now honoured; reading a port that is set as an output returns the current output value. --- Components/AY38910/AY38910.cpp | 8 ++++++-- Components/AY38910/AY38910.hpp | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Components/AY38910/AY38910.cpp b/Components/AY38910/AY38910.cpp index 1a3f0b33e..e98395618 100644 --- a/Components/AY38910/AY38910.cpp +++ b/Components/AY38910/AY38910.cpp @@ -226,7 +226,11 @@ uint8_t AY38910::get_register_value() { 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0x00, 0x00 }; - return registers_[selected_register_] | register_masks[selected_register_]; + switch(selected_register_) { + default: return registers_[selected_register_] | register_masks[selected_register_]; + case 14: return (registers_[0x7] & 0x40) ? registers_[14] : port_inputs_[0]; + case 15: return (registers_[0x7] & 0x80) ? registers_[15] : port_inputs_[1]; + } } #pragma mark - Port handling @@ -236,7 +240,7 @@ uint8_t AY38910::get_port_output(bool port_b) { } void AY38910::set_port_input(bool port_b, uint8_t value) { - registers_[port_b ? 15 : 14] = value; + port_inputs_[port_b ? 1 : 0] = value; update_bus(); } diff --git a/Components/AY38910/AY38910.hpp b/Components/AY38910/AY38910.hpp index 8065990de..2c021ed95 100644 --- a/Components/AY38910/AY38910.hpp +++ b/Components/AY38910/AY38910.hpp @@ -59,6 +59,7 @@ class AY38910: public ::Outputs::Filter { private: int selected_register_; uint8_t registers_[16], output_registers_[16]; + uint8_t port_inputs_[2]; int master_divider_; From 7fbb45583659b2c242ef8851271d83cfb7198f22 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 7 Aug 2017 19:07:12 -0400 Subject: [PATCH 2/5] Per the CPC test I'm checking, 0s should be returned for non-retained bits, not 1s. --- Components/AY38910/AY38910.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Components/AY38910/AY38910.cpp b/Components/AY38910/AY38910.cpp index e98395618..4a885e8aa 100644 --- a/Components/AY38910/AY38910.cpp +++ b/Components/AY38910/AY38910.cpp @@ -227,7 +227,7 @@ uint8_t AY38910::get_register_value() { }; switch(selected_register_) { - default: return registers_[selected_register_] | register_masks[selected_register_]; + default: return registers_[selected_register_] & ~register_masks[selected_register_]; case 14: return (registers_[0x7] & 0x40) ? registers_[14] : port_inputs_[0]; case 15: return (registers_[0x7] & 0x80) ? registers_[15] : port_inputs_[1]; } From 4709ae80cbc6e257ced3fd71b020f3a8d8c47a2a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 7 Aug 2017 19:36:55 -0400 Subject: [PATCH 3/5] Added port direction tests. --- Components/8255/i8255.hpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Components/8255/i8255.hpp b/Components/8255/i8255.hpp index e188d669c..256f3d473 100644 --- a/Components/8255/i8255.hpp +++ b/Components/8255/i8255.hpp @@ -46,9 +46,13 @@ template class i8255 { uint8_t get_register(int address) { switch(address & 3) { - case 0: return port_handler_.get_value(0); - case 1: return port_handler_.get_value(1); - case 2: return port_handler_.get_value(2); + case 0: return (control_ & 0x10) ? port_handler_.get_value(0) : outputs_[0]; + case 1: return (control_ & 0x02) ? port_handler_.get_value(1) : outputs_[1]; + case 2: { + if(!(control_ & 0x09)) return outputs_[2]; + uint8_t input = port_handler_.get_value(2); + return ((control_ & 0x01) ? (input & 0x0f) : (outputs_[2] & 0x0f)) | ((control_ & 0x08) ? (input & 0xf0) : (outputs_[2] & 0xf0)); + } case 3: return control_; } return 0xff; From 41a30c147d23a93447d488be03aec72dc9ac4a34 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 7 Aug 2017 19:51:36 -0400 Subject: [PATCH 4/5] Adjusted: invalid register selection simply deselects all registers. --- Components/AY38910/AY38910.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Components/AY38910/AY38910.cpp b/Components/AY38910/AY38910.cpp index 4a885e8aa..683e325c9 100644 --- a/Components/AY38910/AY38910.cpp +++ b/Components/AY38910/AY38910.cpp @@ -169,10 +169,11 @@ void AY38910::evaluate_output_volume() { #pragma mark - Register manipulation void AY38910::select_register(uint8_t r) { - selected_register_ = r & 0xf; + selected_register_ = r; } void AY38910::set_register_value(uint8_t value) { + if(selected_register_ > 15) return; registers_[selected_register_] = value; if(selected_register_ < 14) { int selected_register = selected_register_; @@ -226,6 +227,7 @@ uint8_t AY38910::get_register_value() { 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0x00, 0x00 }; + if(selected_register_ > 15) return 0xff; switch(selected_register_) { default: return registers_[selected_register_] & ~register_masks[selected_register_]; case 14: return (registers_[0x7] & 0x40) ? registers_[14] : port_inputs_[0]; From 390ecec3d9c102ae08a475d90eabbec48a871c9e Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 7 Aug 2017 19:56:22 -0400 Subject: [PATCH 5/5] Added: now declines to pass on output if in input mode for ports A and B. --- Components/8255/i8255.hpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Components/8255/i8255.hpp b/Components/8255/i8255.hpp index 256f3d473..423fc95c2 100644 --- a/Components/8255/i8255.hpp +++ b/Components/8255/i8255.hpp @@ -26,8 +26,17 @@ template class i8255 { void set_register(int address, uint8_t value) { switch(address & 3) { - case 0: outputs_[0] = value; port_handler_.set_value(0, value); break; - case 1: outputs_[1] = value; port_handler_.set_value(1, value); break; + case 0: + if(!(control_ & 0x10)) { + // TODO: so what would output be when switching from input to output mode? + outputs_[0] = value; port_handler_.set_value(0, value); + } + break; + case 1: + if(!(control_ & 0x02)) { + outputs_[1] = value; port_handler_.set_value(1, value); + } + break; case 2: outputs_[2] = value; port_handler_.set_value(2, value); break; case 3: if(value & 0x80) {