c++.dos.32-bits - Accessing VRAM directly
- Javier Gutiérrez (5/5) Aug 28 2001 How can I access the VRAM directly under a DOSX DMC program. The PDF
- Walter (2/7) Aug 28 2001
- Roland (172/177) Aug 30 2001 use _dosptr_toptr macro below
- Javier Gutiérrez (12/190) Aug 31 2001 Thank you very much Roland for your sample code, I think I got the i...
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
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
"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
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









"Walter" <walter digitalmars.com> 