Code: Select all
;Библиотека пока не оптимизированна и не везде вставлена проверка на выход за границы области вывода.
; при компиляции небудут определены некоторые переменные
; но их нетрудно восстановить по смысловому названию (страница экрана, порт Y)
;Переменные в начальном заголовке - вообще не актуальны до выхода операционной системы и утверждения стандарта для заголовка библиотек
; На реальном железе не проверялась :-( - написана под эмулятор
;include system.a
;include graph.h
;include object.asm
db TLIB
db 0
dw 0
dw 0
dw 0
dw nameLib
db LibGraph/256,10h
db 0
dw 0
db 0ffh ; - количество функций
dw _GrExec
dw _GrExit
dw _GrTime
dw _GrMain
dw _GrError
dw 0
dw 0
dw 0
dw _GrLineOx
dw _CanLineOx
dw _GrLineOy
dw _CanLineOy
dw _GrRect ;debug
dw _CanRect
dw _GrFullRect ;ok
dw _CanFullRect
dw _GrLineXY ; ok
dw _CanLineXY
dw _GrCircle
dw _CanCircle
namelib db 'Graph библиотека графических функций',0
_GrExec
nop
ret
_GrTime
_GrError
_GrExit
_GrMain
ld bc,SysExitGos
rst gos
ret
_CanLineOx
_CanLineOy
_CanRect
_CanFullRect
_CanLineXY
_CanCircle
ret
;*****************************************************
;Рисует окружность
; а - цвет
;hl,e - координаты центра - x,y
;d - радиус
_GrCircle
; инициализируем переменные по алгаритму
ld (cir_col),a
ld a,d
ld (cir_y),a
xor a
ld (cir_x),a
ld d,a
ld (cir_yc),de
ld (cir_xc),hl
; определяем переменную приближения D=3-2*r
ld hl,3
ld de,(cir_y)
sla e
rl d
sbc hl,de
ld (cir_d),hl
in a,(PAGE3) ;запомнить окно 3
ld (cir_sp3+1),a
ld a,VPAGE
out (PAGE3),a ;подключить видеостраницу
lop_cir
ld a,(cir_x)
ld c,a
ld a,(cir_y)
cp c
jp c,end_cir
; вывод точек на экран
;**********************************
ld hl,(cir_xc)
ld de,(cir_x)
add hl,de
ld de,Screen_offset
add hl,de
ld a,(cir_yc)
ld c,a
ld a,(cir_y)
add a,c
jr c,c1_n1
out(PORT_Y),a
ld a,(cir_col)
ld (hl),a
c1_n1 ld a,(cir_y)
ld c,a
ld a,(cir_yc)
sub c
jr c,c1_n
out(PORT_Y),a
ld a,(cir_col)
ld (hl),a
;***********************************
c1_n ld hl,(cir_xc)
ld de,Screen_offset
add hl,de
ld de,(cir_x)
sbc hl,de
ld a,(cir_yc)
ld c,a
ld a,(cir_y)
add a,c
jr c,c2_n1
out(PORT_Y),a
ld a,(cir_col)
ld (hl),a
c2_n1 ld a,(cir_y)
ld c,a
ld a,(cir_yc)
sub c
jr c,c2_n
out(PORT_Y),a
ld a,(cir_col)
ld (hl),a
;*********************************
c2_n ld hl,(cir_xc)
ld de,(cir_y)
add hl,de
ld de,Screen_offset
add hl,de
ld a,(cir_yc)
ld c,a
ld a,(cir_x)
add a,c
jr c,c3_n1
out(PORT_Y),a
ld a,(cir_col)
ld (hl),a
c3_n1 ld a,(cir_x)
ld c,a
ld a,(cir_yc)
sub c
jr c,c3_n
out(PORT_Y),a
ld a,(cir_col)
ld (hl),a
;***********************************
c3_n
ld hl,(cir_xc)
ld de,Screen_offset
add hl,de
ld de,(cir_y)
sbc hl,de
ld a,(cir_yc)
ld c,a
ld a,(cir_x)
add a,c
jr c,c4_n1
out(PORT_Y),a
ld a,(cir_col)
ld (hl),a
c4_n1 ld a,(cir_x)
ld c,a
ld a,(cir_yc)
sub c
jr c,c4_n
out(PORT_Y),a
ld a,(cir_col)
ld (hl),a
c4_n
; определяем напрвление приращения D
ld a,(cir_d+1)
and a
jp m,cir_dmin
ld hl,(cir_x) ; d=d+4*(x-y)+10
ld de,(cir_y)
sbc hl,de
add hl,hl
add hl,hl
ld de,(cir_d)
add hl,de
ld de,10
add hl,de
ld (cir_d),hl
ld a,(cir_y) ;уменьшаем y
dec a
ld (cir_y),a
jr cir_dpl
cir_dmin ; d=d+4*x+6
ld hl,(cir_x)
add hl,hl
add hl,hl
ld de,(cir_d)
add hl,de
ld de,6
add hl,de
ld (cir_d),hl
cir_dpl ;увеличиваем x
ld a,(cir_x)
inc a
ld (cir_x),a
jp lop_cir
end_cir
cir_sp3 ld a,0 ;восстановить окно
out (PAGE3),a
ret
cir_col dw 0
cir_x dw 0
cir_y dw 0
cir_yc dw 0
cir_xc dw 0
cir_d dw 0
;*****************************************************
;Рисует вертикальную линию
; а - цвет
;hl,de - координаты начала - x,y
;hl`,de` - координаты конца - x,y
_GrLineOy
ld (loy_col3+1),a
in a,(PAGE3) ;запомнить окно 3
ld (loy_sp3+1),a
ld a,VPAGE
out (PAGE3),a ;подключить видеостраницу
ld a,e
out (PORT_Y),a ;определить переменные y,
ld bc,Screen_offset
add hl,bc ;определить переменные x,
exx
ld a,e
ld (loy_yl+1),a
exx
di
ld d,d ;команда ускорителя - длинна операции
loy_yl ld a,0
ld b,b
loy_col3 ld a,0
ld e,e ;команда ускорителя - тело операции
ld (hl),a
ld b,b
ei
loy_sp3 ld a,0 ;восстановить окно
out (PAGE3),a
ret
;*****************************************************
;Рисует горизониальную линию
; а - цвет
;hl,de - координаты начала - x,y
;hl`,de` - координаты конца - x,y
_GrLineOx
ld (lox_col1+1),a
ld (lox_col2+1),a
in a,(PAGE3) ;запомнить окно 3
ld (lox_sp3+1),a
ld a,VPAGE
out (PAGE3),a ;подключить видеостраницу
ld a,e
out (PORT_Y),a ;определить переменные y,
ld bc,Screen_offset
add hl,bc ;определить переменные x,
ld (loxkor_x+1),hl
exx
ld a,l
ld (loxkor_xl+1),a
and a
jr z,inclox
ld a,h
inclox ld (loxblop+1),a
loxkor_x ld hl,0
di
loxblop ld a,0
and a
jr z,loxmop
ld d,d ;команда ускорителя - длинна операции
ld a,0
ld b,b
lox_col1 ld a,0
ld c,c ;команда ускорителя - тело операции
ld (hl),a
ld b,b
inc h
loxmop ld d,d ;команда ускорителя - длинна операции
loxkor_xl ld a,0
ld b,b
lox_col2 ld a,0
ld c,c ;команда ускорителя - тело операции
ld (hl),a
ld b,b
ei
lox_sp3 ld a,0 ;восстановить окно
out (PAGE3),a
ret
;**************************************************
;Рисует контурный прямоугольник
; а - цвет
;hl,de - координаты начала - x,y
;hl`,de` - высота ширина - dx,dy
_GrRect
ld (rec_col1+1),a
ld (rec_col2+1),a
ld (rec_col3+1),a
in a,(PAGE3) ;запомнить окно 3
ld (rec_sp3+1),a
ld a,VPAGE
out (PAGE3),a ;подключить видеостраницу
ld a,e
out (PORT_Y),a ;определить переменные y,
ld (rec_y+1),a
ld bc,Screen_offset
add hl,bc ;определить переменные x,
ld (reckor_x+1),hl
exx
ld a,e
ld (rec_yl+1),a
ld (rec_dx+1),hl
ld a,l
ld (reckor_xl+1),a
and a
jr z,inchtr
ld a,h
inchtr ld (recblop+1),a
ld b,2
reckor_x ld hl,0
di
recblop ld a,0
and a
jr z,rsmop
ld d,d ;команда ускорителя - длинна операции
ld a,0
ld b,b
rec_col1 ld a,0
ld c,c ;команда ускорителя - тело операции
ld (hl),a
ld b,b
inc h
rsmop ld d,d ;команда ускорителя - длинна операции
reckor_xl ld a,0
ld b,b
rec_col2 ld a,0
ld c,c ;команда ускорителя - тело операции
ld (hl),a
ld b,b
ei
in a,(PORT_Y)
add a,e
out (PORT_Y),a
djnz reckor_x
ld hl,(reckor_x+1)
ld b,2
rec_y ld a,0
out (PORT_Y),a
di
ld d,d ;команда ускорителя - длинна операции
rec_yl ld a,0
ld b,b
rec_col3 ld a,0
ld e,e ;команда ускорителя - тело операции
ld (hl),a
ld b,b
ei
rec_dx ld de,0
add hl,de
djnz rec_y
rec_sp3 ld a,0 ;восстановить окно
out (PAGE3),a
ret
;**************************************************
;Рисует заполненный прямоугольник
; а - цвет
;hl,de - координаты начала - x,y
;hl`,de` - высота ширина - dx,dy
_GrFullRect
ld (fulr_col1+1),a
ld (fulr_col2+1),a
in a,(PAGE3) ;запомнить окно 3
ld (fulr_sp3+1),a
ld a,VPAGE
out (PAGE3),a ;подключить видеостраницу
ld a,e
out (PORT_Y),a ;определить переменные y,
ld bc,Screen_offset
add hl,bc ;определить переменные x,
ld (frkor_x+1),hl
exx
ld a,l
ld (frkor_xl+1),a
and a
jr z,inch
ld a,h
inch ld (rbiglop+1),a
ld b,e
lopfrect
frkor_x ld hl,0
di
rbiglop ld a,0
and a
jr z,smallop
ld d,d ;команда ускорителя - длинна операции
ld a,0
ld b,b
fulr_col1 ld a,0
ld c,c ;команда ускорителя - тело операции
ld (hl),a
ld b,b
inc h
smallop ld d,d ;команда ускорителя - длинна операции
frkor_xl ld a,0
ld b,b
fulr_col2 ld a,0
ld c,c ;команда ускорителя - тело операции
ld (hl),a
ld b,b
ei
in a,(PORT_Y)
inc a
jr z,fulr_sp3
out (PORT_Y),a
djnz lopfrect
fulr_sp3 ld a,0 ;восстановить окно
out (PAGE3),a
ret
;*****************************************************
;Рисует линию
; а - цвет
;hl,de - координаты начала - x,y
;hl`,de` - координаты конца - x,y
;*****************************************************
_GrLineXY
ld (line_col1+1),a
ld (line_col2+1),a
in a,(PAGE3) ;запомнить окно 3
ld (lxy_sp3+1),a
ld a,VPAGE
out (PAGE3),a ;подключить видеостраницу
ld a,e
out (PORT_Y),a ;определить переменные y,
push de
push hl
ld bc,Screen_offset
add hl,bc
exx ;определить переменные x в hl`
pop bc
and a
sbc hl,bc
jr nc,l_xok
ld a,255
xor h
ld h,a
ld a,255
xor l
ld l,a
inc hl
ld (line_dx1+1),hl ;определить переменные dx
ld (line_dy2+1),hl
ld hl,-1
jr l_xno
l_xok ld (line_dx1+1),hl
ld (line_dy2+1),hl
ld hl,1
l_xno ld (line_sx1+1),hl ;определить знак прироста sx
ld (line_sx2+1),hl
pop bc
ex de,hl
and a
sbc hl,bc
jr nc,l_yok
ld a,255
xor h
ld h,a
ld a,255
xor l
ld l,a
inc hl
ld (line_dy1+1),hl ;определить переменные dy
ld (line_dx2+1),hl
ld a,-1
jr l_yno
l_yok ld (line_dy1+1),hl
ld (line_dx2+1),hl
ld a,1
l_yno ld (line_sy1+1),a ;определить знак прироста sy
ld (line_sy2+1),a
ld hl,(line_dx1+1)
ld de,(line_dy1+1)
and a
sbc hl,de
jr c,CH_NZ ; определить направление прироста координат
CH_Z ld hl,(line_dy1+1)
ld de,(line_dx1+1)
srl d
rr e
and a
sbc hl,de
exx ;определить переменную приближениея E - в hl`
ld bc,(line_dx1+1) ; инициализвция цикла
ld a,c
ld c,b
ld b,a
and a
in a,(PORT_Y)
jr z, l256
linelop ; в начале цикла в hl - x
line_col1 ld e,0
ld (hl),e
exx
bit 7,h
jr nz,E_min ; нужно ли уменьшать Е ?
line_dx1 ld de,0 ;(line_dx)
and a
sbc hl,de ;уменьшаем Е
line_sy1 add a,0 ;приращение координат y
out (PORT_Y),a
E_min exx
line_sx1 ld de,0 ; (line_sx)
add hl,de
exx
line_dy1 ld de,0 ; (line_dy)
add hl,de ; увеличиваем Е
exx
djnz linelop
l256 dec c
jr z,linelop
line_exit
lxy_sp3 ld a,0 ;восстановить окно
out (PAGE3),a
ret
CH_NZ
; определить переменную приближениея Е
ld hl,(line_dy2+1)
ld de,(line_dx2+1)
srl d
rr e
and a
sbc hl,de
exx ; E - в hl`
; цикл прорисовки
ld bc,(line_dx2+1)
ld a,c
ld c,b
ld b,a
and a
in a,(PORT_Y)
jr z, l256z
linelop2 ; в начале цикла в hl - x
line_col2 ld e,0
ld (hl),e
exx
bit 7,h
jr nz,E_min2 ; нужно ли уменьшать Е ?
line_dx2 ld de,0 ;(line_dx)
and a
sbc hl,de
exx
line_sx2 ld de,0 ;(line_sx)
add hl,de
exx
E_min2
line_sy2 add a,0
out (PORT_Y),a
line_dy2 ld de,0 ;(line_dy)
add hl,de
exx
djnz linelop2
l256z dec c
jr z,linelop2
jr line_exit