int21 / fix console input & move file stamp stuff

Jukka Heinonen jhei at iki.fi
Sun Jan 26 07:23:40 CST 2003


This patch makes all console input functions handle
extended keycodes correctly. Previously only one of these
did work properly. Also, some small migration stuff is included
to this patch.




Changelog:
  Return scancode when extended keycodes are read using
  console input functions. Move file stamp handling to
  winedos. Implement DOS7 file stamp extensions.




Index: dlls/winedos/int21.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int21.c,v
retrieving revision 1.21
diff -u -r1.21 int21.c
--- dlls/winedos/int21.c	23 Jan 2003 01:23:01 -0000	1.21
+++ dlls/winedos/int21.c	26 Jan 2003 13:14:43 -0000
@@ -83,6 +83,40 @@
 
 
 /***********************************************************************
+ *           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
  *
  * Return DOS country code for default system locale.
@@ -370,6 +404,106 @@
 
 
 /***********************************************************************
+ *           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
  *
  * Handler for functions 0x51 and 0x62.
@@ -544,7 +678,7 @@
 
 
 /***********************************************************************
- *           DOSVM_Int21Handler (WINEDOS16.133)
+ *           DOSVM_Int21Handler
  *
  * Interrupt 0x21 handler.
  */
@@ -584,8 +718,11 @@
         {
             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 @@
         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 */
-                    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 */
-                    SET_AL( context, 0 );
-                    SET_ZFLAG(context);
-                    scan = 0; /* just in case */
-                }
+                INT21_ReadChar( &ascii, FALSE );
+                SET_AL( context, ascii );
+                RESET_ZFLAG( context );
+            }
+            else
+            {
+                /* no character available */
+                SET_AL( context, 0 );
+                SET_ZFLAG( context );
             }
-        } 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 @@
     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 @@
     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 @@
         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 @@
     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 */




Index: msdos/int21.c
===================================================================
RCS file: /home/wine/wine/msdos/int21.c,v
retrieving revision 1.84
diff -u -r1.84 int21.c
--- msdos/int21.c	23 Jan 2003 22:51:04 -0000	1.84
+++ msdos/int21.c	26 Jan 2003 13:14:49 -0000
@@ -1441,41 +1441,6 @@
 			       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);
@@ -1488,13 +1453,6 @@
                _lcreat16_uniq( CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Edx),
                                CX_reg(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:




-- 
Jukka Heinonen <http://www.iki.fi/jhei/>



More information about the wine-patches mailing list