Deja Vu #0A
30 сентября 2000

__________________________________________

(C) KAPsoft '2000
__________________________________________

              К ВОПРОСУ ...

   В своей  небольшой  статье я постарался
осветить  некоторые  вопросы,  с  которыми
столкнулся в  последнее время. В  основном
этот материал рассчитан  на  программиста,
но и другим не мешало бы его почитать.

              ...О КОНВЕРСИИ

   В Deja Vu #08 была  статья  о конверсии
SCREEN'ов в текстовые файлы. Идея была та-
кова: подсчитываем  количество  включенных
пикселов (точек) в блоке (8 на 4), и,в со-
ответствии с их количеством,ставим тот или
иной символ.
   Я   предлагаю  другой  алгоритм.  Опишу
вкратце его суть. На рассматреваемый  блок
накладываем по очереди все символы  загру-
женного  FONT'а.  Подсчитываем  количество
совпадений (одинакого включенных  или вык-
люченных пикселов). Тот символ, у которого
совпадений  больше, ставим  вместо  блока.
Повторяем все для остальных блоков.
   Да,это все будет работать довольно мед-
ленно. Но и качество будет лучше.
   Вот  листинг программы, выполняющей та-
кую конверсию.

DEMO  CALL START
      LD   A,2
      CALL #1601
      LD   A,22
      RST  16
      XOR  A
      RST  16
      XOR  A
      RST  16
      LD   BC,768
      LD   DE,TEXT
      JP   #203C
;
START LD   HL,#4000
      LD   DE,TEXT
      CALL ST1
      LD   HL,#4800
      CALL ST1
      LD   HL,#5000
      JP   ST1
;
ST1   LD   BC,256
LOOP  PUSH BC
      PUSH DE
      LD   DE,15616
      LD   B,96
      XOR  A
      LD   (NUM+1),A
      LD   (NUP+1),A
      DEC  A
      LD   (RAZL+1),A
N_4   PUSH BC
      LD   C,0
      PUSH HL
      LD   A,8
N_2   PUSH AF
      LD   A,(DE)
      XOR  (HL)
      LD   B,8
N_1   RRA
      JR   NC,NO
      INC  C
NO    DJNZ N_1
      INC  DE
      INC  H
      POP  AF
      DEC  A
      JR   NZ,N_2
      LD   HL,NUP+1
      INC  (HL)
RAZL  LD   A,0
      POP  HL
      CP   C
      JR   C,N_3
NUP   LD   A,0
      DEC  A
      LD   (NUM+1),A
      LD   A,C
N_3   POP  BC
      LD   (RAZL+1),A
      DJNZ N_4
NUM   LD   A,0
      ADD  A,32
      POP  DE
      LD   (DE),A
      INC  DE
      POP  BC
      INC  L
      DEC  BC
      LD   A,B
      OR   C
      JR   NZ,LOOP
      RET

   В программе есть  некоторые  интересные
приемчики.
   Например, если у вас в прогах есть  та-
кие строки:
      LD    (МЕТКА),A
      ...
      LD    A,(МЕТКА)
      ...
METKA DEFB 0,
то их можно заменить на:
      LD    (METKA+1),A
      ...
METKA LD    A,0
   Т.е. хранить переменные в тексте  самой
программы.
   Сравнение происходит с помощью XOR'ива-
ния байтов и подсчета включенных битов.Ес-
ли биты одинаковы (1-1 или 0-0), то  после
XOR'ки получаются 0, а если разные, то  1.
Т.к. нам нужны  различия, то  подсчитываем
нули командой JR NC,S.
   В этой программе блоком  является  одно
знакоместо,и сравнение происходит со стан-
дартным SPECTRUM'овским  FONT'ом, располо-
женным в ПЗУ.
   Это лишь пример,серьезную программу на-
до  делать  более  универсально: различные
размеры блока, подгружаемый FONT и т.п.

              ...О СТРЕЛКАХ.

   А точнее  о стрелочных  интерфейсах. Во
всех виденных  мною "интеллектуальных" ин-
терфейсах (таких, что если вы долго давите
джойстик в одном направлении, то  скорость
курсора - стрелки  увеличивается) скорость
увеличивается  в одном  направлении, и  ее
сброс на начальную  происходит  при  любом
движении джойстика.
   Я предлагаю  другой  алгоритм. Скорость
