Mixx C v2.0.2

This commit is contained in:
davidly 2024-07-01 15:05:57 -07:00
parent f6626f0e06
commit ba556d4163
21 changed files with 2740 additions and 0 deletions

BIN
Mixx C v202/CC.COM Normal file

Binary file not shown.

256
Mixx C v202/CERRORS.DAT Normal file
View File

@ -0,0 +1,256 @@
Identifier expected
Identifier expected in a type declaration
Variable or function declaration expected
')' expected
':' expected
Illegal symbol
Invalid preprocessor statement
Unexpected end of file during declaration definition
Right braces expected
Right bracket ']' or '.)' expected
';' expected
Integer expected
'=' expected
Statement expected
Closing single quote expected
Invalid character constant
',' expected
Invalid octal digit
Expression or ';' expected
Invalid hexadecimal digit
Expression expected
Left parenthesis expected
WHILE keyword expected
Lvalue expected (invalid expression on left hand side of assignment)
Left braces expected or semi-colon missing on function declaration
Exponential part of floating point number expected
Lvalue expected for & and * unary operators
'{' not allowed, contents skipped
Matching '}' to error 37, text between has been skipped
Constant expected
Name of typedef expected
Structure contains a reference to itself
Bitfield too wide
Bitfields must be int or unsigned
Invalid reference to bitfield
Too many parameters in macro invocation
#ENDIF without a matching #IF
Unexpected eof with unclosed #IF statment
Preprocessor command expected
Missing parameter in macro invocation
Error opening #include file
End of file within a comment (missing */)
Open comment within a comment
Unknown option
Identifier already defined
Undeclared identifier
Null array size allowed for first dimension only
Static function definition must precede use
Pointer to a function expected
';' not allowed before '{' in function definition
Type conflict of operands in an expression
Structure assignment with structures of different sizes
| or & do not apply to float or double operands
Pointer arithmetic requires int
Illegal type of operands
Incompatible pointers
Type of variable is not array
Type of variable is not structure or union
Type of variable is not pointer
Constant expression contains illegal operator
No such field in this structure
Function parameter list expected
Redefinition of a global variable
Function definition within a function illegal
Function definition has more than one variable in declaration list
Parameter declaration expected
Label already defined
This symbol is not a label
Label not defined
Too many items in initializer
Initializer contains list to initialize single item
Type not compatible in initializer
Initializer not allowed for this class
Initialization of bitfields not allowed on statics & globals
Can not be initialized by a string constant
& operator does not apply
Pointer required for & in initializers
Expression not allowed for float, double
Switch selector must be int, unsigned or char
Array subscript must be int
Invalid type in operands of an op= or = operator
Operand to & must be a variable
Feature not implemented
String constant cannot span lines
Integer constant too large
Unable to create trace file for debugging
Too many errors

BIN
Mixx C v202/CLIB.MIX Normal file

Binary file not shown.

BIN
Mixx C v202/CONVERT.COM Normal file

Binary file not shown.

30
Mixx C v202/E.C Normal file
View File

@ -0,0 +1,30 @@
#include <stdio.h>
#define DIGITS_TO_FIND 200 /*9009*/
int main() {
int N = DIGITS_TO_FIND;
int x = 0;
int a[ DIGITS_TO_FIND ];
int n;
for (n = N - 1; n > 0; --n) {
a[n] = 1;
}
a[1] = 2, a[0] = 0;
while (N > 9) {
n = N--;
while (--n) {
a[n] = x % n;
x = 10 * a[n-1] + x/n;
}
printf("%d", x);
}
printf( "\ndone\n" );
return 0;
}

BIN
Mixx C v202/LINKER.COM Normal file

Binary file not shown.

BIN
Mixx C v202/NOSOURCE.MIX Normal file

Binary file not shown.

262
Mixx C v202/PRINTF.C Normal file
View File

