/*
 * DOS devices
 *
 * Copyright 1999 Ove Kåven
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdlib.h>
#include <string.h>
#include "wine/winbase16.h"
#include "dosexe.h"
#include "wine/debug.h"

#include "pshpack1.h"

/* Warning: need to return LOL ptr w/ offset 0 (&ptr_first_DPB) to programs ! */
typedef struct _DOS_LISTOFLISTS
{
    WORD  CX_Int21_5e01;        /* -24d contents of CX from INT 21/AX=5E01h */
    WORD  LRU_count_FCB_cache;  /* -22d */
    WORD  LRU_count_FCB_open;   /* -20d */
    DWORD OEM_func_handler;     /* -18d OEM function of INT 21/AH=F8h */
    WORD  INT21_offset;         /* -14d offset in DOS CS of code to return from INT 21 call */
    WORD  sharing_retry_count;  /* -12d */
    WORD  sharing_retry_delay;  /* -10d */
    DWORD ptr_disk_buf;         /* -8d ptr to current disk buf */
    WORD  offs_unread_CON;      /* -4d pointer in DOS data segment of unread CON input */
    WORD  seg_first_MCB;        /* -2d */
    DWORD ptr_first_DPB;        /* 00 */
    DWORD ptr_first_SysFileTable; /* 04 */
    DWORD ptr_clock_dev_hdr;    /* 08 */
    DWORD ptr_CON_dev_hdr;      /* 0C */
    WORD  max_byte_per_sec;     /* 10 maximum bytes per sector of any block device */
    DWORD ptr_disk_buf_info;    /* 12 */
    DWORD ptr_array_CDS;        /* 16 current directory structure */
    DWORD ptr_sys_FCB;          /* 1A */
    WORD  nr_protect_FCB;       /* 1E */
    BYTE  nr_block_dev;         /* 20 */
    BYTE  nr_avail_drive_letters; /* 21 */
    DOS_DEVICE_HEADER NUL_dev;  /* 22 */
    BYTE  nr_drives_JOINed;     /* 34 */
    WORD  ptr_spec_prg_names;   /* 35 */
    DWORD ptr_SETVER_prg_list;  /* 37 */
    WORD DOS_HIGH_A20_func_offs;/* 3B */
    WORD PSP_last_exec;         /* 3D if DOS in HMA: PSP of program executed last; if DOS low: 0000h */
    WORD BUFFERS_val;           /* 3F */
    WORD BUFFERS_nr_lookahead;  /* 41 */
    BYTE boot_drive;            /* 43 */
    BYTE flag_DWORD_moves;      /* 44 01h for 386+, 00h otherwise */
    WORD size_extended_mem;     /* 45 size of extended mem in KB */
    SEGPTR wine_rm_lol;         /* -- wine: Real mode pointer to LOL */
    SEGPTR wine_pm_lol;         /* -- wine: Protected mode pointer to LOL */
} DOS_LISTOFLISTS;

#include "poppack.h"

#define CON_BUFFER 128

enum strategy { SYSTEM_STRATEGY_NUL, SYSTEM_STRATEGY_CON, NB_SYSTEM_STRATEGIES };

static void *strategy_data[NB_SYSTEM_STRATEGIES];

#define LJMP 0xea


/* prototypes */
static void WINAPI nul_strategy(CONTEXT86*ctx);
static void WINAPI nul_interrupt(CONTEXT86*ctx);
static void WINAPI con_strategy(CONTEXT86*ctx);
static void WINAPI con_interrupt(CONTEXT86*ctx);

/* devices */
static const WINEDEV devs[] =
{
  { "NUL     ",
    ATTR_CHAR|ATTR_NUL|ATTR_DEVICE,
    nul_strategy, nul_interrupt },

  { "CON     ",
    ATTR_CHAR|ATTR_STDIN|ATTR_STDOUT|ATTR_FASTCON|ATTR_NOTEOF|ATTR_DEVICE,
    con_strategy, con_interrupt }
};

#define NR_DEVS (sizeof(devs)/sizeof(WINEDEV))

/* DOS data segment */
typedef struct
{
    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];

} DOS_DATASEG;

#define DOS_DATASEG_OFF(xxx) FIELD_OFFSET(DOS_DATASEG, xxx)

static DWORD DOS_LOLSeg;

static struct _DOS_LISTOFLISTS * DOSMEM_LOL(void)
{
    return PTR_REAL_TO_LIN(HIWORD(DOS_LOLSeg),0);
}


