dosbox  0.74-3
About: DOSBox emulates a full x86 PC with sound and DOS (for e.g. to run old DOS games).
  Fossies Dox: dosbox-0.74-3.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

dos_mscdex.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2010 The DOSBox Team
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 /* $Id: dos_mscdex.cpp,v 1.59 2009-04-16 12:28:30 qbix79 Exp $ */
20 
21 #include <string.h>
22 #include <ctype.h>
23 #include "regs.h"
24 #include "callback.h"
25 #include "dos_system.h"
26 #include "dos_inc.h"
27 #include "setup.h"
28 #include "support.h"
29 #include "bios_disk.h"
30 #include "cpu.h"
31 
32 #include "cdrom.h"
33 
34 #define MSCDEX_LOG LOG(LOG_MISC,LOG_ERROR)
35 //#define MSCDEX_LOG
36 
37 #define MSCDEX_VERSION_HIGH 2
38 #define MSCDEX_VERSION_LOW 23
39 #define MSCDEX_MAX_DRIVES 8
40 
41 // Error Codes
42 #define MSCDEX_ERROR_INVALID_FUNCTION 1
43 #define MSCDEX_ERROR_BAD_FORMAT 11
44 #define MSCDEX_ERROR_UNKNOWN_DRIVE 15
45 #define MSCDEX_ERROR_DRIVE_NOT_READY 21
46 
47 // Request Status
48 #define REQUEST_STATUS_DONE 0x0100
49 #define REQUEST_STATUS_ERROR 0x8000
50 
51 // Use cdrom Interface
53 int forceCD = -1;
54 
55 static Bitu MSCDEX_Strategy_Handler(void);
56 static Bitu MSCDEX_Interrupt_Handler(void);
57 
59 public:
60  DOS_DeviceHeader(PhysPt ptr) { pt = ptr; };
61 
65  void SetDriveLetter (Bit8u letter) { sSave(sDeviceHeader,driveLetter,letter); };
68  void SetName (char const* _name) { MEM_BlockWrite(pt+offsetof(sDeviceHeader,name),_name,8); };
71 
72 public:
73  #ifdef _MSC_VER
74  #pragma pack(1)
75  #endif
76  struct sDeviceHeader{
81  Bit8u name[8];
85  } GCC_ATTRIBUTE(packed) TDeviceHeader;
86  #ifdef _MSC_VER
87  #pragma pack()
88  #endif
89 };
90 
91 class CMscdex {
92 public:
93  CMscdex (void);
94  ~CMscdex (void);
95 
97  Bit16u GetNumDrives (void) { return numDrives; };
98  Bit16u GetFirstDrive (void) { return dinfo[0].drive; };
99  Bit8u GetSubUnit (Bit16u _drive);
100  bool GetUPC (Bit8u subUnit, Bit8u& attr, char* upc);
101 
102  void InitNewMedia (Bit8u subUnit);
103  bool PlayAudioSector (Bit8u subUnit, Bit32u start, Bit32u length);
104  bool PlayAudioMSF (Bit8u subUnit, Bit32u start, Bit32u length);
105  bool StopAudio (Bit8u subUnit);
106  bool GetAudioStatus (Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end);
107 
108  bool GetSubChannelData (Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs);
109 
110  int RemoveDrive (Bit16u _drive);
111  int AddDrive (Bit16u _drive, char* physicalPath, Bit8u& subUnit);
112  bool HasDrive (Bit16u drive);
113  void ReplaceDrive (CDROM_Interface* newCdrom, Bit8u subUnit);
114  void GetDrives (PhysPt data);
115  void GetDriverInfo (PhysPt data);
116  bool GetVolumeName (Bit8u subUnit, char* name);
120  bool GetDirectoryEntry (Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error);
121  bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error);
122  bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data);
123  bool ReadSectors (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data);
124  bool ReadSectorsMSF (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data);
126  bool IsValidDrive (Bit16u drive);
127  bool GetCDInfo (Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut);
128  Bit32u GetVolumeSize (Bit8u subUnit);
129  bool GetTrackInfo (Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start);
131  bool GetCurrentPos (Bit8u subUnit, TMSF& pos);
132  Bit32u GetDeviceStatus (Bit8u subUnit);
133  bool GetMediaStatus (Bit8u subUnit, Bit8u& status);
134  bool LoadUnloadMedia (Bit8u subUnit, bool unload);
135  bool ResumeAudio (Bit8u subUnit);
136  bool GetMediaStatus (Bit8u subUnit, bool& media, bool& changed, bool& trayOpen);
137 
138 private:
139 
140  PhysPt GetDefaultBuffer (void);
141  PhysPt GetTempBuffer (void);
142 
144 
145  typedef struct SDriveInfo {
146  Bit8u drive; // drive letter in dosbox
147  Bit8u physDrive; // drive letter in system
148  bool audioPlay; // audio playing active
149  bool audioPaused; // audio playing paused
150  Bit32u audioStart; // StartLoc for resume
151  Bit32u audioEnd; // EndLoc for resume
152  bool locked; // drive locked ?
153  bool lastResult; // last operation success ?
154  Bit32u volumeSize; // for media change
155  } TDriveInfo;
156 
160 
161 public:
163 };
164 
166  numDrives = 0;
168  defaultBufSeg = 0;
169 
170  memset(dinfo,0,sizeof(dinfo));
171  for (Bit32u i=0; i<MSCDEX_MAX_DRIVES; i++) cdrom[i] = 0;
172 }
173 
175  defaultBufSeg = 0;
176  for (Bit16u i=0; i<GetNumDrives(); i++) {
177  delete (cdrom)[i];
178  cdrom[i] = 0;
179  };
180 }
181 
183 {
184  for (Bit16u i=0; i<GetNumDrives(); i++) mem_writeb(data+i,dinfo[i].drive);
185 }
186 
188 {
189  _drive &= 0xff; //Only lowerpart (Ultimate domain)
190  for (Bit16u i=0; i<GetNumDrives(); i++) if (dinfo[i].drive==_drive) return true;
191  return false;
192 }
193 
195 {
196  _drive &= 0xff; //Only lowerpart (Ultimate domain)
197  for (Bit16u i=0; i<GetNumDrives(); i++) if (dinfo[i].drive==_drive) return (Bit8u)i;
198  return 0xff;
199 }
200 
202 {
204  for (Bit16u i=0; i<GetNumDrives(); i++) {
205  if (dinfo[i].drive == _drive) {
206  idx = i;
207  break;
208  }
209  }
210 
211  if (idx == MSCDEX_MAX_DRIVES || (idx!=0 && idx!=GetNumDrives()-1)) return 0;
212  delete (cdrom)[idx];
213  if (idx==0) {
214  for (Bit16u i=0; i<GetNumDrives(); i++) {
215  if (i == MSCDEX_MAX_DRIVES-1) {
216  cdrom[i] = 0;
217  memset(&dinfo[i],0,sizeof(TDriveInfo));
218  } else {
219  dinfo[i] = dinfo[i+1];
220  cdrom[i] = cdrom[i+1];
221  }
222  }
223  } else {
224  cdrom[idx] = 0;
225  memset(&dinfo[idx],0,sizeof(TDriveInfo));
226  }
227  numDrives--;
228 
229  if (GetNumDrives() == 0) {
232  devHeader.SetStrategy(off+4); // point to the RETF (To deactivate MSCDEX)
233  devHeader.SetInterrupt(off+4); // point to the RETF (To deactivate MSCDEX)
234  devHeader.SetDriveLetter(0);
235  } else if (idx==0) {
237  devHeader.SetDriveLetter(GetFirstDrive()+1);
238  }
239  return 1;
240 }
241 
242 int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit)
243 {
244  subUnit = 0;
245  if ((Bitu)GetNumDrives()+1>=MSCDEX_MAX_DRIVES) return 4;
246  if (GetNumDrives()) {
247  // Error check, driveletter have to be in a row
248  if (dinfo[0].drive-1!=_drive && dinfo[numDrives-1].drive+1!=_drive)
249  return 1;
250  }
251  // Set return type to ok
252  int result = 0;
253  // Get Mounttype and init needed cdrom interface
254  switch (CDROM_GetMountType(physicalPath,forceCD)) {
255  case 0x00: {
256  LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting physical cdrom: %s" ,physicalPath);
257 #if defined (WIN32)
258  // Check OS
259  OSVERSIONINFO osi;
260  osi.dwOSVersionInfoSize = sizeof(osi);
261  GetVersionEx(&osi);
262  if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) {
263  // only WIN NT/200/XP
265  cdrom[numDrives] = new CDROM_Interface_Ioctl(CDROM_Interface_Ioctl::CDIOCTL_CDA_DIO);
266  LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface.");
267  break;
268  }
270  cdrom[numDrives] = new CDROM_Interface_Ioctl(CDROM_Interface_Ioctl::CDIOCTL_CDA_DX);
271  LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface (digital audio extraction).");
272  break;
273  }
275  cdrom[numDrives] = new CDROM_Interface_Ioctl(CDROM_Interface_Ioctl::CDIOCTL_CDA_MCI);
276  LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface (media control interface).");
277  break;
278  }
279  }
281  // all Wins - ASPI
282  cdrom[numDrives] = new CDROM_Interface_Aspi();
283  LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: ASPI Interface.");
284  break;
285  }
286 #endif
287 #if defined (LINUX) || defined(OS2)
288  // Always use IOCTL in Linux or OS/2
289  cdrom[numDrives] = new CDROM_Interface_Ioctl();
290  LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface.");
291 #else
292  // Default case windows and other oses
294  LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface.");
295 #endif
296  } break;
297  case 0x01: // iso cdrom interface
298  LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting iso file as cdrom: %s", physicalPath);
300  break;
301  case 0x02: // fake cdrom interface (directories)
303  LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting directory as cdrom: %s",physicalPath);
304  LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: You wont have full MSCDEX support !");
305  result = 5;
306  break;
307  default : // weird result
308  return 6;
309  };
310 
311  if (!cdrom[numDrives]->SetDevice(physicalPath,forceCD)) {
312 // delete cdrom[numDrives] ; mount seems to delete it
313  return 3;
314  }
315 
316 
317  if (rootDriverHeaderSeg==0) {
318 
319  Bit16u driverSize = sizeof(DOS_DeviceHeader::sDeviceHeader) + 10; // 10 = Bytes for 3 callbacks
320 
321  // Create Device Header
322  Bit16u seg = DOS_GetMemory(driverSize/16+((driverSize%16)>0));
323  DOS_DeviceHeader devHeader(PhysMake(seg,0));
324  devHeader.SetNextDeviceHeader (0xFFFFFFFF);
325  devHeader.SetAttribute(0xc800);
326  devHeader.SetDriveLetter (_drive+1);
327  devHeader.SetNumSubUnits (1);
328  devHeader.SetName ("MSCD001 ");
329 
330  //Link it in the device chain
332  Bit16u segm = (Bit16u)(start>>16);
333  Bit16u offm = (Bit16u)(start&0xFFFF);
334  while(start != 0xFFFFFFFF) {
335  segm = (Bit16u)(start>>16);
336  offm = (Bit16u)(start&0xFFFF);
337  start = real_readd(segm,offm);
338  }
339  real_writed(segm,offm,seg<<16);
340 
341  // Create Callback Strategy
343  Bit16u call_strategy=(Bit16u)CALLBACK_Allocate();
345  real_writeb(seg,off+0,(Bit8u)0xFE); //GRP 4
346  real_writeb(seg,off+1,(Bit8u)0x38); //Extra Callback instruction
347  real_writew(seg,off+2,call_strategy); //The immediate word
348  real_writeb(seg,off+4,(Bit8u)0xCB); //A RETF Instruction
349  devHeader.SetStrategy(off);
350 
351  // Create Callback Interrupt
352  off += 5;
353  Bit16u call_interrupt=(Bit16u)CALLBACK_Allocate();
355  real_writeb(seg,off+0,(Bit8u)0xFE); //GRP 4
356  real_writeb(seg,off+1,(Bit8u)0x38); //Extra Callback instruction
357  real_writew(seg,off+2,call_interrupt); //The immediate word
358  real_writeb(seg,off+4,(Bit8u)0xCB); //A RETF Instruction
359  devHeader.SetInterrupt(off);
360 
361  rootDriverHeaderSeg = seg;
362 
363  } else if (GetNumDrives() == 0) {
366  devHeader.SetDriveLetter(_drive+1);
367  devHeader.SetStrategy(off);
368  devHeader.SetInterrupt(off+5);
369  }
370 
371  subUnit = (Bit8u)numDrives;
372  // Set drive
374  devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1);
375 
376  if (dinfo[0].drive-1==_drive) {
377  CDROM_Interface *_cdrom = cdrom[numDrives];
378  for (Bit16u i=GetNumDrives(); i>0; i--) {
379  dinfo[i] = dinfo[i-1];
380  cdrom[i] = cdrom[i-1];
381  }
382  cdrom[0] = _cdrom;
383  dinfo[0].drive = (Bit8u)_drive;
384  dinfo[0].physDrive = (Bit8u)toupper(physicalPath[0]);
385  } else {
386  dinfo[numDrives].drive = (Bit8u)_drive;
387  dinfo[numDrives].physDrive = (Bit8u)toupper(physicalPath[0]);
388  }
389  numDrives++;
390  // stop audio
391  StopAudio(subUnit);
392  return result;
393 }
394 
396  return (GetSubUnit(drive) != 0xff);
397 }
398 
399 void CMscdex::ReplaceDrive(CDROM_Interface* newCdrom, Bit8u subUnit) {
400  if (cdrom[subUnit] != NULL) {
401  StopAudio(subUnit);
402  delete cdrom[subUnit];
403  }
404  cdrom[subUnit] = newCdrom;
405 }
406 
408  if (defaultBufSeg==0) {
409  Bit16u size = (2352*2+15)/16;
411  };
412  return PhysMake(defaultBufSeg,2352);
413 }
414 
416  if (defaultBufSeg==0) {
417  Bit16u size = (2352*2+15)/16;
419  };
420  return PhysMake(defaultBufSeg,0);
421 }
422 
424  for (Bit16u i=0; i<GetNumDrives(); i++) {
425  mem_writeb(data ,(Bit8u)i); // subunit
427  data+=5;
428  };
429 }
430 
431 bool CMscdex::GetCDInfo(Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut)
432 {
433  if (subUnit>=numDrives) return false;
434  int tr1i,tr2i;
435  // Assume Media change
436  cdrom[subUnit]->InitNewMedia();
437  dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioTracks(tr1i,tr2i,leadOut);
438  if (!dinfo[subUnit].lastResult) {
439  tr1 = tr2 = 0;
440  memset(&leadOut,0,sizeof(leadOut));
441  } else {
442  tr1 = (Bit8u) tr1i;
443  tr2 = (Bit8u) tr2i;
444  }
445  return dinfo[subUnit].lastResult;
446 }
447 
448 bool CMscdex::GetTrackInfo(Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start)
449 {
450  if (subUnit>=numDrives) return false;
451  dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioTrackInfo(track,start,attr);
452  if (!dinfo[subUnit].lastResult) {
453  attr = 0;
454  memset(&start,0,sizeof(start));
455  };
456  return dinfo[subUnit].lastResult;
457 }
458 
460 {
461  if (subUnit>=numDrives) return false;
462  // If value from last stop is used, this is meant as a resume
463  // better start using resume command
464  if (dinfo[subUnit].audioPaused && (sector==dinfo[subUnit].audioStart)) {
465  dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(true);
466  } else
467  dinfo[subUnit].lastResult = cdrom[subUnit]->PlayAudioSector(sector,length);
468 
469  if (dinfo[subUnit].lastResult) {
470  dinfo[subUnit].audioPlay = true;
471  dinfo[subUnit].audioPaused = false;
472  dinfo[subUnit].audioStart = sector;
473  dinfo[subUnit].audioEnd = length;
474  };
475  return dinfo[subUnit].lastResult;
476 }
477 
479 {
480  if (subUnit>=numDrives) return false;
481  Bit8u min = (Bit8u)(start>>16) & 0xFF;
482  Bit8u sec = (Bit8u)(start>> 8) & 0xFF;
483  Bit8u fr = (Bit8u)(start>> 0) & 0xFF;
484  Bit32u sector = min*60*75+sec*75+fr - 150;
485  return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,sector,length);
486 }
487 
488 bool CMscdex::GetSubChannelData(Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs)
489 {
490  if (subUnit>=numDrives) return false;
491  dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioSub(attr,track,index,rel,abs);
492  if (!dinfo[subUnit].lastResult) {
493  attr = track = index = 0;
494  memset(&rel,0,sizeof(rel));
495  memset(&abs,0,sizeof(abs));
496  };
497  return dinfo[subUnit].lastResult;
498 }
499 
500 bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end)
501 {
502  if (subUnit>=numDrives) return false;
503  dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioStatus(playing,pause);
504  if (dinfo[subUnit].lastResult) {
505  // Start
506  Bit32u addr = dinfo[subUnit].audioStart + 150;
507  start.fr = (Bit8u)(addr%75); addr/=75;
508  start.sec = (Bit8u)(addr%60);
509  start.min = (Bit8u)(addr/60);
510  // End
511  addr = dinfo[subUnit].audioEnd + 150;
512  end.fr = (Bit8u)(addr%75); addr/=75;
513  end.sec = (Bit8u)(addr%60);
514  end.min = (Bit8u)(addr/60);
515  } else {
516  playing = false;
517  pause = false;
518  memset(&start,0,sizeof(start));
519  memset(&end,0,sizeof(end));
520  };
521 
522  return dinfo[subUnit].lastResult;
523 }
524 
526 {
527  if (subUnit>=numDrives) return false;
528  if (dinfo[subUnit].audioPlay) dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(false);
529  else dinfo[subUnit].lastResult = cdrom[subUnit]->StopAudio();
530 
531  if (dinfo[subUnit].lastResult) {
532  if (dinfo[subUnit].audioPlay) {
533  TMSF pos;
534  GetCurrentPos(subUnit,pos);
535  dinfo[subUnit].audioStart = pos.min*60*75+pos.sec*75+pos.fr - 150;
536  dinfo[subUnit].audioPaused = true;
537  } else {
538  dinfo[subUnit].audioPaused = false;
539  dinfo[subUnit].audioStart = 0;
540  dinfo[subUnit].audioEnd = 0;
541  };
542  dinfo[subUnit].audioPlay = false;
543  };
544  return dinfo[subUnit].lastResult;
545 }
546 
548  if (subUnit>=numDrives) return false;
549  return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,dinfo[subUnit].audioStart,dinfo[subUnit].audioEnd);
550 }
551 
553  if (subUnit>=numDrives) return false;
554  Bit8u tr1,tr2;
555  TMSF leadOut;
556  dinfo[subUnit].lastResult = GetCDInfo(subUnit,tr1,tr2,leadOut);
557  if (dinfo[subUnit].lastResult) return (leadOut.min*60*75)+(leadOut.sec*75)+leadOut.fr;
558  return 0;
559 }
560 
562  Bit8u subunit = GetSubUnit(drive);
563 /* if (subunit>=numDrives) {
564  error=MSCDEX_ERROR_UNKNOWN_DRIVE;
565  return false;
566  } */
567  if (!ReadSectors(subunit,false,16+volume,1,data)) {
569  return false;
570  }
571  char id[5];
572  MEM_BlockRead(data + 1, id, 5);
573  if (strncmp("CD001",id, 5)!=0) {
574  error = MSCDEX_ERROR_BAD_FORMAT;
575  return false;
576  }
578  error = (type == 1) ? 1 : (type == 0xFF) ? 0xFF : 0;
579  return true;
580 }
581 
582 bool CMscdex::GetVolumeName(Bit8u subUnit, char* data) {
583  if (subUnit>=numDrives) return false;
584  Bit16u drive = dinfo[subUnit].drive;
585 
586  Bit16u error;
587  bool success = false;
588  PhysPt ptoc = GetTempBuffer();
589  success = ReadVTOC(drive,0x00,ptoc,error);
590  if (success) {
591  MEM_StrCopy(ptoc+40,data,31);
592  data[31] = 0;
593  rtrim(data);
594  };
595 
596  return success;
597 }
598 
600  Bit16u error;
601  bool success = false;
602  PhysPt ptoc = GetTempBuffer();
603  success = ReadVTOC(drive,0x00,ptoc,error);
604  if (success) {
605  MEM_BlockCopy(data,ptoc+702,37);
606  mem_writeb(data+37,0);
607  };
608  return success;
609 }
610 
612  Bit16u error;
613  bool success = false;
614  PhysPt ptoc = GetTempBuffer();
615  success = ReadVTOC(drive,0x00,ptoc,error);
616  if (success) {
617  MEM_BlockCopy(data,ptoc+739,37);
618  mem_writeb(data+37,0);
619  };
620  return success;
621 }
622 
624  Bit16u error;
625  bool success = false;
626  PhysPt ptoc = GetTempBuffer();
627  success = ReadVTOC(drive,0x00,ptoc,error);
628  if (success) {
629  MEM_BlockCopy(data,ptoc+776,37);
630  mem_writeb(data+37,0);
631  };
632  return success;
633 }
634 
635 bool CMscdex::GetUPC(Bit8u subUnit, Bit8u& attr, char* upc)
636 {
637  if (subUnit>=numDrives) return false;
638  return dinfo[subUnit].lastResult = cdrom[subUnit]->GetUPC(attr,&upc[0]);
639 }
640 
641 bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data) {
642  if (subUnit>=numDrives) return false;
643  if ((4*num*2048+5) < CPU_Cycles) CPU_Cycles -= 4*num*2048;
644  else CPU_Cycles = 5;
645  dinfo[subUnit].lastResult = cdrom[subUnit]->ReadSectors(data,raw,sector,num);
646  return dinfo[subUnit].lastResult;
647 }
648 
649 bool CMscdex::ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u start, Bit16u num, PhysPt data) {
650  if (subUnit>=numDrives) return false;
651  Bit8u min = (Bit8u)(start>>16) & 0xFF;
652  Bit8u sec = (Bit8u)(start>> 8) & 0xFF;
653  Bit8u fr = (Bit8u)(start>> 0) & 0xFF;
654  Bit32u sector = min*60*75+sec*75+fr - 150;
655  return ReadSectors(subUnit,raw,sector,num,data);
656 }
657 
658 // Called from INT 2F
660  return ReadSectors(GetSubUnit(drive),false,sector,num,data);
661 }
662 
663 bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u& error)
664 {
665  char volumeID[6] = {0};
666  char searchName[256];
667  char entryName[256];
668  bool foundComplete = false;
669  bool foundName;
670  char* useName = 0;
671  Bitu entryLength,nameLength;
672  // clear error
673  error = 0;
674  MEM_StrCopy(pathname+1,searchName,mem_readb(pathname));
675  upcase(searchName);
676  char* searchPos = searchName;
677 
678  //strip of tailing . (XCOM APOCALYPSE)
679  size_t searchlen = strlen(searchName);
680  if (searchlen > 1 && strcmp(searchName,".."))
681  if (searchName[searchlen-1] =='.') searchName[searchlen-1] = 0;
682 
683  //LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Find : %s",searchName);
684  // read vtoc
685  PhysPt defBuffer = GetDefaultBuffer();
686  if (!ReadSectors(GetSubUnit(drive),false,16,1,defBuffer)) return false;
687  // TODO: has to be iso 9960
688  MEM_StrCopy(defBuffer+1,volumeID,5); volumeID[5] = 0;
689  bool iso = (strcmp("CD001",volumeID)==0);
690  if (!iso) E_Exit("MSCDEX: GetDirEntry: Not an ISO 9960 CD.");
691  // get directory position
692  Bitu dirEntrySector = mem_readd(defBuffer+156+2);
693  Bits dirSize = mem_readd(defBuffer+156+10);
694  Bitu index;
695  while (dirSize>0) {
696  index = 0;
697  if (!ReadSectors(GetSubUnit(drive),false,dirEntrySector,1,defBuffer)) return false;
698  // Get string part
699  foundName = false;
700  if (searchPos) {
701  useName = searchPos;
702  searchPos = strchr(searchPos,'\\');
703  }
704 
705  if (searchPos) { *searchPos = 0; searchPos++; }
706  else foundComplete = true;
707 
708  do {
709  entryLength = mem_readb(defBuffer+index);
710  if (entryLength==0) break;
711  nameLength = mem_readb(defBuffer+index+32);
712  MEM_StrCopy(defBuffer+index+33,entryName,nameLength);
713  if (strcmp(entryName,useName)==0) {
714  //LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Found : %s",useName);
715  foundName = true;
716  break;
717  }
718  /* Xcom Apocalipse searches for MUSIC. and expects to find MUSIC;1
719  * All Files on the CDROM are of the kind blah;1
720  */
721  char* longername = strchr(entryName,';');
722  if(longername) {
723  *longername = 0;
724  if (strcmp(entryName,useName)==0) {
725  //LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Get DirEntry : Found : %s",useName);
726  foundName = true;
727  break;
728  }
729  }
730  index += entryLength;
731  } while (index+33<=2048);
732 
733  if (foundName) {
734  if (foundComplete) {
735  if (copyFlag) {
736  LOG(LOG_MISC,LOG_WARN)("MSCDEX: GetDirEntry: Copyflag structure not entirely accurate maybe");
737  Bit8u readBuf[256];
738  Bit8u writeBuf[256];
739  if (entryLength > 256)
740  return false;
741  MEM_BlockRead( defBuffer+index, readBuf, entryLength );
742  writeBuf[0] = readBuf[1]; // 00h BYTE length of XAR in Logical Block Numbers
743  memcpy( &writeBuf[1], &readBuf[0x2], 4); // 01h DWORD Logical Block Number of file start
744  writeBuf[5] = 0;writeBuf[6] = 8; // 05h WORD size of disk in logical blocks
745  memcpy( &writeBuf[7], &readBuf[0xa], 4); // 07h DWORD file length in bytes
746  memcpy( &writeBuf[0xb], &readBuf[0x12], 7); // 0bh DWORD date and time
747  writeBuf[0x12] = readBuf[0x19]; // 12h BYTE bit flags
748  writeBuf[0x13] = readBuf[0x1a]; // 13h BYTE interleave size
749  writeBuf[0x14] = readBuf[0x1b]; // 14h BYTE interleave skip factor
750  memcpy( &writeBuf[0x15], &readBuf[0x1c], 2); // 15h WORD volume set sequence number
751  writeBuf[0x17] = readBuf[0x20];
752  memcpy( &writeBuf[0x18], &readBuf[21], readBuf[0x20] <= 38 ? readBuf[0x20] : 38 );
753  MEM_BlockWrite( buffer, writeBuf, 0x18 + 40 );
754  } else {
755  // Direct copy
756  MEM_BlockCopy(buffer,defBuffer+index,entryLength);
757  }
758  error = iso ? 1:0;
759  return true;
760  }
761  // change directory
762  dirEntrySector = mem_readd(defBuffer+index+2);
763  dirSize = mem_readd(defBuffer+index+10);
764  } else {
765  // continue search in next sector
766  dirSize -= 2048;
767  dirEntrySector++;
768  }
769  };
770  error = 2; // file not found
771  return false; // not found
772 }
773 
775 {
776  if (subUnit>=numDrives) return false;
777  TMSF rel;
778  Bit8u attr,track,index;
779  dinfo[subUnit].lastResult = GetSubChannelData(subUnit, attr, track, index, rel, pos);
780  if (!dinfo[subUnit].lastResult) memset(&pos,0,sizeof(pos));
781  return dinfo[subUnit].lastResult;
782 }
783 
784 bool CMscdex::GetMediaStatus(Bit8u subUnit, bool& media, bool& changed, bool& trayOpen)
785 {
786  if (subUnit>=numDrives) return false;
787  dinfo[subUnit].lastResult = cdrom[subUnit]->GetMediaTrayStatus(media,changed,trayOpen);
788  return dinfo[subUnit].lastResult;
789 }
790 
792 {
793  if (subUnit>=numDrives) return false;
794  bool media,changed,trayOpen;
795 
796  dinfo[subUnit].lastResult = GetMediaStatus(subUnit,media,changed,trayOpen);
797  Bit32u status = (trayOpen << 0) | // Drive is open ?
798  (dinfo[subUnit].locked << 1) | // Drive is locked ?
799  (1<<2) | // raw + cooked sectors
800  (1<<4) | // Can read sudio
801  (1<<9) | // Red book & HSG
802  ((!media) << 11); // Drive is empty ?
803  return status;
804 }
805 
807 {
808  if (subUnit>=numDrives) return false;
809 /* bool media,changed,open,result;
810  result = GetMediaStatus(subUnit,media,changed,open);
811  status = changed ? 0xFF : 0x01;
812  return result; */
813  status = getSwapRequest() ? 0xFF : 0x01;
814  return true;
815 }
816 
817 bool CMscdex::LoadUnloadMedia(Bit8u subUnit, bool unload)
818 {
819  if (subUnit>=numDrives) return false;
820  dinfo[subUnit].lastResult = cdrom[subUnit]->LoadUnloadMedia(unload);
821  return dinfo[subUnit].lastResult;
822 }
823 
825 {
826  Bit8u subUnit = GetSubUnit(drive);
827  if (subUnit>=numDrives) return false;
828  // Get SubUnit
829  mem_writeb(data+1,subUnit);
830  // Call Strategy / Interrupt
833  return true;
834 }
835 
837 {
838  if (subUnit>=numDrives) return REQUEST_STATUS_ERROR | 0x02; // error : Drive not ready
839 
840  if (dinfo[subUnit].lastResult) status |= REQUEST_STATUS_DONE; // ok
841  else status |= REQUEST_STATUS_ERROR;
842 
843  if (dinfo[subUnit].audioPlay) {
844  // Check if audio is still playing....
845  TMSF start,end;
846  bool playing,pause;
847  if (GetAudioStatus(subUnit,playing,pause,start,end)) {
848  dinfo[subUnit].audioPlay = playing;
849  } else
850  dinfo[subUnit].audioPlay = false;
851 
852  status |= (dinfo[subUnit].audioPlay<<9);
853  }
854  dinfo[subUnit].lastResult = true;
855  return status;
856 }
857 
859  if (subUnit<numDrives) {
860  // Reopen new media
861  cdrom[subUnit]->InitNewMedia();
862  }
863 }
864 
865 static CMscdex* mscdex = 0;
867 
869  Bitu ioctl_fct = mem_readb(buffer);
870  MSCDEX_LOG("MSCDEX: IOCTL INPUT Subfunction %02X",ioctl_fct);
871  switch (ioctl_fct) {
872  case 0x00 : /* Get Device Header address */
874  break;
875  case 0x01 :{/* Get current position */
876  TMSF pos;
877  mscdex->GetCurrentPos(drive_unit,pos);
878  Bit8u addr_mode = mem_readb(buffer+1);
879  if (addr_mode==0) { // HSG
880  Bit32u frames=MSF_TO_FRAMES(pos.min, pos.sec, pos.fr);
881  if (frames<150) MSCDEX_LOG("MSCDEX: Get position: invalid position %d:%d:%d", pos.min, pos.sec, pos.fr);
882  else frames-=150;
883  mem_writed(buffer+2,frames);
884  } else if (addr_mode==1) { // Red book
885  mem_writeb(buffer+2,pos.fr);
886  mem_writeb(buffer+3,pos.sec);
887  mem_writeb(buffer+4,pos.min);
888  mem_writeb(buffer+5,0x00);
889  } else {
890  MSCDEX_LOG("MSCDEX: Get position: invalid address mode %x",addr_mode);
891  return 0x03; // invalid function
892  }
893  }break;
894  case 0x06 : /* Get Device status */
895  mem_writed(buffer+1,mscdex->GetDeviceStatus(drive_unit));
896  break;
897  case 0x07 : /* Get sector size */
898  if (mem_readb(buffer+1)==0) mem_writed(buffer+2,2048);
899  else if (mem_readb(buffer+1)==1) mem_writed(buffer+2,2352);
900  else return 0x03; // invalid function
901  break;
902  case 0x08 : /* Get size of current volume */
903  mem_writed(buffer+1,mscdex->GetVolumeSize(drive_unit));
904  break;
905  case 0x09 : /* Media change ? */
906  Bit8u status;
907  if (!mscdex->GetMediaStatus(drive_unit,status)) {
908  status = 0; // state unknown
909  }
911  break;
912  case 0x0A : /* Get Audio Disk info */
913  Bit8u tr1,tr2; TMSF leadOut;
914  if (!mscdex->GetCDInfo(drive_unit,tr1,tr2,leadOut)) return 0x05;
915  mem_writeb(buffer+1,tr1);
916  mem_writeb(buffer+2,tr2);
917  mem_writeb(buffer+3,leadOut.fr);
918  mem_writeb(buffer+4,leadOut.sec);
919  mem_writeb(buffer+5,leadOut.min);
920  mem_writeb(buffer+6,0x00);
921  break;
922  case 0x0B :{/* Audio Track Info */
923  Bit8u attr; TMSF start;
924  Bit8u track = mem_readb(buffer+1);
925  mscdex->GetTrackInfo(drive_unit,track,attr,start);
926  mem_writeb(buffer+2,start.fr);
927  mem_writeb(buffer+3,start.sec);
928  mem_writeb(buffer+4,start.min);
929  mem_writeb(buffer+5,0x00);
931  break; };
932  case 0x0C :{/* Get Audio Sub Channel data */
933  Bit8u attr,track,index;
934  TMSF abs,rel;
935  mscdex->GetSubChannelData(drive_unit,attr,track,index,rel,abs);
937  mem_writeb(buffer+2,track);
938  mem_writeb(buffer+3,index);
939  mem_writeb(buffer+4,rel.min);
940  mem_writeb(buffer+5,rel.sec);
941  mem_writeb(buffer+6,rel.fr);
942  mem_writeb(buffer+7,0x00);
943  mem_writeb(buffer+8,abs.min);
944  mem_writeb(buffer+9,abs.sec);
945  mem_writeb(buffer+10,abs.fr);
946  break;
947  };
948  case 0x0E :{ /* Get UPC */
949  Bit8u attr; char upc[8];
950  mscdex->GetUPC(drive_unit,attr,&upc[0]);
952  for (int i=0; i<7; i++) mem_writeb(buffer+2+i,upc[i]);
953  mem_writeb(buffer+9,0x00);
954  break;
955  };
956  case 0x0F :{ /* Get Audio Status */
957  bool playing,pause;
958  TMSF resStart,resEnd;
959  mscdex->GetAudioStatus(drive_unit,playing,pause,resStart,resEnd);
961  mem_writeb(buffer+3,resStart.min);
962  mem_writeb(buffer+4,resStart.sec);
963  mem_writeb(buffer+5,resStart.fr);
964  mem_writeb(buffer+6,0x00);
965  mem_writeb(buffer+7,resEnd.min);
966  mem_writeb(buffer+8,resEnd.sec);
967  mem_writeb(buffer+9,resEnd.fr);
968  mem_writeb(buffer+10,0x00);
969  break;
970  };
971  default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL INPUT Subfunction %02X",ioctl_fct);
972  return 0x03; // invalid function
973  }
974  return 0x00; // success
975 }
976 
978  Bitu ioctl_fct = mem_readb(buffer);
979 // MSCDEX_LOG("MSCDEX: IOCTL OUTPUT Subfunction %02X",ioctl_fct);
980  switch (ioctl_fct) {
981  case 0x00 : // Unload /eject media
982  if (!mscdex->LoadUnloadMedia(drive_unit,true)) return 0x02;
983  break;
984  case 0x03: //Audio Channel control
985  MSCDEX_LOG("MSCDEX: Audio Channel Control used. Not handled. Faking succes!");
986  case 0x01 : // (un)Lock door
987  // do nothing -> report as success
988  break;
989  case 0x02 : // Reset Drive
990  LOG(LOG_MISC,LOG_WARN)("cdromDrive reset");
991  if (!mscdex->StopAudio(drive_unit)) return 0x02;
992  break;
993  case 0x05 : // load media
994  if (!mscdex->LoadUnloadMedia(drive_unit,false)) return 0x02;
995  default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported IOCTL OUTPUT Subfunction %02X",ioctl_fct);
996  return 0x03; // invalid function
997  }
998  return 0x00; // success
999 }
1000 
1003 // MSCDEX_LOG("MSCDEX: Device Strategy Routine called, request header at %x",curReqheaderPtr);
1004  return CBRET_NONE;
1005 }
1006 
1008  if (curReqheaderPtr==0) {
1009  MSCDEX_LOG("MSCDEX: invalid call to interrupt handler");
1010  return CBRET_NONE;
1011  }
1012  Bit8u subUnit = mem_readb(curReqheaderPtr+1);
1013  Bit8u funcNr = mem_readb(curReqheaderPtr+2);
1014  Bit16u errcode = 0;
1015  PhysPt buffer = 0;
1016 
1017  MSCDEX_LOG("MSCDEX: Driver Function %02X",funcNr);
1018 
1019  if ((funcNr==0x03) || (funcNr==0x0c) || (funcNr==0x80) || (funcNr==0x82)) {
1021  }
1022 
1023  switch (funcNr) {
1024  case 0x03 : { /* IOCTL INPUT */
1025  Bit16u error=MSCDEX_IOCTL_Input(buffer,subUnit);
1026  if (error) errcode = error;
1027  break;
1028  };
1029  case 0x0C : { /* IOCTL OUTPUT */
1030  Bit16u error=MSCDEX_IOCTL_Optput(buffer,subUnit);
1031  if (error) errcode = error;
1032  break;
1033  };
1034  case 0x0D : // device open
1035  case 0x0E : // device close - dont care :)
1036  break;
1037  case 0x80 : // Read long
1038  case 0x82 : { // Read long prefetch -> both the same here :)
1039  Bit32u start = mem_readd(curReqheaderPtr+0x14);
1040  Bit16u len = mem_readw(curReqheaderPtr+0x12);
1041  bool raw = (mem_readb(curReqheaderPtr+0x18)==1);
1042  if (mem_readb(curReqheaderPtr+0x0D)==0x00) // HSG
1043  mscdex->ReadSectors(subUnit,raw,start,len,buffer);
1044  else
1045  mscdex->ReadSectorsMSF(subUnit,raw,start,len,buffer);
1046  break;
1047  };
1048  case 0x83 : // Seek - dont care :)
1049  break;
1050  case 0x84 : { /* Play Audio Sectors */
1051  Bit32u start = mem_readd(curReqheaderPtr+0x0E);
1052  Bit32u len = mem_readd(curReqheaderPtr+0x12);
1053  if (mem_readb(curReqheaderPtr+0x0D)==0x00) // HSG
1054  mscdex->PlayAudioSector(subUnit,start,len);
1055  else // RED BOOK
1056  mscdex->PlayAudioMSF(subUnit,start,len);
1057  break;
1058  };
1059  case 0x85 : /* Stop Audio */
1060  mscdex->StopAudio(subUnit);
1061  break;
1062  case 0x88 : /* Resume Audio */
1063  mscdex->ResumeAudio(subUnit);
1064  break;
1065  default : LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unsupported Driver Request %02X",funcNr);
1066  break;
1067 
1068  };
1069 
1070  // Set Statusword
1071  mem_writew(curReqheaderPtr+3,mscdex->GetStatusWord(subUnit,errcode));
1072  MSCDEX_LOG("MSCDEX: Status : %04X",mem_readw(curReqheaderPtr+3));
1073  return CBRET_NONE;
1074 }
1075 
1076 static bool MSCDEX_Handler(void) {
1077  if(reg_ah == 0x11) {
1078  if(reg_al == 0x00) {
1079  PhysPt check = PhysMake(SegValue(ss),reg_sp);
1080  if(mem_readw(check+6) == 0xDADA) {
1081  //MSCDEX sets word on stack to ADAD if it DADA on entry.
1082  mem_writew(check+6,0xADAD);
1083  }
1084  reg_al = 0xff;
1085  return true;
1086  } else {
1087  LOG(LOG_MISC,LOG_ERROR)("NETWORK REDIRECTOR USED!!!");
1088  reg_ax = 0x49;//NETWERK SOFTWARE NOT INSTALLED
1089  CALLBACK_SCF(true);
1090  return true;
1091  }
1092  }
1093 
1094  if (reg_ah!=0x15) return false; // not handled here, continue chain
1095 
1097  MSCDEX_LOG("MSCDEX: INT 2F %04X BX= %04X CX=%04X",reg_ax,reg_bx,reg_cx);
1098  switch (reg_ax) {
1099 
1100  case 0x1500: /* Install check */
1101  reg_bx = mscdex->GetNumDrives();
1102  if (reg_bx>0) reg_cx = mscdex->GetFirstDrive();
1103  reg_al = 0xff;
1104  return true;
1105  case 0x1501: /* Get cdrom driver info */
1107  return true;
1108  case 0x1502: /* Get Copyright filename */
1110  CALLBACK_SCF(false);
1111  } else {
1113  CALLBACK_SCF(true);
1114  };
1115  return true;
1116  case 0x1503: /* Get Abstract filename */
1118  CALLBACK_SCF(false);
1119  } else {
1121  CALLBACK_SCF(true);
1122  };
1123  return true;
1124  case 0x1504: /* Get Documentation filename */
1126  CALLBACK_SCF(false);
1127  } else {
1129  CALLBACK_SCF(true);
1130  };
1131  return true;
1132  case 0x1505: { // read vtoc
1133  Bit16u error = 0;
1134  if (mscdex->ReadVTOC(reg_cx,reg_dx,data,error)) {
1135 // reg_ax = error; // return code
1136  CALLBACK_SCF(false);
1137  } else {
1138  reg_ax = error;
1139  CALLBACK_SCF(true);
1140  };
1141  };
1142  return true;
1143  case 0x1508: { // read sectors
1144  Bit32u sector = (reg_si<<16)+reg_di;
1145  if (mscdex->ReadSectors(reg_cx,sector,reg_dx,data)) {
1146  reg_ax = 0;
1147  CALLBACK_SCF(false);
1148  } else {
1149  // possibly: MSCDEX_ERROR_DRIVE_NOT_READY if sector is beyond total length
1151  CALLBACK_SCF(true);
1152  };
1153  return true;
1154  };
1155  case 0x1509: // write sectors - not supported
1157  CALLBACK_SCF(true);
1158  return true;
1159  case 0x150B: /* Valid CDROM drive ? */
1160  reg_ax = (mscdex->IsValidDrive(reg_cx) ? 0x5ad8 : 0x0000);
1161  reg_bx = 0xADAD;
1162  return true;
1163  case 0x150C: /* Get MSCDEX Version */
1164  reg_bx = mscdex->GetVersion();
1165  return true;
1166  case 0x150D: /* Get drives */
1167  mscdex->GetDrives(data);
1168  return true;
1169  case 0x150E: /* Get/Set Volume Descriptor Preference */
1170  if (mscdex->IsValidDrive(reg_cx)) {
1171  if (reg_bx == 0) {
1172  // get preference
1173  reg_dx = 0x100; // preference?
1174  CALLBACK_SCF(false);
1175  } else if (reg_bx == 1) {
1176  // set preference
1177  if (reg_dh == 1) {
1178  // valid
1179  CALLBACK_SCF(false);
1180  } else {
1182  CALLBACK_SCF(true);
1183  }
1184  } else {
1186  CALLBACK_SCF(true);
1187  }
1188  } else {
1190  CALLBACK_SCF(true);
1191  }
1192  return true;
1193  case 0x150F: { // Get directory entry
1194  Bit16u error;
1195  bool success = mscdex->GetDirectoryEntry(reg_cl,reg_ch&1,data,PhysMake(reg_si,reg_di),error);
1196  reg_ax = error;
1197  CALLBACK_SCF(!success);
1198  }; return true;
1199  case 0x1510: /* Device driver request */
1201  CALLBACK_SCF(false);
1202  } else {
1204  CALLBACK_SCF(true);
1205  }
1206  return true;
1207  };
1208  LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Unknwon call : %04X",reg_ax);
1209  return true;
1210 }
1211 
1212 class device_MSCDEX : public DOS_Device {
1213 public:
1214  device_MSCDEX() { SetName("MSCD001"); }
1215  bool Read (Bit8u * /*data*/,Bit16u * /*size*/) { return false;}
1216  bool Write(Bit8u * /*data*/,Bit16u * /*size*/) {
1217  LOG(LOG_ALL,LOG_NORMAL)("Write to mscdex device");
1218  return false;
1219  }
1220  bool Seek(Bit32u * /*pos*/,Bit32u /*type*/){return false;}
1221  bool Close(){return false;}
1222  Bit16u GetInformation(void){return 0xc880;}
1223  bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode);
1224  bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode);
1225 private:
1226 // Bit8u cache;
1227 };
1228 
1230  if (MSCDEX_IOCTL_Input(bufptr,0)==0) {
1231  *retcode=size;
1232  return true;
1233  }
1234  return false;
1235 }
1236 
1238  if (MSCDEX_IOCTL_Optput(bufptr,0)==0) {
1239  *retcode=size;
1240  return true;
1241  }
1242  return false;
1243 }
1244 
1245 int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit)
1246 {
1247  int result = mscdex->AddDrive(driveLetter-'A',(char*)physicalPath,subUnit);
1248  return result;
1249 }
1250 
1252 {
1253  if(!mscdex) return 0;
1254  return mscdex->RemoveDrive(driveLetter-'A');
1255 }
1256 
1258 {
1259  return mscdex->HasDrive(driveLetter-'A');
1260 }
1261 
1263 {
1264  mscdex->ReplaceDrive(cdrom, subUnit);
1265 }
1266 
1268 {
1269  return mscdex->GetSubUnit(driveLetter-'A');
1270 }
1271 
1272 bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name)
1273 {
1274  return mscdex->GetVolumeName(subUnit,name);
1275 }
1276 
1278 {
1279  static TMSF leadOut[MSCDEX_MAX_DRIVES];
1280 
1281  TMSF leadnew;
1282  Bit8u tr1,tr2;
1283  if (mscdex->GetCDInfo(subUnit,tr1,tr2,leadnew)) {
1284  bool changed = (leadOut[subUnit].min!=leadnew.min) || (leadOut[subUnit].sec!=leadnew.sec) || (leadOut[subUnit].fr!=leadnew.fr);
1285  if (changed) {
1286  leadOut[subUnit].min = leadnew.min;
1287  leadOut[subUnit].sec = leadnew.sec;
1288  leadOut[subUnit].fr = leadnew.fr;
1289  mscdex->InitNewMedia(subUnit);
1290  }
1291  return changed;
1292  };
1293  if (subUnit<MSCDEX_MAX_DRIVES) {
1294  leadOut[subUnit].min = 0;
1295  leadOut[subUnit].sec = 0;
1296  leadOut[subUnit].fr = 0;
1297  }
1298  return true;
1299 }
1300 
1301 void MSCDEX_SetCDInterface(int intNr, int numCD) {
1302  useCdromInterface = intNr;
1303  forceCD = numCD;
1304 }
1305 
1306 void MSCDEX_ShutDown(Section* /*sec*/) {
1307  delete mscdex;
1308  mscdex = 0;
1309  curReqheaderPtr = 0;
1310 }
1311 
1312 void MSCDEX_Init(Section* sec) {
1313  // AddDestroy func
1315  /* Register the mscdex device */
1316  DOS_Device * newdev = new device_MSCDEX();
1317  DOS_AddDevice(newdev);
1318  curReqheaderPtr = 0;
1319  /* Add Multiplexer */
1321  /* Create MSCDEX */
1322  mscdex = new CMscdex;
1323 }
DOS_DeviceHeader
Definition: dos_mscdex.cpp:58
cdrom.h
DOS_AddDevice
void DOS_AddDevice(DOS_Device *adddev)
Definition: dos_devices.cpp:159
pos
Bit8u * pos
Definition: cache.h:61
MSCDEX_HasMediaChanged
bool MSCDEX_HasMediaChanged(Bit8u subUnit)
Definition: dos_mscdex.cpp:1277
CDROM_Interface::InitNewMedia
virtual void InitNewMedia(void)
Definition: cdrom.h:60
CMscdex::GetVersion
Bit16u GetVersion(void)
Definition: dos_mscdex.cpp:96
CDROM_Interface::GetUPC
virtual bool GetUPC(unsigned char &attr, char *upc)=0
MEM_StrCopy
void MEM_StrCopy(PhysPt pt, char *data, Bitu size)
Definition: memory.cpp:199
LOG_ALL
Definition: logging.h:4
CMscdex::ReplaceDrive
void ReplaceDrive(CDROM_Interface *newCdrom, Bit8u subUnit)
Definition: dos_mscdex.cpp:399
DOS_DeviceHeader::sDeviceHeader::driveLetter
Bit8u driveLetter
Definition: dos_mscdex.cpp:83
CMscdex::AddDrive
int AddDrive(Bit16u _drive, char *physicalPath, Bit8u &subUnit)
Definition: dos_mscdex.cpp:242
device_MSCDEX::Seek
bool Seek(Bit32u *, Bit32u)
Definition: dos_mscdex.cpp:1220
MSCDEX_Interrupt_Handler
static Bitu MSCDEX_Interrupt_Handler(void)
Definition: dos_mscdex.cpp:1007
CMscdex::GetAbstractName
bool GetAbstractName(Bit16u drive, PhysPt data)
Definition: dos_mscdex.cpp:611
forceCD
int forceCD
Definition: dos_mscdex.cpp:53
CMscdex::GetTempBuffer
PhysPt GetTempBuffer(void)
Definition: dos_mscdex.cpp:415
dos_infoblock
DOS_InfoBlock dos_infoblock
Definition: dos.cpp:36
SegValue
static INLINE Bit16u SegValue(SegNames index)
Definition: regs.h:100
MSCDEX_VERSION_HIGH
#define MSCDEX_VERSION_HIGH
Definition: dos_mscdex.cpp:37
MSCDEX_RemoveDrive
int MSCDEX_RemoveDrive(char driveLetter)
Definition: dos_mscdex.cpp:1251
CDROM_Interface::PauseAudio
virtual bool PauseAudio(bool resume)=0
data
Bit8u data
Definition: disney.cpp:43
devAttributes
Bit16u devAttributes
Definition: dos_mscdex.cpp:72
DOS_DeviceHeader::sDeviceHeader::nextDeviceHeader
RealPt nextDeviceHeader
Definition: dos_mscdex.cpp:77
CMscdex::SDriveInfo::audioPaused
bool audioPaused
Definition: dos_mscdex.cpp:149
CDROM_USE_IOCTL_MCI
Definition: cdrom.h:26
reg_si
reg_si
Definition: prefix_none.h:225
CMscdex::GetCopyrightName
bool GetCopyrightName(Bit16u drive, PhysPt data)
Definition: dos_mscdex.cpp:599
CMscdex::GetSubChannelData
bool GetSubChannelData(Bit8u subUnit, Bit8u &attr, Bit8u &track, Bit8u &index, TMSF &rel, TMSF &abs)
Definition: dos_mscdex.cpp:488
MSCDEX_ERROR_DRIVE_NOT_READY
#define MSCDEX_ERROR_DRIVE_NOT_READY
Definition: dos_mscdex.cpp:45
DOS_DeviceHeader::sDeviceHeader::devAttributes
Bit16u devAttributes
Definition: dos_mscdex.cpp:78
reg_sp
#define reg_sp
Definition: regs.h:158
device_MSCDEX::Close
bool Close()
Definition: dos_mscdex.cpp:1221
CMscdex::GetStatusWord
Bit16u GetStatusWord(Bit8u subUnit, Bit16u status)
Definition: dos_mscdex.cpp:836
PhysPt
Bit32u PhysPt
Definition: mem.h:26
LOG_MISC
Definition: logging.h:10
real_writew
static INLINE void real_writew(Bit16u seg, Bit16u off, Bit16u val)
Definition: mem.h:177
CMscdex::GetUPC
bool GetUPC(Bit8u subUnit, Bit8u &attr, char *upc)
Definition: dos_mscdex.cpp:635
CMscdex::GetVolumeSize
Bit32u GetVolumeSize(Bit8u subUnit)
Definition: dos_mscdex.cpp:552
CMscdex::CMscdex
CMscdex(void)
Definition: dos_mscdex.cpp:165
DOS_InfoBlock::GetDeviceChain
Bit32u GetDeviceChain(void)
Definition: dos_classes.cpp:165
device_MSCDEX::WriteToControlChannel
bool WriteToControlChannel(PhysPt bufptr, Bit16u size, Bit16u *retcode)
Definition: dos_mscdex.cpp:1237
device_MSCDEX::device_MSCDEX
device_MSCDEX()
Definition: dos_mscdex.cpp:1214
real_readd
static INLINE Bit32u real_readd(Bit16u seg, Bit16u off)
Definition: mem.h:170
CMscdex::cdrom
CDROM_Interface * cdrom[8]
Definition: dos_mscdex.cpp:159
CMscdex::GetDocumentationName
bool GetDocumentationName(Bit16u drive, PhysPt data)
Definition: dos_mscdex.cpp:623
regs.h
MSCDEX_ShutDown
void MSCDEX_ShutDown(Section *)
Definition: dos_mscdex.cpp:1306
CMscdex::StopAudio
bool StopAudio(Bit8u subUnit)
Definition: dos_mscdex.cpp:525
MEM_BlockCopy
void MEM_BlockCopy(PhysPt dest, PhysPt src, Bitu size)
Definition: memory.cpp:195
DOS_File::SetName
virtual void SetName(const char *_name)
Definition: dos_system.h:75
DOS_DeviceHeader::sDeviceHeader::strategy
Bit16u strategy
Definition: dos_mscdex.cpp:79
Section::AddDestroyFunction
void AddDestroyFunction(SectionFunction func, bool canchange=false)
Definition: setup.cpp:720
Bit32u
unsigned long Bit32u
Definition: modules.h:7
drive
Bit8u drive
Definition: dos_inc.h:515
CMscdex::LoadUnloadMedia
bool LoadUnloadMedia(Bit8u subUnit, bool unload)
Definition: dos_mscdex.cpp:817
CDROM_Interface::ReadSectors
virtual bool ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num)=0
PhysMake
static INLINE PhysPt PhysMake(Bit16u seg, Bit16u off)
Definition: mem.h:197
Bit16u
unsigned short Bit16u
Definition: modules.h:5
DOS_DeviceHeader::SetDriveLetter
void SetDriveLetter(Bit8u letter)
Definition: dos_mscdex.cpp:65
CDROM_USE_IOCTL_DIO
Definition: cdrom.h:26
DOS_DeviceHeader::SetInterrupt
void SetInterrupt(Bit16u ofs)
Definition: dos_mscdex.cpp:69
SMSF
Definition: cdrom.h:28
mem_readd
Bit32u mem_readd(PhysPt pt)
Definition: memory.cpp:498
CDROM_Interface::StopAudio
virtual bool StopAudio(void)=0
CDROM_Interface::GetAudioTrackInfo
virtual bool GetAudioTrackInfo(int track, TMSF &start, unsigned char &attr)=0
CMscdex::GetDrives
void GetDrives(PhysPt data)
Definition: dos_mscdex.cpp:182
MSCDEX_GetVolumeName
bool MSCDEX_GetVolumeName(Bit8u subUnit, char *name)
Definition: dos_mscdex.cpp:1272
CDROM_Interface::GetAudioSub
virtual bool GetAudioSub(unsigned char &attr, unsigned char &track, unsigned char &index, TMSF &relPos, TMSF &absPos)=0
callback.h
CMscdex::ReadSectorsMSF
bool ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data)
Definition: dos_mscdex.cpp:649
MSCDEX_MAX_DRIVES
#define MSCDEX_MAX_DRIVES
Definition: dos_mscdex.cpp:39
attr
Bit8u attr
Definition: dos_inc.h:476
CMscdex::GetDefaultBuffer
PhysPt GetDefaultBuffer(void)
Definition: dos_mscdex.cpp:407
CMscdex::InitNewMedia
void InitNewMedia(Bit8u subUnit)
Definition: dos_mscdex.cpp:858
CDROM_Interface_Image
Definition: cdrom.h:108
LOG_ERROR
Definition: logging.h:18
real_writed
static INLINE void real_writed(Bit16u seg, Bit16u off, Bit32u val)
Definition: mem.h:180
CMscdex
Definition: dos_mscdex.cpp:91
upcase
char * upcase(char *str)
Definition: support.cpp:83
CMscdex::PlayAudioMSF
bool PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length)
Definition: dos_mscdex.cpp:478
length
Uint8 length[2]
Definition: ipx.h:70
reg_di
#define reg_di
Definition: regs.h:155
MSCDEX_IOCTL_Optput
static Bit16u MSCDEX_IOCTL_Optput(PhysPt buffer, Bit8u drive_unit)
Definition: dos_mscdex.cpp:977
CPU_Cycles
Bit32s CPU_Cycles
Definition: prefix_66.h:48
mem_writed
void mem_writed(PhysPt pt, Bit32u val)
Definition: memory.cpp:510
CDROM_GetMountType
int CDROM_GetMountType(char *path, int forceCD)
Definition: cdrom.cpp:147
CDROM_Interface::GetAudioTracks
virtual bool GetAudioTracks(int &stTrack, int &end, TMSF &leadOut)=0
DOS_DeviceHeader::SetNumSubUnits
void SetNumSubUnits(Bit8u num)
Definition: dos_mscdex.cpp:66
E_Exit
void E_Exit(const char *format,...)
Definition: support.cpp:174
CMscdex::rootDriverHeaderSeg
Bit16u rootDriverHeaderSeg
Definition: dos_mscdex.cpp:162
LOG_NORMAL
Definition: logging.h:16
reg_dx
reg_dx
Definition: prefix_none.h:226
MSCDEX_AddDrive
int MSCDEX_AddDrive(char driveLetter, const char *physicalPath, Bit8u &subUnit)
Definition: dos_mscdex.cpp:1245
Bit8u
unsigned char Bit8u
Definition: modules.h:3
DOS_DeviceHeader::GetNextDeviceHeader
RealPt GetNextDeviceHeader(void)
Definition: dos_mscdex.cpp:63
reg_ah
reg_ah
Definition: prefix_none.h:595
MSCDEX_IOCTL_Input
static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer, Bit8u drive_unit)
Definition: dos_mscdex.cpp:868
MSCDEX_Handler
static bool MSCDEX_Handler(void)
Definition: dos_mscdex.cpp:1076
CMscdex::HasDrive
bool HasDrive(Bit16u drive)
Definition: dos_mscdex.cpp:395
CDROM_USE_IOCTL_DX
Definition: cdrom.h:26
numSubUnits
Bit8u numSubUnits
Definition: dos_mscdex.cpp:78
CMscdex::GetNumDrives
Bit16u GetNumDrives(void)
Definition: dos_mscdex.cpp:97
mem_readw
Bit16u mem_readw(PhysPt pt)
Definition: memory.cpp:494
rtrim
char * rtrim(char *str)
Definition: support.cpp:71
CMscdex::GetCDInfo
bool GetCDInfo(Bit8u subUnit, Bit8u &tr1, Bit8u &tr2, TMSF &leadOut)
Definition: dos_mscdex.cpp:431
reg_ax
reg_ax
Definition: prefix_none.h:226
status
Bitu status
Definition: midi.cpp:102
CDROM_Interface::GetAudioStatus
virtual bool GetAudioStatus(bool &playing, bool &pause)=0
CDROM_Interface::LoadUnloadMedia
virtual bool LoadUnloadMedia(bool unload)=0
MSCDEX_ERROR_INVALID_FUNCTION
#define MSCDEX_ERROR_INVALID_FUNCTION
Definition: dos_mscdex.cpp:42
LOG
#define LOG(X, Y)
Definition: cpu.cpp:42
CDROM_Interface_SDL
Definition: cdrom.h:63
REQUEST_STATUS_DONE
#define REQUEST_STATUS_DONE
Definition: dos_mscdex.cpp:48
mem_writew
void mem_writew(PhysPt pt, Bit16u val)
Definition: memory.cpp:506
CMscdex::GetAudioStatus
bool GetAudioStatus(Bit8u subUnit, bool &playing, bool &pause, TMSF &start, TMSF &end)
Definition: dos_mscdex.cpp:500
useCdromInterface
int useCdromInterface
Definition: dos_mscdex.cpp:52
device_MSCDEX::ReadFromControlChannel
bool ReadFromControlChannel(PhysPt bufptr, Bit16u size, Bit16u *retcode)
Definition: dos_mscdex.cpp:1229
MSCDEX_LOG
#define MSCDEX_LOG
Definition: dos_mscdex.cpp:34
CDROM_Interface::PlayAudioSector
virtual bool PlayAudioSector(unsigned long start, unsigned long len)=0
MSCDEX_HasDrive
bool MSCDEX_HasDrive(char driveLetter)
Definition: dos_mscdex.cpp:1257
CMscdex::ReadSectors
bool ReadSectors(Bit16u drive, Bit32u sector, Bit16u num, PhysPt data)
Definition: dos_mscdex.cpp:659
CMscdex::SDriveInfo::audioPlay
bool audioPlay
Definition: dos_mscdex.cpp:148
MEM_BlockRead
void MEM_BlockRead(PhysPt pt, void *data, Bitu size)
Definition: memory.cpp:181
CMscdex::PlayAudioSector
bool PlayAudioSector(Bit8u subUnit, Bit32u start, Bit32u length)
Definition: dos_mscdex.cpp:459
Bits
signed int Bits
Definition: config.h:77
strategy
Bit16u strategy
Definition: dos_mscdex.cpp:73
DOS_DeviceHeader::SetName
void SetName(char const *_name)
Definition: dos_mscdex.cpp:68
MSCDEX_GetSubUnit
Bit8u MSCDEX_GetSubUnit(char driveLetter)
Definition: dos_mscdex.cpp:1267
DOS_DeviceHeader::sDeviceHeader::wReserved
Bit16u wReserved
Definition: dos_mscdex.cpp:82
CMscdex::SDriveInfo::locked
bool locked
Definition: dos_mscdex.cpp:152
SMSF::sec
unsigned char sec
Definition: cdrom.h:30
device_MSCDEX::GetInformation
Bit16u GetInformation(void)
Definition: dos_mscdex.cpp:1222
CMscdex::IsValidDrive
bool IsValidDrive(Bit16u drive)
Definition: dos_mscdex.cpp:187
CMscdex::SDriveInfo::lastResult
bool lastResult
Definition: dos_mscdex.cpp:153
DOS_DeviceHeader::DOS_DeviceHeader
DOS_DeviceHeader(PhysPt ptr)
Definition: dos_mscdex.cpp:60
dos_inc.h
pause
Bitu pause
Definition: keyboard.cpp:46
real_writeb
static INLINE void real_writeb(Bit16u seg, Bit16u off, Bit8u val)
Definition: mem.h:174
reg_bx
reg_bx
Definition: prefix_none.h:226
Bitu
unsigned int Bitu
Definition: config.h:76
CMscdex::RemoveDrive
int RemoveDrive(Bit16u _drive)
Definition: dos_mscdex.cpp:201
CMscdex::SDriveInfo::volumeSize
Bit32u volumeSize
Definition: dos_mscdex.cpp:154
CMscdex::SDriveInfo::audioEnd
Bit32u audioEnd
Definition: dos_mscdex.cpp:151
DOS_DeviceHeader::SetAttribute
void SetAttribute(Bit16u atr)
Definition: dos_mscdex.cpp:64
cpu.h
CMscdex::dinfo
TDriveInfo dinfo[8]
Definition: dos_mscdex.cpp:158
CMscdex::SendDriverRequest
bool SendDriverRequest(Bit16u drive, PhysPt data)
Definition: dos_mscdex.cpp:824
CDROM_Interface_Fake
Definition: cdrom.h:91
MSCDEX_ReplaceDrive
void MSCDEX_ReplaceDrive(CDROM_Interface *cdrom, Bit8u subUnit)
Definition: dos_mscdex.cpp:1262
CMscdex::SDriveInfo::drive
Bit8u drive
Definition: dos_mscdex.cpp:146
DOS_DeviceHeader::sDeviceHeader::numSubUnits
Bit8u numSubUnits
Definition: dos_mscdex.cpp:84
CMscdex::~CMscdex
~CMscdex(void)
Definition: dos_mscdex.cpp:174
MSCDEX_ERROR_UNKNOWN_DRIVE
#define MSCDEX_ERROR_UNKNOWN_DRIVE
Definition: dos_mscdex.cpp:44
CallBack_Handlers
CallBack_Handler CallBack_Handlers[]
Definition: callback.cpp:34
CMscdex::numDrives
Bit16u numDrives
Definition: dos_mscdex.cpp:143
mem_writeb
void mem_writeb(PhysPt pt, Bit8u val)
Definition: memory.cpp:502
CDROM_USE_SDL
Definition: cdrom.h:26
CMscdex::TDriveInfo
struct CMscdex::SDriveInfo TDriveInfo
reg_cl
#define reg_cl
Definition: regs.h:142
MSCDEX_SetCDInterface
void MSCDEX_SetCDInterface(int intNr, int numCD)
Definition: dos_mscdex.cpp:1301
DOS_DeviceHeader::sDeviceHeader
Definition: dos_mscdex.cpp:76
CMscdex::GetTrackInfo
bool GetTrackInfo(Bit8u subUnit, Bit8u track, Bit8u &attr, TMSF &start)
Definition: dos_mscdex.cpp:448
x2
const int x2
Definition: render_templates_sai.h:26
CMscdex::GetDirectoryEntry
bool GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, PhysPt buffer, Bit16u &error)
Definition: dos_mscdex.cpp:663
CMscdex::GetCurrentPos
bool GetCurrentPos(Bit8u subUnit, TMSF &pos)
Definition: dos_mscdex.cpp:774
reg_al
reg_al
Definition: prefix_none.h:937
name
Bit8u name[8]
Definition: dos_mscdex.cpp:75
CDROM_Interface
Definition: cdrom.h:36
mem_readb
Bit8u mem_readb(PhysPt pt)
Definition: memory.cpp:490
sGet
#define sGet(s, m)
Definition: dos_inc.h:254
reg_ch
#define reg_ch
Definition: regs.h:143
off
Bit16u off
Definition: ea_lookup.h:1
setup.h
MSCDEX_ERROR_BAD_FORMAT
#define MSCDEX_ERROR_BAD_FORMAT
Definition: dos_mscdex.cpp:43
CMscdex::GetVolumeName
bool GetVolumeName(Bit8u subUnit, char *name)
Definition: dos_mscdex.cpp:582
curReqheaderPtr
static PhysPt curReqheaderPtr
Definition: dos_mscdex.cpp:866
sSave
#define sSave(s, m, val)
Definition: dos_inc.h:255
CDROM_USE_ASPI
Definition: cdrom.h:26
MSCDEX_Strategy_Handler
static Bitu MSCDEX_Strategy_Handler(void)
Definition: dos_mscdex.cpp:1001
CDROM_Interface::GetMediaTrayStatus
virtual bool GetMediaTrayStatus(bool &mediaPresent, bool &mediaChanged, bool &trayOpen)=0
CMscdex::ReadVTOC
bool ReadVTOC(Bit16u drive, Bit16u volume, PhysPt data, Bit16u &error)
Definition: dos_mscdex.cpp:561
CMscdex::GetFirstDrive
Bit16u GetFirstDrive(void)
Definition: dos_mscdex.cpp:98
SMSF::fr
unsigned char fr
Definition: cdrom.h:31
CMscdex::GetMediaStatus
bool GetMediaStatus(Bit8u subUnit, Bit8u &status)
Definition: dos_mscdex.cpp:806
MemStruct::pt
PhysPt pt
Definition: dos_inc.h:278
SMSF::min
unsigned char min
Definition: cdrom.h:29
device_MSCDEX::Write
bool Write(Bit8u *, Bit16u *)
Definition: dos_mscdex.cpp:1216
DOS_DeviceHeader::SetStrategy
void SetStrategy(Bit16u ofs)
Definition: dos_mscdex.cpp:70
bios_disk.h
interrupt
Bit16u interrupt
Definition: dos_mscdex.cpp:74
CMscdex::GetDriverInfo
void GetDriverInfo(PhysPt data)
Definition: dos_mscdex.cpp:423
CBRET_NONE
Definition: callback.h:42
CMscdex::GetDeviceStatus
Bit32u GetDeviceStatus(Bit8u subUnit)
Definition: dos_mscdex.cpp:791
MSCDEX_VERSION_LOW
#define MSCDEX_VERSION_LOW
Definition: dos_mscdex.cpp:38
CMscdex::SDriveInfo::audioStart
Bit32u audioStart
Definition: dos_mscdex.cpp:150
CMscdex::GetSubUnit
Bit8u GetSubUnit(Bit16u _drive)
Definition: dos_mscdex.cpp:194
LOG_WARN
Definition: logging.h:17
MSCDEX_Init
void MSCDEX_Init(Section *sec)
Definition: dos_mscdex.cpp:1312
DOS_DeviceHeader::sDeviceHeader::name
Bit8u name[8]
Definition: dos_mscdex.cpp:81
nextDeviceHeader
RealPt nextDeviceHeader
Definition: dos_mscdex.cpp:71
min
#define min(a, b)
Definition: sblaster.cpp:226
CMscdex::ResumeAudio
bool ResumeAudio(Bit8u subUnit)
Definition: dos_mscdex.cpp:547
DOS_GetMemory
Bit16u DOS_GetMemory(Bit16u pages)
Definition: dos_tables.cpp:45
ss
Bit16u ss
Definition: cpu.h:183
size
Bit32u size
Definition: dos_inc.h:479
Section
Definition: setup.h:225
DOS_DeviceHeader::GetNumSubUnits
Bit8u GetNumSubUnits(void)
Definition: dos_mscdex.cpp:67
playing
bool playing
Definition: mpu401.cpp:72
CALLBACK_SCF
void CALLBACK_SCF(bool val)
Definition: callback.cpp:118
MemStruct
Definition: dos_inc.h:257
dos_system.h
device_MSCDEX::Read
bool Read(Bit8u *, Bit16u *)
Definition: dos_mscdex.cpp:1215
device_MSCDEX
Definition: dos_mscdex.cpp:1212
CALLBACK_Allocate
Bitu CALLBACK_Allocate()
Definition: callback.cpp:45
es
Bit16u es
Definition: cpu.h:181
CMscdex::defaultBufSeg
Bit16u defaultBufSeg
Definition: dos_mscdex.cpp:157
type
Bit32u type
Definition: cpu.h:187
RealMake
static INLINE RealPt RealMake(Bit16u seg, Bit16u off)
Definition: mem.h:201
reg_cx
reg_cx
Definition: prefix_none.h:226
reg_dh
#define reg_dh
Definition: regs.h:148
DOS_DeviceHeader::GCC_ATTRIBUTE
struct DOS_DeviceHeader::sDeviceHeader GCC_ATTRIBUTE(packed) TDeviceHeader
DOS_Device
Definition: dos_system.h:96
DOS_DeviceHeader::SetNextDeviceHeader
void SetNextDeviceHeader(RealPt ptr)
Definition: dos_mscdex.cpp:62
getSwapRequest
bool getSwapRequest(void)
Definition: bios_disk.cpp:118
driveLetter
Bit8u driveLetter
Definition: dos_mscdex.cpp:77
REQUEST_STATUS_ERROR
#define REQUEST_STATUS_ERROR
Definition: dos_mscdex.cpp:49
buffer
char buffer[127]
Definition: dos_inc.h:111
MEM_BlockWrite
void MEM_BlockWrite(PhysPt pt, void const *const data, Bitu size)
Definition: memory.cpp:188
RealPt
Bit32u RealPt
Definition: mem.h:28
DOS_DeviceHeader::sDeviceHeader::interrupt
Bit16u interrupt
Definition: dos_mscdex.cpp:80
CMscdex::SDriveInfo::physDrive
Bit8u physDrive
Definition: dos_mscdex.cpp:147
mscdex
static CMscdex * mscdex
Definition: dos_mscdex.cpp:865
CMscdex::SDriveInfo
Definition: dos_mscdex.cpp:145
DOS_AddMultiplexHandler
void DOS_AddMultiplexHandler(MultiplexHandler *handler)
Definition: dos_misc.cpp:34