From e1ef2fe5a107327a6b1a1cb7cb303f7ebb51f5b0 Mon Sep 17 00:00:00 2001 From: meepingsnesroms Date: Fri, 4 Jan 2019 11:06:50 -0800 Subject: [PATCH] ARM now seems to be fully attached, also hooked up more emu commands(Ill need them later anyway) Just need to write the driver and get save states working for ARM. --- qtBuildSystem/Mu/mainwindow.cpp | 15 +++---- src/ads7846.c | 1 + src/armv5.c | 63 ++++++++++++------------------ src/armv5.h | 11 +++--- src/emulator.c | 3 +- src/emulator.h | 2 +- src/hardwareRegisters.c | 25 ++++++++++-- src/memoryAccess.h | 4 +- src/pdiUsbD12.c | 2 +- src/specs/emuFeatureRegisterSpec.h | 12 +++--- 10 files changed, 71 insertions(+), 67 deletions(-) diff --git a/qtBuildSystem/Mu/mainwindow.cpp b/qtBuildSystem/Mu/mainwindow.cpp index 27e08c0..51f1522 100644 --- a/qtBuildSystem/Mu/mainwindow.cpp +++ b/qtBuildSystem/Mu/mainwindow.cpp @@ -292,8 +292,10 @@ void MainWindow::on_right_released(){ //emu control void MainWindow::on_ctrlBtn_clicked(){ if(!emu.isInited()){ + uint32_t enabledFeatures = FEATURE_EXT_KEYS | FEATURE_HYBRID_CPU | FEATURE_CUSTOM_FB | FEATURE_DEBUG; QString sysDir = settings->value("resourceDirectory", "").toString(); - uint32_t error = emu.init(sysDir + "/palmos41-en-m515.rom", QFile(sysDir + "/bootloader-en-m515.rom").exists() ? sysDir + "/bootloader-en-m515.rom" : "", sysDir + "/userdata-en-m515.ram", sysDir + "/sd-en-m515.img", FEATURE_CUSTOM_FB | FEATURE_DEBUG); + uint32_t error = emu.init(sysDir + "/palmos41-en-m515.rom", QFile(sysDir + "/bootloader-en-m515.rom").exists() ? sysDir + "/bootloader-en-m515.rom" : "", sysDir + "/userdata-en-m515.ram", sysDir + "/sd-en-m515.img", enabledFeatures); + if(error == EMU_ERROR_NONE){ ui->calendar->setEnabled(true); ui->addressBook->setEnabled(true); @@ -305,12 +307,11 @@ void MainWindow::on_ctrlBtn_clicked(){ ui->power->setEnabled(true); - /* - //if FEATURE_EXT_KEYS enabled add OS 5 buttons - ui->left->setEnabled(true); - ui->right->setEnabled(true); - ui->center->setEnabled(true); - */ + if(enabledFeatures & FEATURE_EXT_KEYS){ + ui->left->setEnabled(true); + ui->right->setEnabled(true); + ui->center->setEnabled(true); + } ui->screenshot->setEnabled(true); ui->install->setEnabled(true); diff --git a/src/ads7846.c b/src/ads7846.c index 76c4338..9926096 100644 --- a/src/ads7846.c +++ b/src/ads7846.c @@ -8,6 +8,7 @@ bool ads7846PenIrqEnabled; static const uint16_t ads7846DockResistorValues[PORT_END] = {0xFFF/*none*/, 0x1EB/*USB cradle*/, 0x000/*serial cradle, unknown*/, 0x000/*USB peripheral, unknown*/, 0x000/*serial peripheral, unknown*/}; + static uint8_t ads7846BitsToNextControl; static uint8_t ads7846ControlByte; static uint16_t ads7846OutputValue; diff --git a/src/armv5.c b/src/armv5.c index 5ba4670..667ae82 100755 --- a/src/armv5.c +++ b/src/armv5.c @@ -8,8 +8,12 @@ #include "armv5/CPU.h" +#define ARMV5_CYCLES_PER_OPCODE 2 + + +bool armv5ServiceRequest;//not in states yet! + static ArmCpu armv5Cpu; -static uint32_t armv5StackLocation; static Boolean armv5MemoryAccess(ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 size, Boolean write, Boolean privileged, UInt8* fsr){ @@ -104,7 +108,7 @@ static Boolean armv5MemoryAccess(ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 siz } static Boolean armv5Hypercall(ArmCpu* cpu){ - //return true if handled, does nothing for now + armv5ServiceRequest = true; return true; } @@ -116,21 +120,15 @@ static void armv5SetFaultAddr(struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus) //TODO } -void armv5Init(void){ - //cant return an error, the only possible error was if int sizes are wrong which is already handled by (u)int(8/16/32/64)_t types - cpuInit(&armv5Cpu, 0x00000000/*pc, set by 68k while emulating*/, armv5MemoryAccess, armv5EmulErr, armv5Hypercall, armv5SetFaultAddr); - armv5StackLocation = 0x00000000; -} - void armv5Reset(void){ - armv5StackLocation = 0x00000000; + cpuInit(&armv5Cpu, 0x00000000/*pc, set by 68k while emulating*/, armv5MemoryAccess, armv5EmulErr, armv5Hypercall, armv5SetFaultAddr); + armv5ServiceRequest = false; } uint64_t armv5StateSize(void){ uint64_t size = 0; //need to add armv5Cpu here - size += sizeof(uint32_t);//armv5StackLocation return size; } @@ -139,47 +137,34 @@ void armv5SaveState(uint8_t* data){ uint64_t offset = 0; //need to add armv5Cpu here - writeStateValue32(data + offset, armv5StackLocation); - offset += sizeof(uint32_t); } void armv5LoadState(uint8_t* data){ uint64_t offset = 0; //need to add armv5Cpu here - armv5StackLocation = readStateValue32(data + offset); - offset += sizeof(uint32_t); -} - -void armv5SetStackLocation(uint32_t stackLocation){ - armv5StackLocation = stackLocation; -} - -void armv5PceNativeCall(uint32_t functionPtr, uint32_t userdataPtr){ - //need to push some args and a return to 68k mode function to the stack here! - - cpuSetReg(&armv5Cpu, 15/*pc*/, functionPtr); -} - -uint32_t armv5Execute(uint32_t cycles){ - //on a ARM device ARM is faster than 68k, each ARM opcode is equivalent to 2 68k cycles here - - while(cycles > 0){ - cpuCycleNoIrqs(&armv5Cpu); - cycles--; - } - - return cycles; } uint32_t armv5GetRegister(uint8_t reg){ return cpuGetRegExternal(&armv5Cpu, reg); } +void armv5SetRegister(uint8_t reg, uint32_t value){ + cpuSetReg(&armv5Cpu, reg, value); +} + +int32_t armv5Execute(int32_t cycles){ + armv5ServiceRequest = false; + + //execution aborts on hypercall to request things from the 68k + while(cycles > 0 && !armv5ServiceRequest){ + cpuCycleNoIrqs(&armv5Cpu); + cycles -= ARMV5_CYCLES_PER_OPCODE; + } + + return cycles; +} + uint32_t armv5GetPc(void){ return cpuGetRegExternal(&armv5Cpu, 15/*pc*/); } - -uint64_t armv5ReadArbitraryMemory(uint32_t address, uint8_t size){ - return UINT64_MAX;//invalid access -} diff --git a/src/armv5.h b/src/armv5.h index aa01e6f..2321ce1 100755 --- a/src/armv5.h +++ b/src/armv5.h @@ -4,18 +4,17 @@ #include #include -void armv5Init(void); +extern bool armv5ServiceRequest; + void armv5Reset(void); uint64_t armv5StateSize(void); void armv5SaveState(uint8_t* data); void armv5LoadState(uint8_t* data); -void armv5SetStackLocation(uint32_t stackLocation); -void armv5PceNativeCall(uint32_t functionPtr, uint32_t userdataPtr); -uint32_t armv5Execute(uint32_t cycles);//returns cycles left +uint32_t armv5GetRegister(uint8_t reg); +void armv5SetRegister(uint8_t reg, uint32_t value); +int32_t armv5Execute(int32_t cycles);//returns cycles left -uint32_t armv5GetRegister(uint8_t reg);//only for debugging uint32_t armv5GetPc(void);//only for debugging -uint64_t armv5ReadArbitraryMemory(uint32_t address, uint8_t size);//only for debugging #endif diff --git a/src/emulator.c b/src/emulator.c index 3c85f49..1a4f908 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -100,13 +100,12 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t enab palmMisc.batteryLevel = 100; palmCycleCounter = 0.0; palmClockMultiplier = (enabledEmuFeatures & FEATURE_FAST_CPU) ? 2.00 : 1.00;//overclock + palmClockMultiplier *= 0.70;//account for wait states when reading memory, tested with SysInfo.prc palmEmuFeatures.info = enabledEmuFeatures; //initialize components blip_set_rates(palmAudioResampler, AUDIO_CLOCK_RATE, AUDIO_SAMPLE_RATE); flx68000Init(); - if(enabledEmuFeatures & FEATURE_HYBRID_CPU) - armv5Init(); sandboxInit(); //reset everything diff --git a/src/emulator.h b/src/emulator.h index abb6c33..cf9b805 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -142,7 +142,7 @@ extern int16_t* palmAudio;//read allowed, 2 channel signed 16 bit audio extern blip_t* palmAudioResampler;//dont touch extern double palmSysclksPerClk32;//dont touch extern double palmCycleCounter;//dont touch -extern double palmClockMultiplier;//read/write allowed +extern double palmClockMultiplier;//dont touch extern uint32_t palmFrameClk32s;//dont touch extern double palmClk32Sysclks;//dont touch diff --git a/src/hardwareRegisters.c b/src/hardwareRegisters.c index 2564449..f771d4a 100644 --- a/src/hardwareRegisters.c +++ b/src/hardwareRegisters.c @@ -287,14 +287,31 @@ void setEmuRegister(uint32_t address, uint32_t value){ case EMU_CMD: switch(value){ - case CMD_SET_ARM_STACK: + case CMD_ARM_SERVICE: if(palmEmuFeatures.info & FEATURE_HYBRID_CPU) - armv5SetStackLocation(palmEmuFeatures.value); + palmEmuFeatures.value = armv5ServiceRequest; break; - case CMD_RUN_AS_ARM: + case CMD_ARM_SET_REG: if(palmEmuFeatures.info & FEATURE_HYBRID_CPU) - armv5PceNativeCall(palmEmuFeatures.src, palmEmuFeatures.dst); + armv5SetRegister(palmEmuFeatures.dst, palmEmuFeatures.value); + break; + + case CMD_ARM_GET_REG: + if(palmEmuFeatures.info & FEATURE_HYBRID_CPU) + palmEmuFeatures.value = armv5GetRegister(palmEmuFeatures.src); + break; + + case CMD_ARM_RUN: + if(palmEmuFeatures.info & FEATURE_HYBRID_CPU) + palmEmuFeatures.value = armv5Execute(palmEmuFeatures.value); + break; + + case CMD_SET_RESOLUTION: + if(palmEmuFeatures.info & FEATURE_CUSTOM_FB){ + palmFramebufferWidth = palmEmuFeatures.value >> 16; + palmFramebufferHeight = palmEmuFeatures.value & 0xFFFF; + } break; case CMD_PRINT: diff --git a/src/memoryAccess.h b/src/memoryAccess.h index afb9102..82314b8 100644 --- a/src/memoryAccess.h +++ b/src/memoryAccess.h @@ -29,7 +29,7 @@ //the read/write stuff looks messy here but makes the memory access functions alot cleaner #if defined(EMU_BIG_ENDIAN) -//memory layout is the same as the Palm m515, just cast to pointer and access +//memory layout is the same as the Palm m515, just cast to pointer and access, 32 bit accesses are split to prevent unaligned access issues #define BUFFER_READ_8(segment, accessAddress, mask) (*(uint8_t*)(segment + ((accessAddress) & (mask)))) #define BUFFER_READ_16(segment, accessAddress, mask) (*(uint16_t*)(segment + ((accessAddress) & (mask)))) #define BUFFER_READ_32(segment, accessAddress, mask) (*(uint16_t*)(segment + ((accessAddress) & (mask))) << 16 | *(uint16_t*)(segment + ((accessAddress) + 2 & (mask)))) @@ -60,7 +60,7 @@ #define SWAP_16(x) ((uint16_t)((((uint16_t)(x) & 0x00FF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8))) #define SWAP_32(x) ((uint32_t)((((uint32_t)(x) & 0x000000FF) << 24) | (((uint32_t)(x) & 0x0000FF00) << 8) | (((uint32_t)(x) & 0x00FF0000) >> 8) | (((uint32_t)(x) & 0xFF000000) >> 24))) -#define SWAP_64(val) ((((uint64_t)(val) & UINT64_C(0x00000000000000FF)) << 56) | (((uint64_t)(val) & UINT64_C(0x000000000000FF00)) << 40) | (((uint64_t)(val) & UINT64_C(0x0000000000FF0000)) << 24) | (((uint64_t)(val) & UINT64_C(0x00000000FF000000)) << 8) | (((uint64_t)(val) & UINT64_C(0x000000FF00000000)) >> 8) | (((uint64_t)(val) & UINT64_C(0x0000FF0000000000)) >> 24) | (((uint64_t)(val) & UINT64_C(0x00FF000000000000)) >> 40) | (((uint64_t)(val) & UINT64_C(0xFF00000000000000)) >> 56)) +#define SWAP_64(x) ((((uint64_t)(x) & UINT64_C(0x00000000000000FF)) << 56) | (((uint64_t)(x) & UINT64_C(0x000000000000FF00)) << 40) | (((uint64_t)(x) & UINT64_C(0x0000000000FF0000)) << 24) | (((uint64_t)(x) & UINT64_C(0x00000000FF000000)) << 8) | (((uint64_t)(x) & UINT64_C(0x000000FF00000000)) >> 8) | (((uint64_t)(x) & UINT64_C(0x0000FF0000000000)) >> 24) | (((uint64_t)(x) & UINT64_C(0x00FF000000000000)) >> 40) | (((uint64_t)(x) & UINT64_C(0xFF00000000000000)) >> 56)) extern uint8_t bankType[]; diff --git a/src/pdiUsbD12.c b/src/pdiUsbD12.c index ab6b7d5..7b05d6f 100644 --- a/src/pdiUsbD12.c +++ b/src/pdiUsbD12.c @@ -85,7 +85,7 @@ uint8_t pdiUsbD12GetRegister(bool address){ } else{ //0x1 commands - debugLog("USB read command\n", address); + debugLog("USB read command\n"); //may just return 0x00(or random 0xXX) or may return current command(not read by Palm OS during boot up) } diff --git a/src/specs/emuFeatureRegisterSpec.h b/src/specs/emuFeatureRegisterSpec.h index b420eb5..50437cf 100644 --- a/src/specs/emuFeatureRegisterSpec.h +++ b/src/specs/emuFeatureRegisterSpec.h @@ -43,17 +43,19 @@ These registers will do nothing if their corresponding feature bit is not set on /*new HLE API cmds go here*/ /*new system cmds go here*/ -#define CMD_SET_ARM_STACK 0x0000FFF5/*EMU_VALUE = address of ARM stack, must be set before running ARM code*/ +#define CMD_IDLE_X_CLK32 0x0000FFF4/*EMU_VALUE = CLK32s to waste, used to remove idle loops*/ +#define CMD_SET_CYCLE_COST 0x0000FFF5/*EMU_DST = HLE API number, EMU_VALUE = how many cycles it takes*/ +#define CMD_SET_CYCLE_COST 0x0000FFF5/*EMU_DST = HLE API number, EMU_VALUE = how many cycles it takes*/ #define CMD_SET_RESOLUTION 0x0000FFF6/*EMU_VALUE >> 16 = width, EMU_VALUE & 0xFFFF = height*/ #define CMD_GET_KEYS 0x0000FFF7/*EMU_VALUE = OS 5 keys*/ #define CMD_PRINT 0x0000FFF8/*EMU_SRC = pointer to string*/ #define CMD_SHELL_EXECUTE 0x0000FFF9/*execute shell commands from inside the emulator, will be used for a cool web project*/ #define CMD_SOUND 0x0000FFFA/*needed for OS 5 advanced sound*/ #define CMD_EXECUTION_DONE 0x0000FFFB/*terminates execution, used when a function is called from outside the emulator*/ -#define CMD_IDLE_X_CLK32 0x0000FFFC/*used to remove idle loops*/ -#define CMD_RUN_AS_M68K 0x0000FFFD/*emulStateP is ignored, EMU_SRC = argsOnStackP, EMU_SIZE = argsSizeAndwantA0, EMU_VALUE = trapOrFunction, on exit EMU_VALUE = Call68KFuncType() return value*/ -#define CMD_RUN_AS_ARM 0x0000FFFE/*EMU_SRC = nativeFuncP, EMU_DST = userDataP, on exit EMU_VALUE = PceNativeCall() return value*/ -#define CMD_SET_CYCLE_COST 0x0000FFFF/*EMU_DST = HLE API number, EMU_VALUE = how many cycles it takes*/ +#define CMD_ARM_SERVICE 0x0000FFFC/*EMU_VALUE = 1 if ARM wants service from 68k routines*/ +#define CMD_ARM_SET_REG 0x0000FFFD/*EMU_DST = register number, EMU_VALUE = new value*/ +#define CMD_ARM_GET_REG 0x0000FFFE/*EMU_SRC = register number, EMU_VALUE = value after calling*/ +#define CMD_ARM_RUN 0x0000FFFF/*EMU_VALUE = cycles, EMU_VALUE = cycles not used on return, 0 if all are used*/ /*buttons*/ #define EXT_BUTTON_LEFT 0x01000000