comp.lang.ada
 help / color / mirror / Atom feed
From: "Jerry van Dijk" <jvandyk@ibm.net>
Subject: Re: DOS interrupts with GNAT 3.04
Date: 1996/12/25
Date: 1996-12-25T00:00:00+00:00	[thread overview]
Message-ID: <01bbf242$ea2558a0$LocalHost@jerryware> (raw)
In-Reply-To: 59p725$ff4@top.mitre.org



>   procedure interrupt_16 (interrupt: interrupts;
>                           register:  in out dos16bit.registers_16) is
>     reg: registers;

As DJ  and other warned several times:

1) This 16-bit Borland interface supports only a limited number of DOS
calls, which
    ones is not documented.
2) BIOS and other interrupt calls are not possible
3) These functions are *unsupported* and will disappear in the next DJGPP
    distribution.

Here's an example that shows some reliable techniques to access DOS from
the
GNAT/DJGPP enviroment:

-- Demonstrates how to call a dos interrupt with GNAT 3.05

with Interfaces;   use Interfaces;
with Interfaces.C; use Interfaces.C;

procedure Demo is

   -- Raised if the conventional memory transfer buffer is too small
   Transfer_Buffer_Too_Small : exception;

   -- Defines the DPMI available processor registers.
   -- Note: one of several possible definitions
   type Dpmi_Regs is
      record
         Di     : Unsigned_16;
         Di_Hi  : Unsigned_16;
         Si     : Unsigned_16;
         Si_Hi  : Unsigned_16;
         Bp     : Unsigned_16;
         Bp_Hi  : Unsigned_16;
         Res    : Unsigned_16;
         Res_Hi : Unsigned_16;
         Bx     : Unsigned_16;
         Bx_Hi  : Unsigned_16;
         Dx     : Unsigned_16;
         Dx_Hi  : Unsigned_16;
         Cx     : Unsigned_16;
         Cx_Hi  : Unsigned_16;
         Ax     : Unsigned_16;
         Ax_Hi  : Unsigned_16;
         Flags  : Unsigned_16;
         Es     : Unsigned_16;
         Ds     : Unsigned_16;
         Fs     : Unsigned_16;
         Gs     : Unsigned_16;
         Ip     : Unsigned_16;
         Cs     : Unsigned_16;
         Sp     : Unsigned_16;
         Ss     : Unsigned_16;
      end record;
   pragma Convention (C, Dpmi_Regs);

   -- Make DPMI issue a real mode interrupt
   procedure Dpmi_Int (Vector : in Unsigned_16; Regs : in out Dpmi_Regs);
   pragma Import (C, Dpmi_Int, "__dpmi_int");

   -- Defines the dos extender info block
   type Go32_Info_Block is
      record
         Size_Of_This_Structure_In_Bytes        : Unsigned_32;
         Linear_Address_Of_Primary_Screen       : Unsigned_32;
         Linear_Address_Of_Secondary_Screen     : Unsigned_32;
         Linear_Address_Of_Transfer_Buffer      : Unsigned_32;
         Size_Of_Transfer_Buffer                : Unsigned_32;
         Pid                                    : Unsigned_32;
         Master_Interrupt_Controller_Base       : Unsigned_8;
         Slave_Interrupt_Controller_Base        : Unsigned_8;
         Selector_For_Linear_Memory             : Unsigned_16;
         Linear_Address_Of_Stub_Info_Structure  : Unsigned_32;
         Linear_Address_Of_Original_Psp         : Unsigned_32;
         Run_Mode                               : Unsigned_16;
         Run_Mode_Info                          : Unsigned_16;
      end record;
   pragma Convention (C, Go32_Info_Block);

   -- Make the current extender info available within Ada
   Current_Info : Go32_Info_Block;
   pragma Import (C, Current_Info, "_go32_info_block");

   -- Procedure to copy data to conventional memory
   procedure Dosmemput (Buffer  : in char_array;
                        Length  : in Unsigned_32;
                        Fysical : in Unsigned_32);
   pragma Import (C, Dosmemput, "dosmemput");

   procedure DOS_Print(Str : in String) is

      -- The DOS formatted string (note the zero)
      DOS_String : char_array(0..Str'Length);

      -- The processor registers
      Regs : Dpmi_Regs;

   begin

      -- Translate the string to a DOS string by appending
      -- the '$' that DOS uses to mark the end of the string
      for I in Str'Range loop
         DOS_String (size_t (I-1)) := To_C ( Str (I));
      end loop;
      DOS_String (size_t (Str'Length)) := To_C ('$');

      -- Check that the djgpp conventional memory transfer buffer is
      -- large enough to hold our string. If not, raise an exception.
      -- Normally we would either enlarge the transfer buffer or allocate
      -- our own. Here we leave this as an exercise for the reader :-)
      if Current_Info.Linear_Address_Of_Transfer_Buffer < Str'Length + 1
then
         raise Transfer_Buffer_Too_Small;
      end if;

      -- Next, copy our string to the transfer buffer
      Dosmemput (DOS_String, Str'Length + 1,
        Current_Info.Linear_Address_Of_Transfer_Buffer);

      -- Now, tell dos to print the contents of the transfer buffer
      Regs.Ax := 16#0900#;

      -- Make Ds point to the segment part of the physical address
      Regs.Ds := Unsigned_16( Shift_Right(
        Current_Info.Linear_Address_Of_Transfer_Buffer, 4)) and 16#FFFF#;

      -- Make Dx point to the offset part of the physical address
      Regs.Dx := Unsigned_16(
        Current_Info.Linear_Address_Of_Transfer_Buffer) and 16#0F#;

      -- Issue the interrupt
      Dpmi_Int (16#21#, Regs);

   end DOS_Print;

begin
   DOS_Print("Hello, world!");
end Demo;

Jerry.





  reply	other threads:[~1996-12-25  0:00 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1996-12-21  0:00 DOS interrupts with GNAT 3.04 Rich Maggio
1996-12-23  0:00 ` Gautier
1996-12-24  0:00   ` Michael F Brenner
1996-12-25  0:00     ` Jerry van Dijk [this message]
1996-12-24  0:00   ` Robert Dewar
1996-12-25  0:00     ` Jerry van Dijk
1996-12-25  0:00       ` Robert Dewar
1996-12-25  0:00       ` Robert Dewar
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox