#include "hardware.h"
#include <time.h>
#include "common.h"
+#include "logger.h"
namespace SA1100 {
// Peripheral Control Modules
// 0x80000000 address space
uint8_t Emulator::readPCM8(uint32_t physAddr) {
- printf("Read PCM8 at 0x%08x\n", physAddr);
+ assert(false);
return 0x0;
}
bool Emulator::writePCM8(uint8_t value, uint32_t physAddr) {
- printf("Write PCM8 0x%08x at 0x%08x\n", value, physAddr);
+ assert(false);
return true;
}
switch (region) {
case 0x8005:
// Serial 3
- //printf("Getting serial 3 at 0x%08x\n", physAddr);
return serial3->get_data(physAddr);
default:
- printf("Read PCM32 at 0x%08x\n", physAddr);
return 0x0;
}
}
switch (region) {
case 0x8005:
// Serial 3
- //printf("Serial 3 write 0x%08x at 0x%08x\n", value, physAddr);
serial3->put_data(physAddr, value);
return true;
default:
- printf("Write PCM32 0x%08x at 0x%08x\n", value, physAddr);
return true;
}
}
// System Control Modules
// 0x90000000 address space
uint8_t Emulator::readSCM8(uint32_t physAddr) {
- printf("Read SCM8 at 0x%08x\n", physAddr);
return 0x0;
}
bool Emulator::writeSCM8(uint8_t value, uint32_t physAddr) {
- printf("Write SCM8 0x%08x at 0x%08x\n", value, physAddr);
+ assert(false);
return true;
}
switch (region) {
case 0x9000:
// OS Timer
- //printf("Getting timer at 0x%08x\n", physAddr);
return osTimer->get_data(physAddr);
case 0x9001:
// RTC
- printf("Getting RTC at 0x%08x\n", physAddr);
return rtc->get_data(physAddr);
case 0x9002:
// Power manager
- printf("Getting power manager at 0x%08x\n", physAddr);
return powerManager->get_data(physAddr);
case 0x9003:
// Reset controller
- printf("Getting reset controller at 0x%08x\n", physAddr);
return resetController->get_data(physAddr);
case 0x9004:
// GPIO
- printf("GPIO read at 0x%08x\n", physAddr);
return gpioController->get_data(physAddr);
case 0x9005: {
// Interrupt Controller
auto value = intController->get_data(physAddr);
- printf("Interrupt controller read at 0x%08x [0x%08x]\n", physAddr, value);
return value;
}
default:
- printf("Read SCM32 at 0x%08x\n", physAddr);
+ assert(false);
return 0x0;
}
}
switch (region) {
case 0x9000:
// OS Timer
- printf("OS timer write 0x%08x at 0x%08x\n", value, physAddr);
osTimer->put_data(physAddr, value);
return true;
case 0x9001:
// RTC
- printf("RTC write 0x%08x at 0x%08x\n", value, physAddr);
rtc->put_data(physAddr, value);
return true;
case 0x9002:
// Power manager
- printf("Power manager write 0x%08x at 0x%08x\n", value, physAddr);
powerManager->put_data(physAddr, value);
return true;
case 0x9003:
// Reset controller
- printf("Reset controller write 0x%08x at 0x%08x\n", value, physAddr);
resetController->put_data(physAddr, value);
return true;
case 0x9004:
// GPIO
- printf("GPIO write 0x%08x at 0x%08x\n", value, physAddr);
gpioController->put_data(physAddr, value);
return true;
case 0x9005:
// Interrupt Controller
- printf("Interrupt controller write 0x%08x at 0x%08x\n", value, physAddr);
intController->put_data(physAddr, value);
return true;
default:
- printf("Write SCM32 0x%08x at 0x%08x\n", value, physAddr);
+ //assert(false);
+ LOG_REG_W("Unknown", physAddr, value);
return true;
}
}
-uint8_t Emulator::readPhysical8(uint32_t physAddr) {
+MaybeU32 Emulator::readPhysical8(uint32_t physAddr) {
uint8_t region = (physAddr >> 24) & 0xFF;
switch (region) {
return ROM[physAddr & 0xFFFFFF];
case 0x10:
// Should not reach here
- printf("Reading from ASIC14 in byte mode?\n");
+ assert(false);
return 0;
case 0x20:
case 0x21:
case 0x2E:
case 0x2F:
// PCMCIA slot 0
- printf("Read8 PCMCIA0 %08x\n", physAddr);
return 0x0;
case 0x30:
case 0x31:
case 0x3E:
case 0x3F:
// PCMCIA slot 1
- printf("Read8 PCMCIA1 %08x\n", physAddr);
return 0x0;
case 0x40:
case 0x41:
case 0x7E:
case 0x7F:
// Reserved, causes a data abort exception
- printf("Read8 Reserved %08x\n", physAddr);
- return 0x0;
+ return std::nullopt;
case 0x80:
// Peripheral Control Modules
return readPCM8(physAddr);
case 0xA0:
// Memory Control Registers
// Not valid in byte access
- printf("Read8 Memory Controller %08x\n", physAddr);
+ assert(false);
return 0x0;
case 0xB0:
// LCD/DMA Control Registers
- printf("Read physical 8 LCD access 0x%08x\n", physAddr);
+ assert(false);
return 0x0;
case 0xC0:
case 0xC1:
// case 0xDF:
// return MemoryBlockD8[physAddr & memoryMask];
default:
- printf("Read8 from %08x\n", physAddr);
return 0x0; // just throw accesses to unmapped RAM away
}
return 0x0;
}
-uint32_t Emulator::readPhysical32(uint32_t physAddr) {
+MaybeU32 Emulator::readPhysical32(uint32_t physAddr) {
uint8_t region = (physAddr >> 24) & 0xFF;
uint32_t result;
switch (region) {
case 0x00:
LOAD_32LE(result, physAddr & 0xFFFFFF, ROM);
- //printf("Reading %08x from %08x\n", result, physAddr);
break;
case 0x10:
// Should not reach here
- printf("Reading from ASIC14 in word mode?\n");
- result = 0;
+ assert(false);
break;
case 0x20:
case 0x21:
case 0x2F:
// PCMCIA slot 0
result = 0x0;
- printf("Reading PCMCIA0 from %08x\n", physAddr);
break;
case 0x30:
case 0x31:
case 0x3F:
// PCMCIA slot 1
result = 0x0;
- printf("Reading PCMCIA1 from %08x\n", physAddr);
break;
case 0x40:
case 0x41:
case 0x7E:
case 0x7F:
// Reserved, causes a data abort exception
- result = 0x0;
- printf("Reading Reserved from %08x\n", physAddr);
- break;
+ return std::nullopt;
case 0x80:
// Peripheral Control Modules
result = readPCM32(physAddr);
case 0xA0:
// Memory Control Registers
result = memoryConfig.get_data(physAddr);
- printf("Memory controller read from %08x of %08x\n", physAddr, result);
break;
case 0xB0:
// LCD/DMA Control Registers
result = lcdController->get_data32(physAddr);
- printf("LCD controller get %08x from %08x\n", result, physAddr);
break;
case 0xC0:
case 0xC1:
case 0xE0:
return 0x0;
default:
- printf("Reading from %08x\n", physAddr);
return 0x0; // just throw accesses to unmapped RAM away
}
}
}
-uint16_t Emulator::readPhysical16(uint32_t physAddr) {
+MaybeU32 Emulator::readPhysical16(uint32_t physAddr) {
uint8_t region = (physAddr >> 24) & 0xFF;
switch (region) {
case 0x10:
switch (region) {
case 0x00:
- printf("Write8 %08x to %08x\n", value, physAddr);
- // Read-only
- return false;
+ // Read-only. writes are dropped with no effect.
+ return true;
case 0x10:
- printf("Write8 %08x to %08x\n", value, physAddr);
+ // Shouldn't write to asic14 in byte mode
+ assert(false);
return true;
case 0x20:
case 0x21:
case 0x2E:
case 0x2F:
// PCMCIA slot 0
- printf("Write8 PCMCIA0 %08x to %08x\n", value, physAddr);
return true;
case 0x30:
case 0x31:
case 0x3E:
case 0x3F:
// PCMCIA slot 1
- printf("Write8 PCMCIA1 %08x to %08x\n", value, physAddr);
return true;
case 0x40:
case 0x41:
case 0x7D:
case 0x7E:
case 0x7F:
- // Reserved, causes a data abort exception
- printf("Write8 Reserved %08x to %08x\n", value, physAddr);
- return false;
+ // Reserved, only reads cause a data abort exception
+ return true;
case 0x80:
// Peripheral Control Modules
return writePCM8(value, physAddr);
return writeSCM8(value, physAddr);
case 0xA0:
// Memory Control Registers
- // Invalid to write to with bytes
- printf("Write8 Memory Controller %08x to %08x\n", value, physAddr);
- return false;
+ assert(false);
+ return true;
case 0xB0:
// LCD/DMA Control Registers
- printf("Write LCD physical8 0x%08x to 0x%08x\n", value, physAddr);
+ assert(false);
return true;
case 0xC0:
case 0xC1:
// return true;
default:
// just throw accesses to unmapped RAM away
- printf("Write8 %08x to %08x\n", value, physAddr);
return true;
}
}
switch (region) {
case 0x00:
// Read-only
- printf("Attempting write to %08x of %08x\n", physAddr, value);
- return false;
+ return true;
+ case 0x10:
+ // Should only write to ASIC14 in half word mode
+ assert(false);
+ return true;
case 0x20:
case 0x21:
case 0x22:
case 0x2D:
case 0x2E:
case 0x2F:
- printf("Write32 PCMCIA0 %08x to %08x\n", value, physAddr);
// PCMCIA slot 0
return true;
case 0x30:
case 0x3E:
case 0x3F:
// PCMCIA slot 1
- printf("Write32 PCMCIA1 %08x to %08x\n", value, physAddr);
return true;
case 0x40:
case 0x41:
case 0x7D:
case 0x7E:
case 0x7F:
- // Reserved, causes a data abort exception
- printf("Write32 reserved %08x to %08x\n", value, physAddr);
- return false;
+ // Reserved, only reads cause a data abort exception
+ return true;
case 0x80:
// Peripheral Control Modules
return writePCM32(value, physAddr);
return writeSCM32(value, physAddr);
case 0xA0:
// Memory Control Registers
- printf("Memory controller write to %08x of %08x\n", physAddr, value);
memoryConfig.put_data(physAddr, value);
return true;
case 0xB0:
// LCD/DMA Control Registers
- printf("LCD controller write %08x to %08x\n", value, physAddr);
lcdController->put_data32(physAddr, value);
return true;
case 0xC0:
case 0xC5:
case 0xC6:
case 0xC7:
- if (physAddr == 0xC0000000 && value == 0x0fff1fff) {
+ if (physAddr == 0xC0000000) {
printf ("Writing palette %08x\n", value);
}
STORE_32LE(value, physAddr & memoryMask, MemoryBlockC0);
// return true;
default:
// just throw accesses to unmapped RAM away
- printf("Write32 %08x to %08x\n", value, physAddr);
return true;
}
}
nextTimerTick += TICKS_3_6864_MHZ;
}
if (passedCycles >= nextRTCTick) {
- printf("RTC tick\n");
+ //printf("RTC tick\n");
rtc->run();
nextRTCTick += TICKS_1_HZ;
}
bool writePhysical(uint32_t value, uint32_t physAddr, ValueSize valueSize) override;
private:
- uint8_t readPhysical8(uint32_t physAddr);
- uint16_t readPhysical16(uint32_t physAddr);
- uint32_t readPhysical32(uint32_t physAddr);
+ MaybeU32 readPhysical8(uint32_t physAddr);
+ MaybeU32 readPhysical16(uint32_t physAddr);
+ MaybeU32 readPhysical32(uint32_t physAddr);
bool writePhysical8(uint8_t value, uint32_t physAddr);
bool writePhysical16(uint16_t value, uint32_t physAddr);
#include "asic14.h"
+#include "logger.h"
+
namespace SA1100 {
ASIC14::ASIC14(GPIOController* const gpioController) : mGPIOController(gpioController) {
uint16_t ASIC14::get_data(uint32_t const address) {
switch (address) {
case CTRL0:
- printf("ASIC14 read register CTRL0: %04x\n", m_CTRL0);
+ LOG_REG_R("A14Ctrl0", address, m_CTRL0);
return 0;
case KBD_PADR:
- printf("ASIC14 read register KBD_PADR: %04x\n", m_KBD_PADR);
+ LOG_REG_R("A14KbdPadr", address, m_KBD_PADR);
return m_KBD_PADR;
case CTRL_STATUS:
- printf("ASIC14 read register CTRL_STATUS: %04x\n", m_CTRL_STATUS);
+ LOG_REG_R("A14CtrlStatus", address, m_CTRL_STATUS);
return m_CTRL_STATUS;
case POWER:
- printf("ASIC14 read register POWER: %04x\n", m_POWER);
+ LOG_REG_R("A14Power", address, m_POWER);
return m_POWER;
case STATUS4:
- printf("ASIC14 read register STATUS4: %04x\n", m_STATUS4);
+ LOG_REG_R("A14Status4", address, m_STATUS4);
return m_STATUS4;
case CONTRAST:
- printf("ASIC14 read register CONTRAST: %04x\n", m_CONTRAST);
+ LOG_REG_R("A14Contrast", address, m_CONTRAST);
return m_CONTRAST;
case BRIGHTNESS:
- printf("ASIC14 read register BRIGHTNESS: %04x\n", m_BRIGHTNESS);
+ LOG_REG_R("A14Brightness", address, m_BRIGHTNESS);
return m_BRIGHTNESS;
case IRQ_STATUS:
- printf("ASIC14 read register IRQ_STATUS: %04x\n", m_IRQ_STATUS);
+ LOG_REG_R("A14IrqStatus", address, m_IRQ_STATUS);
return m_IRQ_STATUS;
case IRQ_MASK:
- printf("ASIC14 read register IRQ_MASK: %04x\n", m_IRQ_MASK);
+ LOG_REG_R("A14IrqMask", address, m_IRQ_MASK);
return m_IRQ_MASK;
case STATUS3:
- printf("ASIC14 read register STATUS3: %04x\n", m_STATUS3);
+ LOG_REG_R("A14Status3", address, m_STATUS3);
return m_STATUS3;
case KBD_SCAN:
- printf("ASIC14 read register KBD_SCAN: %04x\n", m_KBD_SCAN);
+ LOG_REG_R("A14KbdScan", address, m_KBD_SCAN);
return m_KBD_SCAN;
case IRQ_EDGE:
- printf("ASIC14 read register IRQ_EDGE: %04x\n", m_IRQ_EDGE);
+ LOG_REG_R("A14IrqEdge", address, m_IRQ_EDGE);
return m_IRQ_EDGE;
case STATUS6: {
- printf("ASIC14 read register STATUS6: %04x\n", m_STATUS6);
+ LOG_REG_R("A14Status6", address, m_STATUS6);
auto status = m_STATUS6;
m_STATUS6 = 0;
return status;
}
case SPI_DATA:
- printf("ASIC14 read register SPI_DATA: %04x\n", prom[mCurrPlace] | prom[mCurrPlace+1] << 8);
+ LOG_REG_R("A14SpiData", address, prom[mCurrPlace] | prom[mCurrPlace+1] << 8);
return prom[mCurrPlace++] | prom[mCurrPlace++] << 8;
case SPI_FN:
- printf("ASIC14 read register SPI_FN: %04x\n", m_SPI_FN);
+ LOG_REG_R("A14SpiFn", address, m_SPI_FN);
return m_SPI_FN;
default:
- printf("Unknown ASIC14 register requested %08x\n", address);
+ LOG_REG_R("A14Unknown", address, 0);
return 0;
}
}
void ASIC14::put_data(uint32_t const address, uint16_t const value) {
switch (address) {
case CTRL0:
- printf("ASIC14 write %04x to register CTRL0\n", value);
+ LOG_REG_W("A14Ctrl0", address, value);
m_CTRL0 = value;
break;
case KBD_PADR:
- printf("ASIC14 write %04x to register KBD_PADR\n", value);
+ LOG_REG_W("A14KbdPadr", address, value);
m_KBD_PADR = value;
break;
case CTRL_STATUS:
- printf("ASIC14 write %04x to register CTRL_STATUS\n", value);
- m_CTRL_STATUS &= ~value;
+ LOG_REG_W("A14CtrlStatus", address, value);
+ m_CTRL_STATUS = value;
break;
case POWER:
- printf("ASIC14 write %04x to register POWER\n", value);
+ LOG_REG_W("A14Power", address, value);
m_POWER = value;
break;
case STATUS4:
- printf("ASIC14 write %04x to register STATUS4\n", value);
- m_STATUS4 &= ~value;
+ LOG_REG_W("A14Status4", address, value);
+ m_STATUS4 = value;
break;
case CONTRAST:
- printf("ASIC14 write %04x to register CONTRAST\n", value);
+ LOG_REG_W("A14Contrast", address, value);
m_CONTRAST = value;
break;
case BRIGHTNESS:
- printf("ASIC14 write %04x to register BRIGHTNESS\n", value);
+ LOG_REG_W("A14Brightness", address, value);
m_BRIGHTNESS = value;
break;
case IRQ_STATUS:
- printf("ASIC14 write %04x to register IRQ_STATUS\n", value);
+ LOG_REG_W("A14IrqStatus", address, value);
m_IRQ_STATUS &= ~value;
break;
case IRQ_MASK:
- printf("ASIC14 write %04x to register IRQ_MASK\n", value);
+ LOG_REG_W("A14IrqMask", address, value);
m_IRQ_MASK = value;
break;
case STATUS3:
- printf("ASIC14 write %04x to register STATUS3\n", value);
- m_STATUS3 &= ~value;
+ LOG_REG_W("A14Status3", address, value);
+ m_STATUS3 = value;
break;
case KBD_SCAN:
- printf("ASIC14 write %04x to register KBD_SCAN\n", value);
+ LOG_REG_W("A14KbdScan", address, value);
m_KBD_SCAN = value;
break;
case IRQ_EDGE:
- printf("ASIC14 write %04x to register IRQ_EDGE\n", value);
+ LOG_REG_W("A14IrqEdge", address, value);
m_IRQ_EDGE = value;
break;
case STATUS6:
- printf("ASIC14 write %04x to register STATUS6\n", value);
+ LOG_REG_W("A14Status6", address, value);
//m_STATUS6 = value;
break;
case SPI_DATA:
- printf("ASIC14 write %04x to register SPI_DATA\n", value);
+ LOG_REG_W("A14SpiData", address, value);
m_SPI_DATA = value;
break;
case SPI_FN:
- printf("ASIC14 write %04x to register SPI_FN\n", value);
+ LOG_REG_W("A14SpiFn", address, value);
if (value == 4 || value == 6)
m_STATUS6 = 2;
m_SPI_FN = value;
break;
default:
- printf("ASIC14 write %04x to unknown register %08x\n", value, address);
+ LOG_REG_W("A14Unknown", address, value);
break;
}
return;
void tick() {
//m_IRQ_STATUS = IRQ_CFCARD_CHANGE | IRQ_PCMCIA_CHANGE;
- m_IRQ_STATUS = m_IRQ_MASK;
+ if (m_IRQ_MASK & 0x6000) {
+ m_IRQ_STATUS = m_IRQ_MASK;
+ }
+
if (m_IRQ_STATUS != 0) {
if (pinState == false) {
// Go high for one cycle, then low next cycle.
//
#include "gpio_controller.h"
+#include "logger.h"
namespace SA1100 {
void GPIOController::reset() {
uint32_t GPIOController::get_data(uint32_t const address) const {
switch (address) {
case GPLR:
+ LOG_REG_R("GPIO GPLR", address, m_GPLR);
return m_GPLR;
case GPDR:
+ LOG_REG_R("GPIO GPDR", address, m_GPDR);
return m_GPDR;
case GPSR:
+ // :SA-1110 Developer's Manual: p.77: Wei 2004-Jun-05:
+ //
+ // GPSR & GPCR are write-only registers.
+ LOG_REG_R("GPIO GPSR", address, 0);
+ return 0;
case GPCR:
// :SA-1110 Developer's Manual: p.77: Wei 2004-Jun-05:
//
// GPSR & GPCR are write-only registers.
+ LOG_REG_R("GPIO GPCR", address, 0);
return 0;
case GRER:
+ LOG_REG_R("GPIO GRER", address, m_GRER);
return m_GRER;
case GFER:
+ LOG_REG_R("GPIO GFER", address, m_GFER);
return m_GFER;
case GEDR:
+ LOG_REG_R("GPIO GEDR", address, m_GEDR);
return m_GEDR;
case GAFR:
+ LOG_REG_R("GPIO GAFR", address, m_GAFR);
return m_GAFR;
default:
+ LOG_REG_R("GPIO Unknown", address, 0);
return 0;
}
}
// :SA-1110 Developer's Manual: p.75: Wei 2004-Jun-05:
//
// GPLR is a read-only register.
+ LOG_REG_W("GPIO GPLR", address, value);
break;
case GPDR:
// :SA-1110 Developer's Manual: p.233: Wei 2004-Jun-06:
// :SA-1110 Developer's Manual: p.76: Wei 2004-Jun-05:
//
// The upper 4 bits are always 0.
+ LOG_REG_W("GPIO GPDR", address, value);
m_GPDR = (value & 0xFFFFFFF);
break;
case GPSR:
{
+ LOG_REG_W("GPIO GPSR", address, value);
+
// Determine what pins are configured as output and we want to set it value now.
uint32_t const temp = (m_GPDR & (value & 0xFFFFFFF));
uint32_t const new_GPLR = m_GPLR | temp;
case GPCR:
{
+ LOG_REG_W("GPIO GPCR", address, value);
+
// Determine what pins are configured as output and we want to clear it value now.
uint32_t const temp = (m_GPDR & (value & 0xFFFFFFF));
break;
case GRER:
+ LOG_REG_W("GPIO GRER", address, value);
m_GRER = (value & 0xFFFFFFF);
break;
case GFER:
+ LOG_REG_W("GPIO GFER", address, value);
m_GFER = (value & 0xFFFFFFF);
break;
case GEDR:
+ LOG_REG_W("GPIO GEDR", address, value);
// :SA-1110 Developer's Manual: p.79: Wei 2004-Jun-05:
//
// GEDR status bits are cleared by writing a one to them.
break;
case GAFR:
+ LOG_REG_W("GPIO GAFR", address, value);
// :SA-1110 Developer's Manual: p.233: Wei 2004-Jun-06:
//
// In active mode, GPIO pins 2..9 are also used.
//
#include "interrupt_controller.h"
+#include "logger.h"
namespace SA1100 {
uint32_t IntController::get_data(uint32_t const address) const {
switch (address) {
- case ICIP: return m_ICIP;
- case ICMR: return m_ICMR;
- case ICLR: return m_ICLR;
- case ICCR: return m_ICCR;
- case ICFP: return m_ICFP;
- case ICPR: return m_ICPR;
-
+ case ICIP:
+ LOG_REG_R("IntController ICIP", address, m_ICIP);
+ return m_ICIP;
+ case ICMR:
+ LOG_REG_R("IntController ICMR", address, m_ICMR);
+ return m_ICMR;
+ case ICLR:
+ LOG_REG_R("IntController ICLR", address, m_ICLR);
+ return m_ICLR;
+ case ICCR:
+ LOG_REG_R("IntController ICCR", address, m_ICCR);
+ return m_ICCR;
+ case ICFP:
+ LOG_REG_R("IntController ICFP", address, m_ICFP);
+ return m_ICFP;
+ case ICPR:
+ LOG_REG_R("IntController ICPR", address, m_ICPR);
+ return m_ICPR;
+
default:
+ LOG_REG_R("IntController Unknown", address, 0);
return 0;
}
}
// :SA-1110 Developer's Manual: Wei 2003-Dec-09:
//
// ICIP is a read-only register
+ LOG_REG_W("IntController ICIP", address, value);
break;
case ICMR:
+ LOG_REG_W("IntController ICMR", address, value);
m_ICMR = value;
break;
case ICLR:
+ LOG_REG_W("IntController ICLR", address, value);
m_ICLR = value;
break;
// :SA-1110 Developer's Manual: p.89: Wei 2004-May-09:
//
// bits[31:1] are reserved.
+ LOG_REG_W("IntController ICCR", address, value);
m_ICCR = (value & 0x1);
break;
// :SA-1110 Developer's Manual: Wei 2003-Dec-09:
//
// ICFP is a read-only register
+ LOG_REG_W("IntController ICFP", address, value);
break;
case ICPR:
// :SA-1110 Developer's Manual: Wei 2003-Dec-09:
//
// ICPR is a read-only register
+ LOG_REG_W("IntController ICPR", address, value);
break;
default:
+ LOG_REG_W("IntController Unknown", address, value);
break;
}
}
#include <iostream>
#include "lcd_controller.h"
+#include "logger.h"
namespace SA1100 {
}
uint32_t LCDController::get_data32(uint32_t const address) const {
- //std::cout << "LCD: get value at " << std::hex << address << std::endl;
-
switch (address) {
- case LCCR0: return m_LCCR0;
- case LCCR1: return m_LCCR1;
- case LCCR2: return m_LCCR2;
- case LCCR3: return m_LCCR3;
- case DBAR1: return m_DBAR1;
- case DCAR1: return m_DCAR1;
- case DBAR2: return m_DBAR2;
- case DCAR2: return m_DCAR2;
- case LCSR: return m_LCSR;
+ case LCCR0:
+ LOG_REG_R("LCD LCCR0", address, m_LCCR0);
+ return m_LCCR0;
+ case LCCR1:
+ LOG_REG_R("LCD LCCR1", address, m_LCCR1);
+ return m_LCCR1;
+ case LCCR2:
+ LOG_REG_R("LCD LCCR2", address, m_LCCR2);
+ return m_LCCR2;
+ case LCCR3:
+ LOG_REG_R("LCD LCCR3", address, m_LCCR3);
+ return m_LCCR3;
+ case DBAR1:
+ LOG_REG_R("LCD DBAR1", address, m_DBAR1);
+ return m_DBAR1;
+ case DCAR1:
+ LOG_REG_R("LCD DCAR1", address, m_DCAR1);
+ return m_DCAR1;
+ case DBAR2:
+ LOG_REG_R("LCD DBAR2", address, m_DBAR2);
+ return m_DBAR2;
+ case DCAR2:
+ LOG_REG_R("LCD DCAR2", address, m_DCAR2);
+ return m_DCAR2;
+ case LCSR:
+ LOG_REG_R("LCD LCSR", address, m_LCSR);
+ return m_LCSR;
default:
+ LOG_REG_R("LCD Unknown", address, 0);
return 0;
}
}
switch (address) {
case LCCR0:
{
- std::cout << "LCD: LCCR0: " << std::hex << value << std::endl;
-
+ LOG_REG_W("LCD LCCR0", address, value);
uint32_t const diff = (m_LCCR0 ^ value);
if ((diff & LCCR0_LEN) != 0)
{
if (0 == (value & LCCR0_LEN))
{
- std::cout << "LCD: disable lcd" << std::endl;
mEnabled = false;
m_LCSR |= LCSR_LDD;
}
else
{
- std::cout << "LCD: enable lcd" << std::endl;
mEnabled = true;
// :NOTE: Wei 2004-Jun-06:
break;
case LCCR1:
- std::cout << "LCD: LCCR1: " << std::hex << value << std::endl;
-
+ LOG_REG_W("LCD LCCR1", address, value);
// :SA-1110 Developer's Manual: Wei 2004-Jan-13:
//
// Note that the bottom four bits of PPL are not implemented and
break;
case LCCR2:
- std::cout << "LCD: LCCR2: " << std::hex << value << std::endl;
-
+ LOG_REG_W("LCD LCCR2", address, value);
m_LCCR2 = value;
break;
case LCCR3:
- std::cout << "LCD: LCCR3: " << std::hex << value << std::endl;
-
+ LOG_REG_W("LCD LCCR3", address, value);
m_LCCR3 = (value & 0xFFFFFF);
break;
case DBAR1:
- std::cout << "LCD: DBAR1: " << std::hex << value << std::endl;
-
+ LOG_REG_W("LCD DBAR1", address, value);
// :SA-1110 Developer's Manual: p.245: Wei 2003-Dec-08:
//
// Addresses programmed in the base address register must be aligned
break;
case DBAR2:
- std::cout << "LCD: DBAR2: " << std::hex << value << std::endl;
-
+ LOG_REG_W("LCD DBAR2", address, value);
// :SA-1110 Developer's Manual: p.245: Wei 2003-Dec-08:
//
// Addresses programmed in the base address register must be aligned
break;
case DCAR1:
+ LOG_REG_W("LCD DCAR1", address, value);
+ break;
case DCAR2:
+ LOG_REG_W("LCD DCAR2", address, value);
// :SA-1110 Developer's Manual: p.247: Wei 2004-Jun-06:
// :SA-1110 Developer's Manual: p.248: Wei 2004-Jun-06:
//
// These are read-only registers.
- // assert(!"Should not reach here.");
break;
case LCSR:
- std::cout << "LCD: LCSR: " << std::hex << value << std::endl;
-
+ LOG_REG_W("LCD LCSR", address, value);
// :SA-1110 Developer's Manual: p.248: Wei 2004-Jun-06:
//
// Status bits are referred to as 'sticky' (once set by hardware,
break;
default:
- // assert(!"Should not reach here.");
+ LOG_REG_W("LCD Unknown", address, value);
break;
}
}
#include "memory_conf.h"
+#include "logger.h"
+
namespace SA1100 {
void MemoryConf::reset() {
uint32_t MemoryConf::get_data(uint32_t const address) const {
switch (address) {
- case MDCNFG: return mMDCNFG;
- case MDCAS00: return mMDCAS00;
- case MDCAS01: return mMDCAS01;
- case MDCAS02: return mMDCAS02;
- case MSC0: return mMSC0;
- case MSC1: return mMSC1;
- case MECR: return mMECR;
- case MDREFR: return mMDREFR;
- case MDCAS20: return mMDCAS20;
- case MDCAS21: return mMDCAS21;
- case MDCAS22: return mMDCAS22;
- case MSC2: return mMSC2;
- case SMCNFG: return mSMCNFG;
-
+ case MDCNFG:
+ LOG_REG_R("MemConf MDCNFG", address, mMDCNFG);
+ return mMDCNFG;
+ case MDCAS00:
+ LOG_REG_R("MemConf MDCAS00", address, mMDCAS00);
+ return mMDCAS00;
+ case MDCAS01:
+ LOG_REG_R("MemConf MDCAS01", address, mMDCAS01);
+ return mMDCAS01;
+ case MDCAS02:
+ LOG_REG_R("MemConf MDCAS02", address, mMDCAS02);
+ return mMDCAS02;
+ case MSC0:
+ LOG_REG_R("MemConf MSC0", address, mMSC0);
+ return mMSC0;
+ case MSC1:
+ LOG_REG_R("MemConf MSC1", address, mMSC1);
+ return mMSC1;
+ case MECR:
+ LOG_REG_R("MemConf MECR", address, mMECR);
+ return mMECR;
+ case MDREFR:
+ LOG_REG_R("MemConf MDREFR", address, mMDREFR);
+ return mMDREFR;
+ case MDCAS20:
+ LOG_REG_R("MemConf MDCAS20", address, mMDCAS20);
+ return mMDCAS20;
+ case MDCAS21:
+ LOG_REG_R("MemConf MDCAS21", address, mMDCAS21);
+ return mMDCAS21;
+ case MDCAS22:
+ LOG_REG_R("MemConf MDCAS22", address, mMDCAS22);
+ return mMDCAS22;
+ case MSC2:
+ LOG_REG_R("MemConf MSC2", address, mMSC2);
+ return mMSC2;
+ case SMCNFG:
+ LOG_REG_R("MemConf SMCNFG", address, mSMCNFG);
+ return mSMCNFG;
default:
+ LOG_REG_R("MemConf Unknown", address, 0);
return 0;
}
}
void MemoryConf::put_data(uint32_t const address, uint32_t const value) {
switch (address) {
- case MDCNFG: mMDCNFG = value; break;
- case MDCAS00: mMDCAS00 = value; break;
- case MDCAS01: mMDCAS01 = value; break;
- case MDCAS02: mMDCAS02 = value; break;
- case MSC0: mMSC0 = value; break;
- case MSC1: mMSC1 = value; break;
- case MECR: mMECR = value; break;
- case MDREFR: mMDREFR = value; break;
- case MDCAS20: mMDCAS20 = value; break;
- case MDCAS21: mMDCAS21 = value; break;
- case MDCAS22: mMDCAS22 = value; break;
- case MSC2: mMSC2 = value; break;
- case SMCNFG: mSMCNFG = value; break;
- default: break;
+ case MDCNFG:
+ LOG_REG_W("MemConf MDCNFG", address, value);
+ mMDCNFG = value;
+ break;
+ case MDCAS00:
+ LOG_REG_W("MemConf MDCAS00", address, value);
+ mMDCAS00 = value;
+ break;
+ case MDCAS01:
+ LOG_REG_W("MemConf MDCAS01", address, value);
+ mMDCAS01 = value;
+ break;
+ case MDCAS02:
+ LOG_REG_W("MemConf MDCAS02", address, value);
+ mMDCAS02 = value;
+ break;
+ case MSC0:
+ LOG_REG_W("MemConf MSC0", address, value);
+ mMSC0 = value;
+ break;
+ case MSC1:
+ LOG_REG_W("MemConf MSC1", address, value);
+ mMSC1 = value;
+ break;
+ case MECR:
+ LOG_REG_W("MemConf MECR", address, value);
+ mMECR = value;
+ break;
+ case MDREFR:
+ LOG_REG_W("MemConf MDREFR", address, value);
+ mMDREFR = value;
+ break;
+ case MDCAS20:
+ LOG_REG_W("MemConf MDCAS20", address, value);
+ mMDCAS20 = value;
+ break;
+ case MDCAS21:
+ LOG_REG_W("MemConf MDCAS21", address, value);
+ mMDCAS21 = value;
+ break;
+ case MDCAS22:
+ LOG_REG_W("MemConf MDCAS22", address, value);
+ mMDCAS22 = value;
+ break;
+ case MSC2:
+ LOG_REG_W("MemConf MSC2", address, value);
+ mMSC2 = value;
+ break;
+ case SMCNFG:
+ LOG_REG_W("MemConf SMCNFG", address, value);
+ mSMCNFG = value;
+ break;
+ default:
+ LOG_REG_W("MemConf Unknown", address, value);
+ break;
}
}
//
#include "os_timer.h"
+#include "logger.h"
namespace SA1100 {
switch (address)
{
case OSMR0:
+ LOG_REG_R("OSTimer OSMR0", address, m_OSMR[0]);
return m_OSMR[0];
case OSMR1:
+ LOG_REG_R("OSTimer OSMR1", address, m_OSMR[1]);
return m_OSMR[1];
case OSMR2:
+ LOG_REG_R("OSTimer OSMR2", address, m_OSMR[2]);
return m_OSMR[2];
case OSMR3:
+ LOG_REG_R("OSTimer OSMR3", address, m_OSMR[3]);
return m_OSMR[3];
case OSCR:
+ LOG_REG_R("OSTimer OSCR", address, m_OSCR);
return m_OSCR;
case OSSR:
+ LOG_REG_R("OSTimer OSSR", address, m_OSSR);
return m_OSSR;
case OWER:
+ LOG_REG_R("OSTimer OWER", address, m_OWER);
return m_OWER;
case OIER:
+ LOG_REG_R("OSTimer OIER", address, m_OIER);
return m_OIER;
default:
+ LOG_REG_R("OSTimer Unknown", address, 0);
return 0;
}
}
switch (address)
{
case OSMR0:
+ LOG_REG_W("OSTimer OSMR0", address, value);
m_OSMR[0] = value;
break;
case OSMR1:
+ LOG_REG_W("OSTimer OSMR1", address, value);
m_OSMR[1] = value;
break;
case OSMR2:
+ LOG_REG_W("OSTimer OSMR2", address, value);
m_OSMR[2] = value;
break;
case OSMR3:
+ LOG_REG_W("OSTimer OSMR3", address, value);
m_OSMR[3] = value;
break;
case OSCR:
+ LOG_REG_W("OSTimer OSCR", address, value);
m_OSCR = value;
break;
case OSSR:
+ LOG_REG_W("OSTimer OSSR", address, value);
// :SA-1110 Developer's Manual: p.97: Wei 2004-Apr-24:
//
// bits 0 ~ 3 of OSSR register are cleared by writing a one to the
break;
case OWER:
+ LOG_REG_W("OSTimer OWER", address, value);
// :SA-1110 Developer's Manual: p.96: Wei 2004-Apr-24:
//
// WME (Watchdog Match Enable) bit is set by writing a one to it.
break;
case OIER:
+ LOG_REG_W("OSTimer OIER", address, value);
// :NOTE: Wei 2004-Apr-24:
//
// According to OSSR register: All reserved bits read as zeros and are unaffected by writes
break;
default:
+ LOG_REG_W("OSTimer Unknown", address, value);
break;
}
}
}
}
if (osmrs & OSMR3_MASK) {
- if (m_has_enabled_watchdog_timer) {
+ if (false && m_has_enabled_watchdog_timer) {
+ //printf("TODO: implement watchdog\n");
// TODO: implement watchdog
} else {
if (m_OSCR == m_OSMR[3]) {
#include "power_manager.h"
+#include "logger.h"
+
namespace SA1100 {
void PowerManager::reset() {
uint32_t PowerManager::get_data(uint32_t const address) const {
switch (address) {
- case PMCR: return mPMCR;
- case PSSR: return mPSSR;
- case PSPR: return mPSPR;
- case PWER: return mPWER;
- case PCFR: return mPCFR;
- case PPCR: return mPPCR;
- case PGSR: return mPGSR;
- case POSR: return mPOSR;
+ case PMCR:
+ LOG_REG_R("PowerManager PMCR", address, mPMCR);
+ return mPMCR;
+ case PSSR:
+ LOG_REG_R("PowerManager PSSR", address, mPSSR);
+ return mPSSR;
+ case PSPR:
+ LOG_REG_R("PowerManager PSPR", address, mPSPR);
+ return mPSPR;
+ case PWER:
+ LOG_REG_R("PowerManager PWER", address, mPWER);
+ return mPWER;
+ case PCFR:
+ LOG_REG_R("PowerManager PCFR", address, mPCFR);
+ return mPCFR;
+ case PPCR:
+ LOG_REG_R("PowerManager PPCR", address, mPPCR);
+ return mPPCR;
+ case PGSR:
+ LOG_REG_R("PowerManager PGSR", address, mPGSR);
+ return mPGSR;
+ case POSR:
+ LOG_REG_R("PowerManager POSR", address, mPOSR);
+ return mPOSR;
default:
+ LOG_REG_R("PowerManager Unknown", address, mPOSR);
return 0;
}
}
void PowerManager::put_data(uint32_t const address, uint32_t const value)
{
switch (address) {
- case PMCR: mPMCR = value; break;
- case PSSR: mPSSR = value; break;
- case PSPR: mPSPR = value; break;
- case PWER: mPWER = value; break;
- case PCFR: mPCFR = value; break;
+ case PMCR:
+ LOG_REG_W("PowerManager PMCR", address, value);
+ mPMCR = value;
+ break;
+ case PSSR:
+ LOG_REG_W("PowerManager PSSR", address, value);
+ mPSSR = value;
+ break;
+ case PSPR:
+ LOG_REG_W("PowerManager PSPR", address, value);
+ mPSPR = value;
+ break;
+ case PWER:
+ LOG_REG_W("PowerManager PWER", address, value);
+ mPWER = value;
+ break;
+ case PCFR:
+ LOG_REG_W("PowerManager PCFR", address, value);
+ mPCFR = value;
+ break;
case PPCR:
+ LOG_REG_W("PowerManager PPCR", address, value);
// :SA-1110 Developer's Manual: Wei 2004-Jan-11:
//
// The PPCR contains bits used to configure the core operating frequency generated by the PLL.
mPPCR = value;
break;
- case PGSR: mPGSR = value; break;
- case POSR: break;
- default: break;
+ case PGSR:
+ LOG_REG_W("PowerManager PGSR", address, value);
+ mPGSR = value;
+ break;
+ case POSR:
+ LOG_REG_W("PowerManager POSR", address, value);
+ break;
+ default:
+ LOG_REG_W("PowerManager Unknown", address, value);
+ break;
}
}
#include "reset_controller.h"
+#include "logger.h"
+
namespace SA1100
{
{
switch (address) {
case RSRR:
+ LOG_REG_R("ResetController RSRR", address, 0);
// :SA-1110 Developer's Manual: Wei 2003-Dec-11:
//
// RSRR is write-only.
return 0;
case RCSR:
+ LOG_REG_R("ResetController RCSR", address, mRCSR);
return mRCSR;
default:
+ LOG_REG_R("ResetController Unknown", address, 0);
return 0;
}
}
void ResetController::put_data(uint32_t const address, uint32_t const value) {
switch (address) {
- case RSRR: mRSRR = value; break;
- case RCSR: mRCSR = value; break;
- default: break;
+ case RSRR:
+ LOG_REG_W("ResetController RSRR", address, value);
+ mRSRR = value;
+ break;
+ case RCSR:
+ LOG_REG_W("ResetController RCSR", address, value);
+ mRCSR = value;
+ break;
+ default:
+ LOG_REG_W("ResetController Unknown", address, value);
+ break;
}
}
}
enum {
CLOCK_SPEED = 190*1000*1000, // 190MHz
TICKS_3_6864_MHZ = CLOCK_SPEED / 3686400,
- TICKS_1_HZ = CLOCK_SPEED / 64, // run the RTC a little faster just for testing
+ TICKS_1_HZ = CLOCK_SPEED / 1, // run the RTC a little faster just for testing
TICK_INTERVAL = CLOCK_SPEED / 64
};