]> localhost Git - WindEmu.git/commitdiff
sa1100: implement readLCDIntoBuffer
authorGeorge Wright <gw@gwright.org.uk>
Thu, 25 Jun 2026 04:18:35 +0000 (21:18 -0700)
committerGeorge Wright <gw@gwright.org.uk>
Fri, 26 Jun 2026 03:45:43 +0000 (20:45 -0700)
WindCore/series7/sa1100.cpp

index e07d03006f7c5fdc205163a9defdd86e6abfa536..4ce5c4188d1b264f18449d0b28c2b84842d8662c 100644 (file)
@@ -146,7 +146,60 @@ int Emulator::getLCDOffsetY() const { return 0; }
 int Emulator::getLCDWidth() const { return 640; }
 int Emulator::getLCDHeight() const { return 480; }
 
-void Emulator::readLCDIntoBuffer(uint8_t** lines, bool is32BitOutput) const {}
+uint8_t getByteIdx(uint32_t word, int idx) {
+  return word >> (24 - (idx * 8)) & 0xFF;
+}
+
+void Emulator::readLCDIntoBuffer(uint8_t** lines, bool is32BitOutput) const {
+  if (!mLcdController->isLCDEnabled()) {
+    for (int i = 0; i < 480; i++) {
+      uint8_t* line = reinterpret_cast<uint8_t*>(lines[i]);
+      memset(line, 0x0AAA, 2 * 640);
+    }
+    return;
+  }
+
+  uint32_t paletteBase =
+      mLcdController->getFramebufferBase(LCDController::Framebuffer::Top);
+  // The palette is 512 bytes long
+  uint32_t framebufferTopHalfBase = paletteBase + 512;
+  uint32_t framebufferBottomHalfBase =
+      mLcdController->getFramebufferBase(LCDController::Framebuffer::Bottom);
+
+  uint32_t temp;
+  std::vector<uint16_t> palette;
+  for (int i = 0; i < 128; i++) {
+    LOAD_32LE(temp, (paletteBase + (4 * i)) & MemoryBlockMask, MemoryBlockC0);
+    palette.emplace_back(temp & 0xFFF);
+    palette.emplace_back((temp >> 16) & 0xFFF);
+  }
+
+  std::vector<uint8_t> pixels;
+  for (int i = 0; i < 640 * 240; i += 4) {
+    LOAD_32LE(temp, (framebufferTopHalfBase + (i)) & MemoryBlockMask,
+              MemoryBlockC0);
+    for (int j = 0; j < 4; j++) {
+      pixels.emplace_back(getByteIdx(temp, 3 - j));
+    }
+  }
+  for (int i = 0; i < 640 * 240; i += 4) {
+    LOAD_32LE(temp, (framebufferBottomHalfBase + (i)) & MemoryBlockMask,
+              MemoryBlockC0);
+    for (int j = 0; j < 4; j++) {
+      pixels.emplace_back(getByteIdx(temp, 3 - j));
+    }
+  }
+
+  for (int i = 0; i < 480; i++) {
+    uint16_t* line = reinterpret_cast<uint16_t*>(lines[i]);
+    memset(line, 0, 2 * 640);
+    for (int j = 0; j < 640; j++) {
+      line[j] = palette[pixels[(640 * i) + j]];
+    }
+  }
+
+  mLcdController->endFrame();
+}
 
 void Emulator::diffPorts(uint32_t oldval, uint32_t newval) {}