Впечатывание страниц.
Следующий вопрос, который мы рассмотрим, - это как дать компьютеру указание о том, какую страницу ПЗУ или какую страницу ОЗУ нужно впечатать.
Это выполняется с помощью команды OUT. Ключом же к этой операции служит внешний порт 7FFD. Вы можете представить себе его как некий дополнительный регистр процессора, поскольку там может находиться число от 0 до 255. Как в ячейку памяти, туда можно отправить новое число, но в отличие от нее, считать число оттуда нельзя. В машинном коде выдача байта n по этому порту запишется так: LD A, n LD ВС, 7FFD OUT (С),A
Число, выдаваемое через этот порт и определяет какая страница ПЗУ и ОЗУ будет впечатана. На рис.1 показано, какие функции выполняют отдельные биты байта, выдаваемого на порт 7FFD.
7 6 5 4 3 2 1 0
Номер страницы ОЗУ Номер экрана Номер страницы ПЗУ Переключатель режимов 128/48. Не используются
Рис.1
Как видно из рисунка, младшие три бита задают страницу ОЗУ (от 0 до 7). Четвертый бит задает страницу ПЗУ (0 или 1). Про прочие биты мы поговорим чуть позже.
В то же время, использование порта 7FFD доставляет одну маленькую проблему. Выдачей байта на этот порт можно переключать страницы, но поскольку нельзя прочитать значение, там находящееся, то и нельзя определить, какие же именно страницы в данный момент впечатаны.
Чтобы уйти от этой трудности, SPECTRUM 128 оставляет копию байта, выданного на этот порт в одной из своих новых системных переменных (которых не было в SPECTRUM 48). Эта системная переменная называется BANK_M и хранится в ячейке памяти с адресом 5В5С. Теперь Вы можете, прочитав содержимое этого адреса, определить, какие страницы у Вас впечатаны.
В то же время, это означает, что когда Вы выдаете байт на порт 7FFD, Вам следует
применять меры и для того, чтобы отправить в BANK_M его копию, в противном случае, когда управление от Вашей программы будет передано ПЗУ, произойдет зависание или сброс компьютера.
Кроме того, процедуры обработки прерываний, расположенные в адресах 00038 и 10038 требуют, чтобы по крайней мере бит 4 системной переменной ВАNК_М был выставлен точно. Это означает, что прежде чем заниматься переключением страниц ПЗУ, Вы должны отключить обработку прерываний. Вдобавок к этому, при выходе из процедуры обработки прерываний значение, содержащееся в BANK_M выдается на порт 7FFD, так что если они не совпадают, то возможны неприятности. Это означает, что при переключении страниц ОЗУ (или смене экранов, о чем чуть позже) Вы должны либо отключать прерывания, либо сначала загружать нужный байт в BANK_M, а только потом выдавать его на порт 7FFD и не наоборот. Если этого не сделаете, то при первой же обработке прерываний компьютер зависнет.
Экранная память
Как и в "Спектруме 48", здесь экран хранится, начиная с адреса 4000Н. В предыдущем выпуске мы говорили, что за экраном постоянно закреплена пятая страница ОЗУ, т.е. 4000H - это то же самое, что и 5С000.
В свою очередь "Спектрум 128" имеет не одну, а две экранные области памяти, хотя даже сопроводительные руководства по эксплуатации не всегда об этом упоминают.
Оба экрана имеют в памяти свои адреса, но очевидно, что выдаваться на экран они могут только по одному. Традиционная экранная область, выдаваемая при нормальных обстоятельствах, называется SCREEN0, а альтернативная SCREEN1 и хранится SCREEN1 в адресах, начиная с 7C000, т.е. начиная с адреса С000 на странице 7.
Та экранная область, которая в данный момент отображается на экране телевизора, называется активной. Обычно активным экраном является SCREEN0, но Вы можете это изменить из машинного кода включением третьего бита в системной переменной BANK_M и выдачей соответствующего байта на порт 7FFD. После этого на экране будет изображаться содержимое экранной области памяти SCREEN1.
Черно-белая часть изображения хранится в адресах, начиная с 7С000 по 7D7FF, а атрибуты цвета в адресах с 7D800 по 7DAFF.
Очевидно, что страница 7 должна быть впечатана, чтобы экран SCREEN1 мог сменить экран SCREEN0 но совсем нет необходимости, чтобы страница 7 оставалась впечатанной, чтобы SCREEN1 оставался активным. Может быть впечатана любая страница ОЗУ и, тем не менее, экран SCREEN1 будет изображаться на экране до тех пор, пока он остается активным и убрать его можно будет только активизацией экрана SCREEN0.
Можно переключать текущий экран и из Бейсика, не выходя в машинный код. Команда POKE 23388, 24 активизирует SCREEN1, а команда POKE 23388,16 активизирует SCREEN0.
Если Вы попробуете это сделать, то получите черный экран, т.к. все байты атрибутов у экрана SCREEN 1 содержат нули. К сожалению, из Бейсика нельзя печатать на экране SCREEN1, это можно делать только процедурами, записанными в машинном коде. Тем не менее, следующая техника может быть полезной при загрузке программ: POKE 23388,24: LOAD""SCREEN$ POKE 23388,16
Работает эта программа так: экран гаснет и начинается загрузка в память "картинки", но при этом на экране ничего не изображается. После окончания загрузки вся картинка высвечивается на экране целиком и мгновенно.
Имейте также в виду, что любое сообщение Бейсика об ошибке (и даже 0: OK) автоматически реактивирует SCREEN0, поэтому если Вы забудете отключить SCREEN1, то компьютер во многих случаях сделает это за Вас.
Переключатель режимов
Порт 7FFD имеет еще один бит, который мы не рассмотрели - это бит 5, который в режиме 128K должен быть всегда выключен. Если он включен, то компьютер "запирается" в режиме 48К, при этом постоянно включена первая страница ПЗУ и постоянно активен экран SCREEN0. В то же время, включение бита 5 еще не означает, что этого достаточно для перехода в режим 48K, поскольку машинный стек содержит адреса возврата, относящиеся к ПЗУ0, а поскольку компьютер "заперт", то страница 0 ПЗУ не может быть впечатана.
"Спектрум 128" имеет две новые команды Бейсика - это команды PLAY и SPECTRUM. Команда PLAY служит для воспроизведения музыки но поскольку отечественные модификации 128-го не имеют музыкального процессора, а владельцы фирменных машин имеют фирменные инструкции и могут все прочитать сами, то мы на ней останавливаться не будем, а рассмотрим команду SPECTRUM.
Эта команда имеет двойной эффект. Во-первых, по ней компьютер переключается в режим 48К, а во-вторых выдается сообщение 0:OK, при этом останавливается исполнение текущей программы.