Инструменты пользователя

Инструменты сайта


msx:basic_programming_guide:11

Это старая версия документа!


Первая страницаПредыдущая страницаНазад к обзоруСледующая страницаПоследняя страница

Глава XI. Работа с видеопамятью и видеопроцессором


Надо понять тот минимум, на котором покоится мир, и всё избыточное безжалостно отсекать (бритва Оккама).

У.Оккам

XI.1. Видеопамять

Процессор (англ. «processor», от «process» — «обрабатывать») — совокупность устройств ЭВМ, выполняющих функции по преобразованию информации. В зависимости от назначения различают центральные, функционально–ориентированные и проблемно–ориентированные процессоры.

Графические возможности ПЭВМ «YAMAHA» поддерживаются функционально–ориентированным процессором — видеопроцессором. Видеопроцессор (VDP) постоянно «общается» с видеопамятью (VRAM), которая доступна центральному процессору через порты ввода–вывода, отвечает за изображение на экране и интерпретирует находящиеся в ней данные в соответствии с заданным режимом SCREEN. Видеопроцессор обеспечивает отображение информации, хранящейся в видеопамяти, на экран дисплея.

Видеопамять («Video RAM») — доступная устройству сопряжения дисплея и компьютера область оперативной памяти ЭВМ, в которой расположены данные, соответствующие изображению на экране. В текстовом режиме видеопамять содержит коды и атрибуты символов,в графических режимах каждой точке экрана соответствует одна или несколько ячеек видеопамяти, указывающие её цвет и яркость. Видеопамять разделена на несколько областей, называемых Таблицами, имена которых, размеры и назначение зависят от установленного режима SCREEN.

Это деление памяти автоматически выполняется оператором SCREEN, который инициализирует Таблицы видеопамяти.

Прежде чем Вы попытаетесь непосредственно воздействовать на «содержимое» экрана дисплея, хорошо разберитесь в назначении Таблиц VRAM!

Далее в тексте Вам часто будут встречаются следующие аббревиатуры:

Аббревиатура Что Вам необходимо запомнить!
PNT «Pattern Name Table»«Таблица имён образов»
PGT «Pattern Generation Table»«Таблица шаблонов образов» («Таблица изображений»)
CT «Color Table»«Таблица цветов»
SGT «Sprite Generation Table»«Таблица шаблонов спрайтов»
SAT «Sprite Attribute Table»«Таблица атрибутов спрайтов»
SCT «Sprite Color Table»«Таблица цветов спрайтов»
PT «Palette Table»«Таблица палитры»

XI.1.1. Псевдопеременная BASE

Псевдопеременная BASE используется для чтения начальных адресов Таблиц VRAM, а также для их «перемещения» в видеопамяти.

  • Вначале о синтаксисе псевдопеременной BASE, используемой как функция:

    BASE(N)

    ,

    где:

    • BASE («base» — «база», «значение или адрес, относительно которого представляются другие значения и адреса») — служебное слово;
    • N — арифметическое выражение, целая часть значения которого должна принадлежать отрезку [0,19] для компьютеров MSX 1 и отрезку [0,44] для компьютеров MSX 2. По значению N можно определить номер Таблицы видеопамяти (VRAM).

    Функция BASE(N), где N=M*5+T, возвращает начальный адрес Таблицы с номером Т в режиме SCREEN M. Ясно, что M=N\5 и T=N MOD 5

    Номер Таблицы T принадлежит интервалу [0,4]; режим экрана M может принимать значения 0, 1, 2, 3, 4, 5, 6, 7, 8 для компьютеров MSX 2 (0, 1, 2, 3 для компьютеров MSX 1). Таким образом, с помощью функции BASE() можно иметь доступ не более, чем к пяти Таблицам для каждого из режимов экрана.

    Ниже приведены имена Таблиц, соответствующих различным значениям T:

    T Имя Таблицы
    0PNT
    1CT (кроме режимов SCREEN 3, 5, 6, 7, 8 и 40–символьного режима SCREEN 0)
    2PGT (кроме режимов SCREEN 5, 6, 7, 8)
    3SAT (кроме режима SCREEN 0)
    4SGT (кроме режима SCREEN 0)

    Например, найдём начальный адрес Таблицы CT в режиме SCREEN 2. Для этого выполним команду:

    PRINT HEX$(BASE(5*2+1))
     2000             ▲ ▲
    Ok  Режим экрана──┘ └── Номер Таблицы

    Следующая табличка позволяет найти начальный адрес Таблицы VRAM с номером T для режима SCREEN M:

    М \ Т 0(PNT) 1(CT) 2(PGT) 3(SAT) 4(SGT)
    0 (40) 0 —— &H800 —— ——
    0 (80) 0 &H800 &H1000 —— ——
    1 &H1800 &H2000 0 &H1B00 &H3800
    2 &H1800 &H2000 0 &H1B00 &H3800
    3 &H800 —— 0 &H1B00 &H3800
    4 &H1800 &H2000 0 &H1E00 &H3800
    5 0 —— —— &H7600 &H7800
    6 0 —— —— &H7600 &H7800
    7 0 —— —— &HFA00 &HF000
    8 0 —— —— &HFA00 &HF000

    Прочерками здесь помечены адреса Таблиц, отсутствующих в видеопамяти для данных M и T. Числа 40 и 80, стоящие в круглых скобках, указывают на ширину экрана в режиме SCREEN 0.

    А в этой табличке показано количество байтов в каждой из Таблиц VRAM.

    М \ Т 0(PNT) 1(CT) 2(PGT) 3(SAT) 4(SGT)
    0 (40) 960 —— 2048 —— ——
    0 (80) 1920 270 2048 —— ——
    1 768 32 2048 128 2048
    2 768 6144 6144 128 2048
    3 768 —— 1536 128 2048
    4 768 6144 6144 128 2048
    5 27136 —— —— 128 2048
    6 27136 —— —— 128 2048
    7 54272 —— —— 128 2048
    8 54272 —— —— 128 2048

    Внимание! Функция BASE не позволяет найти начальные адреса Таблиц PT и SCT

    Но Вы не волнуйтесь: в следующей табличке мы приводим начальные адреса и этих Таблиц:

    Режим PT SCT
    0 (40) &H0400 ——
    0 (80) &H0800 ——
    1 &H2020 ——
    2 &H1B80 ——
    3 &H2020 ——
    4 &H1E80 &H1C00
    5 &H7680 &H7400
    6 &H7680 &H7400
    7 &HFA80 &HF800
    8 &HFA80 &HF800

    Таблица PT для всех режимов SCREEN занимает в видеопамяти 32 байта. Таблица SCT для всех режимов SCREEN занимает в видеопамяти 512 байт.

  • А теперь — синтаксис псевдопеременной BASE,используемой в левой части оператора присваивания:

    BASE(N)= 1024*A

    или

    BASE(N)=&H400*A

    где:

    • N — арифметическое выражение, целая часть значения которого должна принадлежать отрезку [0,19]. Значение N — это номер Таблицы VRAM;
    • A — арифметическое выражение,целая часть значения которого, умноженная на число 1024, определяет новый начальный адрес таблицы VRAM с номером N (1Кбайт = 1024 байтам). Значение A должно принадлежать отрезку [0,15] для компьютеров серий MSX 1 и MSX 2.
    Значение A 0 1 2 3 4 5 6 7 8
    &H400·A 0 &H400 &H0800 &H0C00 &H1000 &H1400 &H1800 &H1C00 &H2000
    Значение A 9 10 11 12 13 14 15
    &H400·A &H2400 &H2800 &H2C00 &H3000 &H3400 &H3800 &H3C00

    Если значения N или A не будут принадлежать указанным отрезкам, то компьютер выдаст сообщение об ошибке:

    «Illegal function call».

    Псевдопеременная BASE, расположенная в правой части оператора присваивания, позволяет «перемещать» Таблицы. Она используется только в режимах SCREEN 0 ÷ SCREEN 3, и поэтому значение N должно принадлежать отрезку [0,19].

    Вспомним, что в режимах SCREEN 5÷8 можно переключаться с одной экранной страницы на другую при помощи оператора SET PAGE. Этот оператор, однако, не применим в режимах SCREEN 0÷4. Используя же псевдопеременную BASE, можно «работать» с экранными страницами в режимах SCREEN 0÷3. В режиме SCREEN 4 работа с экранными страницами запрещена. Приведём следующую табличку:

    Режим экрана 0(40) 0(80) 1 2 3 4 5 6 7 8
    Число разрешённых
    экранных страниц
    4 2 1 1 1 1 4 4 2 2
    Используется BASE Используется SET PAGE

Пример. Запись нескольких экранных страниц в режиме SCREEN 0 и их переключение.

Стандартный начальный адрес для Таблицы PNT в режиме SCREEN 0 равен 0. «Передвинем» эту таблицу вначале к адресу &H2000, а затем к адресу &H2400. Идентифицируем экранные страницы («что–нибудь» на них напишем!), а затем будем переключаться с одной страницы на другую путём переопределения начала Таблицы PNT в строках 100 и 110.

Заметим, что начальные адреса Таблиц PNT, PGT, SGT и SAT для текущего режима SCREEN хранятся в рабочей области, начиная с адресов &HF922, &HF924, &HF926 и &HF928 соответственно,и занимают по два байта каждый.

Эти значения не могут быть изменены оператором BASE: Вы должны сделать это сами (строка 110). Если Вы это не сделаете, то выход в непосредственный режим работы будет возможен только из нулевой страницы, а выйти на неё из другой страницы можно осуществить, если набрать «вслепую» команду
SCREEN М , где М — номер режима.


1111-01.bas
1111-01.bas

10 SCREEN 0:WIDTH 40
20 FOR I=0 TO 2
30    GOSUB 100:GOSUB 200 '──▶
40 NEXT I
50 IF INKEY$="" THEN 50
60 I=(I+1)MOD3:GOSUB 100 '──▶
70 GOTO 50
90 '∗∗∗∗∗ Подпрограмма 1 ∗∗∗∗∗
100 IF I=0 THEN BASE(0)=0 ELSE BASE(0)=&H2000+(I-1)*&H400
110 IF I=0 THEN  POKE &HF922,&H00:POKE &HF923,&H00
           ELSE  POKE &HF922,0:POKE &HF923,&H20+(I-1)*4'Запись в слово
                      ──▲───        ───▲──             ' NAMBAS
   Адрес младшего байта─┘              └─ Адрес старшего байта
120 RETURN '──▶
190 '∗∗∗∗∗ Подпрограмма 2 ∗∗∗∗∗
200 CLS:FOR J=0 TO 50:PRINT "PAGE";I;:NEXT:RETURN '──▶

XI.1.2. Функция VPEEK. Оператор VPOKE

Вы всегда можете посмотреть, какое число находится в той или иной ячейке видеопамяти. Для этого используется функция VPEEK, общий вид которой:

VPEEK(адрес)

,

где:

  • VPEEK («Video RAM PEEK») — служебное слово;
  • адрес — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,16383] для компьютеров MSX 1 и [0,65535] для компьютеров MSX 2. Нарушение этого условия приводит к сообщению об ошибке

    «Illegal function call».

Функция VPEEK возвращает содержимое ячейки VRAM с номером «адрес». Действия функций VPEEK и PEEK аналогичны.

Для записи данных в конкретную ячейку видеопамяти предназначен оператор VPOKE, синтаксис которого:

VPOKE адрес, данное

,

где:

  • VPOKE («Video RAM POKE») — служебное слово;
  • адрес — арифметическое выражение, целая часть значения которого должна принадлежать отрезку [0,16383] для компьютеров MSX 1 и отрезку [0,65535] для компьютеров MSX 2;
  • данное — арифметическое выражение, целая часть значения которого должна принадлежать отрезку [0,255].

Если хотя бы одно из значений параметров адрес или данное не удовлетворяет требуемым условиям, то компьютер сообщает об ошибке:

«Illegal function call».

Приведём простейший пример: вначале запишем в ячейку VRAM с номером 16383 число 10 командой VPOKE 16383,10, а затем «прочтём»содержимое этой ячейки:

print VPEEK(16383)
 10
Ok

Думаем, Вам ясна аналогия в действиях операторов VPOKE и POKE.

Если Вы посмотрите на структуру видеопамяти в различных экранных режимах, то заметите, что некоторые области видеопамяти не используются. Эти области могут служить в качестве дополнительного пространства для сохранения данных при помощи оператора VPOKE, когда RAM почти полностью использована! Однако при таком методе необходимо постоянно пользоваться нулевым текстовым режимом экрана — при смене режима Ваши данные будут уничтожены.

Пример 1. «Спрячем» числовой массив (кстати, а где оператор DIM ?!) в видеопамяти, а затем «извлечём его» оттуда.
1112-01.bas
1112-01.bas

10 SCREEN 0:WIDTH 40:ADR=4096 'Начальный адрес хранения данных в VRAM
20 INPUT"Число элементов массива";N
30 FOR T=1 TO N
40    INPUT"Очередной элемент";Z
50    FOR I=0 TO 7
60       VPOKE ADR+8*T+I,PEEK(VARPTR(Z)+I)
70 NEXT I,T
80 'Выведем элементы массива на экран
90 FOR T=1 TO N
100    IF VPEEK(ADR+8*T)\128=1 THEN Z$="-." ELSE Z$="+." 'Знак числа
110    FOR I=1 TO 7
120       Z$=Z$+RIGHT$("00"+HEX$(VPEEK(ADR+8*T+I)),2) 'Мантисса числа
130    NEXT I
140    IF(VPEEK(ADR+8*T) MOD 128)\64=1 THEN Z$=Z$+"E+" ELSE Z$=Z$+"E-"
150    Z$=Z$+MID$(STR$((VPEEK(ADR+8*T)MOD 128)-64),2) 'Порядок числа
160 U=VAL(Z$):PRINT U;:NEXT T

Пример 2.
1112-02.bas
1112-02.bas

10 TP=4096:SCREEN 0:WIDTH 38
30 INPUT"Имя (символ '*' - для окончания)";N$
40 IF LEFT$(N$,1)="*"THEN 120
50 IF TP+LEN(N$)+1>16383 THEN PRINT"Память заполнена":GOTO 120
60 FOR I=1 TO LEN(N$)
70      VPOKE TP,ASC(MID$(N$,I,1)):TP=TP+1
90 NEXT
100 VPOKE TP,0:TP=TP+1
110 GOTO 30
120 CLS:I=4096
140 X=VPEEK(I)
150 IF X=0 THEN PRINT:GOTO 170
160 PRINT CHR$(X)
170 I=I+1
180 IF I<TP THEN 140
190 END

Если скорость не является существенным фактором, то рассмотренный способ хранения данных в видеопамяти может быть весьма полезным, особенно для больших программ!

XI.1.3. Текстовые режимы


Они мастера накапливать факты, а вот извлечь из них пользу им удаётся не всегда.

Конан Дойль. Морской договор

Введём понятия общей ширины (высоты) экрана и доступной ширины (высоты) экрана.

Доступная ширина экрана — это область экрана, «доступная» текстовому курсору. Её размер устанавливается оператором WIDTH.

Общая ширина экрана однозначно определяется оператором SCREEN.

В режиме SCREEN 1 она равна 32 символам.

В режиме SCREEN 0 она устанавливается равной 40 символам, если аргумент в операторе WIDTH ≤ 40 и равной 80 символам в противном случае.

Общая высота экрана для текстовых режимов равна 24 символам, однако для режимов SCREEN 0 (80 символов) и SCREEN 1 она может быть равной 26.5 символам.

Для расположения символов в нужном Вам месте экрана используйте Таблицу имён образов (PNT)!

На рисунках показана нумерация возможных позиций курсора на текстовых экранах:

  • SCREEN 0 (40 символов)
    ┌───┬───┬─────┬───┬───┐
    │ 0 │ 1 │ ··· │ 38│ 39│
    ├───┴───┘     └───┴───┤
    │  ···    ···    ···  │
    ├───┬───┐     ┌───┬───┤
    │920│921│ ··· │958│959│
    └───┴───┴─────┴───┴───┘
  • SCREEN 0 (80 символов), высота экрана — 24 симв.
    ┌────┬────┬─────┬────┬────┐
    │  0 │  1 │ ··· │ 78 │ 79 │
    ├────┴────┘     └────┴────┤
    │   ···     ···     ···   │
    ├────┬────┐     ┌────┬────┤
    │1840│1841│ ··· │1918│1919│
    └────┴────┴─────┴────┴────┘
  • SCREEN 1 , высота экрана — 24 симв.
    ┌───┬───┬─────┬───┬───┐
    │ 0 │ 1 │ ··· │ 30│ 31│
    ├───┴───┘     └───┴───┤
    │  ···    ···    ···  │
    ├───┬───┐     ┌───┬───┤
    │744│745│ ··· │766│767│
    └───┴───┴─────┴───┴───┘

Чтобы изобразить символ в нужном месте экрана,используйте оператор:

VPOKE BASE(5*T)+W,K

,

где:

  • T — номер режима экрана (0 или 1);
  • W — номер позиции символа на экране;
  • K — код ASCII символа.

Пример 1. Вывести «A» (код ASCII 65) в 8–й строке и 10–м столбце экрана SCREEN 0:
1113-01.bas
1113-01.bas

10 SCREEN 0:WIDTH 40
20 VPOKE BASE(5*T)+40*8+10,65
                      ▲ ▲
  Номер строки экрана─┘ └─ Номер столбца экрана

Описанная возможность позволяет, например, выводить информацию в те места экрана, которые недоступны для вывода оператором PRINT.

Пример 2. Обратите внимание на то, что общая ширина экрана и доступная ширина экрана — различны!
1113-02.bas
1113-02.bas

10 TIME=0:INTERVAL ON:ON INTERVAL=60 GOSUB 100
20 GOTO 20 'Место для основной программы.
100 WIDTH 28:T1=INT(TIME/3600):T2=T2+1:IF T2=60 THEN T2=0
110 FOR J=0 TO 1
120 VPOKE 40+J,ASC(MID$(RIGHT$("0"+MID$(STR$(T1),2),2),J+1)):VPOKE 42,ASC(":")
130 VPOKE 43+J,ASC(MID$(RIGHT$("0"+MID$(STR$(T2),2),2),J+1)):NEXT:RETURN

Оказывается, можно одновременно «хранить» содержимое нескольких экранных страниц, причём в любой момент можно «открыть» любую страницу и «прочесть» её содержимое.

Вывод информации на нулевую страницу предполагает использование операторов PRINT или VPOKE. Для остальных же страниц вывод информации оператором PRINT невозможен, и поэтому приходится пользоваться оператором VPOKE.

Вы всегда можете изобразить любой символ в нужном месте любой экранной страницы при помощи оператора:

VPOKE 4096*T*(N+1)^2+W,K

,

где:

  • T — номер страницы;
  • N — режим экрана (0 или 1);
  • W — номер позиции символа на экране;
  • K — код ASCII символа.

При этом Вы сможете увидеть содержимое только нулевой страницы. Чтобы «просмотреть содержимое» других страниц, воспользуйтесь псевдопеременной BASE.

Пример 3. «Полистаем» экранные страницы!
1113-03.bas
1113-03.bas

NEW
Ok                                   ┌─ Код символа "SPACE"("пробел")
10 FOR T=1 TO 3                      ▼
20     FOR D=0 TO 959:VPOKE 4096*T+D,32:NEXT D 'Очистка T-ой страницы
30     PRINT "Введите"T"слово";:INPUT A$
40     PRINT "С какого места печатать?"
50     INPUT "X(от 0 до 39)";VX:INPUT "Y(от 0 до 23)";VY
60   FOR B=1 TO LEN(A$)
70    VPOKE 4096*T+40*VY+VX+B,ASC(MID$(A$,B,1))'Запись на T-ю страницу
80   NEXT B:NEXT T
90  FOR T=1 TO 3:Z$=INPUT$(1): BASE(0)=4096*T '4096=&H1000 ──▶ &H10 00
95    POKE &HF923, &H10*T: POKE &HF922, 0*T 'Чтение с экрана
           ──▲───               ───▲──
             └ Адрес старшего байта└ Адрес младшего байта
97  NEXT T
100 A$=INPUT$(1):BASE(0)=0:POKE &HF923,0 'Вывод "содержимого" 0-й страницы

Внимание! Страницы могут быть «засорены» посторонней информацией, оставшейся от прежнего обращения к ним. Ваши сообщения могут затеряться среди этого «мусора». Поэтому рекомендуем своевременно заботиться о чистоте страниц (посмотрите на строку 20 примера 3)!

Приведём структуру Таблицы имён образов (PNT) для 80–символьного режима SCREEN 0 в соответствии с расположением символов на экране дисплея:

0–й байт код символа в 0–ой строке и 0–ом столбце экрана
1–й байт код символа в 0–ой строке и 1–ом столбце экрана
79–й байт код символа в 0–ой строке и 79–ом столбце экрана
80–й байт код символа в 1–ой строке и 0–ом столбце экрана
1919–й байт код символа в 23–ой строке и 79–ом столбце экрана

Приведём структуру Таблицы имён образов (PNT) для режима SCREEN 1 в соответствии с расположением символов на экране дисплея:

0–й байт код символа в 0–ой строке и 0–ом столбце экрана
1–й байт код символа в 0–ой строке и 1–ом столбце экрана
31–й байт код символа в 0–ой строке и 31–ом столбце экрана
32–й байт код символа в 1–ой строке и 0–ом столбце экрана
767–й байт код символа в 23–ой строке и 31–ом столбце экрана

Структуру Таблицы имён образов(PNT) для 40–символьного режима SCREEN 0 в соответствии с расположением символов на экране дисплея Вы теперь легко изобразите самостоятельно!

Информация о символах, имеющихся на клавиатуре компьютера, находится в ROM, начиная с адреса &H1BBF, и занимает 2 Кбайта памяти. При переходе в режимы SCREEN 0 или SCREEN 1 эта информация автоматически копируется в видеопамять, инициализируя тем самым Таблицу шаблонов образов (PGT).

