Thread overview
Accessing VRAM directly
Aug 28, 2001
Javier Gutiérrez
Aug 29, 2001
Walter
Aug 30, 2001
Roland
Aug 31, 2001
Javier Gutiérrez
August 28, 2001
    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?


August 29, 2001
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?
>
>


August 30, 2001

"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


August 31, 2001
    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
>
>