CodeNet / Языки программирования / Ассемблер / Пишем "многозадачную" ОС в "Real Mode"
CodeNet / Платформы / Пишем ОС / Пишем "многозадачную" ОС в "Real Mode"
CodeNet / Платформы / Пишем ОС / Пишем "многозадачную" ОС в "Real Mode"
Модуль commands.asm
; Выход ###################################################################### PROC doQuit mov [QuitFLG],1 ret ENDP doQuit ; Страничка помощи ########################################################### PROC doHELP lea di,[ctable] doHelp0: mov si,di push di mov al,[di] or al,al je doHelp3 call write lea si,[plots] call write pop di doHelp1: inc di cmp [Byte Ptr di],0 jne doHelp1 inc di push di mov si,di call write lea si,[null] call writeln pop di doHelp2: inc di cmp [Byte Ptr di],0 jne doHelp2 inc di inc di inc di jmp doHelp0 doHelp3: pop di ret ENDP doHELP ; Очистка экрана ############################################################# PROC doCLS mov ch,[windowy] ;¬ mov cl,[windowx] ;¦ dec cl ;¦ mov dh,[windowHx] ;¦ inc dh ;¦ mov dl,[windowWx] ;¦ Сдвиг окна вверх inc dl ;¦ (или очистка) inc dl ;¦ mov ax,0600h ;¦ mov bh,[color] ;¦ int 10h ;- mov [Byte Ptr mainx],0 mov [Byte Ptr mainy],0 ret ENDP doCLS ; Загрузка задачи (из корня) ################################################# doStartData0 DB "Enter Task name: ",0 doStartData1 DB " ¦ Error: Task not found.",0 doStartData2 DB " ¦ Error: Absent task name.",0 doStartData3 DB " ¦ Loading task. Please wait...",0 doStartData4 DB " ¦ Error: No memory.",0 doStartData5 DB " ¦ Error: No free task descriptors.",0 doStartName DB "FILENAMEEXT" PROC doStart lea si,[doStartData0] call write call input lea si,[null] call writeln ; Не пустая-ли строка mov al,[command] or al,al je doStart2 lea di,[command] call UpperString ; Копируем строку из command в doCDSubStr1 lea di,[doCDSubStr1] lea si,[command] DoStart2_0: mov al,[cs:si] or al,al je DoStart2_1 mov [cs:di],al inc si inc di jmp DoStart2_0 DoStart2_1: mov [Byte Ptr cs:di],0 call doCDNormaliseName ; Нормализуем имя файла ; Поиск файла в каталоге call _di call FindFirst or ax,ax jne doStart3_0 DoStart2_2: lea di,[find_FileName] lea si,[doCDFileName] mov cx,11 DoStart2_4: mov al,[di] cmp al,[si] jne DoStart2_3 inc di inc si loop DoStart2_4 ; Найден файл call _ei jmp doStart5 DoStart2_3: call FindNext or ax,ax jne doStart3_0 jmp DoStart2_2 doStart3_0: lea si,[doStartData1] doStart3: call writeln call _ei ret doStart2: pop dx lea si,[doStartData2] jmp doStart3 doStart6: pop di dx lea si,[doStartData4] jmp doStart3 ; Найдено название файла в секторе ; (надо узнать начальный кластер) doStart5: mov dx,[cs:find_ClustNo] push dx push di call GetMemory or dx,dx je doStart6 push dx lea si,[doStartData3] call writeln pop dx pop di mov es,dx pop dx call _di add dx,33-2 ; 33 - первый сектор данных mov cx,127 mov di,100h doStart7: push es dx di cx call ReadSect pop cx di dx es inc dx add di,512 loop doStart7 mov [Word Ptr ES:0000h],020CDh ; int 20h ; Теперь в ES:0000 имеем задачу (точка входа ES:0100h) ; Инициализируем задачу ; Ищем первый свободный дескриптор задачи lea di,[tasks] mov cx,8 doStart9: cmp [Byte Ptr cs:di],255 je doStart8 add di,515 loop doStart9 ; Нет свободных дескрипторв (такого быть не может, но ладно) lea si,[doStartData5] jmp doStart3 ; В DI имеем адрес свободного дескриптора doStart8: mov al,[tasknum] inc al mov [tasknum],al mov [cs:di],al ; Сохраним точку входа в дескрипторе задач mov [Word Ptr cs:di+1],100h mov [cs:di+3],es ; Подготовим оба стека mov [Word Ptr es:0FFFEh],00000h ; 0 - если программа ; закончится RET'ом, то CS:IP=CS:0000, а там int 20h mov [Word Ptr es:0FFFCh],00232h ; FLAGS mov [Word Ptr es:0FFFAh],es ; CS PSP mov [Word Ptr es:0FFF8h],00100h ; IP 100h mov [Word Ptr es:0FFF6h],00111h ; DI 0000 mov [Word Ptr es:0FFF4h],00222h ; BX 0000 mov [Word Ptr es:0FFF2h],00333h ; AX 0000 mov [Word Ptr es:0FFF0h],es ; ES PSP mov [Word Ptr es:0FFEEh],es ; DS PSP mov [Word Ptr es:0FFECh],00000h ; SI 0000 mov [Word Ptr cs:di+513],0FFECh ; SS FFEC mov [Word Ptr cs:di+511],ES ; SP seg mov [Word Ptr cs:di+509],00000h ; CX 0000 mov [Word Ptr cs:di+507],00000h ; DX 0000 mov [Word Ptr cs:di+505],00000h ; BP 0000 mov [Word Ptr cs:di+9],1 ; Задаем приоритет задачи mov [Word Ptr cs:di+11],1 ; Задаем приоритет задачи call _ei ret ENDP doStart ; Выдает список задач ######################################################## doListData1 DB "Task list:",0 doListData3 DB " ",0 doListData4 DB ":",0 doListData5 DB "Task not loaded.",0 doListData6 DB "Task stoped.",0 PROC doList lea si,[doListData1] call writeln lea di,[tasks] mov bx,1 doList1: push bx di lea si,[doListData3] call write mov ax,bx xor ah,ah call writeAX lea si,[doListData3] call write pop di push di mov al,[cs:di] cmp al,255 je doList2 cmp al,254 je doList4 mov ax,[cs:di+3] call writeAX lea si,[doListData4] call write pop di push di mov ax,[cs:di+1] call writeAX lea si,[doListData3] call write pop di push di mov ax,[cs:di+11] call writeAX lea si,[doListData3] call write lea si,[null] call writeln doList3: pop di bx inc bx add di,515 cmp bx,9 jne doList1 ret doList2: lea si,[doListData5] call writeln jmp doList3 doList4: lea si,[doListData6] call writeln jmp doList3 ENDP doList ; Выгружает задачу ########################################################### doKillData0 DB "Enter task number (1-8): ",0 doKillData1 DB " ¦ Parametrs error.",0 doKillData2 DB " ¦ This task not loaded.",0 PROC doKill lea si,[doKillData0] call write call input lea si,[null] call writeln lea si,[command] cmp [Byte Ptr cs:si+1],0 jne doKill1 mov al,[Byte Ptr cs:si] cmp al,'1' jl doKill1 cmp al,'8' ja doKill1 sub al,'1' xor ah,ah push ax lea di,[tasks] mov cx,515 imul cx add di,ax mov al,[cs:di] cmp al,255 pop ax je doKill2 inc al cmp [cs:LastLineFlag],al jne doKill3 mov [Byte Ptr cs:LastLineFlag],0 doKill3: call _di mov al,255 mov [cs:di],al mov dx,[cs:di+3] call FreeMemory call _ei ret doKill1: lea si,[doKillData1] call writeln ret doKill2: lea si,[doKillData2] call writeln ret ENDP doKill ; Вывод каталога ############################################################# doDirData1 DB "------",0 doDirData2 DB "",0 doDirEnd: pop bx ret PROC doDir xor bx,bx push bx call ReadFAT mov [Word Ptr RSSData],0 call FindFirst or ax,ax jne doDirEnd test [Byte Ptr find_Attr],08h je doDirFFileName pop bx jmp Dodirnext doDirFFileName: call doDirPrintFind pop bx inc bx Dodirnext: mov dl,[cs:windowhx] dec dl cmp bl,dl jne doDir1 xor ax,ax int 16h xor bx,bx doDir1: push bx call FindNext or ax,ax jne doDirEnd test [Byte Ptr find_Attr],08h je doDirFileName pop bx jmp doDirNext doDirFileName: call doDirPrintFind pop bx inc bx jmp doDirNext ENDP doDir ; Вывод структуры find PROC doDirPrintFind ; Вывод имени файла с расширением lea si,[find_FileName] mov cx,8 call writeCX cmp [Word Ptr find_Ext],2020h jne doDirFileName1 cmp [Byte Ptr find_Ext+2],20h jne doDirFileName1 lea si,[space] call write lea si,[space] call write lea si,[space] call write lea si,[space] call write jmp doDirSp1 doDirFileName1: lea si,[Plot] call write lea si,[find_Ext] mov cx,3 call writeCX ; Два пробела doDirSp1: lea si,[space] call write lea si,[space] call write ; Вывод размера test [Byte Ptr find_Attr],10h je doDirSize1 lea si,[doDirData2] call write jmp doDirSize2 doDirSize1: mov ax,[cs:find_SizeH] call writeAX mov ax,[cs:find_SizeL] call writeAX ; Два пробела doDirSize2: lea si,[space] call write lea si,[space] call write ; Вывод время создания mov ax,[find_Time] push ax and ax,0F800h shr ax,11 call writeDEC2 lea si,[dvoet] call write pop ax push ax and ax,07E0h ; (t & 001fH) shr ax,5 ; ((t & 07e0H) >> 5) call writeDEC2 ; ((t & 0f800H) >> 11) lea si,[dvoet] call write pop ax and ax,001Fh shl ax,1 call writeDEC2 ; Два пробела lea si,[space] call write lea si,[space] call write ; Вывод даты создания mov ax,[find_Date] push ax and ax,001Fh call writeDEC2 lea si,[plot] call write pop ax push ax and ax,01E0h ; (d & 001fH) shr ax,5 ; ((d & 01e0H) >> 5) call writeDEC2 ; ((d & f800H) >> 9) lea si,[plot] call write pop ax and ax,0F800h shr ax,9 add ax,1980 call writeDEC4 ; Два пробела lea si,[space] call write lea si,[space] call write ; Вывод аттрибутов lea si,[doDirData1] mov [Word Ptr cs:si],2D2Dh mov [Word Ptr cs:si+2],2D2Dh mov [Byte Ptr cs:si+4],2Dh mov al,[find_Attr] test al,001h je doDirAttr1 mov [cs:doDirData1+0],'R' doDirAttr1: test al,002h je doDirAttr2 mov [cs:doDirData1+1],'H' doDirAttr2: test al,004h je doDirAttr3 mov [cs:doDirData1+2],'S' doDirAttr3: test al,008h je doDirAttr4 mov [cs:doDirData1+3],'V' doDirAttr4: test al,010h je doDirAttr5 mov [cs:doDirData1+4],'D' doDirAttr5: test al,020h je doDirAttr6 mov [cs:doDirData1+5],'A' doDirAttr6: lea si,[doDirData1] call write ; Перенос строки lea si,[null] call writeln ret ENDP doDirPrintFind ; Смена текущего каталога #################################################### doCDData1 DB " Curent dir: ",0 doCDData2 DB "New Curent dir: ",0 doCDData3 DB " ¦ Specified directory not found.",0 doCDSubStr1 DB "dir_name.ext",0 doCDFileName DB "dir_name" doCDExt DB "ext" doCDError DW 0 ; Внешний цикл - разбивает строку типа DIR1\DIR2\DIR3. И передает во ; внутренний параметры DIR1, DIR2, DIR3 и т.д. PROC doCD ; Вывод старого каталога lea si,[doCDData1] call write lea si,[dos_CurDir] call writeln lea si,[doCDData2] call write call input call ReadFAT mov [Word Ptr RSSData],0 lea di,[command] push di call Upperstring pop di mov [Word Ptr cs:doCDError],0 ; Если ввели '\', то меняем на корень mov ax,[di] cmp ax,005Ch jne doCDnRoot mov [Word Ptr cs:dos_CurDir+3],0 lea si,[null] call writeln ret ; Разбиваем строку на подстроки doCDnRoot: lea si,[command] doCDnRoot0: lea di,[doCDSubStr1] xor cx,cx doCDnRoot2: mov al,[cs:si] or al,al je doCDnRoot3 cmp al,'\' jne doCDnRoot1 doCDnRoot3: mov [Byte Ptr cs:di],0 push ax si call doCDNormaliseName call doCDInner pop si ax inc si or al,al je CDEnd jmp doCDnRoot0 doCDnRoot1: mov [cs:di],al inc si inc di inc cx cmp cx,13 jne doCDnRoot2 mov [Word Ptr cs:doCDError],1 jmp doCDnRoot3 CDEnd: mov ax,[cs:doCDError] or ax,ax je CDEnd1 lea si,[null] call writeln lea si,[doCDData3] call writeln CDEnd1: lea si,[null] call writeln push cs pop ds xor ah,ah lea di,[dos_CurDir] mov ah,1 ; Задать строку статуса int 0FFh ret ENDP doCD ; Нормализация имени файла ################################################### PROC doCDNormaliseName push si lea di,[doCDFileName] mov cx,11 mov ax,20h rep stosb xor cx,cx lea di,[doCDSubStr1] lea si,[doCDFileName] cmp [Word Ptr cs:di],02E2Eh ; '..' je doCDNUp doCDN1: mov al,[di] or al,al je doCDNEnd cmp al,'.' je doCDNExt mov [si],al inc si inc di inc cx cmp cx,9 je doCDNEnd1 jmp doCDN1 doCDNExt: lea si,[doCDExt] inc di xor cx,cx doCDN2: mov al,[di] or al,al je doCDNEnd mov [si],al inc si inc di inc cx cmp cx,4 je doCDNEnd1 jmp doCDN2 doCDNEnd1: mov [Word Ptr cs:doCDError],1 doCDNEnd: pop si ret doCDNUp: mov [Word Ptr cs:si],02E2Eh ; '..' pop si ret ENDP doCDNormaliseName ; Внутренний цикл ############################################################ PROC doCDInner call FindFirst or ax,ax jne doCDInnerEnd doCDInner0: lea di,[find_FileName] lea si,[doCDFileName] mov cx,11 doCDInner2: mov al,[di] cmp al,[si] jne doCDInner1 inc di inc si loop doCDInner2 ; Найден каталог lea si,[doCDFileName] cmp [Word Ptr cs:si],02E2Eh ; Если .. ,то на каталог ; выше. je doCDUp lea si,[dos_CurDir] xor cx,cx doCDChange2: cmp [Byte Ptr cs:si],0 je doCDChange1 inc si inc cx jmp doCDChange2 doCDChange1: lea di,[doCDSubStr1] doCDChange4: mov al,[cs:di] or al,al je doCDChange3 mov [cs:si],al inc si inc di inc cx cmp cx,128 jne doCDChange4 mov [Word Ptr cs:doCDError],1 jmp doCDChange5 doCDChange3: mov [Word Ptr cs:si],005Ch doCDChange5: ret ; На каталог выше doCDUp: lea si,[dos_CurDir] doCDUp0: cmp [Byte Ptr cs:si],0 je doCDUp1 inc si jmp doCDUp0 doCDUp1: dec si doCDUp2: dec si cmp [Byte Ptr cs:si],':' je doCDUp3 cmp [Byte Ptr cs:si],'\' jne doCDUp2 inc si mov [Byte Ptr cs:si],0 ret doCDUp3: ;mov [Word Ptr cs:doCDError],1 ret doCDInner1: call FindNext or ax,ax jne doCDInnerEnd jmp doCDInner0 doCDInnerEnd: mov [Word Ptr cs:doCDError],1 ret ENDP doCDInner ; Вывод текущего каталога #################################################### PROC doCDir lea si,[dos_CurDir] jmp WriteLn ENDP doCDir ; Приостановка задачи ######################################################## doStopData0 DB "Enter task number (1-8): ",0 doStopData1 DB " ¦ Parametrs error.",0 doStopData2 DB " ¦ This task not loaded.",0 PROC doStop lea si,[doStopData0] call write call input lea si,[null] call writeln lea si,[command] cmp [Byte Ptr cs:si+1],0 jne doStop1 mov al,[Byte Ptr cs:si] cmp al,'1' jl doStop1 cmp al,'8' ja doStop1 sub al,'1' xor ah,ah push ax lea di,[tasks] mov cx,515 imul cx add di,ax mov al,[cs:di] cmp al,255 pop ax je doStop2 inc al cmp [cs:LastLineFlag],al jne doStop3 mov [Byte Ptr cs:LastLineFlag],0 doStop3: call _di mov al,254 mov [cs:di],al mov dx,[cs:di+3] call _ei ret doStop1: lea si,[doStopData1] call writeln ret doStop2: lea si,[doStopData2] call writeln ret ENDP doStop ; Перезапуск задачи ########################################################## doReStartData0 DB "Enter task number (1-8): ",0 doReStartData1 DB " ¦ Parametrs error.",0 doReStartData2 DB " ¦ This task not stoped.",0 PROC doReStart lea si,[doReStartData0] call write call input lea si,[null] call writeln lea si,[command] cmp [Byte Ptr cs:si+1],0 jne doReStart1 mov al,[Byte Ptr cs:si] cmp al,'1' jl doReStart1 cmp al,'8' ja doReStart1 sub al,'1' xor ah,ah lea di,[tasks] mov cx,515 imul cx add di,ax cmp [Byte PTr cs:di],254 jne doReStart2 call _di mov al,1 mov [cs:di],al call _ei ret doReStart1: lea si,[doReStartData1] jmp writeln doReStart2: lea si,[doReStartData2] jmp writeln ENDP doReStart ; Задать приоритет ########################################################### doPrioritetD0 DB "Enter task number (1-8): ",0 doPrioritetD1 DB " ¦ Parametrs error.",0 doPrioritetD2 DB " ¦ This task not loaded.",0 doPrioritetD3 DB "Enter new prioritet (1-9): ",0 PROC doSetPrioritet lea si,[doPrioritetD0] call write call input lea si,[null] call writeln lea si,[command] cmp [Byte Ptr cs:si+1],0 jne doPrioritet1 mov al,[Byte Ptr cs:si] cmp al,'1' jl doPrioritet1 cmp al,'8' ja doPrioritet1 sub al,'1' xor ah,ah lea di,[tasks] mov cx,515 imul cx add di,ax cmp [Byte PTr cs:di],255 je doPrioritet2 push di lea si,[doPrioritetD3] call write call input lea si,[command] cmp [Byte Ptr cs:si+1],0 jne doPrioritet1 mov al,[Byte Ptr cs:si] cmp al,'1' jl doPrioritet1 cmp al,'9' ja doPrioritet1 sub al,'0' xor ah,ah pop di call _di mov [cs:di+11],ax mov [cs:di+9],ax call _ei lea si,[null] jmp writeln doPrioritet1: lea si,[doPrioritetD1] jmp writeln doPrioritet2: lea si,[doPrioritetD2] jmp writeln ENDP doSetPrioritet ; Запуск программы ########################################################### doRunData1 DB "Not yet implimented.",0 PROC doRun lea si,[doRunData1] call WriteLn ret ENDP doRun
Оставить комментарий
Комментарии
1.
23 ноября 2004, 20:39:27
На первый взгляд все нормально, но это тока на первый!!!!!!!
Я нашел 5 ошибок после того как изучил код. И это тока за полчаса.
Вы учите ОС писать или очередное детище от мелко-мягких.
Я нашел 5 ошибок после того как изучил код. И это тока за полчаса.
Вы учите ОС писать или очередное детище от мелко-мягких.