CodeNet / Языки программирования / Ассемблер / Пишем "многозадачную" ОС в "Real Mode"
CodeNet / Платформы / Пишем ОС / Пишем "многозадачную" ОС в "Real Mode"
CodeNet / Платформы / Пишем ОС / Пишем "многозадачную" ОС в "Real Mode"
Модуль boot.asm
%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
Оставить комментарий
Комментарии
1.
10 июня 2005, 16:22:09
А как его установить как Boot ?