// This file may be distributed under the terms of the GNU LGPLv3 license.
#include "biosvar.h" // GET_BDA
+#include "bregs.h" // struct bregs
#include "vgabios.h" // handle_gfx_op
// Draw/undraw a cursor on the framebuffer by xor'ing the cursor cell
}
// Draw/undraw a cursor on the screen
-void
-vgafb_set_swcursor(int enable)
+static void
+set_swcursor(int enable)
{
- if (!vga_emulate_text())
- return;
u8 flags = GET_BDA_EXT(flags);
if (!!(flags & BF_SWCURSOR) == enable)
// Already in requested mode.
attr = (attr >> 4) | (attr << 4);
SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u8*)dest_far, attr);
}
+
+// Disable virtual cursor if a vgabios call accesses the framebuffer
+void
+swcursor_pre_handle10(struct bregs *regs)
+{
+ if (!vga_emulate_text())
+ return;
+ switch (regs->ah) {
+ case 0x4f:
+ if (!CONFIG_VGA_VBE || regs->al != 0x02)
+ break;
+ // NO BREAK
+ case 0x00 ... 0x02:
+ case 0x05 ... 0x0e:
+ case 0x13:
+ set_swcursor(0);
+ break;
+ default:
+ break;
+ }
+}
+
+// Called by periodic (18.2hz) timer
+void
+swcursor_check_event(void)
+{
+ if (!vga_emulate_text())
+ return;
+ set_swcursor(GET_BDA(timer_counter) % 18 < 9);
+}
static void
set_cursor_shape(u16 cursor_type)
{
- vgafb_set_swcursor(0);
SET_BDA(cursor_type, cursor_type);
if (CONFIG_VGA_STDVGA_PORTS)
stdvga_set_cursor_shape(get_cursor_shape());
if (cp.page == GET_BDA(video_page)) {
// Update cursor in hardware
- vgafb_set_swcursor(0);
if (CONFIG_VGA_STDVGA_PORTS)
stdvga_set_cursor_pos((int)text_address(cp));
}
if (!vmode_g)
return;
- vgafb_set_swcursor(0);
-
// Calculate memory address of start of page
struct cursorpos cp = {0, 0, page};
int address = (int)text_address(cp);
if (!vmode_g)
return VBE_RETURN_STATUS_FAILED;
- vgafb_set_swcursor(0);
-
int ret = vgahw_set_mode(vmode_g, flags);
if (ret)
return ret;
handle_10(struct bregs *regs)
{
debug_enter(regs, DEBUG_VGA_10);
+ swcursor_pre_handle10(regs);
+
switch (regs->ah) {
case 0x00: handle_1000(regs); break;
case 0x01: handle_1001(regs); break;
u8 vgafb_read_pixel(u16 x, u16 y);
// swcursor.c
-void vgafb_set_swcursor(int enable);
+struct bregs;
+void swcursor_pre_handle10(struct bregs *regs);
+void swcursor_check_event(void);
// vbe.c
extern u32 VBE_total_memory;
#define VBE_VENDOR_STRING "SeaBIOS Developers"
#define VBE_PRODUCT_STRING "SeaBIOS VBE Adapter"
#define VBE_REVISION_STRING "Rev. 1"
-struct bregs;
void handle_104f(struct bregs *regs);
#endif // vgabios.h
struct vgamode_s *vmode_g = get_current_mode();
if (!vmode_g)
return;
- vgafb_set_swcursor(0);
struct gfx_op op;
init_gfx_op(&op, vmode_g);
struct vgamode_s *vmode_g = get_current_mode();
if (!vmode_g)
return 0;
- vgafb_set_swcursor(0);
struct gfx_op op;
init_gfx_op(&op, vmode_g);
vgafb_scroll(struct cursorpos win, struct cursorpos winsize
, int lines, struct carattr ca)
{
- vgafb_set_swcursor(0);
if (!lines) {
// Clear window
vgafb_clear_chars(win, winsize, ca);
struct vgamode_s *vmode_g = get_current_mode();
if (!vmode_g)
return;
- vgafb_set_swcursor(0);
if (GET_GLOBAL(vmode_g->memmodel) != MM_TEXT) {
gfx_write_char(vmode_g, cp, ca);
struct vgamode_s *vmode_g = get_current_mode();
if (!vmode_g)
return (struct carattr){0, 0, 0};
- vgafb_set_swcursor(0);
if (GET_GLOBAL(vmode_g->memmodel) != MM_TEXT)
return gfx_read_char(vmode_g, cp);
void VISIBLE16
handle_timer_hook(void)
{
- if (!vga_emulate_text())
- return;
- vgafb_set_swcursor(GET_BDA(timer_counter) % 18 < 9);
+ swcursor_check_event();
}
static void