]> localhost Git - WindEmu.git/commitdiff
make some things a bit more optimised for web usage
authorAsh Wolf <ninji@wuffs.org>
Thu, 26 Dec 2019 00:19:37 +0000 (00:19 +0000)
committerAsh Wolf <ninji@wuffs.org>
Thu, 26 Dec 2019 00:19:37 +0000 (00:19 +0000)
WindCore/arm710.cpp
WindCore/arm710.h
WindCore/clps7111.cpp
WindCore/emubase.h
WindCore/hardware.h
WindCore/windermere.cpp
WindWasm/build.sh
WindWasm/main.cpp

index c9fc6263eed066b6c07ce1122d45574154576295..5d804d3d9e6c3589177c4a09259419274adb5a23 100644 (file)
@@ -664,15 +664,19 @@ uint32_t ARM710::execCP15RegisterTransfer(uint32_t CPOpc, bool L, uint32_t CRn,
                case 5:
                        if (isTVersion)
                                cp15_faultStatus = what;
+#ifdef ARM710T_TLB
                        else
                                flushTlb();
+#endif
                        break;
                case 6:
                        if (isTVersion)
                                cp15_faultAddress = what;
+#ifdef ARM710T_TLB
                        else
                                flushTlb(what);
                        break;
+#endif
                case 7:
 #ifdef ARM710T_CACHE
                        clearCache();
@@ -680,12 +684,14 @@ uint32_t ARM710::execCP15RegisterTransfer(uint32_t CPOpc, bool L, uint32_t CRn,
 #endif
                        break;
                case 8: {
+#ifdef ARM710T_TLB
                        if (isTVersion) {
                                if (CPOpc == 1)
                                        flushTlb(what);
                                else
                                        flushTlb();
                        }
+#endif
                        break;
                }
                }
@@ -900,6 +906,7 @@ ARM710::MMUFault ARM710::writeVirtual(uint32_t value, uint32_t virtAddr, ValueSi
 
 
 // TLB
+#ifdef ARM710T_TLB
 void ARM710::flushTlb() {
        for (TlbEntry &e : tlb)
                e = {0, 0, 0, 0};
@@ -912,21 +919,28 @@ void ARM710::flushTlb(uint32_t virtAddr) {
                }
        }
 }
+#endif
 
 ARM710::TlbEntry *ARM710::_allocateTlbEntry(uint32_t addrMask, uint32_t addr) {
+#ifdef ARM710T_TLB
        TlbEntry *entry = &tlb[nextTlbIndex];
+       nextTlbIndex = (nextTlbIndex + 1) % TlbSize;
+#else
+       TlbEntry *entry = &singleTlbEntry;
+#endif
        entry->addrMask = addrMask;
        entry->addr = addr & addrMask;
-       nextTlbIndex = (nextTlbIndex + 1) % TlbSize;
        return entry;
 }
 
 variant<ARM710::TlbEntry *, ARM710::MMUFault> ARM710::translateAddressUsingTlb(uint32_t virtAddr, TlbEntry *useMe) {
+#ifdef ARM710T_TLB
        // first things first, do we have a matching entry in the TLB?
        for (TlbEntry &e : tlb) {
                if (e.addrMask && (virtAddr & e.addrMask) == e.addr)
                        return &e;
        }
+#endif
 
        // no, so do a page table walk
        TlbEntry *entry;
index c6cf91f3d6a9f6766655951332683edbcc06a60b..cb85566824d76cc3c1bf4b4e706b0565610c4a21 100644 (file)
@@ -18,6 +18,7 @@ using namespace std;
 
 // Speedhacks:
 //#define ARM710T_CACHE
+//#define ARM710T_TLB
 
 typedef optional<uint32_t> MaybeU32;
 
@@ -87,7 +88,9 @@ public:
 #ifdef ARM710T_CACHE
                clearCache();
 #endif
+#ifdef ARM710T_TLB
                flushTlb();
+#endif
        }
 
        void setProcessorID(uint32_t v) { cp15_id = v; }
@@ -239,16 +242,20 @@ private:
                return (MMUFault)(baseFault | (isPage ? 2 : 0) | (domain << 4) | ((uint64_t)virtAddr << 32));
        }
 
-       enum { TlbSize = 64 };
        struct TlbEntry { uint32_t addrMask, addr, lv1Entry, lv2Entry; };
