diff --git a/hwTestSuite/cpu.c b/hwTestSuite/cpu.c index 71cbd9b..5b81967 100644 --- a/hwTestSuite/cpu.c +++ b/hwTestSuite/cpu.c @@ -64,7 +64,6 @@ const char* getCpuString(){ uint8_t dragonballSubtype = getPhysicalCpuType() & CPU_M68K_TYPES; char* dragonballTypeName; switch(dragonballSubtype){ - case CPU_M68K_328: dragonballTypeName = "328"; break; diff --git a/hwTestSuite/irda.c b/hwTestSuite/irda.c index f4cfa3d..2520d83 100644 --- a/hwTestSuite/irda.c +++ b/hwTestSuite/irda.c @@ -29,7 +29,6 @@ void irdaHandleCommands(){ uint8_t irdaCommand = irdaReceiveUint8(); while(irdaCommand != IRDA_COMMAND_NONE){ switch(irdaCommand){ - case IRDA_COMMAND_NONE: break; diff --git a/hwTestSuite/tests.c b/hwTestSuite/tests.c index 81179e1..cb093e3 100644 --- a/hwTestSuite/tests.c +++ b/hwTestSuite/tests.c @@ -132,7 +132,7 @@ var interrogateSpi2(){ StrPrintF(sharedDataBuffer, "PCDATA:0x%02X", readArbitraryMemory8(HW_REG_ADDR(PCDATA))); UG_PutString(0, y, sharedDataBuffer); y += FONT_HEIGHT + 1; - //PDDATA is buttons, not relevent to the SPI + /*PDDATA is buttons, not relevent to the SPI*/ StrPrintF(sharedDataBuffer, "PEDATA:0x%02X", readArbitraryMemory8(HW_REG_ADDR(PEDATA))); UG_PutString(0, y, sharedDataBuffer); y += FONT_HEIGHT + 1; @@ -341,6 +341,12 @@ var toggleBacklight(){ if(firstRun){ firstRun = false; debugSafeScreenClear(C_WHITE); + StrPrintF(sharedDataBuffer, "Left = SED1376"); + UG_PutString(0, y, sharedDataBuffer); + y += FONT_HEIGHT + 1; + StrPrintF(sharedDataBuffer, "Right = Port G"); + UG_PutString(0, y, sharedDataBuffer); + y += FONT_HEIGHT + 1; } if(getButtonPressed(buttonBack)){ @@ -356,12 +362,7 @@ var toggleBacklight(){ writeArbitraryMemory8(HW_REG_ADDR(PGDATA), readArbitraryMemory8(HW_REG_ADDR(PGDATA)) ^ 0x02); } - StrPrintF(sharedDataBuffer, "Left = SED1376"); - UG_PutString(0, y, sharedDataBuffer); - y += FONT_HEIGHT + 1; - StrPrintF(sharedDataBuffer, "Right = Port G"); - UG_PutString(0, y, sharedDataBuffer); - y += FONT_HEIGHT + 1; + y = (FONT_HEIGHT + 1) * 2; StrPrintF(sharedDataBuffer, "PGDATA:0x%02X", readArbitraryMemory8(HW_REG_ADDR(PGDATA))); UG_PutString(0, y, sharedDataBuffer); y += FONT_HEIGHT + 1; @@ -381,7 +382,7 @@ var toggleMotor(){ if(firstRun){ firstRun = false; debugSafeScreenClear(C_WHITE); - StrPrintF(sharedDataBuffer, "Press select to toggle motor(only works on m515)"); + StrPrintF(sharedDataBuffer, "Select = Toggle Motor"); UG_PutString(0, 0, sharedDataBuffer); } @@ -397,4 +398,45 @@ var toggleMotor(){ return makeVar(LENGTH_0, TYPE_NULL, 0); } +var watchPenIrq(){ + static Boolean firstRun = true; + + if(firstRun){ + firstRun = false; + writeArbitraryMemory8(HW_REG_ADDR(PFDIR), readArbitraryMemory8(HW_REG_ADDR(PFDIR)) & 0xFD); + writeArbitraryMemory8(HW_REG_ADDR(PFSEL), readArbitraryMemory8(HW_REG_ADDR(PFSEL)) | 0x02); + debugSafeScreenClear(C_WHITE); + } + + if(getButtonPressed(buttonBack)){ + firstRun = true; + writeArbitraryMemory8(HW_REG_ADDR(PFSEL), readArbitraryMemory8(HW_REG_ADDR(PFSEL)) & 0xFD); + exitSubprogram(); + } + + StrPrintF(sharedDataBuffer, "PENIRQ State:%s", (readArbitraryMemory8(HW_REG_ADDR(PFDATA)) & 0x02) ? "true " : "false");/*"true " needs the space to clear the e from "false"*/ + UG_PutString(0, 0, sharedDataBuffer); + + return makeVar(LENGTH_0, TYPE_NULL, 0); +} + +var watchIcr(){ + static Boolean firstRun = true; + + if(firstRun){ + firstRun = false; + debugSafeScreenClear(C_WHITE); + } + + if(getButtonPressed(buttonBack)){ + firstRun = true; + writeArbitraryMemory8(HW_REG_ADDR(PFSEL), readArbitraryMemory8(HW_REG_ADDR(PFSEL)) & 0xFD); + exitSubprogram(); + } + + StrPrintF(sharedDataBuffer, "ICR:0x%02X", readArbitraryMemory16(HW_REG_ADDR(ICR))); + UG_PutString(0, 0, sharedDataBuffer); + + return makeVar(LENGTH_0, TYPE_NULL, 0); +} diff --git a/hwTestSuite/tests.h b/hwTestSuite/tests.h index ea2b04f..23f6aaf 100644 --- a/hwTestSuite/tests.h +++ b/hwTestSuite/tests.h @@ -13,5 +13,7 @@ var getClk32Frequency(); var getDeviceId(); var toggleBacklight(); var toggleMotor(); +var watchPenIrq(); +var watchIcr(); #endif diff --git a/hwTestSuite/tools.c b/hwTestSuite/tools.c index 364900a..8b6c500 100644 --- a/hwTestSuite/tools.c +++ b/hwTestSuite/tools.c @@ -70,20 +70,25 @@ uint16_t ads7846GetValue(uint8_t channel, Boolean referenceMode, Boolean mode8bi writeArbitraryMemory16(HW_REG_ADDR(SPICONT2), spi2Control); } + /*flush the register*/ + writeArbitraryMemory16(HW_REG_ADDR(SPIDATA2), 0x0000); + writeArbitraryMemory16(HW_REG_ADDR(SPICONT2), spi2Control | 0x0100/*exchange*/ | 0x0015); + while(readArbitraryMemory16(HW_REG_ADDR(SPICONT2)) & 0x0100); + /*set data to send*/ writeArbitraryMemory16(HW_REG_ADDR(SPIDATA2), config << 8); #if 1 /*send data*/ - writeArbitraryMemory16(HW_REG_ADDR(SPICONT2), spi2Control | 0x0100/*exchange*/ | 0x0008);/*there is a 1 bit delay after the config byte before data is sent*/ + writeArbitraryMemory16(HW_REG_ADDR(SPICONT2), spi2Control | 0x0100/*exchange*/ | 0x0007); while(readArbitraryMemory16(HW_REG_ADDR(SPICONT2)) & 0x0100); /*clear any data received in SPIDATA2 during the previous send*/ - //writeArbitraryMemory16(HW_REG_ADDR(SPIDATA2), 0x0000); - /*trigger a busy event*/ + writeArbitraryMemory16(HW_REG_ADDR(SPIDATA2), 0x0000); + /*trigger a busy event*//*there is a 1 bit delay after the config byte before data is sent*/ writeArbitraryMemory16(HW_REG_ADDR(SPICONT2), spi2Control | 0x0100/*exchange*/); - /*receive data, mode = 1(8 bits) or mode = 0(12 bits)*/ + /*receive data, mode = 1(8 bits) or mode = 0(12 bits), 1 bit is a busy event*/ writeArbitraryMemory16(HW_REG_ADDR(SPICONT2), spi2Control | 0x0100/*exchange*/ | (mode8bit ? 0x0007 : 0x000B)); while(readArbitraryMemory16(HW_REG_ADDR(SPICONT2)) & 0x0100); #endif @@ -117,7 +122,6 @@ float percentageOfTimeAs1(uint32_t address, uint8_t readSize, uint8_t bitNumber, Boolean lastClk32; switch(readSize){ - case 8: value = readArbitraryMemory8(address); break; diff --git a/hwTestSuite/viewer.c b/hwTestSuite/viewer.c index 8a8a4b8..03c2387 100644 --- a/hwTestSuite/viewer.c +++ b/hwTestSuite/viewer.c @@ -150,13 +150,13 @@ CODE_SECTION("viewer") static var listModeFrame(){ if(selectedEntry + 1 < listLength) selectedEntry++; - if(getButtonPressed(buttonLeft) && listLength > ITEM_LIST_ENTRYS) + if(getButtonPressed(buttonLeft)) if(selectedEntry - ITEM_LIST_ENTRYS >= 0) selectedEntry -= ITEM_LIST_ENTRYS;/*flip the page*/ else selectedEntry = 0; - if(getButtonPressed(buttonRight) && listLength > ITEM_LIST_ENTRYS) + if(getButtonPressed(buttonRight)) if(selectedEntry + ITEM_LIST_ENTRYS < listLength) selectedEntry += ITEM_LIST_ENTRYS;/*flip the page*/ else @@ -195,7 +195,6 @@ var valueViewer(){ debugSafeScreenClear(C_WHITE); switch(getVarType(value)){ - case TYPE_UINT: StrPrintF(sharedDataBuffer, "uint32_t:0x%08lX", (uint32_t)varData); UG_PutString(0, 0, sharedDataBuffer); @@ -306,6 +305,10 @@ void resetFunctionViewer(){ hwTests[totalHwTests].testFunction = getDeviceId; totalHwTests++; + StrNCopy(hwTests[totalHwTests].name, "Watch ICR", TEST_NAME_LENGTH); + hwTests[totalHwTests].testFunction = watchIcr; + totalHwTests++; + if(isM515){ StrNCopy(hwTests[totalHwTests].name, "Toggle Backlight", TEST_NAME_LENGTH); hwTests[totalHwTests].testFunction = toggleBacklight; @@ -314,6 +317,10 @@ void resetFunctionViewer(){ StrNCopy(hwTests[totalHwTests].name, "Toggle Motor", TEST_NAME_LENGTH); hwTests[totalHwTests].testFunction = toggleMotor; totalHwTests++; + + StrNCopy(hwTests[totalHwTests].name, "Watch PENIRQ", TEST_NAME_LENGTH); + hwTests[totalHwTests].testFunction = watchPenIrq; + totalHwTests++; } if(unsafeMode){ diff --git a/qtBuildSystem/Mu/Mu.pro b/qtBuildSystem/Mu/Mu.pro index 9611272..419574f 100644 --- a/qtBuildSystem/Mu/Mu.pro +++ b/qtBuildSystem/Mu/Mu.pro @@ -31,7 +31,7 @@ macx { } CONFIG(debug, debug|release){ - DEFINES += EMU_DEBUG EMU_CUSTOM_DEBUG_LOG_HANDLER + DEFINES += EMU_MULTITHREADED EMU_DEBUG EMU_CUSTOM_DEBUG_LOG_HANDLER # DEFINES += EMU_OPCODE_LEVEL_DEBUG EMU_LOG_APIS EMU_LOG_REGISTER_ACCESS_UNKNOWN } diff --git a/src/emulator.c b/src/emulator.c index a2cb665..20a2a5c 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -870,7 +870,7 @@ uint32_t emulatorInstallPrcPdb(buffer_t file){ void emulateFrame(){ refreshInputState(); - sendTouchEvents(); + //sendTouchEvents(); while(palmCycleCounter < CRYSTAL_FREQUENCY / EMU_FPS){ if(palmCrystalCycles != 0.0 && !lowPowerStopActive){ @@ -899,7 +899,7 @@ bool emulateUntilDebugEventOrFrameEnd(){ #if defined(EMU_DEBUG) && defined(EMU_OPCODE_LEVEL_DEBUG) invalidBehaviorAbort = false; refreshInputState(); - sendTouchEvents(); + //sendTouchEvents(); while(palmCycleCounter < CRYSTAL_FREQUENCY / EMU_FPS){ if(palmCrystalCycles != 0.0 && !lowPowerStopActive){ diff --git a/src/emulator.h b/src/emulator.h index 84a769d..8c620cb 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -37,6 +37,15 @@ void frontendHandleDebugClearLogs(); #define debugLog(...) #endif +//threads +#if defined(EMU_MULTITHREADED) +#define MULTITHREAD_LOOP _Pragma("omp parallel for") +#define MULTITHREAD_DOUBLE_LOOP _Pragma("omp parallel for collapse(2)") +#else +#define MULTITHREAD_LOOP +#define MULTITHREAD_DOUBLE_LOOP +#endif + //emu errors enum{ EMU_ERROR_NONE = 0, diff --git a/src/hardwareRegisters.c b/src/hardwareRegisters.c index 849ff4d..84924ac 100644 --- a/src/hardwareRegisters.c +++ b/src/hardwareRegisters.c @@ -48,26 +48,51 @@ bool sed1376ClockConnected(){ } void refreshInputState(){ - /* - uint16_t icr = registerArrayRead16(ICR); - bool penIrqPin = !(ads7846PenIrqEnabled && palmInput.touchscreenTouched);//penIrqPin pulled low on touch + //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) && (penIrqPin == (bool)(icr & 0x0080)) != (bool)(edgeTriggeredInterruptLastValue & INT_IRQ5)) + // setIprIsrBit(INT_IRQ5); - if(penIrqPin == (bool)(icr & 0x0080)) - edgeTriggeredInterruptLastValue |= INT_IRQ5; - else - edgeTriggeredInterruptLastValue &= ~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; + } + } */ + if(!(registerArrayRead8(PFSEL) & 0x02)){ + uint16_t icr = registerArrayRead16(ICR); + bool penIrqPin = !(ads7846PenIrqEnabled && palmInput.touchscreenTouched);//penIrqPin pulled low on touch + + //switch polarity + if(icr & 0x0080) + penIrqPin = !penIrqPin; + + //state changed trigger an interrupt + if(penIrqPin != (bool)(edgeTriggeredInterruptLastValue & INT_IRQ5)) + setIprIsrBit(INT_IRQ5); + + if(penIrqPin) + edgeTriggeredInterruptLastValue |= INT_IRQ5; + else + edgeTriggeredInterruptLastValue &= ~INT_IRQ5; + } + checkPortDInterrupts();//this calls checkInterrupts() so it doesnt need to be called above } @@ -446,8 +471,7 @@ uint8_t getHwRegister8(uint32_t address){ return (registerArrayRead8(PEDATA) & registerArrayRead8(PEDIR)) | ~registerArrayRead8(PEDIR); case PFDATA: - //read outputs as is and inputs as true, floating pins are high - return (registerArrayRead8(PFDATA) & registerArrayRead8(PFDIR)) | ~registerArrayRead8(PFDIR); + return getPortFValue(); case PGDATA: //read outputs as is and inputs as true, floating pins are high diff --git a/src/hardwareRegistersAccessors.c.h b/src/hardwareRegistersAccessors.c.h index 2427984..2d61db5 100644 --- a/src/hardwareRegistersAccessors.c.h +++ b/src/hardwareRegistersAccessors.c.h @@ -394,12 +394,27 @@ static inline uint8_t getPortDValue(){ portDValue |= 0x50;//floating pins are high portDValue ^= portDPolarity;//only input polarity is affected by PDPOL - portDValue &= ~portDDir;//only use above pin values for inputs + portDValue &= ~portDDir;//only use above pin values for inputs, port d allows using special function pins as inputs while active unlike other ports portDValue |= portDData & portDDir;//if a pin is an output and has its data bit set return that too return portDValue; } +static inline uint8_t getPortFValue(){ + uint8_t portFValue = 0x00; + uint8_t portFData = registerArrayRead8(PKDATA); + uint8_t portFDir = registerArrayRead8(PKDIR); + uint8_t portFSel = registerArrayRead8(PKSEL); + bool penIrqPin = !(ads7846PenIrqEnabled && palmInput.touchscreenTouched);//penIrqPin pulled low on touch + + portFValue |= penIrqPin << 1; + portFValue |= 0xFD;//floating pins are high + portFValue &= ~portFDir & portFSel; + portFValue |= portFData & portFDir & portFSel; + + return portFValue; +} + static inline uint8_t getPortKValue(){ uint8_t portKValue = 0x00; uint8_t portKData = registerArrayRead8(PKDATA); diff --git a/src/memoryAccess.c b/src/memoryAccess.c index ed4f96e..bcc871a 100644 --- a/src/memoryAccess.c +++ b/src/memoryAccess.c @@ -1,4 +1,5 @@ #include +#include #include "emulator.h" #include "hardwareRegisters.h" @@ -359,12 +360,12 @@ static uint8_t getProperBankType(uint32_t bank){ } void setRegisterXXFFAccessMode(){ - for(uint32_t topByte = 0; topByte < 0x100; topByte++) + MULTITHREAD_LOOP for(uint32_t topByte = 0; topByte < 0x100; topByte++) bankType[START_BANK(topByte << 24 | 0x00FFF000)] = CHIP_REGISTERS; } void setRegisterFFFFAccessMode(){ - for(uint32_t topByte = 0; topByte < 0x100; topByte++){ + MULTITHREAD_LOOP for(uint32_t topByte = 0; topByte < 0x100; topByte++){ uint32_t bank = START_BANK(topByte << 24 | 0x00FFF000); bankType[bank] = getProperBankType(bank); } @@ -372,19 +373,21 @@ void setRegisterFFFFAccessMode(){ void setSed1376Attached(bool attached){ if(chips[CHIP_B_SED].enable){ + memset(&bankType[START_BANK(chips[CHIP_B_SED].start)], attached ? CHIP_B_SED : CHIP_NONE, END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size) - START_BANK(chips[CHIP_B_SED].start) + 1); + /* if(attached){ - for(uint16_t bank = START_BANK(chips[CHIP_B_SED].start); bank <= END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size); bank++) + MULTITHREAD_LOOP for(uint16_t bank = START_BANK(chips[CHIP_B_SED].start); bank <= END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size); bank++) bankType[bank] = CHIP_B_SED; } else{ - for(uint16_t bank = START_BANK(chips[CHIP_B_SED].start); bank <= END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size); bank++) + MULTITHREAD_LOOP for(uint16_t bank = START_BANK(chips[CHIP_B_SED].start); bank <= END_BANK(chips[CHIP_B_SED].start, chips[CHIP_B_SED].size); bank++) bankType[bank] = CHIP_NONE; } + */ } } void resetAddressSpace(){ - //#pragma omp parallel for - for(uint32_t bank = 0; bank < TOTAL_MEMORY_BANKS; bank++) + MULTITHREAD_LOOP for(uint32_t bank = 0; bank < TOTAL_MEMORY_BANKS; bank++) bankType[bank] = getProperBankType(bank); } diff --git a/src/sed1376.c b/src/sed1376.c index 025ea24..6506761 100644 --- a/src/sed1376.c +++ b/src/sed1376.c @@ -294,7 +294,7 @@ void sed1376Render(){ selectRenderer(color, bitDepth); if(renderPixel){ - for(uint16_t pixelY = 0; pixelY < 160; pixelY++) + MULTITHREAD_DOUBLE_LOOP for(uint16_t pixelY = 0; pixelY < 160; pixelY++) for(uint16_t pixelX = 0; pixelX < 160; pixelX++) palmFramebuffer[pixelY * 160 + pixelX] = renderPixel(pixelX, pixelY); @@ -321,7 +321,7 @@ void sed1376Render(){ pipEndY = uMin(pipEndX, 160); screenStartAddress = getPipStartAddress(); lineSize = (sed1376Registers[PIP_LINE_SZ_1] << 8 | sed1376Registers[PIP_LINE_SZ_0]) * 4; - for(uint16_t pixelY = pipStartY; pixelY < pipEndY; pixelY++) + MULTITHREAD_DOUBLE_LOOP for(uint16_t pixelY = pipStartY; pixelY < pipEndY; pixelY++) for(uint16_t pixelX = pipStartX; pixelX < pipEndX; pixelX++) palmFramebuffer[pixelY * 160 + pixelX] = renderPixel(pixelX, pixelY); } @@ -332,12 +332,12 @@ void sed1376Render(){ //software display inversion if((sed1376Registers[DISP_MODE] & 0x30) == 0x10) - for(uint32_t count = 0; count < 160 * 160; count++) + MULTITHREAD_LOOP for(uint32_t count = 0; count < 160 * 160; count++) palmFramebuffer[count] ^= 0xFFFF; //backlight off, half color intensity if(!palmMisc.backlightOn) - for(uint32_t count = 0; count < 160 * 160; count++){ + MULTITHREAD_LOOP for(uint32_t count = 0; count < 160 * 160; count++){ palmFramebuffer[count] >>= 1; palmFramebuffer[count] &= 0x7BEF; } diff --git a/unimplementedFeatures.txt b/unimplementedFeatures.txt index 958197c..0b46fc9 100644 --- a/unimplementedFeatures.txt +++ b/unimplementedFeatures.txt @@ -32,6 +32,7 @@ port g data bit 2 may need to be 0 to access ADS7846 REFREQ clock frequency in RTCCTL should slow down the RTC when enabled port d IRQ* bits edge triggered interrupt mode is not emulated port g backlight state readback +port d seems to allow using special function pins as inputs while active unlike other ports, this needs to be verified Debug tools: missing icons