www.digitalmars.com         C & C++   DMDScript  

c++.dos.32-bits - Accessing VRAM directly

reply "Javier Gutiérrez" <nikkho hotmail.com> writes:
    How can I access the VRAM directly under a DOSX DMC program. The PDF
only explain it using assembler.

    In real mode it was easy, only create a pointer as:

    unsigned char far *pVram=MK_FP(0xA000, 0x0000);

    How can I do it in protected mode?
Aug 28 2001
next sibling parent "Walter" <walter digitalmars.com> writes:
The inline assembler ought to do the trick. -Walter

Javier Gutiérrez wrote in message <9mgsmq$1lhk$1 digitaldaemon.com>...
    How can I access the VRAM directly under a DOSX DMC program. The PDF
only explain it using assembler.

    In real mode it was easy, only create a pointer as:

    unsigned char far *pVram=MK_FP(0xA000, 0x0000);

    How can I do it in protected mode?
Aug 28 2001
prev sibling parent reply Roland <rv ronetech.com> writes:
"Javier Gutiérrez" a écrit :

     How can I access the VRAM directly under a DOSX DMC program. The PDF
 only explain it using assembler.

     In real mode it was easy, only create a pointer as:

     unsigned char far *pVram=MK_FP(0xA000, 0x0000);

     How can I do it in protected mode?
use _dosptr_toptr macro below regards Roland ----------------------------------------------------------------------- here some code to manipulate pointers. compile and run for 16 bit large model and 32 bit DOSX model as well. comes from code debugged and tested for years. but i had to make some cut and past to make this. i had to translate my comments to english. sorry if it is not sheakspear.. i hope i don't forget anything and it compile like that. let me know if i forgot something //----------------------------------------------------------------------- #if (1==0) written by Roland VARICHON for RONE Technologies 69100 FRANCE //does not hurt #endif #if (sizeof(int)==2) #define __INTSIZE 2 #else #define __INTSIZE 4 #endif #if (__INTSIZE==4) #include <io.h> //getDS #endif //----------------------------------------------------------------------- //some definitions and declaration: #if (__INTSIZE==2) #define dword unsigned long #else #define dword unsigned int #endif #define dosptr dword //real mode far pointer: segment:offset #define dosptr_tooff(ptr) ( ((((unsigned)(ptr))>>12) & ~0xf)+(((unsigned)(ptr)) & 0xffff) ) //transform a dosptr to an offset based on 0000:0000 addresse extern "C" dosptr off_todosptr(const dword s); //transform an offset based on 0000:0000 addresse to a dosptr //see asm code below extern "C" dosptr dosptr_align(const dosptr ptr); //align a dosptr: transform it so that offset <= 0xf //see asm code below extern "C" dosptr dosptr_add(const dosptr ptr, const dword v); //add v to a dosptr, return an aligned dosptr //!! v must be >=0 //see asm code below extern "C" dosptr dosptr_seek(const dosptr ptr, const long v); //same as dosptr_add but v can be <0 //see asm code below //----------------------------------------------------------------------------- //C++ code #if (__INTSIZE==2) #define _dosptr_toptr(ptr) ( ((void*)(ptr)) ) //nop on 16 bit lare model #define _ptr_align(ptr) ( ((void*)dosptr_align((dosptr)(ptr))) ) //align a real mode far pointer: transform it so that offset <= 0xf #define _ptr_add(ptr,v) ( ((void*)dosptr_add((dosptr)(ptr),v)) ) //add an offset to a real mode far pointer, return an aligned real mode far pointer //!! v must be >=0 #define _ptr_seek(ptr,v) ( ((void*)dosptr_seek((dosptr)(ptr),v)) ) //same as _ptr_add but v can be <0 #else //__INTSIZE==4 //#include <dos.h> //_x386_get_abs_addresse //commented here because in a SC++ version, if included here it didn't compile, i don't know why #define DGROUP MK_FP(getDS(),0) #define _offtoptr(off) ( ((void*)(-_x386_get_abs_address(DGROUP)+off)) ) //transform an offset based on 0000:0000 addresse to a DOSX near pointer #define _dosptr_toptr(ptr) ( ((void*)(-_x386_get_abs_address(DGROUP)+dosptr_tooff(ptr))) ) //transform a real mode far pointer to a DOSX near pointer #define _ptr_align(ptr) ( ((void*)(ptr)) ) //nop in DOSX model #define _ptr_add(ptr,v) ( ((void*)(((byte*)(ptr))+((unsigned)(v)))) ) //add an offset to a pointer #define _ptr_seek(ptr,v) ( ((void*)(((byte*)(ptr))+((int)(v)))) ) //same as _ptr_add but v is int #endif //__INTSIZE==2 //----------------------------------------------------------------------------- //ASSEMBLY CODE ; you may have to rewrite the functions as i can't give you all the macro i wrote for assembly ;it may be enough to be understandable ;just know that all names beginning with ' ' charactere are macros ;extern "C" dword dosptr_tooff(dosptr s); ;// CS PROC _dosptr_tooff,<_dosptr ??s>; enter movzx eax,WORD PTR P.??s movzx edx,WORD PTR P.??s[WORD] shl edx,4 add eax,edx IF (INTG EQ 2) shld edx,eax,16 ENDIF leave ENDP ENDS ;extern "C" dosptr off_todosptr(dword s); ;// CS PROC _off_todosptr,<_dword ??s>; enter mov eax,P.??s mov edx,eax shr edx,4 and _ax,0fh IF (INTG EQ 4) shl eax,16 shrd eax,edx,16 ENDIF leave ENDP ENDS ;extern "C" dosptr dosptr_align(dosptr ptr); ;// CS PROC _dosptr_align,<_dosptr ??ptr>; enter movzx eax,WORD PTR P.??ptr mov edx,eax shr _dx,4 add dx,WORD PTR P.??ptr[WORD] and _ax,0fh IF (INTG EQ 4) shl eax,16 shrd eax,edx,16 ENDIF leave ENDP ENDS ;extern "C" dosptr dosptr_add(dosptr ptr, dword v); ;// CS PROC _dosptr_add,<_dosptr ??ptr, _dword ??v>; enter movzx eax,WORD PTR P.??ptr add eax,P.??v mov edx,eax shr edx,4 add dx,WORD PTR P.??ptr[WORD] and _ax,0fh IF (INTG EQ 4) shl eax,16 shrd eax,edx,16 ENDIF leave ENDP ENDS ;extern "C" dosptr dosptr_seek(dosptr ptr, long_short v); ;// CS PROC _dosptr_seek,<_dosptr ??ptr, _dword ??v>; enter movzx eax,WORD PTR P.??ptr movzx edx,WORD PTR P.??ptr[WORD] shl edx,4 add eax,edx add eax,P.??v mov edx,eax shr edx,4 and _ax,0fh IF (INTG EQ 4) shl eax,16 shrd eax,edx,16 ENDIF leave ENDP ENDS
Aug 30 2001
parent "Javier Gutiérrez" <nikkho hotmail.com> writes:
    Thank you very much Roland for your sample code, I think I got the idea.

    PD: I am not from the Shackespeare's realms, so I understand your
