mirror of
https://github.com/libretro/Mu.git
synced 2026-07-08 17:57:01 +00:00
Start tunring m515 and dragonball stuff into modules
Prepareing for tungsten c support.
This commit is contained in:
@@ -94,8 +94,6 @@ SOURCES += \
|
||||
../../src/ads7846.c \
|
||||
../../src/emulator.c \
|
||||
../../src/flx68000.c \
|
||||
../../src/hardwareRegisters.c \
|
||||
../../src/memoryAccess.c \
|
||||
../../src/pdiUsbD12.c \
|
||||
../../src/sdCard.c \
|
||||
../../src/sed1376.c \
|
||||
@@ -107,7 +105,9 @@ SOURCES += \
|
||||
../../src/m68k/m68kopnz.c \
|
||||
../../src/m68k/m68kops.c \
|
||||
../../src/expansionHardware.c \
|
||||
settingsmanager.cpp
|
||||
settingsmanager.cpp \
|
||||
../../src/m515Bus.c \
|
||||
../../src/dbvzRegisters.c
|
||||
|
||||
HEADERS += \
|
||||
debugviewer.h \
|
||||
@@ -128,10 +128,6 @@ HEADERS += \
|
||||
../../src/ads7846.h \
|
||||
../../src/emulator.h \
|
||||
../../src/flx68000.h \
|
||||
../../src/hardwareRegisters.h \
|
||||
../../src/hardwareRegistersAccessors.c.h \
|
||||
../../src/hardwareRegistersTiming.c.h \
|
||||
../../src/memoryAccess.h \
|
||||
../../src/pdiUsbD12.h \
|
||||
../../src/portability.h \
|
||||
../../src/sdCard.h \
|
||||
@@ -145,7 +141,11 @@ HEADERS += \
|
||||
../../src/expansionHardware.h \
|
||||
../../src/sdCardAccessors.c.h \
|
||||
../../src/sdCardCrcTables.c.h \
|
||||
settingsmanager.h
|
||||
settingsmanager.h \
|
||||
../../src/m515Bus.h \
|
||||
../../src/dbvzRegisterAccessors.c.h \
|
||||
../../src/dbvzTiming.c.h \
|
||||
../../src/dbvzRegisters.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui \
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "emulator.h"
|
||||
#include "portability.h"
|
||||
#include "hardwareRegisters.h"
|
||||
#include "dbvzRegisters.h"
|
||||
|
||||
|
||||
bool ads7846PenIrqEnabled;
|
||||
@@ -33,7 +33,7 @@ void ads7846Reset(void){
|
||||
ads7846OutputValue = 0x0000;
|
||||
ads7846ChipSelect = true;
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
refreshTouchState();
|
||||
m515RefreshTouchState();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ void ads7846SetChipSelect(bool value){
|
||||
ads7846PenIrqEnabled = true;
|
||||
ads7846OutputValue = 0x0000;
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
refreshTouchState();
|
||||
m515RefreshTouchState();
|
||||
#endif
|
||||
}
|
||||
ads7846ChipSelect = value;
|
||||
@@ -273,7 +273,7 @@ bool ads7846ExchangeBit(bool bitIn){
|
||||
|
||||
ads7846PenIrqEnabled = !(powerSave & 0x01);
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
refreshTouchState();
|
||||
m515RefreshTouchState();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ int32_t pwm1FifoRunSample(int32_t now, int32_t clockOffset){
|
||||
if(pwm1FifoEntrys() < 2){
|
||||
//trigger interrupt if enabled
|
||||
if(pwmc1 & 0x0040)
|
||||
setIprIsrBit(INT_PWM1);
|
||||
setIprIsrBit(DBVZ_INT_PWM1);
|
||||
//checkInterrupts() is run when the clock that called this function is finished
|
||||
|
||||
registerArrayWrite16(PWMC1, pwmc1 | 0x0080);//set IRQ bit
|
||||
@@ -147,18 +147,18 @@ static void pwm1FifoFlush(void){
|
||||
|
||||
//register setters
|
||||
static void setCsa(uint16_t value){
|
||||
chips[CHIP_A0_ROM].enable = value & 0x0001;
|
||||
chips[CHIP_A0_ROM].readOnly = !!(value & 0x8000);
|
||||
chips[CHIP_A0_ROM].lineSize = 0x20000/*128kb*/ << (value >> 1 & 0x0007);
|
||||
chips[DBVZ_CHIP_A0_ROM].enable = value & 0x0001;
|
||||
chips[DBVZ_CHIP_A0_ROM].readOnly = !!(value & 0x8000);
|
||||
chips[DBVZ_CHIP_A0_ROM].lineSize = 0x20000/*128kb*/ << (value >> 1 & 0x0007);
|
||||
|
||||
//CSA is now just a normal chip select
|
||||
if(chips[CHIP_A0_ROM].enable && chips[CHIP_A0_ROM].inBootMode)
|
||||
chips[CHIP_A0_ROM].inBootMode = false;
|
||||
if(chips[DBVZ_CHIP_A0_ROM].enable && chips[DBVZ_CHIP_A0_ROM].inBootMode)
|
||||
chips[DBVZ_CHIP_A0_ROM].inBootMode = false;
|
||||
|
||||
chips[CHIP_A1_USB].enable = chips[CHIP_A0_ROM].enable;
|
||||
chips[CHIP_A1_USB].readOnly = chips[CHIP_A0_ROM].readOnly;
|
||||
chips[CHIP_A1_USB].start = chips[CHIP_A0_ROM].start + chips[CHIP_A0_ROM].lineSize;
|
||||
chips[CHIP_A1_USB].lineSize = chips[CHIP_A0_ROM].lineSize;
|
||||
chips[DBVZ_CHIP_A1_USB].enable = chips[DBVZ_CHIP_A0_ROM].enable;
|
||||
chips[DBVZ_CHIP_A1_USB].readOnly = chips[DBVZ_CHIP_A0_ROM].readOnly;
|
||||
chips[DBVZ_CHIP_A1_USB].start = chips[DBVZ_CHIP_A0_ROM].start + chips[DBVZ_CHIP_A0_ROM].lineSize;
|
||||
chips[DBVZ_CHIP_A1_USB].lineSize = chips[DBVZ_CHIP_A0_ROM].lineSize;
|
||||
|
||||
registerArrayWrite16(CSA, value & 0x81FF);
|
||||
}
|
||||
@@ -166,25 +166,25 @@ static void setCsa(uint16_t value){
|
||||
static void setCsb(uint16_t value){
|
||||
uint16_t csControl1 = registerArrayRead16(CSCTRL1);
|
||||
|
||||
chips[CHIP_B0_SED].enable = value & 0x0001;
|
||||
chips[CHIP_B0_SED].readOnly = !!(value & 0x8000);
|
||||
chips[CHIP_B0_SED].lineSize = 0x20000/*128kb*/ << (value >> 1 & 0x0007);
|
||||
chips[DBVZ_CHIP_B0_SED].enable = value & 0x0001;
|
||||
chips[DBVZ_CHIP_B0_SED].readOnly = !!(value & 0x8000);
|
||||
chips[DBVZ_CHIP_B0_SED].lineSize = 0x20000/*128kb*/ << (value >> 1 & 0x0007);
|
||||
|
||||
//attributes
|
||||
chips[CHIP_B0_SED].supervisorOnlyProtectedMemory = !!(value & 0x4000);
|
||||
chips[CHIP_B0_SED].readOnlyForProtectedMemory = !!(value & 0x2000);
|
||||
chips[DBVZ_CHIP_B0_SED].supervisorOnlyProtectedMemory = !!(value & 0x4000);
|
||||
chips[DBVZ_CHIP_B0_SED].readOnlyForProtectedMemory = !!(value & 0x2000);
|
||||
if(csControl1 & 0x4000 && csControl1 & 0x0001)
|
||||
chips[CHIP_B0_SED].unprotectedSize = chips[CHIP_B0_SED].lineSize / (1 << 7 - ((value >> 11 & 0x0003) | 0x0004));
|
||||
chips[DBVZ_CHIP_B0_SED].unprotectedSize = chips[DBVZ_CHIP_B0_SED].lineSize / (1 << 7 - ((value >> 11 & 0x0003) | 0x0004));
|
||||
else
|
||||
chips[CHIP_B0_SED].unprotectedSize = chips[CHIP_B0_SED].lineSize / (1 << 7 - (value >> 11 & 0x0003));
|
||||
chips[DBVZ_CHIP_B0_SED].unprotectedSize = chips[DBVZ_CHIP_B0_SED].lineSize / (1 << 7 - (value >> 11 & 0x0003));
|
||||
|
||||
chips[CHIP_B1_NIL].enable = chips[CHIP_B0_SED].enable;
|
||||
chips[CHIP_B1_NIL].readOnly = chips[CHIP_B0_SED].readOnly;
|
||||
chips[CHIP_B1_NIL].start = chips[CHIP_B0_SED].start + chips[CHIP_B0_SED].lineSize;
|
||||
chips[CHIP_B1_NIL].lineSize = chips[CHIP_B0_SED].lineSize;
|
||||
chips[CHIP_B1_NIL].supervisorOnlyProtectedMemory = chips[CHIP_B0_SED].supervisorOnlyProtectedMemory;
|
||||
chips[CHIP_B1_NIL].readOnlyForProtectedMemory = chips[CHIP_B0_SED].readOnlyForProtectedMemory;
|
||||
chips[CHIP_B1_NIL].unprotectedSize = chips[CHIP_B0_SED].unprotectedSize;
|
||||
chips[DBVZ_CHIP_B1_NIL].enable = chips[DBVZ_CHIP_B0_SED].enable;
|
||||
chips[DBVZ_CHIP_B1_NIL].readOnly = chips[DBVZ_CHIP_B0_SED].readOnly;
|
||||
chips[DBVZ_CHIP_B1_NIL].start = chips[DBVZ_CHIP_B0_SED].start + chips[DBVZ_CHIP_B0_SED].lineSize;
|
||||
chips[DBVZ_CHIP_B1_NIL].lineSize = chips[DBVZ_CHIP_B0_SED].lineSize;
|
||||
chips[DBVZ_CHIP_B1_NIL].supervisorOnlyProtectedMemory = chips[DBVZ_CHIP_B0_SED].supervisorOnlyProtectedMemory;
|
||||
chips[DBVZ_CHIP_B1_NIL].readOnlyForProtectedMemory = chips[DBVZ_CHIP_B0_SED].readOnlyForProtectedMemory;
|
||||
chips[DBVZ_CHIP_B1_NIL].unprotectedSize = chips[DBVZ_CHIP_B0_SED].unprotectedSize;
|
||||
|
||||
registerArrayWrite16(CSB, value & 0xF9FF);
|
||||
}
|
||||
@@ -192,22 +192,22 @@ static void setCsb(uint16_t value){
|
||||
static void setCsd(uint16_t value){
|
||||
uint16_t csControl1 = registerArrayRead16(CSCTRL1);
|
||||
|
||||
chips[CHIP_DX_RAM].enable = value & 0x0001;
|
||||
chips[CHIP_DX_RAM].readOnly = !!(value & 0x8000);
|
||||
chips[DBVZ_CHIP_DX_RAM].enable = value & 0x0001;
|
||||
chips[DBVZ_CHIP_DX_RAM].readOnly = !!(value & 0x8000);
|
||||
if(csControl1 & 0x0040 && value & 0x0200)
|
||||
chips[CHIP_DX_RAM].lineSize = 0x800000/*8mb*/ << (value >> 1 & 0x0001);
|
||||
chips[DBVZ_CHIP_DX_RAM].lineSize = 0x800000/*8mb*/ << (value >> 1 & 0x0001);
|
||||
else
|
||||
chips[CHIP_DX_RAM].lineSize = 0x8000/*32kb*/ << (value >> 1 & 0x0007);
|
||||
chips[DBVZ_CHIP_DX_RAM].lineSize = 0x8000/*32kb*/ << (value >> 1 & 0x0007);
|
||||
|
||||
//attributes
|
||||
chips[CHIP_DX_RAM].supervisorOnlyProtectedMemory = !!(value & 0x4000);
|
||||
chips[CHIP_DX_RAM].readOnlyForProtectedMemory = !!(value & 0x2000);
|
||||
chips[DBVZ_CHIP_DX_RAM].supervisorOnlyProtectedMemory = !!(value & 0x4000);
|
||||
chips[DBVZ_CHIP_DX_RAM].readOnlyForProtectedMemory = !!(value & 0x2000);
|
||||
if(csControl1 & 0x4000 && csControl1 & 0x0010)
|
||||
chips[CHIP_DX_RAM].unprotectedSize = chips[CHIP_DX_RAM].lineSize / (1 << 7 - ((value >> 11 & 0x0003) | 0x0004));
|
||||
chips[DBVZ_CHIP_DX_RAM].unprotectedSize = chips[DBVZ_CHIP_DX_RAM].lineSize / (1 << 7 - ((value >> 11 & 0x0003) | 0x0004));
|
||||
else
|
||||
chips[CHIP_DX_RAM].unprotectedSize = chips[CHIP_DX_RAM].lineSize / (1 << 7 - (value >> 11 & 0x0003));
|
||||
chips[DBVZ_CHIP_DX_RAM].unprotectedSize = chips[DBVZ_CHIP_DX_RAM].lineSize / (1 << 7 - (value >> 11 & 0x0003));
|
||||
|
||||
//debugLog("RAM unprotected size:0x%08X, bits:0x%02X\n", chips[CHIP_DX_RAM].unprotectedSize, ((value >> 11 & 0x0003) | (csControl1 & 0x4000 && csControl1 & 0x0010) * 0x0004));
|
||||
//debugLog("RAM unprotected size:0x%08X, bits:0x%02X\n", chips[DBVZ_CHIP_DX_RAM].unprotectedSize, ((value >> 11 & 0x0003) | (csControl1 & 0x4000 && csControl1 & 0x0010) * 0x0004));
|
||||
|
||||
registerArrayWrite16(CSD, value);
|
||||
}
|
||||
@@ -217,11 +217,11 @@ static void setCsgba(uint16_t value){
|
||||
|
||||
//add extra address bits if enabled
|
||||
if(csugba & 0x8000)
|
||||
chips[CHIP_A0_ROM].start = (csugba >> 12 & 0x0007) << 29 | value >> 1 << 14;
|
||||
chips[DBVZ_CHIP_A0_ROM].start = (csugba >> 12 & 0x0007) << 29 | value >> 1 << 14;
|
||||
else
|
||||
chips[CHIP_A0_ROM].start = value >> 1 << 14;
|
||||
chips[DBVZ_CHIP_A0_ROM].start = value >> 1 << 14;
|
||||
|
||||
chips[CHIP_A1_USB].start = chips[CHIP_A0_ROM].start + chips[CHIP_A0_ROM].lineSize;
|
||||
chips[DBVZ_CHIP_A1_USB].start = chips[DBVZ_CHIP_A0_ROM].start + chips[DBVZ_CHIP_A0_ROM].lineSize;
|
||||
|
||||
registerArrayWrite16(CSGBA, value & 0xFFFE);
|
||||
}
|
||||
@@ -231,11 +231,11 @@ static void setCsgbb(uint16_t value){
|
||||
|
||||
//add extra address bits if enabled
|
||||
if(csugba & 0x8000)
|
||||
chips[CHIP_B0_SED].start = (csugba >> 8 & 0x0007) << 29 | value >> 1 << 14;
|
||||
chips[DBVZ_CHIP_B0_SED].start = (csugba >> 8 & 0x0007) << 29 | value >> 1 << 14;
|
||||
else
|
||||
chips[CHIP_B0_SED].start = value >> 1 << 14;
|
||||
chips[DBVZ_CHIP_B0_SED].start = value >> 1 << 14;
|
||||
|
||||
chips[CHIP_B1_NIL].start = chips[CHIP_B0_SED].start + chips[CHIP_B0_SED].lineSize;
|
||||
chips[DBVZ_CHIP_B1_NIL].start = chips[DBVZ_CHIP_B0_SED].start + chips[DBVZ_CHIP_B0_SED].lineSize;
|
||||
|
||||
registerArrayWrite16(CSGBB, value & 0xFFFE);
|
||||
}
|
||||
@@ -245,9 +245,9 @@ static void setCsgbd(uint16_t value){
|
||||
|
||||
//add extra address bits if enabled
|
||||
if(csugba & 0x8000)
|
||||
chips[CHIP_DX_RAM].start = (csugba & 0x0007) << 29 | value >> 1 << 14;
|
||||
chips[DBVZ_CHIP_DX_RAM].start = (csugba & 0x0007) << 29 | value >> 1 << 14;
|
||||
else
|
||||
chips[CHIP_DX_RAM].start = value >> 1 << 14;
|
||||
chips[DBVZ_CHIP_DX_RAM].start = value >> 1 << 14;
|
||||
|
||||
registerArrayWrite16(CSGBD, value & 0xFFFE);
|
||||
}
|
||||
@@ -258,19 +258,19 @@ static void updateCsdAddressLines(void){
|
||||
|
||||
if(registerArrayRead16(CSD) & 0x0200 && sdctrl & 0x8000 && dramc & 0x8000 && !(dramc & 0x0400)){
|
||||
//this register can remap address lines, that behavior is way too CPU intensive and complicated so only the "memory testing" and "correct" behavior is being emulated
|
||||
chips[CHIP_DX_RAM].mask = 0x003FFFFF;
|
||||
chips[DBVZ_CHIP_DX_RAM].mask = 0x003FFFFF;
|
||||
|
||||
//address line 23 is enabled
|
||||
if((sdctrl & 0x000C) == 0x0008)
|
||||
chips[CHIP_DX_RAM].mask |= 0x00800000;
|
||||
chips[DBVZ_CHIP_DX_RAM].mask |= 0x00800000;
|
||||
|
||||
//address line 22 is enabled
|
||||
if((sdctrl & 0x0030) == 0x0010)
|
||||
chips[CHIP_DX_RAM].mask |= 0x00400000;
|
||||
chips[DBVZ_CHIP_DX_RAM].mask |= 0x00400000;
|
||||
}
|
||||
else{
|
||||
//RAM is not enabled properly
|
||||
chips[CHIP_DX_RAM].mask = 0x00000000;
|
||||
chips[DBVZ_CHIP_DX_RAM].mask = 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,14 +294,14 @@ static void setScr(uint8_t value){
|
||||
//clear violations on writing 1 to them
|
||||
newScr &= ~(value & 0xE0);
|
||||
|
||||
chips[CHIP_REGISTERS].supervisorOnlyProtectedMemory = value & 0x08;
|
||||
chips[DBVZ_CHIP_REGISTERS].supervisorOnlyProtectedMemory = value & 0x08;
|
||||
|
||||
registerArrayWrite8(SCR, newScr);//must be written before calling setRegisterFFFFAccessMode
|
||||
if((newScr & 0x04) != (oldScr & 0x04)){
|
||||
if(newScr & 0x04)
|
||||
setRegisterXXFFAccessMode();
|
||||
dbvzSetRegisterXXFFAccessMode();
|
||||
else
|
||||
setRegisterFFFFAccessMode();
|
||||
dbvzSetRegisterFFFFAccessMode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,9 +354,9 @@ static void setSpiIntCs(uint16_t value){
|
||||
//if interrupt state changed update interrupts too, top 8 bits are just the enable bits for the bottom 8
|
||||
if(!!(newSpiIntCs >> 8 & newSpiIntCs) != !!(oldSpiIntCs >> 8 & oldSpiIntCs)){
|
||||
if(newSpiIntCs >> 8 & newSpiIntCs)
|
||||
setIprIsrBit(INT_SPI1);
|
||||
setIprIsrBit(DBVZ_INT_SPI1);
|
||||
else
|
||||
clearIprIsrBit(INT_SPI1);
|
||||
clearIprIsrBit(DBVZ_INT_SPI1);
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
@@ -425,9 +425,9 @@ static void setSpiCont2(uint16_t value){
|
||||
|
||||
//force or clear an interrupt
|
||||
if((value & 0x00C0) == 0x00C0)
|
||||
setIprIsrBit(INT_SPI2);
|
||||
setIprIsrBit(DBVZ_INT_SPI2);
|
||||
else
|
||||
clearIprIsrBit(INT_SPI2);
|
||||
clearIprIsrBit(DBVZ_INT_SPI2);
|
||||
|
||||
//do a transfer if enabled(this register write and last) and exchange set
|
||||
if(value & oldSpiCont2 & 0x0200 && value & 0x0100){
|
||||
@@ -465,7 +465,7 @@ static void setSpiCont2(uint16_t value){
|
||||
|
||||
//IRQEN set, send an interrupt after transfer
|
||||
if(value & 0x0040)
|
||||
setIprIsrBit(INT_SPI2);
|
||||
setIprIsrBit(DBVZ_INT_SPI2);
|
||||
}
|
||||
|
||||
//check for any interrupts from the transfer
|
||||
@@ -482,7 +482,7 @@ static void setTstat1(uint16_t value){
|
||||
|
||||
if(!(newTstat1 & 0x0001) && (oldTstat1 & 0x0001)){
|
||||
//debugLog("Timer 1 interrupt cleared.\n");
|
||||
clearIprIsrBit(INT_TMR1);
|
||||
clearIprIsrBit(DBVZ_INT_TMR1);
|
||||
checkInterrupts();
|
||||
}
|
||||
timerStatusReadAcknowledge[0] &= newTstat1;//clear acknowledged reads cleared bits
|
||||
@@ -497,7 +497,7 @@ static void setTstat2(uint16_t value){
|
||||
|
||||
if(!(newTstat2 & 0x0001) && (oldTstat2 & 0x0001)){
|
||||
//debugLog("Timer 2 interrupt cleared.\n");
|
||||
clearIprIsrBit(INT_TMR2);
|
||||
clearIprIsrBit(DBVZ_INT_TMR2);
|
||||
checkInterrupts();
|
||||
}
|
||||
timerStatusReadAcknowledge[1] &= newTstat2;//clear acknowledged reads for cleared bits
|
||||
@@ -518,14 +518,14 @@ static void setPwmc1(uint16_t value){
|
||||
|
||||
//clear interrupt by write(reading can also clear the interrupt)
|
||||
if(oldPwmc1 & 0x0080 && !(value & 0x0080)){
|
||||
clearIprIsrBit(INT_PWM1);
|
||||
clearIprIsrBit(DBVZ_INT_PWM1);
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
//interrupt enabled and interrupt set
|
||||
if((value & 0x00C0) == 0x00C0){
|
||||
//this register also allows forcing an interrupt by writing a 1 to its IRQ bit when IRQEN is enabled
|
||||
setIprIsrBit(INT_PWM1);
|
||||
setIprIsrBit(DBVZ_INT_PWM1);
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
@@ -549,19 +549,19 @@ static void setIsr(uint32_t value, bool useTopWord, bool useBottomWord){
|
||||
|
||||
//IRQ1 is not edge triggered
|
||||
if(!(interruptControlRegister & 0x0800))
|
||||
value &= ~INT_IRQ1;
|
||||
value &= ~DBVZ_INT_IRQ1;
|
||||
|
||||
//IRQ2 is not edge triggered
|
||||
if(!(interruptControlRegister & 0x0400))
|
||||
value &= ~INT_IRQ2;
|
||||
value &= ~DBVZ_INT_IRQ2;
|
||||
|
||||
//IRQ3 is not edge triggered
|
||||
if(!(interruptControlRegister & 0x0200))
|
||||
value &= ~INT_IRQ3;
|
||||
value &= ~DBVZ_INT_IRQ3;
|
||||
|
||||
//IRQ6 is not edge triggered
|
||||
if(!(interruptControlRegister & 0x0100))
|
||||
value &= ~INT_IRQ6;
|
||||
value &= ~DBVZ_INT_IRQ6;
|
||||
|
||||
registerArrayWrite16(IPR, registerArrayRead16(IPR) & ~(value >> 16));
|
||||
registerArrayWrite16(ISR, registerArrayRead16(ISR) & ~(value >> 16));
|
||||
@@ -718,7 +718,7 @@ static uint16_t getPwmc1(void){
|
||||
|
||||
//clear INT_PWM1 if active
|
||||
if(returnValue & 0x0080){
|
||||
clearIprIsrBit(INT_PWM1);
|
||||
clearIprIsrBit(DBVZ_INT_PWM1);
|
||||
checkInterrupts();
|
||||
registerArrayWrite16(PWMC1, returnValue & 0xFF5F);
|
||||
}
|
||||
@@ -747,14 +747,14 @@ static void updateSdCardChipSelectStatus(void){
|
||||
}
|
||||
|
||||
static void updateBacklightAmplifierStatus(void){
|
||||
palmMisc.backlightLevel = (palmMisc.backlightLevel > 0) ? (1 + backlightAmplifierState()) : 0;
|
||||
palmMisc.backlightLevel = (palmMisc.backlightLevel > 0) ? (1 + m515BacklightAmplifierState()) : 0;
|
||||
}
|
||||
|
||||
static void updateTouchState(void){
|
||||
if(!(registerArrayRead8(PFSEL) & registerArrayRead8(PFDIR) & 0x02)){
|
||||
if((ads7846PenIrqEnabled ? !palmInput.touchscreenTouched : true) == !!(registerArrayRead16(ICR) & 0x0080))
|
||||
setIprIsrBit(INT_IRQ5);
|
||||
setIprIsrBit(DBVZ_INT_IRQ5);
|
||||
else
|
||||
clearIprIsrBit(INT_IRQ5);
|
||||
clearIprIsrBit(DBVZ_INT_IRQ5);
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#include "emulator.h"
|
||||
#include "specs/dragonballVzRegisterSpec.h"
|
||||
#include "hardwareRegisters.h"
|
||||
#include "memoryAccess.h"
|
||||
#include "dbvzRegisters.h"
|
||||
#include "m515Bus.h"
|
||||
#include "portability.h"
|
||||
#include "flx68000.h"
|
||||
#include "ads7846.h"
|
||||
@@ -14,25 +14,25 @@
|
||||
#include "debug/sandbox.h"
|
||||
|
||||
|
||||
chip_t chips[CHIP_END];
|
||||
int8_t pllSleepWait;
|
||||
int8_t pllWakeWait;
|
||||
uint32_t clk32Counter;
|
||||
double pctlrCpuClockDivider;
|
||||
double timerCycleCounter[2];
|
||||
uint16_t timerStatusReadAcknowledge[2];
|
||||
uint8_t portDInterruptLastValue;//used for edge triggered interrupt timing
|
||||
uint16_t spi1RxFifo[9];
|
||||
uint16_t spi1TxFifo[9];
|
||||
uint8_t spi1RxReadPosition;
|
||||
uint8_t spi1RxWritePosition;
|
||||
bool spi1RxOverflowed;
|
||||
uint8_t spi1TxReadPosition;
|
||||
uint8_t spi1TxWritePosition;
|
||||
int32_t pwm1ClocksToNextSample;
|
||||
uint8_t pwm1Fifo[6];
|
||||
uint8_t pwm1ReadPosition;
|
||||
uint8_t pwm1WritePosition;
|
||||
dbvz_chip_t chips[DBVZ_CHIP_END];
|
||||
int8_t pllSleepWait;
|
||||
int8_t pllWakeWait;
|
||||
uint32_t clk32Counter;
|
||||
double pctlrCpuClockDivider;
|
||||
double timerCycleCounter[2];
|
||||
uint16_t timerStatusReadAcknowledge[2];
|
||||
uint8_t portDInterruptLastValue;//used for edge triggered interrupt timing
|
||||
uint16_t spi1RxFifo[9];
|
||||
uint16_t spi1TxFifo[9];
|
||||
uint8_t spi1RxReadPosition;
|
||||
uint8_t spi1RxWritePosition;
|
||||
bool spi1RxOverflowed;
|
||||
uint8_t spi1TxReadPosition;
|
||||
uint8_t spi1TxWritePosition;
|
||||
int32_t pwm1ClocksToNextSample;
|
||||
uint8_t pwm1Fifo[6];
|
||||
uint8_t pwm1ReadPosition;
|
||||
uint8_t pwm1WritePosition;
|
||||
|
||||
|
||||
static void checkInterrupts(void);
|
||||
@@ -43,18 +43,18 @@ static int32_t audioGetFramePercentIncrementFromClk32s(int32_t count);
|
||||
static int32_t audioGetFramePercentIncrementFromSysclks(double count);
|
||||
static int32_t audioGetFramePercentage(void);
|
||||
|
||||
#include "hardwareRegistersAccessors.c.h"
|
||||
#include "hardwareRegistersTiming.c.h"
|
||||
#include "dbvzRegisterAccessors.c.h"
|
||||
#include "dbvzTiming.c.h"
|
||||
|
||||
bool pllIsOn(void){
|
||||
bool dbvzIsPllOn(void){
|
||||
return !(palmSysclksPerClk32 < 1.0);
|
||||
}
|
||||
|
||||
bool backlightAmplifierState(void){
|
||||
bool m515BacklightAmplifierState(void){
|
||||
return !!(getPortKValue() & 0x02);
|
||||
}
|
||||
|
||||
bool registersAreXXFFMapped(void){
|
||||
bool dbvzAreRegistersXXFFMapped(void){
|
||||
return !!(registerArrayRead8(SCR) & 0x04);
|
||||
}
|
||||
|
||||
@@ -69,9 +69,9 @@ void ads7846OverridePenState(bool value){
|
||||
if(value != (ads7846PenIrqEnabled ? !palmInput.touchscreenTouched : true)){
|
||||
if(!(registerArrayRead8(PFSEL) & registerArrayRead8(PFDIR) & 0x02)){
|
||||
if(value == !!(registerArrayRead16(ICR) & 0x0080))
|
||||
setIprIsrBit(INT_IRQ5);
|
||||
setIprIsrBit(DBVZ_INT_IRQ5);
|
||||
else
|
||||
clearIprIsrBit(INT_IRQ5);
|
||||
clearIprIsrBit(DBVZ_INT_IRQ5);
|
||||
}
|
||||
checkInterrupts();
|
||||
|
||||
@@ -81,13 +81,13 @@ void ads7846OverridePenState(bool value){
|
||||
}
|
||||
}
|
||||
|
||||
void refreshTouchState(void){
|
||||
void m515RefreshTouchState(void){
|
||||
//called when ads7846PenIrqEnabled is changed
|
||||
updateTouchState();
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
void refreshInputState(void){
|
||||
void m515RefreshInputState(void){
|
||||
//update power button LED state if palmMisc.batteryCharging changed
|
||||
updatePowerButtonLedStatus();
|
||||
|
||||
@@ -115,7 +115,7 @@ int32_t interruptAcknowledge(int32_t intLevel){
|
||||
return vector;
|
||||
}
|
||||
|
||||
void setBusErrorTimeOut(uint32_t address, bool isWrite){
|
||||
void dbvzSetBusErrorTimeOut(uint32_t address, bool isWrite){
|
||||
uint8_t scr = registerArrayRead8(SCR);
|
||||
debugLog("Bus error timeout at:0x%08X, PC:0x%08X\n", address, flx68000GetPc());
|
||||
registerArrayWrite8(SCR, scr | 0x80);
|
||||
@@ -123,7 +123,7 @@ void setBusErrorTimeOut(uint32_t address, bool isWrite){
|
||||
flx68000BusError(address, isWrite);
|
||||
}
|
||||
|
||||
void setPrivilegeViolation(uint32_t address, bool isWrite){
|
||||
void dbvzSetPrivilegeViolation(uint32_t address, bool isWrite){
|
||||
uint8_t scr = registerArrayRead8(SCR);
|
||||
debugLog("Privilege violation at:0x%08X, PC:0x%08X\n", address, flx68000GetPc());
|
||||
registerArrayWrite8(SCR, scr | 0x20);
|
||||
@@ -131,7 +131,7 @@ void setPrivilegeViolation(uint32_t address, bool isWrite){
|
||||
flx68000BusError(address, isWrite);
|
||||
}
|
||||
|
||||
void setWriteProtectViolation(uint32_t address){
|
||||
void dbvzSetWriteProtectViolation(uint32_t address){
|
||||
uint8_t scr = registerArrayRead8(SCR);
|
||||
debugLog("Write protect violation at:0x%08X, PC:0x%08X\n", address, flx68000GetPc());
|
||||
registerArrayWrite8(SCR, scr | 0x40);
|
||||
@@ -143,7 +143,7 @@ static void pllWakeCpuIfOff(void){
|
||||
const int8_t pllWaitTable[4] = {32, 48, 64, 96};
|
||||
|
||||
//PLL is off and not already in the process of waking up
|
||||
if(!pllIsOn() && pllWakeWait == -1)
|
||||
if(!dbvzIsPllOn() && pllWakeWait == -1)
|
||||
pllWakeWait = pllWaitTable[registerArrayRead16(PLLCR) & 0x0003];
|
||||
}
|
||||
|
||||
@@ -157,38 +157,38 @@ static void checkInterrupts(void){
|
||||
uint8_t intLevel = 0;
|
||||
|
||||
//static interrupts
|
||||
if(activeInterrupts & INT_EMIQ)
|
||||
if(activeInterrupts & DBVZ_INT_EMIQ)
|
||||
intLevel = 7;//EMIQ - Emulator IRQ, has nothing to do with emulation, used for debugging on a dev board
|
||||
|
||||
if(intLevel < 6 && activeInterrupts & (INT_TMR1 | INT_PWM1 | INT_IRQ6))
|
||||
if(intLevel < 6 && activeInterrupts & (DBVZ_INT_TMR1 | DBVZ_INT_PWM1 | DBVZ_INT_IRQ6))
|
||||
intLevel = 6;
|
||||
|
||||
if(intLevel < 5 && activeInterrupts & INT_IRQ5)
|
||||
if(intLevel < 5 && activeInterrupts & DBVZ_INT_IRQ5)
|
||||
intLevel = 5;
|
||||
|
||||
if(intLevel < 4 && activeInterrupts & (INT_SPI2 | INT_UART1 | INT_WDT | INT_RTC | INT_KB | INT_RTI | INT_INT0 | INT_INT1 | INT_INT2 | INT_INT3))
|
||||
if(intLevel < 4 && activeInterrupts & (DBVZ_INT_SPI2 | DBVZ_INT_UART1 | DBVZ_INT_WDT | DBVZ_INT_RTC | DBVZ_INT_KB | DBVZ_INT_RTI | DBVZ_INT_INT0 | DBVZ_INT_INT1 | DBVZ_INT_INT2 | DBVZ_INT_INT3))
|
||||
intLevel = 4;
|
||||
|
||||
if(intLevel < 3 && activeInterrupts & INT_IRQ3)
|
||||
if(intLevel < 3 && activeInterrupts & DBVZ_INT_IRQ3)
|
||||
intLevel = 3;
|
||||
|
||||
if(intLevel < 2 && activeInterrupts & INT_IRQ2)
|
||||
if(intLevel < 2 && activeInterrupts & DBVZ_INT_IRQ2)
|
||||
intLevel = 2;
|
||||
|
||||
if(intLevel < 1 && activeInterrupts & INT_IRQ1)
|
||||
if(intLevel < 1 && activeInterrupts & DBVZ_INT_IRQ1)
|
||||
intLevel = 1;
|
||||
|
||||
//configureable interrupts
|
||||
if(intLevel < spi1IrqLevel && activeInterrupts & INT_SPI1)
|
||||
if(intLevel < spi1IrqLevel && activeInterrupts & DBVZ_INT_SPI1)
|
||||
intLevel = spi1IrqLevel;
|
||||
|
||||
if(intLevel < uart2IrqLevel && activeInterrupts & INT_UART2)
|
||||
if(intLevel < uart2IrqLevel && activeInterrupts & DBVZ_INT_UART2)
|
||||
intLevel = uart2IrqLevel;
|
||||
|
||||
if(intLevel < pwm2IrqLevel && activeInterrupts & INT_PWM2)
|
||||
if(intLevel < pwm2IrqLevel && activeInterrupts & DBVZ_INT_PWM2)
|
||||
intLevel = pwm2IrqLevel;
|
||||
|
||||
if(intLevel < timer2IrqLevel && activeInterrupts & INT_TMR2)
|
||||
if(intLevel < timer2IrqLevel && activeInterrupts & DBVZ_INT_TMR2)
|
||||
intLevel = timer2IrqLevel;
|
||||
|
||||
//even masked interrupts turn off PCTLR, 4.5.4 Power Control Register MC68VZ328UM.pdf
|
||||
@@ -209,55 +209,55 @@ static void checkPortDInterrupts(void){
|
||||
uint8_t portDInterruptEdgeTriggered = icrEdgeTriggered | registerArrayRead8(PDIRQEG);
|
||||
uint8_t portDInterruptEnabled = (~registerArrayRead8(PDSEL) & 0xF0) | registerArrayRead8(PDIRQEN);
|
||||
uint8_t portDIsInput = ~registerArrayRead8(PDDIR);
|
||||
uint8_t portDInterruptTriggered = portDInterruptValue & portDInterruptEnabled & portDIsInput & (~portDInterruptEdgeTriggered | ~portDInterruptLastValue & (pllIsOn() ? 0xFF : 0xF0));
|
||||
uint8_t portDInterruptTriggered = portDInterruptValue & portDInterruptEnabled & portDIsInput & (~portDInterruptEdgeTriggered | ~portDInterruptLastValue & (dbvzIsPllOn() ? 0xFF : 0xF0));
|
||||
|
||||
if(portDInterruptTriggered & 0x01)
|
||||
setIprIsrBit(INT_INT0);
|
||||
setIprIsrBit(DBVZ_INT_INT0);
|
||||
else if(!(portDInterruptEdgeTriggered & 0x01))
|
||||
clearIprIsrBit(INT_INT0);
|
||||
clearIprIsrBit(DBVZ_INT_INT0);
|
||||
|
||||
if(portDInterruptTriggered & 0x02)
|
||||
setIprIsrBit(INT_INT1);
|
||||
setIprIsrBit(DBVZ_INT_INT1);
|
||||
else if(!(portDInterruptEdgeTriggered & 0x02))
|
||||
clearIprIsrBit(INT_INT1);
|
||||
clearIprIsrBit(DBVZ_INT_INT1);
|
||||
|
||||
if(portDInterruptTriggered & 0x04)
|
||||
setIprIsrBit(INT_INT2);
|
||||
setIprIsrBit(DBVZ_INT_INT2);
|
||||
else if(!(portDInterruptEdgeTriggered & 0x04))
|
||||
clearIprIsrBit(INT_INT2);
|
||||
clearIprIsrBit(DBVZ_INT_INT2);
|
||||
|
||||
if(portDInterruptTriggered & 0x08)
|
||||
setIprIsrBit(INT_INT3);
|
||||
setIprIsrBit(DBVZ_INT_INT3);
|
||||
else if(!(portDInterruptEdgeTriggered & 0x08))
|
||||
clearIprIsrBit(INT_INT3);
|
||||
clearIprIsrBit(DBVZ_INT_INT3);
|
||||
|
||||
if(portDInterruptTriggered & 0x10)
|
||||
setIprIsrBit(INT_IRQ1);
|
||||
setIprIsrBit(DBVZ_INT_IRQ1);
|
||||
else if(!(portDInterruptEdgeTriggered & 0x10))
|
||||
clearIprIsrBit(INT_IRQ1);
|
||||
clearIprIsrBit(DBVZ_INT_IRQ1);
|
||||
|
||||
if(portDInterruptTriggered & 0x20)
|
||||
setIprIsrBit(INT_IRQ2);
|
||||
setIprIsrBit(DBVZ_INT_IRQ2);
|
||||
else if(!(portDInterruptEdgeTriggered & 0x20))
|
||||
clearIprIsrBit(INT_IRQ2);
|
||||
clearIprIsrBit(DBVZ_INT_IRQ2);
|
||||
|
||||
if(portDInterruptTriggered & 0x40)
|
||||
setIprIsrBit(INT_IRQ3);
|
||||
setIprIsrBit(DBVZ_INT_IRQ3);
|
||||
else if(!(portDInterruptEdgeTriggered & 0x40))
|
||||
clearIprIsrBit(INT_IRQ3);
|
||||
clearIprIsrBit(DBVZ_INT_IRQ3);
|
||||
|
||||
if(portDInterruptTriggered & 0x80)
|
||||
setIprIsrBit(INT_IRQ6);
|
||||
setIprIsrBit(DBVZ_INT_IRQ6);
|
||||
else if(!(portDInterruptEdgeTriggered & 0x80))
|
||||
clearIprIsrBit(INT_IRQ6);
|
||||
clearIprIsrBit(DBVZ_INT_IRQ6);
|
||||
|
||||
//active low/off level triggered interrupt(triggers on 0, not a pull down resistor)
|
||||
//The SELx, POLx, IQENx, and IQEGx bits have no effect on the functionality of KBENx, 10.4.5.8 Port D Keyboard Enable Register MC68VZ328UM.pdf
|
||||
//the above has finally been verified to be correct!
|
||||
if(registerArrayRead8(PDKBEN) & ~(getPortDValue() ^ registerArrayRead8(PDPOL)) & portDIsInput)
|
||||
setIprIsrBit(INT_KB);
|
||||
setIprIsrBit(DBVZ_INT_KB);
|
||||
else
|
||||
clearIprIsrBit(INT_KB);
|
||||
clearIprIsrBit(DBVZ_INT_KB);
|
||||
|
||||
//save to check against next time this function is called
|
||||
portDInterruptLastValue = portDInterruptTriggered;
|
||||
@@ -272,10 +272,10 @@ static void printHwRegAccess(uint32_t address, uint32_t value, uint32_t size, bo
|
||||
debugLog("CPU read %d bits from register 0x%03X, PC:0x%08X.\n", size, address, flx68000GetPc());
|
||||
}
|
||||
|
||||
uint8_t getHwRegister8(uint32_t address){
|
||||
uint8_t dbvzGetRegister8(uint32_t address){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
setBusErrorTimeOut(address, false);
|
||||
dbvzSetBusErrorTimeOut(address, false);
|
||||
return 0x00;
|
||||
}
|
||||
#endif
|
||||
@@ -382,10 +382,10 @@ uint8_t getHwRegister8(uint32_t address){
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t getHwRegister16(uint32_t address){
|
||||
uint16_t dbvzGetRegister16(uint32_t address){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
setBusErrorTimeOut(address, false);
|
||||
dbvzSetBusErrorTimeOut(address, false);
|
||||
return 0x0000;
|
||||
}
|
||||
#endif
|
||||
@@ -472,10 +472,10 @@ uint16_t getHwRegister16(uint32_t address){
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t getHwRegister32(uint32_t address){
|
||||
uint32_t dbvzGetRegister32(uint32_t address){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
setBusErrorTimeOut(address, false);
|
||||
dbvzSetBusErrorTimeOut(address, false);
|
||||
return 0x00000000;
|
||||
}
|
||||
#endif
|
||||
@@ -501,10 +501,10 @@ uint32_t getHwRegister32(uint32_t address){
|
||||
}
|
||||
}
|
||||
|
||||
void setHwRegister8(uint32_t address, uint8_t value){
|
||||
void dbvzSetRegister8(uint32_t address, uint8_t value){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
setBusErrorTimeOut(address, true);
|
||||
dbvzSetBusErrorTimeOut(address, true);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -570,7 +570,7 @@ void setHwRegister8(uint32_t address, uint8_t value){
|
||||
case PFSEL:
|
||||
//this register controls the clock output pin for the SED1376 and IRQ line for PENIRQ
|
||||
registerArrayWrite8(PFSEL, value);
|
||||
setSed1376Attached(sed1376ClockConnected());
|
||||
m515SetSed1376Attached(sed1376ClockConnected());
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
updateTouchState();
|
||||
checkInterrupts();
|
||||
@@ -667,10 +667,10 @@ void setHwRegister8(uint32_t address, uint8_t value){
|
||||
}
|
||||
}
|
||||
|
||||
void setHwRegister16(uint32_t address, uint16_t value){
|
||||
void dbvzSetRegister16(uint32_t address, uint16_t value){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
setBusErrorTimeOut(address, true);
|
||||
dbvzSetBusErrorTimeOut(address, true);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -725,15 +725,15 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
//1 must be written to clear INTF
|
||||
registerArrayWrite16(WATCHDOG, (value & 0x0003) | (registerArrayRead16(WATCHDOG) & (~value & 0x0080)));
|
||||
if(!(registerArrayRead16(WATCHDOG) & 0x0080))
|
||||
clearIprIsrBit(INT_WDT);
|
||||
clearIprIsrBit(DBVZ_INT_WDT);
|
||||
return;
|
||||
|
||||
case RTCISR:
|
||||
registerArrayWrite16(RTCISR, registerArrayRead16(RTCISR) & ~value);
|
||||
if(!(registerArrayRead16(RTCISR) & 0xFF00))
|
||||
clearIprIsrBit(INT_RTI);
|
||||
clearIprIsrBit(DBVZ_INT_RTI);
|
||||
if(!(registerArrayRead16(RTCISR) & 0x003F))
|
||||
clearIprIsrBit(INT_RTC);
|
||||
clearIprIsrBit(DBVZ_INT_RTC);
|
||||
checkInterrupts();
|
||||
return;
|
||||
|
||||
@@ -745,7 +745,7 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
//CLKEN is required for SED1376 operation
|
||||
registerArrayWrite16(PLLCR, value & 0x3FBB);
|
||||
palmSysclksPerClk32 = sysclksPerClk32();
|
||||
setSed1376Attached(sed1376ClockConnected());
|
||||
m515SetSed1376Attached(sed1376ClockConnected());
|
||||
|
||||
if(value & 0x0008)
|
||||
pllSleepWait = 30;//The PLL shuts down 30 clocks of CLK32 after the DISPLL bit is set in the PLLCR
|
||||
@@ -785,13 +785,13 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
|
||||
case CSA:{
|
||||
uint16_t oldCsa = registerArrayRead16(CSA);
|
||||
bool oldBootMode = chips[CHIP_A0_ROM].inBootMode;
|
||||
bool oldBootMode = chips[DBVZ_CHIP_A0_ROM].inBootMode;
|
||||
|
||||
setCsa(value);
|
||||
|
||||
//only reset address space if size changed, enabled/disabled or exiting boot mode
|
||||
if((value & 0x000F) != (oldCsa & 0x000F) || chips[CHIP_A0_ROM].inBootMode != oldBootMode)
|
||||
resetAddressSpace();
|
||||
if((value & 0x000F) != (oldCsa & 0x000F) || chips[DBVZ_CHIP_A0_ROM].inBootMode != oldBootMode)
|
||||
dbvzResetAddressSpace();
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -802,7 +802,7 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
|
||||
//only reset address space if size changed or enabled/disabled
|
||||
if((value & 0x000F) != (oldCsb & 0x000F))
|
||||
resetAddressSpace();
|
||||
dbvzResetAddressSpace();
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -822,7 +822,7 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
|
||||
//only reset address space if size changed, enabled/disabled or DRAM bit changed
|
||||
if((value & 0x020F) != (oldCsd & 0x020F))
|
||||
resetAddressSpace();
|
||||
dbvzResetAddressSpace();
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -830,7 +830,7 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
//sets the starting location of ROM(0x10000000) and the PDIUSBD12 chip
|
||||
if((value & 0xFFFE) != registerArrayRead16(CSGBA)){
|
||||
setCsgba(value);
|
||||
resetAddressSpace();
|
||||
dbvzResetAddressSpace();
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -838,7 +838,7 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
//sets the starting location of the SED1376(0x1FF80000)
|
||||
if((value & 0xFFFE) != registerArrayRead16(CSGBB)){
|
||||
setCsgbb(value);
|
||||
resetAddressSpace();
|
||||
dbvzResetAddressSpace();
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -850,7 +850,7 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
//sets the starting location of RAM(0x00000000)
|
||||
if((value & 0xFFFE) != registerArrayRead16(CSGBD)){
|
||||
setCsgbd(value);
|
||||
resetAddressSpace();
|
||||
dbvzResetAddressSpace();
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -861,7 +861,7 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
setCsgba(registerArrayRead16(CSGBA));
|
||||
setCsgbb(registerArrayRead16(CSGBB));
|
||||
setCsgbd(registerArrayRead16(CSGBD));
|
||||
resetAddressSpace();
|
||||
dbvzResetAddressSpace();
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -875,7 +875,7 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
//CSA is not dependent on CSCTRL1
|
||||
setCsb(registerArrayRead16(CSB));
|
||||
setCsd(registerArrayRead16(CSD));
|
||||
resetAddressSpace();
|
||||
dbvzResetAddressSpace();
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -956,10 +956,10 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
}
|
||||
}
|
||||
|
||||
void setHwRegister32(uint32_t address, uint32_t value){
|
||||
void dbvzSetRegister32(uint32_t address, uint32_t value){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if((address & 0x0000F000) != 0x0000F000){
|
||||
setBusErrorTimeOut(address, true);
|
||||
dbvzSetBusErrorTimeOut(address, true);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -1004,11 +1004,11 @@ void setHwRegister32(uint32_t address, uint32_t value){
|
||||
}
|
||||
}
|
||||
|
||||
void resetHwRegisters(void){
|
||||
void dbvzResetRegisters(void){
|
||||
uint32_t oldRtc = registerArrayRead32(RTCTIME);//preserve RTCTIME
|
||||
uint16_t oldDayr = registerArrayRead16(DAYR);//preserve DAYR
|
||||
|
||||
memset(palmReg, 0x00, REG_SIZE - BOOTLOADER_SIZE);
|
||||
memset(palmReg, 0x00, DBVZ_REG_SIZE - DBVZ_BOOTLOADER_SIZE);
|
||||
palmSysclksPerClk32 = 0.0;
|
||||
clk32Counter = 0;
|
||||
pctlrCpuClockDivider = 1.0;
|
||||
@@ -1033,19 +1033,19 @@ void resetHwRegisters(void){
|
||||
|
||||
memset(chips, 0x00, sizeof(chips));
|
||||
//all chip selects are disabled at boot and CSA0 is mapped to 0x00000000 and covers the entire address range until CSA is set enabled
|
||||
chips[CHIP_A0_ROM].inBootMode = true;
|
||||
chips[DBVZ_CHIP_A0_ROM].inBootMode = true;
|
||||
|
||||
//default sizes
|
||||
chips[CHIP_A0_ROM].lineSize = 0x20000;
|
||||
chips[CHIP_A1_USB].lineSize = 0x20000;
|
||||
chips[CHIP_B0_SED].lineSize = 0x20000;
|
||||
chips[CHIP_DX_RAM].lineSize = 0x8000;
|
||||
chips[DBVZ_CHIP_A0_ROM].lineSize = 0x20000;
|
||||
chips[DBVZ_CHIP_A1_USB].lineSize = 0x20000;
|
||||
chips[DBVZ_CHIP_B0_SED].lineSize = 0x20000;
|
||||
chips[DBVZ_CHIP_DX_RAM].lineSize = 0x8000;
|
||||
|
||||
//masks for reading and writing
|
||||
chips[CHIP_A0_ROM].mask = 0x003FFFFF;//4mb
|
||||
chips[CHIP_A1_USB].mask = 0x00000002;//A1 is used as USB chip A0
|
||||
chips[CHIP_B0_SED].mask = 0x0001FFFF;
|
||||
chips[CHIP_DX_RAM].mask = 0x00000000;//16mb, no RAM enabled until the DRAM module is initialized
|
||||
chips[DBVZ_CHIP_A0_ROM].mask = 0x003FFFFF;//4mb
|
||||
chips[DBVZ_CHIP_A1_USB].mask = 0x00000002;//A1 is used as USB chip A0
|
||||
chips[DBVZ_CHIP_B0_SED].mask = 0x0001FFFF;
|
||||
chips[DBVZ_CHIP_DX_RAM].mask = 0x00000000;//16mb, no RAM enabled until the DRAM module is initialized
|
||||
|
||||
//system control
|
||||
registerArrayWrite8(SCR, 0x1C);
|
||||
@@ -1156,7 +1156,7 @@ void resetHwRegisters(void){
|
||||
palmSysclksPerClk32 = sysclksPerClk32();
|
||||
}
|
||||
|
||||
void setRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds){
|
||||
void dbvzSetRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds){
|
||||
registerArrayWrite32(RTCTIME, hours << 24 & 0x1F000000 | minutes << 16 & 0x003F0000 | seconds & 0x0000003F);
|
||||
registerArrayWrite16(DAYR, days & 0x01FF);
|
||||
}
|
||||
119
src/dbvzRegisters.h
Normal file
119
src/dbvzRegisters.h
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifndef DBVZ_REGISTERS_H
|
||||
#define DBVZ_REGISTERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
//interrupt names
|
||||
#define DBVZ_INT_EMIQ 0x00800000//level 7
|
||||
#define DBVZ_INT_RTI 0x00400000//level 4
|
||||
#define DBVZ_INT_SPI1 0x00200000//level 1<->6, configurable, datasheet is contraditory on this one
|
||||
#define DBVZ_INT_IRQ5 0x00100000//level 5
|
||||
#define DBVZ_INT_IRQ6 0x00080000//level 6
|
||||
#define DBVZ_INT_IRQ3 0x00040000//level 3
|
||||
#define DBVZ_INT_IRQ2 0x00020000//level 2
|
||||
#define DBVZ_INT_IRQ1 0x00010000//level 1
|
||||
#define DBVZ_INT_PWM2 0x00002000//level 1<->6, configurable
|
||||
#define DBVZ_INT_UART2 0x00001000//level 1<->6, configurable
|
||||
#define DBVZ_INT_INT3 0x00000800//level 4
|
||||
#define DBVZ_INT_INT2 0x00000400//level 4
|
||||
#define DBVZ_INT_INT1 0x00000200//level 4
|
||||
#define DBVZ_INT_INT0 0x00000100//level 4
|
||||
#define DBVZ_INT_PWM1 0x00000080//level 6
|
||||
#define DBVZ_INT_KB 0x00000040//level 4
|
||||
#define DBVZ_INT_TMR2 0x00000020//level 1<->6, configurable
|
||||
#define DBVZ_INT_RTC 0x00000010//level 4
|
||||
#define DBVZ_INT_WDT 0x00000008//level 4
|
||||
#define DBVZ_INT_UART1 0x00000004//level 4
|
||||
#define DBVZ_INT_TMR1 0x00000002//level 6
|
||||
#define DBVZ_INT_SPI2 0x00000001//level 4
|
||||
|
||||
//reasons a timer is triggered
|
||||
#define DBVZ_TIMER_REASON_SYSCLK 0x00
|
||||
#define DBVZ_TIMER_REASON_TIN 0x01
|
||||
#define DBVZ_TIMER_REASON_CLK32 0x02
|
||||
|
||||
//chip names
|
||||
enum{
|
||||
DBVZ_CHIP_BEGIN = 0,
|
||||
DBVZ_CHIP_A0_ROM = 0,
|
||||
DBVZ_CHIP_A1_USB,
|
||||
DBVZ_CHIP_B0_SED,
|
||||
DBVZ_CHIP_B1_NIL,
|
||||
//DBVZ_CHIP_CX_RAM, //CSC* is owned by CSD during normal operation
|
||||
DBVZ_CHIP_DX_RAM,
|
||||
DBVZ_CHIP_00_EMU, //used for EMUCS on hardware, used by the emu registers here
|
||||
DBVZ_CHIP_REGISTERS,
|
||||
DBVZ_CHIP_NONE,
|
||||
DBVZ_CHIP_END
|
||||
};
|
||||
|
||||
//types
|
||||
typedef struct{
|
||||
bool enable;
|
||||
uint32_t start;
|
||||
uint32_t lineSize;//the size of a single chip select line, multiply by 2 to get the range size for RAM
|
||||
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;
|
||||
uint32_t unprotectedSize;
|
||||
}dbvz_chip_t;
|
||||
|
||||
//variables
|
||||
extern dbvz_chip_t chips[];
|
||||
extern int8_t pllSleepWait;
|
||||
extern int8_t pllWakeWait;
|
||||
extern uint32_t clk32Counter;
|
||||
extern double pctlrCpuClockDivider;
|
||||
extern double timerCycleCounter[];
|
||||
extern uint16_t timerStatusReadAcknowledge[];
|
||||
extern uint8_t portDInterruptLastValue;
|
||||
extern uint16_t spi1RxFifo[];
|
||||
extern uint16_t spi1TxFifo[];
|
||||
extern uint8_t spi1RxReadPosition;
|
||||
extern uint8_t spi1RxWritePosition;
|
||||
extern bool spi1RxOverflowed;
|
||||
extern uint8_t spi1TxReadPosition;
|
||||
extern uint8_t spi1TxWritePosition;
|
||||
extern int32_t pwm1ClocksToNextSample;
|
||||
extern uint8_t pwm1Fifo[];
|
||||
extern uint8_t pwm1ReadPosition;
|
||||
extern uint8_t pwm1WritePosition;
|
||||
|
||||
//timing
|
||||
void dbvzBeginClk32(void);
|
||||
void dbvzEndClk32(void);
|
||||
void dbvzAddSysclks(double value);//only call between begin/endClk32
|
||||
|
||||
//CPU
|
||||
bool dbvzIsPllOn(void);
|
||||
bool m515BacklightAmplifierState(void);
|
||||
bool dbvzAreRegistersXXFFMapped(void);
|
||||
bool sed1376ClockConnected(void);
|
||||
void ads7846OverridePenState(bool value);
|
||||
void m515RefreshTouchState(void);//just refreshes the touchscreen
|
||||
void m515RefreshInputState(void);//refreshes touchscreen, buttons and docked status
|
||||
//int32_t interruptAcknowledge(int32_t intLevel);//this is in m68kexternal.h
|
||||
|
||||
//memory errors
|
||||
void dbvzSetBusErrorTimeOut(uint32_t address, bool isWrite);
|
||||
void dbvzSetPrivilegeViolation(uint32_t address, bool isWrite);
|
||||
void dbvzSetWriteProtectViolation(uint32_t address);
|
||||
|
||||
//memory accessors
|
||||
uint8_t dbvzGetRegister8(uint32_t address);
|
||||
uint16_t dbvzGetRegister16(uint32_t address);
|
||||
uint32_t dbvzGetRegister32(uint32_t address);
|
||||
void dbvzSetRegister8(uint32_t address, uint8_t value);
|
||||
void dbvzSetRegister16(uint32_t address, uint16_t value);
|
||||
void dbvzSetRegister32(uint32_t address, uint32_t value);
|
||||
|
||||
//config
|
||||
void dbvzResetRegisters(void);
|
||||
void dbvzSetRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds);
|
||||
|
||||
#endif
|
||||
@@ -16,25 +16,25 @@ static void timer1(uint8_t reason, double sysclks){
|
||||
return;
|
||||
|
||||
case 0x0001://SYSCLK / timer prescaler
|
||||
if(reason != TIMER_REASON_SYSCLK)
|
||||
if(reason != DBVZ_TIMER_REASON_SYSCLK)
|
||||
return;
|
||||
timerCycleCounter[0] += sysclks / timer1Prescaler;
|
||||
break;
|
||||
|
||||
case 0x0002://SYSCLK / 16 / timer prescaler
|
||||
if(reason != TIMER_REASON_SYSCLK)
|
||||
if(reason != DBVZ_TIMER_REASON_SYSCLK)
|
||||
return;
|
||||
timerCycleCounter[0] += sysclks / 16.0 / timer1Prescaler;
|
||||
break;
|
||||
|
||||
case 0x0003://TIN/TOUT pin / timer prescaler, the other timer can be attached to TIN/TOUT
|
||||
if(reason != TIMER_REASON_TIN)
|
||||
if(reason != DBVZ_TIMER_REASON_TIN)
|
||||
return;
|
||||
timerCycleCounter[0] += 1.0 / timer1Prescaler;
|
||||
break;
|
||||
|
||||
default://CLK32 / timer prescaler
|
||||
if(reason != TIMER_REASON_CLK32)
|
||||
if(reason != DBVZ_TIMER_REASON_CLK32)
|
||||
return;
|
||||
timerCycleCounter[0] += 1.0 / timer1Prescaler;
|
||||
break;
|
||||
@@ -47,7 +47,7 @@ static void timer1(uint8_t reason, double sysclks){
|
||||
|
||||
//interrupt enabled
|
||||
if(timer1Control & 0x0010)
|
||||
setIprIsrBit(INT_TMR1);
|
||||
setIprIsrBit(DBVZ_INT_TMR1);
|
||||
//checkInterrupts() is run when the clock that called this function is finished
|
||||
|
||||
//set timer triggered bit
|
||||
@@ -56,7 +56,7 @@ static void timer1(uint8_t reason, double sysclks){
|
||||
|
||||
//increment other timer if enabled
|
||||
if(pcrTinToutConfig == 0x03)
|
||||
timer2(TIMER_REASON_TIN, 0);
|
||||
timer2(DBVZ_TIMER_REASON_TIN, 0);
|
||||
|
||||
//not free running, reset to 0, to prevent loss of ticks after compare event just subtract timerXCompare
|
||||
if(!(timer1Control & 0x0100))
|
||||
@@ -83,25 +83,25 @@ static void timer2(uint8_t reason, double sysclks){
|
||||
return;
|
||||
|
||||
case 0x0001://SYSCLK / timer prescaler
|
||||
if(reason != TIMER_REASON_SYSCLK)
|
||||
if(reason != DBVZ_TIMER_REASON_SYSCLK)
|
||||
return;
|
||||
timerCycleCounter[1] += sysclks / timer2Prescaler;
|
||||
break;
|
||||
|
||||
case 0x0002://SYSCLK / 16 / timer prescaler
|
||||
if(reason != TIMER_REASON_SYSCLK)
|
||||
if(reason != DBVZ_TIMER_REASON_SYSCLK)
|
||||
return;
|
||||
timerCycleCounter[1] += sysclks / 16.0 / timer2Prescaler;
|
||||
break;
|
||||
|
||||
case 0x0003://TIN/TOUT pin / timer prescaler, the other timer can be attached to TIN/TOUT
|
||||
if(reason != TIMER_REASON_TIN)
|
||||
if(reason != DBVZ_TIMER_REASON_TIN)
|
||||
return;
|
||||
timerCycleCounter[1] += 1.0 / timer2Prescaler;
|
||||
break;
|
||||
|
||||
default://CLK32 / timer prescaler
|
||||
if(reason != TIMER_REASON_CLK32)
|
||||
if(reason != DBVZ_TIMER_REASON_CLK32)
|
||||
return;
|
||||
timerCycleCounter[1] += 1.0 / timer2Prescaler;
|
||||
break;
|
||||
@@ -114,7 +114,7 @@ static void timer2(uint8_t reason, double sysclks){
|
||||
|
||||
//interrupt enabled
|
||||
if(timer2Control & 0x0010)
|
||||
setIprIsrBit(INT_TMR2);
|
||||
setIprIsrBit(DBVZ_INT_TMR2);
|
||||
//checkInterrupts() is run when the clock that called this function is finished
|
||||
|
||||
//set timer triggered bit
|
||||
@@ -123,7 +123,7 @@ static void timer2(uint8_t reason, double sysclks){
|
||||
|
||||
//increment other timer if enabled
|
||||
if(pcrTinToutConfig == 0x02)
|
||||
timer1(TIMER_REASON_TIN, 0);
|
||||
timer1(DBVZ_TIMER_REASON_TIN, 0);
|
||||
|
||||
//not free running, reset to 0, to prevent loss of ticks after compare event just subtract timerXCompare
|
||||
if(!(timer2Control & 0x0100))
|
||||
@@ -205,7 +205,7 @@ static void rtiInterruptClk32(void){
|
||||
triggeredRtiInterrupts &= registerArrayRead16(RTCIENR);
|
||||
if(triggeredRtiInterrupts){
|
||||
registerArrayWrite16(RTCISR, registerArrayRead16(RTCISR) | triggeredRtiInterrupts);
|
||||
setIprIsrBit(INT_RTI);
|
||||
setIprIsrBit(DBVZ_INT_RTI);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ static void watchdogSecondTickClk32(void){
|
||||
if(watchdogState & 0x0002){
|
||||
//interrupt
|
||||
watchdogState |= 0x0080;
|
||||
setIprIsrBit(INT_WDT);
|
||||
setIprIsrBit(DBVZ_INT_WDT);
|
||||
}
|
||||
else{
|
||||
//reset
|
||||
@@ -291,7 +291,7 @@ static void rtcAddSecondClk32(void){
|
||||
rtcInterruptEvents &= registerArrayRead16(RTCIENR);
|
||||
if(rtcInterruptEvents){
|
||||
registerArrayWrite16(RTCISR, registerArrayRead16(RTCISR) | rtcInterruptEvents);
|
||||
setIprIsrBit(INT_RTC);
|
||||
setIprIsrBit(DBVZ_INT_RTC);
|
||||
}
|
||||
|
||||
registerArrayWrite32(RTCTIME, newRtcTime);
|
||||
@@ -301,11 +301,11 @@ static void rtcAddSecondClk32(void){
|
||||
watchdogSecondTickClk32();
|
||||
}
|
||||
|
||||
void beginClk32(void){
|
||||
void dbvzBeginClk32(void){
|
||||
palmClk32Sysclks = 0.0;
|
||||
}
|
||||
|
||||
void endClk32(void){
|
||||
void dbvzEndClk32(void){
|
||||
//currently using toggle on read hack
|
||||
//registerArrayWrite16(PLLFSR, registerArrayRead16(PLLFSR) ^ 0x8000);
|
||||
|
||||
@@ -322,8 +322,8 @@ void endClk32(void){
|
||||
if(registerArrayRead16(RTCCTL) & 0x0080 || registerArrayRead16(WATCHDOG) & 0x01)
|
||||
rtiInterruptClk32();
|
||||
|
||||
timer1(TIMER_REASON_CLK32, 0);
|
||||
timer2(TIMER_REASON_CLK32, 0);
|
||||
timer1(DBVZ_TIMER_REASON_CLK32, 0);
|
||||
timer2(DBVZ_TIMER_REASON_CLK32, 0);
|
||||
samplePwm1(true/*forClk32*/, 0.0);
|
||||
|
||||
//PLLCR sleep wait
|
||||
@@ -350,9 +350,9 @@ void endClk32(void){
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
void addSysclks(double count){
|
||||
timer1(TIMER_REASON_SYSCLK, count);
|
||||
timer2(TIMER_REASON_SYSCLK, count);
|
||||
void dbvzAddSysclks(double count){
|
||||
timer1(DBVZ_TIMER_REASON_SYSCLK, count);
|
||||
timer2(DBVZ_TIMER_REASON_SYSCLK, count);
|
||||
samplePwm1(false/*forClk32*/, count);
|
||||
|
||||
checkInterrupts();
|
||||
@@ -370,5 +370,5 @@ static int32_t audioGetFramePercentIncrementFromSysclks(double count){
|
||||
static int32_t audioGetFramePercentage(void){
|
||||
//returns how much of the frame has executed
|
||||
//0% = 0, 100% = AUDIO_END_OF_FRAME
|
||||
return audioGetFramePercentIncrementFromClk32s(palmFrameClk32s) + (pllIsOn() ? audioGetFramePercentIncrementFromSysclks(palmClk32Sysclks) : 0);
|
||||
return audioGetFramePercentIncrementFromClk32s(palmFrameClk32s) + (dbvzIsPllOn() ? audioGetFramePercentIncrementFromSysclks(palmClk32Sysclks) : 0);
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "../m68k/m68kcpu.h"
|
||||
#include "../emulator.h"
|
||||
#include "../ads7846.h"
|
||||
#include "../hardwareRegisters.h"
|
||||
#include "../dbvzRegisters.h"
|
||||
#include "../portability.h"
|
||||
#include "../specs/emuFeatureRegisterSpec.h"
|
||||
#include "sandbox.h"
|
||||
@@ -165,9 +165,9 @@ static void printTrapInfo(uint16_t trap){
|
||||
}
|
||||
|
||||
bool validExecutionAddress(uint32_t address){
|
||||
if(chips[CHIP_A0_ROM].inBootMode || address >= chips[CHIP_A0_ROM].start && address < chips[CHIP_A0_ROM].start + chips[CHIP_A0_ROM].lineSize)
|
||||
if(chips[DBVZ_CHIP_A0_ROM].inBootMode || address >= chips[DBVZ_CHIP_A0_ROM].start && address < chips[DBVZ_CHIP_A0_ROM].start + chips[DBVZ_CHIP_A0_ROM].lineSize)
|
||||
return true;
|
||||
if(address >= chips[CHIP_DX_RAM].start && address < chips[CHIP_DX_RAM].start + chips[CHIP_DX_RAM].lineSize)
|
||||
if(address >= chips[DBVZ_CHIP_DX_RAM].start && address < chips[DBVZ_CHIP_DX_RAM].start + chips[DBVZ_CHIP_DX_RAM].lineSize)
|
||||
return true;
|
||||
if(sandboxActive && address >= 0xFFFFFE00)//used to run custom code when in sandbox mode
|
||||
return true;
|
||||
@@ -252,8 +252,8 @@ static uint32_t scanForPrivateFunctionAddress(const char* name){
|
||||
//function name format [0x**(unknown), string(with null terminator), 0x00, 0x00(if last 0x00 was on an even address, protects opcode alignemnt)]
|
||||
//this is not 100% accurate, it scans memory for a function address based on a string
|
||||
//if a duplicate set of stings is found but not encasing a function a fatal error will occur on execution
|
||||
uint32_t rangeEnd = chips[CHIP_A0_ROM].start + chips[CHIP_A0_ROM].lineSize - 1;
|
||||
uint32_t address = find68kString(name, chips[CHIP_A0_ROM].start, rangeEnd);
|
||||
uint32_t rangeEnd = chips[DBVZ_CHIP_A0_ROM].start + chips[DBVZ_CHIP_A0_ROM].lineSize - 1;
|
||||
uint32_t address = find68kString(name, chips[DBVZ_CHIP_A0_ROM].start, rangeEnd);
|
||||
|
||||
while(address < rangeEnd){
|
||||
uint32_t signatureBegining = address - 3;//last opcode of function being looked for if the string is correct
|
||||
@@ -376,7 +376,7 @@ static bool installResourceToDevice(buffer_t resourceBuffer){
|
||||
*/
|
||||
|
||||
uint32_t palmSideResourceData = sandboxCallGuestFunction(false, 0x00000000, MemChunkNew, "p(wlw)", 1/*heapID, storage RAM*/, resourceBuffer.size, 0x1200/*attr, seems to work without memOwnerID*/);
|
||||
bool storageRamReadOnly = chips[CHIP_DX_RAM].readOnlyForProtectedMemory;
|
||||
bool storageRamReadOnly = chips[DBVZ_CHIP_DX_RAM].readOnlyForProtectedMemory;
|
||||
uint16_t error;
|
||||
uint32_t count;
|
||||
|
||||
@@ -384,10 +384,10 @@ static bool installResourceToDevice(buffer_t resourceBuffer){
|
||||
if(!palmSideResourceData)
|
||||
return false;
|
||||
|
||||
chips[CHIP_DX_RAM].readOnlyForProtectedMemory = false;//need to unprotect storage RAM
|
||||
chips[DBVZ_CHIP_DX_RAM].readOnlyForProtectedMemory = false;//need to unprotect storage RAM
|
||||
for(count = 0; count < resourceBuffer.size; count++)
|
||||
m68k_write_memory_8(palmSideResourceData + count, resourceBuffer.data[count]);
|
||||
chips[CHIP_DX_RAM].readOnlyForProtectedMemory = storageRamReadOnly;//restore old protection state
|
||||
chips[DBVZ_CHIP_DX_RAM].readOnlyForProtectedMemory = storageRamReadOnly;//restore old protection state
|
||||
error = sandboxCallGuestFunction(false, 0x00000000, DmCreateDatabaseFromImage, "w(p)", palmSideResourceData);//Err DmCreateDatabaseFromImage(MemPtr bufferP);//this looks best
|
||||
sandboxCallGuestFunction(false, 0x00000000, MemChunkFree, "w(p)", palmSideResourceData);
|
||||
|
||||
@@ -1197,7 +1197,7 @@ void sandboxOnMemoryAccess(uint32_t address, uint8_t size, bool write, uint32_t
|
||||
if(!functionValid)
|
||||
function = "NAME NOT FOUND";
|
||||
|
||||
if(address >= chips[CHIP_DX_RAM].start && address < chips[CHIP_DX_RAM].start + 0x10000){
|
||||
if(address >= chips[DBVZ_CHIP_DX_RAM].start && address < chips[DBVZ_CHIP_DX_RAM].start + 0x10000){
|
||||
//low mem globals
|
||||
address &= 0xFFFF;
|
||||
|
||||
@@ -1232,7 +1232,7 @@ void sandboxOnMemoryAccess(uint32_t address, uint8_t size, bool write, uint32_t
|
||||
debugLog("Reading hardware register: name:%s/address:0x%08X, size:%d, function:%s/PC:0x%08X\n", registerName, address, size, function, pc);
|
||||
}
|
||||
}
|
||||
else if(address >= chips[CHIP_B0_SED].start && address < chips[CHIP_B0_SED].start + chips[CHIP_B0_SED].lineSize){
|
||||
else if(address >= chips[DBVZ_CHIP_B0_SED].start && address < chips[DBVZ_CHIP_B0_SED].start + chips[DBVZ_CHIP_B0_SED].lineSize){
|
||||
//SED1376
|
||||
if(address & SED1376_MR_BIT){
|
||||
//SED1376 data
|
||||
|
||||
102
src/emulator.c
102
src/emulator.c
@@ -6,9 +6,9 @@
|
||||
#include "audio/blip_buf.h"
|
||||
#include "flx68000.h"
|
||||
#include "emulator.h"
|
||||
#include "hardwareRegisters.h"
|
||||
#include "dbvzRegisters.h"
|
||||
#include "expansionHardware.h"
|
||||
#include "memoryAccess.h"
|
||||
#include "m515Bus.h"
|
||||
#include "sed1376.h"
|
||||
#include "ads7846.h"
|
||||
#include "pdiUsbD12.h"
|
||||
@@ -68,10 +68,10 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t enab
|
||||
return EMU_ERROR_INVALID_PARAMETER;
|
||||
|
||||
//allocate buffers, add 4 to memory regions to prevent SIGSEGV from accessing off the end
|
||||
palmRam = malloc(RAM_SIZE + 4);
|
||||
palmRom = malloc(ROM_SIZE + 4);
|
||||
palmReg = malloc(REG_SIZE + 4);
|
||||
palmFramebuffer = malloc(480 * 480 * sizeof(uint16_t));
|
||||
palmRam = malloc(M515_RAM_SIZE + 4);
|
||||
palmRom = malloc(M515_ROM_SIZE + 4);
|
||||
palmReg = malloc(DBVZ_REG_SIZE + 4);
|
||||
palmFramebuffer = malloc(160 * 220 * sizeof(uint16_t));
|
||||
palmAudio = malloc(AUDIO_SAMPLES_PER_FRAME * 2 * sizeof(int16_t));
|
||||
palmAudioResampler = blip_new(AUDIO_SAMPLE_RATE);//have 1 second of samples
|
||||
if(!palmRam || !palmRom || !palmReg || !palmFramebuffer || !palmAudio || !palmAudioResampler){
|
||||
@@ -85,19 +85,19 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t enab
|
||||
}
|
||||
|
||||
//set default values
|
||||
memset(palmRam, 0x00, RAM_SIZE);
|
||||
memcpy(palmRom, palmRomDump.data, u32Min(palmRomDump.size, ROM_SIZE));
|
||||
if(palmRomDump.size < ROM_SIZE)
|
||||
memset(palmRom + palmRomDump.size, 0x00, ROM_SIZE - palmRomDump.size);
|
||||
swap16BufferIfLittle(palmRom, ROM_SIZE / sizeof(uint16_t));
|
||||
memset(palmRam, 0x00, M515_RAM_SIZE);
|
||||
memcpy(palmRom, palmRomDump.data, u32Min(palmRomDump.size, M515_ROM_SIZE));
|
||||
if(palmRomDump.size < M515_ROM_SIZE)
|
||||
memset(palmRom + palmRomDump.size, 0x00, M515_ROM_SIZE - palmRomDump.size);
|
||||
swap16BufferIfLittle(palmRom, M515_ROM_SIZE / sizeof(uint16_t));
|
||||
if(palmBootDump.data){
|
||||
memcpy(palmReg + REG_SIZE - 1 - BOOTLOADER_SIZE, palmBootDump.data, u32Min(palmBootDump.size, BOOTLOADER_SIZE));
|
||||
if(palmBootDump.size < BOOTLOADER_SIZE)
|
||||
memset(palmReg + REG_SIZE - 1 - BOOTLOADER_SIZE + palmBootDump.size, 0x00, BOOTLOADER_SIZE - palmBootDump.size);
|
||||
swap16BufferIfLittle(palmReg + REG_SIZE - 1 - BOOTLOADER_SIZE, BOOTLOADER_SIZE / sizeof(uint16_t));
|
||||
memcpy(palmReg + DBVZ_REG_SIZE - 1 - DBVZ_BOOTLOADER_SIZE, palmBootDump.data, u32Min(palmBootDump.size, DBVZ_BOOTLOADER_SIZE));
|
||||
if(palmBootDump.size < DBVZ_BOOTLOADER_SIZE)
|
||||
memset(palmReg + DBVZ_REG_SIZE - 1 - DBVZ_BOOTLOADER_SIZE + palmBootDump.size, 0x00, DBVZ_BOOTLOADER_SIZE - palmBootDump.size);
|
||||
swap16BufferIfLittle(palmReg + DBVZ_REG_SIZE - 1 - DBVZ_BOOTLOADER_SIZE, DBVZ_BOOTLOADER_SIZE / sizeof(uint16_t));
|
||||
}
|
||||
else{
|
||||
memset(palmReg + REG_SIZE - 1 - BOOTLOADER_SIZE, 0x00, BOOTLOADER_SIZE);
|
||||
memset(palmReg + DBVZ_REG_SIZE - 1 - DBVZ_BOOTLOADER_SIZE, 0x00, DBVZ_BOOTLOADER_SIZE);
|
||||
}
|
||||
memset(palmAudio, 0x00, AUDIO_SAMPLES_PER_FRAME * 2/*channels*/ * sizeof(int16_t));
|
||||
memset(&palmInput, 0x00, sizeof(palmInput));
|
||||
@@ -115,7 +115,7 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t enab
|
||||
|
||||
//reset everything
|
||||
emulatorSoftReset();
|
||||
setRtc(0, 0, 0, 0);//RTCTIME and DAYR are not cleared by reset, clear them manually in case the frontend doesnt set the RTC
|
||||
dbvzSetRtc(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;
|
||||
|
||||
@@ -137,10 +137,10 @@ void emulatorExit(void){
|
||||
|
||||
void emulatorHardReset(void){
|
||||
//equivalent to taking the battery out and putting it back in
|
||||
memset(palmRam, 0x00, RAM_SIZE);
|
||||
memset(palmRam, 0x00, M515_RAM_SIZE);
|
||||
emulatorSoftReset();
|
||||
sdCardReset();
|
||||
setRtc(0, 0, 0, 0);
|
||||
dbvzSetRtc(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void emulatorSoftReset(void){
|
||||
@@ -159,7 +159,7 @@ void emulatorSoftReset(void){
|
||||
}
|
||||
|
||||
void emulatorSetRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds){
|
||||
setRtc(days, hours, minutes, seconds);
|
||||
dbvzSetRtc(days, hours, minutes, seconds);
|
||||
}
|
||||
|
||||
uint32_t emulatorGetStateSize(void){
|
||||
@@ -175,11 +175,11 @@ uint32_t emulatorGetStateSize(void){
|
||||
size += pdiUsbD12StateSize();
|
||||
size += expansionHardwareStateSize();
|
||||
size += sandboxStateSize();
|
||||
size += RAM_SIZE;//system RAM buffer
|
||||
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) * 5 * CHIP_END;//chip select states
|
||||
size += M515_RAM_SIZE;//system RAM buffer
|
||||
size += DBVZ_REG_SIZE;//hardware registers
|
||||
size += DBVZ_TOTAL_MEMORY_BANKS;//bank handlers
|
||||
size += sizeof(uint32_t) * 4 * DBVZ_CHIP_END;//chip select states
|
||||
size += sizeof(uint8_t) * 5 * DBVZ_CHIP_END;//chip select states
|
||||
size += sizeof(uint64_t) * 5;//32.32 fixed point double, timerXCycleCounter and CPU cycle timers
|
||||
size += sizeof(int8_t);//pllSleepWait
|
||||
size += sizeof(int8_t);//pllWakeWait
|
||||
@@ -249,15 +249,15 @@ bool emulatorSaveState(buffer_t buffer){
|
||||
offset += sandboxStateSize();
|
||||
|
||||
//memory
|
||||
memcpy(buffer.data + offset, palmRam, RAM_SIZE);
|
||||
swap16BufferIfLittle(buffer.data + offset, RAM_SIZE / sizeof(uint16_t));
|
||||
offset += RAM_SIZE;
|
||||
memcpy(buffer.data + offset, palmReg, REG_SIZE);
|
||||
swap16BufferIfLittle(buffer.data + offset, REG_SIZE / sizeof(uint16_t));
|
||||
offset += REG_SIZE;
|
||||
memcpy(buffer.data + offset, bankType, TOTAL_MEMORY_BANKS);
|
||||
offset += TOTAL_MEMORY_BANKS;
|
||||
for(index = CHIP_BEGIN; index < CHIP_END; index++){
|
||||
memcpy(buffer.data + offset, palmRam, M515_RAM_SIZE);
|
||||
swap16BufferIfLittle(buffer.data + offset, M515_RAM_SIZE / sizeof(uint16_t));
|
||||
offset += M515_RAM_SIZE;
|
||||
memcpy(buffer.data + offset, palmReg, DBVZ_REG_SIZE);
|
||||
swap16BufferIfLittle(buffer.data + offset, DBVZ_REG_SIZE / sizeof(uint16_t));
|
||||
offset += DBVZ_REG_SIZE;
|
||||
memcpy(buffer.data + offset, dbvzBankType, DBVZ_TOTAL_MEMORY_BANKS);
|
||||
offset += DBVZ_TOTAL_MEMORY_BANKS;
|
||||
for(index = DBVZ_CHIP_BEGIN; index < DBVZ_CHIP_END; index++){
|
||||
writeStateValue8(buffer.data + offset, chips[index].enable);
|
||||
offset += sizeof(uint8_t);
|
||||
writeStateValue32(buffer.data + offset, chips[index].start);
|
||||
@@ -447,15 +447,15 @@ bool emulatorLoadState(buffer_t buffer){
|
||||
offset += sandboxStateSize();
|
||||
|
||||
//memory
|
||||
memcpy(palmRam, buffer.data + offset, RAM_SIZE);
|
||||
swap16BufferIfLittle(palmRam, RAM_SIZE / sizeof(uint16_t));
|
||||
offset += RAM_SIZE;
|
||||
memcpy(palmReg, buffer.data + offset, REG_SIZE);
|
||||
swap16BufferIfLittle(palmReg, REG_SIZE / sizeof(uint16_t));
|
||||
offset += REG_SIZE;
|
||||
memcpy(bankType, buffer.data + offset, TOTAL_MEMORY_BANKS);
|
||||
offset += TOTAL_MEMORY_BANKS;
|
||||
for(index = CHIP_BEGIN; index < CHIP_END; index++){
|
||||
memcpy(palmRam, buffer.data + offset, M515_RAM_SIZE);
|
||||
swap16BufferIfLittle(palmRam, M515_RAM_SIZE / sizeof(uint16_t));
|
||||
offset += M515_RAM_SIZE;
|
||||
memcpy(palmReg, buffer.data + offset, DBVZ_REG_SIZE);
|
||||
swap16BufferIfLittle(palmReg, DBVZ_REG_SIZE / sizeof(uint16_t));
|
||||
offset += DBVZ_REG_SIZE;
|
||||
memcpy(dbvzBankType, buffer.data + offset, DBVZ_TOTAL_MEMORY_BANKS);
|
||||
offset += DBVZ_TOTAL_MEMORY_BANKS;
|
||||
for(index = DBVZ_CHIP_BEGIN; index < DBVZ_CHIP_END; index++){
|
||||
chips[index].enable = readStateValue8(buffer.data + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
chips[index].start = readStateValue32(buffer.data + offset);
|
||||
@@ -607,25 +607,25 @@ bool emulatorLoadState(buffer_t buffer){
|
||||
}
|
||||
|
||||
uint32_t emulatorGetRamSize(void){
|
||||
return RAM_SIZE;
|
||||
return M515_RAM_SIZE;
|
||||
}
|
||||
|
||||
bool emulatorSaveRam(buffer_t buffer){
|
||||
if(buffer.size < RAM_SIZE)
|
||||
if(buffer.size < M515_RAM_SIZE)
|
||||
return false;
|
||||
|
||||
memcpy(buffer.data, palmRam, RAM_SIZE);
|
||||
swap16BufferIfLittle(buffer.data, RAM_SIZE / sizeof(uint16_t));
|
||||
memcpy(buffer.data, palmRam, M515_RAM_SIZE);
|
||||
swap16BufferIfLittle(buffer.data, M515_RAM_SIZE / sizeof(uint16_t));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool emulatorLoadRam(buffer_t buffer){
|
||||
if(buffer.size < RAM_SIZE)
|
||||
if(buffer.size < M515_RAM_SIZE)
|
||||
return false;
|
||||
|
||||
memcpy(palmRam, buffer.data, RAM_SIZE);
|
||||
swap16BufferIfLittle(palmRam, RAM_SIZE / sizeof(uint16_t));
|
||||
memcpy(palmRam, buffer.data, M515_RAM_SIZE);
|
||||
swap16BufferIfLittle(palmRam, M515_RAM_SIZE / sizeof(uint16_t));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -680,7 +680,7 @@ void emulatorRunFrame(void){
|
||||
uint32_t samples;
|
||||
|
||||
//I/O
|
||||
refreshInputState();
|
||||
m515RefreshInputState();
|
||||
|
||||
//CPU
|
||||
palmFrameClk32s = 0;
|
||||
|
||||
@@ -12,7 +12,7 @@ extern "C" {
|
||||
#include <stdio.h>
|
||||
|
||||
#include "audio/blip_buf.h"
|
||||
#include "memoryAccess.h"//for size macros
|
||||
#include "m515Bus.h"//for size macros
|
||||
#include "specs/emuFeatureRegisterSpec.h"//for feature names
|
||||
|
||||
//DEFINE INFO!!!
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include "emulator.h"
|
||||
#include "portability.h"
|
||||
#include "specs/emuFeatureRegisterSpec.h"
|
||||
#include "memoryAccess.h"
|
||||
#include "hardwareRegisters.h"
|
||||
#include "m515Bus.h"
|
||||
#include "dbvzRegisters.h"
|
||||
#include "silkscreen.h"
|
||||
#include "sed1376.h"
|
||||
#include "flx68000.h"
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
#include "emulator.h"
|
||||
#include "portability.h"
|
||||
#include "hardwareRegisters.h"
|
||||
#include "memoryAccess.h"
|
||||
#include "dbvzRegisters.h"
|
||||
#include "m515Bus.h"
|
||||
#include "m68k/m68kcpu.h"
|
||||
|
||||
|
||||
@@ -19,19 +19,19 @@ void flx68000PcLongJump(uint32_t newPc){
|
||||
uint32_t windowSize;
|
||||
|
||||
switch(bankType[START_BANK(newPc)]){
|
||||
case CHIP_A0_ROM:
|
||||
case DBVZ_CHIP_A0_ROM:
|
||||
dataBufferHost = (uintptr_t)palmRom;
|
||||
dataBufferGuest = chips[CHIP_A0_ROM].start;
|
||||
windowSize = chips[CHIP_A0_ROM].mask + 1;
|
||||
dataBufferGuest = chips[DBVZ_CHIP_A0_ROM].start;
|
||||
windowSize = chips[DBVZ_CHIP_A0_ROM].mask + 1;
|
||||
break;
|
||||
|
||||
case CHIP_DX_RAM:
|
||||
case DBVZ_CHIP_DX_RAM:
|
||||
dataBufferHost = (uintptr_t)palmRam;
|
||||
dataBufferGuest = chips[CHIP_DX_RAM].start;
|
||||
windowSize = chips[CHIP_DX_RAM].mask + 1;
|
||||
dataBufferGuest = chips[DBVZ_CHIP_DX_RAM].start;
|
||||
windowSize = chips[DBVZ_CHIP_DX_RAM].mask + 1;
|
||||
break;
|
||||
|
||||
case CHIP_REGISTERS:
|
||||
case DBVZ_CHIP_REGISTERS:
|
||||
//needed for when EMU_NO_SAFETY is set and a function is run in the sandbox
|
||||
dataBufferHost = (uintptr_t)palmReg;
|
||||
dataBufferGuest = BANK_ADDRESS(START_BANK(newPc));
|
||||
@@ -93,8 +93,8 @@ void flx68000Init(void){
|
||||
}
|
||||
|
||||
void flx68000Reset(void){
|
||||
resetHwRegisters();
|
||||
resetAddressSpace();//address space must be reset after hardware registers because it is dependent on them
|
||||
dbvzResetRegisters();
|
||||
dbvzResetAddressSpace();//address space must be reset after hardware registers because it is dependent on them
|
||||
m68k_pulse_reset();
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ void flx68000LoadStateFinished(void){
|
||||
void flx68000Execute(void){
|
||||
double cyclesRemaining = palmSysclksPerClk32;
|
||||
|
||||
beginClk32();
|
||||
dbvzBeginClk32();
|
||||
|
||||
while(cyclesRemaining >= 1.0){
|
||||
double sysclks = dMin(cyclesRemaining, EMU_SYSCLK_PRECISION);
|
||||
@@ -260,12 +260,12 @@ void flx68000Execute(void){
|
||||
|
||||
if(cpuCycles > 0)
|
||||
m68k_execute(cpuCycles);
|
||||
addSysclks(sysclks);
|
||||
dbvzAddSysclks(sysclks);
|
||||
|
||||
cyclesRemaining -= sysclks;
|
||||
}
|
||||
|
||||
endClk32();
|
||||
dbvzEndClk32();
|
||||
}
|
||||
|
||||
void flx68000SetIrq(uint8_t irqLevel){
|
||||
@@ -297,7 +297,7 @@ uint64_t flx68000ReadArbitraryMemory(uint32_t address, uint8_t size){
|
||||
uint64_t data = UINT64_MAX;//invalid access
|
||||
|
||||
//reading from a hardware register FIFO will corrupt it!
|
||||
if(bankType[START_BANK(address)] != CHIP_NONE){
|
||||
if(dbvzBankType[DBVZ_START_BANK(address)] != DBVZ_CHIP_NONE){
|
||||
uint16_t m68kSr = m68k_get_reg(NULL, M68K_REG_SR);
|
||||
m68k_set_reg(M68K_REG_SR, 0x2000);//prevent privilege violations
|
||||
switch(size){
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
#ifndef HARDWARE_REGISTERS_H
|
||||
#define HARDWARE_REGISTERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
//interrupt names
|
||||
#define INT_EMIQ 0x00800000//level 7
|
||||
#define INT_RTI 0x00400000//level 4
|
||||
#define INT_SPI1 0x00200000//level 1<->6, configurable, datasheet is contraditory on this one
|
||||
#define INT_IRQ5 0x00100000//level 5
|
||||
#define INT_IRQ6 0x00080000//level 6
|
||||
#define INT_IRQ3 0x00040000//level 3
|
||||
#define INT_IRQ2 0x00020000//level 2
|
||||
#define INT_IRQ1 0x00010000//level 1
|
||||
#define INT_PWM2 0x00002000//level 1<->6, configurable
|
||||
#define INT_UART2 0x00001000//level 1<->6, configurable
|
||||
#define INT_INT3 0x00000800//level 4
|
||||
#define INT_INT2 0x00000400//level 4
|
||||
#define INT_INT1 0x00000200//level 4
|
||||
#define INT_INT0 0x00000100//level 4
|
||||
#define INT_PWM1 0x00000080//level 6
|
||||
#define INT_KB 0x00000040//level 4
|
||||
#define INT_TMR2 0x00000020//level 1<->6, configurable
|
||||
#define INT_RTC 0x00000010//level 4
|
||||
#define INT_WDT 0x00000008//level 4
|
||||
#define INT_UART1 0x00000004//level 4
|
||||
#define INT_TMR1 0x00000002//level 6
|
||||
#define INT_SPI2 0x00000001//level 4
|
||||
|
||||
//reasons a timer is triggered
|
||||
#define TIMER_REASON_SYSCLK 0x00
|
||||
#define TIMER_REASON_TIN 0x01
|
||||
#define TIMER_REASON_CLK32 0x02
|
||||
|
||||
//chip names
|
||||
enum{
|
||||
CHIP_BEGIN = 0,
|
||||
CHIP_A0_ROM = 0,
|
||||
CHIP_A1_USB,
|
||||
CHIP_B0_SED,
|
||||
CHIP_B1_NIL,
|
||||
//CHIP_CX_RAM, //CSC* is owned by CSD during normal operation
|
||||
CHIP_DX_RAM,
|
||||
CHIP_00_EMU, //used for EMUCS on hardware, used by the emu registers here
|
||||
CHIP_REGISTERS,
|
||||
CHIP_NONE,
|
||||
CHIP_END
|
||||
};
|
||||
|
||||
//types
|
||||
typedef struct{
|
||||
bool enable;
|
||||
uint32_t start;
|
||||
uint32_t lineSize;//the size of a single chip select line, multiply by 2 to get the range size for RAM
|
||||
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;
|
||||
uint32_t unprotectedSize;
|
||||
}chip_t;
|
||||
|
||||
//variables
|
||||
extern chip_t chips[];
|
||||
extern int8_t pllSleepWait;
|
||||
extern int8_t pllWakeWait;
|
||||
extern uint32_t clk32Counter;
|
||||
extern double pctlrCpuClockDivider;
|
||||
extern double timerCycleCounter[];
|
||||
extern uint16_t timerStatusReadAcknowledge[];
|
||||
extern uint8_t portDInterruptLastValue;
|
||||
extern uint16_t spi1RxFifo[];
|
||||
extern uint16_t spi1TxFifo[];
|
||||
extern uint8_t spi1RxReadPosition;
|
||||
extern uint8_t spi1RxWritePosition;
|
||||
extern bool spi1RxOverflowed;
|
||||
extern uint8_t spi1TxReadPosition;
|
||||
extern uint8_t spi1TxWritePosition;
|
||||
extern int32_t pwm1ClocksToNextSample;
|
||||
extern uint8_t pwm1Fifo[];
|
||||
extern uint8_t pwm1ReadPosition;
|
||||
extern uint8_t pwm1WritePosition;
|
||||
|
||||
//timing
|
||||
void beginClk32(void);
|
||||
void endClk32(void);
|
||||
void addSysclks(double value);//only call between begin/endClk32
|
||||
|
||||
//CPU
|
||||
bool pllIsOn(void);
|
||||
bool backlightAmplifierState(void);
|
||||
bool registersAreXXFFMapped(void);
|
||||
bool sed1376ClockConnected(void);
|
||||
void ads7846OverridePenState(bool value);
|
||||
void refreshTouchState(void);//just refreshes the touchscreen
|
||||
void refreshInputState(void);//refreshes touchscreen, buttons and docked status
|
||||
//int32_t interruptAcknowledge(int32_t intLevel);//this is in m68kexternal.h
|
||||
|
||||
//memory errors
|
||||
void setBusErrorTimeOut(uint32_t address, bool isWrite);
|
||||
void setPrivilegeViolation(uint32_t address, bool isWrite);
|
||||
void setWriteProtectViolation(uint32_t address);
|
||||
|
||||
//memory accessors
|
||||
uint8_t getHwRegister8(uint32_t address);
|
||||
uint16_t getHwRegister16(uint32_t address);
|
||||
uint32_t getHwRegister32(uint32_t address);
|
||||
void setHwRegister8(uint32_t address, uint8_t value);
|
||||
void setHwRegister16(uint32_t address, uint16_t value);
|
||||
void setHwRegister32(uint32_t address, uint32_t value);
|
||||
|
||||
//config
|
||||
void resetHwRegisters(void);
|
||||
void setRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds);
|
||||
|
||||
#endif
|
||||
435
src/m515Bus.c
Normal file
435
src/m515Bus.c
Normal file
@@ -0,0 +1,435 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "emulator.h"
|
||||
#include "dbvzRegisters.h"
|
||||
#include "expansionHardware.h"
|
||||
#include "m515Bus.h"
|
||||
#include "portability.h"
|
||||
#include "flx68000.h"
|
||||
#include "sed1376.h"
|
||||
#include "pdiUsbD12.h"
|
||||
#include "debug/sandbox.h"
|
||||
|
||||
|
||||
uint8_t dbvzBankType[DBVZ_TOTAL_MEMORY_BANKS];
|
||||
|
||||
|
||||
//RAM accesses
|
||||
static uint8_t ramRead8(uint32_t address){return BUFFER_READ_8(palmRam, address, chips[DBVZ_CHIP_DX_RAM].mask);}
|
||||
static uint16_t ramRead16(uint32_t address){return BUFFER_READ_16(palmRam, address, chips[DBVZ_CHIP_DX_RAM].mask);}
|
||||
static uint32_t ramRead32(uint32_t address){return BUFFER_READ_32(palmRam, address, chips[DBVZ_CHIP_DX_RAM].mask);}
|
||||
static void ramWrite8(uint32_t address, uint8_t value){BUFFER_WRITE_8(palmRam, address, chips[DBVZ_CHIP_DX_RAM].mask, value);}
|
||||
static void ramWrite16(uint32_t address, uint16_t value){BUFFER_WRITE_16(palmRam, address, chips[DBVZ_CHIP_DX_RAM].mask, value);}
|
||||
static void ramWrite32(uint32_t address, uint32_t value){BUFFER_WRITE_32(palmRam, address, chips[DBVZ_CHIP_DX_RAM].mask, value);}
|
||||
|
||||
//ROM accesses
|
||||
static uint8_t romRead8(uint32_t address){return BUFFER_READ_8(palmRom, address, chips[DBVZ_CHIP_A0_ROM].mask);}
|
||||
static uint16_t romRead16(uint32_t address){return BUFFER_READ_16(palmRom, address, chips[DBVZ_CHIP_A0_ROM].mask);}
|
||||
static uint32_t romRead32(uint32_t address){return BUFFER_READ_32(palmRom, address, chips[DBVZ_CHIP_A0_ROM].mask);}
|
||||
|
||||
//SED1376 accesses
|
||||
static uint8_t sed1376Read8(uint32_t address){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(sed1376PowerSaveEnabled())
|
||||
return 0x00;
|
||||
#endif
|
||||
if(address & SED1376_MR_BIT)
|
||||
return BUFFER_READ_8_BIG_ENDIAN(sed1376Ram, address, chips[DBVZ_CHIP_B0_SED].mask);
|
||||
else
|
||||
return sed1376GetRegister(address & chips[DBVZ_CHIP_B0_SED].mask);
|
||||
}
|
||||
static uint16_t sed1376Read16(uint32_t address){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(sed1376PowerSaveEnabled())
|
||||
return 0x0000;
|
||||
#endif
|
||||
if(address & SED1376_MR_BIT)
|
||||
return BUFFER_READ_16_BIG_ENDIAN(sed1376Ram, address, chips[DBVZ_CHIP_B0_SED].mask);
|
||||
else
|
||||
return sed1376GetRegister(address & chips[DBVZ_CHIP_B0_SED].mask);
|
||||
}
|
||||
static uint32_t sed1376Read32(uint32_t address){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(sed1376PowerSaveEnabled())
|
||||
return 0x00000000;
|
||||
#endif
|
||||
if(address & SED1376_MR_BIT)
|
||||
return BUFFER_READ_32_BIG_ENDIAN(sed1376Ram, address, chips[DBVZ_CHIP_B0_SED].mask);
|
||||
else
|
||||
return sed1376GetRegister(address & chips[DBVZ_CHIP_B0_SED].mask);
|
||||
}
|
||||
static void sed1376Write8(uint32_t address, uint8_t value){
|
||||
if(address & SED1376_MR_BIT)
|
||||
BUFFER_WRITE_8_BIG_ENDIAN(sed1376Ram, address, chips[DBVZ_CHIP_B0_SED].mask, value);
|
||||
else
|
||||
sed1376SetRegister(address & chips[DBVZ_CHIP_B0_SED].mask, value);
|
||||
}
|
||||
static void sed1376Write16(uint32_t address, uint16_t value){
|
||||
if(address & SED1376_MR_BIT)
|
||||
BUFFER_WRITE_16_BIG_ENDIAN(sed1376Ram, address, chips[DBVZ_CHIP_B0_SED].mask, value);
|
||||
else
|
||||
sed1376SetRegister(address & chips[DBVZ_CHIP_B0_SED].mask, value);
|
||||
}
|
||||
static void sed1376Write32(uint32_t address, uint32_t value){
|
||||
if(address & SED1376_MR_BIT)
|
||||
BUFFER_WRITE_32_BIG_ENDIAN(sed1376Ram, address, chips[DBVZ_CHIP_B0_SED].mask, value);
|
||||
else
|
||||
sed1376SetRegister(address & chips[DBVZ_CHIP_B0_SED].mask, value);
|
||||
}
|
||||
|
||||
static bool probeRead(uint8_t bank, uint32_t address){
|
||||
if(chips[bank].supervisorOnlyProtectedMemory){
|
||||
uint32_t index = address - chips[bank].start;
|
||||
if(index >= chips[bank].unprotectedSize && !flx68000IsSupervisor()){
|
||||
dbvzSetPrivilegeViolation(address, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool probeWrite(uint8_t bank, uint32_t address){
|
||||
if(chips[bank].readOnly){
|
||||
dbvzSetWriteProtectViolation(address);
|
||||
return false;
|
||||
}
|
||||
else if(chips[bank].supervisorOnlyProtectedMemory || chips[bank].readOnlyForProtectedMemory){
|
||||
uint32_t index = address - chips[bank].start;
|
||||
if(index >= chips[bank].unprotectedSize){
|
||||
if(chips[bank].supervisorOnlyProtectedMemory && !flx68000IsSupervisor()){
|
||||
dbvzSetPrivilegeViolation(address, true);
|
||||
return false;
|
||||
}
|
||||
if(chips[bank].readOnlyForProtectedMemory){
|
||||
dbvzSetWriteProtectViolation(address);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t m68k_read_memory_8(uint32_t address){
|
||||
uint8_t addressType = dbvzBankType[DBVZ_START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeRead(addressType, address))
|
||||
return 0x00;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 8, false, 0);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case DBVZ_CHIP_A0_ROM:
|
||||
return romRead8(address);
|
||||
|
||||
case DBVZ_CHIP_A1_USB:
|
||||
return pdiUsbD12GetRegister(!!(address & chips[DBVZ_CHIP_A1_USB].mask));
|
||||
|
||||
case DBVZ_CHIP_B0_SED:
|
||||
return sed1376Read8(address);
|
||||
|
||||
case DBVZ_CHIP_DX_RAM:
|
||||
return ramRead8(address);
|
||||
|
||||
case DBVZ_CHIP_00_EMU:
|
||||
return 0x00;
|
||||
|
||||
case DBVZ_CHIP_REGISTERS:
|
||||
return dbvzGetRegister8(address);
|
||||
|
||||
case DBVZ_CHIP_B1_NIL:
|
||||
case DBVZ_CHIP_NONE:
|
||||
dbvzSetBusErrorTimeOut(address, false);
|
||||
return 0x00;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", dbvzBankType[DBVZ_START_BANK(address)]);
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t m68k_read_memory_16(uint32_t address){
|
||||
uint8_t addressType = dbvzBankType[DBVZ_START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeRead(addressType, address))
|
||||
return 0x0000;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 16, false, 0);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case DBVZ_CHIP_A0_ROM:
|
||||
return romRead16(address);
|
||||
|
||||
case DBVZ_CHIP_A1_USB:
|
||||
return pdiUsbD12GetRegister(!!(address & chips[DBVZ_CHIP_A1_USB].mask));
|
||||
|
||||
case DBVZ_CHIP_B0_SED:
|
||||
return sed1376Read16(address);
|
||||
|
||||
case DBVZ_CHIP_DX_RAM:
|
||||
return ramRead16(address);
|
||||
|
||||
case DBVZ_CHIP_00_EMU:
|
||||
return 0x0000;
|
||||
|
||||
case DBVZ_CHIP_REGISTERS:
|
||||
return dbvzGetRegister16(address);
|
||||
|
||||
case DBVZ_CHIP_B1_NIL:
|
||||
case DBVZ_CHIP_NONE:
|
||||
dbvzSetBusErrorTimeOut(address, false);
|
||||
return 0x0000;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", dbvzBankType[DBVZ_START_BANK(address)]);
|
||||
return 0x0000;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t m68k_read_memory_32(uint32_t address){
|
||||
uint8_t addressType = dbvzBankType[DBVZ_START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeRead(addressType, address))
|
||||
return 0x00000000;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 32, false, 0);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case DBVZ_CHIP_A0_ROM:
|
||||
return romRead32(address);
|
||||
|
||||
case DBVZ_CHIP_A1_USB:
|
||||
return pdiUsbD12GetRegister(!!(address & chips[DBVZ_CHIP_A1_USB].mask));
|
||||
|
||||
case DBVZ_CHIP_B0_SED:
|
||||
return sed1376Read32(address);
|
||||
|
||||
case DBVZ_CHIP_DX_RAM:
|
||||
return ramRead32(address);
|
||||
|
||||
case DBVZ_CHIP_00_EMU:
|
||||
return expansionHardwareGetRegister(address);
|
||||
|
||||
case DBVZ_CHIP_REGISTERS:
|
||||
return dbvzGetRegister32(address);
|
||||
|
||||
case DBVZ_CHIP_B1_NIL:
|
||||
case DBVZ_CHIP_NONE:
|
||||
dbvzSetBusErrorTimeOut(address, false);
|
||||
return 0x00000000;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", dbvzBankType[DBVZ_START_BANK(address)]);
|
||||
return 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
void m68k_write_memory_8(uint32_t address, uint8_t value){
|
||||
uint8_t addressType = dbvzBankType[DBVZ_START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeWrite(addressType, address))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 8, true, value);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case DBVZ_CHIP_A0_ROM:
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_A1_USB:
|
||||
pdiUsbD12SetRegister(!!(address & chips[DBVZ_CHIP_A1_USB].mask), value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_B0_SED:
|
||||
sed1376Write8(address, value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_DX_RAM:
|
||||
ramWrite8(address, value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_00_EMU:
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_REGISTERS:
|
||||
dbvzSetRegister8(address, value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_B1_NIL:
|
||||
case DBVZ_CHIP_NONE:
|
||||
dbvzSetBusErrorTimeOut(address, true);
|
||||
return;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", dbvzBankType[DBVZ_START_BANK(address)]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void m68k_write_memory_16(uint32_t address, uint16_t value){
|
||||
uint8_t addressType = dbvzBankType[DBVZ_START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeWrite(addressType, address))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 16, true, value);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case DBVZ_CHIP_A0_ROM:
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_A1_USB:
|
||||
pdiUsbD12SetRegister(!!(address & chips[DBVZ_CHIP_A1_USB].mask), value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_B0_SED:
|
||||
sed1376Write16(address, value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_DX_RAM:
|
||||
ramWrite16(address, value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_00_EMU:
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_REGISTERS:
|
||||
dbvzSetRegister16(address, value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_B1_NIL:
|
||||
case DBVZ_CHIP_NONE:
|
||||
dbvzSetBusErrorTimeOut(address, true);
|
||||
return;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", dbvzBankType[DBVZ_START_BANK(address)]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void m68k_write_memory_32(uint32_t address, uint32_t value){
|
||||
uint8_t addressType = dbvzBankType[DBVZ_START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeWrite(addressType, address))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 32, true, value);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case DBVZ_CHIP_A0_ROM:
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_A1_USB:
|
||||
pdiUsbD12SetRegister(!!(address & chips[DBVZ_CHIP_A1_USB].mask), value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_B0_SED:
|
||||
sed1376Write32(address, value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_DX_RAM:
|
||||
ramWrite32(address, value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_00_EMU:
|
||||
expansionHardwareSetRegister(address, value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_REGISTERS:
|
||||
dbvzSetRegister32(address, value);
|
||||
return;
|
||||
|
||||
case DBVZ_CHIP_B1_NIL:
|
||||
case DBVZ_CHIP_NONE:
|
||||
dbvzSetBusErrorTimeOut(address, true);
|
||||
return;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", dbvzBankType[DBVZ_START_BANK(address)]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void m68k_write_memory_32_pd(uint32_t address, uint32_t value){
|
||||
m68k_write_memory_32(address, value >> 16 | value << 16);
|
||||
}
|
||||
|
||||
//memory access for the disassembler, unused but must be defined
|
||||
uint8_t m68k_read_disassembler_8(uint32_t address){return m68k_read_memory_8(address);}
|
||||
uint16_t m68k_read_disassembler_16(uint32_t address){return m68k_read_memory_16(address);}
|
||||
uint32_t m68k_read_disassembler_32(uint32_t address){return m68k_read_memory_32(address);}
|
||||
|
||||
|
||||
static uint8_t getProperBankType(uint32_t bank){
|
||||
//registers have first priority, they cover 0xFFFFF000(and 0xXXFFF000 when DMAP enabled in SCR) even if a chip select overlaps this area or DBVZ_CHIP_A0_ROM is in boot mode
|
||||
//EMUCS also cant be covered by normal chip selects
|
||||
if(DBVZ_BANK_IN_RANGE(bank, DBVZ_REG_START_ADDRESS, DBVZ_REG_SIZE) || ((bank & 0x00FF) == 0x00FF && dbvzAreRegistersXXFFMapped()))
|
||||
return DBVZ_CHIP_REGISTERS;
|
||||
else if(palmEmuFeatures.info != FEATURE_ACCURATE && DBVZ_BANK_IN_RANGE(bank, DBVZ_EMUCS_START_ADDRESS, DBVZ_EMUCS_SIZE))
|
||||
return DBVZ_CHIP_00_EMU;
|
||||
else if(chips[DBVZ_CHIP_A0_ROM].inBootMode || (chips[DBVZ_CHIP_A0_ROM].enable && DBVZ_BANK_IN_RANGE(bank, chips[DBVZ_CHIP_A0_ROM].start, chips[DBVZ_CHIP_A0_ROM].lineSize)))
|
||||
return DBVZ_CHIP_A0_ROM;
|
||||
else if(chips[DBVZ_CHIP_DX_RAM].enable && DBVZ_BANK_IN_RANGE(bank, chips[DBVZ_CHIP_DX_RAM].start, chips[DBVZ_CHIP_DX_RAM].lineSize * 2))
|
||||
return DBVZ_CHIP_DX_RAM;
|
||||
else if(chips[DBVZ_CHIP_B0_SED].enable && DBVZ_BANK_IN_RANGE(bank, chips[DBVZ_CHIP_B0_SED].start, chips[DBVZ_CHIP_B0_SED].lineSize) && sed1376ClockConnected())
|
||||
return DBVZ_CHIP_B0_SED;
|
||||
else if(chips[DBVZ_CHIP_A1_USB].enable && DBVZ_BANK_IN_RANGE(bank, chips[DBVZ_CHIP_A1_USB].start, chips[DBVZ_CHIP_A1_USB].lineSize))
|
||||
return DBVZ_CHIP_A1_USB;
|
||||
else if(chips[DBVZ_CHIP_B1_NIL].enable && DBVZ_BANK_IN_RANGE(bank, chips[DBVZ_CHIP_B1_NIL].start, chips[DBVZ_CHIP_B1_NIL].lineSize))
|
||||
return DBVZ_CHIP_B1_NIL;
|
||||
|
||||
return DBVZ_CHIP_NONE;
|
||||
}
|
||||
|
||||
void dbvzSetRegisterXXFFAccessMode(void){
|
||||
uint32_t topByte;
|
||||
|
||||
MULTITHREAD_LOOP(topByte) for(topByte = 0; topByte < 0x100; topByte++)
|
||||
dbvzBankType[DBVZ_START_BANK(topByte << 24 | 0x00FFF000)] = DBVZ_CHIP_REGISTERS;
|
||||
}
|
||||
|
||||
void dbvzSetRegisterFFFFAccessMode(void){
|
||||
uint32_t topByte;
|
||||
|
||||
MULTITHREAD_LOOP(topByte) for(topByte = 0; topByte < 0x100; topByte++){
|
||||
uint32_t bank = DBVZ_START_BANK(topByte << 24 | 0x00FFF000);
|
||||
dbvzBankType[bank] = getProperBankType(bank);
|
||||
}
|
||||
}
|
||||
|
||||
void m515SetSed1376Attached(bool attached){
|
||||
if(chips[DBVZ_CHIP_B0_SED].enable && dbvzBankType[DBVZ_START_BANK(chips[DBVZ_CHIP_B0_SED].start)] != (attached ? DBVZ_CHIP_B0_SED : DBVZ_CHIP_NONE))
|
||||
memset(&dbvzBankType[DBVZ_START_BANK(chips[DBVZ_CHIP_B0_SED].start)], attached ? DBVZ_CHIP_B0_SED : DBVZ_CHIP_NONE, DBVZ_END_BANK(chips[DBVZ_CHIP_B0_SED].start, chips[DBVZ_CHIP_B0_SED].lineSize) - DBVZ_START_BANK(chips[DBVZ_CHIP_B0_SED].start) + 1);
|
||||
}
|
||||
|
||||
void dbvzResetAddressSpace(void){
|
||||
uint32_t bank;
|
||||
|
||||
MULTITHREAD_LOOP(bank) for(bank = 0; bank < DBVZ_TOTAL_MEMORY_BANKS; bank++)
|
||||
dbvzBankType[bank] = getProperBankType(bank);
|
||||
}
|
||||
36
src/m515Bus.h
Normal file
36
src/m515Bus.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef M515_BUS_H
|
||||
#define M515_BUS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//address space
|
||||
//new bank size (0x4000)
|
||||
#define DBVZ_BANK_SCOOT 14
|
||||
#define DBVZ_NUM_BANKS(areaSize) (((areaSize) >> DBVZ_BANK_SCOOT) + ((areaSize) & ((1 << DBVZ_BANK_SCOOT) - 1) ? 1 : 0))
|
||||
#define DBVZ_START_BANK(address) ((address) >> DBVZ_BANK_SCOOT)
|
||||
#define DBVZ_END_BANK(address, size) (DBVZ_START_BANK(address) + DBVZ_NUM_BANKS(size) - 1)
|
||||
#define DBVZ_BANK_IN_RANGE(bank, address, size) ((bank) >= DBVZ_START_BANK(address) && (bank) <= DBVZ_END_BANK(address, size))
|
||||
#define DBVZ_BANK_ADDRESS(bank) ((bank) << DBVZ_BANK_SCOOT)
|
||||
#define DBVZ_TOTAL_MEMORY_BANKS (1 << (32 - DBVZ_BANK_SCOOT))//0x40000 banks for BANK_SCOOT = 14
|
||||
|
||||
//chip addresses and sizes
|
||||
//after boot RAM is at 0x00000000,
|
||||
//ROM is at 0x10000000
|
||||
//and the SED1376 is at 0x1FF80000(+ 0x20000 for framebuffer)
|
||||
#define DBVZ_EMUCS_START_ADDRESS 0xFFFC0000
|
||||
#define DBVZ_REG_START_ADDRESS 0xFFFFF000
|
||||
#define M515_RAM_SIZE (16 * 0x100000)//16mb RAM
|
||||
#define M515_ROM_SIZE (4 * 0x100000)//4mb ROM
|
||||
#define DBVZ_EMUCS_SIZE 0x20000
|
||||
#define DBVZ_REG_SIZE 0x1000//is actually 0xE00 without bootloader
|
||||
#define DBVZ_BOOTLOADER_SIZE 0x200
|
||||
#define SED1376_MR_BIT 0x20000
|
||||
|
||||
extern uint8_t dbvzBankType[];
|
||||
|
||||
void dbvzSetRegisterXXFFAccessMode(void);
|
||||
void dbvzSetRegisterFFFFAccessMode(void);
|
||||
void m515SetSed1376Attached(bool attached);
|
||||
void dbvzResetAddressSpace(void);
|
||||
|
||||
#endif
|
||||
@@ -1,435 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "emulator.h"
|
||||
#include "hardwareRegisters.h"
|
||||
#include "expansionHardware.h"
|
||||
#include "memoryAccess.h"
|
||||
#include "portability.h"
|
||||
#include "flx68000.h"
|
||||
#include "sed1376.h"
|
||||
#include "pdiUsbD12.h"
|
||||
#include "debug/sandbox.h"
|
||||
|
||||
|
||||
uint8_t bankType[TOTAL_MEMORY_BANKS];
|
||||
|
||||
|
||||
//RAM accesses
|
||||
static uint8_t ramRead8(uint32_t address){return BUFFER_READ_8(palmRam, address, chips[CHIP_DX_RAM].mask);}
|
||||
static uint16_t ramRead16(uint32_t address){return BUFFER_READ_16(palmRam, address, chips[CHIP_DX_RAM].mask);}
|
||||
static uint32_t ramRead32(uint32_t address){return BUFFER_READ_32(palmRam, address, chips[CHIP_DX_RAM].mask);}
|
||||
static void ramWrite8(uint32_t address, uint8_t value){BUFFER_WRITE_8(palmRam, address, chips[CHIP_DX_RAM].mask, value);}
|
||||
static void ramWrite16(uint32_t address, uint16_t value){BUFFER_WRITE_16(palmRam, address, chips[CHIP_DX_RAM].mask, value);}
|
||||
static void ramWrite32(uint32_t address, uint32_t value){BUFFER_WRITE_32(palmRam, address, chips[CHIP_DX_RAM].mask, value);}
|
||||
|
||||
//ROM accesses
|
||||
static uint8_t romRead8(uint32_t address){return BUFFER_READ_8(palmRom, address, chips[CHIP_A0_ROM].mask);}
|
||||
static uint16_t romRead16(uint32_t address){return BUFFER_READ_16(palmRom, address, chips[CHIP_A0_ROM].mask);}
|
||||
static uint32_t romRead32(uint32_t address){return BUFFER_READ_32(palmRom, address, chips[CHIP_A0_ROM].mask);}
|
||||
|
||||
//SED1376 accesses
|
||||
static uint8_t sed1376Read8(uint32_t address){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(sed1376PowerSaveEnabled())
|
||||
return 0x00;
|
||||
#endif
|
||||
if(address & SED1376_MR_BIT)
|
||||
return BUFFER_READ_8_BIG_ENDIAN(sed1376Ram, address, chips[CHIP_B0_SED].mask);
|
||||
else
|
||||
return sed1376GetRegister(address & chips[CHIP_B0_SED].mask);
|
||||
}
|
||||
static uint16_t sed1376Read16(uint32_t address){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(sed1376PowerSaveEnabled())
|
||||
return 0x0000;
|
||||
#endif
|
||||
if(address & SED1376_MR_BIT)
|
||||
return BUFFER_READ_16_BIG_ENDIAN(sed1376Ram, address, chips[CHIP_B0_SED].mask);
|
||||
else
|
||||
return sed1376GetRegister(address & chips[CHIP_B0_SED].mask);
|
||||
}
|
||||
static uint32_t sed1376Read32(uint32_t address){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(sed1376PowerSaveEnabled())
|
||||
return 0x00000000;
|
||||
#endif
|
||||
if(address & SED1376_MR_BIT)
|
||||
return BUFFER_READ_32_BIG_ENDIAN(sed1376Ram, address, chips[CHIP_B0_SED].mask);
|
||||
else
|
||||
return sed1376GetRegister(address & chips[CHIP_B0_SED].mask);
|
||||
}
|
||||
static void sed1376Write8(uint32_t address, uint8_t value){
|
||||
if(address & SED1376_MR_BIT)
|
||||
BUFFER_WRITE_8_BIG_ENDIAN(sed1376Ram, address, chips[CHIP_B0_SED].mask, value);
|
||||
else
|
||||
sed1376SetRegister(address & chips[CHIP_B0_SED].mask, value);
|
||||
}
|
||||
static void sed1376Write16(uint32_t address, uint16_t value){
|
||||
if(address & SED1376_MR_BIT)
|
||||
BUFFER_WRITE_16_BIG_ENDIAN(sed1376Ram, address, chips[CHIP_B0_SED].mask, value);
|
||||
else
|
||||
sed1376SetRegister(address & chips[CHIP_B0_SED].mask, value);
|
||||
}
|
||||
static void sed1376Write32(uint32_t address, uint32_t value){
|
||||
if(address & SED1376_MR_BIT)
|
||||
BUFFER_WRITE_32_BIG_ENDIAN(sed1376Ram, address, chips[CHIP_B0_SED].mask, value);
|
||||
else
|
||||
sed1376SetRegister(address & chips[CHIP_B0_SED].mask, value);
|
||||
}
|
||||
|
||||
static bool probeRead(uint8_t bank, uint32_t address){
|
||||
if(chips[bank].supervisorOnlyProtectedMemory){
|
||||
uint32_t index = address - chips[bank].start;
|
||||
if(index >= chips[bank].unprotectedSize && !flx68000IsSupervisor()){
|
||||
setPrivilegeViolation(address, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool probeWrite(uint8_t bank, uint32_t address){
|
||||
if(chips[bank].readOnly){
|
||||
setWriteProtectViolation(address);
|
||||
return false;
|
||||
}
|
||||
else if(chips[bank].supervisorOnlyProtectedMemory || chips[bank].readOnlyForProtectedMemory){
|
||||
uint32_t index = address - chips[bank].start;
|
||||
if(index >= chips[bank].unprotectedSize){
|
||||
if(chips[bank].supervisorOnlyProtectedMemory && !flx68000IsSupervisor()){
|
||||
setPrivilegeViolation(address, true);
|
||||
return false;
|
||||
}
|
||||
if(chips[bank].readOnlyForProtectedMemory){
|
||||
setWriteProtectViolation(address);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t m68k_read_memory_8(uint32_t address){
|
||||
uint8_t addressType = bankType[START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeRead(addressType, address))
|
||||
return 0x00;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 8, false, 0);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case CHIP_A0_ROM:
|
||||
return romRead8(address);
|
||||
|
||||
case CHIP_A1_USB:
|
||||
return pdiUsbD12GetRegister(!!(address & chips[CHIP_A1_USB].mask));
|
||||
|
||||
case CHIP_B0_SED:
|
||||
return sed1376Read8(address);
|
||||
|
||||
case CHIP_DX_RAM:
|
||||
return ramRead8(address);
|
||||
|
||||
case CHIP_00_EMU:
|
||||
return 0x00;
|
||||
|
||||
case CHIP_REGISTERS:
|
||||
return getHwRegister8(address);
|
||||
|
||||
case CHIP_B1_NIL:
|
||||
case CHIP_NONE:
|
||||
setBusErrorTimeOut(address, false);
|
||||
return 0x00;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", bankType[START_BANK(address)]);
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t m68k_read_memory_16(uint32_t address){
|
||||
uint8_t addressType = bankType[START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeRead(addressType, address))
|
||||
return 0x0000;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 16, false, 0);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case CHIP_A0_ROM:
|
||||
return romRead16(address);
|
||||
|
||||
case CHIP_A1_USB:
|
||||
return pdiUsbD12GetRegister(!!(address & chips[CHIP_A1_USB].mask));
|
||||
|
||||
case CHIP_B0_SED:
|
||||
return sed1376Read16(address);
|
||||
|
||||
case CHIP_DX_RAM:
|
||||
return ramRead16(address);
|
||||
|
||||
case CHIP_00_EMU:
|
||||
return 0x0000;
|
||||
|
||||
case CHIP_REGISTERS:
|
||||
return getHwRegister16(address);
|
||||
|
||||
case CHIP_B1_NIL:
|
||||
case CHIP_NONE:
|
||||
setBusErrorTimeOut(address, false);
|
||||
return 0x0000;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", bankType[START_BANK(address)]);
|
||||
return 0x0000;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t m68k_read_memory_32(uint32_t address){
|
||||
uint8_t addressType = bankType[START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeRead(addressType, address))
|
||||
return 0x00000000;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 32, false, 0);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case CHIP_A0_ROM:
|
||||
return romRead32(address);
|
||||
|
||||
case CHIP_A1_USB:
|
||||
return pdiUsbD12GetRegister(!!(address & chips[CHIP_A1_USB].mask));
|
||||
|
||||
case CHIP_B0_SED:
|
||||
return sed1376Read32(address);
|
||||
|
||||
case CHIP_DX_RAM:
|
||||
return ramRead32(address);
|
||||
|
||||
case CHIP_00_EMU:
|
||||
return expansionHardwareGetRegister(address);
|
||||
|
||||
case CHIP_REGISTERS:
|
||||
return getHwRegister32(address);
|
||||
|
||||
case CHIP_B1_NIL:
|
||||
case CHIP_NONE:
|
||||
setBusErrorTimeOut(address, false);
|
||||
return 0x00000000;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", bankType[START_BANK(address)]);
|
||||
return 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
void m68k_write_memory_8(uint32_t address, uint8_t value){
|
||||
uint8_t addressType = bankType[START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeWrite(addressType, address))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 8, true, value);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case CHIP_A0_ROM:
|
||||
return;
|
||||
|
||||
case CHIP_A1_USB:
|
||||
pdiUsbD12SetRegister(!!(address & chips[CHIP_A1_USB].mask), value);
|
||||
return;
|
||||
|
||||
case CHIP_B0_SED:
|
||||
sed1376Write8(address, value);
|
||||
return;
|
||||
|
||||
case CHIP_DX_RAM:
|
||||
ramWrite8(address, value);
|
||||
return;
|
||||
|
||||
case CHIP_00_EMU:
|
||||
return;
|
||||
|
||||
case CHIP_REGISTERS:
|
||||
setHwRegister8(address, value);
|
||||
return;
|
||||
|
||||
case CHIP_B1_NIL:
|
||||
case CHIP_NONE:
|
||||
setBusErrorTimeOut(address, true);
|
||||
return;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", bankType[START_BANK(address)]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void m68k_write_memory_16(uint32_t address, uint16_t value){
|
||||
uint8_t addressType = bankType[START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeWrite(addressType, address))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 16, true, value);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case CHIP_A0_ROM:
|
||||
return;
|
||||
|
||||
case CHIP_A1_USB:
|
||||
pdiUsbD12SetRegister(!!(address & chips[CHIP_A1_USB].mask), value);
|
||||
return;
|
||||
|
||||
case CHIP_B0_SED:
|
||||
sed1376Write16(address, value);
|
||||
return;
|
||||
|
||||
case CHIP_DX_RAM:
|
||||
ramWrite16(address, value);
|
||||
return;
|
||||
|
||||
case CHIP_00_EMU:
|
||||
return;
|
||||
|
||||
case CHIP_REGISTERS:
|
||||
setHwRegister16(address, value);
|
||||
return;
|
||||
|
||||
case CHIP_B1_NIL:
|
||||
case CHIP_NONE:
|
||||
setBusErrorTimeOut(address, true);
|
||||
return;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", bankType[START_BANK(address)]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void m68k_write_memory_32(uint32_t address, uint32_t value){
|
||||
uint8_t addressType = bankType[START_BANK(address)];
|
||||
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!probeWrite(addressType, address))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX) && defined(EMU_SANDBOX_LOG_MEMORY_ACCESSES)
|
||||
sandboxOnMemoryAccess(address, 32, true, value);
|
||||
#endif
|
||||
|
||||
switch(addressType){
|
||||
case CHIP_A0_ROM:
|
||||
return;
|
||||
|
||||
case CHIP_A1_USB:
|
||||
pdiUsbD12SetRegister(!!(address & chips[CHIP_A1_USB].mask), value);
|
||||
return;
|
||||
|
||||
case CHIP_B0_SED:
|
||||
sed1376Write32(address, value);
|
||||
return;
|
||||
|
||||
case CHIP_DX_RAM:
|
||||
ramWrite32(address, value);
|
||||
return;
|
||||
|
||||
case CHIP_00_EMU:
|
||||
expansionHardwareSetRegister(address, value);
|
||||
return;
|
||||
|
||||
case CHIP_REGISTERS:
|
||||
setHwRegister32(address, value);
|
||||
return;
|
||||
|
||||
case CHIP_B1_NIL:
|
||||
case CHIP_NONE:
|
||||
setBusErrorTimeOut(address, true);
|
||||
return;
|
||||
|
||||
default:
|
||||
debugLog("Unknown bank type:%d\n", bankType[START_BANK(address)]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void m68k_write_memory_32_pd(uint32_t address, uint32_t value){
|
||||
m68k_write_memory_32(address, value >> 16 | value << 16);
|
||||
}
|
||||
|
||||
//memory access for the disassembler, unused but must be defined
|
||||
uint8_t m68k_read_disassembler_8(uint32_t address){return m68k_read_memory_8(address);}
|
||||
uint16_t m68k_read_disassembler_16(uint32_t address){return m68k_read_memory_16(address);}
|
||||
uint32_t m68k_read_disassembler_32(uint32_t address){return m68k_read_memory_32(address);}
|
||||
|
||||
|
||||
static uint8_t getProperBankType(uint32_t bank){
|
||||
//registers have first priority, they cover 0xFFFFF000(and 0xXXFFF000 when DMAP enabled in SCR) even if a chip select overlaps this area or CHIP_A0_ROM is in boot mode
|
||||
//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(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;
|
||||
else if(chips[CHIP_DX_RAM].enable && BANK_IN_RANGE(bank, chips[CHIP_DX_RAM].start, chips[CHIP_DX_RAM].lineSize * 2))
|
||||
return CHIP_DX_RAM;
|
||||
else if(chips[CHIP_B0_SED].enable && BANK_IN_RANGE(bank, chips[CHIP_B0_SED].start, chips[CHIP_B0_SED].lineSize) && sed1376ClockConnected())
|
||||
return CHIP_B0_SED;
|
||||
else if(chips[CHIP_A1_USB].enable && BANK_IN_RANGE(bank, chips[CHIP_A1_USB].start, chips[CHIP_A1_USB].lineSize))
|
||||
return CHIP_A1_USB;
|
||||
else if(chips[CHIP_B1_NIL].enable && BANK_IN_RANGE(bank, chips[CHIP_B1_NIL].start, chips[CHIP_B1_NIL].lineSize))
|
||||
return CHIP_B1_NIL;
|
||||
|
||||
return CHIP_NONE;
|
||||
}
|
||||
|
||||
void setRegisterXXFFAccessMode(void){
|
||||
uint32_t topByte;
|
||||
|
||||
MULTITHREAD_LOOP(topByte) for(topByte = 0; topByte < 0x100; topByte++)
|
||||
bankType[START_BANK(topByte << 24 | 0x00FFF000)] = CHIP_REGISTERS;
|
||||
}
|
||||
|
||||
void setRegisterFFFFAccessMode(void){
|
||||
uint32_t topByte;
|
||||
|
||||
MULTITHREAD_LOOP(topByte) for(topByte = 0; topByte < 0x100; topByte++){
|
||||
uint32_t bank = START_BANK(topByte << 24 | 0x00FFF000);
|
||||
bankType[bank] = getProperBankType(bank);
|
||||
}
|
||||
}
|
||||
|
||||
void setSed1376Attached(bool attached){
|
||||
if(chips[CHIP_B0_SED].enable && bankType[START_BANK(chips[CHIP_B0_SED].start)] != (attached ? CHIP_B0_SED : CHIP_NONE))
|
||||
memset(&bankType[START_BANK(chips[CHIP_B0_SED].start)], attached ? CHIP_B0_SED : CHIP_NONE, END_BANK(chips[CHIP_B0_SED].start, chips[CHIP_B0_SED].lineSize) - START_BANK(chips[CHIP_B0_SED].start) + 1);
|
||||
}
|
||||
|
||||
void resetAddressSpace(void){
|
||||
uint32_t bank;
|
||||
|
||||
MULTITHREAD_LOOP(bank) for(bank = 0; bank < TOTAL_MEMORY_BANKS; bank++)
|
||||
bankType[bank] = getProperBankType(bank);
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
#ifndef MEMORY_ACCESS_H
|
||||
#define MEMORY_ACCESS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//address space
|
||||
//new bank size (0x4000)
|
||||
#define BANK_SCOOT 14
|
||||
#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))
|
||||
#define BANK_ADDRESS(bank) ((bank) << BANK_SCOOT)
|
||||
#define TOTAL_MEMORY_BANKS (1 << (32 - BANK_SCOOT))//0x40000 banks for BANK_SCOOT = 14
|
||||
|
||||
//chip addresses and sizes
|
||||
//after boot RAM is at 0x00000000,
|
||||
//ROM is at 0x10000000
|
||||
//and the SED1376 is at 0x1FF80000(+ 0x20000 for framebuffer)
|
||||
#define EMUCS_START_ADDRESS 0xFFFC0000
|
||||
#define REG_START_ADDRESS 0xFFFFF000
|
||||
#define RAM_SIZE (16 * 0x100000)//16mb RAM
|
||||
#define ROM_SIZE (4 * 0x100000)//4mb ROM
|
||||
#define EMUCS_SIZE 0x20000
|
||||
#define REG_SIZE 0x1000//is actually 0xE00 without bootloader
|
||||
#define BOOTLOADER_SIZE 0x200
|
||||
#define SED1376_MR_BIT 0x20000
|
||||
|
||||
//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, 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))))
|
||||
#define BUFFER_WRITE_8(segment, accessAddress, mask, value) (*(uint8_t*)(segment + ((accessAddress) & (mask))) = (value))
|
||||
#define BUFFER_WRITE_16(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value))
|
||||
#define BUFFER_WRITE_32(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value) >> 16 , *(uint16_t*)(segment + ((accessAddress) + 2 & (mask))) = (value) & 0xFFFF)
|
||||
#define BUFFER_READ_8_BIG_ENDIAN BUFFER_READ_8
|
||||
#define BUFFER_READ_16_BIG_ENDIAN BUFFER_READ_16
|
||||
#define BUFFER_READ_32_BIG_ENDIAN BUFFER_READ_32
|
||||
#define BUFFER_WRITE_8_BIG_ENDIAN BUFFER_WRITE_8
|
||||
#define BUFFER_WRITE_16_BIG_ENDIAN BUFFER_WRITE_16
|
||||
#define BUFFER_WRITE_32_BIG_ENDIAN BUFFER_WRITE_32
|
||||
#else
|
||||
//memory layout is different from the Palm m515, optimize for opcode fetches(16 bit reads)
|
||||
#define BUFFER_READ_8(segment, accessAddress, mask) (*(uint8_t*)(segment + ((accessAddress) & (mask) ^ 1)))
|
||||
#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))))
|
||||
#define BUFFER_WRITE_8(segment, accessAddress, mask, value) (*(uint8_t*)(segment + ((accessAddress) & (mask) ^ 1)) = (value))
|
||||
#define BUFFER_WRITE_16(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value))
|
||||
#define BUFFER_WRITE_32(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value) >> 16 , *(uint16_t*)(segment + ((accessAddress) + 2 & (mask))) = (value) & 0xFFFF)
|
||||
#define BUFFER_READ_8_BIG_ENDIAN(segment, accessAddress, mask) (segment[(accessAddress) & (mask)])
|
||||
#define BUFFER_READ_16_BIG_ENDIAN(segment, accessAddress, mask) (segment[(accessAddress) & (mask)] << 8 | segment[(accessAddress) + 1 & (mask)])
|
||||
#define BUFFER_READ_32_BIG_ENDIAN(segment, accessAddress, mask) (segment[(accessAddress) & (mask)] << 24 | segment[(accessAddress) + 1 & (mask)] << 16 | segment[(accessAddress) + 2 & (mask)] << 8 | segment[(accessAddress) + 3 & (mask)])
|
||||
#define BUFFER_WRITE_8_BIG_ENDIAN(segment, accessAddress, mask, value) (segment[(accessAddress) & (mask)] = (value))
|
||||
#define BUFFER_WRITE_16_BIG_ENDIAN(segment, accessAddress, mask, value) (segment[(accessAddress) & (mask)] = (value) >> 8, segment[(accessAddress) + 1 & (mask)] = (value) & 0xFF)
|
||||
#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(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[];
|
||||
|
||||
void setRegisterXXFFAccessMode(void);
|
||||
void setRegisterFFFFAccessMode(void);
|
||||
void setSed1376Attached(bool attached);
|
||||
void resetAddressSpace(void);
|
||||
|
||||
#endif
|
||||
@@ -4,10 +4,45 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
//endian
|
||||
static inline void swap16BufferIfLittle(uint8_t* buffer, uint32_t count){
|
||||
#if !defined(EMU_BIG_ENDIAN)
|
||||
//endian/buffers
|
||||
//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, 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))))
|
||||
#define BUFFER_WRITE_8(segment, accessAddress, mask, value) (*(uint8_t*)(segment + ((accessAddress) & (mask))) = (value))
|
||||
#define BUFFER_WRITE_16(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value))
|
||||
#define BUFFER_WRITE_32(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value) >> 16 , *(uint16_t*)(segment + ((accessAddress) + 2 & (mask))) = (value) & 0xFFFF)
|
||||
#define BUFFER_READ_8_BIG_ENDIAN BUFFER_READ_8
|
||||
#define BUFFER_READ_16_BIG_ENDIAN BUFFER_READ_16
|
||||
#define BUFFER_READ_32_BIG_ENDIAN BUFFER_READ_32
|
||||
#define BUFFER_WRITE_8_BIG_ENDIAN BUFFER_WRITE_8
|
||||
#define BUFFER_WRITE_16_BIG_ENDIAN BUFFER_WRITE_16
|
||||
#define BUFFER_WRITE_32_BIG_ENDIAN BUFFER_WRITE_32
|
||||
#else
|
||||
//memory layout is different from the Palm m515, optimize for opcode fetches(16 bit reads)
|
||||
#define BUFFER_READ_8(segment, accessAddress, mask) (*(uint8_t*)(segment + ((accessAddress) & (mask) ^ 1)))
|
||||
#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))))
|
||||
#define BUFFER_WRITE_8(segment, accessAddress, mask, value) (*(uint8_t*)(segment + ((accessAddress) & (mask) ^ 1)) = (value))
|
||||
#define BUFFER_WRITE_16(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value))
|
||||
#define BUFFER_WRITE_32(segment, accessAddress, mask, value) (*(uint16_t*)(segment + ((accessAddress) & (mask))) = (value) >> 16 , *(uint16_t*)(segment + ((accessAddress) + 2 & (mask))) = (value) & 0xFFFF)
|
||||
#define BUFFER_READ_8_BIG_ENDIAN(segment, accessAddress, mask) (segment[(accessAddress) & (mask)])
|
||||
#define BUFFER_READ_16_BIG_ENDIAN(segment, accessAddress, mask) (segment[(accessAddress) & (mask)] << 8 | segment[(accessAddress) + 1 & (mask)])
|
||||
#define BUFFER_READ_32_BIG_ENDIAN(segment, accessAddress, mask) (segment[(accessAddress) & (mask)] << 24 | segment[(accessAddress) + 1 & (mask)] << 16 | segment[(accessAddress) + 2 & (mask)] << 8 | segment[(accessAddress) + 3 & (mask)])
|
||||
#define BUFFER_WRITE_8_BIG_ENDIAN(segment, accessAddress, mask, value) (segment[(accessAddress) & (mask)] = (value))
|
||||
#define BUFFER_WRITE_16_BIG_ENDIAN(segment, accessAddress, mask, value) (segment[(accessAddress) & (mask)] = (value) >> 8, segment[(accessAddress) + 1 & (mask)] = (value) & 0xFF)
|
||||
#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(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))
|
||||
|
||||
static inline void swap16(uint8_t* buffer, uint32_t count){
|
||||
uint32_t index;
|
||||
|
||||
//count specifys the number of uint16_t's that need to be swapped, the uint8_t* is because of alignment restrictions that crash on some platforms
|
||||
count *= sizeof(uint16_t);
|
||||
for(index = 0; index < count; index += 2){
|
||||
@@ -15,6 +50,17 @@ static inline void swap16BufferIfLittle(uint8_t* buffer, uint32_t count){
|
||||
buffer[index] = buffer[index + 1];
|
||||
buffer[index + 1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void swap16BufferIfLittle(uint8_t* buffer, uint32_t count){
|
||||
#if !defined(EMU_BIG_ENDIAN)
|
||||
swap16(buffer, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void swap16BufferIfBig(uint8_t* buffer, uint32_t count){
|
||||
#if defined(EMU_BIG_ENDIAN)
|
||||
swap16(buffer, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "emulator.h"
|
||||
#include "portability.h"
|
||||
#include "hardwareRegisters.h"
|
||||
#include "dbvzRegisters.h"
|
||||
#include "flx68000.h"//for flx68000GetPc()
|
||||
#include "specs/sed1376RegisterSpec.h"
|
||||
|
||||
@@ -352,7 +352,7 @@ void sed1376SetRegister(uint8_t address, uint8_t value){
|
||||
|
||||
void sed1376Render(void){
|
||||
//render if LCD on, PLL on, power save off and force blank off, SED1376 clock is provided by the CPU, if its off so is the SED
|
||||
if(palmMisc.lcdOn && pllIsOn() && !sed1376PowerSaveEnabled() && !(sed1376Registers[DISP_MODE] & 0x80)){
|
||||
if(palmMisc.lcdOn && dbvzIsPllOn() && !sed1376PowerSaveEnabled() && !(sed1376Registers[DISP_MODE] & 0x80)){
|
||||
bool color = !!(sed1376Registers[PANEL_TYPE] & 0x40);
|
||||
bool pictureInPictureEnabled = !!(sed1376Registers[SPECIAL_EFFECT] & 0x10);
|
||||
uint8_t bitDepth = 1 << (sed1376Registers[DISP_MODE] & 0x07);
|
||||
@@ -436,6 +436,6 @@ void sed1376Render(void){
|
||||
else{
|
||||
//black screen
|
||||
memset(sed1376Framebuffer, 0x00, 160 * 160 * sizeof(uint16_t));
|
||||
debugLog("Cant draw screen, LCD on:%s, PLL on:%s, power save on:%s, forced blank on:%s\n", palmMisc.lcdOn ? "true" : "false", pllIsOn() ? "true" : "false", sed1376PowerSaveEnabled() ? "true" : "false", !!(sed1376Registers[DISP_MODE] & 0x80) ? "true" : "false");
|
||||
debugLog("Cant draw screen, LCD on:%s, PLL on:%s, power save on:%s, forced blank on:%s\n", palmMisc.lcdOn ? "true" : "false", dbvzIsPllOn() ? "true" : "false", sed1376PowerSaveEnabled() ? "true" : "false", !!(sed1376Registers[DISP_MODE] & 0x80) ? "true" : "false");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,5 +117,5 @@ static void selectRenderer(bool color, uint8_t bpp){
|
||||
//updaters
|
||||
static void updateLcdStatus(void){
|
||||
palmMisc.lcdOn = !!(sed1376Registers[GPIO_CONT_0] & sed1376Registers[GPIO_CONF_0] & 0x20);
|
||||
palmMisc.backlightLevel = !!(sed1376Registers[GPIO_CONT_0] & sed1376Registers[GPIO_CONF_0] & 0x10) ? (1 + backlightAmplifierState()) : 0;
|
||||
palmMisc.backlightLevel = !!(sed1376Registers[GPIO_CONT_0] & sed1376Registers[GPIO_CONF_0] & 0x10) ? (1 + m515BacklightAmplifierState()) : 0;
|
||||
}
|
||||
|
||||
3843
src/silkscreen.c
3843
src/silkscreen.c
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
extern const uint16_t silkscreen160x60[];
|
||||
extern const uint16_t silkscreen320x120[];
|
||||
|
||||
#endif
|
||||
|
||||
@@ -47,7 +47,7 @@ These registers will do nothing if their corresponding feature bit is not set on
|
||||
#define CMD_SET_CPU_SPEED 0x0000FFF3/*EMU_VALUE = CPU speed percent, 100% = normal*/
|
||||
#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_LCD_SET_FB 0x0000FFF6/*EMU_SRC = framebuffer pointer(must be in RAM and word aligned, unused if size is 160x220), EMU_VALUE >> 16 = width, EMU_VALUE & 0xFFFF = height*/
|
||||
/*CMD_UNUSED 0x0000FFF6*/
|
||||
/*CMD_UNUSED 0x0000FFF7*/
|
||||
#define CMD_DEBUG_PRINT 0x0000FFF8/*EMU_SRC = pointer to string*/
|
||||
#define CMD_DEBUG_WATCH 0x0000FFF9/*EMU_VALUE = 0/clear watch reference or 1/make code watch reference or 2/make data watch reference, EMU_SRC = address of area(or watch area reference number), EMU_SIZE = size of area(unused if clear operation), EMU_VALUE is set to the watch areas reference number after a set operation*/
|
||||
|
||||
Reference in New Issue
Block a user