;=============================================================== ; BOOT SECTOR ; [http://www.karig.net/000d.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 mov ax, 0x1000 mov ss, ax mov sp, 0xFFFE sti ; ------ Load other sectors into memory. ; ------ [http://www.karig.net/000d.html] push dx .0: xor ax, ax int 0x13 jc .0 pop dx mov al, initial_count mov dh, initial_head mov ch, initial_cylinder mov bx, initial_address mov cl, initial_sector mov ah, 2 .1: pusha int 0x13 popa jc .1 mov al, sectors_per_track sub bx, bytes_per_track dec dh jz .9 mov dh, 1 dec ch jns .1 .9: ; ------ Test new code. ; ------ [http://www.karig.net/000d.html] testcode: mov bx, 0xFFE0 call dump_16 call dump_16 ; ------ Halt computer. jmp $ ; ------ DATA for the test code. recdata: db "Here's some text" ; 16 chars long ; ROUTINES to print to the screen. ; ------ [http://www.karig.net/0008.html] clear_screen: mov ax, 3 int 0x10 xor bh, bh xor dx, dx mov ah, 2 int 0x10 ret 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.) ; ------ [http://www.karig.net/000d.html] times 508 - ($-$$) db 0x90 ; nop jmp short $+4 db 0x55, 0xAA ; ------ (Simulate a 33KB system loader.) ; ------ [http://www.karig.net/000d.html] times (512 * 65) - 16 db 0x90 ; nop db "Loader is loaded" ; for testing ; ------ (Equates and assembly-time calculations.) ; ------ [http://www.karig.net/000d.html] %if (($-$$) % 512) times 512 - (($-$$) % 512) db 0 %endif sector_total equ ($-$$)/512 sectors_per_track equ 18 heads_per_track equ 2 bytes_per_sector equ 512 bytes_per_track equ bytes_per_sector * sectors_per_track initial_sector equ 1 initial_platter equ (sector_total - 1) / sectors_per_track initial_cylinder equ initial_platter / heads_per_track initial_head equ initial_platter % heads_per_track initial_address equ initial_platter * bytes_per_track + 0x7C00 initial_count_test equ sector_total % sectors_per_track %if initial_count_test initial_count equ initial_count_test %else initial_count equ sectors_per_track %endif