comments qute good.

"Roland" <rv ronetech.com> escribió en el mensaje
news:3B8DF4FF.219FB09F ronetech.com...
 "Javier Gutiérrez" a écrit :

     How can I access the VRAM directly under a DOSX DMC program. The PDF
 only explain it using assembler.

     In real mode it was easy, only create a pointer as:

     unsigned char far *pVram=MK_FP(0xA000, 0x0000);

     How can I do it in protected mode?
use _dosptr_toptr macro below regards Roland ----------------------------------------------------------------------- here some code to manipulate pointers. compile and run for 16 bit large model and 32 bit DOSX model as well. comes from code debugged and tested for years. but i had to make some cut and past to make this. i had to translate my comments to english. sorry if it is not sheakspear.. i hope i don't forget anything and it compile like that. let me know if i forgot something //----------------------------------------------------------------------- #if (1==0) written by Roland VARICHON for RONE Technologies 69100 FRANCE
//does
 not hurt
 #endif

 #if (sizeof(int)==2)
     #define __INTSIZE 2
 #else
     #define __INTSIZE 4
 #endif

 #if (__INTSIZE==4)
     #include <io.h>  //getDS
 #endif

 //-----------------------------------------------------------------------
 //some definitions and declaration:


 #if (__INTSIZE==2)
    #define dword unsigned long
 #else
     #define dword unsigned int
 #endif

 #define dosptr dword        //real mode far pointer: segment:offset

 #define dosptr_tooff(ptr) ( ((((unsigned)(ptr))>>12) &
 ~0xf)+(((unsigned)(ptr)) & 0xffff) )
 //transform a dosptr to an offset based on 0000:0000 addresse

 extern "C" dosptr off_todosptr(const dword s);
 //transform an offset based on 0000:0000 addresse to a dosptr
 //see asm code below

 extern "C" dosptr dosptr_align(const dosptr ptr);
 //align a dosptr: transform it so that offset <= 0xf
 //see asm code below

 extern "C" dosptr dosptr_add(const dosptr ptr, const dword v);
 //add v to a dosptr, return an aligned dosptr
 //!! v must be >=0
 //see asm code below

 extern "C" dosptr dosptr_seek(const dosptr ptr, const long v);
 //same as dosptr_add but v can be <0
 //see asm code below
