ZX-Ревю 1997 №1-2 1997 г.

Этюды - процедура заполнения экрана.


ИФК: О своих успехах в освоении ассемблера решил написать Хороших Дмитрий из города Сосенский, Калужской области.

КОРР: Совсем недавно, после прочтения книги "ИНФОРКОМА" о программировании в машинных кодах (КИ1), я начал писать программы на Ассемблере (и что самое интересное -они даже начали работать). Я хочу предложить свою процедуру для заполнения экрана. Такой эффект я видел в игре "CJ in the USA" Я не стал взламывать программу, а решил написать свою процедуру, которая бы воспроизводила такой эффект. Идея алгоритма пришла мне в голову во время просматривания в книге Инфоркома "Элементарная графика" процедуры для закраски части экрана. Там используется конвейерная организация стека, которую я и применил в своей программе.

Процедура занимает всего 188 байт (без буфера). Экран обязательно должен располагаться с адреса 32768. Программе также требуется некоторая область памяти (100 байт в большинстве случаев будет предостаточно), которая определяется в строках 1070 и 1080. STK B F это физическая верхняя граница (конец) стека. В листинге под стек отдана область памяти с 41000 по 41100. Благодаря строкам 760-900 при "доезжании" конвейером до конца отданной ему области памяти, он автоматически копируется в начало, и таким образом использует отданную ему область памяти циклически. Программа может заполнять экран параллельно с любого количества мест. Это определяется заполнением конвейера: нужно занести в STK_BEG, которая является началом буфера, 41000, а в область памяти, начиная с 41000, координаты тех точек, с которых программа должна заполнять экран: сначала X, потом Y.

Например, для трех точек (10,6), (16,16) и (22,6) область памяти с 41000 по 41005 будет содержать значения 10,6,16,16,22,6. В переменной STKEND в таком случае должно быть 41006, т.е. она указывает на адрес на единицу больший, чем конец буфера. Единственным ограничением при использовании процедуры является то, что на экране не может быть знакоместа с атрибутом 0 (т.е. черный цвет на черном фоне). Я не думаю, что это серьезное ограничение, а процедура использует это для распознования тех мест, где она еще не закрасила экран.

Кстати, этот факт может использоваться для усложнения эффекта: например, если между строками 110 и 120 изменить цвет различных частей экрана на отличный от 0, то заполнение не коснется этих частей экрана, а если в каждом знакоместе объединить вывод цветовой и графической информации, то можно будет в один экран "впечатывать" фрагмент любого другого экрана, причем фрагмент произвольной формы. Достаточно только отметить этот участок атрибутом 0. Это может делать, например, процедура PRINT, вызов которой вставляется между строками 530 и 540. В таком случае строки 80-110 не нужны вообще, а строки 30-70 не нужны в том случае, когда пользова-

ЭТЮДЫ

этюды

те ль сам заполнит нужный уча-

Процедура заполнения экрана: FILL SCREEN

ORG 40000 ENT

LD HL,#5800

LD DE,#5801

LD BC,#2FF

LD (HL),L LDIR

LD HL,#8000

LD DE,#4000

LD ВС, #1800 LDIR

LD HL,(STKJ3EG)

LD D,(HL)

INC HL

LD E,(HL)

INC HL

LD (STK_BEG)

PUSH DE

LD A,E

OR A

JR Z,CONT_1

DEC E

CALL VERIFY

POP DE

PUSH DE

LD A.E

CP 28

JR Z,CONT_2

INC E

CALL VERIFY

POP DE

PUSH DE

LD A.D

OR A

JR Z,CONT_3

DEC D

CALL VERIFY

POP DE

PUSH DE

LD A.D

CP 31

JR Z,CONT_4

INC D

CALL VERIFY

POP DE

CALL TRANS

10 20 30 40 50 60 70 80 90 100 110

120 BEGIN 130 140 150 160 170 180 190 200 210 220 230

240 CONTJ

250

260

270

280

290

300

310 CONT.2

320

330

340

350

360

370

380 CONT_3

390

400

410

420

430

440

450 CONT_4 460