изменяется для четырех направлений отдель-
но. Если пользователь не давит в каком-ли-
бо направлении, то скорость в этом направ-
лении сбрасывается на начальное значение.
   Вот листинг:

      ORG  30000
      ENT
      LD   DE,#8080  ;Начальные
START HALT           ;координаты
      LD   HL,TABL
      IN   A,(#1F)   ;Опросили джойстик
      BIT  0,A       ;Вправо ?
      PUSH AF
      LD   A,#3C
      LD   (LOOP),A
      LD   A,#51
      LD   (SBROS),A
      LD   A,#57
      LD   (REG),A
      CALL NZ,MOVE   ;Да - двигаемся
      POP  AF
      CALL Z,SBR     ;Нет - сброс
      BIT  1,A       ;Влево ?
      PUSH AF
      LD   A,#3D
      LD   (LOOP),A
      CALL NZ,MOVE
      POP  AF
      CALL Z,SBR
      BIT  2,A       ;Вниз ?
      PUSH AF
      LD   A,#5F
      LD   (REG),A
      LD   A,#59
      LD   (SBROS),A
      CALL NZ,MOVE
      POP  AF
      CALL Z,SBR
      BIT  3,A       ;Вверх ?
      PUSH AF
      LD   A,#3C
      LD   (LOOP),A
      CALL NZ,MOVE
      POP  AF
      CALL Z,SBR
      BIT  4,A       ;Огонь - выход
      RET  NZ
      LD   C,D       ;Рисуем точку с
      LD   B,E       ;помощью программы
      PUSH DE        ;ПЗУ по адресу ┐
      CALL #22E5     ; <────────────┘
      POP  DE
      JR   START
;
MOVE  LD   A,(REG)   ;Подпрограмма
      CP   #57       ;перемещения
      LD   A,E
      JR   NZ,NEXT
      LD   A,D
NEXT  LD   C,(HL)
      INC  HL
      LD   B,(HL)
LOOM  CP   C
      JR   Z,SBROS
LOOP  INC  A         ;или  DEC  A
      DJNZ LOOM
REG   LD   D,A       ;или  LD  E,A
      INC  HL
      DEC  (HL)
      JR   NZ,L_1
      LD   (HL),24   ;Время закончи-
      DEC  HL        ;лось - увеличиваем
      INC  (HL)      ;скорость
      INC  HL
L_1   INC  HL
      RET
;
SBROS LD   D,C       ;или  LD  E,C
      JR   CONT
SBR   INC  HL        ;Сброс скорости и
      LD   (HL),1    ;времени на началь-
      INC  HL        ;ные значения.
      LD   (HL),24
      INC  HL
      RET
;
TABL  DEFB 255,1,24  ;Первое - MAX/MIN
      DEFB   0,1,24  ;Второе - скорость
      DEFB   0,1,24  ;Третье - время
      DEFB 175,1,24

   Для упрощения вместо стрелки  использу-
ется точка. Для  того, чтобы  бегала стре-
лочка, вместо CALL #22E5  поставьте  вызов
своей процедуры вывода стрелки.
  Чтобы точка бегала быстрее,можете умень-
шать значение времени, но не в  таблице, а
в строках LD (HL),24 в конце процедур MOVE
и SBROS. Также можно участить вызов проце-
дуры (в этой программе-один раз в прерыва-
ние или 50 раз в секунду).

          ...О МНОГОЗАДАЧНОСТИ.

   Как вы знаете, процессоры Intel способ-
ны  выполнять  несколько программ одновре-
менно. На  самом  деле они, конечно же, не
работают  все  сразу. Операционная система
запускает маленький кусочек одной програм-
мы, потом кусочек другой, третьей. И поль-
зователям  кажется, что  все  они работают
одновременно.
   Мне пришла в голову (бредовая ?) идея -
попробовать создать такую систему на SPEC-
CY. На первой же минуте обдумывания встала
проблема:КАК ПРЕРЫВАТЬ ПРОЦЕССОР ПОСЛЕ НЕ-
КОТОРОГО ВРЕМЕНИ? На РС  все  просто: есть
специальные прерывания.Так бы и канула эта
идея в лету, если бы не вторая  моя  идея:
IM 2. Но оно уже задействовано  под  опрос
клавиатуры, музоны и т.д.
   Что поделаешь, программы под такую сис-
тему придется писать  особые. Но  это, как
говорится, если  прижмет (сильно надо  бу-
дет), то сделают. Причем,сама система тра-
тит около 1% процессорного времени. А  вы-
зов музонов и др. осуществляется как и без
системы, т.е. 50 раз в секунду.
   Итак, идея:

    * Для каждой  программы создается лич-
       ный стек.
    * Подключается  первый, и  запускается
       первая программа.
  ┌>* Когда приходит  прерывание, запуска-
     ется система, которая сохраняет все
     регистры процессора в стеке  выпол-
     няемой  программы.  Она  запоминает
     значение стека в специальной табли-
     це. Подключается стек для следующей
     задачи, с него берутся значения ре-
     гистров и адрес запуска(или продол-
     жения, если это не запуск).
  │ * Запускается вторая программа.
  └─┘

   Вот листинг :

      ORG  30000
      ENT
DEMO  DI
      LD   HL,KOL+1
      LD   (HL),3
      LD   HL,PROG2
      LD   (29022),HL
      LD   A,#7F
      LD   I,A
      LD   HL,INT
      LD   (#7FFF),HL
      IM   2
      EI
;
PROG1 LD   A,#87
      LD   (#5800),A
      LD   A,#7F
      IN   A,(#FE)
      AND  #1F
      XOR  #1F
      JR   Z,PROG1
      DI
      LD   A,63
      LD   I,A
      IM   1
      EI
      RET
;
PROG2 LD   A,#78
      LD   (#581F),A
      JR   PROG2
;
NUMB  DEFB 0
TABL1 DEFB 0,1,0
TABL2 DEFW 0,29000
;
INT   PUSH AF
      LD   A,R
      PUSH AF
      PUSH DE
      PUSH BC
      PUSH HL
      PUSH IX
      PUSH IY
      EX   AF,AF'
      PUSH AF
      EXX
      PUSH DE
      PUSH BC
      PUSH HL
      LD   A,(NUMB)
      LD   E,A
      LD   D,0
      LD   HL,TABL1
      ADD  HL,DE
      LD   A,(HL)
      ADD  A,A
      LD   E,A
      LD   HL,TABL2
      ADD  HL,DE
      LD   A,L
      LD   (KK+2),A
      LD   A,H
      LD   (KK+3),A
KK    LD   (#FFFF),SP
;Здесь можно поставить вызовы ваших
;программ обработки прерываний
;типа     CALL  MYINT
      LD   A,(NUMB)
      INC  A
KOL   CP   3
      JR   NZ,OBHOD
      LD   A,0
OBHOD LD   (NUMB),A
      LD   HL,TABL1
      LD   E,A
      ADD  HL,DE
      LD   A,(HL)
      ADD  A,A
      LD   E,A
      LD   HL,TABL2
      ADD  HL,DE
      LD   A,L
      LD   (LL+2),A
      LD   A,H
      LD   (LL+3),A
LL    LD   SP,(#FFFF)
      POP  HL
      POP  BC
      POP  DE
      EXX
      POP  AF
      AX   AF,AF'
      POP  IY
      POP  IX
      POP  HL
      POP  BC
      POP  DE
      POP  AF
      SUB  7
      LD   R,A
      POP  AF
      EI
      RET

   Часть DEMO - демонстация. Сама  система
начинается с NUMB.
   Как ей пользоваться ?
 1.Определяетесь,сколько программ вам нуж-
    но использовать.
 2.По адресу KOL+1 заносите это число :
      LD   HL,KOL+1
      LD   (HL),N
 3.Для каждой выделяете место для стека.
 4.По адресу STACK+22 каждой программы за-
    носите адрес ее запуска.
 5.Составляете таблицу вызова задач.
    Например :

      TABL1 DEFB 0
            DEFB 1
            DEFB 0
            DEFB 2
            DEFB 0
    Где 0,1,2 - номера программ (соответс-
    твенно 1-ая, 2-ая  и  3-я). При  такой
    таблице 1-ой задаче отводится 3/5*100=
    =60% времени. 2-ой и 3-ей -по 1/5*100=
    =20% времени.
 6.В TABL2 заносите адреса стеков задач :
      TABL2 DEFW STACK0
            DEFW STACK1
            DEFW STACK2
 7.Устанавливаете в регистре SP адрес сте-
    ка первой задачи :
      LD   SP,STACK0
 8.Переустанавливаете прерывания :
      DI
      LD   A,#NN
      LD   I,A
      LD   HL,INT
      LD   (#NNFF),HL
      IM   2
      EI
 9.Запускаете первую программу :
      JP   PROG0
   Примечание :
  Если предусматривается выход из задач по
RET, то поместите по адресу  STACK+24 каж-
дого стека адрес программы выхода. Это мо-
жет быть процедура отключения одной задачи
от системы (замена в TABL1 номера этой за-
дачи на номер другой), или процедура выхо-
да из системы :
      DI
      LD   SP,стандартное значение
      LD   A,63
      LD   I,A
      IM   1
      EI
      RET
   В демонстрационной программе одна зада-
ча рисует мигающий квадрат в левом верхнем
углу экрана и опрашивает клавиатуру.Другая
только рисует квадрат в правом верхнем уг-
лу экрана. При нажатии на пробел  происхо-
дит выход.
   Если вы хотите использовать музоны, оп-
рашивать  клавиатуру или наращивать какие-
-либо счетчики, поставьте CALL'ы в указан-
ом месте.
   Ограничения на задачи:
1.Не портить память, занятую другими зада-
   чами.
2.Не изменять регистр I.
3.Перед  использованием расширенной памяти
   запрещать  прерывания. Разрешать только
   тогда,  когда  установлена  стандартная
   конфигурация.
4.Не запрещать надолго прерывания.
   Ограничение '3' можно снять,если в сис-
теме  организовать  проверку конфигурации,
запоминания  ее  на  стеке  и последующего
восстановления.

       ...ОБ ЭЛЕКТРОННЫХ ЖУРНАЛАХ.

   Мне, как  обычному  пользователю, хоте-
лось бы дать пару  замечаний для изготови-
телей электронных журналов.
   1.Если вы придумали какой-нибудь крутой
трюк и засунули его в заставку журнала, то
опишите его  в  журнале, или  ассемблерный
текст в приложение, чтобы другие тоже мог-
ли им воспользоваться.
   2.Расширьте меню SAVE. Например, если в
тексте  есть  картинка, то  добавить пункт
SAVE SCREEN, если  есть  ассемблерный лис-
тинг, то дать  возможность  выгрузить  его
сразу, а  не  вырезать из отгруженной ста-
тьи.
   3.Дайте возможность отгружать музоны, с
проигрывателем или без него.
   Вот пока и вся критика.

              ...О РЕКЛАМЕ.

   С радостью  буду переписываться со все-
ми, кто любит и работает со SPECCY.
   У вас есть какие-либо вопросы  по прог-
раммированию? Пишите. Если смогу, то отве-
чу.
   Вам  нужен  кодер? Если вам понравились
мои разработки (смотри выше), пишите.
   И еще: кто поможет достать книгу П. Фе-
дина "ПОЛНОЕ ОПИСАНИЕ И ПОЛНЫЙ ДИЗАССЕМБ-
ЛЕР TR-DOS 5.04(5.03)". Можно и на диске.

                ...О СЕБЕ.

   Мне 16 лет. Увлекаюсь программированием
на SPECTRUME, который  у  меня  уже 6 лет.
Сейчас  у  меня  SCORPION. В  совершенстве
знаю бейсик, паскаль. Довольно  хорошо ра-
ботаю и на ассемблере.

              ...О ПРОЩАНИИ.

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

   ┌─────────────────────────────────┐
    612831  Кировская обл.,                   Верхнекамский р-н,                пос. Рудничный,                   ул. Орджоникидзе,                 д. 33, кв. 48.            КИСЕЛЕВУ АЛЕКСАНДРУ ПЕТРОВИЧУ    └─────────────────────────────────┘
------------------------------------------



Other articles:


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

Similar articles:
Report - a report of Hsc St.Pete Computer Festival Chaos Constructions 2oo1.
Programming - Displays 64 characters per line.

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