2.2.3 Движение спрайта в окне.
В предыдущих параграфах ны ознакомились с тем.
как выполняется скроллинг экрана и убедились в том, что его можно
использовать для оживления заднего плана. Но двигать весь экран
-занятие довольно расточительное как с точки зрения быстродействия, так
и в смысле расходуемой памяти. Гораздо практичнее бы ло бы рассмотреть
скроллинг в рамках небольшого окна, содержащего спрайт. Полезность
такой процедуры очевидна уже тем, что повторяя раз за разом прокрутку
спрайта (спрайтов) через окно. Вы можете создать ощущение непрерывной
последовательности и динамики движения. Сравните эту ситуацию с тем,
что Вы видите из окна быстродвижущегося поезда, с Вашей точки зрения
поезд стоит на месте, а мимо окна мелькают деревья, столбы и
придорожные постройки. Но полезность заключается не только в этом.
Можно представить систену экранных окон,
например такую, как на рис. 19 Спрайт постепенно "выползает" в первом
окне, проходит его и "скрывается" за рамой. После непродолжительной
задержки "выплывает" во втором окне, проходит его и повторяет то же
самое в третьем окне.
|
|
|
|
|
□
|
Окно 1
спрайт /
|
|
|
|
Окно 2
|
|
|
|
Окно 3
|
Рис. 19 Скроллинг в системе нескольких окон
дает полное ощущение того, что спрайт проходит за объектами переднего
плана (за рамой)
Формат процедуры для выполнения скроллинга в окне заданного размера - следующий: FN n(x,y,l,n,d,r).
Процедура скроллирует все то, что имеется в пределах окна, заданного параметрами х,у,1.
х,у - координаты окна. Они задаются для левого
верхнего угла окна. Способ задания координат здесь принят в
знакоместах, а не в пикселах.
0<=х<=31; 0<=у<=21
I - ширина окна (в знакоместах О...31)
II - номер спрайта, скроллируемого в окне.
d - direction - параметр, определяющий направление перемещения .
d-o - скроллинг вправо. d=l - скроллинг влево.
г - флаг повтора: г=0 - есть повтор; г=1 - нет повтора.
Здесь ничего не сказано о высоте окна. Предполагается, что высота его равна высоте спрайта, т.е. 21 пикселу.
Элементарные основы техники скроллирования
Задача скроллирования спрайта в окне - весьма
интересна и поучительна, поскольку дает наиболее полное художественное
впечатление для наблюдателя. Поэтому мы рассмотрим ее здесь подробнее,
чем прочие процедуры.
В основу техники гладкого попиксельного
скроллирования шаблона изображения здесь (как и в большинстве подобных
случаев) положены команды ротации байтов RRA (ротация аккумулятора
вправо) и RLA (рогация аккумулятора влево). Выбор той или другой
зависит от того, куда движется спрайт. Это то, что касается шаблона
спрайта, находящегося где-то в оперативной памяти. На экране же
скроллинг организован тоже командами ротации байта, но на этот раз RR
(HL) (ротация вправо) и RL (HL) (ротация влево) . При этом в
регистровой паре HL содержится адрес восьмипик-сельной линии экрана,
принадлежащей текущему знакоместу.
Весь прием основан на том, что при ротации
байта его крайний бит "откладывается" во флаг переноса (флаг С регистра
F) и потом "подхватывается" при ротации соседнего байта. Рассмотрим,
как это происходит для одной строки спрайта. Она имеет в ширину 24
пиксела, т.е. задана тремя байтами. Флаг переноса (С) в начале операции
должен быть обязательно обнулен. Это выполняется какой-либо логической
командой, например AND А.
- X - флаг С регистра F
Рис. 21 после первой операции RRA
Рис. 20. Исходное состояние.
после первой операции ротации для байта ХХХХ
ХХХХ его младший (крайний правый) бит перейдет во флаг С, а содержимое
флага С перейдет в старший (крайний левый) бит этого байта, т.е. он
обнулится. Так происходит ротация (скроллинг) вправо. Если бы нам надо
было скроллировать спрайт влево, то мы начинали бы не с байта ХХХХ
ХХХХ, а с байта ZZZZ ZZZZ.
Следующую операцию ротации вправо проводин для
соседнего справа байта (YYYY YYYY). Он "подхватывает" из флага С
младший бит от ХХХХ ХХХХ и помещает в свой старший бит. И так далее.
Н
- флаг С регистра F
Рис. 22 Результат трех операций RRA
/
Как видите, в шаблоне спрайта у нас вся линия сместилась на один пиксел вправо, а во флаг С отложился правый бит самого правого байта. Возникает вопрос: что же с ним делать? Может быть, он не нужен?
Напротив, он очень даже нужен, ведь именно ради
него и затевалась вся эта "кухня". Его теперь надо поместить на экран.
Так возникнет впечатление плавного, попиксельного "выплывания" спрайта
в окне.
Если спрайт движется вправо, то для этого мы
воспользуемся командой RR (HL), которая вращает биты в том байте, на
который указывает адрес, установленный в паре HL. В книге "Элементарная
графика" мы говорили о том, что для графических работ принято в этой
паре хранит экранные адреса. И немалую роль в таком подходе
программистов сыграл и тот факт, что в системе команд процессора Z-80
команды RR (HL) и RL (HL) имеются, а команды типа RR (ВС), P.L (ВС), RR (DE) и P.L (DE) отсутствуют.
Рис. 23 Так спрайт начинает "выплывать 1 в окне экрана
Операция скроллирования в окне RR (HL) повторяется столько раз, сколько знакомест имеет окно по ширине.
Как работает процедура.
1. Как обычно, работа процедуры начинается с того, что принимаются из БЕЙСИКа параметры процедуры (х,у,1... и др ).
2. Затем организуются пять вложенных
циклов Как обычно, параметр цикла выставляется в регистре В Вершинами
циклов являются команды
PUSH HL PUSH ВС,
а окончанием цикла - команды
D3N2 adress POP ВС POP HL
спрайт
Структура этих циклов связана со структурой спрайта и раскладкой экрана.
Спрайт имеет в ширину три знакоместа В высоту - три ряда
Каждое знакоместо имеет восемь горизонтальных
линий, кроме нижнего ряда в нем только пять линий, поскольку высота
спрайта у нас принята равной 21 пикселу (8+8+5). Каждая линия имеет во
семь точек (битов)
Первый цикл
(самый внешний) связан с шириной окна и имеет размерность, равную
ширине окна в знакоместах + 3, т.к. "прогнать" спрайт надо не только по
ширине окна, но и по ширине самого спрайта, которая равна трем
знакоместам. Он начинается в адресе #С210 и заканчивается в #С263.
Второй цикл
связан с тем, что ширина каждого знакоместа равна восьми пикселам. Его
размерность - 8. Он начинается в адресе #С218 и заканчивается в #C25F.
Третий цикл
связан тремя рядами знакомест в спрайте (последний ряд неполный) и
имеет размерность 3. Он начинается в ад ресе #С229 и заканчивается в
#С25В.
Четвертый цикл
связан с тем, что в знакоместе содержатся восемь пиксельных линий (в
нижнем ряду - пять). Его размерность - 8 или 5. Он начинается в адресе
#С236 и заканчивается в адресе #C24D.
Пятый цикл
связан с тем, что в одном ряду спрайта есть три знакоместа. Он имеет
размерность, равную трем. Этот цикл вынесен из главной процедуры во
вспомогательные подпрограммы LEFT и RIGHT, которые осуществляют
скроллинг соответственно влево или вправо, в зависимости от того, какое
направление задано пользователем в параметре <3 Для движения влево
он начинается в адресе #С2С1 и заканчивается в #C2D7. Для движения
вправо он начи нается в #С2А4 и заканчивается в #С2В0.
Структура организации циклов приведена на рис.24.
Цикл 1 Размерность: 1+3
#С210
Цикл 2 Раэмермость: 8
#С218
Цикл 3 Размер:
#С229
Цикл 4 Размер 8/5
#С236
Цикл 5 Разм.: 3
#С2А4 #С2В0 #С2С1 #C2D7
#C24D
#С25В
#C25F
#С263
Рис. 24 Структура процедуры.
3. Поскольку нам нужно, чтобы спрайт "выплывал"
в окне постепенно, пиксел за пикселом, нам приходится "вращать" байты в
спрайте, а это значит, что исходный оригинальный спрайт "портится". Для
того, чтобы не уродовать спрайты в таблице спрайтов (начинается с
адреса #D548 54600 DEC), мы должны создать временный буфер, в
котором и будем манипулировать со спрайтом. Этот буфер создаем после
нашей процедуры, начиная с адреса #С2Е1. Он помечен меткой BUFFER.
Для "перетаскивания" спрайта из таблицы
шаблонов в этот буфер применяется специальная процедура GETBPR (Get
Sprite). Но в ее работе имеются некоторые тонкости, которые следует
здесь рассмотреть.
Во-первых, в этой процедуре организован
троичный счетчик, который служит для того, чтобы не каждый раз при
обращении к этой процедуре происходило "перетаскивание" шаблона спрайта
из таблицы спрайтов в буфер, а только один раз из четырех. Так как
спрайт имеет в ширину три знакоместа, то новый спрайт принимать в
буфер, пока все 3 знакоместа не вышли на экран, не надо.
Этот троичный счетчик организован в программной
переменной COUNT. При инициализации программы в нем выставляется 1 При
обращении к процедуре GETBPR наличие там нуля говорит о том, что буфер
надо заполнить. Далее происходит декремент счетчика, он обнуляется,
после чего в нем выставляется число 3. Теперь при трех ближайших
обращениях к процедуре GETSPR буфер не будет переписываться.
При четвертом обращении появляется возможность
переписать буфер новым шаблоном спрайта, но будет ли она реализована
зависит от того, нужна ли нам повторная "прогонка" этого спрайта, т.е.
зависит от того, что задано в параметре г. Если Нам такой повтор не
нужен (г=1), то выключается флаговая переменная FLAG (изначально она
включена), после чего новый спрайт в буфер не помещается, а его место в
буфере забивается нулями.
В общих чертах это все сложности, связанные с организацией скроллинга спрайтов в заданном окне.
Листинг 23
Загрузчик машинного кода процедуры скроллирования спрайта в окне
10 REM *** Загрузчик машинного кода
20 LET adr=49600: LET long=290: LET check=81010: LET sum=0
30 FOR к=0 ТО long-1: READ а 40 POKE (adr+k),a: LET sum=sum+a 50 NEXT к
60 IF sumocheck THEN PRINT "??": STOP 100 REM *»» Данные для машинного кода
110
|
DATA
|
042,
|
011,
|
092,
|
001,
|
004
|
120
|
DATA
|
000,
|
009,
|
086,
|
014,
|
008
|
130
|
DATA
|
009,
|
094,
|
009,
|
126,
|
050
|
140
|
DATA
|
218,
|
194,
|
009,
|
126,
|
050
|
150
|
DATA
|
223,
|
194,
|
009,
|
126,
|
230
|
160
|
DATA
|
001 ,
|
050,
|
222,
|
194,
|
009
|
170
|
DATA
|
126,
|
230,
|
001 ,
|
050,
|
221
|
180
|
DATA
|
194,
|
062,
|
001,
|
050,
|
219
|
190
|
DATA
|
194,
|
050,
|
224,
|
194,
|
123
|
200
|
DATA
|
230,
|
024,
|
246,
|
064,
|
103
|
210
|
DATA
|
123,
|
230
|
,007,
|
183,
|
031
|
220
|
DATA
|
031 ,
|
031
|
,031,
|
130,
|
111
|
230
|
DATA
|
058,
|
222
|
.194,
|
254,
|
000
|
240
|
DATA
|
040,
|
006
|
,058,
|
218,
|
194
|
250
|
DATA
|
133,
|
061
|
,111,
|
058,
|
218
|
260
|
DATA
|
194,
|
060
|
,060,
|
060,
|
071
|
270
|
DATA
|
197,
|
229
|
,205,
|
102,
|
194
|
280
|
DATA
|
225,
|
006
|
,008,
|
229,
|
197
|
290
|
DATA
|
017,
|
225
|
,194,
|
058,
|
222
|
300
|
DATA
|
194,
|
254
|
,000,
|
040,
|
003
|
310 DATA 017,011,195,006,003
320 DATA 229,197,120,254,001
330 DATA 032,004,006,005,024
340 DATA 002,006,008,197,213
350 DATA 229,058,222,194,254
360 DATA 000,032,005,205,160
370 DATA 194,024,003,205,189
380 DATA 194,225,209,193,036
390 DATA 019.016.231.193,225
400 DATA 062,032,133,111,048
410 DATA 004,062,008,132,103 420 DATA
016,204,193.225.016 430 DATA 183,193,118,016,171 440 DATA
201,058,224,194,061 450 DATA 050,224,194,192,062 460 DATA
003,050,224,194,058 470 DATA 223,194,017,063,000
480
|
DATA
|
071,
|
033
|
,072,
|
213,
|
167
|
490
|
DATA
|
237,
|
082
|
,025,
|
016,
|
253
|
500
|
DATA
|
067,
|
017
|
,225,
|
194,
|
058
|
510
|
DATA
|
219,
|
194
|
,254,
|
000,
|
040
|
520
|
DATA
|
001 ,
|
126
|
,018,
|
035,
|
019
|
530
|
DATA
|
016,
|
243
|
,058,
|
221,
|
194
|
540
|
DATA
|
254,
|
000
|
, 200,
|
062,
|
000
|
550
|
DATA
|
050,
|
219
|
,194,
|
201,
|
167
|
560
|
DATA
|
006,
|
003
|
,213,
|
026,
|
031
|
570
|
DATA
|
018,
|
245
|
,062,
|
021,
|
131
|
580
|
DATA
|
095,
|
048
|
,001,
|
020,
|
241
|
590
|
DATA
|
016,
|
242
|
,209,
|
058,
|
218
|
600
|
DATA
|
194,
|
071
|
,203,
|
030,
|
035
|
610
|
DATA
|
016,
|
251
|
,201,
|
167,
|
213
|
620
|
DATA
|
006,
|
003
|
,026,
|
023,
|
018
|
630
|
DATA
|
245,
|
123
|
,214,
|
021 ,
|
095
|
640
|
DATA
|
048,
|
001
|
,021,
|
241,
|
016
|
650
|
DATA
|
242,
|
209
|
,058,
|
218,
|
194
|
660
|
DATA
|
071,
|
203
|
,022,
|
043,
|
016
|
670
|
DATA
|
251,
|
201
|
,013,
|
000,
|
000
|
680
|
DATA
|
001,
|
000
|
,010,
|
003,
|
000
|
Листинг 24 Процедура, управляющая скроллингом спрайта в окне
Адрес Маш.код Метка Мнемоника
С1С0 2А0В5С
010400
09
56
0Е08
С1СЗ С1С6 С1С7 С1С8 С1СА С1СВ С1СС
09 5Е 09
C1CD 7Е С1СЕ 32DAC2
C1D1 09
C1D2 7Е C1D3 32DFC2
C1D6 09
C1D7 7Е C1D8 Е601
C1DA 32DEC2
C1DD 09
LD HL,(#5С0В)
ВС,#0004 HL.BC
D,(HL) C, #08 HL.BC
E,(HL) HL.BC
A,(HL) (WIDTH),A
ADD HL.ВС
LD A,(HL)
LD (NUMBER),A
ADD HL,BC
LD A,(HL)
AND #01
LD (DIRECT),A
ADD HL.BC
LD
ADD
LD
LD
ADD
LD
ADD
LD LD
Указание на адрес, в котором располагаются
параметры функции пользователя FN п(). Вычисление адреса первого
параметра. Прием параметра х. Переход ко второму параметру. Прием
параметра у. Переход к третьему параметру. Прием параметра 1 Сохранили
ширину окна в программной переменной .
Переход к четвертому параметру Прием параметра п. Запомнили номер спрайта в программной переменной.
Переход к пятому параметру .
Прием параметра d. Гашение ненужных старших битов. Запомнили в программной переменной.
Переход к шестому параметру .
Адрес Маш код Метка Мненоника_Комментарий -
C1DE
|
7Е
|
LD
|
A,(HL)
|
Прием параметра г.
|
C1DF
|
Е601
|
AND
|
#01
|
Оставили младший бит.
|
С1Е1
|
32DDC2
|
LD
|
(REPIT), A
|
Сохранили в переменной.
|
С1Е4
|
ЗЕ01
|
LD
|
A,#01
|
|
С1Е6
|
32DBC2
|
LD
|
(FLAG) , A
|
Инициализация флаговой
|
|
|
|
|
переменной.
|
С1Е9
|
32Е0С2
|
LD
|
(COUNT), A
|
Инициализация троичного
|
|
|
|
|
счетчика
|
С1ЕС
|
7В
|
LD
|
A,E
|
|
C1ED
|
Е618
|
AND
|
#18
|
|
C1EF
|
F640
|
OR
|
#40
|
|
C1F1
|
67
|
LD
|
H,A
|
Поиск в дисплейном
|
C1F2
|
7В
|
LD
|
A,E
|
файле адреса, соот
|
C1F3
|
Е607
|
AND
|
#07
|
ветствующего коор
|
C1F5
|
В7
|
OR
|
A
|
динатам, заданным в
|
C1F6
|
1F
|
RRA
|
|
знакоместах.
|
C1F7
|
1F
|
RRA
|
|
|
C1F8
|
1F
|
RRA
|
|
Адрес выставляется
|
C1F9
|
1F
|
RRA
|
|
в регистровой паре
|
C1FA
|
82
|
ADD
|
A,D
|
HL
|
C1FB
|
6F
|
LD
|
L,A
|
|
C1FC
|
3ADEC2
|
LD
|
A,(DIREC) •
|
Проверяем, в каком на
|
C1FF
|
FEOO
|
CP
|
#00
|
правлении идет скроллинг
|
С201
|
2806
|
JR
|
Z,LBL-1
|
Если ноль, то вправо.
|
|
|
|
|
Иначе - влево.
|
С203
|
3ADAC2
|
LD
|
A,(WIDTH)
|
Ширина окна.
|
С206
|
85
|
ADD
|
A,L
|
Получили х+1
|
С207
|
3D
|
DEC
|
A
|
Получили х+1-1.
|
С208
|
6F
|
LD
|
L,A
|
что равно координате х
|
|
|
|
|
последнего (правого)
|
|
|
|
|
столбца окна. Если
|
|
|
|
|
скроллинг идет влево.
|
|
|
|
|
то эта координата нужна
|
|
|
|
|
как исходная.
|
С209
|
3ADAC2 LBL-1
|
LD
|
A,(WIDTH)
|
Ширина окна.
|
1 I4U
Адрес Маш.код Метка Мнемоника
ЗС ЗС ЗС
C20F 47
С210 С211
С212 CD66C2
С215 Е1
С216 0608
С218 Е5
С219 С5
С21А 11Е1С2
3ADEC2 FE00
2803
С224 110БСЗ
INC А INC А INC А
Б,А
LOOP 1 PUSH ВС PUSH HL
CALL GETSPR POP HL LD B, #08
LOOP-2 PUSH HL PUSH ВС
LD DE,BUFFER
A,(DIREC) #00
Z,LBL2
LD DE,#C30B
; Рассчитали 1+3 - длину ;пути, который должен
;пройти спрайт. Организовали счетчик ;первого, самого внешнего ;цикла.
(Счетчик пути). ;Сохранили его на стеке ;Запомнили на стеке : адрес в
экранной памяти, соответствующий правому или левому ;верхнему углу
окна. ;Прием спрайта в буфер. :Экранный адрес ;Ширина каждого
знакоместа равна 8 пикселам. ; Сохранили на стеке перед организацией
второго ;цикла.
;Адрес буфера. Там находятся данные о шаблоне левого столбца ;спрайта.
.•Направление скроллинга. ;Проверка направления. ;Если движение вправо, ;то обход следующей опе-,рации -
;Если же движение идет ;влево, то вместо данных ;о левом столбце спрайта ;шаблона спрайта нам нуж-,ны данные о его правом
С227 0601
С229 Е5 С22А С5
С22В 78 С22С FE01 С22Е 2004
С230 0605
1802 0608
C5 D5 E5
3ADEC2 FEOO 2005 CDA0C2
1803 CDBDC2
El D1 CI
С232 С234
С236 С2 37 С238 С239 С23С C2JE С240
С243 С245
С248 С249 С24А
Адрес Маш-код Метка Мнемоника
LBL 2 LD В,#03
LOOP-3 PUSH HL PUSH ВС
LD А,В CP #01 JR NZ.LBL 3
LD В,#05
LOOP-4 B,#08
LBL- 3
LOOP-4
PUSH ВС PUSH DE PUSH HL LD A,(DIREC) CP #00 JR NZ.LBL-4 CALL RIGHT
JR LBL-5 CALL LEFT
POP HL POP DE POP ВС
;столбце. Они смещены на ;#2А байтов (42 байта)
от ;начала буфера ;#С2Е1 + #2А = #С30В. ;Цикл по трем вертикальным
рядам спрайта. ;Сохранение регистров на ;стеке перед организацией
;третьего цикла. ;Проверка, с каким рядом ;мы имеем дело. :Если не с
последним, ;то обход следующей ;операции.
;В последнем ряду спрайта только пять линий, ;т.к. высота спрайта :равна 21 пикселу. ;Обход.
;В двух верхних рядах ;спрайта по восемь линий. Это организация ;счетчика четвертого ;цикла
Направление скроллинга.
;Если влево. то обход. ;Вызов процедуры скрол ;линга вправо-;Обход.
;Вызов процедуры скроллинга влево. :Восстановление регистров ;со стека перед оконча-;нием цикла.
Адрес Машкод Метка Мнемоника
INC Н
INC DE
DJNZ LOOP-4
POP ВС
POP HL
LD A,#20
ADD A,L
LD L,A
JR NC.LBL-6
LD A,#08 ADD A,H LD H,A
DJNZ LOOP-3 POP ВС POP HL
DJNZ LOOP-2 POP ВС
HALT
DJNZ LOOP-l RET
:Переход к соседней снизу ;линии знакоместа на экране.
;Переход к соседней снизу ;линии в шаблоне
спрайта. ;Конец четвертого цикла. :Восстановление регистров ;со стека
перед окончанием цикла.
;Переход к соседнему снизу знакоместу на экране.
;Если не произошло переполнение регистра L, то ;обход следующих операций.
;Если же такое переполнение произошло, то это
;означает, что мы "пере-;валили" за границу экранного сегмента и в
.-этом случае регистр Н увеличивается скачком на 8 пунктов. ;Конец
третьего цикла. ;Восстановление регистров ;со стека перед оконча-;нием
цикла. ;Конец второго цикла. ;Восстановление счетчика Первого
(внешнего) цик-; ла.
;Краткая пауза. ;Конец внешнего цикла. ;Конец работы.
Процедура GETSPR. Осуществляет переброску шаблона спрайта во временный буфер. Адрес Маш код Метка Мнемоника_Комментарий
С269 3D С26А 32Е0С2 C26D СО
С26Е ЗЕОЗ
С270 32Е0С2
С273 3ADFC2
С276 113F00
С279 47
С266 ЗАЕ0С2 GETSPR LD A,(COUNT)
С27А 2148D5
C27D А7
С27Е ED52
С280 19 NEXT
С281 10FD
С283 43 С284 11Е1С2 (COUNT),A NZ
A,#03 (COUNT),A
A,(NUMBER) DE,#003F
B, A
HL,#D548
AND A
SBC HL.DE ADD HL.DE
D3NZ NEXT
LD B.E LD DE,BUFFER ;Приняли данные иэ
;троичного счетчика. ;Сняли с него единицу. ;И снова его запомнили.
;Если не ноль, значит ;наш спрайт еще не весь ;"выехал" на экран и
принимать спрайт в буфер ;пока не надо. :Выставляем число 3 в ;троичном
счетчике, ;Номер спрайта. ;Длина одного шаблона ;спрайта.
.•Создали счетчик. ;Адрес начала таблицы, ;в которой размещаются
;спрайты (54600). ;Сброс флага переноса, ;чтобы он не влиял на
результат операции SBC. ;Выставление начального ;адреса для первого
;спрайта.
;Возврат за отысканием ;адреса очередного ;спрайта.
;Длина шаблона спрайта. ;Приняли адрес временного ;буфера для размещения ; спрайта.
Адрес Маш.код Метка Мнемоника
С28А FEOO С28С 2801
С28Е 7Е
C28F 12
С290 23
С291 13
С292 10F3
С294 3ADDC2
С297 FEOO
C299 C8
C29A 3E00
C29C 32DBC2
C29F C9
#00
Z,BYPASS
LD A,(HL) BYPASS LD (DE),A INC HL
INC DE
D3NZ AGAIN
LD A,(REPIT)
CP #00
RET Z
LD A,#00
LD (FLAG),A RET
С287 3ADBC2 AGAIN LD А,(FLAG)
;Проверка флага, связанного с необходимостью Повторного "прогона" ;спрайта,
;Проверка на ноль. ;Если ноль, то спрайт ;прннимать не надо, идем ;в обход и обнуляем бу-;фер.
;Байт шаблона спрайта. ;Запомнили его в буфере.
,Переход к очередному ;бай ту шаблона. ,Переход к очередному ;байту
буфера. ;Если не все байты шаблона скопированы, то воз-;врат.
;Проверка необходимости повтора.
;Если есть необходимость, ;то выход, в
переменной ;Bl.AG остается единица. , В противном случае обнуляем
переменную FLAG. ;Возврат в вызывающую :процедуру.
C2A5 IF
C2A6 12
C2A7 F5
C2A8 3E15
C2AA 83
C2AB 5F
C2AC 3001
C2AE 14
C2AF F1
C2B0 10F2
C2B2 DI
C2B3 3ADAC2
Процедура RIGHT. Осуществляет "прокрутку" окна вправо. Адрес Маш.код Метка Мнемоника_Комментарий.
RIGHT AND А
LD В.#03
С2А4 1А L00P-5A LD A,(DE)
PUSH DE
RRA
LD (DE) , A PUSH AF
LD A,#15
ADD A,E
LD E,A
DR NC,LBL-7
LBL-7 POP AF
DDNZ LOOP-5A POP DE
LD A, (WIDTH)
;Сброс флага переноса. .Начало внутреннего,
;пятого цикла. Установка ;параметра цикла. ;Сохранение регистра ;на
время работы подпро-;граммы.
;Взяли в аккумулятор ;байт из левого вертикального столбца в шаблоне спрайта. .Ротация вправо ;Заменили байт в шаблоне .
.•Сохранили флаговый регистр на стеке.
Важен ;флаг переноса. ;Сдвиг на 21 байт для ;перехода к соседнему
;справа столбцу. ;Указатель в буфере ;спрайта переместили. ;Если не
возникло переполнения, то обход. ;Иначе наращиваем ;старший регистр,
восстановили флаг С. ;Конец пятого цикла. ;Восстановили указатель ;на
буфер. ;Ширина окна.
Адрес Наш.код Метка Мнемоника
С2В6 47 LD В,А
С2В7 СВ1Е L00P-6A RR (HL)
С2В9 23 INC HL
С2ВА 10FB DJNZ L00P-6A
С2ВС С9
;Ввели ее в качестве ;счетчика.
;Ротация вправо байтов ;в окне.
; Переход в окне к сосед ;нему знакоместу справа. ;Прокручиваем линию по ;всей ширине окна ;Возврат в вызывающую ;процедуру.
Процедура LEFT. Осуществляет "прокрутку" окна влево.
Адрес Маш-код Метка Мнемоника
C2BD А 7 LEFT AND А
С2ВЕ D5 PUSH DE
LD В, #03
C2C1 1A L00P-5B LD A,(DE)
RLA
LD (DE),A PUSH AF
;Сброс флага переноса. ;Сохранение регистра ;на время работы подпро-;граммы.
;Начало внутреннего, •.пятого цикла.
Установка ;параметра цикла. ;Взяли в аккумулятор ;байт иэ правого
вертикального столбца в шаблоне спрайта. ;Ротация влево. ;Заменили байт
в табло ; не.
;Сохранили флаговый регистр на стеке. Важен ;флаг переноса.
Адрес Маш-код Нетка Мнемоника
С2С5 7В
С2С6 D615
С2С8 5F
С2С9 3001
С2СВ 15
С2СС F1
C2CD 10F2
C2CF D1
C2D0 3ADAC2
C2D3 47
C2D4 СБ16
C2D6 2В
C2D7 10FB
C2D9 С9
LD А,Е
SUB #15
LD Е,А
JR NC,LBL-8
DEC D
LBL-8 POP AF
DJNZ LOOP-5B
POP DE
LD A, (WIDTH)
LD B,A
L00P-6B RL (HL)
DEC HL
DJNZ L00P-6B
RET
;Сдвиг назад на 21 байт ;для перехода к
соседнему ;слева столбцу. ;Если не возникло двоичного займа, то обход.
Уменьшаем старший байт, восстановили флаг С. ;Конец внутреннего,
;пятого цикла, восстановили указатель ;на буфер. ."Ширина окна. ;Ввели
ее в качестве ;счетчика.
;Ротация влево байтов ;в окне.
;Переход к соседнему ;знакоместу слева. ;Прогон на всю ширину
;окна.
;Возврат в вызывающую ;процедуру.
DEFB 0D DEFB 00
;Ширина окна. ;Флаг, указывающий на ;необходимость повтора ;"прогона" спрайта.
;Параметр повтора. ;Направление скроллинга.
;Номер спрайта. ;Троичный счетчик для Процедуры GETSPR. ;Временный
буфер для ;хранения шаблона ;спрайта.
Здесь и далее расположены временные данные о шаблоне спрайта.
NOP
DEFB 00 DEFB 00 DEFB OA DEFB 03
REPIT DIRECT NUHBER COUNT