ZX-Ревю 1996 №4-5 1996 г.

Этюды - о табличном программировании.


ЭТЮДЫ

© А.Астафьев, г.Новосибирск

КОРР: То, что вы назвали "гасилкой экрана", называется FADE-OUT эффектом (это принято во всем мире), а "зажигалка", соответственно, называется FADE-IN эффектом.

Проанализировав предыдущие процедуры, я пришел к выводу, что все забыли об одном замечательном методе программирования - табличном программировании. А зря. Порой, метод табличного программирования дает изящное, простое и, главное, быстродействующее решение. Ниже, как иллюстрацию данного метода, я привожу FADE-OUT, гасящую экран "как в TERMINATORS".

ORG

#8000

PREPARE

LD

HL,DAL_TBL

PREP_T

LD

A, L

AND

7

JR

z, $+3

DEC

A

LD

E,A

LD

A, L

AND

#38

JR

Z, $ + 4

SUB

8

OR

E

LD

(HL),A

INC

L

JR

NZ,PREP_T

FADEOUT

LD

D,DAL_TBL/256

LD

B, 7

W_RAY

HALT

LD

HL,#5800

ATR_DEC

LD

E,(HL)

LD

A,(DE)

LD

(HL),A

INC

HL

LD

A, H

CP

#5B

JR

C,ATR_DEC

DJNZ

W_RAY

RET

ORG

$&#FF00+256

DAL_TBL

DEFS

256

в D - старший байт адреса таблицы

ровно 7 переходов

ждем сканирования экрана

это адрес атрибутов

берем код атрибута

и заменяем его значением из таблицы повторяем 7 68 раз до конца области атрибутов

адрес таблицы на 256 байт

256

выравниваем резервируем

Пару слов по данной процедуре. Написана она в TASM128, который легко дает возможность определить адреса таблиц, кодов и т.п. более простыми методами, чем ZEUS. Сама же процедура создает для своей работы таблицу из 256 байт. Таблица располагается по адресу, выровненному на 256 - с такими таблицами процессору проще работать, так как от элемента к элементу в таблице можно переходить командами INC L или DEC L (предполагаем, что адрес таблицы находится в HL), а от таблицы к таблице переходить командами INC H / DEC H. Аналогичным образом, элементарно находятся и элементы в таких таблицах. Порой, достаточно загрузить номером элемента младшую часть адресного регистра. Вдобавок ко всему, подобные таблицы (если, конечно, занимаются все 256 байт таблицы) обладают способностью "заворота". Вот простой пример:

повторяем 7 раз на случай белого цвета

HL,#BE00 A,STEP A, L L,A

(POINTER+1) A, (HL)

таблицы

POINTER

LD

LD

ADD

LD

LD

LD

смещение где STEP

на элемент знаковое!

HL

Здесь каким бы ни было значение STEP - мы можем "летать" по таблице, перескакивая хоть по 50 элементов, но никогда не вырвемся за ее пределы!

Если требовался бы двухбайтный результат - легко продолжить:

INC H

LD H, (HL)

LD L,A

Но вернемся-таки к нашей процедуре FADE-OUT. Если не быть буквоедом, пожертвовать памятью, то можно написать процедуру - рекордсмен по длине. Пусть дополнительно использованы 2048 байтов, пусть предварительно нужно прогнать процедуру, которая выстраивает эту таблицу, но зато какой результат! И все как в TERMINATORS!

ORG

#8000

PAL_TBL

EQU

0-256*8

FADEOUT

LD

D,PAL_TBL/256

W_RAY

HALT

LD

H, #5A

ATR_DEC

LD

E,(HL)

LD

A,(DE)

LD

(HL),A

DEC

HL

BIT

3,H

JR

NZ,ATR_DEC

INC

D

JR

NZ,W_RAY

RET

PREPARE

LD

HL,PAL_TBL

LD

BC,#0800

FILL_T

LD

A, L

AND

7

JR

z, $+3

DEC

A

LD

E,A

LD

A, L

AND

#38

JR

Z, $ + 4

SUB

8

OR

E

LD

(HL),A

CP I

JP

PE, FILL_T

RET

LITRLE TRICK

