ZX Review #5-6
04 ноября 1997

Ретро - 40 лучших процедур: Слияние картинок, Вращение символа по часовой стрелке, Инвертирование символов, Изменение атрибута, Закрашивание контура, Построение шаблонов (Дж.Хардман, Э.Хьюзон.).

<b>Ретро</b> - 40 лучших процедур: Слияние картинок, Вращение символа
       по часовой стрелке, Инвертирование символов, Изменение атрибута, Закрашивание контура, Построение шаблонов (Дж.Хардман, Э.Хьюзон.).
┌──────────────────────────────┐
│                              │
│           РЕТРО              │
│                              │
└──────────────────────────────┘

Дж.Хардман, Э.Хьюзон

       40 лучших процедур

Продолжение. Начало в ZX РЕВЮ
1997 NN 1-2, 3-4.

    6. ДИСПЛЕЙНЫЕ ПРОГРАММЫ

     6.1. Слияние картинок

  Длина: 21
  Количество переменных: 1
  Контрольная сумма: 1709
  Назначение:   эта    программа
объединяет  картинку, хранящуюся
в ОЗУ, с  текущим  экраном  дис-
плея.
  Атрибуты не изменяются.
  Переменные:
   Имя: screen_store
   Длина: 2
   Ячейка: 23296
  Комментарий:   содержит  адрес
картинки в ОЗУ.
  Вызов программы:
     RANDOMIZE USR адрес
  Контроль ошибок: нет.
  Комментарий:  Для  объединения
картинок должна быть использова-
на приведенная на листинге прог-
рамма.  Однако  интересные   ре-
зультаты могут быть также  полу-
чены заменой OR (HL) на XOR (HL)
или AND (HL).

   ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА  АССЕМБЛЕР      ЧИСЛА ДЛЯ ВВОДА
147.
       LD HL,16384    33   0  64
       LD DE,(23296) 237 91 0 91
       LD BC,6144      1   0  24
NEXT_B LD A,(DE)      26
       OR (HL)       182
       LD (HL),A     119
       INC HL         35
       INC DE         19
       DEC BC         11
       LD A,B        120
       OR C          177
       JR NZ,NEXT_B   32 246
       RET           201
2
  Как она работает:
  В пару регистров HL загружает-
ся начальный  адрес  дисплейного
файла, а в пару регистров  DE  -
его длина. Регистровая  пара  BC
используется в качестве  счетчи-
ка.
  В аккумулятор загружается байт
с адресом в DE и выполняется ло-
гическое ИЛИ (OR)  этого  значе-
ния с байтом дисплейного  файла.
Результат затем помещается в об-
ласть дисплея.
  HL и DE перемещаются на следу-
ющую позицию, счетчик уменьшает-
ся.  Если счетчик не равен 0, то
подпрограмма  возвращается назад
для  повторения процесса со сле-
дующим байтом.
 Программа возвращается в BASIC.

   6.2. Инвертирование экрана

  Длина: 18
  Количество переменных: 0
  Контрольная сумма: 1613
  Назначение: инвертирует все  в
дисплейном  файле:  если  пиксел
включен, он сбрасывается  (OFF),
если пиксел выключен,  он  уста-
навливается.
  Вызов программы:
     RANDOMIZE USR адрес
  Контроль ошибок: нет.
  Комментарий: эта программа мо-
жет быть использована для  полу-
чения эффекта вспышки. Этот  эф-
фект усиливается, если  делается
вызов несколько раз и добавляет-
ся звук.

   ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА  АССЕМБЛЕР      ЧИСЛА ДЛЯ ВВОДА
147.
       LD HL,16384    33   0  64
       LD BC,6144      1   0  24
       LD D,255       22 255
NEXT_B LD A,D        122
       SUB (HL)      150
       LD (HL),A     119
       INC HL         35
       DEC BC         11
       LD A,B        120
       OR C          177
       JR NZ,NEXT_B   32 247
       RET           201
2
  Как она работает:
  В пару регистров HL загружает-
ся адрес дисплейного файла, а  в
BC  загружается  его  длина.   В
D-регистр   помещается  значение
255. Всякий  раз, когда подпрог-
рамма возвращается  к  NEXT_B, в
аккумулятор загружается значение
из D-регистра.  Этот метод пред-
почтительнее, чем  инструкция LD
A,255, т.к.  LD A,D  выполняется
приблизительно в 2 раза быстрее,
чем инструкция LD A,255.  Значе-
ние  байта, хранящегося в ячейке
по адресу, указанному  в HL, вы-
читается  из аккумулятора, а ре-
зультат загружается в тот же са-
мый байт. Таким образом, делает-
ся инвертирование.
  HL увеличивается, указывая  на
следующий  байт,  а  счетчик  BC
уменьшается. Если счетчик не ра-
вен 0, программа возвращается  к
NEXT_B. Если  счетчик  равен  0,
программа возвращается в BASIC.

  6.3. Инвертирование символа
          вертикально

  Длина: 20
  Количество переменных: 1
  Контрольная сумма: 1757
  Назначение: эта программа  ин-
вертирует  символ   вертикально.
Например, стрелка,  направленная
вверх,  должна  стать  стрелкой,
направленной вниз, и наоборот.
  Переменные:
   Имя: chr_start
   Длина: 2
   Ячейка: 23296
  Комментарий:  адрес символа  в
