www.digitalmars.com         C & C++   DMDScript  

c++.dos.32-bits - Load Pointer via subroutine into ES:BX for an software Interript

reply Nils Koehler <nils.koehler ibt-interfaces.de> writes:
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&#8217;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 21 2007
parent reply Heinz Saathoff <newshsaat arcor.de> writes:
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 22 2007
next sibling parent Nils Koehler <nils.koehler ibt-interfaces.de> writes:
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
prev sibling parent reply Nils Koehler <nils.koehler ibt-interfaces.de> writes:
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 23 2007
parent Heinz Saathoff <newshsaat arcor.de> writes:
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
May 25 2007