Пишем свой загрузочный сектор - Процедура загрузки секторов
ОГЛАВЛЕНИЕ
Страница 3 из 4
Процедура загрузки секторов
Теперь разберем процедуру загрузки секторов. Процедура получает номер сектора в dx:ax (нумерация с нуля) и преобразует его к формату CSH (цилиндр, сектор, сторона), используемому прерыванием BIOS int 0x13.
<>; *************************************************
; * Чтение секторов с диска *
; *************************************************
; * Входные параметры: *
; * dx:ax - (LBA) номер сектора *
; * cx - количество секторов для чтения *
; * es:bx - адрес буфера *
; *************************************************
; * Выходные параметры: *
; * cx - Количество не прочтенных секторов *
; * es:bx - Указывает на конец буфера *
; * cf = 1 - Произошла ошибка при чтении *
; *************************************************
ReadSectors ;proc
next_sector:
; Читаем очередной сектор
mov byte [bp+fails], 3 ; Количество попыток прочесть сектор
try:
; Очередная попытка
pusha
; Преобразуем линейный адрес в CSH
; dx:ax = a1:a0
xchg ax, cx ; cx = a0
mov ax, [byte bp+BPB_SecPerTrk]
xchg ax, si ; si = Scnt
xchg ax, dx ; ax = a1
xor dx, dx
; dx:ax = 0:a1
div si ; ax = q1, dx = c1
xchg ax, cx ; cx = q1, ax = a0
; dx:ax = c1:a0
div si ; ax = q2, dx = c2 = c
inc dx ; dx = Sector?
xchg cx, dx ; cx = c, dx = q1
; dx:ax = q1:q2
div word [byte bp+BPB_NumHeads] ; ax = C (track), dx = H
mov dh, dl ; dh = H
mov ch, al
ror ah, 2
or cl, ah
mov ax, 0201h ; ah=2 - номер функции, al = 1 сектор
mov dl, [byte bp+BS_DrvNum]
int 13h
popa
jc Failure ; Ошибка при чтении
; Номер следующего сектора
inc ax
jnz next
inc dx
next:
add bx, [byte bp+BPB_BytsPerSec]
dec cx ; Все сектора прочтены?
jnz next_sector ; Нет, читаем дальше
return:
ret
Failure:
dec byte [bp+fails] ; Последняя попытка?
jnz try ; Нет, еще раз
; Последняя, выходим с ошибкой
stc
ret
;ReadSectors endp>
Осталось всего ничего:
; Сообщения об ошибках
NotFound: ; Файл не найден
mov si, BOOT_ADDR + mLoaderNotFound
call print
jmp short die
DiskError: ; Ошибка чтения
mov si, BOOT_ADDR + mDiskError
call print
;jmp short die
die: ; Просто ошибка
mov si, BOOT_ADDR + mReboot
call print
_die: ; Бесконечный цикл, пользователь сам нажмет Reset
jmp short _die
; Процедура вывода ASCIIZ строки на экран
; ds:si - адрес строки
print: ; proc
pusha
print_char:
lodsb ; Читаем очередной символ
test al, al ; 0 - конец?
jz short pr_exit ; Да конец
; Нет, выводим этот символ
mov ah, 0eh
mov bl, 7
int 10h
jmp short print_char ; Следующий
pr_exit:
popa
ret
;print endp
; Перевод строки
%define endl 10,13,0
; Строковые сообщения
mLoading db 'Loading...',endl
mDiskError db 'Disk I/O error',endl
mLoaderNotFound db 'Loader not found',endl
mReboot db 'Reboot system',endl
; Выравнивание размера образа на 512 байт
times 499-($-$$) db 0
LoaderName db 'BOOTOR ' ; Имя файла загрузчика
BootMagic dw 0xAA55 ; Сигнатура загрузочного сектора