ОЗУ (ПЗУ).
  Вызов программы:
     RANDOMIZE USR адрес
  Контроль ошибок: нет.
  Комментарий: эта программа по-
лезна в играх, т.к. можно  изме-
нять отдельные  символы, не  за-
трагивая при этом соседние обла-
сти изображения.

   ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА  АССЕМБЛЕР      ЧИСЛА ДЛЯ ВВОДА
147.
       LD HL,(23296)  42   0  91
       LD D,H         84
       LD E,L         93
       LD B,8          6   8
NEXT_B LD A,(HL)     126
       INC HL         35
       PUSH AF       245
       DJNZ NEXT_B    16 251
       LD B,8          6   8
REPL   POP AF        241
       LD (DE),A      18
       INC DE         19
       DJNZ REPL      16 251
       RET           201
2
  Как она работает:
  В пару регистров HL загружает-
ся адрес данных символа. Этот же
адрес затем копируется в  DE.  В
регистр B загружается значение 8
для использования регистра в ка-
честве счетчика.
  Для каждого байта в  аккумуля-
тор загружается имеющееся в нас-
тоящий момент значение. HL  уве-
личивается, указывая на  следую-
щий байт, а содержимое аккумуля-
тора помещается на  стек.  Счет-
чик уменьшается и,  если  он  не
равен  0,  подпрограмма  возвра-
щается, чтобы повторить  процесс
для следующего байта. В  регистр
B повторно загружается  значение
8, чтобы снова использовать  его
в качестве  счетчика.  Изображе-
ние символа сохранено на стеке.
  Процедура REPL возвращает дан-
ные со стека на то же  знакомес-
то, но уже в обратном порядке.
  Байт за байтом берутся со сте-
ка и через аккумулятор помещают-
ся по  адресу,  содержащемуся  в
DE. DE увеличивается, чтобы ука-
зать на следующий байт, а  счет-
чик уменьшается. Если он не  ра-
вен 0, программа возвращается  к
REPL.  В  противном  случае  она
возвращается в BASIC.

  6.4. 

  Длина: 19
  Количество переменных: 1
  Контрольная сумма: 1621
  Назначение: эта программа  ин-
вертирует символ  горизонтально.
Например, стрелка,  направленная
влево, становится стрелкой, нап-
равленной вправо.
  Переменные:
   Имя: chr_start
   Длина: 2
   Ячейка: 23296
   Комментарий:   адрес   данных
символа.
  Вызов программы:
     RANDOMIZE USR адрес
  Контроль ошибок: нет.
  Комментарий: нет.

   ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА  АССЕМБЛЕР      ЧИСЛА ДЛЯ ВВОДА
147.
       LD HL,(23296)  42   0  91
       LD A,8         62   8
NEXT_B LD B,8          6   8
NEXT_P RR (HL)       203  30
       RL C          203  17
       DJNZ NEXT_P    16 250
       LD (HL),C     113
       INC HL         35
       DEC A          61
       JR NZ,NEXT_B   32 243
       RET           201
2
  Как она работает:
  В пару регистров HL загружает-
ся адрес данных символа, а в ак-
кумулятор  загружается  количес-
тво байтов, которые должны  быть
инвертированы. В регистр B  заг-
ружается число  битов  в  каждом
байте  -  он  используется   как
счетчик.
  Байт с адресом в HL  сдвигает-
ся  вправо  таким  образом,  что
крайний правый бит копируется во
флаг переноса.  C-регистр  сдви-
гается влево так, что флаг пере-
носа копируется в  крайний  пра-
вый  бит.  Счетчик   (B-регистр)
уменьшается.
  Если  счетчик  не  равен    0,
происходит переход к NEXT_P  для
работы со следующим пикселом.
  Инвертированный байт,  который
находится в  регистре  C,  поме-
щается в ячейку, из  которой  он
был взят.
  HL увеличивается, указывая  на
следующий  байт,  а  аккумулятор
уменьшается. Если аккумулятор не
равен 0,  происходит  переход  к
NEXT_BYTE, в противном  случае -
возврат в BASIC.

      6.5. Вращение символа
       по часовой стрелке

  Длина: 42
  Количество переменных: 1
  Контрольная сумма: 3876
  Назначение: эта программа  по-
ворачивает символ на  90  граду-
сов по часовой  стрелке.  Напри-
мер,    стрелка,    направленная
вверх,  становится  направленной
вправо.
  Переменные:
   Имя: chr_start
   Длина: 2
   Ячейка: 23296
   Комментарий:   адрес   данных
символа.
   Вызов программы:
     RANDOMIZE USR адрес
  Контроль ошибок: нет.
  Комментарий: эта программа по-
лезна в играх  и  для  серьезных
целей, например, в графике.

   ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА  АССЕМБЛЕР      ЧИСЛА ДЛЯ ВВОДА
147.
       LD HL,(23296)  42   0  91
       LD E,128       30 128
N_BIT  PUSH HL       229
       LD C,0         14   0
       LD B,1          6   1
NEXT_B LD A,E        123
       AND (HL)      166
       CP 0          254   0
       JR Z,NOT_S     40   3
       LD A,C        121
       ADD A,B       128
       LD C,A         79