Место в ROM и видеопамяти, предназначенное для записи одного символа, занимает восемь байт.

Адрес начала места, отведённого для символа в видеопамяти, можно определить обращением к функции BASE:

BASE(5*N+2)+K*8

где:

  • N — номер режима экрана (0 или 1);
  • K — код ASCII символа.

Приведём пример «хранения» информации о символе в ROM и VRAM (справа для каждого байта выписан его шестнадцатеричный код, который и задаёт содержимое данного байта):

          ┌───┬───┬───┬───┬───┬───┬───┬───┐
0–й  байт │   │   │   │   │   │   │   │   │  &H00
          ├───┼───┼───┼───┼───┼───┼───┼───┤
1–й  байт │   │   │   │   │   │   │   │   │  &H00
          ├───┼───┼───┼───┼───┼───┼───┼───┤
2–й  байт │   │ █ │   │   │   │   │ █ │   │  &H42
          ├───┼───┼───┼───┼───┼───┼───┼───┤
3–й  байт │ █ │   │   │   │   │   │   │ █ │  &H81
          ├───┼───┼───┼───┼───┤───┼───┼───┤
4–й  байт │ █ │   │   │   │   │   │   │ █ │  &H81
          ├───┼───┼───┼───┼───┼───┼───┼───┤
5–й  байт │ █ │   │   │   │   │   │   │ █ │  &H81
          ├───┼───┼───┼───┼───┼───┼───┼───┤
6–й  байт │ █ │   │   │ █ │ █ │   │   │ █ │  &H99
          ├───┼───┼───┼───┼───┼───┼───┼───┤
7–й  байт │   │ █ │ █ │   │   │ █ │ █ │   │  &H66
          └───┴───┴───┴───┴───┴───┴───┴───┘
            8   4   2   1   8   4   2   1

Расскажем Вам о том, как можно получить «содержимое» конкретного байта видеопамяти. Разобьём каждый байт на две половинки (два полубайта). Под рисунком для каждого полубайта изображено по 4 числа (каждое из них назовём «весом»). Код полубайта получим суммированием «весов» точек, содержащихся в нем (напомним шестнадцатеричные цифры: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F). Код байта получим, если справа от кода левого полубайта напишем код правого полубайта, а слева — символ «&H».

Внимание! Только режим SCREEN 0, а в компьютере серии MSX 2 также и режимы SCREEN 6 и SCREEN 7, поддерживают вывод символов размером 6×8 точек; остальные режимы используют размер 8×8. Приведём пример вывода одного и того же символа в двух режимах:

         SCREEN 0                        SCREEN 1
┌───┬───┬───┬───┬───┬───┐   ┌───┬───┬───┬───┬───┬───┬───┬───┐
│   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┤   ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┤   ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │ █ │   │   │   │   │   │   │ █ │   │   │   │   │ █ │   │
├───┼───┼───┼───┼───┼───┼   ├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │   │   │   │   │   │   │ █ │   │   │   │   │   │   │ █ │
├───┼───┼───┼───┼───┼───┤   ├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │   │   │   │   │   │   │ █ │   │   │   │   │   │   │ █ │
├───┼───┼───┼───┼───┼───┤   ├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │   │   │   │   │   │   │ █ │   │   │   │   │   │   │ █ │
├───┼───┼───┼───┼───┼───┤   ├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │   │   │ █ │ █ │   │   │ █ │   │   │ █ │ █ │   │   │ █ │
├───┼───┼───┼───┼───┼───┤   ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │ █ │ █ │   │   │ █ │   │   │ █ │ █ │   │   │ █ │ █ │   │
└───┴───┴───┴───┴───┴───┘   └───┴───┴───┴───┴───┴───┴───┴───┘

Важно отметить, что в языке MSX BASIC есть возможность программным путём создавать «собственные» символы (отличные от стандартных!). Взгляните на приведённые ниже примеры.

Пример 4.
1113-04.bas
1113-04.bas

              Код ASCII символа "у"┐
5  SCREEN 0:WIDTH 40               ▼
10 FOR I=0 TO 7:READ M:VPOKE 2048+213*8+I,M:NEXT
20 DATA &H00,&H00,&H42,&H81,&H81,&H81,&H99,&H66

Данные в операторе DATA определяют шестнадцатеричные коды каждого байта «нового» символа. Число 213 в операторе VPOKE означает, что «построенному» нами символу присваивается код ASCII, равный 213. Если раньше коду 213 соответствовал символ «у», то теперь это место занял символ, который мы «сконструировали». Поэтому в тех местах экрана дисплея, где встречался символ «у», Вы увидите новый символ.

Пример 5.
1113-05.bas
1113-05.bas

5  SCREEN 0:WIDTH 80
10 FOR I=0 TO 7:READ M:VPOKE &h1000+213*8+I,M:NEXT
20 DATA &H00,&H00,&H42,&H81,&H81,&H81,&H99,&H66

Пример 6.
1113-06.bas
1113-06.bas

5 PRINT"Вводите последовательно байты шаблона символа:"
10 FOR I=0 TO 7:INPUT T(I):NEXT
20 INPUT"Введите код изменяемого символа";K%
30 FOR I=0 TO 7:VPOKE 2048+K%*8+I,T(I):NEXT

Отметим, что вместо переменной K% можно использовать любое арифметическое выражение, целая часть значения которого определяет код ASCII заменяемого символа. А теперь взгляните на следующую программу!

Пример 7. Изображение «псевдослучайных» символов.
1113-07.bas
1113-07.bas

10 P=RND(-TIME):FOR I=0 TO 7:T(I)=INT(255*RND(1)):NEXT
20 K=INT(223*RND(1)+31)
30 FOR I=0 TO 7:VPOKE 2048+K*8+I,T(I):NEXT:PRINT K,CHR$(K)

После выполнения этой программы нажмите на кнопку RESET.

Отметим, что при выполнении оператора SCREEN 0 (или SCREEN 1) Таблица шаблонов образов (PGT) инициализируется вновь данными из ROM!

Ещё ряд примеров на изменение шаблонов символов:

Пример 8 [76]. «Мелкие» и обычные буквы латинского алфавита.
1113-08.bas
1113-08.bas

40 SCREEN 0:KEY OFF
50 BASE(2)=2048
60 PRINT"Загрузка данных":PRINT
70 FOR I=4616 TO 4823
80    READ A$:VPOKE I,VAL("&h"+A$)
90    VPOKE I+256,VAL("&h"+A$)
100 NEXT
120 PRINT"Нажмите клавишу для изменения"
130 PRINT"      набора символов"
140 A$=INPUT$(1)
160 BASE(2)=4096
180 ' Б у к в ы  а л ф а в и т а
200 DATA 00,00,70,88,F8,88,88,00:'A
210 DATA 00,00,F0,48,70,48,F0,00:'B
220 DATA 00,00,78,80,80,80,78,00:'C
230 DATA 00,00,F0,88,88,88,F0,00:'D
240 DATA 00,00,F0,80,E0,80,F0,00:'E
250 DATA 00,00,F0,80,E0,80,80,00:'F
260 DATA 00,00,78,80,B8,88,70,00:'G
270 DATA 00,00,88,88,F8,88,88,00:'H
280 DATA 00,00,70,20,20,20,70,00:'I
290 DATA 00,00,70,20,20,A0,E0,00:'J
300 DATA 00,00,90,A0,C0,A0,90,00:'K
310 DATA 00,00,80,80,80,80,F8,00:'L
320 DATA 00,00,88,D8,A8,88,88,00:'M
330 DATA 00,00,88,C8,A8,98,88,00:'N
340 DATA 00,00,F8,88,88,88,F8,00:'O
350 DATA 00,00,F0,88,F0,80,80,00:'P
360 DATA 00,00,F8,88,A8,90,E8,00:'Q
370 DATA 00,00,F8,88,F8,A0,90,00:'R
380 DATA 00,00,78,80,70,08,F0,00:'S
390 DATA 00,00,F8,20,20,20,20,00:'T
400 DATA 00,00,88,88,88,88,70,00:'U
410 DATA 00,00,88,88,90,A0,40,00:'V
420 DATA 00,00,88,88,A8,D8,88,00:'W
430 DATA 00,00,88,50,20,50,88,00:'X
440 DATA 00,00,88,50,20,20,20,00:'Y
450 DATA 00,00,F8,10,20,40,F8,00:'Z

Пример 9. Автограф программиста!
1113-09.bas
1113-09.bas

10 COLOR15,1,1:SCREEN 1
20 J=33:KEYOFF
30 DATA 0000000000000003,00001E214346E098,0000000000000000,0001010101097595,C850408000000000,0409090701010262,840404081C026291,0202444464505162,89A1C10F32C20206,000000E010080810,938584C870000000,0102847800000000,0202010000000000,0A33C20000000000,906000000
40 READ A$:FOR T=2 TO 16 STEP 2:VPOKE8*J+T/2-1,VAL("&h"+MID$(A$,T-1,2)):NEXT
50 IF J<47 THEN J=J+1:GOTO 40
60 A$=CHR$(33)+CHR$(34)+CHR$(35)+CHR$(36)+CHR$(37)+CHR$(29)+CHR$(29)+CHR$(29)+CHR$(29)+CHR$(29)+CHR$(31)+CHR$(38)+CHR$(39)+CHR$(40)+CHR$(41)+CHR$(42)+CHR$(29)+CHR$(29)+CHR$(29)+CHR$(29)+CHR$(29)+CHR$(31)+CHR$(43)+CHR$(44)+CHR$(45)+CHR$(46)+CHR$(47)
70 LOCATE 2,2:PRINTA$
80 GOTO 80

Пример 10. «Изготовление» «толстых» символов!
1113-10.bas
1113-10.bas

5 SCREEN 1:A1=0:A2=255        ' Имеющийся шаблон символа сдвигается
10 FOR X=A1*8 TO A2*8+7       ' на один разряд и складывается со
20 D=VPEEK(X):VPOKE X,D OR D/2'              "старым".
30 NEXT


Целью придумавших систему было, очевидно, скрыть, что в этих значках содержится какой–то смысл.

Конан Дойль. Пляшущие человечки

Пример 11. Бегущий человечек.
1113-11.bas
1113-11.bas

5 COLOR 15,1,1:CLS:INPUT"Укажите желаемую скорость движения человечка (чем больше число - тем меньше скорость)";C
10 CLS:SCREEN 1,2,90:DIM A$(50):J=100
30 DATA 0C0C7ADE38EC8406,03030E171607050A,0000010301000701
60 DATA C0C0808080C08080,0000000101000000,3030E078606050A0
90 READA$:FOR T=2 TO 16 STEP 2:VPOKE 8*J+T/2-1,VAL("&h"+MID$(A$,T-1,2)):NEXT
100 IF J<105 THEN J=J+1:GOTO 90 '──▶
110 A$(0)=CHR$(100)+" ":A$(1)=CHR$(101)+" ":A$(2)=CHR$(102)+CHR$(103)
140 A$(3)=CHR$(104)+CHR$(105)
150 FOR I=0 TO 3:LOCATE Y,7:PRINT" ";A$(I)
165 FOR W=0 TO C:NEXT
166 IF Y=27 THEN Y=0
170 NEXT:Y=Y+1:A$=INKEY$:IF A$=" " THEN END
171 GOTO 150 '──▶

Приведём шаблоны четырёх символов из шести,сформированных в данной программе:

┌───┬───┬───┬───┬───┬───┬───┬───┐       ┌───┬───┬───┬───┬───┬───┬───┬───┐
│   │   │   │   │ █ │ █ │   │   │0C   03│   │   │   │   │   │   │ █ │ █ │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │ █ │ █ │   │   │0C   03│   │   │   │   │   │   │ █ │ █ │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │ █ │ █ │ █ │ █ │   │ █ │   │7A   0E│   │   │   │   │ █ │ █ │ █ │   │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │ █ │   │ █ │ █ │ █ │ █ │   │DE   17│   │   │   │ █ │   │ █ │ █ │ █ │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │ █ │ █ │ █ │   │   │   │38   16│   │   │   │ █ │   │ █ │ █ │   │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │ █ │ █ │   │ █ │ █ │   │   │EC   07│   │   │   │   │   │ █ │ █ │ █ │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │   │   │   │   │ █ │   │   │84   05│   │   │   │   │   │ █ │   │ █ │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │ █ │ █ │   │06   0A│   │   │   │   │ █ │   │ █ │   │
└───┴───┴───┴───┴───┴───┴───┴───┘       └───┴───┴───┴───┴───┴───┴───┴───┘
┌───┬───┬───┬───┬───┬───┬───┬───┐       ┌───┬───┬───┬───┬───┬───┬───┬───┐
│   │   │   │   │   │   │   │   │00   C0│ █ │ █ │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │00   C0│ █ │ █ │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │ █ │01   80│ █ │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │ █ │ █ │03   80│ █ │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │ █ │01   80│ █ │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │00   C0│ █ │ █ │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │ █ │ █ │ █ │07   80│ █ │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┤       ├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │ █ │01   80│ █ │   │   │   │   │   │   │   │
└───┴───┴───┴───┴───┴───┴───┴───┘       └───┴───┴───┴───┴───┴───┴───┴───┘

В режиме SCREEN 1 Таблица цветов (CT) позволяет, вообще говоря, выводить текст, символы которого имеют разные цвета. Однако, учтите, что каждый из 32 байтов Таблицы CT действует на группу из 8 символов, причём за цвет изображения данной группы «отвечает» старший полубайт, а младший полубайт «отвечает» за цвет фона символов.

Байт Таблицы CT

Цвет изображения восьми символовЦвет фона восьми символов
8 7 6 5 4 3 2 1

Пример 12. Вывод семи первых прописных букв латинского алфавита и символа «@» в «инвертированном» цвете:
1113-12.bas
1113-12.bas

10 SCREEN 1:COLOR 15,4,7
20 VPOKE &H2008,&H4F

Адрес Таблицы CT (&H2000+8) связан с символами, у которых коды ASCII принадлежат отрезку [64,71] (символы @, A, B, C, D, E, F, G). Если Вы хотите напечатать в «инвертированном» цвете символ «H» (восьмую букву латинского алфавита),то адрес &H2009 видеопамяти должен быть загружен значением &H4F. Это приведёт к выводу в «инвертированном» цвете восьми символов: H, I, J, K, L, M, N, O.

Пример 13. Изменение цвета символов (напомним,что начальный адрес Таблицы цветов &H2000 = 8192).
1113-13.bas
1113-13.bas

40 SCREEN 1:COLOR 15,4,4
50 FOR I=0 TO 255:PRINT CHR$(I);:NEXT
60 FOR I=0 TO 255
70    FOR J=8192 TO 8223
80       VPOKE J,I
90       FOR K=1 TO 25:NEXT K
100   NEXT J
110 NEXT I

Пример 14. Изменение цвета курсора (напомним Вам, что код ASCII символа «█» равен 255).
1113-14.bas
1113-14.bas

SCREEN 1:VPOKE &H201F,&HFF

Далее, команда VPOKE BASE(1*5+1)+255\8,&H28 задаёт цвет курсора и цвет, которым через курсор «просвечивается» тот символ, на который курсор «наложен». Если оба этих цвета совпадают, то сам курсор и символ сливаются, создавая иллюзию непрозрачности курсора.

Обратите внимание на тот факт, что Таблица CT в режиме SCREEN 1 инициализируется оператором COLOR.

Пример 15. Не поленитесь, наберите приведённую ниже программу. Затем включите принтер, вставьте лист бумаги и запустите программу. Результаты её работы пригодятся Вам в дальнейшем!
1113-15.bas
1113-15.bas

10 KEYOFF:CLS
120 LOCATE 0,12,0:PRINT CHR$(27);"MFirst page ";:MP=1:INPUT MP:IF MP<1 OR MP>6 GOTO 120
130 PRINT:PRINT:POKE &HF418,1:DEFUSR=&H156
140 LPRINT CHR$(27);"c1";CHR$(27);"p0";CHR$(27);"T15";CHR$(27);">";CHR$(27);"Q";
150 IF MP=1 THEN I=0:LPRINT CHR$(27);"E (c) LHsoft     ver.2":LPRINT CHR$(27);"Q" ELSE I=43*MP-45
160 P=MP
170 GOSUB 460
180 IF P=1 THEN K=41 ELSE K=43
190 FOR N=1 TO K
200    GOSUB 260
210    I=I+1
220 NEXT N
230 LPRINT"└────┴─────┴────┴──────┴──────┴──────┴──────┴──────┴──────┴─────────────────────────────────┴─────────────────────────┘
240 LPRINT CHR$(12);:IF P<6 THEN PRINT CHR$(27);"MPut in a new sheet ";:QQ=USR(0):Q$=INPUT$(1):P=P+1:GOTO 170
250 CLS:KEYON:END
260 LPRINT"│    │     │    │      │      │      │      │      │      │                                 │                         │
270 LPRINT"│    │ ";
280 LPRINTUSING("###");I;
290 A1=I*8:A0=A1+2048:LPRINT" │ ";RIGHT$("0"+HEX$(I),2);" │";A0;"│ 0";HEX$(A0);" │ ";
300 LPRINTUSING("####");A1;
310 LPRINT" │ ";RIGHT$("000"+HEX$(A1),4);" │";
320 IF IMOD8=0 THEN LPRINT 8192+I/8;"│ ";HEX$(&H2000+I/8);" │";ELSE LPRINT"      │      │";
330 FOR T=0 TO 7:LPRINTUSING(" ###");PEEK(&H1BBF+I*8+T);:NEXT
340 LPRINT" │ ";
350 FOR T=0 TO 7:LPRINT RIGHT$("0"+HEX$(PEEK(&H1BBF+I*8+T)),2);" ";:NEXT
360 LPRINT"│";CHR$(13);"   ";CHR$(27);"N";CHR$(27);"S0008";
370 M=128
380 FOR K1=0 TO 7
390    D=0
400    FOR K2=7 TO 0 STEP-1
410    D=D*2
420    IF PEEK(&H1BBF+I*8+K2)ANDM THEN D=D+1
430 NEXT K2:LPRINT CHR$(D);:M=M/2:NEXT K1
440 LPRINT CHR$(27);"Q"
450 RETURN
460 PRINT CHR$(27);"MCurrent page is";P;
470 LPRINT"┌────┬──────────┬───────────────────────────┬─────────────┬───────────────────────────────────────────────────────────┐
480 LPRINT"│    │   Код    │        Адрес в  PGT       │  Адрес в CT │                                                           │
490 LPRINT"│Сим-│          ├─────────────┬─────────────┼─────────────┤                Стандартное значение                       │
500 LPRINT"│вол │  ASCII   │  SCREEN 0   │   SCREEN 1  │  SCREEN 1   │                                                           │
510 LPRINT"│    ├─────┬────┼──────┬──────┼──────┬──────┼──────┬──────┼─────────────────────────────────┬─────────────────────────┤
520 LPRINT"│    │ дес.│шест│ дес. │ шест.│ дес. │ шест.│ дес. │ шест.│            десятичное           │     шестнадцатеричное   │
530 LPRINT"├────┼─────┼────┼──────┼──────┼──────┼──────┼──────┼──────┼─────────────────────────────────┼─────────────────────────┤
540 RETURN

XI.1.4. Режимы SCREEN 2 и SCREEN 4


Есть медленно и умеренно, не пить во время еды, тщательно разжёвывать пищу и с лёгкостью вставать из–за стола с чувством, что мог бы съесть ещё.

Ж.Фрумузак

Разделим экран (размером 256×192 точек) на квадраты размером по 8×8 точек. Легко подсчитать, что мы получим 768 таких квадратов. Каждый из них имеет свой номер, который хранится в Таблице PNT. А так как максимальное целое число, которое можно «разместить» в одном байте памяти (в данном случае VRAM), равно 255, поэтому Таблицу PNT необходимо разбить на три области, каждая из которых будет отвечать за нумерацию только 256 квадратов.

При установке режимов SCREEN 2 или SCREEN 4 (при инициализации) в каждую треть Таблицы PNT последовательно заносятся целые числа от 0 до 255.

Адрес байта PNT, отвечающего за квадрат с номером n2, вычисляется при помощи арифметического выражения

BASE(5·N) + 256·n1 + n2

где:

  • N — номер режима SCREEN (2 или 4);
  • n1 — номер трети таблицы PNT, в которой находится квадрат;
  • n2 — номер квадрата.

Соответственно Таблице PNT, весь экран также разбивается на три области (каждая размером 256×64 точек), которые мы будем называть окнами.

┌───┬───┬─────────────────────┬───┐
│ 0 │ 1 │···               ···│ 31│
├───┴───┘                     └───┤
│  ···          Окно 0         ···│
├───┬───┐                     ┌───┤
│224│225│···               ···│255│
├───┼───┼─────────────────────┼───┤
│ 0 │ 1 │···               ···│ 31│
├───┴───┘                     └───┤
│  ···          Окно 1         ···│
├───┬───┐                     ┌───┤
│224│225│···               ···│255│
├───┼───┼─────────────────────┼───┤
│ 0 │ 1 │···               ···│ 31│
├───┴───┘                     └───┤
│  ···          Окно 2         ···│
├───┬───┐                     ┌───┤
│224│225│···               ···│255│
└───┴───┴─────────────────────┴───┘

Если мы захотим изменить «что–нибудь» в Таблице PNT, это немедленно скажется на изображении в соответствующем окне.

Таблица PNT редко используется при составлении программ. Более того, можно рассматривать структуру экрана, «забыв» о делении экрана на окна. Достаточно при этом мысленно пронумеровать квадраты экрана от 0 до 767.

Покажем, как можно использовать Таблицу PNT для копирования изображения в пределах одного экранного окна. Пусть, например, Вам нужно скопировать изображение из квадрата с номером A в квадрат с номером B.Для этого в байт Таблицы PNT, отвечающий за квадрат с номером B, поместите номер квадрата A. Этого достаточно для того, чтобы произошёл процесс копирования!

