Итак даны: два "Поиска". Первый - модификация со 128Кб RAM, второй - модификация с 512KB RAM. У обоих был выпаян родной процессор 1810ВМ88, установлена панелька на его место и в панельку вставлен NEC V20. Итог таков: компьютер работает нормально, быстрее чем со штатным процессором, кроме одного досадного бага, портящего всю картину, а именно:

В некоторых программах не отрисовывается каждый второй символ на экране. В числе таких программ - Volkov Commander и RAR. С другой стороны, например, Norton Commander отображается правильно.
Как мы все знаем, ПК Поиск эмулирует CGA, а именно работает всегда в графическом режиме, прорисовывая каждый символ на экране программно. Из-за этого у него есть две области видео-памяти по 16Kb каждая, отображаться на экране может одна из них. В графическом режиме отображается B800h, в текстовом - отображается BC000h, содержащая графическое представление текстовых символов из B800h. Происходит это в моем понимании примерно так: когда установлен текстовый режим, при записи символа в видео-память B800h срабатывают ловушки адреса (регистры-защелки), которые запоминают, по какому адресу произошла запись. Дальше вызывается обработчик NMI, который в свою очередь читает из портов 28h и 29h значение адреса (из регистров-защелок), по которому произошла запись, и отрисовывает символ в видимой графической области BC000. Сам код символа записывается в B8000h.
Путем выяснения причин "эффекта" была найдена закономерность - баг проявляется когда происходит прямая запись в видео-память, например с помощью команды REP STOSW. Были проведены простейшие тесты, которые показали, что не срабатывает "ловушка" адреса - порт 28h (TRAP_A):
Code: Select all
mov ax, 0B800h
mov es,ax
mov di,0
mov al,'O' ; буква O
mov ah,7 ; белым по черному
mov cx,1 ; один раз
rep stosw
in ax,28h
call PrintHexAX
Code: Select all
mov ax, 0B800h
mov es,ax
mov di,0
mov al,'O' ; буква O
mov ah,7 ; белым по черному
mov cx,2 ; два раза
rep stosw
in ax,28h
call PrintHexAX
Ну и в довершение:
Code: Select all
mov ax, 0B800h
mov es,ax
mov di,0
mov al,'O' ; буква O
mov ah,7 ; белым по черному
mov cx,3 ; три раза
rep stosw
in ax,28h
call PrintHexAX
При этом сами символы все-таки записываются в B800h. Если сменить видео-страницу стандартными функциями int 10h, то при возврате на текущую отобразятся три буквы "O". Не записывается адрес в защелки и не вызывается NMI для отрисовки на экране.
Дальше я обратился к схеме. Здесь я буду показывать схему 512Kb модификации, хотя она аналогична и 128Кб модификации, на мой взгляд. За отслеживание, что запись происходит в видео-память отвечает РТ4 (с небольшой помощью РТ5?), при удачной дешифрации формирующая сигнал /CRTIOM. Дальше этот сигнал вместе с некоторыми другими запускает мультивибратор, который дает длинный импульс NMI (не менее пяти тактов, наверное).

По сигналу NMI происходит защелкивания текущего адреса в регистры-защелки:

Ну и дальше проц должен уйти на обработчик NMI, который прочтет из портов 28h,29h адрес куда писался байт и отрисует его графическое представление в отображаемый экран BC000h. Дешифрует порты РТ5, формируя сигнал /TRAPSEL, который потом разделяется на 28h (TRAPL),29h (TRAPH) и 2ah (TRAPDAT) с помощью ИД7. Но это уже потом, меня же пока интересует /CRTIOM и возникновение NMI.
Решил посмотреть что происходит с помощью восьми канального логического анализатора. Для этого взял родной BIOS, из которого выкинул монитор и работу с кассетой, а вместо этого после всей инициализации прикрутил тестовую программку - записывает один символ в видео-память, ждет пару секунд, записывает два символа в видео-память, ждет пару секунд и так по кругу. Такого плана:
Code: Select all
again:
MOV DX,01
CALL BEEP_ERROR
mov ax, 0B800h
mov es,ax
mov di,0
mov al,'1' ; буква 1
mov ah,7 ; белым по черному
mov cx,1 ; один раз
rep stosw
mov cx,200
call delay_pit
MOV DX,02
CALL BEEP_ERROR
mov ax, 0B800h
mov es,ax
mov di,160
mov al,'2' ; буква 2
mov ah,7 ; белым по черному
mov cx,2 ; два раза
rep stosw
mov cx,200
call delay_pit
jmp again
Вот так выглядит запись одного байта в приближении:

IO/M стал высокий (идет доступ к портам ввода-вывода), РТ5 видит что доступ к IO, адрес порта совпал, дешифровала TRAPSEL, ИД7 в свою очередь дала сначала TRAPL, затем TRAPH. Все понятно.
Дальше полный цикл для обоих процов NEC V20 и 8088. Полный цикл - запись одного байта, ожидание, запись двух байт. Это 8088:

Это V20:

В целом - все очень похоже, за исключением TRAPSEL, который на 8088 проце активно живет, а на V20 не очень. Но нас интересует момент записи двух байт сразу. Это вторая "черточка" из TRAPL и TRAPH на рисунках. Приближаем:
Это 8088:

Сначала был считан из портов младший адрес, затем старший. Все четко.
А это уже V20, то же место:

Не было считано второго адреса.
Забыл я сохранить фотографии когда я уже понял, что смотреть мне нужно сигналы /CRTIOM и NMI, но могу сказать словами - когда пишутся два байта, первый байт есть сигнал /CRTIOM, затем длинный NMI и затем уже /TRAPSEL, TRAPL и TRAPH. А вот второй байт - нет сигнала /CRTIOM, соответственно нет и всего остального. Такое ощущение, что "проскакивает" он.
Вот такая загадка....