MSD #07
11 сентября 1999



                        Ассемблер.


  Если вы не знаете, что это такое, но хотите узнать, то очень
рекомендую прочесть статьи на эту тему в ZF #7 & #8.
 В этом выпуске материал уже для разберающихся, наш главный
кодер 3М поделится своим мастерством.


  Привет, пиплы!
  Я (3M) решил поделиться некоторыми секретами кодинга на
SPECCY. На 'дисковом' SPECTRUM'e я сижу всего 2 года, до этого
был самопальный кассетный ЛЕНИНГРАД 48, который пахал 5 лет и
умер от моих 'гениальных' доработок, + пакет ассемблеров GENS и
ZEUS с 'мгновенной' отгрузкой на кассету под заунывные звуки
пилот-сигнала. Именно на нем я заработал профессиональную бо-
лезнь всех 48кб - минимализм. А теперь перейдем к делу.

 Для начала приведу некоторые процедуры,которыми я пользуюсь для
написания своих прог. Первые 2 из них, самые распространенные и
самые необходимые, осуществляют расчет адреса следующей строки в
области экрана:


Вход : HL - адрес строки.
Выход: HL - адрес следующей строки.

   Поиск следующей     Поиск следующей
    нижней строки      верхней строки

 NEXTHL  INC H        BACKHL  DEC H
         LD  A,H              LD  A,H
         AND 7                CPL
         RET NZ               AND 7
         LD  A,L              RET NZ
         ADD A,32             LD  A,L
         LD  L,A              SUB 32
         RET C                LD  L,A
         LD  A,H              RET C
         SUB 8                LD  A,H
         LD  H,A              ADD A,8
         RET                  LD  H,A
                              RET


  Надеюсь, здесь вопросов не возникнет ? Пошли дальше. Сле-
дующая процедура,тоже распространенная, расчитывает адрес экрана
по известным координатам:


Вход : H - Y (0-191), L - X (0-255).
Выход: HL - адрес, B - номер бита (0-7).

   CORHL   LD  A,L
           AND 7
           LD  B,A
           XOR L
           LD  L,A
           LD  A,H
           AND 7
           LD  C,A
           XOR H
           RRA
           SCF
           RRA
           RRA
           LD  H,A
           AND 7
           OR  L
           RRCA
           RRCA
           RRCA
           LD  L,A
           LD  A,H
           AND 248
           OR  C
           LD  H,A
           RET


  Если к этой процедуре добавить (перед RET) вот такие строчки:


         INC B
         LD  A,1
 ROLLER  RRCA
         DJNZ ROLLER
         OR  (HL)   или  XOR (HL) ; маска
         LD  (HL),A


  то получим процедуру печати точки - PLOT по координатам в HL.
Хотя данная процедура очень быстра, но и ее скорости может не
хватать для времекретичных эффектов (DEMO, ЗD-графика и др.),для
них есть метод еще более быстрого вывода точки за 69 тактов.
 Следующая процедура была разработана мной, оиа подготавливает
спрайт для печати с точностью до пиксела (если у кого есть дан-
ная процедура работающая быстрее, прошу позвонить).


 Вход : B - высота спрайта в пикселах
        С - ширина спрайта в байтах
        DE - адрес спрайта
        HL - адрес буфера
        A - номер бита или кол-во циклических
             сдвигов спрайта (0-7)
 Выход: в буфере готовый спрайт с шириной+1

  RUNSPR   PUSH HL
           EXX
           LD   (L13+1),A
           INC  A
           LD   B,A
           LD   A,1
  L10      RRCA
           DJNZ L10
           LD   E,A
           DEC  A
           OR   E
           LD   E,A
           POP  HL
           EXX
  L11      LD   A,C
           EXX
           LD   B,A
           LD   D,0
  L12      EXX
           LD   A,(DE)
           INC  DE
  L13      JR   L13
           RLCA
           RLCA
           RLCA
           RLCA
           RLCA
           RLCA
           RLCA
           RLCA
           EXX
           LD   C,A
           AND  E
           OR   D
           LD   (HL),A
           INC  HL
           XOR  D
           XOR  C
           LD   D,A
           DJNZ L12
           LD   (HL),D
           INC  HL
           EXX
           DJNZ L11
           RET


  Уникальность данной процедуры состоит в том, что она 'бе-