Пример 1.
1114-01.bas
1114-01.bas

10 COLOR 1,15:SCREEN 2
20 LINE(8,8)-(15,15),,BF 'Сформировано изображение в квадрате 33
30 A$=INPUT$(1)
40 VPOKE &H1800+40,33    'Скопировали его в квадрат 40
50 GOTO 50

Более того, Вы можете заранее (до того, как будете что–то рисовать на экране) «размножить» по нужным адресам номер определённого блока. Далее, Вам достаточно лишь заполнить изображением тот квадрат,номер которого был «размножен»,и, к Вашей радости,это изображение появится и в других местах!

Пример 2.
1114-02.bas
1114-02.bas

10 COLOR 1,15:SCREEN 2
20 VPOKE &H1800+40,33               'Квадрат 40 подготовлен для приема
30 A$=INPUT$(1)                     'копии из квадрата 33
40 LINE(8,8)-(15,15),,BF            'Сформировано изображение в 33-м и
50 GOTO 50                          'в 40-м квадрате

Если же Вы захотите скопировать какой–либо элемент в другое окно экрана, то Вам поможет работа с Таблицами PGT и CT,к рассмотрению которых мы и переходим.

Каждый квадрат 8×8 точек разобьём на 8 горизонтальных участков,которые будем называть линиями .

Информация о каждой линии (1 байт) содержится в Таблице PGT.

Следовательно, объем этой Таблицы равен 768×8 = 6144 байтам.

Адрес байта Таблицы PGT, отвечающего за расположение линии вычисляется при помощи арифметического выражения

BASE(5·N+2) + (256·n1+n2)·8 + k

где:

  • N — номер режима SCREEN;
  • n1 — номер окна;
  • n2 — номер квадрата в этом окне;
  • k — номер линии в этом квадрате.

Отметим, что если в Таблице PNT были изменения, то могут возникнуть затруднения при попытке «нарисовать» что–либо в квадрате с изменённым номером.

Пример 3.
1114-03.bas
1114-03.bas

10 COLOR 1,15:SCREEN 2
20 VPOKE 6144+40,VPEEK(6144+33)'Произошло изменение в Таблице PNT
30 A$=INPUT$(1)                'Ждем нажатия клавиши!
40 LINE(64,8)-(71,15),,BF      'Попытка вывести изображение в квадрате
50 GOTO 50                     '40 не привела к ожидаемому результату!

Так как информация о линии хранится в одном байте, то каждой точке линии соответствует определённый бит этого байта. Оказывается, что «высветить точку на экране» — это значит установить нужный бит в 1,«стереть точку с экрана» — это значит установить бит в 0 !

Если некоторый бит равен 0,то соответствующую ему точку на экране будем называть точкой фона, в противном случае будем называть её точкой изображения.

Каждому байту Таблицы PGT однозначно соответствует один байт в Таблице цветов (CT), причём четыре младших бита этого байта кодируют локальный цвет фона для каждой линии, а четыре старших — локальный цвет изображения.

Например:

               Точки фона
        │    │    │              │    │
┌────┬──▼─┬──▼─┬──▼─┬────┬────┬──▼─┬──▼─┐
│  1 │  0 │  0 │  0 │  1 │  1 │  0 │  0 │  Байт PGT
└──▲─┴────┴────┴────┴──▲─┴──▲─┴────┴────┘
   │                   │    │
             Точки изображения
┌────┬────┬────┬────┬────┬────┬────┬────┐
│  0 │  1 │  0 │  1 │  1 │  1 │  0 │  1 │  Байт CT
└────┴────┴────┴────┴────┴────┴────┴────┘
 └────────▲────────┘ └────────▲─────────┘
          │                   │
   Цвет изображения       Цвет фона

Таким образом,точки изображения будут иметь цвет 5, а точки фона будут иметь цвет 13.

Так как из четырёх двоичных цифр можно составить только 16 комбинаций, то ясно, что

одновременно на экране может быть не более 16 цветов.

Вследствие этого, изменение цвета одной точки приводит к переопределению цвета изображения всей линии!

Адрес байта Таблицы CT, отвечающего за цвет линии, вычисляется при помощи арифметического выражения:

BASE(5·N+1) + (256·n1+n2)·8 + k

где:

  • N — номер режима SCREEN;
  • n1 — номер окна;
  • n2 — номер квадрата в этом окне;
  • k — номер линии в этом квадрате.

Пример 4. Предположим, что Вам захотелось в 5–й линии 58–го квадрата 2–го окна в режиме SCREEN 2 точки 0÷3 изобразить цветом 3, а точки 4÷7 — цветом 15.
1114-04.bas
1114-04.bas

10 SCREEN 2
20 A=BASE(5*2+1)+(256*2+58)*8+5
30 B=BASE(5*2+2)+(256*2+58)*8+5
40 VPOKE B,&B11110000
50 VPOKE A,&H3F
60 GOTO 60

А теперь — давно обещанный Вам пример…

Пример 5. Копирование содержимого 0–го квадрата из 0–го окна в содержимое 0–го квадрата 2–го окна
1114-05.bas
1114-05.bas

10 COLOR 15,1,1:SCREEN2
20 LINE(0,0)-(7,7),,BF
25 FOR I=0 TO 7
30 VPOKE BASE(5*2+2)+(256*2+0)*8+I,VPEEK(BASE(5*2+2)+(256*0+0)*8+I): 'Копирование изображения
35 VPOKE BASE(5*2+1)+(256*2+0)*8+I,VPEEK(BASE(5*2+1)+(256*0+0)*8+I): 'Копирования цвета
40 NEXT
50 GOTO 50

Пример 6. Изобразим квадрат,стороны которого имеют разные цвета, не используя оператор PSET.
1114-06.bas
1114-06.bas

10 SCREEN 2
14 DATA   0,5,1,37,2,37,4,37,8,165,4,165,2,165,1,21,0,5,0,5,128,133,64,133,32,133,64,21,128,21,0,5:'Фон синего цвета
15 FOR I=0 TO 1
16   FOR J=0 TO 7
20     A=BASE(5*2+2)+(256*0+I)*8+J
30     B=BASE(5*2+1)+(256*0+I)*8+J
40     READ Z,U:VPOKE A,Z:VPOKE B,U
60   NEXT J
70 NEXT I
80 GOTO 80

                ·
  Точки        · ·       Точки
зелёного   ──▶·   ·◀──  красного
  цвета      ·     ·     цвета
  Точки    ──▶·   ·◀──   Точки
 жёлтого       · ·      чёрного
  цвета         ·        цвета

Важно заметить, что Таблица CT инициализируется цветом фона, задаваемым в операторе COLOR.

Опишем алгоритм установки точки в режимах SCREEN 2 и SCREEN 4.

  1. 1. Первый шаг состоит в нахождении адреса байта Таблицы PGT в зависимости от координат (X,Y) («грубая настройка»).

    Адрес = ((Y\8)*32+Х\8)*8+Y MOD 8

    .

  2. 2. После этого нужно точно определить номер бита найденного байта, отвечающего за данную точку («точная настройка»). Трудность состоит в несоответствии номеров бит в байте и значений Х–координат тех точек, за которые этот байт отвечает:

    Х MOD 8 01234567
    Номер бита 76543210

    Формула, при помощи которой можно найти номер бита по Х–координате, выглядит следующим образом:

    NB = 2^(8+NOT(X MOD 8))

    .

  3. 3. Теперь остаётся записать «1» в найденный бит.

    VPOKE Адрес, VPEEK (Адрес) OR NB .

    И…точка появится в требуемом месте экрана.

  4. 4. Наконец, изменим цвет изображения выведенной точки:

    Адрес = Адрес + &h2000
    VPOKE  Адрес, VPEEK(Адрес) MOD 16 + COL*16

    ,

    • где COL — номер цвета.

Опишем алгоритм работы видеопроцессора при выводе содержимого квадрата 8×8 на графические экраны SCREEN 2 или SCREEN 4.

Предположим, что нам известно местоположение данного квадрата на экране. Пусть N — номер квадрата с координатами (X,Y) (0≤X≤31,0≤Y≤23)(номер N пока нам неизвестен!). Взгляните на рисунок:

     ┌───┬───┬─────────────────────┬───┐
 Y=0 │ 0 │ 1 │···               ···│ 31│
  ·  ├───┴───┘                     └───┤
  ·  │  ···                     ···    │ Окно 0
  ·  ├───┬───┐                     ┌───┤
 Y=7 │224│225│···               ···│255│
     ├───┼───┼─────────────────────┼───┤
 Y=8 │ 0 │ 1 │···       ┌───┐   ···│ 31│
  ·  ├───┴───┘         ┼▼┼  X      └───┤
  ·  │  ···        Y───▶N│      ···    │ Окно 1
  ·  ├───┬───┐         ┼─┼         ┌───┤
Y=15 │224│225│                  ···│255│
     ├───┼───┼─────────────────────┼───┤
Y=16 │ 0 │ 1 │                  ···│ 31│
  ·  ├───┴───┘                     └───┤
  ·  │  ···                     ···    │ Окно 2
  ·  ├───┬───┐                     ┌───┤
Y=23 │224│225│                  ···│255│
     └───┴───┴─────────────────────┴───┘

«Посмотрев» Таблицу PNT по адресу (Y\8)*256+(YMOD8)*32+X, найдём N.

«Запишем» информацию о квадрате в Таблицу PGT по адресам:

  • (Y\8)*2048+N*8,
  • (Y\8)*2048+N*8+1,
  • (Y\8)*2048+N*8+2,
  • (Y\8)*2048+N*8+3,
  • (Y\8)*2048+N*8+4,
  • (Y\8)*2048+N*8+5,
  • (Y\8)*2048+N*8+6,
  • (Y\8)*2048+N*8+7,

в результате на экране в квадрате (X,Y) Вы увидите то, что хотели!

А теперь «раскрасим» изображение.

«Запишем» информацию о цвете в Таблицу CT по адресам:

  • (Y\8)*2048+N*8 ,
  • (Y\8)*2048+N*8+1,
  • (Y\8)*2048+N*8+2,
  • (Y\8)*2048+N*8+3,
  • (Y\8)*2048+N*8+4,
  • (Y\8)*2048+N*8+5,
  • (Y\8)*2048+N*8+6,
  • (Y\8)*2048+N*8+7,

в результате квадрат с координатами (X,Y) будет раскрашен в нужные Вам цвета.

Пример 7.
1114-07.bas
1114-07.bas

10 COLOR 1,15,8:SCREEN 2:X=5:Y=10
20 N=VPEEK(BASE(5*2+0)+(Y\8)*256+(YMOD8)*32+X) 'Видеопроцессор "опрашивает" байт номер 69 в окне 1 Таблицы PNT и находит значение N (N=69, если Таблица PNT не изменялась)
30 FOR I=0 TO 7
40 VPOKE(&H800+N*8+I),&B11100011'Таблица PGT разделена на три окна,каждое из которых содержит по 2048 байтов. Следовательно, окно 1 этой Таблицы начинается по адресу 2048=&H800. 
41 '                             Первый из 8 байтов квадрата, на который указывает N в окне 1, размещается в ячейке &Н800+N*8
50 NEXT 'Содержимое этих 8 байтов и будет выведено в квадрате (X,Y)
60 GOTO 60

Пример 8.
1114-08.bas
1114-08.bas

10 SCREEN 2:X=15:Y=12
20 A=VPEEK(BASE(5*2+0)+(Y\8)*256+(YMOD8)*32+X) '"Смотрим" PNT
30 FOR I=0 TO 7
40   VPOKE(BASE(5*2+2)+(Y\8)*2048+A*8+I),&b11100011 'Формируем "содержимое" квадрата
50 NEXT
60 GOTO 60

Пример 9. Раскрасим выводимый квадрат 8–м и 10–м цветами.
1114-09.bas
1114-09.bas

10 SCREEN 2:X=15:Y=12
20 A=VPEEK(BASE(5*2+0)+(Y\8)*256+(YMOD8)*32+X) '"Смотрим" Таблицу PNT
30 FOR I=0 TO 7
40   VPOKE(BASE(5*2+2)+(Y\8)*2048+A*8+I),&B11100011 'Формируем "содержимое" квадрата
50 NEXT
60 FOR I=0 TO 7
70   VPOKE(BASE(5*2+1)+(Y\8)*2048+A*8+I),&H8A ' "Раскрасим" квадрат
80 NEXT
90 GOTO 90

Однако в режимах SCREEN 2 и SCREEN 4 используется система координат (X,Y), в которой Х изменяется от 0 до 255, а Y от 0 до 191. Следующий пример иллюстрирует, как эта система координат соотносится с делением экрана на квадраты.

Пример 10.
1114-10.bas
1114-10.bas

10 SCREEN 2:X=100:Y=75
30 N=(Y\8)*32+(X\8) 'Номер квадрата, в котором будет выведена точка
40 M=Y MOD 8        'Номер линии в квадрате
50 AP=N*8+M         'Адрес соответствующего байта в Tаблице PGT
60 VA=&b00001000
65 AC=AP+&H2000     'Для определения соответствующего адреса в Таблице CT прибавим &H2000 к адресу Таблицы PGT
70 VPOKE AP,VA      'Значение  VA=&B00001000  загрузим в PGT
80 VPOKE AC,&HF1    'Вводим значение &HF1 в Таблицу цветов для изображения точки белого цвета на черном фоне
90 IF INKEY$="" THEN 90
100 PSET(X,Y),6
110 GOTO 110

Сначала будет нарисована белая точка на чёрном фоне. Когда Вы нажмёте любую клавишу, эта точка приобретёт красный цвет.

При программировании на MSX BASIC этот способ формирования изображения применяется редко. Однако, если Вы хотите нарисовать что–либо с помощью программы на машинном языке, то приведённый выше алгоритм несомненно поможет Вам!

Ясно,что обладая определённым набором графических элементов, можно синтезировать различные графические изображения.

Приведём без комментариев ряд примеров:

Пример 11. Одинаковые шаблоны
1114-11.bas
1114-11.bas

20 COLOR 15,1,1:CLS:SCREEN 2:COLOR 15,1:CLS
60 FOR I=0 TO 7
70    READ A:VPOKE I,A:VPOKE I+2048,A:VPOKE I+4096,A
80 NEXT
90 FOR I=6144 TO 6144+767:VPOKE I,0:NEXT
120 FOR I=8192 TO 14435:VPOKE I,241:NEXT
150 GOTO 150
160 DATA &b11111111
170 DATA &b10011001
180 DATA &b10111101
190 DATA &b11100111
200 DATA &b11100111
210 DATA &b10111101
220 DATA &b10011001
230 DATA &b11111111

Пример 12.
1114-12.bas
1114-12.bas

10 COLOR 1,15,6:SCREEN 2
20 FOR T=8 TO 15:LINE(8,T)-(15,T),T:NEXT:A$=INPUT$(1)
30 FOR T=0 T0 7:VPOKE 2048+33*8+T,VPEEK(33*8+T):NEXT
40 A$=INPUT$(1)
50 FOR T=0 TO 7:VPOKE 10240+33*8+T,VPEEK(8192+33*8+T):NEXT
60 A$=INPUT$(1)

Пример 13.
1114-13.bas
1114-13.bas

10 'Шахматная доска!
20 INPUT "Координаты X,Y";X,Y:X=X-XMOD8:Y=Y-YMOD8
21 IF X=0 THEN X=8
22 U=Y/8*32+X/8
25 COLOR 1,15,1:SCREEN 2
30 FOR T=0 TO 3:FOR I1=0 TO 1:FOR I2=0 TO 1:FOR F=U TO U+12 STEP 4:FOR K=0 TO 1
40 VPOKE BASE(10)+(F+(64+2)*K)+I2+32*I1+128*T,VPEEK (BASE(10)):NEXT K,F,I2,I1,T
50 LINE(0,0)-(8,192),1,BF:LINE(X,Y)-STEP(128,128),1,B:A$=INPUT$(1)

Пример 14.
1114-14.bas
1114-14.bas

10 COLOR 1,15,8:SCREEN 2:LINE(0,64)-(255,127),,BF 'Фон!
20 LINE(0,64)-(7,71),8,BF 'Перемещаемый объект!
30 FOR T=1 TO 31
40 F=VPEEK(6400+T):VPOKE 6400+T,VPEEK(6400+T-1):VPOKE 6400+T-1,F'Обмен значений между ячейками видеопамяти!
50 IF T=31 THEN VPOKE 6400+T,T:VPOKE 6400,0
60 NEXT T:GOTO 30

Пример 15.
1114-15.bas
1114-15.bas

10 CLEAR 200,&HC300:SCREEN 2
20 CIRCLE(90,70),56:PAINT STEP(0,0) 'Сформировано изображение
25 'Сохраняем изображения в памяти (RAM)
30 FOR I=BASE(5*2+1) TO BASE(5*2+1)+6143:POKE &HC300-BASE(5*2+1)+I, VPEEK(I):NEXT
40 FOR I=BASE(5*2+2) TO BASE(5*2+2)+6143:POKE &HC300+6144-BASE(5*2+2)+I,VPEEK(I):NEXT
50 SCREEN 0
60 SCREEN 2 'Вывод изображения на экран
70 FOR I=BASE(5*2+1) TO BASE(5*2+1)+6143:VPOKE I,PEEK(&HC300-BASE(5*2+1)+I):NEXT
80 FOR I=BASE(5*2+2) TO BASE(5*2+2)+6143:VPOKE I,PEEK(&HC300-BASE(5*2+2)+6144+I):NEXT
90 A$=INPUT$(1) 'Программа работает ≈ 5 минут

XI.1.5. Режим SCREEN 3

Как и в режиме SCREEN 2, экран в режиме SCREEN 3 разбит на квадраты размером 8×8 точек (32×24 квадрата). Каждый квадрат разобьём на две линии толщиной четыре точки (на экране расположено 32×48 «толстых» линий). Каждая из этих «толстых» линий разбита на две «большие» точки (4×4 «маленьких» точек).

         ──▲──┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐
           │  │    │    │    │    │  │    │    │    │████│◀── "Маленькая"
           │  │────│────│────│────│  │────│────│────│────│       точка
  "Толщина"│  │    │    │    │    │  │    │    │    │    │
           │  │────│────│────│────│  │────│────│────│────│
    линии  │  │    │    │    │    │  │    │    │    │    │
           │  │────│────│────│────│  │────│────│────│────│
           │  │    │    │                      │    │    │
         ──▼──└────┴────┴────    Квадрат   ────┴────┴────┘
              ┌────┬────┬────              ────┬────┬────┐
              │    │    │    │    │  │████│████│████│████│
              │────│────│────│────│  │────│────│────│────│
"Толстая"     │    │    │    │    │  │████│████│████│████│
         ───▶ │────│────│────│────│  │────│────│────│────│ ◀── "Большая"
  линия       │    │    │    │    │  │████│████│████│████│       точка
              │────│────│────│────│  │────│────│────│────│
              │    │    │    │    │  │████│████│████│████│
              ├────┴────┴────┴────┘  └────┴────┴────┴────┤
              │◀─────────────"Длина" линии ─────────────▶│

Каждая из «больших» точек может быть раскрашена только в один цвет. Попытка расположить в «большой» точке «маленькую» точку другого цвета приведёт к изменению цвета всей «большой» точки.

Информация о цвете «толстой» линии находится в Таблице PGT, причём левый полубайт байта PGT кодирует цвет левой «большой» точки «толстой» линии, а правый полубайт отвечает за цвет правой «большой» точки.

                        Байт PGT
           ┌───┬───┬───┬───┬───┬───┬───┬───┐
           │ 1 │ 0 │ 0 │ 0 │ 1 │ 0 │ 1 │ 0 │
           └───┴───┴───┴───┴───┴───┴───┴───┘
            └──────▲──────┘ └──────▲──────┘
                   │               │
Цвет левой "большой" точки     Цвет правой "большой" точки

Поскольку один байт Таблицы PGT кодирует цвета «толстой» линии, то эта Таблица требует 32×48=1536 байт VRAM.

Пример 1.
1115-01.bas
1115-01.bas

10 SCREEN 3:OPEN"GRP:" AS#1
20 PSET(8,0),3:PSET(12,0),1 'Рисуем "толстую" линию
30 PSET(30,80):PRINT #1,HEX$(VPEEK(8))
40 A$=INPUT$(1)

Оператор COLOR с последующим оператором CLS инициализируют Таблицу PGT,

причём все байты Таблицы PGT инициализируются цветом фона, закодированным как в левом, так и в правом полубайтах.

А в следующей табличке показаны номера позиций «толстых» линий на экране:

┌────┬────┬────┬─────┬────┐
│  0 │  8 │ 16 │ ··· │ 248│
├────┼────┼────┼─────┼────┤
│  1 │  9 │ 17 │ ··· │ 249│
├────┼────┼────┼─────┼────┤
│  2 │ 10 │ 18 │ ··· │ 250│
├────┼────┼────┼─────┼────┤
│  3 │ 11 │ 19 │ ··· │ 251│
├────┼────┼────┼─────┼────┤
│  4 │ 12 │ 20 │ ··· │ 252│
├────┼────┼────┼─────┼────┤
│  5 │ 13 │ 21 │ ··· │ 253│
├────┼────┼────┼─────┼────┤
│  6 │ 14 │ 22 │ ··· │ 254│
├────┼────┼────┼─────┼────┤
│  7 │ 15 │ 23 │ ··· │ 255│
├────┼────┼────┼─────┼────┤
│ 256│ 264│ 272│ ··· │ 504│
├────┼────┼────┼─────┼────┤
│ 257│ 265│ 273│ ··· │ 505│
├────┼────┼────┼─────┼────┤
│ ···│ ···│ ···│ ··· │ ···│
├────┼────┼────┼─────┼────┤
│ 263│ 271│ 279│ ··· │ 511│
├────┼────┼────┼─────┼────┤
│ ···│ ···│ ···│ ··· │ ···│
├────┼────┼────┼─────┼────┤
│1285│1293│1301│ ··· │1534│
├────┼────┼────┼─────┼────┤
│1286│1294│1302│ ··· │1535│
└────┴────┴──│─┴─────┴────┘
  ┌──┬──┬──┬─▼┬──┬──┬──┬──┐
  │ 1│ 0│ 0│ 0│ 0│ 0│ 1│ 0│
  └──┴──┴──┴──┴──┴──┴──┴──┘

