Пишем свой загрузочный сектор
Страница 3. Процедура загрузки секторов


 

Процедура загрузки секторов

Теперь разберем процедуру загрузки секторов. Процедура получает номер сектора в dx:ax (нумерация с нуля) и преобразует его к формату CSH (цилиндр, сектор, сторона), используемому прерыванием BIOS int 0x13.

<>; *************************************************
 ; *          Чтение секторов с диска              *
 ; *************************************************
 ; * Входные параметры:                            *
 ; * dx:ax       - (LBA) номер сектора             *
 ; * cx          - количество секторов для чтения  *
 ; * es:bx       - адрес буфера                    *
 ; *************************************************
 ; * Выходные параметры:                           *
 ; * cx       - Количество не прочтенных секторов  *
 ; * es:bx    - Указывает на конец буфера          *
 ; * cf = 1   - Произошла ошибка при чтении        *
 ; *************************************************
 ReadSectors;proc
 next_sector:
 ; Читаем очередной сектор
 movbyte [bp+fails], 3; Количество попыток прочесть сектор
 try:
 ; Очередная попытка
 pusha
 ; Преобразуем линейный адрес в CSH
 ; dx:ax = a1:a0
 xchgax, cx; cx = a0
 movax, [byte bp+BPB_SecPerTrk]
 xchgax, si; si = Scnt
 xchgax, dx; ax = a1
 xordx, dx
 ; dx:ax = 0:a1
 divsi; ax = q1, dx = c1
 xchgax, cx; cx = q1, ax = a0
 ; dx:ax = c1:a0
 divsi; ax = q2, dx = c2 = c
 incdx; dx = Sector?
 xchgcx, dx; cx = c, dx = q1
 ; dx:ax = q1:q2
 divword [byte bp+BPB_NumHeads]; ax = C (track), dx = H
 movdh, dl; dh = H
 movch, al
 rorah, 2
 orcl, ah
 movax, 0201h; ah=2 - номер функции, al = 1 сектор
 movdl, [byte bp+BS_DrvNum]
 int13h
 popa
 jcFailure; Ошибка при чтении
 ; Номер следующего сектора
 incax
 jnznext
 incdx
 next:
 addbx, [byte bp+BPB_BytsPerSec]
 deccx; Все сектора прочтены?
 jnznext_sector; Нет, читаем дальше
 return:
 ret
 Failure:
 decbyte [bp+fails]; Последняя попытка?
 jnztry; Нет, еще раз
 ; Последняя, выходим с ошибкой
 stc
 ret
 ;ReadSectorsendp
>

Осталось всего ничего:

; Сообщения об ошибках
NotFound:; Файл не найден
movsi, BOOT_ADDR + mLoaderNotFound
callprint
jmpshort die
DiskError:; Ошибка чтения
movsi, BOOT_ADDR + mDiskError
callprint
;jmpshort die
die:; Просто ошибка
movsi, BOOT_ADDR + mReboot
callprint
_die:; Бесконечный цикл, пользователь сам нажмет Reset
jmpshort _die
; Процедура вывода ASCIIZ строки на экран
; ds:si - адрес строки
print:; proc
pusha
print_char:
lodsb; Читаем очередной символ
testal, al; 0 - конец?
jzshort pr_exit; Да конец
; Нет, выводим этот символ
movah, 0eh
movbl, 7
int10h
jmpshort print_char; Следующий
pr_exit:
popa
ret
;printendp
; Перевод строки
%defineendl 10,13,0
; Строковые сообщения
mLoadingdb 'Loading...',endl
mDiskErrordb 'Disk I/O error',endl
mLoaderNotFounddb 'Loader not found',endl
mRebootdb 'Reboot system',endl
; Выравнивание размера образа на 512 байт
times 499-($-$$) db 0
LoaderNamedb 'BOOTOR     '; Имя файла загрузчика
BootMagicdw 0xAA55; Сигнатура загрузочного сектора

 
« Предыдущая статья   Следующая статья »