рет' спрайты любого размера.
  Многие начинающие кодеры сталкиваются с проблемой печати чи-
сел.Первое неуклюжее ее решение - использование подпрограмм ПЗУ,
которые в результате тесного обшения с 'калькулятором' жрут уйму
времени. Следующая процедура быстро подготовит в буфере число в
виде 5 байтной строки для его последующей печати:


 Вход : HL - число (0-65535)
        DE - адрес буфера на 5 байт
 Выход: в буфере стринг числа

 NUMSTR    LD   BC,10000
           CALL L10
           LD   BC,1000
           CALL L10
           LD   BC,100
           CALL L10
           LD   BC,10
           CALL L10
           LD   BC,1
 L10       LD   A,47
 L11       INC  A
           SBC  HL,BC
           JR   NC,L11
           ADD  HL,BC
           LD   (DE),A
           INC  DE
           RET


  Следующая процедура выполняет задачу обратную предыдущей -
преобразует стринг в двоичное число:


 Вход : DE - адрес буфера на 5 байт
 Выход: HL - число

 STRNUM    LD   HL,0
           LD   BC,10000
           CALL L10
           LD   BC,1000
           CALL L10
           LD   BC,100
           CALL L10
           LD   BC,10
           CALL L10
           LD   BC,1
 L10       LD   A,(DE)
           INC  DE
 L11       DEC  A
           CP   47
           RET  Z
           ADD  HL,BC
           JR   L11


  А теперь процедура умножения 2 байтного числа на 1 байтовое
(идея тоже моя):


 Вход : HL - число (0-65535)
        A  - число (0-255)
 Выход: HL=HL*A

 HLA       LD   DE,0
 HLA1      AND  A
           RET  Z
           RRA
           JR   NC,L10
           EX   DE,HL
           ADD  HL,DE
           EX   DE,HL
 L10       ADD  HL,HL
           JR   HLA1


  Если ее запустить с HLA1, то это будет равносильно вычислению
HL=HL*A+DE.
  А теперь 2 очень короткие процедуры скроллирования экрана по
знакоместам с аттрибутами:


      SCROLL UP           SCROLL DOWN

SCRUP  LD  DE,16384   SCRDW  LD  DE,23295
       LD  A,24              LD  A,24
SU10   LD  HL,32      SD10   LD  HL,0-32
       ADD HL,DE             ADD HL,DE
       LD  BC,224            LD  BC,224
       LDIR                  LDDR
       LD  HL,1824           LD  HL,0-1824
       ADD HL,DE             ADD HL,DE
       LD  BC,32             LD  BC,32
       LDIR                  LDDR
       DEC A                 DEC A
       JR  NZ,SU10           JR  NZ,SD10
       RET                   RET


   Вопрос скроллирования экрана является очень важным для созда-
ния полноценных текстовых VIEWER'ов.Так как нетурбириванный Z80
не успевает обновить экран за одно прерывание, то при листании
текста во многих случаях наблюдается нечитаемое мерцание. Для
того,чтобы этого избежать необходима синхронизация скроллинга с
прерываниями и быстрое перестроение экрана. Этого можно достичь
используя 2 экрана 128 SPECCY,либо методом,который недавно при-
шел мне в голову и который должен показать хороший результат.
  Его сущность в том, что готовый экран начинает перебрасываться
не с началом прерывания, а где-то с его середины, в результате
чего времени на переброску будет около 1.5 INT'а, что на SCORPI-
ON'е (как на самом тормозном) составит >100000 тактов чего впол-
не достаточно для скроллирования без мерцания.Но все это работа-
ет только при переброске (перестроении) сверху вниз.Данный спо-
соб вполне может обеспечить скорость скроллирования без мерцания
25 строк в секунду.И напоследок приведу временные характеристики
некоторых видов переброски (перестроения) экрана:


            МЕТОД                        ТАКТЫ
         1 по LDIR                       129024
         2 процедуры SCRUP,SCRDW          99696
         3 переброска через стек          78336


   На этом данное повествование заканчиваю.

Буду рад выслушать все отклики, пожелания, вопросы и предложения
по телефону 28-70-91 (Марат) с 20-22ч.




Other articles:


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Similar articles:
INTRO - On the shell of the newspaper - its features.

В этот день...   21 November