NOT_S  SLA B         203  32
       INC HL         35
       JR NZ,NEXT_B   48 242
       POP HL        225
       PUSH BC       197
       SRL E         203  59
       JR NC,N_BIT    48 231
       LD DE,7        17   7   0
       ADD HL,DE      25
       LD B,8          6   8
REPL   POP DE        209
       LD (HL),E     115
       DEC HL         43
       DJNZ REPL      16 251
       RET           201
2
  Как она работает:
  Символ состоит из группы  пик-
селей размером  8х8,  каждый  из
которых может быть  в  состоянии
ON (1) или OFF  (0).  Рассмотрим
любой бит B2 байта B1 на  рис.1.
Данные хранятся в ячейке (B2,B1)
в форме:

          │ N1   N3 │
          │ N2   N4 │

  где:
  N1 = байт,  в  который  пиксел
  (B2,B1) будет  вставлен  после
  вращения.
  N2 = бит в N1,  в  который  он
  будет вставлен.
  N3 = значение,  которое  пред-
ставляет текущее значение бита.
  N4 = значение бита N2.  Каждый
байт  вращаемого  символа  будет
сформирован  добавлением  значе-
ний всех битов N2,  которые  бу-
дут в новом байте.

┌──────────────────────────────────────────────────────────────┐
│ ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐            │
│ │1 128│2  64│3  32│4  16│5   8│6   4│7   2│8   1│  1         │
│ │0   1│0   1│0   1│0   1│0   1│0   1│0   1│0   1│            │
│ ├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤            │
│ │1 128│2  64│3  32│4  16│5   8│6   4│7   2│8   1│  2         │
│ │1   2│1   2│1   2│1   2│1   2│1   2│1   2│1   2│            │
│ ├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤            │
│ │1 128│2  64│3  32│4  16│5   8│6   4│7   2│8   1│  3         │
│ │2   4│2   4│2   4│2   4│2   4│2   4│2   4│2   4│            │

│ ├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤            │
│ │1 128│2  64│3  32│4  16│5   8│6   4│7   2│8   1│  4         │
│ │3   8│3   8│3   8│3   8│3   8│3   8│3   8│3   8│            │
│ ├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤    Байт(B1)│
│ │1 128│2  64│3  32│4  16│5   8│6   4│7   2│8   1│  5         │
│ │4  16│4  16│4  16│4  16│4  16│4  16│4  16│4  16│            │
│ ├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤            │
│ │1 128│2  64│3  32│4  16│5   8│6   4│7   2│8   1│  6         │
│ │5  32│5  32│5  32│5  32│5  32│5  32│5  32│5  32│            │
│ ├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤            │
│ │1 128│2  64│3  32│4  16│5   8│6   4│7   2│8   1│  7         │
│ │6  64│6  64│6  64│6  64│6  64│6  64│6  64│6  64│            │
│ ├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤            │
│ │1 128│2  64│3  32│4  16│5   8│6   4│7   2│8   1│  8         │
│ │7 128│7 128│7 128│7 128│7 128│7 128│7 128│7 128│            │
│ └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘            │
│   7     6     5     4     3     2     1     0   Бит(B2)      │
│                                                              │
│         Рис.1. Ключ к подпрограмме вращения символа          │
└──────────────────────────────────────────────────────────────┘

  В HL загружается адрес  перво-
го байта символа.  В  регистр  E
загружается значение байта,  ко-
торый имеет 7-й бит в  состоянии
ON и с 0 по 6-й биты  -  в  OFF,
т.е. 128. HL сохраняется в  сте-
ке. В регистр  C  засылается  0.
Далее в него  будут  добавляться
данные, давая новое значение для
формируемого байта. В регистр  B
загружается значение байта,  ну-
левой  бит  которого  включен, а
биты  1-7 - выключены, т.е., это
единица.
  В аккумулятор загружается  со-
держимое  E-регистра  (N3).  Это
значение перемножается  логичес-
ки (AND) с байтом, адрес которо-
го  хранится  в  HL.  Если   ре-
зультат равен 0, происходит  пе-
реход к NOT_S, т.к. пиксел,  ад-
ресованный регистром E и  регис-
тровой парой HL  сброшен  (OFF).
Если же он  установлен  (ON),  в
аккумулятор загружается имеющее-
ся значение байта (N1).  Регистр
B (N4) добавляется к аккумулято-
ру и это значение загружается  в
регистр C. Регистр  затем  уста-
навливается,  чтобы  указать  на
следующий бит  N1.  HL  увеличи-
вается,  указывая  на  следующий
байт (B1). Если байт N1  не  за-
вершен, подпрограмма возвращает-
ся к NEXT_B.
  HL восстанавливается из стека,
чтобы снова  указать  на  первый
байт символа. BC  сохраняется  в
стеке, чтобы запомнить  значение
последнего байта для  завершения
в C-регистре. E-регистр настраи-
вается на адрес следующего  бита
каждого байта. Если вращение  не
завершено, происходит переход  к
N_BIT.
  В DE загружается значение 7, и
