From 5cf299d8ba459c1936967b65146a317465bca6fb Mon Sep 17 00:00:00 2001 From: meepingsnesroms Date: Fri, 30 Mar 2018 00:10:23 -0700 Subject: [PATCH] Add button access, define port d access --- src/emulator.c | 35 +++++++---- src/emulator.h | 55 ++++++++++------- src/hardwareRegisters.c | 122 +++++++++++++++++++++++++++++++++++++- unimplementedFeatures.txt | 4 +- 4 files changed, 183 insertions(+), 33 deletions(-) diff --git a/src/emulator.c b/src/emulator.c index bfd8c28..27273ea 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -22,15 +22,16 @@ //0xFFFFFF00-0xFFFFFFFF Bootloader, pesumably does the 256 byte ROM to RAM copy, never been dumped -uint8_t palmRam[RAM_SIZE]; -uint8_t palmRom[ROM_SIZE]; -uint8_t palmReg[REG_SIZE]; -input_t palmIo; -sdcard_t palmSdCard; -uint16_t palmFramebuffer[160 * (160 + 60)];//really 160*160, the extra pixels are the silkscreened digitizer area -double palmCrystalCycles;//how many cycles before toggling the 32.768 kHz crystal -double palmCycleCounter;//can be greater then 0 if too many cycles where run -double palmClockMultiplier;//used by the emulator to overclock the emulated palm +uint8_t palmRam[RAM_SIZE]; +uint8_t palmRom[ROM_SIZE]; +uint8_t palmReg[REG_SIZE]; +input_t palmIo; +sdcard_t palmSdCard; +misc_hw_t palmMisc; +uint16_t palmFramebuffer[160 * (160 + 60)];//really 160*160, the extra pixels are the silkscreened digitizer area +double palmCrystalCycles;//how many cycles before toggling the 32.768 kHz crystal +double palmCycleCounter;//can be greater then 0 if too many cycles where run +double palmClockMultiplier;//used by the emulator to overclock the emulated palm void emulatorInit(uint8_t* palmRomDump, uint16_t specialFeatures){ @@ -53,15 +54,29 @@ void emulatorInit(uint8_t* palmRomDump, uint16_t specialFeatures){ sed1376Reset(); //interfaces - palmIo.buttonState = 0x0000; + palmIo.buttonUp = false; + palmIo.buttonDown = false; + palmIo.buttonLeft = false;//only used in hybrid mode + palmIo.buttonRight = false;//only used in hybrid mode + palmIo.buttonCalender = false; + palmIo.buttonAddress = false; + palmIo.buttonTodo = false; + palmIo.buttonNotes = false; + palmIo.buttonPower = false; + palmIo.buttonContrast = false; palmIo.touchscreenX = 0; palmIo.touchscreenY = 0; palmIo.touchscreenTouched = false; palmSdCard.getSdCardChunk = NULL; palmSdCard.setSdCardChunk = NULL; + palmSdCard.size = 0; palmSdCard.inserted = false; + palmMisc.powerButtonLed = false; + palmMisc.batteryCharging = false; + palmMisc.batteryLevel = 100; + //config palmClockMultiplier = 1.0;//Overclock disabled diff --git a/src/emulator.h b/src/emulator.h index dc6f9c5..5994ce6 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -13,27 +13,41 @@ enum emu_error_t{ //types typedef struct{ - uint16_t buttonState; + bool buttonUp; + bool buttonDown; + bool buttonLeft;//only used in hybrid mode + bool buttonRight;//only used in hybrid mode + bool buttonCalender;//hw button 1 + bool buttonAddress;//hw button 2 + bool buttonTodo;//hw button 3 + bool buttonNotes;//hw button 4 + bool buttonPower; + bool buttonContrast; uint16_t touchscreenX; uint16_t touchscreenY; bool touchscreenTouched; }input_t; typedef struct{ - void (*getSdCardChunk)(uint8_t* data, uint32_t size); - void (*setSdCardChunk)(uint8_t* data, uint32_t size); - bool inserted; + void (*getSdCardChunk)(uint8_t* data, uint32_t size); + void (*setSdCardChunk)(uint8_t* data, uint32_t size); + uint64_t size; + bool inserted; }sdcard_t; -//buttons -#define buttonUp 0 -//etc... +typedef struct{ + bool powerButtonLed; + bool batteryCharging; + uint8_t batteryLevel; +}misc_hw_t; //special features, these make the emulator inaccurate in a good way, but still inaccurate and are therefore optional, they dont do anything yet -#define ACCURATE 0x0000 //no hacks/addons -#define INACCURATE_RAM_HUGE 0x0001 //128 mb ram -#define INACCURATE_FAST_CPU 0x0002 //doubles cpu speed -#define INACCURATE_HYBRID_CPU 0x0004 //allows running arm opcodes in an OS 4 enviroment +#define ACCURATE 0x0000//no hacks/addons +#define INACCURATE_RAM_HUGE 0x0001//128 mb ram +#define INACCURATE_FAST_CPU 0x0002//doubles cpu speed +#define INACCURATE_HYBRID_CPU 0x0004//allows running arm opcodes in an OS 4 enviroment +#define INACCURATE_320x320 0x0008//creates a 320x320 frambuffer for hires mode, the 320x320 framebuffer is a transparent overlay over the 160x160 one and covers it where its pixels are enabled +#define INACCURATE_SYNCED_RTC 0x0010//rtc always equals host system time //config options #define EMU_FPS 60.0 @@ -55,15 +69,16 @@ typedef struct{ #define SED1376_FB_SIZE 0x14000//likely also has 0x20000 used address space entrys //emulator data -extern uint8_t palmRam[]; -extern uint8_t palmRom[]; -extern uint8_t palmReg[]; -extern input_t palmIo; -extern sdcard_t palmSdCard; -extern uint16_t palmFramebuffer[]; -extern double palmCrystalCycles; -extern double palmCycleCounter; -extern double palmClockMultiplier; +extern uint8_t palmRam[]; +extern uint8_t palmRom[]; +extern uint8_t palmReg[]; +extern input_t palmIo; +extern sdcard_t palmSdCard; +extern misc_hw_t palmMisc; +extern uint16_t palmFramebuffer[]; +extern double palmCrystalCycles; +extern double palmCycleCounter; +extern double palmClockMultiplier; //functions void emulatorInit(uint8_t* palmRomDump, uint16_t specialFeatures); diff --git a/src/hardwareRegisters.c b/src/hardwareRegisters.c index 45f5843..0a1e950 100644 --- a/src/hardwareRegisters.c +++ b/src/hardwareRegisters.c @@ -11,6 +11,9 @@ #include "m68k/m68kcpu.h" +void checkInterrupts(); + + static inline uint8_t registerArrayRead8(uint32_t address){ return palmReg[address]; } @@ -52,6 +55,108 @@ static inline void clearIprIsrBit(uint32_t interruptBit){ } +static inline void checkPortDInts(){ + uint8_t requestedRow = registerArrayRead8(PKDIR) & registerArrayRead8(PKDATA);//keys are requested on port k and read on port d + uint8_t portDValue = 0x00;//ports always read the chip pins even if they are set to output + uint8_t portDpolarity = registerArrayRead8(PDPOL); + uint8_t portDIrqEnable = registerArrayRead8(PDIRQEN); + uint8_t portDIrqPins = ~registerArrayRead8(PDSEL); + + portDValue |= 0x80/*battery not dead bit*/; + + if(palmSdCard.inserted){ + portDValue |= 0x20; + } + + if((requestedRow & 0x20) == 0){ + //kbd row 0 + portDValue |= (!palmIo.buttonCalender | (!palmIo.buttonAddress << 1) | (!palmIo.buttonTodo << 2) | (!palmIo.buttonNotes << 3)) ^ portDpolarity; + } + + if((requestedRow & 0x40) == 0){ + //kbd row 1 + portDValue |= (!palmIo.buttonUp | (!palmIo.buttonDown << 1)) ^ portDpolarity; + } + + if((requestedRow & 0x80) == 0){ + //kbd row 2 + portDValue |= (!palmIo.buttonPower | (!palmIo.buttonContrast << 1) | (!palmIo.buttonAddress << 3)) ^ portDpolarity; + } + + if(portDIrqEnable & portDValue & 0x01){ + //int 0 + setIprIsrBit(INT_INT0); + } + + if(portDIrqEnable & portDValue & 0x02){ + //int 1 + setIprIsrBit(INT_INT1); + } + + if(portDIrqEnable & portDValue & 0x04){ + //int 2 + setIprIsrBit(INT_INT2); + } + + if(portDIrqEnable & portDValue & 0x08){ + //int 3 + setIprIsrBit(INT_INT3); + } + + if(portDIrqPins & portDValue & 0x10){ + //irq 1 + setIprIsrBit(INT_IRQ1); + } + + if(portDIrqPins & portDValue & 0x20){ + //irq 2 + setIprIsrBit(INT_IRQ2); + } + + if(portDIrqPins & portDValue & 0x40){ + //irq 3 + setIprIsrBit(INT_IRQ3); + } + + if(portDIrqPins & portDValue & 0x80){ + //irq 6 + setIprIsrBit(INT_IRQ6); + } + + checkInterrupts(); +} + +static inline uint8_t getPortDValue(){ + uint8_t requestedRow = registerArrayRead8(PKDIR) & registerArrayRead8(PKDATA);//keys are requested on port k and read on port d + uint8_t portDValue = 0x00;//ports always read the chip pins even if they are set to output + uint8_t portDpolarity = registerArrayRead8(PDPOL); + uint8_t portDIrqEnable = registerArrayRead8(PDIRQEN); + + portDValue |= 0x80/*battery not dead bit*/; + + if(palmSdCard.inserted){ + portDValue |= 0x20; + } + + if((requestedRow & 0x20) == 0){ + //kbd row 0 + portDValue |= (!palmIo.buttonCalender | (!palmIo.buttonAddress << 1) | (!palmIo.buttonTodo << 2) | (!palmIo.buttonNotes << 3)) ^ portDpolarity; + } + + if((requestedRow & 0x40) == 0){ + //kbd row 1 + portDValue |= (!palmIo.buttonUp | (!palmIo.buttonDown << 1)) ^ portDpolarity; + } + + if((requestedRow & 0x80) == 0){ + //kbd row 2 + portDValue |= (!palmIo.buttonPower | (!palmIo.buttonContrast << 1) | (!palmIo.buttonAddress << 3)) ^ portDpolarity; + } + + return portDValue; +} + + uint32_t clk32Counter; double timer1CycleCounter; double timer2CycleCounter; @@ -533,7 +638,6 @@ bool cpuIsOn(){ return !((registerArrayRead16(PLLCR) & 0x0008) || lowPowerStopActive); } - int interruptAcknowledge(int intLevel){ int vectorOffset = registerArrayRead8(IVR); int vector; @@ -558,6 +662,9 @@ int interruptAcknowledge(int intLevel){ unsigned int getHwRegister8(unsigned int address){ switch(address){ + case PADATA: + return getPortDValue(); + //select between gpio or special function case PBSEL: case PCSEL: @@ -630,11 +737,23 @@ unsigned int getHwRegister32(unsigned int address){ void setHwRegister8(unsigned int address, unsigned int value){ switch(address){ + case PKDIR: + case PKDATA: + checkPortDInts(); + break; + case PDSEL: //write without the bottom 4 bits registerArrayWrite8(address, value & 0xF0); break; + case PDPOL: + case PDIRQEN: + case PDIRQEG: + //write without the top 4 bits + registerArrayWrite8(address, value & 0x0F); + break; + case IVR: //write without the bottom 3 bits registerArrayWrite8(address, value & 0xF8); @@ -666,7 +785,6 @@ void setHwRegister8(unsigned int address, unsigned int value){ case PEDIR: case PFDIR: case PJDIR: - case PKDIR: //pull up/down enable case PAPUEN: diff --git a/unimplementedFeatures.txt b/unimplementedFeatures.txt index 4886bfb..ffe4855 100644 --- a/unimplementedFeatures.txt +++ b/unimplementedFeatures.txt @@ -5,4 +5,6 @@ sysTrapPceNativeCall, ARM Emulator cpu32 table lookup opcodes PLL Control Register, Wake Select Peripheral Control Register, audio ppm mixing selection -System Control Register, 0xXXFFF000 all upper banks are registers mode \ No newline at end of file +System Control Register, 0xXXFFF000 all upper banks are registers mode +Port D level sensitive interrupts +Port D keyboard enable register