Skip to content

Commit

Permalink
Replaced the last few asserts with error handler messages in Via
Browse files Browse the repository at this point in the history
Allows more roms to at least attempt to execute, rather than assert and
exit or break into debugger.

Fixes GCE test rom V4 when running the DAC offset test.
  • Loading branch information
amaiorano committed Dec 23, 2023
1 parent d24d4a7 commit f872ea2
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 14 deletions.
4 changes: 4 additions & 0 deletions libs/emulator/include/emulator/Timers.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
#include "core/Base.h"

enum class TimerMode { FreeRunning, OneShot, PulseCounting };
inline const char* TimerModeToString(TimerMode mode) {
constexpr char* v[] = {"FreeRunning", "OneShot", "PulseCounting"};
return v[static_cast<int>(mode)];
}

// Timer 1 is used mainly for drawing.
// Supports timed interrupt each time t1 is loaded (one-shot), or continuous interrupts
Expand Down
37 changes: 23 additions & 14 deletions libs/emulator/src/Via.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,25 +425,36 @@ void Via::Write(uint16_t address, uint8_t value) {
case Register::AuxCntl: {
m_shiftRegister.SetMode(AuxCntl::GetShiftRegisterMode(value));

ASSERT_MSG(AuxCntl::GetTimer1Mode(value) == TimerMode::OneShot,
"t1 assumed always on one-shot mode");
ASSERT_MSG(AuxCntl::GetTimer2Mode(value) == TimerMode::OneShot,
"t2 assumed always on one-shot mode");
m_timer1.SetTimerMode(AuxCntl::GetTimer1Mode(value));
m_timer2.SetTimerMode(AuxCntl::GetTimer2Mode(value));
const TimerMode mode1 = AuxCntl::GetTimer1Mode(value);
if (mode1 == TimerMode::OneShot) {
m_timer1.SetTimerMode(mode1);
} else {
ErrorHandler::Unsupported("t1 assumed always on one-shot mode, read: %s\n",
TimerModeToString(mode1));
}

const TimerMode mode2 = AuxCntl::GetTimer2Mode(value);
if (mode2 == TimerMode::OneShot) {
m_timer2.SetTimerMode(mode2);
} else {
ErrorHandler::Unsupported("t2 assumed always on one-shot mode, read: %s\n",
TimerModeToString(mode2));
}

m_timer1.SetPB7Flag(TestBits(value, AuxCntl::PB7Flag));

} break;

case Register::PeriphCntl: {
ASSERT_MSG(ReadBitsWithShift(value, PeriphCntl::CA2Mask, PeriphCntl::CA2Shift) == 0b110 ||
ReadBitsWithShift(value, PeriphCntl::CA2Mask, PeriphCntl::CA2Shift) == 0b111,
"Unexpected value for CA2 bits");
const uint8_t ca2 = ReadBitsWithShift(value, PeriphCntl::CA2Mask, PeriphCntl::CA2Shift);
if (ca2 != 0b110 && ca2 != 0b111) {
ErrorHandler::Undefined("Unexpected value for CA2 bits, read: 0x%X\n", ca2);
}

ASSERT_MSG(ReadBitsWithShift(value, PeriphCntl::CB2Mask, PeriphCntl::CB2Shift) == 0b110 ||
ReadBitsWithShift(value, PeriphCntl::CB2Mask, PeriphCntl::CB2Shift) == 0b111,
"Top 2 bits should always be 1 (right?)");
const uint8_t cb2 = ReadBitsWithShift(value, PeriphCntl::CB2Mask, PeriphCntl::CB2Shift);
if (cb2 != 0b110 && cb2 != 0b111) {
ErrorHandler::Undefined("Unexpected value for CB2 bits, read: 0x%X\n", cb2);
}

m_periphCntl = value;
if (m_shiftRegister.Mode() == ShiftRegisterMode::Disabled) {
Expand All @@ -455,7 +466,6 @@ void Via::Write(uint16_t address, uint8_t value) {
// Clear interrupt flags for any bits that are enabled
//@TODO: validate if this is the correct behaviour

// Assert if trying to clear an interrupt we don't handle yet
#define LOG_UNHANDLED(flag) \
if (TestBits(value, flag)) \
do { \
Expand Down Expand Up @@ -483,7 +493,6 @@ void Via::Write(uint16_t address, uint8_t value) {
// (Zeros in bit positions are left unchanged)
SetBits(m_interruptEnable, (value & 0x7F), TestBits(value, BITS(7)));

// Assert if trying to enable interrupt we don't handle yet
#define LOG_UNHANDLED(flag) \
if (TestBits(m_interruptEnable, flag)) \
do { \
Expand Down

0 comments on commit f872ea2

Please sign in to comment.