это значение добавляется  к  HL.
Теперь HL указывает  на  послед-
ний байт  данных.  В  регистр  B
загружается число байтов,  кото-
рые должны быть взяты из  стека.
Для каждого байта новое значение
копируется в E, и  это  значение
помещается в ячейку с адресом  в
HL.  HL уменьшается, чтобы  ука-
зать на следующий байт, и  счет-
чик (B-регистр) уменьшается.
  Если счетчик  не равен 0, про-
исходит переход к REPL.
 Программа возвращается в BASIC.

     6.6. Изменение атрибута

  Длина: 21
  Количество переменных: 2
  Контрольная сумма: 1952
  Назначение: эта программа  из-
меняет значение  атрибутов  всех
символов экрана  на  задаваемое,
например,  могут  быть  изменены
цвета всех символов или весь эк-
ран может замигать и т.д.
  Переменные:
   Имя: data_saved
   Длина: 1
   Ячейка: 23296
  Комментарий: неизменяемые биты
атрибута.
   Имя: new_data
   Длина: 1
   Ячейка: 23297
  Комментарий:  новые биты, вво-
димые в байт атрибута.
  Вызов программы:
     RANDOMIZE USR адрес
  Контроль ошибок: нет.
  Комментарий:  отдельные   биты
атрибута каждого  символа  могут
быть изменены с помощью инструк-
ции AND и OR.

   ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА  АССЕМБЛЕР      ЧИСЛА ДЛЯ ВВОДА
147.
       LD HL,22528    33   0  88
       LD BC,768       1   0   3
       LD DE,(23296) 237 91 0 91
NEXT_B LD A,(HL)     126
       AND E         163
       OR D          178
       LD (HL),A     119
       INC H          35
       DEC BC         11
       LD A,B        120
       OR C          177
       JR NZ,NEXT_B   32 246
       RET           201
2
  Как она работает:
  В пару регистров HL загружает-
ся адрес области атрибутов, а  в
пару  регистров  BC - количество
символов на экране. В регистр  D
загружается значение new_data, а
в регистр E  загружается  значе-
ние data_saved.
  В аккумулятор загружается байт
с адресом, находящимся в  HL,  а
биты  устанавливаются   соответ-
ственно значениям регистров D  и
E. Результат помещается  обратно
в ячейку в адресом, хранящимся в
HL.  HL увеличивается,  указывая
на следующий байт, а счетчик  BC
уменьшается. Если содержимое  BC
на равно 0, программа  возвраща-
ется к NEXT_B.
 Программа возвращается в BASIC.

      6.7. Смена атрибута

  Длина: 22
  Количество переменных: 2
  Контрольная сумма: 1825
  Назначение: эта программа ищет
атрибуты с  определенным  значе-
нием и заменяет  каждое  найден-
ное вхождение другим значением.
  Переменные:
   Имя: old_value
   Длина: 1
   Ячейка: 23296
  Комментарий:  значение  байта,
подлежащего замене.
   Имя: new_value
   Длина: 1
   Ячейка: 23297
  Комментарий: значение замещаю-
щего байта.
  Вызов программы:
     RANDOMIZE USR адрес
  Контроль ошибок: нет.
  Комментарий: эта программа по-
лезна  для  выделения   областей
текста и графических символов.

   ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА  АССЕМБЛЕР      ЧИСЛА ДЛЯ ВВОДА
147.
       LD HL,22528    33   0  88
       LD BC,768       1   0   3
       LD DE,(23296) 237 91 0 91
NEXT_B LD A,(HL)     126
       CP E          187
       JR NZ,NO_CH    32   1
       LD (HL),D     114
N)_CH  INC HL         35
       DEC BC         11
       LD A,B        120
       OR C          177
       JR NZ,NEXT_B   32 245
       RET           201
2
  Как она работает:
  В пару регистров HL загружает-
ся адрес области атрибутов, а  в
BC загружается число символов на
экране. В E-регистр  загружается
old_value, а в D-регистр nev_va-
lue.  В  аккумулятор загружается
байт, адрес которого хранится  в
паре HL. Если аккумулятор хранит 
значение,  которое  эквивалентно
содержимому  E-регистра,  то   в
байт  с адресом, имеющимся в HL, 
помещается  содержимое  D-регис-
тра.  При этом HL увеличивается,
указывая  на  следующий  байт, а
счетчик  BC уменьшается. Если BC
не равно 0, происходит переход к   
NEXT_B, иначе программа  возвра-
щается в BASIC.

    6.8. Закрашивание контура

  Длина: 263
  Количество переменных: 2
  Контрольная сумма: 26647
  Назначение: эта программа зак-
рашивает область экрана, ограни-
ченную линией пикселей.
  Переменные:
   Имя: X_coord
   Длина: 1
   Ячейка: 23296
  Комментарий:    координата   X
стартовой позиции.
   Имя: Y_coord
   Длина: 1
   Ячейка: 23297
  Комментарий:    координата   Y
стартовой позиции.
  Вызов программы:
     RANDOMIZE USR адрес
  Контроль ошибок: если  коорди-
ната Y>175 или POINT (X,Y)=1, то
программа тотчас же возвращается
в BASIC.
  Комментарий: эта программа  не
перемещаемая, ее  стартовый  ад-
рес - 31955. Когда  закрашивает-
ся большая область сложной  фор-
мы,  нужно  большое   количество
свободного  пространства.   Если
это невозможно, может  произойти
сбой.

   ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА  АССЕМБЛЕР      ЧИСЛА ДЛЯ ВВОДА
