summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <[email protected]>2026-05-10 16:57:06 +0200
committerJaroslav Hensl <[email protected]>2026-05-10 16:57:06 +0200
commit0755608c75c2c0f70978c46ef757746583d6348d (patch)
tree093f69ef88d6ad2416ab28a1e3591c7b7e9db2c8
parentd921dcce330c3e17e5e05da0b11e50454fedbd08 (diff)
VESA: real HW fixesHEADmain
-rw-r--r--makefile51
-rw-r--r--vxd_async.c10
-rw-r--r--vxd_terror.c286
-rw-r--r--vxd_terror.h33
-rw-r--r--vxd_vesa.c39
5 files changed, 384 insertions, 35 deletions
diff --git a/makefile b/makefile
index aa63119..bcc2cd0 100644
--- a/makefile
+++ b/makefile
@@ -11,11 +11,11 @@ OBJS += &
vxd_vdd_svga.obj vxd_vbe.obj vxd_vbe_qemu.obj vxd_mouse.obj &
vxd_mouse_svga.obj vxd_svga_mouse.obj vxd_svga_mem.obj vxd_svga_cb.obj &
vxd_halloc.obj vxd_main_vesa.obj vxd_vesa.obj vxd_vdd_vesa.obj vxd_mtrr.obj &
- vxd_wram.obj vxd_async.obj vxd_gtf.obj vxd_fbhda_dd.obj
+ vxd_wram.obj vxd_async.obj vxd_gtf.obj vxd_fbhda_dd.obj vxd_terror.obj
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
-VER_BUILD = 120
+VER_BUILD = 124
FLAGS = -DDRV_VER_BUILD=$(VER_BUILD)
@@ -242,6 +242,9 @@ vxd_async.obj : vxd_async.c .autodepend
vxd_gtf.obj : vxd_gtf.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+vxd_terror.obj : vxd_terror.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
# Resources
boxvmini.res : res/boxvmini.rc res/colortab.bin res/config.bin res/fonts.bin res/fonts120.bin .autodepend
wrc -q -r -ad -bt=windows -fo=$@ -Ires -I$(%WATCOM)/h/win $(FLAGS) res/boxvmini.rc
@@ -572,11 +575,12 @@ file vxd_mouse_svga.obj
file vxd_halloc.obj
file vxd_wram.obj
file vxd_async.obj
-segment '_TEXT' PRELOAD NONDISCARDABLE
-segment '_DATA' PRELOAD NONDISCARDABLE
-segment 'CONST' PRELOAD NONDISCARDABLE
-segment 'CONST2' PRELOAD NONDISCARDABLE
-segment '_BSS' PRELOAD NONDISCARDABLE
+file vxd_terror.obj
+segment '_TEXT' PRELOAD NONDISCARDABLE IOPL
+segment '_DATA' PRELOAD NONDISCARDABLE IOPL
+segment 'CONST' PRELOAD NONDISCARDABLE IOPL
+segment 'CONST2' PRELOAD NONDISCARDABLE IOPL
+segment '_BSS' PRELOAD NONDISCARDABLE IOPL
export VXD_DDB.1
<<
$(FIXLINK_EXE) -vxd32 $@
@@ -600,11 +604,12 @@ file vxd_vdd_qemu.obj
file vxd_mouse.obj
file vxd_wram.obj
file vxd_async.obj
-segment '_TEXT' PRELOAD NONDISCARDABLE
-segment '_DATA' PRELOAD NONDISCARDABLE
-segment 'CONST' PRELOAD NONDISCARDABLE
-segment 'CONST2' PRELOAD NONDISCARDABLE
-segment '_BSS' PRELOAD NONDISCARDABLE
+file vxd_terror.obj
+segment '_TEXT' PRELOAD NONDISCARDABLE IOPL
+segment '_DATA' PRELOAD NONDISCARDABLE IOPL
+segment 'CONST' PRELOAD NONDISCARDABLE IOPL
+segment 'CONST2' PRELOAD NONDISCARDABLE IOPL
+segment '_BSS' PRELOAD NONDISCARDABLE IOPL
export VXD_DDB.1
<<
$(FIXLINK_EXE) -vxd32 $@
@@ -625,11 +630,12 @@ file vxd_vdd.obj
file vxd_mouse.obj
file vxd_wram.obj
file vxd_async.obj
-segment '_TEXT' PRELOAD NONDISCARDABLE
-segment '_DATA' PRELOAD NONDISCARDABLE
-segment 'CONST' PRELOAD NONDISCARDABLE
-segment 'CONST2' PRELOAD NONDISCARDABLE
-segment '_BSS' PRELOAD NONDISCARDABLE
+file vxd_terror.obj
+segment '_TEXT' PRELOAD NONDISCARDABLE IOPL
+segment '_DATA' PRELOAD NONDISCARDABLE IOPL
+segment 'CONST' PRELOAD NONDISCARDABLE IOPL
+segment 'CONST2' PRELOAD NONDISCARDABLE IOPL
+segment '_BSS' PRELOAD NONDISCARDABLE IOPL
export VXD_DDB.1
<<
$(FIXLINK_EXE) -vxd32 $@
@@ -652,11 +658,12 @@ file vxd_mouse.obj
file vxd_mtrr.obj
file vxd_wram.obj
file vxd_async.obj
-segment '_TEXT' PRELOAD NONDISCARDABLE
-segment '_DATA' PRELOAD NONDISCARDABLE
-segment 'CONST' PRELOAD NONDISCARDABLE
-segment 'CONST2' PRELOAD NONDISCARDABLE
-segment '_BSS' PRELOAD NONDISCARDABLE
+file vxd_terror.obj
+segment '_TEXT' PRELOAD NONDISCARDABLE IOPL
+segment '_DATA' PRELOAD NONDISCARDABLE IOPL
+segment 'CONST' PRELOAD NONDISCARDABLE IOPL
+segment 'CONST2' PRELOAD NONDISCARDABLE IOPL
+segment '_BSS' PRELOAD NONDISCARDABLE IOPL
export VXD_DDB.1
<<
$(FIXLINK_EXE) -vxd32 $@
diff --git a/vxd_async.c b/vxd_async.c
index 7027ec2..6c42256 100644
--- a/vxd_async.c
+++ b/vxd_async.c
@@ -71,7 +71,7 @@ void __stdcall async_timeout(DWORD tardiness, DWORD refdata)
DWORD act = *curtime;
DWORD delta;
- void *curctx = _GetCurrentContext();
+ //void *curctx = _GetCurrentContext();
//dbg_printf("CTX: %lX, device CTX: %lX\n", curctx, DeviceCTX);
//_ContextSwitch(DeviceCTX);
@@ -90,8 +90,12 @@ void __stdcall async_timeout(DWORD tardiness, DWORD refdata)
burned = *curtime - act;
delta = calc_delta(burned);
- Set_Async_Time_Out(delta, refdata+1, async_timeout_proc);
- _ContextSwitch(curctx);
+ if(!Set_Async_Time_Out(delta, refdata+1, async_timeout_proc))
+ {
+ delta = calc_delta(0);
+ Set_Async_Time_Out(delta, refdata+1, async_timeout_proc);
+ }
+ //_ContextSwitch(curctx);
//dbg_printf("... set (%d)!\n", delta);
}
diff --git a/vxd_terror.c b/vxd_terror.c
new file mode 100644
index 0000000..5d24674
--- /dev/null
+++ b/vxd_terror.c
@@ -0,0 +1,286 @@
+/**************************************************************************
+
+Copyright (c) 2026 Jaroslav Hensl <[email protected]>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*****************************************************************************/
+#include <stdarg.h>
+#include "winhack.h"
+#include "vmm.h"
+#include "vxd.h"
+#include "vxd_lib.h"
+#include "vxd_terror.h"
+
+#define TERROR_MAX 256
+#define TERROR_MAX_NUM 12
+
+static char fmtbuffer[TERROR_MAX];
+static char hex_lower[] = "0123456789abcdef";
+static char hex_upper[] = "0123456789ABCDEF";
+
+static void terrorf_d(char **outp, long d)
+{
+ char buf[TERROR_MAX_NUM];
+ int n = d;
+ char *ptr = buf;
+ char *out = *outp;
+
+ if(d == 0)
+ {
+ *out = '0';
+ out++;
+ *outp = out;
+ return;
+ }
+
+ while(n != 0)
+ {
+ int k = (n % 10);
+ if(k < 0) k = -k;
+ *ptr = k + '0';
+ n /= 10;
+ ptr++;
+ }
+
+ if(d < 0)
+ {
+ *ptr = '-';
+ ptr++;
+ }
+
+ while(ptr != buf)
+ {
+ ptr--;
+ *out = *ptr;
+ out++;
+ }
+ *outp = out;
+}
+
+static void terrorf_u(char **outp, unsigned long d)
+{
+ char buf[TERROR_MAX_NUM];
+ int n = d;
+ char *ptr = buf;
+ char *out = *outp;
+
+ if(d == 0)
+ {
+ *out = '0';
+ out++;
+ *outp = out;
+ return;
+ }
+
+ while(n != 0)
+ {
+ *ptr = (n % 10) + '0';
+ n /= 10;
+ ptr++;
+ }
+
+ while(ptr != buf)
+ {
+ ptr--;
+ *out = *ptr;
+ out++;
+ }
+ *outp = out;
+}
+
+static void terrorf_x(char **outp, unsigned long x, int upper)
+{
+ char buf[TERROR_MAX_NUM];
+ int n = x;
+ char *ptr = buf;
+ char *out = *outp;
+ const char *hex = hex_lower;
+
+ if(x == 0)
+ {
+ *out = '0';
+ out++;
+ *outp = out;
+ return;
+ }
+
+ if(upper)
+ {
+ hex = hex_upper;
+ }
+
+ while(n != 0)
+ {
+ unsigned long k = n % 16;
+ *ptr = hex[k];
+ n /= 16;
+ ptr++;
+ }
+
+ while(ptr != buf)
+ {
+ ptr--;
+ *out = *ptr;
+ out++;
+ }
+ *outp = out;
+}
+
+static void terrorf_s(char **outp, const char *s)
+{
+ char *out = *outp;
+ while(*s != '\0')
+ {
+ *out = *s;
+ s++;
+ out++;
+ }
+ *outp = out;
+}
+
+static volatile void terror_out(char c)
+{
+ _asm mov ax, 0x200
+ _asm mov dl, [c]
+ _asm push dword ptr 0x21
+ VMMCall(Exec_VxD_Int)
+}
+
+static volatile char terror_in()
+{
+ volatile char c = 0;
+
+ _asm mov ax, 0x100
+ _asm push dword ptr 0x21
+ VMMCall(Exec_VxD_Int)
+ _asm mov [c], al
+
+ return c;
+}
+
+/**
+ * Very simple support only:
+ * d, i,
+ * u
+ * x, X
+ * s
+ **/
+void terrorf(const char *fmt, ...)
+{
+ const char *ptr;
+ char *out = fmtbuffer;
+ va_list va;
+ int in_command = 0;
+
+ va_start(va, fmt);
+ for(ptr = fmt;*ptr != '\0'; ptr++)
+ {
+ if(in_command == 0)
+ {
+ switch(*ptr)
+ {
+ case '%':
+ in_command = 1;
+ break;
+ default:
+ *out = *ptr;
+ out++;
+ break;
+ }
+ }
+ else
+ {
+ switch(*ptr)
+ {
+ case '%':
+ *out = '%';
+ in_command = 0;
+ break;
+ case 'i':
+ case 'd':
+ {
+ long d = va_arg(va, long);
+ terrorf_d(&out, d);
+ in_command = 0;
+ break;
+ }
+ case 'u':
+ {
+ unsigned long u = va_arg(va, unsigned long);
+ terrorf_u(&out, u);
+ in_command = 0;
+ break;
+ }
+ case 's':
+ {
+ const char *s = va_arg(va, const char *);
+ terrorf_s(&out, s);
+ in_command = 0;
+ break;
+ }
+ case 'x':
+ case 'X':
+ {
+ unsigned long u = va_arg(va, unsigned long);
+ terrorf_x(&out, u, *ptr == 'X');
+ in_command = 0;
+ break;
+ }
+ default:
+ /* eat all potencial formating... */
+ break;
+ }
+ }
+ }
+ *out = '\0';
+
+ va_end(va);
+ terror(fmtbuffer);
+}
+
+void terror(const char *str)
+{
+ const char *ptr = str;
+ while(*ptr != '\0')
+ {
+ /* auto include return */
+ if(*ptr == '\n')
+ {
+ terror_out('\r');
+ }
+
+ terror_out(*ptr);
+ ptr++;
+ }
+}
+
+void tpause()
+{
+ terror("Press Enter to continue...\n");
+ for(;;)
+ {
+ char c = terror_in();
+ if(c == '\r' || c == '\n')
+ {
+ break;
+ }
+ }
+}
+
diff --git a/vxd_terror.h b/vxd_terror.h
new file mode 100644
index 0000000..ec67be8
--- /dev/null
+++ b/vxd_terror.h
@@ -0,0 +1,33 @@
+/**************************************************************************
+
+Copyright (c) 2026 Jaroslav Hensl <[email protected]>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*****************************************************************************/
+#ifndef __VXD_TERROR_H__INCLUDED__
+#define __VXD_TERROR_H__INCLUDED__
+
+/* function to print messages (usually errors) to text console */
+
+void terrorf(const char *fmt, ...);
+void terror(const char *str);
+void tpause();
+
+#endif /* __VXD_TERROR_H__INCLUDED__ */
diff --git a/vxd_vesa.c b/vxd_vesa.c
index 87490ce..8ae5622 100644
--- a/vxd_vesa.c
+++ b/vxd_vesa.c
@@ -44,6 +44,8 @@ THE SOFTWARE.
#define IO_OUT8
#include "io32.h"
+#include "vxd_terror.h"
+
#include "code32.h"
#define ISA_LFB 0xE0000000UL
@@ -170,7 +172,7 @@ static int vesa_pal_bits = 6;
static BOOL vesa_valid = FALSE;
static DWORD conf_dos_window = 0;
-static DWORD conf_hw_double_buf = 2;
+static DWORD conf_hw_double_buf = 1; /* much better performance on real HW */
static DWORD conf_mtrr = 1;
#define MODE_OFFSET 1024
@@ -307,7 +309,8 @@ BOOL VESA_init_hw()
if(info->VESAVersion < VESA_VBE_2_0)
{
- dbg_printf("We need VBE 2.0 as minimum, abort\n");
+ terror("We need VBE 2.0 as minimum, abort\n");
+ tpause();
return FALSE;
}
@@ -369,6 +372,7 @@ BOOL VESA_init_hw()
dbg_printf("Mode 0x%X = (%ld x %ld x %ld) = phy:%lX\n",
m->mode_id, m->width, m->height, m->bpp, m->phy);
+#if 0
if(info->VESAVersion >= VESA_VBE_3_0)
{
vesa_crtc_info_t crtc_test;
@@ -409,6 +413,7 @@ BOOL VESA_init_hw()
mode_sort_freqs(i);
}
else
+#endif
{
m->freqs[0] = 0;
}
@@ -465,7 +470,7 @@ BOOL VESA_init_hw()
hda->flags |= FB_SUPPORT_FLIPING | FB_VESA_MODES;
if(vesa_version >= VESA_VBE_3_0)
{
- hda->flags |= FB_SUPPORT_CLOCK;
+ //hda->flags |= FB_SUPPORT_CLOCK;
}
vesa_pal = (vesa_palette_entry_t*)(((BYTE*)vesa_buf)+PAL_OFFSET);
@@ -483,6 +488,11 @@ BOOL VESA_init_hw()
return TRUE;
}
+ else
+ {
+ terror("Can't interact with VESA BIOS, this driver can't work\n");
+ tpause();
+ }
}
}
return FALSE;
@@ -499,6 +509,7 @@ BOOL VESA_display_start_pm(BOOL vtrace, DWORD start_addr)
... but in 8+ bits per pixel modes this is the offset from the start of memory divided by 4 */
WORD h1 = (start_addr >> 2) & 0xFFFF;
WORD h2 = start_addr >> 18;
+
if(vbios32 != NULL && vbios32[VESA_PMTABLE_OFF_DISPLAY_START])
{
//dbg_printf("VESA_display_start_pm ...");
@@ -559,22 +570,32 @@ void VESA_load_vbios_pm()
bios_pm = (WORD*)bios_pm_flat;
dbg_printf("set display off func: %X\n", bios_pm[VESA_PMTABLE_OFF_DISPLAY_START]);
-
+
vbios32 = (WORD*)_PageAllocate(code_pages, PG_SYS, 0, 0x0, PAGE_ALLOC_MIN, PAGE_ALLOC_MAX, NULL, PAGEZEROINIT);
if(vbios32 != NULL)
{
+ memset(vbios32, 0xFF, code_pages*P_SIZE);
memcpy(vbios32, bios_pm, code_size);
_PageModifyPermissions(((DWORD)vbios32) / P_SIZE, code_pages, 0, PC_USER | PC_WRITEABLE);
dbg_printf("copy to vbios32 success\n");
}
-
+/*
+ terror("Here is dump of pm32 table:\n");
+ terrorf("vbios32[0] = %X\n", vbios32[0]);
+ terrorf("vbios32[1] = %X\n", vbios32[1]);
+ terrorf("vbios32[2] = %X\n", vbios32[2]);
+ terrorf("vbios32[3] = %X\n", vbios32[3]);
+ terrorf("code size = %d\n", code_size);
+*/
if(vbios32[VESA_PMTABLE_OFF_PORTS])
{
ports = vbios32 + vbios32[VESA_PMTABLE_OFF_PORTS];
+ // ^ some BIOSes has this table after the code to copy
while(*ports != 0xFFFF)
{
dbg_printf("port: %04X\n", *ports);
+ //terrorf("port: = %X\n", *ports);
ports++;
}
ports++;
@@ -583,7 +604,9 @@ void VESA_load_vbios_pm()
DWORD mem_adr = *((DWORD*)ports);
DWORD mem_size = ports[2];
- vbios32_mem = _MapPhysToLinear(mem_adr, mem_adr, 0);
+ //terrorf("mem: = %X, size = %d\n", mem_adr, mem_size);
+
+ vbios32_mem = _MapPhysToLinear(mem_adr, mem_size, 0);
if(vbios32_mem != 0xFFFFFFFF)
{
DWORD hi = 0;
@@ -597,10 +620,6 @@ void VESA_load_vbios_pm()
dbg_printf("VESA PM need memory addr=0x%8X (size=%d)\n", mem_adr, mem_size);
}
- else
- {
- dbg_printf("VESA PM using only I/O ports!\n");
- }
}
#if 0