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

Этюды - примеры улучшения процедур.


Следующие две процедуры -улучшенные аналоги программ Куликова Вадима, которые были опубликованы в ZX РЕВЮ 96/3, стр. 34. Теперь процедуры сдвига экрана вверх и вниз на один пиксел занимают по 33 байта каждая (вместо 46 и 44 соответственно). Строки листинга, заданные как комментарии, отвечают за очистку нужной линии изображения после сдвига (нижняя для SRL UP и верхняя - для SRL DN). Если очистка необходима, то просто удалите; в началах этих строк. В этом случае процедуры будут занимать 38 и 39 байт соответственно. SRLJJP

LD DE,#4000 LP_SU1 LD H,D LD L,E LD ВС, #0020 INC H LD A,H AND #07 JR NZ,GO_SU1 LD A.L ADD А,С LD L,A JR C,GO_SU1 LD A.H SUB #08 LD H,A GO_SU 1 PUSH HL LDIR

POP DE LD A,H CP #58 JR C,LP.SU 1 ; XOR A

;LP_SU2 LD (DE),A INC E

JR NZ,LP_SU2 RET

#08 #FF #08 #0E

ЭТЮДЫ

ЗЗак. 119

Ж&~Р<жу> Wfl

SRL.DN

ЭТЮДЫ

LPFLR1

LD LD

С,YRWIND HL,BEG_LN

LP.SD1

LD

DE,#57FF

LD

B,C

LD

H,D

LPFLR2

PUSH

ВС

LD

L.E

LD

D.H

LD

ВС,#0020

LD

E,L

LD

A,H

LD

A,H

DEC

H

DEC

H

AND

#07

AND

#07

JR

NZ.GO SD1

JR

NZ.GOFLR1

LD

A.L

LD

A,L

SUB

С

SUB

#20

LD

L,A

LD

L.A

JR

C,GO SD1

JR

C.GOFLR1

LD

A,H

LD

A,H

ADD

A,#08

ADD

A,#08

LD

H,A

LD

H,A

PUSH

HL

GOFLR1

LD

C,L

LDDR

LD

B,XRWIND

POP

DE

LPFLR3

LD

A,(DE)

LD

A.H

PUSH

AF

CP

#40

OR

(HL)

JR

NC.LP SD1

LD

(DE),A

XOR

A

POP

AF

LD

(DE),A

AND

(HL)

DEC

E

LD

(HL),A

JR

NZ.LP SD2

INC

E

LD

(DE),A

INC

L

RET

DJNZ

LPFLR3

В ZX РЕВЮ 96/6 на стр. 40 приведена процедура осыпания экрана. Мне удалось немного упростить структуру программы и уменьшить объем занимаемой памяти (с 52 до 47 байт). Изменяемые константы:

• XRWIND ширина окна осыпания в знакоместах;

• YRWIND высота окна осыпания в пикселях;

• BEG LN - адрес нижнего правого угла окна в экране.

Итак, вот новая процедура: XRWIND EQU 32 YRWIND EQU 191 BEG_LN EQU #57E0

FALLER

LD L,C POP ВС DJNZ LPFLR2 DEC С JR NZ.LPFLR1 RET

В одном из украинских РЕВЮ я увидел процедуру "переворачивания" экрана. Кажется, ее длина была 56 байт не помню. Так вот, чтобы украинские кодеры не расслаблялись и не поплевывали свысока на наших, я написал свою процедуру, которая занимает всего 36 (!) байт. Итак, УКРАИНА vs РОССИЯ: TRNSCR

LD HL,#597F LD DE,#5980 LP_TS 1 LD A,(DE)

LP TS2

LP TS3

LDI

DEC

HL

LD

(HL),A

DEC

HL

BIT

3,H

JR

NZ.LP TS1

LD

D,#40

LD

A.(DE)

LD

B,#08

RLA

RR

(HL)

DJNZ

LP_TS3

RLA

LD

(DE),A

INC

DE

DEC

HL

LD

A,D

CP

#4C

JR

NZ.LP TS2

RET

