Mixx C v2.0.2
This commit is contained in:
parent
f6626f0e06
commit
ba556d4163
BIN
Mixx C v202/CC.COM
Normal file
BIN
Mixx C v202/CC.COM
Normal file
Binary file not shown.
256
Mixx C v202/CERRORS.DAT
Normal file
256
Mixx C v202/CERRORS.DAT
Normal 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
BIN
Mixx C v202/CLIB.MIX
Normal file
Binary file not shown.
BIN
Mixx C v202/CONVERT.COM
Normal file
BIN
Mixx C v202/CONVERT.COM
Normal file
Binary file not shown.
30
Mixx C v202/E.C
Normal file
30
Mixx C v202/E.C
Normal 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
BIN
Mixx C v202/LINKER.COM
Normal file
Binary file not shown.
BIN
Mixx C v202/NOSOURCE.MIX
Normal file
BIN
Mixx C v202/NOSOURCE.MIX
Normal file
Binary file not shown.
262
Mixx C v202/PRINTF.C
Normal file
262
Mixx C v202/PRINTF.C
Normal 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
140
Mixx C v202/READ.ME
Normal 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
BIN
Mixx C v202/RUNTIME.OVY
Normal file
Binary file not shown.
350
Mixx C v202/SCANF.C
Normal file
350
Mixx C v202/SCANF.C
Normal 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
BIN
Mixx C v202/SHRINK.COM
Normal file
Binary file not shown.
35
Mixx C v202/SIEVE.C
Normal file
35
Mixx C v202/SIEVE.C
Normal 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
BIN
Mixx C v202/SMALLCOM.OVY
Normal file
Binary file not shown.
BIN
Mixx C v202/SPEEDUP.COM
Normal file
BIN
Mixx C v202/SPEEDUP.COM
Normal file
Binary file not shown.
26
Mixx C v202/STDIO
Normal file
26
Mixx C v202/STDIO
Normal 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
26
Mixx C v202/STDIO.H
Normal 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
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
14
Mixx C v202/STDLIB.H
Normal 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
516
Mixx C v202/TTT.C
Normal 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
3
Mixx C v202/m.bat
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
ntvdm cc %1.c
|
||||||
|
ntvdm linker %1
|
||||||
|
|
Loading…
Reference in New Issue
Block a user