/*
 * 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 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 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) : 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]));
}

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;
}