Недавно, один из моих друзей попросил меня написать процедуру для эффектного вывода картинки на экран. В чем же оригинальность? Дело в том, что картинка появляется на экране постепенно раскручивающейся спиралью по часовой стрелке. Причем, центр раскрутки задается произвольно и даже может находиться за пределами экрана. Итак, автор идеи - Андреев Андрей (LONE WOLF, Шадринск), ну а программу написал ваш покорный слуга.

Перед вызовом CALL OUTSCR необходимо в регисте Е установить координату X центра спирали, а в регистре D - координату Y. В регистре А (аккумуляторе) должен находиться старший байт адреса картинки. А сама картинка должна располо-гаться в памяти с адреса, кратного 256.

Подпрограмма PUT_ZN выводит на экран одно знакоместо из

картинки, если координаты его лежат внутри экрана.

Длина процедуры 118 байт. ORG #8000

EXAM PL

LD E,15 ;X -

КООРДИНАТА LD D, 11 ;Y

7Х-Р<гаю >7/1

ЭТЮДЫ

КООРДИНАТА ;старший байт картинки, выравненной на сегмент (адрес, кратный 256):

LD

A,SCREEN/256

OUTSCR

SUB

#40

EX

AF.AF'

LD

C,#01

LP OSO

LD

в,а

LP_OS 1

CALL

PUT ZN

INC

E

; ВПРАВО

DJNZ

LP OS1

LD

B,C

LP_OS2

CALL

PUT ZN

INC

D

;ВНИЗ

DJNZ

LP OS2

INC

С

LD

В,С

LP_OS3

CALL

PUT ZN

DEC

E

;B/IEBO

DJNZ

LP OS3

LD

B.C

LP__OS4

CALL

PUT ZN

DEC

D

; ВВЕРХ

DJNZ

LP OS4

INC

С

LD

A,E

CP

#20

JR

C,LP_OSO

;X - в экране

ADD

А,С

CP

#20

JR

С, LP OSO

;Х - в экране

LD

A,D

СР

#18

JR

C,LP_OS0

;Y - в экране

ADD

A.C

CP

#18

JR

C,LP OSO

;Y - в экране

;иначе - повсюду вышли за экран! RET

;выход из процедуры PUT.ZN

PUSH

ВС

LD

A,30

;величина задержки

LPPZN1

EX

AF.AF'

LD

C,A

PUSH

DE

LD

A,E

CP

#20

JR

NC, GOPZN 1

;X вне экрана

LD

A,D

CP

#18

JR

NC.GOPZN1

;Y вне экрана

AND

#07

RRCA

RRCA

RRCA

ADD

A,E

LD

E.A

LD

A,D

AND

#18

OR

#40

LD

D.A

ADD

А,С

LD

H,A

LD

L.E

LD

B,#08

LPPZN2

LD

A.(HL)

; перенос

LD

(DE).A

графики

INC

H

INC

D

DJNZ

LPPZN2

D

A,D

#03

#58

D,A

A,C

H,A

A,(HL)

(DE),A

;перенос

; атрибута GOPZN1 POP DE LD A,C EX AF.AF' DEC A JR NZ.LPPZN1

POP ВС RET

;выход из подпрограммы выравнивание на сегмент:

DS

SCREEN INSERT ; КАРТИНКА

В одном

$/256*256 + 256-$ "myface.$"

из номеров ZX РЕВЮ читатели подали очень хорошую мысль насчет публикации адресов различных подпрограмм TR DOS для различных версий ПЗУ. Но это так и не решает проблемы при появлении новых версий ROM, в которых по каким-либо причинам процедуры расположены по другим адресам. Мне пришла в голову мысль:

А ПОЧЕМУ БЫ НЕ ИСКАТЬ НЕОБХОДИМЫЕ ПОДПРОГРАММЫ В ТОМ ПЗУ, КОТОРОЕ СТОИТ В КОНКРЕТНОМ КОМПЬЮТЕРЕ?!

Сказано сделано... В результате получилась система процедур именно для этих целей. Теперь можно в любом ПЗУ TR DOS искать именно те процедуры, которые нужны для работы конкретной программы.

DEC

LD

RRA

RRA

RRA

AND

OR

LD

ADD

LD

LD

LD

этюды

