diff options
| author | Javier <dev.git@javispedro.com> | 2022-04-04 00:22:24 +0200 | 
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2022-04-04 00:22:24 +0200 | 
| commit | 87397e96fd87a3741f63aa1e898d92fe8133a78e (patch) | |
| tree | 50b64a633c7e2fb96796eedc741ffb066f18dd00 | |
| parent | f9b0699da8adb44fd91640180a7b70639a43449b (diff) | |
| download | vbados-87397e96fd87a3741f63aa1e898d92fe8133a78e.tar.gz vbados-87397e96fd87a3741f63aa1e898d92fe8133a78e.zip | |
add planar/ega mode cursor support
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | dostsr.c | 5 | ||||
| -rw-r--r-- | int10vga.h | 91 | 
3 files changed, 89 insertions, 8 deletions
| @@ -4,4 +4,5 @@ vbmouse.flp  *.o  *.obj  *.map +*.err  runvm.sh @@ -332,7 +332,8 @@ static void refresh_cursor(void)  		// we will have to play with the VGA registers  		// so let's save and restore them.  		if (video_planar) { -			save_video_registers(®s); +			vga_save_registers(®s); +			vga_set_graphics_mode(®s, 0, 0);  		}  		if (data.cursor_visible) { @@ -343,7 +344,7 @@ static void refresh_cursor(void)  		}  		if (video_planar) { -			restore_video_registers(®s); +			vga_restore_register(®s);  		}  	} else {  		// Unknown video mode, don't render cursor. @@ -2,6 +2,7 @@  #define INT10_H  #include <stdint.h> +#include <conio.h>  #define BIOS_DATA_AREA_SEGMENT 0x40 @@ -191,23 +192,101 @@ static inline uint8_t __far * get_video_scanline(const struct modeinfo *info, un  	}  } +enum vga_io_ports { +	VGA_PORT_SC_ADDRESS = 0x3c4, +	VGA_PORT_SC_DATA    = 0x3c5, +	VGA_PORT_GC_ADDRESS = 0x3ce, +	VGA_PORT_GC_DATA    = 0x3cf +}; + +enum vga_sc_regs { +	VGA_SC_REG_MAP_MASK = 2 +}; + +enum vga_gc_regs { +	VGA_GC_REG_SET_RESET = 0, +	VGA_GC_REG_ENABLE_SET_RESET = 1, +	VGA_GC_REG_DATA_ROTATE = 3, +	VGA_GC_REG_READ_MAP = 4, +	VGA_GC_REG_GRAPHICS_MODE = 5, +	VGA_GC_REG_BIT_MASK = 8 +}; +  struct videoregs { -	uint16_t dummy; +	uint8_t sc_reg; +	uint8_t sc_map_mask; +	uint8_t gc_reg; +	uint8_t gc_enable_set_reset; +	uint8_t gc_data_rotate; +	uint8_t gc_graphics_mode; +	uint8_t gc_read_map; +	uint8_t gc_bit_mask;  }; -static void save_video_registers(struct videoregs *regs) +static inline uint8_t vga_sc_reg_read(uint8_t reg) +{ +	outp(VGA_PORT_SC_ADDRESS, reg); +	return inp(VGA_PORT_SC_DATA); +} + +static inline void vga_sc_reg_write(uint8_t reg, uint8_t val) +{ +	// Do one 16-bit write, the higher part will be the data while the lower byte the register. +	outpw(VGA_PORT_SC_ADDRESS, (val << 8) | reg); +} + +static inline uint8_t vga_gc_reg_read(uint8_t reg)  { -	// TODO +	outp(VGA_PORT_GC_ADDRESS, reg); +	return inp(VGA_PORT_GC_DATA);  } -static void restore_video_registers(struct videoregs *regs) +static inline void vga_gc_reg_write(uint8_t reg, uint8_t val)  { -	// TODO +	outpw(VGA_PORT_GC_ADDRESS, (val << 8) | reg); +} + +static void vga_save_registers(struct videoregs __far *regs) +{ +	regs->sc_reg = inp(VGA_PORT_SC_ADDRESS); +	regs->sc_map_mask = vga_sc_reg_read(VGA_SC_REG_MAP_MASK); +	regs->gc_reg = inp(VGA_PORT_GC_ADDRESS); +	regs->gc_enable_set_reset = vga_gc_reg_read(VGA_GC_REG_ENABLE_SET_RESET); +	regs->gc_data_rotate = vga_gc_reg_read(VGA_GC_REG_DATA_ROTATE); +	regs->gc_read_map = vga_gc_reg_read(VGA_GC_REG_READ_MAP); +	regs->gc_graphics_mode = vga_gc_reg_read(VGA_GC_REG_GRAPHICS_MODE); +	regs->gc_bit_mask = vga_gc_reg_read(VGA_GC_REG_BIT_MASK); +} + +static void vga_restore_register(struct videoregs __far *regs) +{ +	vga_sc_reg_write(VGA_SC_REG_MAP_MASK, regs->sc_map_mask); +	outp(VGA_PORT_SC_ADDRESS, regs->sc_reg); +	vga_gc_reg_write(VGA_GC_REG_ENABLE_SET_RESET, regs->gc_enable_set_reset); +	vga_gc_reg_write(VGA_GC_REG_DATA_ROTATE, regs->gc_data_rotate); +	vga_gc_reg_write(VGA_GC_REG_READ_MAP, regs->gc_read_map); +	vga_gc_reg_write(VGA_GC_REG_GRAPHICS_MODE, regs->gc_graphics_mode); +	vga_gc_reg_write(VGA_GC_REG_BIT_MASK, regs->gc_bit_mask); +	outp(VGA_PORT_GC_ADDRESS, regs->gc_reg); +} + +static void vga_set_graphics_mode(struct videoregs __far *regs, unsigned read, unsigned write) +{ +	vga_gc_reg_write(VGA_GC_REG_GRAPHICS_MODE, (regs->gc_graphics_mode & ~(8|3)) +	                                           | ((read << 3) & 8) | write & 3); +	if (write == 0) { +		// Set registers to a reasonable default ... +		vga_gc_reg_write(VGA_GC_REG_ENABLE_SET_RESET, 0); +		vga_gc_reg_write(VGA_GC_REG_DATA_ROTATE, 0); +		vga_gc_reg_write(VGA_GC_REG_BIT_MASK, 0xFF); +	}  }  static inline void vga_select_plane(unsigned plane)  { -	// TODO +	vga_gc_reg_write(VGA_GC_REG_READ_MAP, plane & 0x3); +	vga_sc_reg_write(VGA_SC_REG_MAP_MASK, 1 << plane); +  }  #endif | 
