Модуль внешнего ПЗУ

http://zx-pk.ru/threads/15297-korvet-zagruzka-iz-vneshnego-pzu.html

Всем привет, опишу тут эту особенность Корвета.

Корвет умеет грузиться из подключенной к левому разъему XS1 - блока ПЗУ

для этого надо нажать F2+Reset или без нажатия кнопки после тестов (т.е. если внешнее ПЗУ подключено и корректно - загрузка из него !!!!)

без внешнего пзу он обругает, иначе попробует загрузить из него что-то и передать управление.

в реальной жизни я слышал про 2 применения

* 1-е КТДП - тестовая программа
* 2-е LINTECH сеть, которая была сильно быстрее родной.

начнем с железа.

боковой порт, он назван XS1 ("Расширение") в документации, из интересного нам выведено

* 1. все 3 порта PPI3 к580вв55 (ниже 0-7)
	+ A: XS1:34,35,36,37,19,18,17,16
	+ B: XS1:3,2,1,20,21,22,23,24
	+ C: XS1:7,6,5,4,8,9,10,11
* 2. питание (+5,+12,-12, GND) (XS1:25,26, XS1:28, XS1:29)
* 3. IRQ0 - запрос на прерывание (XS1:33)
* 4. старший бит(7) порта С PPI2 (XS1:32) (кстати в тех. описании написано что XS1:32 не подключен, а на схеме он есть)
* и еще не нужный нам тут но полезные 2mhz и выход канала 0 таймера ВИ53

исходя из загрузчика схема подключения следующая

* порт А - шина данных ПЗУ
* порты B и C - шина адреса ПЗУ
* отсюда 64к пзу
* + XS1:32 судя по комментарию (; ВКЛЮЧ. ПЗУ) в исходнике заведен на CS чипа
* этот же вывод заведен на XS1:33 - IRQ0 и используется для определения подключен ли блок пзу.

собственно вот и вся схемотехника.

как ОПТС грузит его, пошаговое описание

если нажато при старте пзу F2 (или после ОПТС тестов без F2)

* 1. установили PPI2.C7=0, проверили что в регистре контроллера прерываний нет запроса IRQ0
* 2. установили PPI2.C7=1, проверили что в регистре контроллера прерываний есть запрос IRQ0
* 3. (оставили PPI2.C7=1)
* 4. если это выполнено то блок подключен.
	+ иначе если F2 нажато не было то просто грузим как обычно ОПТС (эт для автостарта EXT ROM) или если было нажато F2 то обругались:

```
ОПТС 1.1 - "Подключите внешнее ПЗУ"
ОПТС 2.0 - "нет внешнего ПЗУ"

```

* 5. далее читаем из блока ПЗУ по адресам
	+ 0x0004 - DW Start addr (куда будет передано управление)
	+ 0x0006 - DB Page to read (xx00) (старший байт адреса куда грузить)
	+ 0x0007 - DB Page count (сколько 256байтных страниц грузить)

* 6. далее считаем сумму всех байт которые будем грузить, их сумма должна быть 0xff, если это не так то пишем
	+ ОПТС 1.1 - "Внешнее ПЗУ неисправно"
	+ ОПТС 2.0 - "ошибка КС"
* 7. теперь грузим что надо из пзу в RAM
* 8. а теперь сравним, то что загрузили в память с тем что в ПЗУ. если есть отличия, то выводим их на экран и вешаем машину.
* 9. если все ОК то передаем управление тому что загрузили.

теперь комментарии.

шаг 8 по очень актуален для загрузки теста в память.
т.е. в ситуации битого RAM он не даст запустить бред.
по шагам получается что мы считаем что CRC совпало, значит эта часть железа нормальная, значит битый RAM.

собственно то что ПЗУ отключаемо, делает возможность
вешать на этот порт что угодно, а в пзу записать загрузчик этого

можно даже сделать "супер ROM диск" на много к, например повесив регистр, в который при отключенном ПЗУ можно записать старшую часть адреса.
ну и прочее
хоть HDD подключить, благо портов там много разных.

а сама идея такого использования порта достаточно красивая ...
получается достаточно удобный и функциональный порт расширения, без выноса шины даных/адреса наружу.

в аттаче дизасмы этой части ОПТС 1.1 и ОПТС 2.0
и кусок исходника R002.asm

korvet\_extrom.zip

(кстати у нас в харьковском Пед институте был класс из 2х партий корветов,
у одних это разъем был "Папа" у других "Мама", у тех что "папа" - народ заклеивал разъем, иначе шаловливые ручки студентов совали туда ключи и палили платы).

 2014-07-07

Огромное спасибо Serebriakov, за СХЕМУ
в общем она подтвердила теорию
схема на 8 кб (2x4k)

## Недоработка адресации

в пзу который считали с Квант8
есть такое

```
RAM:05E3          incExtRomADDR:                          ; CODE XREF: RAM:053A�p

RAM:05E3 13                       inc     de
RAM:05E4 1A                       ld      a, (de)
RAM:05E5 3C                       inc     a
RAM:05E6 12                       ld      (de), a
RAM:05E7 1B                       dec     de
RAM:05E8 C0                       ret     nz
RAM:05E9 13                       inc     de
RAM:05EA C3 EC 0C                 jp      incHIextRomAddr
RAM:05ED
RAM:05ED          incExtAddrend:                          ; CODE XREF: incExtRomADDR+70E�j
RAM:05ED                                                  ; incExtRomADDR+713�j
RAM:05ED 12                       ld      (de), a
RAM:05EE 1B                       dec     de
RAM:05EF 1B                       dec     de
RAM:05F0 B8                       cp      b
RAM:05F1 C9                       ret
RAM:05F1          ; End of function incExtRomADDR

RAM:0CEC          incHIextRomAddr:                        ; CODE XREF: incExtRomADDR+7�j
RAM:0CEC 13                       inc     de
RAM:0CED 1A                       ld      a, (de)
RAM:0CEE 3C                       inc     a
RAM:0CEF FE 20                    cp      20h ; ' '
RAM:0CF1 C2 ED 05                 jp      nz, incExtAddrend
RAM:0CF4 C6 20                    add     a, 20h ; ' '
RAM:0CF6 C3 ED 05                 jp      incExtAddrend

```

на редкость странное поведение.
или а10 они под что-то используют.
в общем или баг или странная логка.
8кб tdp.rom не грузит,
он грузит 8к, потом перепрвгивает 2000 -> 4000.
и срабатывает проверка на конец, т.е. чтоб оно нормально работало надо и патченый ром.
бред однако, а может защита.

Ну, да, понятно. А если вписать принудительно в файл размер на 20 больше, то загрузится?

Сдается мне, что разработчики контура проявили элементарное разгильдяйство и сами не поняли, что у них получилось. Может быть, вообще ни разу в жизни ничего так не загружали. Это все равно что сдуру ляпнуть про 96К ПЗУ в журнально статье. Все равно ведь никто не проверит - за четверть века ты первый, кто это заметил

Между прочим, когда счетчик добежит до 5FFF, он не перепрыгнет на 8000, а спокойно пойдет на 6000. Так что адресная ножка рано или поздно тоже будет задействована. Ума не приложу, зачем так было делать...