Skip to content

Commit 3804560

Browse files
committed
Modifications for boxv9x to run on QEMU
1 parent 8d49b0c commit 3804560

File tree

10 files changed

+196
-83
lines changed

10 files changed

+196
-83
lines changed

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.vscode/
2+
res/*.obj
3+
res/*.bin
4+
*.obj
5+
*.err
6+
*.lib
7+
*.drv
8+
*.map
9+
*.res
10+
*.img

boxv.c

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ int BOXV_ext_mode_set( void *cx, int xres, int yres, int bpp, int v_xres, int v_
8181
vid_outw( cx, VBE_DISPI_IOPORT_DATA, 0 );
8282
/* Enable the extended display registers. */
8383
vid_outw( cx, VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE );
84-
vid_outw( cx, VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_8BIT_DAC );
84+
vid_outw( cx, VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_8BIT_DAC | VBE_DISPI_LFB_ENABLED );
8585

8686
/* Re-enable the sequencer. */
8787
vid_wridx( cx, VGA_SEQUENCER, VGA_SR_RESET, VGA_SR0_NORESET );
@@ -126,13 +126,16 @@ int BOXV_detect( void *cx, unsigned long *vram_size )
126126

127127
vid_outw( cx, VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID );
128128
boxv_id = vid_inw( cx, VBE_DISPI_IOPORT_DATA );
129+
130+
if( boxv_id < VBE_DISPI_ID0 || boxv_id > VBE_DISPI_ID6 )
131+
return( 0 );
132+
129133
if( vram_size ) {
130-
*vram_size = vid_ind( cx, VBE_DISPI_IOPORT_DATA );
134+
vid_outw( cx, VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K );
135+
*vram_size = (unsigned long)vid_inw( cx, VBE_DISPI_IOPORT_DATA ) << 16;
131136
}
132-
if( boxv_id >= VBE_DISPI_ID0 && boxv_id <= VBE_DISPI_ID4 )
133-
return( boxv_id );
134-
else
135-
return( 0 );
137+
138+
return( boxv_id );
136139
}
137140

138141
/* Disable extended mode and place the hardware into a VGA compatible state.
@@ -145,25 +148,3 @@ int BOXV_ext_disable( void *cx )
145148
vid_outw( cx, VBE_DISPI_IOPORT_DATA, VBE_DISPI_DISABLED );
146149
return( 0 );
147150
}
148-
149-
/* Return the physical base address of the framebuffer. Needed in environments
150-
* that do not query the base through PCI.
151-
*/
152-
unsigned long BOXV_get_lfb_base( void *cx )
153-
{
154-
unsigned long fb_base;
155-
156-
/* Ask the virtual hardware for the high 16 bits. */
157-
vid_outw( cx, VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_FB_BASE_HI );
158-
fb_base = vid_inw( cx, VBE_DISPI_IOPORT_DATA );
159-
160-
/* Old versions didn't support that, so use the default
161-
* if the value looks like garbage.
162-
*/
163-
if( fb_base != 0 && fb_base != 0xffff )
164-
fb_base = fb_base << 16;
165-
else
166-
fb_base = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
167-
168-
return( fb_base );
169-
}