@ -0,0 +1,262 @@
#include "stdio"
printf(fs) /* standard routine */
char *fs;
{
int putc();
int _write();
return _output(stdout, &fs, putc, _write);
}
fprintf(fp, fs) /* standard routine */
FILE *fp;
char *fs;
{
int putc();
int _write();
return _output(fp, &fs, putc, _write);
}
sprintf(s,fs) /* standard routine */
char *s;
char *fs;
{
int _mputc();
int _mwrite();
int status;
status = _output(&s, &fs, _mputc, _mwrite);
*s = '\0';
return status;
}
_output(fp, parms, putc, write) /* output routine for */
/* printf, sprintf, fprintf */
char *fp; /* pointer to destination */
char **parms; /* pointer to addr of parameters */
int (*putc)(); /* pointer to output function */
int (*write)(); /* pointer to output function */
{
char buffer[80]; /* encode buffer */
char *bufptr; /* pointer into buffer */
char *format; /* format string pointer */
char *cptr; /* pointer to character */
char c; /* current character */
char padchar; /* pad character */
int ljflag; /* left justify flag */
int length; /* length of output string */
int precision; /* precision for reals */
int flag; /* ftoa edit flag */
int left; /* number digits left of decimal */
int right; /* number digits right of decimal */
int width; /* mimimum field width */
int (*enc)(); /* pointer to encode function */
int _eint(); /* encode integer function */
int _elong(); /* encode long function */
int _edouble(); /* encode double function */
int _atoi(); /* convert string to integer */
int _getformat(); /* get format flag */
int strlen(); /* determine length of string */
STRING *dynamic; /* dynamic string pointer */
format = *parms--; /* format points to format string */
while (c = *format++) {
if (c != '%') {
if ((*putc)(c,fp) != EOF) continue;
else return EOF;
}
precision = -1;
bufptr = buffer;
ljflag = 0;
if (*format == '-') {
++format;
++ljflag;
}
padchar = (*format == '0') ? '0' : ' ';
width = (isdigit(*format)) ? _atoi(&format) : 0;
if ((*format) == '.') {
++format;
if (isdigit(*format)) precision = _atoi(&format);
}
enc = _eint;
if (toupper(c = *format++) == 'L') {
c = *format++;
enc = _elong;
--parms;
}
switch(toupper(c)) {
case 'D': /* signed decimal */
(*enc)(parms, buffer, 10, 1);
length = strlen(bufptr);
break;
case 'U': /* unsigned decimal */
(*enc)(parms, buffer, 10, 0);
length = strlen(bufptr);
break;
case 'O': /* unsigned octal */
(*enc)(parms, buffer, 8, 0);
length = strlen(bufptr);
break;
case 'X': /* unsigned hexadecimal */
(*enc)(parms, buffer, 16, 0);
length = strlen(bufptr);
break;
case 'S': /* string */
bufptr = *parms;
length = strlen(bufptr);
break;
case 'C': /* character */
cptr = parms;
buffer[0] = *cptr;
buffer[1] = '\0';
length = 1;
break;
case 'E': /* exponential */
flag = 1;
goto reals;
case 'F': /* fixed point */
flag = 0;
goto reals;
case 'G': /* no trailing 0's */
/* fixed or exponential? */
flag = _getformat(parms-3);
reals:
left = 1;
parms = parms - 3;
if (precision == -1) right = 6;
else right = precision;
_edouble(parms, buffer, flag, left, right);
precision = -1;
length = 0;
while (c=buffer[length]) {
if (c == 'D') buffer[length] = 'E';
++length;
}
break;
case 'Y': /* dynamic string */
dynamic = *parms;
length = dynamic->length;
bufptr = dynamic->string;
break;
default : /* format string character */
if ((*putc)(c, fp) != EOF) continue;
else return EOF;
}
if (precision >= 0 && length > precision) length = precision;
width = width - length;
if (!ljflag) {
if (padchar == '0' && *bufptr == '-') {
--length;
if ((*putc)(*bufptr++, fp) == EOF) return EOF;
}
while (width-- > 0)
if ((*putc)(padchar, fp) == EOF) return EOF;
}
if ((*write)(fp,bufptr,length) == EOF) return EOF;
while (width-- > 0)
if ((*putc)(padchar,fp) == EOF) return EOF;
--parms;
}
return 0;
}
_eint(iptr, bufptr, base, sf) /* encode an integer*/
int *iptr; /* pointer to integer */
char *bufptr; /* pointer to encode buffer */
int base; /* number base */
int sf; /* signed or unsigned flag */
{
if (*iptr < 0 && sf) {
*bufptr++ = '-';
*iptr = -*iptr;
}
_itoa(*iptr, &bufptr, base); /* convert integer to string */
*bufptr = '\0';
}
_elong(lptr, bufptr, base, sf) /* encode a long */
long *lptr; /* pointer to long */
char *bufptr; /* pointer to encode buffer */
int base; /* number base */
int sf; /* sign flag */
{
if (*lptr < 0 && sf) {
*bufptr++ = '-';
*lptr = -*lptr;
}
_ltostr(*lptr, &bufptr, base); /* convert long to string */
*bufptr = '\0';
}
_itoa(n, bufptr, base) /* integer encode routine */
unsigned n; /* unsigned integer */
char **bufptr; /* pointer to the buffer pointer */
int base; /* number base */
{
if (n < base) {
*(*bufptr)++ = (n < 10) ? n + 48 : n + 55;
return;
}
_itoa(n/base, bufptr, base);
_itoa(n%base, bufptr, base);
}
_ltostr(lptr, bufptr, base) /* long encode routine */
long lptr; /* long integer */
char **bufptr; /* pointer to the buffer pointer */
int base; /* number base */
{
if (lptr < base) {
*(*bufptr)++ = (lptr < 10) ? lptr + '0' : lptr + 55;
return;
}
_ltostr(lptr/base, bufptr, base);
_ltostr(lptr%base, bufptr, base);
}
_edouble(dptr, bufptr, flag, left, right) /* encode a double */
double *dptr; /* pointer to double */
char *bufptr; /* pointer to encode buffer */
int flag; /* encode format flag */
int left; /* # of digits left of decimal */
int right; /* # of digits right of decimal */
{
ftoa(*dptr, bufptr, flag, left, right);
}
_mputc(c, fp) /* write c to fp */
int c;
char **fp;
{
*(*fp)++ = c;
return c;
}
_mwrite(fp, s, n)
char **fp;
char *s;
int n;
{
int i;
for (i=0; i < n; i++) *(*fp)++ = *s++;
return n;
}
_getformat(dptr) /* get format flag */
double *dptr; /* for _edouble */
{
if (*dptr < 100000.0) return 2; /* fixed format */
else return 3; /* exponential format */
}

