From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: *** X-Spam-Status: No, score=3.2 required=5.0 tests=BAYES_00,RATWARE_MS_HASH, RATWARE_OUTLOOK_NONAME autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,e9b3af563ee9322a X-Google-Attributes: gid103376,public From: "Laura & Mike Palmer" Subject: Re: Interrupt Calls Date: 1997/11/10 Message-ID: <01bcee03$8908d020$cd3663c3@default> X-Deja-AN: 288952885 References: <34651851.DAA7064E@academic.truman.edu> Organization: British Telecom Newsgroups: comp.lang.ada Date: 1997-11-10T00:00:00+00:00 List-Id: 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 /* 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 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 > >