home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet MPEG Audio Archive
/
IMAA.mdf
/
util
/
dos
/
l3v100n
/
rsx
/
source
/
start32.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-19
|
10KB
|
295 lines
/* This file is START32.C
**
** contains :
**
** - DPMI-switches for DPMI 0.9
** - init some protected mode interrupts
** - init exception handlers
** - clean up for exit
**
** Copyright (c) Rainer Schnitker 91,92,93
*/
#include <stdio.h>
#include <malloc.h>
#include "DPMI.H"
#include "DPMIDOS.H"
#include "PROCESS.H"
#include "RSX.H"
#include "ADOSX32.H"
#include "CDOSX32.H"
#include "EXCEP32.H"
#include "START32.H"
/* global extender segments,selectors */
WORD cs16real, ds16real; /* 16-bit segments for extender */
WORD code16sel, data16sel; /* 16-bit cs,ds for extender */
WORD stack16sel; /* 16-bit stack sel */
DWORD stackp16; /* 16-bit stack offset */
WORD sel_incr; /* increment to next selector */
WORD dosmem_sel; /* selector for the first MB */
char dpmi10 = 0;
/* private vars */
static WORD DPMIdata_para_needed = 0;
static WORD DPMIdata_segm_address = 0;
extern WORD _psp; /* new psp after switch to protmode */
/*
** back to real-mode, terminate ( int0x21 must set to orginal )
*/
void protected_to_real(WORD errorlevel)
{
DpmiDisableFpu();
dos_exit(errorlevel);
/* program ends here */
}
int real_to_protected(WORD mode)
{
WORD stackp;
WORD DPMIflags, DPMIversion;
BYTE processor;
DWORD PM_jump; /* switch to protmode jump */
cs16real = GetCS(); /* save real mode segments */
ds16real = GetDS(); /* for real mode calls */
clearregs();
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 */
code16sel = GetCS();
data16sel = stack16sel = GetDS();
_psp = GetES();
stackp16 = (WORD) & stackp;
clearregs();
if (copro) {
if (DpmiEnableFpu(copro)) {
puts("No DPMI-server 387 support");
puts("use -e option");
protected_to_real(1);
}
}
/* to catch a missing 387 we must do this */
else
DpmiEnableFpu(3);
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);
/* lock all program memory and memory for locked DPMI-stack */
LockLinRegion((DWORD) cs16real << 4,
((DWORD) (ds16real - cs16real) << 4) + 0x10000L);
LockLinRegion((DWORD) DPMIdata_segm_address << 4,
(DWORD) DPMIdata_para_needed << 4);
if ((DPMIversion >> 8) >= 1)
dpmi10 = 1;
if (opt_printall) {
printf("DPMI version %d,%d\n", DPMIversion >> 8, DPMIversion & 0xff);
printf("CPU 80%d86\n", processor);
printf("16bit real_seg: cs=%04X ds=%04X\n"
,cs16real, ds16real);
printf("16bit prot_sel: cs=%04X ds=%04X ss=%04X es=%04X\n"
,code16sel, data16sel, stack16sel, _psp);
printf("DPMI stack: segment=%04X size=%04X\n"
,DPMIdata_segm_address, DPMIdata_para_needed << 4);
printf("sel increment: %d\n", sel_incr);
}
return 0;
}
static POINTER16_32 int21v; /* old int21h handler address */
static POINTER16_32 ctrlcv; /* old control-c handler */
static POINTER16_32 timerv; /* old timer handler */
static POINTER16_32 debintv; /* old int3 handler */
extern void debug_entry(void);
typedef struct {
DWORD off;
WORD sel;
} PWORD;
PWORD criterrv; /* old critical error handler */
static POINTER16_32 excep0v, excep1v, excep2v, excep3v, excep4v, excep5v, excep6v,
excep7v, excep8v, excep9v, excep10v, excep11v, excep12v, excep13v, excep14v,
excep15v, excep16v, excep17v;
int hangin_extender(void)
{
WORD alias_cs; /* alias sel for codesel */
WORD far *write_cs_word; /* writing in code */
DWORD far *write_cs_dword;
/* store ds-sel in code for some interrupt handler */
if (CreatAlias(code16sel, &alias_cs)) /* get alias for cs */
return -1;
/* store 16bit data selector in load_ds function */
write_cs_word = MK_FP(alias_cs, (WORD) load_ds + 2);
*write_cs_word = 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) (WORD) doscall) == -1) {
puts("error:can't SET int21");
return -1;
}
align_iobuf();
/* if we want to chain to default int 0x21 */
write_cs_dword = MK_FP(alias_cs, (WORD) int21vsel);
*write_cs_dword = int21v.sel;
write_cs_dword = MK_FP(alias_cs, (WORD) int21voff);
*write_cs_dword = int21v.off;
FreeLDT(alias_cs);
/* 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 */
SetExceptionVector32(0, code16sel, (DWORD) FP_LO(excep0_386));
SetExceptionVector32(1, code16sel, (DWORD) FP_LO(excep1_386));
SetExceptionVector32(2, code16sel, (DWORD) FP_LO(excep2_386));
SetExceptionVector32(3, code16sel, (DWORD) FP_LO(excep3_386));
SetExceptionVector32(4, code16sel, (DWORD) FP_LO(excep4_386));
SetExceptionVector32(5, code16sel, (DWORD) FP_LO(excep5_386));
SetExceptionVector32(6, code16sel, (DWORD) FP_LO(excep6_386));
SetExceptionVector32(7, code16sel, (DWORD) FP_LO(excep7_386));
SetExceptionVector32(8, code16sel, (DWORD) FP_LO(excep8_386));
SetExceptionVector32(9, code16sel, (DWORD) FP_LO(excep9_386));
SetExceptionVector32(10, code16sel, (DWORD) FP_LO(excep10_386));
SetExceptionVector32(11, code16sel, (DWORD) FP_LO(excep11_386));
SetExceptionVector32(12, code16sel, (DWORD) FP_LO(excep12_386));
SetExceptionVector32(13, code16sel, (DWORD) FP_LO(excep13_386));
SetExceptionVector32(14, code16sel, (DWORD) FP_LO(excep14_386));
SetExceptionVector32(15, code16sel, (DWORD) FP_LO(excep15_386));
SetExceptionVector32(16, code16sel, (DWORD) FP_LO(excep16_386));
SetExceptionVector32(17, code16sel, (DWORD) FP_LO(excep17_386));
/* TIMER */
GetProtModeVector32(0x1C, &timerv.sel, &timerv.off);
SetProtModeVector32(0x1C, code16sel, (DWORD) (WORD) timer_handler);
/* CTRL-C */
GetProtModeVector32(0x23, &ctrlcv.sel, &ctrlcv.off);
SetProtModeVector32(0x23, code16sel, (DWORD) (WORD) prot_cbrk);
/* debug int3 */
GetProtModeVector32(0x03, &debintv.sel, &debintv.off);
SetProtModeVector32(0x03, code16sel, (DWORD) (WORD) debug_entry);
return 0;
}
/* clean up interrupt handlers, exceptions, memory ... */
void clean_up(void)
{
fflush(stdin);
fflush(stdout);
fflush(stderr);
clearregs();
if (opt_printall)
puts("cleanup now");
UnlockLinRegion((DWORD) cs16real << 4,
((DWORD) (ds16real - cs16real) << 4) + 0x10000L);
UnlockLinRegion((DWORD) DPMIdata_segm_address << 4,
(DWORD) DPMIdata_para_needed << 4);
/* unset 387-usage (otherwise: crash) */
if (copro) {
DpmiDisableFpu();
}
/* free 387 emulator */
if (copro == 3 && emu_sel != 0) {
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);
}
copro = 0;
SetProtModeVector32(0x21, int21v.sel, int21v.off);
SetProtModeVector32(0x1C, timerv.sel, timerv.off);
SetProtModeVector32(0x23, ctrlcv.sel, ctrlcv.off);
SetProtModeVector32(0x03, debintv.sel, debintv.off);
SetExceptionVector32(0, excep0v.sel, excep0v.off);
SetExceptionVector32(1, excep1v.sel, excep1v.off);
SetExceptionVector32(2, excep2v.sel, excep2v.off);
SetExceptionVector32(3, excep3v.sel, excep3v.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);
}