diff --git a/include/tui.h b/include/tui.h index d239d46..5ee1618 100644 --- a/include/tui.h +++ b/include/tui.h @@ -4,6 +4,14 @@ #include #include +/* On 16-bit DOS, the screen buffer lives in far heap to save near heap. + * GW_FAR expands to __far on 16-bit OpenWatcom, nothing elsewhere. */ +#if defined(_M_I86) +#define GW_FAR __far +#else +#define GW_FAR +#endif + #define TUI_DEFAULT_ROWS 25 #define TUI_DEFAULT_COLS 80 #define TUI_MAX_ROWS 200 @@ -50,7 +58,7 @@ typedef struct { /* TUI state */ typedef struct { - tui_cell_t *screen; /* dynamically allocated [rows * cols] */ + tui_cell_t GW_FAR *screen; /* dynamically allocated [rows * cols] */ int rows; /* screen height (default 25) */ int cols; /* screen width (default 80) */ int cursor_row; diff --git a/src/tui.c b/src/tui.c index 04b78e5..6145683 100644 --- a/src/tui.c +++ b/src/tui.c @@ -9,6 +9,9 @@ #include #include #endif +#ifdef _M_I86 +#include /* _fcalloc, _ffree */ +#endif tui_state_t tui; @@ -37,8 +40,13 @@ static const char *default_fkeys[10] = { static void scroll_up(void) { int bottom = tui.view_bottom; +#ifdef _M_I86 + _fmemmove(&TUI_CELL(0, 0), &TUI_CELL(1, 0), + bottom * tui.cols * sizeof(tui_cell_t)); +#else memmove(&TUI_CELL(0, 0), &TUI_CELL(1, 0), bottom * tui.cols * sizeof(tui_cell_t)); +#endif for (int c = 0; c < tui.cols; c++) { TUI_CELL(bottom, c).ch = ' '; TUI_CELL(bottom, c).attr = tui.current_attr; @@ -666,10 +674,13 @@ void tui_init(bool fullscreen) tui.view_bottom = tui.rows - 1; /* Allocate screen buffer */ + /* On 16-bit DOS, use far heap to avoid exhausting the 64KB data segment */ +#ifdef _M_I86 + tui.screen = _fcalloc(tui.rows * tui.cols, sizeof(tui_cell_t)); +#else tui.screen = calloc(tui.rows * tui.cols, sizeof(tui_cell_t)); +#endif if (!tui.screen) { - /* Not enough near heap (common on 16-bit DOS). - * Disable TUI — batch mode still works via HAL. */ tui.active = false; return; } @@ -732,7 +743,11 @@ void tui_shutdown(void) printf("\033[0 q"); fflush(stdout); +#ifdef _M_I86 + _ffree(tui.screen); +#else free(tui.screen); +#endif tui.screen = NULL; signal(SIGINT, SIG_DFL);