Qbasicnews.com

Full Version: C/C++ Pointer Question...
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
How do I put 0xa000:0000 into a pointer?

ie.

Code:
char *screen;

This won't work:

Code:
screen = 0xa000+0000;
Or let's say I can put a dword val of the same hex value into
DX:AX, how do I return it to C inside the ASM statement?


Code:
long returnscreen()
{
       asm{
        xor ax, ax
        mov dx, a000h
        }
    //how would I "return" dx:ax
}
If you're using Borland Turbo C, you can use the MK_FP macro. (You have to include dos.h for that.)
Code:
char far *screen;

screen = MK_FP(0xA000, 0);
If you're using an other compiler, you might do that by putting 0xA0000000 in a far pointer, but I don't really know.

And about returning a long: it should work the way you do it. The compiler will give a warning though. I just tested this in my Turbo C:
Code:
long retlong()
{
        asm mov dx, 1;
        asm mov ax, 0x86A0;
}

int main()
{
        printf("%lu\n", retlong());
        return(0);
}
And it correctly prints 100000 (=0x186A0).
Quote:Or let's say I can put a dword val of the same hex value into
DX:AX, how do I return it to C inside the ASM statement?
AFAIK, in C++ (MSVS) you could do this:

Code:
void dosomething (void)
{
   char myvalue = 0;
   _asm {
      mov ax, 0A000h
      mov es, ax
      xor ax, ax
      mov dx, 0

      mov myvalue, es:[dx]
   }
}
Neo and MMSPP: Thanks.

I just tried(last night) MK_FP and TurboC++ ver 1.01 gives me a warning. Plus I don't have a "malloc.h" only "alloc.h" so no fmemset, fmemcpy or farmalloc for me. :*(*
Quote:How do I put 0xa000:0000 into a pointer?

ie.

Code:
char *screen;

This won't work:

Code:
screen = 0xa000+0000;

Rel...dare I ask...what are you trying to do? It seems pretty unusual to need to assign a numeric literal constant to a pointer. What do you have stored at that location, and how did it get there? Seems that you could take whatever's at that location and cast it's address to a char*, and assign the result to screen. This might be a more straightforward way.
eg:
screen = (char*) &whateverisat0xa0000000;

However...I've seen your work and don't doubt you have strange and myserious reasons for wanting to do thisSmile . But...I somehow get the idea that you are stuck in an asm mindset, and not really understanding the capabilities of c. Also...why are you using an old compiler rather than, eg a recent gcc compiler (correct me if I'm wrong here)?

Please...don't take this as criticism...you are a much better programmer than I am...I have great respect for your skills. I just wonder if you there might be a simple way to do what you want.
Quote:Neo and MMSPP: Thanks.
I just tried(last night) MK_FP and TurboC++ ver 1.01 gives me a warning. Plus I don't have a "malloc.h" only "alloc.h" so no fmemset, fmemcpy or farmalloc for me. :*(*
I just dl'ed TC++ 1.01 and checked, you have farmalloc and farfree (declared in ALLOC.H), but no fmemset, fmemcpy etc. You could either write them yourself or download a later version of TC++ like 3.0 that they got here:
http://www.upseros.net/compiladores/compiladores.php

This seems to work (in TC++ 1.01), as it copies the garbage from uninitialized backbuf to the screen. (But I had to copy TASM.EXE to TC's BIN directory.)
Code:
#include <dos.h>
#include <alloc.h>

char far *screen, far *backbuf;

void scrnmode(int mode)
{
    _AX = mode;
    asm int 0x10;
}

int getkey()
{
    _AX = 0;
    asm int 0x16;
}

void myfmemcpy(void far *dest, void far *src, unsigned int nbytes)
{
    asm push ds;
    _DS = FP_SEG(src);
    _SI = FP_OFF(src);
    _ES = FP_SEG(dest);
    _DI = FP_OFF(dest);
    _CX = nbytes;
myfmemcpy0:
asm{
    lodsb
    stosb
    loop  myfmemcpy0
    pop   ds
}
}

int main()
{
    screen = (char far*)MK_FP(0xA000, 0);
    backbuf = (char far*)farmalloc(64000);
    scrnmode(0x13);

    myfmemcpy(screen, backbuf, 64000);

    getkey();
    scrnmode(3);
    farfree(backbuf);
    return(0);
}

@Mango: A000:0000 is the location of the visible display memory in mode 13h.
Rel, I just reread you message Wink

Quote:ie.

Code:
char *screen;

This won't work:

Maybe you should try it like this:
[syntax="C"]screen = 0xA000000;[/syntax]
In C(++) the offsets and segments are just one int (32 bit). Under Windows, doing:
[syntax="C"]printf("%c\n", *screen);[/syntax]probably won't work and you'll get an error indicating you passed outside your programs memory boundaries (yes, you can only change your program's own memory). In Windows, you can use the WinAPI for accessing memory your program doesn't own. In DOS, I guess it won't be any problem (I guess) Smile
Mango: Yep, that would be a better idea. I am helping some Comp Sci students pass their C class. :*) And considering I have like 6 man-hours experience in C... Big Grin . But yeah, I already made one group pass by making them a plasma and a starfield. I would like to do double buffering though. :*)

MMSPP: thanks for the link and the examples!!! BTW what does this mean?
screen = (char far*)MK_FP(0xA000, 0);
casting by char far pointer?

And this should theoritically work right?

Code:
les di, screen
lds si, page
mov cx, 32000
rep movsw

so you could assign a reg like this:
_AX = Blah

Instead of :

mov ax, blah?

Cool!!!


Neo: so declaring a pointer of char type like this is invalid?

char *screen;

then
screen = MK_FP(0xa000,0);


anyways, would this work?

*(screen + (y<<6) + (y<<8) +x) = c;

c would be a char.

Or would this be better?

screen [(y<<6) + (y<<8) +x] = c;


Thanks for the reply folks. I haven't read much C so it's partly my fault. :*)
Quote:BTW what does this mean?
screen = (char far*)MK_FP(0xA000, 0);
casting by char far pointer?
Yup, it's a cast to char far*.
So here are some proggies:
1 and 2 works seamlessly as I didn't use a D buffer and it seems pointer to screen works. But 3 just bombs. Why?
I even used mostly C only code.