Пример 2. Выполнив эту программу Вы можете убедиться в правильности заполнения данной таблички.
1115-02.bas
1115-02.bas

NEW
Ok
10 SCREEN 3
20 VPOKE BASE(5*3+2)+6,&H56
30 VPOKE BASE(5*3+2)+7,&H34
40 VPOKE BASE(5*3+2)+8,&H78
50 VPOKE BASE(5*3+2)+9,&H9A
60 A$=INPUT$(1)

Байт из Таблицы PGT (в нем хранится цвет «толстой» линии с номером 1302)

Приведём таблицу, по которой можно определить адрес байта Таблицы PGT, отвечающего за точку (X,Y), в режимах 2÷4:

Режим экрана Адрес байта в PGT
2 и 4 ((Y\8)*32+(Х\8))*8+Y MOD 8
3 BASE(5*3+2)+(Х\8)*8+(Y\32)*256+(Y\4) MOD 8

Пример 1. Заполнение экрана чёрными и белыми клетками в шахматном порядке.
1115-11.bas
1115-11.bas

10 'Шахматная доска
20 COLOR 15,1,1:CLS:SCREEN 3
50 FOR I=0 TO 7 STEP 2
60    VPOKE I,&HF1:VPOKE I+1,&H1F
70 NEXT
80  FOR I=BASE(5*3+0) TO I+767
90     VPOKE I,0
100 NEXT
110 GOTO 110

Таблица PGT разбита на 192 «кусочка» размером по 8 байт. Каждый «кусочек» отвечает за 4 квадрата размером 2×2 «больших» точки (такой квадрат называется именем). Упомянутые 4 имени имеют один и тот же номер, который записывается в Таблицу PNT.

Но первый квадрат — это имя с данным номером для строк (строка имеет высоту 2 «большие» точки) с номерами 0, 4, 8, 12, 16, 20;

  • второй — для строк с номерами 1, 5, 9, 13, 17, 21;
  • третий — для строк с номерами 2, 6, 10, 14, 18, 22;
  • четвёртый — для строк с номерами 3, 7, 11, 15, 19, 23.

Следовательно, весь экран разбит на четыре окна (понятие экранного окна см. в описании режима SCREEN 2).

За имя с номером N в окне с номером M отвечают байты PGT

N·8+M·2 и N·8+M·2+1,

где N∈[0,191], a M∈[0,3]

Приведём структуру PGT с учётом разбивки экрана на имена и окна.

            ┌────┬────┬────┬─────┬────┐
Номер имени │  0 │  1 │  2 │ ··· │ 15 │
    N       ├────┼────┼────┼─────┼────┤
            ├────┼────┼────┼─────┼────┤ ─┐
            │  0 │  8 │ 16 │ ··· │ 248│  │
            ├────┼────┼────┼─────┼────┤  ├─ Имя с номером N для окна 0
            │  1 │  9 │ 17 │ ··· │ 249│  │
            ├────┼────┼────┼─────┼────┤ ─┤
            │  2 │ 10 │ 18 │ ··· │ 250│  │
            ├────┼────┼────┼─────┼────┤  ├─ Имя с номером N для окна 1
            │  3 │ 11 │ 19 │ ··· │ 251│  │
            ├────┼────┼────┼─────┼────┤ ─┤
            │  4 │ 12 │ 20 │ ··· │ 252│  │
            ├────┼────┼────┼─────┼────┤  ├─ Имя с номером N для окна 2
            │  5 │ 13 │ 31 │ ··· │ 253│  │
            ├────┼────┼────┼─────┼────┤ ─┤
            │  6 │ 14 │ 22 │ ··· │ 254│  │
            ├────┼────┼────┼─────┼────┤  ├─ Имя с номером N для окна 3
         │  │  7 │ 15 │ 23 │ ··· │ 255│  │
        ─▼─ ├────┼────┼────┼─────┼────┤ ─┘
            │ ···│ ···│ ···│ ··· │ ···│
            ├────┼────┼────┼─────┼────┤
            │ 263│ 271│ 279│ ··· │ 511│
            ├────┼────┼────┼─────┼────┤
            │ ···│ ···│ ···│ ··· │ ···│
            ├────┼────┼────┼─────┼────┤ ─┐
            │1285│1293│1301│ ··· │1534│  │
            ├────┼────┼────┼─────┼────┤  ├─ Имя с номером N для окна 3
            │1286│1294│1302│ ··· │1535│  │
            └────┴────┴────┴─────┴──▲─┘ ─┘
                                    └─ Имя с номером 191

Приведём структуру PNT с номерами имён и их расположением на экране:

      0   1   2   3   ·   ·   ·   31 ◀─ Номер столбца
    ┌───┬───┬───┬───┬───┬───┬───┬────┐
  0 │ 0 │ 1 │ 2 │ 3 │···│···│···│ 31 │  Окно 0: строки 0,4, 8,12,16,20
    ├───┼───┼───┼───┼───┼───┼───┼────┤
  1 │ 0 │ 1 │ 2 │···│···│···│ 30│ 31 │  Окно 1: строки 1,5, 9,13,17,21
    ├───┼───┼───┼───┼───┼───┼───┼────┤
  2 │ 0 │ 1 │···│···│···│ 29│ 30│ 31 │  Окно 2: строки 2,6,10,14,18,22
    ├───┼───┼───┼───┼───┼───┼───┼────┤
  3 │ 0 │···│···│···│ 28│ 29│ 30│ 31 │  Окно 3: строки 3,7,11,15,19,23
    ├───┼───┼───┼───┼───┼───┼───┼────┤
  4 │ 32│ 33│ 34│ 35│···│ 61│ 62│ 63 │
    ├───┼───┼───┼───┼───┼───┼───┼────┤
  · │···│···│···│···│···│···│···│ ···│
    ├───┼───┼───┼───┼───┼───┼───┼────┤
  7 │ 32│33 │···│···│···│···│ 62│ 63 │
    ├───┼───┼───┼───┼───┼───┼───┼────┤
  · │···│···│···│···│···│···│···│ ···│
    ├───┼───┼───┼───┼───┼───┼───┼────┤
  23│160│161│···│···│···│189│190│ 191│
  ▲ └───┴───┴───┴───┴───┴───┴───┴────┘
  └─ Номер строки

Номер имени в квадрате с координатами X,Y (X∈[0,31],Y∈[0,23]) хранится в ячейке VRAM с адресом:

BASE(5*3+0)+(Y\4)*32+X

Это имя находится в окне с номером Y MOD 4

Пример 2.
1115-12.bas
1115-12.bas

10 COLOR 15,1,1:CLS:SCREEN 3
20 FOR I=0 TO 1 STEP 2
30   VPOKE I,&HF1:VPOKE I+1,&H1F   'Имя 0 для окна 0 (черно-белое)
40   VPOKE I+2,&HF8:VPOKE I+3,&H8F 'Имя 0 для окна 1 (красно-белое)
45 'Имя с номером 0 для окон 2 и 3 - пустое
60 NEXT
70 FOR I=BASE(5*3+0) TO I+767      ' Заполним PNT нулями
80     VPOKE I,0
90 NEXT
95 'На экране появятся 6 (24/4) черно-белых и красно-белых полос
100 GOTO 100

XI.1.6. Режимы SCREEN 5, SCREEN 6, SCREEN 7 и SCREEN 8 (для компьютеров MSX 2)

В режимах SCREEN 5 ÷ SCREEN 8 Таблицы PGT и CT отсутствуют!

Поэтому вся информация об изображении точек находится в Таблице PNT.

В отличие от рассмотренных ранее режимов, эти режимы не имеют деления экрана на квадраты.

Вначале приведём важную табличку, которая поможет Вам определить адрес байта Таблицы PNT, отвечающего за точку с координатами (X,Y), в различных режимах SCREEN>:

Режим экрана Адрес байта в PNT
SCREEN 5 BASE(5*5)+(256/2)*Y+(X\2)
SCREEN 6 BASE(5*6)+(512/4)*Y+(X\4)
SCREEN 7 BASE(5*7)+(512/2)*Y+(X\2)
SCREEN 8 BASE(5*8)+(256/1)*Y+(X\1)
  1. В режиме SCREEN 5 экран разделен на 212 строк, состоящих из 256 точек каждая, или на 192 строки, состоящих из 256 точек каждая. Совокупность двух точек по горизонтали будем называть линией (точки 0 и 1 образуют 1–ю линию, точки 2 и 3 — 2–ю линию ,… , точки 254 и 255 — 128–ю линию).

    Каждая линия кодируется в одном байте, причём четыре старших бита этого байта определяют цвет первой точки, а четыре младших — цвет второй точки. Ясно, что требуется 212×256/2=27136 байтов для хранения сведений о цветах линий (как раз объем Таблицы PNT в режиме SCREEN 5 !).

    Первый байт Таблицы PNT «хранит» информацию о цвете первой линии первой строки экрана, второй байт — о цвете второй линии той же строки, и так далее:

    1–й байт Таблицы PNT 2–й байт Таблицы PNT
    Цвет 1–й точки
    первой линии
    Цвет 2–й точки
    первой линии
    Цвет 1–й точки
    второй линии
    Цвет 2–й точки
    второй линии

    Таблица PNT инициализируется цветом фона, который устанавливается оператором COLOR.

    Пример 1. Изобразим в режиме SCREEN 5 точку с координатами (X,Y) белым цветом.
    1116-01.bas
    1116-01.bas

    10 COLOR 15,4,7:INPUT"X,Y";X,Y
    20 SCREEN 5                        ┌───────── Код цвета фона
    30 AD=BASE(5*5)+Y*128+(X\2)        │┌──────── Код цвета изображения
                                       ▼▼
    40 IF XMOD2=0 THEN C=&HF4 ELSE C=&H4F'Если не будет этого условия, то изобразятся две соседние точки
    50 VPOKE AD,C   'Вы легко можете убедиться,что этот оператор эквивалентен оператору PSET(X,Y),15.
    60 GOTO 60

    Приведём схематическое изображение PNT для режима SCREEN 5.

    0–й байт отвечает за точки с координатами (0,0) и (1,0)
    1–й байт отвечает за точки с координатами (2,0) и (3,0)
    127–й байт отвечает за точки с координатами (254,0) и (255,0)
    128–й байт отвечает за точки с координатами (0,1) и (1,1)
    27134–й байт отвечает за точки с координатами (252,211) и (253,211)
    27135–й байт отвечает за точки с координатами (254,211) и (255,211)
  2. В режиме SCREEN 6 экран имеет 212 строк из 512 точек или 192 строки по 512 точек в каждой строке. Количество байтов в Таблице PNT точно такое же, как и в Таблице PNT режима SCREEN 5: информация об одной строке экрана кодируется в 128 байтах.

    Линия в режиме SCREEN 6 состоит из четырёх точек и кодируется в одном байте. А тогда палитра каждой точки кодируется в двух битах, а так как из двух двоичных цифр можно составить только четыре комбинации (00, 01, 10, 11), то каждую точку экрана можно раскрасить не более, чем четырьмя различными способами. Так, например, оператор

    VPOKE 0,&B11100100

    присваивает палитру 3 первой точке первой линии, палитру 2 — второй точке первой линии, палитру 1 — третьей точке первой линии и палитру 0 — четвёртой точке первой линии.

             Байт Таблицы PNT
    ┌───┬───┬───┬───┬───┬───┬───┬───┐
    │ 1 │ 1 │ 1 │ 0 │ 0 │ 1 │ 0 │ 0 │
    └───┴───┴───┴───┴───┴───┴───┴───┘
    └───▲───┘└──▲──┘└───▲───┘└──▲───┘
        │       │       │       │
     Палитра Палитра Палитра Палитра
     первой  второй  третьей четвёртой
     точки   точки    точки   точки

    Таблица PNT инициализируется последними двумя битами цвета фона, задаваемого в операторе COLOR.

    Поясним сказанное примером. Если цвет фона имеет номер 13=&B1101, то в каждый байт Таблицы PNT будет занесено число &B01010101 (четыре раза повторяются последние два бита кода цвета фона).

    Приведём схематическое изображение PNT для режима SCREEN 6.

    (0,0) (1,0) (2,0) (3,0) 0–й байт
    (4,0) (5,0) (6,0) (7,0) 1–й байт
    (508,0) (509,0) (510,0) (511,0) 127–й байт
    (0,1) (1,1) (2,1) (3,1) 128–й байт
    (508,211) (509,211) (510,211) (511,211) 27135–й байт
  3. Как и в режиме SCREEN 6,в режиме SCREEN 7 на экране расположено 212 строк, состоящих из 512 точек каждая, или 512 строк, состоящих из 192 строк каждая. Однако, один байт Таблицы PNT кодирует линию, состоящую из двух точек: старшие четыре бита определяют палитру левой точки, младшие четыре — палитру правой точки.

    1–й байт Таблицы PNT 2–й байт Таблицы PNT
    Палитра первой
    точки 1–й линии
    Палитра второй
    точки 1–й линии
    Палитра первой
    точки 2–й линии
    Палитра второй
    точки 2–й линии

    Следовательно, каждой точке может быть присвоена любая из 16 палитр.

    Поскольку для кодирования номера палитры необходимо четыре бита, то Таблица PNT занимает объем 212×512/2 = 54272 байта.

    Уже отсюда становится понятно, что для использования этого режима VRAM должна иметь объем не менее 128 Кбайт!

    Режим SCREEN 7 аналогичен режиму SCREEN 5, за исключением того, что в режиме SCREEN 7 в строке экрана в два раза больше точек.

    Таблица PNT инициализируется цветом фона, который устанавливает оператор COLOR.

    Приведём схематическое изображение PNT для режима SCREEN 7.

    0–й байт отвечает за точки с координатами (0,0) и (1,0)
    1–й байт │отвечает за точки с координатами (2,0) и (3,0)
    255–й байт │отвечает за точки с координатами (510,0) и (511,0)
    256–й байт отвечает за точки с координатами (0,1) и (1,1)
    54270–й байт отвечает за точки с координатами (508,211) и (509,211)
    54271–й байт отвечает за точки с координатами (510,211) и (511,211)
  4. В режиме SCREEN 8 экран состоит из 212 строк по 256 точек в каждой или из 212 строк по 192 точки в каждой.

    Линия состоит из одной–единственной точки. Цвет линии здесь уже определяется не кодом палитры, а непосредственным заданием «смеси» основных цветов. Этот оригинальный способ кодирования цвета требует по одному байту(!) на линию, а, значит, на точку! Поэтому Таблица PNT имеет объем 212·256=54272 байта.

    Уже отсюда становится понятно, что для использования этого режима VRAM должна иметь объем не менее 128 Кбайт!

    Информация о линии с координатами (X,Y) находится по адресу

    X+256·Y

    в Таблице PNT. Для высвечивания этой линии достаточно занести по этому адресу значение цвета из отрезка [0,255], которое можно найти по формуле:

    C = 32·G+4·R+B   ,

    где G, R, B — значения в диапазоне от 0 до 7, определяющие интенсивность зелёного («Green»), красного («Red») и синего («Blue») цветов соответственно. Например, цвету с номером 187=&b10111011 соответствует следующее «содержимое» байта Таблицы PNT:

              Байт Таблицы PNT
      ┌───┬───┬───┬───┬───┬───┬───┬───┐
      │ 1 │ 0 │ 1 │ 1 │ 1 │ 0 │ 1 │ 1 │
      └───┴───┴───┴───┴───┴───┴───┴───┘
      └──────────┘ └──────────┘└──────┘
    Интенсивность Интенсивность Интенсивность
       зелёного      красного      синего
       цвета          цвета        цвета

    При инициализации байты Таблицы PNT получают номер цвета фона (который изменяется в пределах от 0 до 255).

    Приведём схематическое изображение PNT для режима SCREEN 8.

    Базовый адрес PNT

    0–й байт отвечает за точку с координатами (0,0)
    1–й байт отвечает за точку с координатами (1,0)
    255–й байт отвечает за точку с координатами (255,0)
    256–й байт отвечает за точку с координатами (0,1)
    54270–й байт отвечает за точку с координатами (256,210)
    54271–й байт отвечает за точку с координатами (256,211)

XI.1.7. Таблица палитр (для компьютеров MSX 2)

Независимо от режима SCREEN, Таблица PT занимает в видеопамяти объём 32 байта. «Местоположение» этой Таблицы зависит от режима SCREEN.

Режим Адрес Комментарий
SCREEN 0 (40 символов) &H0400 Не используется в MSX 1
SCREEN 0 (80 символов) &H0800
SCREEN 1 &H2020 Не используется в MSX 1
SCREEN 2 &H1B80 Не используется в MSX 1
SCREEN 3 &H2020 Не используется в MSX 1
SCREEN 4 &H1E80
SCREEN 5 &H7680
SCREEN 6 &H7680 Используются палитры 0÷3
SCREEN 7 &HFA80
SCREEN 8 &HFA80 Не используется

Каждая из палитр закодирована в двух байтах.

Адрес AD первого байта палитры N в Таблице PT вычисляется по формуле:

AD=A0+2·N

где А0 — адрес начала Таблицы PT (например,в режиме SCREEN 1 Таблица PT начинается по адресу &h2020).

По адресу AD в Таблице PT находится байт, который мы назовём «красный–синий». Биты 4÷6 этого байта определяют пропорцию красного, а биты 0÷2 — пропорцию синего цвета. Байт Таблицы PT с адресом AD+1 определяет пропорцию зелёного цвета, закодированную в битах 0÷2 :

        7   6   5   4   3   2   1   0  ◀──  Номера бит
       ┌───┬───┬───┬───┬───┬───┬───┬───┐
  AD   │   │ ∗ │ ∗ │ ∗ │   │ ∗ │ ∗ │ ∗ │◀──────┐
       └───┴───┴───┴───┴───┴───┴───┴───┘       │
           └─────▲─────┘   └─────▲─────┘       │           Два
                 │               │              ◀──  последовательных
     Красный цвет ("Red")  Синий цвет ("Blue") │          байта
       ┌───┬───┬───┬───┬───┬───┬───┬───┐       │       Таблицы PT
AD+1   │   │   │   │   │   │ ∗ │ ∗ │ ∗ │◀──────┘
       └───┴───┴───┴───┴───┴───┴───┴───┘
                           └─────▲─────┘
                                 └── Зелёный цвет ("Green")

Пример 1. «Чтение» Таблицы палитр в режиме SCREEN 1. Выполнив программу, Вы узнаете, каким образом оператор SCREEN инициализирует Таблицу PT.
1117-01.bas
1117-01.bas

10 COLOR 1,15,7:SCREEN 1
20 ' :::::::::::::::
30  FOR N=0 TO 15
40     AD=&H2020+2*N
50     RB=VPEEK(AD):G=VPEEK(AD+1)'Обратите внимание на мнемонику имен: 'RB и G!
60     PRINT N;TAB(4);HEX$(RB);HEX$(G)
70  NEXT

Отметим, что оператор COLOR=(…) переопределяет байты Таблицы PT в соответствии с указанной палитрой.

Пример 2. Изменим Таблицу PT и вновь «прочитаем» её.
1117-02.bas
1117-02.bas

10 COLOR 1,15,7:SCREEN 1
20 GOSUB 30:COLOR=(7,7,2,7):GOSUB 30:COLOR=(7,7,7,4):GOSUB 30:END
30  FOR N=0 TO 15
40     AD=&H2020+2*N
50     RB=VPEEK(AD):G=VPEEK(AD+1)
60     PRINT N;TAB(4);HEX$(RB);HEX$(G)
70  NEXT
80 A$=INPUT$(1):CLS:RETURN

Как видите, байты, соответствующие палитре 7,изменяются; немедленно изменяется и цвет бордюра!

Разумеется, палитры в Таблице PT могут быть изменены и операторами VPOKE. Однако, следует отметить, что изменение Таблицы PT операторами VPOKE само по себе не приводит к изменению цветов. Для считывания содержимого Таблицы PT и присвоения цвета новой палитре существует специальный оператор. Его синтаксис предельно прост:

COLOR = RESTORE

.

Пример 3.
1117-03.bas
1117-03.bas

10 COLOR 1,15,7:SCREEN 1
20 GOSUB 30:VPOKE &H2020+14,&H77:VPOKE &H2020+15,2
25 COLOR=RESTORE:GOSUB 30:END
30  FOR N=0 TO 15
40     AD=&H2020+2*N
50     RB=VPEEK(AD):G=VPEEK(AD+1)
60     PRINT N;TAB(4);HEX$(RB);HEX$(G)
70  NEXT
80 A$=INPUT$(1):CLS:RETURN

Для инициализации Таблицы PT используются:

  • оператор SCREEN ;
  • оператор COLOR=NEW ;
  • оператор COLOR (без параметров!) .

XI.1.8. Спрайты


Вопрос в том, кто за это отвечает?

Шалтай–Болтай

Видеопроцессор имеет два режима отображения спрайтов. Режим отображения спрайтов выбирается автоматически в соответствии с выбранным Вами режимом SCREEN.

Если в Вашей программе присутствует один из операторов:

SCREEN 1, SCREEN 2, SCREEN 3,

то Вы находитесь в режиме спрайтов 1.

Если же в Вашей программе присутствует один из операторов:

SCREEN 4, SCREEN 5, SCREEN 6, SCREEN 7, SCREEN 8,

то Вы находитесь в режиме спрайтов 2.

Вкратце напомним уже известные нам результаты.

В режиме спрайтов 1 на экран одновременно можно вывести 32 спрайта с номерами от 0 до 31. Спрайты с меньшими номерами имеют более высокий приоритет. На одной горизонтальной линии экрана размещается до четырёх спрайтов с высшим приоритетом, а в пересекающейся части спрайты с более низким приоритетом становятся невидимыми.

Когда два спрайта сталкиваются, т.е. пересекаются заполненные части их образов (если сталкиваются два спрайта, шаблоны которых занулены, или спрайты сталкиваются занулёнными участками шаблонов,то столкновение не бнаруживается), тогда бит 5 регистра состояния с номером 0 устанавливается в 1.

Кроме того, если на одной горизонтальной линии находятся пять или более спрайтов, то 6–й бит регистра состояния будет установлен в 1, а пять младших бит зафиксируют номер пятого спрайта.

В режиме спрайтов 2 на экран одновременно можно вывести 32 спрайта, пронумерованных от 0 до 31. Спрайты с меньшими номерами имеют более высокий приоритет. На одной горизонтальной линии экрана изображается до восьми спрайтов с высшим приоритетом, а в перекрывающийся части спрайты с меньшим приоритетом не видны.

Столкновение двух спрайтов обнаруживается по состоянию 5–го бита регистра состояния с номером 0 (он устанавливается в 1). Интересно отметить, что в этом случае координаты столкновения фиксируются в регистрах состояния с номерами от 3 до 5.

Вдобавок, если на одной горизонтальной линии экрана появляются девять или более спрайтов, то 6–й бит регистра состояния с номером 0 будет установлен в 1,а 5 младших бит этого регистра зафиксируют номер девятого спрайта.

В режимах SCREEN 1 ÷ SCREEN 3 спрайты задаются при помощи двух Таблиц:

  • Таблицы шаблонов спрайтов (SGT);
  • Таблицы атрибутов спрайтов (SAT);

В режимах SCREEN 4 ÷ SCREEN 8 дополнительно используется ещё и

  • Таблица цветов спрайтов (SCT).

В этом разделе мы расскажем Вам о каждой Таблице.


Шаблон (от нем. Schablone — образец, модель), пластина с вырезами, очертания которых соответствуют контуру чертежа, изделия и т.п.

Советский Энциклопедический Словарь

  1. Таблица SGT содержит образы спрайтов (которые ниже мы будем называть шаблонами), установленные оператором

    SPRITE$(N)= строковое выражение

    Эта Таблица инициализируется нулями оператором SCREEN, причём оператор SCREEN ,T приводит к исчезновению спрайтов с экрана, сохраняя при этом на экране остальную информацию, а операторы SCREEN M,T и SCREEN M инициализируют всю видеопамять.

    2048 байт Таблицы SGT позволяют хранить информацию о 256 шаблонах спрайтов, если вторым параметром в операторе SCREEN является 0 или 1, и информацию о 64–х шаблонах, если этот параметр равен 2 или 3.

    Адрес шаблона спрайта в Таблице SGT, созданного при помощи оператора SPRITE$(N)=…, вычисляется по формуле:

    A0 +8·N

    или

    A0+32·N    ,

    где А0 — адрес начала Таблицы SGT.

    Напомним Вам, что начальный адрес Таблицы SGT для разных режимов SCREEN возвращает функция BASE():

    BASE(M*5+4)

    где M — номер режима SCREEN.

    Байты шаблона записаны в Таблице SGT в том же порядке, как и байты (символы!) значения строкового выражения, стоящего в правой части оператора SPRITE$(N)=…

    Теперь, надеемся, Вам понятно, что действие, например, операторов:

    SCREEN 1:SPRITE$(0)=STRING(8,255)

    эквивалентно действию цикла:

    FOR I=0 TO 7:VPOKE &H3800+I,255:NEXT
                       ───▲──
                          └─ BASE(1*5+4)

    Пример 1.
    1118-01.bas
    1118-01.bas

    10 SCREEN 1,0
    20 A$="Microsoft"
    30 FORI=1TOLEN(A$):B$=MID$(A$,I,1)
    50 VPOKEBASE(1*5+4)+8*2+(I-1),ASC(B$)
    60 NEXT
    70 PRINT SPRITE$(2)
    
          8 байтов        8 байтов          8 байтов
    ┌────────────────┬────────────────┬────────────────┐
    │  "Место" в SGT │  "Место" в SGT │ "Место в SGT   │
    │для 0–го спрайта│для 1–го спрайта│для 2–го спрайта│
    └────────────────┴────────────────┴▲───────────────┘
                                       │
                                BASE(1*5+4)+8*2


    Атрибут (от лат. Attribuo — придаю, наделяю), необходимое, существенное, неотъемлемое свойство объекта.

    Советский Энциклопедический Словарь

  2. В 128 байтах Таблицы атрибутов спрайтов (Таблицы SAT) кодируется информация о способе вывода образов (шаблонов) спрайтов на экран. Поскольку одновременно на экране могут отображаться не более 32 спрайтов, то атрибуты одного спрайта кодируются в 128/32 = 4 байтах. Вероятно, Вас заинтересует их содержимое? Поспешим удовлетворить Ваше любопытство:

                          Байты Таблицы SAT
    ┌──────────────┬──────────────┬──────────────┬───────────────┐
    │  Первый байт │  Второй байт │  Третий байт │ Четвёртый байт│
    └──────▲───────┴───────▲──────┴───────▲──────┴────────▲──────┘
           │               │              │               │
      Координата Y   Координата X   Номер шаблона       Номер
        (0÷255)        (0÷255)      в SGT (0÷255)      палитры

    Отметим, что если величина Y–координаты спрайта равна 216, то все спрайты с меньшим приоритетом не будут отображаться. Например, если Y–координата спрайта с номером 10 равна 216,то спрайты с номерами от 10 до 31 не будут отображаться.

    Если размер спрайта — 16×16, то, как известно, одному спрайту соответствуют четыре номера шаблонов спрайта. В этом случае можно задать любой из четырёх номеров шаблонов спрайта!

    Таким образом, если мы обозначим A0 — начальный адрес Таблицы SAT, то оператор

    PUT SPRITE SN,(X,Y),C,NP
    <code>
    эквивалентен следующим операторам:
    <code>
    AD=A0+4*SN:VPOKE AD,Y:VPOKE AD+1,X:VPOKE AD+2,NP:VPOKE AD+3,C
             ▲          ▲            ▲            ▲             ▲
             └─!!!      └─!!!        └─!!!        └─!!!         └─!!!

    Пример 2.
    1118-02.bas
    1118-02.bas

    10 COLOR 1,15,8:SCREEN 1,1:SPRITE$(20)="СПРАЙТ!"
    20 PUT SPRITE 2,(165,38),7,20
    30 ? "X=";VPEEK(6921):? "Y="VPEEK(6920):?"Цвет номер";VPEEK(6923):?"Шаблон";VPEEK(6922)
    40 FOR T=0 TO 8:? CHR$(VPEEK(14336+VPEEK(6922)*8+T));:
    NEXT

    Рассмотрим подробнее четвёртый байт Таблицы SAT для какого–нибудь выбранного спрайта.

               ┌───┬───┬───┬───┬───┬───┬───┬───┐
    Старший бит│   │ 0 │ 0 │ 0 │  Цвет спрайта │ Младший бит
               └─▲─┴───┴───┴───┴───┴───┴───┴───┘
                 └── Синхронизирующий бит (его имя EC)

    Его младшие четыре бита определяют текущий цвет спрайта (для высвечиваемых точек шаблона). Невысвечиваемые точки шаблона «окрашены» в прозрачный цвет.

    Старший бит этого байта называется синхронизирующим. Если его значение равно 1, то положение спрайта смещается влево на 32 точки.

    Пример 3. «Работа» синхронизирующего бита.
    1118-03.bas
    1118-03.bas

    20 COLOR 1,15,15
    30 SCREEN 1,3:WIDTH 30
    40 SPRITE$(0)=STRING$(32,255)
    50 PUT SPRITE 0,(80,80),8,0
    60 VPOKE 6915,&B10001000
    61 '            ▲
    63 '            │────────────  1 - координаты спрайта (X-32,Y)
    65 '            └────────────  0 - координаты спрайта (X,Y)
    70 LOCATE 2,8,0:PRINT"Нажмите клавишу"
    80 A$=INPUT$(1)
    90 VPOKE 6915,&B00001000
    100 END

    Разумеется, при программировании на языке MSX BASIC лучше использовать оператор PUT SPRITE, а не последовательность операторов VPOKE.

    Однако, последовательность операторов VPOKE гораздо проще моделировать на машинном языке, чем оператор PUT SPRITE.

    Более того, знание структуры Таблицы SAT позволяет «прочитать» атрибуты спрайта непосредственно из памяти !

    Пример 4. Превращение белого спрайта в чёрный и наоборот.
    1118-04.bas
    1118-04.bas

    10 COLOR 1,4,8:SCREEN 1,1
    20 SPRITE$(0)=STRING$(8,255)
    30 PUT SPRITE 0,(115,80),15,0
    40 IF INKEY$="" THEN 40
    50 GOSUB 100:GOTO 40
    100 VPOKE &H1B03,VPEEK(&H1B03) XOR 14  'BASE(1*5+3) ──▶ &H1B00
    110 RETURN       ──────────▲─────────
                               │
                   &b00001111 XOR &b00001110 = &b00000001 ──▶ цвет 1

    Оператор SCREEN инициализирует четыре байта Таблицы SAT, кодирующих атрибуты одного спрайта, следующим образом:

    ┌──────────────┬──────────────┬──────────────┬───────────────┐
    │  Первый байт │  Второй байт │  Третий байт │ Четвёртый байт│
    └──────▲───────┴───────▲──────┴───────▲──────┴────────▲──────┘
           │               │              │               │
      Координата Y   Координата X   Номер шаблона    Текущий цвет
                                    в Таблице SGT     изображения

    Координата Y отображения спрайта по умолчанию приведена в следующей табличке (из неё видно, что при таких Y неважно, каково Х):

    Серия компьютера MSX 1 MSX 2
    Режим экрана Y Y
    SCREEN 1 209 209
    SCREEN 2 209 209
    SCREEN 3 209 209
    SCREEN 4 217
    SCREEN 5 217
    SCREEN 6 217
    SCREEN 7 217
    SCREEN 8 217

    С учётом значения координаты Y спрайт является невидимым. Координата Y обладает интересной особенностью. Если Y–координата спрайта с номером N равна 209 (в режимах SCREEN 1, SCREEN 2, SCREEN 3) или 217 (в режимах SCREEN 4, SCREEN 5, SCREEN 6, SCREEN 7, SCREEN 8), то этот спрайт не отображается на экране. Самое интересное заключается в том, что не отображаются и все остальные спрайты с номерами, большими, чем N.

    Пример 5.
    1118-05.bas
    1118-05.bas

    10 DIM X(3):SCREEN 2,0
    20 A$="ЧЧЧЧЧЧЧЧ":Y=0
    30 FOR I=1 TO 3:SPRITE$(I)=A$:X(I)=10*I:NEXT I
    40 PUT SPRITE 1,(X(1),Y),1,1
    50 PUT SPRITE 3,(X(3),Y),15,3
    60 PUT SPRITE 2,(X(2),Y),8,2
    70 Y=Y+1:IF Y>208 THEN BEEP:A$=INPUT$(1):END 'Исчезли два спрайта!
    80 GOTO 60

    «Экранный» номер спрайта по умолчанию равен номеру шаблона спрайта.

    Цветом спрайта по умолчанию является текущий цвет изображения.

  3. Таблица SCT используется только в режимах SCREEN 4 ÷ SCREEN 8.

    Базовый адрес Таблицы цветов спрайтов (SCT) будет всегда автоматически вычисляться вычитанием числа 512 из базового адреса Таблицы атрибутов спрайтов (SAT).

    С помощью SCT можно моделировать оператор COLOR SPRITE$(), который, как Вы, конечно, помните, позволяет определить цвет для высвечиваемых точек шаблона спрайта для каждой спрайтовой линии (цвет невысвечиваемых точек шаблона спрайта всегда прозрачный).

    Так как для каждого из 32 спрайтов необходимо хранить информацию максимум о 16 спрайтовых линиях различного цвета, эта Таблица занимает

    32·16 = 512 байтов VRAM .

    Адрес байта, начиная с которого располагается информация о цвете спрайта в Таблице SCT, вычисляется по формуле:

    AD = A0 + 16·SN

    где:

    • A0 — адрес начала Таблицы SCT;
    • SN — номер шаблона спрайта

    Пример 6. Вторая спрайтовая линия изображения девятого спрайта раскрашена восьмым цветом.
    1118-06.bas
    1118-06.bas

    10 COLOR 15,1,8:SCREEN 4,0
    20 SPRITE$(3)="пример":PUT SPRITE 9,(40,80),15,3
    40 VPOKE &H1C00+16*9+2,8
    50 GOTO 50

Заметим, что для информации о цвете шаблона спрайта размером 8×8 точек отводятся только 16 младших полубайтов 16–ти байтов SCT, отводимых для одного шаблона.

Опишем содержимое оставшихся 16–ти старших полубайтов… Оказывается с их помощью можно разрешить или запретить приоритеты спрайтов, обработать определённым образом столкновения и задать или отменить так называемое «опережение» для спрайта.

Изобразим схематически Таблицу SCT…

                      Номера бит
        ┌────┬────┬────┬────┬───┬───┬───┬───┐
        │ 7  │ 6  │  5 │  4 │ 3 │ 2 │ 1 │ 0 │            
        ├────┼────┼────┼────┼───┴───┴───┴───┤
  0 байт│    │    │    │  0 │   Код цвета   │ Спр.лин. 1 для спрайта  0
        ├────┼────┼────┼────┼───────────────┤
  1 байт│    │    │    │  0 │   Код цвета   │ Спр.лин. 2 для спрайта  0
        ├────┴────┴────┴────┴───────────────┤
    …   │            …              …       │            …
        ├────┬────┬────┬────┬───────────────┤
 15 байт│    │    │    │  0 │   Код цвета   │ Спр.лин. 16 для спрайта 0
        ├────┴────┴────┴────┼───────────────┤
    …   │            …              …       │            …
        ├────┬────┬────┬────┼───────────────┤
496 байт│    │    │    │  0 │   Код цвета   │ Спр.лин.  1 для спрайта 31
        ├────┼────┼────┼────┼───────────────┤
497 байт│    │    │    │  0 │   Код цвета   │ Спр.лин.  2 для спрайта 31
        ├────┴────┴────┴────┼───────────────┤
    …   │            …              …       │            …
        ├────┬────┬────┬────┼───────────────┤
511 байт│    │    │    │  0 │   Код цвета   │ Спр.лин. 16 для спрайта 31
        └──▲─┴──▲─┴──▲─┴────┴───────────────┘
           │    │    └─ Бит IC (определитель столкновений):1 — нет, 0 — да;
           │    └────── Бит CC (разрешение приоритета)    :0 — нет, 1 — да;
           └─────────── Бит EC ("опережение")             :1 — да,  0 — нет.

В режиме спрайтов 2, если СС–бит Таблицы SCT установлен в 1, порядок приоритетности спрайтов для данной спрайтовой линии отменяется. Спрайтовая линия, для которой бит СС установлен в 1 , будет отображаться только на горизонтальных линиях,где существуют спрайты с низшими номерами.

Отметим, что и в этом случае, если на одной линии экрана более 8 спрайтов, то девятый спрайт и все последующие не будут изображаться на экране дисплея.

Более того не фиксируется столкновение спрайта, для которого с SCT бит СС установлен в 1, с другим спрайтом (даже если у этого спрайта в SCT бит СС установлен в 0). В этом случае для пересекающихся спрайтов над их цветовыми кодами производится логическая операция OR.

Говорят, что в режиме SCREEN 6 цвет фона и цвета спрайтов подвергаются аппаратному тилингу. Эти цвета кодируются четырьмя битами: два старших бита определяют код цвета нечётных точек, а два младших бита определяют код цвета чётных точек по X–координате (от 0 до 511).

В режиме SCREEN 6 размер одной точки спрайта в 2 раза больше,чем у графической точки (пикселя), однако, за счёт наличия аппаратного тилинга, одна точка спрайта может обладать двумя цветами одновременно (чётные и нечётные точки фонового цвета могут быть определены таким же образом).

        ┌─────────────────── Чётные точки   (0,2,…,510)
        │    ┌────────────── Нечётные точки (1,3,…,511)
     ┌──▼─┬──▼─┐
     │    │    │   Две графические точки
     └────┴────┘
     ┌────┬────┐   
     │    │    │   Одна точка спрайта
     └──▲─┴─▲──┘
        │   │     
┌───┬───┐   ┌───┬───┐
│ █ │ █ │   │ █ │ █ │  Биты, определяющие цвета спрайта
└───┴───┘   └───┴───┘

Приведём табличку начальных адресов Таблиц SCT для различных режимов:

Режим Адрес
SCREEN 4 &H1C00
SCREEN 5 &H7400
SCREEN 6 &H7400
SCREEN 7 &HF800
SCREEN 8 &HF800

Отметим, что 16 байтов Таблицы SCT, отвечающих за цвет спрайта, первоначально инициализируются текущим цветом изображения или цветом, заданным в операторе PUT SPRITE. «Содержимое» этих байтов может быть переопределено непосредственно операторами VPOKE или оператором COLOR SPRITE() (COLOR SPRITE$()).

В режиме SCREEN 8 цвета спрайта фиксированы и не зависят от регистра палитры. Цвета спрайта в режиме SCREEN 8 показаны на следующей таблице.

Код цвета Зелёный Красный Синий
С3С2С1С0G2G1G0R2R1R0B2B1B0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 0 1 1 0 0 0
0 0 1 1 0 0 0 0 1 1 0 1 0
0 1 0 0 0 1 1 0 0 0 0 0 0
0 1 0 1 0 1 1 0 0 0 0 1 0
0 1 1 0 0 1 1 0 1 1 0 0 0
0 1 1 1 0 1 1 0 1 1 0 1 0
1 0 0 0 1 0 0 1 1 1 0 1 0
1 0 0 1 0 0 0 0 0 0 1 1 1
1 0 1 0 0 0 0 1 1 1 0 0 0
1 0 1 1 0 0 0 1 1 1 1 1 1
1 1 0 0 1 1 1 0 0 0 0 0 0
1 1 0 1 1 1 1 0 0 0 1 1 1
1 1 1 0 1 1 1 1 1 1 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1

XI.1.9. Слоты видеопамяти

Вся видеопамять на компьютерах серии MSX 2 разбита на два больших участка объёмом по 64 Кбайта каждый. Эти участки будем называть слотами видеопамяти (по аналогии с участками RAM и ROM объёмом по 64 Кбайта, называемыми слотами памяти). На компьютерах серии MSX 1 имеется только один слот VRAM объёмом в 16 Кбайт.

Для того, чтобы переключиться с работы со слотом 0 на работу со слотом 1, достаточно выполнить оператор:

  • SET PAGE 2 или SET PAGE 3 в режимах SCREEN 5 и SCREEN 6;
  • SET PAGE 1 в режимах SCREEN 7 и SCREEN 8.

После этого оператором VPOKE и функцией VPEEK можно работать с логическими адресами видеопамяти. В помощь Вам предлагаем следующие таблички:

Физические адреса Логические адреса Номера слотов Способ включения слота
от &H00000 от &H0000 Слот 0 SET PAGE 0 Для режимов SCREEN 5 и SCREEN 6
до &H07FFF до &H7FFF
от &H08000 от &H8000 SET PAGE 1
до &H0FFFF до &HFFFF
от &H10000 от &H0000 Слот 1 SET PAGE 2
до &H17FFF до &H7FFF
от &H18000 от &H8000 SET PAGE 3
до &H1FFFF до &HFFFF
от &H00000 от &H0000 Слот 0 SET PAGE 0 Для режимов SCREEN 7 и SCREEN 8
до &H0FFFF до &HFFFF
от &H10000 от &H0000 Слот 1 SET PAGE 1
до &H1FFFF до &HFFFF

Отметим также, что в режимах SCREEN 0 ÷ SCREEN 4 работа со слотом 1 запрещена.

XI.1.10. Порты, отвечающие за работу с видеопамятью

Другой способ доступа к видеопамяти заключается в работе с портами ввода–вывода. Этот способ очень часто используется при написании программ в машинных кодах.

Напомним, что перед использованием команды (оператора) OUT на компьютерах серии MSX 2 необходимо выполнить команду CALL NETEND.

  1. Для записи числа в ячейку видеопамяти примените серию команд:

    • OUT &H99, Младший байт номера ячейки
    • OUT &H99, Старший байт номера ячейки OR &H40
    • OUT &H98, Число

    Пример.
    11110-01.bas
    11110-01.bas

    10 SCREEN 0:CLS:KEYOFF
    20 OUT &H99,0:OUT &H99,0 OR &H40
    30 FOR I=1 TO 20
    40    READ R$:R=ASC(R$):OUT &H98,R
    50 NEXT I:PRINT 'Попробуйте убрать в этой строке оператор PRINT
    60 DATA Г,р,у,п,п,о,в,а,я," ",п,е,р,е,с,ы,л,к,а,!
  2. Для чтения числа из ячейки видеопамяти, примените следующие команды:

    • OUT &H99, Младший байт номера ячейки
    • OUT &H99, Старший байт номера ячейки
    • A=INP(&H98)

Важно отметить следующее. Изменение содержимого видеопамяти или видеопроцессора приводит к немедленной корректировке содержимого экрана. Однако, отсюда вовсе не следует истинность обратного утверждения.

Изменение «содержимого» экрана не всегда приводит к изменению VRAM.

Если Вы не будете в программе «работать» с портами ввода–вывода,то можно утверждать, что VRAM и VDP «управляют» «содержимым» экрана.На самом же деле состояние экрана изменяют порты ввода–вывода с адресами &H98, &H99, &H9A и &H9B. На эти порты можно «воздействовать» оператором VPOKE. В этом случае сигнал из VRAM сразу же поступает в порт, а тот,в свою очередь изменяет «рисунок» на экране.

          ┌───────────┐
          │   Экран   │
          └───▲─▲─▲───┘
              │ │ │
┌─────────────────────────────┐ ◀──
│      Порты ввода–вывода     │ ◀── Оператор OUT
└────▲─▲─▲────────────▲─▲─▲───┘ ◀──
     │ │ │            │ │ │
┌──────────────┐  ┌───────────┐ ◀──
│Видеопроцессор│─▶│Видеопамять│ ◀── Оператор VPOKE
└──────────────┘  └───────────┘ ◀──

Если же воздействовать непосредственно на порт оператором OUT, минуя видеопамять, то могут возникнуть следующие ситуации:

  1. если адрес VRAM принадлежит отрезку [0,&H3FFE], то после записи оператором OUT в ячейку с этим адресом её содержимое можно прочесть как функцией INP, так и функцией VPEEK;
  2. если адрес VRAM принадлежит отрезку [&H3FFF,&HFFFF], то после записи оператором OUT в ячейку с этим адресом её содержимое можно прочесть только функцией INP.

Пример. Сравните результаты работы этой программы на компьютерах серий MSX 1 и MSX 2 !
11110-02.bas
11110-02.bas

10 CALL NETEND
20 INPUT"Младший байт";N1:INPUT"Старший байт";N2:INPUT"Значение";D
30 PRINT"Старое значение:";
40 OUT&H99,N1:OUT&H99,N2:PRINT INP(&H98)
50 OUT&H99,N1:OUT&H99,N2 OR&H40:OUT&H98,D
60 PRINT"Новое значение:";
70 OUT&H99,N1:OUT&H99,N2:PRINT INP(&H98)
80 CALL NETINI:'Отмена действия команды CALL NETEND

XI.2. Работа с видеопроцессором


Четыре величайших изобретения в истории человечества:

  1. колесо;
  2. электрическая лампочка;
  3. микрокомпьютер;
  4. руководства по микрокомпьютерам вместе с их авторами.

М.Уэйт, С.Прата, Д.Мартин

Работа с псевдопеременными BASE и VDP — весьма эффективное средство управления видеопамятью. Однако при использовании этих средств нужно быть крайне осторожным, ибо малейшая ошибка в программировании может сделать экран «неуправляемым», что вынудит Вас нажать кнопку RESET!

Мы познакомим Вас с несколькими сравнительно «безопасными» примерами.

Более детальная информация о способах работы с видеопамятью содержится в книгах [65], [89] (если Вы, конечно, сможете их раздобыть!).

Работой видеопамяти управляет специальный процессор,который называется видеопроцессором. Видеопроцессор «работает» с двумя группами восьмибитных регистров: 47 регистров VDP и 16 регистров статуса.

Регистр — электронное устройство для временного хранения информации во время её обработки. Регистры называют часто сверхоперативной памятью, т.к. для регистров используются специальные электронные схемы, позволяющие значительно быстрее записывать информацию в регистры и читать информацию из регистров.

Регистры VDP можно разделить на несколько категорий:

  • по назначению:
    1. регистры установки режима (0, 1, 8, 9);
    2. регистры базовых адресов (2÷6, 10, 11);
    3. регистры цветов (7, 12, 13, 20÷22);
    4. регистры управления экраном (18, 19, 23);
    5. регистры доступа (14÷17);
    6. регистры команд (32÷46);
  • по способу доступа:
    1. разрешены чтение и запись на компьютерах и серии MSX 1, и серии MSX 2 (регистры 0÷7);
    2. разрешены чтение и запись на компьютерах MSX 2 и только запись на компьютерах MSX 1 (регистры 8÷23);
    3. разрешена только запись (регистры 32÷46).

Для чтения «содержимого» регистров VDP предназначена одноименная псевдопеременная, используемая в правой части оператора присваивания.

Её синтаксис:

VDP(N)

,

где:

  • VDP («ViDeo Processor») — служебное слово;
  • N — арифметическое выражение, целая часть значения которого указывает на номер регистра VDP, причём:
    • α) если используется регистр с номером из диапазона [0,7], то значение параметра N должно быть равно номеру регистра;
    • β) если используется регистр с номером из диапазона [8,23] (для компьютера MSX 2), то N=RG+1, где RG — номер регистра.

Теперь мы расскажем Вам о способах записи в регистры VDP:

  1. запись с использованием псевдопеременной VDP. Этот способ является самым простым: оператор

    VDP(N) = M

    ,

    где:

    • VDP («ViDeo Processor») — служебное слово;
    • N — арифметическое выражение, целая часть значения которого указывает на номер регистра VDP, причём:
    • α) если используется регистр с номером из диапазона [0,7], то значение параметра N должно быть равно номеру регистра;
    • β) если используется регистр с номером из диапазона [8,23], либо из диапазона [32,46] (для компьютера MSX 2), то N=RG+1, где RG — номер регистра;
    • M — арифметическое выражение, целая часть значения которого принадлежит отрезку [0,255],

    позволяет поместить значение выражения M в регистр VDP;

  2. запись через порты ввода–вывода (для всех регистров). Этот способ заключается в использовании порта с номером &H99, связывающего видеопроцессор с центральным процессором MSX–компьютера (Z–80). Чтобы записать число A в регистр VDP с номером N, примените следующие операторы:

    OUT &H99,A:OUT &H99,RG OR &H80 .

    Данные операторы последовательно выводят данные и номер регистра в порт 99h.

    Номер бита 7 6 5 4 3 2 1 0
    Первый байт Данные
    Второй байт 1 0 Номер регистра

    Замечание. Будьте особенно внимательными при обращении к видеопроцессору из подпрограммы обработки прерываний.

  3. косвенная запись в регистры VDP. Про неё будет рассказано в разделе XI.2.6..

    Напомним, что если Вы работаете с компьютером серии MSX 2, то перед набором программы, использующей порты ввода–вывода, нужно выполнить команду

    CALL NETEND

    .

XI.2.1. Регистры установки режима


Нехватка информации восполняется избытком интуиции.

М.Мишин

Перейдём теперь к описанию «содержимого» некоторых регистров VDP.

Вначале напомним Вам принятую нумерацию бит в байте:

7–й
бит
6–й
бит
5–й
бит
4–й
бит
3–й
бит
2–й
бит
1–й
бит
0–й
бит

Регистр 0.

Номер бита Значение бита Комментарий
7 0 Не используется
6 1 Устанавливает цветовую шину в режиме ввода и вводит данные в видеопамять
5 1 Бит «IE2» Запретить прерывания от светового пера
0 Разрешить прерывания от светового пера
4 1 Бит «IE1» Запретить прерывание от горизонтального сканирования линии по «IE1» и отключить сигналы с клавиатуры
0 Разрешить прерывания по «IE1»
3 Бит «M5» установки графических режимов
2 Бит «M4» установки графических режимов
1 Бит «M3» установки графических режимов
0 Внешний видеосигнал (бит «IV»)

Пример.
1121-00.bas
1121-00.bas

10 OUT &H99,VDP(0) OR 16:OUT &H99,0 OR &H80 'Отключение клавиатуры!

Регистр 1.

Номер бита Значение бита Комментарий
7 0 Не используется
6 0 Применение аналогично нажатию кнопки питания дисплеяизображение отключено
1 изображение включено
5 0 Бит «IE0» Запретить прерывание от горизонтального сканирования линии по «IE0» и отключить сигналы с клавиатуры
1 Разрешить прерывания по «IE0»
4 Бит «M1» установки графических режимов
3 Бит «M2» установки графических режимов
2 0 Не используется
1 0 Размер спрайтов 8×8Использование этих бит позволяет моделировать оператор SCREEN,n
1 Размер спрайтов 16×16
0 0 Нормальный размер спрайтов
1 «Увеличение» размера спрайтов

Назначение 6–го бита регистра 1 иллюстрируется примерами 1 и 2:

Пример 1.


  1. 1121-011.bas
    1121-011.bas
    10 SCREEN 2
    15 :::::::::::::::::
    20 CIRCLE(125,95),90
    30 PAINT STEP(0,0)
    35 :::::::::::::::::
    40 GOTO 40

  2. 1021-012.bas
    1021-012.bas
                 ┌─ OFF
    10 SCREEN 2  ▼
    15 VDP(1)=&B10100000
    20 CIRCLE(125,95),90
    30 PAINT STEP(0,0)
    35 VDP(1)=&B11100000
    40 GOTO 40   ▲
                 └─ ON

  3. 1021-013.bas
    1021-013.bas
    10 SCREEN 2
    15 OUT &H99,&B10100000:OUT &H99,1 OR &H80
    20 CIRCLE(125,95),90:PAINT STEP (0,0)
    35 VDP(1)=&B11100000
    40 GOTO 40

Перед записью в регистр лучше всего сначала прочитать его текущее содержимое, а лишь затем с помощью логических операций AND, OR и XOR установить или «сбросить» нужные биты.

Пример 2. Включение и выключение экрана дисплея
1121-02.bas
1121-02.bas

VDP(1)=VDP(1) XOR 64

Эта команда включает экран, если он был выключен, и наоборот.

А теперь разберёмся с нулевым битом регистра 1…

Пример 3. Изменение размера спрайта без очистки шаблонов.
1121-031.bas
1121-031.bas

10 SCREEN 2,1
20 SPRITE$(0)="0123456789ABCDEF"
30 PUT SPRITE 0,(50,50),,0
40 FOR I=1 TO 1000:NEXT
50 VDP(1)=VDP(1) XOR 1 'Эта команда переключает масштаб спрайтов без очистки шаблонов
60 GOTO 60

А теперь замените строку 50 на строку
1121-032.bas
1121-032.bas

50 OUT &H99,VDP(1) XOR 1:OUT &H99,1 OR &H80

и выполните программу.

Биты «M1»,«M2»,«M3»,«M4»,«M5» «отвечают» за выбор режима экрана:

Биты и их значение Режим видеопроцессора
M1 M2 M3 M4 M5
1 0 0 0 0 SCREEN 0 (40 символов)
1 0 0 1 0 SCREEN 0 (80 символов)
0 0 0 0 0 SCREEN 1
0 0 1 0 0 SCREEN 2
0 1 0 0 0 SCREEN 3
0 0 0 1 0 SCREEN 4
0 0 1 1 0 SCREEN 5
0 0 0 1 1 SCREEN 6
0 0 1 0 1 SCREEN 7
0 0 1 1 1 SCREEN 8

Изменять содержимое бит «M1»,«M2»,«M3»,«M4» и «M5» не рекомендуется! Эти биты используются видеопроцессором при инициализации режима SCREEN, однако следует помнить, что для полной инициализации этого надостаточно!

Легко, например, проверить, что команда VDP(0)=4 не устанавливает полностью 80–символьный режим SCREEN 0. Зато чтение этих бит поможет Вам «вспомнить», в каком режиме SCREEN Вы работаете в данный момент.

Для полной инициализации экрана нужно выполнить следующие действия:

  1. установить биты M1, M2, M3, M4, M5;
  2. установить начальные адреса Таблиц VRAM в регистрах базовых адресов;
  3. заполнить таблицы видеопамяти необходимыми данными;
  4. занести в ячейку памяти с адресом &HFCAF номер режима SCREEN.

Регистр 8.

Номер бита Значение бита Комментарий
7 1 Цветовая шина устанавливается на режим ввода и разрешается использование манипулятора «мышь»
0 Цветовая шина устанавливается на режим вывода и запрещается использование манипулятора «мышь»
6 1 Разрешается обработка светового пера
0 Запрещается обработка светового пера
5 Бит с именем TP. Устанавливается цвет кода 0 в цветовой палитре
1 изображение 0–го цвета имеет цвет 0 из Таблицы PT
0 изображение 0–го цвета имеет цвет бордюра
4 Моделирует оператор SET VIDEO,,n
1 происходит вывод данных на видеомагнитофон
0 происходит ввод данных от внешнего TV–источника или от компьютера;
3 Содержимое бита изменять не рекомендуется!
1 Размер видеопамяти ≥64 Кб (для компьютеров MSX 2)
0 Размер видеопамяти ≤64 Кб (для компьютеров MSX 1)
2 0 Не используется
1 1 Запрещается отображение спрайтов
0 Разрешается отображение спрайтов
0 1 Установить черно–белый режим с 32 градациями тона
0 Установить цветовой режим

По умолчанию 5–й бит регистра с номером 8 равен 0. В этом случае объект нулевого цвета будет окрашиваться цветом бордюра (т.е. будет прозрачным). Участки спрайтов с нулевым цветом на экране не отображаются. Но если спрайты пересекаются «невидимыми» частями, то столкновение спрайтов не будет установлено. Для получения на экране одновременно 16 цветов необходимо, чтобы бордюр был окрашен в нулевой цвет.

Если 5–й бит 8–го регистра равен 1, то объект нулевого цвета не будет окрашиваться цветом бордюра (если, конечно, бордюр сам не окрашен в нулевой цвет). Код цвета 0 будет кодом, который определяется в регистре палитры (только в режиме SCREEN 8 R=0, G=0, B=0). На экране одновременно могут отображаться 16 цветов, причём в области, отличной от бордюра; более того, отображаются спрайты всех цветов. Участки спрайтов с нулевым цветом на экране по–прежнему не отображаются. Но если спрайты пересекаются «невидимыми» частями, то столкновение спрайтов будет установлено.

Пример 4.
1121-04.bas
1121-04.bas

10 COLOR =(0,2,4,7) 'Изменим палитру нулевого цвета
20 COLOR 1,15,8:SCREEN 2
30 VDP(8+1)=8 'Инициализация 8-го регистра
40 CIRCLE (90,90),45,0 'Изображение имеет цвет бордюра
50 A$=INPUT$(1)
60 VDP(8+1)=&B00101000 'Бордюр окрашен в 8-й цвет,
70 GOTO 70             'а изображение - в нулевой

Регистр 9.

Номер
бита
Значение
бита
Комментарий
7 Бит «LN» Отвечает за общую высоту экрана (за доступную высоту отвечает ячейка &hF3B1 в рабочей области RAM)
1 На экране 212 графических или 26.5 текстовых строк
0 На экране 192 графических или 24 текстовых строк
6 0 Не используется
5 1 Поступает сигнал только от внешнего TV–источникаЭти биты моделируют оператор SET VIDEO n
0 Разрешено изображение от компьютера
4 1 Происходит смешивание изображения от компьютера и от TV–источника
0 Смешивания сигналов не происходит
3 1 Происходит «дрожание» экранаЭти биты моделируют оператор SCREEN ,,,,,n (5 запятых!)
0 «Дрожания» не происходит
2 1 Происходит поочерёдный показ страниц на страницах с нечётными номерами в режимах SCREEN 5 ÷ SCREEN 8
0 Отображается одна и та же страница на чётное/нечётное поле
1 Выбор системы телевидения
1 PAL (313 линий, американский стандарт)
0 NTSC (262 линии, японский стандарт) — только для RGB–выхода
0 1 Установка на режим ввода
0 Установка на режим вывода

Пример 5. Установим высоту экрана равной 26.5 строкам.
1121-05.bas
1121-05.bas

10 SCREEN 0:WIDTH 80
20 VDP(9+1)=VDP(9+1) OR 128
30 POKE &hF3B1,27
40 FOR T=BASE(0)+(1920-80) TO BASE(0)+(1920-80)+240
50 VPOKE T,32:NEXT

XI.2.2. Регистры базовых адресов


Мы находимся в положении, несколько аналогичном положению человека, держащего в руках связку ключей и пытающегося открыть одну за другой несколько дверей. Рано или поздно ему всегда удаётся подобрать ключ к очередной двери, но сомнения относительно взаимнооднозначного соответствия между ключами и дверями у него остаются.

Юджин Вигнер

Адрес байта видеопамяти кодируется 17–ю двоичными цифрами, которые мы будем обозначать Ai, где i=0,1,2,…,16, причём через A16 будем обозначать старший бит, через A0 — младший бит.

Старший бит A16 A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 Младший бит

В регистрах базовых адресов хранятся старшие биты начальных адресов Таблиц VRAM для текущего режима SCREEN.

Эти регистры инициализируются псевдопеременной BASE.

Отметим,что при использовании этих регистров рекомендуется маскировать ненужные в текущем режиме отображения биты.

Регистр с номером 2 VDP содержит семь старших бит начального адреса Таблицы PNT:

0 A16 A15 A14 A13 A12 A11 A10

Пример 1.
1122-01.bas
1122-01.bas

10 SCREEN 1
20 A$=RIGHT$("0000000000000000"+BIN$(BASE(5*1+0)),16)
30 ?A$:B$=RIGHT$("00000000"+BIN$(VDP(2)),8):?B$ 'Читаем текущий адрес PNT
run
┌──────┐
│000110│0000000000◀── Начальный адрес Таблицы PNT в SCREEN1
└──────┘
   ┌──────┐
 00│000110│       ◀── Содержимое регистра с номером 2
Ok └──────┘

Регистры с номерами 10 и 3 содержат одиннадцать старших бит начального адреса Таблицы CT:

Регистр 10

0 0 0 0 0 A16 A15 A14

Регистр 3

A13 A12 A11 A10 A9 A8 A7 A6

Пример 2.
1122-02.bas
1122-02.bas

10 SCREEN 1
20 A$=RIGHT$("0000000000000000"+BIN$(BASE(5*1+1)),16)
30 ?A$:B$=RIGHT$("0000000000000000"+BIN$(VDP(10+1))+BIN$(VDP(3)),16):?B$
run
┌──────────┐
│0010000000│000000 ◀── Начальный адрес Таблицы CT в SCREEN1
└──────────┘
       ┌──────────┐
 000000│0010000000│◀── Содержимое регистров с номерами 10 и 3
Ok     └──────────┘

Регистр с номером 4 содержит шесть старших бит начального адреса Таблицы PGT:

0 0 A16 A15 A14 A13 A12 A11

Пример 3.
1122-03.bas
1122-03.bas

10 SCREEN 0:WIDTH 80
20 A$=RIGHT$("0000000000000000"+BIN$(BASE(5*0+2)),16)
30 ?A$:B$=RIGHT$("00000000"+BIN$(VDP(4)),8):?B$
run
┌─────┐
│00010│00000000000◀── Начальный адрес Таблицы PGT
└─────┘                      в SCREEN0
    ┌─────┐
 000│00010│       ◀── Содержимое регистра с номером 4
Ok  └─────┘

Регистры с номерами 11 и 5 содержат десять старших бит начального адреса Таблицы SAT:

Регистр 11

0 0 0 0 0 0 A16 А15

Регистр 5

А14 A13 A12 A11 A10 A9 A8 А7

Пример 4.
1122-04.bas
1122-04.bas

10 SCREEN 1
20 A$=RIGHT$("0000000000000000"+BIN$(BASE(5*1+3)),16)
30 ?A$:A$=RIGHT$("0000000000000000"+BIN$(VDP(1+11))+BIN$(VDP(5)),16):?A$
run
┌─────────┐
│000110110│0000000 ◀── Начальный адрес Таблицы SAT в SCREEN1
└─────────┘
        ┌─────────┐
 0000000│000110110│◀── Содержимое регистров с номерами 11 и 5
Ok      └─────────┘

Замечание. С Таблицей SAT связана Таблица SCT, адрес которой получается вычитанием 512 байт из начального адреса Таблицы SAT.

Регистр с номером 6 содержит шесть старших бит начального адреса Таблицы SGT:

0 0 A16 A15 A14 A13 A12 A11

Пример 5.
1122-05.bas
1122-05.bas

10 SCREEN 1
20 A$=RIGHT$("0000000000000000"+BIN$(BASE(5*1+4)),16)
30 ?A$:B$=RIGHT$("00000000"+BIN$(VDP(6)),8):?B$ 'Читаем текущий адрес SGT
run
┌─────┐
│00111│00000000000◀── Начальный адрес Таблицы SGT
└─────┘                      в SCREEN1
    ┌─────┐
 000│00111│       ◀── Содержимое регистра с номером 6
Ok  └─────┘

Отметим, что при использовании этих регистров рекомендуется маскировать ненужные в текущем режиме отображения биты.

XI.2.3. Регистры цветов


— Вы знаете отличительные способности животного, называемого раком?
— Да, конечно. Рак — это рыба красного цвета, которая ходит боком.
— Ну, что ж. Я вижу, что Вы кое–что знаете о раке…

Студенческий фольклор

  1. Регистр с номером 7 видеопроцессора в режиме SCREEN 0 определяет цвет изображения и фона.

    Четыре старших бита этого регистра «хранят» цвет изображения, а четыре младших — цвет фона.

    Например, команда

               VDP(7)=&H4B
                        ▲▲
    Цвет изображения  ──┘└── Цвет фона

    в режиме SCREEN 0 эквивалентна команде COLOR 4,11 .

    А команда VDP(7)=&H1F приводит к тому же результату, что и оператор COLOR 1,15 .

    Регистр с номером 7 (регистр цвета текста/фона)

    Номер бита 7 6 5 4 3 2 1 0
    Имя бита TC3 TC2 TC1 TC0 BD3 BD2 BD1 BD0
    Назначениеопределяет цвет текста в режимах SCREEN 0 и SCREEN 1определяет цвет фона во всех режимах отображения

    В других режимах SCREEN этот регистр «хранит» цвет бордюра.

    Пример 1.
    1123-01.bas
    1123-01.bas

    10 COLOR 1,15,4:SCREEN 2:Z=VDP(7)
    20 SCREEN 0:PRINT Z
    run
     4
    Ok

    Содержимое седьмого регистра инициализируется оператором COLOR

  2. В 80–символьном режиме SCREEN 0 существует явление, которое мы назовём миганием. Информация о символах, которые должны мигать, находится в Таблице цветов (CT), которая занимает 270 байтов с адреса, возвращаемого псевдопеременной BASE(0*5+1). Рассмотрим, как она располагается.

    Каждая строка экрана разбивается на 10 участков по 8 квадратов (знакомест) в каждом. За каждый из этих участков отвечает один байт, а за квадрат, естественно, один бит. Если значение бита равно 1, то символ на соответствующем знакоместе (в соответствующем квадрате) мигает. В противном случае мигания не происходит.

    Запись в Таблицу CT ещё не означает, что какое–то знакоместо на экране сразу замигает. Для начала мигания необходимо обратиться к регистрам VDP, отвечающим за этот процесс.

    Вначале договоримся о терминологии.

    Основным цветом текста (фона) будем называть цвет, задаваемый оператором COLOR и хранящийся в 7–м регистре VDP.

    Цветом мигания текста (фона) будем называть цвет,который приобретает текст (фон) при мигании.

    Частотой включения мигания назовём промежуток времени, в течение которого текст и фон приобретают цвет мигания.

    Частотой выключения мигания будем называть промежуток времени, в течении которого текст и фон приобретают основной цвет.

    Единица измерения частоты мигания равна 1/6 секунды. Максимально возможный период мигания составляет 5 секунд (15/6 секунд на включение мигания и столько же на выключение мигания).

    Регистр с номером двенадцать VDP содержит информацию о цвете мигания текста и фона. Старший полубайт этого регистра отвечает за цвет мигания текста, а младший полубайт отвечает за цвет мигания фона.

    Регистр с номером 12 (регистр цвета текста/фона)

    Номер бита 7 6 5 4 3 2 1 0
    Имя бита TC3 TC2 TC1 TC0 BC3 BC2 BC1 BC0
    Назначениеопределяют цвет части 1 шаблонаопределяют цвет части 0 шаблона

    Если в режиме SCREEN 1 установлен признак мерцания, то цвета из этого регистра и из регистра с номером 7 поочерёдно отображаются.

    За частоту мигания «отвечает» регистр с номером тринадцать, причём в его старшем полубайте хранится информация о частоте включения мигания, а в младшем — информация о частоте выключения мигания.

    Регистр с номером 13 (регистр периода мерцания)

    Номер бита 7 6 5 4 3 2 1 0
    Имя бита ON3 ON2 ON1 ON0 OF3 OF2 OF1 OF0
    Назначениеопределяют период отображения для чётной страницыопределяют период отображения для нечётной страницы

    В режимах растровой графики (SCREEN 5 ÷ SCREEN 8) попеременно сменяются две страницы памяти. Данные помещаются в этот регистр для установления отображаемой страницы как нечётной страницы для начала мерцания. Этот регистр используется также в режиме SCREEN 1.

    Приведём табличку…

    Содержимое
    полубайта
    регистра 13
    Время (мс)
    0000 0
    0001 166,9
    0010 333,8
    0011 500,6
    0100 667,5
    0101 834,4
    0110 1001,3
    0111 1168,2
    1000 1335,1
    1001 1501,9
    1010 1668,8
    1011 1835,7
    1100 2002,6
    1101 2169,5
    1110 2336,3
    1111 2503,2

    А теперь взгляните на следующий пример.

    Пример 2.
    1123-02.bas
    1123-02.bas

    NEW
    Ok
    10 SCREEN 0:WIDTH 80 'Установка режима для мигания
    20 FOR T=2048 TO 2048+269:VPOKE T,0:NEXT 'Очистка Таблицы мигания
    30 LINEINPUT "Введите слово:";B$
    40 INPUT "Где ему мигать (X,Y)";X,Y
    50 INPUT "Цвет слова для мигания";MI
    60 INPUT "Цвет фона для мигания";MF
    70 INPUT "Частота включения мигания (от 0 до 15)";TN
    80 INPUT "Частота выключения мигания (от 0 до 15)";TK
    90 VPOKE 2048+10*Y+X/8,&B11111111 'Будуть мигать 8 символов
    100 CLS:LOCATE X,Y:PRINT B$
    110 COL=16*MI+MF:TIM=16*TN+TK
    120 VDP(12+1)=COL:VDP(13+1)=TIM

    Для прекращения мигания поместите в старший полубайт 13–го регистра число 0.

  3. Две графические страницы экрана могут отображаться попеременно (в режимах SCREEN 5 ÷ SCREEN 8). Страницы, которые будут попеременно отображаться, расположены следующим образом:

    Режим SCREEN 5 и  SCREEN 6       Режим SCREEN 7 и SCREEN 8
         ┌─────────────┐                  ┌────────────┐
         │ Страница 0  │─┐                │            │─┐
         ├─────────────┤ │                │ Страница 0 │ │
         │ Страница 1  │─┘                │            │ │
         ├─────────────┤                  ├────────────┤ │
         │ Страница 2  │─┐                │            │ │ 
         ├─────────────┤ │                │ Страница 1 │─┘
         │ Страница 3  │─┘                │            │ 
         └─────────────┘                  └────────────┘

    Период отображения,находящийся в промежутке между 166 мсек и 2053 мсек, может быть определён для каждой страницы. Для этого необходимо:

    1. задать базовый адрес Таблицы имён шаблонов нечётной страницы (регистр с номером 2);
    2. задать время включения (интервал, в течение которого отображается чётная страница) и время выключения (интервал, в течение которого отображается нечётная страница) в регистре с номером 13.

      Регистр с номером 13 (регистр периода мерцания)

      Номер бита 7 6 5 4 3 2 1 0
      Имя бита ON3 ON2 ON1 ON0 OF3 OF2 OF1 OF0
      НазначениеВремя включенияВремя выключения
    3. После этого начнётся процесс мигания.

    Пример 3.
    1123-03.bas
    1123-03.bas

    10 SCREEN 7                    :' Режим растровой графики (SCREEN 5÷8)
    20 SET PAGE 0,0: CLS           :' На странице 0
    30 CIRCLE (254,106),30,15      :' рисуем окружность
    40 SET PAGE 1,1: CLS           :' А на странице 1
    50 CIRCLE (254,106),60,15      :' рисуем окружность побольше
    60 VDP(13+1)=&H11              :' Включим смену страниц
    70                             :' Окружность  п у л ь с и р у е т !
    80 A$=INPUT$(1)                :' Немного подождем...
    90 VDP(13+1)=0                 :' Выключим смену страниц

    Опишем ещё один способ осуществления смены двух графических страниц на экране.

    Бит ЕО (второй бит регистра с номером 9), используется для попеременной демонстрации двух графических страниц экрана с частотой 60 Гц.

    Для этого необходимо: 1) задать базовый адрес Таблицы имён шаблонов нечётной страницы (регистр с номером 2); 2) установить второй бит регистра с номером 9 в 1.

    Пример 4.
    1123-04.bas
    1123-04.bas

    10 SCREEN 7:VDP(10)=0       :' Режим растровой графики (SCREEN 5÷8)
    20 SET PAGE 0,0: CLS        :' Рисуем на странице 0
    30 CIRCLE (256,106),30,15   :' окружность радиусом 30
    31 FOR I=1 TO 100:NEXT      :' З а д е р ж к а...
    40 SET PAGE 1,1: CLS        :' А на странице 1 -
    50 CIRCLE (256,106),60,15   :' окружность радиусом 60
    51 FOR I=1 TO 100:NEXT      :' З а д е р ж к а...
    59 :'                       :' А теперь - п о м и г а е м ...
    60 VDP(9+1)=&B00000100:' Включаем попеременное отображение страниц.
    70 :' Окружности с двух страниц одновременно отображаются на экране !
    80 :' Недостаток: заметное мигание изображения
    81 :' Эта возможность используется в программе PAINTER
    82 :' (меню Tool.Show Canvas)
    90 A$=INPUT$(1)             :' З а д е р ж к а

    Кроме того, видеопроцессор поддерживает функцию черезстрочного отображения. Отображение первого и второго полей на одной и той же странице можно получить, установив бит IL (третий бит регистра с номером 9) в 1.

    Отображение чётной страницы в первом поле и нечётной страницы во втором поле можно получить, выполнив следующее: 1) установить бит IL (третий бит регистра с номером 9) в 1; 2) установить бит ЕО (второй бит регистра с номером 9) в 1; 3) задать базовый адрес Таблицы имён шаблонов нечётной страницы (регистр с номером 2).

    Пример 5.
    1123-05.bas
    1123-05.bas

    10 COLOR 15,1,1: SCREEN 7                   ' Режим растровой графики
    15 ' Обратите внимание на координаты линий !
    20 SET PAGE 0,0:CLS:LINE (0,100)-(511,100),15 'На странице 0 рисуем линию
    30 SET PAGE 1,1:CLS:LINE (0,100)-(511,100),8 ' На 1–й странице тоже рисуем линию
    31 VDP(9+1)=&B00001100
    32 '              │└─────── Отображаем четную страницу в первом поле
    33 '              └──────── и нечетную страницу во втором поле
    34 'Линии накладываются друг на друга на 1/2 (!) точки
    40 A$=INPUT$(1)   ' Задержка
    41 VDP(9+1)=0     ' Выключим мигание
    • Регистр с номером 20 называется регистром цветовой вспышки 1.
    • Регистр с номером 21 называется регистром цветовой вспышки 2.
    • Регистр с номером 22 называется регистром цветовой вспышки 3.

    Данные регистры инициализируются при включении компьютера следующим образом:

    Номер бита 7 6 5 4 3 2 1 0
    Регистр 20 0 0 0 0 0 0 0 0
    Регистр 21 0 0 1 1 1 0 1 1
    Регистр 22 0 0 0 1 0 1 0 1

    Если все величины в трёх вышеуказанных регистрах равны нулю, то сигнал «цветовой вспышки» на NTSC–видеовыходе будет отсутствовать. Если же вышеуказанные величины затем возвращаются в исходное состояние, то будет получен обычный сигнал «цветовой вспышки» на NTSC–видеовыходе.

XI.2.4. Регистры управления экраном

Регистрами управления экраном будем называть регистры с номерами 18, 19, 23. Эти регистры используются для управления отображением на дисплее.

  1. Использование регистра с номером восемнадцать даёт возможность центрирования изображения относительно электронно–лучевой трубки дисплея:

                              Регистр с номером 18
            ┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┐
            │      │  Параметр смещения │      │  Параметр смешения │
            │      │      вверх–вниз    │      │     вправо–влево   │
            └──▲───┴──────┴──────┴──────┴──▲───┴──────┴──────┴──────┘
               │                           │
     Флаг смещения вверх–вниз:          Флаг смещения вправо–влево:
     1 означает смещение экрана вниз;   1 означает смещение экрана вправо;
     0 означает смещение экрана вверх   0 означает смещение экрана влево

    А теперь посмотрите на фрагмент алгоритма нахождения величины смещения экрана, который записан на школьном алгоритмическом языке:

      если   Флаг смещения = 1
      ────
    │     то      Величина смещения = 8 - параметр смещения
    │     ──
    │     иначе   Величина смещения = параметр смещения
    │     ─────
    │ все
      ───

    Пример 1. Сдвинем экран влево на 2 точки и вниз на 5 точек.
    1124-01.bas
    1124-01.bas

           10 VDP(18+1)=&B10110010
                          ▲└▲┘▲└▲┘
    Смещение экрана вниз ─┘ │ │ └─ 2 точки
                   5=8-3 ───┘ └─── Смещение экрана влево

    На компьютерах MSX 2 по умолчанию «содержимое» регистра с номером 18 по умолчанию задаётся оператором

    SET ADJUST (X,Y)

    Значения выражений X и Y принадлежат отрезку [-7,8].

  2. Можно установить прерывание в момент, когда видeопроцессор начинает сканировать определённую линию. Для получения прерывания используется регистр с номером девятнадцать, в котором хранится номер линии.
  3. Регистр 23.

    Взгляните на рисунок, и Вы увидите, как изменяется изображение символов на текстовом экране в зависимости от содержимого 23–го регистра (значимыми при этом являются только три младших бита):

        VDP(23+1)=0       VDP(23+1)=1       VDP(23+1)=2       VDP(23+1)=3
     ┌─┬─┬─┬─┬─┬─┬─┬─┐ ┌─┬─┬─┬─┬─┬─┬─┬─┐ ┌─┬─┬─┬─┬─┬─┬─┬─┐ ┌─┬─┬─┬─┬─┬─┬─┬─┐
     │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │█│ │█│ │ │ │
     │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │█│ │█│ │ │ │ │█│ │█│ │█│ │ │ │
     │█│ │ │ │█│ │ │ │ │█│ │█│ │█│ │ │ │ │█│ │█│ │█│ │ │ │ │█│█│ │█│█│ │ │ │
     │█│ │█│ │█│ │ │ │ │█│ │█│ │█│ │ │ │ │█│█│ │█│█│ │ │ │ │█│ │ │ │█│ │ │ │
     │█│ │█│ │█│ │ │ │ │█│█│ │█│█│ │ │ │ │█│ │ │ │█│ │ │ │ │ │ │ │ │ │ │ │ │
     │█│█│ │█│█│ │ │ │ │█│ │ │ │█│ │ │ │ │ │ │ │ │ │ │ │ │ │█│ │ │ │█│ │ │ │
     │█│ │ │ │█│ │ │ │ │ │ │ │ │ │ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │
     │ │ │ │ │ │ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │
     └─┴─┴─┴─┴─┴─┴─┴─┘ └─┴─┴─┴─┴─┴─┴─┴─┘ └─┴─┴─┴─┴─┴─┴─┴─┘ └─┴─┴─┴─┴─┴─┴─┴─┘
    
        VDP(23+1)=4       VDP(23+1)=5       VDP(23+1)=6       VDP(23+1)=7
     ┌─┬─┬─┬─┬─┬─┬─┬─┐ ┌─┬─┬─┬─┬─┬─┬─┬─┐ ┌─┬─┬─┬─┬─┬─┬─┬─┐ ┌─┬─┬─┬─┬─┬─┬─┬─┐
     │█│ │█│ │█│ │ │ │ │█│█│ │█│█│ │ │ │ │█│ │ │ │█│ │ │ │ │ │ │ │ │ │ │ │ │
     │█│█│ │█│█│ │ │ │ │█│ │ │ │█│ │ │ │ │ │ │ │ │ │ │ │ │ │█│ │ │ │█│ │ │ │
     │█│ │ │ │█│ │ │ │ │ │ │ │ │ │ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │
     │ │ │ │ │ │ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │
     │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │█│ │█│ │ │ │
     │█│ │ │ │█│ │ │ │ │█│ │ │ │█│ │ │ │ │█│ │█│ │█│ │ │ │ │█│ │█│ │█│ │ │ │
     │█│ │ │ │█│ │ │ │ │█│ │█│ │█│ │ │ │ │█│ │█│ │█│ │ │ │ │█│█│ │█│█│ │ │ │
     │█│ │█│ │█│ │ │ │ │█│ │█│ │█│ │ │ │ │█│█│ │█│█│ │ │ │ │█│ │ │ │█│ │ │ │
     └─┴─┴─┴─┴─┴─┴─┴─┘ └─┴─┴─┴─┴─┴─┴─┴─┘ └─┴─┴─┴─┴─┴─┴─┴─┘ └─┴─┴─┴─┴─┴─┴─┴─┘

    Пример 2.
    1124-02.bas
    1124-02.bas

    5 SCREEN 0
    10 CLS:KEYOFF
    20 FOR I=0 TO 5:PRINT "▧▨▧▨▧":NEXT
    30 FOR J=0 TO 7
    40    FOR K=0 TO 10:NEXT K
    50    VDP(23+1)=J
    60 NEXT J
    70 IF INKEY$="" THEN 30
    80 VDP(23+1)=0:END

    В графических режимах регистр с номером 23 предоставляет другую интересную возможность. Вначале следует вспомнить, что доступная высота графического экрана равна 192 или 212 линиям (в зависимости от девятого регистра VDP). Однако, Вы можете, воздействуя на VRAM (используя, например, оператор VPOKE), сформировать шаблоны 256 линий, просмотрев которые Вы можете, использовав регистр с номером 23. Понять, как это происходит, Вы можете из следующих рисунков:

    VDP(23+1)=0:      ┌─────────────────┐ Y=0
                      │  Видимые линии  │
                      ├─────────────────┤ Y=192 или 212
                      │ Невидимые линии │
                      └─────────────────┘ Y=255
    
    VDP(23+1)=200:    ┌─────────────────┐ Y=0
                      │  Видимые линии  │
                      ├─────────────────┤ Y=136 или 156
                      │ Невидимые линии │
                      ├─────────────────┤ Y=200
                      │  Видимые линии  │
                      └─────────────────┘ Y=255

XI.2.5. Некоторые регистры доступа

Имеется возможность изменить палитру некоторого цвета.

Для установки данных в девятибитные регистры палитры видеопроцессора (с номерами от 0 до 15) следует вначале установить номер регистра палитры в регистре с номером шестнадцать, а затем последовательно вывести два байта данных (по порядку) через порт &H9A.

Номера бит 7 6 5 4 3 2 1 0
Регистр 16 0 0 0 0 Номер палитры
Порт &H9A 0 Красный 0 Синий
Порт &H9A 0 0 0 0 0 Зелёный

Для изменения цвета надо набрать последовательно команды (операторы):

VDP(16+1)=C:OUT &H9A,16*R+B:OUT &H9A,G

,

где:

  • C — номер цветовой палитры, которую Вы хотите изменить;
  • R, B, G — числа, определяющие соотношение красного, синего и зелёного цветов в палитре.

Пример 1.
1125-01.bas
1125-01.bas

COLOR 15,3
Ok
VDP(16+1)=3:OUT &H9A,64:OUT &H9A,3
Ok

Отметим, что для компьютеров MSX 1 этот способ изменения цветов является единственно возможным!

Пример 2.
1125-02.bas
1125-02.bas

10 COLOR 8,15,0:KEY OFF:SCREEN 1
20 FOR R=0 TO 7:FOR G=0 TO 7:FOR B=0 TO 7
30 OUT &H99,0:OUT &H99,16 OR &H80:OUT &H9A,16*R+B:OUT &H9A,G
40 LOCATE 10,10:?"R="R:LOCATE 10,11:?"G="G:LOCATE 10,12:?"B="B
50 FOR T=1 TO 500:NEXT T:NEXT B,G,R

Регистр с номером семнадцать хранит информацию о косвенном доступе в регистры VDP.

Взгляните на его содержимое:

7 6 5 4 3 2 1 0
0 Номер регистра
0 запрещено
1 разрешено
∗ = автоинкрементирование

В соответствии со значением 7–го бита регистра 17 содержимое этого регистра может автоматически увеличиваться. Если автoинкрементирование запрещено, то содержимое 17–го регистра останется прежним.

Приведём два способа косвенной записи в видеопроцессор с использованием регистра с номером 17:

  1. α)
    10 VDP(17+1)=N OR &H80'или OUT &H99,N OR &H80:OUT &H99,17 OR &H80
    20 OUT &h9B, Число для регистра с номером N
    30 OUT &h9B, Число для регистра с номером N+1
    40 OUT &H9B, Число для регистра с номером N+2
    50 ' ···

    Пример 3.
    1125-03.bas
    1125-03.bas

    5 SCREEN 1:COLOR 15,0,8
    10 VDP(17+1)=8 OR &H40 'Установка регистра с номером 17 на косвенный доступ
    20 OUT &H9B,VDP(8+1) OR &H20  'Цвет 0 из Таблицы палитр
    30 OUT &H9B,VDP(9+1) OR &H80  'На экране - 26.5 строк
  2. β)
    10 VDP(17+1)=N               'или OUT &H99,N:OUT &H99,17 OR &H80
    20 OUT &H9B, Число для регистра N
    30 OUT &H9B, Число для регистра N
    40 OUT &H9B, Число для регистра N
    50 ' ···

    Косвенный доступ к регистрам видеопроцессора применяется тогда, когда необходимо записать информацию в несколько регистров, адреса которых идут подряд. При этом запись через порт с адресом &H9B будет происходить до тех пор, пока не будет сделана новая установка на косвенный доступ.

Данные в 17–ом регистре не могут быть изменены косвенной адресацией!

XI.2.6. Доступ к видеопамяти

Регистр 14 (регистр базового адреса доступа к VRAM).

Этот регистр видеопроцессора используется при доступе к видеопамяти. Если Вы располагаете видеопамятью объёмом до 16 Кбайт, то использование этого регистра не имеет смысла, так как в нем хранятся старшие биты текущего адреса видеопамяти.

Регистр с номером 14

Номера бит 7 6 5 4 3 2 1 0
0 0 0 0 0 A16 A15 A14

В регистре с номером 14 устанавливаются три старших бита адреса ячейки видеопамяти (A16, A15, A14).

Сейчас мы расскажем, как обратиться к любой ячейке видеопамяти.

На компьютерах серии MSX 2 существует 2 типа видеопамяти: VRAM и ERAM. VRAM («Video RAM») имеет объем в 128 Кб, а ERAM («Expanded RAM») — 64 Кб. Информация о том, какая видеопамять используется в настоящий момент, хранится в регистре с номером 45.

Доступ к видеопамяти осуществляется в следующей последовательности:

  1. выберите тип видеопамяти:
    VDP(45+1)=&B0∗∗∗∗∗∗∗
                 ▲└──▲─┘
                 │   └── эти биты используются для других целей
                 ├────── 1 — если используется ERAM
                 └────── 0 — если используется VRAM

    Отметим, что содержимое регистра с номером 45 не меняется при очередном обращении к памяти.

  2. установите биты A14÷A16 адреса видеопамяти:
    VDP(14+1)=&B00000∗∗∗
                     ▲▲▲
              A16 ───┘│└─── A14
                      └──── A15
  3. установите биты A0÷A7 счётчика адреса посредством вывода данных в порт &H99:
    OUT &H99,&B∗∗∗∗∗∗∗∗
               ▲▲▲▲▲▲▲▲
               │││││││└──── A0
               ││││││└───── A1
               │││││└────── A2
               ││││└─────── A3
               │││└──────── A4
               ││└───────── A5
               │└────────── A6
               └─────────── A7
  4. установите биты A8÷A13 счётчика адреса и признак чтения или записи посредством вывода данных в порт &H99:
    OUT &H99,&B∗∗∗∗∗∗∗∗
               ▲▲▲▲▲▲▲▲
               │││││││└──── A8
               ││││││└───── A9
               │││││└────── A10
               ││││└─────── A11
               │││└──────── A12
               ││└───────── A13
               └┼────────── 00 — признак чтения
                └────────── 01 — признак записи
  5. А теперь остаётся прочитать или записать данные в нужный байт:
    A=INP(&H98) — чтение
    OUT &H98,A  — запись
  6. После чтения или записи данных содержимое адресного счётчика автоматически увеличивается на единицу. При этом, если есть перенос из бита A13, то в режимах SCREEN 4÷8 происходит увеличение содержимого регистра с номером 14. В режимах SCREEN 1÷3 и в 40–символьном режиме SCREEN 0 увеличения содержимого 14–го регистра не происходит.

