[RESENT 3/4] winedos: implement true CDROM DOS device driver
Petr Tesarik
hat at tesarici.cz
Tue Apr 11 03:36:08 CDT 2006
Hi,
while I was trying to make Kindler Literaturlexikon work in Wine, I
found out that this program uses a DOS program to access the CDROM,
and that it requires a real working MSCDEX device driver (and not only
that, the driver has to reside in a different segment than the DOS
core).
To make the patches as small as possible, I've split the patch into
several parts.
This part moves device driver setup to a new function which can be
used from other files. This is meant to reduce code duplication in
int2f.c.
ChangeLog:
* dlls/winedos/devices.c:
winedos: move all device driver initialization code to a newly written
function DOSDEV_SetupDevice()
* dlls/winedos/dosexe.h:
winedos: add the prototype for DOSDEV_SetupDevice()
-------------- next part --------------
Index: devices.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/devices.c,v
retrieving revision 1.14
diff -u -r1.14 devices.c
--- devices.c 21 Jun 2005 20:53:14 -0000 1.14
+++ devices.c 10 Apr 2006 13:52:12 -0000
@@ -186,6 +101,7 @@
{
DOS_LISTOFLISTS lol;
DOS_DEVICE_HEADER dev[NR_DEVS-1];
+ DOS_DEVICE_HEADER *last_dev; /* ptr to last registered device driver */
WINEDEV_THUNK thunk[NR_DEVS];
REQ_IO req;
BYTE buffer[CON_BUFFER];
@@ -500,6 +416,29 @@
DOS_LOL->size_extended_mem = 0xf000; /* very high value */
}
+void DOSDEV_SetupDevice(const WINEDEV * devinfo,
+ WORD seg, WORD off_dev, WORD off_thunk)
+{
+ DOS_DEVICE_HEADER *dev = PTR_REAL_TO_LIN(seg, off_dev);
+ WINEDEV_THUNK *thunk = PTR_REAL_TO_LIN(seg, off_thunk);
+ DOS_DATASEG *dataseg = (DOS_DATASEG*)DOSMEM_LOL();
+
+ dev->attr = devinfo->attr;
+ dev->strategy = off_thunk + FIELD_OFFSET(WINEDEV_THUNK, ljmp1);
+ dev->interrupt = off_thunk + FIELD_OFFSET(WINEDEV_THUNK, ljmp2);
+ memcpy(dev->name, devinfo->name, 8);
+
+ thunk->ljmp1 = LJMP;
+ thunk->strategy = DPMI_AllocInternalRMCB(devinfo->strategy);
+ thunk->ljmp2 = LJMP;
+ thunk->interrupt = DPMI_AllocInternalRMCB(devinfo->interrupt);
+
+ dev->next_dev = NONEXT;
+ if (dataseg->last_dev)
+ dataseg->last_dev->next_dev = MAKESEGPTR(seg, off_dev);
+ dataseg->last_dev = dev;
+}
+
void DOSDEV_InstallDOSDevices(void)
{
DOS_DATASEG *dataseg;
@@ -520,31 +459,18 @@
InitListOfLists(&dataseg->lol);
/* Set up first device (NUL) */
- dataseg->lol.NUL_dev.next_dev = MAKESEGPTR(seg, DOS_DATASEG_OFF(dev[0]));
- dataseg->lol.NUL_dev.attr = devs[0].attr;
- dataseg->lol.NUL_dev.strategy = DOS_DATASEG_OFF(thunk[0].ljmp1);
- dataseg->lol.NUL_dev.interrupt = DOS_DATASEG_OFF(thunk[0].ljmp2);
- memcpy(dataseg->lol.NUL_dev.name, devs[0].name, 8);
+ dataseg->last_dev = NULL;
+ DOSDEV_SetupDevice( &devs[0],
+ seg,
+ DOS_DATASEG_OFF(lol.NUL_dev),
+ DOS_DATASEG_OFF(thunk[0]) );
/* Set up the remaining devices */
for (n = 1; n < NR_DEVS; n++)
- {
- dataseg->dev[n-1].next_dev = (n+1) == NR_DEVS ? NONEXT :
- MAKESEGPTR(seg, DOS_DATASEG_OFF(dev[n]));
- dataseg->dev[n-1].attr = devs[n].attr;
- dataseg->dev[n-1].strategy = DOS_DATASEG_OFF(thunk[n].ljmp1);
- dataseg->dev[n-1].interrupt = DOS_DATASEG_OFF(thunk[n].ljmp2);
- memcpy(dataseg->dev[n-1].name, devs[n].name, 8);
- }
-
- /* Set up thunks */
- for (n = 0; n < NR_DEVS; n++)
- {
- dataseg->thunk[n].ljmp1 = LJMP;
- dataseg->thunk[n].strategy = (RMCBPROC)DPMI_AllocInternalRMCB(devs[n].strategy);
- dataseg->thunk[n].ljmp2 = LJMP;
- dataseg->thunk[n].interrupt = (RMCBPROC)DPMI_AllocInternalRMCB(devs[n].interrupt);
- }
+ DOSDEV_SetupDevice( &devs[n],
+ seg,
+ DOS_DATASEG_OFF(dev[n-1]),
+ DOS_DATASEG_OFF(thunk[n]) );
/* CON is device 1 */
dataseg->lol.ptr_CON_dev_hdr = MAKESEGPTR(seg, DOS_DATASEG_OFF(dev[0]));
Index: dosexe.h
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosexe.h,v
retrieving revision 1.38
diff -u -r1.38 dosexe.h
--- dosexe.h 27 Mar 2006 11:30:41 -0000 1.38
+++ dosexe.h 10 Apr 2006 13:52:12 -0000
@@ -267,6 +366,8 @@
/* devices.c */
extern void DOSDEV_InstallDOSDevices(void);
+extern void DOSDEV_SetupDevice(const WINEDEV * devinfo,
+ WORD seg, WORD off_dev, WORD off_thunk);
extern DWORD DOSDEV_Console(void);
extern DWORD DOSDEV_FindCharDevice(char*name);
extern int DOSDEV_Peek(DWORD dev, BYTE*data);
More information about the wine-patches
mailing list