The ones with //?????? seems to be the problem in #3.



#1
Code:
#include  <stdio.h>
#include  <conio.h>
#include  <dos.h>
#include  <stdlib.h>
#include  <math.h>

void setscreen13(void);
void writergb(char cindex, char r, char g, char b);



void main()
{
      int x, y;
      int c, i;
      char red, green, blue;
      int short counter;
      int rot, xoffs, yoffs;
      char far *screen;
      char far *pixel_ptr;
      int sin1[2048];
      int sin2[2048];
      int sin3[2048];
      screen = (char far*) 0xa0000000;
      for (i=0; i<2048;i++)
          {
            sin1[i] = sin((float)(i)/64)*256;
            sin2[i] = sin((float)(i)/16)*28;
            sin3[i] = sin((float)(i)/64)*64;
          }


      setscreen13();

          for (i=0; i<256;i++)
          {
           red = 32 - 31 * sin((float) i * 3.141593 /32);
           green = 32 - 31 * sin((float) i * 3.141593 /64);
           blue = 32 - 31 * sin((float) i * 3.141593 /28);

           writergb(i, red, green, blue);
          }
          counter = 0;
          rot = 0;
          xoffs = 0;
          yoffs = 0;


      do
      {
          counter++;
        rot = 128 * (((counter && 1) == 1) || 1);
        pixel_ptr = screen;
        for (y =0; y<200; y++)
        {

              for (x =0; x<319; x++)
                  {
                  rot = -rot;
                c = sin1[(128+x+rot)&2047] + sin3[(y)&2047]+ sin2[(counter+x+y)&2047] + sin1[(x+y)&1023];
                *(pixel_ptr) = (char)c;
                pixel_ptr++;
                }
                pixel_ptr++;
        }
      } while(!kbhit());

}


void setscreen13(void)
{
     asm mov ax, 0013h
     asm int 10h
}

void writergb(char cindex, char r, char g, char b)
{
   asm mov  dx, 03c8h
   asm mov  al, cindex
   asm out  dx, al
   asm inc  dx
   asm mov  al, r
   asm out  dx, al
   asm mov  al, g
   asm out  dx, al
   asm mov  al, b
   asm out  dx, al
}


#2

Code:
/*This works!!!*/

#include  <stdio.h>
#include  <conio.h>
#include  <dos.h>
#include  <stdlib.h>
#include  <math.h>
#include  <time.h>
#include  <alloc.h>
#include  <string.h>


void xsetscreen13(void);
void xputpixel(char far *layer, int x, int y, char c);
void xwritergb(char cindex, char r, char g, char b);
void pcopy(char far *dest, char far *source);
void xwait();
void xcls(char far *dest, unsigned char c);



struct startype
      {
           float x;
           float y;
           float z;
           float zvel;
      };



