;=============================================================== ; BOOT SECTOR ; [http://www.karig.net/001f.html] ;=============================================================== [ORG 0x7C00] [BITS 16] main: ; ------ Straighten out segment registers. ; ------ [http://www.karig.net/0002.html] jmp word 0:segzero segzero: mov ax, cs mov ds, ax mov es, ax mov fs, ax mov gs, ax ; ------ Set up stack. cli in al, 0x70 or al, 0x80 out 0x70, al mov ax, 0x1000 mov ss, ax xor sp, sp in al, 0x70 and al, 0x7F out 0x70, al sti ; ------ Clear screen. call clear_screen ; ------ Read from hard drive using BIOS. mov ax, 0x0201 mov bx, 0x1000 mov cx, 0x13FF ; ch = cylinder, cl = sector mov dx, 0x7F80 ; dh = head push bx int 0x13 mov [0x1F00], ah ; ------ Dump sector. pop bx call dump_16 call dump_16 call dump_16 call dump_16 call dump_16 call dump_16 call dump_16 call dump_16 call next_row ; Dump error byte. mov bx, 0x1F00 call dump_16 ; ------ Read from hard drive using ports. ; ------ [http://www.karig.net/001f.html] cli ; Send command to read one sector. mov dx, 0x1F2 mov al, 1 ; # sectors to transfer inc dx ; mov dx, 0x1F3 mov eax, 0x60F5FF ; LBA out dx, al inc dx ; mov dx, 0x1F4 shr eax, 8 out dx, al inc dx ; mov dx, 0x1F5 shr eax, 8 out dx, al inc dx ; mov dx, 0x1F6 mov al, 0xE0 out dx, al inc dx ; mov dx, 0x1F7 mov al, 0x20 ; read with retry out dx, al ; Wait for data to be ready. .rdy: in al, dx and al, 8 jz .rdy ; Read data to buffer at address 0x2000. mov dx, 0x1F0 mov cx, 256 mov di, 0x2000 mov bx, di cld rep insw ; Get error bytes. push bx mov dx, 0x1F7 in al, dx mov [0x1F00], al mov dx, 0x1F1 in al, dx mov [0x1F01], al ; Wait for not-busy. mov dx, 0x1F7 .bsy: in al, dx and al, 0x80 jnz .bsy ; Turn off drive motor. mov dx, 0x1F7 mov al, 0x08 ; rest out dx, al sti ; Dump error bytes. mov bx, 0x1F00 call dump_16 call next_row pop bx ; ------ Dump sector. call dump_16 call dump_16 call dump_16 call dump_16 call dump_16 call dump_16 call dump_16 call dump_16 ; ------ Hang computer. jmp $ ; ROUTINES to print to the screen. ; ------ [http://www.karig.net/0008.html] clear_screen: mov ax, 3 int 0x10 xor dx, dx jmp set_pos scroll_up: mov bh, 7 xor cx, cx mov dx, (24*0x100) + 79 mov ax, (0x0600 + 23) int 0x10 ret ; ROUTINES needed to support hex dumps. ; ------ [http://www.karig.net/0009.html] byte_to_hex: xor bh, bh mov bl, al and bl, 0x0F mov ah, [.digits + bx] mov bl, al shr bl, 4 mov al, [.digits + bx] ret .digits: db "0123456789ABCDEF" print_colon: mov al, ':' jmp print_char print_space: mov al, ' ' jmp print_char print_vbar: mov al, '|' jmp print_char print_word: ; pass word in AX push ax mov al, ah call print_byte pop ax print_byte: ; pass byte in AL call byte_to_hex push ax call print_char pop ax mov al, ah ;jmp print_char print_char: xor bh, bh xor cx, cx inc cx mov ah, 0x0A int 0x10 get_pos: xor bh, bh mov ah, 3 int 0x10 next_column: inc dl cmp dl, 80 jb set_pos next_row: xor dl, dl inc dh cmp dh, 25 jb set_pos dec dh push dx call scroll_up pop dx set_pos: xor bh, bh mov ah, 2 int 0x10 ret ; ROUTINE to dump bytes to the screen. ; ------ [http://www.karig.net/0009.html] dump_16: push bx mov ax, fs call print_word call print_colon pop ax push ax call print_word call print_colon call print_space pop bx xor si, si .1: mov al, [fs:bx+si] push si push bx call print_byte call print_space pop bx pop si inc si cmp si, 16 jb .1 push bx call print_vbar call print_space pop bx xor si, si .2: mov al, [fs:bx+si] push si push bx call print_char pop bx pop si inc si cmp si, 16 jb .2 push bx call get_pos call next_row pop bx add bx, 16 ret ; ------ (Required to make this a boot sector.) times 0x1FE - ($-$$) db 0 dw 0xAA55