+#ifdef ARM710T_TLB
+       enum { TlbSize = 64 };
        TlbEntry tlb[TlbSize];
        int nextTlbIndex = 0;
 
        void flushTlb();
        void flushTlb(uint32_t virtAddr);
-       variant<TlbEntry *, MMUFault> translateAddressUsingTlb(uint32_t virtAddr, TlbEntry *useMe=nullptr);
-       TlbEntry *_allocateTlbEntry(uint32_t addrMask, uint32_t addr);
+#else
+       TlbEntry singleTlbEntry;
+#endif 
 
+       TlbEntry *_allocateTlbEntry(uint32_t addrMask, uint32_t addr);
+       variant<TlbEntry *, MMUFault> translateAddressUsingTlb(uint32_t virtAddr, TlbEntry *useMe=nullptr);
        static uint32_t physAddrFromTlbEntry(TlbEntry *tlbEntry, uint32_t virtAddr);
        MMUFault checkAccessPermissions(TlbEntry *entry, uint32_t virtAddr, bool isWrite) const;
 
index af98d79492d4fbf2e558fbc450f8838a44afbc48..618e54606aeece8657a4ab0d0b6c39030f0cedb7 100644 (file)
@@ -147,12 +147,14 @@ void Emulator::writeReg8(uint32_t reg, uint8_t value) {
 void Emulator::writeReg32(uint32_t reg, uint32_t value) {
        if (reg == SYSCON1) {
                kScan = value & 0xF;
-               tc1.config = Timer::ENABLED; // always on with PS-7111!
-               if (value & 0x10) tc1.config |= Timer::PERIODIC;
-               if (value & 0x20) tc1.config |= Timer::MODE_512KHZ;
-               tc2.config = Timer::ENABLED;
-               if (value & 0x40) tc2.config |= Timer::PERIODIC;
-               if (value & 0x80) tc2.config |= Timer::MODE_512KHZ;
+               uint8_t tc1cfg = Timer::ENABLED; // always on with PS-7111!
+               if (value & 0x10) tc1cfg |= Timer::PERIODIC;
+               if (value & 0x20) tc1cfg |= Timer::MODE_512KHZ;
+               uint8_t tc2cfg = Timer::ENABLED;
+               if (value & 0x40) tc2cfg |= Timer::PERIODIC;
+               if (value & 0x80) tc2cfg |= Timer::MODE_512KHZ;
+               tc1.setConfig(tc1cfg);
+               tc2.setConfig(tc2cfg);
        } else if (reg == INTMR1) {
                interruptMask &= 0xFFFF0000;;
                interruptMask |= (value & 0xFFFF);
@@ -277,6 +279,8 @@ void Emulator::configure() {
        tc2.clockSpeed = CLOCK_SPEED;
 
        nextTickAt = TICK_INTERVAL;
+       tc1.nextTickAt = tc1.tickInterval();
+       tc2.nextTickAt = tc2.tickInterval();
        rtc = getRTC();
 
        reset();
index a5a6f7084e4d590641cd232ecbc18a3d7df0b377..ae35d9d8434642a142d2f9c6ca6ad6bbed9ddee7 100644 (file)
@@ -103,7 +103,9 @@ enum EpocKey {
 class EmuBase : public ARM710
 {
 protected:
+#ifndef __EMSCRIPTEN__
        std::unordered_set<uint32_t> _breakpoints;
+#endif
        int64_t passedCycles = 0;
        int64_t nextTickAt = 0;
        uint8_t readKeyboard(int kScan);
@@ -127,7 +129,9 @@ public:
        virtual void setKeyboardKey(EpocKey key, bool value) = 0;
        virtual void updateTouchInput(int32_t x, int32_t y, bool down) = 0;
 
+#ifndef __EMSCRIPTEN__
        std::unordered_set<uint32_t> &breakpoints() { return _breakpoints; }
+#endif
        uint64_t currentCycles() const { return passedCycles; }
 };
 
index c1857ae5632ee4979a1f19208a0c5967301ff011..02ac9485ed9eb1974803cb9eb6ac3deaab3ca4e2 100644 (file)
@@ -10,7 +10,7 @@ struct Timer {
                PERIODIC = 1<<6,
                ENABLED = 1<<7
        };
-    int64_t lastTicked;
+    int64_t nextTickAt;
        uint8_t config;
        uint32_t interval;
        int32_t value;
@@ -23,9 +23,14 @@ struct Timer {
                interval = lval;
                value = lval;
        }
+       void setConfig(uint8_t cval) {
+               nextTickAt -= tickInterval();
+               config = cval;
+               nextTickAt += tickInterval();
+       }
     bool tick(int64_t cycles) {
-               if (cycles >= (lastTicked + tickInterval())) {
-                       lastTicked += tickInterval();
+               if (cycles >= nextTickAt) {
+                       nextTickAt += tickInterval();
 
                        if (config & ENABLED) {
                                --value;
index 7ca6a8c1fa198b0ef7b698754cd63a83d726fc1c..41bbe708a04151ed6844f5946707a5df43d1cd2d 100644 (file)
@@ -115,9 +115,9 @@ void Emulator::writeReg8(uint32_t reg, uint8_t value) {
        } else if ((reg & 0xF00) == 0x700) {
                uart2.writeReg8(reg & 0xFF, value);
        } else if (reg == TC1CTRL) {
-               tc1.config = value;
+               tc1.setConfig(value);
        } else if (reg == TC2CTRL) {
-               tc2.config = value;
+               tc2.setConfig(value);
        } else if (reg == PADR) {
                uint32_t oldPorts = portValues;
                portValues &= 0x00FFFFFF;
@@ -364,6 +364,8 @@ void Emulator::configure() {
        tc2.clockSpeed = CLOCK_SPEED;
 
        nextTickAt = TICK_INTERVAL;
+       tc1.nextTickAt = tc1.tickInterval();
+       tc2.nextTickAt = tc2.tickInterval();
        rtc = getRTC();
 
        reset();
@@ -413,22 +415,25 @@ void Emulator::executeUntil(int64_t cycles) {
                // what's running?
                if (halted) {
                        // keep the clock moving
-                       passedCycles++;
+                       // when does the next earliest thing happen?
+                       // this stops us from spinning needlessly
+                       int64_t nextEvent = nextTickAt;
+                       if (tc1.nextTickAt < nextEvent) nextEvent = tc1.nextTickAt;
+                       if (tc2.nextTickAt < nextEvent) nextEvent = tc2.nextTickAt;
+                       if (cycles < nextEvent) nextEvent = cycles;
+                       passedCycles = nextEvent;
                } else {
                        if (auto v = virtToPhys(getGPR(15) - 0xC); v.has_value() && instructionReady())
                                debugPC(v.value());
                        passedCycles += tick();
 
+#ifndef __EMSCRIPTEN__
                        uint32_t new_pc = getGPR(15) - 0xC;
                        if (_breakpoints.find(new_pc) != _breakpoints.end()) {
                                log("⚠️ Breakpoint triggered at %08x!", new_pc);
                                return;
                        }
-                       if (new_pc >= 0x80000000 && new_pc <= 0x90000000) {
-                               log("BAD PC %08x!!", new_pc);
-                               logPcHistory();
-                               return;
-                       }
+#endif
                }
        }
 }
index fb52887481d1ba94a84825daada3af129790ae83..00aa9d80f63c12e945f5b27df5aa55e99a91d4ec 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-FLAGS="-O3 --profiling -s WASM_OBJECT_FILES=0 -std=c++17"
+FLAGS="-O3 --profiling -g -s WASM_OBJECT_FILES=0 -std=c++17"
 
 mkdir -p obj
 for i in arm710 emubase etna windermere; do emcc -c $FLAGS -o obj/$i.o ../WindCore/$i.cpp; done
index b785226ee782e69bebb15ac54d366a0db51d5e67..c05ba6774586a06496b10af0205a4c25625a27cf 100644 (file)
@@ -120,15 +120,8 @@ int main(int argc, char **argv) {
                printf("SDL_SetVideoMode failed: %s\n", SDL_GetError());
                return 1;
        }
-       // window = SDL_CreateWindow(
-       //      "WindEmu",
-       //      SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
-       //      emu->getDigitiserWidth(), emu->getDigitiserHeight(),
-       //      0);
-       // if (window == NULL) {
-       //      printf("SDL_CreateWindow failed: %s\n", SDL_GetError());
-       //      return 1;
-       // }
+
+       EM_ASM("SDL.defaults.copyOnLock = false; SDL.defaults.discardOnLock = true; SDL.defaults.opaqueFrontBuffer = false;");
 
        emscripten_set_main_loop(&emuEventLoop, 64, 1);