;**************************************************************
;**       SP_FORTH       20.07.1992 - 31.07.1992     v1.0    **
;**************************************************************
Краткие описания слов (процедур), входящих в базовый словарь
СП-Форта (файл SP_FORTH.COM) - взятые из исходного текста ком-
ментарии. Расширения СП-Форта здесь не комментируются, т.к. вам
доступны их исходные тексты в SP_FORTH.DAT и в файлах "... .F"

 SPAN   (-> A)  переменная для результата "EXPECT"

  HLD   (-> A)  переменная - позиция последней литеры,
                перенесенной в буфер "PAD" по "HOLD"

 BASE   (-> A)  переменная - текущее основание системы
                счисления при вводе-выводе чисел (2..201)

;==============================================================
;=    Слова уровня машинной реализации                        =
;==============================================================

  !     (W, A ->)       заслать значение W по адресу A

  *     (N1, N2 -> N3)  произведение чисел N1 и N2

  */    (N1, N2, N3 -> N4) частное от деления N1*N2 на N3

 */MOD  (N1, N2, N3 -> N4, N5) остаток N4 и частное N5

  +     (W1, W2 -> W3)    сумма чисел W1 и W2

  +!    (W, A ->)        увеличить значение по адресу A на W

  -     (W1, W2 -> W3)   вычесть W2 из W1

  /     (N1, N2 -> N3)   частное от деления N1 на N2

 /MOD   (N1, N2 -> N2, N4) остаток N3 и частное N4
                           от деления N1 на N2

  0<    (N -> F)      F - истина, если N отрицательно

  0=    (W -> F)      F - истина, если W=0

  0>    (N -> F)      F - истина, если N положительно

  1+    (W1 -> W2)    увеличить W1 на 1

  1-    (W1 -> W2)    уменьшить W1 на 1

  XOR   (W1, W2 -> W3)  поразрядное "исключающее ИЛИ"

  2+    (W1 -> W2)   увеличить W1 на 2

  2-    (W1 -> W2)   уменьшить W1 на 2

  2/    (W1 -> W2)   арифметический сдвиг вправо на 1

  <     (N1, N2 -> F)  F не нуль, если N1<N2

  =     (W1, W2 -> F)  F не нуль, если W1=W2

  >     (N1, N2 -> F)  F не нуль, если N1>N2

  >R    (W ->)         перенести W на стек возвратов

  DUP   (W -> W, W)    продублировать верхнее значение

 ?DUP   (W -> W, W)    продублировать W, если это не нуль

  @     (A -> W)       дать значение по адресу A

  ABS   (N1 -> N2)    абсолютная величина

  AND   (W1, W2 -> W3)  поразрядное логическое "И"

  C!    (C, A ->)      заслать байт C по адресу A

  C@    (A -> C)      дать байт по адресу A

 CMOVE  (A1, A2, U ->) переслать U байтов от A1 в A2

 CMOVE> (A1, A2, U ->)   переслать U байтов от A1 в A2,
                         начиная с младших адресов

 COUNT  (T -> A, N)    дать адрес первой литеры A и число
                       литер N строки со счетчиком T

  D+    (WD1, WD2 -> WD3)  сумма двойных чисел WD1 и WD2

  D<    (D1, D2 -> F)     F - истина, если D1<D2

 DEPTH  (-> +N)    количество значений на стеке до +N

DNEGATE (D1 -> D2)  результат вычитания D1 из нуля

 DROP   (W ->)     убрать со стека верхнее значение

EXECUTE (CFA ->)   исполнить слово по CFA его статьи

 EXIT   (->)     закончить исполнение текущего определения

 FILL   (A, U, C ->)  заслать C в U байтов по адресу A

  I     (-> W)   текущее значение счетчика цикла "DO"

  J     (-> W)   текущее значение W счетчика второго
                 обьемлющего цикла "DO"

  MAX   (N1, N2 -> N3)  большее из чисел N1 и N2

  MIN   (N1, N2 -> N3)  меньшее из чисел N1 и N2

  MOD   (N1, N2 -> N3)  остаток от деления N1 на N2

 NEGATE (W1 -> W2)   результат вычитания W1 из нуля

  NOT   (W1 -> W2)  поразрядное инвертирование

  OR    (W1, W2 -> W3)  поразрядное логическое "ИЛИ"

  OVER  (W1, W2 -> W1, W2, W1)  продублировать второе сверху

  PICK  (WN,...,W0,+N -> WN,...,W0,WN) продублировать N-е
                                       сверху значение

  R>    (-> W)  перенести значение со стека возвратов

  R@    (-> W)  скопировать вершину стека возвратов

  ROLL  (WN,WN-1,...,W0,+N->WN-1,...,W0,WN)
        циклически переставить N верхних значений

  ROT   (W1, W2, W3 -> W2, W3, W1)  переставить три
        верхних значения по часовой стрелке

  SWAP  (W1, W2 -> W2, W1)  обменять местами два верхних

  U<    (U1, U2 -> F)  F - истина, если U1<U2

  UM*   (U1, U2 -> UD)  произведение UD чисел U1 и U2

 UM/MOD (UD, U1 -> U2, U3)  остаток U2 и частное U3 от
        деления UD на U1

