Category : Recently Uploaded Files
Archive   : DPMIGCC5.ZIP
Filename : START32.C
* FILE: start32 *
* *
* DESC: *
* - DPMI-switches for DPMI 0.9 *
* - init some protected mode interrupts *
* - init exception handlers *
* - clean up for exit *
* *
* Copyright (C) 1993,1994 *
* Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld *
* email: [email protected] *
* *
*****************************************************************************/
#include "DPMI.H"
#include "DPMI10.H"
#include "PRINTF.H"
#include "PROCESS.H"
#include "RSX.H"
#include "ADOSX32.H"
#include "CDOSX32.H"
#include "EXCEP32.H"
#include "START32.H"
#include "COPY32.H"
#include "SYSDEP.H"
/* global extender segments,selectors */
UINT cs16real, ds16real; /* 16-bit segments for extender */
UINT code16sel, data16sel; /* 16-bit cs,ds for extender */
UINT stack16sel; /* 16-bit stack sel */
DWORD stackp16; /* 16-bit stack offset (use long!) */
UINT sel_incr; /* increment to next selector */
UINT dosmem_sel; /* selector for the first MB */
UINT fpu_status;
WORD DPMIversion = 0;
WORD previous_client_cs;
char dpmi10; /* DPMI 1.0 server */
char dpmi10_map; /* DPMI 1.0 mapping supported */
char dpmi10_page; /* DPMI 1.0 access/dirty supported */
char dpmi10_zero; /* DPMI 1.0 demand zero supported */
/* private vars */
static WORD DPMIdata_para_needed;
static WORD DPMIdata_segm_address;
static char fpu_status_init;
/*
** back to real-mode, terminate ( int0x21 must set to orginal )
*/
#ifndef __EMX__
extern void ProtectedModeSwitch(void);
extern void RealModeSwitch(void);
extern void _cexit(void);
#endif
void protected_to_real(WORD errorlevel)
{
if (fpu_status_init)
DpmiSetCoproStatus(fpu_status & 3);
#ifdef _MSC_VER
RealModeSwitch(); /* clean up in real mode */
_cexit();
ProtectedModeSwitch();
#endif
#ifdef _TURBOC_
RealModeSwitch(); /* clean up interrupt vector */
_restorezero();
ProtectedModeSwitch();
#endif
dos_exit(errorlevel);
/* program ends here */
}
void init_real_mode(void)
{
#ifdef __EMX__
DWORD base_addr; /* rsx32 is in protected mode */
code16sel = GetCS();
data16sel = stack16sel = GetDS();
GetBaseAddress(code16sel, &base_addr);
cs16real = (UINT) (base_addr >> 4);
GetBaseAddress(data16sel, &base_addr);
ds16real = (UINT) (base_addr >> 4);
#else /* rsx16 is in real mode */
cs16real = GetCS();
ds16real = GetDS();
#endif
}
/*
** switch to protected-mode via DPMI-host
*/
int real_to_protected(WORD mode)
{
#ifndef __EMX__
WORD DPMIflags;
BYTE processor;
DWORD PM_jump; /* switch to protmode jump */
clearregs();
/* setbuf(stdout,NULL); */
if (GetDpmiEntryPoint(&PM_jump, &DPMIdata_para_needed,
&DPMIflags, &DPMIversion, &processor)) {
puts("No DPMI-host found!");
return -1;
}
if (mode == 1 && !(DPMIflags & 1)) {
puts("32bit programs not supported\n");
return -1;
}
if (DPMIdata_para_needed) { /* get DPMI ring 0 stack */
DPMIdata_segm_address = GetDpmiHostParagraph(DPMIdata_para_needed);
if (!DPMIdata_segm_address) {
puts("Can't alloc memory for the DPMI-host-stack");
return -1;
}
}
if (DpmiEnterProtectedMode(PM_jump, mode, DPMIdata_segm_address)) {
puts("can't switch to Protected Mode");
return -1;
}
/* Now we are in Protected Mode */
/* lock DPMI-stack */
if (DPMIdata_para_needed) {
LockLinRegion((DWORD) DPMIdata_segm_address << 4,
(DWORD) DPMIdata_para_needed << 4);
}
/* get prot-mode extender segments */
code16sel = GetCS();
data16sel = stack16sel = GetDS();
#endif
return 0;
}
/*
** test DPMI server
*/
int test_dpmi_capabilities(void)
{
if (!DPMIversion) {
DPMIVERSION ver;
GetDPMIVersion(&ver);
DPMIversion = ((WORD)ver.major << 8) | ver.minor;
if (opt_printall)
printf("DPMI version %d.%d\n", ver.major, ver.minor);
}
if (!opt_force_dpmi09) {
DPMICAP cap;
if ((DPMIversion >> 8) >= 1)
dpmi10 = 1;
if (!GetDPMICapabilities(&cap, iobuf)) {
if (cap.bits & 1)
dpmi10_page = 1;
if (cap.bits & 8)
dpmi10_map = 1;
if (cap.bits & 16)
dpmi10_zero = 1;
if (dpmi10_page & dpmi10_map) /* give 0.9x a chance */
dpmi10 = 1;
}
}
sel_incr = SelInc();
/* build selector for first megabyte */
AllocLDT(1, &dosmem_sel);
SetBaseAddress(dosmem_sel, 0L);
SetAccess(dosmem_sel, APP_DATA_SEL, BIG_BIT | GRANULAR_BIT);
SetLimit(dosmem_sel, 1024L * 1024L - 1L);
return 0;
}
static POINTER16_32 int21v; /* old int21h handler address */
static POINTER16_32 int10v; /* old int10h handler address */
static POINTER16_32 int33v; /* old int33h handler address */
static POINTER16_32 ctrlcv; /* old control-c handler */
static POINTER16_32 timerv; /* old timer handler */
static POINTER16_32 debintv; /* old int3 handler */
static POINTER16_32 excep0v, excep1v, excep2v, excep3v, excep4v, excep5v,
excep6v, excep7v, excep8v, excep9v, excep10v, excep11v, excep12v, excep13v, excep14v,
excep15v, excep16v, excep17v;
int hangin21;
int hangin_extender(void)
{
UINT alias_cs;
int stackp;
/* entry stack for interrupts, exceptions */
stackp16 = (UINT) & stackp;
/* store ds-sel in code for some interrupt handler */
if (CreatAlias(code16sel, &alias_cs))
return -1;
/* store 16bit data selector in load_ds function */
store32(alias_cs, (DWORD) (UINT) extender_ds, (DWORD) data16sel);
/* hang in int 0x21 */
if (GetProtModeVector32(0x21, &int21v.sel, &int21v.off) == -1) {
puts("error:can't get int21");
return -1;
}
if (SetProtModeVector32(0x21, code16sel, (DWORD) (UINT) doscall) == -1) {
puts("error:can't set int21");
return -1;
}
hangin21 = 1;
previous_client_cs = int21v.sel;
align_iobuf();
/* chain to default int 0x21 */
store32(alias_cs, (DWORD) (unsigned) &int21vsel, (DWORD) int21v.sel);
store32(alias_cs, (DWORD) (unsigned) &int21voff, (DWORD) int21v.off);
/* set new bios int10 for vesa calls */
if (GetProtModeVector32(0x10, &int10v.sel, &int10v.off)<0)
puts("int10 fail:get");
if (SetProtModeVector32(0x10, code16sel, (DWORD) (UINT) bioscall)<0)
puts("int10 fail:set");
store32(alias_cs, (DWORD) (unsigned) &int10vsel, (DWORD) int10v.sel);
store32(alias_cs, (DWORD) (unsigned) &int10voff, (DWORD) int10v.off);
FreeLDT(alias_cs);
/* MOUSE */
GetProtModeVector32(0x33, &int33v.sel, &int33v.off);
SetProtModeVector32(0x33, code16sel, (DWORD) (UINT) mousecall);
/* get all exception vectors */
GetExceptionVector32(0, &excep0v.sel, &excep0v.off);
GetExceptionVector32(1, &excep1v.sel, &excep1v.off);
GetExceptionVector32(2, &excep2v.sel, &excep2v.off);
GetExceptionVector32(3, &excep3v.sel, &excep3v.off);
GetExceptionVector32(4, &excep4v.sel, &excep4v.off);
GetExceptionVector32(5, &excep5v.sel, &excep5v.off);
GetExceptionVector32(6, &excep6v.sel, &excep6v.off);
GetExceptionVector32(7, &excep7v.sel, &excep7v.off);
GetExceptionVector32(8, &excep8v.sel, &excep8v.off);
GetExceptionVector32(9, &excep9v.sel, &excep9v.off);
GetExceptionVector32(10, &excep10v.sel, &excep10v.off);
GetExceptionVector32(11, &excep11v.sel, &excep11v.off);
GetExceptionVector32(12, &excep12v.sel, &excep12v.off);
GetExceptionVector32(13, &excep13v.sel, &excep13v.off);
GetExceptionVector32(14, &excep14v.sel, &excep14v.off);
GetExceptionVector32(15, &excep15v.sel, &excep15v.off);
GetExceptionVector32(16, &excep16v.sel, &excep16v.off);
GetExceptionVector32(17, &excep17v.sel, &excep17v.off);
/* set all exception vectors */
if (!opt_debugrsx) {
SetExceptionVector32(1, code16sel, (DWORD) (UINT) (excep1_386));
SetExceptionVector32(3, code16sel, (DWORD) (UINT) (excep3_386));
}
SetExceptionVector32(0, code16sel, (DWORD) (UINT) (excep0_386));
SetExceptionVector32(2, code16sel, (DWORD) (UINT) (excep2_386));
SetExceptionVector32(4, code16sel, (DWORD) (UINT) (excep4_386));
SetExceptionVector32(5, code16sel, (DWORD) (UINT) (excep5_386));
SetExceptionVector32(6, code16sel, (DWORD) (UINT) (excep6_386));
SetExceptionVector32(7, code16sel, (DWORD) (UINT) (excep7_386));
SetExceptionVector32(8, code16sel, (DWORD) (UINT) (excep8_386));
SetExceptionVector32(9, code16sel, (DWORD) (UINT) (excep9_386));
SetExceptionVector32(10, code16sel, (DWORD) (UINT) (excep10_386));
SetExceptionVector32(11, code16sel, (DWORD) (UINT) (excep11_386));
SetExceptionVector32(12, code16sel, (DWORD) (UINT) (excep12_386));
SetExceptionVector32(13, code16sel, (DWORD) (UINT) (excep13_386));
SetExceptionVector32(15, code16sel, (DWORD) (UINT) (excep15_386));
SetExceptionVector32(16, code16sel, (DWORD) (UINT) (excep16_386));
SetExceptionVector32(17, code16sel, (DWORD) (UINT) (excep17_386));
if (dpmi10)
SetExceptionVector32(14, code16sel, (DWORD) (UINT) (page_fault));
else
SetExceptionVector32(14, code16sel, (DWORD) (UINT) (excep14_386));
/* TIMER */
GetProtModeVector32(0x1C, &timerv.sel, &timerv.off);
SetProtModeVector32(0x1C, code16sel, (DWORD) (UINT) timer_handler);
/* CTRL-C */
GetProtModeVector32(0x23, &ctrlcv.sel, &ctrlcv.off);
SetProtModeVector32(0x23, code16sel, (DWORD) (UINT) prot_cbrk);
/* debug int3 */
if (!opt_debugrsx) {
GetProtModeVector32(0x03, &debintv.sel, &debintv.off);
SetProtModeVector32(0x03, code16sel, (DWORD) (UINT) debug_entry);
}
return 0;
}
/*
** init fpu
*/
int init_fpu(void)
{
/* Get FPU status, if user allow this (not -e0) */
if (opt_force_copro != 1) {
if (DpmiGetCoproStatus(&fpu_status))
fpu_status = 0;
if (opt_printall)
printf("fpu_status = 0x%X\n", fpu_status);
}
/*
** copro = 0 , with -e option : if no 387, set copro = 2
** copro = 1 , default : enable FPU
** copro = 3 , if no FPU : enable kernel FPU emulation
*/
if (copro == 0 && !npx_present) /* catch missing 387 */
if (! opt_force_copro)
copro = 2;
if (copro) {
fpu_status_init = 1;
if (DpmiSetCoproStatus(copro))
puts("Warning: No DPMI-server FPU support");
}
return 0;
}
static void free_emu_mem(void)
{
UnlockLinRegion(RSX_PROCESS.memaddress, RSX_PROCESS.membytes);
if (rsx387_in_dosmem)
FreeDosMem((WORD) RSX_PROCESS.memhandle);
else
FreeMem(RSX_PROCESS.memhandle);
FreeLDT(RSX_PROCESS.code32sel);
FreeLDT(RSX_PROCESS.data32sel);
FreeLDT(RSX_PROCESS.data32sel + sel_incr);
}
/* clean up interrupt handlers, exceptions, memory ... */
void clean_up(void)
{
flush_all_buffers();
clearregs();
if (opt_printall)
puts("cleanup now");
if (DPMIdata_para_needed)
UnlockLinRegion((DWORD) DPMIdata_segm_address << 4,
(DWORD) DPMIdata_para_needed << 4);
/* unset 387-usage (otherwise: crash) */
if (fpu_status_init) {
DpmiSetCoproStatus(fpu_status & 3);
if (copro == 3 && emu_sel != 0)
free_emu_mem();
}
fpu_status_init = 0;
copro = 0;
SetProtModeVector32(0x21, int21v.sel, int21v.off);
SetProtModeVector32(0x10, int10v.sel, int10v.off);
SetProtModeVector32(0x1C, timerv.sel, timerv.off);
SetProtModeVector32(0x23, ctrlcv.sel, ctrlcv.off);
SetProtModeVector32(0x03, debintv.sel, debintv.off);
if (!opt_debugrsx) {
SetExceptionVector32(1, excep1v.sel, excep1v.off);
SetExceptionVector32(3, excep3v.sel, excep3v.off);
}
SetExceptionVector32(0, excep0v.sel, excep0v.off);
SetExceptionVector32(2, excep2v.sel, excep2v.off);
SetExceptionVector32(4, excep4v.sel, excep4v.off);
SetExceptionVector32(5, excep5v.sel, excep5v.off);
SetExceptionVector32(6, excep6v.sel, excep6v.off);
SetExceptionVector32(7, excep7v.sel, excep7v.off);
SetExceptionVector32(8, excep8v.sel, excep8v.off);
SetExceptionVector32(9, excep9v.sel, excep9v.off);
SetExceptionVector32(10, excep10v.sel, excep10v.off);
SetExceptionVector32(11, excep11v.sel, excep11v.off);
SetExceptionVector32(12, excep12v.sel, excep12v.off);
SetExceptionVector32(13, excep13v.sel, excep13v.off);
SetExceptionVector32(14, excep14v.sel, excep14v.off);
SetExceptionVector32(15, excep15v.sel, excep15v.off);
SetExceptionVector32(16, excep16v.sel, excep16v.off);
SetExceptionVector32(17, excep17v.sel, excep17v.off);
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/