
Санкт-петербургский государственный университет
информационных технологий, механики и оптики
(СПбГУ ИТМО)
Кафедра вычислительной техники
Отчет
По лабораторной работе №1б
По дисциплине «Компьютерная графика»
Вариант № 6
Работу выполнил:
Студент группы 4103
Голубцов Евгений Сергеевич
Санкт-Петербург
2010
ЗАДАНИЕ ПО ЛАБОРАТОРНОЙ РАБОТЕ N 1b
1) Разработать программу построения первой буквы своего имени или фамилии с использованием наклонных линий (Алгоритм Брезенхема)
Описание используемого видеоадаптера CGA.
Видеоадаптер CGA поддерживает три графических режима - режимы 4, 5 и 6. Черно-белый режим адаптера CGA (Color Graphic Adapter), устанавливавшегося на ПК IBM PC XT, имеет разрешение 640х200 битовых точек. Организация памяти в режиме CGA максимально приспособлена для чересстрочной развертки. С сегментного адреса B800h начинается банк четных строк, а с адреса D800h – банк нечетных строк. Нумерация строк начинается с нуля, поэтому такое расположение банков памяти является логичным. Каждой точке на экране соответствует один бит. Таким образом, каждая строка занимает 80 байт, а четный полукадр – 8000 байт. Нечетный полукадр находится со смещением 2000h = 8192. Лишние 192 байта не используются. Такое решение продиктовано соображением простоты адресации.
Программа.
.model small
.286
.data
bitmask db 128,64,32,16,8,4,2,1 ;таблица
.code
mov ax,@data
mov ds,ax
mov ax, 06h ;инициализация графического
int 10h ;режима CGA: 640x200
mov ax,0B800h ;адрес видеопамяти
mov es,ax ;устанавливаем сегментный регистр
;наклонная линия \
mov ax, 30 ;координата y0
mov bx, 250 ;координата x0
mov dx, 110 ;координата y1
mov cx, 350 ;координата x1
call INCLINED
;наклонная линия /
mov ax, 30 ;координата y0
mov bx, 350 ;координата x0
mov dx, 110 ;координата y1
mov cx, 250 ;координата x1
call INCLINED
;вертикальная линия
mov bx, 300 ;координата x
mov ax, 30 ;координата y0
push ax ;заносим в стек y0
mov dx, 110 ;координата y1
push dx ;заносим в стек y1
call PNT
pop cx ;извлекаем из стека y1
pop dx ;извлекаем из стека y0
sub cx, dx ;вычисляем dy
shr cx, 1 ;делим на 2
push cx ;заносим в стек
vert1:
add bx, 50h ;переход через строчку
or es:[bx],ax ;записываем байт в видеопамять
loop vert1 ;рисуем вертикальную линию
pop cx ;извлекаем dу
cmp bx, 2000h ;сравниваем смещение
jge vertcor ;если больше или равно, переходим
add bx, 2000h ;прибавляем к смещению 2000
inc cx ;инкрементируем dy
jmp vert2
vertcor:
sub bx, 2000h ;вычитаем из смещения 2000
vert2:
or es:[bx],ax ;записываем байт в видеопамять
sub bx, 50h ;поднимаемся через строчку
loop vert2 ;конец рисования вертикальной линии
xor ax,ax ;ожидаем нажатие клавиши
int 16h
mov ax,4c00h
int 21h
PNT proc
;процедура рисования точки
xor cx, cx
xor di, di ;обнуляем индексный регистр
mov dx, bx ;в dx заносим x0
and dx, 07h ;находим битовое смещение
mov cl, 3
shr bx, cl ;делим x0 на 8 (определяем байт, в котором находится точка)
mov cx, ax ;в cx заносим y0
and cx, 01h ;выделяем последний бит y0
cmp cx, 0 ;сравниваем его с нулем (четное или нечетное)
je EV ;если он равен 0, то переходим к EV
add bx, 2000h ;получаем адрес
dec ax ;декрементируем y0
EV:
mov cl, 1
shr ax, cl ;ax = (y - 1) / 2
mov cl, 4
sal ax, cl ;ax=((y - 1)/2) * 2^4, bx = x/8
add bx, ax
mov cl, 2
sal ax, cl ;ax=((y - 1)/2) * 2^6, bx = x/8 + ((y - 1)/2) * 2^4
add bx, ax ;прибавляем к смещению х
xor ax,ax ;очищаем ax
mov si,dx ;x0 заносим в индексный регистр
mov al,bitmask+[si] ;загружаем маску в al
or es:[bx],ax ;записываем байт в видеопамять
ret
PNT endp
; процедура рисования наклонной линии
INCLINED proc
cmp ax, dx ;сравниваем y0 и y1
jl OK1 ;если y0 < y1, переходим к ОК1
mov si, 01b ;если y0 > y1, записываем в si 1
OK1:
cmp bx, cx ;сравниваем х0 и х1
jl OK2 ;если х0 < х1, переходим к ОК2
mov di, 01b ;если х0 > х1, записываем в di 1
OK2:
cmp si, di ;сравниваем si и di
je OK3 ;если si=di, переходим к ОК3
cmp si, 01b ;проверям равно ли si 1 (y1 < y0)
je YCORR ;если равно (y0 > y1, x0 < x1), коррекция необходима
jmp LRU ;если не равно (y0 < y1, x0 > x1), коррекция не нужна(si=0, di=1)
YCORR: ;приводим координаты к виду y0 > y1, x0 < x1
xchg ax, dx
xchg bx, cx
jmp LRU
OK3: ;приводим координаты к виду y0 < y1, x0 > x1
cmp si, 01b ;если si = 1 или di = 1, то меняем местами
jne LRD ;если не равно, переходим
xchg ax, dx
xchg bx, cx
LRD: ;линия, направленная влево вниз (y0>y1, x0<x1)
push ax ;заносим в стек y0
push bx ;заносим в стек x0
sub cx, bx ;находим dx
sub dx, ax ;находим dy
mov si, cx ;si = dx
mov di, dx ;di = dy
pop bx ;достаем из стека x0
pop ax ;достаем из стека y0
xor dx, dx ;очищаем dx(y1)
L1:
push cx ;заносим в стек dx
pusha ;размещяем в стеке регистры общего назначения в следующей последовательности: ax, cx, dx, bx, sp, bp, si, di
call PNT ;вызываем процедуру рисования точки
popa ;извлекаем из стека регистры общего назначения di, si, bp, sp, bx, dx, cx, ax
inc bx ;инкрементируем x0
add dx, di ;dx(ошибка) = dx + dy
mov cx, dx
shl cx, 1 ;вычисляем удвоенную ошибку
cmp cx, si ;сравниваем удвоенную ошибку с dx
jle A1 ;если меньше чем или равно переходим
inc ax ;инкрементируем y0
sub dx, si ;вычитаем из ошибки dx
A1:
pop cx ;извлекаем из стека dx
loop L1 ;пока dx не равно нулю повторяем L1
ret ;возврат управления из процедуры
LRU: ;линия, направленная вправо вниз (y0>y1, x0>x1)
push ax ;заносим в стек y0
push bx ;заносим в стек x0
sub bx, cx ;находим dx
sub dx, ax ;находим dy
mov si, bx ;si = dx
mov di, dx ;di = dy
mov cx, bx ;заносим в сx x0
pop bx ;достаем из стека x0
pop ax ;достаем из стека y0
xor dx, dx ;очищаем регистр dx
L2:
push cx ;заносим в стек x0
pusha ;размещяем в стеке регистры общего назначения в следующей последовательности: ax, cx, dx, bx, sp, bp, si, di
call PNT ;вызываем процедуру рисования точки
popa ;извлекаем из стека регистры общего назначения di, si, bp, sp, bx, dx, cx, ax
dec bx ;декрементируем x0
add dx, di ;dx(ошибка) = dx + dy
mov cx, dx
shl cx, 1 ;вычисляем удвоенную ошибку
cmp cx, si ;сравниваем удвоенную ошибку с dx
jle A2 ;если меньше чем или равно переходим
inc ax ;инкрементируем y0
sub dx, si ;вычитаем из ошибки dx
A2:
pop cx ;извлекаем из стека dx
loop L2 ;пока dx не равно нулю повторяем L2
ret ;возврат управления из процедуры
INCLINED endp
end