1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-24 12:29:06 +00:00

The inversion of truth was clearly just a problematic API. Got explicit. LineLevel might need to become more pervasive.

This commit is contained in:
Thomas Harte 2016-07-07 06:44:13 -04:00
parent dcb86a027a
commit c9479f923b
4 changed files with 35 additions and 30 deletions

View File

@ -35,8 +35,8 @@ class SerialPortVIA: public MOS::MOS6522<SerialPortVIA>, public MOS::MOS6522IRQD
std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock();
if(serialPort) { if(serialPort) {
// serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x10)); // serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x10));
serialPort->set_output(::Commodore::Serial::Line::Clock, !(value&0x08)); serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)(value&0x08));
serialPort->set_output(::Commodore::Serial::Line::Data, !(value&0x02)); serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)(value&0x02));
} }
// printf("1540 serial port VIA port B: %02x\n", value); // printf("1540 serial port VIA port B: %02x\n", value);
} }
@ -48,11 +48,11 @@ class SerialPortVIA: public MOS::MOS6522<SerialPortVIA>, public MOS::MOS6522IRQD
// printf("1540 Serial port line %d: %s\n", line, value ? "on" : "off"); // printf("1540 Serial port line %d: %s\n", line, value ? "on" : "off");
switch(line) { switch(line) {
default: break; default: break;
case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x00 : 0x01); break; case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x01 : 0x00); break;
case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x00 : 0x04); break; case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x04 : 0x00); break;
case ::Commodore::Serial::Line::Attention: case ::Commodore::Serial::Line::Attention:
_portB = (_portB & ~0x80) | (value ? 0 : 0x80); _portB = (_portB & ~0x80) | (value ? 0x80 : 0x00);
set_control_line_input(Port::A, Line::One, !value); // truth here is active low; my 6522 takes true to be high set_control_line_input(Port::A, Line::One, value);
break; break;
} }
} }
@ -77,9 +77,9 @@ class DriveVIA: public MOS::MOS6522<DriveVIA>, public MOS::MOS6522IRQDelegate {
class SerialPort : public ::Commodore::Serial::Port { class SerialPort : public ::Commodore::Serial::Port {
public: public:
void set_input(::Commodore::Serial::Line line, bool value) { void set_input(::Commodore::Serial::Line line, ::Commodore::Serial::LineLevel level) {
std::shared_ptr<SerialPortVIA> serialPortVIA = _serialPortVIA.lock(); std::shared_ptr<SerialPortVIA> serialPortVIA = _serialPortVIA.lock();
if(serialPortVIA) serialPortVIA->set_serial_line_state(line, value); if(serialPortVIA) serialPortVIA->set_serial_line_state(line, (bool)level);
} }
void set_serial_port_via(std::shared_ptr<SerialPortVIA> serialPortVIA) { void set_serial_port_via(std::shared_ptr<SerialPortVIA> serialPortVIA) {

View File

@ -31,35 +31,35 @@ void Bus::add_port(std::shared_ptr<Port> port)
set_line_output_did_change((Line)line); set_line_output_did_change((Line)line);
// ... but the new device will need to be told the current state regardless // ... but the new device will need to be told the current state regardless
port->set_input((Line)line, _line_values[line]); port->set_input((Line)line, _line_levels[line]);
} }
} }
void Bus::set_line_output_did_change(Line line) void Bus::set_line_output_did_change(Line line)
{ {
// i.e. I believe these lines to be open collector, active low // i.e. I believe these lines to be open collector
bool new_line_value = false; LineLevel new_line_level = High;
for(std::weak_ptr<Port> port : _ports) for(std::weak_ptr<Port> port : _ports)
{ {
std::shared_ptr<Port> locked_port = port.lock(); std::shared_ptr<Port> locked_port = port.lock();
if(locked_port) if(locked_port)
{ {
new_line_value |= locked_port->get_output(line); new_line_level = (LineLevel)((bool)new_line_level & (bool)locked_port->get_output(line));
} }
} }
// post an update only if one occurred // post an update only if one occurred
if(new_line_value != _line_values[line]) if(new_line_level != _line_levels[line])
{ {
printf("[Bus] %s is %s\n", StringForLine(line), new_line_value ? "true" : "false"); printf("[Bus] %s is %s\n", StringForLine(line), new_line_level ? "high" : "low");
_line_values[line] = new_line_value; _line_levels[line] = new_line_level;
for(std::weak_ptr<Port> port : _ports) for(std::weak_ptr<Port> port : _ports)
{ {
std::shared_ptr<Port> locked_port = port.lock(); std::shared_ptr<Port> locked_port = port.lock();
if(locked_port) if(locked_port)
{ {
locked_port->set_input(line, new_line_value); locked_port->set_input(line, new_line_level);
} }
} }
} }

View File

@ -22,37 +22,42 @@ namespace Serial {
Reset Reset
}; };
enum LineLevel: bool {
High = true,
Low = false
};
const char *StringForLine(Line line); const char *StringForLine(Line line);
class Port; class Port;
class Bus { class Bus {
public: public:
Bus() : _line_values{false, false, false, false, false} {} Bus() : _line_levels{High, High, High, High, High} {}
void add_port(std::shared_ptr<Port> port); void add_port(std::shared_ptr<Port> port);
void set_line_output_did_change(Line line); void set_line_output_did_change(Line line);
private: private:
bool _line_values[5]; LineLevel _line_levels[5];
std::vector<std::weak_ptr<Port>> _ports; std::vector<std::weak_ptr<Port>> _ports;
}; };
class Port { class Port {
public: public:
Port() : _line_values{false, false, false, false, false} {} Port() : _line_levels{High, High, High, High, High} {}
void set_output(Line line, bool value) { void set_output(Line line, LineLevel level) {
_line_values[line] = value; _line_levels[line] = level;
std::shared_ptr<Bus> bus = _serial_bus.lock(); std::shared_ptr<Bus> bus = _serial_bus.lock();
if(bus) bus->set_line_output_did_change(line); if(bus) bus->set_line_output_did_change(line);
} }
bool get_output(Line line) { LineLevel get_output(Line line) {
return _line_values[line]; return _line_levels[line];
} }
virtual void set_input(Line line, bool value) = 0; virtual void set_input(Line line, LineLevel value) = 0;
inline void set_serial_bus(std::shared_ptr<Bus> serial_bus) { inline void set_serial_bus(std::shared_ptr<Bus> serial_bus) {
_serial_bus = serial_bus; _serial_bus = serial_bus;
@ -60,7 +65,7 @@ namespace Serial {
private: private:
std::weak_ptr<Bus> _serial_bus; std::weak_ptr<Bus> _serial_bus;
bool _line_values[5]; LineLevel _line_levels[5];
}; };
} }

View File

@ -95,7 +95,7 @@ class UserPortVIA: public MOS::MOS6522<UserPortVIA>, public MOS::MOS6522IRQDeleg
if(!port) { if(!port) {
std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock();
if(serialPort) if(serialPort)
serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x80)); serialPort->set_output(::Commodore::Serial::Line::Attention, (::Commodore::Serial::LineLevel)(value&0x80));
} }
} }
@ -154,9 +154,9 @@ class KeyboardVIA: public MOS::MOS6522<KeyboardVIA>, public MOS::MOS6522IRQDeleg
std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock();
if(serialPort) { if(serialPort) {
if(port == Port::A) { if(port == Port::A) {
serialPort->set_output(::Commodore::Serial::Line::Clock, value); serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)value);
} else { } else {
serialPort->set_output(::Commodore::Serial::Line::Data, value); serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)value);
} }
} }
} }
@ -184,9 +184,9 @@ class KeyboardVIA: public MOS::MOS6522<KeyboardVIA>, public MOS::MOS6522IRQDeleg
class SerialPort : public ::Commodore::Serial::Port { class SerialPort : public ::Commodore::Serial::Port {
public: public:
void set_input(::Commodore::Serial::Line line, bool value) { void set_input(::Commodore::Serial::Line line, ::Commodore::Serial::LineLevel level) {
std::shared_ptr<UserPortVIA> userPortVIA = _userPortVIA.lock(); std::shared_ptr<UserPortVIA> userPortVIA = _userPortVIA.lock();
if(userPortVIA) userPortVIA->set_serial_line_state(line, value); if(userPortVIA) userPortVIA->set_serial_line_state(line, (bool)level);
} }
void set_user_port_via(std::shared_ptr<UserPortVIA> userPortVIA) { void set_user_port_via(std::shared_ptr<UserPortVIA> userPortVIA) {