Глава X

@@ -1,24 +1,22 @@
-c1E
+\/d
 Г Л А В А  X.  УПРАВЛЕНИЕ РЕСУРСАМИ ПАМЯТИ  MSX-КОМПЬЮТЕРОВ
-
-
+\/d-
 
                                    Мозг, хорошо устроенный, стоит больше,
                                    чем мозг, хорошо наполненный.
-                                                           Мишель Монтень
+                                                                М.Монтень
 
 
    X.1.  К а р т а  п а м я т и  (д л я  к о м п ь ю т е р о в  MSX-1)
 
-
    Персональный MSX-компьютер имеет небольшой объем памяти  -  96 Кбайтов
 для MSX-1 и 242 Кбайта для MSX-2. Поэтому полезной для пользователя оказы-
-вается информация о распределении ресурсов памяти и сведения о наличии  и
+ваются информация о распределении ресурсов памяти и сведения о наличии  и
 объеме в ней свободных мест в любой момент времени.
    Общий объем памяти у компьютеров серии MSX-1 равен 96 Кбайтам. Здесь и
 далее мы будем рассматривать только 64 Кбайта, с которыми обычно и работа-
 ет основная масса пользователей.
-   Взгляните на приведенный ниже рис.1 ...
+   Взгляните на приведенный ниже рис.12 ...
 
    Вся память разбита на две основные части:
  ┌─────────────────────────────────────────────────────────────────────┐
@@ -50,8 +48,8 @@
 мы BIOS расположены по одним  и  тем же адресам ROM  независимо от версии
 MSX-BASIC  и осуществляют переход к другим подпрограммам,  положение кото-
 рых может быть изменено.
-   В противоположность ROM,  RAM  не сохраняет информацию  при выключении
-компьютера. Поговорим теперь о его структуре.
+   В противоположность ROM RAM не сохраняет информацию при выключении ком-
+пьютера. Сейчас мы расскажем Вам о структуре RAM.
    "Верхушка" памяти (она изображена  в  н и ж н е й  части таблицы)   за-
 нята  р а б о ч е й  о б л а с т ь ю, которая состоит из:
    α) таблицы системных переменных,
@@ -62,7 +60,7 @@
    2) таблицей переменных ("Variable Table", VT). VT содержит все перемен-
 ные, создаваемые в ходе выполнения программы;
    3) таблицей массивов ("Array Variable Table").
-   Между "верхней" и "нижней" областью памяти располагаются:
+   Между "верхней" и "нижней" областями памяти располагаются:
    α) свободная область ("Free Area");
    β) с т е к  ("Stack Area");  стек содержит всю информацию, необходимую
 для выполнения программы. Например, именно здесь хранится  адрес  тех бай-
@@ -76,7 +74,6 @@
 он задает максимальное количество  одновременно открытых файлов),  то для
 каждого файла  автоматически резервируется  267-байтное пространство  для
 осуществления обмена информацией с файловыми устройствами.
-
       &H0000 ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
              ∗▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧▧∗
              ∗▧▧▧▧▧▧▧▧▧  ROM (Интерпретатор MSX-BASIC) ▧▧▧▧▧▧▧∗
@@ -117,33 +114,30 @@
              │         Таблица ловушек ("Hooks Table")        │
       &HFFFF │                                                │
      ─ ─ ─ ─ └────────────────────────────────────────────────┘
-                                 Р и с. 1
+                                 Р и с. 12
 
    Приведенная карта памяти справедлива и для компьютеров серии MSX-2. Но
 в отличие от компьютеров серии MSX-1 с объемом ROM в 32 Кбайта и RAM в 64
 Кбайта, компьютеры серии MSX-2 имеют гораздо  больший  объем  памяти (108
-Кбайтов ROM и 134 Кбайта RAM). Спрашивается, где размещаются эта память? 
+Кбайтов ROM и 134 Кбайта RAM). Спрашивается, где размещается эта память?
           ┌────────────────────────────────────────────────────┐
           │   Оказывается, вся память ПЭВМ разбита на блоки    │
           │  объемом по 64 Кбайта, называемые  с л о т а м и ! │
           └────────────────────────────────────────────────────┘
    Однако рассмотрение этого вопроса потребует от читателя дополнительных
-знаний, и поэтому мы рассмотрим его позднее (см. раздел XI.1.9.).
+знаний, и поэтому мы рассмотрим его позднее (см. Приложение 1.8.2).
    Память разделена на ячейки  (б а й т ы), каждая из которых имеет адрес,
 закодированный  д в у м я  байтами:
-
                      А д р е с   я ч е й к и (байта)
                  ┌─────────────────┬─────────────────┐
                  │ 1 1 0 1 1 0 1 1 │ 1 0 1 1 1 1 0 1 │
                  └────────▲────────┴────────▲────────┘
                           └──  Б а й т ы  ──┘
-
    Поэтому максимально большой адрес байта равен
      256·&B11111111+&B11111111+1 = 256·&hFF+&HFF+1 = 65535+1 = 65536 ,
-а следовательно,  и обратиться можно не более, чем к 65536 ячейкам памяти
+а следовательно, и обратиться  можно не более  чем к 65536 ячейкам памяти
 (подумайте, почему производится умножение именно на 256?).
-   Говорят, что "объем непосредственно адресуемой памяти - 65536 байта".
-
+   Говорят, что "объем непосредственно адресуемой памяти - 65536 байтов".
 
            X.2.   Ф у н к ц и я  PEEK  и  о п е р а т о р  POKE
 
@@ -173,12 +167,13 @@
 тацию можно дать по контексту, однако, если должной уверенности нет, надо
 а н а л и з и р о в а т ь  не только содержимое одной ячейки, но  и содер-
 жимое ячеек, находящихся в ее "окрестности"!
-
    П р и м е р 1. 10 X=&H8000'"Заглянем" в память,начиная с адреса &H8001!
    ─────────────  20 X=X+1:Y=PEEK(X)
                   30 IF Y<32 THEN ?"│";:GOTO 20 ELSE ?CHR$(Y);" ";:GOTO20
    Наличие условия Y<32 в строке 26 связано с тем, что существуют "непеча-
 таемые" символы, имеющие код ASCII, меньший 32.
+
+
    Поговорим теперь об очень полезном операторе POKE.
    Общий вид оператора:       ┌───────────┐
                               │  POKE A,D │
@@ -193,7 +188,7 @@
 ние на то, что значение А может оказаться  о т р и ц а т е л ь н ы м!
    Если значение А не удовлетворяет ограничениям, то компьютер сообщит об
 ошибке:             "Overflow"  ("П е р е п о л н е н и е"),
-а если значение D, то      "Illegal function call"
+а если значение D, - то    "Illegal function call"
             ("Н е п р а в и л ь н ы й   в ы з о в   ф у н к ц и и").
    Вы можете использовать оператор POKE для:
    α) модификации текста Вашей программы;
@@ -203,23 +198,18 @@
    Более того, этот оператор позволяет Вам экспериментировать с "подвалом"
 компьютера (рабочей областью).  Но делайте так только в том случае,  если 
 Вы понимаете, что за этим последует!
-
    П р и м е р 2.  Сравните результаты работы двух программ:
    ─────────────    10 SCREEN 1:PRINT"A"         10 SCREEN 1:PRINT"A"
                     20 WIDTH 10                  20 POKE &HF3B0,10
 
 
-
       X.3.  Т а б л и ц а  п р о г р а м м н ы х  к о м а н д  (PIT)
 
    Таблица PIT обычно начинается по адресу &H8000.  Однако ее можно "сдви-
 нуть", изменив значение системной переменной TXTTAB  в  таблице системных
 переменных.
-
-   П р и м е р 1.  Для помещения PIT с адреса &HА000,достаточно выполнить 
+   П р и м е р 1.  Для помещения PIT с адреса &HА000 достаточно выполнить
    ─────────────   следующую программу:
-   NEW
-   Ok
    5 'Адрес &HА001,находящийся в двух ячейках с номерами,начиная с &hF676
    (слове TXTTAB (&HF676)),определяет место,с которого начнется текст про-
    граммы
