(*~\Глагол\приложкемяLink\МПГ2009 (компилируется, но НЕ раб.?)\~~~~~~~~~~~~~~~*)
(**)                                                     ОТДЕЛ Код;
(****************************************************************************** 
 * НАЗНАЧЕНИЕ: вывод машинных кодов
 ******************************************************************************)

ИСПОЛЬЗУЕТ 
  ОБХОД,
        (*  \Глагол\              *)
  Асм     ИЗ "..\..\Отделы\Заграница\",
        (*  \Глагол\              *)
  оЦепи   ИЗ "..\..\Отделы\Иное\",
(* Пустой ИЗ "..\..\Отделы\Иное\",*)
ЧэргаСлеД ИЗ "..\..\Отделы\Иное\",
(*оЗнака  ИЗ "..\..\Отделы\Иное\",*)
(*
  Набор   ИЗ "..\..\Отделы\Иное\",
  Цепь    ИЗ "..\..\Отделы\Иное\",
  Знак    ИЗ "..\..\Отделы\Иное\",
*)
        (*  \Глагол\              *)
  Текст   ИЗ "..\..\Отделы\Обмен\",

  Ядро,
  Настрой,
  Данные,
  Разбор,
  Рег,
  Обмен,
  Ошибка;

(******* номера используемых кодов действий (НКД) *****************************)
ПОСТ   
                                       (* Простая Загрузка и Сохранение (ПЗС) *)
  LDR-  = 1;
  STR-  = 2;
  LDRB- = 3;
  STRB- = 4;
  LDRp- = 5; (* вычисление адреса после доступа *)
  STRp- = 6; (* вычисление адреса после доступа *)
  LDRBp-= 7; (* вычисление адреса после доступа *)
  STRBp-= 8; (* вычисление адреса после доступа *)
  LDRHp-= 9; (* вычисление адреса после доступа *)
  STRHp-=10; (* вычисление адреса после доступа *)
                                         (* Узкая Загрузка и Сохранение (УЗС) *)
  LDRSH-=11;
  LDRSB-=12;
  LDRH- =13; 
  STRH- =14;
                                     (* Составная Загрузка и Сохранение (СЗС) *)
  LDMIA-=15;
  STMDB-=16;
                        (* Обработка Данных (ОД) *)
                        (* у всех, кроме MOV, д.б. ВКЛ S-разряд *)
  MOV-  =17;
  MVN-  =18;
  TST-  =19;
  CMP-  =20; 
  ADD-  =21;
  SUB-  =22; 
  AND-  =23; 
  EOR-  =24; 
  ORR-  =25;
  RSB-  =26;
  BIC-  =27;
                        (* умножение *)
  MUL-  =28;
  MLA-  =29;

(******* коды условий (КУ) ****************************************************)
  EQ-= 0; (*    =    *)
  NE-= 1; (*    #    *)
  CS-= 2; (*    >=   *)
  CC-= 3; (*    <    *)
  MI-= 4; (*         *)
  PL-= 5; (*         *)
  VS-= 6; (*         *)
  VC-= 7; (*         *)
  HI-= 8; (*    >    *) 
  LS-= 9; (*    <=   *)
  GE-=10; (* зн >=   *)
  LT-=11; (* зн <    *)
  GT-=12; (* зн >    *)
  LE-=13; (* зн <=   *)
  AL-=14; (* всегда  *)
  NV-=15; (* никогда *) 

(******* способы сдвигов (СС) *************************************************)
  LSL-= 1; (* логический влево            *)
  LSR-= 2; (* логический вправо           *)
  ASR-= 3; (* арифметический вправо       *)
  ROR-= 4; (* вращение вправо             *)
  RRX-= 5; (* расширенное вращение вправо *)

(******* особые метки *********************************************************)
  мПеременные = 0;
  мУказания   = 1;
  мКонец      = 2;
  мЦепочки    = 3;
  мОписатель- = 4;                     (* общедоступная метка вида ПОСТоянная *)
  мОбычная    = 5;

(******* цепочки знаков отдела ************************************************)
  ЗнаковЦепочкам =10000; (* выделяется памяти под все цепочки отдела *)

ПЕР
        цепочки:ЦЕПЬ[ЗнаковЦепочкам]; (*        память        *)
  знаковЦепочек:ЦЕЛ;                  (* занято памяти        *)

(******* скопления постоянных *************************************************)
ПОСТ
  СловПост =1024; (* размер скопления *)
                                               (* разновидности постоянных:   *)
  пЧисло   =0; (* числовая постоянная    *)
  пЦепьАдр =1; (* адрес цепочки знаков   *)
  пОбщАдр  =2; (* адрес общей переменной *)
  пМетка   =3; (* адрес метки            *)
  пВид     =4; (* адрес описателя вида   *)

ВИД
(*------------------------------------ ВидПост -------------------------------*)
(*Пост  = НАБОР*)
  нПост = НАБОР

    родп :ЦЕЛ;  (* пЧисло, ...               *)
    знач :ЦЕЛ;  (* число, смещ. цепочки      *)
    метка:ЦЕЛ;  (* метка у постоянной        *)
    пон:Данные.ДкПонятию; (* общая переменная *)
    вид:Данные.ДкВиду     (* описываемый вид       *)
  КОН;

ПЕР
  разрешёнСбросПост:ЦЕЛ;     (* если >=0, то сброс разрешён  *)

  пост:РЯД СловПост ИЗ нПост;(* текущее скопление постоянных *)

  словПост:ЦЕЛ;              (* счётчик постоянных в <пост>  *)
  удалениеПост:ЦЕЛ;          (* смещение от постоянной до самой удалённой LDR *)


(*------ описатели видов для наборов отдела ----------------------------------*)

(*------------------------------------ ВидНабор -----------------------------*)
ВИД
(*ВидНабор = ДОСТУП К НАБОР(Набор.Вид)*)
  ДкНабору = ДОСТУП К нНабор;
                      нНабор = НАБОР(ЧэргаСлеД.нПустой)
    вид:Данные.ДкВиду
                               КОН;

(*---
              набор-список из доступов к набору
  ---*)
ПЕР
  наборы:ЧэргаСлеД.нСписок;

  следОВ:ЦЕЛ; (* следующий номер описателя вида для вида набор *)

(*----------------------------------------------------------------------------*)
ПЕР
  СК-:ЦЕЛ;      (* счётчик выработанных команд *)
  будетКУ+:ЦЕЛ; (* КУ для следующей команды (после сбрасывается в AL)   *)
  будетS+:КЛЮЧ; (* S признак для следующей команды (после сбрасывается) *)
  будетВ+:КЛЮЧ; (* восклицательный знак для следующей команды простой (узкой)
                 * загрузки и сохранения (после сбрасывается) *)
  текМетка:ЦЕЛ; (* номер выданной метки *)


(*-оооооооооооооо- опережающие определения/заготовки задач -ооооооооооооооооо-*)

ЗАДАЧА ^ПроверитьЗаполнениеПост;
ЗАДАЧА ^СбросПост-;
ЗАДАЧА ^ПЗС1-(нкд,рн,ро,смещ:ЦЕЛ);
ЗАДАЧА ^ОД1-(нкд,рн,р1,пост:ЦЕЛ); 

(* Далее задачи для вывода текста на машинном языке. Для преобразования
 * нескольких аргументов используется особое описание. Описание содержит
 * обычные знаки, которые просто переписываются в текст и следующие описатели
 * аргументов (после знака '%'):
 *  н - НКД
 *  р - регистр
 *  м - числовая метка
 *  у - код условия
 *  д - десятичное целое
 *  с - сдвиг
 *  ш - шестнадцатеричное целое
 *  з - знак
 *  о - отступ
 *  ^ - новая строка *)


(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Вывод5(описание-:ЦЕПЬ;
              а0,а1,а2,а3,а4:ЦЕЛ);
(* Вывод в текст 5-и аргументов *)
ПОСТ
  (* признаки последующей обработки *)
  прСледАрг =0;
  прСледЗнак=1;
ПЕР
  дло:ЦЕЛ;      (* длина <описание>                      *)
  позо:ЦЕЛ;     (* позиции текущего знака в <описание>   *)
  зно:ЗНАК;     (* знак, прочитанный из <описание>       *)
  номарг:ЦЕЛ;   (* номер текущего аргумента              *)
  арг:ЦЕЛ;      (* текущий аргумент                      *)
  признаки:МНОЖ;(* множ. признаков последующей обработки *)
  оарг:ЦЕПЬ[100]; (* описание для тек. аргумента         *)
  тку:ЦЕПЬ[3];  (* текстовое представление КУ            *)

 (*................................................подЗАДАЧА...*)
  ЗАДАЧА СледЗнак;
                                     (* чтение следующего знака из <описание> *)
  УКАЗ
    ЕСЛИ позо < дло ТО
      зно:=описание[позо];
      УВЕЛИЧИТЬ(позо)
    ИНАЧЕ
      зно:=0X
    КОН
  КОН СледЗнак;

 (*................................................подЗАДАЧА...*)
  ЗАДАЧА КУвТКУ(ку:ЦЕЛ);
                    (* преобразование кода условия <ку> в текстовый вид <тку> *)
  УКАЗ
    ВЫБРАТЬ ку ИЗ
    | EQ: тку:="EQ" | NE: тку:="NE" | CS: тку:="CS" | CC: тку:="CC"
    | MI: тку:="MI" | PL: тку:="PL" | VS: тку:="VS" | VC: тку:="VC"
    | HI: тку:="HI" | LS: тку:="LS" | GE: тку:="GE" | LT: тку:="LT"
    | GT: тку:="GT" | LE: тку:="LE" | AL: тку:="" 
    КОН
  КОН КУвТКУ;

УКАЗ
  дло:=ДЛИНА(описание);
  позо:=0;
  номарг:=0;
  арг:=а0;
  КОЛЬЦО
    СледЗнак;
    ПОКА зно = '%' ВЫП
      СледЗнак;
      признаки:={прСледАрг,прСледЗнак};
      ВЫБРАТЬ зно ИЗ
      | 'м':
        оарг:="|%d|"
      | 'р':
        ВЫБРАТЬ арг ИЗ
        | Рег.PC: оарг:="PC"
        | Рег.LR: оарг:="LR"
        | Рег.SP: оарг:="SP"
        | Рег.FP: оарг:="FP"
        ИНАЧЕ
          оарг:="R%d"
        КОН
      | 'с':
        ВЫБРАТЬ арг ИЗ
        | LSL: оарг:="LSL"
        | LSR: оарг:="LSR"
        | ASR: оарг:="ASR"
        | ROR: оарг:="ROR"
        | RRX: оарг:="RRX"
        КОН
      | 'д':
        оарг:="%d"
      | 'ш':
        оарг:="0x%x"
      | 'з':
        оарг:="0x%.4x"
      | 'н':  
        ВЫБРАТЬ арг ИЗ
        | AND:  оарг:="AND"
        | EOR:  оарг:="EOR"
        | SUB:  оарг:="SUB"
        | RSB:  оарг:="RSB"
        | ADD:  оарг:="ADD"
        | TST:  оарг:="TST"
        | CMP:  оарг:="CMP"
        | ORR:  оарг:="ORR"
        | MOV:  оарг:="MOV"
        | BIC:  оарг:="BIC"
        | MVN:  оарг:="MVN"
        | MUL:  оарг:="MUL"
        | MLA:  оарг:="MLA"
        | LDR:  оарг:="LDR"
        | STR:  оарг:="STR"
        | LDRB: оарг:="LDRB"
        | LDRH: оарг:="LDRH"
        | STRB: оарг:="STRB"
        | STRH: оарг:="STRH"
        | LDRSH:оарг:="LDRSH"
        | LDRSB:оарг:="LDRSB"
        | LDMIA:оарг:="LDMIA"
        | STMDB:оарг:="STMDB"
        КОН;
        КУвТКУ(будетКУ);

        оЦепи.ДобавитьВКонец(оарг,тку);

        будетКУ:=AL;
        ЕСЛИ будетS ТО

          оЦепи.ДобавитьВКонец(оарг,"S");

          будетS:=ОТКЛ
        КОН
      | 'у':
        КУвТКУ(арг);
        СПИСАТЬ(тку,оарг)
      | 'о':
        Обмен.КодЗнак(09X);
        признаки:={прСледЗнак}
      ИНАЧЕ
        ЕСЛИ зно = '%' ТО
          Обмен.КодЗнак(зно);
          признаки:={прСледЗнак}
        ИНАЧЕ
          признаки:={}
        КОН
      КОН;
      ЕСЛИ прСледЗнак В признаки ТО
        СледЗнак
      КОН;
      ЕСЛИ прСледАрг В признаки ТО
        Обмен.КодЦел(оарг,арг);
        ЕСЛИ номарг < 4 ТО
          УВЕЛИЧИТЬ(номарг)
        КОН;
        ВЫБРАТЬ номарг ИЗ
        | 1: арг:=а1
        | 2: арг:=а2
        | 3: арг:=а3
        | 4: арг:=а4
        КОН
      КОН
    КОН;
    ЕСЛИ зно = 0X ТО ВЫХОД КОН;
    Обмен.КодЗнакЦепи(зно)
  КОН
КОН Вывод5;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Вывод4(описание-:ЦЕПЬ;
              а0,а1,а2,а3:ЦЕЛ);
УКАЗ Вывод5(описание,а0,а1,а2,а3,0) КОН Вывод4;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Вывод3(описание-:ЦЕПЬ;
              а0,а1,а2 :ЦЕЛ);
УКАЗ Вывод5(описание,а0,а1,а2,0,0) КОН Вывод3;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Вывод2(описание-:ЦЕПЬ; а0,а1:ЦЕЛ);
УКАЗ Вывод5(описание,а0,а1,0,0,0) КОН Вывод2;

(*----------------------------------------------------------------------------*)
ЗАДАЧА Вывод1(описание-:ЦЕПЬ; а0:ЦЕЛ);
УКАЗ Вывод5(описание,а0,0,0,0,0) КОН Вывод1;

(******************************************************************************)
ЗАДАЧА Вывод0(описание-:ЦЕПЬ);
УКАЗ Вывод5(описание,0,0,0,0,0) КОН Вывод0;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВыводПолногоИмени(пон:Данные.ДкПонятию);

 (*................................................подЗАДАЧА...*)
  ЗАДАЧА ИмяОбласти(область:Данные.ДкОбласти);
  УКАЗ
    ЕСЛИ область = ПУСТО ТО
      ВОЗВРАТ
    КОН;
    ИмяОбласти(область.окробл);
    Вывод0(область.имя);
    Вывод0(".")
  КОН ИмяОбласти;

УКАЗ
  Вывод0("|");
  ИмяОбласти(пон.обл);
  Вывод0(пон.имя);
  Вывод0("|")
КОН ВыводПолногоИмени;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВыводИмениОВ(вид:Данные.ДкВиду);
УКАЗ
  Вывод0("|.");
  Вывод0(Данные.вхотд[вид.нвхотд].имя);
  Вывод1(".ВИД.%д|",вид.ов)
КОН ВыводИмениОВ;


(*====== обслуживание меток и переходов ======================================*)


(*----------------------------------------------------------------------------*)
ЗАДАЧА УвеличитьСК;
(* увеличить <СК> и пересчитать <удалениеПост> *)
УКАЗ
  УВЕЛИЧИТЬ(СК);
  ЕСЛИ удалениеПост >= 0 ТО
    УВЕЛИЧИТЬ(удалениеПост)
  КОН
КОН УвеличитьСК;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПолучитьМетку-():ЦЕЛ;
(* создаёт новую метку *)
УКАЗ
  УВЕЛИЧИТЬ(текМетка);
  ВОЗВРАТ текМетка
КОН ПолучитьМетку;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПоставитьМетку-(метка:ЦЕЛ);
(* вывод числовой метки *)
УКАЗ
  Вывод1("%м^",метка)
КОН ПоставитьМетку;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПоставитьАдресМетки-(метка:ЦЕЛ);
(* вывод постоянной с адресом метки *)
УКАЗ
  Вывод1("%оDCD%о%м^",метка)
КОН ПоставитьАдресМетки;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПоставитьАдресОВ-(вид:Данные.ДкВиду);
(* вывод постоянной с адресом ОВ вида *)
УКАЗ
  Вывод0("%оDCD%о");
  ВыводИмениОВ(вид);
  Вывод0("^")
КОН ПоставитьАдресОВ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ЗначениеМетке-(метка,значение:ЦЕЛ);
(* сопоставить числовой метке численное значение *)
УКАЗ
  Вывод2("%м%оEQU%о%д^",метка,значение)
КОН ЗначениеМетке;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПоставитьИмя-(пон:Данные.ДкПонятию);
(* вывод текстовой метки *)
УКАЗ
  ВыводПолногоИмени(пон);
  Вывод0("^")
КОН ПоставитьИмя;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПоставитьЧисло-(число:ЦЕЛ);
(* вывод постоянного числа *)
УКАЗ
  Вывод1("%оDCD%о%д^",число)
КОН ПоставитьЧисло;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПоставитьПер-(пон:Данные.ДкПонятию);
(* вывод метки для переменной *)
ПЕР
  размер:ЦЕЛ;
УКАЗ
  размер:=пон.вид.размер;
  УВЕЛИЧИТЬ(размер,(-размер) ОСТАТОК 4);
  ВыводПолногоИмени(пон);
  Вывод1("%о%% %ш^",размер)
КОН ПоставитьПер;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПереходПоКУ-(метка+,ку:ЦЕЛ); 
(* Цель:  вывод кода условного перехода "B" на метку <метка>
 * До:    <метка> - существующая метка перехода
 *        <ку>    - код условия перехода *)
УКАЗ
  ЕСЛИ ку # NV ТО
    ПроверитьЗаполнениеПост;
    Вывод2("%оB%у%о%м^",ку,метка);
    УвеличитьСК
  КОН
КОН ПереходПоКУ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПереходНа-(метка+:ЦЕЛ); 
(* Цель: вывод кода безусловного перехода "B" на метку <метка>
 * До:   <метка> - метка перехода или 0 *)
УКАЗ
  ПереходПоКУ(метка,AL)
КОН ПереходНа;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Вызов-(пон:Данные.ДкПонятию); 
(* Цель: вывод кода безусловного перехода с возвратом "BL"
 * До:   <пон> - вызываемая задача *)
УКАЗ
  ПроверитьЗаполнениеПост;
  Вывод0("%оBL%о");
  ВыводПолногоИмени(пон);
  Вывод0("^");
  УвеличитьСК
КОН Вызов;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВызовПоИмени(имя-:ЦЕПЬ); 
(* Цель: вывод кода безусловного перехода с возвратом "BL"
 * До:   <имя> - имя вызываемой задачи *)
УКАЗ
  ПроверитьЗаполнениеПост;
  Вывод0("%оBL%о");
  Вывод0(имя);
  Вывод0("^");
  УвеличитьСК
КОН ВызовПоИмени;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВызовСреды-(имя-:ЦЕПЬ);
(* Цель:  вызов задачи из СРЕДА
 * До:    <имя> - имя задачи *)
ПЕР
  полноеИмя:ЦЕПЬ[Ядро.рИмени*2+10];
УКАЗ
  полноеИмя:="|.СРЕДА.";

 оЦепи.ДобавитьВКонец(полноеИмя,имя);
 оЦепи.ДобавитьВКонец(полноеИмя,"|");

  ВызовПоИмени(полноеИмя)
КОН ВызовСреды;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВызовВнешнегоИмени-(имя-:ЦЕПЬ); 
(* Цель: вывод кода безусловного перехода с возвратом "BL" на внешнюю задачу
 * До:   <имя> - имя вызываемой задачи *)
УКАЗ
  Вывод0("%оIMPORT%о");
  Вывод0(имя);
  Вывод0("^");
  ВызовПоИмени(имя)
КОН ВызовВнешнегоИмени;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПоставитьВнешнееИмя-(имя-:ЦЕПЬ);
(* Цель: поставить внешнюю метку *)
УКАЗ
  Вывод0("%оEXPORT%о|");
  Вывод0(имя);
  Вывод0("|^|");
  Вывод0(имя);
  Вывод0("|^")
КОН ПоставитьВнешнееИмя;


(*====== обслуживание скоплений постоянных ===================================*)


(*----------------------------------------------------------------------------*)
ЗАДАЧА ПроверитьЗаполнениеПост;
(* если постоянных в <пост> уже очень много, то сбрасывает их в область кода
 * и перешагивает через них *)
ПЕР
  метка:ЦЕЛ;
УКАЗ
  ЕСЛИ разрешёнСбросПост < 0 ТО
    ВОЗВРАТ
  КОН;
  ЕСЛИ удалениеПост >= СловПост-15 ТО
    метка:=ПолучитьМетку();
    УМЕНЬШИТЬ(разрешёнСбросПост);
    ПереходНа(метка);
    СбросПост;
ПоставитьМетку(метка);
    УВЕЛИЧИТЬ(разрешёнСбросПост)
  КОН
КОН ПроверитьЗаполнениеПост;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВводПост(родп,
                знач :ЦЕЛ;
                 пон :Данные.ДкПонятию;
                 вид :Данные.ДкВиду):ЦЕЛ;
(* вносит значение <знач> в <пост> и возвращает метку этой постоянной *) 
ПЕР
  ц:ЦЕЛ;
  метка:ЦЕЛ;
УКАЗ
  (* может такая постоянная уже есть в этом скоплении ? *)
  ОТ ц:=0 ДО словПост-1 ВЫП
    ЕСЛИ (пост[ц].родп = родп) И
         ((родп = пЧисло  ) И (пост[ц].знач = знач) ИЛИ
          (родп = пЦепьАдр) И (пост[ц].знач = знач) ИЛИ
          (родп = пОбщАдр ) И (пост[ц].пон  = пон ) ИЛИ
          (родп = пМетка  ) И (пост[ц].знач = знач) ИЛИ
          (родп = пВид    ) И (пост[ц].вид  = вид )) ТО
        ВОЗВРАТ пост[ц].метка
    КОН
  КОН;
  метка:=ПолучитьМетку();
  (* заносим в скопление новую постоянную *)
  пост[словПост].родп:=родп;
  пост[словПост].метка:=метка;
  пост[словПост].знач:=знач;
  пост[словПост].пон:=пон;
  пост[словПост].вид:=вид;
  ЕСЛИ словПост > удалениеПост ТО
    удалениеПост:=словПост
  КОН;
  УВЕЛИЧИТЬ(словПост);
  ВОЗВРАТ метка
КОН ВводПост;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СбросПост-;
(* сбрасывает скопление <пост> в область кода *)
ПЕР
  ц:ЦЕЛ; (* счётчик *)
УКАЗ
  (* выдаём все постоянные в область кода *)
  ОТ ц:=0 ДО словПост-1 ВЫП
    Вывод1("%м%оDCD%о",пост[ц].метка);
    ВЫБРАТЬ пост[ц].родп ИЗ
    | пЧисло:   
        Вывод1("%ш^",пост[ц].знач)
    | пЦепьАдр: 
        (* метка начала цепочек + смещение *)
        Вывод2("%м+%ш^",мЦепочки,пост[ц].знач)
    | пОбщАдр: 
        ВыводПолногоИмени(пост[ц].пон);
        Вывод0("^")
    | пМетка:   
        Вывод1("%м^",пост[ц].знач)
    | пВид:   
        ВыводИмениОВ(пост[ц].вид);
        Вывод0("^")
    КОН;
    УВЕЛИЧИТЬ(СК)
  КОН;
  (* готовимся к новому заполнению скопления *)
  словПост:=0;
  удалениеПост:=-1
КОН СбросПост;

(*----------------------------------------------------------------------------*)
ЗАДАЧА ВычисляемаяПост(число:ЦЕЛ):КЛЮЧ;
(* пытается представить <число> в виде правого вращения
 * 8 разрядной беззнаковой постоянной, т.е. <число> = <ц8> >> (2*<вр2>)
 * возвращает ВКЛ, если такое возможно *)
ПЕР
  вр2:ЦЕЛ;
УКАЗ
  вр2:=0;
  ПОКА (вр2 < 15)
      И
       НЕ ((число >= 0) И (число <= 255))
  ВЫП
    число:=Асм.Вращение(число,-2);
    УВЕЛИЧИТЬ(вр2)
  КОН;
  ВОЗВРАТ (число >= 0) И (число <= 255)
КОН ВычисляемаяПост;

(*----------------------------------------------------------------------------*)
ЗАДАЧА LDRпоPC(р,метка:ЦЕЛ);
(* LDR в регистр <р> постоянной, расположенной рядом с PC *)
ПЕР
  будетS:КЛЮЧ;
УКАЗ
  ПРОВЕРИТЬ((р >= 0) И (р <= 15));
  (* задержим S *)
  будетS:=Код.будетS;
  Код.будетS:=ОТКЛ;
  (* смещение должно быть в байтах *)
  Вывод3("%о%н%о%р,%м^",LDR,р,метка);
  (* отпустим S *)
  Код.будетS:=будетS;
  УвеличитьСК
КОН LDRпоPC;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ЗагрузитьПост-(р,число:ЦЕЛ);
УКАЗ
  ЕСЛИ ВычисляемаяПост(число) ТО
    ОД1(MOV,р,0,число) 
  ИНАЧЕ
    LDRпоPC(р,ВводПост(пЧисло,число,ПУСТО,ПУСТО))
  КОН
КОН ЗагрузитьПост;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВводЦепочки-(пон:Данные.ДкПонятию);
(* ввод цепочки в областьи цепочек и присваивание ей адреса в области цепочек *)
ПЕР
  поз:ЦЕЛ;
УКАЗ
  пон.адр:=знаковЦепочек*Настрой.рЗнак;
                                                (* конечный 0 тоже записываем *)
  ОТ поз:=0 ДО РАЗМЕР(пон.достцепь^)-1 ВЫП
    ЕСЛИ знаковЦепочек >= ЗнаковЦепочкам ТО
      Ошибка.Отметить(Ошибка.МНОГО_ПОСТОЯННЫХ)
    КОН;
    цепочки[знаковЦепочек]:=пон.достцепь[поз];
    УВЕЛИЧИТЬ(знаковЦепочек)
  КОН
КОН ВводЦепочки;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ЗагрузитьЦепьАдр-(р,цепьАдр:ЦЕЛ);
(* вывод кода загрузки адреса цепочки в регистр <р>.
 * <цепьАдр> - адрес в области цепочек *)
УКАЗ
  LDRпоPC(р,ВводПост(пЦепьАдр,цепьАдр,ПУСТО,ПУСТО))
КОН ЗагрузитьЦепьАдр;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ЗагрузитьОбщАдр-(р:ЦЕЛ; пон:Данные.ДкПонятию);
УКАЗ
  LDRпоPC(р,ВводПост(пОбщАдр,0,пон,ПУСТО))
КОН ЗагрузитьОбщАдр;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ЗагрузитьМетку-(р,метка:ЦЕЛ);
УКАЗ
  LDRпоPC(р,ВводПост(пМетка,метка,ПУСТО,ПУСТО))
КОН ЗагрузитьМетку;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ЗагрузитьОВ-(р:ЦЕЛ; вид:Данные.ДкВиду);
УКАЗ
  LDRпоPC(р,ВводПост(пВид,0,ПУСТО,вид))
КОН ЗагрузитьОВ;

(*============================================================================*)
(* Далее:
 *   нкд - номер кода действия
 *   рн  - регистр назначения
 *   ро  - регистр основы
 *   рд  - регистр данных
 *   рс  - регистр сдвига
 *   ц8  - 8 разрядное целое число *)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ОбратныйКУ-(ку:ЦЕЛ):ЦЕЛ; 
(* меняет смысл условия из <ку> на противоположный *)
УКАЗ
  ЕСЛИ ЧЕТ(ку) ТО
    ВОЗВРАТ ку+1
  ИНАЧЕ
    ВОЗВРАТ ку-1
  КОН
КОН ОбратныйКУ;

(******************************************************************************)
ЗАДАЧА ПослеДоступа(нкд+:ЦЕЛ):КЛЮЧ; 
(* Если вычисление адреса Загрузки и Сохранения после доступа, то смена <нкд> *)
УКАЗ
  ВЫБРАТЬ нкд ИЗ
  | LDRp: нкд:=LDR
  | STRp: нкд:=STR
  | LDRBp:нкд:=LDRB
  | STRBp:нкд:=STRB
  | LDRHp:нкд:=LDRH
  | STRHp:нкд:=STRH
  ИНАЧЕ
    ВОЗВРАТ ОТКЛ
  КОН;
  ВОЗВРАТ ВКЛ
КОН ПослеДоступа;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПЗС-(нкд,рн,ро,рс,сдвиг:ЦЕЛ); 
(* Простая Загрузка и Сохранение со смещением в регистре <рс>
 * с логическим сдвигом влево на <сдвиг> *)
УКАЗ
  ПРОВЕРИТЬ((рн >= 0) И (рн <= 15) И (ро >= 0) И (ро <= 15) И (рс >= 0) И (рс <= 15));
  ПроверитьЗаполнениеПост;
  ЕСЛИ ПослеДоступа(нкд) ТО
    Вывод5("%о%н%о%р,[%р],%р,LSL ##%ш",нкд,рн,ро,рс,сдвиг)
  ИНАЧЕ
    Вывод5("%о%н%о%р,[%р,%р,LSL ##%ш]",нкд,рн,ро,рс,сдвиг);
    ЕСЛИ будетВ ТО
      Вывод0("!")
    КОН
  КОН;
  Вывод0("^");
  будетВ:=ОТКЛ;
  УвеличитьСК
КОН ПЗС;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПЗС1-(нкд,рн,ро,смещ:ЦЕЛ); 
(* Простая Загрузка и Сохранение с непосредственным смещением *)
ПЕР
  р:ЦЕЛ;
УКАЗ
  ПРОВЕРИТЬ((рн >= 0) И (рн <= 15) И (ро >= 0) И (ро <= 15));
  ПроверитьЗаполнениеПост;
  ЕСЛИ МОДУЛЬ(смещ) >= 4096 ТО
    УМЕНЬШИТЬ(разрешёнСбросПост);
    Рег.ЗанятьРОН(р);
    ЗагрузитьПост(р,смещ);
    ПЗС(нкд,рн,ро,р,0);
    Рег.ОсвободитьРОН(р);
    УВЕЛИЧИТЬ(разрешёнСбросПост)
  ИНАЧЕ
    ЕСЛИ ПослеДоступа(нкд) ТО
      Вывод4("%о%н%о%р,[%р],##%д",нкд,рн,ро,смещ)
    ИНАЧЕ
      Вывод4("%о%н%о%р,[%р,##%д]",нкд,рн,ро,смещ);
      ЕСЛИ будетВ ТО
        Вывод0("!")
      КОН
    КОН;
    Вывод0("^");
    будетВ:=ОТКЛ;
    УвеличитьСК
  КОН
КОН ПЗС1;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА УЗС-(нкд,рн,ро,рс:ЦЕЛ);
(* Узкая Загрузка и Сохранение со смещением в регистре <рс> *)
УКАЗ
  ПРОВЕРИТЬ((рн >= 0) И (рн <= 15) И (ро >= 0) И (ро <= 15) И (рс >= 0) И (рс <= 15));
  ПроверитьЗаполнениеПост;
  ЕСЛИ ПослеДоступа(нкд) ТО
    Вывод4("%о%н%о%р,[%р],%р",нкд,рн,ро,рс)
  ИНАЧЕ
    Вывод4("%о%н%о%р,[%р,%р]",нкд,рн,ро,рс);
    ЕСЛИ будетВ ТО
      Вывод0("!")
    КОН
  КОН;
  Вывод0("^");
  будетВ:=ОТКЛ;
  УвеличитьСК
КОН УЗС;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА УЗС1-(нкд,рн,ро,смещ:ЦЕЛ); 
(* Узкая Загрузка и Сохранение (полуслов) с непосредственным смещением *)
ПЕР
  р:ЦЕЛ;
УКАЗ
  ПРОВЕРИТЬ((рн >= 0) И (рн <= 15) И (ро >= 0) И (ро <= 15));
  ПроверитьЗаполнениеПост;
  ЕСЛИ МОДУЛЬ(смещ) >= 256 ТО
    УМЕНЬШИТЬ(разрешёнСбросПост);
    Рег.ЗанятьРОН(р);
    ЗагрузитьПост(р,смещ);
    УЗС(нкд,рн,ро,р);
    Рег.ОсвободитьРОН(р);
    УВЕЛИЧИТЬ(разрешёнСбросПост)
  ИНАЧЕ
    ЕСЛИ ПослеДоступа(нкд) ТО
      Вывод4("%о%н%о%р,[%р],##%д",нкд,рн,ро,смещ)
    ИНАЧЕ
      Вывод4("%о%н%о%р,[%р,##%д]",нкд,рн,ро,смещ);
      ЕСЛИ будетВ ТО
        Вывод0("!")
      КОН
    КОН;
    Вывод0("^");
    будетВ:=ОТКЛ;
    УвеличитьСК
  КОН
КОН УЗС1;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СЗС-(нкд,ро:ЦЕЛ; воскл:КЛЮЧ; реги:МНОЖ);
(* Составная Загрузка и Сохранение с записью <ро> *)
ПЕР
  р:ЦЕЛ;
  сзапятой:КЛЮЧ; 
УКАЗ
  ПРОВЕРИТЬ((ро >= 0) И (ро <= 15));
  ПроверитьЗаполнениеПост;
  сзапятой:=ОТКЛ;
  ЕСЛИ воскл ТО
    Вывод2("%о%н%о%р!,{",нкд,ро)
  ИНАЧЕ
    Вывод2("%о%н%о%р,{",нкд,ро);
  КОН;
  ОТ р:=0 ДО 15 ВЫП
    ЕСЛИ р В реги ТО
      ЕСЛИ сзапятой ТО
        Вывод0(",");
      КОН;
      Вывод1("%р",р);
      сзапятой:=ВКЛ
    КОН
  КОН;
  Вывод0("}^");
  УвеличитьСК
КОН СЗС;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВСтог-(рн:ЦЕЛ); 
(* Цель:  сохраняет регистр данных <рн> в стеке *)
УКАЗ
  будетВ:=ВКЛ;
  ПЗС1(STR,рн,Рег.SP,-4)
КОН ВСтог;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Умн-(нкд,рн,р1,р2,р3:ЦЕЛ); 
(* Умножение *)
УКАЗ
  ПроверитьЗаполнениеПост;
  ПРОВЕРИТЬ((рн >= 0) И (рн <= 15) И (р1 >= 0) И (р1 <= 15) И (р2 >= 0) И (р2 <= 15));
  ПРОВЕРИТЬ(рн # р1);
  ПРОВЕРИТЬ(НЕ (Рег.PC В {рн,р1,р2}));
  ЕСЛИ нкд = MLA ТО
    (* р3 = добавляемый регистр *)
    Вывод5("%о%н%о%р,%р,%р,%р^",нкд,рн,р1,р2,р3)
  ИНАЧЕ
    Вывод4("%о%н%о%р,%р,%р^",нкд,рн,р1,р2)
  КОН;
  УвеличитьСК
КОН Умн;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ОД-(нкд,рн,р1,р2,сс,рс:ЦЕЛ); 
(* Обработка Данных со вторым данным в регистрах *)
УКАЗ
  ПроверитьЗаполнениеПост;
  ПРОВЕРИТЬ((рн >= 0) И (рн <= 15) И (р1 >= 0) И (р1 <= 15) И (р2 >= 0) И (р2 <= 15));
  Вывод1("%о%н%о",нкд);
  ЕСЛИ (нкд # TST) И (нкд # CMP) ТО
    Вывод1("%р,",рн)
  КОН;
  ЕСЛИ (нкд # MOV) И (нкд # MVN) ТО
    Вывод1("%р,",р1)
  КОН;
  Вывод1("%р",р2);
  ЕСЛИ сс # 0 ТО
    ЕСЛИ рс > 15 ТО (* непосредственный сдвиг *)
      УМЕНЬШИТЬ(рс,16);
      Вывод2(",%с ##%д",сс,рс)
    ИНАЧЕ
      Вывод2(",%с %р",сс,рс)
    КОН
  КОН;
  Вывод0("^");
  УвеличитьСК
КОН ОД;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ОД1-(нкд,рн,р1,пост:ЦЕЛ); 
(* Обработка Данных с непосредственным вторым данным *)
ПЕР
  р:ЦЕЛ;
УКАЗ
  ПРОВЕРИТЬ((рн >= 0) И (рн <= 15) И (р1 >= 0) И (р1 <= 15));
  ЕСЛИ (нкд = ADD) И (пост < 0) ТО
    нкд:=SUB;
    пост:=-пост
  АЕСЛИ (нкд = SUB) И (пост < 0) ТО
    нкд:=ADD;
    пост:=-пост
  КОН;
  ПроверитьЗаполнениеПост;
  ЕСЛИ ВычисляемаяПост(пост) ТО
    Вывод1("%о%н%о",нкд);
    ЕСЛИ (нкд # TST) И (нкд # CMP) ТО
      Вывод1("%р,",рн)
    КОН;
    ЕСЛИ (нкд # MOV) И (нкд # MVN) ТО
      Вывод1("%р,",р1)
    КОН;
    Вывод1("##%ш^",пост);
    УвеличитьСК
  ИНАЧЕ
    УМЕНЬШИТЬ(разрешёнСбросПост);
    Рег.ЗанятьРОН(р);
    ЗагрузитьПост(р,пост);
    ОД(нкд,рн,р1,р,0,0);
    Рег.ОсвободитьРОН(р);
    УВЕЛИЧИТЬ(разрешёнСбросПост)
  КОН
КОН ОД1;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ПодготовитьОВ-(вид:Данные.ДкВиду);
(*
 * Цель:  запомнить данные для создания ОВ
 * До:    <вид> - вид набора
 *)
ПЕР 
          наборД:ДкНабору;
УКАЗ
    вид.ов:=следОВ;
  УВЕЛИЧИТЬ(следОВ);

  СОЗДАТЬ(наборД);
          наборД.вид:=вид;

  ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(наборы,наборД)
(*Набор.ВКонецСписка(наборы,набор)*)
КОН ПодготовитьОВ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПереписатьПамять-(ир,пр,рр:ЦЕЛ);
(* Цель:  переписывает данные, не проверяя размер в [рр]
 * До:    ир - регистр с адресом источника данных 
 *        пр - регистр с адресом приёмника данных
 *        рр - регистр с размером переносимых данных, [рр] > 0
 * После: [рр] = 0 *)
ПЕР
  вр:ЦЕЛ;     (* временный регистр *)
  мПовтор:ЦЕЛ; (* метка *)
УКАЗ
  Рег.ЗанятьРОН(вр);
  мПовтор:=ПолучитьМетку();
ПоставитьМетку(мПовтор);
  ПЗС1(LDRBp,вр,ир,1);
  ПЗС1(STRBp,вр,пр,1);
  будетS:=ВКЛ;
  ОД1(SUB,рр,рр,1);
  ПереходПоКУ(мПовтор,NE);
  Рег.ОсвободитьРОН(вр)
КОН ПереписатьПамять;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВнешниеПер-;
УКАЗ
КОН ВнешниеПер;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Примечание-(текст-:ЦЕПЬ);
УКАЗ 
  ЕСЛИ Настрой.клОтлДанные ТО
    Вывод0("^; ");
    Вывод0(текст);
    Вывод0("^");
  КОН
КОН Примечание;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Ловушка-(ку,ловушка:ЦЕЛ);
(* Цель:  вызов из среды задачи аварийной остановки приложения
 * До:    
 *        <ку>      - код условия срабатывания ловушки
 *        <ловушка> - номер ловушки *)
ПЕР
  р:ЦЕЛ;
  мВыход:ЦЕЛ;
УКАЗ
  мВыход:=ПолучитьМетку();
  ПереходПоКУ(мВыход,Код.ОбратныйКУ(ку));
  (* описатель отдела *)
  Рег.ЗанятьРОН(р);
  ЗагрузитьМетку(р,мОписатель);
  ВСтог(р);
  (* номер ловушки и текущей строки текста отдела в одно слово *)
  ЗагрузитьПост(р,ловушка+Разбор.начСлова.строка*Ядро.Ловушек);
  ВСтог(р);
  Рег.ОсвободитьРОН(р);
  ВызовСреды("Ловушка");
ПоставитьМетку(мВыход)
КОН Ловушка;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Начало-;
(* начало области указаний задач *)
УКАЗ
  Вывод0("^; начало области указаний задач");
  Вывод0("^%оAREA%о|.text|,CODE^");
  ПоставитьМетку(мУказания)
КОН Начало;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Открыть-();
                 (* испСреда=ВКЛ, если нужно использовать задачи отдела СРЕДА *)
ПЕР
  нвхотд:ЦЕЛ;
  пон:Данные.ДкПонятию;
УКАЗ
                                                        (* начальные значения *)
  следОВ:=1;
  ЧэргаСлеД.ОчиститьСписок(наборы);
  СК:=0;
  словПост:=0;
  знаковЦепочек:=0;
  удалениеПост:=-1;
  разрешёнСбросПост:=0;
  текМетка:=мОбычная-1;
  будетКУ:=AL;
  будетS:=ОТКЛ;
  будетВ:=ОТКЛ;
  Обмен.КодОткрыть;
  (* заголовок *)
  Вывод0("; Преобразователь Сокращенного Глагола в ARM код^");
  Вывод0("; Выпуск www.glagol.nad.ru от __.__.2009^");
  Вывод0("; ***************************************************************^");
  (* используемые переменные и задачи *)
  Вывод0("^; используемые переменные и задачи^");
  ОТ нвхотд:=0 ДО Данные.чвхотд-1 ВЫП
    пон:=Данные.вхотд[нвхотд].обл.первпон;
    ПОКА пон # ПУСТО ВЫП
      ЕСЛИ (пон.родп В {Данные.пПер,Данные.пЗадача}) ИЛИ
           (пон.родп = Данные.пВид) И (пон.вид.родв = Данные.вНабор) ТО
        Вывод0("%оIMPORT%о");
        ЕСЛИ пон.родп = Данные.пВид ТО
          ВыводИмениОВ(пон.вид)
        АЕСЛИ пон.родп = Данные.пПер ТО
          ВыводПолногоИмени(пон)
        АЕСЛИ пон.родп = Данные.пЗадача ТО
          ВыводПолногоИмени(пон)
        КОН;
        Вывод0("^")
      КОН;
      пон:=пон.след
    КОН
  КОН;
                                           (* задачи среды *)
  Вывод0("^; задачи из СРЕДА.asm^");
  Вывод0("%оIMPORT%о|.СРЕДА.Делить|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Остаток|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Цел32ВВещ32|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32ВЦел32|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32ЦелЧасть|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32Сложить|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32Вычесть|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32Умножить|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32Делить|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32Равно|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32МРавно|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32Меньше|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32Неравно|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32БРавно|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32Больше|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32Отрицание|^");
  Вывод0("%оIMPORT%о|.СРЕДА.Вещ32Модуль|^");
                                          (* начало области переменных отдела *)
  Вывод0("^; начало области переменных отдела");
  Вывод0("^%оAREA%о|.bss|,NOINIT^");
  ПоставитьМетку(мПеременные)
КОН Открыть;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ЗапускПриложения-;
ПЕР
  нвхотд:ЦЕЛ;
  имя:Ядро.Имя;
  имягз:ЦЕПЬ[Ядро.рИмени*2+10];
УКАЗ
  ОТ нвхотд:=1 ДО Данные.чвхотд-1 ВЫП
    (* полное имя главной задачи *)
    имя:=Данные.вхотд[нвхотд].имя;
    имягз:="|.";

   оЦепи.ДобавитьВКонец(имягз,имя);
   оЦепи.ДобавитьВКонец(имягз,".");
   оЦепи.ДобавитьВКонец(имягз,имя);
   оЦепи.ДобавитьВКонец(имягз,"!|^");
                                        (* вызов *)
    Вывод0("%оIMPORT%о");
    Вывод0(имягз);
    Вывод0("%оBL%о");
    Вывод0(имягз)
  КОН
КОН ЗапускПриложения;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Закрыть-;
ПЕР
  ц,поз:ЦЕЛ;
(*       звено :Набор.Звено; *)
         звеноД:ЧэргаСлеД.ДкЗвену_телоД;

    пон :Данные.ДкПонятию;
    видД:Данные.ДкВиду;

  колено:ЦЕЛ;

 (*................................................подЗАДАЧА...*)
  ЗАДАЧА ВыводООВ(вид:Данные.ДкВиду);
       (* Цель:  самовызовом записывает адреса описателей опорных видов (ООВ) *)
  УКАЗ
    ЕСЛИ вид = Данные.неопрвид ТО ВОЗВРАТ КОН;
    ЕСЛИ колено > Настрой.ВсегоРасширений ТО
      Ошибка.Отметить(Ошибка.БОЛЬШАЯ_ГЛУБИНА)
    КОН;
    ПРОВЕРИТЬ(   вид.ов # 0);

        ВыводООВ(вид.овид);
    Вывод0("%оDCD%о");
    ВыводИмениОВ(вид);
    Вывод0("^");
    УВЕЛИЧИТЬ(колено)
  КОН ВыводООВ;

УКАЗ
  ПоставитьМетку(мКонец);
                                                          (* описатель отдела *)
  Вывод0("^; описатель отдела^");
  ПоставитьМетку(мОписатель);
  Вывод1('%оDCW%о%з',ВЦЕЛ(Настрой.отдИмя[0]));
  ОТ ц:=1 ДО Ядро.рИмени-1 ВЫП
    Вывод1(',%з',ВЦЕЛ(Настрой.отдИмя[ц]))
  КОН;
  Вывод0("^");
  ПоставитьАдресМетки(мПеременные);
  ПоставитьАдресМетки(мУказания);
  ПоставитьАдресМетки(мКонец);
                                                            (* цепочки отдела *)
  Вывод1("^; цепочки отдела^%м",мЦепочки);
  ц:=0;
  КОЛЬЦО
    ОТ поз:=0 ДО 7 ВЫП
      ЕСЛИ
           ц >= знаковЦепочек
      ТО
        ВЫХОД  (* из КОЛЬЦО *)
      КОН;
      ЕСЛИ поз = 0 ТО
        Вывод1('^%оDCW%о%з',ВЦЕЛ(цепочки[ц]))
      ИНАЧЕ
        Вывод1(',%з',ВЦЕЛ(цепочки[ц]))
      КОН;
      УВЕЛИЧИТЬ(ц)
    КОН
  КОН;
  Вывод0("^");
                                         (* общедоступные переменные и задачи *)
  Вывод0("^; общедоступные переменные и задачи^");
  пон:=Данные.текОбласть.первпон;

  ПОКА пон # ПУСТО ВЫП
    ЕСЛИ
         Данные.прОбщедоступная В пон.признаки
    ТО
      ЕСЛИ
           пон.родп В {Данные.пПер,Данные.пЗадача}
      ТО
          Вывод0("%оEXPORT%о");
          ВыводПолногоИмени(пон);
        ЕСЛИ
             пон.родп = Данные.пПер
        ТО
          Вывод0("%о[DATA]")
        КОН;
          Вывод0("^")
      КОН
    КОН;
    пон:=пон.след
  КОН;
                                               (* описатели видов для наборов *)
  Вывод0("^; описатели видов для наборов^");

(*
   Обход списка с 1-го звена до N-го, т.е. пока звеноД.слеД # ПУСТО
 *)
          звеноД:=ЧэргаСлеД.Дк1муЗвену(наборы);
  ПОКА
          звеноД # ПУСТО
  ВЫП
    видД:=звеноД.телоД(ДкНабору).вид;

    ВыводИмениОВ(видД);
    Вывод0("^%оEXPORT%о");

    ВыводИмениОВ(видД);
    Вывод0("^");
    колено:=0;
        ВыводООВ(видД);
                                                   (* до конца ОВ пишем ПУСТО *)
    ПОКА
         колено < Настрой.ВсегоРасширений
    ВЫП
      ПоставитьЧисло(0);
      УВЕЛИЧИТЬ(колено)
    КОН;

          звеноД:=звеноД.слеД
  КОН;
                              (* всё *)
  Вывод0("^%оEND^");
  Обмен.КодЗакрыть
КОН Закрыть;

КОН Код.
