Проблемы с чтением CF через int13h на некоторых старых BIOS

Описания, советы, ремонт, эксплуатация старых IBM PC-совместимых ПК
i8088
Advanced Member
Сообщения: 4383
Зарегистрирован: 30.01.2015,17:06
Откуда: г. Баку, Азербайджан

Конкурсы

Вклад в сообщество

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение i8088 » 09.05.2020,08:43

Aleks69, пока не записывайте новый BIOS, я нашел одну ошибку у себя
(вместо вызова wait_int поставил wait_hdd_ready, хотя не исключено, что и так будет
работать)

+ еще нашел у себя 286 плату на точно таком же движке BIOS, как у Вас, сделаю
изменения на ней тоже и заодно проверю правильность выбранной концепции.

i8088
Advanced Member
Сообщения: 4383
Зарегистрирован: 30.01.2015,17:06
Откуда: г. Баку, Азербайджан

Конкурсы

Вклад в сообщество

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение i8088 » 09.05.2020,14:48

Aleks69, прилагаю новый вариант BIOS для Вас, attv.m02

Модифкация PHOENIX BIOS моей 286 платы удалась! Код обработчика команды чтения
int13h очень похож на Ваш, но чуть сложнее. В целом код PHOENIX написан более
виртуозно, чем AMI, из-за этого понимать его тяжелее. CF теперь у меня читается и
загружается DOS с нее.

Интресно, что сектор в 286 PHOENIX читается как обычно (rep insw), а на вашем
386 PHOENIX просто insw поставленный в loop цикл 256 раз. Потенциально это
медленнее (разработчики перестраховались на случай медленного диска без
IORDY?). Даты обеих BIOS одинаковые.

Плата эта - NEAT 12Mhz PTM-1232C
Чипсет CHIPS
P82C215
P82C211-12 C
P82C212B-12 A
P82C206

BIOS ее также приложен
Вложения
ptm1232c.zip
(26.22 КБ) 116 скачиваний
attvm02.zip
(49.29 КБ) 109 скачиваний

i8088
Advanced Member
Сообщения: 4383
Зарегистрирован: 30.01.2015,17:06
Откуда: г. Баку, Азербайджан

Конкурсы

Вклад в сообщество

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение i8088 » 10.05.2020,10:17

Aleks69, а на Вашей плате Вы как в SETUP заходите, если ошибок
во время POST нет?

Но в SETUP у них можно войти прямо из DOS, вызовом int18h.
Прилагаю простейшую программу для этого
Вложения
int18.zip
(484 байт) 107 скачиваний

Aleks69
Advanced Member
Сообщения: 441
Зарегистрирован: 31.01.2010,18:30

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение Aleks69 » 11.05.2020,15:36

Добрый день!

i8088, спасибо огромное!

Обязательно попробую. У меня осталась парочка 39SF010A (после сборки Micro 8088), они как раз 128Kx8.
Вроде бы они совместимы по пинам с той, что стоит в плате. Но вот проблема - нет программатора сейчас.

А Micro 8088 в моем варианте не может сама шить BIOS - не было при сборке ATF16V8/GAL16V8 SPLD (U16).
Есть правда где-то плата на Pentium-II, может в ней можно прошить... или попробую собрать программатор, из того, что есть дома.

Насчет входа в BIOS Вы правы. Без ошибок он там какой-то мутный, кажется, ESC+F1 или что-то в этом роде. Могу и ошибаться.
Когда подключу - попробую нашупать, если получится. За утилиту - отдельное спасибо!
PC/XT 8088х1; Commodore 64x1; Micro 8088х1 (сделай сам :thumbup:); XT 286x1; SX386-20x1; 486DX2-66x1, Mac LC475x1; Pentium II 133-300x1; Duron 1300+SQ2500x1, Intel D201GLY2A+SQ2500x1

i8088
Advanced Member
Сообщения: 4383
Зарегистрирован: 30.01.2015,17:06
Откуда: г. Баку, Азербайджан

Конкурсы

Вклад в сообщество

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение i8088 » 11.05.2020,15:59

Aleks69 писал(а): 11.05.2020,15:36 Вроде бы они совместимы по пинам с той, что стоит в плате. Но вот проблема - нет программатора сейчас.
Да, вполне совместимы на чтение.
Aleks69 писал(а): 11.05.2020,15:36 Насчет входа в BIOS Вы правы. Без ошибок он там какой-то мутный, кажется, ESC+F1 или что-то в этом
роде. Могу и ошибаться. Когда подключу - попробую нашупать, если получится. За утилиту - отдельное спасибо!
Всегда пожалуйста! Я попробую тоже ESC + F1, и в коде еще поищу обработку комбинации клавиш.

Aleks69
Advanced Member
Сообщения: 441
Зарегистрирован: 31.01.2010,18:30

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение Aleks69 » 11.05.2020,22:31

Подскажите, пожалуйста - кто помнит. Есть какая-то методика пришивки микросхем флеш памяти (например, 39SF010A) в материнских платах, например для P-II.
Правильно ли я понимаю, что это делается так:

