|
Spectrum Progress
#01
30 сентября 1996 |
|
Записки программиста - работа с расширенной опертивной памятью на ZX Spectrum.

Как бывает обидно порой, когда полезная
программа с завидным упорством отказывается
использовать весь объём памяти компьютера и
наивно считает, глупая, что 128 или 256
килобайт - это головокружительная роскошь для
конца ХХ века.
(c) Денис Паринов, 1996.
Когда говорят "память", то имеют ввиду опера-
тивную память, то есть память, напрямую связан-
ную с микропроцессором и предназначенную для
хранения и выполнения программ, а также данных,
непосредственно участвующих в операциях.
Под управлением памятью понимают обеспечение
доступа к ней и распределение между программа-
ми.
В компьютерах ZX Spectrum используется про-
цессор Z80, который имеет 16-разрядную шину
адреса, что позволяет ему адресоваться
к 2^16=65536 ячейкам памяти. В модели
ZX Spectrum 48 процессор непосредственно мог
адресоваться ко всем ячейкам памяти.
Но в модели ZX Spectrum 128 адресного
пространства процессора уже не хватало и его
разработчики решили использовать страничную мо-
дель памяти.
Страничная модель памяти отличается от линей-
ной тем, что в линейной каждая ячейка имеет
свой индивидуальный адрес и процессор может ад-
ресоваться к ней в любой момент, а в странич-
ной, ячейки объединены в группы (страницы) по
16 килобайт и процессор может адресоваться в
любой момент к 32 килобайтам линейной памяти
(ОЗУ), к 16 килобайтам (ПЗУ), а также к 16 ки-
лобайтам страничной памяти (ОЗУ).
Переключение страниц памяти осуществляется с
помощью команды
Страничная модель памяти. OUT 32765,n, где
n - конфигурация
┌────────────┐ порта 32765 dec/
│7 страница │ #7FFD hex.
┌─┴──────────┐ │ Назначение битов
│6 страница │ │ D0...D2 - номер
┌─┴──────────┐ ├─┘ текущий страницы
│4 страница │ │ размещаемой в
┌─┴──────────┐ ├─┘ диапазоне адресов
│3 старница │ │ с 49152 (#C000)
┌─┴──────────┐ ├─┘ по 65535 (#FFFF).
│1 страница │ │ D3 - текущее ПЗУ:
#FFFF ╔═╧══════════╗ 65535 0-128 ПЗУ, 1-48 ПЗУ
║0 страница ║ │ D4 - активный экран
║ ╟─┘ 0 -обычный с 16384/
║ ║ #4000, 1-дополни-
#C000 ╠════════════╣ 49152 тельный с 49152/
│2 страница │ #C000 на 7-й стр.
│ │ памяти.
│ │ D5 - блокировка
#8000 ├────────────┤ 32768 порта 32765 / #7FFD
│5 страница │ D6..D7 -в ZX Spect-
│ │ rum 128 не исполь-
│ │ зуется.
#4000 ├────────────┤ 16384 Перед переключением
│ │ страниц необходимо
│ ПЗУ 16К │ выполнить следующие
│ │ действия:
#0000 └────────────┘ 0 а) переместить
указатель стека на
адрес ниже 49152, это можно сделать из
ассемблера командой LD SP,#BFFF или из Бейсика
командой CLEAR 49151.
б) поместить в системную переменную 128-го
Бейсика "BANK" (23388) значение конфигурации
порта 32765 (#7FFD), чтобы на прерывании
страница ОЗУ не переключилась в обычное
состояние.
Пример:
LD (STACK),SP;Сохранение указателя стека
LD SP,#BFFF ;Установка стека на 49151
LD HL,#C000 ;
LD A,1 ;Переключение на 1-ю стра-
CALL BANK ;ницу памяти.
LD B,(HL) ;Взять содержимое ячейки
;49152 на 1-й стр. памяти.
LD A,0 ;Переключение на 0-ю стра-
CALL BANK ;ницу памяти.
LD C,(HL) ;Взять содержимое ячейки
;49152 на 0-й стр. памяти.
LD SP,(STACK) ;Востановление указателя
;стека.
RET ;Возврат из программы.
BANK DI ;Запрет прерываний.
PUSH BC ;Запомнить BC.
LD BC,#7FFD ;
OR #10 ;Установить ПЗУ 48.
LD (23388),A ;Изменить пер. BANK.
OUT (C),A ;Вывести в порт 32765 зна-
;чение аккумулятора.
POP BC ;Вспомнить BC.
EI ;Разрешить прерывания.
RET ;Вернуться из подпрограммы
Дополнительный экран.
В компьютере ZX Spectrum 128 имеется
второй, дополнительный экран.
Он располагается на 7-й странице памяти с
адреса 49152 (#C000) и имеет точно такую же
структуру как и обычный экран. Единственным
отличием является 15-й бит экранных адресов, на
обычном экране этот бит равен 0, а на
дополнительном 1.
Переключение между экранами осуществляется
через порт 32765 (#7FFD), для отображения до-
полнительного экрана надо выполнить программу:
DI ;Запретить прерывания.
PUSH BC ;Запомнить BC.
LD BC,#7FFD ;
LD A,(23388) ;Взять содержимое пер. BANK
SET 3,A ;Установить 3-й бит опреде-
;ляющий активный экран.
LD (23388),A ;Поместить новое знаэение в
; переменную BANK.
OUT (C),A ;Вывод в порт 32765 (#7FFD)
;содержимого аккумулятора.
POP BC ;Вспомнить BC.
EI ;Разрешить прерывания.
RET ;Вернуться из программы.
Для обычного экрана:
DI ;Запретить прерывания.
PUSH BC ;Запомнить BC.
LD BC,#7FFD ;
LD A,(23388) ;Взять содержимое пер. BANK
RES 3,A ;Сбросить 3-й бит определя-
;ющий активный экран.
LD (23388),A ;Поместить новое знаэение в
; переменную BANK.
OUT (C),A ;Вывод в порт 32765 (#7FFD)
;содержимого аккумулятора.
POP BC ;Вспомнить BC.
EI ;Разрешить прерывания.
RET ;Вернуться из программы.
Приведённые программы выполняют только отоб-
ражение одного из экранов, изменяя 3-й бит пор-
та конфигурации.
Перед выводом изображения на дополнительный
экран следует включить 7-ю страницу памяти и
вывести изображение.
После чего вы можете включить любую другую
страницу памяти, изображение будет отображаться
пока установлен 3-й бит порта #7FFD/32765.
НЕДОПУСТИМОЕ использование неполной
адресации порта конфигурации.
В связи с нехваткой информации по вышеописан-
ной теме, начинающие программисты пытаются ра-
зобраться в чужих программах и в какой-то мо-
мент находят более "лучший" способ переключения
страниц при помощи команды OUT (#FD),A.
Они смело заменяют более громоздкий:
LD BC,#7FFD
OUT (C),A
на более компактный: OUT (#FD),A.
Так появляются программы не работающие на
компьютерах Scorpion, Profi и др. у которых па-
мять больше 128K.
Кстати, если уж зашла речь о подобных маши-
нах, то рассмотрим коротко управление памятью
в Скорпионе.
Порт #7FFD (32765), назначение битов:
D0-D2 - номер страницы памяти, размещаемой с
адреса #C000.
D3 - выбор 1-го экрана для отображения на
дисплее.
D4 - выбор ПЗУ 48.
D5 - выключить порт #7FFD.
D6 - не используется.
D7 - не используется.
Порт #1FFD (8189), назначение битов:
D0 - замещение ПЗУ нулевой страницей памяти.
D1 - выбор дополнительного ПЗУ с теневым
сервис монитором.
D2 - не используется.
D3 - вывод на RS-232.
D4 - банк ОЗУ. ( 0-основной, 1-расширенный ).
D5 - сигнал STROBE для CENTRONICS.
D6 - не используется.
D7 - не используется.
На примере программы мы продемонстрируем вы-
шесказанное.
Допустим, нам нужно сохранить содержимое эк-
рана на 8-й странице памяти, вывести другое
изображение, подождать нажатия клавиши и
восстановить экран.
ORG #8000 ; Переместить стек на
LD (STACK),SP ; адрес #7FFF, чтобы
LD SP,#7FFF ; можно было вернуть-
; ся из прогр. BANK.
LD A,8 ; Выбор 8-й страницы
CALL BANK ; памяти.
LD HL,#4000 ; Установка парам.для
LD DE,#DB00 ; сохранения экрана с
LD BC,#1B00 ; адреса #DB00.
LDIR ; Сохранение экрана.
LD A,0 ; Выбор 0-й страницы
CALL BANK ; памяти.
LD HL,#C000 ; Установка парам.для
LD DE,#4000 ; вывода на экран
LD BC,#1B00 ; изображения с #C000
LDIR ; Вывод на экран.
RES 5,(IY+1) ; Сброс флага нажатия
LOOP BIT 5,(IY+1) ; Клавиша нажата?
JR Z,LOOP ; Повторить если не
; нажата.
LD A,8 ; Выбор 8-й страницы
CALL BANK ; памяти.
LD HL,#DB00 ; Установка парам.для
LD DE,#4000 ; востановлен. экрана
LD BC,#1B00 ; с адреса #DB00.
LDIR ; Вывод на экран.
LD A,0 ; Выбор 0-й страницы
CALL BANK ; памяти.
LD SP,(STACK) ; Востановить стек.
RET ; Вернуться из прог-
; раммы.
STACK DEFW 0 ; Ячейки для хранения
; указателя стека.
BANK DI ; Запрет прерываний.
PUSH BC ; Сохранить BC.
PUSH AF ; Сохранить AF.
AND #08 ; Номер страницы > 7
RLA ; Результат
LD BC,#1FFD ; выдать
OUT (C),A ; в порт #1FFD.
POP AF ; Вспомнить AF.
AND #07 ; Откорректировать
; номер страницы для
; порта #7FFD.
OR #10 ; Установить ПЗУ 48.
LD B,#7F ; Выдать в
OUT (C),A ; порт #7FFD.
POP BC ; Восстановить BC.
EI ; Разрешить прерыва-
; ния.
RET ; Вернуться из прог-
; раммы BANK.
Примечание. Перенос стека необходим, если он
находится выше адреса #C000, т.к. при помещении
страницы памяти с #C000, информация по адресу
размещения стека не будет соответствовать адре-
су возврата.
Как видите, память Скорпиона не намного
сложнее Спектрумовской. Поэтому не забывайте
поддерживать в своих программах возможность её
использования, а благодарные пользователи оце-
нят ваш труд.
Другие статьи номера:
Похожие статьи:
В этот день... 16 ноября