/* the device implementations */
static void do_lret(CONTEXT86*ctx)
{
  WORD *stack = CTX_SEG_OFF_TO_LIN(ctx, ctx->SegSs, ctx->Esp);

  ctx->Eip   = *(stack++);
  ctx->SegCs = *(stack++);
  ctx->Esp  += 2*sizeof(WORD);
}

static void do_strategy(CONTEXT86*ctx, int id, int extra)
{
  REQUEST_HEADER *hdr = CTX_SEG_OFF_TO_LIN(ctx, ctx->SegEs, ctx->Ebx);
  void **hdr_ptr = strategy_data[id];

  if (!hdr_ptr) {
    hdr_ptr = calloc(1,sizeof(void *)+extra);
    strategy_data[id] = hdr_ptr;
  }
  *hdr_ptr = hdr;
  do_lret(ctx);
}

static REQUEST_HEADER * get_hdr(int id, void**extra)
{
  void **hdr_ptr = strategy_data[id];
  if (extra)
    *extra = hdr_ptr ? (void*)(hdr_ptr+1) : NULL;
  return hdr_ptr ? *hdr_ptr : NULL;
}

static void WINAPI nul_strategy(CONTEXT86*ctx)
{
  do_strategy(ctx, SYSTEM_STRATEGY_NUL, 0);
}

static void WINAPI nul_interrupt(CONTEXT86*ctx)
{
  REQUEST_HEADER *hdr = get_hdr(SYSTEM_STRATEGY_NUL, NULL);
  /* eat everything and recycle nothing */
  switch (hdr->command) {
  case CMD_INPUT:
    ((REQ_IO*)hdr)->count = 0;
    hdr->status = STAT_DONE;
    break;
  case CMD_SAFEINPUT:
    hdr->status = STAT_DONE|STAT_BUSY;
    break;
  default:
    hdr->status = STAT_DONE;
  }
  do_lret(ctx);
}

static void WINAPI con_strategy(CONTEXT86*ctx)
{
  do_strategy(ctx, SYSTEM_STRATEGY_CON, sizeof(int));
}

