mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-26 09:29:45 +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:
parent
b3f806201b
commit
c1bae49a92
@ -23,7 +23,7 @@ WD1770::WD1770(Personality p) :
|
|||||||
posit_event(int(Event1770::Command));
|
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) {
|
switch(address&3) {
|
||||||
case 0: {
|
case 0: {
|
||||||
if((value&0xf0) == 0xd0) {
|
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) {
|
switch(address&3) {
|
||||||
default: {
|
default: {
|
||||||
update_status([] (Status &status) {
|
update_status([] (Status &status) {
|
||||||
|
@ -36,10 +36,10 @@ class WD1770: public Storage::Disk::MFMController {
|
|||||||
using Storage::Disk::MFMController::set_is_double_density;
|
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.
|
/// 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.
|
/// 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.
|
/// Runs the controller for @c number_of_cycles cycles.
|
||||||
void run_for(const Cycles cycles);
|
void run_for(const Cycles cycles);
|
||||||
|
@ -94,10 +94,10 @@ template <class T> class MOS6522: public MOS6522Storage {
|
|||||||
MOS6522(const MOS6522 &) = delete;
|
MOS6522(const MOS6522 &) = delete;
|
||||||
|
|
||||||
/*! Sets a register value. */
|
/*! Sets a register value. */
|
||||||
void set_register(int address, uint8_t value);
|
void write(int address, uint8_t value);
|
||||||
|
|
||||||
/*! Gets a register value. */
|
/*! Gets a register value. */
|
||||||
uint8_t get_register(int address);
|
uint8_t read(int address);
|
||||||
|
|
||||||
/*! @returns the bus handler. */
|
/*! @returns the bus handler. */
|
||||||
T &bus_handler();
|
T &bus_handler();
|
||||||
|
@ -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;
|
address &= 0xf;
|
||||||
access(address);
|
access(address);
|
||||||
switch(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;
|
address &= 0xf;
|
||||||
access(address);
|
access(address);
|
||||||
switch(address) {
|
switch(address) {
|
||||||
|
@ -32,7 +32,7 @@ template <class T> class MOS6532 {
|
|||||||
inline void set_ram(uint16_t address, uint8_t value) { ram_[address&0x7f] = value; }
|
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 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;
|
const uint8_t decodedAddress = address & 0x07;
|
||||||
switch(decodedAddress) {
|
switch(decodedAddress) {
|
||||||
// Port output
|
// 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;
|
const uint8_t decodedAddress = address & 0x7;
|
||||||
switch(decodedAddress) {
|
switch(decodedAddress) {
|
||||||
// Port input
|
// Port input
|
||||||
|
@ -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
|
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.
|
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 {
|
template <class BusHandler> class MOS6560 {
|
||||||
public:
|
public:
|
||||||
@ -353,7 +353,7 @@ template <class BusHandler> class MOS6560 {
|
|||||||
/*!
|
/*!
|
||||||
Writes to a 6560 register.
|
Writes to a 6560 register.
|
||||||
*/
|
*/
|
||||||
void set_register(int address, uint8_t value) {
|
void write(int address, uint8_t value) {
|
||||||
address &= 0xf;
|
address &= 0xf;
|
||||||
registers_.direct_values[address] = value;
|
registers_.direct_values[address] = value;
|
||||||
switch(address) {
|
switch(address) {
|
||||||
@ -417,7 +417,7 @@ template <class BusHandler> class MOS6560 {
|
|||||||
/*
|
/*
|
||||||
Reads from a 6560 register.
|
Reads from a 6560 register.
|
||||||
*/
|
*/
|
||||||
uint8_t get_register(int address) {
|
uint8_t read(int address) {
|
||||||
address &= 0xf;
|
address &= 0xf;
|
||||||
switch(address) {
|
switch(address) {
|
||||||
default: return registers_.direct_values[address];
|
default: return registers_.direct_values[address];
|
||||||
|
@ -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
|
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.
|
then the PortHandler will be informed.
|
||||||
*/
|
*/
|
||||||
void set_register(int address, uint8_t value) {
|
void write(int address, uint8_t value) {
|
||||||
switch(address & 3) {
|
switch(address & 3) {
|
||||||
case 0:
|
case 0:
|
||||||
if(!(control_ & 0x10)) {
|
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
|
Obtains the current value for the register at @c address. If this provides a reading
|
||||||
of input then the PortHandler will be queried.
|
of input then the PortHandler will be queried.
|
||||||
*/
|
*/
|
||||||
uint8_t get_register(int address) {
|
uint8_t read(int address) {
|
||||||
switch(address & 3) {
|
switch(address & 3) {
|
||||||
case 0: return (control_ & 0x10) ? port_handler_.get_value(0) : outputs_[0];
|
case 0: return (control_ & 0x10) ? port_handler_.get_value(0) : outputs_[0];
|
||||||
case 1: return (control_ & 0x02) ? port_handler_.get_value(1) : outputs_[1];
|
case 1: return (control_ & 0x02) ? port_handler_.get_value(1) : outputs_[1];
|
||||||
|
@ -163,7 +163,7 @@ void i8272::run_for(Cycles cycles) {
|
|||||||
if(is_sleeping_) update_clocking_observer();
|
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
|
// don't consider attempted sets to the status register
|
||||||
if(!address) return;
|
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(address) {
|
||||||
if(result_stack_.empty()) return 0xff;
|
if(result_stack_.empty()) return 0xff;
|
||||||
uint8_t result = result_stack_.back();
|
uint8_t result = result_stack_.back();
|
||||||
@ -865,7 +865,7 @@ void i8272::posit_event(int event_type) {
|
|||||||
SetDataRequest();
|
SetDataRequest();
|
||||||
SetDataDirectionToProcessor();
|
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.
|
// until the processor has read all result bytes.
|
||||||
WAIT_FOR_EVENT(Event8272::ResultEmpty);
|
WAIT_FOR_EVENT(Event8272::ResultEmpty);
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ class i8272 : public Storage::Disk::MFMController {
|
|||||||
void set_data_input(uint8_t value);
|
void set_data_input(uint8_t value);
|
||||||
uint8_t get_data_output();
|
uint8_t get_data_output();
|
||||||
|
|
||||||
void set_register(int address, uint8_t value);
|
void write(int address, uint8_t value);
|
||||||
uint8_t get_register(int address);
|
uint8_t read(int address);
|
||||||
|
|
||||||
void set_dma_acknowledge(bool dack);
|
void set_dma_acknowledge(bool dack);
|
||||||
void set_terminal_count(bool tc);
|
void set_terminal_count(bool tc);
|
||||||
|
@ -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
|
// Writes to address 0 are writes to the video RAM. Store
|
||||||
// the value and return.
|
// the value and return.
|
||||||
if(!(address & 1)) {
|
if(!(address & 1)) {
|
||||||
@ -670,7 +670,7 @@ void TMS9918::latch_horizontal_counter() {
|
|||||||
latched_column_ = write_pointer_.column;
|
latched_column_ = write_pointer_.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t TMS9918::get_register(int address) {
|
uint8_t TMS9918::read(int address) {
|
||||||
write_phase_ = false;
|
write_phase_ = false;
|
||||||
|
|
||||||
// Reads from address 0 read video RAM, via the read-ahead buffer.
|
// Reads from address 0 read video RAM, via the read-ahead buffer.
|
||||||
|
@ -54,10 +54,10 @@ class TMS9918: public Base {
|
|||||||
void run_for(const HalfCycles cycles);
|
void run_for(const HalfCycles cycles);
|
||||||
|
|
||||||
/*! Sets a register value. */
|
/*! Sets a register value. */
|
||||||
void set_register(int address, uint8_t value);
|
void write(int address, uint8_t value);
|
||||||
|
|
||||||
/*! Gets a register 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. */
|
/*! Gets the current scan line; provided by the Master System only. */
|
||||||
uint8_t get_current_line();
|
uint8_t get_current_line();
|
||||||
@ -69,8 +69,8 @@ class TMS9918: public Base {
|
|||||||
void latch_horizontal_counter();
|
void latch_horizontal_counter();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the amount of time until get_interrupt_line would next return true if
|
Returns the amount of time until @c get_interrupt_line would next return true if
|
||||||
there are no interceding calls to set_register or get_register.
|
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
|
If get_interrupt_line is true now, returns zero. If get_interrupt_line would
|
||||||
never return true, returns -1.
|
never return true, returns -1.
|
||||||
|
@ -48,7 +48,7 @@ void SN76489::set_sample_volume_range(std::int16_t range) {
|
|||||||
evaluate_output_volume();
|
evaluate_output_volume();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SN76489::set_register(uint8_t value) {
|
void SN76489::write(uint8_t value) {
|
||||||
task_queue_.defer([value, this] () {
|
task_queue_.defer([value, this] () {
|
||||||
if(value & 0x80) {
|
if(value & 0x80) {
|
||||||
active_register_ = value;
|
active_register_ = value;
|
||||||
|
@ -26,7 +26,7 @@ class SN76489: public Outputs::Speaker::SampleSource {
|
|||||||
SN76489(Personality personality, Concurrency::DeferringAsyncTaskQueue &task_queue, int additional_divider = 1);
|
SN76489(Personality personality, Concurrency::DeferringAsyncTaskQueue &task_queue, int additional_divider = 1);
|
||||||
|
|
||||||
/// Writes a new value to the SN76489.
|
/// Writes a new value to the SN76489.
|
||||||
void set_register(uint8_t value);
|
void write(uint8_t value);
|
||||||
|
|
||||||
// As per SampleSource.
|
// As per SampleSource.
|
||||||
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
||||||
|
@ -924,14 +924,14 @@ template <bool has_fdc> class ConcreteMachine:
|
|||||||
|
|
||||||
// Check for an 8255 PIO access
|
// Check for an 8255 PIO access
|
||||||
if(!(address & 0x800)) {
|
if(!(address & 0x800)) {
|
||||||
i8255_.set_register((address >> 8) & 3, *cycle.value);
|
i8255_.write((address >> 8) & 3, *cycle.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (has_fdc) {
|
if constexpr (has_fdc) {
|
||||||
// Check for an FDC access
|
// Check for an FDC access
|
||||||
if((address & 0x580) == 0x100) {
|
if((address & 0x580) == 0x100) {
|
||||||
flush_fdc();
|
flush_fdc();
|
||||||
fdc_.set_register(address & 1, *cycle.value);
|
fdc_.write(address & 1, *cycle.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for a disk motor access
|
// Check for a disk motor access
|
||||||
@ -947,14 +947,14 @@ template <bool has_fdc> class ConcreteMachine:
|
|||||||
|
|
||||||
// Check for a PIO access
|
// Check for a PIO access
|
||||||
if(!(address & 0x800)) {
|
if(!(address & 0x800)) {
|
||||||
*cycle.value &= i8255_.get_register((address >> 8) & 3);
|
*cycle.value &= i8255_.read((address >> 8) & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for an FDC access
|
// Check for an FDC access
|
||||||
if constexpr (has_fdc) {
|
if constexpr (has_fdc) {
|
||||||
if((address & 0x580) == 0x100) {
|
if((address & 0x580) == 0x100) {
|
||||||
flush_fdc();
|
flush_fdc();
|
||||||
*cycle.value &= fdc_.get_register(address & 1);
|
*cycle.value &= fdc_.read(address & 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,9 +227,9 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
// VIA accesses are via address 0xefe1fe + register*512,
|
// VIA accesses are via address 0xefe1fe + register*512,
|
||||||
// which at word precision is 0x77f0ff + register*256.
|
// which at word precision is 0x77f0ff + register*256.
|
||||||
if(cycle.operation & Microcycle::Read) {
|
if(cycle.operation & Microcycle::Read) {
|
||||||
cycle.value->halves.low = via_.get_register(register_address);
|
cycle.value->halves.low = via_.read(register_address);
|
||||||
} else {
|
} 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;
|
if(cycle.operation & Microcycle::SelectWord) cycle.value->halves.high = 0xff;
|
||||||
|
@ -181,9 +181,9 @@ template<class T> class Cartridge:
|
|||||||
if((address&0x1280) == 0x280) {
|
if((address&0x1280) == 0x280) {
|
||||||
update_6532();
|
update_6532();
|
||||||
if(isReadOperation(operation)) {
|
if(isReadOperation(operation)) {
|
||||||
returnValue &= mos6532_.get_register(address);
|
returnValue &= mos6532_.read(address);
|
||||||
} else {
|
} else {
|
||||||
mos6532_.set_register(address, *value);
|
mos6532_.write(address, *value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ uint16_t DMAController::read(int address) {
|
|||||||
if(control_ & Control::CPUTarget) {
|
if(control_ & Control::CPUTarget) {
|
||||||
return 0xffff;
|
return 0xffff;
|
||||||
} else {
|
} else {
|
||||||
return 0xff00 | fdc_.get_register(control_ >> 1);
|
return 0xff00 | fdc_.read(control_ >> 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -78,7 +78,7 @@ void DMAController::write(int address, uint16_t value) {
|
|||||||
if(control_ & Control::CPUTarget) {
|
if(control_ & Control::CPUTarget) {
|
||||||
// TODO: HDC.
|
// TODO: HDC.
|
||||||
} else {
|
} else {
|
||||||
fdc_.set_register(control_ >> 1, uint8_t(value));
|
fdc_.write(control_ >> 1, uint8_t(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -153,7 +153,7 @@ void DMAController::wd1770_did_change_output(WD::WD1770 *) {
|
|||||||
|
|
||||||
// Read from the data register into the active buffer.
|
// Read from the data register into the active buffer.
|
||||||
if(bytes_received_ < 16) {
|
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_;
|
++bytes_received_;
|
||||||
}
|
}
|
||||||
if(bytes_received_ == 16) {
|
if(bytes_received_ == 16) {
|
||||||
|
@ -256,7 +256,7 @@ class ConcreteMachine:
|
|||||||
case CPU::Z80::PartialMachineCycle::Input:
|
case CPU::Z80::PartialMachineCycle::Input:
|
||||||
switch((address >> 5) & 7) {
|
switch((address >> 5) & 7) {
|
||||||
case 5:
|
case 5:
|
||||||
*cycle.value = vdp_->get_register(address);
|
*cycle.value = vdp_->read(address);
|
||||||
z80_.set_non_maskable_interrupt_line(vdp_->get_interrupt_line());
|
z80_.set_non_maskable_interrupt_line(vdp_->get_interrupt_line());
|
||||||
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
||||||
break;
|
break;
|
||||||
@ -299,14 +299,14 @@ class ConcreteMachine:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
vdp_->set_register(address, *cycle.value);
|
vdp_->write(address, *cycle.value);
|
||||||
z80_.set_non_maskable_interrupt_line(vdp_->get_interrupt_line());
|
z80_.set_non_maskable_interrupt_line(vdp_->get_interrupt_line());
|
||||||
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
update_audio();
|
update_audio();
|
||||||
sn76489_.set_register(*cycle.value);
|
sn76489_.write(*cycle.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -86,14 +86,14 @@ Cycles MachineBase::perform_bus_operation(CPU::MOS6502::BusOperation operation,
|
|||||||
}
|
}
|
||||||
} else if(address >= 0x1800 && address <= 0x180f) {
|
} else if(address >= 0x1800 && address <= 0x180f) {
|
||||||
if(isReadOperation(operation))
|
if(isReadOperation(operation))
|
||||||
*value = serial_port_VIA_.get_register(address);
|
*value = serial_port_VIA_.read(address);
|
||||||
else
|
else
|
||||||
serial_port_VIA_.set_register(address, *value);
|
serial_port_VIA_.write(address, *value);
|
||||||
} else if(address >= 0x1c00 && address <= 0x1c0f) {
|
} else if(address >= 0x1c00 && address <= 0x1c0f) {
|
||||||
if(isReadOperation(operation))
|
if(isReadOperation(operation))
|
||||||
*value = drive_VIA_.get_register(address);
|
*value = drive_VIA_.read(address);
|
||||||
else
|
else
|
||||||
drive_VIA_.set_register(address, *value);
|
drive_VIA_.write(address, *value);
|
||||||
}
|
}
|
||||||
|
|
||||||
serial_port_VIA_.run_for(Cycles(1));
|
serial_port_VIA_.run_for(Cycles(1));
|
||||||
|
@ -503,10 +503,10 @@ class ConcreteMachine:
|
|||||||
if((address&0xfc00) == 0x9000) {
|
if((address&0xfc00) == 0x9000) {
|
||||||
if(!(address&0x100)) {
|
if(!(address&0x100)) {
|
||||||
update_video();
|
update_video();
|
||||||
result &= mos6560_.get_register(address);
|
result &= mos6560_.read(address);
|
||||||
}
|
}
|
||||||
if(address & 0x10) result &= user_port_via_.get_register(address);
|
if(address & 0x10) result &= user_port_via_.read(address);
|
||||||
if(address & 0x20) result &= keyboard_via_.get_register(address);
|
if(address & 0x20) result &= keyboard_via_.read(address);
|
||||||
}
|
}
|
||||||
*value = result;
|
*value = result;
|
||||||
|
|
||||||
@ -590,12 +590,12 @@ class ConcreteMachine:
|
|||||||
// The VIC is selected by bit 8 = 0
|
// The VIC is selected by bit 8 = 0
|
||||||
if(!(address&0x100)) {
|
if(!(address&0x100)) {
|
||||||
update_video();
|
update_video();
|
||||||
mos6560_.set_register(address, *value);
|
mos6560_.write(address, *value);
|
||||||
}
|
}
|
||||||
// The first VIA is selected by bit 4 = 1.
|
// 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.
|
// 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ class ConcreteMachine:
|
|||||||
case 0xfe0c: case 0xfe0d: case 0xfe0e: case 0xfe0f:
|
case 0xfe0c: case 0xfe0d: case 0xfe0e: case 0xfe0f:
|
||||||
if(!isReadOperation(operation)) {
|
if(!isReadOperation(operation)) {
|
||||||
update_display();
|
update_display();
|
||||||
video_output_.set_register(address, *value);
|
video_output_.write(address, *value);
|
||||||
video_access_range_ = video_output_.get_memory_access_range();
|
video_access_range_ = video_output_.get_memory_access_range();
|
||||||
queue_next_display_interrupt();
|
queue_next_display_interrupt();
|
||||||
}
|
}
|
||||||
@ -260,9 +260,9 @@ class ConcreteMachine:
|
|||||||
set_key_state(KeyShift, false);
|
set_key_state(KeyShift, false);
|
||||||
}
|
}
|
||||||
if(isReadOperation(operation))
|
if(isReadOperation(operation))
|
||||||
*value = plus3_->get_register(address);
|
*value = plus3_->read(address);
|
||||||
else
|
else
|
||||||
plus3_->set_register(address, *value);
|
plus3_->write(address, *value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xfc00:
|
case 0xfc00:
|
||||||
|
@ -250,7 +250,7 @@ void VideoOutput::run_for(const Cycles cycles) {
|
|||||||
|
|
||||||
// MARK: - Register hub
|
// MARK: - Register hub
|
||||||
|
|
||||||
void VideoOutput::set_register(int address, uint8_t value) {
|
void VideoOutput::write(int address, uint8_t value) {
|
||||||
switch(address & 0xf) {
|
switch(address & 0xf) {
|
||||||
case 0x02:
|
case 0x02:
|
||||||
start_screen_address_ = (start_screen_address_ & 0xfe00) | static_cast<uint16_t>((value & 0xe0) << 1);
|
start_screen_address_ = (start_screen_address_ & 0xfe00) | static_cast<uint16_t>((value & 0xe0) << 1);
|
||||||
|
@ -46,7 +46,7 @@ class VideoOutput {
|
|||||||
Writes @c value to the register at @c address. May mutate the results of @c get_next_interrupt,
|
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.
|
@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.
|
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
|
The time until signalling returned is the number of cycles after the final one triggered
|
||||||
by the most recent call to @c run_for.
|
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();
|
Interrupt get_next_interrupt();
|
||||||
|
|
||||||
|
@ -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) {
|
void DiskROM::write(uint16_t address, uint8_t value, bool pc_is_outside_bios) {
|
||||||
switch(address) {
|
switch(address) {
|
||||||
case 0x7ff8: case 0x7ff9: case 0x7ffa: case 0x7ffb:
|
case 0x7ff8: case 0x7ff9: case 0x7ffa: case 0x7ffb:
|
||||||
set_register(address, value);
|
WD::WD1770::write(address, value);
|
||||||
break;
|
break;
|
||||||
case 0x7ffc:
|
case 0x7ffc:
|
||||||
selected_head_ = value & 1;
|
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) {
|
uint8_t DiskROM::read(uint16_t address) {
|
||||||
if(address >= 0x7ff8 && address < 0x7ffc) {
|
if(address >= 0x7ff8 && address < 0x7ffc) {
|
||||||
return get_register(address);
|
return WD::WD1770::read(address);
|
||||||
}
|
}
|
||||||
if(address == 0x7fff) {
|
if(address == 0x7fff) {
|
||||||
return (get_data_request_line() ? 0x00 : 0x80) | (get_interrupt_request_line() ? 0x00 : 0x40);
|
return (get_data_request_line() ? 0x00 : 0x80) | (get_interrupt_request_line() ? 0x00 : 0x40);
|
||||||
|
@ -428,7 +428,7 @@ class ConcreteMachine:
|
|||||||
// TAPION
|
// TAPION
|
||||||
|
|
||||||
// Enable the tape motor.
|
// Enable the tape motor.
|
||||||
i8255_.set_register(0xab, 0x8);
|
i8255_.write(0xab, 0x8);
|
||||||
|
|
||||||
// Disable interrupts.
|
// Disable interrupts.
|
||||||
z80_.set_value_of_register(CPU::Z80::Register::IFF1, 0);
|
z80_.set_value_of_register(CPU::Z80::Register::IFF1, 0);
|
||||||
@ -509,7 +509,7 @@ class ConcreteMachine:
|
|||||||
case CPU::Z80::PartialMachineCycle::Input:
|
case CPU::Z80::PartialMachineCycle::Input:
|
||||||
switch(address & 0xff) {
|
switch(address & 0xff) {
|
||||||
case 0x98: case 0x99:
|
case 0x98: case 0x99:
|
||||||
*cycle.value = vdp_->get_register(address);
|
*cycle.value = vdp_->read(address);
|
||||||
z80_.set_interrupt_line(vdp_->get_interrupt_line());
|
z80_.set_interrupt_line(vdp_->get_interrupt_line());
|
||||||
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
||||||
break;
|
break;
|
||||||
@ -523,7 +523,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
case 0xa8: case 0xa9:
|
case 0xa8: case 0xa9:
|
||||||
case 0xaa: case 0xab:
|
case 0xaa: case 0xab:
|
||||||
*cycle.value = i8255_.get_register(address);
|
*cycle.value = i8255_.read(address);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -536,7 +536,7 @@ class ConcreteMachine:
|
|||||||
const int port = address & 0xff;
|
const int port = address & 0xff;
|
||||||
switch(port) {
|
switch(port) {
|
||||||
case 0x98: case 0x99:
|
case 0x98: case 0x99:
|
||||||
vdp_->set_register(address, *cycle.value);
|
vdp_->write(address, *cycle.value);
|
||||||
z80_.set_interrupt_line(vdp_->get_interrupt_line());
|
z80_.set_interrupt_line(vdp_->get_interrupt_line());
|
||||||
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
||||||
break;
|
break;
|
||||||
@ -550,7 +550,7 @@ class ConcreteMachine:
|
|||||||
|
|
||||||
case 0xa8: case 0xa9:
|
case 0xa8: case 0xa9:
|
||||||
case 0xaa: case 0xab:
|
case 0xaa: case 0xab:
|
||||||
i8255_.set_register(address, *cycle.value);
|
i8255_.write(address, *cycle.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xfc: case 0xfd: case 0xfe: case 0xff:
|
case 0xfc: case 0xfd: case 0xfe: case 0xff:
|
||||||
|
@ -240,7 +240,7 @@ class ConcreteMachine:
|
|||||||
*cycle.value = vdp_.last_valid()->get_latched_horizontal_counter();
|
*cycle.value = vdp_.last_valid()->get_latched_horizontal_counter();
|
||||||
break;
|
break;
|
||||||
case 0x80: case 0x81:
|
case 0x80: case 0x81:
|
||||||
*cycle.value = vdp_->get_register(address);
|
*cycle.value = vdp_->read(address);
|
||||||
z80_.set_interrupt_line(vdp_->get_interrupt_line());
|
z80_.set_interrupt_line(vdp_->get_interrupt_line());
|
||||||
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
||||||
break;
|
break;
|
||||||
@ -288,10 +288,10 @@ class ConcreteMachine:
|
|||||||
} break;
|
} break;
|
||||||
case 0x40: case 0x41:
|
case 0x40: case 0x41:
|
||||||
update_audio();
|
update_audio();
|
||||||
sn76489_.set_register(*cycle.value);
|
sn76489_.write(*cycle.value);
|
||||||
break;
|
break;
|
||||||
case 0x80: case 0x81:
|
case 0x80: case 0x81:
|
||||||
vdp_->set_register(address, *cycle.value);
|
vdp_->write(address, *cycle.value);
|
||||||
z80_.set_interrupt_line(vdp_->get_interrupt_line());
|
z80_.set_interrupt_line(vdp_->get_interrupt_line());
|
||||||
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
time_until_interrupt_ = vdp_->get_time_until_interrupt();
|
||||||
break;
|
break;
|
||||||
|
@ -386,16 +386,16 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
|||||||
} else {
|
} else {
|
||||||
if((address & 0xff00) == 0x0300) {
|
if((address & 0xff00) == 0x0300) {
|
||||||
if(address < 0x0310 || (disk_interface == Analyser::Static::Oric::Target::DiskInterface::None)) {
|
if(address < 0x0310 || (disk_interface == Analyser::Static::Oric::Target::DiskInterface::None)) {
|
||||||
if(isReadOperation(operation)) *value = via_.get_register(address);
|
if(isReadOperation(operation)) *value = via_.read(address);
|
||||||
else via_.set_register(address, *value);
|
else via_.write(address, *value);
|
||||||
} else {
|
} else {
|
||||||
switch(disk_interface) {
|
switch(disk_interface) {
|
||||||
default: break;
|
default: break;
|
||||||
case Analyser::Static::Oric::Target::DiskInterface::Microdisc:
|
case Analyser::Static::Oric::Target::DiskInterface::Microdisc:
|
||||||
switch(address) {
|
switch(address) {
|
||||||
case 0x0310: case 0x0311: case 0x0312: case 0x0313:
|
case 0x0310: case 0x0311: case 0x0312: case 0x0313:
|
||||||
if(isReadOperation(operation)) *value = microdisc_.get_register(address);
|
if(isReadOperation(operation)) *value = microdisc_.read(address);
|
||||||
else microdisc_.set_register(address, *value);
|
else microdisc_.write(address, *value);
|
||||||
break;
|
break;
|
||||||
case 0x314: case 0x315: case 0x316: case 0x317:
|
case 0x314: case 0x315: case 0x316: case 0x317:
|
||||||
if(isReadOperation(operation)) *value = microdisc_.get_interrupt_request_register();
|
if(isReadOperation(operation)) *value = microdisc_.get_interrupt_request_register();
|
||||||
|
@ -67,9 +67,9 @@
|
|||||||
</Testables>
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Debug"
|
||||||
selectedDebuggerIdentifier = ""
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
enableASanStackUseAfterReturn = "YES"
|
enableASanStackUseAfterReturn = "YES"
|
||||||
disableMainThreadChecker = "YES"
|
disableMainThreadChecker = "YES"
|
||||||
launchStyle = "0"
|
launchStyle = "0"
|
||||||
|
@ -53,11 +53,11 @@ class VanillaVIAPortHandler: public MOS::MOS6522::PortHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)setValue:(uint8_t)value forRegister:(NSUInteger)registerNumber {
|
- (void)setValue:(uint8_t)value forRegister:(NSUInteger)registerNumber {
|
||||||
_via->set_register((int)registerNumber, value);
|
_via->write((int)registerNumber, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (uint8_t)valueForRegister:(NSUInteger)registerNumber {
|
- (uint8_t)valueForRegister:(NSUInteger)registerNumber {
|
||||||
return _via->get_register((int)registerNumber);
|
return _via->read((int)registerNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)runForHalfCycles:(NSUInteger)numberOfHalfCycles {
|
- (void)runForHalfCycles:(NSUInteger)numberOfHalfCycles {
|
||||||
|
@ -22,11 +22,11 @@ class VanillaRIOT: public MOS::MOS6532<VanillaRIOT> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)setValue:(uint8_t)value forRegister:(NSUInteger)registerNumber {
|
- (void)setValue:(uint8_t)value forRegister:(NSUInteger)registerNumber {
|
||||||
_riot.set_register((int)registerNumber, value);
|
_riot.write((int)registerNumber, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (uint8_t)valueForRegister:(NSUInteger)registerNumber {
|
- (uint8_t)valueForRegister:(NSUInteger)registerNumber {
|
||||||
return _riot.get_register((int)registerNumber);
|
return _riot.read((int)registerNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)runForCycles:(NSUInteger)numberOfCycles {
|
- (void)runForCycles:(NSUInteger)numberOfCycles {
|
||||||
|
@ -43,15 +43,15 @@
|
|||||||
TI::TMS::TMS9918 vdp(TI::TMS::Personality::SMSVDP);
|
TI::TMS::TMS9918 vdp(TI::TMS::Personality::SMSVDP);
|
||||||
|
|
||||||
// Disable end-of-frame interrupts, enable line interrupts.
|
// Disable end-of-frame interrupts, enable line interrupts.
|
||||||
vdp.set_register(1, 0x00);
|
vdp.write(1, 0x00);
|
||||||
vdp.set_register(1, 0x81);
|
vdp.write(1, 0x81);
|
||||||
|
|
||||||
vdp.set_register(1, 0x10);
|
vdp.write(1, 0x10);
|
||||||
vdp.set_register(1, 0x80);
|
vdp.write(1, 0x80);
|
||||||
|
|
||||||
// Set a line interrupt to occur in five lines.
|
// Set a line interrupt to occur in five lines.
|
||||||
vdp.set_register(1, 5);
|
vdp.write(1, 5);
|
||||||
vdp.set_register(1, 0x8a);
|
vdp.write(1, 0x8a);
|
||||||
|
|
||||||
// Get time until interrupt.
|
// Get time until interrupt.
|
||||||
auto time_until_interrupt = vdp.get_time_until_interrupt().as_integral() - 1;
|
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]");
|
NSAssert(vdp.get_interrupt_line(), @"Interrupt line wasn't set when promised [1]");
|
||||||
|
|
||||||
// Read the status register to clear interrupt status.
|
// 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");
|
NSAssert(!vdp.get_interrupt_line(), @"Interrupt wasn't reset by status read");
|
||||||
|
|
||||||
// Check interrupt flag isn't set prior to the reported time.
|
// Check interrupt flag isn't set prior to the reported time.
|
||||||
@ -86,20 +86,20 @@
|
|||||||
TI::TMS::TMS9918 vdp(TI::TMS::Personality::SMSVDP);
|
TI::TMS::TMS9918 vdp(TI::TMS::Personality::SMSVDP);
|
||||||
|
|
||||||
// Disable end-of-frame interrupts, enable line interrupts, set an interrupt to occur every line.
|
// Disable end-of-frame interrupts, enable line interrupts, set an interrupt to occur every line.
|
||||||
vdp.set_register(1, 0x00);
|
vdp.write(1, 0x00);
|
||||||
vdp.set_register(1, 0x81);
|
vdp.write(1, 0x81);
|
||||||
|
|
||||||
vdp.set_register(1, 0x10);
|
vdp.write(1, 0x10);
|
||||||
vdp.set_register(1, 0x80);
|
vdp.write(1, 0x80);
|
||||||
|
|
||||||
vdp.set_register(1, 0);
|
vdp.write(1, 0);
|
||||||
vdp.set_register(1, 0x8a);
|
vdp.write(1, 0x8a);
|
||||||
|
|
||||||
// Advance to outside of the counted area.
|
// Advance to outside of the counted area.
|
||||||
while(vdp.get_current_line() < 200) vdp.run_for(Cycles(228));
|
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).
|
// 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;
|
auto time_until_interrupt = vdp.get_time_until_interrupt().as_integral() - 1;
|
||||||
|
|
||||||
// Check that an interrupt is now scheduled.
|
// Check that an interrupt is now scheduled.
|
||||||
@ -121,16 +121,16 @@
|
|||||||
for(int c = 0; c < 256; ++c) {
|
for(int c = 0; c < 256; ++c) {
|
||||||
for(int with_eof = (c < 192) ? 0 : 1; with_eof < 2; ++with_eof) {
|
for(int with_eof = (c < 192) ? 0 : 1; with_eof < 2; ++with_eof) {
|
||||||
// Enable or disable end-of-frame interrupts as required.
|
// Enable or disable end-of-frame interrupts as required.
|
||||||
vdp.set_register(1, with_eof ? 0x20 : 0x00);
|
vdp.write(1, with_eof ? 0x20 : 0x00);
|
||||||
vdp.set_register(1, 0x81);
|
vdp.write(1, 0x81);
|
||||||
|
|
||||||
// Enable line interrupts.
|
// Enable line interrupts.
|
||||||
vdp.set_register(1, 0x10);
|
vdp.write(1, 0x10);
|
||||||
vdp.set_register(1, 0x80);
|
vdp.write(1, 0x80);
|
||||||
|
|
||||||
// Set the line interrupt timing as desired.
|
// Set the line interrupt timing as desired.
|
||||||
vdp.set_register(1, c);
|
vdp.write(1, c);
|
||||||
vdp.set_register(1, 0x8a);
|
vdp.write(1, 0x8a);
|
||||||
|
|
||||||
// Now run through an entire frame...
|
// Now run through an entire frame...
|
||||||
int half_cycles = 262*228*2;
|
int half_cycles = 262*228*2;
|
||||||
@ -138,7 +138,7 @@
|
|||||||
while(half_cycles--) {
|
while(half_cycles--) {
|
||||||
// Validate that an interrupt happened if one was expected, and clear anything that's present.
|
// 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);
|
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));
|
vdp.run_for(HalfCycles(1));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user