147.
       LD HL,(23296)  42   0  91
       LD A,H        124
       CP 176        254 176
       RET NC        208
       CALL SUBR     205 143*125
       AND (HL)      166
       CP 0          254   0
       RET NZ        192
       LD BC,65535     1 255 255
       PUSH BC       197
RIGHT  LD HL,(23296)  42   0  91
       CALL SUBR     205 143*125
       AND (HL)      166
       CP 0          254   0
       JR NZ,LEFT     32   9
       LD HL,(23296)  42   0  91
       INC L          44
       LD (23296),HL  34   0  91
       JR NZ,RIGHT    32 236
LEFT   LD DE,0        17   0   0
       LD HL,(23296)  42   0  91
       DEC L          45
       LD (23296),HL  34   0  91
PLOT   LD HL,(23296)  42   0  91
       PUSH HL       229
       CALL SUBR     205 143*125
       OR (HL)       182
       LD (HL),A     119
       POP HL        225
       LD A,H        124
       CP 175        254 175
       JR Z,DOWN      40  44
       LD A,E        123
       CP 0          254   0
       JR NZ,RESET    32  16
       INC H          36
       CALL SUBR     205 143*125
       AND (HL)      166
       CP 0          254   0
       JR NZ,RESET    32   7
       LD HL,(23296)  42   0  91
       INC H          36
       PUSH HL       229
       LD E,1         30   1
RESET  LD HL,(23296)  42   0  91
       LD A,E        123
       CP 1          254   1
       JR NX,DOWN     32  15
       INC H          36
       CALL SUBR     205 143*125
       AND (HL)      166
       CP 0          254   0
       JR Z, DOWN     40   6
       LD E,0         30   0
       JR DOWN        24   2
L_JUMP JR RIGHT       24 167
DOWN   LD HL,(23296)  42   0  91
       LD A,H        124
       CP 0          254   0
       JR Z,NEXT_P    40  40
       LD A,D        122
       CP 0          254   0
       JR NZ,REST     32  16
       DEC H          37
       CALL SUBR     205 143*125
       AND (HL)      166
       CP 0          254   0
       JR NZ,REST     32   7
       LD HL,(23296)  42   0  91
       DEC H          37
       PUSH HL       229
       LD D,1         22   1
REST   LD A,D        122   1
       CP 1          254   1
       JR NZ,NEXT_P   32  14
       LD HL,(23296)  42   0  91
       DEC H          37
       CALL SUBR     205 143*125
       AND (HL)      166
       CP 0          254   0
       JR Z,NEXT_P    40   2
       LD D,0         22   0
NEXT_P LD HL,(23296)  42   0  91
       LD A,L        125
       CP 0          254   0
       JR Z,RETR      40  12
       DEC L          45
       LD (23296),HL  34   0  91
       CALL SUBR     205 143*125
       AND (HL)      166
       CP 0          254   0
       JR Z,PLOT      40 129
RETR   POP HL        225
       LD (23296),HL  34   0  91
       LD A,255       62 255
       CP H          188
       JR NZ,L_JUMP   32 177
       CP 1          189
       JR NZ,L_JUMP   32 174
       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        203  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

147.
       RRA           203  31
       AND 31        203  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
  Как она работает:
  Эта программа вычерчивает  го-
ризонтальные  линии  из  смежных
пикселей. Назовем их  строчками.
Предел заполнения области строч-
ками ограничен включенными  (ON)
пикселями. Каждая строчка  запо-
минается с помощью  занесения  в
стек координат крайнего  правого
пикселя этой строчки.
  Запускаясь   с    определенных
координат, программа делает  за-
полнение в каждой строчке, отме-
чая позиции каждой  из  невыпол-
ненных строчек выше или ниже. По
завершении одной строчки послед-
нее значение отмеченных  коорди-
нат  восстанавливается  и    для
соответствующей строчки происхо-
дит  заполнение.  Этот   процесс
повторяется до тех пор, пока  не
останется незаполненных строчек.
  Рис.2  иллюстрирует    технику
процесса. Квадраты  представляют
пиксели, X обозначает  стартовую
позицию в пределах области штри-
ховки, а  *  обозначает  крайние
правые пиксели строчек.

       ┌───────────────────────────────────────────────┐
       │   ┌────╥────╥────╥────╥────╥────╥────╥────┐   │
       │   │////║////║////║////║////║////║////║////│   │
       │   ╞════╬════╬════╬════╬════╬════╬════╬════╡   │
       │   │////║  0 ║////║    ║  * ║////║////║////│   │
       │   ╞════╬════╬════╬════╬════╬════╬════╬════╡   │
       │   │////║  0 ║////║    ║  X ║    ║    ║////│   │
       │   ╞════╬════╬════╬════╬════╬════╬════╬════╡   │
       │   │////║////║////║    ║    ║    ║  * ║////│   │
       │   ╞════╬════╬════╬════╬════╬════╬════╬════╡   │
       │   │////║    ║    ║  * ║////║    ║  * ║////│   │
       │   ╞════╬════╬════╬════╬════╬════╬════╬════╡   │
       │   │////║    ║  * ║////║////║////║  * ║////│   │
       │   ╞════╬════╬════╬════╬════╬════╬════╬════╡   │
       │   │////║    ║  * ║////║////║////║  * ║////│   │
       │   ╞════╬════╬════╬════╬════╬════╬════╬════╡   │
       │   │////║////║////║////║////║////║////║////│   │
       │   └────╨────╨────╨────╨────╨────╨────╨────┘   │
       │ Рис.2. Иллюстрация техники заполнения области │
       │   X - стартовая позиция, * - начало строчек,  │
       │    0 - оставшаяся незаштрихованная область    │
       └───────────────────────────────────────────────┘

  Программа  штрихует   горизон-