1. Загружаем DOS
2. На ходу вынимаем микросхему BIOS из платы
3. Вставляем прошиваемую микросхему
4. Программой для прошивки (флешером) BIOS от этой платы заливаем свой двоичный файл.

Поймет ли флешер произвольный бинарник ?
PC/XT 8088х1; Commodore 64x1; Micro 8088х1 (сделай сам :thumbup:); XT 286x1; SX386-20x1; 486DX2-66x1, Mac LC475x1; Pentium II 133-300x1; Duron 1300+SQ2500x1, Intel D201GLY2A+SQ2500x1

Аватара пользователя
Rio444
Почётный пользователь
Сообщения: 26861
Зарегистрирован: 14.09.2014,19:11
Откуда: Ростов-на-Дону

Вклад в сообщество

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение Rio444 » 11.05.2020,23:14

Aleks69, да, как-то так. Вынимать биос можно сразу после загрузки DOS.
Перед включением компьютера родной БИОС вытащить и вставить очень не туго. Чтобы легко было вытащить. Вставлять новую флешку быстро, сразу всеми ножками. Лучше заранее потренируйтесь. Если необходимо, подогните ножки.
Убедитесь, что родная флешка НЕ 12-вольтовая (маркировка 28хххх). Иначе скорее всего будет джампер 12-5В. Вам нужно 5В.
Юнифлэш шьёт всё.
Электронка: Изображение копия Изображение

i8088
Advanced Member
Сообщения: 4383
Зарегистрирован: 30.01.2015,17:06
Откуда: г. Баку, Азербайджан

Конкурсы

Вклад в сообщество

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение i8088 » 12.05.2020,16:58

Да, кстати, если микросхему прошиваемую (и оригинальную) поставить в DIP панели,
и вставлять в материнку уже все это, то выдергивать и вставлять на ходу проще
будет и ноги микросхем гарантированно не помнуться.

PS1. Если вдруг нужно будет читать в материнке родное ПЗУ, то тоже осторожно, на
контакте 1 не должно быть 12V (некоторые производители заводят на контакт 1 12V,
а flash стоит 5-вольтовая).

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

PS3. Я уже сделал программу, имтирующую работу команды чтения BIOS, но сталось
внести в нее неправильные изменения (как в проблемных BIOS), чтобы посмотреть
детально на ошибки

i8088
Advanced Member
Сообщения: 4383
Зарегистрирован: 30.01.2015,17:06
Откуда: г. Баку, Азербайджан

Конкурсы

Вклад в сообщество

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение i8088 » 15.05.2020,16:23

Интересно что "неправильный" код в exe файле вполне работает, хотя проверял на
486, надо будет проверить на плате, где проблема имелась.

Еще любопытно, что некоторые CF держат 0x58 (DRQ+DRSC+DRDY) в регистре
статуса не более 5-10 сек после подачи ATA команды чтения, и спустя это время
содержимое status reg (0x1f7 или 0x3f6) становится 0xff и соответственно чтение
невозможно. Это затрудняет отладку по шагам в debug.

Вообще наверно лучше без debug-а проверять, а в интересующих точках
ставить отладочную печать

i8088
Advanced Member
Сообщения: 4383
Зарегистрирован: 30.01.2015,17:06
Откуда: г. Баку, Азербайджан

Конкурсы

Вклад в сообщество

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение i8088 » 20.05.2020,16:46

Пока не очень понятно - с HDD даже больше времени проходит, пока он даст DRQ
на чтение очередного сектора. Но по любому, код с "неправильным" подходом работает
в exe файле. Почему это не работает в BIOS, с той же самой CF пока неясно.

Aleks69, у Вас получилось записать BIOS?

i8088
Advanced Member
Сообщения: 4383
Зарегистрирован: 30.01.2015,17:06
Откуда: г. Баку, Азербайджан

Конкурсы

Вклад в сообщество

Проблемы с чтением CF через int13h на некоторых старых BIOS

Сообщение i8088 » 21.05.2020,15:10

Итак, причина похоже найдена!

Дело оказалось совсем не в слишком быстром чтении главного регистра состояния
(0x1f7 для первого канала, эти BIOS-ы поддерживают только один канал ATA), как я
вначале думал.

Рассмотрим еще раз проблемный код (я его упростил чтоы не загромождать
несущественными деталями).
=====================================================================
ata_read:
call chk_num_of_hdd
jb ata_read_exit
call chk_ata_status
jb ata_read_exit
mov di, bx
mov si, es
call en_h3_hdpt

call tf_write
call wp_set ; write precomp set
mov al, ah
call ata_cmd ; execute ata command

ata_read_sec:
; wait for set int flag in the BDA 0x40:0x8E
; it is set in the HW IRQ14 interrupt handler
call wait_int
jb ata_read_exit
mov es, si
mov cx, 100h ; read 256 words (sector)
mov dx, 1F0h ; data reg in dx
cli
cld
rep ins word ptr es:[di], dx ; reading sector
sti

call chk_err_set_bda ; check status and error reg (if need)
; and set BDA bytes
jnb ata_r_no_err
cmp byte ptr ds:74h, 11h
jnz set_error_flag

