- u8 mask, attr, data;
-
- // Get the mode
- u8 mode = GET_BDA(video_mode);
- u8 line = find_vga_entry(mode);
- if (line == 0xFF)
- return;
- if (GET_GLOBAL(vga_modes[line].class) == TEXT)
- return;
-
- u8 *addr;
- switch (GET_GLOBAL(vga_modes[line].memmodel)) {
- case PLANAR4:
- case PLANAR1:
- addr = (void*)(CX / 8 + DX * GET_BDA(video_cols));
- mask = 0x80 >> (CX & 0x07);
- outw((mask << 8) | 0x08, VGAREG_GRDC_ADDRESS);
- outw(0x0205, VGAREG_GRDC_ADDRESS);
- data = GET_FARVAR(0xa000, *addr);
- if (AL & 0x80)
- outw(0x1803, VGAREG_GRDC_ADDRESS);
- SET_FARVAR(0xa000, *addr, AL);
- outw(0xff08, VGAREG_GRDC_ADDRESS);
- outw(0x0005, VGAREG_GRDC_ADDRESS);
- outw(0x0003, VGAREG_GRDC_ADDRESS);
- break;
- case CGA:
- if (GET_GLOBAL(vga_modes[line].pixbits) == 2)
- addr = (void*)((CX >> 2) + (DX >> 1) * 80);
- else
- addr = (void*)((CX >> 3) + (DX >> 1) * 80);
- if (DX & 1)
- addr += 0x2000;
- data = GET_FARVAR(0xb800, *addr);
- if (GET_GLOBAL(vga_modes[line].pixbits) == 2) {
- attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2);
- mask = 0x03 << ((3 - (CX & 0x03)) * 2);
- } else {
- attr = (AL & 0x01) << (7 - (CX & 0x07));
- mask = 0x01 << (7 - (CX & 0x07));
- }
- if (AL & 0x80) {
- data ^= attr;
- } else {
- data &= ~mask;
- data |= attr;
- }
- SET_FARVAR(0xb800, *addr, data);
- break;
- case LINEAR8:
- addr = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
- SET_FARVAR(0xa000, *addr, AL);
- break;
- }
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX)
-{
- u8 mode, line, mask, attr, data, i;
-
- // Get the mode
- mode = GET_BDA(video_mode);
- line = find_vga_entry(mode);
- if (line == 0xFF)
- return;
- if (GET_GLOBAL(vga_modes[line].class) == TEXT)
- return;
-
- u8 *addr;
- switch (GET_GLOBAL(vga_modes[line].memmodel)) {
- case PLANAR4:
- case PLANAR1:
- addr = (void*)(CX / 8 + DX * GET_BDA(video_cols));
- mask = 0x80 >> (CX & 0x07);
- attr = 0x00;
- for (i = 0; i < 4; i++) {
- outw((i << 8) | 0x04, VGAREG_GRDC_ADDRESS);
- data = GET_FARVAR(0xa000, *addr) & mask;
- if (data > 0)
- attr |= (0x01 << i);
- }
- break;
- case CGA:
- addr = (void*)((CX >> 2) + (DX >> 1) * 80);
- if (DX & 1)
- addr += 0x2000;
- data = GET_FARVAR(0xb800, *addr);
- if (GET_GLOBAL(vga_modes[line].pixbits) == 2)
- attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03;
- else
- attr = (data >> (7 - (CX & 0x07))) & 0x01;
- break;
- case LINEAR8:
- addr = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
- attr = GET_FARVAR(0xa000, *addr);
- break;
- }
- *AX = (*AX & 0xff00) | attr;
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
-{ // flag = WITH_ATTR / NO_ATTR
- u8 cheight, xcurs, ycurs, mode, line, bpp;
- u16 nbcols, nbrows;
- u16 cursor, dummy;
-
- // special case if page is 0xff, use current page
- if (page == 0xff)
- page = GET_BDA(video_page);
-
- // Get the mode
- mode = GET_BDA(video_mode);
- line = find_vga_entry(mode);
- if (line == 0xFF)
- return;
-
- // Get the cursor pos for the page
- biosfn_get_cursor_pos(page, &dummy, &cursor);
- xcurs = cursor & 0x00ff;
- ycurs = (cursor & 0xff00) >> 8;
-
- // Get the dimensions
- nbrows = GET_BDA(video_rows) + 1;
- nbcols = GET_BDA(video_cols);
-
- switch (car) {
- case 7:
- //FIXME should beep
- break;
-
- case 8:
- if (xcurs > 0)
- xcurs--;
- break;
-
- case '\r':
- xcurs = 0;
- break;
-
- case '\n':
- ycurs++;
- break;
-
- case '\t':
- do {
- biosfn_write_teletype(' ', page, attr, flag);
- biosfn_get_cursor_pos(page, &dummy, &cursor);
- xcurs = cursor & 0x00ff;
- ycurs = (cursor & 0xff00) >> 8;
- } while (xcurs % 8 == 0);
- break;
-
- default:
-
- if (GET_GLOBAL(vga_modes[line].class) == TEXT) {
- // Compute the address
- u8 *address = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
- + (xcurs + ycurs * nbcols) * 2);
- // Write the char
- SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), address[0], car);
- if (flag == WITH_ATTR)
- SET_FARVAR(GET_GLOBAL(vga_modes[line].sstart), address[1], attr);
- } else {
- // FIXME gfx mode not complete
- cheight = GET_GLOBAL(video_param_table[GET_GLOBAL(line_to_vpti[line])].cheight);
- bpp = GET_GLOBAL(vga_modes[line].pixbits);
- switch (GET_GLOBAL(vga_modes[line].memmodel)) {
- case PLANAR4:
- case PLANAR1:
- write_gfx_char_pl4(car, attr, xcurs, ycurs, nbcols,
- cheight);
- break;
- case CGA:
- write_gfx_char_cga(car, attr, xcurs, ycurs, nbcols, bpp);
- break;
- case LINEAR8:
- write_gfx_char_lin(car, attr, xcurs, ycurs, nbcols);
- break;
- }
- }
- xcurs++;
- }
-
- // Do we need to wrap ?
- if (xcurs == nbcols) {
- xcurs = 0;
- ycurs++;
- }
- // Do we need to scroll ?
- if (ycurs == nbrows) {
- if (GET_GLOBAL(vga_modes[line].class) == TEXT)
- biosfn_scroll(0x01, 0x07, 0, 0, nbrows - 1, nbcols - 1, page,
- SCROLL_UP);
- else
- biosfn_scroll(0x01, 0x00, 0, 0, nbrows - 1, nbcols - 1, page,
- SCROLL_UP);
- ycurs -= 1;
- }
- // Set the cursor for the page
- cursor = ycurs;
- cursor <<= 8;
- cursor += xcurs;
- biosfn_set_cursor_pos(page, cursor);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_get_video_mode(struct bregs *regs)
-{
- regs->bh = GET_BDA(video_page);
- regs->al = GET_BDA(video_mode) | (GET_BDA(video_ctl) & 0x80);
- regs->ah = GET_BDA(video_cols);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_set_overscan_border_color(struct bregs *regs)
-{
- inb(VGAREG_ACTL_RESET);
- outb(0x11, VGAREG_ACTL_ADDRESS);
- outb(regs->bh, VGAREG_ACTL_WRITE_DATA);
- outb(0x20, VGAREG_ACTL_ADDRESS);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_set_all_palette_reg(struct bregs *regs)
-{
- inb(VGAREG_ACTL_RESET);
-
- u8 *data = (u8*)(regs->dx + 0);
- int i;
- for (i = 0; i < 0x10; i++) {
- outb(i, VGAREG_ACTL_ADDRESS);
- u8 val = GET_FARVAR(regs->es, *data);
- outb(val, VGAREG_ACTL_WRITE_DATA);
- data++;
- }
- outb(0x11, VGAREG_ACTL_ADDRESS);
- outb(GET_FARVAR(regs->es, *data), VGAREG_ACTL_WRITE_DATA);
- outb(0x20, VGAREG_ACTL_ADDRESS);
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_toggle_intensity(struct bregs *regs)
-{
- inb(VGAREG_ACTL_RESET);
- outb(0x10, VGAREG_ACTL_ADDRESS);
- u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0x7f) | ((regs->bl & 0x01) << 3);
- outb(val, VGAREG_ACTL_WRITE_DATA);
- outb(0x20, VGAREG_ACTL_ADDRESS);
-}
-
-// -------------------------------------------------------------------
-void
-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 = (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, inb(VGAREG_ACTL_READ_DATA));
- data++;
- }
- inb(VGAREG_ACTL_RESET);
- outb(0x11, VGAREG_ACTL_ADDRESS);
- SET_FARVAR(regs->es, *data, 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 = (u8*)(regs->dx + 0);
- int count = regs->cx;
- while (count) {
- outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
- data++;
- outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
- data++;
- outb(GET_FARVAR(regs->es, *data), VGAREG_DAC_DATA);
- data++;
- 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 = (u8*)(regs->dx + 0);
- int count = regs->cx;
- while (count) {
- SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
- data++;
- SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
- data++;
- SET_FARVAR(regs->es, *data, inb(VGAREG_DAC_DATA));
- data++;
- 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, cols, vde;
- u8 crtc_r9, ovl, rows;
-
- crtc_addr = GET_BDA(crtc_address);
- outb(0x09, crtc_addr);
- 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);
- vde = inb(crtc_addr + 1);
- outb(0x07, crtc_addr);
- ovl = inb(crtc_addr + 1);
- vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
- rows = vde / lines;
- SET_BDA(video_rows, rows - 1);
- 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);