Info Guide #11
05 июля 2015

Системки - Оберон и ассемблер: Сопряжение с ассемблером (часть 2).

     Оберон и ассемблер
         Сопряжение с ассемблером

           Передача параметров

   Передача  параметров в регистрах в SDCC
не реализована,хотя Филипп Краузе и обещал
над этим подумать.Параметры функциям пере─
даются в стеке,верхним хранится адрес воз─
врата.Есть несколько способов получить па─
раметры, и вам необходимо выбрать наиболее
приемлемый. Если  параметр(ы) занимает(ют)
1 или 2 байта,то неплохим будет такой код:

  POP  HL; Адрес возврата
  POP  BC; Однобайтовый параметр ─ в C,
  PUSH BC; а если двухбайтовый, то в BC
  PUSH HL; Если в процедуре HL не
           ; портится, то можно заменить
           ; PUSH HL:RET на JP (HL)

Или же так (такты и байты считайте сами):

  LD   HL,#2
  ADD  HL,SP
  LD   C,(HL); 1-й байт параметра(ов)
  INC  HL
  LD   B,(HL); 2-й байт параметра(ов)

Если глубоко в теле подпрограммы требуется
получение параметров в произвольном поряд─
ке, то, возможно, более  оптимальным будет
адресовать параметры черезIX:

  PUSH IX
  LD   IX,#0
  ADD  IX,SP
  LD   C,4(IX); 1-й байт параметра(ов)
  LD   B,5(IX); 2-й байт параметра(ов)
  ...
  POP  IX

Функция не должна извлекать свои параметры
из стека совсем, ─ в модели вызова по умо─
лчанию  компилятор сам извлекает параметры
после  возвращения  из функции (что в ряде
случаев  помогает ему оптимизировать код).
Также функция не должна разрушать содержи─
мое  регистраIX, через который SDCC рабо─
тает с локальными переменными.
   Результат функций в зависимости от раз─
мера  возвращается в регистреL, в паре HL
или вDE:HL.

        Эффективный вид Z80-кода,
       подходящий для портирования

  Коснёмся такого интересного вопроса, как
портирование  Спектрум-игр на другие плат─
формы. Не секрет, что код на ассемблере не
слишком нагляден, но зато слишком объёмен.
И для прояснения его логики часто приходи─
тся очень подробно разбирать огромные кус─
ки кода, пытаясь понять и описать, что они
делают. Результаты такой кропотливой рабо─
ты  не грех задокументировать, переписывая
на более высокоуровневый язык, и здесь нам
может  помочь  XDev, который предоставляет
язык достаточно простой,чтобы быть развёр─
нутым на других платформах,но и достаточно
современный концептуально, ибо,несмотря на
свой почти 30-летний возраст,прекрасно ло─
жится практически на все современные аппа─
ратные и программные платформы,что я демо─
нстрировал примерами мидлетов наОбероне
(http://zx.oberon2.ru/forum/
viewtopic.php?f=27&t=38 )
 и даже некоторыми подвижками в разработке
для Android
(http://zx.oberon2.ru/forum/
viewtopic.php?f=87&t=244 ).
   А вот, например,Си, насколько  мне из─
вестно, нельзя  транслировать  в  байт-код
Dalvik и  в Java .class'ы, ибо  Си  имеет 
слишком много опасных возможностей, от ко─
торых в Java-машинах постарались избавить─
ся  на уровне байт-кода. То же самое можно
сказать  о браузерных  приложениях.Оберон
же прекрасно ложится даже на микроконтрол─
леры
(http://www.youtube.com/
watch?v=zlnj6FCY1tY ),
 не говоря уж оJVM и .NET
(http://gpcp.codeplex.com ).

   К сожалению,формат журнальной статьи не
позволяет развёрнуто описать процессы миг─
рации Z80-кода на другие платформы,но если
вам  интересно, как могут выглядеть интер─
фейсы библиотек и прикладной код, трансли─
руемый в различные (очень различные!) тар─
геты, то смотрите среду XDev (и её подсис─
темы для разработки  под разные платформы)
и среду Monkey X(http://monkey-x.ru), ко─
торая также предлагает трансляцию с едино─
го языка  под  различные  таргеты, что при
всех  недостатках реализации (ей далеко до
универсальности, но  всё  нужно развивать)
экономит время и ресурсы, которые в проти─
вном случае тратились бы на изучение деся─
тков (быстроменяющихся) языков, платформ и
их API.

   Ещё хотелось бы отметить,что я не видел
ни  одного удовлетворительного решения для
одномоментной  разработки для Спека и дру─
гих платформ. Вы можете возразить, что ни─
кого не интересует скрещивание Спека с ПЦ.
Я  же  могу  возразить  в ответ ─ а почему
одинаковая  программа или игра должна быть
написана по-разному для разных платформ? И
особенно  на разных языках, которых сейчас
как собак нерезаных.Устаю удивляться,когда
просто  читаю  новые  названия  языков. Не
кроется  ли  здесь проблема, которой вы не
заметили?

   Так  почему же я не считаюСи таким хо─
рошим средством для одномоментной разрабо─
тки. Во-первых, см. выше о том, какСи ло─
жится на современные платформы, а, вернее,
уже  не ложится. Во-вторых, посмотрите не─
предвзятым взглядом на исходники любой иг─
рушки для Спектрума, написанной наСи[ну,
не считая игр  на движке Churrera -Ред.].
Вы  не  обращали  ранее внимания на обилие
вставок на асме? Так вот,я вас уверяю: это
приговор. Хотя  и  приятно, что не целиком
всё на асме.Вобщем,не видел ни одного сре─
дства разработки, при помощи которого уда─
лось  бы хотя бы частично автоматизировать
процесс  вытаскивания игры из рамок спект─
румных ограничений. Нужно всё переписывать
заново. XDev тоже не является таким средс─
твом,ноОберон как язык при всей жёсткости
его  каркаса  и обилии ограничений ─ в об─
щем-то  хорошая основа для мультитаргетной
разработки, как  мне кажется. Но предстоит
изучение  его возможностей в этом плане и,
разумеется,их совершенствование. Важно по─
нимать, что я не предлагаю панацею, просто
обозначаю  проблему и призываю искать пути
её решения, если вам это интересно.

   Мы  мигрируем  от Z80-асма кСи, но, не
найдя в нём достаточной опоры для приклад─
ного  высокоуровневого  программирования ─
безопасного, наглядного средства для прог─
рамм со сложной структурой и мета-програм─
мирования (скриптования)
(http://forum.oberoncore.ru/
viewtopic.php?f=6&t=5267 ),
оставаясь в рамках компилируемого кода, мы
движемся дальше,к Оберону, но оставляем за
собой возможность юзать для низкого уровня
и асм, иСи, и Java, если понадобится (по─
следнее не для ZX,конечно,а для Java-based
платформ). Вот  поэтому  я вижу  языкСи в
применении к другим платформам в роли асма
Z80  для Спека. Хорошо для низкого уровня,
но начинает нервировать, когда идёт работа
со сложной прикладной логикой.
   С учётом того, что к коду на Z80 хорошо
бы приложить удобный и однозначно соответ─
ствующий  логике  асмовского  код на языке
высокого уровня, а главное ─ компилируемый
и исполняемый  (а в идеале ─ ещё  и кросс─
платформенный!), оставляя за бортом упоми─
нание  о множестве проблем совместимости и
различий по библиотекам, интерфейсам и ещё
много  чего, просто покажу, как может выг─
лядеть код,реализующий игру для Спектрума/
Z80  и других платформ одномоментно, вовсе
не утверждая, кстати, что XDev ─ идеальная
среда  для  этих применений (в этот момент
асмеры кричат "маздай" и бьются в парокси─
змах  ЯВУ-ненавистничества  в применении к
Спектруму).
   Итак,вот процедура опроса клавиатуры из
игры  "Дурак" от CopperFeet, портированная
наОберон  с Laser Basic'а, а потом допол─
ненная альтернативной реализацией на ассе─
мблере:

MODULE Durak;
IMPORT M := Asm, B := Basic, Cfg;

TYPE KeyCode = CHAR; VAR time: INTEGER;

(* Scan keys & return a control code: *) 
PROCEDURE GetKey (): KeyCode;
BEGIN
  IF Cfg.Oberon THEN

     (* ~ 2 min 50 sec to play music: *)
    DEC(time, 9); B.PAUSE(9);
     (* <Y>, <U>, <I>, <O>, <P>: *)
    IF BITS(B.PORTIN(0DFFEH))*BITS(1FH)
      # BITS(1FH) THEN RETURN 2X END;
     (* <Q>, <W>, <E>, <R>, <T>: *)
    IF BITS(B.PORTIN(0FBFEH))*BITS(1FH)
      # BITS(1FH) THEN RETURN 1X END;
     (* <A>, <S>, <D>, <F>, <G>:  *)
    IF BITS(B.PORTIN(0FDFEH))*BITS(1FH)
      # BITS(1FH) THEN RETURN 3X END;
     (* <H>, <J>, <K>, <L>, <Enter>: *)
    IF BITS(B.PORTIN(0BFFEH))*BITS(1FH)
      # BITS(1FH) THEN RETURN 4X END;
     (* <B>, <N>, <M>, <SS>, <Space>: *)
    IF BITS(B.PORTIN( 7FFEH))*BITS(1FH)
      # BITS(1FH) THEN RETURN 5X END;

  ELSE

   (* DEC(time, 9): *)
  M.Code("LD   HL, (_Durak_time)      ");
  M.Code("LD   DE, #0-9               ");
  M.Code("ADD  HL, DE                 ");
  M.Code("LD   (_Durak_time), HL      ");
   (* B.PAUSE(9): *)
  M.Code("LD   HL, #9                 ");
  M.Code("PUSH HL                     ");
  M.Code("CALL _Basic_PAUSE_DI_stdcall");
   (* <Y>, <U>, <I>, <O>, <P>: *)
  M.Code("LD   BC, #0xDFFE            ");
  M.Code("IN   A, (C)                 ");
  M.Code("CPL                         ");
  M.Code("AND  #0x1F                  ");
  M.Code("LD   L, #2                  ");
  M.Code("RET  Z                      ");
   (* <Q>, <W>, <E>, <R>, <T>: *)
  M.Code("DEC  L                      ");
  M.Code("LD   BC, #0xFBFE            ");
  M.Code("IN   A, (C)                 ");
  M.Code("CPL                         ");
  M.Code("AND  #0x1F                  ");
  M.Code("RET  Z                      ");
   (* <A>, <S>, <D>, <F>, <G>:  *)
  M.Code("LD   BC,#0xFDFE             ");
  M.Code("IN   A, (C)                 ");
  M.Code("CPL                         ");
  M.Code("AND  #0x1F                  ");
  M.Code("LD   L, #3                  ");
  M.Code("RET  Z                      ");
   (* <H>, <J>, <K>, <L>, <Enter>: *)
  M.Code("INC  L                      ");
  M.Code("LD   BC, #0xBFFE            ");
  M.Code("IN   A, (C)                 ");
  M.Code("CPL                         ");
  M.Code("AND  #0x1F                  ");
  M.Code("RET  Z                      ");
   (* <B>, <N>, <M>, <SS>, <Space>: *)
  M.Code("INC  L                      ");
  M.Code("LD   BC, #0x7FFE            ");
  M.Code("IN   A, (C)                 ");
  M.Code("CPL                         ");
  M.Code("AND  #0x1F                  ");
  M.Code("RET  Z                      ");
  END;

  RETURN 0X
END GetKey;

END Durak.

   Что  любопытно, асмовский код, конечно,
компактнее,но если сжать это дело Hrum'ом,
то в результате сжатая обероновская реали─
зация по размеру меньше, чем сжатая асмов─
ская. Что позволяет  сделать смелый вывод:
при  достаточном количестве памяти и быст─
родействии в случае загрузки машинного ко─
да в уже  сжатом виде (и при разумной ско─
рости  распаковки) остаётся экономить лишь
адресное пространство,которое в таком слу─
чае  и является основным ресурсом для эко─
номии  и самым  весомым аргументом за асм-
реализацию  в случае  его недостаточности,
тогда  как  для  некоторых  проблем важнее
иметь не столько экономию адресного прост─
ранства, сколько  бОльшую простоту  и гиб─
кость разработки (макетирование,прототипи─
рование, средства отладки  и т.д.). [Впро─
чем,мы можем использовать интерпретируемый 
пи-код  для экономии адресного пространст─ 
ва, потеряв при этом в скорости -Ред.]

        Возможности Оберон-языков,
          отсутствующие в ZXDev

   Есть  ряд возможностейОберона, которые
вряд  ли  будут когда-либо реализованы для
разработки  под процессор Z80. Это динами─
ческая  модульность (загрузка-выгрузка мо─
дулей "на лету"),автоматическое управление
памятью  (сборка  мусора; но  пользоваться
динамической  памятью всё-таки можно, явно
освобождая её с помощьюPlatform.DISPOSE),
возможности ядра по мета-программированию,
обработке  исключений,  моментальной  (по─
смертной) отладке и т.д. Как вы понимаете,
скорости и памяти (особенно адресного про─
странства) Z80  явно недостаточно, чтобы в
полной  мере почувствовать прелесть разра─
ботки на Оберон-языках.




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

Похожие статьи:
Железо - Turbo Z-80 , сигнал INT для "Пентагон 128".
PROFI CLUB - О файловых оболочках: Copy K v4.31, HOP COMMANDER v1.05, DOS NAVIGATOR v1.0.
GAMER - О новинках в мире игр: Войны Эмбера, Винни Пух, ZX-STAG MD, THE LAST BATTLE: SUPER BRAIN.

В этот день...   16 ноября