From: "A.Appleyard" To: djgpp AT sun DOT soe DOT clarkson DOT edu Date: Fri, 7 Apr 1995 10:15:42 BST Subject: Re: DPMI-safe screen access Chris Tate wrote (Subject: DPMI-safe screen access):- > Just how would I go about expressing a text-screen blit as either a > dosmemput() to the right place, or something using the routines, > or some other such approach that works under DPMI? I had this problem when adapting a Gnu C++ program to DPMI, and I wrote these C++ classes. Variables of type `c_byte' and `c_short' are used roughly the same as ordinary unsigned char and short, but are in conventional memory. Conventional memory addresses are types c_byte_addr and c_short_addr, not c_byte* and c_short*. To get the conventional memory address of a conventional memory variable, use the .addr() function, not `&' (I found that redefining `operator&' causes strange side effects). My `*' operator looks up the conventional memory value which is at a conventional memory address. To get the unsigned char value of a c_byte, or the short int value of a c_short, you may have to convert explicitly with the .val() function. The functions .Char() and .color() are the two bytes of a text screen character position. I only put in those arithmetic functions that I needed in that program: likely any others needed could be provided by analogy of those here. c_byte and c_short are declared only by their absolute addresses, e.g. c_short_addr screen(0xb8000); c_short_addr graphicalscreen(0xa0000); give C++ variable names to the (color) text and graphical screens. To set up your own conventional memory space, declare e.g. c_mem Dustbin(512); c_short_addr dustbin(Dustbin); /* 256 shorts */ /*-----*/ #include #include #include /*-----*/ #define uns unsigned #define reg register typedef uns char byte; /*-----*//* 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 ~c_mem(){_go32_dpmi_free_dos_memory(&x);};}; /* typedef struct { u_long size, pm_offset; u_short pm_selector, rm_offset, rm_segment; } _go32_dpmi_seginfo; */ /*-----*/ class c_byte_addr; class c_short_addr; /*-----*/ class c_byte {public: uns int addr; inline c_byte_addr&adr(); inline char val(){char c; dosmemget(addr,1,&c); return c;}; inline void operator=(char c){dosmemput(&c,1,addr);}; inline char(){char c; dosmemget(addr,1,&c); return c;};}; /*-----*/ class c_byte_addr {public: uns int addr; inline c_byte_addr(uns int Addr=0){addr=Addr;}; inline c_byte_addr(uns short Seg,uns short Offset){addr=Seg*16+Offset;}; inline c_byte_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_byte_addr&c_byte::adr(){return*(c_byte_addr*)this;} /*-----*/ class c_short {public: uns int addr; inline short(){short c; dosmemget(addr,2,&c); return c;}; inline short val(){short c; dosmemget(addr,2,&c); return c;}; inline c_short_addr&adr(); inline uns short operator=(short c){dosmemput(&c,2,addr); 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(){return *c_byte_addr(addr+1);};}; /*-----*/ class c_short_addr {public: uns int addr; inline c_short_addr(uns int Addr=0){addr=Addr;}; inline c_short_addr(c_mem m){addr=m.x.rm_segment*16+m.x.rm_offset;}; inline c_short_addr(uns short Seg,uns short Offset){addr=Seg*16+Offset;}; inline c_short_addr operator+(int i){c_short_addr x; x.addr=addr+2*i;return x;}; inline c_short_addr operator-(int i){c_short_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){dosmemput(&i,2,addr); addr+=2;}; inline void operator=(c_short_addr p){addr=p.addr;}; inline int operator-(c_short_addr x){return (addr-x.addr)/2;}; inline int operator>=(c_short_addr p){return addr>=p.addr;}; inline int operator< (c_short_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;};}; /*-----*/ extern void newcolor(c_short_addr x,int from,int to,char c); inline c_short_addr&c_short::adr(){return*(c_short_addr*)this;} inline void c_put(c_short_addr x,short*y,int n){dosmemput(y,n*2,x.addr);}; inline void c_get(short*y,c_short_addr x,int n){dosmemget(x.addr,n*2,y);}; extern void c_put_color(c_short_addr x,char*y,int n,byte color); /*-----*/ /*-----*/ void c_put_color(c_short_addr x,char*y,int n,byte color){if(n<0) n=strlen(y); int i; short s[n]; for(i=0;ito?:from<0) return; short s[to-from]; int i; uns short j; c_get(s,x+from,to-from); for(i=from;i>8)!=Red) s[i-from]=(j&255)+(c<<8);} c_put(x+from,s,to-from);}