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

Made a first attempt to hash out the ZX80's bus. Video output isn't yet going though. Can't seem to find clarity on whether horizontal sync is really programmatic. Let's see.

This commit is contained in:
Thomas Harte 2017-06-04 18:32:23 -04:00
parent c485c460f7
commit 096551ab3e
3 changed files with 76 additions and 4 deletions

View File

@ -10,17 +10,64 @@
using namespace ZX8081;
Machine::Machine() {
Machine::Machine() :
vertical_sync_(false),
ram_(65536) {
// run at 3.25 Mhz
set_clock_rate(3250000);
}
int Machine::perform_machine_cycle(const CPU::Z80::MachineCycle &cycle) {
cycles_since_display_update_ += cycle.length;
uint8_t r;
switch(cycle.operation) {
case CPU::Z80::BusOperation::Output:
if(*cycle.address == 0xff) {
update_display();
set_sync(false);
}
break;
case CPU::Z80::BusOperation::Input:
if(*cycle.address == 0xfe) {
update_display();
set_sync(true);
}
break;
case CPU::Z80::BusOperation::Interrupt:
*cycle.value = 0xff;
break;
case CPU::Z80::BusOperation::ReadOpcode:
r = (uint8_t)get_value_of_register(CPU::Z80::Register::R);
set_interrupt_line(!(r & 0x40));
case CPU::Z80::BusOperation::Read:
if(*cycle.address < rom_.size()) *cycle.value = rom_[*cycle.address];
else {
uint8_t value = ram_[*cycle.address];
if(*cycle.address > 32768 && !(value & 0x40) && cycle.operation == CPU::Z80::BusOperation::ReadOpcode) {
// TODO: character lookup.
output_byte(value);
*cycle.value = 0;
}
else *cycle.value = value;
}
break;
case CPU::Z80::BusOperation::Write:
ram_[*cycle.address] = *cycle.value;
break;
default: break;
}
return 0;
}
void Machine::setup_output(float aspect_ratio) {
crt_.reset(new Outputs::CRT::CRT(207 * 8, 8, Outputs::CRT::DisplayType::PAL50, 1));
crt_.reset(new Outputs::CRT::CRT(207, 1, Outputs::CRT::DisplayType::PAL50, 1));
crt_->set_rgb_sampling_function(
"vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)"
"{"
@ -29,6 +76,7 @@ void Machine::setup_output(float aspect_ratio) {
}
void Machine::flush() {
update_display();
}
void Machine::close_output() {
@ -46,6 +94,8 @@ void Machine::run_for_cycles(int number_of_cycles) {
}
void Machine::configure_as_target(const StaticAnalyser::Target &target) {
// TODO: pay attention to the target
rom_ = zx80_rom_;
}
void Machine::set_rom(ROMType type, std::vector<uint8_t> data) {
@ -54,3 +104,16 @@ void Machine::set_rom(ROMType type, std::vector<uint8_t> data) {
case ZX81: zx81_rom_ = data; break;
}
}
#pragma mark - Video
void Machine::update_display() {
// TODO.
cycles_since_display_update_ = 0;
}
void Machine::set_sync(bool sync) {
}
void Machine::output_byte(uint8_t byte) {
}

View File

@ -49,6 +49,13 @@ class Machine:
std::shared_ptr<Outputs::CRT::CRT> crt_;
std::vector<uint8_t> zx81_rom_, zx80_rom_, rom_;
std::vector<uint8_t> ram_;
bool vertical_sync_;
int cycles_since_display_update_;
void update_display();
void set_sync(bool sync);
void output_byte(uint8_t byte);
};
}

View File

@ -38,7 +38,7 @@ enum Register {
IXh, IXl, IX,
IYh, IYl, IY,
R, I,
R, I, Refresh,
IFF1, IFF2, IM
};
@ -1652,10 +1652,11 @@ template <class T> class Processor {
case Register::R: return r_;
case Register::I: return i_;
case Register::Refresh: return (uint16_t)(r_ | (i_ << 8));
case Register::IFF1: return iff1_ ? 1 : 0;
case Register::IFF2: return iff2_ ? 1 : 0;
case Register::IM: return interrupt_mode_;
case Register::IM: return (uint16_t)interrupt_mode_;
default: return 0;
}
@ -1710,6 +1711,7 @@ template <class T> class Processor {
case Register::R: r_ = (uint8_t)value; break;
case Register::I: i_ = (uint8_t)value; break;
case Register::Refresh: r_ = (uint8_t)value; i_ = (uint8_t)(value >> 8); break;
case Register::IFF1: iff1_ = !!value; break;
case Register::IFF2: iff2_ = !!value; break;