Главная | Файловый архив | Музей | Статьи и FAQ | Журнал "Downgrade" | Total Hardware'99 | Ссылки | Авторам | База данных | Конкурсы

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

ПОЛИГОН ПРИЗРАКОВ

Железные призраки прошлого - всё о старых компьютерах

Информация

ВНИМАНИЕ! При получении на e-mail оповещения о новом личном сообщении не отвечайте, пожалуйста, почтой. Воспользуйтесь личными сообщениями, иначе адресат не получит ваше послание.

ПОЛИГОН ПРИЗРАКОВ »   СТАРОЕ ЖЕЛЕЗО. IBM PC-совместимое. До 2000 года включительно »   Переделка АТ интерфейса клавиатуры в PS/2 на старых платах
RSS

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

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

Выводить сообщения

<<Назад  Вперед>>Страницы: 1 2 3 4 5 ... 7 8 9 10 11 * 12
Модераторы: Кай, Jccwu
Печать
 
i8088
Advanced Member


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


Ссылка


Дата регистрации на форуме:
30 янв. 2015
Только для AT (не слишком новых, где есть канал 1 8254)
можно попробовать процедуру из исходников IBM AT


;--- WAITF -------------------------------------------------------------
;  FIXED TIME WAIT ROUTINE HARDWARE CONTROLLED - NOT PROCESSOR)   :
;                       :
; ENTRY:                     :
;  (CX) = COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT        :
;    MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE        :
; EXIT:                      :
;    AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)  :
;  (CX) = 0                   :
;-----------------------------------------------------------------------

REFRESH_BIT  EQU  00010000B  ; REFRESH TEST BIT
PORT_B    EQU  061H    ; PORT B READ/WRITE DIAGNOSTIC REGISTER


WAITF  PROC  NEAR      ;  DELAY FOR (CX)*15.085737 US
  PUSH  AX      ; SAVE WORK REGISTER (AH)

WAITF1:         ;  USE TIMER 1 OUTPUT BITS
  IN  AL,PORT_B    ; READ CURRENT COUNTER OUTPUT STATUS
  AND  AL,REFRESH_BIT    ; MASK FOR REFRESH DETERMINE BIT
  CMP  AL,AH      ; DID IT JUST CHANGE
  JE  WAITF1      ; WAIT FOR A CHANGE IN OUTPUT LINE

  MOV  AH,AL      ; SAVE NEW FLAG STATE
  LOOP  WAITF1      ; DECREMENT HALF CYCLES TILL COUNT END

  POP  AX      ; RESTORE (AH)
  RET        ; RETURN (CX)= 0

WAITF  ENDP
Сейчас на форуме
Rio444
Модсостав
Обычный модератор

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


Ссылка


Дата регистрации на форуме:
14 сен. 2014
Очень просто, но очень неточно. Даже значение в Ah не инициализируют.
Перед WAITF1 должно быть:
IN  AL,PORT_B
MOV  AH,AL

Возможно именно этот алгоритм используется в int 15h функция 86h.

---
Троллей не кормить!!! За каждый "засчитанный слив" бан на неделю.
Сейчас на форуме
i8088
Advanced Member


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


Ссылка


Дата регистрации на форуме:
30 янв. 2015

Rio444 написал:
[q]
Даже значение в Ah не инициализируют.
[/q]

Мне тоже это не понравилось но я решил привести как в оригинале.

Дилемма в том, что с 8253/54 слишком много команд получается, что снизит точность.
Но при использовании канала2 будет чуть проще, тк его можно останавливать без latch.
Сейчас на форуме
Rio444
Модсостав
Обычный модератор

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


Ссылка


Дата регистрации на форуме:
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


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


Ссылка


Дата регистрации на форуме:
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
Модсостав
Обычный модератор

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


Ссылка


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

i8088 написал:
[q]
Те Вы предлагаете сделать пре-калибровку, а потом всюду использовать найденную константу?
[/q]

Собственно я так изначально предлагал
Rio444 написал:
[q]
Вообще, первая мысль была - использовать тупой цикл, со счетчиком.Вопрос только, где брать начальное значение счетчика? Оно будет зависеть от скорости процессора.Это начальное значение можно считать на этапе инициализации (т.е. только один раз).Но нужен какой-то таймер, который работает на всех вышеуказанных машинах, и работает одинаково.
[/q]


i8088 написал:
[q]
Цикл у Вас в конце лучше сделать так
[/q]

Смысл в том, что сохраняется число тактов на один проход цикла. Весь код совпадает, только меняется порядок инструкций, и inc cx меняется на dec cx.
Будут ли по числу тактов loop и dec(inc) cx jnz равноценны?

---
Троллей не кормить!!! За каждый "засчитанный слив" бан на неделю.
Сейчас на форуме
i8088
Advanced Member


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


Ссылка


Дата регистрации на форуме:
30 янв. 2015

Rio444 написал:
[q]
Будут ли по числу тактов loop и dec(inc) cx jnz равноценны?
[/q]

Навряд-ли, loop должна быть быстрее. Тогда оставим как есть.

Теперь осталось проверить реально получающуюся задержку.
Сейчас на форуме
Rio444
Модсостав
Обычный модератор

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


Ссылка


Дата регистрации на форуме:
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


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


Ссылка


Дата регистрации на форуме:
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
Модсостав
Обычный модератор

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


Ссылка


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

i8088 написал:
[q]
[/q]

Спасибо!
Дя, обломчик с int 15 86h.
Странно, что в большинстве источников не указан такой принципиальный момент.

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

---
Троллей не кормить!!! За каждый "засчитанный слив" бан на неделю.
Сейчас на форуме
<<Назад  Вперед>>Страницы: 1 2 3 4 5 ... 7 8 9 10 11 * 12
Модераторы: Кай, Jccwu
Печать
ПОЛИГОН ПРИЗРАКОВ »   СТАРОЕ ЖЕЛЕЗО. IBM PC-совместимое. До 2000 года включительно »   Переделка АТ интерфейса клавиатуры в PS/2 на старых платах
RSS

Последние RSS
Raspberry Pi приобрету
CRT Commodore 1084 - EGA|-EGA?
Задание тем у кого есть ДВК с MX:
Продаются платы, HDD-SATA-HDD, HDD, память.
Куплю оригинальный сетевой кабель для ЕС1841


Время выполнения скрипта: 0.0709. Количество выполненных запросов: 15, время выполнения запросов 0.0351


Партнёры: Компьютерный музей в Таллине | ЖЖ-сообщество | Таллин: Переулки Городских Легенд | Журнал "Downgrade"





Авторские права и условия копирования материалов



Hosted by Compic