Start tunring m515 and dragonball stuff into modules

Prepareing for tungsten c support.
This commit is contained in:
meepingsnesroms
2019-04-19 09:35:14 -07:00
parent 47ba41fdc5
commit f7c1dacba4
22 changed files with 926 additions and 4759 deletions

View File

@@ -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 \

View File

@@ -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
}

View File

@@ -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);
}
}

View File

@@ -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
View 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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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!!!

View File

@@ -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"

View File

@@ -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){

View File

@@ -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
View 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
View 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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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");
}
}

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,5 @@
#include <stdint.h>
extern const uint16_t silkscreen160x60[];
extern const uint16_t silkscreen320x120[];
#endif

View File

@@ -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*/