Внимание! Это временный неофициальный архив старой версии форума Полигон Призраков, созданный сочувствующим форуму участником. Этот сайт просуществует лишь до тех пор, пока администрация Полигона не сдержит своё обещание и не откроет официальный архив по адресу old.sannata.org.

Полигон-2

Форум о старых компьютерах

Объявление форума

Если пользуетесь личными сообщениями и получили по электронной почте оповещение о новом письме, не отвечайте, пожалуйста, почтой. Зайдите на форум и ответьте отправителю через ЛС.

Полигон-2 »   IBM PC-совместимое. До 2000 года включительно »   Переделка АТ интерфейса клавиатуры в PS/2 на старых платах
RSS

Переделка АТ интерфейса клавиатуры в PS/2 на старых платах

Уровня 386-х, 486-х, чтобы можно было подключить PS/2 мышь.

<<Назад  Вперед>> Страницы: 1 2 3 4 5 ... 8 9 10 11 12 13 14 15 16 17
Печать
 
Rio444
Гость


Откуда: Ростов-на-Дону
Всего сообщений: 8632
Рейтинг пользователя: 0


Ссылка


Дата регистрации на форуме:
14 сен. 2014
Посмотрите вот такой вариант:

; Расчет значения счетчика для задержки 15мкс
; Выходное значение cx = значение счетчика для цикла с задержкой 15мкс
; Если cx = 0 - ошибка
  timer equ 040h    ; Используем таймер 0
  xor cx,cx  ; Обнуляем счетчик
  cli    ; Запрещаем прерывания
  in al,timer
  mov bh,al
  in al,timer
  mov bl,al  ; Теперь в bh, bl у нас два подряд считанных значения из тамера. Младший байт и старший байт. Порядок значения не имеет.
        ; Это начальные значения, с которыми будем сравнивать
start_loop:
  inc cx  ; Увеличиваем на 1 счетчик
  jz exit_15us  ; Если счетчик = 0, т.е. прошло 65536 циклов, то выходим. Ошибка.
  xchg  bl,bh  ; Меняем местами bh и bl. В первом цикле в bl 1-й принятый байт, во втором 2-й, опять 1-й, снова 2-й и т.д.
  mov ah,bl  ; То же самое теперь в ah
  in al,timer
  sub ah,al  ; Вычитаем новое значение в счетчике из начального
  cmp ah,18  ; Если разница > 18
  jb start_loop  ; Повторяем цикл
exit_15us:  
  mov word [const_15us],cx  ; Сохраняем рассчитанное значение
  sti    ; Включаем прерывания
const_15us: dw 0
  
; Теперь сам цикл с задержкой. Из-за того, что прерывания не отключаем, реальная задержка может быть больше 15мкс
  mov word cx,[const_15us]  ; Задаём начальное значение счетчика
loop_15:
  xchg  bl,bh  ; Фиктивные операции, которые бесполезны, но вносят такую же задержку, как в расчете начального значения счетчика
  mov ah,bl  ; Фиктивная
  in al,timer  ; Фиктивная
  sub ah,al  ; Фиктивная
  cmp ah,18  ; Фиктивная
  jb next_15  ; Фиктивная
next_15:  
  dec cx  ; Уменьшаем на 1 счетчик
  jnz loop_15  ; Если он не равен 0, повторяем цикл


На 386DX-40 получилось на выходе 10 циклов. Что вполне неплохо. На 286-й конечно точность будет очень низкая.
i8088
Advanced Member


Откуда: г. Баку, Азербайджан
Всего сообщений: 2132
Рейтинг пользователя: 0


Ссылка


Дата регистрации на форуме:
30 янв. 2015
Те Вы предлагаете сделать пре-калибровку, а потом всюду использовать найденную константу?

В принципе оба варианта (IBM и Ваш) могут использоваться, в
зависимости от целей.

А Вы пробовали проверить реальную задержку осциллографом?

Я проверял так

LPT_DATA_PORT  EQU  0378H

  MOV  DX, LPT_DATA_PORT
  MOV  AX, 55H
  OUT  DX, AL
  MOV CX,  0
CLI
LPT_LOOP:
  CALL  NEAR PTR DLY
  IN  AL, DX
  XOR  AL, 0FFH
  OUT  DX, AL
  LOOP  LPT_LOOP
STI