140
Mixx C v202/READ.ME Normal file
View File

@ -0,0 +1,140 @@
Mix C 2.0.2
New Features in version 2.0
---------------------------
. Maximum length of a line is increased to 256 characters
. Keywords are recognized in lower case only. The compiler
option /*$KEYWCASE*/ may be used to switch to upper and mixed
case for keywords
. On the listing, lines are numbered separately for each include
file. A letter (a .. z) is present on the left of each line from
an include file to indicate the depth of includes.
. When errors occur in include files, the error file (C.ERR) will
have the name of the file as well as the line in error.
. Include files have a default extension of ".H" . If a file name
in a #include does not have an extension, the compiler looks first
for the file as specified. If no file exists by that name, the
compiler trys the same name with ".H" as an extension.
. Initializers are supported for float and double. Initializers for
auto variables may use constant expressions. Initializers for float
and double static or global variables allow only a constant.
. Hexadecimal character constants are supported and hexadecimal
characters may be included in strings. They are represented by
a backslash followed by "x" and a two digit hexadecimal number.
Examples:
'\x30' is the character '0'
"ab\x63d" is equivalent to "abcd"
. Enumerations are supported. Enumerations are declared similar
to structures with the keyword "enum". The braces contain a
list of identifiers with optional initialization values. Values
are assigned starting at zero and increasing by one for each
identifier. If an intialization value is present, the corresponding
identifier is assigned the value supplied and counting continues
from that point.
Examples:
enum primecolor {red, blue, green} c;
/* declares a variable of type primecolor. The identifiers
are assigned values: red=0, blue=1, green=2.
*/
typedef enum {orange, yellow=8, pink, aqua} color;
/* defines the type color. The values of the colors are:
orange=0, yellow=8, pink=9, aqua=10
*/
c = blue; /* assigns the value "blue" (1) to c */
. Structures and unions may be passed as parameters to functions.
They are passed by value.
. Functions may return structures or unions as results.
. The compiler has a command line option to redirect the object
code to a different file. "-ofilename.ext" will place the object
code in the specified file. "-o" with not file name will cause
the compiler to not generate object code.
Optional Patches
----------------
Some people may wish to change some of the file names used by Mix C
so that it will use a different disk drive or directory. The addresses
of these file names are listed below. You can use the debug utility
supplied with MSDOS to change the names to the ones that you prefer.
Mix C will search for the error messages ("CERRORS.DAT") in the default
directory and all directories listed in the path string in the
environment. See the msdos manual for a description of the "PATH"
command. Most users will not need to change this. Be sure to make a
copy of the original disk before attempting to make the changes. The
file names are strings of characters up to 15 characters in length and
terminated by a binary zero.
CERRORS.DAT DBAD Error messages file
C.ERR 6804 File for lines in error
A: D6CF Prefix for include files that are
enclosed in "<>"
Example:
To make the #include preprocessor statement use drive C, directory "MIXC"
as the system device (ie for file names enclosed in "< >") you would
use debug to make the patch as illustrated below.
C>debug cc.com
-ed6cf "C:\MIXC\" ;Patch in path name
-W ;Write cc.com back to disk
Writing ED00 bytes
-Q ;Exit debugger
C>
The Mix linker also has some file names that are built in. In some
applications you may wish to change one or more of these names. Each
file name can be up to 31 bytes long and must be terminated by a zero
byte. These names are changed in the same way as illustrated above.
"RUNTIME.OVY" 391C Default name for the runtime support file
"CLIB.MIX" 3A14 Library that is searched for standard functions.
"LINKER.MIX" 3AA5 Library that is searched if clib does not contain
all referenced functions.
"A:" and "A:\" 3AC5 Directory prefix used to search for runtime.ovy .
Each prefix is terminated by a zero, and the entire
list is terminated by two zeros.
Example:
The following example patches the linker to search for its files in
directory MIXC on drive C.
C>debug linker.com
-ed3AC5 "C:\MIXC\" ;Patch in path name
-W ;Write linker.com back to disk
Writing 3D00 bytes
-Q ;Exit debugger
C>
When the short form of the linker is used to build a command file, the
runtime support routines are not inlcuded in the file. To make the linker
include the runtime by default, make the following change.
A>debug linker.com
-e72c
09FE:072C 32.b0 C0.01
-w
Writing 3D00 bytes
-q
A>
Note: When using the change command in the linker to use a different
runtime file, the change command must be executed before any
load commands. The linker must know the size of the runtime so
it can perform relocation as it loads the program.

