X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f From: "Rod Pemberton" Newsgroups: comp.os.msdos.djgpp Subject: Re: dos buffer Date: Thu, 20 Apr 2006 21:48:54 -0400 Organization: Aioe.org NNTP Server Lines: 131 Message-ID: References: <20060420034145 DOT K3950 AT dynamite DOT narpes DOT com> NNTP-Posting-Host: pCFjXAYAthfOLF6YhIh1ZA.user.aioe.org X-Complaints-To: abuse AT aioe DOT org X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1441 X-Priority: 3 X-Newsreader: Microsoft Outlook Express 6.00.2800.1437 X-MSMail-Priority: Normal To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com "A. Wik" wrote in message news:20060420034145 DOT K3950 AT dynamite DOT narpes DOT com... > On Wed, 19 Apr 2006, Rod Pemberton wrote: > > > > > Anyway, I've written two examples. They both compile cleanly, but haven't > > been thoroughly tested (i.e., possible bugs...). If there are any bugs, > > you'll need to sort them out yourself. > > > > Method 1) > > ---- > > #include > > #include > > #include > > > > #define BUFF 32768 > > int main(void) > > { > > unsigned long base; > > /* unsigned short segment,offset; */ > > int selector; > > char buf[BUFF]; > > > > /* base is the physical address of the low mem buffer */ > > /* selector is used for virtual addressing, i.e., within application space > > */ > > __dpmi_allocate_dos_memory((BUFF+15)>>4,&selector); > > __dpmi_get_segment_base_address(selector,&base); > > Some nit-picking regarding terminology: > > "physical" = The primitive, most low-level form of address from > a system software (privileged) point of view, and > which in the good old days referred to an address > output by the CPU onto the bus for referencing main > memory, hardware registers (memory mapped IO), the > video BIOS, RAM buffers on SCSI/EMS/Ethernet cards, > and so on (or non-existent address space). In this > day and age, references to "physical" addresses > usually never leave the chip (instead landing on > the cache). Various CPUs are capable of generating > 20-, 24-, 32-, 36-, 40-bit physical addresses or > some other size. > > "logical" = The address formed (explicitly or implicitly) by a > 16-bit segment + a 16-, 32-, or 64-bit offset, all > depending CPU type and mode. Translated into a > linear address through the classical "SHL 4 & ADD"- > scheme, or starting from the 286 in protected mode, > via the descriptor cache initialised from the GDT > and optional LDT table(s) upon loading a segment > register. > > "linear" = The 0-based address space derived from a logical > address. From the 8086-80286, and on 386+ in the > absence of paging, physical addresses are formed > directly by copying/extending/truncating the linear > address. With paging enabled on the 386+, > translation into physical is instead done according > to the page tables, configurable in an ever > increasing numbers of ways. At least one of those > ways must be sizeable enough to cover the CPU's > physical addressing capabilities (or the latter > would be rather pointless), however awkward it may > be to implement and use (e.g. 36-bit addressing, > for using more than 4 GB RAM on 32-bit CPUs would > require a scheme of swapping physical memory in and > out of the address space, much like the classical > 16-bit DOS technologies: EMS, bank-switching, > overlays...). > > "flat" = The memory management scheme in which the code-, > stack- and data-segments are all set up with a > base address of 0 and a limit including all the > memory the program is intended reference. > > "virtual" = Linear address not equal to the physical address > by sign/zero-extension. Might even be swapped > out to disk. > > .. (Corrections/additions welcome.) > > That's a bit different than the way I use those terms. I usually use 'virtual' for EIP address since it's relative to the base address of the CS selector. I usually use physical for a base 0, flat address space or what is the closest thing to the hardware lines... > The __dpmi_physical_address_mapping() function can be used to > request a virtual address (range) mapped to a specific physical > address, such as the linear frame buffer for a SVGA graphics > mode - sample code (error checking omitted): > > __dpmi_meminfo dmemi; > unsigned sel; > int st; /* status of calls */ > > dmemi.size = xres * yres * bpp + 4093 & ~4093; > dmemi.address = lfb_addr; > st = __dpmi_physical_address_mapping(&dmemi); > > sel = __dpmi_allocate_ldt_descriptors(1); > st = __dpmi_set_segment_base_address(sel, dmemi.address); > st = __dpmi_set_segment_limit(sel, dmemi.size-1); > Just remember that the DPMI host has already mapped memory below 1Mb (or is it 1Mb+64k?). So, you shouldn't pass addresses below 1Mb to __dpmi_physical_address_mapping. This will cause failures with certain DPMI hosts. Also, the Charles Sandmann based DPMI hosts (CWSDPMI, and CWSDPR0) have a hardcoded physical address limit of 128Mb. You only need two selectors for DJGPP, both of which are provided _dos_ds and _my_ds() (and/or _my_cs()). The limit of _dos_ds can be extended to 4Gb with __dpmi_set_segment_limit, providing a base 0, flat or linear address space. But, you must use non-standard functions like _far/nearptr. _my_ds() can also be extended to 4Gb (except under Windows), but it's base address is set by the DPMI host. This allows a full 4Gb address space (with 32-bit wraparound), and standard C pointers. But, the pointers need to be adjusted for the base address... If you want a non-segmented programming environment, i.e., true base 0, flat or linear address space, OpenWatcom compiles that way. Rod Pemberton