Increase ADS7846 accuracy, implement PLLFSR 8 bit reads, enable logging on all unemulated regiser accesses

This commit is contained in:
meepingsnesroms
2019-01-17 13:45:11 -08:00
parent 4f96b53bb1
commit 8a990b2839
9 changed files with 1239 additions and 1182 deletions

View File

@@ -26,6 +26,7 @@ UART1 USTCNT1
PLLFSR has a hack that makes busy wait loops finish faster by toggling the CLK32 bit on read, for power button issue
should also not transfer data to SD card when MOSI, MISO or SPICLK1 are disabled
port d data register INT* bits seem to have there data bits cleared when an edge triggered interrupt is cleared(according to MC68VZ328UM.pdf Page 10-15)
sound plays too long when the category's menu is selected on the home screen and the pen is pressed and held in the middle of the screen(only happens there, other views of the same type don't have this issue)
Memory:
SD card can't be read or written to by Palm OS

View File

@@ -31,7 +31,7 @@ windows{
}
macx{
# QMAKE_CFLAGS += -std=c89 -D__STDBOOL_H -Dinline= -Dbool=char -Dtrue=1 -Dfalse=0 # tests C89 mode
QMAKE_CFLAGS += -std=c89 -D__STDBOOL_H -Dinline= -Dbool=char -Dtrue=1 -Dfalse=0 # tests C89 mode
ICON = macos/Mu.icns
QMAKE_INFO_PLIST = macos/Info.plist
DEFINES += EMU_MULTITHREADED

View File

@@ -3,6 +3,7 @@
#include "emulator.h"
#include "portability.h"
#include "hardwareRegisters.h"
bool ads7846PenIrqEnabled;
@@ -30,7 +31,10 @@ void ads7846Reset(void){
ads7846ControlByte = 0x00;
ads7846PenIrqEnabled = true;
ads7846OutputValue = 0x0000;
ads7846ChipSelect = false;
ads7846ChipSelect = true;
#if !defined(EMU_NO_SAFETY)
refreshTouchState();
#endif
}
uint64_t ads7846StateSize(void){
@@ -79,7 +83,11 @@ void ads7846SetChipSelect(bool value){
ads7846ControlByte = 0x00;
ads7846PenIrqEnabled = true;
ads7846OutputValue = 0x0000;
#if !defined(EMU_NO_SAFETY)
refreshTouchState();
#endif
}
ads7846ChipSelect = value;
}
bool ads7846ExchangeBit(bool bitIn){
@@ -107,17 +115,22 @@ bool ads7846ExchangeBit(bool bitIn){
else if(ads7846BitsToNextControl == 6){
//control byte and busy cycle finished, get output value
bool bitMode = !!(ads7846ControlByte & 0x08);
//bool differentialMode = !(ads7846ControlByte & 0x04);
bool differentialMode = !(ads7846ControlByte & 0x04);
uint8_t channel = (ads7846ControlByte & 0x70) >> 4;
uint8_t powerSave = ads7846ControlByte & 0x03;
//debugLog("Accessed ADS7846 Ch:%d, %d bits, %s Mode, Power Save:%d, PC:0x%08X.\n", channel, bitMode ? 8 : 12, differentialMode ? "Diff" : "Normal", ads7846ControlByte & 0x03, flx68000GetPc());
//check if ADC is on, PENIRQ is handled in refreshInputState() in hardwareRegisters.c
switch(powerSave){
case 0:
case 1:
//touchscreen data only
//reference disabled currently isnt emulated, I dont know what the proper behavior for that would be
#if !defined(EMU_NO_SAFETY)
//trigger fake IRQs
ads7846OverridePenState(!(channel == 1 || channel == 3 || channel == 4 || channel == 5));
#endif
if(powerSave != 2){
//ADC enabled, get analog value
if(differentialMode){
switch(channel){
case 0:
//temperature 0, wrong mode
@@ -171,18 +184,8 @@ bool ads7846ExchangeBit(bool bitIn){
ads7846OutputValue = 0xDFF;
break;
}
break;
case 2:
//ADC is off, return invalid data
if((channel == 3 || channel == 5) && !palmInput.touchscreenTouched)
ads7846OutputValue = 0x000;
else
ads7846OutputValue = 0xFFF;
break;
case 3:
//all data
}
else{
if(!palmInput.touchscreenTouched){
switch(channel){
case 0:
@@ -249,7 +252,14 @@ bool ads7846ExchangeBit(bool bitIn){
//crosses lines with REF+(unverified)
ads7846OutputValue = 0xF80;
}
break;
}
}
else{
//ADC disabled, return invalid data
if((channel == 3 || channel == 5) && !palmInput.touchscreenTouched)
ads7846OutputValue = 0x000;
else
ads7846OutputValue = 0xFFF;
}
//move to output position
@@ -262,6 +272,9 @@ bool ads7846ExchangeBit(bool bitIn){
}
ads7846PenIrqEnabled = !(powerSave & 0x01);
#if !defined(EMU_NO_SAFETY)
refreshTouchState();
#endif
}
return ads7846GetAdcBit();

View File

@@ -406,7 +406,8 @@ uint32_t sandboxCommand(uint32_t command, void* data){
patchOsRom(0x2C5E, "203C020000004E75");//move.l 0x2000000, d0; rts
patchOsRom(0x8442E, "203C020000004E75");//move.l 0x2000000, d0; rts
//bus error at 0x1001DEDA when 128MB is present
//0x55555555 memory filler, 32 bit, at PC:0x1001FFDC
//0x55 memory filler, 32 bit, at PC:0x1001FFDC, and of course, its MemSet, need a stack trace now
//PrvInitHeapPtr_10021908 sets up the 0x55 stuff in RAM
}
break;

File diff suppressed because it is too large Load Diff

View File

@@ -66,6 +66,29 @@ bool sed1376ClockConnected(void){
return !(registerArrayRead8(PFSEL) & 0x04) && !(registerArrayRead16(PLLCR) & 0x0010);
}
void ads7846OverridePenState(bool value){
//causes a temporary override of the touchscreen value, used to trigger fake interrupts from line noise when reading from the ADS7846
if(value != (ads7846PenIrqEnabled ? !palmInput.touchscreenTouched : true)){
if(!(registerArrayRead8(PFSEL) & registerArrayRead8(PFDIR) & 0x02)){
if(value == !!(registerArrayRead16(ICR) & 0x0080))
setIprIsrBit(INT_IRQ5);
else
clearIprIsrBit(INT_IRQ5);
}
checkInterrupts();
//override over, put back real state
updateTouchState();
checkInterrupts();
}
}
void refreshTouchState(void){
//called when ads7846PenIrqEnabled is changed
updateTouchState();
checkInterrupts();
}
void refreshInputState(void){
//update power button LED state if palmMisc.batteryCharging changed
updatePowerButtonLedStatus();
@@ -408,6 +431,8 @@ uint8_t getHwRegister8(uint32_t address){
case SPICONT1 + 1:
case SPIINTCS:
case SPIINTCS + 1:
case PLLFSR:
case PLLFSR + 1:
//basic non GPIO functions
case SCR:
@@ -660,9 +685,22 @@ void setHwRegister8(uint32_t address, uint8_t value){
return;
case PFSEL:
//this is the clock output pin for the SED1376, if its disabled so is the LCD controller
//this register controls the clock output pin for the SED1376 and IRQ line for PENIRQ
registerArrayWrite8(PFSEL, value);
setSed1376Attached(sed1376ClockConnected());
#if !defined(EMU_NO_SAFETY)
updateTouchState();
checkInterrupts();
#endif
return;
case PFDIR:
//this register controls the IRQ line for PENIRQ
registerArrayWrite8(PFDIR, value);
#if !defined(EMU_NO_SAFETY)
updateTouchState();
checkInterrupts();
#endif
return;
case PGSEL:
@@ -712,7 +750,6 @@ void setHwRegister8(uint32_t address, uint8_t value){
case PCDIR:
case PDDIR:
case PEDIR:
case PFDIR:
//pull up/down enable
case PAPUEN:

View File

@@ -93,8 +93,10 @@ bool pllIsOn(void);
bool backlightAmplifierState(void);
bool registersAreXXFFMapped(void);
bool sed1376ClockConnected(void);
void refreshInputState(void);
int32_t interruptAcknowledge(int32_t intLevel);
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);

View File

@@ -624,7 +624,7 @@ static uint8_t getPortFValue(void){
uint8_t portFData = registerArrayRead8(PFDATA);
uint8_t portFDir = registerArrayRead8(PFDIR);
uint8_t portFSel = registerArrayRead8(PFSEL);
bool penIrqPin = !(ads7846PenIrqEnabled && palmInput.touchscreenTouched);//penIrqPin pulled low on touch
bool penIrqPin = ads7846PenIrqEnabled ? !palmInput.touchscreenTouched : true;//penIrqPin pulled low on touch
portFValue |= penIrqPin << 1;
portFValue |= 0x85;//bit 7 & 2-0 have pull ups, bits 6-3 have pull downs, bit 2 is occupied by PENIRQ
@@ -737,9 +737,8 @@ static void updateBacklightAmplifierStatus(void){
}
static void updateTouchState(void){
//check if interrupt enabled and is input
if(!(registerArrayRead8(PFSEL) & registerArrayRead8(PFDIR) & 0x02)){
if(!(ads7846PenIrqEnabled && palmInput.touchscreenTouched) == !!(registerArrayRead16(ICR) & 0x0080))
if((ads7846PenIrqEnabled ? !palmInput.touchscreenTouched : true) == !!(registerArrayRead16(ICR) & 0x0080))
setIprIsrBit(INT_IRQ5);
else
clearIprIsrBit(INT_IRQ5);

View File

@@ -211,6 +211,7 @@ uint8_t sed1376GetRegister(uint8_t address){
return sed1376Registers[address];
default:
debugLog("SED1376 unknown register read 0x%02X, PC 0x%08X.\n", address, flx68000GetPc());
return 0x00;
}
}
@@ -256,11 +257,13 @@ void sed1376SetRegister(uint8_t address, uint8_t value){
sed1376BLut[value] = sed1376Registers[LUT_B_WRITE];
sed1376GLut[value] = sed1376Registers[LUT_G_WRITE];
sed1376RLut[value] = sed1376Registers[LUT_R_WRITE];
//whether or not these are changed on a write, or if that depends on the LUT_READ_LOC register is yet to be tested, turn this off for now
//whether or not LUT_X_READ are changed on a write when LUT_WRITE_LOC == LUT_READ_LOC is yet to be tested, turn this off for now
/*
sed1376Registers[LUT_B_READ] = sed1376BLut[value];
sed1376Registers[LUT_G_READ] = sed1376GLut[value];
sed1376Registers[LUT_R_READ] = sed1376RLut[value];
if(sed1376Registers[LUT_WRITE_LOC] == sed1376Registers[LUT_READ_LOC]){
sed1376Registers[LUT_B_READ] = sed1376BLut[value];
sed1376Registers[LUT_G_READ] = sed1376GLut[value];
sed1376Registers[LUT_R_READ] = sed1376RLut[value];
}
*/
//debugLog("Writing R:0x%02X, G:0x%02X, B:0x%02X to LUT:0x%02X\n", sed1376RLut[value], sed1376GLut[value], sed1376BLut[value], value);
sed1376OutputLut[value] = makeRgb16FromSed666(sed1376RLut[value], sed1376GLut[value], sed1376BLut[value]);
@@ -314,13 +317,14 @@ void sed1376SetRegister(uint8_t address, uint8_t value){
return;
default:
debugLog("SED1376 unknown register write, wrote 0x%02X to 0x%02X, PC 0x%08X.\n", value, address, flx68000GetPc());
return;
}
}
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)){
//only 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
bool color = !!(sed1376Registers[PANEL_TYPE] & 0x40);
bool pictureInPictureEnabled = !!(sed1376Registers[SPECIAL_EFFECT] & 0x10);
uint8_t bitDepth = 1 << (sed1376Registers[DISP_MODE] & 0x07);