From 723854473537f94653ea45fa7f77d781cfef6cfc Mon Sep 17 00:00:00 2001 From: meepingsnesroms Date: Thu, 3 Jan 2019 14:00:34 -0800 Subject: [PATCH] Add more ARM stuff --- roadmap.txt | 6 + src/armv5.c | 106 +++++++++++++++++- src/emulator.c | 21 +++- src/hardwareRegisters.c | 25 ++++- src/memoryAccess.h | 6 +- src/portability.h | 4 +- src/specs/emuFeatureRegisterSpec.h | 4 +- .../specs/emuFeatureRegisterSpec.h | 4 +- .../specs/emuFeatureRegisterSpec.h | 4 +- 9 files changed, 161 insertions(+), 19 deletions(-) diff --git a/roadmap.txt b/roadmap.txt index 9da2899..dd366f8 100644 --- a/roadmap.txt +++ b/roadmap.txt @@ -1,6 +1,12 @@ ------------------------------------------ The end??? +------------------------------------------ +v3.2.0 to v4.0.0(*** ** 2020 - *** ** 2020) + +Core: +Add Dragonball OG/EZ/VZ CPU builtin LCD controller support, some Palm OS 1<->3 games write directly to these registers to display their video and they won't work(with the exception of LSSA since the OS monitors that one) + ------------------------------------------ v2.5.0 to v3.2.0(*** ** 2019 - *** ** 2020) diff --git a/src/armv5.c b/src/armv5.c index 65b3275..5ba4670 100755 --- a/src/armv5.c +++ b/src/armv5.c @@ -2,6 +2,9 @@ #include #include "emulator.h" +#include "hardwareRegisters.h" +#include "memoryAccess.h" +#include "portability.h" #include "armv5/CPU.h" @@ -11,7 +14,93 @@ static uint32_t armv5StackLocation; static Boolean armv5MemoryAccess(ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 size, Boolean write, Boolean privileged, UInt8* fsr){ //ARM only has access to RAM, the OS 4 ROM has no data important to it and it would be wrong to access 68k registers from ARM + vaddr &= chips[CHIP_DX_RAM].mask; +#if !defined(EMU_NO_SAFETY) + if(size & (size - 1))//size is not a power of two + return false; + if(vaddr & (size - 1))//bad alignment + return false; +#endif + +#if defined(EMU_BIG_ENDIAN) + if(write){ + switch(size){ + case 1: + *(uint8_t*)(palmRam + vaddr) = *(uint8_t*)buf; + break; + + case 2: + *(uint16_t*)(palmRam + vaddr) = SWAP_16(*(uint16_t*)buf); + break; + + case 4: + *(uint32_t*)(palmRam + vaddr) = SWAP_32(*(uint32_t*)buf); + break; + + default: + return false; + } + } + else{ + switch(size){ + case 1: + *(uint8_t*)buf = *(uint8_t*)(palmRam + vaddr); + break; + + case 2: + *(uint16_t*)buf = SWAP_16(*(uint16_t*)(palmRam + vaddr)); + break; + + case 4: + *(uint32_t*)buf = SWAP_32(*(uint32_t*)(palmRam + vaddr)); + break; + + default: + return false; + } + } +#else + if(write){ + switch(size){ + case 1: + *(uint8_t*)(palmRam + (vaddr ^ 1)) = *(uint8_t*)buf; + break; + + case 2: + *(uint16_t*)(palmRam + vaddr) = SWAP_16(*(uint16_t*)buf); + break; + + case 4: + *(uint16_t*)(palmRam + vaddr) = SWAP_16(*(uint32_t*)buf & 0xFFFF); + *(uint16_t*)(palmRam + vaddr + 2) = SWAP_16(*(uint32_t*)buf >> 16); + break; + + default: + return false; + } + } + else{ + switch(size){ + case 1: + *(uint8_t*)buf = *(uint8_t*)(palmRam + (vaddr ^ 1)); + break; + + case 2: + *(uint16_t*)buf = SWAP_16(*(uint16_t*)(palmRam + vaddr)); + break; + + case 4: + *(uint32_t*)buf = SWAP_16(*(uint16_t*)(palmRam + vaddr + 2)) << 16 | SWAP_16(*(uint16_t*)(palmRam + vaddr)); + break; + + default: + return false; + } + } +#endif + + return true; } static Boolean armv5Hypercall(ArmCpu* cpu){ @@ -20,11 +109,11 @@ static Boolean armv5Hypercall(ArmCpu* cpu){ } static void armv5EmulErr(ArmCpu* cpu, const char* errStr){ - debugLog(errStr); + debugLog("%s", errStr); } static void armv5SetFaultAddr(struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus){ - + //TODO } void armv5Init(void){ @@ -34,23 +123,32 @@ void armv5Init(void){ } void armv5Reset(void){ - + armv5StackLocation = 0x00000000; } uint64_t armv5StateSize(void){ uint64_t size = 0; + //need to add armv5Cpu here + size += sizeof(uint32_t);//armv5StackLocation + return size; } 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){ @@ -58,7 +156,7 @@ void armv5SetStackLocation(uint32_t stackLocation){ } void armv5PceNativeCall(uint32_t functionPtr, uint32_t userdataPtr){ - //need to push some args to the stack here! + //need to push some args and a return to 68k mode function to the stack here! cpuSetReg(&armv5Cpu, 15/*pc*/, functionPtr); } diff --git a/src/emulator.c b/src/emulator.c index 8483979..3c85f49 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -5,6 +5,7 @@ #include "audio/blip_buf.h" #include "flx68000.h" +#include "armv5.h" #include "emulator.h" #include "hardwareRegisters.h" #include "memoryAccess.h" @@ -104,13 +105,17 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t enab //initialize components blip_set_rates(palmAudioResampler, AUDIO_CLOCK_RATE, AUDIO_SAMPLE_RATE); flx68000Init(); - sandboxInit(); + if(enabledEmuFeatures & FEATURE_HYBRID_CPU) + armv5Init(); + sandboxInit(); //reset everything sed1376Reset(); ads7846Reset(); pdiUsbD12Reset(); sdCardReset(); + if(enabledEmuFeatures & FEATURE_HYBRID_CPU) + armv5Reset(); flx68000Reset(); setRtc(0, 0, 0, 0);//RTCTIME and DAYR are not cleared by reset, clear them manually in case the frontend doesnt set the RTC @@ -145,6 +150,8 @@ void emulatorHardReset(void){ ads7846Reset(); pdiUsbD12Reset(); sdCardReset(); + if(palmEmuFeatures.info & FEATURE_HYBRID_CPU) + armv5Reset(); flx68000Reset(); setRtc(0, 0, 0, 0); } @@ -158,6 +165,8 @@ void emulatorSoftReset(void){ ads7846Reset(); pdiUsbD12Reset(); sdCardReset(); + if(palmEmuFeatures.info & FEATURE_HYBRID_CPU) + armv5Reset(); flx68000Reset(); } @@ -173,6 +182,8 @@ uint64_t emulatorGetStateSize(void){ size += sizeof(uint64_t);//palmSdCard.flashChip.size, needs to be done first to verify the malloc worked size += sizeof(uint16_t) * 2;//palmFramebuffer(Width/Height) size += flx68000StateSize(); + if(palmEmuFeatures.info & FEATURE_HYBRID_CPU) + size += armv5StateSize(); size += sed1376StateSize(); size += ads7846StateSize(); size += pdiUsbD12StateSize(); @@ -234,6 +245,10 @@ bool emulatorSaveState(buffer_t buffer){ //chips flx68000SaveState(buffer.data + offset); offset += flx68000StateSize(); + if(palmEmuFeatures.info & FEATURE_HYBRID_CPU){ + armv5SaveState(buffer.data + offset); + offset += armv5StateSize(); + } sed1376SaveState(buffer.data + offset); offset += sed1376StateSize(); ads7846SaveState(buffer.data + offset); @@ -411,6 +426,10 @@ bool emulatorLoadState(buffer_t buffer){ //chips flx68000LoadState(buffer.data + offset); offset += flx68000StateSize(); + if(palmEmuFeatures.info & FEATURE_HYBRID_CPU){ + armv5LoadState(buffer.data + offset); + offset += armv5StateSize(); + } sed1376LoadState(buffer.data + offset); offset += sed1376StateSize(); ads7846LoadState(buffer.data + offset); diff --git a/src/hardwareRegisters.c b/src/hardwareRegisters.c index f0a4493..2564449 100644 --- a/src/hardwareRegisters.c +++ b/src/hardwareRegisters.c @@ -293,13 +293,28 @@ void setEmuRegister(uint32_t address, uint32_t value){ break; case CMD_RUN_AS_ARM: - //not done yet - /* - if(palmEmuFeatures.info & FEATURE_HYBRID_CPU){ - //armv5PceNativeCall(uint32_t armFunctionPtr, uint32_t userdataPtr); + if(palmEmuFeatures.info & FEATURE_HYBRID_CPU) + armv5PceNativeCall(palmEmuFeatures.src, palmEmuFeatures.dst); + break; + case CMD_PRINT: + if(palmEmuFeatures.info & FEATURE_DEBUG){ + char tempString[200]; + uint16_t offset = 0; + uint8_t newChar;//cant use char, if its signed < 128 will allow non ascii chars through + + while(true){ + newChar = flx68000ReadArbitraryMemory(palmEmuFeatures.src + offset, 8); + newChar = newChar < 128 ? newChar : 0; + tempString[offset] = newChar; + offset++; + + if(newChar == 0 || offset >= 200) + break; + } + + debugLog("CMD_PRINT:%s\n", tempString); } - */ break; case CMD_GET_KEYS: diff --git a/src/memoryAccess.h b/src/memoryAccess.h index 6d6b948..afb9102 100644 --- a/src/memoryAccess.h +++ b/src/memoryAccess.h @@ -6,7 +6,7 @@ //address space //new bank size (0x4000) #define BANK_SCOOT 14 -#define NUM_BANKS(areaSize) (((areaSize) >> BANK_SCOOT) + ((areaSize) & 0x00003FFF ? 1 : 0)) +#define NUM_BANKS(areaSize) (((areaSize) >> BANK_SCOOT) + ((areaSize) & ((1 << BANK_SCOOT) - 1) ? 1 : 0)) #define START_BANK(address) ((address) >> BANK_SCOOT) #define END_BANK(address, size) (START_BANK(address) + NUM_BANKS(size) - 1) #define BANK_IN_RANGE(bank, address, size) ((bank) >= START_BANK(address) && (bank) <= END_BANK(address, size)) @@ -58,6 +58,10 @@ #define BUFFER_WRITE_32_BIG_ENDIAN(segment, accessAddress, mask, value) (segment[(accessAddress) & (mask)] = (value) >> 24, segment[(accessAddress) + 1 & (mask)] = ((value) >> 16) & 0xFF, segment[(accessAddress) + 2 & (mask)] = ((value) >> 8) & 0xFF, segment[(accessAddress) + 3 & (mask)] = (value) & 0xFF) #endif +#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)) + extern uint8_t bankType[]; void setRegisterXXFFAccessMode(void); diff --git a/src/portability.h b/src/portability.h index e451e1f..b7a13c9 100644 --- a/src/portability.h +++ b/src/portability.h @@ -181,9 +181,9 @@ static inline double getDoubleFromUint64(uint64_t data){ //1.32.31 fixed point double floatingPointDouble; - floatingPointDouble = (double)(data & UINT64_C(0x000000007FFFFFFF)); + floatingPointDouble = (double)(data & 0x7FFFFFFF); floatingPointDouble /= (double)0x7FFFFFFF; - floatingPointDouble += (double)(data >> 31 & UINT64_C(0x00000000FFFFFFFF)); + floatingPointDouble += (double)(data >> 31 & 0xFFFFFFFF); if(data & UINT64_C(0x8000000000000000)) floatingPointDouble = -floatingPointDouble; diff --git a/src/specs/emuFeatureRegisterSpec.h b/src/specs/emuFeatureRegisterSpec.h index 9d0da13..b420eb5 100644 --- a/src/specs/emuFeatureRegisterSpec.h +++ b/src/specs/emuFeatureRegisterSpec.h @@ -44,9 +44,9 @@ These registers will do nothing if their corresponding feature bit is not set on /*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_SET_RESOLUTION 0x0000FFF6/*EMU_VALUE >> 16 = width, EMU_VALUE & 0x0000FFFF = height*/ +#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_PRINTF 0x0000FFF8/*EMU_SRC = pointer to string*/ +#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*/ diff --git a/tools/palm/hwTestSuite/specs/emuFeatureRegisterSpec.h b/tools/palm/hwTestSuite/specs/emuFeatureRegisterSpec.h index 9d0da13..b420eb5 100644 --- a/tools/palm/hwTestSuite/specs/emuFeatureRegisterSpec.h +++ b/tools/palm/hwTestSuite/specs/emuFeatureRegisterSpec.h @@ -44,9 +44,9 @@ These registers will do nothing if their corresponding feature bit is not set on /*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_SET_RESOLUTION 0x0000FFF6/*EMU_VALUE >> 16 = width, EMU_VALUE & 0x0000FFFF = height*/ +#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_PRINTF 0x0000FFF8/*EMU_SRC = pointer to string*/ +#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*/ diff --git a/tools/palm/muExpansionDriver/specs/emuFeatureRegisterSpec.h b/tools/palm/muExpansionDriver/specs/emuFeatureRegisterSpec.h index 9d0da13..b420eb5 100644 --- a/tools/palm/muExpansionDriver/specs/emuFeatureRegisterSpec.h +++ b/tools/palm/muExpansionDriver/specs/emuFeatureRegisterSpec.h @@ -44,9 +44,9 @@ These registers will do nothing if their corresponding feature bit is not set on /*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_SET_RESOLUTION 0x0000FFF6/*EMU_VALUE >> 16 = width, EMU_VALUE & 0x0000FFFF = height*/ +#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_PRINTF 0x0000FFF8/*EMU_SRC = pointer to string*/ +#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*/