BIN
Mixx C v202/RUNTIME.OVY Normal file

Binary file not shown.

350
Mixx C v202/SCANF.C Normal file
View File

@ -0,0 +1,350 @@
#include "stdio"
scanf(fs) /* standard routine */
char *fs;
{
int getc();
int ungetc();
return _input(stdin, &fs, getc, ungetc);
}
fscanf(fp, fs) /* standard routine */
char *fp, *fs;
{
int getc();
int ungetc();
return _input(fp, &fs, getc, ungetc);
}
sscanf(s,fs) /* standard routine */
char *s, *fs;
{
int _mread();
int _mungetc();
return _input(&s, &fs, _mread, _mungetc);
}
_input(fp, parms, read, ungetc) /* input routine for */
/* scanf, sscanf, fscanf */
char *fp; /* pointer to input */
char **parms; /* pointer to addr of parameters */
int (*read)(); /* character read function */
int (*ungetc)(); /* character unget function */
{
union { /* buffer for numeric & string storage */
int integer;
char string[81];
} buffer;
char *format; /* format string pointer */
char c; /* format string character */
char **ptr; /* pointer to pointer */
int base; /* number base */
int value; /* binary value of digit */
int pflag; /* real precision flag */
int asflag; /* assignment supression flag */
int sflag; /* sign flag */
int ch; /* input character */
int temp; /* temporary storage */
int i; /* loop counter */
int count; /* character count */
int width; /* maximum field width */
int status; /* status returned from the read */
int valid; /* valid real number format */
int (*acc)(); /* pointer to accumulate function */
int (*neg)(); /* pointer to negate function */
int (*asn)(); /* pointer to assign function */
int _digit(); /* decode digit function */
int _dint(); /* decode integer function */
int _dlong(); /* decode long function */
int _negint(); /* negate integer function */
int _neglong(); /* negate long function */
int _aint(); /* assign integer function */
int _along(); /* assign long function */
int _atoi(); /* convert string to integer */
int isspace(); /* whitespace function */
int isdigit(); /* digit function */
STRING *stods(); /* convert string to dynamic string */
format = *parms--; /* format points to format string */
count = 0; /* number of parameters read */
while (c = *format++) {
if (isspace(c)) continue; /* skip white space */
if (c != '%') {
while (isspace(ch = (*read)(fp)));
if (ch == c) continue;
else return (ch == EOF) ? EOF : count;
}
pflag = sflag = asflag = 0;
if ((*format) == '*') { /* check for assignment suppression */
++asflag;
++format;
}
acc = _dint;
neg = _negint;
asn = _aint;
width = isdigit(*format) ? _atoi(&format) : -1;
if (toupper(*format) == 'L') { /* check for double precision */
++pflag;
++format;
acc = _dlong;
neg = _neglong;
asn = _along;
}
c = *format++;
switch (toupper(c)) {
case 'H': /* signed decimal */
pflag++;
case 'D':
case 'U':
base = 10;
goto decode;
case 'O': /* unsigned octal */
base = 8;
goto decode;
case 'X': /* unsigned hexadecimal */
base = 16;
decode:
for (i=0; i<5; ++i) buffer.string[i] = '\0';
while ((ch=(*read)(fp))==' ' || ch == '\t'
|| ch == '\n');
if (ch == EOF) return EOF;
if (width && (ch == '+' || ch == '-')) {
if (ch == '-') ++sflag;
ch = (*read)(fp);
--width;
}
if (width && base == 16 && ch == '0') {
temp = (*read)(fp);
--width;
if (toupper(temp) == 'X' && width) {
ch = (*read)(fp);
--width;
}
else {
(*ungetc)(temp, fp);
++width;
}
}
if ((value = _digit(ch, base)) == -1) return count;
while (width && (value != -1)) {
(*acc)(&buffer.integer, value, base);
ch = (*read)(fp);
--width;
value = _digit(ch,base);
}
(*ungetc)(ch, fp);
if (sflag) (*neg)(&buffer.integer);
if (!asflag) {
(*asn)(&buffer.integer, *parms, pflag);
++count;
--parms;
}
break;
case 'S': /* string */
while ((ch=(*read)(fp))==' ' || ch == '\t'
|| ch == '\n');
if (ch == EOF) return EOF;
while (width && ch != ' ' && ch != '\t'
&& ch != '\n' && ch != EOF) {
if (!asflag) *(*parms)++ = ch;
ch = (*read)(fp);
--width;
}
(*ungetc)(ch, fp);
if (!asflag) {
*(*parms) = '\0';
++count;
--parms;
}
break;
case 'C': /* character */
if ((ch = (*read)(fp)) == EOF) return EOF;
else
if (!asflag) {
*(*parms) = ch;
++count;
--parms;
}
break;
case 'E':
case 'F': /* floating point */
while ((ch=(*read)(fp))==' ' || ch == '\t'
|| ch == '\n');
if (ch == EOF) return EOF;
i = 0;
valid = 0;
if (width && (ch == '+' || ch == '-')) {
buffer.string[i++] = ch;
ch = (*read)(fp);
--width;
}
while (width && ch >= '0' && ch <= '9') {
buffer.string[i++] = ch;
ch = (*read)(fp);
--width;
++valid;
}
if (width && ch == '.') {
buffer.string[i++] = ch;
ch = (*read)(fp);
--width;
while (width && ch >= '0' && ch <= '9') {
buffer.string[i++] = ch;
ch = (*read)(fp);
--width;
++valid;
}
}
if (width && (ch == 'E' || ch == 'e' || ch == 'D')) {
if (!valid) return count;
valid = 0;
buffer.string[i++] = 'E';
ch = (*read)(fp);
--width;
if (width && (ch == '+' || ch == '-')) {
buffer.string[i++] = ch;
ch = (*read)(fp);
--width;
}
while (width && isdigit(ch)) {
buffer.string[i++] = ch;
ch = (*read)(fp);
--width;
++valid;
}
}
(*ungetc)(ch, fp);
if (!valid) return count;
buffer.string[i] = '\0';
if (!asflag) {
_dreal(buffer.string, *parms, pflag);
++count;
--parms;
}
break;
case 'Y': /* dynamic string */
while ((ch=(*read)(fp))==' ' || ch == '\t'
|| ch == '\n');
if (ch == EOF) return EOF;
i = 0;
while (width && ch != ' ' && ch != '\t'
&& ch != '\n' && ch != EOF) {
if (i < 80) buffer.string[i++] = ch;
ch = (*read)(fp);
--width;
}
buffer.string[i] = '\0';
(*ungetc)(ch,fp);
if (!asflag) {
ptr = *parms;
*ptr = stods(buffer.string);
++count;
--parms;
}
break;
default :
return count;
}
}
return count;
}
_negint(iptr) /* negate integer */
int *iptr; /* pointer to integer */
{
*iptr = -*iptr;
}
_aint(iptr1, iptr2, pflag) /* assign integer */
int *iptr1; /* pointer to fp */
int *iptr2; /* pointer to destination */
int pflag; /* short integer flag */
{
short *sptr;
if (pflag) {
sptr = iptr2;
*sptr = *iptr1;
}
else *iptr2 = *iptr1;
}
_neglong(lptr) /* negate long */
long *lptr; /* pointer to long integer */
{
*lptr = -*lptr;
}
_along(lptr1, lptr2) /* assign long */
long *lptr1; /* pointer to fp */
long *lptr2; /* pointer to destination */
{
*lptr2 = *lptr1;
}
_digit(ch, base) /* decode ch to binary */
int ch; /* character to decode */
int base; /* number base */
{
if (ch >= '0' && ch <= '9') ch -= 48;
else
if (isalpha(ch = toupper(ch))) ch -= 55;
else
return -1;
if (ch < base) return ch;
else return -1;
}
_dint(iptr, digit, base) /* decode an integer */
int *iptr; /* pointer to integer */
int digit; /* digit to add to integer */
int base; /* number base */
{
*iptr = *iptr * base + digit;
}
_dlong(lptr, digit, base) /* decode a long */
long *lptr; /* pointer to long */
int digit; /* digit to add to long */
int base; /* number base */
{
*lptr = *lptr * base + digit;
}
_dreal(s, fptr, pflag) /* decode a real */
char *s; /* pointer to decode string */
float *fptr; /* pointer to float */
int pflag; /* precision flag */
{
double atof(); /* string to double function */
double *dptr; /* pointer to double */
if (pflag) {
dptr = fptr;
*dptr = atof(s);
}
else
*fptr = (float) atof(s);
}
_mread(s) /* read character from string */
char **s; /* pointer to string */
{
if (*(*s) != '\0') return *(*s)++;
else return EOF;
}
_mungetc(c,s) /* unget character to string */
int c; /* dumy parameter */
char **s; /* pointer to string pointer */
{
--(*s);
return c;
}