@@ -229,7 +219,6 @@
    40 NEW               'Стираем данную программу!
    Напомним Вам, что адрес  &HА001  (как и любой другой!)  размещается  в
 двух байтах так:
-
                Адрес   ──▶   &HF676    &HF677  ◀──   Адрес
            младшего байта      │         │       старшего байта
                          ┌─────│─────────│────┐
@@ -238,11 +227,10 @@
              байта       │ └──────┘  └──────┘ │       байта
                          └────────────────────┘
                                Слово TXTTAB
-
    Очевидно, что в результате этих "манипуляций" размер свободной области
 уменьшится на &H2000 байтов (&HA000-&H8000=&H2000), и область, расположен-
 ная между &H8000 и началом PIT, будет защищена от "вторжения" программ на 
-MSX-BASIC, и следовательно, "б е з о п а с н а"  для программ на машинном 
+MSX-BASIC и, следовательно, "б е з о п а с н а"  для программ на машинном 
 языке.
    Ясно, что величина PIT зависит от размера текста программы.
    После выполнения данной программы нажмите кнопку сброса "RESET".
@@ -259,7 +247,6 @@
 │ нем коде (один или два байта на слово, цифру)                         │
 │    Для остального текста используется код ASCII.                      │
 └───────────────────────────────────────────────────────────────────────┘
-
    П р и м е р 2.   Введем в память следующую короткую программу:
    ─────────────                     10 B=5
                                      20 END
@@ -302,10 +289,10 @@
    Попробуйте выполнить следующее:
       POKE &H8005,&H41   '41 - шестнадцатеричный код ASCII буквы "A"
       POKE &H8007,&H17   '17 ─ внутренний код цифры "6"
+
    А теперь наберите команду LIST, затем нажмите клавишу◀─┘ и ...:
                               10 A=6
                               20 END
-
    П р и м е р 3.  Теперь Вам ясно,что "инструкции" PEEK и POKE таят в се-
    ─────────────   бе поистине безграничные возможности. По существу, они
 позволяют нам распоряжаться памятью компьютера по своему усмотрению.
@@ -322,7 +309,7 @@
                80 9
                Ok
    Таким образом, указатель следующей (с номером 20) строки располагается
-в ячейках с адресами &H8009 и &H800A, а следовательно, номер второй  стро-
+в ячейках с адресами &H8009 и &H800A, а, следовательно, номер второй стро-
 ки находится в ячейках с адресами &H800B и &H800C .
    Проверим этот факт:
    PRINT HEX$(PEEK(&H800C));" ";HEX$(PEEK(&H800B))     ┌──▶  PRINT &H14
@@ -336,7 +323,6 @@
                           Ok
    Программа действует, но строку с номером 1 нельзя ни стереть, ни испра-
 вить. Вы можете написать еще одну 1-ю строку и даже новую 20-ю строку!
-
    П р и м е р 4.   Введем в память короткую программу:
    ─────────────     10 FOR AB=-2.23227 TO 7 STEP 32.671533782376#
    Теперь "просмотрим" содержимое  PIT, используя в непосредственном режи-
@@ -389,7 +375,6 @@
 │    8020   │       0     │                 Конец строки                │
 │    8021   │       0     │               Конец программы               │
 └───────────┴─────────────┴─────────────────────────────────────────────┘
-
    Однако не пытайтесь изменять с помощью оператора POKE длину строки или
 путать указатели: результат будет  к а т a с т р о ф и ч е с к и м!
    Если Вы хотите защитить свою программу  от "постороннего взгляда"  (ко-
@@ -400,7 +385,7 @@
    Ну а если Вы нечаянно нажали RESET, - не спешите отчаиваться! Вашу про-
 грамму еще можно спасти. Это очень легко сделать, набрав ту же команду
                               POKE &H8001,1
-а затем                       auto
+а затем                       auto          .
 На экране появятся строки:    10*
                               20*             и так далее ...
    Строки с "*" - спасенные. Теперь достаточно "скомандовать": LIST и ..., 
@@ -419,6 +404,7 @@
 переменных (см. Приложение 2). Ее длина зависит от  количества  используе-
 мых переменных (скалярных и массивов) и их типов.
    Отметим, что переменные и массивы хранятся в порядке их создания.
+
    Будем говорить, что один программный объект  "располагается  в  памяти
 в ы ш е  другого", если адрес, с которого он расположен, больше.
               ┌───────────────────────────────────────────┐
@@ -442,7 +428,6 @@
 располагается значение переменной γ.
    Если переменная не существует, то выдается сообщение:
                          "Illegal function call" .
-
    П р и м е р.   Будьте бдительны!
    ───────────
    10 INPUT Z
@@ -457,16 +442,13 @@
 
        X.4.1. Х р а н е н и е  п р о с т ы х  п е р е м е н н ы х
 
-
                                        Ты славно роешь землю, старый крот!
                                        Годишься в рудокопы.
-                                                        В.Шекспир. Гамлет
-
-
+                                                        У.Шекспир. Гамлет
    Как уже неоднократно упоминалось, ц е л о е  число  кодируется  в двух
 байтах. Меньший по адресу байт называется  с т а р ш и м ,  больший по ад-
 ресу байт  -  м л а д ш и м.
-   Однако, напомним Вам, что
+   Однако напомним Вам, что
        ┌─────────────────────────────────────────────────────────┐
        │   процессор Z80 "хранит" младший байт "перед" старшим   │.
        └─────────────────────────────────────────────────────────┘
@@ -480,6 +462,8 @@
    4) младший байт значения;
    5) старший байт значения.
 
+
+
 ┌───────────┐  ┌───────────┐  ┌───────────┐  ┌───────────┐  ┌───────────┐
 │  1-й байт │  │ 2-й  байт │  │  3-й байт │  │  4-й байт │  │  5-й байт │
 └─────▲─────┘  └─────▲─────┘  └─────▲─────┘  └─────▲─────┘  └─────▲─────┘
@@ -487,7 +471,6 @@
       │          Код ASCII       Код ASCII    Младший байт   Старший байт 
    VALTYPE    первого символа второго символа   значения       значения
              имени переменной имени переменной
-
    Оказывается, что адрес четвертого байта (младшего байта значения число-
 вой переменной) возвращает как раз переменная VARPTR! Кроме того,напомним,
 что "содержимое" байта с известным адресом может быть "прочитано"функцией
@@ -495,7 +478,6 @@
    Перед тем как работать с нижеприведенным примером, во избежание расхож-
 дений в результатах не забудьте "почистить" память компьютера  оператором
 CLEAR.
-
    П р и м е р 1.      A%=356:PRINT HEX$(VARPTR(A%))
    ─────────────       8006
                        Ok
@@ -514,23 +496,19 @@
 │               │            Вы, конечно же, получите число 1.           │
 └───────────────┴────────────────────────────────────────────────────────┘
    Перепишем два последних значения в двоичной системе счисления:
-
             100 = 0110 0100              1=0000 0001
                            ²                        ²
    А теперь примем во внимание инверсию порядка байтов:
-
                        0000 0001 0110 0100  ──▶ 356
                        ────▲──── ────▲────         10
                            │         │
                            1        100
-
    И перед выполнением следующего примера не забудьте ввести в память ком-
 пьютера оператор CLEAR !
 
    П р и м е р 2.      A%=-356:PRINT HEX$(VARPTR(A%))
    ─────────────       8006
                        Ok
-
    Полученный результат - это шестнадцатеричный адрес младшего байта.
 ┌───────────────┬────────────────────────────────────────────────────────┐
 │ ? РЕЕК(&Н8003)│                   Вы должны получить 2.                │
@@ -545,26 +523,21 @@
 └───────────────┴────────────────────────────────────────────────────────┘
 
    Перепишем два последних значения в двоичной системе счисления:
-
                156 = 1001 1100            254=1111 1110
                               ²                        ²
    Принимая во внимание инверсию порядка байтов, запишем их содержимое:
-
                           1111 1110 1001 1100 
                           ────▲──── ────▲────
                               │         │
                              254       156
-
    А теперь учитывая, что двоичное число 1111111010011100 записано  в  до-
 полнительном коде, получим                               ²
