home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1991
/
11
/
dpmimem.c
< prev
next >
Wrap
Text File
|
1991-05-10
|
4KB
|
155 lines
/*
DPMIMEM.C -- Demonstrates DPMI and Windows 3.0 DOS extender
Microsoft C: cl -AS dpmimem.c
Turbo C: tcc -ms dpmimem.c
Copyright (c) 1991 Ziff Communications Co.
PC Magazine * Andrew Schulman
*/
#ifdef __TURBOC__
#pragma inline
#define _asm asm
#define _dos_allocmem(x,y) (allocmem(x, y) != -1)
#else
#define MK_FP(seg, ofs) \
((void far *) (((unsigned long) (seg) << 16) | (ofs)))
#endif
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include <dos.h>
typedef enum { FALSE, TRUE } BOOL;
/* Call MS-DOS Terminate Process with Return Code function
(INT 21h AH=4Ch), in either real or protected mode */
void dos_exit(unsigned err)
{
_asm mov al, err
_asm mov ah, 4Ch
_asm int 21h
}
/* Call Windows Release Time-Slice function (INT 2Fh AX=1680h) */
void win_yield(void)
{
_asm mov ax, 1680h
_asm int 2Fh
}
/* Call the Windows Enhanced Mode Install Check function
(INT 2Fh AX=1600h) */
BOOL win_3enh(void)
{
unsigned char vers;
_asm mov ax, 1600h
_asm int 2Fh
_asm mov vers, al
return (vers && (! (vers == 0x80 || vers == 1 || vers == 0xFF)));
}
void fail(char *s) { puts(s); dos_exit(1); }
/* Call the DPMI Mode Detection function (INT 2Fh AX=1686h) to
see if we are *already* running in protected mode under DPMI */
BOOL dpmi_present(void)
{
unsigned _ax;
_asm mov ax, 1686h
_asm int 2Fh
_asm mov _ax, ax
return (! _ax);
}
/* Call the DPMI function for Obtaining the Real to Protected
Mode Switch Entry Point (INT 2Fh AX=1687h), to determine if
DPMI is available and, if so, switch into protected mode by
calling the Switch Entry Point */
BOOL dpmi_init(void)
{
unsigned rds, rcs;
void (far *dpmi)();
unsigned hostdata_seg, hostdata_para, dpmi_flags;
_asm mov ax, 1687h // test for DPMI presence
_asm int 2Fh
_asm and ax, ax
_asm jnz nodpmi // if (AX == 0) DPMI is present
_asm mov dpmi_flags, bx
_asm mov hostdata_para, si // paras for DPMI host private data
_asm mov dpmi, di
_asm mov dpmi+2, es // DPMI protected-mode switch entry point
_asm jmp short gotdpmi
nodpmi:
return FALSE;
gotdpmi:
if (_dos_allocmem(hostdata_para, &hostdata_seg) != 0)
fail("can't allocate memory");
dpmi_flags &= ~1; /* this is a 16-bit protected-mode program */
_asm mov rds, ds
_asm mov rcs, cs
printf("DS=%04X CS=%04X in real mode\n", rds, rcs);
/* enter protected mode */
_asm mov ax, hostdata_seg
_asm mov es, ax
_asm mov ax, dpmi_flags
(*dpmi)();
/* now in protected mode */
_asm mov rds, ds
_asm mov rcs, cs
printf("DS=%04X CS=%04X in protected mode\n", rds, rcs);
return TRUE;
}
/* Call the MS-DOS Allocate Memory Block function (INT 21h AH=48h),
via the compiler's library function. The Windows DOS extender
provides INT 21h AH=48h in protected mode. */
void far *my_malloc(unsigned bytes)
{
unsigned seg;
return (_dos_allocmem(bytes >> 4, &seg)) ? 0 : MK_FP(seg, 0) ;
}
#define SIZE 20480
main()
{
unsigned long bytes = 0;
char far *fp;
time_t t1, t2;
if (! dpmi_present())
if (! dpmi_init())
fail("This program requires DPMI");
/* now in protected mode */
if (! win_3enh())
puts("Running under DPMI, but not under Windows 3.x enhanced mode");
/* allocation loop */
time(&t1);
while (fp = my_malloc(SIZE))
{
*fp = 'x';
fp[SIZE-1] = 'y';
bytes += SIZE;
win_yield();
}
time(&t2);
printf("Allocated %lu bytes in %lu seconds\n", bytes, t2 - t1);
printf("Press ENTER to release memory...");
fflush(stdout);
getchar();
dos_exit(0);
}