%TITLE "Загрузчик GlukOS"
IDEAL
MODEL tiny
DATASEG
KernelSeg EQU 01000h
color DB 01Fh
string DB "Welcome to GlukOS v.01",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
FatCnt DB 002h
RootSiz DW 000E0h
TotSecs DW 00B40h
Media DB 0F0h
FatSize DW 00009h
TrkSecs DW 00012h
HeadCnt DW 00002h
HidnSec DW 00000h
; Мои переменные
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,2
and cl,0C0h
mov ch,al
and cx,0FFC0h
mov ax,[AbsSectNum] ; г5T4T3T2T1T0T9T8T7T6T5T4T3T2T1T0¬
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
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
|