有人能告诉我如何让RTC产生周期性中断吗?这是我试过的。
mov al, 0Bh
out 70h, al
in al, 71h
or al, 10000000b
push ax
mov al, 0Bh
out 70h, al
pop ax
out 71h, al
mov al, 0Ah
out 70h, al
in al, 71h
or al, 00001111b
push ax
mov al, 0Ah
out 70h, al
pop ax
out 71h, al
mov al, 0Bh
out 70h, al
in al, 71h
or al, 01000000b
push ax
mov al, 0Bh
out 70h, al
pop ax
out 71h, al
mov al, 0Bh
out 70h, al
in al, 71h
and al, 01111111b
push ax
mov al, 0Bh
out 70h, al
pop ax
out 71h, al
我做错了什么?在我看来,阻止RTC并不是很重要,但这是我可以尝试的最后一件事。
答案 0 :(得分:0)
我在Borland / Turbo Pascal中有一些旧代码,它曾经在真正的硬件上工作,仍然可以在DosBox中运行,看看是否有帮助:
uses
crt, dos;
const
daystr : array [0..6] of string[10] = (
'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednsday',
'Thirsday', 'Friday');
var
poldtimer : pointer;
irq8_enabled,
rtc_int_enabled : boolean;
int_count : integer;
hour, minute, second,
dayofweek,
day, month, year, century : word;
function readcmos (reg : byte) : byte; assembler;
asm
mov al, reg
out $70, al
jmp @1
@1:
in al, $71
end;
procedure writecmos (reg, value : byte); assembler;
asm
mov al, reg
out $70, al
jmp @1
@1:
mov al, value
out $71, al
end;
{ New IRQ8 ISR }
procedure irq8 (Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word); interrupt;
begin
inc (int_count);
readcmos($c); { W/O this, RTC doesn't work }
if irq8_enabled then
asm
pushf
call dword ptr [poldtimer] { Call to original IRQ8 ISR }
end
else begin
port [$20] := $20;
port [$a0] := $20
end;
end;
begin
clrscr;
int_count := 0;
irq8_enabled := port[$a1] and 1 = 0;
rtc_int_enabled := readcmos ($b) and $40 = $40;
getintvec ($70, poldtimer); { Save old IRQ8 ISR address }
setintvec ($70, @irq8); { Set new IRQ8 ISR }
if not irq8_enabled then
port[$a1] := port[$a1] and $fe; { Unmask IRQ8 }
writecmos ($a, $26);
if not rtc_int_enabled then
writecmos ($b, readcmos($b) or $40); { Enable RTC interrupt }
writeln ('Testing IRQ8. Wait a second...');
delay (1000); { Little delay }
if not rtc_int_enabled then
writecmos ($b, readcmos($b) and not $40); { Disable RTC interrupt }
if not irq8_enabled then
port[$a1] := port[$a1] or 1; { Mask IRQ8 }
setintvec ($70, poldtimer); { Restore old IRQ8 ISR }
writeln ('Counts per second: ', int_count);
writeln ('Current time and date:');
repeat
gotoxy (1, wherey);
while (readcmos($a) and $80 = $80) do;
second := readcmos(0);
minute := readcmos(2);
hour := readcmos(4);
dayofweek := readcmos (6);
day := readcmos (7);
month := readcmos (8);
year := readcmos (9);
century := readcmos ($32);
write (hour shr 4, hour and 15, ':', minute shr 4, minute and 15, ':',
second shr 4, second and 15, ' ');
write (day shr 4, day and 15, '/', month shr 4, month and 15, '/',
century shr 4, century and 15, year shr 4, year and 15,
' [', daystr[dayofweek], ']');
until keypressed;
while keypressed do readkey;
writeln
end.
它打印(在DosBox中):
Testing IRQ8. Wait a second...
Counts per second: 1048
Current time and date:
03:13:19 30/03/2012 [Friday]