RTC 和周期性中断

发布于 2024-12-27 17:40:00 字数 531 浏览 1 评论 0原文

谁能告诉我如何让 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 并不是必要的,但这是我最不可能尝试的事情。

Could anyone tell me how to make RTC generate periodic interrupts? Here's what I tried.

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

What I'm doing wrong? It actually seems to me that it's not nesesarry to block RTC, but this was the last thing i could've tried.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我为君王 2025-01-03 17:40:00

我在 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]

I have some old code in Borland/Turbo Pascal that used to work on real hardware and still works in DosBox, see if it helps:

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.

It prints (in DosBox):

Testing IRQ8. Wait a second...
Counts per second: 1048
Current time and date:
03:13:19 30/03/2012 [Friday]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文