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

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

Конкурсы

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

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

Сообщение i8088 » 03.05.2020,14:41

Изначально тема начата здесь viewtopic.php?f=12&t=32154&start=77
Поскольку проблема (как оказалось) довольно глобальна, решил новую тему создать.

Проблема проявляется при чтении функцией 02h int13h (read sectors into memory) - на некоторых
старых BIOS невозможно прочитать более 2 секторов. Проблемны именно некоторые старые BIOS:
ранние AMI (до "Hi-Flex", это которые часто с диагностикой еще), Phoenix и AWARD. Чуть более свежий
AWARD (1993 год, 386SX, уже с автоопределением параметров HDD) все нормально. AMI Hi-Flex версия
тоже OK.

CF тоже ведут себя слегка по разному на проблемных BIOS - так одна из CF позволяет прочестьдо 64
секторов в slave режиме, хотя с другой CF (тоже в slave режиме) по прежнему читается не более 2
секторов, причем чтение двух секторов с с флагом - "ошибка скорректирована с помощью ECC" (код
11h). Если заказать 3 и более сектора, то ошибка 80h - тайм аут рекалибровки. Впрочем важен факт
проблемной работы любой CF в любом режиме (master/slave) при превышении определенного лимита
секторов, чаще всего 2.

Мне удалось найти две версии 286 AMI BIOS на одном движке (D286, для ранних плат, эти BIOS еще без
чипсетозависимых процедур). Один BIOS выпуска 89 года, проблема есть, второй 90 года, и проблемы
уже нет, CF работают нормально. Начато реверсирование обеих BIOS на предмет сравнения процедуры
чтения int 13 02h, и обработчика IRQ14.

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

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

Сообщение Aleks69 » 04.05.2020,11:30

Добрый день! Спасибо за интереснейшую информацию.

Биос - сделаю дамп, сегодня вечером или завтра уже точно. Есть Checkit, еще кое-какие утилиты по DOS - PCProbe, PCDR, TS.
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 » 04.05.2020,14:55

Aleks69 писал(а): 04.05.2020,11:30 Биос - сделаю дамп, сегодня вечером или завтра уже точно. Есть Checkit, еще кое-какие утилиты по DOS - PCProbe, PCDR, TS.
У Вас там 1Mbit ПЗУ (128KB) - скорее всего основной BIOS + VGA. Сделайте дамп
приложенной утилитой (bios128.exe). Обязательно отключите все shadow и кеши
перед этим!

Теперь продолжение.
В ходе сравнения обработчиков обнаружилось, что BIOS-ы весьма схожи, но есть
отличие в обработчике команд чтения/длинного чтения (с ECC байтами)

Вот код обработчика команды чтения из проблемных BIOS, он абсолютно
идентичен у 286 (BIOS 09/15/89) и 386DX-20 (BIOS 09/15/89) плат:
======================================================
; 286 (BIOS 09/15/89) and 386DX-20 (BIOS 09/15/89)
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
test byte ptr ds:76h, 0C0h
jz skip_dis_retry
inc ah

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

ata_read_sec:
call chk_busy_set_fl
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
test byte ptr [bp+8], 2 ; normal or long read?
jz skip_ecc_read
call chk_drq_and_dly
jb ata_read_exit
mov cx, 4 ; read 4 ECC words

read_ecc_bytes:
in al, dx
mov es:[di], al
inc di
jmp short $+2
jmp short $+2
jmp short $+2
loop read_ecc_bytes

skip_ecc_read:
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
======================================================

А вот код из 286 (BIOS 04/09/90 года) и 386 платы M321 (BIOS 06/06/92),
где с чтением CF все нормально, обработчики у этих BIOS почти идентичны:
======================================================
; 386 M321 (BIOS 06/06/92) and 286 (BIOS 04/09/90)
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 ; enable head 3 and set HDPT's
test byte ptr ds:76h, 0C0h
jz skip_dis_retry
inc ah

