Category : Alternate Operating Systems - Quarterdeck DesqView, CP/M, etc
Archive   : PCCAPP.ZIP
Filename : CONFIG.C

 
Output of file : CONFIG.C contained in archive : PCCAPP.ZIP
/*
* This file is part of the Choices Operating System
* Developed by: The TAPESTRY Parallel Computing Laboratory
* University of Illinois at Urbana-Champaign
* Department of Computer Science
* 1304 W. Springfield Ave.
* Urbana, IL 61801
*
* Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992
* The University of Illinois Board of Trustees.
* All Rights Reserved.
* Distribution restricted under license agreement.
*
* Author: Lee Lup Yuen ([email protected])
* Project Manager and Principal Investigator: Roy Campbell ([email protected])
*
* Funded by: NSF TAPESTRY Grant No. 1-5-30035, NASA ICLASS Grant
* No. 1-5-25469 and No. NSG1471 and AT&T Metronet Grant No. 1-5-37411.
*/

#include
#include
#include
#include
// NOTE: This file must be exactly the same as Includes/MachineDependent/
// PC/PCConfiguration.h.
#include "PCConfiguration.h"

class Parameter
{
// A Parameter corresponds to a parameter that may be set in the loadcoff
// configuration file. A Parameter has a name, a default value, and
// a storage location. A Parameter may be set to a certain value.
public:
// Make a Paramater with that name.
Parameter (const char *name);
// Return true if the name and my Parameter name are identical.
int hasName (const char *name);
// Set the value of my Parameter to the value. The argument is an
// ASCII string that requires interpretation. Return non-zero if error.
// filename and lineNumber are for printing error messages.
virtual int setValue (const char *filename, int lineNumber, const char
*value) = 0;
// Print myself. Used for debugging.
virtual void print () = 0;
protected:
const char *name;
};

class BooleanParameter : public Parameter
{
// I'm a BooleanParameter. My value is stored in an unsigned int;
// zero indicates false, non-zero indicates true.
public:
// Make a BooleanParameter with that name and default value. param is
// the location in memory where the parameter value should be stored.
BooleanParameter (const char *name, unsigned char defaultValue,
unsigned char *param);
// Set the value of my Parameter to the value. The argument is an
// ASCII string that requires interpretation. Return non-zero if error.
// filename and lineNumber are for printing error messages. Valid
// values for are "yes" and "no".
int setValue (const char *filename, int lineNumber, const char *value);
void print ();
protected:
unsigned char *param;
};

class IntegerParameter : public Parameter
{
// I'm an IntegerParameter. My value is a 32-bit unsigned int.
public:
// Make an IntegerParameter with that name and default value. param is
// the location in memory where the parameter value should be stored.
IntegerParameter (const char *name, unsigned long defaultValue,
unsigned long *param);
// Set the value of my Parameter to the value. The argument is an
// ASCII string that requires interpretation. Return non-zero if error.
// filename and lineNumber are for printing error messages. value is
// an ASCII string of the form "09999", "9999" or "0x9999" to denote
// base 8, 10 and 16 respectively.
int setValue (const char *filename, int lineNumber, const char *value);
void print ();
protected:
unsigned long *param;
};

extern PCConfiguration thePCConfiguration;
extern char ps2Keyboard;
static unsigned long maxLowMemory;

