King_V Posted July 8, 2006 Share Posted July 8, 2006 All,Well, put my project on hold a bit before, but now I'm getting back into it.I want to essentially create a Win98Lite boot CD of sorts.However, what I've been searching for on the web and can't quite get a handle on how to do, is some method that will give me the following:1) List of hard drives on the system (or the last hard drive) that are NOT cd drives.2) List of CD drives on the system.Anyone know how this can be done? I've found a couple of batch file programs that are supposed to be able to show all the drives that exist, but they don't seem to work reliably. Link to comment Share on other sites More sharing options...
LLXX Posted July 9, 2006 Share Posted July 9, 2006 Use the BIOS int 13 disk services. There are several that can be used, but this one comes to mind:INT 13 - DISK - GET DISK TYPE (XT 1986/1/10 or later,XT286,AT,PS) AH = 15h DL = drive number (bit 7 set for hard disk) (AL = FFh, CX = FFFFh, see Note)Return: CF clear if successful AH = type code 00h no such drive (SpeedStor) AL = 03h hard disk CX:DX = number of 512-byte sectors 01h floppy without change-line support 02h floppy (or other removable drive) with change-line support 03h hard disk CX:DX = number of 512-byte sectors CF set on errorLoop through from drive 80 onwards, this essentially scans for valid drives. Once a drive is found, it can be determined to be removable or fixed with another function.The byte at 0040:0075 is also "number of fixed disk drives", according to the IBM PC AT Technical Reference Manual.Another alternative is to check for drives via hardware I/O through the ports starting at 1F0 (primary IDE controller) and 170 (secondary IDE controller) Link to comment Share on other sites More sharing options...
somewan Posted July 10, 2006 Share Posted July 10, 2006 Another alternative is to check for drives via hardware I/O through the ports starting at 1F0 (primary IDE controller) and 170 (secondary IDE controller)That method seems to yield the best results (including anASCII model name) - even on older computers where theBIOS is incapable of detecting or supporting the drive.I copied and pasted a chunk below from an IDE documentI didn't know I had.If you have SCSI like me, the simple method is to load anASPI driver from CONFIG.SYS. Both Adaptec and LSI driverswill scan the bus and list all devices by default. The hardbut more interesting way is to program the SCSI hostadapter card directly - get the data sheet/manual first.(Also, if you ever wondered why a proper SCSI driverconsumes less CPU, the manual should be enlightening.)LSI53C1010 - PCI to Dual-Channel Ultra160 SCSI ControllerController technical manualIDE doc quote follows...5. Register Address DecodingThe host addresses the drive with programmed I/O. Host address lines A0, A1,A2, chip select CS1FX- and CS3FX-, IOR- and IOW- address the disk registers.Host address lines A3...A9 generate the two chip selects: CS1FX- and CS3FX-.Chip select CS1FX- accesses the eight hard disk Command Block Registers.Chip select CS3FX- is valid during 8 bit transfers to/from the Control Blockregisters alternate status and Device Control, and drive address.The drive selects the primary or alternate command block addresses usingaddress bit A7.(Note: What the above sentence means is that there is a provision for aprimary host adapter at I/O address 1FX/3FX and a secondary host adapter atI/O adress 17X/37X. Each host adapter can have up to two hard drivesMASTER/SLAVED off it).See below for a graphical explanation:HEX BINARY DESCRIPTION1FX 0001 1111 XXXX Primary Command Registers3FX 0011 1111 XXXX Primary Control Registers17X 0001 0111 XXXX Alternate Command Registers37X 0011 0111 XXXX Alternate Control Registers ^ | +--- Address bit A7X means "don't care" i.e. X can be 0h, 1h, 2h, ..., Dh, Eh, Fh or 0b, 1b).Data bus lines D8...D15 are valid only when IOCS16- is active and the driveis transferring data. The transfer of ECC information occurs only on databus lines D0...D7 and data bus lines D8...D15 are invalid during suchtransfer.7. I/O Port Functions+----+------+------+---+---+---+----------------+---------------+|Addr|-CS1FX|-CS3FX|SA2|SA1|SA0| Read (-IOR) | Write (-IOW) |+----+------+------+---+---+---+----------------+---------------+-----------+| | 0 | 0 | X | X | X | ILLEGAL | ILLEGAL | <--+ || | 1 | 1 | X | X | X | High Impedance | Not Used | Control ||3FX | 1 | 0 | 0 | X | X | High Impedance | Not Used | Block ||3FX | 1 | 0 | 1 | 0 | X | High Impedance | Not Used | Registers ||3F6 | 1 | 0 | 1 | 1 | 0 | Altern Status | Device Control| | ||3F7 | 1 | 0 | 1 | 1 | 1 | Drive Address | Not Used | <--+ |+----+------+------+---+---+---+----------------+---------------+-----------+|1F0 | 0 | 1 | 0 | 0 | 0 | Data Port | Data Port | <--+ ||1F1 | 0 | 1 | 0 | 0 | 1 | Error Register | Precomp | | ||1F2 | 0 | 1 | 0 | 1 | 0 | Sector Count | Sector Count | Command ||1F3 | 0 | 1 | 0 | 1 | 1 | Sector Number | Sector Number | Block ||1F4 | 0 | 1 | 1 | 0 | 0 | Cylinder Low | Cylinder Low | Registers ||1F5 | 0 | 1 | 1 | 0 | 1 | Cylinder High | Cylinder High | | ||1F6 | 0 | 1 | 1 | 1 | 0 | Drive / Head | Drive / Head | | ||1F7 | 0 | 1 | 1 | 1 | 1 | Status | Command | <--+ |+----+------+------+---+---+---+----------------+---------------+-----------+At power-up or after reset, the Command Block Registers are initialized tothe following values:REGISTER VALUE1F1 Error : 011F2 Sector Count : 011F3 Sector Number : 011F4 Cylinder Low : 001F5 Cylinder High : 001F6 Drive / Head : 00 ------------------------------------------------------------------------8. Register Descriptions1F0: Read/Write: DATA PORT REGISTER All data transferred between the device data buffer and the host passes through this register. Also, the port to which the sector table is transferred during execution of the Format command. Transfers of ECC bytes during the execution of Read/Write Long commands are 8 bit transfers.1F1: Read: ERROR REGISTER Contains status information about the last command executed by the drive. The contents of this register are valid only when the error bit (ERR) in the Status Register is set, except at drive power-up or at the completion of the drive's internal diagnostics, when the register contains a status code. When the error bit (ERR) is set, Error Register bits are interpreted as such: +-----+--------+-------------------------------------------------------------+ | BIT | Mnemon | Description | +-----+--------+-------------------------------------------------------------+ | 7 | BBK | Bad block mark detected in the requested sector's ID field | | 6 | UNC | Uncorrectable data error encountered | | 5 | | Not used | | 4 | IDNF | Requested sector's ID field not found | | 3 | | Not used | | 2 | ABRT | Command aborted due to drive status error or invalid command| | 1 | TK0NF | Track 0 not found during execution of Recalibrate command | | 0 | AMNF | Data address mark not found after correct ID field found | +-----+--------+-------------------------------------------------------------+1F1: Write: WRITE PRECOMPENSATION The drive ignores the write precompensation value passed by the host.1F2: Read/Write: SECTOR COUNT REGISTER Defines the number of sectors of data to be transferred across the host bus, for the subsequent command. If the value in this register is zero, the sector count is 256 sectors. If the command executes successfully, the value in this register at command completion is zero. As each sector is transferred, the Sector Count register is decremented by one to reflect the number of sectors remaining to be transferred. If the command execution is not successful, this register contains the number of sectors that must be transferred to complete the original request.1F3: Read/Write: SECTOR NUMBER REGISTER Contains the ID number of the first sector to be accessed by the subsequent command. The sector can be from one to the maximum number of sectors per track. See the command description for additional information about the contents of the Sector Number Register following command completion whether successful or unsuccessful.1F4: Read/Write: CYLINDER LOW REGISTER Contains the eight low order bits of the starting cylinder address for any disk access. On multiple sector transfers that cross cylinder boundaries, this register is updated at the end of the command to reflect the current cylinder number. The least significant bits of the cylinder address are loaded into the cylinder low register.1F5: Read/Write: CYLINDER HIGH REGISTER Contains the eight high order bits of the starting cylinder address for any disk access. On multiple sector transfers that cross cylinder boundaries, this register is updated at hte end of the command to reflect the current cylinder number. The most significant bits of the cylinder address are loaded into the cylinder high register.1F6: Read/Write: DRIVE/HEAD REGISTER Contains the drive ID number and its head number for any disk access. The contents of the Drive/Head Register are defined on execution of the Initialize Drive Parameters command. The bits are defined as follows: +-----+----------+---------------------------------------------------------+ | BIT | Mnemonic | Description | +-----+----------+---------------------------------------------------------+ | 7 | Reserved | Always one. | | 6 | Reserved | Always zero. | | 5 | Reserved | Always one. | | 4 | DRV | 0 to select primary drive, 1 to select secondary drive. | | 3 | HS3 | MSB of head number. | | 2 | HS2 | | | 1 | HS1 | | | 0 | HS0 | LSB of head number. | +-----+----------+---------------------------------------------------------+ Upon command completion this register is updated to refplect the head number currently selected.1F7: Read: STATUS REGISTER Contains information about the status of the drive and controller. The contents of this register are updated at the completion of each command. When the busy bit is set, no other bits in the Command Block Registers are valid. When the busy bit is not set, the information in the Status Register and Command Block Registers is valid. +-----+----------+----------------------------------------------------------+ | BIT | Mnemonic | Description | +-----+----------+----------------------------------------------------------+ | 7 | BUSY | Busy bit. Set by the controller logic of the drive when | | | | ever the drive has access to and the host is locked out | | | | of the Command Block Registers. Set under the following | | | | conditions: | | | | o Within 400 nsec after the negation of RESET or after | | | | SRST is set in the Device Control Register. After a | | | | reset it is recomended that BUSY be set no more than | | | | 30 seconds. | | | | o Within 400 nsec of a host write to the Command | | | | Register with a Recalibrate, Read Long, Read Buffer, | | | | Read, Read Verify, Initialize Drive Parameters, Seek | | | | Identify Drive, or Execute Drive Diagnostic command. | | | | o Within 5 microseconds following the transfer of 512 | | | | bytes of data during the execution of a Write, Write | | | | Buffer or Format Track command; or 512 bytes of data | | | | and the appropriate number of ECC bytes during the | | | | execution of a Write Long command. | | | | When BUSY is set no Command Block Register can be | | | | written too and a read of any Command Block Register | | | | returns the contents of the Status Register. | | | | | | 6 | DRDY | Drive Ready bit. Indicates that the drive is ready to | | | | accept commands. When and error occurs, this bit stays | | | | unchanged until the host reads the Status Register then | | | | again indicates that hte drive is ready. On power up, | | | | this bit should be cleared and should remain cleared | | | | until the drive is up to speed and ready to accept a | | | | command. | | | | | | 5 | DWF | Drive Write Fault bit. When an error occurs, this bit | | | | remains unchanged until the host reads the Status | | | | Register, then again indicates the current write fault | | | | status. | | | | | | 4 | DSC | Drive Seek Complete bit. This bit is set when a seek | | | | operation is complete and the heads are settled over a | | | | track. When an error occurs, this bit remains unchanged | | | | until the host reads the Status Register, then again it | | | | indicates the current seek complete status. | | | | | | 3 | DRQ | Data Request bit. When set it indicates that the drive | | | | is ready to transfer a word or byte of data between the | | | | host and the data port. | | | | | | 2 | CORR | Corrected Data bit. When a correctable data error has | | | | been encountered and the data has been corrected, this | | | | bit is set. This condition does not terminate a multi | | | | sector read operation. | | | | | | 1 | INDEX | Index bit. Set when the index mark is detected once per | | | | disk revolution. | | | | | | 0 | ERROR | Error bit. When set indicates that the previous command | | | | ended in an error. The other bits in the Error Register | | | | and Status Register contain additional information about | | | | the cause of the error. | +-----+----------+----------------------------------------------------------+1F7: Write: COMMAND REGISTER When the host request a command it is transferred to the hard drive through an eight bit code written to the command register. As soon as the drive receives a command in its command register, it begins execution of the command. The following table lists the commands in alphabetical order and the parameters for each executable command: +--------+---------------------------------+-----------------+ | Command| Command Description | Parameters Used | | Code | | PC SC SN CY DH | +--------+---------------------------------+-----------------+ | 98h @ | Check Power Mode | V D | | E5h @ | Check Power Mode (same as 98h) | V D | | 90h | Execute Drive Diagnostic | D+ | | 50h | Format Track | V V | | ECh @ | Identify Drive | D | | 97h @ | Idle | V D | | E3h @ | Idle (same as 97h) | V D | | 95h @ | Idle Immediate | D | | E1h @ | Idle Immadiate (same as 95h) | D | | 91h | Initialize Drive Parameters | V V | | E4h @ | Read Buffer | D | | C8h @ | Read DMA With Retry | >> Unknown << | | C9h @ | Read DMA | >> Unknown << | | C4h @ | Read Multiple | V V V V | | 20h | Read Sectors With Retry | V V V V | | 21h | Read Sectors | V V V V | | 22h | Read Long With Retry | V V V V | | 23h | Read Long | V V V V | | 40h | Read Verify Sectors With Retry | V V V V | | 41h | Read Verify Sectors | V V V V | | 1Xh | Recalibrate | D | | 7Xh | Seek | V V | | EFh @ | Set Features | V D | | C6h @ | Set Multiple Mode | V D | | 99h @ | Set Sleep Mode | D | | E6h @ | Set Sleep Mode (same as 99h) | D | | 96h @ | Standby | V D | | E2h @ | Standby (same as 96h) | V D | | 94h @ | Standby Immediate | D | | E0h @ | Standby Immediate (same as 94h) | D | | 8Xh | Vendor Unique | >> Unknown << | | 9Ah | Vendor Unique | >> Unknown << | | C0h | Vendor Unique | >> Unknown << | | C1h | Vendor Unique | >> Unknown << | | C2h | Vendor Unique | >> Unknown << | | C3h | Vendor Unique | >> Unknown << | | F5h | Vendor Unique | >> Unknown << | | F6h | Vendor Unique | >> Unknown << | | F7h | Vendor Unique | >> Unknown << | | F8h | Vendor Unique | >> Unknown << | | F9h | Vendor Unique | >> Unknown << | | FAh | Vendor Unique | >> Unknown << | | FBh | Vendor Unique | >> Unknown << | | FCh | Vendor Unique | >> Unknown << | | FDh | Vendor Unique | >> Unknown << | | FEh | Vendor Unique | >> Unknown << | | FFh | Vendor Unique | >> Unknown << | | E8h @ | Write Buffer | D | | CAh @ | Write DMA With Retry | >> Unknown << | | CBh @ | Write DMA | >> Unknown << | | C5h @ | Write Multiple | V V V V | | E9h @ | Write Same | >> Unknown << | | 30h | Write Sectors With Retry | V V V V | | 31h | Write Sectors | V V V V | | 32h | Write Long With Retry | V V V V | | 33h | Write Long | V V V V | | 3Ch @ | Write Verify | V V V V | +--------+---------------------------------+-----------------+ KEY FOR SYMBOLS IN ABOVE TABLE: PC Register 1F1: Write Precompensation SC Register 1F2: Sector Count SN Register 1F3: Sector Number CY Register 1F4+1F5: Cylinder low + high DH Register 1F6: Drive / Head @ These commands are optional and may not be supported by some drives. D Only DRIVE parameter is valid, HEAD parameter is ignored. D+ Both drives execute this command regardless of the DRIVE parameter. V Indicates that the register contains a valid paramterer. Commands with >> Unknown << Parameters are not described in this document. If a parameter is blank, then the command does not require the contents of that register.3F6: Read: Alternate Status Register Contains the same information as the Status Register in the Command Block. Reading the Alternate Status Register does not imply an interrupt acknowledge from the host or clear a pending interrupt. See the description of the Status Register above for a definition of bits in this register.3F6: Write: Device Control Register The bits in the Device Control Register are lister in the table below: +-----+----------+----------------------------------------------------------+ | BIT | Mnemonic | Description | +-----+----------+----------------------------------------------------------+ | 7 | Reserved | | | 6 | Reserved | | | 5 | Reserved | | | 4 | Reserved | | | 3 | 1 | Always set. | | 2 | SRST | Host Software Reset bit. When this bit is set the drive | | | | is held reset. If two drives are daisy chained on the | | | | interface, this bit resets both drives simultaneously. | | | | | | 1 | nIEN | Drive Interrupt Enable bit. The enable bit for the drive | | | | interrupt to the host. When nIEN is 0 or the drive is | | | | selected the host interrupt signal INTRQ is enabled | | | | through a tri state buffer to the host. When nIEN is 1 | | | | or the drive is not selected the host interrupt signal | | | | INTRQ is in a hig himpedance state regardless of the | | | | presence or absence of a pending interrupt. | | | | | | 0 | 0 | Always clear. | +-----+----------+----------------------------------------------------------+3F7: Read: Drive Address Register This port returns the drive select and head select addresses for the drive currently selected. The Drive Address bits are listed in the table below: +-----+----------+------------------------------------------------------+ | BIT | Mnemonic | Description | +-----+----------+------------------------------------------------------+ | 7 | HiZ | This bit is in high impedance when read. | | 6 | nWTG | Write Gate bit. When a write to the hard drive is in | | | | progress, nWTG is 0 | | 5 | nHS3 | Negated MSB of head number | | 4 | nHS2 | | | 3 | nHS1 | | | 2 | nHS0 | Negated LSB of head number. | | 1 | nDS1 | Drive 1 Select bit. When 0, Drive 1 is selected. | | 0 | nDS0 | Drive 0 Select bit. When 0, Drive 0 is selected. | +-----+----------+------------------------------------------------------+ ------------------------------------------------------------------------9. Command DescriptionsThe drive decodes and executes commands loaded into the Command Register. Inapplications involving two hard drives, both drives receive all commands butonly the selected drive executes commands. The recommended procedure forexecuting a command on the selected drive is: 1. Wait for drive to clear BUSY. 2. Load required parameters in the Command Block Registers. 3. Activate the Interrupt Enable (nIEN) bit. 4. Wait for drive to set DRDY. 5. Write the command code to the Command Register.Execution of the command begins as soon as the drive loads the Command BlockRegister. The remainder of this section describes the function of eachcommand.90h: Execute Drive Diagnostic Performs internal diagnostic tests implemented by the drive. Drive 0 sets BUSY within 400 nsec of the receipt of the command. If Drive 1 is present: o Both drives execute diagnostics. o Drive 0 waits up to 5 seconds for Drive 1 to assert PDIAG- o If Drive 1 does not assert PDIAG-, indicatinf a failure, Drive 0 appends 80h with its own diagnostic status. o If the host detects a Drive 1 diagnostic failure when reading Drive 0 status it sets the DRV bit then reads the Drive 1 status. If Drive 1 is not present: o Drive 0 reports only its own diagnostic results. o Drive 0 clears BUSY and generates an interrupt. If Drive 1 fails diagnostics, Drive 0 appends 80h with its own diagnostic status and loads that code in the Error Register. If Drive 1 passes its diagnostics or no Drive 1 is present, Drive 0 appends 00h with its own diagnostic status and loads that in the Error Register. The Diagnostic Code written to the Error Register is a unique 8 bit code as listed below. +------+----------------------------------+ | Code | Description | +------+----------------------------------+ | 01 | No error detected. | | 02 | Formatter device error. | | 03 | Sector buffer error. | | 04 | ECC circuitry error. | | 05 | Controller microprocessor error. | | 8X | Drive 1 failed. | +------+----------------------------------+50h: Format Track The track address is specified in the Sector Count Register. When the drive accepts this command, it sets the DRQ bit then waits for the host to fill the sector buffer. When the buffer is full, the drive clears DRQ, sets BUSY and begins command execution.ECh: Identify Drive This command enables the host to receive paramater information from the drive. When the host issues this command, the drive sets BUSY, stores the required parameter information in the sector buffer, sets DRQ and generates an interrupt. The host then reads the information from the sector buffer. The table below defines the words stored in the buffer. All reserved fields should be zeros. +-------+-----------------------------------------------------------------+ | Word | Description | +-------+-----------------------------------------------------------------+ | 00h | Bit mapped general configuration information. True when bit set | | | Bit 15: Reserved for non magnetic drives. &nbs Link to comment Share on other sites More sharing options...
King_V Posted July 14, 2006 Author Share Posted July 14, 2006 Forgive my inexperience with this, but am I correct in assuming, based on the above explanations, that this requires either assembly code, or in some other way a binary executable, and direct-reading of particular memory locations?My experience working with DOS is extremely minimal, and pretty much limited thus far to .BAT files, so I wanted to make sure I understood what was going on before tinkering with anything. Link to comment Share on other sites More sharing options...
LLXX Posted July 14, 2006 Share Posted July 14, 2006 (edited) Forgive my inexperience with this, but am I correct in assuming, based on the above explanations, that this requires either assembly code, or in some other way a binary executable, and direct-reading of particular memory locations?My experience working with DOS is extremely minimal, and pretty much limited thus far to .BAT files, so I wanted to make sure I understood what was going on before tinkering with anything.Yes, you'll need to learn a little bit of Asm. It isn't that hard though - here's a little program (11 bytes) that just returns the number of drives according to this method:The byte at 0040:0075 is also "number of fixed disk drives", according to the IBM PC AT Technical Reference Manual.mov al, 40mov ds, ax; segment at 40mov al, [0075]; get # drivesmov ah, 4cint 21; return to DOS with errorlevel=# drives Edited July 14, 2006 by LLXX Link to comment Share on other sites More sharing options...
No6 Posted July 14, 2006 Share Posted July 14, 2006 All,Well, put my project on hold a bit before, but now I'm getting back into it.I want to essentially create a Win98Lite boot CD of sorts.However, what I've been searching for on the web and can't quite get a handle on how to do, is some method that will give me the following:1) List of hard drives on the system (or the last hard drive) that are NOT cd drives.2) List of CD drives on the system.Anyone know how this can be done? I've found a couple of batch file programs that are supposed to be able to show all the drives that exist, but they don't seem to work reliably.A while ago I found this thread. The objective of the script is different, but in it you'll find references to what you're asking. The script works well and it's well documented, you'll just have to dedicate some time to it to discover how it works. I used parts of it to identify built-in removable drives (mem slots) and remove them because they were interfering with my unattended installation.http://www.msfn.org/board/index.php?showtopic=18087 Link to comment Share on other sites More sharing options...
jaclaz Posted July 15, 2006 Share Posted July 15, 2006 (edited) @No6That script MapDrive.cmd uses DISKPART, i.e. a XP tool, and a number of features that only NT based OS have in their batch interpreter.@King_VI presume in your project you somehow boot into DOS, so that you can use DOS batch files only.If you can explain in more detail when this happens (i.e. in autoexec.bat BEFORE loading mscdex or shsucdx or after it) and exactly what you need this for, maybe I can give you a couple of ideas.jaclaz Edited July 15, 2006 by jaclaz Link to comment Share on other sites More sharing options...
Petr Posted July 15, 2006 Share Posted July 15, 2006 I don't know if it could help you but all bootable setup CDs and bootable setup floppy disks for Windows 98 contains utility called FINDCD.EXE and here is a fragment from AUTOEXEC.BAT showing how to start setup from CD-ROM if you don't know the drive letter in advance:set CDROM=FOO23FINDCD.EXEif "%CDROM%"=="FOO23" goto NOCDROMpath=a:\;%CDROM%\%CDROM%cd \WIN98echo.OEMSETUP.EXEApparently it puts the drive letter to the environment variable "CDROM".Petr Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now