Implement paletted framebuffer (320x200 for now)

This commit is contained in:
Konstantin Nazarov 2024-12-22 02:18:02 +00:00
parent 557d5dfa75
commit 844ad3b073
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
3 changed files with 33 additions and 12 deletions

View file

@ -2,6 +2,7 @@
typedef unsigned long long uint64_t;
typedef unsigned long uint32_t;
typedef unsigned char uint8_t;
#define MTIME_BASE 0x0200BFF8
volatile uint32_t* mtime_upper = (uint32_t*)(MTIME_BASE+4);
@ -36,10 +37,10 @@ int fib(int n) {
void draw() {
for (int k = 0; k < 200; k++) {
for (int i = 0; i< 640; i++) {
for (int j = 0; j < 480; j++) {
uint32_t color = i*(j + k);
uint32_t* addr = (uint32_t*)(FRAMEBUFFER_BASE + ((j*640) + i) *4);
for (int i = 0; i< 320; i++) {
for (int j = 0; j < 200; j++) {
uint8_t color = i*(j + k);
uint8_t* addr = (uint8_t*)(FRAMEBUFFER_BASE + (j*320) + i);
*addr = color;
}
}

View file

@ -9,12 +9,21 @@ SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_Texture* texture = nullptr;
Framebuffer::Framebuffer() : Device(FRAMEBUFFER_ADDR, 640 * 480 * 4) {
#define FB_WIDTH 320
#define FB_HEIGHT 200
#define FB_SCALE 2
#define FB_OFFSET 0x10000
Framebuffer::Framebuffer()
: Device(FRAMEBUFFER_ADDR, FB_WIDTH * FB_HEIGHT + FB_OFFSET),
width(FB_WIDTH),
height(FB_HEIGHT),
buf(FB_WIDTH * FB_HEIGHT, 0) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
throw std::runtime_error("Failed to initialize SDL");
}
window = SDL_CreateWindow("rve Framebuffer", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480, 0);
SDL_WINDOWPOS_CENTERED, width, height, 0);
if (!window) {
throw std::runtime_error("Failed to create SDL window");
}
@ -33,7 +42,7 @@ Framebuffer::Framebuffer() : Device(FRAMEBUFFER_ADDR, 640 * 480 * 4) {
throw std::runtime_error("Failed to create SDL renderer");
}
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, 640, 480);
SDL_TEXTUREACCESS_STREAMING, width, height);
if (!texture) {
throw std::runtime_error("Failed to create SDL texture");
}
@ -44,8 +53,15 @@ Framebuffer::Framebuffer() : Device(FRAMEBUFFER_ADDR, 640 * 480 * 4) {
}
void Framebuffer::draw() {
SDL_UpdateTexture(texture, nullptr, &mem[0],
640 * 4); // Update the SDL texture
for (size_t i = 0; i < width * height; i++) {
uint8_t color = mem[i + FB_OFFSET];
uint32_t cmap = ((uint32_t*)&mem[0])[color];
buf[i] = cmap;
}
SDL_UpdateTexture(texture, nullptr, &buf[0],
width * 4); // Update the SDL texture
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
SDL_RenderPresent(renderer);
@ -54,7 +70,7 @@ void Framebuffer::draw() {
void Framebuffer::write_mem_u8(uint8_t* src, size_t addr) {
Device::write_mem_u8(src, addr);
if (addr + 1 == base() + (640 * 480) * 4) {
if (addr + 1 == base() + width * height + FB_OFFSET) {
// draw to the screen when the last byte is written
draw();
}
@ -63,7 +79,7 @@ void Framebuffer::write_mem_u8(uint8_t* src, size_t addr) {
void Framebuffer::write_mem_u16(uint16_t* src, size_t addr) {
Device::write_mem_u16(src, addr);
if (addr + 2 == base() + (640 * 480) * 4) {
if (addr + 2 == base() + width * height + FB_OFFSET) {
// draw to the screen when the last byte is written
draw();
}
@ -72,7 +88,7 @@ void Framebuffer::write_mem_u16(uint16_t* src, size_t addr) {
void Framebuffer::write_mem_u32(uint32_t* src, size_t addr) {
Device::write_mem_u32(src, addr);
if (addr + 4 == base() + (640 * 480) * 4) {
if (addr + 4 == base() + width * height + FB_OFFSET) {
// draw to the screen when the last byte is written
draw();
}

View file

@ -114,6 +114,10 @@ class Framebuffer final : public Device {
protected:
void draw();
size_t width;
size_t height;
std::vector<uint32_t> buf;
};
class VM {