;==============================================================
;=       Слова уровня управления периферийными устройствами   =
;==============================================================

 BLOCK  (+N -> A)  дать адрес A буфера с блоком +N

 BUFFER (+N -> A)   приписать блоку +N буфер

 UPDATE (->)    отметить текущий блок как измененный

 SAVE-BUFFERS (->) записать на диск все исправленные блоки

 FLUSH  (->)    записать блоки на диск и очистить пул

  KEY   (-> C)  ввести литеру с терминала
                ( используется функция 8 int 21h )

 EXPECT (A, +N ->) ввести с терминала +N литер по адресу A;
 в переменную SPAN заслать фактическое число введенных литер
 ( используется функция 1 int 21h )

 EMIT   (C ->)  вывести на терминал литеру с кодом C
                ( везде используется функция 2 int 21h )

  CR    (->)    вывести на терминал перевод строки

 SPACE  (->)    напечатать на терминале пробел

 SPACES (+N ->) напечатать на терминале +N пробелов

 TYPE   (A, +N ->) напечатать на терминале +N литер от адреса A

;==============================================================
;=       Слова уровня интерпретатора и компилятора            =
;==============================================================

 HERE   (-> A)  дать адрес текущей вершины словаря

  PAD   (-> A)  дать адрес буфера PAD ( он равен HERE + 80 )

 HOLD   (C ->)  перенести литеру C на вершину буфера PAD

  <#    (->)    начать форматное преобразование

  #     (D1 -> D2)  делением D1 на значение "BASE" выделить
                      1 цифру с конца и добавить ее в буфер
                      PAD, оставив частное D2

 BRANCH (->)    продолжить интерпретацию от значения
                следующего скомпилированного адреса

?BRANCH (F ->)  если F ложь, то как BRANCH, иначе продолжить
                  интерпретацию от адреса, следующего за
                  адресом перехода

 2DUP   (WD -> WD, WD) продублировать двойное значение

  D0=   (WD -> F) F - истина, если WD нуль

 2DROP  (WD ->) снять верхнее двойное значение

  LIT   (-> W)  поместить на стек следующий код

  0     (-> 0)  константа нуль (значение "ложь")