Это делает 65536 импульсов и пауз в порт принтера.
Проверить, насколько изменится длительность импульсов и паузы
если заккоментировать CALL DLY (для уменьшения потерь времени можно заменить макроопределением). Разность и даст задержку.

Цикл у Вас в конце лучше сделать так

loop_15:
  xchg  bl,bh  ; Фиктивные операции, которые бесполезны, но вносят такую же задержку, как в расчете начального значения счетчика
  mov ah,bl  ; Фиктивная
  in al,timer  ; Фиктивная
  sub ah,al  ; Фиктивная
  cmp ah,18  ; Фиктивная
  jb next_15  ; Фиктивная
next_15:  
  loop loop_15  ; Если он не равен 0, повторяем цикл
Rio444
Гость


Откуда: Ростов-на-Дону
Всего сообщений: 8632
Рейтинг пользователя: 0


Ссылка


Дата регистрации на форуме:
14 сен. 2014
i8088 написал:
[q]
Те Вы предлагаете сделать пре-калибровку, а потом всюду использовать найденную константу?
[/q]
Собственно я так изначально предлагал
Rio444 написал:
[q]
Вообще, первая мысль была - использовать тупой цикл, со счетчиком.Вопрос только, где брать начальное значение счетчика? Оно будет зависеть от скорости процессора.Это начальное значение можно считать на этапе инициализации (т.е. только один раз).Но нужен какой-то таймер, который работает на всех вышеуказанных машинах, и работает одинаково.
[/q]
i8088 написал:
[q]
Цикл у Вас в конце лучше сделать так
[/q]
Смысл в том, что сохраняется число тактов на один проход цикла. Весь код совпадает, только меняется порядок инструкций, и inc cx меняется на dec cx.
Будут ли по числу тактов loop и dec(inc) cx jnz равноценны?
i8088
Advanced Member


Откуда: г. Баку, Азербайджан
Всего сообщений: 2132
Рейтинг пользователя: 0


Ссылка


Дата регистрации на форуме:
30 янв. 2015
Rio444 написал:
[q]
Будут ли по числу тактов loop и dec(inc) cx jnz равноценны?
[/q]
Навряд-ли, loop должна быть быстрее. Тогда оставим как есть.

Теперь осталось проверить реально получающуюся задержку.
Rio444
Гость


Откуда: Ростов-на-Дону
Всего сообщений: 8632
Рейтинг пользователя: 0


Ссылка


Дата регистрации на форуме:
14 сен. 2014
Осциллограф далеко и барахлит, поэтому проверил программно:
org 0100h
; Расчет значения счетчика для задержки 15мкс
; Выходное значение cx = значение счетчика для цикла с задержкой 15мкс
; Если cx = 0 - ошибка
  timer equ 040h    ; Используем таймер 0
  xor cx,cx  ; Обнуляем счетчик
  cli    ; Запрещаем прерывания
  in al,timer
  mov bh,al
  in al,timer
  mov bl,al  ; Теперь в bh, bl у нас два подряд считанных значения из таймера. Младший байт и старший байт. Порядок значения не имеет.
        ; Это начальные значения, с которыми будем сравнивать
start_loop:
  inc cx  ; Увеличиваем на 1 счетчик
  jz exit_15us  ; Если счетчик = 0, т.е. прошло 65536 циклов, то выходим. Ошибка.
  xchg  bl,bh  ; Меняем местами bh и bl. В первом цикле в bl 1-й принятый байт, во втором 2-й, опять 1-й, снова 2-й и т.д.
  mov ah,bl  ; То же самое теперь в ah
  in al,timer
  sub ah,al  ; Вычитаем новое значение в счетчике из начального
  cmp ah,18  ; Если разница > 18
  jb start_loop  ; Повторяем цикл
exit_15us:  
  mov word [const_15us],cx  ; Сохраняем рассчитанное значение
  sti    ; Включаем прерывания
  
  mov ah, 09h
  mov dx, start_string
  int 21h      ; вывод строки на экран

  xor cx,cx
start_main_loop:
  call delay_15us
  call delay_15us
  call delay_15us
  call delay_15us
  call delay_15us
  call delay_15us
  call delay_15us
  call delay_15us
  call delay_15us
  call delay_15us
  loop start_main_loop
  
  
  mov ah, 09h
  mov dx, end_string
  int 21h      ; вывод строки на экран  
  
  int 20h ; Выходим из программы