// If you add a new parameter to this list, make sure you add it to
// the configParameter array too! These are all the parameters that can
// be set in the configuration file.
static IntegerParameter MaxLowMemory ("MaxLowMemory", 200,
&maxLowMemory);
static IntegerParameter KernelWorkingMemorySize
("KernelWorkingMemorySize", 1024,
&(thePCConfiguration.KernelWorkingMemorySize));
static BooleanParameter DisplayMemoryAllocation
("DisplayMemoryAllocation", 1,
&(thePCConfiguration.DisplayMemoryAllocation));
static BooleanParameter PS2Keyboard ("PS2Keyboard", 0,
&(thePCConfiguration.PS2Keyboard));
static BooleanParameter PS2Timer ("PS2Timer", 0,
&(thePCConfiguration.PS2Timer));
static BooleanParameter IRQ1Enabled ("IRQ1Enabled", 1,
&(thePCConfiguration.IRQEnabled [1]));
static BooleanParameter IRQ2Enabled ("IRQ2Enabled", 1,
&(thePCConfiguration.IRQEnabled [2]));
static BooleanParameter IRQ3Enabled ("IRQ3Enabled", 1,
&(thePCConfiguration.IRQEnabled [3]));
static BooleanParameter IRQ4Enabled ("IRQ4Enabled", 1,
&(thePCConfiguration.IRQEnabled [4]));
static BooleanParameter IRQ5Enabled ("IRQ5Enabled", 1,
&(thePCConfiguration.IRQEnabled [5]));
static BooleanParameter IRQ6Enabled ("IRQ6Enabled", 1,
&(thePCConfiguration.IRQEnabled [6]));
static BooleanParameter IRQ7Enabled ("IRQ7Enabled", 1,
&(thePCConfiguration.IRQEnabled [7]));
static BooleanParameter IRQ8Enabled ("IRQ8Enabled", 1,
&(thePCConfiguration.IRQEnabled [8]));
static BooleanParameter IRQ9Enabled ("IRQ9Enabled", 1,
&(thePCConfiguration.IRQEnabled [9]));
static BooleanParameter IRQ10Enabled ("IRQ10Enabled", 1,
&(thePCConfiguration.IRQEnabled [10]));
static BooleanParameter IRQ11Enabled ("IRQ11Enabled", 1,
&(thePCConfiguration.IRQEnabled [11]));
static BooleanParameter IRQ12Enabled ("IRQ12Enabled", 1,
&(thePCConfiguration.IRQEnabled [12]));
static BooleanParameter IRQ13Enabled ("IRQ13Enabled", 1,
&(thePCConfiguration.IRQEnabled [13]));
static BooleanParameter IRQ14Enabled ("IRQ14Enabled", 1,
&(thePCConfiguration.IRQEnabled [14]));
static BooleanParameter IRQ15Enabled ("IRQ15Enabled", 1,
&(thePCConfiguration.IRQEnabled [15]));

static Parameter *configParameter [] =
{
&MaxLowMemory, &KernelWorkingMemorySize, &DisplayMemoryAllocation,
&PS2Keyboard, &PS2Timer,
&IRQ1Enabled, &IRQ2Enabled, &IRQ3Enabled, &IRQ4Enabled, &IRQ5Enabled,
&IRQ6Enabled, &IRQ7Enabled, &IRQ8Enabled, &IRQ9Enabled, &IRQ10Enabled,
&IRQ11Enabled, &IRQ12Enabled, &IRQ13Enabled, &IRQ14Enabled, &IRQ15Enabled,
0
};

static void automaticConfiguration ();
void readConfigurationFile (const char *filename);
static int parseLine (const char *filename, int lineNumber, char *str,
char *&name, char *&value);
static Parameter *lookupParameter (const char *filename, int lineNumber,
const char *param);
void trim (char *str);
extern int verbose;

void writeConfiguration ()
{
if (verbose)
{
puts ("Default values:");
for (int i = 0; configParameter [i] != 0; i++)
configParameter [i] -> print ();
puts ("");
}
readConfigurationFile ("config");
automaticConfiguration ();
}

