-biosfn_set_single_palette_reg(u8 reg, u8 val)
-{
- inb(VGAREG_ACTL_RESET);
- outb(reg, VGAREG_ACTL_ADDRESS);
- outb(val, VGAREG_ACTL_WRITE_DATA);
- outb(0x20, VGAREG_ACTL_ADDRESS);
-}
-
-// -------------------------------------------------------------------
-u8
-biosfn_get_single_palette_reg(u8 reg)
-{
- inb(VGAREG_ACTL_RESET);
- outb(reg, VGAREG_ACTL_ADDRESS);
- u8 v = inb(VGAREG_ACTL_READ_DATA);
- inb(VGAREG_ACTL_RESET);
- outb(0x20, VGAREG_ACTL_ADDRESS);
- return v;
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_read_overscan_border_color(struct bregs *regs)
-{
- inb(VGAREG_ACTL_RESET);
- outb(0x11, VGAREG_ACTL_ADDRESS);
- regs->bh = inb(VGAREG_ACTL_READ_DATA);
- inb(VGAREG_ACTL_RESET);
- outb(0x20, VGAREG_ACTL_ADDRESS);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_get_all_palette_reg(struct bregs *regs)
-{
- u8 *data_far = (u8*)(regs->dx + 0);
- int i;
- for (i = 0; i < 0x10; i++) {
- inb(VGAREG_ACTL_RESET);
- outb(i, VGAREG_ACTL_ADDRESS);
- SET_FARVAR(regs->es, *data_far, inb(VGAREG_ACTL_READ_DATA));
- data_far++;
- }
- inb(VGAREG_ACTL_RESET);
- outb(0x11, VGAREG_ACTL_ADDRESS);
- SET_FARVAR(regs->es, *data_far, inb(VGAREG_ACTL_READ_DATA));
- inb(VGAREG_ACTL_RESET);
- outb(0x20, VGAREG_ACTL_ADDRESS);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_set_single_dac_reg(struct bregs *regs)
-{
- outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS);
- outb(regs->dh, VGAREG_DAC_DATA);
- outb(regs->ch, VGAREG_DAC_DATA);
- outb(regs->cl, VGAREG_DAC_DATA);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_set_all_dac_reg(struct bregs *regs)
-{
- outb(regs->bl, VGAREG_DAC_WRITE_ADDRESS);
- u8 *data_far = (u8*)(regs->dx + 0);
- int count = regs->cx;
- while (count) {
- outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA);
- data_far++;
- outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA);
- data_far++;
- outb(GET_FARVAR(regs->es, *data_far), VGAREG_DAC_DATA);
- data_far++;
- count--;
- }
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_select_video_dac_color_page(struct bregs *regs)
-{
- inb(VGAREG_ACTL_RESET);
- outb(0x10, VGAREG_ACTL_ADDRESS);
- u8 val = inb(VGAREG_ACTL_READ_DATA);
- if (!(regs->bl & 0x01)) {
- val = (val & 0x7f) | (regs->bh << 7);
- outb(val, VGAREG_ACTL_WRITE_DATA);
- outb(0x20, VGAREG_ACTL_ADDRESS);
- return;
- }
- inb(VGAREG_ACTL_RESET);
- outb(0x14, VGAREG_ACTL_ADDRESS);
- u8 bh = regs->bh;
- if (!(val & 0x80))
- bh <<= 2;
- bh &= 0x0f;
- outb(bh, VGAREG_ACTL_WRITE_DATA);
- outb(0x20, VGAREG_ACTL_ADDRESS);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_read_single_dac_reg(struct bregs *regs)
-{
- outb(regs->bl, VGAREG_DAC_READ_ADDRESS);
- regs->dh = inb(VGAREG_DAC_DATA);
- regs->ch = inb(VGAREG_DAC_DATA);
- regs->cl = inb(VGAREG_DAC_DATA);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_read_all_dac_reg(struct bregs *regs)
-{
- outb(regs->bl, VGAREG_DAC_READ_ADDRESS);
- u8 *data_far = (u8*)(regs->dx + 0);
- int count = regs->cx;
- while (count) {
- SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA));
- data_far++;
- SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA));
- data_far++;
- SET_FARVAR(regs->es, *data_far, inb(VGAREG_DAC_DATA));
- data_far++;
- count--;
- }
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_set_pel_mask(struct bregs *regs)
-{
- outb(regs->bl, VGAREG_PEL_MASK);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_read_pel_mask(struct bregs *regs)
-{
- regs->bl = inb(VGAREG_PEL_MASK);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_read_video_dac_state(struct bregs *regs)
-{
- inb(VGAREG_ACTL_RESET);
- outb(0x10, VGAREG_ACTL_ADDRESS);
- u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7;
-
- inb(VGAREG_ACTL_RESET);
- outb(0x14, VGAREG_ACTL_ADDRESS);
- u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f;
- if (!(val1 & 0x01))
- val2 >>= 2;
-
- inb(VGAREG_ACTL_RESET);
- outb(0x20, VGAREG_ACTL_ADDRESS);
-
- regs->bl = val1;
- regs->bh = val2;
-}
-
-// -------------------------------------------------------------------
-static void
-get_font_access()
-{
- 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 = (void*)(BP + i * BH);
- void *dest = (void*)(blockaddr + (DX + i) * 32);
- memcpy_far(0xA000, dest, ES, src, 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 = (void*)(blockaddr + i * 32);
- memcpy_far(0xA000, dest, 0xC000, &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 = (void*)(blockaddr + i * 32);
- memcpy_far(0xA000, dest, 0xC000, &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 = (void*)(blockaddr + i * 32);
- memcpy_far(0xA000, dest, 0xC000, &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 = 0xC000;
- *BP = (u32)vgafont14;
- break;
- case 0x03:
- *ES = 0xC000;
- *BP = (u32)vgafont8;
- break;
- case 0x04:
- *ES = 0xC000;
- *BP = (u32)vgafont8 + 128 * 8;
- break;
- case 0x05:
- *ES = 0xC000;
- *BP = (u32)vgafont14alt;
- break;
- case 0x06:
- *ES = 0xC000;
- *BP = (u32)vgafont16;
- break;
- case 0x07:
- *ES = 0xC000;
- *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)