Ликбез - Ассемблер - взгляд издалека: распределение памяти ZX Spectrum.
Ассемблер - взгляд издалека
Продолжение.
Начало в || 20, 21, 24, 25, 28-30,
32, 33, 35
{} Инфарх, 2000
Друзья мои, я опечален! Все имеющиеся в
языке Ассемблер команды нами уже изуче-
ны...
Но не падайте духом! От изучения средств
языка мы переходим непосредственно к прог-
раммированию. Для того, чтобы сей процесс
увенчался успехом, необходимо для начала
как следует усвоить...
Распределение памяти Speccy
Итак, память... С адреса #0000 и по ад-
рес #3fff включительно расположено ПЗУ ва-
шего компьютера. Там прошита операционная
система (ОС). Естественно, в её составе
найдётся немало полезных процедур, которые
попытаются вас соблазнить и заставить ис-
пользовать себя в ваших программах. Конеч-
но, это вполне допустимо. Но не всегда...
ОС - программа высоконадёжная, универ-
сальная. Но за эти плюсы мы вынуждены
расплачиваться тормозами в работе и слож-
ностями при использовании вышеупомянутого
ПЗУ. Лично меня такое состояние дел не
устраивает, и потому все нужные средства я
делаю, по возможности, сам.
Но это лирика, продолжим урок. Следом за
ПЗУ расположена область памяти, отведённая
под экран. Она начинается с адреса #4000 и
заканчивается адресом #5aff. Причём, до
адреса #5900 находится область графики, а
далее - атрибуты.
Затем идут области памяти, занятые пере-
менными ОС. Размеры этих областей меняются
в зависимости от разных факторов, однако,
как правило, можно раcсчитывать на то, что
с адреса #6000 по адрес #ffff - свободное
пространство.
Таким образом, если вы решили работать
полностью независимо от ОС, то можете сме-
ло использовать всю оперативную память.
Однако для того, чтобы иметь возможность
иногда обратиться к ОС, желательно ниже
#6000 не уходить. Не забывайте и о том,
что некоторое количество памяти необходимо
отвести под стек. Мне, как правило, наибо-
лее подходил вариант, при котором значение
регистра SP в самом начале программы уста-
навливалось в #6000. Это давало возмож-
ность использовать те байты, которые ещё
оставались между моей программой и систем-
ными областями.
Кстати, обычно, когда вы находитесь в
оболочке редактора и запускаете программу
из-под него, стек будет установлен так,
что проблем в работе у вас, как правило,
не возникнет.
Но хватит! Пора уже попробовать написать
некую программу. Загрузите ваш редактор.
Заодно вспомните, что разные редакторы
имеют некоторые отличия. Когда я буду при-
водить примеры, имейте в виду, что подра-
зумевается редактор XAS. Если же вы поль-
зуетесь другим, вносите коррективы соглас-
но его специфике.
Итак, начало программы. Как правило, это
оператор ORG, который указывает редактору,
с какого адреса вы хотите разместить код,
полученный после компиляции вашего текста.
Поэтому смело ставьте первой строкой вашей
программы ORG #6000.
Теперь разберёмся, какими ресурсами вы
располагаете, если у вас - Spectrum 128.
Конечно, он имеет те же области памяти,
что и 48-ой вариант. Но помимо их вы може-
те использовать и т.н. "страницы памяти".
Для более успешного понимания этого взгля-
ните на схему:
┌─────────────────┐
│ страница 7 │
┌─────────────────┐ │
│ страница 6 │─┘
┌─────────────────┐ │
│ страница 4 │─┘
┌─────────────────┐ │
│ страница 3 │─┘
┌─────────────────┐ │
│ страница 1 │─┘
╔═════════════════╗ │
║ ║─┘
║ страница 0 ║
║ ║
╠═════════════════╣ #C000
│ │
│ страница 2 │
│ │
├─────────────────┤ #8000
│ │
│ страница 5 │
│ │
├─────────────────┤ #4000
│ │─┐
│ ПЗУ 128 (16k) │ │
│ │ │
└─────────────────┘ │ #0000
│ ПЗУ 48 (16K) │
└─────────────────┘ #0000
Перед вами - модель страничной памяти.
Цифры справа показывают адрес начала об-
ластей памяти, которые мы и рассмотрим по
порядку.
В самом начале расположено ПЗУ.
Далее - экранная область, системные пе-
ременные и всё прочее, что уместится до
адреса #8000. Этой странице памяти присво-
ен |5.
Затем - страница |2 (#8000 - #BFFF).
Вышеназванные страницы всегда находятся
на своём месте и потому никаких проблем с
ними нет. Но вот за ними начинается самое
интересное...
Область памяти с #C000 по #FFFF предназ-
начена для отображения тех страниц, кото-
рые являются дополнительными. При рестарте
там отображается страница |0, вместо кото-
рой можно подключить страницы || 1, 3, 4,
6 или 7. Специфика такова, что может быть
подключена только одна страница, и, пока
она активна, все остальные пребывают "в
тени". Можно провести аналогию с альтерна-
тивным набором регистров (команда EXX,
помните?). Только там было два набора ре-
гистров, а здесь вы видите шесть страниц.
Для их переключения служит порт #7FFD, ку-
да посылается байт управления.
Перед тем, как дать подробное разъясне-
ние каждому биту этого порта, немного об-
щей информации насчёт экрана. В 48-ом ва-
рианте область экранной памяти расположена
начиная с адреса #4000 (страница 5). Для
128-го Спектрума ситуация аналогична,
но...
Область памяти в #1B00 байт, расположен-
ная в странице |7, начиная с адреса #С000,
может быть использована как дополнительный
экран. Его организация будет в точности
соответствовать обычному экрану во всём,
кроме, разумеется, адреса размещения.
А сейчас - опишем порт:
Биты D0-D2 определяют, какая страница
будет отображена с адреса #С000.
Бит D3 заведует активным экраном. Если
он установлен в "0", активен стандартный
экран (в странице 5).
Бит D4 управляет текущим ПЗУ. Он, будучи
установленным в "0", подключает ПЗУ-48, а
при установке его в "1" - ПЗУ-128.
Бит D5 блокирует порт. Если заслать в
него "1", порт отключается и до следующего
Reset'а совершенно недоступен.
Биты D6,D7 проблем не вызывают: они в
128-ом варианте не задействованы.
И, наконец, нечто программоподобное:
ORG #6000
; Активизируем ПЗУ-48, экран |1
; включаем страницу 0
LD BC,#7ffd
LD A,#10
OUT (C),A
; и читаем первый байт
LD HL,#c000
LD A,(HL)
; изменяем его и кладём на
; то же самое место, но в странице 1
CPL
LD E,A
LD A,#11
OUT (C),A
LD (HL),E
; восстанавливаем страницу 0
LD A,#10
OUT (C),A
; её первый байт сравниваем
; с изменённым ранее
LD A,(HL)
CP E
; анализируем результат
JR NZ,mode128
; mode 48
...
...
mode128
Таким образом у нас получилась програм-
ма, определяющая, располагает ли компью-
тер, на котором она запущена, расширенной
памятью. Первый байт страницы 0 мы инвер-
тируем и помещаем в страницу 1. Производим
обратное переключение и сравниваем проин-
вертированный байт с имеющимся. Если они
равны, значит, переключения не произошло и
компьютер, скорее всего, 48-ой. В против-
ном случае переходим в режим работы со
128-ой памятью.
Разберёмся теперь с дополнительным экра-
ном. Для начала возьмите некий экранный
файл и поместите его на диск с именем,
скажем, "screen.C". Для того, чтобы внед-
рить некий кодовый блок с диска в код
программы, используем оператор "LCODE".
Напишем следующее:
ORG #6000
; подключим страницу 7
LD A,#17
LD BC,#7ffd
OUT (C),A
; скопируем в неё загруженный экран
LD HL,scr
LD DE,#c000
LD BC,#1b00
LDIR
; восстанавливаем страницу 0
; и активизируем второй экран
LD A,#18
LD BC,#7ffd
OUT (C),A
; не помешает небольшая задержка
; для лицезрения результата
LD BC,0
wait
DEC BC
LD A,B
OR C
JR NZ,wait
RET
scr LCODE "screen"
Если всё прошло успешно, перед вами поя-
вится картинка, которую вы поместили во
второй экран. Она продержится столько, на
сколько хватит цикла задержки. После этого
управление перейдёт к редактору и он авто-
матически восстановит экран |1.
Обратите внимание и на то, что для отоб-
ражения экрана |2 вовсе не обязательно
иметь страницу 7 активной. Достаточно то-
го, что режим работы выбран соответствую-
щим битом порта.
Ну, на этот раз хватит. До скорого!
Продолжение следует...
──══════════──
Другие статьи номера:
|
|
|
|
Ликбез - Ассемблер - взгляд издалека: распределение памяти ZX Spectrum.
|
|
|
|
|
|
|