1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-03-22 00:35:23 +00:00

Establishes valid initial BRAM.

This commit is contained in:
Thomas Harte 2021-09-10 19:56:20 -04:00
parent 0ca4631279
commit dfcd1508c9
3 changed files with 76 additions and 19 deletions

View File

@ -9,6 +9,8 @@
#ifndef Apple_RealTimeClock_hpp
#define Apple_RealTimeClock_hpp
#include <array>
namespace Apple {
namespace Clock {
@ -21,32 +23,36 @@ namespace Clock {
*/
class ClockStorage {
public:
ClockStorage() {
// TODO: this should persist, if possible, rather than
// being default initialised.
// constexpr uint8_t default_data[] = {
// 0xa8, 0x00, 0x00, 0x00,
// 0xcc, 0x0a, 0xcc, 0x0a,
// 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x02, 0x63, 0x00,
// 0x03, 0x88, 0x00, 0x4c
// };
// memcpy(data_, default_data, sizeof(default_data));
// memset(&data_[sizeof(default_data)], 0xff, sizeof(data_) - sizeof(default_data));
}
ClockStorage() {}
/*!
Advances the clock by 1 second.
The caller should also signal an interrupt.
The caller should also signal an interrupt if applicable.
*/
void update() {
for(int c = 0; c < 4; ++c) {
for(size_t c = 0; c < 4; ++c) {
++seconds_[c];
if(seconds_[c]) break;
}
}
/*!
Sets the current [P/B]RAM contents.
*/
template <typename CollectionT> void set_data(const CollectionT &collection) {
set_data(collection.begin(), collection.end());
}
template <typename IteratorT> void set_data(IteratorT begin, const IteratorT end) {
size_t c = 0;
while(begin != end && c < 256) {
data_[c] = *begin;
++begin;
++c;
}
}
protected:
static constexpr uint16_t NoResult = 0x100;
static constexpr uint16_t DidComplete = 0x101;
@ -92,7 +98,7 @@ class ClockStorage {
case 0x30:
// Either a register access or an extended instruction.
if(command & 0x08) {
address_ = (command & 0x7) << 5;
address_ = unsigned((command & 0x7) << 5);
phase_ = (command & 0x80) ? Phase::SecondAddressByteRead : Phase::SecondAddressByteWrite;
return NoResult;
} else {
@ -162,10 +168,10 @@ class ClockStorage {
private:
uint8_t data_[256]{};
uint8_t seconds_[4]{};
std::array<uint8_t, 256> data_{0xff};
std::array<uint8_t, 4> seconds_{};
uint8_t write_protect_ = 0;
int address_ = 0;
unsigned int address_ = 0;
static constexpr int SecondsBuffer = 0x100;
static constexpr int RegisterTest = 0x200;

View File

@ -42,6 +42,27 @@ namespace {
constexpr int CLOCK_RATE = 14'318'180;
// This is the first result that came up when searching for valid Apple IIgs BRAM states;
// I'm unclear on its provenance.
constexpr uint8_t default_bram[] = {
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0d, 0x06, 0x02, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x06, 0x06, 0x00, 0x05, 0x06,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x02, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x96, 0x57, 0x3c,
};
class MemManagerChecker {
int handle_total_ = 0;
bool dump_bank(const Apple::IIgs::MemoryMap &memory, const char *name, uint32_t address, bool print, uint32_t must_contain = 0xffffffff) {
@ -187,6 +208,7 @@ class ConcreteMachine:
set_clock_rate(double(CLOCK_RATE));
speaker_.set_input_rate(float(CLOCK_RATE) / float(audio_divider));
clock_.ClockStorage::set_data(std::begin(default_bram), std::end(default_bram));
using Target = Analyser::Static::AppleIIgs::Target;
ROM::Name system;
@ -353,6 +375,26 @@ class ConcreteMachine:
static bool log = false;
bool is_1Mhz = false;
if(operation == CPU::WDC65816::BusOperation::ReadOpcode) {
if(address == 0xffb626 && m65816_.get_value_of_register(CPU::WDC65816::Register::X) == 0x51) {
printf("");
}
if(address == 0xffb54c) {
printf("");
}
printf("%06x a:%04x x:%04x y:%04x s:%04x d:%04x b:%04x\n",
address,
m65816_.get_value_of_register(CPU::WDC65816::Register::A),
m65816_.get_value_of_register(CPU::WDC65816::Register::X),
m65816_.get_value_of_register(CPU::WDC65816::Register::Y),
// m65816_.get_value_of_register(CPU::WDC65816::Register::Flags),
m65816_.get_value_of_register(CPU::WDC65816::Register::StackPointer),
m65816_.get_value_of_register(CPU::WDC65816::Register::Direct),
m65816_.get_value_of_register(CPU::WDC65816::Register::DataBank)
);
}
if(operation == CPU::WDC65816::BusOperation::ReadVector && !(memory_.get_shadow_register()&0x40)) {
// I think vector pulls always go to ROM?
// That's slightly implied in the documentation, and doing so makes GS/OS boot, so...

View File

@ -49,6 +49,15 @@ namespace {
constexpr int CLOCK_RATE = 7833600;
// Former default PRAM:
//
// 0xa8, 0x00, 0x00, 0x00,
// 0xcc, 0x0a, 0xcc, 0x0a,
// 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x02, 0x63, 0x00,
// 0x03, 0x88, 0x00, 0x4c
}
namespace Apple {