Thread overview
Load Pointer via subroutine into ES:BX for an software Interript
May 21, 2007
Nils Koehler
May 22, 2007
Heinz Saathoff
May 23, 2007
Nils Koehler
May 23, 2007
Nils Koehler
May 25, 2007
Heinz Saathoff
May 21, 2007
Hello,

I have a problem to place a pointer in the ES:BX register. I goggled a lot and tried different ways but I can get it not to work... The code is for reading bios ID Information from a Kontron CPU.

I Perini the pointer buffer to "Test". Through the subroutine call the bios should change the "Test" information in something else like "D201". But it won’t work. What can be wrong?

I put my minimum code example at the end of this massage.

May be one can help me to get out of this pointer problem


Kindest Regards

Nils Koehler


// Main
void main(void)
{
  char __far * bios_pointer = "Test";

  ReadID(bios_pointer);
  printf("BIOS ID=%c%c%c%c\n",(char *)*(bios_pointer+0),
                              (char *)*(bios_pointer+1),
                              (char *)*(bios_pointer+2),
                              (char *)*(bios_pointer+3));
}

// Subroutine
int ReadID(char __far* id_pointer)
{
        myregs.x.ax=0xEA01;  // Bios call int 15 Get BIOS ID
        myregs.x.dx=0x4648;  // Must be 0x4648
        myregs.h.cl=1;       // Board Number  3=Error

	myseg.es  = _FP_SEG(id_pointer);   // es:bx to Buffer
	myregs.x.bx = _FP_OFF(id_pointer); // id_pointer.

        int86x(JIDAINT,&myregs,&myregs,&myseg); // IRQ call
       	return(0);
}
May 22, 2007
Hello,

Nils Koehler wrote ...
> I have a problem to place a pointer in the ES:BX register. I goggled a lot and tried different ways but I can get it not to work... The code is for reading bios ID Information from a Kontron CPU.

First, do you use the DOSX 32-bit extender or do you compile in 16-bit
real mode?
In DOSX you can't address physical memory directly via ES:EBX.


> I Perini the pointer buffer to "Test". Through the subroutine call the bios should change the "Test" information in something else like "D201". But it won't work. What can be wrong?

In DOSX bios calls are a bit complicated because there is a change from 32-bit protected mode to 16-bit real mode. The full version of the DOSX extender (see http://www.dosextender.com/) has some support functions to do it but it's still complicated.


- Heinz
May 23, 2007
Hello Heinz,

Thank you for your answer. Yes I use DOSX 32-Bit extender.
I have really no idea how to solve the problem, do you know an
example code where i can look how to work?

Nils
May 23, 2007
Hello Heinz,

I found an examplecode to read some vesa information in the dosextender example directory, is this may be the right way to get my pointer problem solved?


Nils




#include <stdio.h>  /* For fputs() and fputc(). */
#include <dos.h>    /* For int86x_real(). */
#include <string.h> /* For memset(). */

#include "x32.h"

unsigned int get_vesa_info();

int main()
{
  unsigned int vesa_real_p = get_vesa_info();

  if(vesa_real_p)
  {
    char *vesa_p = _x32_real_to_protected(vesa_real_p);
    unsigned int real_mode_oem_p = *(unsigned int *)(vesa_p + 6);
    char *oem_p = _x32_real_to_protected(real_mode_oem_p);

    printf("VESA OEM name = '%s'\n",oem_p);

    _x32_real_free(vesa_real_p);
  }
  return 0;
}

/*******************************************************************
*********
Returns a real mode pointer to a 256 byte block of memory that
contains the
VESA info. This block of memory was allocated useing _x32_real_alloc
() and
must be freed with _x32_real_free().  If return value is 0, the
call failed.
November 29, 1993
********************************************************************
********/
unsigned int get_vesa_info(void)
{
  unsigned int real_ptr = _x32_real_alloc(256);

  if(real_ptr)
  {
    union _REGS reg;
    struct _SREGS seg;

    memset(&reg,0,sizeof(reg)); /* Just to initialize to known
values. */
    memset(&seg,0,sizeof(seg));

    reg.x.ax = 0x4f00;
    reg.x.bx = 0;
    reg.x.di = _x32_real_offset(real_ptr);
    seg.es = _x32_real_segment(real_ptr);
    int86x_real(0x10,&reg,&reg,&seg);

    if(reg.x.ax != 0x4f)  /* Did call succeed? */
    {
      _x32_real_free(real_ptr); /* Call failed -- return failure
result. */
      real_ptr = 0;
    }
  }

  return real_ptr;
}


May 25, 2007
Hello Nils,


Nils Koehler wrote...
> Hello Heinz,
> 
> I found an examplecode to read some vesa information in the dosextender example directory, is this may be the right way to get my pointer problem solved?
> 
> [snip code]

Yes, this example looks right. They use a special memory area that's
allocated the real-mode accessable area.
As I told, it's a little bit complicated but possible ;-)


- Heinz