# #assembly #timer #x86 #masm #real-mode
Вопрос:
Я пытаюсь сделать аппаратную задержку, используя счетчик 2 из 8254 микросхем, создав квадратную волну и подсчитав, сколько раз значение квадратной волны получало 1:
mov al, 10101110B
out 43H, al
mov al, 33h
out 42H, al
mov al, 05h
out 42H, al
;;enable the port
in AL, 61H
push ax
OR AL, 00000011B ;;enable PB0 and PB1
out 61h, al
mov cx, 200
;;make delay
waitf1:
in al, 62H ;; Reads from 62H The result is always 20h
and al, 20h
cmp al, ah
je waitf1
mov ah, al
loop waitf1
pop ax
out 61h, al
программа работает в цикле, так как значение, считываемое с порта 62h
, равно alwas 20h
( PC5
всегда равно 1), в то время как я ожидал, что это будет квадратная волна.
Ответ №1:
Мне интересно, имеет ли значение, находится ли таймер в режиме 2 или нет. Вот старый ассемблерный код, который я использовал, чтобы получить точное время из timer0 с помощью MSDOS. Короткие задержки jmp в размере $ 2 были необходимы, возможно, потому, что процессор работал немного быстрее, чем шина ISA. Поскольку этот код получает 16-битное количество от таймера, бит 15 может быть использован для шаблона прямоугольной волны. Количество прерываний, считанное в dx в этом коде, не требуется для исходного вопроса.
TMR equ 040h
Tmrgt0: cli
mov dx,IntCnt ;get current int count
mov al,0c2h ;output read channel 0 cmd
out TMR 3,al
jmp short $ 2
in al,TMR ;get bit (15 )
test al,2 ;br if in mode 2
jz Tmrgt1
shl al,1
jmp short $ 2
in al,TMR ;get bits ( 7-0) << 1
mov ah,al
jmp short $ 2
in al,TMR ;get bits (14-8) << 1
sti
xchg al,ah ;ax = bits 15-0
rcr ax,1
test ax,07fffh ;if bits (14-0) == 0 re-get
jz Tmrgt0
cmp dx,IntCnt ;if int occured re-get
jne Tmrgt0
neg ax ;make count positive
ret
Tmrgt1: in al,TMR ;get bits ( 7-0)
mov ah,al
jmp short $ 2
in al,TMR ;get bits (15-8)
sti
xchg al,ah ;ax = bits 15-0
cmp dx,IntCnt ;if int occured re-get
jne Tmrgt0
neg ax ;make count positive
ret
Комментарии:
1. Это тоже не работает с режимом 3. Я также меняю частоту на минимально возможную (значение в 42 часа на 0xFFFF ), но без изменений. Кажется, что квадратная волна не генерируется, но выход всегда равен 1
2. @Pouria — Я рекомендую использовать один из битов подсчета, полученных в приведенном выше коде, для прямоугольной волны. Для timer0 в одном из режимов вы получаете прямоугольную волну, в другом режиме вы просто получаете импульс, и это один из переходов, который соединен с выводом прерывания, управляемым краем, обычно используемым для тикера 18,2 Гц. Для чего вы инициализируете значение перезагрузки для счетчика?