]> localhost Git - WindEmu.git/commitdiff
fix broken timekeeping on 5mx and touch panel on 5mx
authorAsh Wolf <ninji@wuffs.org>
Wed, 25 Dec 2019 19:25:34 +0000 (19:25 +0000)
committerAsh Wolf <ninji@wuffs.org>
Wed, 25 Dec 2019 19:25:34 +0000 (19:25 +0000)
README.md
WindCore/arm710.cpp
WindCore/arm710.h
WindCore/etna.cpp
WindCore/windermere.cpp

index 6efb1ad47501cf1493f7afa967c67c38170424d2..05443616186131d80dad3e7c7f45b79622df97db 100644 (file)
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ Psion 5mx (EPOC R5) features:
 
 - ✅ LCD: partially implemented
 - ✅ Keyboard: implemented
-- â\9d\8c Touch panel: not implemented
+- â\9c\85 Touch panel: implemented
 - ❌ Audio: not implemented
 - ❌ Serial/UART support: stubbed out
 - ❌ ETNA (PCMCIA/CompactFlash): mostly stubbed out
@@ -20,7 +20,7 @@ Psion 5mx (EPOC R5) features:
 Oregon Scientific Osaris (EPOC R4) features:
 
 - ✅ LCD: implemented
-- ✅ Keyboard: mostly implemented (key mappings wrong)
+- ✅ Keyboard: implemented (somewhat buggy)
 - ✅ Touch panel: implemented
 - ❌ Audio: not implemented
 - ❌ Serial/UART support: stubbed out
