Added VBE memory size option (requires latest VGABIOS).

Setting VBE memory size to 4, 8, 16 and 32 MB is now possible. Since a memory
size change can also change the number of available modes and the value for
"number of image pages" in the mode info it is required to use the latest
VGABIOS binary.
Related changes:
- Make sure the VBE entry appears at index 1 of VGA extension option list.
- Removed all memory size constants and use BX_VGA_THIS s.memsize instead.

TODO: Remove the static mode info table and create it dynamicly similar to
      Banshee and Cirrus.
This commit is contained in:
Volker Ruppert 2024-11-03 19:44:55 +01:00
parent 8562c955bf
commit c511f3f270
6 changed files with 67 additions and 33 deletions

View File

@ -51,6 +51,8 @@ Detailed change log :
- Fix Pause / Ctrl+Break key handling (possibly SDL issue)
- I/O Devices
- VGA / Bochs VBE support
- Added VBE memory size option (requires latest VGABIOS)
- Cirrus SVGA
- Added support for hardware cursor in VGA mode
- Fixed text mode cursor blinking / text mode cursor rendering issues

View File

@ -454,7 +454,7 @@ void bx_init_displaylib_list()
void bx_init_vgaext_list()
{
Bit8u i, count = 0;
Bit8u i, j, count = 0;
const char *plugname;
count = PLUG_get_plugins_count(PLUGTYPE_VGA);
@ -462,15 +462,19 @@ void bx_init_vgaext_list()
vga_extension_plugins = (const char**) malloc((count + 1) * sizeof(char*));
vga_extension_names[0] = "none";
vga_extension_plugins[0] = "vga";
vga_extension_names[1] = "vbe";
vga_extension_plugins[1] = "vga";
j = 2;
for (i = 0; i < count; i++) {
plugname = PLUG_get_plugin_name(PLUGTYPE_VGA, i);
vga_extension_plugins[i + 1] = plugname;
if (!strcmp(plugname, "vga")) {
vga_extension_names[i + 1] = "vbe";
} else if (!strcmp(plugname, "svga_cirrus")) {
vga_extension_names[i + 1] = plugname + 5;
} else {
vga_extension_names[i + 1] = plugname;
if (strcmp(plugname, "vga")) {
vga_extension_plugins[j] = plugname;
if (!strcmp(plugname, "svga_cirrus")) {
vga_extension_names[j] = plugname + 5;
} else {
vga_extension_names[j] = plugname;
}
j++;
}
}
vga_extension_names[count + 1] = NULL;
@ -1217,10 +1221,8 @@ void bx_init_options()
"VGA Extension",
"Name of the VGA extension",
vga_extension_names,
0, 0);
vga_extension->set_by_name("vbe");
BX_VGA_EXTENSION_VBE, BX_VGA_EXTENSION_NONE);
vga_extension->set_handler(bx_param_handler);
display->set_options(display->SHOW_PARENT);
static const char *ddc_mode_list[] = {
"disabled",
@ -1244,6 +1246,26 @@ void bx_init_options()
ddc_mode->set_dependent_list(deplist, 0);
ddc_mode->set_dependent_bitmap(BX_DDC_MODE_FILE, 1);
static const char *vbe_memsize_list[] = {
"4",
"8",
"16",
"32",
NULL
};
bx_param_enum_c *vbe_memsize = new bx_param_enum_c(display,
"vbe_memsize",
"VBE memory size (MB)",
"Size of VBE memory in MB",
vbe_memsize_list,
BX_VBE_MEMSIZE_16MB, BX_VBE_MEMSIZE_4MB);
deplist = new bx_list_c(NULL);
deplist->add(vbe_memsize);
vga_extension->set_dependent_list(deplist, 0);
vga_extension->set_dependent_bitmap(BX_VGA_EXTENSION_VBE, 1);
display->set_options(display->SHOW_PARENT);
// keyboard & mouse subtree
bx_list_c *kbd_mouse = new bx_list_c(root_param, "keyboard_mouse", "Keyboard & Mouse Options");
bx_list_c *keyboard = new bx_list_c(kbd_mouse, "keyboard", "Keyboard Options");
@ -3112,6 +3134,8 @@ static int parse_line_formatted(const char *context, int num_params, char *param
SIM->get_param_enum(BXPN_DDC_MODE)->set(BX_DDC_MODE_FILE);
SIM->get_param_string(BXPN_DDC_FILE)->set(strval+5);
}
} else if (!strncmp(params[i], "vbe_memsize=", 12)) {
SIM->get_param_enum(BXPN_VBE_MEMSIZE)->set_by_name(&params[i][12]);
} else {
PARSE_ERR(("%s: vga directive malformed.", context));
}
@ -3742,7 +3766,7 @@ int bx_write_configuration(const char *rc, int overwrite)
if (SIM->get_param_enum(BXPN_DDC_MODE)->get() == BX_DDC_MODE_FILE) {
fprintf(fp, ":%s", SIM->get_param_string(BXPN_DDC_FILE)->getptr());
}
fprintf(fp, "\n");
fprintf(fp, ", vbe_memsize=%s\n", SIM->get_param_enum(BXPN_VBE_MEMSIZE)->get_selected());
#if BX_SUPPORT_SMP
fprintf(fp, "cpu: count=%u:%u:%u, ips=%u, quantum=%d, ",
SIM->get_param_num(BXPN_CPU_NPROCESSORS)->get(), SIM->get_param_num(BXPN_CPU_NCORES)->get(),

View File

@ -441,12 +441,24 @@ enum {
BX_RUN_START
};
enum {
BX_VGA_EXTENSION_NONE,
BX_VGA_EXTENSION_VBE
};
enum {
BX_DDC_MODE_DISABLED,
BX_DDC_MODE_BUILTIN,
BX_DDC_MODE_FILE
};
enum {
BX_VBE_MEMSIZE_4MB,
BX_VBE_MEMSIZE_8MB,
BX_VBE_MEMSIZE_16MB,
BX_VBE_MEMSIZE_32MB
};
enum {
BX_MOUSE_TYPE_NONE,
BX_MOUSE_TYPE_PS2,

View File

@ -91,16 +91,16 @@ bool bx_vga_c::init_vga_extension(void)
DEV_register_ioread_handler(this, vbe_read_handler, addr, "vga video", 7);
DEV_register_iowrite_handler(this, vbe_write_handler, addr, "vga video", 7);
}
BX_VGA_THIS s.memsize = atoi(SIM->get_param_enum(BXPN_VBE_MEMSIZE)->get_selected()) << 20;
if (!BX_VGA_THIS pci_enabled) {
BX_VGA_THIS vbe.base_address = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
DEV_register_memory_handlers(theVga, mem_read_handler, mem_write_handler,
BX_VGA_THIS vbe.base_address,
BX_VGA_THIS vbe.base_address + VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES - 1);
BX_VGA_THIS vbe.base_address + BX_VGA_THIS s.memsize - 1);
}
if (BX_VGA_THIS s.memory == NULL)
BX_VGA_THIS s.memory = new Bit8u[VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES];
memset(BX_VGA_THIS s.memory, 0, VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES);
BX_VGA_THIS s.memsize = VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES;
BX_VGA_THIS s.memory = new Bit8u[BX_VGA_THIS s.memsize];
memset(BX_VGA_THIS s.memory, 0, BX_VGA_THIS s.memsize);
BX_VGA_THIS vbe.cur_dispi=VBE_DISPI_ID0;
BX_VGA_THIS vbe.xres=640;
BX_VGA_THIS vbe.yres=480;
@ -140,7 +140,7 @@ bool bx_vga_c::init_vga_extension(void)
if (BX_VGA_THIS vbe_present) {
BX_VGA_THIS pci_conf[0x10] = 0x08;
BX_VGA_THIS init_bar_mem(0, VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES,
BX_VGA_THIS init_bar_mem(0, BX_VGA_THIS s.memsize,
mem_read_handler, mem_write_handler);
}
BX_VGA_THIS pci_rom_address = 0;
@ -762,7 +762,7 @@ bx_vga_c::vbe_mem_read(bx_phy_address addr)
}
// check for out of memory read
if (offset > VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES)
if (offset > BX_VGA_THIS s.memsize)
return 0;
return (BX_VGA_THIS s.memory[offset]);
@ -787,7 +787,7 @@ bx_vga_c::vbe_mem_write(bx_phy_address addr, Bit8u value)
}
// check for out of memory write
if (offset < VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES) {
if (offset < BX_VGA_THIS s.memsize) {
BX_VGA_THIS s.memory[offset] = value;
} else {
// make sure we don't flood the logfile
@ -894,7 +894,7 @@ Bit32u bx_vga_c::vbe_read(Bit32u address, unsigned io_len)
return BX_VGA_THIS vbe.virtual_yres;
case VBE_DISPI_INDEX_VIDEO_MEMORY_64K:
return (VBE_DISPI_TOTAL_VIDEO_MEMORY_KB >> 6);
return (BX_VGA_THIS s.memsize >> 16);
case VBE_DISPI_INDEX_DDC:
if (BX_VGA_THIS vbe.ddc_enabled) {
@ -1041,7 +1041,7 @@ Bit32u bx_vga_c::vbe_write(Bit32u address, Bit32u value, unsigned io_len)
case VBE_DISPI_INDEX_BANK: // set bank
{
Bit16u num_banks = (Bit16u)(VBE_DISPI_TOTAL_VIDEO_MEMORY_KB / BX_VGA_THIS vbe.bank_granularity_kb);
Bit16u num_banks = (Bit16u)((BX_VGA_THIS s.memsize >> 10) / BX_VGA_THIS vbe.bank_granularity_kb);
Bit16u rw_mode = VBE_DISPI_BANK_RW; // compatibility mode
if (BX_VGA_THIS vbe.bpp == VBE_DISPI_BPP_4) num_banks >>= 2;
if ((value & VBE_DISPI_BANK_RW) != 0) {
@ -1126,7 +1126,7 @@ Bit32u bx_vga_c::vbe_write(Bit32u address, Bit32u value, unsigned io_len)
BX_INFO(("VBE enabling x %d, y %d, bpp %d, %u bytes visible", BX_VGA_THIS vbe.xres, BX_VGA_THIS vbe.yres, BX_VGA_THIS vbe.bpp, BX_VGA_THIS vbe.visible_screen_size));
if ((value & VBE_DISPI_NOCLEARMEM) == 0) {
memset(BX_VGA_THIS s.memory, 0, VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES);
memset(BX_VGA_THIS s.memory, 0, BX_VGA_THIS s.memsize);
}
if (depth > 4) {
bx_gui->dimension_update(BX_VGA_THIS vbe.xres, BX_VGA_THIS vbe.yres, 0, 0, depth);
@ -1210,14 +1210,14 @@ Bit32u bx_vga_c::vbe_write(Bit32u address, Bit32u value, unsigned io_len)
Bit32u new_screen_start = value * BX_VGA_THIS vbe.line_offset;
if (BX_VGA_THIS vbe.bpp != VBE_DISPI_BPP_4) {
if ((new_screen_start + BX_VGA_THIS vbe.visible_screen_size) > VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES)
if ((new_screen_start + BX_VGA_THIS vbe.visible_screen_size) > BX_VGA_THIS s.memsize)
{
BX_PANIC(("VBE offset y %d out of bounds", value));
break;
}
new_screen_start += (BX_VGA_THIS vbe.offset_x * BX_VGA_THIS vbe.bpp_multiplier);
} else {
if ((new_screen_start + BX_VGA_THIS vbe.visible_screen_size) > (VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES / 4))
if ((new_screen_start + BX_VGA_THIS vbe.visible_screen_size) > (BX_VGA_THIS s.memsize >> 2))
{
BX_PANIC(("VBE offset y %d out of bounds", value));
break;
@ -1249,9 +1249,9 @@ Bit32u bx_vga_c::vbe_write(Bit32u address, Bit32u value, unsigned io_len)
Bit16u new_width=value;
Bit16u new_height;
if (BX_VGA_THIS vbe.bpp != VBE_DISPI_BPP_4) {
new_height=(VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES / BX_VGA_THIS vbe.bpp_multiplier) / new_width;
new_height = (BX_VGA_THIS s.memsize / BX_VGA_THIS vbe.bpp_multiplier) / new_width;
} else {
new_height=(VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES * 2) / new_width;
new_height = (BX_VGA_THIS s.memsize << 1) / new_width;
}
if (new_height >=BX_VGA_THIS vbe.yres)
{
@ -1263,9 +1263,9 @@ Bit32u bx_vga_c::vbe_write(Bit32u address, Bit32u value, unsigned io_len)
// no decent virtual height: adjust width & height
new_height=BX_VGA_THIS vbe.yres;
if (BX_VGA_THIS vbe.bpp != VBE_DISPI_BPP_4) {
new_width=(VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES / BX_VGA_THIS vbe.bpp_multiplier) / new_height;
new_width = (BX_VGA_THIS s.memsize / BX_VGA_THIS vbe.bpp_multiplier) / new_height;
} else {
new_width=(VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES * 2) / new_height;
new_width = (BX_VGA_THIS s.memsize << 1) / new_height;
}
BX_INFO(("VBE recalc virtual width %d height %d",new_width, new_height));

View File

@ -26,8 +26,6 @@
// Bochs VBE definitions
#define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 16
#define VBE_DISPI_BANK_ADDRESS 0xA0000
#define VBE_DISPI_MAX_XRES 2560
@ -78,9 +76,6 @@
#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
#define VBE_DISPI_TOTAL_VIDEO_MEMORY_KB (VBE_DISPI_TOTAL_VIDEO_MEMORY_MB * 1024)
#define VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES (VBE_DISPI_TOTAL_VIDEO_MEMORY_KB * 1024)
// End Bochs VBE definitions
#if BX_USE_VGA_SMF

View File

@ -114,6 +114,7 @@
#define BXPN_VGA_REALTIME "display.vga_realtime"
#define BXPN_DDC_MODE "display.ddc_mode"
#define BXPN_DDC_FILE "display.ddc_file"
#define BXPN_VBE_MEMSIZE "display.vbe_memsize"
#define BXPN_VOODOO "display.voodoo"
#define BXPN_KEYBOARD "keyboard_mouse.keyboard"
#define BXPN_KBD_TYPE "keyboard_mouse.keyboard.type"