static void automaticConfiguration ()
{
// Fill in the configuration information that we can find out
// automatically. This includes extended memory size, interrupt masks
// and the interrupt vector area.
// Find out how much extended memory there is.
REGS regs;
regs.h.ah = 0x88;
int86 (0x15, ®s, ®s);
if (thePCConfiguration.PS2Keyboard)
// PS/2's return the amount of memory INCLUDING the lower 640K.
// Therefore we must reduce it by 640K to get the correct
// amount of extended memory.
thePCConfiguration.extendedMemorySize = regs.x.ax + 640 - 1024;
else
thePCConfiguration.extendedMemorySize = regs.x.ax;

// Save the program segment prefix (PSP).
regs.h.ah = 0x62;
intdos (®s, ®s);
thePCConfiguration.psp = regs.x.bx;

// Save the interrupt masks so that we can restore them when we exit.
thePCConfiguration.interruptMask1 = inportb (0x21);
thePCConfiguration.interruptMask2 = inportb (0xA1);

// Save the interrupt vectors.
unsigned char far *vectors = (unsigned char far *) 0;
for (int i = 0; i <= 1023; i++)
thePCConfiguration.interruptVectors [i] = vectors [i];

// Save the information to help Choices return to real mode.
extern char ChoicesReturn, ChoicesReturnBegin, ChoicesReturnEnd;
thePCConfiguration.choicesReturn = (uint32) FP_SEG (&ChoicesReturn)
* 16 + FP_OFF (&ChoicesReturn);
thePCConfiguration.choicesReturnArea = (uint32) FP_SEG
(&ChoicesReturnBegin) * 16 + FP_OFF (&ChoicesReturnBegin);
thePCConfiguration.choicesReturnSize = (uint32) FP_SEG
(&ChoicesReturnEnd) * 16 + FP_OFF (&ChoicesReturnEnd) -
thePCConfiguration.choicesReturnArea;
if (verbose)
{
printf ("choicesReturn = 0x%lx\n", thePCConfiguration.choicesReturn);
printf ("choicesReturnArea = 0x%lx\n", thePCConfiguration.choicesReturnArea);
printf ("choicesReturnSize = 0x%lx\n", thePCConfiguration.choicesReturnSize);
}

// Try to obtain a chunk of memory of size maxLowMemory from DOS.
regs.h.ah = 0x48;
regs.x.bx = maxLowMemory * 64; // Convert Kb to 16-byte paragraphs.
int paragraphsAllocated = regs.x.bx;
intdos (®s, ®s);
if (regs.x.cflag)
{
if (regs.x.ax != 8)
{
puts ("DOS memory control block error");
exit (1);
}
// If unsuccessful, DOS should have told us the maximum allocatable
// memory in BX. Allocate that instead.
regs.h.ah = 0x48;
paragraphsAllocated = regs.x.bx;
intdos (®s, ®s);
// Make sure it was successful.
if (regs.x.cflag)
{
puts ("Can't allocate low memory from DOS");
exit (1);
}
}
int segmentAllocated = regs.x.ax;
// Set the virtual PC memory addresses. Reserve half the memory
// for the task space, half for the buffer space.
thePCConfiguration.virtualPCTaskBase = (unsigned long)
segmentAllocated * 16;
thePCConfiguration.virtualPCTaskBound = (unsigned long)
segmentAllocated * 16 + (unsigned long) paragraphsAllocated * 16 / 2;
thePCConfiguration.virtualPCBufferBase = thePCConfiguration.
virtualPCTaskBound;
thePCConfiguration.virtualPCBufferBound = (unsigned long)
segmentAllocated * 16 + (unsigned long) paragraphsAllocated * 16;
if (verbose)
{
printf ("virtualPCTaskBase = 0x%lx\n", thePCConfiguration.
virtualPCTaskBase);
printf ("virtualPCTaskBound = 0x%lx\n", thePCConfiguration.
virtualPCTaskBound);
printf ("virtualPCBufferBase = 0x%lx\n", thePCConfiguration.
virtualPCBufferBase);
printf ("virtualPCBufferBound = 0x%lx\n", thePCConfiguration.
virtualPCBufferBound);
}

// Move the cursor to the bottom of the screen so that it becomes
// less distracting.
regs.x.ax = 0x200; regs.x.bx = 0; regs.x.dx = 24 * 0x100;
int86 (0x10, ®s, ®s);

// Take note whether we're running on a PS/2 so that A20 may
// be handled differently.
if (thePCConfiguration.PS2Keyboard) ps2Keyboard = 1;
else ps2Keyboard = 0;
}

void readConfigurationFile (const char *filename)
{
// Open the configuration file and set the parameters. All lines in
// the configuration file must be either: a blank line, a line beginning
// with '#', or a parameter-setting command of the form "para=value".
FILE *file = fopen (filename, "r");
if (file == 0)
{
printf ("Can't open configuration file '%s'\n", filename);
exit (1);
}
int totalErrors = 0;
static char buffer [1000];
int lineNumber = 1;
while (fgets (buffer, 1000, file))
{
char *str = buffer;
buffer [strlen (buffer) - 1] = 0; // Remove trailing newline.
trim (str);
int err = 0;
if (str [0] != 0 && str [0] != '#')
{
char *param, *value;
err = parseLine (filename, lineNumber, str, param, value);
if (!err)
{
Parameter *p = lookupParameter (filename, lineNumber, param);
if (p == 0) err = 1;
else err = p -> setValue (filename, lineNumber, value);
}
}
totalErrors = totalErrors + err;
lineNumber++;
}
fclose (file);
if (totalErrors) exit (1);
}

