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) {}