skip_dis_retry:
call tf_write
call wp_set ; write pre-cmpensation set
mov al, ah
call ata_cmd

ata_read_sec:
call chk_busy_set_fl
jb ata_read_exit
call chk_err_set_bda ; check status and error reg (if need)
; and set BDA bytes
jnb ata_r_no_error ; if no errors, processed
cmp byte ptr ds:74h, 11h
jnz set_ah_err_code ; if ECC corrected error, also processed

ata_r_no_error:
mov es, si
mov cx, 100h
mov dx, 1F0h
cli
cld
rep ins word ptr es:[di], dx
sti
test byte ptr [bp+8], 2
jz skip_ecc_read
call chk_drq_and_dly ; check DRQ and delay, set time-out flag
jb ata_read_exit
mov cx, 4

read_ecc_bytes:
in al, dx
mov es:[di], al
inc di
jcxz $+2 ; (BIOS D286 used <jmp short $+2> commands)
jcxz $+2
jcxz $+2
loop read_ecc_bytes
skip_ecc_read:
dec byte ptr [bp+3]
jnz ata_read_sec

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

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

Можно видеть что в проблемных BIOS-ах происходит проверка регистров состояния
и ошибок (и установка флагов BDA) почти сразу же после чтения сектора (rep insw),
это собственно процедура chk_err_set_bda

А в BIOS-ах, где с чтением CF все нормально процедура chk_err_set_bda вызывается
до первого чтения сектора и далее она вызывается после каждого чтения очередного
сектора, но после процедуры chk_busy_set_fl, в которой есть внутреняя процедура
задержки.

Текущее предположение - CF не всегда успевает вовремя выставить правильные
биты в регистрах состояния и (возможно) регистра ошибок при чтении с количеством
секторов более определенного (и соответственно наш код ошибается после
определенного сектора). Так ли это надо еще проверить. И если так, то проверить
какие именно биты устанавливаются неверно. Возможно это случается и с какими-то
HDD, ведь код не случайно же изменили, а CF в 90 году еще и в проекте не было.
Буду проверять.

А вот код процедуры chk_err_set_bda
======================================================
chk_err_set_bda proc near
push dx
push ax
mov dx, 1F7h
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
mov ds:8Ch, al ; set in BDA status that controller return
mov ah, 11h
test al, 4
jnz exitchk_setbda ; ECC error?
mov ah, 0CCh
test al, 20h
jnz exitchk_setbda ; write fault error?
mov ah, 0AAh
test al, 40h
jz exitchk_setbda ; Drive not ready error?
mov ah, 40h
test al, 10h
jz exitchk_setbda ; No seek completed error?
mov ah, 0
test al, 1
jz exitchk_setbda ; No error?
mov dx, 1F1h
in al, dx ; AT hard disk controller
; Error register. Bits for last error:
; 0: Data Address Mark not found
; 1: Track 0 Error
; 2: Command aborted
; 4: Sector ID not found
; 6: ECC Error: Uncorrectable data error
; 7: Bad block
mov ds:8Dh, al ; set in BDA error that controller return
mov ah, 2
test al, 1
jnz exitchk_setbda ; AMNF error?
mov ah, 1
test al, 4
jnz exitchk_setbda ; bad command?
mov ah, 4
test al, 10h
jnz exitchk_setbda ; sector not found error?
mov ah, 10h
test al, 40h
jnz exitchk_setbda ; ECC uncorrectable error?
mov ah, 40h
test al, 2
jnz exitchk_setbda ; seek (track 0) failure error?
mov ah, 0Ah
test al, 80h
jnz exitchk_setbda ; bad sector found?
mov ah, 0BBh ; set undefined error

exitchk_setbda:
mov ds:74h, ah
pop dx
mov al, dl
pop dx
or ah, ah
jz no_set_carry
stc

no_set_carry:
retn
chk_err_set_bda endp
======================================================
Вложения
bios128.exe
(13.41 КБ) 201 скачивание

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