-
     1111 1110 1001 1100  ──▶ 0000 0001 0110 0011 ──▶ 0000 0001 0110 0011+
                        ²                        ²
 +1 = 0000 0001 0110 0100 = 101100100 = 356. Ура!
                         ²           ²
    Приведем схему расположения информации в памяти для простой числовой
 переменной  о д и н а р н о й  и  д в о й н о й  точности:
-
             Байт, адрес которого возвращает функция VARPTR()
                                    │
                      ┌───┬───┬───┬─▼─┬───┬───┬───┬───┐
@@ -576,14 +549,11 @@
                        │     │  Знак и порядок
                        │  Идентификатор
                  Тип переменной
-
    Прежде чем проверить работу ниже приведенной командной строки,наберите
 команду CLEAR.
-
    П р и м е р 3.     AR!=22.3210E+4:PRINT HEX$(VARPTR(AR!))
    ─────────────      8006
                       Ok
-
    Если Вы прочитаете адреса с &H8006-&H3=&H8003 по &H8006+&H3=&H8009, то
 обнаружите:
         &H8003    4  VALTYPE  п е р е м е н н о й  о д и н а р н о й  точ-
@@ -599,22 +569,17 @@
          ├──────────────────┼────────────────────┼──────────┤
          │    01  000000    │        64          │      0   │
          │    01  000001    │        65          │      1   │
-         │    01  000010    │        66          │      2   │
          │        ···       │       ···          │    ···   │
        ──▶    01  000110    │        70          │      6   ◀──
          │        ···       │       ···          │    ···   │
-         │    01  111110    │       126          │     62   │
          │    01  111111    │       127          │     63   │
          │    00  111111    │        63          │    - 1   │
          │    00  111110    │        62          │    - 2   │
-         │    00  111101    │        61          │    - 3   │
          │        ···       │       ···          │    ···   │
-         │    00  000010    │         2          │    -62   │
          │    00  000001    │         1          │    -63   │
          │    00  000000    │         0          │    -64   │
          └────▲─────────────┴────────────────────┴──────────┘
               └── Бит знака мантиссы
-
    Величина порядка задается формулой:
         ┌───────────────────────────────────────────────────────┐
         │    Порядок = Двоичное значение 7 младших битов  - 64  │
@@ -634,7 +599,6 @@
     └──────────────────────────────────────────────────────────────┘
    Перед тем как выполнить предлагаемые в примере действия,наберите и вве-
 дите в память компьютера оператор CLEAR.
-
    П р и м е р 4.    AR#=-22.321054981117E-4:PRINT HEX$(VARPTR(AR#))
    ─────────────     8006
                      Ok
@@ -647,13 +611,10 @@
      &H8006  190  = &B 1011 1110 
                        ▲
                        └── Знак мантиссы отрицательный!
-
    Подсчитаем теперь величину порядка:
-
                print &B0111110-64
                -2
                Ok
-
    "Продолжим наши игры!":
      &H8007   34 =  &B 0010 0010 = 22 в двоично-десятичной системе
      &H8008   50 =  &B 0011 0010 = 32 в двоично-десятичной системе
@@ -662,13 +623,11 @@
      &H800B  152 =  &B 1001 1000 = 98 в двоично-десятичной системе
      &H800C   17 =  &B 0001 0001 = 11 в двоично-десятичной системе
      &H800D   23 =  &B 0001 0111 = 17 в двоично-десятичной системе
-
    В семи последних байтах "узнается" число 0.22321054981117.
   ┌─────────────────────────────────────────────────────────────────┐
   │    Мантисса числа двойной точности занимает 7 байтов, которые   │
   │   позволяют закодировать 14 разрядов в двоично-десятичном виде  │
   └─────────────────────────────────────────────────────────────────┘
-
    Подведем  и т о г и  всему сказанному о хранении числовых переменных.
 ┌─────────┬───────┬──────┬──────┬───────────────────────────────────────┐
 │  Т и п  │Значен.│Колич.│Номера│      Значение (система счисления)     │
@@ -692,7 +651,7 @@
 │ "Содержимое" этого     ├──────┼───────────────────────────────────────┤
 │  байта возвращает  ───▶│   0  │  Порядок и знак (знак в первом бите)  │
 │  функция VARPTR()      │      │              (двоичная)               │
-│         │       │      │      │ Величина порядка = двоичное значение  │
+│         │       │      │      │ Величина порядка = двоичному значению │
 │         │       │      │      │      семи последних битов - 64        │
 │         │       │      ├──────┼───────────────────────────────────────┤
 │         │       │      │  1÷3 │  М а н т и с с а (двоично-десятичная) │
@@ -705,7 +664,7 @@
 │ "Содержимое" этого     ├──────┼───────────────────────────────────────┤
 │  байта возвращает  ───▶│   0  │   Порядок и знак (знак в первом бите) │
 │  функция VARPTR()      │      │               (двоичная)              │
-│         │       │      │      │ Величина порядка = двоичное значение  │
+│         │       │      │      │ Величина порядка = двоичному значению │
 │         │       │      │      │       семи последних битов - 64       │
 │         │       │      ├──────┼───────────────────────────────────────┤
 │         │       │      │  1÷7 │  М а н т и с с а (двоично-десятичная) │
@@ -713,8 +672,6 @@
 
    П р и м е р 5.  Попробуйте самостоятельно в нем разобраться!
    ─────────────
-   NEW
-   Ok
    10 INPUT"Введите число";A:PRINT"Попробуем 'собрать' его из памяти"
    30 B=VARPTR(A):K$=RIGHT$("00000000"+BIN$(PEEK(B)),8)
    50 IF MID$(K$,1,1)="1" THEN Z$="-." ELSE Z$="+."
@@ -734,17 +691,14 @@
         X.4.2.  Х р а н е н и е  э л е м е н т о в  ч и с л о в ы х
                                м а с с и в о в
 
-
                                 Что имеем - не храним; потерявши - плачем.
                                                            Козьма Прутков
 
-
    Вначале мы расскажем Вам о том, как хранится  в  памяти  ц е л о ч и с-
 л е н н ы й  массив.
    Приведем схемы расположения информации в памяти  для целочисленных чис-
 ловых массивов:
    α)  о д н о м е р н ы й  массив.
-
      Байт, адрес которого возвращает функция VARPTR()──┐
      ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─▼─┬───┬───┬───┬─
      │     │     │     │     │     │ &H1 │     │     │███│███│███│███│···
@@ -756,9 +710,7 @@
        │   Идентификатор      Для одномерного  │     элемента элемента
    Тип массива                    массива   Количество
                                         элементов в массиве
-
    β)  д в у х м е р н ы й  массив.
-
               Байт, адрес которого возвращает функция VARPTR()──┐
   ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─▼─┬───┬─
   │     │     │     │     │     │ &H2 │     │     │     │     │███│███│···
@@ -769,9 +721,7 @@
     │         │    Служебная инф.  │    Количество  Количество элемента
     │   Идентификатор    Для двухмерного  столбцов    строк     (0,0)
  Тип массива                  массива
-
    γ)  для  э л е м е н т о в  целочисленных числовых массивов.
-
                     ┌─── Байт, адрес которого возвращает функция VARPTR()
                   ┌─▼─┬───┬───┬───┐
                   │███│███│···│███│
@@ -779,9 +729,7 @@
                   └───────▲───────┘
                           │
                       Значение
-
    Не забыли ли Вы набрать и ввести в память компьютера оператор CLEAR?
-
    П р и м е р 4.   DIM C5%(2):C5%(0)=32000:C5%(1)=13:C5%(2)=-4
    ─────────────    Ok
                     print HEX$(VARPTR(C5%(0))-8)
@@ -805,6 +753,7 @@
                                ²
    Теперь можно найти количество элементов в массиве:00000000 00000011 =3
                                                                       ²
+
   ? PEEK(&H800B)       0 = 00000000
   ? PEEK(&H800C)    125 = 01111101 ²
                                   ²
@@ -812,7 +761,6 @@
                                                            ²
   ? PEEK(&H800D)    13 = 00001101
   ? PEEK(&H800E)     0           ²
-
    Добрались до первого элемента массива: 00000000 00001101 = 13
                                                            ²
   ? PEEK(&H800F)     252 = 11111100
