page 250,150 ;Begin-------------------------------------------------------------------- ; ; DDiag.asm ; ; by: P.R. Faasse ; Hakfort 337 ; 1102LA Amsterdam ; ; Program to dump the diagnostics information of a PoFoIDE driver. ; ; update history: ; --------------- ; ; 10-08-1998: Started ; ;End---------------------------------------------------------------------- ; ------------------------------------------------------------------------ ; standard beginning of a .COM file. Seems to satisfy MASM... ; ------------------------------------------------------------------------ code segment para 'code' ; define the code segment org 0100h ; begin at offset 0100H assume cs:code, ds:code, es:code, ss:code ; all segment registers ; point to the code segment Start: jmp Main ; goto the main processing loop ;Pars--------------------------------------------------------------------- ; cr equ 0DH ; carriage return lf equ 0AH ; line-feed eos equ '$' ; ; ;End---------------------------------------------------------------------- ;Data--------------------------------------------------------------------- ; the local parameters for the program, text strings too ;------------------------------------------------------------------------- ; DriveNo db 0 ; drive number PoFoIDE drive ; text strings, a lot of them..... ; the strings for the data found: ; PartStr db "Drive Unit LBB : ",eos ; SegStr db "Seg:BootInfo : ",eos ; CHSStr db "Disk geometry : ",eos ; LBAStr db "Latest access : ",eos ; IoStr db "I/O ports : ",eos ; RegStr db "IDE Regs: Cyl Hd Sc # St Er",eos RegStr1 db " ",eos ; NewLn db cr,lf,eos ; NoPars db "usage: ddiag ",lf,cr,eos NoDriver db "PoFoIDE driver not found",lf,cr,eos ; ;End---------------------------------------------------------------------- ;Prog--------------------------------------------------------------------- ; ; The main program itself. It will first look for a PoFo driver. ; Next it will blindly pump a file-system on the drive. ; Main: ; Parse parameters mov si,081H ; si -> begin of parameters cld ; ParLp: lodsb ; cmp al,CR ; jz ParErr ; cmp al,' ' ; jz ParLp ; ; convert to upper and al,0DFH ; -> upper ; test if valid drive letter cmp al,'D' ; test A .. Z jc parerr ; cmp al,'Z'+1 ; jnc parerr ; sub al,'A' - 1 ; A -> 1; D -> 4 mov driveno,al ; jmp TstIdeDrv ; ; wrong parameters given ParErr: mov dx,offset NoPars ; give message jmp MesEx ; exit ; test if an IDE driver there for that drive TstIdeDrv: mov bl,driveno ; save drive number mov ax,04404H ; IoCtlRead mov cx,0258H ; # bytes mov dx,offset IoBuf ; int 21H ; jc NoIdeDrv ; ; test if driver there cmp word ptr IoBuf,'KP' ; test if signal there jz GoDump ; NoIdeDrv: mov dx,offset NoDriver ; error message mesex: mov ah,9 ; int 21H ; mov ax,04C01H ; exit int 21H ; ; driver found GoDump: nop ; ; give message mov dx,offset PartStr ; driver found message call Mess ; mov al,driveno ; add al,'A'-1 ; call DisChar ; mov al,':' ; call DisChar ; mov al,' ' ; call DisChar ; ; dump the information found in a readable format mov si,offset IoBuf+2 ; si -> information lodsb ; Unit call DisHexByte ; mov al,' ' ; LBB call DisChar ; lodsw ; push ax ; lodsw ; call DisHexWord ; pop ax ; call DisHexWord ; mov dx,offset SegStr ; driver segment call Mess ; and Boot info offset lodsw ; call DisHexWord ; mov al,':' ; call DisChar ; lodsw ; call DisHexWord ; mov dx,offset CHSStr ; disk's geometry call Mess ; lodsw ; disk size push ax ; lodsw ; call DisHexWord ; pop ax ; call DisHexWord ; mov al,' ' ; call DisChar ; lodsw ; C/H/S call DisHexWord ; mov al,'/' ; call DisChar ; lodsw ; call DisHexByte ; mov al,'/' ; call DisChar ; lodsw ; call DisHexByte ; ; The latest access mov dx,offset LBAStr ; call Mess ; lodsw ; LBA push ax ; lodsw ; call DisHexWord ; pop ax ; call DisHexWord ; mov al,' ' ; call DisChar ; lodsw ; CHS call DisHexWord ; mov al,'/' ; call DisChar ; lodsb ; call DisHexByte ; mov al,'/' ; call DisChar ; lodsb ; call DisHexByte ; ; I/O ports status mov dx,offset IoStr ; call Mess ; lodsw ; call DisHexWord ; mov al,' ' ; call DisChar ; lodsb ; call DisHexByte ; ; IDE registers mov dx,offset RegStr ; call Mess ; mov dx,offset RegStr1 ; call Mess ; lodsw ; call DisHexWord ; Cyl mov al,' ' ; call DisChar ; lodsb ; and al,01011111B ; remove reserved bits call DisHexByte ; Hd mov al,' ' ; call DisChar ; lodsb ; call DisHexByte ; Sc mov al,' ' ; call DisChar ; lodsb ; call DisHexByte ; # mov al,' ' ; call DisChar ; lodsb ; call DisHexByte ; St mov al,' ' ; call DisChar ; lodsb ; call DisHexByte ; Er mov ax,04c00H ; exit int 21h ; ;End---------------------------------------------------------------------- ;Routines----------------------------------------------------------------- ; ; The data display routines I use ; ;--------------------------------------------------------------------- ; Routine Mess ; purp: display a message on the console, on a new line ; in : dx -> message ; out : nothing ; uses: nothing Mess: push ax ; save registers push dx ; mov dx,offset NewLn ; print new line mov ah,9 ; int 21h ; pop dx ; push dx ; mov ah,9 ; print string int 21h ; pop dx ; pop ax ; ret ; done ;--------------------------------------------------------------------- ; Routine NewLine ; purp: make the console goto a new line ; in : nothing ; out : nothing ; uses: nothing Newline:push ax ; save registers push dx ; mov ah,9 ; print predefined string mov dx,Offset NewLn ; int 21h ; pop dx ; pop ax ; ret ; done ;-------------------------------------- ; Routine DisHexByte and DisHexWord ; purp : Writes AL or AX as hex ascii ; in : byte in AL (DisHexByte) ; word in AX (DisHexWord) ; out : nothing ; uses : nothing DisHexWord: ; save registers push ax ; ; higher byte mov al,ah ; call DisHexByte ; ; lower byte pop ax ; call DisHexByte ; ; done ret ; DisHexByte: ; save registers pushf ; push ax ; ; higher nibble shr al,1 ; shr al,1 ; shr al,1 ; shr al,1 ; call ToHex ; call DisChar ; ; lower nibble pop ax ; push ax ; and al,0FH ; call ToHex ; call DisChar ; ; restore registers pop ax ; popf ; ; done ret ; ; -------------------------------------- ; Routine ToHex ; purp : converts nibble to hex ASCII character ; in : nibble in al ; out : ASCII char in al ; uses : nothing ToHex: pushf ; and al,0FH ; make sure of 0 .. F cmp al,0AH ; jge tohex1 ; ; 0 .. 9 add al,'0' ; 0 .. 9 convert jmp tohexe ; ; A .. F tohex1: add al,('A' - 0AH) ; tohexe: popf ; ret ; ; -------------------------------------- ; Routine DisChar ; purp : Writes AL to display ; in : character in al ; out : nothing ; uses : nothing DisChar:pushf ; push ax ; push dx ; mov dl,al ; mov ah,02H ; int 21H ; disnsio:pop dx ; pop ax ; popf ; ret ; ;End---------------------------------------------------------------------- ;Buffer------------------------------------------------------------------- ; ; The I/O buffer. This buffer is used to write sector data to the ; disk. I do not store the buffer data on the disk image of the ; program because I will always put something in the buffer ; before writing it to disk. ; IoBuf equ this byte ; the I/O buffer IoBufSize equ 512 ; ; ;End---------------------------------------------------------------------- ;Tail--------------------------------------------------------------------- ; ; Note that I do not do any stack inits at all. The stackpointer ; is just left at the end of the allocated memory segment. It ; should do no harm there. ; code ends end Start ; end of the program ; ;End----------------------------------------------------------------------