тальную линию, содержащую  стар-
товую  позицию,  и  сохраняет  в
стеке позицию начала строчки  на
линиях  непосредственно  выше  и
ниже.  Далее  она штрихует линию
выше, а  затем  ниже, отмечая  в
последнем  случае, что  еще  две
строчки запускаются  на  следую-
щей нижней строке и  т.д.  Любая
позиция в пределах  области  для
штриховки может быть выбрана как
стартовая позиция.  Но  заметим,
что два пикселя,  промаркирован-
ные нулями, нетронуты, т.к.  они
отделены от заштриховываемой об-
ласти.
  В регистр H загружается  Y-ко-
ордината, а в  L-регистр - X-ко-
ордината. Если значение Y больше 
чем 175, программа  возвращается  
в BASIC. Процедура SUBR  вызыва-
ется, возвращая адрес бита (X,Y)  
в память. Если этот бит в состо-
янии  ON (включен), подпрограмма  
возвращается в BASIC.
  Число 65535 помещается в стек,
чтобы отметить первое  сохранен-
ное  значение.  Позднее,   когда
число восстанавливается из  сте-
ка,  оно  интерпретируется,  как
пара  координат.  Однако,   если
число  равно  65535,  происходит
возврат в BASIC, т.к.  программа
закончена.
  В регистр H загружается  Y-ко-
ордината, а в  регистр L - X-ко-
ордината. Процедура SUBR вызыва-
ется, возвращая в  HL адрес бита 
(X,Y). Если этот бит  установлен 
(ON), происходит переход к LEFT. 
Иначе X-координата увеличивается 
и делается переход к RIGHT, если 
X не равен 256.
  В процедуре LEFT DE устанавли-
вается в 0. Регистры D и  E  ис-
пользуются как флаги: D  -  вниз
(DOWN), E - вверх (UP).  X-коор-
дината уменьшается.  SUBR  вызы-
вается  и  вычерчивается   точка
(X,Y). Если  Y-координата  равна
175,  подпрограмма  переходит  к
DOWN. Если флаг  ВВЕРХ  установ-
лен, происходит переход к RESET.
Если бит (X,Y+1) сброшен, значе-
ние X и Y+1 сохраняется в  стеке
и флаг ВВЕРХ включается.
  В процедуре RESET,  если  флаг
ВВЕРХ включен, происходит  пере-
ход к  DOWN.  Если  бит  (X,Y+1)
включен (ON), флаг ВВЕРХ  выклю-
чается. В процедуре  DOWN,  если
Y-координата равна  0,  происхо-
дит переход к  NEXT_PIXEL.  Если
флаг  ВНИЗ  включен,  происходит
переход к REST. Если бит (X,Y-1)
сброшен (OFF), то значения  X  и
Y-1 сохраняются на стеке и  флаг
ВНИЗ включается.
  В процедуре  REST,  если  флаг
ВНИЗ выключен, происходит  пере-
ход к NEXT_P. Если  бит  (X,Y-1)
установлен (ON),  то  флаг  ВНИЗ
выключается. В процедуре NEXT_P,
если X-координата равна 0,  под-
программа  переходит  к    RETR.
X-координата уменьшается и  если
новый бит (X,Y)  сброшен  (OFF),
происходит  переход  к  PLOT.  В
процедуре RETR X- и  Y-координа-
ты извлекаются из стека. Если  X
и Y равны 255, то  -  возврат  в
BASIC, т.к.  заполнение  области
завершено.  Иначе   подпрограмма
возвращается в RIGHT.
  Процедура SUBR должна  подсчи-
тать адрес бита (X,Y) в  памяти.
В BASIC этот адрес будет:      

16384 + INT(Z/8) + 256 * (Z - 8 
* INT(Z/8)) + 32 * (64 * INT(Z/
64) + INT(Z/8) - 8 * INT(Z/64))

  где Z=175-Y.

  Пары регистров BC и DE  сохра-
няются на стеке.  В  аккумулятор
засылается число 175, и из этого
значения  вычитается  Y-коодина-
та. Результат копируется в H-ре-
гистр. Затем HL  сохраняется  на
стеке. Пять левых битов  аккуму-
лятора устанавливаются  в  0,  а
затем к ним прибавляется 64. Ре-
зультат копируется в  C-регистр.
При умножении на 256 получаем:

   16384+256*(Z-8*INT(Z/8))

  В аккумулятор  загружается  Z,
это значение делится на  8,  ре-
зультат копируется в регистр  B.
Этот результат - INT(Z/8). Уста-
новка трех крайних правых  битов
в 0 при  ротации  дает  значение
8*INT(Z/64), которое  загружает-
ся в D-регистр.
  В аккумулятор загружается Z  и