delay_15us:  ; Подпрограмма задержки 15 микросекунд
  mov word dx,[const_15us]  ; Задаём начальное значение счетчика
loop_15:
  xchg  bl,bh  ; Фиктивные операции, которые бесполезны, но вносят такую же задержку, как в расчете счетчика
  mov ah,bl  ; Фиктивная
  in al,timer  ; Фиктивная
  sub ah,al  ; Фиктивная
  cmp ah,0  ; Фиктивная
  jb next_15  ; Фиктивная
next_15:  
  dec dx  ; Уменьшаем на 1 счетчик
  jnz loop_15  ; Если он не равен 0, повторяем цикл
  ret
  
const_15us: dw 0
start_string: db 'Program start$'
end_string: db 10,13,'Program end$'

С метки start_main_loop находится цикл, который выполняется 65536 раз, в каждом цикле 10 раз вызывается задержка 15мкс.
Расчетная задержка = 15мкс*65536*10 = 9 830400 мкс = 9,83 секунд
Интервал считаем между появлением на экране сообщений Program start и Program end.
По секундомеру получилось 11,3 секунды. Что вполне неплохо коррелирует. Т.е. реальная задержка (с учетом затрат времени на call и ret) получается ~17мкс.
i8088
Advanced Member


Откуда: г. Баку, Азербайджан
Всего сообщений: 2132
Рейтинг пользователя: 0


Ссылка


Дата регистрации на форуме:
30 янв. 2015
OK, неплохо! Можно попробовать использовать!

PS. Я кстати посмотрел несколько datasheet, канал1 имеется и в достаточно
новых системах (865, современные PCH например), те простой вариант IBM тоже можно использовать даже на современных платах.


Я нашел про int 15 AH=86

INT 15 - системное прерывание - WAIT
- ожидание - (для AT,XT2,XT286,CONV,PS)
AH = 86h
CX,DX = число микросекунд ожидания (с точностью до 977 мс)
Возвращает: CF сброшен: после окончания ожидания
CF установлен: немедленно при ошибке
Примечание: точность периода ожидания равна 977 микросекунд в большинстве
секунд потому что большинство BIOS использует прерывание от мик-
росхемы таймера AT с частотой 1/1024 секунды доступные по INT 70
Смотри: AH=83h, INT 70

NT 70 - IRQ8 - AT/XT286/PS50+ - REAL-TIME CLOCK
- часы реального времени -
Примечание: может маскироваться установкой бита 0 в порте Ввода/Вывода A1h
Смотри: INT 58

Те оно использует прерывание от RTC и не годится для нашей цели.
Rio444
Гость


Откуда: Ростов-на-Дону
Всего сообщений: 8632
Рейтинг пользователя: 0


Ссылка


Дата регистрации на форуме:
14 сен. 2014
i8088 написал:
[q]
[/q]
Спасибо!
Дя, обломчик с int 15 86h.
Странно, что в большинстве источников не указан такой принципиальный момент.

Но, по большому счету, в TSR программе вообще нельзя использовать int.
Rio444
Гость


Откуда: Ростов-на-Дону
Всего сообщений: 8632
Рейтинг пользователя: 0


Ссылка


Дата регистрации на форуме:
14 сен. 2014
Не прошло и месяца, как появились хоть немного заметные подвижки)))
Наконец есть рабочая "альфа" версия программы.
Работает пока через одно место, не со всеми драйверами и многое не понятно. Но работает.
Довольно много драйверов мыши "плюют" на "штатный" обработчик прерывания мыши Irq12 (Int 74h) и полностью подменяют его собственным.
Вот некоторые из таких драйверов и заработали. В частности, проверил на CuteMouse (версии 1.9, 2.0, 2.1 - работает со всеми).
И какой-то старый драйвер от А4 Tech.
Некий неизвестно чей драйвер "amouse.com" отказывается загружаться, сообщая, что "установка драйвера PS/2 мыши невозможна".
Драйвер, который при запуске пишет, что он ©Microsoft и ©IBM, 1992-го года, загружается, но сразу вешает систему (или отрубает клавиатуру?).
Пока так.

В процессе инициализации размаскировываю прерывание Irq12, но к концу программы какая-то хрень снова его маскирует.
Не могу понять какая. Сейчас перед выходом из программы приходится повторно его размаскировывать.
i8088
Advanced Member