void main()
{
      int x, y;
      int i;
      char clr;
      int distance;
      char red, green, blue;
      char far  *vpage;
      char far  *screen;
      float sx, sy, sz;
      struct startype stars[301];
      vpage = (char far*)malloc(64000);
      screen = (char far*)0xa0000000;


      randomize();
      xsetscreen13();
      for (i=0; i<256; i++)
          {
              red = i/4;
              green= i/4;
              blue = i/4;
            xwritergb((char)i, red,green,blue);
          }

      for (i=0; i<301; i++)
          {
                  stars[i].x = -60 + rand() % 120;
                stars[i].y = -60 + rand() % 120;
                stars[i].z = (rand()) % 255;
                stars[i].zvel = 1 + rand() % 2;

          }


      sx = 0;
      sy = 0;
      sz = 0;
      distance = 0;

    do
    {
      //xcls(vpage, 0);
      //erase loop
          for (i=0; i<301; i++)
          {
            sx = stars[i].x;
            sy = stars[i].y;
            sz = stars[i].z;
            distance = (256 - sz);
            if (distance > 0)
               {
                      x = 160 + (256 * sx / distance);
                      y = 100 - (256 * sy / distance);
               }
            clr = 0;
            xputpixel (screen, x, y, clr);
          }


      for (i=0; i<301; i++)
          {

            stars[i].z = stars[i].z + stars[i].zvel;
            if (stars[i].z > 255)
                stars[i].z = 0;

            sx = stars[i].x;
            sy = stars[i].y;
            sz = stars[i].z;
            distance = (256 - sz);
            if (distance > 0)
               {
                      x = 160 + (256 * sx / distance);
                      y = 100 - (256 * sy / distance);
               }
            clr = (char)sz & 255;
            xputpixel (screen, x, y, clr);
          }
          xwait();
         //pcopy(screen, vpage);
    }while(!kbhit());
    free(vpage);
}

void xsetscreen13(void)
{
asm{
     mov ax, 0013h
     int 10h
    }
}

void xputpixel(char far *layer, int x, int y, char c)
{

   if ((x>=0) && (x<320) && (y>=0) && (y<200))
    layer[(y<<8) + (y<<6) + x] = c;

}

void xwritergb(char cindex, char r, char g, char b)
{
   asm {
            mov  dx, 03c8h
         mov  al, cindex
         out  dx, al
         inc  dx
         mov  al, r
         out  dx, al
         mov  al, g
         out  dx, al
         mov  al, b
         out  dx, al
       }
}

void xwait()
{
   while (inportb(0x3da) & 0x08);
   while (!(inportb(0x3da) & 0x08));
}

void pcopy(char far *dest, char far  *source)
{
    memcpy(dest,source, 64000);
}


void xcls(char far *dest, unsigned char c)
{
    memset(dest, c, 64000);
}

#3: This won't work

Code:
/* This bombs!!! Uses a dbuffer(suppossedly)*/

#include  <stdio.h>
#include  <conio.h>
#include  <dos.h>
#include  <stdlib.h>
#include  <math.h>
#include  <time.h>
#include  <alloc.h>
#include  <string.h>


void xsetscreen13(void);
void xputpixel(char far *layer, int x, int y, char c);
void xwritergb(char cindex, char r, char g, char b);
void pcopy(char far *dest, char far *source);
void xwait();
void xcls(char far *dest, unsigned char c);



struct startype
      {
           float x;
           float y;
           float z;
           float zvel;
      };



void main()
{
      int x, y;
      int i;
      char clr;
      int distance;
      char red, green, blue;
      char far  *vpage;
      char far  *screen;
      float sx, sy, sz;
      struct startype stars[301];
      vpage = (char far*)malloc(64000);
      screen = (char far*)0xa0000000;


      randomize();
      xsetscreen13();
      for (i=0; i<256; i++)
          {
              red = i/4;
              green= i/4;
              blue = i/4;
            xwritergb((char)i, red,green,blue);
          }

      for (i=0; i<301; i++)
          {
                  stars[i].x = -60 + rand() % 120;
                stars[i].y = -60 + rand() % 120;
                stars[i].z = (rand()) % 255;
                stars[i].zvel = .1 + rand() % 2;

          }


      sx = 0;
      sy = 0;
      sz = 0;
      distance = 0;

    do
    {
      xcls(vpage, 0);  //???????
      for (i=0; i<301; i++)
          {

            stars[i].z = stars[i].z + stars[i].zvel;
            if (stars[i].z > 255)
                stars[i].z = 0;

            sx = stars[i].x;
            sy = stars[i].y;
            sz = stars[i].z;
            distance = (256 - sz);
            if (distance > 0)
               {
                      x = 160 + (256 * sx / distance);
                      y = 100 - (256 * sy / distance);
               }
            clr = (char)sz & 255;
            xputpixel (vpage, x, y, clr);  //???????
          }
          xwait();
         pcopy(screen, vpage);  //???????
    }while(!kbhit());
    free(vpage);
}

void xsetscreen13(void)
{
asm{
     mov ax, 0013h
     int 10h
    }
}

void xputpixel(char far *layer, int x, int y, char c)
{

   if ((x>=0) && (x<320) && (y>=0) && (y<200))
    layer[(y<<8)+(y<<6)+x] = c;

}

void xwritergb(char cindex, char r, char g, char b)
{
   asm {
            mov  dx, 03c8h
         mov  al, cindex
         out  dx, al
         inc  dx
         mov  al, r
         out  dx, al
         mov  al, g
         out  dx, al
         mov  al, b
         out  dx, al
       }
}

void xwait()
{
   while (inportb(0x3da) & 0x08);
   while (!(inportb(0x3da) & 0x08));
}

void pcopy(char far *dest, char far  *source)
{
    memcpy(dest,source, 64000);
}


void xcls(char far *dest, unsigned char c)
{
    memset(dest, c, 64000);
}
Pages: 1 2