@@ -820,10 +768,11 @@
                                   ²
   Далее 11111111 11111100 ──▶00000000 00000011 +1 ──▶00000000 00000100 =4
                          ²                    ²                       ²
+
+
    Приведем  схемы  расположения  информации в памяти для нецелочисленных
 числовых массивов:
    α)  о д н о м е р н ы й  массив.
-
   Байт, адрес которого возвращает функция VARPTR() ──┐
   ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬──▼──┬───┬───┬───┬──
   │     │     │     │     │     │ &H1 │     │     │ ∗∗∗ │███│···│███│···
@@ -837,7 +786,6 @@
                              Количество элементов в массиве
 
    β)  д в у х м е р н ы й  массив.
-
               Байт, адрес которого возвращает функция VARPTR() ──┐
   ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬──▼──┬─
   │     │     │     │     │     │ &H2 │     │     │     │     │ ∗∗∗ │···
@@ -850,7 +798,6 @@
  Тип массива                 массива              Количество строк
 
    γ)  для  э л е м е н т о в  нецелочисленных числовых массивов.
-
                     ┌─── Байт, адрес которого возвращает функция VARPTR()
                   ┌─▼─┬───┬───┬───┬───┐
                   │∗∗∗│███│███│···│███│
@@ -859,21 +806,19 @@
                     ▲         │
                     │     Значение
              Знак и порядок
-
    Думаем, что теперь Вы в состоянии самостоятельно разобраться с вопроса-
 ми,  касающимися  "хранения"  в RAM многомерных (двухмерных, трехмерных и 
 т.д.) вещественных числовых массивов!
 
-                           X.5.  С т е к
 
 
+                           X.5.  С т е к
+
                                            А люди все роптали и роптали,
                                            А люди справедливости хотят:
                                            - Мы в очереди первые стояли,
                                            А те, кто сзади нас,- уже едят.
                                                                В.Высоцкий
-
-
    С т е к (от англ. "stack" - "стог", "груда")  - структура  данных  или 
 устройство памяти  для хранения наращиваемой и сокращаемой  последователь-
 ности значений,  в которой в любой момент доступен только последний  член 
@@ -898,7 +843,6 @@
              Ok
 
         Адрес значения AB% в VT
-
 Адреса байтов  │        ┌─ FF◀── для отрицательного шага
  │  ┌────┬─────▼─────┬──▼─┬────┬─────┬─────┬─────┬─────┬─────┬─────┬───┬─
  │  │&H82│ &H1B│ &H80│ &H1│&HFF│ ··· │ &HF │ &H0 │ &H7 │ &H0 │ &HA │&H0│  
@@ -951,7 +895,6 @@
                      │                 │          │
            Мантисса верхнего предела   │   Адрес конца программной строки
                             Номер строки оператора FOR
-
    Не забудьте о команде CLEAR!
 
      γ)      10 FOR AB!=2.7 TO 7 STEP-32.6715
@@ -1013,13 +956,11 @@
                ─────▲─────       ▲
                     │            └── "Вершина" стека
      Адрес конца программной строки
-
    Отметим, что для версии MSX-Disk BASIC с отключенным дисководом B  при
 нулевой длине строковой области максимальное число вложенных циклов равно
 576.
    А теперь настала очередь оператора GOSUB...
-   Тем не менее, о команде CLEAR забывать не стоит!
-
+   Тем не менее о команде CLEAR забывать не стоит!
    П р и м е р 2.    10 GOSUB 30:INPUT A
    ─────────────     20 'Просто комментарий!
                      30 'Еще один комментарий!
@@ -1036,13 +977,9 @@
            │           │              │                 └─ Вершина стека
          Код GOSUB     │     Адрес следующего оператора
                 Номер текущей строки
-
-
-   П р и м е р 3.
-   ─────────────
-   Работу этих двух программ Вы должны проверить  на ученическом дисплее.
- α)  Ok                        β)  Ok
-     10 GOSUB 30:PRINT 1:END       10 GOSUB 30:PRINT 1:END
+   П р и м е р 3.  Работу этих двух программ Вы должны проверить на учени-
+   ─────────────   ческом компьютере.
+  α) 10 GOSUB 30:PRINT 1:END    β) 10 GOSUB 30:PRINT 1:END
      20 PRINT 2:END                20 PRINT 2:END
      30 'POKE (&HF0A0-4),&H10      30 POKE (&HF0A0-4),&H10'Адрес перехода
      40 RETURN                     40 RETURN 'изменен с адреса &H800A на
@@ -1050,8 +987,6 @@
       1                             2
      Ok                            Ok
 
-
-
          X.6.   Х р а н е н и е  с т р о к о в ы х  в е л и ч и н
 
    Функция  VARPTR  указывает адрес расположения строковых данных в опера-
@@ -1067,7 +1002,6 @@
 3 позиции правее той, с которой располагается информация о переменной γ.
    Пусть γ - простая строковая переменная. Изобразим  "кусочек"  памяти в
 окрестности байта с адресом X:
-
                              ┌── Байт, адрес которого возвращает функция
                ┌───┬───┬───┬─▼─┬───┬───┐      VARPTR(γ)
                │▧▧▧│▧▧▧│▧▧▧│∗∗∗│▧▧▧│▧▧▧│
@@ -1077,7 +1011,6 @@
                  │     │     │     └─ Ссылка на адрес в PIT или  на адрес
       Тип переменной   │     └── Байт длины           в строковой области
                  Идентификатор
-
    Напомним Вам, что в программировании  с с ы л к а - содержимое  ячейки
 памяти, воспринимаемое как адрес некоторой другой ячейки.
    Указатели строковых переменных хранятся в VT.  Они  занимают  6 байтов,
@@ -1110,6 +1043,8 @@
     MSX
     Ok
 
+
+
    П р и м е р 2.   10 A$="ABCD"
    ─────────────    run
                     Ok
@@ -1128,12 +1063,10 @@
                                         ²
                  1000 0000 0000 1001  = &H8009
                                     ²
-   Итак, строка помещается в PIT по адресу &H8009.
-   Все остальное очевидно! 
+   Итак, строка помещается в PIT по адресу &H8009.Все остальное очевидно!
    ? PEEK(&H8009)  ? PEEK(&H800A)  ? PEEK(&H800B)  ? PEEK(&H800C)
     65              66              67              68 ◀── Код ASCII "D"
    Ok              Ok              Ok              Ok
-
    П р и м е р 3.  А теперь измените строку 10 и выполните программу.
    ─────────────           10 A$="ABCD"+""
                            run
@@ -1148,7 +1081,6 @@
  PRINT PEEK(&H8017) ──▶   4    Длина строки
  PRINT PEEK(&H8018) ──▶ 101 =  &H65 ──▶  Новый адрес (млaдший байт)
  PRINT PEEK(&H8019) ──▶ 241 =  &HF1 ──▶  Новый адрес (старший байт)
-
    Операция, выполненная над строкой, явилась причиной пересылки ее по ад-
 ресу &HF165 (без изменения). Вы можете убедиться в этом, используя  "в ок-
 рестности" этого адреса функцию PEEK.
@@ -1156,10 +1088,9 @@
       65               66               67               68
      Ok               Ok               Ok               Ok
   Забегая несколько вперед,  отметим, что  функция FRE("")  возвратила бы 
-число 200 в первом случае, однако, во втором случае возвращает число 196.
+число 200 в первом случае, однако во втором случае возвращает число 196.
    Приведем схемы расположения информации в памяти для строковых массивов:
    α) о д н о м е р н ы й  строковый массив.
-
                         VARPTR(B$(0))───┐           ┌── VARPTR(B$(1))
       ┌───┬───┬───┬───┬───┬───┬───┬───┬─▼─┬───┬───┬─▼─┬───┬───┬─── 
       │   │   │   │   │   │ 1 │   │   │∗∗∗│   │   │∗∗∗│   │   │∗∗∗
@@ -1172,7 +1103,6 @@
                             │     │     │ Адрес 0-го элемента
               Размерность массива │ Длина значения 0-го элемента
                      Число элементов в массиве
-
    П р и м е р 4.  Обязательно разберите пример "с компьютером в руках"!
    ─────────────
      10 DIM SM$(2):SM$(0)="рог"+"":SM$(1)="Inform"+"":SM$(2)="1989 г."+""
