Konwersja czasu o kodzie BCD do DEC - jak to zrobić?

0

Witam,
Za pomocą przerwań BIOS'a chcę otrzymać datę i czas. Jeśli miałbym użyć do tego przerwań DOS'a, to skorzystałbym z $2C. Ale w przypadku biosa, korzystam z int $1A, gdzie AH:= $02. Otrzymuję w tym momencie czas w kodzie BCD.
Informacja o przerwaniu:

AH = 02h
CF clear to avoid bug (see below)

Return:
CF clear if successful
CH = hour (BCD)
CL = minutes (BCD)
DH = seconds (BCD)
DL = daylight savings flag (00h standard time, 01h daylight time)
CF set on error (i.e. clock not running or in middle of update)

Staram się skonwertować otrzymany wynik na ludzką postać, do kodu dziesiętnego.

writeln(CH and 240,':',CL and 112);

Jeśli jeszcze w przypadku godziny wynik był poprawny, to już dalej nie mogę dobrać odpowiedniej maski.

0

Maski tu niczego nie załatwią.
23 w BCD to 2*16+3 z powrotem to ((CH)shr(4))+((CH)and($F))

0
program p1;
uses dos,crt;
procedure info;
var r:Registers;
godzina:string;
begin
with r do begin
AH:=$02;
intr($1A,r);
{writeln(CH,':',CL,':',DH);}
writeln(((CH) SHR (4)) + ((CH) and ($F)));
end;
end;

begin
info;
readln;
end.

Ten kod w takim wypadku powinien być poprawny. Ale nie jest. Bo niby jest godzina 17. A wyświetla "8".

0

Nie wyzerowałeś CX i DX przed wywołaniem przerwania. Nie masz pewności ci dostałeś jakiś zwrot czy zostali ci jakieś śmiecie.

0

W takim wypadku teraz mam wyzerowane te rejestry + flagę CF

program p1;
uses dos,crt;
procedure info;
var r:Registers;
godzina:string;
begin
with r do begin
AH:=$02;
CX:=0;
DX:=0;
FLAGS:= FLAGS AND $fffe;
intr($1A,r);
writeln(CH,':',CL,':',DH);
writeln(((CH) SHR (4)) + ((CH) and ($F)));
if (FLAGS and 1) = 1 then writeln('Blad');
end;
end;

begin
info;
readln;
end.

I w tej chwili również jest nieprawidłowa godzina.

0

To odpal sobie to:

Sek:=60;
while true do
begin
  NewSek:=Trunc(Now*24*60*60)mod(60);
  if Sek<>NewSek then
  begin
    Sek:=NewSek;
    with r do
    begin
      AH:=$02;
      CX:=0;
      DX:=0;
      FLAGS:= FLAGS AND $fffe;
      intr($1A,r);
      writeln(DH,' : ',Sek);
    end;
  end;
end;

przez minutę, po czym wydedukuj przeliczenie lub wklej wynik tu.

0

Witam,
Zrozumiałem, tyle że samodzielnie (ten program wymagał sporo zmian by w leciwym TP7 go odpalić - np. brak Now, o zmiennych nie wspominam bo je dodałem).
Wiedziałem wcześniej jak się koduje w kodzie BCD, ale jakoś nie wpadłem na pomysł co robię źle.

writeln(((CH) SHR (4)),((CH) and ($F)));

Teraz ten kod poprawnie wyświetla godzinę, a podobne linijki działają dobrze dla minut i sekund.
Dziękuję za pomoc.

1

TP7 to 16-bitowe środowisko (i pascal jako język programowania w tym środowisku) sprzed ponad 20 lat. To tak, jakbyś cofnął się do czasów 286. Użyj Delphi lub FPC/Lazarus (dzięki FP).

0

Niestety, ale u nas na uczelni króluje Turbo Pascal. Zresztą, niby moduły dosowe - czyli przerwania nie działają poprawnie w Lazarusie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1