From bd0cda4f02cbf8d2b19ddd1a137b6372486d6091 Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Mon, 22 Jan 2024 17:08:06 +0000 Subject: [PATCH] Fix for 'black window' on some hardware Plus a few other minor bits... Signed-off-by: Michel Pollet --- libmui/mui/mui.c | 1 + libmui/mui/mui.h | 21 ++++++---- src/mii_mish.c | 77 +++++++++++++++++++++++++++++++++- src/mii_sw.h | 96 ++++++++++++++++++++----------------------- src/mii_video.h | 7 ++++ ui_gl/mii_emu_gl.c | 43 +++++++++++++++---- ui_gl/mii_mui_menus.c | 11 ++--- 7 files changed, 178 insertions(+), 78 deletions(-) diff --git a/libmui/mui/mui.c b/libmui/mui/mui.c index c0655ee..584d17f 100644 --- a/libmui/mui/mui.c +++ b/libmui/mui/mui.c @@ -34,6 +34,7 @@ mui_dispose( mui_t *ui) { pixman_region32_fini(&ui->inval); + pixman_region32_fini(&ui->redraw); mui_font_dispose(ui); mui_window_t *w; while ((w = TAILQ_FIRST(&ui->windows))) { diff --git a/libmui/mui/mui.h b/libmui/mui/mui.h index 6aa38d5..9b8d732 100644 --- a/libmui/mui/mui.h +++ b/libmui/mui/mui.h @@ -111,7 +111,7 @@ enum mui_modifier_e { #define MUI_ICON_SBAR_UP "" #define MUI_ICON_SBAR_DOWN "" -/* These are specific the Charcoal System font */ +/* These are specific to our custom version of the Charcoal System font */ #define MUI_GLYPH_APPLE "" // solid apple #define MUI_GLYPH_OAPPLE "" // open apple #define MUI_GLYPH_COMMAND "" @@ -138,7 +138,7 @@ enum mui_modifier_e { typedef uint64_t mui_time_t; /* - * Even description. pretty standard stuff here -- the 'when' field is + * Event description. pretty standard stuff here -- the 'when' field is * only used really to detect double clicks so far. * * Even handlers should return true if the event was handled, (in which case @@ -204,7 +204,7 @@ struct mui_listbox_elem_t; /* * Window DEFinition -- Handle all related to a window, from drawing to - * even handling. + * event handling. */ enum { MUI_WDEF_INIT = 0, @@ -288,7 +288,7 @@ struct cg_ctx_t; /* * Describes a pixmap. Currently only used for the screen destination pixels. - * And really, only bpp:43 for ARGB is supported. + * And really, only bpp:32 for ARGB is supported. */ typedef struct mui_pixmap_t { uint8_t * pixels; @@ -447,6 +447,7 @@ mui_font_textbox( unsigned int text_len, mui_color_t color, uint16_t flags ); + DECLARE_C_ARRAY(stb_ttc_g*, mui_glyph_array, 8, int x, y, w; ); DECLARE_C_ARRAY(mui_glyph_array_t, mui_glyph_line_array, 8); @@ -519,7 +520,7 @@ mui_window_create( uint8_t layer, const char * title, uint32_t instance_size); -// Dispose a window and it's content (controls). +// Dispose of a window and it's content (controls). /* * Note: if an action is in progress the window is not freed immediately * but added to the zombie list, and freed when the action is done. @@ -574,8 +575,9 @@ struct mui_menu_items_t; /* * This is a menu item descriptor (also used for the titles, bar a few bits). - * This does not a *control* in the window, instead this is used to describe - * the menus and menu item controls that are created when the menu becomes visible. + * This is not a *control* in the window, instead this is used to describe + * the menus and menu item controls that are created when the menu becomes + * visible. */ typedef struct mui_menu_item_t { uint32_t disabled : 1, hilited : 1; @@ -777,10 +779,11 @@ mui_button_new( const char * title, uint32_t uid ); /* - * Create a static text box. Font is optional, flags correponds to the MUI_TEXT_ALIGN_* - * PLUS the extrast listed below. + * Create a static text box. Font is optional (default to the system main font), + * flags corresponds to the MUI_TEXT_ALIGN_* * PLUS the extra(s) listed below. */ enum mui_textbox_e { + // draw the frame around the text box MUI_CONTROL_TEXTBOX_FRAME = (1 << 8), }; mui_control_t * diff --git a/src/mii_mish.c b/src/mii_mish.c index efb03f3..9909a5e 100644 --- a/src/mii_mish.c +++ b/src/mii_mish.c @@ -64,15 +64,30 @@ show_state: char buf[32]; sprintf(buf, "%s:%d", mii_sw_names[i], !!(mii->sw_state & (1 << i))); - printf("%-13.13s%s", buf, !(i % 6) ? "\n" : " "); + printf("%-13.13s%s", buf, !((i+1) % 6) ? "\n" : " "); } printf("\n"); + printf("RGB Video Mode: %d\n", mii->video.color_mode); return; } if (!strcmp(argv[1], "reset")) { mii_reset(mii, 0); return; } + if (!strcmp(argv[1], "rgb")) { + if (argc < 3) { + printf("rgb: missing argument\n"); + return; + } + uint8_t val = strtol(argv[2], NULL, 16); + if (val > MII_VIDEO_MODE_COUNT) { + printf("rgb: invalid mode %d\n", val); + return; + } + mii->video.color_mode = val; + return; + } + if (!strcmp(argv[1], "mem")) { printf("mii: memory map: "); for (int i = 0; i < MII_BANK_COUNT; i++) @@ -241,6 +256,54 @@ _mii_mish_il( } } + +static void +_mii_mish_mm( + void * param, + int argc, + const char * argv[]) +{ + static uint32_t addr = 0x800; + if (argv[1]) { + addr = strtol(argv[1], NULL, 16); + if (addr > 0x00100000) + addr = 0x00fff0; + } + mii_t * mii = param; + int bi = (addr >> 16) & 0xf; + if (bi > MII_BANK_COUNT) { + printf("mii: invalid bank index %d (0:7)\n", bi); + return; + } + addr &= 0xffff; + mii_bank_t * bank = &mii->bank[bi]; +// addr -= bank->base; + if (!strcmp(argv[0], "mm")) { + printf("%s %04x\n", bank->name, addr); + for (int i = 0; i < 8; i++) { + printf("%06x: ", addr); + for (int j = 0; j < 16; j++) + printf("%02x ", mii_bank_peek(bank, addr++)); + printf("\n"); + } + return; + } + if (!strcmp(argv[0], "mb")) { + printf("%s: %04x: ", bank->name, addr); + printf("%02x ", mii_bank_peek(bank, addr++)); + printf("\n"); + return; + } + if (!strcmp(argv[0], "mw") || !strcmp(argv[0], "ma")) { + printf("%s: %04x: ", bank->name, addr); + uint8_t l = mii_bank_peek(bank, addr++); + uint8_t h = mii_bank_peek(bank, addr++); + printf("%02x%02x", h, l); + printf("\n"); + return; + } +} + static void _mii_mish_dm( void * param, @@ -403,6 +466,7 @@ MISH_CMD_NAMES(mii, "mii"); MISH_CMD_HELP(mii, "mii: access internals, trace, reset, speed, etc", " : dump current state", + " rgb : Set RGB mode to (0:color,1:green,2:amber)" " reset : reset the cpu", " t|trace : toggle trace_cpu (WARNING HUGE traces!))", " mem : dump memory and bank map", @@ -442,6 +506,17 @@ MISH_CMD_HELP(dm, ); MII_MISH(dm, _mii_mish_dm); +MISH_CMD_NAMES(mm, "mm","mb","mw","ma"); +MISH_CMD_HELP(mm, + "mii: dump memory, byte, word, [raw address]", + " |mm : dump 64 bytes.", + " mb []: dump one byte.", + " mw []: dump one word.", + " ma []: dump one address.", + " [addr]: 24 bits address addr 00 main, 01 aux" + ); +MII_MISH(mm, _mii_mish_mm); + MISH_CMD_NAMES(step, "s","step","n","next","cont","h","halt"); MISH_CMD_HELP(step, "mii: step instructions", diff --git a/src/mii_sw.h b/src/mii_sw.h index 1b56843..f2dab00 100644 --- a/src/mii_sw.h +++ b/src/mii_sw.h @@ -8,60 +8,54 @@ #pragma once enum { - SW80STORE = 0xc018, - SWVBL = 0xc019, - SWALTCHARSET = 0xc01e, - SW80COL = 0xc01f, - SWTEXT = 0xc01a, - SWMIXED = 0xc01b, - SWPAGE2 = 0xc01c, - SWHIRES = 0xc01d, - - SW80STOREOFF = 0xc000, - SW80STOREON = 0xc001, + SWKBD = 0xc000, + SW80STOREOFF = 0xc000, + SW80STOREON = 0xc001, + SWRAMRDOFF = 0xc002, + SWRAMRDON = 0xc003, + SWRAMWRTOFF = 0xc004, + SWRAMWRTON = 0xc005, + SWINTCXROMOFF = 0xc006, + SWINTCXROMON = 0xc007, + SWALTPZOFF = 0xc008, + SWALTPZON = 0xc009, + SWSLOTC3ROMOFF = 0xc00a, + SWSLOTC3ROMON = 0xc00b, + SW80COLOFF = 0xc00c, + SW80COLON = 0xc00d, SWALTCHARSETOFF = 0xc00e, SWALTCHARSETON = 0xc00f, - SW80COLOFF = 0xc00c, - SW80COLON = 0xc00d, - SWTEXTOFF = 0xc050, // (AKA LORES ON) - SWTEXTON = 0xc051, - SWMIXEDOFF = 0xc052, - SWMIXEDON = 0xc053, - SWPAGE2OFF = 0xc054, - SWPAGE2ON = 0xc055, - SWHIRESOFF = 0xc056, - SWHIRESON = 0xc057, - + SWAKD = 0xc010, + SWBSRBANK2 = 0xc011, + SWBSRREADRAM = 0xc012, + SWRAMRD = 0xc013, + SWRAMWRT = 0xc014, + SWINTCXROM = 0xc015, + SWALTPZ = 0xc016, + SWSLOTC3ROM = 0xc017, + SW80STORE = 0xc018, + SWVBL = 0xc019, + SWALTCHARSET = 0xc01e, + SW80COL = 0xc01f, + SWTEXT = 0xc01a, + SWMIXED = 0xc01b, + SWPAGE2 = 0xc01c, + SWHIRES = 0xc01d, + SWSPEAKER = 0xc030, + SWTEXTOFF = 0xc050, // (AKA LORES ON) + SWTEXTON = 0xc051, + SWMIXEDOFF = 0xc052, + SWMIXEDON = 0xc053, + SWPAGE2OFF = 0xc054, + SWPAGE2ON = 0xc055, + SWHIRESOFF = 0xc056, + SWHIRESON = 0xc057, // this one is inverted, the ON is the even address - SWDHIRESOFF = 0xc05f, // AN3_ON - SWDHIRESON = 0xc05e, // AN3_OFF - SWAN3 = 0xc05e, // AN3 status - SWAN3_REGISTER = 0xc05f, // AN3 register for video mode - SWRDDHIRES = 0xc07f, - - SWRAMRDOFF = 0xc002, - SWRAMRDON = 0xc003, - SWRAMWRTOFF = 0xc004, - SWRAMWRTON = 0xc005, - SWALTPZOFF = 0xc008, - SWALTPZON = 0xc009, - SWINTCXROMOFF = 0xc006, - SWINTCXROMON = 0xc007, - SWSLOTC3ROMOFF = 0xc00a, - SWSLOTC3ROMON = 0xc00b, - SWBSRBANK2 = 0xc011, - SWBSRREADRAM = 0xc012, - - SWRAMRD = 0xc013, - SWRAMWRT = 0xc014, - SWINTCXROM = 0xc015, - SWALTPZ = 0xc016, - SWSLOTC3ROM = 0xc017, - - SWSPEAKER = 0xc030, - SWKBD = 0xc000, - SWAKD = 0xc010, - + SWDHIRESON = 0xc05e, // AN3_OFF + SWDHIRESOFF = 0xc05f, // AN3_ON + SWAN3 = 0xc05e, // AN3 status + SWAN3_REGISTER = 0xc05f, // AN3 register for video mode + SWRDDHIRES = 0xc07f, }; /* diff --git a/src/mii_video.h b/src/mii_video.h index fc6d14a..b93b20c 100644 --- a/src/mii_video.h +++ b/src/mii_video.h @@ -15,13 +15,20 @@ #define MII_VIDEO_WIDTH (280 * 2) #define MII_VIDEO_HEIGHT (192 * 2) // in case padding is needed, these can be changed + +#if 0 // Loads of padding to align to power of 2 sizes +#define MII_VRAM_WIDTH (1024 * 4) +#define MII_VRAM_HEIGHT 512 +#else #define MII_VRAM_WIDTH (MII_VIDEO_WIDTH * 4) #define MII_VRAM_HEIGHT MII_VIDEO_HEIGHT +#endif enum { MII_VIDEO_COLOR = 0, MII_VIDEO_GREEN, MII_VIDEO_AMBER, + MII_VIDEO_MODE_COUNT }; struct mii_t; diff --git a/ui_gl/mii_emu_gl.c b/ui_gl/mii_emu_gl.c index d541f6f..ed7100e 100644 --- a/ui_gl/mii_emu_gl.c +++ b/ui_gl/mii_emu_gl.c @@ -36,9 +36,10 @@ #define WINDOW_WIDTH 1280 #define WINDOW_HEIGHT 720 +#define POWER_OF_TWO 0 typedef struct mii_gl_tex_t { - c2_rect_t frame; +// c2_rect_t frame; GLuint id; } mii_gl_tex_t; @@ -47,6 +48,7 @@ typedef struct mii_x11_t { pthread_t cpu_thread; mui_drawable_t dr; // drawable + uint32_t dr_padded_y; union { struct { @@ -392,6 +394,7 @@ mii_x11_init( ui->glContext = create_context(ui->dpy, ui->fbc, 0, True, attr); } } + XSync(ui->dpy, False); XSetErrorHandler(old_handler); if (gl_err || !ui->glContext) @@ -402,9 +405,28 @@ mii_x11_init( mui_pixmap_t* pix = &ui->dr.pix; pix->size.y = WINDOW_HEIGHT; pix->size.x = WINDOW_WIDTH; - pix->row_bytes = WINDOW_WIDTH * 4; + // annoyingly I have to make it a LOT bigger to handle that the + // non-power-of-2 texture extension is not avialable everywhere + // textures, which is a bit of a waste of memory, but oh well. + +#if POWER_OF_TWO + int padded_x = 1; + int padded_y = 1; + while (padded_x < pix->size.x) + padded_x <<= 1; + while (padded_y < pix->size.y) + padded_y <<= 1; +#else + int padded_x = pix->size.x; + int padded_y = pix->size.y; +#endif + pix->row_bytes = padded_x * 4; pix->bpp = 32; - pix->pixels = malloc(pix->row_bytes * WINDOW_HEIGHT * (pix->bpp / 8)); + + ui->dr_padded_y = padded_y; + printf("MUI Padded UI size is %dx%d\n", padded_x, padded_y); + + pix->pixels = malloc(pix->row_bytes * ui->dr_padded_y); mui->screen_size = pix->size; } { @@ -631,7 +653,7 @@ mii_x11_prepare_textures( mii_x11_t *ui) { mii_t * mii = &ui->video.mii; - mui_t * mui = &ui->video.mui; +// mui_t * mui = &ui->video.mui; GLuint tex[2]; glGenTextures(2, tex); for (int i = 0; i < 2; i++) { @@ -658,9 +680,10 @@ mii_x11_prepare_textures( glBindTexture(GL_TEXTURE_2D, ui->mui_tex.id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, 4, - ui->dr.pix.row_bytes / 4, - mui->screen_size.y, 0, GL_RGBA, + ui->dr.pix.row_bytes / 4, // already power of two. + ui->dr_padded_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, ui->dr.pix.pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -730,10 +753,10 @@ mii_x11_render( glTexCoord2f(ui->attr.width / (double)(ui->dr.pix.row_bytes / 4), 0); glVertex2f(ui->attr.width, 0); glTexCoord2f(ui->attr.width / (double)(ui->dr.pix.row_bytes / 4), - ui->attr.height / (double)(ui->dr.pix.size.y)); + ui->attr.height / (double)(ui->dr_padded_y)); glVertex2f(ui->attr.width, ui->attr.height); glTexCoord2f(0, - ui->attr.height / (double)(ui->dr.pix.size.y)); + ui->attr.height / (double)(ui->dr_padded_y)); glVertex2f(0, ui->attr.height); glEnd(); } @@ -857,6 +880,8 @@ mii_x11_reload_config( ui->cpu_thread = mii_thread_start(mii); } +mii_x11_t g_mii = {}; + int main( int argc, @@ -866,7 +891,6 @@ main( asprintf(&conf_path, "%s/.local/share/mii", getenv("HOME")); mkdir(conf_path, 0755); - mii_x11_t g_mii = {}; mii_x11_t * ui = &g_mii; mii_t * mii = &g_mii.video.mii; bool no_config_found = false; @@ -990,6 +1014,7 @@ main( glViewport(0, 0, ui->width, ui->height); _mii_transition(ui); mii_x11_render(ui); + glFlush(); glXSwapBuffers(ui->dpy, ui->win); } /* Wait for next frame */ diff --git a/ui_gl/mii_mui_menus.c b/ui_gl/mii_mui_menus.c index 4e63294..b4b248f 100644 --- a/ui_gl/mii_mui_menus.c +++ b/ui_gl/mii_mui_menus.c @@ -333,8 +333,8 @@ mii_mui_menu_slot_menu_update( mui_control_t * m = mui_control_get_by_id(mbar, FCC('f','i','l','e')); mui_menu_items_t * items = mui_popupmenu_get_items(m); - printf("%s items %p count %d RO:%d\n", - __func__, items, items? items->count : 0, items? items->read_only : 0); +// printf("%s items %p count %d RO:%d\n", +// __func__, items, items? items->count : 0, items? items->read_only : 0); mui_menu_items_clear(items); if (!items->read_only) @@ -373,11 +373,6 @@ mii_mui_menu_slot_menu_update( } // array is NULL terminated mui_menu_items_push(items, (mui_menu_item_t){}); - for (int i = 0; i < (int)items->count; i++) - printf(" %d: %s\n", i, items->e[i].title); - - printf("%s items %p count %d RO:%d done\n", - __func__, items, items? items->count : 0, items? items->read_only : 0); } void @@ -400,4 +395,4 @@ mii_mui_menus_init( mui_menubar_add_simple(mbar, "CPU", FCC('c','p','u','m'), m_cpu_menu); -} \ No newline at end of file +}