┌──────────────────────────────┐ │ │ │ РЕТРО │ │ │ └──────────────────────────────┘ 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 идентична той, что используется в программе "Закрашивание контура".