Откуда: г. Баку, Азербайджан
Всего сообщений: 2132
Рейтинг пользователя: 0


Ссылка


Дата регистрации на форуме:
30 янв. 2015
Роман, поздравляю с первым вариантом программы!!


Rio444 написал:
[q]
В процессе инициализации размаскировываю прерывание Irq12, но к концу программы какая-то хрень снова его маскирует.
Не могу понять какая. Сейчас перед выходом из программы приходится повторно его размаскировывать.
[/q]
Это под чистым DOS делается? По идее кроме драйвера мыши
заниматься манипуляциями с irq12 некому? Он уже загружен при
запуске программы?
Rio444
Гость


Откуда: Ростов-на-Дону
Всего сообщений: 8632
Рейтинг пользователя: 0


Ссылка


Дата регистрации на форуме:
14 сен. 2014
Спасибо!

i8088 написал:
[q]
Это под чистым DOS делается?
[/q]
Да, MS-DOS 6.22

i8088 написал:
[q]
По идее кроме драйвера мышизаниматься манипуляциями с irq12 некому? Он уже загружен призапуске программы?
[/q]
Нет. Ни один драйвер мыши не грузится до запуска проги. Чтобы не запутаться, пусть прога будет называться "ps2supp.com".

Программа ps2supp добавляет PS/2 мышь в список устройств, хранящийся по адресу 40:10h (и вызываемый через int 11h).
Драйверы в первую очередь проверяют, есть ли мышь в этом списке.
Ps2supp также подменяет обработчик int 15h. Оставляет в памяти свой, который проверяет, не являются ли запрашиваемые функции службами работы с мышью (AH = C2h, AL = 00-07h). Если не являются, передаёт управление дефолтному обработчику. Если являются - обрабатывает сам.
Кроме этого ps2supp.com подменяет int 74h - прерывание, вызываемое по irq12. Обработка int74h видимо пока не работает должным образом, поэтому драйверы мыши, которые его используют тоже не работают. Но как писал выше, многие драйверы подменяют int74h своим обработчиком.

Штатный обработчик irq12 (int 74h) не так прост, как кажется.
Он не только вызывает драйвер мыши, а готовит для него данные.
Пакет данных от мыши содержит 3 или 4 байта (мышь без колесика и с колесиком). Отправляет их мышь по очереди, по одному байту. После каждого байта генерируется irq12. Штатный обработчик irq12 (int74h) собирает все эти 3 или 4 байта вместе, помещает их в стек и только после этого вызывает драйвер мыши.
Для того, чтобы можно было хранить промежуточные данные до того, как пакет придет полностью, плюс адрес драйвера мыши, плюс флаги и счетчики, в конце RAM (в конце 640кб) резервируется 1кб памяти под EBDA - "Extended BIOS Data Area". Основное её назначение именно хранение данных для поддержки PS/2 мыши. Но как пишут в источниках, биос мождет хранить там и другие данные.
Тут я немного схитрил, и разместил первые 30h байт EBDA (которые используются для PS/2 мыши) в теле резидентной части ps2supp.com. Точнее в конце её PSP.
Возможно некоторый драйверы видят "подвох" и отказываются грузиться.

Возможная причина также может быть в том, что наличие PS/2 мыши фиксируется в CMOS. Это пока не реализовано.
Помимо этого, прерывание int 15h, служба C0h возвращает адрес таблицы конфигурации системы, в которой содержится информация, выделена ли область EBDA. Находится эта таблица в ROM. В принципе, эту службу тоже можно подменить, переместив таблицу в RAM.
Маловероятно, но возможно какие-то драйверы проверяют и эту таблицу.
<<Назад  Вперед>> Страницы: 1 2 3 4 5 ... 8 9 10 11 12 13 14 15 16 17
Печать
Полигон-2 »   IBM PC-совместимое. До 2000 года включительно »   Переделка АТ интерфейса клавиатуры в PS/2 на старых платах
RSS

1 посетитель просмотрел эту тему за последние 15 минут
В том числе: 1 гость, 0 скрытых пользователей

Последние RSS
[Москва] LIQUID-Акция. Сливаются разъемы CF
МС7004 и 7004А на AT и XT
Пайка термотрубок
Проммать s478 PEAK 715VL2-HT ( Full-Size SBC)
Подскажите по 386 материке по джамперам.

Самые активные 5 тем RSS