data segment
	ST_X    dw 50
	END_X   dw 150
	ST_Y    dw 100
	END_Y   dw 50
	COLOR   DB 2
	DI_Y_IN DW ?
	DI_X_IN DW ?
	SH_DI   DW ?
	ST_X_IN DW ?
	ST_Y_IN DW ?
	ST_CO   DW ?
	DI_CO   DW ?
data ends

code segment
	assume CS:code, DS:data

;-------------Процедура исования линии по алгоритму Брезенхема------------------
line proc
;-------------Перевод видеоадаптера в графический режим VGA 640x480-------------
mov ah,00h
mov al,10h
int 10h
;--------------------------------------------------------------------------------
	mov CX,1                ;Инкремент для оси Х
	mov DX,1                ;Инкремент для оси У
;---Вычисление вертикальной дистанции
	mov DI,END_Y            ;Вычитаем координату начала 
	sub DI,ST_Y             ;из координаты конца
	jge KEEP_Y              ;Если DI положительно, то перейти на метку
	neg DX                  ;Инвертировать DX (инкремент = -1)
	neg DI                  ;Инвертировать DI (дистанция положительная)
KEEP_Y: mov DI_Y_IN,DX          ;
;---Вычисление горизонтальной дистанции
	mov SI,END_X            ;Вычитаем координату начала
	sub SI,ST_X             ;из координаты конца
	jge KEEP_X              ;Если SI положительно то перейти на метку
	neg CX                  ;Инвертировать CX  (инкркремент = -1)
	neg SI                  ;Инвертировать SI  (дистанция положительная)
KEEP_X: mov DI_X_IN,CX          ;
;---Определяем, горизонтальные или вертикальные прямые сегменты
	cmp SI,DI               ;Сравнение (Х нач.-Х конеч.) и (Y нач.- Yконеч.)
	jge HORS                ;Если SI >= DI то перейти на метку
	mov CX,0                ;Инкремент по Х равен нулю
	xchg SI,DI              ;Меняем местами SI и DI
	jmp SAVS                ;Переход на метку
HORS:   mov DX,0                ;Инкремент по Y равен 0
SAVS:	mov SH_DI,DI            ;Сохраняем меньшее расстояние
	mov ST_X_IN,CX          ;Сохряняем приращение по Х   
	mov ST_Y_IN,DX          ;-------//---------//-по Y
;---Вычисляем выравнивающий фактор
	mov AX,SH_DI            ;В АХ меньшее расстояние
	shl AX,1                ;Удваиваем его
	mov ST_CO,AX            ;Сохраняем
	sub AX,SI               ;Вычитаем из удвоенного меньшего большее
	mov BX,AX               ;Запоминаем как счетчик цикла
	sub AX,SI               ;
	mov DI_CO,AX            ;
;---Подготовка к выводу линии
	mov CX,ST_X             ;Х-координата
	mov DX,ST_Y             ;Y-координата
	inc SI                  ;прибавляем 1 для конца
	mov AL,COLOR            ;Цвет пиксела
MLOOP:	dec SI                  ;
	jz FINIS                ;Выход после последней точки
	mov AH,12               ;Функция вывода точки
	int 10h                 ;
	cmp BX,0                ;Если ВХ<0, то прямой сегмент
	jge DILIN               ;иначе диагональный сегмент
;---Выводим прямые сегменты
	add CX,ST_X_IN          ;
	add DX,ST_Y_IN          ;
	add BX,ST_CO            ;
	jmp short MLOOP         ;
;---Выводим диагональные сегменты
DILIN:	add CX,DI_X_IN          ;
	add DX,DI_Y_IN          ;
	add BX,DI_CO            ;
	jmp short MLOOP         ;
FINIS:
;-------------------------Задержка до нажатия клавиши---------------------------
mov ah,08h
int 21h
;---------------------Перевод адаптера в текстовый режим------------------------
mov ah,00h
mov al,2h
int 10h
ret
line endp
;-------------------------------------------------------------------------------
main proc
	mov AX,data
	mov DS,AX
call line
;-------------------------Функция завершения программы--------------------------
mov ah,4ch
int 21h
;-------------------------------------------------------------------------------
main endp
code ends
end main
