1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Give Nick some RAM to inspect and just enough sense to know when it should reload its line parameter table.

This commit is contained in:
Thomas Harte 2021-06-15 17:43:13 -04:00
parent 440b11708b
commit a1e4389f63
3 changed files with 33 additions and 10 deletions

View File

@ -63,7 +63,8 @@ class ConcreteMachine:
public MachineTypes::TimedMachine {
public:
ConcreteMachine([[maybe_unused]] const Analyser::Static::Enterprise::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
z80_(*this) {
z80_(*this),
nick_(ram_.end() - 65536) {
// Request a clock of 4Mhz; this'll be mapped upwards for Nick and Dave elsewhere.
set_clock_rate(4'000'000);
@ -189,11 +190,9 @@ class ConcreteMachine:
}
private:
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
// MARK: - Memory layout
std::array<uint8_t, 32 * 1024> exos_;
std::array<uint8_t, 256 * 1024> ram_;
std::array<uint8_t, 32 * 1024> exos_;
const uint8_t min_ram_slot_ = 0xff - 3;
const uint8_t *read_pointers_[4] = {nullptr, nullptr, nullptr, nullptr};
@ -209,7 +208,8 @@ class ConcreteMachine:
}
if(offset >= min_ram_slot_) {
const size_t address = (offset - min_ram_slot_) * 0x4000;
const auto ram_floor = 4194304 - ram_.size();
const size_t address = offset * 0x4000 - ram_floor;
page<slot>(&ram_[address], &ram_[address]);
return;
}
@ -236,7 +236,8 @@ class ConcreteMachine:
z80_.run_for(cycles);
}
// MARK: - Video.
// MARK: - Chips.
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
JustInTimeActor<Nick, HalfCycles, 444923, 125000> nick_;
// Cf. timing guesses above.
};

View File

@ -12,17 +12,34 @@
using namespace Enterprise;
Nick::Nick() :
crt_(16 * 57, 16, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red4Green4Blue4) {
Nick::Nick(const uint8_t *ram) :
crt_(16 * 57, 16, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red4Green4Blue4),
ram_(ram) {
// Just use RGB for now.
crt_.set_display_type(Outputs::Display::DisplayType::RGB);
}
void Nick::write(uint16_t address, uint8_t value) {
printf("Nick write: %02x -> %d\n", value, address & 3);
switch(address & 3) {
default:
printf("Unhandled Nick write: %02x -> %d\n", value, address & 3);
printf("Unhandled\n");
break;
case 2:
line_parameter_base_ = uint16_t((line_parameter_base_ & 0xf000) | (value << 4));
break;
case 3:
line_parameter_base_ = uint16_t((line_parameter_base_ & 0x0ff0) | (value << 12));
// Still a mystery to me: the exact meaning of the top two bits here. For now
// just treat a 0 -> 1 transition of the MSB as a forced frame restart.
if((value^line_parameter_control_) & value & 0x80) {
// TODO: restart frame.
printf("Should restart frame from %04x\n", line_parameter_base_);
}
line_parameter_control_ = value & 0xc0;
break;
}
}

View File

@ -17,7 +17,7 @@ namespace Enterprise {
class Nick {
public:
Nick();
Nick(const uint8_t *ram);
void write(uint16_t address, uint8_t value);
uint8_t read(uint16_t address);
@ -29,6 +29,11 @@ class Nick {
private:
Outputs::CRT::CRT crt_;
const uint8_t *const ram_;
uint8_t line_parameter_control_ = 0xc0;
uint16_t line_parameter_base_ = 0x0000;
int horizontal_counter_ = 0;
};