@@ -1204,7 +1134,6 @@
                  Адреса ──▶ X  X+1 X+2
                             ▲  ───▲───
                Байт длины ──┘     └── Ссылка на адрес в строковой области
-
    Продолжим наш пример:
        PRINT HEX$(VARPTR(SM$(0)))
        804F
@@ -1228,8 +1157,11 @@
        г                    ◀─┘
        Ok
 
-   β)  д в у х м е р н ы й  строковый массив.
 
+
+
+
+   β)  д в у х м е р н ы й  строковый массив.
                      Значение, возвращаемое функцией VARPTR() ───┐
   ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬──▼──┐
   │     │     │     │     │     │ &H2 │     │     │     │     │ ∗∗∗ │
@@ -1242,19 +1174,15 @@
  Тип массива                    массива     │           │
                               Количество столбцов  Количество строк
 
-
-
                       X.7.  О п е р а т о р  CLEAR
 
-
                               Чтобы вычистить одно, приходится выпачкать
                               что-нибудь другое; но можно испачкать  все,
                               что угодно, и ничего при этом не вычистить.
-                                       Принцип Накопления Грязи по Питеру 
-
+                                       Принцип накопления грязи по Питеру
 
    Оператор CLEAR в общем виде записывается так:
-                              CLEAR [[n][,A]]
+                              CLEAR [[n][,A]]      ,
 где:  CLEAR ("очистить") - служебное слово;
       n  - арифметическое выражение, целая  часть  значения  которого ука-
 зывает количество байтов, резервируемых под строковое пространство; значе-
@@ -1268,7 +1196,7 @@
 Вам данные.
    Другими словами, значение А "переопределяет верхний предел  пространст-
 ва, используемого MSX-BASIC".
-   Например, команда  CLEAR 1000,&HF000  отводит  1000  байт для значений
+   Например, команда CLEAR 1000,&HF000 отводит  1000 байтов для  значений
 строковых констант в строковой области и RAM с адреса &HF000 для  размеще-
 ния машинной подпрограммы.
    М а к с и м а л ь н ы м  значением выражения A , конечно же,  является
@@ -1311,10 +1239,8 @@
 &HF69B. Этот адрес занимает 2 байта памяти;
       VARTAB - имя слова, расположенного  в  рабочей  области  по  адресу
 &HF6C2. Этот адрес занимает 2 байта памяти.
-
    П р и м е р 3.   Нажмите кнопку "RESET" Вашего компьютера.
-   ─────────────
-   А теперь:
+   ─────────────   А теперь:
     print hex$(peek(&HF69C));" ";hex$(peek(&HF69B))
     DC 5F  ◀─────  Вы узнали адрес FRETOP ?
     Ok
@@ -1324,7 +1250,6 @@
     print &HDC5F-&H8003-145-16
      23483 ◀─────  0≤n≤23483
     Ok
-
    П р и м е р 4.   10 CLEAR200:T$=SPACE$(198):B$=STRING$(2,"#"):?B$:X$=
    ─────────────    STRING$(1,"L"):?X$
                     run
@@ -1339,20 +1264,16 @@
   run
   ## 0
   Ok
-
                         X.8.   Ф у н к ц и я  FRE
 
-
           Garbage collection ("чистка памяти","сборка мусора") - действия
           системы динамического распределения памяти для обнаружения неис-
           пользуемых программой блоков памяти и присоединения их к списку
           свободной памяти для повторного использования.
                   Англо-русский словарь по программированию и информатике
-
-
    Информацию о размере свободной области ("Free Area") в RAM  можно полу-
 чить с помощью функции FRE, обращение к которой имеет вид:
-                                  FRE(A)
+                                  FRE(A)   ,
 где:  FRE ("FREe"-"свободный") - служебное слово;
       A - арифметическое или строковое выражение, причем для интерпретато-
 ра важным является лишь тип выражения, а не его значение.
@@ -1360,14 +1281,13 @@
                          FRE(0)     или      FRE("")   .
    Функция FRE(0) возвращает количество байтов, оставленных  для  расшире-
 ния PIT, VT, стека, строковой области и блока управления файлами.
-
    П р и м е р 1.
    ─────────────
    10 ? FRE(0):X=451:? FRE(0):Z#=7.5:? FRE(0)
    20 Y!=555:? FRE(0):W%=111:? FRE(0)
    run
     28739
-    28728 ◀──т.к. переменная Х по умолчанию - двойной точности, а,следова-
+    28728 ◀──т.к. переменная Х по умолчанию - двойной точности, а следова-
              тельно, занимает  в памяти 11 байтов;
     28717 ◀──т.к. переменная  Z - двойной точности (занимает в памяти так-
              же 11 байтов);
@@ -1375,7 +1295,6 @@
              байтов);
     28705 ◀──т.к. переменная W - целого типа (занимает в памяти 5 байтов).
    Ok
-
    Функция FRE(0) выдает сообщение:         
            "Out of memory"  ("Н е  х в а т а е т  п а м я т и")
 при достижении значения, меньшего 145 байтов, минимально  допустимого для
@@ -1399,9 +1318,8 @@
 го  типа,  перед вычислением  объема свободной памяти  функция  выполняет 
 "с б о р к у  м у с о р а",  т.е.  удаление  всех неиспользуемых данных и 
 освобождение занимаемых ими областей.
-
    П р и м е р 2.  Оказывается,что если у Вас в начале программы встречает-
-   ─────────────   ся оператор A$="ABCD"+"EF", а затем-оператор A$="X"+"Y",
+   ─────────────   ся оператор A$="ABCD"+"EF", а затем оператор A$="X"+"Y",
 то Вы сразу же создадите 6-байтовое пространство, заполненное "мусором"!
    Покажем это:
    print HEX$(PEEK(&HF69C)); HEX$(PEEK(&HF69B));
@@ -1414,6 +1332,9 @@
    Ok
    a$="X"+"Y"
    Ok
+
+
+
    for t=0 to 7:print chr$(peek(&hF168-t));:next
    FEDCBAYX
    └──▲─┘
@@ -1425,7 +1346,6 @@
    YXXCBAYX
      └──▲─┘
    Ok   └─── "м у с о р"
-
    Из примера следует, что строки хранятся в строковом пространстве в том
 порядке, в каком они были определены.
    Таким образом,  функция FRE("") изменила положение значения  строковой 
@@ -1434,7 +1354,6 @@
 определено много символьных переменных, время "сборки мусора" может соста-
 вить несколько минут. При выполнении этой  операции  компьютер  полностью
 "застывает". Посмотрите...
-
    П р и м е р 3.
    ─────────────
    10 CLEAR 5000 'Объявлен размер строковой области - 5000 байтов
@@ -1474,7 +1393,6 @@
 
    Перед работой со следующим примером выключите, а затем снова  включите
 Ваш компьютер.
-
    П р и м е р 5.
    ─────────────
    A$="полет"
@@ -1509,7 +1427,6 @@
 ли на значения строковых переменных. Обычный же оператор присваивания, ра-
 зумеется, указатели изменяет! Покажем это на примере (не забудьте о коман-
 де CLEAR !).
-
    П р и м е р 6.
    ─────────────
    a$="полет"
@@ -1530,9 +1447,10 @@
    Ok
    Как видим, значение указателя в последнем случае не изменилось!
    γ) при необходимости используйте оператор SWAP A$,В$ , который не меня-
-ет расположение значений переменных, а лишь  меняет местами  указатели на
+ет расположения значений переменных, а лишь  меняет местами  указатели на
 эти значения. Проиллюстрируем этот факт на примере...
 
+
    П р и м е р 7.
    ─────────────
    clear
@@ -1550,6 +1468,8 @@
    for t=0 to len(a$)+len(b$):print chr$(peek(&hF168-t));:next
    течаЗтамотвАА
    Ok
+
+
    И наконец, функция FRE() может помочь Вам также  в  з а щ и т е  Вашей
 программы. Например, в "укромном" месте  программы, работающей  со строко-
 вой информацией, поместите оператор X$=SPACE$(FRE(""))- конечно,Вы должны
@@ -1563,6 +1483,10 @@
    Ok
 
 