6 крайних  правых  битов  выклю-
чается, что  дает  64*INT(Z/64).
Это значение загружается в E-ре-
гистр.  Значение  из  C-регистра
копируется в  H.  В  аккумулятор
загружается  X-координата,   это
значение делится  на  8,  а  ре-
зультат копируется в L.
  В аккумулятор затем загружает-
ся значение E-регистра и к  нему
прибавляется содержимое B.  Зна-
чение  D-регистра  вычитается  и
результат загружается в DE.  Это
значение умножается  на  32,  DE
восстанавливается  из  стека   и
прибавляется к HL. Т.о.  HL  те-
перь хранит адрес бита (X,Y).
  В аккумулятор загружается пер-
воначальное значение X. Установ-
ка пяти левых битов в ноль  дает
значение X-8*INT(X/8).  В  B-ре-
гистр затем загружается 8  минус
значение аккумулятора, чтобы ис-
пользовать его в качестве  счет-
чика. Аккумулятор устанавливает-
ся в 1 и  это  умножается  на  2
(B-1) раз.
  В этот момент  в  аккумуляторе
необходимо установить бит, кото-
рый соответствует биту  (X,Y)  с
адресом в HL. DE и BC затем вос-
станавливаются из стека, и  SUBR
выполняет  возврат  в   основную
программу.

    6.9. Построение шаблонов

  Длина: 196
  Количество переменных: 2
  Контрольная сумма: 20278
  Назначение: эта программа чер-
тит шаблон любого размера на эк-
ране.  Под  шаблоном  понимается
любая, ранее определенная фигура.
  Переменные:
   Имя: X_start
   Длина: 1
   Ячейка: 23296
  Комментарий:  X-координата пер-
вого пикселя.
   Имя: Y_start
   Длина: 1
   Ячейка: 23297
  Комментарий:  Y-координата пер-
вого пикселя. 
  Вызов программы:
     RANDOMIZE USR адрес
  Контроль ошибок: если  строко-
вая переменная, хранящая  инфор-
мацию по шаблону A$,  не  сущес-
твует, имеет нулевую  длину  или
не содержит никакой  информации,
программа возвращается непосред-
ственно в BASIC. Это  происходит
также  в  случае,  если  Y-start
больше, чем 175.
  Комментарий:   это    полезная
программа для хранения  фигур  в
памяти и  быстрого  вычерчивания
их на экране.
  Использование этой программы:

  (I) LET  A$ = "информация   по
шаблону"
  (II) POKE  23296, X-координата
первого пикселя
  (III) POKE 23297, Y-координата
первого пикселя
  (IV) RANDOMIZE USR адрес

  Информация шаблона - это  сим-
вол,  который   имеет  следующий
формат: 

  "0" - поместить точку
  "5" - уменьшить X-координату
  "6" - уменьшить Y-координату 
  "7" - увеличить X-координату  
  "8" - увеличить Y-координату

   Любые другие символы  игнори-
руются. Программа включает в се-
бя  возможность    "wrap-round",
т.е., если X-координата  выходит
за левую  часть  экрана,  шаблон
появляется справа и т.п.
  Чтобы изменить  программу  для
использования иной строковой пе-
ременной вместо A$, нужно  изме-
нить 65*  (код буквы A)  на  код
иного символа.

   ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА  АССЕМБЛЕР      ЧИСЛА ДЛЯ ВВОДА
147.
       LD HL,(23627)  42  75  92
NEXT_V LD A,(HL)     126
       CP 128        254 128
       RET Z         200
       BIT 7,A       203 127
       JR NZ,FORNXT   32  23
       CP 96         254  96
       JR NC,NUMBER   48  11
       CP 65         254  65*
       JR Z,FOUND     40  35
STRING INC HL         35
       LD E,(HL)      94
       INC HL         35
       LD D,(HL)      86
ADD    ADD HL,DE      25
       JR INCR        24   5
NUMBER INC HL         35
       INC HL         35
       INC HL         35
       INC HL         35
       INC HL         35
INCR   INC HL         35
       JR NEXT_V      24 225
FORNXT CP 224        254 224
       JR C,N_BIT     56   5
       LD DE,18       17  18   0
       JR ADD         24 236
N_BIT  BIT 5,A       203 111
       JR Z,STRING    40 228
NEXT_B INC HL         35
       BIT 7,(HL)    203 126
       JR Z,NEXT_B    40 251
       JR NUMBER      24 228
FOUND  INC HL         35
       LD C,(HL)      78
       INC HL         35
       LD B,(HL)      70
       INC HL         35
       EX DE,HL      235
       LD A,(23297)   58   1  91
       CP 176        254     176
       RET NC        208
AGAIN  LD HL,(23296)  42   0  91
       LD A,B        120
       OR C          177
       RET Z         200
       DEC BC         11
       LD A,(DE)      26
       INC DE         19
       CP 48         254  48
       JR NZ,NOT_PL   32  78
       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

147.
       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,L         62   1
ROTARE ADD A,A       135
       DJNZ ROTARE    16 253
       RRA           203  31
       POP DE        209
       POP BC        193
       OR (HL)       182
       LD (HL),A     119
HERE   JR AGAIN       24 165
NOT_PL CP 53         254  53
       JR NZ,DOWN     32   1
       DEC 1          45
