Следующие две процедуры -улучшенные аналоги программ Куликова Вадима, которые были опубликованы в 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
ЗЗак. 119
Ж&~Р<жу> Wfl
ЭТЮДЫ
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
КООРДИНАТА ;старший байт картинки, выравненной на сегмент (адрес, кратный 256):
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 данная процедура
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 РЕВЮ три свои программы.
СОДЕРЖАНИЕ:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Форум-Игры - в разделе рассмотрены: Dun Darach, Murray Mause (Supercop), Wild West Seymour, Sim City, Hero Quest, Dizzy-Y, Apollo, Cliffhanger, Laser Squad, Movie, Elite, Where Time Stood Still, Sceptre, Carrier Command, Math Day.
-
-
-
-
-
-
-
-
-