+
+
+
+
                    X.9.  Р а б о ч а я   о б л а с т ь
 
    В рабочей области содержатся системные подпрограммы, системные перемен-
@@ -1576,8 +1500,8 @@
    │         нимает 2 байта, расположенных с адреса  &HFC4A .        │
    └─────────────────────────────────────────────────────────────────┘
    Еще раз напомним Вам, что адреса, занимающие два байта,  всегда записы-
-ваются так: вначале записывается содержимое младшего байта,  а затем - со-
-держимое старшего байта!
+ваются так: вначале записывается содержимое младшего байта, а затем содер-
+жимое старшего байта!
    Отметим, что значением  выражения  HEX$(PEEK(&HFC4A)+256*PEEK(&HFC4B))
 является  а д р е с  н а ч а л а  р а б о ч е й  области.
    Поскольку рабочая область расположена в RAM, ее  переменные могут изме-
@@ -1588,12 +1512,11 @@
               X.9.1.   М а т р и ц а   к л а в и а т у р ы
 
    М а т р и ц е й  клавиатуры для MSX-компьютеров назовем таблицу вида:
-
                      0-й   1-й   2-й   3-й   4-й   5-й   6-й    7-й
                      бит   бит   бит   бит   бит   бит   бит    бит
             ┌──────┬─────┬─────┬─────┬─────┬─────┬─────┬──────┬──────┐
-            │Адреса│     │     │     │     │     │     │      │      │
-            │байтов│ 254 │ 253 │ 251 │ 247 │ 239 │ 223 │  191 │ 127  │
+            │Адреса│ &hFE│ &hFD│ &hFB│ &hF7│ &hEF│ &hDF│ &hBF │ &h7F │
+            │байтов│(254)│(253)│(251)│(247)│(239)│(223)│ (191)│ (127)│
             ├──────┼─────┼─────┼─────┼─────┼─────┼─────┼──────┼──────┤
  0-я строка │ FBE5 │  9  │  ;  │  1  │  2  │  3  │  4  │   5  │   6  │
             ├──────┼─────┼─────┼─────┼─────┼─────┼─────┼──────┼──────┤
@@ -1621,14 +1544,12 @@
             ├──────┼─────┼─────┼─────┼─────┼─────┼─────┼──────┼──────┤
 10-я строка │ FBEF │  5  │  6  │  7  │  8  │  9  │  -  │   ,  │   .  │
             └──────┴─────┴─────┴─────┴─────┴─────┴─────┴──────┴──────┘
-
    Последние две строки соответствуют цифровой  (правой)  зоне клавиатуры
 учительского компьютера серии MSX-2.
    Ответим теперь на Ваш очевидный вопрос:
                 ┌───────────────────────────────────────┐
                 │   Как воспользоваться этой таблицей?  │
                 └───────────────────────────────────────┘
-
    П р и м е р 1. Ниже приведены программа, останавливаемая нажатием  кла-
    ─────────────  виши "GRAPH":
              10 Z=PEEK(&HFBEB):IF Z<>251 THEN 10
@@ -1654,17 +1575,12 @@
    60 PRINT"X=";8-INSTR(Z$,"0"):PRINT
    80 NEXT:GOTO 10 '──▶
 
-
-
        X.9.2.   Д и н а м и ч е с к а я  к л а в и а т у р а  [46]
  
-
                               Промедление с легким делом превращает его в
                               трудное, промедление же с трудным делом пре-
                               вращает его в невозможное.
                                                                 Д.Лоример
-
-
    Исследуем один  подход к разработке учебных программ,  работающих  под 
 управлением интерпретатора MSX-BASIC.  Существенная особенность этого под-
 хода состоит в том,  что программа  в процессе выполнения  модифицируется  
@@ -1707,6 +1623,8 @@
 приведенной ниже программе - строка 10);
    2) символьная строка дополняется впереди номером, а в конце - кодом ко-
 манды "RETURN" (строки 15 и 1890):  F$="номер строки 1"+F$+CHR$(13)     ;
+
+
    3) строка побайтно переписывается в БК, начиная  с  aдреса &HFBF0, при
 помощи оператора POKE и функции PEEK (подпрограмма, начинающаяся  со стро-
 ки 1880);
@@ -1724,7 +1642,6 @@
    Таким образом, указанный алгоритм решает  задачу автоматической модифи-
 кации программы в соответствии с текстом запроса, вводимого пользователем
 с клавиатуры, и запуска ее с указанного номера строки.
-
    П р и м е р.
    ───────────
    1 GOTO 10
@@ -1776,15 +1693,15 @@
    2450 W$=INKEY$:IF W$="" THEN 2450 ELSE GOTO 10
    2460 RETURN'──▶
 
-                X.10.  П о р т ы  в в о д а - в ы в о д а
-
 
-                       И я надеюсь, что наши потомки будут благодарны мне
-                       не только за то, что я здесь разъяснил, но и за то,
-                       что мною было добровольно опущено с целью предоста-
-                       вить им удовольствие самим найти это.
-                                                   Pене Декарт. Геометрия
+                X.10.  П о р т ы   в в о д а - в ы в о д а
 
+                           И я надеюсь, что наши потомки будут благодарны
+                           мне не только за то, что я здесь разъяснил, но
+                           и за то, что мною было  добровольно  опущено с
+                           целью предоставить им удовольствие самим найти
+                           это.
+                                                      P.Декарт. Геометрия
 
    П о р т  ввода-вывода - многоразрядный вход или выход компьютера,через
 который процессор обменивается данными с внешними устройствами  (клавиату-
@@ -1801,16 +1718,15 @@
    1) порты с адресами &H00÷&H7F. Вы не можете  и з м е н и т ь  их содер-
 жимоe (сравните с ROM!);
    2) порты с адресами &H80÷&HFF. Их содержимое изменять можно  (сравните
-с RAM!);
-   3) порты с адресами &H100÷&HFFFF зарезервированы(пока не используются).
+с RAM!).
    Некоторые порты, их функции и адреса перечислены ниже:
 ┌────────────────┬───────────────┬─────────────────────────────────────┐
 │    А д р е с   │ Чтение(Запись)│         Н а з н а ч е н и е         │
 │────────────────┴───────────────┴─────────────────────────────────────┤
 │   Порты, отвечающие за работу с локальной сетью КУВТ YAMAHA MSX-1    │
 ├────────────────┬───────────────┬─────────────────────────────────────┤
-│      &h00      │ Чтение(Запись)│         Посылаемые данные           │
-│      &h01      │    Чтение     │               Статус                │
+│      &H00      │ Чтение(Запись)│         Посылаемые данные           │
+│      &H01      │    Чтение     │               Статус                │
 ├────────────────┼───────────────┼─────────────────────────────────────┤
 │      &H02      │    Чтение     │  Номер компьютера в локальной сети  │
 │                │               │   (только для компьютеров MSX-1)    │
@@ -1843,7 +1759,7 @@
 │      &HA0      │    Запись     │      Ввод в порт номера регистра    │
 │      &HA1      │    Запись     │ Ввод в порт информации для установ- │
 │                │               │          ленного регистра           │
-│      &HA2      │    Чтение     │  Последнее число, записанное в PSG  │
+│      &HA2      │    Чтение     │    Чтение числа из регистра PSG     │
 ├────────────────┴───────────────┴─────────────────────────────────────┤
 │  Программируемый  п а р а л л е л ь н ы й   и н т е р ф е й с  (PPI) │
 ├────────────────┬───────────────┬─────────────────────────────────────┤
@@ -1851,12 +1767,26 @@
 │      &HA9      │ Чтение(Запись)│   Запись (чтение) данных в порт B   │
 │      &HAA      │ Чтение(Запись)│   Запись (чтение) данных в порт C   │
 │      &HAB      │ Чтение(Запись)│     Запись (чтение) режимов PPI     │
+├────────────────┼───────────────┼─────────────────────────────────────┤
+│      &HB0      │               │ Внешняя память (SONY)  (через &HB3) │
 ├────────────────┴───────────────┴─────────────────────────────────────┤
-│           Порты, отвечающие за работу с  д и с к о в о д о м         │
+│           Порты, отвечающие за работу с  т а й м е р о м             │
 ├────────────────┬───────────────┬─────────────────────────────────────┤
