Как поставить точку на экране процедурой PLOT

ZX Land #05

Как поставить точку на экране?

В самом начале «байткового» курса ассемблера прозвучало утверждение: неважно, быстрая ли программа, лишь бы она была короткой. Подобной позиции придерживается большинство преподавателей программирования в высших учебных заведениях. Что ж, не желая оспаривать мнение признанных авторитетов, я хотел бы представить процедуру PLOT. Она занимает 1 КБ (±15 байт), но выполняется за 68 тактов.

 10    LD  L,y
 20    LD  E,x

 30    LD  H,TABY1
 40    LD  D,TABX1
 50    LD  A,(DE)
 60    INC D
 70    ADD A,(HL)
 80    INC H
 90    LD  H,(HL)
100    LD  L,A
110    LD  A,(DE)
120    OR  (HL)
130    LD  (HL),A

Инструкции в строках 10 и 20 не являются частью процедуры. Они устанавливают координаты точки: x и y — числа, обозначающие координаты точки на экране.

Строки 30 и 40 задают старшие байты адресов таблиц, то есть теперь регистровые пары HL и DE указывают соответственно на позиции y и x в таблицах TABY1 и TABX1. В A помещаем значение из TABX1 — позицию точки по горизонтали с точностью до знакоместа. Увеличиваем D, и теперь в DE находится адрес позиции x в TABX2.

К A прибавляем значение из TABY1 — позицию точки по вертикали с точностью до знакоместа в пределах одной страницы памяти (256 байт). Увеличиваем H, и теперь в HL находится адрес позиции y в TABY2. В H помещаем значение из TABY2 — старший байт экранного адреса, то есть позицию точки по вертикали с точностью до графической строки. В L помещаем A — уже вычисленный младший байт экранного адреса, а в A — значение из TABX2, которое задаёт позицию пикселя внутри байта (разумеется, с точностью до точки).

Теперь складываем A с содержимым экранной ячейки и помещаем результат в экранную память. Чтобы получить режим OVER 1, вместо OR (HL) используйте XOR (HL).

Стоит заметить, что HL разрушается, а DE — не полностью. Если перед следующим вызовом процедуры мы не используем DE, вместо LD DE,TABX1 можно выполнить DEC D.

Процедура была бы бесполезна без таблиц — вот они. Таблицы занимают по 256 байт, должны начинаться с начала страниц памяти и располагаться на следующих друг за другом страницах, например:

#8000 TABX1, #8100 TABX2, ...
TABX1 - 0*8, 1*8, 2*8 ...
        30*8, 31*8 ; то есть
        8 нулей, 8 единиц и так далее

TABX2 - 128,64,32,16,8,4,2,1
        --------------------
                *32
         (то есть последовательность
        повторить 32 раза)

TABY1 - 0*8, 32*8, 64*8, 96*8
        128*8, 160*8, 192*8,
        224*8
        -----------------------
        всю последовательность
        повторить 3 раза

        оставшиеся 64 байта —
        любые; здесь можно разместить
        какую-нибудь короткую процедуру

TABY2 - 64,65,66,67,68,69,70,71
        -----------------------
        всю последовательность повторить 8 раз

        72,73,74,75,76,77,78,79
        -----------------------
        всю последовательность повторить 8 раз

        80,81,82,83,84,85,86,87
        -----------------------
        всю последовательность повторить 8 раз

        оставшиеся 64 байта —
        любые, лучше всего нули

При такой конфигурации экрана точка (0,0) находится в левом нижнем углу экрана, а (255,191) — в правом верхнем, то есть экран включает и системное окно. Если заполнить TABY2 нулями, выводить точку с координатой y > 191 будет безопасно.

Ещё одно преимущество использования таблиц — возможность произвольно настраивать экран; я не раз этим пользовался.

DC PAK/EXODUS

Поделитесь вашим мнением о статье