Очищаем внутреннюю очередь команд процессора
cli mov al,8f out CMOS_PORT,al jmp next1 ; небольшая задержка next1:
mov al,5 out CMOS_PORT+1,al ; код возврата
ret
ENDP init_protected_mode
; ------------------------------------------------------------ ; Процедура переключает процессор в защищённый режим ; ------------------------------------------------------------
PROC set_protected_mode NEAR
mov ax,[rl_crt] ; записываем в es сегментный mov es,ax ; адрес видеопамяти
call enable_a20 ; открываем адресную линию A20
mov [real_ss],ss ; запоминаем указатель стека mov [real_es],es ; для реального режима
; Загружаем регистр GDTR
lgdt [QWORD gdt_gdt]
; Устанавливаем защищённый режим работы процессора
mov ax,VIRTUAL_MODE lmsw ax
; Мы находимся в защищённом режиме
; Очищаем внутреннюю очередь команд процессора ; Выполняем команду межсегментного прерхода, ; в качестве селектора указываем селектор текущего ; сегмента кода, в качестве смещения - метку flush
; jmp far flush db 0ea dw OFFSET flush dw CS_DESCR
LABEL flush FAR
; Загружаем сегментные регистры SS и DS селекторами
mov ax,SS_DESCR mov ss,ax mov ax,DS_DESCR mov ds,ax ret
ENDP set_protected_mode
; ------------------------------------------------------------ ; Процедура возвращает процессор в реальный режим ; ------------------------------------------------------------
PROC set_real_mode NEAR
; Запоминаем содержимое указателя стека, так как после ; сброса процессора оно будет потеряно
mov [real_sp],sp
; Выполняем сброс процессора
mov al,SHUT_DOWN out STATUS_PORT,al
; Ожидаем сброса процессора
wait_reset: hlt jmp wait_reset
; ------->> В это место мы попадём после сброса процессора, ; теперь мы снова в реальном режиме
LABEL shutdown_return FAR
; Инициализируем ds адресом сегмента данных
mov ax,DGROUP mov ds,ax assume ds:DGROUP
; Восстанавливаем указатель стека
mov ss,[real_ss] mov sp,[real_sp]
; Восстанавливаем содержимое регистра es
mov es,[real_es]
; Закрываем адресную линию A20
call disable_a20
; Разрешаем все прерывания
mov ax,000dh ; разрешаем немаскируемые прерывания out CMOS_PORT,al
in al,INT_MASK_PORT ; разрешаем маскируемые прерывания and al,0 out INT_MASK_PORT,al sti
ret ENDP set_real_mode
; ------------------------------------------------------------ ; Процедура открывает адресную линию A20 ; ------------------------------------------------------------
PROC enable_a20 NEAR mov al,A20_PORT out STATUS_PORT,al mov al,A20_ON out KBD_PORT_A,al ret ENDP enable_a20
; ------------------------------------------------------------ ; Процедура закрывает адресную линию A20 ; ------------------------------------------------------------
PROC disable_a20 NEAR mov al,A20_PORT out STATUS_PORT,al mov al,A20_OFF out KBD_PORT_A,al ret ENDP disable_a20
; ------------------------------------------------------------ ; Процедура выполняет небольшую временную задержку ; ------------------------------------------------------------
PROC pause NEAR push cx mov cx,50 ploop0: push cx xor cx,cx ploop1: loop ploop1 pop cx loop ploop0
pop cx ret ENDP pause
; ------------------------------------------------------------ ; Сегмент данных для процедур обслуживания видеоадаптера ; ------------------------------------------------------------
DATASEG columns db 80d ; количество столбцов на экране rows db 25d ; количество строк на экране
rl_crt dw COLOR_SEG ; сегментный адрес видеобуфера vir_crt dw CRT_DESCR ; селектор видеобуфера
curr_line dw 0d ; номер текущей строки
CODESEG
; ------------------------------------------------------------ ; Определение базового адреса видеобуфера ; ------------------------------------------------------------
PROC set_crt_base NEAR
; Определяем количество столбцов на экране и записываем ; в переменную columns
mov ax,40 mov es,ax mov bx,[WORD es:4a] mov [columns],bl
; То же для количества строк, записываем в переменную rows
mov bl,[BYTE es:84] inc bl mov [rows],bl
; Для того чтобы определить тип видеоконтроллера (цветной ; или монохромный), считываем адрес микросхемы 6845
mov bx,[WORD es:PORT_6845] cmp bx,COLOR_PORT je set_crt_exit
; Если видеоконтроллер монохромный, изменяем адрес сегмента ; и селектор, заданные по умолчанию
mov [rl_crt],MONO_SEG mov [vir_crt],MDA_DESCR
set_crt_exit: ret ENDP set_crt_base
; ------------------------------------------------------------ ; Вывод строки на экран ; Параметры: ; (ax, bx) - координаты (x, y) выводимой строки ; ds:si - адрес выводимой строки ; cx - длина выводимой строки ; dh - атрибут выводимой строки ; es - сегмент или селектор видеопамяти ; ------------------------------------------------------------
PROC writexy NEAR push si push di
; Вычисляем смещение в видеобуфере для записи строки, ; используем формулу ((y * columns) + x) * 2
mov dl,[columns] mul dl add ax,bx shl ax,1 mov di,ax mov ah,dh ; записываем в ah байт атрибута
; Выполняем запись в видеобуфер
wxy_write: lodsb ; очередной символ в al stosw ; записываем его в видеопамять loop wxy_write ; цикл до конца строки
pop di pop si ret ENDP writexy
; ------------------------------------------------------------ ; Процедура стирания экрана ; Параметр: bh - атрибут для заполнения экрана ; ------------------------------------------------------------
PROC clrscr NEAR xor cx,cx mov dl,[columns] mov dh,[rows] mov ax,0600h int 10h ret ENDP clrscr
DATASEG
hello_msg db " Protected mode monitor *TINY/OS*, v.1.0 for CPU 80286 ¦ © Frolov A.V., 1992 "
CODESEG
; ------------------------------------------------------------ ; Процедура выводит сообщение в защищённом режиме ; ------------------------------------------------------------
PROC write_hello_msg NEAR
mov ax,[vir_crt] ; загружаем селектор видеопамяти mov es,ax ; в регистр es
; Выводим сообщение в верхний левый угол экрана (x=y=0)
mov bx,0 ;(X,Y) = (AX,BX) mov ax,[curr_line] inc [curr_line] ; увеличиваем номер текущей строки
; Загружаем адрес выводимой строки и её длину
mov si,OFFSET hello_msg mov cx,SIZE hello_msg
mov dh,30h ; аттрибут - черный текст на голубом фоне
call writexy ; выводим строку
ret ENDP write_hello_msg
CSEG_SIZE = ($ - start) ; размер сегмента кода
DATASEG
DSEG_SIZE = ($ - DSEG_BEG) ; размер сегмента данных
END start
Содержание Назад Вперед
Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий