diff --git a/src/armv5.c b/src/armv5.c index f04d586..65b3275 100755 --- a/src/armv5.c +++ b/src/armv5.c @@ -5,7 +5,8 @@ #include "armv5/CPU.h" -static ArmCpu slaveCpu; +static ArmCpu armv5Cpu; +static uint32_t armv5StackLocation; static Boolean armv5MemoryAccess(ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 size, Boolean write, Boolean privileged, UInt8* fsr){ @@ -18,17 +19,18 @@ static Boolean armv5Hypercall(ArmCpu* cpu){ return true; } -void armv5EmulErr(ArmCpu* cpu, const char* errStr){ +static void armv5EmulErr(ArmCpu* cpu, const char* errStr){ debugLog(errStr); } -void armv5SetFaultAddr(struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus){ +static void armv5SetFaultAddr(struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus){ } 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(&slaveCpu, 0x00000000/*pc, set by 68k while emulating*/, armv5MemoryAccess, armv5EmulErr, armv5Hypercall, armv5SetFaultAddr); + cpuInit(&armv5Cpu, 0x00000000/*pc, set by 68k while emulating*/, armv5MemoryAccess, armv5EmulErr, armv5Hypercall, armv5SetFaultAddr); + armv5StackLocation = 0x00000000; } void armv5Reset(void){ @@ -36,32 +38,50 @@ void armv5Reset(void){ } uint64_t armv5StateSize(void){ + uint64_t size = 0; + return size; } void armv5SaveState(uint8_t* data){ + uint64_t offset = 0; } void armv5LoadState(uint8_t* data){ + uint64_t offset = 0; } -void armv5Execute(uint32_t cycles){ +void armv5SetStackLocation(uint32_t stackLocation){ + armv5StackLocation = stackLocation; +} + +void armv5PceNativeCall(uint32_t functionPtr, uint32_t userdataPtr){ + //need to push some args 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(&slaveCpu); + cpuCycleNoIrqs(&armv5Cpu); cycles--; } + + return cycles; } uint32_t armv5GetRegister(uint8_t reg){ - + return cpuGetRegExternal(&armv5Cpu, reg); } 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 a21c086..aa01e6f 100755 --- a/src/armv5.h +++ b/src/armv5.h @@ -10,7 +10,9 @@ uint64_t armv5StateSize(void); void armv5SaveState(uint8_t* data); void armv5LoadState(uint8_t* data); -void armv5Execute(uint32_t cycles); +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);//only for debugging uint32_t armv5GetPc(void);//only for debugging diff --git a/src/debug/sandbox.c b/src/debug/sandbox.c index aad20c2..0f9355f 100644 --- a/src/debug/sandbox.c +++ b/src/debug/sandbox.c @@ -480,7 +480,7 @@ uint32_t sandboxCommand(uint32_t command, void* data){ uint32_t result = EMU_ERROR_NONE; //tests cant run properly(hang forever) unless the debug return hook is enabled, it also completly destroys accuracy to execute hacked in asm buffers - if(!(palmSpecialFeatures & FEATURE_DEBUG)) + if(!(palmEmuFeatures.info & FEATURE_DEBUG)) return EMU_ERROR_NOT_IMPLEMENTED; debugLog("Sandbox: Command %d started\n", command); diff --git a/src/emulator.c b/src/emulator.c index 91ff99e..c9be6b2 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -38,12 +38,12 @@ uint8_t* palmReg; input_t palmInput; sd_card_t palmSdCard; misc_hw_t palmMisc; +emu_reg_t palmEmuFeatures; uint16_t* palmFramebuffer; uint16_t palmFramebufferWidth; uint16_t palmFramebufferHeight; int16_t* palmAudio; blip_t* palmAudioResampler; -uint32_t palmSpecialFeatures; double palmSysclksPerClk32;//how many SYSCLK cycles before toggling the 32.768 kHz crystal double palmCycleCounter;//can be greater then 0 if too many cycles where run double palmClockMultiplier;//used by the emulator to overclock the emulated Palm @@ -51,7 +51,7 @@ uint32_t palmFrameClk32s;//how many CLK32s have happened in the current frame double palmClk32Sysclks;//how many SYSCLKs have happened in the current CLK32 -uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t specialFeatures){ +uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t enabledEmuFeatures){ if(emulatorInitialized) return EMU_ERROR_RESOURCE_LOCKED; @@ -59,7 +59,7 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t spec return EMU_ERROR_INVALID_PARAMETER; //allocate buffers, add 4 to memory regions to prevent SIGSEGV from accessing off the end - palmRam = malloc(((specialFeatures & FEATURE_RAM_HUGE) ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE) + 4); + palmRam = malloc(((enabledEmuFeatures & FEATURE_RAM_HUGE) ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE) + 4); palmRom = malloc(ROM_SIZE + 4); palmReg = malloc(REG_SIZE + 4); palmFramebuffer = malloc(480 * 480 * sizeof(uint16_t)); @@ -76,7 +76,7 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t spec } //set default values - memset(palmRam, 0x00, specialFeatures & FEATURE_RAM_HUGE ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE); + memset(palmRam, 0x00, enabledEmuFeatures & FEATURE_RAM_HUGE ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE); memcpy(palmRom, palmRomDump.data, u64Min(palmRomDump.size, ROM_SIZE)); if(palmRomDump.size < ROM_SIZE) memset(palmRom + palmRomDump.size, 0x00, ROM_SIZE - palmRomDump.size); @@ -93,12 +93,13 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t spec memset(palmAudio, 0x00, AUDIO_SAMPLES_PER_FRAME * 2/*channels*/ * sizeof(int16_t)); memset(&palmInput, 0x00, sizeof(palmInput)); memset(&palmMisc, 0x00, sizeof(palmMisc)); + memset(&palmEmuFeatures, 0x00, sizeof(palmEmuFeatures)); palmFramebufferWidth = 160; palmFramebufferHeight = 220; palmMisc.batteryLevel = 100; palmCycleCounter = 0.0; - palmClockMultiplier = (specialFeatures & FEATURE_FAST_CPU) ? 2.00 : 1.00;//overclock - palmSpecialFeatures = specialFeatures; + palmClockMultiplier = (enabledEmuFeatures & FEATURE_FAST_CPU) ? 2.00 : 1.00;//overclock + palmEmuFeatures.info = enabledEmuFeatures; //initialize components blip_set_rates(palmAudioResampler, AUDIO_CLOCK_RATE, AUDIO_SAMPLE_RATE); @@ -136,9 +137,10 @@ void emulatorExit(void){ void emulatorHardReset(void){ //equivalent to taking the battery out and putting it back in - memset(palmRam, 0x00, palmSpecialFeatures & FEATURE_RAM_HUGE ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE); + memset(palmRam, 0x00, palmEmuFeatures.info & FEATURE_RAM_HUGE ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE); palmFramebufferWidth = 160; palmFramebufferHeight = 220; + palmEmuFeatures.value = 0x00000000; sed1376Reset(); ads7846Reset(); pdiUsbD12Reset(); @@ -151,6 +153,7 @@ void emulatorSoftReset(void){ //equivalent to pushing the reset button on the back of the device palmFramebufferWidth = 160; palmFramebufferHeight = 220; + palmEmuFeatures.value = 0x00000000; sed1376Reset(); ads7846Reset(); pdiUsbD12Reset(); @@ -173,7 +176,7 @@ uint64_t emulatorGetStateSize(void){ size += sed1376StateSize(); size += ads7846StateSize(); size += pdiUsbD12StateSize(); - if(palmSpecialFeatures & FEATURE_RAM_HUGE) + if(palmEmuFeatures.info & FEATURE_RAM_HUGE) size += SUPERMASSIVE_RAM_SIZE;//system RAM buffer else size += RAM_SIZE;//system RAM buffer @@ -214,7 +217,7 @@ bool emulatorSaveState(buffer_t buffer){ offset += sizeof(uint32_t); //features, hotpluging emulated hardware is not supported - writeStateValue32(buffer.data + offset, palmSpecialFeatures); + writeStateValue32(buffer.data + offset, palmEmuFeatures.info); offset += sizeof(uint32_t); //SD card size @@ -238,7 +241,7 @@ bool emulatorSaveState(buffer_t buffer){ offset += pdiUsbD12StateSize(); //memory - if(palmSpecialFeatures & FEATURE_RAM_HUGE){ + if(palmEmuFeatures.info & FEATURE_RAM_HUGE){ memcpy(buffer.data + offset, palmRam, SUPERMASSIVE_RAM_SIZE); swap16BufferIfLittle(buffer.data + offset, SUPERMASSIVE_RAM_SIZE / sizeof(uint16_t)); offset += SUPERMASSIVE_RAM_SIZE; @@ -377,7 +380,7 @@ bool emulatorLoadState(buffer_t buffer){ offset += sizeof(uint32_t); //features, hotpluging emulated hardware is not supported - if(readStateValue32(buffer.data + offset) != palmSpecialFeatures) + if(readStateValue32(buffer.data + offset) != palmEmuFeatures.info) return false; offset += sizeof(uint32_t); @@ -405,7 +408,7 @@ bool emulatorLoadState(buffer_t buffer){ offset += pdiUsbD12StateSize(); //memory - if(palmSpecialFeatures & FEATURE_RAM_HUGE){ + if(palmEmuFeatures.info & FEATURE_RAM_HUGE){ memcpy(palmRam, buffer.data + offset, SUPERMASSIVE_RAM_SIZE); swap16BufferIfLittle(palmRam, SUPERMASSIVE_RAM_SIZE / sizeof(uint16_t)); offset += SUPERMASSIVE_RAM_SIZE; @@ -540,11 +543,11 @@ bool emulatorLoadState(buffer_t buffer){ } uint64_t emulatorGetRamSize(void){ - return palmSpecialFeatures & FEATURE_RAM_HUGE ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE; + return palmEmuFeatures.info & FEATURE_RAM_HUGE ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE; } bool emulatorSaveRam(buffer_t buffer){ - uint64_t size = palmSpecialFeatures & FEATURE_RAM_HUGE ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE; + uint64_t size = palmEmuFeatures.info & FEATURE_RAM_HUGE ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE; if(buffer.size < size) return false; @@ -556,7 +559,7 @@ bool emulatorSaveRam(buffer_t buffer){ } bool emulatorLoadRam(buffer_t buffer){ - uint64_t size = palmSpecialFeatures & FEATURE_RAM_HUGE ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE; + uint64_t size = palmEmuFeatures.info & FEATURE_RAM_HUGE ? SUPERMASSIVE_RAM_SIZE : RAM_SIZE; if(buffer.size < size) return false; diff --git a/src/emulator.h b/src/emulator.h index 4d3600c..667c30f 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -105,6 +105,15 @@ typedef struct{ uint8_t dataPort; }misc_hw_t; +typedef struct{ + uint32_t info; + uint32_t src;//not in savestate yet! + uint32_t dst;//not in savestate yet! + uint32_t size;//not in savestate yet! + uint32_t value;//not in savestate yet! + //uint32_t cmd;//one time use, has no variable +}emu_reg_t; + //config options #define EMU_FPS 60 #define EMU_SYSCLK_PRECISION 2000000//the amount of cycles to run before adding SYSCLKs, higher = faster, higher values may skip timer events and lower audio accuracy @@ -125,12 +134,12 @@ extern uint8_t* palmReg;//dont touch extern input_t palmInput;//write allowed extern sd_card_t palmSdCard;//dont touch extern misc_hw_t palmMisc;//read/write allowed +extern emu_reg_t palmEmuFeatures;//dont touch extern uint16_t* palmFramebuffer;//read allowed extern uint16_t palmFramebufferWidth;//read allowed extern uint16_t palmFramebufferHeight;//read allowed extern int16_t* palmAudio;//read allowed, 2 channel signed 16 bit audio extern blip_t* palmAudioResampler;//dont touch -extern uint32_t palmSpecialFeatures;//read allowed extern double palmSysclksPerClk32;//dont touch extern double palmCycleCounter;//dont touch extern double palmClockMultiplier;//read/write allowed @@ -138,7 +147,7 @@ extern uint32_t palmFrameClk32s;//dont touch extern double palmClk32Sysclks;//dont touch //functions -uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t specialFeatures);//calling any emulator functions before emulatorInit results in undefined behavior +uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t enabledEmuFeatures);//calling any emulator functions before emulatorInit results in undefined behavior void emulatorExit(void); void emulatorHardReset(void); void emulatorSoftReset(void); diff --git a/src/hardwareRegisters.c b/src/hardwareRegisters.c index ad7909c..150a12e 100644 --- a/src/hardwareRegisters.c +++ b/src/hardwareRegisters.c @@ -9,6 +9,7 @@ #include "memoryAccess.h" #include "portability.h" #include "flx68000.h" +#include "armv5.h" #include "ads7846.h" #include "sdCard.h" #include "audio/blip_buf.h" @@ -254,7 +255,10 @@ uint32_t getEmuRegister(uint32_t address){ address &= 0xFFF; switch(address){ case EMU_INFO: - return palmSpecialFeatures; + return palmEmuFeatures.info; + + case EMU_VALUE: + return palmEmuFeatures.value; default: debugLog("Invalid read from emu register 0x%08X.\n", address); @@ -265,19 +269,49 @@ uint32_t getEmuRegister(uint32_t address){ void setEmuRegister(uint32_t address, uint32_t value){ address &= 0xFFF; switch(address){ + case EMU_SRC: + palmEmuFeatures.src = value; + break; + + case EMU_DST: + palmEmuFeatures.dst = value; + break; + + case EMU_SIZE: + palmEmuFeatures.size = value; + break; + + case EMU_VALUE: + palmEmuFeatures.value = value; + break; + case EMU_CMD: if(value >> 16 == EMU_CMD_KEY){ value &= 0xFFFF; switch(value){ - case CMD_EXECUTION_DONE: - if(palmSpecialFeatures & FEATURE_DEBUG) - sandboxReturn(); + case CMD_SET_ARM_STACK: + if(palmEmuFeatures.info & FEATURE_HYBRID_CPU) + armv5SetStackLocation(palmEmuFeatures.value); break; - case CMD_PRINTF: - if(palmSpecialFeatures & FEATURE_DEBUG){ + case CMD_RUN_AS_ARM: + //not done yet + /* + if(palmEmuFeatures.info & FEATURE_HYBRID_CPU){ + //armv5PceNativeCall(uint32_t armFunctionPtr, uint32_t userdataPtr); } + */ + break; + + case CMD_GET_KEYS: + if(palmEmuFeatures.info & FEATURE_EXT_KEYS) + palmEmuFeatures.value = (palmInput.buttonLeft ? EXT_BUTTON_LEFT : 0) | (palmInput.buttonRight ? EXT_BUTTON_RIGHT : 0) | (palmInput.buttonSelect ? EXT_BUTTON_SELECT : 0); + break; + + case CMD_EXECUTION_DONE: + if(palmEmuFeatures.info & FEATURE_DEBUG) + sandboxReturn(); break; default: diff --git a/src/memoryAccess.c b/src/memoryAccess.c index 51d6166..1746dd0 100644 --- a/src/memoryAccess.c +++ b/src/memoryAccess.c @@ -370,7 +370,7 @@ static uint8_t getProperBankType(uint32_t bank){ //EMUCS also cant be covered by normal chip selects if(BANK_IN_RANGE(bank, REG_START_ADDRESS, REG_SIZE) || ((bank & 0x00FF) == 0x00FF && registersAreXXFFMapped())) return CHIP_REGISTERS; - else if(palmSpecialFeatures != FEATURE_ACCURATE && BANK_IN_RANGE(bank, EMUCS_START_ADDRESS, EMUCS_SIZE)) + else if(palmEmuFeatures.info != FEATURE_ACCURATE && BANK_IN_RANGE(bank, EMUCS_START_ADDRESS, EMUCS_SIZE)) return CHIP_00_EMU; else if(chips[CHIP_A0_ROM].inBootMode || (chips[CHIP_A0_ROM].enable && BANK_IN_RANGE(bank, chips[CHIP_A0_ROM].start, chips[CHIP_A0_ROM].lineSize))) return CHIP_A0_ROM; diff --git a/src/specs/emuFeatureRegisterSpec.h b/src/specs/emuFeatureRegisterSpec.h index 5f7da4b..b575d23 100644 --- a/src/specs/emuFeatureRegisterSpec.h +++ b/src/specs/emuFeatureRegisterSpec.h @@ -27,13 +27,11 @@ These registers will do nothing if their corresponding feature bit is not set on /*registers*/ #define EMU_INFO 0x000/*gets the feature bits, read only*/ -#define EMU_HIRESFB 0x004/*sets the address of the dynamic framebuffer, read/write, EMU_SIZE must have width in the top 16 bits and height in the bottom 16 bits*/ -#define EMU_SRC 0x008/*write only*/ -#define EMU_DST 0x00C/*write only*/ -#define EMU_SIZE 0x010/*write only*/ -#define EMU_VALUE 0x014/*read/write*/ -#define EMU_CMD 0x018/*the command actually runs once this register is written with a value, write only*/ -#define EMU_KEYS 0x01C/*read only, stores the extra left/right/select keys that OS 4 Palms lack*/ +#define EMU_SRC 0x004/*write only*/ +#define EMU_DST 0x008/*write only*/ +#define EMU_SIZE 0x00C/*write only*/ +#define EMU_VALUE 0x010/*read/write*/ +#define EMU_CMD 0x014/*the command actually runs once this register is written with a value, write only*/ /*new registers go here*/ /*commands*/ @@ -46,10 +44,13 @@ These registers will do nothing if their corresponding feature bit is not set on #define CMD_STRNCPY 0x0004 #define CMD_STRCMP 0x0005 #define CMD_STRNCMP 0x0006 -#define CMD_PRINTF 0x0007 /*new HLE API cmds go here*/ /*new system cmds go here*/ +#define CMD_SET_ARM_STACK 0xFFF5/*EMU_VALUE = address of ARM stack, must be set before running ARM code*/ +#define CMD_SET_RESOLUTION 0xFFF6/*EMU_VALUE >> 16 = width, EMU_VALUE & 0x0000FFFF = height*/ +#define CMD_GET_KEYS 0xFFF7/*EMU_VALUE = OS 5 keys*/ +#define CMD_PRINTF 0xFFF8/*EMU_SRC = pointer to string*/ #define CMD_SHELL_EXECUTE 0xFFF9/*execute shell commands from inside the emulator, will be used for a cool web project*/ #define CMD_SOUND 0xFFFA/*may be needed to work around the overhead of emulating SYSCLK, will be needed fo OS5 advanced sound*/ #define CMD_EXECUTION_DONE 0xFFFB/*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 5f7da4b..b575d23 100644 --- a/tools/palm/hwTestSuite/specs/emuFeatureRegisterSpec.h +++ b/tools/palm/hwTestSuite/specs/emuFeatureRegisterSpec.h @@ -27,13 +27,11 @@ These registers will do nothing if their corresponding feature bit is not set on /*registers*/ #define EMU_INFO 0x000/*gets the feature bits, read only*/ -#define EMU_HIRESFB 0x004/*sets the address of the dynamic framebuffer, read/write, EMU_SIZE must have width in the top 16 bits and height in the bottom 16 bits*/ -#define EMU_SRC 0x008/*write only*/ -#define EMU_DST 0x00C/*write only*/ -#define EMU_SIZE 0x010/*write only*/ -#define EMU_VALUE 0x014/*read/write*/ -#define EMU_CMD 0x018/*the command actually runs once this register is written with a value, write only*/ -#define EMU_KEYS 0x01C/*read only, stores the extra left/right/select keys that OS 4 Palms lack*/ +#define EMU_SRC 0x004/*write only*/ +#define EMU_DST 0x008/*write only*/ +#define EMU_SIZE 0x00C/*write only*/ +#define EMU_VALUE 0x010/*read/write*/ +#define EMU_CMD 0x014/*the command actually runs once this register is written with a value, write only*/ /*new registers go here*/ /*commands*/ @@ -46,10 +44,13 @@ These registers will do nothing if their corresponding feature bit is not set on #define CMD_STRNCPY 0x0004 #define CMD_STRCMP 0x0005 #define CMD_STRNCMP 0x0006 -#define CMD_PRINTF 0x0007 /*new HLE API cmds go here*/ /*new system cmds go here*/ +#define CMD_SET_ARM_STACK 0xFFF5/*EMU_VALUE = address of ARM stack, must be set before running ARM code*/ +#define CMD_SET_RESOLUTION 0xFFF6/*EMU_VALUE >> 16 = width, EMU_VALUE & 0x0000FFFF = height*/ +#define CMD_GET_KEYS 0xFFF7/*EMU_VALUE = OS 5 keys*/ +#define CMD_PRINTF 0xFFF8/*EMU_SRC = pointer to string*/ #define CMD_SHELL_EXECUTE 0xFFF9/*execute shell commands from inside the emulator, will be used for a cool web project*/ #define CMD_SOUND 0xFFFA/*may be needed to work around the overhead of emulating SYSCLK, will be needed fo OS5 advanced sound*/ #define CMD_EXECUTION_DONE 0xFFFB/*terminates execution, used when a function is called from outside the emulator*/