TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

Документация   

Странности

FAQ

Ссылки

Форум

Гостевая книга

Рассылка

Благодарности

Об авторе

49: How is the code for rebooting the PC written in Turbo Pascal?

 A: This item draws from 
the information and the C-code example in
Stan Brown's, later J.Carlyle's comp.os.msdos.programmer FAQ,
ftp://garbo.uwasa.fi/pc/doc-net/dosfv204.zip (at the time of
updating this), from memory.lst and interrup.b in
ftp://garbo.uwasa.fi/pc/programming/inter46b.zip, and from
ftp://garbo.uwasa.fi/pc/programming/helppc21.zip. The Turbo 
Pascal
code is my adaptation of the C-code. It is not a one-to-one port.
   The usually advocated warm-boot method is storing $1234 in the
word at $0040:$0072 and jumping to address $FFFF:$0000. The 
problem
with this approach is that files must first be closed, potential
caches flushed. This is how to do this
  procedure REBOOT;
  label next;
  var regs  : registers;
      i     : byte;
      ticks : longint;
  begin
    {... "press" alt-ctrl ...}
    mem[$0040:$0017] := mem[$0040:$0017] or $0C;  { 00001100 }
    {... "press" del, try a few times ...}
    for i := 1 to 10 do
      begin
        FillChar (regs, sizeOf(regs), 0);  { initialize }
        regs.ah := $4F;  { service number }
        regs.al := $53;  { del key's scan code }
        regs.flags := FCarry;  { "sentinel for ignoring key" }
        Intr ($15, regs);
        {... check if the del key registered, if not retry ...}
        if regs.flags and Fcarry > 0 then goto next;
        {... waste some time, watch out for midnight ...}
        ticks := MemL [$0040:$006C];
        repeat until (MemL[$0040:$006C] - ticks > 3) or
                     (MemL[$0040:$006C] - ticks < 0)
    end; {for}
    exit;
  next:
    {... disk reset: writes all modified disk buffers to disk ...}
    FillChar (regs, sizeOf(regs), 0);
    regs.ah := $0D;
    MsDos (regs);
    {... set post-reset flag, use $0000 instead of $1234 for coldboot 
...}
    memW[$0040:$0072] := $1234;
    {... jump to $FFFF:0000 BIOS reset ...}
    Inline($EA/$00/$00/$FF/$FF);
  end;  (* reboot *)
One slight problem with this approach is that the keyboard 
intercept
interrupt $15 service $4F requires at least an AT according to
ftp://garbo.uwasa.fi/pc/programming/inter46b.zip. A simple test
based on "FFFF:E byte ROM machine id" (the 
previous definition is
from ftp://garbo.uwasa.fi/pc/programming/helppc21.zip) is:
  function ISATFN : boolean;
  begin
     case Mem[$F000:$FFFE] of
       $FC, $FA, $F8 : isatfn := true;
       else isatfn := false;
     end; {case}
  end;  (* isatfn *)
For a more comprehensive test use CPUFN "Get the type of 
the
processor chip" from TSUNTH in 
ftp://garbo.uwasa.fi/pc/ts/tspa3470.zip
or see the TP + ASM code in Michael Ticher (1992), PC Intern 
System
Programming, pp. 725-727.
   An addition by Per 
Bergland (d6caps@dtek.chalmers.se): I recently
downloaded the FAQ for this newsgroup, and studied the code for
rebooting a PC. The problem with that code (calling FFFF:0000) is
that it will not work in protected mode programs such as those
compiled for Windows or BP7 DPMI, or even in a DOS program 
run in a
Windows DOS session. The solution provided has been tested on
various COMPAQ PC:s, but I think it will work on any AT-class
machine. It involves using the 8042 keyboard controller chip output
pin 0, which is physically connected to the reset pin of the CPU.
There is unfortunately no way to perform a "warm" 
reboot this way,
and the warnings about disk caches etc apply to this code, too 
(see
FAQ). The code is written in BP7 assembly lingo, because that's 
what
I normally write code in, but anyone could rewrite it in C or high
level Pascal.
  UNIT Reboot;
  INTERFACE
    procedure DoReboot;
  IMPLEMENTATION
    procedure DoReboot;assembler;
    asm
      cli
  @@WaitOutReady:       { Busy-wait until 8042 is ready for new 
command}
      in al,64h         { read 8042 status byte}
      test al,00000010b { Bit 1 of status indicates input buffer full }
      jnz @@WaitOutReady
      mov al,0FEh       { Pulse "reset" = 8042 pin 0 }
      out 64h,al
      { The PC will reboot now }
    end;
  END.
 

 Contents

На первую страницу

Rambler's Top100 Rambler's Top100
PROext: Top 1000

(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz