Г Л А В А 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 │ И м я Таблицы │ ├───┼───────────────────────────────────────┤ │ 0 │ PNT │ │ 1 │ CT (кроме режимов SCREEN 3,5,6,7,8 и│ │ │ 40-символьного режима SCREEN 0) │ │ 2 │ PGT (кроме режимов SCREEN 5,6,7,8) │ │ 3 │ SAT (кроме режима SCREEN 0) │ │ 4 │ SGT (кроме режима 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 │ ├───────┼────────┼────────┤ Таблица PT для всех режимов │ 0 (40)│ &H0400 │ ── │ SCREEN занимает в видеопамяти │ 0 (80)│ &H0800 │ ── │ 32 байта. │ 1 │ &H2020 │ ── │ Таблица SCT для всех режимов │ 2 │ &H1B80 │ ── │ SCREEN занимает в видеопамяти │ 3 │ &H2020 │ ── │ 512 байтов. │ 4 │ &H1E80 │ &H1C00 │ │ 5 │ &H7680 │ &H7400 │ │ 6 │ &H7680 │ &H7400 │ │ 7 │ &HFA80 │ &HF800 │ │ 8 │ &HFA80 │ &HF800 │ └───────┴────────┴────────┘ β) А теперь -синтаксис псевдопеременной 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 М , где М - номер режима. 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 ?!) ───────────── в видеопамяти, а затем "извлечем его" оттуда. 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. ───────────── 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