******************************************************************************** ** Этот доумент пригоден для просмотра на ZX Spectrum в 80 символьном формате ** ******************************************************************************** (c) Black_Cat 2013 www.zx.clan.su BC Info Guide #8. OUT(#FD),A и как с ним бороться. Эта статья посвящается использованию на Спектруме обращения к портам с основани- ем #xxFD в короткой адресации командой OUT(#FD),A , проблемам возникающим в этой связи, и их решению. 1. Предистория вопроса. Первый, "официальный" клон ZX Spectrum - ZX Spectrum 128, имел дешифрацию порта #7FFD только по двум адресным разрядам A15 и A1, а для портов #BFFD, #FFFD ещё и по A14. При написании программ, выполняющихся за минимальное количество тактов, для обращения к #7FFD или #BFFD применялась команда OUT(#FD),A при выполнении которой в качестве старшего байта адреса использовалось содержимое аккумулятора. Соответственно, для корректной дешифрации порта #7FFD, достаточно было обеспе- чить равенство нулю старшего бита аккумулятора, а для корректной дешифрации пор- та #BFFD соответственно A15=1, A14=0. Такое обращение к этим портам было распро- странённым методом в демомейкинге. Но в расширенном клоне ZX Spectrum +3 произ- водства Amstrad были добавлены порты #0FFD, #1FFD, #2FFD, #3FFD, требовавшие для своей дешифрации не только A15 и A14, но и A13, A12, что, естественно, никак не учитывалось в ранее созданных демо-программах и приводило к программной несов- местимости с новым железом. Позже, положение усугубилось использованием портов #1FFD и #DFFD в отечественных клонах Спектрума - Scorpion/KAY и Profi. Всё это породило программную несовместимость любительского софта с новыми кло- нами. Конечно, виноваты в таком положении дел сами демомейкеры, но это плохое утешение при невозможности корректного исполнения программы. Поэтому любителями предпринимались разнообразные меры по решению этой проблемы. 2. Программный подход решения проблемы. Программный подход решения проблемы состоит в изменении кода конфликтующих про- грамм таким образом, что бы происходила корректная выборка портов используемых при короткой адресации. 1) Порт #7FFD. Для корректного выбора порта #7FFD значение старших трёх разрядов в аккумуляторе должно было быть A15=0, A14=1, а значение A13=0, если не требуется что бы сра- ботала защёлка порта #7FFD, блокирующая запись в него и переводящая компьютер в режим 48k, например так: LD A,(номер страницы + 16) OR 64 OUT (253),A 2) Порт #BFFD. Для корректного выбора порта #BFFD значение старших двух разрядов в аккумуляторе должно было быть A15=1, A14=0. 3) Порты #0FFD, #1FFD, #2FFD, #3FFD. Для обеспечения обратной совместимости с ZX Spectrum 128, использовать короткую адресацию для портов #0FFD, #1FFD, #2FFD, #3FFD строго не рекомендуется вообще. 4) Порт #DFFD. Использовать короткую адресацию для порта #DFFD теоретически возможно при уста- новке значений старших трёх разрядов аккумулятора A15=1, A14=1, A13=0, но прак- тически бесполезно, т.к. только частично переводит компьютер в режим CP/M. Поэ- тому использовать короткую адресацию для #DFFD не рекомендуется вообще. 5) Порт #FFFD. Использовать короткую адресацию применительно к порту адреса AY #FFFD было не- возможно, т.к. сам адрес внутренних регистров AY должен содержать нули в старшем полубайте. Но в TurboSound/TurboSoundFM/ZXM-SoundCard стало возможно обращение в короткой адресации к дополнительным внутренним регистрам управления этих устрой- ств в диапазоне #E0-#FF. Этот диапазон учитывает особенности дешифрации перечис- ленных выше клонов Спектрума. При таком обращении значение старших трёх разрядов в аккумуляторе должно быть A15=1, A14=1, A13=1. Несмотря на потенциальную воз- можность использования короткой адресации для #FFFD, всё же не рекомендуется её использовать, т.к. в будущем это может привести к конфликтам с новыми внутрен- ними регистрами управления выходящими за пределы диапазона #E0-#FF. 3. Аппаратный метод решения проблемы совместимости. К сожалению не для каждой демо-программы есть возможность модифицировать код, поэтому среди радиолюбителей получили распространение так же аппаратные методы решения проблемы совместимости. Как правило такие методы применяются только для корректного определения обращения к порту #7FFD. Существует два концептуально отличающихся подхода: - перехват кода операции команды OUT(#FD),A и принудительная выборка порта #7FFD; - детектирование исполнения команды OUT(#FD),A по равенству байтов на шине дан- ных и в старшем байте адреса и принудительная выборка порта #7FFD. Рассмотрим их подробнее. Схемы представлены на http://zx.clan.su/forum/8-66-808-16-1373062339 1) Перехват кода операции команды OUT(#FD),A. Дешифратора команды OUT(#FD),A проверяет каждый КОП, и при выявлении КОПа OUT(#FD),A, взводит триггер, который принудительно устанавливет адресный вход A14 дешифратора порта #7FFD компьютера в единицу. После исполнения команды OUT(#FD),A, следующий КОП сбрасывает триггер. Сигнал A15=0 отделяет обращения к порту #7FFD от #BFFD, #FFFD, #DFFD. В конкретной реализации в ПЛИС ZXM-Phoenix rev.3-5 вместо сигнала MREQ/, исполь- зуется инверсный сигнал IORQ/. 2) Детектирование исполнения команды OUT(#FD),A по равенству байтов на шине дан- ных и в старшем байте адреса. В данном методе постоянно сравниваются старший байт адреса и байт данных, и по их равенству определяется исполнение команды OUT(#FD),A. Такое сравнение произ- водится только для A15=0 чтобы отделить обращения к портам #BFFD, #FFFD, #DFFD, и для A13=0, т.к. команда OUT(#FD),A как правило не применяется для бло- кировки порта #7FFD. Этот метод имеет недостаток - ложное срабатывание при запи- си #1F в порт #1FFD, или #0F в порт #0FFD. Устраняется этот недостаток либо отказом в использовании этих портов, либо запретом использования таких комбина- ций данных для этих портов, что для отечественных клонов, использующих порт #1FFD вполне осуществимо. Заключение. К сожалению, универсального и при этом простого решения данный вопрос не имеет, но частные решения при соблюдении изложенных ограничений в большинстве случаев являются вполне приемлемым решением проблемы.