mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-26 15:32:04 +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:
parent
dcb86a027a
commit
c9479f923b
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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];
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user