From: "Laura & Mike Palmer" <thepalmers@lineone.net>
Subject: Re: Interrupt Calls
Date: 1997/11/10
Date: 1997-11-10T00:00:00+00:00 [thread overview]
Message-ID: <01bcee03$8908d020$cd3663c3@default> (raw)
In-Reply-To: 34651851.DAA7064E@academic.truman.edu
Hi,
here is an interesting example of how to use INT 21, as it make use
of GNAT's ability to call C programs easily.
N.B. We use Windows 95.
First of all, you must create a package which contains a record that
defines the registers and a procedure that will allow you to call the
interrupt.
For this purpose you can use 'package Disk', file disk.ads.
Then you need to write a C program which contains your own defined
procedure
(void ada86) that uses the machine interrupt 'int86'. Why C ? Because so
you can use the C libraries --> Dos.h
You can call the C program DISKC.C
To test it write a procedure that calls My_Int86. You can use any
interrupts you like, in this example we use INT21, 36.
The package Interfaces is in the directory ' GNAT305/ADAINC ' and allows
the eay usage of C types in Ada code.
***********************************************************************
* DISK.ADS
* This is the package spec; here we define a record that contains the
registers;
* also we declare our custom design interrupt procedure (my_int86) which
has
* three parameters.
* 'pragma Import' import the procedure from the C program.
*
***********************************************************************
with Interfaces; use Interfaces;
with Interfaces.C; use Interfaces.C;
package Disk is
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);
--------------------------------------------------------------
procedure My_Int86(BIOS_number : Unsigned_16; -- from Interfaces.C
Registers_In : in out Dpmi_Regs;
Registers_Out : in out Dpmi_Regs);
pragma Import(C, My_Int86, "ada86");
-- Ada name / C name/
--------------------------------------------------------------
end Disk; (END OF DISK.ADS)
***********************************************************************
* DISKC.C
* This is your interface program.
* You need this C program to be able to use the C libraries.
* After you define your ada interrupt procedure (my_int86)(see disk.ads)
you have to
* import it using (pragma Import). This allow you to create a C procedure
* (void ada86) that can use the predefined machine interrupt 'int86'.
*
***********************************************************************
#include <dos.h>
/* This is a 'wrapper' to the C function that is provided in dos.h */
void ada86 (int num, union REGS *in_regs, union REGS *out_regs)
{
int86 (num, in_regs, out_regs);
}
(END OF DISKC.C)
***********************************************************************
* TEST.ADB
* This is your test procedure. In this example we use INT 21, 36 that
gives
* information about the free space on the disk.
* AX = 36
* DX = 3 that is the C drive (A=1, B=2, C=3, etc.)
*
* the procedure My_Int86(16#21#, Reg_in, Reg_Out) has three parameters;
* you can pass the interrupt number; in this case 21, as the first
parameter
*
*
***********************************************************************
with Interfaces.c;
use Interfaces.c;
with Ada.Text_IO;
use Ada.Text_IO;
with Disk;
use Disk;
procedure Test is
Reg_in, Reg_out : Dpmi_Regs;
The_Buffer : Buffer_Type := (others => 0);
package Int_IO is new Ada.Text_IO.Integer_IO(Integer);
use Int_IO;
begin
Reg_in.Ax := 16#3600#; -- INT 21, 36 Gets Disk Free Space
-- Note Ax covers both AH and AL and so the above assigns 36 to AH
Reg_in.Dx := 16#0003#; -- drive number (1 - 25; A: - Z:)
-- Note Dx covers DH and DL, as above
My_Int86(16#21#, Reg_in, Reg_Out);
Put ("Number Available Of Clusters : ");
Put(Integer(Reg_Out.bx));
new_line;
Put ("Number Of Byte per Sector : ");
Put(Integer(Reg_Out.cx));
new_line;
Put ("Number Of Cluster per Drive : ");
Put(Integer(Reg_Out.dx));
end Test ; (END OF TEST.ADB)
******************************************************************
SUMMARY
a) Create a directory and dump all the files (disk.ads, diskc.c and
test.adb)
b) From dos type the following :
C:\ gcc -c diskc.c -- this compiles the C program to produce an object code
file
-- for subsequent linking
C:\ gnat make test.adb
-- this will compile bind and link the test program
N.B. at this point you will see an error message saying that the link has
failed;
just ignore it and type the following command.
C:\ gnat link test.ali diskc.o -- this is a correct link command
You should now have an executable 'test.exe', just type
C:\ test
and ENJOY !!!
Mike and Laura Palmer
Any problems / queries contact us at :
thepalmers@lineone.net
Chad R. Meiners <v025@academic.truman.edu> wrote in article
<34651851.DAA7064E@academic.truman.edu>...
> Would anyone be able to give me an example on how to call an interrupt
> in Ada. I have tried to sort through the reference manual, and I have
> looked in interrupt packages. I am intending to call the dos interrupt
> 21h, and I am using Gnat 3.10p for NT if that makes a difference.
> Thanks
> -Chad R. Meiners
>
>
next prev parent reply other threads:[~1997-11-10 0:00 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
1997-11-08 0:00 Interrupt Calls Chad R. Meiners
1997-11-10 0:00 ` Laura & Mike Palmer [this message]
1997-11-11 0:00 ` Jerry van Dijk
1997-11-12 0:00 ` Jerry van Dijk
[not found] ` <01bcf06a$ba1d1900$933e63c3@default>
1997-11-21 0:00 ` Chad R. Meiners
1997-11-21 0:00 ` Larry Coon
1997-11-22 0:00 ` Jerry van Dijk
1997-11-10 0:00 ` Jerry van Dijk
1997-11-11 0:00 ` Chad R. Meiners
1997-11-12 0:00 ` Jerry van Dijk
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox