1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +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();
if(serialPort) {
// serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x10));
serialPort->set_output(::Commodore::Serial::Line::Clock, !(value&0x08));
serialPort->set_output(::Commodore::Serial::Line::Data, !(value&0x02));
serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)(value&0x08));
serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)(value&0x02));
}
// 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");
switch(line) {
default: break;
case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x00 : 0x01); break;
case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x00 : 0x04); break;
case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x01 : 0x00); break;
case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x04 : 0x00); break;
case ::Commodore::Serial::Line::Attention:
_portB = (_portB & ~0x80) | (value ? 0 : 0x80);
set_control_line_input(Port::A, Line::One, !value); // truth here is active low; my 6522 takes true to be high
_portB = (_portB & ~0x80) | (value ? 0x80 : 0x00);
set_control_line_input(Port::A, Line::One, value);
break;
}
}
@ -77,9 +77,9 @@ class DriveVIA: public MOS::MOS6522<DriveVIA>, public MOS::MOS6522IRQDelegate {
class SerialPort : public ::Commodore::Serial::Port {
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();
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) {

View File

@ -31,35 +31,35 @@ void Bus::add_port(std::shared_ptr<Port> port)
set_line_output_did_change((Line)line);
// ... 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)
{
// i.e. I believe these lines to be open collector, active low
bool new_line_value = false;
// i.e. I believe these lines to be open collector
LineLevel new_line_level = High;
for(std::weak_ptr<Port> port : _ports)
{
std::shared_ptr<Port> locked_port = port.lock();
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
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");
_line_values[line] = new_line_value;
printf("[Bus] %s is %s\n", StringForLine(line), new_line_level ? "high" : "low");
_line_levels[line] = new_line_level;
for(std::weak_ptr<Port> port : _ports)
{
std::shared_ptr<Port> locked_port = port.lock();
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
};
enum LineLevel: bool {
High = true,
Low = false
};
const char *StringForLine(Line line);
class Port;
class Bus {
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 set_line_output_did_change(Line line);
private:
bool _line_values[5];
LineLevel _line_levels[5];
std::vector<std::weak_ptr<Port>> _ports;
};
class Port {
public:
Port() : _line_values{false, false, false, false, false} {}
Port() : _line_levels{High, High, High, High, High} {}
void set_output(Line line, bool value) {
_line_values[line] = value;
void set_output(Line line, LineLevel level) {
_line_levels[line] = level;
std::shared_ptr<Bus> bus = _serial_bus.lock();
if(bus) bus->set_line_output_did_change(line);
}
bool get_output(Line line) {
return _line_values[line];
LineLevel get_output(Line 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) {
_serial_bus = serial_bus;
@ -60,7 +65,7 @@ namespace Serial {
private:
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) {
std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock();
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();
if(serialPort) {
if(port == Port::A) {
serialPort->set_output(::Commodore::Serial::Line::Clock, value);
serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)value);
} 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 {
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();
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) {