Return scancode when extended keycodes are read using console input

functions. Move file stamp handling to winedos. Implement DOS7 file
stamp extensions.
This commit is contained in:
Jukka Heinonen 2003-01-28 00:18:57 +00:00 committed by Alexandre Julliard
parent 7ee13d8f3e
commit f92c8ca401
2 changed files with 179 additions and 76 deletions

View file

@ -82,6 +82,40 @@ typedef struct _INT21_HEAP {
#include "poppack.h"
/***********************************************************************
* INT21_ReadChar
*
* Reads a character from the standard input.
* Extended keycodes will be returned as two separate characters.
*/
static BOOL INT21_ReadChar( BYTE *input, BOOL peek )
{
static BYTE pending_scan = 0;
if (pending_scan)
{
if (input)
*input = pending_scan;
if (!peek)
pending_scan = 0;
return TRUE;
}
else
{
BYTE ascii;
BYTE scan;
if (!DOSVM_Int16ReadChar( &ascii, &scan, peek ))
return FALSE;
if (input)
*input = ascii;
if (!peek && !ascii)
pending_scan = scan;
return TRUE;
}
}
/***********************************************************************
* INT21_GetSystemCountryCode
*
@ -369,6 +403,106 @@ static void INT21_ExtendedCountryInformation( CONTEXT86 *context )
}
/***********************************************************************
* INT21_FileDateTime
*
* Handler for function 0x57.
*/
static BOOL INT21_FileDateTime( CONTEXT86 *context )
{
HANDLE handle = DosFileHandleToWin32Handle(BX_reg(context));
FILETIME filetime;
WORD date, time;
switch (AL_reg(context)) {
case 0x00: /* Get last-written stamp */
TRACE( "GET FILE LAST-WRITTEN DATE AND TIME, handle %d\n",
BX_reg(context) );
{
if (!GetFileTime( handle, NULL, NULL, &filetime ))
return FALSE;
FileTimeToDosDateTime( &filetime, &date, &time );
SET_DX( context, date );
SET_CX( context, time );
break;
}
case 0x01: /* Set last-written stamp */
TRACE( "SET FILE LAST-WRITTEN DATE AND TIME, handle %d\n",
BX_reg(context) );
{
DosDateTimeToFileTime( DX_reg(context),
CX_reg(context),
&filetime );
if (!SetFileTime( handle, NULL, NULL, &filetime ))
return FALSE;
break;
}
case 0x04: /* Get last access stamp, DOS 7 */
TRACE( "GET FILE LAST ACCESS DATE AND TIME, handle %d\n",
BX_reg(context) );
{
if (!GetFileTime( handle, NULL, &filetime, NULL ))
return FALSE;
FileTimeToDosDateTime( &filetime, &date, &time );
SET_DX( context, date );
SET_CX( context, time );
break;
}
case 0x05: /* Set last access stamp, DOS 7 */
TRACE( "SET FILE LAST ACCESS DATE AND TIME, handle %d\n",
BX_reg(context) );
{
DosDateTimeToFileTime( DX_reg(context),
CX_reg(context),
&filetime );
if (!SetFileTime( handle, NULL, &filetime, NULL ))
return FALSE;
break;
}
case 0x06: /* Get creation stamp, DOS 7 */
TRACE( "GET FILE CREATION DATE AND TIME, handle %d\n",
BX_reg(context) );
{
if (!GetFileTime( handle, &filetime, NULL, NULL ))
return FALSE;
FileTimeToDosDateTime( &filetime, &date, &time );
SET_DX( context, date );
SET_CX( context, time );
/*
* FIXME: SI has number of 10-millisecond units past time in CX.
*/
SET_SI( context, 0 );
break;
}
case 0x07: /* Set creation stamp, DOS 7 */
TRACE( "SET FILE CREATION DATE AND TIME, handle %d\n",
BX_reg(context) );
{
/*
* FIXME: SI has number of 10-millisecond units past time in CX.
*/
DosDateTimeToFileTime( DX_reg(context),
CX_reg(context),
&filetime );
if (!SetFileTime( handle, &filetime, NULL, NULL ))
return FALSE;
break;
}
default:
INT_BARF( context, 0x21 );
break;
}
return TRUE;
}
/***********************************************************************
* INT21_GetPSP
*
@ -544,7 +678,7 @@ static void INT21_GetExtendedError( CONTEXT86 *context )
/***********************************************************************
* DOSVM_Int21Handler (WINEDOS16.133)
* DOSVM_Int21Handler
*
* Interrupt 0x21 handler.
*/
@ -584,8 +718,11 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
{
BYTE ascii;
TRACE("DIRECT CHARACTER INPUT WITH ECHO\n");
DOSVM_Int16ReadChar(&ascii, NULL, FALSE);
INT21_ReadChar( &ascii, FALSE );
SET_AL( context, ascii );
/*
* FIXME: What to echo when extended keycodes are read?
*/
DOSVM_PutChar(AL_reg(context));
}
break;
@ -602,43 +739,41 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
break;
case 0x06: /* DIRECT CONSOLE IN/OUTPUT */
/* FIXME: Use DOSDEV_Peek/Read/Write(DOSDEV_Console(),...) !! */
if (DL_reg(context) == 0xff) {
static char scan = 0;
if (DL_reg(context) == 0xff)
{
TRACE("Direct Console Input\n");
if (scan) {
/* return pending scancode */
SET_AL( context, scan );
RESET_ZFLAG(context);
scan = 0;
} else {
if (INT21_ReadChar( NULL, TRUE ))
{
BYTE ascii;
if (DOSVM_Int16ReadChar(&ascii,&scan,TRUE)) {
DOSVM_Int16ReadChar(&ascii,&scan,FALSE);
/* return ASCII code */
INT21_ReadChar( &ascii, FALSE );
SET_AL( context, ascii );
RESET_ZFLAG( context );
/* return scan code on next call only if ascii==0 */
if (ascii) scan = 0;
} else {
/* nothing pending, clear everything */
}
else
{
/* no character available */
SET_AL( context, 0 );
SET_ZFLAG( context );
scan = 0; /* just in case */
}
}
} else {
else
{
TRACE("Direct Console Output\n");
DOSVM_PutChar(DL_reg(context));
/*
* At least DOS versions 2.1-7.0 return character
* that was written in AL register.
*/
SET_AL( context, DL_reg(context) );
}
break;
case 0x07: /* DIRECT CHARACTER INPUT WITHOUT ECHO */
{
BYTE ascii;
/* FIXME: Use DOSDEV_Peek/Read(DOSDEV_Console(),...) !! */
TRACE("DIRECT CHARACTER INPUT WITHOUT ECHO\n");
DOSVM_Int16ReadChar(&ascii, NULL, FALSE);
INT21_ReadChar( &ascii, FALSE );
SET_AL( context, ascii );
}
break;
@ -646,9 +781,8 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
case 0x08: /* CHARACTER INPUT WITHOUT ECHO */
{
BYTE ascii;
/* FIXME: Use DOSDEV_Peek/Read(DOSDEV_Console(),...) !! */
TRACE("CHARACTER INPUT WITHOUT ECHO\n");
DOSVM_Int16ReadChar(&ascii, NULL, FALSE);
INT21_ReadChar( &ascii, FALSE );
SET_AL( context, ascii );
}
break;
@ -664,11 +798,10 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
case 0x0b: /* GET STDIN STATUS */
TRACE( "GET STDIN STATUS\n" );
{
BIOSDATA *data = BIOS_DATA;
if(data->FirstKbdCharPtr == data->NextKbdCharPtr)
SET_AL( context, 0 );
if (INT21_ReadChar( NULL, TRUE ))
SET_AL( context, 0xff ); /* character available */
else
SET_AL( context, 0xff );
SET_AL( context, 0 ); /* no character available */
}
break;
@ -1080,10 +1213,14 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
break;
case 0x56: /* "RENAME" - RENAME FILE */
case 0x57: /* FILE DATE AND TIME */
INT_Int21Handler( context );
break;
case 0x57: /* FILE DATE AND TIME */
if (!INT21_FileDateTime( context ))
bSetDOSExtendedError = TRUE;
break;
case 0x58: /* GET OR SET MEMORY ALLOCATION STRATEGY */
TRACE( "GET OR SET MEMORY ALLOCATION STRATEGY, subfunction %d\n",
AL_reg(context) );
@ -1111,7 +1248,15 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
case 0x5a: /* CREATE TEMPORARY FILE */
case 0x5b: /* CREATE NEW FILE */
case 0x5c: /* "FLOCK" - RECORD LOCKING */
INT_Int21Handler( context );
break;
case 0x5d: /* NETWORK 5D */
FIXME( "Network function 5D not implemented.\n" );
SetLastError( ER_NoNetwork );
bSetDOSExtendedError = TRUE;
break;
case 0x5e: /* NETWORK 5E */
case 0x5f: /* NETWORK 5F */
case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */

View file

@ -1441,41 +1441,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
CTX_SEG_OFF_TO_LIN(context, context->SegEs,context->Edi)));
break;
case 0x57: /* FILE DATE AND TIME */
switch (AL_reg(context))
{
case 0x00: /* Get */
{
FILETIME filetime;
TRACE("GET FILE DATE AND TIME for handle %d\n",
BX_reg(context));
if (!GetFileTime( DosFileHandleToWin32Handle(BX_reg(context)), NULL, NULL, &filetime ))
bSetDOSExtendedError = TRUE;
else
{
WORD date, time;
FileTimeToDosDateTime( &filetime, &date, &time );
SET_DX( context, date );
SET_CX( context, time );
}
}
break;
case 0x01: /* Set */
{
FILETIME filetime;
TRACE("SET FILE DATE AND TIME for handle %d\n",
BX_reg(context));
DosDateTimeToFileTime( DX_reg(context), CX_reg(context),
&filetime );
bSetDOSExtendedError =
(!SetFileTime( DosFileHandleToWin32Handle(BX_reg(context)),
NULL, NULL, &filetime ));
}
break;
}
break;
case 0x5a: /* CREATE TEMPORARY FILE */
TRACE("CREATE TEMPORARY FILE\n");
bSetDOSExtendedError = !INT21_CreateTempFile(context);
@ -1490,13 +1455,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
bSetDOSExtendedError = (AX_reg(context) != 0);
break;
case 0x5d: /* NETWORK */
FIXME("Function 0x%04x not implemented.\n", AX_reg (context));
/* Fix the following while you're at it. */
SetLastError( ER_NoNetwork );
bSetDOSExtendedError = TRUE;
break;
case 0x5e:
bSetDOSExtendedError = INT21_networkfunc (context);
break;