BIN
Mixx C v202/SHRINK.COM Normal file

Binary file not shown.

35
Mixx C v202/SIEVE.C Normal file
View File

@ -0,0 +1,35 @@
/* sieve.c */
/* Eratosthenes Sieve Prime Number Program in C from Byte Jan 1983
to compare the speed. */
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define SIZE 8190
typedef int bool;
char flags[SIZE+1];
int main()
{
int i,k;
int prime,count,iter;
for (iter = 1; iter <= 10; iter++) { /* do program 10 times */
count = 0; /* initialize prime counter */
for (i = 0; i <= SIZE; i++) /* set all flags TRUE */
flags[i] = TRUE;
for (i = 0; i <= SIZE; i++) {
if (flags[i]) { /* found a prime */
prime = i + i + 3; /* twice index + 3 */
for (k = i + prime; k <= SIZE; k += prime)
flags[k] = FALSE; /* kill all multiples */
count++; /* primes found */
}
}
}
printf("%d primes.\n",count); /*primes found in 10th pass */
return 0;
}

BIN
Mixx C v202/SMALLCOM.OVY Normal file

Binary file not shown.

BIN
Mixx C v202/SPEEDUP.COM Normal file

Binary file not shown.

26
Mixx C v202/STDIO Normal file
View File

@ -0,0 +1,26 @@
/******************* Standard I/O Header ***********************/
#define MAXFILES 20
#define BUFSIZ 512
#define EOF -1
#define NULL 0
#define stdin _iob[0]
#define stdout _iob[1]
#define stderr _iob[2]
#define getchar() getc(stdin)
#define putchar(c) putc(c,stdout)
typedef struct {
char file[32]; /* file descriptor */
int fd; /* file descriptor number */
} FILE;
extern FILE *_iob[MAXFILES];
typedef struct {
int length;
char string[80];
} STRING;
/***************************************************************/

