Use far heap for TUI screen buffer on 16-bit DOS
The 4KB screen buffer (80x25x2 bytes) was allocated from near heap via calloc(), which exhausted the 64KB data segment on 16-bit DOS. Now uses _fcalloc()/_ffree() from OpenWatcom's far heap on 16-bit, keeping the buffer outside DGROUP. The TUI now works fully on 16-bit FreeDOS: full-screen editor, F-key bar, cursor positioning, and scroll -- all via BIOS INT 10h through the DOS HAL, with the screen buffer in far memory. Changes: - tui.h: GW_FAR macro (expands to __far on 16-bit, nothing elsewhere), tui.screen declared as tui_cell_t GW_FAR * - tui.c: _fcalloc/_ffree for 16-bit, _fmemmove for scroll_up() - TUI_CELL() macro works unchanged (far pointer dereference is transparent)
This commit is contained in:
+9
-1
@@ -4,6 +4,14 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* 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;
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef _M_I86
|
||||
#include <malloc.h> /* _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);
|
||||
|
||||
Reference in New Issue
Block a user