Схема распределения портов
Sprinter имеет две обособленные группы портов. Первая группа, это внутренние порты процессора Z84C15, вторая – внешние порты. Адресация портов первой группы не может быть изменена, так как эти порты на одном кристалле с процессором. Вторая группа погключается через ППЛМ и их адреса могут изменяться как угодно, с единственным условием, непересечения с адресами первой группы.
О том какие порты имеются на кристалле Z84C15 можно прочитать в документации по этому процессору и здесь я упомяну некоторые из них. Один из последовательных портов используется для ввода данных с активной мыши. Один из параллельных используется для вывода данных, на второй параллельный порт заведены сигналы прерываний и запросов прямого доступа со слотов ISA. Параллельный порт процессора Z84C15 устроен таким образом, что на нем возможна организация прерываний по сигналам приходящим через параллельный порт. Фактически второй параллельный порт используется как контроллер прерываний.
Схема распределения портов второй группы имеет свою особенность. Главной идеей было получение воз- можности бысро изменять конфигурацию портов без перегрузки ППЛМ. Это достигнуто путем применения карты распределения портов, располагающейся на специальной странице ОЗУ.
При появлении цикла обращения к порту сначала происходит обращение к ОЗУ карты портов. В карте портов записано какой именно порт подключен к данному адресу. Далее происходит внутренняя дешифрация по байту из карты портов и обращение к выбранному порту. В режиме нетурбо это происходит без каких либо задержек, а в режиме турбо процессору выставляется сигнал WAIT в зависимости от необходимой длины цикла обращения к порту.
Для подключения к какому либо адресу или отключения от него какого либо порта достаточно открыть карту портов и вписать в нужное место один байт.
В странице карты портов содержится четыре карты, которые могут переключаться через системный порт. Таким образом можно осуществить быстрое переключение конфигурации портов, что может быть полезно при работе Spectrum-овских программ совместно со Sprinter-овским биосом.
Карты портов расположена в странице 40h. Переключение производится через системный порт (адрес 7Ch/3Ch). При записи в системный порт значений 04h,0Ch,14h,1Ch происходит переключение на одну из четырех карт. Начальное значение 04h.
Номер карты соответсвует адресам A12,A13 в странице (блоки по 4kb). На остальные адреса подаются следующие сигналы:
A0 - A0
A1 - A1
A2 - A2
A3 - A7
A4 - A13
A5 - A5
A6 - A6
A7 - A14
A8 - A15
A9 -
A10 -
A11 -
/WR - сигнал записи
/DOS - 0 - дос включен, 1 - выключен
PN5 - сигнал блокировки порта Пентагона (может отсутствовать)
Таким образом порт выбирается именно по указанным сигналам, т.е. например, нельзя назначить на ад- реса 0050h и 0058h различные порты. Участие в дешифрации сигнала /WR позволяет назначать различные порты на один и тот же адрес на чтение и запись. Так, например, в схеме контроллера дисковода на порт 0FFh на чтение назначено чтение порта джойстика и сигналов DRQ, INTRQ контроллера дисковода, а на запись - запись в микросхему ТМ9 - системный порт TR-DOS.
Назначение порта производится записью соответствующего байта в карту памяти. Так, для того что бы назначить на некий адрес, скажем, на 7785h некий порт, первым делом следует удостовериться, что этот порт не пересекается ни с какими другими портами. Проще всего, это узнать, прочитав карту памяти из адреса, соответсывющего этому порту. Если в этом месте оказался нуль, значит, порт не занят и его возможно использовать (надо помнить, что не все незанятые порты стоит использовать, так как есть еще и внутренние порты Z84C15).
Как определить адрес, откуда читать байт?
Для этого надо из 7785h выделить биты 0, 1, 2, 5, 6, 7, 13, 14, 15, и установить соответсвенно им биты адреса карты памяти:
A0=p_A0=1, A1=p_A1=0, A2=p_A2=1, A3=p_A7=1, A4=p_A13=1, A5=p_A5=0,
A6=p_A6=0, A7=p_A14=1, A8=p_A15=0, A9=xxx, A10=xxx, A11=xxx.
Значениe xxx имеeтся в виду «не определено» . Это означает, что в карте памяти по всем адресам, у которых из A[11..0] биты A[8..0] равны 010011101b=09Dh следует прописать один и тот же байт, соот- ветсвующий номеру порта. Биты A[15..A12] адреса устанавливаются соответсвенно номеру окна и номеру карты (обычно 1100b для окна C000-FFFF и нулевой карты), таким образом, рассчитанный адрес равен C09Dh, если xxx заменить на нули, а весь набор - C09Dh, C29Dh, C49Dh, C69Dh, C89Dh, CA9Dh, CC9Dh, CE9Dh.
Если необходимо, что бы порт был «виден» только на запись, то A9 устанавливается в 0, если только на чтение - A9=1. Аналогично с битами DOS и PN5. Если нужно, что бы порт был виден только в DOS или только при открытом порте «Пентагона», необходимо устанавливать соответсувующие биты в адресе карты в конкретные значения.
С другой стороны, при необходимости неполной дешифрации (например, порт 8-мибитный), надо уста- новить в «не определено» значения для A13,A14,A15, то есть биты 4,7 и 8 адреса карты портов и рассчитать соответствующий набор адресов.
Ввиду отсутствия дешифрации по части адресам, естественно, открытый для 7785h будет виден и по всем другим адресам, различающимся в битах A[12..8] и A[4..3].
Для наглядности напишу програму, которая откроет на чтение и запись порт 7785h некий виртуальный порт с номером 0D0h.
OPEN_PORT:
LD B,0D0 ; номер виртуального порта
OPEN_P1: DI ; запретить прерывания! Не дай бог нагадить в 40h
; все полетит к чертям.
IN A,(PAGE3)
EX AF,AF’ ; сохранить адрес окна C000h
; стеком не пользуюсь намеренно, бог его знает, где
; он, a я страницами щелкаю
LD A,40h
OUT (PAGE3),A ; установить новый адрес окна на страницу 40h
; Здесь я не буду проверять, что было записано в том месте,
; считая, что там были нули (но в реальном Спринтере стоит проверить,
; не занят ли он). Для проверки этой программы, лучше всего воспользоваться
; портом 0000h, для которого в следующей команде константа
; равна 0C000h, и он точно не зянят. Но здесь так для наглядности.
LD HL,0C09Dh ; адрес в карте памяти для порта 7785h на запись
; это адрес, биты которого рассчитаны немного выше. Aдрес для карты 0,
; которая и устанавливается при обычной работе.
LD (HL),B ; установить порт на чтение в режиме DOS
SET 1,H ; включить A9 в 1 (сигнал /WR)
LD (HL),B ; установить порт на запись в режиме DOS
SET 2,H ; включить A10 в 1 (сигнал DOS)
LD (HL),B ; установить порт на запись в режиме не-DOS
RES 1,H ;
LD (HL),B ; установить порт на чтение в режиме не-DOS
; порт установлен открывать его в режиме отключенного порта пентагона я не
; стал, собственно, и не обязательно, если программа работает в 128-м
; режиме.
EX AF,AF
OUT (PAGE3),A ; восстановить страницу
EI
RET
CLOSE_PORT:
LD B,0 ; значение 0 - порт закрыт
JR OPEN_P1 ; все остальное так же как при открытии
; теперь, что бы пользоваться портом 0, достаточно сделать так
CALL OPEN_PORT
.....
LD BC,0
OUT (C),A
.....
LD BC,0
IN A,(C)
.....
CALL CLOSE_PORT
; можно вызывать и OPEN_P1, например
LD B,0D1h ; открыть виртуальный порт 0D1h
CALL OPEN_P1
; Естественно, можно вызывать открытие нового виртуального
; порта и не закрывая старый. Надо только помнить, что порт
; стоит закрыть при выходе из программы.
О виртуальных портах.
В Спринтере есть набор нескольких дополнительных портов, которые никак нигде не используются, но просто являются некими ячейками памяти. Это порты с номeрами D0h..DFh. Они используются при работе в режиме Pentagon-512 как адреса дополнительных страниц, но в режиме Pentagon-128/Scorpion-256 могут использоваться программистом для каких нибудь особых целей, например, эмуляции какого либо порта для уже написанных программ. А в некоторых случаях могут стать передатчиком дополнительных параметров (хотя и несколько извращенным).
Байты номеров портов для карты памяти (для sp-97):
00 - Нет порта
01h..0Fh - reserved
10h - порт ВГ93 (1F)
11h - порт ВГ93 (3F)
12h - порт ВГ93 (5F)
13h - порт ВГ93 (7F)
14h - порт на запись - состояние контроллера дисковода (FF)
15h - порт на чтение - джойстик и IRQ/INTRQ контроллера
16h..1Fh - reserved
20h - HDD - регистр данных
21h - HDD - регистр состояния/ошибок
22h - HDD - регистр количества секторов для операций R/W
23h - HDD - регистр сектора
24h - HDD - регистр дорожки-low
25h - HDD - регистр дорожки-high
26h - HDD - регистр головок/выбора мастер-слэйв
27h - HDD - регистр команд
28h - HDD - дополнительный регистр управления 3F6
29h - HDD - дополнительный регистр состояния 3F7
2Ah..2Fh - reserved
30h - ISA-SLOT 1 - memory R/W
31h - ISA-SLOT 2 - memory R/W
32h - ISA-SLOT 1 - ports R/W
33h - ISA-SLOT 2 - ports R/W
34h..3Fh - reserved
40h - ZX-Keyboard (порт FE)
41h..7Fh - reserved
80h..87h - reserved
88h - COVOX/COVOX-Blaster
89h..8Fh - reserved
90h - AY-8910-port (BFFD)
91h - AY-8910-port (FFFD)
92..BFh - reserved
C0h - Scorpion-256 port (1FFD)
C1h - Pentagon-128 port (7FFD)
C2h - Border, write only (FE)
C3h - reserved
C4h - port RGADR, PORT_Y (89)
C5h - port RGMOD (C9)
C6h..C7h - reserved
C8h..CFh - копии C0..C7h (not used!)
D0h..DFh - Virtual Ports (USER ports)
E0h - ROM page EXRANSION
E1h - ROM page TR-DOS
E2h - ROM page BASIC-128
E3h - ROM page BASIC-48
E4h - ROM page EXRANSION’
E5h - ROM page TR-DOS’
E6h - ROM page BASIC-128’
E7h - ROM page BASIC-48’
E8h - RAM page (окно 0000-3FFF)
E9h - RAM page (окно 4000-7FFF)
EAh - RAM page (окно 8000-BFFF)
EBh - ROM page SYSTEM
ECh - RAM page CASHE
EDh..EEh - reserved
EFh - ROM page SYSTEM’
F0h..FFh - RAM pages (окно C000-FFFF)
О последних 16-ти номерах поподробнее. Установка в какой либо порт значения от F0h до FFh приве- дет к одному и тому же результату, что и просто установка в этот порт значения F0h. В схеме сделана переадресация номера порта так, что при значении FXh номер порта берется как F0h+SpectrumPAGE, где SpectrumPAGE - номер спектрумовской страницы, адресуемой по портам 7FFD и 1FFD. Таким образом достигается совместимость с Пентагоном и Скорпионом по распределению памяти и делается возможным установка любого номера страницы спринтеровской памяти для любой страницы Спектрума.