Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование драйвера экрана

.docx
Скачиваний:
3
Добавлен:
08.11.2017
Размер:
50.81 Кб
Скачать

Федеральное Агентство по образованию

ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОНИКИ (ТУСУР)

Кафедра компьютерных систем в управлении и проектировании (КСУП)

ОТЧЁТ

по лабораторной работе № 1

«Программирование драйвера экрана»

Студент группы

2015

Содержание

1. Цель работы 2

2. Результаты выполнения программы 3

3. Выводы 4

Список используемой литературы 5

Приложение А – Листинг нерезидентного драйвера screen.asm 6

Приложение Б – Листинг основной программы lab1.asm 16

1. Цель работы

Требуется реализовать программно нерезидентный драйвер экрана с видеоадаптером CGA, логическая схема которого приведена на рисунке 40 [1]. Кроме того, требуется разработать прикладную программу, выполняющую вывод на экран фамилии и имени, и, возможно, другой информации, используя для вывода на экран написанный драйвер.

Исходя из последних двух цифр в пароле и общего кол-ва заданий, мне выпадает вариант № 17.

Цвет символов: серый.

Цвет фона: ярко-красный.

2. Результаты выполнения программы

3. Выводы

В ходе выполнения данной работы был написан и отлажен модуль драйвер экрана, а также разработана прикладная программа, использующая его интерфейс для вывода символов на экран монитора.

Список используемой литературы

  1. Одиноков В. В. ЭВМ и вычислительные системы. Однопрограммные системы: Учебное пособие. – Томск: Томский межвузовский центр дистанционного образования, 2002. – 133 с.

2. http://www.escolero.ru/shop/13/Programmirovanie_drajvera_ekrana/

Приложение А – Листинг нерезидентного драйвера screen.asm

code_seg segment public

assume cs:code_seg

public sc_x_coord, sc_y_coord, sc_symbol, sc_attributes ; переменные, доступные другим модулям

public sc_init, sc_print_symbol, sc_print_string ; функции, доступные другим модулям

; данные

sc_video_addr equ 0B800h ; адрес начала видеопамяти

; публичные переменные

sc_x_coord db 0 ; координата X (номер строки)

sc_y_coord db 0 ; координата Y (номер столбца)

sc_symbol db 0 ; символ

sc_attributes db 0 ; атрибуты

;-------------------------------------------------------------------------------

; Процедура инициализации драйвера экрана

; ничего не получает, не возвращает

; заполняет видеопамять заданными символами (пробел с цветом фона)

sc_init proc near

push ES ; сохраняем значение регистров на стеке

push AX

push DI

push CX

push DX

; очистка видеопамяти (заполение символом пробела)

mov AL, ' ' ; символ пробела

mov AH, 01001000b ; атрибуты

mov CX, sc_video_addr

mov ES, CX ; адрес начала видеопамяти

xor DI, DI ; итератор цикла

cycle1: ; цикл заполнения памяти

cmp DI, 4000 ; 4000 байт (по два байта на символ)

jge end_of_cycle1

cld ; очистка флагов направления

stosw ; [ES:DI] = AX

jmp cycle1

end_of_cycle1:

; Установка размера курсора

; начало курсора

mov DX, 3D4h ; индексный регистр указывает на

mov AL, 10 ; регистр "начало курсора"

out DX, AL ; пишем в порт

inc DX ; 3D5h - управляющий регистр

mov AL, 0 ; начало = 0

out DX, AL ; пишем в регистр "начало курсора"

; конец курсора

mov DX, 3D4h ; индексный регистр указывает на

mov AL, 11 ; регистр "конец курсора"

out DX, AL ; пишем в порт

inc DX ; 3D5h - управляющий регистр

mov AL, 15 ; конец равен 15

out DX, AL ; пишем в регистр "конец курсора"

; установка позиции курсора

; старший байт

mov DX, 3D4h ; индексный регистр указывает на

mov AL, 14 ; регистр "адрес курсора" (ст.)

out DX, AL ; пишем в порт

inc DX ; 3D5h - управляющий регистр

