MOV DX, 1F7h ;status register
LOOP1:
IN AL, DX ;sets AL to status register (which is 8 bits)

;If the first bit of the status register (BUSY) isn't 0, the device is busy,
;so keep looping until it isn't.

AND AL, 10000000xB
JNE LOOP1

;----------------------------------------------------------------------------

;Clear interrupts so something doesn't interrupt the drive or controller
;while this program is working.
CLI

;----------------------------------------------------------------------------

MOV DX, 1F7h ;status register again
LOOP2:
IN AL, DX ;sets AL to status register again

;If the second bit of the status register (DRDY) isn't 1, the device isn't
;ready, so keep looping until it is.

AND AL, 01000000xB
JE LOOP2

;----------------------------------------------------------------------------

MOV DX, 1F6h ;device/head register
MOV AL, 0 ;0 selects device 0 (master). 10h would select device 1 (slave).
OUT DX, AL ;selects master device

MOV DX, 1F7h ;command register
MOV AL, 0ECh ;"IDENTIFY DRIVE" command
OUT DX, AL ;sends the command!

;----------------------------------------------------------------------------

MOV DX, 1F7h ;status register
LOOP3:
IN AL, DX

AND AL, 00001000xB ;if DRQ is not high, the device doesn't have data for us
JE LOOP3 ;yet, so keep looking until it does!

;----------------------------------------------------------------------------

MOV DX, 1F0h ;data register
MOV DI, OFFSET buff ;points DI to the buffer we're using
MOV CX, 256 ;256 decimal. This controls the REP command.
CLD ;clear the direction flag so INSW increments DI (not decrements it)
REP INSW

;----------------------------------------------------------------------------

;We now have the string data in buff, so let's re-enable interrupts.

STI

;----------------------------------------------------------------------------

;...And now we can display the contents of buff!

MOV ES, SEG buff
MOV BX, OFFSET buff
MOV CX, 256 ;256 decimal
MOV AH, 2 ;"display output" option for INT 21
LOOP4:
MOV DL, [BX] ;moves the contents of the byte from "buff" into DL
INT 21h
INC BX
LOOPNZ LOOP4 ;does this 256 times, because CX was set to 256

mov ah,004C  ;terminate program
int 21h

buff db 256 DUP(?) ;buffer to hold the drive identification info
