RTC и периодические прерывания - PullRequest
0 голосов
/ 20 января 2012

Может кто-нибудь сказать мне, как заставить 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 не обязательно, но это было последнее, что я мог попробовать.

1 Ответ

0 голосов
/ 30 марта 2012

У меня есть какой-то старый код в 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]
...