From 73688d2e9623a8d3b5e2edc20f4e3ef2dd1a4bc5 Mon Sep 17 00:00:00 2001 From: Nihilazo Date: Thu, 28 Oct 2021 21:26:36 +0100 Subject: [PATCH] it's broken but I'm trying --- apps/plugins/varvara/devices/ppu.c | 1 + apps/plugins/varvara/varvara.c | 238 +++++++++++++++++++++++++---- 2 files changed, 212 insertions(+), 27 deletions(-) diff --git a/apps/plugins/varvara/devices/ppu.c b/apps/plugins/varvara/devices/ppu.c index 24a1a5525b..c66516150f 100644 --- a/apps/plugins/varvara/devices/ppu.c +++ b/apps/plugins/varvara/devices/ppu.c @@ -1,4 +1,5 @@ #include "ppu.h" +#include /* Copyright (c) 2021 Devine Lu Linvega diff --git a/apps/plugins/varvara/varvara.c b/apps/plugins/varvara/varvara.c index 5821a6d93b..1eda0913d8 100644 --- a/apps/plugins/varvara/varvara.c +++ b/apps/plugins/varvara/varvara.c @@ -1,4 +1,19 @@ -/* Varvara plugin for rockbox. I have no idea what I'm doing. */ +/* Varvara plugin for rockbox. I have no idea what I'm doing. + +Functions taken from uxnemu.c and uxncli.c are copyright (c) 2021 Devine Lu Linvega. + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. + +TODO screen vector, de-janking display code +TODO other devices +TODO hardware builds, support for hardware other than simulated e200 +TODO clean up +*/ #include "uxn.h" #include "devices/ppu.h" @@ -8,15 +23,122 @@ #include -const uint8_t uxn_rom[] = { /* hello world ROM */ + + +const uint8_t hwrom[] = { /* hello world ROM */ 0x20, 0x01, 0x0e, 0x94, 0x80, 0x18, 0x17, 0x21, 0x94, 0x80, 0xf7, 0x0d, 0x22, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x55, 0x78, 0x6e, 0x21, 0x21, }; +const uint8_t uxn_rom[] = { /* screen test ROM */ + 0x20, 0x01, 0x43, 0x80, 0x20, 0x37, 0x20, 0xf0, + 0x7f, 0x80, 0x08, 0x37, 0x20, 0xf0, 0xe0, 0x80, + 0x0a, 0x37, 0x20, 0xf0, 0xc0, 0x80, 0x0c, 0x37, + 0x80, 0x22, 0x36, 0x80, 0x01, 0x3f, 0x20, 0x00, + 0x20, 0x39, 0x80, 0x02, 0x31, 0x80, 0x24, 0x36, + 0x80, 0x01, 0x3f, 0x80, 0x04, 0x31, 0x20, 0x01, + 0xd4, 0x2e, 0x20, 0x02, 0x2f, 0x2e, 0x20, 0x02, + 0x71, 0x2e, 0x20, 0x02, 0xae, 0x2e, 0x20, 0x03, + 0x3a, 0x2e, 0x00, 0x80, 0x00, 0x30, 0x21, 0x23, + 0x80, 0x00, 0x31, 0x80, 0x02, 0x30, 0x20, 0x00, + 0x48, 0x38, 0x80, 0x28, 0x37, 0x80, 0x04, 0x30, + 0x20, 0x00, 0x50, 0x39, 0x80, 0x2a, 0x37, 0x80, + 0x01, 0x0f, 0x05, 0x03, 0x80, 0x04, 0x1f, 0x80, + 0x00, 0x05, 0x80, 0x30, 0x3f, 0x20, 0x03, 0x91, + 0x38, 0x80, 0x2c, 0x37, 0xcf, 0x80, 0x2f, 0x17, + 0x80, 0x0f, 0x1c, 0x80, 0x00, 0x05, 0x80, 0x30, + 0x3f, 0x20, 0x03, 0x91, 0x38, 0x80, 0x2c, 0x37, + 0x80, 0x28, 0x36, 0x20, 0x00, 0x08, 0x38, 0x80, + 0x28, 0x37, 0xcf, 0x80, 0x2f, 0x17, 0x03, 0x80, + 0x04, 0x1f, 0x80, 0x00, 0x05, 0x80, 0x30, 0x3f, + 0x20, 0x03, 0x91, 0x38, 0x80, 0x2c, 0x37, 0x80, + 0x28, 0x36, 0x20, 0x00, 0x08, 0x38, 0x80, 0x28, + 0x37, 0xcf, 0x80, 0x2f, 0x17, 0x80, 0x0f, 0x1c, + 0x80, 0x00, 0x05, 0x80, 0x30, 0x3f, 0x20, 0x03, + 0x91, 0x38, 0x80, 0x2c, 0x37, 0x80, 0x28, 0x36, + 0x20, 0x00, 0x08, 0x38, 0x80, 0x28, 0x37, 0x4f, + 0x80, 0x2f, 0x17, 0x00, 0x80, 0x10, 0x80, 0x00, + 0x03, 0x80, 0x30, 0x1f, 0x80, 0x00, 0x05, 0x20, + 0x03, 0x91, 0x38, 0x80, 0x2c, 0x37, 0x03, 0x80, + 0x30, 0x1f, 0x80, 0x00, 0x05, 0x80, 0x02, 0x30, + 0x20, 0x00, 0x40, 0x39, 0x38, 0x80, 0x28, 0x37, + 0x80, 0x04, 0x30, 0x20, 0x00, 0x50, 0x39, 0x80, + 0x2a, 0x37, 0x80, 0x01, 0x80, 0x2f, 0x17, 0x03, + 0x80, 0x30, 0x1f, 0x80, 0x00, 0x05, 0x80, 0x04, + 0x30, 0x20, 0x00, 0x40, 0x39, 0x38, 0x80, 0x2a, + 0x37, 0x80, 0x02, 0x30, 0x20, 0x00, 0x50, 0x39, + 0x80, 0x28, 0x37, 0x80, 0x01, 0x80, 0x2f, 0x17, + 0x01, 0x8a, 0x80, 0xab, 0x0d, 0x22, 0x6c, 0x20, + 0x03, 0x81, 0x80, 0x2c, 0x37, 0x80, 0x00, 0x80, + 0x00, 0x03, 0x80, 0x0f, 0x1c, 0x80, 0x40, 0x1f, + 0x80, 0x01, 0x1f, 0x80, 0x00, 0x05, 0x80, 0x02, + 0x30, 0x20, 0x00, 0x40, 0x39, 0x38, 0x80, 0x28, + 0x37, 0x03, 0x80, 0xf0, 0x1c, 0x80, 0x01, 0x1f, + 0x80, 0x00, 0x05, 0x80, 0x04, 0x30, 0x20, 0x00, + 0x40, 0x39, 0x38, 0x80, 0x2a, 0x37, 0x03, 0x80, + 0x2f, 0x17, 0x01, 0x89, 0x80, 0xca, 0x0d, 0x22, + 0x6c, 0x80, 0x10, 0x80, 0x00, 0x8f, 0x03, 0x80, + 0x02, 0x1f, 0x80, 0x00, 0x05, 0x80, 0x40, 0x3f, + 0x80, 0x04, 0x30, 0x20, 0x00, 0x40, 0x39, 0x38, + 0x2f, 0x03, 0x80, 0x03, 0x1c, 0x80, 0x00, 0x05, + 0x80, 0x40, 0x3f, 0x20, 0x00, 0x40, 0x38, 0x80, + 0x02, 0x30, 0x20, 0x00, 0x08, 0x38, 0x38, 0x6f, + 0x4f, 0x80, 0x00, 0x20, 0x02, 0xe7, 0x2e, 0x01, + 0x8a, 0x80, 0xc9, 0x0d, 0x22, 0x6c, 0x80, 0x10, + 0x80, 0x00, 0x8f, 0x03, 0x80, 0x02, 0x1f, 0x80, + 0x00, 0x05, 0x80, 0x40, 0x3f, 0x80, 0x04, 0x30, + 0x38, 0x2f, 0x03, 0x80, 0x03, 0x1c, 0x80, 0x00, + 0x05, 0x80, 0x40, 0x3f, 0x20, 0x00, 0x40, 0x38, + 0x80, 0x02, 0x30, 0x20, 0x00, 0x08, 0x38, 0x38, + 0x6f, 0x4f, 0x80, 0x80, 0x20, 0x02, 0xe7, 0x2e, + 0x01, 0x8a, 0x80, 0xcd, 0x0d, 0x22, 0x6c, 0x18, + 0x0f, 0x20, 0x03, 0x81, 0x80, 0x2c, 0x37, 0x80, + 0x2a, 0x37, 0x80, 0x28, 0x37, 0x80, 0x00, 0xcf, + 0x18, 0x80, 0x2f, 0x17, 0x80, 0x28, 0x36, 0x20, + 0x00, 0x08, 0x38, 0x80, 0x28, 0x37, 0x80, 0x10, + 0xcf, 0x18, 0x80, 0x2f, 0x17, 0x80, 0x28, 0x36, + 0x20, 0x00, 0x08, 0x39, 0x80, 0x28, 0x37, 0x80, + 0x2a, 0x36, 0x20, 0x00, 0x08, 0x38, 0x80, 0x2a, + 0x37, 0x80, 0x20, 0xcf, 0x18, 0x80, 0x2f, 0x17, + 0x80, 0x28, 0x36, 0x20, 0x00, 0x08, 0x38, 0x80, + 0x28, 0x37, 0x80, 0x30, 0x4f, 0x18, 0x80, 0x2f, + 0x17, 0x6c, 0x80, 0x04, 0x30, 0x20, 0x00, 0x40, + 0x39, 0x80, 0x2a, 0x37, 0x80, 0x02, 0x30, 0x20, + 0x00, 0x48, 0x38, 0x80, 0x28, 0x37, 0x80, 0x00, + 0x80, 0x2e, 0x17, 0x80, 0x02, 0x30, 0x20, 0x00, + 0x49, 0x38, 0x80, 0x28, 0x37, 0x80, 0x01, 0x80, + 0x2e, 0x17, 0x80, 0x02, 0x30, 0x20, 0x00, 0x4a, + 0x38, 0x80, 0x28, 0x37, 0x80, 0x02, 0x80, 0x2e, + 0x17, 0x80, 0x02, 0x30, 0x20, 0x00, 0x4b, 0x38, + 0x80, 0x28, 0x37, 0x80, 0x03, 0x80, 0x2e, 0x17, + 0x6c, 0x0f, 0x38, 0x67, 0x5f, 0xdf, 0xbf, 0xbf, + 0xbf, 0x00, 0x07, 0x18, 0x20, 0x23, 0x44, 0x48, + 0x48, 0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x7c, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x00, 0x7c, 0x82, 0x02, 0x7c, 0x80, 0x80, + 0xfe, 0x00, 0x7c, 0x82, 0x02, 0x1c, 0x02, 0x82, + 0x7c, 0x00, 0x0c, 0x14, 0x24, 0x44, 0x84, 0xfe, + 0x04, 0x00, 0xfe, 0x80, 0x80, 0x7c, 0x02, 0x82, + 0x7c, 0x00, 0x7c, 0x82, 0x80, 0xfc, 0x82, 0x82, + 0x7c, 0x00, 0x7c, 0x82, 0x02, 0x1e, 0x02, 0x02, + 0x02, 0x00, 0x7c, 0x82, 0x82, 0x7c, 0x82, 0x82, + 0x7c, 0x00, 0x7c, 0x82, 0x82, 0x7e, 0x02, 0x82, + 0x7c, 0x00, 0x7c, 0x82, 0x02, 0x7e, 0x82, 0x82, + 0x7e, 0x00, 0xfc, 0x82, 0x82, 0xfc, 0x82, 0x82, + 0xfc, 0x00, 0x7c, 0x82, 0x80, 0x80, 0x80, 0x82, + 0x7c, 0x00, 0xfc, 0x82, 0x82, 0x82, 0x82, 0x82, + 0xfc, 0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, + 0x7c, 0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, + 0x80, 0x80, +}; + + static Uxn u; -static Device *devsystem, *devconsole; +static Ppu ppu; +static Device *devsystem, *devconsole, *devscreen; +unsigned int palette[3]; static void memzero8(void *src, uint64_t n) @@ -43,6 +165,22 @@ inspect(Stack *s, char *name) } } +// TODO implement +static void +set_palette(Uint8 *addr) +{ + #if LCD_DEPTH > 1 + int i; + for(i = 0; i < 4; ++i) { + Uint8 + r = (*(addr + i / 2) >> (!(i % 2) << 2)) & 0x0f, + g = (*(addr + 2 + i / 2) >> (!(i % 2) << 2)) & 0x0f, + b = (*(addr + 4 + i / 2) >> (!(i % 2) << 2)) & 0x0f; + palette[i] = LCD_RGBPACK(r*8,g*8,b*8); + } + #endif +} + /* taken from uxncli */ static int system_talk(Device *d, Uint8 b0, Uint8 w) @@ -62,6 +200,8 @@ system_talk(Device *d, Uint8 b0, Uint8 w) break; case 0xf: return 0; } + if(b0 > 0x7 && b0 < 0xe) + set_palette(&d->dat[0x8]); } return 1; } @@ -77,6 +217,50 @@ console_talk(Device *d, Uint8 b0, Uint8 w) return 1; } +/* taken from uxnemu */ +static int +screen_talk(Device *d, Uint8 b0, Uint8 w) +{ + if(!w) switch(b0) { + case 0x2: d->dat[0x2] = ppu.width >> 8; break; + case 0x3: d->dat[0x3] = ppu.width; break; + case 0x4: d->dat[0x4] = ppu.height >> 8; break; + case 0x5: d->dat[0x5] = ppu.height; break; + } + else + switch(b0) { + case 0x1: d->vector = peek16(d->dat, 0x0); break; + case 0x5: + break; + case 0xe: { + Uint16 x = peek16(d->dat, 0x8); + Uint16 y = peek16(d->dat, 0xa); + Uint8 layer = d->dat[0xe] & 0x40; + ppu_write(&ppu, !!layer, x, y, d->dat[0xe] & 0x3); + if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 1); /* auto x+1 */ + if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 1); /* auto y+1 */ + break; + } + case 0xf: { + Uint16 x = peek16(d->dat, 0x8); + Uint16 y = peek16(d->dat, 0xa); + Uint8 layer = d->dat[0xf] & 0x40; + Uint8 *addr = &d->mem[peek16(d->dat, 0xc)]; + if(d->dat[0xf] & 0x80) { + ppu_2bpp(&ppu, !!layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20); + if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 16); /* auto addr+16 */ + } else { + ppu_1bpp(&ppu, !!layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] & 0x10, d->dat[0xf] & 0x20); + if(d->dat[0x6] & 0x04) poke16(d->dat, 0xc, peek16(d->dat, 0xc) + 8); /* auto addr+8 */ + } + if(d->dat[0x6] & 0x01) poke16(d->dat, 0x8, x + 8); /* auto x+8 */ + if(d->dat[0x6] & 0x02) poke16(d->dat, 0xa, y + 8); /* auto y+8 */ + break; + } + } + return 1; +} + static int nil_talk(Device *d, Uint8 b0, Uint8 w) { @@ -86,6 +270,23 @@ nil_talk(Device *d, Uint8 b0, Uint8 w) return 1; } +// TODO store palette in a non-guesswork format, optimise, make build on non-color devices +static int redraw(Uxn *u) +{ + Uint16 x, y; + for(y = 0; y < ppu.height; ++y) + for(x = 0; x < ppu.width; ++x) { + #if LCD_DEPTH > 1 + rb->lcd_set_foreground(palette[ppu_read(&ppu, x, y)]); + #endif + rb->lcd_drawpixel(x, y); + + } + rb->lcd_update(); + ppu.reqdraw = 0; + +} + int uxn_halt(Uxn *u, Uint8 error, char *name, int id) { @@ -94,15 +295,14 @@ uxn_halt(Uxn *u, Uint8 error, char *name, int id) } /* this is the plugin entry point */ + enum plugin_status plugin_start(const void* parameter) { - /* if you don't use the parameter, you can do like - this to avoid the compiler warning about it */ - (void)parameter; - /* "rb->" marks a plugin api call. Rockbox offers many of its built-in - * functions to plugins */ - /* now go ahead and have fun! */ + (void)parameter; + + DEBUGF("Setting PPU size\n"); + ppu_set_size(&ppu, LCD_WIDTH, LCD_HEIGHT); DEBUGF("UXN init\n"); // Clear RAM and copy rom to VM. DEBUGF("zeroing\n"); @@ -113,7 +313,7 @@ enum plugin_status plugin_start(const void* parameter) // Register ports /* system */ devsystem = uxn_port(&u, 0x0, system_talk); /* console */ devconsole = uxn_port(&u, 0x1, console_talk); - /* screen */ uxn_port(&u, 0x2, nil_talk); + /* screen */ devscreen = uxn_port(&u, 0x2, screen_talk); /* audio0 */ uxn_port(&u, 0x3, nil_talk); /* audio1 */ uxn_port(&u, 0x4, nil_talk); /* audio2 */ uxn_port(&u, 0x5, nil_talk); @@ -127,25 +327,9 @@ enum plugin_status plugin_start(const void* parameter) /* empty */ uxn_port(&u, 0xd, nil_talk); /* empty */ uxn_port(&u, 0xe, nil_talk); /* empty */ uxn_port(&u, 0xf, nil_talk); - - // Boot - // if(!uxn_boot(&u)) - // return -1; - // Run DEBUGF("eval\n"); uxn_eval(&u, 0x0100); - - rb->lcd_clear_display(); - // 0x000f: blue, 0x00f0: - //rb->lcd_set_foreground(LCD_RGBPACK(0,0,255)); - rb->lcd_fillrect(0,0,10,10); - //rb->lcd_set_foreground(0x00f0); - rb->lcd_fillrect(10,0,10,10); - //rb->lcd_set_foreground(0x0f00); - rb->lcd_fillrect(20,0,10,10); - //rb->lcd_set_foreground(0xf000); - rb->lcd_fillrect(30,0,10,10); - rb->lcd_update(); + redraw(&u); rb->button_get(true); return PLUGIN_OK;