From: douglas@cs.scarolina.edu (G. David Douglas Jr.)
Subject: Re: INT in TC2.0
Organization: USC  Department of Computer Science
Date: 22 Jan 93 00:01:34 GMT

ereimber@cipres.cec.uchile.cl (Reimberg Navarro Erich Eduardo) writes:

>Hi.

>>     The main difference is that intr() is using only 1 struct which
>>     contains the registers both before and after the execution of
>>     the interrupt. intr() is unique to Borland while int86 is quite
>>     common among C compiler for DOS.

>   Thank you for your reply. BUt there are some stuff I still can't
>get right. int86 uses a union for both the passed registers and the
>returned ones. I have this as:

>  int86 (int intno, union REGS *inregs, union REGS *outregs)

>  while union REGS is as:

>   union REGS {
>      struct WORDREGS x;   /* Word-sized registers */
>      struct BYTEREGS h;   /* Byte-sized registers */
>   }
>   struct BYTREGS contains registers al, ah, bl, bh, cl, ch, dl, dh;
>   and struct WORDREGS, ax, bx, cx, dx, si, di, cflag, flags;

>  There are some INT calls, that return pointers in the form DS:BX. And
>I don't have any DS register in either WORDREGS or BYTEREGS.
>There's another struct called REGPACK that does have the DS register
>in the form      
>   unsigned r_ds;      but it has no ah, al, bh, ....

** You could get ah from (r_ax >> 16), and al from
** (r_ax & 0xFF), where r_ax IS an element of the REGPACK structure, since
** the AX register's high-half is known as AH and its low-half is known
** as AL.  Storing a value, say  x,  in AH and another value, say  y,
** in AL, could be done (assuming x and y are both in the range
** 0 through 255) with  ((x << 16) | y)

>The fact is that I'm trying to execute INT 0x21 with AL=0x1c. INT 0x21
>returns a pointer in the form DS:BX. Here I use both AL, and DS registers,
>but I can't figure out how can I handle both registers with only
>one call. (?)

>                             -ern

>--
>PS: I could not reply via e-mail.

Well, I'm currently (still?) using TC 1.5, doing something similar to
what you want to do:  use INT 0x21, but with AH=0x52.
The following code fragment should help clear up any misunderstandings
on using the  intr  command  .  (I'm loading a value into the AH
pseudo-register by specifying the (bigger) value for the entire AX
register, with 0x00 as the value stored in the AL pseudo-register).



        struct REGPACK    cpu_registers;
        unsigned int      *word_pointer;

   ...

        /*
         *  Prefix string setup is now done.
         *
         *  Issue a PC-DOS service number 52h call to retrieve the
         *  segment and offset of the last location "officially"
         *  occupied by DOS.  Segment will be contained in the ES
         *  pseudo-register, offset in the BX pseudo-register.  Subtract
         *  2 from BX to get offset of the 2 bytes containing segment number
         *  of the first Memory Control Block (MCB).
         */

        cpu_registers.r_ax = 0x5200;  /* AH register <- 0x52,          */
                                      /* AL register <- 0x00           */

        intr(0x21, &cpu_registers);

        cpu_registers.r_bx -= 2;

        /*
         *  Load segment and offset into pointer variable -- r_es and
         *  r_bx pseudo_registers (as well as actual registers ES and
         *  BX) are 16 bits in width, so shift ES component left 16
         *  bits before including the offset contained in BX.
         */

        word_pointer = (unsigned int *)(((long)cpu_registers.r_es << 16) |
                                         (long)cpu_registers.r_bx);



Hope this helps!


David Douglas
douglas@usceast.cs.scarolina.edu