www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/04/07/10:24:05

From: "A.Appleyard" <A DOT APPLEYARD AT fs2 DOT mt DOT umist DOT ac DOT uk>
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 <FIXER AT FAXCSL DOT DCRT DOT NIH DOT GOV> 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 <farptr.h> 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 <pc.h>
#include <dpmi.h>
#include <go32.h>
/*-----*/
#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;i<n;i++) s[i]=(y[i]&255)+(color<<8); c_put(x,s,n);}
/*-----*/
void newcolor(c_short_addr x,int from,int to, char c) {
if(from>to?:from<0) return;
short s[to-from]; int i; uns short j; c_get(s,x+from,to-from);
for(i=from;i<to;i++) {j=s[i-from]; if((j>>8)!=Red) s[i-from]=(j&255)+(c<<8);}
c_put(x+from,s,to-from);}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019