1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 18:30:21 +00:00

Standardises on read and write for bus accesses.

Logic being: name these things for the bus action they model, not the effect they have.
This commit is contained in:
Thomas Harte 2020-01-05 13:40:02 -05:00
parent b3f806201b
commit c1bae49a92
31 changed files with 100 additions and 100 deletions

View File

@ -23,7 +23,7 @@ WD1770::WD1770(Personality p) :
posit_event(int(Event1770::Command));
}
void WD1770::set_register(int address, uint8_t value) {
void WD1770::write(int address, uint8_t value) {
switch(address&3) {
case 0: {
if((value&0xf0) == 0xd0) {
@ -54,7 +54,7 @@ void WD1770::set_register(int address, uint8_t value) {
}
}
uint8_t WD1770::get_register(int address) {
uint8_t WD1770::read(int address) {
switch(address&3) {
default: {
update_status([] (Status &status) {

View File

@ -36,10 +36,10 @@ class WD1770: public Storage::Disk::MFMController {
using Storage::Disk::MFMController::set_is_double_density;
/// Writes @c value to the register at @c address. Only the low two bits of the address are decoded.
void set_register(int address, uint8_t value);
void write(int address, uint8_t value);
/// Fetches the value of the register @c address. Only the low two bits of the address are decoded.
uint8_t get_register(int address);
uint8_t read(int address);
/// Runs the controller for @c number_of_cycles cycles.
void run_for(const Cycles cycles);

View File

@ -94,10 +94,10 @@ template <class T> class MOS6522: public MOS6522Storage {
MOS6522(const MOS6522 &) = delete;
/*! Sets a register value. */
void set_register(int address, uint8_t value);
void write(int address, uint8_t value);
/*! Gets a register value. */
uint8_t get_register(int address);
uint8_t read(int address);
/*! @returns the bus handler. */
T &bus_handler();

View File

@ -30,7 +30,7 @@ template <typename T> void MOS6522<T>::access(int address) {
}
}
template <typename T> void MOS6522<T>::set_register(int address, uint8_t value) {
template <typename T> void MOS6522<T>::write(int address, uint8_t value) {
address &= 0xf;
access(address);
switch(address) {
@ -155,7 +155,7 @@ template <typename T> void MOS6522<T>::set_register(int address, uint8_t value)
}
}
template <typename T> uint8_t MOS6522<T>::get_register(int address) {
template <typename T> uint8_t MOS6522<T>::read(int address) {
address &= 0xf;
access(address);
switch(address) {

View File

@ -32,7 +32,7 @@ template <class T> class MOS6532 {
inline void set_ram(uint16_t address, uint8_t value) { ram_[address&0x7f] = value; }
inline uint8_t get_ram(uint16_t address) { return ram_[address & 0x7f]; }
inline void set_register(int address, uint8_t value) {
inline void write(int address, uint8_t value) {
const uint8_t decodedAddress = address & 0x07;
switch(decodedAddress) {
// Port output
@ -63,7 +63,7 @@ template <class T> class MOS6532 {
}
}
inline uint8_t get_register(int address) {
inline uint8_t read(int address) {
const uint8_t decodedAddress = address & 0x7;
switch(decodedAddress) {
// Port input

View File

@ -58,7 +58,7 @@ enum class OutputMode {
To run the VIC for a cycle, the caller should call @c get_address, make the requested bus access
and call @c set_graphics_value with the result.
@c set_register and @c get_register provide register access.
@c write and @c read provide register access.
*/
template <class BusHandler> class MOS6560 {
public:
@ -353,7 +353,7 @@ template <class BusHandler> class MOS6560 {
/*!
Writes to a 6560 register.
*/
void set_register(int address, uint8_t value) {
void write(int address, uint8_t value) {
address &= 0xf;
registers_.direct_values[address] = value;
switch(address) {
@ -417,7 +417,7 @@ template <class BusHandler> class MOS6560 {
/*
Reads from a 6560 register.
*/
uint8_t get_register(int address) {
uint8_t read(int address) {
address &= 0xf;
switch(address) {
default: return registers_.direct_values[address];

View File

@ -27,7 +27,7 @@ template <class T> class i8255 {
Stores the value @c value to the register at @c address. If this causes a change in 8255 output
then the PortHandler will be informed.
*/
void set_register(int address, uint8_t value) {
void write(int address, uint8_t value) {
switch(address & 3) {
case 0:
if(!(control_ & 0x10)) {
@ -60,7 +60,7 @@ template <class T> class i8255 {
Obtains the current value for the register at @c address. If this provides a reading
of input then the PortHandler will be queried.
*/
uint8_t get_register(int address) {
uint8_t read(int address) {
switch(address & 3) {
case 0: return (control_ & 0x10) ? port_handler_.get_value(0) : outputs_[0];
case 1: return (control_ & 0x02) ? port_handler_.get_value(1) : outputs_[1];

View File

@ -163,7 +163,7 @@ void i8272::run_for(Cycles cycles) {
if(is_sleeping_) update_clocking_observer();
}
void i8272::set_register(int address, uint8_t value) {
void i8272::write(int address, uint8_t value) {
// don't consider attempted sets to the status register
if(!address) return;
@ -181,7 +181,7 @@ void i8272::set_register(int address, uint8_t value) {
}
}
uint8_t i8272::get_register(int address) {
uint8_t i8272::read(int address) {
if(address) {
if(result_stack_.empty()) return 0xff;
uint8_t result = result_stack_.back();
@ -865,7 +865,7 @@ void i8272::posit_event(int event_type) {
SetDataRequest();
SetDataDirectionToProcessor();
// The actual stuff of unwinding result_stack_ is handled by ::get_register; wait
// The actual stuff of unwinding result_stack_ is handled by ::read; wait
// until the processor has read all result bytes.
WAIT_FOR_EVENT(Event8272::ResultEmpty);

View File

@ -33,8 +33,8 @@ class i8272 : public Storage::Disk::MFMController {
void set_data_input(uint8_t value);
uint8_t get_data_output();
void set_register(int address, uint8_t value);
uint8_t get_register(int address);
void write(int address, uint8_t value);
uint8_t read(int address);
void set_dma_acknowledge(bool dack);
void set_terminal_count(bool tc);

View File

@ -492,7 +492,7 @@ void Base::output_border(int cycles, uint32_t cram_dot) {
}
}
void TMS9918::set_register(int address, uint8_t value) {
void TMS9918::write(int address, uint8_t value) {
// Writes to address 0 are writes to the video RAM. Store
// the value and return.
if(!(address & 1)) {
@ -670,7 +670,7 @@ void TMS9918::latch_horizontal_counter() {
latched_column_ = write_pointer_.column;
}
uint8_t TMS9918::get_register(int address) {
uint8_t TMS9918::read(int address) {
write_phase_ = false;
// Reads from address 0 read video RAM, via the read-ahead buffer.

View File

@ -54,10 +54,10 @@ class TMS9918: public Base {
void run_for(const HalfCycles cycles);
/*! Sets a register value. */
void set_register(int address, uint8_t value);
void write(int address, uint8_t value);
/*! Gets a register value. */
uint8_t get_register(int address);
uint8_t read(int address);
/*! Gets the current scan line; provided by the Master System only. */
uint8_t get_current_line();
@ -69,8 +69,8 @@ class TMS9918: public Base {
void latch_horizontal_counter();
/*!
Returns the amount of time until get_interrupt_line would next return true if
there are no interceding calls to set_register or get_register.
Returns the amount of time until @c get_interrupt_line would next return true if
there are no interceding calls to @c write or to @c read.
If get_interrupt_line is true now, returns zero. If get_interrupt_line would
never return true, returns -1.

View File

@ -48,7 +48,7 @@ void SN76489::set_sample_volume_range(std::int16_t range) {
evaluate_output_volume();
}
void SN76489::set_register(uint8_t value) {
void SN76489::write(uint8_t value) {
task_queue_.defer([value, this] () {
if(value & 0x80) {
active_register_ = value;

View File

@ -26,7 +26,7 @@ class SN76489: public Outputs::Speaker::SampleSource {
SN76489(Personality personality, Concurrency::DeferringAsyncTaskQueue &task_queue, int additional_divider = 1);
/// Writes a new value to the SN76489.
void set_register(uint8_t value);
void write(uint8_t value);
// As per SampleSource.
void get_samples(std::size_t number_of_samples, std::int16_t *target);

View File

@ -924,14 +924,14 @@ template <bool has_fdc> class ConcreteMachine:
// Check for an 8255 PIO access
if(!(address & 0x800)) {
i8255_.set_register((address >> 8) & 3, *cycle.value);
i8255_.write((address >> 8) & 3, *cycle.value);
}
if constexpr (has_fdc) {
// Check for an FDC access
if((address & 0x580) == 0x100) {
flush_fdc();
fdc_.set_register(address & 1, *cycle.value);
fdc_.write(address & 1, *cycle.value);
}
// Check for a disk motor access
@ -947,14 +947,14 @@ template <bool has_fdc> class ConcreteMachine:
// Check for a PIO access
if(!(address & 0x800)) {
*cycle.value &= i8255_.get_register((address >> 8) & 3);
*cycle.value &= i8255_.read((address >> 8) & 3);
}
// Check for an FDC access
if constexpr (has_fdc) {
if((address & 0x580) == 0x100) {
flush_fdc();
*cycle.value &= fdc_.get_register(address & 1);
*cycle.value &= fdc_.read(address & 1);
}
}

View File

@ -227,9 +227,9 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
// VIA accesses are via address 0xefe1fe + register*512,
// which at word precision is 0x77f0ff + register*256.
if(cycle.operation & Microcycle::Read) {
cycle.value->halves.low = via_.get_register(register_address);
cycle.value->halves.low = via_.read(register_address);
} else {
via_.set_register(register_address, cycle.value->halves.low);
via_.write(register_address, cycle.value->halves.low);
}
if(cycle.operation & Microcycle::SelectWord) cycle.value->halves.high = 0xff;

View File

@ -181,9 +181,9 @@ template<class T> class Cartridge:
if((address&0x1280) == 0x280) {
update_6532();
if(isReadOperation(operation)) {
returnValue &= mos6532_.get_register(address);
returnValue &= mos6532_.read(address);
} else {
mos6532_.set_register(address, *value);
mos6532_.write(address, *value);
}
}

View File

@ -45,7 +45,7 @@ uint16_t DMAController::read(int address) {
if(control_ & Control::CPUTarget) {
return 0xffff;
} else {
return 0xff00 | fdc_.get_register(control_ >> 1);
return 0xff00 | fdc_.read(control_ >> 1);
}
}
break;
@ -78,7 +78,7 @@ void DMAController::write(int address, uint16_t value) {
if(control_ & Control::CPUTarget) {
// TODO: HDC.
} else {
fdc_.set_register(control_ >> 1, uint8_t(value));
fdc_.write(control_ >> 1, uint8_t(value));
}
}
break;
@ -153,7 +153,7 @@ void DMAController::wd1770_did_change_output(WD::WD1770 *) {
// Read from the data register into the active buffer.
if(bytes_received_ < 16) {
buffer_[active_buffer_].contents[bytes_received_] = fdc_.get_register(3);
buffer_[active_buffer_].contents[bytes_received_] = fdc_.read(3);
++bytes_received_;
}
if(bytes_received_ == 16) {

View File

@ -256,7 +256,7 @@ class ConcreteMachine:
case CPU::Z80::PartialMachineCycle::Input:
switch((address >> 5) & 7) {
case 5:
*cycle.value = vdp_->get_register(address);
*cycle.value = vdp_->read(address);
z80_.set_non_maskable_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
@ -299,14 +299,14 @@ class ConcreteMachine:
break;
case 5:
vdp_->set_register(address, *cycle.value);
vdp_->write(address, *cycle.value);
z80_.set_non_maskable_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
case 7:
update_audio();
sn76489_.set_register(*cycle.value);
sn76489_.write(*cycle.value);
break;
default:

View File

@ -86,14 +86,14 @@ Cycles MachineBase::perform_bus_operation(CPU::MOS6502::BusOperation operation,
}
} else if(address >= 0x1800 && address <= 0x180f) {
if(isReadOperation(operation))
*value = serial_port_VIA_.get_register(address);
*value = serial_port_VIA_.read(address);
else
serial_port_VIA_.set_register(address, *value);
serial_port_VIA_.write(address, *value);
} else if(address >= 0x1c00 && address <= 0x1c0f) {
if(isReadOperation(operation))
*value = drive_VIA_.get_register(address);
*value = drive_VIA_.read(address);
else
drive_VIA_.set_register(address, *value);
drive_VIA_.write(address, *value);
}
serial_port_VIA_.run_for(Cycles(1));

View File

@ -503,10 +503,10 @@ class ConcreteMachine:
if((address&0xfc00) == 0x9000) {
if(!(address&0x100)) {
update_video();
result &= mos6560_.get_register(address);
result &= mos6560_.read(address);
}
if(address & 0x10) result &= user_port_via_.get_register(address);
if(address & 0x20) result &= keyboard_via_.get_register(address);
if(address & 0x10) result &= user_port_via_.read(address);
if(address & 0x20) result &= keyboard_via_.read(address);
}
*value = result;
@ -590,12 +590,12 @@ class ConcreteMachine:
// The VIC is selected by bit 8 = 0
if(!(address&0x100)) {
update_video();
mos6560_.set_register(address, *value);
mos6560_.write(address, *value);
}
// The first VIA is selected by bit 4 = 1.
if(address & 0x10) user_port_via_.set_register(address, *value);
if(address & 0x10) user_port_via_.write(address, *value);
// The second VIA is selected by bit 5 = 1.
if(address & 0x20) keyboard_via_.set_register(address, *value);
if(address & 0x20) keyboard_via_.write(address, *value);
}
}

View File

@ -204,7 +204,7 @@ class ConcreteMachine:
case 0xfe0c: case 0xfe0d: case 0xfe0e: case 0xfe0f:
if(!isReadOperation(operation)) {
update_display();
video_output_.set_register(address, *value);
video_output_.write(address, *value);
video_access_range_ = video_output_.get_memory_access_range();
queue_next_display_interrupt();
}
@ -260,9 +260,9 @@ class ConcreteMachine:
set_key_state(KeyShift, false);
}
if(isReadOperation(operation))
*value = plus3_->get_register(address);
*value = plus3_->read(address);
else
plus3_->set_register(address, *value);
plus3_->write(address, *value);
}
break;
case 0xfc00:

View File

@ -250,7 +250,7 @@ void VideoOutput::run_for(const Cycles cycles) {
// MARK: - Register hub
void VideoOutput::set_register(int address, uint8_t value) {
void VideoOutput::write(int address, uint8_t value) {
switch(address & 0xf) {
case 0x02:
start_screen_address_ = (start_screen_address_ & 0xfe00) | static_cast<uint16_t>((value & 0xe0) << 1);

View File

@ -46,7 +46,7 @@ class VideoOutput {
Writes @c value to the register at @c address. May mutate the results of @c get_next_interrupt,
@c get_cycles_until_next_ram_availability and @c get_memory_access_range.
*/
void set_register(int address, uint8_t value);
void write(int address, uint8_t value);
/*!
Describes an interrupt the video hardware will generate by its identity and scheduling time.
@ -62,7 +62,7 @@ class VideoOutput {
The time until signalling returned is the number of cycles after the final one triggered
by the most recent call to @c run_for.
This result may be mutated by calls to @c set_register.
This result may be mutated by calls to @c write.
*/
Interrupt get_next_interrupt();

View File

@ -21,7 +21,7 @@ DiskROM::DiskROM(const std::vector<uint8_t> &rom) :
void DiskROM::write(uint16_t address, uint8_t value, bool pc_is_outside_bios) {
switch(address) {
case 0x7ff8: case 0x7ff9: case 0x7ffa: case 0x7ffb:
set_register(address, value);
WD::WD1770::write(address, value);
break;
case 0x7ffc:
selected_head_ = value & 1;
@ -41,7 +41,7 @@ void DiskROM::write(uint16_t address, uint8_t value, bool pc_is_outside_bios) {
uint8_t DiskROM::read(uint16_t address) {
if(address >= 0x7ff8 && address < 0x7ffc) {
return get_register(address);
return WD::WD1770::read(address);
}
if(address == 0x7fff) {
return (get_data_request_line() ? 0x00 : 0x80) | (get_interrupt_request_line() ? 0x00 : 0x40);

View File

@ -428,7 +428,7 @@ class ConcreteMachine:
// TAPION
// Enable the tape motor.
i8255_.set_register(0xab, 0x8);
i8255_.write(0xab, 0x8);
// Disable interrupts.
z80_.set_value_of_register(CPU::Z80::Register::IFF1, 0);
@ -509,7 +509,7 @@ class ConcreteMachine:
case CPU::Z80::PartialMachineCycle::Input:
switch(address & 0xff) {
case 0x98: case 0x99:
*cycle.value = vdp_->get_register(address);
*cycle.value = vdp_->read(address);
z80_.set_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
@ -523,7 +523,7 @@ class ConcreteMachine:
case 0xa8: case 0xa9:
case 0xaa: case 0xab:
*cycle.value = i8255_.get_register(address);
*cycle.value = i8255_.read(address);
break;
default:
@ -536,7 +536,7 @@ class ConcreteMachine:
const int port = address & 0xff;
switch(port) {
case 0x98: case 0x99:
vdp_->set_register(address, *cycle.value);
vdp_->write(address, *cycle.value);
z80_.set_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
@ -550,7 +550,7 @@ class ConcreteMachine:
case 0xa8: case 0xa9:
case 0xaa: case 0xab:
i8255_.set_register(address, *cycle.value);
i8255_.write(address, *cycle.value);
break;
case 0xfc: case 0xfd: case 0xfe: case 0xff:

View File

@ -240,7 +240,7 @@ class ConcreteMachine:
*cycle.value = vdp_.last_valid()->get_latched_horizontal_counter();
break;
case 0x80: case 0x81:
*cycle.value = vdp_->get_register(address);
*cycle.value = vdp_->read(address);
z80_.set_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;
@ -288,10 +288,10 @@ class ConcreteMachine:
} break;
case 0x40: case 0x41:
update_audio();
sn76489_.set_register(*cycle.value);
sn76489_.write(*cycle.value);
break;
case 0x80: case 0x81:
vdp_->set_register(address, *cycle.value);
vdp_->write(address, *cycle.value);
z80_.set_interrupt_line(vdp_->get_interrupt_line());
time_until_interrupt_ = vdp_->get_time_until_interrupt();
break;

View File

@ -386,16 +386,16 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
} else {
if((address & 0xff00) == 0x0300) {
if(address < 0x0310 || (disk_interface == Analyser::Static::Oric::Target::DiskInterface::None)) {
if(isReadOperation(operation)) *value = via_.get_register(address);
else via_.set_register(address, *value);
if(isReadOperation(operation)) *value = via_.read(address);
else via_.write(address, *value);
} else {
switch(disk_interface) {
default: break;
case Analyser::Static::Oric::Target::DiskInterface::Microdisc:
switch(address) {
case 0x0310: case 0x0311: case 0x0312: case 0x0313:
if(isReadOperation(operation)) *value = microdisc_.get_register(address);
else microdisc_.set_register(address, *value);
if(isReadOperation(operation)) *value = microdisc_.read(address);
else microdisc_.write(address, *value);
break;
case 0x314: case 0x315: case 0x316: case 0x317:
if(isReadOperation(operation)) *value = microdisc_.get_interrupt_request_register();

View File

@ -67,9 +67,9 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableASanStackUseAfterReturn = "YES"
disableMainThreadChecker = "YES"
launchStyle = "0"

View File

@ -53,11 +53,11 @@ class VanillaVIAPortHandler: public MOS::MOS6522::PortHandler {
}
- (void)setValue:(uint8_t)value forRegister:(NSUInteger)registerNumber {
_via->set_register((int)registerNumber, value);
_via->write((int)registerNumber, value);
}
- (uint8_t)valueForRegister:(NSUInteger)registerNumber {
return _via->get_register((int)registerNumber);
return _via->read((int)registerNumber);
}
- (void)runForHalfCycles:(NSUInteger)numberOfHalfCycles {

View File

@ -22,11 +22,11 @@ class VanillaRIOT: public MOS::MOS6532<VanillaRIOT> {
}
- (void)setValue:(uint8_t)value forRegister:(NSUInteger)registerNumber {
_riot.set_register((int)registerNumber, value);
_riot.write((int)registerNumber, value);
}
- (uint8_t)valueForRegister:(NSUInteger)registerNumber {
return _riot.get_register((int)registerNumber);
return _riot.read((int)registerNumber);
}
- (void)runForCycles:(NSUInteger)numberOfCycles {

View File

@ -43,15 +43,15 @@
TI::TMS::TMS9918 vdp(TI::TMS::Personality::SMSVDP);
// Disable end-of-frame interrupts, enable line interrupts.
vdp.set_register(1, 0x00);
vdp.set_register(1, 0x81);
vdp.write(1, 0x00);
vdp.write(1, 0x81);
vdp.set_register(1, 0x10);
vdp.set_register(1, 0x80);
vdp.write(1, 0x10);
vdp.write(1, 0x80);
// Set a line interrupt to occur in five lines.
vdp.set_register(1, 5);
vdp.set_register(1, 0x8a);
vdp.write(1, 5);
vdp.write(1, 0x8a);
// Get time until interrupt.
auto time_until_interrupt = vdp.get_time_until_interrupt().as_integral() - 1;
@ -69,7 +69,7 @@
NSAssert(vdp.get_interrupt_line(), @"Interrupt line wasn't set when promised [1]");
// Read the status register to clear interrupt status.
vdp.get_register(1);
vdp.read(1);
NSAssert(!vdp.get_interrupt_line(), @"Interrupt wasn't reset by status read");
// Check interrupt flag isn't set prior to the reported time.
@ -86,20 +86,20 @@
TI::TMS::TMS9918 vdp(TI::TMS::Personality::SMSVDP);
// Disable end-of-frame interrupts, enable line interrupts, set an interrupt to occur every line.
vdp.set_register(1, 0x00);
vdp.set_register(1, 0x81);
vdp.write(1, 0x00);
vdp.write(1, 0x81);
vdp.set_register(1, 0x10);
vdp.set_register(1, 0x80);
vdp.write(1, 0x10);
vdp.write(1, 0x80);
vdp.set_register(1, 0);
vdp.set_register(1, 0x8a);
vdp.write(1, 0);
vdp.write(1, 0x8a);
// Advance to outside of the counted area.
while(vdp.get_current_line() < 200) vdp.run_for(Cycles(228));
// Clear the pending interrupt and ask about the next one (i.e. the first one).
vdp.get_register(1);
vdp.read(1);
auto time_until_interrupt = vdp.get_time_until_interrupt().as_integral() - 1;
// Check that an interrupt is now scheduled.
@ -121,16 +121,16 @@
for(int c = 0; c < 256; ++c) {
for(int with_eof = (c < 192) ? 0 : 1; with_eof < 2; ++with_eof) {
// Enable or disable end-of-frame interrupts as required.
vdp.set_register(1, with_eof ? 0x20 : 0x00);
vdp.set_register(1, 0x81);
vdp.write(1, with_eof ? 0x20 : 0x00);
vdp.write(1, 0x81);
// Enable line interrupts.
vdp.set_register(1, 0x10);
vdp.set_register(1, 0x80);
vdp.write(1, 0x10);
vdp.write(1, 0x80);
// Set the line interrupt timing as desired.
vdp.set_register(1, c);
vdp.set_register(1, 0x8a);
vdp.write(1, c);
vdp.write(1, 0x8a);
// Now run through an entire frame...
int half_cycles = 262*228*2;
@ -138,7 +138,7 @@
while(half_cycles--) {
// Validate that an interrupt happened if one was expected, and clear anything that's present.
NSAssert(vdp.get_interrupt_line() == (last_time_until_interrupt == 0), @"Unexpected interrupt state change; expected %d but got %d; position %d %d @ %d", (last_time_until_interrupt == 0), vdp.get_interrupt_line(), c, with_eof, half_cycles);
vdp.get_register(1);
vdp.read(1);
vdp.run_for(HalfCycles(1));