Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

833 lines
25 KiB

  1. /*
  2. * demdasd.c - module for direct disk access related support functions
  3. *
  4. * Williamh 09-Dec-1992 Created
  5. * Revision 24-Mar-1993 added fdisk support
  6. */
  7. #include "io.h"
  8. #include "dem.h"
  9. #include "stdio.h"
  10. #include "windows.h"
  11. #include "demdasd.h"
  12. #include "softpc.h"
  13. PBDS demBDS;
  14. BYTE NumberOfFloppy;
  15. BYTE NumberOfFdisk;
  16. #if defined(NEC_98)
  17. #define LPTBL_adr 0x0066c
  18. #define EXLPTBL_adr 0x03286
  19. #define FLOPY_LPTBL 0x90 // Floppy
  20. #define FDISK_LPTBL 0xA0 // Shown as SCSI
  21. #endif // NEC_98
  22. extern WORD int13h_vector_off, int13h_vector_seg;
  23. extern WORD int13h_caller_off, int13h_caller_seg;
  24. #if defined(NEC_98)
  25. extern void sas_store(char*,unsigned char);
  26. #endif // NEC_98
  27. BPB StdBpb[MAX_FLOPPY_TYPE] = {
  28. {512, 2, 1, 2, 112, 2*9*40, 0xFD, 2, 9, 2, 0, 0}, // 360KB
  29. {512, 1, 1, 2, 224, 2*15*80, 0xF9, 7, 15, 2, 0, 0}, // 1.2MB
  30. {512, 2, 1, 2, 112, 2*9*80, 0xF9, 3, 9, 2, 0, 0}, // 720KB
  31. {512, 1, 1, 2, 224, 2*18*80, 0xF0, 9, 18, 2, 0, 0}, // 1.44MB
  32. {512, 2, 1, 2, 240, 2*36*80, 0xF0, 9, 36, 2, 0, 0} // 2.88MB
  33. #if defined(NEC_98)
  34. , {1024, 1, 1, 2, 192, 2*8*77, 0xFE, 2, 8, 2, 0, 0}, // 1.2MB
  35. {512, 2, 1, 2, 112, 2*8*80, 0xFB, 2, 8, 2, 0, 0} // 640KB
  36. #endif // !NEC_98
  37. };
  38. BYTE FormFactorTable[MAX_FLOPPY_TYPE] = {
  39. FF_360,
  40. FF_120,
  41. FF_720,
  42. FF_144,
  43. #if defined(NEC_98)
  44. FF_288,
  45. FF_125,
  46. FF_640
  47. #else // !NEC_98
  48. FF_288
  49. #endif // !NEC_98
  50. };
  51. /* demDasdInit - dem diskette system Initialiazation
  52. *
  53. * Entry
  54. * none
  55. *
  56. *
  57. * Exit
  58. * None
  59. */
  60. VOID demDasdInit(VOID)
  61. {
  62. demBDS = NULL;
  63. NumberOfFloppy = NumberOfFdisk = 0;
  64. demFloppyInit();
  65. demFdiskInit();
  66. }
  67. /* demAbsRead - int 25, absolute read
  68. *
  69. * Entry
  70. * Client (AL) = drive number (0 based)
  71. * (DS:BX) = pointer to the buffer to receive the read data
  72. * or pointer to the DISKIO structure
  73. * (CX) = number of sectors to read
  74. * if (0FFFFh) then DS:DX points to DISKIO
  75. * DX contents are discarded
  76. * (DX) = starting sector number
  77. *
  78. *
  79. * Exit
  80. * Client (CY) = 0 if operation succeed
  81. * (AX) = 0
  82. *
  83. * (CY) = 1 if operation failed
  84. * (AX) = error code
  85. */
  86. VOID demAbsRead (VOID)
  87. {
  88. #if DBG
  89. if (fShowSVCMsg & DEM_ABSDRD)
  90. OutputDebugStringOem("DEM: INT 25 Called \n");
  91. #endif
  92. demAbsReadWrite(FALSE);
  93. }
  94. /* demAbsWrite - int 26, absolute read
  95. *
  96. *
  97. * Entry
  98. * Client (AL) = drive number (0 based)
  99. * (DS:BX) = pointer to the buffer to receive the read data
  100. * or pointer to the DISKIO structure
  101. * (CX) = number of sectors to read
  102. * if (0FFFFh) then DS:DX points to DISKIO
  103. * DX contents are discarded
  104. * (DX) = starting sector number
  105. *
  106. *
  107. * Exit
  108. * Client (CY) = 0 if operation succeed
  109. * (AX) = 0
  110. *
  111. * (CY) = 1 if operation failed
  112. * (AX) = error code
  113. */
  114. VOID demAbsWrite(VOID)
  115. {
  116. #if DBG
  117. if (fShowSVCMsg & DEM_ABSWRT)
  118. OutputDebugStringOem("DEM: INT 26 Called \n");
  119. #endif
  120. demAbsReadWrite(TRUE);
  121. }
  122. extern BOOL (*DosWowDoDirectHDPopup)(VOID); // defined in demlfn.c
  123. VOID demAbsReadWrite(BOOL IsWrite)
  124. {
  125. BYTE Drive;
  126. DWORD LastError;
  127. DWORD Sectors;
  128. DWORD StartSector;
  129. PDISKIO DiskIo;
  130. DWORD SectorsReturned;
  131. PBDS pBDS;
  132. WORD BufferOff, BufferSeg;
  133. Drive = getAL();
  134. if ((Sectors = getCX()) == 0xFFFF) {
  135. DiskIo = (PDISKIO) GetVDMAddr(getDS(), getBX());
  136. Sectors = DiskIo->Sectors;
  137. StartSector = DiskIo->StartSector;
  138. BufferOff = DiskIo->BufferOff;
  139. BufferSeg = DiskIo->BufferSeg;
  140. }
  141. else {
  142. StartSector = getDX();
  143. BufferOff = getBX();
  144. BufferSeg = getDS();
  145. }
  146. if ((pBDS = demGetBDS(Drive)) == NULL) {
  147. if (!demIsDriveFloppy(Drive) && Drive < 26) {
  148. if (NULL == DosWowDoDirectHDPopup || (*DosWowDoDirectHDPopup)()) {
  149. host_direct_access_error(NOSUPPORT_HARDDISK);
  150. }
  151. }
  152. setAX(DOS_DRIVE_NOT_READY);
  153. setCF(1);
  154. return;
  155. }
  156. #if DBG
  157. if (fShowSVCMsg & (DEM_ABSDRD | DEM_ABSWRT)) {
  158. sprintf(demDebugBuffer, "Drive Number: %d\n", Drive);
  159. OutputDebugStringOem(demDebugBuffer);
  160. sprintf(demDebugBuffer, "StartSector: %d\n", StartSector);
  161. OutputDebugStringOem(demDebugBuffer);
  162. sprintf(demDebugBuffer, "Total Sectors: %d\n", Sectors);
  163. OutputDebugStringOem(demDebugBuffer);
  164. sprintf(demDebugBuffer, "Buffer: %x:%x\n", BufferSeg, BufferOff);
  165. }
  166. #endif
  167. if (IsWrite)
  168. SectorsReturned = demDasdWrite(pBDS,
  169. StartSector,
  170. Sectors,
  171. BufferOff,
  172. BufferSeg
  173. );
  174. else
  175. SectorsReturned = demDasdRead(pBDS,
  176. StartSector,
  177. Sectors,
  178. BufferOff,
  179. BufferSeg
  180. );
  181. if (SectorsReturned != Sectors) {
  182. LastError = GetLastError();
  183. #if DBG
  184. if (fShowSVCMsg & (DEM_ABSDRD | DEM_ABSWRT)) {
  185. sprintf(demDebugBuffer, "dem: AbsRDWR Failed, error=%lx\n", LastError);
  186. OutputDebugStringOem(demDebugBuffer);
  187. }
  188. #endif
  189. setAX(demWinErrorToDosError(LastError));
  190. setCF(1);
  191. return;
  192. }
  193. setCF(0);
  194. return;
  195. }
  196. DWORD demDasdRead(
  197. PBDS pbds,
  198. DWORD StartSector,
  199. DWORD Sectors,
  200. WORD BufferOff,
  201. WORD BufferSeg
  202. )
  203. {
  204. ULONG SizeReturned;
  205. LARGE_INTEGER LargeInteger;
  206. DWORD Size;
  207. DWORD SectorSize;
  208. WORD CurBiosDiskIoOff, CurBiosDiskIoSeg;
  209. PBYTE Buffer;
  210. // if this is the first time we access the BDS or
  211. // the media has been changed, build the bds -- floppy
  212. if (!(pbds->Flags & NON_REMOVABLE) &&
  213. ((pbds->Flags & UNFORMATTED_MEDIA) ||
  214. !nt_floppy_media_check(pbds->DrivePhys))) {
  215. if (!demGetBPB(pbds))
  216. return 0;
  217. }
  218. if (StartSector >= pbds->TotalSectors ||
  219. StartSector + Sectors > pbds->TotalSectors) {
  220. SetLastError(ERROR_SECTOR_NOT_FOUND);
  221. return 0 ;
  222. }
  223. SectorSize = pbds->bpb.SectorSize;
  224. LargeInteger.QuadPart = Int32x32To64(Sectors, SectorSize);
  225. // size must fit in ulong
  226. if (LargeInteger.HighPart != 0) {
  227. SetLastError(ERROR_SECTOR_NOT_FOUND);
  228. return 0;
  229. }
  230. Size = LargeInteger.LowPart;
  231. Buffer = (PBYTE) GetVDMAddr(BufferSeg, BufferOff);
  232. if (pbds->Flags & NON_REMOVABLE) {
  233. LargeInteger.QuadPart = Int32x32To64(StartSector, SectorSize);
  234. SizeReturned = nt_fdisk_read(
  235. pbds->DrivePhys,
  236. &LargeInteger,
  237. Size,
  238. Buffer
  239. );
  240. }
  241. else {
  242. // floppy need special care beacuse application may hook
  243. // bios disk interrupt. We dont' do this for hard disks because
  244. // we don't allow int13 to them
  245. sas_loadw(0x13*4, &CurBiosDiskIoOff);
  246. sas_loadw(0x13* 4 + 2, &CurBiosDiskIoSeg);
  247. #if defined(NEC_98)
  248. if ( 1 ) // if NEC_98, always TRUE
  249. #else // !NEC_98
  250. if (int13h_vector_off == CurBiosDiskIoOff &&
  251. int13h_vector_seg == CurBiosDiskIoSeg)
  252. #endif // !NEC_98
  253. SizeReturned = nt_floppy_read(
  254. pbds->DrivePhys,
  255. StartSector * SectorSize,
  256. Size,
  257. Buffer
  258. );
  259. else
  260. return (demBiosDiskIoRW(pbds,
  261. StartSector,
  262. Sectors,
  263. BufferOff,
  264. BufferSeg,
  265. FALSE
  266. ));
  267. }
  268. if (SizeReturned == Size)
  269. return Sectors;
  270. else
  271. return SizeReturned / SectorSize;
  272. }
  273. DWORD demDasdWrite(
  274. PBDS pbds,
  275. DWORD StartSector,
  276. DWORD Sectors,
  277. WORD BufferOff,
  278. WORD BufferSeg
  279. )
  280. {
  281. ULONG SizeReturned;
  282. LARGE_INTEGER LargeInteger;
  283. DWORD Size;
  284. DWORD SectorSize;
  285. WORD CurBiosDiskIoOff, CurBiosDiskIoSeg;
  286. PBYTE Buffer;
  287. // if this is the first time we access the BDS or
  288. // the media has been changed, build the bds
  289. if (!(pbds->Flags & NON_REMOVABLE) &&
  290. ((pbds->Flags & UNFORMATTED_MEDIA) ||
  291. !nt_floppy_media_check(pbds->DrivePhys))) {
  292. if (!demGetBPB(pbds))
  293. return 0;
  294. }
  295. if (StartSector >= pbds->TotalSectors ||
  296. StartSector + Sectors > pbds->TotalSectors) {
  297. SetLastError(ERROR_SECTOR_NOT_FOUND);
  298. return 0 ;
  299. }
  300. SectorSize = pbds->bpb.SectorSize;
  301. LargeInteger.QuadPart = Int32x32To64(Sectors, SectorSize);
  302. // size must fit in ulong
  303. if (LargeInteger.HighPart != 0) {
  304. SetLastError(ERROR_SECTOR_NOT_FOUND);
  305. return 0;
  306. }
  307. Size = LargeInteger.LowPart;
  308. Buffer = (PBYTE) GetVDMAddr(BufferSeg, BufferOff);
  309. if (pbds->Flags & NON_REMOVABLE) {
  310. LargeInteger.QuadPart = Int32x32To64(StartSector, SectorSize);
  311. SizeReturned = nt_fdisk_write(
  312. pbds->DrivePhys,
  313. &LargeInteger,
  314. Size,
  315. Buffer
  316. );
  317. }
  318. else {
  319. // floppy need special care beacuse application may hook
  320. // bios disk interrupt. We dont' do this for hard disks because
  321. // we don't allow int13 to them
  322. sas_loadw(0x13*4, &CurBiosDiskIoOff);
  323. sas_loadw(0x13* 4 + 2, &CurBiosDiskIoSeg);
  324. #if defined(NEC_98)
  325. if ( 1 ) // if NEC_98, always TRUE
  326. #else // !NEC_98
  327. if (int13h_vector_off == CurBiosDiskIoOff &&
  328. int13h_vector_seg == CurBiosDiskIoSeg)
  329. #endif // !NEC_98
  330. SizeReturned = nt_floppy_write(
  331. pbds->DrivePhys,
  332. StartSector * SectorSize,
  333. Size,
  334. Buffer
  335. );
  336. else
  337. return(demBiosDiskIoRW(pbds,
  338. StartSector,
  339. Sectors,
  340. BufferOff,
  341. BufferSeg,
  342. TRUE
  343. ));
  344. }
  345. if (Size == SizeReturned)
  346. return Sectors;
  347. else
  348. return SizeReturned / SectorSize;
  349. }
  350. BOOL demDasdFormat(PBDS pbds, DWORD Head, DWORD Cylinder, MEDIA_TYPE * Media)
  351. {
  352. BOOL Result;
  353. if (pbds->Flags & NON_REMOVABLE)
  354. Result = demDasdVerify(pbds, Head, Cylinder);
  355. else {
  356. if (*Media == Unknown) {
  357. *Media = nt_floppy_get_media_type(pbds->DrivePhys,
  358. pbds->Cylinders,
  359. pbds->bpb.TrackSize,
  360. pbds->bpb.Heads
  361. );
  362. return TRUE;
  363. }
  364. else {
  365. Result = nt_floppy_format(pbds->DrivePhys,
  366. (WORD)Cylinder,
  367. (WORD)Head,
  368. *Media
  369. );
  370. }
  371. }
  372. return (Result);
  373. }
  374. BOOL demDasdVerify(PBDS pbds, DWORD Head, DWORD Cylinder)
  375. {
  376. DWORD Size, StartSector;
  377. LARGE_INTEGER LargeInteger;
  378. // if floppy, make sure we have up-to-date BPB and a valid media is in
  379. if (!(pbds->Flags & NON_REMOVABLE)) {
  380. if (!demGetBPB(pbds))
  381. return FALSE;
  382. Size = pbds->bpb.TrackSize * pbds->bpb.SectorSize;
  383. StartSector = pbds->bpb.TrackSize * (Cylinder * pbds->bpb.Heads + Head) + 1;
  384. return (nt_floppy_verify(pbds->DrivePhys,
  385. StartSector * pbds->bpb.SectorSize,
  386. Size));
  387. }
  388. // hard disk needs special care because of their size
  389. Size = pbds->bpb.TrackSize * pbds->bpb.SectorSize;
  390. StartSector = pbds->bpb.TrackSize * (Cylinder * pbds->bpb.Heads + Head) + 1;
  391. LargeInteger.QuadPart = Int32x32To64(StartSector, pbds->bpb.SectorSize);
  392. return (nt_fdisk_verify(pbds->DrivePhys,
  393. &LargeInteger,
  394. Size
  395. ));
  396. }
  397. PBDS demGetBDS(BYTE DriveLog)
  398. {
  399. PBDS pbds;
  400. pbds = demBDS;
  401. while (pbds != NULL && pbds->DriveLog != DriveLog)
  402. pbds = pbds->Next;
  403. return pbds;
  404. }
  405. BOOL demGetBPB(PBDS pbds)
  406. {
  407. PBOOTSECTOR pbs;
  408. BYTE SectorBuffer[BYTES_PER_SECTOR];
  409. // when RETURN_FAKE_BPB is set(set by Set Device Parameter IOCTL,
  410. // the appplication has set a new BPB, we simply return it
  411. if (!(pbds->Flags & RETURN_FAKE_BPB) &&
  412. !(pbds->Flags & NON_REMOVABLE) &&
  413. ((pbds->Flags & UNFORMATTED_MEDIA) || !nt_floppy_media_check(pbds->DrivePhys))
  414. ) {
  415. pbds->Flags &= ~(UNFORMATTED_MEDIA);
  416. nt_floppy_close(pbds->DrivePhys);
  417. if (nt_floppy_read(pbds->DrivePhys,
  418. 0,
  419. BYTES_PER_SECTOR,
  420. SectorBuffer
  421. ) != BYTES_PER_SECTOR)
  422. return FALSE;
  423. pbs = (PBOOTSECTOR)SectorBuffer;
  424. if ((pbs->Jump == 0x69 || pbs->Jump == 0xE9 ||
  425. (pbs->Jump == 0xEB && pbs->Target[1] == 0x90)) &&
  426. (pbs->bpb.MediaID & 0xF0) == 0xF0) {
  427. pbds->bpb = pbs->bpb;
  428. pbds->TotalSectors = (pbs->bpb.Sectors) ? pbs->bpb.Sectors :
  429. pbs->bpb.BigSectors;
  430. return TRUE;
  431. }
  432. // an unknown media found
  433. else {
  434. pbds->Flags |= UNFORMATTED_MEDIA;
  435. // What should we do here? The diskette has strange boot sector
  436. // should we guess it or what?
  437. //
  438. #if DEVL
  439. if (fShowSVCMsg & (DEM_ABSDRD | DEM_ABSWRT)) {
  440. sprintf(demDebugBuffer, "Invalid Boot Sector Found\n");
  441. OutputDebugStringOem(demDebugBuffer);
  442. }
  443. #endif
  444. host_direct_access_error(NOSUPPORT_FLOPPY);
  445. return FALSE;
  446. }
  447. }
  448. return TRUE;
  449. }
  450. DWORD demBiosDiskIoRW(
  451. PBDS pbds,
  452. DWORD StartSector,
  453. DWORD Sectors,
  454. WORD BufferOff,
  455. WORD BufferSeg,
  456. BOOL IsWrite
  457. )
  458. {
  459. BYTE CurHead, CurSector, BiosErrorCode;
  460. WORD CurTrack, TrackSize, Heads, SectorTrack;
  461. WORD AX, BX, CX, DX, ES, CS, IP;
  462. BYTE SectorsRead, SectorsToRead;
  463. WORD wRetry = 3;
  464. AX = getAX();
  465. BX = getBX();
  466. CX = getCX();
  467. DX = getDX();
  468. ES = getES();
  469. CS = getCS();
  470. IP = getIP();
  471. TrackSize = pbds->bpb.TrackSize;
  472. Heads = pbds->bpb.Heads;
  473. SectorsRead = 0;
  474. CurSector = (BYTE) ((StartSector % TrackSize) + 1);
  475. CurTrack = (WORD) (StartSector / TrackSize);
  476. CurHead = CurTrack % Heads;
  477. CurTrack /= Heads;
  478. SectorsToRead = TrackSize - CurSector + 1;
  479. while (Sectors != 0) {
  480. if (Sectors < SectorsToRead)
  481. SectorsToRead = (BYTE) Sectors;
  482. // low byte: bit 6 and 7 are high bits of track,
  483. // bit 0 - 5 are sector number
  484. // high byte: bit 0 - bit 7 ->track lower 8 bits
  485. SectorTrack = ((CurTrack & 0x300) >> 2) | (CurSector & 0x3f) |
  486. ((CurTrack &0xFF) << 8);
  487. wRetry = 3;
  488. BiosRetry:
  489. setAH((BYTE) ((IsWrite) ? DISKIO_WRITE : DISKIO_READ));
  490. setAL(SectorsToRead);
  491. setBX(BufferOff);
  492. setES(BufferSeg);
  493. setDH(CurHead);
  494. setDL(pbds->DrivePhys);
  495. setCX(SectorTrack);
  496. setCS(int13h_caller_seg);
  497. setIP(int13h_caller_off);
  498. host_simulate();
  499. if (getCF() == 0) {
  500. SectorsRead += SectorsToRead;
  501. if ((Sectors -= SectorsToRead) == 0)
  502. break;
  503. CurSector = 1;
  504. if (++CurHead == Heads) {
  505. CurHead = 0;
  506. CurTrack++;
  507. }
  508. SectorsToRead = (BYTE) TrackSize;
  509. }
  510. else {
  511. BiosErrorCode = getAH();
  512. // reset the disk
  513. setAH(DISKIO_RESET);
  514. setDL(pbds->DrivePhys);
  515. setCS(int13h_caller_seg);
  516. setIP(int13h_caller_off);
  517. host_simulate();
  518. // NOTE that we dont' handle DMA boundary here
  519. // because it shouldn't happen. -- the NT disk DD
  520. // will take care of that.
  521. if (BiosErrorCode & BIOS_TIME_OUT) {
  522. SetLastError(ERROR_NO_MEDIA_IN_DRIVE);
  523. break;
  524. }
  525. if (wRetry--)
  526. goto BiosRetry;
  527. SetLastError(BiosErrorToNTError(BiosErrorCode));
  528. break;
  529. }
  530. }
  531. setAX(AX);
  532. setBX(BX);
  533. setCX(CX);
  534. setDX(DX);
  535. setES(ES);
  536. setCS(CS);
  537. setIP(IP);
  538. return SectorsRead;
  539. }
  540. DWORD BiosErrorToNTError(BYTE BiosErrorCode)
  541. {
  542. DWORD NtErrorCode;
  543. switch (BiosErrorCode) {
  544. case BIOS_INVALID_FUNCTION:
  545. NtErrorCode = ERROR_BAD_COMMAND;
  546. break;
  547. case BIOS_BAD_ADDRESS_MARK:
  548. NtErrorCode = ERROR_FLOPPY_ID_MARK_NOT_FOUND;
  549. break;
  550. case BIOS_WRITE_PROTECTED:
  551. NtErrorCode = ERROR_WRITE_PROTECT;
  552. break;
  553. case BIOS_BAD_SECTOR:
  554. case BIOS_CRC_ERROR:
  555. NtErrorCode = ERROR_SECTOR_NOT_FOUND;
  556. break;
  557. case BIOS_DISK_CHANGED:
  558. NtErrorCode = ERROR_DISK_CHANGE;
  559. break;
  560. case BIOS_NO_MEDIA:
  561. NtErrorCode = ERROR_NO_MEDIA_IN_DRIVE;
  562. break;
  563. case BIOS_SEEK_ERROR:
  564. NtErrorCode = ERROR_SEEK;
  565. break;
  566. default:
  567. NtErrorCode = ERROR_FLOPPY_UNKNOWN_ERROR;
  568. }
  569. return NtErrorCode;
  570. }
  571. WORD demWinErrorToDosError(DWORD LastError)
  572. {
  573. WORD DosError;
  574. switch(LastError) {
  575. case ERROR_SEEK:
  576. DosError = DOS_SEEK_ERROR;
  577. break;
  578. case ERROR_BAD_UNIT:
  579. DosError = DOS_UNKNOWN_UNIT;
  580. break;
  581. case ERROR_NO_MEDIA_IN_DRIVE:
  582. case ERROR_NOT_READY:
  583. DosError = DOS_DRIVE_NOT_READY;
  584. break;
  585. case ERROR_NOT_DOS_DISK:
  586. DosError = DOS_UNKNOWN_MEDIA;
  587. break;
  588. case ERROR_SECTOR_NOT_FOUND:
  589. case ERROR_FLOPPY_WRONG_CYLINDER:
  590. DosError = DOS_SECTOR_NOT_FOUND;
  591. break;
  592. case ERROR_READ_FAULT:
  593. DosError = DOS_READ_FAULT;
  594. break;
  595. case ERROR_WRITE_FAULT:
  596. DosError = DOS_WRITE_FAULT;
  597. break;
  598. case ERROR_WRONG_DISK:
  599. case ERROR_DISK_CHANGE:
  600. case ERROR_MEDIA_CHANGED:
  601. DosError = DOS_INVALID_MEDIA_CHANGE;
  602. break;
  603. case ERROR_WRITE_PROTECT:
  604. DosError = DOS_WRITE_PROTECTION;
  605. break;
  606. default:
  607. DosError = DOS_GEN_FAILURE;
  608. }
  609. return (DosError);
  610. }
  611. VOID demFdiskInit(VOID)
  612. {
  613. PBDS pbds;
  614. UCHAR Drive;
  615. DISK_GEOMETRY DiskGeometry;
  616. BPB bpb;
  617. #if defined(NEC_98)
  618. CHAR numFlop = 0;
  619. CHAR numFdisk = 0;
  620. #endif // NEC_98
  621. Drive = 0;
  622. do {
  623. // first, the drive must be valid
  624. // second, the drive must be a hard disk(fixed)
  625. // third, the drive must be a FAT
  626. if (demGetPhysicalDriveType(Drive) == DRIVE_FIXED &&
  627. nt_fdisk_init(Drive, &bpb, &DiskGeometry)) {
  628. #if defined(NEC_98)
  629. sas_store( LPTBL_adr+Drive , (FDISK_LPTBL+numFdisk) );
  630. sas_store( EXLPTBL_adr+Drive*2, 0 );
  631. sas_store( EXLPTBL_adr+Drive*2+1, (FDISK_LPTBL+numFdisk++) );
  632. #endif // NEC_98
  633. pbds = (PBDS) malloc(sizeof(BDS));
  634. if (pbds != NULL) {
  635. pbds->bpb = bpb;
  636. pbds->rbpb = bpb;
  637. pbds->DrivePhys = NumberOfFdisk++;
  638. pbds->DriveLog = Drive;
  639. pbds->DriveType = DRIVETYPE_FDISK;
  640. pbds->FormFactor = FF_FDISK;
  641. pbds->TotalSectors = (bpb.Sectors) ?
  642. bpb.Sectors :
  643. bpb.BigSectors;
  644. pbds->Cylinders = (WORD) DiskGeometry.Cylinders.LowPart;
  645. pbds->Next = demBDS;
  646. pbds->Flags = NON_REMOVABLE | PHYS_OWNER;
  647. demBDS = pbds;
  648. }
  649. }
  650. #if defined(NEC_98)
  651. else if (demGetPhysicalDriveType(Drive) == DRIVE_REMOVABLE ) {
  652. sas_store( LPTBL_adr+Drive, (FLOPY_LPTBL+numFlop) );
  653. sas_store( EXLPTBL_adr+Drive*2, 0 );
  654. sas_store( EXLPTBL_adr+Drive*2+1, (FLOPY_LPTBL+numFlop++) );
  655. }
  656. #endif // NEC_98
  657. } while (++Drive < 26);
  658. }
  659. VOID demFloppyInit(VOID)
  660. {
  661. WORD AX, BX, CX, DX, DI, ES;
  662. #if defined(NEC_98)
  663. // BUG???: NumberOfFloppy is defined before.
  664. BYTE i;
  665. #else // !NEC_98
  666. BYTE i, NumberOfFloppy;
  667. #endif // NEC_98
  668. PBDS pbds;
  669. BYTE DriveType;
  670. #if defined(NEC_98)
  671. DWORD DriveMask;
  672. CHAR achRoot[] = "A:\\";
  673. #endif // NEC_98
  674. AX = getAX();
  675. BX = getBX();
  676. CX = getCX();
  677. DX = getDX();
  678. DI = getDI();
  679. ES = getES();
  680. // reset the floppy system
  681. #if defined(NEC_98)
  682. DriveMask = GetLogicalDrives();
  683. i=0;
  684. if ( DriveMask ) {
  685. while (DriveMask != 0) {
  686. achRoot[0] = i + 'A';
  687. if ((DriveMask & 1)
  688. &&(GetDriveType(achRoot) == DRIVE_REMOVABLE)){
  689. pbds = (PBDS) malloc(sizeof(BDS));
  690. if (pbds == NULL) {
  691. OutputDebugStringOem("dem: not enough memory for BDS\n");
  692. break;
  693. }
  694. pbds->DrivePhys = pbds->DriveLog = i;
  695. pbds->DriveType = DriveType = 6; // 1.2 MB 2HD
  696. pbds->fd = NULL; //
  697. pbds->Cylinders = 77; //
  698. pbds->Sectors = 8; //
  699. pbds->rbpb = StdBpb[DriveType - 1];
  700. pbds->TotalSectors = 0;
  701. pbds->Next = demBDS;
  702. pbds->FormFactor = FormFactorTable[DriveType - 1];
  703. demBDS = pbds;
  704. pbds->Flags = UNFORMATTED_MEDIA | PHYS_OWNER;
  705. pbds->Flags |= HAS_CHANGELINE;
  706. }
  707. DriveMask>>=1;
  708. i++;
  709. NumberOfFloppy++;
  710. }
  711. }
  712. #else // !NEC_98
  713. setDL(0);
  714. setAH(DISKIO_RESET);
  715. diskette_io();
  716. setDL(0);
  717. setAH(DISKIO_GETPARAMS);
  718. diskette_io();
  719. if (getCF() == 0 && (NumberOfFloppy = getDL()) != 0) {
  720. for(i = 0; i < NumberOfFloppy; i++) {
  721. setDL(i);
  722. setAH(DISKIO_GETPARAMS);
  723. diskette_io();
  724. if (getCF() == 0) {
  725. pbds = (PBDS) malloc(sizeof(BDS));
  726. if (pbds == NULL) {
  727. OutputDebugStringOem("dem: not enough memory for BDS\n");
  728. break;
  729. }
  730. pbds->DrivePhys = pbds->DriveLog = i;
  731. pbds->DriveType = DriveType = getBL() & 0x0F;
  732. pbds->fd = NULL;
  733. pbds->Cylinders = getCH() + 1;
  734. pbds->Sectors = getCL();
  735. pbds->rbpb = StdBpb[DriveType - 1];
  736. pbds->TotalSectors = 0;
  737. pbds->Next = demBDS;
  738. pbds->FormFactor = FormFactorTable[DriveType - 1];
  739. demBDS = pbds;
  740. pbds->Flags = UNFORMATTED_MEDIA | PHYS_OWNER;
  741. setAH(DISKIO_DRIVETYPE);
  742. setDL(i);
  743. diskette_io();
  744. if (getAH() == 2 )
  745. pbds->Flags |= HAS_CHANGELINE;
  746. }
  747. }
  748. }
  749. #endif //NEC_98
  750. setAX(AX);
  751. setBX(BX);
  752. setCX(CX);
  753. setDX(DX);
  754. setDI(DI);
  755. setES(ES);
  756. }
  757. #if defined(NEC_98)
  758. BOOL demIsDriveFloppy(BYTE DriveLog){
  759. CHAR achRoot[] = "A:\\";
  760. achRoot[0]='A'+DriveLog;
  761. return (GetDriveType(achRoot) == DRIVE_REMOVABLE );
  762. }
  763. #endif // NEC_98