static int parseLine (const char *filename, int lineNumber, char *str,
char *&name, char *&value)
{
// Parse str, a line of the form "name=value", and set name and value
// accordingly. name and value will be stripped of leading and
// trailing spaces when returned. Return non-zero if error.
// filename and lineNumber are for printing error messages.
// Find out where the '=' is and set name and value.
for (int i = 0; str [i] != 0 && str [i] != '='; i++) {}
if (str [i] == 0)
{
printf ("File %s line %d: Bad setting; settings must have "
"the form 'NAME=VALUE'\n", filename, lineNumber);
return 1;
}
name = str;
value = str + i + 1;
str [i] = 0;
trim (name);
trim (value);
// Check whether name or value are empty.
if (name [0] == 0 || value [0] == 0)
{
printf ("File %s line %d: Bad setting; both NAME and VALUE must be "
"present in settings of the form 'NAME=VALUE'\n", filename,
lineNumber);
return 1;
}
return 0;
}

static Parameter *lookupParameter (const char *filename, int lineNumber,
const char *param)
{
// Lookup the Parameter that has name param and return the Parameter.
// If not found, print an error message using filename and lineNumber
// and return 0.
for (int i = 0; configParameter [i] != 0; i++)
if (configParameter [i] -> hasName (param))
return configParameter [i];
printf ("File %s line %d: No parameter named '%s'\n", filename,
lineNumber, param);
return 0;
}

Parameter :: Parameter (const char *name2)
{
name = name2;
}

int Parameter :: hasName (const char *name2)
{
if (strcmp (name, name2) == 0) return 1;
return 0;
}

BooleanParameter :: BooleanParameter (const char *name2, unsigned char defaultValue,
unsigned char *param2) : Parameter (name2)
{
param = param2;
*param = defaultValue;
}

int BooleanParameter :: setValue (const char *filename, int lineNumber,
const char *value)
{
if (strcmp (value, "yes") == 0) *param = 1;
else if (strcmp (value, "no") == 0) *param = 0;
else

{
printf ("File %s line %d: Bad value '%s'; expecting either "
"'yes' or 'no'\n", filename, lineNumber, value);
return 1;
}
if (verbose) printf ("Parameter %s (boolean) set to %s\n", name, value);
return 0;
}

void BooleanParameter :: print ()
{
char *s = 0;
if (*param) s = "yes";
else s = "no";
printf ("Parameter %s (boolean) has value %s\n", name, s);
}

IntegerParameter :: IntegerParameter (const char *name2, unsigned long
defaultValue, unsigned long *param2) : Parameter (name2)
{
param = param2;
*param = defaultValue;
}

int IntegerParameter :: setValue (const char *filename, int lineNumber,
const char *value)
{
long v = strtoul (value, 0, 0);
if (v == 0)
{
printf ("File %s line %d: Bad value '%s'; expecting an unsigned "
"integer\n", filename, lineNumber, value);
return 1;
}
*param = v;
if (verbose) printf ("Parameter %s (integer) set to %s\n", name, value);
return 0;
}

void IntegerParameter :: print ()
{
printf ("Parameter %s (integer) has value 0x%lx\n", name, *param);
}

static void trim (char *str)
{
// Remove leading and trailing spaces from str.
char *src = str, *dest = str;
for (; *src == ' '; src++) {}
for (;;)
{
if (*src == 0) { *dest = 0; break; }
else { *dest = *src; src++; dest++; }
}
dest--;
for (; dest >= str && *dest == ' '; dest--) *dest = 0;
}



  3 Responses to “Category : Alternate Operating Systems - Quarterdeck DesqView, CP/M, etc
Archive   : PCCAPP.ZIP
Filename : CONFIG.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. 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/