Ну, а если необходимая процедура все-же так и не найдена, то ее можно заменять другими, менее эффективными (как, например, чтение регистра состояния). В итоге получим как бы самонастраивающийся дисковый интерфейс.

Процедуры: TRCOPY аналог команды LDIR, но копирует данные из ПЗУ TR-DOS. Длина копируемого блока должна быть кратна 16. Регистры, задаваемые при вызове:

HL адрес в ПЗУ (откуда копировать)

DE - адрес буфера (куда копировать)

ВС длина копируемого блока

ABSEEK - поиск нужной последовательности байтов в памяти и выдача смещения найденной последовательности относительно начала проверяемого блока памяти.

На входе: HL блока

DE адрес последовательности, которую ищем ВС длина проверяемого блока

А длина последовательности На выходе:

Z_flag=0 (NZ) - нужная последовательность не найдена.

Z flag=l (Z) последовательность найдена и находится со смещением HL от начала проверяемого блока.

адрес проверяемого

отсутствует.

ORG

EXAMPL

ЭТЮДЫ

SEEKER - аналогична предыдущей точке входа, но при найденной последовательности выдает не адрес смещения от начала блока, а реальный адрес расположения последовательности в памяти.

Процедуры ABSEEK и SEEKER можно использовать и для других целей в своих программах (с указанием авторства, естественно).

В приведенном ниже примере в ПЗУ TR DOS ищется процедура вывода в порт ВС регистра А. При вызове из бейсика командой PRINT USR 32768 программа напечатает адрес найденной процедуры или выдаст сообщение об ошибке FOUND, б

VARIABLE NOT данная процедура

#8000

ER.EX1 ;VARIABLI BUFFER FORFND

LD

HL,#0000

LD

DE.BUFFER

LD

ВС, #4000

PUSH

DE

PUSH

ВС

CALL

TRCOPY

POP

ВС

POP

HL

LD

DE,FORFND

LD

A.FNDLEN

CALL

ABSEEK

JR

NZ.ER EX1

LD

B.H

LD

C,L

RET

RST

#08

DB

#01

:NOT FOUND

EQU

#C000

OUT

(C),A

RET

ЭТЮДЫ

TRCOPY

PUSH

ВС

EQU

S-FORFND

LP.SK2

EX

AF.AF'

DEC

A

JR

Z.EX.SK1

PUSH

ВС

;Fz=1

PUSH

HL

EX

AF.AF'

PUSH

DE

INC

DE

LD

C,#13

LD

A.(DE)

CALL

#3D13

CPI

POP

DE

JR

NZ.GO SK1

LD

HL,#5CDD

JP

PE.LP SK2

LD

BC,#0010

EX

AF.AF'

LDIR

DEC

A

POP

HL

;Fz=(A=0)

LD

C,#10

EX_SK1

POP

ВС

ADD

HL.BC

POP

DE

POP

ВС

POP

HL

LD

A,C

DEC

HL

SUB

#10

RET

LD

C,A

GO_SK1

POP

ВС

JR

NC.TRCOPY

POP

DE

LD

A.B

POP

HL

SUB

#01

LB_SK1

LD

A.O

LD

B.A

JR

LP SK1

JR RET

NC.TRCOPY

ABSEEK

PUSH HL CALL SEEKER POP DE RET NZ

;Fz=0 -> not found AND A SBC HL.DE XOR A RET

В заключение хочется добавить, что все приведенные здесь программы были написаны и отлажены на великолепном ассемблере ZX ASM 3.0 (данная статья тоже набиралась на нем) и пожелать всем дочитавшим до этого места ВСЕГО НАИЛУЧШЕГО!

(с) Евгений Куликаев, р.п. Муром-цево/96

Представляю на суд читателей ZX РЕВЮ три свои программы.




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
Сделай сам - - Сделай сам себе визитку.
Архивчик - Mikie, Sabre Wulf.
Итоги - неофициальные предварительные итоги ENLIGHT'97.
Штирлиц - С пеpвoгo нoмеpa гaзеты мы pешили нaчaть цикл paсскaзoв пpo шпиoнa 009 - Штиpлицa.
Умные игры - Прохождение игры "Dragonia".

В этот день...   19 апреля