mov AL, 1 ; устанавливаем старший байт (например, 1)

out DX, AL ; пишем в регистр "адрес курсора" (ст.)

; младший байт

mov DX, 3D4h ; индексный регистр указывает на

mov AL, 15 ; регистр "адрес курсора" (мл.)

out DX, AL ; пишем в порт

inc DX ; 3D5h - управляющий регистр

mov AL, 1 ; устанавливаем младший байт (например, 1)

out DX, AL ; пишем в порт

pop DX

pop CX ; восстанавливаем регистры

pop DI

pop AX

pop ES

ret ; возврат из процедуры

sc_init endp

;-------------------------------------------------------------------------------

;-------------------------------------------------------------------------------

; Процедура вывода символа

; Выводит символ sc_symbol с атрибутами (sc_attributes)

; по координатам(sc_x_coord, sc_y_coord) и перемещает курсор

; изменяет переменные sc_x_coord и sc_y_coord

; в случае, если строка > 25 - оставляем 25 и производим скроллинг (сдвиг)

; ничего не возвращает

sc_print_symbol proc near

push ES ; сохраняем значения регистров на стеке

push AX

push DI

push CX

push DX

push BX

push SI

mov AL, sc_symbol ; в AL - символ

cmp AL, 0Dh ; сравним с возвратом каретки

je change_coordinates ; если равен - только установка новых координат

cmp AL, 0Ah ; сравним с переводом строки

je change_coordinates ; если равен - только установка координат

; если нужно изменить символ в видеопамяти

mov CX, sc_video_addr

mov ES, CX ; адрес начала видеопамяти

xor AX, AX

; вычисляем адрес в памяти по координатам

mov AL, sc_x_coord

mov CL, 80

mul CL ; AX = 80*sc_x_coord

xor CX, CX

mov CL, sc_y_coord

add AX, CX ; AX = 80*sc_x_coord + sc_y_coord

shl AX, 1 ; AX = (80*sc_x_coord + sc_y_coord) * 2

mov DI, AX ; DI = (80*sc_x_coord + sc_y_coord) * 2

; устанавливаем символ и атрибуты

mov AL, sc_symbol ; символ

mov AH, sc_attributes ; атрибуты

cld ; очистка флагов направления

stosw ; [ES:DI] = AX

; изменим sc_x_coord и sc_y_coord

change_coordinates:

mov AL, sc_symbol

cmp AL, 0Dh ; возврат каретки

jne not_cr ; переход на сравнение с Переводом строки

mov AL, 0

mov sc_y_coord, AL ; то sc_y_coord = 0

jmp set_cursor_position

not_cr:

cmp AL, 0Ah ; новая строка

jne not_lf ; если не равно, переход

jmp only_inc_x ; переход на след. строку

not_lf: ; не перевод строки

mov AL, sc_y_coord

inc AL ; увеличим кооринату y

cmp AL, 80

jge next_row ; если >= 80 - следующая строка

mov sc_y_coord, AL

jmp set_cursor_position ; изменили sc_y_coord, перейдем к установке курсора

next_row: ; если нужен перевод строки и возврат каретки

mov AL, 0

mov sc_y_coord, AL ; запиываем новое значение

only_inc_x: ; если нужен только перевод строки

mov AL, sc_x_coord

inc AL ; увеличим кооринату x

cmp AL, 25 ; если >= 25 - произведем сдвиг экрана

jge scroll_screen ; переход к скроллингу

mov sc_x_coord, AL ; сохраняем значение

jmp set_cursor_position ; изменили sc_x_coord, перейдем к установке курсора

;====================================================================

scroll_screen:

; значение sc_x_coord не изменяем

; сдвиг экрана на строку вверх

push DS ; сохраняем DS

mov CX, sc_video_addr

mov ES, CX ; адрес начала видеопамяти

mov DS, CX

xor AX, AX

mov SI, 160

xor DI, DI

shift_cycle:

cmp SI, 4000 ; последнюю строку оставляем

jge end_of_shift_cycle