DOWN   CP 54         254  54
       JR NZ,UP       32   8
       DEC H          37
       LD H,A        124
       CP 255        254 255
       JR NZ,SAVE     32  19
       LD H,175       38 175
       CP 55         254  55
       JR NZ,RIGHT    32   8
       INC H          36
       LD A,H        124
       CP 176        254 176
       JR NZ,SAVE     32   7
       LD H,0         38   0
RIGHT  CP 56         254  56
       JR NZ,SAVE     32   1
       INC 1          44
SAVE   LD (23296),HL  34   0  91
       JR HERE        24 215
2
  Как она работает:
  Для нахождения адреса  строко-
вой переменной используется  не-
много измененная  первая   часть
программы "Поиск подстроки".
  Длина  строковой    переменной
загружается в BC, а адрес перво-
го символа A$ загружается в  DE.
В  аккумуляторе  устанавливается
начальное значение Y и, если оно
больше 175, подпрограмма возвра-
щается в BASIC. В H-регистр заг-
ружается Y-координата, а в  L  -
X-координата. Если значение  па-
ры регистров BC  равно  0,  под-
программа возвращается в  BASIC,
т.к. достигнут  конец  строковой
переменной. BC уменьшается, что-
бы показать, что  обрабатывается
следующий символ. Следующий сим-
вол загружается в аккумулятор  и
DE  увеличивается,  указывая  на
следующий байт.  Если  аккумуля-
тор не содержит код 48, происхо-
дит  переход  к  NOT_PL.   Точка
(X,Y)  вычерчивается,  используя
процедуру  SUBR  из    программы
"Закрашивание  контура".   Затем
программа возвращается  назад  к
AGAIN.
  В процедуре NOT_PL, если акку-
мулятор  содержит   число    53,
X-координата уменьшается. В про-
цедуре DOWN, если аккумулятор не
содержит число 54, делается  пе-
реход к UP. Y-координата  умень-
шается, и, если ее значение ста-
новится равным  -1, Y-координата
устанавливается на значение 175.
  В процедуре UP, если аккумуля-
тор не содержит  55,  происходит
переход  к  RIGHT.  Y-координата
увеличивается, и, если она равна
176, то Y-координата  устанавли-
вается в 0. В  процедуре  RIGHT,
если аккумулятор содержит значе-
ние  56,  X-координата  увеличи-
вается. В процедуре SAVE коорди-
наты X и Y помещаются в  память,
а  программа  делает  переход  к
HERE.

           *   *   *




Другие статьи номера:

Adventure Project - Проектирование и разработака Адвентюрных и RPG игр.

Adventure Project - Русификация адвентюр.

TR-DOS для начинающих - Продолжение.

Авторская разработка - Scorpion 2000 (С.Зонов).

Авторская разработка - Трамплин (С.Веремеенко).

Визитная карточка - новый электронный юмористический журнал "SpectrofUn".

Перекресток драконов - Раскрутка игры Finders Keepers.

Перекресток драконов - Раскрутка игры Knight Tyme.

Перекресток драконов - Раскрутка игры Spellbound.

Перекресток драконов - Раскрутка игры Stormbringer.

Ретро - 40 лучших процедур: Слияние картинок, Вращение символа по часовой стрелке, Инвертирование символов, Изменение атрибута, Закрашивание контура, Построение шаблонов (Дж.Хардман, Э.Хьюзон.).

Советы экспертов - Total Eclipse 2.

Советы экспертов Super League.

Форум-игры - Описание игры Страна Мифов.

Форум-игры - Прохождение Renegade.

Форум-игры - Тонкости торговли в игре Elite

Форум - Изучение и отладка @-файлов с помощью STS 5.1. Особенности отладки программ с помощью монитора STS. Исправление ошибки STS 5.1.

Форум - Компрессия программ.

форум - О сокращении времени форматирования. О записи секторов одновременно с форматированием. Перестроение экрана за одно прерывание.

Форум - Особенности ассемблера ZX ASM 3.0.

Форум - По поводу компилятора бейсика "Blast".

Форум - По поводу релоцируемых программ.

Форум - Программы "Пламя" и "Дракон".

Читатель-читателю - TR-DOS: как не допустить ошибки?

Читатель-читателю - Эффективная работа с дисководом .

Этиды - Расчет адреса в файле атрибутов. Программа скроллирования заданного окна на 1 пиксел вправо. Программа очистки заданного окна. Процедура вывода картинки из буфера.

Этюды - Индикатор каналов музыкального процессора. Процедура очистки экрана. Предложение по стандартизации.

Этюды - Набор из восьми программ "расширения" экрана. Две процедуры проявления экрана.

Этюды - Новые темы для разработок.

Этюды - Программа воспроизведения инструмента от редакторов оцифрованной музыки.

Этюды - Программа обработки @-бейсик файлов.

Этюды - Процедура поворота символа на 90 градусов по часовой стрелке.

Этюды - Процедура поиска текстовых файлов.

Этюды - Экранная процедура "UP HL".


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

Похожие статьи:
Новый ночной бред - сказочка на ночь.
чудеса - кружится метель...
Объявления
Открытые письма Nemo №5.9
Приложение - приложение журнала.

В этот день...   25 апреля