Скачиваний:
14
Добавлен:
16.05.2015
Размер:
110.08 Кб
Скачать

2.4. Интерфейс int 13h (дисковый ввод-вывод)

Управлять дисками можно как через порты ввода/вывода, так и через BIOS. Порты очень интересны, однако BIOS программируется на порядок проще, к тому же он поддерживает множество разнокалиберных накопителей, абстрагируя нас от конструктивных особенностей каждой конкретной модели винчестера.

Сервис INT 13h предоставляет прямой доступ к адаптерам дискеты и твердого диска. Рекомендуется там, где возможно, использовать INT 25h и INT 26h, чтобы предоставить драйверам устройств DOS выполнять всю низкоуровневую обработку. Разумеется, для таких операций, как форматирование диска или установка защиты от копирования, прерывание INT 13h может оказаться единственной альтернативой.

  1. Листинг программы

%TITLE "Загрузчик OS"

IDEAL

MODEL tiny

DATASEG

KernelSeg EQU 01000h

color DB 01Fh

string DB "Welcome to OS",0

loading DB "System now loading... please wait...",0

BytesPerRowa=80*2

rowa=0

LABEL ScRow Word

REPT 25

DW (rowa*BytesPerRowa)

rowa=rowa+1

ENDM

CODESEG

ORG 100h ; Данные из boot сектора грузятся по адрессу

Start: jmp Start1 ; 0000:7C00, следовательно мы должны писать

ORG 07C00h ; под этот адрес.

Start1: jmp Begin ; безусловный переход

; EB 3C 90

; Данные о дискете для совместимости с DOS

nop

OEMName DB 29h,63h,7Eh,26h,49h,49h,48h,43h ; Аббревиатура и номер версии ОС

SectSize DW 00200h ; Число байт на сектор

ClustSize DB 001h ; Число секторов на кластер

ResSecs DW 00001h ; количество резервных секторов (1)

FatCnt DB 002h ; Число копий FAT (2)

RootSiz DW 000E0h ; Размер корневой директории (224)

TotSecs DW 00B40h ; Общее число секторов

Media DB 0F0h ; Тип носителя информации

FatSize DW 00009h ; размер одной копии FAT (9 секторов)

TrkSecs DW 00012h ; Число секторов на дорожку

HeadCnt DW 00002h ; Число головок

HidnSec DW 00000h ; количество "скрытых" секторов (0)

; Мои переменные

AbsSectNum DW 0

AbsHeadNum DW 0

Begin: ; Рамка

mov cx,00101h

mov dx,0164Dh

call Ramka

; Вывод строки

lea si,[String]

mov dx,031Ch

call print

; Вывод строки

lea si,[loading]

mov dx,0503h

call print

; Читаем ядро

mov ax,KernelSEG

mov es,ax

mov di,100h ; Entry Point - KernelSEG:100h

mov dx,33 ; Первый сектор с данными (128 секторов ядра)

nextsect: push dx es di

call ReadSect

pop di es dx

add di,512

inc dx

cmp dx,160

jne nextsect ; переход, если не равно

call far KernelSEG:0100h

; ReadKey

int 20h

; Чтение сектора (DX=номер сектора). Зная абсолютный номер сектора, нам надо его преобразовать в номер головки, дорожки и сектора.чтения кластера в определённую область памяти

; ES:DI - куда читать

PROC ReadSect

push di es

; Начало расчета сектора/дорожки/головки (нахождение абсолютного сектора)

push cs

pop ds

mov cx,[TrkSecs] ; количество секторов на дорожку

mov si,dx

; tmp=(Sect/Sectors);

mov ax,si

xor dx,dx

div cx

mov di,ax

; Sec=Sect-(tmp*Sectors)+1;

mov ax,di

imul cx

mov dx,si

sub dx,ax

inc dx

mov [AbsSectNum],dx

; Hea=tmp & 1;

mov ax,di

and ax,1

mov [AbsHeadNum],ax

; Trk=(Sect-(Hea*Sectors)-(Sec-1))/(Sectors*2);

imul cx

push ax

mov ax,si

pop dx

sub ax,dx

mov dx,[AbsSectNum]

dec dx

sub ax,dx

mov dx,cx

shl dx,1

push ax

push dx

xor dx,dx

pop bx

pop ax

div bx ; AX = AbsTrackNum

; Конец расчетов

mov cx,ax

mov al,cl

shr cx,1

and cl,0C0h

mov ch,al

and cx,0FFC0h

mov ax,[AbsSectNum] ; -5-4-3-2-1-0-9-8-7-6-5-4-3-2-1-0-

or cl,al ; CX = |c|c|c|c|c|c|c|c|C|c|S|s|s|s|s|s|

pop es bx ; ES:BX = Куда считывать

mov dx,[AbsHeadNum]

mov dh,dl ; Номер головки

mov dl,0 ; Номер диска 0 = A

mov al,1 ; Количество считываемых секторов

mov ah,2 ; Номер функции

int 13h

ret

ENDP ReadSect

; Вывод строки ds:di #########################################################

PROC print

mov ax,0B800h

mov es,ax

call SetVidAddr

print1: mov ah,[Color]

mov al,[ds:si]

or al,al

je prnend

mov [es:di],ax

inc di

inc di

inc si

jmp print1

prnend: ret

ENDP print

; Установить адресс видеопамяти ##############################################

PROC SetVidAddr ;подготовить адресс видеопамяти.

xor bh, bh ;dx - координаты

mov bl, dh ;Возвращяет в di адресс

shl bx, 1

mov di, [ScRow+bx]

xor dh, dh

shl dx, 1

add di, dx

ret

ENDP SetVidAddr

; Рамка ######################################################################

Ramka: mov ax,0B800h

mov es,ax

or dl,dl ; [ch] - Y [cl] - X

je RamkaEnd ; [dh] - Y [dl] - X

or dh,dh

je RamkaEnd

mov ah,[Color]

dec dl

dec dh

xor bh,bh

mov bl,ch

push dx ax

mov dx,160

mov ax,bx

mul dx

mov bx,ax

pop ax dx

xor ch,ch

shl cx,1

add bx,cx

mov di,bx ;[di] - адресс верхнего-левого

push di

mov al,"г"

stosw

mov al,"="

xor ch,ch

mov cl,dl

rep stosw

mov al,"¬"

stosw

pop di

mov cl,dh

xor ch,ch

Ramka_1: add di,160

push di

push cx

mov al,"¦"

stosw

mov al," "

xor ch,ch ; обнуление ch

mov cl,dl

rep stosw

mov al,"¦"

stosw

pop cx ;восстановление регистра

pop di

loop Ramka_1

add di,160

mov al,"L"

stosw

mov al,"="

xor ch,ch

mov cl,dl

rep stosw ; выводим(запись двух символов) столько раз, сколько указано в сх

mov al,"-"

stosw

RamkaEnd: ret

END Start

Соседние файлы в папке Курсовая. Разработка внесистемного загрузчика первой фазы на дискете, вызываемого из BIOS (эмуляция IPL1)