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.
next prev parent 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