1 /* 2 * COPYRIGHT: GPL - See COPYING in the top level directory 3 * PROJECT: ReactOS Virtual DOS Machine 4 * FILE: subsystems/mvdm/ntvdm/dos/dos32krnl/condrv.c 5 * PURPOSE: DOS32 CON Driver 6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org> 7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr) 8 */ 9 10 /* INCLUDES *******************************************************************/ 11 12 #include "ntvdm.h" 13 14 #define NDEBUG 15 #include <debug.h> 16 17 #include "emulator.h" 18 19 #include "dos.h" 20 #include "dos/dem.h" 21 22 #include "bios/bios.h" 23 24 /* PRIVATE VARIABLES **********************************************************/ 25 26 PDOS_DEVICE_NODE Con = NULL; 27 BYTE ExtendedCode = 0; 28 29 /* PRIVATE FUNCTIONS **********************************************************/ 30 31 WORD NTAPI ConDrvReadInput(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length) 32 { 33 CHAR Character; 34 WORD BytesRead = 0; 35 PCHAR Pointer = (PCHAR)FAR_POINTER(Buffer); 36 37 /* Save AX */ 38 USHORT AX = getAX(); 39 40 /* 41 * Use BIOS Get Keystroke function 42 */ 43 while (BytesRead < *Length) 44 { 45 if (!ExtendedCode) 46 { 47 /* Call the BIOS INT 16h, AH=00h "Get Keystroke" */ 48 setAH(0x00); 49 Int32Call(&DosContext, BIOS_KBD_INTERRUPT); 50 51 /* Retrieve the character in AL (scan code is in AH) */ 52 Character = getAL(); 53 } 54 else 55 { 56 /* Return the extended code */ 57 Character = ExtendedCode; 58 59 /* And then clear it */ 60 ExtendedCode = 0; 61 } 62 63 /* Check if this is a special character */ 64 if (Character == 0) ExtendedCode = getAH(); 65 66 Pointer[BytesRead++] = Character; 67 68 /* Stop on first carriage return */ 69 if (Character == '\r') break; 70 } 71 72 *Length = BytesRead; 73 74 /* Restore AX */ 75 setAX(AX); 76 return DOS_DEVSTAT_DONE; 77 } 78 79 WORD NTAPI ConDrvInputStatus(PDOS_DEVICE_NODE Device) 80 { 81 /* Save AX */ 82 USHORT AX = getAX(); 83 84 /* Call the BIOS */ 85 setAH(0x01); // or 0x11 for enhanced, but what to choose? 86 Int32Call(&DosContext, BIOS_KBD_INTERRUPT); 87 88 /* Restore AX */ 89 setAX(AX); 90 91 /* If ZF is set, set the busy bit */ 92 if (getZF() && !ExtendedCode) return DOS_DEVSTAT_BUSY; 93 else return DOS_DEVSTAT_DONE; 94 } 95 96 WORD NTAPI ConDrvWriteOutput(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length) 97 { 98 WORD BytesWritten; 99 PCHAR Pointer = (PCHAR)FAR_POINTER(Buffer); 100 101 /* Save AX */ 102 USHORT AX = getAX(); 103 104 for (BytesWritten = 0; BytesWritten < *Length; BytesWritten++) 105 { 106 /* Set the character */ 107 setAL(Pointer[BytesWritten]); 108 109 /* Call the BIOS INT 29h "Fast Console Output" function */ 110 Int32Call(&DosContext, 0x29); 111 } 112 113 /* Restore AX */ 114 setAX(AX); 115 return DOS_DEVSTAT_DONE; 116 } 117 118 WORD NTAPI ConDrvOpen(PDOS_DEVICE_NODE Device) 119 { 120 DPRINT("Handle to %Z opened\n", &Device->Name); 121 return DOS_DEVSTAT_DONE; 122 } 123 124 WORD NTAPI ConDrvClose(PDOS_DEVICE_NODE Device) 125 { 126 DPRINT("Handle to %Z closed\n", &Device->Name); 127 return DOS_DEVSTAT_DONE; 128 } 129 130 /* PUBLIC FUNCTIONS ***********************************************************/ 131 132 VOID ConDrvInitialize(VOID) 133 { 134 Con = DosCreateDevice(DOS_DEVATTR_STDIN 135 | DOS_DEVATTR_STDOUT 136 | DOS_DEVATTR_CON 137 | DOS_DEVATTR_CHARACTER, 138 "CON"); 139 140 Con->ReadRoutine = ConDrvReadInput; 141 Con->InputStatusRoutine = ConDrvInputStatus; 142 Con->WriteRoutine = ConDrvWriteOutput; 143 Con->OpenRoutine = ConDrvOpen; 144 Con->CloseRoutine = ConDrvClose; 145 } 146 147 VOID ConDrvCleanup(VOID) 148 { 149 if (Con) DosDeleteDevice(Con); 150 } 151