- u8 *addr_far, mask, attr, data;
- switch (GET_GLOBAL(vmode_g->memmodel)) {
- case PLANAR4:
- case PLANAR1:
- addr_far = (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_far);
- if (AL & 0x80)
- outw(0x1803, VGAREG_GRDC_ADDRESS);
- SET_FARVAR(0xa000, *addr_far, AL);
- outw(0xff08, VGAREG_GRDC_ADDRESS);
- outw(0x0005, VGAREG_GRDC_ADDRESS);
- outw(0x0003, VGAREG_GRDC_ADDRESS);
- break;
- case CGA:
- if (GET_GLOBAL(vmode_g->pixbits) == 2)
- addr_far = (void*)((CX >> 2) + (DX >> 1) * 80);
- else
- addr_far = (void*)((CX >> 3) + (DX >> 1) * 80);
- if (DX & 1)
- addr_far += 0x2000;
- data = GET_FARVAR(0xb800, *addr_far);
- if (GET_GLOBAL(vmode_g->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_far, data);
- break;
- case LINEAR8:
- addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
- SET_FARVAR(0xa000, *addr_far, AL);
- break;
- }
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_read_pixel(u8 BH, u16 CX, u16 DX, u16 *AX)
-{
- // Get the mode
- struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
- if (!vmode_g)
- return;
- if (GET_GLOBAL(vmode_g->class) == TEXT)
- return;
-
- u8 *addr_far, mask, attr=0, data, i;
- switch (GET_GLOBAL(vmode_g->memmodel)) {
- case PLANAR4:
- case PLANAR1:
- addr_far = (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_far) & mask;
- if (data > 0)
- attr |= (0x01 << i);
- }
- break;
- case CGA:
- addr_far = (void*)((CX >> 2) + (DX >> 1) * 80);
- if (DX & 1)
- addr_far += 0x2000;
- data = GET_FARVAR(0xb800, *addr_far);
- if (GET_GLOBAL(vmode_g->pixbits) == 2)
- attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03;
- else
- attr = (data >> (7 - (CX & 0x07))) & 0x01;
- break;
- case LINEAR8:
- addr_far = (void*)(CX + DX * (GET_BDA(video_cols) * 8));
- attr = GET_FARVAR(0xa000, *addr_far);
- break;
- }
- *AX = (*AX & 0xff00) | attr;
-}
-
-// -------------------------------------------------------------------
-static void
-biosfn_write_teletype(u8 car, u8 page, u8 attr, u8 flag)
-{ // flag = WITH_ATTR / NO_ATTR
- // special case if page is 0xff, use current page
- if (page == 0xff)
- page = GET_BDA(video_page);
-
- // Get the mode
- struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode));
- if (!vmode_g)
- return;
-
- // Get the cursor pos for the page
- u16 cursor = biosfn_get_cursor_pos(page);
- u8 xcurs = cursor & 0x00ff;
- u8 ycurs = (cursor & 0xff00) >> 8;
-
- // Get the dimensions
- u16 nbrows = GET_BDA(video_rows) + 1;
- u16 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);
- cursor = biosfn_get_cursor_pos(page);
- xcurs = cursor & 0x00ff;
- ycurs = (cursor & 0xff00) >> 8;
- } while (xcurs % 8 == 0);
- break;
-
- default:
-
- if (GET_GLOBAL(vmode_g->class) == TEXT) {
- // Compute the address
- u8 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, page)
- + (xcurs + ycurs * nbcols) * 2);
- // Write the char
- SET_FARVAR(GET_GLOBAL(vmode_g->sstart), address_far[0], car);
- if (flag == WITH_ATTR)
- SET_FARVAR(GET_GLOBAL(vmode_g->sstart), address_far[1], attr);
- } else {
- // FIXME gfx mode not complete
- struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam);
- u8 cheight = GET_GLOBAL(vparam_g->cheight);
- u8 bpp = GET_GLOBAL(vmode_g->pixbits);
- switch (GET_GLOBAL(vmode_g->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(vmode_g->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_far = (u8*)(regs->dx + 0);
- int i;
- for (i = 0; i < 0x10; i++) {
- outb(i, VGAREG_ACTL_ADDRESS);
- u8 val = GET_FARVAR(regs->es, *data_far);
- outb(val, VGAREG_ACTL_WRITE_DATA);
- data_far++;
- }
- outb(0x11, VGAREG_ACTL_ADDRESS);
- outb(GET_FARVAR(regs->es, *data_far), 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);
-}