1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Added overflow-flag setting logic and ensured disk ROM gets through regardless of ROM/disk installation order.

This commit is contained in:
Thomas Harte 2016-07-31 19:33:18 -04:00
parent 0945049cd3
commit 740ea0b7e2
5 changed files with 55 additions and 2 deletions

View File

@ -39,6 +39,10 @@ void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bu
unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value)
{ {
// static bool log = false;
// if(operation == CPU6502::BusOperation::ReadOpcode) printf("%04x\n", address);
// if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xf3be)) log = true;
// if(operation == CPU6502::BusOperation::ReadOpcode && log) printf("%04x\n", address);
// if(operation == CPU6502::BusOperation::ReadOpcode && (address >= 0xF556 && address <= 0xF56D)) printf("%04x\n", address); // if(operation == CPU6502::BusOperation::ReadOpcode && (address >= 0xF556 && address <= 0xF56D)) printf("%04x\n", address);
// if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xE887)) printf("A: %02x\n", get_value_of_register(CPU6502::Register::A)); // if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xE887)) printf("A: %02x\n", get_value_of_register(CPU6502::Register::A));
@ -123,7 +127,13 @@ void Machine::process_input_bit(int value, unsigned int cycles_since_index_hole)
{ {
_driveVIA.set_data_input((uint8_t)_shift_register); _driveVIA.set_data_input((uint8_t)_shift_register);
_bit_window_offset = 0; _bit_window_offset = 0;
if(_driveVIA.get_should_set_overflow())
{
set_overflow_line(true);
}
} }
else
set_overflow_line(false);
} }
// the 1540 does not recognise index holes // the 1540 does not recognise index holes

View File

@ -132,6 +132,16 @@ class DriveVIA: public MOS::MOS6522<DriveVIA>, public MOS::MOS6522IRQDelegate {
_port_a = value; _port_a = value;
} }
bool get_should_set_overflow() {
return _should_set_overflow;
}
void set_control_line_output(Port port, Line line, bool value) {
if(port == Port::A && line == Line::Two) {
_should_set_overflow = value;
}
}
void set_port_output(Port port, uint8_t value, uint8_t direction_mask) { void set_port_output(Port port, uint8_t value, uint8_t direction_mask) {
if(port) if(port)
{ {
@ -147,6 +157,7 @@ class DriveVIA: public MOS::MOS6522<DriveVIA>, public MOS::MOS6522IRQDelegate {
private: private:
uint8_t _port_b, _port_a; uint8_t _port_b, _port_a;
bool _should_set_overflow;
}; };
/*! /*!

View File

@ -169,6 +169,11 @@ void Machine::set_rom(ROMSlot slot, size_t length, const uint8_t *data)
_c1540->set_rom(data); _c1540->set_rom(data);
_c1540->run_for_cycles(2000000); // pretend it booted a couple of seconds ago _c1540->run_for_cycles(2000000); // pretend it booted a couple of seconds ago
} }
else
{
_driveROM.reset(new uint8_t[length]);
memcpy(_driveROM.get(), data, length);
}
return; return;
} }
@ -221,6 +226,13 @@ void Machine::set_disk(std::shared_ptr<Storage::Disk> disk)
// hand it the disk // hand it the disk
_c1540->set_disk(disk); _c1540->set_disk(disk);
// install the ROM if it was previously set
if(_driveROM)
{
_c1540->set_rom(_driveROM.get());
_driveROM.reset();
}
} }
#pragma mark - Typer #pragma mark - Typer

View File

@ -287,6 +287,7 @@ class Machine:
uint8_t _screenMemory[0x1000]; uint8_t _screenMemory[0x1000];
uint8_t _colorMemory[0x0400]; uint8_t _colorMemory[0x0400];
uint8_t _junkMemory[0x0400]; uint8_t _junkMemory[0x0400];
std::unique_ptr<uint8_t> _driveROM;
uint8_t *_videoMemoryMap[16]; uint8_t *_videoMemoryMap[16];
uint8_t *_processorReadMemoryMap[64]; uint8_t *_processorReadMemoryMap[64];

View File

@ -472,6 +472,7 @@ template <class T> class Processor {
bool _ready_line_is_enabled; bool _ready_line_is_enabled;
bool _irq_line_is_enabled, _irq_request_history; bool _irq_line_is_enabled, _irq_request_history;
bool _nmi_line_is_enabled, _set_overflow_line_is_enabled;
/*! /*!
Gets the program representing an RST response. Gets the program representing an RST response.
@ -549,7 +550,10 @@ template <class T> class Processor {
_interruptFlag(Flag::Interrupt), _interruptFlag(Flag::Interrupt),
_s(0), _s(0),
_nextBusOperation(BusOperation::None), _nextBusOperation(BusOperation::None),
_interrupt_requests(InterruptRequestFlags::PowerOn) _interrupt_requests(InterruptRequestFlags::PowerOn),
_irq_line_is_enabled(false),
_nmi_line_is_enabled(false),
_set_overflow_line_is_enabled(false)
{ {
// only the interrupt flag is defined upon reset but get_flags isn't going to // only the interrupt flag is defined upon reset but get_flags isn't going to
// mask the other flags so we need to do that, at least // mask the other flags so we need to do that, at least
@ -1237,6 +1241,19 @@ template <class T> class Processor {
_irq_line_is_enabled = active; _irq_line_is_enabled = active;
} }
/*!
Sets the current level of the set overflow line.
@param active @c true if the line is logically active; @c false otherwise.
*/
inline void set_overflow_line(bool active)
{
// a leading edge will set the overflow flag
if(active && !_set_overflow_line_is_enabled)
_overflowFlag = Flag::Overflow;
_set_overflow_line_is_enabled = active;
}
/*! /*!
Sets the current level of the NMI line. Sets the current level of the NMI line.
@ -1245,7 +1262,9 @@ template <class T> class Processor {
inline void set_nmi_line(bool active) inline void set_nmi_line(bool active)
{ {
// NMI is edge triggered, not level // NMI is edge triggered, not level
_interrupt_requests |= (active ? InterruptRequestFlags::NMI : 0); if(active && !_nmi_line_is_enabled)
_interrupt_requests |= InterruptRequestFlags::NMI;
_nmi_line_is_enabled = active;
} }
/*! /*!