26
Mixx C v202/STDIO.H Normal file
View File

@ -0,0 +1,26 @@
/******************* Standard I/O Header ***********************/
#define MAXFILES 20
#define BUFSIZ 512
#define EOF -1
#define NULL 0
#define stdin _iob[0]
#define stdout _iob[1]
#define stderr _iob[2]
#define getchar() getc(stdin)
#define putchar(c) putc(c,stdout)
typedef struct {
char file[32]; /* file descriptor */
int fd; /* file descriptor number */
} FILE;
extern FILE *_iob[MAXFILES];
typedef struct {
int length;
char string[80];
} STRING;
/***************************************************************/

1082
Mixx C v202/STDLIB.C Normal file

File diff suppressed because it is too large Load Diff

14
Mixx C v202/STDLIB.H Normal file
View File

@ -0,0 +1,14 @@
/***************** Miscellaneous Definitions *******************/
typedef char jmp_buf[32];
typedef union {
struct {
char al, ah, bl, bh, cl, ch, dl, dh;
} byte;
struct {
int ax, bx, cx, dx, si, di, bp, es, ds, cs;
} word;
} REGS;
/**************************************************************/

516
Mixx C v202/TTT.C Normal file
View File

@ -0,0 +1,516 @@
/*
Mix C 2.0 version. I can't get function pointers to compile.
*/
#define LINT_ARGS
#include <stdio.h>
#ifdef DOSTIME
#include <time.h>
#include <dos.h>
#endif
#define true 1
#define false 0
/* Function Pointers are the fastest implementation for almost every compiler */
#define UseFunPointers 1
#define UseWinner2 2
#define UseLookForWinner 3
#define WinMethod UseWinner2
#define ABPrune true /* alpha beta pruning */
#define WinLosePrune true /* stop early on win/lose */
#define ScoreWin 6
#define ScoreTie 5
#define ScoreLose 4
#define ScoreMax 9
#define ScoreMin 2
#define DefaultIterations 100
#define PieceX 1
#define PieceO 2
#define PieceBlank 0
typedef char ttype; /* 8-bit and 16-bit cpus do best with char aside from register in locals */
int g_Iterations = DefaultIterations;
ttype g_board[ 9 ];
#if WinMethod == UseFunPointers
ttype pos0func()
{
/* using "register int" instead of "ttype" for x is faster on 8086 and Z80 */
register int x = g_board[0];
if ( ( x == g_board[1] && x == g_board[2] ) ||
( x == g_board[3] && x == g_board[6] ) ||
( x == g_board[4] && x == g_board[8] ) )
return x;
return PieceBlank;
}
ttype pos1func()
{
register int x = g_board[1];
if ( ( x == g_board[0] && x == g_board[2] ) ||
( x == g_board[4] && x == g_board[7] ) )
return x;
return PieceBlank;
}
ttype pos2func()
{
register int x = g_board[2];
if ( ( x == g_board[0] && x == g_board[1] ) ||
( x == g_board[5] && x == g_board[8] ) ||
( x == g_board[4] && x == g_board[6] ) )
return x;
return PieceBlank;
}
ttype pos3func()
{
register int x = g_board[3];
if ( ( x == g_board[4] && x == g_board[5] ) ||
( x == g_board[0] && x == g_board[6] ) )
return x;
return PieceBlank;
}
ttype pos4func()
{
register int x = g_board[4];
if ( ( x == g_board[0] && x == g_board[8] ) ||
( x == g_board[2] && x == g_board[6] ) ||
( x == g_board[1] && x == g_board[7] ) ||
( x == g_board[3] && x == g_board[5] ) )
return x;
return PieceBlank;
}
ttype pos5func()
{
register int x = g_board[5];
if ( ( x == g_board[3] && x == g_board[4] ) ||
( x == g_board[2] && x == g_board[8] ) )
return x;
return PieceBlank;
}
ttype pos6func()
{
register int x = g_board[6];
if ( ( x == g_board[7] && x == g_board[8] ) ||
( x == g_board[0] && x == g_board[3] ) ||
( x == g_board[4] && x == g_board[2] ) )
return x;
return PieceBlank;
}
ttype pos7func()
{
register int x = g_board[7];
if ( ( x == g_board[6] && x == g_board[8] ) ||
( x == g_board[1] && x == g_board[4] ) )
return x;
return PieceBlank;
}
ttype pos8func()
{
register int x = g_board[8];
if ( ( x == g_board[6] && x == g_board[7] ) ||
( x == g_board[2] && x == g_board[5] ) ||
( x == g_board[0] && x == g_board[4] ) )
return x;
return PieceBlank;
}
typedef ttype pfunc_t();
pfunc_t * winner_functions[9] =
{
pos0func,
pos1func,
pos2func,
pos3func,
pos4func,
pos5func,
pos6func,
pos7func,
pos8func
};
#endif
#if WinMethod == UseWinner2
ttype winner2( move ) ttype move;
{
register int x; /* faster than ttype x on the stack */
switch( move ) /* msc v3 from 1985 generates a jump table! */
{
case 0:
{
x = g_board[ 0 ];
if ( ( ( x == g_board[1] ) && ( x == g_board[2] ) ) ||
( ( x == g_board[3] ) && ( x == g_board[6] ) ) ||
( ( x == g_board[4] ) && ( x == g_board[8] ) ) )
return x;
break;
}
case 1:
{
x = g_board[ 1 ];
if ( ( ( x == g_board[0] ) && ( x == g_board[2] ) ) ||
( ( x == g_board[4] ) && ( x == g_board[7] ) ) )
return x;
break;
}
case 2:
{
x = g_board[ 2 ];
if ( ( ( x == g_board[0] ) && ( x == g_board[1] ) ) ||
( ( x == g_board[5] ) && ( x == g_board[8] ) ) ||
( ( x == g_board[4] ) && ( x == g_board[6] ) ) )
return x;
break;
}
case 3:
{
x = g_board[ 3 ];
if ( ( ( x == g_board[4] ) && ( x == g_board[5] ) ) ||
( ( x == g_board[0] ) && ( x == g_board[6] ) ) )
return x;
break;
}
case 4:
{
x = g_board[ 4 ];
if ( ( ( x == g_board[0] ) && ( x == g_board[8] ) ) ||
( ( x == g_board[2] ) && ( x == g_board[6] ) ) ||
( ( x == g_board[1] ) && ( x == g_board[7] ) ) ||
( ( x == g_board[3] ) && ( x == g_board[5] ) ) )
return x;
break;
}
case 5:
{
x = g_board[ 5 ];
if ( ( ( x == g_board[3] ) && ( x == g_board[4] ) ) ||
( ( x == g_board[2] ) && ( x == g_board[8] ) ) )
return x;
break;
}
case 6:
{
x = g_board[ 6 ];
if ( ( ( x == g_board[7] ) && ( x == g_board[8] ) ) ||
( ( x == g_board[0] ) && ( x == g_board[3] ) ) ||
( ( x == g_board[4] ) && ( x == g_board[2] ) ) )
return x;
break;
}
case 7:
{
x = g_board[ 7 ];
if ( ( ( x == g_board[6] ) && ( x == g_board[8] ) ) ||
( ( x == g_board[1] ) && ( x == g_board[4] ) ) )
return x;
break;
}
case 8:
{
x = g_board[ 8 ];
if ( ( ( x == g_board[6] ) && ( x == g_board[7] ) ) ||
( ( x == g_board[2] ) && ( x == g_board[5] ) ) ||
( ( x == g_board[0] ) && ( x == g_board[4] ) ) )
return x;
break;
}
}
return PieceBlank;
} /*winner2*/
#endif
#if WinMethod == UseLookForWinner
ttype LookForWinner()
{
register int p = g_board[0]; /* faster as register int than ttype on 8086 and Z80 */
if ( PieceBlank != p )
{
if ( p == g_board[1] && p == g_board[2] )
return p;
if ( p == g_board[3] && p == g_board[6] )
return p;
}
p = g_board[3];
if ( PieceBlank != p && p == g_board[4] && p == g_board[5] )
return p;
p = g_board[6];
if ( PieceBlank != p && p == g_board[7] && p == g_board[8] )
return p;
p = g_board[1];
if ( PieceBlank != p && p == g_board[4] && p == g_board[7] )
return p;
p = g_board[2];
if ( PieceBlank != p && p == g_board[5] && p == g_board[8] )
return p;
p = g_board[4];
if ( PieceBlank != p )
{
if ( ( p == g_board[0] ) && ( p == g_board[8] ) )
return p;
if ( ( p == g_board[2] ) && ( p == g_board[6] ) )
return p;
}
return PieceBlank;
} /*LookForWinner*/
#endif
int g_IMoves = 0;
ttype MinMax( alpha, beta, depth, move ) ttype alpha; ttype beta; ttype depth; ttype move;
{
ttype pieceMove, score; /* better perf with char than int. out of registers so use stack */
register int p, value; /* better perf with these as an int on Z80, 8080, and 8086 */
g_IMoves++;
if ( depth >= 4 )
{
#if WinMethod == UseFunPointers
p = ( * winner_functions[ move ] )();
#endif
#if WinMethod == UseWinner2
p = winner2( move );
#endif
#if WinMethod == UseLookForWinner
p = LookForWinner();
#endif
if ( PieceBlank != p )
{
if ( PieceX == p )
return ScoreWin;
return ScoreLose;
}
if ( 8 == depth )
return ScoreTie;
}
if ( depth & 1 )
{
value = ScoreMin;
pieceMove = PieceX;
}
else
{
value = ScoreMax;
pieceMove = PieceO;
}
for ( p = 0; p < 9; p++ )
{
if ( PieceBlank == g_board[ p ] )
{
g_board[p] = pieceMove;
score = MinMax( alpha, beta, depth + 1, p );
g_board[p] = PieceBlank;
if ( depth & 1 )
{
#if WinLosePrune /* #if statements must be in first column for MS C 1.0 */
if ( ScoreWin == score )
return ScoreWin;
#endif
if ( score > value )
{
value = score;
#if ABPrune
if ( value >= beta )
return value;
if ( value > alpha )
alpha = value;
#endif
}
}
else
{
#if WinLosePrune
if ( ScoreLose == score )
return ScoreLose;
#endif
if ( score < value )
{
value = score;
#if ABPrune
if ( value <= alpha )
return value;
if ( value < beta )
beta = value;
#endif
}
}
}
}
return value;
} /*MinMax*/
long g_Moves = 0;
int FindSolution( position ) ttype position;
{
register int i;
for ( i = 0; i < 9; i++ )
g_board[ i ] = PieceBlank;
g_board[ position ] = PieceX;
for ( i = 0; i < g_Iterations; i++ )
{
g_IMoves = 0;
MinMax( ScoreMin, ScoreMax, 0, position );
g_Moves += g_IMoves; /* do the 4-byte long addition once per loop to save work */
}
return 0;
} /*FindSolution*/
#ifdef CPMTIME
struct CPMTimeValue
{
int h, m, s, l;
};
void print_time_now()
{
/* This CP/M BDOS call of 105 is only implemented in NTVCM -- it's not a standard CP/M 2.2 call */
struct CPMTimeValue t;
t.h = t.m = t.s = t.l = 0;
bdos( 105, &t );
printf( "current time: %02d:%02d:%02d.%02d\n", t.h, t.m, t.s, t.l );
} /*print_time_now*/
long get_ms()
{
/* This CP/M BDOS call of 105 is only implemented in NTVCM -- it's not a standard CP/M 2.2 call */
long h, m, s, l;
struct CPMTimeValue t;
t.h = t.m = t.s = t.l = 0;
bdos( 105, &t );
h = t.h;
m = t.m;
s = t.s;
l = t.l;
return h * 3600000 + m * 60000 + s * 1000 + l * 10;
} /*get_ms*/
#else /* no elif with old compilers */
#ifdef DOSTIME
void print_time_now()
{
/* Make a DOS interrupt call to get the time */
union REGS wrIn, wrOut;
wrIn.h.ah = 0x2c;
intdos( &wrIn, &wrOut );
printf( "current time: %02d:%02d:%02d.%02d\n", wrOut.h.ch, wrOut.h.cl, wrOut.h.dh, wrOut.h.dl );
fflush( stdout );
} /*print_time_now*/
long get_ms()
{
/* this function takes about 3 milliseconds on the original IBM PC */
long h, m, s, l;
union REGS wrIn, wrOut;
wrIn.h.ah = 0x2c;
intdos( &wrIn, &wrOut );
h = wrOut.h.ch;
m = wrOut.h.cl;
s = wrOut.h.dh;
l = wrOut.h.dl;
return h * 3600000 + m * 60000 + s * 1000 + l * 10;
} /*get_ms*/
#else
/* must do this on actual CP/M machines */
int print_time_now() { return 0; }
long get_ms() { return 0; }
#endif
#endif
int main( argc, argv ) int argc; char * argv[];
{
long start_time, end_time;
if ( 2 == argc )
sscanf( argv[ 1 ], "%d", &g_Iterations ); /* no atoi in MS C 1.0 */
start_time = get_ms();
FindSolution( 0 );
FindSolution( 1 );
FindSolution( 4 );
end_time = get_ms();
printf( "runtime in ms: %ld\n", end_time - start_time );
printf( "move count: %ld\n", g_Moves ); /* 6493 * g_Iterations */
printf( "iteration count: %d\n", g_Iterations );
printf( "method: %s\n",
( WinMethod == UseFunPointers ) ? "function pointers" :
( WinMethod == UseWinner2 ) ? "winner2" :
( WinMethod == UseLookForWinner ) ? "look for winner" :
"invalid method" );
return 0;
} /*main*/

3
Mixx C v202/m.bat Normal file
View File

@ -0,0 +1,3 @@
ntvdm cc %1.c
ntvdm linker %1