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
Оставить комментарий
Оставлять комментарии могут только зарегистрированные пользователи.
Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.


