コード例 #1
0
ファイル: dosdev.c プロジェクト: AlexSteel/wine
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]));
}
コード例 #2
0
ファイル: devices.c プロジェクト: WASSUM/longene_travel
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;
    }
  }
}
コード例 #3
0
ファイル: dosdev.c プロジェクト: AlexSteel/wine
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;
}
コード例 #4
0
ファイル: dosdev.c プロジェクト: AlexSteel/wine
SEGPTR DOSDEV_GetLOL(BOOL v86)
{
    if (v86) return DOSMEM_LOL()->wine_rm_lol;
    else return DOSMEM_LOL()->wine_pm_lol;
}
コード例 #5
0
ファイル: dosdev.c プロジェクト: AlexSteel/wine
void DOSDEV_SetSharingRetry(WORD delay, WORD count)
{
    DOSMEM_LOL()->sharing_retry_delay = delay;
    if (count) DOSMEM_LOL()->sharing_retry_count = count;
}
コード例 #6
0
ファイル: dosdev.c プロジェクト: AlexSteel/wine
static void WINAPI con_interrupt(CONTEXT*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) : 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);
}
コード例 #7
0
ファイル: devices.c プロジェクト: WASSUM/longene_travel
DWORD DOSDEV_Console(void)
{
  return DOSMEM_LOL()->ptr_CON_dev_hdr;
}