From c668ddccb9dee29273cd51b2e47322110d169727 Mon Sep 17 00:00:00 2001 From: meepingsnesroms Date: Thu, 17 May 2018 13:31:37 -0700 Subject: [PATCH] Major cleanups No longer wasting bandwidth with 64 bit commands, start adding IRDA VNC client --- hwTestSuite/TstSuite.def | 2 +- hwTestSuite/cpu.c | 26 +++-- hwTestSuite/cpu.h | 5 +- hwTestSuite/emuFunctions.c | 1 + hwTestSuite/emuFunctions.h | 1 + hwTestSuite/irda.c | 157 ++++++++++++++++++----------- hwTestSuite/irda.h | 3 +- hwTestSuite/irdaAccessors.c.h | 57 +++++++++++ hwTestSuite/make.sh | 6 +- hwTestSuite/testSuite.c | 3 +- hwTestSuite/testSuite.h | 1 + hwTestSuite/tests.c | 3 + hwTestSuite/tools.c | 2 + hwTestSuite/tools.h | 1 + hwTestSuite/viewer.c | 5 +- hwTestSuite/vnc.c | 78 ++++++++++++++ hwTestSuite/vnc.h | 12 +++ musashi/m68kdasm.c | 4 +- qtBuildSystem/Mu/Mu.pro.user | 2 +- specifications/irdaCommands.h | 27 ++--- src/hardwareRegisters.c | 10 +- src/hardwareRegisters.h | 2 +- src/hardwareRegistersAccessors.c.h | 12 +-- 23 files changed, 310 insertions(+), 110 deletions(-) create mode 100644 hwTestSuite/irdaAccessors.c.h create mode 100644 hwTestSuite/vnc.c create mode 100644 hwTestSuite/vnc.h diff --git a/hwTestSuite/TstSuite.def b/hwTestSuite/TstSuite.def index a31ebfc..892e5ee 100644 --- a/hwTestSuite/TstSuite.def +++ b/hwTestSuite/TstSuite.def @@ -1,3 +1,3 @@ application{"TstSuite" GuiC} -multiple code{"ugui" "irda" "viewer"} +multiple code{"ugui" "viewer"} diff --git a/hwTestSuite/cpu.c b/hwTestSuite/cpu.c index ab4d890..034209e 100644 --- a/hwTestSuite/cpu.c +++ b/hwTestSuite/cpu.c @@ -1,5 +1,6 @@ #include #include + #include "testSuite.h" #include "emuFunctions.h" #include "specs/hardwareRegisterNames.h" @@ -8,10 +9,26 @@ static char cpuStringBuffer[100]; +static Boolean interruptsEnabled = true; static uint32_t oldImr; static uint8_t oldScr; +void turnInterruptsOff(){ + if(interruptsEnabled){ + oldImr = readArbitraryMemory32(HW_REG_ADDR(IMR)); + writeArbitraryMemory32(HW_REG_ADDR(IMR), 0xFFFFFFFF); + interruptsEnabled = false; + } +} + +void turnInterruptsOn(){ + if(!interruptsEnabled){ + writeArbitraryMemory32(HW_REG_ADDR(IMR), oldImr); + interruptsEnabled = true; + } +} + uint8_t getPhysicalCpuType(){ long osVer; FtrGet(sysFtrCreator, sysFtrNumROMVersion, &osVer); @@ -77,12 +94,8 @@ var enterUnsafeMode(){ exitSubprogram();/*only run once/for one frame*/ if((getPhysicalCpuType() & CPU_M68K) || isEmulator()){ - oldImr = readArbitraryMemory32(HW_REG_ADDR(IMR)); oldScr = readArbitraryMemory8(HW_REG_ADDR(SCR)); - /*disable unwanted interrupt handlers*/ - writeArbitraryMemory32(HW_REG_ADDR(IMR), oldImr & 0x006F3FFE); - /*disable interrupt on invalid memory access*/ writeArbitraryMemory8(HW_REG_ADDR(SCR), oldScr & 0xEF); @@ -98,12 +111,11 @@ var exitUnsafeMode(){ exitSubprogram();/*only run once/for one frame*/ if(unsafeMode){ - writeArbitraryMemory32(HW_REG_ADDR(IMR), oldImr); + turnInterruptsOn(); writeArbitraryMemory8(HW_REG_ADDR(SCR), oldScr); unsafeMode = false; resetFunctionViewer(); - return makeVar(LENGTH_1, TYPE_BOOL, true); } - return makeVar(LENGTH_1, TYPE_BOOL, false); + return makeVar(LENGTH_0, TYPE_NULL, 0); } diff --git a/hwTestSuite/cpu.h b/hwTestSuite/cpu.h index a067283..04db565 100644 --- a/hwTestSuite/cpu.h +++ b/hwTestSuite/cpu.h @@ -1,9 +1,10 @@ #ifndef CPU_HEADER #define CPU_HEADER -#include #include +#include "testSuite.h" + #define CPU_NONE 0x00/*only if in emulator with special features enabled, returned for physical cpu in emulator*/ #define CPU_M68K 0x01 #define CPU_ARM 0x02 @@ -16,6 +17,8 @@ #define CPU_M68K_SZ 0x80 #define CPU_M68K_TYPES 0xF0 +void turnInterruptsOff(); +void turnInterruptsOn(); uint8_t getPhysicalCpuType(); uint8_t getSupportedInstructionSets(); char* getCpuString(); diff --git a/hwTestSuite/emuFunctions.c b/hwTestSuite/emuFunctions.c index 6c9dbc3..9a071ee 100644 --- a/hwTestSuite/emuFunctions.c +++ b/hwTestSuite/emuFunctions.c @@ -1,5 +1,6 @@ #include #include + #include "testSuite.h" #include "specs/emuFeatureRegistersSpec.h" diff --git a/hwTestSuite/emuFunctions.h b/hwTestSuite/emuFunctions.h index 39377ad..65e6f8a 100644 --- a/hwTestSuite/emuFunctions.h +++ b/hwTestSuite/emuFunctions.h @@ -3,6 +3,7 @@ #include #include + #include "specs/emuFeatureRegistersSpec.h"/*needed for feature names*/ Boolean isEmulator(); diff --git a/hwTestSuite/irda.c b/hwTestSuite/irda.c index 5259d62..8d62cb8 100644 --- a/hwTestSuite/irda.c +++ b/hwTestSuite/irda.c @@ -1,81 +1,63 @@ #include +#include #include + #include "testSuite.h" #include "specs/irdaCommands.h" #include "debug.h" #include "ugui.h" +#include "vnc.h" /*since modern OSs dont support any way to communicate with Palm OS I am making my own with an IR LED and receiver*/ /*this is mainly because running any sort of test takes 3 minutes to compile it, get it on a memory card, load it then find out it doesnt work*/ -static Boolean irdaRunning; -static Boolean irdaError; -static Boolean irdaOutOfSync; +#define IRDA_WAIT_FOREVER 0x7FFFFFFF + + +static Boolean irdaRunning = false; +static Err irdaError; +static Boolean irdaUseThreadedVnc;/*use Dragonball VZ timer 2 interrupt as a second thread for VNC*/ static uint16_t irdaPortId; -static uint32_t irdaCommandBufferLength; -static uint8_t irdaCommandInOffset; -static uint8_t irdaCommandInBytes[IRDA_COMMAND_SIZE]; -static uint8_t irdaCommandOutBytes[IRDA_COMMAND_SIZE]; -CODE_SECTION("irda") static void irdaSendCommand(uint64_t command){ +#include "irdaAccessors.c.h" + +void irdaHandleCommands(){ if(irdaRunning){ - uint32_t bytes; - Err error; - - bytes = SrmSend(irdaPortId, &irdaCommandOutBytes, IRDA_COMMAND_SIZE/*bytes*/, &error); - if(error != errNone) - irdaError = true; - if(bytes != IRDA_COMMAND_SIZE) - irdaOutOfSync = true; - } -} - -CODE_SECTION("irda") static uint64_t irdaGetCommand(){ - if(irdaRunning){ - uint32_t requestBytes; - uint32_t bytes; - Err error; - - error = SrmReceiveCheck(irdaPortId, &requestBytes); - if(error != errNone) - irdaError = true; - - requestBytes = min(requestBytes, IRDA_COMMAND_SIZE - irdaCommandInOffset + 1); - - bytes = SrmReceive(irdaPortId, &irdaCommandInBytes[irdaCommandInOffset], requestBytes, 0, &error); - if(error != errNone) - irdaError = true; - irdaCommandInOffset += bytes; - - if(irdaCommandInOffset >= IRDA_COMMAND_SIZE){ - irdaCommandInOffset = 0; - return IRDA_GET_COMMAND(irdaCommandInBytes); - } - - return IRDA_MAKE_COMMAND(IRDA_COMMAND_NONE, 0); - } -} - -CODE_SECTION("irda") static void irdaHandleCommands(){ - if(irdaRunning){ - uint64_t irdaCommand = irdaGetCommand(); - while(irdaCommand != IRDA_MAKE_COMMAND(IRDA_COMMAND_NONE, 0)){ - switch(IRDA_GET_COMMAND_OPERATION(irdaCommand)){ + uint8_t irdaCommand = irdaReceiveUint8(); + while(irdaCommand != IRDA_COMMAND_NONE){ + switch(irdaCommand){ + case IRDA_COMMAND_NONE: break; + case IRDA_COMMAND_GET_BYTE:{ + uint32_t location = irdaReceiveUint32(); + irdaTransmitUint8(IRDA_COMMAND_RETURN); + irdaTransmitUint8(readArbitraryMemory8(location)); + break; + } + + case IRDA_COMMAND_SET_BYTE:{ + uint32_t location = irdaReceiveUint32(); + uint8_t data = irdaReceiveUint8(); + writeArbitraryMemory8(location, data); + break; + } + default: /*todo: print error and terminate*/ break; } + + irdaCommand = irdaReceiveUint8(); } } } -CODE_SECTION("irda") static Boolean irdaStart(){ +static Boolean irdaInit(Boolean useThreadedVnc){ if(!irdaRunning){ uint32_t value; Err error; @@ -88,20 +70,30 @@ CODE_SECTION("irda") static Boolean irdaStart(){ if(error != errNone) return false; - irdaCommandInOffset = 0; - memset(irdaCommandInBytes, 0x00, IRDA_COMMAND_SIZE); - memset(irdaCommandOutBytes, 0x00, IRDA_COMMAND_SIZE); - irdaRunning = true; + if(useThreadedVnc){ + Boolean success; + success = vncInit(); + if(success) + irdaUseThreadedVnc = true; + else + irdaUseThreadedVnc = false; + } + else{ + irdaUseThreadedVnc = false; + } + irdaRunning = true; return true; } return true;/*its already running, return success*/ } -CODE_SECTION("irda") static void irdaClose(){ +static void irdaExit(){ if(irdaRunning){ - irdaSendCommand((uint64_t)IRDA_COMMAND_CLOSE_CONNECTION << 32); + if(irdaUseThreadedVnc) + vncExit(); + irdaTransmitUint8(IRDA_COMMAND_CLOSE_CONNECTION); SrmSendWait(irdaPortId); SrmReceiveFlush(irdaPortId, 1); SrmSendFlush(irdaPortId); @@ -111,11 +103,13 @@ CODE_SECTION("irda") static void irdaClose(){ var irdaCommandLoop(){ static Boolean firstRun = true; + static Boolean running; if(firstRun){ Boolean success; firstRun = false; - success = irdaStart(); + running = false; + success = irdaInit(varsEqual(getSubprogramArgs(), makeVar(LENGTH_1, TYPE_BOOL, true))); if(success){ debugSafeScreenClear(C_WHITE); StrPrintF(sharedDataBuffer, "IRDA remote control\n mode running..."); @@ -130,11 +124,54 @@ var irdaCommandLoop(){ if(getButtonPressed(buttonBack)){ firstRun = true; - irdaClose(); + irdaExit(); exitSubprogram(); } - irdaHandleCommands(); + if(!irdaUseThreadedVnc) + irdaHandleCommands(); + + return makeVar(LENGTH_0, TYPE_NULL, 0); +} + +var irdaRun(){ + static Boolean firstRun = true; + uint16_t y = 0; + + if(firstRun){ + firstRun = false; + if(!unsafeMode){ + /*cant run VNC server anyway*/ + setSubprogramArgs(makeVar(LENGTH_1, TYPE_BOOL, false)); + execSubprogram(irdaCommandLoop); + return makeVar(LENGTH_0, TYPE_NULL, 0); + } + + debugSafeScreenClear(C_WHITE); + StrPrintF(sharedDataBuffer, "Use Dragonball VZ timer 2 as VNC thread?"); + UG_PutString(0, y, sharedDataBuffer); + y += (FONT_HEIGHT + 1) * 2; + StrPrintF(sharedDataBuffer, "Left = No, Right = Yes"); + UG_PutString(0, y, sharedDataBuffer); + y += FONT_HEIGHT + 1; + } + + if(getButtonPressed(buttonLeft)){ + firstRun = true; + setSubprogramArgs(makeVar(LENGTH_1, TYPE_BOOL, false)); + execSubprogram(irdaCommandLoop); + } + + if(getButtonPressed(buttonRight)){ + firstRun = true; + setSubprogramArgs(makeVar(LENGTH_1, TYPE_BOOL, true)); + execSubprogram(irdaCommandLoop); + } + + if(getButtonPressed(buttonBack)){ + firstRun = true; + exitSubprogram(); + } return makeVar(LENGTH_0, TYPE_NULL, 0); } diff --git a/hwTestSuite/irda.h b/hwTestSuite/irda.h index 440f9d4..57d2d68 100644 --- a/hwTestSuite/irda.h +++ b/hwTestSuite/irda.h @@ -3,7 +3,8 @@ #include "testSuite.h" -var irdaCommandLoop(); +void irdaHandleCommands(); +var irdaRun(); #endif diff --git a/hwTestSuite/irdaAccessors.c.h b/hwTestSuite/irdaAccessors.c.h new file mode 100644 index 0000000..920739f --- /dev/null +++ b/hwTestSuite/irdaAccessors.c.h @@ -0,0 +1,57 @@ +static void irdaTransmitUint8(uint8_t data){ + if(irdaRunning) + SrmSend(irdaPortId, &data, 1/*bytes*/, &irdaError); +} + +static uint8_t irdaReceiveUint8(){ + if(irdaRunning){ + uint8_t data; + + SrmReceive(irdaPortId, &data, 1/*bytes*/, IRDA_WAIT_FOREVER, &irdaError); + return data; + } + + return 0x00; +} + +static void irdaTransmitUint16(uint16_t data){ + if(irdaRunning) + SrmSend(irdaPortId, &data, 2/*bytes*/, &irdaError); +} + +static uint16_t irdaReceiveUint16(){ + if(irdaRunning){ + uint16_t data; + + SrmReceive(irdaPortId, &data, 2/*bytes*/, IRDA_WAIT_FOREVER, &irdaError); + return data; + } + + return 0x0000; +} + +static void irdaTransmitUint32(uint32_t data){ + if(irdaRunning) + SrmSend(irdaPortId, &data, 4/*bytes*/, &irdaError); +} + +static uint32_t irdaReceiveUint32(){ + if(irdaRunning){ + uint32_t data; + + SrmReceive(irdaPortId, &data, 4/*bytes*/, IRDA_WAIT_FOREVER, &irdaError); + return data; + } + + return 0x00000000; +} + +static void irdaTransmitBuffer(uint8_t* data, uint32_t size){ + if(irdaRunning) + SrmSend(irdaPortId, data, size, &irdaError); +} + +static void irdaReceiveBuffer(uint8_t* data, uint32_t size){ + if(irdaRunning) + SrmReceive(irdaPortId, data, size/*bytes*/, IRDA_WAIT_FOREVER, &irdaError); +} diff --git a/hwTestSuite/make.sh b/hwTestSuite/make.sh index 425f96d..4344ecb 100755 --- a/hwTestSuite/make.sh +++ b/hwTestSuite/make.sh @@ -6,15 +6,13 @@ cd $DIR APPNAME="TstSuite" ICONTEXT="HWTests" -#APPID="TstS" -#CREATORID="GuiC" if [ "$1" = "clean" ]; then rm -rf *.o *.a $APPNAME $APPNAME-sections.s $APPNAME-sections.ld $APPNAME.prc *.bin exit fi -declare -a FILES=("testSuite" "viewer" "tools" "tests" "cpu" "irda" "emuFunctions" "ugui") +declare -a FILES=("testSuite" "viewer" "tools" "tests" "cpu" "irda" "vnc" "emuFunctions" "ugui") DEFINES="-DHW_TEST" CFLAGS="-palmos3.5 -O3 $DEFINES" @@ -33,5 +31,3 @@ m68k-palmos-gcc -o $APPNAME *.o $APPNAME-sections.ld pilrc $APPNAME.rcp build-prc $APPNAME.def $APPNAME *.bin -# $ICONTEXT $CREATORID -# build-prc $PRC $ICONTEXT $CREATORID *.grc *.bin diff --git a/hwTestSuite/testSuite.c b/hwTestSuite/testSuite.c index 7cbe69a..0604e09 100644 --- a/hwTestSuite/testSuite.c +++ b/hwTestSuite/testSuite.c @@ -1,6 +1,7 @@ #include #include #include + #include "ugui.h" #include "testSuiteConfig.h" #include "testSuite.h" @@ -15,7 +16,7 @@ /*exported function, cant be converted into a macro*/ var makeVar(uint8_t length, uint8_t type, uint64_t value){ var newVar; - newVar.type = (length & 0xF0) | (type & 0x0F); + newVar.type = length & 0xF0 | type & 0x0F; newVar.value = value; return newVar; } diff --git a/hwTestSuite/testSuite.h b/hwTestSuite/testSuite.h index af7aceb..4fd431d 100644 --- a/hwTestSuite/testSuite.h +++ b/hwTestSuite/testSuite.h @@ -3,6 +3,7 @@ #include #include + #include "testSuiteConfig.h" /*defines*/ diff --git a/hwTestSuite/tests.c b/hwTestSuite/tests.c index dc98572..c864d59 100644 --- a/hwTestSuite/tests.c +++ b/hwTestSuite/tests.c @@ -1,3 +1,6 @@ +#include +#include + #include "testSuite.h" #include "testSuiteConfig.h" #include "specs/hardwareRegisterNames.h" diff --git a/hwTestSuite/tools.c b/hwTestSuite/tools.c index 1daaddf..95ffe8a 100644 --- a/hwTestSuite/tools.c +++ b/hwTestSuite/tools.c @@ -1,4 +1,6 @@ #include +#include + #include "specs/hardwareRegisterNames.h" #include "testSuite.h" #include "viewer.h" diff --git a/hwTestSuite/tools.h b/hwTestSuite/tools.h index dd22f12..3f48f05 100644 --- a/hwTestSuite/tools.h +++ b/hwTestSuite/tools.h @@ -2,6 +2,7 @@ #define TOOLS_HEADER #include + #include "testSuite.h" Err makeFile(uint8_t* data, uint32_t size, char* fileName); diff --git a/hwTestSuite/viewer.c b/hwTestSuite/viewer.c index 42dd04e..ca04825 100644 --- a/hwTestSuite/viewer.c +++ b/hwTestSuite/viewer.c @@ -1,3 +1,6 @@ +#include +#include + #include "testSuiteConfig.h" #include "testSuite.h" #include "tools.h" @@ -274,7 +277,7 @@ void resetFunctionViewer(){ totalHwTests++; StrNCopy(hwTests[totalHwTests].name, "IrDa telnet/VNC", TEST_NAME_LENGTH); - hwTests[totalHwTests].testFunction = irdaCommandLoop; + hwTests[totalHwTests].testFunction = irdaRun; totalHwTests++; if(getPhysicalCpuType() & CPU_M68K){ diff --git a/hwTestSuite/vnc.c b/hwTestSuite/vnc.c new file mode 100644 index 0000000..b938e37 --- /dev/null +++ b/hwTestSuite/vnc.c @@ -0,0 +1,78 @@ +#include +#include + +#include "testSuite.h" +#include "specs/hardwareRegisterNames.h" +#include "irda.h" +#include "cpu.h" + + +/*the OS doesnt seem to use timer 2(at least on Sony Clie PEG-SL10) since it was added after*/ +/*the OS was written since it was originally for the Dragonball 328,*/ +/*this makes it perfect for using as a hardware thread*/ + + +static Boolean vncRunning = false; +static void (*palmOsIntLevel6Handler)(); + + +static void vncInterruptHandler(){ + /*called when VNC is enabled and a level 6 interrupt occurs*/ + if(readArbitraryMemory16(HW_REG_ADDR(TSTAT2))){ + /*the interrupt was called by timer 2*/ + irdaHandleCommands(); + + /*clear timer 2 interrupt, it must be read before writing it is possible but that is performed by the check above*/ + writeArbitraryMemory16(HW_REG_ADDR(TSTAT2), 0x0000); + } + else{ + /*not timer 2, send interrupt to Palm OS*/ + palmOsIntLevel6Handler(); + } +} + +Boolean vncInit(){ + if(!vncRunning){ + uint16_t ilcr; + + turnInterruptsOff(); + + /*install interrupt handler*/ + palmOsIntLevel6Handler = (void*)readArbitraryMemory32(readArbitraryMemory8(HW_REG_ADDR(IVR) | 6/*int level*/) * 4); + writeArbitraryMemory32(readArbitraryMemory8(HW_REG_ADDR(IVR) | 6/*int level*/) * 4, (uint32_t)vncInterruptHandler); + + /*set timer 2 interrupt priority, using level 6 because its the highest*/ + ilcr = readArbitraryMemory16(HW_REG_ADDR(ILCR)); + ilcr &= 0x7770;/*remove TMR2 field*/ + ilcr |= 0x0006;/*set new TMR2 field*/ + writeArbitraryMemory16(HW_REG_ADDR(ILCR), ilcr); + + /*set interrupt to trigger every 32768 / 15 seconds, 15 fps*/ + readArbitraryMemory16(HW_REG_ADDR(TSTAT2));/*clear any existing interrupt*/ + writeArbitraryMemory16(HW_REG_ADDR(TSTAT2), 0x0000);/*clear any existing interrupt*/ + writeArbitraryMemory16(HW_REG_ADDR(TPRER2), 0x0000);/*timer prescaler off*/ + writeArbitraryMemory16(HW_REG_ADDR(TCMP2), 32768 / 15);/*timer duration*/ + writeArbitraryMemory16(HW_REG_ADDR(TCTL2), 0x001F);/*turn on timer 2, using CLK32 as the source*/ + + turnInterruptsOn(); + + vncRunning = true; + } + + return true;/*its already running, return success*/ +} + +void vncExit(){ + if(vncRunning){ + turnInterruptsOff(); + + /*turn off timer 2*/ + writeArbitraryMemory16(HW_REG_ADDR(TCTL2), 0x0000); + + writeArbitraryMemory32(readArbitraryMemory8(HW_REG_ADDR(IVR) | 6/*int level*/) * 4, (uint32_t)palmOsIntLevel6Handler); + + turnInterruptsOn(); + + vncRunning = false; + } +} diff --git a/hwTestSuite/vnc.h b/hwTestSuite/vnc.h new file mode 100644 index 0000000..d1ee7bd --- /dev/null +++ b/hwTestSuite/vnc.h @@ -0,0 +1,12 @@ +#ifndef VNC_HEADER +#define VNC_HEADER + +#include + +#include "testSuite.h" + +Boolean vncInit(); +void vncExit(); + +#endif + diff --git a/musashi/m68kdasm.c b/musashi/m68kdasm.c index 5e95f6e..16ca45d 100755 --- a/musashi/m68kdasm.c +++ b/musashi/m68kdasm.c @@ -171,8 +171,8 @@ char* get_imm_str_s32(void); /* Stuff to build the opcode handler jump table */ static void build_opcode_table(void); -static int valid_ea(uint opcode, uint mask); -static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr); +static int32_t valid_ea(uint opcode, uint mask); +static int32_t DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr); /* used to build opcode handler jump table */ typedef struct diff --git a/qtBuildSystem/Mu/Mu.pro.user b/qtBuildSystem/Mu/Mu.pro.user index bd4f103..14acad0 100644 --- a/qtBuildSystem/Mu/Mu.pro.user +++ b/qtBuildSystem/Mu/Mu.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/specifications/irdaCommands.h b/specifications/irdaCommands.h index 3219e9c..d100e97 100644 --- a/specifications/irdaCommands.h +++ b/specifications/irdaCommands.h @@ -3,34 +3,25 @@ #include -/*commands are 64 bit big endian, 1 byte command/7 bytes data, the data is usualy a pointer*/ +/*commands are big endian*/ /*all access require 2 transfers, a request and an acknowledge, each device must take turns sending and receiving*/ -#define IRDA_COMMAND_SIZE 8 - -/*the uint64_t casts are required since int is 16 bit on m68k and bit shifting is always performed at int length unless specified otherwise*/ -#define IRDA_GET_COMMAND(ptr) ((uint64_t)((ptr)[0]) << 56 | (uint64_t)((ptr)[1]) << 48 | (uint64_t)((ptr)[2]) << 40 | (uint64_t)((ptr)[3]) << 32 | (uint64_t)((ptr)[4]) << 24 | (uint64_t)((ptr)[5]) << 16 | (uint64_t)((ptr)[6]) << 8 | (uint64_t)((ptr)[7])) -#define IRDA_SET_COMMAND(ptr, cmd) ((ptr)[0] = (cmd) >> 56, (ptr)[1] = (cmd) >> 48 & 0xFF, (ptr)[2] = (cmd) >> 40 & 0xFF, (ptr)[3] = (cmd) >> 32 & 0xFF, (ptr)[4] = (cmd) >> 24 & 0xFF, (ptr)[5] = (cmd) >> 16 & 0xFF, (ptr)[6] = (cmd) >> 8 & 0xFF, (ptr)[7] = (cmd) & 0xFF) -#define IRDA_MAKE_COMMAND(operation, data) ((uint64_t)(operation) << 56 | ((uint64_t)(data) & 0x00FFFFFFFFFFFFFFULL)) -#define IRDA_GET_COMMAND_OPERATION(command) ((command) >> 56) -#define IRDA_GET_COMMAND_DATA(command) ((command) & 0x00FFFFFFFFFFFFFFULL) - - enum{ IRDA_COMMAND_NONE = 0, IRDA_COMMAND_GET_BYTE, IRDA_COMMAND_GET_WORD, IRDA_COMMAND_GET_LONG, - IRDA_COMMAND_SET_BYTE, - IRDA_COMMAND_SET_WORD, - IRDA_COMMAND_SET_LONG, - IRDA_COMMAND_CALL_TRAP, + IRDA_COMMAND_SET_BYTE,/*(uint32_t)pointer << 8 | (uint8_t)value*/ + IRDA_COMMAND_SET_WORD,/*(uint32_t)pointer << 16 | (uint16_t)value*/ + IRDA_COMMAND_SET_LONG,/*(uint32_t)pointer << 32 | (uint32_t)value*/ + IRDA_COMMAND_CALL_TRAP,/*(uint16_t)trapNum*/ IRDA_COMMAND_GET_REGISTER, - IRDA_COMMAND_SET_REGISTER,/*data is regNum << 32 | regValue */ + IRDA_COMMAND_SET_REGISTER,/*data is (uint8_t)regNum << 32 | (uint32_t)regValue */ IRDA_COMMAND_RETURN,/*used to acknowledge the end of a command, returns a value if the command returns data*/ IRDA_COMMAND_ALLOCATE_BUFFER,/*returns a pointer to the buffer or NULL on failure*/ - IRDA_COMMAND_SET_BUFFER,/*data is size << 32 | pointer*/ - IRDA_COMMAND_BUFFER_CHUNK,/*contains 7 bytes of the buffer data*/ + IRDA_COMMAND_SET_BUFFER,/*(uint32_t)pointer << 32 | (uint32_t)size then raw data*/ + IRDA_COMMAND_GET_BUFFER,/*(uint32_t)pointer << 32 | (uint32_t)size*/ + IRDA_COMMAND_GET_FRAMEBUFFER,/*all execution is halted until this is finished, returns (uint16_t)width << 24 | (uint16_t)height << 8 | (uint8_t)bpp then raw data*/ IRDA_COMMAND_CLOSE_CONNECTION }; diff --git a/src/hardwareRegisters.c b/src/hardwareRegisters.c index 718f478..8b31352 100644 --- a/src/hardwareRegisters.c +++ b/src/hardwareRegisters.c @@ -69,13 +69,13 @@ void refreshInputState(){ checkPortDInterrupts();//this calls checkInterrupts() so it doesnt need to be called above } -int interruptAcknowledge(int intLevel){ - int vectorOffset = registerArrayRead8(IVR); - int vector; +int32_t interruptAcknowledge(int32_t intLevel){ + uint8_t vectorOffset = registerArrayRead8(IVR); + int32_t vector; - //If an interrupt occurs before the IVR has been programmed, the interrupt vector number 0x0F is returned to the CPU as an uninitialized interrupt. + //If an interrupt occurs before the IVR has been programmed, interrupt vector 15 is returned to the CPU as an uninitialized interrupt. if(!vectorOffset) - vector = 0x0F;//EXCEPTION_UNINITIALIZED_INTERRUPT + vector = 15;//EXCEPTION_UNINITIALIZED_INTERRUPT else vector = vectorOffset | intLevel; diff --git a/src/hardwareRegisters.h b/src/hardwareRegisters.h index 72562b6..7ae5628 100644 --- a/src/hardwareRegisters.h +++ b/src/hardwareRegisters.h @@ -82,7 +82,7 @@ bool pllIsOn(); bool registersAreXXFFMapped(); bool sed1376ClockConnected(); void refreshInputState(); -int interruptAcknowledge(int intLevel); +int32_t interruptAcknowledge(int32_t intLevel); //memory errors void setBusErrorTimeOut(); diff --git a/src/hardwareRegistersAccessors.c.h b/src/hardwareRegistersAccessors.c.h index e86d32c..9760eef 100644 --- a/src/hardwareRegistersAccessors.c.h +++ b/src/hardwareRegistersAccessors.c.h @@ -254,10 +254,6 @@ static inline void setSpiCont2(uint16_t value){ } registerArrayWrite16(SPIDATA2, spi2Data); - //IRQEN set, send an interrupt after transfer - if(value & 0x0040) - setIprIsrBit(INT_SPI2); - //debugLog("SPI2 transfer, ENABLE:%s, XCH:%s, IRQ:%s, IRQEN:%s, BITCOUNT:%d\n", boolString(value & 0x0200), boolString(value & 0x0100), boolString(value & 0x0080), boolString(value & 0x0400), (value & 0x000F) + 1); //debugLog("SPI2 transfer, shifted in:0x%04X, shifted out:0x%04X\n", spi2Data << (16 - bitCount) >> bitCount, oldSpiCont2 >> (16 - bitCount)); @@ -266,6 +262,10 @@ static inline void setSpiCont2(uint16_t value){ //acknowledge transfer finished, transfers are instant since timing is not emulated value |= 0x0080; + + //IRQEN set, send an interrupt after transfer + if(value & 0x0040) + setIprIsrBit(INT_SPI2); } registerArrayWrite16(SPICONT2, value & 0xE3FF); @@ -312,9 +312,9 @@ static inline void setPwmc1(uint16_t value){ if(!(value & 0x0010)){ //PWM1 set to disabled - value &= 0x80FF;//clear prescaler value + value &= 0x80FF;//clear PWM prescaler value - //unemulated, also need to flush PWM1 FIFO + //need to flush PWM1 FIFO, unemulated } registerArrayWrite16(PWMC1, value);