dorl@vms.macc.wisc.edu (Michael Dorl - MACC) (09/01/88)
I've been trying to reference screen memory directly from Quickc.
The stuff I've tried looks something like this
char far *p;
long i;
p = (char far *)0xb8000;
for (i=0; i<0x8000; i++) {
*p = '\000';
p++;
}
What i'm trying to do is blank out the screen on a Hercules card after
setting graph mode. The manual for my machine says the graph memory is
at 0xb8000 and I've done similar things from GWBasic so I know they work.
When I run the above program, the PC hangs up. I'm not even able to reboot
using ctrl-alt-del.
Questions:
Is this kind of thing legal?
If not, is there some other way to go about it?
What should I set the pointer to so that *p referneces
the right place?
Michael Dorl (608) 262-0466
dorl@vms.macc.wisc.edu
dorl@wiscmacc.bitnet
cdold@starfish.Convergent.COM (Clarence Dold) (09/02/88)
From article <666@dogie.edu>, by dorl@vms.macc.wisc.edu (Michael Dorl - MACC): > I've been trying to reference screen memory directly from Quickc. > The stuff I've tried looks something like this > > char far *p; > long i; > > p = (char far *)0xb8000; [...] The problem is in the way that Microsoft chose to implement SEGMENT:OFFSET in QuickC. The address 0xb800:0000 should appear ax 0xb8000000. This appears to be 32 bit addressing, but is actually SEGMENT followed by OFFSET, with each being 16 bits, which will then be folded into the SEG:OFF that the CPU wants to see. This topic shows up in the SAMs book 'Microsoft C on the IBM PC'. -- Clarence A Dold - cdold@starfish.Convergent.COM (408) 435-5274 ...pyramid!ctnews!mitisft!professo!dold P.O.Box 6685, San Jose, CA 95150-6685
markd@proxftl.UUCP (Mark Davidson) (09/02/88)
In article <666@dogie.edu> dorl@vms.macc.wisc.edu (Michael Dorl - MACC) writes: >I've been trying to reference screen memory directly from Quickc. >The stuff I've tried looks something like this > > char far *p; > long i; > > p = (char far *)0xb8000; > for (i=0; i<0x8000; i++) { > *p = '\000'; > p++; > } (I hope this is right!) One problem I see (at least it's different from the way I tried it) is your assignment to p. If your screen memory starts at 0xb8000 (this is an absolute address), then the value you assign to p must be given in a variation of segment:offset format. In other words, say p = (char far *) 0xb8000000; and then dereference p to access a location in screen memory. I've done this in Quick C to implement pull-down menus, windows, etc (i.e., quick and dirty prototyping). -- In real life: Mark E. Davidson uflorida!novavax!proxftl!markd Proximity Technology Inc., 3511 NE 22nd Ave, Ft. Lauderdale FL, 33308 #define STANDARD_DISCLAIMER <Quote construction site>
mrh@camcon.co.uk (Mark Hughes) (09/08/88)
From article <666@dogie.edu>, by dorl@vms.macc.wisc.edu (Michael Dorl - MACC): > I've been trying to reference screen memory directly from Quickc. > The stuff I've tried looks something like this > > char far *p; > long i; > > p = (char far *)0xb8000; > for (i=0; i<0x8000; i++) { > *p = '\000'; > p++; > } > Try defining a macro like:- #define fp(a) ( (( (long)(a) & 0xf0000 )<< 12) | ( (long(a) & 0xffff ) ) and replacing your pointer assignment with:- p = (char far *)( fp( 0xb8000 ) ); The problem is caused by the way that pointers are stored, i.e. most significant word contains segment address and l.s.w. contains the offset within the segment. Unfortunately, Microsoft C does not realise that you want to point to the address 0xb8000, and simply interprets this as segment=0xb, offset 0x8000. What you want is segment=0xb000, offset=0x8000. The macro performs this conversion for you. This is a consequence of the architecture of the 8086 (etc.), but I'm not sure if the compiler should interpret your assignment in the way that it does. Intuitively, I would say that the compiler should realise that you want to point to a memory location and implement the assignment appropriately instead of blindly stuffing the value into your variable. Does anyone know what the standards say (if anything) about this? -- ------------------- <mrh@camcon.co.uk> or <...!mcvax!ukc!idec!camcon!mrh> | Mark Hughes | Telex: 265871 (MONREF G) quoting: MAG70076 |(Compware . CCL) | BT Gold: 72:MAG70076 ------------------- Teleph: Cambridge (UK) (0)223-358855
kneller@cgl.ucsf.edu (Don Kneller) (09/13/88)
In article <1920@titan.camcon.co.uk> mrh@camcon.co.uk (Mark Hughes) writes: >From article <666@dogie.edu>, by dorl@vms.macc.wisc.edu (Michael Dorl - MACC): >> I've been trying to reference screen memory directly from Quickc. >> The stuff I've tried looks something like this >> >> char far *p; >> >> p = (char far *)0xb8000; >> >Try defining a macro like:- > >#define fp(a) ( (( (long)(a) & 0xf0000 )<< 12) | ( (long(a) & 0xffff ) ) > MSC supplies the macros you need with FP_SEG and FP_OFF, which can be used to get the segment and offset of far (32-bit) pointers. They can also be used to SET the segment and offset: FP_SEG(p) = 0xB800; FP_OFF(p) = 0; and away you go with p[0], p[1], etc. The macros are in dos.h. - don ----- Don Kneller UUCP: ...ucbvax!ucsfcgl!kneller INTERNET: kneller@cgl.ucsf.edu BITNET: kneller@ucsfcgl.BITNET