
Санкт-петербургский государственный университет
информационных технологий, механики и оптики
(СПбГУ ИТМО)
Кафедра вычислительной техники
Отчет
По лабораторной работе №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
.data
bitmask db 128,64,32,16,8,4,2,1
string_length equ 100 ; произвольная длина строки в пикселях
hor_length equ 90
hor_length1 equ 90
x1 equ 3 ; координаты наклонной линии
y1 equ 46
x2 equ 96
y2 equ 98
d_x dw 0
d_y dw 0
y_i dw 0
x_i dw 0
d_i dw 0
.code
mov ax,@data
mov ds,ax
mov ax, 06h
int 10h
mov ax, 0B800h ; загрузка адреса начала
mov es, ax ; видеопамяти в регистр ES
;-----угол наклона
mov bx, x2
mov ax, y2
sub bx, x1 ; dx
sub ax, y1 ; dy
;-----dx=|x2-x1|, dy=|y2-y1|
cmp bx, 0
jg pos_dx ; dx c 0,если (x2-x1)<0, то по модулю
neg bx
pos_dx:
mov d_x, bx
cmp ax, 0 ; dy с 0
jg pos_dy ; если (y2-y1)<0, то по модулю
neg ax
pos_dy:
mov d_y, ax
mov bx, x1
mov ax, y1
mov x_i, bx
mov y_i, ax
; -----d0=2dy-dx,d0 в dx
mov dx, d_y
shl dx, 1
sub dx, d_x
mov d_i, dx
jmp paint
EX1:
cmp d_i, 0 ; сравниваем di с нулём
jl EX2 ; если d0 <0, то EX2
; координаты следующей точки
;-----di>=0
mov ax, d_y
mov bx, d_x
sub ax, bx ; dy-dx
shl ax, 1 ; 2*(dy-dx)
mov dx, d_i
add dx, ax ; d(i+1)=di+2(dy-dx)
mov d_i, dx
inc x_i ; x(i+1)=xi+1
inc y_i ; y(i+1)=yi-1
jmp paint
; -----di<0
EX2:
mov ax, d_y
shl ax, 1 ; 2*dy
mov dx, d_i
add dx, ax ; d(i+1)=di+2dy
mov d_i, dx
inc x_i ; x(i+1)=xi+1, y(i+1)=yi
jmp paint
EX3:
cmp d_i, 0 ; сравниваем di с нулём
jl EX4 ; если d0 <0, то EX2
; -----di >=0
mov ax, d_y
mov bx, d_x
sub bx, ax ; dx-dy
shl bx, 1 ; 2*(dx-dy)
mov dx, d_i
add dx, bx ; d(i+1)=di+2(dx-dy)
mov d_i, dx
inc y_i ; y(i+1)=yi+1
inc x_i ; x(i+1)=xi+1
jmp paint
; -----di<0
EX4:
mov bx, d_x
shl bx, 1 ; 2*dx
mov dx, d_i
add dx, bx ; d(i+1)=di+2dx
mov d_i, dx
inc y_i ; y(i+1)=yi+1, x(i+1)=xi
jmp paint
paint:
; -----точка
mov bx, x_i
mov ax, y_i
mov dx, bx
and dx, 07h ;находим битовое смещение
mov cl, 3
shr bx, cl ;делим x0 на 8 (определяем байт, в котором находится точка)
mov cx, ax
and cx, 01h
cmp cx, 0 ; определем чётное или нечётное
jz EX
add bx, 2000h
dec ax
EX:
mov cl, 1
shr ax, cl ;ax = (y-1)/2 or y/2 - т.к. банк только четных/нечетных строк
mov cl, 4
sal ax, cl ;ax = (y/2)*16, bx=x/4
add bx, ax
mov cl, 2
sal ax, cl ;ax = (y/2)*64, bx =x/4 + (y/2)*16
add bx, ax ;bx = x/4+(y/2)*80 - полных байт
xor ax, ax
mov si, dx
mov al, bitmask+[si]; в al - маска
or es:[bx], ax
; ----tg_n<=1
mov bx, d_x
cmp bx, d_y ; сравниваем проекцию на ось 0Х с на ось 0Y
jl sign ; если dx<dy, то tg>1&-->EX1
cmp x_i, x2
jle EX1
sign:
; -----tg_n>1
cmp y_i, y2
jle EX3
;вертикальная линия
mov ax, 0B800h ; загрузка адреса начала
mov es, ax ; видеопамяти в регистр ES
mov bx, 0 ; указываем на первый байт буфера
xor ax, ax ; обнуляем аккумулятор
mov dx, string_length
mov cl, 1
shr dx, cl
mov cx, dx
vertical_line:
mov al, 1b
mov es:[bx], al
add bx, 80 ; длина строки в байтах
loop vertical_line ;пока сх !=0
mov ax, string_length
and ax, 01h ; смотрим последний бит
cmp ax, 0 ; сравниваем с нулём, если равен нулю - нечётное, равен - чётное
jz EXV ; если равен нулю, осуществляем переход на M1
mov al, 1
mov es:[bx], al
EXV:
mov bx, 02000h
mov cx, dx
vertical_line_2:
mov al, 1
mov es:[bx], al
add bx, 80
loop vertical_line_2
;горизонтальная линия нижняя
mov ax,0B8F5h ;загрузка адреса начала
mov es, ax ; видеопамяти в регистр ES
mov bx, 1 ; указываем на первый байт буфера
mov ax, hor_length
mov dx, ax
and dx, 07h
mov cl, 3
shr ax, cl ;ax = x/8
mov cx,ax
xor ax,ax
cmp cx,0
je lbl_2
lbl_horizontal_line:
mov al,55h
mov es:[bx],al
add bx,1
loop lbl_horizontal_line
;горизонтальная линия верхняя
mov ax,0b800h ;загрузка адреса начала
mov es, ax ; видеопамяти в регистр ES
mov bx, 1 ; указываем на первый байт буфера
mov ax, hor_length1
mov dx, ax
and dx, 07h
mov cl, 3
shr ax, cl ;ax = x/8
mov cx,ax
xor ax,ax
cmp cx,0
je lbl_2
lbl_horizontal_line1:
mov al,55h
mov es:[bx],al
add bx,1
loop lbl_horizontal_line1
lbl_2:
xor ax,ax
int 16h
mov ax,4c00h
int 21h
end