Сама процедура FADE-OUT занимает 17 байт. Для приготовления таблицы можно использовать несколько модифицированную PREPARE. И под конец, для затравки умов читателей, приведу пример процедуры установки точки на экран, которая, во-первых, сама по себе работает очень быстро, и, во-вторых, также является иллюстрацией табличных методов программирования. Из особенностей этой процедуры приведу следующую - не требуется никаких дополнительных вычислений, чтобы ограничить размер экрана по Y-координате. Вследствие того, что для точек с координатами больше 191, таблица просто заполнена нулями - точка просто не ставится на экран, процедура посылает данные в адрес 0...31, где находится ПЗУ. Таблица занимает 1K памяти и, конечно же, выровнена на адрес, кратный 256. Я называю такие адреса -"адресами начала параграфа", где параграф - блок 256 байтов с адреса, кратного 256. Вообще, во всех 8-битных процессорах такие блоки называют страницами (64K=256 страниц по 256 байт), но я, чтобы избежать путаницы со страницами 128-ого Спектрума, называю их параграфами. PSET

SET TBL

LD

H,SCR_TBL/256

H - начало таблицы

LD

L, E

в L загружаем X-координату

LD

C, (HL)

берем байт с необходимым битом

INC

H

шагаем к следующему

параграфу

LD

A, (HL)

берем значение X/8 -

это номер

столбца

INC

H

LD

L, D

теперь нужна Y-координата

OR

(HL)

HL указывает сейчас

на младшую

часть адреса

INC

H

LD

H, (HL)

берем старшую часть

адреса

LD

L,A ;

в HL - адрес точки,

в C - нужный бит

LD

A, (HL)

ставим точку по OR

OR

C

LD

(HL),A

RET

LD

HL,SCR_TBL

в HL - адрес таблицы

SET DOT

SET_DIV

SET_ADR

LD

B, L

;

в B=00, так как таблица выровнена

LD

A, #80

;

начинаем от старшего бита

LD

(HL),A

;

и заносим его в список

RRCA

;

переходим к следующему биту

INC

HL

DJNZ

SET_DOT

;

и так 256 раз

LD

A, L

RRCA

;

три вращения для деления на 8

RRCA

RRCA

AND

31

;

а можно бы было дать три раза SRL A

LD

(HL),A

;

так мы заносим в (HL) значение L деленное

INC

HL

DJNZ

SET_DIV

;

и так 256 раз

LD

B, #C0

;

требуется 192 экранных адреса

LD

DE,#4000

;

адрес левого столбца - самая верхушка

LD

(HL),E

INC

H

LD

(HL),D

;

грузим DE в два параграфа. E в первый; D

на 8

H

L

D_STEP SET_ADR

второй

D_STEP

D

A, D

7

NZ A, E A,32 E,A

C

A, D

8

D,A

DEC

INC

CALL

DJNZ

RET

INC

LD

AND

RET

LD

ADD

LD

RET

LD

SUB

LD

RET

ORG

DEFS

смещаем на байт (точку) ниже повторим 192 раза

смещаемся на 256 в экране - байт вниз проверка - это следующее знакоместо?

если нет - вернемся обратно сместимся на знакоместо вниз (+32)

должны перейти в следующую треть - возвращаемся иначе компенсируем результат восьми INC D возвращаем адрес в текущую треть экрана (треть, кстати, равна 256*8=2048 (256=INC D))

$&#FF00+256 256*4

резервируем 1K нулей средствами TASM12 8

SCR_TBL

Здесь процедура SET_TBL подготавливает эту таблицу. Сама таблица выглядит следующим обра-

зом:

#8100 256 байт - байты с установленным битом в соответствии с X. #8200 256 байт - значение в таблице = ее индекс/b (b - номер столбца (X)). #8300 192 байта в начале - младший байт адреса левого столбца экрана. #8400 первые 192 байта - аналогично, старшие байты.

Вот такие вот "пироги". Думаю, недолго домыслить, что с начала параграфа удобно хранить не только таблицы. Там можно размещать спрайты, фонт (что те же самые спрайты и есть), многобайтные переменные (для этого группируйте их), и т.д. и т.п. Кстати, не забывайте, что родной фонт размещается с адреса #3D00 - суть начала параграфа. Аналогично, и экран Спектрума тоже.




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Анекдоты - Юмор.
Железо - Львовский вариант - как расширить память до 512Кб.
События - Весенняя демосцена: правила DiHalt2006.
Игры - читы в игре HAMON IV: return to home from deathmanland.
Demo Parrt - место проведения CC'999.

В этот день...   21 ноября