static void WINAPI con_interrupt(CONTEXT86*ctx)
{
  int *scan;
  REQUEST_HEADER *hdr = get_hdr(SYSTEM_STRATEGY_CON,(void **)&scan);
  BIOSDATA *bios = DOSVM_BiosData();
  WORD CurOfs = bios->NextKbdCharPtr;
  DOS_LISTOFLISTS *lol = DOSMEM_LOL();
  DOS_DATASEG *dataseg = (DOS_DATASEG *)lol;
  BYTE *linebuffer = dataseg->buffer;
  BYTE *curbuffer = (lol->offs_unread_CON) ?
    (((BYTE*)dataseg) + lol->offs_unread_CON) : (BYTE*)NULL;
  DOS_DEVICE_HEADER *con = dataseg->dev;
  DWORD w;

  switch (hdr->command) {
  case CMD_INPUT:
    {
      REQ_IO *io = (REQ_IO *)hdr;
      WORD count = io->count, len = 0;
      BYTE *buffer = CTX_SEG_OFF_TO_LIN(ctx,
					SELECTOROF(io->buffer),
					(DWORD)OFFSETOF(io->buffer));

      hdr->status = STAT_BUSY;
      /* first, check whether we already have data in line buffer */
      if (curbuffer) {
	/* yep, copy as much as we can */
	BYTE data = 0;
	while ((len<count) && (data != '\r')) {
	  data = *curbuffer++;
	  buffer[len++] = data;
	}
	if (data == '\r') {
	  /* line buffer emptied */
	  lol->offs_unread_CON = 0;
	  curbuffer = NULL;
	  /* if we're not in raw mode, call it a day */
	  if (!(con->attr & ATTR_RAW)) {
	    hdr->status = STAT_DONE;
	    io->count = len;
	    break;
	  }
	} else {
	  /* still some data left */
	  lol->offs_unread_CON = curbuffer - (BYTE*)lol;
	  /* but buffer was filled, we're done */
	  hdr->status = STAT_DONE;
	  io->count = len;
	  break;
	}
      }

      /* if we're in raw mode, we just need to fill the buffer */
      if (con->attr & ATTR_RAW) {
	while (len<count) {
	  WORD data;

	  /* do we have a waiting scancode? */
	  if (*scan) {
	    /* yes, store scancode in buffer */
	    buffer[len++] = *scan;
	    *scan = 0;
	    if (len==count) break;
	  }

	  /* check for new keyboard input */
	  while (CurOfs == bios->FirstKbdCharPtr) {
	    /* no input available yet, so wait... */
	    DOSVM_Wait( ctx );
	  }
	  /* read from keyboard queue (call int16?) */
	  data = ((WORD*)bios)[CurOfs];
	  CurOfs += 2;
	  if (CurOfs >= bios->KbdBufferEnd) CurOfs = bios->KbdBufferStart;
	  bios->NextKbdCharPtr = CurOfs;
	  /* if it's an extended key, save scancode */
	  if (LOBYTE(data) == 0) *scan = HIBYTE(data);
	  /* store ASCII char in buffer */
	  buffer[len++] = LOBYTE(data);
	}
      } else {
	/* we're not in raw mode, so we need to do line input... */
	while (TRUE) {
	  WORD data;
	  /* check for new keyboard input */
	  while (CurOfs == bios->FirstKbdCharPtr) {
	    /* no input available yet, so wait... */
	    DOSVM_Wait( ctx );
	  }
	  /* read from keyboard queue (call int16?) */
	  data = ((WORD*)bios)[CurOfs];
	  CurOfs += 2;
	  if (CurOfs >= bios->KbdBufferEnd) CurOfs = bios->KbdBufferStart;
	  bios->NextKbdCharPtr = CurOfs;

	  if (LOBYTE(data) == '\r') {
	    /* it's the return key, we're done */
	    linebuffer[len++] = LOBYTE(data);
	    break;
	  }
	  else if (LOBYTE(data) >= ' ') {
	    /* a character */
	    if ((len+1)<CON_BUFFER) {
	      linebuffer[len] = LOBYTE(data);
	      WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), &linebuffer[len++], 1, &w, NULL);
	    }
	    /* else beep, but I don't like noise */
	  }
	  else switch (LOBYTE(data)) {
	  case '\b':
	    if (len>0) {
	      len--;
	      WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\b \b", 3, &w, NULL);
	    }
	    break;
	  }
	}
	if (len > count) {
	  /* save rest of line for later */
	  lol->offs_unread_CON = linebuffer - (BYTE*)lol + count;
	  len = count;
	}
	memcpy(buffer, linebuffer, len);
      }
      hdr->status = STAT_DONE;
      io->count = len;
    }
    break;
  case CMD_SAFEINPUT:
    if (curbuffer) {
      /* some line input waiting */
      hdr->status = STAT_DONE;
      ((REQ_SAFEINPUT*)hdr)->data = *curbuffer;
    }
    else if (con->attr & ATTR_RAW) {
      if (CurOfs == bios->FirstKbdCharPtr) {
	/* no input */
	hdr->status = STAT_DONE|STAT_BUSY;
      } else {
	/* some keyboard input waiting */
	hdr->status = STAT_DONE;
	((REQ_SAFEINPUT*)hdr)->data = ((BYTE*)bios)[CurOfs];
      }
    } else {
      /* no line input */
      hdr->status = STAT_DONE|STAT_BUSY;
    }
    break;
  case CMD_INSTATUS:
    if (curbuffer) {
      /* we have data */
      hdr->status = STAT_DONE;
    }
    else if (con->attr & ATTR_RAW) {
      if (CurOfs == bios->FirstKbdCharPtr) {
	/* no input */
	hdr->status = STAT_DONE|STAT_BUSY;
      } else {
	/* some keyboard input waiting */
	hdr->status = STAT_DONE;
      }
    } else {
      /* no line input */
      hdr->status = STAT_DONE|STAT_BUSY;
    }

    break;
  case CMD_INFLUSH:
    /* flush line and keyboard queue */
    lol->offs_unread_CON = 0;
    bios->NextKbdCharPtr = bios->FirstKbdCharPtr;
    break;
  case CMD_OUTPUT:
  case CMD_SAFEOUTPUT:
    {
      REQ_IO *io = (REQ_IO *)hdr;
      BYTE *buffer = CTX_SEG_OFF_TO_LIN(ctx,
					SELECTOROF(io->buffer),
					(DWORD)OFFSETOF(io->buffer));
      DWORD result = 0;
      WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, io->count, &result, NULL);
      io->count = result;
      hdr->status = STAT_DONE;
    }
    break;
  default:
    hdr->status = STAT_DONE;
  }
  do_lret(ctx);
}