boxv.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,3 @@ extern int BOXV_ext_mode_set( void *cx, int xres, int yres, int bpp, int v_xres
4646
extern int BOXV_mode_set( void *cx, int mode_no );
4747
extern int BOXV_dac_set( void *cx, unsigned start, unsigned count, void *pal );
4848
extern int BOXV_ext_disable( void *cx );
49-
extern unsigned long BOXV_get_lfb_base( void *cx );

boxv_io.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,3 @@ static unsigned vid_inw( void *cx, unsigned port )
6060
{
6161
return( inpw( port ) );
6262
}
63-
64-
static unsigned long vid_ind( void *cx, unsigned port )
65-
{
66-
return( inpd( port ) );
67-
}

boxvint.h

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -94,34 +94,32 @@ THE SOFTWARE.
9494
#define VBE_DISPI_IOPORT_INDEX 0x01CE
9595
#define VBE_DISPI_IOPORT_DATA 0x01CF
9696

97-
#define VBE_DISPI_INDEX_ID 0x0
98-
#define VBE_DISPI_INDEX_XRES 0x1
99-
#define VBE_DISPI_INDEX_YRES 0x2
100-
#define VBE_DISPI_INDEX_BPP 0x3
101-
#define VBE_DISPI_INDEX_ENABLE 0x4
102-
#define VBE_DISPI_INDEX_BANK 0x5
103-
#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
104-
#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
105-
#define VBE_DISPI_INDEX_X_OFFSET 0x8
106-
#define VBE_DISPI_INDEX_Y_OFFSET 0x9
107-
#define VBE_DISPI_INDEX_VBOX_VIDEO 0xa
108-
#define VBE_DISPI_INDEX_FB_BASE_HI 0xb
109-
110-
#define VBE_DISPI_ID0 0xB0C0
111-
#define VBE_DISPI_ID1 0xB0C1
112-
#define VBE_DISPI_ID2 0xB0C2
113-
#define VBE_DISPI_ID3 0xB0C3
114-
#define VBE_DISPI_ID4 0xB0C4
115-
116-
#define VBE_DISPI_DISABLED 0x00
117-
#define VBE_DISPI_ENABLED 0x01
118-
#define VBE_DISPI_GETCAPS 0x02
119-
#define VBE_DISPI_8BIT_DAC 0x20
120-
#define VBE_DISPI_LFB_ENABLED 0x40
121-
#define VBE_DISPI_NOCLEARMEM 0x80
122-
123-
/* Default LFB base. Might be different! */
124-
#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
97+
#define VBE_DISPI_INDEX_ID 0x0
98+
#define VBE_DISPI_INDEX_XRES 0x1
99+
#define VBE_DISPI_INDEX_YRES 0x2
100+
#define VBE_DISPI_INDEX_BPP 0x3
101+
#define VBE_DISPI_INDEX_ENABLE 0x4
102+
#define VBE_DISPI_INDEX_BANK 0x5
103+
#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
104+
#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
105+
#define VBE_DISPI_INDEX_X_OFFSET 0x8
106+
#define VBE_DISPI_INDEX_Y_OFFSET 0x9
107+
#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa
108+
109+
#define VBE_DISPI_ID0 0xB0C0
110+
#define VBE_DISPI_ID1 0xB0C1
111+
#define VBE_DISPI_ID2 0xB0C2
112+
#define VBE_DISPI_ID3 0xB0C3
113+
#define VBE_DISPI_ID4 0xB0C4
114+
#define VBE_DISPI_ID5 0xB0C5
115+
#define VBE_DISPI_ID6 0xB0C6
116+
117+
#define VBE_DISPI_DISABLED 0x00
118+
#define VBE_DISPI_ENABLED 0x01
119+
#define VBE_DISPI_GETCAPS 0x02
120+
#define VBE_DISPI_8BIT_DAC 0x20
121+
#define VBE_DISPI_LFB_ENABLED 0x40
122+
#define VBE_DISPI_NOCLEARMEM 0x80
125123

126124
/*------------ End bochs Specific -------------*/
127125

dbgprint.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ THE SOFTWARE.
3535

3636

3737
/* Backdoor logging I/O ports. */
38-
#define INFO_PORT 0x504
39-
#define DEBUG_PORT 0x403
38+
#define INFO_PORT 0xe9
4039

4140
#pragma code_seg( _INIT );
4241

ddk/configmg.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
/* Definitions for the configuration manager. */
3+
4+
typedef DWORD CONFIGRET; /* Standardized return value. */
5+
6+
typedef DWORD LOG_CONF; /* Logical configuration. */
7+
typedef LOG_CONF FAR *PLOG_CONF; /* Far pointer to logical configuration. */
8+
9+
typedef DWORD RES_DES; /* Resource descriptor. */
10+
typedef RES_DES FAR *PRES_DES; /* Far pointer to resource descriptor. */
11+
12+
typedef DWORD DEVNODE; /* Devnode. */
13+
14+
typedef DWORD ULONG;
15+
16+
typedef void FAR *PFARVOID;
17+
18+
typedef ULONG RESOURCEID; /* Resource type ID. */
19+
typedef RESOURCEID FAR *PRESOURCEID; /* Far pointer to resource type ID. */
20+
21+
typedef struct {
22+
WORD MD_Count;
23+
WORD MD_Type;
24+
ULONG MD_Alloc_Base;
25+
ULONG MD_Alloc_End;
26+
WORD MD_Flags;
27+
WORD MD_Reserved;
28+
} MEM_DES, *PMEM_DES;
29+
30+
#define CR_SUCCESS 0
31+
#define ALLOC_LOG_CONF 2
32+
#define ResType_Mem 1

init.c

Lines changed: 114 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ THE SOFTWARE.
2929
#include <dibeng.h>
3030
#include <minivdd.h>
3131
#include "minidrv.h"
32-
32+
#include <configmg.h>
3333

3434
/* GlobalSmartPageLock is a semi-undocumented function. Not officially
3535
* documented but described in KB Article Q180586. */
@@ -41,8 +41,10 @@ WORD wDpi = 96; /* Current DPI setting. */
4141
WORD wBpp = 8; /* Current BPP setting. */
4242
WORD wPalettized = 0; /* Non-zero if palettized. */
4343

44-
WORD OurVMHandle = 0; /* The current VM's ID. */
45-
DWORD VDDEntryPoint = 0; /* The VDD entry point. */
44+
WORD OurVMHandle = 0; /* The current VM's ID. */
45+
DWORD VDDEntryPoint = 0; /* The VDD entry point. */
46+
DWORD ConfigMGEntryPoint = 0; /* The configuration manager entry point. */
47+
DWORD LfbBase = 0; /* The physical base address of the linear framebuffer. */
4648

4749
/* On Entry:
4850
* EAX = Function code (VDD_GET_DISPLAY_CONFIG)
@@ -65,18 +67,72 @@ extern DWORD CallVDDGetDispConf( WORD Function, WORD wDInfSize, LPVOID pDInf );
6567
"call dword ptr VDDEntryPoint"\
6668
"mov edx, eax" \
6769
"shr edx, 16" \
68-
parm [ax] [cx] [es di];
70+
parm [ax] [cx] [es di] modify [bx];
6971

7072

7173
#pragma code_seg( _INIT )
7274

75+
/* Get the first logical configuration for a devnode.
76+
*/
77+
CONFIGRET static _near _cdecl CM_Get_First_Log_Conf(
78+
PLOG_CONF plcLogConf,
79+
DEVNODE dnDevNode,
80+
ULONG ulFlags)
81+
{
82+
WORD wRc = 0;
83+
84+
_asm { mov eax, 01Ah }; /* CM_GET_FIRST_LOG_CONF */
85+
_asm { call ConfigMGEntryPoint };
86+
_asm { mov wRc, ax };
87+
88+
return( wRc );
89+
}
90+
91+
/* Get the next resource descriptor of a given type.
92+
*/
93+
CONFIGRET static _near _cdecl CM_Get_Next_Res_Des(
94+
PRES_DES prdResDes,
95+
RES_DES CurrentResDesOrLogConf,
96+
RESOURCEID ForResource,
97+
PRESOURCEID pResourceID,
98+
ULONG ulFlags)
99+
{
100+
WORD wRc = 0;
101+
102+
_asm { mov eax, 01Fh }; /* CM_GET_NEXT_RES_DES */
103+
_asm { call ConfigMGEntryPoint };
104+
_asm { mov wRc, ax };
105+
106+
return( wRc );
107+
}
108+
109+
/* Get the data for a resource descriptor.
110+
*/
111+
CONFIGRET static _near _cdecl CM_Get_Res_Des_Data(
112+
RES_DES rdResDes,
113+
PFARVOID Buffer,
114+
ULONG BufferLen,
115+
ULONG ulFlags)
116+
{
117+
WORD wRc = 0;
118+
119+
_asm { mov eax, 022h }; /* CM_GET_RES_DES_DATA */
120+
_asm { call ConfigMGEntryPoint };
121+
_asm { mov wRc, ax };
122+
123+
return( wRc );
124+
}
125+
73126
/* Read the display settings from SYSTEM.INI or Registry.
74127
*/
75-
void ReadDisplayConfig( void )
128+
DEVNODE ReadDisplayConfig( void )
76129
{
77130
WORD wX, wY;
78131
UINT bIgnoreRegistry;
79132
MODEDESC mode;
133+
DEVNODE devNode;
134+
DISPLAYINFO DispInfo;
135+
DWORD dwRc;
80136

81137
/* Get the DPI, default to 96. */
82138
wDpi = GetPrivateProfileInt( "display", "dpi", 96, "system.ini" );
@@ -92,13 +148,13 @@ void ReadDisplayConfig( void )
92148

93149
bIgnoreRegistry = GetPrivateProfileInt( "display", "IgnoreRegistry", 0, "system.ini" );
94150

95-
if( !bIgnoreRegistry ) {
96-
DISPLAYINFO DispInfo;
97-
DWORD dwRc;
151+
dwRc = CallVDDGetDispConf( VDD_GET_DISPLAY_CONFIG, sizeof( DispInfo ), &DispInfo );
152+
if( (dwRc != VDD_GET_DISPLAY_CONFIG) && !dwRc ) {
153+
devNode = (DEVNODE)DispInfo.diDevNodeHandle;
98154

99-
dwRc = CallVDDGetDispConf( VDD_GET_DISPLAY_CONFIG, sizeof( DispInfo ), &DispInfo );
100-
if( (dwRc != VDD_GET_DISPLAY_CONFIG) && !dwRc ) {
101-
/* Call succeeded, use the data. */
155+
/* Call succeeded, use the data. */
156+
if (!bIgnoreRegistry)
157+
{
102158
wScrX = DispInfo.diXRes;
103159
wScrY = DispInfo.diYRes;
104160
wBpp = DispInfo.diBpp;
@@ -108,9 +164,10 @@ void ReadDisplayConfig( void )
108164
/* DPI might not be set, careful. */
109165
if( DispInfo.diDPI )
110166
wDpi = DispInfo.diDPI;
111-
} else {
112-
dbg_printf( "VDD_GET_DISPLAY_CONFIG failed, dwRc=%lX\n",dwRc );
113167
}
168+
} else {
169+
dbg_printf( "VDD_GET_DISPLAY_CONFIG failed, dwRc=%lX\n",dwRc );
170+
devNode = 0;
114171
}
115172

116173
mode.xRes = wScrX;
@@ -129,9 +186,12 @@ void ReadDisplayConfig( void )
129186
wPalettized = GetPrivateProfileInt( "display", "palettized", 1, "system.ini" );
130187
else
131188
wPalettized = 0;
189+
190+
return( devNode );
132191
}
133192

134-
#define VDD_ID 10 /* Virtual Display Driver ID. */
193+
#define VDD_ID 10 /* Virtual Display Driver ID. */
194+
#define CONFIGMG_ID 51 /* Configuration Manager Driver ID. */
135195

136196
/* Get Device API Entry Point. */
137197
void __far *int_2F_GetEP( unsigned ax, unsigned bx );
@@ -154,6 +214,8 @@ extern char __based( __segname( "_TEXT" ) ) *pText;
154214
#pragma aux DriverInit parm [cx] [di] [es si]
155215
UINT FAR DriverInit( UINT cbHeap, UINT hModule, LPSTR lpCmdLine )
156216
{
217+
DEVNODE devNode;
218+
157219
/* Lock the code segment. */
158220
GlobalSmartPageLock( (__segment)pText );
159221

@@ -166,7 +228,43 @@ UINT FAR DriverInit( UINT cbHeap, UINT hModule, LPSTR lpCmdLine )
166228
dbg_printf( "DriverInit: VDDEntryPoint=%WP, OurVMHandle=%x\n", VDDEntryPoint, OurVMHandle );
167229

168230
/* Read the display configuration before doing anything else. */
169-
ReadDisplayConfig();
231+
LfbBase = 0;
232+
devNode = ReadDisplayConfig();
233+
234+
/* Use the Configuration Manager to locate the base address of the linear framebuffer. */
235+
if( devNode ) {
236+
RES_DES rd;
237+
238+
ConfigMGEntryPoint = (DWORD)int_2F_GetEP( 0x1684, CONFIGMG_ID );
239+
240+
if( CM_Get_First_Log_Conf( &rd, devNode, ALLOC_LOG_CONF ) == CR_SUCCESS ) {
241+
ULONG cbAllocMax = 0;
242+
243+
/* Take the largest physical memory range in use by this device
244+
* and store it into LfbBase. */
245+
while( CM_Get_Next_Res_Des( &rd, rd, ResType_Mem, NULL, 0 ) == CR_SUCCESS ) {
246+
247+
/* Experimentally, no MEM_RES was found to be larger than 0x28 bytes
248+
* with the QEMU VGA adapter, so this buffer is static, but it would
249+
* be better to query the size (with CM_Get_Res_Des_Data_Size) and
250+
* then use alloca here. */
251+
char memRes[0x28];
252+
253+
if( CM_Get_Res_Des_Data( rd, memRes, sizeof(memRes), 0 ) == CR_SUCCESS ) {
254+
PMEM_DES pMemDes = (PMEM_DES)memRes;
255+
ULONG cbAlloc = pMemDes->MD_Alloc_End - pMemDes->MD_Alloc_Base + 1;
256+
257+
if( cbAlloc > cbAllocMax ) {
258+
cbAllocMax = cbAlloc;
259+
LfbBase = pMemDes->MD_Alloc_Base;
260+
}
261+
}
262+
}
263+
}
264+
}
265+
266+
dbg_printf("DriverInit: LfbBase is %lX\n", LfbBase);
170267

171-
return( 1 ); /* Success. */
268+
/* Return 1 (success) iff we located the physical address of the linear framebuffer. */
269+
return ( !!LfbBase );
172270
}

0 commit comments

Comments
 (0)