Mail Archives: djgpp/1996/05/22/04:30:03
Bryanston School <MOLESWORTH DOT THOMAS AT bryanston DOT co DOT uk> wrote (Subject:
Acessing DPMI memory without farptr):-
> Is there a way to access memory allocated through the __dpmi functions
> through pointers? I would prefer to access it directly, rather than using
> things like _farpeekb and so on ...
I wrote these C++ classes declaring char and short type values in conventional
memory. They work OK for me in version 1: what needs changing in version 2?
The only differences from the usual * & [] etc notation in using them are:-
If X is a conv.memory byte or short, its address is `X.adr()', not `&X'
Declare an array in conv.mem as e.g. `c_b_array A(6);' not `c_byte A[6]'
#include <dpmi.h>
#include <go32.h> /* needed to declare _go32_dpmi_seginfo */
/*-----*/
#define uns unsigned
#define reg register
#define pk __attribute__((packed))
typedef uns long ul;
typedef uns short us;
typedef uns char byte;
/*-----*/
#define SEL _go32_info_block.selector_for_linear_memory
#define TBaddr _go32_info_block.linear_address_of_transfer_buffer
#define segoff(x,y,z) ((x)=(z)>>4,(y)=(z)&15)
inline void _farpokeb(uns short selector, uns long offset, uns char value) {
asm("movw %0,%%fs" : : "r" (selector));
asm(".byte 0x64\n" " movb %0,(%1)" : : "r" ((uns char)value), "r" (offset));}
inline void _farpokew(uns short selector, uns long offset, uns short value) {
asm("movw %0,%%fs" : : "r" (selector));
asm(".byte 0x64\n" " movw %0,(%1)" : : "r" (value), "r" (offset));}
inline void _farpokel(uns short selector, uns long offset, uns long value) {
asm("movw %0,%%fs" : : "r" (selector));
asm(".byte 0x64\n" " movl %0,(%1)" : : "r" (value), "r" (offset));}
inline uns char _farpeekb(uns short selector, uns long offset) {uns char R;
asm("movw %0,%%fs" : : "r" (selector));
asm(".byte 0x64\n" " movb (%1),%0" : "=r" ((int)R) : "r" (offset)); return R;}
inline uns short _farpeekw(uns short selector, uns long offset) {uns short R;
asm("movw %0,%%fs" : : "r" (selector));
asm(".byte 0x64\n" " movw (%1),%0" : "=r" (R) : "r" (offset)); return R;}
inline uns long _farpeekl(uns short selector, uns long offset) {uns long R;
asm("movw %0,%%fs" : : "r" (selector));
asm(".byte 0x64\n" " movl (%1),%0" : "=r" (R) : "r" (offset)); return R;}
/*-----*//* E.g. `c_mem X(76);' declares 76 bytes of conventional memory */
class c_mem {public: _go32_dpmi_seginfo x;
inline c_mem(int nbytes){x.size=nbytes; _go32_dpmi_allocate_dos_memory(&x);};
inline segof(uns short&s,uns short&o){s=x.rm_segment; o=x.rm_offset;};
inline ~c_mem(){_go32_dpmi_free_dos_memory(&x);};};
/* typedef struct {uns long size, pm_offset;
uns short pm_selector, rm_offset, rm_segment;} _go32_dpmi_seginfo; */;
/*-----*/
class c_b_addr; class c_s_addr;
/*-----*/
class c_byte {public: uns int addr;
inline c_b_addr&adr();
inline operator char(){return _farpeekb(SEL,addr);};
inline val(){return _farpeekb(SEL,addr);};
inline char operator=(char c){_farpokeb(SEL,addr,c); return c;};};
/*-----*//* E.g. `c_b_addr Y;' is like `char*Y;' but points to conv. memory */
class c_b_addr {public: uns int addr;
inline c_b_addr(uns int Addr=0){addr=Addr;};
inline c_b_addr(uns short Seg,uns short Offset){addr=Seg*16+Offset;};
inline c_b_addr(c_mem&m){addr=m.x.rm_segment*16+m.x.rm_offset;};
inline c_byte operator*(){return*(c_byte*)this;};
inline c_byte operator[](int i){c_byte x; x.addr=addr+i; return x;};};
/*-----*/
inline c_b_addr&c_byte::adr(){return*(c_b_addr*)this;}
/*-----*/
class c_short {public: uns int addr;
inline operator short(){return _farpeekw(SEL,addr);};
inline val(){return _farpeekw(SEL,addr);};
inline c_s_addr&adr();
inline uns short operator=(short c){_farpokew(SEL,addr,c); return c;};
inline void operator+=(int c){*this=(*this).val()+c;};
inline void operator&=(int c){*this=(*this).val()&c;};
inline c_byte Char(){return*(c_byte*)this;}
inline c_byte color/*of text mode screen char*/(){return *c_b_addr(addr+1);};};
/*-----*//* E.g. `c_b_array A(6);' is like `char A[6]' but in conv.memory */
class c_b_array:public c_b_addr{public: c_mem m;
c_b_array(int n): m(n){addr=m.x.rm_segment*16+m.x.rm_offset;};};
/*-----*//* E.g. `c_s_addr Z;' is like `short*Z;' but points to conv. memory */
class c_s_addr {public: uns int addr;
inline c_s_addr(uns int Addr=0){addr=Addr;};
inline c_s_addr(c_mem&m){addr=m.x.rm_segment*16+m.x.rm_offset;};
inline c_s_addr(uns short Seg,uns short Offset){addr=Seg*16+Offset;};
inline c_s_addr operator+(int i){c_s_addr x; x.addr=addr+2*i;return x;};
inline c_s_addr operator-(int i){c_s_addr x; x.addr=addr-2*i;return x;};
inline void operator+=(int i){addr+=2*i;};
inline void operator++(){addr+=2;};
inline c_short push(int i){_farpokew(SEL,addr,i); addr+=2;};
inline void operator=(c_s_addr p){addr=p.addr;};
inline int operator-(c_s_addr x){return (addr-x.addr)/2;};
inline int operator>=(c_s_addr p){return addr>=p.addr;};
inline int operator< (c_s_addr p){return addr< p.addr;};
inline c_short operator*(){return*(c_short*)this;};
inline c_short operator[](int i){c_short x; x.addr=addr+2*i; return x;};};
/*-----*/
class c_s_array:public c_s_addr{public: c_mem m;
c_s_array(int n): m(n){addr=m.x.rm_segment*16+m.x.rm_offset;};};
/*-----*/
inline c_s_addr&c_short::adr(){return*(c_s_addr*)this;}
inline void c_put(c_s_addr x,short*y,int n){dosmemput(y,n*2,x.addr);};
inline void c_get(short*y,c_s_addr x,int n){dosmemget(x.addr,n*2,y);};
/*-----*/
- Raw text -