DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 00020 #include <string.h> 00021 #include "dosbox.h" 00022 #include "callback.h" 00023 #include "regs.h" 00024 #include "mem.h" 00025 #include "bios.h" 00026 #include "dos_inc.h" 00027 #include "support.h" 00028 #include "parport.h" 00029 #include "drives.h" //Wildcmp 00030 /* Include all the devices */ 00031 00032 #include "dev_con.h" 00033 00034 00035 DOS_Device * Devices[DOS_DEVICES] = {NULL}; 00036 extern int dos_clipboard_device_access; 00037 extern char * dos_clipboard_device_name; 00038 00039 class device_NUL : public DOS_Device { 00040 public: 00041 device_NUL() { SetName("NUL"); }; 00042 virtual bool Read(Bit8u * data,Bit16u * size) { 00043 (void)data; // UNUSED 00044 *size = 0; //Return success and no data read. 00045 // LOG(LOG_IOCTL,LOG_NORMAL)("%s:READ",GetName()); 00046 return true; 00047 } 00048 virtual bool Write(const Bit8u * data,Bit16u * size) { 00049 (void)data; // UNUSED 00050 (void)size; // UNUSED 00051 // LOG(LOG_IOCTL,LOG_NORMAL)("%s:WRITE",GetName()); 00052 return true; 00053 } 00054 virtual bool Seek(Bit32u * pos,Bit32u type) { 00055 (void)type; 00056 (void)pos; 00057 // LOG(LOG_IOCTL,LOG_NORMAL)("%s:SEEK",GetName()); 00058 return true; 00059 } 00060 virtual bool Close() { return true; } 00061 virtual Bit16u GetInformation(void) { return 0x8084; } 00062 virtual bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { (void)bufptr; (void)size; (void)retcode; return false; } 00063 virtual bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { (void)bufptr; (void)size; (void)retcode; return false; } 00064 }; 00065 00066 class device_PRN : public DOS_Device { 00067 public: 00068 device_PRN() { 00069 SetName("PRN"); 00070 } 00071 bool Read(Bit8u * data,Bit16u * size) { 00072 (void)data; // UNUSED 00073 (void)size; // UNUSED 00074 DOS_SetError(DOSERR_ACCESS_DENIED); 00075 return false; 00076 } 00077 bool Write(const Bit8u * data,Bit16u * size) { 00078 for(int i = 0; i < 3; i++) { 00079 // look up a parallel port 00080 if(parallelPortObjects[i] != NULL) { 00081 // send the data 00082 for (Bit16u j=0; j<*size; j++) { 00083 if(!parallelPortObjects[i]->Putchar(data[j])) return false; 00084 } 00085 return true; 00086 } 00087 } 00088 return false; 00089 } 00090 bool Seek(Bit32u * pos,Bit32u type) { 00091 (void)type; // UNUSED 00092 *pos = 0; 00093 return true; 00094 } 00095 Bit16u GetInformation(void) { 00096 return 0x80A0; 00097 } 00098 bool Close() { 00099 return false; 00100 } 00101 }; 00102 00103 #if defined(WIN32) 00104 bool lastwrite = false; 00105 Bit8u *clipAscii = NULL; 00106 Bit32u clipSize = 0, cPointer = 0, fPointer; 00107 00108 void Unicode2Ascii(const Bit16u* unicode) 00109 { 00110 int memNeeded = WideCharToMultiByte(dos.loaded_codepage, WC_NO_BEST_FIT_CHARS, (LPCWSTR)unicode, -1, NULL, 0, "\x07", NULL); 00111 if (memNeeded <= 1) // Includes trailing null 00112 return; 00113 if (!(clipAscii = (Bit8u *)malloc(memNeeded))) 00114 return; 00115 // Untranslated characters will be set to 0x07 (BEL), and later stripped 00116 if (WideCharToMultiByte(dos.loaded_codepage, WC_NO_BEST_FIT_CHARS, (LPCWSTR)unicode, -1, (LPSTR)clipAscii, memNeeded, "\x07", NULL) != memNeeded) 00117 { // Can't actually happen of course 00118 free(clipAscii); 00119 clipAscii = NULL; 00120 return; 00121 } 00122 memNeeded--; // Don't include trailing null 00123 for (int i = 0; i < memNeeded; i++) 00124 if (clipAscii[i] > 31 || clipAscii[i] == 9 || clipAscii[i] == 10 || clipAscii[i] == 13) // Space and up, or TAB, CR/LF allowed (others make no sense when pasting) 00125 clipAscii[clipSize++] = clipAscii[i]; 00126 return; // clipAscii dould be downsized, but of no real interest 00127 } 00128 00129 bool getClipboard() 00130 { 00131 if (clipAscii) 00132 { 00133 free(clipAscii); 00134 clipAscii = NULL; 00135 } 00136 clipSize = 0; 00137 if (OpenClipboard(NULL)) 00138 { 00139 if (HANDLE cbText = GetClipboardData(CF_UNICODETEXT)) 00140 { 00141 Bit16u *unicode = (Bit16u *)GlobalLock(cbText); 00142 Unicode2Ascii(unicode); 00143 GlobalUnlock(cbText); 00144 } 00145 CloseClipboard(); 00146 } 00147 return clipSize != 0; 00148 } 00149 00150 Bit16u cpMap[256] = { 00151 0x0020, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2219, 0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c, 00152 0x25ba, 0x25c4, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc, 00153 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 00154 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 00155 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 00156 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 00157 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 00158 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302, 00159 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, 00160 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, 00161 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, 00162 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, // 176 - 223 line/box drawing 00163 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, 00164 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, 00165 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, 00166 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x0020 00167 }; 00168 00169 00170 class device_CLIP : public DOS_Device { 00171 private: 00172 char tmpAscii[20]; 00173 char tmpUnicode[20]; 00174 std::string rawdata; // the raw data sent to CLIP$... 00175 virtual void CommitData() { 00176 if (cPointer>0) { 00177 if (!clipSize) 00178 getClipboard(); 00179 if (cPointer>clipSize) 00180 cPointer=clipSize; 00181 if (clipSize) { 00182 if (rawdata.capacity() < 100000) 00183 rawdata.reserve(100000); 00184 std::string temp=std::string((char *)clipAscii).substr(0, cPointer); 00185 if (temp[temp.length()-1]!='\n') temp+="\n"; 00186 rawdata.insert(0, temp); 00187 clipSize=0; 00188 } 00189 cPointer=0; 00190 } 00191 FILE* fh = fopen(tmpAscii, "wb"); // Append or write to ASCII file 00192 if (fh) 00193 { 00194 fwrite(rawdata.c_str(), rawdata.size(), 1, fh); 00195 fclose(fh); 00196 fh = fopen(tmpUnicode, "w+b"); // The same for Unicode file (it's eventually read) 00197 if (fh) 00198 { 00199 fprintf(fh, "\xff\xfe"); // It's a Unicode text file 00200 for (Bit32u i = 0; i < rawdata.size(); i++) 00201 { 00202 Bit16u textChar = (Bit8u)rawdata[i]; 00203 switch (textChar) 00204 { 00205 case 9: // Tab 00206 case 12: // Formfeed 00207 fwrite(&textChar, 1, 2, fh); 00208 break; 00209 case 10: // Linefeed (combination) 00210 case 13: 00211 fwrite("\x0d\x00\x0a\x00", 1, 4, fh); 00212 if (i < rawdata.size() -1 && textChar == 23-rawdata[i+1]) 00213 i++; 00214 break; 00215 default: 00216 if (textChar >= 32) // Forget about further control characters? 00217 fwrite(cpMap+textChar, 1, 2, fh); 00218 break; 00219 } 00220 } 00221 } 00222 } 00223 if (!fh) 00224 { 00225 rawdata.clear(); 00226 return; 00227 } 00228 if (OpenClipboard(NULL)) 00229 { 00230 if (EmptyClipboard()) 00231 { 00232 int bytes = ftell(fh); 00233 HGLOBAL hCbData = GlobalAlloc(NULL, bytes); 00234 Bit8u* pChData = (Bit8u*)GlobalLock(hCbData); 00235 if (pChData) 00236 { 00237 fseek(fh, 2, SEEK_SET); // Skip Unicode signature 00238 fread(pChData, 1, bytes-2, fh); 00239 pChData[bytes-2] = 0; 00240 pChData[bytes-1] = 0; 00241 SetClipboardData(CF_UNICODETEXT, hCbData); 00242 GlobalUnlock(hCbData); 00243 } 00244 } 00245 CloseClipboard(); 00246 } 00247 fclose(fh); 00248 remove(tmpAscii); 00249 remove(tmpUnicode); 00250 rawdata.clear(); 00251 return; 00252 } 00253 public: 00254 device_CLIP() { 00255 SetName(*dos_clipboard_device_name?dos_clipboard_device_name:"CLIP$"); 00256 strcpy(tmpAscii, "#clip$.asc"); 00257 strcpy(tmpUnicode, "#clip$.txt"); 00258 } 00259 virtual bool Read(Bit8u * data,Bit16u * size) { 00260 if(control->SecureMode()||!(dos_clipboard_device_access==2||dos_clipboard_device_access==4)) { 00261 *size = 0; 00262 return true; 00263 } 00264 lastwrite=false; 00265 if (!clipSize) // If no data, we have to read the Windows CLipboard (clipSize gets reset on device close) 00266 { 00267 getClipboard(); 00268 fPointer = 0; 00269 } 00270 if (fPointer >= clipSize) 00271 *size = 0; 00272 else if (fPointer+*size > clipSize) 00273 *size = (Bit16u)(clipSize-fPointer); 00274 if (*size > 0) { 00275 memmove(data, clipAscii+fPointer, *size); 00276 fPointer += *size; 00277 } 00278 return true; 00279 } 00280 virtual bool Write(const Bit8u * data,Bit16u * size) { 00281 if(control->SecureMode()||!(dos_clipboard_device_access==3||dos_clipboard_device_access==4)) { 00282 DOS_SetError(DOSERR_ACCESS_DENIED); 00283 return false; 00284 } 00285 lastwrite=true; 00286 const Bit8u* datasrc = (Bit8u*)data; 00287 Bit8u * datadst = (Bit8u *) data; 00288 00289 int numSpaces = 0; 00290 for (Bit16u idx = *size; idx; idx--) 00291 { 00292 if (*datasrc == ' ') // Put spaces on hold 00293 numSpaces++; 00294 else 00295 { 00296 if (numSpaces && *datasrc != 0x0a && *datasrc != 0x0d) // Spaces on hold and not end of line 00297 while (numSpaces--) 00298 *(datadst++) = ' '; 00299 numSpaces = 0; 00300 *(datadst++) = *datasrc; 00301 } 00302 datasrc++; 00303 } 00304 while (numSpaces--) 00305 *(datadst++) = ' '; 00306 if (Bit16u newsize = (Bit16u)(datadst - data)) // If data 00307 { 00308 if (rawdata.capacity() < 100000) // Prevent repetive size allocations 00309 rawdata.reserve(100000); 00310 rawdata.append((char *)data, newsize); 00311 } 00312 return true; 00313 } 00314 virtual bool Seek(Bit32u * pos,Bit32u type) { 00315 if(control->SecureMode()||!(dos_clipboard_device_access==2||dos_clipboard_device_access==4)) { 00316 *pos = 0; 00317 return true; 00318 } 00319 lastwrite=false; 00320 if (clipSize == 0) // No data yet 00321 { 00322 getClipboard(); 00323 fPointer =0; 00324 } 00325 Bit32s newPos; 00326 switch (type) 00327 { 00328 case 0: // Start of file 00329 newPos = *pos; 00330 break; 00331 case 1: // Current file position 00332 newPos = fPointer+*pos; 00333 break; 00334 case 2: // End of file 00335 newPos = clipSize+*pos; 00336 break; 00337 default: 00338 { 00339 DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); 00340 return false; 00341 } 00342 } 00343 if (newPos > (Bit32s)clipSize) // Different from "real" Files 00344 newPos = clipSize; 00345 else if (newPos < 0) 00346 newPos = 0; 00347 *pos = newPos; 00348 cPointer = newPos; 00349 fPointer = newPos; 00350 return true; 00351 } 00352 virtual bool Close() { 00353 if(control->SecureMode()||dos_clipboard_device_access<2) 00354 return false; 00355 clipSize = 0; // Reset clipboard read 00356 rawdata.erase(rawdata.find_last_not_of(" \n\r\t")+1); // Remove trailing white space 00357 if (!rawdata.size()&&!lastwrite) // Nothing captured/to do 00358 return false; 00359 lastwrite=false; 00360 int len = (int)rawdata.size(); 00361 if (len > 2 && rawdata[len-3] == 0x0c && rawdata[len-2] == 27 && rawdata[len-1] == 64) // <ESC>@ after last FF? 00362 rawdata.erase(len-2, 2); 00363 CommitData(); 00364 return true; 00365 } 00366 Bit16u GetInformation(void) { 00367 return 0x80E0; 00368 } 00369 }; 00370 #endif 00371 00372 bool DOS_Device::Read(Bit8u * data,Bit16u * size) { 00373 return Devices[devnum]->Read(data,size); 00374 } 00375 00376 bool DOS_Device::Write(const Bit8u * data,Bit16u * size) { 00377 return Devices[devnum]->Write(data,size); 00378 } 00379 00380 bool DOS_Device::Seek(Bit32u * pos,Bit32u type) { 00381 return Devices[devnum]->Seek(pos,type); 00382 } 00383 00384 bool DOS_Device::Close() { 00385 return Devices[devnum]->Close(); 00386 } 00387 00388 Bit16u DOS_Device::GetInformation(void) { 00389 return Devices[devnum]->GetInformation(); 00390 } 00391 00392 bool DOS_Device::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { 00393 return Devices[devnum]->ReadFromControlChannel(bufptr,size,retcode); 00394 } 00395 00396 bool DOS_Device::WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { 00397 return Devices[devnum]->WriteToControlChannel(bufptr,size,retcode); 00398 } 00399 00400 DOS_File::DOS_File(const DOS_File& orig) : flags(orig.flags), open(orig.open), attr(orig.attr), 00401 time(orig.time), date(orig.date), refCtr(orig.refCtr), hdrive(orig.hdrive) { 00402 if(orig.name) { 00403 name=new char [strlen(orig.name) + 1];strcpy(name,orig.name); 00404 } 00405 } 00406 00407 DOS_File& DOS_File::operator= (const DOS_File& orig) { 00408 if (this != &orig) { 00409 flags = orig.flags; 00410 time = orig.time; 00411 date = orig.date; 00412 attr = orig.attr; 00413 refCtr = orig.refCtr; 00414 open = orig.open; 00415 hdrive = orig.hdrive; 00416 drive = orig.drive; 00417 newtime = orig.newtime; 00418 if (name) { 00419 delete[] name; name = 0; 00420 } 00421 if (orig.name) { 00422 name = new char[strlen(orig.name) + 1]; strcpy(name, orig.name); 00423 } 00424 } 00425 return *this; 00426 } 00427 00428 Bit8u DOS_FindDevice(char const * name) { 00429 /* should only check for the names before the dot and spacepadded */ 00430 char fullname[DOS_PATHLENGTH];Bit8u drive; 00431 // if(!name || !(*name)) return DOS_DEVICES; //important, but makename does it 00432 if (!DOS_MakeName(name,fullname,&drive)) return DOS_DEVICES; 00433 00434 char* name_part = strrchr(fullname,'\\'); 00435 if(name_part) { 00436 *name_part++ = 0; 00437 //Check validity of leading directory. 00438 if(!Drives[drive]->TestDir(fullname)) return DOS_DEVICES; 00439 } else name_part = fullname; 00440 00441 char* dot = strrchr(name_part,'.'); 00442 if(dot) *dot = 0; //no ext checking 00443 00444 static char com[5] = { 'C','O','M','1',0 }; 00445 static char lpt[5] = { 'L','P','T','1',0 }; 00446 // AUX is alias for COM1 and PRN for LPT1 00447 // A bit of a hack. (but less then before). 00448 // no need for casecmp as makename returns uppercase 00449 if (strcmp(name_part, "AUX") == 0) name_part = com; 00450 if (strcmp(name_part, "PRN") == 0) name_part = lpt; 00451 00452 /* loop through devices */ 00453 for(Bit8u index = 0;index < DOS_DEVICES;index++) { 00454 if (Devices[index]) { 00455 if (WildFileCmp(name_part,Devices[index]->name)) return index; 00456 } 00457 } 00458 return DOS_DEVICES; 00459 } 00460 00461 00462 void DOS_AddDevice(DOS_Device * adddev) { 00463 //Caller creates the device. We store a pointer to it 00464 //TODO Give the Device a real handler in low memory that responds to calls 00465 if (adddev == NULL) E_Exit("DOS_AddDevice with null ptr"); 00466 for(Bitu i = 0; i < DOS_DEVICES;i++) { 00467 if (Devices[i] == NULL){ 00468 // LOG_MSG("DOS_AddDevice %s (%p)\n",adddev->name,(void*)adddev); 00469 Devices[i] = adddev; 00470 Devices[i]->SetDeviceNumber(i); 00471 return; 00472 } 00473 } 00474 E_Exit("DOS:Too many devices added"); 00475 } 00476 00477 void DOS_DelDevice(DOS_Device * dev) { 00478 // We will destroy the device if we find it in our list. 00479 // TODO:The file table is not checked to see the device is opened somewhere! 00480 if (dev == NULL) return E_Exit("DOS_DelDevice with null ptr"); 00481 for (Bitu i = 0; i <DOS_DEVICES;i++) { 00482 if (Devices[i] == dev) { /* NTS: The mainline code deleted by matching names??? Why? */ 00483 // LOG_MSG("DOS_DelDevice %s (%p)\n",dev->name,(void*)dev); 00484 delete Devices[i]; 00485 Devices[i] = 0; 00486 return; 00487 } 00488 } 00489 00490 /* hm. unfortunately, too much code in DOSBox assumes that we delete the object. 00491 * prior to this fix, failure to delete caused a memory leak */ 00492 LOG_MSG("WARNING: DOS_DelDevice() failed to match device object '%s' (%p). Deleting anyway\n",dev->name,(void*)dev); 00493 delete dev; 00494 } 00495 00496 void DOS_ShutdownDevices(void) { 00497 for (Bitu i=0;i < DOS_DEVICES;i++) { 00498 if (Devices[i] != NULL) { 00499 // LOG_MSG("DOS: Shutting down device %s (%p)\n",Devices[i]->name,(void*)Devices[i]); 00500 delete Devices[i]; 00501 Devices[i] = NULL; 00502 } 00503 } 00504 00505 /* NTS: CON counts as a device */ 00506 if (IS_PC98_ARCH) update_pc98_function_row(0); 00507 } 00508 00509 // INT 29h emulation needs to keep track of CON 00510 device_CON *DOS_CON = NULL; 00511 00512 bool ANSI_SYS_installed() { 00513 if (DOS_CON != NULL) 00514 return DOS_CON->ANSI_SYS_installed(); 00515 00516 return false; 00517 } 00518 00519 void DOS_SetupDevices(void) { 00520 DOS_Device * newdev; 00521 DOS_CON=new device_CON(); newdev=DOS_CON; 00522 DOS_AddDevice(newdev); 00523 DOS_Device * newdev2; 00524 newdev2=new device_NUL(); 00525 DOS_AddDevice(newdev2); 00526 DOS_Device * newdev3; 00527 newdev3=new device_PRN(); 00528 DOS_AddDevice(newdev3); 00529 #if defined(WIN32) 00530 if (dos_clipboard_device_access) { 00531 DOS_Device * newdev4; 00532 newdev4=new device_CLIP(); 00533 DOS_AddDevice(newdev4); 00534 } 00535 #endif 00536 } 00537 00538 /* PC-98 INT DC CL=0x10 AH=0x00 DL=cjar */ 00539 void PC98_INTDC_WriteChar(unsigned char b) { 00540 if (DOS_CON != NULL) { 00541 Bit16u sz = 1; 00542 00543 DOS_CON->Write(&b,&sz); 00544 } 00545 } 00546 00547 void INTDC_CL10h_AH03h(Bit16u raw) { 00548 if (DOS_CON != NULL) 00549 DOS_CON->INTDC_CL10h_AH03h(raw); 00550 } 00551 00552 void INTDC_CL10h_AH04h(void) { 00553 if (DOS_CON != NULL) 00554 DOS_CON->INTDC_CL10h_AH04h(); 00555 } 00556 00557 void INTDC_CL10h_AH05h(void) { 00558 if (DOS_CON != NULL) 00559 DOS_CON->INTDC_CL10h_AH05h(); 00560 } 00561 00562 void INTDC_CL10h_AH06h(Bit16u count) { 00563 if (DOS_CON != NULL) 00564 DOS_CON->INTDC_CL10h_AH06h(count); 00565 } 00566 00567 void INTDC_CL10h_AH07h(Bit16u count) { 00568 if (DOS_CON != NULL) 00569 DOS_CON->INTDC_CL10h_AH07h(count); 00570 } 00571 00572 void INTDC_CL10h_AH08h(Bit16u count) { 00573 if (DOS_CON != NULL) 00574 DOS_CON->INTDC_CL10h_AH08h(count); 00575 } 00576 00577 void INTDC_CL10h_AH09h(Bit16u count) { 00578 if (DOS_CON != NULL) 00579 DOS_CON->INTDC_CL10h_AH09h(count); 00580 } 00581 00582 Bitu INT29_HANDLER(void) { 00583 if (DOS_CON != NULL) { 00584 unsigned char b = reg_al; 00585 Bit16u sz = 1; 00586 00587 DOS_CON->Write(&b,&sz); 00588 } 00589 00590 return CBRET_NONE; 00591 } 00592 00593 extern bool dos_kernel_disabled; 00594 00595 // save state support 00596 void POD_Save_DOS_Devices( std::ostream& stream ) 00597 { 00598 if (!dos_kernel_disabled) { 00599 if( strcmp( Devices[2]->GetName(), "CON" ) == 0 ) 00600 Devices[2]->SaveState(stream); 00601 } 00602 } 00603 00604 void POD_Load_DOS_Devices( std::istream& stream ) 00605 { 00606 if (!dos_kernel_disabled) { 00607 if( strcmp( Devices[2]->GetName(), "CON" ) == 0 ) 00608 Devices[2]->LoadState(stream, false); 00609 } 00610 }