Конкурсы

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

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

Сообщение i8088 » 05.05.2020,15:42

Кажется получилось!
Я заменил процедуру чтения и поправил вторую КС, CF стала читаться, проверил
128 секторов читает. Буду проверять с разными CF.

Прилагаю архив с оригинальным (386dx20.rom) и модифицированным BIOS (xxx.m01)
А плата сама - ранний 386DX-20MHz без кеша, чипсет CHIPS
P82B305
P82B305
P82C302
P82A303
P82C301
P82A306
P82A304
P82C206
Вложения
386dx20.zip
(106.31 КБ) 187 скачиваний

marinovsoft
Advanced Member
Сообщения: 568
Зарегистрирован: 02.09.2017,09:08
Откуда: Кемерово
Контактная информация:

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

Сообщение marinovsoft » 05.05.2020,17:20

А вот накачать бы биосов старых, да написать универсальный патчер под это дело :)
ПК8010 "Корвет"+ExtRom+AY, Atari 65XE+SDrive, Дельта-С(52ИС)+AY
Продам материнские платы

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

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

Сообщение Aleks69 » 05.05.2020,18:47

Добрый день!

Вот БИОС с платы AT&T MODEL 6386SX/EL20 (FM-0589-09) на процессоре 80386-SX20. Все кеши и затенение отключил.
Первый вариант сделан с отражением Video BIOS на начало с С0000, второй - E0000. На всякий случай. Больше у нее ничего не настраивается.
Вложения
Bios_AT&T.zip
(80.45 КБ) 185 скачиваний
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 » 06.05.2020,14:16

Aleks69, OK, принято!

Я сейчас хочу перенести код из BIOS в exe файл, чтобы точно узнать при каких
условиях ошибка с CF случается. Те если нужна задержка, то какая итп

Кстати, ни у кого нет Phoenix BIOS (286 - 386 - 486, но не новее), на котором CF
работают? Чипсет не важен.

Mx_Serg
Advanced Member
Сообщения: 1847
Зарегистрирован: 04.06.2018,22:47

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

Сообщение Mx_Serg » 06.05.2020,17:25

i8088 писал(а): 06.05.2020,14:16 Кстати, ни у кого нет Phoenix BIOS (286 - 386 - 486, но не новее), на котором CF
работают?
У меня только на 486-й работают. На 386-й VLSI "non-system or disk error" при загрузке и долго горит светодиод активности. AWARD VLSI 286 ведет себя точно так же, кстати... "четверка" уже 95-го года на UMC 8881. Если такая интересует - попробую снять образ.

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

Конкурсы

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

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

Сообщение i8088 » 07.05.2020,09:02

Mx_Serg писал(а): 06.05.2020,17:25 "четверка" уже 95-го года на UMC 8881. Если такая интересует - попробую снять образ.
Да, если он еще неупакованный, то вполне может помочь.

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

Mx_Serg
Advanced Member
Сообщения: 1847
Зарегистрирован: 04.06.2018,22:47

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

Сообщение Mx_Serg » 07.05.2020,13:06

Снял программатором. 94г
Вложения
UMC8881.BIN
(128 КБ) 167 скачиваний

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

Конкурсы

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

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

Сообщение i8088 » 08.05.2020,17:19

Mx_Serg писал(а): 07.05.2020,13:06 Снял программатором. 94г
Спасибо, посмотрю!

Я сделал изменения как считал правильным, но не уверен.
Aleks69, попробуйте тестовый вариант, attv.m01
Если есть возможность, считайте оригинальное ПЗУ программатором, мне интересно
что точно между 0x8000 и 0xFFFF. Я заполнил 0xFF. Байтовую КС разместил по адресу
0x1FFFF

Только не трогайте оригинальное ПЗУ, запишите образ в новую микросхему, можно
и flash использовать.
Вложения
attm01.zip
(49.29 КБ) 160 скачиваний

Ответить