mirror of
https://github.com/libretro/Mu.git
synced 2026-09-24 07:35:55 +00:00
Update GPIO map, remove port a from tests, it cant be used when the CPU is in 16 bit mode which Palm OS uses
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
//stuck on timer wait, inside interrupt level 6 handler
|
||||
|
||||
PCR
|
||||
TYPE RESET
|
||||
Peripheral Control Register 0x(FF)FFF003
|
||||
|
||||
PCR T field could be set to use timer chaining
|
||||
|
||||
CPU wrote 16 bits of 0x00000000 to register 0x60A, PC 0x10083BF0.
|
||||
|
||||
#define kChannelSet1 \
|
||||
kChannelTemp0, \
|
||||
kChannelPenY, \
|
||||
kChannelBattery7846, \
|
||||
kChannelUnused, \
|
||||
kChannelUnused, \
|
||||
kChannelPenX, \
|
||||
kChannelDockTwister, \
|
||||
kChannelTemp1
|
||||
|
||||
CPU read 8 bits from register 0x0431, PC 0x100815B2.
|
||||
CPU read 8 bits from register 0x0420, PC 0x100815B8.
|
||||
CPU read 8 bits from register 0x0421, PC 0x100815BE.
|
||||
SPI2 transfer, ENABLE:true, XCH:false, IRQ:false, IRQEN:false, BITCOUNT:12 //XCH false, does nothing
|
||||
SPI2 transfer, ENABLE:true, XCH:true, IRQ:false, IRQEN:false, BITCOUNT:12
|
||||
SPI2 transfer, ENABLE:true, XCH:false, IRQ:false, IRQEN:false, BITCOUNT:5 //XCH false, does nothing
|
||||
SPI2 transfer, ENABLE:true, XCH:true, IRQ:false, IRQEN:false, BITCOUNT:5
|
||||
SPI2 transfer, ENABLE:true, XCH:false, IRQ:false, IRQEN:false, BITCOUNT:16 //XCH false, does nothing
|
||||
SPI2 transfer, ENABLE:true, XCH:true, IRQ:false, IRQEN:false, BITCOUNT:16
|
||||
SPI2 transfer, ENABLE:true, XCH:true, IRQ:false, IRQEN:false, BITCOUNT:3
|
||||
SPI2 transfer, ENABLE:false, XCH:false, IRQ:false, IRQEN:false, BITCOUNT:1 //XCH false, does nothing
|
||||
CPU read 8 bits from register 0x0431, PC 0x10081A04.
|
||||
|
||||
CPU read 8 bits from register 0x0431, PC 0x100815B2.
|
||||
CPU read 8 bits from register 0x0420, PC 0x100815B8.
|
||||
CPU read 8 bits from register 0x0421, PC 0x100815BE.
|
||||
|
||||
|
||||
//copilots SPI touch code
|
||||
case SPIMCONT:
|
||||
db_SPIMCONT.x = value;
|
||||
if (db_SPIMCONT.anon.XCH && db_SPIMCONT.anon.IRQEN) {
|
||||
db_SPIMCONT.anon.SPIMIRQ = 1;
|
||||
db_SPIMCONT.anon.XCH = 0;
|
||||
switch (db_PFDATA.x & 0x0f) {
|
||||
case 0x6:
|
||||
db_SPIMDATA.x = (0xff - CustShptr->penx) * 2;
|
||||
break;
|
||||
case 0x9:
|
||||
db_SPIMDATA.x = (0xff - CustShptr->peny) * 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
89
gpioMap.txt
89
gpioMap.txt
@@ -1,89 +0,0 @@
|
||||
General Layout:
|
||||
Port A: D* Data Lines
|
||||
Port B: Fixed 0x3F, likely nothing attached, probably used for chip select
|
||||
Port C: Usually 0x7F or 0x3F(less common), needs to be investigated further
|
||||
Port D: Hardware buttons
|
||||
Port E: Always 0x5E or 0x5C, only bit 1 seems used, needs to be investigated further
|
||||
Port F: Always 0x9D or 0x9C, only bit 0 seems used, needs to be investigated further
|
||||
Port G: 0x15 when backlight is off, 0x17 when its on, bit 1 is a read back of SED1376 GPIO 0 pin 4
|
||||
Port J: Fixed 0xB0, needs to be investigated further
|
||||
Port K: Fixed 0x04 in testing, used to select Port Ds active matrix line, bit 4 enables the vibrator motor
|
||||
Port M: Fixed 0x23, needs to be investigated further
|
||||
|
||||
Pin Mapping(all pins are accounted for, documented or not):
|
||||
Port A Pin 0: Data Line 0(can only be used as a GPIO in 8 bit mode)
|
||||
Port A Pin 1: Data Line 1(can only be used as a GPIO in 8 bit mode)
|
||||
Port A Pin 2: Data Line 2(can only be used as a GPIO in 8 bit mode)
|
||||
Port A Pin 3: Data Line 3(can only be used as a GPIO in 8 bit mode)
|
||||
Port A Pin 4: Data Line 4(can only be used as a GPIO in 8 bit mode)
|
||||
Port A Pin 5: Data Line 5(can only be used as a GPIO in 8 bit mode)
|
||||
Port A Pin 6: Data Line 6(can only be used as a GPIO in 8 bit mode)
|
||||
Port A Pin 7: Data Line 7(can only be used as a GPIO in 8 bit mode)
|
||||
Port B Pin 0: Unknown
|
||||
Port B Pin 1: Unknown
|
||||
Port B Pin 2: Unknown
|
||||
Port B Pin 3: Unknown
|
||||
Port B Pin 4: Unknown
|
||||
Port B Pin 5: Unknown
|
||||
Port B Pin 6: Unknown
|
||||
Port B Pin 7: Unknown
|
||||
Port C Pin 0: Unknown
|
||||
Port C Pin 1: Unknown
|
||||
Port C Pin 2: Unknown
|
||||
Port C Pin 3: Unknown
|
||||
Port C Pin 4: Unknown
|
||||
Port C Pin 5: Unknown
|
||||
Port C Pin 6: Unknown
|
||||
Port C Pin 7: Unknown
|
||||
Port D Pin 0: Button Matrix Input Line 0(INT0)(low when button pressed)
|
||||
Port D Pin 1: Button Matrix Input Line 1(INT1)(low when button pressed)
|
||||
Port D Pin 2: Button Matrix Input Line 2(INT2)(low when button pressed)
|
||||
Port D Pin 3: Button Matrix Input Line 3(INT3)(low when button pressed)
|
||||
Port D Pin 4: HotSync Cable Button(IRQ1)(low when button pressed)
|
||||
Port D Pin 5: SD Card Status(IRQ2)(low when card is inserted)
|
||||
Port D Pin 6: Unknown(IRQ3)
|
||||
Port D Pin 7: Battery Critical Interrupt(IRQ6)(low when critical)
|
||||
Port E Pin 0: SPITXD(used for ADS7846)
|
||||
Port E Pin 1: SPIRXD(used for ADS7846)
|
||||
Port E Pin 2: SPICLK2(used for ADS7846)
|
||||
Port E Pin 3: Unknown
|
||||
Port E Pin 4: Unknown
|
||||
Port E Pin 5: Unknown
|
||||
Port E Pin 6: Unknown
|
||||
Port E Pin 7: Unknown
|
||||
Port F Pin 0: Unknown
|
||||
Port F Pin 1: ADS7846 PENIRQ(low when screen is touched)
|
||||
Port F Pin 2: Clock Output(required for SED1376 operation, reads and writes do nothing)
|
||||
Port F Pin 3: Address Line 20(must be an address line for 16mb RAM to be addressed)
|
||||
Port F Pin 4: Address Line 21(must be an address line for 16mb RAM to be addressed)
|
||||
Port F Pin 5: Address Line 22(must be an address line for 16mb RAM to be addressed)
|
||||
Port F Pin 6: Address Line 23(must be an address line for 16mb RAM to be addressed)
|
||||
Port F Pin 7: Unknown
|
||||
Port G Pin 0: Unknown
|
||||
Port G Pin 1: Backlight State Read Back(high when backlight on)
|
||||
Port G Pin 2: Unknown
|
||||
Port G Pin 3: Unknown
|
||||
Port G Pin 4: Unknown
|
||||
Port G Pin 5: Unknown
|
||||
Port J Pin 0: Unknown
|
||||
Port J Pin 1: Unknown
|
||||
Port J Pin 2: Unknown
|
||||
Port J Pin 3: Unknown
|
||||
Port J Pin 4: Unknown
|
||||
Port J Pin 5: Unknown
|
||||
Port J Pin 6: Unknown
|
||||
Port J Pin 7: Unknown
|
||||
Port K Pin 0: Unknown
|
||||
Port K Pin 1: Unknown
|
||||
Port K Pin 2: Battery Charging/Docked(low when charging)
|
||||
Port K Pin 3: Unknown
|
||||
Port K Pin 4: Enable Vibrator Motor(set high to enable)
|
||||
Port K Pin 5: Button Matrix Line Select 0(set low to enable line, multiple lines can be enabled at once)
|
||||
Port K Pin 6: Button Matrix Line Select 1(set low to enable line, multiple lines can be enabled at once)
|
||||
Port K Pin 7: Button Matrix Line Select 2(set low to enable line, multiple lines can be enabled at once)
|
||||
Port M Pin 0: Unknown
|
||||
Port M Pin 1: Unknown
|
||||
Port M Pin 2: Unknown
|
||||
Port M Pin 3: Unknown
|
||||
Port M Pin 4: Unknown
|
||||
Port M Pin 5: Unknown
|
||||
@@ -74,9 +74,6 @@ var listDataRegisters(){
|
||||
exitSubprogram();
|
||||
}
|
||||
|
||||
StrPrintF(sharedDataBuffer, "PADATA:0x%02X", readArbitraryMemory8(HW_REG_ADDR(PADATA)));
|
||||
UG_PutString(0, y, sharedDataBuffer);
|
||||
y += FONT_HEIGHT + 1;
|
||||
StrPrintF(sharedDataBuffer, "PBDATA:0x%02X", readArbitraryMemory8(HW_REG_ADDR(PBDATA)));
|
||||
UG_PutString(0, y, sharedDataBuffer);
|
||||
y += FONT_HEIGHT + 1;
|
||||
@@ -124,9 +121,6 @@ var interrogateSpi2(){
|
||||
exitSubprogram();
|
||||
}
|
||||
|
||||
StrPrintF(sharedDataBuffer, "PADATA:0x%02X", readArbitraryMemory8(HW_REG_ADDR(PADATA)));
|
||||
UG_PutString(0, y, sharedDataBuffer);
|
||||
y += FONT_HEIGHT + 1;
|
||||
StrPrintF(sharedDataBuffer, "PBDATA:0x%02X", readArbitraryMemory8(HW_REG_ADDR(PBDATA)));
|
||||
UG_PutString(0, y, sharedDataBuffer);
|
||||
y += FONT_HEIGHT + 1;
|
||||
@@ -426,6 +420,28 @@ var toggleMotor(){
|
||||
return makeVar(LENGTH_0, TYPE_NULL, 0);
|
||||
}
|
||||
|
||||
var toggleAlarmLed(){
|
||||
static Boolean firstRun = true;
|
||||
|
||||
if(firstRun){
|
||||
firstRun = false;
|
||||
debugSafeScreenClear(C_WHITE);
|
||||
StrPrintF(sharedDataBuffer, "Select = Toggle Alarm LED");
|
||||
UG_PutString(0, 0, sharedDataBuffer);
|
||||
}
|
||||
|
||||
if(getButtonPressed(buttonBack)){
|
||||
firstRun = true;
|
||||
exitSubprogram();
|
||||
}
|
||||
|
||||
if(getButtonPressed(buttonSelect)){
|
||||
writeArbitraryMemory8(HW_REG_ADDR(PBDATA), readArbitraryMemory8(HW_REG_ADDR(PBDATA)) ^ 0x40);
|
||||
}
|
||||
|
||||
return makeVar(LENGTH_0, TYPE_NULL, 0);
|
||||
}
|
||||
|
||||
var watchPenIrq(){
|
||||
static Boolean firstRun = true;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ var getDeviceId();
|
||||
var getCpuInfo();
|
||||
var toggleBacklight();
|
||||
var toggleMotor();
|
||||
var toggleAlarmLed();
|
||||
var watchPenIrq();
|
||||
var watchIcr();
|
||||
|
||||
|
||||
@@ -322,6 +322,10 @@ void resetFunctionViewer(){
|
||||
hwTests[totalHwTests].testFunction = toggleMotor;
|
||||
totalHwTests++;
|
||||
|
||||
StrNCopy(hwTests[totalHwTests].name, "Toggle Alarm LED", TEST_NAME_LENGTH);
|
||||
hwTests[totalHwTests].testFunction = toggleAlarmLed;
|
||||
totalHwTests++;
|
||||
|
||||
StrNCopy(hwTests[totalHwTests].name, "Watch PENIRQ", TEST_NAME_LENGTH);
|
||||
hwTests[totalHwTests].testFunction = watchPenIrq;
|
||||
totalHwTests++;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.6.2, 2018-06-18T11:31:16. -->
|
||||
<!-- Written by QtCreator 4.6.2, 2018-06-18T13:13:34. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
||||
@@ -30,6 +30,7 @@ static void checkInterrupts();
|
||||
static void checkPortDInterrupts();
|
||||
static void recalculateCpuSpeed();
|
||||
static void pllWakeCpuIfOff();
|
||||
static void updateAlarmLedStatus();
|
||||
|
||||
#include "hardwareRegistersAccessors.c.h"
|
||||
#include "hardwareRegistersTiming.c.h"
|
||||
@@ -48,34 +49,11 @@ bool sed1376ClockConnected(){
|
||||
return !(registerArrayRead8(PFSEL) & 0x04) && !(registerArrayRead16(PLLCR) & 0x0010);
|
||||
}
|
||||
|
||||
void refreshInputState(){
|
||||
//uint16_t icr = registerArrayRead16(ICR);
|
||||
//bool penIrqPin = !(ads7846PenIrqEnabled && palmInput.touchscreenTouched);//penIrqPin pulled low on touch
|
||||
|
||||
/*
|
||||
//IRQ set as pin function and triggered
|
||||
if(!(registerArrayRead8(PFSEL) & 0x02) && penIrqPin == (bool)(icr & 0x0080))
|
||||
setIprIsrBit(INT_IRQ5);
|
||||
*/
|
||||
|
||||
//IRQ set as pin function and triggered, the pen IRQ triggers when going low to high or high to low
|
||||
//if(!(registerArrayRead8(PFSEL) & 0x02) && (penIrqPin == (bool)(icr & 0x0080)) != (bool)(edgeTriggeredInterruptLastValue & INT_IRQ5))
|
||||
// setIprIsrBit(INT_IRQ5);
|
||||
|
||||
/*
|
||||
if(!(registerArrayRead8(PFSEL) & 0x02)){
|
||||
if(penIrqPin == (bool)(icr & 0x0080)){
|
||||
if(!(edgeTriggeredInterruptLastValue & INT_IRQ5)){
|
||||
setIprIsrBit(INT_IRQ5);
|
||||
edgeTriggeredInterruptLastValue |= INT_IRQ5;
|
||||
}
|
||||
}
|
||||
else{
|
||||
edgeTriggeredInterruptLastValue &= ~INT_IRQ5;
|
||||
}
|
||||
}
|
||||
*/
|
||||
void refreshInputState(){
|
||||
//update alarm LED state if palmMisc.batteryCharging changed
|
||||
updateAlarmLedStatus();
|
||||
|
||||
//update touchscreen state
|
||||
if(!(registerArrayRead8(PFSEL) & 0x02)){
|
||||
uint16_t icr = registerArrayRead16(ICR);
|
||||
bool penIrqPin = !(ads7846PenIrqEnabled && palmInput.touchscreenTouched);//penIrqPin pulled low on touch
|
||||
@@ -99,6 +77,7 @@ void refreshInputState(){
|
||||
*/
|
||||
}
|
||||
|
||||
//check for button presses and interrupts
|
||||
checkPortDInterrupts();//this calls checkInterrupts() so it doesnt need to be called above
|
||||
}
|
||||
|
||||
@@ -387,14 +366,15 @@ static void checkPortDInterrupts(){
|
||||
checkInterrupts();
|
||||
}
|
||||
|
||||
static inline void updateAlarmLedStatus(){
|
||||
if(registerArrayRead8(PBDATA) & registerArrayRead8(PBSEL) & registerArrayRead8(PBDIR) & 0x40)
|
||||
static void updateAlarmLedStatus(){
|
||||
bool pinLineOn = registerArrayRead8(PBDATA) & registerArrayRead8(PBSEL) & registerArrayRead8(PBDIR) & 0x40;
|
||||
if(pinLineOn != palmMisc.batteryCharging)
|
||||
palmMisc.alarmLed = true;
|
||||
else
|
||||
palmMisc.alarmLed = false;
|
||||
}
|
||||
|
||||
static inline void updateVibratorStatus(){
|
||||
static void updateVibratorStatus(){
|
||||
if(registerArrayRead8(PKDATA) & registerArrayRead8(PKSEL) & registerArrayRead8(PKDIR) & 0x10)
|
||||
palmMisc.vibratorOn = true;
|
||||
else
|
||||
|
||||
@@ -166,13 +166,13 @@ static inline void setPllfsr(uint16_t value){
|
||||
|
||||
static inline void setScr(uint8_t value){
|
||||
uint8_t oldScr = registerArrayRead8(SCR);
|
||||
uint8_t newScr = value;
|
||||
uint8_t newScr = value & 0x1F;
|
||||
|
||||
//preserve privilege violation, write protect violation and bus error timeout
|
||||
newScr |= oldScr & 0xE0;
|
||||
|
||||
//clear violations on writing 1 to them
|
||||
newScr &= ~(oldScr & value & 0xE0);
|
||||
newScr &= ~(value & 0xE0);
|
||||
|
||||
chips[CHIP_REGISTERS].supervisorOnlyProtectedMemory = value & 0x08;
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ static inline void timer12Clk32(){
|
||||
}
|
||||
}
|
||||
|
||||
if(timer1Enabled && timer1OldCount <= timer1Compare && timerCycleCounter[0] >= timer1Compare){
|
||||
if(timer1Enabled && timer1OldCount < timer1Compare && timerCycleCounter[0] >= timer1Compare){
|
||||
//the comparison against the old value is to prevent an interrupt on every increment in free running mode
|
||||
//the timer is not cycle accurate and may not hit the value in the compare register perfectly so check if it would have during in the emulated time
|
||||
|
||||
@@ -158,7 +158,7 @@ static inline void timer12Clk32(){
|
||||
timerCycleCounter[0] -= timer1Compare;
|
||||
}
|
||||
|
||||
if(timer2Enabled && timer2OldCount <= timer2Compare && timerCycleCounter[1] >= timer2Compare){
|
||||
if(timer2Enabled && timer2OldCount < timer2Compare && timerCycleCounter[1] >= timer2Compare){
|
||||
//the comparison against the old value is to prevent an interrupt on every increment in free running mode
|
||||
//the timer is not cycle accurate and may not hit the value in the compare register perfectly so check if it would have during in the emulated time
|
||||
|
||||
@@ -196,6 +196,8 @@ static inline void timer12Clk32(){
|
||||
}
|
||||
}
|
||||
|
||||
//if timer chaining causes an interrupt the actual interrupt takes place the next time this function is called
|
||||
|
||||
if(timer1Enabled){
|
||||
if(timerCycleCounter[0] > 0xFFFF)
|
||||
timerCycleCounter[0] -= 0xFFFF;
|
||||
|
||||
@@ -49,6 +49,7 @@ swivelview register
|
||||
|
||||
|
||||
Fixed:
|
||||
port b pin 6 is xored with the power detection on the alarm/power LED, if docked it turns the LED off, if not docked it turns the LED on
|
||||
touch interrupt seems to not use IRQ5(it does, theres a test for it now)
|
||||
port d seems to allow using special function pins as inputs while active unlike other ports, this needs to be verified(verified by MC68VZ328UM.pdf Page 10-15)
|
||||
CPU_RUN_MODE is not preserved on save state and could allow executing after an address error if a save and load are performed(CPU_RUN_MODE is not used when address error is disabled)
|
||||
|
||||
Reference in New Issue
Block a user