ata_r_no_err:
dec byte ptr [bp+3] ; [bp+3] sectors count
jnz ata_read_sec

set_error_flag:
mov ah, ds:74h
or ah, ah
jz ata_read_exit
stc

ata_read_exit:
retn
=====================================================================

Вспомним, что в ATA интерфейсе запрос прерывания (IRQ) сбрасывается при чтении главного регистра
состояния (0x1f7), а для чтения статуса без сброса IRQ предназначен альтернативный регистр
состояния (0x3f6)

Запрос прерывания в INT13h в основном просто устанавливает 0xff в ячейке BDA 0x40:0x8E, и
сбрасывает запрос в контроллере прерываний. А в коде наблюдают за состоянием ячейки BDA
0x40:0x8E. В общем, получается почти так же, как если бы мы просто ждали готовности и не
использовали прерываний от HDD (я такой вариант тоже проверял, в ходе поиска причины дефекта).

Перед чтением сектора (rep ins word ptr es:[di], dx) запрос прерывания не сбрасывается (в процедуре
wait_int не предусмотрено чтение 0x1f7). Чтение 0x1f7 есть в процедуре chk_err_set_bda. Старые HDD в
таких условиях вырабатывают новый запрос прерывания, в обработчике IRQ14 снова взводится
флаг 0x40:0x8E, и все работает нормально. Экспериментально установлено, что большинство CF для
нормальной работы требуют сброса IRQ до чтения сектора, иначе последующие прерывания не
возникают, и wait_int завершает работу по тайм-ауту. Для исправления дефекта, помимо ранее
приведеных "фирменых" исправлений можно просто прочитать 0x1f7 перед чтением сектора.

И еще некоторые интересные детали.
1. С "неправильным" кодом старый HDD возввращает 0xD0 (BUSY+DRDY+DSC) в регистре состояния
после чтения сектора, вместо положенных 0x58 (DRDY+DSC+DRQ). Однако первое чтение 0x1f7 в
chk_err_set_bda сбрасыает IRQ, далее HDD ставит новый запрос (если еще есть секторы для чтения).
После этого чтение 0x1f7/0x3f6 возвращает положенные 0x58 (или 0x50, если сектор последний). CF
же в таких условиях почти сразу возвращает 0x58, но это не помогает, так как уже отмечалось
не вырабатывается новый IRQ, даже после чтения 0x1f7 в chk_err_set_bda.

2. "Неправильный" код на LS-486E работает с CF нормально. Это связано с тем, что в обработчике IRQ14
LS-486E предусмотрено чтение регистра состояния, что сбрасывает IRQ от HDD
=====================================================================
IRQ14:
push ax
push ds
mov ax, 40h ; '@'
mov ds, ax
assume ds:nothing
or byte ptr ds:8Eh, 0FFh
push dx
mov dx, 1F7h ; just clear int flag inside HDD

from_irq15: ; CODE XREF: F:ED34j
in al, dx ; AT hard disk
; status register bits:
; 0: 1=prev cmd error
; 2: Corrected data
; 3: Data Request. Buffer is busy
; 4: Seek completed
; 5: Write fault
; 6: Drive ready (unless bit 4=0)
; 7: Busy
pop dx
out 0EBh, al
mov al, 20h ; ' '
out 0A0h, al ; PIC 2 same as 0020 for PIC 1
out 0EBh, al
out 20h, al ; Interrupt controller, 8259A.
mov ax, 9100h
pop ds
assume ds:nothing
int 15h ; OS HOOK - SET FLAG AND COMPLETE INTERRUPT (AT,XT2,XT286,CONV,PS)
; AL = type code (see AH=90h), ES:BX -> request block for type codes 80h through BFh
pop ax
iret
; ───────────────────────────────────────────────────────────────────────────
IRQ15:
push ax
push ds
mov ax, 40h ; '@'
mov ds, ax
assume ds:nothing
or byte ptr ds:8Eh, 0C0h
push dx
mov dx, 177h
jmp short from_irq15
=====================================================================

В старом же BIOS этого не предусмотрено
=====================================================================
IRQ14:
sti
push ax
push ds
push 40h
pop ds
mov byte ptr ds:8Eh, 0FFh
mov al, 20h ; ' '
out 0A0h, al ; PIC 2 same as 0020 for PIC 1
jmp short $+2
jmp short $+2
out 20h, al ; Interrupt controller, 8259A.
mov ax, 9100h

pop ds
assume ds:nothing
int 15h ; OS HOOK - SET FLAG AND COMPLETE INTERRUPT (AT,XT2,XT286,CONV,PS)
; AL = type code (see AH=90h), ES:BX -> request block for type codes 80h through BFh
pop ax
iret
=====================================================================

3. А каким же образом читается два сектора через int13h на проблемных BIOS? В debug этого добиться
не удалось, читался лишь один сектор. Однако если исполнять участок кода между чтением чектора и
обращением к 0x1f7 в chk_err_set_bda быстро (те не по шагам в debug и не вставляя лишних задержек в
код) то удается прочесть два сектора Можно предположить что в таких условиях CF вырабатывает IRQ,
но только один раз. Это все уже зависит от конкретной CF.

Ответить