- outw(0x0100, VGAREG_SEQU_ADDRESS);
- outw(0x0402, VGAREG_SEQU_ADDRESS);
- outw(0x0704, VGAREG_SEQU_ADDRESS);
- outw(0x0300, VGAREG_SEQU_ADDRESS);
- outw(0x0204, VGAREG_GRDC_ADDRESS);
- outw(0x0005, VGAREG_GRDC_ADDRESS);
- outw(0x0406, VGAREG_GRDC_ADDRESS);
-}
-
-static void
-release_font_access()
-{
- outw(0x0100, VGAREG_SEQU_ADDRESS);
- outw(0x0302, VGAREG_SEQU_ADDRESS);
- outw(0x0304, VGAREG_SEQU_ADDRESS);
- outw(0x0300, VGAREG_SEQU_ADDRESS);
- u16 v = inw(VGAREG_READ_MISC_OUTPUT);
- v = ((v & 0x01) << 10) | 0x0a06;
- outw(v, VGAREG_GRDC_ADDRESS);
- outw(0x0004, VGAREG_GRDC_ADDRESS);
- outw(0x1005, VGAREG_GRDC_ADDRESS);
-}
-
-static void
-set_scan_lines(u8 lines)
-{
- u16 crtc_addr = GET_BDA(crtc_address);
- outb(0x09, crtc_addr);
- u8 crtc_r9 = inb(crtc_addr + 1);
- crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
- outb(crtc_r9, crtc_addr + 1);
- if (lines == 8)
- biosfn_set_cursor_shape(0x06, 0x07);
- else
- biosfn_set_cursor_shape(lines - 4, lines - 3);
- SET_BDA(char_height, lines);
- outb(0x12, crtc_addr);
- u16 vde = inb(crtc_addr + 1);
- outb(0x07, crtc_addr);
- u8 ovl = inb(crtc_addr + 1);
- vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
- u8 rows = vde / lines;
- SET_BDA(video_rows, rows - 1);
- u16 cols = GET_BDA(video_cols);
- SET_BDA(video_pagesize, rows * cols * 2);
-}
-
-static void
-biosfn_load_text_user_pat(u8 AL, u16 ES, u16 BP, u16 CX, u16 DX, u8 BL,
- u8 BH)
-{
- get_font_access();
- u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
- u16 i;
- for (i = 0; i < CX; i++) {
- void *src_far = (void*)(BP + i * BH);
- void *dest_far = (void*)(blockaddr + (DX + i) * 32);
- memcpy_far(SEG_GRAPH, dest_far, ES, src_far, BH);
- }
- release_font_access();
- if (AL >= 0x10)
- set_scan_lines(BH);
-}
-
-static void
-biosfn_load_text_8_14_pat(u8 AL, u8 BL)
-{
- get_font_access();
- u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
- u16 i;
- for (i = 0; i < 0x100; i++) {
- u16 src = i * 14;
- void *dest_far = (void*)(blockaddr + i * 32);
- memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont14[src], 14);
- }
- release_font_access();
- if (AL >= 0x10)
- set_scan_lines(14);
-}
-
-static void
-biosfn_load_text_8_8_pat(u8 AL, u8 BL)
-{
- get_font_access();
- u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
- u16 i;
- for (i = 0; i < 0x100; i++) {
- u16 src = i * 8;
- void *dest_far = (void*)(blockaddr + i * 32);
- memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont8[src], 8);
- }
- release_font_access();
- if (AL >= 0x10)
- set_scan_lines(8);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_set_text_block_specifier(struct bregs *regs)
-{
- outw((regs->bl << 8) | 0x03, VGAREG_SEQU_ADDRESS);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_load_text_8_16_pat(u8 AL, u8 BL)
-{
- get_font_access();
- u16 blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
- u16 i;
- for (i = 0; i < 0x100; i++) {
- u16 src = i * 16;
- void *dest_far = (void*)(blockaddr + i * 32);
- memcpy_far(SEG_GRAPH, dest_far, get_global_seg(), &vgafont16[src], 16);
- }
- release_font_access();
- if (AL >= 0x10)
- set_scan_lines(16);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_get_font_info(u8 BH, u16 *ES, u16 *BP, u16 *CX, u16 *DX)
-{
- switch (BH) {
- case 0x00: {
- u32 segoff = GET_IVT(0x1f).segoff;
- *ES = segoff >> 16;
- *BP = segoff;
- break;
- }
- case 0x01: {
- u32 segoff = GET_IVT(0x43).segoff;
- *ES = segoff >> 16;
- *BP = segoff;
- break;
- }
- case 0x02:
- *ES = get_global_seg();
- *BP = (u32)vgafont14;
- break;
- case 0x03:
- *ES = get_global_seg();
- *BP = (u32)vgafont8;
- break;
- case 0x04:
- *ES = get_global_seg();
- *BP = (u32)vgafont8 + 128 * 8;
- break;
- case 0x05:
- *ES = get_global_seg();
- *BP = (u32)vgafont14alt;
- break;
- case 0x06:
- *ES = get_global_seg();
- *BP = (u32)vgafont16;
- break;
- case 0x07:
- *ES = get_global_seg();
- *BP = (u32)vgafont16alt;
- break;
- default:
- dprintf(1, "Get font info BH(%02x) was discarded\n", BH);
- return;
- }
- // Set byte/char of on screen font
- *CX = GET_BDA(char_height) & 0xff;
-
- // Set Highest char row
- *DX = GET_BDA(video_rows);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_get_ega_info(struct bregs *regs)
-{
- regs->cx = GET_BDA(video_switches) & 0x0f;
- regs->ax = GET_BDA(crtc_address);
- if (regs->ax == VGAREG_MDA_CRTC_ADDRESS)
- regs->bx = 0x0103;
- else
- regs->bx = 0x0003;
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_select_vert_res(struct bregs *regs)
-{
- u8 mctl = GET_BDA(modeset_ctl);
- u8 vswt = GET_BDA(video_switches);
-
- switch (regs->al) {
- case 0x00:
- // 200 lines
- mctl = (mctl & ~0x10) | 0x80;
- vswt = (vswt & ~0x0f) | 0x08;
- break;
- case 0x01:
- // 350 lines
- mctl &= ~0x90;
- vswt = (vswt & ~0x0f) | 0x09;
- break;
- case 0x02:
- // 400 lines
- mctl = (mctl & ~0x80) | 0x10;
- vswt = (vswt & ~0x0f) | 0x09;
- break;
- default:
- dprintf(1, "Select vert res (%02x) was discarded\n", regs->al);
- break;
- }
- SET_BDA(modeset_ctl, mctl);
- SET_BDA(video_switches, vswt);
- regs->ax = 0x1212;
-}
-
-static void
-biosfn_enable_default_palette_loading(struct bregs *regs)
-{
- u8 v = (regs->al & 0x01) << 3;
- u8 mctl = GET_BDA(video_ctl) & ~0x08;
- SET_BDA(video_ctl, mctl | v);
- regs->ax = 0x1212;
-}
-
-static void
-biosfn_enable_video_addressing(struct bregs *regs)
-{
- u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
- u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02;
- outb(v | v2, VGAREG_WRITE_MISC_OUTPUT);
- regs->ax = 0x1212;
-}
-
-
-static void
-biosfn_enable_grayscale_summing(struct bregs *regs)
-{
- u8 v = ((regs->al << 1) & 0x02) ^ 0x02;
- u8 v2 = GET_BDA(modeset_ctl) & ~0x02;
- SET_BDA(modeset_ctl, v | v2);
- regs->ax = 0x1212;
-}
-
-static void
-biosfn_enable_cursor_emulation(struct bregs *regs)
-{
- u8 v = (regs->al & 0x01) ^ 0x01;
- u8 v2 = GET_BDA(modeset_ctl) & ~0x01;
- SET_BDA(modeset_ctl, v | v2);
- regs->ax = 0x1212;
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_write_string(u8 flag, u8 page, u8 attr, u16 count, u8 row, u8 col,
- u16 seg, u8 *offset_far)
-{
- // Read curs info for the page
- u16 oldcurs = biosfn_get_cursor_pos(page);
-
- // if row=0xff special case : use current cursor position
- if (row == 0xff) {
- col = oldcurs & 0x00ff;
- row = (oldcurs & 0xff00) >> 8;
- }
-
- u16 newcurs = row;
- newcurs <<= 8;
- newcurs += col;
- biosfn_set_cursor_pos(page, newcurs);
-
- while (count-- != 0) {
- u8 car = GET_FARVAR(seg, *offset_far);
- offset_far++;
- if ((flag & 0x02) != 0) {
- attr = GET_FARVAR(seg, *offset_far);
- offset_far++;
- }
-
- biosfn_write_teletype(car, page, attr, WITH_ATTR);
- }
-
- // Set back curs pos
- if ((flag & 0x01) == 0)
- biosfn_set_cursor_pos(page, oldcurs);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_read_display_code(struct bregs *regs)
-{
- regs->bx = GET_BDA(dcc_index);
- regs->al = 0x1a;
-}
-
-static void
-biosfn_set_display_code(struct bregs *regs)
-{
- SET_BDA(dcc_index, regs->bl);
- dprintf(1, "Alternate Display code (%02x) was discarded\n", regs->bh);
- regs->al = 0x1a;
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_read_state_info(u16 BX, u16 ES, u16 DI)
-{
- // Address of static functionality table
- SET_FARVAR(ES, *(u16*)(DI + 0x00), (u32)static_functionality);
- SET_FARVAR(ES, *(u16*)(DI + 0x02), get_global_seg());
-
- // Hard coded copy from BIOS area. Should it be cleaner ?
- memcpy_far(ES, (void*)(DI + 0x04), SEG_BDA, (void*)0x49, 30);
- memcpy_far(ES, (void*)(DI + 0x22), SEG_BDA, (void*)0x84, 3);
-
- SET_FARVAR(ES, *(u8*)(DI + 0x25), GET_BDA(dcc_index));
- SET_FARVAR(ES, *(u8*)(DI + 0x26), 0);
- SET_FARVAR(ES, *(u8*)(DI + 0x27), 16);
- SET_FARVAR(ES, *(u8*)(DI + 0x28), 0);
- SET_FARVAR(ES, *(u8*)(DI + 0x29), 8);
- SET_FARVAR(ES, *(u8*)(DI + 0x2a), 2);
- SET_FARVAR(ES, *(u8*)(DI + 0x2b), 0);
- SET_FARVAR(ES, *(u8*)(DI + 0x2c), 0);
- SET_FARVAR(ES, *(u8*)(DI + 0x31), 3);
- SET_FARVAR(ES, *(u8*)(DI + 0x32), 0);
-
- memset_far(ES, (void*)(DI + 0x33), 0, 13);
-}
-
-// -------------------------------------------------------------------
-// -------------------------------------------------------------------
-static u16
-biosfn_read_video_state_size(u16 CX)
-{
- u16 size = 0;
- if (CX & 1)
- size += 0x46;
- if (CX & 2)
- size += (5 + 8 + 5) * 2 + 6;
- if (CX & 4)
- size += 3 + 256 * 3 + 1;
- return size;
-}