Расчет адреса в экране

Материал из SpeccyWiki
Перейти к: навигация, поиск

В силу познакоместной и нелинейной раскладки видеопамяти, расчет адреса в экранной памяти по координатам может вызывать сложности у начинающих программистов. Точность расчета адреса по вертикали может быть как попиксельная (0..191), так и познакоместная (0..23). Точность адреса расчета по горизонтали - только познакоместная (0..31). Для расчета адреса в области атрибутов применима только познакоместная точность.

; Адрес экрана, используемый в процедурах ниже
; Для обычного экрана- #4000. Для рисования на втором экране- #c000
; Используя другие адреса можно рассчитывать координаты и во внеэкранных буферах.
; Адрес должен быть кратен #2000 - для других адресов процедуры придется усложнять
SCREEN_ADDR EQU #4000
ATTR_ADDR EQU SCREEN_ADDR+#1800
; Расчет адреса в экранной области с точностью до знакоместа
; Входные параметры:
;  L - координата по оси ординат (0..23)
;  H - координата по оси абсцисс (0..31)
; Результат:
;  HL - адрес в экранной области
; Замечание:
;  используется аккумулятор

        LD A,L
        AND 7
        RRCA 
        RRCA 
        RRCA 
        ADD A,H
        LD H,L
        LD L,A
        LD A,H
        AND #18
        OR SCREEN_ADDR/#100
        LD H,A
; Расчет адреса в области атрибутов с точностью до знакоместа
; Входные параметры:
;  L - координата по оси ординат (0..23)
;  H - координата по оси абсцисс (0..31)
; Результат:
;  HL - адрес в области атрибутов
; Замечание:
;  используется аккумулятор

        LD A,H
        LD H,L
        LD L,0
        AND A
        DUP 3  ;повторить участок между DUP/EDUP 3 раза
        RR H
        RR L
        EDUP 
        ADD A,L
        LD L,A
        LD A,H
        OR ATTR_ADDR/#100
        LD H,A

Также может быть полезна следующая процедура

; Входные параметры:
;  HL - адрес в экранной области
; Результат:
;  HL - адрес в области атрибутов
; Замечание:
;  используется аккумулятор

        LD A,H
        AND #18
        RRCA 
        RRCA 
        RRCA 
        ADD A,ATTR_ADDR/#100
        LD H,A