; экран

; заполняется ; атрибутом 0

;копирование ; графической ; информации ; на экран ; снятие координат ; с вершины конвейера и занесение в DE ; X -> DE, Y -> DE

; сохраним DE ; если Y=0, то на ; CONTJ

; иначе проверка ; точки сверху ; восстановим DE ; снова сохраним ; если Y=28, то на ; CONT_2

; иначе проверка точки снизу

сток атрибутом 0.

; аналогично ; слева

снимаем DE со стека вызов процедуры расчета ад-

аналогично справа

ЭТЮДЫ

реса в экранной области

470

LD

E.L

; преобразование

480

LD

A,H

старшего байта

490

AND

#03

адреса для буферного

500

OR

#98

экрана

510

LD

D.A

520

LD

A,(DE)

копирование атрибута

530

LD

(HL),A

из буфера в экран

540

LD

DE,(STK BEG)

; проверка, не кончились ли

550

LD

HL,(STK END)

; значения на конвейере

560

SBC

HL.DE

если да то конец

570

RET

Z

580

LD

B,#FF

590 PAUSE

DJNZ

PAUSE

пауза

600

JR

BEGIN

все сначала

610 VERIFY

CALL

TRANS

; пересчет координат

620

LD

A,(HL)

; проверка атрибута

630

OR

A

на экране

640

RET

NZ

; если не ноль - конец

650

LD

A,63

иначе атрибут 63 (белый

660

LD

(HL),A

по белому) и

670

LD

HL,(STK END)

занесение координат

680

LD

(HL),D

на конвейер

690

INC

HL

700

LD

(HL),E

710

INC

HL

720

LD

(STK END),HL

проверка - не достиг ли

730

LD

DE,(STK E F)

конец конвейера

740

SBC

HL.DE

физического конца

750

RET

NZ

если нет, то конец

760

LD

HL,(STK END)

иначе вычисляется

770

LD

DE,(STK BEG)

; длина конвейера...

780

SBC

HL.DE

790

LD

B,H

800

LD

C,L

810

PUSH

HL

сохраняется

820

LD

HL,(STK BEG)

и конвейер копируется

830

LD

DE,(STK E F)

в начало отведенной

840

PUSH

DE

; ему области памяти

850

LDIR

860

POP

DE

высчитываются новые

870

LD

(STK BEG),DE

начало и конец

880

POP

HL

конвейера

890

ADD

HL.DE

900

LD

(STK END),HL

910

RET

920 TRANS

LD

A,E ; на входе в DE - координата

930

AND

#18

в знакоместах

940

RRA

в D - X, E - Y

950

RRA

на выходе в HL - адрес

960

RRA

; в файле атрибутов

970

OR

#58

980

LD

H,A

990

LD

A.E

1000

AND

#07

1010

RRCA

1020

RRCA

1030

RRCA

1040

ADD

A,D

1050

LD

L,A

1060

RET

1070 STK_B_F 1080 STK_E_F 1090 STK.BEG 1100 ST К END

1110 ORG 41000

1120 DEFB 10,6

1130 DEFB 16,16

1140 DEFB 22,6

занесение координат на конвейер

Текст процедуры PRINT:

PRINT

10 PRINT

LD

A,H

пересчет адреса из файла

20

AND

#03

; атрибутов в дисплейный файл

30

RLCA

изменяется только старший байт

40

RLCA

50

RLCA

60

OR

#40

70

LD

H,A

; в HL - адрес на экране

80

AND

#18

90

OR

#80

100

LD

D,A

в DE - адрес в буферном экране

110

LD

B,#08

120 REP 1

LD

A,(DE)

копирование восьми

130

LD

(HL),A

; пиксельных линий

140

INC

D

; знакоместа

150

INC

H

160

DJNZ

REP 1

170

RET




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
От авторов - Редакция.
Анекдот - 3 анекдота. Смешилки - страшилки (4).
Конкурс - вам надо ответить хотя бы на 3 загадки.
Заметки СисОпа - Правила пользования ZX-Magazine BBS-2...
Вступление - содержание номера.

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