cld ; очистка флагов направления

movsw ; [ES:DI] = [DS:SI]

jmp shift_cycle

end_of_shift_cycle:

pop DS ; восстанавливаем DS

; очистка последней строки

mov CX, sc_video_addr

mov ES, CX ; адрес начала видеопамяти

mov AL, ' ' ; символ пробела

mov AH, sc_attributes ; атрибуты

mov DI, 4000 - 160

clean_row_cycle: ; цикл заполнения памяти

cmp DI, 4000 ; 2000 * 2 байт

jge end_of_clean_row_cycle

cld ; очистка флагов направления

stosw ; [ES:DI] = AX

jmp clean_row_cycle

end_of_clean_row_cycle:

;====================================================================

set_cursor_position:

; расчет координат = 80 * sc_x_coord + sc_y_coord

mov AL, sc_x_coord

mov CL, 80

mul CL

xor CX, CX

mov CL, sc_y_coord

add AX, CX

mov CX, AX ; CX = новые координаты

; установка позиции курсора на основе sc_x_coord и sc_y_coord

; старший байт

mov DX, 3D4h ; индексный регистр указывает на

mov AL, 14 ; регистр адрес курсора (ст.)

out DX, AL ; пишем в порт

inc DX ; 3D5h - управляющий регистр

mov AL, CH ; устанавливаем старший байт

out DX, AL ; пишем в регистр адрес курсора (ст.)

; младший байт

mov DX, 3D4h ; индексный регистр указывает на

mov AL, 15 ; регистр адрес курсора (мл.)

out DX, AL ; пишем в порт

inc DX ; 3D5h - управляющий регистр

mov AL, CL ; устанавливаем младший байт

out DX, AL ; пишем в порт

exit_print_symbol:

pop SI

pop BX

pop DX

pop CX ; восстанавливаем регистры

pop DI

pop AX

pop ES

ret ; возврат из процедуры

sc_print_symbol endp

;-------------------------------------------------------------------------------

;-------------------------------------------------------------------------------

; Процедура вывода последовательности символов

; в DS:BX - адрес данной строки

; ничего не возвращает

; выводит символы с помощью процедуры sc_print_symbol

; пока не встретится нулевой байт

sc_print_string proc near

push AX

push BX ; сохраняем регистры, значение которых меняется в данной процедуре

print_cycle: ; цикл вывода строки

mov AL, byte ptr[BX]

cmp AL, '$' ; сравниваем текущий символ с нулевым байтом

je end_of_print_cycle ; если символ - ноль - заканчиваем вывод

mov sc_symbol, AL ; помещаем текущий символ

call sc_print_symbol ; вызов процедуры вывода символа

inc BX ; увеличиваем индекс

jmp print_cycle

end_of_print_cycle:

pop BX ; восстанавливаем регистры

pop AX

ret

sc_print_string endp

;-------------------------------------------------------------------------------

code_seg ends

end

Приложение Б – Листинг основной программы lab1.asm

code_seg segment public

assume cs:code_seg

org 100h

; Внешние переменные и процедуры (определены в модуле "Драйвер экрана")

extrn sc_x_coord:byte, sc_y_coord:byte, sc_symbol:byte, sc_attributes:byte

extrn sc_init:near, sc_print_symbol:near, sc_print_string:near

begin: ; точка входа

call sc_init ; вызываем процедуру инициализации экрана

mov sc_x_coord, 0 ; устанавливаем координаты

mov sc_y_coord, 0 ; устанавливаем координаты

mov sc_attributes, 01001000b ; устанавливаем атрибуты символов

mov BX, offset txt ; адрес начала выводимой строки

call sc_print_string ; вывод строки

mov AH, 00

int 16h ; ждем нажатия клавиши

mov AX, 4c00h

int 21h ; завершаем программу

; данные

txt db "Лабораторная работа #1", 13, 10, "Программирование драйвера экрана", 13, 10,13, 10,"Иванов Иван Иванович", 13, 10, "666У-б", 13, 10, "г.Урюпинск$"

code_seg ends

end begin