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, информация по адресу размещения стека не будет соответствовать адре- су возврата. Как видите, память Скорпиона не намного сложнее Спектрумовской. Поэтому не забывайте поддерживать в своих программах возможность её использования, а благодарные пользователи оце- нят ваш труд.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября