Microsoft C v1.0
This commit is contained in:
parent
643f795c5a
commit
c4ecbf7d91
116
Microsoft C v1/C.ASM
Normal file
116
Microsoft C v1/C.ASM
Normal file
@ -0,0 +1,116 @@
|
||||
|
||||
; name XCMAIN -- initiate execution of C program
|
||||
;
|
||||
; description This is the main module for a C program on the
|
||||
; MS-DOS implementation. It initializes the segment
|
||||
; registers, sets up the stack, and calls the C main
|
||||
; function _main with a pointer to the remainder of
|
||||
; the command line.
|
||||
;
|
||||
; Also defined in this module is the exit entry point
|
||||
; XCEXIT.
|
||||
;
|
||||
pgroup group base,prog
|
||||
dgroup group data,stack
|
||||
;
|
||||
; The following segment serves only to force "pgroup" lower in
|
||||
; memory. It also contains the Microsoft C revision number.
|
||||
;
|
||||
base segment 'prog'
|
||||
db "MS-C V 1.04 "
|
||||
base ends
|
||||
;
|
||||
; The data segment defines locations which contain the offsets
|
||||
; of the base and top of the stack.
|
||||
;
|
||||
data segment byte public 'data'
|
||||
public _top, _base
|
||||
_top dw 0
|
||||
_base dw 0
|
||||
data ends
|
||||
;
|
||||
; The stack segment is included to prevent the warning from the
|
||||
; linker, and also to define the base (lowest address) of the stack.
|
||||
;
|
||||
stack segment stack 'data'
|
||||
sbase dw 128 dup (?)
|
||||
stack ends
|
||||
;
|
||||
; The main program must set up the initial segment registers
|
||||
; and the stack pointer, and set up a far return to the MS-DOS
|
||||
; exit point at ES:0. The command line bytes from the program
|
||||
; segment prefix are moved onto the stack, and a pointer to
|
||||
; them supplied to the C main module _main (which calls main).
|
||||
;
|
||||
prog segment byte public 'prog'
|
||||
public XCMAIN, XCEXIT
|
||||
extrn _main:near
|
||||
assume cs:pgroup, ds:dgroup, ss:dgroup
|
||||
XCMAIN proc far
|
||||
cli ;disable interrupts
|
||||
mov ax,dgroup
|
||||
mov ds,ax ;initialize ds and ss
|
||||
mov ss,ax
|
||||
mov bx,es:2 ;total memory size (paragraphs)
|
||||
sub bx,ax
|
||||
test bx,0f000h
|
||||
jnz m1 ;branch if more than 64K bytes
|
||||
mov cl,4
|
||||
shl bx,cl ;highest available byte
|
||||
jmp short m2
|
||||
m1: mov bx,0fff0h
|
||||
m2: mov sp,bx ;set stack pointer
|
||||
sti ;enable interrupts
|
||||
mov _top,bx ;save top of stack
|
||||
mov ax,offset dgroup:sbase
|
||||
mov _base,ax ;store ptr to bottom of stack
|
||||
push es ;push ptr to pgm segment prefix
|
||||
xor ax,ax
|
||||
push ax ;instr ptr for far return
|
||||
mov bp,sp ;save in bp
|
||||
mov si,80h ;ptr to command line bytes
|
||||
mov cl,es:[si] ;get number of bytes
|
||||
inc si
|
||||
xor ch,ch ;clear high byte
|
||||
mov bx,cx
|
||||
add bx,4 ;3 bytes additional, 1 for rounding
|
||||
and bx,0fffeh ;force even number of bytes
|
||||
sub sp,bx ;allocate space on stack
|
||||
mov di,sp
|
||||
mov byte ptr [di],'c' ;store dummy program name
|
||||
inc di
|
||||
jcxz m4 ;skip if no bytes to move
|
||||
mov byte ptr [di],' '
|
||||
inc di
|
||||
m3: mov al,es:[si] ;move bytes to stack
|
||||
mov [di],al
|
||||
inc si
|
||||
inc di
|
||||
loop m3
|
||||
m4: xor ax,ax
|
||||
mov [di],al ;store null byte
|
||||
mov ax,ds
|
||||
mov es,ax ;es, ds, and ss are all equal
|
||||
mov ax,sp
|
||||
push ax ;ptr to command line
|
||||
call _main ;call C main
|
||||
mov sp,bp ;restore ptr to far return
|
||||
ret ;return to MS-DOS
|
||||
XCMAIN endp
|
||||
;
|
||||
; name XCEXIT -- terminate execution of C program
|
||||
;
|
||||
; description This function terminates execution of the current
|
||||
; program by returning to MS-DOS. The error code
|
||||
; argument normally supplied to XCEXIT is ignored
|
||||
; in this implementation.
|
||||
;
|
||||
XCEXIT proc far
|
||||
mov ax,_top ;load stack ptr with top address
|
||||
sub ax,4
|
||||
mov sp,ax
|
||||
ret ;return
|
||||
XCEXIT endp
|
||||
prog ends
|
||||
end XCMAIN
|
||||
|
BIN
Microsoft C v1/C.EXE
Normal file
BIN
Microsoft C v1/C.EXE
Normal file
Binary file not shown.
BIN
Microsoft C v1/C.MAP
Normal file
BIN
Microsoft C v1/C.MAP
Normal file
Binary file not shown.
BIN
Microsoft C v1/C.OBJ
Normal file
BIN
Microsoft C v1/C.OBJ
Normal file
Binary file not shown.
33
Microsoft C v1/CAT.C
Normal file
33
Microsoft C v1/CAT.C
Normal file
@ -0,0 +1,33 @@
|
||||
/* (This program is from p. 154 of the Kernighan and Ritchie text */
|
||||
#include <stdio.h>
|
||||
|
||||
main(argc, argv) /* cat: concatenate files */
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
FILE *fp, *fopen();
|
||||
|
||||
if (argc == 1) /* no args; copy standard input */
|
||||
filecopy(stdin);
|
||||
else
|
||||
while (--argc > 0)
|
||||
if ((fp = fopen(*++argv, "r")) == NULL) {
|
||||
fprintf(stderr,
|
||||
"cat: can't open %s\n", *argv);
|
||||
exit(1);
|
||||
} else {
|
||||
filecopy(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
filecopy(fp) /* copy file fp to standard output */
|
||||
FILE *fp;
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = getc(fp)) != EOF)
|
||||
putc(c, stdout);
|
||||
}
|
||||
p) /* cop
|
133
Microsoft C v1/CC.ASM
Normal file
133
Microsoft C v1/CC.ASM
Normal file
@ -0,0 +1,133 @@
|
||||
; name XCMAIN -- initiate execution of C program
|
||||
;
|
||||
; description This is the main module for a C program on the
|
||||
; MS-DOS implementation. It initializes the segment
|
||||
; registers, sets up the stack, and calls the C main
|
||||
; function _main with a pointer to the remainder of
|
||||
; the command line.
|
||||
;
|
||||
; Also defined in this module is the exit entry point
|
||||
; XCEXIT.
|
||||
;
|
||||
pgroup group base,prog,tail
|
||||
dgroup group data,stack
|
||||
assume cs:pgroup
|
||||
;
|
||||
; The following segment serves only to force "pgroup" lower in
|
||||
; memory.
|
||||
;
|
||||
base segment 'prog'
|
||||
db ?
|
||||
base ends
|
||||
;
|
||||
; The data segment defines locations which contain the offsets
|
||||
; of the base and top of the stack.
|
||||
;
|
||||
data segment public 'data'
|
||||
public _top, _base
|
||||
_top dw 0
|
||||
_base dw 0
|
||||
data ends
|
||||
;
|
||||
; The stack segment defines the base (lowest address) of the
|
||||
; stack. Note that in this module it is NOT defined to be
|
||||
; of the STACK combining type, thus allowing a .COM file to be
|
||||
; made of the resulting .EXE file.
|
||||
;
|
||||
stack segment 'data'
|
||||
sbase dw 128 dup (?)
|
||||
stack ends
|
||||
;
|
||||
; The tail segment allows this module to determine the paragraph
|
||||
; at which the data segment begins, without use of a relocatable
|
||||
; value.
|
||||
;
|
||||
tail segment byte 'prog'
|
||||
db "MS-C V 1.04 "
|
||||
last db 0 ;last byte in PGROUP
|
||||
tail ends
|
||||
;
|
||||
; The main program must set up the initial segment registers
|
||||
; and the stack pointer, and set up a far return to the MS-DOS
|
||||
; exit point at ES:0. The command line bytes from the program
|
||||
; segment prefix are moved onto the stack, and a pointer to
|
||||
; them supplied to the C main module _main (which calls main).
|
||||
;
|
||||
prog segment byte public 'prog'
|
||||
public XCMAIN, XCEXIT
|
||||
extrn _main:near
|
||||
assume cs:pgroup, ds:dgroup, ss:dgroup
|
||||
org 0ffh
|
||||
XCMAIN proc far
|
||||
cli
|
||||
mov ax,offset pgroup:last ;get offset of last byte
|
||||
add ax,16
|
||||
mov cl,4
|
||||
shr ax,cl ;number of paragraphs in PGROUP
|
||||
mov bx,cs
|
||||
add ax,bx ;base of DGROUP
|
||||
mov ds,ax ;initialize ds and ss
|
||||
mov ss,ax
|
||||
mov bx,es:2 ;total memory size (paragraphs)
|
||||
sub bx,ax
|
||||
test bx,0f000h
|
||||
jnz m1 ;branch if more than 64K bytes
|
||||
mov cl,4
|
||||
shl bx,cl ;highest available byte
|
||||
jmp short m2
|
||||
m1: mov bx,0fff0h
|
||||
m2: mov sp,bx ;set stack pointer
|
||||
sti
|
||||
mov _top,bx ;save top of stack
|
||||
mov ax,offset dgroup:sbase
|
||||
mov _base,ax ;store ptr to bottom of stack
|
||||
push es ;push ptr to pgm segment prefix
|
||||
xor ax,ax
|
||||
push ax ;instr ptr for far return
|
||||
mov bp,sp ;save in bp
|
||||
mov si,80h ;ptr to command line bytes
|
||||
mov cl,es:[si] ;get number of bytes
|
||||
inc si
|
||||
xor ch,ch ;clear high byte
|
||||
mov bx,cx
|
||||
add bx,4 ;3 bytes additional, 1 for rounding
|
||||
and bx,0fffeh ;force even number of bytes
|
||||
sub sp,bx ;allocate space on stack
|
||||
mov di,sp
|
||||
mov byte ptr [di],'c' ;store dummy program name
|
||||
inc di
|
||||
jcxz m4 ;skip if no bytes to move
|
||||
mov byte ptr [di],' '
|
||||
inc di
|
||||
m3: mov al,es:[si] ;move bytes to stack
|
||||
mov [di],al
|
||||
inc si
|
||||
inc di
|
||||
loop m3
|
||||
m4: xor ax,ax
|
||||
mov [di],al ;store null byte
|
||||
mov ax,ds
|
||||
mov es,ax ;es, ds, and ss are all equal
|
||||
mov ax,sp
|
||||
push ax ;ptr to command line
|
||||
call _main ;call C main
|
||||
mov sp,bp ;restore ptr to far return
|
||||
ret ;return to MS-DOS
|
||||
XCMAIN endp
|
||||
;
|
||||
; name XCEXIT -- terminate execution of C program
|
||||
;
|
||||
; description This function terminates execution of the current
|
||||
; program by returning to MS-DOS. The error code
|
||||
; argument normally supplied to XCEXIT is ignored
|
||||
; in this implementation.
|
||||
;
|
||||
XCEXIT proc far
|
||||
mov ax,_top ;load stack ptr with top address
|
||||
sub ax,4
|
||||
mov sp,ax
|
||||
ret ;return
|
||||
XCEXIT endp
|
||||
prog ends
|
||||
end XCMAIN
|
||||
|
BIN
Microsoft C v1/CC.EXE
Normal file
BIN
Microsoft C v1/CC.EXE
Normal file
Binary file not shown.
BIN
Microsoft C v1/CC.OBJ
Normal file
BIN
Microsoft C v1/CC.OBJ
Normal file
Binary file not shown.
151
Microsoft C v1/CONIO.C
Normal file
151
Microsoft C v1/CONIO.C
Normal file
@ -0,0 +1,151 @@
|
||||
/**
|
||||
*
|
||||
* This module defines the various console I/O functions. They may
|
||||
* be called directly, using the names included here, or the header
|
||||
* file CONIO.H may be included so that more standard names may be
|
||||
* used. This source module is provided so that users may customize
|
||||
* the console I/O functions, if desired. Note that "cprintf" and
|
||||
* "cscanf" (included in MC.LIB) call the functions "putch", "getch",
|
||||
* and "ungetch".
|
||||
*
|
||||
**/
|
||||
#define BDOS_IN 7 /* input function for "getch" */
|
||||
#define BDOS_OUT 6 /* output function for "putch" */
|
||||
#define BDOS_CKS 11 /* check keyboard status for "kbhit" */
|
||||
#define BDOS_BKI 10 /* buffered keyboardd input for "cgets" */
|
||||
#define BDOS_PRT 9 /* print string for "cputs" */
|
||||
|
||||
static char pushback; /* character save for "ungetch" */
|
||||
|
||||
/**
|
||||
*
|
||||
* name getch -- get character from console
|
||||
*
|
||||
* synopsis c = getch();
|
||||
* char c; input character
|
||||
*
|
||||
* description This function obtains the next character typed at
|
||||
* the console or, if one was pushed back via "ungetch",
|
||||
* returns the previously pushed back character.
|
||||
*
|
||||
**/
|
||||
getch()
|
||||
{
|
||||
int c;
|
||||
|
||||
if (pushback != '\0')
|
||||
{ /* character was pushed back */
|
||||
c = pushback;
|
||||
pushback = '\0';
|
||||
return(c);
|
||||
}
|
||||
return(bdos(BDOS_IN, 0xFF) & 127);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* name putch -- send character directly to console
|
||||
*
|
||||
* synopsis putch(c);
|
||||
* char c; character to be sent
|
||||
*
|
||||
* description This function sends the specified character directly
|
||||
* to the user's console.
|
||||
*
|
||||
**/
|
||||
putch(c)
|
||||
char c;
|
||||
{
|
||||
bdos(BDOS_OUT, c&127);
|
||||
return(c);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* name ungetch -- push character back to console
|
||||
*
|
||||
* synopsis r = ungetch(c);
|
||||
* int r; return code
|
||||
* char c; character to be pushed back
|
||||
*
|
||||
* description This function pushes the indicated character back
|
||||
* on the console. Only a single level of pushback is
|
||||
* allowed. The effect is to cause "getch" to return
|
||||
* the pushed-back character the next time it is called.
|
||||
*
|
||||
* returns r = -1 if character already pushed back
|
||||
* = c otherwise
|
||||
*
|
||||
**/
|
||||
ungetch(c)
|
||||
char c;
|
||||
{
|
||||
|
||||
if (pushback != '\0') return(-1);
|
||||
pushback = c;
|
||||
return(c);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* name cgets -- get string directly from console
|
||||
*
|
||||
* synopsis p = cgets(s);
|
||||
* char *p; pointer to result string
|
||||
* char *s; string buffer (first byte = count)
|
||||
*
|
||||
* description This function obtains a string directly from the
|
||||
* user's console. This version uses the buffered
|
||||
* keyboard input function supported by the BDOS, so
|
||||
* that all of the line editing capabilities are available.
|
||||
* The first byte of "s" must be initialized to contain
|
||||
* the number of bytes, minus two, in "s". The string
|
||||
* pointer returned is "s+2", which contains the first
|
||||
* byte of input data. Note that "s[1]" will contain
|
||||
* the number of characters in the string. The carriage
|
||||
* return (which the user at the console must type to
|
||||
* terminate the operation) is replaced by a null byte.
|
||||
*
|
||||
* returns p = pointer to string received
|
||||
*
|
||||
**/
|
||||
char *cgets(s)
|
||||
char *s;
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (*s == 0) *s = 250; /* do not allow zero byte count */
|
||||
bdos(BDOS_BKI, s);
|
||||
p = s+2;
|
||||
p[s[1]] = '\0'; /* set terminating byte */
|
||||
return(p);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* name cputs -- send character string directly to console
|
||||
*
|
||||
* synopsis cputs(s);
|
||||
* char *s; character string to be sent
|
||||
*
|
||||
* description This function sends the specified string directly to
|
||||
* the user's console. The BDOS function for "print
|
||||
* string" is used. The function locates the terminating
|
||||
* null byte, changes it to a '$' (the terminator
|
||||
* required by the BDOS function), and then changes it
|
||||
* back to the null byte before returning. Thus, the
|
||||
* string to be printed cannot itself contain a '$' and
|
||||
* it cannot reside in read-only memory (ROM).
|
||||
*
|
||||
* Note that a carriage return or linefeed is NOT appended
|
||||
* by this function; they must be included in the string,
|
||||
* if desired.
|
||||
*
|
||||
**/
|
||||
cputs(s)
|
||||
char *s;
|
||||
{
|
||||
char *p;
|
||||
|
||||
for (p = s; *p != '\0'; p++) ; /* find string terminator */
|
||||
*p = '$';
|
||||
bdos(BDOS_PRT, s);
|
||||
*p = '\0';
|
||||
return;
|
||||
}
|
15
Microsoft C v1/CONIO.H
Normal file
15
Microsoft C v1/CONIO.H
Normal file
@ -0,0 +1,15 @@
|
||||
/**
|
||||
*
|
||||
* This header file defines an equivalence between several of the
|
||||
* standard level 2 I/O functions and their console I/O counterparts.
|
||||
* Use this header file for programs which perform all of these functions
|
||||
* to the console only, and need an unbuffered, direct interface to the
|
||||
* user's console. See Section 3.2.3 of the manual for more information.
|
||||
*
|
||||
**/
|
||||
#define getchar getch
|
||||
#define putchar putch
|
||||
#define gets cgets
|
||||
#define puts cputs
|
||||
#define printf cprintf
|
||||
#define scanf cscanf
|
52
Microsoft C v1/CTYPE.H
Normal file
52
Microsoft C v1/CTYPE.H
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
*
|
||||
* This header file defines various ASCII character manipulation macros,
|
||||
* as follows:
|
||||
*
|
||||
* isalpha(c) non-zero if c is alpha
|
||||
* isupper(c) non-zero if c is upper case
|
||||
* islower(c) non-zero if c is lower case
|
||||
* isdigit(c) non-zero if c is a digit (0 to 9)
|
||||
* isxdigit(c) non-zero if c is a hexadecimal digit (0 to 9, A to F,
|
||||
* a to f)
|
||||
* isspace(c) non-zero if c is white space
|
||||
* ispunct(c) non-zero if c is punctuation
|
||||
* isalnum(c) non-zero if c is alpha or digit
|
||||
* isprint(c) non-zero if c is printable (including blank)
|
||||
* isgraph(c) non-zero if c is graphic (excluding blank)
|
||||
* iscntrl(c) non-zero if c is control character
|
||||
* isascii(c) non-zero if c is ASCII
|
||||
* iscsym(c) non-zero if valid character for C symbols
|
||||
* iscsymf(c) non-zero if valid first character for C symbols
|
||||
*
|
||||
**/
|
||||
|
||||
#define _U 1 /* upper case flag */
|
||||
#define _L 2 /* lower case flag */
|
||||
#define _N 4 /* number flag */
|
||||
#define _S 8 /* space flag */
|
||||
#define _P 16 /* punctuation flag */
|
||||
#define _C 32 /* control character flag */
|
||||
#define _B 64 /* blank flag */
|
||||
#define _X 128 /* hexadecimal flag */
|
||||
|
||||
extern char _ctype[]; /* character type table */
|
||||
|
||||
#define isalpha(c) (_ctype[(c)+1]&(_U|_L))
|
||||
#define isupper(c) (_ctype[(c)+1]&_U)
|
||||
#define islower(c) (_ctype[(c)+1]&_L)
|
||||
#define isdigit(c) (_ctype[(c)+1]&_N)
|
||||
#define isxdigit(c) (_ctype[(c)+1]&_X)
|
||||
#define isspace(c) (_ctype[(c)+1]&_S)
|
||||
#define ispunct(c) (_ctype[(c)+1]&_P)
|
||||
#define isalnum(c) (_ctype[(c)+1]&(_U|_L|_N))
|
||||
#define isprint(c) (_ctype[(c)+1]&(_P|_U|_L|_N|_B))
|
||||
#define isgraph(c) (_ctype[(c)+1]&(_P|_U|_L|_N))
|
||||
#define iscntrl(c) (_ctype[(c)+1]&_C)
|
||||
#define isascii(c) ((unsigned)(c)<=127)
|
||||
#define iscsym(c) (isalnum(c)||(c==0x5f))
|
||||
#define iscsymf(c) (isalpha(c)||(c==0x5f))
|
||||
|
||||
#define toupper(c) (islower(c)?((c)-('a'-'A')):(c))
|
||||
#define tolower(c) (isupper(c)?((c)+('a'-'A')):(c))
|
||||
#define toascii(c) ((c)&127)
|
23
Microsoft C v1/FTOC.C
Normal file
23
Microsoft C v1/FTOC.C
Normal file
@ -0,0 +1,23 @@
|
||||
/* print Fahrenheit-Celsius table
|
||||
for f = 0, 20, ..., 300
|
||||
(This program is from p. 8 of the Kernighan and Ritchie text)
|
||||
*/
|
||||
main()
|
||||
{
|
||||
int lower, upper, step;
|
||||
float fahr, celsius;
|
||||
|
||||
lower = 0; /* lower limit of temperature table */
|
||||
upper = 300; /* upper limit */
|
||||
step = 20; /* step size */
|
||||
|
||||
fahr = lower;
|
||||
while (fahr <= upper) {
|
||||
celsius = (5.0/9.0) * (fahr-32.0);
|
||||
printf("%4.0f %6.1f\n", fahr, celsius);
|
||||
fahr = fahr + step;
|
||||
}
|
||||
}
|
||||
celsius = (5.0/9.0) * (fahr-32.0);
|
||||
printf("%4.0f %6.1f\n", fahr, celsius);
|
||||
fahr = fahr +
|
149
Microsoft C v1/FXU.C
Normal file
149
Microsoft C v1/FXU.C
Normal file
@ -0,0 +1,149 @@
|
||||
/**
|
||||
* name fxu -- function extract utility
|
||||
*
|
||||
* usage fxu filename function
|
||||
*
|
||||
* where "filename" is the name of a file containing
|
||||
* several C functions, and "function" is the name of
|
||||
* the particular function to be extracted. If the
|
||||
* named function is found, then (1) standard input is
|
||||
* copied to the standard output until EOF, and (2) the
|
||||
* text of the named function is written to the standard
|
||||
* output. The first option allows header information
|
||||
* to be prepended to the output file.
|
||||
*
|
||||
**/
|
||||
|
||||
#include "stdio.h"
|
||||
#include "ctype.h"
|
||||
|
||||
#define MAX 16 /* maximum characters in function name */
|
||||
#define MAXBUF 2000 /* maximum characters buffered between functions */
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int c, brace, cnest, nc;
|
||||
int i, ns, copy, inlit, delim, pc;
|
||||
FILE *sfp;
|
||||
char symbol[MAX+1];
|
||||
char text[MAXBUF];
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
fputs("Usage: fxu filename function\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
if ((sfp = fopen(argv[1], "r")) == NULL)
|
||||
{
|
||||
fputs("Can't open source file\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
brace = cnest = nc = ns = copy = inlit = pc = 0;
|
||||
c = getc(sfp); /* get first char */
|
||||
while (c != EOF)
|
||||
{ /* scan through source file */
|
||||
if (ns == MAXBUF)
|
||||
{
|
||||
fputs("Maximum buffer size exceeded\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (copy == 0)
|
||||
{
|
||||
if (brace == 0) text[ns++] = c; /* save chars between functions */
|
||||
}
|
||||
else
|
||||
if (putchar(c) == EOF)
|
||||
{
|
||||
fputs("Copy error\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (c == '/')
|
||||
{ /* possible comment */
|
||||
nc = 0;
|
||||
if ((c = getc(sfp)) == '*')
|
||||
{
|
||||
++cnest; /* bump nesting level */
|
||||
if (copy) putchar(c);
|
||||
else if (brace == 0) text[ns++] = c;
|
||||
c = getc(sfp);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (cnest != 0)
|
||||
{ /* inside comment */
|
||||
if (c == '*')
|
||||
{
|
||||
if ((c = getc(sfp)) == '/')
|
||||
{
|
||||
--cnest; /* reduce nesting level */
|
||||
if (copy) putchar(c);
|
||||
else if (brace == 0) text[ns++] = c;
|
||||
c = getc(sfp);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
nc = 0;
|
||||
}
|
||||
else if (inlit)
|
||||
{ /* inside literal string */
|
||||
if (c == '\\' && pc == '\\') c = 0;
|
||||
if (c == delim && pc != '\\') inlit = 0;
|
||||
pc = c; /* save previous character */
|
||||
}
|
||||
else if (c == '\'' || c == '\"')
|
||||
{ /* enter literal string */
|
||||
inlit = 1;
|
||||
pc = 0;
|
||||
delim = c;
|
||||
}
|
||||
else if (c == '{') ++brace;
|
||||
else if (c == '}')
|
||||
{ /* right brace */
|
||||
nc = 0;
|
||||
if (--brace == 0)
|
||||
if (copy == 0) ns = 0; /* reset save index if not found */
|
||||
else
|
||||
{ /* copy complete */
|
||||
putchar('\n');
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else if (brace == 0)
|
||||
{
|
||||
if (nc == 0)
|
||||
{ /* symbol not started yet */
|
||||
if (iscsymf(c))
|
||||
symbol[nc++] = c; /* start new symbol */
|
||||
}
|
||||
else if (iscsym(c) || c == '$')
|
||||
/* continue symbol */
|
||||
if (nc < MAX) symbol[nc++] = c;
|
||||
else symbol[0] = '\0';
|
||||
else if (nc != 0)
|
||||
{ /* end of current symbol */
|
||||
symbol[nc++] = '\0';
|
||||
if (strcmp(symbol,argv[2]) == 0)
|
||||
{ /* named function has been found */
|
||||
while ((c = getchar()) != EOF)
|
||||
putchar(c); /* copy standard input to output */
|
||||
for (i = 0; i < ns; i++)
|
||||
putchar(text[i]); /* copy saved characters */
|
||||
copy = 1; /* turn on copy flag */
|
||||
}
|
||||
nc = 0;
|
||||
}
|
||||
}
|
||||
c = getc(sfp); /* get next char */
|
||||
}
|
||||
|
||||
fputs("Named function not found\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
c = getc(sfp); /* get next char */
|
||||
}
|
||||
|
||||
fputs("Name
|
BIN
Microsoft C v1/FXU.EXE
Normal file
BIN
Microsoft C v1/FXU.EXE
Normal file
Binary file not shown.
49
Microsoft C v1/IO.ASM
Normal file
49
Microsoft C v1/IO.ASM
Normal file
@ -0,0 +1,49 @@
|
||||
; This module defines subroutines to input and output bytes from
|
||||
; an auxiliary port.
|
||||
;
|
||||
; name inp -- input byte from port
|
||||
;
|
||||
; synopsis c = inp(port);
|
||||
; int c; returned byte
|
||||
; int port; port address
|
||||
;
|
||||
; description This function inputs a byte from the specified port
|
||||
; address and returns it as the function value.
|
||||
;
|
||||
PGROUP GROUP PROG
|
||||
PROG SEGMENT BYTE PUBLIC 'PROG'
|
||||
PUBLIC INP,OUTP
|
||||
ASSUME CS:PGROUP
|
||||
INP PROC NEAR
|
||||
PUSH BP ;SAVE BP
|
||||
MOV BP,SP
|
||||
MOV DX,[BP+4] ;GET PORT ADDRESS
|
||||
IN AL,DX ;GET INPUT BYTE
|
||||
XOR AH,AH ;CLEAR HIGH BYTE
|
||||
POP BP
|
||||
RET
|
||||
INP ENDP
|
||||
;
|
||||
; name outp -- output byte to port
|
||||
;
|
||||
; synopsis outp(port,c);
|
||||
; int port; port address
|
||||
; int c; byte to send
|
||||
;
|
||||
; description This function sends the specified character to
|
||||
; the specified port.
|
||||
;
|
||||
OUTP PROC NEAR
|
||||
PUSH BP ;SAVE BP
|
||||
MOV BP,SP
|
||||
MOV DX,[BP+4] ;GET PORT ADDRESS
|
||||
MOV AX,[BP+6] ;GET OUTPUT BYTE
|
||||
OUT DX,AL
|
||||
POP BP
|
||||
RET
|
||||
OUTP ENDP
|
||||
PROG ENDS
|
||||
END
|
||||
,SP
|
||||
MOV DX,[BP+4] ;GET PORT ADDRESS
|
||||
MOV AX,[BP+6]
|
BIN
Microsoft C v1/LIB.EXE
Normal file
BIN
Microsoft C v1/LIB.EXE
Normal file
Binary file not shown.
BIN
Microsoft C v1/LINK.EXE
Normal file
BIN
Microsoft C v1/LINK.EXE
Normal file
Binary file not shown.
BIN
Microsoft C v1/Lattice_C_8086_1982.pdf
Normal file
BIN
Microsoft C v1/Lattice_C_8086_1982.pdf
Normal file
Binary file not shown.
126
Microsoft C v1/MAIN.C
Normal file
126
Microsoft C v1/MAIN.C
Normal file
@ -0,0 +1,126 @@
|
||||
/**
|
||||
*
|
||||
* This module defines the standard C main function _main.
|
||||
*
|
||||
* This version processes the command-line specifiers which modify
|
||||
* the stack size or specify assignments for "stdin" and "stdout".
|
||||
*
|
||||
**/
|
||||
#include "stdio.h"
|
||||
#include "ctype.h"
|
||||
|
||||
#define MAXNAM 16 /* maximum filename size */
|
||||
#define MAXARG 32 /* maximum command line arguments */
|
||||
|
||||
/**
|
||||
*
|
||||
* The following location defines the default stack size (bytes). It is
|
||||
* used by "sbrk" to call XCMEM to initialize the memory pool.
|
||||
*
|
||||
**/
|
||||
extern int _stack;
|
||||
|
||||
/**
|
||||
*
|
||||
* name _main - process command line, open files, and call "main"
|
||||
*
|
||||
* synopsis _main(line);
|
||||
* char *line; ptr to command line that caused execution
|
||||
*
|
||||
* description This function performs the standard pre-processing for
|
||||
* the main module of a C program. It accepts a command
|
||||
* line of the form
|
||||
*
|
||||
* pgmname [=stack] [<infile] [>outfile] parms
|
||||
*
|
||||
* and processes the three optional leading fields, builds
|
||||
* a list of pointers to the other parameters, and calls
|
||||
* the main function "main". The first optional field
|
||||
* specifies an override of the default stack size; "stack"
|
||||
* should be a decimal number of bytes. The second specifies
|
||||
* a file name for assignment to "stdin"; "infile" is the
|
||||
* file name. The third specifies, similarly, a file name
|
||||
* "outfile" for assignment to "stdout". Note that the
|
||||
* optional fields need not be specified in the order listed
|
||||
* above.
|
||||
*
|
||||
**/
|
||||
_main(line)
|
||||
char *line;
|
||||
{
|
||||
int i;
|
||||
FILE *fp0, *fp1, *fp2;
|
||||
static int argc = 1;
|
||||
static char *outmode = "w";
|
||||
static char inam[MAXNAM+1], onam[MAXNAM+1], tnam[1];
|
||||
static char *argv[MAXARG];
|
||||
|
||||
while (isspace(*line)) line++; /* find program name */
|
||||
for(argc = 0; argc < MAXARG; )
|
||||
{
|
||||
switch(*line)
|
||||
{
|
||||
case '=': /* stack size specifier */
|
||||
line++;
|
||||
_stack = 0;
|
||||
while (isdigit(*line))
|
||||
_stack = 10*_stack + (*line++ & 15);
|
||||
break;
|
||||
|
||||
case '<': /* input file specifier */
|
||||
line++;
|
||||
for(i = 0; (*line != '\0') && (isspace(*line) == 0); line++)
|
||||
if (i<MAXNAM) inam[i++] = *line;
|
||||
inam[i] = '\0';
|
||||
break;
|
||||
|
||||
case '>': /* output file specifier */
|
||||
line++;
|
||||
if (*line == '>')
|
||||
{ /* output file to be appended to */
|
||||
outmode = "a";
|
||||
line++;
|
||||
}
|
||||
for (i = 0; (*line != '\0') && (isspace(*line) == 0); line++)
|
||||
if (i<MAXNAM) onam[i++] = *line;
|
||||
onam[i] = '\0';
|
||||
break;
|
||||
|
||||
default: /* command line argument */
|
||||
argv[argc++] = line;
|
||||
while (*line != '\0' && isspace(*line) == 0) line++;
|
||||
}
|
||||
i = *line; /* save terminating character */
|
||||
*line++ = '\0';
|
||||
if (i == '\0') break; /* end of line */
|
||||
while (isspace(*line)) line++; /* scan to next */
|
||||
if (*line == '\0') break;
|
||||
}
|
||||
|
||||
fp0 = fopen(inam, "r"); /* open stdin */
|
||||
fp1 = fopen(onam, outmode); /* open stdout */
|
||||
fp2 = fopen(tnam, "a"); /* open stderr */
|
||||
if (fp2 == NULL) _exit(1);
|
||||
if (fp0 == NULL)
|
||||
{
|
||||
fputs("Can't open stdin file\n", fp2);
|
||||
exit(1);
|
||||
}
|
||||
if (fp1 == NULL)
|
||||
{
|
||||
fputs("Can't create stdout file\n", fp2);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (inam[0] == '\0')
|
||||
fp0->_flag |= _IONBF;
|
||||
if (onam[0] == '\0')
|
||||
fp1->_flag |= _IONBF;
|
||||
fp2->_flag |= _IONBF;
|
||||
|
||||
main(argc, argv); /* call main function */
|
||||
exit(0);
|
||||
}
|
||||
0')
|
||||
fp1->_flag |= _IONBF;
|
||||
fp2->_flag |= _IONBF;
|
BIN
Microsoft C v1/MC.BAT
Normal file
BIN
Microsoft C v1/MC.BAT
Normal file
Binary file not shown.
BIN
Microsoft C v1/MC.LIB
Normal file
BIN
Microsoft C v1/MC.LIB
Normal file
Binary file not shown.
BIN
Microsoft C v1/MC1.EXE
Normal file
BIN
Microsoft C v1/MC1.EXE
Normal file
Binary file not shown.
BIN
Microsoft C v1/MC2.EXE
Normal file
BIN
Microsoft C v1/MC2.EXE
Normal file
Binary file not shown.
82
Microsoft C v1/MM.C
Normal file
82
Microsoft C v1/MM.C
Normal file
@ -0,0 +1,82 @@
|
||||
/* BYTE magazine October 1982. Jerry Pournelle. */
|
||||
/* ported to C by David Lee */
|
||||
/* various bugs not found because dimensions are square fixed by David Lee */
|
||||
/* expected result: 4.65880E+05 */
|
||||
|
||||
#define LINT_ARGS
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define l 20 /* rows in A and resulting matrix C */
|
||||
#define m 20 /* columns in A and rows in B (must be identical) */
|
||||
#define n 20 /* columns in B and resulting matrix C */
|
||||
|
||||
#define ftype float
|
||||
|
||||
ftype Summ;
|
||||
ftype A[ l + 1 ] [ m + 1 ];
|
||||
ftype B[ m + 1 ] [ n + 1 ];
|
||||
ftype C[ l + 1 ] [ n + 1 ];
|
||||
|
||||
int filla()
|
||||
{
|
||||
int i, j;
|
||||
for ( i = 1; i <= l; i++ )
|
||||
for ( j = 1; j <= m; j++ )
|
||||
A[ i ] [ j ] = i + j;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fillb()
|
||||
{
|
||||
int i, j;
|
||||
for ( i = 1; i <= m; i++ )
|
||||
for ( j = 1; j <= n; j++ )
|
||||
B[ i ] [ j ] = (ftype) (int) ( ( i + j ) / j );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fillc()
|
||||
{
|
||||
int i, j;
|
||||
for ( i = 1; i <= l; i++ )
|
||||
for ( j = 1; j <= n; j++ )
|
||||
C[ i ] [ j ] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int matmult()
|
||||
{
|
||||
int i, j, k;
|
||||
for ( i = 1; i <= l; i++ )
|
||||
for ( j = 1; j <= n; j++ )
|
||||
for ( k = 1; k <= m; k++ )
|
||||
C[ i ] [ j ] += A[ i ] [ k ] * B[ k ] [ j ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int summit()
|
||||
{
|
||||
int i, j;
|
||||
for ( i = 1; i <= l; i++ )
|
||||
for ( j = 1; j <= n; j++ )
|
||||
Summ += C[ i ] [ j ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main( argc, argv ) int argc; char * argv[];
|
||||
{
|
||||
Summ = 0;
|
||||
|
||||
filla();
|
||||
fillb();
|
||||
fillc();
|
||||
matmult();
|
||||
summit();
|
||||
|
||||
printf( "summ is : %lf\n", Summ );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
BIN
Microsoft C v1/OMD.EXE
Normal file
BIN
Microsoft C v1/OMD.EXE
Normal file
Binary file not shown.
29
Microsoft C v1/SIEVE.C
Normal file
29
Microsoft C v1/SIEVE.C
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
#define size 8190
|
||||
#define sizepl 8191
|
||||
|
||||
main() {
|
||||
int i,prime,k,count,iter;
|
||||
char flags[sizepl];
|
||||
printf("10 iterations\n");
|
||||
for(iter=1;iter<= 10;iter++){
|
||||
count=0;
|
||||
for(i = 0; i<=size;i++)
|
||||
flags[i]=true;
|
||||
for(i=0;i <= size; i++){
|
||||
if(flags[i]){
|
||||
prime = i+i+3;
|
||||
k=i+prime;
|
||||
while(k<=size){
|
||||
flags[k] = false;
|
||||
k += prime;
|
||||
}
|
||||
count = count+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n%d primes\n",count);
|
||||
}
|
||||
|
55
Microsoft C v1/STDIO.H
Normal file
55
Microsoft C v1/STDIO.H
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
*
|
||||
* This header file defines the information used by the standard I/O
|
||||
* package.
|
||||
*
|
||||
**/
|
||||
#define _BUFSIZ 512 /* standard buffer size */
|
||||
#define _NFILE 16 /* maximum number of files */
|
||||
|
||||
struct _iobuf
|
||||
{
|
||||
char *_ptr; /* current buffer pointer */
|
||||
int _cnt; /* current byte count */
|
||||
char *_base; /* base address of I/O buffer */
|
||||
char _flag; /* control flags */
|
||||
char _file; /* file number */
|
||||
};
|
||||
|
||||
extern struct _iobuf _iob[_NFILE];
|
||||
|
||||
#define _IOREAD 1 /* read flag */
|
||||
#define _IOWRT 2 /* write flag */
|
||||
#define _IONBF 4 /* non-buffered flag */
|
||||
#define _IOMYBUF 8
|
||||
#define _IOEOF 16 /* end-of-file flag */
|
||||
#define _IOERR 32 /* error flag */
|
||||
#define _IOSTRG 64
|
||||
#define _IORW 128
|
||||
|
||||
#define NULL 0 /* null pointer value */
|
||||
#define FILE struct _iobuf /* shorthand */
|
||||
#define EOF (-1) /* end-of-file code */
|
||||
|
||||
#define stdin (&_iob[0]) /* standard input file pointer */
|
||||
#define stdout (&_iob[1]) /* standard output file pointer */
|
||||
#define stderr (&_iob[2]) /* standard error file pointer */
|
||||
|
||||
#define getc(p) (--(p)->_cnt>=0? *(p)->_ptr++&255:_filbf(p))
|
||||
#define getchar() getc(stdin)
|
||||
#define putc(c,p) (--(p)->_cnt>=0? ((int)(*(p)->_ptr++=(c))):_flsbf((c),p))
|
||||
#define putchar(c) putc(c,stdout)
|
||||
#define feof(p) (((p)->_flag&_IOEOF)!=0)
|
||||
#define ferror(p) (((p)->_flag&_IOERR)!=0)
|
||||
#define fileno(p) (p)->_file
|
||||
#define rewind(fp) fseek(fp,0L,0)
|
||||
#define fflush(fp) _flsbf(-1,fp)
|
||||
|
||||
FILE *fopen();
|
||||
FILE *freopen();
|
||||
long ftell();
|
||||
char *fgets();
|
||||
|
||||
#define abs(x) ((x)<0?-(x):(x))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#define min(a,b) ((a)<=(b)?(a):(b))
|
33
Microsoft C v1/TINYMAIN.C
Normal file
33
Microsoft C v1/TINYMAIN.C
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
*
|
||||
* This module defines a version of _main which processes the
|
||||
* command line for arguments but does not open "stdin", "stdout",
|
||||
* and "stderr". Since these files are not opened, the library
|
||||
* functions "printf" and "scanf" will not work; however, the
|
||||
* console functions "cprintf" and "cscanf" can be used instead.
|
||||
*
|
||||
**/
|
||||
#include "CTYPE.H"
|
||||
#define MAXARG 32 /* maximum command line arguments */
|
||||
|
||||
_main(line)
|
||||
char *line;
|
||||
{
|
||||
static int argc = 0;
|
||||
static char *argv[MAXARG];
|
||||
|
||||
while (isspace(*line)) line++; /* find program name */
|
||||
while (*line != '\0' && argc < MAXARG)
|
||||
{ /* get command line parameters */
|
||||
argv[argc++] = line;
|
||||
while (*line != '\0' && isspace(*line) == 0) line++;
|
||||
if (*line == '\0') break;
|
||||
*line++ = '\0';
|
||||
while (isspace(*line)) line++;
|
||||
}
|
||||
main(argc, argv); /* call main function */
|
||||
_exit(0);
|
||||
}
|
||||
break;
|
||||
*line++ = '\0';
|
||||
|
33
Microsoft C v1/e.c
Normal file
33
Microsoft C v1/e.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*#include <string.h>*/
|
||||
#include <stdio.h>
|
||||
/*#include <stdlib.h> */
|
||||
|
||||
#define DIGITS_TO_FIND 200 /*9009*/
|
||||
|
||||
int main() {
|
||||
|
||||
int N = DIGITS_TO_FIND;
|
||||
char buf[ 128 ];
|
||||
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;
|
||||
}
|
8
Microsoft C v1/m.bat
Normal file
8
Microsoft C v1/m.bat
Normal file
@ -0,0 +1,8 @@
|
||||
rem errorlevel can't be used because all 3 apps use the value-less cp/m exit function
|
||||
|
||||
ntvdm mc1 %1
|
||||
|
||||
ntvdm mc2 %1
|
||||
|
||||
ntvdm link %1 + c + gettm,, %1.map, mc
|
||||
|
99
Microsoft C v1/tap.c
Normal file
99
Microsoft C v1/tap.c
Normal file
@ -0,0 +1,99 @@
|
||||
#include <stdio.h>
|
||||
/*
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
|
||||
#ifndef __max
|
||||
#define __max( a, b ) (a) > (b) ? a : b
|
||||
#define __min( a, b ) (a) < (b) ? a : b
|
||||
#endif
|
||||
|
||||
typedef /*unsigned*/ long ulong;
|
||||
|
||||
ulong gcd( m, n ) ulong m, n;
|
||||
{
|
||||
ulong a = 0;
|
||||
ulong b = __max( m, n );
|
||||
ulong r = __min( m, n );
|
||||
|
||||
while ( 0 != r )
|
||||
{
|
||||
a = b;
|
||||
b = r;
|
||||
r = a % b;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/*
|
||||
ulong randi()
|
||||
{
|
||||
return (ulong) rand() | ( ( (ulong) rand() ) << 16 );
|
||||
}
|
||||
*/
|
||||
|
||||
/* https://en.wikipedia.org/wiki/Ap%C3%A9ry%27s_theorem */
|
||||
|
||||
int first_implementation()
|
||||
{
|
||||
ulong total = 1000;
|
||||
ulong i, iq;
|
||||
double sofar = 0.0;
|
||||
ulong prev = 1;
|
||||
|
||||
for ( i = 1; i <= total; i++ )
|
||||
{
|
||||
iq = i * i * i;
|
||||
sofar += (double) 1.0 / (double) ( iq );
|
||||
/*printf( "i, iq, and sofar: %lu, %lu, %lf\n", i, iq, sofar );*/
|
||||
|
||||
if ( i == ( prev * 10 ) )
|
||||
{
|
||||
prev = i;
|
||||
printf( " at %12lu iterations: %lf\n", i, sofar );
|
||||
fflush( stdout );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
ulong totalEntries = 100000;
|
||||
ulong i, prev, totalCoprimes, greatest, a, b, c;
|
||||
|
||||
printf( "starting, should tend towards 1.2020569031595942854...\n" );
|
||||
|
||||
printf( "first implementation...\n" );
|
||||
first_implementation();
|
||||
|
||||
/* no rand
|
||||
printf( "second implementation...\n" );
|
||||
|
||||
|
||||
totalCoprimes = 0;
|
||||
prev = 1;
|
||||
|
||||
for ( i = 1; i <= totalEntries; i++ )
|
||||
{
|
||||
a = randi();
|
||||
b = randi();
|
||||
c = randi();
|
||||
|
||||
greatest = gcd( a, gcd( b, c ) );
|
||||
if ( 1 == greatest )
|
||||
totalCoprimes++;
|
||||
|
||||
if ( i == ( prev * 10 ) )
|
||||
{
|
||||
prev = i;
|
||||
printf( " at %12lu iterations: %lf\n", i, (double) i / (double) totalCoprimes );
|
||||
fflush( stdout );
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
printf( "done\n" );
|
||||
return 1202;
|
||||
}
|
171
Microsoft C v1/tm.c
Normal file
171
Microsoft C v1/tm.c
Normal file
@ -0,0 +1,171 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef AZTEC86
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HISOFTC
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#define OLDMSC
|
||||
#ifdef OLDMSC
|
||||
#define unsigned
|
||||
#define void int
|
||||
#endif
|
||||
|
||||
#ifdef WATCOM
|
||||
#include <malloc.h>
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef powerc
|
||||
#define allocs 50
|
||||
#else
|
||||
#ifdef HISOFTC
|
||||
#define allocs 66 /* not enough RAM with hisoft to go higher */
|
||||
#else
|
||||
/* most c runtimes work up to 69, but use 66 to have a consistent benchmark */
|
||||
#define allocs 66
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int logging = 1;
|
||||
|
||||
char * memset_x( p, v, c ) char * p; int v; int c;
|
||||
{
|
||||
unsigned char * pc = (unsigned char *) p;
|
||||
unsigned char val = (unsigned char) ( v & 0xff );
|
||||
int i;
|
||||
|
||||
if ( 0 == p )
|
||||
{
|
||||
printf( "request to memset a null pointer\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( logging )
|
||||
#ifdef CPMTIME
|
||||
printf( " memset p %u, v %d, val %x, c %d\n", p, v, val, c );
|
||||
#else
|
||||
|
||||
#ifdef HISOFTC
|
||||
printf( " memset p %u, v %d, val %x, c %d\n", p, v, val, c );
|
||||
#else
|
||||
printf( " memset p %p, v %d, val %x, c %d\n", p, v, val, c );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for ( i = 0; i < c; i++ )
|
||||
*pc++ = val;
|
||||
return p;
|
||||
}
|
||||
|
||||
void chkmem( p, v, c ) char * p; int v; int c;
|
||||
{
|
||||
unsigned char * pc = (unsigned char *) p;
|
||||
unsigned char val = (unsigned char) ( v & 0xff );
|
||||
int i;
|
||||
|
||||
if ( 0 == p )
|
||||
{
|
||||
printf( "request to chkmem a null pointer\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
for ( i = 0; i < c; i++ )
|
||||
{
|
||||
if ( *pc != val )
|
||||
{
|
||||
#ifdef CPMTIME
|
||||
printf( "memory isn't as expected! p %u, v %d, c %d, *pc %d\n",p, v, c, *pc );
|
||||
#else
|
||||
printf( "memory isn't as expected! p %p, v %d, c %d, *pc %d\n",p, v, c, *pc );
|
||||
#endif
|
||||
exit( 1 );
|
||||
}
|
||||
pc++;
|
||||
}
|
||||
}
|
||||
|
||||
int main( argc, argv ) int argc; char * argv[];
|
||||
{
|
||||
int i, cb, c_cb, j;
|
||||
char * pc;
|
||||
char * ap[ allocs ];
|
||||
|
||||
logging = ( argc > 1 );
|
||||
pc = argv[ 0 ]; /* evade compiler warning */
|
||||
|
||||
for ( j = 0; j < 10; j++ )
|
||||
{
|
||||
if ( logging )
|
||||
printf( "in alloc mode\n" );
|
||||
|
||||
for ( i = 0; i < allocs; i++ )
|
||||
{
|
||||
cb = 8 + ( i * 10 );
|
||||
c_cb = cb + 5;
|
||||
if ( logging )
|
||||
printf( " i, cb: %d %d\n", i, cb );
|
||||
|
||||
pc = (char *) calloc( c_cb, 1 );
|
||||
chkmem( pc, 0, c_cb );
|
||||
memset_x( pc, 0xcc, c_cb );
|
||||
|
||||
ap[ i ] = (char *) malloc( cb );
|
||||
memset_x( ap[ i ], 0xaa, cb );
|
||||
|
||||
chkmem( pc, 0xcc, c_cb );
|
||||
free( pc );
|
||||
}
|
||||
|
||||
if ( logging )
|
||||
printf( "in free mode, even first\n" );
|
||||
|
||||
for ( i = 0; i < allocs; i += 2 )
|
||||
{
|
||||
cb = 8 + ( i * 10 );
|
||||
c_cb = cb + 3;
|
||||
if ( logging )
|
||||
printf( " i, cb: %d %d\n", i, cb );
|
||||
|
||||
pc = (char *) calloc( c_cb, 1 );
|
||||
chkmem( pc, 0, c_cb );
|
||||
memset_x( pc, 0xcc, c_cb );
|
||||
|
||||
chkmem( ap[ i ], 0xaa, cb );
|
||||
memset_x( ap[ i ], 0xff, cb );
|
||||
free( ap[ i ] );
|
||||
|
||||
chkmem( pc, 0xcc, c_cb );
|
||||
free( pc );
|
||||
}
|
||||
|
||||
if ( logging )
|
||||
printf( "in free mode, now odd\n" );
|
||||
|
||||
for ( i = 1; i < allocs; i += 2 )
|
||||
{
|
||||
cb = 8 + ( i * 10 );
|
||||
c_cb = cb + 7;
|
||||
if ( logging )
|
||||
printf( " i, cb: %d %d\n", i, cb );
|
||||
|
||||
pc = (char *) calloc( c_cb, 1 );
|
||||
chkmem( pc, 0, c_cb );
|
||||
memset_x( pc, 0xcc, c_cb );
|
||||
|
||||
chkmem( ap[ i ], 0xaa, cb );
|
||||
memset_x( ap[ i ], 0xff, cb );
|
||||
free( ap[ i ] );
|
||||
|
||||
chkmem( pc, 0xcc, c_cb );
|
||||
free( pc );
|
||||
}
|
||||
}
|
||||
|
||||
printf( "success\n" );
|
||||
return 0;
|
||||
}
|
46
Microsoft C v1/tpi.c
Normal file
46
Microsoft C v1/tpi.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define HIGH_MARK 500 /* 2800 */
|
||||
|
||||
static long r[HIGH_MARK + 1];
|
||||
|
||||
int main() {
|
||||
long i, k, c;
|
||||
long b, d;
|
||||
long iter;
|
||||
|
||||
int iterations = 1;
|
||||
|
||||
for ( iter = 0; iter < iterations; iter++ ) {
|
||||
c = 0;
|
||||
|
||||
for (i = 0; i < HIGH_MARK; i++) {
|
||||
r[i] = 2000;
|
||||
}
|
||||
|
||||
for (k = HIGH_MARK; k > 0; k -= 14) {
|
||||
d = 0;
|
||||
|
||||
i = k;
|
||||
for (;;) {
|
||||
d += r[i] * 10000;
|
||||
b = 2 * i - 1;
|
||||
|
||||
r[i] = d % b;
|
||||
d /= b;
|
||||
i--;
|
||||
if (i == 0) break;
|
||||
d *= i;
|
||||
}
|
||||
if ( iter == ( iterations - 1 ) )
|
||||
{
|
||||
printf( "%.4d", c + d / 10000 );
|
||||
fflush( stdout );
|
||||
}
|
||||
c = d % 10000;
|
||||
}
|
||||
}
|
||||
|
||||
printf( "\n" );
|
||||
return 0;
|
||||
}
|
545
Microsoft C v1/ttt.c
Normal file
545
Microsoft C v1/ttt.c
Normal file
@ -0,0 +1,545 @@
|
||||
/*
|
||||
This version builds with old compilers including:
|
||||
Aztec C 1.06 for 8080 & Z80 on CP/M.
|
||||
Microsoft C Compiler V1.04 for 8086 on DOS. (This is Lattice C)
|
||||
Microsoft C Compiler V2.03 for 8086 on DOS. (Still Lattice C)
|
||||
Microsoft C Compiler V3.00 for 8086 on DOS.
|
||||
QuickC 1.0
|
||||
Turbo C 2.0
|
||||
The syntax is old and reminds me of 7th grade summer vacation.
|
||||
Much of this code is awkward to satisfy the lowest common denominator of many compilers.
|
||||
unsigned long isn't supported in many older compilers, so long is used instead.
|
||||
Early DOS and CP/M require register variabes to be int, not char or other types.
|
||||
The perf improvement of using register-int instead of stack-char is worth it.
|
||||
*/
|
||||
|
||||
#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 UseFunPointers
|
||||
|
||||
#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
|
||||
|
||||
/* see gettm.asm in masm folder for function to get current time */
|
||||
|
||||
extern long gettm();
|
||||
|
||||
long getms()
|
||||
{
|
||||
long r, h, m, s, l;
|
||||
|
||||
r = gettm();
|
||||
|
||||
h = ( r >> 24 ) & 0xff;
|
||||
m = ( r >> 16 ) & 0xff;
|
||||
s = ( r >> 8 ) & 0xff;
|
||||
l = ( r >> 0 ) & 0xff;
|
||||
|
||||
return h * 3600000 + m * 60000 + s * 1000 + l * 10;
|
||||
} /*getms*/
|
||||
|
||||
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 = getms();
|
||||
|
||||
FindSolution( 0 );
|
||||
FindSolution( 1 );
|
||||
FindSolution( 4 );
|
||||
|
||||
end_time = getms();
|
||||
|
||||
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*/
|
||||
|
Loading…
Reference in New Issue
Block a user