mirror of
https://github.com/libretro/Mu.git
synced 2026-09-23 07:05:37 +00:00
Add direct trap calling from C
This commit is contained in:
@@ -103,7 +103,6 @@ MOBILITY =
|
||||
|
||||
DISTFILES += \
|
||||
images/addressBook.png \
|
||||
images/calender.png \
|
||||
images/center.png \
|
||||
images/down.png \
|
||||
images/left.png \
|
||||
@@ -126,7 +125,8 @@ DISTFILES += \
|
||||
images/play.png \
|
||||
images/saveLoad.png \
|
||||
images/screenshot.png \
|
||||
images/stop.png
|
||||
images/stop.png \
|
||||
images/calendar.png
|
||||
|
||||
RESOURCES += \
|
||||
mainwindow.qrc
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.6.1, 2018-06-02T13:31:16. -->
|
||||
<!-- Written by QtCreator 4.6.1, 2018-06-05T05:29:49. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
||||
@@ -59,7 +59,6 @@ QString DebugViewer::stringFromNumber(int64_t number, bool hex, uint32_t forcedZ
|
||||
|
||||
void DebugViewer::debugRadioButtonHandler(){
|
||||
switch(bitsPerEntry){
|
||||
|
||||
case 8:
|
||||
ui->debug8Bit->setDown(true);
|
||||
ui->debug16Bit->setDown(false);
|
||||
|
||||
@@ -234,7 +234,6 @@ uint64_t EmuWrapper::getEmulatorMemory(uint32_t address, uint8_t size){
|
||||
uint16_t m68kSr = m68k_get_reg(NULL, M68K_REG_SR);
|
||||
m68k_set_reg(M68K_REG_SR, 0x2000);//prevent privilege violations
|
||||
switch(size){
|
||||
|
||||
case 8:
|
||||
data = m68k_read_memory_8(address);
|
||||
break;
|
||||
|
||||
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
@@ -29,7 +29,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
||||
emuDebugger = new DebugViewer(this);
|
||||
refreshDisplay = new QTimer(this);
|
||||
|
||||
ui->calender->installEventFilter(this);
|
||||
ui->calendar->installEventFilter(this);
|
||||
ui->addressBook->installEventFilter(this);
|
||||
ui->todo->installEventFilter(this);
|
||||
ui->notes->installEventFilter(this);
|
||||
@@ -132,12 +132,12 @@ void MainWindow::on_power_released(){
|
||||
emu.emuInput.buttonPower = false;
|
||||
}
|
||||
|
||||
void MainWindow::on_calender_pressed(){
|
||||
emu.emuInput.buttonCalender = true;
|
||||
void MainWindow::on_calendar_pressed(){
|
||||
emu.emuInput.buttonCalendar = true;
|
||||
}
|
||||
|
||||
void MainWindow::on_calender_released(){
|
||||
emu.emuInput.buttonCalender = false;
|
||||
void MainWindow::on_calendar_released(){
|
||||
emu.emuInput.buttonCalendar = false;
|
||||
}
|
||||
|
||||
void MainWindow::on_addressBook_pressed(){
|
||||
@@ -170,7 +170,7 @@ void MainWindow::on_ctrlBtn_clicked(){
|
||||
//uint32_t error = emu.init(settings.value("resourceDirectory", "").toString() + "/palmos41-en-m515.rom", settings.value("resourceDirectory", "").toString() + "/bootloader-en-m515.rom", FEATURE_ACCURATE);
|
||||
uint32_t error = emu.init(settings.value("resourceDirectory", "").toString() + "/palmos41-en-m515.rom", ""/*no bootloader for now*/, FEATURE_ACCURATE);
|
||||
if(error == EMU_ERROR_NONE){
|
||||
ui->calender->setEnabled(true);
|
||||
ui->calendar->setEnabled(true);
|
||||
ui->addressBook->setEnabled(true);
|
||||
ui->todo->setEnabled(true);
|
||||
ui->notes->setEnabled(true);
|
||||
@@ -201,12 +201,15 @@ void MainWindow::on_ctrlBtn_clicked(){
|
||||
emu.resume();
|
||||
ui->ctrlBtn->setIcon(QIcon(":/buttons/images/pause.png"));
|
||||
}
|
||||
|
||||
ui->ctrlBtn->repaint();//Qt 5.11 broke icon changes on click, this is a patch
|
||||
}
|
||||
|
||||
void MainWindow::on_debugger_clicked(){
|
||||
if(emu.isInited()){
|
||||
emu.pause();
|
||||
ui->ctrlBtn->setIcon(QIcon(":/buttons/images/play.png"));
|
||||
ui->ctrlBtn->repaint();//Qt 5.11 broke icon changes on click, this is a patch
|
||||
emuDebugger->exec();
|
||||
}
|
||||
else{
|
||||
|
||||
@@ -35,8 +35,8 @@ private slots:
|
||||
//palm buttons
|
||||
void on_power_pressed();
|
||||
void on_power_released();
|
||||
void on_calender_pressed();
|
||||
void on_calender_released();
|
||||
void on_calendar_pressed();
|
||||
void on_calendar_released();
|
||||
void on_addressBook_pressed();
|
||||
void on_addressBook_released();
|
||||
void on_todo_pressed();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/buttons">
|
||||
<file>images/addressBook.png</file>
|
||||
<file>images/calender.png</file>
|
||||
<file>images/center.png</file>
|
||||
<file>images/down.png</file>
|
||||
<file>images/left.png</file>
|
||||
@@ -16,5 +15,6 @@
|
||||
<file>images/screenshot.png</file>
|
||||
<file>images/stop.png</file>
|
||||
<file>images/hexViewer.png</file>
|
||||
<file>images/calendar.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="6" column="0">
|
||||
<widget class="QPushButton" name="calender">
|
||||
<widget class="QPushButton" name="calendar">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
@@ -43,7 +43,7 @@
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="mainwindow.qrc">
|
||||
<normaloff>:/buttons/images/calender.png</normaloff>:/buttons/images/calender.png</iconset>
|
||||
<normaloff>:/buttons/images/calendar.png</normaloff>:/buttons/images/calendar.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -47,6 +47,7 @@ These registers will do nothing it there corresponding feature bit is not set on
|
||||
/*new HLE API cmds go here*/
|
||||
|
||||
/*new system cmds go here*/
|
||||
#define CMD_EXECUTION_DONE 0xFFFB/*1 is written here at the end of a callback to indicate when execution is done*/
|
||||
#define CMD_IDLE_X_CLK32 0xFFFC/*used to remove idle loops*/
|
||||
#define CMD_RUN_AS_M68K 0xFFFD/*emulStateP is ignored, EMU_SRC = argsOnStackP, EMU_SIZE = argsSizeAndwantA0, EMU_VALUE = trapOrFunction, on exit EMU_VALUE = Call68KFuncType() return value*/
|
||||
#define CMD_RUN_AS_ARM 0xFFFE/*EMU_SRC = nativeFuncP, EMU_DST = userDataP, on exit EMU_VALUE = PceNativeCall() return value*/
|
||||
|
||||
@@ -37,7 +37,6 @@ void ads7846SendBit(bool bit){
|
||||
ads7846PenIrqEnabled = !(ads7846ControlByte & 0x01);
|
||||
|
||||
switch(ads7846ControlByte & 0x70){
|
||||
|
||||
case 0x00:
|
||||
//temperature 1, unemulated for now
|
||||
rangeMax = 1;
|
||||
|
||||
172
src/emulator.c
172
src/emulator.c
@@ -84,7 +84,6 @@ static char* takeStackDump(uint32_t bytes){
|
||||
#if defined(EMU_LOG_APIS)
|
||||
static bool spammingTrap(uint16_t trap){
|
||||
switch(trap){
|
||||
|
||||
case 0xA249://sysTrapHwrDelay
|
||||
return true;
|
||||
|
||||
@@ -180,6 +179,154 @@ static void invalidBehaviorCheck(){
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG)
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
typedef struct{
|
||||
void* hostPointer;
|
||||
uint32_t emuPointer;
|
||||
uint64_t bytes;//may be used for strings or structs in the future
|
||||
}return_pointer_t;
|
||||
|
||||
|
||||
bool executionFinished;
|
||||
uint8_t touchCalibrateScreen[160 * 160] = {0};//add proper image
|
||||
|
||||
|
||||
uint16_t reverseLookupTrap(const char* name);//in trapNumToName.c
|
||||
|
||||
uint32_t callTrap(const char* name, const char* prototype, ...){
|
||||
//prototype is a java style function signature describing values passed and returned "v(wllp)"
|
||||
//is return void and pass a uint16_t(word), 2 uint32_t(long) and 1 pointer
|
||||
//valid types are b(yte), w(ord), l(ong), p(ointer) and v(oid), a capital letter means its a return pointer
|
||||
//EvtGetPen v(WWB) returns nothing but writes back to tha calling function with 3 pointers,
|
||||
//these are allocated in the bootloader area and interpreted to host pointers on return
|
||||
va_list args;
|
||||
const char* params = prototype + 2;
|
||||
uint16_t trap = reverseLookupTrap(name);
|
||||
uint32_t stackAddr = m68k_get_reg(NULL, M68K_REG_SP);
|
||||
uint32_t oldPc = m68k_get_reg(NULL, M68K_REG_PC);
|
||||
uint32_t oldA0 = m68k_get_reg(NULL, M68K_REG_A0);
|
||||
uint32_t oldD0 = m68k_get_reg(NULL, M68K_REG_D0);
|
||||
uint32_t trapReturn;
|
||||
return_pointer_t trapReturnPointers[10] = {0};
|
||||
uint8_t trapReturnPointerIndex = 0;
|
||||
uint32_t callWriteOut = 0xFFFFFFE0;
|
||||
|
||||
va_start(args, prototype);
|
||||
while(*params != ')'){
|
||||
uint32_t value = va_arg(args, uint32_t);
|
||||
|
||||
switch(*params){
|
||||
case 'v':
|
||||
case 'V':
|
||||
//do nothing
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
//bytes are 16 bits long on the stack due to memory alignment restrictions
|
||||
case 'w':
|
||||
stackAddr -= 2;
|
||||
m68k_write_memory_16(stackAddr, value);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
case 'p':
|
||||
stackAddr -= 4;
|
||||
m68k_write_memory_32(stackAddr, value);
|
||||
break;
|
||||
|
||||
//return pointer values
|
||||
case 'B':
|
||||
trapReturnPointers[trapReturnPointerIndex].hostPointer = va_arg(args, void*);
|
||||
trapReturnPointers[trapReturnPointerIndex].emuPointer = callWriteOut;
|
||||
trapReturnPointers[trapReturnPointerIndex].bytes = 1;
|
||||
callWriteOut += 2;
|
||||
trapReturnPointerIndex++;
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
trapReturnPointers[trapReturnPointerIndex].hostPointer = va_arg(args, void*);
|
||||
trapReturnPointers[trapReturnPointerIndex].emuPointer = callWriteOut;
|
||||
trapReturnPointers[trapReturnPointerIndex].bytes = 2;
|
||||
callWriteOut += 2;
|
||||
trapReturnPointerIndex++;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
case 'P':
|
||||
trapReturnPointers[trapReturnPointerIndex].hostPointer = va_arg(args, void*);
|
||||
trapReturnPointers[trapReturnPointerIndex].emuPointer = callWriteOut;
|
||||
trapReturnPointers[trapReturnPointerIndex].bytes = 4;
|
||||
callWriteOut += 4;
|
||||
trapReturnPointerIndex++;
|
||||
break;
|
||||
}
|
||||
|
||||
params++;
|
||||
}
|
||||
|
||||
//write to the bootloader memory, its not important when debugging
|
||||
m68k_write_memory_16(callWriteOut, 0x4E4F);//trap f opcode
|
||||
callWriteOut += 2;
|
||||
m68k_write_memory_16(callWriteOut, trap);
|
||||
callWriteOut += 2;
|
||||
|
||||
executionFinished = false;
|
||||
m68k_set_reg(M68K_REG_PC, callWriteOut - 4);
|
||||
while(!executionFinished)
|
||||
m68k_execute(1);//m68k_execute() always runs requested cycles + extra cycles of the final opcode, this executes 1 opcode
|
||||
if(prototype[0] == 'p')
|
||||
trapReturn = m68k_get_reg(NULL, M68K_REG_A0);
|
||||
else if(prototype[0] == 'b' || prototype[0] == 'w' || prototype[0] == 'l' )
|
||||
trapReturn = m68k_get_reg(NULL, M68K_REG_D0);
|
||||
else
|
||||
trapReturn = 0x00000000;
|
||||
m68k_set_reg(M68K_REG_PC, oldPc);
|
||||
m68k_set_reg(M68K_REG_A0, oldA0);
|
||||
m68k_set_reg(M68K_REG_D0, oldD0);
|
||||
|
||||
//remap all argument pointers
|
||||
for(uint8_t count = 0; count < trapReturnPointerIndex; count++){
|
||||
switch(trapReturnPointers[count].bytes){
|
||||
case 1:
|
||||
*(uint8_t*)trapReturnPointers[count].hostPointer = m68k_read_memory_8(trapReturnPointers[count].emuPointer);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*(uint16_t*)trapReturnPointers[count].hostPointer = m68k_read_memory_16(trapReturnPointers[count].emuPointer);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*(uint32_t*)trapReturnPointers[count].hostPointer = m68k_read_memory_32(trapReturnPointers[count].emuPointer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
return trapReturn;
|
||||
}
|
||||
|
||||
void sinfulExecution(){
|
||||
//jump directly to an application using sysTrapSysAppLaunch, very evil and inaccurate, will be removed before version 1.0
|
||||
static bool alreadyRun = false;
|
||||
|
||||
if(!alreadyRun){
|
||||
bool hasBooted = !memcmp(palmFramebuffer, touchCalibrateScreen, 160 * (160 + 60) * 2);
|
||||
if(hasBooted){
|
||||
/*proto: Err SysAppLaunch(UInt16 cardNo, LocalID dbID, UInt16 launchFlags,
|
||||
UInt16 cmd, MemPtr cmdPBP, UInt32 *resultP)
|
||||
SYS_TRAP(sysTrapSysAppLaunch);
|
||||
*/
|
||||
callTrap("sysTrapSysAppLaunch", "w(wlwwpp)", 0, 'calc', 0, 0, NULL, NULL);
|
||||
|
||||
alreadyRun = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t specialFeatures){
|
||||
if(emulatorInitialized)
|
||||
@@ -244,6 +391,7 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t spec
|
||||
ads7846Reset();
|
||||
sdCardInit();
|
||||
|
||||
/*
|
||||
//input
|
||||
palmInput.buttonUp = false;
|
||||
palmInput.buttonDown = false;
|
||||
@@ -251,7 +399,7 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t spec
|
||||
palmInput.buttonRight = false;//only used in hybrid mode
|
||||
palmInput.buttonSelect = false;//only used in hybrid mode
|
||||
|
||||
palmInput.buttonCalender = false;
|
||||
palmInput.buttonCalendar = false;
|
||||
palmInput.buttonAddress = false;
|
||||
palmInput.buttonTodo = false;
|
||||
palmInput.buttonNotes = false;
|
||||
@@ -274,6 +422,11 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t spec
|
||||
palmMisc.batteryCharging = false;
|
||||
palmMisc.batteryLevel = 100;
|
||||
palmMisc.inDock = false;
|
||||
*/
|
||||
memset(&palmInput, 0x00, sizeof(palmInput));
|
||||
memset(&palmSdCard, 0x00, sizeof(palmSdCard));
|
||||
memset(&palmMisc, 0x00, sizeof(palmMisc));
|
||||
palmMisc.batteryLevel = 100;
|
||||
|
||||
//config
|
||||
palmClockMultiplier = (specialFeatures & FEATURE_FAST_CPU) ? 2.0 : 1.0;//overclock
|
||||
@@ -284,15 +437,6 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t spec
|
||||
//start running
|
||||
m68k_pulse_reset();
|
||||
|
||||
/*
|
||||
double correct = 123456789.123456789;
|
||||
uint64_t swap = getUint64FromDouble(correct);
|
||||
double test = getDoubleFromUint64(swap);
|
||||
debugLog("Original double is:%lf\n", correct);
|
||||
debugLog("swap is:0x%016lX\n", swap);
|
||||
debugLog("Final double is:%lf\n", test);
|
||||
*/
|
||||
|
||||
emulatorInitialized = true;
|
||||
return EMU_ERROR_NONE;
|
||||
}
|
||||
@@ -338,11 +482,14 @@ uint32_t emulatorSetNewSdCard(uint64_t size, uint8_t type){
|
||||
palmSdCard.inserted = true;
|
||||
}
|
||||
else{
|
||||
memset(&palmSdCard, 0x00, sizeof(palmSdCard));
|
||||
/*
|
||||
palmSdCard.sessionId = 0x0000000000000000;
|
||||
palmSdCard.stateId = 0x0000000000000000;
|
||||
palmSdCard.size = 0;
|
||||
palmSdCard.type = CARD_NONE;
|
||||
palmSdCard.inserted = false;
|
||||
*/
|
||||
}
|
||||
|
||||
return EMU_ERROR_NONE;
|
||||
@@ -754,6 +901,9 @@ bool emulateUntilDebugEventOrFrameEnd(){
|
||||
|
||||
sed1376Render();
|
||||
|
||||
//launch app when framebuffer == touchscreen calibrate
|
||||
//sinfulExecution();
|
||||
|
||||
return invalidBehaviorAbort;
|
||||
#else
|
||||
emulateFrame();
|
||||
|
||||
@@ -21,6 +21,7 @@ extern "C" {
|
||||
|
||||
//debug
|
||||
#if defined(EMU_DEBUG)
|
||||
extern bool executionFinished;
|
||||
#if defined(EMU_CUSTOM_DEBUG_LOG_HANDLER)
|
||||
extern uint32_t frontendDebugStringSize;
|
||||
extern char* frontendDebugString;
|
||||
@@ -45,9 +46,9 @@ enum{
|
||||
//sdcard types
|
||||
enum{
|
||||
CARD_BEGIN = 0,
|
||||
CARD_SD = 0,
|
||||
CARD_NONE = 0,
|
||||
CARD_SD,
|
||||
CARD_MMC,
|
||||
CARD_NONE,
|
||||
CARD_END
|
||||
};
|
||||
|
||||
@@ -64,7 +65,7 @@ typedef struct{
|
||||
bool buttonRight;//only used in hybrid mode
|
||||
bool buttonSelect;//only used in hybrid mode
|
||||
|
||||
bool buttonCalender;//hw button 1
|
||||
bool buttonCalendar;//hw button 1
|
||||
bool buttonAddress;//hw button 2
|
||||
bool buttonTodo;//hw button 3
|
||||
bool buttonNotes;//hw button 4
|
||||
|
||||
@@ -155,7 +155,6 @@ static inline void pllWakeCpuIfOff(){
|
||||
if(!pllIsOn() && pllWakeWait == -1){
|
||||
//PLL is off and not already in the process of waking up
|
||||
switch(registerArrayRead16(PLLCR) & 0x0003){
|
||||
|
||||
case 0x0000:
|
||||
pllWakeWait = 32;
|
||||
break;
|
||||
@@ -337,26 +336,60 @@ static inline void updateVibratorStatus(){
|
||||
}
|
||||
|
||||
void printUnknownHwAccess(uint32_t address, uint32_t value, uint32_t size, bool isWrite){
|
||||
if(isWrite){
|
||||
if(isWrite)
|
||||
debugLog("CPU wrote %d bits of 0x%08X to register 0x%03X, PC 0x%08X.\n", size, value, address, m68k_get_reg(NULL, M68K_REG_PPC));
|
||||
}
|
||||
else{
|
||||
else
|
||||
debugLog("CPU read %d bits from register 0x%03X, PC 0x%08X.\n", size, address, m68k_get_reg(NULL, M68K_REG_PPC));
|
||||
}
|
||||
|
||||
static uint32_t getEmuRegister(uint32_t address){
|
||||
address &= 0xFFF;
|
||||
switch(address){
|
||||
|
||||
default:
|
||||
debugLog("Invalid read from emu register 0x%08X.\n", address);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
static void setEmuRegister(uint32_t address, uint32_t value){
|
||||
address &= 0xFFF;
|
||||
switch(address){
|
||||
case EMU_CMD:
|
||||
if(value >> 16 == EMU_CMD_KEY){
|
||||
value &= 0xFFFF;
|
||||
switch(value){
|
||||
case CMD_EXECUTION_DONE:
|
||||
#if defined(EMU_DEBUG)
|
||||
executionFinished = true;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
debugLog("Invalid emu command 0x%04X.\n", value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
debugLog("Invalid write 0x%08X to emu register 0x%08X.\n", value, address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getHwRegister8(uint32_t address){
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
//not emu or hardware register, invalid access
|
||||
//not emu or hardware register, invalid access
|
||||
if((address & 0x0000F000) != 0x0000F000)
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
address &= 0x00000FFF;
|
||||
#if defined(EMU_DEBUG) && defined(EMU_LOG_REGISTER_ACCESS_ALL)
|
||||
printUnknownHwAccess(address, 0, 8, false);
|
||||
#endif
|
||||
switch(address){
|
||||
|
||||
/*
|
||||
case PBDATA:
|
||||
//read outputs as is and inputs as true, floating pins are high
|
||||
@@ -443,17 +476,15 @@ uint8_t getHwRegister8(uint32_t address){
|
||||
}
|
||||
|
||||
uint16_t getHwRegister16(uint32_t address){
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
//not emu or hardware register, invalid access
|
||||
//not emu or hardware register, invalid access
|
||||
if((address & 0x0000F000) != 0x0000F000)
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
address &= 0x00000FFF;
|
||||
#if defined(EMU_DEBUG) && defined(EMU_LOG_REGISTER_ACCESS_ALL)
|
||||
printUnknownHwAccess(address, 0, 16, false);
|
||||
#endif
|
||||
switch(address){
|
||||
|
||||
case TSTAT1:
|
||||
timerStatusReadAcknowledge[0] |= registerArrayRead16(TSTAT1);//active bits acknowledged
|
||||
return registerArrayRead16(TSTAT1);
|
||||
@@ -513,12 +544,10 @@ uint16_t getHwRegister16(uint32_t address){
|
||||
}
|
||||
|
||||
uint32_t getHwRegister32(uint32_t address){
|
||||
if((address & 0x0000F000) == 0x0000E000){
|
||||
//32 bit emu register read, valid
|
||||
return 0x00000000;
|
||||
}
|
||||
else if((address & 0x0000F000) != 0x0000F000){
|
||||
//not emu or hardware register, invalid access
|
||||
//32 bit emu register read, valid
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
if((address & 0x0000F000) == 0x0000E000)
|
||||
return getEmuRegister(address);
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
@@ -527,7 +556,6 @@ uint32_t getHwRegister32(uint32_t address){
|
||||
printUnknownHwAccess(address, 0, 32, false);
|
||||
#endif
|
||||
switch(address){
|
||||
|
||||
//16 bit registers being read as 32 bit
|
||||
case PLLFSR:
|
||||
|
||||
@@ -551,17 +579,15 @@ uint32_t getHwRegister32(uint32_t address){
|
||||
|
||||
|
||||
void setHwRegister8(uint32_t address, uint8_t value){
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
//not emu or hardware register, invalid access
|
||||
//not emu or hardware register, invalid access
|
||||
if((address & 0x0000F000) != 0x0000F000)
|
||||
return;
|
||||
}
|
||||
|
||||
address &= 0x00000FFF;
|
||||
#if defined(EMU_DEBUG) && defined(EMU_LOG_REGISTER_ACCESS_ALL)
|
||||
printUnknownHwAccess(address, value, 8, true);
|
||||
#endif
|
||||
switch(address){
|
||||
|
||||
switch(address){
|
||||
case SCR:
|
||||
setScr(value);
|
||||
break;
|
||||
@@ -683,17 +709,15 @@ void setHwRegister8(uint32_t address, uint8_t value){
|
||||
}
|
||||
|
||||
void setHwRegister16(uint32_t address, uint16_t value){
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
//not emu or hardware register, invalid access
|
||||
//not emu or hardware register, invalid access
|
||||
if((address & 0x0000F000) != 0x0000F000)
|
||||
return;
|
||||
}
|
||||
|
||||
address &= 0x00000FFF;
|
||||
#if defined(EMU_DEBUG) && defined(EMU_LOG_REGISTER_ACCESS_ALL)
|
||||
printUnknownHwAccess(address, value, 16, true);
|
||||
#endif
|
||||
switch(address){
|
||||
|
||||
switch(address){
|
||||
case RTCIENR:
|
||||
//missing bits 6 and 7
|
||||
registerArrayWrite16(address, value & 0xFF3F);
|
||||
@@ -886,12 +910,10 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
}
|
||||
|
||||
void setHwRegister32(uint32_t address, uint32_t value){
|
||||
if((address & 0x0000F000) == 0x0000E000){
|
||||
//32 bit emu register write, valid
|
||||
return;
|
||||
}
|
||||
else if((address & 0x0000F000) != 0x0000F000){
|
||||
//not emu or hardware register, invalid access
|
||||
//32 bit emu register write, valid
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
if((address & 0x0000F000) == 0x0000E000)
|
||||
setEmuRegister(address, value);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -900,7 +922,6 @@ void setHwRegister32(uint32_t address, uint32_t value){
|
||||
printUnknownHwAccess(address, value, 32, true);
|
||||
#endif
|
||||
switch(address){
|
||||
|
||||
case RTCTIME:
|
||||
case RTCALRM:
|
||||
registerArrayWrite32(address, value & 0x1F3F003F);
|
||||
@@ -950,6 +971,8 @@ void resetHwRegisters(){
|
||||
spi1RxPosition = 0;
|
||||
spi1TxPosition = 0;
|
||||
|
||||
memset(chips, 0x00, sizeof(chips));
|
||||
/*
|
||||
for(uint8_t chip = CHIP_BEGIN; chip < CHIP_END; chip++){
|
||||
chips[chip].enable = false;
|
||||
chips[chip].start = 0x00000000;
|
||||
@@ -962,6 +985,7 @@ void resetHwRegisters(){
|
||||
chips[chip].supervisorOnlyProtectedMemory = false;
|
||||
chips[chip].unprotectedSize = 0x00000000;
|
||||
}
|
||||
*/
|
||||
//all chipselects are disabled at boot and CSA is mapped to 0x00000000 and covers the entire address range until CSGBA set otherwise
|
||||
chips[CHIP_A_ROM].inBootMode = true;
|
||||
|
||||
|
||||
@@ -337,7 +337,7 @@ static inline uint8_t getPortDValue(){
|
||||
|
||||
if((requestedRow & 0x20) == 0){
|
||||
//kbd row 0, pins are 0 when button pressed and 1 when released, Palm OS then uses PDPOL to swap back to pressed == 1
|
||||
portDValue |= !palmInput.buttonCalender | !palmInput.buttonAddress << 1 | !palmInput.buttonTodo << 2 | !palmInput.buttonNotes << 3;
|
||||
portDValue |= !palmInput.buttonCalendar | !palmInput.buttonAddress << 1 | !palmInput.buttonTodo << 2 | !palmInput.buttonNotes << 3;
|
||||
}
|
||||
|
||||
if((requestedRow & 0x40) == 0){
|
||||
|
||||
@@ -95,7 +95,6 @@ static inline void timer12Clk32(){
|
||||
|
||||
if(timer1Enabled && pcrTinToutConfig != 0x02){
|
||||
switch((timer1Control & 0x000E) >> 1){
|
||||
|
||||
case 0x0000://stop counter
|
||||
//do nothing
|
||||
break;
|
||||
@@ -120,7 +119,6 @@ static inline void timer12Clk32(){
|
||||
|
||||
if(timer2Enabled && pcrTinToutConfig != 0x03){
|
||||
switch((timer2Control & 0x000E) >> 1){
|
||||
|
||||
case 0x0000://stop counter
|
||||
//do nothing
|
||||
break;
|
||||
@@ -179,7 +177,6 @@ static inline void timer12Clk32(){
|
||||
|
||||
if(timer1Enabled && timer2Enabled){
|
||||
switch(pcrTinToutConfig){
|
||||
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
//do nothing
|
||||
@@ -212,10 +209,32 @@ static inline void timer12Clk32(){
|
||||
}
|
||||
}
|
||||
|
||||
static inline void watchdogSecondTickClk32(){
|
||||
//this function is part of clk32();
|
||||
uint16_t watchdogState = registerArrayRead16(WATCHDOG);
|
||||
|
||||
if(watchdogState & 0x0001){
|
||||
//watchdog enabled
|
||||
watchdogState += 0x0100;//add second to watchdog timer
|
||||
watchdogState &= 0x0383;//cap overflow
|
||||
if((watchdogState & 0x0200) == 0x0200){
|
||||
//time expired
|
||||
if(watchdogState & 0x0002){
|
||||
//interrupt
|
||||
setIprIsrBit(INT_WDT);
|
||||
}
|
||||
else{
|
||||
//reset
|
||||
emulatorReset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
registerArrayWrite16(WATCHDOG, watchdogState);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rtcAddSecondClk32(){
|
||||
//this function is part of clk32();
|
||||
|
||||
//RTC
|
||||
if(registerArrayRead16(RTCCTL) & 0x0080){
|
||||
//RTC enable bit set
|
||||
uint16_t rtcInterruptEvents = 0x0000;
|
||||
@@ -275,26 +294,7 @@ static inline void rtcAddSecondClk32(){
|
||||
registerArrayWrite16(DAYR, days & 0x01FF);
|
||||
}
|
||||
|
||||
//watchdog
|
||||
uint16_t watchdogState = registerArrayRead16(WATCHDOG);
|
||||
if(watchdogState & 0x0001){
|
||||
//watchdog enabled
|
||||
watchdogState += 0x0100;//add second to watchdog timer
|
||||
watchdogState &= 0x0383;//cap overflow
|
||||
if((watchdogState & 0x0200) == 0x0200){
|
||||
//time expired
|
||||
if(watchdogState & 0x0002){
|
||||
//interrupt
|
||||
setIprIsrBit(INT_WDT);
|
||||
}
|
||||
else{
|
||||
//reset
|
||||
emulatorReset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
registerArrayWrite16(WATCHDOG, watchdogState);
|
||||
}
|
||||
watchdogSecondTickClk32();
|
||||
}
|
||||
|
||||
void clk32(){
|
||||
|
||||
@@ -105,7 +105,6 @@ static inline bool probeWrite(uint8_t bank, uint32_t address){
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Read from anywhere */
|
||||
uint8_t m68k_read_memory_8(uint32_t address){
|
||||
uint8_t addressType = bankType[START_BANK(address)];
|
||||
|
||||
@@ -113,7 +112,6 @@ uint8_t m68k_read_memory_8(uint32_t address){
|
||||
return 0x00;
|
||||
|
||||
switch(addressType){
|
||||
|
||||
case CHIP_A_ROM:
|
||||
return romRead8(address);
|
||||
|
||||
@@ -148,7 +146,6 @@ uint16_t m68k_read_memory_16(uint32_t address){
|
||||
return 0x0000;
|
||||
|
||||
switch(addressType){
|
||||
|
||||
case CHIP_A_ROM:
|
||||
return romRead16(address);
|
||||
|
||||
@@ -183,7 +180,6 @@ uint32_t m68k_read_memory_32(uint32_t address){
|
||||
return 0x00000000;
|
||||
|
||||
switch(addressType){
|
||||
|
||||
case CHIP_A_ROM:
|
||||
return romRead32(address);
|
||||
|
||||
@@ -211,7 +207,6 @@ uint32_t m68k_read_memory_32(uint32_t address){
|
||||
return 0x00000000;
|
||||
}
|
||||
|
||||
/* Write to anywhere */
|
||||
void m68k_write_memory_8(uint32_t address, uint8_t value){
|
||||
uint8_t addressType = bankType[START_BANK(address)];
|
||||
|
||||
@@ -219,7 +214,6 @@ void m68k_write_memory_8(uint32_t address, uint8_t value){
|
||||
return;
|
||||
|
||||
switch(addressType){
|
||||
|
||||
case CHIP_A_ROM:
|
||||
break;
|
||||
|
||||
@@ -257,7 +251,6 @@ void m68k_write_memory_16(uint32_t address, uint16_t value){
|
||||
return;
|
||||
|
||||
switch(addressType){
|
||||
|
||||
case CHIP_A_ROM:
|
||||
break;
|
||||
|
||||
@@ -295,7 +288,6 @@ void m68k_write_memory_32(uint32_t address, uint32_t value){
|
||||
return;
|
||||
|
||||
switch(addressType){
|
||||
|
||||
case CHIP_A_ROM:
|
||||
break;
|
||||
|
||||
@@ -332,7 +324,7 @@ void m68k_write_memory_32_pd(uint32_t address, uint32_t value){
|
||||
m68k_write_memory_32(address, value >> 16 | value << 16);
|
||||
}
|
||||
|
||||
/* Memory access for the disassembler */
|
||||
//memory access for the disassembler
|
||||
uint8_t m68k_read_disassembler_8(uint32_t address){return m68k_read_memory_8(address);}
|
||||
uint16_t m68k_read_disassembler_16(uint32_t address){return m68k_read_memory_16(address);}
|
||||
uint32_t m68k_read_disassembler_32(uint32_t address){return m68k_read_memory_32(address);}
|
||||
@@ -381,17 +373,18 @@ void setRegisterFFFFAccessMode(){
|
||||
void setSed1376Attached(bool attached){
|
||||
if(chips[CHIP_B_SED].enable){
|
||||
if(attached){
|
||||
for(uint32_t bank = START_BANK(chips[CHIP_B_SED].start); bank <= END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size); bank++)
|
||||
for(uint16_t bank = START_BANK(chips[CHIP_B_SED].start); bank <= END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size); bank++)
|
||||
bankType[bank] = CHIP_B_SED;
|
||||
}
|
||||
else{
|
||||
for(uint32_t bank = START_BANK(chips[CHIP_B_SED].start); bank <= END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size); bank++)
|
||||
for(uint16_t bank = START_BANK(chips[CHIP_B_SED].start); bank <= END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size); bank++)
|
||||
bankType[bank] = CHIP_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resetAddressSpace(){
|
||||
//#pragma omp parallel for
|
||||
for(uint32_t bank = 0; bank < TOTAL_MEMORY_BANKS; bank++)
|
||||
bankType[bank] = getProperBankType(bank);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ static uint16_t (*renderPixel)(uint16_t x, uint16_t y);
|
||||
static inline uint32_t getBufferStartAddress(){
|
||||
uint32_t screenStartAddress = sed1376Registers[DISP_ADDR_2] << 16 | sed1376Registers[DISP_ADDR_1] << 8 | sed1376Registers[DISP_ADDR_0];
|
||||
switch((sed1376Registers[SPECIAL_EFFECT] & 0x03) * 90){
|
||||
|
||||
case 0:
|
||||
//desired byte address / 4.
|
||||
screenStartAddress *= 4;
|
||||
@@ -73,7 +72,6 @@ static inline uint32_t getBufferStartAddress(){
|
||||
static inline uint32_t getPipStartAddress(){
|
||||
uint32_t pipStartAddress = sed1376Registers[PIP_ADDR_2] << 16 | sed1376Registers[PIP_ADDR_1] << 8 | sed1376Registers[PIP_ADDR_0];
|
||||
switch((sed1376Registers[SPECIAL_EFFECT] & 0x03) * 90){
|
||||
|
||||
case 0:
|
||||
//desired byte address / 4.
|
||||
pipStartAddress *= 4;
|
||||
@@ -119,7 +117,6 @@ uint8_t sed1376GetRegister(uint8_t address){
|
||||
debugLog("SED1376 register read from 0x%02X, PC 0x%08X.\n", address, m68k_get_reg(NULL, M68K_REG_PPC));
|
||||
#endif
|
||||
switch(address){
|
||||
|
||||
case LUT_READ_LOC:
|
||||
case LUT_WRITE_LOC:
|
||||
case LUT_R_WRITE:
|
||||
@@ -160,7 +157,6 @@ void sed1376SetRegister(uint8_t address, uint8_t value){
|
||||
debugLog("SED1376 register write 0x%02X to 0x%02X, PC 0x%08X.\n", value, address, m68k_get_reg(NULL, M68K_REG_PPC));
|
||||
#endif
|
||||
switch(address){
|
||||
|
||||
case PWR_SAVE_CFG:
|
||||
//bit 7 must always be set, timing hack
|
||||
sed1376Registers[address] = (value & 0x01) | 0x80;
|
||||
|
||||
@@ -65,7 +65,6 @@ static inline void selectRenderer(bool color, uint8_t bpp){
|
||||
renderPixel = NULL;
|
||||
if(color){
|
||||
switch(bpp){
|
||||
|
||||
case 1:
|
||||
renderPixel = get1BppColor;
|
||||
break;
|
||||
@@ -89,7 +88,6 @@ static inline void selectRenderer(bool color, uint8_t bpp){
|
||||
}
|
||||
else{
|
||||
switch(bpp){
|
||||
|
||||
case 1:
|
||||
renderPixel = get1BppMonochrome;
|
||||
break;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "emulator.h"//for EMU_* flags
|
||||
#include "emulator.h"//for EMU_DEBUG flag
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_OPCODE_LEVEL_DEBUG) && defined(EMU_LOG_APIS)
|
||||
#if defined(EMU_DEBUG)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>//for NULL
|
||||
@@ -1163,4 +1163,11 @@ const char* lookupTrap(uint16_t trap){
|
||||
return "Trap function ID unknown";
|
||||
}
|
||||
|
||||
uint16_t reverseLookupTrap(const char* name){
|
||||
for(uint32_t i = 0; i < sizeof(traps) / sizeof(traps[0]); i++)
|
||||
if(!strcmp(traps[i].name, name))
|
||||
return traps[i].trap;
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user