mirror of
https://github.com/libretro/Mu.git
synced 2026-09-23 07:05:37 +00:00
The program counter and status register were not saved properly with the old method, load stating after a emulated crash or lockup now works
This commit is contained in:
@@ -6,10 +6,10 @@ When running OS commands through callFunction() it can crash
|
||||
Only runs in debug mode because the touchscreen can only be pushed with a jump to OS function hack
|
||||
Holding the buttons emulates pressing them like a turbo button(may be caused by the lack of sound emulation, a sound plays on app switch and may block the CPU while waiting for the button to release)
|
||||
State manager goes bezerk and crashes when saving on android, also can't close the window or it won't open again(also only on android)
|
||||
Lockups occur when a state is loaded after the device locked up from trying to boot with an SD card(some part of the devices state is not being saved)
|
||||
Screen doesnt have the proper size on load on android(rotating it sideways and back fixes it)
|
||||
|
||||
Fixed:
|
||||
Lockups occur when a state is loaded after the device locked up from trying to boot with an SD card(the program counter and status register where not restored properly)
|
||||
Deleting a save state
|
||||
Screenshots use window size and that makes them blurry from filtering
|
||||
State menu jitters when made too small(smallest size is now 30x40)
|
||||
|
||||
@@ -106,7 +106,7 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t spec
|
||||
palmClockMultiplier = (specialFeatures & FEATURE_FAST_CPU) ? 2.0 : 1.0;//overclock
|
||||
palmClockMultiplier *= 0.80;//run at 80% speed, 20% is likely memory waitstates, at 100% it crashes on the spinning Palm welcome screen, 90% works though
|
||||
palmSpecialFeatures = specialFeatures;
|
||||
setRtc(0,0,0,0);//RTCTIME and DAYR are not cleared by reset, clear them manually in case the front end doesnt set the RTC
|
||||
setRtc(0,0,0,0);//RTCTIME and DAYR are not cleared by reset, clear them manually in case the frontend doesnt set the RTC
|
||||
|
||||
emulatorInitialized = true;
|
||||
return EMU_ERROR_NONE;
|
||||
@@ -141,7 +141,7 @@ uint64_t emulatorGetStateSize(){
|
||||
|
||||
size += sizeof(uint32_t);//save state version
|
||||
size += sizeof(uint32_t);//palmSpecialFeatures
|
||||
size += sizeof(uint32_t) * (M68K_REG_IR + 1);//CPU registers
|
||||
size += m68328StateSize();//the current CPU state
|
||||
size += sizeof(uint8_t);//lowPowerStopActive
|
||||
if(palmSpecialFeatures & FEATURE_RAM_HUGE)
|
||||
size += SUPERMASSIVE_RAM_SIZE;//system RAM buffer
|
||||
@@ -187,12 +187,8 @@ bool emulatorSaveState(buffer_t buffer){
|
||||
offset += sizeof(uint32_t);
|
||||
|
||||
//CPU
|
||||
for(uint8_t cpuReg = 0; cpuReg <= M68K_REG_IR; cpuReg++){
|
||||
writeStateValueUint32(buffer.data + offset, m68k_get_reg(NULL, cpuReg));
|
||||
offset += sizeof(uint32_t);
|
||||
}
|
||||
writeStateValueBool(buffer.data + offset, m68328LowPowerStop);
|
||||
offset += sizeof(uint8_t);
|
||||
m68328SaveState(buffer.data + offset);
|
||||
offset += m68328StateSize();
|
||||
|
||||
//memory
|
||||
if(palmSpecialFeatures & FEATURE_RAM_HUGE){
|
||||
@@ -306,8 +302,6 @@ bool emulatorSaveState(buffer_t buffer){
|
||||
memcpy(buffer.data + offset, palmSdCard.data, palmSdCard.size);
|
||||
offset += palmSdCard.size;
|
||||
|
||||
//printf("Offset:%d, Size:%d\n", offset, emulatorGetStateSize());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -325,12 +319,8 @@ bool emulatorLoadState(buffer_t buffer){
|
||||
offset += sizeof(uint32_t);
|
||||
|
||||
//CPU
|
||||
for(uint8_t cpuReg = 0; cpuReg <= M68K_REG_IR; cpuReg++){
|
||||
m68k_set_reg(cpuReg, readStateValueUint32(buffer.data + offset));
|
||||
offset += sizeof(uint32_t);
|
||||
}
|
||||
m68328LowPowerStop = readStateValueBool(buffer.data + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
m68328LoadState(buffer.data + offset);
|
||||
offset += m68328StateSize();
|
||||
|
||||
//memory
|
||||
if(palmSpecialFeatures & FEATURE_RAM_HUGE){
|
||||
@@ -443,11 +433,8 @@ bool emulatorLoadState(buffer_t buffer){
|
||||
if(palmSdCard.data){
|
||||
free(palmSdCard.data);
|
||||
palmSdCard.data = NULL;
|
||||
//palmSdCard.size = 0;
|
||||
}
|
||||
palmSdCard.size = readStateValueUint64(buffer.data + offset);
|
||||
//printf("state SD size:0x%016lX\n", palmSdCard.size);
|
||||
//printf("New State PC:0x%08X\n", m68k_get_reg(NULL, M68K_REG_PPC));
|
||||
offset += sizeof(uint64_t);
|
||||
if(palmSdCard.size > 0){
|
||||
palmSdCard.data = malloc(palmSdCard.size);
|
||||
@@ -459,8 +446,6 @@ bool emulatorLoadState(buffer_t buffer){
|
||||
}
|
||||
offset += palmSdCard.size;
|
||||
|
||||
//printf("Offset:%d, Size:%d\n", offset, emulatorGetStateSize());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
67
src/m68328.c
67
src/m68328.c
@@ -127,8 +127,13 @@ void m68328Reset(){
|
||||
m68k_pulse_reset();
|
||||
}
|
||||
|
||||
uint64_t m68328GetStateSize(){
|
||||
return sizeof(uint32_t) * 51;
|
||||
uint64_t m68328StateSize(){
|
||||
uint64_t size = 0;
|
||||
|
||||
size += sizeof(uint32_t) * 51;//m68ki_cpu
|
||||
size += sizeof(uint8_t);//m68328LowPowerStop
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void m68328SaveState(uint8_t* data){
|
||||
@@ -198,8 +203,10 @@ void m68328SaveState(uint8_t* data){
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.run_mode);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueBool(data + offset, m68328LowPowerStop);
|
||||
offset += sizeof(uint8_t);
|
||||
|
||||
printf("Offset:%d, Size:%d\n", offset, m68328GetStateSize());
|
||||
printf("Offset:%d, Size:%d\n", offset, m68328StateSize());
|
||||
}
|
||||
|
||||
void m68328LoadState(uint8_t* data){
|
||||
@@ -213,64 +220,66 @@ void m68328LoadState(uint8_t* data){
|
||||
}
|
||||
m68ki_cpu.ppc = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.pc);
|
||||
m68ki_cpu.pc = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
for(uint8_t index = 0; index < 7; index++){
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.sp[index]);
|
||||
m68ki_cpu.sp[index] = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
}
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.vbr);
|
||||
m68ki_cpu.vbr = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.sfc);
|
||||
m68ki_cpu.sfc = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.dfc);
|
||||
m68ki_cpu.dfc = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.cacr);
|
||||
m68ki_cpu.cacr = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.caar);
|
||||
m68ki_cpu.caar = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.ir);
|
||||
m68ki_cpu.ir = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.t1_flag);
|
||||
m68ki_cpu.t1_flag = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.t0_flag);
|
||||
m68ki_cpu.t0_flag = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.s_flag);
|
||||
m68ki_cpu.s_flag = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.m_flag);
|
||||
m68ki_cpu.m_flag = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.x_flag);
|
||||
m68ki_cpu.x_flag = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.n_flag);
|
||||
m68ki_cpu.n_flag = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.not_z_flag);
|
||||
m68ki_cpu.not_z_flag = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.v_flag);
|
||||
m68ki_cpu.v_flag = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.c_flag);
|
||||
m68ki_cpu.c_flag = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.int_mask);
|
||||
m68ki_cpu.int_mask = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.int_level);
|
||||
m68ki_cpu.int_level = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.int_cycles);
|
||||
m68ki_cpu.int_cycles = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.stopped);
|
||||
m68ki_cpu.stopped = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.pref_addr);
|
||||
m68ki_cpu.pref_addr = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.pref_data);
|
||||
m68ki_cpu.pref_data = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.address_mask);
|
||||
m68ki_cpu.address_mask = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueUint32(data + offset, m68ki_cpu.sr_mask);
|
||||
m68ki_cpu.sr_mask = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
m68ki_cpu.instr_mode = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
m68ki_cpu.run_mode = readStateValueUint32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
m68328LowPowerStop = readStateValueBool(data + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
|
||||
printf("Offset:%d, Size:%d\n", offset, m68328GetStateSize());
|
||||
printf("Offset:%d, Size:%d\n", offset, m68328StateSize());
|
||||
}
|
||||
|
||||
void m68328BusError(uint32_t address, bool isWrite){
|
||||
|
||||
@@ -7,7 +7,7 @@ extern bool m68328LowPowerStop;
|
||||
|
||||
void m68328Init();
|
||||
void m68328Reset();
|
||||
uint64_t m68328GetStateSize();
|
||||
uint64_t m68328StateSize();
|
||||
void m68328SaveState(uint8_t* data);
|
||||
void m68328LoadState(uint8_t* data);
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ Channels 3 and 4(they need to be scaled differently)
|
||||
|
||||
|
||||
Fixed:
|
||||
there was what appeared to be memory corruption because a byte was incrementing and dementing for loading and saving the same state but it was just the precision cast from uint64_t > double > uint64_t made it increment by 1
|
||||
power button must be pushed twice to turn the CPU back on(when debugging it works the first time, then must be pushed twice to turn off instead of on)(this also occurs in the RetroArch build)(this was not a bug, I was just pushing the power button too fast, when counting to 6 inbetween presses it worked fine)
|
||||
STOP opcode may be causing issues with the power button(it may be setting a separate CPU disable option)(not a bug)
|
||||
add 320*320 frame buffer silkscreen, 2xBRZ should be able to make 320*320 version of the 160*160 silkscreen(not hooked up but one has been created)
|
||||
|
||||
Reference in New Issue
Block a user