//-------------------------------------------------------------------------- ---
 //C++ code

 #if (__INTSIZE==2)

 #define _dosptr_toptr(ptr) ( ((void*)(ptr)) )
 //nop on 16 bit lare model

 #define _ptr_align(ptr) ( ((void*)dosptr_align((dosptr)(ptr))) )
 //align a real mode far pointer: transform it so that offset <= 0xf

 #define _ptr_add(ptr,v) ( ((void*)dosptr_add((dosptr)(ptr),v)) )
 //add an offset to a real mode far pointer, return an aligned real mode
far
 pointer
 //!! v must be >=0

 #define _ptr_seek(ptr,v) ( ((void*)dosptr_seek((dosptr)(ptr),v)) )
 //same as _ptr_add but v can be <0

 #else
 //__INTSIZE==4

 //#include <dos.h> //_x386_get_abs_addresse
 //commented here because in a SC++ version, if included here it didn't
 compile, i don't know why

 #define DGROUP MK_FP(getDS(),0)

 #define _offtoptr(off) ( ((void*)(-_x386_get_abs_address(DGROUP)+off)) )
 //transform an offset based on 0000:0000 addresse to a DOSX near pointer

 #define _dosptr_toptr(ptr) (
 ((void*)(-_x386_get_abs_address(DGROUP)+dosptr_tooff(ptr))) )
 //transform a real mode far pointer to a DOSX near pointer

 #define _ptr_align(ptr) ( ((void*)(ptr)) )
 //nop in DOSX model

 #define _ptr_add(ptr,v) ( ((void*)(((byte*)(ptr))+((unsigned)(v)))) )
 //add an offset to a pointer

 #define _ptr_seek(ptr,v) ( ((void*)(((byte*)(ptr))+((int)(v)))) )
 //same as _ptr_add but v is int

 #endif    //__INTSIZE==2
//-------------------------------------------------------------------------- ---
 //ASSEMBLY CODE
 ; you may have to rewrite the functions as i can't give you all the macro
i
 wrote for assembly
 ;it may be enough to be understandable
 ;just know that all names beginning with ' ' charactere are macros

 ;extern "C" dword dosptr_tooff(dosptr s);
 ;//
  CS
  PROC _dosptr_tooff,<_dosptr ??s>;
   enter
  movzx eax,WORD PTR P.??s
  movzx edx,WORD PTR P.??s[WORD]
  shl  edx,4
  add  eax,edx
   IF (INTG EQ 2)
  shld edx,eax,16
   ENDIF
   leave
  ENDP
  ENDS

 ;extern "C" dosptr off_todosptr(dword s);
 ;//
  CS
  PROC _off_todosptr,<_dword ??s>;
   enter
  mov  eax,P.??s
  mov  edx,eax
  shr  edx,4
  and  _ax,0fh
   IF (INTG EQ 4)
  shl  eax,16
  shrd eax,edx,16
   ENDIF
   leave
  ENDP
  ENDS

 ;extern "C" dosptr dosptr_align(dosptr ptr);
 ;//
  CS
  PROC _dosptr_align,<_dosptr ??ptr>;
   enter
  movzx eax,WORD PTR P.??ptr
  mov  edx,eax
  shr  _dx,4
  add  dx,WORD PTR P.??ptr[WORD]
  and  _ax,0fh
   IF (INTG EQ 4)
  shl eax,16
  shrd eax,edx,16
   ENDIF
   leave
  ENDP
  ENDS

 ;extern "C" dosptr dosptr_add(dosptr ptr, dword v);
 ;//
  CS
  PROC _dosptr_add,<_dosptr ??ptr, _dword ??v>;
   enter
  movzx eax,WORD PTR P.??ptr
  add  eax,P.??v
  mov  edx,eax
  shr  edx,4
  add  dx,WORD PTR P.??ptr[WORD]
  and  _ax,0fh
   IF (INTG EQ 4)
  shl eax,16
  shrd eax,edx,16
   ENDIF
   leave
  ENDP
  ENDS

 ;extern "C" dosptr dosptr_seek(dosptr ptr, long_short v);
 ;//
  CS
  PROC _dosptr_seek,<_dosptr ??ptr, _dword ??v>;
   enter
  movzx eax,WORD PTR P.??ptr
  movzx edx,WORD PTR P.??ptr[WORD]
  shl  edx,4
  add  eax,edx
  add  eax,P.??v
  mov  edx,eax
  shr  edx,4
  and  _ax,0fh
   IF (INTG EQ 4)
  shl  eax,16
  shrd eax,edx,16
   ENDIF
   leave
  ENDP
  ENDS
Aug 31 2001