Move
#10
04 сентября 1997 |
|
Алгоритмы - Подпрограммы связанные с выводом на экран: переход к предыдущему символу по экранному адресу, переход на следующую экранную линию, переход к предыдущей линии экрана, как определить адрес атрибута для заданного символа с координатами XY, переход к следующей строке атрибутов. Быстрая процедура умножения.
Алгоритмы и идеи. Быстрая процедура умножения. Ars; KVA from E-Mage /г.Гродно/ (ОКОНЧАНИЕ. НАЧАЛО В MOVE #09) ──────────────────────────────────────────────────────────────── (c) Ars В этой рубрике мы продолжаем публиковать полезные процедуры. На этот раз речь пойдет о различных подпрограммах, связанных с выводом на экран. Если у вас возникнут какие-то замечания, сообщите нам. А также вы можете предложить для обсуждения свой вариант алгоритмов на страницах MOVE. Часть процедур, приводимых ниже, написал Rui Ribeiro - автор WSpecem - эмулятора Спектрума для Windows. 7) Переход к предыдущему символу по экранному адресу. Input: HL = screen address Output: HL = previous char screen address PrevChr RR H RR H RR H DEC HL RL H RL H RL H RET Две следующие процедуры вы наверняка знаете наизусть, настолько часто они используются в программах. 8) Переход на следующую экранную линию. Input: HL = screen address Output: HL = scan inferior address NextLine INC H LD A,H AND 7 RET NZ LD A,L ADD A,32 LD L,A RET C LD A,H SUB 8 LD H,A RET 9) Переход к предыдущей линии экрана. Input: HL = screen address Output: HL = superior scan address PrevLine DEC H LD A,H AND 7 CP 7 RET NZ LD A,L SUB 32 LD L,A RET C LD A,H ADD A,8 LD H,A RET 10) Следующая процедура позволяет просканировать экран так, как это делает луч разверки. Input: screen address Output: next visual scan address NextVAdd INC L LD A,L AND #1F RET NZ INC H LD A,H AND 7 LD A,L JR NZ,NVALab AND #E0 RET Z LD A,H SUB 8 LD H,A RET NVALab SUB 32 LD L,A RET 11) Та же самая операция, но движение в обратную сторону - снизу вверх. Input: HL = screen address Output: HL = previous visual scan address PrevVAdd DEC L LD A,L AND #1F CP #1F RET NZ DEC H LD A,H AND 7 CP 7 LD A,L JR NZ,PVALab AND #E0 CP #E0 RET Z LD A,H ADD A,8 LD H,A RET PVALab ADD A,32 LD L,A RET И напоследок, процедуры, связанные с адресацией атрибутов. Atribute file: Length=768 bytes. Address: #5800..#5AFF (22528..23295) Цвета задаются Адрес атрибута вычисляется так: следующими битами: adr(C,L) = 22528+L*32+C 7 6 543 210 --------------- где: L - строчка (0..23) f b p i C - столбец (0..31) l r a n a i p k Схематически адрес атрибута выглядит так: s g e h h r 0101 10LL LLLC CCCC t 12) Как определить адрес атрибута для заданного символа с координатами XY. Input: BC = YX Output: HL = attribute address AdrAttr LD A,B RRCA RRCA RRCA LD H,A AND #E0 OR C LD L,A LD A,H AND 3 OR #58 LD H,A RET 13) Переход к следующей строке атрибутов. Input: HL = attribute address Output: HL = upper attribute address DownAttr LD A,L LD DE,32 ADD A,32 или ADD HL,DE LD L,A RET NC INC H RET 14) Переход к предыдущей строке атрибутов. Input: HL = attribute address Output: HL = lower attribute address UpAttr LD A,L LD DE,32 SUB 32 или AND A LD L,A SBC HL,DE RET NC DEC H RET Информация получена с Web-странички: http://www.atlantic.net/~adansby/plot.html КАК БЫСТРО ПЕРЕМНОЖИТЬ ДВА ЧИСЛА. (Концепция процедур умножения.) ──────────────────────────────────────────────────────────────── (c) KVA from E-Mage /г.Гродно/ В настоящее время многие знают как быстро перемножить два числа, однако не все знают как работают те процедуры, которыми они пользуются. Если же понять, по какому принципу написаны все эти алгоритмы, то под каждый конкретный случай можно написать процедуру, которая будет раза в два быстрее, чем процедура для общего случая. Рассмотрим, как мы перемножаем два числа в десятичной системе счисления: 176*25 = 100*(1*25)+10*(7*25)+1*(6*25) Т.е., мы раскладываем одно из чисел на разряды (единицы, сотни, десятки и т.д.). Но ведь можно же сделать то же самое и в двоичной системе счисления : 101101*1011 = 100000*(1*1011)+10000*(0*1011)+... Теперь заметим, что умножение сводится к двум операциям: 1. Умножение на два (операция в Assembler'e - ADD r,r). 2. Прибавление второго числа. Попробуем на таком принципе разложить предыдущее число: 101101*1011=1*1011+10*(0*1011+10*(1*1011+10*(1*1011+ 10*(0*1011+10*(1*1011))))) Рассмотрим процедуру умножения байт*байт, написанную в Echo: ADD HL,HL ┐ H - число 1 ┐ JR NC,M1 ├ Повторить 8 раз. E - число 2 ├Вход ADD HL,DE │ D и L = 0 ┘ M1: ┘ HL = Answer ─Выход Команда ADD HL,HL выполняет сразу две функции: 1. Умножает содержимое регистра L на два. 2. Выносит последний бит регистра H в флаг C. (При первой команде получаем 7-й бит входного числа, при второй - 6- бит входного числа и т.д.) Команда JR NC,M1 выполняет функцию умножения (т.к. мы пользуемся двоичной системой, то у нас есть только две цифры, на которые мы можем умножить - 0 и 1) Команда ADD HL,DE используется для прибавления к регистру L регистра E. Команды JR NC,M1 и ADD HL,DE вместе выполняют функцию прибавления к регистру L регистра Е, умноженного на последний бит регистра H. В этой процедуре используется принцип "с конца", т.е. сначала обрабатывается бит 7, затем 6 и т.д. А если короче, то здесь применяется сочетательный закон математики, который изучается еще в школе. Можно сначала взять E, умноженное на 0-й бит H. Затем прибавить число 10*E*[1-й бит H] (10 - двоичная система), потом число 100*Е*[2-й бит H], потом 1000*Е*[3-й бит H]...прибавляем 10000000*E*[7-й бит H]. А можно сделать по-другому. Сначала берем Е*[7-й бит H], умножаем на 10 (2), прибавляем Е*[6-й бит H], умножаем на 10, прибавляем Е*[5-й бит H]...умножаем на 10, прибавляем Е*[0-й бит H]. В конце этой операции, получим точно такой же эффект, как и в первом случае, однако с помощью assembler'a Spectrum'а второе сделать легче !!! Напоследок, привожу пару процедур, написанных мной для случая байт*слово=слово (слово это 2 байта), слово*слово=слово, слово*слово=двойное слово (4 байта), двойное слово*двойное слово= двойное слово. Хочу сразу же всех предупредить, что тексты здесь с использованием специальных директив ассемблера ALASM v3.8 - DUP и EDUP (DUP x -повторить x раз строчки, следующие за этой командой и оканчивающиеся строчкой с командой EDUP). ; байт*слово=слово ; Вход - А-число 1, DE-число 2. ; Выход - HL-результат. LD HL,0 DUP 8 ADD HL,HL ADD A,A JR NC,$+3 ADD HL,DE EDUP ; слово*слово=слово ; Вход - BC-число 1,DE-число 2. ; Выход - HL-результат. LD HL,0 LD A,B DUP 8 ADD HL,HL ADD A,A JR NC,$+3 ADD HL,DE EDUP LD A,C DUP 8 ADD HL,HL ADD A,A JR NC,$+3 ADD HL,DE EDUP ; слово*слово=двойное слово ; Вход - BC-число 1,DE-число 2 ; Выход - HL-младшая часть слова,HL'-старшая часть слова. LD HL,0 EXX LD HL,0 LD DE,0 EXX LD A,B DUP 8 ADD HL,HL EXX ADC HL,HL EXX ADD A,A JR NC,$+6 ADD HL,DE EXX ADC HL,DE EDUP LD A,C DUP 8 ADD HL,HL EXX ADC HL,HL EXX ADD A,A JR NC,$+6 ADD HL,DE EXX ADC HL,DE EXX EDUP ; двойное слово*довойное слово=двойное слово ; Вход - DE' DE-число 1, BC' BC-число 2 ; Выход - HL' HL-результат LD HL,0 EXX LD HL,0 EXX DUP 16 ADD HL,HL EXX ADC HL,HL EX DE,HL ADD HL,HL EX DE,HL EXX JR NC,$+6 ADD HL,BC EXX ADC HL,BC EXX EDUP DUP 16 ADD HL,HL EXX ADC HL,HL EXX EX DE,HL ADD HL,HL EX DE,HL JR NC,$+6 ADD HL,BC EXX ADC HL,BC EDUP P.S. Если кого-нибудь заинтересовала эта статья (и вообще, эта тема), вы можете написать в редакцию MOVE или связаться со мной по телефону (0152) 318-721 (Витя), либо оставить сообщение на E-Mage BBS (0152) 441-176. Ждите следующих номеров MOVE, где я опишу процедуры деления.
Другие статьи номера:
Эхо - Обзор писем читателей газеты: Beard, Space5, DarkMax. |
Система - Организация почты в C-DOS v1.32. |
Алгоритмы - Подпрограммы связанные с выводом на экран: переход к предыдущему символу по экранному адресу, переход на следующую экранную линию, переход к предыдущей линии экрана, как определить адрес атрибута для заданного символа с координатами XY, переход к следующей строке атрибутов. Быстрая процедура умножения. |
Железо - Гальвоническая развязка с телефонной линией в C-DOS модеме. |
Мозаика - Спектрум в Internet. |
BRAVO на отдых - Рассказы : Автобус, Ода комару. |
Реклама - Реклама и объявления. |
Похожие статьи:
В этот день... 21 ноября