The dragonball uses a 68000 not 68020, more boot chip fixes

This commit is contained in:
meepingsnesroms
2018-04-18 16:44:44 -07:00
parent 6db96712f8
commit 3577016ba8
10 changed files with 90 additions and 33 deletions

View File

@@ -40,13 +40,13 @@ SOURCES += \
src/m68k/m68kopdm.c \
src/m68k/m68kopnz.c \
src/m68k/m68kops.c \
src/cpu32Opcodes.c \
src/emulator.c \
src/hardwareRegisters.c \
src/memoryAccess.c \
src/sdcard.c \
src/sed1376.c \
src/silkscreen.c
src/silkscreen.c \
src/68328Functions.c
HEADERS += \
mainwindow.h \
@@ -61,7 +61,6 @@ HEADERS += \
src/m68k/m68kconf.h \
src/m68k/m68kcpu.h \
src/m68k/m68kops.h \
src/cpu32Opcodes.h \
src/emuFeatureRegistersSpec.h \
src/emulator.h \
src/hardwareRegisterNames.h \
@@ -70,7 +69,8 @@ HEADERS += \
src/portability.h \
src/sdcard.h \
src/sed1376.h \
src/silkscreen.h
src/silkscreen.h \
src/68328Functions.h
FORMS += \
mainwindow.ui

View File

