text: /*
   * Copyright (c) 2021, Dylan Cleaver <dylancleaver@yahoo.com>
   *
   * SPDX-License-Identifier: BSD-2-Clause
   */
  
  #include <kernel/vga.h>
  #include <stdbool.h>
  #include <sys/io.h>
  
  
  int vga_cursor_pos;
  int vga_cursor_enabled;
  
  
  void
  vga_cursor_enable(uint8_t min_scanline, uint8_t max_scanline)
  {
      /* bytes 0-4 are the min scanline, byte 5 is enable/disable, 6/7 unused */
      outb(0x3D4, 0x0A);
      outb(0x3D5, (inb(0x3D5) & 0xC0) | min_scanline);
  
      outb(0x3D4, 0x0B);
      outb(0x3D5, (inb(0x3D5) & 0xE0) | max_scanline);
      
      vga_cursor_enabled = 1;
  }
  
  
  void
  vga_cursor_disable(void)
  {
      outb(0x3D4, 0x0A);  
      outb(0x3D5, 0x20);
  
      vga_cursor_enabled = 0;
  }
  
  
  int
  vga_cursor_getpos(void)
  {
      int pos = 0;
  
      outb(0x3D4, 0x0F);
      pos |= inb(0x3D5);
      outb(0x3D4, 0x0E);
      pos |= ((uint16_t) inb(0x3D5)) << 8;
  
      return pos;
  }
  
  
  void
  vga_cursor_setpos(int new_xpos, int new_ypos, bool pos_is_relative)
  {
      if (!vga_cursor_enabled)
          return;
  
      uint16_t new_cursor_pos = new_ypos * VGA_NUM_COLS + new_xpos;
      if (pos_is_relative)
      {
          new_cursor_pos += vga_cursor_pos;   
      }
      
  
      /* Tell the command port we are sending the high byte, then send it to
       * the data port. Repeat for low byte.
       */
      outb(0x3D4, 0x0E);
      outb(0x3D5, (new_cursor_pos >> 8));
  
      outb(0x3D4, 0x0F);
      outb(0x3D5, new_cursor_pos);
  
      vga_cursor_pos = new_cursor_pos;
  }
  
  
  void
  vga_cursor_newline()
  {
      size_t cur_line_char = vga_cursor_pos % VGA_NUM_COLS;
      vga_cursor_setpos(VGA_NUM_COLS - cur_line_char, 0, true);
  }
  