diff --git a/bugs/brokenLibretroPlatforms.txt b/bugs/brokenLibretroPlatforms.txt index e21c48f..b228908 100644 --- a/bugs/brokenLibretroPlatforms.txt +++ b/bugs/brokenLibretroPlatforms.txt @@ -1,9 +1,9 @@ -PSP classics/new haxchi(should work) xbox(don't know) xbox360(don't know) Fixed: +PSP msvc2010 msvc2003 remove old haxchi diff --git a/bugs/futureTimeline.txt b/bugs/futureTimeline.txt index 040b471..4b3d88d 100644 --- a/bugs/futureTimeline.txt +++ b/bugs/futureTimeline.txt @@ -1,4 +1,5 @@ -Sister projects with SquirrelJME: -https://github.com/XerTheSquirrel/SquirrelJME - Release at Christmas 17:00 GMT, 9:00 My time, 12:00 SquirrelJME devs time + + +Done: +Sister projects with SquirrelJME: https://github.com/XerTheSquirrel/SquirrelJME diff --git a/bugs/missingFunctions.txt b/bugs/missingFunctions.txt index a4faada..eb3540b 100644 --- a/bugs/missingFunctions.txt +++ b/bugs/missingFunctions.txt @@ -1,13 +1,12 @@ This is like unimplementedHardware.txt but only lists things that have functionality issues not accuracy issues. -Holding the buttons emulates pressing them like a turbo button(may be caused by the lack of sound emulation, a sound plays on app switch and may block the CPU while waiting for the button to release)(also may be because the minimum length of a button press is a whole frame) State manager goes bezerk and crashes when saving on android, also can't close the window or it won't open again(also only on Android) If there is no userdata-en-m515.ram on Android the emu won't create it(this is likely because theres no graceful exit being done on Android only goto home menu and kill process) -Theres no auto ROM installer app install hack needs to be removed when SD card works -double pressing power button issue +double pressing power button issue(better without PDKBEN but still not correct) Fixed: +Holding the buttons emulates pressing them like a turbo button(may be caused by the lack of sound emulation(wrong, sound works now))(may be because the minimum length of a button press is a whole frame(wrong, increasing the framerate doesn't change this behavior))(port d doesn't seem to be documented properly) 16 bpp mode is broken 64k app install limit device runs at around half speed for some reason(the SYSCLK divider was not scaled properly) diff --git a/bugs/regressions.txt b/bugs/regressions.txt index 46e5cb4..e2f23df 100644 --- a/bugs/regressions.txt +++ b/bugs/regressions.txt @@ -1,4 +1,3 @@ -Endian compatibility is broken(the CPU state needs to be standardized)(fixed again with musashi) - Fixed: +Endian compatibility is broken(the CPU state needs to be standardized)(fixed again with musashi and the other 68k core isn't used right now) RetroArch port crashes on exit(needed to check if environ_cb returned true, switched to libretro-common filestreams too) diff --git a/bugs/unimplementedHardware.txt b/bugs/unimplementedHardware.txt index c207ef9..7f51a09 100644 --- a/bugs/unimplementedHardware.txt +++ b/bugs/unimplementedHardware.txt @@ -23,7 +23,6 @@ power button must be pushed twice to turn the CPU back on(when debugging it work RxOverflow on SPI1, don't know if back or front of FIFO is overwritten on overflow(currently losing oldest entry) ICR POL(1,2,3,6) may flip the pin value as well as the interrupt, POL5 does not flip the INT5 pin though, this was confirmed with a hardware test(it doesnt seem to but there is instability on the pin when the SD card is plugged in, this may have to do with card detect also being a data line on the SD pinout) edge triggered INT* don't clear on write to ISR when masked in IMR(at least that seems to be the reason) -if a sound interrupt is triggered while the button interrupt is disabled the button interrupt will still trigger(in galax game) Cyclone will cause SIGSEGVs, don't know why yet PWM2 is not implemented don't know if flushing the PWM1 FIFO sets all the bytes to 0x00, or just sets the read pointer to the write pointer preserving the newest sample and making the size 0(readPtr = writePtr has significantly cleaner audio then 0ing it out though) @@ -36,20 +35,21 @@ MakePalmBitmap: Memory: SD card can't be read or written to by Palm OS unknown if DRAM bit expanded address space is used for CSC when its not an extension of CSD -there is conflicting information on wether the DRAM bit effects CSC, needs a test made +there is conflicting information on whether the DRAM bit effects CSC, needs a test made the unemulated chip selects(CSB1, CSC0/1) privilege violation interrupts will not be handled properly SED1376: swivelview register ADS7846: -verify chip select(no test has been done yet, put everything points to port g bit 2) +verify chip select(no test has been done yet, but everything points to port g bit 2) need to trigger a false PENIRQ interrupt on reading certain channels electrical noise on lines(conversions probably should have +-20 added to values)(probably no need for this, it works so theres no need to use less precise values) in the edge case that SPICLK2 is disabled while using ADS7846 and a 1 was the last bit shifted out 0s will still be shifted in Fixed: +if a sound interrupt is triggered while the button interrupt is disabled the button interrupt will still trigger(in galax game)(seems to be an issue with FIFOAV always = true hack and how INT_PWM1 needed to be cleared on read or write) SED1376 16 bpp mode is broken and crushed to the top of the screen audio can max out the resampler buffer, the max 1 FIFO sample can play is around 2.16 minutes(CLK32 / period(257) / clockDivider(16) / prescaler(128) / repeat(8))(257 * 16 * 128 * 8 / 32768=128.5 seconds)(safety check added, >= 1 second duty cycle is useless and will just make annoying cracks anyway) Cyclone CPU emulator is not working diff --git a/libretroBuildSystem/libretro.c b/libretroBuildSystem/libretro.c index 6368523..b7a080b 100644 --- a/libretroBuildSystem/libretro.c +++ b/libretroBuildSystem/libretro.c @@ -34,8 +34,8 @@ static uint16_t screenHeight; static uint16_t screenData[320 * 440]; static uint32_t emuFeatures; static bool useJoystickAsMouse; -static double touchCursorX; -static double touchCursorY; +static float touchCursorX; +static float touchCursorY; static void renderMouseCursor(int16_t screenX, int16_t screenY){ @@ -274,7 +274,10 @@ void retro_run(void){ palmInput.touchscreenTouched = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2); } else{ - //TODO use physical touchscreen of host device + //use RetroArch internal pointer + palmInput.touchscreenX = ((float)input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) / 0x7FFF + 1.0) / 2.0 * 159; + palmInput.touchscreenY = ((float)input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) / 0x7FFF + 1.0) / 2.0 * 219; + palmInput.touchscreenTouched = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED); } //dpad @@ -299,7 +302,7 @@ void retro_run(void){ //draw mouse if(useJoystickAsMouse) - renderMouseCursor(touchCursorX, touchCursorY); + renderMouseCursor(palmInput.touchscreenX, palmInput.touchscreenY); video_cb(screenData, screenWidth, screenHeight, screenWidth * sizeof(uint16_t)); audio_cb(palmAudio, AUDIO_SAMPLES_PER_FRAME); diff --git a/qtBuildSystem/Mu/mainwindow.cpp b/qtBuildSystem/Mu/mainwindow.cpp index 9983d34..542b773 100644 --- a/qtBuildSystem/Mu/mainwindow.cpp +++ b/qtBuildSystem/Mu/mainwindow.cpp @@ -193,7 +193,7 @@ void MainWindow::selectHomePath(){ //display void MainWindow::updateDisplay(){ if(emu.newFrameReady()){ - //video + //video, this is doing bilinear filitering in software, this is why the Qt port is broken on Android, move this to a new thread if possible ui->display->setPixmap(emu.getFramebuffer().scaled(ui->display->size().width(), ui->display->size().height(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); //audio @@ -213,7 +213,7 @@ void MainWindow::updateDisplay(){ //printLastRun(); } -//palm buttons +//Palm buttons void MainWindow::on_power_pressed(){ emu.emuInput.buttonPower = true; } diff --git a/src/emulator.c b/src/emulator.c index d0eb408..9ad4c01 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -197,7 +197,6 @@ uint64_t emulatorGetStateSize(void){ size += sizeof(uint32_t);//clk32Counter size += sizeof(uint64_t);//pctlrCpuClockDivider size += sizeof(uint16_t) * 2;//timerStatusReadAcknowledge - size += sizeof(uint32_t);//interruptEdgeTriggered size += sizeof(uint16_t) * 9;//RX 8 * 16 SPI1 FIFO, 1 index is for FIFO full size += sizeof(uint16_t) * 9;//TX 8 * 16 SPI1 FIFO, 1 index is for FIFO full size += sizeof(uint8_t) * 4;//spi1(R/T)x(Read/Write)Position @@ -301,8 +300,6 @@ bool emulatorSaveState(buffer_t buffer){ offset += sizeof(uint16_t); writeStateValue16(buffer.data + offset, timerStatusReadAcknowledge[1]); offset += sizeof(uint16_t); - writeStateValue32(buffer.data + offset, interruptEdgeTriggered); - offset += sizeof(uint32_t); //SPI1 for(index = 0; index < 9; index++){ @@ -460,8 +457,6 @@ bool emulatorLoadState(buffer_t buffer){ offset += sizeof(uint16_t); timerStatusReadAcknowledge[1] = readStateValue16(buffer.data + offset); offset += sizeof(uint16_t); - interruptEdgeTriggered = readStateValue32(buffer.data + offset); - offset += sizeof(uint32_t); //SPI1 for(index = 0; index < 9; index++){ diff --git a/src/emulator.h b/src/emulator.h index 12de9af..a935ce6 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -108,7 +108,7 @@ typedef struct{ }misc_hw_t; //config options -#define EMU_FPS 60 +#define EMU_FPS 30 #define EMU_SYSCLK_PRECISION 2000000//the amount of cycles to run before adding SYSCLKs, higher = faster, higher values may skip timer events and lower audio accuracy #define AUDIO_SAMPLE_RATE 48000 #define AUDIO_CLOCK_RATE 235929600//smallest amount of time a second can be split into:(2.0 * (14.0 * (255 + 1.0) + 15 + 1.0)) * 32768 == 235929600, used to convert the variable timing of SYSCLK and CLK32 to a fixed location in the current frame 0<->AUDIO_END_OF_FRAME diff --git a/src/hardwareRegisters.c b/src/hardwareRegisters.c index 6caedbe..e7888b2 100644 --- a/src/hardwareRegisters.c +++ b/src/hardwareRegisters.c @@ -22,7 +22,6 @@ uint32_t clk32Counter; double pctlrCpuClockDivider; double timerCycleCounter[2]; uint16_t timerStatusReadAcknowledge[2]; -uint32_t interruptEdgeTriggered; uint16_t spi1RxFifo[9]; uint16_t spi1TxFifo[9]; uint8_t spi1RxReadPosition; @@ -202,18 +201,17 @@ static void checkInterrupts(void){ } static void checkPortDInterrupts(void){ - uint8_t portDInputValues = getPortDInputPinValues(); - uint8_t portDInputValuesWithPolarity = portDInputValues ^ registerArrayRead8(PDPOL); - uint8_t portDDir = registerArrayRead8(PDDIR); - uint8_t portDKeyboardEnable = registerArrayRead8(PDKBEN); + uint8_t portDValue = getPortDValue(); uint8_t portDIrqPins = ~registerArrayRead8(PDSEL); uint8_t portDEdgeTriggered = registerArrayRead8(PDIRQEG); uint16_t interruptControlRegister = registerArrayRead16(ICR); - uint8_t triggeredIntXInterrupts = portDInputValuesWithPolarity & registerArrayRead8(PDIRQEN) & ~portDDir; + uint8_t triggeredIntXInterrupts = portDValue & registerArrayRead8(PDIRQEN); + //bool pllOn = pllIsOn(); //On hardware PDIRQEG seems not to actually work at all(CPUID:0x57000000), unimplementedHardware.txt //the correct behavior is not being used right now because it doesnt seem to happen on the actual device + /* if(triggeredIntXInterrupts & 0x01) setIprIsrBit(INT_INT0); else @@ -233,107 +231,63 @@ static void checkPortDInterrupts(void){ setIprIsrBit(INT_INT3); else clearIprIsrBit(INT_INT3); - - /* - if(triggeredIntXInterrupts & 0x01){ - if(!(portDEdgeTriggered & 0x01) || (!(interruptEdgeTriggered & INT_INT0) && pllIsOn())) - setIprIsrBit(INT_INT0); - interruptEdgeTriggered |= INT_INT0; - } - else{ - if(!(portDEdgeTriggered & 0x01)) - clearIprIsrBit(INT_INT0); - interruptEdgeTriggered &= ~INT_INT0; - } - - if(triggeredIntXInterrupts & 0x02){ - if(!(portDEdgeTriggered & 0x02) || (!(interruptEdgeTriggered & INT_INT1) && pllIsOn())) - setIprIsrBit(INT_INT1); - interruptEdgeTriggered |= INT_INT1; - } - else{ - if(!(portDEdgeTriggered & 0x02)) - clearIprIsrBit(INT_INT1); - interruptEdgeTriggered &= ~INT_INT1; - } - - if(triggeredIntXInterrupts & 0x04){ - if(!(portDEdgeTriggered & 0x04) || (!(interruptEdgeTriggered & INT_INT2) && pllIsOn())) - setIprIsrBit(INT_INT2); - interruptEdgeTriggered |= INT_INT2; - } - else{ - if(!(portDEdgeTriggered & 0x04)) - clearIprIsrBit(INT_INT2); - interruptEdgeTriggered &= ~INT_INT2; - } - - if(triggeredIntXInterrupts & 0x08){ - if(!(portDEdgeTriggered & 0x08) || (!(interruptEdgeTriggered & INT_INT3) && pllIsOn())) - setIprIsrBit(INT_INT3); - interruptEdgeTriggered |= INT_INT3; - } - else{ - if(!(portDEdgeTriggered & 0x08)) - clearIprIsrBit(INT_INT3); - interruptEdgeTriggered &= ~INT_INT3; - } */ + if(triggeredIntXInterrupts & 0x01/* && (!(portDEdgeTriggered & 0x01) || pllOn)*/) + setIprIsrBit(INT_INT0); + else if(!(portDEdgeTriggered & 0x01)) + clearIprIsrBit(INT_INT0); + + if(triggeredIntXInterrupts & 0x02/* && (!(portDEdgeTriggered & 0x02) || pllOn)*/) + setIprIsrBit(INT_INT1); + else if(!(portDEdgeTriggered & 0x02)) + clearIprIsrBit(INT_INT1); + + if(triggeredIntXInterrupts & 0x04/* && (!(portDEdgeTriggered & 0x04) || pllOn)*/) + setIprIsrBit(INT_INT2); + else if(!(portDEdgeTriggered & 0x04)) + clearIprIsrBit(INT_INT2); + + if(triggeredIntXInterrupts & 0x08/* && (!(portDEdgeTriggered & 0x08) || pllOn)*/) + setIprIsrBit(INT_INT3); + else if(!(portDEdgeTriggered & 0x08)) + clearIprIsrBit(INT_INT3); + //IRQ1, polarity set in ICR - if(portDIrqPins & ~portDDir & 0x10 && !!(portDInputValues & 0x10) == !!(interruptControlRegister & 0x8000)){ - if(!(interruptControlRegister & 0x0800) || !(interruptEdgeTriggered & INT_IRQ1)) - setIprIsrBit(INT_IRQ1); - interruptEdgeTriggered |= INT_IRQ1; - } - else{ - if(!(interruptControlRegister & 0x0800)) - clearIprIsrBit(INT_IRQ1); - interruptEdgeTriggered &= ~INT_IRQ1; - } + if(portDIrqPins & 0x10 && !!(portDValue & 0x10) == !!(interruptControlRegister & 0x8000)) + setIprIsrBit(INT_IRQ1); + else if(!(interruptControlRegister & 0x0800)) + clearIprIsrBit(INT_IRQ1); //IRQ2, polarity set in ICR - if(portDIrqPins & ~portDDir & 0x20 && !!(portDInputValues & 0x20) == !!(interruptControlRegister & 0x4000)){ - if(!(interruptControlRegister & 0x0400) || !(interruptEdgeTriggered & INT_IRQ2)) - setIprIsrBit(INT_IRQ2); - interruptEdgeTriggered |= INT_IRQ2; - } - else{ - if(!(interruptControlRegister & 0x0400)) - clearIprIsrBit(INT_IRQ2); - interruptEdgeTriggered &= ~INT_IRQ2; - } + if(portDIrqPins & 0x20 && !!(portDValue & 0x20) == !!(interruptControlRegister & 0x4000)) + setIprIsrBit(INT_IRQ2); + else if(!(interruptControlRegister & 0x0400)) + clearIprIsrBit(INT_IRQ2); //IRQ3, polarity set in ICR - if(portDIrqPins & ~portDDir & 0x40 && !!(portDInputValues & 0x40) == !!(interruptControlRegister & 0x2000)){ - if(!(interruptControlRegister & 0x0200) || !(interruptEdgeTriggered & INT_IRQ3)) - setIprIsrBit(INT_IRQ3); - interruptEdgeTriggered |= INT_IRQ3; - } - else{ - if(!(interruptControlRegister & 0x0200)) - clearIprIsrBit(INT_IRQ3); - interruptEdgeTriggered &= ~INT_IRQ3; - } + if(portDIrqPins & 0x40 && !!(portDValue & 0x40) == !!(interruptControlRegister & 0x2000)) + setIprIsrBit(INT_IRQ3); + else if(!(interruptControlRegister & 0x0200)) + clearIprIsrBit(INT_IRQ3); //IRQ6, polarity set in ICR - if(portDIrqPins & ~portDDir & 0x80 && !!(portDInputValues & 0x80) == !!(interruptControlRegister & 0x1000)){ - if(!(interruptControlRegister & 0x0100) || !(interruptEdgeTriggered & INT_IRQ6)) - setIprIsrBit(INT_IRQ6); - interruptEdgeTriggered |= INT_IRQ6; - } - else{ - if(!(interruptControlRegister & 0x0100)) - clearIprIsrBit(INT_IRQ6); - interruptEdgeTriggered &= ~INT_IRQ6; - } + if(portDIrqPins & 0x80 && !!(portDValue & 0x80) == !!(interruptControlRegister & 0x1000)) + setIprIsrBit(INT_IRQ6); + else if(!(interruptControlRegister & 0x0100)) + clearIprIsrBit(INT_IRQ6); //active low/off level triggered interrupt - //The SELx, POLx, IQENx, and IQEGx bits have no effect on the functionality of KBENx - if(portDKeyboardEnable & ~portDInputValues & ~portDDir) + //The SELx, POLx, IQENx, and IQEGx bits have no effect on the functionality of KBENx, 10.4.5.8 Port D Keyboard Enable Register MC68VZ328UM.pdf + //the above seems like a lie, 10.4.4 Port D Operation MC68VZ328UM.pdf + //completely removing PDKBEN is not accurate but makes the buttons function properly + //I am fairly sure that port d is not documented properly by the data sheet so Im going with what works properly right now + /* + if(registerArrayRead8(PDKBEN) & portDValue) setIprIsrBit(INT_KB); else clearIprIsrBit(INT_KB); + */ checkInterrupts(); } @@ -659,6 +613,13 @@ void setHwRegister8(uint32_t address, uint8_t value){ checkPortDInterrupts(); break; + case PDDATA: + case PDKBEN: + //can change interrupt state + registerArrayWrite8(address, value); + checkPortDInterrupts(); + break; + case PFSEL: //this is the clock output pin for the SED1376, if its disabled so is the LCD controller registerArrayWrite8(PFSEL, value); @@ -721,14 +682,10 @@ void setHwRegister8(uint32_t address, uint8_t value){ //port data value, nothing known is attached to port case PCDATA: - case PDDATA: case PEDATA: case PFDATA: case PJDATA: - //misc port config - case PDKBEN: - //dragonball LCD controller, not attached to anything in Palm m515 case LCKCON: //simple write, no actions needed @@ -1075,7 +1032,6 @@ void resetHwRegisters(void){ timerCycleCounter[1] = 0.0; timerStatusReadAcknowledge[0] = 0x0000; timerStatusReadAcknowledge[1] = 0x0000; - interruptEdgeTriggered = 0x00000000; memset(spi1RxFifo, 0x00, sizeof(spi1RxFifo)); memset(spi1TxFifo, 0x00, sizeof(spi1TxFifo)); spi1RxReadPosition = 0; diff --git a/src/hardwareRegisters.h b/src/hardwareRegisters.h index 88643d2..d7876bf 100644 --- a/src/hardwareRegisters.h +++ b/src/hardwareRegisters.h @@ -70,7 +70,6 @@ extern uint32_t clk32Counter; extern double pctlrCpuClockDivider; extern double timerCycleCounter[]; extern uint16_t timerStatusReadAcknowledge[]; -extern uint32_t interruptEdgeTriggered; extern uint16_t spi1RxFifo[]; extern uint16_t spi1TxFifo[]; extern uint8_t spi1RxReadPosition;