@@ -17,7 +17,9 @@ bool lowPowerStopActive;
static inline void patchOpcode(uint16_t opcode, void (*handler)(void), unsigned char cycles){
m68ki_instruction_jump_table[opcode] = handler;
m68ki_cycles[2][opcode] = cycles;//set how many cycles for 68020
m68ki_cycles[0][opcode] = cycles;
m68ki_cycles[1][opcode] = cycles;
m68ki_cycles[2][opcode] = cycles;
}
@@ -32,28 +34,28 @@ void cpu32OpLpstop(void){
//program lacks authority
m68ki_exception_privilege_violation();
}
debugLog("LowPowerStop set, CPU is off, PC 0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
debugLog("LowPowerStop set, CPU is off, PC:0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
}
void cpu32OpTbls(void){
debugLog("TBLS opcode not implemented, PC 0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
debugLog("TBLS opcode not implemented, PC:0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
}
void cpu32OpTblsn(void){
debugLog("TBLSN opcode not implemented, PC 0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
debugLog("TBLSN opcode not implemented, PC:0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
}
void cpu32OpTblu(void){
debugLog("TBLU opcode not implemented, PC 0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
debugLog("TBLU opcode not implemented, PC:0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
}
void cpu32OpTblun(void){
debugLog("TBLUN opcode not implemented, PC 0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
debugLog("TBLUN opcode not implemented, PC:0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
}
void m68k_op_bgnd(void){
debugLog("Opcode BGND not implemented, PC 0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
debugLog("Opcode BGND not implemented, PC:0x%08X!\n", m68k_get_reg(NULL, M68K_REG_PC));
}
void m68k_op_cpu32_dispatch(void){
@@ -89,9 +91,13 @@ void m68k_op_cpu32_dispatch(void){
}
void patchMusashiOpcodeHandlerCpu32(){
void patchTo68328(){
CPU_ADDRESS_MASK = 0xFFFFFFFF;
patchOpcode(OPCODE_BGND, m68k_op_bgnd, 16/*dont know how many cycles, average opcode*/);
for(uint32_t currentOpcode = OPCODE_CPU32_START; currentOpcode <= OPCODE_CPU32_END; currentOpcode++)
patchOpcode(currentOpcode, m68k_op_cpu32_dispatch, 91/*dont know how many cycles, most expensive opcode*/);
//68328 may actually use some 68020 opcodes, those will be patched in if and when Palm OS attempts to call one
}

View File

@@ -4,4 +4,4 @@
extern bool lowPowerStopActive;
void patchMusashiOpcodeHandlerCpu32();
void patchTo68328();

View File

@@ -4,7 +4,7 @@
#include <boolean.h>
#include "m68k/m68k.h"
#include "cpu32Opcodes.h"
#include "68328Functions.h"
#include "emulator.h"
#include "hardwareRegisters.h"
#include "memoryAccess.h"
@@ -54,20 +54,42 @@ static inline bool allSdCardCallbacksPresent(){
//debug
#ifdef EMU_OPCODE_LEVEL_DEBUG
#define LOGGED_OPCODES 10
#define LOGGED_OPCODES 100
static bool invalidBehaviorAbort;
static char disassemblyBuffer[LOGGED_OPCODES][100];//store the opcode and program counter for the last 10 opcodes
static char* takeStackDump(uint32_t bytes){
char* textBytes = malloc(bytes * 2);
uint32_t textBytesOffset = 0;
uint32_t stackAddress = m68k_get_reg(NULL, M68K_REG_SP);
textBytes[0] = '\0';
for(uint32_t count = 0; count < bytes; count++){
sprintf(textBytes + textBytesOffset, "%02X", m68k_read_memory_8(stackAddress + count));
textBytesOffset = strlen(textBytes);
}
return textBytes;
}
static void invalidBehaviorCheck(){
char opcodeName[100];
uint32_t lastProgramCounter = m68k_get_reg(NULL, M68K_REG_PPC);
uint32_t programCounter = m68k_get_reg(NULL, M68K_REG_PC);
uint16_t instruction = m68k_get_reg(NULL, M68K_REG_IR);
bool invalidInstruction = !m68k_is_valid_instruction(instruction, M68K_CPU_TYPE_68020);
bool invalidInstruction = !m68k_is_valid_instruction(instruction, M68K_CPU_TYPE_68000);
bool invalidBank = (bankType[START_BANK(programCounter)] == CHIP_NONE);
//get current opcode
m68k_disassemble(opcodeName, programCounter, M68K_CPU_TYPE_68020);
if(!invalidBank){
//must dissasemble as 68020 to prevent address masking, is also more descriptive for invalid opcodes
m68k_disassemble(opcodeName, programCounter, M68K_CPU_TYPE_68020);
}
else{
strcpy(opcodeName, "Invalid bank, cant read");
}
sprintf(opcodeName + strlen(opcodeName), " at PC:0x%08X", programCounter);
//shift opcode buffer
for(uint32_t i = 0; i < LOGGED_OPCODES - 1; i++)
@@ -85,7 +107,25 @@ static void invalidBehaviorCheck(){
for(uint32_t i = 0; i < LOGGED_OPCODES; i++)
debugLog("%s\n", disassemblyBuffer[i]);
//currently CPU32 opcodes will be listed as "unknown", I cant change that properly unless I directly edit musashi source, something I want to avoid doing
debugLog("Instruction:\"%s\", instruction value:0x%04X, bank type:%d, program counter:0x%08X\n", invalidInstruction ? "unknown" : opcodeName, instruction, START_BANK(programCounter), programCounter);
debugLog("Instruction:\"%s\", instruction value:0x%04X, bank type:%d\n", invalidInstruction ? "unknown" : opcodeName, instruction, bankType[START_BANK(programCounter)]);
}
//custom debug operations
switch(programCounter){
/*
//case 0x10000566:
case 0x100003F8:
{
//failing on executing first trap "HwrPreDebugInit"
char* data = takeStackDump(32);
debugLog("Stack dump:%s\n", data);
free(data);
}
break;
*/
default:
break;
}
}
#endif
@@ -94,7 +134,8 @@ static void invalidBehaviorCheck(){
void emulatorInit(uint8_t* palmRomDump, uint8_t* palmBootDump, uint32_t specialFeatures){
//CPU
m68k_init();
m68k_set_cpu_type(M68K_CPU_TYPE_68020);
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
patchTo68328();
m68k_set_reset_instr_callback(emulatorReset);
m68k_set_int_ack_callback(interruptAcknowledge);
#ifdef EMU_OPCODE_LEVEL_DEBUG
@@ -102,7 +143,6 @@ void emulatorInit(uint8_t* palmRomDump, uint8_t* palmBootDump, uint32_t specialF
strcpy(disassemblyBuffer[i], "Not an opcode.\n");
m68k_set_instr_hook_callback(invalidBehaviorCheck);
#endif
patchMusashiOpcodeHandlerCpu32();
resetHwRegisters();
lowPowerStopActive = false;
palmCrystalCycles = 2.0 * (14.0 * (71.0/*p*/ + 1.0) + 3.0/*q*/ + 1.0) / 2.0/*prescaler1*/;
@@ -166,8 +206,6 @@ void emulatorInit(uint8_t* palmRomDump, uint8_t* palmBootDump, uint32_t specialF
debugLog("Fixed 32.32:0x%08lX\n", fixed3232);
debugLog("Rebuilt double:%f\n", rebuilt);
*/
//debugLog("0x01000014 bank type:%d\n", bankType[0x0100]);
}
void emulatorExit(){
@@ -176,6 +214,7 @@ void emulatorExit(){
void emulatorReset(){
//reset doesnt clear RAM or sdcard, all programs are stored in RAM or on sdcard
debugLog("Reset triggered, PC:0x%08X\n", m68k_get_reg(NULL, M68K_REG_PC));
resetHwRegisters();
resetAddressSpace();//address space must be reset after hardware registers because it is dependant on them
sed1376Reset();
@@ -208,7 +247,7 @@ uint32_t emulatorGetStateSize(){
size += REG_SIZE;//hardware registers
size += TOTAL_MEMORY_BANKS;//bank handlers
size += sizeof(uint32_t) * 4 * CHIP_END;//chip select states
size += sizeof(uint8_t) * 4 * CHIP_END;//chip select states
size += sizeof(uint8_t) * 5 * CHIP_END;//chip select states
size += sizeof(uint64_t) * 3;//palmSdCard
size += sizeof(uint8_t) * 2;//palmSdCard
size += sizeof(uint64_t) * 4;//32.32 fixed point double, timerXCycleCounter and CPU cycle timers
@@ -254,6 +293,8 @@ void emulatorSaveState(uint8_t* data){
offset += sizeof(uint32_t);
writeStateValueUint32(data + offset, chips[chip].mask);
offset += sizeof(uint32_t);
writeStateValueBool(data + offset, chips[chip].inBootMode);
offset += sizeof(uint8_t);
writeStateValueBool(data + offset, chips[chip].readOnly);
offset += sizeof(uint8_t);
writeStateValueBool(data + offset, chips[chip].readOnlyForProtectedMemory);
@@ -338,6 +379,8 @@ void emulatorLoadState(uint8_t* data){
offset += sizeof(uint32_t);
chips[chip].mask = readStateValueUint32(data + offset);
offset += sizeof(uint32_t);
chips[chip].inBootMode = readStateValueBool(data + offset);
offset += sizeof(uint8_t);
chips[chip].readOnly = readStateValueBool(data + offset);
offset += sizeof(uint8_t);
chips[chip].readOnlyForProtectedMemory = readStateValueBool(data + offset);

View File

@@ -6,7 +6,7 @@
#include "hardwareRegisterNames.h"
#include "hardwareRegisters.h"
#include "memoryAccess.h"
#include "cpu32Opcodes.h"
#include "68328Functions.h"
#include "portability.h"
#include "m68k/m68k.h"
@@ -70,6 +70,10 @@ static inline void setCsa(uint16_t value){
chips[CHIP_A_ROM].readOnly = CAST_TO_BOOL(value & 0x8000);
chips[CHIP_A_ROM].size = 0x20000/*128kb*/ << ((value >> 1) & 0x0007);
//CSA is now just a normal chipselect
if(chips[CHIP_A_ROM].enable && chips[CHIP_A_ROM].inBootMode)
chips[CHIP_A_ROM].inBootMode = false;
registerArrayWrite16(CSA, value & 0x81FF);
}
@@ -818,6 +822,7 @@ void refreshButtonState(){
void setBusErrorTimeOut(){
uint8_t scr = registerArrayRead8(SCR);
debugLog("Bus error timeout, PC:0x%08X\n", m68k_get_reg(NULL, M68K_REG_PC));
if(scr & 0x10){
//trigger bus error interrupt
}
@@ -826,6 +831,7 @@ void setBusErrorTimeOut(){
void setWriteProtectViolation(){
uint8_t scr = registerArrayRead8(SCR);
debugLog("Write protect violation, PC:0x%08X\n", m68k_get_reg(NULL, M68K_REG_PC));
if(scr & 0x10){
//trigger bus error interrupt
}
@@ -834,6 +840,7 @@ void setWriteProtectViolation(){
void setPrivilegeViolation(){
uint8_t scr = registerArrayRead8(SCR);
debugLog("Privilege violation, PC:0x%08X\n", m68k_get_reg(NULL, M68K_REG_PC));
if(scr & 0x10){
//trigger bus error interrupt
}
@@ -920,7 +927,7 @@ unsigned int getHwRegister16(unsigned int address){
}
address &= 0x00000FFF;
printUnknownHwAccess(address, 0, 16, false);
//printUnknownHwAccess(address, 0, 16, false);
switch(address){
//32 bit registers accessed as 16 bit
@@ -940,7 +947,7 @@ unsigned int getHwRegister16(unsigned int address){
return registerArrayRead16(address);
default:
//printUnknownHwAccess(address, 0, 16, false);
printUnknownHwAccess(address, 0, 16, false);
return 0x0000;
}
@@ -1305,15 +1312,14 @@ void resetHwRegisters(){
chips[chip].size = 0x00000000;
chips[chip].mask = 0x00000000;
chips[chip].inBootMode = false;
chips[chip].readOnly = false;
chips[chip].readOnlyForProtectedMemory = false;
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].enable = true;
chips[CHIP_A_ROM].start = 0x00000000;
chips[CHIP_A_ROM].size = 0xFFFF0000;//0xFFFFFFFF will block hw registers and emu registers
chips[CHIP_A_ROM].inBootMode = true;
//masks for reading and writing
chips[CHIP_A_ROM].mask = 0x003FFFFF;

View File

@@ -48,6 +48,7 @@ typedef struct{
uint32_t mask;//the address lines the chip responds to, so 0x10000 on an chip with 16 address lines will return the value at 0x0000
//attributes
bool inBootMode;
bool readOnly;
bool readOnlyForProtectedMemory;
bool supervisorOnlyProtectedMemory;

View File

@@ -65,7 +65,7 @@
/* Turn ON if you want to use the following M68K variants */
#define M68K_EMULATE_010 OPT_OFF
#define M68K_EMULATE_EC020 OPT_OFF
#define M68K_EMULATE_020 OPT_ON
#define M68K_EMULATE_020 OPT_OFF
/* If ON, the CPU will call m68k_read_immediate_xx() for immediate addressing

View File

@@ -4,7 +4,7 @@ EMU_SOURCES_C := $(EMU_PATH)/emulator.c \
$(EMU_PATH)/sed1376.c \
$(EMU_PATH)/sdcard.c \
$(EMU_PATH)/silkscreen.c \
$(EMU_PATH)/cpu32Opcodes.c \
$(EMU_PATH)/68328Functions.c \
$(EMU_PATH)/m68k/m68kops.c \
$(EMU_PATH)/m68k/m68kopnz.c \
$(EMU_PATH)/m68k/m68kopdm.c \

View File

@@ -335,10 +335,10 @@ static uint8_t getProperBankType(uint32_t bank){
//normal banks
if(BANK_IN_RANGE(bank, REG_START_ADDRESS, REG_SIZE)){
//registers have first priority, they cover 0xFFFFF000 even if a chipselect overlaps this area
//registers have first priority, they cover 0xFFFFF000 even if a chipselect overlaps this area or CHIP_A_ROM is in boot mode
return CHIP_REGISTERS;
}
else if(chips[CHIP_A_ROM].enable && BANK_IN_RANGE(bank, chips[CHIP_A_ROM].start, chips[CHIP_A_ROM].size)){
else if(chips[CHIP_A_ROM].inBootMode || (chips[CHIP_A_ROM].enable && BANK_IN_RANGE(bank, chips[CHIP_A_ROM].start, chips[CHIP_A_ROM].size))){
return CHIP_A_ROM;
}
else if(chips[CHIP_B_SED].enable && BANK_IN_RANGE(bank, chips[CHIP_B_SED].start, chips[CHIP_B_SED].size) && sed1376ClockConnected()){

View File

@@ -17,6 +17,7 @@ interrupt control register (ICR), POL5 and edge trigger selects
storage RAM protect(likely already done from fixing chip select bits)
Fixed:
Palm OS usage of the "rte" instruction is incompatible with the 68020, switch to 68000 core
System Control Register, 0xXXFFF000 all upper banks are registers mode
Port D keyboard enable register
(HW verified)PDPOL inverts interrupts by inverting PDDATA bits, the data register is affected by PDPOL