mirror of
https://github.com/libretro/Mu.git
synced 2026-09-23 15:15:43 +00:00
Increase ADS7846 accuracy, implement PLLFSR 8 bit reads, enable logging on all unemulated regiser accesses
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user