; ; hdzero (Zeros a whole hard disk) ; ; $Id: hdzero.asm 8 2004-11-08 07:13:24Z guillem $ ; ; Copyright (C) 2000, 2001 Guillem Jover ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software Foundation, ; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ; ; if you want real functionality enable this %define DANGER org 0x100 section .text main: ; initialize the bss section to zero xor ax, ax mov di, bss_start mov cx, bss_size/2 rep stosw call parse_args cmp byte [force], 0 jne .do_zero mov si, msg_sure call puts mov dl, [drive] call putb mov si, msg_sure_end call puts xor ah, ah int 0x16 and al, 0xdf ; to uppercase cmp al, 'Y' je .do_zero mov si, msg_cancel call puts jmp .end .do_zero: call putnl call hd_zero .end: mov ax, 0x4c00 int 0x21 ; ; Output functions ; ; function: puts(asciz) ; input: ; ds:si -> string puts: push ax .next: lodsb or al, al je .end call putc jmp short .next .end: pop ax ret ; function: putdec(word) ; input: ; ax -> word to write in decimal putdec: push bp mov bp, sp sub sp, 30 push es mov bx, ds mov es, bx mov di, bp sub di, 2 std push ax xor al, al ; Mark \0 end of an ASCIZ stosb pop ax mov cx, 10 .next: xor dx, dx div cx add dx, 0x30 xchg ax, dx stosb xchg ax, dx cmp ax, 0 jnz .next cld pop es mov si, di inc si call puts mov sp, bp pop bp ret ; function: putb(byte) ; input: ; dl -> byte to write putb: push dx push cx mov cl, 4 shr dl, cl call putdigit pop cx pop dx ; function: putdigit(byte) ; input: ; dl -> low nibble to write putdigit: mov ax, 0x0e0f and al, dl add al, 0x90 daa add al, 0x40 daa int 0x10 ret putnl: mov al, 0xD call putc mov al, 0xA ; functin: putc(char) ; input: ; al -> char to write putc: push bx mov bx, 0x0007 mov ah, 0xE int 0x10 pop bx ret ; ; Parsing functions ; ; function: parse_error(byte) ; input: ; ah -> bios return status parse_error: cmp ah, 0 jnz .error ret .error: mov si, bios_error .next: lodsb cmp al, ah je .print mov al, 0 xor cx, cx mov di, si repne scasb mov si, di jmp .next .print: push si mov si, msg_bios_error call puts pop si call puts mov al, 1 jmp main.end ; function: parse_drive(byte) ; desc: Converts a hex char to a nibble ; output: ; ah <- hex byte parse_drive: xor ah, ah call .scan_nibble mov cl, 4 ror ax, cl lodsb .scan_nibble: cmp al, '0' jb .invalid cmp al, '9' ja .letter sub al, '0' jmp .return .letter: and al, 0xdf ; to upper case cmp al, 'A' jb .invalid cmp al, 'F' ja .invalid sub al, 'A' - 10 .return or al, ah ret .invalid: mov si, msg_err_invalid call puts jmp main.end ; function: parse_args(void) parse_args: mov si, 0x81 .next: lodsb cmp al, 0xd je .return cmp al, ' ' je .next cmp al, '-' je .arg call parse_drive mov [drive], al jmp short .next .arg: lodsb cmp al, 0xd je .return .arg_force: cmp al, 'f' jne .arg_version mov byte [force], 1 jmp short .next .arg_version: cmp al, 'v' jne .arg_usage call version .arg_usage: call usage .return: ret .syntax_error: mov si, msg_err_syntax call puts jmp main.end ; function: hd_zero(void) hd_zero: mov si, msg_reset call puts mov dl, [drive] mov ah, 0x0d int 0x13 call parse_error mov si, msg_ok call puts mov si, msg_info mov dl, [drive] xor di, di mov es, di mov ah, 0x8 int 0x13 call parse_error mov al, cl and al, 0x3f mov [sect], al xchg ch, cl rol ch, 1 rol ch, 1 and ch, 2 mov [cyl], cx mov [head], dh mov si, msg_chs call puts mov ax, [cyl] call putdec mov al, ',' call putc xor ah, ah mov al, [head] call putdec mov al, ',' call putc xor ah, ah mov al, [sect] call putdec mov si, msg_ok call puts mov si, msg_write call puts .cyl_loop: .head_loop: mov bx, buf mov cx, [cyl] xchg ch, cl ror cl, 1 ror cl, 1 or cl, 1 mov al, [sect] mov dh, [head] mov dl, [drive] mov ah, 3 %ifdef DANGER int 0x13 %endif xor ah, ah call parse_error dec byte [head] cmp byte [head], 0 jnz .head_loop mov al, '.' call putc dec word [cyl] cmp word [cyl], 0 jnz .cyl_loop mov si, msg_ok call puts ret usage: mov si, msg_help call puts mov al, 1 jmp main.end version: mov si, msg_version call puts xor al, al jmp main.end section .bss bss_start: force resb 1 buf resb 512 info resb 10 cyl resw 1 head resb 1 sect resb 1 bss_size equ ($-$$) section .data drive db 0x80 msg_version db 'hdzero 1.0', 0xd, 0xa, 0 msg_help db 'usage: hdzero [options] drive', 0xd, 0xa db ' drive 80+x for hard drives', 0xd, 0xa db ' 00+x for floppy drives', 0xd, 0xa db ' default drive = 80 (in hex)', 0xd, 0xa db ' -f action without confirmation', 0xd, 0xa db ' -h this help', 0xd, 0xa db ' -v version', 0xd, 0xa, 0 msg_reset db 'Resetting disk drive...', 0 msg_info db 'Getting disk information...', 0 msg_chs db ' CHS: ', 0 msg_write db 'Writing zeroes to disk' , 0 msg_sure db 'Really sure to zero drive (', 0 msg_sure_end db ') [yn] ? ', 0 msg_ok db ' Ok', 0xd, 0xa, 0 msg_cancel db 'Cancelled.', 0xd, 0xa, 0 msg_err_syntax db 'error: invalid syntax', 0xd, 0xa, 0 msg_err_invalid db 'error: invalid drive number', 0xd, 0xa, 0 msg_bios_error db 'bios error: ', 0 bios_error db 1, 'invalid function', 0 db 2, 'address mark not found', 0 db 3, 'disk write-protected', 0 db 4, 'sector not found/read error', 0 db 5, 'reset failed', 0 db 6, 'disk changed', 0 db 7, 'drive parameter activity failed', 0 db 8, 'DMA overrun', 0 db 9, 'data boundary error', 0 db 0xA, 'bad sector detected', 0 db 0xB, 'bad track detected', 0 db 0xC, 'unsupported track or invalid media', 0 db 0xE, 'control data address mark detected', 0 db 0xF, 'DMA arbitration level out of range', 0 db 0x10, 'uncorrectable CRC or ECC error on read', 0 db 0x11, 'data ECC corrected', 0 db 0x20, 'controller failure', 0 db 0x40, 'seek failed', 0 db 0x80, 'timeout', 0 db 0xAA, 'drive not ready', 0 db 0xBB, 'undefined error', 0 db 0xCC, 'write fault', 0 db 0xE0, 'status register error', 0 db 0xFF, 'sense operation failed', 0 db 0x0, 'unknown error', 0