-│      &HB4      │     Запись    │                  ?                  │
-│      &HB5      │ Чтение(Запись)│                  ?                  │
+│      &HB4      │     Запись    │  Номер столбца ОЗУ таймера          │
+│      &HB5      │ Чтение(Запись)│  Чтение/запись данных в ОЗУ таймера │
+├────────────────┼───────────────┼─────────────────────────────────────┤
+│      &HB8      │               │  Световое перо (Sanyo) (через &HBB) │
 ├────────────────┼───────────────┼─────────────────────────────────────┤
+│                │               │      Управление Audio/Video         │
+│                │               ├─────┬───────────────────────────────┤
+│                │               │Номер│       Назначение бита         │
+│                │               │бита │                               │
+│      &HF7      │     Запись    ├─────┼───────────────────────────────┤
+│                │               │  4  │ Управление AV    (0 - TV)     │
+│                │               │  5  │ Управление Ym    (0 - TV)     │
+│                │               │  6  │ Управление Ys    (0 - Super)  │
+│                │               │  7  │ Выбор Video      (0 - TV)     │
+├────────────────┼───────────────┼─────┴───────────────────────────────┤
 │      &HFC      │ Чтение(Запись)│       Регистры распределения        │
 │      &HFD      │ Чтение(Запись)│             с л о т о в             │
 │      &HFE      │ Чтение(Запись)│         (расширений памяти)         │
@@ -1867,6 +1797,8 @@
        │      Для работы с портами ввода-вывода используются:    │
        │            функция INP и операторы OUT и WAIT           │
        └─────────────────────────────────────────────────────────┘
+
+
    Формат оператора OUT:
                    ┌──────────────────────────────────┐
                    │   OUT  а д р е с,  д а н н о е   │,
@@ -1878,11 +1810,9 @@
 го принадлежит отрезку [0,255].
   Оператор OUT "посылает" заданное операндом  д а н н о е значение в порт,
 номер которого задан значением параметра  а д р е с .
-В н и м а н и е !
-       На компьютерах серии MSX-2 прежде, чем использовать оператор
-       OUT, необходимо в непосредственном режиме выполнить команду
-                               CALL NETEND
-                (отключить Ваш компьютер от локальной сети)
+В н и м а н и е ! На компьютерах серии MSX-2 прежде, чем использовать опе-
+ратор OUT, необходимо в непосредственном режиме выполнить команду
+        CALL NETEND  (т.е. отключить Ваш компьютер от локальной сети).
    Опишем синтаксис функции INP:
                        ┌────────────────────────┐
                        │     INP (а д р е с)    │,
@@ -1920,15 +1850,16 @@
    1. │  Порт А используется для выбора  с л о т о в, осуществляющих  │
       │           управление расширенной памятью компьютера.          │
       └───────────────────────────────────────────────────────────────┘
+       За подробностями мы отсылаем Вас к Приложению 1 (раздел 1.8.2).
       ┌───────────────────────────────────────────────────────────────┐
-      │  Порты PPI  B и C применяются для "работы" с матрицей клавиа- │
-      │  туры, причем номер строки  матрицы клавиатуры "посылается" в │
+      │  Порты B и C применяются для "работы" с матрицей клавиатуры,  │
+      │  причем номер строки матрицы клавиатуры "посылается" в порт   │
       │  порт C, а номер столбца "читается" в порту B .               │
       └───────────────────────────────────────────────────────────────┘
 
    П р и м е р 1.     О б н а р у ж е н и е  нажатия клавиши "GRAPH".
    ─────────────   Отметим,  что  клавиша  "GRAPH" находится в строке 6 и
-столбце 2 матрицы клавиатуры (и строки, и столбцы матрицы  нумеруются, на-
+столбце 2 матрицы клавиатуры (и строки  и столбцы матрицы  нумеруются, на-
 чиная с 0). Тогда:
    1) номер строки матрицы клавиатуры "посылаем" в порт C :
                                  OUT &HAA,6
@@ -1951,9 +1882,9 @@
    Взгляните на приведенную ниже таблицу, в которой описаны назначения би-
 тов порта C:
           ┌──────────┬──────────────────────────────────────────┐
-          │ Биты 0÷3 │            Строка клавиатуры             │
-          │ Бит 4    │  Если 0, то запускается кассетная лента  │
-          │ Бит 5    │          Сигнал записи на ленту          │
+         │ Биты 0÷3 │       Строка матрицы клавиатуры          │
+         │ Бит 4    │  Если 0, то запускается магнитная лента  │
+         │ Бит 5    │     Сигнал записи на магнитную ленту     │
           │ Бит 6    │  Если 0, то включается индикатор "CAPS"  │
           │ Бит 7    │       Управление звуковым сигналом       │
           └──────────┴──────────────────────────────────────────┘
@@ -1970,14 +1901,12 @@
           &B00000110 OR (&B∗1∗∗∗∗∗∗ AND &B11110000) = &B∗1∗∗ 0110
 (символом "∗" отмечены биты, состояние которых в данном случае роли не иг-
 рает).
-
    П р и м е р 2.  Включение индикатора "CAPS"  (если он выключен!) можно
    ─────────────   осуществить следующей командой:
                      OUT &HAA, INP(&HAA) XOR &B01000000
                                 │               │         ┌─ !!!
                                 ▼               ▼         ▼
                          &B∗1∗∗∗∗∗∗  XOR  &B01000000 = &B∗0∗∗∗∗∗∗
-
    П р и м е р 3.
    ─────────────
    10 OUT &HAA,6 OR (INP(&HAA) AND &HF0):B=INP(&HA9)
@@ -1986,7 +1915,6 @@
    40 IF (B AND 4)=0 THEN PRINT "Нажата клавиша GRAPH":GOTO 10 ELSE 10
    В ходе работы программы индикатор "CAPS" сохранит состояние, в котором
 он находился до пуска программы!
-
    П р и м е р 4. Получим  матрицу  клавиатуры при помощи оператора OUT!
    ───────────── ┌────────────────────────────────────────────┐
                  │   10 INPUT "Номер строки";N                │
@@ -1996,19 +1924,18 @@
                  │   50 IF B THEN PRINT "Клавиша нажата":END  │
                  │   60 GOTO 30                               │
                  └────────────────────────────────────────────┘
-
    П р и м е р 5. Включение и выключение кассетной ленты. Операторы MOTOR
    ─────────────  ON и MOTOR OFF могут быть имитированы с помощью команды:
                         OUT &HAA, INP(&HAA) XOR &B00010000
 
 
 
+
           X.10.2.  П р о г р а м м и р у е м ы й  з в у к о в о й
                           г е н е р а т о р (PSG)
 
    Вначале приведем два примера записи информации в PSG при помощи портов
 ввода-вывода.
-
    П р и м е р 6.
    ─────────────
    10 SOUND 7,8  'Шум из канала A   10 OUT &HA0,7:OUT &HA1,8: A=INP(&HA2)
@@ -2018,7 +1945,6 @@
                                     run
                                      8  15  26
                                     Ok
-
    П р и м е р 7.   Представьте, что Вы находитесь на берегу Черного моря
    ─────────────    в районе Ялты. Закройте глаза и ...
    10 FOR I=0 TO 13:READ V
@@ -2047,7 +1973,11 @@
          │ PLAY "O4B"  │        227        │        0         │
          │ PLAY "O5C"  │        214        │        0         │
          └─────────────┴───────────────────┴──────────────────┘
-
+   Вы можете проверить эту таблицу при помощи следующей программы:
+   10 PLAY "O4C"
+   20 OUT &hA0,0: PRINT INP(&hA2) 'Читаем данные
+   30 OUT &hA0,1: PRINT INP(&hA2) 'из регистров PSG
+      А теперь слушайте ...
    П р и м е р 8.  Гамма "до-мажор".
    ─────────────
    10 DATA 1,172,1,125,1,83,1,64,1,29,0,254,0,227,0,214
@@ -2059,56 +1989,19 @@
    50 NEXT
    60 OUT &HA0,8:OUT &HA1,0 'Сбросим громкость канала A
 