index bbb6401f16673aa04a87b55e8fec3058e271bd4c..c9fc6263eed066b6c07ce1122d45574154576295 100644 (file)
@@ -161,6 +161,8 @@ uint32_t ARM710::executeInstruction(uint32_t i) {
                cycles += execSingleDataSwap(extract1(i,22), extract(i,19,16), extract(i,15,12), extract(i,3,0));
        else if ((i & 0x0F8000F0) == 0x00000090)
                cycles += execMultiply(extract(i,21,20), extract(i,19,16), extract(i,15,12), extract(i,11,8), extract(i,3,0));
+       else if ((i & 0x0F8000F0) == 0x00800090 && isTVersion)
+               cycles += execMultiplyLong(extract(i,22,20), extract(i,19,16), extract(i,15,12), extract(i,11,8), extract(i,3,0));
        else if ((i & 0x0C000000) == 0x00000000)
                cycles += execDataProcessing(extract1(i,25), extract(i,24,21), extract1(i,20), extract(i,19,16), extract(i,15,12), extract(i,11,0));
        else
@@ -399,6 +401,35 @@ uint32_t ARM710::execMultiply(uint32_t AS, uint32_t Rd, uint32_t Rn, uint32_t Rs
        return 0;
 }
 
+// ARM710T only!
+uint32_t ARM710::execMultiplyLong(uint32_t UAS, uint32_t RdHi, uint32_t RdLo, uint32_t Rs, uint32_t Rm)
+{
+       // no need for R15 fuckery
+       // datasheet says it's not allowed here
+       uint64_t result;
+       if (UAS & 4) // unsigned
+               result = (uint64_t)GPRs[Rm] * (uint64_t)GPRs[Rs];
+       else // signed
+               result = (uint64_t)((int64_t)GPRs[Rm] * (int64_t)GPRs[Rs]);
+
+       if (UAS & 2) {
+               // accumulate
+               uint64_t addend = (uint64_t)GPRs[RdLo] | ((uint64_t)GPRs[RdHi] << 32);
+               result += addend;
+       }
+
+       if (UAS & 1) {
+               CPSR &= ~(CPSR_N | CPSR_Z);
+               CPSR |= result ? 0 : CPSR_Z;
+               CPSR |= (result & 0x8000000000000000) ? CPSR_N : 0;
+       }
+
+       GPRs[RdLo] = result & 0xFFFFFFFF;
+       GPRs[RdHi] = result >> 32;
+
+       return 0;
+}
+
 uint32_t ARM710::execSingleDataSwap(bool B, uint32_t Rn, uint32_t Rd, uint32_t Rm)
 {
        auto valueSize = B ? V8 : V32;
index c8179c66ff3038b1fc062360949407e286405a6e..c6cf91f3d6a9f6766655951332683edbcc06a60b 100644 (file)
@@ -287,6 +287,7 @@ private:
 
        uint32_t execDataProcessing(bool I, uint32_t Opcode, bool S, uint32_t Rn, uint32_t Rd, uint32_t Operand2);
        uint32_t execMultiply(uint32_t AS, uint32_t Rd, uint32_t Rn, uint32_t Rs, uint32_t Rm);
+       uint32_t execMultiplyLong(uint32_t UAS, uint32_t RdHi, uint32_t RdLo, uint32_t Rs, uint32_t Rm);
        uint32_t execSingleDataSwap(bool B, uint32_t Rn, uint32_t Rd, uint32_t Rm);
        uint32_t execSingleDataTransfer(uint32_t IPUBWL, uint32_t Rn, uint32_t Rd, uint32_t offset);
        uint32_t execBlockDataTransfer(uint32_t PUSWL, uint32_t Rn, uint32_t registerList);
index 2267db76c87968a6acd21363ec5c8ae3568b465a..1e7c75be4749c437858fecdc6acd95e2262c0f62 100644 (file)
@@ -79,14 +79,14 @@ Etna::Etna(ARM710 *owner) {
         chk ^= prom[i];
 
     // EPOC is expecting 66
-    prom[0x7F] = chk ^ 66;
+       prom[0x7F] = chk ^ 66;
 }
 
 
 uint32_t Etna::readReg8(uint32_t reg)
 {
-    if (!promReadActive)
-        printf("ETNA readReg8: reg=%s @ pc=%08x,lr=%08x\n", nameReg(reg), owner->getGPR(15) - 4, owner->getGPR(14));
+//    if (!promReadActive)
+//             owner->log("ETNA readReg8: reg=%s @ pc=%08x,lr=%08x", nameReg(reg), owner->getGPR(15) - 4, owner->getGPR(14));
     switch (reg) {
     case regIntClear: return 0;
     case regSktVarA0: return 1; // will store some status flags
@@ -100,14 +100,14 @@ uint32_t Etna::readReg8(uint32_t reg)
 uint32_t Etna::readReg32(uint32_t reg)
 {
     // may be able to remove this, p. sure Etna is byte addressing only
-    printf("ETNA readReg32: reg=%x\n", reg);
+       owner->log("ETNA readReg32: reg=%x", reg);
     return 0xFFFFFFFF;
 }
 
 void Etna::writeReg8(uint32_t reg, uint8_t value)
 {
     if (!promReadActive)
-        printf("ETNA writeReg8: reg=%s value=%02x @ pc=%08x,lr=%08x\n", nameReg(reg), value, owner->getGPR(15) - 4, owner->getGPR(14));
+               owner->log("ETNA writeReg8: reg=%s value=%02x @ pc=%08x,lr=%08x", nameReg(reg), value, owner->getGPR(15) - 4, owner->getGPR(14));
     switch (reg) {
     case regIntClear: pendingInterrupts &= ~value; break;
     case regWake1: wake1 = value; break;
@@ -118,7 +118,7 @@ void Etna::writeReg8(uint32_t reg, uint8_t value)
 void Etna::writeReg32(uint32_t reg, uint32_t value)
 {
     // may be able to remove this, p. sure Etna is byte addressing only
-    printf("ETNA writeReg32: reg=%x value=%08x\n", reg, value);
+       owner->log("ETNA writeReg32: reg=%x value=%08x", reg, value);
 }
 
 void Etna::setPromBit0High()
index 335d3eb6b60dcd0a6c51c9b34b2e6dc3e9189c47..2de212871e78ac40a462d3f1c90a72dc816b13e0 100644 (file)
@@ -76,10 +76,8 @@ uint32_t Emulator::readReg32(uint32_t reg) {
                // as per 5000A7B0 in 5mx rom
                uint16_t ssiValue = 0;
                switch (lastSSIRequest) {
-//             case 0x9093: ssiValue = (uint16_t)(1156 - (touchY * 3.96)); break;
-//             case 0xD0D3: ssiValue = (uint16_t)(2819 - (touchX * 3.91)); break;
-               case 0x9093: ssiValue = (uint16_t)(1156 - (touchY * 3.96)); break;
-               case 0xD0D3: ssiValue = (uint16_t)(1276 + (touchX * 3.91)); break;
+               case 0xD0D3: ssiValue = (uint16_t)(50 + (touchX * 5.7)); break;
+               case 0x9093: ssiValue = (uint16_t)(3834 - (touchY * 13.225)); break;
                case 0xA4A4: ssiValue = 3100; break; // MainBattery
                case 0xE4E4: ssiValue = 3100; break; // BackupBattery
                }
@@ -97,11 +95,11 @@ uint32_t Emulator::readReg32(uint32_t reg) {
                return 0;
     } else if (reg == RTCDRL) {
         uint16_t v = rtc & 0xFFFF;
-//        printf("RTCDRL: %04x\n", v);
+//             log("RTCDRL: %04x", v);
         return v;
     } else if (reg == RTCDRU) {
         uint16_t v = rtc >> 16;
-//        printf("RTCDRU: %04x\n", v);
+//             log("RTCDRU: %04x", v);
         return v;
     } else if (reg == KSCAN) {
         return kScan;
@@ -207,6 +205,14 @@ void Emulator::writeReg32(uint32_t reg, uint32_t value) {
                tc2.load(value);
        } else if (reg == TC2EOI) {
                pendingInterrupts &= ~(1 << TC2OI);
+       } else if (reg == RTCDRL) {
+               rtc &= 0xFFFF0000;
+               rtc |= (value & 0xFFFF);
+               log("RTC write lower: %04x", value);
+       } else if (reg == RTCDRU) {
+               rtc &= 0x0000FFFF;
+               rtc |= (value & 0xFFFF) << 16;
+               log("RTC write upper: %04x", value);
        } else {
 //             printf("RegWrite32 unknown:: pc=%08x reg=%03x value=%08x\n", getGPR(15)-4, reg, value);
        }
@@ -523,7 +529,7 @@ void Emulator::debugPC(uint32_t pc) {
                case 15: n = "EButton3Up"; break;
                case 16: n = "ESwitchOff"; break;
                }
-               log("EVENT %s: tick=%d params=%08x,%08x", n, evtTick, evtParamA, evtParamB);
+               log("EVENT %s: tick=%d params=%d,%d", n, evtTick, evtParamA, evtParamB);
        }
 }