| 110 | if !self.double_buffered { |
| 111 | self.version += 1; |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | // Publish the back buffer to the front (no-op when single-buffered). |
| 116 | fn present(&mut self) { |
| 117 | if self.double_buffered { |
| 118 | self.front.copy_from_slice(&self.back); |
| 119 | self.version += 1; |
| 120 | } |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | impl MemoryAccess for Framebuffer { |
| 125 | fn read_byte(&mut self, addr: u64) -> Result<u8, VmError> { |
| 126 | let a = addr as usize; |
| 127 | if a < FB_BYTES { |
| 128 | // Reads see the buffer the guest is actively drawing into. |
| 129 | Ok(self.draw_buffer()[a]) |
| 130 | } else if a < FB_TOTAL_BYTES { |
| 131 | // Control registers read back as zero. |
| 132 | Ok(0) |
| 133 | } else { |
| 134 | Err(VmError::BusError(addr)) |
| 135 | } |