static void InitListOfLists(DOS_LISTOFLISTS *DOS_LOL)
{
/*
Output of DOS 6.22:

0133:0020                    6A 13-33 01 CC 00 33 01 59 00         j.3...3.Y.
0133:0030  70 00 00 00 72 02 00 02-6D 00 33 01 00 00 2E 05   p...r...m.3.....
0133:0040  00 00 FC 04 00 00 03 08-92 21 11 E0 04 80 C6 0D   .........!......
0133:0050  CC 0D 4E 55 4C 20 20 20-20 20 00 00 00 00 00 00   ..NUL     ......
0133:0060  00 4B BA C1 06 14 00 00-00 03 01 00 04 70 CE FF   .K...........p..
0133:0070  FF 00 00 00 00 00 00 00-00 01 00 00 0D 05 00 00   ................
0133:0080  00 FF FF 00 00 00 00 FE-00 00 F8 03 FF 9F 70 02   ..............p.
0133:0090  D0 44 C8 FD D4 44 C8 FD-D4 44 C8 FD D0 44 C8 FD   .D...D...D...D..
0133:00A0  D0 44 C8 FD D0 44                                 .D...D
*/
  DOS_LOL->CX_Int21_5e01		= 0x0;
  DOS_LOL->LRU_count_FCB_cache	= 0x0;
  DOS_LOL->LRU_count_FCB_open		= 0x0;
  DOS_LOL->OEM_func_handler		= -1; /* not available */
  DOS_LOL->INT21_offset		= 0x0;
  DOS_LOL->sharing_retry_count	= 3;
  DOS_LOL->sharing_retry_delay	= 1;
  DOS_LOL->ptr_disk_buf		= 0x0;
  DOS_LOL->offs_unread_CON		= 0x0;
  DOS_LOL->seg_first_MCB		= 0x0;
  DOS_LOL->ptr_first_DPB		= 0x0;
  DOS_LOL->ptr_first_SysFileTable	= 0x0;
  DOS_LOL->ptr_clock_dev_hdr		= 0x0;
  DOS_LOL->ptr_CON_dev_hdr		= 0x0;
  DOS_LOL->max_byte_per_sec		= 512;
  DOS_LOL->ptr_disk_buf_info		= 0x0;
  DOS_LOL->ptr_array_CDS		= 0x0;
  DOS_LOL->ptr_sys_FCB		= 0x0;
  DOS_LOL->nr_protect_FCB		= 0x0;
  DOS_LOL->nr_block_dev		= 0x0;
  DOS_LOL->nr_avail_drive_letters	= 26; /* A - Z */
  DOS_LOL->nr_drives_JOINed		= 0x0;
  DOS_LOL->ptr_spec_prg_names		= 0x0;
  DOS_LOL->ptr_SETVER_prg_list	= 0x0; /* no SETVER list */
  DOS_LOL->DOS_HIGH_A20_func_offs	= 0x0;
  DOS_LOL->PSP_last_exec		= 0x0;
  DOS_LOL->BUFFERS_val		= 99; /* maximum: 99 */
  DOS_LOL->BUFFERS_nr_lookahead	= 8; /* maximum: 8 */
  DOS_LOL->boot_drive			= 3; /* C: */
  DOS_LOL->flag_DWORD_moves		= 0x01; /* i386+ */
  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;
  WORD seg;
  WORD selector;
  unsigned int n;

  /* allocate DOS data segment or something */
  dataseg = DOSVM_AllocDataUMB( sizeof(DOS_DATASEG), &seg, &selector );

  DOS_LOLSeg = MAKESEGPTR( seg, 0 );
  DOSMEM_LOL()->wine_rm_lol = 
      MAKESEGPTR( seg, FIELD_OFFSET(DOS_LISTOFLISTS, ptr_first_DPB) );
  DOSMEM_LOL()->wine_pm_lol = 
      MAKESEGPTR( selector, FIELD_OFFSET(DOS_LISTOFLISTS, ptr_first_DPB) );

  /* initialize the magnificent List Of Lists */
  InitListOfLists(&dataseg->lol);

  /* Set up first device (NUL) */
  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++)
    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]));
}

DWORD DOSDEV_Console(void)
{
  return DOSMEM_LOL()->ptr_CON_dev_hdr;
}

DWORD DOSDEV_FindCharDevice(char*name)
{
  SEGPTR cur_ptr = MAKESEGPTR(HIWORD(DOS_LOLSeg), FIELD_OFFSET(DOS_LISTOFLISTS,NUL_dev));
  DOS_DEVICE_HEADER *cur = PTR_REAL_TO_LIN(SELECTOROF(cur_ptr),OFFSETOF(cur_ptr));
  char dname[8];
  int cnt;

  /* get first 8 characters */
  /* if less than 8 characters, pad with spaces */
  for (cnt=0; name[cnt] && cnt<8; cnt++)
    dname[cnt]=name[cnt];

  while(cnt<8) dname[cnt++] = ' ';

  /* search for char devices with the right name */
  while (cur &&
	 ((!(cur->attr & ATTR_CHAR)) ||
	  memcmp(cur->name,dname,8))) {
    cur_ptr = cur->next_dev;
    if (cur_ptr == NONEXT) cur=NULL;
    else cur = PTR_REAL_TO_LIN(SELECTOROF(cur_ptr),OFFSETOF(cur_ptr));
  }
  return cur_ptr;
}