Из сказанного следует, что если нужно записать информацию в несколько подряд расположенных ячеек видеопамяти, достаточно установить лишь начальный адрес этой группы ячеек.

XI.2.7. Регистры статуса

Кроме регистров VDP, видеопроцессор работает с группой регистров, называемыми регистрами статуса. Данные регистры содержат информацию о состоянии видеопроцессора. Из них информацию можно только читать.

Текущий номер регистра статуса записывается в регистр VDP с номером пятнадцать (регистр–указатель регистра состояния).

Номера бит 7 6 5 4 3 2 1 0
0 0 0 0 Номер регистра статуса

Для доступа к регистрам состояния видеопроцессора (с номерами 0,1,2,3,…,9) вначале нужно установить номер регистра статуса в регистре с номером 15, а затем прочесть данные через порт &H99.

Для записи в переменную W числа из регистра статуса с номером S, выполните следующие действия:

VDP(15+1)=S:W=INP(&H99):VDP(15+1)=0

Регистр статуса номер 0.

    7      6      5      4      3      2      1      0
┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┐
│      │      │      │   ∗  │   ∗  │   ∗  │   ∗  │   ∗  │
└───▲──┴───▲──┴──▲───┴──────┴──────┴──────┴──────┴──────┘
    │      │     │    └───▲──────────────────────────────┘
    │      │     │        └ Экранный номер пятого или девятого
    │      │     │          (в зависимости от режима SCREEN) спрайта в строке
    │      │     └─── Флаг, указывающий на столкновение 2–х спрайтов
    │      │
    │      └───────── Флаг обнаружения пятого (или девятого) спрайта в строке
    │                 
    └──────────────── Флаг прерывания от вертикального сканирования
                      (после чтения регистра состояния 0 данный флаг сбрасывается)

Если бит СС=0 и высвечиваемые части шаблонов спрайтов перекрываются, то устанавливается столкновение спрайтов. Если столкновение спрайтов обнаружено, то бит 5 регистра статуса с номером 0 устанавливается в 1.

Этот бит устанавливается в 0 после чтения регистра статуса с номером 0.

Использование регистра статуса с номером 0 рассмотрим на примерах.

Пример 1.
1127-01.bas
1127-01.bas

10 SCREEN 1,2
20 SPRITE$(2)="Проверка":SPRITE$(3)="на столкновение"
30 FOR T=1 TO 130
40 PUT SPRITE 2,(T,80):PUT SPRITE 3,(240-T,80)
50 VDP(15+1)=0:Z=INP(&H99) AND 32
60 IF Z<>0 THEN PRINT "Столкновение состоялось!"
70 NEXT

Пример 2.
1127-02.bas
1127-02.bas

10 SCREEN 1:KEYOFF
20 FOR I=0 TO 7:READ E:VPOKE &H3800+I,E:NEXT
30 A0=BASE(1*5+3):AD=A0+4*1:AP=A0+4*2
40 VPOKE AP,50:VPOKE AP+1,100:VPOKE AP+2,0:VPOKE AP+3,15
50 FOR X=0 TO 255
60 VPOKE AD,50:VPOKE AD+1,X:VPOKE AD+2,0:VPOKE AD+3,15
70 VDP(15+1)=0:Z=INP(&H99) AND 32
80 IF Z<>0 THEN LOCATE 1,1:PRINT"столкновение":FOR L=0 TO 100:NEXT:LOCATE1,1:PRINT"               "
90 NEXT
100 GOTO 50
110 DATA 255,255,195,195,195,195,255,255

Пример 3.
1127-03.bas
1127-03.bas

10 SCREEN1,2
20 SPRITE$(1)="Проверка":SPRITE$(2)="появления":SPRITE$(3)="пятого":SPRITE$(4)="спрайта":SPRITE$(5)="в строке"
30 PUT SPRITE0,(10,80),,5:PUT SPRITE1,(20,80),,4:PUT SPRITE2,(30,80),,3:PUT SPRITE3,(40,80),,2
40 VDP(15+1)=0:Z=INP(&H99)
50 PRINT RIGHT$("00000000"+BIN$(Z),8)
55 A$=INPUT$(1)
60 PUT SPRITE4,(50,80),,1
70 VDP(15+1)=0:Z=INP(&H99)
80 ? RIGHT$("00000000"+BIN$(Z),8);"◀─ Появился 5-ый спрайт в строке!"

Отметим, что содержимое регистра статуса с номером 0 можно прочесть не только функцией INP, но и при помощи псевдопеременной VDP:

A = VDP(8)

.

Пример 4. Управление столкновениями спрайтов.
1127-04.bas
1127-04.bas

20 SCREEN 2,2
30 SPRITE$(0)=STRING$(32,255)
40 PUT SPRITE 0,(112,80),1,0
50 PUT SPRITE 1,(10,80),8,0
60 IF (VDP(8)AND32)=32 THEN GOTO 90
70 PUT SPRITE 1,STEP(1,0),8,0
80 GOTO 60
90 BEEP:GOTO 90

Замечание. Назначения бит регистров статуса с номерами 1, 2, 3, 4, 5, 6, 7, 8, 9 рассмотрены в Приложении 2 1). Там же рассмотрены назначения бит командных регистров с номерами 32,33,… ,45,46.

XI.3. Нестандартные режимы видеопроцессора


Боги открыли людям не все.
В поиск пустившись, люди сами открыли немало.

Ксенофан

XI.3.1. Режим SCREEN 4 на компьютерах MSX 1

Для Вас, наверное, окажется неожиданностью, что на компьютерах MSX 1 можно использовать режимы SCREEN 4 ÷ SCREEN 8. Доступ к этим режимам осуществляется путём непосредственной записи в регистры видеопроцессора.

Режим SCREEN 4 вызывается из режима SCREEN 2 путём обращения к видеопроцессору:

VDP(0)=4    .

При этом изображение, нарисованное в режиме SCREEN 2, останется на экране. Этот режим выгодно отличается возможностями работы со спрайтами.

Приведём начальные адреса Таблиц VRAM, отвечающих за спрайты, в этом режиме:

Имя Таблицы Начальный адрес Таблицы
SGT &H3800
SAT &H1A00
SCT &H1800

Чтобы вернуться в режим SCREEN 2, достаточно снова обратиться к видеопроцессору:

 VDP(0)=2     .

Учтите, что режим SCREEN 4 на компьютерах серии MSX 1 имеет некоторые особенности:

  1. происходит частичное «наложение» Таблиц SAT и SCT на Таблицу PNT, что приводит к искажению неподвижного изображения. Поэтому необходимо «спасти» Таблицу PNT, т.е. передвинуть её на свободное место в видеопамяти;
  2. при переходе в этот режим возникает несоответствие между начальным адресом Таблицы SAT, возвращаемым псевдопеременной BASE(13),и тем же адресом,хранящимся в рабочей области RAM. Поместите поэтому в рабочую область RAM по адресам &HF928 и &HF929 число, записанное в псевдопеременной BASE(13);
  3. образы спрайтов выводятся на экран уже на стадии формирования спрайтовых переменных.Единственный способ избавиться от этого — временно отключить изображение (без очистки экрана) и включить его непосредственно перед обращением к Таблице атрибутов спрайтов (SAT).

А теперь взгляните на

Пример 1. Вы, конечно, помните, что текущий адрес Таблицы PNT хранится в рабочей области по адресам &HF922 и &HF923.
1131-01.bas
1131-01.bas

10 SCREEN 2,2
20 'Инициализация режима SCREEN 4
50 VDP(2)=7:POKE &HF923,&H1C 'Передвинем Таблицу PNT
60 VDP(5)=52:POKE &HF929,&H1A 'Приведем в порядок SAT
65 VDP(0)=4 'Установим режим SCREEN 4
70 'Основная программа
75 VDP(1)=VDP(1) XOR 64 'Отключим изображение
80 CIRCLE(100,100),50,15
90 FOR X=0 TO 8
100 SPRITE$(X)=STRING$(32,255):NEXT 'Сформируем спрайты
110 FOR Y=0 TO 15:V=INT(RND(1)*16)
120    FOR X=0 TO 8
130    VPOKE &H1800+X*16+Y,V 'Раскрасим спрайты, используя Таблицу SCT
140 NEXT X,Y
150 VDP(1)=VDP(1) XOR64 'Включим изображение
160 PUT SPRITE 8,(70,30),,0
170 X=128:Y=96
180 A=STICK(0)
190 IF A=1 OR A=2 OR A=8 THEN Y=Y-2
200 IF A=2 OR A=3 OR A=4 THEN X=X+2
210 IF A=4 OR A=5 OR A=6 THEN Y=Y+2
220 IF A=6 OR A=7 OR A=8 THEN X=X-2
230 FOR Z=0 TO 7
240    PUT SPRITE Z,(X-Z*17,Y),,0  'В о с е м ь  спрайтов в строке!
250 NEXT Z
260 GOTO 180

Вас, конечно, не удивляет тот факт, что на экране — восемь спрайтов в строке, так как Вам, наверное, известно, что режимы SCREEN 4 ÷ SCREEN 8 предоставляют такую возможность!

XI.3.2. Текстово–графические режимы

Мы опишем здесь два текстово–графических режима:

  • режим SCREEN 1–2 («совмещённый» режим SCREEN 1 и SCREEN 2);
  • режим SCREEN 1–4 («совмещённый» режим SCREEN 1 и SCREEN 4).

«Совмещенный» режим SCREEN 1–2 устанавливается операторами:

SCREEN 1:DEFUSR=&H7E:A=USR(0)

.

Однако прежде чем начать «работать» в этом режиме, его надо инициализировать следующим образом:
1132-00.bas
1132-00.bas

10 SCREEN1:WIDTH 32
20 DEFUSR=&H7E:A=USR(0) 'Установили совмещенный режим
30 'Считываем шаблоны символов из ROM в Таблицу PGT
40 FOR T=0 TO 2
50    FOR K=0 TO 2047
60       VPOKE BASE(7)+2048*T+K,PEEK(&H1BBF+K)
70 NEXT K,T
80 'Инициализируем цвета символов в Таблице CT
90 FOR I=0 TO 6143:VPOKE BASE(6)+I,&HF4:NEXT I
100 'Установим форму курсора во 2-м и 3-м окне экрана
110 FOR Y=1 TO 2:FOR X=0 TO 7:VPOKE &H800*Y+255*8+X,255:NEXT X,Y
120 NEW

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

Пример 1. Смотрите и завидуйте!
1132-01.bas
1132-01.bas

100 CLEAR 100,&HD000
110 SCREEN 1:WIDTH 32:DEFUSR=&H7E:A=USR(0)
120 A$="21000011BF1B1ACD1CD03EF0CBECCD1CD0CBAC13237CD608C206D0C947CD4D00CBDC78CD4D00CB9CCBE478CD4D00CBA4C9"
130 FOR X=0 TO 48:POKE &HD000+X,VAL("&h"+MID$(A$,X*2+1,2)):NEXT
140 DEFUSR=&HD000:A=USR(0)
150 FOR Y=1 TO 2:FOR X=0 TO 7:VPOKE &H800*Y+255*8+X,255:NEXT X,Y

Поговорим об особенностях режима SCREEN 1–2 :

  1. Данный режим позволяет формировать многоцветные символы, причём информация о цветах каждого из них хранится в восьми байтах Таблицы CT:

               1–й байт           …              8–й байт
    ┌─────────────┬─────────────┬─────┬─────────────┬─────────────┐
    │  Код цвета     Код цвета  │     │  Код цвета     Код цвета  │
    │ изображения │     фона    │     │ изображения │     фона    │
    │ для  первой   для  первой │  …  │ для восьмой   для восьмой │
    │   строки    │   строки    │     │   строки    │    строки   │
    │   символа       символа   │     │   символа        символа  │
    └─────────────┴─────────────┴─────┴─────────────┴─────────────┘

    Проведём аналогию с режимом SCREEN 1:

              1–й байт CT
    ┌─────────────┬─────────────┐
    │  Код цвета     Код цвета  │
    │ изображения │     фона    │
    │ для первых    для  первых │
    │   восьми    │    восьми   │
    │  символов       символов  │
    └─────────────┴─────────────┘
  2. Режим SCREEN 1–2 имеет трёхоконную структуру(как и режим SCREEN 2):

    Внимательно изучите следующую табличку:

    Адрес Комментарий
    &H0000 Таблица шаблонов образов, расположенных в верхней части экрана, т.е. с 0–й по 7–ю строку. На каждый символ отводится 8 байтов
    &H0800 Таблица шаблонов символов, расположенных в средней части экрана, т.е. с 8–й по 15–ю строку
    &H1000 Таблица шаблонов символов, расположенных в нижней части экрана, т.е. с 16–й по 23–ю строку
    &H1800 Таблица имён образов (строки 0÷7)
    &H1900 Таблица имён образов (строки 8÷15)
    &H1A00 Таблица имён образов (строки 16÷23)
    &H1B00 Таблица атрибутов спрайтов
    &H2000 Таблица цветов символов, расположенных с 0–ой по 7–ю строку.
    На каждый символ отводится 8 байтов. На каждую строку символа отводится 1 байт, старший полубайт которого отвечает за цвет установленных бит в Таблице шаблонов символов
    &H2800 Таблица цветов символов, расположенных с 8–ой по 15–ю строку
    &H3000 Таблица цветов символов, расположенных с 16–ой по 23–ю строку
    &H3800 Таблица шаблонов спрайтов
  3. В режиме SCREEN 1–2 разрешено использование как текстовых,так и графических операторов, т.о. «совмещённый» режим SCREEN 1–2 может находиться в двух «состояниях».

Во–первых, это — текстовый режим.В нем «работают» все операторы текстового экрана. Однако, он отличается от текстового режима SCREEN 1 в следующих моментах:

  1. весь экран разбит на три горизонтальных окна;
  2. символ, вообще говоря, раскрашен одновременно в 16 цветов (по два цвета на линию);
  3. один и тот же символ (определяемый кодом АSCII), может быть различным по начертанию и цвету в трёх различных окнах экрана.

Для изменения цвета какой–либо строки любого символа в любой трети экрана, примените оператор:

VPOKE BASE(5+1)+2048*N+8*K+S,&HIF

,

где:

  • N — номер окна экрана;
  • K — код ASCII символа;
  • S — номер строки символа;
  • I — цвет изображения;
  • F — цвет фона.

Для изменения шаблона одной строки символа используйте оператор

VPOKE BASE(5+2)+2048*N+8*K+S,&B∗∗∗∗∗∗∗∗

,

где:

  • N — номер окна экрана;
  • K — код ASCII символа;
  • S — номер строки символа;
  • ∗∗∗∗∗∗∗∗ — двоичное представление шаблона строки символа.

Приведём несколько примеров:

Пример 2. Полюбуйтесь на цветной курсор!
1132-02.bas
1132-02.bas

10 FOR X=0 TO 2
20    A=&H2000+&H800*X+255*8
30    FOR Y=0 TO 7
40       VPOKE A+Y,Y*16
50    NEXT Y
60 NEXT X

Пример 3. А вот «переливание» латинских букв «А» в верхней трети экрана!
1132-03.bas
1132-03.bas

10 FOR A=0 TO 8
20    FOR X=0 TO 7
30       VPOKE &H2000+65*8+X,(X+A)*16
40    NEXT X
50 NEXT A
60 GOTO 10

Чтобы прекратить процесс «переливания», нажмите клавиши CTRL+STOP.

Пример 4. Вместо буквы «W» в верхнем углу экрана Вы уведите… «яблоко»!
1132-04.bas
1132-04.bas

10 OUT&H99,6:OUT&H99,144:OUT&H98,16*4:OUT&H98,2 'Изменим 6-й цвет
20 A$="3C7E307830787E3C8484B8B8B8866414"
30 FOR X=0 TO 7
40  VPOKE 87*8+X,VAL("&H"+MID$(A$,X*2+1,2))
50  VPOKE &H2000+87*8+X,VAL("&H"+MID$(A$,2*X+17,2))
60 NEXT X

Пример 5. «Толстые» символы — только в верхней трети экрана!
1132-05.bas
1132-05.bas

10 FOR X=&HFF TO &H7F7
20    A=VPEEK(X):VPOKE X,A OR A/2
30 NEXT X

Пример 6. Теперь повращаем «трубу» вокруг своей оси!
1132-06.bas
1132-06.bas

10 FOR I=0 TO 7:VPOKE 8*43+I,255:NEXT
20 CLS:PRINT"++++++++++++++++++++++++++++++"
30 FOR F=7 TO 0 STEP -1
40    VPOKE &H2000+&H800*0+8*43+F,&H71
50    IF F=7 THEN W=0 ELSE W=F+1
60    VPOKE &H2000+&H800*0+8*43+W,&H51
70    IF W=7 THEN WC=0 ELSE WC=W+1
80    VPOKE &H2000+&H800*0+8*43+WC,&H41
90    IF WC=7 THEN JC=0 ELSE JC=WC+1
100   VPOKE &H2000+&H800*0+8*43+JC,&H51
110   IF JC=7 THEN JJ=0 ELSE JJ=JC+1
120   VPOKE &H2000+&H800*0+8*43+JJ,&H71
130   IF JJ=7 THEN YJ=0 ELSE YJ=JJ+1
140   VPOKE &H2000+&H800*0+8*43+YJ,&HF1
150 NEXT:GOTO 30

Во–вторых, режим SCREEN 1–2 — это графический режим, в котором можно одновременно и рисовать, и выводить текст. Для этого предварительно решите, в какой части экрана (одной или нескольких) Вы будете рисовать, а в какой — писать.

Для того, чтобы рисовать в какой–либо части экрана, её надо предварительно подготовить следующим образом:

FOR T=0 TO 255 :VPOKE BASE(5)+256*N+T,T      :NEXT
FOR T=0 TO 2047:VPOKE BASE(5+1)+2048*N+T,&HF4:NEXT
FOR T=0 TO 2047:VPOKE BASE(5+2)+2048*N+T,0   :NEXT

,

где N — номер части экрана, в которой Вы хотите применить графические операторы.

Таким образом, Вы инициализируете участки Таблиц PNT, CT и PGT, отвечающие за изображение в нужном окне экрана.

Теперь в приготовленной части экрана можно применять графические операторы. Однако, их можно применять только после выполнения оператора:

POKE &HFCAF,2

.

Для выхода в текстовый режим «пригодится» оператор:

POKE &HFCAF,1

.

Если Вы его не выполните, то произойдёт переход в режим SCREEN 1 !

Нужно постоянно помнить о том, что Ваши рисунки могут «портиться», так как любой символ, напечатанный в графической части экрана, портит рисунок. Однако, рисунок можно восстановить, применив операторы:

FOR T=0 TO 255:VPOKE BASE(5)+256*N+T,T:NEXT

Пример 7. В верхней части экрана — графический режим!
1132-07.bas
1132-07.bas

10 CLS
20 FOR X=0 TO 255:VPOKE &H1800+X,X:NEXT
30 FOR X=0 TO &H7FF:VPOKE X,0:NEXT
40 LOCATE 5,10:PRINT"Вверху графика!"
50 POKE &HFCAF,2
60 LINE (20,10)-(100,40),15,BF
70 CIRCLE (80,30),40,8
80 POKE &HFCAF,1

Рассмотрим теперь «совмещённый» режим SCREEN 1–4. Единственное отличие режима SCREEN 1–4 от режима SCREEN 1–2 состоит в том, что в нем разрешена работа с многоцветными спрайтами (как и в режиме SCREEN 4).

Инициализируется режим SCREEN 1–4 следующим образом:
1132-08.bas
1132-08.bas

10 SCREEN 1:WIDTH 32
15 'Установим режим SCREEN 1-2
20 DEFUSR=&H7E:A=USR(0)
30 'Считываем шаблоны символов из ROM в Таблицу PGT
40 FOR T=0 TO 2
50    FOR K=0 TO 2047
60       VPOKE BASE(7)+2048*T+K,PEEK(&H1BBF+K)
70 NEXT K,T
80 'Инициализируем цвета символов в Таблице CT
90 FOR I=0 TO 6143:VPOKE BASE(6)+I,&HF4:NEXT I
100 'Установим форму курсора во 2-м и 3-м окнах экрана
110 FOR Y=1 TO 2:FOR X=0 TO 7:VPOKE &H800*Y+255*8+X,255:NEXT X,Y
115 'Теперь установим режим SCREEN 1-4
120 VDP(2)= 7:POKE &HF923,&H1C 'Передвинем Таблицу PNT
140 VDP(5)=52:POKE &HF929,&H1A 'Приведем в порядок SAT
150 VDP(0)=4:CLS:NEW

Все сказанное о режиме SCREEN 1–2, распространяется и на режим SCREEN 1–4. Остаётся только добавить, что структура видеопамяти в «совмещённом» режиме SCREEN 1–4 полностью совпадает со структурой VRAM в режиме SCREEN 4 для компьютеров серии MSX 1.

Диск с примерами

1)
Пока не найдено, подробнее здесь
msx/basic_programming_guide/11.1569183714.txt.gz · Последние изменения: 2019-09-22 23:21 (внешнее изменение)