; до этого момента ВСЕ слова имели тип "CODE" ( машинный код )
; дальше такие слова будут помечаться значком [C]

  #S    (D1 -> 0, 0) выделять цифры D1 по слову "#" до
                     получения нуля

 DABS   (D1 -> D2) абсолютная величина двойного числа

  #>    (D -> A, +N) закончить форматное преобразование;
          дать адрес A начала литер и их число +N

 SIGN   (N ->)  добавить в форматную строку знак минус,
                если число отрицательно

 #TIB   (-> A)  переменная - число литер в буфере "TIB"

 -TRAILING (A, N1 -> A, N2) отсечь концевые пробелы         [C]

  D.    (D ->)  напечатать D на терминале и дать пробел

  S>D   (N -> D) расширить N до числа двойной длины         [C]

  .     (N ->)  напечатать N на терминале и дать пробел

  U.    (U ->)  напечатать U на терминале как число без знака

 DECIMAL (->) перейти в десятичную систему                  [C]

  BLK   (-> A)  переменная - номер входного блока - экрана

  >IN   (-> A)  переменная - смещение очередной литеры во
                входном текстовом буфере или экране

 >BODY  (CFA -> PFA) от поля кода к полю параметров         [C]
 ( возвращает ноль, если первый байт CFA <> E8h, т.е. если
   это не высокоуровневое слово, а слово типа CODE и
   PFA <> CFA+3 ) - отличие от стандарта

  TIB   (-> A)  адрес входного текстового буфера для ввода
                с терминала ( константа )

  1+!   (A ->)  увеличить на 1 значение по адресу A         [C]

  DPL   (-> A)  переменная - позиция последней точки в
                последнем введенном числе от конца

 DIGIT  (C, N1 -> N2,TF / FF) N2 - значение литеры C как    [C]
                 цифры в системе счисления по основанию N1

 CONVERT (WD1, A1 -> WD2, A2) преобразовать WD1 и литеры
    от A1+1 в WD2 и A2 - адрес первой не цифры

 VOC-LINK (-> A) переменная - адрес поля связи последнего
                 созданного по "VOCABULARY" списка слов

 CURRENT (-> A) переменная - список для добавления слов

 CONTEXT (-> A) переменная - список, с которого начинается
                поиск вводимых слов

 LATEST (-> NFA) дать NFA последней созданной статьи
                 (последней в текущем списке CURRENT)

 IMMEDIATE (->) дать признак "IMMEDIATE" последней
                созданной словарной статье

 DEFINITIONS (->) установить список "CURRENT" на "CONTEXT"

 W-LINK (-> A)  переменная - адрес LFA (т.е.адрес ссылки)
         указывающей на найденое при последнем поиске слово
         W-LINK @ @ даст NFA найденного слова

 ?WORD  (A1, A2 -> A3, F) производится поиск в списке A2   [C]
   статьи по имени, заданному строкой со счетчиком,
   расположенной по адресу A1. Если статья найдена, то на
   стек помещается адрес ее поля имени A3 и значение
   "истина", иначе A3=A1 и "ложь". A2 - адрес машинного
   слова, содержащего адрес поля имени статьи, с которой
   начинается поиск в этом списке.

 -1     (-> -1) положить на стек "true"                    [C]

 N?BRANCH (F ->) условный переход по значению "истина"     [C]

 NAME>  (NFA -> CFA) перейти от поля имени к полю кода     [C]

 FIND   (T -> A, N) искать слово T в текущем контексте.
   Если N=0, то A=T и слово не найдено; иначе A=CFA
   найденной статьи, N=1 для слов "IMMEDIATE" и N=-1
   для остальных.

 ENCLOSE (C, A1, U1 -> A2, U2, A3, TRUE)                   [C]
         (C, A1, U1 -> FALSE)
         выделение слова по ограничителям C в строке,
         начиная с адреса A1 длиной U1; A2 - адрес первого
         не разделителя, U2 - длина слова, A3 - адрес байта,
         следующего за первым разделителем после слова.

  BL    (-> 32) код пробела

  INB   (-> A)  переменная, содержащая адрес буфера
                входного потока (если BLK@=0, то INB@=TIB)

 WORD   (C -> T) ввести слово до стоп-литеры C

 WARNING (-> A) переменная, которая служит для управления
                выдачей предупреждений о повторном
                определении слов. Предупреждения выдаются,
                если эта переменная <>0.

 PRESS  (W1, W2 -> W2) снимает со стека второе сверху значение [C]

  ID.   (NFA ->) напечатать имя слова

 (.")   (->)    процедура, компилируемая ."

  CFL   (-> 3)  константа - длина поля кода словарной статьи

 ALLOT  (W ->)  сместить вершину словаря на W байтов           [C]

  ,     (W ->)  скомпилировать W на вершину словаря            [C]

  ",    (A ->)  компиляция строки со счетчиком, заданной
                адресом A с отведением памяти по ALLOT

 +WORD  (A1, A2 ->) добавление заголовка статьи с именем,
         заданным строкой со счетчиком A1, к списку, заданному
         переменной A2. Формирует только поля имени и связи с
         отведением памяти по ALLOT. В машинном слове по
         адресу A2 расположен адрес поля имени статьи, с
         которой начинается поиск в этом списке.

  !CF   (A1, A2 ->) сформировать по адресу A2 машинную
                    команду CALL A1  ( call near с кодом 0E8h )

 (!CODE) (A ->) сформировать поле кода текущего определения
                с исполнением A, т.е. сформировать
                машинную команду CALL A  (call near)

 CREATE (->)    создать начало статьи (до PFA) для следующего
                слова

  C,    (C ->)  скомпилировать байт на вершину словаря       [C]

  1     (-> 1)  константа 1                                  [C]

  0!    (A ->)  записать 0 по адресу A                       [C]

 CONSOLE (->)   установить стандартный ввод-вывод
                с консоли оператора
 ( реализация:   : console  blk 0! ; т.е. перенаправлением
   ввода-вывода на уровне DOS данная процедура не занимается;
   она только указывает на ввод через буфер TIB, а не через
   блочные буферы )

 (DOES>) (->)   компилируется словом DOES>. В поле кода
          последнего в списке компиляции определения
          формируется машинная команда CALL вызова
          следующей за (DOES>) программы, после чего
          происходит выход из слова, в котором встретилось
          слово (DOES>)

 VOCABULARY (->) определить следующее слово как список над
                 текущим значением CURRENT

 FORTH  (->)    установить CONTEXT на начальный список

 FORTH-83 (->)  стандартный контекст Форт-системы
                ( реализация:   : forth-83 forth decimal ; )

 STATE  (-> A)  переменная с состоянием текстового
        интерпретатора: "истина" - компиляция

  (     (->)    комментарий - пропустить следующий текст
                до закрывающей круглой скобки

 C/L    (-> N)  константа - максимальный размер строки,
        которую можно ввести с клавиатуры
         dw      80

 QUERY  (->)    ввести с терминала литеры в буфер TIB,
                число введенных литер заслать в #TIB

  <>    (W1, W2 -> F) F не нуль, если W1<>W2              [C]

 COMPILE (->)   производится компиляция в словарь         [C]
                содержимого машинного слова, следующего
                за COMPILE

 DLIT   (-> D)  помещает на стек содержимое следующих за  [C]
                ним двух машинных слов как число
                двойной длины

 LITERAL (W ->) /компиляция/
           (->) /исполнение/ скомпилировать W как литерал

 DLITERAL (DW ->) компилирует слово DLIT и вслед за ним
                  число двойной длины, взятое со стека

  R0    (-> A)  переменная, содержащая адрес дна стека
                возвратов

 RP@    (-> A)  помещает на стек значение указателя стека [C]
                возвратов

 RP!    (A ->)  значение указателя стека возвратов        [C]
                становится равным A

  S0    (-> A)  переменная, содержащая адрес дна стека данных

 SP@    (-> A)  адрес текущей вершины стека данных        [C]

 SP!    (A ->)  установить указатель вершины стека на A   [C]

  U/    (W1, W2 -> W3) беззнаковое деление W1 на W2       [C]

 U/MOD  (W1, W2 -> W3, W4) остаток W3 и частное W4 от     [C]
                           беззнакового деления W1 на W2

 ?KEY   (-> F)  F - истина, если на клавиатуре нажата клавиша
                ( через функцию 6 int 21h )               [C]

 PORT@  (N ->W)  получить данные из порта N               [C]

 PORT!  (W, N ->) записать W в порт N                     [C]

 S@     (SEG, OFFS -> W) получить слово по адресу SEG:OFFS [C]

 S!     (W, SEG, OFFS ->) записать слово W по адресу SEG:OFFS [C]

 REGS   (-> A)  адрес массива регистров для слова INTR
         dw      0      ;ax
         dw      0      ;bx
         dw      0      ;cx
         dw      0      ;dx
         dw      0      ;di
         dw      0      ;si
         dw      0      ;ds
         dw      0      ;es
         dw      0      ;flags

 INTR   (N ->)  выполнить прерывание int N с регистрами из REGS [C]

 FRESH  (->)    освежить регистры в REGS (DS, ES, FLAGS)  [C]

 EXECPRG (A1, A2 -> F) выполнить программу: A1 - адрес маршрута [C]
          ASCIIZ , A2 - адрес блока параметров. F - истина,
          если программа выполнена
          Выполнение через функцию 4B00h. Предварительно должна
          быть освобождена память при помощи слов FREEMEM или
          SETBLK ( см. описание прилагаемых экранов Форта )
          Все жизненно важные регистры Форта корректно сохраняются
          и восстанавливаются. Необходимые строки маршрутов и
          параметров и управляющие блоки готовятся словами START
          ( см. там же )

 ABORT  (->)    сбросить стек и уйти по QUIT

 (ABORT") (F ->) если F - истина, то печатается строка со
          счетчиком после (ABORT") и выполняются действия
          ABORT: если BLK не ноль, то дополнительно
          печатается строка экрана, во время интерпретации
          которого возникла ошибка.

  '     (-> CFA) дать CFA для следующего слова

 RDROP  (->)    снять число со стека возвратов          [C]

 NUMBER (A -> D) преобразовать строку со счетчиком по
         адресу A в число двойной длины со знаком
         в установленной системе счисления

 ?STACK (->)    выдать ошибку "исчерпание стека", если он
                более чем пуст

 INTERPRET (->) интерпретировать входной поток
         head    'INTERPRET',9,interpret

  [     (->)    переключить текстовый интерпретатор в режим
                исполнения

  ]     (->)    переключить текстовый интерпретатор в режим
                компиляции

 QUIT   (->)    сбросить стек возвратов, перейти в режим
                исполнения и продолжить интерпретацию

 "ПУСТОЕ СЛОВО" (->) закончить интерпретацию входного потока

 B/BUF  (-> 1024) число байтов в блочном буфере             [C]

 TITLE  (->)  вывод на экран Copyright:
             'SP-FORTH v1.0 (c) 1992 Stroyprogress Ltd.'
              загрузка экрана (блока) номер 0 ("autoexec")
              и выполнение частичной инициализации

 FINIT  (->)  начальная инициализация Форт-системы
              Сюда передается управление сразу после старта
              SP_FORTH.COM ( предварительно только устанавливается
              стек )   : finit title decimal quit ;

 LOAD   (+N ->) интерпретировать экран с номером +N

 FENCE  (-> A)  переменная - граница защиты от FORGET
                ( последнее защищаемое слово ".("  )

 FORGET (->)    удалить словарную статью следующего слова и
                всех слов, определенных после него
                Корректно удаляются слова из всех списков

 TOGGLE (A, C ->) операция XOR C с байтом по адресу A      [C]

 SMUDGE (->)    инвертировать флаг SMUDGE в последней
                созданной словарной статье

 :      (->)    начать определение слова через двоеточие

 ;      (->)    закончить определение через двоеточие

 VARIABLE (->)  определить следующее слово как переменную
                с начальным значением нуль

 CONSTANT (W ->) определить следуещее слово как константу
                 со значением W

 CAPSLOCK (-> A) изменение CAPS на противоположное
                 Не управляет светодиодом на клавиатуре.
                 В исходном состоянии не делается различий
                 между строчными и прописными латинскими буквами,
                 все они воспринимаются как прописные. После
                 CAPSLOCK они идут под своими настоящими кодами.
                 В этом случае, например, слова Example и EXAMPLE
                 будут считаться разными словами Форта.

  ."    (->)     при исполнении напечатать следующие литеры
                 до кавычки исключительно

 >MARK  (-> A)   компилирует значение 0 и оставляет на стеке
                 его адрес

 >RESOLVE (A ->) запоминает текущий адрес вершины словаря
                 по адресу A

 <MARK  (-> A)   оставляет на стеке текущий адрес вершины
                 словаря (=HERE)

 <RESOLVE (A ->) компилирует адрес, находящийся на стеке

 (DO)   (W1, W2 ->) вход в цикл со счетчиком от W2 до W1  [C]

 (LOOP) (->)    значение на стеке возвратов ++1           [C]

 (+LOOP) (N ->) значение на стеке возвратов увеличивается [C]
         на N и затем сравнивается со значением, находящимся
         под ним на стеке возвратов (N2) ; если меньше N2-1,
         то следующая петля цикла

 LEAVE  (->)    немедленный выход из цикла DO...LOOP      [C]

  DO    (-> A1, A2) компилирует слово (DO) и оставляет адреса
        для реализации структур управления

 LOOP   (A1, A2 ->) компилирует слово (LOOP) и вслед за ним
         значение A2 (адрес начала тела цикла), по адресу
         A1 заносит адрес выхода из цикла
         head    'LOOP',84h,iloop

 +LOOP  (A1, A2 ->) компилирует слово (+LOOP) ...

  IF    (-> A)  начало ветвления IF; компилирует слово
         ?BRANCH, резервирует 2 байта под адрес перехода
         и оставляет на стеке их адрес

 THEN   (A ->)  конец ветвления IF; разрешает ссылку по
                адресу A

 ELSE   (A1 -> A2) начало ветви ELSE ветвления IF;
         разрешает ссылку назад (записывает HERE+4 в два
         байта A1 после IF), компилирует слово BRANCH и
         за ним по адресу A2 резервирует два байта под
         адрес перехода

 BEGIN  (-> A)  начало цикла BEGIN

 UNTIL  (A ->)  конец цикла BEGIN...UNTIL

 WHILE  (-> A)  ветвление WHILE в цикле BEGIN...WHILE...REPEAT

 REPEAT (A1, A2 ->) конец цикла BEGIN...WHILE...REPEAT

 DOES>  (->)    начало "исполнения" в определяющем слове

 ABORT" (->)    компилирует слово (ABORT") и текст до
                закрывающих кавычек исключительно

 [']    (->)    скомпилировать CFA следующего слова как
                числовой литерал

 [COMPILE] (->) скомпилировать следующее слово независимо
                от его признака IMMEDIATE

  ;S    (->)    прекращение интерпретации экрана

  .(    (->)    напечатать следующие литеры до закрывающей
                скобки исключительно


         ORG     0fe00h-1028
         Блочный буфер

         ORG     0fe00h
         Буфер TIB для вводимого текста