static void DOSDEV_DoReq(void*req, DWORD dev)
{
  REQUEST_HEADER *hdr = (REQUEST_HEADER *)req;
  DOS_DEVICE_HEADER *dhdr;
  CONTEXT86 ctx;
  char *phdr;

  dhdr = PTR_REAL_TO_LIN(SELECTOROF(dev),OFFSETOF(dev));
  phdr = ((char*)DOSMEM_LOL()) + DOS_DATASEG_OFF(req);

  /* copy request to request scratch area */
  memcpy(phdr, req, hdr->size);

  /* prepare to call device driver */
  memset(&ctx, 0, sizeof(ctx));
  ctx.EFlags |= V86_FLAG;

  /* ES:BX points to request for strategy routine */
  ctx.SegEs = HIWORD(DOS_LOLSeg);
  ctx.Ebx   = DOS_DATASEG_OFF(req);

  /* call strategy routine */
  ctx.SegCs = SELECTOROF(dev);
  ctx.Eip   = dhdr->strategy;
  DPMI_CallRMProc(&ctx, 0, 0, 0);

  /* call interrupt routine */
  ctx.SegCs = SELECTOROF(dev);
  ctx.Eip   = dhdr->interrupt;
  DPMI_CallRMProc(&ctx, 0, 0, 0);

  /* completed, copy request back */
  memcpy(req, phdr, hdr->size);

  if (hdr->status & STAT_ERROR) {
    switch (hdr->status & STAT_MASK) {
    case 0x0F: /* invalid disk change */
      /* this error seems to fit the bill */
      SetLastError(ERROR_NOT_SAME_DEVICE);
      break;
    default:
      SetLastError((hdr->status & STAT_MASK) + 0x13);
      break;
    }
  }
}

static int DOSDEV_IO(unsigned cmd, DWORD dev, DWORD buf, int buflen)
{
  REQ_IO req;

  req.hdr.size=sizeof(req);
  req.hdr.unit=0; /* not dealing with block devices yet */
  req.hdr.command=cmd;
  req.hdr.status=STAT_BUSY;
  req.media=0; /* not dealing with block devices yet */
  req.buffer=buf;
  req.count=buflen;
  req.sector=0; /* block devices */
  req.volume=0; /* block devices */

  DOSDEV_DoReq(&req, dev);

  return req.count;
}

int DOSDEV_Peek(DWORD dev, BYTE*data)
{
  REQ_SAFEINPUT req;

  req.hdr.size=sizeof(req);
  req.hdr.unit=0; /* not dealing with block devices yet */
  req.hdr.command=CMD_SAFEINPUT;
  req.hdr.status=STAT_BUSY;
  req.data=0;

  DOSDEV_DoReq(&req, dev);

  if (req.hdr.status & STAT_BUSY) return 0;

  *data = req.data;
  return 1;
}

int DOSDEV_Read(DWORD dev, DWORD buf, int buflen)
{
  return DOSDEV_IO(CMD_INPUT, dev, buf, buflen);
}

int DOSDEV_Write(DWORD dev, DWORD buf, int buflen, int verify)
{
  return DOSDEV_IO(verify?CMD_SAFEOUTPUT:CMD_OUTPUT, dev, buf, buflen);
}

int DOSDEV_IoctlRead(DWORD dev, DWORD buf, int buflen)
{
  return DOSDEV_IO(CMD_INIOCTL, dev, buf, buflen);
}

int DOSDEV_IoctlWrite(DWORD dev, DWORD buf, int buflen)
{
  return DOSDEV_IO(CMD_OUTIOCTL, dev, buf, buflen);
}

void DOSDEV_SetSharingRetry(WORD delay, WORD count)
{
    DOSMEM_LOL()->sharing_retry_delay = delay;
    if (count) DOSMEM_LOL()->sharing_retry_count = count;
}

SEGPTR DOSDEV_GetLOL(BOOL v86)
{
    if (v86) return DOSMEM_LOL()->wine_rm_lol;
    else return DOSMEM_LOL()->wine_pm_lol;
}