-   П р и м е р 10. "В траве сидел кузнечик!"
-   ──────────────
-   10 'DEFINTA-Z:BEEP
-   20 OUT &HA0,8:OUT&HA1,15:OUT &HA0,1:OUT &HA1,0:OUT &HA0,0:OUT &HA1,254
-   30 RESTORE 240:S=S+1:IF S=1 THEN K=14 ELSE K=12
-   40 FOR I=1 TO K:READ S1,S0,T1
-   50 OUT &HA0,8:OUT &HA1,15
-   60 OUT &HA0,1:OUT &HA1,S1:OUT &HA0,0:OUT &HA1,S0
-   70 TIME=0
-   80 T=TIME:IF T<T1 THEN 80
-   90 SOUND 8,0             'OUT &HA0,8:OUT &HA1,0:FOR J=1 TO 10:NEXT
-   100 NEXT
-   110 IF S=1 THEN 30
-   120 RESTORE 260:S=0
-   130 S=S+1:IF S=1 THEN K=20 ELSE K=14
-   140 FOR I=1 TO K:READ S1,S0,T1
-   150 OUT &HA0,8:OUT &HA1,15
-   160 OUT &HA0,1:OUT &HA1,S1:OUT &HA0,0:OUT &HA1,S0
-   170 TIME=0
-   180 T=TIME:IFT<T1 THEN 180
-   190 OUT &HA0,0:OUT &HA1,0:OUT &HA0,1:OUT &HA0,0:FOR J=1 TO 10:NEXT:NEXT
-   200 IF S=1 THEN RESTORE 270:GOTO 130
-   210 OUT &HA0,8:OUT &HA1,15
-   220 OUT &HA0,1:OUT &HA1,0:OUT &HA0,0:OUT &HA1,254
-   230 RUN
-   240 DATA 0,254,15,1,83,15,0,254,15,1,83,15,0,254,15,1,13,15,1,13,30
-   250 DATA 1,13,15,1,83,15,1,13,15,1,83,15,1,13,15,0,254,15,0,254,30
-   260 DATA 0,254,15,0,0,15,0,254,30
-   270 DATA 0,227,15,0,227,7.5,0,227,7.5,0,227,15,0,227,15
-   280 DATA 0,215,15,0,215,7.5,0,215,7.5,0,215,15,0,215,15
-   290 DATA 0,215,15,0,227,15,0,254,15,1,13,15,0,254,15,0,254,30
-   300 DATA 0,254,15
-
-
 
          X.10.3.  Д р у г и е  п о р т ы.  О п е р а т о р  WAIT
 
    Приведем примеры использования "содержимого" других портов.
-
    П р и м е р 1.  Использование портов с адресами &H90 и &H91 для вывода
    ─────────────   символа на принтер.
    Вначале о "роли" первого бита порта с номером &H90:
-
     7-й бит  6-й бит  5-й бит 4-й бит  3-й бит 2-й бит 1-й бит 0-й бит
    ┌───────┬────────┬────────┬────────┬───────┬───────┬───────┬───────┐
    │   ∗   │    ∗   │    ∗   │    ∗   │   ∗   │   ∗   │       │   ∗   │
    └───────┴────────┴────────┴────────└───────┴───────┴───▲───┴───────┘
    Принтер в режиме  ON LINE (подключен к ПЭВМ): 0 ───────│
    Принтер в режиме OFF LINE (отключен от ПЭВМ): 1 ───────┘
-
    A теперь: включите принтер и вставьте бумагу...
       5 CLEAR 300
       10 INPUT"Слово";A$
@@ -2120,7 +2013,6 @@
       40    B=ASC(MID$(A$,I,1))
       50    OUT &H91,B
       60 NEXT I
-
    П р и м е р 2.   Считывание кода выведенного на экран символа:
    ─────────────    10 K$=INKEY$:IF K$="" THEN 10 ELSE PRINT K$;
                     20 PRINT INP(&H98):GOTO 10
@@ -2143,7 +2035,7 @@
 (при этом Вы вернетесь в командный режим).
    Содержимое порта с указанным адресом заносится в некоторый регистр про-
 цессора Z-80, который мы назовем X. Далее содержимое регистра X комбиниру-
-ется со значениями параметров M и С, по формуле:
+ется со значениями параметров M и С по формуле:
                          X = (X XOR C) AND M
    Если после этого содержимое регистра X окажется равным  0, то  происхо-
 дит "выход из оператора WAIT". В противном случае порт  вновь "опрашивает-
@@ -2158,24 +2050,24 @@
             ├─────────────────┼───────────────────────────────┤
             │ (X XOR C) AND M │ 0   0   0   1   0   1   0   0 │
             └─────────────────┴───────────────────────────────┘
-Вопрос к читателю: Какой вид будет иметь таблица-"подсказка" при  отсутст-
-вии параметра C ?
-
+   Вопрос к читателю: Какой вид будет иметь таблица-"подсказка" при отсут-
+ствии параметра C ?
    П р и м е р 3.               10 WAIT &HAA,64,255
    ─────────────
       (&B∗1∗∗∗∗∗∗ XOR &B11111111) AND &B01000000 = &B00000000 = 0 !
    Эта программа закончит свою работу, если загорится индикатор "CAPS".
-
    П р и м е р 4.
    ─────────────
    α) WAIT &H90,2,255 'Ожидается  в к л ю ч е н и е  принтера
    β) WAIT &H90,2,0   'Ожидается  о т к л ю ч е н и е  принтера
 
 
-   Д о п о л н е н и е.  Работа с портом ввода-вывода с адресом &h0C
-   ───────────────────
-   Предварительно кратко опишем структуру порта &h0C...
+                    X.11.  Д о п о л н е н и е
+
+         Р а б о т а  с  п о р т о м   в в о д а - в ы в о д а
+                       с  а д р е с о м   &h0C
 
+   Предварительно кратко опишем структуру данного порта.
  Старший ┌───┬───┬───┬───┬───┬───┬───┬───┐ Младший
    бит   │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │   бит
          └─▲─┴─▲─┴─▲─┴─▲─┴─▲─┴─▲─┴─▲─┴─▲─┘
@@ -2186,8 +2078,9 @@
            │   └── Бит направления поступления информации (1: от учителя)
            └────── Бит направления поступления информации (1: от ученика)
 
-   А теперь два примера использования данного порта...
-
+   А теперь два примера его использования.
+   В н и м а н и е ! Слабонервых просим не смотреть: примеры  написаны на
+Макроассемблере M80!
    П р и м е р  1.   П о с ы л к а  байта по сети
    ──────────────
 OUT_BYTE::                  ; На входе в регистре A - д а н н о е
@@ -2220,3 +2113,30 @@
         EI                  ;
     RET                 ;
 
+
+   К а р т а   а д р е с о в   п о р т о в   в в о д а - в ы в о д а
+               д л я   к о м п ь ю т е р о в   MSX-1  [30]
+
+FF·┌──────────────────────────────┐ B4·┌──────────────────────────────┐
+   │                              │    │ Внешняя память               │
+F8·├──────────────────────────────┤ B0·├──────────────────────────────┤
+   │ Порты управления Audio/Video │    │ PPI (8255)                   │
+F7·├──────────────────────────────┤ A8·├──────────────────────────────┤
+   │                              │    │ PSG (AY-3-8910)              │
+F0·├──────────────────────────────┤ A0·├──────────────────────────────┤
+   │                              │    │ VDP (9918A)                  │
+E0·├──────────────────────────────┤ 98·├──────────────────────────────┤
+   │ ROM для китайских иероглифов │    │ Принтер                      │
+D8·├──────────────────────────────┤ 90·├──────────────────────────────┤
+   │ Контроллер Floppy Disk       │    │                              │
+D0·├──────────────────────────────┤ 88·├──────────────────────────────┤
+   │                              │    │ RS-232C                      │
+C0·├──────────────────────────────┤ 80·├──────────────────────────────┤
+   │ Световое перо                │    │ Зарезервированы              │
+B8·├──────────────────────────────┤ 40·├──────────────────────────────┤
+   │                              │    │ Не определены                │
+B5·├──────────────────────────────┤ 00·└──────────────────────────────┘
+   │ Календарь. Часы              │
+B4·└──────────────────────────────┘
+
+