74 lines
2.2 KiB
Diff
74 lines
2.2 KiB
Diff
# UNDF: UNDF-2026-000001057
|
|
# UNDF: UNDF-2026-XXXXXXXXX
|
|
--- a/src/hardware.cpp
|
|
+++ b/src/hardware.cpp
|
|
@@ -1,6 +1,8 @@
|
|
#include "sysdeps.h"
|
|
#include "hardware.h"
|
|
+#include <algorithm>
|
|
+#include <vector>
|
|
#include "cpu_emulation.h"
|
|
#include "memory-uae.h"
|
|
#include "icio.h"
|
|
@@ -62,6 +64,21 @@ enum {iMFP = 0, iMMU, iIKBD, iMIDI, iFDC, iRTC, iIDE, iDSP, iBLITTER, iVIDEL,
|
|
/* the iITEMS must be the last one in the enum */
|
|
iITEMS};
|
|
|
|
+/*
|
|
+ * Sorted dispatch table for O(log D) binary-search lookup.
|
|
+ * Populated by HWInit() after all devices are constructed.
|
|
+ * Each entry: (hw_offset, hw_offset+hw_size, BASE_IO*).
|
|
+ */
|
|
+struct HWRange {
|
|
+ memptr base;
|
|
+ memptr end;
|
|
+ BASE_IO *dev;
|
|
+ bool operator<(memptr addr) const { return end <= addr; }
|
|
+};
|
|
+static HWRange hw_sorted[iITEMS];
|
|
+static unsigned int hw_sorted_cnt = 0;
|
|
+
|
|
BASE_IO *arhw[iITEMS];
|
|
|
|
void HWInit()
|
|
@@ -97,6 +114,19 @@ void HWInit()
|
|
arhw[iSCC] = scc = new SCC(0xff8c81, 8);
|
|
arhw[iCARTRIDGE] = new BASE_IO(0xfa0000, 0x20000);
|
|
+
|
|
+ /* Build sorted dispatch table. */
|
|
+ hw_sorted_cnt = 0;
|
|
+ for (int i = 0; i < iITEMS; i++) {
|
|
+ hw_sorted[hw_sorted_cnt].base = arhw[i]->getHWoffset();
|
|
+ hw_sorted[hw_sorted_cnt].end = arhw[i]->getHWoffset() + arhw[i]->getHWsize();
|
|
+ hw_sorted[hw_sorted_cnt].dev = arhw[i];
|
|
+ hw_sorted_cnt++;
|
|
+ }
|
|
+ std::sort(hw_sorted, hw_sorted + hw_sorted_cnt,
|
|
+ [](const HWRange &a, const HWRange &b){ return a.base < b.base; });
|
|
}
|
|
|
|
void HWExit()
|
|
@@ -118,11 +148,17 @@ void HWReset()
|
|
|
|
BASE_IO *getModule(memptr addr)
|
|
{
|
|
- for(int i=0; i<iITEMS; i++) {
|
|
- if (arhw[i]->isMyHWRegister(addr))
|
|
- return arhw[i];
|
|
- }
|
|
- D(bug("HW register %08x not emulated", addr));
|
|
- return NULL;
|
|
+ /*
|
|
+ * Binary search over hw_sorted[] (sorted by base address).
|
|
+ * Complexity: O(log D) where D=17, vs the previous O(D) linear scan.
|
|
+ * Every 68k I/O access calls this function, so the saving is real.
|
|
+ */
|
|
+ const HWRange *first = hw_sorted;
|
|
+ const HWRange *last = hw_sorted + hw_sorted_cnt;
|
|
+ const HWRange *it = std::lower_bound(first, last, addr,
|
|
+ [](const HWRange &r, memptr a){ return r.end <= a; });
|
|
+ if (it != last && addr >= it->base && addr < it->end)
|
|
+ return it->dev;
|
|
+ D(bug("HW register %08x not emulated", addr));
|
|
+ return NULL;
|
|
}
|