From: Robert Pengelly Date: Sun, 18 Oct 2026 11:15:46 +0000 (+0100) Subject: Implement BIOS INT 10h rectangular window scrolling X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=6bd3003d0635f9b487b7e5a61eb90e8536b83af7;p=dosemu.git Implement BIOS INT 10h rectangular window scrolling --- diff --git a/interrupts.c b/interrupts.c index 28a5418..5443907 100644 --- a/interrupts.c +++ b/interrupts.c @@ -6018,6 +6018,35 @@ static uint8_t bios_cursor_end = 7; static uint8_t bios_cursor_row[8]; static uint8_t bios_cursor_col[8]; +static uint8_t bios_video_chars[25][80]; +static uint8_t bios_video_attrs[25][80]; + +static int bios_video_initialized; + +static void bios_video_initialize (void) { + + unsigned row; + unsigned col; + + if (bios_video_initialized) { + return; + } + + for (row = 0; row < 25; row++) { + + for (col = 0; col < 80; col++) { + + bios_video_chars[row][col] = ' '; + bios_video_attrs[row][col] = 0x07; + + } + + } + + bios_video_initialized = 1; + +} + static void bios_write_video_char (uint8_t ch) { if (ch == 0x18) { @@ -6079,7 +6108,7 @@ static void int_10 (CPU8086 *cpu) { } - case 0x06: { /* scroll window up */ + case 0x06: /* scroll window up */ case 0x07: /* scroll window down */ { uint8_t lines = get_reg8 (cpu, REG_AX); uint8_t attr = (uint8_t) (cpu->regs[REG_BX] >> 8); @@ -6100,48 +6129,78 @@ static void int_10 (CPU8086 *cpu) { height = (unsigned) bottom - top + 1; - if (lines == 0 || lines >= height) { - - /* Blank only the requested window, leaving the cursor in place. */ - if (top == 0 && left == 0 && bottom == 24 && right == 79) { - fputs ("\033[2J", stdout); - } + if (lines >= height) { + lines = 0; + } + + if (lines != 0) { + + if (ah == 0x06) { - fputs ("\0337\033[?7l", stdout); - fprintf (stdout, "\033[%um\033[%um", 40 + (attr >> 4 & 7), 30 + (attr & 7)); + for (row = top; row + lines <= bottom; row++) { + + for (col = left; col <= right; col++) { + + bios_video_chars[row][col] = bios_video_chars[row + lines][col]; + bios_video_attrs[row][col] = bios_video_attrs[row + lines][col]; + + } + + } - for (row = top; row <= bottom; row++) { + } else { - fprintf (stdout, "\033[%u;%uH", row + 1, (unsigned) left + 1); + for (row = bottom + 1; row > (unsigned) top + lines; ) { + + row--; + + for (col = left; col <= right; col++) { + + bios_video_chars[row][col] = bios_video_chars[row - lines][col]; + bios_video_attrs[row][col] = bios_video_attrs[row - lines][col]; + + } - for (col = left; col <= right; col++) { - fputc (' ', stdout); } } - - fputs ("\033[0m\033[?7h\0338", stdout); - } else if (left == 0 && right == 79) { + } + + for (row = top; row <= bottom; row++) { - /* ANSI scrolling margins act on whole terminal rows. */ - fputs ("\0337", stdout); - fprintf (stdout, "\033[%u;%ur\033[%u;1H", (unsigned) top + 1, (unsigned) bottom + 1, (unsigned) bottom + 1); - - for (row = 0; row < lines; row++) { - fputc ('\n', stdout); + if (lines != 0 && (ah == 0x06 ? row <= (unsigned) bottom - lines : row >= (unsigned) top + lines)) { + continue; } - fputs ("\033[r", stdout); - fputs ("\0338", stdout); + for (col = left; col <= right; col++) { + + bios_video_chars[row][col] = ' '; + bios_video_attrs[row][col] = attr; + + } - } else { + } + + fputs ("\0337\033[?7l", stdout); - /* A partial-width scroll requires a video-cell buffer. */ - fprintf (stderr, "Unsupported partial-width INT 10h AH=06h scroll\n"); + for (row = top; row <= bottom; row++) { + + fprintf (stdout, "\033[%u;%uH", row + 1, (unsigned) left + 1); + + for (col = left; col <= right; col++) { + + uint8_t cell_attr = bios_video_attrs[row][col]; + + fprintf (stdout, "\033[%u;%um", 40 + ((cell_attr >> 4) & 7), 30 + (cell_attr & 7)); + bios_write_video_char (bios_video_chars[row][col]); + + } } + fputs ("\033[0m\033[?7h\0338", stdout); + fflush (stdout); break; @@ -6157,6 +6216,19 @@ static void int_10 (CPU8086 *cpu) { if (page == 0) { + bios_video_initialize (); + + for (i = 0; i < count && (unsigned) bios_cursor_col[0] + i < 80; i++) { + + if (bios_cursor_row[0] < 25) { + + bios_video_chars[bios_cursor_row[0]][bios_cursor_col[0] + i] = al; + bios_video_attrs[bios_cursor_row[0]][bios_cursor_col[0] + i] = (uint8_t) cpu->regs[REG_BX]; + + } + + } + fputs ("\0337\033[?7l", stdout); for (i = 0; i < count; i++) {