┌──────────────────────────────┐
│ │
│ РЕТРО │
│ │
└──────────────────────────────┘
Music by MITCHELL
Дж.Хардман, Э.Хьюзон
40 лучших процедур
Окончание. Начало в ZX РЕВЮ
1997 NN 1-2, 3-4.
6.10. Увеличение экрана
и копирование
Длина: 335
Количество переменных: 8
Контрольная сумма: 33663
Назначение: Эта программа ко-
пирует часть дисплея в другую
область экрана, увеличивая ко-
пию по X или по Y.
Переменные:
┌──────────────────────────────────────────────────────────────┐
│ Имя Длина Адрес Комментарий │
│ upper_Y_co-ord 1 23296 Y-координата верхнего ряда │
│ lower_Y_co-ord 1 23297 Y-координата нижнего ряда │
│ right_X_co-ord 1 23298 X-координата крайней правой │
│ колонки │
│ left_X_co-ord 1 23299 X-координата крайней левой │
│ колонки │
│ horizontal_scale 1 23300 увеличение по X │
│ vertical_scale 1 23301 увеличение по Y │
│ new_left_co-ord 1 23302 X-координата крайней левой │
│ колонки области, в которую │
│ делается копирование │
│ new_lower_co-ord 1 23303 Y-координата нижнего ряда │
│ области, в которую делается │
│ копирование │
└──────────────────────────────────────────────────────────────┘
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: программа
возвращается в BASIC, если одно
из следующих условий верно:
(I) horizontal_scale=0,
(II) vertical_scale=0,
(III) upper_Y_co-ord больше,
чем 175,
(IV) new_lower_co-ord больше,
чем 175,
(V) lower_Y_co-ord больше, чем
upper_Y_co-ord,
(VI) left_X_co-ord больше, чем
right_X_co-ord.
Однако, для краткости прог-
раммы нет контроля, который про-
верял бы возможность размещения
новой картинки на экране. Если
этого не получается, может прои-
зойти сбой. Программа также тре-
бует большого объема свободной
области ОЗУ и, если это недос-
тупно, может произойти сбой.
Комментарий: эта программа не-
перемещаемая из-за процедуры
PLOT. Она размещается по адресу
65033.
Если скопированная область эк-
рана имеет тот же самый размер,
что и оригинал, масштаб должен
быть установлен в 1, для двойно-
го размера загружается масштаб
2:1, для тройного размера загру-
жается масштаб 3:1 и т.д.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА147.
LD IX,23296 221 33 0 91
LD A,175 62 175
CP (IX+0) 221 190 0
RET C 216
CP (IX+7) 221 190 7
RET C 216
SUB A 151
CP (IX+4) 221 190 4
RET Z 200
CP (IX+5) 221 190 5
RET Z 200
LD HL,(23296) 42 0 91
LD B,L 69
LD A,L 125
SUB H 148
RET C 216
LD (23298),A 50 0 91
LD E,A 95
LD HL,(23298) 42 2 91
LD C,L 77
LD A,L 125
SUB H 148
RET C 216
LD (23298),A 50 2 91
PUSH BC 197
LD L,A 111
LD H,0 38 0
INC HL 35
PUSH HL 229
POP BC 193
INC E 28
ADD DEC E 29
JR Z,REMAIN 40 3
ADD HL,BC 9
JR ADD 24 250
REMAIN LD A,L 125
AND 15 230 15
LD B,A 71
POP HL 225
LD C,L 77
JR NZ,SAVE 32 2
FULL LD B,16 6 16
SAVE PUSH HL 229
CALL SUBR 205 13 255
AND (HL) 166
JR Z,OFF 40 2
LD A,1 62 1
OFF POP HL 225
RRA 203 31
RL E 203 19
RL D 203 18
LD A,L 125
CP (IX+3) 221 190 3
JR Z,NEXT_R 40 6
DEC L 45
N_BIT DJNZ SAVE 16 231
PUSH DE 213
JR FULL 24 226
NEXT_R LD L,C 105
LD A,H 124
CP (IX+1) 221 190 1
JR Z,COPY 40 3
DEC H 37
JR N_BIT 24 241
COPY PUSH DE 213
LD B,0 6 0
LD H,B 96
LD L,B 104
RESET LD (23306),HL 34 10 91
LD A,B 120
OR A 183
JR NZ,RETR 32 3
POP DE 209
LD B,16 6 16
RETR SUB A 151
DEC B 5
RR D 203 26
RR E 203 27
RL A 203 23
PUSH DE 213
PUSH BC 197
PUSH AF 245
LD H,1 38 1
LOOP LD L,1 46 1
PRESER LD (23304),HL 34 8 91
LD A,(23307) 58 11 91
LD HL,0 33 0 0
LD DE,(23301) 237 91 5 91
LD D,L 85
MULTIP OR A 183
JR Z,CALC 40 6
ADD HL,DE 25
DEC A 61
JR MULTIP 24 249
L_JUMP JR RESET 24 208
CALC LD A,(23303) 58 7 91
ADD A,L 133
LD HL,(23304) 42 8 91
ADD A,L 133
DEC A 61
PUSH AF 245
LD A,(23306) 58 10 91
LD HL,0 33 0 0
LD DE,(23300) 237 91 4 91
LD D,L 85
REPEAT OR A 183
JR Z,CONTIN 40 4
ADD HL,DE 25
DEC A 61
JR REPEAT 24 249
CONTIN LD A,(23302) 58 6 91
ADD A,L 133
LD HL,(23305) 42 9 91
ADD H,L 133
DEC A 61
LD L,A 111
POP AF 241
LD H,A 103
POP AF 241
PUSH AF 245
OR A 183
JR NZ,PLOT 32 7
CALL SUBR 205 13 255
CPL 47
AND (HL) 166
JR POKE 24 4
PLOT CALL SUBR 205 13 255
OR (HL) 182
POKE LD (HL),A 119
LD HL,(23304) 42 8 91
INC L 44
LD A,(23301) 58 5 91
INC A 60
CP L 189
JR NZ,PRESER 32 165
INC H 36
LD A,(23300) 58 4 91
INC A 60
CP H 188
JR NZ,LOOP 32 155
POP AF 241
POP BC 193
POP DE 209
LD HL,(23306) 42 10 91
INC L 44
LD A,(23298) 58 2 91
INC A 60
CP L 189
JR NZ,L_JUMP 32 164
LD L,0 46 0
INC H 36
LD A,(23296) 58 0 91
INC A 60
CP H 188
JR NZ,L_JUMP 32 154
RET 201
SUBR PUSH BC 197
PUSH DE 213
LD A,175 62 175
SUB H 148
LD H,A 103
PUSH HL 229
AND 7 230 7
ADD A,64 198 64
LD C,A 79
LD A,H 124
RRA 203 31
RRA 203 31
RRA 203 31
AND 31 230 31
LD B,A 71
AND 24 230 24
LD D,A 87
LD A,H 124
AND 192 230 192
LD E,A 95
LD H,C 97
LD A,L 125
RRA 203 31
RRA 203 31
RRA 203 31
AND 31 230 31
LD L,A 111
LD A,E 123
ADD A,B 128
SUB D 146
LD E,A 95
LD D,0 22 0
PUSH HL 229
PUSH DE 213
POP HL 225
ADD HL,HL 41
ADD HL,HL 41
ADD HL,HL 41
ADD HL,HL 41
ADD HL,HL 41
POP DE 209
ADD HL,DE 25
POP DE 209
LD A,E 123
AND 7 230 7
LD B,A 71
LD A,8 62 8
SUB B 144
LD B,A 71
LD A,1 62 1
ROTARE ADD A,A 135
DJNZ ROTARE 16 253
RRA 203 31
POP DE 209
POP BC 193
RET 201
2
Как она работает:
В IX загружается адрес буфера
принтера для использования его в
качестве указателя переменных.
Если верхняя Y-координата или
новая нижняя координата боль-
ше 175, программа возвращается в
BASIC. Если значение увеличения
по горизонтали или вертикали
равно 0, происходит возврат в
BASIC.
В H-регистр загружается ниж-
няя Y-координата, а в L-регистр
верхняя Y-координата. L-регистр
копируется в B-регистр и в акку-
мулятор. H-регистр вычитается из
аккумулятора и подпрограмма воз-
вращается в BASIC, если резуль-
тат отрицательный.
Значение аккумулятора затем
помещается в ячейку 23298 для
использования в качестве счетчи-
ка. Пара регистров BC затем сох-
раняется на стеке.
Регистр HL загружается значе-
нием аккумулятора, увеличивает-
ся и копируется в регистр BC. BC
прибавляется к HL E раз, резуль-
тирующее значение в HL является
числом пикселей для копирования.
В аккумулятор загружается зна-
чение L-регистра и 4 крайних ле-
вых бита устанавливаются в 0.
Результат копируется в B-ре-
гистр для использования его в
качестве счетчика.
Пара регистров HL восстанавли-
вается из стека и регистр L ко-
пируется в C-регистр. Если B-ре-
гистр содержит 0, в регистр заг-
ружается число 16 - это количес-
тво битов в регистровой паре.
Затем вызывается процедура SUBR
и в аккумулятор загружается зна-
чение POINT (L,H). Пара регис-
тров DE сдвигается влево, а зна-
чение бита из аккумулятора заг-
ружается в крайний правый бит
E-регистра.
Если L-регистр равен левой
X-координате, подпрограмма пере-
ходит к NEXT_R (следующий ряд).
Иначе уменьшается L-регистр, а
затем - B-регистр. Если B-ре-
гистр не содержит 0, подпрограм-
ма возвращается к SAVE для пода-
чи следующего бита в пару регис-
тров DE. Если B-регистр содер-
жит 0, пара регистров DE поме-
щается в стек и происходит пере-
ход к FULL.
Процедуре NEXT_R в L-регистр
загружается правая X-координата,
а в аккумулятор загружается зна-
чение H-регистра. Если значение
аккумулятора равно нижней Y-ко-
ординате, происходит переход к
COPY, т.к. последний пиксель для
копирования подан в DE. Иначе H-
регистр уменьшается, указывая на
следующий ряд, и подпрограмма
возвращается к N_BIT.
В процедуре COPY содержимое
пары DE помещается в стек, а B-,
H- и L-регистры устанавливаются
в 0 для использования их в ка-
честве счетчиков. Содержимое па-
ры регистров HL помещается в
ячейку с адресами 23306/7. HL
теперь может использоваться как
счетчик для последующих циклов
без использования стека. Если
B-регистр содержит 0, DE восста-
навливается из стека, а регистр
B повторно устанавливается на
значение 16, определяя количес-
тво пикселей, хранимых в DE.
B-регистр уменьшается, показы-
вая, что бит информации удален
из DE. Крайний правый бит E-ре-
гистра загружается в аккумуля-
тор, а пара регистров DE сдви-
гается вправо. DE, BC и AF поме-
щаются в стек до тех пор, пока
не выполнятся определеные расче-
ты.
В регистры H и L загружается 1
для использования их в качестве
счетчика, а HL помещается в
ячейки с адресами 23304/5. В ак-
кумулятор загружается значение
байта по адресу 23307 - это один
из счетчиков, сохраненных ранее.
В пару регистров DE загружается
масштаб по вертикали. Это значе-
ние затем умножается на значе-
ние аккумулятора, а результат
подается в HL. Это значение при-
бавляется к новой нижней Y-коор-
динате в аккумуляторе. Байт по
адресу 23304 затем добавляется к
аккумулятору, а результат умень-
шается.
Аккумулятор теперь хранит
Y-координату для построения сле-
дующего пикселя. Это значение
хранится в стеке до тех пор, по-
ка подсчитывается X-координата
похожим способом. После расчета
X-координата загружается в L-ре-
гистр. Y-координата восстанавли-
вается из стека и загружается в
H-регистр. В аккумуляторе уста-
навливается последнее значение,
хранящееся в стеке. Если оно
равно 1, то должна быть постро-
ена точка (X,Y), иначе должна
быть выполнена процедура UNPLOT-
TED. Вызывается SUBR и выполня-
ются соответствующие действия.
Пара регистров HL загружается
счетчиками цикла, хранящимися по
адресам 23304/5. Регистр L уве-
личивается и, если он не содер-
жит значение (1+vertical_scale),
подпрограмма возвращается к PRE-
SER. Регистр H увеличивается и,
если он не содержит значение
(1+horizontal_scale), происходит
переход к LOOP.
Пара регистров AF, BC и DE
восстанавливаются из стека, а в
пару регистров HL загружается
второе значение набора счетчи-
ков цикла, которое хранится по
адресам 23306/7. Регистр L уве-
личивается и происходит переход
к RESET, если результат не равен
(right_X_co - ord - left_X_co -
ord + 1).
Регистр L устанавливается в
0 - это первоначальное значение
счетчика цикла. H-регистр затем
увеличивается и подпрограмма пе-
реходит к RESET, если результат
не равен (uppen_Y_co-ord-lower_Y
_co-ord+1). Программа возвращае-
тся в BASIC.
Процедура SUBR идентична той,
что используется в программе
"Закрашивание контура".